Commit Graph

1537 Commits

Author SHA1 Message Date
gsxdsm
47a035fde1 feat(FN-1286): add ErrorBoundary component with page-level, modal, and root-level wrapping
- 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
2026-04-08 20:04:23 -07:00
gsxdsm
2842088216 feat(FN-1238): add dashboard loading screen with animated loader component
- Create DashboardLoader component with pulsing Fusion logo and progress bar animation
- Add CSS keyframe animations for smooth loading states
- Gate initial App render with loader until dashboard data is ready
- Add comprehensive tests for DashboardLoader component and App loading behavior
- Update existing App tests to account for loader wrapper
2026-04-08 19:38:45 -07:00
gsxdsm
7e8a99a9ce fix(FN-1235): restore terminal text input interaction
- Remove the xterm pointer-events override from dashboard styles to allow terminal text input focus and typing
- Add a terminal input CSS contract test to guard against regressions in xterm helper element interactivity
- Add a patch changeset for @gsxdsm/fusion documenting the terminal text input fix
2026-04-08 19:19:49 -07:00
gsxdsm
9240c1b10d feat(FN-1233): theme remaining dashboard checkboxes
- Add todo accent-color styling to markdown-rendered checkbox inputs
- Apply consistent checkbox theming in list view header and row checkbox controls
- Theme workflow form and mission checkbox inputs to match dashboard color tokens
- Update mission toggle checkbox input to use the same todo accent color
2026-04-08 19:09:16 -07:00
gsxdsm
d92237c5a1 feat(FN-1230): inline quick entry advanced controls
- Remove the quick-entry actions dropdown and expose Deps, Attach, Models, Agent, and Save controls directly in the expanded panel
- Simplify overlay state handling by dropping actions-menu logic and tightening Escape dismissal order for model/dependency popovers
- Update QuickEntryBox and ListView tests to assert the new inline controls and revised keyboard behavior
- Clean up quick-entry CSS by deleting actions-dropdown styles and adjusting expanded control layout/alignment
- Refresh AGENTS.md quick-entry documentation to match the inline control UX
2026-04-08 19:00:54 -07:00
gsxdsm
a05cfd4b55 feat(FN-1255): add comment-aware heartbeat wakes and blocked-state dedup
- Add BlockedStateSnapshot typing/export and AgentStore persistence APIs for last blocked heartbeat state
- Deduplicate blocked-task heartbeat comments using blockedBy + context hash, and clear blocked snapshots when tasks are no longer blocked
- Thread triggeringCommentIds/triggeringCommentType through heartbeat execution, wake context, scheduler assignment triggers, and runtime wiring
- Trigger immediate heartbeat runs from task/steering comment routes for assigned immediate-response agents, with validation for comment wake fields on /api/agents/:id/runs
- Expand core, engine, and dashboard tests to cover blocked dedup logic, comment-triggered wakes, validation, and skip scenarios
2026-04-08 18:38:06 -07:00
gsxdsm
8b538988eb test(FN-1156): add AI session lifecycle and reconnect coverage
- Add ai-session-store unit tests for upsert/get round-trips, active filtering, stale recovery, cleanup, thinking debounce, and update/delete events
- Add persistence and resume-history integration tests for planning, subtask, and mission interview sessions across SQLite reload and cancellation flows
- Add reconnect and cross-tab lock tests covering SSE Last-Event-ID replay, keep-alive ping touches, optimistic lock conflicts, stale lock expiry, and lock release on tab close
- Expand useBackgroundSessions hook tests for SSE-driven updates/deletes, project-scoped fetch/stream behavior, counts, dismiss, and refresh state handling
2026-04-08 18:13:36 -07:00
gsxdsm
b2f0df5455 feat(FN-1219): add mission observability and autopilot dashboard UX
- Add mission observability types and API helpers, and forward mission events through SSE with mission filtering support
- Expand MissionManager with health indicators, activity/event log views, improved autopilot controls, and activity auto-scroll behavior
- Refine mission detail mobile controls and styling updates for responsive observability surfaces
- Add regression coverage for MissionManager behavior/mobile CSS and SSE mission filtering
- Include a changeset documenting the mission dashboard observability update
2026-04-08 18:08:06 -07:00
gsxdsm
61117c8a2b feat(FN-1254): add inbox-lite task selection for heartbeat agents
- Add InboxTask typing and TaskStore.selectNextTaskForAgent() with priority ordering, dependency checks, paused filtering, and FIFO selection
- Wire heartbeat execution to auto-select and assign inbox work when no task is set, with optional checkout attempts and graceful conflict fallback
- Add POST /api/agents/:id/inbox to expose next-task selection details (task, priority, reason) and return task:null when no work is available
- Expand core, engine, and dashboard tests to cover selection priorities, heartbeat precedence/metadata, checkout-conflict handling, and route behavior with type-safe mocks
2026-04-08 17:57:16 -07:00
gsxdsm
86e3869f75 feat(FN-1155): add AI session cleanup scheduling and API controls
- Enhance AiSessionStore cleanup logic to handle stale generating/awaiting_input sessions and remove expired records consistently
- Add a dedicated API route to trigger AI session cleanup and return cleanup results
- Wire scheduled server-side cleanup startup/shutdown behavior using configurable interval and TTL settings
- Expand dashboard tests to cover cleanup logic, route behavior, and cleanup endpoint scenarios
2026-04-08 17:26:34 -07:00
gsxdsm
2911fe7d44 feat(FN-1253): implement task checkout leasing end-to-end
- Add checkout lease types and conflict error exports, plus DB schema v20 migration for checkedOutBy/checkedOutAt
- Persist checkout lease fields in TaskStore and add AgentStore checkout/release/force-release/get-holder operations
- Add dashboard checkout API routes for acquire/release/force-release/status with explicit 409 conflict and 403 holder enforcement
- Enforce checkout ownership in heartbeat execution with graceful checkout_conflict exits when another agent holds the lease
- Expand core and dashboard test coverage for schema, store behavior, API routes, and leasing workflows, and document leasing behavior in AGENTS.md
2026-04-08 17:01:44 -07:00
gsxdsm
e5dc8373b9 feat(FN-1154): sync AI session state across browser tabs
- Add a shared AiSessionSync store with BroadcastChannel + storage fallback, ownership locks, heartbeats, and stale-tab detection
- Merge cross-tab session snapshots into useBackgroundSessions with timestamp guards and rebroadcast SSE updates to peers
- Update background session UI and planning/mission/subtask modals to show active-tab lock status and only allow takeover when ownership is stale
- Add hook tests covering sync store messaging/fallback behavior and background session cross-tab merge flows
2026-04-08 16:48:35 -07:00
gsxdsm
b17d4c9b73 feat(FN-1215): refresh settings branding and scope banner theming
- Update Settings modal copy from fn to Fusion for shared/project messaging
- Adjust worktree naming example to use uppercase task IDs (FN-042)
- Make scope banner colors theme-aware using info/success CSS variables with color-mix
- Update desktop and mobile Settings modal tests for the new Fusion scope text
2026-04-08 16:37:13 -07:00
gsxdsm
719cf901aa feat(FN-1320): re-engage autopilot when resuming missions
- Re-engage MissionAutopilot when a paused mission is resumed with autopilot enabled
- Wire mission autopilot into dashboard route setup so resume flows can trigger watcher start
- Extend mission e2e tests to cover autopilot mock shape and resume re-engagement behavior
- Add a patch changeset documenting the mission resume autopilot fix
2026-04-08 16:29:46 -07:00
gsxdsm
e044cfbed7 feat(FN-1211): add collapsible advanced options to task form
- Split TaskForm into a primary section and a collapsible "More options" block for dependencies, models, workflow steps, and attachments
- Auto-expand advanced options when non-default values exist and reset dependency dropdown state when the section is collapsed
- Restyle modal form hierarchy, description actions, and advanced option container for clearer visual grouping across desktop and responsive layouts
- Update NewTaskModal and TaskForm tests to open and assert advanced fields through the new More options toggle
2026-04-08 16:23:08 -07:00
gsxdsm
f60c06be79 feat(FN-1298): add stop-agent-run flow across engine and dashboard
- Add heartbeat stopRun support in the engine and wire it into the dashboard server lifecycle
- Add an agent run stop API route and client helper with route-level test coverage
- Add stop controls in AgentDetailView and AgentRunHistory with updated UI tests
- Add a changeset for @gsxdsm/fusion documenting the new stop run feature
2026-04-08 16:17:34 -07:00
gsxdsm
02148d79b6 feat(FN-1153): add cross-tab locks for AI planning sessions
- Bump SQLite schema to v19 with ai_sessions lock columns and lock index, and align migration coverage in core DB tests
- Extend AiSessionStore with acquire/release/force lock APIs, stale lock cleanup, and lock metadata in ai_session update summaries
- Enforce lock checks on planning, subtask, and mission interview mutation routes with 409 conflict responses while keeping stream reads unaffected
- Add frontend tab identity + useSessionLock hook and wire Planning, Subtask, and Mission modals to pass tabId, show lock overlay, and support Take Control
- Expand dashboard route/e2e and modal tests to validate lock enforcement, lock handoff, and lock-aware session reentry behavior
2026-04-08 16:14:32 -07:00
gsxdsm
55e8b6fd94 feat(FN-1209): add quick entry image attachment flow
- Return the created task from board quick create and propagate the onQuickCreate return type through board/list components
- Add pending image handling in QuickEntryBox with paste support, hidden file input, and an Attach action in the menu
- Render removable pending image previews, include image count in the actions badge, and clean up object URLs on reset/unmount
- Upload pending images after task creation with error toasts for failed uploads, and extend tests for attachment and quick-create behavior
2026-04-08 16:03:46 -07:00
gsxdsm
8aa77c8b77 refactor(FN-1288): consolidate GitHub remote parsing in @fusion/core
- Replace dashboard calls to local getCurrentGitHubRepo helpers with getCurrentRepo from @fusion/core
- Update engine scheduler PR-monitor startup paths to use shared core repo resolution
- Remove duplicated remote parsing implementations from dashboard and engine packages
- Mark gap analysis finding 6.3 as resolved after centralizing parsing logic
2026-04-08 15:53:38 -07:00
gsxdsm
0304a3df20 fix(FN-1207): improve mobile header search behavior
- Replace delayed focus effect with native autoFocus on the mobile search input
- Constrain expanded mobile search positioning and width to prevent overflow on small viewports
- Add Header tests covering mobile search auto-focus and expanded container rendering
2026-04-08 15:41:18 -07:00
gsxdsm
d66300c794 feat(FN-1236): migrate GitHub PR workflows to gh authentication
- Require gh-authenticated paths for task pr-create and dashboard PR routes
- Switch dashboard command and extension GitHub tools to use the gh auth client instead of token-based auth
- Update CLI and dashboard tests to cover gh-only createPr and import behavior
- Refresh README guidance and add a changeset removing the GitHub token requirement for PR flows
2026-04-08 15:40:39 -07:00
gsxdsm
a47db4fa6b feat(FN-1206): promote missions to an inline top-level view
- 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
2026-04-08 15:33:19 -07:00
gsxdsm
e80fb448d4 feat(FN-1152): add retry flows for failed AI planning sessions
- Keep errored AI sessions retryable in the session store and add backend retry handlers for planning, subtask breakdown, and mission interview flows
- Add retry API routes and dashboard API client helpers for planning, subtask, and mission interview session retries
- Update PlanningModeModal, SubtaskBreakdownModal, MissionInterviewModal, and background session handling to show error states with retry/cancel UX
- Expand unit and integration tests across store, services, routes, and modal components to cover retry success and failure paths
2026-04-08 15:10:46 -07:00
gsxdsm
5f53949e2a feat(FN-1192): migrate agent log styling to theme classes
- Add dedicated AgentLogViewer CSS classes for model header layout, badge/timestamp rows, and tool/thinking/result/error states
- Remove inline style objects from AgentLogViewer and switch rendered elements to semantic class names for theme-driven styling
- Update AgentLogViewer tests to verify class-based styling behavior instead of inline style attributes
2026-04-08 15:02:32 -07:00
gsxdsm
af23d6ddb8 feat(FN-1222): add distributed node discovery APIs
- Add discovery configuration and node metadata types in core, including exported interfaces for consumers
- Implement a NodeDiscovery service and wire it into CentralCore with lifecycle hooks and discovery helpers
- Add comprehensive unit coverage for NodeDiscovery behavior and CentralCore discovery integration
- Expose discovery REST endpoints in dashboard routes for config, node listing, and summary/health data
- Add frontend discovery API helpers and route-level tests, plus dependency updates in lockfiles
2026-04-08 14:58:34 -07:00
gsxdsm
c1918c6819 feat(FN-1318): rename CLI binary artifacts from kb to fn
- Update CLI build and runtime paths to emit and reference fn-named binaries across default and cross-target builds
- Adjust Bun binary bootstrap stubs and native patch temp/symlink prefixes to use fn naming consistently
- Update CI, release, and test-release workflows to validate and collect fn-prefixed artifacts
- Align CLI build and package config tests with fn binary expectations and add a patch changeset for @gsxdsm/fusion
2026-04-08 14:47:30 -07:00
gsxdsm
65e98af3b5 feat(FN-1180): improve dashboard modal mobile responsiveness
- Add responsive rules for Workflow Step Manager tabs, cards, templates, and footer actions on small screens
- Refactor ScriptsModal to use dedicated CSS classes and mobile-friendly list/form/action layouts
- Add mobile breakpoint adjustments for Scheduled Tasks and Setup Wizard modal spacing and controls
- Optimize model onboarding for mobile with full-width modal layout and stacked provider/API key inputs
- Improve activity log and changes diff mobile behavior with touch-friendly rows, wrapped actions, and horizontal diff scrolling
2026-04-08 14:45:52 -07:00
gsxdsm
42bb54ad89 docs(FN-1319): align AGENTS task ID examples with FN prefix
- Update AGENTS.md examples to use FN-style task IDs instead of KB-style IDs
- Keep documented commit/message conventions consistent with the project task ID format
2026-04-08 14:43:12 -07:00
gsxdsm
1d57fb4b50 refactor(FN-1317): rename remaining kb references to fn
- Update executor, triage, and merger prompt strings to identify the product as "fn"
- Align branch/worktree documentation examples with fusion/fn-* naming conventions
- Rename dashboard websocket attachment guard from __kbWebSocketsAttached to __fnWebSocketsAttached
- Refresh engine tests, dashboard utility comments, and TUI header text to remove stale kb wording
2026-04-08 14:38:36 -07:00
gsxdsm
9ad0b8be24 feat(FN-1216): rename extension tools to fn_* across CLI and docs
- Rename all pi extension tool registrations from kb_* to fn_* across task, mission, and agent tool families
- Update extension and skill-sync tests plus Fusion skill docs/workflows to assert and document the new fn_* tool names
- Align product-identity strings across core, dashboard, and CLI references, including GitHub import examples, User-Agent headers, and terminal TERM_PROGRAM
- Add a @gsxdsm/fusion minor changeset describing the extension tool-prefix rename
2026-04-08 14:26:30 -07:00
gsxdsm
324f28a90c feat(FN-1151): preserve and display planning conversation history
- Persist per-turn thinking output for planning and mission interview sessions, including history serialization and recovery-safe state fields
- Add shared conversation history parsing/API types and a reusable timeline component with formatted answers and expandable AI reasoning
- Restore and render conversation history across Planning Mode, Mission Interview, and Subtask Breakdown modals during resume and live question flow
- Harden response submission with nullable-question guards and expand unit/e2e coverage for history rendering and persistence behavior
2026-04-08 14:17:20 -07:00
gsxdsm
8354a86a82 feat(FN-1196): support API-key providers in dashboard auth flow
- Wrap dashboard auth storage with API-key provider helpers derived from model registry providers
- Normalize provider display names and bridge set/clear/has API-key operations to AuthStorage credentials
- Expand route and onboarding tests for mixed OAuth/API-key states and API-key-authenticated setup paths
- Stabilize assignment-trigger heartbeat timing test by replacing fixed delays with waitFor assertions
2026-04-08 13:54:30 -07:00
gsxdsm
8c0d30d206 feat(FN-1190): add agent export for Agent Companies packages
- Add a core exporter that generates COMPANY.md, per-agent AGENTS.md files, and optional SKILL.md stubs with stable slug/link handling
- Export new Agent Companies exporter APIs from @fusion/core and extend manifest kinds to include skill entries
- Add fn agent export with project-aware agent loading, optional company metadata flags, and export summary/error output
- Add POST /api/agents/export route with request validation, agent ID filtering, custom/default output directory support, and exporter integration
- Add focused tests for core exporter behavior, CLI export command, and dashboard route handling
2026-04-08 13:31:07 -07:00
gsxdsm
fd4ba8ab34 feat(FN-1150): add session notification banner for awaiting input
- Add SessionNotificationBanner to list awaiting_input AI sessions with type-specific labels/icons and resume or dismiss actions
- Integrate the banner into App project layout and wire resume handlers for planning, subtask, and mission interview sessions
- Add dismiss-all handling that clears all currently awaiting-input background sessions from the banner
- Style the banner with sticky placement, entry animation, responsive layout, and action button states
- Add component tests covering filtering, count rendering, resume/dismiss callbacks, type metadata, and local dismissal behavior
2026-04-08 13:18:28 -07:00
gsxdsm
67ce1ca2ca feat(FN-1171): add agent soul memory and employees workflows
- Add soul and memory fields to agent types and AgentStore with persistence/update test coverage
- Add dashboard routes and API helpers to fetch and update agent soul/memory data
- Extend AgentDetailView with Soul, Memory, and Employees tabs and rename children labels to employees
- Normalize employee route params for type safety and add focused route/component tests for the new flows
2026-04-08 13:00:12 -07:00
gsxdsm
d3c5f35f3d feat(FN-1179): improve dashboard core modal mobile behavior
- Update core modal CSS for mobile breakpoints across task detail, new task, settings, and git manager flows
- Align spacing, sizing, and responsive layout rules to keep modal interactions usable on small screens
- Add core-modals-mobile tests to verify mobile-specific CSS behavior and regression coverage
- Document the modal mobile adaptations in the dashboard README for maintainability
2026-04-08 12:59:39 -07:00
gsxdsm
b0b3ca7e4b fix(FN-1300): capture agent run output in heartbeat and step sessions
- Wire AgentLogger into heartbeat runs, including tool/text callbacks and stdout excerpts on run records
- Persist heartbeat context taskId snapshots earlier and ensure logger flushes on success and failure paths
- Pass TaskStore into StepSessionExecutor and flush per-attempt agent logs in finally cleanup
- Expand heartbeat and step-session tests to verify log persistence and flush behavior, and add a patch changeset for @gsxdsm/fusion
2026-04-08 12:46:24 -07:00
gsxdsm
f465c3688c docs(FN-1315): update AGENTS.md CLI references to fn
- Replace kb CLI command examples with fn equivalents across multi-project documentation
- Update project resolution and error message examples to reference fn commands
- Align terminology from kb to fn/Fusion in architecture and runtime sections
2026-04-08 12:43:25 -07:00
gsxdsm
156d49f70b fix(FN-1287): standardize dashboard API error responses
- Add shared ApiError class and response helpers for consistent error shape
- Migrate routes and mission-routes handlers to use standardized API errors
- Update server error middleware, rate limiter, and node metrics error handling to use shared helpers
- Expand dashboard tests with ApiError coverage and standardized response assertions
- Add a changeset documenting the @gsxdsm/fusion patch for API error shape standardization
2026-04-08 12:37:47 -07:00
gsxdsm
def7b82a7f docs(FN-1314): document headless fn serve mode
- Add a dedicated AGENTS.md section describing fn serve as a headless node runtime
- Document serve flags, remote binding defaults, and differences from fn dashboard behavior
- Capture startup banner, lifecycle state updates, graceful shutdown order, and implementation references
- Add /api/health endpoint details and common remote and Docker usage examples
2026-04-08 12:36:52 -07:00
gsxdsm
134f9d8c23 fix(FN-1313): use stable mission event ordering
- Replace mission event list sorting fallback from rowid to id for deterministic ordering
- Update latest mission error lookup to order by id instead of rowid when timestamps tie
2026-04-08 12:36:19 -07:00
gsxdsm
686b1e3f8a feat(FN-1301): add Projects action to mobile more sheet
- Add a Projects entry with icon and test id in the mobile More sheet actions
- Extend MobileNavBar props with onViewAllProjects and trigger it via the shared more-sheet action handler
- Wire App to pass handleViewAllProjects into MobileNavBar so the new action opens project selection
- Add test coverage for rendering the Projects item and invoking its callback while closing the sheet
2026-04-08 12:30:24 -07:00
gsxdsm
754cebb641 test(FN-1312): add mobile feature access regression guard
- Add dashboard regression tests that keep board, list, and agents views reachable on mobile
- Verify mobile header overflow preserves project navigation and All Projects access
- Assert More-sheet secondary actions and mobile-nav visibility fallbacks remain accessible
2026-04-08 12:29:35 -07:00
gsxdsm
abbb4eab11 feat(FN-1272): add task document tools for triage and executor
- Add task_document_write and task_document_read factories with schemas, revision-aware responses, and error handling in agent-tools
- Wire document tools into executor and triage sessions and update prompts to persist and reuse planning artifacts across runs
- Export document tool factories and parameter schemas from engine public entrypoints while keeping executor re-export compatibility
- Add comprehensive tests covering write/read success paths, empty/not-found cases, and store failure handling
2026-04-08 12:27:11 -07:00
gsxdsm
dc4db25786 feat(FN-1178): harden mobile responsiveness across agent modals
- Add mobile full-screen and safe-area CSS rules for agent dialogs, including touch-friendly inputs and footer actions
- Remove hardcoded inline width constraints from AgentGenerationModal so mobile styles can fully apply
- Fill AgentListModal mobile gaps with improved control sizing, wrapped layouts, and single-column behavior at small breakpoints
- Add agent modal mobile regression tests covering responsive classes, breakpoints, and dialog sizing expectations
2026-04-08 12:18:55 -07:00
gsxdsm
e4b758d901 fix(FN-1299): stabilize agent detail refresh callbacks
- Stabilize AgentDetailView callback usage by storing onClose/addToast in refs and removing them from loadAgent dependencies
- Prevent full-screen loading spinner on background refresh by only showing it before the initial agent load
- Memoize detail modal handlers in AgentsView to keep callback identities stable across parent re-renders
- Add regression tests covering callback identity churn and refresh behavior without loading-state flicker
2026-04-08 12:15:54 -07:00
gsxdsm
786c9309e1 feat(FN-1297): prevent mobile detail open from control taps
- Broaden TaskCard touch target detection from HTMLElement to Element so nested SVG targets are treated as interactive
- Keep mobile tap handling from opening task details when pressing card controls
- Add board-mobile regressions for edit button taps, steps toggle taps, and SVG-inside-button touch events
2026-04-08 12:10:16 -07:00
gsxdsm
a997436b7c feat(FN-1270): add task document storage with revision history
- Add task document domain types and key validation helpers in core types
- Introduce schema v18 migration creating task_documents and task_document_revisions tables with indexes
- Implement TaskStore CRUD/upsert APIs for task documents, including revision archiving and task update events
- Export task document types from the core index for downstream consumers
- Add comprehensive task document tests and update database schema/version assertions
2026-04-08 12:09:41 -07:00
gsxdsm
105d224b7f feat(FN-1264): enforce heartbeat budget governance for trigger execution
- Gate heartbeat runs in executeHeartbeat when agents are over budget and skip timer runs above threshold
- Pause agents with pauseReason "budget-exhausted" when run usage pushes them over budget
- Budget-gate assignment and timer triggers in HeartbeatTriggerScheduler and include budgetStatus in assignment wake context
- Expand agent-heartbeat test coverage for budget exhaustion, threshold behavior, pause transitions, and trigger gating
2026-04-08 12:03:38 -07:00
gsxdsm
9219323bc0 feat(FN-1277): hydrate dashboard theme settings from backend
- Hydrate useTheme from global settings while seeding initial state from localStorage cache to prevent flash
- Add write-through theme persistence so setter updates local cache immediately and asynchronously saves via updateGlobalSettings
- Clarify Settings modal save behavior for intentional idempotent global theme writes
- Expand useTheme and App tests to cover backend hydration, fallback handling, and new global settings fetch expectations
2026-04-08 11:58:18 -07:00