Commit Graph

107 Commits

Author SHA1 Message Date
Fusion
4a6b56136b feat(FN-4224): tighten github tracking header to single-row layout in task
Restyles the GitHub tracking header in TaskDetailModal to a compact single-row layout with tighter spacing, adds test coverage for the header layout, and includes a regression verification pass alongside a changeset documenting the change.

Fusion-Task-Id: FN-4224
2026-05-12 17:34:26 -07:00
Fusion
5e74361859 feat(FN-4055): add task ID collision audit script and recovery documentatio
Adds a standalone audit script for detecting task ID collisions, a regression test for store creation collision handling, and documentation of the recovery path; also applies minor UX refinements to ChatView and TaskDetailModal.

Fusion-Task-Id: FN-4055
2026-05-12 17:04:33 -07:00
Fusion
bbfd6a9740 feat(FN-4189): lift chat input height cap and add autosize behavior
Lifts the chat input height cap and enables auto-resize as the user types, improving the chat UX in `@fusion/dashboard`. Includes test coverage for the autosize behavior and a changeset for the `@runfusion/fusion` package.

Fusion-Task-Id: FN-4189
2026-05-12 17:04:33 -07:00
Fusion
056b1a9d6a feat(FN-4179): optimistically clear room composer on send
Implements optimistic room composer clear in the ChatView, providing instant UI feedback when switching rooms without waiting for server confirmation, with accompanying tests and documentation updates.

Fusion-Task-Id: FN-4179

Fusion-Task-Lineage: 0c3588fa-81ca-464b-b001-506c1756d0ea
2026-05-12 17:04:33 -07:00
Fusion
8653a368fe feat(FN-4182): keep keyboard open on first tap of mobile room send button
Fixes a mobile UX bug where the keyboard would dismiss when tapping the room send button for the first time, plus adds a regression test in ChatView to guard against this behavior.

Fusion-Task-Id: FN-4182
2026-05-12 17:04:33 -07:00
Fusion
062b5a9039 feat(FN-4139): add swipe-back navigation to chat, mission, and planning flo
Implements swipe-back gesture support for mobile navigation across ChatView, MissionManager, and PlanningModeModal, wired through a shared navigation history context and covered by a comprehensive test suite (~548 lines of swipe-back tests). A small fixup ensures swipe-back behaves correctly when la

Fusion-Task-Id: FN-4139
2026-05-12 17:04:33 -07:00
Fusion
239f7bf38c feat(FN-4107): persist chat draft auto-save in ChatView
Persist chat drafts to storage in the ChatView component, with accompanying test coverage in a new `ChatView.draft.test.tsx` file.

Fusion-Task-Id: FN-4107
2026-05-12 17:04:32 -07:00
Fusion
24b839bb1b feat(FN-4118): restore last viewed room thread on chat load
Adds chat room scroll anchoring so that when returning to a room, the view stays positioned at the previously visited thread rather than resetting to the top, with test coverage in the rooms suite and a patch changeset for the published CLI.

Fusion-Task-Id: FN-4118
2026-05-12 09:20:39 -07:00
Fusion
10cc5d08ce feat(FN-4054): surface inline chat failures with interactive error referenc
Implements inline chat failure rendering in the ChatView with interactive reference affordances, proper attribution preservation in failure bubbles, and aligned error typing across the chat stream pipeline, with corresponding tests and documentation updates.

Fusion-Task-Id: FN-4054
2026-05-12 07:47:10 -07:00
Fusion
f0d4709c2e feat(FN-4077): fix mobile switcher trigger sizing in ChatView
Fixes the mobile switcher trigger sizing in ChatView by updating CSS dimensions and adjusting the component's conditional rendering logic, with corresponding test coverage added.

Fusion-Task-Id: FN-4077

Fusion-Task-Lineage: 966eafb9-35fd-4ac6-ab4a-42c0e96a2584
2026-05-12 07:47:10 -07:00
Fusion
a2303c67a9 feat(FN-4040): add optimistic room send with failure handling and reconcili
The merge implements optimistic room send with failure recovery in the ChatView and useChatRooms hook, including a reconciliation flow that handles send failures gracefully and documents the UX behavior. The dashboard guide and architecture docs are updated to reflect the new room messaging pattern.

Fusion-Task-Id: FN-4040
2026-05-11 16:51:01 -07:00
Fusion
351702d055 feat(FN-4042): add mobile chat quick switcher to thread header
Added a mobile chat quick switcher accessible from the thread header, with styling for the session dropdown and test coverage. Documentation for the feature was added to MOBILE.md and the dashboard guide.

Fusion-Task-Id: FN-4042
2026-05-11 16:24:08 -07:00
Fusion
e4d071b398 feat(FN-4040): anchor mobile chat views to latest message on show
Anchored mobile ChatView and QuickChat FAB to scroll to the latest message when opened, improving chat tail behavior on small screens; added documentation for this behavior. Also aligned scoped chat manager's pluginRunner typing and expanded test coverage for both components.

Fusion-Task-Id: FN-4040
2026-05-11 15:58:26 -07:00
Fusion
f25cf6e34d feat(FN-4017): add /new command alias for task creation in quick chat
Added a `/new` slash command alias across the chat interface, with interception in ChatView, support in the QuickChatFAB, corresponding tests, and documentation in the dashboard guide.

Fusion-Task-Id: FN-4017
2026-05-11 10:45:24 -07:00
Fusion
ef4aeb253a feat(FN-4011): align room input keyboard handlers
Completes Step 1 of mobile touch-focus parity by aligning room input keyboard handlers in ChatView, with a regression test covering mobile room and direct composer touch-focus behavior.

Fusion-Task-Id: FN-4011
2026-05-11 09:11:19 -07:00
Fusion
0cdc291f44 feat(FN-3950): reuse keyboard-aware room thread container (+3 more)
Commits merged:
- fix(FN-3950): replace graph task rgba highlights with color tokens
- test(FN-3950): add room mobile keyboard anchoring regression coverage
- fix(FN-3950): enable mobile keyboard tracking for room threads
- feat(FN-3950): complete Step 1 — reuse keyboard-aware room thread container

Files changed:
docs/dashboard-guide.md                            |  1 +
 packages/dashboard/app/components/ChatView.tsx     | 11 ++-
 .../components/__tests__/ChatView.rooms.test.tsx   | 88 +++++++++++++++++++++-
 3 files changed, 93 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-3950
2026-05-10 15:33:25 -07:00
Fusion
140d5b97a5 feat(FN-3928): clear room composer after send
Completes the room composer clear-on-send behavior in `ChatView` with regression tests covering the reset flow, plus documentation updates for parity.

Fusion-Task-Id: FN-3928
2026-05-10 15:33:25 -07:00
Fusion
b94fd232a6 feat(FN-3812): add rooms test scaffolds and coverage across core and dashbo
This branch establishes test scaffolding for rooms functionality across core and dashboard, adding test plans, room-specific test files for ChatView, AgentMentionPopup, QuickChatFAB, and core chat routes/stores, while also updating AgentMentionPopup with enhanced room-aware behavior and QuickChatFAB

Fusion-Task-Id: FN-3812
2026-05-10 07:59:40 -07:00
Fusion
772c9f6b24 feat(FN-3906): add Chat Rooms experimental feature with Settings toggle
Added an experimental Chat Rooms feature gated behind a settings toggle in the dashboard. The ChatView rooms UI is now conditionally rendered based on the experimental features setting, controlled via the SettingsModal. Included documentation updates and corresponding test coverage.

Fusion-Task-Id: FN-3906
2026-05-09 20:20:07 -07:00
Fusion
4ecdbf49d3 feat(FN-3898): migrate roadmap plugin vitest config to test.projects
Migrate the Fusion dashboard's vitest configuration to use the new `test.projects` API in the roadmap plugin, with plugin view registration updates and typecheck fixes in the dashboard components.

Fusion-Task-Id: FN-3898
2026-05-09 18:55:28 -07:00
Fusion
271166ad7c feat(FN-3899): add chat rooms with send routing and delete-room UI
This merge delivers chat rooms with room send routing and delete-room UI in the dashboard (FN-3899), including fixes for bundled plugin view imports and a release changeset. Supporting changes include a merger improvement that tightens scope-warning diff base when baseBranch is missing, companies.sh

Fusion-Task-Id: FN-3899
2026-05-09 16:29:11 -07:00
Fusion
1e800594d5 feat(FN-3884): anchor QuickChatFAB and chat messages to latest on layout sh
Merges FN-3884 chat scroll anchoring — ChatView now re-scrolls to the latest message when reopened or when activation transitions occur, with a bounded bottom-anchor helper preventing layout-shift overshoots. QuickChatFAB was updated to wire the new anchoring behavior, and both components gained com

Fusion-Task-Id: FN-3884
2026-05-09 13:49:11 -07:00
Fusion
e7acd2788b feat(FN-3879): add chat room management in ChatView
- Add useChatRooms hook with room lifecycle state and API integration
- Wire ChatView UI for room selection/creation and update room-focused tests
- Tokenize ChatView and TaskCard color usage to align with dashboard design tokens
- Update architecture docs and include FN-3879 changesets for published CLI package

Fusion-Task-Id: FN-3879
2026-05-09 13:21:47 -07:00
Fusion
b33b640d02 feat(FN-3809): normalize mention filtering for underscore handles
Added a `mentionMatching.ts` utility to normalize agent mention filtering across the codebase, fixing the handling of handles containing underscores. Updated `AgentMentionPopup`, `ChatView`, and `QuickChatFAB` to use the new utility, with corresponding tests added including a new `mentionMatching.te

Fusion-Task-Id: FN-3809
2026-05-09 10:31:05 -07:00
Fusion
1abbb10607 fix(FN-3829): recover stale merging status and align chat sidebar search styling
- Add self-healing recovery for stale in-review merging statuses when no active merger owns the task
- Skip merge re-enqueue for tasks already marked with transient merging statuses and add regression coverage
- Wire active merge task ID provider through project runtime for safer stale-status detection
- Use chat-sidebar-search-container in ChatView with matching CSS padding
- Normalize fusion-plugin-reports test script to use local vitest and add changeset for @runfusion/fusion patch

Fusion-Task-Id: FN-3829
2026-05-09 10:31:05 -07:00
Fusion
dd295bdcdc feat(FN-3806): implement rooms create modal and chat sidebar with plugin ro
Adds a rooms feature to the chat sidebar including a new CreateRoomModal for creating chat rooms, with mobile selection handling and search empty-state copy fixes. Also introduces listTasksModifiedSince plugin contract and report plugin scaffold, replacing the removed dashboard roadmap backend.

Fusion-Task-Id: FN-3806
2026-05-09 10:31:05 -07:00
Fusion
365720edb2 feat(FN-3805): remove dashboard roadmap backend, add reports plugin scaffol
This merge extracts the roadmap feature from the dashboard into a new reports plugin scaffold, adds universal web fetch to reviewer/merger/triage agents, and introduces /tasks deep-link routing. The massive file deletions are roadmap backend code and 2,100+ lines of associated tests being removed as

Fusion-Task-Id: FN-3805
2026-05-09 10:31:04 -07:00
Fusion
6f0e167532 feat(FN-3771): add chat bottom-snap behavior and roadmap plugin extraction
Chat UX improvements land first: bottom-snap scrolling behavior is wired into both `ChatView` and `QuickChatFAB`, with comprehensive test coverage added for the components and their underlying hooks; stale-closure bugs in the `useChat` and `useQuickChat` queue-flush handlers are also patched. Roadna

Fusion-Task-Id: FN-3771
2026-05-08 17:59:57 -07:00
Fusion
011ae14aa7 feat(FN-3712): add provider response copy action to chat bubble
The merge delivers four distinct features: a copy-to-clipboard action on provider responses in the chat bubble (FN-3712, with styling and tests across ChatView), richer agent onboarding drafts documented and wired into the dashboard onboarding modal (FN-3555), assigned-agent triage inheritance so ag

Fusion-Task-Id: FN-3712
2026-05-07 11:41:01 -07:00
gsxdsm
6294993dd8 fix(dashboard): block iOS visualViewport pan while chat keyboard is up
Previous textarea-only touchmove listener didn't catch swipes that
started elsewhere (header, composer padding) — those still panned the
iOS visualViewport over the locked document, sliding the composer up.

Replaces it with a document-level non-passive touchmove listener that
fires while keyboardOpen on mobile and preventDefaults all gestures
EXCEPT when the target is inside .chat-messages (the one container
where pan-y should still work). Stops both header-swipe and composer-
swipe from panning the page, while leaving messages-list scroll
intact.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 22:44:16 -07:00
gsxdsm
12b1ace95f fix(dashboard): use non-passive touchmove listener on textarea
React's onTouchMove handler is registered as a passive listener by
default, so the previous JSX-handler preventDefault() was silently a
no-op — drags on the composer still scrolled the input box up.

Attaches the listener imperatively via addEventListener with
{ passive: false } so preventDefault actually cancels the drag. Tap
(touchstart + touchend without touchmove between) is still unaffected,
so first-tap focus continues to work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 22:39:35 -07:00
gsxdsm
6815dd15c2 Reapply "fix(dashboard): block composer drag-pan via onTouchMove preventDefault"
This reverts commit 3478604fac.
2026-05-06 22:37:24 -07:00
gsxdsm
3478604fac Revert "fix(dashboard): block composer drag-pan via onTouchMove preventDefault"
This reverts commit 2bc7aa0151.
2026-05-06 22:36:04 -07:00
Fusion
1de4844369 feat(FN-3575): rebuild plugin system with catalog, settings, and CLI comman
Restores plugin management features across the CLI and dashboard, including a new `plugin available/settings` commands and a refactored PluginManager component that groups built-in plugins (agent-browser, fusion) separately from custom ones, with updated documentation on the plugin authoring guide.

Fusion-Task-Id: FN-3575
2026-05-06 22:17:35 -07:00
Fusion
ad60886794 fix(FN-3624): harden mobile chat keyboard layout behavior
- Update ChatView keyboard spacer styling to keep viewport layout stable on mobile
- Adjust ChatView viewport handling logic to better align chat body with keyboard transitions
- Add ChatView regression tests covering mobile layout and keyboard interaction scenarios
- Add useMobileKeyboard hook tests to lock keyboard metric behavior and prevent regressions

Fusion-Task-Id: FN-3624
2026-05-06 21:55:22 -07:00
gsxdsm
2bc7aa0151 fix(dashboard): block composer drag-pan via onTouchMove preventDefault
touch-action: manipulation is needed on the textarea so iOS registers
first-tap focus reliably, but it also allows pan-y — which let the
user drag the input box up off-screen with the keyboard up.
Cancelling touchmove blocks the drag without affecting tap (a tap
fires touchstart + touchend with no touchmove in between), so the
composer stays locked AND first-tap focus works.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 21:51:40 -07:00
gsxdsm
2ed722ecbd fix(dashboard): allow textarea taps + resync iOS keyboard on page restore
Two fixes for residual mobile chat issues:

1) Textarea touch-action: none was preventing iOS from registering a
   clean tap-to-focus, causing the keyboard to flash up via the
   programmatic focus() in onTouchStart and then auto-dismiss because
   iOS never saw the gesture complete. Switching to manipulation
   allows tap while still blocking pan/zoom — the composer stays
   anchored thanks to overscroll-behavior: contain on its container.

2) On switch-away-and-back the visualViewport metrics could get
   stuck in a half-state (composer pushed up, or blank pane covering
   it). Adding a visibilitychange / pageshow handler on ChatView that
   force-blurs and re-focuses the active textarea makes iOS resync
   the keyboard / vv metrics cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 21:44:39 -07:00
Fusion
c071a3aab5 feat(FN-3423): show task branch metadata on cards
- Render Branch/Base chips in TaskCard when branch metadata is present
- Add responsive TaskCard styles for branch metadata chips using design tokens
- Expand TaskCard tests to cover branch/base rendering and memo comparator branch changes
- Remove unused ChatView focus-preservation refs/callback to resolve lint blockers
- Document branch metadata semantics in task-management docs

Fusion-Task-Id: FN-3423
2026-05-06 21:16:33 -07:00
gsxdsm
21b01f8f56 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
d83fd28065 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
92d40bc519 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
ddf9f03ec8 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
6e38dad1c3 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
da36f8feb4 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
74378dcfc7 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
073c5047ea Revert "fix(dashboard): stop mobile send-button double-fire that aborted chats"
This reverts commit 35ea499e08.
2026-05-06 20:02:02 -07:00
gsxdsm
0c1bca9915 Revert "fix(dashboard): self-clear mobile send/stop dedupe ref so subsequent taps work"
This reverts commit 157865a583.
2026-05-06 20:02:02 -07:00
gsxdsm
157865a583 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
35ea499e08 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
6e0490544a 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