@openclaw/crabline 0.1.11 → 0.1.13

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 (214) hide show
  1. package/README.md +137 -23
  2. package/dist/src/bin/crabline.js +3 -1
  3. package/dist/src/bin/crabline.js.map +1 -1
  4. package/dist/src/cli/program.d.ts +5 -1
  5. package/dist/src/cli/program.js +281 -52
  6. package/dist/src/cli/program.js.map +1 -1
  7. package/dist/src/config/load.js +39 -3
  8. package/dist/src/config/load.js.map +1 -1
  9. package/dist/src/config/schema.d.ts +20 -0
  10. package/dist/src/config/schema.js +163 -35
  11. package/dist/src/config/schema.js.map +1 -1
  12. package/dist/src/core/errors.d.ts +1 -0
  13. package/dist/src/core/errors.js +6 -3
  14. package/dist/src/core/errors.js.map +1 -1
  15. package/dist/src/core/http-path.d.ts +1 -0
  16. package/dist/src/core/http-path.js +14 -0
  17. package/dist/src/core/http-path.js.map +1 -0
  18. package/dist/src/core/matcher.d.ts +3 -1
  19. package/dist/src/core/matcher.js +58 -2
  20. package/dist/src/core/matcher.js.map +1 -1
  21. package/dist/src/core/nonces.d.ts +2 -0
  22. package/dist/src/core/nonces.js +11 -1
  23. package/dist/src/core/nonces.js.map +1 -1
  24. package/dist/src/core/reporters.d.ts +5 -0
  25. package/dist/src/core/reporters.js +26 -2
  26. package/dist/src/core/reporters.js.map +1 -1
  27. package/dist/src/core/run.d.ts +3 -1
  28. package/dist/src/core/run.js +178 -66
  29. package/dist/src/core/run.js.map +1 -1
  30. package/dist/src/index.d.ts +12 -10
  31. package/dist/src/index.js +6 -5
  32. package/dist/src/index.js.map +1 -1
  33. package/dist/src/matrix-ids.d.ts +5 -0
  34. package/dist/src/matrix-ids.js +83 -0
  35. package/dist/src/matrix-ids.js.map +1 -0
  36. package/dist/src/openclaw/artifact-generation.d.ts +7 -6
  37. package/dist/src/openclaw/artifact-generation.js +385 -41
  38. package/dist/src/openclaw/artifact-generation.js.map +1 -1
  39. package/dist/src/openclaw/bridges/discord.d.ts +1 -0
  40. package/dist/src/openclaw/bridges/discord.js +149 -0
  41. package/dist/src/openclaw/bridges/discord.js.map +1 -0
  42. package/dist/src/openclaw/bridges/matrix.js +22 -5
  43. package/dist/src/openclaw/bridges/matrix.js.map +1 -1
  44. package/dist/src/openclaw/bridges/mattermost.js +14 -9
  45. package/dist/src/openclaw/bridges/mattermost.js.map +1 -1
  46. package/dist/src/openclaw/bridges/probe-response.d.ts +1 -0
  47. package/dist/src/openclaw/bridges/probe-response.js +5 -0
  48. package/dist/src/openclaw/bridges/probe-response.js.map +1 -0
  49. package/dist/src/openclaw/bridges/signal.js +16 -7
  50. package/dist/src/openclaw/bridges/signal.js.map +1 -1
  51. package/dist/src/openclaw/bridges/slack.js +117 -24
  52. package/dist/src/openclaw/bridges/slack.js.map +1 -1
  53. package/dist/src/openclaw/bridges/telegram.js +46 -20
  54. package/dist/src/openclaw/bridges/telegram.js.map +1 -1
  55. package/dist/src/openclaw/bridges/whatsapp.js +33 -17
  56. package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
  57. package/dist/src/openclaw/bridges/zalo.js +9 -4
  58. package/dist/src/openclaw/bridges/zalo.js.map +1 -1
  59. package/dist/src/openclaw/outbound-contract.js +3 -0
  60. package/dist/src/openclaw/outbound-contract.js.map +1 -1
  61. package/dist/src/openclaw/private-file.d.ts +38 -3
  62. package/dist/src/openclaw/private-file.js +2008 -87
  63. package/dist/src/openclaw/private-file.js.map +1 -1
  64. package/dist/src/openclaw/{smoke-lock.d.ts → provider-readiness-lock.d.ts} +14 -5
  65. package/dist/src/openclaw/provider-readiness-lock.js +1320 -0
  66. package/dist/src/openclaw/provider-readiness-lock.js.map +1 -0
  67. package/dist/src/openclaw/shared.d.ts +10 -17
  68. package/dist/src/openclaw/shared.js +53 -19
  69. package/dist/src/openclaw/shared.js.map +1 -1
  70. package/dist/src/openclaw.d.ts +3 -5
  71. package/dist/src/openclaw.js +245 -60
  72. package/dist/src/openclaw.js.map +1 -1
  73. package/dist/src/platform/process-owned-lock.d.ts +11 -0
  74. package/dist/src/platform/process-owned-lock.js +1698 -0
  75. package/dist/src/platform/process-owned-lock.js.map +1 -0
  76. package/dist/src/platform/recorder-directory.d.ts +1 -0
  77. package/dist/src/platform/recorder-directory.js +14 -0
  78. package/dist/src/platform/recorder-directory.js.map +1 -0
  79. package/dist/src/platform/windows-acl.d.ts +18 -0
  80. package/dist/src/platform/windows-acl.js +1367 -0
  81. package/dist/src/platform/windows-acl.js.map +1 -0
  82. package/dist/src/platform/windows-lock-root.d.ts +13 -0
  83. package/dist/src/platform/windows-lock-root.js +98 -0
  84. package/dist/src/platform/windows-lock-root.js.map +1 -0
  85. package/dist/src/providers/builtin/discord.d.ts +4 -0
  86. package/dist/src/providers/builtin/discord.js +52 -9
  87. package/dist/src/providers/builtin/discord.js.map +1 -1
  88. package/dist/src/providers/builtin/external-webhook-auth.d.ts +1 -0
  89. package/dist/src/providers/builtin/external-webhook-auth.js +38 -1
  90. package/dist/src/providers/builtin/external-webhook-auth.js.map +1 -1
  91. package/dist/src/providers/builtin/feishu.d.ts +1 -0
  92. package/dist/src/providers/builtin/feishu.js +96 -26
  93. package/dist/src/providers/builtin/feishu.js.map +1 -1
  94. package/dist/src/providers/builtin/googlechat.d.ts +1 -0
  95. package/dist/src/providers/builtin/googlechat.js +95 -26
  96. package/dist/src/providers/builtin/googlechat.js.map +1 -1
  97. package/dist/src/providers/builtin/imessage.js +60 -17
  98. package/dist/src/providers/builtin/imessage.js.map +1 -1
  99. package/dist/src/providers/builtin/loopback.js +88 -35
  100. package/dist/src/providers/builtin/loopback.js.map +1 -1
  101. package/dist/src/providers/builtin/matrix.d.ts +2 -2
  102. package/dist/src/providers/builtin/matrix.js +78 -21
  103. package/dist/src/providers/builtin/matrix.js.map +1 -1
  104. package/dist/src/providers/builtin/mattermost.d.ts +11 -7
  105. package/dist/src/providers/builtin/mattermost.js +138 -24
  106. package/dist/src/providers/builtin/mattermost.js.map +1 -1
  107. package/dist/src/providers/builtin/msteams.d.ts +1 -0
  108. package/dist/src/providers/builtin/msteams.js +118 -38
  109. package/dist/src/providers/builtin/msteams.js.map +1 -1
  110. package/dist/src/providers/builtin/native-local-mock.js +4 -4
  111. package/dist/src/providers/builtin/native-local-mock.js.map +1 -1
  112. package/dist/src/providers/builtin/script.js +1057 -146
  113. package/dist/src/providers/builtin/script.js.map +1 -1
  114. package/dist/src/providers/builtin/slack.d.ts +8 -1
  115. package/dist/src/providers/builtin/slack.js +327 -24
  116. package/dist/src/providers/builtin/slack.js.map +1 -1
  117. package/dist/src/providers/builtin/telegram.d.ts +1 -1
  118. package/dist/src/providers/builtin/telegram.js +55 -14
  119. package/dist/src/providers/builtin/telegram.js.map +1 -1
  120. package/dist/src/providers/builtin/whatsapp.d.ts +4 -3
  121. package/dist/src/providers/builtin/whatsapp.js +157 -29
  122. package/dist/src/providers/builtin/whatsapp.js.map +1 -1
  123. package/dist/src/providers/builtin/zalo.d.ts +5 -2
  124. package/dist/src/providers/builtin/zalo.js +31 -7
  125. package/dist/src/providers/builtin/zalo.js.map +1 -1
  126. package/dist/src/providers/catalog.d.ts +1 -1
  127. package/dist/src/providers/catalog.js +1 -1
  128. package/dist/src/providers/catalog.js.map +1 -1
  129. package/dist/src/providers/local-mock.d.ts +4 -0
  130. package/dist/src/providers/local-mock.js +162 -35
  131. package/dist/src/providers/local-mock.js.map +1 -1
  132. package/dist/src/providers/native-ids.d.ts +2 -0
  133. package/dist/src/providers/native-ids.js +3 -0
  134. package/dist/src/providers/native-ids.js.map +1 -1
  135. package/dist/src/providers/recorder.d.ts +14 -3
  136. package/dist/src/providers/recorder.js +521 -41
  137. package/dist/src/providers/recorder.js.map +1 -1
  138. package/dist/src/providers/registry.d.ts +1 -0
  139. package/dist/src/providers/registry.js +65 -20
  140. package/dist/src/providers/registry.js.map +1 -1
  141. package/dist/src/providers/signed-jwt.d.ts +6 -1
  142. package/dist/src/providers/signed-jwt.js +241 -50
  143. package/dist/src/providers/signed-jwt.js.map +1 -1
  144. package/dist/src/providers/slack-ids.d.ts +1 -0
  145. package/dist/src/providers/slack-ids.js +5 -0
  146. package/dist/src/providers/slack-ids.js.map +1 -1
  147. package/dist/src/providers/target-normalizers.d.ts +9 -1
  148. package/dist/src/providers/target-normalizers.js +177 -58
  149. package/dist/src/providers/target-normalizers.js.map +1 -1
  150. package/dist/src/providers/webhook-server.d.ts +3 -0
  151. package/dist/src/providers/webhook-server.js +268 -47
  152. package/dist/src/providers/webhook-server.js.map +1 -1
  153. package/dist/src/servers/discord.d.ts +40 -0
  154. package/dist/src/servers/discord.js +842 -0
  155. package/dist/src/servers/discord.js.map +1 -0
  156. package/dist/src/servers/http.d.ts +14 -2
  157. package/dist/src/servers/http.js +229 -58
  158. package/dist/src/servers/http.js.map +1 -1
  159. package/dist/src/servers/index.d.ts +10 -4
  160. package/dist/src/servers/index.js +4 -0
  161. package/dist/src/servers/index.js.map +1 -1
  162. package/dist/src/servers/matrix.d.ts +3 -0
  163. package/dist/src/servers/matrix.js +268 -110
  164. package/dist/src/servers/matrix.js.map +1 -1
  165. package/dist/src/servers/mattermost.d.ts +5 -0
  166. package/dist/src/servers/mattermost.js +389 -91
  167. package/dist/src/servers/mattermost.js.map +1 -1
  168. package/dist/src/servers/recorder.d.ts +11 -0
  169. package/dist/src/servers/recorder.js +1072 -69
  170. package/dist/src/servers/recorder.js.map +1 -1
  171. package/dist/src/servers/signal.d.ts +1 -0
  172. package/dist/src/servers/signal.js +279 -44
  173. package/dist/src/servers/signal.js.map +1 -1
  174. package/dist/src/servers/slack.d.ts +15 -0
  175. package/dist/src/servers/slack.js +270 -54
  176. package/dist/src/servers/slack.js.map +1 -1
  177. package/dist/src/servers/telegram-identity.d.ts +6 -0
  178. package/dist/src/servers/telegram-identity.js +27 -0
  179. package/dist/src/servers/telegram-identity.js.map +1 -0
  180. package/dist/src/servers/telegram.d.ts +17 -6
  181. package/dist/src/servers/telegram.js +1218 -107
  182. package/dist/src/servers/telegram.js.map +1 -1
  183. package/dist/src/servers/webhook-target.d.ts +12 -4
  184. package/dist/src/servers/webhook-target.js +226 -28
  185. package/dist/src/servers/webhook-target.js.map +1 -1
  186. package/dist/src/servers/whatsapp-baileys-websocket.d.ts +60 -1
  187. package/dist/src/servers/whatsapp-baileys-websocket.js +782 -112
  188. package/dist/src/servers/whatsapp-baileys-websocket.js.map +1 -1
  189. package/dist/src/servers/whatsapp-jid.d.ts +1 -0
  190. package/dist/src/servers/whatsapp-jid.js +9 -5
  191. package/dist/src/servers/whatsapp-jid.js.map +1 -1
  192. package/dist/src/servers/whatsapp-wire/binary-node.d.ts +1 -0
  193. package/dist/src/servers/whatsapp-wire/binary-node.js +37 -13
  194. package/dist/src/servers/whatsapp-wire/binary-node.js.map +1 -1
  195. package/dist/src/servers/whatsapp-wire/crypto.d.ts +3 -0
  196. package/dist/src/servers/whatsapp-wire/crypto.js +23 -8
  197. package/dist/src/servers/whatsapp-wire/crypto.js.map +1 -1
  198. package/dist/src/servers/whatsapp-wire/handshake.d.ts +9 -3
  199. package/dist/src/servers/whatsapp-wire/handshake.js +173 -12
  200. package/dist/src/servers/whatsapp-wire/handshake.js.map +1 -1
  201. package/dist/src/servers/whatsapp-wire/signal.js +3 -3
  202. package/dist/src/servers/whatsapp-wire/signal.js.map +1 -1
  203. package/dist/src/servers/whatsapp.d.ts +7 -1
  204. package/dist/src/servers/whatsapp.js +149 -25
  205. package/dist/src/servers/whatsapp.js.map +1 -1
  206. package/dist/src/servers/zalo.d.ts +1 -0
  207. package/dist/src/servers/zalo.js +193 -82
  208. package/dist/src/servers/zalo.js.map +1 -1
  209. package/docs/channel-setup.md +251 -64
  210. package/fixtures/examples/crabline.example.yaml +3 -2
  211. package/package.json +18 -10
  212. package/dist/src/openclaw/smoke-lock.js +0 -1004
  213. package/dist/src/openclaw/smoke-lock.js.map +0 -1
  214. package/fixtures/examples/openclaw-bridge.yaml +0 -125
@@ -1,18 +1,46 @@
1
+ import { performance } from "node:perf_hooks";
1
2
  import { matchesInbound } from "./matcher.js";
2
3
  import { createOutboundText } from "./message-template.js";
3
4
  import { createNonce } from "./nonces.js";
4
- import { inboundRegexSafetyError } from "./safe-regex.js";
5
+ import { compileInboundRegex } from "./safe-regex.js";
5
6
  import { CrablineError, ensureErrorMessage } from "./errors.js";
6
7
  import { EXIT_CODES } from "./exit-codes.js";
8
+ import { fixtureModeValidationIssue } from "../config/schema.js";
7
9
  const INBOUND_DEADLINE_REACHED = Symbol("inbound deadline reached");
8
10
  const INBOUND_ABORT_GRACE_MS = 250;
9
11
  const MAX_EXCLUDED_INBOUND_IDS = 1_024;
10
12
  const MAX_SCRIPT_STDIN_BYTES = 1024 * 1024;
13
+ const suiteBlockingOperations = new WeakMap();
11
14
  class UnsettledProviderOperationError extends CrablineError {
15
+ operation;
16
+ constructor(message, options, operation) {
17
+ super(message, options);
18
+ this.operation = operation;
19
+ }
20
+ }
21
+ class ProviderOperationTimeoutError extends CrablineError {
22
+ retryable;
23
+ constructor(message, retryable) {
24
+ super(message, { kind: "timeout" });
25
+ this.retryable = retryable;
26
+ }
12
27
  }
13
28
  function sleep(ms) {
14
29
  return new Promise((resolve) => setTimeout(resolve, ms));
15
30
  }
31
+ function observeProviderOperation(promise) {
32
+ let operationSettled = false;
33
+ const settled = promise.then(() => {
34
+ operationSettled = true;
35
+ }, () => {
36
+ operationSettled = true;
37
+ });
38
+ return {
39
+ isSettled: () => operationSettled,
40
+ promise,
41
+ settled,
42
+ };
43
+ }
16
44
  async function raceInboundDeadline(operation, timeoutMs) {
17
45
  let timer;
18
46
  const deadline = new Promise((resolve) => {
@@ -27,32 +55,30 @@ async function raceInboundDeadline(operation, timeoutMs) {
27
55
  }
28
56
  }
29
57
  }
30
- async function withFixtureDeadline(operation, timeoutMs, operationName) {
58
+ async function withFixtureDeadline(operation, timeoutMs, operationName, retryableAfterTimeout = true) {
31
59
  const controller = new AbortController();
32
- const pending = Promise.resolve().then(async () => await operation(controller.signal));
33
- const result = await raceInboundDeadline(pending, timeoutMs);
60
+ const pending = observeProviderOperation(Promise.resolve().then(async () => await operation(controller.signal)));
61
+ const result = await raceInboundDeadline(pending.promise, timeoutMs);
34
62
  if (result === INBOUND_DEADLINE_REACHED) {
35
- const timeoutError = new CrablineError(`Provider ${operationName} timed out after ${timeoutMs}ms.`, {
36
- kind: "timeout",
37
- });
63
+ const timeoutError = new ProviderOperationTimeoutError(`Provider ${operationName} timed out after ${timeoutMs}ms.`, retryableAfterTimeout);
38
64
  controller.abort(timeoutError);
39
- const settled = pending.then(() => true, () => true);
40
- if ((await raceInboundDeadline(settled, INBOUND_ABORT_GRACE_MS)) === INBOUND_DEADLINE_REACHED) {
65
+ if ((await raceInboundDeadline(pending.settled, INBOUND_ABORT_GRACE_MS)) ===
66
+ INBOUND_DEADLINE_REACHED) {
41
67
  throw new UnsettledProviderOperationError(`Provider ${operationName} did not settle within ${INBOUND_ABORT_GRACE_MS}ms after abort.`, {
42
68
  cause: timeoutError,
43
69
  kind: "timeout",
44
- });
70
+ }, pending);
45
71
  }
46
72
  throw timeoutError;
47
73
  }
48
74
  return result;
49
75
  }
50
76
  async function withCleanupDeadline(operation, timeoutMs, operationName) {
51
- const result = await raceInboundDeadline(operation, timeoutMs);
77
+ const result = await raceInboundDeadline(operation.promise, timeoutMs);
52
78
  if (result === INBOUND_DEADLINE_REACHED) {
53
- throw new CrablineError(`Provider ${operationName} timed out after ${timeoutMs}ms.`, {
79
+ throw new UnsettledProviderOperationError(`Provider ${operationName} timed out after ${timeoutMs}ms.`, {
54
80
  kind: "timeout",
55
- });
81
+ }, operation);
56
82
  }
57
83
  return result;
58
84
  }
@@ -168,8 +194,11 @@ function scriptPayloadBase(context) {
168
194
  }
169
195
  async function abortAndDrainInboundWait(operation, controller) {
170
196
  controller.abort(new Error("Inbound wait deadline reached."));
171
- const settled = operation.then(() => true, () => true);
172
- return (await raceInboundDeadline(settled, INBOUND_ABORT_GRACE_MS)) !== INBOUND_DEADLINE_REACHED;
197
+ return ((await raceInboundDeadline(operation.settled, INBOUND_ABORT_GRACE_MS)) !==
198
+ INBOUND_DEADLINE_REACHED);
199
+ }
200
+ function isPermanentFailure(result) {
201
+ return result.failureKind === "auth" || result.failureKind === "config";
173
202
  }
174
203
  export async function runFixtureCommand(params) {
175
204
  const configuredFixture = params.manifest.fixtures.find((entry) => entry.id === params.fixtureId);
@@ -178,9 +207,14 @@ export async function runFixtureCommand(params) {
178
207
  }
179
208
  const mode = params.modeOverride ?? configuredFixture.mode;
180
209
  const fixture = mode === configuredFixture.mode ? configuredFixture : { ...configuredFixture, mode };
210
+ const validationIssue = fixtureModeValidationIssue(fixture);
211
+ if (validationIssue) {
212
+ return toFailure(configuredFixture.id, configuredFixture.provider, mode, new CrablineError(`Invalid effective fixture "${configuredFixture.id}": ${validationIssue.message}`, { kind: "config" }), "config");
213
+ }
181
214
  const provider = params.registry.resolve(fixture.provider, fixture.id);
182
215
  const diagnostics = [];
183
216
  let abortDrainFailed = false;
217
+ const unsettledProviderOperations = [];
184
218
  const contextBase = {
185
219
  config: params.manifest.providers[fixture.provider],
186
220
  fixture,
@@ -188,6 +222,7 @@ export async function runFixtureCommand(params) {
188
222
  providerId: fixture.provider,
189
223
  userName: params.manifest.userName,
190
224
  };
225
+ const maxAttempts = fixture.retries + 1;
191
226
  let result;
192
227
  try {
193
228
  if (!provider.supports.includes(mode)) {
@@ -222,35 +257,55 @@ export async function runFixtureCommand(params) {
222
257
  // Preflight failures still flow through provider cleanup before returning.
223
258
  }
224
259
  else if (mode === "probe") {
225
- try {
226
- if (contextBase.config.adapter === "script") {
227
- assertScriptStdinPayloadSize(scriptPayloadBase(contextBase));
260
+ let attempts = 0;
261
+ let lastFailure = null;
262
+ while (attempts < maxAttempts) {
263
+ attempts += 1;
264
+ try {
265
+ if (contextBase.config.adapter === "script") {
266
+ assertScriptStdinPayloadSize(scriptPayloadBase(contextBase));
267
+ }
268
+ const probeResult = await withFixtureDeadline(async (signal) => await provider.probe({ ...contextBase, signal }), fixture.timeoutMs, "probe");
269
+ const probeAttempt = {
270
+ diagnostics: probeResult.details,
271
+ failureKind: probeResult.healthy ? undefined : "connectivity",
272
+ fixtureId: fixture.id,
273
+ mode,
274
+ ok: probeResult.healthy,
275
+ providerId: fixture.provider,
276
+ };
277
+ if (probeAttempt.ok) {
278
+ return (result = probeAttempt);
279
+ }
280
+ lastFailure = probeAttempt;
228
281
  }
229
- const probeResult = await withFixtureDeadline(async (signal) => await provider.probe({ ...contextBase, signal }), fixture.timeoutMs, "probe");
230
- return (result = {
231
- diagnostics: probeResult.details,
232
- failureKind: probeResult.healthy ? undefined : "connectivity",
233
- fixtureId: fixture.id,
234
- mode,
235
- ok: probeResult.healthy,
236
- providerId: fixture.provider,
237
- });
238
- }
239
- catch (error) {
240
- if (error instanceof UnsettledProviderOperationError) {
241
- abortDrainFailed = true;
282
+ catch (error) {
283
+ lastFailure = toFailure(fixture.id, fixture.provider, mode, error, "connectivity");
284
+ if (error instanceof UnsettledProviderOperationError) {
285
+ abortDrainFailed = true;
286
+ unsettledProviderOperations.push(error.operation);
287
+ break;
288
+ }
289
+ if (isPermanentFailure(lastFailure)) {
290
+ break;
291
+ }
242
292
  }
243
- return (result = toFailure(fixture.id, fixture.provider, mode, error, "connectivity"));
244
293
  }
294
+ return (result = lastFailure ?? {
295
+ diagnostics: ["unknown failure"],
296
+ failureKind: "connectivity",
297
+ fixtureId: fixture.id,
298
+ mode,
299
+ ok: false,
300
+ providerId: fixture.provider,
301
+ });
245
302
  }
246
303
  else {
304
+ let compiledInboundRegex;
247
305
  if (fixture.inboundMatch.strategy === "regex" && fixture.inboundMatch.pattern) {
248
306
  try {
249
307
  RegExp(fixture.inboundMatch.pattern, "u");
250
- const safetyError = inboundRegexSafetyError(fixture.inboundMatch.pattern);
251
- if (safetyError) {
252
- throw new Error(safetyError);
253
- }
308
+ compiledInboundRegex = compileInboundRegex(fixture.inboundMatch.pattern);
254
309
  }
255
310
  catch (error) {
256
311
  return (result = toFailure(fixture.id, fixture.provider, mode, new CrablineError(`Invalid inbound regex: ${ensureErrorMessage(error)}`, {
@@ -259,8 +314,10 @@ export async function runFixtureCommand(params) {
259
314
  }), "config"));
260
315
  }
261
316
  }
317
+ const preparedInboundMatch = compiledInboundRegex
318
+ ? { ...fixture.inboundMatch, pattern: undefined }
319
+ : fixture.inboundMatch;
262
320
  let attempts = 0;
263
- const maxAttempts = fixture.retries + 1;
264
321
  let lastFailure = null;
265
322
  while (attempts < maxAttempts) {
266
323
  attempts += 1;
@@ -287,12 +344,19 @@ export async function runFixtureCommand(params) {
287
344
  },
288
345
  });
289
346
  }
290
- accepted = await withFixtureDeadline(async (signal) => await provider.send({ ...sendContext, signal }), fixture.timeoutMs, "send");
347
+ accepted = await withFixtureDeadline(async (signal) => await provider.send({ ...sendContext, signal }), fixture.timeoutMs, "send", false);
291
348
  }
292
349
  catch (error) {
293
350
  lastFailure = toFailure(fixture.id, fixture.provider, mode, error, "outbound", nonce);
294
351
  if (error instanceof UnsettledProviderOperationError) {
295
352
  abortDrainFailed = true;
353
+ unsettledProviderOperations.push(error.operation);
354
+ break;
355
+ }
356
+ if (error instanceof ProviderOperationTimeoutError && !error.retryable) {
357
+ break;
358
+ }
359
+ if (isPermanentFailure(lastFailure)) {
296
360
  break;
297
361
  }
298
362
  continue;
@@ -314,13 +378,16 @@ export async function runFixtureCommand(params) {
314
378
  providerId: fixture.provider,
315
379
  });
316
380
  }
317
- const inboundDeadline = Date.now() + fixture.timeoutMs;
381
+ const inboundDeadline = performance.now() + fixture.timeoutMs;
318
382
  const seenInbound = new Set();
319
383
  const excludedInboundIds = new Set();
320
384
  let inbound;
321
385
  try {
322
- while (Date.now() < inboundDeadline) {
323
- const timeoutMs = inboundDeadline - Date.now();
386
+ while (true) {
387
+ const timeoutMs = Math.max(0, Math.ceil(inboundDeadline - performance.now()));
388
+ if (timeoutMs === 0) {
389
+ break;
390
+ }
324
391
  const controller = new AbortController();
325
392
  const excludeIds = [...excludedInboundIds];
326
393
  const waitContext = {
@@ -345,12 +412,13 @@ export async function runFixtureCommand(params) {
345
412
  },
346
413
  });
347
414
  }
348
- const wait = provider.waitForInbound(waitContext);
349
- const candidate = await raceInboundDeadline(wait, timeoutMs);
415
+ const wait = observeProviderOperation(provider.waitForInbound(waitContext));
416
+ const candidate = await raceInboundDeadline(wait.promise, timeoutMs);
350
417
  if (candidate === INBOUND_DEADLINE_REACHED) {
351
418
  if (!(await abortAndDrainInboundWait(wait, controller))) {
352
419
  abortDrainFailed = true;
353
- throw new UnsettledProviderOperationError(`Provider inbound wait did not settle within ${INBOUND_ABORT_GRACE_MS}ms after abort.`, { kind: "inbound" });
420
+ unsettledProviderOperations.push(wait);
421
+ throw new UnsettledProviderOperationError(`Provider inbound wait did not settle within ${INBOUND_ABORT_GRACE_MS}ms after abort.`, { kind: "inbound" }, wait);
354
422
  }
355
423
  break;
356
424
  }
@@ -359,27 +427,37 @@ export async function runFixtureCommand(params) {
359
427
  }
360
428
  const key = JSON.stringify([candidate.provider, candidate.threadId, candidate.id]);
361
429
  if (seenInbound.has(key)) {
362
- await sleep(Math.min(10, Math.max(0, inboundDeadline - Date.now())));
430
+ await sleep(Math.min(10, Math.max(0, Math.ceil(inboundDeadline - performance.now()))));
363
431
  continue;
364
432
  }
365
- seenInbound.add(key);
366
- if (matchesInbound(candidate, fixture.inboundMatch, nonce)) {
433
+ if (matchesInbound(candidate, preparedInboundMatch, nonce, {
434
+ requireAcknowledgement: mode === "agent",
435
+ }) &&
436
+ (!compiledInboundRegex || compiledInboundRegex.test(candidate.text ?? ""))) {
367
437
  inbound = candidate;
368
438
  break;
369
439
  }
440
+ if (seenInbound.size >= MAX_EXCLUDED_INBOUND_IDS) {
441
+ const diagnostic = excludedInboundIds.size >= MAX_EXCLUDED_INBOUND_IDS &&
442
+ !excludedInboundIds.has(candidate.id)
443
+ ? `Provider returned more than ${MAX_EXCLUDED_INBOUND_IDS} unmatched inbound message IDs.`
444
+ : `Provider returned more than ${MAX_EXCLUDED_INBOUND_IDS} distinct unmatched inbound envelopes.`;
445
+ throw new CrablineError(diagnostic, { kind: "inbound" });
446
+ }
447
+ seenInbound.add(key);
370
448
  if (!excludedInboundIds.has(candidate.id)) {
371
- if (excludedInboundIds.size >= MAX_EXCLUDED_INBOUND_IDS) {
372
- throw new CrablineError(`Provider returned more than ${MAX_EXCLUDED_INBOUND_IDS} unmatched inbound message IDs.`, { kind: "inbound" });
373
- }
374
449
  excludedInboundIds.add(candidate.id);
375
450
  }
376
451
  }
377
452
  }
378
453
  catch (error) {
379
- lastFailure = toFailure(fixture.id, fixture.provider, mode, error, "inbound", nonce);
454
+ lastFailure = toFailure(fixture.id, fixture.provider, mode, error, "inbound", nonce, diagnostics);
380
455
  if (abortDrainFailed) {
381
456
  break;
382
457
  }
458
+ if (isPermanentFailure(lastFailure)) {
459
+ break;
460
+ }
383
461
  continue;
384
462
  }
385
463
  if (!inbound) {
@@ -410,7 +488,7 @@ export async function runFixtureCommand(params) {
410
488
  });
411
489
  }
412
490
  catch (error) {
413
- lastFailure = toFailure(fixture.id, fixture.provider, mode, error, "assertion", nonce);
491
+ lastFailure = toFailure(fixture.id, fixture.provider, mode, error, "assertion", nonce, diagnostics);
414
492
  }
415
493
  }
416
494
  return (result = lastFailure ?? {
@@ -432,11 +510,14 @@ export async function runFixtureCommand(params) {
432
510
  cleanupErrors.push(error);
433
511
  }
434
512
  try {
435
- const cleanup = provider.cleanup?.();
436
- if (cleanup) {
513
+ const cleanupPromise = provider.cleanup?.();
514
+ if (cleanupPromise) {
515
+ const cleanup = observeProviderOperation(cleanupPromise);
437
516
  if (abortDrainFailed &&
438
- (await raceInboundDeadline(cleanup, INBOUND_ABORT_GRACE_MS)) === INBOUND_DEADLINE_REACHED) {
517
+ (await raceInboundDeadline(cleanup.promise, INBOUND_ABORT_GRACE_MS)) ===
518
+ INBOUND_DEADLINE_REACHED) {
439
519
  cleanupErrors.push(new Error(`Provider cleanup did not settle within ${INBOUND_ABORT_GRACE_MS}ms after an aborted operation.`));
520
+ unsettledProviderOperations.push(cleanup);
440
521
  }
441
522
  if (!abortDrainFailed) {
442
523
  await withCleanupDeadline(cleanup, fixture.timeoutMs, "cleanup");
@@ -444,6 +525,9 @@ export async function runFixtureCommand(params) {
444
525
  }
445
526
  }
446
527
  catch (error) {
528
+ if (error instanceof UnsettledProviderOperationError) {
529
+ unsettledProviderOperations.push(error.operation);
530
+ }
447
531
  cleanupErrors.push(error);
448
532
  }
449
533
  if (cleanupErrors.length > 0) {
@@ -471,23 +555,51 @@ export async function runFixtureCommand(params) {
471
555
  };
472
556
  }
473
557
  }
558
+ await Promise.resolve();
559
+ const blockingOperations = unsettledProviderOperations.filter((operation) => !operation.isSettled());
560
+ if (result && blockingOperations.length > 0) {
561
+ suiteBlockingOperations.set(result, blockingOperations);
562
+ }
474
563
  }
475
564
  // The finally block can synthesize a result when provider cleanup fails.
476
565
  // oxlint-disable-next-line no-unreachable
477
566
  return result;
478
567
  }
479
568
  export async function runSuite(params) {
569
+ const requestedFixtureIds = [...params.fixtureIds];
480
570
  const results = [];
481
- for (const fixtureId of params.fixtureIds) {
482
- results.push(await runFixtureCommand({
483
- fixtureId,
484
- manifest: params.manifest,
485
- manifestPath: params.manifestPath,
486
- registry: params.registry,
487
- }));
571
+ let skippedFixtureIds = [];
572
+ for (const [index, fixtureId] of requestedFixtureIds.entries()) {
573
+ let result;
574
+ try {
575
+ result = await runFixtureCommand({
576
+ fixtureId,
577
+ manifest: params.manifest,
578
+ manifestPath: params.manifestPath,
579
+ registry: params.registry,
580
+ });
581
+ }
582
+ catch (error) {
583
+ const fixture = params.manifest.fixtures.find((entry) => entry.id === fixtureId);
584
+ const provider = fixture ? params.manifest.providers[fixture.provider] : undefined;
585
+ if (!fixture ||
586
+ (provider?.status !== "disabled" && provider?.status !== "planned") ||
587
+ !(error instanceof CrablineError) ||
588
+ error.kind !== "config") {
589
+ throw error;
590
+ }
591
+ result = toFailure(fixture.id, fixture.provider, fixture.mode, error, "config");
592
+ }
593
+ results.push(result);
594
+ if (suiteBlockingOperations.get(result)?.some((operation) => !operation.isSettled())) {
595
+ skippedFixtureIds = requestedFixtureIds.slice(index + 1);
596
+ break;
597
+ }
488
598
  }
489
599
  return {
600
+ requestedFixtureIds,
490
601
  results,
602
+ skippedFixtureIds,
491
603
  totalPassed: results.filter((entry) => entry.ok).length,
492
604
  };
493
605
  }
@@ -521,13 +633,13 @@ export function computeExitCode(result) {
521
633
  return 1;
522
634
  }
523
635
  }
524
- function toFailure(fixtureId, providerId, mode, error, fallbackKind, nonce) {
525
- const diagnostics = [ensureErrorMessage(error)];
636
+ function toFailure(fixtureId, providerId, mode, error, fallbackKind, nonce, priorDiagnostics = []) {
637
+ const diagnostics = [...priorDiagnostics, ensureErrorMessage(error)];
526
638
  if (error instanceof CrablineError) {
527
639
  return {
528
640
  diagnostics,
529
- exitCode: error.exitCode,
530
- failureKind: error.kind,
641
+ ...(error.hasExplicitExitCode || error.kind ? { exitCode: error.exitCode } : {}),
642
+ failureKind: error.kind ?? fallbackKind,
531
643
  fixtureId,
532
644
  mode,
533
645
  nonce,
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/core/run.ts"],"names":[],"mappings":"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","sourcesContent":["import { matchesInbound } from \"./matcher.js\";\nimport { createOutboundText } from \"./message-template.js\";\nimport { createNonce } from \"./nonces.js\";\nimport { inboundRegexSafetyError } from \"./safe-regex.js\";\nimport { type FailureKind, CrablineError, ensureErrorMessage } from \"./errors.js\";\nimport { EXIT_CODES, type ExitCode } from \"./exit-codes.js\";\nimport type { ManifestDefinition } from \"../config/schema.js\";\nimport type { Registry } from \"../providers/registry.js\";\n\nexport type CommandRunResult = {\n diagnostics: string[];\n exitCode?: ExitCode | undefined;\n failureKind?: FailureKind | undefined;\n fixtureId: string;\n mode: string;\n nonce?: string | undefined;\n ok: boolean;\n providerId: string;\n};\n\nexport type SuiteRunResult = {\n results: CommandRunResult[];\n totalPassed: number;\n};\n\nconst INBOUND_DEADLINE_REACHED = Symbol(\"inbound deadline reached\");\nconst INBOUND_ABORT_GRACE_MS = 250;\nconst MAX_EXCLUDED_INBOUND_IDS = 1_024;\nconst MAX_SCRIPT_STDIN_BYTES = 1024 * 1024;\n\nclass UnsettledProviderOperationError extends CrablineError {}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function raceInboundDeadline<T>(\n operation: Promise<T>,\n timeoutMs: number,\n): Promise<T | typeof INBOUND_DEADLINE_REACHED> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<typeof INBOUND_DEADLINE_REACHED>((resolve) => {\n timer = setTimeout(() => resolve(INBOUND_DEADLINE_REACHED), timeoutMs);\n });\n try {\n return await Promise.race([operation, deadline]);\n } finally {\n if (timer) {\n clearTimeout(timer);\n }\n }\n}\n\nasync function withFixtureDeadline<T>(\n operation: (signal: AbortSignal) => Promise<T>,\n timeoutMs: number,\n operationName: string,\n): Promise<T> {\n const controller = new AbortController();\n const pending = Promise.resolve().then(async () => await operation(controller.signal));\n const result = await raceInboundDeadline(pending, timeoutMs);\n if (result === INBOUND_DEADLINE_REACHED) {\n const timeoutError = new CrablineError(\n `Provider ${operationName} timed out after ${timeoutMs}ms.`,\n {\n kind: \"timeout\",\n },\n );\n controller.abort(timeoutError);\n const settled = pending.then(\n () => true,\n () => true,\n );\n if ((await raceInboundDeadline(settled, INBOUND_ABORT_GRACE_MS)) === INBOUND_DEADLINE_REACHED) {\n throw new UnsettledProviderOperationError(\n `Provider ${operationName} did not settle within ${INBOUND_ABORT_GRACE_MS}ms after abort.`,\n {\n cause: timeoutError,\n kind: \"timeout\",\n },\n );\n }\n throw timeoutError;\n }\n return result;\n}\n\nasync function withCleanupDeadline<T>(\n operation: Promise<T>,\n timeoutMs: number,\n operationName: string,\n): Promise<T> {\n const result = await raceInboundDeadline(operation, timeoutMs);\n if (result === INBOUND_DEADLINE_REACHED) {\n throw new CrablineError(`Provider ${operationName} timed out after ${timeoutMs}ms.`, {\n kind: \"timeout\",\n });\n }\n return result;\n}\n\nfunction jsonStringByteLength(value: string, limit: number): number {\n let bytes = 2;\n for (let index = 0; index < value.length && bytes <= limit; index += 1) {\n const code = value.charCodeAt(index);\n if (code === 0x22 || code === 0x5c || code === 0x08 || code === 0x09 || code === 0x0a) {\n bytes += 2;\n } else if (code === 0x0c || code === 0x0d) {\n bytes += 2;\n } else if (code <= 0x1f) {\n bytes += 6;\n } else if (code >= 0xd800 && code <= 0xdbff) {\n const next = value.charCodeAt(index + 1);\n if (next >= 0xdc00 && next <= 0xdfff) {\n bytes += 4;\n index += 1;\n } else {\n bytes += 6;\n }\n } else if (code >= 0xdc00 && code <= 0xdfff) {\n bytes += 6;\n } else if (code <= 0x7f) {\n bytes += 1;\n } else if (code <= 0x7ff) {\n bytes += 2;\n } else {\n bytes += 3;\n }\n }\n return bytes;\n}\n\nfunction boundedJsonByteLength(\n value: unknown,\n limit: number,\n ancestors = new Set<object>(),\n arrayEntry = false,\n): number {\n if (value === null || value === undefined || typeof value === \"function\") {\n return value === undefined && !arrayEntry ? 0 : 4;\n }\n if (typeof value === \"string\") {\n return jsonStringByteLength(value, limit);\n }\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? String(value).length : 4;\n }\n if (typeof value === \"boolean\") {\n return value ? 4 : 5;\n }\n if (typeof value !== \"object\") {\n return 0;\n }\n if (ancestors.has(value)) {\n throw new CrablineError(\"Script command input must not contain circular values.\", {\n kind: \"config\",\n });\n }\n\n ancestors.add(value);\n let bytes = 2;\n let entries = 0;\n if (Array.isArray(value)) {\n for (const entry of value) {\n if (entries > 0) {\n bytes += 1;\n }\n bytes += boundedJsonByteLength(entry, limit - bytes, ancestors, true);\n entries += 1;\n if (bytes > limit) {\n break;\n }\n }\n } else {\n for (const [key, entry] of Object.entries(value)) {\n if (entry === undefined || typeof entry === \"function\") {\n continue;\n }\n if (entries > 0) {\n bytes += 1;\n }\n bytes += jsonStringByteLength(key, limit - bytes) + 1;\n bytes += boundedJsonByteLength(entry, limit - bytes, ancestors);\n entries += 1;\n if (bytes > limit) {\n break;\n }\n }\n }\n ancestors.delete(value);\n return bytes;\n}\n\nexport function assertScriptStdinPayloadSize(payload: unknown): void {\n if (boundedJsonByteLength(payload, MAX_SCRIPT_STDIN_BYTES) > MAX_SCRIPT_STDIN_BYTES) {\n throw new CrablineError(`Script command input exceeded ${MAX_SCRIPT_STDIN_BYTES} bytes.`, {\n kind: \"config\",\n });\n }\n}\n\nfunction scriptPayloadBase(context: {\n config: ManifestDefinition[\"providers\"][string];\n fixture: ManifestDefinition[\"fixtures\"][number];\n manifestPath: string;\n providerId: string;\n}): object {\n return {\n fixture: context.fixture,\n provider: {\n config: context.config,\n id: context.providerId,\n manifestPath: context.manifestPath,\n },\n };\n}\n\nasync function abortAndDrainInboundWait(\n operation: Promise<unknown>,\n controller: AbortController,\n): Promise<boolean> {\n controller.abort(new Error(\"Inbound wait deadline reached.\"));\n const settled = operation.then(\n () => true,\n () => true,\n );\n return (await raceInboundDeadline(settled, INBOUND_ABORT_GRACE_MS)) !== INBOUND_DEADLINE_REACHED;\n}\n\nexport async function runFixtureCommand(params: {\n fixtureId: string;\n manifest: ManifestDefinition;\n manifestPath: string;\n modeOverride?: \"agent\" | \"probe\" | \"roundtrip\" | \"send\";\n registry: Registry;\n}): Promise<CommandRunResult> {\n const configuredFixture = params.manifest.fixtures.find((entry) => entry.id === params.fixtureId);\n if (!configuredFixture) {\n throw new CrablineError(`Unknown fixture: ${params.fixtureId}`, { kind: \"config\" });\n }\n\n const mode = params.modeOverride ?? configuredFixture.mode;\n const fixture =\n mode === configuredFixture.mode ? configuredFixture : { ...configuredFixture, mode };\n const provider = params.registry.resolve(fixture.provider, fixture.id);\n const diagnostics: string[] = [];\n let abortDrainFailed = false;\n\n const contextBase = {\n config: params.manifest.providers[fixture.provider]!,\n fixture,\n manifestPath: params.manifestPath,\n providerId: fixture.provider,\n userName: params.manifest.userName,\n };\n\n let result: CommandRunResult | undefined;\n try {\n if (!provider.supports.includes(mode)) {\n result = {\n diagnostics: [`provider ${fixture.provider} does not support mode ${mode}`],\n failureKind: \"config\",\n fixtureId: fixture.id,\n mode,\n ok: false,\n providerId: fixture.provider,\n };\n }\n\n if (!result) {\n for (const envName of [\n ...fixture.env,\n ...(params.manifest.providers[fixture.provider]?.env ?? []),\n ]) {\n if (!process.env[envName]) {\n result = {\n diagnostics: [`missing env: ${envName}`],\n failureKind: \"config\",\n fixtureId: fixture.id,\n mode,\n ok: false,\n providerId: fixture.provider,\n };\n break;\n }\n }\n }\n\n if (result) {\n // Preflight failures still flow through provider cleanup before returning.\n } else if (mode === \"probe\") {\n try {\n if (contextBase.config.adapter === \"script\") {\n assertScriptStdinPayloadSize(scriptPayloadBase(contextBase));\n }\n const probeResult = await withFixtureDeadline(\n async (signal) => await provider.probe({ ...contextBase, signal }),\n fixture.timeoutMs,\n \"probe\",\n );\n return (result = {\n diagnostics: probeResult.details,\n failureKind: probeResult.healthy ? undefined : \"connectivity\",\n fixtureId: fixture.id,\n mode,\n ok: probeResult.healthy,\n providerId: fixture.provider,\n });\n } catch (error) {\n if (error instanceof UnsettledProviderOperationError) {\n abortDrainFailed = true;\n }\n return (result = toFailure(fixture.id, fixture.provider, mode, error, \"connectivity\"));\n }\n } else {\n if (fixture.inboundMatch.strategy === \"regex\" && fixture.inboundMatch.pattern) {\n try {\n RegExp(fixture.inboundMatch.pattern, \"u\");\n const safetyError = inboundRegexSafetyError(fixture.inboundMatch.pattern);\n if (safetyError) {\n throw new Error(safetyError);\n }\n } catch (error) {\n return (result = toFailure(\n fixture.id,\n fixture.provider,\n mode,\n new CrablineError(`Invalid inbound regex: ${ensureErrorMessage(error)}`, {\n cause: error,\n kind: \"config\",\n }),\n \"config\",\n ));\n }\n }\n\n let attempts = 0;\n const maxAttempts = fixture.retries + 1;\n let lastFailure: CommandRunResult | null = null;\n\n while (attempts < maxAttempts) {\n attempts += 1;\n const nonce = createNonce(fixture.id);\n\n try {\n const outboundText = createOutboundText({ ...fixture, mode }, nonce);\n const since = new Date().toISOString();\n let accepted;\n try {\n const sendContext = {\n ...contextBase,\n mode,\n nonce,\n text: outboundText,\n };\n if (contextBase.config.adapter === \"script\") {\n assertScriptStdinPayloadSize({\n ...scriptPayloadBase(contextBase),\n outbound: {\n mode,\n nonce,\n target: fixture.target,\n text: outboundText,\n },\n });\n }\n accepted = await withFixtureDeadline(\n async (signal) => await provider.send({ ...sendContext, signal }),\n fixture.timeoutMs,\n \"send\",\n );\n } catch (error) {\n lastFailure = toFailure(fixture.id, fixture.provider, mode, error, \"outbound\", nonce);\n if (error instanceof UnsettledProviderOperationError) {\n abortDrainFailed = true;\n break;\n }\n continue;\n }\n if (!accepted.accepted) {\n lastFailure = toFailure(\n fixture.id,\n fixture.provider,\n mode,\n new CrablineError(`Provider rejected outbound message ${accepted.messageId}.`, {\n kind: \"outbound\",\n }),\n \"outbound\",\n nonce,\n );\n continue;\n }\n diagnostics.push(`accepted message ${accepted.messageId}`);\n\n if (mode === \"send\") {\n return (result = {\n diagnostics,\n fixtureId: fixture.id,\n mode,\n nonce,\n ok: true,\n providerId: fixture.provider,\n });\n }\n\n const inboundDeadline = Date.now() + fixture.timeoutMs;\n const seenInbound = new Set<string>();\n const excludedInboundIds = new Set<string>();\n let inbound;\n try {\n while (Date.now() < inboundDeadline) {\n const timeoutMs = inboundDeadline - Date.now();\n const controller = new AbortController();\n const excludeIds = [...excludedInboundIds];\n const waitContext = {\n ...contextBase,\n excludeIds,\n nonce,\n signal: controller.signal,\n since,\n threadId: accepted.threadId,\n timeoutMs,\n };\n if (contextBase.config.adapter === \"script\") {\n assertScriptStdinPayloadSize({\n ...scriptPayloadBase(contextBase),\n wait: {\n excludeIds,\n nonce,\n since,\n target: fixture.target,\n threadId: accepted.threadId,\n timeoutMs,\n },\n });\n }\n const wait = provider.waitForInbound(waitContext);\n const candidate = await raceInboundDeadline(wait, timeoutMs);\n if (candidate === INBOUND_DEADLINE_REACHED) {\n if (!(await abortAndDrainInboundWait(wait, controller))) {\n abortDrainFailed = true;\n throw new UnsettledProviderOperationError(\n `Provider inbound wait did not settle within ${INBOUND_ABORT_GRACE_MS}ms after abort.`,\n { kind: \"inbound\" },\n );\n }\n break;\n }\n if (!candidate) {\n break;\n }\n\n const key = JSON.stringify([candidate.provider, candidate.threadId, candidate.id]);\n if (seenInbound.has(key)) {\n await sleep(Math.min(10, Math.max(0, inboundDeadline - Date.now())));\n continue;\n }\n seenInbound.add(key);\n\n if (matchesInbound(candidate, fixture.inboundMatch, nonce)) {\n inbound = candidate;\n break;\n }\n if (!excludedInboundIds.has(candidate.id)) {\n if (excludedInboundIds.size >= MAX_EXCLUDED_INBOUND_IDS) {\n throw new CrablineError(\n `Provider returned more than ${MAX_EXCLUDED_INBOUND_IDS} unmatched inbound message IDs.`,\n { kind: \"inbound\" },\n );\n }\n excludedInboundIds.add(candidate.id);\n }\n }\n } catch (error) {\n lastFailure = toFailure(fixture.id, fixture.provider, mode, error, \"inbound\", nonce);\n if (abortDrainFailed) {\n break;\n }\n continue;\n }\n if (!inbound) {\n lastFailure = {\n diagnostics: [\n ...diagnostics,\n `timed out waiting for inbound after ${fixture.timeoutMs}ms`,\n ],\n failureKind: \"timeout\",\n fixtureId: fixture.id,\n mode,\n nonce,\n ok: false,\n providerId: fixture.provider,\n };\n if (attempts < maxAttempts) {\n await sleep(50);\n }\n continue;\n }\n\n return (result = {\n diagnostics: [...diagnostics, `matched inbound ${inbound.id}`],\n fixtureId: fixture.id,\n mode,\n nonce,\n ok: true,\n providerId: fixture.provider,\n });\n } catch (error) {\n lastFailure = toFailure(fixture.id, fixture.provider, mode, error, \"assertion\", nonce);\n }\n }\n\n return (result = lastFailure ?? {\n diagnostics: [\"unknown failure\"],\n failureKind: \"assertion\",\n fixtureId: fixture.id,\n mode,\n ok: false,\n providerId: fixture.provider,\n });\n }\n } finally {\n const cleanupErrors: unknown[] = [];\n try {\n provider.beginCleanup?.();\n } catch (error) {\n cleanupErrors.push(error);\n }\n try {\n const cleanup = provider.cleanup?.();\n if (cleanup) {\n if (\n abortDrainFailed &&\n (await raceInboundDeadline(cleanup, INBOUND_ABORT_GRACE_MS)) === INBOUND_DEADLINE_REACHED\n ) {\n cleanupErrors.push(\n new Error(\n `Provider cleanup did not settle within ${INBOUND_ABORT_GRACE_MS}ms after an aborted operation.`,\n ),\n );\n }\n if (!abortDrainFailed) {\n await withCleanupDeadline(cleanup, fixture.timeoutMs, \"cleanup\");\n }\n }\n } catch (error) {\n cleanupErrors.push(error);\n }\n if (cleanupErrors.length > 0) {\n const cleanupError =\n cleanupErrors.length === 1\n ? cleanupErrors[0]\n : new AggregateError(\n cleanupErrors,\n cleanupErrors.map((error) => ensureErrorMessage(error)).join(\"; \"),\n );\n const diagnostic = `cleanup failed: ${ensureErrorMessage(cleanupError)}`;\n if (result) {\n result.diagnostics.push(diagnostic);\n if (result.ok) {\n result.exitCode = EXIT_CODES.ASSERTION;\n result.failureKind = \"assertion\";\n result.ok = false;\n }\n } else {\n result = {\n diagnostics: [...diagnostics, diagnostic],\n exitCode: EXIT_CODES.ASSERTION,\n failureKind: \"assertion\",\n fixtureId: fixture.id,\n mode,\n ok: false,\n providerId: fixture.provider,\n };\n }\n }\n }\n\n // The finally block can synthesize a result when provider cleanup fails.\n // oxlint-disable-next-line no-unreachable\n return result!;\n}\n\nexport async function runSuite(params: {\n fixtureIds: string[];\n manifest: ManifestDefinition;\n manifestPath: string;\n registry: Registry;\n}): Promise<SuiteRunResult> {\n const results: CommandRunResult[] = [];\n for (const fixtureId of params.fixtureIds) {\n results.push(\n await runFixtureCommand({\n fixtureId,\n manifest: params.manifest,\n manifestPath: params.manifestPath,\n registry: params.registry,\n }),\n );\n }\n\n return {\n results,\n totalPassed: results.filter((entry) => entry.ok).length,\n };\n}\n\nexport function computeExitCode(result: CommandRunResult | SuiteRunResult): number {\n if (\"results\" in result) {\n const failure = result.results.find((entry) => !entry.ok);\n return failure ? computeExitCode(failure) : 0;\n }\n\n if (result.ok) {\n return 0;\n }\n\n if (result.exitCode !== undefined) {\n return result.exitCode;\n }\n\n switch (result.failureKind) {\n case \"auth\":\n return 11;\n case \"config\":\n return 10;\n case \"connectivity\":\n return 12;\n case \"outbound\":\n return 13;\n case \"inbound\":\n return 14;\n case \"timeout\":\n return 15;\n case \"assertion\":\n return 16;\n default:\n return 1;\n }\n}\n\nfunction toFailure(\n fixtureId: string,\n providerId: string,\n mode: string,\n error: unknown,\n fallbackKind: FailureKind,\n nonce?: string,\n): CommandRunResult {\n const diagnostics = [ensureErrorMessage(error)];\n if (error instanceof CrablineError) {\n return {\n diagnostics,\n exitCode: error.exitCode,\n failureKind: error.kind,\n fixtureId,\n mode,\n nonce,\n ok: false,\n providerId,\n };\n }\n\n return {\n diagnostics,\n failureKind: fallbackKind,\n fixtureId,\n mode,\n nonce,\n ok: false,\n providerId,\n };\n}\n"]}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/core/run.ts"],"names":[],"mappings":"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","sourcesContent":["import { performance } from \"node:perf_hooks\";\nimport { matchesInbound } from \"./matcher.js\";\nimport { createOutboundText } from \"./message-template.js\";\nimport { createNonce } from \"./nonces.js\";\nimport { compileInboundRegex } from \"./safe-regex.js\";\nimport { type FailureKind, CrablineError, ensureErrorMessage } from \"./errors.js\";\nimport { EXIT_CODES, type ExitCode } from \"./exit-codes.js\";\nimport { fixtureModeValidationIssue, type ManifestDefinition } from \"../config/schema.js\";\nimport type { Registry } from \"../providers/registry.js\";\n\nexport type CommandRunResult = {\n diagnostics: string[];\n exitCode?: ExitCode | undefined;\n failureKind?: FailureKind | undefined;\n fixtureId: string;\n mode: string;\n nonce?: string | undefined;\n ok: boolean;\n providerId: string;\n};\n\nexport type SuiteRunResult = {\n requestedFixtureIds?: string[];\n results: CommandRunResult[];\n skippedFixtureIds?: string[];\n totalPassed: number;\n};\n\nconst INBOUND_DEADLINE_REACHED = Symbol(\"inbound deadline reached\");\nconst INBOUND_ABORT_GRACE_MS = 250;\nconst MAX_EXCLUDED_INBOUND_IDS = 1_024;\nconst MAX_SCRIPT_STDIN_BYTES = 1024 * 1024;\nconst suiteBlockingOperations = new WeakMap<\n CommandRunResult,\n ObservedProviderOperation<unknown>[]\n>();\n\ntype ObservedProviderOperation<T> = {\n isSettled(): boolean;\n promise: Promise<T>;\n settled: Promise<void>;\n};\n\nclass UnsettledProviderOperationError extends CrablineError {\n constructor(\n message: string,\n options: { cause?: unknown; kind: FailureKind },\n readonly operation: ObservedProviderOperation<unknown>,\n ) {\n super(message, options);\n }\n}\n\nclass ProviderOperationTimeoutError extends CrablineError {\n constructor(\n message: string,\n readonly retryable: boolean,\n ) {\n super(message, { kind: \"timeout\" });\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction observeProviderOperation<T>(promise: Promise<T>): ObservedProviderOperation<T> {\n let operationSettled = false;\n const settled = promise.then(\n () => {\n operationSettled = true;\n },\n () => {\n operationSettled = true;\n },\n );\n return {\n isSettled: () => operationSettled,\n promise,\n settled,\n };\n}\n\nasync function raceInboundDeadline<T>(\n operation: Promise<T>,\n timeoutMs: number,\n): Promise<T | typeof INBOUND_DEADLINE_REACHED> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<typeof INBOUND_DEADLINE_REACHED>((resolve) => {\n timer = setTimeout(() => resolve(INBOUND_DEADLINE_REACHED), timeoutMs);\n });\n try {\n return await Promise.race([operation, deadline]);\n } finally {\n if (timer) {\n clearTimeout(timer);\n }\n }\n}\n\nasync function withFixtureDeadline<T>(\n operation: (signal: AbortSignal) => Promise<T>,\n timeoutMs: number,\n operationName: string,\n retryableAfterTimeout = true,\n): Promise<T> {\n const controller = new AbortController();\n const pending = observeProviderOperation(\n Promise.resolve().then(async () => await operation(controller.signal)),\n );\n const result = await raceInboundDeadline(pending.promise, timeoutMs);\n if (result === INBOUND_DEADLINE_REACHED) {\n const timeoutError = new ProviderOperationTimeoutError(\n `Provider ${operationName} timed out after ${timeoutMs}ms.`,\n retryableAfterTimeout,\n );\n controller.abort(timeoutError);\n if (\n (await raceInboundDeadline(pending.settled, INBOUND_ABORT_GRACE_MS)) ===\n INBOUND_DEADLINE_REACHED\n ) {\n throw new UnsettledProviderOperationError(\n `Provider ${operationName} did not settle within ${INBOUND_ABORT_GRACE_MS}ms after abort.`,\n {\n cause: timeoutError,\n kind: \"timeout\",\n },\n pending,\n );\n }\n throw timeoutError;\n }\n return result;\n}\n\nasync function withCleanupDeadline<T>(\n operation: ObservedProviderOperation<T>,\n timeoutMs: number,\n operationName: string,\n): Promise<T> {\n const result = await raceInboundDeadline(operation.promise, timeoutMs);\n if (result === INBOUND_DEADLINE_REACHED) {\n throw new UnsettledProviderOperationError(\n `Provider ${operationName} timed out after ${timeoutMs}ms.`,\n {\n kind: \"timeout\",\n },\n operation,\n );\n }\n return result;\n}\n\nfunction jsonStringByteLength(value: string, limit: number): number {\n let bytes = 2;\n for (let index = 0; index < value.length && bytes <= limit; index += 1) {\n const code = value.charCodeAt(index);\n if (code === 0x22 || code === 0x5c || code === 0x08 || code === 0x09 || code === 0x0a) {\n bytes += 2;\n } else if (code === 0x0c || code === 0x0d) {\n bytes += 2;\n } else if (code <= 0x1f) {\n bytes += 6;\n } else if (code >= 0xd800 && code <= 0xdbff) {\n const next = value.charCodeAt(index + 1);\n if (next >= 0xdc00 && next <= 0xdfff) {\n bytes += 4;\n index += 1;\n } else {\n bytes += 6;\n }\n } else if (code >= 0xdc00 && code <= 0xdfff) {\n bytes += 6;\n } else if (code <= 0x7f) {\n bytes += 1;\n } else if (code <= 0x7ff) {\n bytes += 2;\n } else {\n bytes += 3;\n }\n }\n return bytes;\n}\n\nfunction boundedJsonByteLength(\n value: unknown,\n limit: number,\n ancestors = new Set<object>(),\n arrayEntry = false,\n): number {\n if (value === null || value === undefined || typeof value === \"function\") {\n return value === undefined && !arrayEntry ? 0 : 4;\n }\n if (typeof value === \"string\") {\n return jsonStringByteLength(value, limit);\n }\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? String(value).length : 4;\n }\n if (typeof value === \"boolean\") {\n return value ? 4 : 5;\n }\n if (typeof value !== \"object\") {\n return 0;\n }\n if (ancestors.has(value)) {\n throw new CrablineError(\"Script command input must not contain circular values.\", {\n kind: \"config\",\n });\n }\n\n ancestors.add(value);\n let bytes = 2;\n let entries = 0;\n if (Array.isArray(value)) {\n for (const entry of value) {\n if (entries > 0) {\n bytes += 1;\n }\n bytes += boundedJsonByteLength(entry, limit - bytes, ancestors, true);\n entries += 1;\n if (bytes > limit) {\n break;\n }\n }\n } else {\n for (const [key, entry] of Object.entries(value)) {\n if (entry === undefined || typeof entry === \"function\") {\n continue;\n }\n if (entries > 0) {\n bytes += 1;\n }\n bytes += jsonStringByteLength(key, limit - bytes) + 1;\n bytes += boundedJsonByteLength(entry, limit - bytes, ancestors);\n entries += 1;\n if (bytes > limit) {\n break;\n }\n }\n }\n ancestors.delete(value);\n return bytes;\n}\n\nexport function assertScriptStdinPayloadSize(payload: unknown): void {\n if (boundedJsonByteLength(payload, MAX_SCRIPT_STDIN_BYTES) > MAX_SCRIPT_STDIN_BYTES) {\n throw new CrablineError(`Script command input exceeded ${MAX_SCRIPT_STDIN_BYTES} bytes.`, {\n kind: \"config\",\n });\n }\n}\n\nfunction scriptPayloadBase(context: {\n config: ManifestDefinition[\"providers\"][string];\n fixture: ManifestDefinition[\"fixtures\"][number];\n manifestPath: string;\n providerId: string;\n}): object {\n return {\n fixture: context.fixture,\n provider: {\n config: context.config,\n id: context.providerId,\n manifestPath: context.manifestPath,\n },\n };\n}\n\nasync function abortAndDrainInboundWait(\n operation: ObservedProviderOperation<unknown>,\n controller: AbortController,\n): Promise<boolean> {\n controller.abort(new Error(\"Inbound wait deadline reached.\"));\n return (\n (await raceInboundDeadline(operation.settled, INBOUND_ABORT_GRACE_MS)) !==\n INBOUND_DEADLINE_REACHED\n );\n}\n\nfunction isPermanentFailure(result: CommandRunResult): boolean {\n return result.failureKind === \"auth\" || result.failureKind === \"config\";\n}\n\nexport async function runFixtureCommand(params: {\n fixtureId: string;\n manifest: ManifestDefinition;\n manifestPath: string;\n modeOverride?: \"agent\" | \"probe\" | \"roundtrip\" | \"send\";\n registry: Registry;\n}): Promise<CommandRunResult> {\n const configuredFixture = params.manifest.fixtures.find((entry) => entry.id === params.fixtureId);\n if (!configuredFixture) {\n throw new CrablineError(`Unknown fixture: ${params.fixtureId}`, { kind: \"config\" });\n }\n\n const mode = params.modeOverride ?? configuredFixture.mode;\n const fixture =\n mode === configuredFixture.mode ? configuredFixture : { ...configuredFixture, mode };\n const validationIssue = fixtureModeValidationIssue(fixture);\n if (validationIssue) {\n return toFailure(\n configuredFixture.id,\n configuredFixture.provider,\n mode,\n new CrablineError(\n `Invalid effective fixture \"${configuredFixture.id}\": ${validationIssue.message}`,\n { kind: \"config\" },\n ),\n \"config\",\n );\n }\n const provider = params.registry.resolve(fixture.provider, fixture.id);\n const diagnostics: string[] = [];\n let abortDrainFailed = false;\n const unsettledProviderOperations: ObservedProviderOperation<unknown>[] = [];\n\n const contextBase = {\n config: params.manifest.providers[fixture.provider]!,\n fixture,\n manifestPath: params.manifestPath,\n providerId: fixture.provider,\n userName: params.manifest.userName,\n };\n const maxAttempts = fixture.retries + 1;\n\n let result: CommandRunResult | undefined;\n try {\n if (!provider.supports.includes(mode)) {\n result = {\n diagnostics: [`provider ${fixture.provider} does not support mode ${mode}`],\n failureKind: \"config\",\n fixtureId: fixture.id,\n mode,\n ok: false,\n providerId: fixture.provider,\n };\n }\n\n if (!result) {\n for (const envName of [\n ...fixture.env,\n ...(params.manifest.providers[fixture.provider]?.env ?? []),\n ]) {\n if (!process.env[envName]) {\n result = {\n diagnostics: [`missing env: ${envName}`],\n failureKind: \"config\",\n fixtureId: fixture.id,\n mode,\n ok: false,\n providerId: fixture.provider,\n };\n break;\n }\n }\n }\n\n if (result) {\n // Preflight failures still flow through provider cleanup before returning.\n } else if (mode === \"probe\") {\n let attempts = 0;\n let lastFailure: CommandRunResult | null = null;\n while (attempts < maxAttempts) {\n attempts += 1;\n try {\n if (contextBase.config.adapter === \"script\") {\n assertScriptStdinPayloadSize(scriptPayloadBase(contextBase));\n }\n const probeResult = await withFixtureDeadline(\n async (signal) => await provider.probe({ ...contextBase, signal }),\n fixture.timeoutMs,\n \"probe\",\n );\n const probeAttempt: CommandRunResult = {\n diagnostics: probeResult.details,\n failureKind: probeResult.healthy ? undefined : \"connectivity\",\n fixtureId: fixture.id,\n mode,\n ok: probeResult.healthy,\n providerId: fixture.provider,\n };\n if (probeAttempt.ok) {\n return (result = probeAttempt);\n }\n lastFailure = probeAttempt;\n } catch (error) {\n lastFailure = toFailure(fixture.id, fixture.provider, mode, error, \"connectivity\");\n if (error instanceof UnsettledProviderOperationError) {\n abortDrainFailed = true;\n unsettledProviderOperations.push(error.operation);\n break;\n }\n if (isPermanentFailure(lastFailure)) {\n break;\n }\n }\n }\n return (result = lastFailure ?? {\n diagnostics: [\"unknown failure\"],\n failureKind: \"connectivity\",\n fixtureId: fixture.id,\n mode,\n ok: false,\n providerId: fixture.provider,\n });\n } else {\n let compiledInboundRegex: ReturnType<typeof compileInboundRegex> | undefined;\n if (fixture.inboundMatch.strategy === \"regex\" && fixture.inboundMatch.pattern) {\n try {\n RegExp(fixture.inboundMatch.pattern, \"u\");\n compiledInboundRegex = compileInboundRegex(fixture.inboundMatch.pattern);\n } catch (error) {\n return (result = toFailure(\n fixture.id,\n fixture.provider,\n mode,\n new CrablineError(`Invalid inbound regex: ${ensureErrorMessage(error)}`, {\n cause: error,\n kind: \"config\",\n }),\n \"config\",\n ));\n }\n }\n const preparedInboundMatch = compiledInboundRegex\n ? { ...fixture.inboundMatch, pattern: undefined }\n : fixture.inboundMatch;\n\n let attempts = 0;\n let lastFailure: CommandRunResult | null = null;\n\n while (attempts < maxAttempts) {\n attempts += 1;\n const nonce = createNonce(fixture.id);\n\n try {\n const outboundText = createOutboundText({ ...fixture, mode }, nonce);\n const since = new Date().toISOString();\n let accepted;\n try {\n const sendContext = {\n ...contextBase,\n mode,\n nonce,\n text: outboundText,\n };\n if (contextBase.config.adapter === \"script\") {\n assertScriptStdinPayloadSize({\n ...scriptPayloadBase(contextBase),\n outbound: {\n mode,\n nonce,\n target: fixture.target,\n text: outboundText,\n },\n });\n }\n accepted = await withFixtureDeadline(\n async (signal) => await provider.send({ ...sendContext, signal }),\n fixture.timeoutMs,\n \"send\",\n false,\n );\n } catch (error) {\n lastFailure = toFailure(fixture.id, fixture.provider, mode, error, \"outbound\", nonce);\n if (error instanceof UnsettledProviderOperationError) {\n abortDrainFailed = true;\n unsettledProviderOperations.push(error.operation);\n break;\n }\n if (error instanceof ProviderOperationTimeoutError && !error.retryable) {\n break;\n }\n if (isPermanentFailure(lastFailure)) {\n break;\n }\n continue;\n }\n if (!accepted.accepted) {\n lastFailure = toFailure(\n fixture.id,\n fixture.provider,\n mode,\n new CrablineError(`Provider rejected outbound message ${accepted.messageId}.`, {\n kind: \"outbound\",\n }),\n \"outbound\",\n nonce,\n );\n continue;\n }\n diagnostics.push(`accepted message ${accepted.messageId}`);\n\n if (mode === \"send\") {\n return (result = {\n diagnostics,\n fixtureId: fixture.id,\n mode,\n nonce,\n ok: true,\n providerId: fixture.provider,\n });\n }\n\n const inboundDeadline = performance.now() + fixture.timeoutMs;\n const seenInbound = new Set<string>();\n const excludedInboundIds = new Set<string>();\n let inbound;\n try {\n while (true) {\n const timeoutMs = Math.max(0, Math.ceil(inboundDeadline - performance.now()));\n if (timeoutMs === 0) {\n break;\n }\n const controller = new AbortController();\n const excludeIds = [...excludedInboundIds];\n const waitContext = {\n ...contextBase,\n excludeIds,\n nonce,\n signal: controller.signal,\n since,\n threadId: accepted.threadId,\n timeoutMs,\n };\n if (contextBase.config.adapter === \"script\") {\n assertScriptStdinPayloadSize({\n ...scriptPayloadBase(contextBase),\n wait: {\n excludeIds,\n nonce,\n since,\n target: fixture.target,\n threadId: accepted.threadId,\n timeoutMs,\n },\n });\n }\n const wait = observeProviderOperation(provider.waitForInbound(waitContext));\n const candidate = await raceInboundDeadline(wait.promise, timeoutMs);\n if (candidate === INBOUND_DEADLINE_REACHED) {\n if (!(await abortAndDrainInboundWait(wait, controller))) {\n abortDrainFailed = true;\n unsettledProviderOperations.push(wait);\n throw new UnsettledProviderOperationError(\n `Provider inbound wait did not settle within ${INBOUND_ABORT_GRACE_MS}ms after abort.`,\n { kind: \"inbound\" },\n wait,\n );\n }\n break;\n }\n if (!candidate) {\n break;\n }\n\n const key = JSON.stringify([candidate.provider, candidate.threadId, candidate.id]);\n if (seenInbound.has(key)) {\n await sleep(\n Math.min(10, Math.max(0, Math.ceil(inboundDeadline - performance.now()))),\n );\n continue;\n }\n\n if (\n matchesInbound(candidate, preparedInboundMatch, nonce, {\n requireAcknowledgement: mode === \"agent\",\n }) &&\n (!compiledInboundRegex || compiledInboundRegex.test(candidate.text ?? \"\"))\n ) {\n inbound = candidate;\n break;\n }\n if (seenInbound.size >= MAX_EXCLUDED_INBOUND_IDS) {\n const diagnostic =\n excludedInboundIds.size >= MAX_EXCLUDED_INBOUND_IDS &&\n !excludedInboundIds.has(candidate.id)\n ? `Provider returned more than ${MAX_EXCLUDED_INBOUND_IDS} unmatched inbound message IDs.`\n : `Provider returned more than ${MAX_EXCLUDED_INBOUND_IDS} distinct unmatched inbound envelopes.`;\n throw new CrablineError(diagnostic, { kind: \"inbound\" });\n }\n seenInbound.add(key);\n if (!excludedInboundIds.has(candidate.id)) {\n excludedInboundIds.add(candidate.id);\n }\n }\n } catch (error) {\n lastFailure = toFailure(\n fixture.id,\n fixture.provider,\n mode,\n error,\n \"inbound\",\n nonce,\n diagnostics,\n );\n if (abortDrainFailed) {\n break;\n }\n if (isPermanentFailure(lastFailure)) {\n break;\n }\n continue;\n }\n if (!inbound) {\n lastFailure = {\n diagnostics: [\n ...diagnostics,\n `timed out waiting for inbound after ${fixture.timeoutMs}ms`,\n ],\n failureKind: \"timeout\",\n fixtureId: fixture.id,\n mode,\n nonce,\n ok: false,\n providerId: fixture.provider,\n };\n if (attempts < maxAttempts) {\n await sleep(50);\n }\n continue;\n }\n\n return (result = {\n diagnostics: [...diagnostics, `matched inbound ${inbound.id}`],\n fixtureId: fixture.id,\n mode,\n nonce,\n ok: true,\n providerId: fixture.provider,\n });\n } catch (error) {\n lastFailure = toFailure(\n fixture.id,\n fixture.provider,\n mode,\n error,\n \"assertion\",\n nonce,\n diagnostics,\n );\n }\n }\n\n return (result = lastFailure ?? {\n diagnostics: [\"unknown failure\"],\n failureKind: \"assertion\",\n fixtureId: fixture.id,\n mode,\n ok: false,\n providerId: fixture.provider,\n });\n }\n } finally {\n const cleanupErrors: unknown[] = [];\n try {\n provider.beginCleanup?.();\n } catch (error) {\n cleanupErrors.push(error);\n }\n try {\n const cleanupPromise = provider.cleanup?.();\n if (cleanupPromise) {\n const cleanup = observeProviderOperation(cleanupPromise);\n if (\n abortDrainFailed &&\n (await raceInboundDeadline(cleanup.promise, INBOUND_ABORT_GRACE_MS)) ===\n INBOUND_DEADLINE_REACHED\n ) {\n cleanupErrors.push(\n new Error(\n `Provider cleanup did not settle within ${INBOUND_ABORT_GRACE_MS}ms after an aborted operation.`,\n ),\n );\n unsettledProviderOperations.push(cleanup);\n }\n if (!abortDrainFailed) {\n await withCleanupDeadline(cleanup, fixture.timeoutMs, \"cleanup\");\n }\n }\n } catch (error) {\n if (error instanceof UnsettledProviderOperationError) {\n unsettledProviderOperations.push(error.operation);\n }\n cleanupErrors.push(error);\n }\n if (cleanupErrors.length > 0) {\n const cleanupError =\n cleanupErrors.length === 1\n ? cleanupErrors[0]\n : new AggregateError(\n cleanupErrors,\n cleanupErrors.map((error) => ensureErrorMessage(error)).join(\"; \"),\n );\n const diagnostic = `cleanup failed: ${ensureErrorMessage(cleanupError)}`;\n if (result) {\n result.diagnostics.push(diagnostic);\n if (result.ok) {\n result.exitCode = EXIT_CODES.ASSERTION;\n result.failureKind = \"assertion\";\n result.ok = false;\n }\n } else {\n result = {\n diagnostics: [...diagnostics, diagnostic],\n exitCode: EXIT_CODES.ASSERTION,\n failureKind: \"assertion\",\n fixtureId: fixture.id,\n mode,\n ok: false,\n providerId: fixture.provider,\n };\n }\n }\n await Promise.resolve();\n const blockingOperations = unsettledProviderOperations.filter(\n (operation) => !operation.isSettled(),\n );\n if (result && blockingOperations.length > 0) {\n suiteBlockingOperations.set(result, blockingOperations);\n }\n }\n\n // The finally block can synthesize a result when provider cleanup fails.\n // oxlint-disable-next-line no-unreachable\n return result!;\n}\n\nexport async function runSuite(params: {\n fixtureIds: string[];\n manifest: ManifestDefinition;\n manifestPath: string;\n registry: Registry;\n}): Promise<SuiteRunResult> {\n const requestedFixtureIds = [...params.fixtureIds];\n const results: CommandRunResult[] = [];\n let skippedFixtureIds: string[] = [];\n for (const [index, fixtureId] of requestedFixtureIds.entries()) {\n let result: CommandRunResult;\n try {\n result = await runFixtureCommand({\n fixtureId,\n manifest: params.manifest,\n manifestPath: params.manifestPath,\n registry: params.registry,\n });\n } catch (error) {\n const fixture = params.manifest.fixtures.find((entry) => entry.id === fixtureId);\n const provider = fixture ? params.manifest.providers[fixture.provider] : undefined;\n if (\n !fixture ||\n (provider?.status !== \"disabled\" && provider?.status !== \"planned\") ||\n !(error instanceof CrablineError) ||\n error.kind !== \"config\"\n ) {\n throw error;\n }\n result = toFailure(fixture.id, fixture.provider, fixture.mode, error, \"config\");\n }\n results.push(result);\n if (suiteBlockingOperations.get(result)?.some((operation) => !operation.isSettled())) {\n skippedFixtureIds = requestedFixtureIds.slice(index + 1);\n break;\n }\n }\n\n return {\n requestedFixtureIds,\n results,\n skippedFixtureIds,\n totalPassed: results.filter((entry) => entry.ok).length,\n };\n}\n\nexport function computeExitCode(result: CommandRunResult | SuiteRunResult): number {\n if (\"results\" in result) {\n const failure = result.results.find((entry) => !entry.ok);\n return failure ? computeExitCode(failure) : 0;\n }\n\n if (result.ok) {\n return 0;\n }\n\n if (result.exitCode !== undefined) {\n return result.exitCode;\n }\n\n switch (result.failureKind) {\n case \"auth\":\n return 11;\n case \"config\":\n return 10;\n case \"connectivity\":\n return 12;\n case \"outbound\":\n return 13;\n case \"inbound\":\n return 14;\n case \"timeout\":\n return 15;\n case \"assertion\":\n return 16;\n default:\n return 1;\n }\n}\n\nfunction toFailure(\n fixtureId: string,\n providerId: string,\n mode: string,\n error: unknown,\n fallbackKind: FailureKind,\n nonce?: string,\n priorDiagnostics: readonly string[] = [],\n): CommandRunResult {\n const diagnostics = [...priorDiagnostics, ensureErrorMessage(error)];\n if (error instanceof CrablineError) {\n return {\n diagnostics,\n ...(error.hasExplicitExitCode || error.kind ? { exitCode: error.exitCode } : {}),\n failureKind: error.kind ?? fallbackKind,\n fixtureId,\n mode,\n nonce,\n ok: false,\n providerId,\n };\n }\n\n return {\n diagnostics,\n failureKind: fallbackKind,\n fixtureId,\n mode,\n nonce,\n ok: false,\n providerId,\n };\n}\n"]}