@alpacakit/agents 0.1.0-beta.20 → 0.1.0-beta.21

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 (140) hide show
  1. package/README.md +60 -0
  2. package/dist/agents/claude.d.ts.map +1 -1
  3. package/dist/agents/claude.js +3 -0
  4. package/dist/agents/codex.d.ts.map +1 -1
  5. package/dist/agents/codex.js +4 -0
  6. package/dist/agents/openai-compatible/config.d.ts.map +1 -1
  7. package/dist/agents/openai-compatible/config.js +5 -0
  8. package/dist/agents/openai-compatible/fetch-engine.d.ts.map +1 -1
  9. package/dist/agents/openai-compatible/fetch-engine.js +6 -0
  10. package/dist/agents/openai-compatible/pi/module.d.ts.map +1 -1
  11. package/dist/agents/openai-compatible/pi/module.js +1 -0
  12. package/dist/agents/openai-compatible/pi/sandbox.js +2 -0
  13. package/dist/agents/openai-compatible/response.js +1 -0
  14. package/dist/auth/profile-store.d.ts.map +1 -1
  15. package/dist/auth/profile-store.js +1 -0
  16. package/dist/auth/secrets.d.ts.map +1 -1
  17. package/dist/auth/secrets.js +2 -0
  18. package/dist/codex/app-server.js +6 -0
  19. package/dist/core/controlled-process.d.ts +98 -0
  20. package/dist/core/controlled-process.d.ts.map +1 -0
  21. package/dist/core/controlled-process.js +29 -0
  22. package/dist/core/error.d.ts +25 -0
  23. package/dist/core/error.d.ts.map +1 -1
  24. package/dist/core/error.js +32 -0
  25. package/dist/core/node-controlled-exec.d.ts +3 -0
  26. package/dist/core/node-controlled-exec.d.ts.map +1 -0
  27. package/dist/core/node-controlled-exec.js +32 -0
  28. package/dist/core/node-ports.d.ts +1 -0
  29. package/dist/core/node-ports.d.ts.map +1 -1
  30. package/dist/core/node-ports.js +9 -1
  31. package/dist/core/ports.d.ts +5 -0
  32. package/dist/core/ports.d.ts.map +1 -1
  33. package/dist/fleet/fleet.d.ts.map +1 -1
  34. package/dist/fleet/fleet.js +5 -2
  35. package/dist/fleet/store.d.ts.map +1 -1
  36. package/dist/fleet/store.js +3 -0
  37. package/dist/host/github-dir.d.ts.map +1 -1
  38. package/dist/host/github-dir.js +5 -0
  39. package/dist/host/mcp-list.d.ts.map +1 -1
  40. package/dist/host/mcp-list.js +1 -0
  41. package/dist/host/run-command.d.ts.map +1 -1
  42. package/dist/host/run-command.js +2 -0
  43. package/dist/index.d.ts +6 -3
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +3 -1
  46. package/dist/internal/controlled-process/authentication.d.ts +13 -0
  47. package/dist/internal/controlled-process/authentication.d.ts.map +1 -0
  48. package/dist/internal/controlled-process/authentication.js +112 -0
  49. package/dist/internal/controlled-process/child-fd.d.ts +5 -0
  50. package/dist/internal/controlled-process/child-fd.d.ts.map +1 -0
  51. package/dist/internal/controlled-process/child-fd.js +47 -0
  52. package/dist/internal/controlled-process/framed-transport.d.ts +6 -0
  53. package/dist/internal/controlled-process/framed-transport.d.ts.map +1 -0
  54. package/dist/internal/controlled-process/framed-transport.js +117 -0
  55. package/dist/internal/controlled-process/host-controller.d.ts +23 -0
  56. package/dist/internal/controlled-process/host-controller.d.ts.map +1 -0
  57. package/dist/internal/controlled-process/host-controller.js +908 -0
  58. package/dist/internal/controlled-process/lifecycle.d.ts +5 -0
  59. package/dist/internal/controlled-process/lifecycle.d.ts.map +1 -0
  60. package/dist/internal/controlled-process/lifecycle.js +22 -0
  61. package/dist/internal/controlled-process/model.d.ts +99 -0
  62. package/dist/internal/controlled-process/model.d.ts.map +1 -0
  63. package/dist/internal/controlled-process/model.js +1 -0
  64. package/dist/internal/controlled-process/record-store.d.ts +17 -0
  65. package/dist/internal/controlled-process/record-store.d.ts.map +1 -0
  66. package/dist/internal/controlled-process/record-store.js +170 -0
  67. package/dist/internal/controlled-process/record.d.ts +12 -0
  68. package/dist/internal/controlled-process/record.d.ts.map +1 -0
  69. package/dist/internal/controlled-process/record.js +87 -0
  70. package/dist/internal/controlled-process/schema.d.ts +133 -0
  71. package/dist/internal/controlled-process/schema.d.ts.map +1 -0
  72. package/dist/internal/controlled-process/schema.js +99 -0
  73. package/dist/internal/controlled-process/shim-entry.d.ts +2 -0
  74. package/dist/internal/controlled-process/shim-entry.d.ts.map +1 -0
  75. package/dist/internal/controlled-process/shim-entry.js +2 -0
  76. package/dist/internal/controlled-process/shim-runtime.d.ts +2 -0
  77. package/dist/internal/controlled-process/shim-runtime.d.ts.map +1 -0
  78. package/dist/internal/controlled-process/shim-runtime.js +57 -0
  79. package/dist/internal/controlled-process/supervisor-coordinator.d.ts +67 -0
  80. package/dist/internal/controlled-process/supervisor-coordinator.d.ts.map +1 -0
  81. package/dist/internal/controlled-process/supervisor-coordinator.js +325 -0
  82. package/dist/internal/controlled-process/supervisor-entry.d.ts +2 -0
  83. package/dist/internal/controlled-process/supervisor-entry.d.ts.map +1 -0
  84. package/dist/internal/controlled-process/supervisor-entry.js +2 -0
  85. package/dist/internal/controlled-process/supervisor-model.d.ts +92 -0
  86. package/dist/internal/controlled-process/supervisor-model.d.ts.map +1 -0
  87. package/dist/internal/controlled-process/supervisor-model.js +1 -0
  88. package/dist/internal/controlled-process/supervisor-platform.d.ts +16 -0
  89. package/dist/internal/controlled-process/supervisor-platform.d.ts.map +1 -0
  90. package/dist/internal/controlled-process/supervisor-platform.js +104 -0
  91. package/dist/internal/controlled-process/supervisor-runtime.d.ts +11 -0
  92. package/dist/internal/controlled-process/supervisor-runtime.d.ts.map +1 -0
  93. package/dist/internal/controlled-process/supervisor-runtime.js +773 -0
  94. package/dist/internal/controlled-process/supervisor-schema.d.ts +100 -0
  95. package/dist/internal/controlled-process/supervisor-schema.d.ts.map +1 -0
  96. package/dist/internal/controlled-process/supervisor-schema.js +73 -0
  97. package/dist/internal/controlled-process/supervisor-transport.d.ts +46 -0
  98. package/dist/internal/controlled-process/supervisor-transport.d.ts.map +1 -0
  99. package/dist/internal/controlled-process/supervisor-transport.js +368 -0
  100. package/dist/internal/controlled-process/supervisor-values.d.ts +39 -0
  101. package/dist/internal/controlled-process/supervisor-values.d.ts.map +1 -0
  102. package/dist/internal/controlled-process/supervisor-values.js +38 -0
  103. package/dist/internal/controlled-process/token.d.ts +4 -0
  104. package/dist/internal/controlled-process/token.d.ts.map +1 -0
  105. package/dist/internal/controlled-process/token.js +38 -0
  106. package/dist/internal/controlled-process/values.d.ts +39 -0
  107. package/dist/internal/controlled-process/values.d.ts.map +1 -0
  108. package/dist/internal/controlled-process/values.js +38 -0
  109. package/dist/kernel/cli-agent.d.ts.map +1 -1
  110. package/dist/kernel/cli-agent.js +330 -34
  111. package/dist/kernel/cli-login.d.ts.map +1 -1
  112. package/dist/kernel/cli-login.js +5 -0
  113. package/dist/kernel/env-template.js +1 -0
  114. package/dist/kernel/facets.d.ts.map +1 -1
  115. package/dist/kernel/facets.js +1 -0
  116. package/dist/kernel/keyed.d.ts.map +1 -1
  117. package/dist/kernel/keyed.js +1 -0
  118. package/dist/kernel/login.js +2 -0
  119. package/dist/kernel/options.d.ts +14 -0
  120. package/dist/kernel/options.d.ts.map +1 -1
  121. package/dist/kernel/options.js +3 -0
  122. package/dist/kernel/process-lifecycle-failure.d.ts +5 -0
  123. package/dist/kernel/process-lifecycle-failure.d.ts.map +1 -0
  124. package/dist/kernel/process-lifecycle-failure.js +5 -0
  125. package/dist/kernel/run.d.ts.map +1 -1
  126. package/dist/kernel/run.js +11 -0
  127. package/dist/kernel/runtime.d.ts.map +1 -1
  128. package/dist/kernel/runtime.js +2 -0
  129. package/dist/keyring/resolver.d.ts.map +1 -1
  130. package/dist/keyring/resolver.js +2 -0
  131. package/dist/structured/run-structured.js +1 -0
  132. package/dist/testing/fake-controlled-exec.d.ts +21 -0
  133. package/dist/testing/fake-controlled-exec.d.ts.map +1 -0
  134. package/dist/testing/fake-controlled-exec.js +172 -0
  135. package/dist/testing/fake-exec.d.ts.map +1 -1
  136. package/dist/testing/fake-exec.js +64 -54
  137. package/dist/testing/index.d.ts +1 -0
  138. package/dist/testing/index.d.ts.map +1 -1
  139. package/dist/testing/index.js +1 -0
  140. package/package.json +2 -2
@@ -0,0 +1,908 @@
1
+ // biome-ignore-all lint/nursery/noExcessiveLinesPerFile: Section 5.103 confines the correction to this existing host lifecycle owner.
2
+ import { spawn } from "node:child_process";
3
+ import { CHILD_PROCESS_ABSENCE_PROOF, CHILD_PROCESS_TERMINATION_EVIDENCE_KIND, CHILD_PROCESS_TERMINATION_KIND, CHILD_PROCESS_UNKILLABLE_REASON, } from "../../core/controlled-process.js";
4
+ import { readFramedRecords, readRequiredFrame, writeFramedRecord, } from "./framed-transport.js";
5
+ import { transitionControlledProcess } from "./lifecycle.js";
6
+ import { controlledProcessRecordMatchesToken, signControlledProcessRecord, verifySignedControlledProcessRecord, } from "./record.js";
7
+ import { assertSecureRuntimeDirectory, resolveSupervisorSocketNamespace, SignedRecordStore, supervisorSocketPath, } from "./record-store.js";
8
+ import { controlledProcessIdentitySchema } from "./schema.js";
9
+ import { createSupervisorPlatformAdapter } from "./supervisor-platform.js";
10
+ import { supervisorIdentityFrameSchema, supervisorLaunchFailedFrameSchema, } from "./supervisor-schema.js";
11
+ import { requestSupervisor } from "./supervisor-transport.js";
12
+ import { OUTPUT_CHANNEL_KIND, SUPERVISOR_BOOTSTRAP_FRAME_KIND, SUPERVISOR_REQUEST_KIND, SUPERVISOR_RESPONSE_KIND, } from "./supervisor-values.js";
13
+ import { decodeProcessStartToken } from "./token.js";
14
+ import { CONTROLLED_PROCESS_STATE } from "./values.js";
15
+ const HOST_BOOTSTRAP_FD = 3;
16
+ const HOST_IDENTITY_FD = 4;
17
+ const OUTPUT_QUEUE_HIGH_WATER_BYTES = 64 * 1024;
18
+ const OUTPUT_QUEUE_LOW_WATER_BYTES = 32 * 1024;
19
+ const PRE_READY_CLEANUP_AUTHORITY = {
20
+ unprobed: "unprobed",
21
+ unavailable: "unavailable",
22
+ live: "live",
23
+ rollbackCompleted: "rollback_completed",
24
+ reportedFailure: "reported_failure",
25
+ };
26
+ const TERMINATION_OBSERVATION_SOURCE = {
27
+ liveResponse: "live_response",
28
+ liveRequestFailure: "live_request_failure",
29
+ supervisorClose: "supervisor_close",
30
+ offlineFallback: "offline_fallback",
31
+ };
32
+ class SupervisorReportedLaunchFailure extends Error {
33
+ }
34
+ export async function launchControlledProcess(input) {
35
+ const platform = createSupervisorPlatformAdapter();
36
+ const runtimeDirectory = await assertSecureRuntimeDirectory(input.runtimeDirectory, platform.uid);
37
+ const supervisor = spawnSupervisor(input.supervisorEntryPath);
38
+ const supervisorClose = observeSupervisorClose(supervisor, input.timing.probeIntervalMs);
39
+ void supervisorClose.promise.catch(() => undefined);
40
+ const control = supervisor.stdio[HOST_BOOTSTRAP_FD];
41
+ const identityStream = supervisor.stdio[HOST_IDENTITY_FD];
42
+ const identityFrames = readFramedRecords(identityStream)[Symbol.asyncIterator]();
43
+ let output = null;
44
+ let identity = null;
45
+ let descriptorCommitted = false;
46
+ let cleanupAuthority = PRE_READY_CLEANUP_AUTHORITY.unprobed;
47
+ try {
48
+ output = attachSupervisorOutput(supervisor);
49
+ await writeFramedRecord(control, {
50
+ kind: SUPERVISOR_BOOTSTRAP_FRAME_KIND.bootstrap,
51
+ runtimeDirectory,
52
+ shimEntryPath: input.shimEntryPath,
53
+ worker: input.worker,
54
+ timing: input.timing,
55
+ });
56
+ identity = await readSupervisorIdentity(identityFrames);
57
+ let hostAckComplete = false;
58
+ const readinessObservation = observeSupervisorReadiness(identityFrames, () => hostAckComplete);
59
+ await input.lifecycle.beforeExec(identity);
60
+ descriptorCommitted = true;
61
+ await writeFramedRecord(control, {
62
+ kind: SUPERVISOR_BOOTSTRAP_FRAME_KIND.hostAck,
63
+ });
64
+ hostAckComplete = true;
65
+ control.end();
66
+ const readiness = await concludeSupervisorReadiness({
67
+ observation: readinessObservation,
68
+ identity,
69
+ runtimeDirectory,
70
+ supervisorClose,
71
+ timing: input.timing,
72
+ });
73
+ if (readiness.kind === "failure") {
74
+ cleanupAuthority = readiness.cleanupAuthority;
75
+ throw readiness.error;
76
+ }
77
+ const readyIdentity = identity;
78
+ let terminationRequested = false;
79
+ const completion = settleControlledProcess({
80
+ identity: readyIdentity,
81
+ runtimeDirectory,
82
+ outputClosed: output.closed,
83
+ supervisorClose,
84
+ lifecycle: input.lifecycle,
85
+ terminationRequested: () => terminationRequested,
86
+ });
87
+ void completion.catch(() => undefined);
88
+ let requested = null;
89
+ return {
90
+ identity: readyIdentity,
91
+ chunks: output.queue,
92
+ completion,
93
+ requestTermination: () => {
94
+ requested ??= (async () => {
95
+ terminationRequested = true;
96
+ await requestTermination(readyIdentity, runtimeDirectory, supervisorClose);
97
+ return completion;
98
+ })();
99
+ return requested;
100
+ },
101
+ };
102
+ }
103
+ catch (primaryFailure) {
104
+ if (primaryFailure instanceof SupervisorReportedLaunchFailure) {
105
+ cleanupAuthority = PRE_READY_CLEANUP_AUTHORITY.reportedFailure;
106
+ }
107
+ try {
108
+ await cleanupPreReadySupervisor({
109
+ control,
110
+ identity,
111
+ descriptorCommitted,
112
+ runtimeDirectory,
113
+ output,
114
+ supervisorClose,
115
+ lifecycle: input.lifecycle,
116
+ timing: input.timing,
117
+ cleanupAuthority,
118
+ });
119
+ }
120
+ catch (cleanupFailure) {
121
+ throw new AggregateError([primaryFailure, cleanupFailure], "Controlled process launch and pre-ready cleanup both failed.");
122
+ }
123
+ throw primaryFailure;
124
+ }
125
+ }
126
+ function observeSupervisorReadiness(frames, hostAckComplete) {
127
+ return frames.next().then((result) => ({
128
+ kind: "result",
129
+ result,
130
+ observedBeforeHostAck: !hostAckComplete(),
131
+ }), (error) => ({
132
+ kind: "failure",
133
+ error,
134
+ observedBeforeHostAck: !hostAckComplete(),
135
+ }));
136
+ }
137
+ async function concludeSupervisorReadiness(input) {
138
+ const observation = await input.observation;
139
+ if (observation.observedBeforeHostAck) {
140
+ return readinessFailure(new Error("Supervisor readiness arrived before host ACK completed."), PRE_READY_CLEANUP_AUTHORITY.unprobed);
141
+ }
142
+ if (observation.kind === "failure") {
143
+ return readinessFailure(observation.error, PRE_READY_CLEANUP_AUTHORITY.unprobed);
144
+ }
145
+ if (!observation.result.done) {
146
+ const failure = supervisorLaunchFailedFrameSchema.safeParse(observation.result.value);
147
+ if (failure.success) {
148
+ return readinessFailure(new Error(failure.data.reason), PRE_READY_CLEANUP_AUTHORITY.rollbackCompleted);
149
+ }
150
+ return readinessFailure(new Error("Supervisor readiness frame is invalid."), PRE_READY_CLEANUP_AUTHORITY.unprobed);
151
+ }
152
+ const probe = await raceSupervisorRequestWithClose({
153
+ identity: input.identity,
154
+ runtimeDirectory: input.runtimeDirectory,
155
+ requestKind: SUPERVISOR_REQUEST_KIND.probe,
156
+ supervisorClose: input.supervisorClose,
157
+ deadline: preReadyCleanupDeadline(input.timing),
158
+ });
159
+ if (probe.kind === "closed") {
160
+ return readinessFailure(new Error("Supervisor closed before readiness was proven."), PRE_READY_CLEANUP_AUTHORITY.unavailable);
161
+ }
162
+ if (probe.kind === "failure") {
163
+ return readinessFailure(probe.error, PRE_READY_CLEANUP_AUTHORITY.unavailable);
164
+ }
165
+ if (probe.kind === "deadline") {
166
+ return readinessFailure(probe.error, PRE_READY_CLEANUP_AUTHORITY.unavailable);
167
+ }
168
+ if (probe.response.kind !== SUPERVISOR_RESPONSE_KIND.termination) {
169
+ return readinessFailure(new Error("Supervisor readiness probe returned an invalid response."), PRE_READY_CLEANUP_AUTHORITY.live);
170
+ }
171
+ const { result, workerExit } = probe.response;
172
+ if (result.kind === CHILD_PROCESS_TERMINATION_KIND.pending) {
173
+ return { kind: "ready" };
174
+ }
175
+ if (result.kind === CHILD_PROCESS_TERMINATION_KIND.absent &&
176
+ workerExit !== null) {
177
+ return { kind: "ready" };
178
+ }
179
+ return readinessFailure(new Error(`Supervisor readiness probe did not prove a runnable process: ${result.kind}.`), PRE_READY_CLEANUP_AUTHORITY.live);
180
+ }
181
+ function readinessFailure(error, cleanupAuthority) {
182
+ return { kind: "failure", error, cleanupAuthority };
183
+ }
184
+ async function settleControlledProcess(input) {
185
+ const snapshot = await waitForTermination(input.identity, input.runtimeDirectory, input.supervisorClose);
186
+ const { result, workerExit } = snapshot;
187
+ if (result.kind === CHILD_PROCESS_TERMINATION_KIND.pending) {
188
+ throw new Error("Controlled process completion remained pending.");
189
+ }
190
+ if (result.kind === CHILD_PROCESS_TERMINATION_KIND.unkillable) {
191
+ return { ...result, workerExit };
192
+ }
193
+ await input.outputClosed;
194
+ if (workerExit === null &&
195
+ snapshot.source === TERMINATION_OBSERVATION_SOURCE.liveResponse &&
196
+ !input.terminationRequested()) {
197
+ throw new Error("Natural controlled process completion lacks worker exit evidence.");
198
+ }
199
+ await input.lifecycle.afterTermination(terminationEvidenceFromSnapshot(input.identity, result.proof, snapshot));
200
+ await releaseAfterLifecycleClosure({
201
+ identity: input.identity,
202
+ runtimeDirectory: input.runtimeDirectory,
203
+ supervisorClose: input.supervisorClose,
204
+ observedSupervisorExit: snapshot.supervisorExit,
205
+ });
206
+ return { ...result, workerExit };
207
+ }
208
+ async function cleanupPreReadySupervisor(input) {
209
+ if (!input.control.destroyed && !input.control.writableEnded) {
210
+ input.control.end();
211
+ }
212
+ if (input.output !== null) {
213
+ await input.output.queue[Symbol.asyncIterator]().return?.();
214
+ }
215
+ if (input.identity === null &&
216
+ input.cleanupAuthority === PRE_READY_CLEANUP_AUTHORITY.reportedFailure &&
217
+ !input.supervisorClose.didClose() &&
218
+ (await input.supervisorClose.observeAfterRequestSettlement()) === null) {
219
+ return;
220
+ }
221
+ if (input.identity === null || !input.descriptorCommitted) {
222
+ await cleanupAfterSupervisorClose(input);
223
+ return;
224
+ }
225
+ if (input.cleanupAuthority === PRE_READY_CLEANUP_AUTHORITY.rollbackCompleted ||
226
+ input.supervisorClose.didClose()) {
227
+ await cleanupAfterSupervisorClose(input);
228
+ return;
229
+ }
230
+ if (input.cleanupAuthority === PRE_READY_CLEANUP_AUTHORITY.unavailable) {
231
+ throw new Error("Pre-ready controlled process cleanup lacks live supervisor authority.");
232
+ }
233
+ const deadline = preReadyCleanupDeadline(input.timing);
234
+ if (input.cleanupAuthority === PRE_READY_CLEANUP_AUTHORITY.unprobed) {
235
+ const probe = await raceSupervisorRequestWithClose({
236
+ identity: input.identity,
237
+ runtimeDirectory: input.runtimeDirectory,
238
+ requestKind: SUPERVISOR_REQUEST_KIND.probe,
239
+ supervisorClose: input.supervisorClose,
240
+ deadline,
241
+ });
242
+ if (probe.kind === "closed") {
243
+ await cleanupAfterSupervisorClose(input);
244
+ return;
245
+ }
246
+ if (probe.kind === "failure") {
247
+ throw probe.error;
248
+ }
249
+ if (probe.kind === "deadline") {
250
+ throw probe.error;
251
+ }
252
+ }
253
+ await terminatePreReadySupervisor({
254
+ identity: input.identity,
255
+ runtimeDirectory: input.runtimeDirectory,
256
+ lifecycle: input.lifecycle,
257
+ supervisorClose: input.supervisorClose,
258
+ output: input.output,
259
+ deadline,
260
+ });
261
+ }
262
+ async function terminatePreReadySupervisor(input) {
263
+ let snapshot = await requestTerminationBeforeDeadline({
264
+ identity: input.identity,
265
+ runtimeDirectory: input.runtimeDirectory,
266
+ requestKind: SUPERVISOR_REQUEST_KIND.terminate,
267
+ supervisorClose: input.supervisorClose,
268
+ deadline: input.deadline,
269
+ });
270
+ if (snapshot === null) {
271
+ await cleanupAfterSupervisorClose({
272
+ ...input,
273
+ descriptorCommitted: true,
274
+ });
275
+ return;
276
+ }
277
+ while (snapshot.result.kind === CHILD_PROCESS_TERMINATION_KIND.pending) {
278
+ await beforeDeadline(delay(snapshot.result.retryAfterMs), input.deadline, "Pre-ready supervisor termination timed out.");
279
+ snapshot = await requestTerminationBeforeDeadline({
280
+ identity: input.identity,
281
+ runtimeDirectory: input.runtimeDirectory,
282
+ requestKind: SUPERVISOR_REQUEST_KIND.probe,
283
+ supervisorClose: input.supervisorClose,
284
+ deadline: input.deadline,
285
+ });
286
+ if (snapshot === null) {
287
+ await cleanupAfterSupervisorClose({
288
+ ...input,
289
+ descriptorCommitted: true,
290
+ });
291
+ return;
292
+ }
293
+ }
294
+ if (snapshot.result.kind !== CHILD_PROCESS_TERMINATION_KIND.absent) {
295
+ throw new Error(`Pre-ready supervisor termination did not prove absence: ${snapshot.result.kind}.`);
296
+ }
297
+ let lifecycleFailure = null;
298
+ try {
299
+ await input.lifecycle.afterTermination(terminationEvidenceFromSnapshot(input.identity, snapshot.result.proof, snapshot));
300
+ }
301
+ catch (error) {
302
+ lifecycleFailure = { error };
303
+ }
304
+ try {
305
+ await releaseAfterLifecycleClosure({
306
+ identity: input.identity,
307
+ runtimeDirectory: input.runtimeDirectory,
308
+ supervisorClose: input.supervisorClose,
309
+ deadline: input.deadline,
310
+ });
311
+ }
312
+ catch (releaseFailure) {
313
+ if (lifecycleFailure !== null) {
314
+ throw new AggregateError([lifecycleFailure.error, releaseFailure], "Pre-ready lifecycle closure and supervisor release both failed.");
315
+ }
316
+ throw releaseFailure;
317
+ }
318
+ if (lifecycleFailure !== null) {
319
+ throw lifecycleFailure.error;
320
+ }
321
+ if (input.output !== null) {
322
+ await input.output.closed;
323
+ }
324
+ }
325
+ async function requestTerminationBeforeDeadline(input) {
326
+ const raced = await raceSupervisorRequestWithClose(input);
327
+ if (raced.kind === "closed") {
328
+ return null;
329
+ }
330
+ if (raced.kind === "failure" || raced.kind === "deadline") {
331
+ throw raced.error;
332
+ }
333
+ if (raced.response.kind !== SUPERVISOR_RESPONSE_KIND.termination) {
334
+ throw new Error("Supervisor rejected termination request.");
335
+ }
336
+ return {
337
+ result: raced.response.result,
338
+ workerExit: raced.response.workerExit,
339
+ source: TERMINATION_OBSERVATION_SOURCE.liveResponse,
340
+ supervisorExit: null,
341
+ };
342
+ }
343
+ async function raceSupervisorRequestWithClose(input) {
344
+ if (input.supervisorClose.didClose()) {
345
+ return {
346
+ kind: "closed",
347
+ exit: await input.supervisorClose.promise,
348
+ };
349
+ }
350
+ const controller = new AbortController();
351
+ const response = requestLiveSupervisor(input.identity, input.runtimeDirectory, input.requestKind, controller.signal).then((value) => ({ kind: "response", response: value }), (error) => ({ kind: "failure", error }));
352
+ const closed = input.supervisorClose.promise.then((exit) => ({ kind: "closed", exit }));
353
+ let cancelDeadline = () => { };
354
+ const racers = [response, closed];
355
+ if (input.deadline !== null) {
356
+ const deadline = input.deadline;
357
+ const deadlineFailure = new Error("Pre-ready supervisor request timed out.");
358
+ racers.push(new Promise((resolve) => {
359
+ const timeout = setTimeout(() => resolve({ kind: "deadline", error: deadlineFailure }), Math.max(0, deadline - Date.now()));
360
+ cancelDeadline = () => clearTimeout(timeout);
361
+ }));
362
+ }
363
+ const result = await Promise.race(racers);
364
+ cancelDeadline();
365
+ if (result.kind === "response" || result.kind === "failure") {
366
+ const exit = await input.supervisorClose.observeAfterRequestSettlement();
367
+ if (exit !== null) {
368
+ return { kind: "closed", exit };
369
+ }
370
+ }
371
+ if (result.kind === "closed" || result.kind === "deadline") {
372
+ controller.abort(result.kind === "closed"
373
+ ? new Error("Supervisor closed during a live request.")
374
+ : result.error);
375
+ await response;
376
+ }
377
+ return result;
378
+ }
379
+ function preReadyCleanupDeadline(timing) {
380
+ const budget = Math.min(Number.MAX_SAFE_INTEGER, timing.termGraceMs + timing.killProbeTimeoutMs + timing.probeIntervalMs);
381
+ return Math.min(Number.MAX_SAFE_INTEGER, Date.now() + budget);
382
+ }
383
+ function beforeDeadline(operation, deadline, message) {
384
+ return new Promise((resolve, reject) => {
385
+ const remaining = deadline - Date.now();
386
+ if (remaining <= 0) {
387
+ reject(new Error(message));
388
+ return;
389
+ }
390
+ const timeout = setTimeout(() => reject(new Error(message)), remaining);
391
+ operation.then((result) => {
392
+ clearTimeout(timeout);
393
+ resolve(result);
394
+ }, (error) => {
395
+ clearTimeout(timeout);
396
+ reject(error);
397
+ });
398
+ });
399
+ }
400
+ async function cleanupAfterSupervisorClose(input) {
401
+ await input.supervisorClose.promise;
402
+ if (input.output !== null) {
403
+ await input.output.closed;
404
+ }
405
+ if (input.identity === null) {
406
+ return;
407
+ }
408
+ const result = await resolveOfflineTermination(input.identity, input.runtimeDirectory, "child_close");
409
+ if (result.kind !== CHILD_PROCESS_TERMINATION_KIND.absent) {
410
+ throw new Error(`Pre-ready controlled process cleanup did not prove absence: ${result.kind}.`);
411
+ }
412
+ if (input.descriptorCommitted) {
413
+ await input.lifecycle.afterTermination(offlineAbsenceEvidence(input.identity, result.proof));
414
+ await releaseOfflineControlledProcess(input.identity, input.runtimeDirectory);
415
+ }
416
+ }
417
+ async function requestTermination(identity, runtimeDirectory, supervisorClose) {
418
+ const raced = await raceSupervisorRequestWithClose({
419
+ identity,
420
+ runtimeDirectory,
421
+ requestKind: SUPERVISOR_REQUEST_KIND.terminate,
422
+ supervisorClose,
423
+ deadline: null,
424
+ });
425
+ if (raced.kind === "failure" || raced.kind === "deadline") {
426
+ throw raced.error;
427
+ }
428
+ if (raced.kind === "closed") {
429
+ await resolveOfflineTermination(identity, runtimeDirectory, "child_close");
430
+ return;
431
+ }
432
+ if (raced.response.kind !== SUPERVISOR_RESPONSE_KIND.termination) {
433
+ throw new Error("Supervisor rejected termination.");
434
+ }
435
+ }
436
+ async function waitForTermination(identity, runtimeDirectory, supervisorClose) {
437
+ for (;;) {
438
+ const snapshot = await resolveTermination(identity, runtimeDirectory, SUPERVISOR_REQUEST_KIND.probe, supervisorClose);
439
+ if (snapshot.result.kind !== CHILD_PROCESS_TERMINATION_KIND.pending) {
440
+ return snapshot;
441
+ }
442
+ await delay(snapshot.result.retryAfterMs);
443
+ }
444
+ }
445
+ async function resolveTermination(identity, runtimeDirectory, requestKind, supervisorClose) {
446
+ if (supervisorClose !== null) {
447
+ const raced = await raceSupervisorRequestWithClose({
448
+ identity,
449
+ runtimeDirectory,
450
+ requestKind,
451
+ supervisorClose,
452
+ deadline: null,
453
+ });
454
+ if (raced.kind === "closed") {
455
+ return {
456
+ result: await resolveOfflineTermination(identity, runtimeDirectory, "child_close"),
457
+ workerExit: null,
458
+ source: TERMINATION_OBSERVATION_SOURCE.supervisorClose,
459
+ supervisorExit: raced.exit,
460
+ };
461
+ }
462
+ if (raced.kind === "deadline") {
463
+ throw raced.error;
464
+ }
465
+ if (raced.kind === "failure") {
466
+ const classified = classifyLiveRequestFailure(raced.error);
467
+ if (classified !== null) {
468
+ return classified;
469
+ }
470
+ throw raced.error;
471
+ }
472
+ return snapshotFromResponse(raced.response);
473
+ }
474
+ const controller = new AbortController();
475
+ try {
476
+ const response = await requestLiveSupervisor(identity, runtimeDirectory, requestKind, controller.signal);
477
+ return snapshotFromResponse(response);
478
+ }
479
+ catch (error) {
480
+ const classified = classifyLiveRequestFailure(error);
481
+ if (classified !== null) {
482
+ return classified;
483
+ }
484
+ return {
485
+ result: await resolveOfflineTermination(identity, runtimeDirectory, "fresh_host"),
486
+ workerExit: null,
487
+ source: TERMINATION_OBSERVATION_SOURCE.offlineFallback,
488
+ supervisorExit: null,
489
+ };
490
+ }
491
+ }
492
+ function snapshotFromResponse(response) {
493
+ if (response.kind === SUPERVISOR_RESPONSE_KIND.termination) {
494
+ return {
495
+ result: response.result,
496
+ workerExit: response.workerExit,
497
+ source: TERMINATION_OBSERVATION_SOURCE.liveResponse,
498
+ supervisorExit: null,
499
+ };
500
+ }
501
+ return {
502
+ result: unkillable(CHILD_PROCESS_UNKILLABLE_REASON.protocolFailure),
503
+ workerExit: null,
504
+ source: TERMINATION_OBSERVATION_SOURCE.liveResponse,
505
+ supervisorExit: null,
506
+ };
507
+ }
508
+ function classifyLiveRequestFailure(error) {
509
+ if (!(error instanceof Error) ||
510
+ error.message !== "Supervisor socket authentication failed.") {
511
+ return null;
512
+ }
513
+ return {
514
+ result: unkillable(CHILD_PROCESS_UNKILLABLE_REASON.recordAuthenticationFailed),
515
+ workerExit: null,
516
+ source: TERMINATION_OBSERVATION_SOURCE.liveRequestFailure,
517
+ supervisorExit: null,
518
+ };
519
+ }
520
+ export async function recoverControlledProcess(input) {
521
+ const { result } = await resolveTermination(input.identity, input.runtimeDirectory, SUPERVISOR_REQUEST_KIND.terminate, null);
522
+ if (result.kind !== CHILD_PROCESS_TERMINATION_KIND.absent) {
523
+ return result;
524
+ }
525
+ if (result.proof === CHILD_PROCESS_ABSENCE_PROOF.releasedReceipt) {
526
+ return result;
527
+ }
528
+ await input.lifecycle.afterTermination(offlineAbsenceEvidence(input.identity, result.proof));
529
+ if (result.proof === CHILD_PROCESS_ABSENCE_PROOF.supervisorProbe) {
530
+ await releaseRecoveredControlledProcess(input.identity, input.runtimeDirectory);
531
+ }
532
+ else if (result.proof === CHILD_PROCESS_ABSENCE_PROOF.bootChanged) {
533
+ await releaseOfflineControlledProcess(input.identity, input.runtimeDirectory);
534
+ }
535
+ return result;
536
+ }
537
+ async function releaseRecoveredControlledProcess(identity, runtimeDirectory) {
538
+ const controller = new AbortController();
539
+ const response = await requestLiveSupervisor(identity, runtimeDirectory, SUPERVISOR_REQUEST_KIND.release, controller.signal);
540
+ if (response.kind !== SUPERVISOR_RESPONSE_KIND.released) {
541
+ throw new Error("Supervisor rejected release.");
542
+ }
543
+ }
544
+ async function releaseOfflineControlledProcess(identity, runtimeDirectory) {
545
+ const token = decodeProcessStartToken(identity.processStartToken);
546
+ const platform = createSupervisorPlatformAdapter();
547
+ const secureRuntimeDirectory = await assertSecureRuntimeDirectory(runtimeDirectory, platform.uid);
548
+ const store = new SignedRecordStore(secureRuntimeDirectory, token.recordId, platform.uid);
549
+ const signed = await store.read();
550
+ if (!controlledProcessRecordMatchesToken(signed.record, token) ||
551
+ signed.record.pid !== identity.pid ||
552
+ !verifySignedControlledProcessRecord(signed, identity)) {
553
+ throw new Error("Offline controlled process release authentication failed.");
554
+ }
555
+ if (signed.record.state === CONTROLLED_PROCESS_STATE.released) {
556
+ return;
557
+ }
558
+ if (signed.record.state !== CONTROLLED_PROCESS_STATE.absent) {
559
+ throw new Error("Offline controlled process release requires absence.");
560
+ }
561
+ const released = {
562
+ ...signed.record,
563
+ state: transitionControlledProcess(signed.record.state, CONTROLLED_PROCESS_STATE.released),
564
+ absenceProof: signed.record.absenceProof,
565
+ };
566
+ await store.write(signControlledProcessRecord(released, token.capability));
567
+ }
568
+ async function resolveOfflineTermination(identityInput, runtimeDirectory, authority) {
569
+ const identity = controlledProcessIdentitySchema.safeParse(identityInput);
570
+ if (!identity.success) {
571
+ return unkillable(CHILD_PROCESS_UNKILLABLE_REASON.invalidIdentity);
572
+ }
573
+ let token;
574
+ try {
575
+ token = decodeProcessStartToken(identity.data.processStartToken);
576
+ }
577
+ catch {
578
+ return unkillable(CHILD_PROCESS_UNKILLABLE_REASON.invalidIdentity);
579
+ }
580
+ const platform = createSupervisorPlatformAdapter();
581
+ let secureRuntimeDirectory;
582
+ try {
583
+ secureRuntimeDirectory = await assertSecureRuntimeDirectory(runtimeDirectory, platform.uid);
584
+ }
585
+ catch {
586
+ return unkillable(CHILD_PROCESS_UNKILLABLE_REASON.recordAuthenticationFailed);
587
+ }
588
+ let signed;
589
+ try {
590
+ signed = await new SignedRecordStore(secureRuntimeDirectory, token.recordId, platform.uid).read();
591
+ }
592
+ catch {
593
+ return unkillable(CHILD_PROCESS_UNKILLABLE_REASON.recordAuthenticationFailed);
594
+ }
595
+ if (!controlledProcessRecordMatchesToken(signed.record, token) ||
596
+ signed.record.pid !== identity.data.pid) {
597
+ return unkillable(CHILD_PROCESS_UNKILLABLE_REASON.recordIdentityMismatch);
598
+ }
599
+ if (!verifySignedControlledProcessRecord(signed, identity.data)) {
600
+ return unkillable(CHILD_PROCESS_UNKILLABLE_REASON.recordAuthenticationFailed);
601
+ }
602
+ if (signed.record.state === CONTROLLED_PROCESS_STATE.released) {
603
+ return {
604
+ kind: CHILD_PROCESS_TERMINATION_KIND.absent,
605
+ proof: CHILD_PROCESS_ABSENCE_PROOF.releasedReceipt,
606
+ };
607
+ }
608
+ if (signed.record.state === CONTROLLED_PROCESS_STATE.absent) {
609
+ if (signed.record.absenceProof === null) {
610
+ return unkillable(CHILD_PROCESS_UNKILLABLE_REASON.protocolFailure);
611
+ }
612
+ if (authority === "fresh_host" &&
613
+ signed.record.absenceProof === CHILD_PROCESS_ABSENCE_PROOF.supervisorProbe) {
614
+ let currentBootId;
615
+ try {
616
+ currentBootId = await platform.bootId();
617
+ }
618
+ catch {
619
+ return unkillable(CHILD_PROCESS_UNKILLABLE_REASON.bootIdentityUnavailable);
620
+ }
621
+ if (currentBootId === token.bootId) {
622
+ return unkillable(CHILD_PROCESS_UNKILLABLE_REASON.supervisorUnreachable);
623
+ }
624
+ const bootChanged = {
625
+ ...signed.record,
626
+ absenceProof: CHILD_PROCESS_ABSENCE_PROOF.bootChanged,
627
+ };
628
+ await new SignedRecordStore(secureRuntimeDirectory, token.recordId, platform.uid).write(signControlledProcessRecord(bootChanged, token.capability));
629
+ return {
630
+ kind: CHILD_PROCESS_TERMINATION_KIND.absent,
631
+ proof: CHILD_PROCESS_ABSENCE_PROOF.bootChanged,
632
+ };
633
+ }
634
+ return {
635
+ kind: CHILD_PROCESS_TERMINATION_KIND.absent,
636
+ proof: signed.record.absenceProof,
637
+ };
638
+ }
639
+ let currentBootId;
640
+ try {
641
+ currentBootId = await platform.bootId();
642
+ }
643
+ catch {
644
+ return unkillable(CHILD_PROCESS_UNKILLABLE_REASON.bootIdentityUnavailable);
645
+ }
646
+ if (currentBootId !== token.bootId) {
647
+ const absent = {
648
+ ...signed.record,
649
+ state: transitionControlledProcess(signed.record.state, CONTROLLED_PROCESS_STATE.absent),
650
+ absenceProof: CHILD_PROCESS_ABSENCE_PROOF.bootChanged,
651
+ };
652
+ await new SignedRecordStore(secureRuntimeDirectory, token.recordId, platform.uid).write(signControlledProcessRecord(absent, token.capability));
653
+ return {
654
+ kind: CHILD_PROCESS_TERMINATION_KIND.absent,
655
+ proof: CHILD_PROCESS_ABSENCE_PROOF.bootChanged,
656
+ };
657
+ }
658
+ return unkillable(CHILD_PROCESS_UNKILLABLE_REASON.supervisorUnreachable);
659
+ }
660
+ async function releaseAfterLifecycleClosure(input) {
661
+ const raced = input.observedSupervisorExit === undefined ||
662
+ input.observedSupervisorExit === null
663
+ ? await raceSupervisorRequestWithClose({
664
+ ...input,
665
+ requestKind: SUPERVISOR_REQUEST_KIND.release,
666
+ deadline: input.deadline ?? null,
667
+ })
668
+ : {
669
+ kind: "closed",
670
+ exit: input.observedSupervisorExit,
671
+ };
672
+ if (raced.kind === "failure" || raced.kind === "deadline") {
673
+ throw raced.error;
674
+ }
675
+ if (raced.kind === "response") {
676
+ if (raced.response.kind !== SUPERVISOR_RESPONSE_KIND.released) {
677
+ throw new Error("Supervisor rejected release.");
678
+ }
679
+ assertSuccessfulSupervisorClose(await input.supervisorClose.promise);
680
+ return;
681
+ }
682
+ const result = await resolveOfflineTermination(input.identity, input.runtimeDirectory, "child_close");
683
+ if (result.kind !== CHILD_PROCESS_TERMINATION_KIND.absent) {
684
+ throw new Error(`Supervisor closed before release could be confirmed: ${result.kind}.`);
685
+ }
686
+ if (result.proof !== CHILD_PROCESS_ABSENCE_PROOF.releasedReceipt) {
687
+ await releaseOfflineControlledProcess(input.identity, input.runtimeDirectory);
688
+ }
689
+ assertSuccessfulSupervisorClose(raced.exit);
690
+ }
691
+ function assertSuccessfulSupervisorClose(exit) {
692
+ if (exit.code === 0 && exit.signal === null) {
693
+ return;
694
+ }
695
+ throw new Error(`Controlled process supervisor exited abnormally: ${JSON.stringify(exit)}.`);
696
+ }
697
+ async function requestLiveSupervisor(identity, runtimeDirectory, kind, signal) {
698
+ const token = decodeProcessStartToken(identity.processStartToken);
699
+ const platform = createSupervisorPlatformAdapter();
700
+ await assertSecureRuntimeDirectory(runtimeDirectory, platform.uid);
701
+ const socketDirectory = await resolveSupervisorSocketNamespace(token.platform, platform.uid);
702
+ return requestSupervisor({
703
+ socketPath: supervisorSocketPath({
704
+ socketDirectory,
705
+ socketLocator: token.socketLocator,
706
+ platform: token.platform,
707
+ }),
708
+ uid: platform.uid,
709
+ recordId: token.recordId,
710
+ capability: token.capability,
711
+ request: { kind },
712
+ signal,
713
+ });
714
+ }
715
+ function spawnSupervisor(entryPath) {
716
+ const child = spawn(process.execPath, [entryPath], {
717
+ detached: true,
718
+ env: {},
719
+ stdio: ["ignore", "pipe", "pipe", "pipe", "pipe"],
720
+ });
721
+ child.once("error", () => { });
722
+ return child;
723
+ }
724
+ function observeSupervisorClose(supervisor, receiptGraceMs) {
725
+ let closed = false;
726
+ let exited = false;
727
+ const exitObserved = new Promise((resolve) => {
728
+ supervisor.once("exit", () => {
729
+ exited = true;
730
+ resolve();
731
+ });
732
+ });
733
+ const promise = new Promise((resolve) => {
734
+ supervisor.once("close", (code, signal) => {
735
+ closed = true;
736
+ resolve({ code, signal });
737
+ });
738
+ });
739
+ return {
740
+ promise,
741
+ didClose: () => closed,
742
+ observeAfterRequestSettlement: async () => {
743
+ if (closed || exited) {
744
+ return promise;
745
+ }
746
+ const observed = await observeSupervisorExitWithin(exitObserved, receiptGraceMs);
747
+ return observed || closed ? promise : null;
748
+ },
749
+ };
750
+ }
751
+ function observeSupervisorExitWithin(exitObserved, graceMs) {
752
+ return new Promise((resolve) => {
753
+ const timeout = setTimeout(() => resolve(false), graceMs);
754
+ exitObserved.then(() => {
755
+ clearTimeout(timeout);
756
+ resolve(true);
757
+ });
758
+ });
759
+ }
760
+ async function readSupervisorIdentity(frames) {
761
+ const frame = await readRequiredFrame(frames);
762
+ const identity = supervisorIdentityFrameSchema.safeParse(frame);
763
+ if (identity.success) {
764
+ return identity.data.identity;
765
+ }
766
+ const failure = supervisorLaunchFailedFrameSchema.safeParse(frame);
767
+ if (failure.success) {
768
+ throw new SupervisorReportedLaunchFailure(failure.data.reason);
769
+ }
770
+ throw new Error("Supervisor identity frame is invalid.");
771
+ }
772
+ function attachSupervisorOutput(supervisor) {
773
+ const stdout = requireSupervisorOutput(supervisor.stdout, "stdout");
774
+ const stderr = requireSupervisorOutput(supervisor.stderr, "stderr");
775
+ const queue = new ControlledProcessOutputQueue([stdout, stderr]);
776
+ let closeOutput = () => { };
777
+ const closed = new Promise((resolve) => {
778
+ closeOutput = resolve;
779
+ });
780
+ let streamsClosed = 0;
781
+ const attach = (stream, channel) => {
782
+ stream.setEncoding("utf8");
783
+ stream.on("data", (text) => queue.push({ channel, text }));
784
+ stream.once("close", () => {
785
+ streamsClosed += 1;
786
+ if (streamsClosed === 2) {
787
+ queue.end();
788
+ closeOutput();
789
+ }
790
+ });
791
+ };
792
+ attach(stdout, OUTPUT_CHANNEL_KIND.stdout);
793
+ attach(stderr, OUTPUT_CHANNEL_KIND.stderr);
794
+ return { queue, closed };
795
+ }
796
+ class ControlledProcessOutputQueue {
797
+ sources;
798
+ buffered = [];
799
+ waiters = [];
800
+ bufferedBytes = 0;
801
+ ended = false;
802
+ abandoned = false;
803
+ paused = false;
804
+ constructor(sources) {
805
+ this.sources = sources;
806
+ }
807
+ push(value) {
808
+ if (this.ended || this.abandoned) {
809
+ return;
810
+ }
811
+ const waiter = this.waiters.shift();
812
+ if (waiter !== undefined) {
813
+ waiter({ value, done: false });
814
+ return;
815
+ }
816
+ const bytes = Buffer.byteLength(value.text, "utf8");
817
+ this.buffered.push({ value, bytes });
818
+ this.bufferedBytes += bytes;
819
+ if (!this.paused && this.bufferedBytes >= OUTPUT_QUEUE_HIGH_WATER_BYTES) {
820
+ this.paused = true;
821
+ for (const source of this.sources) {
822
+ source.pause();
823
+ }
824
+ }
825
+ }
826
+ end() {
827
+ if (this.ended) {
828
+ return;
829
+ }
830
+ this.ended = true;
831
+ for (const waiter of this.waiters.splice(0)) {
832
+ waiter({ value: undefined, done: true });
833
+ }
834
+ }
835
+ [Symbol.asyncIterator]() {
836
+ return {
837
+ next: () => this.next(),
838
+ return: () => this.abandon(),
839
+ };
840
+ }
841
+ next() {
842
+ const entry = this.buffered.shift();
843
+ if (entry !== undefined) {
844
+ this.bufferedBytes -= entry.bytes;
845
+ this.resumeSourcesWhenDrained();
846
+ return Promise.resolve({ value: entry.value, done: false });
847
+ }
848
+ if (this.ended || this.abandoned) {
849
+ return Promise.resolve({ value: undefined, done: true });
850
+ }
851
+ return new Promise((resolve) => {
852
+ this.waiters.push(resolve);
853
+ });
854
+ }
855
+ abandon() {
856
+ if (!this.abandoned) {
857
+ this.abandoned = true;
858
+ this.buffered.splice(0);
859
+ this.bufferedBytes = 0;
860
+ for (const waiter of this.waiters.splice(0)) {
861
+ waiter({ value: undefined, done: true });
862
+ }
863
+ for (const source of this.sources) {
864
+ source.resume();
865
+ }
866
+ }
867
+ return Promise.resolve({ value: undefined, done: true });
868
+ }
869
+ resumeSourcesWhenDrained() {
870
+ if (this.paused && this.bufferedBytes <= OUTPUT_QUEUE_LOW_WATER_BYTES) {
871
+ this.paused = false;
872
+ for (const source of this.sources) {
873
+ source.resume();
874
+ }
875
+ }
876
+ }
877
+ }
878
+ function requireSupervisorOutput(stream, channel) {
879
+ if (stream === null) {
880
+ throw new Error(`Supervisor ${channel} stream is unavailable.`);
881
+ }
882
+ return stream;
883
+ }
884
+ function unkillable(reason) {
885
+ return { kind: CHILD_PROCESS_TERMINATION_KIND.unkillable, reason };
886
+ }
887
+ function delay(milliseconds) {
888
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
889
+ }
890
+ function terminationEvidenceFromSnapshot(identity, proof, snapshot) {
891
+ if (snapshot.source === TERMINATION_OBSERVATION_SOURCE.liveResponse &&
892
+ snapshot.workerExit !== null) {
893
+ return {
894
+ kind: CHILD_PROCESS_TERMINATION_EVIDENCE_KIND.liveChildClose,
895
+ identity,
896
+ proof,
897
+ workerExit: snapshot.workerExit,
898
+ };
899
+ }
900
+ return offlineAbsenceEvidence(identity, proof);
901
+ }
902
+ function offlineAbsenceEvidence(identity, proof) {
903
+ return {
904
+ kind: CHILD_PROCESS_TERMINATION_EVIDENCE_KIND.offlineAbsence,
905
+ identity,
906
+ proof,
907
+ };
908
+ }