fix(dashboard): prune deleted files from SQLite + global toasts + approval feedback - #26
NancyBraun wants to merge 11 commits into
Conversation
The "--dangerously-skip-permissions" first-run warning defaults its highlight to "No, exit", so the prior bare-Enter auto-accept exited the agent process, crash-looping the daemon. Detect the "Bypass Permissions" screen and send Down+Enter (\x1b[B\r) to select "Yes, I accept"; keep the plain Enter path for the folder-trust prompt. Extend the retry timers to cover the slower bypass render. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Containment/traversal guards compared with `base + '/'`, but on Windows path.resolve()/join() return '\' separators, so the startsWith check failed for legitimately-nested paths and the guard tripped — disabling the hook dispatcher (fast-checker), and rejecting valid worker dirs (ipc-server spawn-worker), catalog installs, and skill auto-PRs. Switch all six sites to `base + sep`, matching the existing correct pattern in src/bus/message.ts. Also normalize separators before the SKILL.md regex in hook-skill-autopr so the path match is platform-independent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Google is migrating Gemini/AI Studio keys from the legacy AIza format to new "auth keys" with an AQ. prefix (standard keys get rejected mid-2026). Key acceptance here was always format-agnostic (verifyGeminiKey hits the live API; other checks are non-empty only), so AQ. keys already work — but the two console hints still said "starts with AIza..." and could confuse users pasting a new auth key. Update the hints to list both formats. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t-checker
The heartbeat watchdog and usage-tier checker called execFile('cortextos', ...)
with a bare command name. On Windows the npm global is a `cortextos.cmd` shim
that execFile (no shell) cannot resolve, so both fired `spawn cortextos ENOENT`
on every tick. Effects: idle agents never refreshed their heartbeat (the
dashboard then falsely marked them "down" after 5h) and rate-limit tier alerts
never ran.
Switch both call sites to `process.execPath` + `<frameworkRoot>/dist/cli.js`,
matching the existing convention in hook-skill-autopr.ts and setup.ts. Fully
portable; no PATH/shim dependency.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Authored by the cpm-dev agent as part of its task to resolve the Windows test failures it identified (78/2611). Verified by Claude Code: the 3 test files pass (38 passed, 8 correctly skipped on Windows), main build is clean, and dashboard/sync.ts type-checks. - dashboard/src/lib/sync.ts: normalize Windows backslashes to forward slashes before path containment checks in syncFile() and the extract* helpers, so the dashboard file-sync (tasks/approvals/events/heartbeat) works on Windows. - tests/support-access.test.ts, tests/unit/cli/enable-agent-validation.test.ts: set USERPROFILE (os.homedir() reads it on Windows, not HOME); skip the two chmod-permission cases on Windows. - tests/unit/utils/atomic.test.ts: skipIf(isWindows) on tests asserting Unix file modes (0o600) and POSIX symlink behavior that do not apply on Windows. Partial fix — covers these 4 files; remaining Windows test failures stay tracked under the cpm-dev task. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sweep of cpm-dev's autonomous Windows-portability work plus two completions found during verification. cpm-dev's fixes (verified): - Normalize `\`→`/` and strip CRLF before path/frontmatter assertions (agent-process, agent-process-hermes, cron-teaching-scanner, sprint1-templates, sprint4-catalog, cron-management-skill, migrate-runtime-field). - skipIf(isWindows) on suites needing symlinks (Developer Mode) or Unix domain sockets (codex-app-server-pty, lifecycle-codex, add-agent-codex, media-route) and on fake-timer scheduling tests that hang under Windows fake timers (fast-checker heartbeat watchdog). Production paths these cover are verified elsewhere/live. Completions added during verify: - add-agent-codex: skip the PR-10 describe too (it also calls symlinkSync; cpm-dev only skipped PR-02) — was 4 EPERM failures. - message.test: skip the processed/ symlink-traversal test (EPERM on Windows without Developer Mode). Full suite on Windows: build + tsc clean; remaining known failures are unrelated (knowledge-base missing-config guard, comms-lint real-homedir isolation) and tracked separately. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nt homedir)
Clears the remaining Windows test failures so the full suite is green
(2574 passed, 0 failed, 37 skipped).
- knowledge-base.test: mockMissingKbConfig() compared the config path with
a forward-slash `.endsWith('/knowledge-base/config.json')`, but production
builds it via path.join → backslashes on Windows. The check never matched,
so existsSync fell through to `true`, the missing-config guard was skipped,
and execFileSync ran (3 failures). Normalize separators before the check.
- comms-lint (both files): tests sandbox the home dir via process.env.HOME,
but os.homedir() reads USERPROFILE on Windows, so the outbound-message log
escaped into the REAL ~/.cortextos and a stale file failed the
"no file written when blocked" assertions. Pin USERPROFILE to the temp dir
too (saved/restored alongside HOME).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rge subprocess timeout
autoCommit beforeEach runs 4 git processes (init, 2x config, commit) which
exceeds the 10s hookTimeout on Windows under AV scanning. Batch to 2 shell
invocations with shell:true and set hookTimeout to 30s.
forge-load-gate spawns node child processes per test; under full-suite
parallelism (16 workers) the cold-start overhead can exceed 10s.
Add describe-level { timeout: 30000 } to keep the file portable.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… seps
Two activity-feed bugs fixed:
1. initWatcher() was only called from /api/events/stream (the SSE
endpoint). If no browser client ever opened the activity page, the
JSONL->SQLite sync never ran, leaving the DB empty and the activity
feed blank regardless of how many events agents logged.
Fix: add src/instrumentation.ts — Next.js calls register() on server
start, which calls initWatcher(). First boot now syncs all existing
JSONL files immediately (846 events on the test instance).
2. categorizeFilePath() used hardcoded forward-slash path segments
('/tasks/', '/analytics/events/', etc.). On Windows, chokidar emits
native backslash paths, so every file-change SSE event was mis-typed
as 'sync' rather than 'task'/'event'/'heartbeat'.
Fix: normalize backslashes to forward slashes before the includes
checks — one-liner, no structural change.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…roval feedback Three improvements found during dashboard survey: 1. watcher.ts: remove guard that skipped syncFile on deletions. syncTasks/ syncApprovals already prune orphaned rows when they rescan the directory, so running syncFile on unlink events correctly removes stale DB entries. 2. dashboard-shell.tsx: mount ToastProvider at the shell level so useToast is available on every dashboard page. Previously only the cron-detail page wrapped its own provider; all other pages could not use toasts. 3. approvals/page.tsx: replace silent catch blocks with toast feedback. Approval resolve success/failure, human-task "Done" success/failure, and fetch errors are now surfaced to the user rather than dropped silently. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The three own changes are concrete and still relevant: file removals currently skip We are not merging this branch as submitted because those focused changes are stacked on #11, #22, and #25, producing a conflicting 34-file branch whose scope is much larger than the dashboard-improvements title. The work is wanted, but this stacked branch is not mergeable. We will extract the deletion-pruning and user-visible error handling into a clean current-main implementation with your credit. You should not have had to submit five PRs before receiving one concrete maintainer response. |
|
Wanted - the |
What
Three dashboard fixes found during a survey of open issues.
1. Watcher: sync on file deletions (
watcher.ts)handleFileChangewas skippingsyncFileonunlinkevents.syncTasksandsyncApprovalsalready handle deletions by rescanning the directory and pruning rows whose source files no longer exist — but only if they're called. Removing the guard lets the same code path clean up SQLite when a task or approval file is deleted on disk.2.
ToastProviderat shell level (dashboard-shell.tsx)ToastProviderwas only mounted inside the cron-detail page. Any component on any other page callinguseToast()would throw"useToast must be used within a ToastProvider". Mounting it inDashboardShellmakes toasts available everywhere without per-page boilerplate.3. Approval feedback toasts (
approvals/page.tsx)All three catch blocks and the success path on the approvals page were silent:
Replaced with
useToastcalls so users know when operations succeed or fail.Stacked on PR #25
This branch is based on
fix/dashboard-activity-feed-sync(PR #25). Merge order: #11 → #22 → #25 → this PR.🤖 Generated with Claude Code