dbb29d449a4e3867c951dcd54e033459c072bada
2223 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8fa2ad0ecd |
Address PR review feedback (#1996)
- contain fn_artifact_register path payloads: realpath-canonicalized containment before stat/read — relative paths require and must stay inside baseDir, absolute paths allowed only under baseDir or the OS temp dir (deliberate allowance for browser/screenshot tooling); the process.cwd() fallback is gone, symlink escapes rejected - bind task-scoped heartbeat artifact registration to the acquired worktree (baseDir: sessionCwd rebind after acquisition); no-task heartbeat prompt now says to pass absolute temp-dir paths - enforce exactly-one payload source (content/uri/dataBase64/path); content+uri combos are now rejected to match the documented contract - add FNXC rationale comments at both visual-artifact instruction sites in the planning prompts (sync contract with the executor prompt) - media route: statSync -> await stat from node:fs/promises - range tests ride the in-memory MockSocket harness (TestResponse gains binary-safe bodyBuffer; real-TCP helper deleted) and assert the full 206 Content-Range/Content-Length contract for every range form - add PdfViewer coverage (iframe src/title) in DocumentsView tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
a8eafbbb14 |
feat: video, HTML mockup, and PDF artifact support end-to-end
Video was registrable but effectively unusable, and HTML/PDF deliverables had no first-class path from agents to the gallery. - media route now serves HTTP byte ranges (Accept-Ranges, 206 + Content-Range, 416 on unsatisfiable) so <video>/<audio> seeking works and Safari plays media at all - video attachments (mp4/webm/mov, 100MB cap vs 5MB for other types) bridge into the artifact registry like images; multer transport ceiling raised to 100MB with per-type caps enforced in the store - fn_artifact_register path payloads are signature-validated for video (ftyp box / EBML header) and PDF (%PDF- prefix), mirroring images - HTML doc artifacts (mimeType text/html) render as live sandboxed iframe previews by default in the doc viewer, with a Preview/Source toggle and the same FileEditor edit mode - executor/heartbeat/planning prompts and tool descriptions now cover the full type matrix: images, videos, audio, HTML mockups, PDFs, and markdown docs, each with the registration recipe Verified live: range requests (200/206/416) via curl, an ffmpeg-generated mp4 playing to completion in the gallery lightbox, and an interactive HTML mockup rendering in the sandboxed preview. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
9024f3a639 |
feat: agent-created visual artifacts end-to-end + redesigned category gallery with doc editing
Agents could never get screenshots/wireframes/mocks into the Artifacts view:
fn_artifact_register was gated on assignedAgentId (never set in default
ephemeral mode), the only image payload source was inline base64, and no
prompt ever told agents to register visual deliverables.
- always expose fn_artifact_register to executor sessions ("executor" author
fallback), resolve relative paths against the task worktree, and default
taskId to the executing task (heartbeat task lane too)
- add a `path` payload source: file read with 50MB cap, extension MIME
inference, PNG/JPEG/GIF/WebP signature + SVG sniff validation, persisted
through managed artifact storage
- executor/heartbeat/planning prompts + engine-tools reference now instruct
agents to register screenshots, wireframes, mockups, and recordings
- new ArtifactsGallery: Images/Docs/PDFs/Videos/Audio/Other category sections
and filter chips, visual tile grid + lightbox, embedded PDF viewer, audio
player rows, download rows; mobile-responsive down to the 768px breakpoint
- doc artifacts open a full viewer rendered as markdown by default with an
in-place edit mode using the shared CodeMirror FileEditor; persisted via new
GET/PATCH /api/artifacts/:id + TaskStore.updateArtifact and live-refreshed
through the new artifact:updated SSE event
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
23dd0fcdf4 |
test: fix stale refinement-title assertions after FN-7165
Two store-comments refinement tests located the auto-created refinement task by
`title.includes("Refinement")`, but FN-7165 (
|
||
|
|
6e74eedf2d |
fix: make explicit prompt write atomic with the task-row commit (greptile P1)
updateTask now performs the explicit updates.prompt write (and its File Scope validation) BEFORE committing the task row / task.json, instead of after. A failed prompt write (EACCES/EISDIR/disk-full) or invalid File Scope now aborts the whole update atomically rather than leaving the field changes committed with a stale PROMPT.md and returning an error — the write counterpart to the read-resilience guards in getTask/updateStep. Adds an atomicity regression test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
4fd6317aa4 |
fix: accurate error when updateStep can't read prompt-derived steps (greptile P1)
When a task's steps live only in an unreadable PROMPT.md, updateStep still can't resolve step 0 — but it now throws an error naming PROMPT.md as the cause instead of a misleading "task has 0 steps". The operation genuinely cannot succeed (no step data), so this is accurate reporting, not a silent success. The reachable reset path (which derives its loop from getTask's steps) remains unaffected. Adds a test asserting the PROMPT.md-attributed error. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
54960672d7 |
fix: address PR review feedback (surface coverage, list/search guard, Intel Homebrew, serve exit tests)
- store.ts: guard parseStepsFromPrompt in listTasks and searchTasks too, so one unreadable PROMPT.md can't reject the Promise.all and 500 the whole board list/search (CodeRabbit). Matches the getTask fallback. - update-check.ts: isHomebrewInstall now resolves symlinks and matches the real Cellar/opt install roots, fixing Intel-macOS Homebrew detection that only checked /usr/local/Homebrew/ (brew's repo dir) and would have shown npm/sudo guidance instead of `brew upgrade` (CodeRabbit). - task-detail-prompt-resilience.test.ts: extend to assert the invariant across all surfaces — listTasks(slim)/searchTasks, reopen-to-todo moveTask (resetPromptCheckboxes), and deleteTask — not just getTask/updateTask/archive (CodeRabbit; Surface Enumeration rule). - serve.test.ts: add SIGINT/SIGTERM exit-code assertions (130/143) so the serve path's POSIX exit contract can't regress independently of daemon (CodeRabbit). - update-check.test.ts: add Intel-Homebrew remediation test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
93b080102e |
fix: make per-task API resilient to unreadable PROMPT.md; evict archived badge snapshots
#5 root cause (reproduced): getTask — the shared load for the entire per-task API — plus the mutation helpers updateTaskUnlocked, updateStep, readPromptForArchive, and resetPromptCheckboxes all read PROMPT.md unguarded. An unreadable PROMPT.md (root-owned from a prior `sudo` run -> EACCES, PROMPT.md being a directory -> EISDIR, transient FS error) threw and 500'd every per-task operation (GET/DELETE/PATCH/retry/reset/archive) for every task, while the PROMPT.md-free board list and create kept working. These reads are now best-effort: degrade (empty prompt / unsynced steps / skipped cosmetic sync) and log, so a PROMPT.md hiccup can never brick task management. Added a symptom- verification test that forces EISDIR and asserts getTask/updateTask/archiveTask still succeed. #10c: the dashboard badge-snapshot cache only evicted on hard-delete, so archived tasks were re-cached via task:updated and retained for the daemon's lifetime — a slow memory leak. New isBadgeEligibleTask predicate gates the create/update listeners so archived tasks are evicted (matching the startup prime's includeArchived:false). Added a unit test for the invariant. Updates the #5 changeset to cover the real fix; adds a badge-eviction changeset. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
3ef90bc6fe | fix(core): repair chat session thinkingLevel migration | ||
|
|
3d5cc0ada4 |
FN-7795: add thinking-level selectors to fallback model pickers
Adds a per-lane thinking-level selector to every fallback model picker across global, project, and workflow Settings surfaces, wiring them into the existing null-as-delete save paths. - Add inline thinking-level dropdowns to the global Fallback Model, workflow-declared planning/validator fallback lanes, and the project-scoped Title Summarizer fallback picker via CustomModelDropdown's `showThinkingLevel`. - Route `planningFallbackThinkingLevel`/`validatorFallbackThinkingLevel` through workflow settings PATCH and `titleSummarizerFallbackThinkingLevel` through project settings save-split, both with null-as-delete semantics on reset. - Move Title Summarizer fallback out of the workflow-declared model pairs into a dedicated project-scoped lane in ProjectModelsSection so its thinking companion isn't tied to workflow settings. - Update WorkflowSettingsPanel to surface the new fallback thinking companion keys. - Extend/adjust tests (settings-save-split, settings-sections, SettingsModal.models-auth, WorkflowSettingsPanel, core settings-migration) to cover the new selectors and save routing. - Document the fallback thinking-level runtime behavior in docs/settings-reference.md and docs/dashboard-guide.md. - Add a minor changeset describing the new fallback thinking-level selectors. Files changed: .changeset/fn-7795-fallback-thinking-selectors.md | 7 + docs/dashboard-guide.md | 4 +- docs/settings-reference.md | 10 +- packages/core/src/__tests__/settings-migration.test.ts | 14 +- packages/dashboard/app/__tests__/settings-save-split.test.ts | 35 +++++ packages/dashboard/app/__tests__/settings-sections.test.tsx | 163 ++++++++++++++++++++- packages/dashboard/app/components/WorkflowSettingsPanel.tsx | 6 +- packages/dashboard/app/components/__tests__/SettingsModal.models-auth.test.tsx | 11 +- packages/dashboard/app/components/__tests__/WorkflowSettingsPanel.test.tsx | 38 +++++ packages/dashboard/app/components/settings/save-split.ts | 9 +- packages/dashboard/app/components/settings/sections/GlobalModelsSection.tsx | 8 +- packages/dashboard/app/components/settings/sections/ProjectModelsSection.tsx | 58 ++++++-- 12 files changed, 328 insertions(+), 35 deletions(-) Fusion-Task-Id: FN-7795 Fusion-Task-Lineage: ec990d47-defe-4717-993a-56988afe8d7d Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
de67b57517 |
FN-7791: bridge image task attachments into the artifact registry
Image attachments added via TaskStore.addAttachment now surface as first-class image artifacts, reusing the existing artifact listing/SSE/media pipeline instead of duplicating bytes. - addAttachment() registers a URI-only "image" artifact (metadata.source: "attachment") pointing at the already-written attachments/<file> path whenever an image mimeType is attached; registration is best-effort and swallows the archived/soft-deleted-task rejection so addAttachment keeps its always-succeeds contract for valid images. - deleteAttachment() now removes any bridged artifact rows for a filename before deleting the attachment file, so /api/artifacts/:id/media can never point at a deleted attachment. - register-task-workflow-routes.ts's resolveArtifactMediaPath now accepts task-scoped attachments/<file> URIs (in addition to artifacts/<file>) so the media route can stream bridged image-attachment artifacts; task-less artifacts remain restricted to .fusion/artifacts/. - docs/storage.md documents the attachment→artifact bridge behavior and the media route's accepted URI prefixes. - Added a changeset (@runfusion/fusion: minor) describing the user-facing Artifacts view change. - Extended store-attachments and artifacts-route-integration tests to cover the new bridging and deletion behavior. Files changed: .changeset/fn-7791-image-attachments-artifacts.md | 7 +++ docs/storage.md | 3 +- packages/core/src/__tests__/store-attachments.test.ts | 59 +++++++++++++++++++++- packages/core/src/store.ts | 58 ++++++++++++++++++++- packages/dashboard/src/routes/__tests__/artifacts-route-integration.test.ts | 40 +++++++++++++++ packages/dashboard/src/routes/register-task-workflow-routes.ts | 9 +++- 6 files changed, 172 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-7791 Fusion-Task-Lineage: 4df47880-6161-4a8b-933a-2f6fc2fed953 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
84fb5138fc |
FN-7793: add fallback-lane thinking-level settings foundation
Adds the schema/storage foundation for per-fallback-lane thinking-level settings, without any runtime or UI consumption yet. - Add global `fallbackThinkingLevel` default settings key. - Add workflow-declared `planningFallbackThinkingLevel` and `validatorFallbackThinkingLevel` companion settings (enum-validated against THINKING_LEVELS) alongside their existing fallback provider/model pairs. - Add project-scoped `titleSummarizerFallbackThinkingLevel` default settings key. - Extend `GlobalSettings`/`ProjectSettings` TypeScript interfaces with the new optional `ThinkingLevel` fields and FNXC documentation comments. - Update settings-schema `MovedProjectSettingsKey` type to include the new workflow-moved thinking-level keys. - Update `docs/settings-reference.md` and `docs/storage.md` to document the new keys and correct workflow-vs-project scope for the pre-existing planning/validator fallback provider/model keys. - Extend `effective-settings-overlay` and `settings-parity` unit tests to cover the new keys' scope and inheritance behavior. - Add changeset `.changeset/fallback-thinking-levels.md` (minor). Files changed: .changeset/fallback-thinking-levels.md | 7 +++++++ docs/settings-reference.md | 4 ++++ docs/storage.md | 12 +++++++---- .../__tests__/effective-settings-overlay.test.ts | 6 ++++++ .../core/src/__tests__/settings-parity.test.ts | 10 ++++++++++ packages/core/src/builtin-workflow-settings.ts | 23 +++++++++++++++++++++- packages/core/src/settings-schema.ts | 10 +++++++++- packages/core/src/types.ts | 12 +++++++++++ 8 files changed, 78 insertions(+), 6 deletions(-) Fusion-Task-Id: FN-7793 Fusion-Task-Lineage: 0e4bac3e-01d2-4d17-9f0a-af87e8a66eee Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
cc8b1b69e0 |
FN-7786: price analytics from token-usage model snapshot to fix empty estimated cost
Estimated cost on the dashboard could render empty because team/workflow analytics priced rows using the legacy task.modelProvider/modelId columns, which can be NULL even when a durable tokenUsageModelProvider/tokenUsageModelId snapshot exists on the row. - Select tokenUsageModelProvider/tokenUsageModelId alongside the legacy model columns in the team-analytics and workflow-analytics task token queries - Price each row using the token-usage model snapshot first, falling back to the legacy model columns, so cost survives model-resolution drift and empty legacy columns - Add regression coverage in team-analytics, workflow-analytics, and model-pricing tests, plus a dashboard TaskDetailModal summary-tab test asserting estimated cost renders - Add a patch changeset documenting the fix for @runfusion/fusion Files changed: .changeset/fn-7786-estimated-cost.md | 7 +++++ packages/core/src/__tests__/model-pricing.test.ts | 10 +++++++ packages/core/src/__tests__/team-analytics.test.ts | 34 ++++++++++++++++++++-- .../core/src/__tests__/workflow-analytics.test.ts | 33 +++++++++++++++++++-- packages/core/src/team-analytics.ts | 15 ++++++++-- packages/core/src/workflow-analytics.ts | 15 ++++++++-- .../__tests__/TaskDetailModal.summary-tab.test.tsx | 34 ++++++++++++++++++++++ 7 files changed, 140 insertions(+), 8 deletions(-) Fusion-Task-Id: FN-7786 Fusion-Task-Lineage: dab32809-4bb8-42c0-aed0-a0c1131ec641 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
a32307f8f1 |
FN-7778: resolve plugin-contributed skills per requesting project instead of daemon root
Fixes plugin skills silently disappearing when the fn daemon is started outside the project that enabled the contributing plugin, by making skill resolution project-aware instead of scoped to the daemon's root PluginLoader. - getPluginSkills now resolves per requesting rootDir against project_plugin_states rather than the daemon-root PluginLoader scope - Plugins skipped as disabled are now logged at load time for visibility - Wired the new project-aware resolution through dashboard.ts, serve.ts, and daemon.ts CLI commands - Added regression coverage in plugin-loader.test.ts and skills-adapter.test.ts - Documented the project-scoped behavior in docs/PLUGIN_AUTHORING.md and docs/agents.md - Added a patch changeset for @runfusion/fusion Files changed: .changeset/fn-7778-plugin-skills-project-scope.md | 7 +++ docs/PLUGIN_AUTHORING.md | 2 + docs/agents.md | 2 +- packages/cli/src/commands/daemon.ts | 68 +++++++++++++++++++-- packages/cli/src/commands/dashboard.ts | 71 ++++++++++++++++++++-- packages/cli/src/commands/serve.ts | 68 +++++++++++++++++++-- packages/core/src/__tests__/plugin-loader.test.ts | 69 +++++++++++++++++++++ packages/core/src/plugin-loader.ts | 29 ++++++--- .../dashboard/src/__tests__/skills-adapter.test.ts | 29 +++++++++ packages/dashboard/src/skills-adapter.ts | 19 ++++-- 10 files changed, 337 insertions(+), 27 deletions(-) Fusion-Task-Id: FN-7778 Fusion-Task-Lineage: 5d9a8ff2-ed0e-4859-bf9c-a16f715b081d Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
035caca6c8 |
FN-7775: Add thinking level selection to new chat model picker
Adds a per-session thinking-level selector to the new chat model dropdown, persisting the choice through the chat store and engine session options. - Adds thinkingLevel column to chat_sessions with a db migration - Extends chat-store, chat-types, and chat.ts to read/write thinkingLevel - ChatView model selector now exposes a thinking-level control alongside model choice - useChat and register-chat-routes plumb thinkingLevel through session creation/API - engine/src/index.ts passes thinkingLevel as defaultThinkingLevel session option - Adds a minor changeset and updates settings-reference/dashboard-guide docs - Adds/updates unit tests across core and dashboard packages Files changed: .changeset/fn-7775-chat-thinking-level.md | 7 ++ docs/dashboard-guide.md | 1 + docs/settings-reference.md | 2 +- packages/core/src/__tests__/chat-store.test.ts | 15 +++- packages/core/src/__tests__/db-migrate.test.ts | 33 ++++++++ packages/core/src/chat-store.ts | 12 ++- packages/core/src/chat-types.ts | 6 ++ packages/core/src/db.ts | 14 +++- packages/dashboard/app/api/legacy.ts | 2 +- packages/dashboard/app/components/ChatView.tsx | 16 +++- .../__tests__/ChatView.core-interactions.test.tsx | 75 +++++++++++++++--- .../dashboard/app/hooks/__tests__/useChat.test.ts | 17 +++- packages/dashboard/app/hooks/useChat.ts | 6 +- .../dashboard/src/__tests__/chat-manager.test.ts | 90 ++++++++++++++++++++++ packages/dashboard/src/chat.ts | 23 ++++++ .../dashboard/src/routes/register-chat-routes.ts | 25 +++++- packages/engine/src/index.ts | 1 + 17 files changed, 318 insertions(+), 27 deletions(-) Fusion-Task-Id: FN-7775 Fusion-Task-Lineage: e16c7d3b-361e-4908-87ad-10be17a47c47 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
57c3d7ceb8 |
FN-7776: evaluate promptContribution.condition against effective plugin settings
Plugin prompt contributions declared a `condition` field in the SDK, but the host never evaluated it, so gated prompt content always rendered unconditionally. - Add packages/core/src/plugin-prompt-condition.ts implementing a minimal, non-eval `settings["key"] === "value"` / `!==` condition grammar - Wire condition evaluation into plugin-runner.ts / agent-instructions.ts / executor.ts / reviewer.ts / triage.ts / agent-heartbeat.ts so prompt contributions are filtered by effective plugin settings at each call site - Extend plugin-types.ts and core index.ts/index.gate.ts to expose the new evaluator and condition typing - Document the condition grammar in docs/PLUGIN_AUTHORING.md - Add regression tests covering the evaluator and its wiring through plugin-runner and agent-instructions - Add changeset (@runfusion/fusion minor, feature) describing the new gating behavior Files changed: .changeset/fn-7776-prompt-condition.md | 7 ++ docs/PLUGIN_AUTHORING.md | 13 ++- .../src/__tests__/plugin-prompt-condition.test.ts | 90 ++++++++++++++++++++ packages/core/src/index.gate.ts | 6 ++ packages/core/src/index.ts | 6 ++ packages/core/src/plugin-prompt-condition.ts | 51 +++++++++++ packages/core/src/plugin-types.ts | 10 ++- .../src/__tests__/agent-instructions.test.ts | 33 ++++++-- .../engine/src/__tests__/plugin-runner.test.ts | 98 +++++++++++++++++++++- packages/engine/src/agent-heartbeat.ts | 2 +- packages/engine/src/agent-instructions.ts | 6 +- packages/engine/src/executor.ts | 28 +++++-- packages/engine/src/plugin-runner.ts | 64 ++++++++++++-- packages/engine/src/reviewer.ts | 2 +- packages/engine/src/triage.ts | 2 +- packages/plugin-sdk/src/index.ts | 4 + 16 files changed, 385 insertions(+), 37 deletions(-) Fusion-Task-Id: FN-7776 Fusion-Task-Lineage: ba8dcd52-260a-4166-a712-f3dd39b81b15 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
df8ad460af |
FN-7772: add per-lane thinking level for workflow model lanes
Adds a per-workflow-lane thinking-level setting so execution, planning, and review model lanes can each specify their own reasoning-effort/thinking level, threaded through engine phase precedence so lane-specific settings override the workflow default. - Add workflow lane thinking-level settings to builtin workflow settings and settings schema, with new types in core. - Thread lane thinking-level precedence through model-resolution and engine phase execution (executor, step-session-executor, triage, agent-session-helpers). - Surface per-lane thinking-level controls in the dashboard WorkflowSettingsPanel and ProjectModelsSection. - Add/adjust tests for workflow settings, agent-session-helpers, and the dashboard settings panels. - Update settings-reference.md and workflow-steps.md docs. - Add changeset for the new feature (minor). Files changed: .changeset/fn-7772-workflow-lane-thinking.md | 7 ++++ docs/settings-reference.md | 10 ++--- docs/workflow-steps.md | 4 +- .../core/src/__tests__/workflow-settings.test.ts | 41 ++++++++++++++++++++ packages/core/src/builtin-workflow-settings.ts | 27 ++++++++++++- packages/core/src/index.ts | 4 +- packages/core/src/model-resolution.ts | 45 +++++++++++++++++++++- packages/core/src/settings-schema.ts | 3 ++ packages/core/src/types.ts | 6 +++ .../app/components/WorkflowSettingsPanel.tsx | 35 ++++++++++++++--- .../__tests__/SettingsModal.models-auth.test.tsx | 7 +++- .../__tests__/WorkflowSettingsPanel.test.tsx | 31 +++++++++++++++ .../settings/sections/ProjectModelsSection.tsx | 39 ++++++++++++++++--- .../src/__tests__/agent-session-helpers.test.ts | 13 ++++--- .../engine/src/__tests__/executor-test-helpers.ts | 1 + packages/engine/src/agent-session-helpers.ts | 19 +++++---- packages/engine/src/executor.ts | 4 +- packages/engine/src/step-session-executor.ts | 2 +- packages/engine/src/triage.ts | 8 +++- 19 files changed, 264 insertions(+), 42 deletions(-) Fusion-Task-Id: FN-7772 Fusion-Task-Lineage: 70aba3a9-66c2-4bb0-aff9-acabc7b98818 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
235ff4c65e |
FN-7771: add per-node thinking level for workflow model bindings
Adds a per-node thinking-level override (config.thinkingLevel) for workflow IR model bindings so individual workflow nodes can set reasoning effort independently of the global default. - Extend workflow-ir types/schema and workflow-steps-to-ir conversion to carry config.thinkingLevel per node - Wire thinkingLevel through executor and step-session-executor so the engine applies the per-node override during model calls - Add a thinking-level control to WorkflowNodeEditor for authoring per-node overrides in the dashboard - Add/extend tests covering IR round-trip, steps-to-ir conversion, executor model binding, and the WorkflowNodeEditor UI - Document the new setting in docs/workflow-steps.md - Add changeset for @runfusion/fusion (minor) Files changed: .changeset/fn-7771-workflow-node-thinking.md | 7 +++ docs/workflow-steps.md | 10 ++- packages/core/src/__tests__/workflow-ir.test.ts | 42 +++++++++++++ .../src/__tests__/workflow-steps-to-ir.test.ts | 15 +++++ packages/core/src/store.ts | 1 + packages/core/src/types.ts | 9 +++ packages/core/src/workflow-ir.ts | 21 +++++++ packages/core/src/workflow-steps-to-ir.ts | 5 ++ .../app/components/WorkflowNodeEditor.tsx | 42 ++++++++++++- .../__tests__/WorkflowNodeEditor.test.tsx | 73 ++++++++++++++++++++++ .../engine/src/__tests__/executor-test-helpers.ts | 5 ++ .../__tests__/executor-workflow-step-model.test.ts | 31 +++++++++ .../src/__tests__/workflow-step-review.test.ts | 53 ++++++++++++++++ packages/engine/src/executor.ts | 61 ++++++++++++++++-- packages/engine/src/step-session-executor.ts | 12 +++- packages/engine/src/workflow-node-handlers.ts | 29 ++++++++- 16 files changed, 404 insertions(+), 12 deletions(-) Fusion-Task-Id: FN-7771 Fusion-Task-Lineage: 5dbe3efb-773d-47db-9412-b740eb1d7745 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
5f14a58d3b |
FN-7770: add per-lane thinking-level overrides for project & global model settings
Adds an optional thinking-effort/reasoning override per model lane in Settings (project and global), resolved with precedence task > lane > global default, and reconciles this work with the already-landed FN-7768 inline thinking-level control on CustomModelDropdown (kept the shared shouldShowThinking/thinkingBadgeLabel implementation to avoid duplicating the selector/badge UI). - Add lane thinking-level settings schema fields and runtime precedence (task > lane > global default) in @fusion/core - Wire per-lane thinking selectors into GlobalModelsSection and ProjectModelsSection via CustomModelDropdown's existing showThinkingLevel/thinkingLevel/onThinkingLevelChange/defaultThinkingLevel props - Resolve merger thinking level from the default lane rather than the title-summarizer lane in engine session helpers/executor/merger/triage - Update settings-reference docs and add a minor changeset for the new lane thinking overrides - Add/expand test coverage: settings-parity, store-settings, settings-sections, agent-session-helpers - Add new i18n key models.options.defaultWithLevel across locales Files changed: .changeset/fn-7770-lane-thinking.md | 7 ++ docs/settings-reference.md | 8 ++ .../core/src/__tests__/settings-parity.test.ts | 17 ++++ packages/core/src/__tests__/store-settings.test.ts | 42 +++++++++ packages/core/src/settings-schema.ts | 14 +++ packages/core/src/types.ts | 16 ++++ .../app/__tests__/settings-sections.test.tsx | 100 ++++++++++++++++++--- .../app/components/CustomModelDropdown.css | 1 + .../dashboard/app/components/SettingsModal.tsx | 37 ++++++++ .../settings/sections/GlobalModelsSection.tsx | 9 +- .../settings/sections/ProjectModelsSection.tsx | 12 ++- .../app/components/settings/sections/context.ts | 2 + .../src/__tests__/agent-session-helpers.test.ts | 36 ++++++++ packages/engine/src/agent-session-helpers.ts | 60 +++++++++++++ packages/engine/src/executor.ts | 14 +-- packages/engine/src/merger-ai.ts | 12 ++- packages/engine/src/merger.ts | 12 +-- packages/engine/src/pr-response-run-ops.ts | 4 +- packages/engine/src/step-session-executor.ts | 3 +- packages/engine/src/triage.ts | 5 +- packages/i18n/locales/en/app.json | 3 +- packages/i18n/locales/es/app.json | 3 +- packages/i18n/locales/fr/app.json | 3 +- packages/i18n/locales/ko/app.json | 3 +- packages/i18n/locales/zh-CN/app.json | 3 +- packages/i18n/locales/zh-TW/app.json | 3 +- packages/i18n/src/resources.d.ts | 3 + 27 files changed, 390 insertions(+), 42 deletions(-) Fusion-Task-Id: FN-7770 Fusion-Task-Lineage: 3418c621-ac99-4cd4-a435-9348da03972f Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
18841d76a0 |
FN-7761: fix Grok CLI auth to use logged-in CLI instead of requiring API key
Packaged fn serve/daemon/dashboard hosts previously failed with a misleading missing-API-key error for grok-cli agents even though the operator was already logged in via the Grok CLI. This fixes routing so those hosts eagerly ensure the bundled Grok Runtime plugin is installed/loaded before session creation, and no longer silently falls back to the key-requiring direct endpoint when no key is visible. - Eagerly ensure the bundled fusion-plugin-grok-runtime in serve, daemon, and dashboard commands before loadAllPlugins() so runtime id "grok" is available on fresh installs without manual plugin-settings setup. - agent-session-helpers.ts: deriveGrokRuntimeHintForNoVisibleKey now throws an actionable error (naming both remediations: install/enable the Grok CLI runtime plugin, or set GROK_API_KEY) instead of silently falling through to the key-requiring pi/openai-completions path when the runtime can't be loaded. - Update docs/grok-cli-contract.md to document the FN-7761 packaged-host wiring and new no-silent-fallback behavior. - Add regression tests for the packaged bootstrap behavior and bundled-plugin install path. - Add changeset for @runfusion/fusion (patch, category: fix). Files changed: .changeset/fn-7761-grok-cli-packaged-routing.md | 7 +++++ docs/grok-cli-contract.md | 19 +++++++++---- .../__tests__/grok-runtime-bootstrap.test.ts | 31 ++++++++++++++++++++++ packages/cli/src/commands/daemon.ts | 17 +++++++++++- packages/cli/src/commands/dashboard.ts | 20 +++++++++++++- packages/cli/src/commands/serve.ts | 19 +++++++++++-- .../__tests__/bundled-plugin-install.test.ts | 17 ++++++++++++ .../src/__tests__/grok-runtime-routing.test.ts | 17 ++++++------ packages/engine/src/agent-session-helpers.ts | 15 +++++++++-- 9 files changed, 142 insertions(+), 20 deletions(-) Fusion-Task-Id: FN-7761 Fusion-Task-Lineage: 3be5f054-965c-4e8a-ad91-6e61d4dc4a42 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
fed5d3d951 |
FN-7759: fix GPT-5.6 codex models missing from model dropdown
Ensure GPT-5.6 codex models (luna, sol, terra) actually surface in the codex model picker by validating the openai-codex supplemental merge against the real pi-coding-agent ModelRegistry instead of only a mocked one. - Harden openai-models.ts supplemental merge logic against real ModelRegistry auth filtering, registerProvider full-replacement, and OAuth provider validation - Add @earendil-works/pi-coding-agent devDependency to @fusion/core for real-registry testing - Add regression test (openai-models.test.ts) exercising the real registry path - Extend register-model-routes-openai-codex-supplemental.test.ts dashboard test coverage - Update docs/settings-reference.md - Add changeset fn-7759-codex-gpt-5-6-dropdown.md (patch, fix) Files changed: .changeset/fn-7759-codex-gpt-5-6-dropdown.md | 7 ++ docs/settings-reference.md | 2 +- packages/core/package.json | 1 + packages/core/src/__tests__/openai-models.test.ts | 68 +++++++++++++ packages/core/src/openai-models.ts | 107 ++++++++++++++++----- ...-model-routes-openai-codex-supplemental.test.ts | 77 +++++++++++++-- pnpm-lock.yaml | 68 +++++++++++++ 7 files changed, 300 insertions(+), 30 deletions(-) Fusion-Task-Id: FN-7759 Fusion-Task-Lineage: 4c03838f-b8d8-4f6f-ae55-c3356c1c3176 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
b4b183fcd0 |
FN-7757: add missing openai-codex model pricing entries to fix empty estimated costs
Fixes the dashboard showing empty/dash estimated costs for runs on newer OpenAI Codex models, whose pricing was missing from the static model-pricing table. - Add pricing entries for gpt-5.3-codex-spark, gpt-5.4, gpt-5.4-mini, and gpt-5.5 under the openai-codex provider, sourced from the pinned pi-ai 0.80.5 model catalog. - Correct the previously-guessed gpt-5.6-luna/sol/terra rates to match their actual distinct published rates instead of all sharing the gpt-5.3-codex rate. - Update/add tests across model-pricing, team-analytics, token-analytics, and workflow-analytics to cover the new/corrected pricing entries. - Add dashboard tests (TaskSummaryTab prior attempts, CommandCenter mobile scroll, TokensArea, task-planner chat metrics) verifying costs render correctly instead of falling back to unavailable. - Add a patch changeset documenting the estimated-cost fix. Files changed: $(cat /tmp/diffstat.txt) Fusion-Task-Id: FN-7757 Fusion-Task-Lineage: e0f2e9d5-e922-4878-82d0-40c7d9899fdb Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
f7c6f560c0 |
FN-7753: route grok-cli execution through the grok CLI when no Fusion-visible GROK_API_KEY resolves
Route grok-cli model selections through the grok CLI runtime when no Fusion-visible GROK_API_KEY is available. - Add read-only isGrokApiKeyFusionVisible() in packages/core/src/grok-provider.ts, refactored to share user-settings-file reading with hydrateGrokApiKeyFromUserSettings without mutating process.env or logging key material. - In packages/engine/src/agent-session-helpers.ts, auto-derive the existing "grok" runtimeHint when defaultProvider is grok-cli, no key is Fusion-visible, and the grok plugin runtime is registered; explicit runtime hints and mock/test-mode routing remain unchanged, and the provider-qualified model prefix is stripped before handoff. - Normalize provider-qualified model ids (grok-cli/<id>, grok/<id>) in the grok-runtime plugin's runtime-adapter and CLI stream spawn so the concrete model reaches `grok --model`, with the historical grok/default fallback preserved for the no-model path. - Update docs (grok-cli-contract.md, settings-reference.md, plugin README) and add/extend tests covering the new fallback behavior, model normalization, and CLI streaming. - Add changeset fn-7753-grok-cli-no-key-fallback.md (patch, fix). Files changed: .changeset/fn-7753-grok-cli-no-key-fallback.md | 7 ++ docs/grok-cli-contract.md | 83 ++++++++++------ docs/settings-reference.md | 6 +- .../__tests__/grok-provider-user-settings.test.ts | 46 +++++++++ packages/core/src/grok-provider.ts | 39 +++++++- packages/core/src/index.gate.ts | 1 + packages/core/src/index.ts | 1 + .../src/__tests__/grok-runtime-routing.test.ts | 107 +++++++++++++++++++-- packages/engine/src/agent-session-helpers.ts | 52 +++++++++- plugins/fusion-plugin-grok-runtime/README.md | 46 +++++---- .../src/__tests__/cli-stream.test.ts | 70 ++++++++++++++ .../src/__tests__/runtime-adapter.test.ts | 28 ++++++ .../fusion-plugin-grok-runtime/src/cli-stream.ts | 6 ++ .../src/runtime-adapter.ts | 24 ++++- 14 files changed, 443 insertions(+), 73 deletions(-) Fusion-Task-Id: FN-7753 Fusion-Task-Lineage: 30ef7265-1ba9-47fd-8c4e-87b02f6a1d78 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
eb377ba831 |
FN-7750: gate shared-branch-group auto-merge exemption on live groups
Fixes autoMerge=false being bypassed for engine-created branch-group member tasks whose branch group had already dissolved/finalized. - Add isLiveSharedBranchGroupMemberIntegration(task, group) in @fusion/core, requiring the branch group's status be "open" before the shared-branch-member exemption bypasses the global/task autoMerge:false hold. - Export the new helper from packages/core/src/index.ts and index.gate.ts. - Thread the live-group check through packages/engine/src/project-engine.ts (allowInReviewMergeProcessing, enqueueEligibleInReviewTasks, merge-confirmed fast-path branch routing, and merge handoff paths). - Add TaskExecutor.isLiveSharedBranchGroupMember helper in packages/engine/src/executor.ts and use it in retryable pre-merge remediation, no-op finalize, benign pause-abort classification, and merge-processing gates. - Keep self-healing.ts's solo no-op finalize predicate on the pure branchContext-shape check (isSharedBranchGroupMemberIntegration) intentionally, so stale shared-group members stay excluded from solo finalize regardless of group liveness. - Add regression tests covering the executor and project-engine auto-merge-hold behavior for stale/dissolved branch groups. - Add a patch changeset documenting the fix. Files changed: .../fn-7750-automerge-hold-stale-branch-group.md | 7 ++ packages/core/src/__tests__/task-merge.test.ts | 42 +++++++++-- packages/core/src/index.gate.ts | 1 + packages/core/src/index.ts | 1 + packages/core/src/task-merge.ts | 13 +++- ...cutor-live-branch-group-auto-merge-hold.test.ts | 85 ++++++++++++++++++++++ .../engine/src/__tests__/project-engine.test.ts | 37 +++++++++- packages/engine/src/executor.ts | 22 ++++-- packages/engine/src/project-engine.ts | 32 +++++--- packages/engine/src/self-healing.ts | 1 + 10 files changed, 214 insertions(+), 27 deletions(-) Fusion-Task-Id: FN-7750 Fusion-Task-Lineage: d61f8847-0b09-49b5-b66a-00018c8738bb Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
6a13ad175e |
FN-7732: remove dangling release-authorization UI/i18n/docs scaffolding
Narrative: The triage release-authorization gate itself was already removed in b5b0458; this cleans up the leftover scaffolding it left behind — an unemitted activity type, a dead TaskCard badge/label/CSS, orphaned i18n keys across all 6 locales, and a stale solutions doc — so the codebase no longer references a gate that no longer exists. - Drop the unused `task:release-authorization-required` ActivityEventType and its label/rendering in ActivityFeed.tsx and ActivityLogModal.tsx - Remove the dead `isReleaseAuthorizationHold` badge logic and `.awaiting-release-authorization` CSS class from TaskCard.tsx/TaskCard.css - Simplify TaskDetailModal.tsx comments/logic now that legacy release-authorization holds render as ordinary manual plan-approval holds - Delete orphaned i18n keys `tasks.awaitingReleaseAuthorization` and `taskDetail.plan.releaseAuthorizationHold` across en/es/fr/ko/zh-CN/zh-TW locales and resources.d.ts - Delete the stale docs/solutions/architecture-patterns/release-triage-requires-user-authorization.md doc - Update docs/workflow-steps.md and docs/settings-reference.md to describe the gate as removed (superseded by FN-7732) instead of documenting still-active behavior - Add changeset for @runfusion/fusion (patch/internal) Files changed: .changeset/fn-7732-remove-release-authorization-block.md | 7 +++++ docs/settings-reference.md | 2 +- docs/solutions/architecture-patterns/release-triage-requires-user-authorization.md | 33 ---------------------- docs/workflow-steps.md | 6 ++-- packages/core/src/types.ts | 8 ++++-- packages/dashboard/app/components/ActivityFeed.tsx | 5 ---- packages/dashboard/app/components/ActivityLogModal.tsx | 6 ---- packages/dashboard/app/components/TaskCard.css | 11 -------- packages/dashboard/app/components/TaskCard.tsx | 13 +++------ packages/dashboard/app/components/TaskDetailModal.tsx | 14 +++------ packages/i18n/locales/en/app.json | 3 -- packages/i18n/locales/es/app.json | 5 +--- packages/i18n/locales/fr/app.json | 5 +--- packages/i18n/locales/ko/app.json | 5 +--- packages/i18n/locales/zh-CN/app.json | 5 +--- packages/i18n/locales/zh-TW/app.json | 5 +--- packages/i18n/src/resources.d.ts | 3 -- 17 files changed, 30 insertions(+), 106 deletions(-) Fusion-Task-Id: FN-7732 Fusion-Task-Lineage: d4137bd8-9056-4062-9f2a-c6f5d47295f4 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
f9307904c2 |
FN-7745: add GPT-5.6 codenamed model variants to model selector
Registers the three GPT-5.6 codenamed OpenAI Codex model variants (luna, sol, terra) so they appear in the model picker, since pricing alone did not make them selectable. - Add packages/core/src/openai-models.ts with SUPPLEMENTAL_OPENAI_CODEX_PROVIDER_REGISTRATION and mergeSupplementalOpenAiCodexModels(), mirroring the existing Anthropic supplemental-merge seam; additive and dedupe-safe against the pinned pi-ai catalog - Wire mergeSupplementalOpenAiCodexModels into GET /api/models via packages/dashboard/src/routes/register-model-routes.ts, alongside the existing Anthropic supplemental merge - Export new symbols from packages/core/src/index.ts and packages/core/src/index.gate.ts - Add unit tests for the merge helper (packages/core/src/__tests__/openai-models.test.ts) and the route wiring (packages/dashboard/src/__tests__/register-model-routes-openai-codex-supplemental.test.ts) - Document the new supplemental catalog entries in docs/settings-reference.md - Add changeset .changeset/fn-7745-gpt-5-6-codenamed-model-selector.md (minor, @runfusion/fusion) Files changed: .../fn-7745-gpt-5-6-codenamed-model-selector.md | 7 + docs/settings-reference.md | 2 + packages/core/src/__tests__/openai-models.test.ts | 134 +++++++++++++++++ packages/core/src/index.gate.ts | 9 ++ packages/core/src/index.ts | 9 ++ packages/core/src/openai-models.ts | 166 +++++++++++++++++++++ ...-model-routes-openai-codex-supplemental.test.ts | 143 ++++++++++++++++++ .../dashboard/src/routes/register-model-routes.ts | 10 +- 8 files changed, 479 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-7745 Fusion-Task-Lineage: 74c83182-df81-4606-a4dc-0da3ee4cae83 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
0e90578122 |
FN-7737: Add file_scope agent permission category with default allow disposition
Introduces a new file_scope sensitive-action category to the agent permission policy model so file-scope-related FN tools are classified and gated distinctly from other categories, defaulting to allowed under the grant-all preset. - Add file_scope to AGENT_PERMISSION_POLICY_ACTION_CATEGORIES in @fusion/core types - Classify FILE_SCOPE_FN_TOOLS in both agent-action-gate and permanent-agent-gating with a uniform preset disposition (no review_gate_bypass-style override) - Update AgentDetailView and AgentPermissionPolicyEditor to surface the new category in the dashboard UI - Add/extend unit tests across core, engine, and dashboard packages covering the new category's resolution, gating, and UI rendering - Update docs/agents.md and docs/settings-reference.md to document the new permission category - Regenerate i18n locale strings (en/es/fr/ko/zh-CN/zh-TW) and resources.d.ts for the new category labels - Add changeset for @runfusion/fusion (minor) describing the new File Scope permission category Files changed: .../fn-7737-file-scope-permission-category.md | 7 + docs/agents.md | 10 +- docs/settings-reference.md | 8 +- .../agent-permission-policy-resolution.test.ts | 13 + .../src/__tests__/agent-permission-policy.test.ts | 45 +++ packages/core/src/types.ts | 7 + .../dashboard/app/components/AgentDetailView.tsx | 2 + .../app/components/AgentPermissionPolicyEditor.tsx | 8 + .../__tests__/AgentPermissionPolicyEditor.test.tsx | 37 +++ .../engine/src/__tests__/agent-action-gate.test.ts | 46 +++ .../src/__tests__/gating-classifications.test.ts | 67 +++++ .../src/__tests__/permanent-agent-gating.test.ts | 41 +++ packages/engine/src/agent-action-gate.ts | 7 + packages/engine/src/gating-classifications.ts | 6 + packages/engine/src/permanent-agent-gating.ts | 6 + packages/i18n/locales/en/app.json | 4 + packages/i18n/locales/es/app.json | 4 + packages/i18n/locales/fr/app.json | 4 + packages/i18n/locales/ko/app.json | 4 + packages/i18n/locales/zh-CN/app.json | 4 + packages/i18n/locales/zh-TW/app.json | 4 + packages/i18n/src/resources.d.ts | 310 +++++++++++++++------ 22 files changed, 550 insertions(+), 94 deletions(-) Fusion-Task-Id: FN-7737 Fusion-Task-Lineage: 7b161fb3-7dd9-4860-aa4d-0cb35f38ea5b Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
2ff8e2e13e |
FN-7743: detect and recover stalled in-progress executor tasks in overseer
Fix the planner overseer's executor-stage stall detection so hung in-progress tasks get unstuck instead of being reported as progressing forever. - Add configurable stuck-detection: the executor-stage overseer observation now emits signal: "stuck" once an in-progress task has been inactive past a new plannerOverseerExecutorStuckAfterMs threshold, feeding the existing decidePlannerRecovery -> bounded inject_guidance recovery path. - Register the new plannerOverseerExecutorStuckAfterMs setting in builtin-workflow-settings.ts and export it via core index.ts/index.gate.ts. - Preserve human-control withholds (user-paused / approval-blocked / autoMerge-off) taking precedence over stuck detection. - Add/extend tests covering planner-overseer, planner-recovery-controller, planner-recovery, and builtin-workflow-settings-triage. - Document the new setting in docs/architecture.md and docs/settings-reference.md. - Add changeset fn-7743-overseer-executor-stall.md (patch). Files changed: .changeset/fn-7743-overseer-executor-stall.md | 7 + docs/architecture.md | 31 +++++ docs/settings-reference.md | 3 +- .../builtin-workflow-settings-triage.test.ts | 22 ++++ .../core/src/__tests__/planner-recovery.test.ts | 12 ++ packages/core/src/builtin-workflow-settings.ts | 26 ++++ packages/core/src/index.gate.ts | 1 + packages/core/src/index.ts | 1 + .../engine/src/__tests__/planner-overseer.test.ts | 146 +++++++++++++++++++++ .../__tests__/planner-recovery-controller.test.ts | 52 +++++++- packages/engine/src/planner-overseer.ts | 88 ++++++++++++- packages/engine/src/project-engine.ts | 11 +- 12 files changed, 391 insertions(+), 9 deletions(-) Fusion-Task-Id: FN-7743 Fusion-Task-Lineage: 791852a2-5b77-48de-955a-1b3916616dfa Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
9d7b087188 |
FN-7742: bump pi SDK to 0.80.5 and add GPT-5.6 codex-tier model pricing
Updates the @earendil-works/pi SDK dependency and adds pricing entries for the new GPT-5.6 codex-tier models so Command Center reports real cost instead of unavailable. - Bump @earendil-works/pi-ai and @earendil-works/pi-coding-agent from ^0.80.3 to ^0.80.5 in packages/cli, packages/dashboard, packages/engine, and packages/pi-claude-cli - Add openai-codex:gpt-5.6-luna, openai-codex:gpt-5.6-sol, and openai-codex:gpt-5.6-terra pricing entries to model-pricing.ts, mirroring the existing gpt-5.3-codex rate - Bump pricingAsOf to 2026-07-09 - Add regression tests covering the new GPT-5.6 pricing entries - Add changeset (minor) for @runfusion/fusion - Update pnpm-lock.yaml for the dependency bump Files changed: .changeset/fn-7742-pi-sdk-gpt-5-6.md | 7 + packages/cli/package.json | 4 +- packages/core/src/__tests__/model-pricing.test.ts | 14 + packages/core/src/model-pricing.ts | 35 ++- packages/dashboard/package.json | 2 +- packages/engine/package.json | 4 +- packages/pi-claude-cli/package.json | 8 +- pnpm-lock.yaml | 323 ++++++++++++---------- 8 files changed, 246 insertions(+), 151 deletions(-) Fusion-Task-Id: FN-7742 Fusion-Task-Lineage: 2fae3ac1-0877-4d12-b08f-d53d261f2fea Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
bab42b40dd |
FN-7736: prevent recovery/oversight from resuming approval-blocked tasks
Introduces a canonical awaiting-approval pause reason and predicate so recovery and oversight paths treat approval-blocked tasks as terminal-until-approved instead of eligible for early rebound. - Add isTaskBlockedOnApproval predicate and canonical "awaiting-approval" pause reason in @fusion/core (store.ts, task-merge.ts, index.ts/index.gate.ts) - Exclude approval-blocked tasks from paused-scope-decay rebound in self-healing.ts - Keep the planner overseer withholding oversight for approval-blocked tasks (overseer-human-control-policy.ts) - Executor and agent-heartbeat now recognize the approval-blocked state and avoid resuming it - Add regression tests across store-persistence, task-merge, overseer-human-control-policy, paused-scope-decay, and self-healing-paused-abort-recovery - Update docs/architecture.md with the new approval-hold invariant - Add changeset fn-7736-approval-hold.md (patch) Files changed: .changeset/fn-7736-approval-hold.md | 7 +++ docs/architecture.md | 64 ++++++++++++++++++++-- .../core/src/__tests__/store-persistence.test.ts | 18 ++++++ packages/core/src/__tests__/task-merge.test.ts | 34 ++++++++++++ packages/core/src/index.gate.ts | 2 + packages/core/src/index.ts | 2 + packages/core/src/store.ts | 18 +++++- packages/core/src/task-merge.ts | 34 ++++++++++++ .../executor-approval-gate-suspend.test.ts | 5 +- .../src/__tests__/heartbeat-executor.test.ts | 5 +- .../overseer-human-control-policy.test.ts | 44 +++++++++++++++ .../paused-scope-decay.test.ts | 44 +++++++++++++++ .../self-healing-paused-abort-recovery.test.ts | 21 +++++++ packages/engine/src/agent-heartbeat.ts | 8 ++- packages/engine/src/executor.ts | 13 ++++- .../engine/src/overseer-human-control-policy.ts | 45 +++++++++++---- packages/engine/src/self-healing.ts | 12 +++- 17 files changed, 351 insertions(+), 25 deletions(-) Fusion-Task-Id: FN-7736 Fusion-Task-Lineage: 67e05b7f-f621-4f9b-bc01-721ff05d715b Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
e4a59f7269 |
fix: remove over-firing triage release-authorization gate
The triage release-authorization gate (FN-6481/FN-6469) false-flagged any spec that merely mentioned release tooling (scripts/release.mjs, pnpm release) and, because non-user sources made the in-band authorization marker inert, stranded ordinary tasks in awaiting-approval with no exit. - Delete triage-release-authorization.ts + its test and the finalizeApprovedTask parking block; release-class specs now flow through triage normally. - Remove the dashboard approve/reject-plan API guards and UI gating so tasks still carrying the legacy awaitingApprovalReason="release-authorization" hold render as ordinary manual plan-approval holds and can be resolved. - Keep the awaitingApprovalReason field + activity label for backward-compat. - Replace the engine gate with agent instruction (AGENTS.md -> Releasing): agents must never run a release from inside a Fusion task. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
7420abe80e |
FN-7731: add CLI-level lock retry for task show/move commands
Add bounded exponential-backoff retry above the DB layer so `fn task show`/`fn task move` ride out transient SQLite lock contention instead of failing outright or hanging. - Add packages/cli/src/lock-retry.ts: retries a thunk on SQLite lock errors (via @fusion/core's isSqliteLockError) with exponential backoff capped by a wall-clock deadline (default 15s, override via FUSION_CLI_LOCK_RETRY_MS); non-lock errors propagate immediately; raises LockRetryExhaustedError on deadline exhaustion. - Wire lock-retry into packages/cli/src/commands/task.ts for the show/move task-store operations, and close the resolved TaskStore for deterministic exit. - Export isSqliteLockError from packages/core/src/index.ts for CLI reuse. - Add packages/cli/src/commands/__tests__/task-lock-retry.test.ts covering retry/backoff/deadline/error-passthrough behavior; extend task.test.ts. - Document the new behavior/env var in docs/cli-reference.md. - Add changeset (@runfusion/fusion: patch). Files changed: .changeset/fn-7731-task-cmd-lock-retry.md | 7 + docs/cli-reference.md | 9 + .../src/commands/__tests__/task-lock-retry.test.ts | 430 +++++++++++++++++++++ packages/cli/src/commands/__tests__/task.test.ts | 11 + packages/cli/src/commands/task.ts | 117 +++++- packages/cli/src/lock-retry.ts | 117 ++++++ packages/core/src/index.ts | 5 + 7 files changed, 688 insertions(+), 8 deletions(-) Fusion-Task-Id: FN-7731 Fusion-Task-Lineage: 85543164-10d6-4da9-8c3c-a84cd86827aa Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
badb86a965 |
FN-7726: unify fs.watch/poll logic between TaskStore and AgentStore
Extracted the duplicated file-watch-with-polling-fallback logic from TaskStore and AgentStore into a shared controller. - Added packages/core/src/fs-watch-poll-controller.ts implementing a reusable fs.watch + polling-fallback controller - Refactored packages/core/src/store.ts (TaskStore) to use the shared controller instead of its own watch/poll implementation - Refactored packages/core/src/agent-store.ts (AgentStore) to use the shared controller instead of its own watch/poll implementation - Added packages/core/src/__tests__/fs-watch-poll-controller.test.ts covering the new controller's behavior - Updated docs/architecture.md to document the shared controller Files changed: docs/architecture.md | 1 + .../src/__tests__/fs-watch-poll-controller.test.ts | 187 +++++++++++++++++++++ packages/core/src/agent-store.ts | 66 +++----- packages/core/src/fs-watch-poll-controller.ts | 123 ++++++++++++++ packages/core/src/store.ts | 66 +++----- 5 files changed, 364 insertions(+), 79 deletions(-) Fusion-Task-Id: FN-7726 Fusion-Task-Lineage: 69be6dc3-5414-44f2-a3f1-3eb72c2d7391 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
5663067e62 |
FN-7733: remove GitLab browse tools from task_agent_mutation policy examples
Fixes a task_agent_mutation policy example drift: the read-only GitLab browse tools were incorrectly listed as mutation examples even though they were never part of ACTION_GATE_TASK_AGENT_MANAGEMENT_TOOLS and are already classified read-only. - Remove fn_task_browse_gitlab_project_issues, fn_task_browse_gitlab_group_issues, and fn_task_browse_gitlab_merge_requests from AGENT_PERMISSION_POLICY_CATEGORY_TOOL_EXAMPLES.task_agent_mutation in packages/core/src/types.ts, keeping the mutating fn_task_import_gitlab_* variants - Add an FNXC:ToolGovernance comment documenting the invariant and rationale - Add regression coverage asserting the browse tools are excluded from task_agent_mutation examples and are pinned as READONLY_FN_TOOLS Files changed: .../src/__tests__/agent-permission-policy.test.ts | 19 +++++++++++++++++++ packages/core/src/types.ts | 6 ++---- 2 files changed, 21 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-7733 Fusion-Task-Lineage: 3a54faa1-89dd-48bc-978a-4a53f06706be Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
927741a8cf |
FN-7727: persist failed workflow step history across self-healing retries
Preserves prior failed pre-merge review attempts instead of overwriting them when self-healing re-runs a failed workflow step. - Add optional bounded `priorAttempts?: WorkflowStepResult[]` field to `WorkflowStepResult` (capped at `MAX_WORKFLOW_STEP_PRIOR_ATTEMPTS`) - Add shared pure `upsertWorkflowStepResult(existing, incoming, opts?)` helper in `@fusion/core` (packages/core/src/workflow-step-results.ts) - Route the executor graph adapter's `recordWorkflowStepResult` and triage's `recordPlanReviewWorkflowResult` through the new helper so a self-healing recovery re-run snapshots the prior failed/advisory_failure attempt into `priorAttempts` instead of dropping it - Selection logic (self-healing, merge-blocker, progress/timing) is unchanged and still reads only the current entry - Surface prior failed attempts in the TaskDetailModal Summary tab's Workflow results list as a collapsed "previous failed attempts" disclosure - Add core/engine/dashboard tests covering the upsert helper, self-healing recovery snapshotting, and the UI disclosure - Document the behavior in docs/workflow-steps.md - Add changeset for @runfusion/fusion (patch) Files changed: .changeset/fn-7727-persist-failed-step-history.md | 7 ++ docs/workflow-steps.md | 15 +++ .../src/__tests__/workflow-step-results.test.ts | 138 +++++++++++++++++++++ packages/core/src/index.gate.ts | 4 + packages/core/src/index.ts | 4 + packages/core/src/types.ts | 19 +++ packages/core/src/workflow-step-results.ts | 99 +++++++++++++++ .../dashboard/app/components/TaskDetailModal.css | 55 ++++++++ .../dashboard/app/components/TaskSummaryTab.tsx | 42 ++++++- .../TaskSummaryTab.prior-attempts.test.tsx | 89 +++++++++++++ .../clear-terminal-workflow-step-failures.test.ts | 27 ++++ packages/engine/src/__tests__/self-healing.test.ts | 50 ++++++++ ...flow-step-results-self-healing-recovery.test.ts | 115 +++++++++++++++++ packages/engine/src/executor.ts | 29 +++-- packages/engine/src/triage.ts | 14 ++- 15 files changed, 688 insertions(+), 19 deletions(-) Fusion-Task-Id: FN-7727 Fusion-Task-Lineage: 7316fb18-bc92-426d-91f4-b1a4ad41c9b1 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
5a9f354e9a |
FN-7730: fix linked-worktree project-root resolution so board writes don't silently land in the wrong .fusion.db
Board mutations (fn_task_update, CEO override, direct SQL) issued from a pi-extension tool session could silently write into a task's throwaway, never-synced worktree-local .fusion/fusion.db instead of the true project root when git CLI resolution failed (missing git binary, Docker "dubious ownership" refusal, or a non-default settings.worktreesDir). This fixes root-cause resolution and adds regression coverage plus a docs writeup.
- getProjectRootFromGitLinkedWorktree now resolves a linked worktree's project root from git's own on-disk .git/commondir metadata via pure filesystem reads before falling back to the git rev-parse CLI, so writes no longer fall through to a local hydrated copy on git-invocation failure.
- Added getMainRepoRootFromGitFile and resolveCommonGitDirFromWorktreeGitFile helpers with FNXC:Storage comments documenting the FN-7730 root cause and fix rationale.
- Added packages/core/src/__tests__/pi-extensions-write-path-durability.test.ts regression coverage for the write-path durability invariant.
- Extended packages/core/src/__tests__/pi-extensions.test.ts with additional resolution-path assertions.
- Documented the failure mode and fix in docs/storage.md ("Silent board-mutation write loss (FN-7730)").
- Added a patch changeset for @runfusion/fusion describing the user-facing fix.
Files changed:
.changeset/fn-7730-worktree-project-root-resolution.md | 7 ++
docs/storage.md | 54 ++++++++++
packages/core/src/__tests__/pi-extensions-write-path-durability.test.ts | 98 ++++++++++++++++++
packages/core/src/__tests__/pi-extensions.test.ts | 87 +++++++++++++++-
packages/core/src/pi-extensions.ts | 114 +++++++++++++++++++++
5 files changed, 359 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-7730
Fusion-Task-Lineage: 00753a2d-a934-42cf-8fde-0f9b8ad98142
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
|
||
|
|
d44dbaab15 |
FN-7728: add review_gate_bypass RBAC category for fn_task_bypass_review
Introduces a dedicated review_gate_bypass permission-policy category so operators can govern who may bypass a failed pre-merge review gate independently of ordinary task-mutation permissions. - Add review_gate_bypass as a new sensitive-action category in packages/core/src/types.ts, distinct from task_agent_mutation, with fn_task_bypass_review as its sole example tool - Default review_gate_bypass to require-approval even under the unrestricted preset (stricter than the preset's uniform disposition) in packages/core/src/agent-permission-policy.ts, while approval-required/locked-down already cover it uniformly - Classify fn_task_bypass_review into the new category via a shared REVIEW_GATE_BYPASS_FN_TOOLS set in packages/engine/src/gating-classifications.ts, consumed identically by both evaluateAgentActionGate and the permanent-agent gate to prevent path drift - Render the new category as its own row in the dashboard's project-default and per-agent AgentPermissionPolicyEditor, surfaced in AgentDetailView - Update docs/settings-reference.md and add unit tests across core/engine/dashboard covering the new category, its stricter default, and gate-classification alignment - Add changeset (@runfusion/fusion: minor) documenting the new operator-facing permission category Files changed: .changeset/fn-7728-review-gate-bypass-rbac.md | 7 +++ docs/settings-reference.md | 8 +-- .../src/__tests__/agent-permission-policy.test.ts | 54 ++++++++++++++++++- packages/core/src/agent-permission-policy.ts | 12 ++++- packages/core/src/types.ts | 8 +++ .../dashboard/app/components/AgentDetailView.tsx | 2 + .../app/components/AgentPermissionPolicyEditor.tsx | 8 +++ .../__tests__/AgentPermissionPolicyEditor.test.tsx | 5 ++ .../engine/src/__tests__/agent-action-gate.test.ts | 45 ++++++++++++++++ .../src/__tests__/gating-classifications.test.ts | 63 ++++++++++++++++++++++ .../src/__tests__/permanent-agent-gating.test.ts | 41 ++++++++++++++ packages/engine/src/agent-action-gate.ts | 7 +++ packages/engine/src/gating-classifications.ts | 8 ++- packages/engine/src/permanent-agent-gating.ts | 6 +++ 14 files changed, 266 insertions(+), 8 deletions(-) Fusion-Task-Id: FN-7728 Fusion-Task-Lineage: 100c8563-2897-4d53-9546-5c2faa6ab7d8 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
626e00288c |
FN-7720: add operator review-lane bypass for stranded pre-merge review failures
Add a policy-gated review-lane bypass primitive so operators can unstick cards stranded by a failed pre-merge review step (e.g. the no-feedback review-engine defect), without exposing it to agent-driven lanes.
- Add `store.bypassFailedPreMergeReviewStep(id, { reason, actor })` in @fusion/core plus `getLatestFailedPreMergeReviewStep` in task-merge.ts, and new `bypassedBy`/`bypassedAt`/`bypassReason`/`bypassedFromStatus`/`bypassedFromVerdict` fields on `WorkflowStepResult`
- Add operator-only `fn_task_bypass_review` CLI/pi-extension tool; explicitly withheld from executor/reviewer/triage agent tool lists
- Add `POST /tasks/:id/bypass-review` dashboard API route and wire it through `register-task-workflow-routes.ts` and legacy API compatibility layer
- Add dashboard UI affordance (context menu action + task detail modal + right-dock controller wiring) to trigger the bypass with a reason
- Add i18n strings for the bypass action/labels across en/es/fr/ko/zh-CN/zh-TW locales
- Update `gating-classifications.ts` to recognize the bypassed state
- Add unit tests: `store-bypass-review.test.ts`, `task-merge-bypass.test.ts`, extension test coverage, and `useTasks` hook test coverage
- Update docs (`docs/workflow-steps.md`, `docs/dashboard-guide.md`, AGENTS.md, fusion skill references) to describe the new bypass tool/route
- Add changeset `.changeset/fn-7720-review-lane-bypass-primitive.md` (minor)
Files changed:
$(git diff --cached --stat)
Fusion-Task-Id: FN-7720
Fusion-Task-Lineage: 590b020a-ae02-4b51-8189-df8f54bf3044
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
|
||
|
|
e657d3b965 |
FN-7723: add cross-process agent state change notification bus
Adds opt-in cross-process change detection to AgentStore so the engine reacts to CLI-driven agent stop/start mutations promptly instead of waiting for the periodic audit sweep. - AgentStore gains fs.watch-based (with poll fallback) cross-process notification, modeled on TaskStore's existing mechanism - Re-emits existing agent:updated/agent:stateChanged events in the engine process when another process (the fn CLI) mutates an agent row - HeartbeatTriggerScheduler listeners now fire immediately instead of waiting up to 60s for the auditTimerRegistrations sweep; the sweep remains as durable backstop - in-process-runtime.ts wires up the new notification bus - Adds unit tests for agent-store cross-process notifications and heartbeat-scheduler reaction behavior - Updates docs/agents.md and docs/architecture.md - Adds changeset (patch) for @runfusion/fusion Files changed: .changeset/fn-7723-cross-process-agent-notify.md | 7 + docs/agents.md | 1 + docs/architecture.md | 1 + packages/core/src/__tests__/agent-store.test.ts | 177 +++++++++++++++++ packages/core/src/agent-store.ts | 210 ++++++++++++++++++++- .../src/__tests__/heartbeat-scheduler.test.ts | 162 ++++++++++++++++ packages/engine/src/runtimes/in-process-runtime.ts | 30 +++ 7 files changed, 587 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-7723 Fusion-Task-Lineage: d3a7fa05-b40d-4388-8e98-140f9d8861c9 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
b2613b7132 |
FN-7714: honor ~/.grok/user-settings.json apiKey when GROK_API_KEY is unset
Fall back to the Grok CLI's user-settings file for the API key so pi's $GROK_API_KEY provider reference resolves even when the env var isn't exported.
- Add hydrateGrokApiKeyFromUserSettings() in grok-provider.ts, called from registerBuiltInGrokProvider(), which hydrates process.env.GROK_API_KEY from ~/.grok/user-settings.json { apiKey } only when the env var is unset/empty
- Env var always wins; a missing (ENOENT), malformed, or empty-apiKey settings file is fail-soft (no throw, no env mutation), mirroring the grok-runtime probe's fallback behavior
- Add regression tests covering env-precedence, fallback hydration, and fail-soft error paths (grok-provider-user-settings.test.ts)
- Document the fallback in docs/settings-reference.md
- Add a patch changeset for @runfusion/fusion
Files changed:
.changeset/fn-7714-grok-user-settings-apikey.md | 7 +
docs/settings-reference.md | 2 +-
.../__tests__/grok-provider-user-settings.test.ts | 156 +++++++++++++++++++++
packages/core/src/grok-provider.ts | 47 +++++++
4 files changed, 211 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-7714
Fusion-Task-Lineage: 5450b480-3a32-4331-9494-867b84605464
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
|
||
|
|
7dc271027f |
FN-7711: add built-in Grok CLI provider to fix pi model registry lookup
Registers a built-in grok-cli provider so Grok CLI model executions no longer hard-fail with "not found in the pi model registry". - Add packages/core/src/grok-provider.ts: built-in grok-cli provider config (xAI OpenAI-compatible endpoint https://api.x.ai/v1, api openai-completions, apiKey $GROK_API_KEY), mirroring the existing Z.ai provider - Register the provider in packages/engine/src/pi.ts (registerExtensionProviders) and packages/engine/src/provider-registration.ts (seedDashboardProviders) - Wire the provider into CLI entrypoints: packages/cli/src/commands/daemon.ts, dashboard.ts, serve.ts - Export grok-provider from packages/core/src/index.ts and packages/core/src/index.gate.ts - Add unit tests: packages/core/src/__tests__/grok-provider.test.ts, and extend packages/engine/src/__tests__/pi-create-fn-agent.test.ts and provider-registration.test.ts - Document the new provider in docs/settings-reference.md - Add changeset .changeset/fn-7711-grok-cli-model-registry.md (patch, category: fix) Note: Grok CLI binary remains discovery/probe only; GrokRuntimeAdapter streaming is a stub (tracked follow-up). Files changed: .changeset/fn-7711-grok-cli-model-registry.md | 7 + docs/settings-reference.md | 2 + packages/cli/src/commands/daemon.ts | 4 + packages/cli/src/commands/dashboard.ts | 4 + packages/cli/src/commands/serve.ts | 4 + packages/core/src/__tests__/grok-provider.test.ts | 130 ++++++++++++ packages/core/src/grok-provider.ts | 224 +++++++++++++++++++++ packages/core/src/index.gate.ts | 7 + packages/core/src/index.ts | 7 + .../src/__tests__/pi-create-fn-agent.test.ts | 78 ++++++- .../src/__tests__/provider-registration.test.ts | 4 +- packages/engine/src/pi.ts | 4 + packages/engine/src/provider-registration.ts | 4 + 13 files changed, 476 insertions(+), 3 deletions(-) Fusion-Task-Id: FN-7711 Fusion-Task-Lineage: ae90b54f-206e-46fd-8365-b0a4488ceb84 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
66069029a5 |
FN-7709: unref background integrity-check spawn and scheduling timer
Prevents short-lived CLI processes from being held open by background SQLite integrity checks. - unref the sqlite3 child process (and its stdio) spawned by integrityCheckSqliteFileAsync via the shared unrefQmdChildProcess helper, immediately after spawn - unref the 60s scheduling timer in scheduleBackgroundIntegrityCheck so a short-lived caller isn't pinned waiting for a background check it never asked to block on - add regression test coverage (db-integrity-check-unref.test.ts) plus a CLI fixture (db-integrity-check-fixture.mjs) that exercises the fix in a real short-lived process - add changeset documenting the fix and the audit of other spawn sites across @fusion/core/@fusion/engine/@fusion/dashboard/cli confirming they are safe Files changed: .changeset/fn-7709-db-integrity-check-unref.md | 7 ++ .../src/__tests__/db-integrity-check-unref.test.ts | 135 +++++++++++++++++++++ .../fixtures/db-integrity-check-fixture.mjs | 28 +++++ packages/core/src/db.ts | 26 ++++ 4 files changed, 196 insertions(+) Fusion-Task-Id: FN-7709 Fusion-Task-Lineage: 6594aca4-0268-4bba-9a7f-af96d695f1e9 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
dcfbee9ae6 |
FN-7707: reuse hardened unref'd executor in searchWithQmd
Fixes searchWithQmd's inline promisify(execFile) copy that could hold a caller open by reusing the already-hardened, synchronously-unref'd executor established for the background refresh path. - searchWithQmd now calls getDefaultExecFileAsync() instead of building its own promisify(execFile) executor inline - Removes the second un-unref'd execFile executor that could keep a short-lived caller (e.g. one-shot CLI memory search) open up to the awaited timeout - Adds regression test fixture and test coverage (qmd-search-fixture.mjs, qmd-search-unref.test.ts) asserting the shared executor is used - Adds changeset (patch) for @runfusion/fusion Files changed: .changeset/fn-7707-qmd-search-unref.md | 7 + packages/core/src/__tests__/fixtures/qmd-search-fixture.mjs | 30 ++++ packages/core/src/__tests__/qmd-search-unref.test.ts | 166 +++++++++++++++++++++ packages/core/src/memory-backend.ts | 16 +- 4 files changed, 216 insertions(+), 3 deletions(-) Fusion-Task-Id: FN-7707 Fusion-Task-Lineage: 3f9f94a7-5613-4b9a-a3ba-8e9bcdd6b687 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
4fb2bf5c55 |
FN-7706: unref qmd child process so background refresh doesn't block exit
Replaces promisify(execFile) with a hand-rolled spawn()-based qmd executor that unrefs the child process and its stdio, so a fire-and-forget scheduleQmd* memory-index refresh never keeps a short-lived caller process (e.g. CLI) alive; long-lived callers like the dashboard server still see refresh resolve/reject normally. - memory-backend.ts: replace promisify(execFile) qmd exec path with spawn()-based executor that unrefs child + stdio - Add qmd-refresh-unref.test.ts covering unref behavior with a qmd-refresh-fixture.mjs test fixture - Add changeset fn-7706-qmd-unref.md (patch, fix category) Files changed: .changeset/fn-7706-qmd-unref.md | 7 ++ .../src/__tests__/fixtures/qmd-refresh-fixture.mjs | 28 +++++ .../core/src/__tests__/qmd-refresh-unref.test.ts | 136 +++++++++++++++++++++ packages/core/src/memory-backend.ts | 123 ++++++++++++++++++- 4 files changed, 291 insertions(+), 3 deletions(-) Fusion-Task-Id: FN-7706 Fusion-Task-Lineage: 713c23c2-d7da-42c4-b066-31883ba78321 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
081dae0e0f |
FN-7705: Add Grok CLI runtime support as a bundled plugin
Adds a new bundled Grok CLI runtime plugin, wiring it end-to-end into settings, auth routes, model discovery, and the dashboard authentication UI. - New `fusion-plugin-grok-runtime` package with CLI spawn, probe, provider, process-manager, and runtime-adapter modules plus tests - Bundled-plugin install list (CLI + core) updated to auto-install the grok-cli plugin - New `useGrokCli`/`grokCliBinaryPath` settings in `settings-schema.ts` and `types.ts` - Dashboard: `GrokCliProviderCard` component/styles, `ProviderIcon` grok entry, `AuthenticationSection` wiring - New `grok-model-cache.ts` for caching `grok models` discovery results, registered model/auth routes for `/auth/grok-cli` and `/providers/grok-cli/status`, merged into `/api/models` - `runtime-provider-probes.ts` extended with Grok CLI probe/model-discovery delegation - Docs updated (`PLUGIN_AUTHORING.md`, `settings-reference.md`) and changeset added (minor, feature) - Workspace config (`pnpm-workspace.yaml`, `pnpm-lock.yaml`) updated to register the new plugin package Files changed: .changeset/fn-7705-grok-cli-runtime.md | 7 + docs/PLUGIN_AUTHORING.md | 2 +- docs/settings-reference.md | 4 + packages/cli/src/plugins/bundled-plugin-install.ts | 8 + .../cli/src/plugins/staged-bundled-plugin-ids.ts | 1 + packages/cli/vitest.config.ts | 12 + .../core/src/__tests__/grok-cli-settings.test.ts | 34 +++ packages/core/src/index.ts | 1 + .../core/src/plugins/bundled-plugin-install.ts | 10 + packages/core/src/settings-schema.ts | 6 + packages/core/src/types.ts | 9 + packages/dashboard/app/api/legacy.ts | 40 ++++ .../app/components/GrokCliProviderCard.css | 65 ++++++ .../app/components/GrokCliProviderCard.tsx | 204 ++++++++++++++++ packages/dashboard/app/components/ProviderIcon.tsx | 5 + .../__tests__/GrokCliProviderCard.test.tsx | 105 +++++++++ .../app/components/__tests__/ProviderIcon.test.tsx | 8 + .../settings/sections/AuthenticationSection.tsx | 8 +- packages/dashboard/package.json | 1 + .../src/__tests__/grok-model-cache.test.ts | 152 ++++++++++++ .../register-model-routes-grok-cli.test.ts | 214 +++++++++++++++++ .../dashboard/src/__tests__/routes-auth.test.ts | 258 ++++++++++++++++++++- packages/dashboard/src/grok-model-cache.ts | 166 +++++++++++++ packages/dashboard/src/routes.ts | 1 + .../dashboard/src/routes/register-auth-routes.ts | 134 ++++++++++- .../dashboard/src/routes/register-model-routes.ts | 51 ++++ packages/dashboard/src/runtime-provider-probes.ts | 43 ++++ packages/dashboard/vitest.config.ts | 12 + packages/desktop/scripts/workspace-tools.ts | 3 +- plugins/fusion-plugin-grok-runtime/CHANGELOG.md | 7 + plugins/fusion-plugin-grok-runtime/README.md | 54 +++++ plugins/fusion-plugin-grok-runtime/manifest.json | 6 + plugins/fusion-plugin-grok-runtime/package.json | 40 ++++ .../src/__tests__/cli-spawn.test.ts | 103 ++++++++ .../src/__tests__/index.test.ts | 12 + .../src/__tests__/probe.test.ts | 135 +++++++++++ .../src/__tests__/process-manager.test.ts | 96 ++++++++ .../src/__tests__/provider.test.ts | 57 +++++ .../src/__tests__/runtime-adapter.test.ts | 21 ++ .../fusion-plugin-grok-runtime/src/cli-spawn.ts | 50 ++++ plugins/fusion-plugin-grok-runtime/src/index.ts | 74 ++++++ plugins/fusion-plugin-grok-runtime/src/probe.ts | 107 +++++++++ .../src/process-manager.ts | 86 +++++++ plugins/fusion-plugin-grok-runtime/src/provider.ts | 25 ++ .../src/runtime-adapter.ts | 25 ++ plugins/fusion-plugin-grok-runtime/src/types.ts | 12 + plugins/fusion-plugin-grok-runtime/tsconfig.json | 10 + .../fusion-plugin-grok-runtime/vitest.config.ts | 22 ++ pnpm-lock.yaml | 25 ++ pnpm-workspace.yaml | 1 + 50 files changed, 2525 insertions(+), 7 deletions(-) Fusion-Task-Id: FN-7705 Fusion-Task-Lineage: b8194ea8-c773-4199-a52a-b0e4e7347192 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
400f04530c |
chore(release): v0.57.0
Version bump via changesets. |
||
|
|
67cc02750c |
FN-7692: fix misleading merger confirmation copy under active auto-merge
Correct the planner-oversight confirmation messaging so it no longer claims a hard block when the active auto-merge policy will actually advance the merge/pull-request stage unattended. - decidePlannerRecovery accepts an additive, messaging-only `autoMergeWillProceed` flag and picks accurate reason wording (advisory vs. genuine human-approval block vs. neutral/unknown) for merger/pull-request await_confirmation decisions - PlannerRecoveryController.tick threads `allowsAutoMergeProcessing(task, settings)` into decidePlannerRecovery as `autoMergeWillProceed` - project-engine's requestConfirmation steering comment prefix changed from "confirmation required" to neutral "merge checkpoint" so it doesn't contradict the now-accurate reason text - added regression tests in planner-recovery.test.ts and planner-overseer-intervention-wiring.test.ts - added changeset and doc note Files changed: .changeset/fn-7692-merger-confirmation-copy.md | 7 +++ docs/architecture.md | 10 +++- packages/core/src/__tests__/planner-recovery.test.ts | 66 ++++++++++++++++++++++ packages/core/src/planner-recovery.ts | 36 +++++++++++- packages/engine/src/__tests__/planner-overseer-intervention-wiring.test.ts | 37 ++++++++++++ packages/engine/src/planner-recovery-controller.ts | 14 ++++- packages/engine/src/project-engine.ts | 11 +++- 7 files changed, 176 insertions(+), 5 deletions(-) Fusion-Task-Id: FN-7692 Fusion-Task-Lineage: 187684b8-1d24-425d-85d4-627587469908 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
461a4a2711 |
FN-7689: add opt-in Anthropic-style prompt caching for custom providers
Custom providers previously never enabled prompt-cache control, so agent turns re-billed the full context every request even on cache-capable backends. - Add `CustomProvider.anthropicPromptCaching` opt-in flag in @fusion/core types - Set pi-ai `compat.cacheControlFormat="anthropic"` on opted-in models in both registration paths: custom-provider-registry `toProviderConfig` and pi.ts `createFnAgent` - Expose the new toggle in the dashboard CustomProvidersSection UI (with supporting CSS) and thread it through the legacy API + custom-provider routes - Update docs (dashboard-guide, settings-reference) to document the new setting - Add engine test coverage for the caching flag across provider registration and pi-create-fn-agent paths - Add changeset for the fix Files changed: .changeset/fn-7689-custom-provider-prompt-caching.md | 7 + docs/dashboard-guide.md | 1 + docs/settings-reference.md | 2 +- packages/core/src/types.ts | 15 ++ packages/dashboard/app/api/legacy.ts | 12 ++ packages/dashboard/app/components/CustomProvidersSection.css | 24 +++ packages/dashboard/app/components/CustomProvidersSection.tsx | 58 +++++- packages/dashboard/src/routes/register-custom-provider-routes.ts | 16 ++ packages/engine/src/__tests__/pi-create-fn-agent.test.ts | 71 +++++++ packages/engine/src/__tests__/provider-registration.test.ts | 204 ++++++++++++++++++++- packages/engine/src/custom-provider-registry.ts | 71 +++++-- packages/engine/src/pi.ts | 27 ++- 12 files changed, 473 insertions(+), 35 deletions(-) Fusion-Task-Id: FN-7689 Fusion-Task-Lineage: b4f88f32-50da-4651-a546-432a95a1ab1c Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
8ee8f15dc6 |
FN-7675: add agent runtime self-awareness to system prompts
Agents were composing plans (e.g. reboot/wait-and-retry loops) that assumed they could keep acting even after the Fusion platform itself shut down, since prompts never told them they run inside Fusion. This adds a shared, docs-grounded self-awareness preamble prepended to chat, heartbeat, and executor base prompts so agents know their own runtime constraints. - Added FUSION_RUNTIME_SELF_AWARENESS shared preamble in packages/core/src/agent-prompts.ts, exported via packages/core/src/index.ts - Prepended the preamble to the chat system prompt (packages/dashboard/src/chat.ts) - Prepended the preamble to the heartbeat session prompt (packages/engine/src/agent-heartbeat.ts) - Prepended the preamble to the executor base prompt (packages/engine/src/executor.ts) - Updated docs/agents.md and CONCEPTS.md to document the new self-awareness/capability-grounding behavior - Added regression tests across core, dashboard, and engine covering the new prompt content - Added changeset for @runfusion/fusion (minor, fix category) Files changed: .changeset/fn-7675-agent-runtime-self-awareness.md | 7 ++++ CONCEPTS.md | 4 +- docs/agents.md | 17 ++++++++ packages/core/src/__tests__/agent-prompts.test.ts | 41 ++++++++++++++++++++ packages/core/src/agent-prompts.ts | 32 ++++++++++++++- packages/core/src/index.ts | 1 + packages/dashboard/src/__tests__/chat-system-prompt.test.ts | 17 ++++++++ packages/dashboard/src/chat.ts | 6 ++- packages/engine/src/__tests__/executor-prompt.test.ts | 45 ++++++++++++++++++++++ packages/engine/src/__tests__/heartbeat-session-prompt.test.ts | 35 +++++++++++++++++ packages/engine/src/agent-heartbeat.ts | 10 +++-- packages/engine/src/executor.ts | 7 +++- 12 files changed, 213 insertions(+), 9 deletions(-) Fusion-Task-Id: FN-7675 Fusion-Task-Lineage: 126d04a6-2c68-4347-9789-591b274277bf Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
38d883d83e |
fix: surface model-lane drift when a workflow's default model changes (#1958)
## Problem A task's model fields (`modelProvider`/`modelId` and the planning/validator equivalents) are snapshotted once at task-creation time from the workflow's model-lane default in `workflow_settings`. Nothing re-syncs, flags, or surfaces drift when that default is later changed. Concretely: the `builtin:coding` workflow's execution default was `claude-sonnet-4-6` until it was corrected on 2026-07-05. Every task created before that correction stayed permanently, invisibly pinned to the stale model id — 52 tasks were found silently stuck on it. ## Fix - `TaskStore.getModelLaneDrift(workflowId, before, after)` (`packages/core/src/store.ts`): read-only diff over the three model lanes (execution/planning/validator). For any lane whose provider+modelId actually changed, it lists the non-terminal (`column` not `archived`/`done`, not soft-deleted) tasks on that workflow still pinned to the old value. Never mutates `tasks`. - Wired into `PATCH /workflows/:id/setting-values` (`packages/dashboard/src/routes/register-workflow-routes.ts`): captures a `before` snapshot, runs the existing `updateWorkflowSettingValues` unchanged, then attaches an optional `modelDrift` field to the response when a lane change orphans existing tasks. Backward compatible — the field is only present when non-empty. - Operators can act on the surfaced drift via the existing `POST /tasks/batch-update-models` endpoint; this change intentionally does not auto-rewrite any task (avoids touching tasks mid-execution). ## Testing - New tests in `packages/core/src/__tests__/workflow-settings.test.ts` (`TaskStore.getModelLaneDrift`): verifies a task pinned to a changed lane's old value is surfaced, a task already on the new value and a `done`-column task are excluded, and an unrelated/unchanged lane produces no drift entry. - `packages/core`: `npx vitest run src/__tests__/workflow-settings.test.ts` — 24/24 pass. - `npx tsc --noEmit` clean in both `packages/core` and `packages/dashboard`. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Workflow setting updates can now return a lane-based model drift summary (execution, planning, validator) showing task IDs still pinned to the previous model configuration. * The PATCH workflow setting response conditionally includes `modelDrift` when impacted tasks are found. * **Bug Fixes** * Drift detection now compares a consistent “before” snapshot with the updated values to avoid stale pairing. * “No workflow selection” tasks are handled correctly based on the default-workflow behavior. * **Tests** * Added coverage for lane drift across model changes and null-selection inclusion rules. * **Documentation** * Added a release note entry for the change. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |