Repository files navigation

oneshot

npmlicensedocs

Fire-and-forget agentic software work. Repo + task in, detached agent run out, reviewed PR plus a proof-of-work receipt ready.

laptop -> server, local worktree, or GitHub Actions -> Codex/Claude -> reviewed PR + receipt

oneshot is a tiny public workflow runtime for agentic software work. It gives coding agents the boring-but-crucial rails they need in the real world: clean worktrees, provider routing, durable logs, policy gates, review loops, PR creation, and a receipt that proves the whole contract actually ran.

It runs over SSH to a dev box, entirely locally with --local, or detached in CI with oneshot gha init.

Why try it

  • Fire and forget: detach a task with --bg (or in CI), close your laptop, get pinged when the receipt is ready.
  • Proof of work: every run writes a receipt (plan, contract steps, review outcome, policy verdict, assumptions, confidence) so you can trust a detached result without re-reading the whole diff. oneshot receipt <run-id> --html.
  • No dirty main branch: every run gets an isolated git worktree, so parallel work is safe.
  • Bring your agent: Codex-first by default, Claude-compatible, with adaptive routing when enabled.
  • Durable anywhere: SSH to your own box, a local detached process, or GitHub Actions for zero-infra runs that survive your machine.
  • Observable by design: every run writes JSONL events plus a durable ledger you can inspect later.
  • Workflow-shaped: use presets like ship, review, fix-ci, research, docs, and swarm-review.
  • Policy-aware: add .oneshot/policy.json for protected paths, secret checks, and required repo gates.
  • Toolable: oneshot mcp serve exposes the same engine to MCP-capable agent clients.

Install

Requires Bun. macOS and Linux.

bun install -g oneshot-ship

Quick start

oneshot init # configure
oneshot doctor # check local + remote setup
oneshot doctor --repo my-org/my-app # verify a checkout target
oneshot my-org/my-app "fix the login timeout"# ship

Try the runtime surface:

oneshot workflow list
oneshot my-org/my-app "fix failing CI" --workflow fix-ci
oneshot runs
oneshot status <run-id|events-file> --json
oneshot eval --json
oneshot mcp serve

How it works

oneshot runs an 8-step pipeline. Each run gets its own git worktree in /tmp, so your main branch is never touched. Parallel runs on the same repo are safe.

StepEngineWhat it does
1. ValidategitChecks the repo exists, fetches latest
2. WorktreegitCreates an isolated /tmp worktree from origin/main
3. RouteAdaptive routerPicks provider, reasoning, context shape, execution style, and fast/deep mode
4. PlanRoutedReads the codebase + repo instructions, outputs an implementation plan
5. ExecuteRoutedImplements the plan
6. Draft PRConfigurableCreates branch, commits, and writes PR metadata; runtime pushes and opens or updates the draft PR
7. ReviewConfigurableReviews the diff across correctness, compatibility, policy, security, and docs. Fixes issues directly
8. Finalizegit/ghPushes review fixes and marks PR ready, or preserves the draft if review fails

If execute times out with partial changes, the draft PR is still created so nothing is lost.

Usage

oneshot <repo>"<task>"# ship a task
oneshot <repo><linear-url># ship from a Linear ticket
oneshot <repo>"<task>" --bg # fire and forget
oneshot <repo>"<task>" --local # run locally, no SSH
oneshot <repo>"<task>" --mode deep # skip classification and force deep mode
oneshot <repo>"<task>" --workflow ship # apply a workflow preset
oneshot <repo>"<task>" --deep-review # force exhaustive review
oneshot <repo>"<task>" --model gpt-5.5 # override configured plan/PR model
oneshot <repo>"<task>" --branch dev # target a different branch
oneshot <repo>"<task>" --base-path /srv/workspaces # override repo root for this run
oneshot <repo>"<task>" --worktree-root /tmp/agents # override temp worktree root
oneshot <repo> --dry-run # validate only
oneshot init # configure
oneshot stats # recent runs + timing
oneshot runs # durable run ledger
oneshot runs --json --limit 10 # list runs for automation
oneshot status <run-id|events-file> --json # inspect one run
oneshot receipt <run-id># proof-of-work receipt (text)
oneshot receipt <run-id> --html # receipt as a self-contained HTML artifact
oneshot eval --json # summarize run outcomes
oneshot doctor # setup and remote health checks
oneshot doctor --repo my-org/my-app # setup + checkout health
oneshot route "fix failing CI and publish" --json # inspect the hidden route
oneshot workflow list # inspect workflow presets
oneshot workflow show fix-ci --json # inspect one workflow preset
oneshot policy init # create .oneshot/policy.json
oneshot policy init --path ./repo # write policy in another directory
oneshot gha init # scaffold a GitHub Actions workflow for detached runs
oneshot mcp serve # expose oneshot as MCP tools

Flags

FlagShortDescription
--model-mOverride configured plan/PR model
--branch-bBase branch (default: main)
--base-pathOverride the workspace path used to locate the repo
--worktree-rootOverride where temporary git worktrees are created
--modeSkip classification and force fast or deep mode
--workflowApply a workflow preset: ship, review, fix-ci, research, docs, or swarm-review
--deep-reviewForce exhaustive review mode
--localRun locally instead of over SSH
--bgRun detached in background (returns PID + log path)
--dry-run-dValidate only
--events-fileMirror JSONL events to an additional file
--repoWith doctor, verify a specific owner/repo checkout exists
--providerWith route, choose the fallback provider (codex or claude)

Prerequisites

On your laptop:Bun, SSH access to your server

On your server (or local machine with --local):

Configuration

~/.oneshot/config.json, created by oneshot init:

{
"host": "user@100.x.x.x",
"basePath": "~/projects",
"provider": "codex",
"routing": { "enabled": true },
"linearApiKey": "lin_api_...",
"claude": {
"model": "opus",
"timeoutMinutes": 180
},
"codex": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh",
"reviewModel": "gpt-5.5",
"reviewReasoningEffort": "xhigh",
"timeoutMinutes": 180
},
"phases": {
"classify": { "model": "gpt-5.5", "reasoningEffort": "medium" },
"plan": { "model": "gpt-5.5", "reasoningEffort": "xhigh" },
"execute": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"review": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"deepReview": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"pr": { "model": "gpt-5.5", "reasoningEffort": "high" }
},
"stepTimeouts": {
"planMinutes": 20,
"executeMinutes": 60,
"reviewMinutes": 20,
"deepReviewMinutes": 20,
"prMinutes": 20
}
}

Only host is required for SSH runs. Local mode works without a config file. Remote SSH runs stream the active oneshot config to the server for that run, so basePath, provider defaults, timeout settings, and configured Linear credentials stay aligned without requiring a duplicate ~/.oneshot/config.json on the server.

KeyRequiredDescription
hostSSH onlySSH target, e.g. user@192.168.1.10
basePathNoWhere repos live. Default: ~/projects
worktreeRootNoScratch directory for temporary git worktrees. Default: /tmp
providerNoFallback agent provider when adaptive routing is off or no route rule wins. Default: codex
routing.enabledNoEnables invisible provider/reasoning routing. Codex and Claude still use their configured frontier model; the router varies provider and effort, not model class
anthropicApiKeyClaude onlyFalls back to ANTHROPIC_API_KEY env var
linearApiKeyNoEnables Linear ticket integration
claude.modelClaude onlyDefault Claude model. Default: opus
codex.modelCodex onlyDefault Codex model. Default: gpt-5.5
codex.reasoningEffortCodex onlyDefault Codex reasoning effort. Default: xhigh
codex.reviewModelCodex onlyDefault for review phases. Default: same as codex.model
codex.reviewReasoningEffortCodex onlyDefault review reasoning effort. Default: same as codex.reasoningEffort
phases.<phase>.modelNoExact model for that phase under the selected provider
phases.<phase>.reasoningEffortNoReasoning effort for that phase, e.g. medium, high, xhigh. Passed to Codex and to Claude via --effort
stepTimeoutsNoPer-step timeout overrides in minutes

phases is optional. If it is omitted, every agent phase uses the selected provider and its default model settings. Any stale phases.<phase>.provider values from older configs are ignored when adaptive routing is off. With routing.enabled: true, oneshot's adaptive router can silently choose Codex or Claude per task while preserving each provider's configured frontier model.

Adaptive routing is intentionally invisible during normal use. Code edits, tests, refactors, PR work, and ship requests route to Codex by default. Tool-heavy operations, browser/admin/log/service work, and external workflow orchestration can route to Claude. If code will be edited, Codex wins the tie. Use oneshot route "<task>" --json only when you want to inspect the decision.

Repos on the server should live as <org>/<repo> under the base path. Repo slugs are intentionally strict: exactly owner/repo, using only letters, numbers, dot, underscore, and hyphen. Nested paths and .. are rejected before any filesystem access.

~/projects/
acme/api/
acme/web/

Linear integration

Pass a Linear URL instead of a task string:

oneshot acme/api https://linear.app/acme/issue/ENG-142
  1. Fetches issue title, description, and comments via GraphQL
  2. Uses ticket as context for the planning step
  3. Uses the issue ID in the branch name (oneshot/eng-142-...)
  4. Moves the ticket to "In Review" and comments the PR URL

Requires linearApiKey in config.

Customization

CLAUDE.md: put one in any repo root. oneshot passes it to the configured agents for planning and execution. Use it for coding standards, architecture decisions, test requirements.

Prompt templates: edit these to change pipeline behavior:

FileControls
prompts/plan.txtHow the plan agent explores and plans
prompts/execute.txtHow the execute agent implements changes
prompts/review.txtHow the review agent reviews the diff
prompts/pr.txtHow the PR agent writes branch/commit/PR metadata

Templates use {{variable}} placeholders replaced at runtime.

The repo's CLAUDE.md is also supplied to the planning and execution steps, so the task string is the primary operator input, not the only context the agents receive.

For dense specs, explainers, review maps, incident reports, design sheets, or one-off editors, the templates allow a self-contained HTML artifact instead of a long markdown document. Durable artifacts should live under docs/artifacts/; throwaway local artifacts should stay under /tmp/oneshot-html-artifacts/.

Events

Every run writes JSONL events to /tmp/oneshot-<runId>.events.jsonl and the durable local ledger at ~/.oneshot/runs/<runId>.events.jsonl. Use --events-file <path> to mirror to another file:

oneshot acme/api "fix bug" --local --events-file /tmp/run.events.jsonl

Events:

  • started (includes runtime metadata such as CLI version, host, pid, cwd, platform, and worktree root), classified, step (running/done/failed), completed (success/failed/dry-run)
  • agent for live agent activity: commands, tools, file changes, todos, web searches, warnings, draft PR creation, and turn/session markers

Workflows, policy, and MCP

Workflow presets wrap a task with a stronger operating mode while keeping the CLI portable:

oneshot workflow list
oneshot acme/api "fix the failing payment test" --workflow fix-ci
oneshot acme/web "review PR feedback and make it shippable" --workflow review

Policy packs live at .oneshot/policy.json. The default pack protects secret-like files and can require repo-specific checks before a draft PR is created:

oneshot policy init

oneshot mcp serve exposes the public engine as MCP tools for agent clients. The server supports running a task, listing runs, reading run status, reading a run receipt, initializing policy, listing workflows, and summarizing eval outcomes.

Receipts

Every run writes a proof-of-work receipt to ~/.oneshot/runs/<runId>.receipt.json. The receipt is the thing that makes fire-and-forget trustworthy: it records what was planned, which contract steps ran and how long they took, the review outcome (passed / timed-out / failed), the policy verdict, the defaults the run had to assume because a detached run cannot ask you, and a derived confidence rating (high only when the run shipped with a clean review and a clean policy gate).

oneshot receipt <run-id># human-readable sitrep
oneshot receipt <run-id> --json # machine-readable
oneshot receipt <run-id> --html > receipt.html # self-contained artifact

Runs without a receipt file (older or remote-only runs) reconstruct a thinner receipt from the event stream; reconstructed successes are capped at medium confidence since the contract verdict cannot be re-derived.

Notifications

So a detached run can ping you when its receipt is ready, add a notify block to ~/.oneshot/config.json. It is backend-agnostic on purpose: wire Slack, Discord, a desktop toast, or anything else yourself. Notification is best effort and never fails a run.

{
"notify": {
"webhook": "https://hooks.example.com/oneshot",
"command": "my-notify-script.sh",
"onSuccess": true,
"onFailure": true
}
}

The webhook receives the receipt summary as a JSON POST. The command runs with the same payload on stdin and in ONESHOT_NOTIFY_STATUS, ONESHOT_NOTIFY_REPO, ONESHOT_NOTIFY_HEADLINE, ONESHOT_NOTIFY_PR_URL, ONESHOT_NOTIFY_RECEIPT, and ONESHOT_NOTIFY_JSON.

GitHub Actions backend

Not everyone has a 24/7 dev box, but every repo has Actions: a durable executor that survives your laptop closing, with a secrets vault, that can open PRs natively. oneshot gha init scaffolds a workflow_dispatch workflow that runs the same contract in CI and uploads the receipt as an artifact.

oneshot gha init # writes .github/workflows/oneshot.yml
oneshot gha init --provider claude # wire the Anthropic key instead of OpenAI
gh workflow run oneshot.yml -f task="fix the login timeout"

It requires one provider API key in the repo's Actions secrets (OPENAI_API_KEY for Codex, ANTHROPIC_API_KEY for Claude); GITHUB_TOKEN is provided automatically and opens the PR. The command prints exactly which secret to add.

Doctor and recovery

oneshot doctor checks the installed package freshness against npm, local prerequisites, config file, recent event stream, SSH reachability, and remote binaries when a remote host is configured. Use oneshot doctor --local --json for machine-readable local checks.

Add --repo <owner/repo> to verify the configured local or remote base path actually contains the checkout before dispatch:

oneshot doctor --repo zkp2p/pay
oneshot doctor --local --repo zkp2p/pay --json

Failed runs preserve the worktree under the configured worktreeRoot and write a failed completed event with the error code and completed step timings. Start with oneshot runs, oneshot status <run-id>, and oneshot eval, then inspect the event file or preserved worktree path printed in the logs.

Agent skill

Works as an Agent Skill in Claude Code, Codex CLI, Cursor, and other compatible agents.

npx skills add ADWilkinson/oneshot-cli

Or via ClawHub:

clawhub install oneshot-ship

Agents pick it up automatically, or call /oneshot-ship directly.

License

MIT

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

oneshot

npmlicensedocs

Fire-and-forget agentic software work. Repo + task in, detached agent run out, reviewed PR plus a proof-of-work receipt ready.

laptop -> server, local worktree, or GitHub Actions -> Codex/Claude -> reviewed PR + receipt

oneshot is a tiny public workflow runtime for agentic software work. It gives coding agents the boring-but-crucial rails they need in the real world: clean worktrees, provider routing, durable logs, policy gates, review loops, PR creation, and a receipt that proves the whole contract actually ran.

It runs over SSH to a dev box, entirely locally with --local, or detached in CI with oneshot gha init.

Why try it

  • Fire and forget: detach a task with --bg (or in CI), close your laptop, get pinged when the receipt is ready.
  • Proof of work: every run writes a receipt (plan, contract steps, review outcome, policy verdict, assumptions, confidence) so you can trust a detached result without re-reading the whole diff. oneshot receipt <run-id> --html.
  • No dirty main branch: every run gets an isolated git worktree, so parallel work is safe.
  • Bring your agent: Codex-first by default, Claude-compatible, with adaptive routing when enabled.
  • Durable anywhere: SSH to your own box, a local detached process, or GitHub Actions for zero-infra runs that survive your machine.
  • Observable by design: every run writes JSONL events plus a durable ledger you can inspect later.
  • Workflow-shaped: use presets like ship, review, fix-ci, research, docs, and swarm-review.
  • Policy-aware: add .oneshot/policy.json for protected paths, secret checks, and required repo gates.
  • Toolable: oneshot mcp serve exposes the same engine to MCP-capable agent clients.

Install

Requires Bun. macOS and Linux.

bun install -g oneshot-ship

Quick start

oneshot init # configure
oneshot doctor # check local + remote setup
oneshot doctor --repo my-org/my-app # verify a checkout target
oneshot my-org/my-app "fix the login timeout"# ship

Try the runtime surface:

oneshot workflow list
oneshot my-org/my-app "fix failing CI" --workflow fix-ci
oneshot runs
oneshot status <run-id|events-file> --json
oneshot eval --json
oneshot mcp serve

How it works

oneshot runs an 8-step pipeline. Each run gets its own git worktree in /tmp, so your main branch is never touched. Parallel runs on the same repo are safe.

StepEngineWhat it does
1. ValidategitChecks the repo exists, fetches latest
2. WorktreegitCreates an isolated /tmp worktree from origin/main
3. RouteAdaptive routerPicks provider, reasoning, context shape, execution style, and fast/deep mode
4. PlanRoutedReads the codebase + repo instructions, outputs an implementation plan
5. ExecuteRoutedImplements the plan
6. Draft PRConfigurableCreates branch, commits, and writes PR metadata; runtime pushes and opens or updates the draft PR
7. ReviewConfigurableReviews the diff across correctness, compatibility, policy, security, and docs. Fixes issues directly
8. Finalizegit/ghPushes review fixes and marks PR ready, or preserves the draft if review fails

If execute times out with partial changes, the draft PR is still created so nothing is lost.

Usage

oneshot <repo>"<task>"# ship a task
oneshot <repo><linear-url># ship from a Linear ticket
oneshot <repo>"<task>" --bg # fire and forget
oneshot <repo>"<task>" --local # run locally, no SSH
oneshot <repo>"<task>" --mode deep # skip classification and force deep mode
oneshot <repo>"<task>" --workflow ship # apply a workflow preset
oneshot <repo>"<task>" --deep-review # force exhaustive review
oneshot <repo>"<task>" --model gpt-5.5 # override configured plan/PR model
oneshot <repo>"<task>" --branch dev # target a different branch
oneshot <repo>"<task>" --base-path /srv/workspaces # override repo root for this run
oneshot <repo>"<task>" --worktree-root /tmp/agents # override temp worktree root
oneshot <repo> --dry-run # validate only
oneshot init # configure
oneshot stats # recent runs + timing
oneshot runs # durable run ledger
oneshot runs --json --limit 10 # list runs for automation
oneshot status <run-id|events-file> --json # inspect one run
oneshot receipt <run-id># proof-of-work receipt (text)
oneshot receipt <run-id> --html # receipt as a self-contained HTML artifact
oneshot eval --json # summarize run outcomes
oneshot doctor # setup and remote health checks
oneshot doctor --repo my-org/my-app # setup + checkout health
oneshot route "fix failing CI and publish" --json # inspect the hidden route
oneshot workflow list # inspect workflow presets
oneshot workflow show fix-ci --json # inspect one workflow preset
oneshot policy init # create .oneshot/policy.json
oneshot policy init --path ./repo # write policy in another directory
oneshot gha init # scaffold a GitHub Actions workflow for detached runs
oneshot mcp serve # expose oneshot as MCP tools

Flags

FlagShortDescription
--model-mOverride configured plan/PR model
--branch-bBase branch (default: main)
--base-pathOverride the workspace path used to locate the repo
--worktree-rootOverride where temporary git worktrees are created
--modeSkip classification and force fast or deep mode
--workflowApply a workflow preset: ship, review, fix-ci, research, docs, or swarm-review
--deep-reviewForce exhaustive review mode
--localRun locally instead of over SSH
--bgRun detached in background (returns PID + log path)
--dry-run-dValidate only
--events-fileMirror JSONL events to an additional file
--repoWith doctor, verify a specific owner/repo checkout exists
--providerWith route, choose the fallback provider (codex or claude)

Prerequisites

On your laptop:Bun, SSH access to your server

On your server (or local machine with --local):

Configuration

~/.oneshot/config.json, created by oneshot init:

{
"host": "user@100.x.x.x",
"basePath": "~/projects",
"provider": "codex",
"routing": { "enabled": true },
"linearApiKey": "lin_api_...",
"claude": {
"model": "opus",
"timeoutMinutes": 180
},
"codex": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh",
"reviewModel": "gpt-5.5",
"reviewReasoningEffort": "xhigh",
"timeoutMinutes": 180
},
"phases": {
"classify": { "model": "gpt-5.5", "reasoningEffort": "medium" },
"plan": { "model": "gpt-5.5", "reasoningEffort": "xhigh" },
"execute": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"review": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"deepReview": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"pr": { "model": "gpt-5.5", "reasoningEffort": "high" }
},
"stepTimeouts": {
"planMinutes": 20,
"executeMinutes": 60,
"reviewMinutes": 20,
"deepReviewMinutes": 20,
"prMinutes": 20
}
}

Only host is required for SSH runs. Local mode works without a config file. Remote SSH runs stream the active oneshot config to the server for that run, so basePath, provider defaults, timeout settings, and configured Linear credentials stay aligned without requiring a duplicate ~/.oneshot/config.json on the server.

KeyRequiredDescription
hostSSH onlySSH target, e.g. user@192.168.1.10
basePathNoWhere repos live. Default: ~/projects
worktreeRootNoScratch directory for temporary git worktrees. Default: /tmp
providerNoFallback agent provider when adaptive routing is off or no route rule wins. Default: codex
routing.enabledNoEnables invisible provider/reasoning routing. Codex and Claude still use their configured frontier model; the router varies provider and effort, not model class
anthropicApiKeyClaude onlyFalls back to ANTHROPIC_API_KEY env var
linearApiKeyNoEnables Linear ticket integration
claude.modelClaude onlyDefault Claude model. Default: opus
codex.modelCodex onlyDefault Codex model. Default: gpt-5.5
codex.reasoningEffortCodex onlyDefault Codex reasoning effort. Default: xhigh
codex.reviewModelCodex onlyDefault for review phases. Default: same as codex.model
codex.reviewReasoningEffortCodex onlyDefault review reasoning effort. Default: same as codex.reasoningEffort
phases.<phase>.modelNoExact model for that phase under the selected provider
phases.<phase>.reasoningEffortNoReasoning effort for that phase, e.g. medium, high, xhigh. Passed to Codex and to Claude via --effort
stepTimeoutsNoPer-step timeout overrides in minutes

phases is optional. If it is omitted, every agent phase uses the selected provider and its default model settings. Any stale phases.<phase>.provider values from older configs are ignored when adaptive routing is off. With routing.enabled: true, oneshot's adaptive router can silently choose Codex or Claude per task while preserving each provider's configured frontier model.

Adaptive routing is intentionally invisible during normal use. Code edits, tests, refactors, PR work, and ship requests route to Codex by default. Tool-heavy operations, browser/admin/log/service work, and external workflow orchestration can route to Claude. If code will be edited, Codex wins the tie. Use oneshot route "<task>" --json only when you want to inspect the decision.

Repos on the server should live as <org>/<repo> under the base path. Repo slugs are intentionally strict: exactly owner/repo, using only letters, numbers, dot, underscore, and hyphen. Nested paths and .. are rejected before any filesystem access.

~/projects/
acme/api/
acme/web/

Linear integration

Pass a Linear URL instead of a task string:

oneshot acme/api https://linear.app/acme/issue/ENG-142
  1. Fetches issue title, description, and comments via GraphQL
  2. Uses ticket as context for the planning step
  3. Uses the issue ID in the branch name (oneshot/eng-142-...)
  4. Moves the ticket to "In Review" and comments the PR URL

Requires linearApiKey in config.

Customization

CLAUDE.md: put one in any repo root. oneshot passes it to the configured agents for planning and execution. Use it for coding standards, architecture decisions, test requirements.

Prompt templates: edit these to change pipeline behavior:

FileControls
prompts/plan.txtHow the plan agent explores and plans
prompts/execute.txtHow the execute agent implements changes
prompts/review.txtHow the review agent reviews the diff
prompts/pr.txtHow the PR agent writes branch/commit/PR metadata

Templates use {{variable}} placeholders replaced at runtime.

The repo's CLAUDE.md is also supplied to the planning and execution steps, so the task string is the primary operator input, not the only context the agents receive.

For dense specs, explainers, review maps, incident reports, design sheets, or one-off editors, the templates allow a self-contained HTML artifact instead of a long markdown document. Durable artifacts should live under docs/artifacts/; throwaway local artifacts should stay under /tmp/oneshot-html-artifacts/.

Events

Every run writes JSONL events to /tmp/oneshot-<runId>.events.jsonl and the durable local ledger at ~/.oneshot/runs/<runId>.events.jsonl. Use --events-file <path> to mirror to another file:

oneshot acme/api "fix bug" --local --events-file /tmp/run.events.jsonl

Events:

  • started (includes runtime metadata such as CLI version, host, pid, cwd, platform, and worktree root), classified, step (running/done/failed), completed (success/failed/dry-run)
  • agent for live agent activity: commands, tools, file changes, todos, web searches, warnings, draft PR creation, and turn/session markers

Workflows, policy, and MCP

Workflow presets wrap a task with a stronger operating mode while keeping the CLI portable:

oneshot workflow list
oneshot acme/api "fix the failing payment test" --workflow fix-ci
oneshot acme/web "review PR feedback and make it shippable" --workflow review

Policy packs live at .oneshot/policy.json. The default pack protects secret-like files and can require repo-specific checks before a draft PR is created:

oneshot policy init

oneshot mcp serve exposes the public engine as MCP tools for agent clients. The server supports running a task, listing runs, reading run status, reading a run receipt, initializing policy, listing workflows, and summarizing eval outcomes.

Receipts

Every run writes a proof-of-work receipt to ~/.oneshot/runs/<runId>.receipt.json. The receipt is the thing that makes fire-and-forget trustworthy: it records what was planned, which contract steps ran and how long they took, the review outcome (passed / timed-out / failed), the policy verdict, the defaults the run had to assume because a detached run cannot ask you, and a derived confidence rating (high only when the run shipped with a clean review and a clean policy gate).

oneshot receipt <run-id># human-readable sitrep
oneshot receipt <run-id> --json # machine-readable
oneshot receipt <run-id> --html > receipt.html # self-contained artifact

Runs without a receipt file (older or remote-only runs) reconstruct a thinner receipt from the event stream; reconstructed successes are capped at medium confidence since the contract verdict cannot be re-derived.

Notifications

So a detached run can ping you when its receipt is ready, add a notify block to ~/.oneshot/config.json. It is backend-agnostic on purpose: wire Slack, Discord, a desktop toast, or anything else yourself. Notification is best effort and never fails a run.

{
"notify": {
"webhook": "https://hooks.example.com/oneshot",
"command": "my-notify-script.sh",
"onSuccess": true,
"onFailure": true
}
}

The webhook receives the receipt summary as a JSON POST. The command runs with the same payload on stdin and in ONESHOT_NOTIFY_STATUS, ONESHOT_NOTIFY_REPO, ONESHOT_NOTIFY_HEADLINE, ONESHOT_NOTIFY_PR_URL, ONESHOT_NOTIFY_RECEIPT, and ONESHOT_NOTIFY_JSON.

GitHub Actions backend

Not everyone has a 24/7 dev box, but every repo has Actions: a durable executor that survives your laptop closing, with a secrets vault, that can open PRs natively. oneshot gha init scaffolds a workflow_dispatch workflow that runs the same contract in CI and uploads the receipt as an artifact.

oneshot gha init # writes .github/workflows/oneshot.yml
oneshot gha init --provider claude # wire the Anthropic key instead of OpenAI
gh workflow run oneshot.yml -f task="fix the login timeout"

It requires one provider API key in the repo's Actions secrets (OPENAI_API_KEY for Codex, ANTHROPIC_API_KEY for Claude); GITHUB_TOKEN is provided automatically and opens the PR. The command prints exactly which secret to add.

Doctor and recovery

oneshot doctor checks the installed package freshness against npm, local prerequisites, config file, recent event stream, SSH reachability, and remote binaries when a remote host is configured. Use oneshot doctor --local --json for machine-readable local checks.

Add --repo <owner/repo> to verify the configured local or remote base path actually contains the checkout before dispatch:

oneshot doctor --repo zkp2p/pay
oneshot doctor --local --repo zkp2p/pay --json

Failed runs preserve the worktree under the configured worktreeRoot and write a failed completed event with the error code and completed step timings. Start with oneshot runs, oneshot status <run-id>, and oneshot eval, then inspect the event file or preserved worktree path printed in the logs.

Agent skill

Works as an Agent Skill in Claude Code, Codex CLI, Cursor, and other compatible agents.

npx skills add ADWilkinson/oneshot-cli

Or via ClawHub:

clawhub install oneshot-ship

Agents pick it up automatically, or call /oneshot-ship directly.

License

MIT

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

oneshot

npmlicensedocs

Fire-and-forget agentic software work. Repo + task in, detached agent run out, reviewed PR plus a proof-of-work receipt ready.

laptop -> server, local worktree, or GitHub Actions -> Codex/Claude -> reviewed PR + receipt

oneshot is a tiny public workflow runtime for agentic software work. It gives coding agents the boring-but-crucial rails they need in the real world: clean worktrees, provider routing, durable logs, policy gates, review loops, PR creation, and a receipt that proves the whole contract actually ran.

It runs over SSH to a dev box, entirely locally with --local, or detached in CI with oneshot gha init.

Why try it

  • Fire and forget: detach a task with --bg (or in CI), close your laptop, get pinged when the receipt is ready.
  • Proof of work: every run writes a receipt (plan, contract steps, review outcome, policy verdict, assumptions, confidence) so you can trust a detached result without re-reading the whole diff. oneshot receipt <run-id> --html.
  • No dirty main branch: every run gets an isolated git worktree, so parallel work is safe.
  • Bring your agent: Codex-first by default, Claude-compatible, with adaptive routing when enabled.
  • Durable anywhere: SSH to your own box, a local detached process, or GitHub Actions for zero-infra runs that survive your machine.
  • Observable by design: every run writes JSONL events plus a durable ledger you can inspect later.
  • Workflow-shaped: use presets like ship, review, fix-ci, research, docs, and swarm-review.
  • Policy-aware: add .oneshot/policy.json for protected paths, secret checks, and required repo gates.
  • Toolable: oneshot mcp serve exposes the same engine to MCP-capable agent clients.

Install

Requires Bun. macOS and Linux.

bun install -g oneshot-ship

Quick start

oneshot init # configure
oneshot doctor # check local + remote setup
oneshot doctor --repo my-org/my-app # verify a checkout target
oneshot my-org/my-app "fix the login timeout"# ship

Try the runtime surface:

oneshot workflow list
oneshot my-org/my-app "fix failing CI" --workflow fix-ci
oneshot runs
oneshot status <run-id|events-file> --json
oneshot eval --json
oneshot mcp serve

How it works

oneshot runs an 8-step pipeline. Each run gets its own git worktree in /tmp, so your main branch is never touched. Parallel runs on the same repo are safe.

StepEngineWhat it does
1. ValidategitChecks the repo exists, fetches latest
2. WorktreegitCreates an isolated /tmp worktree from origin/main
3. RouteAdaptive routerPicks provider, reasoning, context shape, execution style, and fast/deep mode
4. PlanRoutedReads the codebase + repo instructions, outputs an implementation plan
5. ExecuteRoutedImplements the plan
6. Draft PRConfigurableCreates branch, commits, and writes PR metadata; runtime pushes and opens or updates the draft PR
7. ReviewConfigurableReviews the diff across correctness, compatibility, policy, security, and docs. Fixes issues directly
8. Finalizegit/ghPushes review fixes and marks PR ready, or preserves the draft if review fails

If execute times out with partial changes, the draft PR is still created so nothing is lost.

Usage

oneshot <repo>"<task>"# ship a task
oneshot <repo><linear-url># ship from a Linear ticket
oneshot <repo>"<task>" --bg # fire and forget
oneshot <repo>"<task>" --local # run locally, no SSH
oneshot <repo>"<task>" --mode deep # skip classification and force deep mode
oneshot <repo>"<task>" --workflow ship # apply a workflow preset
oneshot <repo>"<task>" --deep-review # force exhaustive review
oneshot <repo>"<task>" --model gpt-5.5 # override configured plan/PR model
oneshot <repo>"<task>" --branch dev # target a different branch
oneshot <repo>"<task>" --base-path /srv/workspaces # override repo root for this run
oneshot <repo>"<task>" --worktree-root /tmp/agents # override temp worktree root
oneshot <repo> --dry-run # validate only
oneshot init # configure
oneshot stats # recent runs + timing
oneshot runs # durable run ledger
oneshot runs --json --limit 10 # list runs for automation
oneshot status <run-id|events-file> --json # inspect one run
oneshot receipt <run-id># proof-of-work receipt (text)
oneshot receipt <run-id> --html # receipt as a self-contained HTML artifact
oneshot eval --json # summarize run outcomes
oneshot doctor # setup and remote health checks
oneshot doctor --repo my-org/my-app # setup + checkout health
oneshot route "fix failing CI and publish" --json # inspect the hidden route
oneshot workflow list # inspect workflow presets
oneshot workflow show fix-ci --json # inspect one workflow preset
oneshot policy init # create .oneshot/policy.json
oneshot policy init --path ./repo # write policy in another directory
oneshot gha init # scaffold a GitHub Actions workflow for detached runs
oneshot mcp serve # expose oneshot as MCP tools

Flags

FlagShortDescription
--model-mOverride configured plan/PR model
--branch-bBase branch (default: main)
--base-pathOverride the workspace path used to locate the repo
--worktree-rootOverride where temporary git worktrees are created
--modeSkip classification and force fast or deep mode
--workflowApply a workflow preset: ship, review, fix-ci, research, docs, or swarm-review
--deep-reviewForce exhaustive review mode
--localRun locally instead of over SSH
--bgRun detached in background (returns PID + log path)
--dry-run-dValidate only
--events-fileMirror JSONL events to an additional file
--repoWith doctor, verify a specific owner/repo checkout exists
--providerWith route, choose the fallback provider (codex or claude)

Prerequisites

On your laptop:Bun, SSH access to your server

On your server (or local machine with --local):

Configuration

~/.oneshot/config.json, created by oneshot init:

{
"host": "user@100.x.x.x",
"basePath": "~/projects",
"provider": "codex",
"routing": { "enabled": true },
"linearApiKey": "lin_api_...",
"claude": {
"model": "opus",
"timeoutMinutes": 180
},
"codex": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh",
"reviewModel": "gpt-5.5",
"reviewReasoningEffort": "xhigh",
"timeoutMinutes": 180
},
"phases": {
"classify": { "model": "gpt-5.5", "reasoningEffort": "medium" },
"plan": { "model": "gpt-5.5", "reasoningEffort": "xhigh" },
"execute": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"review": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"deepReview": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"pr": { "model": "gpt-5.5", "reasoningEffort": "high" }
},
"stepTimeouts": {
"planMinutes": 20,
"executeMinutes": 60,
"reviewMinutes": 20,
"deepReviewMinutes": 20,
"prMinutes": 20
}
}

Only host is required for SSH runs. Local mode works without a config file. Remote SSH runs stream the active oneshot config to the server for that run, so basePath, provider defaults, timeout settings, and configured Linear credentials stay aligned without requiring a duplicate ~/.oneshot/config.json on the server.

KeyRequiredDescription
hostSSH onlySSH target, e.g. user@192.168.1.10
basePathNoWhere repos live. Default: ~/projects
worktreeRootNoScratch directory for temporary git worktrees. Default: /tmp
providerNoFallback agent provider when adaptive routing is off or no route rule wins. Default: codex
routing.enabledNoEnables invisible provider/reasoning routing. Codex and Claude still use their configured frontier model; the router varies provider and effort, not model class
anthropicApiKeyClaude onlyFalls back to ANTHROPIC_API_KEY env var
linearApiKeyNoEnables Linear ticket integration
claude.modelClaude onlyDefault Claude model. Default: opus
codex.modelCodex onlyDefault Codex model. Default: gpt-5.5
codex.reasoningEffortCodex onlyDefault Codex reasoning effort. Default: xhigh
codex.reviewModelCodex onlyDefault for review phases. Default: same as codex.model
codex.reviewReasoningEffortCodex onlyDefault review reasoning effort. Default: same as codex.reasoningEffort
phases.<phase>.modelNoExact model for that phase under the selected provider
phases.<phase>.reasoningEffortNoReasoning effort for that phase, e.g. medium, high, xhigh. Passed to Codex and to Claude via --effort
stepTimeoutsNoPer-step timeout overrides in minutes

phases is optional. If it is omitted, every agent phase uses the selected provider and its default model settings. Any stale phases.<phase>.provider values from older configs are ignored when adaptive routing is off. With routing.enabled: true, oneshot's adaptive router can silently choose Codex or Claude per task while preserving each provider's configured frontier model.

Adaptive routing is intentionally invisible during normal use. Code edits, tests, refactors, PR work, and ship requests route to Codex by default. Tool-heavy operations, browser/admin/log/service work, and external workflow orchestration can route to Claude. If code will be edited, Codex wins the tie. Use oneshot route "<task>" --json only when you want to inspect the decision.

Repos on the server should live as <org>/<repo> under the base path. Repo slugs are intentionally strict: exactly owner/repo, using only letters, numbers, dot, underscore, and hyphen. Nested paths and .. are rejected before any filesystem access.

~/projects/
acme/api/
acme/web/

Linear integration

Pass a Linear URL instead of a task string:

oneshot acme/api https://linear.app/acme/issue/ENG-142
  1. Fetches issue title, description, and comments via GraphQL
  2. Uses ticket as context for the planning step
  3. Uses the issue ID in the branch name (oneshot/eng-142-...)
  4. Moves the ticket to "In Review" and comments the PR URL

Requires linearApiKey in config.

Customization

CLAUDE.md: put one in any repo root. oneshot passes it to the configured agents for planning and execution. Use it for coding standards, architecture decisions, test requirements.

Prompt templates: edit these to change pipeline behavior:

FileControls
prompts/plan.txtHow the plan agent explores and plans
prompts/execute.txtHow the execute agent implements changes
prompts/review.txtHow the review agent reviews the diff
prompts/pr.txtHow the PR agent writes branch/commit/PR metadata

Templates use {{variable}} placeholders replaced at runtime.

The repo's CLAUDE.md is also supplied to the planning and execution steps, so the task string is the primary operator input, not the only context the agents receive.

For dense specs, explainers, review maps, incident reports, design sheets, or one-off editors, the templates allow a self-contained HTML artifact instead of a long markdown document. Durable artifacts should live under docs/artifacts/; throwaway local artifacts should stay under /tmp/oneshot-html-artifacts/.

Events

Every run writes JSONL events to /tmp/oneshot-<runId>.events.jsonl and the durable local ledger at ~/.oneshot/runs/<runId>.events.jsonl. Use --events-file <path> to mirror to another file:

oneshot acme/api "fix bug" --local --events-file /tmp/run.events.jsonl

Events:

  • started (includes runtime metadata such as CLI version, host, pid, cwd, platform, and worktree root), classified, step (running/done/failed), completed (success/failed/dry-run)
  • agent for live agent activity: commands, tools, file changes, todos, web searches, warnings, draft PR creation, and turn/session markers

Workflows, policy, and MCP

Workflow presets wrap a task with a stronger operating mode while keeping the CLI portable:

oneshot workflow list
oneshot acme/api "fix the failing payment test" --workflow fix-ci
oneshot acme/web "review PR feedback and make it shippable" --workflow review

Policy packs live at .oneshot/policy.json. The default pack protects secret-like files and can require repo-specific checks before a draft PR is created:

oneshot policy init

oneshot mcp serve exposes the public engine as MCP tools for agent clients. The server supports running a task, listing runs, reading run status, reading a run receipt, initializing policy, listing workflows, and summarizing eval outcomes.

Receipts

Every run writes a proof-of-work receipt to ~/.oneshot/runs/<runId>.receipt.json. The receipt is the thing that makes fire-and-forget trustworthy: it records what was planned, which contract steps ran and how long they took, the review outcome (passed / timed-out / failed), the policy verdict, the defaults the run had to assume because a detached run cannot ask you, and a derived confidence rating (high only when the run shipped with a clean review and a clean policy gate).

oneshot receipt <run-id># human-readable sitrep
oneshot receipt <run-id> --json # machine-readable
oneshot receipt <run-id> --html > receipt.html # self-contained artifact

Runs without a receipt file (older or remote-only runs) reconstruct a thinner receipt from the event stream; reconstructed successes are capped at medium confidence since the contract verdict cannot be re-derived.

Notifications

So a detached run can ping you when its receipt is ready, add a notify block to ~/.oneshot/config.json. It is backend-agnostic on purpose: wire Slack, Discord, a desktop toast, or anything else yourself. Notification is best effort and never fails a run.

{
"notify": {
"webhook": "https://hooks.example.com/oneshot",
"command": "my-notify-script.sh",
"onSuccess": true,
"onFailure": true
}
}

The webhook receives the receipt summary as a JSON POST. The command runs with the same payload on stdin and in ONESHOT_NOTIFY_STATUS, ONESHOT_NOTIFY_REPO, ONESHOT_NOTIFY_HEADLINE, ONESHOT_NOTIFY_PR_URL, ONESHOT_NOTIFY_RECEIPT, and ONESHOT_NOTIFY_JSON.

GitHub Actions backend

Not everyone has a 24/7 dev box, but every repo has Actions: a durable executor that survives your laptop closing, with a secrets vault, that can open PRs natively. oneshot gha init scaffolds a workflow_dispatch workflow that runs the same contract in CI and uploads the receipt as an artifact.

oneshot gha init # writes .github/workflows/oneshot.yml
oneshot gha init --provider claude # wire the Anthropic key instead of OpenAI
gh workflow run oneshot.yml -f task="fix the login timeout"

It requires one provider API key in the repo's Actions secrets (OPENAI_API_KEY for Codex, ANTHROPIC_API_KEY for Claude); GITHUB_TOKEN is provided automatically and opens the PR. The command prints exactly which secret to add.

Doctor and recovery

oneshot doctor checks the installed package freshness against npm, local prerequisites, config file, recent event stream, SSH reachability, and remote binaries when a remote host is configured. Use oneshot doctor --local --json for machine-readable local checks.

Add --repo <owner/repo> to verify the configured local or remote base path actually contains the checkout before dispatch:

oneshot doctor --repo zkp2p/pay
oneshot doctor --local --repo zkp2p/pay --json

Failed runs preserve the worktree under the configured worktreeRoot and write a failed completed event with the error code and completed step timings. Start with oneshot runs, oneshot status <run-id>, and oneshot eval, then inspect the event file or preserved worktree path printed in the logs.

Agent skill

Works as an Agent Skill in Claude Code, Codex CLI, Cursor, and other compatible agents.

npx skills add ADWilkinson/oneshot-cli

Or via ClawHub:

clawhub install oneshot-ship

Agents pick it up automatically, or call /oneshot-ship directly.

License

MIT

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

oneshot

npmlicensedocs

Fire-and-forget agentic software work. Repo + task in, detached agent run out, reviewed PR plus a proof-of-work receipt ready.

laptop -> server, local worktree, or GitHub Actions -> Codex/Claude -> reviewed PR + receipt

oneshot is a tiny public workflow runtime for agentic software work. It gives coding agents the boring-but-crucial rails they need in the real world: clean worktrees, provider routing, durable logs, policy gates, review loops, PR creation, and a receipt that proves the whole contract actually ran.

It runs over SSH to a dev box, entirely locally with --local, or detached in CI with oneshot gha init.

Why try it

  • Fire and forget: detach a task with --bg (or in CI), close your laptop, get pinged when the receipt is ready.
  • Proof of work: every run writes a receipt (plan, contract steps, review outcome, policy verdict, assumptions, confidence) so you can trust a detached result without re-reading the whole diff. oneshot receipt <run-id> --html.
  • No dirty main branch: every run gets an isolated git worktree, so parallel work is safe.
  • Bring your agent: Codex-first by default, Claude-compatible, with adaptive routing when enabled.
  • Durable anywhere: SSH to your own box, a local detached process, or GitHub Actions for zero-infra runs that survive your machine.
  • Observable by design: every run writes JSONL events plus a durable ledger you can inspect later.
  • Workflow-shaped: use presets like ship, review, fix-ci, research, docs, and swarm-review.
  • Policy-aware: add .oneshot/policy.json for protected paths, secret checks, and required repo gates.
  • Toolable: oneshot mcp serve exposes the same engine to MCP-capable agent clients.

Install

Requires Bun. macOS and Linux.

bun install -g oneshot-ship

Quick start

oneshot init # configure
oneshot doctor # check local + remote setup
oneshot doctor --repo my-org/my-app # verify a checkout target
oneshot my-org/my-app "fix the login timeout"# ship

Try the runtime surface:

oneshot workflow list
oneshot my-org/my-app "fix failing CI" --workflow fix-ci
oneshot runs
oneshot status <run-id|events-file> --json
oneshot eval --json
oneshot mcp serve

How it works

oneshot runs an 8-step pipeline. Each run gets its own git worktree in /tmp, so your main branch is never touched. Parallel runs on the same repo are safe.

StepEngineWhat it does
1. ValidategitChecks the repo exists, fetches latest
2. WorktreegitCreates an isolated /tmp worktree from origin/main
3. RouteAdaptive routerPicks provider, reasoning, context shape, execution style, and fast/deep mode
4. PlanRoutedReads the codebase + repo instructions, outputs an implementation plan
5. ExecuteRoutedImplements the plan
6. Draft PRConfigurableCreates branch, commits, and writes PR metadata; runtime pushes and opens or updates the draft PR
7. ReviewConfigurableReviews the diff across correctness, compatibility, policy, security, and docs. Fixes issues directly
8. Finalizegit/ghPushes review fixes and marks PR ready, or preserves the draft if review fails

If execute times out with partial changes, the draft PR is still created so nothing is lost.

Usage

oneshot <repo>"<task>"# ship a task
oneshot <repo><linear-url># ship from a Linear ticket
oneshot <repo>"<task>" --bg # fire and forget
oneshot <repo>"<task>" --local # run locally, no SSH
oneshot <repo>"<task>" --mode deep # skip classification and force deep mode
oneshot <repo>"<task>" --workflow ship # apply a workflow preset
oneshot <repo>"<task>" --deep-review # force exhaustive review
oneshot <repo>"<task>" --model gpt-5.5 # override configured plan/PR model
oneshot <repo>"<task>" --branch dev # target a different branch
oneshot <repo>"<task>" --base-path /srv/workspaces # override repo root for this run
oneshot <repo>"<task>" --worktree-root /tmp/agents # override temp worktree root
oneshot <repo> --dry-run # validate only
oneshot init # configure
oneshot stats # recent runs + timing
oneshot runs # durable run ledger
oneshot runs --json --limit 10 # list runs for automation
oneshot status <run-id|events-file> --json # inspect one run
oneshot receipt <run-id># proof-of-work receipt (text)
oneshot receipt <run-id> --html # receipt as a self-contained HTML artifact
oneshot eval --json # summarize run outcomes
oneshot doctor # setup and remote health checks
oneshot doctor --repo my-org/my-app # setup + checkout health
oneshot route "fix failing CI and publish" --json # inspect the hidden route
oneshot workflow list # inspect workflow presets
oneshot workflow show fix-ci --json # inspect one workflow preset
oneshot policy init # create .oneshot/policy.json
oneshot policy init --path ./repo # write policy in another directory
oneshot gha init # scaffold a GitHub Actions workflow for detached runs
oneshot mcp serve # expose oneshot as MCP tools

Flags

FlagShortDescription
--model-mOverride configured plan/PR model
--branch-bBase branch (default: main)
--base-pathOverride the workspace path used to locate the repo
--worktree-rootOverride where temporary git worktrees are created
--modeSkip classification and force fast or deep mode
--workflowApply a workflow preset: ship, review, fix-ci, research, docs, or swarm-review
--deep-reviewForce exhaustive review mode
--localRun locally instead of over SSH
--bgRun detached in background (returns PID + log path)
--dry-run-dValidate only
--events-fileMirror JSONL events to an additional file
--repoWith doctor, verify a specific owner/repo checkout exists
--providerWith route, choose the fallback provider (codex or claude)

Prerequisites

On your laptop:Bun, SSH access to your server

On your server (or local machine with --local):

Configuration

~/.oneshot/config.json, created by oneshot init:

{
"host": "user@100.x.x.x",
"basePath": "~/projects",
"provider": "codex",
"routing": { "enabled": true },
"linearApiKey": "lin_api_...",
"claude": {
"model": "opus",
"timeoutMinutes": 180
},
"codex": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh",
"reviewModel": "gpt-5.5",
"reviewReasoningEffort": "xhigh",
"timeoutMinutes": 180
},
"phases": {
"classify": { "model": "gpt-5.5", "reasoningEffort": "medium" },
"plan": { "model": "gpt-5.5", "reasoningEffort": "xhigh" },
"execute": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"review": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"deepReview": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"pr": { "model": "gpt-5.5", "reasoningEffort": "high" }
},
"stepTimeouts": {
"planMinutes": 20,
"executeMinutes": 60,
"reviewMinutes": 20,
"deepReviewMinutes": 20,
"prMinutes": 20
}
}

Only host is required for SSH runs. Local mode works without a config file. Remote SSH runs stream the active oneshot config to the server for that run, so basePath, provider defaults, timeout settings, and configured Linear credentials stay aligned without requiring a duplicate ~/.oneshot/config.json on the server.

KeyRequiredDescription
hostSSH onlySSH target, e.g. user@192.168.1.10
basePathNoWhere repos live. Default: ~/projects
worktreeRootNoScratch directory for temporary git worktrees. Default: /tmp
providerNoFallback agent provider when adaptive routing is off or no route rule wins. Default: codex
routing.enabledNoEnables invisible provider/reasoning routing. Codex and Claude still use their configured frontier model; the router varies provider and effort, not model class
anthropicApiKeyClaude onlyFalls back to ANTHROPIC_API_KEY env var
linearApiKeyNoEnables Linear ticket integration
claude.modelClaude onlyDefault Claude model. Default: opus
codex.modelCodex onlyDefault Codex model. Default: gpt-5.5
codex.reasoningEffortCodex onlyDefault Codex reasoning effort. Default: xhigh
codex.reviewModelCodex onlyDefault for review phases. Default: same as codex.model
codex.reviewReasoningEffortCodex onlyDefault review reasoning effort. Default: same as codex.reasoningEffort
phases.<phase>.modelNoExact model for that phase under the selected provider
phases.<phase>.reasoningEffortNoReasoning effort for that phase, e.g. medium, high, xhigh. Passed to Codex and to Claude via --effort
stepTimeoutsNoPer-step timeout overrides in minutes

phases is optional. If it is omitted, every agent phase uses the selected provider and its default model settings. Any stale phases.<phase>.provider values from older configs are ignored when adaptive routing is off. With routing.enabled: true, oneshot's adaptive router can silently choose Codex or Claude per task while preserving each provider's configured frontier model.

Adaptive routing is intentionally invisible during normal use. Code edits, tests, refactors, PR work, and ship requests route to Codex by default. Tool-heavy operations, browser/admin/log/service work, and external workflow orchestration can route to Claude. If code will be edited, Codex wins the tie. Use oneshot route "<task>" --json only when you want to inspect the decision.

Repos on the server should live as <org>/<repo> under the base path. Repo slugs are intentionally strict: exactly owner/repo, using only letters, numbers, dot, underscore, and hyphen. Nested paths and .. are rejected before any filesystem access.

~/projects/
acme/api/
acme/web/

Linear integration

Pass a Linear URL instead of a task string:

oneshot acme/api https://linear.app/acme/issue/ENG-142
  1. Fetches issue title, description, and comments via GraphQL
  2. Uses ticket as context for the planning step
  3. Uses the issue ID in the branch name (oneshot/eng-142-...)
  4. Moves the ticket to "In Review" and comments the PR URL

Requires linearApiKey in config.

Customization

CLAUDE.md: put one in any repo root. oneshot passes it to the configured agents for planning and execution. Use it for coding standards, architecture decisions, test requirements.

Prompt templates: edit these to change pipeline behavior:

FileControls
prompts/plan.txtHow the plan agent explores and plans
prompts/execute.txtHow the execute agent implements changes
prompts/review.txtHow the review agent reviews the diff
prompts/pr.txtHow the PR agent writes branch/commit/PR metadata

Templates use {{variable}} placeholders replaced at runtime.

The repo's CLAUDE.md is also supplied to the planning and execution steps, so the task string is the primary operator input, not the only context the agents receive.

For dense specs, explainers, review maps, incident reports, design sheets, or one-off editors, the templates allow a self-contained HTML artifact instead of a long markdown document. Durable artifacts should live under docs/artifacts/; throwaway local artifacts should stay under /tmp/oneshot-html-artifacts/.

Events

Every run writes JSONL events to /tmp/oneshot-<runId>.events.jsonl and the durable local ledger at ~/.oneshot/runs/<runId>.events.jsonl. Use --events-file <path> to mirror to another file:

oneshot acme/api "fix bug" --local --events-file /tmp/run.events.jsonl

Events:

  • started (includes runtime metadata such as CLI version, host, pid, cwd, platform, and worktree root), classified, step (running/done/failed), completed (success/failed/dry-run)
  • agent for live agent activity: commands, tools, file changes, todos, web searches, warnings, draft PR creation, and turn/session markers

Workflows, policy, and MCP

Workflow presets wrap a task with a stronger operating mode while keeping the CLI portable:

oneshot workflow list
oneshot acme/api "fix the failing payment test" --workflow fix-ci
oneshot acme/web "review PR feedback and make it shippable" --workflow review

Policy packs live at .oneshot/policy.json. The default pack protects secret-like files and can require repo-specific checks before a draft PR is created:

oneshot policy init

oneshot mcp serve exposes the public engine as MCP tools for agent clients. The server supports running a task, listing runs, reading run status, reading a run receipt, initializing policy, listing workflows, and summarizing eval outcomes.

Receipts

Every run writes a proof-of-work receipt to ~/.oneshot/runs/<runId>.receipt.json. The receipt is the thing that makes fire-and-forget trustworthy: it records what was planned, which contract steps ran and how long they took, the review outcome (passed / timed-out / failed), the policy verdict, the defaults the run had to assume because a detached run cannot ask you, and a derived confidence rating (high only when the run shipped with a clean review and a clean policy gate).

oneshot receipt <run-id># human-readable sitrep
oneshot receipt <run-id> --json # machine-readable
oneshot receipt <run-id> --html > receipt.html # self-contained artifact

Runs without a receipt file (older or remote-only runs) reconstruct a thinner receipt from the event stream; reconstructed successes are capped at medium confidence since the contract verdict cannot be re-derived.

Notifications

So a detached run can ping you when its receipt is ready, add a notify block to ~/.oneshot/config.json. It is backend-agnostic on purpose: wire Slack, Discord, a desktop toast, or anything else yourself. Notification is best effort and never fails a run.

{
"notify": {
"webhook": "https://hooks.example.com/oneshot",
"command": "my-notify-script.sh",
"onSuccess": true,
"onFailure": true
}
}

The webhook receives the receipt summary as a JSON POST. The command runs with the same payload on stdin and in ONESHOT_NOTIFY_STATUS, ONESHOT_NOTIFY_REPO, ONESHOT_NOTIFY_HEADLINE, ONESHOT_NOTIFY_PR_URL, ONESHOT_NOTIFY_RECEIPT, and ONESHOT_NOTIFY_JSON.

GitHub Actions backend

Not everyone has a 24/7 dev box, but every repo has Actions: a durable executor that survives your laptop closing, with a secrets vault, that can open PRs natively. oneshot gha init scaffolds a workflow_dispatch workflow that runs the same contract in CI and uploads the receipt as an artifact.

oneshot gha init # writes .github/workflows/oneshot.yml
oneshot gha init --provider claude # wire the Anthropic key instead of OpenAI
gh workflow run oneshot.yml -f task="fix the login timeout"

It requires one provider API key in the repo's Actions secrets (OPENAI_API_KEY for Codex, ANTHROPIC_API_KEY for Claude); GITHUB_TOKEN is provided automatically and opens the PR. The command prints exactly which secret to add.

Doctor and recovery

oneshot doctor checks the installed package freshness against npm, local prerequisites, config file, recent event stream, SSH reachability, and remote binaries when a remote host is configured. Use oneshot doctor --local --json for machine-readable local checks.

Add --repo <owner/repo> to verify the configured local or remote base path actually contains the checkout before dispatch:

oneshot doctor --repo zkp2p/pay
oneshot doctor --local --repo zkp2p/pay --json

Failed runs preserve the worktree under the configured worktreeRoot and write a failed completed event with the error code and completed step timings. Start with oneshot runs, oneshot status <run-id>, and oneshot eval, then inspect the event file or preserved worktree path printed in the logs.

Agent skill

Works as an Agent Skill in Claude Code, Codex CLI, Cursor, and other compatible agents.

npx skills add ADWilkinson/oneshot-cli

Or via ClawHub:

clawhub install oneshot-ship

Agents pick it up automatically, or call /oneshot-ship directly.

License

MIT

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

oneshot

npmlicensedocs

Fire-and-forget agentic software work. Repo + task in, detached agent run out, reviewed PR plus a proof-of-work receipt ready.

laptop -> server, local worktree, or GitHub Actions -> Codex/Claude -> reviewed PR + receipt

oneshot is a tiny public workflow runtime for agentic software work. It gives coding agents the boring-but-crucial rails they need in the real world: clean worktrees, provider routing, durable logs, policy gates, review loops, PR creation, and a receipt that proves the whole contract actually ran.

It runs over SSH to a dev box, entirely locally with --local, or detached in CI with oneshot gha init.

Why try it

  • Fire and forget: detach a task with --bg (or in CI), close your laptop, get pinged when the receipt is ready.
  • Proof of work: every run writes a receipt (plan, contract steps, review outcome, policy verdict, assumptions, confidence) so you can trust a detached result without re-reading the whole diff. oneshot receipt <run-id> --html.
  • No dirty main branch: every run gets an isolated git worktree, so parallel work is safe.
  • Bring your agent: Codex-first by default, Claude-compatible, with adaptive routing when enabled.
  • Durable anywhere: SSH to your own box, a local detached process, or GitHub Actions for zero-infra runs that survive your machine.
  • Observable by design: every run writes JSONL events plus a durable ledger you can inspect later.
  • Workflow-shaped: use presets like ship, review, fix-ci, research, docs, and swarm-review.
  • Policy-aware: add .oneshot/policy.json for protected paths, secret checks, and required repo gates.
  • Toolable: oneshot mcp serve exposes the same engine to MCP-capable agent clients.

Install

Requires Bun. macOS and Linux.

bun install -g oneshot-ship

Quick start

oneshot init # configure
oneshot doctor # check local + remote setup
oneshot doctor --repo my-org/my-app # verify a checkout target
oneshot my-org/my-app "fix the login timeout"# ship

Try the runtime surface:

oneshot workflow list
oneshot my-org/my-app "fix failing CI" --workflow fix-ci
oneshot runs
oneshot status <run-id|events-file> --json
oneshot eval --json
oneshot mcp serve

How it works

oneshot runs an 8-step pipeline. Each run gets its own git worktree in /tmp, so your main branch is never touched. Parallel runs on the same repo are safe.

StepEngineWhat it does
1. ValidategitChecks the repo exists, fetches latest
2. WorktreegitCreates an isolated /tmp worktree from origin/main
3. RouteAdaptive routerPicks provider, reasoning, context shape, execution style, and fast/deep mode
4. PlanRoutedReads the codebase + repo instructions, outputs an implementation plan
5. ExecuteRoutedImplements the plan
6. Draft PRConfigurableCreates branch, commits, and writes PR metadata; runtime pushes and opens or updates the draft PR
7. ReviewConfigurableReviews the diff across correctness, compatibility, policy, security, and docs. Fixes issues directly
8. Finalizegit/ghPushes review fixes and marks PR ready, or preserves the draft if review fails

If execute times out with partial changes, the draft PR is still created so nothing is lost.

Usage

oneshot <repo>"<task>"# ship a task
oneshot <repo><linear-url># ship from a Linear ticket
oneshot <repo>"<task>" --bg # fire and forget
oneshot <repo>"<task>" --local # run locally, no SSH
oneshot <repo>"<task>" --mode deep # skip classification and force deep mode
oneshot <repo>"<task>" --workflow ship # apply a workflow preset
oneshot <repo>"<task>" --deep-review # force exhaustive review
oneshot <repo>"<task>" --model gpt-5.5 # override configured plan/PR model
oneshot <repo>"<task>" --branch dev # target a different branch
oneshot <repo>"<task>" --base-path /srv/workspaces # override repo root for this run
oneshot <repo>"<task>" --worktree-root /tmp/agents # override temp worktree root
oneshot <repo> --dry-run # validate only
oneshot init # configure
oneshot stats # recent runs + timing
oneshot runs # durable run ledger
oneshot runs --json --limit 10 # list runs for automation
oneshot status <run-id|events-file> --json # inspect one run
oneshot receipt <run-id># proof-of-work receipt (text)
oneshot receipt <run-id> --html # receipt as a self-contained HTML artifact
oneshot eval --json # summarize run outcomes
oneshot doctor # setup and remote health checks
oneshot doctor --repo my-org/my-app # setup + checkout health
oneshot route "fix failing CI and publish" --json # inspect the hidden route
oneshot workflow list # inspect workflow presets
oneshot workflow show fix-ci --json # inspect one workflow preset
oneshot policy init # create .oneshot/policy.json
oneshot policy init --path ./repo # write policy in another directory
oneshot gha init # scaffold a GitHub Actions workflow for detached runs
oneshot mcp serve # expose oneshot as MCP tools

Flags

FlagShortDescription
--model-mOverride configured plan/PR model
--branch-bBase branch (default: main)
--base-pathOverride the workspace path used to locate the repo
--worktree-rootOverride where temporary git worktrees are created
--modeSkip classification and force fast or deep mode
--workflowApply a workflow preset: ship, review, fix-ci, research, docs, or swarm-review
--deep-reviewForce exhaustive review mode
--localRun locally instead of over SSH
--bgRun detached in background (returns PID + log path)
--dry-run-dValidate only
--events-fileMirror JSONL events to an additional file
--repoWith doctor, verify a specific owner/repo checkout exists
--providerWith route, choose the fallback provider (codex or claude)

Prerequisites

On your laptop:Bun, SSH access to your server

On your server (or local machine with --local):

Configuration

~/.oneshot/config.json, created by oneshot init:

{
"host": "user@100.x.x.x",
"basePath": "~/projects",
"provider": "codex",
"routing": { "enabled": true },
"linearApiKey": "lin_api_...",
"claude": {
"model": "opus",
"timeoutMinutes": 180
},
"codex": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh",
"reviewModel": "gpt-5.5",
"reviewReasoningEffort": "xhigh",
"timeoutMinutes": 180
},
"phases": {
"classify": { "model": "gpt-5.5", "reasoningEffort": "medium" },
"plan": { "model": "gpt-5.5", "reasoningEffort": "xhigh" },
"execute": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"review": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"deepReview": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"pr": { "model": "gpt-5.5", "reasoningEffort": "high" }
},
"stepTimeouts": {
"planMinutes": 20,
"executeMinutes": 60,
"reviewMinutes": 20,
"deepReviewMinutes": 20,
"prMinutes": 20
}
}

Only host is required for SSH runs. Local mode works without a config file. Remote SSH runs stream the active oneshot config to the server for that run, so basePath, provider defaults, timeout settings, and configured Linear credentials stay aligned without requiring a duplicate ~/.oneshot/config.json on the server.

KeyRequiredDescription
hostSSH onlySSH target, e.g. user@192.168.1.10
basePathNoWhere repos live. Default: ~/projects
worktreeRootNoScratch directory for temporary git worktrees. Default: /tmp
providerNoFallback agent provider when adaptive routing is off or no route rule wins. Default: codex
routing.enabledNoEnables invisible provider/reasoning routing. Codex and Claude still use their configured frontier model; the router varies provider and effort, not model class
anthropicApiKeyClaude onlyFalls back to ANTHROPIC_API_KEY env var
linearApiKeyNoEnables Linear ticket integration
claude.modelClaude onlyDefault Claude model. Default: opus
codex.modelCodex onlyDefault Codex model. Default: gpt-5.5
codex.reasoningEffortCodex onlyDefault Codex reasoning effort. Default: xhigh
codex.reviewModelCodex onlyDefault for review phases. Default: same as codex.model
codex.reviewReasoningEffortCodex onlyDefault review reasoning effort. Default: same as codex.reasoningEffort
phases.<phase>.modelNoExact model for that phase under the selected provider
phases.<phase>.reasoningEffortNoReasoning effort for that phase, e.g. medium, high, xhigh. Passed to Codex and to Claude via --effort
stepTimeoutsNoPer-step timeout overrides in minutes

phases is optional. If it is omitted, every agent phase uses the selected provider and its default model settings. Any stale phases.<phase>.provider values from older configs are ignored when adaptive routing is off. With routing.enabled: true, oneshot's adaptive router can silently choose Codex or Claude per task while preserving each provider's configured frontier model.

Adaptive routing is intentionally invisible during normal use. Code edits, tests, refactors, PR work, and ship requests route to Codex by default. Tool-heavy operations, browser/admin/log/service work, and external workflow orchestration can route to Claude. If code will be edited, Codex wins the tie. Use oneshot route "<task>" --json only when you want to inspect the decision.

Repos on the server should live as <org>/<repo> under the base path. Repo slugs are intentionally strict: exactly owner/repo, using only letters, numbers, dot, underscore, and hyphen. Nested paths and .. are rejected before any filesystem access.

~/projects/
acme/api/
acme/web/

Linear integration

Pass a Linear URL instead of a task string:

oneshot acme/api https://linear.app/acme/issue/ENG-142
  1. Fetches issue title, description, and comments via GraphQL
  2. Uses ticket as context for the planning step
  3. Uses the issue ID in the branch name (oneshot/eng-142-...)
  4. Moves the ticket to "In Review" and comments the PR URL

Requires linearApiKey in config.

Customization

CLAUDE.md: put one in any repo root. oneshot passes it to the configured agents for planning and execution. Use it for coding standards, architecture decisions, test requirements.

Prompt templates: edit these to change pipeline behavior:

FileControls
prompts/plan.txtHow the plan agent explores and plans
prompts/execute.txtHow the execute agent implements changes
prompts/review.txtHow the review agent reviews the diff
prompts/pr.txtHow the PR agent writes branch/commit/PR metadata

Templates use {{variable}} placeholders replaced at runtime.

The repo's CLAUDE.md is also supplied to the planning and execution steps, so the task string is the primary operator input, not the only context the agents receive.

For dense specs, explainers, review maps, incident reports, design sheets, or one-off editors, the templates allow a self-contained HTML artifact instead of a long markdown document. Durable artifacts should live under docs/artifacts/; throwaway local artifacts should stay under /tmp/oneshot-html-artifacts/.

Events

Every run writes JSONL events to /tmp/oneshot-<runId>.events.jsonl and the durable local ledger at ~/.oneshot/runs/<runId>.events.jsonl. Use --events-file <path> to mirror to another file:

oneshot acme/api "fix bug" --local --events-file /tmp/run.events.jsonl

Events:

  • started (includes runtime metadata such as CLI version, host, pid, cwd, platform, and worktree root), classified, step (running/done/failed), completed (success/failed/dry-run)
  • agent for live agent activity: commands, tools, file changes, todos, web searches, warnings, draft PR creation, and turn/session markers

Workflows, policy, and MCP

Workflow presets wrap a task with a stronger operating mode while keeping the CLI portable:

oneshot workflow list
oneshot acme/api "fix the failing payment test" --workflow fix-ci
oneshot acme/web "review PR feedback and make it shippable" --workflow review

Policy packs live at .oneshot/policy.json. The default pack protects secret-like files and can require repo-specific checks before a draft PR is created:

oneshot policy init

oneshot mcp serve exposes the public engine as MCP tools for agent clients. The server supports running a task, listing runs, reading run status, reading a run receipt, initializing policy, listing workflows, and summarizing eval outcomes.

Receipts

Every run writes a proof-of-work receipt to ~/.oneshot/runs/<runId>.receipt.json. The receipt is the thing that makes fire-and-forget trustworthy: it records what was planned, which contract steps ran and how long they took, the review outcome (passed / timed-out / failed), the policy verdict, the defaults the run had to assume because a detached run cannot ask you, and a derived confidence rating (high only when the run shipped with a clean review and a clean policy gate).

oneshot receipt <run-id># human-readable sitrep
oneshot receipt <run-id> --json # machine-readable
oneshot receipt <run-id> --html > receipt.html # self-contained artifact

Runs without a receipt file (older or remote-only runs) reconstruct a thinner receipt from the event stream; reconstructed successes are capped at medium confidence since the contract verdict cannot be re-derived.

Notifications

So a detached run can ping you when its receipt is ready, add a notify block to ~/.oneshot/config.json. It is backend-agnostic on purpose: wire Slack, Discord, a desktop toast, or anything else yourself. Notification is best effort and never fails a run.

{
"notify": {
"webhook": "https://hooks.example.com/oneshot",
"command": "my-notify-script.sh",
"onSuccess": true,
"onFailure": true
}
}

The webhook receives the receipt summary as a JSON POST. The command runs with the same payload on stdin and in ONESHOT_NOTIFY_STATUS, ONESHOT_NOTIFY_REPO, ONESHOT_NOTIFY_HEADLINE, ONESHOT_NOTIFY_PR_URL, ONESHOT_NOTIFY_RECEIPT, and ONESHOT_NOTIFY_JSON.

GitHub Actions backend

Not everyone has a 24/7 dev box, but every repo has Actions: a durable executor that survives your laptop closing, with a secrets vault, that can open PRs natively. oneshot gha init scaffolds a workflow_dispatch workflow that runs the same contract in CI and uploads the receipt as an artifact.

oneshot gha init # writes .github/workflows/oneshot.yml
oneshot gha init --provider claude # wire the Anthropic key instead of OpenAI
gh workflow run oneshot.yml -f task="fix the login timeout"

It requires one provider API key in the repo's Actions secrets (OPENAI_API_KEY for Codex, ANTHROPIC_API_KEY for Claude); GITHUB_TOKEN is provided automatically and opens the PR. The command prints exactly which secret to add.

Doctor and recovery

oneshot doctor checks the installed package freshness against npm, local prerequisites, config file, recent event stream, SSH reachability, and remote binaries when a remote host is configured. Use oneshot doctor --local --json for machine-readable local checks.

Add --repo <owner/repo> to verify the configured local or remote base path actually contains the checkout before dispatch:

oneshot doctor --repo zkp2p/pay
oneshot doctor --local --repo zkp2p/pay --json

Failed runs preserve the worktree under the configured worktreeRoot and write a failed completed event with the error code and completed step timings. Start with oneshot runs, oneshot status <run-id>, and oneshot eval, then inspect the event file or preserved worktree path printed in the logs.

Agent skill

Works as an Agent Skill in Claude Code, Codex CLI, Cursor, and other compatible agents.

npx skills add ADWilkinson/oneshot-cli

Or via ClawHub:

clawhub install oneshot-ship

Agents pick it up automatically, or call /oneshot-ship directly.

License

MIT

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

oneshot

npmlicensedocs

Fire-and-forget agentic software work. Repo + task in, detached agent run out, reviewed PR plus a proof-of-work receipt ready.

laptop -> server, local worktree, or GitHub Actions -> Codex/Claude -> reviewed PR + receipt

oneshot is a tiny public workflow runtime for agentic software work. It gives coding agents the boring-but-crucial rails they need in the real world: clean worktrees, provider routing, durable logs, policy gates, review loops, PR creation, and a receipt that proves the whole contract actually ran.

It runs over SSH to a dev box, entirely locally with --local, or detached in CI with oneshot gha init.

Why try it

  • Fire and forget: detach a task with --bg (or in CI), close your laptop, get pinged when the receipt is ready.
  • Proof of work: every run writes a receipt (plan, contract steps, review outcome, policy verdict, assumptions, confidence) so you can trust a detached result without re-reading the whole diff. oneshot receipt <run-id> --html.
  • No dirty main branch: every run gets an isolated git worktree, so parallel work is safe.
  • Bring your agent: Codex-first by default, Claude-compatible, with adaptive routing when enabled.
  • Durable anywhere: SSH to your own box, a local detached process, or GitHub Actions for zero-infra runs that survive your machine.
  • Observable by design: every run writes JSONL events plus a durable ledger you can inspect later.
  • Workflow-shaped: use presets like ship, review, fix-ci, research, docs, and swarm-review.
  • Policy-aware: add .oneshot/policy.json for protected paths, secret checks, and required repo gates.
  • Toolable: oneshot mcp serve exposes the same engine to MCP-capable agent clients.

Install

Requires Bun. macOS and Linux.

bun install -g oneshot-ship

Quick start

oneshot init # configure
oneshot doctor # check local + remote setup
oneshot doctor --repo my-org/my-app # verify a checkout target
oneshot my-org/my-app "fix the login timeout"# ship

Try the runtime surface:

oneshot workflow list
oneshot my-org/my-app "fix failing CI" --workflow fix-ci
oneshot runs
oneshot status <run-id|events-file> --json
oneshot eval --json
oneshot mcp serve

How it works

oneshot runs an 8-step pipeline. Each run gets its own git worktree in /tmp, so your main branch is never touched. Parallel runs on the same repo are safe.

StepEngineWhat it does
1. ValidategitChecks the repo exists, fetches latest
2. WorktreegitCreates an isolated /tmp worktree from origin/main
3. RouteAdaptive routerPicks provider, reasoning, context shape, execution style, and fast/deep mode
4. PlanRoutedReads the codebase + repo instructions, outputs an implementation plan
5. ExecuteRoutedImplements the plan
6. Draft PRConfigurableCreates branch, commits, and writes PR metadata; runtime pushes and opens or updates the draft PR
7. ReviewConfigurableReviews the diff across correctness, compatibility, policy, security, and docs. Fixes issues directly
8. Finalizegit/ghPushes review fixes and marks PR ready, or preserves the draft if review fails

If execute times out with partial changes, the draft PR is still created so nothing is lost.

Usage

oneshot <repo>"<task>"# ship a task
oneshot <repo><linear-url># ship from a Linear ticket
oneshot <repo>"<task>" --bg # fire and forget
oneshot <repo>"<task>" --local # run locally, no SSH
oneshot <repo>"<task>" --mode deep # skip classification and force deep mode
oneshot <repo>"<task>" --workflow ship # apply a workflow preset
oneshot <repo>"<task>" --deep-review # force exhaustive review
oneshot <repo>"<task>" --model gpt-5.5 # override configured plan/PR model
oneshot <repo>"<task>" --branch dev # target a different branch
oneshot <repo>"<task>" --base-path /srv/workspaces # override repo root for this run
oneshot <repo>"<task>" --worktree-root /tmp/agents # override temp worktree root
oneshot <repo> --dry-run # validate only
oneshot init # configure
oneshot stats # recent runs + timing
oneshot runs # durable run ledger
oneshot runs --json --limit 10 # list runs for automation
oneshot status <run-id|events-file> --json # inspect one run
oneshot receipt <run-id># proof-of-work receipt (text)
oneshot receipt <run-id> --html # receipt as a self-contained HTML artifact
oneshot eval --json # summarize run outcomes
oneshot doctor # setup and remote health checks
oneshot doctor --repo my-org/my-app # setup + checkout health
oneshot route "fix failing CI and publish" --json # inspect the hidden route
oneshot workflow list # inspect workflow presets
oneshot workflow show fix-ci --json # inspect one workflow preset
oneshot policy init # create .oneshot/policy.json
oneshot policy init --path ./repo # write policy in another directory
oneshot gha init # scaffold a GitHub Actions workflow for detached runs
oneshot mcp serve # expose oneshot as MCP tools

Flags

FlagShortDescription
--model-mOverride configured plan/PR model
--branch-bBase branch (default: main)
--base-pathOverride the workspace path used to locate the repo
--worktree-rootOverride where temporary git worktrees are created
--modeSkip classification and force fast or deep mode
--workflowApply a workflow preset: ship, review, fix-ci, research, docs, or swarm-review
--deep-reviewForce exhaustive review mode
--localRun locally instead of over SSH
--bgRun detached in background (returns PID + log path)
--dry-run-dValidate only
--events-fileMirror JSONL events to an additional file
--repoWith doctor, verify a specific owner/repo checkout exists
--providerWith route, choose the fallback provider (codex or claude)

Prerequisites

On your laptop:Bun, SSH access to your server

On your server (or local machine with --local):

Configuration

~/.oneshot/config.json, created by oneshot init:

{
"host": "user@100.x.x.x",
"basePath": "~/projects",
"provider": "codex",
"routing": { "enabled": true },
"linearApiKey": "lin_api_...",
"claude": {
"model": "opus",
"timeoutMinutes": 180
},
"codex": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh",
"reviewModel": "gpt-5.5",
"reviewReasoningEffort": "xhigh",
"timeoutMinutes": 180
},
"phases": {
"classify": { "model": "gpt-5.5", "reasoningEffort": "medium" },
"plan": { "model": "gpt-5.5", "reasoningEffort": "xhigh" },
"execute": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"review": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"deepReview": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"pr": { "model": "gpt-5.5", "reasoningEffort": "high" }
},
"stepTimeouts": {
"planMinutes": 20,
"executeMinutes": 60,
"reviewMinutes": 20,
"deepReviewMinutes": 20,
"prMinutes": 20
}
}

Only host is required for SSH runs. Local mode works without a config file. Remote SSH runs stream the active oneshot config to the server for that run, so basePath, provider defaults, timeout settings, and configured Linear credentials stay aligned without requiring a duplicate ~/.oneshot/config.json on the server.

KeyRequiredDescription
hostSSH onlySSH target, e.g. user@192.168.1.10
basePathNoWhere repos live. Default: ~/projects
worktreeRootNoScratch directory for temporary git worktrees. Default: /tmp
providerNoFallback agent provider when adaptive routing is off or no route rule wins. Default: codex
routing.enabledNoEnables invisible provider/reasoning routing. Codex and Claude still use their configured frontier model; the router varies provider and effort, not model class
anthropicApiKeyClaude onlyFalls back to ANTHROPIC_API_KEY env var
linearApiKeyNoEnables Linear ticket integration
claude.modelClaude onlyDefault Claude model. Default: opus
codex.modelCodex onlyDefault Codex model. Default: gpt-5.5
codex.reasoningEffortCodex onlyDefault Codex reasoning effort. Default: xhigh
codex.reviewModelCodex onlyDefault for review phases. Default: same as codex.model
codex.reviewReasoningEffortCodex onlyDefault review reasoning effort. Default: same as codex.reasoningEffort
phases.<phase>.modelNoExact model for that phase under the selected provider
phases.<phase>.reasoningEffortNoReasoning effort for that phase, e.g. medium, high, xhigh. Passed to Codex and to Claude via --effort
stepTimeoutsNoPer-step timeout overrides in minutes

phases is optional. If it is omitted, every agent phase uses the selected provider and its default model settings. Any stale phases.<phase>.provider values from older configs are ignored when adaptive routing is off. With routing.enabled: true, oneshot's adaptive router can silently choose Codex or Claude per task while preserving each provider's configured frontier model.

Adaptive routing is intentionally invisible during normal use. Code edits, tests, refactors, PR work, and ship requests route to Codex by default. Tool-heavy operations, browser/admin/log/service work, and external workflow orchestration can route to Claude. If code will be edited, Codex wins the tie. Use oneshot route "<task>" --json only when you want to inspect the decision.

Repos on the server should live as <org>/<repo> under the base path. Repo slugs are intentionally strict: exactly owner/repo, using only letters, numbers, dot, underscore, and hyphen. Nested paths and .. are rejected before any filesystem access.

~/projects/
acme/api/
acme/web/

Linear integration

Pass a Linear URL instead of a task string:

oneshot acme/api https://linear.app/acme/issue/ENG-142
  1. Fetches issue title, description, and comments via GraphQL
  2. Uses ticket as context for the planning step
  3. Uses the issue ID in the branch name (oneshot/eng-142-...)
  4. Moves the ticket to "In Review" and comments the PR URL

Requires linearApiKey in config.

Customization

CLAUDE.md: put one in any repo root. oneshot passes it to the configured agents for planning and execution. Use it for coding standards, architecture decisions, test requirements.

Prompt templates: edit these to change pipeline behavior:

FileControls
prompts/plan.txtHow the plan agent explores and plans
prompts/execute.txtHow the execute agent implements changes
prompts/review.txtHow the review agent reviews the diff
prompts/pr.txtHow the PR agent writes branch/commit/PR metadata

Templates use {{variable}} placeholders replaced at runtime.

The repo's CLAUDE.md is also supplied to the planning and execution steps, so the task string is the primary operator input, not the only context the agents receive.

For dense specs, explainers, review maps, incident reports, design sheets, or one-off editors, the templates allow a self-contained HTML artifact instead of a long markdown document. Durable artifacts should live under docs/artifacts/; throwaway local artifacts should stay under /tmp/oneshot-html-artifacts/.

Events

Every run writes JSONL events to /tmp/oneshot-<runId>.events.jsonl and the durable local ledger at ~/.oneshot/runs/<runId>.events.jsonl. Use --events-file <path> to mirror to another file:

oneshot acme/api "fix bug" --local --events-file /tmp/run.events.jsonl

Events:

  • started (includes runtime metadata such as CLI version, host, pid, cwd, platform, and worktree root), classified, step (running/done/failed), completed (success/failed/dry-run)
  • agent for live agent activity: commands, tools, file changes, todos, web searches, warnings, draft PR creation, and turn/session markers

Workflows, policy, and MCP

Workflow presets wrap a task with a stronger operating mode while keeping the CLI portable:

oneshot workflow list
oneshot acme/api "fix the failing payment test" --workflow fix-ci
oneshot acme/web "review PR feedback and make it shippable" --workflow review

Policy packs live at .oneshot/policy.json. The default pack protects secret-like files and can require repo-specific checks before a draft PR is created:

oneshot policy init

oneshot mcp serve exposes the public engine as MCP tools for agent clients. The server supports running a task, listing runs, reading run status, reading a run receipt, initializing policy, listing workflows, and summarizing eval outcomes.

Receipts

Every run writes a proof-of-work receipt to ~/.oneshot/runs/<runId>.receipt.json. The receipt is the thing that makes fire-and-forget trustworthy: it records what was planned, which contract steps ran and how long they took, the review outcome (passed / timed-out / failed), the policy verdict, the defaults the run had to assume because a detached run cannot ask you, and a derived confidence rating (high only when the run shipped with a clean review and a clean policy gate).

oneshot receipt <run-id># human-readable sitrep
oneshot receipt <run-id> --json # machine-readable
oneshot receipt <run-id> --html > receipt.html # self-contained artifact

Runs without a receipt file (older or remote-only runs) reconstruct a thinner receipt from the event stream; reconstructed successes are capped at medium confidence since the contract verdict cannot be re-derived.

Notifications

So a detached run can ping you when its receipt is ready, add a notify block to ~/.oneshot/config.json. It is backend-agnostic on purpose: wire Slack, Discord, a desktop toast, or anything else yourself. Notification is best effort and never fails a run.

{
"notify": {
"webhook": "https://hooks.example.com/oneshot",
"command": "my-notify-script.sh",
"onSuccess": true,
"onFailure": true
}
}

The webhook receives the receipt summary as a JSON POST. The command runs with the same payload on stdin and in ONESHOT_NOTIFY_STATUS, ONESHOT_NOTIFY_REPO, ONESHOT_NOTIFY_HEADLINE, ONESHOT_NOTIFY_PR_URL, ONESHOT_NOTIFY_RECEIPT, and ONESHOT_NOTIFY_JSON.

GitHub Actions backend

Not everyone has a 24/7 dev box, but every repo has Actions: a durable executor that survives your laptop closing, with a secrets vault, that can open PRs natively. oneshot gha init scaffolds a workflow_dispatch workflow that runs the same contract in CI and uploads the receipt as an artifact.

oneshot gha init # writes .github/workflows/oneshot.yml
oneshot gha init --provider claude # wire the Anthropic key instead of OpenAI
gh workflow run oneshot.yml -f task="fix the login timeout"

It requires one provider API key in the repo's Actions secrets (OPENAI_API_KEY for Codex, ANTHROPIC_API_KEY for Claude); GITHUB_TOKEN is provided automatically and opens the PR. The command prints exactly which secret to add.

Doctor and recovery

oneshot doctor checks the installed package freshness against npm, local prerequisites, config file, recent event stream, SSH reachability, and remote binaries when a remote host is configured. Use oneshot doctor --local --json for machine-readable local checks.

Add --repo <owner/repo> to verify the configured local or remote base path actually contains the checkout before dispatch:

oneshot doctor --repo zkp2p/pay
oneshot doctor --local --repo zkp2p/pay --json

Failed runs preserve the worktree under the configured worktreeRoot and write a failed completed event with the error code and completed step timings. Start with oneshot runs, oneshot status <run-id>, and oneshot eval, then inspect the event file or preserved worktree path printed in the logs.

Agent skill

Works as an Agent Skill in Claude Code, Codex CLI, Cursor, and other compatible agents.

npx skills add ADWilkinson/oneshot-cli

Or via ClawHub:

clawhub install oneshot-ship

Agents pick it up automatically, or call /oneshot-ship directly.

License

MIT

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

oneshot

npmlicensedocs

Fire-and-forget agentic software work. Repo + task in, detached agent run out, reviewed PR plus a proof-of-work receipt ready.

laptop -> server, local worktree, or GitHub Actions -> Codex/Claude -> reviewed PR + receipt

oneshot is a tiny public workflow runtime for agentic software work. It gives coding agents the boring-but-crucial rails they need in the real world: clean worktrees, provider routing, durable logs, policy gates, review loops, PR creation, and a receipt that proves the whole contract actually ran.

It runs over SSH to a dev box, entirely locally with --local, or detached in CI with oneshot gha init.

Why try it

  • Fire and forget: detach a task with --bg (or in CI), close your laptop, get pinged when the receipt is ready.
  • Proof of work: every run writes a receipt (plan, contract steps, review outcome, policy verdict, assumptions, confidence) so you can trust a detached result without re-reading the whole diff. oneshot receipt <run-id> --html.
  • No dirty main branch: every run gets an isolated git worktree, so parallel work is safe.
  • Bring your agent: Codex-first by default, Claude-compatible, with adaptive routing when enabled.
  • Durable anywhere: SSH to your own box, a local detached process, or GitHub Actions for zero-infra runs that survive your machine.
  • Observable by design: every run writes JSONL events plus a durable ledger you can inspect later.
  • Workflow-shaped: use presets like ship, review, fix-ci, research, docs, and swarm-review.
  • Policy-aware: add .oneshot/policy.json for protected paths, secret checks, and required repo gates.
  • Toolable: oneshot mcp serve exposes the same engine to MCP-capable agent clients.

Install

Requires Bun. macOS and Linux.

bun install -g oneshot-ship

Quick start

oneshot init # configure
oneshot doctor # check local + remote setup
oneshot doctor --repo my-org/my-app # verify a checkout target
oneshot my-org/my-app "fix the login timeout"# ship

Try the runtime surface:

oneshot workflow list
oneshot my-org/my-app "fix failing CI" --workflow fix-ci
oneshot runs
oneshot status <run-id|events-file> --json
oneshot eval --json
oneshot mcp serve

How it works

oneshot runs an 8-step pipeline. Each run gets its own git worktree in /tmp, so your main branch is never touched. Parallel runs on the same repo are safe.

StepEngineWhat it does
1. ValidategitChecks the repo exists, fetches latest
2. WorktreegitCreates an isolated /tmp worktree from origin/main
3. RouteAdaptive routerPicks provider, reasoning, context shape, execution style, and fast/deep mode
4. PlanRoutedReads the codebase + repo instructions, outputs an implementation plan
5. ExecuteRoutedImplements the plan
6. Draft PRConfigurableCreates branch, commits, and writes PR metadata; runtime pushes and opens or updates the draft PR
7. ReviewConfigurableReviews the diff across correctness, compatibility, policy, security, and docs. Fixes issues directly
8. Finalizegit/ghPushes review fixes and marks PR ready, or preserves the draft if review fails

If execute times out with partial changes, the draft PR is still created so nothing is lost.

Usage

oneshot <repo>"<task>"# ship a task
oneshot <repo><linear-url># ship from a Linear ticket
oneshot <repo>"<task>" --bg # fire and forget
oneshot <repo>"<task>" --local # run locally, no SSH
oneshot <repo>"<task>" --mode deep # skip classification and force deep mode
oneshot <repo>"<task>" --workflow ship # apply a workflow preset
oneshot <repo>"<task>" --deep-review # force exhaustive review
oneshot <repo>"<task>" --model gpt-5.5 # override configured plan/PR model
oneshot <repo>"<task>" --branch dev # target a different branch
oneshot <repo>"<task>" --base-path /srv/workspaces # override repo root for this run
oneshot <repo>"<task>" --worktree-root /tmp/agents # override temp worktree root
oneshot <repo> --dry-run # validate only
oneshot init # configure
oneshot stats # recent runs + timing
oneshot runs # durable run ledger
oneshot runs --json --limit 10 # list runs for automation
oneshot status <run-id|events-file> --json # inspect one run
oneshot receipt <run-id># proof-of-work receipt (text)
oneshot receipt <run-id> --html # receipt as a self-contained HTML artifact
oneshot eval --json # summarize run outcomes
oneshot doctor # setup and remote health checks
oneshot doctor --repo my-org/my-app # setup + checkout health
oneshot route "fix failing CI and publish" --json # inspect the hidden route
oneshot workflow list # inspect workflow presets
oneshot workflow show fix-ci --json # inspect one workflow preset
oneshot policy init # create .oneshot/policy.json
oneshot policy init --path ./repo # write policy in another directory
oneshot gha init # scaffold a GitHub Actions workflow for detached runs
oneshot mcp serve # expose oneshot as MCP tools

Flags

FlagShortDescription
--model-mOverride configured plan/PR model
--branch-bBase branch (default: main)
--base-pathOverride the workspace path used to locate the repo
--worktree-rootOverride where temporary git worktrees are created
--modeSkip classification and force fast or deep mode
--workflowApply a workflow preset: ship, review, fix-ci, research, docs, or swarm-review
--deep-reviewForce exhaustive review mode
--localRun locally instead of over SSH
--bgRun detached in background (returns PID + log path)
--dry-run-dValidate only
--events-fileMirror JSONL events to an additional file
--repoWith doctor, verify a specific owner/repo checkout exists
--providerWith route, choose the fallback provider (codex or claude)

Prerequisites

On your laptop:Bun, SSH access to your server

On your server (or local machine with --local):

Configuration

~/.oneshot/config.json, created by oneshot init:

{
"host": "user@100.x.x.x",
"basePath": "~/projects",
"provider": "codex",
"routing": { "enabled": true },
"linearApiKey": "lin_api_...",
"claude": {
"model": "opus",
"timeoutMinutes": 180
},
"codex": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh",
"reviewModel": "gpt-5.5",
"reviewReasoningEffort": "xhigh",
"timeoutMinutes": 180
},
"phases": {
"classify": { "model": "gpt-5.5", "reasoningEffort": "medium" },
"plan": { "model": "gpt-5.5", "reasoningEffort": "xhigh" },
"execute": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"review": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"deepReview": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"pr": { "model": "gpt-5.5", "reasoningEffort": "high" }
},
"stepTimeouts": {
"planMinutes": 20,
"executeMinutes": 60,
"reviewMinutes": 20,
"deepReviewMinutes": 20,
"prMinutes": 20
}
}

Only host is required for SSH runs. Local mode works without a config file. Remote SSH runs stream the active oneshot config to the server for that run, so basePath, provider defaults, timeout settings, and configured Linear credentials stay aligned without requiring a duplicate ~/.oneshot/config.json on the server.

KeyRequiredDescription
hostSSH onlySSH target, e.g. user@192.168.1.10
basePathNoWhere repos live. Default: ~/projects
worktreeRootNoScratch directory for temporary git worktrees. Default: /tmp
providerNoFallback agent provider when adaptive routing is off or no route rule wins. Default: codex
routing.enabledNoEnables invisible provider/reasoning routing. Codex and Claude still use their configured frontier model; the router varies provider and effort, not model class
anthropicApiKeyClaude onlyFalls back to ANTHROPIC_API_KEY env var
linearApiKeyNoEnables Linear ticket integration
claude.modelClaude onlyDefault Claude model. Default: opus
codex.modelCodex onlyDefault Codex model. Default: gpt-5.5
codex.reasoningEffortCodex onlyDefault Codex reasoning effort. Default: xhigh
codex.reviewModelCodex onlyDefault for review phases. Default: same as codex.model
codex.reviewReasoningEffortCodex onlyDefault review reasoning effort. Default: same as codex.reasoningEffort
phases.<phase>.modelNoExact model for that phase under the selected provider
phases.<phase>.reasoningEffortNoReasoning effort for that phase, e.g. medium, high, xhigh. Passed to Codex and to Claude via --effort
stepTimeoutsNoPer-step timeout overrides in minutes

phases is optional. If it is omitted, every agent phase uses the selected provider and its default model settings. Any stale phases.<phase>.provider values from older configs are ignored when adaptive routing is off. With routing.enabled: true, oneshot's adaptive router can silently choose Codex or Claude per task while preserving each provider's configured frontier model.

Adaptive routing is intentionally invisible during normal use. Code edits, tests, refactors, PR work, and ship requests route to Codex by default. Tool-heavy operations, browser/admin/log/service work, and external workflow orchestration can route to Claude. If code will be edited, Codex wins the tie. Use oneshot route "<task>" --json only when you want to inspect the decision.

Repos on the server should live as <org>/<repo> under the base path. Repo slugs are intentionally strict: exactly owner/repo, using only letters, numbers, dot, underscore, and hyphen. Nested paths and .. are rejected before any filesystem access.

~/projects/
acme/api/
acme/web/

Linear integration

Pass a Linear URL instead of a task string:

oneshot acme/api https://linear.app/acme/issue/ENG-142
  1. Fetches issue title, description, and comments via GraphQL
  2. Uses ticket as context for the planning step
  3. Uses the issue ID in the branch name (oneshot/eng-142-...)
  4. Moves the ticket to "In Review" and comments the PR URL

Requires linearApiKey in config.

Customization

CLAUDE.md: put one in any repo root. oneshot passes it to the configured agents for planning and execution. Use it for coding standards, architecture decisions, test requirements.

Prompt templates: edit these to change pipeline behavior:

FileControls
prompts/plan.txtHow the plan agent explores and plans
prompts/execute.txtHow the execute agent implements changes
prompts/review.txtHow the review agent reviews the diff
prompts/pr.txtHow the PR agent writes branch/commit/PR metadata

Templates use {{variable}} placeholders replaced at runtime.

The repo's CLAUDE.md is also supplied to the planning and execution steps, so the task string is the primary operator input, not the only context the agents receive.

For dense specs, explainers, review maps, incident reports, design sheets, or one-off editors, the templates allow a self-contained HTML artifact instead of a long markdown document. Durable artifacts should live under docs/artifacts/; throwaway local artifacts should stay under /tmp/oneshot-html-artifacts/.

Events

Every run writes JSONL events to /tmp/oneshot-<runId>.events.jsonl and the durable local ledger at ~/.oneshot/runs/<runId>.events.jsonl. Use --events-file <path> to mirror to another file:

oneshot acme/api "fix bug" --local --events-file /tmp/run.events.jsonl

Events:

  • started (includes runtime metadata such as CLI version, host, pid, cwd, platform, and worktree root), classified, step (running/done/failed), completed (success/failed/dry-run)
  • agent for live agent activity: commands, tools, file changes, todos, web searches, warnings, draft PR creation, and turn/session markers

Workflows, policy, and MCP

Workflow presets wrap a task with a stronger operating mode while keeping the CLI portable:

oneshot workflow list
oneshot acme/api "fix the failing payment test" --workflow fix-ci
oneshot acme/web "review PR feedback and make it shippable" --workflow review

Policy packs live at .oneshot/policy.json. The default pack protects secret-like files and can require repo-specific checks before a draft PR is created:

oneshot policy init

oneshot mcp serve exposes the public engine as MCP tools for agent clients. The server supports running a task, listing runs, reading run status, reading a run receipt, initializing policy, listing workflows, and summarizing eval outcomes.

Receipts

Every run writes a proof-of-work receipt to ~/.oneshot/runs/<runId>.receipt.json. The receipt is the thing that makes fire-and-forget trustworthy: it records what was planned, which contract steps ran and how long they took, the review outcome (passed / timed-out / failed), the policy verdict, the defaults the run had to assume because a detached run cannot ask you, and a derived confidence rating (high only when the run shipped with a clean review and a clean policy gate).

oneshot receipt <run-id># human-readable sitrep
oneshot receipt <run-id> --json # machine-readable
oneshot receipt <run-id> --html > receipt.html # self-contained artifact

Runs without a receipt file (older or remote-only runs) reconstruct a thinner receipt from the event stream; reconstructed successes are capped at medium confidence since the contract verdict cannot be re-derived.

Notifications

So a detached run can ping you when its receipt is ready, add a notify block to ~/.oneshot/config.json. It is backend-agnostic on purpose: wire Slack, Discord, a desktop toast, or anything else yourself. Notification is best effort and never fails a run.

{
"notify": {
"webhook": "https://hooks.example.com/oneshot",
"command": "my-notify-script.sh",
"onSuccess": true,
"onFailure": true
}
}

The webhook receives the receipt summary as a JSON POST. The command runs with the same payload on stdin and in ONESHOT_NOTIFY_STATUS, ONESHOT_NOTIFY_REPO, ONESHOT_NOTIFY_HEADLINE, ONESHOT_NOTIFY_PR_URL, ONESHOT_NOTIFY_RECEIPT, and ONESHOT_NOTIFY_JSON.

GitHub Actions backend

Not everyone has a 24/7 dev box, but every repo has Actions: a durable executor that survives your laptop closing, with a secrets vault, that can open PRs natively. oneshot gha init scaffolds a workflow_dispatch workflow that runs the same contract in CI and uploads the receipt as an artifact.

oneshot gha init # writes .github/workflows/oneshot.yml
oneshot gha init --provider claude # wire the Anthropic key instead of OpenAI
gh workflow run oneshot.yml -f task="fix the login timeout"

It requires one provider API key in the repo's Actions secrets (OPENAI_API_KEY for Codex, ANTHROPIC_API_KEY for Claude); GITHUB_TOKEN is provided automatically and opens the PR. The command prints exactly which secret to add.

Doctor and recovery

oneshot doctor checks the installed package freshness against npm, local prerequisites, config file, recent event stream, SSH reachability, and remote binaries when a remote host is configured. Use oneshot doctor --local --json for machine-readable local checks.

Add --repo <owner/repo> to verify the configured local or remote base path actually contains the checkout before dispatch:

oneshot doctor --repo zkp2p/pay
oneshot doctor --local --repo zkp2p/pay --json

Failed runs preserve the worktree under the configured worktreeRoot and write a failed completed event with the error code and completed step timings. Start with oneshot runs, oneshot status <run-id>, and oneshot eval, then inspect the event file or preserved worktree path printed in the logs.

Agent skill

Works as an Agent Skill in Claude Code, Codex CLI, Cursor, and other compatible agents.

npx skills add ADWilkinson/oneshot-cli

Or via ClawHub:

clawhub install oneshot-ship

Agents pick it up automatically, or call /oneshot-ship directly.

License

MIT

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

oneshot

npmlicensedocs

Fire-and-forget agentic software work. Repo + task in, detached agent run out, reviewed PR plus a proof-of-work receipt ready.

laptop -> server, local worktree, or GitHub Actions -> Codex/Claude -> reviewed PR + receipt

oneshot is a tiny public workflow runtime for agentic software work. It gives coding agents the boring-but-crucial rails they need in the real world: clean worktrees, provider routing, durable logs, policy gates, review loops, PR creation, and a receipt that proves the whole contract actually ran.

It runs over SSH to a dev box, entirely locally with --local, or detached in CI with oneshot gha init.

Why try it

  • Fire and forget: detach a task with --bg (or in CI), close your laptop, get pinged when the receipt is ready.
  • Proof of work: every run writes a receipt (plan, contract steps, review outcome, policy verdict, assumptions, confidence) so you can trust a detached result without re-reading the whole diff. oneshot receipt <run-id> --html.
  • No dirty main branch: every run gets an isolated git worktree, so parallel work is safe.
  • Bring your agent: Codex-first by default, Claude-compatible, with adaptive routing when enabled.
  • Durable anywhere: SSH to your own box, a local detached process, or GitHub Actions for zero-infra runs that survive your machine.
  • Observable by design: every run writes JSONL events plus a durable ledger you can inspect later.
  • Workflow-shaped: use presets like ship, review, fix-ci, research, docs, and swarm-review.
  • Policy-aware: add .oneshot/policy.json for protected paths, secret checks, and required repo gates.
  • Toolable: oneshot mcp serve exposes the same engine to MCP-capable agent clients.

Install

Requires Bun. macOS and Linux.

bun install -g oneshot-ship

Quick start

oneshot init # configure
oneshot doctor # check local + remote setup
oneshot doctor --repo my-org/my-app # verify a checkout target
oneshot my-org/my-app "fix the login timeout"# ship

Try the runtime surface:

oneshot workflow list
oneshot my-org/my-app "fix failing CI" --workflow fix-ci
oneshot runs
oneshot status <run-id|events-file> --json
oneshot eval --json
oneshot mcp serve

How it works

oneshot runs an 8-step pipeline. Each run gets its own git worktree in /tmp, so your main branch is never touched. Parallel runs on the same repo are safe.

StepEngineWhat it does
1. ValidategitChecks the repo exists, fetches latest
2. WorktreegitCreates an isolated /tmp worktree from origin/main
3. RouteAdaptive routerPicks provider, reasoning, context shape, execution style, and fast/deep mode
4. PlanRoutedReads the codebase + repo instructions, outputs an implementation plan
5. ExecuteRoutedImplements the plan
6. Draft PRConfigurableCreates branch, commits, and writes PR metadata; runtime pushes and opens or updates the draft PR
7. ReviewConfigurableReviews the diff across correctness, compatibility, policy, security, and docs. Fixes issues directly
8. Finalizegit/ghPushes review fixes and marks PR ready, or preserves the draft if review fails

If execute times out with partial changes, the draft PR is still created so nothing is lost.

Usage

oneshot <repo>"<task>"# ship a task
oneshot <repo><linear-url># ship from a Linear ticket
oneshot <repo>"<task>" --bg # fire and forget
oneshot <repo>"<task>" --local # run locally, no SSH
oneshot <repo>"<task>" --mode deep # skip classification and force deep mode
oneshot <repo>"<task>" --workflow ship # apply a workflow preset
oneshot <repo>"<task>" --deep-review # force exhaustive review
oneshot <repo>"<task>" --model gpt-5.5 # override configured plan/PR model
oneshot <repo>"<task>" --branch dev # target a different branch
oneshot <repo>"<task>" --base-path /srv/workspaces # override repo root for this run
oneshot <repo>"<task>" --worktree-root /tmp/agents # override temp worktree root
oneshot <repo> --dry-run # validate only
oneshot init # configure
oneshot stats # recent runs + timing
oneshot runs # durable run ledger
oneshot runs --json --limit 10 # list runs for automation
oneshot status <run-id|events-file> --json # inspect one run
oneshot receipt <run-id># proof-of-work receipt (text)
oneshot receipt <run-id> --html # receipt as a self-contained HTML artifact
oneshot eval --json # summarize run outcomes
oneshot doctor # setup and remote health checks
oneshot doctor --repo my-org/my-app # setup + checkout health
oneshot route "fix failing CI and publish" --json # inspect the hidden route
oneshot workflow list # inspect workflow presets
oneshot workflow show fix-ci --json # inspect one workflow preset
oneshot policy init # create .oneshot/policy.json
oneshot policy init --path ./repo # write policy in another directory
oneshot gha init # scaffold a GitHub Actions workflow for detached runs
oneshot mcp serve # expose oneshot as MCP tools

Flags

FlagShortDescription
--model-mOverride configured plan/PR model
--branch-bBase branch (default: main)
--base-pathOverride the workspace path used to locate the repo
--worktree-rootOverride where temporary git worktrees are created
--modeSkip classification and force fast or deep mode
--workflowApply a workflow preset: ship, review, fix-ci, research, docs, or swarm-review
--deep-reviewForce exhaustive review mode
--localRun locally instead of over SSH
--bgRun detached in background (returns PID + log path)
--dry-run-dValidate only
--events-fileMirror JSONL events to an additional file
--repoWith doctor, verify a specific owner/repo checkout exists
--providerWith route, choose the fallback provider (codex or claude)

Prerequisites

On your laptop:Bun, SSH access to your server

On your server (or local machine with --local):

Configuration

~/.oneshot/config.json, created by oneshot init:

{
"host": "user@100.x.x.x",
"basePath": "~/projects",
"provider": "codex",
"routing": { "enabled": true },
"linearApiKey": "lin_api_...",
"claude": {
"model": "opus",
"timeoutMinutes": 180
},
"codex": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh",
"reviewModel": "gpt-5.5",
"reviewReasoningEffort": "xhigh",
"timeoutMinutes": 180
},
"phases": {
"classify": { "model": "gpt-5.5", "reasoningEffort": "medium" },
"plan": { "model": "gpt-5.5", "reasoningEffort": "xhigh" },
"execute": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"review": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"deepReview": {
"model": "gpt-5.5",
"reasoningEffort": "xhigh"
},
"pr": { "model": "gpt-5.5", "reasoningEffort": "high" }
},
"stepTimeouts": {
"planMinutes": 20,
"executeMinutes": 60,
"reviewMinutes": 20,
"deepReviewMinutes": 20,
"prMinutes": 20
}
}

Only host is required for SSH runs. Local mode works without a config file. Remote SSH runs stream the active oneshot config to the server for that run, so basePath, provider defaults, timeout settings, and configured Linear credentials stay aligned without requiring a duplicate ~/.oneshot/config.json on the server.

KeyRequiredDescription
hostSSH onlySSH target, e.g. user@192.168.1.10
basePathNoWhere repos live. Default: ~/projects
worktreeRootNoScratch directory for temporary git worktrees. Default: /tmp
providerNoFallback agent provider when adaptive routing is off or no route rule wins. Default: codex
routing.enabledNoEnables invisible provider/reasoning routing. Codex and Claude still use their configured frontier model; the router varies provider and effort, not model class
anthropicApiKeyClaude onlyFalls back to ANTHROPIC_API_KEY env var
linearApiKeyNoEnables Linear ticket integration
claude.modelClaude onlyDefault Claude model. Default: opus
codex.modelCodex onlyDefault Codex model. Default: gpt-5.5
codex.reasoningEffortCodex onlyDefault Codex reasoning effort. Default: xhigh
codex.reviewModelCodex onlyDefault for review phases. Default: same as codex.model
codex.reviewReasoningEffortCodex onlyDefault review reasoning effort. Default: same as codex.reasoningEffort
phases.<phase>.modelNoExact model for that phase under the selected provider
phases.<phase>.reasoningEffortNoReasoning effort for that phase, e.g. medium, high, xhigh. Passed to Codex and to Claude via --effort
stepTimeoutsNoPer-step timeout overrides in minutes

phases is optional. If it is omitted, every agent phase uses the selected provider and its default model settings. Any stale phases.<phase>.provider values from older configs are ignored when adaptive routing is off. With routing.enabled: true, oneshot's adaptive router can silently choose Codex or Claude per task while preserving each provider's configured frontier model.

Adaptive routing is intentionally invisible during normal use. Code edits, tests, refactors, PR work, and ship requests route to Codex by default. Tool-heavy operations, browser/admin/log/service work, and external workflow orchestration can route to Claude. If code will be edited, Codex wins the tie. Use oneshot route "<task>" --json only when you want to inspect the decision.

Repos on the server should live as <org>/<repo> under the base path. Repo slugs are intentionally strict: exactly owner/repo, using only letters, numbers, dot, underscore, and hyphen. Nested paths and .. are rejected before any filesystem access.

~/projects/
acme/api/
acme/web/

Linear integration

Pass a Linear URL instead of a task string:

oneshot acme/api https://linear.app/acme/issue/ENG-142
  1. Fetches issue title, description, and comments via GraphQL
  2. Uses ticket as context for the planning step
  3. Uses the issue ID in the branch name (oneshot/eng-142-...)
  4. Moves the ticket to "In Review" and comments the PR URL

Requires linearApiKey in config.

Customization

CLAUDE.md: put one in any repo root. oneshot passes it to the configured agents for planning and execution. Use it for coding standards, architecture decisions, test requirements.

Prompt templates: edit these to change pipeline behavior:

FileControls
prompts/plan.txtHow the plan agent explores and plans
prompts/execute.txtHow the execute agent implements changes
prompts/review.txtHow the review agent reviews the diff
prompts/pr.txtHow the PR agent writes branch/commit/PR metadata

Templates use {{variable}} placeholders replaced at runtime.

The repo's CLAUDE.md is also supplied to the planning and execution steps, so the task string is the primary operator input, not the only context the agents receive.

For dense specs, explainers, review maps, incident reports, design sheets, or one-off editors, the templates allow a self-contained HTML artifact instead of a long markdown document. Durable artifacts should live under docs/artifacts/; throwaway local artifacts should stay under /tmp/oneshot-html-artifacts/.

Events

Every run writes JSONL events to /tmp/oneshot-<runId>.events.jsonl and the durable local ledger at ~/.oneshot/runs/<runId>.events.jsonl. Use --events-file <path> to mirror to another file:

oneshot acme/api "fix bug" --local --events-file /tmp/run.events.jsonl

Events:

  • started (includes runtime metadata such as CLI version, host, pid, cwd, platform, and worktree root), classified, step (running/done/failed), completed (success/failed/dry-run)
  • agent for live agent activity: commands, tools, file changes, todos, web searches, warnings, draft PR creation, and turn/session markers

Workflows, policy, and MCP

Workflow presets wrap a task with a stronger operating mode while keeping the CLI portable:

oneshot workflow list
oneshot acme/api "fix the failing payment test" --workflow fix-ci
oneshot acme/web "review PR feedback and make it shippable" --workflow review

Policy packs live at .oneshot/policy.json. The default pack protects secret-like files and can require repo-specific checks before a draft PR is created:

oneshot policy init

oneshot mcp serve exposes the public engine as MCP tools for agent clients. The server supports running a task, listing runs, reading run status, reading a run receipt, initializing policy, listing workflows, and summarizing eval outcomes.

Receipts

Every run writes a proof-of-work receipt to ~/.oneshot/runs/<runId>.receipt.json. The receipt is the thing that makes fire-and-forget trustworthy: it records what was planned, which contract steps ran and how long they took, the review outcome (passed / timed-out / failed), the policy verdict, the defaults the run had to assume because a detached run cannot ask you, and a derived confidence rating (high only when the run shipped with a clean review and a clean policy gate).

oneshot receipt <run-id># human-readable sitrep
oneshot receipt <run-id> --json # machine-readable
oneshot receipt <run-id> --html > receipt.html # self-contained artifact

Runs without a receipt file (older or remote-only runs) reconstruct a thinner receipt from the event stream; reconstructed successes are capped at medium confidence since the contract verdict cannot be re-derived.

Notifications

So a detached run can ping you when its receipt is ready, add a notify block to ~/.oneshot/config.json. It is backend-agnostic on purpose: wire Slack, Discord, a desktop toast, or anything else yourself. Notification is best effort and never fails a run.

{
"notify": {
"webhook": "https://hooks.example.com/oneshot",
"command": "my-notify-script.sh",
"onSuccess": true,
"onFailure": true
}
}

The webhook receives the receipt summary as a JSON POST. The command runs with the same payload on stdin and in ONESHOT_NOTIFY_STATUS, ONESHOT_NOTIFY_REPO, ONESHOT_NOTIFY_HEADLINE, ONESHOT_NOTIFY_PR_URL, ONESHOT_NOTIFY_RECEIPT, and ONESHOT_NOTIFY_JSON.

GitHub Actions backend

Not everyone has a 24/7 dev box, but every repo has Actions: a durable executor that survives your laptop closing, with a secrets vault, that can open PRs natively. oneshot gha init scaffolds a workflow_dispatch workflow that runs the same contract in CI and uploads the receipt as an artifact.

oneshot gha init # writes .github/workflows/oneshot.yml
oneshot gha init --provider claude # wire the Anthropic key instead of OpenAI
gh workflow run oneshot.yml -f task="fix the login timeout"

It requires one provider API key in the repo's Actions secrets (OPENAI_API_KEY for Codex, ANTHROPIC_API_KEY for Claude); GITHUB_TOKEN is provided automatically and opens the PR. The command prints exactly which secret to add.

Doctor and recovery

oneshot doctor checks the installed package freshness against npm, local prerequisites, config file, recent event stream, SSH reachability, and remote binaries when a remote host is configured. Use oneshot doctor --local --json for machine-readable local checks.

Add --repo <owner/repo> to verify the configured local or remote base path actually contains the checkout before dispatch:

oneshot doctor --repo zkp2p/pay
oneshot doctor --local --repo zkp2p/pay --json

Failed runs preserve the worktree under the configured worktreeRoot and write a failed completed event with the error code and completed step timings. Start with oneshot runs, oneshot status <run-id>, and oneshot eval, then inspect the event file or preserved worktree path printed in the logs.

Agent skill

Works as an Agent Skill in Claude Code, Codex CLI, Cursor, and other compatible agents.

npx skills add ADWilkinson/oneshot-cli

Or via ClawHub:

clawhub install oneshot-ship

Agents pick it up automatically, or call /oneshot-ship directly.

License

MIT

Releases

Packages

Contributors

Languages