8d84cee11ec00ca796d2b98dcd45a65f308f3cc9
160 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3aa942ee5f |
capacity: spawned agents count against the project agent count (#2579)
Two configurable numbers per project. `maxSpawnedAgentsPerParent` (5) and `maxSpawnedAgentsGlobal` (20) were a **third and fourth** limiter with private budgets invisible to both. ## This closes a hole, not just knobs A spawned child **is** an agent and gets **its own git worktree** (branched from the parent’s — the tool’s own description says so), but children were counted by **neither** capacity gate. A fan-out could put up to 20 extra worktrees on disk while the scheduler believed the project was at its configured limit. The operator’s two numbers were simply wrong about what was running. ## The old caps also measured the wrong thing `totalSpawnedCount` decrements on child cleanup, but the per-parent **set** is cleared only when the **parent task** ends. So `maxSpawnedAgentsPerParent` throttled *cumulative* spawns across a task’s life rather than *concurrent* ones — a long-running task could exhaust its budget with five children that had all long since finished, and the operator had no way to see why. ## Fix `fn_spawn_agent` gates on the same project agent count every other lane uses (`computeTopLevelConcurrencyClaimedFromStore`) plus live children. One number, one answer, no private budget that can disagree with the board. The refusal names **Max Concurrent Tasks** — a control the operator actually has. The old messages pointed at settings that no longer exist, which is worse than no message: it sends someone hunting for a knob that is not there. ## Verification **Revert-proof, measured:** restoring the private budgets turns **3 of the 4** new cases red — a project at 1/1 could still spawn, which is precisely the hole. `executor.ts` restored byte-identical. `pnpm lint` clean · core + engine `tsc` clean · `pnpm test:gate` green (414 + 10 + 71) · new suite 4/4 · `settings-default-descriptions` 4/4. There was no spawn-capacity test before this; the file is new. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Spawned agents now count toward the project’s **Max Concurrent Tasks** capacity. * Agent spawning is blocked when capacity is reached, including concurrent spawn attempts. * **Bug Fixes** * Prevented over-allocation during simultaneous agent spawns. * Restored available capacity when agent creation fails. * **Changes** * Removed separate per-parent and global spawned-agent limits. * Updated settings to reflect the revised capacity controls. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
18d654a5ff |
capacity, part 3: delete the globalMaxConcurrent setting, API and UI (#2529)
Part 3 of the capacity simplification, and the half that removes the **knob**. Enforcement (shared semaphore, runtime wiring) went in #2509; this removes everything an operator or API client can still see, so nothing is left readable-but-ignored. ## Deleted Settings key + schema default · CentralCore’s `getGlobalConcurrencyState` / `updateGlobalConcurrency` / `acquireGlobalSlot` / `releaseGlobalSlot` and the `concurrency:changed` event · the whole Global Concurrency block in `async-central-core` · `PUT /api/global-concurrency` · the Scheduling · Global settings section · the footer and Command Center global sliders · the dead `getGlobalConcurrencyLimit` reader whose only caller went in #2509. ## Kept, deliberately **`GET /api/global-concurrency` survives as telemetry only** — live `currentlyActive` / `projectsActive` from CentralCore’s side-effect-safe source. “How busy is this machine?” is still a real question once the cap that used to answer it is gone. It no longer reports `globalMaxConcurrent`/`queuedCount`: those came from the deleted cap and from slot bookkeeping production code never incremented, so publishing them was publishing zeros dressed as state. **`useGlobalConcurrency` becomes read-only.** Everything that existed to *persist* went with the cap — the 500 ms debounce, the save-state machine, the commit-on-close/unmount flush, the slider clamp, the `interactive` gate. The module-level shared store is **kept**: its original justification (two mounted consumers drift apart with private copies) holds for a polled read exactly as it did for a cap, and one fetch now serves both. The live “N running (all projects)” readout survives in both surfaces, moved onto the per-project row. ## Two sections become one Scheduling · Global existed to host exactly one control. With it deleted the section renders an empty pane, so the Global/Project pair merges back into **“Scheduling”**. An empty nav entry is a promise of settings that are not there. ## One real fix found on the way `SchedulingSection`’s `concurrencyLoading` gated the **project** concurrency inputs on the **global**-concurrency fetch — never the right source, since `maxConcurrent` and `maxWorktrees` come from the settings form. It is repointed at the form’s own load, preserving the invariant it existed for: a concurrency input stays disabled until its live value arrives, so an operator cannot overwrite a resolved limit with a blank fallback. ## Migration A stored `globalMaxConcurrent` is **ignored** — it is a project-blob key nothing reads, so dropping it needs no schema change. The `central.global_concurrency` **table** is dropped in a follow-up; this slice stops seeding and reading it first, so that drop has no live writer to race. ## Verification, and how the wider suite was controlled `pnpm lint` clean · core/engine/dashboard `tsc` clean · `pnpm test:gate` green (309 + 10 + 71) · dashboard settings/footer/command-center/hooks **2237/2237** · core `central-core-backend` 9/9. The broader dashboard suite shows failures, and I checked rather than assumed: running the suspect files on **clean main** reproduces `api-git` (49), `TaskDetailModal.rendering` (28) and `settings-mobile` (17) identically. Two were genuinely mine — `SettingsModal.scheduling-merge` (0 on main, 17 on this branch: my nav rename) and one `settings-mobile` picker case asserting `scheduling` is a scoped pair — and both are fixed. Tests for deleted behaviour are removed with it (footer confirm/cancel/flush/dedupe, global marker geometry, the hook’s PUT case, the CentralCore slot cases), each carrying a note on what it guarded and where the surviving **project-side** equivalent lives. Fixture-only references were updated, not deleted. Nothing booted. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
743df98aa4 |
capacity, part 1: merge pinned at 1, worktrees-off mode, and one dead knob deleted (#2502)
First slice of the capacity simplification. Operator: *"just have two
capacity — overall per project agent count and max worktrees. Remove all
other capacities and counts."* Plus two later additions: **merge is
always 1, fixed**, and **worktrees off ⇒ limit by total agents only**.
Three independently revertable commits. No limiter is added anywhere;
one is deleted, one is made structurally absent, and one is pinned.
---
## 1. Merge concurrency ratcheted at 1 (test-only)
I was asked to add a limiter if merge concurrency could be raised. **It
cannot** — there is no setting, workflow property, pool or trait config
anywhere that raises it, so this adds no code and pins what already
holds.
Serialization lives in the **pump**: `drainMergeQueue`’s `mergeRunning`
re-entrancy latch, `activeMergeTaskId` as a single-slot identity, the
`mergeBodyInFlight` next-generation latch, and one `ProjectEngine` per
projectId.
**Not** in the merge-queue lease, which is a per-task ROW (`primaryKey
[projectId, taskId]`) — two tasks can hold leases simultaneously by
construction, and it has exactly one caller (the worktree-reuse
handoff). Ordinary merges never take it. A lease-level test would have
been describing an invariant that layer has never held.
The second half guards the other direction: a merge-concurrency
*setting* would not fail the pump ratchet — it would sit unread until
someone wired it up.
**Revert-proof:** deleting the latch → `expected 1 times, but got 2
times`; deleting the `finally` → latch-stuck; injecting
`maxConcurrentMerges: 2` → fails naming the key; injecting a
`maxParallelLanes` merge-trait field → fails naming the field. Sources
restored byte-identical after each injection.
## 2. `worktreesEnabled` — off means the worktree limit cannot bind
No worktrees-off mode existed (no
`worktreesEnabled`/`useWorktrees`/`worktreeMode` anywhere — only
worktree *configuration*).
**Why not `maxWorktrees: 0`, which needs no new key:** it deadlocks. `??
4` keeps `0` (not nullish), the gate is `used >= limit`, so `0 >= 0`
holds **on an empty board** and nothing ever dispatches — while the
operator-visible reason reads `gate=maxWorktrees; used=0/0`, a limiter
that looks like it is working while the board is dead. It also needs the
Command Center `{min:1}` clamp relaxed. So `0` costs the gate rewrite
*and* the clamp change *and* encodes a mode as a magic value.
**Off is absence, not a big number.** `resolveWorktreeCapacityLimit`
returns `number | null`; `ConcurrencyGateDiagnostic.maxWorktreesGate` is
now optional, so consulting a worktree limit in OFF mode does not
type-check. A gate holding `Infinity` can start binding again the moment
someone "fixes" a comparison; an absent gate cannot.
That paid for itself immediately: making it nullable surfaced a
**second, independent** worktree gate (`activeWorktrees >= maxWorktrees`
early-return) that a skip-by-convention approach would have missed
silently.
**Scope, deliberately:** this is a statement about *counting*, not
isolation. It does not make concurrent agents safe to share one checkout
and builds nothing toward that — the non-worktree paths that exist today
are fallbacks to the operator’s own tree, one of which caused FN-8600.
**Revert-proof:** a resolver ignoring the flag turns both OFF scheduler
tests red while every ON test stays green — they reuse the *same*
fixture (5 in-progress, limit 4) that pre-existing tests prove blocks,
so the pair moves in opposite directions. Removing `disabled:` reddens
the UI test.
## 3. `maxTriageConcurrent` deleted — it controlled nothing
**Measured: zero enforcement reads.** The only `.maxTriageConcurrent`
reference in the repo was a route echoing it back in `/config`. FN-8453
removed the pool it gated and left the knob shipping in
`DEFAULT_SETTINGS`, the settings type, the section registry, the API
response and six i18n catalogs, doing nothing, for releases.
Historical FNXC comments are **updated, not deleted** — they explain a
real past incident; they now say "planning admission slot" so they stop
implying a live setting. Tombstoned so it cannot return.
`/config` loses a field; safe in-repo since `fetchConfig`’s own return
type never declared it.
---
## Two corrections worth recording
- I earlier reported `maxWorktrees` had **no** Settings UI. Wrong —
`WorktreesSection.tsx:47`; my grep was truncated by `head`. It changed
the placement (toggle beside it, rather than a duplicate key in
Scheduling).
- I planned to assert the queued-reason string is rewritten in OFF mode.
Measured that it is **unreachable**: when `maxConcurrent` binds, the
sweep bails before the per-task reason and logs nothing. The test
asserts absence instead.
Two near-misses caught before commit: a pre-existing FN-7505 guard
caught my *new* key missing a description mapping; and editing i18n via
`json.load/dump` silently dropped unrelated duplicate keys
(`autoUpdateAndRestart` in `fr`) — Python keeps only the last of a
duplicated key. Redone textually, every catalog re-validated.
## Verification
`pnpm lint` clean · core/engine/dashboard/i18n typecheck clean · `pnpm
test:gate` green (309 + 10 + 71) · capacity/worktree suites 11/11 ·
engine merge-invariant + scheduler 45/45 · dashboard settings 114/114.
Rebased onto current main and re-verified.
Nothing was booted at any point.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a project setting to enable or disable running tasks in
worktrees.
* Disabling worktrees removes worktree capacity limits from task
scheduling.
* The “Max Worktrees” setting is disabled when worktree execution is
turned off.
* **Changes**
* Removed the unused triage concurrency setting from configuration and
dashboard responses.
* Updated scheduling diagnostics and queue messages to reflect disabled
worktree capacity limits.
* Added localized labels and help text for the new setting.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
710d56b2db |
U4 trim: delete the dependency-blocked-todo feature (unreachable in production) and revert 5a2de7d (#2477)
Stacked on #2474. Base is `feature/workflow-vocabulary-u4-dead-code` — do not merge before it. Deletes an **entire feature that has never executed in production**, and reverts `5a2de7d`, which only threaded resolved lifecycle columns through it. ## Reachability evidence — the whole basis for this ``` surfaceDependencyBlockedTodos ← in NEITHER sweep registry; no caller in └─ getDependencyBlockedTodoReporter() engine/dashboard/cli — only tests └─ engine/dependency-blocked-todo-reporter.ts ← sole caller of ↓ └─ core/computeDependencyBlockedTodoReport ``` self-healing owns two name-based sweep registries (`runStartupRecovery`, 58 entries; `runMaintenance`, 76). `surfaceDependencyBlockedTodos` is in **neither**, so nothing ever invoked the chain below it. Its four tests passed while proving nothing about production. ## Why delete rather than wire it up Wiring was the tempting option and is the riskier one. Switching on a 450-line path that has never run — whose tests therefore establish nothing about its behavior against real data — is a **behavior change with unquantified blast radius**. This program already refused exactly that move for the **pool-id sentinel**, a one-line change that would switch on dormant enforcement across every project. This is the same class of move at ~450× the size. Deleting is also the recoverable direction: git keeps the feature, and it can be resurrected deliberately — with tests that prove it *runs* — if dependency-blocked reporting is actually wanted. ## The settings keys go with it `dependencyBlockedTodoReportEnabled` defaulted `true` while driving nothing. A schema/API-visible switch that lies about what the system does is worse than no switch. (It had no dashboard UI field — the dashboard test allowlist already recorded it as *"no UI field"*.) Four sibling tuning keys are removed with it. ## Against my own earlier work `5a2de7d` threaded resolved lifecycle roles into `computeDependencyBlockedTodoReport` and its reporter, answering a review finding I confirmed as real. **The code was correct; the impact claim was not**, because the path never executes. Neither the reviewer nor I checked *reachability* before agreeing the defect mattered — only correctness. A correction is posted on that thread in #2470. **Scope limit on that admission:** the same finding also described *incorrect scheduler ordering*. That half runs through `buildUnblockWeightMap` in `task-priority.ts`, which is **live** and was already threading `terminalColumns` (B1, `434b385`). Scheduler ordering was never affected, before or after. ## What survives `blocker-fanout.ts` **stays** — it is live via `task-priority.ts`. Only the plural `holdColumns` option added by `5a2de7d` is reverted, since the deleted report was its sole consumer. `holdColumn` (singular, from B1) remains. ## Net **1,244 deletions / 5 insertions across 15 files** — ~450 production lines, ~684 test lines, 5 settings keys. ## Verification - `tsc --noEmit` clean in **core, engine, and dashboard-app**; `pnpm lint` clean - merge gate green (299 + 10 + 71) - self-healing suite: 411 passed, 1 **pre-existing** failure (`archiveStaleDoneTasks`) - dashboard settings-descriptions suite green - `settings-parity.test.ts` has one **pre-existing** failure (`agentToolOutputMaxChars` overlap) that fails identically with these changes stashed — unrelated to this deletion No changeset: `@fusion/core` and `@fusion/engine` are private. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added quiet-window backlog health diagnostics for stalled items in review, with repeat-alert suppression. * Added default thresholds for backlog-pressure alerts. * **Changes** * Removed dependency-blocked todo reporting and related alerts. * Removed the dependency-blocked todo enable/disable setting; remaining tuning options are no longer active. * Updated the workflow hold classification to use a single todo column. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0e3d2a2265 |
refactor: delete meta-task auto-archive and automated recovery follow-ups (#2461)
Deletes two pieces of automated "meta" machinery that filed and garbage-collected cards restating state already on the task that failed. Net **-1015 lines**. ## Why **Automated recovery follow-ups.** `createAutomatedFollowup` and its dedup engine (289 lines of signature matching, 1h recurrence rate-limiting, 24h supersedes windows) existed to file recovery cards for verification-cap and merge-conflict give-ups. In both cases the parent is *already* parked `failed` with a descriptive `error` and a log entry carrying the failing command, branch, and output — the card was a second copy of that. **Meta-task auto-archive.** The sweeps that garbage-collected those cards were worse than redundant: the regex classifier matched ordinary feature work, and its positional fallback bound cards to unrelated tasks, so **live work could be archived**. They are removed together, because the auto-archive sweeps only existed to clean up after the follow-up engine. ## What changed ### Deleted - `packages/engine/src/verification-followup-dedup.ts` in full — `createAutomatedFollowup`, `decideAutomatedFollowup`, `AutomatedFollowupKind`, `computeVerificationFailureSignature`, `extractFailingTestFiles`. - `findActiveRecoveryFollowUp` — dead code, defined and never called (`tsc` independently flagged it `6133 declared but its value is never read`). - The meta-task auto-archive sweeps `autoArchiveResolvedMetaTasks` / `autoArchiveStalledMetaTasks` and helpers `classifyMetaTask` / `resolveMetaTargetTaskId` / `computeMetaChainDepth` / `archiveMetaTask` / `evaluateMetaAutoArchiveGuards`, plus settings `metaTaskStallAutoCloseMs` and `metaTaskActiveExecutionGraceMs`. - Run-audit types `task:auto-archived-meta-resolved`, `task:auto-archived-meta-stalled`, `task:auto-archive-meta-resolved-skipped`, `task:auto-archive-meta-stalled-skipped`, `verification:followup-created`, `verification:followup-deduped`. The two signature helpers were **deleted rather than relocated** — once the three call sites went they were provably unreachable: `buildVerificationFailureSignature` had exactly one caller, and it was the only caller of `extractFailingTestFiles`. ### Call sites 1 and 2 — park kept, card dropped Verification-cap and merge-conflict give-ups keep their park, audit event, operator comment, and log entry. Site 1's `error` string was reworded off `"See follow-up task for investigation."` (no follow-up will exist) to carry the guidance itself. `autoResolveDisabled` was **kept** — it still drives the outer park guard and the `reason` string; only the inner branch that guarded card creation is gone. ### Call site 3 — autostash orphan, replaced not deleted This one is a genuine data-loss guard, so it keeps a durable trail. A `live`-classified orphan is a merger stash holding **real uncommitted work**, and unlike sites 1–2 there is no parked parent — the parent may already be `done` and merged, so nothing else on the board would ever mention the stash. The card is replaced by a `logEntry` **and** an `addTaskComment` on the parent, preserving every fact the old description carried: the sha, `record.label` (the handle `git stash` recovery needs), `record.detectedByTaskId`, and `sourcePhase`. New truthful run-audit event `task:autostash-orphan-live-detected` replaces the borrowed `verification:followup-*` name, with ids/outcomes-only metadata per AGENTS.md. ### Kept unchanged: the two real product features Eval follow-ups (`eval-followups.ts`) and PR-comment follow-ups (`pr-comment-handler.ts`) only borrowed the shared engine for its dedup pass. Both keep their exact behavior, column, priority, `sourceType`, and log lines, with dedup inlined as a `listTasks` scan on `suggestionId` / `prNumber` respectively. Both fail open (create) if the listing throws, matching the old engine. ## Test changes — read this one Two tests asserted the *deleted* engine's rate-limited `"[verification recurrence]"` logEntry. Those assertions were removed, **not loosened**: both tests still assert no duplicate card is created, and the eval test still asserts the existing id is reported back. No coverage of surviving behavior was weakened. The three `meta-*` test files were deleted along with the sweeps they covered. ## Verification ``` $ pnpm test:gate Test Files 2 passed (2) Tests 10 passed (10) # core Test Files 16 passed (16) Tests 299 passed (299) # engine-core Test Files 1 passed (1) Tests 70 passed (70) # ci-shape GATE_EXIT=0 $ pnpm --filter @fusion/engine --filter @fusion/core exec tsc --noEmit -p tsconfig.json TSC_EXIT=0 (no output) ``` Plus a file-scoped run over the touched surfaces (`eval-followups`, `pr-comment-handler`, `merger-autostash-orphan-surface`, `merger-autostash-cleanup`, `run-audit`, `run-audit-secret-taxonomy`, `project-engine`, `project-engine-manager`): **213/213 passed**. A repo-wide grep confirms no surviving references to any deleted symbol, module, or audit event. 🤖 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** * Failed tasks now retain recovery and verification details directly on the original task instead of generating separate follow-up cards. * Live autostash issues now preserve stash information in task comments and activity logs. * Existing evaluation and pull-request follow-ups continue to be reused when appropriate. * **Changes** * Removed automatic archival of meta-tasks. * Removed obsolete meta-task timing settings. * **Documentation** * Updated architecture and settings documentation to reflect these workflow changes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
3f33cb000f |
feat: per-origin workflow selection + feedback-derived refinement titles
Two task origins had no workflow picker in front of the operator and always inherited the project default: `fn task create` (CLI + the `fn_task_create` agent tool) and refinement tasks. Add a Project General setting for each, where blank/unset means "Selected workflow" (the operator's current Board lane, falling back to the project default) and a concrete id pins that origin. Because the Board lane lives in browser localStorage, non-browser callers could not resolve "Selected workflow" at all. `boardSelectedWorkflowId` mirrors the lane into project settings so they can. Note this makes the mirrored lane project-scoped: two operators on one project share it, last switch wins. The Board never reads it back, so the only effect is which workflow a newly created task inherits. Resolution is `TaskStore.resolveOriginWorkflowOverrideId(origin)`: pinned setting -> mirrored lane -> `undefined` to inherit each caller's existing default-workflow path unchanged. A deleted or fragment id degrades to inherit rather than throwing, so a stale settings value can never break task creation. An explicit `workflow_id` argument to `fn_task_create` still wins. Separately, a refinement is now titled by the operator's own feedback via the shared `deriveFallbackTaskTitle`, not `Refinement: <parent title>`. Ten refinements of one task previously rendered ten identical titles, so the board could not tell them apart while the text saying what each one asked for sat in the description. Provenance moves to a `Refines <id>` card chip alongside the existing detail-view parent link and dependency edge. Verified: merge gate (299 tests), lint, full build, and typecheck for core, CLI, and dashboard all pass. New coverage: origin resolution across both origins and the full precedence ladder, the two settings pickers, the board-lane mirror, refinement titling (including sibling distinctness), and the card chip. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
2bb8537352 |
FN-8616: make agent tool-output limits configurable
Expose the shared agent tool-output budget as a scoped operator setting with an explicit no-limit option. - Resolve global and project output caps with a safe finite default and zero sentinel. - Propagate configured budgets through PI and plugin runtime tool wrappers. - Add settings controls, localized labels, documentation, and regression coverage. Files changed: .changeset/fn-8616-tool-output-budget-setting.md | 7 ++++ docs/agents.md | 4 +- docs/settings-reference.md | 1 + .../core/src/__tests__/tool-output-budget.test.ts | 23 ++++++++--- packages/core/src/index.gate.ts | 2 + packages/core/src/index.ts | 2 + packages/core/src/settings-schema.ts | 12 ++++++ packages/core/src/tool-output-budget.ts | 31 +++++++++++++-- packages/core/src/types/settings-scope.ts | 8 ++++ .../app/components/settings/save-split.ts | 1 + .../sections/GlobalGeneralSection.search.ts | 20 ++++++++++ .../settings/sections/GlobalGeneralSection.tsx | 26 ++++++++++++ ...lobalGeneralSection.tool-output-budget.test.tsx | 46 ++++++++++++++++++++++ .../settings-default-descriptions.test.tsx | 1 + .../src/__tests__/agent-session-helpers.test.ts | 20 ++++++++++ .../src/__tests__/runtime-resolution.test.ts | 15 +++++++ .../__tests__/tool-output-budget-wrapper.test.ts | 45 ++++++++++++++++----- packages/engine/src/agent-runtime.ts | 2 + packages/engine/src/agent-session-helpers.ts | 18 +++++++-- packages/engine/src/pi.ts | 29 ++++++++++---- packages/engine/src/runtime-resolution.ts | 10 ++++- packages/i18n/locales/en/app.json | 4 ++ packages/i18n/locales/es/app.json | 6 ++- packages/i18n/locales/fr/app.json | 6 ++- packages/i18n/locales/ko/app.json | 6 ++- packages/i18n/locales/zh-CN/app.json | 6 ++- packages/i18n/locales/zh-TW/app.json | 6 ++- packages/i18n/src/resources.d.ts | 4 ++ 28 files changed, 323 insertions(+), 38 deletions(-) Fusion-Task-Id: FN-8616 Fusion-Task-Lineage: 3ca99a61-d6ae-48ff-98d2-f14a153aa2b7 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
99b80ad748 |
feat(dashboard): add opt-in auto-update and harden restart supervision
Add the `autoUpdateAndRestart` global setting (default off, Settings -> General next to Release channel). When enabled, the dashboard host installs available updates on the selected channel by itself and requests the supervised in-place restart. Supervised hosts only: without a parent to respawn, installing would leave a running process whose code no longer matches its own install. Fix two ways the restart affordance could silently do nothing: - The supervisor now stamps FUSION_SUPERVISOR_PID and supervision is only counted when that pid is the real parent. FUSION_RESTART_SUPERVISED is inherited by every process Fusion spawns, so `fn dashboard` launched from an agent terminal skipped its own supervisor while still advertising restart support -- a restart request then killed it for good. - Settings and the update banner probe /system/info on mount and treat capability as advisory: the button always issues the request and shows the server's actual refusal instead of sitting disabled after a failed probe. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
2ea5ac206d |
fix(cli-tests,dashboard): align quiet-mode result spies and voiceInput allowlist
CLI JSON/create success lines write via result() (raw stdout) so quiet mode cannot drop machine-readable output; capture that seam in research/update/task tests instead of console.log. Allowlist nested voiceInput settings for the FN-7505 default-description guard and ship locale keys for Voice Input UI. |
||
|
|
2a2b157cb9 |
FN-8585: fix dashboard composer test source reads
Stabilize dashboard composer tests when Vitest launches from the workspace root. - Resolve dashboard test source fixtures relative to the app directory. - Migrate affected component tests away from cwd-relative CSS reads. - Enforce the fixture convention in test hooks and document it. Files changed: docs/testing.md | 4 +++ package.json | 6 ++-- .../__tests__/AuthTokenRecoveryDialog.test.tsx | 3 +- .../components/__tests__/ChatView.mobile.test.tsx | 5 +-- .../__tests__/EngineControlMenu.test.tsx | 11 ++---- .../components/__tests__/FloatingWindow.test.tsx | 5 +-- .../app/components/__tests__/ListView.test.tsx | 5 +-- .../__tests__/MissionInterviewModal.test.tsx | 3 +- .../app/components/__tests__/MobileNavBar.test.tsx | 3 +- .../app/components/__tests__/NewTaskModal.test.tsx | 3 +- .../__tests__/PlanningModeModal.initial.test.tsx | 3 +- .../PlanningModeModal.ui-interactions.test.tsx | 7 ++-- .../components/__tests__/PrCreateModal.test.tsx | 3 +- .../__tests__/QuickChat.persist.test.tsx | 3 +- .../components/__tests__/QuickEntryBox.test.tsx | 3 +- .../components/__tests__/ReportActionMenu.test.tsx | 9 ++--- .../app/components/__tests__/ReportModal.test.tsx | 3 +- .../__tests__/ShadcnColorPicker.test.tsx | 3 +- .../components/__tests__/TerminalModal.test.tsx | 3 +- .../components/__tests__/ThemeDropdown.test.tsx | 9 ++--- .../__tests__/WorkflowNodeEditor.test.tsx | 5 +-- .../WorkflowOptionalStepsDropdown.test.tsx | 3 +- .../components/__tests__/WorkflowSwitcher.test.tsx | 5 +-- .../app/components/__tests__/board-mobile.test.tsx | 4 +-- .../__tests__/CommandCenterControls.test.tsx | 6 ++-- .../__tests__/SystemControlsArea.test.tsx | 5 +-- .../__tests__/SystemStatsArea.test.tsx | 3 +- .../command-center/areas/__tests__/areas.test.tsx | 3 +- .../__tests__/KeyboardShortcutsSection.test.tsx | 3 +- .../app/test/__tests__/cssFixture.test.ts | 35 +++++++++++++++++++ packages/dashboard/app/test/cssFixture.ts | 12 +++++++ .../check-no-cwd-relative-dashboard-test-reads.mjs | 39 ++++++++++++++++++++++ 32 files changed, 162 insertions(+), 55 deletions(-) Fusion-Task-Id: FN-8585 Fusion-Task-Lineage: 83a35fb6-a29d-4e97-b282-1054c68b8cc9 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
11db36187f |
FN-8572: add voice input settings and model controls
Add project-scoped voice dictation controls with observable local model management. - Add the Voice Input settings section with opt-in enablement and runtime-safe status handling. - Add Parakeet v3 model download, removal, progress polling, search, documentation, and regression coverage. - Add a minor release changeset for Voice Input settings. Files changed: .changeset/fn-8572-voice-input-settings.md | 7 ++ docs/dashboard-guide.md | 4 + docs/settings-reference.md | 1 + .../dashboard/app/components/SettingsModal.tsx | 7 +- .../VoiceInputSection.modal-visibility.test.tsx | 19 +++ .../settings/__tests__/VoiceInputSection.test.tsx | 137 +++++++++++++++++++++ .../settings/__tests__/section-keys.test.ts | 1 + .../search/__tests__/settings-search-index.test.ts | 1 + .../app/components/settings/search/entries.ts | 2 + .../app/components/settings/section-keys.ts | 2 + .../settings/sections/VoiceInputSection.css | 48 ++++++++ .../settings/sections/VoiceInputSection.search.ts | 14 +++ .../settings/sections/VoiceInputSection.tsx | 128 ++++++++++++++++++++ 13 files changed, 370 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-8572 Fusion-Task-Lineage: 2d2ad0df-3765-4d19-a6f3-7c2b5ca5df95 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
4b0edf65d5 |
fix(dashboard-tests): index Anthropic auth preference and pause badge contract
- Register AuthenticationSection search entry for anthropicAuthPreference - Map setting default description + en locale strings for the new control - Expect executorState paused when enginePaused with zero running tasks |
||
|
|
8dc6598aa0 |
feat(auth): let operators choose which Anthropic credential wins
An operator can hold a raw Anthropic API key and a Claude subscription OAuth
login at once, and the raw key always won silently. A stale or revoked saved
key therefore shadowed a working subscription and failed every direct Anthropic
call with 401 invalid x-api-key, while both Settings cards still read Active.
Add the global anthropicAuthPreference setting ("api-key" default, preserving
the historical precedence, or "subscription"), read in resolveAnthropicRuntimeApiKey
straight from ~/.fusion/settings.json so it applies without a restart and needs
no settings plumbing through createFusionAuthStorage. Neither value removes a
source: with one credential configured, resolution reaches it either way.
Settings -> Authentication now names the credential in use on the two Anthropic
cards and renders the control, but only when both are actually connected.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
0a6f84bbdf |
fix(dashboard): index the FN-8348 Report row in settings search; re-green backfill test lane
Product fixes surfaced by the drift guards: - GeneralSection.search.ts: FN-8348 added the Report row (bug/feedback/idea/help) without a search-index entry, so settings search could not find it. - WorkflowNodeEditor.css: FN-8526 introduced the undefined deprecated alias --text-secondary; substitute the FN-8043 migration token --text-muted. Stale-test alignment (no assertions weakened): - settings-sections: builtin:coding-ideas is no longer deprecated post-#2378. - TaskDetailModal workflow/oversight suites: mocked workflows gain the columns array FN-8476 metadata resolution requires; rerender-refetch tests use persistent mocks since the board-workflows effect now keys on task identity. - ChatView.chat-commands: sendMessage gained the FN-8502 delivery-callback arg. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
6111a6e3f2 |
fix(ci): full-suite bookkeeping v31 after origin/main (#2408)
## Summary Restore full-suite green after latest `origin/main` landings. PR #2392 already merged; this branch starts from current main. - **ExecutorStatusBar mobile utility test:** assert `Waiting` (product rename from Queued) and that the In Review segment is gone. - **AppearanceSection task-popup help:** assert FN-8478 fallback copy (board deep-tab chips + List row/card + right-dock → movable popup). - **Changeset format gate:** shorten `mobile-board-pointercancel-settle.md` summary to ≤120 chars (was blocking `pnpm test:gate` on main). ## Context Latest main Full Suite run failed primarily on dashboard app quality backfill: - https://github.com/Runfusion/Fusion/actions/runs/29970703115 ## Test plan - [x] `pnpm test:gate` ×2 - [x] `utility-mobile.test.tsx` + `AppearanceSection.test.tsx` - [x] `settings-default-descriptions.test.tsx` - [ ] CI PR checks / Full Suite on this branch <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved mobile board column snapping when resting mid-screen, flinging past columns, or making unintended swipes. * Updated task status labels to show “Waiting,” “Running,” and “Blocked.” * Refined help text for opening tasks as popups, including click-target and subsequent-task behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e5d6be4123 |
Fix Windows embedded PostgreSQL 0xC0000142 crashes (issue #2411) (#2418)
## Summary Two-part fix for #2411 — Windows embedded PostgreSQL backends dying with exception `0xC0000142` and taking the whole dashboard down. ### 1. Crash hardening + recovery (FN-8522) - Child-only native `PATH` hardening so forked backends can always resolve their runtime DLLs. - Non-blocking `.pgrunner` log monitoring (shared read), eliminating the self-inflicted ~30s `sharing violation` retry window at boot. - Detection of the ordered 0xC0000142 shutdown sequence with a single automatic restart of owned clusters on their resolved port, plus operator diagnostics. ### 2. Platform-aware `max_connections` default (follow-up from [operator report](https://github.com/Runfusion/Fusion/issues/2411#issuecomment-5054900702)) On Windows every PostgreSQL connection is a separate process; the embedded cluster's unconfigured `max_connections=500` cap lets backend spawn bursts exhaust the non-interactive desktop heap, which kills forked backends with exactly `0xC0000142`. The reporter confirmed stability after lowering the cap. - `embeddedPostgresMaxConnections` is now schema-unset so the server can distinguish "operator never set it" from an explicit choice (`getSettings()` merges schema defaults, which previously pinned 500 unconditionally and made the runtime fallback dead code). - New `resolveEmbeddedMaxConnections()` resolves the unset default platform-aware: **150 on win32, 500 elsewhere**. Explicit settings are honored on every platform, clamped to [32, 2000] as before. - Settings UI renders the cap empty ("auto") with platform-aware help copy across all six locales. - Fixed a latent reset bug this exposed: global "Reset this menu" wrote `undefined` for undefined-default keys, which JSON serialization drops — the stored value silently survived reset. Now uses null-as-delete. ## Testing - New unit tests for `resolveEmbeddedMaxConnections` (platform defaults, clamping, non-integer handling). - Updated settings-defaults, default-descriptions, and SettingsModal tests; embedded lifecycle + recovery coverage from FN-8522. - `@fusion/core` builds clean; changesets included for both parts. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
0e2aa49f8d |
FN-8520: hide uninstalled runtimes from Settings
Keep Settings runtime navigation synchronized with installed runtime plugins. - Filter runtime sections to installed plugins while preserving disabled installed runtimes - Refresh runtime navigation after plugin lifecycle events and direct plugin mutations - Add Settings coverage and document runtime visibility behavior Files changed: .changeset/fn-8520-runtime-sidebar.md | 7 +++ docs/dashboard-guide.md | 2 +- .../dashboard/app/components/PluginManager.tsx | 10 +++- .../dashboard/app/components/SettingsModal.tsx | 70 +++++++++++++++++++++- .../__tests__/SettingsModal.general.test.tsx | 58 ++++++++++++++++++ .../__tests__/SettingsModal.test-harness.tsx | 2 + .../components/__tests__/settings-mobile.test.tsx | 1 + .../settings/sections/PluginsSection.tsx | 6 +- 8 files changed, 149 insertions(+), 7 deletions(-) Fusion-Task-Id: FN-8520 Fusion-Task-Lineage: 914ae503-e1b0-4051-bc01-4da950bf55b3 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
3cd023fa43 |
FN-8491: add declarative plugin MCP server registrations
Enable plugins to declare per-project MCP server registrations. - Add plugin MCP server contribution types, loading, and resolution across core and engine runtimes. - Expose resolved plugin registrations through project configuration APIs and MCP settings UI. - Document the declarative contribution API and add release metadata and regression coverage. Files changed: .changeset/plugin-mcp-servers.md | 7 ++ docs/PLUGIN_AUTHORING.md | 17 +++++ docs/mcp.md | 4 ++ docs/settings-reference.md | 4 ++ packages/core/src/__tests__/mcp-config.test.ts | 33 +++++++++ .../__tests__/plugin-contribution-types.test.ts | 16 +++++ .../__tests__/plugin-loader-single-load.test.ts | 23 +++++++ packages/core/src/index.gate.ts | 3 + packages/core/src/index.ts | 3 + packages/core/src/mcp-config.ts | 37 ++++++++-- packages/core/src/plugin-loader.ts | 24 +++++++ packages/core/src/plugin-mcp-servers.ts | 78 ++++++++++++++++++++++ packages/core/src/plugin-types.ts | 15 ++++- packages/core/src/types.ts | 2 +- .../__tests__/SettingsModal.mcp.test.tsx | 34 +++++++++- .../settings/sections/McpServersCard.tsx | 52 ++++++++++----- .../settings/sections/ProjectMcpSection.tsx | 31 ++++++++- .../register-config-mcp-pi-settings-routes.test.ts | 18 ++++- packages/dashboard/src/routes/context.ts | 71 +++++++++++++++++++- .../register-config-mcp-pi-settings-routes.ts | 30 ++++++++- .../engine/src/__tests__/mcp-resolution.test.ts | 20 ++++++ packages/engine/src/mcp-resolution.ts | 15 ++++- packages/engine/src/plugin-runner.ts | 38 +++++++++++ packages/engine/src/runtimes/in-process-runtime.ts | 23 +++++++ packages/plugin-sdk/src/index.ts | 1 + 25 files changed, 563 insertions(+), 36 deletions(-) Fusion-Task-Id: FN-8491 Fusion-Task-Lineage: be7e22fa-5776-4b3d-9fd1-a873799e6427 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
e514e134da |
fix: apply project model lanes across workflows (#2400)
## Summary Project workflow model lanes now apply to tasks on every workflow instead of only tasks using the active default workflow. Model selection consistently resolves task-specific choice -> project workflow baseline -> global lane -> selected-workflow value -> project/global default for primary models, fallback models, and thinking levels. The active default workflow remains the storage owner for backward compatibility, while runtime resolution keeps its project baseline distinct from lower-priority selected-workflow values. Non-model workflow policies remain isolated to their selected workflow. ## Validation - Core workflow/model resolution: 60 tests passed - Engine effective settings and session resolution: 59 tests passed - Reviewer: 85 tests passed - Scheduler: 154 tests passed - Heartbeat: 90 tests passed - Settings UI: 67 tests passed - Workspace lint and core/engine/dashboard typechecks passed - `pnpm verify:fast` passed workspace builds, the published CLI build, and real `/api/health` boot smoke --- [](https://github.com/EveryInc/compound-engineering-plugin) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added **Project workflow model lanes** to establish a project baseline for model selection and thinking levels across workflows. * Updated model/fallback resolution to account for task overrides, project baselines, global lanes, and selected-workflow values. * **Bug Fixes** * Improved effective settings merging so project baselines are applied correctly (including scheduled/idle and heartbeat flows) while preserving selected-workflow provenance. * **Documentation** * Refreshed settings and dashboard guidance for workflow lane inheritance and resolution precedence. * **Tests** * Expanded unit test coverage for lane precedence, fallback detection, and thinking-level behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fee920d366 |
FN-8478: open board deep tabs in task popups
Make board task deep-tab actions preserve their requested popup tab when task popups are enabled. - Route Changes, Retries, and Workflow board actions through the popup preference. - Store and refresh each popup's requested initial tab for its task and view. - Add regression coverage, documentation, and a patch changeset. Files changed: .changeset/task-card-popup-deep-tabs.md | 7 +++++ docs/dashboard-guide.md | 4 +-- docs/settings-reference.md | 2 +- packages/dashboard/app/App.tsx | 25 ++++++++++----- .../__tests__/App.openTasksInRightSidebar.test.ts | 36 ++++++++++++---------- .../__tests__/navigation-history.test.tsx | 25 ++++++++++++++- .../settings/sections/AppearanceSection.tsx | 4 +-- .../app/hooks/__tests__/usePoppedOutTasks.test.ts | 13 ++++++++ packages/dashboard/app/hooks/usePoppedOutTasks.ts | 15 ++++++--- 9 files changed, 97 insertions(+), 34 deletions(-) Fusion-Task-Id: FN-8478 Fusion-Task-Lineage: e12452c0-24d5-4f19-b50c-39526d72d7ab Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
1e05793876 |
fix(ci): green full-suite bookkeeping after origin/main cutover (#2392)
## Summary Restores green merge-gate and package-default suites after repeated `origin/main` merges brought workflow-graph ownership cutover drift into CI. - Align engine/dashboard/core tests with post-cutover contracts (`moveTaskIf`/`deleteTaskIf`, graph handoff, worktree-pool reclaim via `removeWorktree` + `RemovalReason`, multi-step RESUMING parse, soft-pause merge requester, graph-terminal failure surfaces). - Small product fixes needed for real regressions uncovered by the suite: soft-delete refuse before graph routing, skip DUPLICATE step-heading withhold when an explicit marker is present, PG schema applier guards, and related bookkeeping (research promote tool inventory / migration seed, stop shell `psql` in PG admin DDL). - Quarantine/ledger hygiene only where required by standing rules; no timeout/worker appeasement. ## Verification - `pnpm test:gate` ×2 green - `@fusion/engine` full package suite green (~9083 tests) - Targeted core/dashboard clusters green (schema applier, agent-runs UI, settings descriptions, mobile close) ## Test plan - [x] `pnpm test:gate` (twice) - [x] `pnpm --filter @fusion/engine test` - [ ] CI full suite / PR checks on this branch - [ ] Confirm no unrelated product behavior changes beyond the listed regression fixes <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for `roadmap-item` native structure kinds, including native structure embeds and metadata validation. * Added Stable and Beta release channel options in General settings. * Added per-action reporting target configuration with clearer “unset” guidance. * **Bug Fixes** * Improved heartbeat/prompt behavior when patrol is disabled. * Prevented deleted tasks from continuing through execution. * Made recovery for explicit duplicate redirects more permissive. * Hardened database migration and test database cleanup to reduce flaky failures. * **Documentation** * Updated settings text for release channels, reporting targets, and inheritance/unset behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
eef5eb751e |
FN-8453: unify concurrency accounting and indicators
Unify live-agent capacity accounting across engine and dashboard. - Derive Running and Waiting from workflow traits and durable agent liveness. - Apply unified limits to planner, executor, and merge admission while updating dashboard indicators. - Remove duplicate concurrency controls and document the unified operator model. Files changed: .changeset/fn-8453-unified-concurrency.md | 7 + docs/agent-tool-surface-full-loop.md | 4 +- docs/architecture.md | 2 +- docs/dashboard-guide.md | 4 +- docs/settings-reference.md | 4 +- .../skill/fusion/references/fusion-capabilities.md | 4 +- .../core/src/__tests__/live-agent-count.test.ts | 91 ++++---- packages/core/src/index.gate.ts | 6 + packages/core/src/index.ts | 6 + packages/core/src/live-agent-count.ts | 107 ++++++--- packages/dashboard/app/App.tsx | 28 ++- packages/dashboard/app/api/board-workflows.ts | 2 + packages/dashboard/app/components/Column.tsx | 6 +- .../dashboard/app/components/EngineControlMenu.tsx | 26 --- .../dashboard/app/components/ExecutorStatusBar.tsx | 38 ++- .../dashboard/app/components/SettingsModal.tsx | 1 - .../app/components/__tests__/Column.test.tsx | 6 +- .../__tests__/EngineControlMenu.test.tsx | 10 +- .../__tests__/ExecutorStatusBar.test.tsx | 32 ++- .../command-center/CommandCenterControls.tsx | 26 --- .../settings/sections/SchedulingSection.search.ts | 9 - .../settings/sections/SchedulingSection.tsx | 13 -- .../app/hooks/__tests__/useExecutorStats.test.ts | 12 +- packages/dashboard/app/hooks/useExecutorStats.ts | 50 ++-- .../src/__tests__/project-store-resolver.test.ts | 11 +- packages/dashboard/src/project-store-resolver.ts | 14 +- .../register-config-mcp-pi-settings-routes.ts | 3 +- packages/engine/src/__tests__/concurrency.test.ts | 123 +++++++++- .../engine/src/__tests__/project-engine.test.ts | 34 +++ packages/engine/src/__tests__/triage.test.ts | 7 +- packages/engine/src/concurrency.ts | 207 ++++++++++++++++- packages/engine/src/project-engine.ts | 151 ++++++++++-- packages/engine/src/scheduler.ts | 82 ++++++- packages/engine/src/triage.ts | 254 +++++++++++++-------- .../lib/dashboard-browser-safe-core-modules.json | 5 + 35 files changed, 991 insertions(+), 394 deletions(-) Fusion-Task-Id: FN-8453 Fusion-Task-Lineage: 12cfa5df-675d-4fce-b17e-932376544239 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
d4a87accb8 |
FN-8395: autosave settings changes
Settings edits now persist automatically with safe feedback and close handling. - Debounce and serialize settings persistence, retaining newer edits through in-flight saves and unmounts. - Remove the Settings Save action and unsaved-changes prompt while flushing pending section and workflow-lane updates. - Update Settings documentation, release metadata, and regression coverage for auto-save behavior. Files changed: .changeset/fn-8395-settings-autosave.md | 7 + docs/dashboard-guide.md | 11 +- docs/settings-reference.md | 8 +- .../dashboard/app/components/SettingsModal.tsx | 402 ++++++++++++++++----- .../__tests__/SettingsModal.general.test.tsx | 154 ++++++-- .../SettingsModal.keyboardShortcuts.test.tsx | 7 +- .../__tests__/SettingsModal.models-auth.test.tsx | 46 +-- .../SettingsModal.remote-notifications.test.tsx | 38 +- .../SettingsModal.scheduling-merge.test.tsx | 58 ++- .../__tests__/SettingsModal.test-harness.tsx | 9 +- .../__tests__/SettingsModalNodeRouting.test.tsx | 2 - .../settings/sections/ProjectModelsSection.tsx | 15 +- 12 files changed, 548 insertions(+), 209 deletions(-) Fusion-Task-Id: FN-8395 Fusion-Task-Lineage: 77f4c0d3-d0cc-4973-9831-c70eb2a2b49b Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
18f1cb743a |
FN-8308: add selectable GitHub Discussions report targets
Enable configurable GitHub Issue or Discussion destinations for in-app reports. - Add report target and Discussion category settings with localized controls. - Validate target overrides before Help shortcuts and route them through report filing. - Discover and validate GitHub Discussion categories through GraphQL. - Cover target validation on both draft and file routes. Files changed: .changeset/fn-8308-report-discussions.md | 7 +++ docs/dashboard-guide.md | 7 +++ .../core/src/__tests__/settings-parity.test.ts | 9 +++ packages/core/src/index.gate.ts | 2 +- packages/core/src/index.ts | 2 +- packages/core/src/settings-schema.ts | 4 ++ packages/core/src/types.ts | 10 ++++ packages/dashboard/app/api/report.ts | 13 +++- packages/dashboard/app/components/ReportModal.tsx | 9 ++- .../__tests__/SettingsModal.general.test.tsx | 18 ++++++ .../settings/sections/GeneralSection.tsx | 16 ++++- .../src/__tests__/github-discussions.test.ts | 44 ++++++++++++++ .../src/__tests__/report-pipeline.test.ts | 70 +++++++++++++++++++++- .../dashboard/src/__tests__/report-routes.test.ts | 19 ++++++ packages/dashboard/src/github.ts | 37 ++++++++++-- packages/dashboard/src/index.ts | 4 +- packages/dashboard/src/report-pipeline.ts | 41 +++++++++---- .../dashboard/src/routes/register-report-routes.ts | 32 ++++++++-- packages/i18n/locales/en/app.json | 26 +++++++- packages/i18n/locales/es/app.json | 26 +++++++- packages/i18n/locales/fr/app.json | 26 +++++++- packages/i18n/locales/ko/app.json | 26 +++++++- packages/i18n/locales/zh-CN/app.json | 26 +++++++- packages/i18n/locales/zh-TW/app.json | 26 +++++++- 24 files changed, 453 insertions(+), 47 deletions(-) Fusion-Task-Id: FN-8308 Fusion-Task-Lineage: f5ac1b67-ecbc-4765-88c7-c524c7e943bf Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
bea51f7bdb |
FN-8348: relocate report actions to settings and command center
Relocate guided reporting from the header into durable project and overview surfaces. - Add Report entry points to Project General settings and Command Center Overview. - Preserve guided report modal context through a shared route helper. - Cover relocated controls and update dashboard guidance. Files changed: docs/dashboard-guide.md | 2 +- packages/dashboard/app/components/Header.tsx | 33 ++++------------------ .../dashboard/app/components/SettingsModal.tsx | 2 +- .../app/components/__tests__/Header.test.tsx | 7 +++++ .../components/command-center/CommandCenter.css | 32 +++++++++++++++++++++ .../components/command-center/CommandCenter.tsx | 30 +++++++++++++++++++- .../__tests__/CommandCenter.test.tsx | 11 ++++++++ .../settings/sections/GeneralSection.tsx | 21 ++++++++++++++ .../GeneralSection.aiUndoWorkflow.test.tsx | 20 +++++++++++-- packages/dashboard/app/utils/reportContextRefs.ts | 13 +++++++++ 10 files changed, 139 insertions(+), 32 deletions(-) Fusion-Task-Id: FN-8348 Fusion-Task-Lineage: add1b302-deab-4e17-be2f-832971c1c83d Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
da1e445d6b |
FN-8310: add public-roadmap report deduplication
Add public-roadmap issues as a configurable, reviewable deduplication source for in-app reports. - Resolve roadmap settings across project, global, and tracking-repository fallbacks - Search and endorse matching open roadmap issues before filing duplicate reports - Expose and index roadmap controls with localized default descriptions Files changed: .changeset/fn-8310-public-roadmap-dedupe.md | 7 ++ docs/dashboard-guide.md | 2 +- docs/settings-reference.md | 4 +- .../core/src/__tests__/settings-parity.test.ts | 14 +++- packages/core/src/settings-schema.ts | 7 +- packages/core/src/types.ts | 13 +++- packages/dashboard/app/api/report.ts | 2 +- packages/dashboard/app/components/ReportModal.tsx | 18 ++--- .../dashboard/app/components/SettingsModal.tsx | 15 +++- .../app/components/__tests__/ReportModal.test.tsx | 12 ++-- .../__tests__/SettingsModal.general.test.tsx | 6 +- .../settings/__tests__/section-keys.test.ts | 5 +- .../app/components/settings/save-split.ts | 14 ++-- .../app/components/settings/section-keys.ts | 5 ++ .../settings/sections/GeneralSection.search.ts | 34 ++++++--- .../settings/sections/GeneralSection.tsx | 29 ++++++-- .../sections/SourceControlGlobalSection.search.ts | 27 +++++++ .../sections/SourceControlGlobalSection.tsx | 55 ++++++++++---- .../settings-default-descriptions.test.tsx | 4 +- .../src/__tests__/report-pipeline.test.ts | 73 ++++++++++++------- .../dashboard/src/__tests__/report-routes.test.ts | 23 +++--- packages/dashboard/src/report-pipeline.ts | 84 ++++++++++++++-------- .../dashboard/src/routes/register-report-routes.ts | 9 +-- packages/i18n/locales/en/app.json | 17 ++++- packages/i18n/locales/es/app.json | 17 ++++- packages/i18n/locales/fr/app.json | 17 ++++- packages/i18n/locales/ko/app.json | 17 ++++- packages/i18n/locales/zh-CN/app.json | 16 ++++- packages/i18n/locales/zh-TW/app.json | 16 ++++- 29 files changed, 409 insertions(+), 153 deletions(-) Fusion-Task-Id: FN-8310 Fusion-Task-Lineage: 0efa8d76-e849-4256-bdcd-e9d6dd612e41 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
2302fb8a3d |
feat: add beta/stable release tracks with switchable update channel (#2345)
## Summary Fusion can now ship on two release tracks. Betas are cut from `main` as `vX.Y.Z-beta.N` (npm dist-tag `beta`, GitHub prerelease), stable releases are promoted to a long-lived `release` branch and published to `latest`, and users pick their track with the new `updateChannel` global setting — via **Settings → General → Release channel** or `fn update --channel <stable|beta>`. Previously everything was single-track: every publish landed on `latest` and every update surface could only see it. | | beta | stable | |---|---|---| | Cut from | `main` | `release` branch | | Version | `X.Y.Z-beta.N` (changesets pre-mode) | `X.Y.Z` | | npm dist-tag | `beta` | `latest` | | GitHub Release | prerelease | latest | | Homebrew tap / X draft | skipped | bumped / printed | ## How releasing works now `pnpm release` prompts for the channel and **defaults to beta**, so day-to-day releases are betas; stable is always an explicit choice. Choosing stable from `main` triggers assisted promotion: the script proposes the newest beta tag reachable from HEAD, verifies `release` fast-forwards to it, then runs the whole stable release inside a temporary git worktree on `release` — the primary checkout never leaves `main`. Changesets pre-mode preserves changeset files across betas, so the promoted stable release aggregates every changeset since the last stable into one clean changelog entry. ## Design decisions - **Every publish path names an explicit `--tag`.** A beta accidentally landing on `latest` is the one unrecoverable failure of a dual-track scheme, so nothing relies on npm's implicit default (`release.mjs`, `version.yml`). - **Beta channel resolves to semver-max of `latest` and `beta`**, so beta users are offered each promoted stable once it overtakes their prerelease. Switching beta → stable never downgrades; `fn update --channel stable --force` is the explicit escape hatch. - **One comparator instead of three.** CLI, dashboard, and desktop each had their own `isRemoteNewer` that ignored prerelease identifiers — `0.73.0-beta.2`, `-beta.3`, and `0.73.0` all compared equal, which breaks the moment any beta exists. They now share full SemVer-precedence helpers (`compareVersions`, `resolveUpdateTargetVersion`) from `@fusion/core`. - **Installs pin exact versions** (`@runfusion/fusion@0.73.0-beta.2`), never a dist-tag, so an install can't silently land on the wrong track. - **Desktop channels via electron-updater manifests.** Beta tags build desktop artifacts with `publish.channel=beta` (emitting `beta*.yml`); the app sets `channel`/`allowPrerelease` from the shared setting, re-read on every manual check. - **Update caches are channel-stamped** — a cache written for one channel is never served to the other, so switching tracks takes effect on the next check instead of after TTL. ## Test plan - New unit coverage: SemVer precedence + channel resolution in `@fusion/core` (30), channel behavior of the dashboard update check (28, incl. 9 new) and `fn update` (16, incl. 8 new: persist `--channel`, no-downgrade, `--force`, cache channel mismatch). - `pnpm verify:fast` green (scoped typecheck, builds, CLI build, boot smoke); desktop + settings-section suites green. - `release.mjs` dry-run matrix exercised by hand: channel prompt (default/override/invalid), branch preflights per channel, assisted-promotion target selection, fast-forward guard against a diverged `release` branch, and bootstrap when no `release` branch exists. - Not exercised live: an end-to-end publish (needs TTY authorization + real npm publish). First real run is the first `pnpm release --channel beta`. --- [](https://github.com/EveryInc/compound-engineering-plugin)  <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added beta and stable release channels across CLI, dashboard, and desktop updates. * Users can select a channel via Settings or `fn update --channel <stable|beta>` (stored as a global default). * Desktop beta releases now generate beta update manifests and publish as prereleases. * **Documentation** * Expanded release-track, settings, and CLI references to explain channel semantics and workflows. * **Bug Fixes** * Updates now pin the resolved version per channel, improve version comparison, and prevent unintended cross-channel downgrades unless `--force` is used. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
12aee016ee |
FN-8352: promote ideation to top-level navigation
Make ideation independently accessible from desktop and mobile navigation. - Add an Ideation view backed by the Command Center panel and view-state routing. - Surface Ideation in desktop/sidebar and mobile primary navigation, with coverage for navigation and rendering. - Document the experimental setting and add a minor changeset. Files changed: .changeset/fn-8352-ideation-top-level-view.md | 7 ++++ docs/dashboard-guide.md | 14 +++++++ docs/settings-reference.md | 3 +- .../src/__tests__/mobile-nav-primary-items.test.ts | 10 ++++- packages/core/src/mobile-nav-primary-items.ts | 17 +++++++- packages/dashboard/app/App.tsx | 16 ++++++- packages/dashboard/app/components/Header.tsx | 21 +++++++-- .../dashboard/app/components/LeftSidebarNav.tsx | 8 +++- packages/dashboard/app/components/MobileNavBar.tsx | 2 + .../dashboard/app/components/SettingsModal.tsx | 6 +++ .../app/components/__tests__/App.test.tsx | 20 +++++++++ .../app/components/__tests__/Header.test.tsx | 15 +++++++ .../components/__tests__/LeftSidebarNav.test.tsx | 5 +++ .../app/components/__tests__/MobileNavBar.test.tsx | 43 +++++++++++++++--- .../components/command-center/CommandCenter.tsx | 12 +++--- .../__tests__/CommandCenter.test.tsx | 7 ++-- .../__tests__/IdeationPanel.test.tsx | 49 ++++++++++++++++++++++ .../app/components/dashboard/MainContent.tsx | 13 ++++++ .../dashboard/app/components/dashboard/types.ts | 1 + .../settings/sections/GeneralSection.tsx | 10 ++--- packages/dashboard/app/hooks/useViewState.ts | 8 +++- 21 files changed, 256 insertions(+), 31 deletions(-) Fusion-Task-Id: FN-8352 Fusion-Task-Lineage: e7791119-2fe5-4e68-b669-0e5bd8df9b49 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
9f44f26a36 |
FN-8350: move configuration versions into Settings
Move project configuration revision history and rollback controls from Command Center to Settings. - Add a Project Settings configuration versions section with rollback handling. - Remove the Command Center revision card and retain organization portability controls. - Update translations, dashboard documentation, tests, and release metadata. Files changed: .changeset/fn-8350-config-versions-settings.md | 7 ++ docs/dashboard-guide.md | 3 +- .../dashboard/app/components/SettingsModal.tsx | 11 ++++ .../command-center/OrgPortabilityControls.css | 47 ++------------ .../command-center/OrgPortabilityControls.tsx | 55 +--------------- .../__tests__/CommandCenter.mobile-scroll.test.tsx | 2 +- .../__tests__/OrgPortabilityControls.test.tsx | 37 ++--------- .../sections/ConfigurationVersionsSection.css | 56 ++++++++++++++++ .../sections/ConfigurationVersionsSection.tsx | 75 ++++++++++++++++++++++ .../ConfigurationVersionsSection.test.tsx | 58 +++++++++++++++++ packages/i18n/locales/en/app.json | 29 +++++---- 11 files changed, 238 insertions(+), 142 deletions(-) Fusion-Task-Id: FN-8350 Fusion-Task-Lineage: a7f68720-038a-42a6-b064-38533c584492 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
a348428f32 |
FN-8335: surface settings defaults in help tips
Expose default and inheritance descriptions through consistent Settings help affordances. - Move report-mode and per-action override descriptions into accessible help tips - Cover default, override reset, and embedded PostgreSQL connection-cap help text - Keep the settings-default description inventory aligned with rendered copy Files changed: .../__tests__/SettingsModal.general.test.tsx | 37 ++++++++++++++++++++++ .../settings/sections/GeneralSection.tsx | 28 +++++++++------- .../settings-default-descriptions.test.tsx | 13 ++++---- 3 files changed, 60 insertions(+), 18 deletions(-) Fusion-Task-Id: FN-8335 Fusion-Task-Lineage: 7a8711be-8559-4799-afcd-8f22ac3adc2b Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
6268433d37 |
fix(ci): parent-task uniqueness mocks, roadmap search index, flake quarantine (#2323)
## Summary - FN-8277 parent-scoped uniqueness: mock `findRecentTasksBySourceParentTaskId` in heartbeat/triage/split suites. - FN-8326: index `reportRoadmapDedup` in Settings search. - Quarantine re-flaked `dev-server-process` under full-suite API load (run 29661202279). ## Test plan - [x] Targeted createTask / search-index tests green locally - [ ] Full Suite all 4 shards green on main after merge |
||
|
|
1215c76d9a |
FN-8326: add roadmap report deduplication
Add an optional public-roadmap source for report deduplication. - Add project settings and localized controls for roadmap matching. - Resolve roadmap entries through the plugin API and stop strong duplicate reports before filing. - Cover report pipeline, route, UI, and roadmap store behavior with tests. Files changed: .changeset/fn-8326-roadmap-report-dedup.md | 7 +++ docs/dashboard-guide.md | 2 + docs/settings-reference.md | 1 + .../core/src/__tests__/settings-parity.test.ts | 3 + packages/core/src/settings-schema.ts | 1 + packages/core/src/types.ts | 6 ++ packages/dashboard/app/components/ReportModal.tsx | 11 +++- .../app/components/__tests__/ReportModal.test.tsx | 14 +++++ .../__tests__/SettingsModal.general.test.tsx | 2 + .../settings/sections/GeneralSection.tsx | 10 ++++ .../settings-default-descriptions.test.tsx | 1 + .../src/__tests__/report-pipeline.test.ts | 31 +++++++++++ .../src/__tests__/report-roadmap-source.test.ts | 32 +++++++++++ .../dashboard/src/__tests__/report-routes.test.ts | 27 +++++++-- packages/dashboard/src/index.ts | 1 + packages/dashboard/src/report-pipeline.ts | 36 +++++++++++- packages/dashboard/src/report-roadmap-source.ts | 64 ++++++++++++++++++++++ .../dashboard/src/routes/register-report-routes.ts | 3 + packages/i18n/locales/en/app.json | 10 +++- packages/i18n/locales/es/app.json | 10 +++- packages/i18n/locales/fr/app.json | 10 +++- packages/i18n/locales/ko/app.json | 10 +++- packages/i18n/locales/zh-CN/app.json | 10 +++- packages/i18n/locales/zh-TW/app.json | 10 +++- .../src/__tests__/roadmap-store-factory.test.ts | 25 +++++++++ .../src/routes/roadmap-routes.ts | 24 +------- plugins/fusion-plugin-roadmap/src/server/index.ts | 34 ++++++++++++ 27 files changed, 360 insertions(+), 35 deletions(-) Fusion-Task-Id: FN-8326 Fusion-Task-Lineage: e9731c3f-dd92-44ac-910b-0e0efbaaf288 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
1a63b6dba6 |
fix(ci): index embedded Postgres cap and mock portability API in CC controls (#2317)
## Summary - Index `embeddedPostgresMaxConnections` in Settings search (backups-global). - Export `withProjectId` + `api` from `CommandCenterControls` legacy mock so FN-8284 portability card can mount under the controls suite. ## Test plan - [x] CommandCenterControls + settings-search-index tests green locally - [ ] Full Suite all 4 shards green on main after merge <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added the embedded PostgreSQL maximum connections setting to Settings search, with relevant labels, help text, and keywords. * **Tests** * Improved test coverage setup for controls that use project-specific API paths. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
13f936eb7b |
FN-8286: add review artifact controls and galleries
Add configurable review-deliverable policies and surface eligible artifacts in review workflows. - Add project and PROMPT.md review-artifact modes with task eligibility enforcement. - Display video and live-demo deliverables in Task Review and Command Center galleries. - Document, localize, and test the new review-artifact controls. Files changed: .changeset/fn-8286-review-artifacts.md | 7 ++ docs/settings-reference.md | 1 + .../core/src/__tests__/review-artifacts.test.ts | 53 +++++++++++++++ .../core/src/__tests__/settings-parity.test.ts | 5 ++ packages/core/src/index.ts | 4 +- packages/core/src/settings-schema.ts | 1 + packages/core/src/types.ts | 75 ++++++++++++++++++++++ packages/core/src/types/execution-and-ui.ts | 8 +++ .../dashboard/app/components/TaskReviewTab.tsx | 28 +++++++- .../__tests__/SettingsModal.general.test.tsx | 8 +++ .../components/__tests__/TaskReviewTab.test.tsx | 27 ++++++++ .../components/command-center/CommandCenter.tsx | 5 ++ .../command-center/areas/ReviewArtifactsArea.tsx | 59 +++++++++++++++++ .../areas/__tests__/ReviewArtifactsArea.test.tsx | 39 +++++++++++ .../app/components/settings/section-keys.ts | 1 + .../settings/sections/GeneralSection.tsx | 20 ++++++ .../settings-default-descriptions.test.tsx | 1 + .../src/__tests__/agent-artifact-tools.test.ts | 19 +++++- packages/engine/src/agent-tools.ts | 26 ++++++++ packages/i18n/locales/en/app.json | 7 ++ packages/i18n/src/resources.d.ts | 7 ++ 21 files changed, 397 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-8286 Fusion-Task-Lineage: 357ccbe3-510d-4ffd-ba7c-6bf79fe40a09 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
17ee1a8040 |
fix(ci): restore Full Suite bookkeeping after concurrent main landings (#2316)
## Summary - Align heartbeat `customTools` expectations with FN-8294 mission hierarchy tools (43→58). - Refresh `COORDINATION_EXEMPT_TOOLS` snapshot for `fn_mission_list` / `fn_mission_show`. - Backfill `commandCenter.portability.*` for non-en locales and map `reportMode` / `reportModeByAction` / `embeddedPostgresMaxConnections` into settings default-description inventory with i18n help text. - Realign FN-8064 skip-narration unit test with store-owned proactive chat (no tool-side `appendAgentLog`). - Quarantine load-sensitive `async-quality-store.pg.test.ts` (5s timeout + leftover psql under full-suite shard load; run 29657633544). ## Test plan - [x] `pnpm --filter @fusion/engine exec vitest run` gating-classifications + executor-prompt + heartbeat expected-tools case - [x] `pnpm --filter @fusion/i18n exec vitest run` i18n-gate-coverage + parity - [x] `pnpm --filter @fusion/dashboard exec vitest run` settings-default-descriptions - [ ] Full Suite all 4 shards green on main after merge <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Settings** * Added clearer, localized help text for report modes and per-action overrides, including inheritance behavior. * Added advanced embedded database connection-limit settings and validation guidance. * **Localization** * Expanded translations for report settings, database tuning, and organization configuration import/export workflows across supported languages. * **Tests & Maintenance** * Updated test coverage and expectations for expanded tools and reporting behavior. * Quarantined a flaky database-related test. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d593d87686 |
feat(FN-8064): make proactive task chat optional
Fusion-Task-Id: FN-8064 |
||
|
|
e8c37b076e |
FN-8277: add in-app agentic reporting
Add guided in-app reporting that safely files or endorses GitHub issues and discussions. - Add report actions, modal UI, API routes, and configurable per-action filing modes. - Scrub report payloads, self-check Help requests, and deduplicate before filing or endorsing. - Extend GitHub discussion support and cover the report pipeline with tests and documentation. Files changed: .changeset/fn-8277-agentic-reports.md | 7 + docs/dashboard-guide.md | 8 + docs/settings-reference.md | 2 + .../core/src/__tests__/settings-parity.test.ts | 9 + packages/core/src/index.gate.ts | 2 +- packages/core/src/index.ts | 2 +- packages/core/src/settings-schema.ts | 2 + packages/core/src/types.ts | 10 + packages/dashboard/app/api.ts | 1 + packages/dashboard/app/api/report.ts | 11 + packages/dashboard/app/components/Header.tsx | 30 +++ .../dashboard/app/components/ReportActionMenu.css | 6 + .../dashboard/app/components/ReportActionMenu.tsx | 22 ++ packages/dashboard/app/components/ReportModal.css | 6 + packages/dashboard/app/components/ReportModal.tsx | 81 ++++++++ .../app/components/__tests__/Header.test.tsx | 7 +- .../components/__tests__/ReportActionMenu.test.tsx | 18 ++ .../app/components/__tests__/ReportModal.test.tsx | 94 +++++++++ .../__tests__/SettingsModal.general.test.tsx | 15 ++ .../settings/sections/GeneralSection.tsx | 31 ++- .../src/__tests__/report-pipeline.test.ts | 127 ++++++++++++ .../dashboard/src/__tests__/report-routes.test.ts | 51 +++++ .../dashboard/src/__tests__/report-scrub.test.ts | 47 +++++ packages/dashboard/src/github.ts | 151 +++++++++++++- packages/dashboard/src/index.ts | 3 + packages/dashboard/src/report-help-selfcheck.ts | 13 ++ packages/dashboard/src/report-pipeline.ts | 225 +++++++++++++++++++++ packages/dashboard/src/report-scrub.ts | 66 ++++++ packages/dashboard/src/routes.ts | 2 + .../dashboard/src/routes/register-report-routes.ts | 118 +++++++++++ 30 files changed, 1156 insertions(+), 11 deletions(-) Fusion-Task-Id: FN-8277 Fusion-Task-Lineage: d50dc1da-7534-4324-ab05-1f8a0ad77c6a Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
2c17fa70ab | feat(postgres): make embedded connection cap configurable | ||
|
|
7c23771433 |
FN-8265: add task follow-up proposal creation
Enable configured ephemeral workers to propose and create follow-up tasks from mailbox messages. - Add persisted task-proposal claim state, migrations, and async messaging APIs. - Register task-proposal creation routes, SSE events, agent tool support, and CLI integration. - Add mailbox creation controls, settings, documentation, localization, and regression coverage. Files changed: .changeset/fn-8265-task-follow-up-policy.md | 7 ++ docs/dashboard-guide.md | 2 +- docs/settings-reference.md | 12 ++- packages/cli/src/extension.ts | 34 ++++--- .../src/__tests__/postgres/sqlite-migrator.test.ts | 14 ++- .../postgres/task-proposal-claim.pg.test.ts | 51 +++++++++++ packages/core/src/async-message-store.ts | 39 ++++++++ packages/core/src/index.gate.ts | 4 +- packages/core/src/index.ts | 4 +- packages/core/src/message-store.ts | 46 ++++++++++ .../core/src/postgres/migrations/0000_initial.sql | 2 + .../migrations/0020_task_proposal_claim.sql | 4 + packages/core/src/postgres/schema-applier.ts | 13 ++- packages/core/src/postgres/schema/project.ts | 3 + packages/core/src/settings-schema.ts | 19 +++- packages/core/src/task-store/async-persistence.ts | 2 +- packages/core/src/task-store/persistence.ts | 4 +- packages/core/src/task-store/serialization.ts | 1 + packages/core/src/task-store/task-creation.ts | 51 +++++++++++ packages/core/src/task-store/task-row-mappers.ts | 2 +- packages/core/src/types.ts | 56 +++++++++++- packages/dashboard/app/api/legacy.ts | 5 + packages/dashboard/app/components/MailboxModal.tsx | 4 + .../app/components/MailboxTaskProposal.css | 3 + .../app/components/MailboxTaskProposal.tsx | 33 +++++++ packages/dashboard/app/components/MailboxView.tsx | 4 + .../__tests__/MailboxTaskProposal.test.tsx | 43 +++++++++ .../app/components/settings/section-keys.ts | 2 +- .../settings/sections/GeneralSection.search.ts | 13 ++- .../settings/sections/GeneralSection.tsx | 22 +++-- .../settings-default-descriptions.test.tsx | 4 +- .../routes/__tests__/task-proposal-routes.test.ts | 99 ++++++++++++++++++++ .../src/routes/register-messaging-scripts.ts | 101 +++++++++++++++++++++ packages/dashboard/src/sse.ts | 7 ++ packages/engine/src/agent-tools.ts | 30 ++++-- packages/engine/src/executor.ts | 9 +- packages/engine/src/step-session-executor.ts | 8 +- packages/i18n/locales/en/app.json | 5 + 38 files changed, 696 insertions(+), 66 deletions(-) Fusion-Task-Id: FN-8265 Fusion-Task-Lineage: 4e864a2f-3485-4a54-8be7-1699b5479a94 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
7bf83bb458 |
fix(desktop,dashboard): open OAuth URLs via activation-free IPC on desktop
window.open after awaiting /auth/login can outlive Chromium's transient user activation and get silently popup-blocked in the desktop app — the OpenAI Codex flow (method select + localhost callback server) crossed that threshold while Anthropic's faster flow usually didn't, so Codex login never opened the browser. Add a shell:openExternal IPC bridge (http/https only), expose it in preload, and route every dashboard auth-URL open through an openExternalUrl helper that falls back to window.open on the web. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
44c784264a |
FN-8237: refine mobile footer quick actions
Make mobile footer quick actions configurable, reorderable, and immediately applied. - Expand the selectable quick-action universe and preserve valid configured items. - Add General settings controls for reordering, adding, and removing footer actions. - Wire updated navigation settings through the dashboard and document the behavior. Files changed: .../fn-8237-mobile-nav-quick-actions-refinement.md | 7 + docs/dashboard-guide.md | 2 +- docs/settings-reference.md | 2 +- .../src/__tests__/mobile-nav-primary-items.test.ts | 17 +- packages/core/src/mobile-nav-primary-items.ts | 44 ++- packages/dashboard/app/App.tsx | 4 +- packages/dashboard/app/components/AppModals.tsx | 2 + packages/dashboard/app/components/MobileNavBar.tsx | 319 ++++----------------- .../dashboard/app/components/SettingsModal.tsx | 4 + .../app/components/__tests__/MobileNavBar.test.tsx | 18 +- .../__tests__/SettingsModal.general.test.tsx | 20 ++ .../dashboard/app/components/dashboard/MainContent.tsx | 2 + .../dashboard/app/components/dashboard/types.ts | 1 + .../settings/sections/GeneralSection.tsx | 75 ++--- packages/dashboard/app/hooks/useAppSettings.ts | 11 + packages/i18n/locales/en/app.json | 5 +- 16 files changed, 220 insertions(+), 313 deletions(-) Fusion-Task-Id: FN-8237 Fusion-Task-Lineage: cff91b30-7ef9-4557-8880-cc71ed74dafb Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
abc2550cc6 |
FN-8216: fix settings description test guard
Keep the Settings default-description coverage aligned with surfaced and global-only settings. - Add missing Notifications and Scheduling description keys to the coverage map - Allowlist the global-only LAN discovery setting so the guard does not require a UI description Files changed: .../sections/__tests__/settings-default-descriptions.test.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) Fusion-Task-Id: FN-8216 Fusion-Task-Lineage: a5449429-c5b2-4d88-915b-26baba3fb60b Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
d6860b5b76 |
FN-8204: add configurable mobile footer quick actions
Add an ordered project setting for mobile footer quick-action destinations. - Render selected destinations as primary mobile tabs and retain omitted choices in More. - Provide settings controls, validation, translations, documentation, and regression coverage. - Add a minor changeset for the published CLI package. Files changed: .changeset/fn-8204-mobile-nav-primary-items.md | 7 + docs/dashboard-guide.md | 4 + docs/settings-reference.md | 4 + .../src/__tests__/mobile-nav-primary-items.test.ts | 23 +++ packages/core/src/index.ts | 9 ++ packages/core/src/mobile-nav-primary-items.ts | 55 +++++++ packages/core/src/settings-schema.ts | 1 + packages/core/src/types.ts | 7 + packages/dashboard/app/App.tsx | 2 + .../mobile-feature-access-regression.test.tsx | 19 +++ packages/dashboard/app/components/MobileNavBar.tsx | 159 +++++---------------- .../app/components/__tests__/MobileNavBar.test.tsx | 16 +++ .../app/components/settings/section-keys.ts | 1 + .../settings/sections/GeneralSection.search.ts | 9 ++ .../settings/sections/GeneralSection.tsx | 45 ++++++ .../settings-default-descriptions.test.tsx | 1 + packages/dashboard/app/hooks/useAppSettings.ts | 5 + packages/i18n/locales/en/app.json | 4 + 18 files changed, 244 insertions(+), 127 deletions(-) Fusion-Task-Id: FN-8204 Fusion-Task-Lineage: 077de4c4-d281-401d-bddd-e5ce8e91d4ab Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
5f70447a62 |
FN-8108: require resolution for triage duplicate tasks
Require explicit resolution for triage-detected duplicate tasks. - Add configurable prompt, keep, and delete handling for explicit duplicate markers. - Surface linked duplicate decisions in task details and scheduling settings. - Preserve task failure provenance and strengthen lifecycle recovery coverage. Files changed: .changeset/blocked-park-survives-graph-teardown.md | 7 + .changeset/failure-provenance-promoter-marker.md | 7 + .changeset/fn-8108-triage-duplicate-resolution.md | 7 + .changeset/veto-progressing-does-not-clear.md | 7 + docs/settings-reference.md | 2 + .../completed-promotion-failure-provenance.test.ts | 31 +++ .../core/src/__tests__/duplicate-intake.test.ts | 11 ++ .../src/completed-promotion-failure-provenance.ts | 38 +++- packages/core/src/duplicate-intake.ts | 29 +++ packages/core/src/index.gate.ts | 1 + packages/core/src/index.ts | 3 +- packages/core/src/settings-schema.ts | 1 + packages/core/src/types.ts | 6 + .../dashboard/app/components/TaskDetailModal.tsx | 38 +++- .../__tests__/TaskDetailModal.rendering.test.tsx | 26 +++ .../settings/sections/SchedulingSection.search.ts | 9 + .../settings/sections/SchedulingSection.tsx | 15 ++ .../__tests__/routes-tasks-near-duplicate.test.ts | 31 +++ .../src/routes/register-task-workflow-routes.ts | 19 ++ .../__tests__/executor-task-done-blocked.test.ts | 212 ++++++++++++++++++++- packages/engine/src/__tests__/merger-ai.test.ts | 56 +++++- .../__tests__/overseer-noop-finalize-veto.test.ts | 64 ++++++- .../explicit-duplicate-marker-sweep.test.ts | 19 +- packages/engine/src/__tests__/self-healing.test.ts | 53 ++++++ .../triage-explicit-duplicate-marker.test.ts | 22 ++- packages/engine/src/executor.ts | 30 +++ packages/engine/src/merger-ai.ts | 5 +- packages/engine/src/overseer-noop-finalize-veto.ts | 148 ++++++++++---- packages/engine/src/self-healing.ts | 29 ++- packages/engine/src/triage.ts | 58 +++--- packages/i18n/locales/en/app.json | 15 +- packages/i18n/src/resources.d.ts | 13 +- 32 files changed, 897 insertions(+), 115 deletions(-) Fusion-Task-Id: FN-8108 Fusion-Task-Lineage: 8e732bad-d418-426e-85e1-903a7f990fba Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
5006e5543c |
FN-8169: group workflow fallback lanes with primary lanes
Keep fallback model lanes adjacent to their primary lanes throughout Settings. - Interleave planning, execution, and validator fallback lanes after their respective primary lanes. - Classify executor fallback settings in the Models group so the row remains visible. - Add ordering coverage for project and workflow Settings surfaces. Files changed: .changeset/fn-8169-group-fallback-lanes.md | 7 ++++ .../app/__tests__/settings-sections.test.tsx | 47 ++++++++++++++++++++++ .../app/components/WorkflowSettingsPanel.tsx | 31 +++++++------- .../__tests__/WorkflowSettingsPanel.test.tsx | 40 ++++++++++++++++++ .../settings/sections/ProjectModelsSection.tsx | 31 +++++++------- .../app/components/workflow-setting-display.ts | 12 ++++++ 6 files changed, 140 insertions(+), 28 deletions(-) Fusion-Task-Id: FN-8169 Fusion-Task-Lineage: 89402b95-1f42-46a7-8ad6-5182dc21f172 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
fd036665ae |
FN-8123: add agent clarification notifications
Add agent clarification notices with ntfy delivery and mailbox support. - Add configurable clarification ntfy topics and notification settings - Route agent clarification requests to ntfy and the planning mailbox - Update planning dialogs, translations, documentation, and regression tests Files changed: .changeset/fn-8123-agent-clarification.md | 7 + docs/dashboard-guide.md | 6 + docs/settings-reference.md | 1 + .../core/src/__tests__/global-settings.test.ts | 11 + packages/core/src/settings-schema.ts | 2 + packages/core/src/types.ts | 6 + .../app/__tests__/settings-save-split.test.ts | 13 ++ packages/dashboard/app/api/legacy.ts | 3 +- .../dashboard/app/components/PlanningModeModal.tsx | 29 ++- .../dashboard/app/components/SettingsModal.tsx | 1 + .../__tests__/PlanningModeModal.initial.test.tsx | 17 +- .../app/components/settings/save-split.ts | 1 + .../settings/sections/NotificationsSection.tsx | 11 + .../src/__tests__/routes-planning.test.ts | 7 +- packages/dashboard/src/planning.ts | 228 ++++++++++++++++----- .../src/routes/register-planning-subtask-routes.ts | 59 +++++- packages/i18n/locales/en/app.json | 4 + packages/i18n/src/resources.d.ts | 4 + 18 files changed, 346 insertions(+), 64 deletions(-) Fusion-Task-Id: FN-8123 Fusion-Task-Lineage: cf397749-01c6-44d6-8d12-8ce7f5627c29 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 --> |
||
|
|
edc64138e0 |
feat(worktrees): task-pinned worktrees under worktreeNaming "task-id" (#2233)
## Summary Adds **task-pinned worktrees** for `worktreeNaming: "task-id"`. Under task-id naming, a task is pinned to exactly one derivable directory `<worktreesDir>/<lowercased-task-id>` (e.g. `.worktrees/fn-7996`) for its entire lifecycle — removing the ambiguity that let stale/foreign `task.worktree` pointers strand a task (the FN-7996 shape). `recycleWorktrees` stays fully functional and is **mutually exclusive** with task-id pinning: the two can't be enabled together. ## Behavior - **Pinned acquisition (`worktreeNaming: "task-id"`, recycling off):** `acquireTaskWorktree` runs **derive → validate → reuse-or-recreate** at the derived path — warm-reuse when the dir is a registered, usable worktree on the task's own branch; otherwise reclaim-in-place (`removeWorktree` + recreate at the SAME path, never a sibling name). A disagreeing `task.worktree` cache self-corrects and emits a new `worktree:pin-rederived` audit event, without consuming worktree-session retries. The recycle pool is never consulted in pinned mode. - **Mutual exclusivity:** enabling both `recycleWorktrees` and `worktreeNaming: "task-id"` is rejected at the settings-write boundary — HTTP 400 at `PUT /settings`, and an `Error` backstop in `store.updateSettings` covering the CLI and every other writer (`assertWorktreeNamingRecycleExclusive`). The runtime also gates pinned mode on `!recycleWorktrees`, so a legacy on-disk config carrying both degrades safely to recycling. - **Settings UI:** the Settings → Worktrees panel enforces the exclusivity bidirectionally — the *Recycle worktrees* toggle is disabled while naming is *Task ID*, and the naming select is disabled while recycling is on — so the conflicting state is unreachable, with help text explaining why. - **Byte-inert for the rest:** `random`/`task-title` naming and the recycle pool (incl. `merger.ts` release) are unchanged; worktrunk-managed layouts bypass pinning. ## Acceptance criteria (from the plan) 1. ✅ Pinned task dispatched N times only ever touches `<worktreesDir>/<task-id>` on its own branch 2. ✅ No code path can hand task A's dir to task B (pool bypassed; path derived from task id) 3. ✅ FN-7996 stale/foreign `task.worktree` self-corrects at next dispatch (`worktree:pin-rederived`) without consuming session retries 4. ✅ Non-pinned modes with `recycleWorktrees: true|false` are byte-identical (existing pool tests pass unchanged) 5. ✅ Stale same-name dir (crash leftover / archive→restore) reclaimed in place, never suffixed 6. ✅ Docs updated (settings-reference, architecture, `worktreeNaming` type doc); changeset (`minor`, `feature`); FNXC comments encode the invariant ## Files - `packages/engine/src/worktree-pinning.ts` — new pure helpers (`isTaskPinnedWorktreeNaming`, `pinnedWorktreePathForTask`) - `packages/engine/src/worktree-acquisition.ts` — pinned branch + branch-match reclaim-in-place - `packages/engine/src/run-audit.ts` — `worktree:pin-rederived` audit type - `packages/core/src/settings-validation.ts` (+ `index.ts`, `task-store/settings-ops.ts`) — mutual-exclusion validator + wiring - `packages/dashboard/src/routes/register-settings-memory-routes.ts` — 400 on conflict - `packages/dashboard/app/components/settings/sections/WorktreesSection.tsx` (+ `packages/i18n/locales/en/app.json`) — bidirectional UI exclusivity - `packages/core/src/types.ts`, `docs/*`, `.changeset/*` ## Verification - New tests: engine `worktree-pinning` (5) + `worktree-acquisition-pinned` (7); core `worktree-naming-recycle-exclusive` (2); dashboard settings-route 400 (3) + WorktreesSection UI exclusivity (3) - Regression sweep green: 194 engine worktree/acquisition/pool/executor/merger-release tests, core settings tests, dashboard i18n/settings-section tests - `tsc --noEmit` clean for `@fusion/core` and `@fusion/engine`; changed source files clean; eslint clean - `pnpm verify:fast` PASS (build + scoped typecheck + boot smoke) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Task ID worktree naming, providing each task with a stable, deterministic worktree directory. * Automatically reuses valid pinned worktrees and recreates stale or conflicting ones at the same path. * Added clear settings controls and validation for incompatible Task ID naming and worktree recycling options. * **Documentation** * Updated worktree architecture, settings reference, and in-app guidance to explain pinned worktrees and configuration constraints. * **Bug Fixes** * Improved recovery from stale or incorrect worktree assignments without consuming session retries. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
d870878a23 |
FN-7998: add executor alternate model escalation
Add opt-in executor escalation after same-model tool-failure retries are exhausted. - Persist escalation settings and one-shot task state across SQLite and PostgreSQL stores. - Retry once on a configured alternate model or scheduler node and audit escalation outcomes. - Expose escalation controls, documentation, translations, migration, and regression coverage. Files changed: .changeset/fn-7998-executor-escalation.md | 7 ++ AGENTS.md | 1 + docs/settings-reference.md | 13 ++- .../core/src/__tests__/settings-defaults.test.ts | 23 ++++- packages/core/src/in-review-stall.ts | 29 ++++++ packages/core/src/index.gate.ts | 3 +- packages/core/src/index.ts | 3 +- packages/core/src/manual-retry-reset.ts | 1 + .../0014_executor_escalation_attempt.sql | 2 + packages/core/src/postgres/schema-applier.ts | 17 ++++ packages/core/src/postgres/schema/project.ts | 1 + packages/core/src/settings-schema.ts | 4 + packages/core/src/store.ts | 2 +- packages/core/src/task-store/persistence.ts | 2 + packages/core/src/task-store/remaining-ops-2.ts | 2 +- packages/core/src/task-store/remaining-ops-3.ts | 2 +- packages/core/src/task-store/remaining-ops-6.ts | 2 +- packages/core/src/task-store/serialization.ts | 1 + packages/core/src/task-store/task-update.ts | 2 + packages/core/src/types.ts | 13 +++ .../dashboard/app/components/SettingsModal.tsx | 12 +++ .../app/components/settings/section-keys.ts | 4 + .../settings/sections/SchedulingSection.search.ts | 36 +++++++ .../settings/sections/SchedulingSection.tsx | 6 ++ .../settings-default-descriptions.test.tsx | 4 + .../__tests__/executor-tool-failure-retry.test.ts | 91 +++++++++++++++++- packages/engine/src/executor.ts | 104 +++++++++++++++++++-- packages/i18n/locales/en/app.json | 8 ++ 28 files changed, 376 insertions(+), 19 deletions(-) Fusion-Task-Id: FN-7998 Fusion-Task-Lineage: bbce767d-c61a-4667-be62-abc0cc54d8be Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |