Strategy: reset main to upstream/main (v0.39.0) and reapply only the
fork-specific patches that survive — most older patches (plugin-loader
routing, heartbeat resolver, autoload, cross-spawn, scope-resolution
fixes) were absorbed by upstream between v0.28.1 → v0.39.0.
Surviving patches:
- Dockerfile: keep single-stage Coolify-compatible build (upstream went
multi-stage which breaks our bind-mount strategy for
/home/s/.codex, /home/s/.claude, /usr/lib/node_modules)
- packages/engine/src/sandbox-tester-gate.ts: shared Phase-3 pre-merge
gate module (Opus 4.7 + OpenSandbox + Playwright smoke)
- packages/engine/src/executor.ts: call runSandboxTesterGate from
finalizeAlreadyReviewedTask recovery path
- packages/engine/src/project-engine.ts: call applySandboxTesterGate
from primary direct-merge dispatch (the path that actually fires in
prod — recovery path only catches stuck tasks)
- packages/dashboard/src/auth-middleware.ts: registerPluginExemptPath
for webhook endpoints (Grafana, Gitea) that must bypass daemon-token
- packages/dashboard/src/plugin-routes.ts: auto-register plugin-defined
routes as daemon-exempt so external plugins (telemetry-watcher,
gitea-issues) work out of the box
Tested locally: pnpm install + pnpm -r build green, no TS errors.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The Minimax usage panel only rendered one model row. The primary `general`
model meters quota purely via `current_interval_remaining_percent` (its
`current_interval_total_count` is 0), so the count-based `total > 0` visibility
filter dropped it entirely. The percent was also derived from count fields
rather than the authoritative `*_remaining_percent` field.
fetchMinimaxUsage now builds windows via a helper that prefers
`*_remaining_percent` (count-based fallback when absent) and skips a window only
when no quota signal exists. Each model's separate weekly quota window is now
surfaced as its own indicator alongside the interval window.
Verified against the live coding_plan/remains endpoint: 2 models (general,
video) now produce 4 windows (interval + weekly each) instead of 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove the duplicate merger override from the SettingsModal test fixture.
- delete the earlier legacy merger object from the mocked settings payload
- keep the deterministic merger override as the single effective fixture value
Files changed:
packages/dashboard/app/components/__tests__/SettingsModal.test.tsx | 1 -
1 file changed, 1 deletion(-)
Fusion-Task-Id: FN-5923
Fusion-Task-Lineage: 206239b0-af4a-4e45-93b8-2940a42d431a
Align the dependency graph plugin's dashboard interop declarations with the current dashboard contract.
- import ReactNode for plugin task card rendering support
- add DetailTaskTab, PluginToastType, and PluginTaskView type exports
- update PluginDashboardViewContext to require workflowSteps and the expanded openTaskDetail signature
- add optional renderTaskCard and addToast hooks to match dashboard expectations
Files changed:
.../src/dashboard-interop.d.ts | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
Fusion-Task-Id: FN-5935
Fusion-Task-Lineage: 32313a96-1008-4de6-a7cb-e6bfbc385534
Keep research settings controls inside their containment wrappers so inputs stay onscreen across breakpoints.
- wrap advanced provider controls in a dedicated research settings body container
- tighten research grid and field min-width behavior in desktop and mobile styles
- add regression coverage for global and project research sections on desktop and mobile
Files changed:
packages/dashboard/app/components/SettingsModal.css | 37 +++++++-
packages/dashboard/app/components/SettingsModal.tsx | 104 +++++++++++----------
packages/dashboard/app/components/__tests__/SettingsModal.test.tsx | 65 +++++++++++++
packages/dashboard/app/components/__tests__/settings-mobile.test.tsx | 48 ++++++++++
4 files changed, 201 insertions(+), 53 deletions(-)
Fusion-Task-Id: FN-5932
Fusion-Task-Lineage: 22dff41f-b563-40d0-97ea-1ca6d1e09466
Document and enforce pnpm build-script review decisions to prevent ignored-script install warnings.
- add reviewed ignoredBuiltDependencies entries to the root pnpm config and mirror the effective policy in pnpm-workspace.yaml
- add a regression test that verifies reviewed dependencies are categorized exactly once and stay aligned across both config files
- document the pnpm build-script approval policy in contributing docs and link plugin authoring guidance from AGENTS.md and PLUGIN_AUTHORING.md
Files changed:
AGENTS.md | 5 ++
docs/PLUGIN_AUTHORING.md | 3 +-
docs/contributing.md | 14 ++++
package.json | 9 +++
pnpm-workspace.yaml | 14 ++++
scripts/__tests__/pnpm-build-scripts-config.test.mjs | 74 ++++++++++++++++++++++
6 files changed, 118 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-5927
Fusion-Task-Lineage: 192bbed9-c5ed-45cb-b4bd-fb18514e2783
Refine the task review tab layout for clearer hierarchy and better mobile behavior.
- group the review summary and decision badge into a stacked header layout
- reorganize review items with dedicated selection, status, and metadata regions
- restyle review cards, status badges, auto-merge controls, and body containers for improved spacing and overflow handling
- extend TaskReviewTab coverage for populated layout hooks and mobile CSS regressions
Files changed:
packages/dashboard/app/components/TaskReviewTab.css | 220 +++++++++++++++------
packages/dashboard/app/components/TaskReviewTab.tsx | 24 ++-
packages/dashboard/app/components/__tests__/TaskReviewTab.test.tsx | 32 ++-
3 files changed, 206 insertions(+), 70 deletions(-)
Fusion-Task-Id: FN-5925
Fusion-Task-Lineage: fdb9d882-abda-48b0-aed0-a1ff4262af8f
Store hidden usage windows with per-instance identities while keeping legacy labels restorable.
- persist hidden usage windows with an index-qualified identity instead of label-only keys
- treat legacy label-only entries as matches for restore/show-hidden behavior
- guard hidden-window counts when provider windows are empty or undefined
- add regression coverage for duplicate labels, multiple hidden windows, and legacy persistence
Files changed:
packages/dashboard/app/components/UsageIndicator.tsx | 71 +++++++++----
packages/dashboard/app/components/__tests__/UsageIndicator.test.tsx | 113 ++++++++++++++++++++-
2 files changed, 159 insertions(+), 25 deletions(-)
Fusion-Task-Id: FN-5929
Fusion-Task-Lineage: eb48988e-80b8-4d6c-90b9-0d324564f1aa
Keep queued chat composer state when users move between sessions and only clear it when the session is truly discarded.
- stop clearing persisted pending chat messages during session switches in useChat and useQuickChat
- clear persisted queued messages only when creating a fresh session or archiving/deleting an existing session
- add regression coverage for navigation, reselection, pre-session queueing, and cleanup behavior across chat and quick chat hooks
Files changed:
.../dashboard/app/hooks/__tests__/useChat.test.ts | 246 ++++++++++++++++++++-
.../app/hooks/__tests__/useQuickChat.test.ts | 150 +++++++++++++
packages/dashboard/app/hooks/useChat.ts | 9 +-
packages/dashboard/app/hooks/useQuickChat.ts | 5 +-
4 files changed, 396 insertions(+), 14 deletions(-)
Fusion-Task-Id: FN-5921
Fusion-Task-Lineage: 8916f862-77f5-4d5b-be9a-412e8a71a47d
Fix NewChatDialog to resolve the model from the dropdown default when the user has not
explicitly picked a model, allowing chat creation with the default model.
- Introduce `resolvedModel` that falls back to `defaultModelValue` when `selectedModel` is empty
- Use `resolvedModel` in submit handler and submit-disabled guard so the default model is accepted
- Add test for creating a session with the default model ("Use default" selected)
- Add test for creating a session with an explicitly chosen non-default model
- Update existing no-default test to verify the submit button stays disabled and no session is created
Files changed:
packages/dashboard/app/components/ChatView.tsx | 12 ++--
packages/dashboard/app/components/__tests__/ChatView.test.tsx | 69 ++++++++++++++++++++--
2 files changed, 72 insertions(+), 9 deletions(-)
Fusion-Task-Id: FN-5922
Fusion-Task-Lineage: 30b2aecb-af73-4f6d-b697-cc0b5630d5d8
Keep the usage indicator's Show hidden action available when persisted hidden rows no longer render.
- count hidden usage rows from both rendered windows and orphaned persisted labels
- preserve Show hidden visibility on mobile modal and desktop popover surfaces
- add regression coverage for orphaned hidden labels across both UI surfaces
Files changed:
packages/dashboard/app/components/UsageIndicator.tsx | 22 ++++++-
packages/dashboard/app/components/__tests__/UsageIndicator.test.tsx | 75 ++++++++++++++++++++++
2 files changed, 96 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-5919
Fusion-Task-Lineage: 6e4827a6-0d6f-424d-a4df-ec7185adf841
Use a committed launcher for published CLI bin links to avoid fresh-install warnings.
- point the published fn and fusion bin entries at a committed bin.mjs launcher
- add a launcher that checks for dist/bin.js and forwards execution to the built CLI
- cover bin target invariants across workspace packages and update CLI package config tests
- add a patch changeset for the published @runfusion/fusion package
Files changed:
.changeset/fn-5916-cli-bin-launcher.md | 5 ++
packages/cli/bin.mjs | 20 ++++++
packages/cli/package.json | 5 +-
packages/cli/src/__tests__/bin-targets.test.ts | 85 +++++++++++++++++++++++
packages/cli/src/__tests__/package-config.test.ts | 8 ++-
5 files changed, 118 insertions(+), 5 deletions(-)
Fusion-Task-Id: FN-5916
Fusion-Task-Lineage: 59d40654-ff77-4655-b9ce-3f3421521b2c
The FN-5930 squash merge combined two wait-for-exit strategies,
leaving a shadowed 'const exited' and double await. Collapse to
a single register-before-kill pattern.
Fusion-Task-Id: FN-5930
Reduce flakiness in the real-git verification spawn supervision test.\n\n- write the child PID to stdout with an awaited newline flush before the parent exits\n- collapse the scenario branching so the SIGTERM path is mutually exclusive with crash handling\n- await parent process exit during cleanup and document coverage across normal, signal, and crash teardown paths\n\nFiles changed:\n .../verification-spawn-supervision.real-git.test.ts | 9 ++++++---\n 1 file changed, 6 insertions(+), 3 deletions(-)
Fusion-Task-Id: FN-5930
Fusion-Task-Lineage: 20c3fe73-a640-4c34-8a07-edf5bdda4b25
Keep planning summary actions responsive with operation-specific loading indicators.
- pass separate single-task and breakdown loading flags into the planning summary view
- show the Creating spinner only on Create Single Task and the Breaking down spinner only on Break into Tasks while keeping the sibling action disabled
- add regression coverage for both pending-action paths and normalize the restart integration test temp worktree root under /private/tmp
Files changed:
.../dashboard/app/components/PlanningModeModal.tsx | 14 ++-
.../PlanningModeModal.planning-flow.test.tsx | 138 +++++++++++++++++++++
.../src/__tests__/restart.integration.test.ts | 7 +-
3 files changed, 151 insertions(+), 8 deletions(-)
Fusion-Task-Id: FN-5912
Fusion-Task-Lineage: b93da566-0c2b-4ff8-83ea-b6e009dfd650
Prevent dashboard test wrappers from leaving orphaned Vitest subprocesses after interruption or timeout.
- run dashboard vitest wrappers in a detached process group and forward shutdown signals to the whole group
- add an exit-time cleanup path and spawn override seam for process-lifecycle handling without launching real vitest
- cover SIGINT/SIGTERM orphan reaping and keep the dashboard test config guard aligned with the new script test
Files changed:
.../scripts/__tests__/run-vitest-with-heap.test.ts | 172 +++++++++++++++++++++
.../dashboard/scripts/run-vitest-with-heap.mjs | 89 ++++++++++-
.../__tests__/dashboard-test-config-guard.test.ts | 1 +
packages/dashboard/vitest.config.ts | 1 +
4 files changed, 256 insertions(+), 7 deletions(-)
Fusion-Task-Id: FN-5918
Fusion-Task-Lineage: 5c695b3b-14c5-4749-ad9c-eb9f33d5ecd5
Ensure initial planning reasoning streams live to the UI instead of being emitted before subscribers connect.
- register each new or restarted planning session's first turn as pending until the SSE stream attaches
- consume the deferred initial turn on the first subscriber so thinking output and first question are broadcast live
- add route-planning coverage for deferred first-turn behavior, existing drafts, concurrent subscribers, and settings-resolution flows
Files changed:
.../src/__tests__/routes-planning.test.ts | 190 +++++++++++++++++++++
packages/dashboard/src/planning.ts | 63 +++++--
.../src/routes/register-planning-subtask-routes.ts | 2 +
3 files changed, 238 insertions(+), 17 deletions(-)
Fusion-Task-Id: FN-5906
Fusion-Task-Lineage: 204fcbaa-15b4-46a0-b794-6dae6ebd97fe
Add unread mailbox status to the desktop header toggle while keeping pending approvals prioritized.
- show an unread status dot on the desktop header mailbox toggle when unread mail exists without pending approvals
- keep pending-approval indicators taking precedence and hide mailbox indicators while the mailbox view is active
- extend Header coverage for unread-only, pending-only, combined, zero-count, and active-mailbox states
- update restart integration coverage to reuse an existing worktree during orphaned resume concurrency
Files changed:
docs/dashboard-guide.md | 2 +-
packages/dashboard/app/components/Header.tsx | 9 +++++--
.../app/components/__tests__/Header.test.tsx | 26 ++++++++++++++++---
.../src/__tests__/restart.integration.test.ts | 29 ++++++++++++++++++++--
4 files changed, 58 insertions(+), 8 deletions(-)
Fusion-Task-Id: FN-5915
Fusion-Task-Lineage: 3a207e2c-ca58-402f-94cf-3a9e514fe263
Keep the Skills view toggle anchored correctly after skill enablement on mobile and desktop.
- add relative positioning to the Skills view toggle wrapper so the hidden input stays aligned with its label
- expand the CSS regression test to verify the hidden input anchoring contract and checked-toggle geometry selectors
Files changed:
packages/dashboard/app/components/SkillsView.css | 1 +
.../components/__tests__/SkillsView.css.test.ts | 30 +++++++++++++++++++---
2 files changed, 28 insertions(+), 3 deletions(-)
Fusion-Task-Id: FN-5910
Fusion-Task-Lineage: d5988ddb-febe-4319-bfef-d0dbc37909ba
Keep mobile discovered-skill rows aligned after toggles and skill enablement.
- keep .skills-view-item rows from wrapping at the mobile breakpoint
- let .skills-view-item-info flex instead of forcing full-width stacking
- add CSS regression coverage for the mobile row layout and toggle geometry
- add component coverage that preserves row structure across enabled and disabled toggle states
Files changed:
packages/dashboard/app/components/SkillsView.css | 5 ++-
.../components/__tests__/SkillsView.css.test.ts | 49 ++++++++++++++++++++++
.../app/components/__tests__/SkillsView.test.tsx | 47 +++++++++++++++++++++
.../__tests__/skills-view-mobile.test.tsx | 9 ++--
4 files changed, 104 insertions(+), 6 deletions(-)
Fusion-Task-Id: FN-5903
Fusion-Task-Lineage: 1004a702-28e7-4e7e-af22-591cc122be01
Keep MissionManager mission interview state and detail rendering in sync while stabilizing the failing test coverage.
- reload assertion-linked feature data when mission details or milestone panels load
- keep selected mission detail state synchronized after mission update events instead of forcing a full mission reload
- hide the sidebar edit form while the selected mission is already being edited in the detail pane
- add a non-destructive Send to background action for resume-launched mission interview modals
- tighten MissionManager tests to target the detail pane and slice-scoped controls that now render alongside sidebar content
Files changed:
docs/missions.md | 2 +-
.../app/components/MissionInterviewModal.tsx | 30 ++++++++
.../dashboard/app/components/MissionManager.tsx | 77 +++++++++++--------
.../components/__tests__/MissionManager.test.tsx | 88 +++++++++++++++-------
4 files changed, 137 insertions(+), 60 deletions(-)
Fusion-Task-Id: FN-5895
Fusion-Task-Lineage: d018a945-33a7-4471-9636-35bc36dc88a9