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
Three coordinated fixes for the FN-2978 incident class — auto-requeues
that orphaned committed work and watchdog kills on long verification runs.
**Auto-requeue branch reuse** (executor.ts, worktree-pool.ts)
- executor.ts:1782 now uses `task.branch || fusion/<id>` so persisted
branches are honored on requeue. Previously the hardcoded fallback
always tried to re-create the original branch, hit a conflict with
the prior run's ref, and got suffix -2/-3. Other call sites already
honor task.branch — this aligns the worktree-acquisition path.
- worktree-pool.ts:181 prepareForTask now probes existing branches with
`git rev-parse --verify` and checks them out as-is. Falls through to
suffixed creation only when the branch is genuinely in use by another
live worktree. Previously force-reset with `checkout -B`, destroying
prior commits.
- New private reconcileStepsFromGitHistory walks `git log
baseCommitSha..HEAD` for `feat(FN-X): complete Step N` commits and
marks matching steps[] as done so resumes don't redo committed work.
**Manual reset endpoint + UI** (dashboard)
- POST /api/tasks/:id/reset (requires `confirm: true`) — clears worktree,
branch, all retry counters, resets steps[] to pending, moves to todo.
Distinct from /retry which is the soft-resume path.
- Reset button alongside Retry in TaskDetailModal with confirm dialog,
wired through useTasks → AppModals → API.
**fn_run_verification tool** (run-verification-tool.ts, executor.ts)
- New custom tool wrapping test/lint/build commands with a heartbeat
callback (per-line + 60s synthetic), 200KB head+tail output cap, hard
timeout with SIGTERM→SIGKILL escalation, and auto-bootstrap detection
for missing node_modules. Prevents the inactivity watchdog from
killing sessions during long compiles.
- Cross-platform via `shell: true` (Node picks /bin/sh on POSIX,
cmd.exe on Windows). Prompt section in EXECUTOR_SYSTEM_PROMPT and
EXECUTOR_PROMPT_TEXT instructs agents to prefer package-scoped
verification first and reserve workspace-scoped runs for final
integration.
**Tests** (64 passing)
- detect-pseudo-pause.test.ts (27 tests) — covers all 7 regex patterns,
structural fallback, FN-2978 regression text.
- reconcile-step-regex.test.ts (25 tests) — pins the commit-message
regex against a wide variant set.
- run-verification-command.test.ts (12 tests) — basic execution, output
capture, heartbeat callbacks, timeout, error handling. POSIX-specific
cases (multi-cmd `;`, `>&2`, `\$USER`) gated behind itPosix.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Track and thread usage trigger bounds from Header through modal management to UsageIndicator
- Render desktop usage details as an anchored popover while preserving existing modal wiring behavior
- Extract usage indicator styling into a dedicated UsageIndicator.css and remove planning-mode style duplication
- Expand header and usage indicator tests to cover anchor rect propagation and popover behavior
- Stabilize CLI bundle output sqlite assertion for workspace test reliability
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>
- Replace the server-computed settings flag with prAuthAvailable and document it in shared Settings types
- Compute PR auth availability from gh CLI auth first, with GITHUB_TOKEN as fallback in GET /api/settings
- Rename dashboard settings state/props/hooks from githubTokenConfigured to prAuthAvailable and strip server-owned auth fields on save
- Update PR section messaging to guide users to run 'gh auth login' and refresh related route/component tests
- Track the first task created from onboarding in AppModals and pass it back into the onboarding modal
- Keep onboarding open after launching New Task, then switch to a task-created success state when a task is returned
- Add success actions to view the created task or return to the dashboard, while preserving the no-task completion path
- Style the task-created success panel and add comprehensive ModelOnboardingModal tests for transition, rendering, and button behavior
- Add scope selector controls to ScheduleForm and RoutineEditor components
- Add scope badges to RoutineCard and ScheduleCard for visual scope indication
- Add scope controls to ScheduledTasksModal with projectId propagation
- Add scheduling scope options to automation/routine API wrappers
- Add comprehensive regression tests for scope propagation and modal wiring
- Update README with dashboard UI scope selection documentation
- Add MailboxView as a full-page navigation view replacing the modal-based approach
- Migrate MessageStore from filesystem to SQLite backend for message persistence
- Implement conversation grouping for inbox display with unread badge state
- Remove modal plumbing (useModalManager, AppModals exports) and simplify App.tsx
- Add evictStaleProcessing() to TriageProcessor for self-healing hung triage sessions
- Add comprehensive MailboxView tests and Header mailbox tests
- Update README documentation with MailboxView features
- Add CSS styles for MailboxView component
- Fix MobileNavBar tests for mailbox tab visibility
- Add markOnboardingCompleted() to set completedAt timestamp when user finishes onboarding
- Add isOnboardingCompleted() to check if onboarding was completed (vs dismissed)
- Update ModelOnboardingModal to call markOnboardingCompleted on successful completion
- Skip onboarding auto-open when already completed locally
- Add completion state tracking tests in ModelOnboardingModal.test.tsx
- Add model-onboarding-state unit tests
- Update useAuthOnboarding to check local completion state before auto-opening
- Document localStorage completion state tracking pattern in .fusion/memory.md
GitManagerModal was not receiving projectId from AppModals, causing all
git operations to run against the default repo instead of the active
project's repo. Threads projectId through all git API calls.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Update useModalManager to accept Task objects for immediate modal display before full detail loads
- Refactor TaskDetailModal to render with basic Task data and load TaskDetail asynchronously
- Update TaskCard click handlers to open modal immediately with optimistic data
- Update ListView click handler for same optimistic opening behavior
- Update AppModals types to support Task | TaskDetail union
- Add CSS for modal loading/skeleton states
- Add comprehensive tests for TaskDetailModal and useModalManager optimistic flow
- Simplify TaskCard and ListView tests to reflect new optimistic opening pattern
- Create ErrorBoundary and ModalErrorBoundary components with recovery actions (retry, reload)
- Add error boundary CSS styles with fallback UI styling
- Wrap main dashboard pages (Board, List, Settings, Agents) with PageErrorBoundary in App.tsx
- Wrap all key modals (task detail, planning, subtask breakdown, mission) with ModalErrorBoundary in AppModals.tsx
- Wrap entire App with RootErrorBoundary in main.tsx as final safety net
- Add 11 comprehensive ErrorBoundary tests covering all rendering and error scenarios
- Extend dashboard task view state and nav controls to include a persistent missions view toggle
- Render MissionManager inline in App project content and route mission/session navigation into the missions view
- Remove modal-based mission wiring from AppModals and useModalManager now that missions are no longer a modal
- Add inline MissionManager styling and update App/Header/tablet tests for the new missions navigation behavior
- Extract view state, project actions, and task handler concerns from AppInner into dedicated hooks
- Add AppModals component to centralize modal rendering and related props wiring
- Inline thin aliases and complete AppInner cleanup after moving responsibilities out
- Add unit tests for useViewState, useProjectActions, and useTaskHandlers hooks