Skip to content

refactor(runner): unify CLI + webui executor option builder, fix WithRegistry drop#1570

Merged
nextlevelshit merged 2 commits into
mainfrom
wave/pre1-service-layer
Apr 29, 2026
Merged

refactor(runner): unify CLI + webui executor option builder, fix WithRegistry drop#1570
nextlevelshit merged 2 commits into
mainfrom
wave/pre1-service-layer

Conversation

@nextlevelshit
Copy link
Copy Markdown
Collaborator

Closes #1566. First Phase 0 child of Epic #1565.

What

  • New runner.BuildExecutorOptions — single source of truth for assembling pipeline.ExecutorOption lists. Both LaunchInProcess (webui) and CLI's runOnce use it.
  • New runner.LaunchForeground — synchronous-run primitive for the CLI. Owns running/heartbeat/terminal status transitions (running → cancelled/rejected/failed/completed) so the dispatch logic lives in one package.
  • CLI runOnce becomes a thin wrapper around LaunchForeground. The pipeline.NewDefaultPipelineExecutor call no longer happens in cmd/wave/commands/.

Bug fix

runner.LaunchInProcess previously skipped pipeline.WithRegistry, silently dropping manifest-declared adapter binaries (e.g. forks like opencode-patched) on every dashboard-launched in-process run. BuildExecutorOptions always seeds an adapter.Registry from cfg.Manifest.Adapters[*].Binary.

Diff

  • +615 / -172 across 6 files (3 new, 3 modified)
  • Pure refactor + bug fix. No new flags, no behavior changes for green-path runs.

Tests

  • go test ./... passes.
  • internal/runner/options_test.go covers: registry-from-manifest (the bug fix), nil-manifest fallback, runtime override permutations (model/force-model/adapter/preserve/auto-approve), step filter parsing.

Acceptance vs #1566

  • CLI run calls service (runner.LaunchForeground), no direct executor access from cmd/
  • Webui control handlers continue calling runner.LaunchInProcess (via server_launcher.launchInProcess); registry bug fixed
  • Layer rules pass (go vet ./... clean)
  • No behavior change — full test suite green

…ground

Add runner.BuildExecutorOptions as the single source of truth for assembling
pipeline.ExecutorOption lists, and runner.LaunchForeground for CLI-shaped
synchronous runs. Both LaunchInProcess (webui) and the CLI's runOnce now
funnel through these primitives so option drift between the two paths is
no longer possible.

Fixes a latent bug where webui's LaunchInProcess never called
pipeline.WithRegistry, so manifest-declared adapter binaries (e.g. forks
named "opencode-patched") were silently dropped on dashboard-launched
runs. BuildExecutorOptions always seeds an adapter.Registry from the
manifest's Adapters[*].Binary entries.

LaunchForeground also pulls the running/heartbeat/terminal status
transitions out of cmd/wave/commands/run_stages.go runOnce so that the
cancelled/rejected/failed/completed dispatch lives in one package — both
launch shapes share the contract-rejection handling that used to be
CLI-only.

Closes #1566.
Address review feedback on PR #1570:
- SkipStatusUpdates docstring incorrectly implied the CLI sets it true.
  Both CLI and webui leave it false (default) — LaunchForeground owns
  status transitions. Comment now reflects this.
- Add coverage for MockOverride=true: confirms manifest-declared adapters
  are rerouted through the supplied runner so pipelines pinning a
  non-mock adapter still hit the mock under --mock.
@nextlevelshit nextlevelshit merged commit 54a5669 into main Apr 29, 2026
3 checks passed
@nextlevelshit nextlevelshit deleted the wave/pre1-service-layer branch April 29, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PRE-1: Service layer extraction (PipelineService/ExecutorService)

1 participant