feat(edge-worker): forward per-runner custom binary paths to spawned runners#1228
Open
mitekk wants to merge 1 commit into
Open
feat(edge-worker): forward per-runner custom binary paths to spawned runners#1228mitekk wants to merge 1 commit into
mitekk wants to merge 1 commit into
Conversation
…runners Adds three optional per-repository config fields that flow through RunnerConfigBuilder into the corresponding runner's config when the resolved runner type matches: pathToClaudeCodeExecutable → claude runner (SDK option name) codexPath → codex runner geminiPath → gemini runner Each runner SDK already accepts its respective option, but cyrus's edge-worker / RunnerConfigBuilder never read them from `~/.cyrus/config.json` and forwarded them. So today, operators wanting to wrap a runner binary (sandbox dispatch, credential brokering, telemetry header injection, etc.) have to fork cyrus or replace the binary on PATH — neither great. Scoped narrowly: - Fields are per-repository (matches `model`, `fallbackModel`, `allowedTools`, etc.). No top-level fallback. - Each is only honored for its matching runner type; silently ignored for the others. Same conditional shape as the existing per-runner fields (plugins, skills, sandbox, chrome extraArgs). - The cursor runner is in-process (no spawned binary) and has no analogous knob — deliberately omitted. - Schemas regenerated via `pnpm --filter cyrus-core generate:json-schema`. Tests: 9 cases in packages/edge-worker/test/RunnerConfigBuilder.runner-binary-paths.test.ts (claude/codex/gemini × forwarded/omitted/wrong-runner-ignored).
ddd584b to
42d3372
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Cyrus's three spawned-binary runners —
claude,codex,gemini— each expose an SDK option for replacing the dispatched binary with a custom path:pathToClaudeCodeExecutable(Anthropic SDK)codexPath(cyrus-codex-runner)codexon PATHgeminiPath(cyrus-gemini-runner)geminion PATH(The
cursorrunner is in-process via the Cursor SDK — no spawned binary, so no analogous knob.)Useful when operators wrap the runner binary for:
docker run sandbox …)Today, none of these options can be set from
~/.cyrus/config.json.cyrus-claude-runner,cyrus-codex-runner, andcyrus-gemini-runnereach read their respective option from their own runner config, but nothing upstream of them in cyrus-edge-worker reads from cyrus config and forwards. So operators have to fork cyrus or replace the binary on PATH — neither great.Change
Adds three optional per-repository fields to
RepositoryConfigSchema:pathToClaudeCodeExecutable,codexPath,geminiPath. Each is forwarded byRunnerConfigBuilder.buildIssueConfigto the returned runner config when the resolved runner type matches. Naming matches each SDK's existing option, so the cyrus docs entry maps 1:1 to the SDK docs.Field placement: per-repository, matching the existing pattern for
model,fallbackModel,allowedTools,mcpConfigPath. No top-level fallback (kept the surface minimal; can be added in a follow-up).Files
packages/core/src/config-schemas.ts— three optional fields with JSDocpackages/edge-worker/src/RunnerConfigBuilder.ts— three runner-type-conditional forwards inbuildIssueConfig's claude/codex/gemini blockspackages/core/schemas/*.json— regenerated viapnpm --filter cyrus-core generate:json-schemadocs/CONFIG_FILE.md— documents the three fields under a "Custom runner-binary paths" subsectionpackages/edge-worker/test/RunnerConfigBuilder.runner-binary-paths.test.ts— 9 tests: claude/codex/gemini × forwarded-when-set / omitted-when-unset / ignored-when-wrong-runnerVerification
pnpm buildandpnpm test:packages:runboth clean on this branch. 632 edge-worker tests pass (was 626 on main, +6 for the new codex/gemini variants); 129 core tests pass; suite-wide green.Out of scope
executablefield ("bun"vs"node"for claude) — separate concern; wrapper scripts that shebangbashornodework fine via the default.buildChatConfig— only added tobuildIssueConfigsince that's where the per-runner-type branches live. Small follow-up if you want the same knob for Slack chat sessions.Closes no issue — happy to file a separate one if you'd prefer.