@ai-devkit/agent-manager 0.28.1 → 0.30.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 (219) hide show
  1. package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js +1 -342
  2. package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js.map +1 -1
  3. package/dist/__tests__/capacity/codex.test.js +343 -0
  4. package/dist/__tests__/capacity/codex.test.js.map +1 -0
  5. package/dist/__tests__/capacity/index.test.js +50 -0
  6. package/dist/__tests__/capacity/index.test.js.map +1 -0
  7. package/dist/__tests__/database/DurableAgentsDatabase.test.js +31 -3
  8. package/dist/__tests__/database/DurableAgentsDatabase.test.js.map +1 -1
  9. package/dist/__tests__/durable/CodexCliProbe.test.js +129 -0
  10. package/dist/__tests__/durable/CodexCliProbe.test.js.map +1 -0
  11. package/dist/__tests__/durable/CodexDurableAgentRepository.test.js +84 -0
  12. package/dist/__tests__/durable/CodexDurableAgentRepository.test.js.map +1 -0
  13. package/dist/__tests__/durable/CodexPrintAgent.integration.test.js +126 -0
  14. package/dist/__tests__/durable/CodexPrintAgent.integration.test.js.map +1 -0
  15. package/dist/__tests__/durable/CodexPrintAgentService.test.js +271 -0
  16. package/dist/__tests__/durable/CodexPrintAgentService.test.js.map +1 -0
  17. package/dist/__tests__/durable/CodexPrintRunner.test.js +393 -0
  18. package/dist/__tests__/durable/CodexPrintRunner.test.js.map +1 -0
  19. package/dist/__tests__/print/ClaudeCliProbe.test.js +3 -7
  20. package/dist/__tests__/print/ClaudeCliProbe.test.js.map +1 -1
  21. package/dist/__tests__/print/ClaudePrintAgent.integration.test.js +33 -27
  22. package/dist/__tests__/print/ClaudePrintAgent.integration.test.js.map +1 -1
  23. package/dist/__tests__/print/ClaudePrintAgentService.test.js +65 -0
  24. package/dist/__tests__/print/ClaudePrintAgentService.test.js.map +1 -1
  25. package/dist/__tests__/print/ClaudePrintRunner.test.js +4 -10
  26. package/dist/__tests__/print/ClaudePrintRunner.test.js.map +1 -1
  27. package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js +79 -0
  28. package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js.map +1 -0
  29. package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js +436 -0
  30. package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js.map +1 -0
  31. package/dist/__tests__/providers/pi/durable/PiCliProbe.test.js +76 -0
  32. package/dist/__tests__/providers/pi/durable/PiCliProbe.test.js.map +1 -0
  33. package/dist/__tests__/providers/pi/durable/PiDurableAgentRepository.test.js +43 -0
  34. package/dist/__tests__/providers/pi/durable/PiDurableAgentRepository.test.js.map +1 -0
  35. package/dist/__tests__/providers/pi/durable/PiPrintAgentService.test.js +202 -0
  36. package/dist/__tests__/providers/pi/durable/PiPrintAgentService.test.js.map +1 -0
  37. package/dist/__tests__/providers/pi/durable/PiPrintProtocol.test.js +119 -0
  38. package/dist/__tests__/providers/pi/durable/PiPrintProtocol.test.js.map +1 -0
  39. package/dist/__tests__/providers/pi/durable/PiPrintRunner.test.js +386 -0
  40. package/dist/__tests__/providers/pi/durable/PiPrintRunner.test.js.map +1 -0
  41. package/dist/__tests__/providers/pi/durable/PiStreamParser.test.js +34 -0
  42. package/dist/__tests__/providers/pi/durable/PiStreamParser.test.js.map +1 -0
  43. package/dist/__tests__/utils/ClaudeSessionParser.test.js +2 -2
  44. package/dist/__tests__/utils/ClaudeSessionParser.test.js.map +1 -1
  45. package/dist/adapters/index.d.ts +1 -1
  46. package/dist/adapters/index.d.ts.map +1 -1
  47. package/dist/adapters/index.js +1 -1
  48. package/dist/adapters/index.js.map +1 -1
  49. package/dist/capacity/codex.d.ts +36 -0
  50. package/dist/capacity/codex.d.ts.map +1 -0
  51. package/dist/capacity/codex.js +317 -0
  52. package/dist/capacity/codex.js.map +1 -0
  53. package/dist/capacity/index.d.ts +11 -0
  54. package/dist/capacity/index.d.ts.map +1 -0
  55. package/dist/capacity/index.js +49 -0
  56. package/dist/capacity/index.js.map +1 -0
  57. package/dist/capacity/types.d.ts +17 -0
  58. package/dist/capacity/types.d.ts.map +1 -0
  59. package/dist/capacity/types.js +3 -0
  60. package/dist/capacity/types.js.map +1 -0
  61. package/dist/database/migrations/004_codex_durable_sessions.sql +1 -0
  62. package/dist/durable/DurableAgent.d.ts +23 -3
  63. package/dist/durable/DurableAgent.d.ts.map +1 -1
  64. package/dist/durable/DurableAgent.js +12 -0
  65. package/dist/durable/DurableAgent.js.map +1 -1
  66. package/dist/durable/DurableAgentRepository.d.ts +6 -7
  67. package/dist/durable/DurableAgentRepository.d.ts.map +1 -1
  68. package/dist/durable/DurableAgentRepository.js +73 -42
  69. package/dist/durable/DurableAgentRepository.js.map +1 -1
  70. package/dist/durable/process.d.ts +8 -0
  71. package/dist/durable/process.d.ts.map +1 -0
  72. package/dist/durable/process.js +40 -0
  73. package/dist/durable/process.js.map +1 -0
  74. package/dist/durable/run.d.ts +32 -0
  75. package/dist/durable/run.d.ts.map +1 -0
  76. package/dist/durable/run.js +46 -0
  77. package/dist/durable/run.js.map +1 -0
  78. package/dist/durable/utils.d.ts +19 -0
  79. package/dist/durable/utils.d.ts.map +1 -0
  80. package/dist/durable/utils.js +52 -0
  81. package/dist/durable/utils.js.map +1 -0
  82. package/dist/index.d.ts +19 -13
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +10 -8
  85. package/dist/index.js.map +1 -1
  86. package/dist/providers/claude/ClaudeAgentMapper.d.ts +21 -0
  87. package/dist/providers/claude/ClaudeAgentMapper.d.ts.map +1 -0
  88. package/dist/providers/claude/ClaudeAgentMapper.js +42 -0
  89. package/dist/providers/claude/ClaudeAgentMapper.js.map +1 -0
  90. package/dist/providers/claude/ClaudeCodeAdapter.d.ts +29 -0
  91. package/dist/providers/claude/ClaudeCodeAdapter.d.ts.map +1 -0
  92. package/dist/providers/claude/ClaudeCodeAdapter.js +129 -0
  93. package/dist/providers/claude/ClaudeCodeAdapter.js.map +1 -0
  94. package/dist/{adapters/ClaudeCodeAdapter.d.ts → providers/claude/ClaudeSessionLocator.d.ts} +68 -52
  95. package/dist/providers/claude/ClaudeSessionLocator.d.ts.map +1 -0
  96. package/dist/{adapters/ClaudeCodeAdapter.js → providers/claude/ClaudeSessionLocator.js} +71 -189
  97. package/dist/providers/claude/ClaudeSessionLocator.js.map +1 -0
  98. package/dist/{utils → providers/claude}/ClaudeSessionParser.d.ts +2 -2
  99. package/dist/providers/claude/ClaudeSessionParser.d.ts.map +1 -0
  100. package/dist/{utils → providers/claude}/ClaudeSessionParser.js +1 -1
  101. package/dist/providers/claude/ClaudeSessionParser.js.map +1 -0
  102. package/dist/providers/claude/durable/ClaudeCliProbe.d.ts.map +1 -0
  103. package/dist/{durable → providers/claude/durable}/ClaudeCliProbe.js +4 -9
  104. package/dist/providers/claude/durable/ClaudeCliProbe.js.map +1 -0
  105. package/dist/{durable → providers/claude/durable}/ClaudePrintAgentService.d.ts +4 -9
  106. package/dist/providers/claude/durable/ClaudePrintAgentService.d.ts.map +1 -0
  107. package/dist/providers/claude/durable/ClaudePrintAgentService.js +45 -0
  108. package/dist/providers/claude/durable/ClaudePrintAgentService.js.map +1 -0
  109. package/dist/{durable → providers/claude/durable}/ClaudePrintRunner.d.ts +3 -3
  110. package/dist/providers/claude/durable/ClaudePrintRunner.d.ts.map +1 -0
  111. package/dist/providers/claude/durable/ClaudePrintRunner.js +75 -0
  112. package/dist/providers/claude/durable/ClaudePrintRunner.js.map +1 -0
  113. package/dist/providers/claude/durable/ClaudeStreamParser.d.ts +17 -0
  114. package/dist/providers/claude/durable/ClaudeStreamParser.d.ts.map +1 -0
  115. package/dist/providers/claude/durable/ClaudeStreamParser.js +69 -0
  116. package/dist/providers/claude/durable/ClaudeStreamParser.js.map +1 -0
  117. package/dist/providers/codex/durable/CodexCliProbe.d.ts +20 -0
  118. package/dist/providers/codex/durable/CodexCliProbe.d.ts.map +1 -0
  119. package/dist/providers/codex/durable/CodexCliProbe.js +61 -0
  120. package/dist/providers/codex/durable/CodexCliProbe.js.map +1 -0
  121. package/dist/providers/codex/durable/CodexPrintAgentService.d.ts +40 -0
  122. package/dist/providers/codex/durable/CodexPrintAgentService.d.ts.map +1 -0
  123. package/dist/providers/codex/durable/CodexPrintAgentService.js +50 -0
  124. package/dist/providers/codex/durable/CodexPrintAgentService.js.map +1 -0
  125. package/dist/providers/codex/durable/CodexPrintRunner.d.ts +34 -0
  126. package/dist/providers/codex/durable/CodexPrintRunner.d.ts.map +1 -0
  127. package/dist/providers/codex/durable/CodexPrintRunner.js +78 -0
  128. package/dist/providers/codex/durable/CodexPrintRunner.js.map +1 -0
  129. package/dist/providers/codex/durable/CodexStreamParser.d.ts +21 -0
  130. package/dist/providers/codex/durable/CodexStreamParser.d.ts.map +1 -0
  131. package/dist/providers/codex/durable/CodexStreamParser.js +86 -0
  132. package/dist/providers/codex/durable/CodexStreamParser.js.map +1 -0
  133. package/dist/providers/pi/durable/PiCliProbe.d.ts +20 -0
  134. package/dist/providers/pi/durable/PiCliProbe.d.ts.map +1 -0
  135. package/dist/providers/pi/durable/PiCliProbe.js +51 -0
  136. package/dist/providers/pi/durable/PiCliProbe.js.map +1 -0
  137. package/dist/providers/pi/durable/PiPrintAgentService.d.ts +39 -0
  138. package/dist/providers/pi/durable/PiPrintAgentService.d.ts.map +1 -0
  139. package/dist/providers/pi/durable/PiPrintAgentService.js +47 -0
  140. package/dist/providers/pi/durable/PiPrintAgentService.js.map +1 -0
  141. package/dist/providers/pi/durable/PiPrintProtocol.d.ts +4 -0
  142. package/dist/providers/pi/durable/PiPrintProtocol.d.ts.map +1 -0
  143. package/dist/providers/pi/durable/PiPrintProtocol.js +44 -0
  144. package/dist/providers/pi/durable/PiPrintProtocol.js.map +1 -0
  145. package/dist/providers/pi/durable/PiPrintRunner.d.ts +32 -0
  146. package/dist/providers/pi/durable/PiPrintRunner.d.ts.map +1 -0
  147. package/dist/providers/pi/durable/PiPrintRunner.js +61 -0
  148. package/dist/providers/pi/durable/PiPrintRunner.js.map +1 -0
  149. package/dist/providers/pi/durable/PiStreamParser.d.ts +21 -0
  150. package/dist/providers/pi/durable/PiStreamParser.d.ts.map +1 -0
  151. package/dist/providers/pi/durable/PiStreamParser.js +71 -0
  152. package/dist/providers/pi/durable/PiStreamParser.js.map +1 -0
  153. package/package.json +1 -1
  154. package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +1 -307
  155. package/src/__tests__/capacity/codex.test.ts +184 -0
  156. package/src/__tests__/capacity/index.test.ts +38 -0
  157. package/src/__tests__/database/DurableAgentsDatabase.test.ts +28 -3
  158. package/src/__tests__/durable/CodexCliProbe.test.ts +63 -0
  159. package/src/__tests__/durable/CodexDurableAgentRepository.test.ts +54 -0
  160. package/src/__tests__/durable/CodexPrintAgent.integration.test.ts +79 -0
  161. package/src/__tests__/durable/CodexPrintAgentService.test.ts +139 -0
  162. package/src/__tests__/durable/CodexPrintRunner.test.ts +189 -0
  163. package/src/__tests__/fixtures/fake-codex.cjs +45 -0
  164. package/src/__tests__/print/ClaudeCliProbe.test.ts +3 -7
  165. package/src/__tests__/print/ClaudePrintAgent.integration.test.ts +19 -22
  166. package/src/__tests__/print/ClaudePrintAgentService.test.ts +33 -1
  167. package/src/__tests__/print/ClaudePrintRunner.test.ts +4 -10
  168. package/src/__tests__/providers/claude/ClaudeAgentMapper.test.ts +84 -0
  169. package/src/__tests__/providers/claude/ClaudeSessionLocator.test.ts +411 -0
  170. package/src/__tests__/providers/pi/durable/PiCliProbe.test.ts +38 -0
  171. package/src/__tests__/providers/pi/durable/PiDurableAgentRepository.test.ts +32 -0
  172. package/src/__tests__/providers/pi/durable/PiPrintAgentService.test.ts +69 -0
  173. package/src/__tests__/providers/pi/durable/PiPrintProtocol.test.ts +33 -0
  174. package/src/__tests__/providers/pi/durable/PiPrintRunner.test.ts +107 -0
  175. package/src/__tests__/providers/pi/durable/PiStreamParser.test.ts +24 -0
  176. package/src/__tests__/utils/ClaudeSessionParser.test.ts +2 -2
  177. package/src/adapters/index.ts +1 -1
  178. package/src/capacity/codex.ts +320 -0
  179. package/src/capacity/index.ts +57 -0
  180. package/src/capacity/types.ts +18 -0
  181. package/src/database/migrations/004_codex_durable_sessions.sql +1 -0
  182. package/src/durable/DurableAgent.ts +51 -3
  183. package/src/durable/DurableAgentRepository.ts +60 -31
  184. package/src/durable/process.ts +28 -0
  185. package/src/durable/run.ts +74 -0
  186. package/src/durable/utils.ts +61 -0
  187. package/src/index.ts +37 -15
  188. package/src/providers/claude/ClaudeAgentMapper.ts +62 -0
  189. package/src/providers/claude/ClaudeCodeAdapter.ts +160 -0
  190. package/src/{adapters/ClaudeCodeAdapter.ts → providers/claude/ClaudeSessionLocator.ts} +97 -239
  191. package/src/{utils → providers/claude}/ClaudeSessionParser.ts +2 -2
  192. package/src/{durable → providers/claude/durable}/ClaudeCliProbe.ts +4 -10
  193. package/src/providers/claude/durable/ClaudePrintAgentService.ts +66 -0
  194. package/src/providers/claude/durable/ClaudePrintRunner.ts +92 -0
  195. package/src/providers/claude/durable/ClaudeStreamParser.ts +79 -0
  196. package/src/providers/codex/durable/CodexCliProbe.ts +60 -0
  197. package/src/providers/codex/durable/CodexPrintAgentService.ts +65 -0
  198. package/src/providers/codex/durable/CodexPrintRunner.ts +94 -0
  199. package/src/providers/codex/durable/CodexStreamParser.ts +104 -0
  200. package/src/providers/pi/durable/PiCliProbe.ts +48 -0
  201. package/src/providers/pi/durable/PiPrintAgentService.ts +69 -0
  202. package/src/providers/pi/durable/PiPrintProtocol.ts +39 -0
  203. package/src/providers/pi/durable/PiPrintRunner.ts +88 -0
  204. package/src/providers/pi/durable/PiStreamParser.ts +84 -0
  205. package/dist/adapters/ClaudeCodeAdapter.d.ts.map +0 -1
  206. package/dist/adapters/ClaudeCodeAdapter.js.map +0 -1
  207. package/dist/durable/ClaudeCliProbe.d.ts.map +0 -1
  208. package/dist/durable/ClaudeCliProbe.js.map +0 -1
  209. package/dist/durable/ClaudePrintAgentService.d.ts.map +0 -1
  210. package/dist/durable/ClaudePrintAgentService.js +0 -66
  211. package/dist/durable/ClaudePrintAgentService.js.map +0 -1
  212. package/dist/durable/ClaudePrintRunner.d.ts.map +0 -1
  213. package/dist/durable/ClaudePrintRunner.js +0 -128
  214. package/dist/durable/ClaudePrintRunner.js.map +0 -1
  215. package/dist/utils/ClaudeSessionParser.d.ts.map +0 -1
  216. package/dist/utils/ClaudeSessionParser.js.map +0 -1
  217. package/src/durable/ClaudePrintAgentService.ts +0 -94
  218. package/src/durable/ClaudePrintRunner.ts +0 -139
  219. /package/dist/{durable → providers/claude/durable}/ClaudeCliProbe.d.ts +0 -0
@@ -1,94 +0,0 @@
1
- import type { DurableAgent, ProcessIdentity } from './DurableAgent.js';
2
- import { ClaudePrintError, DurableAgentNotFoundError } from './DurableAgent.js';
3
- import { ClaudeCliProbe } from './ClaudeCliProbe.js';
4
- import { ClaudePrintRunner, type ClaudePrintRunResult } from './ClaudePrintRunner.js';
5
- import { DurableAgentRepository, type CreateDurableAgentInput, type DurableRunCompletion } from './DurableAgentRepository.js';
6
-
7
- interface RepositoryLike {
8
- create(input: CreateDurableAgentInput): Promise<DurableAgent>;
9
- list(): Promise<DurableAgent[]>;
10
- resolve(reference: string): Promise<DurableAgent | DurableAgent[] | null>;
11
- acquireRun(id: string): Promise<{ agent: DurableAgent; token: string }>;
12
- recordProviderProcess(id: string, token: string, identity: ProcessIdentity): Promise<void>;
13
- completeRun(id: string, token: string, result: DurableRunCompletion): Promise<DurableAgent>;
14
- }
15
-
16
- interface ProbeLike { validate(): Promise<{ executable: string; version: string }> }
17
- interface RunnerLike { run(request: Parameters<ClaudePrintRunner['run']>[0]): Promise<ClaudePrintRunResult> }
18
-
19
- export interface ClaudePrintAgentServiceOptions {
20
- repository?: RepositoryLike;
21
- probe?: ProbeLike;
22
- runner?: RunnerLike;
23
- executable?: string;
24
- }
25
-
26
- export interface ClaudePrintSendResult extends ClaudePrintRunResult {
27
- agentId: string;
28
- agentName: string;
29
- }
30
-
31
- export class ClaudePrintAgentService {
32
- readonly repository: RepositoryLike;
33
- private readonly probe: ProbeLike;
34
- private readonly runner: RunnerLike;
35
- private readonly executable?: string;
36
-
37
- constructor(options: ClaudePrintAgentServiceOptions = {}) {
38
- this.repository = options.repository ?? new DurableAgentRepository();
39
- this.probe = options.probe ?? new ClaudeCliProbe();
40
- this.runner = options.runner ?? new ClaudePrintRunner();
41
- this.executable = options.executable;
42
- }
43
-
44
- async create(input: CreateDurableAgentInput): Promise<DurableAgent> {
45
- await this.probe.validate();
46
- return this.repository.create(input);
47
- }
48
-
49
- async send(reference: string, prompt: string): Promise<ClaudePrintSendResult> {
50
- const resolved = await this.repository.resolve(reference);
51
- if (!resolved) throw new DurableAgentNotFoundError(reference);
52
- if (Array.isArray(resolved)) {
53
- throw new ClaudePrintError(`Multiple durable agents match "${reference}".`, 'DURABLE_AGENT_AMBIGUOUS');
54
- }
55
- const acquired = await this.repository.acquireRun(resolved.id);
56
- try {
57
- const result = await this.runner.run({
58
- agent: acquired.agent,
59
- prompt,
60
- executable: this.executable,
61
- firstRun: acquired.agent.sessionHealth === 'uninitialized',
62
- onSpawn: (identity) => this.repository.recordProviderProcess(resolved.id, acquired.token, identity),
63
- });
64
- await this.repository.completeRun(resolved.id, acquired.token, {
65
- status: 'succeeded',
66
- exitCode: result.exitCode,
67
- summary: sanitize(result.result, 4096),
68
- sessionHealth: 'healthy',
69
- });
70
- return { ...result, agentId: resolved.id, agentName: resolved.name };
71
- } catch (error) {
72
- const failure = error instanceof Error ? error : new Error(String(error));
73
- const sessionHealth = error instanceof ClaudePrintError && error.code === 'CLAUDE_SESSION_MISMATCH'
74
- ? 'mismatch' as const
75
- : 'unknown' as const;
76
- await this.repository.completeRun(resolved.id, acquired.token, {
77
- status: 'failed',
78
- exitCode: null,
79
- summary: sanitize(failure.message, 4096),
80
- sessionHealth,
81
- });
82
- throw error;
83
- }
84
- }
85
- }
86
-
87
- function sanitize(value: string, max: number): string {
88
- return Array.from(value, (character) => {
89
- const code = character.charCodeAt(0);
90
- return (code <= 8 || code === 11 || code === 12 || (code >= 14 && code <= 31) || code === 127)
91
- ? ' '
92
- : character;
93
- }).join('').trim().slice(0, max);
94
- }
@@ -1,139 +0,0 @@
1
- import { spawn as nodeSpawn, type ChildProcessWithoutNullStreams, type SpawnOptionsWithoutStdio } from 'child_process';
2
- import type { DurableAgent, ProcessIdentity } from './DurableAgent.js';
3
- import { ClaudePrintError } from './DurableAgent.js';
4
- import { LocalProcessInspector, type ProcessInspector } from './DurableAgentRepository.js';
5
-
6
- type Spawn = (
7
- command: string,
8
- args: readonly string[],
9
- options: SpawnOptionsWithoutStdio & { stdio: ['pipe', 'pipe', 'pipe'] },
10
- ) => ChildProcessWithoutNullStreams;
11
-
12
- export interface ClaudePrintRunRequest {
13
- agent: DurableAgent;
14
- prompt: string;
15
- executable?: string;
16
- firstRun: boolean;
17
- onSpawn(identity: ProcessIdentity): Promise<void>;
18
- }
19
-
20
- export interface ClaudePrintRunResult {
21
- sessionId: string;
22
- result: string;
23
- exitCode: number;
24
- }
25
-
26
- export interface ClaudePrintRunnerOptions {
27
- spawn?: Spawn;
28
- processInspector?: ProcessInspector;
29
- maxLineBytes?: number;
30
- }
31
-
32
- export class ClaudePrintRunner {
33
- private readonly spawn: Spawn;
34
- private readonly processInspector: ProcessInspector;
35
- private readonly maxLineBytes: number;
36
-
37
- constructor(options: ClaudePrintRunnerOptions = {}) {
38
- this.spawn = options.spawn ?? (nodeSpawn as Spawn);
39
- this.processInspector = options.processInspector ?? new LocalProcessInspector();
40
- this.maxLineBytes = options.maxLineBytes ?? 1024 * 1024;
41
- }
42
-
43
- async run(request: ClaudePrintRunRequest): Promise<ClaudePrintRunResult> {
44
- const sessionArgs = request.firstRun
45
- ? ['--session-id', request.agent.providerSessionId]
46
- : ['--resume', request.agent.providerSessionId];
47
- const args = ['-p', ...sessionArgs, '--output-format', 'stream-json', '--verbose'];
48
- const child = this.spawn(request.executable ?? 'claude', args, {
49
- cwd: request.agent.cwd,
50
- shell: false,
51
- stdio: ['pipe', 'pipe', 'pipe'],
52
- });
53
- if (!child.pid) {
54
- child.kill();
55
- throw new ClaudePrintError('Claude process did not provide a PID.', 'CLAUDE_PROCESS_IDENTITY');
56
- }
57
- const identity = this.processInspector.getIdentity(child.pid);
58
- if (!identity) {
59
- child.kill();
60
- throw new ClaudePrintError('Cannot verify Claude process identity.', 'CLAUDE_PROCESS_IDENTITY');
61
- }
62
-
63
- let buffer = Buffer.alloc(0);
64
- let terminal: ClaudePrintRunResult | null = null;
65
- let protocolError: ClaudePrintError | null = null;
66
-
67
- child.stdout.on('data', (chunk: Buffer | string) => {
68
- if (protocolError) return;
69
- buffer = Buffer.concat([buffer, Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)]);
70
- if (buffer.length > this.maxLineBytes && buffer.indexOf(0x0a) < 0) {
71
- protocolError = new ClaudePrintError('Claude stream line exceeded the safety limit.', 'CLAUDE_STREAM_OVERSIZED');
72
- return;
73
- }
74
- let newline: number;
75
- while ((newline = buffer.indexOf(0x0a)) >= 0) {
76
- const line = buffer.subarray(0, newline);
77
- buffer = buffer.subarray(newline + 1);
78
- if (line.length === 0) continue;
79
- if (line.length > this.maxLineBytes) {
80
- protocolError = new ClaudePrintError('Claude stream line exceeded the safety limit.', 'CLAUDE_STREAM_OVERSIZED');
81
- return;
82
- }
83
- try {
84
- const value = JSON.parse(line.toString('utf8')) as unknown;
85
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
86
- throw new ClaudePrintError('Claude emitted a non-object stream message.', 'CLAUDE_STREAM_INVALID');
87
- }
88
- const event = value as Record<string, unknown>;
89
- if (typeof event.session_id === 'string' && event.session_id !== request.agent.providerSessionId) {
90
- throw new ClaudePrintError('Claude returned a different session identity.', 'CLAUDE_SESSION_MISMATCH');
91
- }
92
- if (event.type === 'result') {
93
- if (terminal) throw new ClaudePrintError('Claude emitted more than one terminal result.', 'CLAUDE_STREAM_INVALID');
94
- if (typeof event.session_id !== 'string' || typeof event.result !== 'string') {
95
- throw new ClaudePrintError('Claude emitted an invalid terminal result.', 'CLAUDE_STREAM_INVALID');
96
- }
97
- terminal = { sessionId: event.session_id, result: event.result, exitCode: 0 };
98
- }
99
- } catch (error) {
100
- protocolError = error instanceof ClaudePrintError
101
- ? error
102
- : new ClaudePrintError('Claude emitted malformed stream JSON.', 'CLAUDE_STREAM_INVALID');
103
- return;
104
- }
105
- }
106
- });
107
- // Drain provider diagnostics without reflecting potentially sensitive prompt/tool data.
108
- child.stderr.resume();
109
-
110
- const closed = new Promise<{ code: number | null; signal: NodeJS.Signals | null }>((resolve, reject) => {
111
- child.once('error', reject);
112
- child.once('close', (code, signal) => resolve({ code, signal }));
113
- });
114
-
115
- try {
116
- await request.onSpawn(identity);
117
- } catch (error) {
118
- child.kill();
119
- throw error;
120
- }
121
-
122
- child.stdin.end(request.prompt);
123
- const { code, signal } = await closed;
124
-
125
- if (protocolError) throw protocolError;
126
- if (buffer.length > 0) {
127
- throw new ClaudePrintError('Claude stream ended with incomplete JSON.', 'CLAUDE_STREAM_INVALID');
128
- }
129
- if (code !== 0) {
130
- throw new ClaudePrintError(
131
- `Claude print run failed${signal ? ` (${signal})` : '.'}`,
132
- 'CLAUDE_PROCESS_FAILED',
133
- );
134
- }
135
- if (!terminal) throw new ClaudePrintError('Claude stream ended without a terminal result.', 'CLAUDE_RESULT_MISSING');
136
- const finalResult = terminal as ClaudePrintRunResult;
137
- return { sessionId: finalResult.sessionId, result: finalResult.result, exitCode: code };
138
- }
139
- }