Commit Graph

1489 Commits

Author SHA1 Message Date
gsxdsm
0a3c28d872 chore(dashboard): UI polish — Hermes logo, settings header heights, simplify agent card actions
- Use bundled Nous Research SVG (inverted) on the Hermes runtime card
  instead of the generic ProviderIcon.
- Lock GitHub-star and Help buttons in the settings header to a uniform
  26px height so the differing icon sizes don't misalign them.
- Drop the inline Delete button from the idle/terminated agent-card
  states — deletion stays available from the agent detail view.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 23:27:41 -07:00
gsxdsm
a6697ee7ca feat(paperclip-runtime): route Paperclip calls through paperclipai CLI in Local CLI mode
The Paperclip runtime card's Local CLI tab previously only derived an apiUrl
from the local config and then made HTTP calls itself, so the Test action and
the company/agent pickers ignored the user's onboarded CLI auth context.

Add CLI-backed variants for every Paperclip call that has a `paperclipai`
counterpart, and route through them when transport=cli — both from the
settings card and from the runtime adapter's prompt path.

- New plugin functions spawning `paperclipai … --json`:
  * probePaperclipViaCli, listCompaniesViaCli, listCompanyAgentsViaCli
    (settings card test + pickers)
  * createIssueViaCli, getIssueViaCli, agentsMeViaCli (runtime hot path)
- New dashboard routes: /providers/paperclip/cli-status, /cli-companies,
  /cli-agents (read-only façades over the plugin's CLI helpers)
- PaperclipRuntimeCard: branches on transport=cli to use the cli-* fetchers
- PaperclipRuntimeAdapter: stores transport on the session and routes
  createIssue/getIssue + identity derivation through CLI variants in CLI mode;
  raises a clear error when agentId is unset in CLI mode (paperclipai has no
  /agents/me equivalent)
- getIssueComments / wakeAgent / getRunEvents stay on HTTP (no matching
  paperclipai subcommands) and continue to use the apiKey discovered from
  the local paperclipai config, so CLI mode still works end-to-end
- Tests: 9 new paperclip-client tests covering each CLI variant + 5 new
  adapter tests for the Local-CLI transport branch (64/64 plugin tests pass)
- Update routes.test for the existing BUNDLED_PLUGIN_RUNTIMES fallback so
  the bundled hermes/openclaw/paperclip entries are expected alongside
  installed plugins

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 23:06:20 -07:00
Fusion
a3a6794c41 feat(FN-2718): add unavailable node policy setting and validation
- Define and export unavailable node policy types in core settings interfaces
- Add project-level unavailable node policy default and runtime validation helper
- Add core unit coverage for unavailable node policy parsing and acceptance cases
- Guard Paperclip mint requests to include companyId only when available for type-safe payloads
- Document unavailable node policy in the settings reference
2026-04-27 22:40:08 -07:00
Fusion
d3e1c28cef fix(plugins): re-export probe symbols + declare plugin deps in dashboard
- Hermes / OpenClaw plugin index.ts now re-export `probeHermesBinary` /
  `probeOpenClawBinary` and their status types so the dashboard's
  `runtime-provider-probes.ts` façade can import them via the public
  package entry instead of deep paths.
- Dashboard `package.json` adds `@fusion-plugin-examples/hermes-runtime`,
  `…/openclaw-runtime`, `…/paperclip-runtime` as workspace deps so
  pnpm symlinks them into `packages/dashboard/node_modules/`. Without
  these, the new probe imports failed with "Cannot find module" during
  `pnpm typecheck`.

This clears 6 of the 9 outstanding typecheck errors. The remaining 3 are
in the in-flight Hermes plugin rewrite (runtime-adapter still imports
from a deleted `./pi-module.js`; the new `index.ts` calls a factory
with the wrong arg type) and should be resolved by the same change set
that landed the rewrite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 22:17:54 -07:00
gsxdsm
1a1bec1fb4 test(dashboard): align CSS-contract + onboarding tests with current contracts
Two long-standing test failures, root-caused and fixed.

terminal-mobile-keyboard-layout.test.ts (2 tests)
  CSS structure changed: the desktop terminal modal moved its initial
  width/height into companion `:not([style*="width"])` /
  `:not([style*="height"])` rules so persisted resize values can win
  over the default. The tests still searched the base block. Updated
  the helpers to extract from each rule explicitly, asserting:
    width: min(1800px, …)            in the :not([style*="width"]) rule
    max-width: calc(100vw - …)       in the base rule
    85vh                             somewhere in the :not([style*="height"]) rule
    min-height + max-height: calc(100dvh - 40px)  in the base rule
  Same constraints, just reflecting the current selector layout.

ModelOnboardingModal.test.tsx (2 tests)
  Component refactor (commit f3d918997) made the "what GitHub unlocks"
  feature list conditional on `!isGitHubReady`, so the test that mocks
  `authenticated: true` no longer sees "Import issues as tasks". And
  the gh-CLI optional explanation copy was rewritten to "OAuth from
  the dashboard is optional" instead of "OAuth integration in
  Settings → Authentication is optional". Updated:
    - "shows connected state": assert the new connected-state
      sentence ("GitHub is connected — issue imports …") instead of
      the now-hidden feature list line.
    - "explains gh CLI auth": use getAllByText for the two-place
      "GitHub CLI is already authenticated" copy and match the
      current "OAuth from the dashboard is optional" sentence.
  Also adds the missing `afterEach` import to silence its TS error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 20:16:45 -07:00
gsxdsm
aa86dcc05c fix(dashboard): scale stats values to fit metric box without overflow
Token counts on the task detail Stats panel could overflow the metric
box for large values (e.g. 10-digit comma-separated totals). Switched
each metric to a container-query inline-size context and gave the
value a fluid font-size of `clamp(13px, 13cqw, 28px)` so it grows to
fill the box up to a 28px cap and shrinks down to 13px on narrow grid
columns. Combined with `min-width: 0`, `overflow-wrap: anywhere`, and
the metric's `overflow: hidden`, long values now stay within the box
and short values render as large as they can without dominating.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 20:06:06 -07:00
gsxdsm
f3d918997c fix(dashboard): wider/resizable onboarding modal + GitHub CLI-aware messaging
- ModelOnboardingModal: native CSS resize with persisted size via
  useModalResizePersist; default ~1100px wide; modal scrolls inside
  the content area instead of clipping.
- Provider cards flex-wrap so the API-key form drops to a full-width
  row instead of being squished into a fixed side column. Connected
  badge no longer stretches the full body width.
- Step changes now reset content scrollTop so each page lands at the
  top.
- GitHub step: prominent GitHub mark via ProviderIcon; when gh CLI is
  authenticated the intro reads as 'you are all set', primary CTA
  becomes 'Continue with gh CLI auth', and a secondary
  'Connect OAuth (optional)' button is offered.
- CustomModelDropdown: highlight init runs once per open session, and
  filter changes reset highlight to top + scrollTop=0, fixing the
  scroll-fight when filtering models.
- TUI dashboard: at >=150 cols, Stats panel sits to the left of Logs;
  bottom row drops to Utilities + Settings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 20:05:45 -07:00
gsxdsm
4b9fd3dd64 fix(dashboard): clear all 661 test-file type errors
Production typecheck (tsconfig.json + tsconfig.app.json) was already
clean, but a third config that includes test files surfaced 661 errors
across 60+ test files — accumulated drift between mock fixtures and
production types. Six parallel typescript-pro agents fixed every one
without touching production code.

Per-scope before/after (errors → 0):
  ChatView                                                     183
  Mailbox + Agent suite (5 files)                              156
  Task / Modal suite (6 files)                                 127
  App + small components (12 files)                             96
  Hooks + api/auth (8 files)                                    48
  Long tail (32 files)                                          51
  -----------------------------------------------------------------
  Total                                                        661

Major fix categories:
- Untyped state objects inferring `never[]` / `null` literals (root
  cause of ~120 errors in ChatView alone — added a single
  `UseChatReturn` annotation)
- Mock objects missing fields that became required: `WorkflowStep.mode`,
  `ChatMessage.thinkingOutput / metadata`, `ChatSession.projectId`,
  `Task.log`, `ProjectHealth` fields, `PtyTerminalSessionInfo.createdAt`,
  `Agent.metadata`, `InboxResponse.total`, etc.
- Mock objects with stale fields that no longer exist:
  `AgentBudgetStatus.budgetPeriod`, `truncated` on log responses,
  `OutboxResponse.unreadCount`, `MergeResult.source/target/details`
- Modal props that became required (e.g. `PlanningModeModal.onTasksCreated`)
- String literals not in narrowed unions (`Column`, `WorkflowStepPhase`,
  `InsightStatus`, `AgentLogType`, etc.)
- `querySelector` returning `Element` cast to `HTMLElement` for
  `@testing-library/react`'s `within()`
- Vitest mock typing: `.mock.calls` access needing `vi.mocked(...)`,
  zero-param tuple handling, generic `vi.fn(() => [])` inferring
  `never[]`

Helpers introduced in test files (no shared infra):
- `makeSettings(overrides)` in ModelSelectorTab.test.tsx
- `makePromptOverrides(overrides)` in AgentPromptsManager.test.tsx
- `FileBrowserTestOverrides` type alias in FileBrowser.test.tsx
- `makeInboxResponse / makeOutboxResponse` in MailboxView.test.tsx

Verification:
- tsc -p tsconfig.json:        exit 0
- tsc -p tsconfig.app.json:    exit 0
- tsc -p tsconfig.test-check.json (new — includes test files): exit 0
- vitest run:                  9639 / 9641 (2 pre-existing failures
                               in terminal-mobile-keyboard-layout.test.ts
                               unrelated to this work; verified via
                               `git stash` + run on clean HEAD)

Adds packages/dashboard/tsconfig.test-check.json to keep this regression
guard available locally — same as tsconfig.app.json minus the test
exclude.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:59:52 -07:00
gsxdsm
8c554211f3 fix(dashboard): card timer matches stats panel + resizable Changes diff modal
Two related dashboard fixes.

1. Card timer mismatch: the board card timer chip showed only workflow
   runtime (e.g. <1m on FN-2716) while the task detail Stats panel
   reported "Total execution time" of 7m+ for the same task. Cause —
   the slim board listing strips `task.log` to keep payloads small, so
   the card's client-side `[timing]` log scan returned 0. Now the slim
   path aggregates `[timing] … in <N>ms` durations server-side into a
   new `task.timedExecutionMs` field before stripping the log; the
   card prefers this aggregate, falling back to the client scan when
   the full log is loaded (TaskDetailModal). Wire payload stays slim.

2. View Changes diff modal: defaulted to `90vw × 80vh` and was not
   user-resizable. Switched to `min(95vw, 2200px) × min(90vh, ...)`
   default with `resize: both`, persisted via useModalResizePersist
   (`fusion:changes-diff-modal-size`). Mobile keeps fullscreen layout.
   Overlay dismiss switched to the shared `useOverlayDismiss` hook so
   resize-drags that release on the overlay don't close the modal.

Updated the diff modal's regression tests to match the new constraint
shape (still asserts max-height clamps to viewport via calc()).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:55:46 -07:00
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
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
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
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
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
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
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
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
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
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
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
Fusion
9d171d8d32 feat(FN-2665): group consecutive agent log text and thinking entries
- Add render-grouping logic in AgentLogViewer to coalesce adjacent same-agent text/thinking chunks while preserving tool rows
- Keep badge and timestamp rendering at group boundaries and preserve stable render keys for live log updates
- Expand AgentLogViewer tests to cover grouping behavior, markdown/plain-text concatenation, and boundary cases across agents/types/tools
- Stabilize bundled runtime install test by awaiting Hermes Runtime label before querying its card
2026-04-27 03:13:32 -07:00
Fusion
92b8631aad fix(FN-2672): harden automation execution and scheduling flows
- Improve automation startup diagnostics and route handling for manual execution steps
- Add support for full manual automation step execution in dashboard and engine flows
- Expand due-schedule coverage in automation store and dashboard route tests
- Add cron runner regression tests for edge cases and document the automation execution fix via changeset
2026-04-27 03:07:58 -07:00
Fusion
3d9391b076 feat(FN-2669): consolidate mobile fullscreen modal styles
- Move the WorkflowStepManager mobile modal sizing rules into the primary max-width 768px block
- Expand mobile fullscreen behavior to enforce viewport height, remove borders, and zero border radius
- Add mobile wrapping support for step card title/action rows and remove the duplicate trailing media block
2026-04-27 02:36:19 -07:00
gsxdsm
e38a993350 feat(FN-2668): merge fusion/fn-2668 2026-04-27 02:29:40 -07:00
Fusion
ed208452a7 feat(FN-2667): improve login instruction device code handling
- Broaden device-code extraction to support contextual, enter/use, dashed, and short alphanumeric formats
- Auto-copy the device code only when it first appears and keep manual copy feedback behavior
- Move login instruction styles into a dedicated LoginInstructions.css file and remove duplicate SettingsModal styles
- Add LoginInstructions component tests for extraction formats, auto-copy behavior, and copy button state
2026-04-27 02:24:21 -07:00
Fusion
7806724cf2 feat(FN-2664): add dashboard updates check endpoint and settings flow
- Add GET /api/updates/check endpoint in dashboard server with coverage for success, failure, and disabled update scenarios
- Extend legacy dashboard API client with check-for-updates request support
- Add Settings modal update-check UI and styling for trigger, loading, and result states
- Expand Settings modal tests and document the updates check endpoint in architecture docs
2026-04-27 02:19:44 -07:00
Fusion
acbd6580b3 feat(FN-2663): add cached update-check setting, APIs, and banner
- Add global updateCheckEnabled setting to core schema/types and wire dashboard command to cache update checks in the CLI
- Implement dashboard server update-check cache module plus REST routes for status and refresh behavior
- Add dashboard client hook, legacy API helpers, and UpdateAvailableBanner UI to show cached CLI update notices
- Cover update-check server routes, hook behavior, banner rendering, and route registration with focused tests
- Document update-check configuration and API behavior in architecture and settings reference docs
2026-04-27 01:40:07 -07:00
Fusion
1cd40e3592 feat(FN-2661): add keyboard-aware mobile chat layouts
- Add a shared useMobileKeyboard hook that tracks visualViewport overlap on mobile browsers
- Apply keyboard overlap CSS variables to QuickChatFAB so fullscreen mobile panels resize above the virtual keyboard
- Apply the same keyboard-aware sizing to ChatView mobile thread layout and auto-scroll messages when keyboard opens
- Expand ChatView, QuickChatFAB, and hook test coverage for mobile keyboard detection and viewport-resize behavior
2026-04-27 01:22:28 -07:00