- Add shared startup model sync helper and integrate it into dashboard, serve, and daemon command startup flows
- Introduce opencode-go model sync setting in core schema/types and expose it in dashboard settings UI
- Add CLI regression tests covering startup model sync behavior and command wiring
- Document the new startup model sync setting and related CLI behavior updates
Fusion-Task-Id: FN-3227
Combined both branches: TaskStore import from main + rmSync import
from our branch (needed for fresh DB test cleanup).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- task.test.ts: save/delete GITHUB_REPOSITORY env before
runTaskPrCreate fallback test so CI env doesn't bypass the
getCurrentRepo code path
- app.test.tsx: increase waitForFrameContains timeout for ASCII QR
render from 3s to 6s to accommodate slower CI environments
- remote-auth.test.ts: switch createRemoteSettings default from
tailscale to cloudflare with a static ingressUrl so
resolveRemoteBaseUrl doesn't 409 when no tunnel is running
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Documents research recovery semantics in the CLI reference and settings reference, adding 9 lines of documentation across both files.
Fusion-Task-Id: FN-3014
The merge lands the mesh configuration system (FN-3111) with type definitions, a `MeshConfigGenerator` service using a new `DockerClientService.recreateContainer()` method, and backend API routes for managing Docker-based mesh nodes. It also adds a "New Chat" button to the ChatView header on desktop
Fusion-Task-Id: FN-3111
Adds hardening logic to the bundled-plugin-install command to detect stale path or version conditions, with comprehensive tests covering those edge cases. Also includes a minor update and test coverage for the provider-auth command.
Fusion-Task-Id: FN-3318
Enriched agent heartbeat callbacks with a `reason` parameter propagated through the engine, in-process runtime, and dashboard components (AgentDetailView, AgentListModal, AgentsView). Added a new `agentHealth.tsx` utility and corresponding test file to surface the reason in UI health status, with te
Fusion-Task-Id: FN-3319
Merged the three-step FN-3239 feature: auto-installing the dependency graph plugin on first run across the `daemon`, `dashboard`, and `serve` commands, with the core logic centralized in `bundled-plugin-install.ts`, bundling configuration in `tsup.config.ts`, and a documentation file for the default
Fusion-Task-Id: FN-3239
The merge brings in a fix (FN-2998) that scopes the bottom safe-area padding in ResearchView to mobile devices only, correcting an over-application of the padding on desktop or larger screens.
Fusion-Task-Id: FN-2998
Two sync hot paths were stalling the dashboard event loop on a periodic
timer:
1. `pgrep -f vitest` ran via `execSync` in `getVitestProcessIds`
(`/api/system-stats`, `/api/kill-vitest`) and `killVitestProcesses`
(TUI memory-pressure check). On a busy machine pgrep walking the
process table can take 100ms+; execSync blocks the entire Node event
loop for that duration, so every concurrent dashboard request hangs
while pgrep runs. The TUI variant fired on every memory-pressure tick
(~2s when over threshold), the dashboard variant fired on every
system-stats poll (5s while the modal is open). Both now use execFile
with a callback wrapped in a Promise.
2. `discoverDashboardPiExtensions` (called from 3 /api/settings/pi-
extensions routes) did 6+ blocking existsSync/readFileSync calls per
invocation across legacy and fusion settings paths. Converted to
fs.promises.readFile/access and parallelized via Promise.all.
Behavior preserved:
- TUI memory-pressure detection still works (sync os.totalmem path
unchanged); auto-kill still fires on threshold breach.
- The `lastAutoKillAt` 30s re-fire gate is set before the async kill
starts, so concurrent ticks can't trigger duplicate kills.
- system-stats still polls every 5s while the modal is open and still
returns vitestProcessCount.
- All 7 system-stats / kill-vitest tests pass; all 6 settings/pi-
extensions tests pass. Test mocks updated for the (err, stdout, stderr)
callback signature.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merges FN-3183/FN-3186 (priority picker in quick-entry box) and FN-3189 (CLI slow-lane test gating and CI lane) into the codebase. The quick-entry box gains inline priority selection, while the test suite introduces explicit slow/pre-release lane classification and a corresponding CI gate in the wor
Fusion-Task-Id: FN-3189
Enable xterm SGR mouse reporting in the dashboard TUI and dispatch
wheel events to the focused pane: task detail logs, Git lists
(commits/branches/worktrees), and Files view (tree or preview).
Mouse mode is enabled after Ink mounts so the leading ESC of wheel
reports never arrives alone — avoiding spurious Esc keypresses. We
omit motion-tracking modes so terminals still own drag gestures and
Shift+drag native text selection keeps working.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This merge lands four features: a `/clear` command for Chat and Quick Chat with session banner fixes (FN-3062), a todo view redesign with restructured rows and improved styling (FN-3063), deterministic peer exchange shutdown with dashboard improvements (FN-3040), and a summary Q&A disclosure feature
Fusion-Task-Id: FN-3078
This merge lands seven features and fixes across the dashboard and engine. Notable changes: restructured TodoView rows with improved action row styling, added `/clear` command to Chat and QuickChat, persisted session banner dismissals with a hide-banner setting, made peer exchange shutdown determini
Fusion-Task-Id: FN-3040
This merge lands v0.12.0 with two major features: a droid-cli provider integration adding auth routes, status endpoints, and a settings toggle hook for controlling CLI-based authentication, plus a new experimental agent onboarding modal with a create-agent form. The release also stabilizes engine st
Fusion-Task-Id: FN-2981
Merges the FN-2997 research CLI feature (275-line `research` command with routing, error handling, and docs), a droid CLI provider card for onboarding, a consolidated mock helpers module shared across CLI/dashboard/engine, the SSE architecture reference documentation, and the droid CLI probe module
Fusion-Task-Id: FN-2997
The merge consolidates mock helpers across packages by creating a new shared `mockCoreEngine.ts` in the CLI package and strengthening the core/engine helpers, then migrating both CLI command tests and the dashboard's `AgentsView` tests to use the canonical helpers. It also publishes SSE architecture
Fusion-Task-Id: FN-3053
Exports the research settings resolver from `@fusion/core` types to fix dashboard alias builds, ensuring the resolver is available when imported through the dashboard's module alias configuration.
Fusion-Task-Id: FN-2995
Each agent now gets its own .fusion/agents/<id>/HEARTBEAT.md procedure
file instead of sharing a single project-wide file. A one-shot
migration in AgentStore.init() re-points existing agents off the legacy
shared path and copies the legacy file's contents into each agent's
new per-agent location so operator edits are preserved.
The HeartbeatTriggerScheduler now phase-aligns the first tick to
lastHeartbeatAt + intervalMs so a process restart resumes each agent's
existing schedule rather than waiting up to a full interval before
firing again. Overdue ticks fire promptly within a small jitter window
to avoid a thundering herd at boot.
Also fixes three pre-existing QuickChatFAB test failures introduced by
739e899b5: auto-select default model now switches to model mode whether
or not agents are present, the model tag only renders in model mode,
and one test scopes its option lookup to role="option" to disambiguate
the in-header tag from the dropdown entry.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The TUI splash/footer and the dashboard /api/health + /api/updates/check
each had their own walk-up resolver with different rules, so they could
report different versions and trigger spurious update-available banners.
Dashboard now uses a direct ancestor walk (matching the TUI's old logic)
and only falls back to the sibling-cli probe for dashboard-source dev
mode; logo.ts delegates to it so there is one source of truth.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Between 100-175 cols the remote URL pushed the logo/tabs offscreen.
Remote info now sits in a flex-shrinkable, right-justified slot that
truncates. Also paints a solid background on the QR overlay.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
In PR-mode, processPullRequestMergeTask called gh pr create --head
fusion/<task-id> without ever pushing the branch to origin. PR creation
failed and the task stalled in in-review — and combined with the
recover-mergeable-review sweep bug, the stalled task got force-merged
locally instead. Push the branch via git push -u origin <branch>
immediately before createPr (skipped when an existing PR already covers
the branch).
Also remove the dead autoCreatePr setting: defined as a default in the
schema and Settings type but never read anywhere.
Related to https://github.com/Runfusion/Fusion/issues/21
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Replace placeholder /remote/qr SVG (URL drawn as text) with real QR
rendered via the qrcode package; add format=terminal returning ASCII
QR for the TUI.
* Resolve the public tailscale funnel URL from captured CLI output
instead of constructing http://<hostname>:<port> from a configured
hostname label — that label was never used by `tailscale funnel` and
produced a non-public URL in the auth/QR link.
* Drop hostname requirement from engine + UI; only target port matters.
* Tighten tailscale parseReadiness to require a URL on the matched line
so the tunnel manager doesn't lock in `running` before the URL line.
* TUI: poll remote status, show ● tunnel indicator + URL in MainHeader,
bind Ctrl+Q to a global QR overlay (terminal ASCII), and switch the
in-Settings K shortcut to render the same ASCII QR.
* Auto-poll remote status in the dashboard while in `starting`/`stopping`
so the UI flips to running without reopening the modal.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Why: at ≥150 cols Stats was lifted next to Logs but Utilities/Settings
sat in a separate bottom row. Keep them stacked under Stats in the left
column so Logs gets the full height on the right; Stats flex-grows to
absorb leftover space while Utilities/Settings stay at fixed heights.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The [c] copy handler was writing a success/failure log entry to the
buffer, but in expanded mode the panel hides the buffer so users got no
indication the copy ran. Add a transient inline "Copied!" flash in both
list and expanded views, and clamp the index to match the display
cursor so the copy never silently misses.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 now jumps to Stats and 4 to Utilities, matching the documented
"System/Logs/Stats/Utilities/Settings" order. PANEL_ORDER updated so
prev/next cycle navigation follows the same sequence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pin the Token chip after URL in the System panel so it stays visible
(wrapping to a new row at narrow widths) instead of being pushed off-panel.
Switch system memory readings to os.availableMemory() so macOS no longer
reports ~96% used by ignoring reclaimable inactive/cached pages.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>