Skip to content

Merge upstream dashboard bug fixes (cytostack/openwolf#4)#1

Merged
tkensiski merged 1 commit intodevelopfrom
fix/dashboard-bugs
Apr 9, 2026
Merged

Merge upstream dashboard bug fixes (cytostack/openwolf#4)#1
tkensiski merged 1 commit intodevelopfrom
fix/dashboard-bugs

Conversation

@tkensiski
Copy link
Copy Markdown
Owner

Summary

Merges 8 dashboard bug fixes from upstream (cytostack#4) into develop for testing before main.

Fixes included

  1. Run Now button silently did nothing — Replaced WebSocket send with fetch POST /api/cron/run/:taskId; returns 202 and broadcasts errors via WS
  2. AI Insights "Generate Now" opened Claude desktop app — Uses Anthropic API directly via fetch when ANTHROPIC_API_KEY is set; shows copy-able prompt fallback
  3. Token graph x-axis showed date only — Fixed slice to include HH:MM
  4. Design QC only worked on localhost — Added detectDeployedUrl() and manual "Run Capture" button with POST endpoint
  5. Token comparison chart had hardcoded data and visual issues — Uses real token ledger data; fixed bar backgrounds and tooltip colors
  6. "Healthy" and "Live" badges were meaningless — Removed both
  7. Dashboard showed wrong project after switching — Kills stale port holder; added hot-reload via POST /api/switch and project switcher dropdown
  8. Cron execution log was never written — Fixed readState() to merge with complete defaults so execution_log is always an array

Also fixes: openwolf binary losing execute bit on every build (added chmod +x to build script and postinstall hook).

19 files changed, ~635 insertions, ~351 deletions.

Test plan

  • Start dashboard, verify Run Now triggers tasks and shows errors on failure
  • Verify AI Insights shows prompt (no Claude desktop launch)
  • Check token graph x-axis shows date + time
  • Test Design QC capture on non-localhost URL
  • Verify token comparison chart uses real data, no gray bar tails
  • Confirm no "Healthy"/"Live" badges in sidebar/header
  • Switch projects via dropdown, verify dashboard updates in-place
  • Run a cron task, verify execution_log is written to cron-state.json

🤖 Generated with Claude Code

…ject switching, cron logging

Bug 1 — "Run Now" button silently did nothing
The button called client?.send() over WebSocket which drops silently if
the socket is not in OPEN state. Replaced with fetch POST /api/cron/run/:taskId.
The endpoint returns 202 immediately and runs the task in the background.
If the task fails, a task_error WebSocket message is broadcast so the UI
shows the actual error instead of resetting silently.

Bug 2 — AI Insights "Generate Now" opened the Claude desktop app
The cron engine was spawning the claude CLI binary from a background daemon.
On macOS that binary spins up a Linux VM via the Virtualization framework
and delegates auth to the desktop app — both fail from a headless process.
Fix: if ANTHROPIC_API_KEY is set, call the Anthropic API directly via fetch.
If not set, fail immediately with a clear error. The dashboard panel now shows
a copy-able prompt to paste into a Claude Code session — how OpenWolf is meant
to work (Claude writes data, the dashboard reads it).

Bug 3 — Token graph x-axis showed date only, not time
s.started.slice(0, 10) only kept the date. Changed to .slice(0, 16).replace("T", " ")
to show YYYY-MM-DD HH:MM.

Bug 4 — Design QC only worked on localhost
The capture engine only detected dev servers. Added detectDeployedUrl() which
checks package.json homepage, .env.production URL vars, and vercel.json aliases.
Added a manual "Run Capture" button with POST /api/designqc/run endpoint.
Fixed the engine not writing designqc-report.json after capture.

Bug 5 — Token comparison chart had hardcoded data and visual issues
Removed fabricated comparison data. Now uses real tracked values from the token
ledger. Fixed the gray tail on bars (recharts renders a background behind each
bar by default — set background fill to transparent). Fixed tooltip using
undefined CSS variables — now uses explicit dark colors.

Bug 6 — "Healthy" and "Live" badges were meaningless
The sidebar badge always showed green regardless of actual state. The header
Live indicator added noise without value — if the page loaded the daemon is
running. Both removed.

Bug 7 — Dashboard showed wrong project after switching
All projects default to port 18791. Starting a second project's daemon failed
silently because the port was already held, leaving the old project's dashboard
visible. daemonStart now kills whatever is on the port before starting. Added
POST /api/switch which hot-reloads the project in-place: stops the cron engine
and file watcher, swaps the project root, restarts both subsystems, broadcasts
the new project's full state over the existing WebSocket. No process restart
needed. Added a project switcher dropdown in the dashboard header.

Bug 8 — Cron execution log was never written
The daemon writes cron-state.json on startup with only { engine_status,
last_heartbeat }. When tasks completed and tried to append to execution_log,
they hit TypeError: Cannot read properties of undefined (reading 'push') —
caught by the task's own catch block, making every successful run look like a
failure. Fixed by merging stored state with complete defaults in readState()
so execution_log is always an array.

Also: openwolf binary lost execute bit on every build
tsc does not preserve the +x bit. Added chmod +x to the build script and a
postinstall hook so it is set automatically after every build and npm install -g.
@tkensiski tkensiski merged commit 8c0d3bf into develop Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants