- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
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>
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>
- 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
- 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
- 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>
Sweep 3 of the styles.css split. Five settings-related blocks moved out of
the monolith into a single co-located SettingsModal.css. styles.css 3304 →
2509 (–795 lines).
Blocks moved:
- /* === Settings Layout === */ (194 lines)
- /* === Notifications Settings === */ (28 lines)
- /* === Memory Settings === */ (112 lines)
- /* === Auth Provider Cards === */ +
/* === Provider Connection Status === */ (165 lines combined)
- /* === Settings: Model Presets === */ (93 lines)
- Settings lane badges + descriptions (~27 lines)
Mobile @media rules whose selectors matched the moved blocks were also
migrated into SettingsModal.css's mobile block.
Kept global with documented reasons:
- .auth-status-badge (and color modifiers) — consumed outside settings by
ModelOnboardingModal and ClaudeCliProviderCard.
- .settings-empty-state, .settings-muted, .settings-loading — broad reuse
across BackendConnectionErrorPage, PluginManager, MemoryView etc.
Cross-component imports added: MemoryView.tsx and ModelOnboardingModal.tsx
now import SettingsModal.css to reach memory-* / auth-provider-card classes
they consume.
Test: settings-mobile.test.tsx had two assertions that incorrectly matched
literal pixel values; updated to the actual var(--space-*) token values
present in the rules. Verified live in browser (settings + memory tabs
render cleanly).
styles.css total reduction across the three sweeps: 4551 → 2509 (–45%).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Apply shared button utility classes across PluginManager action controls for consistent dashboard styling
- Move PluginManager mobile responsive overrides into PluginManager.css and update code background fallback to token-based color-mix
- Improve PiExtensionsManager remove controls with touch-target sizing, hover feedback, and descriptive aria-labels
- Stabilize ModelOnboardingModal helper-text assertions by waiting for provider fetch/render state before checking visibility
[k] kills all running vitest processes via pgrep -f. [v] toggles a
sampler-driven guard that SIGKILLs vitest when system memory exceeds
90%, throttled to once per 30s. Auto-kill defaults ON.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add refresh-page actions alongside retry/reinitialize in TerminalModal bootstrap and xterm init error states
- Add terminal error action-group styling so multiple recovery buttons render cleanly
- Extend TerminalModal tests to cover new refresh controls and verify window reload behavior
- Remove unused TaskLogEntry import and drop the stale hooks eslint suppression in dashboard-tui app
- Introduce a new "project-setup" onboarding step between GitHub and first-task actions
- Gate first-task navigation on project selection and add contextual setup-wizard guidance
- Centralize ordered onboarding step definitions in shared state and reuse them for navigation/progress labels
- Extract ModelOnboardingModal styles into a dedicated component CSS file and update tests/mocks for the new step order
- Emit an auth-token recovery event when dashboard daemon calls fail with bearer-token 401 responses
- Render a non-dismissable recovery dialog with set-token and clear-token reload actions
- Keep the recovery overlay topmost while aligning modal markup with shared modal conventions
- Add focused regression coverage for dialog behavior and include a patch changeset for @runfusion/fusion
- BoardView columns now window their card list against the available
rows so the cursor stays visible. Cards beyond the viewport scroll
in via "↑ N more" / "↓ N more" indicators. Fixes the "can't reach
cards in the Done column" bug — selectedIndex was advancing but the
cards were clipped.
- Logs section: G (vim-style, in addition to End) jumps to newest
entry. Lowercase g stays as the global Settings shortcut.
- MainHeader gains two new collapse tiers: cols < 50 renders just
FUSION + the active tab pills (no inactive tabs, no dividers); rows
< 10 hides the header entirely so the row isn't wasted.
- ExpandedLog stretches to width="100%" so the panel keeps its width
when an entry is expanded — was collapsing to content width before.
- Lighter blue palette throughout (cyanBright / cyan); status-mode
grid widened to 5:6 so Stats panel gets ~45% of cols.
- Stats: heap limit always on its own continuation row; bytes
formatted with a space ("450 MB") so a forced wrap, if it ever
happens, breaks after the unit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switch the .agents-view-title flex behavior from wrap to nowrap and apply
white-space: nowrap on the title and its h2, so the Bot icon and "Agents"
label stay on one row and the view-toggle / primary actions push to the
right edge. Drop the dedicated 32px icon-only width override that came from
the previous wrapping layout.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add a Git interactive view (hotkey [t]/[4]): branch + ahead/behind,
recent commits with detail strip, staged/unstaged/untracked files
panel, branches list, worktrees panel, and a [P] push modal with
pre-flight commit list and capture of stdout/stderr. ←→ cycles
status → branches → worktrees → commits → changes; ↑↓ navigates
rows in the focused list. 5s poll while mounted.
- Project-scoped task stats: BoardView pushes its selected project
path into the controller; refreshTUIStats now reads from a per-
project TaskStore via a shared getProjectStore helper. Project
switch triggers an immediate refresh via onBoardScopeChange.
- Unified MainHeader used by status and interactive modes — section
tabs ([1]–[5]) and interactive view tabs ([b]/[a]/[g]/[t]) always
visible; previously the interactive header replaced the main one.
- Logs panel keeps its size when expanding a single entry.
- 'f' cycles severity filter from any panel in status mode.
- BoardView: explicit cross-view shortcuts so g/a/t always switch
views regardless of input-handler ordering.
- BoardView column overlap fix: flexShrink={0} on structural rows.
- TaskCard always shows the title with wrap="wrap"; single short-id
pill, no duplicate id-as-title fallback.
- Stats panel reorg: StatRow helper, bold section headers, narrow-
width wrap for Heap and Memory trailing fragments.
- Lighter blue palette: cyanBright fg accents / cyan active bg /
logo gradient whiteBright → white → cyanBright → cyan → blue.
- System stats sampler: RSS, heap (V8 limit-aware color), external,
CPU%, load avg, system used/free. Heap thresholds scale off
--max-old-space-size automatically.
- Test fixture updated for the new InteractiveData.git block.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add a new /api/git/diff/file endpoint with path and staged query handling, including validation and untracked-file diff support
- Introduce fetchGitFileDiff API client wiring and update GitManagerModal to load diffs for selected staged/unstaged file rows
- Improve file-row UX with active/focus styling, keyboard activation, and guarded async diff loading/error states
- Expand dashboard route and modal tests to cover per-file diff behavior, query validation, and stage/unstage interaction isolation
The global SSE broadcast called res.write() without checking the return
value, so a paused or backgrounded client would silently accumulate
every store event for every entity (tasks, missions, plugins, agents,
chat, ...) into res.outputData until the dashboard process OOMed.
Add a 4 MB writableLength threshold; when exceeded, tear down the
connection so the OS releases the buffer.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Treat the completion view as an effective final step so all prior indicators/connectors remain marked done
- Mark the first-task step as completed before tracking onboarding completion and clear it from skipped state
- Replace hardcoded success colors in setup wizard stepper done styles with theme-aware done status tokens
- Add regression assertions verifying all step indicators and connectors stay in done state on the completion screen
- Render the compact project switch trigger for tablet layouts by gating on compact mode instead of mobile-only mode
- Extend ProjectSelector compact-switch styles to the tablet media range so the trigger and dropdown render correctly beside the logo
- Update tablet header control regression coverage to expect the compact switch affordance and absence of the desktop selector trigger
- Add Header tablet interaction tests covering Escape key, outside click, and project selection closing behavior for the compact switch dropdown
- Add cross-browser scrollbar styling for settings sidebar and content panes using existing design tokens
- Extend settings mobile CSS tests to assert the new scrollbar rules for WebKit and Firefox-compatible properties
- Refactor dashboard TUI app tests to render via React.createElement for compatibility with current test tooling
- Tidy mission e2e mock ID generators to satisfy formatting/quality gate checks
- Switch the DirectoryPicker Select action to shared btn btn-primary classes with explicit button type
- Move select-button padding to component-scoped DirectoryPicker.css tokens and remove hardcoded !important overrides
- Extend DirectoryPicker tests to assert the expected class contract before click behavior
- ChatView mobile: hide the top sidebar header's "New Chat" button on
<=768px and show the existing footer button as a pinned full-width
action with safe-area padding. Both buttons existed in JSX; only
CSS was needed.
- styles.css: comments compose/edit textareas use var(--surface) so
they remain visible against the task detail modal's --card panel
(in light theme --bg and --card both resolve to #ffffff).
- Includes resolved-conflict changes from fusion/fn-2469 in
ModelOnboardingModal and SettingsModal (and the related test).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- ChatView mobile: add @media (max-width: 768px) so the session-list
sidebar goes full-width and the thread is hidden when the sidebar
is visible (and vice-versa). The component already had the state,
back-button (ChevronLeft), and visibility toggling — only the CSS
was missing.
- TaskComments compose/edit textareas now use var(--surface) for
background. The base .spec-editor-feedback uses var(--bg), which
in light theme resolves to #ffffff — the same as the task detail
modal's --card panel — making the comment box invisible.
- ChatView CSS is now imported eagerly from App.tsx so it bundles
into the main CSS file. Previously the lazy ChatView JS chunk
loaded its CSS via an async <link> tag, producing a brief flash
of unstyled chat UI on first render.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mostly mechanical cleanup left over from the earlier test-consolidation pass:
- Update import paths to ../../ for mocks now that test files moved deeper
- Simplify mock setup (drop usePluginUiSlots inline mock, etc.)
- Move engine ipc + runtimes tests into __tests__/ subdirs
- Move dashboard utils tests into __tests__/ subdir
- Refresh fusion-plugin-hermes-runtime/dist artifacts
build-exe.test.ts: spawn-import fix from a parallel branch (resolved during
worktree merge of the CSS extraction work).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Split app/styles.css from ~40k lines down to ~4.5k. Created 56 co-located
component CSS files in app/components/, each imported by its owning .tsx.
The remainder of styles.css holds genuinely global rules (design tokens,
.btn/.card/.modal/.form-input primitives, cross-component @media overrides).
- Lazy-load 13 heavy views (AgentsView, RoadmapsView, NodesView, etc.) via
React.lazy + Suspense; prefetch all chunks on idle so first navigation is
instant. Initial JS bundle: 1.58 MB → 1.16 MB (-26%). Initial CSS bundle:
635 kB → 471 kB (-26%); the rest splits into 13 per-view chunks.
- Add app/test/cssFixture.ts exposing loadAllAppCss() + loadAllAppCssBaseOnly()
so CSS regression tests load the full per-component bundle (mirroring Vite
source order). Migrate 30+ tests off direct readFileSync('../styles.css').
- Enable test.css: { include: [/.+/] } in vitest.config.ts so component CSS
imports actually inject styles in jsdom (fixes getComputedStyle assertions).
- Add ESLint rule (no-restricted-syntax) banning direct styles.css reads in
dashboard test files; points at loadAllAppCss() instead.
- Restore lost utility classes (.text-muted, .text-secondary, .text-dim,
.form-input) and rescue dropped chat tool-call rules into QuickChatFAB.css.
- Mobile fixes along the way: scroll containment for view containers
(min-height:0 + -webkit-overflow-scrolling), QuickChatFAB full-screen on
mobile (with safe-area-inset for iOS home bar), AgentsView single-row
header layout, ActivityLogModal close button on right, model-combobox
z-index above the mobile quick-chat panel.
- Bug fix: SkillsView toggle was display:none which hid the input from the
accessibility tree; replaced with the visually-hidden pattern so screen
readers + getByRole still find the checkbox.
- Bug fix: standalone Delete button in TaskDetailModal for triage-column
tasks (Actions dropdown is hidden in triage state, so previously no way
to delete a freshly-created task without status change first).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Move all co-located *.test.* files into sibling __tests__/ directories so the
layout is consistent across packages (159 renames + content-rewrite moves).
Updates relative imports, vi.mock specifiers, and __dirname/import.meta.url
path resolutions where tests read fixtures from disk.
- Drop tracked tsc-emit alongside engine .ts sources (auth-storage/logger/
skill-resolver/context-limit-detector/pi.{js,d.ts,*.map}). These were
accidentally committed in a merge and the stale pi.js was masking a real
test-mock vs source mismatch (tests imported "../pi.js" and vite preferred
the stale build over pi.ts).
- Add packages/engine/.gitignore to block future src/*.{js,d.ts,map}.
- Refactor plugin pi-module seams (openclaw/paperclip/hermes) to ESM-import
createFnAgent / promptWithFallback / describeModel from @fusion/engine
instead of require()-ing packages/engine/src/pi.js. Adds @fusion/engine to
the two plugin package.jsons that were missing it; exports describeModel
from the engine public API.
- Fix engine test mocks now that they run against current pi.ts: add
ModelRegistry.create static to mocks in pi.test.ts and pi-create-fn-agent
.test.ts; switch three boundary-result toEqual assertions to toMatchObject
so the new content/isError fields don't trip exact-match comparison.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Gate unified progress display in ListView to tasks that are executing or in-progress
- Gate TaskCard progress bar and steps toggle behind the same active-execution visibility rule
- Update ListView and mobile list-card tests to cover hidden progress for non-executing todo tasks
- Expand TaskCard and mobile board tests to assert progress/toggle visibility for executing vs queued states
- Add ntfy base URL to global settings schema/types with persistence coverage and regression tests
- Extend dashboard settings API/routes and Settings modal UI to edit and save a custom ntfy server
- Update notifier runtime to use configured ntfy base URL when sending notifications
- Document the new setting and include a changeset for @runfusion/fusion