Commit Graph

3477 Commits

Author SHA1 Message Date
gsxdsm
5e0004cca2 fix(pi-claude-cli): rewrite bare custom tool refs in system prompt to MCP names
Triage system prompts read "MUST call fn_review_spec()" but Sonnet 4.6 routed
through pi-claude-cli writes PROMPT.md and silently skips the call — even with
the addendum explaining the deferred-tool protocol. Confirmed by the FN-2564
agent log: model called other MCP tools (fn_memory_search, fn_task_list) fine
but consistently never reached fn_review_spec, leaving triage looping on
"fn_review_spec was never called" and falling back to zai/glm-5.1 every time.

Rewrite bare `fn_*` (and any non-built-in custom tool name) references in the
system prompt to their `mcp__custom-tools__fn_*` form before sending. The
prompt now literally says "call mcp__custom-tools__fn_review_spec()" so the
model has no inference step, and the deferred-tool reminder Claude Code injects
matches verbatim. Word-boundary safe (won't touch fn_review_specifier) and
idempotent (won't double-prefix already-MCP-named occurrences).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 16:50:33 -07:00
Fusion
cd4cef38fc fix(engine): register grep/find/ls alongside read/bash/edit/write for coding sessions
pi-coding-agent 0.70's createCodingTools preset only includes read/bash/edit/write,
but pi-claude-cli's tool-mapping translates Claude's Glob→find and Grep→grep.
Triage sessions running through Claude CLI hit "Tool find not found" the moment
the model called Glob and looped on the error.

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

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 16:50:33 -07:00
gsxdsm
73ff095ccc fix(engine): register grep/find/ls alongside read/bash/edit/write for coding sessions
pi-coding-agent 0.70's createCodingTools preset only includes read/bash/edit/write,
but pi-claude-cli's tool-mapping translates Claude's Glob→find and Grep→grep.
Triage sessions running through Claude CLI hit "Tool find not found" the moment
the model called Glob and looped on the error.

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

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 16:34:31 -07:00
Fusion
359e08c45c fix(FN-2528): canonicalize Dev Server experimental feature flag
- Treat devServer as a legacy alias of canonical devServerView in Experimental Features
- Canonicalize feature keys when rendering and saving settings to prevent duplicate Dev Server rows
- Preserve enabled-state compatibility by reading either key in useAppSettings
- Add regression tests for single-row rendering, alias normalization on save, and legacy hook behavior
2026-04-25 16:28:46 -07:00
gsxdsm
ad416b5581 fix(pi-claude-cli): teach Claude to call deferred MCP tools by their prefixed names
Claude Code 2.x defers MCP tool schemas behind ToolSearch — tools are listed
but calling them by short name (e.g. fn_review_spec) returns "tool not found"
until ToolSearch loads the schema. Triage system prompts that say "call
fn_review_spec()" leave the model guessing whether to use the bare name or
the mcp__custom-tools__ form.

Append a system-prompt section listing every custom tool with its short and
MCP-prefixed names plus the ToolSearch + call protocol. Drives off the
Context.tools we now already thread through, so plain chats with no custom
tools get no addendum.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 16:23:24 -07:00
Fusion
655169725e fix(FN-2555): restore execution mode updates from task edit flow
- Add explicit executionMode props to TaskForm edit controls and render a Standard/Fast selector in More Options
- Track editExecutionMode state in TaskDetailModal and reset it consistently when opening, canceling, or syncing task changes
- Include executionMode in update payload diffing so standard→fast sends "fast" and fast→standard clears to null
- Add regression tests for TaskForm selector behavior and TaskDetailModal update payload handling
2026-04-25 16:01:49 -07:00
Fusion
9d8852e26a feat(FN-2496): add overlap ignore paths support to scheduler settings
- Add overlap-ignore path validation and typed settings support in core schema
- Apply overlap ignore paths in scheduler overlap detection with dedicated engine tests
- Add Settings modal UI and routes handling for overlap ignore paths including path-picker feedback fixes
- Document overlap ignore paths in storage/settings docs and include a changeset for @runfusion/fusion
2026-04-25 15:48:36 -07:00
Fusion
d028b41164 feat(FN-2552): distinguish workflow failed dots in task progress
- Add a workflow-failed dot modifier class for failed workflow checks in TaskCard
- Apply ws-warning styling to workflow-origin failed steps while keeping regular failed steps unchanged
- Update TaskCard rendering logic to append the workflow-failed class only for workflow failed items
- Expand TaskCard tests to verify class assignment for regular failed, workflow failed, done, and pending dots
2026-04-25 15:44:24 -07:00
Fusion
f589359e83 fix(FN-2551): normalize mailbox mobile header control sizing
- Consolidate mobile mailbox header-actions rules for modal and view layouts with tokenized spacing
- Enforce 36px minimum height/width for action buttons and icon controls on mobile
- Normalize modal close control mobile padding and radius for consistent alignment
- Add CSS contract assertions in MailboxModal and MailboxView tests for spacing and control dimensions
2026-04-25 15:37:02 -07:00
gsxdsm
825fecbb35 fix(extensions): always prefer vendored @fusion/pi-claude-cli over external installs
When users have an external pi-claude-cli (e.g. a global `npm install -g
pi-claude-cli`, or `npm:pi-claude-cli` in ~/.pi/agent/settings.json packages),
pi's extension discovery loaded the upstream copy and shadowed our fork. The
upstream has a once-and-lock MCP-config bug that throws "Extension runtime not
initialized" during early streamSimple calls and never recovers.

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

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 15:25:08 -07:00
gsxdsm
d4c4137d83 feat(FN-2535): merge fusion/fn-2535 2026-04-25 15:21:28 -07:00
Fusion
4b51161310 fix(FN-2534): prevent dismissed background sessions from resurfacing
- Add dismissal tombstone tracking in useBackgroundSessions to ignore stale refresh, sync, and SSE updates for dismissed session IDs
- Treat terminal session states consistently and broadcast completion on dismiss so local/session-sync state remains converged
- Keep lock-conflicted planning cancellations visible instead of falsely dismissing the session when another tab owns the lock
- Expand useBackgroundSessions regression tests to cover stale sync/SSE resurrection, refresh behavior, lock-conflict handling, and newer-authoritative restore paths
2026-04-25 15:17:52 -07:00
Fusion
04d859be37 feat(FN-2527): add bulk actions for in-progress and in-review columns
- Extend column action menus beyond Todo to include In Progress and In Review
- Add Stop All action that pauses only non-paused tasks with confirmation and success/error toasts
- Add Move All to Todo action with confirmation and partial-failure handling for bulk moves
- Thread pauseTask through useTasks, App, and Board so column menus can trigger task pausing
- Expand Column tests to cover new menu actions, disabled states, and bulk operation behavior
2026-04-25 15:11:54 -07:00
gsxdsm
1872abc1d0 fix(pi-claude-cli): source MCP tool list from session Context, not pi.getAllTools
The previous fix regenerated the MCP config per call but still pulled the tool
set from pi.getAllTools(), which depends on the runtime binding being scoped to
the right AgentSession. Engine-spawned triage/executor sessions register custom
tools (fn_review_spec, fn_review_step) and pi-ai already passes those to the
provider via Context.tools — that's the authoritative per-session list and
bypasses any binding ambiguity. Falls back to pi.getAllTools() when the caller
doesn't populate Context.tools.

Also logs the tool names on refresh so missing tools are diagnosable from stderr.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 14:31:15 -07:00
gsxdsm
1a8058f334 feat(FN-2501): merge fusion/fn-2501 2026-04-25 14:24:35 -07:00
gsxdsm
633644a665 chore: clear pre-existing lint warnings
Annotate the intentional NUL-byte regex in log-sink, drop two stale
eslint-disable directives whose underlying any-uses are gone, and swap
@ts-ignore for @ts-expect-error in routes.test.ts.

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

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

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 14:13:30 -07:00
gsxdsm
e8aab69c67 fix: regenerate pi-claude-cli MCP config per session and auto-sync skill tools
The MCP config was generated lazily once and locked, so engine session-scoped
tools (fn_review_spec, fn_review_step) never reached the Claude CLI subprocess
and triage/executor sessions failed with "unknown tool" errors. Now the config
is hashed per call and rewritten when the tool set changes.

Also adds scripts/sync-fusion-skill-tools.mjs to regenerate the SKILL.md
tool-categories block from extension.ts at build time, with a --check mode
wired into skill-sync tests so drift fails CI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 14:10:56 -07:00
Fusion
c597dd4055 fix(FN-2492): polish plugin manager bundled runtime UX
- Add a Bundled Runtime Plugins section with one-click install actions, install-state badges, and empty-state discoverability improvements
- Refine plugin detail semantics and controls by tightening heading hierarchy, button variants, and mobile/toggle styling behavior
- Expand PluginManager test coverage for bundled runtime installation, installed-state disabling, and heading-level accessibility contracts
- Clean up dashboard CSS ownership by removing duplicated global/toggle rules, updating surface-hover usage, and documenting bundled runtime discovery in settings docs
2026-04-25 13:46:00 -07:00
Fusion
6461108a05 feat(FN-2516): show app version in settings modal
- Add typed health endpoint helper in dashboard API for retrieving status metadata
- Fetch dashboard health in SettingsModal and render a non-blocking version label in the modal header
- Add settings modal heading/version styles to support the new header layout
- Expand SettingsModal tests to cover successful version rendering and graceful failure behavior
- Add mobile settings test coverage for displaying the version label
2026-04-25 13:38:49 -07:00
Fusion
d65b75d4b2 fix(FN-2513): anchor mobile toasts below header
- Move mobile .toast-container positioning from bottom offset to top offset beneath the fixed header
- Tokenize horizontal toast spacing on mobile using var(--space-sm) instead of hardcoded pixel values
- Update utility mobile CSS regression test expectations for top anchoring and auto bottom behavior
2026-04-25 13:25:52 -07:00
gsxdsm
dfb566ebc6 feat(FN-2508): merge fusion/fn-2508 2026-04-25 13:21:02 -07:00
Fusion
20635652bc feat(FN-2511): unify task card footer metadata row
- Refactor TaskCard to compute files-changed metadata once and render it through a shared footer slot
- Render elapsed time chip in the same footer row as file-change metadata when either element is present
- Update TaskCard styles to add a reusable .card-footer-row layout and align the timer chip to the row end
- Add regression coverage asserting files-changed and timer chips coexist in one footer container
2026-04-25 13:17:47 -07:00
Fusion
f560af593a feat(FN-2512): add elapsed timer chip to task cards
- Derive task elapsed time from columnMovedAt with updatedAt/createdAt fallbacks and guard against invalid or future timestamps
- Render a clock-based timer chip on in-progress and done cards with accessible labeling and tooltip metadata
- Add TaskCard styles for the timer row/chip using design tokens, including mobile-size adjustments
- Expand TaskCard tests to cover visibility by column, invalid timestamp suppression, boundary label formatting, and 30s live refresh cadence
2026-04-25 13:12:01 -07:00
Fusion
ff6a68bac4 fix(FN-2510): harden skills catalog fallback for short and invalid queries
- Update skills adapter fallback logic to handle empty and short catalog queries without surfacing 400 failures
- Handle ApiRequestError paths in SkillsView so invalid-query responses degrade gracefully in the UI
- Add regression coverage for adapter, routes, and SkillsView behavior across empty/short query cases
- Document short-query catalog behavior in the dashboard guide and include a patch changeset for @runfusion/fusion
2026-04-25 12:40:32 -07:00
gsxdsm
1d3d7438ff feat(FN-2506): merge fusion/fn-2506 2026-04-25 12:21:33 -07:00
gsxdsm
944f2dedda feat(FN-2503): merge fusion/fn-2503 2026-04-25 12:20:35 -07:00
Fusion
8c7f03246c fix(FN-2504): remove hardcoded workflow step and stabilize dashboard timeouts
- Stop injecting a hardcoded Browser Verification option in WorkflowResultsTab and rely only on fetched workflow step definitions
- Normalize workflow step checkbox test IDs to be id-based for all options, including template-backed Browser Verification steps
- Extend WorkflowResultsTab coverage to assert Browser Verification renders exactly once when provided by API data
- Increase dashboard Vitest timeout defaults and update the slow route test timeout to reduce flaky failures under concurrent workspace runs
2026-04-25 12:18:55 -07:00
Fusion
1b3994f1e0 fix(FN-2500): improve terminal modal sizing and input behavior
- Widen the desktop terminal modal to improve usability and align with UX review feedback
- Stabilize terminal input lifecycle handling to avoid focus and interaction regressions
- Add regression coverage for terminal modal input behavior and mobile keyboard layout scenarios
- Include a changeset documenting the terminal modal desktop width and input fixes
2026-04-25 12:14:50 -07:00
gsxdsm
de6cca1a0c feat(FN-2499): merge fusion/fn-2499 2026-04-25 11:50:35 -07:00
gsxdsm
7f5ffc5920 chore(release): v0.2.7
Version bump via changesets.
2026-04-25 11:38:48 -07:00
gsxdsm
d9072a4db6 chore(dashboard): drop unused --bg-tertiary fallback on plugin install hint
The fallback pointed at a token that doesn't exist in any theme; the
color-mix expression was already the intended value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 11:38:05 -07:00
Fusion
adbad8afca feat(FN-2493): add plugin add alias and normalize install guidance
- Route "fn plugin add" to the plugin install handler and update CLI help/usage text to document the alias
- Add bin routing tests that cover plugin add/install parity and updated error/help messaging
- Update getting-started, settings reference, and runtime plugin READMEs to standardize plugin installation examples
- Add a patch changeset for @runfusion/fusion and apply DirectoryPicker/PluginManager design-token styling refinements
2026-04-25 11:28:33 -07:00
Fusion
79b73c343c fix(FN-2498): keep New Task more options collapsed by default
- Add an autoExpandMoreOptionsOnSelection prop to TaskForm and gate advanced-section auto-expansion behind it
- Disable auto-expansion in NewTaskModal so default-on workflow step preselection does not open More options on first render
- Mark collapsed advanced content with the hidden attribute to prevent interaction until expanded
- Add dashboard tests for default collapsed state, opt-out auto-expand behavior, and default-on workflow-step regression coverage
- Replace hardcoded spacing/transition values in NewTaskModal.css with design tokens
2026-04-25 11:21:35 -07:00
gsxdsm
a8124da1ff fix(dashboard): replay buffered planning thinking events on first connect
The /planning/:sessionId/stream route only replayed buffered events when
the client sent a Last-Event-ID (resume case). On a fresh subscription it
just attached as a live subscriber. On slower devices (mobile especially),
the agent often streamed several thinking deltas into the buffer before
the SSE connection finished establishing — so the user saw the spinner
sit there, then a question appear out of nowhere, with no streaming
"thinking" content.

When a session has no current question or summary yet (i.e. the agent is
generating its first response) and the client connects without a
Last-Event-ID, replay every buffered event before attaching the live
subscription. This catches up the user on the in-flight thinking stream.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 11:17:43 -07:00
gsxdsm
59306284e6 fix(dashboard): nudge footer folder icon up and left for better text alignment
Apply a 2px-left / 1px-up transform to the bare folder toggle so it sits
flush with the surrounding status-bar text on desktop. Touch-target sizing
on coarse pointers / mobile is unaffected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 11:12:35 -07:00
gsxdsm
904ed2fbdc feat(FN-2497): merge fusion/fn-2497 2026-04-25 11:10:51 -07:00
Fusion
b19b0005ef feat(FN-2494): add responsive split-pane mailbox view
- Render mailbox in split-pane mode with message list and detail panes on desktop layouts
- Update mailbox modal styling for desktop pane sizing, separators, and responsive behavior
- Preserve single-pane mobile mailbox flow while adapting interactions for split view states
- Expand MailboxView tests to cover split-pane rendering and responsive mailbox behavior
2026-04-25 11:10:10 -07:00
gsxdsm
54bc60bb8a fix(dashboard): stop the planning textarea from reverting to the persisted description on every keystroke
The "restore description from localStorage" branch ran inside an effect
whose deps included handleStartPlanning, and that callback regenerated on
every change to initialPlan. So every keystroke would re-fire the effect,
hit the same `getPlanningDescription` value, and overwrite what the user
just typed.

Guard the restore with a one-shot ref so it only runs the first time the
modal opens, and reset the ref when the modal closes so a future re-open
still picks up an updated persisted value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 11:01:36 -07:00
gsxdsm
56e0860da1 fix(dashboard): align footer folder icon with surrounding text on desktop
Removed the always-on 40px touch-target sizing from the folder toggle so the
icon sits at the same baseline as adjacent status-bar text. Touch targets
are still applied via @media (pointer: coarse) and (max-width: 768px) so
mobile keeps a tappable hit area. line-height: 1 prevents the icon's box
from inheriting status-bar text leading.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 10:59:31 -07:00
Fusion
beb3e7e7fb feat(FN-2487): refine model dropdown spacing and provider icons
- Define a stable spacing contract for custom model dropdown rows and related settings UI layout
- Add kimi-coding alias support in provider icon mapping so model rows render the correct icon
- Add regression coverage for dropdown spacing hooks and provider icon alias behavior
- Include the tabbed Plugins settings consolidation from FN-2443 in the squash context
2026-04-25 10:57:22 -07:00
gsxdsm
79ea99fb7a fix(dashboard): make File Browser, Git Manager, GitHub Import modals proper full-screen sheets on mobile
All three were declared as 100vw/100dvh on mobile but the .modal-overlay
default still applied 10vh top padding, leaving them pushed below the
viewport edge with a sliver of overlay showing on top. Override
.modal-overlay:has(.X) to drop padding and stretch to fill, and explicitly
zero out border/radius/margin on the modal itself so the sheet truly
covers the screen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 10:56:41 -07:00
gsxdsm
6f45b649f2 feat(FN-2473): merge fusion/fn-2473 2026-04-25 10:55:50 -07:00
gsxdsm
e543dabe91 fix(dashboard): drop the border around the footer folder toggle
The status-bar folder-toggle button had a 1px border + radius that made it
look like a chip. Per request, render it as a bare icon — transparent
background, no border. Hover now only shifts the icon color, the active
state drops to color only, and focus-visible still draws a focus ring with
border-radius applied so it remains a clean halo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 10:55:06 -07:00
gsxdsm
8c632a47b3 fix(dashboard): show planning thinking output and silently recover from stream errors
Two related planning-mode issues:

1. The streaming "thinking" panel only showed for models that emit explicit
   thinking_delta events (e.g. Anthropic Extended Thinking). For every other
   model the user saw a spinner with no streaming content because text_delta
   was being accumulated server-side without being broadcast over SSE. Now
   onText also forwards deltas through the same stream channel so any model
   surfaces its in-flight output.

2. Returning to the planning screen after the browser tab was backgrounded
   long enough for the SSE socket to time out would land the user in a
   permanent error view ("Session failed while contacting the AI") even
   though the server session was still alive. The onError handler now first
   re-fetches the AI session row; if the server still reports the session as
   generating or awaiting_input it silently reconnects without surfacing the
   transient error. Only genuine server-side failures still surface.

Tests for the obsolete manual-retry recovery path were rewritten as
auto-recovery assertions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 10:50:54 -07:00
Fusion
d881695ab9 feat(FN-2445): merge fusion/fn-2445 (auto-resolved)
- feat(FN-2445): complete Step 1 — header project trigger context
- fix(FN-2445): complete Step 4 — remediate UX gate feedback
- fix(FN-2445): ignore inspector URLs in preview detection
- feat(FN-2445): complete Step 2 — add footer project directory toggle
- feat(FN-2445): complete Step 1 — show project name in selector trigger
- feat(FN-2488): add terminal refresh fallbacks for terminal startup failures
2026-04-25 10:50:32 -07:00
Fusion
eaa80587a3 fix(FN-2491): align auth actions in mobile settings modal
- Import SettingsModal.css directly in SettingsModal to ensure extracted styles load reliably
- Adjust mobile auth provider layout so non-info header actions stay right-aligned
- Align API key controls to the right on mobile by updating section, row, and button alignment rules
- Extend mobile CSS regression assertions to cover the new auth alignment rules
2026-04-25 10:46:35 -07:00
Fusion
fcbd650a6b feat(FN-2443): unify plugin settings into tabbed Plugins section
- Remove the standalone Pi Extensions section from settings navigation and route legacy initialSection values to Plugins
- Add accessible subsection tabs in Plugins for Fusion Plugins and Pi Extensions with proper tab/tabpanel semantics
- Render plugin content conditionally per active subsection so only the selected manager is mounted
- Add SettingsModal tests covering sidebar navigation, tab accessibility, and subsection switching behavior
- Add subsection styling in SettingsModal.css and preserve extracted styles.css boundaries
2026-04-25 10:39:15 -07:00
gsxdsm
147419022e chore(release): v0.2.6
Version bump via changesets.
2026-04-25 10:21:52 -07:00
gsxdsm
6ff1617c39 fix(dashboard): repair lint+test regressions from CSS sweep and panel rearrange
- eslint: ignore .claude/** so agent worktree scripts don't pull thousands of
  spurious "console/process is not defined" errors into the workspace lint.
- AgentsView: lift the controls popup max-height/overflow into a CSS modifier
  (.agent-controls-panel--scrollable) instead of an inline style so the
  inline-style discipline test stays at 4 (only runtime health colors).
- board-mobile.test: scan every @media (max-width: 768px) block in the loaded
  CSS bundle, not just the legacy section in styles.css. After the cards/
  inline-create extraction those rules now live in component CSS files.
- AgentsView.test: update the layout assertion for the new "stats above the
  collection" placement and open the controls popup before asserting on
  the token-usage panel (which now lives there, not in the main view body).
- agents-view-mobile.test: open the controls popup before asserting on the
  token-stats panel content.
- TaskDetailModal.test: bump tab-count assertions from 7→8 (or 6→7 for
  triage/todo) to include the new Stats tab, and switch to the Stats tab
  before asserting on token-usage text in the optimistic-loading suite.
- Column.test: add MoreVertical/ChevronDown/ChevronUp/Archive to the
  lucide-react vi.mock so the new column dropdown menu renders.

After this: pnpm lint = 0 errors, pnpm typecheck = clean, pnpm test = all
9132 dashboard + plugin/engine/cli/desktop/mobile/core tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 10:21:03 -07:00