Commit Graph

7910 Commits

Author SHA1 Message Date
gsxdsm
87d044f18d fix(dashboard): skill-menu highlight survives identity-only skills revalidation
Root cause of the recurring ChatView skill-menu CI flakes (and a real UX
bug): the highlight-reset effect keyed on filteredSkills array identity,
but useDiscoveredSkillsCache (SWR) re-delivers content-identical lists
with fresh identities — cache reads re-parse JSON and revalidation
notifies a new array. A revalidation landing between a user's (or the
test's) arrow-key press and the next frame wiped the highlight back to 0.

Key the reset on the joined skill-id list instead, so only a semantic
list change resets the keyboard position. Regression test proves the
invariant: deferred revalidation with identical content lands mid-
navigation and the highlight persists (fails on the old identity-keyed
reset in all three vitest projects).

This test family needed three prior stabilization passes (FN-5864,
FN-5745, FN-5725) — this addresses the underlying race rather than the
assertions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 13:16:51 -07:00
gsxdsm
e08a5633fa feat(i18n): language reset-to-auto-detect + review nitpicks (#1352)
Resolves the remaining review threads:

- Reset to auto-detect across all three layers (Greptile): store passes
  language:null through as null-as-delete; dashboard gains an Auto option
  (clearLanguage + hasExplicitChoice in useLanguage, re-detects from
  navigator, syncs cross-tab); CLI accepts 'fn settings set language auto'.
  Catalog keys added for all five locales; tests at every layer.
- CLI i18n test singleton: afterEach locale restore so zh-CN/fr switches
  can't leak across cases (CodeRabbit nitpick)
- useLocaleFormat memoized per locale for stable formatter identities
  (CodeRabbit nitpick)
- settings-reference.md documents the auto reset path

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 13:02:23 -07:00
gsxdsm
75213bbb08 fix(i18n): address PR review feedback
- config: explicit Hans script wins over HK/MO region (zh-Hans-HK -> zh-CN),
  with regression tests for script-vs-region precedence
- dashboard i18n: detection.caches [] so the detector's init-time auto-persist
  can't masquerade as a user choice and suppress server-settings hydration
- LanguageSelector: role=group (radiogroup conflicted with aria-pressed)
- bin: validate --lang against SUPPORTED_LOCALES (fail loudly, not silent
  fallback); help text clarifies the flag is terminal-UI-only
- cli i18n test: assert a real fr catalog lookup (defaultValue could mask a
  catalog that never loaded); comment the async changeLanguage re-init seam
- assert-locale-chunks: only dirs containing common.json count as locales
- plan doc: merge duplicate Ink 6.8->7.0 risk bullets
- AGENTS.md/solution doc: frontmatter field list + normalizer excerpt synced

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 12:29:02 -07:00
gsxdsm
0c3960373f docs(i18n): capture i18n architecture learning + settings-reference language entry
- docs/solutions/architecture-patterns/: knowledge doc covering the Vite
  code-split catalog constraint, zh-CN/zh-TW routing, three-tier language
  persistence, CLI inline-resources init, and the CI failure modes hit
- CONCEPTS.md: seed shared domain vocabulary (Surface, Global Settings,
  Three-Tier Setting, Supported Locale)
- AGENTS.md: surface docs/solutions/ and CONCEPTS.md in Reference docs
- docs/settings-reference.md: add the missing GlobalSettings.language row

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 10:22:30 -07:00
gsxdsm
cfff270be7 fix(i18n): green CI — settings mock + canonical text token
- settings.test.ts mocks @fusion/core; add SUPPORTED_LOCALES to the mock so the
  new language enum import resolves (shard 1).
- LanguageSelector.css used the banned --text-secondary token; switch to the
  canonical --text-muted (shard 2 text-token-canonicalization guard).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 09:13:03 -07:00
gsxdsm
4f6013ff3a test+refactor(i18n): close code-review residuals
- Extract a shared normalizeToSupportedLocale helper in @fusion/i18n used by
  both the CLI env detection and the dashboard navigator detection
  (convertDetectedLanguage), fixing multi-subtag navigator tags (zh-Hans-CN)
  and unifying Chinese script resolution.
- Add a cross-tab storage listener to useLanguage so a language change in one
  tab propagates to others.
- Dedup the namespace lists into packages/i18n/namespaces.json, consumed by
  config.ts and all three build scripts (no more 3-way drift risk).
- Add tests: dashboard i18n/index.ts (document.lang mirror, init non-blocking),
  useLanguage concurrent-hydration race + cross-tab adoption,
  normalizeToSupportedLocale, namespace-source consistency.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 09:03:16 -07:00
gsxdsm
f707b62155 fix(i18n): address code-review findings
- Validate GlobalSettings.language at the write boundary (store.ts) via
  validateLocale, so invalid locales are dropped not persisted (api-contract P1).
- Fix detectEnvLocale: Traditional-script env tags (zh_Hant/zh_Hant_TW/zh_HK/
  zh_MO) now resolve to zh-TW instead of Simplified; use replaceAll for
  multi-underscore POSIX tags (adversarial P2). Add coverage.
- Agent-native parity: add 'language' to the CLI settings allowlist
  (VALID_SETTINGS + GLOBAL_ONLY + enum) so 'fn settings set language' works
  like the dashboard switcher.
- Document --lang in the bin.ts help table (api-contract P3).
- Derive the expected locale-chunk count from the locales dir instead of a
  hardcoded 5 (maintainability), and add prebuild:client so a raw vite build
  on a fresh clone still syncs catalogs (adversarial P2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:51:41 -07:00
gsxdsm
959557ade8 chore(i18n): satisfy lint on node scripts; mark plan completed
Add /* global */ directives to the i18n node scripts (matching the existing
prepare-publish-manifest.mjs convention) and flip the plan status to completed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:35:49 -07:00
gsxdsm
ece6cc6635 feat(i18n): add machine-drafted translations and contributor docs (U8)
Fill zh-CN, zh-TW, fr, and es catalogs for the migrated keys. zh-CN and zh-TW
are independently localized (Simplified vs Traditional script + Taiwan
vocabulary, e.g. 项目/任务 vs 專案/工作), not script-converted. Translations are
machine-drafted and flagged for human review in locales/TRANSLATION_STATUS.md.

Add docs/i18n-contributing.md (translate / add-a-language / --lang usage) and
cross-link it from contributing.md and cli-reference.md. i18n:status reports
100% for all four locales across the migrated key set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:33:34 -07:00
gsxdsm
4b0a6df635 feat(cli): migrate TUI board strings to i18n (U7)
Establish the terminal-UI migration pattern: route BoardView's loading/empty
labels through useTranslation("cli"), keeping single-letter keybinding
accelerators literal via interpolation ([{{key}}]). Add the keys to the en cli
catalog, sync the four locales, and regenerate the CLI import map. Tests cover
the migrated label and accelerator preservation. The remaining TUI labels are
deferred long-tail work; the pattern is in place.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:30:54 -07:00
gsxdsm
454b6cd0e9 feat(cli): add terminal-UI i18n runtime and upgrade Ink to 7 (U6)
Add a synchronous Node-side i18next instance built from the generated
@fusion/i18n CLI catalog map (no async backend, first frame localized), with
locale precedence --lang flag -> GlobalSettings.language -> env (LC_ALL/LANG/..)
-> en. Wrap the Ink DashboardApp render in <I18nextProvider> and thread a
--lang flag through runDashboard.

Upgrade ink 6.8 -> 7.0 (native CJK double-width measurement) and raise the
react/@types/react peer floor to ^19.2.0. A spike test confirms react-i18next
works under Ink's custom reconciler: localized first frame + re-render on
changeLanguage (including CJK), retiring the KTD1 unknown.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:28:52 -07:00
gsxdsm
677fb9c46c feat(dashboard): establish string-migration pattern and locale formatting (U5)
Add the two reusable migration primitives: useLocaleFormat (date/number bound
to the active locale, replacing implicit-browser-locale toLocale* calls — R8)
and useColumnLabel (translate core COLUMN_LABELS via common:columns.* with
English fallback). Migrate the Settings Appearance heading to t() as a worked
example. The bulk migration of the ~464-file long tail is deferred follow-up
work per the plan's Scope Boundaries; the pattern and primitives are in place
so remaining clusters are mechanical.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:22:49 -07:00
gsxdsm
3ae1fc3830 feat(dashboard): add language switcher and persistence (U4)
Add useLanguage (three-tier persistence mirroring useTheme: localStorage cache
+ server GlobalSettings write-through + hydrate-on-mount, local choice wins)
and a LanguageSelector rendered in the Settings Appearance section. Switching
applies in place via i18n.changeLanguage — no reload, so unsaved state and
in-flight agent views survive. Endonyms name each language in its own script.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:19:44 -07:00
gsxdsm
cd71b92930 feat(dashboard): add i18n runtime with per-locale code-splitting (U3)
Initialize the browser i18next instance with lazy per-locale catalog loading,
localStorage->navigator->htmlTag detection, script-aware zh fallback, and the
shared @fusion/i18n config. Catalogs are synced from @fusion/i18n into a
gitignored app/locales/ (predev/prebuild) and imported app-relative so Vite
emits one chunk per locale/namespace (verified: 15 chunks, none inlined into
the main bundle). First paint is gated on i18nReady to avoid raw-key flashes;
<I18nextProvider> wraps the App provider stack; vendor-i18n manualChunk added.

A build-assertion script (verify:locale-chunks) guards the KTD3a splitting
invariant. Fallback/namespace behavior is covered by @fusion/i18n config tests;
the live instance is verified via the build assertion rather than a unit test
(the dynamic catalog backend is impractical to exercise in vitest).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:16:08 -07:00
gsxdsm
9072d71306 feat(i18n): add @fusion/i18n package, catalogs, and i18next-cli tooling (U2)
Create the @fusion/i18n package as the authored source-of-truth: shared
i18next config (namespace split, script-aware zh-CN/zh-TW fallback, plural
setup), en base catalogs, and a generated CLI static-import map so the
terminal surface is drop-in for new locales. Add the i18next-cli workflow
(extract/sync/types/status/lint) wired as root i18n:* scripts, install the
i18next stack into dashboard + CLI, strip @fusion/i18n from the published CLI
manifest, gitignore the generated dashboard catalog tree, and add a changeset.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:00:31 -07:00
gsxdsm
b8045b6f2b feat(core): add locale primitives and GlobalSettings.language (U1)
Add SUPPORTED_LOCALES (en, zh-CN, zh-TW, fr, es), Locale, DEFAULT_LOCALE,
isLocale, and validateLocale to @fusion/core, plus an optional
GlobalSettings.language field registered in the schema defaults and keys.
Locale primitives live in types.ts so the dashboard's @fusion/core->types.ts
Vite alias can reach them. language defaults to undefined (resolve-at-runtime).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 07:51:25 -07:00
gsxdsm
ea8bde9421 docs: add UI localization (i18n) implementation plan
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 07:51:25 -07:00
gsxdsm
6c7ed1e1fc docs: add compound-engineering plugin implementation plan
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 17:41:26 -07:00
gsxdsm
d9941c3886 docs: add compound-engineering plugin requirements (brainstorm + review)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 17:24:17 -07:00
gsxdsm
bb87ac0693 FN-5905: remove orphaned .skip stubs from soft-delete test
Remove obsolete placeholder skips from the soft-delete end-to-end suite.

- delete six orphaned `it.skip(...)` stub cases from `soft-delete-end-to-end.test.ts`
- keep the reliability interaction test focused on active end-to-end assertions instead of cross-file placeholder notes

Files changed:
 packages/engine/src/__tests__/reliability-interactions/soft-delete-end-to-end.test.ts | 49 ----------------------
 1 file changed, 49 deletions(-)

Fusion-Task-Id: FN-5905
Fusion-Task-Lineage: 2edd9ef8-e5f4-492e-9bd0-a58963ac2e58
2026-06-02 16:21:07 -07:00
gsxdsm
a75e3c18da docs: add open ideation pass for Fusion
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 16:19:23 -07:00
gsxdsm
32f8cac284 FN-5903: fix SkillsView mobile row wrapping
Keep mobile discovered-skill rows aligned after toggles and skill enablement.

- keep .skills-view-item rows from wrapping at the mobile breakpoint
- let .skills-view-item-info flex instead of forcing full-width stacking
- add CSS regression coverage for the mobile row layout and toggle geometry
- add component coverage that preserves row structure across enabled and disabled toggle states

Files changed:
 packages/dashboard/app/components/SkillsView.css   |  5 ++-
 .../components/__tests__/SkillsView.css.test.ts    | 49 ++++++++++++++++++++++
 .../app/components/__tests__/SkillsView.test.tsx   | 47 +++++++++++++++++++++
 .../__tests__/skills-view-mobile.test.tsx          |  9 ++--
 4 files changed, 104 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-5903

Fusion-Task-Lineage: 1004a702-28e7-4e7e-af22-591cc122be01
2026-06-02 16:11:42 -07:00
gsxdsm
8666c9fdc2 docs: add product STRATEGY.md anchor
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 15:59:48 -07:00
gsxdsm
3b9ff42073 FN-5901: reap stale mission validator runs
Add self-healing recovery for stale mission validator runs left behind after execution ownership disappears.

- add mission-store support to find and reap stale running validator runs, preserving terminal error status and resetting eligible features to needs_fix
- teach the mission execution loop and self-healing maintenance sweep to skip live validations, reap abandoned runs, record audit events, and avoid double-completing runs
- extend regression coverage, mission docs, architecture notes, and add a published-package changeset for the new recovery behavior

Files changed:
 .changeset/fn-5901-validator-run-reaper.md         |   7 +
 AGENTS.md                                          |   1 +
 docs/architecture.md                               |   2 +
 docs/missions.md                                   |  26 ++-
 packages/core/src/__tests__/mission-store.test.ts  |  99 +++++++++
 packages/core/src/mission-store.ts                 |  91 ++++++++
 packages/engine/src/__tests__/mission-execution-loop.test.ts   | 232 +++++++++++++++++++++
 packages/engine/src/__tests__/reliability-interactions/mission-validator-run-reaper.test.ts           | 181 ++++++++++++++++
 packages/engine/src/mission-execution-loop.ts      | 102 +++++++--
 packages/engine/src/runtimes/in-process-runtime.ts |   8 +-
 packages/engine/src/self-healing.ts                |  22 ++
 11 files changed, 746 insertions(+), 25 deletions(-)

Fusion-Task-Id: FN-5901

Fusion-Task-Lineage: 87eb2f3f-fc31-4e0a-b0fc-b771f6dc48a3
2026-06-02 15:33:31 -07:00
gsxdsm
93e8bd9940 FN-5899: add mission-goal linking commands and tools
Add mission↔goal linkage support across the API, CLI, and pi-extension surfaces.

- add mission goal list/link/unlink REST endpoints and dashboard route coverage
- add `fn mission goals`, `fn mission link-goal`, and `fn mission unlink-goal` CLI commands with tests
- add `fn_mission_list_goals`, `fn_mission_link_goal`, and `fn_mission_unlink_goal` extension tools plus skill/docs updates
- add a changeset for the published CLI package release

Files changed:
 .changeset/FN-5899-mission-goal-tooling.md         |   5 +
 docs/cli-reference.md                              |  11 +-
 docs/missions.md                                   |  27 ++++
 packages/cli/skill/fusion/SKILL.md                 |   2 +-
 packages/cli/skill/fusion/references/extension-tools.md |  26 ++++
 packages/cli/skill/fusion/references/fusion-capabilities.md |   3 +
 packages/cli/src/__tests__/bin.test.ts             |  21 +++
 packages/cli/src/__tests__/extension-mission-goal-tools.test.ts | 140 +++++++++++++++++
 packages/cli/src/bin.ts                            |  32 +++-
 packages/cli/src/commands/__tests__/mission.test.ts     |  99 +++++++++++-
 packages/cli/src/commands/mission.ts               | 102 +++++++++++++-
 packages/cli/src/extension.ts                      | 170 +++++++++++++++++++++
 packages/dashboard/src/__tests__/mission-goal-links-routes.test.ts | 151 ++++++++++++++++++
 packages/dashboard/src/mission-routes.ts           | 153 ++++++++++++++++++-
 14 files changed, 930 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-5899

Fusion-Task-Lineage: c63b0f4b-c77e-4229-ade4-537a4dda0f5f
2026-06-02 14:47:51 -07:00
gsxdsm
30a09e3422 FN-5896: persist mission-goal linkage in schema
Persist mission↔goal relationships through the core mission schema and store APIs.

- add the mission_goals join table, schema migration coverage, and schema version bump to 101
- add MissionStore goal link/unlink/list helpers plus a MissionGoalLink type and emitted linkage events
- add regression tests for persistence, idempotency, ordering, and cascade behavior, and document the new linkage model with a published changeset

Files changed:
 .changeset/fn-5896-mission-goal-linkage.md         |   5 +
 docs/missions.md                                   |  19 +++
 docs/storage.md                                    |   1 +
 packages/core/src/__tests__/db-migrate.test.ts     |  49 ++++++-
 packages/core/src/__tests__/db.test.ts             |  34 ++---
 packages/core/src/__tests__/goals-schema.test.ts   |   4 +-
 packages/core/src/__tests__/insight-store.test.ts  |  10 +-
 .../src/__tests__/merge-request-record.test.ts     |   2 +-
 .../core/src/__tests__/mission-goals-link.test.ts  | 142 +++++++++++++++++++++
 packages/core/src/__tests__/mission-store.test.ts  |   4 +-
 packages/core/src/__tests__/run-audit.test.ts      |   2 +-
 packages/core/src/__tests__/secrets-schema.test.ts |   6 +-
 .../core/src/__tests__/store-merge-queue.test.ts   |   2 +-
 packages/core/src/__tests__/task-documents.test.ts |   2 +-
 packages/core/src/db.ts                            |  31 ++++-
 packages/core/src/mission-store.ts                 | 111 ++++++++++++++++
 packages/core/src/mission-types.ts                 |   6 +
 .../src/store/__tests__/roadmap-store.test.ts      |   2 +-
 18 files changed, 391 insertions(+), 41 deletions(-)

Fusion-Task-Id: FN-5896

Fusion-Task-Lineage: a4c7c495-b20a-454b-9605-782671cdd8c8
2026-06-02 14:41:41 -07:00
gsxdsm
8d9bbc1906 FN-5895: fix MissionManager interview resume behavior
Keep MissionManager mission interview state and detail rendering in sync while stabilizing the failing test coverage.

- reload assertion-linked feature data when mission details or milestone panels load
- keep selected mission detail state synchronized after mission update events instead of forcing a full mission reload
- hide the sidebar edit form while the selected mission is already being edited in the detail pane
- add a non-destructive Send to background action for resume-launched mission interview modals
- tighten MissionManager tests to target the detail pane and slice-scoped controls that now render alongside sidebar content

Files changed:
docs/missions.md                                   |  2 +-
 .../app/components/MissionInterviewModal.tsx       | 30 ++++++++
 .../dashboard/app/components/MissionManager.tsx    | 77 +++++++++++--------
 .../components/__tests__/MissionManager.test.tsx   | 88 +++++++++++++++-------
 4 files changed, 137 insertions(+), 60 deletions(-)

Fusion-Task-Id: FN-5895

Fusion-Task-Lineage: d018a945-33a7-4471-9636-35bc36dc88a9
2026-06-02 14:30:35 -07:00
gsxdsm
b95e7f7575 FN-5894: share project data-boundary and status helpers
Centralize project loading and status-state handling across dashboard surfaces.

- add a reusable DataBoundary component for loading, empty, error, and loaded states
- extract shared project status config helpers for labels, colors, icons, and initializing detection
- update project overview, cards, badges, and selector UI to use the shared helpers
- add regression coverage for data-boundary behavior, project overview empty/loading transitions, and status config fallbacks

Files changed:
 packages/dashboard/app/components/DataBoundary.tsx | 64 ++++++++++++++++++++++
 packages/dashboard/app/components/ProjectCard.tsx  | 48 ++--------------
 .../app/components/ProjectHealthBadge.tsx          | 45 +--------------
 .../dashboard/app/components/ProjectOverview.tsx   |  4 +-
 .../dashboard/app/components/ProjectSelector.tsx   | 27 +--------
 .../app/components/__tests__/DataBoundary.test.tsx | 62 +++++++++++++++++++++
 .../components/__tests__/ProjectOverview.test.tsx  | 25 +++++++++
 .../__tests__/ProjectThemeTokens.test.tsx          | 37 ++++---------
 .../utils/__tests__/projectStatusConfig.test.ts    | 53 ++++++++++++++++++
 .../dashboard/app/utils/projectStatusConfig.ts     | 50 +++++++++++++++++
 packages/dashboard/vitest.config.ts                |  2 +
 11 files changed, 282 insertions(+), 135 deletions(-)

Fusion-Task-Id: FN-5894

Fusion-Task-Lineage: 3626a4af-b62b-456d-82d7-cf47bbf55c21
2026-06-02 14:14:24 -07:00
gsxdsm
65ddb4d4f5 FN-5893: require invariant-level bug regression coverage
Add invariant-first regression guidance to triage prompts and testing docs.

- add an AGENTS standing rule to cover bug-fix invariants across all known surfaces
- update standard, fast, and core triage prompt templates to require invariant-level regression tests
- add triage regression tests that lock the new wording into standard, fast, and core prompts
- link docs/testing guidance back to the new invariant-over-repro rule

Files changed:
 AGENTS.md                                    |  7 ++++++
 docs/testing.md                              |  1 +
 packages/core/src/agent-prompts.ts           |  3 ++-
 packages/engine/src/__tests__/triage.test.ts | 32 ++++++++++++++++++++++++++++
 packages/engine/src/triage.ts                |  6 ++++--
 5 files changed, 46 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-5893

Fusion-Task-Lineage: 31c082c6-2a0a-4619-a13b-94dad97eef62
2026-06-02 14:02:36 -07:00
gsxdsm
bd3190ba19 FN-5769: clarify workflow IR v1 agent-call semantics
Document that workflow IR v1 keeps agent-call and typed-edge semantics as conventions rather than a 1.1 schema bump.

- replace the deferred-v1.1 note with the FN-5769 evaluation outcome
- record that prompt config and edge.condition remain the canonical v1 representation for parity rollout

Files changed:
 docs/workflow-steps.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Fusion-Task-Id: FN-5769

Fusion-Task-Lineage: 341ce4fe-d87d-4c25-a1fc-652ccfbc2e94
2026-06-02 13:37:33 -07:00
gsxdsm
dab1569ac3 FN-5892: dedupe planning sessions and persist history deletion
Prevent duplicate planning-history rows and keep deletions visible only after the backend confirms persistence.

- dedupe Planning Mode history by session id across initial loads, live updates, archive toggles, and draft creation
- make deleteAiSession surface backend/content-type errors instead of silently succeeding on failed deletes
- keep failed history deletions visible, refresh the list, and show an error toast when persistence fails
- add dashboard tests covering session deduplication, delete API failures, and persistence-aware Planning Mode deletion behavior
- document the history dedupe/delete semantics and add a patch changeset for @runfusion/fusion

Files changed:
 .changeset/fn-5892-planning-history-fix.md         |   5 +
 docs/dashboard-guide.md                            |   2 +-
 packages/dashboard/app/api/__tests__/deleteAiSession.test.ts      |  54 +++++
 packages/dashboard/app/api/legacy.ts               |  41 +++-
 packages/dashboard/app/components/PlanningModeModal.tsx |  70 ++++---
 packages/dashboard/app/components/__tests__/PlanningModeModal.autosize.test.tsx  |  11 +
 packages/dashboard/app/components/__tests__/PlanningModeModal.dedupeSessionsById.test.ts   |  44 ++++
 packages/dashboard/app/components/__tests__/PlanningModeModal.initial.test.tsx   |  11 +
 packages/dashboard/app/components/__tests__/PlanningModeModal.planning-flow.test.tsx       | 226 ++++++++++++++++++++-
 packages/dashboard/app/components/__tests__/PlanningModeModal.test-helpers.ts    |   1 +
 10 files changed, 439 insertions(+), 26 deletions(-)

Fusion-Task-Id: FN-5892

Fusion-Task-Lineage: 7453bc34-6d57-4d67-ac92-8fb50084fbee
2026-06-02 12:42:04 -07:00
gsxdsm
a6989ed7f4 FN-5891: respect validator model settings in mission validation
Use the configured validator lane when creating mission validation sessions.

- resolve mission validation session models from test mode, assigned agent runtime, and validator/default task settings in precedence order
- surface validation session creation failures as mission validation errors instead of triggering fix-feature retries
- add regression coverage and documentation for mission validation model resolution and error handling

Files changed:
 AGENTS.md                                          |   1 +
 docs/missions.md                                   |   4 +-
 docs/settings-reference.md                         |   6 +-
 .../src/__tests__/mission-execution-loop.test.ts   | 252 ++++++++++++++++++++-
 packages/engine/src/mission-execution-loop.ts      |  63 +++++-
 5 files changed, 316 insertions(+), 10 deletions(-)

Fusion-Task-Id: FN-5891

Fusion-Task-Lineage: 6254daee-fb6b-4ebb-9fb4-3636237404b1
2026-06-02 12:38:09 -07:00
gsxdsm
8156382d76 FN-5889: suppress post-done continuation wedges
Keep completed post-done continuation errors from wedging review tasks in a failed state.

- route step-session non-continuable continuation errors through the executor recovery path before marking tasks failed
- add self-healing recovery and run-audit events for in-review tasks already wedged by post-done non-continuable errors
- extend reliability coverage and architecture/backstop docs for the new post-done wedge handling

Files changed:
 AGENTS.md                                          |   1 +
 docs/architecture.md                               |   3 +-
 packages/engine/src/__tests__/reliability-interactions/post-done-continuation-no-wedge.test.ts        | 131 ++++++++++++++++++++-
 packages/engine/src/executor.ts                    |  11 +-
 packages/engine/src/run-audit.ts                   |   2 +
 packages/engine/src/self-healing.ts                |  97 ++++++++++++++-
 6 files changed, 236 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-5889

Fusion-Task-Lineage: c22716f2-cddb-4c98-ac87-0282017e7c82
2026-06-02 11:03:18 -07:00
gsxdsm
d9e1cdbbd7 FN-5890: include task description in ntfy task-created notifications
Ensure agent-created ntfy notifications fall back to the task description when the title is still empty.

- pass task descriptions through task-created notification payloads
- cover empty-title task creation in notification service tests
- verify ntfy task-created messages render the id+description fallback
- add a patch changeset for the published CLI package

Files changed:
 .changeset/fn-5890-task-created-title.md                 |  5 +++++
 .../engine/src/__tests__/notification-service.test.ts    | 12 +++++++++++-
 packages/engine/src/__tests__/ntfy-provider.test.ts      | 16 ++++++++++++++++
 packages/engine/src/notification/notification-service.ts |  1 +
 4 files changed, 33 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-5890

Fusion-Task-Lineage: 4a67a4d0-c3a8-4923-a506-7a67a8836127
2026-06-02 10:29:34 -07:00
gsxdsm
742a564491 FN-5888: retry non-continuable sessions with a fresh session
Retry incomplete executor work with a fresh session after non-continuable session errors.

- add executor recovery handling that clears session state and requeues incomplete tasks to todo while retry budget remains
- preserve terminal failure behavior once the fresh-session retry budget is exhausted
- extend reliability coverage and AGENTS.md backstop notes for the new retry path

Files changed:
 AGENTS.md                                          |  1 +
 .../post-done-continuation-no-wedge.test.ts        | 48 +++++++++++++++++++++-
 packages/engine/src/executor.ts                    | 40 ++++++++++++++++++
 3 files changed, 87 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-5888

Fusion-Task-Lineage: 4ebce260-8923-4599-aced-541533b94543
2026-06-02 10:14:20 -07:00
gsxdsm
a66b128089 FN-5883: restore planning-mode single-task history
Keep completed planning sessions restorable after single-task creation.

- preserve completed planning-session rows after create-task by releasing only in-memory runtime state
- keep completed sessions in the Planning Mode history UI and add coverage for history restoration flows
- document the restored Planning Mode history behavior and add a patch changeset for @runfusion/fusion

Files changed:
 .changeset/fn-5883-planning-restore.md             |   5 +
 docs/dashboard-guide.md                            |   2 +
 .../dashboard/app/components/PlanningModeModal.tsx |  17 +--
 .../PlanningModeModal.planning-flow.test.tsx       | 118 ++++++++++++++++++++-
 .../src/__tests__/routes-planning.test.ts          |  86 +++++++++++----
 packages/dashboard/src/planning.ts                 |   7 +-
 .../src/routes/register-planning-subtask-routes.ts |  14 +--
 7 files changed, 207 insertions(+), 42 deletions(-)

Fusion-Task-Id: FN-5883

Fusion-Task-Lineage: 47824bac-3083-45a4-a0d5-b8c7540966c1
2026-06-02 10:07:08 -07:00
gsxdsm
cc5e61dbc4 FN-5882: fix mission interview draft resume handling
Keep mission interview drafts recoverable when closing and refreshing Missions.

- make MissionInterviewModal use a single non-destructive close path for header, Escape, and backdrop actions
- refresh mission interview draft/session rows on mission and ai-session SSE updates and reconnects
- open Plan New Mission as a fresh interview instead of always resuming the last session, with regression coverage and docs updates

Files changed:
 docs/missions.md                                   |   2 +-
 .../app/components/MissionInterviewModal.tsx       |  89 +++-----
 .../dashboard/app/components/MissionManager.tsx    | 156 ++++++++++----
 .../__tests__/MissionInterviewModal.test.tsx       | 100 ++++++++-
 .../components/__tests__/MissionManager.test.tsx   | 224 +++++++++++++++++++++
 5 files changed, 455 insertions(+), 116 deletions(-)

Fusion-Task-Id: FN-5882

Fusion-Task-Lineage: 75de9e94-edef-4564-a266-91782e60c2ac
2026-06-02 10:04:38 -07:00
gsxdsm
9e00a72d7d FN-5884: preserve quick chat session across reopens
Keep quick chat warm and restore the last opened conversation per project.

- persist the active quick chat session id in per-project local storage and restore it before falling back to latest activity
- retain in-memory quick chat state across close/reopen while resetting chat state correctly when the project changes
- add storage, hook, and FAB coverage for restored sessions, warm reopen behavior, and project switching; document the updated quick chat behavior

Files changed:
 docs/dashboard-guide.md                            |   3 +-
 packages/dashboard/app/components/QuickChatFAB.tsx |  29 ++++--
 .../app/components/__tests__/QuickChatFAB.test.tsx | 112 +++++++++++++++++++--
 .../__tests__/quickChatLastSessionStorage.test.ts  |  55 ++++++++++
 .../app/hooks/__tests__/useQuickChat.test.ts       |  70 +++++++++++++
 .../app/hooks/quickChatLastSessionStorage.ts       |  41 ++++++++
 packages/dashboard/app/hooks/useQuickChat.ts       |  25 +++++
 7 files changed, 319 insertions(+), 16 deletions(-)

Fusion-Task-Id: FN-5884

Fusion-Task-Lineage: 4d689611-1824-41db-8fc2-d543407316ff
2026-06-02 09:34:19 -07:00
gsxdsm
cf3b9a575e FN-5886: show empty usage state after empty fetch
Handle empty usage responses without leaving the panel in its loading skeleton.

- add a hasFetched flag to useUsageData so the UI can distinguish initial loading from an empty completed response
- update UsageIndicator to render the skeleton only before the first fetch completes and show the empty state afterward
- refresh dashboard hook and component tests to cover empty fetches, refresh behavior, and the new loading semantics

Files changed:
 .../dashboard/app/components/UsageIndicator.tsx    |  19 +-
 .../components/__tests__/UsageIndicator.test.tsx   | 395 +++++++++++----------
 .../app/hooks/__tests__/useUsageData.test.ts       |  42 ++-
 packages/dashboard/app/hooks/useUsageData.ts       |   5 +
 4 files changed, 245 insertions(+), 216 deletions(-)

Fusion-Task-Id: FN-5886

Fusion-Task-Lineage: 8fa901a9-3167-4e33-a082-e5de95f692da
2026-06-02 09:24:42 -07:00
gsxdsm
fa68edf9fa FN-5885: fix terminal copy/paste shortcuts
Restore expected terminal clipboard shortcuts.

- intercept Ctrl/Cmd+C in the dashboard terminal to copy the current selection while preserving plain SIGINT when nothing is selected
- intercept Ctrl/Cmd+V to read clipboard text and send it into the active PTY session
- add terminal shortcut regression coverage and document the new integrated terminal behavior
- add a patch changeset for @runfusion/fusion

Files changed:
 .changeset/friendly-ravens-hammer.md               |   5 +
 docs/dashboard-guide.md                            |   2 +
 packages/dashboard/app/components/TerminalModal.tsx     |  48 +++++++++
 packages/dashboard/app/components/__tests__/TerminalModal.test.tsx    | 113 +++++++++++++++++++++
 4 files changed, 168 insertions(+)

Fusion-Task-Id: FN-5885

Fusion-Task-Lineage: f8b3658c-2b52-4094-8cef-79c762f4d78d
2026-06-02 09:20:31 -07:00
gsxdsm
1a065f2637 FN-5873: trim async waits in SettingsModal tests
Reduce SettingsModal test setup overhead around Remote and Notifications flows.

- switch key authentication assertions to await section controls directly instead of waiting for full modal readiness
- share a zero-delay user-event instance across Remote and Notifications suites and consolidate default-render setup in nested describe blocks
- replace several clear/type interaction sequences with direct change events to cut async churn while preserving coverage

Files changed:
 .../components/__tests__/SettingsModal.test.tsx    | 473 ++++++++++-----------
 1 file changed, 224 insertions(+), 249 deletions(-)

Fusion-Task-Id: FN-5873

Fusion-Task-Lineage: d1f33301-a43f-467f-97e8-b7bfad28e009
2026-06-02 09:05:22 -07:00
gsxdsm
48e08c07eb FN-5880: recover plan-ready mission interview drafts
Keep completed mission interview summaries resumable until they are approved or discarded.

- include  mission interview sessions in dashboard, CLI, and extension draft listings
- relabel complete drafts as plan-ready review items and reopen them at the summary approval step
- add regression coverage and docs/changeset updates for resumable complete drafts

Files changed:
 .../fn-5880-mission-interview-complete-draft.md    |  5 ++
 docs/missions.md                                   |  8 +--
 packages/cli/src/__tests__/extension.test.ts       | 13 +++-
 .../cli/src/commands/__tests__/mission.test.ts     | 11 ++-
 packages/cli/src/commands/mission.ts               | 17 ++++-
 packages/cli/src/extension.ts                      |  7 +-
 .../dashboard/app/components/MissionManager.tsx    | 24 ++++---
 .../components/__tests__/MissionManager.test.tsx   | 70 ++++++++++++++++++
 packages/dashboard/app/components/mission-types.ts |  2 +-
 .../mission-interview-drafts-routes.test.ts        | 18 ++++ -
 .../src/__tests__/mission-interview.test.ts        | 82 ++++++++++++++++++++++
 packages/dashboard/src/mission-interview.ts        | 36 +++++-----
 12 files changed, 252 insertions(+), 41 deletions(-)

Fusion-Task-Id: FN-5880

Fusion-Task-Lineage: 18a9c25c-3f59-4179-9e9c-63f0747acb7f
2026-06-02 09:02:48 -07:00
gsxdsm
f20c37471d FN-5881: guard project status badges against unknown states
Prevent Projects view status rendering from crashing on unknown or missing project states.

- add fallback status config helpers to ProjectCard, ProjectHealthBadge, and ProjectSelector
- format unknown status strings into readable labels and default missing values to Unknown
- add regression tests for unknown and missing statuses across project dashboard components
- document graceful degradation for transient registry or health status mismatches

Files changed:
 docs/multi-project.md                              |  1 +
 packages/dashboard/app/components/ProjectCard.tsx  | 36 ++++++++++++++++-
 .../app/components/ProjectHealthBadge.tsx          | 36 ++++++++++++++++-
 .../dashboard/app/components/ProjectSelector.tsx   | 15 ++++++-
 .../app/components/__tests__/ProjectCard.test.tsx  | 31 +++++++++++++-
 .../__tests__/ProjectHealthBadge.test.tsx          | 47 ++++++++++++++++++++++
 .../components/__tests__/ProjectSelector.test.tsx  | 24 ++++++++++-
 7 files changed, 182 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-5881

Fusion-Task-Lineage: 55a9df6f-3fcb-46e8-9e83-3494312b4c24
2026-06-02 08:49:25 -07:00
gsxdsm
5bad807189 FN-5879: restore desktop tab scrolling in task detail modal
Keep the task detail tab strip scrollable on desktop without shrinking tab labels.

- move horizontal tab-strip scrolling and momentum styles into the base .detail-tabs rule
- keep .detail-tab items from shrinking at all viewport sizes so overflow remains scrollable
- add a CSS contract test for the base tab strip behavior and extend task detail API mocks with refreshPrStatus

Files changed:
 packages/dashboard/app/components/TaskDetailModal.css              | 7 ++++---
 .../dashboard/app/components/__tests__/TaskDetailModal.css.test.ts | 7 +++++++
 .../app/components/__tests__/TaskDetailModal.test-helpers.ts       | 1 +
 3 files changed, 12 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-5879

Fusion-Task-Lineage: b990a88e-7b1d-44d9-b222-986a28ae143d
2026-06-02 08:46:04 -07:00
gsxdsm
0006408181 FN-5874: persist fast-forward merge details
Persist merge metadata for AI fast-forward landings and done-task recovery.

- capture landed files and shortstat metadata from the single landed commit in the AI merge finalizer
- persist mergeDetails and modifiedFiles for landed squash commits, and record commit associations without setting no-op attribution flags
- extend done-task self-healing to backfill merge metadata when baseCommitSha exists but mergeDetails is empty
- add reliability and self-healing coverage for landed-file persistence, empty AI merges, and recovery behavior

Files changed:
 AGENTS.md                                          |   1 +
 .../ai-merge-ff-landed-files.test.ts               | 150 +++++++++++++++++++++
 packages/engine/src/__tests__/self-healing.test.ts |  76 +++++++++++
 packages/engine/src/merger-ai.ts                   |  40 +++++-
 packages/engine/src/merger.ts                      |  30 ++++-
 packages/engine/src/self-healing.ts                |  11 +-
 6 files changed, 303 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-5874

Fusion-Task-Lineage: a407910c-9ce8-4049-86ef-e80f045c981a
2026-06-02 08:35:47 -07:00
gsxdsm
419d6cda86 FN-5877: add sync-with-origin remotes action
Add a one-click Remotes sync flow that rebases on pull before pushing.

- add a Sync button in Git Manager Remotes that runs pull --rebase and then push
- stop before pushing when the rebase pull reports a conflict or fails, and surface toasts/status updates
- cover successful, conflicting, failing, and loading sync behavior in GitManagerModal tests
- document the new Sync action in the dashboard guide

Files changed:
 docs/dashboard-guide.md                            |   1 +
 .../dashboard/app/components/GitManagerModal.tsx   |  39 ++++++++
 .../components/__tests__/GitManagerModal.test.tsx  | 100 +++++++++++++++++++++
 3 files changed, 140 insertions(+)

Fusion-Task-Id: FN-5877

Fusion-Task-Lineage: 2e28c00d-b965-4f44-a6fa-26536d91d16d
2026-06-02 08:25:46 -07:00
gsxdsm
8b839d79e8 FN-5878: re-hide revealed secrets from the eye toggle
Let users hide a revealed secret again from the row visibility toggle.

- add a hideSecret helper that clears reveal timers and resets the revealed value
- make the row eye toggle switch between reveal and hide states instead of reveal-only
- add a SecretsView regression test covering reveal, hide, and copy button state changes

Files changed:
 packages/dashboard/app/components/SecretsView.tsx         | 18 +++++++++-
 packages/dashboard/app/components/__tests__/SecretsView.test.tsx | 40 ++++++++++++++++++++++
 2 files changed, 57 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-5878

Fusion-Task-Lineage: 936195db-88c9-48f5-8273-9b930bf6b858
2026-06-02 08:14:10 -07:00
gsxdsm
dd1024fe0b FN-5871: streamline SettingsModal tests
Reduce SettingsModal test overhead by reusing setup and waiting on stable UI signals.

- replace generic waitFor polling with findBy* queries and direct mock call assertions
- consolidate project-general persistence coverage and split default-value checks from save-path assertions
- share Memory and Merge section setup across related tests to avoid repeated navigation and duplicate work

Files changed:
 packages/dashboard/app/components/__tests__/SettingsModal.test.tsx | 333 ++++++++-------------
 1 file changed, 127 insertions(+), 206 deletions(-)

Fusion-Task-Id: FN-5871

Fusion-Task-Lineage: 1b625571-f16e-4aec-8640-22d8f3bb8139
2026-06-02 08:10:35 -07:00
gsxdsm
3989193cf2 FN-5876: prevent mobile quick-entry autofocus
Avoid restoring focus to the new-task quick entry on mobile while preserving desktop behavior.

- gate quick-entry autofocus and post-submit focus restoration behind a desktop-width check
- add desktop and mobile coverage for initial focus behavior
- add mobile coverage for avoiding focus restoration after successful task creation

Files changed:
 .../dashboard/app/components/QuickEntryBox.tsx     |  5 ++-
 .../components/__tests__/QuickEntryBox.test.tsx    | 42 ++++++++++++++++++++++
 2 files changed, 46 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-5876

Fusion-Task-Lineage: ede08207-6506-4f5e-8a6f-f7f1cbfb37c9
2026-06-02 08:08:01 -07:00
gsxdsm
91784d9acf FN-5875: fix hidden usage row count
Keep the usage indicator's hidden-row toggle in sync with rendered duplicate windows.

- count hidden usage rows from the currently rendered provider windows instead of persisted label entries
- preserve the Show hidden button when duplicate live windows share a stored hidden label
- add a regression test covering duplicate Daily windows with persisted hidden state

Files changed:
 .../dashboard/app/components/UsageIndicator.tsx    | 12 ++++++-
 .../components/__tests__/UsageIndicator.test.tsx   | 42 ++++++++++++++++++++++
 2 files changed, 53 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-5875

Fusion-Task-Lineage: 648f9cb9-ea0a-4573-b08f-b1a412a46ae4
2026-06-02 07:52:04 -07:00