Commit Graph

81 Commits

Author SHA1 Message Date
Aron Prins
a5ad2c2a1d fix(FN-000): address startup review feedback 2026-05-11 13:36:51 +02:00
Aron Prins
ac64aa5c87 fix(FN-000): improve local startup UX 2026-05-11 09:52:23 +02:00
copilot-swe-agent[bot]
741fc15963 test(FN-66): stabilize remote provider activation assertion
Agent-Logs-Url: https://github.com/Runfusion/Fusion/sessions/7f615374-c19b-4ab4-8869-f9181ee6cb90

Co-authored-by: gsxdsm <602584+gsxdsm@users.noreply.github.com>
2026-05-10 18:49:46 +00:00
Fusion
1b0f3de9f9 feat(FN-3708): restore narrow logs/system mouse auto-toggle policy and docu
The merge delivers three feature themes: FN-3708 restores and tests a narrow logs/system mouse auto-toggle policy in the TUI app with documentation, FN-3087 adds immediate wake controls for the agent inbox and messaging API routes, and FN-3704 separates plugin lifecycle management from setup probe s

Fusion-Task-Id: FN-3708
2026-05-07 11:00:51 -07:00
gsxdsm
3ae9a85c9b fix(tui): ← returns to main pane from focused log split
Previously ← in the narrow log strip cycled the section (matching n/p),
which was disorienting once the user had drilled into the strip — they
expected ← to back out, not flip them to a different panel. Now ← from
a focused log strip clears the narrow-split sub-focus and returns to
the main pane (System / Stats / Utilities / Settings) where the user
can drag-select tokens or interact with the panel as usual. p/P still
cycle sections in all states; ↑ at the top of the strip and Esc
continue to work as before.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 18:31:19 -07:00
gsxdsm
e624dbb054 fix(tui): re-enable narrow log-split on System without losing UI
Bring back the bottom log strip on the System panel and make sure
nothing that lives in System is dropped when the strip steals rows:

- Render the [Enter] / [c] / drag-to-select hint unconditionally so
  shortcuts stay discoverable when the strip has sub-focus and System
  isn't the keyboard target. The split-aware focus border still tracks
  which pane the keyboard is wired to.
- Move URL and Token to their own full-width rows under the status-chip
  wrap row. Long token values now wrap onto multiple lines instead of
  being truncated or pushed off-panel — the auth token is always
  visible (and selectable) in full.
- Keep mouse reporting OFF whenever System is the active section, even
  when the log strip below has sub-focus, so click-drag selection of
  the token text continues to work.
- Update estimateSystemContentRows to mirror the new layout: greedy
  pack of small status chips, full-width URL / Token rows that wrap by
  ceil(width / inner), and an always-counted hint row. The dynamic
  split sizer now reserves enough rows for the panel in every state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 18:27:18 -07:00
gsxdsm
a217969b39 fix(tui): skip narrow log-split on System panel
System has interactive UI — Enter to open URL, [c] to copy auth token,
and click-drag for token selection — whose [Enter]/[c] hint row only
renders when the panel has focus. Auto-shifting focus into a bottom log
strip on ↓ hid that hint and removed a clear visual path back to the
panel for token operations. Restrict the auto-split to inert sections
(Stats / Utilities / Settings); System keeps the full single-pane view
it had before.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 18:16:58 -07:00
gsxdsm
9b30711b43 feat(tui): split narrow main view to surface live logs
When the dashboard TUI collapses to single-pane mode (narrow width or
short terminal), show a horizontal log strip at the bottom of the screen
while the active section renders on top. The split is content-driven:
the top pane gets exactly the rows it needs to render its section
without truncating (computed from SystemPanel's chip wrap at the current
width, or each panel's known row count for Stats/Utilities/Settings),
and the log strip absorbs every remaining row to maximize log
visibility. Down-arrow shifts sub-focus into the log strip with the
same key bindings as the dedicated Logs section (j/k, Home/G, Enter to
expand, w to wrap, c to copy, f to filter, mouse wheel). Up-arrow at
the top of the strip or Esc returns focus to the main pane.
Right/Left/Tab continue to cycle sections, so the dedicated full-screen
Logs view is unchanged. The split auto-disables if the log strip would
get fewer than 6 rows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 18:11:49 -07:00
gsxdsm
3672022f0c feat(tui): up/down cycle sections on Main; Enter on Logs releases mouse for text selection
Up/Down arrows now cycle the focused panel on the Main page (mirroring
Left/Right), except on the Logs panel where they keep their existing
role of navigating log entries. Expanding a log entry with Enter now
also disables xterm mouse reporting so the user can click-drag to
select the message text; closing the expanded view restores wheel
scrolling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 15:03:45 -07:00
gsxdsm
9f2f1fd450 chore: silence node:sqlite ExperimentalWarning in tests, fix QR mock type
Patch process.emitWarning in the shared vitest setup to drop the
"SQLite is an experimental feature" notice; align the test mock for
getQrPayload with the canonical RemoteQrPayload signature.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:33:26 -07:00
gsxdsm
79bf77bd5e Merge pull request #30 from timothyjlaurent/fix/sqlite-corruption-wal-pragmas
fix: prevent SQLite B-tree corruption with WAL tuning and batched agent logs
2026-05-04 21:20:32 -07:00
gsxdsm
ca4cce4e13 feat(dashboard-tui): auto-toggle mouse mode based on focused panel
Default mouse reporting OFF so click-drag selection works by default —
useful for copying the auth token directly off the System panel without
needing the [c] keyboard shortcut. Auto-enable when the user focuses a
panel that consumes wheel events:

  - Status mode → on while Logs is focused, off elsewhere
  - Interactive → on for Files / Git / Board (which uses wheel in the
    task-detail screen), off for Agents / Settings

Implemented as a useEffect in DashboardApp that maps state.activeSection
+ state.mode + state.interactiveView → controller.setMouseEnabled. [M]
remains a manual override; the next focus change reapplies the auto
policy. Controller's start() now honors initial mouseEnabled rather than
unconditionally writing the SGR enable sequence.

Updated System-panel hint to advertise click-drag selection, simplified
the help-overlay [M] entry, and flipped the createInitialState test
expectation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 18:21:57 -07:00
Fusion
5b453ef71a feat(FN-3329): refine dashboard TUI system panel and setup wizard UX
- Expand dashboard TUI state/controller wiring for system panel interactions and mouse toggle behavior
- Update dashboard TUI app rendering and tests to cover the new panel controls
- Improve SetupWizardModal layout and interaction behavior with matching CSS and test updates
- Restore docs/research.md wording and add a changeset for the published CLI package

Fusion-Task-Id: FN-3329
2026-05-04 17:22:21 -07:00
Timothy Laurent
6fd47416ee merge main: resolve db.test.ts import conflict
Combined both branches: TaskStore import from main + rmSync import
from our branch (needed for fresh DB test cleanup).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-04 14:58:47 -07:00
Timothy Laurent
ff22e48881 fix(tests): resolve 4 failing tests across cli and dashboard packages
- task.test.ts: save/delete GITHUB_REPOSITORY env before
  runTaskPrCreate fallback test so CI env doesn't bypass the
  getCurrentRepo code path
- app.test.tsx: increase waitForFrameContains timeout for ASCII QR
  render from 3s to 6s to accommodate slower CI environments
- remote-auth.test.ts: switch createRemoteSettings default from
  tailscale to cloudflare with a static ingressUrl so
  resolveRemoteBaseUrl doesn't 409 when no tunnel is running

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-04 14:54:55 -07:00
Fusion
4b6c11ff0a docs(FN-3293): finalize stabilization audit documentation
- Add FN-3293 stabilization update section to docs/test-audit-report.md
- Document deterministic test hardening across CLI, dashboard, droid-cli, and core suites
- Update flaky hotspot notes to reflect resolved dashboard retry timeout coverage

Fusion-Task-Id: FN-3293
2026-05-04 13:17:57 -07:00
gsxdsm
50eb39fa70 chore: fix eslint warnings
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 07:08:01 -07:00
Fusion
bd8bf5d827 feat(FN-3205): add changeset documenting TUI memory ordering changes
Merges the changeset documenting the TUI memory ordering feature (FN-3205), completing the final delivery step for this work.

Fusion-Task-Id: FN-3205
2026-05-02 21:48:46 -07:00
gsxdsm
60a2947718 perf(dashboard): replace blocking pgrep execSync with async execFile
Two sync hot paths were stalling the dashboard event loop on a periodic
timer:

1. `pgrep -f vitest` ran via `execSync` in `getVitestProcessIds`
   (`/api/system-stats`, `/api/kill-vitest`) and `killVitestProcesses`
   (TUI memory-pressure check). On a busy machine pgrep walking the
   process table can take 100ms+; execSync blocks the entire Node event
   loop for that duration, so every concurrent dashboard request hangs
   while pgrep runs. The TUI variant fired on every memory-pressure tick
   (~2s when over threshold), the dashboard variant fired on every
   system-stats poll (5s while the modal is open). Both now use execFile
   with a callback wrapped in a Promise.

2. `discoverDashboardPiExtensions` (called from 3 /api/settings/pi-
   extensions routes) did 6+ blocking existsSync/readFileSync calls per
   invocation across legacy and fusion settings paths. Converted to
   fs.promises.readFile/access and parallelized via Promise.all.

Behavior preserved:
- TUI memory-pressure detection still works (sync os.totalmem path
  unchanged); auto-kill still fires on threshold breach.
- The `lastAutoKillAt` 30s re-fire gate is set before the async kill
  starts, so concurrent ticks can't trigger duplicate kills.
- system-stats still polls every 5s while the modal is open and still
  returns vitestProcessCount.
- All 7 system-stats / kill-vitest tests pass; all 6 settings/pi-
  extensions tests pass. Test mocks updated for the (err, stdout, stderr)
  callback signature.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 14:57:54 -07:00
gsxdsm
4b7b1e669e feat(FN-XXXX): scroll TUI panes with mouse wheel
Enable xterm SGR mouse reporting in the dashboard TUI and dispatch
wheel events to the focused pane: task detail logs, Git lists
(commits/branches/worktrees), and Files view (tree or preview).
Mouse mode is enabled after Ink mounts so the leading ESC of wheel
reports never arrives alone — avoiding spurious Esc keypresses. We
omit motion-tracking modes so terminals still own drag gestures and
Shift+drag native text selection keeps working.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 23:18:19 -07:00
gsxdsm
c7ff1b68d4 fix: unify CLI version resolver across TUI and dashboard
The TUI splash/footer and the dashboard /api/health + /api/updates/check
each had their own walk-up resolver with different rules, so they could
report different versions and trigger spurious update-available banners.
Dashboard now uses a direct ancestor walk (matching the TUI's old logic)
and only falls back to the sibling-cli probe for dashboard-source dev
mode; logo.ts delegates to it so there is one source of truth.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 22:37:52 -07:00
gsxdsm
e75a22c656 fix(tui): keep header left edge anchored when remote tunnel is shown
Between 100-175 cols the remote URL pushed the logo/tabs offscreen.
Remote info now sits in a flex-shrinkable, right-justified slot that
truncates. Also paints a solid background on the QR overlay.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 20:47:04 -07:00
gsxdsm
8bbd956fa5 feat(remote): real QR codes, live tailscale URL, TUI status & shortcut
* Replace placeholder /remote/qr SVG (URL drawn as text) with real QR
  rendered via the qrcode package; add format=terminal returning ASCII
  QR for the TUI.
* Resolve the public tailscale funnel URL from captured CLI output
  instead of constructing http://<hostname>:<port> from a configured
  hostname label — that label was never used by `tailscale funnel` and
  produced a non-public URL in the auth/QR link.
* Drop hostname requirement from engine + UI; only target port matters.
* Tighten tailscale parseReadiness to require a URL on the matched line
  so the tunnel manager doesn't lock in `running` before the URL line.
* TUI: poll remote status, show ● tunnel indicator + URL in MainHeader,
  bind Ctrl+Q to a global QR overlay (terminal ASCII), and switch the
  in-Settings K shortcut to render the same ASCII QR.
* Auto-poll remote status in the dashboard while in `starting`/`stopping`
  so the UI flips to running without reopening the modal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 13:20:03 -07:00
gsxdsm
63f21c3c71 feat(tui): stack utilities/settings under stats in wide layout
Why: at ≥150 cols Stats was lifted next to Logs but Utilities/Settings
sat in a separate bottom row. Keep them stacked under Stats in the left
column so Logs gets the full height on the right; Stats flex-grows to
absorb leftover space while Utilities/Settings stay at fixed heights.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 11:31:57 -07:00
gsxdsm
36bc8d0e2a fix(tui): surface visible feedback when copying a log entry
The [c] copy handler was writing a success/failure log entry to the
buffer, but in expanded mode the panel hides the buffer so users got no
indication the copy ran. Add a transient inline "Copied!" flash in both
list and expanded views, and clamp the index to match the display
cursor so the copy never silently misses.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 10:23:55 -07:00
gsxdsm
597295e749 fix(FN-XXX): align tui startup update check 2026-04-29 07:54:45 -07:00
Fusion
ebd3201153 feat(FN-2901): merge fusion/fn-2901
- fix(FN-2901): reset source issue collapse state on task change
- fix(FN-2901): use issue number in collapsed source issue summary
- feat(FN-2901): complete Step 5 — finalize source issue toggle UX
- test(FN-2901): complete Step 4 — verify collapsible source issue behavior
- feat(FN-2901): complete Step 3 — style collapsible source issue header
- feat(FN-2901): complete Step 2 — add collapsible source issue section
- feat(FN-2901): complete Step 1 — update lucide imports
- feat(FN-2729): merge fusion/fn-2729
- fix(engine): prevent auto-merge cooldown loop on unresolvable conflicts
- feat(FN-2911): improve chat attachment compose and preview UX

Fusion-Task-Id: FN-2901
2026-04-28 23:31:23 -07:00
Fusion
83ad6e45ab feat(FN-2921): merge fusion/fn-2921
- feat(FN-2921): complete Step 2 — apply filename-first truncation in change lists
- feat(FN-2921): complete Step 1 — prioritize filename-first path truncation

Fusion-Task-Id: FN-2921
2026-04-28 22:43:51 -07:00
Fusion
fc837ad349 feat(FN-2909): merge fusion/fn-2909
- test(FN-2909): complete Step 2 — add v50→v51 attachment migration coverage
- feat(FN-2914): merge fusion/fn-2914
- feat(FN-2902): merge fusion/fn-2902

Fusion-Task-Id: FN-2909
2026-04-28 22:24:13 -07:00
gsxdsm
4c3e88cfde fix(tui): swap 3/4 panel hotkeys so they match the help text
3 now jumps to Stats and 4 to Utilities, matching the documented
"System/Logs/Stats/Utilities/Settings" order. PANEL_ORDER updated so
prev/next cycle navigation follows the same sequence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 21:59:48 -07:00
gsxdsm
a6e6e36266 fix(tui): always show auth token and report accurate macOS memory usage
Pin the Token chip after URL in the System panel so it stays visible
(wrapping to a new row at narrow widths) instead of being pushed off-panel.
Switch system memory readings to os.availableMemory() so macOS no longer
reports ~96% used by ignoring reclaimable inactive/cached pages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 21:57:47 -07:00
Fusion
6bb919864b feat(FN-2895): merge fusion/fn-2895
- feat(FN-2895): complete Step 7 — documentation and delivery

Fusion-Task-Id: FN-2895
2026-04-28 21:50:27 -07:00
Fusion
58e227e97c feat(FN-2885): upgrade routing controls and task timing UI
- Redesign the task Routing tab with effective-node summary rows, unhealthy node signaling, and direct per-task override selection
- Add robust override update handling (loading/saving states, stale-task guards, clear override action, and in-progress lock messaging)
- Extend TaskCard execution time indicator behavior to in-review cards and add focused regression coverage
- Refresh dashboard tests and styling for routing and node-status presentation, and remove an unused remote settings API import
2026-04-28 14:25:56 -07:00
gsxdsm
dbc5d9d15c fix(tui): swap [3]/[4] hotkeys to Stats/Utilities
The live number-key handler hard-coded [3]→utilities, [4]→stats and
returned early, masking a parallel NUMBER_KEY_ORDER table. Update the
live mapping and remove the dead duplicate handler + constant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 14:25:56 -07:00
Fusion
4a56b1c10f fix(FN-2722): simplify dashboard TUI header and panel switching behavior
- Remove stdout header overlay patching and related frame recovery hooks from the dashboard TUI controller
- Keep panel switching logic lightweight by relying on normal state updates without forced recover cycles
- Adjust status footer and utility/system panel rendering to maintain a single-line, truncation-friendly layout
- Add explicit number-key panel mapping while preserving existing tab/cycle panel order
2026-04-28 14:25:56 -07:00
gsxdsm
4e2131f444 fix: harden cross-platform paths and child-process handling
Replace process.env.HOME fallbacks with os.homedir() in dashboard usage
probes and the hermes plugin profile resolver so unset HOME no longer
yields literal "~" paths. Skip POSIX process-group semantics on Windows
in engine/merger and dashboard-tui's pgrep-based vitest killer. Add
shell: true to npx spawns in CLI skills/extension so .cmd shims resolve
on Windows, and route test:build-exe through cross-env.

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

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 20:05:45 -07:00
gsxdsm
569e1977ab fix(tui): tighten StatusModeSingle spacer threshold to cols<71
Previously the spacer kicked in at cols<68 (top of Logs border was
covered at 68-70) then was widened to cols<72 (which added a gap at 71
where Yoga's flex-column placed the panel correctly without help).
cols<71 is the precise boundary: 68-70 need the 1-row compensation
spacer, 71+ does not.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 18:20:18 -07:00
gsxdsm
61ea16e31f feat(dashboard,cli): update-check frequency, GitHub star button, more resizable modals
Update-check frequency (end-to-end)
- Add `updateCheckFrequency: "manual" | "on-startup" | "daily" | "weekly"`
  to GlobalSettings (default: "daily").
- Backend `performUpdateCheck` honors the frequency: TTL = day/week,
  `manual` returns cache or empty without hitting npm, `on-startup`
  refreshes once per process lifetime then serves cache. `/refresh`
  route forces network regardless.
- Settings → Updates surfaces a working `<select>` for the cadence,
  disabled when auto-checks are off entirely.
- Tests: 4 new cases covering ttlForFrequency mapping, weekly window,
  manual semantics, on-startup once-per-process behavior.

TUI update notice
- Read cached update result synchronously on TUI startup. When an
  update is available, render a yellow notice line on the splash and
  a colored ● next to the version in the status bar.

Settings modal header polish
- Add "Star on GitHub" pill (icon + Star + cached star count from the
  GitHub API, 1h localStorage TTL) and "Help" button (opens project
  Discussions). Both link to the Runfusion/Fusion repo.
- Star button auto-hides after the user clicks it (intent = star),
  tracked in localStorage `fusion:github-star-clicked`.
- Settings → General gets a "Show Star on GitHub button" checkbox so
  users can hide it preemptively. New global setting
  `showGitHubStarButton: boolean` (default true) gates rendering.

More resizable modals
- Task Detail modal: 85vh default, resize: both, persisted via
  useModalResizePersist (key `fusion:task-detail-modal-size`).
- Quick Chat FAB: full 8-direction resize (4 corners + 4 edges) via
  pointer-event handlers; persisted to
  `fusion:quick-chat-size-<projectId>`. Each handle has the right
  cursor + role="separator" for accessibility.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 17:55:15 -07:00
gsxdsm
951223052f fix(tui): redesign Main layout, robust header, panel reshuffle
Header was disappearing in tmux at narrow widths under Logs/Utilities
panels because Yoga's flex-column placed the panel body at y=0 instead
of y=1, overdrawing the header. Synthetic tests at every width show the
layout as correct, but real-tmux log-update tracking drifts over many
state updates and the header gets scrolled off.

- Paint header as an ANSI overlay after every Ink frame write (DECSC/
  DECRC cursor save/restore) — guaranteed at terminal row 1 regardless
  of any layout drift. Skipped during splash so the loading screen is
  uncluttered.
- StatusModeGrid: full-width System on top (4-row pinned, chips wrap if
  needed) + Logs filling the middle + Stats/Utilities/Settings as
  equal-width bottom row. Stats now shows just Process/System rows.
- StatusModeSingle: 1-row spacer only at cols<68 (Yoga edge case at
  very narrow widths shifts content up); 68+ has no spacer per UX.
- Panel/LogsPanel/UtilitiesPanel inner content boxes pinned with
  flexShrink=1 + overflow=hidden so panel intrinsic height can't push
  the frame past terminal rows.
- Each Logs entry wrapped in height={1} Box (when wrap is off) — Yoga
  was sometimes measuring nested Text as taller than 1 row at narrow
  widths.
- Tab "Explorer" → "Files" with shortcut "e" → "f" (preserves
  filter-cycle on Logs panel; switches to Files view elsewhere).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 17:00:43 -07:00
Fusion
9eef425525 fix(dashboard): card timer shows total execution = timed events + workflow runtime
The task card timer chip previously fell back through several metrics
(timed duration → workflow runtime → wallclock), so cards showed only a
subset of execution time. For FN-2714 this rendered <1m on the card while
the stats tab reported >2m of workflow runtime.

The chip now reports the sum of [timing]-tagged log events and workflow
step runtime (matching the new "Total execution time" metric in the stats
panel), with live elapsed for in-progress workflow steps. When neither
metric is recorded, the chip is hidden rather than falling back to
wallclock.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 16:05:50 -07:00
Fusion
4247e78c4e fix(dashboard): prevent foreign-branch diffs after worktree pool reuse
When the worktree-recycle pool reassigned a path to a new task, the old
task's diff endpoints kept reading the new task's branch state — surfacing
unrelated commits as the original task's "files changed" list.

- Clear task.worktree/branch in the merger after the worktree is released
  to the pool or removed, so the path no longer points anywhere.
- Validate the worktree's current branch matches task.branch in the three
  worktree-backed diff endpoints; on mismatch return empty rather than
  diffing against a foreign branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:34:49 -07:00
Fusion
5033114625 feat(FN-2697): add todo task creation with agent picker actions
- Add TodoView controls to create todo tasks directly and optionally assign an agent
- Style the TodoView agent picker dropdown for desktop and mobile interactions
- Add TodoView tests covering todo task creation and agent assignment behavior
- Simplify dashboard TUI status grid sizing to use flexible panel layout
2026-04-27 09:01:32 -07:00
Fusion
92b94594f3 feat(FN-2694): merge fusion/fn-2694 2026-04-27 08:45:49 -07:00
gsxdsm
da3da74f6b fix(tui): keep Main header visible in single-column mode
In StatusModeSingle (cols<80 || rows<20), an active panel whose
intrinsic content exceeds the container could push the frame past
terminal rows under tmux, scrolling the header off the top. Yoga
defaults flexShrink to 0 (unlike CSS), so panels refused to shrink
when wrapped Text grew them vertically.

- Default Panel flexShrink to 1 so panels collapse to fit container
- Pin StatusModeSingle's three rows to explicit heights with
  overflow:hidden, eliminating overflow paths entirely
- Pass availableRows to LogsPanel from the capped middleHeight so
  its rowBudget matches the actual height instead of stdout.rows-11

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 05:16:25 -07:00
Fusion
b969b01b1c fix(FN-2672): harden automation execution and scheduling flows
- Improve automation startup diagnostics and route handling for manual execution steps
- Add support for full manual automation step execution in dashboard and engine flows
- Expand due-schedule coverage in automation store and dashboard route tests
- Add cron runner regression tests for edge cases and document the automation execution fix via changeset
2026-04-27 03:07:58 -07:00
Fusion
c8b27040f9 fix(FN-2657): stabilize TUI logs panel width
- Set explicit column widths in the dashboard TUI logs panel to prevent width jitter during log updates
- Add a regression test covering logs panel width stability across rerenders
- Keep existing layout behavior while eliminating shifting in the logs view
2026-04-27 00:47:47 -07:00
Fusion
70155b0f1d feat(FN-2640): align planning labels across agent log and tests
- Rename Planning/Triage label to Planning in Agent Log model metadata and related assertions
- Map triage agent badge display name to Plan while preserving existing labels for other agent roles
- Update TaskDetailModal and AgentLogViewer tests to match the revised planning terminology
- Stabilize dashboard TUI QR payload test by waiting for label and payload text separately with explicit timeouts
2026-04-27 00:09:53 -07:00
gsxdsm
6e336ffccc fix(tui): recover frame on dim-poll divergence under tmux+ssh
The 2s dim-poll fallback relied on _refreshSize() emitting a 'resize'
event to trigger recovery, which doesn't always propagate under tmux+ssh
— leaving Ink's frame buffer pinned to the old layout until the user
resized again. Extract the recovery body and call it directly whenever
OS-reported dims differ from the last recovered size.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:00:26 -07:00
Fusion
864d55065b feat(FN-2648): merge fusion/fn-2648 2026-04-26 23:51:25 -07:00