Commit Graph

3351 Commits

Author SHA1 Message Date
gsxdsm
1d2fc99188 fix(tui): keep FUSION header from wrapping under flex pressure
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>
2026-04-25 00:16:46 -07:00
gsxdsm
c1b7990167 chore(release): v0.2.1
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.
2026-04-25 00:16:46 -07:00
gsxdsm
d46aa988cc fix(tui): G jumps to last log; Agents ←/→ switch panes
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>
2026-04-25 00:11:49 -07:00
gsxdsm
21569e6d48 feat(tui): card windowing, log G-jump, header tiny mode, expand-log width
- 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>
2026-04-25 00:07:19 -07:00
Fusion
7fc3334934 fix(dashboard): keep Agents title row on a single line on mobile
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>
2026-04-25 00:03:15 -07:00
gsxdsm
07d7bac165 feat(tui): git view, project-scoped task stats, polished layout/theme
- 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>
2026-04-24 23:32:45 -07:00
gsxdsm
8c9dfc2f56 fix(dashboard): dedupe agents to stop duplicate-key warning storm
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>
2026-04-24 23:22:46 -07:00
gsxdsm
28eef80b26 fix(dashboard): cap useLiveTranscript entries to prevent heap exhaustion
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>
2026-04-24 23:16:29 -07:00
gsxdsm
f44310a46d fix(dashboard): move AgentMetricsBar and ActiveAgentsPanel above the agent collection
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>
2026-04-24 23:12:49 -07:00
gsxdsm
fde1acb3a5 feat(tui): scale up FUSION splash logo with 2× ANSI Shadow variant
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>
2026-04-24 22:56:41 -07:00
Fusion
c039af066c feat(FN-2408): merge fusion/fn-2408 2026-04-24 22:54:44 -07:00
gsxdsm
dbe34bc141 feat(dashboard): polish modal widths, popover usage, onboarding contrast, TUI logo
- 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>
2026-04-24 22:36:07 -07:00
gsxdsm
18bae531de fix(self-healing): use slim listTasks in maintenance recover loops
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>
2026-04-24 22:25:57 -07:00
gsxdsm
c814f3dfbe fix(dashboard): repair desktop modal widths and NodesView CSS regressions
- 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>
2026-04-24 22:25:57 -07:00
Fusion
c871a938c2 feat(FN-2391): add clickable per-file diffs in Git Manager
- 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
2026-04-24 22:25:57 -07:00
Fusion
bafad3d45a fix(dashboard): close SSE connections on outbound backpressure
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>
2026-04-24 22:25:57 -07:00
gsxdsm
4b95ada290 fix(dashboard): close SSE connections on outbound backpressure
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>
2026-04-24 22:02:40 -07:00
Fusion
554353b8c6 fix(FN-2402): preserve onboarding stepper done state on completion
- 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
2026-04-24 21:48:08 -07:00
Fusion
2ef472f551 feat(FN-2398): restore compact project switch in tablet header
- 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
2026-04-24 21:42:07 -07:00
Fusion
20366ee250 feat(FN-2395): style settings panel scrollbars
- 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
2026-04-24 21:08:35 -07:00
Fusion
70d77f8ba6 fix(FN-2396): align directory picker select button styling
- 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
2026-04-24 20:58:45 -07:00
Fusion
4b01c02fb4 fix(FN-2469): show GitHub OAuth instructions during onboarding login
- 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
2026-04-24 20:50:46 -07:00
gsxdsm
5627e71fde chore(release): v0.2.0
Version bump via changesets.
2026-04-24 20:45:05 -07:00
gsxdsm
2bce4a110d chore(dashboard): drop duplicate ChatView.css eager import
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>
2026-04-24 20:43:37 -07:00
gsxdsm
1fba5ea60a fix(dashboard): mobile chat New Chat button placement + merged fn-2469
- 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>
2026-04-24 20:43:22 -07:00
Fusion
2498b7d235 fix(dashboard): chat mobile single-pane, comment-box theme, ChatView FOUC
- 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>
2026-04-24 20:43:21 -07:00
gsxdsm
9664f78077 fix(dashboard): chat mobile single-pane, comment-box theme, ChatView FOUC
- 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>
2026-04-24 20:35:58 -07:00
gsxdsm
1979a72d03 fix(dashboard): repair AgentsView mobile header and reorder actions
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>
2026-04-24 20:28:13 -07:00
gsxdsm
207e97e6b4 feat(cli): TUI grid threshold, narrow agents view, new-task popup, browser launch
- 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>
2026-04-24 20:07:41 -07:00
gsxdsm
21d05d8b26 feat(cli): default focus to logs panel and tighten splash + log row layout
- 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>
2026-04-24 19:46:48 -07:00
gsxdsm
9cf24e7c0c docs: document CSS extraction, test consolidation, and TUI merge
- AGENTS.md: per-component CSS layout, loadAllAppCss test helper, ESLint
  guardrail, lazy view list + Suspense pattern; __tests__/ convention;
  TUI now invoked via fn (no separate @fusion/tui package).
- docs/contributing.md: Dashboard CSS organization + test layout sections;
  workspace package table reflects fn CLI bundling the TUI.
- docs/architecture.md: CSS architecture subsection; updated CLI/TUI
  references to packages/cli/src/commands/dashboard-tui/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 19:43:00 -07:00
gsxdsm
60e5899686 chore: add pi-claude-cli + plugin-sdk __tests__/ dirs (test consolidation)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 19:39:20 -07:00
gsxdsm
6685d832fa chore: consolidate remaining tests into __tests__/ dirs and refactor mocks
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>
2026-04-24 19:39:20 -07:00
gsxdsm
f11800f2c6 refactor(dashboard): split monolithic styles.css into per-component files
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>
2026-04-24 19:39:20 -07:00
gsxdsm
4d43bf8d6b fix(cli): make logs panel cursor visible and auto-follow tail
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>
2026-04-24 19:39:20 -07:00
gsxdsm
b890c57a29 feat(cli): merge @fusion/tui into fn dashboard with Ink TUI
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>
2026-04-24 19:39:20 -07:00
gsxdsm
bce7dbd96f chore: consolidate test files into __tests__/ dirs and clean stray engine artifacts
- 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>
2026-04-24 19:39:20 -07:00
Fusion
ab98cc3719 fix(FN-2484): limit progress visibility to active execution
- 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
2026-04-24 19:39:20 -07:00
Fusion
a8f5591126 feat(FN-2339): add configurable ntfy server support
- 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
2026-04-24 19:39:20 -07:00
gsxdsm
726a12de1c Update README.md 2026-04-24 17:09:42 -07:00
gsxdsm
da20c330c3 Delete .planning directory 2026-04-24 17:02:11 -07:00
gsxdsm
f89167b595 chore(release): v0.1.3
Version bump via changesets.
2026-04-24 15:35:21 -07:00
gsxdsm
86521e2b13 chore: track .changeset/ instead of ignoring it
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 15:34:40 -07:00
gsxdsm
eb5c575688 fix(cli): bundle pi-claude-cli into published package
Drops @fusion/pi-claude-cli from runtime dependencies so
`pnpm install -g @runfusion/fusion` no longer 404s on the unpublishable
private workspace package. The pi extension is staged into
dist/pi-claude-cli/ at build time and resolved relative to the running
module, with the workspace require.resolve preserved as a dev fallback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 15:34:06 -07:00
Fusion
50e25128f6 feat(FN-2389): add task priority controls across dashboard flows
- Wire priority through task creation and update API payloads for dashboard clients
- Add priority selection to TaskForm, New Task modal, and inline create card with default/reset behavior
- Support priority editing and display in Task Detail modal plus non-default priority badges on task cards
- Extend dashboard styles and component tests to cover priority selectors, rendering, and mobile behavior
2026-04-24 15:00:43 -07:00
Fusion
16959811bc feat(FN-2481): align Hermes runtime artifacts and compatibility coverage
- Regenerate fusion-plugin-hermes-runtime build artifacts and manifest metadata for runtime packaging
- Refactor Hermes runtime source into dedicated pi-module, runtime-adapter, and shared type modules
- Expand Hermes and engine plugin-runner tests to validate cross-runtime compatibility behavior
- Update getting-started, settings reference, and Hermes README docs to reflect the current runtime integration guidance
2026-04-24 14:44:04 -07:00
Fusion
9a84bb1e1a feat(FN-2382): finalize presets-first new-agent tab flow
- Split New Agent step-0 into Presets and Custom tabs with presets-first default behavior
- Refine tab layout and styling in dashboard styles to address review feedback and improve responsive presentation
- Expand NewAgentDialog and AgentsView tests to cover tab switching flows and related route behavior
- Update agent documentation to reflect the revised new-agent dialog flow
2026-04-24 14:31:12 -07:00
Fusion
b7b10a6284 feat(engine): allow read of sibling task PROMPT.md/task.json for deps
Agents working on a task that depends on other tasks (e.g. documentation
alignment tasks needing the sibling tasks' specs) were repeatedly
rejected by the worktree boundary when reading .fusion/tasks/FN-NNNN/PROMPT.md,
which also contributed to the malformed-tool-result crash we just fixed.

Add a read-only exception to isWorktreeAllowedPath: the read/glob/grep
tools may access .fusion/tasks/*/PROMPT.md and .fusion/tasks/*/task.json
at the project root. Writes and bash cwd remain restricted.

Update the system-prompt boundary docs (executor.ts) so agents know the
exception exists and stop burning turns re-trying rejected reads.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 14:24:34 -07:00
gsxdsm
097902d922 fix(engine): shape worktree-boundary rejections as proper tool results
wrapToolsWithBoundary returned a bare {ok:false,error} object when an
agent tried to read/write/bash outside the worktree. pi-coding-agent
wraps tool returns into a toolResult message whose content field it
expects to be an array of content blocks; a bare object leaves content
undefined, which later crashes downstream with "Cannot read properties
of undefined (reading 'filter')" — the failure we've been chasing on
FN-2479 and similar.

Return { content:[{type:"text",text:...}], isError:true, ok:false, error:... }
so pi records a valid toolResult block while existing callers that
inspect .ok / .error still work.

Diagnostic evidence: transcript tail for the failing task showed three
consecutive `read` toolResults with content=array(len=0) (normalized
from undefined by our earlier guard) immediately before the assistant
message with stopReason="error".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 14:00:34 -07:00
Fusion
d2da242d21 feat(FN-2380): add fast mode toggle to quick entry
- Add QuickEntryBox state for a Fast toggle and include executionMode="fast" in create payloads when enabled
- Reset fast mode during form reset flows so follow-up creates default back to standard mode
- Add regression tests for fast toggle pressed state and payload behavior across Enter and Save submission paths
- Add tests ensuring fast mode is omitted when inactive and cleared after successful create, Plan, and Subtask flows
2026-04-24 13:51:55 -07:00