Add multi-agent harness support (Pi, Codex, Claude Code)#58
Merged
Conversation
Repurpose Shipfile/flag agent from binary path to cursor|pi|codex|claude, prompt for kind on TTY Init, and wire Runs through agent.New with PATH preflight.
Wire agent kind pi through the factory so Runs spawn ephemeral print/JSON Pi with project trust, Ship-enforced timeouts, and curated tool/token events from agent_end streams.
Wire agent kind codex through the factory so Runs spawn ephemeral exec/JSON Codex with full approval bypass, Ship-enforced timeouts, and curated tool/token events from turn.completed streams.
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.
Summary
Makes
agent:/--agentan Agent kind (cursor,pi,codex,claude) instead of a binary path, with Init prompting for a kind on TTY (non-TTY defaults tocursor), config validation that rejects legacy binary-style values, and an agent Port factory wired through the CLI. Adds headless adapters for Pi, Codex, and Claude Code so a Run can drive every Phase through one chosen kind via that kind's default PATH binary, with Ship-owned timeouts and curated observability into the same sink Cursor already uses.Linked issues
RISK
agent: agentor a binary path in.ship/config.yamlwill fail at config parse until updated to a kind (agent: cursor). Operators who have not migrated will see a clear error with a migration hint, but Runs will not start until they edit the Shipfile.agent,pi,codex, orclaude) is missing or not authenticated, preflight fails before queue confirmation, or a Phase fails mid-Run and triggers Abort (undo commits for the failing Ticket). Affects anyone switching kinds without installing/auth'ing that CLI.QA — stress-test plan for a human
1. Happy path
From a clean git checkout of a real project (with
ghauthenticated and at least one open GitHub issue labeledship):go build -o /tmp/ship ./cmd/shipcd /path/to/project && /tmp/ship init— confirm the prompt listscursor, pi, codex, claude, typecursor, and verify.ship/config.yamlhasagent: cursor.agenton PATH and logged in, run/tmp/ship --max-iterations 1— confirm queue picker, one Iteration (Implement then Review), Final Phase, and a PR opens.agent: pi(or--agent pi), ensurepiis on PATH and authenticated, run a short Run (--max-iterations 1) and confirm Phases complete.agent: codex/codexon PATH.agent: claude/claudeon PATH.agent: cursor, run/tmp/ship --agent pi --helpis not enough — run a dry config path by starting a Run with--agent piand confirm preflight looks forpi(or completes if Pi is installed).2. Edges / failure cases
agent: agent(oragent: /usr/local/bin/agent) in.ship/config.yamland run/tmp/ship— expect parse failure mentioningagent: cursor.agent: opencodeor--agent opencode— expect unknown-kind error.agent: codexwithcodexremoved from PATH — expect preflight failure before the Ticket picker stamps the queue.ship initin a dir without.ship/config.yaml, typenope— expect failure and no new Shipfile written.ship init </dev/null(or equivalent non-TTY) — expectagent: cursorwritten with no prompt.--timeoutagainst a live Agent — confirm Abort restores the Ticket's commits and leavesshipon unfinished Tickets.3. Out of scope