@openclaw/crabline 0.1.10 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import { randomUUID } from "node:crypto";
1
2
  import { CRABLINE_SERVER_CHANNELS, isCrablineServerChannel, startCrablineServer, } from "./servers/index.js";
2
3
  import { SLACK_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from "./openclaw/bridges/slack.js";
3
4
  import { MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from "./openclaw/bridges/mattermost.js";
@@ -9,6 +10,7 @@ import { ZALO_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from "./openclaw/bridges/zalo.
9
10
  import { OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH, OPENCLAW_CRABLINE_CHANNEL_SMOKE_PATH, OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH, OPENCLAW_CRABLINE_DEFAULT_CHANNEL, OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH, OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY, OPENCLAW_CRABLINE_MANIFEST_PATH, parseQaTarget, runOpenClawCrablineProviderProbe, } from "./openclaw/shared.js";
10
11
  import { publishOpenClawCrablineArtifactGeneration } from "./openclaw/artifact-generation.js";
11
12
  import { isAcceptedOpenClawCrablineOutbound } from "./openclaw/outbound-contract.js";
13
+ import { syncParentDirectory } from "./openclaw/private-file.js";
12
14
  import { acquireOpenClawCrablineSmokeRunLock, releaseOpenClawCrablineSmokeRunLock, } from "./openclaw/smoke-lock.js";
13
15
  import fs from "node:fs/promises";
14
16
  import path from "node:path";
@@ -23,6 +25,82 @@ const OPENCLAW_CRABLINE_PROVIDER_BRIDGES = {
23
25
  zalo: ZALO_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,
24
26
  };
25
27
  const OPENCLAW_CRABLINE_PROVIDER_BRIDGE_LIST = Object.values(OPENCLAW_CRABLINE_PROVIDER_BRIDGES);
28
+ const RECORDER_TEMP_NAME_PATTERN = /^\.([a-z]+)-fake-provider\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.jsonl\.tmp$/iu;
29
+ const RECORDER_LOCK_REMOVAL_TOMBSTONE_PATTERN = /^\.(.+)\.\d+\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.remove$/iu;
30
+ function isOpenClawCrablineRecorderTemporary(name) {
31
+ const channel = RECORDER_TEMP_NAME_PATTERN.exec(name)?.[1]?.toLowerCase();
32
+ return channel !== undefined && isCrablineServerChannel(channel);
33
+ }
34
+ function isOpenClawCrablineRecorderTemporaryLock(name) {
35
+ return name.endsWith(".lock") && isOpenClawCrablineRecorderTemporary(name.slice(0, -5));
36
+ }
37
+ function openClawCrablineRecorderLockTombstoneBaseName(name) {
38
+ const originalName = RECORDER_LOCK_REMOVAL_TOMBSTONE_PATTERN.exec(name)?.[1];
39
+ return originalName !== undefined && isOpenClawCrablineRecorderTemporaryLock(originalName)
40
+ ? originalName
41
+ : null;
42
+ }
43
+ async function reclaimOpenClawCrablineRecorderTemporaryLock(directoryPath, name, lock, quarantineBaseName = name) {
44
+ const lockPath = path.join(directoryPath, name);
45
+ let identity;
46
+ try {
47
+ identity = await fs.lstat(lockPath, { bigint: true });
48
+ }
49
+ catch (error) {
50
+ if (error.code === "ENOENT") {
51
+ return;
52
+ }
53
+ throw error;
54
+ }
55
+ if (!identity.isDirectory()) {
56
+ return;
57
+ }
58
+ const currentUserId = process.geteuid?.();
59
+ if (currentUserId !== undefined && identity.uid !== BigInt(currentUserId)) {
60
+ return;
61
+ }
62
+ const quarantinePath = path.join(directoryPath, `.${quarantineBaseName}.${process.pid}.${randomUUID()}.remove`);
63
+ await lock.assertOwned();
64
+ try {
65
+ await fs.rename(lockPath, quarantinePath);
66
+ }
67
+ catch (error) {
68
+ if (error.code === "ENOENT") {
69
+ return;
70
+ }
71
+ throw error;
72
+ }
73
+ const quarantined = await fs.lstat(quarantinePath, { bigint: true });
74
+ if (!quarantined.isDirectory() ||
75
+ quarantined.dev !== identity.dev ||
76
+ quarantined.ino !== identity.ino) {
77
+ throw new Error("OpenClaw Crabline recorder lock identity changed during recovery.");
78
+ }
79
+ await syncParentDirectory(quarantinePath);
80
+ await fs.rm(quarantinePath, { force: true, recursive: true });
81
+ await syncParentDirectory(quarantinePath);
82
+ }
83
+ async function reclaimOpenClawCrablineRecorderTemporaries(directoryPath, lock) {
84
+ for (const entry of await fs.readdir(directoryPath, { withFileTypes: true })) {
85
+ const tombstoneBaseName = entry.isDirectory()
86
+ ? openClawCrablineRecorderLockTombstoneBaseName(entry.name)
87
+ : null;
88
+ if (isOpenClawCrablineRecorderTemporaryLock(entry.name) || tombstoneBaseName !== null) {
89
+ if (entry.isDirectory()) {
90
+ await reclaimOpenClawCrablineRecorderTemporaryLock(directoryPath, entry.name, lock, tombstoneBaseName ?? entry.name);
91
+ }
92
+ continue;
93
+ }
94
+ if (!isOpenClawCrablineRecorderTemporary(entry.name) ||
95
+ (!entry.isFile() && !entry.isSymbolicLink())) {
96
+ continue;
97
+ }
98
+ await lock.assertOwned();
99
+ const temporaryPath = path.join(directoryPath, entry.name);
100
+ await fs.rm(temporaryPath, { force: true });
101
+ await syncParentDirectory(temporaryPath);
102
+ }
103
+ }
26
104
  function createOpenClawCrablineProviderAdapter(manifest) {
27
105
  const bridge = OPENCLAW_CRABLINE_PROVIDER_BRIDGE_LIST.find((candidate) => candidate.provider === manifest.provider);
28
106
  if (bridge) {
@@ -119,9 +197,12 @@ export async function runOpenClawCrablineProviderReadiness(params, dependencies
119
197
  outputDir,
120
198
  });
121
199
  let outcome;
200
+ let recorderPath;
122
201
  try {
123
- const recorderPath = path.join(outputDir, "artifacts", "crabline", `${params.selection.channel}-fake-provider.jsonl`);
124
- await fs.mkdir(path.dirname(recorderPath), { recursive: true });
202
+ const recorderDirectory = path.join(outputDir, "artifacts", "crabline");
203
+ await fs.mkdir(recorderDirectory, { recursive: true });
204
+ await reclaimOpenClawCrablineRecorderTemporaries(recorderDirectory, smokeLock);
205
+ recorderPath = path.join(recorderDirectory, `.${params.selection.channel}-fake-provider.${randomUUID()}.jsonl.tmp`);
125
206
  const adapter = await (dependencies.startAdapter ?? startOpenClawCrablineAdapter)({
126
207
  channel: params.selection.channel,
127
208
  openclawConfig: {},
@@ -170,6 +251,15 @@ export async function runOpenClawCrablineProviderReadiness(params, dependencies
170
251
  if (probeFailed) {
171
252
  throw probeFailure;
172
253
  }
254
+ let recorderSnapshotContents = "";
255
+ try {
256
+ recorderSnapshotContents = await fs.readFile(recorderPath, "utf8");
257
+ }
258
+ catch (error) {
259
+ if (error.code !== "ENOENT") {
260
+ throw error;
261
+ }
262
+ }
173
263
  const capabilityReport = {
174
264
  result: {
175
265
  driver: "crabline",
@@ -193,9 +283,22 @@ export async function runOpenClawCrablineProviderReadiness(params, dependencies
193
283
  lock: smokeLock,
194
284
  manifest: adapter.manifest,
195
285
  outputDir,
286
+ recorderSnapshot: {
287
+ contents: recorderSnapshotContents,
288
+ fileName: `${params.selection.channel}-fake-provider.jsonl`,
289
+ },
196
290
  selection: params.selection,
197
291
  providerReadiness,
198
292
  });
293
+ let recorderCleanupWarning;
294
+ try {
295
+ await fs.rm(recorderPath, { force: true });
296
+ recorderPath = undefined;
297
+ }
298
+ catch (error) {
299
+ const detail = error instanceof Error ? error.message : String(error);
300
+ recorderCleanupWarning = `OpenClaw Crabline recorder snapshot committed but temporary cleanup failed: ${detail}`;
301
+ }
199
302
  outcome = {
200
303
  committed: true,
201
304
  result: {
@@ -208,12 +311,49 @@ export async function runOpenClawCrablineProviderReadiness(params, dependencies
208
311
  providerReadinessArtifactPath: generation.providerReadinessArtifactPath,
209
312
  smoke: generation.providerReadiness,
210
313
  smokeArtifactPath: generation.providerReadinessArtifactPath,
211
- ...(generation.warnings ? { warnings: generation.warnings } : {}),
314
+ ...(generation.warnings || recorderCleanupWarning
315
+ ? {
316
+ warnings: [
317
+ ...(generation.warnings ?? []),
318
+ ...(recorderCleanupWarning ? [recorderCleanupWarning] : []),
319
+ ],
320
+ }
321
+ : {}),
212
322
  },
213
323
  };
214
324
  }
215
325
  catch (error) {
216
- outcome = { committed: false, error };
326
+ let primaryError = error;
327
+ if (recorderPath) {
328
+ try {
329
+ await fs.rm(recorderPath, { force: true });
330
+ recorderPath = undefined;
331
+ }
332
+ catch (cleanupError) {
333
+ if (primaryError instanceof Error) {
334
+ const existingCause = primaryError.cause;
335
+ try {
336
+ Object.defineProperty(primaryError, "cause", {
337
+ configurable: true,
338
+ value: existingCause === undefined
339
+ ? cleanupError
340
+ : new AggregateError([existingCause, cleanupError], "OpenClaw Crabline readiness failure cleanup also failed."),
341
+ });
342
+ }
343
+ catch {
344
+ // Frozen failures remain authoritative even if temporary cleanup also fails.
345
+ }
346
+ }
347
+ else {
348
+ const combinedError = new Error("OpenClaw Crabline readiness and temporary cleanup both failed.", { cause: cleanupError });
349
+ Object.defineProperty(combinedError, "errors", {
350
+ value: [primaryError, cleanupError],
351
+ });
352
+ primaryError = combinedError;
353
+ }
354
+ }
355
+ }
356
+ outcome = { committed: false, error: primaryError };
217
357
  }
218
358
  try {
219
359
  await releaseLock(smokeLock);
@@ -1 +1 @@
1
- {"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../src/openclaw.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CRABLINE_SERVER_CHANNELS,\n isCrablineServerChannel,\n startCrablineServer,\n type CrablineServerChannel,\n type CrablineServerManifest,\n type StartCrablineServerParams,\n type StartedCrablineServer,\n} from \"./servers/index.js\";\nimport { SLACK_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/slack.js\";\nimport { MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/mattermost.js\";\nimport { MATRIX_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/matrix.js\";\nimport { SIGNAL_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/signal.js\";\nimport { TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/telegram.js\";\nimport { WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/whatsapp.js\";\nimport { ZALO_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/zalo.js\";\nimport {\n OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH,\n OPENCLAW_CRABLINE_CHANNEL_SMOKE_PATH,\n OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH,\n OPENCLAW_CRABLINE_DEFAULT_CHANNEL,\n OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH,\n OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY,\n OPENCLAW_CRABLINE_MANIFEST_PATH,\n parseQaTarget,\n runOpenClawCrablineProviderProbe,\n type OpenClawCrablineAgentDelivery,\n type OpenClawCrablineChannelDriverSelection,\n type OpenClawCrablineProviderReadinessResult,\n type OpenClawCrablineGatewayBinding,\n type OpenClawCrablineInbound,\n type OpenClawCrablineInboundInput,\n type OpenClawCrablineOutboundMessage,\n type OpenClawCrablineProviderAdapter,\n type OpenClawCrablineProviderBridge,\n type OpenClawCrablineProviderBridgeRegistry,\n type StartedOpenClawCrablineAdapter,\n type StartOpenClawCrablineAdapterParams,\n} from \"./openclaw/shared.js\";\nimport { publishOpenClawCrablineArtifactGeneration } from \"./openclaw/artifact-generation.js\";\nimport { isAcceptedOpenClawCrablineOutbound } from \"./openclaw/outbound-contract.js\";\nimport {\n acquireOpenClawCrablineSmokeRunLock,\n releaseOpenClawCrablineSmokeRunLock,\n} from \"./openclaw/smoke-lock.js\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport {\n OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH,\n OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY,\n OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH,\n OPENCLAW_CRABLINE_CHANNEL_SMOKE_PATH,\n OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH,\n OPENCLAW_CRABLINE_DEFAULT_CHANNEL,\n OPENCLAW_CRABLINE_MANIFEST_PATH,\n};\nexport type {\n OpenClawCrablineAgentDelivery,\n OpenClawCrablineChannelDriverSelection,\n OpenClawCrablineChannelDriverSmokeResult,\n OpenClawCrablineProviderReadinessResult,\n OpenClawCrablineConversation,\n OpenClawCrablineGatewayBinding,\n OpenClawCrablineInbound,\n OpenClawCrablineInboundInput,\n OpenClawCrablineOutboundMessage,\n StartedOpenClawCrablineAdapter,\n StartOpenClawCrablineAdapterParams,\n} from \"./openclaw/shared.js\";\n\nconst OPENCLAW_CRABLINE_PROVIDER_BRIDGES = {\n mattermost: MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n matrix: MATRIX_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n signal: SIGNAL_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n slack: SLACK_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n telegram: TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n whatsapp: WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n zalo: ZALO_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n} satisfies OpenClawCrablineProviderBridgeRegistry;\n\nconst OPENCLAW_CRABLINE_PROVIDER_BRIDGE_LIST = Object.values(\n OPENCLAW_CRABLINE_PROVIDER_BRIDGES,\n) as readonly OpenClawCrablineProviderBridge[];\n\nfunction createOpenClawCrablineProviderAdapter(\n manifest: CrablineServerManifest,\n): OpenClawCrablineProviderAdapter {\n const bridge = OPENCLAW_CRABLINE_PROVIDER_BRIDGE_LIST.find(\n (candidate) => candidate.provider === manifest.provider,\n );\n if (bridge) {\n const adapter = bridge.createAdapterFromManifest(manifest);\n return {\n ...adapter,\n createOutboundFromRecorderEvent: (params) =>\n isAcceptedOpenClawCrablineOutbound({\n event: params.event,\n manifest,\n })\n ? adapter.createOutboundFromRecorderEvent(params)\n : null,\n probe: () =>\n runOpenClawCrablineProviderProbe(manifest.provider, (signal) => adapter.probe(signal)),\n };\n }\n throw new Error(\"Unsupported OpenClaw provider binding.\");\n}\n\nexport function resolveOpenClawCrablineChannel(input?: string | null): CrablineServerChannel {\n const channel =\n input === undefined || input === null\n ? OPENCLAW_CRABLINE_DEFAULT_CHANNEL\n : input.trim().toLowerCase();\n if (isCrablineServerChannel(channel)) {\n return channel;\n }\n throw new Error(\n `--channel must be one of ${CRABLINE_SERVER_CHANNELS.join(\", \")} for --channel-driver crabline, got \"${input}\".`,\n );\n}\n\nexport function resolveOpenClawCrablineChannelDriverSelection(params: {\n channel?: string | null;\n}): OpenClawCrablineChannelDriverSelection & {\n providerReadinessArtifactPath: typeof OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH;\n} {\n return {\n channel: resolveOpenClawCrablineChannel(params.channel),\n channelDriver: \"crabline\",\n capabilityMatrixPath: OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH,\n providerReadinessArtifactPath: OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH,\n smokeArtifactPath: OPENCLAW_CRABLINE_CHANNEL_SMOKE_PATH,\n };\n}\n\nexport async function probeOpenClawCrablineProvider(\n manifest: CrablineServerManifest,\n): Promise<unknown> {\n return await createOpenClawCrablineProviderAdapter(manifest).probe();\n}\n\nexport function createOpenClawCrablineProviderBinding(\n manifest: CrablineServerManifest,\n): OpenClawCrablineGatewayBinding {\n return createOpenClawCrablineProviderAdapter(manifest).createBinding();\n}\n\nexport function createOpenClawCrablineAgentDelivery(params: {\n manifest: CrablineServerManifest;\n target: string;\n}): OpenClawCrablineAgentDelivery {\n return createOpenClawCrablineProviderAdapter(params.manifest).createAgentDelivery(\n parseQaTarget(params.target),\n );\n}\n\nexport function createOpenClawCrablineInbound(params: {\n input: OpenClawCrablineInboundInput;\n manifest: CrablineServerManifest;\n}): OpenClawCrablineInbound {\n return createOpenClawCrablineProviderAdapter(params.manifest).createInbound(params.input);\n}\n\nexport function createOpenClawCrablineOutboundFromRecorderEvent(params: {\n event: unknown;\n manifest: CrablineServerManifest;\n targetByProviderTarget: ReadonlyMap<string, string>;\n}): OpenClawCrablineOutboundMessage | null {\n return createOpenClawCrablineProviderAdapter(params.manifest).createOutboundFromRecorderEvent({\n event: params.event,\n targetByProviderTarget: params.targetByProviderTarget,\n });\n}\n\nexport async function startOpenClawCrablineAdapter(\n params: StartOpenClawCrablineAdapterParams,\n dependencies: {\n createProviderAdapter?: typeof createOpenClawCrablineProviderAdapter;\n startServer?: (params: StartCrablineServerParams) => Promise<StartedCrablineServer>;\n } = {},\n): Promise<StartedOpenClawCrablineAdapter> {\n const server: StartedCrablineServer = await (dependencies.startServer ?? startCrablineServer)({\n channel: params.channel,\n onEvent: params.onEvent,\n recorderPath: params.recorderPath,\n });\n try {\n const providerAdapter = (\n dependencies.createProviderAdapter ?? createOpenClawCrablineProviderAdapter\n )(server.manifest);\n const binding = providerAdapter.createBinding();\n return {\n ...binding,\n close: server.close,\n createGatewayConfig: (openclawConfig = params.openclawConfig ?? {}) =>\n binding.createGatewayConfig(openclawConfig),\n createAgentDelivery: ({ target }) =>\n providerAdapter.createAgentDelivery(parseQaTarget(target)),\n createInbound: ({ input }) => providerAdapter.createInbound(input),\n createOutboundFromRecorderEvent: ({ event, targetByProviderTarget }) =>\n providerAdapter.createOutboundFromRecorderEvent({\n event,\n targetByProviderTarget,\n }),\n manifest: server.manifest,\n probe: () => providerAdapter.probe(),\n };\n } catch (error) {\n try {\n await server.close();\n } catch (closeError) {\n const aggregateError = new AggregateError(\n [error, closeError],\n \"OpenClaw Crabline adapter startup failed.\",\n );\n aggregateError.cause = error;\n throw aggregateError;\n }\n throw error;\n }\n}\n\ntype ProviderReadinessDependencies = {\n acquireLock?: typeof acquireOpenClawCrablineSmokeRunLock;\n publishGeneration?: typeof publishOpenClawCrablineArtifactGeneration;\n releaseLock?: typeof releaseOpenClawCrablineSmokeRunLock;\n startAdapter?: typeof startOpenClawCrablineAdapter;\n};\n\nexport function runOpenClawCrablineProviderReadiness(params: {\n outputDir: string;\n selection: OpenClawCrablineChannelDriverSelection;\n}): Promise<OpenClawCrablineProviderReadinessResult>;\nexport async function runOpenClawCrablineProviderReadiness(\n params: {\n outputDir: string;\n selection: OpenClawCrablineChannelDriverSelection;\n },\n dependencies: ProviderReadinessDependencies = {},\n): Promise<OpenClawCrablineProviderReadinessResult> {\n const outputDir = path.resolve(params.outputDir);\n const releaseLock = dependencies.releaseLock ?? releaseOpenClawCrablineSmokeRunLock;\n const smokeLock = await (dependencies.acquireLock ?? acquireOpenClawCrablineSmokeRunLock)({\n channel: params.selection.channel,\n outputDir,\n });\n let outcome:\n | { committed: false; error: unknown }\n | { committed: true; result: OpenClawCrablineProviderReadinessResult };\n\n try {\n const recorderPath = path.join(\n outputDir,\n \"artifacts\",\n \"crabline\",\n `${params.selection.channel}-fake-provider.jsonl`,\n );\n await fs.mkdir(path.dirname(recorderPath), { recursive: true });\n const adapter = await (dependencies.startAdapter ?? startOpenClawCrablineAdapter)({\n channel: params.selection.channel,\n openclawConfig: {},\n recorderPath,\n });\n let probe: unknown;\n let probeFailed = false;\n let probeFailure: unknown;\n try {\n probe = await adapter.probe();\n } catch (error) {\n probeFailed = true;\n probeFailure = error;\n }\n try {\n await adapter.close();\n } catch (cleanupError) {\n if (!probeFailed) {\n throw cleanupError;\n }\n if (probeFailure instanceof Error) {\n const existingCause = probeFailure.cause;\n try {\n Object.defineProperty(probeFailure, \"cause\", {\n configurable: true,\n value:\n existingCause === undefined\n ? cleanupError\n : new AggregateError(\n [existingCause, cleanupError],\n \"OpenClaw Crabline provider probe cleanup also failed.\",\n ),\n });\n } catch {\n // Some provider errors are frozen; preserving the primary failure is authoritative.\n }\n throw probeFailure;\n }\n const combinedError = new Error(\"OpenClaw Crabline provider probe and cleanup both failed.\", {\n cause: cleanupError,\n });\n Object.defineProperty(combinedError, \"errors\", {\n value: [probeFailure, cleanupError],\n });\n throw combinedError;\n }\n if (probeFailed) {\n throw probeFailure;\n }\n\n const capabilityReport = {\n result: {\n driver: \"crabline\",\n selectedChannel: params.selection.channel,\n supportedChannels: [...CRABLINE_SERVER_CHANNELS],\n },\n };\n const providerReadiness = {\n result: {\n ok: true,\n proof: \"provider-api-probe\",\n ready: true,\n probe,\n provider: adapter.manifest.provider,\n endpoints: adapter.manifest.endpoints,\n recorderPath: path.relative(outputDir, adapter.manifest.recorderPath),\n },\n };\n const generation = await (\n dependencies.publishGeneration ?? publishOpenClawCrablineArtifactGeneration\n )({\n capabilityReport,\n lock: smokeLock,\n manifest: adapter.manifest,\n outputDir,\n selection: params.selection,\n providerReadiness,\n });\n outcome = {\n committed: true,\n result: {\n artifactPointerPath: generation.pointerPath,\n capabilityReport,\n capabilityMatrixPath: generation.capabilityMatrixPath,\n generation: generation.generation,\n manifestPath: generation.manifestPath,\n providerReadiness: generation.providerReadiness,\n providerReadinessArtifactPath: generation.providerReadinessArtifactPath,\n smoke: generation.providerReadiness,\n smokeArtifactPath: generation.providerReadinessArtifactPath,\n ...(generation.warnings ? { warnings: generation.warnings } : {}),\n },\n };\n } catch (error) {\n outcome = { committed: false, error };\n }\n\n try {\n await releaseLock(smokeLock);\n } catch (cleanupError) {\n // The pointer switch is authoritative; lock removal cannot roll it back.\n if (!outcome.committed) {\n if (outcome.error instanceof Error) {\n const existingCause = outcome.error.cause;\n try {\n Object.defineProperty(outcome.error, \"cause\", {\n configurable: true,\n value:\n existingCause === undefined\n ? cleanupError\n : new AggregateError(\n [existingCause, cleanupError],\n \"OpenClaw Crabline smoke failure cleanup also failed.\",\n ),\n });\n } catch {\n // Some failures are frozen; preserving the primary error is authoritative.\n }\n throw outcome.error;\n }\n const combinedError = new Error(\"OpenClaw Crabline smoke and lock cleanup both failed.\", {\n cause: cleanupError,\n });\n Object.defineProperty(combinedError, \"errors\", {\n value: [outcome.error, cleanupError],\n });\n throw combinedError;\n }\n const detail = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);\n outcome.result = {\n ...outcome.result,\n warnings: [\n ...(outcome.result.warnings ?? []),\n `OpenClaw Crabline smoke committed but lock cleanup failed: ${detail}`,\n ],\n };\n }\n\n if (!outcome.committed) {\n throw outcome.error;\n }\n return outcome.result;\n}\n\n/** @deprecated Use runOpenClawCrablineProviderReadiness. */\nexport const runOpenClawCrablineChannelDriverSmoke = runOpenClawCrablineProviderReadiness;\n\nexport function createOpenClawCrablineChannelReportNotes(\n selection: OpenClawCrablineChannelDriverSelection | null | undefined,\n): string[] {\n if (!selection) {\n return [];\n }\n\n return [\n `Channel driver: ${selection.channelDriver} local provider for ${selection.channel}.`,\n `Channel artifact pointer: ${OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH}.`,\n `Generation capability filename: ${selection.capabilityMatrixPath}.`,\n `Generation provider-readiness filename: ${selection.providerReadinessArtifactPath ?? selection.smokeArtifactPath}.`,\n \"Crabline verifies the local provider API is ready; OpenClaw channel behavior is proven separately by QA scenarios that run the real channel adapter.\",\n ];\n}\n"]}
1
+ {"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../src/openclaw.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { BigIntStats } from \"node:fs\";\nimport {\n CRABLINE_SERVER_CHANNELS,\n isCrablineServerChannel,\n startCrablineServer,\n type CrablineServerChannel,\n type CrablineServerManifest,\n type StartCrablineServerParams,\n type StartedCrablineServer,\n} from \"./servers/index.js\";\nimport { SLACK_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/slack.js\";\nimport { MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/mattermost.js\";\nimport { MATRIX_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/matrix.js\";\nimport { SIGNAL_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/signal.js\";\nimport { TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/telegram.js\";\nimport { WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/whatsapp.js\";\nimport { ZALO_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from \"./openclaw/bridges/zalo.js\";\nimport {\n OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH,\n OPENCLAW_CRABLINE_CHANNEL_SMOKE_PATH,\n OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH,\n OPENCLAW_CRABLINE_DEFAULT_CHANNEL,\n OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH,\n OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY,\n OPENCLAW_CRABLINE_MANIFEST_PATH,\n parseQaTarget,\n runOpenClawCrablineProviderProbe,\n type OpenClawCrablineAgentDelivery,\n type OpenClawCrablineChannelDriverSelection,\n type OpenClawCrablineProviderReadinessResult,\n type OpenClawCrablineGatewayBinding,\n type OpenClawCrablineInbound,\n type OpenClawCrablineInboundInput,\n type OpenClawCrablineOutboundMessage,\n type OpenClawCrablineProviderAdapter,\n type OpenClawCrablineProviderBridge,\n type OpenClawCrablineProviderBridgeRegistry,\n type StartedOpenClawCrablineAdapter,\n type StartOpenClawCrablineAdapterParams,\n} from \"./openclaw/shared.js\";\nimport { publishOpenClawCrablineArtifactGeneration } from \"./openclaw/artifact-generation.js\";\nimport { isAcceptedOpenClawCrablineOutbound } from \"./openclaw/outbound-contract.js\";\nimport { syncParentDirectory } from \"./openclaw/private-file.js\";\nimport {\n acquireOpenClawCrablineSmokeRunLock,\n releaseOpenClawCrablineSmokeRunLock,\n} from \"./openclaw/smoke-lock.js\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport {\n OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH,\n OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY,\n OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH,\n OPENCLAW_CRABLINE_CHANNEL_SMOKE_PATH,\n OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH,\n OPENCLAW_CRABLINE_DEFAULT_CHANNEL,\n OPENCLAW_CRABLINE_MANIFEST_PATH,\n};\nexport type {\n OpenClawCrablineAgentDelivery,\n OpenClawCrablineChannelDriverSelection,\n OpenClawCrablineChannelDriverSmokeResult,\n OpenClawCrablineProviderReadinessResult,\n OpenClawCrablineConversation,\n OpenClawCrablineGatewayBinding,\n OpenClawCrablineInbound,\n OpenClawCrablineInboundInput,\n OpenClawCrablineOutboundMessage,\n StartedOpenClawCrablineAdapter,\n StartOpenClawCrablineAdapterParams,\n} from \"./openclaw/shared.js\";\n\nconst OPENCLAW_CRABLINE_PROVIDER_BRIDGES = {\n mattermost: MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n matrix: MATRIX_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n signal: SIGNAL_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n slack: SLACK_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n telegram: TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n whatsapp: WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n zalo: ZALO_OPENCLAW_CRABLINE_PROVIDER_BRIDGE,\n} satisfies OpenClawCrablineProviderBridgeRegistry;\n\nconst OPENCLAW_CRABLINE_PROVIDER_BRIDGE_LIST = Object.values(\n OPENCLAW_CRABLINE_PROVIDER_BRIDGES,\n) as readonly OpenClawCrablineProviderBridge[];\nconst RECORDER_TEMP_NAME_PATTERN =\n /^\\.([a-z]+)-fake-provider\\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\\.jsonl\\.tmp$/iu;\nconst RECORDER_LOCK_REMOVAL_TOMBSTONE_PATTERN =\n /^\\.(.+)\\.\\d+\\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\\.remove$/iu;\n\nfunction isOpenClawCrablineRecorderTemporary(name: string): boolean {\n const channel = RECORDER_TEMP_NAME_PATTERN.exec(name)?.[1]?.toLowerCase();\n return channel !== undefined && isCrablineServerChannel(channel);\n}\n\nfunction isOpenClawCrablineRecorderTemporaryLock(name: string): boolean {\n return name.endsWith(\".lock\") && isOpenClawCrablineRecorderTemporary(name.slice(0, -5));\n}\n\nfunction openClawCrablineRecorderLockTombstoneBaseName(name: string): string | null {\n const originalName = RECORDER_LOCK_REMOVAL_TOMBSTONE_PATTERN.exec(name)?.[1];\n return originalName !== undefined && isOpenClawCrablineRecorderTemporaryLock(originalName)\n ? originalName\n : null;\n}\n\nasync function reclaimOpenClawCrablineRecorderTemporaryLock(\n directoryPath: string,\n name: string,\n lock: Awaited<ReturnType<typeof acquireOpenClawCrablineSmokeRunLock>>,\n quarantineBaseName = name,\n): Promise<void> {\n const lockPath = path.join(directoryPath, name);\n let identity: BigIntStats;\n try {\n identity = await fs.lstat(lockPath, { bigint: true });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return;\n }\n throw error;\n }\n if (!identity.isDirectory()) {\n return;\n }\n const currentUserId = process.geteuid?.();\n if (currentUserId !== undefined && identity.uid !== BigInt(currentUserId)) {\n return;\n }\n\n const quarantinePath = path.join(\n directoryPath,\n `.${quarantineBaseName}.${process.pid}.${randomUUID()}.remove`,\n );\n await lock.assertOwned();\n try {\n await fs.rename(lockPath, quarantinePath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return;\n }\n throw error;\n }\n const quarantined = await fs.lstat(quarantinePath, { bigint: true });\n if (\n !quarantined.isDirectory() ||\n quarantined.dev !== identity.dev ||\n quarantined.ino !== identity.ino\n ) {\n throw new Error(\"OpenClaw Crabline recorder lock identity changed during recovery.\");\n }\n await syncParentDirectory(quarantinePath);\n await fs.rm(quarantinePath, { force: true, recursive: true });\n await syncParentDirectory(quarantinePath);\n}\n\nasync function reclaimOpenClawCrablineRecorderTemporaries(\n directoryPath: string,\n lock: Awaited<ReturnType<typeof acquireOpenClawCrablineSmokeRunLock>>,\n): Promise<void> {\n for (const entry of await fs.readdir(directoryPath, { withFileTypes: true })) {\n const tombstoneBaseName = entry.isDirectory()\n ? openClawCrablineRecorderLockTombstoneBaseName(entry.name)\n : null;\n if (isOpenClawCrablineRecorderTemporaryLock(entry.name) || tombstoneBaseName !== null) {\n if (entry.isDirectory()) {\n await reclaimOpenClawCrablineRecorderTemporaryLock(\n directoryPath,\n entry.name,\n lock,\n tombstoneBaseName ?? entry.name,\n );\n }\n continue;\n }\n if (\n !isOpenClawCrablineRecorderTemporary(entry.name) ||\n (!entry.isFile() && !entry.isSymbolicLink())\n ) {\n continue;\n }\n await lock.assertOwned();\n const temporaryPath = path.join(directoryPath, entry.name);\n await fs.rm(temporaryPath, { force: true });\n await syncParentDirectory(temporaryPath);\n }\n}\n\nfunction createOpenClawCrablineProviderAdapter(\n manifest: CrablineServerManifest,\n): OpenClawCrablineProviderAdapter {\n const bridge = OPENCLAW_CRABLINE_PROVIDER_BRIDGE_LIST.find(\n (candidate) => candidate.provider === manifest.provider,\n );\n if (bridge) {\n const adapter = bridge.createAdapterFromManifest(manifest);\n return {\n ...adapter,\n createOutboundFromRecorderEvent: (params) =>\n isAcceptedOpenClawCrablineOutbound({\n event: params.event,\n manifest,\n })\n ? adapter.createOutboundFromRecorderEvent(params)\n : null,\n probe: () =>\n runOpenClawCrablineProviderProbe(manifest.provider, (signal) => adapter.probe(signal)),\n };\n }\n throw new Error(\"Unsupported OpenClaw provider binding.\");\n}\n\nexport function resolveOpenClawCrablineChannel(input?: string | null): CrablineServerChannel {\n const channel =\n input === undefined || input === null\n ? OPENCLAW_CRABLINE_DEFAULT_CHANNEL\n : input.trim().toLowerCase();\n if (isCrablineServerChannel(channel)) {\n return channel;\n }\n throw new Error(\n `--channel must be one of ${CRABLINE_SERVER_CHANNELS.join(\", \")} for --channel-driver crabline, got \"${input}\".`,\n );\n}\n\nexport function resolveOpenClawCrablineChannelDriverSelection(params: {\n channel?: string | null;\n}): OpenClawCrablineChannelDriverSelection & {\n providerReadinessArtifactPath: typeof OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH;\n} {\n return {\n channel: resolveOpenClawCrablineChannel(params.channel),\n channelDriver: \"crabline\",\n capabilityMatrixPath: OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH,\n providerReadinessArtifactPath: OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH,\n smokeArtifactPath: OPENCLAW_CRABLINE_CHANNEL_SMOKE_PATH,\n };\n}\n\nexport async function probeOpenClawCrablineProvider(\n manifest: CrablineServerManifest,\n): Promise<unknown> {\n return await createOpenClawCrablineProviderAdapter(manifest).probe();\n}\n\nexport function createOpenClawCrablineProviderBinding(\n manifest: CrablineServerManifest,\n): OpenClawCrablineGatewayBinding {\n return createOpenClawCrablineProviderAdapter(manifest).createBinding();\n}\n\nexport function createOpenClawCrablineAgentDelivery(params: {\n manifest: CrablineServerManifest;\n target: string;\n}): OpenClawCrablineAgentDelivery {\n return createOpenClawCrablineProviderAdapter(params.manifest).createAgentDelivery(\n parseQaTarget(params.target),\n );\n}\n\nexport function createOpenClawCrablineInbound(params: {\n input: OpenClawCrablineInboundInput;\n manifest: CrablineServerManifest;\n}): OpenClawCrablineInbound {\n return createOpenClawCrablineProviderAdapter(params.manifest).createInbound(params.input);\n}\n\nexport function createOpenClawCrablineOutboundFromRecorderEvent(params: {\n event: unknown;\n manifest: CrablineServerManifest;\n targetByProviderTarget: ReadonlyMap<string, string>;\n}): OpenClawCrablineOutboundMessage | null {\n return createOpenClawCrablineProviderAdapter(params.manifest).createOutboundFromRecorderEvent({\n event: params.event,\n targetByProviderTarget: params.targetByProviderTarget,\n });\n}\n\nexport async function startOpenClawCrablineAdapter(\n params: StartOpenClawCrablineAdapterParams,\n dependencies: {\n createProviderAdapter?: typeof createOpenClawCrablineProviderAdapter;\n startServer?: (params: StartCrablineServerParams) => Promise<StartedCrablineServer>;\n } = {},\n): Promise<StartedOpenClawCrablineAdapter> {\n const server: StartedCrablineServer = await (dependencies.startServer ?? startCrablineServer)({\n channel: params.channel,\n onEvent: params.onEvent,\n recorderPath: params.recorderPath,\n });\n try {\n const providerAdapter = (\n dependencies.createProviderAdapter ?? createOpenClawCrablineProviderAdapter\n )(server.manifest);\n const binding = providerAdapter.createBinding();\n return {\n ...binding,\n close: server.close,\n createGatewayConfig: (openclawConfig = params.openclawConfig ?? {}) =>\n binding.createGatewayConfig(openclawConfig),\n createAgentDelivery: ({ target }) =>\n providerAdapter.createAgentDelivery(parseQaTarget(target)),\n createInbound: ({ input }) => providerAdapter.createInbound(input),\n createOutboundFromRecorderEvent: ({ event, targetByProviderTarget }) =>\n providerAdapter.createOutboundFromRecorderEvent({\n event,\n targetByProviderTarget,\n }),\n manifest: server.manifest,\n probe: () => providerAdapter.probe(),\n };\n } catch (error) {\n try {\n await server.close();\n } catch (closeError) {\n const aggregateError = new AggregateError(\n [error, closeError],\n \"OpenClaw Crabline adapter startup failed.\",\n );\n aggregateError.cause = error;\n throw aggregateError;\n }\n throw error;\n }\n}\n\ntype ProviderReadinessDependencies = {\n acquireLock?: typeof acquireOpenClawCrablineSmokeRunLock;\n publishGeneration?: typeof publishOpenClawCrablineArtifactGeneration;\n releaseLock?: typeof releaseOpenClawCrablineSmokeRunLock;\n startAdapter?: typeof startOpenClawCrablineAdapter;\n};\n\nexport function runOpenClawCrablineProviderReadiness(params: {\n outputDir: string;\n selection: OpenClawCrablineChannelDriverSelection;\n}): Promise<OpenClawCrablineProviderReadinessResult>;\nexport async function runOpenClawCrablineProviderReadiness(\n params: {\n outputDir: string;\n selection: OpenClawCrablineChannelDriverSelection;\n },\n dependencies: ProviderReadinessDependencies = {},\n): Promise<OpenClawCrablineProviderReadinessResult> {\n const outputDir = path.resolve(params.outputDir);\n const releaseLock = dependencies.releaseLock ?? releaseOpenClawCrablineSmokeRunLock;\n const smokeLock = await (dependencies.acquireLock ?? acquireOpenClawCrablineSmokeRunLock)({\n channel: params.selection.channel,\n outputDir,\n });\n let outcome:\n | { committed: false; error: unknown }\n | { committed: true; result: OpenClawCrablineProviderReadinessResult };\n let recorderPath: string | undefined;\n\n try {\n const recorderDirectory = path.join(outputDir, \"artifacts\", \"crabline\");\n await fs.mkdir(recorderDirectory, { recursive: true });\n await reclaimOpenClawCrablineRecorderTemporaries(recorderDirectory, smokeLock);\n recorderPath = path.join(\n recorderDirectory,\n `.${params.selection.channel}-fake-provider.${randomUUID()}.jsonl.tmp`,\n );\n const adapter = await (dependencies.startAdapter ?? startOpenClawCrablineAdapter)({\n channel: params.selection.channel,\n openclawConfig: {},\n recorderPath,\n });\n let probe: unknown;\n let probeFailed = false;\n let probeFailure: unknown;\n try {\n probe = await adapter.probe();\n } catch (error) {\n probeFailed = true;\n probeFailure = error;\n }\n try {\n await adapter.close();\n } catch (cleanupError) {\n if (!probeFailed) {\n throw cleanupError;\n }\n if (probeFailure instanceof Error) {\n const existingCause = probeFailure.cause;\n try {\n Object.defineProperty(probeFailure, \"cause\", {\n configurable: true,\n value:\n existingCause === undefined\n ? cleanupError\n : new AggregateError(\n [existingCause, cleanupError],\n \"OpenClaw Crabline provider probe cleanup also failed.\",\n ),\n });\n } catch {\n // Some provider errors are frozen; preserving the primary failure is authoritative.\n }\n throw probeFailure;\n }\n const combinedError = new Error(\"OpenClaw Crabline provider probe and cleanup both failed.\", {\n cause: cleanupError,\n });\n Object.defineProperty(combinedError, \"errors\", {\n value: [probeFailure, cleanupError],\n });\n throw combinedError;\n }\n if (probeFailed) {\n throw probeFailure;\n }\n let recorderSnapshotContents = \"\";\n try {\n recorderSnapshotContents = await fs.readFile(recorderPath, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n\n const capabilityReport = {\n result: {\n driver: \"crabline\",\n selectedChannel: params.selection.channel,\n supportedChannels: [...CRABLINE_SERVER_CHANNELS],\n },\n };\n const providerReadiness = {\n result: {\n ok: true,\n proof: \"provider-api-probe\",\n ready: true,\n probe,\n provider: adapter.manifest.provider,\n endpoints: adapter.manifest.endpoints,\n recorderPath: path.relative(outputDir, adapter.manifest.recorderPath),\n },\n };\n const generation = await (\n dependencies.publishGeneration ?? publishOpenClawCrablineArtifactGeneration\n )({\n capabilityReport,\n lock: smokeLock,\n manifest: adapter.manifest,\n outputDir,\n recorderSnapshot: {\n contents: recorderSnapshotContents,\n fileName: `${params.selection.channel}-fake-provider.jsonl`,\n },\n selection: params.selection,\n providerReadiness,\n });\n let recorderCleanupWarning: string | undefined;\n try {\n await fs.rm(recorderPath, { force: true });\n recorderPath = undefined;\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n recorderCleanupWarning = `OpenClaw Crabline recorder snapshot committed but temporary cleanup failed: ${detail}`;\n }\n outcome = {\n committed: true,\n result: {\n artifactPointerPath: generation.pointerPath,\n capabilityReport,\n capabilityMatrixPath: generation.capabilityMatrixPath,\n generation: generation.generation,\n manifestPath: generation.manifestPath,\n providerReadiness: generation.providerReadiness,\n providerReadinessArtifactPath: generation.providerReadinessArtifactPath,\n smoke: generation.providerReadiness,\n smokeArtifactPath: generation.providerReadinessArtifactPath,\n ...(generation.warnings || recorderCleanupWarning\n ? {\n warnings: [\n ...(generation.warnings ?? []),\n ...(recorderCleanupWarning ? [recorderCleanupWarning] : []),\n ],\n }\n : {}),\n },\n };\n } catch (error) {\n let primaryError = error;\n if (recorderPath) {\n try {\n await fs.rm(recorderPath, { force: true });\n recorderPath = undefined;\n } catch (cleanupError) {\n if (primaryError instanceof Error) {\n const existingCause = primaryError.cause;\n try {\n Object.defineProperty(primaryError, \"cause\", {\n configurable: true,\n value:\n existingCause === undefined\n ? cleanupError\n : new AggregateError(\n [existingCause, cleanupError],\n \"OpenClaw Crabline readiness failure cleanup also failed.\",\n ),\n });\n } catch {\n // Frozen failures remain authoritative even if temporary cleanup also fails.\n }\n } else {\n const combinedError = new Error(\n \"OpenClaw Crabline readiness and temporary cleanup both failed.\",\n { cause: cleanupError },\n );\n Object.defineProperty(combinedError, \"errors\", {\n value: [primaryError, cleanupError],\n });\n primaryError = combinedError;\n }\n }\n }\n outcome = { committed: false, error: primaryError };\n }\n\n try {\n await releaseLock(smokeLock);\n } catch (cleanupError) {\n // The pointer switch is authoritative; lock removal cannot roll it back.\n if (!outcome.committed) {\n if (outcome.error instanceof Error) {\n const existingCause = outcome.error.cause;\n try {\n Object.defineProperty(outcome.error, \"cause\", {\n configurable: true,\n value:\n existingCause === undefined\n ? cleanupError\n : new AggregateError(\n [existingCause, cleanupError],\n \"OpenClaw Crabline smoke failure cleanup also failed.\",\n ),\n });\n } catch {\n // Some failures are frozen; preserving the primary error is authoritative.\n }\n throw outcome.error;\n }\n const combinedError = new Error(\"OpenClaw Crabline smoke and lock cleanup both failed.\", {\n cause: cleanupError,\n });\n Object.defineProperty(combinedError, \"errors\", {\n value: [outcome.error, cleanupError],\n });\n throw combinedError;\n }\n const detail = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);\n outcome.result = {\n ...outcome.result,\n warnings: [\n ...(outcome.result.warnings ?? []),\n `OpenClaw Crabline smoke committed but lock cleanup failed: ${detail}`,\n ],\n };\n }\n\n if (!outcome.committed) {\n throw outcome.error;\n }\n return outcome.result;\n}\n\n/** @deprecated Use runOpenClawCrablineProviderReadiness. */\nexport const runOpenClawCrablineChannelDriverSmoke = runOpenClawCrablineProviderReadiness;\n\nexport function createOpenClawCrablineChannelReportNotes(\n selection: OpenClawCrablineChannelDriverSelection | null | undefined,\n): string[] {\n if (!selection) {\n return [];\n }\n\n return [\n `Channel driver: ${selection.channelDriver} local provider for ${selection.channel}.`,\n `Channel artifact pointer: ${OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH}.`,\n `Generation capability filename: ${selection.capabilityMatrixPath}.`,\n `Generation provider-readiness filename: ${selection.providerReadinessArtifactPath ?? selection.smokeArtifactPath}.`,\n \"Crabline verifies the local provider API is ready; OpenClaw channel behavior is proven separately by QA scenarios that run the real channel adapter.\",\n ];\n}\n"]}
@@ -189,9 +189,19 @@ function consumeRecordedChunk(state, chunk) {
189
189
  return events;
190
190
  }
191
191
  async function appendJsonLine(filePath, line) {
192
- await serializeAppend(filePath, async (publicationPath, logicalPath) => {
193
- await appendCommittedLine(publicationPath, logicalPath, line, true);
194
- });
192
+ for (let attempt = 0;; attempt++) {
193
+ try {
194
+ await serializeAppend(filePath, async (publicationPath, logicalPath) => {
195
+ await appendCommittedLine(publicationPath, logicalPath, line, true);
196
+ });
197
+ return;
198
+ }
199
+ catch (error) {
200
+ if (!(error instanceof RecorderRotatedError) || attempt + 1 >= RECORDER_ROTATION_ATTEMPTS) {
201
+ throw error;
202
+ }
203
+ }
204
+ }
195
205
  }
196
206
  async function readRecorderFileIdentity(filePath) {
197
207
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../../src/providers/recorder.ts"],"names":[],"mappings":"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","sourcesContent":["import { lstat, mkdir, open, readFile, readlink, realpath } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { lock } from \"proper-lockfile\";\nimport type { InboundEnvelope } from \"./types.js\";\n\nexport type RecordableInboundEnvelope = InboundEnvelope & {\n recordedDirection?: \"inbound\" | \"outbound\";\n};\n\nexport type RecordedInboundEnvelope = RecordableInboundEnvelope & {\n recordedAt: string;\n};\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n const done = () => {\n clearTimeout(timeout);\n signal?.removeEventListener(\"abort\", done);\n resolve();\n };\n const timeout = setTimeout(done, ms);\n signal?.addEventListener(\"abort\", done, { once: true });\n });\n}\n\nconst pendingAppends = new Map<string, Promise<void>>();\nconst recordIdentityIndexes = new Map<string, RecordIdentityIndex>();\nconst MAX_RECORD_IDENTITY_INDEXES = 128;\nconst MAX_RECENT_RECORD_KEYS = 4096;\nconst RECORDER_BATCH_VERSION = 1;\nconst RECORDER_LOCK_STALE_MS = 30_000;\nconst RECORDER_LOCK_UPDATE_MS = 10_000;\nconst RECORDER_ROTATION_ATTEMPTS = 3;\n\nclass RecorderRotatedError extends Error {}\n\ntype IncrementalReadState = {\n caughtUp: boolean;\n continuity: Buffer;\n generation: number;\n identity:\n | {\n dev: number;\n ino: number;\n }\n | undefined;\n offset: number;\n pending: Buffer;\n};\n\ntype RecordIdentityIndex = {\n readState: IncrementalReadState;\n seen: Set<string>;\n};\n\ntype RecorderFileIdentity = {\n dev: bigint;\n ino: bigint;\n};\n\ntype RecordedInboundBatchLine = {\n events: RecordedInboundEnvelope[];\n recordType: \"crabline.recorder.batch\";\n recorderBatchVersion: typeof RECORDER_BATCH_VERSION;\n};\n\nexport type RecordedInboundCursor = {\n buffered: RecordedInboundEnvelope[];\n readState: IncrementalReadState;\n seen: Set<string>;\n};\n\nconst CONTINUITY_BYTES = 4096;\nconst MAX_INCREMENTAL_READ_BYTES = 256 * 1024;\nconst MAX_PENDING_RECORD_BYTES = 4 * 1024 * 1024;\n\nfunction createIncrementalReadState(): IncrementalReadState {\n return {\n caughtUp: true,\n continuity: Buffer.alloc(0),\n generation: 0,\n identity: undefined,\n offset: 0,\n pending: Buffer.alloc(0),\n };\n}\n\nexport function createRecordedInboundCursor(): RecordedInboundCursor {\n return {\n buffered: [],\n readState: createIncrementalReadState(),\n seen: new Set(),\n };\n}\n\nexport function cloneRecordedInboundCursor(cursor: RecordedInboundCursor): RecordedInboundCursor {\n return {\n buffered: [...cursor.buffered],\n readState: {\n caughtUp: cursor.readState.caughtUp,\n continuity: Buffer.from(cursor.readState.continuity),\n generation: cursor.readState.generation,\n identity: cursor.readState.identity ? { ...cursor.readState.identity } : undefined,\n offset: cursor.readState.offset,\n pending: Buffer.from(cursor.readState.pending),\n },\n seen: new Set(cursor.seen),\n };\n}\n\nfunction rememberRecentRecord(seen: Set<string>, event: InboundEnvelope): boolean {\n const key = JSON.stringify([\n event.provider,\n event.threadId,\n event.id,\n recordedDirectionOf(event),\n ]);\n if (seen.has(key)) {\n return false;\n }\n seen.add(key);\n if (seen.size > MAX_RECENT_RECORD_KEYS) {\n seen.delete(seen.values().next().value!);\n }\n return true;\n}\n\nfunction recordedDirectionOf(\n event: Pick<RecordableInboundEnvelope, \"raw\" | \"recordedDirection\">,\n): \"inbound\" | \"outbound\" {\n if (event.recordedDirection) {\n return event.recordedDirection;\n }\n return event.raw !== null &&\n typeof event.raw === \"object\" &&\n \"direction\" in event.raw &&\n event.raw.direction === \"outbound\"\n ? \"outbound\"\n : \"inbound\";\n}\n\nfunction requireNonEmptyString(value: unknown, field: keyof RecordedInboundEnvelope): string {\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(`Recorded inbound envelope ${field} must be a non-empty string.`);\n }\n return value;\n}\n\nfunction requireString(value: unknown, field: keyof RecordedInboundEnvelope): string {\n if (typeof value !== \"string\") {\n throw new Error(`Recorded inbound envelope ${field} must be a string.`);\n }\n return value;\n}\n\nfunction parseRecordedEnvelope(value: unknown): RecordedInboundEnvelope {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(\"Recorded inbound envelope must be an object.\");\n }\n const record = value as Record<string, unknown>;\n if (record.author !== \"assistant\" && record.author !== \"system\" && record.author !== \"user\") {\n throw new Error(\"Recorded inbound envelope author must be assistant, system, or user.\");\n }\n if (\n record.recordedDirection !== undefined &&\n record.recordedDirection !== \"inbound\" &&\n record.recordedDirection !== \"outbound\"\n ) {\n throw new Error(\"Recorded inbound envelope recordedDirection must be inbound or outbound.\");\n }\n return {\n author: record.author,\n id: requireNonEmptyString(record.id, \"id\"),\n provider: requireNonEmptyString(record.provider, \"provider\"),\n ...(record.raw !== undefined ? { raw: record.raw } : {}),\n recordedAt: requireNonEmptyString(record.recordedAt, \"recordedAt\"),\n ...(record.recordedDirection !== undefined\n ? { recordedDirection: record.recordedDirection }\n : {}),\n sentAt: requireNonEmptyString(record.sentAt, \"sentAt\"),\n text: requireString(record.text, \"text\"),\n threadId: requireNonEmptyString(record.threadId, \"threadId\"),\n };\n}\n\nfunction parseRecordedLine(line: string): RecordedInboundEnvelope[] {\n const parsed = JSON.parse(line) as unknown;\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n !Array.isArray(parsed) &&\n \"recordType\" in parsed &&\n parsed.recordType === \"crabline.recorder.batch\" &&\n \"recorderBatchVersion\" in parsed &&\n parsed.recorderBatchVersion === RECORDER_BATCH_VERSION &&\n \"events\" in parsed &&\n Array.isArray(parsed.events)\n ) {\n return parsed.events.map(parseRecordedEnvelope);\n }\n return [parseRecordedEnvelope(parsed)];\n}\n\nfunction resetIncrementalReadState(state: IncrementalReadState): void {\n if (\n state.identity !== undefined ||\n state.offset > 0 ||\n state.pending.length > 0 ||\n state.continuity.length > 0\n ) {\n state.generation += 1;\n }\n state.caughtUp = true;\n state.continuity = Buffer.alloc(0);\n state.offset = 0;\n state.pending = Buffer.alloc(0);\n}\n\nasync function readBufferAt(\n handle: Awaited<ReturnType<typeof open>>,\n length: number,\n position: number,\n): Promise<Buffer> {\n const buffer = Buffer.alloc(length);\n let bytesRead = 0;\n\n while (bytesRead < length) {\n const result = await handle.read(buffer, bytesRead, length - bytesRead, position + bytesRead);\n if (result.bytesRead === 0) {\n break;\n }\n bytesRead += result.bytesRead;\n }\n\n return buffer.subarray(0, bytesRead);\n}\n\nfunction consumeRecordedChunk(\n state: IncrementalReadState,\n chunk: Buffer,\n): RecordedInboundEnvelope[] {\n const continuity = Buffer.concat([state.continuity, chunk]);\n state.continuity = Buffer.from(continuity.subarray(-CONTINUITY_BYTES));\n\n const raw = state.pending.length > 0 ? Buffer.concat([state.pending, chunk]) : chunk;\n const lastNewline = raw.lastIndexOf(0x0a);\n if (lastNewline < 0) {\n if (raw.length > MAX_PENDING_RECORD_BYTES) {\n throw new Error(\n `Recorder record exceeded ${MAX_PENDING_RECORD_BYTES} bytes without a newline.`,\n );\n }\n state.pending = Buffer.from(raw);\n return [];\n }\n\n state.pending = Buffer.from(raw.subarray(lastNewline + 1));\n if (state.pending.length > MAX_PENDING_RECORD_BYTES) {\n throw new Error(\n `Recorder record exceeded ${MAX_PENDING_RECORD_BYTES} bytes without a newline.`,\n );\n }\n\n const events: RecordedInboundEnvelope[] = [];\n for (const line of raw.subarray(0, lastNewline).toString(\"utf8\").split(\"\\n\")) {\n if (line.trim()) {\n events.push(...parseRecordedLine(line));\n }\n }\n return events;\n}\n\nasync function appendJsonLine(filePath: string, line: string): Promise<void> {\n await serializeAppend(filePath, async (publicationPath, logicalPath) => {\n await appendCommittedLine(publicationPath, logicalPath, line, true);\n });\n}\n\nasync function readRecorderFileIdentity(\n filePath: string,\n): Promise<RecorderFileIdentity | undefined> {\n try {\n const stats = await lstat(filePath, { bigint: true });\n if (!stats.isFile()) {\n throw new Error(`Recorder path is not a regular file: ${filePath}`);\n }\n return {\n dev: stats.dev,\n ino: stats.ino,\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction sameRecorderFileIdentity(\n left: RecorderFileIdentity | undefined,\n right: RecorderFileIdentity | undefined,\n): boolean {\n return left?.dev === right?.dev && left?.ino === right?.ino;\n}\n\nasync function resolveRecorderPublicationPath(filePath: string): Promise<string> {\n try {\n return await realpath(filePath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n\n try {\n const stats = await lstat(filePath);\n if (stats.isSymbolicLink()) {\n const target = await readlink(filePath);\n return await resolveRecorderPublicationPath(path.resolve(path.dirname(filePath), target));\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n return path.join(await realpath(path.dirname(filePath)), path.basename(filePath));\n}\n\nasync function prepareRecorderTailForAppend(\n handle: Awaited<ReturnType<typeof open>>,\n): Promise<boolean> {\n const stats = await handle.stat();\n if (stats.size === 0) {\n return false;\n }\n\n const finalByte = await readBufferAt(handle, 1, stats.size - 1);\n if (finalByte[0] === 0x0a) {\n return false;\n }\n\n const windowSize = Math.min(stats.size, MAX_PENDING_RECORD_BYTES + 1);\n const tailWindow = await readBufferAt(handle, windowSize, stats.size - windowSize);\n const lastNewline = tailWindow.lastIndexOf(0x0a);\n if (lastNewline < 0 && stats.size > MAX_PENDING_RECORD_BYTES) {\n throw new Error(\n `Recorder record exceeded ${MAX_PENDING_RECORD_BYTES} bytes without a newline.`,\n );\n }\n\n const tailStart = stats.size - windowSize + lastNewline + 1;\n const tail = tailWindow.subarray(lastNewline + 1).toString(\"utf8\");\n try {\n JSON.parse(tail);\n await handle.writeFile(\"\\n\", \"utf8\");\n return true;\n } catch (error) {\n if (!(error instanceof SyntaxError)) {\n throw error;\n }\n await handle.truncate(tailStart);\n return true;\n }\n}\n\nasync function prepareRecorderPathForAppend(\n publicationPath: string,\n logicalPath: string,\n durable: boolean,\n): Promise<RecorderFileIdentity> {\n const handle = await open(publicationPath, \"a+\");\n const identity = await handle.stat({ bigint: true });\n const recorderIdentity = { dev: identity.dev, ino: identity.ino };\n try {\n const changed = await prepareRecorderTailForAppend(handle);\n if (changed && durable) {\n await handle.sync();\n }\n } finally {\n await handle.close();\n }\n\n if (\n !sameRecorderFileIdentity(\n recorderIdentity,\n await readRecorderFileIdentity(await resolveRecorderPublicationPath(logicalPath)),\n )\n ) {\n throw new RecorderRotatedError(\"Recorder rotated while preparing a committed line.\");\n }\n return recorderIdentity;\n}\n\nasync function appendCommittedLine(\n publicationPath: string,\n logicalPath: string,\n line: string,\n durable: boolean,\n expectedIdentity?: RecorderFileIdentity,\n): Promise<void> {\n const handle = await open(publicationPath, \"a+\");\n const identity = await handle.stat({ bigint: true });\n const recorderIdentity = { dev: identity.dev, ino: identity.ino };\n try {\n if (\n expectedIdentity !== undefined &&\n !sameRecorderFileIdentity(expectedIdentity, recorderIdentity)\n ) {\n throw new RecorderRotatedError(\"Recorder rotated before appending a committed line.\");\n }\n await prepareRecorderTailForAppend(handle);\n await handle.writeFile(line, \"utf8\");\n if (durable) {\n await handle.sync();\n }\n } finally {\n await handle.close();\n }\n\n if (\n !sameRecorderFileIdentity(\n recorderIdentity,\n await readRecorderFileIdentity(await resolveRecorderPublicationPath(logicalPath)),\n )\n ) {\n throw new RecorderRotatedError(\"Recorder rotated while appending a committed line.\");\n }\n}\n\nfunction recorderLockReleaseError(\n filePath: string,\n operationError: unknown,\n releaseError: unknown,\n): AggregateError {\n return new AggregateError(\n [operationError, releaseError],\n `Recorder append and lock release both failed for \"${filePath}\".`,\n { cause: operationError },\n );\n}\n\nasync function withRecorderLock<T>(filePath: string, operation: () => Promise<T>): Promise<T> {\n const release = await lock(filePath, {\n realpath: false,\n retries: {\n factor: 1,\n maxTimeout: 10,\n minTimeout: 10,\n retries: 500,\n },\n stale: RECORDER_LOCK_STALE_MS,\n update: RECORDER_LOCK_UPDATE_MS,\n });\n let operationFailed = false;\n let operationError: unknown;\n let result: T | undefined;\n try {\n result = await operation();\n } catch (error) {\n operationFailed = true;\n operationError = error;\n }\n try {\n await release();\n } catch (releaseError) {\n if (operationFailed) {\n throw recorderLockReleaseError(filePath, operationError, releaseError);\n }\n throw releaseError;\n }\n if (operationFailed) {\n throw operationError;\n }\n return result as T;\n}\n\nasync function serializeAppend<T>(\n filePath: string,\n operation: (publicationPath: string, logicalPath: string) => Promise<T>,\n): Promise<T> {\n const logicalPath = path.resolve(filePath);\n const key = await resolveRecorderPublicationPath(logicalPath);\n const previous = pendingAppends.get(key) ?? Promise.resolve();\n let result: T;\n const current = previous\n .catch(() => {})\n .then(async () => {\n result = await withRecorderLock(key, async () => await operation(key, logicalPath));\n });\n pendingAppends.set(key, current);\n\n try {\n await current;\n return result!;\n } finally {\n if (pendingAppends.get(key) === current) {\n pendingAppends.delete(key);\n }\n }\n}\n\nasync function readRecordedInboundAppend(\n filePath: string,\n state: IncrementalReadState,\n): Promise<RecordedInboundEnvelope[]> {\n let handle;\n\n try {\n handle = await open(filePath, \"r\");\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") {\n resetIncrementalReadState(state);\n state.identity = undefined;\n return [];\n }\n throw error;\n }\n\n try {\n const stats = await handle.stat();\n const identity = { dev: stats.dev, ino: stats.ino };\n const sameFile = state.identity?.dev === identity.dev && state.identity.ino === identity.ino;\n const rotated = state.identity !== undefined && !sameFile;\n let hasContinuity = stats.size >= state.offset;\n\n if (hasContinuity && state.offset > 0 && state.continuity.length === 0) {\n hasContinuity = sameFile;\n } else if (hasContinuity && state.continuity.length > 0) {\n const actual = await readBufferAt(\n handle,\n state.continuity.length,\n state.offset - state.continuity.length,\n );\n hasContinuity = actual.equals(state.continuity);\n }\n\n if (!hasContinuity) {\n resetIncrementalReadState(state);\n } else if (rotated) {\n state.generation += 1;\n }\n state.identity = identity;\n\n const events: RecordedInboundEnvelope[] = [];\n let position = state.offset;\n let remainingBatchBytes = MAX_INCREMENTAL_READ_BYTES;\n let reachedUnexpectedEof = false;\n while (position < stats.size && remainingBatchBytes > 0) {\n const chunk = Buffer.alloc(Math.min(64 * 1024, stats.size - position, remainingBatchBytes));\n const { bytesRead } = await handle.read(chunk, 0, chunk.length, position);\n if (bytesRead === 0) {\n reachedUnexpectedEof = true;\n break;\n }\n position += bytesRead;\n state.offset = position;\n remainingBatchBytes -= bytesRead;\n events.push(...consumeRecordedChunk(state, chunk.subarray(0, bytesRead)));\n }\n state.caughtUp = reachedUnexpectedEof || position >= stats.size;\n return events;\n } finally {\n await handle.close();\n }\n}\n\nexport async function appendRecordedInbound(\n filePath: string,\n event: RecordableInboundEnvelope,\n): Promise<RecordedInboundEnvelope> {\n await mkdir(path.dirname(filePath), { recursive: true });\n\n const recorded = {\n ...event,\n recordedAt: new Date().toISOString(),\n } satisfies RecordedInboundEnvelope;\n\n const line = `${JSON.stringify(recorded)}\\n`;\n if (Buffer.byteLength(line) > MAX_PENDING_RECORD_BYTES) {\n throw new Error(\n `Recorder record exceeded ${MAX_PENDING_RECORD_BYTES} bytes without a newline.`,\n );\n }\n await appendJsonLine(filePath, line);\n return recorded;\n}\n\nexport async function appendRecordedInboundBatch(\n filePath: string,\n events: InboundEnvelope[],\n): Promise<RecordedInboundEnvelope[]> {\n if (events.length === 0) {\n return [];\n }\n await mkdir(path.dirname(filePath), { recursive: true });\n for (let attempt = 0; ; attempt++) {\n try {\n return await serializeAppend(filePath, async (publicationPath, logicalPath) => {\n const generation = await prepareRecorderPathForAppend(publicationPath, logicalPath, true);\n const seen = await syncRecordIdentityIndex(publicationPath);\n const pendingIdentities = new Set<string>();\n const recorded: RecordedInboundEnvelope[] = [];\n for (const event of events) {\n const identity = recordIdentity(event);\n if (seen.has(identity) || pendingIdentities.has(identity)) {\n continue;\n }\n pendingIdentities.add(identity);\n recorded.push({\n ...event,\n recordedAt: new Date().toISOString(),\n });\n }\n if (recorded.length > 0) {\n const batch = {\n events: recorded,\n recordType: \"crabline.recorder.batch\",\n recorderBatchVersion: RECORDER_BATCH_VERSION,\n } satisfies RecordedInboundBatchLine;\n const line = `${JSON.stringify(batch)}\\n`;\n if (Buffer.byteLength(line) > MAX_PENDING_RECORD_BYTES) {\n throw new Error(\n `Recorder record exceeded ${MAX_PENDING_RECORD_BYTES} bytes without a newline.`,\n );\n }\n await appendCommittedLine(publicationPath, logicalPath, line, true, generation);\n await syncRecordIdentityIndex(publicationPath);\n } else if (\n !sameRecorderFileIdentity(\n generation,\n await readRecorderFileIdentity(await resolveRecorderPublicationPath(logicalPath)),\n )\n ) {\n throw new RecorderRotatedError(\"Recorder rotated before confirming a duplicate batch.\");\n }\n return recorded;\n });\n } catch (error) {\n if (!(error instanceof RecorderRotatedError) || attempt + 1 >= RECORDER_ROTATION_ATTEMPTS) {\n throw error;\n }\n }\n }\n}\n\nfunction recordIdentity(event: RecordableInboundEnvelope): string {\n return JSON.stringify([event.provider, event.threadId, event.id, recordedDirectionOf(event)]);\n}\n\nasync function syncRecordIdentityIndex(filePath: string): Promise<Set<string>> {\n const key = path.resolve(filePath);\n let index = recordIdentityIndexes.get(key);\n if (!index) {\n index = { readState: createIncrementalReadState(), seen: new Set() };\n recordIdentityIndexes.set(key, index);\n if (recordIdentityIndexes.size > MAX_RECORD_IDENTITY_INDEXES) {\n recordIdentityIndexes.delete(recordIdentityIndexes.keys().next().value!);\n }\n } else {\n recordIdentityIndexes.delete(key);\n recordIdentityIndexes.set(key, index);\n }\n\n let generation = index.readState.generation;\n do {\n const appended = await readRecordedInboundAppend(filePath, index.readState);\n if (index.readState.generation !== generation) {\n index.seen.clear();\n generation = index.readState.generation;\n }\n for (const event of appended) {\n rememberRecentRecord(index.seen, event);\n }\n } while (!index.readState.caughtUp);\n return index.seen;\n}\n\nexport async function readRecordedInbound(filePath: string): Promise<RecordedInboundEnvelope[]> {\n let raw = \"\";\n\n try {\n raw = await readFile(filePath, \"utf8\");\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") {\n return [];\n }\n throw error;\n }\n\n const lastNewline = raw.lastIndexOf(\"\\n\");\n const completed = lastNewline >= 0 ? raw.slice(0, lastNewline) : \"\";\n const tail = raw.slice(lastNewline + 1);\n const events: RecordedInboundEnvelope[] = [];\n\n for (const line of completed.split(\"\\n\")) {\n if (line.trim()) {\n events.push(...parseRecordedLine(line));\n }\n }\n if (tail.trim()) {\n try {\n events.push(...parseRecordedLine(tail));\n } catch (error) {\n if (!(error instanceof SyntaxError)) {\n throw error;\n }\n // Ignore a syntactically partial final append; completed lines remain strict.\n }\n }\n\n return events;\n}\n\nexport async function waitForRecordedInbound(params: {\n cursor?: RecordedInboundCursor | undefined;\n filePath: string;\n matches: (event: RecordedInboundEnvelope) => boolean;\n pollMs?: number;\n recordedDirection?: \"inbound\" | \"outbound\" | undefined;\n signal?: AbortSignal | undefined;\n since?: string | undefined;\n timeoutMs: number;\n}): Promise<RecordedInboundEnvelope | null> {\n const deadline = Date.now() + params.timeoutMs;\n const cursor = params.cursor ?? createRecordedInboundCursor();\n\n while (!params.signal?.aborted && Date.now() <= deadline) {\n const generation = cursor.readState.generation;\n const events =\n cursor.buffered.length > 0\n ? cursor.buffered.splice(0)\n : await readRecordedInboundAppend(params.filePath, cursor.readState);\n if (cursor.readState.generation !== generation) {\n cursor.seen.clear();\n }\n for (const [index, event] of events.entries()) {\n if (params.recordedDirection && recordedDirectionOf(event) !== params.recordedDirection) {\n continue;\n }\n // Incremental read state owns progress; this bounded window only filters appended retries.\n if (!rememberRecentRecord(cursor.seen, event)) {\n continue;\n }\n if (params.since && new Date(event.sentAt).getTime() < new Date(params.since).getTime()) {\n continue;\n }\n\n if (params.matches(event)) {\n cursor.buffered.push(...events.slice(index + 1));\n return event;\n }\n }\n if (!cursor.readState.caughtUp) {\n if (Date.now() >= deadline) {\n return null;\n }\n continue;\n }\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) {\n return null;\n }\n await sleep(Math.min(params.pollMs ?? 200, remainingMs), params.signal);\n }\n\n return null;\n}\n\nexport async function* watchRecordedInbound(params: {\n filePath: string;\n matches: (event: RecordedInboundEnvelope) => boolean;\n pollMs?: number;\n recordedDirection?: \"inbound\" | \"outbound\" | undefined;\n signal?: AbortSignal | undefined;\n since?: string | undefined;\n}): AsyncIterable<RecordedInboundEnvelope> {\n const state = createIncrementalReadState();\n const seen = new Set<string>();\n\n while (!params.signal?.aborted) {\n const generation = state.generation;\n const events = await readRecordedInboundAppend(params.filePath, state);\n if (state.generation !== generation) {\n seen.clear();\n }\n if (params.signal?.aborted) {\n return;\n }\n for (const event of events) {\n if (params.signal?.aborted) {\n return;\n }\n if (!rememberRecentRecord(seen, event)) {\n continue;\n }\n if (params.recordedDirection && recordedDirectionOf(event) !== params.recordedDirection) {\n continue;\n }\n if (params.since && new Date(event.sentAt).getTime() < new Date(params.since).getTime()) {\n continue;\n }\n\n if (params.matches(event)) {\n yield event;\n }\n }\n if (!state.caughtUp) {\n continue;\n }\n\n await sleep(params.pollMs ?? 250, params.signal);\n }\n}\n"]}
1
+ {"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../../src/providers/recorder.ts"],"names":[],"mappings":"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","sourcesContent":["import { lstat, mkdir, open, readFile, readlink, realpath } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { lock } from \"proper-lockfile\";\nimport type { InboundEnvelope } from \"./types.js\";\n\nexport type RecordableInboundEnvelope = InboundEnvelope & {\n recordedDirection?: \"inbound\" | \"outbound\";\n};\n\nexport type RecordedInboundEnvelope = RecordableInboundEnvelope & {\n recordedAt: string;\n};\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n const done = () => {\n clearTimeout(timeout);\n signal?.removeEventListener(\"abort\", done);\n resolve();\n };\n const timeout = setTimeout(done, ms);\n signal?.addEventListener(\"abort\", done, { once: true });\n });\n}\n\nconst pendingAppends = new Map<string, Promise<void>>();\nconst recordIdentityIndexes = new Map<string, RecordIdentityIndex>();\nconst MAX_RECORD_IDENTITY_INDEXES = 128;\nconst MAX_RECENT_RECORD_KEYS = 4096;\nconst RECORDER_BATCH_VERSION = 1;\nconst RECORDER_LOCK_STALE_MS = 30_000;\nconst RECORDER_LOCK_UPDATE_MS = 10_000;\nconst RECORDER_ROTATION_ATTEMPTS = 3;\n\nclass RecorderRotatedError extends Error {}\n\ntype IncrementalReadState = {\n caughtUp: boolean;\n continuity: Buffer;\n generation: number;\n identity:\n | {\n dev: number;\n ino: number;\n }\n | undefined;\n offset: number;\n pending: Buffer;\n};\n\ntype RecordIdentityIndex = {\n readState: IncrementalReadState;\n seen: Set<string>;\n};\n\ntype RecorderFileIdentity = {\n dev: bigint;\n ino: bigint;\n};\n\ntype RecordedInboundBatchLine = {\n events: RecordedInboundEnvelope[];\n recordType: \"crabline.recorder.batch\";\n recorderBatchVersion: typeof RECORDER_BATCH_VERSION;\n};\n\nexport type RecordedInboundCursor = {\n buffered: RecordedInboundEnvelope[];\n readState: IncrementalReadState;\n seen: Set<string>;\n};\n\nconst CONTINUITY_BYTES = 4096;\nconst MAX_INCREMENTAL_READ_BYTES = 256 * 1024;\nconst MAX_PENDING_RECORD_BYTES = 4 * 1024 * 1024;\n\nfunction createIncrementalReadState(): IncrementalReadState {\n return {\n caughtUp: true,\n continuity: Buffer.alloc(0),\n generation: 0,\n identity: undefined,\n offset: 0,\n pending: Buffer.alloc(0),\n };\n}\n\nexport function createRecordedInboundCursor(): RecordedInboundCursor {\n return {\n buffered: [],\n readState: createIncrementalReadState(),\n seen: new Set(),\n };\n}\n\nexport function cloneRecordedInboundCursor(cursor: RecordedInboundCursor): RecordedInboundCursor {\n return {\n buffered: [...cursor.buffered],\n readState: {\n caughtUp: cursor.readState.caughtUp,\n continuity: Buffer.from(cursor.readState.continuity),\n generation: cursor.readState.generation,\n identity: cursor.readState.identity ? { ...cursor.readState.identity } : undefined,\n offset: cursor.readState.offset,\n pending: Buffer.from(cursor.readState.pending),\n },\n seen: new Set(cursor.seen),\n };\n}\n\nfunction rememberRecentRecord(seen: Set<string>, event: InboundEnvelope): boolean {\n const key = JSON.stringify([\n event.provider,\n event.threadId,\n event.id,\n recordedDirectionOf(event),\n ]);\n if (seen.has(key)) {\n return false;\n }\n seen.add(key);\n if (seen.size > MAX_RECENT_RECORD_KEYS) {\n seen.delete(seen.values().next().value!);\n }\n return true;\n}\n\nfunction recordedDirectionOf(\n event: Pick<RecordableInboundEnvelope, \"raw\" | \"recordedDirection\">,\n): \"inbound\" | \"outbound\" {\n if (event.recordedDirection) {\n return event.recordedDirection;\n }\n return event.raw !== null &&\n typeof event.raw === \"object\" &&\n \"direction\" in event.raw &&\n event.raw.direction === \"outbound\"\n ? \"outbound\"\n : \"inbound\";\n}\n\nfunction requireNonEmptyString(value: unknown, field: keyof RecordedInboundEnvelope): string {\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(`Recorded inbound envelope ${field} must be a non-empty string.`);\n }\n return value;\n}\n\nfunction requireString(value: unknown, field: keyof RecordedInboundEnvelope): string {\n if (typeof value !== \"string\") {\n throw new Error(`Recorded inbound envelope ${field} must be a string.`);\n }\n return value;\n}\n\nfunction parseRecordedEnvelope(value: unknown): RecordedInboundEnvelope {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(\"Recorded inbound envelope must be an object.\");\n }\n const record = value as Record<string, unknown>;\n if (record.author !== \"assistant\" && record.author !== \"system\" && record.author !== \"user\") {\n throw new Error(\"Recorded inbound envelope author must be assistant, system, or user.\");\n }\n if (\n record.recordedDirection !== undefined &&\n record.recordedDirection !== \"inbound\" &&\n record.recordedDirection !== \"outbound\"\n ) {\n throw new Error(\"Recorded inbound envelope recordedDirection must be inbound or outbound.\");\n }\n return {\n author: record.author,\n id: requireNonEmptyString(record.id, \"id\"),\n provider: requireNonEmptyString(record.provider, \"provider\"),\n ...(record.raw !== undefined ? { raw: record.raw } : {}),\n recordedAt: requireNonEmptyString(record.recordedAt, \"recordedAt\"),\n ...(record.recordedDirection !== undefined\n ? { recordedDirection: record.recordedDirection }\n : {}),\n sentAt: requireNonEmptyString(record.sentAt, \"sentAt\"),\n text: requireString(record.text, \"text\"),\n threadId: requireNonEmptyString(record.threadId, \"threadId\"),\n };\n}\n\nfunction parseRecordedLine(line: string): RecordedInboundEnvelope[] {\n const parsed = JSON.parse(line) as unknown;\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n !Array.isArray(parsed) &&\n \"recordType\" in parsed &&\n parsed.recordType === \"crabline.recorder.batch\" &&\n \"recorderBatchVersion\" in parsed &&\n parsed.recorderBatchVersion === RECORDER_BATCH_VERSION &&\n \"events\" in parsed &&\n Array.isArray(parsed.events)\n ) {\n return parsed.events.map(parseRecordedEnvelope);\n }\n return [parseRecordedEnvelope(parsed)];\n}\n\nfunction resetIncrementalReadState(state: IncrementalReadState): void {\n if (\n state.identity !== undefined ||\n state.offset > 0 ||\n state.pending.length > 0 ||\n state.continuity.length > 0\n ) {\n state.generation += 1;\n }\n state.caughtUp = true;\n state.continuity = Buffer.alloc(0);\n state.offset = 0;\n state.pending = Buffer.alloc(0);\n}\n\nasync function readBufferAt(\n handle: Awaited<ReturnType<typeof open>>,\n length: number,\n position: number,\n): Promise<Buffer> {\n const buffer = Buffer.alloc(length);\n let bytesRead = 0;\n\n while (bytesRead < length) {\n const result = await handle.read(buffer, bytesRead, length - bytesRead, position + bytesRead);\n if (result.bytesRead === 0) {\n break;\n }\n bytesRead += result.bytesRead;\n }\n\n return buffer.subarray(0, bytesRead);\n}\n\nfunction consumeRecordedChunk(\n state: IncrementalReadState,\n chunk: Buffer,\n): RecordedInboundEnvelope[] {\n const continuity = Buffer.concat([state.continuity, chunk]);\n state.continuity = Buffer.from(continuity.subarray(-CONTINUITY_BYTES));\n\n const raw = state.pending.length > 0 ? Buffer.concat([state.pending, chunk]) : chunk;\n const lastNewline = raw.lastIndexOf(0x0a);\n if (lastNewline < 0) {\n if (raw.length > MAX_PENDING_RECORD_BYTES) {\n throw new Error(\n `Recorder record exceeded ${MAX_PENDING_RECORD_BYTES} bytes without a newline.`,\n );\n }\n state.pending = Buffer.from(raw);\n return [];\n }\n\n state.pending = Buffer.from(raw.subarray(lastNewline + 1));\n if (state.pending.length > MAX_PENDING_RECORD_BYTES) {\n throw new Error(\n `Recorder record exceeded ${MAX_PENDING_RECORD_BYTES} bytes without a newline.`,\n );\n }\n\n const events: RecordedInboundEnvelope[] = [];\n for (const line of raw.subarray(0, lastNewline).toString(\"utf8\").split(\"\\n\")) {\n if (line.trim()) {\n events.push(...parseRecordedLine(line));\n }\n }\n return events;\n}\n\nasync function appendJsonLine(filePath: string, line: string): Promise<void> {\n for (let attempt = 0; ; attempt++) {\n try {\n await serializeAppend(filePath, async (publicationPath, logicalPath) => {\n await appendCommittedLine(publicationPath, logicalPath, line, true);\n });\n return;\n } catch (error) {\n if (!(error instanceof RecorderRotatedError) || attempt + 1 >= RECORDER_ROTATION_ATTEMPTS) {\n throw error;\n }\n }\n }\n}\n\nasync function readRecorderFileIdentity(\n filePath: string,\n): Promise<RecorderFileIdentity | undefined> {\n try {\n const stats = await lstat(filePath, { bigint: true });\n if (!stats.isFile()) {\n throw new Error(`Recorder path is not a regular file: ${filePath}`);\n }\n return {\n dev: stats.dev,\n ino: stats.ino,\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction sameRecorderFileIdentity(\n left: RecorderFileIdentity | undefined,\n right: RecorderFileIdentity | undefined,\n): boolean {\n return left?.dev === right?.dev && left?.ino === right?.ino;\n}\n\nasync function resolveRecorderPublicationPath(filePath: string): Promise<string> {\n try {\n return await realpath(filePath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n\n try {\n const stats = await lstat(filePath);\n if (stats.isSymbolicLink()) {\n const target = await readlink(filePath);\n return await resolveRecorderPublicationPath(path.resolve(path.dirname(filePath), target));\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n return path.join(await realpath(path.dirname(filePath)), path.basename(filePath));\n}\n\nasync function prepareRecorderTailForAppend(\n handle: Awaited<ReturnType<typeof open>>,\n): Promise<boolean> {\n const stats = await handle.stat();\n if (stats.size === 0) {\n return false;\n }\n\n const finalByte = await readBufferAt(handle, 1, stats.size - 1);\n if (finalByte[0] === 0x0a) {\n return false;\n }\n\n const windowSize = Math.min(stats.size, MAX_PENDING_RECORD_BYTES + 1);\n const tailWindow = await readBufferAt(handle, windowSize, stats.size - windowSize);\n const lastNewline = tailWindow.lastIndexOf(0x0a);\n if (lastNewline < 0 && stats.size > MAX_PENDING_RECORD_BYTES) {\n throw new Error(\n `Recorder record exceeded ${MAX_PENDING_RECORD_BYTES} bytes without a newline.`,\n );\n }\n\n const tailStart = stats.size - windowSize + lastNewline + 1;\n const tail = tailWindow.subarray(lastNewline + 1).toString(\"utf8\");\n try {\n JSON.parse(tail);\n await handle.writeFile(\"\\n\", \"utf8\");\n return true;\n } catch (error) {\n if (!(error instanceof SyntaxError)) {\n throw error;\n }\n await handle.truncate(tailStart);\n return true;\n }\n}\n\nasync function prepareRecorderPathForAppend(\n publicationPath: string,\n logicalPath: string,\n durable: boolean,\n): Promise<RecorderFileIdentity> {\n const handle = await open(publicationPath, \"a+\");\n const identity = await handle.stat({ bigint: true });\n const recorderIdentity = { dev: identity.dev, ino: identity.ino };\n try {\n const changed = await prepareRecorderTailForAppend(handle);\n if (changed && durable) {\n await handle.sync();\n }\n } finally {\n await handle.close();\n }\n\n if (\n !sameRecorderFileIdentity(\n recorderIdentity,\n await readRecorderFileIdentity(await resolveRecorderPublicationPath(logicalPath)),\n )\n ) {\n throw new RecorderRotatedError(\"Recorder rotated while preparing a committed line.\");\n }\n return recorderIdentity;\n}\n\nasync function appendCommittedLine(\n publicationPath: string,\n logicalPath: string,\n line: string,\n durable: boolean,\n expectedIdentity?: RecorderFileIdentity,\n): Promise<void> {\n const handle = await open(publicationPath, \"a+\");\n const identity = await handle.stat({ bigint: true });\n const recorderIdentity = { dev: identity.dev, ino: identity.ino };\n try {\n if (\n expectedIdentity !== undefined &&\n !sameRecorderFileIdentity(expectedIdentity, recorderIdentity)\n ) {\n throw new RecorderRotatedError(\"Recorder rotated before appending a committed line.\");\n }\n await prepareRecorderTailForAppend(handle);\n await handle.writeFile(line, \"utf8\");\n if (durable) {\n await handle.sync();\n }\n } finally {\n await handle.close();\n }\n\n if (\n !sameRecorderFileIdentity(\n recorderIdentity,\n await readRecorderFileIdentity(await resolveRecorderPublicationPath(logicalPath)),\n )\n ) {\n throw new RecorderRotatedError(\"Recorder rotated while appending a committed line.\");\n }\n}\n\nfunction recorderLockReleaseError(\n filePath: string,\n operationError: unknown,\n releaseError: unknown,\n): AggregateError {\n return new AggregateError(\n [operationError, releaseError],\n `Recorder append and lock release both failed for \"${filePath}\".`,\n { cause: operationError },\n );\n}\n\nasync function withRecorderLock<T>(filePath: string, operation: () => Promise<T>): Promise<T> {\n const release = await lock(filePath, {\n realpath: false,\n retries: {\n factor: 1,\n maxTimeout: 10,\n minTimeout: 10,\n retries: 500,\n },\n stale: RECORDER_LOCK_STALE_MS,\n update: RECORDER_LOCK_UPDATE_MS,\n });\n let operationFailed = false;\n let operationError: unknown;\n let result: T | undefined;\n try {\n result = await operation();\n } catch (error) {\n operationFailed = true;\n operationError = error;\n }\n try {\n await release();\n } catch (releaseError) {\n if (operationFailed) {\n throw recorderLockReleaseError(filePath, operationError, releaseError);\n }\n throw releaseError;\n }\n if (operationFailed) {\n throw operationError;\n }\n return result as T;\n}\n\nasync function serializeAppend<T>(\n filePath: string,\n operation: (publicationPath: string, logicalPath: string) => Promise<T>,\n): Promise<T> {\n const logicalPath = path.resolve(filePath);\n const key = await resolveRecorderPublicationPath(logicalPath);\n const previous = pendingAppends.get(key) ?? Promise.resolve();\n let result: T;\n const current = previous\n .catch(() => {})\n .then(async () => {\n result = await withRecorderLock(key, async () => await operation(key, logicalPath));\n });\n pendingAppends.set(key, current);\n\n try {\n await current;\n return result!;\n } finally {\n if (pendingAppends.get(key) === current) {\n pendingAppends.delete(key);\n }\n }\n}\n\nasync function readRecordedInboundAppend(\n filePath: string,\n state: IncrementalReadState,\n): Promise<RecordedInboundEnvelope[]> {\n let handle;\n\n try {\n handle = await open(filePath, \"r\");\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") {\n resetIncrementalReadState(state);\n state.identity = undefined;\n return [];\n }\n throw error;\n }\n\n try {\n const stats = await handle.stat();\n const identity = { dev: stats.dev, ino: stats.ino };\n const sameFile = state.identity?.dev === identity.dev && state.identity.ino === identity.ino;\n const rotated = state.identity !== undefined && !sameFile;\n let hasContinuity = stats.size >= state.offset;\n\n if (hasContinuity && state.offset > 0 && state.continuity.length === 0) {\n hasContinuity = sameFile;\n } else if (hasContinuity && state.continuity.length > 0) {\n const actual = await readBufferAt(\n handle,\n state.continuity.length,\n state.offset - state.continuity.length,\n );\n hasContinuity = actual.equals(state.continuity);\n }\n\n if (!hasContinuity) {\n resetIncrementalReadState(state);\n } else if (rotated) {\n state.generation += 1;\n }\n state.identity = identity;\n\n const events: RecordedInboundEnvelope[] = [];\n let position = state.offset;\n let remainingBatchBytes = MAX_INCREMENTAL_READ_BYTES;\n let reachedUnexpectedEof = false;\n while (position < stats.size && remainingBatchBytes > 0) {\n const chunk = Buffer.alloc(Math.min(64 * 1024, stats.size - position, remainingBatchBytes));\n const { bytesRead } = await handle.read(chunk, 0, chunk.length, position);\n if (bytesRead === 0) {\n reachedUnexpectedEof = true;\n break;\n }\n position += bytesRead;\n state.offset = position;\n remainingBatchBytes -= bytesRead;\n events.push(...consumeRecordedChunk(state, chunk.subarray(0, bytesRead)));\n }\n state.caughtUp = reachedUnexpectedEof || position >= stats.size;\n return events;\n } finally {\n await handle.close();\n }\n}\n\nexport async function appendRecordedInbound(\n filePath: string,\n event: RecordableInboundEnvelope,\n): Promise<RecordedInboundEnvelope> {\n await mkdir(path.dirname(filePath), { recursive: true });\n\n const recorded = {\n ...event,\n recordedAt: new Date().toISOString(),\n } satisfies RecordedInboundEnvelope;\n\n const line = `${JSON.stringify(recorded)}\\n`;\n if (Buffer.byteLength(line) > MAX_PENDING_RECORD_BYTES) {\n throw new Error(\n `Recorder record exceeded ${MAX_PENDING_RECORD_BYTES} bytes without a newline.`,\n );\n }\n await appendJsonLine(filePath, line);\n return recorded;\n}\n\nexport async function appendRecordedInboundBatch(\n filePath: string,\n events: InboundEnvelope[],\n): Promise<RecordedInboundEnvelope[]> {\n if (events.length === 0) {\n return [];\n }\n await mkdir(path.dirname(filePath), { recursive: true });\n for (let attempt = 0; ; attempt++) {\n try {\n return await serializeAppend(filePath, async (publicationPath, logicalPath) => {\n const generation = await prepareRecorderPathForAppend(publicationPath, logicalPath, true);\n const seen = await syncRecordIdentityIndex(publicationPath);\n const pendingIdentities = new Set<string>();\n const recorded: RecordedInboundEnvelope[] = [];\n for (const event of events) {\n const identity = recordIdentity(event);\n if (seen.has(identity) || pendingIdentities.has(identity)) {\n continue;\n }\n pendingIdentities.add(identity);\n recorded.push({\n ...event,\n recordedAt: new Date().toISOString(),\n });\n }\n if (recorded.length > 0) {\n const batch = {\n events: recorded,\n recordType: \"crabline.recorder.batch\",\n recorderBatchVersion: RECORDER_BATCH_VERSION,\n } satisfies RecordedInboundBatchLine;\n const line = `${JSON.stringify(batch)}\\n`;\n if (Buffer.byteLength(line) > MAX_PENDING_RECORD_BYTES) {\n throw new Error(\n `Recorder record exceeded ${MAX_PENDING_RECORD_BYTES} bytes without a newline.`,\n );\n }\n await appendCommittedLine(publicationPath, logicalPath, line, true, generation);\n await syncRecordIdentityIndex(publicationPath);\n } else if (\n !sameRecorderFileIdentity(\n generation,\n await readRecorderFileIdentity(await resolveRecorderPublicationPath(logicalPath)),\n )\n ) {\n throw new RecorderRotatedError(\"Recorder rotated before confirming a duplicate batch.\");\n }\n return recorded;\n });\n } catch (error) {\n if (!(error instanceof RecorderRotatedError) || attempt + 1 >= RECORDER_ROTATION_ATTEMPTS) {\n throw error;\n }\n }\n }\n}\n\nfunction recordIdentity(event: RecordableInboundEnvelope): string {\n return JSON.stringify([event.provider, event.threadId, event.id, recordedDirectionOf(event)]);\n}\n\nasync function syncRecordIdentityIndex(filePath: string): Promise<Set<string>> {\n const key = path.resolve(filePath);\n let index = recordIdentityIndexes.get(key);\n if (!index) {\n index = { readState: createIncrementalReadState(), seen: new Set() };\n recordIdentityIndexes.set(key, index);\n if (recordIdentityIndexes.size > MAX_RECORD_IDENTITY_INDEXES) {\n recordIdentityIndexes.delete(recordIdentityIndexes.keys().next().value!);\n }\n } else {\n recordIdentityIndexes.delete(key);\n recordIdentityIndexes.set(key, index);\n }\n\n let generation = index.readState.generation;\n do {\n const appended = await readRecordedInboundAppend(filePath, index.readState);\n if (index.readState.generation !== generation) {\n index.seen.clear();\n generation = index.readState.generation;\n }\n for (const event of appended) {\n rememberRecentRecord(index.seen, event);\n }\n } while (!index.readState.caughtUp);\n return index.seen;\n}\n\nexport async function readRecordedInbound(filePath: string): Promise<RecordedInboundEnvelope[]> {\n let raw = \"\";\n\n try {\n raw = await readFile(filePath, \"utf8\");\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") {\n return [];\n }\n throw error;\n }\n\n const lastNewline = raw.lastIndexOf(\"\\n\");\n const completed = lastNewline >= 0 ? raw.slice(0, lastNewline) : \"\";\n const tail = raw.slice(lastNewline + 1);\n const events: RecordedInboundEnvelope[] = [];\n\n for (const line of completed.split(\"\\n\")) {\n if (line.trim()) {\n events.push(...parseRecordedLine(line));\n }\n }\n if (tail.trim()) {\n try {\n events.push(...parseRecordedLine(tail));\n } catch (error) {\n if (!(error instanceof SyntaxError)) {\n throw error;\n }\n // Ignore a syntactically partial final append; completed lines remain strict.\n }\n }\n\n return events;\n}\n\nexport async function waitForRecordedInbound(params: {\n cursor?: RecordedInboundCursor | undefined;\n filePath: string;\n matches: (event: RecordedInboundEnvelope) => boolean;\n pollMs?: number;\n recordedDirection?: \"inbound\" | \"outbound\" | undefined;\n signal?: AbortSignal | undefined;\n since?: string | undefined;\n timeoutMs: number;\n}): Promise<RecordedInboundEnvelope | null> {\n const deadline = Date.now() + params.timeoutMs;\n const cursor = params.cursor ?? createRecordedInboundCursor();\n\n while (!params.signal?.aborted && Date.now() <= deadline) {\n const generation = cursor.readState.generation;\n const events =\n cursor.buffered.length > 0\n ? cursor.buffered.splice(0)\n : await readRecordedInboundAppend(params.filePath, cursor.readState);\n if (cursor.readState.generation !== generation) {\n cursor.seen.clear();\n }\n for (const [index, event] of events.entries()) {\n if (params.recordedDirection && recordedDirectionOf(event) !== params.recordedDirection) {\n continue;\n }\n // Incremental read state owns progress; this bounded window only filters appended retries.\n if (!rememberRecentRecord(cursor.seen, event)) {\n continue;\n }\n if (params.since && new Date(event.sentAt).getTime() < new Date(params.since).getTime()) {\n continue;\n }\n\n if (params.matches(event)) {\n cursor.buffered.push(...events.slice(index + 1));\n return event;\n }\n }\n if (!cursor.readState.caughtUp) {\n if (Date.now() >= deadline) {\n return null;\n }\n continue;\n }\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) {\n return null;\n }\n await sleep(Math.min(params.pollMs ?? 200, remainingMs), params.signal);\n }\n\n return null;\n}\n\nexport async function* watchRecordedInbound(params: {\n filePath: string;\n matches: (event: RecordedInboundEnvelope) => boolean;\n pollMs?: number;\n recordedDirection?: \"inbound\" | \"outbound\" | undefined;\n signal?: AbortSignal | undefined;\n since?: string | undefined;\n}): AsyncIterable<RecordedInboundEnvelope> {\n const state = createIncrementalReadState();\n const seen = new Set<string>();\n\n while (!params.signal?.aborted) {\n const generation = state.generation;\n const events = await readRecordedInboundAppend(params.filePath, state);\n if (state.generation !== generation) {\n seen.clear();\n }\n if (params.signal?.aborted) {\n return;\n }\n for (const event of events) {\n if (params.signal?.aborted) {\n return;\n }\n if (!rememberRecentRecord(seen, event)) {\n continue;\n }\n if (params.recordedDirection && recordedDirectionOf(event) !== params.recordedDirection) {\n continue;\n }\n if (params.since && new Date(event.sentAt).getTime() < new Date(params.since).getTime()) {\n continue;\n }\n\n if (params.matches(event)) {\n yield event;\n }\n }\n if (!state.caughtUp) {\n continue;\n }\n\n await sleep(params.pollMs ?? 250, params.signal);\n }\n}\n"]}