Commit Graph

2906 Commits

Author SHA1 Message Date
gsxdsm
938b0c62a0 fix(dashboard): no resize-drag dismiss across all resizable modals + Claude CLI in Authenticated group
When a user drags the native CSS resize grip from inside a modal and
releases the mouse over the overlay, the synthesised click event
targets the common ancestor (the overlay) — fooling the existing
e.target === e.currentTarget dismiss check. Audited every modal with
`resize: both` and switched them to a shared mousedown→mouseup tracking
pattern (new useOverlayDismiss hook) so dismiss only fires when both
events land on the overlay.

Modals fixed: TaskDetail, Settings, FileBrowser, GitHubImport,
GitManager, ScheduledTasks, Scripts, WorkflowStepManager. (Terminal
and AgentDetail were already fixed in 56e8e7324; PlanningModeModal
already had the right pattern inline.)

Also: in Settings → Authentication, the "Anthropic via Claude CLI"
card now lives inside the Authenticated group when authenticated and
the Available group otherwise, instead of floating at the top.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:36:24 -07:00
gsxdsm
56e8e73244 fix(dashboard): resizable terminal + agent detail modals, no resize-drag dismiss
Terminal modal and agent detail view are now resizable via the native
CSS grip with sizes persisted per-modal in localStorage. Mobile keeps
fullscreen layout (resize disabled, !important overrides any persisted
desktop dimensions).

Both modals previously dismissed when a drag-resize started inside the
modal but released over the overlay — the synthesised click event
targets the common ancestor (overlay), tripping the e.target ===
e.currentTarget dismiss check. Switched to mousedown→mouseup tracking
so dismiss only fires when both events land on the overlay.

Terminal additionally observes its own pixel box via ResizeObserver
and refits xterm on every grip drag — `resize: both` doesn't emit
window resize.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:30:05 -07:00
gsxdsm
cdddc602f9 feat(dashboard): add fireworksai and qwen-ai provider id aliases
Two more brand-id spellings observed in the wild that previously fell
through to the generic Cpu glyph:
  fireworksai → FireworksIcon (joins fireworks / fireworks-ai)
  qwen-ai     → QwenIcon       (joins qwen / qwen-coder / alibaba / tongyi)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:25:10 -07:00
gsxdsm
bb340206bf feat(dashboard): add Cerebras / Groq / Vercel icons + cover all pi-ai catalog providers
Audited the pi-ai built-in model catalog provider IDs against the
ProviderIcon registry and filled every remaining gap.

New icons:
  --provider-cerebras    (#f1592a)  → CerebrasIcon (concentric arcs)
  --provider-groq        (#f55036)  → GroqIcon     (lightning bolt)
  --provider-vercel      (text)     → VercelIcon   (triangle wordmark)

New aliases routed to existing icons:
  minimax-cn               → MiniMaxIcon
  azure-openai-responses   → AzureIcon
  google-gemini-cli        → GeminiIcon
  google-generative-ai     → GeminiIcon
  opencode-go              → OpencodeIcon
  vercel-ai-gateway        → VercelIcon

After this commit every provider id emitted by `@mariozechner/pi-ai`'s
register-builtins (anthropic, openai, openai-codex, google,
google-vertex, google-gemini-cli, google-antigravity,
amazon-bedrock, mistral, openrouter, fireworks, cerebras, groq,
huggingface, kimi-coding, minimax, minimax-cn, zai, xai, opencode,
opencode-go, github-copilot, azure-openai-responses,
vercel-ai-gateway) plus the user-curated set (qwen, lm-studio,
hugging-face, alibaba/tongyi, hf, lmstudio…) renders a brand icon
instead of falling back to the generic Cpu glyph.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:22:42 -07:00
gsxdsm
13b502497c feat(dashboard): add Qwen, LM Studio, Hugging Face, Mistral, Azure, Fireworks logos + Gemini aliases
Adds six new provider icons rendered as inline SVG, each backed by a new
brand token in styles.css:
  --provider-qwen          (Qwen / Tongyi)
  --provider-lmstudio      (LM Studio)
  --provider-huggingface   (Hugging Face)
  --provider-mistral       (Mistral AI)
  --provider-azure         (Microsoft Azure / Azure OpenAI)
  --provider-fireworks     (Fireworks AI)

Aliases registered:
  qwen / qwen-coder / alibaba / tongyi
  lmstudio / lm-studio
  huggingface / hugging-face / hf
  mistral / mistral-ai
  azure / azure-openai
  fireworks / fireworks-ai

Also extends the Gemini icon to cover every Google-product alias the
catalog throws at it: google-vertex, vertex, google-cloud-code,
cloud-code, antigravity (in addition to the existing google,
gemini, google-antigravity).

Tests cover each new mapping (and confirm the Gemini alias group all
resolves to the gemini icon with --provider-gemini color).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:07:32 -07:00
gsxdsm
e8fb9672b5 fix(dashboard): onboarding step buttons + tighter auth provider spacing
- ModelOnboardingModal: completed/skipped step indicators render as
  <button> so they're clickable for review. Without explicit reset,
  browsers gave them their default white-ish background. Added
  background: transparent + border/padding/font-family resets to
  .model-onboarding-step-indicator so it inherits cleanly from the
  surrounding card on every theme.
- SettingsModal authentication: tightened spacing around providers —
  group margin 16→10, group label margin 8→4, provider card margin
  8→4, header padding 12 16 → 8 12. Less wasted space between rows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 18:59:37 -07:00
gsxdsm
6094c999ed fix(tui): tighten StatusModeSingle spacer threshold to cols<71
Previously the spacer kicked in at cols<68 (top of Logs border was
covered at 68-70) then was widened to cols<72 (which added a gap at 71
where Yoga's flex-column placed the panel correctly without help).
cols<71 is the precise boundary: 68-70 need the 1-row compensation
spacer, 71+ does not.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 18:20:18 -07:00
gsxdsm
3b3d456ca8 fix(dashboard): mobile rendering for resizable modals
The Settings, Workflow Steps, Automations (and friends) modals all carried
desktop `min-width: 480-520px` constraints from the resize work. On phones
that pushed them off-screen, and the overlay's 10vh top padding plus a
fractional `height: 80vh` left awkward gaps top and bottom.

Apply the same `@media (max-width: 768px)` full-screen-sheet treatment
that File Browser already had to every resize-aware modal: drop the
overlay padding, set width/height to `100vw`/`100dvh`, zero out the
min-* / max-* constraints, and disable `resize` (touchscreens can't grab
the corner grip anyway).

Also tightened the existing File Browser and GitHub Import overrides to
match (`min-width: 0`, `min-height: 0`, `resize: none`).

For TaskDetailModal the mobile rules go inside the existing first
`@media (max-width: 768px)` block to keep the FN-1331 detail-body
padding regression test happy (it captures from the first 768px media
query greedily).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 18:10:24 -07:00
gsxdsm
1fe59be960 feat(dashboard,cli): update-check frequency, GitHub star button, more resizable modals
Update-check frequency (end-to-end)
- Add `updateCheckFrequency: "manual" | "on-startup" | "daily" | "weekly"`
  to GlobalSettings (default: "daily").
- Backend `performUpdateCheck` honors the frequency: TTL = day/week,
  `manual` returns cache or empty without hitting npm, `on-startup`
  refreshes once per process lifetime then serves cache. `/refresh`
  route forces network regardless.
- Settings → Updates surfaces a working `<select>` for the cadence,
  disabled when auto-checks are off entirely.
- Tests: 4 new cases covering ttlForFrequency mapping, weekly window,
  manual semantics, on-startup once-per-process behavior.

TUI update notice
- Read cached update result synchronously on TUI startup. When an
  update is available, render a yellow notice line on the splash and
  a colored ● next to the version in the status bar.

Settings modal header polish
- Add "Star on GitHub" pill (icon + Star + cached star count from the
  GitHub API, 1h localStorage TTL) and "Help" button (opens project
  Discussions). Both link to the Runfusion/Fusion repo.
- Star button auto-hides after the user clicks it (intent = star),
  tracked in localStorage `fusion:github-star-clicked`.
- Settings → General gets a "Show Star on GitHub button" checkbox so
  users can hide it preemptively. New global setting
  `showGitHubStarButton: boolean` (default true) gates rendering.

More resizable modals
- Task Detail modal: 85vh default, resize: both, persisted via
  useModalResizePersist (key `fusion:task-detail-modal-size`).
- Quick Chat FAB: full 8-direction resize (4 corners + 4 edges) via
  pointer-event handlers; persisted to
  `fusion:quick-chat-size-<projectId>`. Each handle has the right
  cursor + role="separator" for accessibility.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 17:55:15 -07:00
gsxdsm
dba2299137 fix(core): polling loop falsely emits task:deleted for archived tasks
TaskStore.checkForChanges detects deletions by comparing the in-memory
taskCache against the tasks table. But archiveTask also DELETEs the row
from `tasks` (after copying to archive_db), so any TaskStore instance
polling the same DB sees the archived task vanish and emits
`task:deleted`. The activity-log listener records that as a deletion,
producing entries like "Task FN-NNNN deleted" for tasks that are alive
and well in the archive.

Reproduced live: 2048 task:deleted entries in a single ~1ms burst, all
of them present in archive.db. Two TaskStores (CLI/engine and dashboard
server) on the same DB → CLI archives, dashboard polls and false-flags.

Fix: in checkForChanges, batch-query the archive for all missing IDs.
For ids that exist in archived_tasks, emit `task:moved` (to:archived) —
matching what archiveTask emits in-process — so the activity log
records the correct event. For ids not in archive, emit task:deleted as
before (real deletion).

Adds ArchiveDatabase.filterArchived(ids) helper that returns the subset
in archived_tasks via a single SELECT IN query (chunked at 500 to stay
under SQLite's parameter limit).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 17:46:05 -07:00
gsxdsm
b3b0ce7cb0 feat(dashboard): UI polish pass — resizable modals, themed scrollbars, settings overhaul
Modal resize + size persistence
- Extract `useModalResizePersist` hook (ResizeObserver + localStorage),
  apply to Files, Git Manager, GitHub Import, Workflow Steps, Automations
  (ScheduledTasks), and Settings modals. Each gets `resize: both`, sane
  min/max constraints, and a unique storage key.
- Bump default heights so the modals feel less cramped (Git: 92vh,
  Workflow/Automation: 80vh, Settings: 80vh / 1100px).

Scrollbar theme
- Add a global `*::-webkit-scrollbar*` + `scrollbar-color` rule in
  styles.css so chat, document, system stats, file browser, usage
  indicator, etc. inherit the theme. Existing per-component overrides
  (.board, .column-body, .settings-sidebar, planning modal) still win.

Document view
- Collapse "Show hidden" toggle and search input onto the same row as
  the Project Files / Task Documents segmented control. Stack again
  below 768px.

Mailbox / Todos
- Match Todos header treatment to the Mailbox header (typography,
  padding, border).
- Add top spacing above Mailbox Inbox/Outbox/Agents tab bar so the
  vertical gaps balance.

Settings
- Wider, resizable, persisted Settings modal.
- Project Models description and Authentication panel get proper
  horizontal padding.
- Reorder project sidebar so "General" is first.
- Plugins page: clean margins, integrate refresh button, exclude
  bundled runtimes from the "Installed Plugins" list (they were
  appearing twice — once erroring, once in their own section).
- New "Updates" panel with auto-check toggle + "Check now" button
  (frequency control noted as needing a backend schema field).

Background sessions
- Fix stale "AI N" / planning-icon badge: `handleDeleted` in
  `useBackgroundSessions` now writes a tombstone, advances the
  timestamp guard, and broadcasts completion so the cross-tab
  sync store stops resurrecting the deleted session on the next
  merge tick. Added regression test.
- Re-fetch list on SSE reconnect so terminal events fired during a
  network blip don't get permanently lost.

System stats
- Refresh button uses correct single class (was getting both `btn`
  and `btn-icon`, which conflicted on padding/border).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 17:26:07 -07:00
gsxdsm
53e763e35f fix(engine): respect global pause in reviewer + stuck detector
Reviewer subprocesses were spawned via fn_review_spec / fn_review_step
even with globalPause on, because reviewer.ts had no pause awareness.
Stuck detector also kept running, treating pause-disposed sessions as
inactivity and re-queuing tasks. Pause-transition listeners only called
session.dispose(), which doesn't always interrupt an in-flight LLM
stream — letting reviewer spawns leak through after pause flipped.

- reviewer.ts: re-read settings, return UNAVAILABLE without spawning
  when globalPause/enginePaused is on.
- stuck-task-detector.ts: skip checkStuckTasks() while paused.
- triage.ts / executor.ts: call session.abort() before dispose() in the
  pause-transition listener to interrupt in-flight work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 17:26:01 -07:00
gsxdsm
e598d60f01 fix(tui): redesign Main layout, robust header, panel reshuffle
Header was disappearing in tmux at narrow widths under Logs/Utilities
panels because Yoga's flex-column placed the panel body at y=0 instead
of y=1, overdrawing the header. Synthetic tests at every width show the
layout as correct, but real-tmux log-update tracking drifts over many
state updates and the header gets scrolled off.

- Paint header as an ANSI overlay after every Ink frame write (DECSC/
  DECRC cursor save/restore) — guaranteed at terminal row 1 regardless
  of any layout drift. Skipped during splash so the loading screen is
  uncluttered.
- StatusModeGrid: full-width System on top (4-row pinned, chips wrap if
  needed) + Logs filling the middle + Stats/Utilities/Settings as
  equal-width bottom row. Stats now shows just Process/System rows.
- StatusModeSingle: 1-row spacer only at cols<68 (Yoga edge case at
  very narrow widths shifts content up); 68+ has no spacer per UX.
- Panel/LogsPanel/UtilitiesPanel inner content boxes pinned with
  flexShrink=1 + overflow=hidden so panel intrinsic height can't push
  the frame past terminal rows.
- Each Logs entry wrapped in height={1} Box (when wrap is off) — Yoga
  was sometimes measuring nested Text as taller than 1 row at narrow
  widths.
- Tab "Explorer" → "Files" with shortcut "e" → "f" (preserves
  filter-cycle on Logs panel; switches to Files view elsewhere).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 17:00:43 -07:00
gsxdsm
b055c81ec0 feat(dashboard): redesign Planning modal as two-pane session manager
- Sidebar lists all planning sessions for the project (any status) with
  inline status badges, relative timestamps, "+ New session", and an
  inline delete confirm. Mobile collapses to a single pane with a back
  chevron in the header.
- Closing the modal (X / Escape / overlay) no longer cancels the server
  session — it stays in the list, resumable. Only an explicit Delete
  cancels + removes. Removes the now-redundant minimize button.
- Add re-sync on reopen so a session whose terminal SSE event was missed
  doesn't stay stuck on a stale loading view; previously only a hard
  reload recovered.
- Persist user-chosen modal width/height across opens via localStorage,
  driven by a ResizeObserver on the modal element.
- Theme the modal scrollbars to match the rest of the app.
- Banner dismiss only hides the banner now — it must not delete the
  underlying session, since sessions are first-class in the new sidebar.
- Refresh background sessions list on SSE reconnect so the footer "AI N"
  pill never gets stuck on tombstoned sessions after a network blip.
- Drop selection + broadcast completion on Create Task / Create Tasks
  so the footer count drops in lockstep instead of waiting on SSE.
- Auto-scroll the AI thinking output as new tokens stream in (only when
  already pinned to the tail).
- Guard overlay-click dismissal with a mousedown-on-overlay check so
  releasing a resize drag outside the modal doesn't close it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 16:58:35 -07:00
Fusion
7986b03207 fix(dashboard): card timer shows total execution = timed events + workflow runtime
The task card timer chip previously fell back through several metrics
(timed duration → workflow runtime → wallclock), so cards showed only a
subset of execution time. For FN-2714 this rendered <1m on the card while
the stats tab reported >2m of workflow runtime.

The chip now reports the sum of [timing]-tagged log events and workflow
step runtime (matching the new "Total execution time" metric in the stats
panel), with live elapsed for in-progress workflow steps. When neither
metric is recorded, the chip is hidden rather than falling back to
wallclock.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 16:05:50 -07:00
Fusion
777d6a1942 fix(FN-2714): restore task timer chip to footer metadata row
- Move TaskCard time indicator rendering from the header back into the footer metadata row
- Render timer and files-changed metadata together in the shared footer row layout
- Update timer chip CSS to stay right-aligned with margin-left:auto and prevent shrinking
- Update TaskCard and mobile board tests to assert footer placement and alignment behavior
2026-04-27 12:45:53 -07:00
Fusion
ac93023f2d fix(FN-2715): show initial loading state in Agents view
- Render an accessible loading status when the first agents fetch is in flight
- Keep existing agent cards visible during refresh instead of replacing the grid with a loader
- Add AgentsView CSS for the loading container with responsive sizing
- Add regression tests covering initial loading, post-load cleanup, and refresh behavior
2026-04-27 12:04:07 -07:00
Fusion
6b2982cda5 test(FN-2712): add runtime e2e and integration coverage
- Add OpenClaw runtime end-to-end tests covering execution flow and runtime contract behavior
- Add OpenClaw integration tests to validate plugin/runtime wiring in engine scenarios
- Add Paperclip runtime end-to-end and integration suites for equivalent cross-runtime coverage
- Update Hermes, OpenClaw, and Paperclip manifest descriptions for consistent runtime metadata
2026-04-27 11:58:31 -07:00
Fusion
626e768f39 feat(FN-2709): migrate Hermes runtime plugin to pi-ai streaming client
- Replace Hermes pi module integration with pi-ai session streaming and updated runtime adapter contracts
- Remove legacy engine guard scaffolding and add hermes-stream-client coverage for streaming behavior
- Rewrite plugin and engine e2e tests to align with the new runtime flow and regenerate dist artifacts
- Update Hermes runtime README and package metadata to document pi-ai execution expectations
2026-04-27 11:34:49 -07:00
gsxdsm
597daeaf33 fix(dashboard): preserve fullDetail.log so task Activity tab renders
The live-token-usage refactor (199ee9cee) merged the SSE-updated `task`
prop on top of `fullDetail` to keep tokenUsage/status fresh. SSE strips
`log` to [] (stripTaskListHeavyFields) for list payloads, so the spread
clobbered fullDetail.log and the Activity timeline rendered empty.

Carve `log` out of the merge alongside `prompt`. Adds a regression test
that simulates the SSE-stripped task prop with a populated fullDetail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:34:49 -07:00
Fusion
db504d2ab6 feat(FN-2713): move timer chip into task card header
- Render the countdown timer in the task card header next to metadata for clearer scanning
- Remove legacy footer timer styling and adjust TaskCard structure accordingly
- Update TaskCard unit tests to assert the new timer placement and header behavior
- Expand mobile board tests to validate timer visibility and placement across card states
2026-04-27 11:34:49 -07:00
Fusion
399c7048cb fix(dashboard): prevent foreign-branch diffs after worktree pool reuse
When the worktree-recycle pool reassigned a path to a new task, the old
task's diff endpoints kept reading the new task's branch state — surfacing
unrelated commits as the original task's "files changed" list.

- Clear task.worktree/branch in the merger after the worktree is released
  to the pool or removed, so the path no longer points anywhere.
- Validate the worktree's current branch matches task.branch in the three
  worktree-backed diff endpoints; on mismatch return empty rather than
  diffing against a foreign branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:34:49 -07:00
gsxdsm
9650019877 fix(dashboard): prevent foreign-branch diffs after worktree pool reuse
When the worktree-recycle pool reassigned a path to a new task, the old
task's diff endpoints kept reading the new task's branch state — surfacing
unrelated commits as the original task's "files changed" list.

- Clear task.worktree/branch in the merger after the worktree is released
  to the pool or removed, so the path no longer points anywhere.
- Validate the worktree's current branch matches task.branch in the three
  worktree-backed diff endpoints; on mismatch return empty rather than
  diffing against a foreign branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:04:42 -07:00
Fusion
bd59b1ff99 fix(FN-2704): gate auth onboarding behind setup wizard
- Prevent useAuthOnboarding from opening model onboarding while the setup wizard is active
- Add app-level wiring so onboarding flow respects setup wizard visibility state
- Add regression tests covering setup wizard gating and non-stacking onboarding behavior
2026-04-27 09:56:05 -07:00
Fusion
637f4350c9 feat(FN-2703): support custom MCP tools in plan generation
- Remove ToolSearch prerequisite so custom MCP tools can be used during triage and plan generation flows
- Align built-in tool sets between provider wiring and prompt builder handling, including custom ls behavior
- Expand pi-claude-cli tests for event bridge, MCP config, prompt builder, and tool mapping regressions
- Add FN-2703 changeset and delivery documentation for the published @runfusion/fusion package
2026-04-27 09:51:49 -07:00
Fusion
9015041283 feat(FN-2705): reduce planning question scroll top padding
- Update PlanningModeModal styles to decrease top padding in the question scroll area
- Improve modal content density so question content starts closer to the top
2026-04-27 09:42:27 -07:00
Fusion
07c635e1b7 test(FN-2702): add Hermes runtime e2e coverage
- Add end-to-end Hermes runtime test covering PluginStore registration through PluginLoader and PluginRunner resolution
- Verify createResolvedAgentSession uses the Hermes runtime and delegates createFnAgent, promptWithFallback, and describeModel calls
- Add regression test ensuring AgentRuntime-shaped Hermes adapters are reused without compatibility wrapping
- Cover fallback behavior to default pi runtime when Hermes plugin is not installed
2026-04-27 09:37:37 -07:00
Fusion
0f04b2a79e feat(FN-2700): add runtime selection to custom agent tab
- Add runtime selection controls to the NewAgentDialog custom tab flow
- Update dialog behavior to persist and apply the selected runtime when creating custom agents
- Add NewAgentDialog styling updates for the new runtime UI states
- Expand NewAgentDialog tests to cover runtime selection behavior on the custom tab
2026-04-27 09:21:03 -07:00
Fusion
347cae8e6c fix(FN-2698): load plugins during CLI runtime startup
- Load configured plugins during dashboard startup before launching the UI flow
- Load plugins during serve and daemon startup so runtime hooks are available immediately
- Add targeted CLI command tests for dashboard, serve, and daemon auto-load behavior at startup
- Add a changeset documenting the plugin runtime startup fix for @runfusion/fusion
2026-04-27 09:10:14 -07:00
Fusion
aa325e5491 feat(FN-2697): add todo task creation with agent picker actions
- Add TodoView controls to create todo tasks directly and optionally assign an agent
- Style the TodoView agent picker dropdown for desktop and mobile interactions
- Add TodoView tests covering todo task creation and agent assignment behavior
- Simplify dashboard TUI status grid sizing to use flexible panel layout
2026-04-27 09:01:32 -07:00
Fusion
ccf77ab507 feat(FN-2699): switch runtime source selectors to tab controls
- Replace runtime source radio groups with tablist/tab buttons in NewAgentDialog and AgentDetailView
- Preserve runtime mode behavior by keeping model/runtime selection handlers and reset logic intact
- Align AgentDetailView runtime selector styling with tab pattern and remove obsolete radio-toggle CSS
- Update AgentDetailView tests to assert tab semantics via role and aria-selected
2026-04-27 08:53:09 -07:00
Fusion
47ace9ca09 feat(FN-2695): gate Todos view behind todoView experimental flag
- Add todoView to experimental feature settings and expose it in Settings modal and docs
- Derive todosEnabled in app settings hook with regression tests for enabled/disabled behavior
- Gate App routing so Todos only renders when the flag is enabled and redirects otherwise
- Hide Todos entries in header overflow and mobile navigation when the flag is off
2026-04-27 08:49:12 -07:00
Fusion
1ded15a40a feat(FN-2694): merge fusion/fn-2694 2026-04-27 08:45:49 -07:00
Fusion
b2f71a2136 feat(FN-2689): standardize cross-platform shell selection
- Add engine shell utility to resolve the correct shell per platform
- Update routine runner to execute commands through shared shell selection
- Update cron runner to use the same cross-platform shell behavior
- Apply shared shell handling in dashboard routes for command execution
- Add shell utility tests covering platform-specific selection behavior
2026-04-27 08:33:03 -07:00
Fusion
8fbd3bdb4b test(FN-2687): add plugin install getRootDir regression coverage
- Add CLI plugin install tests that reproduce and guard the getRootDir path-resolution regression
- Validate plugin installation behavior in the regression scenario to prevent future breakage
- Add a patch changeset for @runfusion/fusion documenting the plugin install getRootDir fix
2026-04-27 08:29:40 -07:00
Fusion
3c8a4903c2 fix(FN-2688): add root dir to plugin install mock task store
- Add getRootDir() to the plugin command mock TaskStore used by createPluginLoader
- Ensure fn plugin install can resolve project root expectations without runtime failures
- Add a patch changeset for @runfusion/fusion documenting the CLI fix
2026-04-27 08:13:58 -07:00
Fusion
ba620ed711 feat(FN-2686): improve system stats refresh UX on mobile
- Fix mobile refresh button icon visibility in SystemStatsModal
- Add auto-refresh activity indicator with spinning refresh state
- Update modal styles for responsive refresh controls and animation states
- Expand SystemStatsModal tests to cover mobile visibility and auto-refresh indicator behavior
2026-04-27 08:03:20 -07:00
Fusion
747a8a91b6 feat(FN-2685): remove TaskCard token usage badge
- Remove token usage badge rendering and compact token formatting from TaskCard
- Drop token usage fields from TaskCard memo equality checks now that the badge is gone
- Delete obsolete TaskCard token badge CSS rules and icon import
- Simplify TaskCard tests by removing token badge assertions and related fixtures
2026-04-27 07:59:42 -07:00
Fusion
0a5dcf12bc fix(FN-2684): harden system-stats when project lookup fails
- Keep /api/system-stats process and host metrics available even if scoped project resolution throws
- Fall back task and agent aggregates to zero when scoped task or agent stores cannot be loaded
- Preserve vitest process reporting while guarding optional vitestLastAutoKillAt lookup behind scoped context success
- Add route tests for scoped project-not-found fallback behavior and include a patch changeset for @runfusion/fusion
2026-04-27 06:03:53 -07:00
Fusion
ec092825ac feat(FN-2681): add Vitest kill controls in system stats
- Add dashboard API endpoint and server route to terminate Vitest worker processes safely
- Extend legacy API client with killVitestProcess support for frontend invocation
- Add SystemStatsModal UI controls and styling for triggering Vitest kill actions, including mobile width stability fixes
- Expand route and modal tests to cover new controls and behavior
- Add changeset and architecture docs updates for the new Vitest kill capability
2026-04-27 05:50:40 -07:00
gsxdsm
fce1755d2b fix(dashboard): reserve iOS PWA status-bar inset on mobile modal headers
The black-translucent status bar overlays the page in iOS standalone PWAs,
clipping close buttons in full-screen mobile modals and the QuickChatFAB
panel. Add `padding-top: env(safe-area-inset-top, …)` so headers render
below the status bar.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 05:17:32 -07:00
gsxdsm
b3700e6e6d fix(tui): keep Main header visible in single-column mode
In StatusModeSingle (cols<80 || rows<20), an active panel whose
intrinsic content exceeds the container could push the frame past
terminal rows under tmux, scrolling the header off the top. Yoga
defaults flexShrink to 0 (unlike CSS), so panels refused to shrink
when wrapped Text grew them vertically.

- Default Panel flexShrink to 1 so panels collapse to fit container
- Pin StatusModeSingle's three rows to explicit heights with
  overflow:hidden, eliminating overflow paths entirely
- Pass availableRows to LogsPanel from the capped middleHeight so
  its rowBudget matches the actual height instead of stdout.rows-11

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 05:16:25 -07:00
Fusion
0f9c0e9ce9 feat(FN-2677): persist step and single-session token usage stats
- Capture prompt/completion/total token usage from step-scoped sessions in the step session executor
- Persist per-step token usage in executor run context so stats survive across task execution
- Record single-session token usage totals alongside run context stats logging for consistent aggregation
- Expand executor and step-session executor tests to validate token usage persistence and fixture behavior
2026-04-27 05:13:59 -07:00
Fusion
403767e4af feat(FN-2683): align mobile action button sizing in task views
- Reduce Task Detail move split chevron width on mobile for a more compact control
- Add mobile padding override to TaskCard send-back button to match sibling action sizing
- Normalize task action button dimensions across card and detail contexts
2026-04-27 05:07:34 -07:00
gsxdsm
199ee9ceef feat: live task token usage and stats-tab fixes
Capture per-session token usage from pi-coding-agent's getSessionStats()
after each promptWithFallback in the executor and merger paths, so
task.tokenUsage populates live during runs and reflects final totals on
done tasks. Previously the executor never read session usage and only
the heartbeat path bumped agent token totals, leaving task.tokenUsage
undefined even after completion.

Stats panel and done-card timing also now reflect live state: the modal
overlays the SSE-updated task prop on top of the one-shot fullDetail
snapshot, in-progress workflow steps contribute live elapsed to the
Workflow runtime metric, and the done card uses Timed duration (matching
the stats tab) with workflow runtime as fallback. Time indicator labels
coarsened to <1m / Nm / Nh / Nd.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 04:51:29 -07:00
Fusion
7de5a17810 feat(FN-2679): move show-hidden control inline in usage indicator
- Reposition the show-hidden toggle into the UsageIndicator inline layout next to usage details
- Update UsageIndicator styles to support the new inline button placement and spacing
- Add UsageIndicator tests that assert the show-hidden button renders in the correct placement
- Preserve existing behavior while improving visual hierarchy for hidden-usage toggling
2026-04-27 04:33:10 -07:00
Fusion
a1522835fc feat(FN-2675): tighten TaskCard right-side action button spacing
- Reduce horizontal spacing for archive/unarchive and send-back action buttons on TaskCard
- Replace hardcoded padding, margin, gap, and font-size values with design-token-based calculations
- Keep mobile action-button padding aligned with the updated compact sizing
2026-04-27 04:20:19 -07:00
Fusion
92e14e3fa6 feat(FN-2639): replace native confirms with dashboard confirm dialog
- Add reusable ConfirmDialog component, styles, and useConfirm hook to provide async confirmation flows
- Wire ConfirmProvider at app level and migrate confirm call sites across task, agent, roadmap, plugin, and settings UI actions
- Update modal interaction patterns to support dialog reentry and consistent destructive-action confirmations
- Expand dashboard tests with confirm dialog and hook coverage plus migrated component test assertions
2026-04-27 04:05:25 -07:00
Fusion
0383613957 feat(FN-2649): add themed scrollbar styles in task detail modal
- Add token-based scrollbar styling for .detail-body across Firefox and WebKit pseudo-elements
- Scope agent log scrollbar rules to .detail-section--agent-log .agent-log-viewer-scroll to avoid selector target drift
- Add TaskDetailModal CSS regression tests that assert scrollbar declarations for modal body and agent log containers
- Introduce shared test helpers for robust selector/declaration matching in stylesheet assertions
2026-04-27 03:47:09 -07:00
Fusion
f333c180f9 feat(FN-2670): surface routine run state and output inline
- Add running-state visual treatment to routine cards, including spinner icon and running class styling
- Capture manual run results in ScheduledTasksModal and pass transient inline output/error to each RoutineCard
- Clear pending inline output when routine data refresh catches up or when leaving/switching routine views
- Expand dashboard tests to cover loader icon, running class, and inline run output rendering
2026-04-27 03:30:54 -07:00