Commit Graph

7518 Commits

Author SHA1 Message Date
gsxdsm
ec4377e10a feat(engine): add Claude Code native-tier cli-agent adapter (U4)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 23:32:58 -07:00
gsxdsm
773ba76209 test(engine): self-skip real-PTY e2e when PTY I/O unavailable in environment 2026-06-04 23:24:54 -07:00
gsxdsm
4fe7dbe016 feat(core): one-time hard-move migration of workflow-policy settings to workflow setting values
30 moved keys (step execution, review/approval, per-phase model lanes) leave
DEFAULT_PROJECT_SETTINGS; marker-gated idempotent per-project migration writes
customized values to every in-use (workflowId, projectId); stale-writer guard;
tombstone allowlist derived from the builtin catalog.
2026-06-04 23:23:48 -07:00
gsxdsm
7b961d63f5 Merge pull request #1428 from Runfusion/gsxdsm/compound-plugin
Fix Settings plugin installs registering unloadable directory paths
2026-06-04 23:23:04 -07:00
gsxdsm
ed4c7ba006 feat(engine): add cli-agent telemetry hub and session state machine (U3)
Pure engine code (no HTTP) for the CLI agent executor:

- state-machine.ts: authoritative per-session state machine implementing the
  HTD diagram (starting→ready→busy⇄waitingOnInput→done; done→busy follow-up;
  dead-classification choice → killed/userExited/authFailed/resuming; resume cap
  of 2 with backoff → needsAttention). Positive completion is distinct from idle
  (idle never produces done); inactivity stall backstop re-armed by output/
  telemetry events (no fixed turn timeout); termination classification helper for
  all five paths; per-turn latches reset between turns. Persists every transition
  via CliSessionStore (the transient `resuming` machine state maps onto the U1
  `dead` store enum) and exposes a throttled `onStateChange` subscription for the
  later SSE bridge — no dashboard imports.

- telemetry-hub.ts: in-process ingestion contract (ingest(sessionId, event)) for
  the U17 route and log-tailing adapters. Mints high-entropy per-session hook
  tokens (issueToken/validateToken/invalidate); rebuilds the registry only from
  live sessions in CliSessionStore so stale tokens for non-live sessions never
  validate; a token validates only for its own session. Bounds everything
  ingested: per-event size caps, per-turn count caps (lifecycle events exempt),
  ANSI/control stripping before pattern matching, and secret redaction that
  survives chunk boundaries via a held-back carry window (redactSecrets from
  @fusion/core).

Tests: 35 new (state-machine.test.ts, telemetry-hub.test.ts) covering AE1/AE2,
stall backstop, all termination paths, resume caps, token registry, two-turn
latch reset, oversized capping, ANSI stripping, and cross-chunk redaction.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 23:18:48 -07:00
gsxdsm
407ce03bf2 feat(dashboard): workflow and template JSON import/export with trust-boundary stripping 2026-06-04 23:16:46 -07:00
gsxdsm
4fc1a9dd46 feat(engine): add CliAgentAdapter interface and CliSessionManager (U2)
Engine-owned PTY lifecycle for CLI agent sessions:
- adapter.ts: CliAgentAdapter interface (launch/env-allowlist builders,
  capability flags, readiness detection, injection formatter, resume builder,
  telemetry wiring) + CliAdapterRegistry with typed unknown/duplicate errors.
- session-manager.ts: CliSessionManager owning node-pty processes via the U16
  shared loader. Byte-bounded scrollback ring (default ~512KB), single
  serialized write queue shared by injections + user input (FIFO, deferral in
  quiet windows), latest-active-client resize, scoped-SIGKILL process registry
  on process exit (never port 4040), explicit async attach interface
  (scrollback + AsyncIterable<Uint8Array> + write/resize/detach),
  requestPause/requestResume watermark hooks, separate concurrency pool with
  typed CliConcurrencyLimitError at the ceiling.
- Security: bracketed paste only when ?2004h observed; unconditional control-char
  neutralization on the raw path; user keystrokes bypass neutralization.
- Persists lifecycle into the U1 CliSessionStore (create on spawn, update
  state/termination).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 23:04:13 -07:00
gsxdsm
66f1db122b Fix quality-backfill suites broken by fast-tests x workflow-columns merge race
Main went red when the fast-tests quality-backfill projects (PR #1385)
landed alongside the workflow-columns stream (PR #1424) — the new test
projects were written against pre-stream code:

- TaskFieldsSection.css toggle knob used background: #fff, violating the
  theme-token assertion in AgentListModal's styling-parity test; use
  var(--card) per the SkillsView toggle convention
- ListView.test.tsx api mock lacked fetchBoardWorkflows (TaskDetailModal
  now calls it on mount)
- chat.test.ts and routes-agent-import.test.ts @fusion/core mocks lacked
  registerTraitHookImpl (engine merge-trait registers hooks at import)
- auto-merge-toggle-blank.mobile and board-mobile-initial-render used
  vi.runAllTimers(), which never terminates now that sse-bus starts a
  keepalive setInterval; use vi.runOnlyPendingTimers()

Both quality-backfill projects now pass fully: 7151/7151 across 414
files.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 23:02:58 -07:00
gsxdsm
7bbb8b650a feat(dashboard): fragment insertion, seam-conflict, and graph-copy helpers 2026-06-04 23:02:50 -07:00
gsxdsm
9a4343be26 feat(engine): fn_workflow_settings agent tool + settings declaration parity, plugin-sdk types, engine-tools docs 2026-06-04 22:57:01 -07:00
gsxdsm
9089e18705 feat(dashboard): WorkflowSettingsPanel — definitions/values tabs, setting-value routes, flow-mapping round-trip 2026-06-04 22:57:01 -07:00
gsxdsm
8a5fa66def feat(engine,dashboard): expose workflow authoring tools to chat and planning agents 2026-06-04 22:54:49 -07:00
gsxdsm
202083dcff Merge U16: shared PTY native-asset loader in engine + redactSecrets in core 2026-06-04 22:54:01 -07:00
gsxdsm
ea18ef8d44 feat(engine): extract shared PTY native-asset loader and redactSecrets (U16)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 22:53:02 -07:00
gsxdsm
ad5205f186 feat(core): add cli_sessions table and CliSessionStore (U1)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 22:52:20 -07:00
gsxdsm
b1ebb22010 Merge current main (fast-tests quality-backfill projects) into plugin install fixes 2026-06-04 22:43:52 -07:00
gsxdsm
e8e54bf343 feat(engine): per-task effective workflow settings — resolver, two-tier entry merge, fallback alignment 2026-06-04 22:37:51 -07:00
gsxdsm
02e53b24b6 Merge pull request #1425 from tomdurrant/fix/opencode-go-api-key-env
Fix opencode-go model sync — pass API key to CLI and strip prefix from model IDs
2026-06-04 22:36:08 -07:00
gsxdsm
d8ff8db759 feat(core,dashboard): lazy idempotent legacy-step migration into workflow templates 2026-06-04 22:33:25 -07:00
gsxdsm
28e74f10d6 feat(core): workflow kind discriminator and steps-to-IR converter 2026-06-04 22:18:36 -07:00
gsxdsm
db4cdc6f5c feat(core): workflow setting values store — per-(workflow,project) table, validating write authority, drop-on-orphan resolution 2026-06-04 22:12:38 -07:00
gsxdsm
784021e95c Tighten plugin install route tests to full entry-resolution contract (#1428)
- Bundled fallback assertions for dependency-graph/reports now require
  the bundled.js entry-file suffix instead of just containing the id
- Add route-level fallback cases for dist/index.js and src/index.ts

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 22:12:36 -07:00
gsxdsm
7dde43a63b Address PR review feedback (#1428)
- Add heal block to createPluginRouter's enable handler so it matches
  routes.ts (directory-path registrations re-pointed at entry files)
- Test the 400 "no loadable entry file" install branch
- Add a real-fs drift-guard test asserting the CLI and @fusion/core
  copies of resolvePluginEntryPath resolve identically

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 22:10:20 -07:00
gsxdsm
5e52f6a3f6 feat(dashboard): shared schema-driven settings UI primitives 2026-06-04 22:00:04 -07:00
gsxdsm
04d5e66d24 feat(core): workflow IR typed settings declarations with built-in moved-key catalog 2026-06-04 22:00:04 -07:00
gsxdsm
742989c402 Merge remote branch updates (workflow-defined custom columns stream + main) into plugin install fixes 2026-06-04 21:58:26 -07:00
gsxdsm
4426eb8d74 Fix Settings plugin installs registering unloadable directory paths
Plugins installed from Settings → Built-in Plugins registered the
manifest directory as the plugin path, but since FN-4128 the loader
requires a loadable entry FILE (Node ESM cannot import directories),
so enabling failed with "Plugin entry must be a file, got directory".
Only the CLI startup path had been migrated to entry-file resolution,
which is why CLI-auto-installed plugins worked and Settings installs
never did.

- Add resolvePluginEntryPath (bundled.js → dist/index.js →
  src/index.ts) to @fusion/core; the CLI keeps its local copy (its
  test fs mocks don't reach externalized core) with sync comments
  both ways.
- Register the resolved entry file in both dashboard install routes;
  400 with a clear message when a package has no loadable entry.
- Heal legacy directory-path registrations on enable, mirroring the
  CLI's startup heal, so existing broken rows recover from the UI
  without a restart.
- Route tests: assert installs register entry files, cover the
  enable-route heal, and update existing install tests to the
  entry-file contract.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 21:57:46 -07:00
gsxdsm
0418730244 fix(i18n): restore catalog keys pruned by i18n:extract; keep only additive editor keys 2026-06-04 21:18:48 -07:00
gsxdsm
7e239e257f feat(dashboard): workflow editor onboarding and empty states 2026-06-04 21:13:13 -07:00
gsxdsm
d382d51c75 feat(dashboard): one-click auto-layout respecting column bands 2026-06-04 21:00:52 -07:00
gsxdsm
5a499ea212 feat(dashboard): workflow editor dialogs, inline rename, and dirty-state guard 2026-06-04 20:51:24 -07:00
gsxdsm
f67a2542b9 feat(dashboard): node/edge deletion with safe cascade semantics 2026-06-04 19:45:44 -07:00
gsxdsm
ffc4d8a6ed feat(dashboard): success/failure edge authoring with cycle guard and interpreter-only banner 2026-06-04 19:35:34 -07:00
gsxdsm
297a00d3de feat(dashboard): redesign workflow nodes as card-style with config summaries 2026-06-04 19:26:55 -07:00
gsxdsm
e5bab640f9 Merge pull request #1385 from Runfusion/gsxdsm/fast-tests
perf: speed up test suite across inner loop, full suite, and CI
2026-06-04 18:38:56 -07:00
gsxdsm
d05226f054 Merge pull request #1424 from Runfusion/gsxdsm/step-inversion
feat: step inversion — steps as workflow-modelable nodes (foreach/step-review/parse-steps/code, parallel execution, custom task fields)
2026-06-04 18:17:55 -07:00
Tom Durrant
978d07c96c Address PR review comments
- Update test assertions for bare model IDs
- Add deduplication guard for models with same bare ID
- Add validation for empty model IDs after prefix stripping
- Add test for API key forwarded as env var to spawn
- Add test for deduplication and empty model ID guard
- Extract shared handleOpencodeGoApiKeySaved helper
- Add changeset for the published package
2026-06-05 11:12:40 +10:00
Tom Durrant
1ae2555dd4 fix: strip provider prefix from opencode-go model IDs
normalizeOpencodeGoModel was prefixing model IDs with 'opencode-go/'
(e.g. 'opencode-go/deepseek-v4-flash'), but the Pi SDK sends the model
id field as the model name in API requests. The OpenCode API expects
bare model names (e.g. 'deepseek-v4-flash'), not prefixed ones.

Now strips the 'opencode/' or 'opencode-go/' prefix entirely so the
registered model ID matches what the API expects.
2026-06-05 10:40:01 +10:00
Tom Durrant
295d726768 fix: pass OPENCODE_API_KEY env var when syncing opencode-go models
discoverOpencodeGoModels() spawns 'opencode models opencode --refresh' but
never passed the saved API key as OPENCODE_API_KEY. The opencode CLI's
internal OpencodePlugin checks this env var to decide whether to show
paid models; without it, only free (cost.input === 0) models appear.

Now threads the apiKey from auth storage through to the spawned process
environment, so the CLI sees the user's Go subscription and returns the
full model catalog including paid models like Claude, GPT-5.x, Gemini, etc.

Callers in serve.ts, daemon.ts, and dashboard.ts all updated to read
the key from dashboardAuthStorage and pass it to refreshOpencodeGoModels.
syncStartupModels reads from authStorage in StartupSyncOptions.
2026-06-05 10:07:27 +10:00
gsxdsm
6f7f6860be fix: address PR review feedback (#1424)
- restore customFields on unarchive; reconcile all occupants on field-schema edits (store.ts)
- serialize per-field saves + controlled inputs in TaskFieldsSection (race fixes)
- fn_workflow_get includes layout; Array.isArray guards in validateCodeNodeSources
- per-instance graphStepActiveContext keying; rebase in instance worktree; clear run-once memo on RETHINK
- GET /api/step-parsers + registry-backed parser select (plugin parsers reachable from editor)
- translate new workflowNodes/workflowFields strings across all 5 non-en locales

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 16:16:50 -07:00
gsxdsm
86867c57b0 fix(ci): deflake seam-in-branch badge test — wait for graph hydration before Save, extend badge waitFor timeout
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 15:51:29 -07:00
gsxdsm
82f40a86b9 Merge branch 'main' into gsxdsm/compound-plugin 2026-06-04 15:34:31 -07:00
gsxdsm
0451172bfa fix(ci): theme-token conventions in field badges (white keyword, --text-muted) + roadmap plugin schema literal 107→108
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 14:43:54 -07:00
gsxdsm
021409d445 test(dashboard): regression tests for stepwise builtin editor render path (foreach group + template children + rework edges)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 14:34:53 -07:00
gsxdsm
3ebaa321f8 fix(review): apply code-review fixes — runId/foreachNodeId wiring, worktree-leak cleanup, rework re-execution, instance pruning, SIGKILL fallback, type dedup, board memo split, agent-native field-schema context + fn_workflow_get
17 findings from 12-reviewer code review applied:
- P1 runId trio (pin-probe/resume/markIntegrated used placeholder runId; 4-reviewer corroboration) + production-wiring tests
- P1 worktree/branch release on instance failure/exhaustion/abort
- P2 runGraphTaskStep no longer masks step-session failures; rejected memo cleared so rework re-executes
- P2 clearStaleInstanceStates wired at run start/end (mirrors branch pruning)
- P2 code-node timeout killSignal SIGKILL; dead template-recursion removed
- P1/P2 field-type re-declarations replaced with @fusion/core imports (stale comments removed)
- P2 Board memo split + TaskCard comparator stringify guard + modal prop-driven field defs
- HIGH agent-native: executor prompt injects custom-field schema/values; self-correcting rejection text; fn_workflow_get; fn_task_update bare-call guard; integration-conflict task log

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 14:01:55 -07:00
gsxdsm
94da14cd81 fix: lazy-load esbuild via createRequire (jsdom-safe engine import) + lint cleanup of dead helpers
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 13:19:55 -07:00
gsxdsm
7076dd4516 feat(sdk,dashboard,docs): U9 — save-time code validation route, SDK type exports, skill doc, step-inversion docs + changeset
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 13:15:50 -07:00
gsxdsm
60e9938f5a feat(core,engine): U7 — builtin stepwise coding workflow + trajectory parity & invariant suite; agent-tool surfaces for custom fields and IR authoring
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 13:15:49 -07:00
gsxdsm
af7c141976 feat(engine): U10 — parallel step execution: dependency scheduler, per-instance worktrees, ordered integration, conflict→rework (KTD-11)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 13:04:15 -07:00
gsxdsm
e87e745379 feat(dashboard): WorkflowFieldsPanel — field-definition authoring with live badge preview (U13 completion)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 12:44:43 -07:00