Adds a thinking-level (reasoning-effort) selector to the quick-create model pickers, matching the levels already available in the full task pickers.
- ModelSelectionModal: adds optional thinking-level <select> (off/minimal/low/medium/high/xhigh) with a status badge, rendered only when onThinkingLevelChange is supplied
- QuickEntryBox: wires thinking-level state through to ModelSelectionModal and persists the override with quick-created tasks
- InlineCreateCard: same thinking-level wiring for the inline task creation card
- Adds i18n strings for the new thinking-level labels across en/es/fr/ko/zh-CN/zh-TW locale files
- Adds test coverage in InlineCreateCard.test.tsx, ModelSelectionModal.test.tsx, and QuickEntryBox.test.tsx for the new selector
Files changed:
.../dashboard/app/components/InlineCreateCard.tsx | 16 ++++-
.../app/components/ModelSelectionModal.tsx | 47 +++++++++++++-
.../dashboard/app/components/QuickEntryBox.tsx | 67 ++++++++++++++++++-
.../components/__tests__/InlineCreateCard.test.tsx | 70 ++++++++++++++++++++
.../__tests__/ModelSelectionModal.test.tsx | 69 ++++++++++++++++++++
.../components/__tests__/QuickEntryBox.test.tsx | 75 ++++++++++++++++++++++
packages/i18n/locales/en/app.json | 2 +
packages/i18n/locales/es/app.json | 2 +
packages/i18n/locales/fr/app.json | 2 +
packages/i18n/locales/ko/app.json | 2 +
packages/i18n/locales/zh-CN/app.json | 2 +
packages/i18n/locales/zh-TW/app.json | 2 +
12 files changed, 351 insertions(+), 5 deletions(-)
Fusion-Task-Id: FN-7746
Fusion-Task-Lineage: 4a221203-0222-47d6-93f8-632638bcfbfe
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Many loading states rendered bare "Loading…" text with no spinner
element, and a couple rendered an unstyled `loading-spinner` div with no
matching CSS (invisible). The global spin animation was never broken —
it rotates in Chromium and WebKit — so prior transform-box edits chased
a non-bug, validated only by a string-matching CSS test.
Add a shared <LoadingSpinner> (self-contained animated SVG, no
lucide-react import so it survives partial test mocks) and adopt it
across ~47 loading placeholders so every loading state shows a
consistent animated spinner. Includes a component test that asserts the
svg carries the animate-spin utility.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Dropdown: aria-multiselectable, drop dead aria-labelledby, ArrowUp opens panel
- Dirty-state: NewTaskModal tracks enabledWorkflowSteps so toggles trigger discard prompt
- TaskForm: reset optionalStepsLoading on the no-workflow early return
- Node editor: pass plugin step templates into the optional-steps panel (both layouts)
- FNXC requirement comments on the new optional-steps components
Add WorkflowOptionalStepsDropdown — a controlled, portal-rendered multi-select
(listbox a11y, keyboard nav, committed 'Steps: N selected' label matrix,
render-nothing empty state) shared by the quick-add card and (next) the full
modal. Swap InlineCreateCard's inline chip toggles for it; the fetch/seed/submit
wiring is unchanged. Remove the now-unused chip CSS.
Ensure quick task model overrides flow through planning and submission.
- add planning model selection state to inline task creation and include it in submit payloads only when explicitly overridden
- extend the model selection modal with an optional planning-model picker that clears preset mode consistently with other manual overrides
- cover planning, combined overrides, and default omission behavior in inline create card and quick entry tests
Files changed:
packages/dashboard/app/components/InlineCreateCard.tsx | 26 ++++++++-
packages/dashboard/app/components/ModelSelectionModal.tsx | 45 +++++++++++++++
packages/dashboard/app/components/__tests__/InlineCreateCard.test.tsx | 67 +++++++++++++++++++++-
packages/dashboard/app/components/__tests__/QuickEntryBox.test.tsx | 49 ++++++++++++----
4 files changed, 172 insertions(+), 15 deletions(-)
Fusion-Task-Id: FN-6101
Fusion-Task-Lineage: 7c1553d2-3edb-4b23-ad36-77756bbfe1dc
Migration (multi-agent sweep over 216 files, 60 batches):
- Every user-visible dashboard + TUI string moved to t() with the exact
English inline default (en rendering byte-identical)
- Catalogs merged from per-batch fragments: en/zh-CN/zh-TW/fr/es now
carry ~5,930 keys each across common/app/errors/cli namespaces;
CLI bundles regenerated (6 locales incl. ko)
Integration fixes:
- 18 type errors: reserved {{count}} interpolations renamed, malformed
plural call, hand-rolled t-param types replaced with TFunction<"app">
- 23 lint errors: superseded label constants/helpers removed
- ExecutorStatusBar hook-order violation (keyboard-open early return
moved below hooks)
- TUI tests wrapped in I18nextProvider (uninitialized fallback renders
literal {{placeholders}}); dashboard vitest.setup boots a minimal en
i18next instance for the same reason
Known WIP (next commits): ~457 residual strings across 50 batches,
Korean drafts for swept keys, and a dashboard test-suite pass that is
still being stabilized (~283 failures under investigation — fake-timer
waitFor interaction, likely stale node_modules vs merged lockfile).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Greptile + CodeRabbit findings across core/engine/dashboard. Stale findings
(written against earlier commits) verified and skipped; valid ones fixed.
Engine:
- await-input: do not clear pausedReason in the /input route (the node's
marker must survive unpause); the node clears it after consuming input.
Embed a colon-free epoch watermark in the marker so only post-pause steering
comments count as the reply (ISO timestamps collided with the colon
separator and the dashboard question parser).
- gate nodes without a registered runner now fail closed (throw) instead of
silently passing.
- a thrown interpreter error in maybeExecuteWorkflowGraph now falls back to the
legacy pipeline instead of stranding the task in-progress.
- approved-CLI path clears the stale awaiting-cli-approval status/marker.
Core:
- persist+cascade workflow selection: purge task_workflow_selection rows and
compiled workflow_steps on physical task deletes; migration 105 cleans
already-orphaned rows; catch-cleanup for materialized steps when the owner
write fails; WF-id allocation now in a BEGIN IMMEDIATE transaction.
- compiler validates the canonical execute->review->merge seam order (rejects
duplicate/misordered seams).
- disk-backed reopen round-trip + tightened updatedAt/list assertions.
Dashboard:
- WorkflowSelector clears stale default/options across project changes and on
fetch failure; InlineCreateCard/NewTaskModal reset the workflow on all
clear/discard paths and include it in dirty-state.
- WorkflowNodeEditor: config-key deletion now persists; removed an invalid
eslint-disable that was itself a hard lint error.
- TaskCard: single status badge for awaiting-input (no duplicate).
- WorkflowResultsTab: reset paused-action UI between pauses; surface
resume/approve failures inline.
- TaskDetailModal: treat awaiting-user-input/awaiting-cli-approval/paused as
not-in-progress for the live-log subscription.
- workflow-flow-mapping: don't write synthetic node names back into IR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New-task modal and the quick-add card (expanded) now expose a workflow picker;
the chosen workflow is applied to the new task via selectTaskWorkflow right
after creation, non-blocking on failure.
Removes no-op `agents.filter((a) => true)` calls (a leftover from the
terminated AgentState refactor) flagged by eslint and updates affected
tests and fixtures so `terminated` is no longer referenced. Also:
- Deletes the duplicate `state === "paused"` render branch in
AgentListModal list view that produced two "Resume" buttons.
- Updates the AgentDetailView help text to reflect the current
deletable states ("idle or paused").
- Aligns the bundled-plugin-install test with the new auto-load
behavior for already-installed enabled plugins.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops "terminated" from AGENT_STATES. The agent lifecycle now runs through
idle | active | running | paused | error. paused (carrying a pauseReason)
absorbs every former terminated use case — manual stop, heartbeat run
termination, spawned-child cleanup. Run status (agentRuns.status) is
unchanged: "terminated" stays a valid run-status value.
AGENT_VALID_TRANSITIONS allows direct any→idle transitions so resetAgent
no longer needs the intermediate hop.
Stack-wide:
- core/agent-store: lastError clearing + resetAgent simplified.
- engine/agent-heartbeat, executor, in-process-runtime: terminated state
writes → paused; halt-state listener fires on paused/error.
- dashboard: AgentsView/AgentListModal/AgentDetailView lose the Terminated
badge/option/state-block; agent pickers no longer filter terminated;
agentHealth drops the Terminated branch; routes/state cast widened to
the new AgentState union.
Tests across core and engine updated to assert paused for AgentState and
left "terminated" intact for run-status assertions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Resolve merge conflicts in InlineCreateCard and QuickEntryBox using the existing node picker UX
- Replace ad-hoc node status rendering with NodeHealthDot in task creation surfaces
- Keep advanced quick-create controls and portal-based dropdown behavior intact
- Preserve related dashboard styling and tests included in the staged squash
Fusion-Task-Id: FN-2729
- Add node status indicators and labels to task creation, quick entry, task form, and settings node selectors
- Surface selected node health in list bulk-edit controls with status dot styling for online/connecting/offline/error states
- Update dashboard component CSS and shared styles for consistent node status presentation
- Include changeset documenting unavailable-node routing policy and default node behavior
- Add a core node-override-guard module, export it from @fusion/core, and enforce conflicts in store updates
- Add API route and CLI extension safeguards so nodeId override updates are blocked when ownership would conflict
- Wire node override routing and validation through dashboard quick-create, list, modal, settings, and task form/detail surfaces
- Add focused unit and integration tests for core guard logic, workflow routes, and dashboard node override UX
Sweep 2 of the styles.css split. Three card-related blocks moved out of the
monolith into co-located component CSS files. styles.css 4488 → 3304
(–1184 lines).
- /* === Cards === */ (583 lines) → new TaskCard.css
- /* === Card Inline Editing === */ (266 lines) → appended to TaskCard.css
- /* === Inline Create Card === */ (342 lines) → new InlineCreateCard.css
Mobile rules for the moved selectors that previously sat in the global mobile
@media block also followed to their respective component CSS files.
Kept global: .dep-dropdown* (4 consumers — InlineCreateCard, NewTaskModal,
TaskDetailModal, TaskForm). Moving without adding imports to the other 3
consumers would silently break their styling.
CSS imports added at TaskCard.tsx:1 and InlineCreateCard.tsx:1. Verified by
visual smoke test against the live dev server (board view + cards render
correctly).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Wire priority through task creation and update API payloads for dashboard clients
- Add priority selection to TaskForm, New Task modal, and inline create card with default/reset behavior
- Support priority editing and display in Task Detail modal plus non-default priority badges on task cards
- Extend dashboard styles and component tests to cover priority selectors, rendering, and mobile behavior
- TaskCard: four catch((err: any) => err.message) promise handlers in
archive/unarchive/delete/move → catch((err) => getErrorMessage(err)).
- InlineCreateCard + QuickEntryBox: .catch((err: any)) model-load handlers
→ getErrorMessage(err) with existing @fusion/core import.
- TerminalModal: drop (navigator as any).maxTouchPoints — modern lib.dom
types already expose the property.
- serve.ts: remove unused any annotation on OpenRouter model mapper; the
array element type is already inferred from json.data.
- pi.js, runtime-resolution.ts, dashboard.ts, serve.ts, dev-server-port-
detect.ts, devserver-manager.ts: drop now-stale eslint-disable comments
that the cleanup made redundant.
Fix a prompt-builder regression surfaced by agent's `any` cleanup: toolCall
with a raw string `arguments` field must be preserved verbatim (JSON-quoted)
rather than coerced to `{}`; restores a previously-passing test.
Then promote @typescript-eslint/no-explicit-any from warn → error. Future
new anys must either come with a one-line disable + justification or use a
real type. Workspace is now lint-clean (0 problems).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Parallel subagent pass: four typescript-pro agents on non-overlapping scopes.
Patterns applied:
- catch (err: any) { ... err.message ... } → catch (err) { ... getErrorMessage(err) ... }
using the new @fusion/core helper. Bare catch {} where the error was unused.
- SQLite row types: defined typed XxxRow interfaces per table and cast
.all()/.get() results via `as unknown as XxxRow[]` (the double cast is
required because better-sqlite3 returns Record<string, SQLOutputValue>).
- rowToX(row: any) converters: typed argument with the matching row interface.
- Dynamic settings key writes: (settings as Record<string, unknown>)[key].
- React event handlers and setState callbacks: inferred types or concrete
React.{Mouse,Change,Form}Event<...> where needed.
- pi-claude-cli: local PiMessage / PiContext duck types to avoid re-typing
pi-ai concrete shapes; typed Claude stream event message fields.
72 files changed, ~400 anys eliminated. Typecheck passes across the workspace.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add Maximize2/Minimize2 toggle button to QuickEntryBox for fullscreen textarea expansion
- Add Maximize2/Minimize2 toggle button to InlineCreateCard for fullscreen textarea expansion
- Implement single-textarea pattern with positioned container for expand button overlay
- Add description--fullscreen CSS class for fullscreen textarea styling
- Add focus handoff when entering fullscreen mode
- Add comprehensive unit tests for fullscreen expansion in both components
- Tests cover collapsed/expanded states, toggle button visibility, and class application
- Refactor InlineCreateCard to display all action buttons (Plan, Subtask, Deps, Agent, Browser Verify, Preset, Models, Save) in one consolidated footer row
- Remove the separate inline-create-description-actions CSS class and associated styles
- Update InlineCreateCard tests to reflect the new consolidated control layout
- Update AGENTS.md documentation for InlineCreateCard controls description
- Update memory file with implementation notes
- Add a project storage utility with scoped key helpers and key inventories for global vs project state
- Scope dashboard/task view, list preferences, quick-entry drafts, agent/tree state, terminal tabs, usage view, and modal draft persistence to projectId
- Reload persisted UI state when project context changes so per-project settings and drafts do not leak across projects
- Update and expand dashboard tests, including new projectStorage coverage and scoped persistence regression fixes
- Add task-agent assignment API helpers with coverage for assign, unassign, and list endpoints
- Show assigned agent badges on task cards and add assignment controls in TaskDetailModal
- Add agent task management tab plus agent selectors in quick and inline task creation UIs
- Expand component test coverage and include a changeset for the dashboard agent assignment feature
- Add browser verification toggle state to InlineCreateCard and submit browser-verification via enabledWorkflowSteps when selected
- Reset browser verification state after submit/cancel flows to prevent stale workflow selections
- Add InlineCreateCard and NewTaskModal tests that verify enabledWorkflowSteps are included in create payloads
- Add a patch changeset for @gsxdsm/fusion describing the workflow-step visibility fix
- Remove the hardcoded Browser Verification checkbox from TaskForm and rely on configured workflow steps
- Remove the InlineCreateCard Browser toggle and stop injecting browser-verification into create payloads
- Align TaskForm and InlineCreateCard tests with template-only workflow-step selection behavior
- Delete obsolete NewTaskModal and TaskDetailModal assertions for browser-verification controls
- Add CSS custom properties (--kb-logo-accent, --kb-cta-*) for logo accent color and new-task action buttons
- Update logo.svg to use currentColor for theme-aware accent stroke
- Apply tokenized styling to Header logo, QuickEntryBox, InlineCreateCard, ListView, and Column new-task buttons
- Add theme-aware test assertions for logo and CTA buttons in Header, InlineCreateCard, ListView, and QuickEntryBox tests
- Document theme token system in dashboard README
- Extend ModelSelectionModal with preset picker and apply-to-task wiring
- Wire preset state through QuickEntryBox and InlineCreateCard new-task flows
- Add regression tests for preset selection in ModelSelectionModal, QuickEntryBox, InlineCreateCard, and ListView
- Update dashboard README with preset-in-quick-add documentation
- Clean up unused footer-safe-layout test and adjust styles
- Move Plan and Subtask buttons next to the description input in QuickEntryBox, InlineCreateCard, and TaskForm
- Improve action button layout with consistent icon+label pattern and disabled states
- Add CSS styles for new action button group and description-adjacent controls
- Add regression tests for all three task creation surfaces ensuring buttons appear next to description
- Document the description-adjacent AI controls pattern in dashboard README
- Add favorite model selection to QuickEntryBox and InlineCreateCard components
- Wire up model favorites in TaskForm and TaskDetailModal
- Add model favorites management UI to SettingsModal
- Add tests for favorites in InlineCreateCard, QuickEntryBox, TaskForm, ListView, and SettingsModal
- Remove unused CommitDiffTab component and related tests
- Replace inline model dropdown in InlineCreateCard with modal-based ModelSelectionModal
- Add model selection button to Header and SettingsModal for unified access
- Add comment threading support in TaskComments component
- Remove unused useTerminal hook and usage tracking module
- Update tests for modal-based model selection and new components
- Updated /tasks/:id/diff endpoint to use merge-base comparison
- Changed from HEAD~1..HEAD to ...HEAD syntax
- Added fallback to HEAD when merge-base fails
- Verified fix matches /tasks/:id/file-diffs endpoint pattern