Commit Graph

1967 Commits

Author SHA1 Message Date
gsxdsm
ec119677de fix(dashboard): lock ChatView composer with touch-action: none on textarea
A pan-y gesture on the focused textarea still triggered iOS auto-
scroll-into-view, lifting the composer up off-screen even with body
locked. touch-action: none on .chat-input-textarea blocks gesture-
driven panning entirely (tap-to-focus, typing, caret moves still
work) so the composer stays anchored. Trade-off: loses gesture-
scroll within the textarea once content exceeds max-height — minor
since textareas rarely exceed 6 lines in this composer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 21:02:22 -07:00
gsxdsm
4708e453ae fix(dashboard): pin --vv-offset-top to resize/focus, ignore pan scrolls
iOS fires visualViewport scroll events at 60fps during a pan with the
keyboard up. Routing those through React state and into the .chat-thread
translateY(--vv-offset-top) transform amplified the pan into a visible
judder + ~300px shift + body background exposure.

useMobileKeyboard now uses two listeners: a full update (resize +
focusin/focusout) that re-snapshots all metrics including offsetTop, and
a scroll-only update that updates only height/keyboardOpen. offsetTop
is therefore frozen between keyboard open/close events — the transform
correctly compensates for iOS's initial visualViewport shift on focus
without following pan-time movement.

Restores the translateY anchor (so the thread isn't off-screen on
first focus) while keeping the swipe-jitter fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 20:58:04 -07:00
gsxdsm
d5858b44b9 fix(dashboard): drop translateY(--vv-offset-top) on ChatView mobile
The transform amplified jitter during iOS textarea swipes: visualViewport
scroll events updated --vv-offset-top rapidly, the transform followed,
and the thread juddered then shifted ~300px exposing the body background.
Removing the transform leaves the thread where iOS places it; the
height-shrink to var(--vv-height) still constrains it to the visible
area. Trade-off: on initial focus the thread anchor relies on iOS's
own viewport adjustment instead of explicit compensation, but that
beats the swipe-time jitter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 20:54:33 -07:00
gsxdsm
1258e471c1 fix(dashboard): contain iOS rubber-band on ChatView messages and composer
Three scoped overscroll fixes for the ChatView mobile keyboard-up case:

- .chat-messages: overscroll-behavior: contain so edge-swipes on the
  messages list don't bounce the parent / document.
- .chat-input-area: overscroll-behavior: contain so swipes on the
  composer footer don't escape upward.
- .chat-input-textarea: touch-action: pan-y + overscroll-behavior:
  contain so a vertical swipe started on the textarea stays inside
  the textarea (multi-line scroll still works) instead of
  rubber-banding the page and exposing the body background.

User-reported symptom: keyboard up + swipe up on the textarea edge,
the composer shakes and a gray box (body background) partially
covers it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 20:49:42 -07:00
Fusion
31f2998a8e feat(FN-3614): improve mobile keyboard handling in ChatView and GitManager
This merge delivers five major themes: a large mobile chat UX pass (viewport-aware GitManager CSS, compact tool-call layout, keyboard-safe modals, and iterative fixes for the send-button double-fire behavior), a complete refactor of the TaskDetailModal test suite from a 6745-line monolith into eight

Fusion-Task-Id: FN-3614
2026-05-06 20:48:50 -07:00
gsxdsm
a41157545d fix(dashboard): reset scroll on ChatView refocus to undo iOS drift
After dismissing and re-bringing up the mobile keyboard, iOS could
leave window.scrollY > 0 and visualViewport.offsetTop > 0. With
useMobileScrollLock then pinning body{position:fixed} relative to that
drifted scroll, the message thread anchored above the visible viewport
and a large blank area appeared below it.

handleInputFocus now resets window scroll to (0,0) on mobile in a
zero-delay timeout — late enough that iOS finishes its own
scroll-into-view first, but before useMobileScrollLock observes the
drifted state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 20:42:14 -07:00
gsxdsm
7b3a31ec3b fix(dashboard): keep keyboard up on send tap; hide status bar with keyboard
Two mobile chat regressions addressed together:

1) ChatView send button: preventDefault now fires on pointerdown for
   touch pointers, before iOS blurs the textarea. The previous
   onMouseDown.preventDefault was too late on iOS (mousedown is
   synthesized after touchend, by which point the keyboard has
   already started dismissing). Click still runs the action so quick
   taps remain reliable.

2) ExecutorStatusBar: hidden on mobile while keyboard is open,
   mirroring MobileNavBar. The bar is position:fixed against the
   layout viewport, which iOS leaves anchored below the keyboard;
   during a swipe/pan it would slide over the messages list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 20:34:35 -07:00
gsxdsm
f08c8ace24 revert(dashboard): undo imperative visualViewport write in ChatView
The imperative useLayoutEffect approach made mobile worse — first tap
flickered and didn't bring up the keyboard, while the original
swipe-overlap symptom remained. Restoring the previous React-state
flow until a better fix is identified. Removes the changeset that
shipped with the failed attempt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 20:29:12 -07:00
gsxdsm
72691c6fd6 fix(dashboard): write ChatView visualViewport vars imperatively
The mobile composer/footer slid over the message list when the user
swiped with the keyboard up. Cause: --vv-height / --vv-offset-top were
routed through React state via useMobileKeyboard, so on iOS — which
fires visualViewport scroll/resize on the same frame as its keyboard
animation — the .chat-thread translation lagged by one paint, visible
as the composer momentarily floating over messages.

Now those two vars are written imperatively in a useLayoutEffect
directly to the .chat-thread DOM node on every visualViewport event,
mirroring the working pattern at QuickChatFAB.tsx:1032-1052 (which
already works correctly on mobile). Only --keyboard-overlap (a
structural open/close signal, not per-frame) still flows through
React state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 20:25:38 -07:00
gsxdsm
bcfb4a3f62 fix(dashboard): keep mobile keyboard up when ChatView send button tapped
Re-add preventDefault on mousedown so the textarea doesn't blur when
the user taps send — keyboard stays up, no viewport reflow jumping
the input to the top of the screen. The action still runs on click
(which fires reliably from the iOS touch sequence even for quick
taps), so this preserves the previous fix's quick-tap reliability.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 20:19:28 -07:00
gsxdsm
0d3324ad95 fix(dashboard): make ChatView mobile send fire on quick tap
The mobile send button used pointerdown + touchstart with preventDefault
and a focus-preservation dance to keep the keyboard up while sending.
That path silently failed on quick taps on iOS — only a long press
registered. Switching to plain onClick (with touch-action: manipulation
to skip the click delay) fires reliably on tap. The soft keyboard may
dismiss on send now, which is a minor regression vs. the previous
intent but vastly preferable to silent failure.

QuickChat is unchanged because it already works on mobile.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 20:15:30 -07:00
gsxdsm
ca047a714a Revert "fix(dashboard): stop mobile send-button double-fire that aborted chats"
This reverts commit 394b1a655a.
2026-05-06 20:02:02 -07:00
gsxdsm
beb0a1a189 Revert "fix(dashboard): self-clear mobile send/stop dedupe ref so subsequent taps work"
This reverts commit 27d6511af3.
2026-05-06 20:02:02 -07:00
gsxdsm
27d6511af3 fix(dashboard): self-clear mobile send/stop dedupe ref so subsequent taps work
The previous fix introduced a regression: handledMobileSendRef /
handledMobileActionRef was set in onPointerDown/onTouchStart but only
cleared in onClick. preventDefault() on pointer/touch events suppresses
the synthesized click on iOS Safari, so the ref stayed true forever
after the first tap — every subsequent tap (quick OR long press) hit
the new dedupe guard and silently bailed.

Now both handlers schedule a 500ms setTimeout to self-clear the ref
alongside their action. That covers the full pointerdown/touchstart/
click burst from one tap while still letting the next user tap go
through.

Applied to: ChatView send button, QuickChat send button, QuickChat
stop button.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 19:59:38 -07:00
gsxdsm
394b1a655a fix(dashboard): stop mobile send-button double-fire that aborted chats
The ChatView and QuickChat send/stop buttons each had both an
onPointerDown and an onTouchStart handler invoking the action. On a
quick mobile tap both fire, so handleSend / handleSendMessage /
stopStreaming ran twice in rapid succession. The second invocation
closed the first's SSE stream (streamRef.current.close()), the server
treated that as a cancel via beginGeneration, and the chat ended with
no output — exactly matching the reported "tap silently fails, long
press works" symptom (long press happened to suppress one of the two
events).

Both handlers now early-return when the existing handledMobile*Ref
flag is already set, so only the first event for a given tap fires the
action. The send button additionally gets touch-action: manipulation
(removes the click delay that lets the textarea blur win the race) and
an expanded invisible hit area via ::before so slightly-off taps don't
land on the surrounding textarea and dismiss the keyboard without
sending.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 19:55:55 -07:00
Fusion
3819d48134 feat(FN-3574): add setup-aware built-in plugin rows
- Add built-in plugin catalog metadata and constants for shipped installable plugins
- Render a Built-in Plugins section with install, setup-required, and manage states
- Fetch and display plugin setup status, including setup install flow and status badges
- Add PluginManager CSS and tests covering built-in plugin install/setup behaviors

Fusion-Task-Id: FN-3574
2026-05-06 19:55:55 -07:00
Fusion
b9b6d06cad feat(FN-3622): add canonical task-detail timing calculations and stats pane
The merge lands three commits for FN-3622's canonical task timing calculations, adding `taskTiming.ts` logic and stats timing semantics to `TaskDetailModal` and `TaskTokenStatsPanel`, backed by regression tests across those panels and the root `test-changed.mjs` script. The remaining commits introdu

Fusion-Task-Id: FN-3622
2026-05-06 19:55:55 -07:00
Fusion
63492e18fd feat(FN-3605): keep mobile header identity and toggle inline in ChatView
The merge completes Step 2 of FN-3605 by refactoring the ChatView mobile header to preserve its visual identity while converting the toggle control to an inline layout, accompanied by corresponding tests.

Fusion-Task-Id: FN-3605
2026-05-06 18:50:59 -07:00
Fusion
d2b840bd92 feat(FN-3604): add chat unread indicator to header and mobile nav
Implements a chat unread indicator across the header and mobile nav bar, driven by a new unread-response tracker in the app state, with tests and a docs update for the feature.

Fusion-Task-Id: FN-3604
2026-05-06 18:47:25 -07:00
Fusion
dc95aa0357 feat(FN-3600): harden TaskDetailModal pause/unpause async assertions
Hardens async assertions in the task detail modal's pause/unpause action tests, improving test reliability for that interaction flow.

Fusion-Task-Id: FN-3600
2026-05-06 18:44:25 -07:00
Fusion
fbf91c74a9 feat(FN-3596): unify board/list task ordering, split TaskDetailModal test m
The merge introduces a major TaskDetailModal test refactor (splitting a 6.7K-line monolith into five focused suites), significant merger improvements including autostash race-rescue, deduplication, and advisory logging for destructive operations, a new TUI narrow-mode log-split feature for the dashb

Fusion-Task-Id: FN-3596
2026-05-06 18:37:23 -07:00
Fusion
fb7d9b116b feat(FN-3617): align mailbox modal css with design tokens
Updated MailboxModal CSS to use design tokens instead of hardcoded values, and adjusted the co-located test to match.

Fusion-Task-Id: FN-3617
2026-05-06 16:14:29 -07:00
Fusion
ed52c3dff3 test(FN-3591): split TaskDetailModal coverage into focused test suites
- Replace the monolithic TaskDetailModal test file with focused suites by behavior area
- Add shared TaskDetailModal test helpers to reduce duplication across suites
- Keep existing coverage while improving test isolation and maintainability
- Remove the legacy combined TaskDetailModal.test.tsx file

Fusion-Task-Id: FN-3591
2026-05-06 15:57:08 -07:00
Fusion
cea7eec3e8 feat(FN-3585): document post-install plugin capabilities and fix mailbox sp
The merge adds a test isolation script (`scripts/check-test-isolation.mjs`) to filter runtime noise from live Fusion app paths, fixes MailboxModal spacing by replacing hardcoded values with design tokens (FN-3585), and documents post-install plugin capabilities in the plugin management guide (FN-358

Fusion-Task-Id: FN-3585
2026-05-06 15:17:07 -07:00
Fusion
d1549b8dff feat(FN-3576): restore plugin setting group field and grouped agent browser
This merge restores plugin setting group functionality in the dashboard (FN-3576), adds documentation for plugin authoring, and improves test isolation by broadening runtime ignore lists for live fusion app paths in the isolation checker script. The feature touches the PluginManager component with n

Fusion-Task-Id: FN-3576
2026-05-06 14:53:07 -07:00
Fusion
f22db4d1fe feat(FN-3180): add dreams notification event and harden plugin setup sync
This merge lands four features: a new "dreams" notification event exposed through settings and docs (FN-3180), hardened plugin setup sync with test isolation improvements (FN-3573), and feedback-driven enhancements to the native shell connection manager (FN-3402). Core settings schema, the plugin AP

Fusion-Task-Id: FN-3180
2026-05-06 14:42:26 -07:00
Fusion
d8f75202e9 feat(FN-3402): address shell connection feedback in NativeShellConnectionMa
Addressed shell connection feedback for FN-3402 in Step 6, updating the NativeShellConnectionManager component and its test file with expanded test coverage and refinements based on review comments.

Fusion-Task-Id: FN-3402
2026-05-06 14:11:32 -07:00
Fusion
fbdfc5beda feat(FN-3602): compact mobile chat tool-call density and layout
Merged FN-3602: Compact tool-call summaries in the ChatView with responsive mobile layout improvements, including new regression tests and documentation in the dashboard guide.

Fusion-Task-Id: FN-3602
2026-05-06 13:57:30 -07:00
Fusion
8726b022c0 feat(FN-3603): improve mobile chat with jump-to-latest and bubble width fix
This merge implements FN-3603, adding jump-to-latest controls for the chat view and improving mobile bubble width layout, with corresponding CSS updates in ChatView and QuickChatFAB components. It also includes documentation for the new mobile chat controls, a fix for workspace lint regex escaping,

Fusion-Task-Id: FN-3603
2026-05-06 13:38:23 -07:00
Fusion
884b91dfc2 feat(FN-3597): guard board and list column grouping against malformed colum
Merged FN-3597 feature branch adds two-step protection against malformed columns in the board and list views: Step 1 normalizes malformed column data at the core level, and Step 2 hardens the Board and ListView grouping logic to gracefully handle edge cases. The changeset covers test isolation impro

Fusion-Task-Id: FN-3597
Fusion-Task-Id: FN-3607
2026-05-06 13:38:23 -07:00
gsxdsm
9c60eb2821 perf(merger): skip redundant in-merge verification and lockfile-stable installs
Two cuts to wasted work in the merge verification loop:

1. After the in-merge fix agent runs, fingerprint the working tree
   (`git diff HEAD` + `git status --porcelain`, sha256). If the post-fix
   fingerprint matches pre-fix and is non-empty, the agent didn't actually
   change anything — re-running the same failing command can only yield
   the same failure, so log and report the attempt as unsuccessful without
   paying the test/build cost. Empty fingerprints (snapshot tooling failed)
   fall through to the existing re-run path so we never silently swallow a
   real fix.

2. Inside `syncDependenciesForMerge`, hash the active lockfile and compare
   against `node_modules/.fusion-install-marker` (written after each
   successful install). When they match, skip `pnpm install
   --frozen-lockfile` even if `package.json` is staged. Covers the common
   case where `package.json` changes but the lockfile doesn't, and
   amortizes install across auto-recovery re-enqueues that hit the same
   worktree.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 12:24:57 -07:00
Fusion
dec27b790e feat(FN-3601): add eval score categorization and mobile mission CTA styling
This merge lands eval score categorization and evaluator hardening in core/engine, mobile mission CTA improvements with documented behavior, reply-link threading documentation, and a test-isolation fix that tolerates runtime noise on shared HOME directories. Dashboard components affected include Mai

Fusion-Task-Id: FN-3601
2026-05-06 11:24:37 -07:00
gsxdsm
a113e95c35 chore(test-isolation): tolerate live fusion app noise on shared HOME
Local `pnpm test:isolated` was failing because a concurrently-running
fusion app continually mutates `~/.fusion` (databases, agent sessions,
memory, automations, plugins, logs). Filter those runtime-owned paths
from the protected-dir signature, widen the baseline-stability sampling
window, and re-sample on suspected violations so transient app activity
doesn't masquerade as test pollution.

Tests still cannot legitimately write into these paths — they're skipped
because the *running app* is expected to.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 10:39:54 -07:00
Fusion
1ce47fd870 feat(FN-3580): restore canonical agent lifecycle and remove terminated agen
This merge restores the canonical agent lifecycle with termination scoped at the run level (FN-3580, 4 steps), adds sender-side wake recipient override for messages, and introduces test isolation CI enforcement with a stuck-requeue race fix. UI changes remove terminated-agent indicators from AgentDe

Fusion-Task-Id: FN-3580
2026-05-06 10:18:27 -07:00
Fusion
7d02ac81ef feat(FN-3593): add test isolation CI enforcement, fix stuck-requeue race, a
This merge lands five FN-3593 commits establishing a test isolation contract with a new `scripts/check-test-isolation.mjs` guard that scans for accidental `beforeEach`/`afterEach`/`beforeAll`/`afterAll` in setup helpers, plus per-package `setup-test-isolation.ts` bootstraps that canonicalize the pat

Fusion-Task-Id: FN-3593
2026-05-06 09:43:51 -07:00
gsxdsm
890f8853ed feat(messages): add sender-side wake recipient override
Senders can now force the recipient agent to wake on receipt regardless
of the recipient's `messageResponseMode`. Surfaced as a "Wake recipient
immediately" checkbox in MessageComposer and as a `wake_recipient`
boolean param on the `fn_send_message` agent tool. Carried as
`metadata.wakeRecipient: true` on the message; the heartbeat hook
treats forced wakes as `message_received_urgent` in the wake delta so
agents can distinguish them from normal `messageResponseMode: immediate`
wakes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 09:26:15 -07:00
gsxdsm
c17c288cea fix(engine): stuck-requeue no longer clobbers concurrently-recovered tasks
When SelfHealingManager.recoverCompletedTasks moved a task from
in-progress to in-review, the executor's stuck-kill cleanup running in
execute()'s finally block could fire 20s later, see a stale captured
task.column = "in-progress", and overwrite the recovery by tearing down
the worktree and moving the task back to todo with all step progress
reset. Both the outer-finally and step-session requeue blocks (and the
force-requeue setTimeout in markStuckAborted) now re-read the latest
column and skip cleanup entirely if the task has moved past
in-progress/todo.

Adds a new preserveProgressOnStuckRequeue setting (default: true,
toggle in Settings near the Stuck Task Timeout) so stuck-requeue passes
{ preserveProgress: true } to moveTask. Completed step statuses now
survive the bounce so the agent resumes from where it left off instead
of restarting every step from pending.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 09:07:52 -07:00
Fusion
b1204576fd feat(FN-3587): make agent error modal mobile-safe
- Update AgentErrorDetailsModal styles to improve mobile layout and avoid viewport overflow
- Add mobile regression tests for agent modal behavior in agent-modals-mobile coverage
- Extend core modal mobile test suite with AgentErrorDetailsModal safeguards

Fusion-Task-Id: FN-3587
2026-05-06 08:51:23 -07:00
Fusion
3918309e0a feat(FN-3586): fix agent heartbeat auto-claim, inbox read behavior, and age
The merge integrates five commits across the engine and dashboard: it fixes a quick chat icon-tag regression, ensures manual heartbeat runs respond immediately once a run record exists, splits the agents overview label into separate active vs running counts, prevents inbox messages from being auto-m

Fusion-Task-Id: FN-3586
2026-05-06 08:44:54 -07:00
gsxdsm
8231fef06b fix(dashboard): split active vs running counts in agents overview label
The Overview dropdown previously rendered "X active · Y running" where
both X (stats.activeCount) and Y (activeAgents.length) counted agents
whose state was either "active" or "running" — so an agent that was
merely enabled but idle would still inflate the "running" tally. The
label now counts each state distinctly so "running" only reflects
agents that are mid-heartbeat. Adds AgentsOverviewBar.test.tsx to lock
in the new contract.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 08:04:47 -07:00
gsxdsm
c2f3d92b5c fix(dashboard): don't mark agent inbox messages read when user views them
When the dashboard user browses another agent's mailbox (e.g. the CEO's
inbox), opening a message no longer triggers POST /messages/:id/read.
The previous behavior silently consumed the agent's unread state, so the
agent's heartbeat never surfaced the message and fn_read_messages (which
defaults to unread_only=true) returned nothing. Auto-mark-read now only
fires on the dashboard user's own inbox tab. Adds regression tests in
MailboxView.test.tsx and MailboxModal.test.tsx.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 08:01:30 -07:00
Fusion
1231db4a1d feat(FN-3584): add memory file markdown preview to agent detail and log vie
This merge introduces a memory file markdown preview feature (FN-3584) with corresponding documentation, refines the AgentDetailView and AgentLogViewer components in the dashboard, and adds defensive collision handling for worktree operations during manual task moves (FN-3583).

Fusion-Task-Id: FN-3584
2026-05-06 07:52:58 -07:00
Fusion
39623ff015 feat(FN-3583): prevent worktree collisions on manual moves and make heartbe
The merge lands five commits: a fix (FN-3583) that preserves non-tool message boundaries when tools are hidden in CLI bundles, plus hardened test coverage for that regression and bundle asset bootstrapping; worktree collision prevention on manual task moves via a new `worktree-names.ts` module and s

Fusion-Task-Id: FN-3583
2026-05-06 07:38:09 -07:00
gsxdsm
e3ca545a66 fix: make agent error modal taller on mobile so full message is visible from top
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 06:40:44 -07:00
Fusion
409f06c5e3 feat(FN-3553): improve agent creation with native shell connection and onbo
This merge adds a canonical in-dialog AI interview flow for agent onboarding (FN-3553), replacing the old wizard with a multi-step dialog that guides users through creating and reviewing agent prompts before spawning, plus tokenized typography fixes. It also introduces native shell connection handof

Fusion-Task-Id: FN-3553
2026-05-06 05:53:01 -07:00
Fusion
419c6f3b31 feat(FN-3400): add native shell connection handoff, plugin management CLI/l
This merge adds a complete plugin management system (FN-3565) with CLI commands, a loader, runner, and dashboard routes, along with project-scoped auth storage (FN-3544), native shell connection support for mobile (FN-3400) spanning onboarding, connection manager, and remote desktop handoff, and ref

Fusion-Task-Id: FN-3400
2026-05-06 05:29:56 -07:00
Fusion
e518ce0b6c feat(FN-3567): sync allowParallelExecution runtime toggle
Fixes FN-3567 by synchronizing the `allowParallelExecution` runtime toggle in the AgentDetailView component, adding one line to keep the setting in sync.

Fusion-Task-Id: FN-3567
2026-05-06 03:36:02 -07:00
Fusion
94a5dca53c feat(FN-3535): restore terminated agent state and align lifecycle controls
This merge completes the agent terminated state alignment (FN-3535), adding "running → terminated" transition support with consistent styling and lifecycle controls across the heartbeat engine, agent store, and dashboard UI, plus plugin author documentation improvements (FN-3537) and plugin loader t

Fusion-Task-Id: FN-3535
2026-05-06 03:07:27 -07:00
Fusion
c630a94ef8 feat(FN-3564): isolate plugin loader test state to prevent cross-test conta
Refactored plugin-loader tests and implementation to isolate plugin test contamination, improving test independence in `@fusion/core`.

Fusion-Task-Id: FN-3564
2026-05-06 02:14:05 -07:00
gsxdsm
6ab270cfe2 fix(dashboard): wrap mission card stats so counts reflow in narrow sidebar
In a narrow resized sidebar the milestones / features / tasks counts ran
off the card edge because .mission-list__item-summary was a non-wrapping
flex row. Switch it to flex-wrap with split row/column gaps so the stats
reflow onto new lines instead of clipping.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 00:09:33 -07:00