Commit Graph

2772 Commits

Author SHA1 Message Date
gsxdsm
564659fcbe fix: prevent agents from killing production dashboard on port 4040
An AI review agent (FN-1506) killed the running dashboard by finding
the process on port 4040 via lsof and running kill -9, causing exit
code 137 (SIGKILL) with no logs. This adds multi-layer guardrails:

- AGENTS.md: project-level rule reserving port 4040
- Executor/reviewer system prompts: explicit prohibition on killing
  port 4040 processes, with instruction to use --port 0 instead
- Core agent-prompts.ts: same guardrails in all prompt variants
- Reviewer told to issue REVISE if executor violates the rule
- SIGHUP handlers in dashboard.ts and serve.ts for resilience
- Background engine reconciliation in dashboard/serve startup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 18:00:49 -07:00
gsxdsm
9a028b6573 feat(FN-1640): add Frontend UX Design built-in workflow template
- Add Frontend UX Design template for verifying UI/UX design implementation
- Include WCAG 2.1 compliance checks, design system adherence, and user flow validation
- Add template to WorkflowStepManager with category-based organization
- Update documentation with new template description
- Add tests for template API endpoints and workflow step manager
2026-04-13 17:41:33 -07:00
gsxdsm
755b8b2520 Fix mission task status sync 2026-04-13 17:14:06 -07:00
gsxdsm
0d0e2e6dbe fix(engine): prevent two tasks showing "merging" status simultaneously
Root cause: if a merge crashed or the process restarted mid-merge, the
"merging" status was never cleared. On next startup the stale task kept
its "merging" status while the queue moved on to the next task, resulting
in two tasks appearing to merge at once.

Two fixes:
1. Add "merging"/"merging-pr" to BLOCKING_TASK_STATUSES so tasks with
   active merge status are not re-enqueued by the retry sweep.
2. Clear stale "merging" statuses during startup merge sweep — no merge
   is actually running at engine start, so any such status is a leftover.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 17:06:17 -07:00
gsxdsm
98bc2dfdae feat(FN-1702): merge fusion/fn-1702 2026-04-13 17:04:15 -07:00
gsxdsm
6079dfd316 fix(engine): serialize manual merge through the auto-merge queue
The onMerge() path (dashboard "merge now" button) bypassed the
drainMergeQueue serialization, allowing two tasks to enter "merging"
status simultaneously within the same project. Route manual merges
through the same queue so only one merge runs at a time per project.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 16:40:06 -07:00
gsxdsm
1712866ae8 feat(FN-1706): merge fusion/fn-1706 2026-04-13 16:35:06 -07:00
gsxdsm
f3087df5de feat(FN-1492): merge fusion/fn-1492 2026-04-13 16:30:42 -07:00
gsxdsm
63c26579fa feat(FN-1700): merge fusion/fn-1700 2026-04-13 16:20:04 -07:00
gsxdsm
4e5067f68d feat(FN-1698): merge fusion/fn-1698 2026-04-13 16:05:12 -07:00
gsxdsm
eb669a21b4 feat(FN-1692): merge fusion/fn-1692 2026-04-13 16:05:05 -07:00
gsxdsm
6aec83fff3 feat(FN-1663): merge fusion/fn-1663 2026-04-13 15:51:05 -07:00
gsxdsm
f46a96dbf1 feat(FN-1661): merge fusion/fn-1661 2026-04-13 15:35:14 -07:00
gsxdsm
ebbc463dc8 feat(FN-1650): merge fusion/fn-1650 2026-04-13 15:35:08 -07:00
gsxdsm
668a6e3894 fix(tests): add globalConcurrency mocks to settings-mobile test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 15:32:30 -07:00
gsxdsm
f395a3d9e5 feat(FN-1680): merge fusion/fn-1680 2026-04-13 15:29:41 -07:00
gsxdsm
a230322068 feat(FN-1451): merge fusion/fn-1451 2026-04-13 15:29:27 -07:00
gsxdsm
f46803d985 fix(triage): enforce per-project maxConcurrent limit on triage
The triage processor was only checking the global semaphore, not the
per-project maxConcurrent setting. Now it counts all active agents
(in-progress + specifying) and respects Math.min(perProjectAvailable,
semaphoreAvailable) before starting new triage tasks. This matches the
scheduler's concurrency enforcement and prevents triage from consuming
all available slots on startup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 15:18:32 -07:00
gsxdsm
8124f10511 fix(triage): respect global concurrency limit before queuing tasks
The triage processor was kicking off all eligible tasks simultaneously,
queuing them all on the semaphore regardless of available slots. Now it
checks semaphore.availableCount first and only starts as many triage
tasks as there are free slots. Remaining tasks get picked up on the
next poll cycle (default 10-15s) as slots free up.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 15:06:29 -07:00
gsxdsm
a8bc136ec4 feat(FN-1485): merge fusion/fn-1485 2026-04-13 15:02:21 -07:00
gsxdsm
fd8da2c2c7 fix(tests): add globalConcurrency mocks to SettingsModal test files
Both SettingsModal test files were missing mocks for fetchGlobalConcurrency
and updateGlobalConcurrency, causing the component to throw on mount.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 14:59:08 -07:00
gsxdsm
730059123b fix: share one global semaphore across all project engines
ProjectEngineManager now creates a single AgentSemaphore and injects it
into all engines via config.globalSemaphore. Previously each engine created
its own semaphore, so the globalMaxConcurrent limit was not enforced across
projects. The semaphore dynamically reads the limit and listens for
concurrency:changed events for live updates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 14:46:21 -07:00
gsxdsm
f2afce2468 feat: expose global execution concurrency limit in settings
- Add PUT /api/global-concurrency endpoint to update globalMaxConcurrent
  via CentralCore (validated 1-50 range)
- Make InProcessRuntime semaphore react to live concurrency changes via
  CentralCore "concurrency:changed" event — no restart needed
- Add Global Max Concurrent input to Settings modal Scheduling section
  with fetch-on-mount and save-alongside-project-settings behavior
- Add updateGlobalConcurrency API client function

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 14:23:40 -07:00
gsxdsm
8b2eea90ff fix(dashboard): resolve typecheck test failures across test files
- Exclude test files from tsconfig.app.json (matches tsconfig.json pattern)
  Test files use loose mocks that don't satisfy strict type checks —
  they're validated by vitest at runtime, not by tsc
- Fix highlightDiff.test.ts React 19 type errors (props typed as unknown)
- Remove duplicate fetchTasks import in api.test.ts
- Add Task[] cast in ActivityLogModal.test.tsx mock data

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 14:15:00 -07:00
gsxdsm
3935f4cf8e chore: update fusion memory notes 2026-04-13 13:50:34 -07:00
gsxdsm
1383b8d7d6 refactor: replace primary/secondary engine pattern with uniform ProjectEngineManager
Remove the anti-pattern where the cwd project was treated as "primary" with a
special engine, and other projects got "secondary" engines through a separate
code path. Every project now gets an identical ProjectEngine created through
ProjectEngineManager.

Key changes:
- Add ProjectEngineManager class to @fusion/engine for uniform engine lifecycle
- Replace manual engine maps in dashboard.ts and serve.ts with engineManager
- Add engineManager to ServerOptions for per-project engine resolution
- Add getProjectContext() helper in routes.ts (replaces 199 getScopedStore calls)
- Merge and automation routes now resolve engine subsystems per-request
- SSE endpoint uses engine's store when available (same EventEmitter)
- Fix tsx not found in dev-with-memory.mjs startup script
- Add invalidateAllGlobalSettingsCaches for cross-project settings sync

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 13:32:38 -07:00
gsxdsm
6d414f7b59 feat(FN-1626): merge fusion/fn-1626
- docs(FN-1626): document PWA home bar gap token and updated bottom-layout contract
- fix(pre-existing): add missing invalidateAllGlobalSettingsCaches export to unblock build
- feat(FN-1626): update regression tests for standalone spacing and PWA home bar gap
- feat(FN-1626): add PWA home bar gap token and update bottom-layout CSS contract
2026-04-13 13:31:05 -07:00
gsxdsm
4e61a05031 chore(FN-1485): align dashboard api lint hygiene 2026-04-13 13:11:39 -07:00
gsxdsm
492f7acd6e test(FN-1485): complete Step 2 — cover chunked chat SSE parsing 2026-04-13 13:06:04 -07:00
gsxdsm
2ccd915122 fix(FN-1485): complete Step 1 — harden chat SSE parsing 2026-04-13 13:05:46 -07:00
gsxdsm
0370e5bfcc feat(FN-1451): complete Step 5 — document hierarchy resolution 2026-04-13 13:00:05 -07:00
gsxdsm
2618eefc75 feat(FN-1451): complete Step 3 — align CLI hierarchy imports 2026-04-13 12:55:30 -07:00
gsxdsm
b1c90013da feat(FN-1451): complete Step 2 — resolve hierarchy in dashboard imports 2026-04-13 12:51:59 -07:00
gsxdsm
6b112e97f6 feat(FN-1451): complete Step 1 — add core hierarchy import planning 2026-04-13 12:49:29 -07:00
gsxdsm
0a1def0cc7 Fix stranded task retry and respec reset 2026-04-13 11:10:17 -07:00
gsxdsm
2486f2fb07 fix(lint): resolve pre-existing lint errors and merge conflicts
- Remove unused imports/vars from routes.ts (VALID_TRANSITIONS, AUTOMATION_PRESETS, ChatStore, FileListResponse, etc.)
- Prefix unused destructured error vars with _ convention
- Fix prefer-const for summary variable
- Add _ ignore pattern to eslint.config.mjs
- Include test files in tsconfig.app.json to fix @testing-library/jest-dom types
- Resolve GitManagerModal.test.tsx merge conflict (take fn-1626 expectLatestCallStartsWith style)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 10:31:15 -07:00
gsxdsm
3e2094dba3 fix(respecify): skip stale spec enforcement for in-progress/in-review/done tasks
Background stale spec checks now skip tasks that are already in an
active work state (in-progress, in-review, done, merging, merging-pr)
to avoid interrupting work that is underway or complete.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 10:08:25 -07:00
gsxdsm
54ce431161 fix mobile task action menu positioning 2026-04-13 10:04:14 -07:00
gsxdsm
42bd3f8f07 fix(milestone-interview): reconnect SSE stream after submitting response
Same bug as MissionInterviewModal: handleSubmitResponse was calling the
API without first reconnecting to the SSE stream. The stream's complete
event closes the connection after each question delivery, so after the
user submits an answer, a fresh connection is needed to receive the
next question or summary.

Also cleans up the stream on API error, matching MissionInterviewModal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 09:58:21 -07:00
gsxdsm
86202b74cf fix(mission): reconnect SSE stream after submitting interview response
After handleSubmitResponse posted an answer, the stream connection was
never re-established, so the next question from the server was never
received. The modal would stay on the loading spinner until the user
closed and reopened it (which triggered the resume-session reconnect).

Fix: call connectToMissionInterviewStream(sessionId) before the API
call, matching the pattern used by handleRetryFromError. Also close
the stream on API error to match the error-recovery path, and add
connectToMissionInterviewStream to the useCallback dependency array.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 09:53:07 -07:00
gsxdsm
36d5373a6e fix(settings): fix Zai API key clear/save and update GitManagerModal tests
- hasApiKey now only returns true for stored api_key credentials; previously
  it fell back to hasAuth() which includes env vars, causing Clear to appear
  to do nothing and Save to never appear
- Save button now shows when user types into the key input even if already
  authenticated, allowing key updates without clearing first
- Remove unused importFile state variable (TS 6133 lint error)
- Update GitManagerModal tests to pass undefined as projectId argument to
  all API mocks, matching the component's project-aware API signatures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 09:48:59 -07:00
gsxdsm
8874c0d73a feat(FN-1667): merge fusion/fn-1667 (auto-resolved)
- test(FN-1667): complete Step 4 — verify roadmap model
- feat(FN-1667): complete Step 3 — document roadmap model
- feat(FN-1667): complete Step 2 — add roadmap ordering helpers
- feat(FN-1667): complete Step 1 — define roadmap contracts
2026-04-13 08:57:48 -07:00
gsxdsm
251af54580 feat(FN-1661): merge fusion/fn-1661 (auto-resolved)
- feat(FN-1661): complete Step 4 — document task-worker health fix
- feat(FN-1661): complete Step 3 — verify task-worker agent health fix
2026-04-13 08:54:19 -07:00
gsxdsm
f4396fe141 fix(dashboard): make GitManagerModal project-aware
GitManagerModal was not receiving projectId from AppModals, causing all
git operations to run against the default repo instead of the active
project's repo. Threads projectId through all git API calls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 08:27:09 -07:00
gsxdsm
cd851c61a6 fix(dashboard): use ProjectEngine for secondary projects
Secondary projects were started via ProjectManager (bare InProcessRuntime)
which lacks auto-merge queue, startup sweep, periodic retry, PR monitor,
and settings listeners. Tasks reaching in-review in secondary projects
would never be auto-merged. Now all projects use ProjectEngine for the
full subsystem set.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 07:58:20 -07:00
gsxdsm
4bbd42c88e fix(engine): recover already-merged tasks stuck in in-review
When a merge completes but auto-recovery moves the task back to
in-review, the retry gating (mergeRetries >= 3) blocked re-processing.
Now canMergeTask always accepts mergeConfirmed tasks and drainMergeQueue
fast-paths them directly to done without re-running the merge agent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 07:49:54 -07:00
gsxdsm
a2d54c4a42 Fix Zai and Minimax auth for usage 2026-04-13 07:38:38 -07:00
gsxdsm
bbe2542362 Read provider settings from fusion fallback 2026-04-13 07:05:01 -07:00
gsxdsm
a3e154dc31 feat(FN-1664): merge fusion/fn-1664 (auto-resolved)
- docs(FN-1664): add changeset for Active Agents card selection fix
- test(FN-1664): add regression tests for active agent card selection
- feat(FN-1664): wire ActiveAgentsPanel selection to open AgentDetailView
2026-04-13 00:31:54 -07:00
gsxdsm
65c15c56b6 feat(FN-1624): add delete button to TaskCard for triage column
- Add delete button component to TaskCard for tasks in the triage column
- Thread onDeleteTask prop through App → Board → Column → TaskCard
- Add CSS styles for delete button with hover/active states
- Add comprehensive tests for delete button visibility and click handling
- Hide delete button for non-triage columns (todo, in-progress, etc.)
2026-04-13 00:21:25 -07:00