{"_id":"@autosk/pi-agent","_rev":"6-14d362ee97c311ce8ceac2996210708f","name":"@autosk/pi-agent","dist-tags":{"latest":"0.1.5"},"versions":{"0.1.0":{"name":"@autosk/pi-agent","version":"0.1.0","keywords":["autosk","autosk-extension","agent","pi","ai-agent"],"author":{"name":"wierdbytes"},"license":"MIT","_id":"@autosk/pi-agent@0.1.0","maintainers":[{"name":"wierdbytes","email":"wb@xff.pw"}],"homepage":"https://github.com/wierdbytes/autosk#readme","bugs":{"url":"https://github.com/wierdbytes/autosk/issues"},"dist":{"shasum":"66dc6b1561b1a3b1aef952bd3ef398c6c1352552","tarball":"https://registry.npmjs.org/@autosk/pi-agent/-/pi-agent-0.1.0.tgz","fileCount":8,"integrity":"sha512-T7S6ojl3GdKIvr+u7uAzNXgn2IAv8+lMedMlnXGKEUWz2kceXRErnBEfEmkKgafVXvED4EvIa/lv4PYGLj3HNg==","signatures":[{"sig":"MEQCIFgtUbgwCZzHOHbHGT34aaIlyXx07mVn8CPpPN9Igg3jAiA9tFIbSxqRMIf0SGXMZyYir0FoHKVEF7ZOyYHGaxe0Pw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":36543},"type":"module","types":"./index.ts","autosk":{"extensions":["./index.ts"]},"exports":{".":"./index.ts"},"gitHead":"33fb3204a8ad14fa0f994796ea9e90a3def5a998","scripts":{"typecheck":"tsc --noEmit -p tsconfig.json"},"_npmUser":{"name":"wierdbytes","email":"wb@xff.pw"},"repository":{"url":"git+https://github.com/wierdbytes/autosk.git","type":"git","directory":"daemon/extensions/pi-agent"},"_npmVersion":"11.9.0","description":"autosk extension that drives `pi --mode rpc` as an agent (model/thinking/first_message, kickback loop, autosk_transit pi-tool bridge).","directories":{},"_nodeVersion":"25.6.1","dependencies":{"@autosk/sdk":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/pi-agent_0.1.0_1781464690001_0.8425901946935315","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@autosk/pi-agent","version":"0.1.1","keywords":["autosk","autosk-extension","agent","pi","ai-agent"],"author":{"name":"wierdbytes"},"license":"MIT","_id":"@autosk/pi-agent@0.1.1","maintainers":[{"name":"wierdbytes","email":"wb@xff.pw"}],"homepage":"https://github.com/wierdbytes/autosk#readme","bugs":{"url":"https://github.com/wierdbytes/autosk/issues"},"dist":{"shasum":"f4d0a465a1cca9ff82fb0a96ef6757d8b0a514d8","tarball":"https://registry.npmjs.org/@autosk/pi-agent/-/pi-agent-0.1.1.tgz","fileCount":8,"integrity":"sha512-zub7f71s6sbLT1u4PPQVbKavT+odhhkW0W2uL+NFowl8ejRnKZqSYI7TY385qOdUYmY5FhNVbcd+l/o7Wm9Oqw==","signatures":[{"sig":"MEUCIQCUlyZR+NBAB/DsOps8TjDKNake14QtYgnu7rKzh8bw9gIgM3ksKdBCmATalqumHUXQPJUDk+5Mf8tadNVmOwC0ed4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38433},"type":"module","types":"./index.ts","autosk":{"extensions":["./index.ts"]},"exports":{".":"./index.ts"},"gitHead":"e39920e85514395b45d69bbf42b3e6c467ab5a2c","scripts":{"typecheck":"tsc --noEmit -p tsconfig.json"},"_npmUser":{"name":"wierdbytes","email":"wb@xff.pw"},"repository":{"url":"git+https://github.com/wierdbytes/autosk.git","type":"git","directory":"daemon/extensions/pi-agent"},"_npmVersion":"11.9.0","description":"autosk extension that drives `pi --mode rpc` as an agent (model/thinking/first_message, kickback loop, autosk_transit pi-tool bridge).","directories":{},"_nodeVersion":"25.6.1","dependencies":{"@autosk/sdk":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/pi-agent_0.1.1_1781475865497_0.4884502079653126","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@autosk/pi-agent","version":"0.1.2","keywords":["autosk","autosk-extension","agent","pi","ai-agent"],"author":{"name":"wierdbytes"},"license":"MIT","_id":"@autosk/pi-agent@0.1.2","maintainers":[{"name":"wierdbytes","email":"wb@xff.pw"}],"homepage":"https://github.com/wierdbytes/autosk#readme","bugs":{"url":"https://github.com/wierdbytes/autosk/issues"},"dist":{"shasum":"9b50bcd8cf8413d70c6b3a624cdab004122ef248","tarball":"https://registry.npmjs.org/@autosk/pi-agent/-/pi-agent-0.1.2.tgz","fileCount":8,"integrity":"sha512-c9QR8gxeiN+h3wBkIm/uJbFVVFimDy1pmUrMnp8GSB0IaTh6unNruegV8dnVO7Pr2a1zThSwL+lVr28Nsl4khg==","signatures":[{"sig":"MEUCICrnjDJtXAgEd5ZdiJ0ZnZqhEfEBImoPpdWDbMvejxhIAiEA14YhcgBxMDaZnGmxSb+yr/I7IwykNE8HnHujsDBu2+8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43889},"type":"module","types":"./index.ts","autosk":{"extensions":["./index.ts"]},"exports":{".":"./index.ts"},"gitHead":"05a5cbc4b6eecdbfad005b4a2d595dc8e49259f4","scripts":{"typecheck":"tsc --noEmit -p tsconfig.json"},"_npmUser":{"name":"wierdbytes","email":"wb@xff.pw"},"repository":{"url":"git+https://github.com/wierdbytes/autosk.git","type":"git","directory":"daemon/extensions/pi-agent"},"_npmVersion":"11.9.0","description":"autosk extension that drives `pi --mode rpc` as an agent (model/thinking/first_message, kickback loop, autosk_transit pi-tool bridge).","directories":{},"_nodeVersion":"25.6.1","dependencies":{"@autosk/sdk":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/pi-agent_0.1.2_1781721576507_0.6136032462220415","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@autosk/pi-agent","version":"0.1.3","keywords":["autosk","autosk-extension","agent","pi","ai-agent"],"author":{"name":"wierdbytes"},"license":"MIT","_id":"@autosk/pi-agent@0.1.3","maintainers":[{"name":"wierdbytes","email":"wb@xff.pw"}],"homepage":"https://github.com/wierdbytes/autosk#readme","bugs":{"url":"https://github.com/wierdbytes/autosk/issues"},"dist":{"shasum":"4a741fdfd4be6da7c4c59ebda701a22c20f73102","tarball":"https://registry.npmjs.org/@autosk/pi-agent/-/pi-agent-0.1.3.tgz","fileCount":8,"integrity":"sha512-59nWGP9qN+Wivjndwewa6iNmxN5HJfFuDQXgaQcPq5zA8j9yXxAPjqrFYa9kc0BnmHsD5MBjaK1TECmXZ3agLA==","signatures":[{"sig":"MEUCIBttU3VgirhFY/U9Qu9lwCiEliUDqBNPCywU23D5Sxj/AiEAmbaQNG0/LC7mTHu09pDCSkM+fkdO+8BdKggp4dpV7VI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49144},"type":"module","types":"./index.ts","autosk":{"extensions":["./index.ts"]},"exports":{".":"./index.ts"},"gitHead":"f2863a8c208bac269d0a404123e19916718d1d13","scripts":{"typecheck":"tsc --noEmit -p tsconfig.json"},"_npmUser":{"name":"wierdbytes","email":"wb@xff.pw"},"repository":{"url":"git+https://github.com/wierdbytes/autosk.git","type":"git","directory":"daemon/extensions/pi-agent"},"_npmVersion":"11.9.0","description":"autosk extension that drives `pi --mode rpc` as an agent (model/thinking/first_message, kickback loop, autosk_transit pi-tool bridge).","directories":{},"_nodeVersion":"25.6.1","dependencies":{"@autosk/sdk":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/pi-agent_0.1.3_1781733771375_0.2949122627824581","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@autosk/pi-agent","version":"0.1.4","keywords":["autosk","autosk-extension","autosk-agent"],"author":{"name":"wierdbytes"},"license":"MIT","_id":"@autosk/pi-agent@0.1.4","maintainers":[{"name":"wierdbytes","email":"wb@xff.pw"}],"homepage":"https://github.com/wierdbytes/autosk#readme","bugs":{"url":"https://github.com/wierdbytes/autosk/issues"},"dist":{"shasum":"5001673121e73179f70420a87e4033577fe4fc8a","tarball":"https://registry.npmjs.org/@autosk/pi-agent/-/pi-agent-0.1.4.tgz","fileCount":8,"integrity":"sha512-cWT/8dvKljeWtC7RurqvSaGHlueZ5sCINhMQ4Rxt1vkfyNGmVyYMEnh4eNVlSEGSRLWf1wcLFHjFhrsEYfRfpQ==","signatures":[{"sig":"MEYCIQC198r5HPOK2j1XoS7rtNLfLc/jEi+YOzHfEqyLYES0KQIhALDzPghKi+b0bPI9N3DSfUhE1622xVV/Sn6NmLao867v","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55033},"type":"module","types":"./index.ts","autosk":{"extensions":["./index.ts"]},"exports":{".":"./index.ts"},"gitHead":"6e4189216039fd42317f92d84106b7415ac1e9dd","scripts":{"typecheck":"tsc --noEmit -p tsconfig.json"},"_npmUser":{"name":"wierdbytes","email":"wb@xff.pw"},"repository":{"url":"git+https://github.com/wierdbytes/autosk.git","type":"git","directory":"daemon/extensions/pi-agent"},"_npmVersion":"11.9.0","description":"autosk extension that drives `pi --mode rpc` as an agent (model/thinking/first_message, kickback loop, autosk_transit pi-tool bridge).","directories":{},"_nodeVersion":"25.6.1","dependencies":{"@autosk/sdk":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/pi-agent_0.1.4_1782167544604_0.1590464521903221","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@autosk/pi-agent","version":"0.1.5","description":"autosk extension that drives `pi --mode rpc` as an agent (model/thinking/first_message, kickback loop, autosk_transit pi-tool bridge).","license":"MIT","author":{"name":"wierdbytes"},"homepage":"https://github.com/wierdbytes/autosk#readme","repository":{"type":"git","url":"git+https://github.com/wierdbytes/autosk.git","directory":"daemon/extensions/pi-agent"},"bugs":{"url":"https://github.com/wierdbytes/autosk/issues"},"keywords":["autosk","autosk-extension","autosk-agent"],"type":"module","publishConfig":{"access":"public"},"exports":{".":"./index.ts"},"types":"./index.ts","autosk":{"extensions":["./index.ts"]},"dependencies":{"@autosk/sdk":"^0.1.0"},"scripts":{"typecheck":"tsc --noEmit -p tsconfig.json"},"gitHead":"b5d78f7763df0ff90569610fbdc17ad54cc40674","_id":"@autosk/pi-agent@0.1.5","_nodeVersion":"24.18.0","_npmVersion":"12.0.1","dist":{"integrity":"sha512-pcRLaumVTiolB4ZLnq1lxPSVaeXYB8Ih2uhRTVAi7ntp92BQ4XalJ8aS0dDAlgmeRPC9z/WUPCjCCozj3R7GmQ==","shasum":"76876e5b4de88b00064dd5b26d872901aceb18e7","tarball":"https://registry.npmjs.org/@autosk/pi-agent/-/pi-agent-0.1.5.tgz","fileCount":8,"unpackedSize":84076,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@autosk%2fpi-agent@0.1.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAUZgHkFupARkAMRVqXiAKOoMzsLD5GJ44+VU1DnhFmvAiALmwFt2tRThFXigmrGIcyyHoOUVRXAlPpVwVcue8NE7A=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:92ba6731-47ff-48e0-86e8-3a867a090d04"}},"directories":{},"maintainers":[{"name":"wierdbytes","email":"wb@xff.pw"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-agent_0.1.5_1785175429873_0.7311104490593723"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-14T19:18:09.889Z","modified":"2026-07-27T18:03:50.417Z","0.1.0":"2026-06-14T19:18:10.163Z","0.1.1":"2026-06-14T22:24:25.621Z","0.1.2":"2026-06-17T18:39:36.649Z","0.1.3":"2026-06-17T22:02:51.516Z","0.1.4":"2026-06-22T22:32:24.771Z","0.1.5":"2026-07-27T18:03:50.030Z"},"bugs":{"url":"https://github.com/wierdbytes/autosk/issues"},"author":{"name":"wierdbytes"},"license":"MIT","homepage":"https://github.com/wierdbytes/autosk#readme","keywords":["autosk","autosk-extension","autosk-agent"],"repository":{"type":"git","url":"git+https://github.com/wierdbytes/autosk.git","directory":"daemon/extensions/pi-agent"},"description":"autosk extension that drives `pi --mode rpc` as an agent (model/thinking/first_message, kickback loop, autosk_transit pi-tool bridge).","maintainers":[{"name":"wierdbytes","email":"wb@xff.pw"}],"readme":"# @autosk/pi-agent\n\nDrive [`pi`](https://github.com/earendil-works/pi) (`pi --mode rpc`) as an\nautoskd v2 **agent**. `piAgent({...})` returns an\n[`AgentDefinition`](../../sdk/src/agent.ts) the engine can run for a workflow\nstep; it ports v1's \"standard branch\" (spawn pi, seed the first message, drive\nturns, kickback loop) onto the v2 `ctx.spawn` + `ctx.transit` API (design\n`docs/plans/20260612-Bun-Daemon-Extensions.md` §3.4).\n\n## Usage\n\n```ts\nimport { piAgent } from \"@autosk/pi-agent\";\nimport { sandboxCleanupStep, worktreeSandbox } from \"@autosk/sandbox\";\nimport { statusStep } from \"@autosk/sdk\";\n\nexport default function (autosk) {\n  const sandbox = worktreeSandbox(); // or dockerSandbox({ image })\n  autosk.registerWorkflow({\n    name: \"my-flow\",\n    firstStep: \"dev\",\n    steps: {\n      // The step key IS the agent name; registering the workflow registers\n      // its inline agents. Each runs its harness in the per-task `sandbox`.\n      dev: piAgent({\n        sandbox,\n        model: \"sonnet:high\",\n        firstMessageFile: new URL(\"./prompts/dev.md\", import.meta.url).pathname,\n      }),\n      review: piAgent({ sandbox, thinking: \"xhigh\", firstMessageFile: \".../review.md\" }),\n      accept: statusStep(\"human\"),\n      // Teardown is a normal step (no engine reap): route terminals through it.\n      cleanup: sandboxCleanupStep(sandbox),\n    },\n  });\n}\n```\n\nA `piAgent({...})` is an inline **step value**: the step key is the agent name\n(there is no `name` option — the driver takes its display name from\n`ctx.workflows.current.step`), so registering the workflow registers its agents.\n\n## How it works\n\nOn each `onRun` the agent:\n\n1. spawns `pi --mode rpc` (with the role's `model` / `thinking` / extra args)\n   and **injects a pi extension** that registers an `autosk_transit` tool. The\n   spawn env also carries `AUTOSK_CWD` (the canonical project root, from\n   `ctx.projectRoot`) and `AUTOSK_AGENT` (the step name), so any `autosk` CLI\n   the agent runs — directly, or via the `@autosk/pi-tools` `autosk_task` /\n   `autosk_comment` tools — targets the task's own project and attributes\n   comments to the step, even when the run is in a throwaway worktree;\n2. seeds pi with the rendered step prompt (role first-message + task context +\n   the available transitions + \"call `autosk_transit`\");\n3. mirrors pi's session entries (messages / custom) into the autosk transcript\n   1:1, so existing pi renderers stay reusable; while a turn streams it also\n   forwards pi's `message_update` events as **ephemeral partial snapshots** via\n   `ctx.partial(m)` (coalesced ~40 ms), so a client renders the in-progress\n   assistant message live before the durable line commits (see [docs/daemon.md →\n   Streaming partial messages](../../../docs/daemon.md#streaming-partial-messages));\n4. **observes the `autosk_transit` tool call** on pi's RPC event stream and\n   translates it into `ctx.transit(...)` (the transit channel — core stays\n   closed, no session-scoped daemon RPC);\n5. runs a **kickback/corrections loop** (private to this extension): if a turn\n   ends without a transit — or a chosen transition is rejected by the workflow's\n   `onTransit` — it feeds a corrective message back to the model and retries, up\n   to `maxCorrections` times. After the budget is spent it returns without a\n   transit and the engine parks the task (`agent_did_not_transit`).\n\n`onSteer` / `onFollowup` forward a `session.input` message into the **live** pi;\n`onAbort` asks pi to wind down gracefully (the engine's abort signal already\nterminates the child).\n\n### Run state & turn boundaries (`agent_end` vs `agent_settled`)\n\npi keeps ONE run-active flag for a whole `prompt()` cycle and rejects a fresh\n`{type:\"prompt\"}` with *\"Agent is already processing\"* while it is set. The flag\ngoes up at `agent_start` and comes down only in `_runAgentPrompt`'s `finally`,\nwhich emits **`agent_settled`** — after pi's *post-run phase* (retry backoff,\nauto-compaction, queued-message drain), each round of which emits its own EXTRA\n`agent_start`/`agent_end` pair. So `agent_end` means \"the assistant response\nfinished streaming\", NOT \"pi is promptable again\", and a kickback sent at\n`agent_end` can land in that window and fail the session\n([#19](https://github.com/wierdbytes/autosk/issues/19)).\n\nThe driver therefore splits the two:\n\n| pi event        | driver reaction                                                                                          |\n| --------------- | -------------------------------------------------------------------------------------------------------- |\n| `agent_start`   | `onActivity(true)`; pi is streaming, bare prompts are refused.                                             |\n| `agent_end`     | **presentation only** — flush partial snapshots, `onActivity(false)` (the chat UI goes idle).             |\n| `agent_settled` | **the turn boundary** — clear `streaming`, open the prompt gate, resolve exactly one `waitForTurnEnd()`. |\n\nWhat that means for anyone reading or reusing `PiDriver`:\n\n- **`waitForTurnEnd()` resolves once per PROMPT CYCLE**, at `agent_settled` — not\n  once per `agent_end` (its pre-0.1.5 semantics). A cycle is opened by an\n  *accepted* `prompt`, so the post-run phase's extra `agent_start`/`agent_end`\n  pairs can never enqueue a phantom turn-end — nor burn a `maxCorrections` slot.\n- **`sendPrompt()` waits for that gate** before writing. If pi still answers\n  \"already processing\", the driver treats the rejection as ground truth (pi IS\n  running), heals its view and re-waits for the real boundary rather than\n  sleeping a fixed amount.\n- **Steer / followup inside the window** dispatch as `steer` / `follow_up` (which\n  pi queues and drains post-run) instead of a doomed `prompt`, because the\n  driver's `streaming` flag now mirrors pi's `isStreaming` exactly.\n- **Legacy pi builds** that never emit `agent_settled` are feature-detected per\n  child: after a grace with no `agent_settled` the driver falls back to the old\n  `agent_end` boundary. The grace is extended by an announced\n  `auto_retry_start.delayMs` and suspended for a `compaction_start`…\n  `compaction_end` bracket, and a late `agent_settled` (or a busy rejection)\n  un-learns a wrong verdict.\n- **No hangs:** the gate and `waitForTurnEnd()` are released unconditionally on\n  child exit and on abort; a `sendPrompt` against a dead pi fails fast.\n\npi's side of this contract is written up in\n[`docs/notes/pi-rpc-contract.md`](../../../docs/notes/pi-rpc-contract.md); the\nfull rationale (and the exact pi source lines it rests on) lives in the\n`PiDriver` class doc comment in `src/driver.ts`.\n\n## Interactive (chat) mode\n\nBesides backing a workflow step, this package's **default export** registers a\nnamed agent, `\"pi\"`, via `autosk.registerAgent(...)`, so the daemon can open an\n**interactive (taskless) chat session** against it (see\n[docs/daemon.md → Interactive sessions](../../../docs/daemon.md#interactive-taskless-sessions)).\n`onRun` branches on `ctx.mode`:\n\n- `\"task\"` — the workflow transit loop above (unchanged).\n- `\"interactive\"` — a chat loop: spawn `pi --mode rpc` **without** the\n  `autosk_transit` extension (transit is unavailable in a chat, so the tool is\n  not offered), send **no** initial prompt (the session is empty until the user\n  types), then await `ctx.signal`. Each composer message arrives via `onFollowup`\n  and is forwarded to the live pi (idle → a fresh turn, streaming → a follow-up).\n  The agent returns when the signal fires; the engine seals the session `done`\n  (graceful end), `aborted` (abort), or `failed` (crash) — no transit, no park.\n\n## Configuration — `PiAgentOptions`\n\nThe agent name is **not** an option — it is the workflow step key the `piAgent`\nis assigned to (taken from `ctx.workflows.current.step` at run time).\n\n| Option             | Default                       | Description                                                              |\n| ------------------ | ----------------------------- | ------------------------------------------------------------------------ |\n| `model`            | pi default                    | pi model spec, e.g. `\"sonnet:high\"` (`--model`).                          |\n| `thinking`         | pi default                    | Thinking level `off`…`xhigh` (`--thinking`).                             |\n| `firstMessage`     | `\"\"`                          | Inline first-message seed (wins over `firstMessageFile`).                |\n| `firstMessageFile` | —                             | Path to a file whose contents seed the first message.                   |\n| `extraArgs`        | `[]`                          | Extra args forwarded verbatim to `pi`.                                   |\n| `piExtensions`     | `[]`                          | pi extensions to load (`-e <path>` each).                                |\n| `piSkills`         | `[]`                          | pi skills to enable (`--skill <name>` each).                            |\n| `maxCorrections`   | `3`                           | Corrective turns before giving up (then the engine parks the task).     |\n| `piBin`            | `$AUTOSK_PI_BIN` or `\"pi\"`    | `pi` binary to spawn (the e2e tests point this at a stub).              |\n\n## The injected `autosk_transit` tool\n\n`src/pi-transit-extension.ts` is the pi extension this package injects via\n`pi -e`. It registers the `autosk_transit` tool (one `to` string: a sibling step\nname, or `done` | `cancel` | `human`). The tool returns an immediate ack; the\nreal transition (and any rejection fed back as a correction) is driven by the\nautosk daemon, which observes the call on pi's RPC event stream. That file is\nloaded by **pi's** toolchain, not the daemon, so it is excluded from this\npackage's `tsc` typecheck.\n\n## Tool surface under a sandbox\n\nThe agent ALWAYS injects only the ack-only `autosk_transit` extension;\n`autosk_task` / `autosk_comment` come from the single, **transport-aware**\n[`@autosk/pi-tools`](https://www.npmjs.com/package/@autosk/pi-tools) extension pi\nloads from its own config. The `sandbox?` option (a `Sandbox` from\n`@autosk/sandbox`, or any structural sandbox) decides where the harness runs AND\nwhich TRANSPORT pi-tools uses:\n\n- **host / `worktreeSandbox`** (not thin): pi runs on the host at the worktree\n  (`~/.autosk/worktrees/<slug>/<task>`); no MCP env is set, so `@autosk/pi-tools`\n  shells out to the `autosk` CLI. The daemon sets **`AUTOSK_CWD`**\n  (= `ctx.projectRoot`) so those calls resolve the original project, not the\n  worktree.\n- **`dockerSandbox`** (thin — `sandbox.thin === true`): the agent mints a\n  per-session HTTP MCP server (`ctx.newMCPServer()`) and injects\n  `AUTOSK_MCP_URL` (rewritten to `host.docker.internal` via\n  `sandbox.endpointFor(port)`) + `AUTOSK_MCP_TOKEN`, so the same\n  `@autosk/pi-tools` POSTs `autosk_task`/`autosk_comment` to it instead of\n  shelling out — the image needs neither `autosk` nor a mounted socket. The\n  sandbox bind-mounts the injected transit extension so `pi -e <path>` resolves\n  inside the container.\n\n## Exports\n\n- `piAgent(options)` → `AgentDefinition`\n- `buildPiCommand(options, { interactive? })` (the `interactive` flag skips the\n  injected transit extension; task/comment always come from `@autosk/pi-tools`),\n  `PiDriver` (note the `waitForTurnEnd()` semantics above — one resolve per\n  prompt cycle, at `agent_settled`),\n  `parseTarget`, `buildInputCommand`, `isStateMismatch`, `isBusyRejection`,\n  the prompt renderers\n  (`renderInitialPrompt`, `kickbackMessage`, `rejectionMessage`, `targetLabels`)\n  — exported for tooling / tests.\n- default export — an extension factory that registers the named `\"pi\"` agent for\n  interactive chat sessions. (Workflow roles are still registered separately, by\n  the consuming extension, e.g. `@autosk/feature-dev`, as inline `piAgent({...})`\n  step values.)\n","readmeFilename":"README.md"}