Commit Graph

4085 Commits

Author SHA1 Message Date
Timothy Laurent
0eea0d02f1 fix(FN-002): fix lint — prefix unused vars with underscore 2026-05-05 15:06:17 -07:00
Timothy Laurent
ac74cb0d6d feat(FN-002): enable browser back-button navigation within the SPA dashboard
Previously the back button left the dashboard page entirely because
useNavigationHistory was only enabled for mobile viewports. Now it's
enabled for all viewports — desktop and mobile — so the browser back
button dismisses modals and reverts view changes within the SPA.

Changes:
- Enable useNavigationHistory for desktop (enabled: true instead of enabled: isMobile)
- Remove all isMobile ? historyAwareHandler : plainHandler ternaries
- Always use navigation-aware handlers (openDetailTask, openSettingsWithNav, etc.)
- Update JSDoc to reflect desktop support
2026-05-05 15:06:17 -07:00
gsxdsm
8a57d3fa96 feat(tui): up/down cycle sections on Main; Enter on Logs releases mouse for text selection
Up/Down arrows now cycle the focused panel on the Main page (mirroring
Left/Right), except on the Logs panel where they keep their existing
role of navigating log entries. Expanding a log entry with Enter now
also disables xterm mouse reporting so the user can click-drag to
select the message text; closing the expanded view restores wheel
scrolling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 15:03:45 -07:00
gsxdsm
61dac2801d fix(cli): declare node-pty as runtime dep so npx runfusion.ai terminal works on clean install
node-pty was previously only present transitively via the workspace
@fusion/dashboard devDependency, which is stripped at publish time. Fresh
users running `npx runfusion.ai` hit a 503 "PTY module could not be loaded"
when opening the dashboard terminal. Tightened the package-config guard so
this regression is caught next time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 15:02:41 -07:00
gsxdsm
b41396de4b chore(release): v0.20.0
Version bump via changesets.
2026-05-05 14:56:34 -07:00
gsxdsm
045f94b98c chore: silence node:sqlite ExperimentalWarning in tests, fix QR mock type
Patch process.emitWarning in the shared vitest setup to drop the
"SQLite is an experimental feature" notice; align the test mock for
getQrPayload with the canonical RemoteQrPayload signature.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:33:26 -07:00
gsxdsm
ca432feaea Update packages/core/src/__tests__/insight-store.test.ts
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-05-05 14:31:53 -07:00
gsxdsm
cfca41dae7 Merge pull request #40 from timothyjlaurent/timothyjlaurent/stuck-spinners
fix: add global spinner animation to prevent stuck loaders
2026-05-05 14:29:38 -07:00
gsxdsm
4677612f23 Merge branch 'main' into timothyjlaurent/broken-insights 2026-05-05 14:18:45 -07:00
gsxdsm
dd09f7c8d6 Merge branch 'main' into timothyjlaurent/stuck-spinners 2026-05-05 14:17:58 -07:00
gsxdsm
d253e01b3f fix: quiet noisy store poll and skill-resolver info logs
Raise checkForChanges slow-poll warn threshold from 100ms to 750ms so
warnings only fire when cycles approach the 1s poll interval, and route
skill-resolver info diagnostics through log() instead of warn().

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:16:30 -07:00
gsxdsm
7d569670c1 test: cover concurrent startRun race in heartbeat recovery sweep
Documents the race called out in code review: when recovery samples a
stale run id and a fresh run is spawned for the same agent before
endHeartbeatRun() lands, only the sampled id is terminated — never the
freshly-spawned run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:14:56 -07:00
gsxdsm
9b01c0a369 fix: auto-recover orphaned heartbeat runs from crashed processes
When the dashboard crashes mid-heartbeat, the agentRuns row is left in
status='active' forever. HeartbeatTriggerScheduler.onTimerTick treats
any active run as "still running" and skips every subsequent tick, so
agents go silent indefinitely (observed: 6+ hours). The existing
in-memory missed-heartbeat watchdog can't help — its trackedAgents map
is wiped on process restart.

SelfHealingManager.recoverStaleHeartbeatRuns now reconciles these on
startup and during periodic maintenance: terminates active runs whose
processPid does not match the current process, has no recorded pid, or
has been active for more than 6 hours.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:13:07 -07:00
Timothy Laurent
b09f7d0602 fix: add listMissions to MissionStore mock to prevent flaky test
The MissionLoop calls this.missionStore.listMissions() during startup
recovery, but the mock TaskStore's getMissionStore() return value didn't
include this method. When the runtime startup sequence raced ahead, it
would hit "listMissions is not a function" — making the test flaky.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 13:55:35 -07:00
Timothy Laurent
8f47e8ddd8 ci: re-trigger checks — flaky in-process-runtime test (unrelated to CSS change)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 13:50:02 -07:00
Fusion
c67e786f48 feat(FN-3498): add self-healing and ownership-aware done-task merge reconci
The merge completes FN-3498 across three steps: adds ownership-aware done-task reconciliation to the merger, prevents branch-missing head SHA pollution during merge operations, and restores workspace typecheck compatibility. Core changes touch the merger (103 lines) and self-healing module (67 lines

Fusion-Task-Id: FN-3498
2026-05-05 13:42:39 -07:00
Fusion
511c0c5442 feat(FN-3502): add comment-triggered retriage when task is in triage status
Merged four commits implementing comment-driven retriage: triage rules now respond to specific comment patterns (Step 1) and surface needs-replan feedback inputs in the UI (Step 2), with documentation for the new behavior and a bug fix restoring workspace typecheck defaults. Changes span the core ta

Fusion-Task-Id: FN-3502
2026-05-05 13:32:10 -07:00
Fusion
7d373286d9 feat(FN-3470): prefer source aliases for runtime plugins and add test artif
Merges FN-3470 in two steps: first, runtime plugins now prefer source path aliases over build artifacts, with hardening tests for vitest alias resolution and plugin view registry updates; second, a new `ensure-test-artifacts.mjs` bootstrap script guarantees required test files exist before test runs

Fusion-Task-Id: FN-3470
2026-05-05 13:25:02 -07:00
Fusion
0aef085f13 feat(FN-3368): tighten research view test coverage and resolve dashboard ty
This merge introduces an eval automation domain store with persistence schema and a plugin dashboard view registry (FN-3512/FN-3513), adds scheduled eval batch architecture documentation (FN-3388), and includes substantial test coverage for Research routes and hooks (FN-3368 steps 1-3). The branch a

Fusion-Task-Id: FN-3368
2026-05-05 13:05:57 -07:00
Timothy Laurent
053ad59d42 fix: suppress pre-existing no-explicit-any lint in chat.ts test mock
The options parameter in __setCreateFnAgent's inline arrow already
uses any to match the module-level let (which has its own suppress
comment). Add the missing eslint-disable-next-line so CI passes.

Unrelated to the spinner fix — pre-existing on main.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 13:03:03 -07:00
Timothy Laurent
06cbb744ff fix(lint): suppress no-explicit-any in chat.ts mock assignment
Pre-existing lint error on main — the `any` cast in __setCreateFnAgent
mirrors the eslint-disable already on the adjacent variable declarations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 12:53:45 -07:00
Timothy Laurent
b0c10849d2 test(insights): add regression test for ensureInsightRunsSchemaCompatibility
Simulates a database where project_insight_runs exists without lifecycle
and cancelledAt columns (the state that caused the original bug), then
verifies that re-opening the database adds the columns and creating a run
succeeds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 12:51:32 -07:00
Fusion
c36d30f517 feat(FN-3388): document scheduled eval batch architecture
Added 3 lines documenting the scheduled eval batch architecture in the architecture docs as part of FN-3388 Step 4.

Fusion-Task-Id: FN-3388
2026-05-05 12:49:01 -07:00
Fusion
0e3eaf063f feat(FN-3512): add eval domain store with persistence schema, plugin dashbo
This merge adds three major features: a new **eval domain store** (`eval-store.ts`, `eval-types.ts`) for AI evaluation data with persistence schema and a `PluginDashboardViewHost` for extensibility; a **plugin dashboard view registry** with navigation integration that lets plugins register custom vi

Fusion-Task-Id: FN-3512
2026-05-05 12:37:25 -07:00
Fusion
30f6381ec0 feat(FN-3513): add eval domain store, plugin dashboard view registry, and G
This merge adds three major features: an eval domain (`eval-store.ts`, `eval-types.ts`) with persistence schema for evaluation data; a plugin dashboard view registry with navigation integration for third-party dashboard extensions; and GitHub source metadata traceability that locks and enforces issu

Fusion-Task-Id: FN-3513
2026-05-05 12:25:50 -07:00
Fusion
d7880c66b0 feat(FN-3157): add plugin dashboard view registry with nav integration
Merged FN-3157 to add a plugin dashboard views system, including a plugin view registry with lazy loading, navigation integration for Header and MobileNavBar, a usePluginDashboardViews hook with cache and refetch support, and tests covering the no-loader path. Also added documentation in `docs/PLUGI

Fusion-Task-Id: FN-3157
2026-05-05 12:14:20 -07:00
Fusion
c87c9e2e1f feat(FN-3387): add eval domain with store and persistence schema
Introduced a new evaluation persistence layer in `@fusion/core` with domain contracts, SQLite-backed storage APIs, and retention/window-rollup support, wired through the core store and documented in the architecture and storage docs.

Fusion-Task-Id: FN-3387
2026-05-05 12:01:53 -07:00
Timothy Laurent
c68bfff4f5 fix: move spinner keyframes outside :root selector block
The @keyframes spin and .animate-spin rules were incorrectly placed
inside the first :root {} block, which is invalid CSS — @keyframes
cannot be nested inside selector blocks. Browsers silently ignore
them in that position, so the spinners would still get stuck on pages
without component CSS loaded.

Moves the rules to the stylesheet top level between the two :root
blocks. Also fixes the mobile-css regression test that parses the
first :root block with a non-greedy regex.

Addresses review feedback from Greptile (P1) and CodeRabbit on PR #40.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 12:01:14 -07:00
Timothy Laurent
74821803c9 fix: add global spinner animation to prevent stuck loaders
The `.animate-spin` CSS utility class and `@keyframes spin` were only
defined in TaskCard.css but used by 25+ components (~60 instances).
On pages without a TaskCard rendered, the class didn't exist in the
stylesheet, causing all spinners to appear frozen.

Moves both the keyframes and utility class to the global styles.css
so they're available from the first paint regardless of which
components are loaded.

Closes Runfusion/Fusion#39

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 12:01:14 -07:00
Fusion
b4bc105726 feat(FN-3481): clean up ephemeral runtimes and spawned agents immediately o
Merges three major changesets: ephemeral agent cleanup for FN-3481 (runtime and spawned agent teardown), a fix for planning-mode refine continuation flow (FN-3209) plus a new local startup script, and chat SSE broadcast isolation with QuickChat backend unification. Key components affected include th

Fusion-Task-Id: FN-3481
2026-05-05 11:43:33 -07:00
Fusion
f2accb736f feat(FN-3209): fix refine continuation flow in planning mode and add local
Merges fixes for the planning refine continuation flow (FN-3209) alongside a new local startup script for development environments. The changes include updates to `PlanningModeModal.tsx`, new and updated tests for the planning system, route handler improvements in `chat.ts` and `planning.ts`, and do

Fusion-Task-Id: FN-3209
2026-05-05 11:32:05 -07:00
Timothy Laurent
46c6b7a59a fix(insights): add ensureInsightRunsSchemaCompatibility for missing lifecycle column
Databases already at schema v59+ when the lifecycle column was added never
re-ran the v59 migration, causing "no column named lifecycle" errors on
insight generation. Adds an unconditional compatibility check following the
existing ensureRoutinesSchemaCompatibility pattern.

Fixes #42

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 11:31:21 -07:00
gsxdsm
1f50be85a1 Merge pull request #38 from Runfusion/codex/local-start-script
[codex] Add local startup script
2026-05-05 11:10:14 -07:00
gsxdsm
b4a2e7a486 feat(chat): unify QuickChat backend path and consolidate render toggle
Backend
- chat.ts now routes both regular chat and QuickChat through
  createResolvedAgentSession instead of branching to createFnAgent for
  the no-runtime-hint case. This removes the divergent path where
  pi-ai's cleanupSessionResources(sessionId) could tear down resources
  the next generation depends on.
- sendMessage's finally only disposes the agent if it still owns the
  activeGenerations slot. A newer generation that has pre-empted us
  cleans up its own agent in its own finally — disposing here would
  yank the underlying CLI process out from under it.
- __setCreateFnAgent test helper now mirrors its mock into the
  createResolvedAgentSession slot so existing test setups still work
  after the unification.

Frontend
- Extract createChatStreamHandlers (RAF coalescing, accumulators,
  tool-call dedup, fallback handling) — useChat and useQuickChat were
  duplicating ~85 LOC each. Both now compose the shared factory.
- Move shared chat types into chatTypes.ts. The hooks re-export them
  for backward compatibility with existing consumers.
- Removed per-message Markdown/plain-text eye toggles. A single
  thread-level toggle in the chat header now flips every assistant
  bubble (including the streaming one) between rendered Markdown and
  plain text.
- Model-only chats hide the per-message agent identity row entirely;
  the model name is already in the thread header.

Tests
- Updated ChatView tests to reflect the new render-toggle contract
  (single header toggle drives all bubbles) and the model-only avatar
  suppression.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 11:04:48 -07:00
Aron Prins
d53a1515e7 fix(FN-000): address local startup review feedback 2026-05-05 19:57:50 +02:00
Aron Prins
53a7877883 feat(FN-000): add local startup script 2026-05-05 19:24:30 +02:00
gsxdsm
a77932205c fix(chat): revert cancelGeneration-on-disconnect
req.on("close") was firing for healthy SSE connections in this
Node/Express setup, which cancelled the in-flight agent the client was
still listening to and made even msg #1 fail after a fresh reload.
Keep the beginGeneration (no dispose) change from the same commit —
that one's correct.
2026-05-05 09:08:51 -07:00
gsxdsm
b85743db84 fix(chat): cancel orphaned generation on client disconnect
Closing the QuickChat browser tab mid-response left the backend agent
running with no listener. The `activeGenerations` slot persisted and the
next message's freshly-opened CLI SessionManager raced against the
lingering agent on the same session file, so the model produced no
output for the new prompt.

- POST /chat/sessions/:id/messages now calls cancelGeneration on
  req.on("close") if the response hasn't ended yet, so disconnects stop
  the agent promptly.
- beginGeneration only aborts the prior controller; it no longer
  disposes the prior agent. Disposing pre-emptively could yank the CLI
  process out from under the new generation's session opened on the
  same file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 09:04:14 -07:00
gsxdsm
41375736e7 Reapply "fix: isolate chat SSE broadcasts per generation"
This reverts commit 46f1f042b0.
2026-05-05 08:21:33 -07:00
gsxdsm
46f1f042b0 Revert "fix: isolate chat SSE broadcasts per generation"
This reverts commit 9d27064c29.
2026-05-05 08:14:10 -07:00
gsxdsm
ba6666fe5f fix: planning modal full-screen height on mobile
Two related bugs left the Planning Mode modal stuck at partial height on
mobile. useModalResizePersist replayed desktop-saved pixel dimensions
that overrode the mobile 100dvh rule, and React reconciled removed CSS
custom properties to empty string rather than calling removeProperty(),
which on iOS Safari defeated the var() fallback after keyboard dismiss.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 07:44:56 -07:00
gsxdsm
9d27064c29 fix: isolate chat SSE broadcasts per generation
After stopping a streaming chat reply, the next message would appear
sent but show no Stop button or "Connecting…" indicator. The cancel
broadcast from the prior generation was leaking into the new SSE
subscription and immediately marking it as errored.

Each `chatManager.sendMessage` now allocates a per-generation id;
`ChatStreamManager` only delivers tagged broadcasts to subscribers
from the matching generation. `sendMessage`'s cleanup also stops
deleting a newer generation's `activeGenerations` slot when an older
one finally unwinds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 07:35:18 -07:00
gsxdsm
df20edb61f fix: skip auto-archive when done task has active dependents
Auto-archive previously wiped .fusion/tasks/{id}/ for stale done tasks
even while downstream agents (triage/todo/in-progress/in-review) still
needed to read those sibling specs from disk. Now the sweep skips any
done task that has an active dependent. The executor prompt also
instructs the agent to fall back to fn_task_show when sibling spec
files are missing on disk (e.g., manually archived deps).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 07:19:30 -07:00
Fusion
ca30babd97 feat(FN-3287): document PR link visibility in dashboard README
Merges the documentation update for FN-3287, adding 2 lines to the dashboard README covering PR link visibility behavior. This completes Step 5 of the task.

Fusion-Task-Id: FN-3287
2026-05-05 07:18:32 -07:00
Fusion
ad94ff3016 feat(FN-3472): expand org chart regression test assertions
The merge adds expanded regression assertions for the org chart feature, covering agent CSS classes and mobile agents view components. The tests verify styling and layout behavior across both desktop and mobile contexts.

Fusion-Task-Id: FN-3472
2026-05-05 07:05:41 -07:00
Fusion
9e2a8006b9 feat(FN-3430): preserve and consume final assistant done payload
This merge adds done-payload snapshot handling across the chat system (FN-3430), normalizing how final assistant messages are preserved and consumed in the dashboard hooks, plus it normalizes dashboard mailbox and user identity for inter-agent messaging (FN-3484) and introduces plugin workflow step

Fusion-Task-Id: FN-3430
2026-05-05 06:42:18 -07:00
Fusion
59f6c8426e feat(FN-3484): normalize dashboard mailbox and user identity for messaging
This merge normalizes dashboard user identity and mailbox messaging (FN-3484, 4 steps), adds workflow step execution for plugins (FN-3490), and updates the restart integration store mock for plugin templates (FN-3096). Core changes touch the message store and store modules with identity normalizatio

Fusion-Task-Id: FN-3484
2026-05-05 06:32:34 -07:00
Fusion
0097212dd9 feat(FN-3490): add workflow step execution for plugins
This merge adds WorkflowStepManager UI enhancements, extends the plugin-runner with new execution capabilities, expands executor tests with improved restart and mock handling, and adds agent routes for the dashboard. The changes span core plugin loading, dashboard components, and engine execution lo

Fusion-Task-Id: FN-3490
2026-05-05 06:32:34 -07:00
Fusion
5bf33e8f66 feat(FN-3096): update restart integration store mock for plugin templates
Updates the restart integration test mock to account for plugin template behavior, keeping the test in sync with recent plugin template changes.

Fusion-Task-Id: FN-3096
2026-05-05 06:32:34 -07:00
Fusion
79322cf67f feat(FN-3500): add shared mesh replication protocol and documentation
This merge introduces a new mesh replication protocol module in `@fusion/core` (with protocol documentation and tests) and updates multiple documentation files, while also normalizing button utility classes in the AgentsView component.

Fusion-Task-Id: FN-3500
2026-05-05 06:32:33 -07:00