@parall/claude-agent 1.58.2 → 1.60.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.
@@ -1,4 +1,5 @@
1
1
  import { randomUUID } from 'node:crypto';
2
+ import { newTurnEvidence, newTurnSink, } from './turn-sink.js';
2
3
  /**
3
4
  * Per-process registry that maps Parall WorkItem batches to Claude stdin
4
5
  * UUIDs. It owns lifecycle transition rules; process/stdout orchestration
@@ -28,17 +29,35 @@ export class ClaudeInputRegistry {
28
29
  hasPendingInjections() {
29
30
  return [...this.byKey.values()].some((delivery) => delivery.injected && !delivery.drained);
30
31
  }
31
- register(deliveryKey, lifecycle, injected) {
32
+ /**
33
+ * Injected inputs whose lifecycle has NOT reached a terminal state. A
34
+ * terminal delivery still counts as pending (its buffered copy owes frame
35
+ * boundary bookkeeping) but owes the server nothing — the lane complete
36
+ * defers on this predicate, never on hasPendingInjections, so a bookkeeping
37
+ * copy that never drains cannot hold the lane open past its lease. Drained
38
+ * is deliberately NOT part of this predicate: a discarded bookkeeping copy
39
+ * (drained, non-terminal) is still a running input — completing its lane
40
+ * would release the member for redrive mid-processing.
41
+ */
42
+ hasUnsettledInjections() {
43
+ return [...this.byKey.values()].some((delivery) => delivery.injected && !delivery.terminal);
44
+ }
45
+ register(deliveryKey, lifecycle, injected, noteActivity, log) {
32
46
  if (this.byKey.has(deliveryKey)) {
33
47
  throw new Error(`duplicate Claude delivery key ${deliveryKey}`);
34
48
  }
49
+ const commandUuid = randomUUID();
35
50
  const delivery = {
36
51
  deliveryKey,
37
- commandUuid: randomUUID(),
52
+ commandUuid,
38
53
  lifecycle,
39
54
  injected,
40
55
  drained: !injected,
41
56
  resultFailed: false,
57
+ sink: newTurnSink(`delivery ${deliveryKey}`, log),
58
+ evidence: newTurnEvidence(),
59
+ noteActivity,
60
+ sessionAnnounced: false,
42
61
  };
43
62
  this.byKey.set(deliveryKey, delivery);
44
63
  this.byCommand.set(delivery.commandUuid, delivery);
@@ -51,6 +70,26 @@ export class ClaudeInputRegistry {
51
70
  if (this.byCommand.get(delivery.commandUuid) === delivery) {
52
71
  this.byCommand.delete(delivery.commandUuid);
53
72
  }
73
+ // The sink stays open: apply() removes a drained delivery at its
74
+ // terminal BEFORE the pump pushes the terminal envelope its drain is
75
+ // waiting for. Only the pump closes sinks (process gone).
76
+ }
77
+ /**
78
+ * The buffered copy backing this delivery was discarded without a
79
+ * dispatch (already rendered into a frame the model saw), so the normal
80
+ * bookkeeping drain never comes. Its frame-boundary obligation is void:
81
+ * mark it drained so nothing waits on it, and drop it once terminal. A
82
+ * still-running input keeps its registration — byCommand must keep routing
83
+ * its lifecycle frames — and is dropped when its terminal state arrives
84
+ * (see apply/fail).
85
+ */
86
+ discardBookkeeping(deliveryKey) {
87
+ const delivery = this.byKey.get(deliveryKey);
88
+ if (!delivery)
89
+ return;
90
+ delivery.drained = true;
91
+ if (delivery.terminal)
92
+ this.remove(delivery);
54
93
  }
55
94
  async apply(delivery, state) {
56
95
  if (delivery.terminal || state === 'queued')
@@ -71,12 +110,19 @@ export class ClaudeInputRegistry {
71
110
  delivery.reportedState = 'completed';
72
111
  }
73
112
  delivery.terminal = 'completed';
113
+ // A discarded bookkeeping copy (drained without a dispatch) has no
114
+ // drain left to remove this entry — drop it at its terminal so it can
115
+ // never shadow a redelivered batch in findOverlapping.
116
+ if (delivery.drained)
117
+ this.remove(delivery);
74
118
  }
75
119
  async fail(delivery) {
76
120
  if (delivery.terminal)
77
121
  return;
78
122
  if (delivery.suppressFailReport) {
79
123
  delivery.terminal = 'settled';
124
+ if (delivery.drained)
125
+ this.remove(delivery);
80
126
  return;
81
127
  }
82
128
  try {
@@ -88,6 +134,8 @@ export class ClaudeInputRegistry {
88
134
  }
89
135
  finally {
90
136
  delivery.terminal ??= 'failed';
137
+ if (delivery.drained)
138
+ this.remove(delivery);
91
139
  }
92
140
  }
93
141
  async failBestEffort(delivery, log) {
@@ -25,10 +25,38 @@ export type ClaudeResultMeta = {
25
25
  /** First model key of `modelUsage` — the model the CLI actually used. */
26
26
  model?: string;
27
27
  };
28
+ /**
29
+ * The CLI's background-work frames (`system` subtypes). Every field is
30
+ * optional except the subtype.
31
+ * Observed on 2.1.227/2.1.258: `background_tasks_changed` (REPLACE
32
+ * semantics — every live task after the change), `task_started`,
33
+ * `task_progress`, `task_updated`, `task_notification` (a task finished or
34
+ * was stopped), `status`, `session_state_changed` (env-gated).
35
+ */
36
+ export type ClaudeRuntimeTaskEvent = {
37
+ type: 'runtime_task';
38
+ subtype: 'background_tasks_changed' | 'task_started' | 'task_progress' | 'task_updated' | 'task_notification' | 'status' | 'session_state_changed';
39
+ taskId?: string;
40
+ toolUseId?: string;
41
+ description?: string;
42
+ taskType?: string;
43
+ status?: string;
44
+ summary?: string;
45
+ isBackgrounded?: boolean;
46
+ tasks?: Array<{
47
+ taskId: string;
48
+ taskType?: string;
49
+ description?: string;
50
+ ambient?: boolean;
51
+ }>;
52
+ };
28
53
  export type ClaudeParsedEvent = RuntimeEvent | {
29
54
  type: 'runtime_init';
30
55
  sessionId?: string;
31
56
  capabilities: string[];
57
+ } | ClaudeRuntimeTaskEvent | {
58
+ type: 'user_text';
59
+ text: string;
32
60
  } | {
33
61
  type: 'runtime_activity';
34
62
  } | {
@@ -38,6 +66,10 @@ export type ClaudeParsedEvent = RuntimeEvent | {
38
66
  } | {
39
67
  type: 'assistant_error';
40
68
  message: string;
69
+ } | {
70
+ type: 'compact_boundary';
71
+ trigger?: string;
72
+ preTokens?: number;
41
73
  } | {
42
74
  type: 'turn_end';
43
75
  sessionId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"output-parser.d.ts","sourceRoot":"","sources":["../src/output-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,GAKpE;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,GAC5B;IACE,IAAI,EAAE,mBAAmB,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;CACvE,GAID;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAqB5C;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B,CAAC;AAgFN,wBAAuB,qBAAqB,CAC1C,QAAQ,EAAE,QAAQ,GACjB,cAAc,CAAC,iBAAiB,CAAC,CAkLnC"}
1
+ {"version":3,"file":"output-parser.d.ts","sourceRoot":"","sources":["../src/output-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EACH,0BAA0B,GAC1B,cAAc,GACd,eAAe,GACf,cAAc,GACd,mBAAmB,GACnB,QAAQ,GACR,uBAAuB,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC/F,CAAC;AAYF,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,GACpE,sBAAsB,GAItB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAKnC;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,GAC5B;IACE,IAAI,EAAE,mBAAmB,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;CACvE,GAID;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAI5C;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAqBlE;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B,CAAC;AAgFN,wBAAuB,qBAAqB,CAC1C,QAAQ,EAAE,QAAQ,GACjB,cAAc,CAAC,iBAAiB,CAAC,CA6NnC"}
@@ -1,3 +1,12 @@
1
+ const RUNTIME_TASK_SUBTYPES = new Set([
2
+ 'background_tasks_changed',
3
+ 'task_started',
4
+ 'task_progress',
5
+ 'task_updated',
6
+ 'task_notification',
7
+ 'status',
8
+ 'session_state_changed',
9
+ ]);
1
10
  function asTrimmedString(value) {
2
11
  if (typeof value !== 'string')
3
12
  return undefined;
@@ -91,20 +100,44 @@ export async function* parseClaudeStreamJson(readable) {
91
100
  const now = Date.now();
92
101
  const eventTimestampMs = parseEventTimestampMs(event) ?? now;
93
102
  const eventRecord = event;
94
- if (eventRecord.type === 'system' && eventRecord.subtype === 'init') {
95
- const sessionId = asTrimmedString(eventRecord.session_id);
96
- const capabilities = Array.isArray(eventRecord.capabilities)
97
- ? eventRecord.capabilities
98
- .map((capability) => asTrimmedString(capability))
99
- .filter((capability) => Boolean(capability))
100
- : [];
103
+ if (eventRecord.type === 'system' && eventRecord.subtype === 'compact_boundary') {
104
+ const meta = eventRecord.compact_metadata && typeof eventRecord.compact_metadata === 'object'
105
+ ? eventRecord.compact_metadata
106
+ : undefined;
107
+ const trigger = asTrimmedString(meta?.trigger);
108
+ const preTokens = asFiniteNumber(meta?.pre_tokens);
101
109
  yield {
102
- type: 'runtime_init',
103
- ...(sessionId ? { sessionId } : {}),
104
- capabilities,
110
+ type: 'compact_boundary',
111
+ ...(trigger ? { trigger } : {}),
112
+ ...(preTokens !== undefined ? { preTokens } : {}),
105
113
  };
106
114
  continue;
107
115
  }
116
+ if (eventRecord.type === 'system') {
117
+ if (eventRecord.subtype === 'init') {
118
+ const sessionId = asTrimmedString(eventRecord.session_id);
119
+ const capabilities = Array.isArray(eventRecord.capabilities)
120
+ ? eventRecord.capabilities
121
+ .map((capability) => asTrimmedString(capability))
122
+ .filter((capability) => Boolean(capability))
123
+ : [];
124
+ yield {
125
+ type: 'runtime_init',
126
+ ...(sessionId ? { sessionId } : {}),
127
+ capabilities,
128
+ };
129
+ continue;
130
+ }
131
+ const subtype = asTrimmedString(eventRecord.subtype);
132
+ if (subtype && RUNTIME_TASK_SUBTYPES.has(subtype)) {
133
+ yield parseRuntimeTask(subtype, eventRecord);
134
+ continue;
135
+ }
136
+ // hook_started / hook_response / thinking_tokens /
137
+ // ...: valid CLI progress with no projection.
138
+ yield { type: 'runtime_activity' };
139
+ continue;
140
+ }
108
141
  if (eventRecord.type === 'command_lifecycle') {
109
142
  const commandUuid = asTrimmedString(eventRecord.command_uuid);
110
143
  const state = asTrimmedString(eventRecord.state);
@@ -190,8 +223,20 @@ export async function* parseClaudeStreamJson(readable) {
190
223
  const content = message && typeof message === 'object'
191
224
  ? message.content
192
225
  : undefined;
226
+ if (typeof content === 'string') {
227
+ const text = content.trim();
228
+ if (text)
229
+ yield { type: 'user_text', text };
230
+ continue;
231
+ }
193
232
  if (!Array.isArray(content))
194
233
  continue;
234
+ if (!content.some((block) => block?.type === 'tool_result')) {
235
+ const text = stringifyContent(content).trim();
236
+ if (text)
237
+ yield { type: 'user_text', text };
238
+ continue;
239
+ }
195
240
  for (const block of content) {
196
241
  if (!block || typeof block !== 'object')
197
242
  continue;
@@ -239,8 +284,59 @@ export async function* parseClaudeStreamJson(readable) {
239
284
  ...(numTurns !== undefined ? { numTurns } : {}),
240
285
  resultMeta: extractResultMeta(eventRecord, isError, numTurns),
241
286
  };
287
+ continue;
288
+ }
289
+ // Any other well-formed frame (rate_limit_event, stream_event, ...) is
290
+ // CLI progress: refresh activity, never project.
291
+ yield { type: 'runtime_activity' };
292
+ }
293
+ }
294
+ function parseRuntimeTask(subtype, frame) {
295
+ const event = { type: 'runtime_task', subtype };
296
+ const taskId = asTrimmedString(frame.task_id);
297
+ if (taskId)
298
+ event.taskId = taskId;
299
+ const toolUseId = asTrimmedString(frame.tool_use_id);
300
+ if (toolUseId)
301
+ event.toolUseId = toolUseId;
302
+ const description = asTrimmedString(frame.description);
303
+ if (description)
304
+ event.description = description;
305
+ const taskType = asTrimmedString(frame.task_type);
306
+ if (taskType)
307
+ event.taskType = taskType;
308
+ const status = asTrimmedString(frame.status) ??
309
+ asTrimmedString(frame.patch?.status) ??
310
+ asTrimmedString(frame.state);
311
+ if (status)
312
+ event.status = status;
313
+ const summary = asTrimmedString(frame.summary);
314
+ if (summary)
315
+ event.summary = summary;
316
+ if (typeof frame.is_backgrounded === 'boolean')
317
+ event.isBackgrounded = frame.is_backgrounded;
318
+ if (Array.isArray(frame.tasks)) {
319
+ event.tasks = [];
320
+ for (const task of frame.tasks) {
321
+ if (!task || typeof task !== 'object')
322
+ continue;
323
+ const record = task;
324
+ const id = asTrimmedString(record.task_id);
325
+ if (!id)
326
+ continue;
327
+ const entry = { taskId: id };
328
+ const entryType = asTrimmedString(record.task_type);
329
+ if (entryType)
330
+ entry.taskType = entryType;
331
+ const entryDescription = asTrimmedString(record.description);
332
+ if (entryDescription)
333
+ entry.description = entryDescription;
334
+ if (record.ambient === true)
335
+ entry.ambient = true;
336
+ event.tasks.push(entry);
242
337
  }
243
338
  }
339
+ return event;
244
340
  }
245
341
  /** Snapshot the result frame's discriminator + usage fields (all optional). */
246
342
  function extractResultMeta(frame, isError, numTurns) {
@@ -0,0 +1,105 @@
1
+ import { type GatewayLogger, type RuntimeBusyState } from '@parall/agent-core';
2
+ import { ClaudeBusyTracker } from './busy-state.js';
3
+ import type { ClaudeInputDelivery, ClaudeInputRegistry } from './input-lifecycle.js';
4
+ import type { ClaudeParsedEvent } from './output-parser.js';
5
+ import { ClaudeRuntimeTurn } from './runtime-turn.js';
6
+ import type { ClaudeProcessHandle } from './session-manager.js';
7
+ import type { ClaudeTurnEndReason } from './turn-sink.js';
8
+ export type ClaudeProcessPumpHooks = {
9
+ /** system.init: capabilities + session id. Return a message to fail the process. */
10
+ onRuntimeInit(init: {
11
+ sessionId?: string;
12
+ capabilities: string[];
13
+ }): string | undefined;
14
+ /** Unrecoverable protocol state: the adapter kills the process. */
15
+ onFatal(): void;
16
+ /** stdout reached EOF (process gone). */
17
+ onEof(): void;
18
+ onRuntimeTurnOpened(turn: ClaudeRuntimeTurn): void;
19
+ onRuntimeTurnClosed(): void;
20
+ };
21
+ export type ClaudeProcessPumpOptions = {
22
+ sessionKey: string;
23
+ parser: AsyncGenerator<ClaudeParsedEvent>;
24
+ handle: ClaudeProcessHandle;
25
+ inputs: ClaudeInputRegistry;
26
+ hooks: ClaudeProcessPumpHooks;
27
+ log?: GatewayLogger;
28
+ followUpHoldMs?: number;
29
+ now?: () => number;
30
+ };
31
+ /**
32
+ * Single owner of one Claude subprocess's stdout. Reads every frame the CLI
33
+ * emits — during dispatches AND between them — and routes it:
34
+ *
35
+ * - `command_lifecycle` frames go to the delivery they name (stdin uuid).
36
+ * - Content frames (thinking / text / tool_call / tool_result / error) go to
37
+ * the delivery whose lifecycle is `started` and not yet terminal
38
+ * (claude-soft-steer-design.md: the lifecycle terminal, not `result`,
39
+ * bounds a delivery); with no started delivery they go to the open
40
+ * runtime-initiated turn, opening one if needed. A `queued` delivery never
41
+ * owns frames.
42
+ * - `result` frames attach turn-outcome evidence to the owner and close a
43
+ * runtime-initiated turn; a poison `num_turns: 0` resume artifact never
44
+ * opens or closes one.
45
+ * - task frames feed the busy ledger; `runtime_activity` only refreshes
46
+ * inactivity deadlines.
47
+ *
48
+ * Reading continuously also removes the latent stall where an unread
49
+ * self-started turn filled the OS pipe and blocked the CLI.
50
+ */
51
+ export declare class ClaudeProcessPump {
52
+ private readonly opts;
53
+ readonly busy: ClaudeBusyTracker;
54
+ capabilities: Set<string>;
55
+ sessionId: string | undefined;
56
+ runtimeTurn: ClaudeRuntimeTurn | null;
57
+ private closed;
58
+ private idleWaiters;
59
+ private idleTimer;
60
+ private activeDrain;
61
+ private readonly now;
62
+ constructor(opts: ClaudeProcessPumpOptions);
63
+ start(): void;
64
+ /** The dispatch generator currently draining `delivery` (owner preference). */
65
+ setActiveDrain(delivery: ClaudeInputDelivery, noteActivity?: () => void): void;
66
+ clearActiveDrain(delivery: ClaudeInputDelivery): void;
67
+ hasStartedDelivery(): boolean;
68
+ /**
69
+ * The CLI has (or is about to start) work no dispatch asked for: a
70
+ * runtime-initiated turn is open, or a finished background task's
71
+ * follow-up hold is pending. Lazy restarts, dispatch aborts and
72
+ * `whenIdle` all defer to it.
73
+ */
74
+ hasOwnWork(now?: number): boolean;
75
+ busyState(now?: number): RuntimeBusyState;
76
+ /** Dispatch abort: fail every live delivery and release its drain. */
77
+ abortDeliveries(message: string): void;
78
+ /**
79
+ * The adapter is terminating the process (kill / reset / shutdown): every
80
+ * drain and the open runtime turn end now, before stdout EOF is observed.
81
+ */
82
+ close(reason: ClaudeTurnEndReason, message: string): void;
83
+ /**
84
+ * Run `cb` once the CLI has nothing left to do on its own: no
85
+ * runtime-initiated turn open and no follow-up hold pending (a hold that
86
+ * turns into a follow-up turn is waited for as well). Immediate when
87
+ * already idle or closed.
88
+ */
89
+ whenIdle(cb: () => void): void;
90
+ private checkIdle;
91
+ closeRuntimeTurn(reason: ClaudeTurnEndReason, message?: string): void;
92
+ private run;
93
+ private route;
94
+ private touchAll;
95
+ private liveDeliveries;
96
+ private ownerFor;
97
+ private openRuntimeTurn;
98
+ private handleInit;
99
+ private handleLifecycle;
100
+ private handleTask;
101
+ private handleTurnEnd;
102
+ private pushErrorToDeliveries;
103
+ private handleEof;
104
+ }
105
+ //# sourceMappingURL=process-pump.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-pump.d.ts","sourceRoot":"","sources":["../src/process-pump.ts"],"names":[],"mappings":"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"}