Commit Graph

2335 Commits

Author SHA1 Message Date
Fusion
cc02def488 feat(FN-3711): add inline fast mode toggle and wire shared state in peer ex
This merge introduces several dashboard and engine improvements: agent inbox wake controls (FN-3087, FN-3588) with immediate message triggers; separated plugin lifecycle from setup probe state (FN-3704); assigned-agent triage inheritance in the engine (FN-3703); inline fast mode toggle in the task d

Fusion-Task-Id: FN-3711
2026-05-07 11:54:41 -07:00
Fusion
24325cd3c1 feat(FN-3710): retry overlap-class cluster create failures in distributed t
Adds retry logic for distributed task ID overlap conflicts across the cluster, hardening the ID allocator with exponential-backoff recovery, wiring the retry into task workflow registration, and documenting the behavior in architecture docs. Minor CSS tokenization on the Mailbox and Plugin Manager m

Fusion-Task-Id: FN-3710
2026-05-07 11:48:25 -07:00
Fusion
a98e5aac1a 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
Fusion
e60c8c3c5a feat(FN-3555): document richer onboarding drafts in agents.md and dashboard
Documents richer onboarding drafts in agents.md and updates the dashboard README with a small addition, completing Step 4 of the onboarding feature.

Fusion-Task-Id: FN-3555
2026-05-07 11:25:01 -07:00
Fusion
a01aa31ab8 feat(FN-3704): separate plugin lifecycle from setup probe state
Fixes a bug where plugin lifecycle operations were incorrectly gated by the setup probe state, separating the two concerns across the API, PluginManager component, routes, and tests, with updated documentation.

Fusion-Task-Id: FN-3704
2026-05-07 10:48:28 -07:00
Fusion
0efba0890f feat(FN-3588): add immediate wake controls for agent inbox and message API
The merge delivers four major bodies of work. The dominant theme is FN-3588, which adds an "immediate wake" override to the message inbox API, exposes it in the MailboxModal UI, and updates `agent-heartbeat.ts` and `executor.ts` to honor the override alongside timer/signal triggers. FN-3705 gates re

Fusion-Task-Id: FN-3588
2026-05-07 10:41:11 -07:00
Fusion
1c0aef28cd feat(FN-3702): fix todo mobile layout keyboard handling and modal row heigh
This merge lands a comprehensive testing suite quality overhaul: new browser layout smoke tests, reverse-dependent test coverage, hardened local test infrastructure, and documentation of the agent test workflow, alongside a mobile keyboard-safe TodoView layout fix.

Fusion-Task-Id: FN-3702
2026-05-07 10:27:48 -07:00
gsxdsm
3948a49eea Merge pull request #51 from Runfusion/codex/testing-suite-quality-prd
test: harden and slim local test workflow
2026-05-07 10:18:35 -07:00
gsxdsm
e3f2e4c3be fix: resume distributed task ID counter past existing IDs; extract plugin view types
The dashboard task-create route now uses the distributed task ID allocator
(FN-3450). On projects whose tasks had been allocated through the legacy
config.nextId counter, the allocator's `ensureStateRow` was seeding a fresh
prefix at sequence 1, so new tasks restarted at FN-001 even when FN-3700
already existed. ensureStateRow now seeds past:

- the legacy config.nextId counter (when configured taskPrefix matches), and
- one past the highest numeric suffix on any existing tasks/archivedTasks row
  for the prefix.

A regression test seeds FN-3700 in a fresh DB and asserts the next reservation
returns FN-3701, not FN-001.

Plugin dashboard view contracts are now exposed via a slim type-only module
(`@fusion/dashboard/app/plugins/types`). External plugin tsc builds previously
imported `pluginViewRegistry`, transitively pulling in dashboard runtime
sources (React components, CSS, lucide-react). The dependency-graph plugin's
import + path mapping is updated to use the new module.

Schema housekeeping: drop unused scaffolding tables left over from an earlier
migration via a new idempotent migration (v67). Fresh DBs see no change;
existing DBs that ran the older migration get the orphan tables dropped on
next init.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 09:41:42 -07:00
Fusion
e7deab16b8 feat(FN-3087): document graph plugin in plugin authoring guide
Documentation-only finish for FN-3087, adding changeset and README updates for the dependency graph plugin and plugin authoring guide.

Fusion-Task-Id: FN-3087
2026-05-07 08:49:19 -07:00
Fusion
1f5e102312 feat(FN-3554): expand AI agent interview onboarding flow
Reuses the experimental onboarding modal for both create and edit, makes
onboarding mode-aware, and plumbs draft handling through the agent detail
view, new agent dialog, and import/export/generation routes.

Fusion-Task-Id: FN-3554
2026-05-07 08:49:18 -07:00
Fusion
760621cc8c feat(FN-3393): add eval settings with scheduled eval project settings UI
Adds a scheduled eval settings feature (FN-3393) with a new `evalSettings` contract in core, type-safe numeric validation, a project settings UI section, and an API route for persisting the payload. The bulk of the changes are in the settings modal and supporting test coverage. Two smaller, unrelate

Fusion-Task-Id: FN-3393
2026-05-07 08:49:18 -07:00
Fusion
4338b590c6 feat(FN-3091): add plugin view remount routing test coverage
Adds test coverage for plugin view remount routing behavior in the App component.

Fusion-Task-Id: FN-3091
2026-05-07 08:49:18 -07:00
Aron Prins
f85b124125 test(FN-000): resolve dashboard test noise 2026-05-07 17:27:15 +02:00
Fusion
5ffd1485c3 feat(FN-3581): honor runtime model precedence for assigned agents
This merge delivers five major feature clusters: a fully rebuilt dependency graph plugin with draggable nodes, position persistence, modular architecture, highlighting and selection states, toolbar navigation, and keyboard controls; a new roadmap plugin with domain store, ordering logic, and compreh

Fusion-Task-Id: FN-3581
2026-05-07 06:45:45 -07:00
Fusion
be54c30980 feat(FN-3636): add roadmap plugin with domain store and ordering logic
Merges the roadmap plugin scaffold (FN-3636): a new `plugins/fusion-plugin-roadmap` workspace with domain types (`roadmap-types.ts`), a store layer (`roadmap-store.ts`, `roadmap-ordering.ts`, `roadmap-handoff.ts`), and comprehensive test suites. Also lands graph position persistence for the dependen

Fusion-Task-Id: FN-3636
2026-05-07 06:28:10 -07:00
Fusion
957b8b4efe feat(FN-3463): refine ScriptsModal responsive token usage
Refines responsive CSS token usage in the ScriptsModal component by swapping hardcoded values for design token variables.

Fusion-Task-Id: FN-3463
2026-05-07 05:40:22 -07:00
Fusion
e56f60371b feat(FN-3623): add stash diff viewing UI and backend contract
Merges FN-3623 stash diff inspection system (backend contract, GitManagerModal viewing UI with new API route and tests) and FN-3088 dependency graph hover/selection highlighting. The stash diff work dominates the commit count and touches the core GitManagerModal, while the graph plugin gains new hig

Fusion-Task-Id: FN-3623
2026-05-07 05:09:57 -07:00
Fusion
3735e0565a feat(FN-3396): bundle Cursor CLI as a plugin provider with dashboard auth w
Merges FN-3396's full Cursor CLI provider integration (Steps 1–4): defines a CLI-backed provider contract, adds the `fusion-plugin-cursor-runtime` plugin package with process management and runtime probes, wires dashboard auth flows and UI (ProviderCard, onboarding modal, settings), and bundles the

Fusion-Task-Id: FN-3396
2026-05-07 04:17:52 -07:00
Fusion
f4568088e0 feat(FN-3625): test TaskCard drag override and graph drag opt-out wiring
Adds test coverage for TaskCard drag override behavior and DependencyGraph drag opt-out wiring, with a minor README clarification in the graph plugin.

Fusion-Task-Id: FN-3625
2026-05-07 03:28:43 -07:00
Fusion
2053b66784 feat(FN-3426): add plugin AI security scan gate and GraphTaskNode wrapper t
Adds a plugin AI security scan gate that enforces security scanning before plugin installation, including new `plugin-security-scan.ts` infrastructure, CLI integration (`fn plugin install`), plugin loader hooks, and a changeset. Implements branch filter persistence across sessions in the dashboard (

Fusion-Task-Id: FN-3426
2026-05-07 02:49:35 -07:00
Fusion
fce3668a83 feat(FN-3077): enforce plugin AI security scan gate across install flows
- Add core plugin AI security scan module and schema support for scan toggle/state metadata
- Enforce scan checks during CLI and dashboard plugin install flows, with preserved API error status on scan failures
- Expose plugin scan toggle and rescan actions in dashboard/plugin manager with route and UI coverage
- Update plugin authoring and CLI/dashboard docs, plus add changeset for published CLI package

Fusion-Task-Id: FN-3077
2026-05-07 02:15:14 -07:00
Fusion
ccddba4a67 feat(FN-3425): add board branch filter with no-branch semantics and respons
Restructures the dependency graph plugin into a modular architecture with separate edges, filters, layout, types, and interaction hooks, adding comprehensive tests for the new modules. Implements a board branch filter with "no-branch" semantics and responsive layout refinement, while removing legacy

Fusion-Task-Id: FN-3425
2026-05-07 01:53:48 -07:00
Fusion
fa57034c05 feat(FN-3632): remove quick-entry branch handling from dashboard and docs
Removes the `QuickEntryBox` component and its styles as part of FN-3632 cleanup, with its tests refactored accordingly. Also updates the test-changed script and fixes an isolated test home cleanup ordering issue.

Fusion-Task-Id: FN-3632
2026-05-07 01:30:34 -07:00
Fusion
16c0477e15 feat(FN-3631): replicate task creation across mesh nodes and fix modal scrolling
- Add mesh task replication plumbing in core store/types with node-aware task creation metadata
- Expose dashboard and mesh API route coverage for replicated task creation and sync behavior
- Restore independent scrolling in Git Manager changes list and prevent Scripts modal scroll regressions
- Expand tests across core, dashboard routes, API, and CLI extension insights for the new behavior

Fusion-Task-Id: FN-3631
2026-05-07 00:52:05 -07:00
Fusion
935166dbb5 feat(FN-3450): add mesh task create replication across nodes
Implements distributed mesh task creation by adding replicated create primitives to the core store, wiring new API routes (`register-mesh-routes.ts`) that replicate task creation across clustered nodes while preserving remote-targeting metadata, and updating the dashboard's task creation flow accord

Fusion-Task-Id: FN-3450
2026-05-07 00:05:34 -07:00
Fusion
967896fb16 feat(FN-3080): document graph navigation canonicalization in plugin authori
Adds documentation for graph navigation canonicalization (FN-3080) covering plugin authoring and dashboard usage, along with a changeset for the `@runfusion/fusion` package release.

Fusion-Task-Id: FN-3080
2026-05-06 22:59:51 -07:00
gsxdsm
98e8b6a134 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
f28e75cc90 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
bb11c7102d Reapply "fix(dashboard): block composer drag-pan via onTouchMove preventDefault"
This reverts commit 60853dab02.
2026-05-06 22:37:24 -07:00
gsxdsm
60853dab02 Revert "fix(dashboard): block composer drag-pan via onTouchMove preventDefault"
This reverts commit feb1be3d14.
2026-05-06 22:36:04 -07:00
gsxdsm
9b2fc4565b fix(dashboard): parse Codex reset_at as epoch ms or seconds
Codex returns weekly window reset_at in milliseconds in some cases,
which was being multiplied by 1000 and producing nonsensical reset
countdowns and pace calculations. Route through _parseResetTimestamp
so both formats work, and add a regression test.

Also tightens comments in useMobileKeyboard / ChatView around why
visualViewport scroll events skip offsetTop updates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 22:17:35 -07:00
Fusion
f77f691d26 feat(FN-3626): migrate plugin storage to project-scoped storage
Migrated the dependency-graph plugin's storage layer to use the project's scoped storage API (`projectStorage`) and added canonical storage-key assertions. The ChatView.tsx utility reference was updated to match the new storage path.

Fusion-Task-Id: FN-3626
2026-05-06 22:17:35 -07:00
Fusion
07b286ba7a 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
2b9f279d9a feat(FN-3629): refine branch chip visibility in task cards
Refined branch chip visibility logic in TaskCard (suppressing the chip when the current branch is the default) and added test coverage for those suppression cases, with corresponding documentation updates. Also added chat layout regression tests and fixed a composer drag-pan issue on mobile touch de

Fusion-Task-Id: FN-3629
2026-05-06 22:17:35 -07:00
Fusion
7eab743eb2 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
feb1be3d14 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
Fusion
3d1e90d6ec feat(FN-3424): add unassigned branch filter options to dashboard header
Adds unassigned branch filter options to the dashboard header, allowing users to filter tasks by unassigned status. Updates the Header component with new filter controls and includes corresponding tests for the App and Header components.

Fusion-Task-Id: FN-3424
2026-05-06 21:47:53 -07:00
gsxdsm
64b45b3064 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
gsxdsm
6488110239 Revert "fix(dashboard): lazy-init useMobileKeyboard so remount has no stale render"
This reverts commit eb111f526e.
2026-05-06 21:41:16 -07:00
gsxdsm
eb111f526e fix(dashboard): lazy-init useMobileKeyboard so remount has no stale render
When ChatView remounted (e.g. tab switch with keyboard still up), the
hook started with keyboardOpen=false and corrected itself only after
the effect ran. That single stale-state render briefly unhid the
executor status bar, which appeared as a blank pane covering half the
input box before the next state update settled it.

useState initializers now call getKeyboardMetrics() lazily on first
render so the very first paint already reflects the live keyboard
state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 21:38:50 -07:00
gsxdsm
3df09883be fix(dashboard): add rAF stability poll for keyboard re-snapshot
Tab/page switches with the keyboard up sometimes still left the
chat-thread anchored wrong because the timed re-reads (50/200/500ms)
missed the actual settlement frame on slower devices.

updateWithTail now also kicks off a rAF poll that re-reads metrics
each frame until offsetTop is stable for 2 consecutive frames or 1.5s
elapses. Combined with the extended timed tail (now adds 1000/1500ms),
this should catch both fast and slow iOS settlement paths without
indefinite polling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 21:36:31 -07:00
Fusion
953ac8a886 feat(FN-3618): surface provider icons in settings and dropdowns
Completes Step 3 of FN-3618 by surfacing AI provider icons throughout the Settings modal and model dropdowns, updating both the component styles and adding integration and unit tests to cover the new icon display behavior.

Fusion-Task-Id: FN-3618
2026-05-06 21:36:31 -07:00
gsxdsm
94c93abf68 fix(dashboard): re-snapshot keyboard metrics on focusin and page restore
Switching away from the chat view and back left the hook with stale
metrics — keyboardOpen was false at remount even though the system
keyboard was still visible, so the .chat-thread transform never
re-applied and the message list anchored too high. focusin and
synchronous reads also captured offsetTop mid-transition.

Adds a tail of delayed re-reads (50ms, 200ms, 500ms) on focusin,
visibilitychange, and pageshow so iOS has time to settle before the
final snapshot is taken.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 21:16:33 -07:00
Fusion
a0fa7f7bc8 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
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