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
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
Merges FN-3311 work into the release pipeline: adds a version notes extractor with tests and integrates GitHub release creation into the release script, plus a minor CSS design token consistency fix in the dashboard.
Fusion-Task-Id: FN-3311
Fixed QuickChatFAB styling to align with the design token system, replacing hardcoded CSS values with consistent token variables in the component's stylesheet.
Fusion-Task-Id: FN-3266
Merges FN-3244's three-step hardening of the mobile FAB drag path, adding regression tests and finalizing TypeScript typing. Includes FN-3296's tokenized typography for agent health reasons, FN-3014's documented recovery semantics for the research system, and related CLI/dashboard work that improves
Fusion-Task-Id: FN-3244
This merge adds a durable insight lifecycle with bounded run executor to the core store layer, along with supporting database schema changes and comprehensive test coverage. It also restores type compatibility for list view detail callbacks and fixes QuickChatFAB CSS scope issues. Documentation acro
Fusion-Task-Id: FN-3243
This merge lands v0.15.0 with two major features: a slash-triggered quick chat skill menu (FN-3119, 8 steps covering skill discovery state, trigger matcher, input wiring, skill menu rendering, styles, local help assistant, and tests) and plugin dashboard views (FN-3079, FN-3066) with dependency grap
Fusion-Task-Id: FN-3119
This merge completes the session-first quick chat FAB flow (Step 5), restores the quick chat hook after fixing a styling regression, and fixes heartbeat prompt composition for autonomous agents. It also adds the planning mode question display with new-session reset, introduces new Droid CLI settings
Fusion-Task-Id: FN-3058
The mobile QuickChat panel was unusable on iOS Safari: the input bar
rendered off-screen, the soft keyboard often did not open on FAB tap,
the panel slid up out of view on the second input focus, and the
header pill overflowed when the model name was long.
- The FAB JSX no longer emits inline right/bottom styles on mobile,
and the mobile media query pins every edge with !important so the
panel cannot be dragged off-screen by the desktop draggable hook.
- Body scroll is locked while the panel is open via overflow:hidden
on <html> and <body>, and the document is reset to scroll 0 on
open. This prevents iOS from leaking residual scroll into the
fixed-positioned panel between opens.
- An always-mounted, offscreen stealth input claims the iOS soft
keyboard inside the FAB click gesture (the real composer input is
initially `disabled` waiting for the chat session, and iOS will
not open the keyboard for a disabled input). Focus is transferred
synchronously to the real input once it becomes enabled.
- The composer input intercepts touchstart on mobile and re-focuses
with `preventScroll: true`, suppressing iOS's default focus-and-
scroll behavior that was shifting visualViewport.offsetTop and
sliding the panel up off-screen on a refocus.
- A useLayoutEffect mirrors visualViewport.height onto the panel as
--vv-height directly via the DOM, bypassing React state to avoid
the per-event reconciliation lag that read as visual jank during
the keyboard slide-in. On blur, the variable is cleared and a
short suppress window (~450ms) prevents iOS's mid-dismiss reports
from clobbering the regrowth, so the panel snaps back to full
height immediately while the keyboard finishes sliding down on
top of it.
- The model-tag pill in the header collapses to the provider icon
when the tag would otherwise exceed ~12 characters on mobile.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This merge brings multiple substantial features: new research extension tools wired through the AI engine (with full test coverage and documentation), legacy routines agentId backward compatibility with migration paths, migration of experimental remote settings to the global scope, Nerd Font glyph a
Fusion-Task-Id: FN-2996
This merge adds research settings to the settings modal and dashboard (FN-2839, FN-3029), implements a dashboard font scale setting with persistence and documentation (FN-3027), refactors AgentDetailView with a new AgentLogViewer CSS module (FN-2839), and improves NewAgentDialog with custom model dr
Fusion-Task-Id: FN-3027
- Pre-select the global default (or first available) model on first open so
users can chat without manually picking from the dropdown.
- Bump specificity of the new-chat (+) button styles so the CTA bg/text
applies instead of being overridden by the header's .btn-icon rule.
- Focus the message input on panel open via rAF.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Inline grouped tool-call rendering in chat surfaces and update summary logic for clearer aggregation
- Refine chat, quick FAB, settings, and agents UI styles/behavior with matching test coverage updates
- Extend dashboard TUI state/controller flow with status and shortcut improvements
- Update engine and dashboard route handling related to agent runs, settings memory sync, and remote access adapters
Fusion-Task-Id: FN-2926
- Extend /models API responses to include optional defaultProvider/defaultModelId from global settings, including empty and error paths
- Update QuickChatFAB to prefer the configured default model on load and fall back to first-model selection only when no agents exist
- Move quick chat model tag/title-wrap inline styles into QuickChatFAB.css using dashboard design tokens
- Add QuickChatFAB tests covering default-model auto-selection with and without agents and legacy behavior when no default is configured
The Settings, Workflow Steps, Automations (and friends) modals all carried
desktop `min-width: 480-520px` constraints from the resize work. On phones
that pushed them off-screen, and the overlay's 10vh top padding plus a
fractional `height: 80vh` left awkward gaps top and bottom.
Apply the same `@media (max-width: 768px)` full-screen-sheet treatment
that File Browser already had to every resize-aware modal: drop the
overlay padding, set width/height to `100vw`/`100dvh`, zero out the
min-* / max-* constraints, and disable `resize` (touchscreens can't grab
the corner grip anyway).
Also tightened the existing File Browser and GitHub Import overrides to
match (`min-width: 0`, `min-height: 0`, `resize: none`).
For TaskDetailModal the mobile rules go inside the existing first
`@media (max-width: 768px)` block to keep the FN-1331 detail-body
padding regression test happy (it captures from the first 768px media
query greedily).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
The black-translucent status bar overlays the page in iOS standalone PWAs,
clipping close buttons in full-screen mobile modals and the QuickChatFAB
panel. Add `padding-top: env(safe-area-inset-top, …)` so headers render
below the status bar.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add a shared useMobileKeyboard hook that tracks visualViewport overlap on mobile browsers
- Apply keyboard overlap CSS variables to QuickChatFAB so fullscreen mobile panels resize above the virtual keyboard
- Apply the same keyboard-aware sizing to ChatView mobile thread layout and auto-scroll messages when keyboard opens
- Expand ChatView, QuickChatFAB, and hook test coverage for mobile keyboard detection and viewport-resize behavior
- Remove generic btn btn-icon classes from quick chat render toggles so component-specific visibility styles apply
- Increase toggle icon size and adjust default muted color for clearer eye/eye-off affordance in assistant messages
- Add explicit focus-visible ring styling for keyboard accessibility on the render toggle control
- Extend QuickChatFAB regression coverage to assert class usage, SVG icon presence, and plain/rendered toggle state transitions
- Add panel resize state and pointer-driven drag handling to QuickChatFAB
- Wire resize behavior into component layout so desktop users can adjust panel dimensions
- Style resize handles and interaction affordances in QuickChatFAB.css
- Expand QuickChatFAB tests to cover resize lifecycle, constraints, and persistence behavior
- Replace hover background fallbacks with direct var(--surface-hover) in QuickChatFAB and SettingsModal styles
- Tighten status-colors theme test to forbid var(--surface-hover, ...) fallback syntax
- Preserve token-based hover styling contract while preventing stale fallback patterns from reappearing
Sweep 1 of the styles.css split. Rules where the desktop counterpart already
lived in a component CSS file have been moved out of the global mobile @media
block in styles.css and appended to the matching component file's mobile
block. styles.css 4551 → 4488.
Affected components: Header, AgentsView, DocumentsView, ListView, QuickChatFAB,
QuickEntryBox, ScriptsModal, TaskDetailModal, TerminalModal, WorkflowResultsTab.
Truly global mobile rules (input font-size for iOS auto-zoom, html/body
overflow, root safe-area padding, base .btn touch targets, bare element
selectors) intentionally stay in styles.css. The remaining bulk of the mobile
block (settings, auth, board/card, inline-create) cannot move yet because
their desktop rules are still in styles.css — those will fall out as part of
the cards and settings extraction sweeps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Split app/styles.css from ~40k lines down to ~4.5k. Created 56 co-located
component CSS files in app/components/, each imported by its owning .tsx.
The remainder of styles.css holds genuinely global rules (design tokens,
.btn/.card/.modal/.form-input primitives, cross-component @media overrides).
- Lazy-load 13 heavy views (AgentsView, RoadmapsView, NodesView, etc.) via
React.lazy + Suspense; prefetch all chunks on idle so first navigation is
instant. Initial JS bundle: 1.58 MB → 1.16 MB (-26%). Initial CSS bundle:
635 kB → 471 kB (-26%); the rest splits into 13 per-view chunks.
- Add app/test/cssFixture.ts exposing loadAllAppCss() + loadAllAppCssBaseOnly()
so CSS regression tests load the full per-component bundle (mirroring Vite
source order). Migrate 30+ tests off direct readFileSync('../styles.css').
- Enable test.css: { include: [/.+/] } in vitest.config.ts so component CSS
imports actually inject styles in jsdom (fixes getComputedStyle assertions).
- Add ESLint rule (no-restricted-syntax) banning direct styles.css reads in
dashboard test files; points at loadAllAppCss() instead.
- Restore lost utility classes (.text-muted, .text-secondary, .text-dim,
.form-input) and rescue dropped chat tool-call rules into QuickChatFAB.css.
- Mobile fixes along the way: scroll containment for view containers
(min-height:0 + -webkit-overflow-scrolling), QuickChatFAB full-screen on
mobile (with safe-area-inset for iOS home bar), AgentsView single-row
header layout, ActivityLogModal close button on right, model-combobox
z-index above the mobile quick-chat panel.
- Bug fix: SkillsView toggle was display:none which hid the input from the
accessibility tree; replaced with the visually-hidden pattern so screen
readers + getByRole still find the checkbox.
- Bug fix: standalone Delete button in TaskDetailModal for triage-column
tasks (Actions dropdown is hidden in triage state, so previously no way
to delete a freshly-created task without status change first).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>