Give it a PR URL → it fetches diff, fans out to 3 subagents, runs npm test in a Daytona sandbox, and pauses for human Allow before posting.
Live demo on PR #3 • 14 tool calls • Sandbox FAIL → Comment posted
| Step | What you see | Screenshot |
|---|---|---|
| 1. Fetch | pull_request_read — 3 files + diff |
Agent steps: 15 tool calls |
| 2. Subagents | 3 parallel per file | src/app.js: BLOCKER · test.js: LOW · package.json: LOW |
| 3. Sandbox | Daytona — npm test → FAIL: add(2,3)=-1 |
Validate in Python fallback (proves sandbox-as-tool) |
| 4. Pause | Tool Approval Required for add_issue_comment |
Allow / Deny buttons |
| 5. Post | Comment posted successfully → [PR #3 comment] |
ID 5461998710 |
Session: Refresh browser mid-run → history persists.
| Harness | How ShipSafe uses it |
|---|---|
| 🔌 Tool | GitHub MCP pull_request_read, get_file_contents — 15 calls |
| 🧊 Sandbox | Daytona sandbox as tool — runs npm test / python test.py isolated |
| ✋ Approval | 2 gates — agent Approve and post? + harness add_issue_comment → Allow |
| 🤖 Subagents | 3 parallel reviews per file — keeps root context clean |
| 🔄 Session | Survives refresh/reconnect via Postgres + Redis |
| 🤖 Model | openrouter/z-ai-glm-5-2-free via Custom provider |
graph LR
A[/review PR URL/] --> B[Parse owner/repo/PR]
B --> C[GitHub MCP<br/>pull_request_read]
C --> D[Subagents x3<br/>per file]
C --> E[Sandbox<br/>npm test / python]
D --> F[Merge + Summarize]
E --> F
F --> G{Pause for human<br/>Allow/Deny}
G -->|Allow| H[add_issue_comment<br/>PR #]
G -->|Deny| I[Exit]
