{"schemaVersion":1,"generatedAt":"2026-11-02T00:41:47.712Z","product":"Bystep","cli":{"package":"@bystep/cli","version":"0.0.0","run":"npx @bystep/cli <command>","manifest":"npx @bystep/cli --llms","exitCodes":{"0":"ok","1":"runtime/API error, or verification failed","2":"validation error (bad input, missing ids, usage)","3":"a stage gate (checkpoint) is waiting for human approval"},"commands":[{"name":"team tasks","args":[],"options":["--plan <id>","--mine"],"description":"List team task owners, claims and review states."},{"name":"team context","args":["<ref>"],"options":["--plan <id>"],"description":"Fetch and remember immutable actor-bound project context."},{"name":"team claim","args":["<ref>"],"options":["--plan <id>","--agent <name>","--lease <seconds>","--key <id>","--file <json>"],"description":"Reserve a task with a lease, human owner, executor and payer. Does not launch an AI."},{"name":"team heartbeat","args":["<ref>"],"options":["--plan <id>","--file <json>","--key <id>"],"description":"Record team heartbeat with explicit JSON input and an idempotency key."},{"name":"team assign","args":["<ref>"],"options":["--plan <id>","--file <json>","--key <id>"],"description":"Record team assign with explicit JSON input and an idempotency key."},{"name":"team report","args":["<ref>"],"options":["--plan <id>","--file <json>","--key <id>"],"description":"Record team report with explicit JSON input and an idempotency key."},{"name":"team review","args":["<ref>"],"options":["--plan <id>","--file <json>","--key <id>"],"description":"Record team review with explicit JSON input and an idempotency key."},{"name":"team handoff","args":["<ref>"],"options":["--plan <id>","--file <json>","--key <id>"],"description":"Record team handoff with explicit JSON input and an idempotency key."},{"name":"team release","args":["<ref>"],"options":["--plan <id>","--file <json>","--key <id>"],"description":"Record team release with explicit JSON input and an idempotency key."},{"name":"team relinquish","args":["<ref>"],"options":["--plan <id>","--file <json>","--key <id>"],"description":"Record team relinquish with explicit JSON input and an idempotency key."},{"name":"login","args":[],"options":["--token <token>"],"description":"Log in (device flow in the browser, or a bs_ token)."},{"name":"connect","args":[],"options":["--workspace <id>","--plan <id>","--json"],"description":"Bind this repository to a Bystep workspace/plan (.bystep/config.json)."},{"name":"init","args":[],"options":["--json","--no-hooks"],"description":"Install the bystep skill, guard hook and subagents into the detected coding agents (Claude Code, Cursor, Copilot, OpenCode, AGENTS.md)."},{"name":"doctor","args":[],"options":["--json","--repo"],"description":"Check the local setup; with --repo, score this checkout for agent readiness offline."},{"name":"plan get","args":["[planId]"],"options":["--json"],"description":"Fetch the PRD of a plan (text, or raw JSON with --json)."},{"name":"plan list","args":[],"options":["--json"],"description":"List the plans of the logged-in user."},{"name":"plan exec","args":[],"options":["--plan <id>","--mode <autopilot|checkpoint|strict>","--verifier <local|reviewer|ci>","--model <tier=model>","--json"],"description":"Set the execution mode, verifier and model hints of a plan."},{"name":"task next","args":[],"options":["--plan <id>","--json","--no-packet"],"description":"Ask the server for the ONE next task (with its Task Packet). Exit 3 when a checkpoint is pending."},{"name":"task list","args":[],"options":["--plan <id>","--json"],"description":"List tasks of a plan."},{"name":"task start","args":["<ref>"],"options":["--plan <id>","--json"],"description":"Mark a task in progress and snapshot the usage counters."},{"name":"task verify","args":["<ref>"],"options":["--plan <id>","--json","--skip <id>","--override <reason>","--no-screenshot","--timeout <seconds>","--tokens <in,out>","--cost <usd>","--model <id>"],"description":"Run the acceptance criteria locally and upload the evidence. Exit 1 when it fails."},{"name":"task complete","args":["<ref>"],"options":["--plan <id>","--json","--override <reason>","--skip <id>","--no-screenshot","--timeout <seconds>","--tokens <in,out>","--cost <usd>","--model <id>"],"description":"Complete a task (runs verify first; refused while the evidence has not passed unless --override)."},{"name":"task fail","args":["<ref>","[reason]"],"options":["--plan <id>","--json","--tokens <in,out>","--cost <usd>","--model <id>"],"description":"Mark a task failed with a reason."},{"name":"task packet","args":["<ref>"],"options":["--plan <id>","--json"],"description":"Print the Task Packet of a task."},{"name":"task guard","args":[],"options":["--plan <id>","--json"],"description":"Claude Code Stop/TaskCompleted hook: refuse to stop while the started task has no passing evidence."},{"name":"task approve","args":["<phase>"],"options":["--plan <id>","--layer <all|frontend|backend>","--note <note>","--return <ref:reason>","--json"],"description":"Approve a phase checkpoint (only when the user says so); --return sends a task back to the agent with a reason."},{"name":"wave next","args":[],"options":["--plan <id>","--json"],"description":"Get the next wave of up to 4 non-overlapping task packets."},{"name":"workflow list","args":[],"options":["--plan <id>"],"description":"List managed agent teams for a plan."},{"name":"workflow start","args":[],"options":["--plan <id>","--agent <backend>","--parallel <count>","--tokens <count>","--usd <amount>","--minutes <count>"],"description":"Start an agent team with the selected executor and payer, within explicit limits."},{"name":"workflow show","args":["<id>"],"options":[],"description":"Read durable progress, handoffs, usage and ordered events."},{"name":"workflow stop","args":["<id>"],"options":[],"description":"Request cancellation; execution ownership remains fenced until all processes stop."},{"name":"workflow resume","args":["<id>"],"options":[],"description":"Continue a checkpoint after the existing phase approval."},{"name":"workflow message","args":["<id>","<text>"],"options":["--recipient <session-id>"],"description":"Send guidance for subsequent worker assignments."},{"name":"import","args":["<path>"],"options":["--from <speckit|openspec|backlog|taskmaster>","--workspace <id>","--json"],"description":"Import an existing spec/backlog (Spec Kit, OpenSpec, backlog.md, Task Master) into a Bystep plan."},{"name":"workspace list","args":[],"options":["--json"],"description":"List workspaces."},{"name":"sync","args":[],"options":["--plan [id]","--if-changed","--json"],"description":"Upload the repository manifest (paths, sizes, hashes, languages; never secrets) and local file summaries."},{"name":"status","args":[],"options":["--json"],"description":"Show the connection and the current task."},{"name":"whoami","args":[],"options":["--json"],"description":"Show the logged-in user and API URL."},{"name":"serve","args":[],"options":["--name <name>","--dir <path>","--yolo","--once","--parallel <n>","--runs-per-hour <n>","--doctor","--json","--listen [host:port]","--no-listen","--pair <code>","--no-keychain"],"description":"Connect this computer to Bystep and build steps here with your own Claude Code / Codex login (--doctor checks readiness). A local listener (on by default, 127.0.0.1) receives agent hooks, reports and approval answers; --no-listen turns it off. --pair <code> pairs this computer with a one-time code from the web and stores its machine-scoped daemon token in the OS keychain (config.json 0600 with --no-keychain or when no keychain exists)."},{"name":"update","args":[],"options":["--check","--apply","--channel <stable|preview>","--json"],"description":"Check for a newer Bystep CLI (default) or --apply it: reads <api>/downloads/latest.json (stable) or preview.json, verifies size + sha256, then npm install -g."},{"name":"service install","args":[],"options":["--name <name>","--json"],"description":"Install and start bystep serve as a background service (systemd user / launchd / Task Scheduler), restarting on failure; logs to ~/.bystep/runtime/serve.log."},{"name":"service uninstall","args":[],"options":["--json"],"description":"Stop the background service and remove exactly what service install created (logs and projects stay)."},{"name":"service status","args":[],"options":["--json"],"description":"Service state from the service manager plus the running daemon (local listener GET /state)."},{"name":"hooks","args":["<adapter>","<event>"],"options":[],"description":"Agent hook entry point (Claude Code / Codex): forwards the hook payload on stdin to the local listener; PermissionRequest waits for the owner’s answer. No-op outside a Bystep session."},{"name":"report","args":[],"options":["--state <state>","--message <text>","--json"],"description":"Report the agent state (active | idle | waiting_input | blocked) with a short message, for agents without hooks."},{"name":"review submit","args":[],"options":["--body <json>","--json"],"description":"Reviewer agent: submit findings as JSON on stdin or --body ({verdict, comments[{severity, file, line?, text}] ≤ 50}) for the current workflow session."},{"name":"decision list","args":[],"options":["--workspace <id>","--history","--json"],"description":"List the active decisions of a workspace (--history adds replaced ones)."},{"name":"decision add","args":["<text>"],"options":["--why <reason>","--workspace <id>","--plan <id>","--json"],"description":"Record a decision — binding for every agent from the next task on."},{"name":"decision archive","args":["<id>"],"options":["--workspace <id>","--json"],"description":"Archive an obsolete decision, preserving history and freeing a slot."},{"name":"decision restore","args":["<id>"],"options":["--workspace <id>","--json"],"description":"Restore historical text without replacing its successor."},{"name":"decision replace","args":["<id>","<text>"],"options":["--why <reason>","--workspace <id>","--json"],"description":"Replace a decision; the old one stays in the history, marked as replaced."}]},"mcp":{"package":"@bystep/mcp","version":"0.0.0","transport":"stdio","tools":[{"name":"team_tasks","description":"List team task owners, claims and review states."},{"name":"team_context","description":"Fetch and remember immutable actor-bound project context."},{"name":"team_claim","description":"Reserve a task with a lease, human owner, executor and payer. Does not launch an AI."},{"name":"team_heartbeat","description":"Record team heartbeat with explicit JSON input and an idempotency key."},{"name":"team_assign","description":"Record team assign with explicit JSON input and an idempotency key."},{"name":"team_report","description":"Record team report with explicit JSON input and an idempotency key."},{"name":"team_review","description":"Record team review with explicit JSON input and an idempotency key."},{"name":"team_handoff","description":"Record team handoff with explicit JSON input and an idempotency key."},{"name":"team_release","description":"Record team release with explicit JSON input and an idempotency key."},{"name":"team_relinquish","description":"Record team relinquish with explicit JSON input and an idempotency key."},{"name":"workflow_list","description":"List managed agent teams for a plan."},{"name":"workflow_get","description":"Read a team’s durable progress, handoffs, usage and events."},{"name":"workflow_start","description":"Start managed parallel execution with the selected executor, payer and limits."},{"name":"workflow_stop","description":"Request cancellation and process reconciliation."},{"name":"workflow_resume","description":"Continue after the phase checkpoint is approved."},{"name":"workflow_message","description":"Send guidance for subsequent assignments."},{"name":"plan_get","description":"Fetch the full PRD of a plan as text or JSON."},{"name":"plan_list","description":"List the plans of the logged-in user."},{"name":"task_next","description":"Pick the ONE next task (with packet)."},{"name":"task_packet","description":"Task Packet of a task."},{"name":"task_start","description":"Mark a task in progress."},{"name":"task_verify","description":"Run acceptance criteria and upload evidence."},{"name":"task_complete","description":"Complete a task; 409 without passing evidence."},{"name":"task_fail","description":"Mark a task failed with a reason."},{"name":"task_evidence_get","description":"Read the recorded evidence of a task."},{"name":"phase_approve","description":"Approve a phase checkpoint."},{"name":"wave_next","description":"Next wave of non-overlapping task packets."},{"name":"sync_status","description":"Codebase sync status of the connected workspace (file/summary counts, wiki)."},{"name":"review_submit","description":"Reviewer agent: submit severity-rated findings of a read-only review (session lease or local listener)."},{"name":"approval_list","description":"Permission requests running agents wait on (Inbox kind approval)."},{"name":"approval_answer","description":"Answer a permission request: accept or decline, optionally remembered as a project rule."},{"name":"decision_card_list","description":"Decision cards of a plan: open questions with 2–3 options and their consequences."},{"name":"decision_card_choose","description":"Choose an option on a decision card (records a binding decision; may re-plan a feature)."},{"name":"decision_list","description":"Decisions of a workspace (binding for every agent)."},{"name":"decision_replace","description":"Replace an active decision, preserving history."},{"name":"decision_archive","description":"Archive an obsolete decision to free a slot."},{"name":"decision_restore","description":"Restore historical text without replacing its successor."},{"name":"decision_add","description":"Record a decision."},{"name":"rules_list","description":"Project rules (ALWAYS / NEVER / ASK FIRST) as in every Task Packet."},{"name":"state_get","description":"Effective state of a run or workflow session, with the reason."}]},"downloads":{"manifest":"https://bystep.dev/downloads/releases.json","cli":"https://bystep.dev/downloads/bystep-cli-0.0.0.tgz","mcp":"https://bystep.dev/downloads/bystep-mcp-0.0.0.tgz"},"mcpHosted":{"endpoint":"https://bystep.dev/api/mcp","transport":"streamable-http","auth":"Authorization: Bearer bs_<token>","tools":[{"name":"workflow_list","description":"List managed agent teams for a plan."},{"name":"workflow_get","description":"Read a team’s durable progress, handoffs, usage and events."},{"name":"workflow_start","description":"Start managed parallel execution with the selected executor, payer and limits."},{"name":"workflow_stop","description":"Request cancellation and process reconciliation."},{"name":"workflow_resume","description":"Continue after the phase checkpoint is approved."},{"name":"workflow_message","description":"Send guidance for subsequent assignments."},{"name":"list_plans","description":"List plans with plain-language status."},{"name":"plan_status","description":"Steps done / total, current stage, what is waiting for the user."},{"name":"run_next","description":"Start the Runner on the next step (uses a monthly step credit)."},{"name":"run_status","description":"Plain-language progress of a run."},{"name":"preview_url","description":"Link to try the app on a phone."},{"name":"approve_stage","description":"Approve the current stage gate."},{"name":"escalate","description":"Explain / revert / skip / ask a human when a step is stuck."},{"name":"review_submit","description":"Explains that only the reviewer agent session can submit findings (read them with workflow_get)."},{"name":"approval_list","description":"Permission requests running agents wait on."},{"name":"approval_answer","description":"Answer a permission request with the user’s decision."},{"name":"decision_card_list","description":"Decision cards of a project with options and consequences."},{"name":"decision_card_choose","description":"Record the option the user picked on a decision card."},{"name":"decision_list","description":"Decisions of a workspace."},{"name":"decision_replace","description":"Replace an active decision, preserving history."},{"name":"decision_archive","description":"Archive an obsolete decision to free a slot."},{"name":"decision_restore","description":"Restore historical text without replacing its successor."},{"name":"decision_add","description":"Record a decision the user stated."},{"name":"rules_list","description":"Project rules every agent follows."},{"name":"state_get","description":"What an agent is doing right now, and why."},{"name":"task_packet","description":"The Task Packet of one step (JSON)."}]},"packet":{"$schema":"https://json-schema.org/draft/2020-12/schema","title":"TaskPacket","type":"object","required":["ref","title","description","layer","priority","tier","escalated","feature","prdExcerpt","acceptance","ownedFiles","doNotTouch","relevantFiles","conventions","verifyCommands","execution","hypotheses","approxTokens"],"properties":{"ref":{"type":"string","description":"Task reference unique within the plan, e.g. T-12"},"title":{"type":"string"},"description":{"type":"string"},"layer":{"type":"string","enum":["frontend","backend"]},"priority":{"type":"string"},"tier":{"type":"string","enum":["light","standard","heavy"]},"escalated":{"type":"boolean","description":"true when the tier was bumped after two failed verifications"},"feature":{"type":"object","required":["name","phase","goal","done"],"properties":{"name":{"type":"string"},"phase":{"type":"integer"},"goal":{"type":"string"},"done":{"type":"array","items":{"type":"string"}}}},"prdExcerpt":{"type":"string"},"acceptance":{"type":"array","items":{"type":"object","required":["id","text","kind"],"properties":{"id":{"type":"string"},"text":{"type":"string"},"kind":{"type":"string","enum":["test","build","lint","http","file","screenshot","manual"]},"cmd":{"type":"string"},"expect":{"type":"string"},"validates":{"type":"string","description":"hypothesis id (H-1…) this criterion validates"}}}},"ownedFiles":{"type":"array","items":{"type":"string"},"description":"the only files the agent may change"},"doNotTouch":{"type":"array","items":{"type":"string"},"description":"files/globs owned by other tasks or protected by a project rule"},"relevantFiles":{"type":"array","items":{"type":"object","required":["path","summary"],"properties":{"path":{"type":"string"},"summary":{"type":"string"}}}},"conventions":{"type":"string","description":"code conventions + the PROJECT RULES block (ALWAYS / NEVER / ASK FIRST)"},"verifyCommands":{"type":"array","items":{"type":"string"}},"modelHint":{"type":["string","null"]},"execution":{"type":"object","properties":{"mode":{"type":"string","enum":["autopilot","checkpoint","strict"]},"verifier":{"type":"string","enum":["local","reviewer","ci"]}}},"hypotheses":{"type":"array","items":{"type":"object","required":["id","text"],"properties":{"id":{"type":"string"},"text":{"type":"string"},"metric":{"type":"string"},"threshold":{"type":"string"},"test":{"type":"string"}}}},"approxTokens":{"type":"integer"}}},"evidence":{"$schema":"https://json-schema.org/draft/2020-12/schema","title":"EvidenceInput","type":"object","required":["criteriaResults"],"properties":{"status":{"type":"string","enum":["pass","fail"]},"criteriaResults":{"type":"array","items":{"type":"object","required":["id","kind","ok"],"properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["test","build","lint","http","file","screenshot","manual"]},"ok":{"type":"boolean"},"output":{"type":"string","description":"≤ 4k chars, secrets redacted client-side"},"durationMs":{"type":"integer"},"skipped":{"type":"boolean"}}}},"commitHash":{"type":"string"},"diffStat":{"type":"object","properties":{"files":{"type":"integer"},"add":{"type":"integer"},"del":{"type":"integer"}}},"filesTouched":{"type":"array","items":{"type":"string"}},"screenshots":{"type":"array","items":{"type":"string"}},"durationMs":{"type":"integer"},"tokens":{"type":"object","properties":{"input":{"type":"integer"},"output":{"type":"integer"},"cacheRead":{"type":"integer"},"cacheWrite":{"type":"integer"}}},"cost":{"type":"number","description":"USD; estimated from tokens when absent"},"agent":{"type":"string"},"model":{"type":"string"},"attempt":{"type":"integer"}}},"serverCapabilities":["workflow-v1","lease-v2","events-v1","wake-sse"],"runtime":{"protocolVersion":2,"serverCapabilities":["workflow-v1","lease-v2","events-v1","wake-sse"],"runEventKinds":["turn.started","turn.completed","item.message","item.tool_use","item.tool_result","item.file_change","item.command","item.terminal","usage","state","session.start_source","provider.failed","approval.request","approval.resolved","review.submitted","review.gate","checkpoint","undo"],"runEventBatch":{"$schema":"https://json-schema.org/draft/2020-12/schema","title":"RunEventBatch","type":"object","required":["events"],"properties":{"events":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","required":["seq","kind"],"properties":{"seq":{"type":"integer","minimum":1,"description":"monotonic per run / per session; duplicates are ignored and counted"},"kind":{"type":"string","enum":["turn.started","turn.completed","item.message","item.tool_use","item.tool_result","item.file_change","item.command","item.terminal","usage","state","session.start_source","provider.failed","approval.request","approval.resolved","review.submitted","review.gate","checkpoint","undo"]},"payload":{"type":"object","description":"≤ 16 KB; longer output/chunk/input/text strings are truncated and payload.truncated=true is set"},"at":{"type":"string","format":"date-time"}}}}}},"endpoints":[{"method":"POST","path":"/api/machines","description":"Register/upsert this computer. v2 body adds agents[{id,version,authSource,capabilities}], capabilities[], capacity; response adds serverCapabilities + protocolVersion."},{"method":"POST","path":"/api/machines/:id/heartbeat","description":"Presence every 30 s; drains queued commands; may patch agents/capabilities/capacity."},{"method":"GET","path":"/api/machines/:id/events","description":"SSE wake: work_available {runId?|workflowId?}, command {id}, ping every 25 s. Keep polling claim as fallback."},{"method":"POST","path":"/api/run/:runId/events","description":"Batch of normalized agent events (run-scoped token or owner; no lease) → {accepted, duplicates, lastSeq}."},{"method":"GET","path":"/api/run/:runId/events?after=&limit=","description":"Owner cursor read → {events:[{id,seq,kind,payload,at}], lastSeq, hasMore}."},{"method":"POST","path":"/api/workflows/:id/sessions/:sid/events","description":"Same batch for one workflow session (owner + lease headers like report)."},{"method":"GET","path":"/api/workflows/:id/sessions/:sid/events?after=&limit=","description":"Owner cursor read for a session."},{"method":"GET","path":"/api/checkpoints/:id","description":"Checkpoint manifest (owner; a daemon sends x-bystep-machine-id) → {id, runId, sessionId, workflowId, workspaceId, turnSeq, entries, treeHash, truncated}."},{"method":"POST","path":"/api/checkpoints/:id/result","description":"Undo result {restored:[path], failed:[{path, reason}]} → run_event `undo`; idempotent per manifest; no lease."},{"method":"POST","path":"/api/machines/pair/code","description":"Owner browser session only (a bearer token → 403 token_scope) → 201 {code (8 chars of 23456789ABCDEFGHJKLMNPQRSTUVWXYZ), expiresAt (+10 min), qr (SVG data URL of bystep://pair?code=<code>&api=<origin>), command (bystep serve --pair <code>)}. Single use; only its sha256 is stored."},{"method":"POST","path":"/api/machines/pair","description":"No auth, 10 attempts/min per IP. {code, name, os?, arch?, hostname?, nodeVersion?, cliVersion?, agents?, capabilities?, capacity?, protocolVersion?, runtimeId?, machineId?} → 201 {machine:{id,name}, token (bs_…, kind daemon), tokenExpiresAt (+90 d), scope machine:<id>, serverCapabilities, protocolVersion}. Unknown, expired or used code → 404 pairing_invalid. A machine:<id> token reaches only that machine’s endpoints and the runs, workflows, workspaces, checkpoints and approvals bound to it; anything else → 403 token_scope."},{"method":"POST","path":"/api/machines/:id/token/rotate","description":"The machine’s current daemon token → {token, tokenExpiresAt (+90 d)}. The old token stays valid until the new one is first used, at most 1 h."}]},"agentPlatform":{"workflowProtocol":{"version":1,"unchanged":true,"leaseHeaders":["x-bystep-lease-id","x-bystep-lease-epoch"],"idempotency":"requestId on claim and dispatch; exact duplicate receipts","ownershipViolation":"a session that changes files outside its ownedFiles fails integration"},"endpoints":[{"phase":"v1","method":"GET","path":"/api/machines","description":"The owner’s connected computers."},{"phase":"v1","method":"GET","path":"/api/machines/:id","description":"One computer (owner, or its own machine:<id> daemon token)."},{"phase":"v1","method":"DELETE","path":"/api/machines/:id","description":"Remove a computer; revokes its daemon token. A machine:<id> token → 403 token_scope."},{"phase":"v1","method":"POST","path":"/api/machines/:id/claim","description":"Single-step Runner: atomically claim one queued run bound to this computer → {run} or {run: null}."},{"phase":"v1","method":"GET","path":"/api/machines/:id/tunnel","description":"SSE of preview requests (/pv/<slug>) for projects that build on this computer."},{"phase":"v1","method":"POST","path":"/api/machines/:id/tunnel/:reqId","description":"The daemon’s answer to one tunnelled preview request."},{"phase":"v1","method":"POST","path":"/api/machines/:id/workflows/claim","description":"{protocolVersion: 2, runtimeId, requestId} → {workflow, lease: {id, epoch, expiresAt}, project}. Retries reuse the persisted requestId and replay the same assignment."},{"phase":"v1","method":"GET","path":"/api/workflows/:id?after=N","description":"Workflow, sessions, ordered events (sequence > N) and messages (owner)."},{"phase":"v1","method":"POST","path":"/api/workflows/:id/heartbeat","description":"{runtimeId, id: lease.id, epoch: lease.epoch, reconciled?} → {lease, status}. A null lease stops every child; an expired lease is never revived."},{"phase":"v1","method":"POST","path":"/api/workflows/:id/dispatch","description":"{baseCommit, requestId} + lease headers → {sessions, status, integration?}. requestId is persisted before the call and reused on retry."},{"phase":"v1","method":"POST","path":"/api/workflows/:id/sessions/:sid/report","description":"Session receipt {attempt, ok, headCommit, contextHash, handoff, tokensIn, tokensOut, costUsd, providerSessionId, error} + lease headers. Exact duplicates are idempotent; a conflicting repeat fails. E1: error \"merge_conflict\" creates a Fix task; E3: optional handoff fields."},{"phase":"v1","method":"POST","path":"/api/workflows/:id/integrate","description":"{headCommit, snapshotCommit, checks[]} → all task evidence/completions in one transaction after ownership, context, snapshot and reviewer checks."},{"phase":"v1","method":"POST","path":"/api/workflows/:id/advance","description":"Next wave in the same parent → workflow.status running | checkpoint | passed."},{"phase":"v1","method":"POST","path":"/api/workflows/:id/action","description":"{action: \"cancel\" | \"resume\"}; cancel keeps reconciliation ownership until the runtime proves its processes stopped."},{"phase":"v1","method":"POST","path":"/api/workflows/:id/messages","description":"{message ≤ 4000, recipientId?} owner guidance for later assignments."},{"phase":"E1","method":"GET","path":"/api/plan/:planId/workflows","description":"Agent teams of a plan; E1 adds limits {parallelRuns, serveParallel, reviewerRuns, machineCapacity, entitlementSlug}."},{"phase":"E1","method":"POST","path":"/api/plan/:planId/workflows","description":"Start an agent team with the chosen executor, payer and limits. E1: 402 parallel_runs {limit, requested} or 402 daily_usd_cap {cap, spent} instead of silently lowering the request."},{"phase":"E0","method":"GET","path":"/api/agents","description":"Coding-agent registry (web session or bs_ token), from packages/cli/src/registry.json: id, label, kind, localOk, cloudOk, enabled, supportsResume, outputFormat, policyRef."},{"phase":"E2","method":"POST","path":"/api/run/:runId/approvals","description":"Daemon: raise a permission request for a single-step run (Inbox kind approval)."},{"phase":"E2","method":"POST","path":"/api/workflows/:id/sessions/:sid/approvals","description":"Daemon: raise a permission request for a team session (owner + lease headers)."},{"phase":"E2","method":"GET","path":"/api/approvals/:id?wait=1","description":"→ {approval}; wait=1 long-polls ≤ 25 s until answered or expired (10 min → denied)."},{"phase":"E2","method":"POST","path":"/api/approvals/:id","description":"{decision: \"accept\" | \"decline\", remember?} → {approval, rule?}. Answered once; the same decision replays, another one → 409. remember writes an always/never project rule."},{"phase":"E2","method":"POST","path":"/api/run/:runId/state","description":"{source: hook | stream | report, seq, state, toolUseId?}; idempotent per source and seq."},{"phase":"E2","method":"GET","path":"/api/run/:runId/state","description":"Effective state {state, reason, sources (last 10)}; silence after 20 s → no_signal, never \"working\"."},{"phase":"E2","method":"POST","path":"/api/workflows/:id/sessions/:sid/state","description":"Same state signal for a team session."},{"phase":"E2","method":"GET","path":"/api/workflows/:id/sessions/:sid/state","description":"Effective state of a team session."},{"phase":"E2","method":"GET","path":"/api/workflows/:id/review","description":"Pemeriksa (reviewer agent) findings of a team (owner)."},{"phase":"E2","method":"POST","path":"/api/workflows/:id/sessions/:sid/review","description":"`bystep review submit` via the daemon (owner token + lease headers): {verdict: pass | fail, comments ≤ 50 [{severity, file, line?, text}]}."},{"phase":"E2","method":"POST","path":"/api/workflows/:id/review/fix-all","description":"{severities? = [critical, major]} → Fix tasks \"Perbaiki temuan Pemeriksa: …\"; a repeat creates nothing new."},{"phase":"E2","method":"POST","path":"/api/workflows/:id/review/recheck","description":"{mode: \"again\" | \"fresh\"} → a NEW workflow on the integrated commit (a failed workflow is never revived)."},{"phase":"E2","method":"GET","path":"/api/plan/:planId/decision-cards?status=open|chosen|expired","description":"Decision cards of a plan, newest first."},{"phase":"E2","method":"POST","path":"/api/plan/:planId/decision-cards","description":"{question, options[2..3] {key, label, consequence}, featureId?} → 201 {card}."},{"phase":"E2","method":"POST","path":"/api/plan/:planId/decision-cards/:cardId/choose","description":"{key} → {card, decision, effect}; records the binding decision \"<question> → <label>\". 409 card_decided · 409 card_expired · 400 bad_key."},{"phase":"E2","method":"POST","path":"/api/plan/:planId/assist/contradictions","description":"\"Periksa rencana\": at most three decision cards (or clean); costs one chat message of the planning quota."},{"phase":"E3","method":"POST","path":"/api/plan/:planId/workflows/continue-elsewhere","description":"{executor: cloud | local, machineId?, connectionId?, confirm: true} → a new team from the last integrated commit. Never automatic. 409 confirm_required · 409 fallback_never · 409 not_eligible · 503 cloud_workflow_disabled."},{"phase":"E3","method":"GET","path":"/api/provider-policy","description":"Public provider-policy table (allowed / gray / forbidden per way of running, with source and date checked); cached one hour."},{"phase":"E4","method":"GET","path":"/api/run/:runId/events/stream?after=N","description":"SSE read from the database: run_event {id, seq, kind, payload, at}, state, ping; frames carry id: for Last-Event-ID."},{"phase":"E4","method":"GET","path":"/api/run/:runId/events/:seq/payload","description":"The stored payload of one event (≤ 16 KB; the full output behind the 4 KB preview)."},{"phase":"E4","method":"GET","path":"/api/workflows/:id/stream?after=N","description":"SSE of a team: workflow_event {sequence, kind, payload, at, sessionId?}, run_event with sessionId, state, ping."},{"phase":"E4","method":"GET","path":"/api/workflows/:id/sessions/:sid/events/:seq/payload","description":"Stored payload of one team-session event."},{"phase":"E4","method":"POST","path":"/api/run/:runId/undo","description":"{turnSeq} (owner, run not active) → undo one checkpointed turn. 409 run_active · 404 · 409 not_undoable · 409 already_undone · 409 machine_unknown · 409 worktree_gone."},{"phase":"E4","method":"POST","path":"/api/workflows/:id/sessions/:sid/undo","description":"{turnSeq} for a CLOUD team session; a session on the owner’s computer → 409 undo_unsupported_local_session."},{"phase":"E4","method":"POST","path":"/api/workspaces/:id/issues/import","description":"Opt-in: {repo: \"owner/name\", labels?, state: \"open\", planId?} → {imported, skipped, tasks, pullRequests}; ≤ 50 per request, one request per 5 min (429 import_backoff); acceptance criteria stay empty."},{"phase":"E4","method":"PATCH","path":"/api/workspace/:id/settings","description":"Workspace settings; E4 adds issueImportEnabled (off by default)."}]},"links":{"agentGuide":"https://bystep.dev/agent-guide.md","agentGuideEn":"https://bystep.dev/agent-guide.en.md","llms":"https://bystep.dev/llms.txt","llmsFull":"https://bystep.dev/llms-full.txt","docs":"https://bystep.dev/docs","start":"https://bystep.dev/mulai"}}