Commit Graph

4530 Commits

Author SHA1 Message Date
gsxdsm
05098e4033 FN-5963: add goals refinement evidence pack
Document the evidence required before activating conditional goals refinement work.

- add a dedicated goals refinement evidence pack doc with required observation fields and activation thresholds
- link the new evidence pack from the docs index and dashboard guide
- cover the doc with a dashboard test and keep PR conflict-resolution modal styling aligned after merge

Files changed:
 docs/README.md                                     |  1 +
 docs/dashboard-guide.md                            |  2 +-
 docs/goals-refinement-evidence-pack.md             | 74 ++++++++++++++++++++++
 .../goals-refinement-evidence-pack-docs.test.ts    | 22 +++++++
 .../dashboard/app/components/PrCreateModal.css     |  6 +-
 .../dashboard/app/components/PrCreateModal.tsx     |  2 +-
 6 files changed, 103 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-5963

Fusion-Task-Lineage: 22cefe55-6b1e-4ff7-8fb1-5734f2b5a29b
2026-06-03 22:31:23 -07:00
gsxdsm
26bc80a0ad FN-5958: add mission goal linking to create and update flows
Expand mission goal-link management across the REST API, CLI, and pi extension.

- accept optional goalIds during mission create and patch requests, and enforce archived-goal rejection while keeping unlink permissive
- add repeatable --goal support to fn mission create and reuse goal validation for CLI linking
- expose archived-goal errors in pi-extension mission goal tools and document the new behavior

Files changed:
 .changeset/FN-5958-mission-goal-links.md           |  10 +
 docs/cli-reference.md                              |   8 +-
 docs/missions.md                                   |  15 +-
 packages/cli/src/__tests__/bin.test.ts             |  34 ++++
 packages/cli/src/__tests__/extension-mission-goal-tools.test.ts |  36 ++++
 packages/cli/src/bin.ts                            |  24 ++-
 packages/cli/src/commands/mission.ts               |  29 ++-
 packages/cli/src/extension.ts                      |   7 +
 packages/dashboard/src/__tests__/mission-goal-links-routes.test.ts | 201 ++++++++++++++++++++-
 packages/dashboard/src/mission-routes.ts           |  66 +++++--
 10 files changed, 390 insertions(+), 40 deletions(-)

Fusion-Task-Id: FN-5958
Fusion-Task-Lineage: cf9d6013-5484-439d-b66d-44cac843c6ef
2026-06-03 22:31:23 -07:00
gsxdsm
8891d4b90a FN-5950: add Create PR branch-push remediation
Add in-app preflight remediation so Create PR can push task branches without leaving Fusion.

- add a dashboard API route and client helper to push the task branch to origin and recompute PR preflight state
- update the Create Pull Request modal, styles, and tests to surface push-branch remediation alongside AI conflict resolution
- document the flow and add a published CLI changeset plus server coverage for the new push-branch endpoint

Files changed:
 .changeset/fn-5950-pr-push-branch.md               |   5 +
 docs/dashboard-guide.md                            |   2 +-
 packages/dashboard/app/api/legacy.ts               |  19 +++
 packages/dashboard/app/components/PrCreateModal.css     |   4 +-
 packages/dashboard/app/components/PrCreateModal.tsx     |  48 +++++-
 packages/dashboard/app/components/__tests__/PrCreateModal.test.tsx    |  44 ++++++
 packages/dashboard/src/__tests__/register-git-github.pr-push-branch.test.ts     | 176 +++++++++++++++++++++
 packages/dashboard/src/routes/register-git-github.ts    |  68 ++++++++
 8 files changed, 362 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-5950

Fusion-Task-Lineage: 5a6c5c6a-8f99-44c0-8f54-f0a6ff537ed0
2026-06-03 22:31:23 -07:00
gsxdsm
6d39b9a325 merge main: workflow graph editor + needs-input status; re-applied i18n t() wrapping to restructured WorkflowStepManager header and TaskCard status chain 2026-06-03 21:33:06 -07:00
gsxdsm
2baa8bce1b Merge pull request #1363 from Runfusion/gsxdsm/workflowbuilder
feat: executable custom workflows + visual graph editor + interpreter cutover foundation
2026-06-03 21:29:26 -07:00
gsxdsm
dfef5dadbd merge main: branch-group promote/abandon gating + compound-engineering plugin; re-applied i18n t() wrapping to main's restructured promote sections 2026-06-03 20:56:05 -07:00
gsxdsm
a2e96b132a feat(i18n): round-2 sweep — 488 residual strings migrated, markup fidelity restored (#1352)
- 51 fix agents covered every dirty batch from the round-1 verifiers:
  helper-function labels (roles, statuses, relative time), constant
  label maps (SETTINGS_SECTIONS, PROVIDER_INFO, EVENT_TYPE_LABELS),
  TUI help overlay + tab labels, toasts, placeholders, aria-labels
- Inline markup flattened by round 1 restored with <Trans>
  (DbCorruptionBanner storage-docs link, UpdateAvailableBanner code chip)
- Catalogs merged: +527 en keys across 5 locales; CLI bundles + app
  locale tree regenerated (6 locales)
- All 23 sweep-caused test regressions fixed: delta vs the clean-main
  baseline is now zero (remaining 4 local failures reproduce identically
  on origin/main; CI-green upstream)
- typecheck/lint clean; TUI 82/82, core locale 9/9

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 20:52:44 -07:00
gsxdsm
cc2ea4a41f Merge pull request #1387 from Runfusion/gsxdsm/queued-messages
fix: confirm server generation state before flushing queued chat messages
2026-06-03 20:45:46 -07:00
gsxdsm
99dd89c029 test(dashboard): boot a real en i18next instance in vitest setup
Components now call useTranslation(); without an initialized instance,
react-i18next's fallback returns inline defaults WITHOUT interpolation
(literal {{count}} in output) and t identity flips once init completes,
double-firing effects that list t in deps. Awaiting a backend-less en
init (all namespaces pre-loaded, useSuspense off) keeps t(key, default,
options) interpolating and identity-stable from the first render.

Cleared ~770 of the 1,051 dashboard test failures; the remainder were
triaged against a clean origin/main worktree baseline: 253 fail
identically there (local-env fake-timer waitFor hangs; CI passes them)
and 23 sweep-caused regressions are being fixed in the round-2 pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 20:41:05 -07:00
gsxdsm
9239e52d4b Update packages/dashboard/app/hooks/__tests__/useChat.test.ts
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-06-03 20:34:39 -07:00
gsxdsm
47bd46e6a3 fix: address PR review feedback (#1387)
- gate Quick Chat's session-activation auto-flush to the pre-session
  queue only, so a restored queue cannot be sent before the restore
  effect's authoritative fetchChatSession check resolves (real flaw —
  the original test passed only because the mocked fetch resolved in a
  microtask and beat the effect)
- add slow-fetch regression tests in both hooks proving the restored
  queue stays un-flushed while server validation is pending
- assert attachChatStream ran before triggering its onDone in the
  quick-chat regression test
- drop redundant Promise.resolve() wrapper around fetchChatSession in
  useQuickChat's restore effect

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 20:21:06 -07:00
gsxdsm
684baa0eb7 fix(FN-5852): confirm server generation state before flushing queued chat messages
Re-entering a chat flushed the restored queued message based on the
client's stale isGenerating flag (a route-level enrichment the
chat:session:updated SSE payload lacks), firing a send that aborted the
live generation server-side and could lose the message entirely. The
restore path in useChat and useQuickChat now asks the server first:
attach and defer the flush while generating, send immediately only when
no generation is in flight, and keep the bubble on a failed check.

Fixes Runfusion/Fusion#1279

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 19:54:02 -07:00
gsxdsm
759e2e67af Merge remote-tracking branch 'origin/main' into gsxdsm/workflowbuilder 2026-06-03 19:52:37 -07:00
gsxdsm
2d2024fb0f fix(dashboard): unfreeze animations broken by transition tokens used as durations
Spinners, status-dot pulses, and entrance animations across the dashboard
rendered frozen: transition tokens (--transition-slow: 0.3s ease) bundle a
duration AND an easing, and 15 animation declarations reused them as bare
durations. Substituting "0.3s ease" next to an explicit easing (linear,
ease-in-out, ease-out) — or inside calc() — makes the declaration invalid at
computed-value time, which per spec resolves the entire property to
animation: none with no console error.

- add duration-only tokens (--duration-instant/fast/normal/slow) and derive
  the --transition-* tokens from them so the two cannot drift
- switch all 15 broken animation declarations across 14 CSS files to the
  duration tokens, preserving effective durations
- add animation-duration-tokens.css.test.ts: sweeps every app CSS file and
  fails on transition-token-as-duration, calc() over a transition token, and
  transition token in animation-duration

Verified in a real browser against the production build: previously frozen
.status-dot--connecting and calc-based NodesView spinners now report running
animations; transition shorthands still resolve to "0.15s / ease".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 19:48:40 -07:00
gsxdsm
1e49494bac feat(i18n): full-sweep string migration — 5,930 keys across 5 locales (#1352)
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>
2026-06-03 19:06:53 -07:00
gsxdsm
dbb8adeff1 feat: surface dual-observe flag + parity summary (CU-U5 #3)
- Settings → Experimental gains a 'Workflow Graph Engine — dual-observe parity
  (diagnostic)' toggle for the workflowInterpreterDualObserve flag.
- store.getWorkflowParitySummary() aggregates the workflow:parity-observed /
  workflow:parity-drift run-audit events into the graduation signal: agree-rate,
  per-field drift counts, and recent drift samples. Covered by
  workflow-parity-summary.test.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 18:54:39 -07:00
gsxdsm
d8b88f3f84 test(dashboard): mock useToast in PlanningModeModal.ui-interactions
These tests render PlanningModeModal bare; it calls useToast() which throws
without a ToastProvider. Mirror the mock already in PlanningModeModal.autosize.
test.tsx. (Pre-existing failure on main; the test is excluded from the CI
quality shards but fails under `--project dashboard-app`/`test:app`.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 18:37:01 -07:00
gsxdsm
e954f1a720 test(dashboard): mock workflow API in board-mobile and settings-mobile tests
InlineCreateCard now renders WorkflowSelector and SettingsModal renders
ProjectDefaultWorkflowField → WorkflowSelector, both of which call
fetchWorkflows / fetchProjectDefaultWorkflow on mount. These two tests mock
"../../api" with a fixed object that omitted those exports, so the components
threw "No fetchWorkflows export is defined" during render (the failures behind
test shards 1/2; masked earlier by the build break). Add the workflow API
mocks, matching the set already present in InlineCreateCard.test.tsx.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 18:27:34 -07:00
gsxdsm
07dd24e37a Merge pull request #1357 from Runfusion/gsxdsm/taskbranch
feat: branch-group single managed PR flow (planning + missions)
2026-06-03 18:24:54 -07:00
gsxdsm
39bbe48c8a test(FN-branch-group): update routes-tasks subtask expectations to real-groupId semantics
Two stale assertions still encoded the synthetic planning:<sessionId> groupId:
shared mode without a group-capable store now stamps no groupId, and
per-task-derived members never carry one.
2026-06-03 18:12:59 -07:00
gsxdsm
d5397d3f69 fix(dashboard): inline isBuiltinWorkflowId — unbreak the app build
The dashboard app build aliases "@fusion/core" to its types-only entry
(core/src/types.ts), which doesn't re-export builtin-workflows, so the Vite/
Rollup bundle failed on `import { isBuiltinWorkflowId } from "@fusion/core"`
(tsc/vitest resolve it via source/dist, so they passed — only the production
build caught it). Inline the one-line "builtin:" prefix check in the editor
instead of pulling the eager BUILTIN_WORKFLOWS construction into the browser
bundle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:59:29 -07:00
gsxdsm
1557fc5a47 fix(FN-branch-group): repair CI failures — execFile mock compatibility, TaskCard narrowing, e2e memo race
- resolve execFile lazily via namespace import in coordinator/merger/
  task-lifecycle so the repo's exec-only child_process test mocks load again
  (10+ engine suites failed at import); dashboard.test.ts mock gains execFile
  so the argv-based git probes hit the mock instead of spawning real git
- TaskCard: capture optional branchContext.groupId into a const (narrowing
  doesn't survive into the onClick closure; app tsconfig caught it in CI)
- planning e2e: bounded poll past the 2.5s listTasks startup memo that served
  a pre-landing snapshot on fast CI runs
2026-06-03 17:57:00 -07:00
gsxdsm
8bb02f7d3c fix(engine,core): merge-seam multi-waiter + autoMerge gate; selection lock; settings toggle
Resolve the two needs-human findings from PR #1363 review, plus surface the flag.

Merge seam (project-engine.ts):
- manualMergeResolvers is now a per-task LIST of waiters. Both the dashboard
  "merge now" path and the interpreter merge seam call onMerge, so a single
  resolver per task let the second caller overwrite (and strand) the first.
  All resolve/reject/requeue/late-resolver/shutdown sites drain the whole list.
- New requestInterpreterMerge() honors auto-merge eligibility: when autoMerge
  is off (or the task isn't merge-ready) it returns merged:false instead of
  forcing the merge, so a graph merge node can't override an autoMerge-off
  project — it parks the task in review for a human. setMergeRequester now wires
  the interpreter to this gate rather than the human bypass.

Selection race (store.ts):
- selectTaskWorkflow/clearTaskWorkflowSelection now hold one withTaskLock across
  their whole mutate sequence. Extracted updateTaskUnlocked() (the per-task lock
  is non-reentrant, so they couldn't wrap the public updateTask without
  deadlocking) and call that inside the lock.

Settings:
- Add "Workflow Graph Engine (run custom workflows)" to the Experimental
  Features list so the workflowGraphExecutor flag is a labeled toggle in
  Settings → Experimental, not just a raw key.

Tests: interpreter-merge-seam.test.ts (multi-waiter resolve/reject + autoMerge
eligibility gate); existing merge lifecycle/bypass/selection suites still pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:53:40 -07:00
gsxdsm
0be074f8c2 fix(FN-branch-group): address fourth-round PR review feedback (#1357)
- needsPrRepair no longer short-circuited by the open-state guard: legacy
  fallback rows (finalized + prState open + prNumber null) now repair by
  creating the real PR on re-promotion; regression test added
- no-PR abandon route test asserts last persisted call + response body
- goal-provenance fallback test clears missionId on its own in-memory store
  so the feature-linkage path is genuinely exercised
2026-06-03 17:42:43 -07:00
gsxdsm
e703bdd608 feat(i18n): add Korean locale + localized READMEs with language switcher
- ko added to SUPPORTED_LOCALES and every enumeration site (config,
  settings enum, help text, tests); Korean catalogs authored for all
  current keys; CLI bundles regenerated for 6 locales; 한국어 endonym
- README translated into zh-CN, zh-TW, fr, es, ko; every README carries
  a language-switcher line and the localized ones note that English is
  canonical

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:33:16 -07:00
gsxdsm
eb67d08213 Address PR review feedback (#1363)
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>
2026-06-03 17:32:12 -07:00
gsxdsm
64d02b5108 fix(FN-branch-group): address third-round PR review feedback (#1357)
- abandon (route + CLI) preserves prState 'none' for groups that never had a
  PR instead of falsely persisting 'closed'; regression tests both sides
- stale-snapshot write guard extracted to syncGroupPrOnLanding and covered by
  a fast in-memory unit test (FN-5048); the slow real-git duplicate removed
2026-06-03 17:22:11 -07:00
gsxdsm
e22401995e Address PR review feedback (#1362)
- Replace dynamic await import("@fusion/engine") in the agent-import route
  with a static top-level import. The dynamic form is banned by the FN-3049
  engine-import-regression test (bundler safety); my earlier reply mistook the
  file's @fusion/core dynamic-import convention for a uniform rule — the
  regression only forbids @fusion/engine. Verified the test now passes.
- AgentImportModal: capture and render dry-run `warnings` in the preview step
  so the custom-role safeguard is shown BEFORE the import runs, not only after.
  Adds a regression test for the preview warning.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:14:42 -07:00
gsxdsm
cce7c0d469 Address PR review feedback (#1362)
- Cover the non-dry-run import warning path with a test (greptile P2): the
  warning is spread into both the dryRun and persist responses but was only
  exercised via dryRun.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:14:42 -07:00
gsxdsm
6a00dd2090 FN-5941: stop missions stalling on incompatible/custom-role agents
Importing a catalog ("company") agent assigns role "custom", which the
scheduler never auto-assigns mission/queue work to. Combined with a
model/provider that rejects the "developer" system role, this surfaced as
an invisible, repeating failure loop (GitHub #1261).

- pi.ts: treat an unsupported message-role rejection as a model-selection
  error so a configured fallback model is tried once (single-swap guarded)
  before the task is marked failed.
- mission-autopilot.ts: block a mission feature immediately on an
  operator-actionable failure instead of burning the retry budget
  re-running the same cryptic error.
- mission-routes.ts: preflight mission start — when ephemeral agents are
  disabled and no eligible executor exists, fail fast with an actionable
  message instead of queueing tasks forever.
- agent import route + AgentImportModal: warn when only custom-role agents
  are imported and no executor exists.
- agent-assignment.ts: extract shared listEligibleExecutorAgents helper.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:14:42 -07:00
gsxdsm
46f525bd28 Merge main: reconcile duplicate pausedReason persistence fix + dashboard deps
Main independently landed the same pausedReason persistence fix (column in
the task INSERT/upsert, TaskRow type, rowToTask mapping) with the column
ordered between paused and userPaused; adopt main's ordering and drop this
branch's duplicate entries so the values array stays aligned. Union the
dashboard package.json deps (main's compound-engineering plugin alongside
this branch's sorted pi-coding-agent/cli-printing-press/cursor-runtime).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 16:37:18 -07:00
gsxdsm
d1cd8b6ed8 merge main: unify CONCEPTS.md vocabularies and reconcile core exports
Both sides bootstrapped CONCEPTS.md — kept main's broader structure (Missions,
Merge lifecycle, CE sessions) and folded the branch-group vocabulary into its
Merge-lifecycle cluster (enriched Shared branch group + Self-healing sweep;
added Branch assignment mode, Landed, Group promotion). Union-merged core
index/store imports; took main's AGENTS.md discoverability wording. Also adds
execFile to the two child_process test mocks that only stubbed exec (the
coordinator's argv-based git calls now require it).
2026-06-03 15:57:41 -07:00
gsxdsm
1853459def FN-5961: document goals refinement evidence gate
Add the governance doc and regression coverage for the conditional post-v1 goals refinement gate.

- add docs/goals-refinement-gate.md defining accepted trigger evidence, activation requirements, and the no-automatic-refinement rule for Slice 4
- link the new goals refinement gate doc from docs/README.md
- add a vitest doc guard that asserts the required trigger categories and activation constraints remain documented

Files changed:
 docs/README.md                                     |   1 +
 docs/goals-refinement-gate.md                      | 104 +++++++++++++++++++++
 packages/dashboard/app/__tests__/goals-refinement-gate-docs.test.ts   |  51 ++++++++++
 3 files changed, 156 insertions(+)

Fusion-Task-Id: FN-5961

Fusion-Task-Lineage: 8e641782-93bb-470e-8bc3-14379dbd6cf6
2026-06-03 15:32:29 -07:00
gsxdsm
8aed4da764 FN-5949: add AI PR conflict resolution to Create PR flow
Add dashboard support for resolving task-branch PR conflicts with AI before PR creation.

- add a dashboard PR conflict resolver that merges the selected base into the task branch, invokes an AI merge session on conflicted files, verifies markers are removed, then commits and pushes the updated branch
- expose a POST /tasks/:id/pr/resolve-conflicts route plus client API/export wiring, docs updates, and a changeset for the published CLI package
- update the Create PR modal UI, styling, and tests to surface preflight conflicts, trigger AI resolution, and refresh preflight state after success
- add API coverage for successful and unresolved conflict-resolution paths and include the new route test in the dashboard API quality shard

Files changed:
 .changeset/fn-5949-pr-conflict-resolution.md       |   5 +
 docs/dashboard-guide.md                            |   1 +
 docs/task-management.md                            |   1 +
 packages/dashboard/README.md                       |   1 +
 packages/dashboard/app/api/legacy.ts               |  20 ++
 .../dashboard/app/components/PrCreateModal.css     |  32 ++-
 .../dashboard/app/components/PrCreateModal.tsx     |  46 ++++
 .../components/__tests__/PrCreateModal.test.tsx    |  33 +++
 ...egister-git-github.pr-resolve-conflicts.test.ts | 186 +++++++++++++++
 packages/dashboard/src/index.ts                    |   5 +
 packages/dashboard/src/pr-conflict-resolver.ts     | 258 +++++++++++++++++++++
 .../dashboard/src/routes/register-git-github.ts    | 225 ++++++++++++------
 packages/dashboard/vitest.config.ts                |   2 +-
 13 files changed, 739 insertions(+), 76 deletions(-)

Fusion-Task-Id: FN-5949

Fusion-Task-Lineage: fea35fbf-6254-415c-83cc-0bc24abc911e
2026-06-03 15:32:29 -07:00
gsxdsm
de3273eba3 FN-5937: clear deadlock auto-pause on retry
Clear deadlock auto-pauses when users retry failed in-review tasks.

- add a shared core helper to clear only the in-review stall deadlock auto-pause without overriding manual or unrelated pauses
- apply the auto-pause clear patch across dashboard, CLI, and extension retry flows while preserving existing merge retry reset behavior
- add regression coverage for core, CLI, extension, and dashboard retry paths plus a patch changeset and architecture note

Files changed:
 .changeset/fn-5937-clear-auto-pause-retry.md       |   5 +
 docs/architecture.md                               |   2 +-
 packages/cli/src/__tests__/extension.test.ts       | 126 ++++++++++++++++++
 packages/cli/src/__tests__/task-retry.test.ts      |  59 +++++++++
 packages/cli/src/commands/task.ts                  |  12 +-
 packages/cli/src/extension.ts                      |  12 +-
 .../core/src/__tests__/manual-retry-reset.test.ts  |  44 ++++++-
 packages/core/src/index.ts                         |   7 +-
 packages/core/src/manual-retry-reset.ts            |  19 +++
 packages/core/src/store.ts                         |   8 +-
 .../src/__tests__/routes-tasks-ops.test.ts         | 141 +++++++++++++++++++++
 .../src/routes/register-task-workflow-routes.ts    |  12 +-
 12 files changed, 436 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-5937

Fusion-Task-Lineage: 8a15e01b-7b05-4126-ac6b-895467801f02
2026-06-03 15:32:29 -07:00
gsxdsm
da7c82ebea FN-5947: fix mobile task review header spacing
Tighten the Task Review tab layout on mobile and lock in the responsive header contract.

- override the mobile .task-review-tab__summary-wrap flex rule so the summary block stops reserving excessive blank space
- extend TaskReviewTab coverage to assert the mobile summary-wrap override and prevent regressions between empty and populated review states across reviewer-agent and pull-request sources
- keep the review header structure stable across both review sources and empty/populated states

Files changed:
 .../dashboard/app/components/TaskReviewTab.css     |  4 +
 .../components/__tests__/TaskReviewTab.test.tsx    | 98 ++++++++++++++++++++++
 2 files changed, 102 insertions(+)

Fusion-Task-Id: FN-5947
Fusion-Task-Lineage: 813e1142-bf28-4687-8510-2f93ec40e582
2026-06-03 15:32:29 -07:00
gsxdsm
f1572a3b62 FN-5946: render PR create modal through a portal
Ensure the PR creation dialog escapes transformed ancestor layout traps.

- render `PrCreateModal` with `createPortal(..., document.body)` so the overlay stays fixed to the viewport
- add regression coverage for container-type and nested-overlay portal behavior plus close interactions
- document the modal overlay portal requirement in the dashboard guide

Files changed:
 docs/dashboard-guide.md                            |  2 +-
 .../dashboard/app/components/PrCreateModal.tsx     |  6 ++-
 .../components/__tests__/PrCreateModal.test.tsx    | 63 +++++++++++++++++++++-
 3 files changed, 66 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-5946

Fusion-Task-Lineage: eb22590e-1776-49f3-82d7-ac87c5138f0b
2026-06-03 15:32:28 -07:00
gsxdsm
acc7456a5e Merge pull request #1343 from Runfusion/gsxdsm/compound
feat: Compound Engineering plugin with interactive sessions, work bridge, and bidirectional sync
2026-06-03 15:31:40 -07:00
gsxdsm
291072446d feat(workflows): enforce node autoApprove by bypassing the CLI approval pause
The node "Auto-approve requests" toggle was captured but unused. The only
human-approval pause reachable from a custom node is the CLI first-run
trust-on-first-use gate (review-style nodes run as ephemeral readonly agents
with no permission gate), so autoApprove now bypasses that pause — a superset
of the CLI-specific cliSkipApproval flag. The inspector explains the effect
when the toggle is on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:26:29 -07:00
gsxdsm
bd8f0fd23c feat(dashboard): make built-in workflows read-only in the node editor
Built-in (builtin:*) workflows are read-only at the store layer; reflect
that in the editor so users aren't misled into editing changes that can't
save. For a built-in: the node palette is disabled, the inspector fields are
wrapped in a disabled fieldset, Save/Delete are replaced by a "Read-only
built-in" label, and a "Duplicate to edit" action clones it into an editable
user workflow. handleSave/handleDeleteWorkflow also early-return for built-ins
as defense-in-depth.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:19:27 -07:00
gsxdsm
0435fefd86 fix(workflows): persist pausedReason + harden CLI approval, await-input, and node isolation
Address PR #1363 review findings:

- core: pausedReason was written in-memory and read by SELECT but never
  persisted by the task upsert (missing column/value) nor mapped back in
  rowToTask — so it was lost on every reload. Add it to both. This is the
  root cause behind the workflow CLI-approval / await-input pause cycle and
  also fixes token-budget / worktrunk pause reasons silently vanishing.
- dashboard: approve-cli now derives the approved command exclusively from
  the task's pausedReason; a caller-supplied body.command is ignored, closing
  a trust-on-first-use bypass.
- engine: await-input nodes resume only when THIS node paused the task (its
  marker on pausedReason), not on any pre-existing steering comment.
- engine: write-capable custom nodes (coding/script/CLI) are refused until a
  task worktree exists, so they never mutate the shared repo root before the
  execute seam.
- engine: document cliSkipApproval as an intentional workflow-author-only
  escape hatch; scriptName is now const (ESLint).
- tests: pausedReason round-trip coverage in store-persistence; approve-cli
  body-command-ignored + no-pending-command coverage; built-in-aware list
  assertion in workflow-routes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:16:16 -07:00
gsxdsm
af41902061 merge remote: adopt main's vitest kill-guard, branch-group-collision, and mission-wedge fixes; union CONCEPTS.md Missions section with localization vocabulary 2026-06-03 15:06:15 -07:00
gsxdsm
0c26441c01 Merge branch 'main' into gsxdsm/localization 2026-06-03 15:05:41 -07:00
gsxdsm
9de0c5cc8b fix(dashboard): apply SWR identity-churn highlight fix to QuickChatFAB + document the learning
The ce-compound simplicity review of the new solution doc surfaced that
QuickChatFAB.tsx carried the same identity-keyed highlight-reset effect
fixed in ChatView (87d044f18) — per FN-5893, the invariant now holds on
both surfaces.

- QuickChatFAB: reset keyed on joined skill ids, not array identity
- docs/solutions/ui-bugs/skill-autocomplete-highlight-reset-on-swr-
  revalidation.md: full root-cause learning (symptoms, three failed
  stabilization passes, fix, reusable identity-churn regression-test
  pattern, working grep heuristic)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:05:40 -07:00
gsxdsm
e685dc54e1 feat(dashboard): select a custom workflow when creating a task
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.
2026-06-03 14:00:59 -07:00
gsxdsm
a98d14c252 feat: per-node option to skip CLI first-run approval
A CLI node can set cliSkipApproval to bypass the trust-on-first-use pause and
run its command immediately. Exposed as a checkbox in the node inspector.
2026-06-03 13:52:42 -07:00
gsxdsm
f3bc757d22 fix(FN-branch-group): address PR review feedback (#1357)
- abandon route: guard already-abandoned groups (matches CLI)
- CLI branch-group list: single task fetch via filterTasksByBranchGroup (N+1)
- branch-name validator: git check-ref-format parity (//, dot-segments, .lock, @, @{, trailing /.)
- updateBranchGroup: validate renamed branchName too
- already-merged-detector: escape regex metachars in git log --grep; non-vacuous prose-mention assertion
- group PR callbacks: thread per-project cwd through SyncGroupPrFn/reconcile/github helpers (multi-project correctness)
- merger: group-PR sync is fire-and-forget (never blocks merge completion); deterministic test handle
- coordinator: sibling PR reuse only when open; reconcile skips member fetch on read-only path; argv-based git calls (no shell)
- task-lifecycle: legacy group-PR path links open PRs only; branch probes via execFile argv (injection hardening)
- mission/planning: branchContext.groupId only stamped for actual shared-mode members (groupId now optional)
- UI: Abandon reachable whenever PR is open (decoupled from completion); promote stays completion-gated
- tests: deterministic concurrency gate, real reconcile path in e2e, Surface Enumeration sections
2026-06-03 13:51:13 -07:00
gsxdsm
d6763e589c feat(dashboard): CLI command field + interactive input/approval banner
Node inspector: CLI executor toggles between a raw command textarea and a named
script. Task modal workflow tab: the await-input banner is now interactive
(reply textarea + Submit & resume), and a new awaiting-cli-approval banner shows
the pending command with an Approve & run action.
2026-06-03 13:48:28 -07:00
gsxdsm
ddde3c5b57 feat(engine,core,api): CLI nodes run arbitrary commands with trust-on-first-use approval
CLI prompt nodes now accept a raw cliCommand (any command + args), not just
named scripts. A raw command must be explicitly approved by the user before it
runs: an unapproved command pauses the task (status awaiting-cli-approval) with
the command shown; the user approves via POST /tasks/:id/workflow/approve-cli,
which records the exact command string in settings.approvedWorkflowCliCommands
and resumes. Named scripts (settings.scripts) still never require approval.
Adds POST /tasks/:id/workflow/input to answer await-input nodes (records a
steering comment + resumes).
2026-06-03 13:44:13 -07:00
gsxdsm
5a318bfe57 feat(dashboard): execution profiles + await-input UI for workflow nodes
Inspector for prompt nodes: executor picker (model via CustomModelDropdown,
agent, skill from discovered skills, CLI named script), auto-approve toggle,
per-node max retries, and a wait-for-user-input mode with a User input palette
preset. Task card shows a 'Needs input' badge for awaiting-user-input status;
the task modal workflow tab shows the node's question as a banner.
2026-06-03 13:34:05 -07:00