Commit Graph

1011 Commits

Author SHA1 Message Date
gsxdsm
8575c48d85 fix(engine): make merger autostash recovery resilient and AI-resolve conflicts
When rootDir is the developer's primary checkout, the merger stashes
uncommitted edits before 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 — a subsequent merge would push another
autostash on top, burying the first. Recent FN-3299 work was lost this
way and surfaced two side-by-side fusion-merger-autostash entries in
the local stash list.

Three changes:

- AI auto-resolve on apply conflict. The new
  runAiAgentForAutostashConflict spawns the same createResolvedAgentSession
  path as the in-merge fix-agent, instructs it to clear conflict markers
  in place without committing, and verifies markers are gone post-run.
  On verified success the stash is dropped; on any failure or remaining
  markers the stash is left intact for manual recovery.
- Outcome surfaced via new MergeResult.autostash (AutostashOutcome)
  field so dashboard / CLI / daemon can show developers whether their
  work was reapplied cleanly, AI-resolved, or needs manual recovery.
- Deterministic stash identity. Replaced `git stash push` + label-grep
  (which races against concurrent stashing tools) with `git stash create`
  + `git stash store`, capturing SHA atomically with snapshot creation
  and using it for apply / drop. Untracked files captured via `git add
  -A` before create; cleanup via `git reset --hard` + `git clean -fd`.

Also surfaces orphaned `fusion-merger-autostash:*` entries from prior
runs at merge entry, so they can no longer be silently buried.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 20:47:38 -07:00
gsxdsm
202f88b80f refactor(agents): remove terminated AgentState; collapse to paused/error
Drops "terminated" from AGENT_STATES. The agent lifecycle now runs through
idle | active | running | paused | error. paused (carrying a pauseReason)
absorbs every former terminated use case — manual stop, heartbeat run
termination, spawned-child cleanup. Run status (agentRuns.status) is
unchanged: "terminated" stays a valid run-status value.

AGENT_VALID_TRANSITIONS allows direct any→idle transitions so resetAgent
no longer needs the intermediate hop.

Stack-wide:
- core/agent-store: lastError clearing + resetAgent simplified.
- engine/agent-heartbeat, executor, in-process-runtime: terminated state
  writes → paused; halt-state listener fires on paused/error.
- dashboard: AgentsView/AgentListModal/AgentDetailView lose the Terminated
  badge/option/state-block; agent pickers no longer filter terminated;
  agentHealth drops the Terminated branch; routes/state cast widened to
  the new AgentState union.

Tests across core and engine updated to assert paused for AgentState and
left "terminated" intact for run-status assertions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 20:47:38 -07:00
gsxdsm
576074e5c5 fix(engine): unstick agents in running and clean up ephemeral worker pile-up
Two related leaks in the agent lifecycle plus a refactor:

- Governance-skip paths in executeHeartbeat (budget/global-pause/engine-paused)
  were leaving agents permanently stuck in `running` because they ran startRun
  first and then short-circuited with skipStateTransition: true. Removed the
  flag from those four paths so they flow through running → active. Added
  HeartbeatMonitor.reconcileOrphanedRunningAgents() on start to recover any
  rows already trapped in this state.
- Ephemeral task-workers piled up across runtime restarts because taskAgentMap
  was in-memory only and the startup sweep ignored ephemerals with no taskId.
  Now: spawn dedup via findAgentByName before create, on-disk fallback in
  finalize when the in-memory map is empty, and the sweep deletes any
  ephemeral not bound to an in-progress task.
- Extracted the lifecycle into EphemeralWorkerManager
  (packages/engine/src/ephemeral-worker-manager.ts). InProcessRuntime drops
  ~140 lines and delegates via onTaskStart/onTaskComplete/onTaskError/
  attachStateChangeListener/reconcileOrphaned. ChildProcessRuntime and
  RemoteNodeRuntime inherit the fix because they delegate execution to a
  worker that runs InProcessRuntime.

Durable assigned agents now return to `active` after task completion (was
`terminated` in the old contract).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 20:47:37 -07:00
Fusion
0e7b3a19cf feat(FN-3485): align memory scope guidance and dashboard tooling
- Clarify task memory scope behavior across core types, project memory logic, engine tool prompts, and related docs
- Add regression coverage for memory scope and runtime plugin alias handling in core/dashboard/engine tests
- Add agent avatar API routes and dashboard UI support for avatar display and storage documentation
- Add line-number gutter toggle support in FileEditor and Files modal with accompanying component tests
- Include changeset for @runfusion/fusion documenting memory scope guidance update

Fusion-Task-Id: FN-3485
2026-05-05 20:47:37 -07:00
gsxdsm
59eeb68198 chore(release): v0.21.0
Version bump via changesets.
2026-05-05 15:31:33 -07:00
gsxdsm
e27e423194 chore(release): v0.20.0
Version bump via changesets.
2026-05-05 14:56:34 -07:00
gsxdsm
a2f197b8f6 Merge branch 'main' into timothyjlaurent/stuck-spinners 2026-05-05 14:17:58 -07:00
gsxdsm
a77f1b4fca fix: quiet noisy store poll and skill-resolver info logs
Raise checkForChanges slow-poll warn threshold from 100ms to 750ms so
warnings only fire when cycles approach the 1s poll interval, and route
skill-resolver info diagnostics through log() instead of warn().

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:16:30 -07:00
gsxdsm
7d23397dca test: cover concurrent startRun race in heartbeat recovery sweep
Documents the race called out in code review: when recovery samples a
stale run id and a fresh run is spawned for the same agent before
endHeartbeatRun() lands, only the sampled id is terminated — never the
freshly-spawned run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:14:56 -07:00
gsxdsm
9ba75598c3 fix: auto-recover orphaned heartbeat runs from crashed processes
When the dashboard crashes mid-heartbeat, the agentRuns row is left in
status='active' forever. HeartbeatTriggerScheduler.onTimerTick treats
any active run as "still running" and skips every subsequent tick, so
agents go silent indefinitely (observed: 6+ hours). The existing
in-memory missed-heartbeat watchdog can't help — its trackedAgents map
is wiped on process restart.

SelfHealingManager.recoverStaleHeartbeatRuns now reconciles these on
startup and during periodic maintenance: terminates active runs whose
processPid does not match the current process, has no recorded pid, or
has been active for more than 6 hours.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:13:07 -07:00
Timothy Laurent
00fd8f473c fix: add listMissions to MissionStore mock to prevent flaky test
The MissionLoop calls this.missionStore.listMissions() during startup
recovery, but the mock TaskStore's getMissionStore() return value didn't
include this method. When the runtime startup sequence raced ahead, it
would hit "listMissions is not a function" — making the test flaky.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 13:55:35 -07:00
Fusion
36493eca0f feat(FN-3498): add self-healing and ownership-aware done-task merge reconci
The merge completes FN-3498 across three steps: adds ownership-aware done-task reconciliation to the merger, prevents branch-missing head SHA pollution during merge operations, and restores workspace typecheck compatibility. Core changes touch the merger (103 lines) and self-healing module (67 lines

Fusion-Task-Id: FN-3498
2026-05-05 13:42:39 -07:00
Fusion
57c67b6bbd feat(FN-3502): add comment-triggered retriage when task is in triage status
Merged four commits implementing comment-driven retriage: triage rules now respond to specific comment patterns (Step 1) and surface needs-replan feedback inputs in the UI (Step 2), with documentation for the new behavior and a bug fix restoring workspace typecheck defaults. Changes span the core ta

Fusion-Task-Id: FN-3502
2026-05-05 13:32:10 -07:00
Fusion
80cdb15b19 feat(FN-3513): add eval domain store, plugin dashboard view registry, and G
This merge adds three major features: an eval domain (`eval-store.ts`, `eval-types.ts`) with persistence schema for evaluation data; a plugin dashboard view registry with navigation integration for third-party dashboard extensions; and GitHub source metadata traceability that locks and enforces issu

Fusion-Task-Id: FN-3513
2026-05-05 12:25:50 -07:00
Fusion
2c3ff4e3eb feat(FN-3481): clean up ephemeral runtimes and spawned agents immediately o
Merges three major changesets: ephemeral agent cleanup for FN-3481 (runtime and spawned agent teardown), a fix for planning-mode refine continuation flow (FN-3209) plus a new local startup script, and chat SSE broadcast isolation with QuickChat backend unification. Key components affected include th

Fusion-Task-Id: FN-3481
2026-05-05 11:43:33 -07:00
gsxdsm
f57a692eeb fix: skip auto-archive when done task has active dependents
Auto-archive previously wiped .fusion/tasks/{id}/ for stale done tasks
even while downstream agents (triage/todo/in-progress/in-review) still
needed to read those sibling specs from disk. Now the sweep skips any
done task that has an active dependent. The executor prompt also
instructs the agent to fall back to fn_task_show when sibling spec
files are missing on disk (e.g., manually archived deps).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 07:19:30 -07:00
Fusion
47ae7783b7 feat(FN-3484): normalize dashboard mailbox and user identity for messaging
This merge normalizes dashboard user identity and mailbox messaging (FN-3484, 4 steps), adds workflow step execution for plugins (FN-3490), and updates the restart integration store mock for plugin templates (FN-3096). Core changes touch the message store and store modules with identity normalizatio

Fusion-Task-Id: FN-3484
2026-05-05 06:32:34 -07:00
Fusion
33c52e80ea feat(FN-3096): update restart integration store mock for plugin templates
Updates the restart integration test mock to account for plugin template behavior, keeping the test in sync with recent plugin template changes.

Fusion-Task-Id: FN-3096
2026-05-05 06:32:34 -07:00
gsxdsm
2d6187d9ce feat(FN-3475): merge fusion/fn-3475
Fusion-Task-Id: FN-3497
2026-05-05 06:32:33 -07:00
Fusion
499417bc8e feat(FN-3321): add agent self-improvement service and heartbeat evaluation
This merge delivers agent self-improvement (FN-3321) — adding evaluation identity tools, wiring evaluation into the heartbeat loop, implementing a self-improvement service, and providing test coverage. It also expands the dashboard guide view with regression tests, adds org chart full-view mode with

Fusion-Task-Id: FN-3321
2026-05-05 06:32:33 -07:00
Fusion
17b7502c67 feat(FN-3197): refresh qmd after agent dream writes and normalize agent-mem
This merge normalizes agent-memory paths in the core memory backend and ensures the qmd gets refreshed after agent dream writes, fixing a bug where stale paths could persist after memory updates. The engine's agent-tools module was updated to integrate with this fix, and a changeset was included for

Fusion-Task-Id: FN-3197
2026-05-05 06:32:33 -07:00
Fusion
aac3c2236b feat(FN-3479): add agent heartbeat monitoring, auto-claim setting, and work
The merge introduces the auto-claim setting feature, enabling agents to automatically claim tasks on assignment, with corresponding UI in AgentDetailView and documentation. It also adds the agent heartbeat execution system to the engine, refinements to workflow results styling and design tokens, aut

Fusion-Task-Id: FN-3479
2026-05-05 01:40:36 -07:00
Fusion
cd2a464a41 feat(FN-3250): add auto-claim setting UI and documentation
Added auto-claim setting UI to the Agent detail view with corresponding documentation in agents.md and test coverage for the new component behavior. The changeset marks this as a minor feature for the published `@runfusion/fusion` package.

Fusion-Task-Id: FN-3250
2026-05-05 01:11:18 -07:00
Fusion
6c59bdabb6 fix(FN-3433): restore workspace llama-cpp docs index integrity
- Restore workspace llama-cpp extension path resolution in CLI command handling
- Add missing docs/README.md index entries and keep README/doc links aligned
- Add regression coverage for docs README index completeness and docker docs references
- Carry forward related workspace stability updates and test hardening from the branch

Fusion-Task-Id: FN-3433
2026-05-04 23:59:52 -07:00
gsxdsm
56597edc4f fix(engine): retry Codex WebSocket transport drops as transient
pi-ai's openai-codex-responses provider surfaces ChatGPT-plan WebSocket
drops as bare "WebSocket error" / "WebSocket closed <code>". The
underlying ErrorEvent.error is dropped by extractWebSocketError (it only
inspects event.message), so the cause is gone by the time we see it.
The engine then propagated these as fatal failures instead of retrying
a transient network blip.

- Add WebSocket patterns to TRANSIENT_ERROR_PATTERNS so the executor's
  existing transient retry path picks them up.
- Tag the model id onto the thrown error and emit a structured warn in
  promptSessionAndCheck so future drops can be triaged by transport.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 23:59:52 -07:00
Fusion
d91780d171 feat(FN-3434): add Claude OAuth credential interop with verification and st
This merge lands four major features: the desktop app gains shell onboarding with remote mode support via a new `DesktopModeChooser` and `shell-settings` module (FN-3399); the dashboard gains full archived insights support with the `InsightsView` redesign and `useInsights` hook overhaul (FN-3315); C

Fusion-Task-Id: FN-3434
2026-05-04 23:47:26 -07:00
Fusion
8565cdcff7 feat(FN-3249): apply run status icon color style (+3 more)
Commits merged:
- fix(FN-3249): apply run status icon color style
- fix(FN-3249): address workflow revision dashboard accessibility feedback
- feat(FN-3249): complete Step 5 — document assigned execution ownership
- feat(FN-3249): complete Step 2 — durable assigned-agent execution ownership

Files changed:
.changeset/fn-3249-assigned-executor-ownership.md  |   5 +
 docs/agents.md                                     |  15 +++
 packages/core/src/__tests__/agent-store.test.ts    |  28 +++++
 packages/core/src/agent-store.ts                   |  34 ++++--
 .../dashboard/app/components/AgentDetailView.css   |   5 +
 .../dashboard/app/components/AgentDetailView.tsx   |   2 +-
 packages/dashboard/app/components/AgentsView.tsx   |   2 +
 .../runtimes/__tests__/in-process-runtime.test.ts  | 125 ++++++++++++++++++---
 packages/engine/src/runtimes/in-process-runtime.ts | 108 +++++++++++-------
 9 files changed, 260 insertions(+), 64 deletions(-)

Fusion-Task-Id: FN-3249
2026-05-04 23:47:25 -07:00
Fusion
9da9109528 feat(FN-3459): enable tool mode for heartbeat agent sessions
This merge enables heartbeat agents to use coding sessions with tool access (FN-3459). It adds heartbeat session prompt tests, updates the heartbeat executor to support tool mode, modifies dashboard node components and hooks, and includes a fix for a typecheck regression. A changeset is included for

Fusion-Task-Id: FN-3459
2026-05-04 21:21:22 -07:00
Fusion
a02b42106d feat(FN-3313): add plugin slot registry, planning mode rewind, and docker n
This merge lands five features spanning the Fusion stack: research settings key renaming (FN-3313, Steps 2–7) across types, defaults, CLI, and engine packages; static plugin slot-host rendering contract documentation (FN-3260); Docker node provisioning routes with a planning modal (FN-3116); plannin

Fusion-Task-Id: FN-3313
2026-05-04 21:21:22 -07:00
gsxdsm
79bf77bd5e Merge pull request #30 from timothyjlaurent/fix/sqlite-corruption-wal-pragmas
fix: prevent SQLite B-tree corruption with WAL tuning and batched agent logs
2026-05-04 21:20:32 -07:00
Timothy Laurent
8bbcb3e88e fix: resolve Greptile P1 close() timer leak, engine git init, dashboard test
- store.ts close(): clear retry timer and buffer before nulling _db to
  prevent re-opening a new connection after close (Greptile P1)
- merger-staging-allowlist.test.ts: use `git init -b main` so the
  default branch is always named 'main' regardless of git config
- SettingsModal.test.tsx: fix expected text for compact DroidCli card
  — shows "✓ Active" badge, not "✓ Connected — 1.2.3"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-04 21:12:42 -07:00
Fusion
732614325c feat(FN-3352): improve in-process runtime cleanup reliability
Adds comprehensive tests for cleanup reliability in the in-process runtime (131-line test suite) plus related coverage in the executor tests, with a small fix to the runtime implementation itself to address the reliability issue.

Fusion-Task-Id: FN-3352
2026-05-04 18:08:31 -07:00
Fusion
f195245776 feat(FN-3419): remove inline lock indicator from PlanningModeModal
Removed the inline lock indicator from PlanningModeModal and added a new test file covering the planning flow behavior.

Fusion-Task-Id: FN-3419
2026-05-04 17:55:34 -07:00
gsxdsm
d65ed8d28d fix(engine/merger): autostash unrelated rootDir changes around aiMergeTask
The merger issues several `git reset --hard` / `git reset --merge` and
forced-checkout calls against `rootDir` during merge attempts. When
`rootDir` is the developer's primary checkout (common for solo / single-host
setups), those resets silently discard any unrelated unstaged or untracked
changes — we burned dev work this way during FN-3329 (dashboard-tui edits
wiped mid-flight by an unrelated merge run).

Snapshot dirty paths at entry to `aiMergeTask`, stash them under a
recognizable label including the taskId (`-u` to capture untracked), and
pop them in a finally block on every exit path. On pop conflict we leave
the stash intact and log a recovery hint rather than dropping it. Best-
effort: a stash failure logs and proceeds with the old behavior so the
merge itself is never blocked.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 17:22:21 -07:00
Fusion
525787edb7 feat(FN-3323): recover orphaned agents and add reports health section to he
The merge lands FN-3323's self-healing system: a new "reports health" prompt section and `agent-heartbeat.ts` module that detect orphaned agents and recover their state (clearing stale error states and re-enabling heartbeat execution). The engine's `self-healing.ts` was expanded with wired recovery

Fusion-Task-Id: FN-3323
2026-05-04 17:22:21 -07:00
gsxdsm
9415d33f72 chore(release): v0.19.0
Version bump via changesets.
2026-05-04 15:54:42 -07:00
Fusion
c48feb2f79 feat(FN-3324): add runtime guard regression sentinel
Adds a regression test sentinel in the engine's in-process runtime test suite to guard against runtime guard behavior regressions (FN-3324).

Fusion-Task-Id: FN-3324
2026-05-04 15:33:39 -07:00
Fusion
452c31a085 feat(FN-3320): add agent configuration tools for settings management
The merge completes FN-3320 by implementing configuration tools for the agent system (`agent-tools.ts`), wiring them through the executor, and adding test coverage (`agent-tools-config.test.ts`). Documentation was updated in `AGENTS.md` and the engine tools reference, with minor updates to the agent

Fusion-Task-Id: FN-3320
2026-05-04 15:21:40 -07:00
Fusion
d3060ef7f4 feat(FN-3317): add merge scheduler recovery test coverage
Added 95 lines of test coverage for merge scheduler recovery paths in the merge error recovery test suite, completing Step 4 of FN-3317.

Fusion-Task-Id: FN-3317
2026-05-04 14:47:12 -07:00
Fusion
88171eb5b3 feat(FN-3308): fix CSS token consistency in settings and task detail modals
Fixes CSS token consistency issues in TaskDetailModal and SettingsModal, and updates the corresponding mobile overflow test to match the refactored styles.

Fusion-Task-Id: FN-3308
2026-05-04 14:05:27 -07:00
gsxdsm
89da1de311 fix(merger): restrict staging to allowlist and harden git invocations
Replaces blanket `git add -A` in `commitOrAmendMergeWithFixes` with an
explicit allowlist of (squash-staged ∪ fix-agent-modified) paths, so
unrelated dirty files in the project root no longer get swept into a
task's squash commit. The in-merge fix agent now snapshots the working
tree before/after its session to capture exactly which files it touched.

Hardens the git invocations the allowlist relies on:
- All `git add` and `git checkout --ours/--theirs` calls switched from
  shell-interpolated `execAsync` to `execFile` array form, eliminating
  path-injection surface and batching per-file spawns into one call.
- `snapshotDirtyFiles` adopts `git -z` NUL-delimited parsing so paths
  with embedded spaces or specials are handled correctly.
- Long allowlist debug logs are truncated to 20 entries with an overflow
  marker.

Refused-to-stage paths emit a warn naming each file so the user can
audit what was filtered.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 13:17:57 -07:00
Fusion
c9e776cb34 feat(FN-3293): add stabilization docs to test audit report
Documentation for test stabilization was finalized by updating the test audit report with 2 additional lines.

Fusion-Task-Id: FN-3293
2026-05-04 13:17:57 -07:00
Fusion
3a97bf2386 feat(FN-3292): document research boundary contract
Documents the research boundary contract in the architecture docs and research hardening preflight guide, updating architecture documentation and adding a new boundary definition file.

Fusion-Task-Id: FN-3292
2026-05-04 13:17:57 -07:00
gsxdsm
1321830800 chore(release): v0.18.1
Version bump via changesets.
2026-05-04 09:55:19 -07:00
gsxdsm
625c5c5f4d chore(release): v0.18.0
Version bump via changesets.
2026-05-04 09:21:08 -07:00
Fusion
3f5893bdc1 feat(FN-3074): sort done column by recency, preserve merge-active state, ad
This merge adds done-column sorting by most recent completion while preserving merge-active state on verification bounces, introduces a comprehensive droid runtime regression test suite covering engine delegation, auth routes, and model routing, hardens the CLI native bundle externalization, and fix

Fusion-Task-Id: FN-3074
2026-05-04 07:25:14 -07:00
gsxdsm
0c1900c583 Merge pull request #29 from HarryCordewener/fix/skill-discovery-path-doubling-and-matching
fix: skill discovery path doubling and pattern/name matching
2026-05-04 07:18:30 -07:00
Fusion
1bd32a542d feat(FN-3231): preserve merge-active state on verification bounce and board
This merge lands FN-3231 across two steps: it preserves a merge-active fix when verification bounces occur (step 1) and ensures the fix is retained during board routing transitions (step 2). Changes span the dashboard Board routing logic and the engine executor, with corresponding test coverage adde

Fusion-Task-Id: FN-3231
2026-05-04 07:00:39 -07:00
gsxdsm
33c011959a fix(engine): treat finish_reason=repeat as soft stop
Moonshot/Kimi returns a non-standard finish_reason of "repeat" when its
server-side repetition detector trips. pi-ai surfaces this as a fatal
session state error, killing the agent heartbeat. Filter that case in
promptSessionAndCheck so the truncated turn is logged and the heartbeat
continues on the next tick.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 06:47:29 -07:00
gsxdsm
eb21d84fa3 chore(release): v0.17.2
Version bump via changesets.
2026-05-04 00:49:34 -07:00