- Add typed dev server models and constants for configs, session state, runtime metadata, and bounded log history
- Add JSON persistence helpers for .fusion/devserver.json with tolerant parsing and session reconstruction
- Add dev command auto-detection across root and workspace package.json scripts with framework inference and priority sorting
- Implement DevServerManager lifecycle controls, preview URL detection, port probing fallback, and singleton manager helpers
- Add Vitest coverage for devserver types, detection/persistence behavior, and manager lifecycle/events
- Add preview embed diagnostics with richer error classification and fallback state handling
- Improve PreviewIframe and DevServerView retry UX for timeout and iframe failure states
- Adjust preview layout/styles to prevent clipping and header overflow while keeping fallback panels centered
- Expand dashboard tests to cover fallback transitions, retry flows, and responsive CSS behavior
- Add usePreviewEmbed hook to derive preview embed URLs and availability state
- Add PreviewIframe component with iframe load/error wiring and deduplicated error callbacks
- Integrate preview panel actions, fallback messaging, and embedded iframe rendering in DevServerView
- Expand test coverage for usePreviewEmbed, PreviewIframe, and DevServerView preview integration scenarios
- Display heartbeat interval and timeout in seconds while persisting runtimeConfig in milliseconds
- Convert derived and persisted heartbeat values before dirty-state comparison so unchanged settings keep Save Settings disabled
- Update heartbeat validation minimums, placeholders, and hints to align with seconds-based inputs
- Expand AgentDetailView tests for pre-filled values, unchanged-state save disabling, validation, and payload conversion
- Replace the silent stale-session eviction catch with a terminal error log in setupTerminalWebSocket
- Add regression tests that assert evictStaleSessions runs on each 60s interval tick
- Verify eviction errors are logged without stopping future ticks and interval cleanup runs on server close
- Show Run Now controls in AgentsView for active and running agents without requiring taskId
- Rename Run Heartbeat copy to Run Now and update runs-tab accessibility labels in AgentDetailView
- Add AgentsView coverage for Run Now visibility and startAgentRun invocation when no task is assigned
- Update agent runs UI static-analysis tests and add a patch changeset for @gsxdsm/fusion
- Add dev-server port detection utilities and wire detected preview state into process/manager lifecycle
- Normalize dev-server status API responses with preview URL, detected port, and manual override compatibility
- Introduce useDevServerLogs and DevServerLogViewer, and integrate them into the DevServer dashboard view
- Expand dashboard test coverage for detection edges, process/routes behavior, log history handling, and CSS regressions
- Add DevServerView with command detection, start/stop/restart controls, live logs, and preview URL management
- Implement useDevServer with SSE log streaming, running-state polling, manual URL updates, and candidate detection support
- Extend dashboard API client mappings for dev-server candidate metadata, status fields, and preview URL helpers
- Integrate dev server navigation in header/mobile nav, normalize devserver view state persistence, and add feature-flag wiring
- Add/refresh DevServerView and useDevServer tests and replace legacy dev-server CSS with the new component styles
- Refresh AgentDetailView on agent:updated SSE events while preserving local unsaved config edits
- Resync heartbeat and budget form state from latest runtime config when agent data changes
- Centralize heartbeat interval defaults/formatting in shared utilities and reuse them in AgentsView selectors
- Add dashboard tests for default heartbeat hints, unset runtime fallback behavior, and custom interval options
- Add docs/skipped-test-inventory.md with the current intentional skip patterns and rationale across test suites
- Link the skipped-test inventory from docs/README.md for easier discovery
- Record reconciliation of older skip follow-up tasks that are now covered and no longer active backlog
- Stabilize PlanningModeModal conversation-history resume testing by overriding stream behavior in the targeted test case
- Extend dev server store with config defaults, normalization, and JSON persistence alongside runtime state.
- Add GET/PUT /api/dev-server/config endpoints with strict request validation for nullable fields and preview URLs.
- Add dashboard API helpers plus a useDevServerConfig hook to load and update selected script, source, command, and preview override.
- Update DevServerView and styles to support saved script selection, change/clear actions, and synchronized command/preview inputs.
- Expand dev server store/routes/component tests and document the config endpoint in architecture docs.
Resume paths (unpause, drift recovery, engine restart) bypassed the
scheduler's todo->in-progress clear, leaving actively executing tasks
labeled status="queued" with a lingering blockedBy. Broadened
clearResumeFailureState to null both fields alongside the existing
failure cleanup, and added a defensive UI backstop so the "Queued"
badge no longer renders for tasks in the in-progress column.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add horizontal padding to the prompt manager container for consistent desktop gutters
- Add top margin to separate the prompt manager from surrounding sections
- Add a mobile-specific prompt manager padding override at the 768px breakpoint
On iOS Safari/PWA, tapping the terminal opened the keyboard but typed
keys produced no output. Focus landed on a 1×1 opacity-0.01 helper
textarea overlapped by the xterm canvas, and capture-phase gesture
handlers re-focused on every tap — a combination iOS silently drops
input events on.
- On touch-primary devices, expand .xterm-helper-textarea to cover the
entire terminal surface (100% × 100%, opacity 0, z-index 2) via
@media (hover: none) and (pointer: coarse). Taps land on the
textarea directly, so iOS grants keyboard + input events natively.
- Desktop keeps the 1×1 rule so xterm's canvas-level drag-to-select
and mouse tracking continue to work.
- Revert onPointerDownCapture/onTouchStartCapture/onClickCapture back
to bubble-phase onPointerDown/onTouchStart; capture phase was
confusing iOS's focus attribution and is no longer needed now that
taps reach the textarea directly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Rename the dashboard markdown files route to /files/markdown-list.
- Update fetchProjectMarkdownFiles to call the new markdown-list endpoint.
- Adjust useDocuments test mocks and assertions to match the renamed route.
- Extend auth status API typing to include optional ghCli availability/authentication metadata.
- Update /api/auth/status to return ghCli readiness using isGhAvailable() and isGhAuthenticated().
- Treat setup GitHub readiness as satisfied when either GitHub OAuth or authenticated gh CLI is present.
- Add hook tests covering gh CLI authenticated, unauthenticated, combined OAuth, and missing-ghCli fallback cases.
- Add optional summary payload support to planning create-task and start-breakdown API client calls
- Pass edited summary data from PlanningModeModal when creating a task or starting breakdown
- Parse and validate summary overrides in planning routes and prioritize override data when present
- Add and update dashboard tests to verify override handling and modal call expectations
- Keep only one optional tab (Skills or Roadmaps) in the top-level mobile nav to preserve touch-target width
- Move overflowed optional destinations into the More sheet and mark More active when those views are selected
- Add MobileNavBar tests covering Skills/Roadmaps overflow behavior and More-sheet routing
- Add mobile nav CSS guards (min-width and label ellipsis) to avoid clipping on narrow screens
Fixes two classes of task failures found while investigating stuck in-review
tasks FN-2165 (worktree base ref missing) and FN-2152 (stray .tmp-fn-2152
gitlink accidentally committed via merger amend).
FN-2165 — stale baseBranch:
- resolveWorktreeStartPoint now returns null instead of throwing
NonRetryableWorktreeError when the stored baseBranch is gone. Caller clears
task.baseBranch and falls back to branching from the default base (HEAD) so
the task self-heals instead of failing permanently.
- New TaskStore.clearStaleBaseBranchReferences() nulls baseBranch on any
dependent task when its upstream branch is deleted. Wired into
cleanupBranchForTask (archive/delete), merger branch cleanup, self-healing
orphan-branch sweep, executor dep-abort and conflict-cleanup paths, and
stale-branch recovery.
Nested worktrees:
- assertWorktreePathNotNested guard in tryCreateWorktree refuses to create a
worktree inside another registered worktree (previously produced pathological
paths like .worktrees/green-finch/.worktrees/amber-panda when rootDir pointed
at a worktree instead of the main repo).
Context-overflow recovery (FN-2182 class):
- Reduced-prompt retry budget raised from 1 → 3 within the same session.
- Adds a fresh-session requeue path when same-session retries still overflow:
task moves back to todo with worktree retained, bounded by
computeRecoveryDecision / MAX_RECOVERY_RETRIES. Prevents late-step context
exhaustion from becoming terminal.
Gitlink prevention (FN-2152 class):
- .gitignore now excludes .tmp-fn-* and .tmp-kb-* so stray worktrees at the
repo root cannot be captured by git add -A.
- Merger amend flow now scans staged entries for 160000 gitlinks and unstages
them with a loud warning; the project uses no submodules, so any such entry
is a bug (this is how f8f90f26 landed in HEAD as .tmp-fn-2152).
Tests: new coverage for baseBranch fallback, nested-worktree guard, and
clearStaleBaseBranchReferences. Full engine + core + dashboard + cli suites
pass (15349 tests).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A stray 160000 (submodule) entry pointing at commit f8f90f26 was
committed by mistake during FN-2152 work. The path had no corresponding
submodule registration and showed up as "modified" in every clone.
Registered git worktree also dangled inside the main repo tree.
Removing the gitlink entry from the tree so subsequent checkouts no
longer carry the stale reference. Corresponding worktree pruned via
`git worktree remove` earlier.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Emit tool_start/tool_end SSE events from dashboard chat backend and parse them in streaming client helpers
- Track in-flight and completed tool calls in useChat/useQuickChat to preserve tool output summaries alongside assistant messages
- Render collapsed tool call preview blocks in ChatView and QuickChatFAB with dedicated tokenized styles for compact output summaries
- Expand frontend and backend test coverage for SSE tool events, hook state transitions, and collapsed preview rendering behavior
- Add a changeset for @gsxdsm/fusion documenting the new tool-call display behavior
- Show formatted model names in sidebar metadata for fn assistant sessions with a Fusion fallback
- Use the resolved model name as the thread header title and assistant avatar label for fn sessions
- Suppress duplicate model tags when the primary label already displays the model while keeping tags for non-fn sessions
- Expand ChatView tests to cover sidebar, header, and avatar model-label and fallback behavior
Root cause: during a triage split the AI could set a child task's
`dependencies` to the parent id. The parent is hard-deleted after the split,
and the scheduler's dep check treats a missing id as unmet — permanently
blocking the dependent. This stranded FN-2164 behind the deleted FN-2163.
- core/store.deleteTask: refuse to delete when any live task still has the id
in its `dependencies` array. Throws TaskHasDependentsError listing dependents
so callers can rewrite or recover. Covers the triage-split path and any
future caller.
- engine/triage task_create: validate each proposed dependency before creating
a child — reject the parent id, reject unknown task ids, allow siblings
created earlier in the same split or pre-existing tasks.
- engine/triage split cleanup: wrap the parent deleteTask in try/catch that
keeps the parent alive (safer than stranding dependents) and logs the reason.
- engine/triage prompts: both the mandatory-split and proactive-split prompts
now explicitly state that subtask deps must never reference the parent.
- dashboard/routes /subtasks/create-tasks: reject parent-id deps, drop unknown
deps with an audit log entry, surface parentTaskCloseError + droppedDependencies
in the response instead of silently swallowing them.
- engine/executor: on execute entry, detect the drift state (in-progress task
with no worktree) and emit a loud log + task log entry; the existing
fresh-worktree path then recovers. Prevents silent "operating without a
worktree" behavior that we saw on FN-2152.
Tests:
core: 2907/2907 pass (+5 new, incl. deleteTask guard regression)
engine: 2554/2554 pass (+17 new, incl. task_create dep validation)
dashboard: 9064/9064 pass (+2 new for /subtasks/create-tasks).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Root cause: during a triage split the AI could set a child task's
`dependencies` to the parent id. The parent is hard-deleted after the split,
and the scheduler's dep check treats a missing id as unmet — permanently
blocking the dependent. This stranded FN-2164 behind the deleted FN-2163.
- core/store.deleteTask: refuse to delete when any live task still has the id
in its `dependencies` array. Throws TaskHasDependentsError listing dependents
so callers can rewrite or recover. Covers the triage-split path and any
future caller.
- engine/triage task_create: validate each proposed dependency before creating
a child — reject the parent id, reject unknown task ids, allow siblings
created earlier in the same split or pre-existing tasks.
- engine/triage split cleanup: wrap the parent deleteTask in try/catch that
keeps the parent alive (safer than stranding dependents) and logs the reason.
- engine/triage prompts: both the mandatory-split and proactive-split prompts
now explicitly state that subtask deps must never reference the parent.
- dashboard/routes /subtasks/create-tasks: reject parent-id deps, drop unknown
deps with an audit log entry, surface parentTaskCloseError + droppedDependencies
in the response instead of silently swallowing them.
- engine/executor: on execute entry, detect the drift state (in-progress task
with no worktree) and emit a loud log + task log entry; the existing
fresh-worktree path then recovers. Prevents silent "operating without a
worktree" behavior that we saw on FN-2152.
Tests:
core: 2907/2907 pass (+5 new, incl. deleteTask guard regression)
engine: 2554/2554 pass (+17 new, incl. task_create dep validation)
dashboard: 9064/9064 pass (+2 new for /subtasks/create-tasks).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Rename core loader, dashboard server chat/planning routes, and frontend agent IDs/storage keys from kb-agent to fn-agent naming
- Update dashboard hooks and components (agent list, chat view, quick chat) to use the new fn agent key prefixes consistently
- Refresh engine, dashboard, core, and CLI tests/mocks to remove remaining kb-agent route and temp prefix references
- Update storage/gap-analysis docs to reflect fn agent key names and add a @gsxdsm/fusion patch changeset for the rename
- Render full template prompt text in cards with a scrollable preview area instead of truncation
- Add expand controls for built-in and custom templates to open a single fullscreen dialog view with Escape/collapse handling
- Align template expand buttons to shared icon-button styling for consistent UI behavior
- Extend AgentPromptsManager tests to cover preview overflow styles and fullscreen interactions across built-in/custom templates
- Rename engine export and call sites to use createFnAgent consistently across runtime flows
- Update core lazy engine loader and dashboard agent-generation/planning/chat paths to reference createFnAgent
- Refresh affected unit and integration tests, including renaming pi-create-kb-agent.test.ts to pi-create-fn-agent.test.ts
- Update AGENTS.md documentation references to match the new createFnAgent name
- Introduce DevServerStore and DevServerProcessManager with a simplified store API contract
- Add dev-server script detection and route legacy manager behavior through the new process manager
- Add a dedicated dev-server router with start/stop/status/log endpoints and SSE event streaming
- Wire dev-server routes into the main route table and hook manager shutdown into server teardown
- Expand tests and architecture docs for store, process, route, detection, and SSE coverage
- Add the `skillsView` entry to the known experimental feature display-name map in SettingsModal.
- Show "Skills View" as the user-facing label in the experimental features list instead of a raw feature key.
- Add a durable dev-server store and manager with persisted state/log history, process reconciliation, and SSE event buffering
- Wire new backend lifecycle APIs for status/history/start/stop/restart/stream and initialize/shutdown manager handling in server startup
- Add dashboard Dev Server view, hook-based hydration/stream handling, nav integration, and supporting styles
- Expand coverage with backend persistence/route tests and frontend DevServerView/useDevServer tests
- Document the dev-server persistence architecture in docs/architecture.md
- Limit background session inclusion to active statuses (generating and awaiting_input)
- Remove sessions from local state when SSE updates deliver complete or error terminal statuses
- Update useBackgroundSessions tests to assert terminal sessions are filtered out and removed on SSE updates
- Adjust session count expectations to reflect active-only tracking
- Add DevServerManager service to start/stop/restart dev processes, persist state, stream logs, and detect preview URLs
- Add dev server candidate detection across root/workspace package scripts with caching and invalidation helpers
- Expose /api/dev-server routes for candidates, status, lifecycle actions, manual preview URL, and SSE log/status stream
- Initialize and tear down dev server managers from dashboard server lifecycle
- Add unit and route tests covering detection, manager lifecycle, URL parsing/fallback probes, and API validation
- Render SetupWarningBanner from App only in project view when setup readiness reports warnings
- Persist dismiss state per project via scoped storage and restore it when switching projects
- Add optional dismiss action to SetupWarningBanner with close button UI and responsive styles
- Remove inline banner from QuickEntryBox and add tests covering dismiss button behavior
- Add an agentLogEntries table and schema migration updates for SQLite-backed agent log persistence
- Persist appended agent logs in SQLite and read task agent logs from the database instead of filesystem-only JSONL
- Import legacy agent log JSONL data into SQLite with type-safe handling for older log field shapes
- Preserve agent logs across task updates and archive flows, and update docs plus tests (including schema assertions) to cover the new behavior
- Add a changeset for @gsxdsm/fusion describing the agent log storage migration
- Add project settings for pushAfterMerge and pushRemote with defaults and typed merge result fields for push status/errors
- Implement post-merge remote sync in the merger with pull --rebase, auto/AI conflict resolution, and one non-fast-forward retry before push
- Expose push-after-merge controls in Settings modal with conditional Push Remote input and coverage for desktop/mobile save flows
- Document the new settings in the settings reference and stabilize CLI cross-build help test timeout
- Make .settings-layout fill available space and allow shrinking with flex: 1 and min-height: 0
- Enable vertical scrolling on .settings-sidebar in desktop layout to prevent content clipping
- Add a SettingsModal regression test that loads styles.css and asserts desktop overflow/scroll computed styles
- Add an autoMerge prop to PrSection and show an auto-merge hint instead of manual PR actions
- Pass project autoMerge settings from TaskDetailModal into PrSection
- Preserve active automation messaging when PR creation is already in progress
- Expand PrSection tests to cover auto-merge enabled and disabled behavior
- Increase core RunMutationContext log entry bounds test timeout to reduce flakiness
- Update reflection trigger API typing to allow null responses from manual generation
- Handle null results in AgentReflectionsTab with a clear insufficient-history toast
- Normalize reflection trigger errors to show specific UX for deleted agents and insufficient history
- Return a clear 500 error when manual reflection generation yields no reflection payload
- Expand dashboard reflection route/UI tests to lock in null and not-found regression behavior
- Add core helpers to list, read, and write .fusion/agent-memory/{agentId} files with strict path validation and exports
- Add dashboard API routes and client methods for agent memory file listing and single-file read/write operations
- Expand AgentDetailView memory tab with file selection, editing, save states, and inline validation feedback
- Add route/backend coverage for agent memory file endpoints and include a @gsxdsm/fusion minor changeset
- Add constructor guards in AgentStore and ReflectionStore that throw when rootDir is omitted under Vitest
- Keep default .fusion root resolution for non-test execution paths
- Prevent accidental test writes to unintended filesystem locations by forcing explicit paths
- Handle retry API "not in an error state" responses by refreshing the server session instead of failing immediately
- Restore the correct view state for generating, awaiting_input, complete, and error sessions during retry recovery
- Reconnect planning/interview/subtask streams only when needed while preserving in-flight output and history
- Add regression tests for connection-loss retry recovery across PlanningModeModal, MissionInterviewModal, and SubtaskBreakdownModal
- Default AgentStore rootDir to resolve(".fusion") so agent data paths are absolute by default
- Default ReflectionStore rootDir to resolve(".fusion") for consistent absolute root resolution
- Validate Database kbDir is absolute and throw a descriptive error when a relative path is provided