- 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
Several layered defenses against the layout occasionally rendering
at the wrong height (header pushed off-screen, content too tall).
Still not fully resolved — flag for further debug — but this
combination materially reduces frequency, especially under tmux/ssh.
* Enter alt-screen on start (\x1b[?1049h), leave on stop. Gives the
TUI a dedicated fullscreen surface that doesn't share scrollback,
so frames taller than the viewport clip cleanly instead of
scrolling the header into shell history.
* Controller subscribes to process.stdout 'resize' and calls
inkInstance.clear() — resets log-update's previous-frame line
count so the next render isn't skewed by a stale clear region.
* App-level resize listener bumps a state counter and the root Box
uses key={`${cols}x${rows}`} so React unmounts and remounts the
whole tree on dimension change, bypassing any Yoga layout cache.
* Root Box gets explicit width={cols} + overflow="hidden" so
overflow gets clipped instead of pushing siblings out.
* StatusBar: Text children now wrap="truncate-end" with
flexShrink={0} on the outer Box. Default wrap="wrap" was letting
long hotkey+URL strings wrap to 2 rows, throwing the row budget
off by 1 — the proximate cause of the 151x46 wedge.
* MainHeader outer Box: flexShrink={0} + overflow="hidden" as
belt-and-suspenders.
* Settings + Utilities side-by-side now match heights: UtilitiesPanel
uses flexGrow={1} (was flexShrink={0}), so cross-axis stretch
applies equally.
* StatusModeGrid receives rows as a prop again (single source of
truth from App's render, instead of each child reading its own
useStdout snapshot).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* HelpOverlay used `key={key}` on each shortcut row, but several keys
legitimately repeat across contexts (`[t]` for Git view AND
Toggle engine pause; `[r]` for Refresh stats AND Refresh agent
detail). React threw "Encountered two children with the same
key" and the overlay crashed. Switch to index-based keys with a
comment explaining each row is unique by position.
* Refresh the help text: unified header tabs, Settings/Files/
Agents ←/→ pane swap, Git push/fetch shortcuts, Files hidden-
files toggle, Logs G jump-to-end.
* Main (status mode) header sometimes vanished after a tmux pane
switch and only resize fixed it. Two fixes:
- Remove the `rows < 10` auto-hide in MainHeader. tmux pane
switches can briefly report stale or zero dimensions, and the
transient `return null` orphaned the header.
- Wrap MainHeader and StatusBar in flexShrink={0} boxes inside
StatusModeGrid/StatusModeSingle (matching the prior
InteractiveMode fix) so Yoga can't squeeze them to 0 rows.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the separate section + interactive tab strips for a single
unified strip: [m] Main [b] Board [a] Agents [g] Settings [t] Git
[e] Explorer. Width tiers tightened to fit every terminal size:
full labels at cols ≥ 90, glyph-only at 50–89, FUSION + active
pill only below 50.
New 'm' shortcut switches to status mode (Main); 's' kept as alias.
Number keys 1–5 still jump to status sections under the hood.
Settings view: ←/→ now switch between list and detail panes,
matching Agents view.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Yoga's default flexShrink: 1 was letting the MiniLogo and tab pills
shrink when the header row's collective content exceeded the
terminal width — driving FUSION onto a second line. Pin every
fixed-content header child (logo, dividers, tab pills, help-hint) to
flexShrink={0}; the trailing flexGrow filler still absorbs slack.
Belt-and-suspenders: wrap="truncate-end" on FUSION so any future
constraint truncates instead of wrapping.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Catch-up commit for the v0.2.1 publish — the prior release script's
git commit step failed silently (allowFail), so the version bumps
and consumed changeset were left uncommitted while the npm publish
still succeeded.
The global "switch to Settings" shortcut matched both g and G, so
uppercase G never reached the logs panel and the vim-style "jump to
end" never fired. Restrict the global handler to lowercase g; G
falls through to the active panel — including the status-mode logs
list (jump-to-newest) and any other scrollable panel that opts in.
Agents view: ← focuses the list pane, → focuses the detail pane,
matching the visual layout. Tab still cycles either direction.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 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>
A duplicate agent id slipping through useAgents (race between initial fetch
and an SSE refresh, or backend pagination edge case) was flooding React with
"Encountered two children with the same key" warnings. With the active panel
re-rendering on every transcript event the warning fired every few ms and
snowballed the console buffer until the page crashed with OOM.
Dedupe by id at the hook (so every consumer benefits) and again in
ActiveAgentsPanel as belt-and-braces.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The hook was prepending every SSE log entry into React state without bound.
Long-lived active agents flooded the array (hundreds of MB) and the dashboard
eventually died with an out-of-memory crash. Cap the buffer at 200 entries —
the UI only ever renders the first 20, so the cap is generous but finite.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Restores the stats-first ordering on the Agents view. Stats (AgentMetricsBar)
and live agents (ActiveAgentsPanel) now render above the tree/list collection
instead of underneath it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the Colossal "888" large-logo variant with a vertically doubled
ANSI Shadow render so the bigger splash keeps the same block-letter
aesthetic as the small variant — the prior variant looked stylistically
inconsistent next to the small block letters. 47 cols × 12 rows.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Resize the dashboard TUI splash logo to scale with the terminal: a Colossal-font variant kicks in on terminals ≥70 cols × 16 rows; gradient palette is now strictly white → blueBright → blue (no cyan/magenta)
- Lower-clip TUI Kanban cards to a single-line title and constrain each column with overflow hidden so cards no longer bleed past the header row
- Center the TerminalModal vertically by overriding overlay alignment via :has() and trimming the modal height
- Match GitHub Import modal width to the file browser modal (90vw / 1600px max)
- Render the Usage indicator as a top-right popover on desktop instead of a centered modal (mobile keeps the full-screen sheet)
- Widen SetupWizard / Model Onboarding modals (540→880px, 560→880px) and replace the washed-out done step indicator background with a solid success swatch
- Drop the duplicate mailbox icon button from the desktop header (view switch covers it; overflow menu still surfaces it on compact)
- Loosen agent health detection: bump the heartbeat grace multiplier 2× → 4× and the staleness floor 60s → 5min so transient ticks don't flag agents Unresponsive
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Batch 2 of runMaintenance() runs ~10 recover passes back-to-back, each
calling listTasks({ column: ... }) without slim. On busy boards this
materializes every task's activity log into memory ~10× per cycle,
walking the dashboard heap toward the 8 GB V8 limit until OOM. The
archive pass at line 610 already had this fix; extend it to the in-progress
and in-review recover passes that only read steps / paused / worktree /
mergeDetails / postReviewFixCount — all included in the slim projection.
Triage recovers are left non-slim because hasLatestSpecReviewApproval
scans task.log to find the most recent spec review; the triage column
is small so the memory cost is bounded.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Move misclassified .mesh-topology, .connect-node, .nodes-view-topology, .node-status-indicator, and pulse-warning keyframe from AgentReflectionsTab.css to NodesView.css; relocate node-related mobile @media rules from SettingsSyncLog.css so NodesView renders standalone
- Add missing CSS import on GitManagerModal so its .gm-* styles load without depending on ScriptsModal being mounted
- Bump desktop max-widths for FileBrowser, Terminal, GitManager, GitHubImport, and WorkflowStepManager modals; raise selector specificity to .modal.X so the base .modal { width: 480px } can't win the cascade
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>
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
- Resolve merge conflicts while preserving current provider grouping and onboarding flow
- Render GitHub login instructions in the onboarding connect CTA while auth is pending
- Add a dedicated test id for the GitHub onboarding instruction message to satisfy regression coverage
A rebase preserved two copies of the eager `import "./components/ChatView.css"`
in App.tsx (one at the top of the imports block, one inline among the
lazy view declarations). Keep the top-of-file copy, remove the inline
duplicate.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 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>
- 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>
The AgentsView mobile header was wrapping onto two rows because
DocumentsView.css carried leaked agents-view-* rules forcing
flex-wrap: wrap on the header/controls/title and width: 100% on the
primary-actions group. Removed those stale overrides so AgentsView's
own mobile rules can take effect.
Header changes:
- Drop the Refresh button.
- Reorder: Bot icon, view-toggle, then primary-actions on the far right
(Controls icon left of New Agent +). Controls is now icon-only with
no text label on every viewport.
- Bump the Bot icon to 24px (was 20) and give its mobile container a
32x32 footprint to align with the view-toggle pill.
- Pin primary-actions to the right via space-between on the controls
flex container; everything stays on one row at <=320px.
Layout: move AgentMetricsBar (stats cards) above the agent collection
so stats sit on top of the list/board/tree/org views.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Lower the multi-panel grid threshold from 100×24 to 80×20 so standard
terminals render the full layout instead of falling back to single-pane.
- Agents view stacks list above detail when cols < 80; Tab focus model
preserved.
- Board view: press [n] to open a centered create-task popup. Title is
edited via ink-text-input; submit calls TaskStore.createTask, refresh
the task list on success.
- System panel: shows the tokenized auth URL alongside the token, says
"no auth" plainly when --no-auth was used, and prompts with
"Press [Enter] to open in browser". Enter (while System is focused)
spawns the platform's URL opener (open / start / xdg-open).
- Tighten log-row layout: each row is now a single Text with inline
spans + fixed-width prefix slot so columns align and the highlight
bar spans the full row.
- Default status section is "logs" so the live feed is what users see
when they run `fn`.
- Drop the ASCII circle brand mark from the splash; FUSION block
letters + tagline + spinner only, pinned to the top-left.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Default activeSection is now "logs" so the live log feed is what the
user sees first when running `fn`.
- Splash drops the ASCII circle brand mark; only the FUSION block-letter
word and tagline remain. The splash always pins to the top-left rather
than centering, so it doesn't shift on resize. Compact terminals show
plain "FUSION" text instead of block letters.
- Log rows render as a single Text with inline-colored spans (marker,
timestamp, level, prefix, message). Prefix sits in a fixed 14-char
slot so the message column aligns across rows, and the selection
highlight now spans the full row width.
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>
The selection arrow on the dashboard TUI's logs panel was rendering for
the wrong row: the list was reversed (newest-first) but selectedLogIndex
is in chronological order, and the viewport was anchored to the buffer's
tail. On a long log buffer the cursor pointed at the oldest entry, which
was always offscreen.
Switch the display to chronological order (oldest top, newest bottom —
matches tail/less/k9s), compute the viewport from the cursor so the
highlighted row is always visible, and surface "↑ N more / ↓ N more"
hints when entries scroll out of view. addLog now keeps the cursor
pinned to the tail when the user hasn't navigated away, so live logs
follow the latest event.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the legacy ANSI-based DashboardTUI with an Ink/React rewrite
under packages/cli/src/commands/dashboard-tui/, delete the standalone
@fusion/tui package, and make `fn` (no args) launch the dashboard.
The new TUI keeps the existing 5-panel status mode (system, logs,
utilities, stats, settings) but adds an interactive mode (b/a/g) with
three views: a kanban board with project picker and per-task detail,
an agents list+detail with state management, and a settings editor.
Bordered focus-aware panels, solid-background help overlay, static
all-blue FUSION splash that adapts to small terminals. DashboardTUI
and DashboardLogSink public API are unchanged so dashboard.ts only
needed import-path updates plus interactiveData/loadingStatus wiring.
Also adds zod to @fusion/dashboard to satisfy a peer dep introduced
by pi-coding-agent 0.70.
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