@procedures/claude-cli 0.0.0-stage → 0.4.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 (65) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/LICENSE +21 -0
  3. package/README.md +92 -2
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/events.d.ts +93 -0
  6. package/dist/events.d.ts.map +1 -0
  7. package/dist/events.js +153 -0
  8. package/dist/events.js.map +1 -0
  9. package/dist/executable.d.ts +28 -0
  10. package/dist/executable.d.ts.map +1 -0
  11. package/dist/executable.js +37 -0
  12. package/dist/executable.js.map +1 -0
  13. package/dist/index.d.ts +7 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +8 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/module.d.ts +19 -0
  18. package/dist/module.d.ts.map +1 -0
  19. package/dist/module.js +81 -0
  20. package/dist/module.js.map +1 -0
  21. package/dist/procedures/claude/cancel.d.ts +13 -0
  22. package/dist/procedures/claude/cancel.d.ts.map +1 -0
  23. package/dist/procedures/claude/cancel.js +15 -0
  24. package/dist/procedures/claude/cancel.js.map +1 -0
  25. package/dist/procedures/claude/follow.d.ts +15 -0
  26. package/dist/procedures/claude/follow.d.ts.map +1 -0
  27. package/dist/procedures/claude/follow.js +21 -0
  28. package/dist/procedures/claude/follow.js.map +1 -0
  29. package/dist/procedures/claude/index.d.ts +5 -0
  30. package/dist/procedures/claude/index.d.ts.map +1 -0
  31. package/dist/procedures/claude/index.js +5 -0
  32. package/dist/procedures/claude/index.js.map +1 -0
  33. package/dist/procedures/claude/read.d.ts +12 -0
  34. package/dist/procedures/claude/read.d.ts.map +1 -0
  35. package/dist/procedures/claude/read.js +14 -0
  36. package/dist/procedures/claude/read.js.map +1 -0
  37. package/dist/procedures/claude/start.d.ts +14 -0
  38. package/dist/procedures/claude/start.d.ts.map +1 -0
  39. package/dist/procedures/claude/start.js +26 -0
  40. package/dist/procedures/claude/start.js.map +1 -0
  41. package/dist/register.d.ts +6 -0
  42. package/dist/register.d.ts.map +1 -0
  43. package/dist/register.js +8 -0
  44. package/dist/register.js.map +1 -0
  45. package/dist/turn.d.ts +142 -0
  46. package/dist/turn.d.ts.map +1 -0
  47. package/dist/turn.js +208 -0
  48. package/dist/turn.js.map +1 -0
  49. package/dist/types.d.ts +61 -0
  50. package/dist/types.d.ts.map +1 -0
  51. package/dist/types.js +61 -0
  52. package/dist/types.js.map +1 -0
  53. package/package.json +78 -3
  54. package/src/events.ts +250 -0
  55. package/src/executable.ts +50 -0
  56. package/src/index.ts +7 -0
  57. package/src/module.ts +116 -0
  58. package/src/procedures/claude/cancel.ts +17 -0
  59. package/src/procedures/claude/follow.ts +26 -0
  60. package/src/procedures/claude/index.ts +4 -0
  61. package/src/procedures/claude/read.ts +16 -0
  62. package/src/procedures/claude/start.ts +28 -0
  63. package/src/register.ts +10 -0
  64. package/src/turn.ts +317 -0
  65. package/src/types.ts +142 -0
@@ -0,0 +1,14 @@
1
+ /**
2
+ * claude.start procedure
3
+ *
4
+ * This procedure starts one turn of the Claude Code CLI as a detached process that writes to a
5
+ * file. The turn continues when the host stops.
6
+ */
7
+ import { type Spawner } from "../../turn.js";
8
+ import type { ClaudeStartInput, ClaudeStartOutput } from "../../types.js";
9
+ /**
10
+ * This function starts a turn. The variables of `input.env` go on top of the environment of the
11
+ * host. It gives the process id and the output file of the turn.
12
+ */
13
+ export declare function claudeStart(input: ClaudeStartInput, spawner?: Spawner): Promise<ClaudeStartOutput>;
14
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/procedures/claude/start.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE1E;;;GAGG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAaxG"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * claude.start procedure
3
+ *
4
+ * This procedure starts one turn of the Claude Code CLI as a detached process that writes to a
5
+ * file. The turn continues when the host stops.
6
+ */
7
+ import { startTurn } from "../../turn.js";
8
+ /**
9
+ * This function starts a turn. The variables of `input.env` go on top of the environment of the
10
+ * host. It gives the process id and the output file of the turn.
11
+ */
12
+ export async function claudeStart(input, spawner) {
13
+ const turn = await startTurn({
14
+ prompt: input.prompt,
15
+ cwd: input.cwd,
16
+ args: input.args,
17
+ outputFile: input.outputFile,
18
+ promptFile: input.promptFile,
19
+ executable: input.executable,
20
+ executableArgs: input.executableArgs,
21
+ env: input.env !== undefined ? { ...process.env, ...input.env } : undefined,
22
+ spawner,
23
+ });
24
+ return { ...turn, args: [...turn.args] };
25
+ }
26
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/procedures/claude/start.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAgB,MAAM,eAAe,CAAC;AAGxD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAuB,EAAE,OAAiB;IAC1E,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC;QAC3B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,GAAG,EAAE,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;QAC3E,OAAO;KACR,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * An import of this file registers the procedures of @procedures/claude-cli in the global registry:
3
+ * `import "@procedures/claude-cli/register"`. The package root registers nothing.
4
+ */
5
+ export * from "./module.js";
6
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,cAAc,aAAa,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * An import of this file registers the procedures of @procedures/claude-cli in the global registry:
3
+ * `import "@procedures/claude-cli/register"`. The package root registers nothing.
4
+ */
5
+ import { registerClaudeCliProcedures } from "./module.js";
6
+ export * from "./module.js";
7
+ registerClaudeCliProcedures();
8
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAE1D,cAAc,aAAa,CAAC;AAE5B,2BAA2B,EAAE,CAAC"}
package/dist/turn.d.ts ADDED
@@ -0,0 +1,142 @@
1
+ /**
2
+ * One turn of the Claude Code CLI as a process that can outlive its host.
3
+ *
4
+ * - `startTurn` starts `claude -p --output-format stream-json --verbose` as a detached process.
5
+ * The prompt comes from a file, and the output goes to a file. The host holds no pipe to the
6
+ * process, so a restart of the host does not stop the turn.
7
+ * - `readTurn` and `followTurn` read the output file from a byte offset, and give normalised
8
+ * events. A new host continues from the last offset.
9
+ * - `cancelTurn` stops the process tree of a turn by its process id.
10
+ */
11
+ import { type SpawnOptions } from "node:child_process";
12
+ import { type CommandOptions, type CommandResult } from "@procedures/shell/command";
13
+ import { type ClaudeEvent } from "./events.js";
14
+ /** The flags that make the CLI run one turn and write stream-json. */
15
+ export declare const CLAUDE_FLAGS: readonly string[];
16
+ /** The part of a child process that `startTurn` uses. */
17
+ export interface SpawnedProcess {
18
+ readonly pid?: number | undefined;
19
+ once(event: "spawn" | "error", listener: (error?: Error) => void): unknown;
20
+ unref(): void;
21
+ }
22
+ /** The function that starts a process. The default is `spawn` of `node:child_process`. */
23
+ export type Spawner = (command: string, args: readonly string[], options: SpawnOptions) => SpawnedProcess;
24
+ /** The options of `startTurn`. */
25
+ export interface StartTurnOptions {
26
+ /** The prompt. The process reads it from a file on its stdin. */
27
+ readonly prompt: string;
28
+ /** The working folder of the turn (default: the current folder). */
29
+ readonly cwd?: string | undefined;
30
+ /** More arguments after the default flags, for example `--resume <session>` or `--model <name>`. */
31
+ readonly args?: readonly string[] | undefined;
32
+ /** The file that gets the output. The process appends to it. The default is a file in a new temporary folder. */
33
+ readonly outputFile?: string | undefined;
34
+ /** The file that holds the prompt (default: `<outputFile>.prompt.txt`). */
35
+ readonly promptFile?: string | undefined;
36
+ /** The `claude` program (default: `CLAUDE_BIN` of the host, then a search). */
37
+ readonly executable?: string | undefined;
38
+ /** The arguments before the default flags, for example the path of `cli.js` when `executable` is `node`. */
39
+ readonly executableArgs?: readonly string[] | undefined;
40
+ /** The full environment of the process (default: `process.env`). The caller removes the secrets. */
41
+ readonly env?: Readonly<Record<string, string | undefined>> | undefined;
42
+ /** The function that starts the process (default: `spawn`). The tests give their own. */
43
+ readonly spawner?: Spawner | undefined;
44
+ }
45
+ /** A turn that runs. Keep `pid`, `outputFile` and `offset` to read or stop the turn later. */
46
+ export interface StartedTurn {
47
+ readonly pid: number;
48
+ /** The absolute path of the output file. */
49
+ readonly outputFile: string;
50
+ /** The absolute path of the prompt file. */
51
+ readonly promptFile: string;
52
+ /** The byte offset in the output file where the output of this turn starts. */
53
+ readonly offset: number;
54
+ /** The program and its arguments. */
55
+ readonly command: string;
56
+ readonly args: readonly string[];
57
+ /** The start time, as an ISO 8601 text. */
58
+ readonly startedAt: string;
59
+ }
60
+ /**
61
+ * This function starts one turn as a detached process: stdin is the prompt file, stdout and
62
+ * stderr go to the output file. The process starts with argv, not through a shell.
63
+ */
64
+ export declare function startTurn(options: StartTurnOptions): Promise<StartedTurn>;
65
+ /** This function tells if a process with this id runs. */
66
+ export declare function isProcessAlive(pid: number): boolean;
67
+ /** One event of a turn, with the byte offset after its line. Give that offset to continue. */
68
+ export interface TurnEvent {
69
+ readonly offset: number;
70
+ readonly event: ClaudeEvent;
71
+ }
72
+ /** The options of `readTurn`. */
73
+ export interface ReadTurnOptions {
74
+ /** The output file of the turn. */
75
+ readonly outputFile: string;
76
+ /** The byte offset to start from (default: 0). */
77
+ readonly offset?: number | undefined;
78
+ /** The process id of the turn. Without it, the last line without a line end stays unread. */
79
+ readonly pid?: number | undefined;
80
+ /** The function that tells if a process runs (default: `isProcessAlive`). */
81
+ readonly isAlive?: ((pid: number) => boolean) | undefined;
82
+ }
83
+ /** The result of `readTurn`. */
84
+ export interface ReadTurnResult {
85
+ readonly events: TurnEvent[];
86
+ /** The byte offset after the last line that was read. Give it to the next read. */
87
+ readonly offset: number;
88
+ /** True when the events include the `result` of the turn. */
89
+ readonly finished: boolean;
90
+ /** True when the process runs. It is absent without `pid`. */
91
+ readonly running?: boolean;
92
+ /** The number of new bytes in the file, read or not. */
93
+ readonly newBytes: number;
94
+ }
95
+ /**
96
+ * This function reads the complete lines of the output file after `offset`, and normalises them.
97
+ * When the process has ended, it also reads a last line without a line end.
98
+ */
99
+ export declare function readTurn(options: ReadTurnOptions): ReadTurnResult;
100
+ /** The options of `followTurn`. */
101
+ export interface FollowTurnOptions extends ReadTurnOptions {
102
+ /** The time between two reads, in milliseconds (default: 250). */
103
+ readonly pollMs?: number | undefined;
104
+ /** The reads without new bytes after the end of the process, before the follow stops (default: 2). */
105
+ readonly quietReads?: number | undefined;
106
+ /** When the signal aborts, the follow stops. The process continues. */
107
+ readonly signal?: AbortSignal | undefined;
108
+ }
109
+ /**
110
+ * This function follows the output file and gives each event while the turn runs. It stops after
111
+ * the `result` event. When the process ends without a result, it gives an `error` event and stops.
112
+ * Without `pid`, only the result or the signal stops it.
113
+ */
114
+ export declare function followTurn(options: FollowTurnOptions): AsyncGenerator<TurnEvent, void, undefined>;
115
+ /** The function that runs a program. The default is `runCommand` of `@procedures/shell`. */
116
+ export type CommandRunner = (command: string, options: CommandOptions) => Promise<CommandResult>;
117
+ /** The options of `cancelTurn`. Each one has a default from the host. */
118
+ export interface CancelTurnOptions {
119
+ /** The operating system (default: `process.platform`). */
120
+ readonly platform?: NodeJS.Platform | undefined;
121
+ /** The function that runs `taskkill` on Windows (default: `runCommand`). */
122
+ readonly runner?: CommandRunner | undefined;
123
+ /** The function that sends a signal on POSIX (default: `process.kill`). */
124
+ readonly kill?: ((pid: number, signal: NodeJS.Signals) => void) | undefined;
125
+ /** The function that tells if a process runs (default: `isProcessAlive`). */
126
+ readonly isAlive?: ((pid: number) => boolean) | undefined;
127
+ /** The signal on POSIX (default: `SIGTERM`). */
128
+ readonly signal?: NodeJS.Signals | undefined;
129
+ }
130
+ /** The result of `cancelTurn`. */
131
+ export interface CancelTurnResult {
132
+ /** True when the stop reached the process. */
133
+ readonly stopped: boolean;
134
+ /** Why the stop did not occur, when `stopped` is false. */
135
+ readonly reason?: string;
136
+ }
137
+ /**
138
+ * This function stops the process tree of a turn. On Windows it starts `taskkill /T /F /PID`.
139
+ * On POSIX it signals the process group, which `startTurn` made. It refuses the id of the host.
140
+ */
141
+ export declare function cancelTurn(pid: number, options?: CancelTurnOptions): Promise<CancelTurnResult>;
142
+ //# sourceMappingURL=turn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn.d.ts","sourceRoot":"","sources":["../src/turn.ts"],"names":[],"mappings":"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"}
package/dist/turn.js ADDED
@@ -0,0 +1,208 @@
1
+ /**
2
+ * One turn of the Claude Code CLI as a process that can outlive its host.
3
+ *
4
+ * - `startTurn` starts `claude -p --output-format stream-json --verbose` as a detached process.
5
+ * The prompt comes from a file, and the output goes to a file. The host holds no pipe to the
6
+ * process, so a restart of the host does not stop the turn.
7
+ * - `readTurn` and `followTurn` read the output file from a byte offset, and give normalised
8
+ * events. A new host continues from the last offset.
9
+ * - `cancelTurn` stops the process tree of a turn by its process id.
10
+ */
11
+ import { spawn } from "node:child_process";
12
+ import { closeSync, mkdirSync, mkdtempSync, openSync, readSync, statSync, writeFileSync } from "node:fs";
13
+ import { tmpdir } from "node:os";
14
+ import { dirname, join, resolve } from "node:path";
15
+ import { setTimeout as sleep } from "node:timers/promises";
16
+ import { runCommand } from "@procedures/shell/command";
17
+ import { normalizeLine } from "./events.js";
18
+ import { CLAUDE_ENV, findClaude } from "./executable.js";
19
+ /** The flags that make the CLI run one turn and write stream-json. */
20
+ export const CLAUDE_FLAGS = ["-p", "--output-format", "stream-json", "--verbose"];
21
+ const defaultSpawner = (command, args, options) => spawn(command, [...args], options);
22
+ /** True when the program is a batch file of Windows, which does not start without a shell. */
23
+ function isBatchFile(program) {
24
+ return /\.(cmd|bat)$/i.test(program);
25
+ }
26
+ function sizeOf(path) {
27
+ try {
28
+ return statSync(path).size;
29
+ }
30
+ catch {
31
+ return 0;
32
+ }
33
+ }
34
+ /**
35
+ * This function starts one turn as a detached process: stdin is the prompt file, stdout and
36
+ * stderr go to the output file. The process starts with argv, not through a shell.
37
+ */
38
+ export async function startTurn(options) {
39
+ // The search reads the environment of the host, not the environment of the turn
40
+ const command = findClaude({ executable: options.executable });
41
+ if (command === undefined)
42
+ throw new Error(`The claude program was not found. Install Claude Code, or set ${CLAUDE_ENV} to the program.`);
43
+ if (process.platform === "win32" && isBatchFile(command)) {
44
+ throw new Error(`${command} is a batch file, which does not start without a shell. Give the native claude.exe, or node and the path of cli.js.`);
45
+ }
46
+ const outputFile = resolve(options.outputFile ?? join(mkdtempSync(join(tmpdir(), "claude-turn-")), "output.ndjson"));
47
+ const promptFile = resolve(options.promptFile ?? `${outputFile}.prompt.txt`);
48
+ mkdirSync(dirname(outputFile), { recursive: true });
49
+ mkdirSync(dirname(promptFile), { recursive: true });
50
+ writeFileSync(promptFile, options.prompt, "utf8");
51
+ const offset = sizeOf(outputFile);
52
+ const args = [...(options.executableArgs ?? []), ...CLAUDE_FLAGS, ...(options.args ?? [])];
53
+ const input = openSync(promptFile, "r");
54
+ const output = openSync(outputFile, "a");
55
+ try {
56
+ const child = (options.spawner ?? defaultSpawner)(command, args, {
57
+ cwd: options.cwd,
58
+ env: { ...(options.env ?? process.env) },
59
+ // Its own process group on POSIX (the cancel signals the group), and no console window
60
+ detached: true,
61
+ windowsHide: true,
62
+ shell: false,
63
+ stdio: [input, output, output],
64
+ });
65
+ await new Promise((resolveStart, rejectStart) => {
66
+ child.once("spawn", () => resolveStart());
67
+ child.once("error", (error) => rejectStart(new Error(`claude did not start: ${error?.message ?? "unknown error"}`)));
68
+ });
69
+ if (child.pid === undefined)
70
+ throw new Error("claude did not start: no process id");
71
+ child.unref();
72
+ return { pid: child.pid, outputFile, promptFile, offset, command, args, startedAt: new Date().toISOString() };
73
+ }
74
+ finally {
75
+ // The process has its own copies of the two files
76
+ closeSync(input);
77
+ closeSync(output);
78
+ }
79
+ }
80
+ /** This function tells if a process with this id runs. */
81
+ export function isProcessAlive(pid) {
82
+ try {
83
+ process.kill(pid, 0);
84
+ return true;
85
+ }
86
+ catch (error) {
87
+ // EPERM: the process runs, but it belongs to another user
88
+ return error.code === "EPERM";
89
+ }
90
+ }
91
+ function readBytes(path, start, end) {
92
+ const fd = openSync(path, "r");
93
+ try {
94
+ const buffer = Buffer.alloc(end - start);
95
+ let done = 0;
96
+ while (done < buffer.length) {
97
+ const read = readSync(fd, buffer, done, buffer.length - done, start + done);
98
+ if (read === 0)
99
+ break;
100
+ done += read;
101
+ }
102
+ return buffer.subarray(0, done);
103
+ }
104
+ finally {
105
+ closeSync(fd);
106
+ }
107
+ }
108
+ /**
109
+ * This function reads the complete lines of the output file after `offset`, and normalises them.
110
+ * When the process has ended, it also reads a last line without a line end.
111
+ */
112
+ export function readTurn(options) {
113
+ const start = options.offset ?? 0;
114
+ // The check comes before the read: when the process has ended, the file is complete
115
+ const running = options.pid === undefined ? undefined : (options.isAlive ?? isProcessAlive)(options.pid);
116
+ const status = running === undefined ? {} : { running };
117
+ const size = sizeOf(options.outputFile);
118
+ if (size <= start)
119
+ return { events: [], offset: start, finished: false, newBytes: 0, ...status };
120
+ const bytes = readBytes(options.outputFile, start, size);
121
+ const events = [];
122
+ let position = 0;
123
+ let finished = false;
124
+ while (position < bytes.length) {
125
+ let end = bytes.indexOf(0x0a, position);
126
+ if (end === -1) {
127
+ if (running !== false)
128
+ break;
129
+ end = bytes.length;
130
+ }
131
+ const line = bytes.subarray(position, end).toString("utf8");
132
+ position = Math.min(end + 1, bytes.length);
133
+ for (const event of normalizeLine(line)) {
134
+ events.push({ offset: start + position, event });
135
+ if (event.type === "result")
136
+ finished = true;
137
+ }
138
+ }
139
+ return { events, offset: start + position, finished, newBytes: bytes.length, ...status };
140
+ }
141
+ /**
142
+ * This function follows the output file and gives each event while the turn runs. It stops after
143
+ * the `result` event. When the process ends without a result, it gives an `error` event and stops.
144
+ * Without `pid`, only the result or the signal stops it.
145
+ */
146
+ export async function* followTurn(options) {
147
+ const pollMs = options.pollMs ?? 250;
148
+ const quietLimit = options.quietReads ?? 2;
149
+ let offset = options.offset ?? 0;
150
+ let quiet = 0;
151
+ while (options.signal?.aborted !== true) {
152
+ const read = readTurn({ ...options, offset });
153
+ for (const item of read.events) {
154
+ yield item;
155
+ if (item.event.type === "result")
156
+ return;
157
+ }
158
+ offset = read.offset;
159
+ if (read.running === false) {
160
+ quiet = read.newBytes > 0 ? 0 : quiet + 1;
161
+ if (quiet >= quietLimit) {
162
+ yield { offset, event: { type: "error", message: "The process ended without a result" } };
163
+ return;
164
+ }
165
+ }
166
+ try {
167
+ await sleep(pollMs, undefined, options.signal ? { signal: options.signal } : undefined);
168
+ }
169
+ catch {
170
+ return;
171
+ }
172
+ }
173
+ }
174
+ /**
175
+ * This function stops the process tree of a turn. On Windows it starts `taskkill /T /F /PID`.
176
+ * On POSIX it signals the process group, which `startTurn` made. It refuses the id of the host.
177
+ */
178
+ export async function cancelTurn(pid, options = {}) {
179
+ if (!Number.isSafeInteger(pid) || pid <= 1)
180
+ throw new Error(`cancelTurn refuses the process id ${pid}`);
181
+ if (pid === process.pid || pid === process.ppid)
182
+ throw new Error("cancelTurn refuses the process of the host");
183
+ if (!(options.isAlive ?? isProcessAlive)(pid))
184
+ return { stopped: false, reason: "The process has ended" };
185
+ if ((options.platform ?? process.platform) === "win32") {
186
+ const result = await (options.runner ?? runCommand)("taskkill", { args: ["/T", "/F", "/PID", String(pid)], timeout: 30_000 });
187
+ if (result.exitCode === 0)
188
+ return { stopped: true };
189
+ return { stopped: false, reason: (result.error ?? result.stderr.trim()) || `taskkill gave the exit code ${result.exitCode}` };
190
+ }
191
+ const kill = options.kill ?? ((target, signal) => void process.kill(target, signal));
192
+ const signal = options.signal ?? "SIGTERM";
193
+ try {
194
+ // The negative id signals the process group: the turn and the programs that it started
195
+ kill(-pid, signal);
196
+ return { stopped: true };
197
+ }
198
+ catch {
199
+ try {
200
+ kill(pid, signal);
201
+ return { stopped: true };
202
+ }
203
+ catch (error) {
204
+ return { stopped: false, reason: error instanceof Error ? error.message : String(error) };
205
+ }
206
+ }
207
+ }
208
+ //# sourceMappingURL=turn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn.js","sourceRoot":"","sources":["../src/turn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACzG,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAA2C,MAAM,2BAA2B,CAAC;AAChG,OAAO,EAAE,aAAa,EAAoB,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEzD,sEAAsE;AACtE,MAAM,CAAC,MAAM,YAAY,GAAsB,CAAC,IAAI,EAAE,iBAAiB,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;AAYrG,MAAM,cAAc,GAAY,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAwC/F,8FAA8F;AAC9F,SAAS,WAAW,CAAC,OAAe;IAClC,OAAO,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,MAAM,CAAC,IAAY;IAC1B,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAyB;IACvD,gFAAgF;IAChF,MAAM,OAAO,GAAG,UAAU,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC/D,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,iEAAiE,UAAU,kBAAkB,CAAC,CAAC;IAC1I,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,qHAAqH,CAAC,CAAC;IACnJ,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;IACrH,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,GAAG,UAAU,aAAa,CAAC,CAAC;IAC7E,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE,GAAG,YAAY,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;IAE3F,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,cAAc,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE;YAC/D,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,GAAG,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE;YACxC,uFAAuF;YACvF,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,IAAI;YACjB,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC;SAC/B,CAAC,CAAC;QACH,MAAM,IAAI,OAAO,CAAO,CAAC,YAAY,EAAE,WAAW,EAAE,EAAE;YACpD,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,yBAAyB,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC;QACvH,CAAC,CAAC,CAAC;QACH,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACpF,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAChH,CAAC;YAAS,CAAC;QACT,kDAAkD;QAClD,SAAS,CAAC,KAAK,CAAC,CAAC;QACjB,SAAS,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0DAA0D;QAC1D,OAAQ,KAA+B,CAAC,IAAI,KAAK,OAAO,CAAC;IAC3D,CAAC;AACH,CAAC;AAiCD,SAAS,SAAS,CAAC,IAAY,EAAE,KAAa,EAAE,GAAW;IACzD,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;QACzC,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,OAAO,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;YAC5E,IAAI,IAAI,KAAK,CAAC;gBAAE,MAAM;YACtB,IAAI,IAAI,IAAI,CAAC;QACf,CAAC;QACD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;YAAS,CAAC;QACT,SAAS,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAwB;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IAClC,oFAAoF;IACpF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,cAAc,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACzG,MAAM,MAAM,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;IACxD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,IAAI,IAAI,IAAI,KAAK;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC;IAEjG,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACzD,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,OAAO,QAAQ,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAC/B,IAAI,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACxC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,IAAI,OAAO,KAAK,KAAK;gBAAE,MAAM;YAC7B,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;QACrB,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5D,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YACjD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;gBAAE,QAAQ,GAAG,IAAI,CAAC;QAC/C,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAG,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;AAC3F,CAAC;AAYD;;;;GAIG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,UAAU,CAAC,OAA0B;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC;IACrC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;IAC3C,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC;YACX,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO;QAC3C,CAAC;QACD,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACrB,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YAC3B,KAAK,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;YAC1C,IAAI,KAAK,IAAI,UAAU,EAAE,CAAC;gBACxB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,oCAAoC,EAAE,EAAE,CAAC;gBAC1F,OAAO;YACT,CAAC;QACH,CAAC;QACD,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC1F,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;IACH,CAAC;AACH,CAAC;AA2BD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,OAAO,GAAsB,EAAE;IAC3E,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,GAAG,EAAE,CAAC,CAAC;IACxG,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG,IAAI,GAAG,KAAK,OAAO,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC/G,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,cAAc,CAAC,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAE1G,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,OAAO,EAAE,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9H,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACpD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,+BAA+B,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IAChI,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,MAAc,EAAE,MAAsB,EAAQ,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnH,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,SAAS,CAAC;IAC3C,IAAI,CAAC;QACH,uFAAuF;QACvF,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC;YACH,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAClB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5F,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * The input and the output of the procedures of this package.
3
+ */
4
+ import { z } from "zod";
5
+ import type { TurnEvent } from "./turn.js";
6
+ /** The schema of one event of a turn, with the byte offset after its line. */
7
+ export declare const TurnEventSchema: z.ZodType<TurnEvent>;
8
+ export interface ClaudeStartInput {
9
+ prompt: string;
10
+ cwd?: string | undefined;
11
+ args?: string[] | undefined;
12
+ outputFile?: string | undefined;
13
+ promptFile?: string | undefined;
14
+ executable?: string | undefined;
15
+ executableArgs?: string[] | undefined;
16
+ env?: Record<string, string> | undefined;
17
+ }
18
+ export declare const ClaudeStartInputSchema: z.ZodType<ClaudeStartInput>;
19
+ export interface ClaudeStartOutput {
20
+ pid: number;
21
+ outputFile: string;
22
+ promptFile: string;
23
+ offset: number;
24
+ command: string;
25
+ args: readonly string[];
26
+ startedAt: string;
27
+ }
28
+ export declare const ClaudeStartOutputSchema: z.ZodType<ClaudeStartOutput>;
29
+ export interface ClaudeReadInput {
30
+ outputFile: string;
31
+ offset?: number | undefined;
32
+ pid?: number | undefined;
33
+ }
34
+ export declare const ClaudeReadInputSchema: z.ZodType<ClaudeReadInput>;
35
+ export interface ClaudeReadOutput {
36
+ events: TurnEvent[];
37
+ offset: number;
38
+ finished: boolean;
39
+ running?: boolean | undefined;
40
+ newBytes: number;
41
+ }
42
+ export declare const ClaudeReadOutputSchema: z.ZodType<ClaudeReadOutput>;
43
+ export interface ClaudeFollowInput {
44
+ outputFile: string;
45
+ offset?: number | undefined;
46
+ pid?: number | undefined;
47
+ pollMs?: number | undefined;
48
+ }
49
+ export declare const ClaudeFollowInputSchema: z.ZodType<ClaudeFollowInput>;
50
+ export type ClaudeFollowOutput = TurnEvent;
51
+ export declare const ClaudeFollowOutputSchema: z.ZodType<ClaudeFollowOutput>;
52
+ export interface ClaudeCancelInput {
53
+ pid: number;
54
+ }
55
+ export declare const ClaudeCancelInputSchema: z.ZodType<ClaudeCancelInput>;
56
+ export interface ClaudeCancelOutput {
57
+ stopped: boolean;
58
+ reason?: string | undefined;
59
+ }
60
+ export declare const ClaudeCancelOutputSchema: z.ZodType<ClaudeCancelOutput>;
61
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAO3C,8EAA8E;AAC9E,eAAO,MAAM,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAGZ,CAAC;AAStC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CAC1C;AAED,eAAO,MAAM,sBAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAS7D,CAAC;AAEH,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,uBAAuB,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAQ/D,CAAC;AAMH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,eAAO,MAAM,qBAAqB,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAI3D,CAAC;AAEH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,sBAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAM7D,CAAC;AAMH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,eAAO,MAAM,uBAAuB,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAK/D,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAE3C,eAAO,MAAM,wBAAwB,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAmB,CAAC;AAMvF,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,uBAAuB,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAE/D,CAAC;AAEH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,eAAO,MAAM,wBAAwB,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAGjE,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,61 @@
1
+ /**
2
+ * The input and the output of the procedures of this package.
3
+ */
4
+ import { z } from "zod";
5
+ /** The schema of one event. It keeps each field of the event. */
6
+ const ClaudeEventSchema = z.looseObject({
7
+ type: z.string().describe("meta, text, text-delta, thinking, tool-use, tool-result, result, log or error"),
8
+ });
9
+ /** The schema of one event of a turn, with the byte offset after its line. */
10
+ export const TurnEventSchema = z.object({
11
+ offset: z.number().describe("The byte offset after the line of the event"),
12
+ event: ClaudeEventSchema,
13
+ });
14
+ const pidSchema = z.number().int().min(2).describe("The process id of the turn");
15
+ const offsetSchema = z.number().int().min(0).describe("The byte offset to start from (default: 0)");
16
+ export const ClaudeStartInputSchema = z.object({
17
+ prompt: z.string().min(1).describe("The prompt of the turn"),
18
+ cwd: z.string().min(1).optional().describe("The working folder of the turn"),
19
+ args: z.array(z.string()).optional().describe('More arguments, for example ["--resume", "<session>"] or ["--model", "<name>"]'),
20
+ outputFile: z.string().min(1).optional().describe("The file that gets the output (default: a file in a new temporary folder)"),
21
+ promptFile: z.string().min(1).optional().describe("The file that holds the prompt (default: <outputFile>.prompt.txt)"),
22
+ executable: z.string().min(1).optional().describe("The claude program (default: CLAUDE_BIN, then a search)"),
23
+ executableArgs: z.array(z.string()).optional().describe("The arguments before the flags, for example the path of cli.js"),
24
+ env: z.record(z.string(), z.string()).optional().describe("Environment variables to add to the environment of the host"),
25
+ });
26
+ export const ClaudeStartOutputSchema = z.object({
27
+ pid: z.number().describe("The process id of the turn"),
28
+ outputFile: z.string().describe("The absolute path of the output file"),
29
+ promptFile: z.string().describe("The absolute path of the prompt file"),
30
+ offset: z.number().describe("The byte offset where the output of this turn starts"),
31
+ command: z.string().describe("The program"),
32
+ args: z.array(z.string()).describe("The arguments of the program"),
33
+ startedAt: z.string().describe("The start time (ISO 8601)"),
34
+ });
35
+ export const ClaudeReadInputSchema = z.object({
36
+ outputFile: z.string().min(1).describe("The output file of the turn"),
37
+ offset: offsetSchema.optional(),
38
+ pid: pidSchema.optional(),
39
+ });
40
+ export const ClaudeReadOutputSchema = z.object({
41
+ events: z.array(TurnEventSchema).describe("The new events"),
42
+ offset: z.number().describe("The byte offset for the next read"),
43
+ finished: z.boolean().describe("True when the events include the result of the turn"),
44
+ running: z.boolean().optional().describe("True when the process runs (only with pid)"),
45
+ newBytes: z.number().describe("The number of new bytes in the file"),
46
+ });
47
+ export const ClaudeFollowInputSchema = z.object({
48
+ outputFile: z.string().min(1).describe("The output file of the turn"),
49
+ offset: offsetSchema.optional(),
50
+ pid: pidSchema.optional().describe("The process id of the turn. Without it, only the result stops the follow."),
51
+ pollMs: z.number().int().min(10).max(60_000).optional().describe("The time between two reads, in milliseconds (default: 250)"),
52
+ });
53
+ export const ClaudeFollowOutputSchema = TurnEventSchema;
54
+ export const ClaudeCancelInputSchema = z.object({
55
+ pid: pidSchema,
56
+ });
57
+ export const ClaudeCancelOutputSchema = z.object({
58
+ stopped: z.boolean().describe("True when the stop reached the process"),
59
+ reason: z.string().optional().describe("Why the stop did not occur"),
60
+ });
61
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}