Commit Graph

850 Commits

Author SHA1 Message Date
Fusion
fbf91c74a9 feat(FN-3596): unify board/list task ordering, split TaskDetailModal test m
The merge introduces a major TaskDetailModal test refactor (splitting a 6.7K-line monolith into five focused suites), significant merger improvements including autostash race-rescue, deduplication, and advisory logging for destructive operations, a new TUI narrow-mode log-split feature for the dashb

Fusion-Task-Id: FN-3596
2026-05-06 18:37:23 -07:00
Fusion
9b56e521eb docs(FN-3421): document branch field plumbing architecture
- Document how branch field data flows through task lifecycle
- Clarify architecture-level plumbing responsibilities for branch metadata
- Capture Step 4 documentation updates in docs/architecture.md

Fusion-Task-Id: FN-3421
2026-05-06 17:54:23 -07:00
gsxdsm
b81196e3a2 fix(merger): prefer step headline subject + add autostash race-rescue
- deriveDeterministicSubjectSummary now picks the lowest-numbered
  `complete Step N` headline (or the oldest commit) instead of the most
  recent commit, so trailing quality-gate revisions stop hijacking the
  squash-merge subject (FN-3617 landed as "align mailbox modal css..."
  when 4 of 5 commits were the actual Claude OAuth fix).
- AI subject + body system prompts in ai-summarize.ts now weight by
  commit theme rather than file size, so a small token cleanup that
  touches a large CSS file no longer dominates the summary.
- stashUnrelatedRootDirChanges adds a bounded re-snapshot loop after
  the primary stash is persisted but before \`git reset --hard\`. Any
  late-dirty paths (concurrent dev edits during a long merger run,
  parallel merger runs racing on rootDir, late test/build artifacts)
  get captured in labeled \`race-rescue-N\` stashes recoverable from
  \`git stash list\`, instead of being wiped by the destructive reset.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 17:06:46 -07:00
Fusion
d1549b8dff feat(FN-3576): restore plugin setting group field and grouped agent browser
This merge restores plugin setting group functionality in the dashboard (FN-3576), adds documentation for plugin authoring, and improves test isolation by broadening runtime ignore lists for live fusion app paths in the isolation checker script. The feature touches the PluginManager component with n

Fusion-Task-Id: FN-3576
2026-05-06 14:53:07 -07:00
Fusion
f22db4d1fe feat(FN-3180): add dreams notification event and harden plugin setup sync
This merge lands four features: a new "dreams" notification event exposed through settings and docs (FN-3180), hardened plugin setup sync with test isolation improvements (FN-3573), and feedback-driven enhancements to the native shell connection manager (FN-3402). Core settings schema, the plugin AP

Fusion-Task-Id: FN-3180
2026-05-06 14:42:26 -07:00
Fusion
2413ccb398 feat(FN-3391): persist evaluator evidence with score categories
- Add eval score category types and exports in core with store support and coverage
- Implement engine evaluator evidence extraction and persistence with dedicated tests
- Update evaluator flow and cron wiring to record evidence alongside eval runs
- Refresh architecture, storage, and eval docs for evidence and categorization behavior

Fusion-Task-Id: FN-3391
2026-05-06 13:38:23 -07:00
gsxdsm
9c60eb2821 perf(merger): skip redundant in-merge verification and lockfile-stable installs
Two cuts to wasted work in the merge verification loop:

1. After the in-merge fix agent runs, fingerprint the working tree
   (`git diff HEAD` + `git status --porcelain`, sha256). If the post-fix
   fingerprint matches pre-fix and is non-empty, the agent didn't actually
   change anything — re-running the same failing command can only yield
   the same failure, so log and report the attempt as unsuccessful without
   paying the test/build cost. Empty fingerprints (snapshot tooling failed)
   fall through to the existing re-run path so we never silently swallow a
   real fix.

2. Inside `syncDependenciesForMerge`, hash the active lockfile and compare
   against `node_modules/.fusion-install-marker` (written after each
   successful install). When they match, skip `pnpm install
   --frozen-lockfile` even if `package.json` is staged. Covers the common
   case where `package.json` changes but the lockfile doesn't, and
   amortizes install across auto-recovery re-enqueues that hit the same
   worktree.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 12:24:57 -07:00
Fusion
f6394cc22b test(FN-3607): harden test workflow verification and isolation checks
- Expand test-changed coverage and shard selection assertions for CI workflows
- Improve vitest worker temp-directory utilities and related core/CLI tests
- Refine test isolation guardrails and runtime ignore handling for live .fusion noise
- Update contributing guidance and root test script usage for the verified workflow

Fusion-Task-Id: FN-3607
2026-05-06 11:51:48 -07:00
Fusion
6c9f87f71a feat(FN-3390): export eval score category type and harden evaluator switch
Exported the eval score category type from `@fusion/core` and added a defensive guard in the evaluator to prevent edge-case failures in the score evaluation switch.

Fusion-Task-Id: FN-3390
2026-05-06 11:09:05 -07:00
Fusion
1ce47fd870 feat(FN-3580): restore canonical agent lifecycle and remove terminated agen
This merge restores the canonical agent lifecycle with termination scoped at the run level (FN-3580, 4 steps), adds sender-side wake recipient override for messages, and introduces test isolation CI enforcement with a stuck-requeue race fix. UI changes remove terminated-agent indicators from AgentDe

Fusion-Task-Id: FN-3580
2026-05-06 10:18:27 -07:00
Fusion
b3aa9f9890 feat(FN-3595): document live reviewer override behavior in settings and tas
Documents the live reviewer override behavior in the settings reference and task management guides, adding two lines to each file for a total of 4 lines of documentation.

Fusion-Task-Id: FN-3595
2026-05-06 10:05:40 -07:00
Fusion
7d02ac81ef feat(FN-3593): add test isolation CI enforcement, fix stuck-requeue race, a
This merge lands five FN-3593 commits establishing a test isolation contract with a new `scripts/check-test-isolation.mjs` guard that scans for accidental `beforeEach`/`afterEach`/`beforeAll`/`afterAll` in setup helpers, plus per-package `setup-test-isolation.ts` bootstraps that canonicalize the pat

Fusion-Task-Id: FN-3593
2026-05-06 09:43:51 -07:00
gsxdsm
890f8853ed feat(messages): add sender-side wake recipient override
Senders can now force the recipient agent to wake on receipt regardless
of the recipient's `messageResponseMode`. Surfaced as a "Wake recipient
immediately" checkbox in MessageComposer and as a `wake_recipient`
boolean param on the `fn_send_message` agent tool. Carried as
`metadata.wakeRecipient: true` on the message; the heartbeat hook
treats forced wakes as `message_received_urgent` in the wake delta so
agents can distinguish them from normal `messageResponseMode: immediate`
wakes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 09:26:15 -07:00
gsxdsm
c17c288cea fix(engine): stuck-requeue no longer clobbers concurrently-recovered tasks
When SelfHealingManager.recoverCompletedTasks moved a task from
in-progress to in-review, the executor's stuck-kill cleanup running in
execute()'s finally block could fire 20s later, see a stale captured
task.column = "in-progress", and overwrite the recovery by tearing down
the worktree and moving the task back to todo with all step progress
reset. Both the outer-finally and step-session requeue blocks (and the
force-requeue setTimeout in markStuckAborted) now re-read the latest
column and skip cleanup entirely if the task has moved past
in-progress/todo.

Adds a new preserveProgressOnStuckRequeue setting (default: true,
toggle in Settings near the Stuck Task Timeout) so stuck-requeue passes
{ preserveProgress: true } to moveTask. Completed step statuses now
survive the bounce so the agent resumes from where it left off instead
of restarting every step from pending.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 09:07:52 -07:00
gsxdsm
4866f341bd fix(engine): prevent worktree collisions on manual task moves
Two related bugs let two in-progress tasks 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 held by another
   active task.

2. moveTask({preserveResumeState:true}) kept the worktree pointer on
   requeue. When the on-disk checkout was later removed or reassigned,
   the next dispatch collided with a worktree the scheduler had handed
   to another task.

moveTask now releases the worktree pointer on every reopen-to-todo hop
(branch is kept so committed progress survives via git worktree add
<path> <branch>). A new preserveWorktree option opts internal bounces
out of the release. moveTask also accepts an allocateWorktree callback
that runs under a new cross-task allocation lock in TaskStore, so two
concurrent moves cannot pick the same name from a stale snapshot. Both
the manual-move route and the scheduler dispatch path flow through the
allocator and share the lock.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 07:23:38 -07:00
Fusion
b28ae48fff feat(FN-3102): add plugin contribution types, scheduled evaluator, and agen
This merge adds a new evaluation framework including signal collection (`eval-signal-collector.ts`), typed evaluation signals (`eval-types.ts`), and an evaluator engine module (`evaluator.ts`) with cron-runner integration for scheduled evaluation. It also establishes plugin contribution type constra

Fusion-Task-Id: FN-3102
2026-05-06 06:18:09 -07:00
Fusion
6a599d607a feat(FN-3389): fix scheduled evaluator integration types
Completes typing for the scheduled evaluator integration in the cron runner and project engine, with corresponding test updates in the evaluator test file.

Fusion-Task-Id: FN-3389
2026-05-06 06:05:05 -07:00
Fusion
fb0e15562d feat(FN-3544): add project-scoped auth storage and docs updates
- Add project auth storage model and persistence wiring in core DB/store/types
- Expand core test coverage for DB migration, store behavior, and project auth store flows
- Update heartbeat agent, settings, dashboard, and storage documentation for the new behavior
- Replace hardcoded mobile touch-target sizing in dependency graph styles with token-based sizing

Fusion-Task-Id: FN-3544
2026-05-06 04:56:29 -07:00
Fusion
408a46e1c2 feat(FN-3565): add plugin management CLI, loader, runner, and dashboard rou
This merge adds a complete plugin management system to Fusion: a new `fn plugin` CLI command for installing/removing plugins, a plugin loader in core, a plugin runner in engine, and dashboard routes for plugin management UI, along with a plugin management guide in docs. It also documents task evalua

Fusion-Task-Id: FN-3565
2026-05-06 04:32:29 -07:00
Fusion
ce323742a3 feat(FN-3514): document task evaluation settings in settings reference
Documents task evaluation settings by adding 6 lines to the settings reference guide.

Fusion-Task-Id: FN-3514
2026-05-06 04:09:23 -07:00
Fusion
79a6b2c840 feat(FN-3539): remove duplicate todos entry and update navigation docs
Merged branch removes the duplicate desktop "Todos" nav entry from the Header, syncs the `allowParallelExecution` runtime toggle into `AgentDetailView`, and updates the corresponding docs (agents.md, settings-reference.md, todo-view.md, dashboard-guide.md) to reflect the navigation change. Tests wer

Fusion-Task-Id: FN-3539
2026-05-06 03:52:18 -07:00
Fusion
94a5dca53c feat(FN-3535): restore terminated agent state and align lifecycle controls
This merge completes the agent terminated state alignment (FN-3535), adding "running → terminated" transition support with consistent styling and lifecycle controls across the heartbeat engine, agent store, and dashboard UI, plus plugin author documentation improvements (FN-3537) and plugin loader t

Fusion-Task-Id: FN-3535
2026-05-06 03:07:27 -07:00
Fusion
c630a94ef8 feat(FN-3564): isolate plugin loader test state to prevent cross-test conta
Refactored plugin-loader tests and implementation to isolate plugin test contamination, improving test independence in `@fusion/core`.

Fusion-Task-Id: FN-3564
2026-05-06 02:14:05 -07:00
gsxdsm
1ada98b53f chore(release): v0.22.0
Version bump via changesets.
2026-05-06 00:11:20 -07:00
Fusion
2c497b3734 docs(FN-3538): clarify pause-safe stuck timeout behavior
- Update enginePaused setting docs to specify stuck-task timers are suspended while pauses are active
- Document that paused wall-clock time does not count toward taskStuckTimeoutMs, including shared globalPause windows
- Clarify that unpausing restores scheduling and grants active sessions a fresh stuck-task grace window before detection resumes

Fusion-Task-Id: FN-3538
2026-05-06 00:05:55 -07:00
gsxdsm
e004b205d9 feat(agents): decouple heartbeat from task state, add allowParallelExecution
Permanent agents now run heartbeats regardless of bound-task block state.
The prior queued+blockedBy early-exit and its state-tracking machinery are
removed; HEARTBEAT_SYSTEM_PROMPT is rewritten to scope heartbeats to
ambient coordination (messaging, memory, finding work, delegation,
surfacing/chasing blockers, status). Task body work continues via the
executor path. Ephemeral agents are unchanged.

New allowParallelExecution flag (default true, permanent agents only) on
AgentHeartbeatConfig. When false, heartbeat and 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. UI toggle surfaces in the
agent's Heartbeat Settings tab.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 22:18:35 -07:00
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
768e0b3568 feat(agents): per-agent run-missed-heartbeat-on-startup setting
When the engine boots, if an agent has the new
runMissedHeartbeatOnStartup flag enabled and lastHeartbeatAt is older
than its interval, fire one catch-up heartbeat through the existing
executeHeartbeat path. Default is off, so existing agents are
unchanged. Toggle exposed in the agent's Heartbeat Settings tab.

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
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
Fusion
964e111f8b feat(FN-3118): document avatar storage in agents and architecture
Added avatar storage and field documentation to the agents guide, with a minor reference added to the architecture docs.

Fusion-Task-Id: FN-3118
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
4c11bafdae Merge pull request #43 from timothyjlaurent/timothyjlaurent/broken-insights
fix(insights): add missing lifecycle column compatibility check
2026-05-05 15:08:45 -07:00
gsxdsm
e27e423194 chore(release): v0.20.0
Version bump via changesets.
2026-05-05 14:56:34 -07:00
gsxdsm
9f2f1fd450 chore: silence node:sqlite ExperimentalWarning in tests, fix QR mock type
Patch process.emitWarning in the shared vitest setup to drop the
"SQLite is an experimental feature" notice; align the test mock for
getQrPayload with the canonical RemoteQrPayload signature.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:33:26 -07:00
gsxdsm
cb7d65712d Update packages/core/src/__tests__/insight-store.test.ts
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-05-05 14:31:53 -07:00
gsxdsm
13a884aafc Merge branch 'main' into timothyjlaurent/broken-insights 2026-05-05 14:18:45 -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
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
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
2e8fb88c44 feat(FN-3368): tighten research view test coverage and resolve dashboard ty
This merge introduces an eval automation domain store with persistence schema and a plugin dashboard view registry (FN-3512/FN-3513), adds scheduled eval batch architecture documentation (FN-3388), and includes substantial test coverage for Research routes and hooks (FN-3368 steps 1-3). The branch a

Fusion-Task-Id: FN-3368
2026-05-05 13:05:57 -07:00
Timothy Laurent
7d3f31e5e4 test(insights): add regression test for ensureInsightRunsSchemaCompatibility
Simulates a database where project_insight_runs exists without lifecycle
and cancelledAt columns (the state that caused the original bug), then
verifies that re-opening the database adds the columns and creating a run
succeeds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 12:51:32 -07:00
Fusion
5083227069 feat(FN-3388): document scheduled eval batch architecture
Added 3 lines documenting the scheduled eval batch architecture in the architecture docs as part of FN-3388 Step 4.

Fusion-Task-Id: FN-3388
2026-05-05 12:49:01 -07:00
Fusion
24a91131db feat(FN-3387): add eval domain with store and persistence schema
Introduced a new evaluation persistence layer in `@fusion/core` with domain contracts, SQLite-backed storage APIs, and retention/window-rollup support, wired through the core store and documented in the architecture and storage docs.

Fusion-Task-Id: FN-3387
2026-05-05 12:01:53 -07:00
Timothy Laurent
6b8cc008b1 fix(insights): add ensureInsightRunsSchemaCompatibility for missing lifecycle column
Databases already at schema v59+ when the lifecycle column was added never
re-ran the v59 migration, causing "no column named lifecycle" errors on
insight generation. Adds an unconditional compatibility check following the
existing ensureRoutinesSchemaCompatibility pattern.

Fixes #42

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 11:31:21 -07:00
Fusion
4225f9fa01 feat(FN-3287): document PR link visibility in dashboard README
Merges the documentation update for FN-3287, adding 2 lines to the dashboard README covering PR link visibility behavior. This completes Step 5 of the task.

Fusion-Task-Id: FN-3287
2026-05-05 07:18:32 -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
e91e937478 feat(FN-3490): add workflow step execution for plugins
This merge adds WorkflowStepManager UI enhancements, extends the plugin-runner with new execution capabilities, expands executor tests with improved restart and mock handling, and adds agent routes for the dashboard. The changes span core plugin loading, dashboard components, and engine execution lo

Fusion-Task-Id: FN-3490
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