chore(release): v0.23.0

Version bump via changesets.
This commit is contained in:
gsxdsm
2026-05-06 22:47:53 -07:00
parent 3701867f9d
commit e9b0aa48de
77 changed files with 685 additions and 370 deletions

View File

@@ -1,7 +0,0 @@
---
"@runfusion/fusion": patch
---
Make the agent error details modal taller on mobile so the full error
message is visible from the top, with the error pre flexing to fill the
available height instead of capping at a small fixed height.

View File

@@ -1,12 +0,0 @@
---
"@runfusion/fusion": patch
---
Stop the dashboard from auto-marking another agent's messages as read when
the user opens them while browsing that agent's mailbox. Previously, viewing
a message in an agent's inbox (e.g. the CEO's mailbox) would call
`POST /messages/:id/read`, which silently consumed the agent's unread state.
The agent's heartbeat would then never see the message as pending, and the
agent's `fn_read_messages` tool (which defaults to `unread_only: true`)
returned nothing. The mark-as-read call now only fires for the dashboard
user's own inbox tab.

View File

@@ -1,10 +0,0 @@
---
"@runfusion/fusion": patch
---
Fix the misleading "X active · Y running" label in the Agents overview
dropdown. Both numbers previously counted agents whose state was either
`active` or `running`, so the "running" tally over-reported by including
idle-but-enabled agents. The label now counts each state distinctly:
"active" reflects only `state === "active"` and "running" reflects only
`state === "running"`.

View File

@@ -1,17 +0,0 @@
---
"@runfusion/fusion": patch
---
Two mobile chat fixes:
1. Tapping the ChatView send button no longer dismisses the soft
keyboard. preventDefault now fires on `pointerdown` for touch
pointers (before iOS blurs the textarea — the synthesized mousedown
it previously relied on fires too late). Click still runs the send
action so quick taps remain reliable.
2. The bottom executor status bar is now hidden on mobile while the
keyboard is open, mirroring `MobileNavBar`. The bar is
`position: fixed` against the layout viewport, which iOS leaves
anchored below the keyboard — during a swipe/pan it would slide
over the message list.

View File

@@ -1,10 +0,0 @@
---
"@runfusion/fusion": patch
---
Fix chat sending silently failing on flaky networks (especially mobile).
The SSE reader in the dashboard client now treats a closed stream without
a terminal `done`/`error` event as an error so streaming state unwinds
instead of getting stuck. The `useChat` and `useQuickChat` hooks also now
show a toast when a message is queued behind an in-flight response, so
the previous stuck state is observable rather than silent.

View File

@@ -1,13 +0,0 @@
---
"@runfusion/fusion": patch
---
Workaround long-standing bug where ChatView's mobile send button only
fired on a long press — quick taps silently did nothing. The previous
implementation used `pointerdown` + `touchstart` with `preventDefault`
and a focus-preservation dance so the keyboard would stay up while
sending; on iOS that path made quick taps fall through entirely. The
button now uses plain `onClick` with `touch-action: manipulation`. The
soft keyboard may dismiss on send, which is a minor UX regression
compared to silent failure. QuickChat is unchanged (it already works
on mobile).

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": patch
---
Fix Codex weekly usage pace calculation when the API returns `reset_at` as epoch milliseconds instead of seconds. The dashboard now parses both formats correctly so weekly reset countdowns and pace status reflect reality.

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": minor
---
Add host support for plugin-registered top-level dashboard views and ship a plugin-first dependency graph view with interactive navigation and project-scoped layout persistence.

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": minor
---
Add native-shell remote connection management across desktop/mobile, including saved server profiles, optional auth token support, and shell-owned connection switching APIs used by dashboard onboarding/connection UI.

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": patch
---
Restore the documented agent lifecycle by removing `terminated` as an agent state again. Agent stop flows now land on `paused`, while heartbeat run history continues to use `terminated` as a run-status value and existing persisted terminated agents migrate to `paused` on startup.

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": patch
---
Fix duplicate ntfy merge notifications by ensuring `ProjectEngine` uses a single `NotificationService` listener graph and passes that shared service into the `NtfyNotifier` compatibility shim.

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": patch
---
Fix bundled runtime plugin settings behavior for fresh installs: bundled Hermes/OpenClaw/Paperclip settings now open without a 404 before install, first save still lazy-installs, missing bundles return explicit server errors, and bundled install entry resolution now prefers workspace source entrypoints over stale build artifacts.

View File

@@ -1,12 +0,0 @@
---
"@runfusion/fusion": patch
---
Fix `scripts/check-test-isolation.mjs` false-failing when `--before` and the
post-run check are invoked from different working directories (e.g. a worktree
recorded the baseline, then the main repo ran the check). The shared baseline
file in `tmpdir()` is now namespaced by a hash of the cwd so concurrent
worktrees don't clobber each other, and protected `.fusion` dirs that were
absent from the baseline are now skipped with a warning instead of being
treated as `{exists: false}` (which previously flagged the entire pre-existing
directory tree as a "test mutation").

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": patch
---
Improve full Chat mobile tool-call cards by keeping collapsed summaries on a single row and tightening spacing for denser scanning without changing expand/collapse behavior.

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": patch
---
Forward engine skill selection into runtime `skills` metadata for all session paths, and improve Hermes runtime behavior so first-turn prompts preserve Fusion system/skill context instead of silently dropping coordination capability hints on non-pi runtime runs.

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": patch
---
Auto-install the bundled Fusion skill when the Hermes runtime plugin loads, including profile-aware Hermes skill-path resolution and safe idempotent replacement behavior. Hermes runtime startup now continues with warnings if skill mirroring fails.

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": patch
---
Fix Claude dashboard OAuth on remote hosts by using the pasted authorization-code flow instead of callback URL rewriting, while preserving callback proxy behavior for providers that still require it.

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": patch
---
Preserve agent inline memory in Agent Companies import/export flows so AGENTS manifests round-trip memory without loss.

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": patch
---
Fix an engine compatibility bug where reviewer/triage/executor runs could fail when a provider extension rejected both `thinking` and `reasoning_effort` together. Fusion now retries without the explicit thinking-level override for that conflict instead of marking the run unavailable.

View File

@@ -1,10 +0,0 @@
---
"@runfusion/fusion": patch
---
Wire `TaskStore` into the runtime's `AgentStore` so the heartbeat auto-claim
path can call `claimTaskForAgent` without warning
`TaskStore not configured for task-claim operations`. The `InProcessRuntime`
previously built its `AgentStore` with only `rootDir`, which left task-claim,
checkout, and release operations unconfigured even though the runtime had a
`TaskStore` available.

View File

@@ -1,9 +0,0 @@
---
"@runfusion/fusion": patch
---
Manual heartbeat runs (POST /api/agents/:id/runs) now respond as soon
as the run record is created instead of blocking on the full
executeHeartbeat call. Long-running heartbeats no longer cause the
dashboard to surface "Failed to start heartbeat run: load failed" when
the client socket times out before the run completes.

View File

@@ -1,9 +0,0 @@
---
"@runfusion/fusion": patch
---
Convert the heartbeat executor's dynamic `import("./agent-session-helpers.js")`
and `import("./session-skill-context.js")` calls to static imports. This makes
missing or partial engine dist surface at module load time (matching the
existing static `pi.js` import) instead of failing mid-heartbeat with a
confusing `ERR_MODULE_NOT_FOUND`.

View File

@@ -1,11 +0,0 @@
---
"@runfusion/fusion": patch
---
Fix merger subject derivation and add a race-rescue layer to the autostash.
The deterministic fallback now prefers the lowest-numbered `complete Step N` headline (or the oldest commit) over the most-recent commit, and the AI subject/body prompts weight by commit theme instead of file size — so a small token-cleanup fixup that touches a large file no longer hijacks the squash-merge subject.
The pre-merge autostash now re-snapshots the working tree after the primary stash is persisted but before `git reset --hard` runs, capturing any dirty paths that landed between the initial snapshot and the destructive wipe (concurrent dev edits during a long merger run, parallel merger runs interleaving, or late test/build artifacts) into a separate `race-rescue` stash so they're recoverable from `git stash list`.
Adds an advisory `.git/.fusion-merger-active.json` written for the duration of each merger run (taskId, pid, hostname, startedAt) so dashboards / status lines / pre-Edit hooks can surface that `rootDir` is volatile. Not a lock — dev edits are never blocked. Race-rescue stashes are now also surfaced on the task feed via `store.logEntry` with the recovery command, instead of only appearing as a `mergerLog.warn`. `resetMergeWithWarn` now wraps each `git reset --merge` in a snapshot-before/after observer so any silent wipe of unrelated dirty paths emits an actionable warning instead of going unnoticed. Exports `readActiveMergerStatus(rootDir)` for consumers.

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": patch
---
Fix race-rescue stash duplicating the primary autostash. `git add -A && git stash create` registers a stash commit but does not clean the working tree, so the rescue loop's subsequent `snapshotDirtyFiles` saw the same files the primary stash already captured and stashed them again on every merger run. Now the rescue diffs current dirty paths against the primary stash's recorded path set and only rescues paths that weren't already captured, plus a tree-SHA equality check that drops any rescue whose tree exactly matches the primary.

View File

@@ -1,10 +0,0 @@
---
"@runfusion/fusion": patch
---
Address code-review findings on the merger autostash work:
- `parsePorcelainZ` now correctly handles rename/copy entries (`R` / `C` status), which emit two NUL-separated entries for one logical change. Previously the old name was treated as an independent dirty path, causing `runObservedDestructiveSyncOp` to emit spurious "cleared N path(s)" warnings whenever a rename was in flight.
- The race-rescue loop in `stashUnrelatedRootDirChanges` now runs `git reset` between attempts so each `git add -A` starts from a clean index, preventing iteration-2+ stashes from drifting due to stale staging rather than genuine new writes.
- `writeActiveMergerStatus` now writes the advisory file via temp-path + atomic `renameSync` so dashboard readers can't observe a partial write.
- `deriveDeterministicSubjectSummary`'s Step regex switched from `[—\-:]` to `(?:—|-|:)` — same matches, but the em-dash intent is obvious to anyone auditing.

View File

@@ -1,18 +0,0 @@
---
"@runfusion/fusion": patch
---
Reduce redundant test/build runs during merge verification:
- **Skip the verification re-run after a no-op in-merge fix.** When the fix
agent doesn't actually modify the working tree (compared via a git
`diff HEAD` + `status --porcelain` content fingerprint), there's nothing
new to verify. The merger now logs "fix agent made no changes — skipping
verification re-run" and records the attempt as failed without paying the
multi-minute test/build cost.
- **Skip `pnpm install --frozen-lockfile` when the lockfile hash hasn't
changed since the last successful install.** A `node_modules/.fusion-install-marker`
file records the lockfile SHA-256 after a successful install; subsequent
merge attempts in the same worktree skip install when the lockfile content
is unchanged, even when `package.json` is staged. Existing
`shouldSyncDependenciesForMerge` filtering still applies as a first gate.

View File

@@ -1,7 +0,0 @@
---
"@runfusion/fusion": minor
---
Add plugin-managed binary installation/setup lifecycle. Plugins can now declare
setup hooks (check, install, uninstall) for required binaries/runtimes. Dashboard
API and CLI commands support checking setup status and triggering install/uninstall.

View File

@@ -1,11 +0,0 @@
---
"@runfusion/fusion": patch
---
Remove the dead `reportDashboardPerf` client and its five call sites in
`App.tsx` / `useProjects.ts`. The companion server route `/_perf/dashboard-load`
no longer exists, so every call was a silently-swallowed 404. Also drops the
`dashboard-perf.log` runtime ignore-list entry from
`scripts/check-test-isolation.mjs` since nothing creates that file anymore.
Console-side perf logging via `console.log("[App] …")` and
`console.log("[useProjects] …")` is preserved.

View File

@@ -1,18 +0,0 @@
---
"@runfusion/fusion": patch
---
Fix a race in the stuck-task requeue path that could clobber a task back to
`todo` (with all step progress reset and worktree torn down) immediately
after `SelfHealingManager.recoverCompletedTasks` had already moved it to
`in-review`. The executor's stuck-kill cleanup ran in `execute()`'s
`finally` block and used a stale captured `task.column` snapshot, so it
would happily overwrite a fresh recovery. The cleanup now re-reads the
latest column and skips entirely when the task has moved past
`in-progress`/`todo`.
Also adds a new setting `preserveProgressOnStuckRequeue` (default: `true`,
toggle in Settings → Engine, near "Stuck Task Timeout"). When enabled, the
stuck detector's requeue passes `{ preserveProgress: true }` to `moveTask`
so completed step statuses survive the bounce and the agent can resume
from where it left off instead of restarting every step from pending.

View File

@@ -1,16 +0,0 @@
---
"@runfusion/fusion": patch
---
Stop inadvertently pausing user-facing tasks during heartbeat-unresponsive
recovery. Adds a `cascadeToTasks` option to `pauseAgent`/`resumeAgent`
(default `true`) and passes `false` from `recoverUnresponsiveAgent` — the
internal pause/resume cycle there is just to set
`pauseReason="heartbeat-unresponsive"` on the agent and shouldn't toggle
the user's task pause state.
Also auto-clears `paused`/`pausedByAgentId` in `updateTask` when the agent
that paused a task is unassigned (or replaced). Previously a task could be
left orphaned-paused with no UI affordance to recover, since the
`Pause/Unpause` action in `TaskDetailModal` is hidden whenever an agent is
assigned.

View File

@@ -1,10 +0,0 @@
---
"@runfusion/fusion": patch
---
Extend `scripts/check-test-isolation.mjs` runtime ignore list to cover live
fusion app paths that previously tripped the merge-time check when a fusion
instance was running on the same HOME during tests: `tasks/`, `messages/`,
`memory-insights.md`, `test-cache.json`, `HEARTBEAT.md`, `kb.db.backup-*`,
and `fusion.db.pre-*` snapshots. Tests still must not write to these paths;
the filter only suppresses noise from a concurrently-running app.

View File

@@ -1,5 +0,0 @@
---
"@runfusion/fusion": patch
---
scripts: make `check-test-isolation` resilient to a concurrently-running fusion app on the same HOME. Filter out paths the live app legitimately writes (databases, agent sessions/memory, plugins, automations, logs, config), sample the baseline over a longer window, and re-sample on suspected violations to avoid false positives during local `pnpm test:isolated`.

View File

@@ -1,20 +0,0 @@
---
"@runfusion/fusion": minor
---
Add a horizontal log split to the TUI's narrow single-pane main view. When
the terminal is too narrow for the multi-pane grid, the bottom of the
screen now shows a live log strip while the top keeps the active section
(System, Stats, Utilities, or Settings). The split is dynamic: the top
pane gets exactly the rows it needs to render its content without
truncating (computed from the System chip wrap at the current width, or
each panel's known row count for Stats/Utilities/Settings), and the log
strip absorbs all remaining rows — maximizing log visibility without
clipping the active section. The split disables itself if the leftover
would give the log strip fewer than 6 rows. Down-arrow shifts sub-focus
into
the strip with the same key bindings as the dedicated logs section
(j/k, Home/G, Enter to expand, w to wrap, c to copy, f to filter).
Up-arrow at the top of the strip returns focus to the main pane; Esc
also exits the split. Right/Left/Tab continue to cycle sections,
including the dedicated full-screen logs view.

View File

@@ -1,12 +0,0 @@
---
"@runfusion/fusion": minor
---
Add a sender-side "wake recipient immediately" override for messages. The
message composer now offers a checkbox (when sending to an agent) that sets
`metadata.wakeRecipient: true` on the message. When honored, the recipient
agent is woken on receipt regardless of their own `messageResponseMode`
setting. To prevent agents from forcing wakes on each other, only
human-originated messages (`fromType: "user"`) trigger the override —
agent-to-agent traffic continues to respect the recipient's configured
behavior.

View File

@@ -1,37 +0,0 @@
---
"@runfusion/fusion": patch
---
Fix worktree collisions when tasks are manually moved into in-progress.
Two related bugs caused two in-progress tasks to share a single
`.worktrees/<name>` directory:
1. The dashboard `POST /tasks/:id/move` route promoted tasks to
in-progress without allocating a fresh worktree path, so a queued
task carrying a stale `worktree` field from a prior
`preserveResumeState` requeue could land in-progress on a directory
already owned by another active task.
2. `TaskStore.moveTask({ preserveResumeState: true })` kept the
worktree pointer on requeue. When the on-disk checkout was later
removed or reassigned, the next dispatch could collide with a
worktree the scheduler had since handed to another task.
Fixes:
- `moveTask` now releases the worktree pointer on every reopen-to-todo
hop. The `branch` field is preserved so the next run reattaches via
`git worktree add <path> <branch>` and resumes any committed
progress. A new `preserveWorktree: true` option opts internal
bounces (workflow-rerun) out of the release so listeners never see
an interim `worktree=null` state.
- `moveTask` accepts an `allocateWorktree` callback that runs under a
cross-task allocation lock in `TaskStore`, building `reservedNames`
from a fresh `listTasks` snapshot so two concurrent moves cannot
pick the same name.
- The manual-move route and the scheduler dispatch path both flow
through the new allocator, sharing the lock.
- `planTaskWorktreePath` is exported from `@fusion/engine` for
consumers that need to plan worktree paths the same way the
scheduler does.

View File

@@ -2,6 +2,297 @@
User-facing release notes aggregated across all packages. This file is auto-synced from each `packages/*/CHANGELOG.md` by `scripts/release.mjs` — do not edit by hand. User-facing release notes aggregated across all packages. This file is auto-synced from each `packages/*/CHANGELOG.md` by `scripts/release.mjs` — do not edit by hand.
## 0.23.0
### @fusion/dashboard
#### Patch Changes
- @fusion/core@0.23.0
- @fusion/engine@0.23.0
- @fusion-plugin-examples/dependency-graph@0.1.12
- @fusion-plugin-examples/droid-runtime@0.1.7
- @fusion-plugin-examples/hermes-runtime@0.2.31
- @fusion-plugin-examples/openclaw-runtime@0.2.31
- @fusion-plugin-examples/paperclip-runtime@0.2.31
### @fusion/engine
#### Patch Changes
- @fusion/core@0.23.0
- @fusion/pi-claude-cli@0.23.0
### @fusion/plugin-sdk
#### Patch Changes
- @fusion/core@0.23.0
### @runfusion/fusion
#### Minor Changes
- 35d5590: Add host support for plugin-registered top-level dashboard views and ship a plugin-first dependency graph view with interactive navigation and project-scoped layout persistence.
- 2b7b922: Add native-shell remote connection management across desktop/mobile, including saved server profiles, optional auth token support, and shell-owned connection switching APIs used by dashboard onboarding/connection UI.
- 8f812e2: Add plugin-managed binary installation/setup lifecycle. Plugins can now declare
setup hooks (check, install, uninstall) for required binaries/runtimes. Dashboard
API and CLI commands support checking setup status and triggering install/uninstall.
- 6e8689a: Add a horizontal log split to the TUI's narrow single-pane main view. When
the terminal is too narrow for the multi-pane grid, the bottom of the
screen now shows a live log strip while the top keeps the active section
(System, Stats, Utilities, or Settings). The split is dynamic: the top
pane gets exactly the rows it needs to render its content without
truncating (computed from the System chip wrap at the current width, or
each panel's known row count for Stats/Utilities/Settings), and the log
strip absorbs all remaining rows — maximizing log visibility without
clipping the active section. The split disables itself if the leftover
would give the log strip fewer than 6 rows. Down-arrow shifts sub-focus
into
the strip with the same key bindings as the dedicated logs section
(j/k, Home/G, Enter to expand, w to wrap, c to copy, f to filter).
Up-arrow at the top of the strip returns focus to the main pane; Esc
also exits the split. Right/Left/Tab continue to cycle sections,
including the dedicated full-screen logs view.
- 8c18b45: Add a sender-side "wake recipient immediately" override for messages. The
message composer now offers a checkbox (when sending to an agent) that sets
`metadata.wakeRecipient: true` on the message. When honored, the recipient
agent is woken on receipt regardless of their own `messageResponseMode`
setting. To prevent agents from forcing wakes on each other, only
human-originated messages (`fromType: "user"`) trigger the override —
agent-to-agent traffic continues to respect the recipient's configured
behavior.
#### Patch Changes
- 9be551b: Make the agent error details modal taller on mobile so the full error
message is visible from the top, with the error pre flexing to fill the
available height instead of capping at a small fixed height.
- 6f46ab0: Stop the dashboard from auto-marking another agent's messages as read when
the user opens them while browsing that agent's mailbox. Previously, viewing
a message in an agent's inbox (e.g. the CEO's mailbox) would call
`POST /messages/:id/read`, which silently consumed the agent's unread state.
The agent's heartbeat would then never see the message as pending, and the
agent's `fn_read_messages` tool (which defaults to `unread_only: true`)
returned nothing. The mark-as-read call now only fires for the dashboard
user's own inbox tab.
- 3e68271: Fix the misleading "X active · Y running" label in the Agents overview
dropdown. Both numbers previously counted agents whose state was either
`active` or `running`, so the "running" tally over-reported by including
idle-but-enabled agents. The label now counts each state distinctly:
"active" reflects only `state === "active"` and "running" reflects only
`state === "running"`.
- 92d40bc: Two mobile chat fixes:
1. Tapping the ChatView send button no longer dismisses the soft
keyboard. preventDefault now fires on `pointerdown` for touch
pointers (before iOS blurs the textarea — the synthesized mousedown
it previously relied on fires too late). Click still runs the send
action so quick taps remain reliable.
2. The bottom executor status bar is now hidden on mobile while the
keyboard is open, mirroring `MobileNavBar`. The bar is
`position: fixed` against the layout viewport, which iOS leaves
anchored below the keyboard — during a swipe/pan it would slide
over the message list.
- d791fa9: Fix chat sending silently failing on flaky networks (especially mobile).
The SSE reader in the dashboard client now treats a closed stream without
a terminal `done`/`error` event as an error so streaming state unwinds
instead of getting stuck. The `useChat` and `useQuickChat` hooks also now
show a toast when a message is queued behind an in-flight response, so
the previous stuck state is observable rather than silent.
- 74378dc: Workaround long-standing bug where ChatView's mobile send button only
fired on a long press — quick taps silently did nothing. The previous
implementation used `pointerdown` + `touchstart` with `preventDefault`
and a focus-preservation dance so the keyboard would stay up while
sending; on iOS that path made quick taps fall through entirely. The
button now uses plain `onClick` with `touch-action: manipulation`. The
soft keyboard may dismiss on send, which is a minor UX regression
compared to silent failure. QuickChat is unchanged (it already works
on mobile).
- c9bbd7d: Fix Codex weekly usage pace calculation when the API returns `reset_at` as epoch milliseconds instead of seconds. The dashboard now parses both formats correctly so weekly reset countdowns and pace status reflect reality.
- a31c432: Restore the documented agent lifecycle by removing `terminated` as an agent state again. Agent stop flows now land on `paused`, while heartbeat run history continues to use `terminated` as a run-status value and existing persisted terminated agents migrate to `paused` on startup.
- 270823d: Fix duplicate ntfy merge notifications by ensuring `ProjectEngine` uses a single `NotificationService` listener graph and passes that shared service into the `NtfyNotifier` compatibility shim.
- a8bfb32: Fix bundled runtime plugin settings behavior for fresh installs: bundled Hermes/OpenClaw/Paperclip settings now open without a 404 before install, first save still lazy-installs, missing bundles return explicit server errors, and bundled install entry resolution now prefers workspace source entrypoints over stale build artifacts.
- 2fce7b3: Fix `scripts/check-test-isolation.mjs` false-failing when `--before` and the
post-run check are invoked from different working directories (e.g. a worktree
recorded the baseline, then the main repo ran the check). The shared baseline
file in `tmpdir()` is now namespaced by a hash of the cwd so concurrent
worktrees don't clobber each other, and protected `.fusion` dirs that were
absent from the baseline are now skipped with a warning instead of being
treated as `{exists: false}` (which previously flagged the entire pre-existing
directory tree as a "test mutation").
- 85381df: Improve full Chat mobile tool-call cards by keeping collapsed summaries on a single row and tightening spacing for denser scanning without changing expand/collapse behavior.
- 8df5d26: Forward engine skill selection into runtime `skills` metadata for all session paths, and improve Hermes runtime behavior so first-turn prompts preserve Fusion system/skill context instead of silently dropping coordination capability hints on non-pi runtime runs.
- 6e38dad: Auto-install the bundled Fusion skill when the Hermes runtime plugin loads, including profile-aware Hermes skill-path resolution and safe idempotent replacement behavior. Hermes runtime startup now continues with warnings if skill mirroring fails.
- cabd6be: Fix Claude dashboard OAuth on remote hosts by using the pasted authorization-code flow instead of callback URL rewriting, while preserving callback proxy behavior for providers that still require it.
- fca8d27: Preserve agent inline memory in Agent Companies import/export flows so AGENTS manifests round-trip memory without loss.
- 3f5d01f: Fix an engine compatibility bug where reviewer/triage/executor runs could fail when a provider extension rejected both `thinking` and `reasoning_effort` together. Fusion now retries without the explicit thinking-level override for that conflict instead of marking the run unavailable.
- 4dc91ed: Wire `TaskStore` into the runtime's `AgentStore` so the heartbeat auto-claim
path can call `claimTaskForAgent` without warning
`TaskStore not configured for task-claim operations`. The `InProcessRuntime`
previously built its `AgentStore` with only `rootDir`, which left task-claim,
checkout, and release operations unconfigured even though the runtime had a
`TaskStore` available.
- 22250eb: Manual heartbeat runs (POST /api/agents/:id/runs) now respond as soon
as the run record is created instead of blocking on the full
executeHeartbeat call. Long-running heartbeats no longer cause the
dashboard to surface "Failed to start heartbeat run: load failed" when
the client socket times out before the run completes.
- a143bcc: Convert the heartbeat executor's dynamic `import("./agent-session-helpers.js")`
and `import("./session-skill-context.js")` calls to static imports. This makes
missing or partial engine dist surface at module load time (matching the
existing static `pi.js` import) instead of failing mid-heartbeat with a
confusing `ERR_MODULE_NOT_FOUND`.
- 923411a: Fix merger subject derivation and add a race-rescue layer to the autostash.
The deterministic fallback now prefers the lowest-numbered `complete Step N` headline (or the oldest commit) over the most-recent commit, and the AI subject/body prompts weight by commit theme instead of file size — so a small token-cleanup fixup that touches a large file no longer hijacks the squash-merge subject.
The pre-merge autostash now re-snapshots the working tree after the primary stash is persisted but before `git reset --hard` runs, capturing any dirty paths that landed between the initial snapshot and the destructive wipe (concurrent dev edits during a long merger run, parallel merger runs interleaving, or late test/build artifacts) into a separate `race-rescue` stash so they're recoverable from `git stash list`.
Adds an advisory `.git/.fusion-merger-active.json` written for the duration of each merger run (taskId, pid, hostname, startedAt) so dashboards / status lines / pre-Edit hooks can surface that `rootDir` is volatile. Not a lock — dev edits are never blocked. Race-rescue stashes are now also surfaced on the task feed via `store.logEntry` with the recovery command, instead of only appearing as a `mergerLog.warn`. `resetMergeWithWarn` now wraps each `git reset --merge` in a snapshot-before/after observer so any silent wipe of unrelated dirty paths emits an actionable warning instead of going unnoticed. Exports `readActiveMergerStatus(rootDir)` for consumers.
- fd7c88c: Fix race-rescue stash duplicating the primary autostash. `git add -A && git stash create` registers a stash commit but does not clean the working tree, so the rescue loop's subsequent `snapshotDirtyFiles` saw the same files the primary stash already captured and stashed them again on every merger run. Now the rescue diffs current dirty paths against the primary stash's recorded path set and only rescues paths that weren't already captured, plus a tree-SHA equality check that drops any rescue whose tree exactly matches the primary.
- e6dc3c7: Address code-review findings on the merger autostash work:
- `parsePorcelainZ` now correctly handles rename/copy entries (`R` / `C` status), which emit two NUL-separated entries for one logical change. Previously the old name was treated as an independent dirty path, causing `runObservedDestructiveSyncOp` to emit spurious "cleared N path(s)" warnings whenever a rename was in flight.
- The race-rescue loop in `stashUnrelatedRootDirChanges` now runs `git reset` between attempts so each `git add -A` starts from a clean index, preventing iteration-2+ stashes from drifting due to stale staging rather than genuine new writes.
- `writeActiveMergerStatus` now writes the advisory file via temp-path + atomic `renameSync` so dashboard readers can't observe a partial write.
- `deriveDeterministicSubjectSummary`'s Step regex switched from `[—\-:]` to `(?:—|-|:)` — same matches, but the em-dash intent is obvious to anyone auditing.
- cd845d3: Reduce redundant test/build runs during merge verification:
- **Skip the verification re-run after a no-op in-merge fix.** When the fix
agent doesn't actually modify the working tree (compared via a git
`diff HEAD` + `status --porcelain` content fingerprint), there's nothing
new to verify. The merger now logs "fix agent made no changes — skipping
verification re-run" and records the attempt as failed without paying the
multi-minute test/build cost.
- **Skip `pnpm install --frozen-lockfile` when the lockfile hash hasn't
changed since the last successful install.** A `node_modules/.fusion-install-marker`
file records the lockfile SHA-256 after a successful install; subsequent
merge attempts in the same worktree skip install when the lockfile content
is unchanged, even when `package.json` is staged. Existing
`shouldSyncDependenciesForMerge` filtering still applies as a first gate.
- 9087239: Remove the dead `reportDashboardPerf` client and its five call sites in
`App.tsx` / `useProjects.ts`. The companion server route `/_perf/dashboard-load`
no longer exists, so every call was a silently-swallowed 404. Also drops the
`dashboard-perf.log` runtime ignore-list entry from
`scripts/check-test-isolation.mjs` since nothing creates that file anymore.
Console-side perf logging via `console.log("[App] …")` and
`console.log("[useProjects] …")` is preserved.
- 0d15916: Fix a race in the stuck-task requeue path that could clobber a task back to
`todo` (with all step progress reset and worktree torn down) immediately
after `SelfHealingManager.recoverCompletedTasks` had already moved it to
`in-review`. The executor's stuck-kill cleanup ran in `execute()`'s
`finally` block and used a stale captured `task.column` snapshot, so it
would happily overwrite a fresh recovery. The cleanup now re-reads the
latest column and skips entirely when the task has moved past
`in-progress`/`todo`.
Also adds a new setting `preserveProgressOnStuckRequeue` (default: `true`,
toggle in Settings → Engine, near "Stuck Task Timeout"). When enabled, the
stuck detector's requeue passes `{ preserveProgress: true }` to `moveTask`
so completed step statuses survive the bounce and the agent can resume
from where it left off instead of restarting every step from pending.
- 7f90308: Stop inadvertently pausing user-facing tasks during heartbeat-unresponsive
recovery. Adds a `cascadeToTasks` option to `pauseAgent`/`resumeAgent`
(default `true`) and passes `false` from `recoverUnresponsiveAgent` — the
internal pause/resume cycle there is just to set
`pauseReason="heartbeat-unresponsive"` on the agent and shouldn't toggle
the user's task pause state.
Also auto-clears `paused`/`pausedByAgentId` in `updateTask` when the agent
that paused a task is unassigned (or replaced). Previously a task could be
left orphaned-paused with no UI affordance to recover, since the
`Pause/Unpause` action in `TaskDetailModal` is hidden whenever an agent is
assigned.
- 593b42e: Extend `scripts/check-test-isolation.mjs` runtime ignore list to cover live
fusion app paths that previously tripped the merge-time check when a fusion
instance was running on the same HOME during tests: `tasks/`, `messages/`,
`memory-insights.md`, `test-cache.json`, `HEARTBEAT.md`, `kb.db.backup-*`,
and `fusion.db.pre-*` snapshots. Tests still must not write to these paths;
the filter only suppresses noise from a concurrently-running app.
- a14ef9e: scripts: make `check-test-isolation` resilient to a concurrently-running fusion app on the same HOME. Filter out paths the live app legitimately writes (databases, agent sessions/memory, plugins, automations, logs, config), sample the baseline over a longer window, and re-sample on suspected violations to avoid false positives during local `pnpm test:isolated`.
- 1100b39: Fix worktree collisions when tasks are manually moved into in-progress.
Two related bugs caused two in-progress tasks to share a single
`.worktrees/<name>` directory:
1. The dashboard `POST /tasks/:id/move` route promoted tasks to
in-progress without allocating a fresh worktree path, so a queued
task carrying a stale `worktree` field from a prior
`preserveResumeState` requeue could land in-progress on a directory
already owned by another active task.
2. `TaskStore.moveTask({ preserveResumeState: true })` kept the
worktree pointer on requeue. When the on-disk checkout was later
removed or reassigned, the next dispatch could collide with a
worktree the scheduler had since handed to another task.
Fixes:
- `moveTask` now releases the worktree pointer on every reopen-to-todo
hop. The `branch` field is preserved so the next run reattaches via
`git worktree add <path> <branch>` and resumes any committed
progress. A new `preserveWorktree: true` option opts internal
bounces (workflow-rerun) out of the release so listeners never see
an interim `worktree=null` state.
- `moveTask` accepts an `allocateWorktree` callback that runs under a
cross-task allocation lock in `TaskStore`, building `reservedNames`
from a fresh `listTasks` snapshot so two concurrent moves cannot
pick the same name.
- The manual-move route and the scheduler dispatch path both flow
through the new allocator, sharing the lock.
- `planTaskWorktreePath` is exported from `@fusion/engine` for
consumers that need to plan worktree paths the same way the
scheduler does.
### runfusion.ai
#### Patch Changes
- Updated dependencies [9be551b]
- Updated dependencies [6f46ab0]
- Updated dependencies [3e68271]
- Updated dependencies [92d40bc]
- Updated dependencies [d791fa9]
- Updated dependencies [74378dc]
- Updated dependencies [c9bbd7d]
- Updated dependencies [35d5590]
- Updated dependencies [2b7b922]
- Updated dependencies [a31c432]
- Updated dependencies [270823d]
- Updated dependencies [a8bfb32]
- Updated dependencies [2fce7b3]
- Updated dependencies [85381df]
- Updated dependencies [8df5d26]
- Updated dependencies [6e38dad]
- Updated dependencies [cabd6be]
- Updated dependencies [fca8d27]
- Updated dependencies [3f5d01f]
- Updated dependencies [4dc91ed]
- Updated dependencies [22250eb]
- Updated dependencies [a143bcc]
- Updated dependencies [923411a]
- Updated dependencies [fd7c88c]
- Updated dependencies [e6dc3c7]
- Updated dependencies [cd845d3]
- Updated dependencies [8f812e2]
- Updated dependencies [9087239]
- Updated dependencies [0d15916]
- Updated dependencies [7f90308]
- Updated dependencies [593b42e]
- Updated dependencies [a14ef9e]
- Updated dependencies [6e8689a]
- Updated dependencies [8c18b45]
- Updated dependencies [1100b39]
- @runfusion/fusion@0.23.0
## 0.22.0 ## 0.22.0
### @fusion/core ### @fusion/core
@@ -3426,6 +3717,14 @@ for reference.
- Updated dependencies [a2ed6d0] - Updated dependencies [a2ed6d0]
- @runfusion/fusion@0.1.0 - @runfusion/fusion@0.1.0
## 0.11.7
### @fusion/droid-cli
#### Patch Changes
- @fusion-plugin-examples/droid-runtime@0.1.7
## 0.11.6 ## 0.11.6
### @fusion/droid-cli ### @fusion/droid-cli

View File

@@ -1,6 +1,6 @@
{ {
"name": "fusion-workspace", "name": "fusion-workspace",
"version": "0.22.0", "version": "0.23.0",
"private": true, "private": true,
"license": "MIT", "license": "MIT",
"homepage": "https://github.com/Runfusion/Fusion#readme", "homepage": "https://github.com/Runfusion/Fusion#readme",

View File

@@ -1,5 +1,46 @@
# runfusion.ai # runfusion.ai
## 0.23.0
### Patch Changes
- Updated dependencies [9be551b]
- Updated dependencies [6f46ab0]
- Updated dependencies [3e68271]
- Updated dependencies [92d40bc]
- Updated dependencies [d791fa9]
- Updated dependencies [74378dc]
- Updated dependencies [c9bbd7d]
- Updated dependencies [35d5590]
- Updated dependencies [2b7b922]
- Updated dependencies [a31c432]
- Updated dependencies [270823d]
- Updated dependencies [a8bfb32]
- Updated dependencies [2fce7b3]
- Updated dependencies [85381df]
- Updated dependencies [8df5d26]
- Updated dependencies [6e38dad]
- Updated dependencies [cabd6be]
- Updated dependencies [fca8d27]
- Updated dependencies [3f5d01f]
- Updated dependencies [4dc91ed]
- Updated dependencies [22250eb]
- Updated dependencies [a143bcc]
- Updated dependencies [923411a]
- Updated dependencies [fd7c88c]
- Updated dependencies [e6dc3c7]
- Updated dependencies [cd845d3]
- Updated dependencies [8f812e2]
- Updated dependencies [9087239]
- Updated dependencies [0d15916]
- Updated dependencies [7f90308]
- Updated dependencies [593b42e]
- Updated dependencies [a14ef9e]
- Updated dependencies [6e8689a]
- Updated dependencies [8c18b45]
- Updated dependencies [1100b39]
- @runfusion/fusion@0.23.0
## 0.22.0 ## 0.22.0
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "runfusion.ai", "name": "runfusion.ai",
"version": "0.22.0", "version": "0.23.0",
"license": "MIT", "license": "MIT",
"description": "Launch Fusion with `npx runfusion.ai` — tiny alias for @runfusion/fusion.", "description": "Launch Fusion with `npx runfusion.ai` — tiny alias for @runfusion/fusion.",
"homepage": "https://runfusion.ai", "homepage": "https://runfusion.ai",

View File

@@ -1,5 +1,228 @@
# @runfusion/fusion # @runfusion/fusion
## 0.23.0
### Minor Changes
- 35d5590: Add host support for plugin-registered top-level dashboard views and ship a plugin-first dependency graph view with interactive navigation and project-scoped layout persistence.
- 2b7b922: Add native-shell remote connection management across desktop/mobile, including saved server profiles, optional auth token support, and shell-owned connection switching APIs used by dashboard onboarding/connection UI.
- 8f812e2: Add plugin-managed binary installation/setup lifecycle. Plugins can now declare
setup hooks (check, install, uninstall) for required binaries/runtimes. Dashboard
API and CLI commands support checking setup status and triggering install/uninstall.
- 6e8689a: Add a horizontal log split to the TUI's narrow single-pane main view. When
the terminal is too narrow for the multi-pane grid, the bottom of the
screen now shows a live log strip while the top keeps the active section
(System, Stats, Utilities, or Settings). The split is dynamic: the top
pane gets exactly the rows it needs to render its content without
truncating (computed from the System chip wrap at the current width, or
each panel's known row count for Stats/Utilities/Settings), and the log
strip absorbs all remaining rows — maximizing log visibility without
clipping the active section. The split disables itself if the leftover
would give the log strip fewer than 6 rows. Down-arrow shifts sub-focus
into
the strip with the same key bindings as the dedicated logs section
(j/k, Home/G, Enter to expand, w to wrap, c to copy, f to filter).
Up-arrow at the top of the strip returns focus to the main pane; Esc
also exits the split. Right/Left/Tab continue to cycle sections,
including the dedicated full-screen logs view.
- 8c18b45: Add a sender-side "wake recipient immediately" override for messages. The
message composer now offers a checkbox (when sending to an agent) that sets
`metadata.wakeRecipient: true` on the message. When honored, the recipient
agent is woken on receipt regardless of their own `messageResponseMode`
setting. To prevent agents from forcing wakes on each other, only
human-originated messages (`fromType: "user"`) trigger the override —
agent-to-agent traffic continues to respect the recipient's configured
behavior.
### Patch Changes
- 9be551b: Make the agent error details modal taller on mobile so the full error
message is visible from the top, with the error pre flexing to fill the
available height instead of capping at a small fixed height.
- 6f46ab0: Stop the dashboard from auto-marking another agent's messages as read when
the user opens them while browsing that agent's mailbox. Previously, viewing
a message in an agent's inbox (e.g. the CEO's mailbox) would call
`POST /messages/:id/read`, which silently consumed the agent's unread state.
The agent's heartbeat would then never see the message as pending, and the
agent's `fn_read_messages` tool (which defaults to `unread_only: true`)
returned nothing. The mark-as-read call now only fires for the dashboard
user's own inbox tab.
- 3e68271: Fix the misleading "X active · Y running" label in the Agents overview
dropdown. Both numbers previously counted agents whose state was either
`active` or `running`, so the "running" tally over-reported by including
idle-but-enabled agents. The label now counts each state distinctly:
"active" reflects only `state === "active"` and "running" reflects only
`state === "running"`.
- 92d40bc: Two mobile chat fixes:
1. Tapping the ChatView send button no longer dismisses the soft
keyboard. preventDefault now fires on `pointerdown` for touch
pointers (before iOS blurs the textarea — the synthesized mousedown
it previously relied on fires too late). Click still runs the send
action so quick taps remain reliable.
2. The bottom executor status bar is now hidden on mobile while the
keyboard is open, mirroring `MobileNavBar`. The bar is
`position: fixed` against the layout viewport, which iOS leaves
anchored below the keyboard — during a swipe/pan it would slide
over the message list.
- d791fa9: Fix chat sending silently failing on flaky networks (especially mobile).
The SSE reader in the dashboard client now treats a closed stream without
a terminal `done`/`error` event as an error so streaming state unwinds
instead of getting stuck. The `useChat` and `useQuickChat` hooks also now
show a toast when a message is queued behind an in-flight response, so
the previous stuck state is observable rather than silent.
- 74378dc: Workaround long-standing bug where ChatView's mobile send button only
fired on a long press — quick taps silently did nothing. The previous
implementation used `pointerdown` + `touchstart` with `preventDefault`
and a focus-preservation dance so the keyboard would stay up while
sending; on iOS that path made quick taps fall through entirely. The
button now uses plain `onClick` with `touch-action: manipulation`. The
soft keyboard may dismiss on send, which is a minor UX regression
compared to silent failure. QuickChat is unchanged (it already works
on mobile).
- c9bbd7d: Fix Codex weekly usage pace calculation when the API returns `reset_at` as epoch milliseconds instead of seconds. The dashboard now parses both formats correctly so weekly reset countdowns and pace status reflect reality.
- a31c432: Restore the documented agent lifecycle by removing `terminated` as an agent state again. Agent stop flows now land on `paused`, while heartbeat run history continues to use `terminated` as a run-status value and existing persisted terminated agents migrate to `paused` on startup.
- 270823d: Fix duplicate ntfy merge notifications by ensuring `ProjectEngine` uses a single `NotificationService` listener graph and passes that shared service into the `NtfyNotifier` compatibility shim.
- a8bfb32: Fix bundled runtime plugin settings behavior for fresh installs: bundled Hermes/OpenClaw/Paperclip settings now open without a 404 before install, first save still lazy-installs, missing bundles return explicit server errors, and bundled install entry resolution now prefers workspace source entrypoints over stale build artifacts.
- 2fce7b3: Fix `scripts/check-test-isolation.mjs` false-failing when `--before` and the
post-run check are invoked from different working directories (e.g. a worktree
recorded the baseline, then the main repo ran the check). The shared baseline
file in `tmpdir()` is now namespaced by a hash of the cwd so concurrent
worktrees don't clobber each other, and protected `.fusion` dirs that were
absent from the baseline are now skipped with a warning instead of being
treated as `{exists: false}` (which previously flagged the entire pre-existing
directory tree as a "test mutation").
- 85381df: Improve full Chat mobile tool-call cards by keeping collapsed summaries on a single row and tightening spacing for denser scanning without changing expand/collapse behavior.
- 8df5d26: Forward engine skill selection into runtime `skills` metadata for all session paths, and improve Hermes runtime behavior so first-turn prompts preserve Fusion system/skill context instead of silently dropping coordination capability hints on non-pi runtime runs.
- 6e38dad: Auto-install the bundled Fusion skill when the Hermes runtime plugin loads, including profile-aware Hermes skill-path resolution and safe idempotent replacement behavior. Hermes runtime startup now continues with warnings if skill mirroring fails.
- cabd6be: Fix Claude dashboard OAuth on remote hosts by using the pasted authorization-code flow instead of callback URL rewriting, while preserving callback proxy behavior for providers that still require it.
- fca8d27: Preserve agent inline memory in Agent Companies import/export flows so AGENTS manifests round-trip memory without loss.
- 3f5d01f: Fix an engine compatibility bug where reviewer/triage/executor runs could fail when a provider extension rejected both `thinking` and `reasoning_effort` together. Fusion now retries without the explicit thinking-level override for that conflict instead of marking the run unavailable.
- 4dc91ed: Wire `TaskStore` into the runtime's `AgentStore` so the heartbeat auto-claim
path can call `claimTaskForAgent` without warning
`TaskStore not configured for task-claim operations`. The `InProcessRuntime`
previously built its `AgentStore` with only `rootDir`, which left task-claim,
checkout, and release operations unconfigured even though the runtime had a
`TaskStore` available.
- 22250eb: Manual heartbeat runs (POST /api/agents/:id/runs) now respond as soon
as the run record is created instead of blocking on the full
executeHeartbeat call. Long-running heartbeats no longer cause the
dashboard to surface "Failed to start heartbeat run: load failed" when
the client socket times out before the run completes.
- a143bcc: Convert the heartbeat executor's dynamic `import("./agent-session-helpers.js")`
and `import("./session-skill-context.js")` calls to static imports. This makes
missing or partial engine dist surface at module load time (matching the
existing static `pi.js` import) instead of failing mid-heartbeat with a
confusing `ERR_MODULE_NOT_FOUND`.
- 923411a: Fix merger subject derivation and add a race-rescue layer to the autostash.
The deterministic fallback now prefers the lowest-numbered `complete Step N` headline (or the oldest commit) over the most-recent commit, and the AI subject/body prompts weight by commit theme instead of file size — so a small token-cleanup fixup that touches a large file no longer hijacks the squash-merge subject.
The pre-merge autostash now re-snapshots the working tree after the primary stash is persisted but before `git reset --hard` runs, capturing any dirty paths that landed between the initial snapshot and the destructive wipe (concurrent dev edits during a long merger run, parallel merger runs interleaving, or late test/build artifacts) into a separate `race-rescue` stash so they're recoverable from `git stash list`.
Adds an advisory `.git/.fusion-merger-active.json` written for the duration of each merger run (taskId, pid, hostname, startedAt) so dashboards / status lines / pre-Edit hooks can surface that `rootDir` is volatile. Not a lock — dev edits are never blocked. Race-rescue stashes are now also surfaced on the task feed via `store.logEntry` with the recovery command, instead of only appearing as a `mergerLog.warn`. `resetMergeWithWarn` now wraps each `git reset --merge` in a snapshot-before/after observer so any silent wipe of unrelated dirty paths emits an actionable warning instead of going unnoticed. Exports `readActiveMergerStatus(rootDir)` for consumers.
- fd7c88c: Fix race-rescue stash duplicating the primary autostash. `git add -A && git stash create` registers a stash commit but does not clean the working tree, so the rescue loop's subsequent `snapshotDirtyFiles` saw the same files the primary stash already captured and stashed them again on every merger run. Now the rescue diffs current dirty paths against the primary stash's recorded path set and only rescues paths that weren't already captured, plus a tree-SHA equality check that drops any rescue whose tree exactly matches the primary.
- e6dc3c7: Address code-review findings on the merger autostash work:
- `parsePorcelainZ` now correctly handles rename/copy entries (`R` / `C` status), which emit two NUL-separated entries for one logical change. Previously the old name was treated as an independent dirty path, causing `runObservedDestructiveSyncOp` to emit spurious "cleared N path(s)" warnings whenever a rename was in flight.
- The race-rescue loop in `stashUnrelatedRootDirChanges` now runs `git reset` between attempts so each `git add -A` starts from a clean index, preventing iteration-2+ stashes from drifting due to stale staging rather than genuine new writes.
- `writeActiveMergerStatus` now writes the advisory file via temp-path + atomic `renameSync` so dashboard readers can't observe a partial write.
- `deriveDeterministicSubjectSummary`'s Step regex switched from `[—\-:]` to `(?:—|-|:)` — same matches, but the em-dash intent is obvious to anyone auditing.
- cd845d3: Reduce redundant test/build runs during merge verification:
- **Skip the verification re-run after a no-op in-merge fix.** When the fix
agent doesn't actually modify the working tree (compared via a git
`diff HEAD` + `status --porcelain` content fingerprint), there's nothing
new to verify. The merger now logs "fix agent made no changes — skipping
verification re-run" and records the attempt as failed without paying the
multi-minute test/build cost.
- **Skip `pnpm install --frozen-lockfile` when the lockfile hash hasn't
changed since the last successful install.** A `node_modules/.fusion-install-marker`
file records the lockfile SHA-256 after a successful install; subsequent
merge attempts in the same worktree skip install when the lockfile content
is unchanged, even when `package.json` is staged. Existing
`shouldSyncDependenciesForMerge` filtering still applies as a first gate.
- 9087239: Remove the dead `reportDashboardPerf` client and its five call sites in
`App.tsx` / `useProjects.ts`. The companion server route `/_perf/dashboard-load`
no longer exists, so every call was a silently-swallowed 404. Also drops the
`dashboard-perf.log` runtime ignore-list entry from
`scripts/check-test-isolation.mjs` since nothing creates that file anymore.
Console-side perf logging via `console.log("[App] …")` and
`console.log("[useProjects] …")` is preserved.
- 0d15916: Fix a race in the stuck-task requeue path that could clobber a task back to
`todo` (with all step progress reset and worktree torn down) immediately
after `SelfHealingManager.recoverCompletedTasks` had already moved it to
`in-review`. The executor's stuck-kill cleanup ran in `execute()`'s
`finally` block and used a stale captured `task.column` snapshot, so it
would happily overwrite a fresh recovery. The cleanup now re-reads the
latest column and skips entirely when the task has moved past
`in-progress`/`todo`.
Also adds a new setting `preserveProgressOnStuckRequeue` (default: `true`,
toggle in Settings → Engine, near "Stuck Task Timeout"). When enabled, the
stuck detector's requeue passes `{ preserveProgress: true }` to `moveTask`
so completed step statuses survive the bounce and the agent can resume
from where it left off instead of restarting every step from pending.
- 7f90308: Stop inadvertently pausing user-facing tasks during heartbeat-unresponsive
recovery. Adds a `cascadeToTasks` option to `pauseAgent`/`resumeAgent`
(default `true`) and passes `false` from `recoverUnresponsiveAgent` — the
internal pause/resume cycle there is just to set
`pauseReason="heartbeat-unresponsive"` on the agent and shouldn't toggle
the user's task pause state.
Also auto-clears `paused`/`pausedByAgentId` in `updateTask` when the agent
that paused a task is unassigned (or replaced). Previously a task could be
left orphaned-paused with no UI affordance to recover, since the
`Pause/Unpause` action in `TaskDetailModal` is hidden whenever an agent is
assigned.
- 593b42e: Extend `scripts/check-test-isolation.mjs` runtime ignore list to cover live
fusion app paths that previously tripped the merge-time check when a fusion
instance was running on the same HOME during tests: `tasks/`, `messages/`,
`memory-insights.md`, `test-cache.json`, `HEARTBEAT.md`, `kb.db.backup-*`,
and `fusion.db.pre-*` snapshots. Tests still must not write to these paths;
the filter only suppresses noise from a concurrently-running app.
- a14ef9e: scripts: make `check-test-isolation` resilient to a concurrently-running fusion app on the same HOME. Filter out paths the live app legitimately writes (databases, agent sessions/memory, plugins, automations, logs, config), sample the baseline over a longer window, and re-sample on suspected violations to avoid false positives during local `pnpm test:isolated`.
- 1100b39: Fix worktree collisions when tasks are manually moved into in-progress.
Two related bugs caused two in-progress tasks to share a single
`.worktrees/<name>` directory:
1. The dashboard `POST /tasks/:id/move` route promoted tasks to
in-progress without allocating a fresh worktree path, so a queued
task carrying a stale `worktree` field from a prior
`preserveResumeState` requeue could land in-progress on a directory
already owned by another active task.
2. `TaskStore.moveTask({ preserveResumeState: true })` kept the
worktree pointer on requeue. When the on-disk checkout was later
removed or reassigned, the next dispatch could collide with a
worktree the scheduler had since handed to another task.
Fixes:
- `moveTask` now releases the worktree pointer on every reopen-to-todo
hop. The `branch` field is preserved so the next run reattaches via
`git worktree add <path> <branch>` and resumes any committed
progress. A new `preserveWorktree: true` option opts internal
bounces (workflow-rerun) out of the release so listeners never see
an interim `worktree=null` state.
- `moveTask` accepts an `allocateWorktree` callback that runs under a
cross-task allocation lock in `TaskStore`, building `reservedNames`
from a fresh `listTasks` snapshot so two concurrent moves cannot
pick the same name.
- The manual-move route and the scheduler dispatch path both flow
through the new allocator, sharing the lock.
- `planTaskWorktreePath` is exported from `@fusion/engine` for
consumers that need to plan worktree paths the same way the
scheduler does.
## 0.22.0 ## 0.22.0
### Minor Changes ### Minor Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@runfusion/fusion", "name": "@runfusion/fusion",
"version": "0.22.0", "version": "0.23.0",
"license": "MIT", "license": "MIT",
"description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.", "description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
"homepage": "https://github.com/Runfusion/Fusion#readme", "homepage": "https://github.com/Runfusion/Fusion#readme",

View File

@@ -1,5 +1,7 @@
# @fusion/core # @fusion/core
## 0.23.0
## 0.22.0 ## 0.22.0
### Minor Changes ### Minor Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion/core", "name": "@fusion/core",
"version": "0.22.0", "version": "0.23.0",
"license": "MIT", "license": "MIT",
"description": "Fusion core: task store, scheduler, settings, and shared domain types backing the Fusion AI coding agent.", "description": "Fusion core: task store, scheduler, settings, and shared domain types backing the Fusion AI coding agent.",
"homepage": "https://github.com/Runfusion/Fusion#readme", "homepage": "https://github.com/Runfusion/Fusion#readme",

View File

@@ -1,5 +1,17 @@
# @fusion/dashboard # @fusion/dashboard
## 0.23.0
### Patch Changes
- @fusion/core@0.23.0
- @fusion/engine@0.23.0
- @fusion-plugin-examples/dependency-graph@0.1.12
- @fusion-plugin-examples/droid-runtime@0.1.7
- @fusion-plugin-examples/hermes-runtime@0.2.31
- @fusion-plugin-examples/openclaw-runtime@0.2.31
- @fusion-plugin-examples/paperclip-runtime@0.2.31
## 0.22.0 ## 0.22.0
### Minor Changes ### Minor Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion/dashboard", "name": "@fusion/dashboard",
"version": "0.22.0", "version": "0.23.0",
"license": "MIT", "license": "MIT",
"description": "Fusion dashboard: React UI and HTTP API server for monitoring and controlling the Fusion AI coding agent.", "description": "Fusion dashboard: React UI and HTTP API server for monitoring and controlling the Fusion AI coding agent.",
"homepage": "https://github.com/Runfusion/Fusion#readme", "homepage": "https://github.com/Runfusion/Fusion#readme",

View File

@@ -1,5 +1,7 @@
# @fusion/desktop # @fusion/desktop
## 0.23.0
## 0.22.0 ## 0.22.0
## 0.21.0 ## 0.21.0

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion/desktop", "name": "@fusion/desktop",
"version": "0.22.0", "version": "0.23.0",
"license": "MIT", "license": "MIT",
"description": "Fusion desktop: Electron wrapper around the Fusion dashboard for macOS, Windows, and Linux.", "description": "Fusion desktop: Electron wrapper around the Fusion dashboard for macOS, Windows, and Linux.",
"homepage": "https://github.com/Runfusion/Fusion#readme", "homepage": "https://github.com/Runfusion/Fusion#readme",

View File

@@ -1,5 +1,11 @@
# @fusion/droid-cli # @fusion/droid-cli
## 0.11.7
### Patch Changes
- @fusion-plugin-examples/droid-runtime@0.1.7
## 0.11.6 ## 0.11.6
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion/droid-cli", "name": "@fusion/droid-cli",
"version": "0.11.6", "version": "0.11.7",
"description": "First-party Fusion pi extension that routes LLM calls through the Droid CLI subprocess.", "description": "First-party Fusion pi extension that routes LLM calls through the Droid CLI subprocess.",
"license": "MIT", "license": "MIT",
"private": true, "private": true,

View File

@@ -1,5 +1,12 @@
# @fusion/engine # @fusion/engine
## 0.23.0
### Patch Changes
- @fusion/core@0.23.0
- @fusion/pi-claude-cli@0.23.0
## 0.22.0 ## 0.22.0
### Minor Changes ### Minor Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion/engine", "name": "@fusion/engine",
"version": "0.22.0", "version": "0.23.0",
"license": "MIT", "license": "MIT",
"description": "Fusion engine: executor, merger, scheduler, and automation runtime for the Fusion AI coding agent.", "description": "Fusion engine: executor, merger, scheduler, and automation runtime for the Fusion AI coding agent.",
"homepage": "https://github.com/Runfusion/Fusion#readme", "homepage": "https://github.com/Runfusion/Fusion#readme",

View File

@@ -1,5 +1,7 @@
# @fusion/mobile # @fusion/mobile
## 0.23.0
## 0.22.0 ## 0.22.0
## 0.21.0 ## 0.21.0

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion/mobile", "name": "@fusion/mobile",
"version": "0.22.0", "version": "0.23.0",
"license": "MIT", "license": "MIT",
"description": "Fusion mobile: Capacitor wrapper around the Fusion dashboard for iOS and Android.", "description": "Fusion mobile: Capacitor wrapper around the Fusion dashboard for iOS and Android.",
"homepage": "https://github.com/Runfusion/Fusion#readme", "homepage": "https://github.com/Runfusion/Fusion#readme",

View File

@@ -1,5 +1,7 @@
# @fusion/pi-claude-cli # @fusion/pi-claude-cli
## 0.23.0
## 0.22.0 ## 0.22.0
## 0.21.0 ## 0.21.0

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion/pi-claude-cli", "name": "@fusion/pi-claude-cli",
"version": "0.22.0", "version": "0.23.0",
"description": "Fusion vendored fork: pi coding-agent extension that routes LLM calls through the Claude Code CLI. Forked from rchern/pi-claude-cli (MIT). See UPSTREAM.md.", "description": "Fusion vendored fork: pi coding-agent extension that routes LLM calls through the Claude Code CLI. Forked from rchern/pi-claude-cli (MIT). See UPSTREAM.md.",
"license": "MIT", "license": "MIT",
"private": true, "private": true,

View File

@@ -1,5 +1,11 @@
# @fusion/plugin-sdk # @fusion/plugin-sdk
## 0.23.0
### Patch Changes
- @fusion/core@0.23.0
## 0.22.0 ## 0.22.0
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion/plugin-sdk", "name": "@fusion/plugin-sdk",
"version": "0.22.0", "version": "0.23.0",
"license": "MIT", "license": "MIT",
"description": "Fusion plugin SDK: types and helpers for authoring third-party plugins that extend the Fusion dashboard and engine.", "description": "Fusion plugin SDK: types and helpers for authoring third-party plugins that extend the Fusion dashboard and engine.",
"homepage": "https://github.com/Runfusion/Fusion#readme", "homepage": "https://github.com/Runfusion/Fusion#readme",

View File

@@ -1,5 +1,11 @@
# @fusion-plugin-examples/auto-label # @fusion-plugin-examples/auto-label
## 0.2.31
### Patch Changes
- @fusion/plugin-sdk@0.23.0
## 0.2.30 ## 0.2.30
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion-plugin-examples/auto-label", "name": "@fusion-plugin-examples/auto-label",
"version": "0.2.30", "version": "0.2.31",
"type": "module", "type": "module",
"description": "Automatically labels tasks based on description content", "description": "Automatically labels tasks based on description content",
"keywords": [ "keywords": [

View File

@@ -1,5 +1,11 @@
# @fusion-plugin-examples/ci-status # @fusion-plugin-examples/ci-status
## 0.2.31
### Patch Changes
- @fusion/plugin-sdk@0.23.0
## 0.2.30 ## 0.2.30
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion-plugin-examples/ci-status", "name": "@fusion-plugin-examples/ci-status",
"version": "0.2.30", "version": "0.2.31",
"type": "module", "type": "module",
"description": "Polls CI status for branches and provides a custom API to query results", "description": "Polls CI status for branches and provides a custom API to query results",
"keywords": [ "keywords": [

View File

@@ -1,5 +1,11 @@
# @fusion-plugin-examples/notification # @fusion-plugin-examples/notification
## 0.2.31
### Patch Changes
- @fusion/plugin-sdk@0.23.0
## 0.2.30 ## 0.2.30
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion-plugin-examples/notification", "name": "@fusion-plugin-examples/notification",
"version": "0.2.30", "version": "0.2.31",
"type": "module", "type": "module",
"description": "Example Fusion plugin that sends webhook notifications on task lifecycle events", "description": "Example Fusion plugin that sends webhook notifications on task lifecycle events",
"keywords": [ "keywords": [

View File

@@ -1,5 +1,11 @@
# @fusion-plugin-examples/settings-demo # @fusion-plugin-examples/settings-demo
## 0.2.31
### Patch Changes
- @fusion/plugin-sdk@0.23.0
## 0.2.30 ## 0.2.30
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion-plugin-examples/settings-demo", "name": "@fusion-plugin-examples/settings-demo",
"version": "0.2.30", "version": "0.2.31",
"type": "module", "type": "module",
"description": "Example Fusion plugin demonstrating settings schema and runtime configuration", "description": "Example Fusion plugin demonstrating settings schema and runtime configuration",
"keywords": [ "keywords": [

View File

@@ -0,0 +1,7 @@
# @fusion-plugin-examples/agent-browser
## 0.1.1
### Patch Changes
- @fusion/plugin-sdk@0.23.0

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion-plugin-examples/agent-browser", "name": "@fusion-plugin-examples/agent-browser",
"version": "0.1.0", "version": "0.1.1",
"type": "module", "type": "module",
"description": "Agent Browser runtime and prompt/skill/workflow contributions for Fusion", "description": "Agent Browser runtime and prompt/skill/workflow contributions for Fusion",
"private": true, "private": true,

View File

@@ -1,5 +1,12 @@
# @fusion-plugin-examples/dependency-graph # @fusion-plugin-examples/dependency-graph
## 0.1.12
### Patch Changes
- @fusion/core@0.23.0
- @fusion/plugin-sdk@0.23.0
## 0.1.11 ## 0.1.11
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion-plugin-examples/dependency-graph", "name": "@fusion-plugin-examples/dependency-graph",
"version": "0.1.11", "version": "0.1.12",
"type": "module", "type": "module",
"description": "Dependency graph dashboard view plugin for Fusion", "description": "Dependency graph dashboard view plugin for Fusion",
"private": true, "private": true,

View File

@@ -1,5 +1,11 @@
# Changelog # Changelog
## 0.1.7
### Patch Changes
- @fusion/plugin-sdk@0.23.0
## 0.1.6 ## 0.1.6
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion-plugin-examples/droid-runtime", "name": "@fusion-plugin-examples/droid-runtime",
"version": "0.1.6", "version": "0.1.7",
"type": "module", "type": "module",
"description": "Droid runtime plugin for Fusion", "description": "Droid runtime plugin for Fusion",
"keywords": [ "keywords": [

View File

@@ -1,5 +1,11 @@
# @fusion-plugin-examples/hermes-runtime # @fusion-plugin-examples/hermes-runtime
## 0.2.31
### Patch Changes
- @fusion/plugin-sdk@0.23.0
## 0.2.30 ## 0.2.30
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion-plugin-examples/hermes-runtime", "name": "@fusion-plugin-examples/hermes-runtime",
"version": "0.2.30", "version": "0.2.31",
"type": "module", "type": "module",
"description": "Hermes AI runtime plugin for Fusion - provides AI agent execution runtime", "description": "Hermes AI runtime plugin for Fusion - provides AI agent execution runtime",
"keywords": [ "keywords": [

View File

@@ -1,5 +1,11 @@
# @fusion-plugin-examples/openclaw-runtime # @fusion-plugin-examples/openclaw-runtime
## 0.2.31
### Patch Changes
- @fusion/plugin-sdk@0.23.0
## 0.2.30 ## 0.2.30
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion-plugin-examples/openclaw-runtime", "name": "@fusion-plugin-examples/openclaw-runtime",
"version": "0.2.30", "version": "0.2.31",
"type": "module", "type": "module",
"description": "Provides OpenClaw runtime for Fusion AI agents", "description": "Provides OpenClaw runtime for Fusion AI agents",
"keywords": [ "keywords": [

View File

@@ -1,5 +1,11 @@
# @fusion-plugin-examples/paperclip-runtime # @fusion-plugin-examples/paperclip-runtime
## 0.2.31
### Patch Changes
- @fusion/plugin-sdk@0.23.0
## 0.2.30 ## 0.2.30
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@fusion-plugin-examples/paperclip-runtime", "name": "@fusion-plugin-examples/paperclip-runtime",
"version": "0.2.30", "version": "0.2.31",
"type": "module", "type": "module",
"description": "Paperclip runtime plugin for Fusion — provides AI agent web access capabilities", "description": "Paperclip runtime plugin for Fusion — provides AI agent web access capabilities",
"keywords": [ "keywords": [