{"_id":"@autosk/claude-agent","_rev":"2-4e3bef43cf7c47f808ad7a66e4b913e7","name":"@autosk/claude-agent","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@autosk/claude-agent","version":"0.1.0","keywords":["autosk","autosk-extension","autosk-agent"],"author":{"name":"wierdbytes"},"license":"MIT","_id":"@autosk/claude-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":"28c50b25704d0e2e5a2ee0b3fd0dc3d00f01869e","tarball":"https://registry.npmjs.org/@autosk/claude-agent/-/claude-agent-0.1.0.tgz","fileCount":8,"integrity":"sha512-E5gMNHXDFDFru04Csa3muc36BDKqqqibpdJEFaru2MNZcQe5Etxtp00q33AdfI2pwAh9OkeQ5XnclaYDHooUaw==","signatures":[{"sig":"MEUCIQDs3tCWo0PrX+ypTVd0HLWQZ0cCNBry9KueFckcqu3e2wIgMecoTUmC2kLI2UwOJU+m3jD0Kybvi3CRDR1765lHoJA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63615},"type":"module","types":"./index.ts","autosk":{"extensions":["./index.ts"]},"exports":{".":"./index.ts"},"gitHead":"505c70bc48c36b4ecdfc022f9aedb85e7b66653f","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/claude-agent"},"_npmVersion":"11.9.0","description":"autosk extension that drives Claude Code (`claude -p` headless stream-json) as an agent (kickback loop, an autosk MCP server for transit/task/comment).","directories":{},"_nodeVersion":"25.6.1","dependencies":{"@autosk/sdk":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-agent_0.1.0_1781824162610_0.1763241022910813","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@autosk/claude-agent","version":"0.1.1","description":"autosk extension that drives Claude Code (`claude -p` headless stream-json) as an agent (kickback loop, an autosk MCP server for transit/task/comment).","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/claude-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":"6e4189216039fd42317f92d84106b7415ac1e9dd","_id":"@autosk/claude-agent@0.1.1","_nodeVersion":"25.6.1","_npmVersion":"11.9.0","dist":{"integrity":"sha512-DGJ48jhg76QoGxb5PaEMjZB47njDesJ59gUoYEPocn14nspD8eKIfEjEqSUMdzzpPyztVGd8v6T2n8LaddFFRA==","shasum":"4c5d149ada21cb2b980399fe78c1f292cd4d484d","tarball":"https://registry.npmjs.org/@autosk/claude-agent/-/claude-agent-0.1.1.tgz","fileCount":8,"unpackedSize":66517,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBNkPrtpMVRBj/WqqDGhIFJ/mBwndXjTYNzdrgwpopJ/AiA0mVjdKaazvaA3NIq1WZJYmheSbkkSItzZMKfkTIV0TQ=="}]},"_npmUser":{"name":"wierdbytes","email":"wb@xff.pw"},"directories":{},"maintainers":[{"name":"wierdbytes","email":"wb@xff.pw"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/claude-agent_0.1.1_1782167547623_0.1467497600409109"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-18T23:09:22.447Z","modified":"2026-06-22T22:32:27.896Z","0.1.0":"2026-06-18T23:09:22.867Z","0.1.1":"2026-06-22T22:32:27.767Z"},"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/claude-agent"},"description":"autosk extension that drives Claude Code (`claude -p` headless stream-json) as an agent (kickback loop, an autosk MCP server for transit/task/comment).","maintainers":[{"name":"wierdbytes","email":"wb@xff.pw"}],"readme":"# @autosk/claude-agent\n\nDrive [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (`claude -p`\nheadless stream-json mode) as an autoskd v2 **agent**. `claudeAgent({...})`\nreturns an [`AgentDefinition`](../../sdk/src/agent.ts) the engine can run for a\nworkflow step — the structural twin of [`@autosk/pi-agent`](../pi-agent/README.md),\nwith Claude Code as the harness instead of `pi --mode rpc` (design\n`docs/plans/20260618-Claude-Code-Agent.md`).\n\n## Usage\n\n```ts\nimport { claudeAgent } from \"@autosk/claude-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: claudeAgent({\n        sandbox,\n        model: \"sonnet\",\n        firstMessageFile: new URL(\"./prompts/dev.md\", import.meta.url).pathname,\n      }),\n      review: claudeAgent({ sandbox, 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 `claudeAgent({...})` is an inline **step value**: the step key is the agent\nname (there is no `name` option — the driver takes its display name from\n`ctx.workflows.current.step`), so registering the workflow registers its agents.\nIt is **not** bootstrapped by the reference `feature-dev` workflow — it is an\nopt-in alternative harness you wire into your own workflow (or replace\n`feature-dev`'s `piAgent({...})` roles with).\n\n### Requirements\n\n- **`claude`** (the Claude Code CLI) on `PATH`, or pointed at by\n  `$AUTOSK_CLAUDE_BIN` / the `claudeBin` option. The headless run is unattended,\n  so Claude Code must be already authenticated.\n- **No `autosk`/`autoskd` in the run environment.** The tool surface is the\n  per-session, host-side HTTP MCP server the daemon mints (`ctx.newMCPServer()`),\n  reached by Claude over `--mcp-config type:\"http\"` with a bearer token — so a\n  containerized run (`dockerSandbox`) needs neither the CLI nor a mounted daemon\n  socket; it reaches the host server via `host.docker.internal`.\n\n## How it works\n\nOn each `onRun` (task mode) the agent:\n\n1. spawns\n   `claude -p --output-format stream-json --input-format stream-json --verbose\n   --include-partial-messages --replay-user-messages` (with the role's `model` /\n   permission posture / extra args), registering **one HTTP `autosk` MCP server**\n   via an inline `--mcp-config` of shape\n   `{ mcpServers: { autosk: { type: \"http\", url, headers: { Authorization: \"Bearer <token>\" } } } }`.\n   The `url`/`token` come from `ctx.newMCPServer()` (a per-session host-side\n   server); under a `sandbox` the host is rewritten via `sandbox.endpointFor(port)`\n   (e.g. `host.docker.internal`). The model sees `mcp__autosk__transit`,\n   `mcp__autosk__task`, and `mcp__autosk__comment`; those three tools are\n   auto-added to `--allowedTools` so a headless `acceptEdits` run never silently\n   aborts on a permission prompt for them. The spawn env carries `AUTOSK_CWD`\n   (the canonical project root, from `ctx.projectRoot`) and `AUTOSK_AGENT` (the\n   step name) for any host-side `autosk` the model runs via bash; the MCP tool\n   surface itself is server-bound and needs no env and no mounted socket;\n2. seeds Claude with the rendered step prompt (role first-message + task context +\n   the available transitions + \"call `mcp__autosk__transit`\");\n3. mirrors Claude's `assistant` / `user` stream entries (text / thinking /\n   tool_use / tool_result) into the autosk transcript 1:1 (see\n   [`src/wire.ts`](src/wire.ts)), so existing pi-format renderers stay reusable;\n   while a turn streams it also coalesces `stream_event` deltas into a cumulative\n   assistant snapshot forwarded via `ctx.partial(m)` (~40 ms), so a client renders\n   the in-progress message live before the durable line commits (see [docs/daemon.md →\n   Streaming partial messages](../../../docs/daemon.md#streaming-partial-messages));\n4. **observes the `mcp__autosk__transit` tool call** on Claude's stream and\n   translates it into `ctx.transit(...)`. The MCP `transit` tool only *acks*; the\n   driver — not the MCP server — drives the real transition (parity with\n   pi-agent's `autosk_transit`). `task` / `comment` calls are **not** special-cased:\n   they execute for real in the MCP server and flow through as ordinary\n   tool_use / tool_result transcript lines;\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` forwards a `session.input` message into the **live** Claude — idle → a\nfresh turn; mid-turn → a stream-json `interrupt` control request followed by the\nmessage. `onFollowup` does the same when idle, and **queues after the current\nturn** when one is streaming (Claude's stream-json input has no mid-turn\nfollow-up command, only `interrupt`). `onAbort` asks Claude to wind down\ngracefully (the engine's abort signal already terminates the child).\n\n## Interactive (chat) mode\n\nBesides backing a workflow step, this package's **default export** registers a\nnamed agent, `\"@autosk/claude-agent\"`, via `autosk.registerAgent(...)`, so the\ndaemon can open an **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 `claude -p` stream-json with the `autosk`\n  MCP server but **without** the `transit` tool (transit is unavailable in a\n  chat, so it is not advertised), send **no** initial prompt (the session is\n  empty until the user types), wire turn boundaries to `ctx.setActivity`\n  (busy / idle), then await `ctx.signal`. Each composer message arrives via\n  `onFollowup` and is forwarded to the live Claude. The agent returns when the\n  signal fires; the engine seals the session `done` (graceful end), `aborted`\n  (abort), or `failed` (crash) — no transit, no park.\n\n## Configuration — `ClaudeAgentOptions`\n\nThe agent name is **not** an option — it is the workflow step key the\n`claudeAgent` is assigned to (taken from `ctx.workflows.current.step` at run\ntime).\n\n| Option                       | Default                          | Description                                                                                  |\n| ---------------------------- | -------------------------------- | -------------------------------------------------------------------------------------------- |\n| `model`                      | Claude Code default              | Model alias/name, e.g. `\"sonnet\"` / `\"opus\"` (`--model`).                                     |\n| `effort`                     | Claude Code default              | Effort level (`--effort`): `low` / `medium` / `high` / `xhigh` / `max` (levels depend on the model). |\n| `firstMessage`               | `\"\"`                             | Inline first-message seed (wins over `firstMessageFile`).                                     |\n| `firstMessageFile`           | —                                | Path to a file whose contents seed the first message.                                         |\n| `appendSystemPrompt`         | —                                | Role guidance appended to the system prompt (`--append-system-prompt`).                       |\n| `permissionMode`             | `\"acceptEdits\"`                  | Unattended permission mode (`--permission-mode`); must be non-interactive-safe.               |\n| `dangerouslySkipPermissions` | `false`                          | Skip all permission prompts (`--dangerously-skip-permissions`); wins over `permissionMode`.   |\n| `allowedTools`               | `[]`                             | Auto-approved tools (`--allowedTools`); the autosk MCP tools are added automatically.         |\n| `disallowedTools`            | `[]`                             | Denied tools (`--disallowedTools`).                                                           |\n| `bare`                       | `false`                          | `--bare` for hermetic runs (skip project `CLAUDE.md` / `.mcp.json` / hooks discovery).        |\n| `autoskTools`                | `true`                           | Register the `autosk` MCP server. `false` omits `--mcp-config` (no transit → the run parks).  |\n| `extraArgs`                  | `[]`                             | Extra args forwarded verbatim to `claude`.                                                    |\n| `maxCorrections`             | `3`                              | Corrective turns before giving up (then the engine parks the task).                           |\n| `claudeBin`                  | `$AUTOSK_CLAUDE_BIN` or `\"claude\"` | `claude` binary to spawn (the e2e tests point this at a stub).                              |\n\n## The `autosk` MCP server\n\nThe tool surface is the **per-session, host-side HTTP MCP server** the daemon\nmints via `ctx.newMCPServer()` (a hand-rolled `Bun.serve()` endpoint with no\n`@modelcontextprotocol/sdk` dependency, so it survives `bun build --compile`).\nClaude reaches it via an inline `--mcp-config` of `type:\"http\"` carrying a\nper-session bearer token; the server binds an ephemeral port and 401s a\nwrong/missing bearer. It advertises up to three tools:\n\n- **`transit`** — *ack-only*, advertised only in task mode (the server is bound\n  that way). The tool returns an immediate ack; the **driver** observes the\n  `tool_use` on Claude's stream and drives the real `ctx.transit`, feeding any\n  `onTransit` rejection back as a corrective message.\n- **`task`** — `create` / `update` / `show` / `list`, the direct analog of\n  `@autosk/pi-tools`' `autosk_task` (schemas + descriptions match it verbatim).\n- **`comment`** — `add` / `list`, the analog of `@autosk/pi-tools`'\n  `autosk_comment`; `add` defaults the author to the running step.\n\n`task` / `comment` **execute for real** against the daemon's own store (the\ndirect-store backend), so there is no `autosk` child process and no mounted\ndaemon socket. The standalone [`autoskd mcp`](../../../docs/daemon.md#the-autoskd-mcp-tool-server)\nstdio subcommand still exists for external use (it shells out to `autosk … --json`).\n\n## Project resolution under a sandbox\n\nUnder a `worktreeSandbox` the agent runs in `~/.autosk/worktrees/<slug>/<task>`,\nand under a `dockerSandbox` it runs inside a `docker run -i --rm` container; in\neither case `ctx.cwd` stays the canonical project root and the harness runs at\nthe workspace dir. The MCP tool surface is server-bound (the daemon already\nknows the project + author for the session), so task/comment calls resolve the\noriginal project with no `AUTOSK_CWD`/`AUTOSK_SOCK` plumbing into the harness; a\ncontainer reaches the host server over `host.docker.internal` with the bearer.\n\n## Exports\n\n- `claudeAgent(options)` → `AgentDefinition`\n- `buildClaudeCommand(options, { mcpConfig?, interactive? })`,\n  `buildMcpConfig(url, token)`, `autoskEnv(ctx)`,\n  `ClaudeDriver`, `Coalescer`, `parseTarget`, `stripAnsi`, `TRANSIT_TOOL_NAME`\n- the wire mappers (`mapAssistant`, `mapUser`, `mapResultUsage`, `mapStopReason`,\n  `mapUsage`) and the prompt renderers (`renderInitialPrompt`, `kickbackMessage`,\n  `rejectionMessage`, `targetLabel`, `targetLabels`) — exported for tooling / tests.\n- default export — an extension factory that registers the named\n  `\"@autosk/claude-agent\"` agent for interactive chat sessions. (Workflow roles\n  are still registered separately, by the consuming extension, as inline\n  `claudeAgent({...})` step values.)\n","readmeFilename":"README.md"}