TaskStore shutdown now tears down its cached plugin store to avoid leaking plugin database handles.
- Dispose the cached PluginStore during TaskStore.close(), clear the cache, and remove listeners before closing.
- Keep close idempotent when no plugin store was created or after a prior teardown.
- Add regression coverage for direct TaskStore.close() and disk-backed harness reopen lifecycle.
Files changed:
.../src/__tests__/store-plugin-store-close.test.ts | 63 ++++++++++++++++++++++
packages/core/src/store.ts | 15 ++++++
2 files changed, 78 insertions(+)
Fusion-Task-Id: FN-7005
Fusion-Task-Lineage: fe2242d8-7004-4d29-904d-58ee77861d99
Stabilize @fusion/core tests by resetting stale plugin-store database handles and aligning fixture assertions.
- Add a PluginStore close method that disposes local and central database connections.
- Reset the lazy plugin store before the shared test harness clears global settings storage.
- Cover plugin-store reopening from the built-in workflow harness.
- Assert the runtime FN task-prefix fallback without requiring serialized defaults.
Files changed:
packages/core/src/__tests__/builtin-workflows.test.ts | 6 ++++++
packages/core/src/__tests__/store-test-helpers.ts | 8 ++++++++
packages/core/src/__tests__/test-project.test.ts | 8 +++++++-
packages/core/src/plugin-store.ts | 12 ++++++++++++
4 files changed, 33 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-7003
Fusion-Task-Lineage: ec4d6e45-61ea-4e6a-b296-3af3acf7ba4b
Remove the stale branch reattachment affordance from Task Detail while preserving self-healing as the recovery path.
- Remove unused rebind banner styles and mobile action-shell rules.
- Drop stale recoverBranchBinding mocks from TaskDetailModal tests.
- Add rendering coverage proving Task Detail and embedded content do not show reattachment affordances across missing, populated, workspace, and mobile branch states.
- Add a patch changeset for the published Fusion package.
Files changed:
.changeset/fn-6983-task-detail-rebind-warning.md | 7 ++
.../dashboard/app/components/TaskDetailModal.css | 42 +-----------
.../TaskDetailModal.create-pr-e2e.test.tsx | 1 -
.../TaskDetailModal.create-pr-integration.test.tsx | 1 -
.../__tests__/TaskDetailModal.rendering.test.tsx | 80 ++++++++++++++++++++++
.../__tests__/TaskDetailModal.test-helpers.ts | 1 -
6 files changed, 88 insertions(+), 44 deletions(-)
Fusion-Task-Id: FN-6983
Fusion-Task-Lineage: 1a45c38e-f7d0-4df7-94cf-7d1309758e0d
Ensure mobile Missions exits detail tabs back to the mission list before outer navigation.
- Track mobile detail visibility instead of selected mission IDs when adding navigation entries.
- Avoid duplicate history entries for Structure/Activity tab switches and mission refreshes.
- Cover browser back and visible Back button behavior across mobile tabs while desktop stays unchanged.
- Add a patch changeset for the published Fusion package.
Files changed:
.changeset/fn-6998-mobile-mission-back.md | 7 ++
.../dashboard/app/components/MissionManager.tsx | 35 +++++--
.../__tests__/MissionManager.swipe-back.test.tsx | 114 ++++++++++++++++++---
3 files changed, 131 insertions(+), 25 deletions(-)
Fusion-Task-Id: FN-6998
Fusion-Task-Lineage: d3dbf3b7-0195-498f-a57f-ed83c6a422e7
Fix 6 failing tests caused by intentional source changes that landed
without updating dependent test assertions:
- Core test-project: taskPrefix default changed from "FN" to undefined
(commit 800f845e1, derived from project name at runtime)
- Dashboard ScriptsModal.css: replace banned --text-primary with --text
- CLI package-config: update expected pi dep version ^0.79.1 -> ^0.79.9
- CLI skill-sync: document 4 new engine tools in engine-tools.md
- CLI version: update expected release:version script to include
run-ci-distill.mjs
- CLI bundled-plugin-freshness: rebuild stale dist directories
## Summary
Running more than one fusion process on a host (multiple dashboards/CLIs
across worktrees, all attaching `~/.fusion/fusion-central.db`) could
crash a `node` process at random — instantly, with no JS stack and
nothing in the logs. This happened 3 times in 3 days on one machine.
After this change those processes coexist without crashing.
The crash was an OS-level `SIGBUS` (`EXC_BAD_ACCESS`, `FS pagein error`
/ kernel `cluster_pagein past EOF`) inside SQLite's `walIndexReadHdr`.
In WAL mode every connection coordinates through a memory-mapped `-shm`
wal-index; on macOS/APFS, when one process resizes/rebuilds that file
during a checkpoint while another has it mmap'd, the reader faults on
the now-out-of-bounds page. A hardware memory fault can't be caught by
`node:sqlite` or JS, so the whole process dies.
The fix switches the central DB to `journal_mode = DELETE` (rollback
journal), which uses no `-shm` memory map and coordinates cross-process
access via POSIX byte-range locks instead — removing the faulting
surface entirely while keeping multi-process access. The existing
`busy_timeout` absorbs the writer serialization that DELETE mode trades
for WAL's reader/writer concurrency. Per-project DBs (`db.ts`) are
intentionally left on WAL: they're single-process-per-project and don't
hit this cross-process fault. SQLite migrates the existing WAL database
on first open (checkpoints `-wal` into the main file and removes
`-wal`/`-shm`), so there is no data loss.
## Test plan
- New regression tests in `central-db.test.ts` assert the central DB
reports `journal_mode = delete` (not `wal`) and that **no `-shm`
wal-index file is ever created** even after write traffic — i.e. the
exact faulted surface is gone.
- All 6 central-DB suites pass (221 tests); `@fusion/core` typechecks
clean.
---
[](https://github.com/EveryInc/compound-engineering-plugin)

<!-- stage-review-badge-begin -->
---
<a href="https://stagereview.app/Runfusion/Fusion/pull/1752">
<picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://stagereview.app/assets/gh-open-in-stage-dark.svg">
<img src="https://stagereview.app/assets/gh-open-in-stage-light.svg"
alt="Open in Stage">
</picture>
</a>
<!-- stage-review-badge-end -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved stability when multiple dashboards or CLIs run on the same
machine.
* Switched the local database to a safer journaling mode to reduce rare
crash issues on macOS/APFS.
* Prevented creation of extra database side files during normal
operation, while keeping data durability and lock-based coordination in
place.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Verify the WAL->DELETE journal-mode switch instead of discarding exec()'s
result. During a rolling upgrade a lingering WAL holder blocks the exclusive
lock the switch needs, so SQLite either throws SQLITE_BUSY or no-ops and
returns "wal". Capture both outcomes and warn loudly so the residual -shm
SIGBUS surface is observable, rather than silently swallowed.
- Do not rethrow: the condition is transient and self-healing (the next start
after the last WAL holder exits migrates cleanly); hard-failing would make the
central DB unopenable during the very upgrade window it describes.
- Add a migration-path regression test (a WAL holder blocking the switch) that
the prior fresh-DB-only tests did not cover.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The central DB (~/.fusion/fusion-central.db) is opened concurrently by every
fusion process on a host. In WAL mode those connections coordinate through a
memory-mapped `-shm` wal-index; on macOS/APFS a reader takes a SIGBUS
(walIndexReadHdr / `cluster_pagein past EOF`) when another process resizes it
mid-checkpoint, killing the node process with no JS stack or log. Observed 3x
in 3 days. Switch the central DB to journal_mode=DELETE, which uses no `-shm`
mmap and coordinates cross-process access via POSIX byte-range locks instead;
busy_timeout absorbs the added writer serialization. Per-project DBs keep WAL.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
local-runtime.ts dynamically imports @fusion/engine, but it was missing from the
esbuild externals list (only @fusion/core and @fusion/dashboard were there). esbuild
followed the import and tried to bundle engine's transitive node-pty native .node
binaries, failing with "No loader is configured for .node files" — which broke every
desktop Windows EXE and macOS DMG build leg. Externalize @fusion/engine like the other
workspace packages; it resolves from node_modules at runtime.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a GitHub issue and pull request picker that seeds new task prompts from detected remotes.
- Add remote-aware GitHub issue/PR selection to the New Task modal.
- Generate focused task descriptions for selected issues and pull requests while confirming before replacing user text.
- Style and document the compact picker and cover loading, errors, remote selection, and overwrite behavior in tests.
- Add a changeset for the published Fusion CLI package.
Files changed:
.changeset/fn-6946-github-reference-picker.md | 7 +
docs/dashboard-guide.md | 2 +
packages/dashboard/app/components/NewTaskModal.css | 53 ++++
packages/dashboard/app/components/NewTaskModal.tsx | 297 ++++++++++++++++++++-
.../app/components/__tests__/NewTaskModal.test.tsx | 199 +++++++++++++-
5 files changed, 555 insertions(+), 3 deletions(-)
Fusion-Task-Id: FN-6946
Fusion-Task-Lineage: e871827c-dfe5-4fc3-a525-c1161639d306
Mobile bottom navigation now keeps balanced horizontal spacing without disturbing existing viewport compensation.\n\n- Add tokenized inline padding to the fixed mobile nav bar while preserving ICB and safe-area behavior.\n- Cover symmetric side spacing in mobile nav CSS and component layout tests.\n- Add a patch changeset for the published CLI package.\n\nFiles changed:\n .changeset/fn-6999-mobile-nav-side-spacing.md | 7 +++++++\n packages/dashboard/app/__tests__/mobile-nav-bar-css.test.ts | 10 ++++++++++\n packages/dashboard/app/components/MobileNavBar.css | 5 +++++\n .../dashboard/app/components/__tests__/MobileNavBar.test.tsx | 8 ++++++++\n 4 files changed, 30 insertions(+)
Fusion-Task-Id: FN-6999
Fusion-Task-Lineage: 91bd2174-8e5d-4227-a035-ff621e309719
Reclaims task detail padding so inline diffs have more readable width on compact screens.
- Expand the compact Changes file list to consume detail-body padding without page overflow.
- Add mobile breakpoint coverage that matches the detail-body padding contract.
- Add regression tests for the phone-width inline diff surface and CSS rules.
- Add a patch changeset for the published Fusion CLI package.
Files changed:
.changeset/fn-6997-diff-panel-width.md | 7 ++
.../dashboard/app/components/TaskChangesTab.css | 20 ++++-
.../components/__tests__/TaskChangesTab.test.tsx | 98 +++++++++++++++++++++-
3 files changed, 121 insertions(+), 4 deletions(-)
Fusion-Task-Id: FN-6997
Fusion-Task-Lineage: a7f21c0d-89a8-430e-a84c-341a10af4a4a
Align the Quick Chat and Terminal footer launchers so they read as matching peer controls.
- Inherit the footer font and color contract for the Terminal footer launcher.
- Preserve usable hover, focus, padding, and scripts chevron behavior in the footer variant.
- Document the footer Quick Chat launcher placement and add release notes.
- Expand status bar tests to lock the shared footer launcher styling.
Files changed:
.changeset/fn-6959-footer-launcher-style.md | 7 ++
docs/dashboard-guide.md | 2 +-
.../dashboard/app/components/ExecutorStatusBar.css | 2 +-
.../dashboard/app/components/TerminalLauncher.css | 37 +++++++-
.../__tests__/ExecutorStatusBar.test.tsx | 105 +++++++++++++++++++--
5 files changed, 138 insertions(+), 15 deletions(-)
Fusion-Task-Id: FN-6959
Fusion-Task-Lineage: 539307cb-dc81-441f-8baf-8823826e2195
From the multi-agent /ce-code-review of PR #1749 (no P0/P1 correctness bugs; these
are perf, race-hardening, and convention fixes):
- P1 (perf/reliability): the workspace diff ran git subprocesses serially per
sub-repo AND per file — an N×M explosion with no aggregate cap. Add a bounded
mapWithConcurrency helper (order-preserving) and parallelize the per-file patch
loop (cap 8) and the per-sub-repo loop (cap 4). Deleted files still fetch their
patch (skipping it would drop deletes from /file-diffs and zero /diff stats).
- P2 (frontend race): GitManagerModal's workspace-detection could be clobbered by
a previous project's in-flight fetch on a rapid projectId switch / close-reopen.
Add a detectionGenerationRef guard — only the latest detection run may mutate
state; the effect cleanup bumps the generation to abandon superseded runs.
- P2 (DRY): reuse the existing parseStatusCode instead of re-inlining the
status-code mapping.
- P2 (convention): FNXC-tag the new functions/branches per CLAUDE.md.
- P3: extract DIFF_TIMEOUT_MS/FILE_DIFFS_TIMEOUT_MS constants, drop a dead
catch-assignment, note the done-fallback oldPath limitation.
Tests: order-preservation after parallelization; rapid-project-switch generation
guard (a stale workspace verdict must not suppress a new project's real error).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Changes / Files-changed tab showed nothing for multi-repo workspace tasks:
the task-diff backend is single-repo throughout, and a workspace task has null
task.worktree/task.branch (its per-repo state lives in workspaceWorktrees), so
every path fell back to git-diff against the non-git workspace root → empty.
Backend (register-session-diff-routes): extract the single-repo per-worktree
detailed-diff into one shared helper (computeWorktreeDetailedFiles) and add a
workspace branch to BOTH /tasks/:id/diff and /tasks/:id/file-diffs that runs
before the single-repo logic: iterate sorted workspaceWorktrees, compute each
sub-repo's diff in its own live worktree against that repo's baseCommitSha (done
tasks fall back to the per-repo landed range in the sub-repo root), and aggregate
with `${repoRel}/`-prefixed paths. Single-repo behavior is byte-for-byte
preserved (renamed→modified fold retained; 58 existing diff-route tests pass).
Frontend: TaskChangesTab takes an isWorkspace prop and no longer shows the
single-repo "No worktree available" empty state for workspace tasks;
TaskDetailModal passes isWorkspace={isWorkspaceTask(workingTask)}.
Tests: backend aggregation (repo-prefixed paths + stats) and frontend rendering
of workspace changes instead of the empty state.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>