Commit Graph

1031 Commits

Author SHA1 Message Date
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
gsxdsm
a3ce8e1f8e fix(FN-XXX): unify codex auth and chat fallback 2026-05-03 23:08:05 -07:00
Fusion
be7be0957d feat(FN-3345): fix lint and typecheck issues in engine verification-utils
Cleans up lint and type errors in the engine by removing unused imports from executor and merger, and replacing `any` types with proper type annotations in verification-utils.

Fusion-Task-Id: FN-3345
2026-05-03 20:08:24 -07:00
gsxdsm
4a4028f526 chore(release): v0.17.1
Version bump via changesets.
2026-05-03 19:37:04 -07:00
gsxdsm
5bfa6a37d8 fix: respect agent model selection in heartbeat and manual runs
Heartbeat read non-existent split modelProvider/modelId fields while the
dashboard saves runtimeConfig.model as combined "provider/modelId", so
sessions fell through to pi's default model and failed with
"No API key for provider: openai-codex". Add extractRuntimeModel helper
that prefers the combined string and use it from heartbeat.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 17:37:02 -07:00
gsxdsm
7bccf6860b chore(release): v0.17.0
Version bump via changesets.
2026-05-03 17:26:39 -07:00
gsxdsm
6d4408c179 fix(FN-3305): preserve task branch on worktree conflict retry 2026-05-03 17:24:19 -07:00
gsxdsm
07e9825d9b fix(FN-3305): reset mergeRetries when dispatching tasks to in-progress
A task whose previous run exhausted its merge budget (mergeRetries=MAX)
could land back in in-review with status=null, where the merger refused
it (canMergeTask false) and the ghost-review fallback bounced it back to
todo every taskStuckTimeoutMs (10 min) — beating the 30 min merge
cooldown reset. Each fresh execution now starts with mergeRetries=0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 17:17:04 -07:00
Fusion
00cdc8a1ac feat(FN-3338): fix project root resolution in registerExtensionProviders an
The merge adds an auto-reload setting (FN-3334) with UI controls in the settings modal, documentation, and a new version-check module, while also fixing a bug (FN-3338) where extension providers incorrectly resolved the project root when invoked from git worktrees — moving the project-root resolutio

Fusion-Task-Id: FN-3338
2026-05-03 16:34:56 -07:00
Fusion
d7e2a3ec42 feat(FN-3335): fix worktree project root resolution in createFnAgent and ad
Merges FN-3335 (worktree project resolution) and FN-3333 (spurious version reloads). The engine's `createFnAgent` now resolves project root from the worktree's cwd rather than the parent process, with `resolveProjectRoot` added to skill-resolver for consistency. The dashboard's `versionCheck` was up

Fusion-Task-Id: FN-3335
2026-05-03 16:01:17 -07:00
gsxdsm
9e7de0cecb fix(engine): teach merger fix agent to rebuild stale dist artifacts
The verification-fix agent prompt previously forbade modifying files
unrelated to the failure, which blocked the natural fix when
deterministic merge verification failed because of stale/missing
plugin `dist/` outputs in sibling workspace packages (e.g.
`Failed to resolve import "./cli-spawn.js"` from
`fusion-plugin-hermes-runtime/dist`).

- Add explicit guidance to detect stale-artifact failure signatures
  and rebuild the affected package(s) before editing source.
- Allow the agent to fix pre-existing breakage on the base branch,
  preferring the smallest change that makes verification green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 14:27:02 -07:00
Fusion
a1b74de12b feat(FN-3319): enrich agent heartbeat callbacks with reason in UI
Enriched agent heartbeat callbacks with a `reason` parameter propagated through the engine, in-process runtime, and dashboard components (AgentDetailView, AgentListModal, AgentsView). Added a new `agentHealth.tsx` utility and corresponding test file to surface the reason in UI health status, with te

Fusion-Task-Id: FN-3319
2026-05-03 12:47:08 -07:00
gsxdsm
d61eb3e8c0 fix(engine): widen AuthStorage cast in proxy set trap to satisfy tsc
TS2352: Direct conversion from AuthStorage to Record<string|symbol, unknown>
no longer overlaps. Route through `unknown` so the proxy set trap continues
to forward writes to the underlying target.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 11:41:09 -07:00
Fusion
d01be28d9b feat(FN-3305): add models.json API key fallback resolution
The merge restores Claude usage tracking by introducing a Proxy-based auth storage with a fallback resolver that falls back to `models.json` API keys when the primary auth store lacks credentials. It also adds planning improvements with corresponding tests and a context limit detector enhancement, a

Fusion-Task-Id: FN-3305
2026-05-03 11:28:42 -07:00
Fusion
ec80d98d2a feat(FN-3302): restore Claude usage tracking with Fusion Anthropic auth sto
Restores Claude usage tracking across the dashboard by integrating with Fusion Anthropic auth storage, and adds detection and testing for the `model_context_window_exceeded` stop reason to handle context limit errors gracefully. The work spans planning logic, usage tracking, mission management UI, a

Fusion-Task-Id: FN-3302
2026-05-03 11:06:27 -07:00
Fusion
f2fa44e270 feat(FN-2999): harden research lifecycle with idempotent cancel/retry, SSE
Merges FN-2999 research hardening (idempotent cancel/retry routes, aligned SSE event wiring, and cleaned status handling in the core research store and orchestrator) plus UI improvements to AgentDetailView header actions and planning disclosure UX in the modal, with a CSS token fallback fix in Scrip

Fusion-Task-Id: FN-2999
2026-05-03 09:11:04 -07:00
Fusion
3878132c4e feat(FN-3207): remove runtime memory-backend side-load
Merged FN-3207 and FN-3242: streamlined the memory backend by removing the runtime side-load pattern in `project-memory.ts` (simplified from 25+ lines), added regression tests across core, engine, and CLI bundle to catch the import issue at build time, and updated ChatView with a CSS fix for file me

Fusion-Task-Id: FN-3207
2026-05-03 07:24:14 -07:00
gsxdsm
abeeec53bd chore(release): v0.16.0
Version bump via changesets.
2026-05-03 02:09:54 -07:00
Harry Cordewener
aa45fec231 fix: reconcile Fusion two-segment skill names with pi-coding-agent bare names
pi-coding-agent sets Skill.name to the parent directory (e.g. 'web-research'),
while Fusion uses two-segment names everywhere (e.g. 'web-research/SKILL.md')
from extractSkillName(), normalizeAgentSkills(), and toggleExecutionSkill().

The previous fix (c9043519) correctly switched matching from skill.filePath to
skill.name, but that only works when both sides use the same format. Since they
don't, all pattern/requested-name comparisons still failed, producing the
spurious 'not found in discovered skills' warnings.

Fix: add bareSkillName() helper that strips the /SKILL.md suffix before
comparison. Applied to all five comparison points in skill-resolver.ts:
  - skillNameMatches() (pattern filtering)
  - requestedSkillNames set lookup (name filtering)
  - hasDiscoveredMatch() (configured-pattern diagnostic)
  - discoveredBareNamesLower (requested-name diagnostic)
  - excluded-path discovery check
2026-05-03 02:16:48 -05:00
gsxdsm
8d9b05e70b fix(triage): stop clobbering freshly-written PROMPT.md specs on title sync
`TriageProcessor.finalizeApprovedTask` (added in FN-3056) called
`store.updateTask({title})` while the task was still in column='triage',
which triggered a pre-existing regen path in `TaskStore.updateTask` that
overwrote the agent's just-written specification with the bootstrap stub
(`# {id}: {title}\n\n{description}\n`). Tasks shipped to `todo` (and
through to `done`) with empty 70–200 byte specs while the executor only
saw the original one-line user description. The same regen path also
silently dropped `## Review Level` / `## Frontend UX Criteria` and any
section outside a fixed whitelist whenever a non-triage task's title or
description was edited.

Replaces the regen with wrapper-shape-exact stub detection (compare to
the bytes `createTask` would have written for the pre-update title and
description) plus surgical edits for real specs: title changes splice
only the leading `# ...` heading, description changes rewrite only the
body of `## Mission`, and every other section is preserved verbatim.
`finalizeApprovedTask` now applies the prompt-declared title after
`moveTask("todo")` as defense in depth. New regression tests cover real
specs surviving title sync, long bootstrap stubs, stubs whose body
contains `##` markdown or `**Created:**` text, and the end-to-end
triage finalize sequence on a real `TaskStore`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 23:41:45 -07:00
Harry Cordewener
c904351954 fix: skill discovery path doubling and pattern/name matching
Three related bugs that prevent agent skills from loading:

1. **Doubled "skills/" prefix in discovery** (skills-adapter.ts)
   `discoverSkills()` unconditionally prepends "skills/" to the relative
   path, but `baseDir` points to the parent of the skills directory
   (e.g. `~/.fusion/agent`), so `relative()` already returns a path
   starting with "skills/". Result: IDs like
   `auto::skills/skills/web-research/SKILL.md` instead of
   `auto::skills/web-research/SKILL.md`.

   Fix: only prepend "skills/" when the relative path does not already
   start with it.

2. **normalizeAgentSkills does not extract name from full ID**
   (session-skill-context.ts)
   The dashboard saves full skill IDs (e.g.
   `"auto::skills/web-research/SKILL.md"`) into agent
   `metadata.skills`. The runtime matches these against
   `skill.name` (e.g. `"web-research/SKILL.md"`) — they never match,
   so agent skills silently fail to load.

   Fix: when an entry contains "::", parse out the skill name (last
   two path segments) before matching.

3. **Pattern matching uses absolute filePath instead of skill name**
   (skill-resolver.ts)
   Settings patterns written by `toggleExecutionSkill()` are relative
   (e.g. `"web-research/SKILL.md"`), but the resolver compares them
   against `skill.filePath` which is absolute. Patterns can never
   match, producing spurious "not found in discovered skills" warnings.

   Fix: match patterns against `skill.name` (case-insensitive) with
   fallback to exact `skill.filePath` match for backward compatibility.
2026-05-03 01:15:56 -05:00
Fusion
d1cb401a0d feat(FN-3156): add database schema init hook runner for plugin settings lif
The merge adds plugin schema initialization lifecycle support (FN-3156), introduces a ResearchTaskActionModal with model fallback notifications (FN-3012, FN-3008), adds async planning draft sync to prevent UI blocking (FN-3229), and implements viewport-conditional mission split layout (FN-3130). Inf

Fusion-Task-Id: FN-3156
2026-05-02 20:30:18 -07:00
Fusion
68f34dd0f7 feat(FN-3008): notify when model settings fall back to defaults
Merges FN-3008 to add a "fallback-used" notification system: the engine now emits events when AI model fallbacks are triggered, dispatches notifications via ntfy/webhook providers, surfaces a session banner in the dashboard, and exposes a settings toggle to enable or disable these alerts.

Fusion-Task-Id: FN-3008
2026-05-02 19:55:54 -07:00
gsxdsm
1aa1e723f6 chore(build,test): split desktop/mobile from default build; share vitest worker budget
- pnpm build now excludes @fusion/desktop and @fusion/mobile by default
  (recursive build still available as pnpm build:all). Saves time on
  workspace-wide builds that don't need the native shells.
- Hoist the per-package max-worker computation into a shared
  packages/core/src/__test-utils__/vitest-workers.ts util. Every
  vitest.config.ts now calls computeMaxWorkers(), which honors
  VITEST_MAX_WORKERS, FUSION_TEST_TOTAL_WORKERS, and a per-config
  defaultCap, clamped to cpus-1.
- pnpm test sets VITEST_MAX_WORKERS=2 so the workspace run keeps total
  fan-out modest with --workspace-concurrency=2.
- Switch dashboard vitest pool from forks to threads so jsdom/React
  suites share a V8 heap instead of duplicating ~500MB per worker.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 15:56:15 -07:00
gsxdsm
99f5ca3fb3 chore(deps): bump pi-ai and pi-coding-agent from 0.70.0 to 0.72.1
Refreshes the built-in model catalog feeding ModelRegistry with the
latest entries upstream pi-ai generates from models.dev (Anthropic,
OpenAI, Codex, Bedrock, etc.). No Fusion-side API changes; upgrades
applied in cli, dashboard, and engine package.json plus lockfile.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 15:49:07 -07:00
gsxdsm
117224ba8f fix(engine): give merge commits a real subject in fallback paths
Three merger fallback commit paths (auto-resolve-all-conflicts,
-X theirs/ours side strategy, AI-agent-didn't-commit) hard-coded
`feat(FN-XXXX): merge fusion/fn-xxxx` as the subject and never used
the AI subject summarizer. Route them through buildDeterministicMergeMessage
so they pick up aiSubject when available.

When the AI subject summarizer returns null, derive the subject from
the branch's first step commit (with conventional-commit prefix
stripped, plus `(+N more)` for multi-commit branches) instead of the
bare `merge <branch>` template.

Bump DEFAULT_COMMIT_SUBJECT_TIMEOUT_MS 15s → 30s so slow-first-token
providers complete instead of silently falling back.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 13:32:47 -07:00
Fusion
bb79f56f8f feat(FN-3106): add draft planning workflow with createAiSession plugin API
This merge delivers the full draft planning feature (FN-3106) — API routes for planning subtasks, the AiSessionStore backend for draft sessions, a draft planning API client, auto-creation of planning drafts from user input, and corresponding UI polish in PlanningModeModal with accessibility-focused

Fusion-Task-Id: FN-3106
2026-05-02 13:32:09 -07:00
Fusion
8cdc0ff449 feat(FN-3155): add createAiSession plugin context API with DI wiring
This merge brings FN-3155's plugin `createAiSession` API (types, DI hooks, engine adapter, context wiring, docs, and tests), FN-3056's task title sanitization, and FN-3129's tokenized footer and mobile initialization for MissionManager. It also adds CentralCore Docker node management, a new AddNodeM

Fusion-Task-Id: FN-3155
2026-05-02 13:24:37 -07:00
Fusion
583822739b feat(FN-3056): merge fusion/fn-3056
This merge ships several feature and infrastructure improvements across the codebase. Task title validation is strengthened in triage with stricter rejection of malformed titles and preference for prompt-declared titles (FN-3056), while task creation now preserves priority settings (FN-3210). The Mi

Fusion-Task-Id: FN-3056
2026-05-02 11:41:40 -07:00
Fusion
656df5de29 feat(FN-3202): handle manual PR linking and feedback follow-ups
- Add scheduler logic to create dependency-linked follow-up tasks when actionable PR feedback remains after a PR is merged or closed
- Update engine runtime/project wiring to support manual PR create flows and branch publish behavior for fusion/<task-id>
- Add dashboard route coverage for manual PR creation/linking behavior and corresponding engine/runtime tests
- Document manual PR branch conventions and follow-up behavior in task management and dashboard docs

Fusion-Task-Id: FN-3202
2026-05-02 10:59:56 -07:00
Fusion
fce79cece0 feat(FN-3185): preserve progress on task reset with explicit confirmation d
This merge implements a "preserve progress" option for task resets across the system. FN-3185 adds a `preserveProgress` flag to `moveTask` that keeps status/history when resetting tasks back to `todo`, with required explicit confirmation dialogs to prevent accidental resets. The feature is wired thr

Fusion-Task-Id: FN-3185
2026-05-02 10:20:44 -07:00