Files
fusion/packages/core/CHANGELOG.md
gsxdsm 08e04498f5 chore(release): v0.26.0
Version bump via changesets.
2026-05-10 08:55:51 -07:00

18 KiB

@fusion/core

0.26.0

0.25.0

0.24.0

0.23.0

0.22.0

Minor Changes

  • e658e8e: Decouple permanent agent heartbeats from task state, and add per-agent allowParallelExecution setting.

    Heartbeats now run for permanent agents regardless of bound-task block state — the prior early-exit on queued + blockedBy is removed along with its dead state-tracking machinery. HEARTBEAT_SYSTEM_PROMPT is rewritten to scope heartbeats to ambient coordination (messaging, memory, finding work, delegation, surfacing/chasing blockers, status); task body work continues to run via the executor path. Ephemeral agents are unchanged — they don't run heartbeats and their blocked-task gating in the scheduler is untouched.

    New allowParallelExecution flag (default true, permanent agents only) on AgentHeartbeatConfig. When false, the heartbeat and task executor paths serialize symmetrically: a heartbeat will not start while the agent's bound task has an active executor session, and an executor session will not start while the agent has an active heartbeat run. Either side re-dispatches the other's deferred work on completion via resumeTaskForAgent and the in-process runtime's onRunCompleted hook.

    UI toggle surfaces in the agent's Heartbeat Settings tab alongside runMissedHeartbeatOnStartup.

Patch Changes

  • aecc050: Make the merger's autostash recovery robust against silent data loss. When rootDir is the developer's primary checkout, the merger stashes uncommitted edits before running its hard resets and applies them back at the end. Previously a pop conflict logged a single warning and silently left the stash in place — and a subsequent merge would push another autostash on top, burying the first.

    Three changes:

    1. AI auto-resolve on apply conflict. When the autostash apply hits a conflict, the merger now spawns a focused fix-agent (same createResolvedAgentSession path used for the in-merge verification fix-agent) to resolve conflict markers in the working tree. On success the stash is dropped and the resolution is recorded in MergeResult.autostash. On failure the stash is left intact for manual recovery.
    2. Outcome surfaced on MergeResult.autostash (new field of type AutostashOutcome). Consumers (dashboard, CLI, daemon) can now show the developer whether their work was reapplied cleanly, AI-resolved, or needs manual recovery — instead of relying on a buried log warning.
    3. Deterministic stash identity via git stash create + git stash store. Replaces the previous git stash push + label-grep flow that raced against any other tool stashing concurrently. The stash SHA is captured atomically with snapshot creation and used for apply/drop, so the operation is robust to stash list reordering.

    Also: orphaned fusion-merger-autostash:* entries from prior failed runs are now detected at merge entry and surfaced as a warning so they cannot be silently buried again.

0.21.0

0.20.0

0.19.0

0.18.1

0.18.0

0.17.2

Patch Changes

  • 17a6634: Fix pre-merge workflow steps stalling on tasks with no relevant changes (FN-3327 post-mortem).

    • @fusion/engine: executeWorkflowStep now computes the diff scope (git diff --name-only plus --shortstat against task.baseCommitSha) before spawning the reviewer agent and injects a "Diff Scope" block into the system prompt. The block lists every file the task actually changed and adds explicit scoping rules: review only those files, and if none match the step's category respond immediately with a short approval line and stop. Without this, an open-ended review prompt (e.g. WS-005 "Frontend UX Design") would drift into pre-existing files matching the task description's keywords, exhaust the 360 s timeout, and trigger the auto-revive → re-finalize → re-fail loop that had FN-3327 wedged in in-review. Both git calls are best-effort; failures degrade to a "no modified files detected" notice rather than blocking the step.
    • @fusion/core: The built-in frontend-ux-design workflow step template (WS-005) now opens with a FAST-BAIL rule telling the reviewer to inspect the Diff Scope first and return an immediate one-line approval when no UI/CSS/component files are present. New installs and freshly-materialized templates pick this up automatically; existing DB rows are unaffected but are still rescued by the executor-side scope injection above.

0.17.1

0.17.0

0.16.0

0.15.0

0.14.3

0.14.2

0.14.1

0.14.0

0.13.0

0.12.0

0.11.0

0.10.0

0.9.4

0.9.3

0.9.2

0.9.1

Patch Changes

  • 76deb48: Fix Active Agents panel cards stuck on "Connecting...". Agents in active state without a current task have no SSE stream to attach to, so the card now shows "Idle — no task assigned" instead of misleading network copy ("Starting..." for the brief running-without-task race). Also fixes a related SSE multiplexer bug: subscribers joining a channel that had already opened never received an onOpen callback (EventSource only emits open once), leaving them at isConnected: false indefinitely whenever another component was already streaming the same task's logs.
  • f6242c2: Hoist the Active Agents panel above the main agent list and surface next-heartbeat ETA. Live work now sits directly under the stats bar so it's visible without scrolling past the full agent directory. Each card footer renders "Next heartbeat in Xs" (or "Heartbeat overdue Xs" when the deadline has passed) using the agent's runtimeConfig.heartbeatIntervalMs with the dashboard default fallback. Cards also gain pointer cursor + hover/focus styling so the existing click-to-select behavior is discoverable.

0.9.0

Minor Changes

  • a654795: Generate richer merge commit messages via the AI summarizer. The merger now routes commit-body summarization through the consolidated ai-summarize.ts pipeline (using the title-summarization model), with an AI fallback cascade to guarantee non-empty merge bodies. Summarization model is configurable in settings.

  • 91f9f20: Add unified multi-node task routing across CLI, dashboard, core, and engine flows.

    • Routing model: Tasks can set a per-task node override with project-level pinned default node fallback. resolveEffectiveNode() computes the effective routing target per task.
    • Core types: Adds Task.nodeId, UnavailableNodePolicy ("block" | "fallback-local"), ProjectSettings.defaultNodeId, and ProjectSettings.unavailableNodePolicy.
    • Engine behavior: Adds effective-node resolution (per-task override → project default → local), unavailable-node policy enforcement, and routing activity event logging.
    • Active-task guard: Blocks node override changes for in-progress tasks via validateNodeOverrideChange().
    • Dashboard updates: Adds project settings controls for default node and unavailable-node policy, task detail routing summary (effective node, routing source, fallback policy, blocking reason), quick task creation node picker, bulk node override actions, and node health/status indicators in selectors.
    • CLI updates: Adds fn settings set defaultNodeId <node-id>, fn settings set unavailableNodePolicy <block|fallback-local>, fn task set-node <id> <node>, fn task clear-node <id>, fn task create --node <name>, and routing details in fn task show.
    • Schema updates: Includes tasks table migration adding the nodeId column.
  • 17a072c: Add requirePrApproval setting (related to #21).

    When mergeStrategy: "pull-request", GitHub's required: true flag for status checks only flows from branch protection — a Pro feature on private repos. On free private repos, isPrMergeReady reports every fresh PR as immediately mergeable, so autoMerge: true causes Fusion to auto-squash-merge the moment the PR opens with no chance for a human to review it.

    The new requirePrApproval setting (project-level, default false) makes Fusion hold the merge until at least one approving GitHub review is present (reviewDecision === "APPROVED"), independent of GitHub's server-side enforcement. Surfaces in the dashboard's Merge settings panel under the Pull Request strategy. Lets you use Fusion's PR mode as "open the PR, wait for me to approve and merge" on any tier.

  • 1beebc0: Allow tasks to be respecified from in-review. VALID_TRANSITIONS["in-review"] now includes triage, so the dashboard's Request AI Revision and Rebuild Spec actions work for in-review tasks. Moving an in-review task to triage performs the same full reset as in-review → todo (clears branch/baseBranch/baseCommitSha/summary/recovery metadata and workflowStepResults) so the next run starts from scratch. The in-review card's Move menu also now offers Planning as a destination.

Patch Changes

  • 48208db: Surface live run status on Active Agent cards instead of a generic "Connecting…" placeholder. The card now polls the agent's task and shows the current step (e.g. "Step 5/8: Write Tests") and executor model while the SSE log stream warms up. A new "Live logs" button on the card opens the task detail modal directly on the Logs tab.

  • a654795: Prefer merge-base over potentially stale baseCommitSha when resolving task diff bases in the dashboard. Diffs no longer drift when the recorded base commit lags behind the actual divergence point.

  • a654795: Show only files actually changed by the task in ChangesDiffModal and TaskChangesTab. The diff baseline is no longer flooded with files that weren't touched by the task itself.

  • a654795: Close executor/merger concurrency races and reviewer pause TOCTOU. Worktree lifecycle is now synchronized more defensively across executor and merger paths, the reviewer pause/unpause flow is hardened against time-of-check/time-of-use races, and AgentSemaphore now guards against invalid limits (NaN, Infinity).

  • a654795: Read assistant text from session state when processing memory dreams. Dream extraction no longer misses content when the assistant message has not been flushed to the output stream yet.

  • b91533c: Fix PR-mode merge flow (related to #21):

    • PR-mode now pushes the per-task branch to origin before creating the PR. processPullRequestMergeTask previously called gh pr create --head fusion/<task-id> without ever publishing the branch, so the PR creation failed and the task stalled in in-review. The branch is now pushed via git push -u origin <branch> immediately before createPr (skipped when an existing PR already covers the branch).
    • Removed dead autoCreatePr setting from the schema and Settings type. It was defined as a default but never read anywhere.
  • 7f42c7f: Fix #21: the recover-mergeable-review maintenance sweep no longer bypasses autoMerge and mergeStrategy. The sweep now early-returns when autoMerge !== true (or when the engine is paused) and routes recovery merges through the engine's merge queue so mergeStrategy: "pull-request" is honored — eligible in-review tasks go through processPullRequestMerge instead of a raw local git merge. Operators using a PR-based review flow with autoMerge: false will no longer have tasks silently merged behind their back.

  • a654795: Restore task card timing and changes fallbacks (FN-2877). The dashboard task card again falls back gracefully when timing data or change summaries are missing, preventing blank states on tasks that haven't reported metrics yet.

  • bb5402a: Keep task card timer live while a task is actively merging (FN-2920). The in-review timer was driven by per-step instrumented duration, which freezes during the merge phase, so a stuck merge could read "3m" indefinitely. While status is merging/merging-pr the card now shows live elapsed since the merger flipped the status, with a "Merging Nm" tooltip.

  • a654795: Surface visible feedback when copying a log entry from the dashboard TUI. The Logs panel title now flashes a "Copied!" / "Copy failed" status so the action is no longer silent.

  • a654795: Stack Utilities and Settings under Stats in the dashboard TUI wide layout (≥150 columns). Logs now fills the full right column for its full height; Stats flex-grows in the left column above fixed-height Utilities and Settings, so Stats absorbs all leftover vertical space.

0.8.4

0.8.3

0.8.2

0.8.1

0.8.0

0.7.1

Patch Changes

  • ce6dcef: fix(0.7.1): mobile polish, modal layout fixes, paperclip CLI parity, schema migration

    Mobile / dashboard:

    • ModelOnboardingModal: dialog was off-screen on phones because the desktop min-width: 640px won over the mobile max-width: 100%. Reset min-width/min-height to 0 in the mobile media query (with !important so persisted desktop sizes from useModalResizePersist cannot re-pin it). Compact provider cards: keep the icon inline beside the name + description, shrink the icon container, drop name/description font sizes, and rely on flex-wrap so the API-key actions still drop to their own row underneath. The API-key input + Save button now live on a single row at the full card width — input grows left-aligned, Save shrinks to the right with a hairline of inline padding.
    • NewAgentDialog: the dialog's top was rendering hidden behind the in-page Agents header on mobile. Render the dialog through createPortal(..., document.body) so the overlay escapes the .agents-view stacking context. Mobile media query also drops the overlay padding, fills 100vw / 100dvh with safe-area insets on header/footer for iOS notch + home indicator, and fixes the classic flex min-height: auto bug that prevented overflow-y: auto on the body from activating.
    • TerminalModal: same root cause as the onboarding modal — desktop min-width: 480px / min-height: 320px pinned the modal off-screen on phones. Reset to 0 in the mobile rule with !important so persisted desktop sizes can't override.
    • WorkflowStepManager: fix React error #310 ("Rendered more hooks than during the previous render") that prevented the workflow steps panel from loading. useOverlayDismiss was being called after an if (!isOpen) return null early return, so the hook count differed between open/closed renders. Moved the hook above the early return.
    • SettingsModal auth panel: tightened .auth-panel-body horizontal padding from --space-xl (24px) to --space-md (12px), giving each provider card more horizontal room.

    Paperclip runtime:

    • CLI parity: in the dashboard's "Local CLI" tab, Test / fetch companies / fetch agents now actually shell out to paperclipai instead of making HTTP calls through a derived URL. New CLI-backed variants (probePaperclipViaCli, listCompaniesViaCli, listCompanyAgentsViaCli, createIssueViaCli, getIssueViaCli, agentsMeViaCli) drive every Paperclip call that has a CLI counterpart; the runtime adapter routes through them when transport=cli. getIssueComments / wakeAgent / getRunEvents continue using HTTP (no matching paperclipai subcommands) but rely on the apiKey discovered from the local paperclipai config so CLI mode works end-to-end.
    • New dashboard routes /providers/paperclip/cli-status, /cli-companies, /cli-agents exposing the CLI helpers.

    Plugin runtime registry:

    • GET /api/plugins/runtimes now merges a bundled hermes/openclaw/paperclip fallback list on top of installed plugins, so the NewAgentDialog "Plugin Runtime" dropdown populates without requiring fn plugin install on a fresh setup. Installed plugins override the bundled entry by runtimeId. Coalesced the optional version field to "0.0.0" to satisfy the bundled-runtime type.

    Core:

    • Schema migration fix: bumped SCHEMA_VERSION from 48 → 49 so migration 49 (per-task nodeId column for remote-node routing) actually runs. Existing DBs at version 48 hit the early-return guard, never created the column, and TaskStore.listTasks crashed at startup with no such column: nodeId — the dashboard exited before initialization. The bump unblocks app startup on any pre-existing 0.7.0 install.

0.7.0

Minor Changes

  • b30e017: feat(runtimes): real Hermes / OpenClaw / Paperclip runtime plugins

    Replaces the stub runtime plugins with end-to-end working integrations:

    • Hermes runtime drives the local hermes CLI as a subprocess (hermes chat -q ... -Q --source tool [--resume <id>]), captures session ids for continuity, with profile picker (HERMES_HOME-based switching) and Nous Research co-brand.
    • OpenClaw runtime drives openclaw --no-color agent --local --json --session-id <uuid> --message <prompt>, parses the OpenAI-compatible JSON output, surfaces visible/reasoning text via callbacks; defaults to embedded mode (no daemon required).
    • Paperclip runtime now uses the modern POST /api/agents/{id}/wakeup + heartbeat-run streaming API (replaces the old issue-checkout + heartbeat-invoke flow); supports both API mode (URL + bearer) and CLI mode (auto-derives URL from ~/.paperclip/instances/default/config.json); company + agent dropdowns; CLI key bootstrap via paperclipai agent local-cli.

    Engine fix: agent-session-helpers.ts:createResolvedAgentSession now attaches the resolved runtime's promptWithFallback to the session so pi's dispatch hook routes prompts through the plugin runtime instead of falling through to pi's native path.

    Dashboard adds a unified RuntimeCardShell component, real provider logos (caduceus, pixel-lobster, paperclip outline), Test/Save/Save & Test buttons with success/failure toasts, "Learn more →" links, and a "Runtimes" group in Settings.

    Backend adds GET /providers/{hermes,openclaw,paperclip}/status, GET /providers/hermes/profiles, GET /providers/paperclip/{companies,agents,cli-discovery}, POST /providers/paperclip/cli-mint-key.

    Plugin SDK: now ships a proper dist/ build (was previously TS-source-only), unblocking runtime imports from compiled plugins.

0.6.0

0.5.0

0.4.1

0.4.0

0.2.7

0.2.6