@ai-hero/sandcastle 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +160 -31
  2. package/dist/AgentProvider.d.ts +28 -4
  3. package/dist/AgentProvider.d.ts.map +1 -1
  4. package/dist/AgentProvider.js +193 -49
  5. package/dist/AgentProvider.js.map +1 -1
  6. package/dist/InitService.d.ts +16 -3
  7. package/dist/InitService.d.ts.map +1 -1
  8. package/dist/InitService.js +166 -19
  9. package/dist/InitService.js.map +1 -1
  10. package/dist/Orchestrator.d.ts +9 -34
  11. package/dist/Orchestrator.d.ts.map +1 -1
  12. package/dist/Orchestrator.js +38 -105
  13. package/dist/Orchestrator.js.map +1 -1
  14. package/dist/SandboxFactory.d.ts +14 -5
  15. package/dist/SandboxFactory.d.ts.map +1 -1
  16. package/dist/SandboxFactory.js +86 -36
  17. package/dist/SandboxFactory.js.map +1 -1
  18. package/dist/WorktreeManager.d.ts +10 -5
  19. package/dist/WorktreeManager.d.ts.map +1 -1
  20. package/dist/WorktreeManager.js +13 -8
  21. package/dist/WorktreeManager.js.map +1 -1
  22. package/dist/cli.d.ts +3 -0
  23. package/dist/cli.d.ts.map +1 -1
  24. package/dist/cli.js +75 -27
  25. package/dist/cli.js.map +1 -1
  26. package/dist/createSandbox.d.ts +82 -0
  27. package/dist/createSandbox.d.ts.map +1 -0
  28. package/dist/createSandbox.js +192 -0
  29. package/dist/createSandbox.js.map +1 -0
  30. package/dist/index.d.ts +5 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +2 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/run.d.ts +22 -6
  35. package/dist/run.d.ts.map +1 -1
  36. package/dist/run.js +36 -31
  37. package/dist/run.js.map +1 -1
  38. package/dist/templates/blank/.env.example +4 -0
  39. package/dist/templates/blank/main.ts +2 -1
  40. package/dist/templates/parallel-planner/.env.example +4 -0
  41. package/dist/templates/parallel-planner/main.ts +4 -4
  42. package/dist/templates/sequential-reviewer/.env.example +4 -0
  43. package/dist/templates/sequential-reviewer/main.ts +3 -3
  44. package/dist/templates/simple-loop/.env.example +4 -0
  45. package/dist/templates/simple-loop/main.ts +6 -5
  46. package/package.json +2 -2
package/README.md CHANGED
@@ -6,7 +6,15 @@
6
6
  </picture>
7
7
  </div>
8
8
 
9
- A TypeScript library for orchestrating AI coding agents in isolated Docker containers. Sandcastle handles the hard parts — building worktrees, invoking the agent, and merging commits back — so you can run AFK agents with a single `run()`.
9
+ ## What Is Sandcastle?
10
+
11
+ A TypeScript library for orchestrating AI coding agents in isolated Docker containers:
12
+
13
+ 1. You invoke agents with a single `sandcastle.run()`.
14
+ 2. Sandcastle handles building worktrees and sandboxing the agent.
15
+ 3. The commits made on the branches get merged back.
16
+
17
+ Great for parallelizing multiple AFK agents, creating review pipelines, or even just orchestrating your own agents.
10
18
 
11
19
  ## Prerequisites
12
20
 
@@ -41,9 +49,10 @@ npx tsx .sandcastle/main.ts
41
49
 
42
50
  ```typescript
43
51
  // 3. Run the agent via the JS API
44
- import { run } from "@ai-hero/sandcastle";
52
+ import { run, claudeCode } from "@ai-hero/sandcastle";
45
53
 
46
54
  await run({
55
+ agent: claudeCode("claude-opus-4-6"),
47
56
  promptFile: ".sandcastle/prompt.md",
48
57
  });
49
58
  ```
@@ -53,9 +62,10 @@ await run({
53
62
  Sandcastle exports a programmatic `run()` function for use in scripts, CI pipelines, or custom tooling.
54
63
 
55
64
  ```typescript
56
- import { run } from "@ai-hero/sandcastle";
65
+ import { run, claudeCode } from "@ai-hero/sandcastle";
57
66
 
58
67
  const result = await run({
68
+ agent: claudeCode("claude-opus-4-6"),
59
69
  promptFile: ".sandcastle/prompt.md",
60
70
  });
61
71
 
@@ -67,9 +77,12 @@ console.log(result.branch); // target branch name
67
77
  ### All options
68
78
 
69
79
  ```typescript
70
- import { run } from "@ai-hero/sandcastle";
80
+ import { run, claudeCode } from "@ai-hero/sandcastle";
71
81
 
72
82
  const result = await run({
83
+ // Agent provider — required. Pass a model string to claudeCode().
84
+ agent: claudeCode("claude-opus-4-6"),
85
+
73
86
  // Prompt source — provide one of these, not both:
74
87
  promptFile: ".sandcastle/prompt.md", // path to a prompt file
75
88
  // prompt: "Fix issue #42 in this repo", // OR an inline prompt string
@@ -82,11 +95,11 @@ const result = await run({
82
95
  // Maximum number of agent iterations to run before stopping. Default: 1
83
96
  maxIterations: 5,
84
97
 
85
- // Branch the agent commits to inside the sandbox.
86
- branch: "agent/fix-42",
87
-
88
- // Claude model passed to the agent. Default: "claude-opus-4-6"
89
- model: "claude-opus-4-6",
98
+ // Worktree mode for sandbox work. Defaults to { mode: 'temp-branch' }.
99
+ // { mode: 'none' } — bind-mount host working directory directly (no worktree).
100
+ // { mode: 'temp-branch' } — create a temp worktree, merge back.
101
+ // { mode: 'branch', branch } create a worktree on an explicit branch.
102
+ worktree: { mode: "branch", branch: "agent/fix-42" },
90
103
 
91
104
  // Docker image used for the sandbox. Default: "sandcastle:<repo-dir-name>"
92
105
  imageName: "sandcastle:local",
@@ -111,8 +124,8 @@ const result = await run({
111
124
  // Default: "<promise>COMPLETE</promise>"
112
125
  completionSignal: "<promise>COMPLETE</promise>",
113
126
 
114
- // Idle timeout in seconds — resets whenever the agent produces output. Default: 300 (5 minutes)
115
- idleTimeoutSeconds: 300,
127
+ // Idle timeout in seconds — resets whenever the agent produces output. Default: 600 (10 minutes)
128
+ idleTimeoutSeconds: 600,
116
129
  });
117
130
 
118
131
  console.log(result.iterationsRun); // number of iterations executed
@@ -121,6 +134,119 @@ console.log(result.commits); // array of { sha } for commits created
121
134
  console.log(result.branch); // target branch name
122
135
  ```
123
136
 
137
+ ### `createSandbox()` — reusable sandbox
138
+
139
+ Use `createSandbox()` when you need to run multiple agents (or multiple rounds of the same agent) inside a single sandbox. It creates the worktree and container once, and you call `sandbox.run()` as many times as you need. This avoids repeated container startup costs and keeps all runs on the same branch.
140
+
141
+ Use `run()` instead when you only need a single one-shot invocation — it handles sandbox lifecycle automatically.
142
+
143
+ #### Basic single-run usage
144
+
145
+ ```typescript
146
+ import { createSandbox, claudeCode } from "@ai-hero/sandcastle";
147
+
148
+ await using sandbox = await createSandbox({
149
+ branch: "agent/fix-42",
150
+ });
151
+
152
+ const result = await sandbox.run({
153
+ agent: claudeCode("claude-opus-4-6"),
154
+ prompt: "Fix issue #42 in this repo.",
155
+ });
156
+
157
+ console.log(result.commits); // [{ sha: "abc123" }]
158
+ ```
159
+
160
+ #### Multi-run implement-then-review
161
+
162
+ ```typescript
163
+ import { createSandbox, claudeCode } from "@ai-hero/sandcastle";
164
+
165
+ await using sandbox = await createSandbox({
166
+ branch: "agent/fix-42",
167
+ hooks: { onSandboxReady: [{ command: "npm install" }] },
168
+ });
169
+
170
+ // Step 1: implement
171
+ const implResult = await sandbox.run({
172
+ agent: claudeCode("claude-opus-4-6"),
173
+ promptFile: ".sandcastle/implement.md",
174
+ maxIterations: 5,
175
+ });
176
+
177
+ // Step 2: review on the same branch, same container
178
+ const reviewResult = await sandbox.run({
179
+ agent: claudeCode("claude-sonnet-4-6"),
180
+ prompt: "Review the changes and fix any issues.",
181
+ });
182
+ ```
183
+
184
+ Commits from all `run()` calls accumulate on the same branch. The sandbox container stays alive between runs, so installed dependencies and build artifacts persist.
185
+
186
+ #### Automatic cleanup with `await using`
187
+
188
+ `await using` calls `sandbox.close()` automatically when the block exits. If the worktree has uncommitted changes, it is preserved on disk; if clean, both container and worktree are removed.
189
+
190
+ #### Manual `close()` with `CloseResult`
191
+
192
+ ```typescript
193
+ const sandbox = await createSandbox({ branch: "agent/fix-42" });
194
+ // ... run agents ...
195
+ const closeResult = await sandbox.close();
196
+ if (closeResult.preservedWorktreePath) {
197
+ console.log(`Worktree preserved at ${closeResult.preservedWorktreePath}`);
198
+ }
199
+ ```
200
+
201
+ #### `CreateSandboxOptions`
202
+
203
+ | Option | Type | Default | Description |
204
+ | --------------- | -------- | ---------------------------- | ------------------------------------------------------------------- |
205
+ | `branch` | string | — | **Required.** Explicit branch for the worktree |
206
+ | `imageName` | string | `sandcastle:<repo-dir-name>` | Docker image name |
207
+ | `hooks` | object | — | Lifecycle hooks (`onSandboxReady`) — run once at creation time |
208
+ | `copyToSandbox` | string[] | — | Host-relative file paths to copy into the worktree at creation time |
209
+
210
+ #### `Sandbox`
211
+
212
+ | Property / Method | Type | Description |
213
+ | ----------------------- | -------------------------------------------------- | ------------------------------------------- |
214
+ | `branch` | string | The branch the worktree is on |
215
+ | `worktreePath` | string | Host path to the worktree |
216
+ | `run(options)` | `(SandboxRunOptions) => Promise<SandboxRunResult>` | Invoke an agent inside the existing sandbox |
217
+ | `close()` | `() => Promise<CloseResult>` | Tear down the container and worktree |
218
+ | `[Symbol.asyncDispose]` | `() => Promise<void>` | Auto teardown via `await using` |
219
+
220
+ #### `SandboxRunOptions`
221
+
222
+ | Option | Type | Default | Description |
223
+ | -------------------- | ------------------ | ----------------------------- | ------------------------------------------------------------------- |
224
+ | `agent` | AgentProvider | — | **Required.** Agent provider (e.g. `claudeCode("claude-opus-4-6")`) |
225
+ | `prompt` | string | — | Inline prompt (mutually exclusive with `promptFile`) |
226
+ | `promptFile` | string | — | Path to prompt file (mutually exclusive with `prompt`) |
227
+ | `promptArgs` | PromptArgs | — | Key-value map for `{{KEY}}` placeholder substitution |
228
+ | `maxIterations` | number | `1` | Maximum iterations to run |
229
+ | `completionSignal` | string \| string[] | `<promise>COMPLETE</promise>` | String(s) the agent emits to stop the iteration loop early |
230
+ | `idleTimeoutSeconds` | number | `600` | Idle timeout in seconds — resets on each agent output event |
231
+ | `name` | string | — | Display name for the run |
232
+ | `logging` | object | file (auto-generated) | `{ type: 'file', path }` or `{ type: 'stdout' }` |
233
+
234
+ #### `SandboxRunResult`
235
+
236
+ | Field | Type | Description |
237
+ | ------------------ | ----------- | ------------------------------------------------------------------ |
238
+ | `iterationsRun` | number | Number of iterations executed |
239
+ | `completionSignal` | string? | The matched completion signal string, or `undefined` if none fired |
240
+ | `stdout` | string | Combined agent output from all iterations |
241
+ | `commits` | `{ sha }[]` | Commits created during the run |
242
+ | `logFilePath` | string? | Path to the log file (only when logging to a file) |
243
+
244
+ #### `CloseResult`
245
+
246
+ | Field | Type | Description |
247
+ | ----------------------- | ------- | ------------------------------------------------------------------------ |
248
+ | `preservedWorktreePath` | string? | Host path to the preserved worktree, set when it had uncommitted changes |
249
+
124
250
  ## How it works
125
251
 
126
252
  Sandcastle uses a worktree-based architecture for agent execution:
@@ -130,7 +256,7 @@ Sandcastle uses a worktree-based architecture for agent execution:
130
256
  - **No sync needed**: Because the agent writes directly to the host filesystem, there are no sync-in or sync-out operations. Commits made by the agent are immediately visible on the host.
131
257
  - **Merge back**: After the run completes, the temp worktree branch is fast-forward merged back to the target branch, and the worktree is cleaned up.
132
258
 
133
- From your point of view, you just run `sandcastle.run({ branch: 'foo' })`, and get a commit on branch `foo` once it's complete. All 100% local.
259
+ From your point of view, you just run `sandcastle.run({ worktree: { mode: 'branch', branch: 'foo' } })`, and get a commit on branch `foo` once it's complete. All 100% local.
134
260
 
135
261
  ## Prompts
136
262
 
@@ -251,9 +377,12 @@ Select a template during `sandcastle init` when prompted, or re-run init in a fr
251
377
 
252
378
  Scaffolds the `.sandcastle/` config directory and builds the Docker image. This is the first command you run in a new repo.
253
379
 
254
- | Option | Required | Default | Description |
255
- | -------------- | -------- | ---------------------------- | ----------------- |
256
- | `--image-name` | No | `sandcastle:<repo-dir-name>` | Docker image name |
380
+ | Option | Required | Default | Description |
381
+ | -------------- | -------- | ---------------------------- | -------------------------------------------------------------------- |
382
+ | `--image-name` | No | `sandcastle:<repo-dir-name>` | Docker image name |
383
+ | `--agent` | No | Interactive prompt | Agent to use (`claude-code`, `pi`, `codex`) |
384
+ | `--model` | No | Agent's default model | Model to use (e.g. `claude-sonnet-4-6`). Defaults to agent's default |
385
+ | `--template` | No | Interactive prompt | Template to scaffold (e.g. `blank`, `simple-loop`) |
257
386
 
258
387
  Creates the following files:
259
388
 
@@ -262,7 +391,7 @@ Creates the following files:
262
391
  ├── Dockerfile # Sandbox environment (customize as needed)
263
392
  ├── prompt.md # Agent instructions
264
393
  ├── .env.example # Token placeholders
265
- └── .gitignore # Ignores .env, patches/, logs/
394
+ └── .gitignore # Ignores .env, logs/, worktrees/
266
395
  ```
267
396
 
268
397
  Errors if `.sandcastle/` already exists to prevent overwriting customizations.
@@ -286,21 +415,21 @@ Removes the Docker image.
286
415
 
287
416
  ### `RunOptions`
288
417
 
289
- | Option | Type | Default | Description |
290
- | -------------------- | ------------------ | ----------------------------- | --------------------------------------------------------------------------- |
291
- | `prompt` | string | — | Inline prompt (mutually exclusive with `promptFile`) |
292
- | `promptFile` | string | — | Path to prompt file (mutually exclusive with `prompt`) |
293
- | `maxIterations` | number | `1` | Maximum iterations to run |
294
- | `hooks` | object | | Lifecycle hooks (`onSandboxReady`) |
295
- | `branch` | string | — | Target branch for sandbox work |
296
- | `model` | string | `claude-opus-4-6` | Model to use for the agent |
297
- | `imageName` | string | `sandcastle:<repo-dir-name>` | Docker image name for the sandbox |
298
- | `name` | string | — | Display name for the run, shown as a prefix in log output |
299
- | `promptArgs` | PromptArgs | — | Key-value map for `{{KEY}}` placeholder substitution |
300
- | `copyToSandbox` | string[] | — | Host-relative file paths to copy into the worktree before start |
301
- | `logging` | object | file (auto-generated) | `{ type: 'file', path }` or `{ type: 'stdout' }` |
302
- | `completionSignal` | string \| string[] | `<promise>COMPLETE</promise>` | String or array of strings the agent emits to stop the iteration loop early |
303
- | `idleTimeoutSeconds` | number | `300` | Idle timeout in seconds — resets on each agent output event |
418
+ | Option | Type | Default | Description |
419
+ | -------------------- | ------------------ | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
420
+ | `agent` | AgentProvider | — | **Required.** Agent provider (e.g. `claudeCode("claude-opus-4-6")`, `pi("claude-sonnet-4-6")`, `codex("gpt-5.4-mini")`) |
421
+ | `prompt` | string | — | Inline prompt (mutually exclusive with `promptFile`) |
422
+ | `promptFile` | string | | Path to prompt file (mutually exclusive with `prompt`) |
423
+ | `maxIterations` | number | `1` | Maximum iterations to run |
424
+ | `hooks` | object | — | Lifecycle hooks (`onSandboxReady`) |
425
+ | `worktree` | WorktreeMode | `{ mode: 'temp-branch' }` | Worktree mode: `{ mode: 'none' }`, `{ mode: 'temp-branch' }`, or `{ mode: 'branch', branch }` |
426
+ | `imageName` | string | `sandcastle:<repo-dir-name>` | Docker image name for the sandbox |
427
+ | `name` | string | — | Display name for the run, shown as a prefix in log output |
428
+ | `promptArgs` | PromptArgs | — | Key-value map for `{{KEY}}` placeholder substitution |
429
+ | `copyToSandbox` | string[] | — | Host-relative file paths to copy into the worktree before start (not supported with `mode: 'none'`) |
430
+ | `logging` | object | file (auto-generated) | `{ type: 'file', path }` or `{ type: 'stdout' }` |
431
+ | `completionSignal` | string \| string[] | `<promise>COMPLETE</promise>` | String or array of strings the agent emits to stop the iteration loop early |
432
+ | `idleTimeoutSeconds` | number | `600` | Idle timeout in seconds — resets on each agent output event |
304
433
 
305
434
  ### `RunResult`
306
435
 
@@ -1,8 +1,32 @@
1
+ export interface TokenUsage {
2
+ readonly input_tokens: number;
3
+ readonly output_tokens: number;
4
+ readonly cache_read_input_tokens: number;
5
+ readonly cache_creation_input_tokens: number;
6
+ readonly total_cost_usd: number;
7
+ readonly num_turns: number;
8
+ readonly duration_ms: number;
9
+ }
10
+ export type ParsedStreamEvent = {
11
+ type: "text";
12
+ text: string;
13
+ } | {
14
+ type: "result";
15
+ result: string;
16
+ usage: TokenUsage | null;
17
+ } | {
18
+ type: "tool_call";
19
+ name: string;
20
+ args: string;
21
+ };
1
22
  export interface AgentProvider {
2
23
  readonly name: string;
3
- readonly envManifest: Record<string, string>;
4
- readonly dockerfileTemplate: string;
24
+ buildPrintCommand(prompt: string): string;
25
+ buildInteractiveArgs(prompt: string): string[];
26
+ parseStreamLine(line: string): ParsedStreamEvent[];
5
27
  }
6
- export declare const claudeCodeProvider: AgentProvider;
7
- export declare const getAgentProvider: (name: string) => AgentProvider;
28
+ export declare const DEFAULT_MODEL = "claude-opus-4-6";
29
+ export declare const pi: (model: string) => AgentProvider;
30
+ export declare const codex: (model: string) => AgentProvider;
31
+ export declare const claudeCode: (model: string) => AgentProvider;
8
32
  //# sourceMappingURL=AgentProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentProvider.d.ts","sourceRoot":"","sources":["../src/AgentProvider.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAqCD,eAAO,MAAM,kBAAkB,EAAE,aAShC,CAAC;AAMF,eAAO,MAAM,gBAAgB,iCAQ5B,CAAC"}
1
+ {"version":3,"file":"AgentProvider.d.ts","sourceRoot":"","sources":["../src/AgentProvider.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,2BAA2B,EAAE,MAAM,CAAC;IAC7C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAwFtD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1C,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC/C,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAAC;CACpD;AAED,eAAO,MAAM,aAAa,oBAAoB,CAAC;AAsD/C,eAAO,MAAM,EAAE,kCAcb,CAAC;AAwCH,eAAO,MAAM,KAAK,kCAchB,CAAC;AAMH,eAAO,MAAM,UAAU,kCAcrB,CAAC"}
@@ -1,54 +1,198 @@
1
- import { SANDBOX_WORKSPACE_DIR } from "./SandboxFactory.js";
2
- const CLAUDE_CODE_DOCKERFILE = `FROM node:22-bookworm
3
-
4
- # Install system dependencies
5
- RUN apt-get update && apt-get install -y \\
6
- git \\
7
- curl \\
8
- jq \\
9
- && rm -rf /var/lib/apt/lists/*
10
-
11
- # Install GitHub CLI
12
- RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \\
13
- | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \\
14
- && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \\
15
- | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \\
16
- && apt-get update && apt-get install -y gh \\
17
- && rm -rf /var/lib/apt/lists/*
18
-
19
- # Create a non-root user for Claude to run as
20
- RUN useradd -m -s /bin/bash agent
21
- USER agent
22
-
23
- # Install Claude Code CLI
24
- RUN curl -fsSL https://claude.ai/install.sh | bash
25
-
26
- # Add Claude to PATH
27
- ENV PATH="/home/agent/.local/bin:$PATH"
28
-
29
- WORKDIR /home/agent
30
-
31
- # In worktree sandbox mode, Sandcastle bind-mounts the git worktree at ${SANDBOX_WORKSPACE_DIR}
32
- # and overrides the working directory to ${SANDBOX_WORKSPACE_DIR} at container start.
33
- # Structure your Dockerfile so that ${SANDBOX_WORKSPACE_DIR} can serve as the project root.
34
- ENTRYPOINT ["sleep", "infinity"]
35
- `;
36
- export const claudeCodeProvider = {
37
- name: "claude-code",
38
- envManifest: {
39
- ANTHROPIC_API_KEY: "Anthropic API key",
40
- GH_TOKEN: "GitHub personal access token",
41
- },
42
- dockerfileTemplate: CLAUDE_CODE_DOCKERFILE,
1
+ const shellEscape = (s) => "'" + s.replace(/'/g, "'\\''") + "'";
2
+ const extractUsage = (obj) => {
3
+ const usage = obj.usage;
4
+ if (!usage ||
5
+ typeof usage.input_tokens !== "number" ||
6
+ typeof usage.output_tokens !== "number") {
7
+ return null;
8
+ }
9
+ return {
10
+ input_tokens: usage.input_tokens,
11
+ output_tokens: usage.output_tokens,
12
+ cache_read_input_tokens: typeof usage.cache_read_input_tokens === "number"
13
+ ? usage.cache_read_input_tokens
14
+ : 0,
15
+ cache_creation_input_tokens: typeof usage.cache_creation_input_tokens === "number"
16
+ ? usage.cache_creation_input_tokens
17
+ : 0,
18
+ total_cost_usd: typeof obj.total_cost_usd === "number" ? obj.total_cost_usd : 0,
19
+ num_turns: typeof obj.num_turns === "number" ? obj.num_turns : 0,
20
+ duration_ms: typeof obj.duration_ms === "number" ? obj.duration_ms : 0,
21
+ };
22
+ };
23
+ /** Maps allowlisted tool names to the input field containing the display arg */
24
+ const TOOL_ARG_FIELDS = {
25
+ Bash: "command",
26
+ WebSearch: "query",
27
+ WebFetch: "url",
28
+ Agent: "description",
29
+ };
30
+ const parseStreamJsonLine = (line) => {
31
+ if (!line.startsWith("{"))
32
+ return [];
33
+ try {
34
+ const obj = JSON.parse(line);
35
+ if (obj.type === "assistant" && Array.isArray(obj.message?.content)) {
36
+ const events = [];
37
+ const texts = [];
38
+ for (const block of obj.message.content) {
39
+ if (block.type === "text" && typeof block.text === "string") {
40
+ texts.push(block.text);
41
+ }
42
+ else if (block.type === "tool_use" &&
43
+ typeof block.name === "string" &&
44
+ block.input !== undefined) {
45
+ const argField = TOOL_ARG_FIELDS[block.name];
46
+ if (argField === undefined)
47
+ continue; // not allowlisted
48
+ const argValue = block.input[argField];
49
+ if (typeof argValue !== "string")
50
+ continue; // missing/wrong arg field
51
+ if (texts.length > 0) {
52
+ events.push({ type: "text", text: texts.join("") });
53
+ texts.length = 0;
54
+ }
55
+ events.push({
56
+ type: "tool_call",
57
+ name: block.name,
58
+ args: argValue,
59
+ });
60
+ }
61
+ }
62
+ if (texts.length > 0) {
63
+ events.push({ type: "text", text: texts.join("") });
64
+ }
65
+ return events;
66
+ }
67
+ if (obj.type === "result" && typeof obj.result === "string") {
68
+ return [{ type: "result", result: obj.result, usage: extractUsage(obj) }];
69
+ }
70
+ }
71
+ catch {
72
+ // Not valid JSON — skip
73
+ }
74
+ return [];
43
75
  };
44
- const AGENT_REGISTRY = {
45
- "claude-code": claudeCodeProvider,
76
+ export const DEFAULT_MODEL = "claude-opus-4-6";
77
+ // ---------------------------------------------------------------------------
78
+ // Pi agent provider
79
+ // ---------------------------------------------------------------------------
80
+ const parsePiStreamLine = (line) => {
81
+ if (!line.startsWith("{"))
82
+ return [];
83
+ try {
84
+ const obj = JSON.parse(line);
85
+ if (obj.type === "message_update" && Array.isArray(obj.content)) {
86
+ const texts = [];
87
+ for (const block of obj.content) {
88
+ if (block.type === "text_delta" && typeof block.text === "string") {
89
+ texts.push(block.text);
90
+ }
91
+ }
92
+ if (texts.length > 0) {
93
+ return [{ type: "text", text: texts.join("") }];
94
+ }
95
+ return [];
96
+ }
97
+ if (obj.type === "tool_execution_start") {
98
+ const toolName = obj.tool_name;
99
+ if (typeof toolName !== "string")
100
+ return [];
101
+ const argField = TOOL_ARG_FIELDS[toolName];
102
+ if (argField === undefined)
103
+ return [];
104
+ const input = obj.input;
105
+ if (!input)
106
+ return [];
107
+ const argValue = input[argField];
108
+ if (typeof argValue !== "string")
109
+ return [];
110
+ return [{ type: "tool_call", name: toolName, args: argValue }];
111
+ }
112
+ if (obj.type === "agent_end" &&
113
+ typeof obj.last_assistant_message === "string") {
114
+ return [
115
+ {
116
+ type: "result",
117
+ result: obj.last_assistant_message,
118
+ usage: extractUsage(obj),
119
+ },
120
+ ];
121
+ }
122
+ }
123
+ catch {
124
+ // Not valid JSON — skip
125
+ }
126
+ return [];
46
127
  };
47
- export const getAgentProvider = (name) => {
48
- const provider = AGENT_REGISTRY[name];
49
- if (!provider) {
50
- throw new Error(`Unknown agent provider: "${name}". Available providers: ${Object.keys(AGENT_REGISTRY).join(", ")}`);
128
+ export const pi = (model) => ({
129
+ name: "pi",
130
+ buildPrintCommand(prompt) {
131
+ return `pi -p --mode json --no-session --model ${shellEscape(model)} ${shellEscape(prompt)}`;
132
+ },
133
+ buildInteractiveArgs(_prompt) {
134
+ return ["pi", "--model", model];
135
+ },
136
+ parseStreamLine(line) {
137
+ return parsePiStreamLine(line);
138
+ },
139
+ });
140
+ // ---------------------------------------------------------------------------
141
+ // Codex agent provider
142
+ // ---------------------------------------------------------------------------
143
+ const parseCodexStreamLine = (line) => {
144
+ if (!line.startsWith("{"))
145
+ return [];
146
+ try {
147
+ const obj = JSON.parse(line);
148
+ // item.completed with agent_message → text + result
149
+ if (obj.type === "item.completed" &&
150
+ obj.item?.type === "agent_message" &&
151
+ typeof obj.item.content === "string") {
152
+ const text = obj.item.content;
153
+ return [
154
+ { type: "text", text },
155
+ { type: "result", result: text, usage: extractUsage(obj) },
156
+ ];
157
+ }
158
+ // item.started with command_execution → tool call
159
+ if (obj.type === "item.started" &&
160
+ obj.item?.type === "command_execution" &&
161
+ typeof obj.item.command === "string") {
162
+ return [{ type: "tool_call", name: "Bash", args: obj.item.command }];
163
+ }
164
+ // turn.completed → skip
165
+ }
166
+ catch {
167
+ // Not valid JSON — skip
51
168
  }
52
- return provider;
169
+ return [];
53
170
  };
171
+ export const codex = (model) => ({
172
+ name: "codex",
173
+ buildPrintCommand(prompt) {
174
+ return `codex exec --json --dangerously-bypass-approvals-and-sandbox -m ${shellEscape(model)} ${shellEscape(prompt)}`;
175
+ },
176
+ buildInteractiveArgs(_prompt) {
177
+ return ["codex", "--model", model];
178
+ },
179
+ parseStreamLine(line) {
180
+ return parseCodexStreamLine(line);
181
+ },
182
+ });
183
+ // ---------------------------------------------------------------------------
184
+ // Claude Code agent provider
185
+ // ---------------------------------------------------------------------------
186
+ export const claudeCode = (model) => ({
187
+ name: "claude-code",
188
+ buildPrintCommand(prompt) {
189
+ return `claude --print --verbose --dangerously-skip-permissions --output-format stream-json --model ${shellEscape(model)} -p ${shellEscape(prompt)}`;
190
+ },
191
+ buildInteractiveArgs(_prompt) {
192
+ return ["claude", "--dangerously-skip-permissions", "--model", model];
193
+ },
194
+ parseStreamLine(line) {
195
+ return parseStreamJsonLine(line);
196
+ },
197
+ });
54
198
  //# sourceMappingURL=AgentProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentProvider.js","sourceRoot":"","sources":["../src/AgentProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAQ5D,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yEA6B0C,qBAAqB;2CACnD,qBAAqB;sCAC1B,qBAAqB;;CAE1D,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAkB;IAC/C,IAAI,EAAE,aAAa;IAEnB,WAAW,EAAE;QACX,iBAAiB,EAAE,mBAAmB;QACtC,QAAQ,EAAE,8BAA8B;KACzC;IAED,kBAAkB,EAAE,sBAAsB;CAC3C,CAAC;AAEF,MAAM,cAAc,GAAkC;IACpD,aAAa,EAAE,kBAAkB;CAClC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAiB,EAAE;IAC9D,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,4BAA4B,IAAI,2BAA2B,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACpG,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC"}
1
+ {"version":3,"file":"AgentProvider.js","sourceRoot":"","sources":["../src/AgentProvider.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,24 @@
1
1
  import { FileSystem } from "@effect/platform";
2
2
  import { Effect } from "effect";
3
- import type { AgentProvider } from "./AgentProvider.js";
4
3
  export interface TemplateMetadata {
5
4
  name: string;
6
5
  description: string;
7
6
  }
8
7
  export declare const listTemplates: () => TemplateMetadata[];
9
- export declare function getNextStepsLines(template: string, provider: AgentProvider): string[];
10
- export declare const scaffold: (repoDir: string, provider: AgentProvider, templateName?: string) => Effect.Effect<void, Error, FileSystem.FileSystem>;
8
+ export interface AgentEntry {
9
+ readonly name: string;
10
+ readonly label: string;
11
+ readonly defaultModel: string;
12
+ readonly factoryImport: string;
13
+ readonly dockerfileTemplate: string;
14
+ }
15
+ export declare const listAgents: () => AgentEntry[];
16
+ export declare const getAgent: (name: string) => AgentEntry | undefined;
17
+ export declare function getNextStepsLines(template: string): string[];
18
+ export interface ScaffoldOptions {
19
+ agent: AgentEntry;
20
+ model: string;
21
+ templateName?: string;
22
+ }
23
+ export declare const scaffold: (repoDir: string, options: ScaffoldOptions) => Effect.Effect<void, Error, FileSystem.FileSystem>;
11
24
  //# sourceMappingURL=InitService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"InitService.d.ts","sourceRoot":"","sources":["../src/InitService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAOxD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAuBD,eAAO,MAAM,aAAa,0BAAsC,CAAC;AAEjE,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,aAAa,GACtB,MAAM,EAAE,CAyBV;AAyDD,eAAO,MAAM,QAAQ,wHA+CjB,CAAC"}
1
+ {"version":3,"file":"InitService.d.ts","sourceRoot":"","sources":["../src/InitService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAUhC,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAuBD,eAAO,MAAM,aAAa,0BAAsC,CAAC;AAMjE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AA6HD,eAAO,MAAM,UAAU,oBAAqC,CAAC;AAE7D,eAAO,MAAM,QAAQ,0CACwB,CAAC;AAM9C,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAoB5D;AAmGD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,QAAQ,kGA4CjB,CAAC"}