Commit Graph

1340 Commits

Author SHA1 Message Date
Fusion
caa773cb95 feat(FN-2606): merge fusion/fn-2606 (auto-resolved)
- fix(FN-2606): complete Step 4 — clean up mkdtemp test directories
- test(FN-2606): complete Step 3 — add isolation guard coverage
- feat(FN-2606): complete Step 2 — add engine/dashboard HOME test isolation setup
2026-04-26 13:00:56 -07:00
Fusion
636401a537 feat(FN-2603): merge fusion/fn-2603 (auto-resolved)
- test(FN-2603): update downstream tests for planning label expectations
- test(FN-2603): complete Step 6 — update engine tests for planning terminology
- feat(FN-2603): complete Step 5 — rename self-healing planning APIs
- feat(FN-2603): complete Step 4 — rename needs-respecify status to needs-replan
- feat(FN-2603): complete Step 3 — rename specifying and re-specification text
- feat(FN-2603): complete Step 2 — rename triageLog usages to planLog
- feat(FN-2603): complete Step 1 — rename triage logger to plan logger
- feat(FN-2602): complete Step 7 — add release changeset
- test(FN-2602): complete Step 6 — align migration and schema tests
- test(FN-2602): complete Step 5 — update store status assertions
- feat(FN-2602): complete Step 4 — rename triage prompt labels
- feat(FN-2602): complete Step 3 — add status rename migration
- feat(FN-2602): complete Step 2 — rename respecify status literals
- feat(FN-2602): complete Step 1 — rename triage display labels
2026-04-26 12:45:05 -07:00
gsxdsm
e087f5ec5c feat(FN-2586): merge fusion/fn-2586 2026-04-26 11:49:43 -07:00
Fusion
aca7e50c71 fix(FN-2583): persist token usage on step completion
- Persist task token usage asynchronously whenever a step completes in StepSession execution
- Log non-fatal warnings if per-step token usage persistence fails
- Add executor integration coverage verifying incremental tokenUsage updates before moving tasks to in-review
2026-04-26 09:33:00 -07:00
Fusion
4379922cc8 feat(FN-2585): remove top-level remote access toggle
- Remove the standalone remoteEnabled setting from CLI, core settings defaults/types, and dashboard settings APIs/UI
- Treat remote access as enabled when an active provider is selected and that provider is configured as enabled
- Update remote auth and engine lifecycle checks to gate on provider activation instead of a global flag
- Adjust tests and add a changeset documenting the remote access configuration simplification
2026-04-26 09:19:03 -07:00
Fusion
5a95353272 fix(FN-2525): harden remote access auth and tunnel regression coverage
- Add regression tests across CLI, core, dashboard, and engine for remote access auth, settings parity, and serve/TUI callback wiring
- Expand dashboard route and modal coverage for remote settings/auth flows including node environment behaviors
- Redact provider-switch failure details in tunnel process manager to avoid leaking sensitive provider diagnostics
- Update route registration and engine lifecycle tests to lock in remote-access behavior under real execution paths
2026-04-26 06:35:46 -07:00
Fusion
e5ed696922 feat(FN-2523): add safe restart restore lifecycle diagnostics
- Add ProjectEngine restore lifecycle core to perform safe restarts and surface detailed restore state transitions
- Expose restore diagnostics through remote-access status types and settings/memory route context, including legacy API mapping updates
- Add comprehensive regression coverage for restore lifecycle behavior in engine and dashboard headless remote-access tests
- Document the restore lifecycle contract in architecture/settings docs and include a patch changeset for @runfusion/fusion
2026-04-26 05:18:12 -07:00
Fusion
db9f4ba57e feat(FN-2519): add remote tunnel manager for settings sync
- Add remote-access contracts, provider adapters, and a tunnel process manager with lifecycle handling
- Wire tunnel manager into ProjectEngine startup/shutdown flow and export new remote-access modules
- Update settings modal UX for remote auth URLs, including wrapping and related UI test coverage
- Document tunnel manager behavior and remote settings sync details in architecture, CLI, and settings docs
2026-04-26 02:20:28 -07:00
Fusion
caf538d7d6 fix(FN-2580): persist executor token usage before in-review moves
- Add per-task token usage baselines in TaskExecutor to track agent token deltas safely
- Persist token usage snapshots before every in-progress → in-review transition path, including failures and retries
- Initialize and clear token baselines during execute() lifecycle to avoid cross-run leakage
- Add executor tests covering token usage persistence across completion, failure, and pre-existing usage scenarios
2026-04-26 00:40:47 -07:00
gsxdsm
371f2d8e01 fix(pi-claude-cli): unblock parameterless MCP tool calls in triage
Triage with claude-sonnet-4-6 via pi-claude-cli kept looping on
fn_review_spec calls that were rejected by pi's validator with
"root: must be object". Parameterless MCP tools (schema
{type:"object", properties:{}}) emit zero input_json_delta events,
so partialJson stayed "" and the catch fell through to
finalArgs = "" — a string, which TypeBox's Type.Object({}) rightly
refuses. Default empty partialJson to {} so the call lands.

Also:
- Add a 2-step reminder loop in triage before swapping to the
  fallback planning model — primary models that wrote PROMPT.md
  but forgot fn_review_spec recover from a nudge, no need to pay
  the cold-start tax of a new triage on a different model.
- Inject @runfusion/fusion's own pi extension into dashboard/
  daemon/serve sessions and propagate the path to createFnAgent
  via setHostExtensionPaths so fn_* tools register globally
  without requiring `pi install npm:@runfusion/fusion`.
- Drop the "historical" qualifier from replayed tool labels —
  Claude was reading "TOOL RESULT (historical Read):" as
  "previous session, ignore" and looping on verification.
- Remove subprocess-lifecycle stderr debug logs that landed for
  hang diagnosis — root cause is fixed, the noise can go.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 00:00:49 -07:00
Fusion
0c696f0107 feat(FN-2571): enforce merger aborts through shutdown and git flow
- Add merger abort primitives and track active merge runs for coordinated cancellation
- Abort in-flight merges during engine shutdown and propagate AbortError through fallback catch paths
- Honor abort signals before commit, push, and dependency sync to prevent post-cancel side effects
- Expand merger and project-engine tests to cover abort propagation and merge-abort-on-stop behavior
2026-04-25 21:39:35 -07:00
gsxdsm
e96e29dbf2 feat(FN-2565): merge fusion/fn-2565 2026-04-25 18:08:27 -07:00
Fusion
c5f80a5f6c fix(FN-2546): harden scheduled automation catch-up reliability
- Preserve overdue nextRunAt when schedule updates only touch non-cadence fields
- Recompute nextRunAt only when cadence changes, schedules are re-enabled, or nextRunAt is missing
- Sync memory dreams automation during ProjectEngine startup before CronRunner begins ticking
- Add core/engine regression coverage and a patch changeset for @runfusion/fusion release notes
2026-04-25 17:06:38 -07:00
gsxdsm
b9e084364f fix(engine): register grep/find/ls alongside read/bash/edit/write for coding sessions
pi-coding-agent 0.70's createCodingTools preset only includes read/bash/edit/write,
but pi-claude-cli's tool-mapping translates Claude's Glob→find and Grep→grep.
Triage sessions running through Claude CLI hit "Tool find not found" the moment
the model called Glob and looped on the error.

Compose the built-in set explicitly so every tool referenced by tool-mapping.ts
is registered. Read-only sessions also gain ls (was silently dropped earlier
when readonly was redefined upstream).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 16:34:31 -07:00
Fusion
c57d11a659 feat(FN-2496): add overlap ignore paths support to scheduler settings
- Add overlap-ignore path validation and typed settings support in core schema
- Apply overlap ignore paths in scheduler overlap detection with dedicated engine tests
- Add Settings modal UI and routes handling for overlap ignore paths including path-picker feedback fixes
- Document overlap ignore paths in storage/settings docs and include a changeset for @runfusion/fusion
2026-04-25 15:48:36 -07:00
gsxdsm
818bff7d06 fix(extensions): always prefer vendored @fusion/pi-claude-cli over external installs
When users have an external pi-claude-cli (e.g. a global `npm install -g
pi-claude-cli`, or `npm:pi-claude-cli` in ~/.pi/agent/settings.json packages),
pi's extension discovery loaded the upstream copy and shadowed our fork. The
upstream has a once-and-lock MCP-config bug that throws "Extension runtime not
initialized" during early streamSimple calls and never recovers.

Adds reconcileClaudeCliPaths in @fusion/core, used by both the daemon's
extension assembly and the engine's per-session registerExtensionProviders, to
drop any path with a `pi-claude-cli` segment that isn't our vendored fork and
prepend the vendored path. Engine resolves the fork via require.resolve and
gracefully no-ops when it isn't reachable (e.g. embedded standalone usage).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 15:25:08 -07:00
gsxdsm
bff703196e feat(FN-2501): merge fusion/fn-2501 2026-04-25 14:24:35 -07:00
gsxdsm
c235705d7c fix: kill agent-spawned bash trees and dev servers on dashboard shutdown
TUI quit ('q'/Ctrl+C) bypassed signal handlers via process.exit(0), and
neither shutdown path closed the HTTP server, so server.close()'s
stopAllDevServers() listener never ran. In-flight agent bash commands
(spawned detached for their own pgroup) were also never aborted, so
their subprocess trees — including vitest workers — survived as orphans.

Route the TUI quit through SIGINT so the registered shutdown handler
runs, await stopAllDevServers() in both shutdown paths, and abort
in-flight bash on every active agent session at the start of the
runtime drain so killProcessTree reaches every grandchild.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 14:13:30 -07:00
gsxdsm
a0d99391bb feat(FN-2508): merge fusion/fn-2508 2026-04-25 13:21:02 -07:00
gsxdsm
e15d01ad13 feat(FN-2506): merge fusion/fn-2506 2026-04-25 12:21:33 -07:00
gsxdsm
9425d7c798 feat(FN-2490): merge fusion/fn-2490 2026-04-25 07:59:48 -07:00
Fusion
1d1f1f0da5 feat(FN-2408): merge fusion/fn-2408 2026-04-24 22:54:44 -07:00
gsxdsm
2bc3543e77 fix(self-healing): use slim listTasks in maintenance recover loops
Batch 2 of runMaintenance() runs ~10 recover passes back-to-back, each
calling listTasks({ column: ... }) without slim. On busy boards this
materializes every task's activity log into memory ~10× per cycle,
walking the dashboard heap toward the 8 GB V8 limit until OOM. The
archive pass at line 610 already had this fix; extend it to the in-progress
and in-review recover passes that only read steps / paused / worktree /
mergeDetails / postReviewFixCount — all included in the slim projection.

Triage recovers are left non-slim because hasLatestSpecReviewApproval
scans task.log to find the most recent spec review; the triage column
is small so the memory cost is bounded.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 22:25:57 -07:00
gsxdsm
d13aec45e6 chore: consolidate remaining tests into __tests__/ dirs and refactor mocks
Mostly mechanical cleanup left over from the earlier test-consolidation pass:
- Update import paths to ../../ for mocks now that test files moved deeper
- Simplify mock setup (drop usePluginUiSlots inline mock, etc.)
- Move engine ipc + runtimes tests into __tests__/ subdirs
- Move dashboard utils tests into __tests__/ subdir
- Refresh fusion-plugin-hermes-runtime/dist artifacts

build-exe.test.ts: spawn-import fix from a parallel branch (resolved during
worktree merge of the CSS extraction work).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 19:39:20 -07:00
gsxdsm
bdcb048e20 chore: consolidate test files into __tests__/ dirs and clean stray engine artifacts
- Move all co-located *.test.* files into sibling __tests__/ directories so the
  layout is consistent across packages (159 renames + content-rewrite moves).
  Updates relative imports, vi.mock specifiers, and __dirname/import.meta.url
  path resolutions where tests read fixtures from disk.
- Drop tracked tsc-emit alongside engine .ts sources (auth-storage/logger/
  skill-resolver/context-limit-detector/pi.{js,d.ts,*.map}). These were
  accidentally committed in a merge and the stale pi.js was masking a real
  test-mock vs source mismatch (tests imported "../pi.js" and vite preferred
  the stale build over pi.ts).
- Add packages/engine/.gitignore to block future src/*.{js,d.ts,map}.
- Refactor plugin pi-module seams (openclaw/paperclip/hermes) to ESM-import
  createFnAgent / promptWithFallback / describeModel from @fusion/engine
  instead of require()-ing packages/engine/src/pi.js. Adds @fusion/engine to
  the two plugin package.jsons that were missing it; exports describeModel
  from the engine public API.
- Fix engine test mocks now that they run against current pi.ts: add
  ModelRegistry.create static to mocks in pi.test.ts and pi-create-fn-agent
  .test.ts; switch three boundary-result toEqual assertions to toMatchObject
  so the new content/isError fields don't trip exact-match comparison.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 19:39:20 -07:00
Fusion
bb75e73e24 feat(FN-2339): add configurable ntfy server support
- Add ntfy base URL to global settings schema/types with persistence coverage and regression tests
- Extend dashboard settings API/routes and Settings modal UI to edit and save a custom ntfy server
- Update notifier runtime to use configured ntfy base URL when sending notifications
- Document the new setting and include a changeset for @runfusion/fusion
2026-04-24 19:39:20 -07:00
Fusion
269b13ecb1 feat(FN-2481): align Hermes runtime artifacts and compatibility coverage
- Regenerate fusion-plugin-hermes-runtime build artifacts and manifest metadata for runtime packaging
- Refactor Hermes runtime source into dedicated pi-module, runtime-adapter, and shared type modules
- Expand Hermes and engine plugin-runner tests to validate cross-runtime compatibility behavior
- Update getting-started, settings reference, and Hermes README docs to reflect the current runtime integration guidance
2026-04-24 14:44:04 -07:00
Fusion
ad46484126 feat(engine): allow read of sibling task PROMPT.md/task.json for deps
Agents working on a task that depends on other tasks (e.g. documentation
alignment tasks needing the sibling tasks' specs) were repeatedly
rejected by the worktree boundary when reading .fusion/tasks/FN-NNNN/PROMPT.md,
which also contributed to the malformed-tool-result crash we just fixed.

Add a read-only exception to isWorktreeAllowedPath: the read/glob/grep
tools may access .fusion/tasks/*/PROMPT.md and .fusion/tasks/*/task.json
at the project root. Writes and bash cwd remain restricted.

Update the system-prompt boundary docs (executor.ts) so agents know the
exception exists and stop burning turns re-trying rejected reads.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 14:24:34 -07:00
gsxdsm
5eba97fc80 fix(engine): shape worktree-boundary rejections as proper tool results
wrapToolsWithBoundary returned a bare {ok:false,error} object when an
agent tried to read/write/bash outside the worktree. pi-coding-agent
wraps tool returns into a toolResult message whose content field it
expects to be an array of content blocks; a bare object leaves content
undefined, which later crashes downstream with "Cannot read properties
of undefined (reading 'filter')" — the failure we've been chasing on
FN-2479 and similar.

Return { content:[{type:"text",text:...}], isError:true, ok:false, error:... }
so pi records a valid toolResult block while existing callers that
inspect .ok / .error still work.

Diagnostic evidence: transcript tail for the failing task showed three
consecutive `read` toolResults with content=array(len=0) (normalized
from undefined by our earlier guard) immediately before the assistant
message with stopReason="error".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 14:00:34 -07:00
gsxdsm
92d90f799a diag(engine): log transcript tail when pi state error looks like null access
pi-coding-agent swallows its own exceptions onto session.state.errorMessage
without preserving a stack, so fusion sees only "Cannot read properties
of undefined (reading 'filter')" with no indication which message is
malformed. When promptSessionAndCheck rethrows an error that matches the
generic TypeError shape, dump the last few state.messages (role, content
type, toolName, stopReason) so the offending message can be identified
next run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 13:49:40 -07:00
gsxdsm
1bbc5fcce7 fix(merger,dashboard): handle empty-squash commitSha to keep card and Changes tab in sync
When a branch contained commits already on main (duplicate cherry-picks),
the merger's local squash collapsed to an empty commit. The merger then
recorded that empty commit's SHA on mergeDetails.commitSha. The actual
content landed later on main as a different SHA via PR merge, but the
task kept pointing at the orphaned empty commit.

Symptom: TaskCard showed "N files changed" (falling back to
task.modifiedFiles), but the Changes tab in the modal showed nothing
because the API hit `git diff sha^..sha` on the empty commit and
returned no files.

Two fixes:

1. merger.ts: detect empty squash commits and skip storing commitSha,
   logging clearly. recoverInterruptedMergingTasks → findLandedTaskCommit
   already exists to backfill the right SHA when the real commit lands;
   a missing commitSha is a known fallback path the UI already handles.

2. TaskChangesTab.tsx: when the API returns no files for a done task,
   fall back to task.modifiedFiles (paths only, no patches) with a clear
   note. Mirrors the existing 3-tier fallback in TaskCard.tsx:1090-1124
   so card and modal always agree.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 13:31:34 -07:00
gsxdsm
e788400a7d fix(engine): normalize user message content to survive malformed session state
pi-coding-agent's _getUserMessageText calls content.filter(...) on user
messages; if a message lands in state.messages with content === undefined
(string or array expected), the library throws
"Cannot read properties of undefined (reading 'filter')", which gets
caught and stored on session.state.errorMessage and rethrown without a
stack. Fusion's existing message-content guard already normalized
assistant/toolResult messages — extend it to user messages as well, and
sweep state.messages once when the guard is installed so content loaded
from a session file is repaired before the first event fires.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 13:30:27 -07:00
Fusion
c3a7669f11 fix: restore claude-cli work silently dropped by FN-2370 squash and add audit guardrails
The FN-2370 auto-resolved squash (de5dd6f7d) reverted three commits' worth
of refinements to the claude-cli provider because the branch contained
rebased duplicates of commits already on main. The auto-resolver picked
the older side line-by-line and dropped the newer.

Restored:
- /api/models filter logic (was inverted; emptied every model picker)
- Claude Opus 4.7 catalog entry in pi-claude-cli
- Provider card status text and toast messages (no longer claim a restart
  is needed — the extension is always-loaded now)
- POST /api/auth/claude-cli returns restartRequired: false

Prevention:
- Regression tests on the /api/models useClaudeCli filter
- scripts/audit-squash-merge.mjs flags duplicate-cherry-pick risk and
  touched-file overlap on any squash commit
- AGENTS.md documents the rebase-before-squash rule and requires the
  merging agent to run the audit and triage every flagged item itself

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 13:24:49 -07:00
gsxdsm
1fe1b395be feat(engine): capture stack traces at task-failure catch sites
Add formatError() helper that extracts both message and full stack from
unknown caught values, and use it at every status:"failed" catch site in
executor, agent-heartbeat, and triage. Stack traces now land in
store.logEntry outcome (persisted to task.log/activityLog) and in stderr
logger output, so failures like "Cannot read properties of undefined
(reading 'filter')" can be diagnosed without re-running.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 12:54:13 -07:00
Fusion
89b5b5d68c fix(FN-2462): enforce frozen-lockfile bootstrap across workflows
- Update CI, version, and test-release workflows to use pnpm install --frozen-lockfile consistently.
- Align contributor and settings documentation plus worktree init examples toward deterministic frozen-lockfile bootstrap.
- Clarify TaskExecutor worktree init guidance to distinguish dependency bootstrap failures from missing workspace dist export failures.
- Refresh workflow, executor, restart, and SettingsModal tests (including stable Node Sync tab selection) to assert the new bootstrap contract.
2026-04-24 11:41:10 -07:00
gsxdsm
703581e8ee test(dashboard): drop redundant field-presence tests in SettingsModal
Each of these tests asserts only that a labeled form field exists in
a section. The consolidated "all settings fields are present across
all sections" test (line 497) covers the same space, and the
accompanying payload-roundtrip tests implicitly require the field to
be present before toggling it.

Dropped 7 presence-only tests:
- Recycle worktrees, Show quick chat button, Auto-completion mode
- Include task ID, Auto-resolve conflicts, Add author attribution
- Smart conflict resolution, groupOverlappingFiles type=checkbox

4,317 → 4,206 LOC (-111). 197 tests still passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 10:04:26 -07:00
Fusion
d6c8f1118b fix(FN-2444): polish node dashboard UX and discovery core handling
- Update node management UI components to use shared form/button classes, semantic color tokens, and accessible interactions
- Refine mesh topology rendering and related dashboard tests for improved readability and behavior coverage
- Adjust discovery routes to reuse injected centralCore instances without unnecessary init/close cycles
- Add/extend tests for shared CentralCore discovery flows and model settings scope save behavior
2026-04-24 09:38:16 -07:00
gsxdsm
f3dc07ce24 perf(engine): add per-phase timing logs and monorepo test warning
Instrument worktree init, setup script, workflow steps, verification
commands, and in-merge fix retries with [timing] log entries so task
duration bottlenecks are visible in task logs. Also warn when
inferDefaultTestCommand falls back to `pnpm test` inside a pnpm
workspace — users should set an explicit scoped testCommand to avoid
running the whole monorepo suite on every merge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 08:55:02 -07:00
Fusion
606de5d14c feat(FN-2394): add Fusion reinstall flow for Pi extensions
- Add dashboard route and server handling to reinstall the Fusion Pi extension
- Introduce a client API helper and wire a reinstall action into PiExtensionsManager
- Polish action spacing and document Fusion reinstall recovery in the CLI README
- Expand route, API, and component tests including reinstall refresh stability coverage
- Add a changeset for @runfusion/fusion patch release
2026-04-24 08:55:02 -07:00
Fusion
9d77185079 fix(FN-2384): schedule triage and todo tasks by priority-aware FIFO
- Sort eligible todo tasks in Scheduler by priority first, then createdAt/id for stable FIFO ordering within each tier
- Sort eligible triage tasks using the same priority-aware ordering while preserving existing pause/status/recovery gating
- Add regression tests for scheduler and triage ordering, including blocked/paused/recovery-gated edge cases
- Update architecture docs to describe priority-first task dispatch behavior
2026-04-24 08:55:02 -07:00
Fusion
a07cb53e1d fix(FN-2392): finalize squash merge conflict resolution
- Resolve merge markers across plugin loader, agents view, dashboard server tests, and engine pi session setup
- Keep current cache-busting and hook-guard implementations while removing stale branch-side fragments
- Preserve rate-limit test imports and useAgents-driven loading flow in dashboard agent UI
- Ensure workspace passes required verification gates with pnpm test and pnpm build
2026-04-24 08:54:25 -07:00
Fusion
8a0885ad48 fix(FN-2392): normalize skill-facing tool references to fn_*
- Update Fusion skill docs, prompts, and capability references to use public fn_* tool names consistently
- Align engine system prompts and tool schemas for messaging/task actions with fn_send_message, fn_read_messages, fn_task_* naming
- Refresh related tests across CLI, engine, dashboard, and core to match normalized tool naming and behavior
- Add a patch changeset for @runfusion/fusion describing the skill-tool namespace normalization
2026-04-24 08:54:25 -07:00
Fusion
40e44401f8 fix(FN-2371): preserve log severity in dashboard TUI capture
- Add severity control markers to core and engine structured loggers while keeping info logs on stderr transport
- Parse and strip internal severity markers in dashboard TUI console capture so logger.log entries render with info icons instead of error icons
- Expand dashboard TUI tests to cover captured console severity mapping and structured logger behavior, plus logger unit tests in core/engine
- Add a patch changeset for @runfusion/fusion describing the TUI log severity icon fix
2026-04-24 08:54:25 -07:00
gsxdsm
71129ad968 fix(FN-2316): harden pi session message normalization 2026-04-23 23:38:05 -07:00
gsxdsm
b7233e833d feat(FN-2340): merge fusion/fn-2340 2026-04-23 23:02:38 -07:00
Fusion
1b00478032 feat(prompts): require lint alongside tests and typecheck in agent instructions
Every agent-facing quality gate that used to pair tests with typecheck now
also includes lint. Specifically:

- core/src/types.ts: QA Check skill prompt runs lint, tests, typecheck (was
  tests only) and gates task_done() on all three.
- core/src/agent-prompts.ts + engine/src/reviewer.ts: "Do NOT issue REVISE"
  exclusion list now covers lint as well, so out-of-scope fixes that
  restore lint remain allowed (matches the already-lint-aware completion
  gate text at the top of the same prompts).
- engine/src/executor.ts: task_done() pre-flight checklist adds an explicit
  "if the repo has a lint command, run it and fix failures" bullet, mirrors
  the typecheck bullet, and expands the CRITICAL line from "ALL test
  failures" to "ALL lint, test, and typecheck failures".
- core/src/store.ts: default Step 2 checklist (Testing & Verification) now
  includes Lint and Typecheck alongside "All tests pass".
- cli/src/commands/plugin-scaffold.ts: generated plugin README and the
  "Next steps" CLI output include \`pnpm lint\` between install and test.

Existing prompts that already paired lint with tests+typecheck (the
Completion section, hard quality gates, triage testing requirements) are
unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 23:02:37 -07:00
gsxdsm
88d8a8fa37 refactor: eliminate remaining 15 any warnings and ratchet rule to error
- TaskCard: four catch((err: any) => err.message) promise handlers in
  archive/unarchive/delete/move → catch((err) => getErrorMessage(err)).
- InlineCreateCard + QuickEntryBox: .catch((err: any)) model-load handlers
  → getErrorMessage(err) with existing @fusion/core import.
- TerminalModal: drop (navigator as any).maxTouchPoints — modern lib.dom
  types already expose the property.
- serve.ts: remove unused any annotation on OpenRouter model mapper; the
  array element type is already inferred from json.data.
- pi.js, runtime-resolution.ts, dashboard.ts, serve.ts, dev-server-port-
  detect.ts, devserver-manager.ts: drop now-stale eslint-disable comments
  that the cleanup made redundant.

Fix a prompt-builder regression surfaced by agent's `any` cleanup: toolCall
with a raw string `arguments` field must be preserved verbatim (JSON-quoted)
rather than coerced to `{}`; restores a previously-passing test.

Then promote @typescript-eslint/no-explicit-any from warn → error. Future
new anys must either come with a one-line disable + justification or use a
real type. Workspace is now lint-clean (0 problems).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 23:02:37 -07:00
gsxdsm
3fbb7c47cf refactor: eliminate ~400 no-explicit-any warnings across the workspace
Parallel subagent pass: four typescript-pro agents on non-overlapping scopes.

Patterns applied:
- catch (err: any) { ... err.message ... } → catch (err) { ... getErrorMessage(err) ... }
  using the new @fusion/core helper. Bare catch {} where the error was unused.
- SQLite row types: defined typed XxxRow interfaces per table and cast
  .all()/.get() results via `as unknown as XxxRow[]` (the double cast is
  required because better-sqlite3 returns Record<string, SQLOutputValue>).
- rowToX(row: any) converters: typed argument with the matching row interface.
- Dynamic settings key writes: (settings as Record<string, unknown>)[key].
- React event handlers and setState callbacks: inferred types or concrete
  React.{Mouse,Change,Form}Event<...> where needed.
- pi-claude-cli: local PiMessage / PiContext duck types to avoid re-typing
  pi-ai concrete shapes; typed Claude stream event message fields.

72 files changed, ~400 anys eliminated. Typecheck passes across the workspace.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 23:02:36 -07:00
gsxdsm
200ebfcd39 refactor(dashboard,desktop,engine): remove unused imports, props, and locals
Clears the remaining no-unused-vars warnings across the dashboard app and
server, desktop main, and engine sources. Dead React state destructures are
collapsed to setter-only, unused props are underscore-prefixed to preserve
API shape, and unreferenced catch bindings are dropped. No behaviour change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 23:02:35 -07:00
gsxdsm
e490a8f35a refactor: adapt resource loader and tool wiring to pi-coding-agent 0.70
Three API shifts converge here:

- DefaultResourceLoaderOptions.agentDir is required as of 0.68 (the
  old process.cwd() fallback was removed). Pass getFusionAgentDir()
  explicitly in createFnAgent.

- createAgentSession({ tools }) is now a string[] allowlist of tool
  names, not a Tool[] array (0.68). Our boundary-wrapping via
  wrapToolsWithBoundary produces Tool instances, so we can no longer
  pass them through \`tools\`. Move them into \`customTools\` and
  suppress the built-in defaults with \`noTools: "builtin"\`. The
  wrapped tools keep the same names (read, bash, ...) as the built-ins
  they replace, so no call-site or prompt changes are needed.

- SettingsManager.create's first arg (cwd) became required (was
  optional before). Dashboard routes that previously passed
  \`undefined\` for a process-global settings view now pass
  process.cwd() to match the existing DefaultPackageManager call below.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 23:02:35 -07:00