@excitedjs/agent-runtime-claude-code 0.2.0-alpha.g0ddd418597ca

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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +32 -0
  3. package/dist/args.d.ts +71 -0
  4. package/dist/args.d.ts.map +1 -0
  5. package/dist/args.js +87 -0
  6. package/dist/args.js.map +1 -0
  7. package/dist/config.d.ts +71 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +86 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/diagnostic.d.ts +12 -0
  12. package/dist/diagnostic.d.ts.map +1 -0
  13. package/dist/diagnostic.js +25 -0
  14. package/dist/diagnostic.js.map +1 -0
  15. package/dist/index.d.ts +18 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +18 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/internal/completion-body.d.ts +38 -0
  20. package/dist/internal/completion-body.d.ts.map +1 -0
  21. package/dist/internal/completion-body.js +62 -0
  22. package/dist/internal/completion-body.js.map +1 -0
  23. package/dist/internal/config-validate.d.ts +23 -0
  24. package/dist/internal/config-validate.d.ts.map +1 -0
  25. package/dist/internal/config-validate.js +122 -0
  26. package/dist/internal/config-validate.js.map +1 -0
  27. package/dist/internal/os.d.ts +30 -0
  28. package/dist/internal/os.d.ts.map +1 -0
  29. package/dist/internal/os.js +81 -0
  30. package/dist/internal/os.js.map +1 -0
  31. package/dist/internal/turn-render.d.ts +22 -0
  32. package/dist/internal/turn-render.d.ts.map +1 -0
  33. package/dist/internal/turn-render.js +40 -0
  34. package/dist/internal/turn-render.js.map +1 -0
  35. package/dist/mcp-config.d.ts +19 -0
  36. package/dist/mcp-config.d.ts.map +1 -0
  37. package/dist/mcp-config.js +22 -0
  38. package/dist/mcp-config.js.map +1 -0
  39. package/dist/provider-ref.d.ts +8 -0
  40. package/dist/provider-ref.d.ts.map +1 -0
  41. package/dist/provider-ref.js +8 -0
  42. package/dist/provider-ref.js.map +1 -0
  43. package/dist/provider.d.ts +60 -0
  44. package/dist/provider.d.ts.map +1 -0
  45. package/dist/provider.js +110 -0
  46. package/dist/provider.js.map +1 -0
  47. package/dist/rpc.d.ts +45 -0
  48. package/dist/rpc.d.ts.map +1 -0
  49. package/dist/rpc.js +212 -0
  50. package/dist/rpc.js.map +1 -0
  51. package/dist/runtime.d.ts +174 -0
  52. package/dist/runtime.d.ts.map +1 -0
  53. package/dist/runtime.js +464 -0
  54. package/dist/runtime.js.map +1 -0
  55. package/dist/stream.d.ts +96 -0
  56. package/dist/stream.d.ts.map +1 -0
  57. package/dist/stream.js +289 -0
  58. package/dist/stream.js.map +1 -0
  59. package/dist/supervisor.d.ts +17 -0
  60. package/dist/supervisor.d.ts.map +1 -0
  61. package/dist/supervisor.js +170 -0
  62. package/dist/supervisor.js.map +1 -0
  63. package/dist/types.d.ts +133 -0
  64. package/dist/types.d.ts.map +1 -0
  65. package/dist/types.js +7 -0
  66. package/dist/types.js.map +1 -0
  67. package/package.json +53 -0
@@ -0,0 +1,464 @@
1
+ /**
2
+ * `builtin:claude-code` AgentRuntime (issue #110 PR6, resident stream-json
3
+ * transport since issue #120; extracted into `@excitedjs/agent-runtime-claude-code`
4
+ * in issue #209).
5
+ *
6
+ * A real second agent runtime that proves the AgentRuntimeProvider abstraction
7
+ * is not "Codex renamed". Like Codex it runs a **resident child process**
8
+ * supervised for the runtime's lifetime — but it differs in every
9
+ * runtime-specific dimension:
10
+ *
11
+ * - **Stream-json over stdio, not an app-server WebSocket.** The resident child
12
+ * is `claude --print --input-format stream-json --output-format stream-json`
13
+ * (see `./args.ts`); turns are NDJSON `user` lines on stdin and
14
+ * `init`/`assistant`/`result` envelopes on stdout (see `./stream.ts`). There
15
+ * is no `initialize` handshake — the child emits `init` lazily with the first
16
+ * turn — so readiness is "child spawned", not "handshake completed".
17
+ * - **MCP injection is a JSON config document** (`--mcp-config <file>`), not
18
+ * Codex's `-c mcp_servers.*` TOML CLI flags.
19
+ * - **Runtime-owned config** is `DispatcherClaudeCodeConfig` (bin / model /
20
+ * permission_mode / remote_control / extra_args / extra_env), distinct from
21
+ * the Codex config.
22
+ * - **Completion delivery** is a plain user turn (no fake task-notification),
23
+ * not the Codex inbox-then-trigger path.
24
+ *
25
+ * Process spawning goes through an injectable {@link ClaudeCodeSessionFactory}
26
+ * seam (mirroring Codex's process-factory seam), so the lifecycle contract is
27
+ * fully unit-testable with a fake session. A live `claude` binary is exercised
28
+ * only by the opt-in live test.
29
+ *
30
+ * Failure contract (unchanged by #120): a turn failure (spawn error, child
31
+ * exit, error `result`) is never swallowed. For inbound/restart turns it drives
32
+ * the runtime to `degraded` with a persisted `last_error` (observable via
33
+ * status/doctor). For `completionInput` it surfaces as a `failed`
34
+ * result the caller can act on (PR8 delivery retry). `channelInput` still
35
+ * returns after accept (submit != completion) so the channel can ack promptly.
36
+ *
37
+ * Restart: an unexpected child exit marks the runtime `degraded`; the next turn
38
+ * re-spawns the resident child with `--resume <session_id>`, restoring the
39
+ * conversation. There is no background backoff timer — re-spawn is lazy and
40
+ * bound to the (serialized) turn queue, so it stays deterministic.
41
+ *
42
+ * Per-turn idle deadline: a turn whose still-alive child goes silent — never
43
+ * emitting another stream line (a stall, or a wait on input the runtime cannot
44
+ * satisfy) — would otherwise pend forever and wedge the serial queue, and behind
45
+ * it TeamMate completion delivery, which awaits this runtime. `turn_timeout_ms`
46
+ * is a *max-idle* window (issue #156): it is reset on every inbound stream line,
47
+ * so a long but continuously-streaming turn (e.g. a deep audit running many
48
+ * tool calls for far longer than the window) is never reaped, while a child that
49
+ * emits nothing for the whole window still is — turning an infinite hang into a
50
+ * normal degraded + `last_error` (inbound) or `failed` delivery result.
51
+ *
52
+ * Reference: the resident stream-json protocol model and process-supervision
53
+ * shape are adapted from the Claudemux `next` implementation; the AgentRuntime /
54
+ * Channel / DispatcherService boundaries (provider seam, runtime-owned MCP
55
+ * injection, degraded/last_error status, TeamMate delivery result contract) are
56
+ * Dreamux's own, per `.agents/decisions/agent-runtime-provider.md`.
57
+ */
58
+ import { mkdir, writeFile } from 'node:fs/promises';
59
+ import { dirname, join } from 'node:path';
60
+ import { BUILTIN_CLAUDE_CODE_PROVIDER_REF } from './provider-ref.js';
61
+ import { claudeCodeResidentArgs } from './args.js';
62
+ import { stringifyClaudeCodeMcpConfig } from './mcp-config.js';
63
+ import { renderChannelInput, resolveCompletionBody } from '@excitedjs/dreamux-utils';
64
+ import { CLAUDE_CODE_AGENT_RUNTIME_CAPABILITIES } from './provider.js';
65
+ let nextRuntimeInstanceId = 0;
66
+ /**
67
+ * Status line opening a TeamMate completion turn. Plain English, status-varied —
68
+ * NOT claude-code's native `<task-notification>` XML. The old XML mimicked
69
+ * claude-code's real task-notification system, so the model could mistake the
70
+ * fabricated task-id / output-file for a live background task and act on them
71
+ * (hallucination / harness collision). A plain user turn avoids that entirely.
72
+ */
73
+ function completionStatusLine(completion) {
74
+ switch (completion.status) {
75
+ case 'completed':
76
+ return `TeamMate ${completion.source} has finished its task.`;
77
+ case 'failed':
78
+ return `TeamMate ${completion.source}'s task failed.`;
79
+ case 'stopped':
80
+ return `TeamMate ${completion.source}'s task was stopped.`;
81
+ }
82
+ }
83
+ /**
84
+ * Build the plain-text completion turn. The result is inlined when short; when
85
+ * it overflows the inline budget the full result is spilled to a file (see
86
+ * {@link resolveCompletionBody}) and only the path is inlined.
87
+ */
88
+ async function buildCompletionTurnText(completion, spillDir) {
89
+ const line = completionStatusLine(completion);
90
+ const body = await resolveCompletionBody(completion, spillDir);
91
+ return body.kind === 'inline'
92
+ ? `${line} Output below:\n\n${body.text}`
93
+ : `${line} The output is too long, so the full result was saved to a file:\n\n${body.path}`;
94
+ }
95
+ function errMessage(err) {
96
+ return err instanceof Error ? err.message : String(err);
97
+ }
98
+ /**
99
+ * The Claude Code agent runtime for one dispatcher. A single resident
100
+ * stream-json child serves every turn. Turns run serially (one at a time) and
101
+ * `channelInput` returns after the message is accepted — not after the turn
102
+ * completes — matching the Codex runtime's submit-then-serialize contract.
103
+ */
104
+ export class ClaudeCodeRuntime {
105
+ deps;
106
+ providerRef = BUILTIN_CLAUDE_CODE_PROVIDER_REF;
107
+ dispatcherId;
108
+ config;
109
+ bin;
110
+ cwd;
111
+ mcpConfigPath;
112
+ mcpConfigDoc;
113
+ stderrLogPath;
114
+ completionSpillDir;
115
+ logger;
116
+ status = 'declared';
117
+ threadId;
118
+ resumed;
119
+ stopped = false;
120
+ seen = new Set();
121
+ queue = Promise.resolve();
122
+ runtimeInstanceId = ++nextRuntimeInstanceId;
123
+ turnCounter = 0;
124
+ session = null;
125
+ lastResult = null;
126
+ activeChannelTurn = null;
127
+ constructor(identity, deps) {
128
+ this.deps = deps;
129
+ this.dispatcherId = identity.runtime_id;
130
+ this.config = deps.config;
131
+ this.bin = deps.resolveBinPath(this.config.bin);
132
+ this.cwd = deps.cwd;
133
+ this.mcpConfigPath = join(deps.paths.dispatcherDir(this.dispatcherId), 'mcp.json');
134
+ this.mcpConfigDoc = stringifyClaudeCodeMcpConfig(deps.mcpServers);
135
+ // Compose the resident stream-json child's stderr log under the neutral
136
+ // central logs root (B2): core no longer names a per-runtime log file. The
137
+ // host supplies a unique, filesystem-safe `runtime_id`.
138
+ this.stderrLogPath = join(deps.paths.logsDir(), 'claude-code', `${this.dispatcherId}.stderr.log`);
139
+ this.completionSpillDir = deps.paths.completionSpillDir(this.dispatcherId);
140
+ this.threadId = identity.checkpoint_id ?? null;
141
+ this.resumed = (identity.checkpoint_id ?? null) !== null;
142
+ this.logger = deps.logger ?? consoleFallbackLogger(this.dispatcherId);
143
+ }
144
+ getStatus() {
145
+ return this.status;
146
+ }
147
+ getCapabilities() {
148
+ return CLAUDE_CODE_AGENT_RUNTIME_CAPABILITIES;
149
+ }
150
+ getThreadId() {
151
+ return this.threadId;
152
+ }
153
+ wasThreadResumed() {
154
+ return this.resumed;
155
+ }
156
+ async getLast() {
157
+ return this.lastResult;
158
+ }
159
+ async getContext() {
160
+ return null;
161
+ }
162
+ async resume(input = {}) {
163
+ if (input.checkpoint !== undefined && input.checkpoint !== null) {
164
+ if (input.checkpoint.kind !== 'claudeCodeSession') {
165
+ throw new Error(`unsupported resume checkpoint for Claude Code runtime: ${input.checkpoint.kind}`);
166
+ }
167
+ this.threadId = input.checkpoint.id;
168
+ this.resumed = true;
169
+ }
170
+ await this.start();
171
+ }
172
+ async start() {
173
+ await this.setStatus('starting');
174
+ try {
175
+ await mkdir(dirname(this.mcpConfigPath), { recursive: true });
176
+ await writeFile(this.mcpConfigPath, this.mcpConfigDoc, { mode: 0o600 });
177
+ // Spawn the resident child up front so the runtime is truly resident
178
+ // (Codex-aligned). A missing/broken `claude` binary fails here and drives
179
+ // the runtime to degraded + throws, rather than a silent no-op.
180
+ await this.ensureSession();
181
+ }
182
+ catch (err) {
183
+ await this.setStatus('degraded', err);
184
+ throw err;
185
+ }
186
+ await this.setStatus('ready');
187
+ }
188
+ async stop() {
189
+ if (this.stopped)
190
+ return;
191
+ this.stopped = true;
192
+ await this.setStatus('stopping');
193
+ const session = this.session;
194
+ this.session = null;
195
+ if (session !== null) {
196
+ try {
197
+ await session.stop();
198
+ }
199
+ catch (err) {
200
+ this.log('warn', 'claude-code session stop errored', err);
201
+ }
202
+ }
203
+ await this.setStatus('stopped');
204
+ }
205
+ async systemInput(notice) {
206
+ if (this.stopped)
207
+ return { status: 'stopped' };
208
+ const turnId = this.nextTurnId('system');
209
+ void this.runTurnOnQueue(notice.text, turnId).then(() => this.markTurnSucceeded(turnId), (err) => this.markTurnFailed(turnId, err));
210
+ return { status: 'submitted', turnId };
211
+ }
212
+ async channelInput(input, hooks = {}) {
213
+ if (this.stopped)
214
+ return { status: 'stopped' };
215
+ const key = input.sourceId;
216
+ if (key !== '' && this.seen.has(key))
217
+ return { status: 'duplicate' };
218
+ if (key !== '')
219
+ this.seen.add(key);
220
+ try {
221
+ await hooks.onAccepted?.(input);
222
+ }
223
+ catch (err) {
224
+ // onAccepted is a best-effort side effect (e.g. a channel reaction); a
225
+ // failure there must not drop the turn.
226
+ this.log('warn', 'claude-code onAccepted hook failed', err);
227
+ }
228
+ // This runtime owns wrapping the channel input into its delivery shape: a
229
+ // structured channel turn becomes the native `<channel source="…">` block;
230
+ // a plain turn passes through unchanged.
231
+ const text = renderChannelInput(input);
232
+ const active = this.activeChannelTurn;
233
+ if (active !== null) {
234
+ try {
235
+ await this.steerChannelTurn(active, text);
236
+ return { status: 'submitted', turnId: active.turnId };
237
+ }
238
+ catch (err) {
239
+ return {
240
+ status: 'failed',
241
+ error: err instanceof Error ? err : new Error(String(err)),
242
+ };
243
+ }
244
+ }
245
+ const turnId = this.nextTurnId('turn');
246
+ const channelTurn = {
247
+ turnId,
248
+ pendingSteers: [],
249
+ session: null,
250
+ steerQueue: Promise.resolve(),
251
+ };
252
+ this.activeChannelTurn = channelTurn;
253
+ // Submit-then-serialize: return after accept (so the channel can ack
254
+ // promptly), run the turn on the serial queue. A turn failure cannot be
255
+ // returned to this caller without blocking the channel ack on full turn
256
+ // completion. Instead, a failed turn drives the runtime to `degraded` with a
257
+ // persisted `last_error` (visible via status/doctor) — never swallowed.
258
+ void this.runChannelTurnOnQueue(text, channelTurn).then(() => this.markTurnSucceeded(turnId), (err) => this.markTurnFailed(turnId, err));
259
+ return { status: 'submitted', turnId };
260
+ }
261
+ async completionInput(completion) {
262
+ if (this.stopped) {
263
+ return { status: 'unsupported', reason: 'runtime stopped' };
264
+ }
265
+ // Plain user-turn delivery: a stream-json user message marked
266
+ // `isSynthetic: false`, so claude-code treats it as ordinary human input
267
+ // rather than routing it through its native task-notification harness path.
268
+ // Submit-then-serialize: return accepted at enqueue so delivery acceptance
269
+ // is decoupled from model thinking time.
270
+ let text;
271
+ try {
272
+ text = await buildCompletionTurnText(completion, this.completionSpillDir);
273
+ }
274
+ catch (err) {
275
+ return {
276
+ status: 'failed',
277
+ error: err instanceof Error ? err : new Error(String(err)),
278
+ };
279
+ }
280
+ const turnId = `claude-teammate-${completion.id}`;
281
+ void this.runTurnOnQueue(text, turnId, { isSynthetic: false }).then(() => this.markTurnSucceeded(turnId), (err) => this.markTurnFailed(turnId, err));
282
+ return { status: 'accepted' };
283
+ }
284
+ /**
285
+ * Chain a turn onto the serial queue. Returns a promise that resolves when
286
+ * this turn completes and rejects when it fails, so awaiting callers (delivery)
287
+ * see the real outcome. The queue itself continues regardless of outcome so a
288
+ * failed turn does not wedge later turns.
289
+ */
290
+ runTurnOnQueue(prompt, turnId, options) {
291
+ const run = this.queue.then(() => this.runTurn(prompt, turnId, options));
292
+ this.queue = run.then(() => undefined, () => undefined);
293
+ return run;
294
+ }
295
+ runChannelTurnOnQueue(prompt, active) {
296
+ const run = this.queue.then(() => this.runChannelTurn(prompt, active));
297
+ this.queue = run.then(() => undefined, () => undefined);
298
+ return run;
299
+ }
300
+ async runChannelTurn(prompt, active) {
301
+ const session = await this.ensureSession();
302
+ const steers = active.pendingSteers.splice(0);
303
+ const fullPrompt = steers.length === 0 ? prompt : [prompt, ...steers].join('\n\n');
304
+ const outcome = session.submitTurn(fullPrompt);
305
+ active.session = session;
306
+ try {
307
+ await this.applyTurnOutcome(await outcome, active.turnId);
308
+ }
309
+ finally {
310
+ active.session = null;
311
+ if (this.activeChannelTurn === active)
312
+ this.activeChannelTurn = null;
313
+ active.pendingSteers = [];
314
+ }
315
+ }
316
+ async steerChannelTurn(active, prompt) {
317
+ const session = active.session;
318
+ if (session === null) {
319
+ active.pendingSteers.push(prompt);
320
+ return;
321
+ }
322
+ const steer = active.steerQueue.then(() => session.steerTurn(prompt, { priority: 'next' }));
323
+ active.steerQueue = steer.then(() => undefined, () => undefined);
324
+ await steer;
325
+ }
326
+ async markTurnSucceeded(turnId) {
327
+ this.deps.onTurnSettled?.({ turnId, status: 'completed' });
328
+ if (this.stopped)
329
+ return;
330
+ if (this.status !== 'ready')
331
+ await this.setStatus('ready');
332
+ }
333
+ async markTurnFailed(turnId, err) {
334
+ this.log('error', `claude-code turn ${turnId} failed`, err);
335
+ // A turn that fails after stop() was requested (the resident child is being
336
+ // torn down) is a `stopped` settlement; otherwise it is a genuine `failed`.
337
+ // Fire before the stopped early-return so an interrupted teammate turn is
338
+ // never lost.
339
+ this.deps.onTurnSettled?.({
340
+ turnId,
341
+ status: this.stopped ? 'stopped' : 'failed',
342
+ error: err instanceof Error ? err : new Error(String(err)),
343
+ });
344
+ if (this.stopped)
345
+ return;
346
+ // Surface the failure as durable runtime state rather than swallowing it.
347
+ await this.setStatus('degraded', err);
348
+ }
349
+ /**
350
+ * Ensure a live resident session exists, spawning (or re-spawning after an
351
+ * unexpected exit) as needed. Re-spawn resumes the persisted session id so the
352
+ * conversation survives a crash.
353
+ */
354
+ async ensureSession() {
355
+ if (this.session !== null && this.session.isAlive())
356
+ return this.session;
357
+ const args = claudeCodeResidentArgs({
358
+ config: this.config,
359
+ mcpConfigPath: this.mcpConfigPath,
360
+ resumeSessionId: this.threadId,
361
+ systemPromptContent: this.deps.systemPromptContent,
362
+ skillSources: this.deps.skillSources,
363
+ });
364
+ const session = this.deps.sessionFactory({
365
+ bin: this.bin,
366
+ args,
367
+ cwd: this.cwd,
368
+ env: this.buildProcessEnv(this.config.extra_env),
369
+ stderrLogPath: this.stderrLogPath,
370
+ turnTimeoutMs: this.config.turn_timeout_ms,
371
+ remoteControl: this.config.remote_control,
372
+ onRemoteControlUrl: this.config.remote_control
373
+ ? (url) => {
374
+ this.log('info', `claude-code remote control URL: ${url}`);
375
+ }
376
+ : undefined,
377
+ log: (level, msg, err) => this.log(level, msg, err),
378
+ });
379
+ session.setOnExit(() => {
380
+ void this.onSessionExit(session);
381
+ });
382
+ await session.start();
383
+ this.session = session;
384
+ return session;
385
+ }
386
+ /** React to an unexpected resident-child exit: degrade and drop the session. */
387
+ async onSessionExit(session) {
388
+ if (this.session !== session)
389
+ return; // already replaced/stopped
390
+ this.session = null;
391
+ if (this.stopped)
392
+ return;
393
+ this.log('error', 'claude-code resident child exited unexpectedly');
394
+ await this.setStatus('degraded', new Error('claude resident child exited'));
395
+ }
396
+ async runTurn(prompt, turnId, options) {
397
+ const session = await this.ensureSession();
398
+ await this.runTurnWithSession(session, prompt, turnId, options);
399
+ }
400
+ async runTurnWithSession(session, prompt, turnId, options) {
401
+ const outcome = await session.submitTurn(prompt, options);
402
+ await this.applyTurnOutcome(outcome, turnId);
403
+ }
404
+ async applyTurnOutcome(outcome, turnId) {
405
+ if (outcome.sessionId !== null &&
406
+ outcome.sessionId !== '' &&
407
+ outcome.sessionId !== this.threadId) {
408
+ this.threadId = outcome.sessionId;
409
+ await this.deps.state.setThreadId(this.dispatcherId, outcome.sessionId);
410
+ }
411
+ if (!outcome.isError)
412
+ this.lastResult = { text: outcome.text };
413
+ if (outcome.isError) {
414
+ const detail = outcome.errors.length > 0
415
+ ? outcome.errors.join('; ')
416
+ : (outcome.subtype ?? 'unknown error');
417
+ throw new Error(`claude turn ${turnId} returned an error result: ${detail}`);
418
+ }
419
+ this.log('info', `claude-code turn ${turnId} completed`);
420
+ }
421
+ nextTurnId(kind) {
422
+ return `claude-${kind}-${this.runtimeInstanceId}-${++this.turnCounter}`;
423
+ }
424
+ buildProcessEnv(extraEnv) {
425
+ // Neutral env boundary: { ...process.env, ...injectEnv, ...extra_env }.
426
+ // `injectEnv` is the host's optional injection seam (empty today); `extraEnv`
427
+ // is this provider's own `config.extra_env`, merged last so it can override.
428
+ return {
429
+ ...globalThis.process.env,
430
+ ...(this.deps.injectEnv ?? {}),
431
+ ...extraEnv,
432
+ };
433
+ }
434
+ async setStatus(status, err) {
435
+ this.status = status;
436
+ await this.deps.state.setStatus(this.dispatcherId, status, err !== undefined ? { last_error: errMessage(err) } : {});
437
+ }
438
+ log(level, msg, err) {
439
+ this.logger[level](msg, err !== undefined ? { err } : undefined);
440
+ }
441
+ }
442
+ /**
443
+ * Minimal `console.error`-backed logger the runtime falls back to when the host
444
+ * passes none (the bare generic-loader / standalone path). Owned here, never in
445
+ * `@excitedjs/dreamux-types` (which is declaration-only).
446
+ */
447
+ function consoleFallbackLogger(dispatcherId) {
448
+ const sink = (level) => (message, fields) => {
449
+ const prefix = `[claude-code ${dispatcherId}] ${level}`;
450
+ const err = fields?.['err'];
451
+ if (err !== undefined)
452
+ console.error(prefix, message, err);
453
+ else
454
+ console.error(prefix, message);
455
+ };
456
+ return {
457
+ error: sink('error'),
458
+ warn: sink('warn'),
459
+ info: sink('info'),
460
+ debug: () => { },
461
+ trace: () => { },
462
+ };
463
+ }
464
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * The Claude Code stream-json wire protocol (issue #120).
3
+ *
4
+ * A clean-room model of the NDJSON envelopes the `claude` CLI emits and accepts
5
+ * on stdio under `--input-format stream-json --output-format stream-json`. This
6
+ * is what makes the `builtin:claude-code` runtime *resident*: one long-lived
7
+ * `claude --print` process consumes user-message lines on stdin and streams
8
+ * `init` / `assistant` / `result` envelopes on stdout, instead of a fresh
9
+ * one-shot process per turn.
10
+ *
11
+ * Two design rules, both load-bearing:
12
+ *
13
+ * - **Forward-tolerant by construction.** The CLI's real envelope set is much
14
+ * wider than anything Dreamux consumes (extra `system` subtypes, rate-limit
15
+ * events, hook lifecycle, streamlined variants, and extra `result` fields).
16
+ * This parser never validates a closed schema and never throws on an unknown
17
+ * `type` / `subtype`; it reads only the fields the runtime needs and ignores
18
+ * the rest. A wider or newer CLI build cannot break a turn.
19
+ *
20
+ * - **Pure, no IO.** No process, no clock, no filesystem — so the line framer,
21
+ * the line parser, and the turn aggregator are unit-tested against synthetic
22
+ * envelope sequences (hand-authored to the real wire shapes) with no live
23
+ * `claude` binary.
24
+ *
25
+ * Public-safety note: this module is a generic protocol model. It carries no
26
+ * Feishu identifiers, tokens, private paths, or environment-specific details.
27
+ */
28
+ import type { JsonObject, ParsedLine, TurnOutcome, TurnSubmitOptions } from './types.js';
29
+ export type { JsonObject, ParsedLine, ResultEnvelope, TurnOutcome, } from './types.js';
30
+ /**
31
+ * Incremental newline framer. The child's stdout is NDJSON but arrives in
32
+ * arbitrary chunks; `push` returns the complete lines so far and buffers a
33
+ * trailing partial line until its newline lands. Blank lines are dropped.
34
+ */
35
+ export declare class LineBuffer {
36
+ private buf;
37
+ push(chunk: string): string[];
38
+ /** Any buffered bytes with no trailing newline (e.g. at stream end). */
39
+ flush(): string | null;
40
+ }
41
+ /**
42
+ * Join the text blocks of an Anthropic assistant `message.content` array.
43
+ * `thinking` and `tool_use` blocks contribute no visible text and are skipped.
44
+ */
45
+ export declare function assistantText(message: unknown): string;
46
+ /**
47
+ * Decode one stdout line. Never throws: a non-JSON line becomes `parse_error`,
48
+ * and a JSON object of an unmodelled type becomes `other`.
49
+ */
50
+ export declare function parseLine(line: string): ParsedLine;
51
+ /**
52
+ * One user turn as a stream-json `user` message line (no trailing newline).
53
+ *
54
+ * `isSynthetic` / `priority` are siblings of `message` on the stdin envelope
55
+ * (claude-code SDKUserMessage schema), not part of the message body. They are
56
+ * only set for the native completion-notification idiom; a plain channel turn
57
+ * omits them entirely and reads as a normal human user turn.
58
+ */
59
+ export declare function buildUserMessage(text: string, options?: TurnSubmitOptions): string;
60
+ /** Enable Claude Code Remote Control via a stream-json control request. */
61
+ export declare function buildRemoteControlEnable(requestId: string): string;
62
+ /**
63
+ * Answer a `can_use_tool` control request with `allow`. A Dreamux dispatcher
64
+ * runs unattended, so the answer for a runtime that has no human to consult is
65
+ * "allow"; `updatedInput` echoes the tool's original input back unchanged.
66
+ *
67
+ * This is a defensive path: under a bypassing permission mode the CLI does not
68
+ * gate tools, so `can_use_tool` is not normally emitted. It is wired so that if
69
+ * a build or mode does emit one, the runtime answers it rather than leaving the
70
+ * turn waiting on an unanswered control request.
71
+ */
72
+ export declare function buildCanUseToolAllow(requestId: string, input: JsonObject): string;
73
+ /** Acknowledge any other control request with a bare success so the CLI proceeds. */
74
+ export declare function buildControlAck(requestId: string): string;
75
+ /**
76
+ * Accumulates the envelopes of a single turn and resolves a `TurnOutcome` when
77
+ * the `result` lands. One aggregator per turn: feed every `ParsedLine`, then
78
+ * read `outcome()` once `done` is true.
79
+ *
80
+ * The final text prefers the `result.result` (the CLI's own canonical answer)
81
+ * and falls back to the latest `assistant` snapshot — so a turn that ends
82
+ * tool-only or whose result text is empty still surfaces whatever the model
83
+ * last said.
84
+ */
85
+ export declare class TurnAggregator {
86
+ private lastAssistantText;
87
+ private result;
88
+ private initSessionId;
89
+ /** Returns `true` once the terminal `result` has been seen. */
90
+ get done(): boolean;
91
+ /** The session id from `init` (or the result), once known. */
92
+ get sessionId(): string | null;
93
+ accept(line: ParsedLine): void;
94
+ outcome(): TurnOutcome | null;
95
+ }
96
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EAEV,WAAW,EACX,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAC;AAYpB;;;;GAIG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,GAAG,CAAM;IAEjB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAc7B,wEAAwE;IACxE,KAAK,IAAI,MAAM,GAAG,IAAI;CAKvB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CActD;AAuBD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAkElD;AAID;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CAQR;AAED,2EAA2E;AAC3E,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMlE;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,CASjF;AAED,qFAAqF;AACrF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKzD;AAID;;;;;;;;;GASG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,aAAa,CAAuB;IAE5C,+DAA+D;IAC/D,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,8DAA8D;IAC9D,IAAI,SAAS,IAAI,MAAM,GAAG,IAAI,CAE7B;IAED,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAgB9B,OAAO,IAAI,WAAW,GAAG,IAAI;CAa9B"}