87ffb24fcacb75f671739a67d8dbfec836afc4e9
1264 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
daa34fbc38 |
fix: refineTask/duplicateTask fail in backend (PostgreSQL) mode (#2253)
## Summary Eliminates the remaining backend/PostgreSQL-mode sync-SQLite (`store.db`) call sites — both the crashing ones and the try/catch-masked ones that silently degraded features. Found via a full audit of `store.db`/`archiveDb` residue after the PG cutover's per-site routing missed them. **Crashes fixed:** 1. **refineTask / duplicateTask** threw `TaskStore.db: SQLite Database is not available in backend mode`. Both create rows through `createTaskWithId` callbacks calling `store.atomicCreateTaskJson()` directly, bypassing `_createTaskInternal`'s backend routing. The shared helper now routes itself (soft-delete conflict check + non-destructive insert in one AsyncDataLayer transaction). 2. **Merger verification cache**: `getVerificationCacheHit` ran sync SQLite unguarded *outside* any try/catch in `runDeterministicVerification`; `recordVerificationCachePass` was swallowed so the cache never warmed. Both are now async with a PG branch. **Silent degradations fixed (features that were dead on PG):** - Workflow run-branch + foreach step-instance persistence (`saveWorkflowRunBranch`, `loadWorkflowRunBranches`, `clearWorkflowRunBranches`, `saveWorkflowRunStepInstance`, `loadWorkflowRunStepInstances`, `clearWorkflowRunStepInstances`) — executor crash-resume checkpoints were silently never persisted. - `getBranchProgressByTask` — returned an empty map, dropping `branchProgress` from task payloads. - `runPluginColumnTransitionHooks` — plugin `onEnter`/`onExit` column-transition hooks never fired (marker bookkeeping + non-locking task read now async). - `getTaskColumns` — dashboard treated all agent-linked tasks as non-terminal. - `getWorkflowStep` / `listWorkflowSteps` — stored workflow-step rows now read from `project.workflow_steps` (listing previously returned plugin steps only); `getLegacyWorkflowStepSnapshot` returns `undefined` on PG (legacy snapshot exists only in pre-migration SQLite). - `readRawProjectSettings` / `listWorkflowPromptOverridesForProject` — now read via the async layer. These store methods became **async**; engine/dashboard callers await them (the workflow persistence interfaces already accepted `Promise`-returning impls). **PG gotcha encoded in the fixes:** migration `0006_project_ownership` rebuilds every project-schema PK to lead with `project_id`, so column-list `ON CONFLICT` inference fails (42P10) — upserts target the PK by constraint name. ## Surface Enumeration - Creators through `atomicCreateTaskJson`: `refineTaskImpl`, `duplicateTaskImpl` (fixed); `_createTaskInternalImpl` unaffected (already routed). - Verification-cache callers (all merger, all 3 sites now awaited). - Run-branch/step-instance callers: executor persistence adapters, parse-steps foreach probe, integration-queue flip, crash-resume reconcile, graph-reset cleanup; triage replan cleanup; dashboard spec-rebuild pin clears; agent-reflection rework summing — all awaited. - Audit classified everything else as guarded or sync-mode-only (dead in production — every entry point constructs stores via `createTaskStoreForBackend`). ## Symptom Verification - **Original symptoms:** refinement/duplicate creation threw; merge verification threw; workflow checkpoints/branch progress/plugin hooks/task-column lookups silently no-oped on PostgreSQL. - **Exact reproduction:** `refine-duplicate-task.pg.test.ts`, `verification-cache.pg.test.ts`, and `sync-db-residue-backend.pg.test.ts` exercise each surface against embedded-PostgreSQL backend-mode TaskStores. - **Assertion it is gone:** all suites pass (14 + 5 tests), plus `transition-pending-and-status-clear.pg.test.ts`, `create-task-reserved-id.pg.test.ts`, dashboard `routes-github.test.ts` (123), engine `triage.test.ts` (221) and `agent-reflection.test.ts` (31). Core/engine/dashboard typecheck fully clean: the 13 errors from the FN-8142 pi SDK migration are fixed by bumping @earendil-works/pi-ai/pi-coding-agent to ^0.80.10 (FN-8142 used APIs absent from the previously locked 0.80.6). Locally green: `pnpm verify:fast` (scoped typecheck + build + CLI build + boot smoke), `pnpm test:gate`, and `pnpm lint`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed refinement/duplication task creation in PostgreSQL-backed backend mode. * Improved backend-mode persistence for workflow checkpoints, foreach-step instances, branch progress, and cleanup flows (including retries/resets/transitions), so stored data reliably round-trips. * Hardened backend-mode reads for workflow steps, task columns, project settings, and prompt overrides. * Made verification-cache reads/writes complete reliably, including command-specific cache behavior. * **Tests** * Added PostgreSQL integration/regression coverage for refinement/duplication, sync residue, and verification caching. * **Chores** * Bumped `@earendil-works/pi-ai` and `@earendil-works/pi-coding-agent` to `^0.80.10`. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
9a37415887 |
fix(engine): add honest blocked exit to fn_task_done so impossible tasks park failed instead of laundering to done (#2256)
## What & why
FN-8141 ("Update pi SDK to latest and verify Kimi K3 end to end") was
impossible as specced — pi 0.80.x removed `AuthStorage`/`ModelRegistry`
APIs, so every SDK bump broke the build. The executor correctly reverted
its work and filed follow-up FN-8145 — but had **no sanctioned way to
end the task in a blocked state**. `fn_task_done` only expressed
success: the bulk-completion gate refused it, the requeue budget re-ran
the doomed task 5 times, and the only remaining affordance (mark every
step `skipped`, then complete) made `isTaskComplete()` return true.
Self-healing then promoted the "complete" todo to in-review and the AI
merger finalized the empty diff as `done`. **The honest path must be
cheaper than the laundering path.**
This adds a first-class **blocked** outcome to the executor's
`fn_task_done` tool.
## Change
- `fn_task_done` gains `outcome: "completed" | "blocked"` (default
`"completed"`), optional `blockedBy: string[]`, and `reason` (required
when blocked).
- `outcome="blocked"` runs **before** every completion gate (completion
blocker, verdict providers, worktree invariants, bulk-completion
refusal) — blocked is not a completion claim, so none of those gates
apply.
- Parks the task `failed` with `error = "BLOCKED: <reason>"`, following
the FN-7863 `EXECUTION_DISPATCH_LOOP_EXHAUSTED` park convention: **steps
keep their true statuses** (no auto-done, no auto-skip), worktree/branch
preserved. It does **not** call `onDone()`, so the executor's existing
`status === "failed"` post-loop branch honors the park instead of
handing off to review.
- `blockedBy` is recorded as real `task.dependencies` edges (unioned
with existing) so the task requeues behind the blocker.
- Emits run-audit `task:execution-blocked-parked` with ids/outcomes-only
metadata (`taskId`, `blockedBy` ids, `hasReason` boolean — **never** the
reason prose).
- Executor + core prompt guidance and the
`bulk-step-completion-without-review` refusal message now name the
blocked exit as **the** correct action when work cannot proceed,
replacing skip-and-done. `PREMISE STALE:` skip guidance is preserved for
genuinely-stale premises.
## Surface enumeration
- **fn_task_done tool schema + handler**
(`packages/engine/src/executor.ts`): blocked branch added at the top of
`execute`, before all gates.
- **Refusal/requeue machinery**: `formatTaskDoneRefusal` for
`bulk-step-completion-without-review` now points at the blocked exit;
the requeue-budget path is untouched (blocked never enters it).
- **Executor prompt text**: turn-ending rules, the "Cannot proceed"
section, the preflight/stale-premise escape hatch (now explicitly
distinguishes stale-premise skip from blocked).
- **Core prompt mirror** (`packages/core/src/agent-prompts.ts`): same
turn-ending + cannot-proceed guidance.
- **Tool reference doc**
(`packages/cli/skill/fusion/references/engine-tools.md`): `fn_task_done`
params updated. (grep for `fn_task_done` confirmed the only executable
tool schema is in executor.ts; CLI/pi surfaces re-export it, no separate
schema copy.)
- **Self-healing**: verified a blocked-parked row is NOT auto-recovered
by `recoverStrandedCompletedTodoTasks` — its steps are not all
done/skipped and `task.error` is set (both are hard filters in the
sweep).
- **Run Audit inventory** (`AGENTS.md`): documented the new event.
## Test evidence
New `packages/engine/src/__tests__/executor-task-done-blocked.test.ts`
(8 tests) asserts the invariant across surfaces:
```
pnpm --filter @fusion/engine exec vitest run \
src/__tests__/executor-task-done-blocked.test.ts \
src/__tests__/executor-task-done-invariant.test.ts \
src/__tests__/gating-classifications.test.ts \
src/__tests__/reliability-interactions/execute-requeue-loop-guard.test.ts --reporter=dot
→ Test Files 3 passed | Tests 138 passed (0 failed)
```
Coverage: blocked parks failed with `BLOCKED:` error and does **not**
trip the bulk-completion refusal or requeue to todo; `blockedBy` unioned
into `dependencies`; `task:execution-blocked-parked` emitted with
metadata that excludes the reason prose; steps left untouched; empty
`reason` rejected without parking; `completed` outcome unchanged (still
marks steps done, no blocked audit); and
`recoverStrandedCompletedTodoTasks` never promotes a blocked-parked row.
### Note on `pnpm verify:fast`
`verify:fast` currently fails at the workspace build step due to
**pre-existing** type errors in `packages/engine/src/auth-storage.ts`,
`pi.ts`, and `provider-registration.ts` — the exact FN-8142 pi SDK API
break that FN-8145 will fix. These are present on the base branch and
untouched by this PR. Verified instead that this change introduces
**zero** new type errors (`tsc` diff before/after, engine and core both
clean) and that all scoped tests are green.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus <noreply@anthropic.com>
|
||
|
|
fd43a57a41 |
FN-8179: align pi SDK versions with ModelRuntime API
Align workspace pi SDK dependencies with the ModelRuntime API required by the engine. - Pin pi AI and coding-agent packages to 0.80.10 across workspace consumers. - Keep session option typing compatible with the updated SDK contract. - Add a patch changeset and regenerate the dependency lockfile. Files changed: .changeset/fn-8179-pi-sdk-align.md | 7 + packages/cli/package.json | 4 +- packages/core/package.json | 2 +- packages/dashboard/package.json | 2 +- packages/engine/package.json | 4 +- packages/engine/src/pi.ts | 8 +- packages/pi-claude-cli/package.json | 8 +- .../src/thinking-config.ts | 9 +- pnpm-lock.yaml | 947 +++++++++++---------- pnpm-workspace.yaml | 5 + 10 files changed, 520 insertions(+), 476 deletions(-) Fusion-Task-Id: FN-8179 Fusion-Task-Lineage: aef45c2e-f353-4014-93de-44be91f43293 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
5a60643c0a |
FN-8142: migrate auth storage and model runtime to pi SDK
Migrate Fusion's credential and model integrations to pi SDK 0.80.8+. - Replace legacy AuthStorage initialization with a locked Fusion credential store and ModelRuntime-backed registry. - Wire asynchronous model initialization and refresh through CLI, desktop, dashboard, executor, and provider paths. - Update provider, routing, and registry tests for the new SDK contracts. Files changed: packages/cli/src/commands/__tests__/daemon.test.ts | 2 +- .../cli/src/commands/__tests__/dashboard.test.ts | 9 +- .../cli/src/commands/__tests__/onboard.test.ts | 1 + packages/cli/src/commands/__tests__/serve.test.ts | 2 +- packages/cli/src/commands/daemon.ts | 19 +- packages/cli/src/commands/dashboard.ts | 20 +- packages/cli/src/commands/onboard.ts | 6 +- packages/cli/src/commands/serve.ts | 19 +- packages/cli/src/commands/startup-model-sync.ts | 4 +- packages/core/src/__tests__/openai-models.test.ts | 17 +- ...-model-routes-openai-codex-supplemental.test.ts | 17 +- ...register-model-routes-zai-real-registry.test.ts | 15 +- packages/dashboard/src/routes.ts | 12 +- .../dashboard/src/routes/register-model-routes.ts | 2 +- packages/desktop/src/local-runtime.ts | 2 +- packages/desktop/src/local-server.ts | 2 +- .../custom-providers-openai-completions.test.ts | 16 +- .../custom-providers-openai-responses.test.ts | 16 +- .../engine/src/__tests__/executor-test-helpers.ts | 2 +- .../src/__tests__/pi-create-fn-agent.test.ts | 8 +- .../engine/src/__tests__/pi-layers-wiring.test.ts | 2 +- packages/engine/src/__tests__/pi.test.ts | 47 ++--- .../src/__tests__/provider-registration.test.ts | 17 +- packages/engine/src/auth-storage.ts | 218 ++++++++++++++++++--- packages/engine/src/custom-provider-registry.ts | 14 +- packages/engine/src/executor.ts | 15 +- packages/engine/src/pi.ts | 50 +++-- packages/engine/src/provider-auth.ts | 58 +++--- packages/engine/src/provider-registration.ts | 16 +- 29 files changed, 421 insertions(+), 207 deletions(-) Fusion-Task-Id: FN-8142 Fusion-Task-Lineage: 8ae79064-7820-4976-9645-9431b5a3129e Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
c6be0b158b |
FN-8129: centralize database backup settings
Move database backup policy and scheduling to shared global configuration. - Split project memory backups from cluster-wide database backup settings. - Migrate legacy backup values and routines safely into central global storage. - Schedule and dispatch one shared PostgreSQL backup routine across project engines. Files changed: .changeset/fn-8129-backup-settings-scope-split.md | 7 + docs/dashboard-guide.md | 2 + docs/settings-reference.md | 10 +- packages/cli/src/commands/backup.ts | 3 +- .../__tests__/backup-settings-migration.test.ts | 50 ++++++ .../src/__tests__/backup-settings-scope.test.ts | 27 +++ packages/core/src/backup-settings-migration.ts | 188 +++++++++++++++++++++ packages/core/src/backup.ts | 77 +++++---- packages/core/src/global-routine-store.ts | 104 ++++++++++++ packages/core/src/index.gate.ts | 6 +- packages/core/src/index.ts | 6 +- .../core/src/postgres/migrations/0000_initial.sql | 19 +++ .../postgres/migrations/0015_global_routines.sql | 19 +++ packages/core/src/postgres/schema-applier.ts | 19 ++- packages/core/src/postgres/schema/central.ts | 21 ++- packages/core/src/postgres/startup-factory.ts | 11 ++ packages/core/src/settings-schema.ts | 14 +- packages/core/src/types.ts | 31 +++- .../dashboard/app/components/SettingsModal.tsx | 10 +- .../settings/__tests__/section-keys.test.ts | 1 + .../app/components/settings/save-split.ts | 2 + .../search/__tests__/settings-search-index.test.ts | 1 + .../settings/search/entries.ts | 2 + .../app/components/settings/section-keys.ts | 4 - .../settings/sections/BackupsSection.search.ts | 40 ----- .../settings/sections/BackupsSection.tsx | 112 +----------- .../sections/DatabaseBackupsSection.search.ts | 51 ++++++ .../settings/sections/DatabaseBackupsSection.tsx | 142 ++++++++++++++++ .../settings-default-descriptions.test.tsx | 1 + packages/dashboard/src/routes.ts | 12 +- .../src/routes/register-settings-memory-routes.ts | 41 ++--- .../engine/src/__tests__/routine-scheduler.test.ts | 55 +++++- packages/engine/src/cron-runner.ts | 4 +- packages/engine/src/routine-runner.ts | 67 +++++--- packages/engine/src/routine-scheduler.ts | 35 +++- 35 files changed, 929 insertions(+), 265 deletions(-) Fusion-Task-Id: FN-8129 Fusion-Task-Lineage: af17f39a-7f1c-40ff-8a4a-cd63895cd532 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
478f226a54 |
test: green full-suite CI after main drift (#2229)
## Summary Restores green **Full Suite (non-blocking)** runs on `main`. Recent main merges left i18n key parity, schema baseline bookkeeping (0011→0012), heartbeat tool inventory (FN-8058 `fn_task_logs_read`), and merger whitespace-classification mocks (execFile `git diff -p -w :2: :3:`) out of date, so all four test shards failed. ## Root causes observed on main - **Shard 4 / `@fusion/i18n`**: missing `skipConfirmationDialogs*` + `reviewBudgetExhausted` in non-en locales; orphan `awaitingApprovalPlanReviewReplanCap` - **Shard 3 / `@fusion/core`**: `SCHEMA_BASELINE_VERSION` advanced to `0012` while tests still equated it with `OWNER_PROJECT_ID_SPLIT_VERSION` (`0011`) and omitted `0012` from applied-migration lists - **Shards 1–2 / `@fusion/engine`**: tool count/snapshot drift for `fn_task_logs_read`; merger tests still mocked `git diff-tree` for trivial classification after the execFile `:2:`/`:3:` cutover; mock provider `updateTask` arity drift ## Changes - Locale catalogs: add missing keys, drop orphan key - Schema applier tests: immutable 0011 identity + baseline 0012 lists - Heartbeat + gating snapshots: include `fn_task_logs_read` - Merger unit mocks: recognize `git diff -p -w :2:path :3:path` - Mock provider: accept optional third `updateTask` arg ## Test plan - [x] `pnpm --filter @fusion/i18n exec vitest run` — 23/23 - [x] `pnpm --filter @fusion/core exec vitest run src/__tests__/postgres/schema-applier.test.ts` (immutable + automation upgrade) — pass - [x] `pnpm --filter @fusion/core exec vitest run` project-identity + satellite-fusiondir — pass - [x] Engine suites from failed CI shards (file-scoped, hermes/openclaw/paperclip/grok, reliability post-finalize/mission, heartbeat, gating, merger recovery/prompt, mock-provider, etc.) — pass - [ ] Full Suite workflow green on merge to main <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Improved project data isolation across backend operations. - Added safer optional toast handling when UI components render outside the full application shell. - Added support for reading task logs during agent heartbeat sessions. - **Bug Fixes** - Prevented runtime probes from hanging and avoided scanning large binary files. - Improved path handling for workspaces with missing descendants. - Corrected task retry state resets and GitHub import/issue-close behavior. - **Style** - Improved chat, terminal, and settings spacing. - Added clearer accessibility labeling for the auto-merge control. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
f57dfc03b6 |
FN-8105: remove archived task worktrees safely
Archive task worktrees through a store-scoped, race-safe disposal lifecycle. - Reserve pinned worktree paths during archive cleanup and successor creation. - Reconcile quarantined removals before reusing a pinned path. - Gate PostgreSQL archival before destructive worktree disposal and wire CLI cleanup. Files changed: .changeset/fn-8105-archive-removes-worktree.md | 7 + docs/task-management.md | 4 + .../extension-experiment-finalize.test.ts | 1 + .../src/__tests__/extension-fn-secret-get.test.ts | 1 + .../extension-gitlab-tracking.test.ts | 1 + .../cli/src/__tests__/extension-web-fetch.test.ts | 1 + .../task-command-github-import-tracking.test.ts | 1 + packages/cli/src/commands/__tests__/task.test.ts | 1 + packages/cli/src/commands/task.ts | 8 +- packages/cli/src/extension.ts | 4 + .../__tests__/worktree-path-reservation.test.ts | 58 ++++++++ packages/core/src/archive-worktree-disposer.ts | 21 +++ packages/core/src/index.gate.ts | 13 ++ packages/core/src/index.ts | 13 ++ .../core/src/task-store/archive-lifecycle-2.ts | 8 ++ packages/core/src/task-store/archive-lifecycle.ts | 37 +++++ packages/core/src/worktree-path-reservation.ts | 149 +++++++++++++++++++++ .../src/archive-worktree-disposer-install.ts | 18 +++ packages/engine/src/executor.ts | 16 +++ packages/engine/src/index.ts | 2 + packages/engine/src/runtimes/in-process-runtime.ts | 1 + packages/engine/src/worktree-acquisition.ts | 27 +++- 22 files changed, 388 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-8105 Fusion-Task-Lineage: cabb8f52-093f-4986-bfda-2c7601a72579 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
d306ab67b2 |
FN-8140: reuse host TaskStore across extension loads
Reuse process-wide extension store state to prevent duplicate backend boots from blocking agent reads. - Share TaskStore cache, boot-inflight, and failure cooldown state across ESM module instances. - Preserve host-injected stores when cold boots race and add bounded boot-resolution coverage. - Add a patch changeset for responsive agent reads. Files changed: .changeset/fn-8140-taskstore-boot-timeout.md | 7 ++ .../src/__tests__/extension-tool-timeout.test.ts | 88 +++++++++++++++++++++- packages/cli/src/extension.ts | 48 ++++++++++-- 3 files changed, 136 insertions(+), 7 deletions(-) Fusion-Task-Id: FN-8140 Fusion-Task-Lineage: de32f4e9-5870-4d8f-8454-2fe342a575a8 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
c803a2d906 |
FN-8100: restore PostgreSQL task delegation collision coverage
Restore PostgreSQL-backed collision coverage for the built task-delegation extension. - Seed an occupied task ID through the shared PostgreSQL TaskStore. - Override the allocator once to exercise the real unique-violation error path. - Assert that fn_delegate_task returns the structured task-ID collision error. Files changed: .../src/__tests__/extension-integration.test.ts | 53 +++++++++++++--------- 1 file changed, 32 insertions(+), 21 deletions(-) Fusion-Task-Id: FN-8100 Fusion-Task-Lineage: d26b825e-2abd-482e-899e-51c0db753176 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
fcd400f02e |
FN-8097: harden CLI package-lane test builds
Stabilize CLI package-lane tests with reliable asset builds and PostgreSQL-backed fixtures. - add stale-lock recovery and deterministic coverage for CLI asset builds - migrate affected CLI tests to shared PostgreSQL harnesses and async build setup - restore delegate collision coverage and clean bundled extension caches Files changed: .../src/__tests__/bundle-output-helpers.test.ts | 185 ++++++++++++---- .../cli/src/__tests__/bundle-output-helpers.ts | 240 +++++++++++++++------ packages/cli/src/__tests__/bundle-output.test.ts | 4 +- .../extension-agent-set-instructions.test.ts | 56 ++--- .../src/__tests__/extension-agent-update.test.ts | 58 ++--- .../src/__tests__/extension-integration.test.ts | 25 ++- packages/cli/src/__tests__/task-plan.test.ts | 67 +++--- packages/cli/src/__tests__/task-steer.test.ts | 56 ++--- .../src/commands/__tests__/agent-export.test.ts | 42 +++- 9 files changed, 481 insertions(+), 252 deletions(-) Fusion-Task-Id: FN-8097 Fusion-Task-Lineage: 7c84efe0-eb5b-4d65-b8ca-ad71926dc84c Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
c484964b82 |
FN-8102: fix CLI package-lane test scaffolding
Restore CLI tests to the current PostgreSQL harness and structured tool-error contracts. - Inject cached stores and project-context mocks for isolated extension and command tests - Assert structured MCP error responses for delete and lineage rejection cases - Update workflow, retry, and project mocks for current harness and core APIs Files changed: .../extension-experiment-finalize.test.ts | 21 ++++++++++-- .../src/__tests__/extension-workflow-tools.test.ts | 15 ++++++-- .../__tests__/task-command-gitlab-import.test.ts | 20 +++++++++++ .../task-delete-allow-resurrection.test.ts | 20 ++++++----- .../cli/src/__tests__/task-lineage-unlink.test.ts | 40 +++++++++++++++------- packages/cli/src/__tests__/task-retry.test.ts | 16 +++++++-- .../cli/src/commands/__tests__/project.test.ts | 4 +++ .../cli/src/commands/__tests__/task.test.ts | 6 ++++ 8 files changed, 114 insertions(+), 28 deletions(-) Fusion-Task-Id: FN-8102 Fusion-Task-Lineage: 20723ce0-77bb-4d37-9395-4191769ee752 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
2ea3c5afec |
FN-8081: migrate CLI tests to PostgreSQL harness
Migrate CLI test coverage from SQLite-specific fixtures to PostgreSQL-compatible stores. - Run built extension tests with the shared PostgreSQL TaskStore harness. - Inject the harness async layer into extension diagnostics and agent setup. - Remove SQLite-only writer-lock and collision fixtures while retaining portable retry coverage. Files changed: .../src/__tests__/extension-integration.test.ts | 115 +++++++++++---------- packages/cli/src/__tests__/extension.test.ts | 24 +++-- .../src/commands/__tests__/task-lock-retry.test.ts | 96 ++--------------- 3 files changed, 84 insertions(+), 151 deletions(-) Fusion-Task-Id: FN-8081 Fusion-Task-Lineage: 89cc39d8-0094-4486-8a9d-772b6b964bb1 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
85b854882d |
FN-8093: rescue dist-barrel coverage
Restore the isolated built-core barrel regression guard to the default CLI test lane. - Hoist recompilation and PostgreSQL fixture setup outside timed test bodies. - Inject the fixture store into the dynamic extension and retain text-budget assertions. - Skip cleanly per test when a transitive dist artifact is unavailable. - Remove the matching CLI quarantine exclusion and ledger entry. Files changed: .../src/__tests__/extension-dist-barrel.test.ts | 234 +++++++++++---------- packages/cli/vitest.config.ts | 8 +- scripts/lib/test-quarantine.json | 5 - 3 files changed, 121 insertions(+), 126 deletions(-) Fusion-Task-Id: FN-8093 Fusion-Task-Lineage: 352b3675-0579-43bc-acd9-6a11919ed646 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
78245a48a3 |
FN-8077: stabilize quarantined test timing
Make previously quarantined CLI and dashboard tests deterministic. - Use the shared PostgreSQL harness for project-context integration coverage. - Control dashboard CPU sampling time with a fake Date-only clock. - Remove both repaired tests from quarantine configuration and ledger. Files changed: packages/cli/src/__tests__/project-context.test.ts | 103 +++++++++++++-------- packages/cli/vitest.config.ts | 5 +- .../dashboard/src/__tests__/routes-system.test.ts | 17 ++-- packages/dashboard/vitest.config.ts | 6 +- scripts/lib/test-quarantine.json | 10 -- 5 files changed, 76 insertions(+), 65 deletions(-) Fusion-Task-Id: FN-8077 Fusion-Task-Lineage: 9a057928-3258-459a-9802-52f58df39c9a Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
6675cdf696 |
FN-8094: persist GitLab tracking metadata
Restore shared TaskStore persistence and hydration for GitLab tracking metadata. - Register GitLab tracking JSONB for task creation, updates, and row hydration. - Reuse the shared mapper during GitLab reconciliation and cover live/deleted reads. - Migrate GitLab extension tests to the PostgreSQL harness and add a patch changeset. Files changed: .changeset/fn-8094-gitlab-tracking-mapping.md | 7 ++ .../__tests__/extension-gitlab-tracking.test.ts | 129 ++++++++++----------- packages/cli/src/__tests__/pg-extension-harness.ts | 4 - .../store-gitlab-tracking-hydration.pg.test.ts | 85 ++++++++++++++ .../store-gitlab-tracking-reconcile.test.ts | 11 +- packages/core/src/task-store/persistence.ts | 9 +- packages/core/src/task-store/remaining-ops-2.ts | 10 +- packages/core/src/task-store/serialization.ts | 1 + packages/core/src/task-store/task-creation.ts | 2 + 9 files changed, 174 insertions(+), 84 deletions(-) Fusion-Task-Id: FN-8094 Fusion-Task-Lineage: 5e876856-cf42-4628-a5ef-ab562c1bf501 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
92a8dc8325 |
FN-8091: migrate CLI plugin persistence test to PostgreSQL
Move the CLI plugin-install persistence coverage to the shared PostgreSQL test harness. - Replace SQLite central and local database assertions with PostgreSQL schema queries. - Assert global installation and project-scoped state persistence without a local plugin store. - Clean up temporary plugin fixtures after the PostgreSQL test. Files changed: packages/cli/src/commands/__tests__/plugin.test.ts | 120 +++++++++++---------- 1 file changed, 64 insertions(+), 56 deletions(-) Fusion-Task-Id: FN-8091 Fusion-Task-Lineage: 99b8d1da-54b7-4cd3-a086-9e4461a8aa06 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
3f133e0b13 |
FN-8058: add task agent log reader
Expose paginated, filterable persisted agent logs to task-scoped and chat agent sessions. - Add the read-only fn_task_logs_read tool across engine, dashboard chat/planning, heartbeat, step, and CLI extension surfaces. - Filter agent-log entries before pagination, report matching totals, and render complete persisted rows for diagnosis. - Document the tool, add release metadata, regression coverage, and complete affected engine mocks. Files changed: .changeset/fn-8058-task-logs-read.md | 7 ++ docs/agents.md | 4 +- packages/cli/skill/fusion/SKILL.md | 2 +- .../cli/skill/fusion/references/extension-tools.md | 11 +++ .../skill/fusion/references/fusion-capabilities.md | 1 + .../extension-experiment-finalize.test.ts | 2 + .../src/__tests__/extension-fn-secret-get.test.ts | 2 + .../__tests__/extension-gitlab-tracking.test.ts | 2 + .../src/__tests__/extension-integration.test.ts | 1 + .../cli/src/__tests__/extension-web-fetch.test.ts | 2 + packages/cli/src/__tests__/extension.test.ts | 1 + packages/cli/src/extension.ts | 34 ++++++++ .../src/__tests__/agent-logs-backend-mode.test.ts | 28 +++++- packages/core/src/store.ts | 11 ++- packages/core/src/task-store/remaining-ops-7.ts | 16 +++- packages/core/src/types.ts | 1 + packages/dashboard/src/__tests__/chat.test.ts | 1 + .../planning-answered-question-reemit.test.ts | 1 + .../planning-generation-cancellation.test.ts | 1 + packages/dashboard/src/chat.ts | 5 ++ packages/dashboard/src/planning.ts | 3 + .../__tests__/agent-task-logs-read-tools.test.ts | 72 ++++++++++++++++ packages/engine/src/agent-heartbeat.ts | 4 +- packages/engine/src/agent-tools.ts | 99 +++++++++++++++++++++- packages/engine/src/executor.ts | 6 ++ packages/engine/src/gating-classifications.ts | 2 + packages/engine/src/index.ts | 6 ++ packages/engine/src/step-session-executor.ts | 6 +- 28 files changed, 316 insertions(+), 15 deletions(-) Fusion-Task-Id: FN-8058 Fusion-Task-Lineage: 74f198b2-f538-4b39-973f-431f22e68f29 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
e3f98253cc |
feat: Quality plugin — Task QA tab, preview servers, tests, and suggested cases (#2127)
## Summary Adds a bundled **Quality** plugin (`fusion-plugin-quality`) that makes task QA easier and more visual: - **Task QA tab** (action-first): preview/test server for the task worktree, allowlisted test runs, report viewer, screenshots CTA, suggested test cases, CI handoff - **Quality hub** (left sidebar): project-wide run history and preset launches - Host **task-detail slot context** (`taskId`, worktree, `projectId`) so plugin tabs can scope correctly - `superviseSpawn` re-exported on the plugin packaging shim for published plugins - Plan: `docs/plans/2026-07-14-001-feat-quality-plugin-plan.md` ## Design constraints - Does **not** replace the merge gate — advisory orchestration only - Composes Dev Server process patterns and artifact registry (no second browser stack) - Never free-form shell; never port 4040 - Full-suite requires explicit confirm ## Test plan - [x] `pnpm --filter @fusion-plugin-examples/quality test` (15 tests) - [x] PluginSlot unit tests still pass - [ ] Enable Quality plugin in dashboard Settings → Built-in Plugins - [ ] Open Task Detail → **QA** tab with a worktree; start preview, run verify:fast, generate suggestions - [ ] Open left sidebar **Quality** hub and list runs - [ ] Confirm merge gate / PR checks unchanged ## Residual / follow-up (same plan, later units) - Deeper hub CI (host route) - Full browser-verification toggle UX + agent QA sessions (U7/U9/U10) - Richer screenshots gallery wiring to live artifacts API - Test plans CRUD polish <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added the Quality plugin with a project Quality hub and task-focused QA tab. * Added test runs, reports, preview server controls, suggested test cases, and run history. * Added configurable test presets, cancellation, status tracking, and safe command execution. * Added experimental-feature controls for enabling Quality functionality. * Bundled Quality with the CLI and made it available through the plugin manager. * **Documentation** * Added Quality plugin guidance, terminology, configuration details, and implementation planning documentation. * **Bug Fixes** * Improved process supervision so command failures and shutdown timers are handled safely. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
10b80453c4 |
FN-7978: share GitHub import dedup via sourceIssue-first helper
Unify GitHub issue import deduplication so prior imports stay marked after description edits or owner/repo casing changes. - Extract shared buildGitHubIssueSource and isGitHubIssueAlreadyImported helpers in dashboard github.ts (sourceIssue-first, case-insensitive repo, sourceMetadata + description URL fallbacks) - Route CLI import paths, extension tools, and dashboard single/batch import through the shared helpers - Drop local description-URL-regex-only importedUrls dedup; list existing tasks with slim:false for full provenance - Add regression coverage and changeset for the operator-facing fix Files changed: .changeset/fn-7978-github-import-dedup.md | 7 ++ docs/gitlab-parity-inventory.md | 2 +- packages/cli/src/__tests__/extension.test.ts | 12 ++-- .../task-command-github-import-tracking.test.ts | 6 ++ packages/cli/src/commands/__tests__/task.test.ts | 36 +++++++--- packages/cli/src/commands/task.ts | 82 +++++++++------------- packages/cli/src/extension.ts | 35 ++------- packages/dashboard/src/__tests__/github.test.ts | 22 +++++- .../dashboard/src/__tests__/routes-github.test.ts | 8 +-- packages/dashboard/src/github.ts | 62 +++++++++++++++- packages/dashboard/src/index.ts | 2 +- .../dashboard/src/routes/register-git-github.ts | 33 +-------- 12 files changed, 174 insertions(+), 133 deletions(-) Fusion-Task-Id: FN-7978 Fusion-Task-Lineage: 44f3d555-49fb-41e2-87d0-0a722462f132 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
05151a25db |
feat: faster dashboard and serve startup (#2132)
## Summary Speeds up **time-to-HTTP-ready** for `fn dashboard` and `fn serve` after the PostgreSQL cutover without reintroducing the historical 3s cwd-engine race that degraded webhooks. - **Dashboard store share (serve parity):** inject the factory-booted `TaskStore` as `externalTaskStore` so cwd `ensureEngine` does not open a second pool; share only when store root matches project working directory (multi-project safe). - **Serve multi-project:** stop awaiting `startAll()` before listen; await only the primary engine; background the rest + reconciliation. - **Defer non-route-critical engine work:** ordered OAuth (refresh → monitor), automation schedule syncs, and auto-merge **enqueue** after the engine handle is returnable. - **Critical-path merge status clear:** still clear stale `merging`/`merging-pr` before ready so manual merge is not blocked after crash. - **Serve `--paused`:** apply `enginePaused` before `ensureEngine`/`startAll` (dashboard ordering). - **Stop safety:** generation counter so deferred tails cannot resume after `stop()` clears `shuttingDown`. - **Phase timing:** shared `phaseTime` helper, factory substep logs, serve time-to-listen. Plan: `docs/plans/2026-07-14-001-feat-faster-startup-plan.md` ## Test plan - [x] `packages/engine` — `project-engine-manager.test.ts` (path-matched external store) - [x] `packages/engine` — `project-engine-deferred-startup.test.ts` (status clear, OAuth order, stop generation) - [x] `packages/cli` — `startup-phase.test.ts` - [x] `packages/cli` — `serve.test.ts` (60 tests, including `--paused`) - [ ] Local: warm `fn dashboard` / `fn serve` and compare `startup phase *` / `time-to-listen` logs - [ ] `pnpm smoke:boot` (real serve `/api/health` on ephemeral port) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Performance** * Improved dashboard and serve startup times, including faster time-to-listen and time-to-ready. * Moved non-essential background initialization off the critical startup path. * Parallelized dashboard service initialization where possible. * **Reliability** * Improved multi-project startup handling and project selection. * Prevented cross-project task-store sharing. * Added safer shutdown behavior for partially completed startup. * **Diagnostics** * Added startup phase timing logs to help identify performance bottlenecks. * **Tests** * Expanded coverage for deferred startup, shutdown, project isolation, and startup timing. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
883f38d68f |
Fix agent AI interview model routing (#2142)
## Summary - resolve the configured planning model when agent onboarding requests omit an explicit override - align the onboarding prompt with supported runtime/model hint fields, allowing AI-created agents to select runtimes such as Hermes - refresh the generated GitHub issue import limits required by the repository sync gate ## Root cause The agent onboarding route loaded project settings but passed only request-body model fields. The AI Interview UI omits those fields, so `createFnAgent` was called with `provider=undefined, model=undefined`; the session returned no usable assistant JSON. The prompt catalog also prohibited `runtimeHint` despite the parser and form already supporting it. ## Verification - targeted agent onboarding tests: 22 passed - `pnpm --filter @fusion/core typecheck` - `pnpm --filter @fusion/dashboard typecheck` - `pnpm lint` - `pnpm build` - `pnpm smoke:boot` - engine merge-gate subset: 294 passed Full `pnpm test` reached the PostgreSQL gate but this host has no `psql` binary, so 23 PostgreSQL suites could not start; this is an environment prerequisite failure, not a test assertion failure. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Agent onboarding interviews now use the configured planning model when no override is provided. * Runtime suggestions and runtime-hint guidance are preserved during onboarding and reflected in generated configurations. * On onboarding start streaming, planning provider/model resolution now comes from settings with stricter override validation, and test mode continues to take priority. * **Documentation** * Updated onboarding prompt guidance to support additional configuration fields and optional runtime draft hints. * Reduced the maximum GitHub issue import/browse limit from 100 to 50. * **Tests** * Added coverage for runtime-hints prompting and planning-model override behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
85f8b1f909 |
feat: shared Postgres multi-node — retire mesh data-plane replication (#2130)
## Summary - Treat **shared PostgreSQL** (`DATABASE_URL`) as the multi-node durable data plane; mesh HTTP is membership + optional auth, not task/settings replication. - **Peer exchange**: under Postgres backend mode, write queue is **topology/auth-only**; non-topology pending rows fail rather than replaying multi-leader task/settings payloads. - **Mesh routes**: task-ID reserve/commit/abort always hit local shared allocator rows (ignore remote `coordinatorNodeId`); mesh sync ignores settings and only exchanges `authMaterial`. - **Docs**: rewrite multi-project runbook, shared cluster protocol, and architecture mesh sections for shared-Postgres + claims/leases. ## Context Follows the SQLite→Postgres cutover. Multiple Fusion nodes can share one external Postgres while keeping **per-node execution** (worktrees, processes, claims via `central.task_claims`). Explicit non-goals remain: scheduler failover and live process migration. Plan: `docs/plans/2026-07-15-001-refactor-mesh-shared-postgres-multinode-plan.md` ## Test plan - [x] `pnpm --filter @fusion/engine exec vitest run src/__tests__/peer-exchange-service.test.ts` - [x] `pnpm --filter @fusion/dashboard exec vitest run src/__tests__/mesh-routes.test.ts` - [x] `pnpm --filter @fusion/core exec vitest run src/__tests__/shared-mesh-state.test.ts` - [ ] CI gate (lint/typecheck/build/gate) - [ ] Manual (optional): two processes, same `DATABASE_URL`, create task on A visible on B; settings change without mesh settings sync; claim exclusivity ## Operator note Multi-node shared board requires **external** `DATABASE_URL` on every node. Default embedded Postgres is still single-host. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved multi-node deployments using shared PostgreSQL as the durable source of execution state. * Task ID reservation/commit/abort now run locally (no remote coordinator forwarding). * Mesh syncing now prioritizes topology visibility and authentication material; settings replication is disabled in shared-Postgres mode. * **Bug Fixes** * Prevented task/settings replication over mesh HTTP in shared-Postgres deployments. * Refined lease ownership, recovery, and reconciliation to converge via shared-database primitives. * **Documentation** * Updated architecture and shared-mesh protocol guidance, including multi-node setup and lease/task-ID allocation behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d956abceee |
FN-7956: bundle three plugins as install-safe JS entrypoints
Ship reports, cli-printing-press, and whatsapp-chat through tsup so global/npm installs no longer load raw .ts under node_modules (ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING). - Route WhatsApp Chat, Reports, and CLI Printing Press through bundlePluginEntry instead of copying src/ - Re-export postgresSchema from the core runtime shim for published plugin bundles - Keep Baileys optional deps external for WhatsApp Chat bundling - Extend bundle-output helpers/tests to assert self-contained plugin bundles - Add patch changeset for @runfusion/fusion packaging fix Files changed: .changeset/fn-7956-bundle-three-plugins.md | 7 ++ .../cli/src/__tests__/bundle-output-helpers.ts | 30 +++++++- packages/cli/src/__tests__/bundle-output.test.ts | 83 ++++++++++++++-------- packages/cli/src/plugin-sdk-core-runtime-shim.ts | 6 ++ packages/cli/tsup.config.ts | 71 +++++++----------- 5 files changed, 123 insertions(+), 74 deletions(-) Fusion-Task-Id: FN-7956 Fusion-Task-Lineage: e32736d9-e637-450c-966b-6b2d6bc69b88 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
ecd497190d |
fix: abort host tools on timeout and tighten store-injection cleanup
Code review follow-up for the dual-boot hang fixes: - Outer tool wrap aborts a linked AbortController on timeout so nested work (npx) stops - fn_skills_install uses SIGTERM then delayed SIGKILL instead of immediate double-kill - clearHostTaskStores only drops external entries (does not wipe unrelated CLI boot state) - Align import/browse schema max with the 50-item hard clamp - Tests for host-store cache injection and timeout-driven signal abort |
||
|
|
64db34da98 |
fix: share engine TaskStore with host extension and harden hang paths
Kill the dual-boot FN-7956 class hang for in-process agent tools: - setHostTaskStore/clearHostTaskStores inject the live dashboard/serve/daemon store - Prefer host-injected store over createTaskStoreForBackend; race-safe with external overwrite - fn_skills_install kills npx on abort/timeout so orphan install processes cannot outlive the turn - Raise budgets for task plan, experiment finalize, and mission backfill - Hard-cap import/browse batch size at 50 (GitHub + GitLab) |
||
|
|
c6050785bf |
fix: remove fn_research_* from the host pi extension
Host-extension research tools dual-booted a second TaskStore and could wedge agent turns via wait_for_completion polling (same hang class as FN-7956). Leave research available only when the engine injects createResearchTools under experimentalFeatures.researchView. Operators still use fn research CLI and the dashboard Research view. Regen fusion skill docs from extension.ts. |
||
|
|
93baf482f9 |
fix: tighten extension tool budgets after hang-fix review
Address review findings on the FN-7956 hang fix: - Per-tool outer timeouts so fn_research_run(wait_for_completion) is not clipped by a flat 60s budget - Longer budgets for skills install, import/browse, and web_fetch - Boot-failure cooldown + orphan-boot log when store boot times out - Log timeout/abort/errors from the extension wrap; clearer host-extension skip reason - Tests for budgets, research wait, and sessionPurpose forwarding |
||
|
|
508453ad03 |
fix: stop merger/extension tools from wedging on hung fn_task_show
AI merge review could park forever when the host fusion extension loaded fn_task_show and booted a second TaskStore without a tool timeout (FN-7956). - Skip host @runfusion/fusion extensions for sessionPurpose "merger" - Forward sessionPurpose into createFnAgent for that policy - Coalesce + 30s-bound extension TaskStore boots; ALS-propagate AbortSignal - Wrap every extension registerTool execute with 60s timeout/abort fail-closed - Unit tests for merger host-extension skip and tool timeout helpers |
||
|
|
3676586460 |
fix(cli): pass engine PluginRunner into hosts, not PluginLoader
Stop publishing the bare PluginLoader as createServer.pluginRunner so Grok CLI routing can resolve getRuntimeById. Dashboard engine mode relies on engine.onMerge; UI-only/bare CLI omit the runner (dual-remediation). Conflict resolver drops non-capable runners instead of casting them. |
||
|
|
30f9cac46a |
fix(cli): forward PluginRunner into UI/CLI merge and PR conflict doors
Thread a real engine PluginRunner (getRuntimeById) into runAiMerge, landWorkspaceTask, and create-PR conflict resolution so grok-cli/no-key sessions resolve the Grok runtime. Bare fn task merge keeps pluginRunner undefined rather than inventing a bootstrap. |
||
|
|
e9f14bf024 |
perf: speed up local pnpm build and cap stacked verifications (#2134)
## Summary - Extend the workspace content-hash skip cache to **all** packages (not just plugins), with `--force` / `--full` flags - Default local CLI packaging to a **fast mode** (bin/extension + migrations only); full desktop/plugin/DTS staging runs on CI or `pnpm build:full` - Enable TypeScript `incremental` builds for warm recompiles - Add `maxConcurrentVerifications` (default **1**) so concurrent tasks cannot stack monorepo typecheck/build and peg CPU Warm `pnpm build` measured ~**126s → ~0.8s** when nothing changed. ## Test plan - [x] `node --test scripts/__tests__/build-workspace.test.mjs` (12 pass) - [x] `pnpm --filter @fusion/engine exec vitest run src/__tests__/verification-concurrency.test.ts` - [x] `pnpm --filter @fusion/core exec vitest run src/__tests__/settings-parity.test.ts` - [x] Local: first `pnpm build` rebuilds as needed; second warm `pnpm build` skips all packages (~0.8s) - [x] Fast CLI packaging logs skip of desktop/plugin staging without `FUSION_CLI_FULL_PACKAGE` - [ ] CI: `pnpm build` still full-packages under `CI=true` (plugin staging / release surfaces) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a Scheduling setting to limit concurrent verification tasks from 1–8, with a default of 1. * Verification tasks now support cancellation while waiting or running. * Added options for forced and full workspace builds. * **Performance** * Local builds can skip unchanged packages and use incremental compilation for faster rebuilds. * Local CLI packaging is faster by default, while full packaging remains available when needed. * **Documentation** * Updated the settings reference with the new verification concurrency option. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a242f1b449 |
fix(FN-7952): migrate bundled plugins to PostgreSQL (#2111)
## Summary Bundled plugins now persist shared runtime state in project-scoped PostgreSQL tables instead of maintaining independent SQLite authority. Reports, CLI Printing Press, Compound Engineering, Roadmap, Even Realities, and WhatsApp all follow the same ownership and startup contract as Fusion core. ## Design decisions - Plugin schema hooks run through the host’s PostgreSQL owner and enforce project isolation. - The SDK exposes the host contract needed by bundled plugins without importing engine internals. - Legacy Roadmap ownership fixtures use the supported empty-owner sentinel, preserving current composite primary/foreign keys while exercising backfill behavior. - The lockfile travels with the Even Realities PostgreSQL dependency so packaged installs remain reproducible. ## Validation - All six affected plugin builds pass. - Affected plugin suites pass: 773 tests across Printing Press, Compound Engineering, Even Realities, Reports, Roadmap, and WhatsApp. - `pnpm test:gate` passes all 478 gate tests. - This PR changes 40 files. ## Stack - Depends on #2110 → #2109 → #2108. - The documentation/release PR completes the stack. Related: #2105 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Breaking Changes** * PostgreSQL is now required for runtime storage; SQLite files are used only as one-time migration inputs. * The legacy `FUSION_NO_EMBEDDED_PG` fallback has been removed. * **New Features** * Added project-isolated PostgreSQL storage for plugins, reports, tasks, notifications, and other plugin data. * Added agent tools for reports and CLI service drafts. * Added PostgreSQL schema initialization support for plugin authors. * **Bug Fixes** * Improved migration and recovery of legacy plugin state. * Prevented cross-project data access and strengthened transactional schema updates. * **Documentation** * Updated storage, migration, deployment, plugin authoring, CLI, and dashboard guidance for PostgreSQL. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
97172fdcf2 |
fix(FN-7952): require PostgreSQL in CLI and desktop (#2110)
## Summary CLI commands, daemon/dashboard startup, packaged desktop startup, and live-data maintenance scripts now share the mandatory PostgreSQL lifecycle. Operators no longer risk a command silently reading or writing a disconnected SQLite shadow when PostgreSQL setup fails. ## Design decisions - Every startup owner retains and awaits its PostgreSQL shutdown callback, including partial-startup failure paths. - CLI project context and lock-retry flows resolve through asynchronous project stores. - Maintenance scripts use the shared backend helper; explicit database migration/inspection remains the only CLI surface allowed to read legacy SQLite sources. ## Validation - CLI and Desktop typechecks pass on the stacked branch. - `pnpm test:gate` passes all 478 gate tests. - This PR changes 54 files. ## Stack - Depends on #2109, which depends on #2108. - Bundled plugins and docs/release follow in later PRs. Related: #2105 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * PostgreSQL is now the authoritative store for structured project and task metadata. * Projects can be recognized and initialized using `.fusion/project.json`, without creating a legacy SQLite database. * CLI commands now retry transient PostgreSQL contention errors. * **Bug Fixes** * Improved cleanup when commands complete, fail, or run in the background, preventing lingering resources. * Improved desktop, server, and session shutdown reliability. * **Documentation** * Updated storage and standalone binary guidance to reflect PostgreSQL and legacy SQLite compatibility. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2e4fcfcaea |
fix(FN-7952): establish PostgreSQL core authority (#2108)
## Summary Fusion’s core runtime now treats PostgreSQL as the authoritative metadata store without leaving current CLI, dashboard, desktop, or engine composition roots uncompilable between stack layers. This is the 99-file foundation for the larger cutover: subsequent PRs migrate the remaining consumers, plugins, and operator surfaces. ## Design decisions - Runtime store construction fails closed when an asynchronous PostgreSQL layer is unavailable; SQLite remains readable only at explicit migration and identity-recovery boundaries. - Project ownership is enforced across active, archived, workflow, mission, analytics, and plugin-schema data. - The small set of cross-package files in this layer are compatibility-critical call sites required for a green intermediate commit, not the complete consumer migration. - Schema migration 0008 remains assigned to session-advisor state from current `main`; mission lineage idempotency advances to 0009 so neither invariant can be skipped. ## Validation - All affected package typechecks pass: Core, Engine, Dashboard, CLI, and Desktop. - `pnpm test:gate` passes: 478 tests across the engine gate, PostgreSQL core gate, and CLI workflow shape. - The PR changes exactly 99 files. ## Stack This is the base PR. Engine/dashboard, CLI/desktop/ops, plugins, and docs/release follow as stacked PRs, each below 100 changed files. Related: #2105 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * PostgreSQL is now the standard runtime backend, with embedded PostgreSQL enabled by default. * Added project-scoped storage for tasks, archives, chat sessions, missions, knowledge pages, and operational data. * Improved archived-task search, filtering, pagination, and restoration. * Added safer plugin schema initialization with validation and project isolation. * Added PostgreSQL-backed workflow, mission, validator, and dashboard capabilities. * **Bug Fixes** * Improved startup timeout cancellation and resource cleanup. * Prevented cross-project data access and phantom reservation cleanup errors. * Ensured archived tasks remain read-only and asynchronous writes complete reliably. * Retired SQLite opt-out settings with clear startup errors. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
be55d0a987 |
fix(cli): reuse project stores for skill discovery (#2102)
## Summary - reuse the dashboard command's backend-aware per-project `TaskStore` cache during project-scoped plugin skill discovery - obtain plugin state through `TaskStore.getPluginStore()` instead of constructing bare SQLite-default `PluginStore` / `TaskStore` instances - keep cached project stores alive for the dashboard process while still stopping request-scoped plugin loaders - add a regression covering the real Skills adapter callback and refresh the dashboard test fixture with `getAsyncLayer()` ## Root cause `GET /api/skills/discovered` resolved the project correctly, then `getProjectScopedPluginSkills()` constructed new stores without an `AsyncDataLayer`. After `VAL-REMOVAL-005`, that enters the physically removed synchronous SQLite runtime and returns HTTP 500 even when PostgreSQL health, projects, tasks, and both project engines are healthy. The existing route tests mocked the Skills adapter callback, so they did not exercise this CLI wiring. ## Verification - targeted dashboard regression: 1 passed, 91 skipped - `pnpm lint` - `pnpm --filter @runfusion/fusion typecheck` - `pnpm --filter @runfusion/fusion build` - `pnpm check:changesets --strict` - `git diff --check` Live Atlas validation against the migrated embedded PostgreSQL runtime: - `/api/skills/discovered?projectId=proj_84f4645c2da64288`: HTTP 200, 36 skills - `/api/skills/discovered?projectId=proj_7538a9dd46c24c5f`: HTTP 200, 36 skills - local dashboard and Tailscale dashboard: HTTP 200 - controlled SIGTERM: launchd restarted the dashboard and both Skills routes remained healthy <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Fixed dashboard project-scoped plugin-skill discovery in PostgreSQL mode with safer store reuse/teardown and request-scoped plugin-loader lifecycle. - Improved dashboard cleanup to avoid duplicate concurrent store closes and ensured proper shutdown behavior per root type. - Made `fusion_runtime` role creation race-safe during concurrent PostgreSQL migrations. - **New Features** - Added `persistRuntimeState` option to control whether plugin runtime state changes are persisted. - **Tests** - Expanded dashboard and core hot-reload tests to verify scoped, non-persistent runtime behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9bdbdc5f16 |
FN-7955: stage bundled plugin skills
Ensure bundled Compound Engineering skills are present in published CLI packages. - Copy plugin src/skills directories into dist/plugins/<id>/skills during CLI packaging. - Add bundle-output coverage that verifies Compound Engineering SKILL.md files stage and resolve from the plugin root. - Document runtime-read bundled plugin asset staging and add a patch changeset for @runfusion/fusion. Files changed: .changeset/fn-7955-ce-skills-published.md | 7 ++++ docs/PLUGIN_AUTHORING.md | 3 ++ packages/cli/src/__tests__/bundle-output.test.ts | 51 ++++++++++++++++++++++++ packages/cli/tsup.config.ts | 14 +++++++ 4 files changed, 75 insertions(+) Fusion-Task-Id: FN-7955 Fusion-Task-Lineage: 32c4ad31-4f3a-478b-996f-ce6bcafd1e27 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
6aff4958ad |
fix(FN-7952): finish async workflow selection cutover
Use PostgreSQL workflow selections in the dashboard TUI, authoritative driver, and graph-runner adapter so migrated tasks cannot silently fall back to the coding workflow. |
||
|
|
2d61976df0 |
fix(FN-7952): restore runtime state after PostgreSQL migration
Route workflow selections, model lanes, goals, skills, and reliability reads through project-scoped async stores. Recover heartbeat agents parked against an unrelated project model and preserve workflow JSONB patches atomically. |
||
|
|
678265a526 |
fix(cli): show live SQLite migration progress
Report source scans, per-table copy milestones, checksum phases, verification outcomes, and unambiguous failure or finalization status during first-boot and manual migrations. |
||
|
|
b563b12662 |
feat: add Oh My Pi (omp) ACP runtime plugin (#2083)
## Summary - Add `fusion-plugin-omp-runtime` so Fusion agents can run through operator-installed **Oh My Pi (`omp`)** over the [Agent Client Protocol](https://omp.sh/docs/acp) (`omp acp`). - Wire staged/bundled install, Settings → Authentication card (enable + binary path), model discovery (`omp models` → `omp-cli/*`), and MCP eligibility for runtime id `omp`. - Forward Fusion `systemPrompt` via ACP `session/new` `_meta.systemPromptOverride`. ## How operators use it 1. Install/auth `omp` (credentials under `~/.omp`). 2. Enable **Oh My Pi — via omp ACP** in Settings → Authentication (optional binary path). 3. Set agent **Runtime Source → OMP Runtime** (`runtimeHint: "omp"`), or pick an `omp-cli/*` model when enabled. ## Known v1 gaps - No Grok-style Fusion `fn_*` loopback tool bridge yet (operator MCP is forwarded; in-process custom tools are not). - Model is fixed at spawn (`omp --model … acp`); no mid-session Fusion model switch. ## Test plan - [x] `pnpm --filter @fusion-plugin-examples/omp-runtime test` (unit + live ACP when `omp` is on PATH) - [x] Auth routes: `POST /api/auth/omp-cli`, `GET /api/providers/omp-cli/status` - [x] Engine `runtimeSupportsMcp("omp")` - [ ] Manual: enable card in dashboard, select OMP runtime on an agent, run a short chat turn <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Oh My Pi (OMP) CLI support as an ACP-backed runtime and model provider, including model discovery and probing. * Added dashboard auth/status controls to enable OMP, check readiness, and configure the local binary path (with validation). * Exposed OMP custom `fn_*` tools via an MCP loopback bridge, plus optional filesystem capabilities and stricter tool permission gating. * **Documentation** * Added/expanded OMP runtime contract and integration docs (including the ACP session/handshake flow). * **Tests** * Added Vitest coverage for settings wiring, provider status, model discovery, runtime sessions, permissions, MCP bridging, and live connectivity. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d8f0b1a268 |
Restore PostgreSQL integration parity (#2089)
## Summary - add asynchronous PostgreSQL parity to research commands and engine execution paths - persist Roadmap, Compound Engineering sessions, and WhatsApp state in PostgreSQL - harden cancellation, concurrency, reconnect, replay-claim, and detached-promise behavior - bundle the PostgreSQL-backed integration implementations in the published CLI This is PR 2 of 2 and is intentionally stacked on #2088. It contains 44 changed files; merge #2088 first, then retarget this PR to `main` if GitHub does not do so automatically. ## Verification - `pnpm check:changesets --strict` - `pnpm lint` - `pnpm test:gate`: 463 tests passed - Compound Engineering plugin: 299 tests passed - Roadmap plugin: 144 tests passed - WhatsApp plugin: 27 tests passed - research CLI: 18 tests passed - `pnpm verify:fast`: all scoped typechecks, builds, CLI build, and boot smoke passed ## Post-Deploy Monitoring & Validation - deploy only after #2088 and verify schema migration `0002` is present - monitor research cancellation, automation claims, agent execution, plugin schema initialization, and unhandled rejections - validate Roadmap ownership, Compound Engineering session recovery, and WhatsApp reconnect/replay deduplication - compare per-project plugin and workflow counts after cutover - restore the pre-deploy backup for data rollback; avoid an in-place schema downgrade |
||
|
|
8e4514e585 |
fix: key workflow settings by the central project id and stamp all partitioned tables on both migration paths
Closes the remaining PG-cutover partitioning gaps: - getWorkflowSettingsProjectId resolves the bound AsyncDataLayer's central- registry id first. In backend mode the SQLite stub's getProjectIdentity() throws, so the old fallback ALWAYS keyed workflow_settings / workflow_prompt_overrides by the rootDir path string — a namespace nothing else reads, making workflow settings appear reset after cutover. - Stamping is extracted into core stampMigratedProjectRows (tasks/archived NULL->id, config ''->id, workflow_settings + workflow_prompt_overrides rootDir-key->id, all guarded against clobbering per-project rows), shared by startup-factory Step 5.5 and 'fn db migrate', which now resolves the registered project by path after the copy and warns when unregistered. - The task-id allocator and merge_queue are verified safe WITHOUT project partitioning: task ids are a global PK, the per-prefix sequence scans are intentionally global (only the per-project config floor can raise them), so two projects sharing a prefix cannot mint duplicate ids. FNXC comments lock the invariant; a cross-project PG regression test proves it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
c15c78feeb |
feat: migrate storage from SQLite to PostgreSQL (#1793)
# Migrate storage from SQLite to PostgreSQL — full dashboard cutover Migrates Fusion's storage layer to the embedded PostgreSQL `AsyncDataLayer` (the default backend) and **completes the satellite-store + feature cutover** so every dashboard and Command Center surface works in PG mode. ## Status — every surface works in embedded-PG mode Verified live against a running embedded-Postgres dashboard (all **200**, zero 5xx) and gate-tested (**23 files / 99 tests** on embedded PG, plus engine-core 294 and ci-shape 63 in the blocking merge gate; core/engine/cli/dashboard typecheck clean). | Area | Surfaces | State | |---|---|---| | Satellite stores | workflows, todos, insights, research, missions, goals, mailbox | ✅ | | Views | artifacts, documents, evals | ✅ | | Command Center | activity, productivity, team, tokens, tools, **workflows**, **github**, **signals**, **plugin-activations**, **live** (all 10) | ✅ | | Run execution | insight generation, research run execution | ✅ (store-path; AI step needs a provider) | | Live updates | SSE push for mission/research/insight events | ✅ | | Workflow editing | create / update / delete / select (+ id counter) | ✅ | | Engine | mission autopilot, incident-signal ingestion, regression storm-guard, agent wake-on-message | ✅ | | Core | tasks, agents, secrets, automations, memory, chat, usage, PRs, git | ✅ | ## Approach Each satellite store gets an `Async<Store>` wrapper exposing the sync store's method names over the existing `async-*-store.ts` helpers; `get<Store>Store()` returns a `Sync | Async` union; consumers `await` (harmless on sync), and engine/CLI paths that can't convert use `instanceof Sync` graceful fallback. Analytics aggregators branch on `"ping" in dbOrLayer` to run schema-qualified raw SQL over `project.*` (snake_case) in PG. Executors/orchestrators/autopilot are await-converted to drive the union store; the async store wrappers extend `EventEmitter` so SSE live-push fires in both backends. Not-yet-ported capabilities degrade gracefully (never 500) and are individually called out in commits. ## Sync with main The branch is kept continuously merged with `main` (currently through FN-7845, 2026-07-12); the earlier "final rebase deferred" note no longer applies. Use **Create a merge commit** (or squash) to land it — GitHub's rebase-merge cannot replay a merge-maintained branch. ## Residual Review Findings Multi-agent code review of the PostgreSQL satellite-store ports (U1–U5) applied 3 safe fixes (see `fix(review): apply autofix feedback`). The following are **real but gated** — recorded here as follow-up work rather than auto-applied. All are SQLite→PostgreSQL **concurrency/atomicity regressions**: the sync stores were immune only by SQLite's single-writer, single-threaded-handler execution; the async ports open multi-await read-modify-write windows. **Reachability is low today** because the execution engines that generate concurrent same-run mutations (insight run executor, research orchestrator/dispatcher) are `instanceof`-gated to sync mode in PG. No process-crash class survived (all engine fallbacks correctly guard the sync store). - **[P1] Research `appendResearchEvent` dual-write is non-atomic** (`packages/core/src/async-research-store.ts`, corroborated: adversarial + reliability). The `research_run_events` insert (own transaction) and the `run.events` jsonb update are separate writes — a crash between them, or two concurrent appends, splits the table count from the jsonb array. **Fix:** perform the seq-insert and the jsonb update in one `layer.transactionImmediate`. - **[P1] Research run terminal-reversion via stale full-row persist** (`async-research-store.ts` `persistResearchRun`/`updateResearchStatus`). Concurrent `PATCH /runs/:id/status` + `POST /runs/:id/events` can revert a terminal run to `running` by overwriting the whole row, bypassing the transition guard. **Fix:** scoped column `UPDATE`s with a `WHERE status …` guard, or optimistic version column. - **[P2] `updateResearchRun`/`updateInsightRun` read-then-write TOCTOU** — concurrent PATCHes last-writer-wins on the lifecycle merge. **Fix:** `SELECT … FOR UPDATE` / enclosing transaction. - **[P2] `upsertRun`/`createRunOrThrowConflict` check-then-create race** (`async-insight-store.ts`) — two callers can each create an "active" run. **Fix:** partial unique index on `(projectId, trigger) WHERE status IN ('pending','running')`. - **[P3] `createResearchRetryRun` return-value divergence** — sync returns the pre-update `queued` snapshot; async returns the reloaded `retry_waiting` run (persisted state is identical). Pick one side for cross-backend parity. - **[P2/perf] Mission `getMissionWithHierarchy`/`getMissionHealth` N+1 fan-out** — O(milestones×slices) sequential round-trips hold one pool slot per request; can starve the pool for large hierarchies. **Fix:** batched/joined reads. - **Testing gaps:** no PG-mode concurrency tests (interleaved status/event mutations), no sync↔async parity assertion for the lifecycle-error codes, and no mission status/health rollup parity test vs the sync `MissionStore`. ~~Out of scope (deferred): AI run *execution* (insight/research) + mission autopilot + live SSE mission events remain sync-gated/degraded in PG mode.~~ **Since ported** — insight/research run execution, mission autopilot, and SSE live push all run on the async layer now, which also makes the concurrency findings above genuinely reachable; they remain open follow-ups. --- ## Update — 2026-07-12: production-readiness hardening & live acceptance Everything below landed on this branch since the description above was written: **Production blockers from review — fixed** - `recoverStaleTransitionPending` ported to the async layer (backend moves write + clear the crash-safe marker; startup/maintenance sweeps no longer throw). - Lost-update class fixed: `atomicWriteTaskJson`/`WithAudit` write changed columns only (full-row upserts silently resurrected stale fields across concurrent store instances — the "task stuck unplanned forever" bug). - First-boot **auto-migration**: booting the PG backend over a project with a legacy `fusion.db` migrates it automatically (loud failure, SQLite kept as backup), and the dashboard shows a one-time **"your data was migrated" banner** with the backup paths and a Need-help Discord link. - `pg_dump`/`pg_restore` discovered from common install locations for embedded-mode backups. - The PG suite is part of the blocking merge gate (`test:pg-gate`). **Multi-project isolation (PR #2007, merged into this branch)** - `project_id` partition key on tasks / archived tasks / config, `taskProjectScope` threaded through every scan/claim/count, per-project config rows, layer bound to the project at startup. - Review P1 follow-up: the shared cold-storage `archive.archived_tasks` table is also partitioned and all archived-board reads/counts/searches are scoped. - Schema drift self-heal generalized to schema-qualified columns so existing databases upgrade in place. **Other changes** - Node settings sync **removed** in PG mode (409 `settings-sync-disabled-postgres`) — nodes share state by connecting to the same database; auth sync kept (per-machine file). - Perf (review findings): `listTasks` pushes column filter + ORDER BY + LIMIT/OFFSET into SQL; `getConversation` capped to the most recent 200 messages. - Fixed a false "operator action required" pause-abort log fired on every successfully auto-merged task. **Live acceptance — PASSED (2026-07-12)** A sandboxed instance (isolated HOME, embedded PG, real Opus executor) ran a task through the complete cycle: create → triage (AI spec) → execute → in-review → AI squash-merge landed on the project's `main` → done. A write+read sweep of every data surface (settings, comments, documents, attachments + artifact bridge + artifact edit, chat with real generation, goals, missions, agent mail, secrets, workflows, memory, CC analytics) was green on embedded PG. **Known remaining work** - The per-project `config` PK re-key has no upgrade path for pre-isolation embedded-PG databases (needs a real `DROP CONSTRAINT`/re-key migration; fresh databases are fine). - `pg_dump`/`pg_restore` binaries are not yet bundled in release artifacts (PATH/common-location discovery only). - The satellite-store concurrency findings listed above. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Phil Larson <hello@phillarson.xyz> Co-authored-by: fusion-merge <fusion-merge@local> |
||
|
|
1ff83a2735 |
chore(release): v0.60.0
Version bump via changesets. |
||
|
|
c3c3861efa |
fix: stale TRANSITIVE_EXTERNALS + dashboard dist/client clean + cross-worker build lock (round 12) (#2065)
## Summary
Fixes shard 3 failures from runs 29258546612 + 29259574946 (FN-7936
drift).
## Fixes
### `package-config.test.ts` — stale TRANSITIVE_EXTERNALS entry
FN-7936 aliased `@fusion/core` to a runtime shim in bundled plugin
outputs; it's no longer a tsup external. Removed the stale allowlist
entry.
### `bundle-output.test.ts` — stale dashboard client hash ENOENT
**Root cause:** Two test files (`bundle-output.test.ts` +
`extension-integration.test.ts`) call
`buildCliWithRealDashboardAssets()` which triggers concurrent vite/tsup
builds. Vitest runs them in parallel (`pool: "forks"`, `fileParallelism:
true`). Without coordination, two builds clean and write `dist/client`
simultaneously, causing `ENOENT` on content-hashed chunk files.
**Fix (3 parts):**
1. **`workspace-tools.ts buildDashboardClient`** — `rm dist/client`
before vite build. Prevents stale content-hash references from previous
builds.
2. **`bundle-output-helpers.ts`** — atomic `mkdirSync` file lock around
`buildCliWithRealDashboardAssets()`. Winner builds; losers poll with
`Atomics.wait`, then re-check `hasBuiltDashboardAssets()`. On timeout,
**throws** (never builds without owning the lock).
3. Lock uses `Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0,
0, 500)` for sync sleep — no child process spawning.
## Verification
- Gate: exit 0 ✅
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved dashboard asset builds by removing stale files before
rebuilding.
* Prevented concurrent builds from producing incomplete or corrupted
dashboard assets.
* Added safeguards to detect stalled asset builds and fail with clearer
errors.
* **Tests**
* Updated package validation checks to reflect current runtime bundling
behavior.
* Improved reliability of CLI build-related test execution.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
281bb05161 |
FN-7936: alias @fusion/core to a runtime shim in bundled plugin outputs
Fix bundled example plugins (dependency-graph, grok-runtime, roadmap, acp-runtime, compound-engineering) crashing on enable with "Cannot find package '@fusion/core'" by aliasing the private import to a self-contained runtime shim during CLI bundling. - packages/cli/tsup.config.ts: drop @fusion/core from bundlePluginEntry's external list and alias it to the existing pluginSdkCoreRuntimeShim so bundled.js no longer references the private workspace package at runtime - packages/cli/src/__tests__/bundle-output.test.ts: add a regression test asserting every staged bundled plugin's bundled.js contains no bare @fusion/core import/reference - docs/PLUGIN_AUTHORING.md: document that bundled.js outputs must be self-contained and must not leak private @fusion/* workspace imports - .changeset/fn-7936-bundled-plugin-fusion-core-external.md: add a patch changeset for @runfusion/fusion describing the fix Files changed: .changeset/fn-7936-bundled-plugin-fusion-core-external.md | 7 +++++ docs/PLUGIN_AUTHORING.md | 3 +++ packages/cli/src/__tests__/bundle-output.test.ts | 30 ++++++++++++++++++++++ packages/cli/tsup.config.ts | 9 +++++-- 4 files changed, 47 insertions(+), 2 deletions(-) Fusion-Task-Id: FN-7936 Fusion-Task-Lineage: a8a391b2-9441-4a7c-92bc-f1675e1a8a0d Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
502c4c132f |
chore(release): v0.59.0
Version bump via changesets. |
||
|
|
f7e942e6f4 |
fix: resolve all full-suite failures + add structural mock-completeness gate check (round 10) (#2040)
## Summary
Fixes ALL failing shards from the latest full-suite run (29225946428)
AND adds a structural gate check to prevent the recurring mock-export
drift pattern that has caused every full-suite failure across rounds
1–9.
## What broke (run 29225946428, commit
|
||
|
|
c8999369c3 |
feat: add gate check for CLI dashboard mock completeness — prevents recurring full-suite barrel-export drift (#2035)
## Summary
**Structural fix** for the recurring full-suite failure pattern where a
new `@fusion/dashboard` barrel export is imported by CLI source code but
missing from the hardcoded `vi.mock("@fusion/dashboard")` factory in CLI
tests.
## What's new
### Gate check script:
`scripts/check-cli-dashboard-mock-completeness.mjs`
Added to the merge gate (`pnpm test:gate`). Statically validates that
every hardcoded `vi.mock("@fusion/dashboard")` factory in CLI tests
includes all `@fusion/dashboard` exports that the corresponding source
files import.
- Pure static analysis (regex + depth-aware brace tracking) — no module
evaluation, <0.1s
- Handles named imports (`import { foo } from "@fusion/dashboard"`) AND
namespace imports (`import * as dashboard from "@fusion/dashboard"` →
scans `dashboard.X` usages)
- Filters against the real barrel exports to avoid false positives from
typos
- Resolves test→source mapping by parsing static/dynamic imports in the
test file (not just naming convention)
**Result:** the next time someone adds `export { newFunc } from
"./mod.js"` to `dashboard/src/index.ts` and `cli/src/commands/daemon.ts`
imports it, the gate catches the missing mock before merge instead of
the full-suite failing on main.
### Completed all 9 incomplete CLI dashboard mocks
Added the missing exports identified by the check:
| File | Missing exports added |
|---|---|
| `daemon.test.ts` | `registerGithubTrackingHook` |
| `serve.test.ts` | `registerGithubTrackingHook` |
| `dashboard.test.ts` | `AttachTicketStore`, `CliInputAttributionLog`,
`CliConfirmAdvanceRegistry`, `CliRelaunchRegistry`,
`registerGithubTrackingHook` |
| `task.test.ts` | `registerGithubTrackingHook`, `GitLabClient`,
`resolveGitlabAuth`, `buildGitLabTaskProvenance`,
`isGitLabAlreadyImported`, `buildGitLabTaskDescription` |
| `extension-*.test.ts` (×4) | `GitLabClient`, `resolveGitlabAuth`,
`buildGitLabTaskProvenance`, `isGitLabAlreadyImported`,
`buildGitLabTaskDescription` |
| `task-command-github-import-tracking.test.ts` | Same GitLab exports |
These were latent issues — the mocks were incomplete but tests passed
because the missing exports weren't called during test execution. Any
test change that exercises those code paths would have broken.
## Why not `importActual` spread?
Tried converting daemon.test.ts to `vi.mock("@fusion/dashboard", async
(importOriginal) => { ... })` — fails because the barrel's `export *
from "./plugins/index.js"` transitively imports
`@agentclientprotocol/sdk` which isn't available at test evaluation
time. The static check approach avoids this entirely.
## Verification
- `pnpm test:gate`: exit 0 (includes new check)
- `pnpm lint`: exit 0
- CLI tests: daemon 21/21, serve 58/58, dashboard 91/91, task 149/149 ✅
- Gate script: `✅ CLI dashboard mock completeness: all hardcoded mocks
cover source imports.`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Tests**
- Added automated validation to ensure CLI test mocks remain aligned
with available dashboard functionality.
- Updated test coverage setup so GitHub, GitLab, daemon, dashboard,
server, and task scenarios use complete dashboard mocks.
- Test verification now reports missing mocked functionality and blocks
the release gate when inconsistencies are detected.
- **Chores**
- Improved reliability and maintainability of automated verification for
CLI and dashboard integrations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
4ea5dd6739 |
fix: CLI shouldSuperviseDashboard mock + getCliPackageVersion/isUnresolvedCliPackageVersion + executeRequeueLoopCount + i18n buttonShort (round 9) (#2034)
## Summary Fixes shard 3 (CLI) + shard 4 (i18n) failures from full-suite run 29223788088. ## Fixes ### CLI (shard 3) — 5 files, ~140 tests - **`bin.test.ts`** — `bin.ts:851` now imports `shouldSuperviseDashboard` and `bin.ts:865` imports `runDashboardSupervised` from `./commands/dashboard.js`. Test mock only exported `runDashboard`. Missing `shouldSuperviseDashboard` → TypeError → caught → `process.exit:1`. Added `shouldSuperviseDashboard: vi.fn(() => false)` + `runDashboardSupervised` to mock + `commandMocks`. - **`daemon/serve/dashboard.test.ts`** — `@fusion/dashboard` barrel (index.ts:115) re-exports `getCliPackageVersion`, `isUnresolvedCliPackageVersion`, `resolveCliPackageVersionInfo`. Added all 3 to each file's `@fusion/dashboard` mock. - **`task.test.ts`** — `executeRequeueLoopCount: 0` added to TaskResetField set by recent commit; retry test assertions needed the new field in both `mockUpdateTask` expectations. ### i18n (shard 4) — 4 locale files - **`settings.reset.buttonShort`** missing from zh-TW, fr, es, ko (zh-CN already had it). ### Engine (shards 1+2) — already fixed in PR #2025 (merged on main) - Run 29223788088 was at commit `b85a6b866` (pre-PR-2025-merge), so engine + i18n `storageMigrationNotice` failures visible in that run are already resolved on main. ## Verification - daemon: 21/21 ✅ | serve: 58/58 ✅ | dashboard: 91/91 ✅ | task retry: 5/5 ✅ - i18n parity + gate-coverage: 7/7 ✅ - Gate (`pnpm test:gate`): exit 0 ✅ - `bin.test.ts`: cannot verify locally (`@agentclientprotocol/sdk` not installed locally; CI resolves from lockfile). Mock exports verified against `dashboard.ts` source. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved task retry recovery by correctly resetting execution counters. * **Localization** * Added support for shorter reset-button labels in Spanish, French, Korean, and Traditional Chinese. * **Tests** * Updated command and startup checks to reflect current dashboard and version-handling behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |