grix-connector 3.33.2 → 3.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/dist/adapter/acp/acp-adapter.js +6 -6
  2. package/dist/adapter/agy/agy-adapter.js +9 -9
  3. package/dist/adapter/agy/model-list.js +2 -2
  4. package/dist/adapter/agy/quota.js +5 -5
  5. package/dist/adapter/claude/claude-adapter.js +21 -21
  6. package/dist/adapter/claude/claude-bridge-server.js +1 -0
  7. package/dist/adapter/claude/claude-tools.js +1 -0
  8. package/dist/adapter/claude/claude-worker-client.js +1 -0
  9. package/dist/adapter/claude/mcp-http-launcher.js +2 -0
  10. package/dist/adapter/claude/model-list.js +1 -1
  11. package/dist/adapter/claude/result-timeout.js +1 -0
  12. package/dist/adapter/codewhale/codewhale-adapter.js +2 -2
  13. package/dist/adapter/codewhale/model-list.js +2 -2
  14. package/dist/adapter/codex/codex-bridge.js +9 -9
  15. package/dist/adapter/cursor/cursor-adapter.js +7 -7
  16. package/dist/adapter/cursor/fetch-models.js +2 -2
  17. package/dist/adapter/cursor/resolve-command.js +1 -1
  18. package/dist/adapter/deepseek/deepseek-adapter.js +6 -0
  19. package/dist/adapter/deepseek/index.js +1 -0
  20. package/dist/adapter/deepseek-harness/jsonrpc-adapter.js +2 -2
  21. package/dist/adapter/opencode/opencode-adapter.js +3 -3
  22. package/dist/adapter/openhuman/openhuman-adapter.js +3 -3
  23. package/dist/adapter/qwen/index.js +1 -0
  24. package/dist/adapter/qwen/qwen-adapter.js +4 -0
  25. package/dist/aibot/client.js +1 -0
  26. package/dist/aibot/index.js +1 -0
  27. package/dist/aibot/types.js +0 -0
  28. package/dist/assets/dsh-bridge/{grix-dsh-bridge-3.33.2.tgz → grix-dsh-bridge-3.34.0.tgz} +0 -0
  29. package/dist/assets/dsh-bridge/manifest.json +5 -5
  30. package/dist/audit/adapters/agy/agy-audit-adapter.js +1 -0
  31. package/dist/audit/adapters/openclaw/openclaw-audit-adapter.js +1 -1
  32. package/dist/audit/adapters/pi/pi-transcript-source.js +1 -1
  33. package/dist/audit/core/audit-state.js +1 -1
  34. package/dist/audit/core/transcript-fingerprint.js +1 -0
  35. package/dist/audit/producer/ipc-audit-producer.js +1 -1
  36. package/dist/audit/worker/audit-recorder-worker-entry.js +1 -1
  37. package/dist/bridge/adapter-pool.js +1 -1
  38. package/dist/bridge/bridge.js +9 -9
  39. package/dist/bridge/cli-install-offer.js +1 -0
  40. package/dist/bridge/deferred-events.js +1 -1
  41. package/dist/bridge/lifecycle-barrier.js +1 -0
  42. package/dist/bridge/pending-event-coordinator.js +1 -0
  43. package/dist/bridge/respawn-manager.js +1 -1
  44. package/dist/core/access/allowlist-gate.js +1 -0
  45. package/dist/core/access/allowlist-store.js +1 -0
  46. package/dist/core/access/index.js +1 -0
  47. package/dist/core/aibot/client.js +2 -2
  48. package/dist/core/file-ops/handler.js +1 -0
  49. package/dist/core/file-ops/list-files.js +1 -0
  50. package/dist/core/file-ops/types.js +0 -0
  51. package/dist/core/files/file-serve.js +1 -1
  52. package/dist/core/installer/installer.js +6 -6
  53. package/dist/core/installer/npm-registry.js +3 -3
  54. package/dist/core/installer/prereq-installer.js +1 -1
  55. package/dist/core/observability/sentry.js +1 -1
  56. package/dist/core/persistence/pending-event-store.js +1 -0
  57. package/dist/core/protocol/interaction-parser.js +1 -1
  58. package/dist/core/proxy/hermes-profile-relay.js +1 -1
  59. package/dist/core/proxy/hermes-profile-relay.py +34 -15
  60. package/dist/core/proxy/relay-state-sync.js +1 -1
  61. package/dist/core/runtime/spawn.js +2 -3
  62. package/dist/core/upgrade/npm-upgrader.js +2 -2
  63. package/dist/core/upgrade/upgrade-checker.js +1 -1
  64. package/dist/core/util/cli-probe.js +2 -2
  65. package/dist/core/util/git-project-root.js +1 -1
  66. package/dist/default-skills/grix-agent-dispatch/SKILL.md +19 -9
  67. package/dist/default-skills/grix-egg/SKILL.md +2 -2
  68. package/dist/default-skills/message-send/SKILL.md +1 -1
  69. package/dist/default-skills/message-unsend/SKILL.md +1 -1
  70. package/dist/grix.js +0 -0
  71. package/dist/log.js +3 -0
  72. package/dist/main.js +31 -0
  73. package/dist/manager-share-config.js +1 -1
  74. package/dist/manager.js +2 -2
  75. package/dist/mcp/stream-http/config.js +1 -0
  76. package/dist/mcp/stream-http/connection-binding.js +1 -0
  77. package/dist/mcp/stream-http/event-tool-executor.js +1 -0
  78. package/dist/mcp/stream-http/gateway.js +1 -0
  79. package/dist/mcp/stream-http/index.js +1 -0
  80. package/dist/mcp/stream-http/security.js +1 -0
  81. package/dist/mcp/stream-http/session-manager.js +1 -0
  82. package/dist/mcp/stream-http/tool-executor.js +1 -0
  83. package/dist/mcp/stream-http/tool-registry.js +1 -0
  84. package/dist/mcp/stream-http/tool-schemas.js +1 -0
  85. package/dist/service/process-control.js +1 -1
  86. package/dist/session/index.js +1 -0
  87. package/dist/session/manager.js +1 -0
  88. package/dist/transport/index.js +1 -0
  89. package/dist/transport/json-rpc.js +3 -0
  90. package/openclaw-plugin/audit-recorder-worker.js +531 -76
  91. package/openclaw-plugin/index.js +89 -14
  92. package/package.json +1 -1
@@ -1291,7 +1291,7 @@ function groupMessages(job, evidence, anomalies) {
1291
1291
  });
1292
1292
  continue;
1293
1293
  }
1294
- const timestamp4 = asTimestamp(line.record.timestamp, job.startedAt);
1294
+ const timestamp5 = asTimestamp(line.record.timestamp, job.startedAt);
1295
1295
  let group = groups.get(messageId);
1296
1296
  if (!group) {
1297
1297
  group = {
@@ -1301,14 +1301,14 @@ function groupMessages(job, evidence, anomalies) {
1301
1301
  sourcePath: line.sourcePath,
1302
1302
  isSubagent: line.isSubagent,
1303
1303
  promptId: targetPromptId,
1304
- startedAt: timestamp4,
1305
- endedAt: timestamp4,
1304
+ startedAt: timestamp5,
1305
+ endedAt: timestamp5,
1306
1306
  samples: [],
1307
1307
  blocks: []
1308
1308
  };
1309
1309
  groups.set(messageId, group);
1310
1310
  } else {
1311
- group.endedAt = timestamp4;
1311
+ group.endedAt = timestamp5;
1312
1312
  if (typeof line.record.requestId === "string") {
1313
1313
  group.requestId = line.record.requestId;
1314
1314
  }
@@ -2299,9 +2299,9 @@ function stableHash(value) {
2299
2299
  return (hash >>> 0).toString(16).padStart(8, "0");
2300
2300
  }
2301
2301
  function observedAt(value) {
2302
- const timestamp4 = stringValue2(value);
2303
- if (!timestamp4 || Number.isNaN(Date.parse(timestamp4))) return void 0;
2304
- return timestamp4;
2302
+ const timestamp5 = stringValue2(value);
2303
+ if (!timestamp5 || Number.isNaN(Date.parse(timestamp5))) return void 0;
2304
+ return timestamp5;
2305
2305
  }
2306
2306
  function captureOptions2(job) {
2307
2307
  return job.options?.enabled === true ? job.options.capture : DEFAULT_CAPTURE2;
@@ -2816,7 +2816,7 @@ function toSpan(job, candidate, modelId) {
2816
2816
  if (candidate.snapshotKey) {
2817
2817
  nativeIds2.usageSnapshotId = stableHash(candidate.snapshotKey);
2818
2818
  }
2819
- const timestamp4 = candidate.observedAt ?? job.startedAt;
2819
+ const timestamp5 = candidate.observedAt ?? job.startedAt;
2820
2820
  return {
2821
2821
  spanId: `codex-llm-${stableHash(`${job.traceId}|${nativeRequestId}`)}`,
2822
2822
  traceId: job.traceId,
@@ -2827,8 +2827,8 @@ function toSpan(job, candidate, modelId) {
2827
2827
  name: "codex response",
2828
2828
  sequence: candidate.sequence,
2829
2829
  status: "completed",
2830
- startedAt: timestamp4,
2831
- endedAt: timestamp4,
2830
+ startedAt: timestamp5,
2831
+ endedAt: timestamp5,
2832
2832
  ...modelId ? { modelId } : {},
2833
2833
  inputRefs: [],
2834
2834
  outputRefs: [],
@@ -3560,13 +3560,60 @@ var CodexAuditAdapter = class {
3560
3560
  };
3561
3561
 
3562
3562
  // src/audit/adapters/pi/pi-transcript-source.ts
3563
- import { open as open3, stat as stat4 } from "node:fs/promises";
3563
+ import { open as open3 } from "node:fs/promises";
3564
+
3565
+ // src/audit/core/transcript-fingerprint.ts
3566
+ import { createHash as createHash3 } from "node:crypto";
3567
+ var READ_CHUNK_BYTES = 64 * 1024;
3568
+ async function readAndHashFilePrefixRange(handle, start, end) {
3569
+ if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start < 0 || end < start) {
3570
+ throw new Error("Transcript range must contain safe non-negative offsets");
3571
+ }
3572
+ const digest = createHash3("sha256").update(String(end)).update("\0");
3573
+ const output = Buffer.allocUnsafe(end - start);
3574
+ const chunk = Buffer.allocUnsafe(Math.min(READ_CHUNK_BYTES, Math.max(1, end)));
3575
+ let position = 0;
3576
+ while (position < end) {
3577
+ const requested = Math.min(chunk.length, end - position);
3578
+ const { bytesRead } = await handle.read(chunk, 0, requested, position);
3579
+ if (bytesRead === 0) {
3580
+ throw new Error(`Transcript ended before prefix offset ${end}`);
3581
+ }
3582
+ const value = chunk.subarray(0, bytesRead);
3583
+ digest.update(value);
3584
+ const overlapStart = Math.max(position, start);
3585
+ const overlapEnd = Math.min(position + bytesRead, end);
3586
+ if (overlapStart < overlapEnd) {
3587
+ value.copy(
3588
+ output,
3589
+ overlapStart - start,
3590
+ overlapStart - position,
3591
+ overlapEnd - position
3592
+ );
3593
+ }
3594
+ position += bytesRead;
3595
+ }
3596
+ return { buffer: output, fingerprint: digest.digest("hex") };
3597
+ }
3598
+
3599
+ // src/audit/adapters/pi/pi-transcript-source.ts
3564
3600
  function isRecord4(value) {
3565
3601
  return typeof value === "object" && value !== null && !Array.isArray(value);
3566
3602
  }
3567
3603
  function finiteOffset3(value, fallback) {
3568
3604
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : fallback;
3569
3605
  }
3606
+ function recordIntegrityFailure(evidence, transcriptPath, detail) {
3607
+ evidence.anomalies.push({
3608
+ code: "pi_transcript_source_changed",
3609
+ message: `${transcriptPath}: ${detail}`
3610
+ });
3611
+ evidence.gaps.push({
3612
+ category: "main_transcript",
3613
+ reason: "correlation_failed",
3614
+ detail: `${transcriptPath}: ${detail}`
3615
+ });
3616
+ }
3570
3617
  async function collectPiTranscript(boundary) {
3571
3618
  const transcriptPath = typeof boundary.transcriptPath === "string" ? boundary.transcriptPath : void 0;
3572
3619
  if (!transcriptPath) {
@@ -3591,31 +3638,57 @@ async function collectPiTranscript(boundary) {
3591
3638
  sourcePaths: [transcriptPath]
3592
3639
  };
3593
3640
  try {
3594
- const sourceStat = await stat4(transcriptPath);
3595
- const requestedStart = finiteOffset3(boundary.transcriptStartOffset, 0);
3596
- const requestedEnd = typeof boundary.transcriptEndOffset === "number" ? finiteOffset3(boundary.transcriptEndOffset, sourceStat.size) : sourceStat.size;
3597
- if (requestedStart > sourceStat.size) {
3598
- evidence.anomalies.push({
3599
- code: "pi_transcript_boundary_out_of_range",
3600
- message: `${transcriptPath}: start ${requestedStart} exceeds size ${sourceStat.size}`
3601
- });
3602
- evidence.gaps.push({
3603
- category: "main_transcript",
3604
- reason: "correlation_failed",
3605
- detail: `${transcriptPath}:${requestedStart}-${requestedEnd}`
3606
- });
3607
- return evidence;
3608
- }
3609
- const start = requestedStart;
3610
- const end = Math.min(Math.max(requestedEnd, start), sourceStat.size);
3611
- const length = end - start;
3612
- if (length === 0) return evidence;
3613
3641
  const handle = await open3(transcriptPath, "r");
3614
3642
  let buffer;
3643
+ let start;
3615
3644
  try {
3616
- buffer = Buffer.allocUnsafe(length);
3617
- const { bytesRead } = await handle.read(buffer, 0, length, start);
3618
- buffer = buffer.subarray(0, bytesRead);
3645
+ const sourceStat = await handle.stat();
3646
+ const requestedStart = finiteOffset3(boundary.transcriptStartOffset, 0);
3647
+ const requestedEnd = typeof boundary.transcriptEndOffset === "number" ? finiteOffset3(boundary.transcriptEndOffset, sourceStat.size) : sourceStat.size;
3648
+ if (requestedStart > sourceStat.size || requestedEnd > sourceStat.size) {
3649
+ evidence.anomalies.push({
3650
+ code: "pi_transcript_boundary_out_of_range",
3651
+ message: `${transcriptPath}: boundary ${requestedStart}-${requestedEnd} exceeds size ${sourceStat.size}`
3652
+ });
3653
+ evidence.gaps.push({
3654
+ category: "main_transcript",
3655
+ reason: "correlation_failed",
3656
+ detail: `${transcriptPath}:${requestedStart}-${requestedEnd}`
3657
+ });
3658
+ return evidence;
3659
+ }
3660
+ const expectedIdentity = typeof boundary.transcriptFileIdentity === "string" ? boundary.transcriptFileIdentity : void 0;
3661
+ const actualIdentity = `${sourceStat.dev}:${sourceStat.ino}`;
3662
+ if (expectedIdentity && actualIdentity !== expectedIdentity) {
3663
+ recordIntegrityFailure(
3664
+ evidence,
3665
+ transcriptPath,
3666
+ `identity ${actualIdentity} does not match ${expectedIdentity}`
3667
+ );
3668
+ return evidence;
3669
+ }
3670
+ const expectedFingerprint = typeof boundary.transcriptPrefixFingerprint === "string" ? boundary.transcriptPrefixFingerprint : void 0;
3671
+ start = requestedStart;
3672
+ const end = Math.max(requestedEnd, start);
3673
+ const length = end - start;
3674
+ if (expectedFingerprint) {
3675
+ const verified = await readAndHashFilePrefixRange(handle, start, end);
3676
+ if (verified.fingerprint !== expectedFingerprint) {
3677
+ recordIntegrityFailure(
3678
+ evidence,
3679
+ transcriptPath,
3680
+ "closed transcript prefix fingerprint changed"
3681
+ );
3682
+ return evidence;
3683
+ }
3684
+ buffer = verified.buffer;
3685
+ } else {
3686
+ if (length === 0) return evidence;
3687
+ buffer = Buffer.allocUnsafe(length);
3688
+ const { bytesRead } = await handle.read(buffer, 0, length, start);
3689
+ buffer = buffer.subarray(0, bytesRead);
3690
+ }
3691
+ if (length === 0) return evidence;
3619
3692
  } finally {
3620
3693
  await handle.close();
3621
3694
  }
@@ -4273,7 +4346,7 @@ var PiAuditAdapter = class {
4273
4346
  };
4274
4347
 
4275
4348
  // src/audit/adapters/acp/generic-acp-audit-adapter.ts
4276
- import { readFile as readFile3, readdir as readdir2, stat as stat5 } from "node:fs/promises";
4349
+ import { readFile as readFile3, readdir as readdir2, stat as stat4 } from "node:fs/promises";
4277
4350
  import { homedir } from "node:os";
4278
4351
  import { basename as basename4, join as join2 } from "node:path";
4279
4352
  var DEFAULT_CAPTURE4 = Object.freeze({
@@ -4305,9 +4378,9 @@ function eventTime(value) {
4305
4378
  }
4306
4379
  return void 0;
4307
4380
  }
4308
- function withinTurn(timestamp4, job) {
4309
- if (!timestamp4) return false;
4310
- const at = Date.parse(timestamp4);
4381
+ function withinTurn(timestamp5, job) {
4382
+ if (!timestamp5) return false;
4383
+ const at = Date.parse(timestamp5);
4311
4384
  return at >= Date.parse(job.startedAt) - 5e3 && at <= Date.parse(job.endedAt) + 3e4;
4312
4385
  }
4313
4386
  function contentText2(value) {
@@ -4364,7 +4437,7 @@ async function collectQwenUsage(job, providerSessionId, cwd) {
4364
4437
  `${providerSessionId}.jsonl`
4365
4438
  );
4366
4439
  try {
4367
- await stat5(sourcePath);
4440
+ await stat4(sourcePath);
4368
4441
  } catch {
4369
4442
  return { records: [] };
4370
4443
  }
@@ -4413,7 +4486,7 @@ async function locateGeminiSession(providerSessionId, cwd) {
4413
4486
  const candidates = names.filter((name) => name.startsWith("session-") && name.includes(shortId) && (name.endsWith(".json") || name.endsWith(".jsonl")));
4414
4487
  const ranked = await Promise.all(candidates.map(async (name) => {
4415
4488
  const sourcePath = join2(chats, name);
4416
- return { sourcePath, modifiedAt: (await stat5(sourcePath)).mtimeMs };
4489
+ return { sourcePath, modifiedAt: (await stat4(sourcePath)).mtimeMs };
4417
4490
  }));
4418
4491
  return ranked.sort((left, right) => right.modifiedAt - left.modifiedAt)[0]?.sourcePath;
4419
4492
  } catch {
@@ -4895,7 +4968,7 @@ var GenericAcpAuditAdapter = class {
4895
4968
  };
4896
4969
 
4897
4970
  // src/audit/adapters/acp/kimi-audit-adapter.ts
4898
- import { readFile as readFile4, readdir as readdir3, stat as stat6 } from "node:fs/promises";
4971
+ import { readFile as readFile4, readdir as readdir3, stat as stat5 } from "node:fs/promises";
4899
4972
  import { homedir as homedir2 } from "node:os";
4900
4973
  import { basename as basename5, dirname, join as join3 } from "node:path";
4901
4974
  var DEFAULT_CAPTURE5 = Object.freeze({
@@ -4950,8 +5023,8 @@ function lineEvent(line) {
4950
5023
  return line.record.type === "context.append_loop_event" && isRecord7(line.record.event) ? line.record.event : void 0;
4951
5024
  }
4952
5025
  function withinTurn2(value, job) {
4953
- const timestamp4 = Date.parse(isoTime(value, ""));
4954
- return Number.isFinite(timestamp4) && timestamp4 >= Date.parse(job.startedAt) - 5e3 && timestamp4 <= Date.parse(job.endedAt) + 3e4;
5026
+ const timestamp5 = Date.parse(isoTime(value, ""));
5027
+ return Number.isFinite(timestamp5) && timestamp5 >= Date.parse(job.startedAt) - 5e3 && timestamp5 <= Date.parse(job.endedAt) + 3e4;
4955
5028
  }
4956
5029
  async function readJsonl2(sourcePath) {
4957
5030
  const raw = await readFile4(sourcePath, "utf8");
@@ -5027,7 +5100,7 @@ async function locateSessionDirectory(job) {
5027
5100
  const path = join3(root, workspace.name, providerSessionId);
5028
5101
  const wirePath = join3(path, "agents", "main", "wire.jsonl");
5029
5102
  try {
5030
- const wireStat = await stat6(wirePath);
5103
+ const wireStat = await stat5(wirePath);
5031
5104
  let cwdMatches = false;
5032
5105
  const cwd = stringValue5(job.boundary.cwd);
5033
5106
  if (cwd) {
@@ -5868,7 +5941,7 @@ var KimiAuditAdapter = class {
5868
5941
  };
5869
5942
 
5870
5943
  // src/audit/adapters/acp/reasonix-transcript-source.ts
5871
- import { open as open4, stat as stat7 } from "node:fs/promises";
5944
+ import { open as open4, stat as stat6 } from "node:fs/promises";
5872
5945
  function isRecord8(value) {
5873
5946
  return typeof value === "object" && value !== null && !Array.isArray(value);
5874
5947
  }
@@ -5921,7 +5994,7 @@ async function collectReasonixTranscript(boundary) {
5921
5994
  return evidence;
5922
5995
  }
5923
5996
  try {
5924
- const sourceStat = await stat7(transcriptPath);
5997
+ const sourceStat = await stat6(transcriptPath);
5925
5998
  const requestedStart = finiteOffset4(boundary.transcriptStartOffset, 0);
5926
5999
  const requestedEnd = typeof boundary.transcriptEndOffset === "number" ? finiteOffset4(boundary.transcriptEndOffset, sourceStat.size) : sourceStat.size;
5927
6000
  if (requestedStart > sourceStat.size) {
@@ -7986,7 +8059,7 @@ var DeepSeekHarnessAuditAdapter = class {
7986
8059
  const mapped = mapDshSessionEvent(event);
7987
8060
  const eventSessionId = String(event.sessionId ?? "");
7988
8061
  const isChild = !!eventSessionId && !!rootSessionId && eventSessionId !== rootSessionId;
7989
- const timestamp4 = iso(record4.at, job.startedAt);
8062
+ const timestamp5 = iso(record4.at, job.startedAt);
7990
8063
  if (mapped.kind === "thinking") {
7991
8064
  if (capture.thinking && mapped.text) {
7992
8065
  addContent10(contents, { role: "thinking", format: "text", value: mapped.text, captureLevel: "runtime_exact" });
@@ -8061,9 +8134,9 @@ var DeepSeekHarnessAuditAdapter = class {
8061
8134
  continue;
8062
8135
  }
8063
8136
  tool.span.status = mapped.isError ? "failed" : "completed";
8064
- tool.span.endedAt = timestamp4;
8137
+ tool.span.endedAt = timestamp5;
8065
8138
  const startMs = Date.parse(tool.span.startedAt);
8066
- const endMs = Date.parse(timestamp4);
8139
+ const endMs = Date.parse(timestamp5);
8067
8140
  if (Number.isFinite(startMs) && Number.isFinite(endMs)) {
8068
8141
  tool.span.durationMs = Math.max(0, endMs - startMs);
8069
8142
  }
@@ -8161,7 +8234,7 @@ function turnSpan(job, spanId) {
8161
8234
  };
8162
8235
  }
8163
8236
  function simpleSpan(job, parentSpanId, sequence, kind, name, at, nativeIds2) {
8164
- const timestamp4 = iso(at, job.startedAt);
8237
+ const timestamp5 = iso(at, job.startedAt);
8165
8238
  return {
8166
8239
  spanId: `deepseek-harness:${job.turnId}:${sequence}`,
8167
8240
  traceId: job.traceId,
@@ -8172,8 +8245,8 @@ function simpleSpan(job, parentSpanId, sequence, kind, name, at, nativeIds2) {
8172
8245
  name,
8173
8246
  sequence,
8174
8247
  status: "completed",
8175
- startedAt: timestamp4,
8176
- endedAt: timestamp4,
8248
+ startedAt: timestamp5,
8249
+ endedAt: timestamp5,
8177
8250
  inputRefs: [],
8178
8251
  outputRefs: [],
8179
8252
  provider: { provider: "deepseek-harness", nativeEventType: name, nativeIds: nativeIds2 },
@@ -8231,31 +8304,412 @@ function usageSpan(job, parentSpanId, sequence, at, raw, requestId2, modelId, pr
8231
8304
  return span2;
8232
8305
  }
8233
8306
 
8234
- // src/audit/adapters/openclaw/openclaw-audit-adapter.ts
8307
+ // src/audit/adapters/agy/agy-audit-adapter.ts
8235
8308
  import { readFile as readFile5 } from "node:fs/promises";
8236
- import { dirname as dirname2, join as join4 } from "node:path";
8309
+ var DEFAULT_CAPTURE11 = Object.freeze({
8310
+ inputOutput: true,
8311
+ tools: true,
8312
+ subagents: false,
8313
+ thinking: true,
8314
+ rawProviderBody: false
8315
+ });
8316
+ var AGY_LOG_EXCERPT_MAX_CHARS = 256e3;
8237
8317
  function isRecord14(value) {
8238
8318
  return typeof value === "object" && value !== null && !Array.isArray(value);
8239
8319
  }
8240
- async function resolveTranscriptBoundary(boundary) {
8241
- if (typeof boundary.transcriptPath === "string") return boundary;
8320
+ function stringValue10(value) {
8321
+ return typeof value === "string" && value.length > 0 ? value : void 0;
8322
+ }
8323
+ function offsetValue(value) {
8324
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
8325
+ }
8326
+ function captureOptions11(job) {
8327
+ return job.options?.enabled === true ? job.options.capture : DEFAULT_CAPTURE11;
8328
+ }
8329
+ function addContent11(contents, seen, content) {
8330
+ const key = [content.role, content.value ?? ""].join("\0");
8331
+ if (seen.has(key)) return seen.get(key);
8332
+ const reference = referenceCaptureContent(content);
8333
+ seen.set(key, reference);
8334
+ contents.push(content);
8335
+ return reference;
8336
+ }
8337
+ function append5(target, reference) {
8338
+ if (reference && !target.some((item) => item.contentId === reference.contentId)) {
8339
+ target.push(reference);
8340
+ }
8341
+ }
8342
+ function timestamp4(value, fallback) {
8343
+ return typeof value === "string" && Number.isFinite(Date.parse(value)) ? value : fallback;
8344
+ }
8345
+ function makeSpan8(input) {
8346
+ const startedAt = input.startedAt ?? input.job.startedAt;
8347
+ const endedAt = input.endedAt ?? input.job.endedAt;
8348
+ const startMs = Date.parse(startedAt);
8349
+ const endMs = Date.parse(endedAt);
8350
+ return {
8351
+ spanId: input.spanId,
8352
+ traceId: input.job.traceId,
8353
+ turnId: input.job.turnId,
8354
+ sessionId: input.job.sessionId,
8355
+ ...input.parentSpanId ? { parentSpanId: input.parentSpanId } : {},
8356
+ kind: input.kind,
8357
+ name: input.name,
8358
+ sequence: input.sequence,
8359
+ status: input.status ?? "completed",
8360
+ startedAt,
8361
+ endedAt,
8362
+ ...Number.isFinite(startMs) && Number.isFinite(endMs) ? { durationMs: Math.max(0, endMs - startMs) } : {},
8363
+ inputRefs: [],
8364
+ outputRefs: [],
8365
+ provider: {
8366
+ provider: "agy",
8367
+ nativeEventType: input.nativeEventType,
8368
+ nativeIds: Object.fromEntries(
8369
+ Object.entries(input.nativeIds ?? {}).filter(
8370
+ (entry) => typeof entry[1] === "string"
8371
+ )
8372
+ ),
8373
+ ...input.rawAttributes ? { rawAttributes: input.rawAttributes } : {}
8374
+ },
8375
+ provenance: {
8376
+ source: "connector",
8377
+ accuracy: "runtime_exact"
8378
+ }
8379
+ };
8380
+ }
8381
+ function parseToolInvocation(value) {
8382
+ if (!isRecord14(value) || typeof value.sequence !== "number" || typeof value.observedAt !== "string" || typeof value.action !== "string") {
8383
+ return void 0;
8384
+ }
8385
+ return {
8386
+ sequence: value.sequence,
8387
+ observedAt: value.observedAt,
8388
+ action: value.action,
8389
+ ...value.params === void 0 ? {} : { params: value.params },
8390
+ ...value.result === void 0 ? {} : { result: value.result },
8391
+ ...typeof value.error === "string" ? { error: value.error } : {},
8392
+ ...typeof value.completedAt === "string" ? { completedAt: value.completedAt } : {}
8393
+ };
8394
+ }
8395
+ var AgyAuditAdapter = class {
8396
+ provider = "agy";
8397
+ async collect(job) {
8398
+ const evidence = {
8399
+ toolInvocations: [],
8400
+ anomalies: [],
8401
+ gaps: []
8402
+ };
8403
+ const bundle = isRecord14(job.boundary.agyEvidence) ? job.boundary.agyEvidence : void 0;
8404
+ if (!bundle) {
8405
+ evidence.gaps.push({
8406
+ category: "agy_evidence",
8407
+ reason: "source_log_missing",
8408
+ detail: "boundary.agyEvidence is missing"
8409
+ });
8410
+ } else {
8411
+ const prompt = stringValue10(bundle.prompt);
8412
+ if (prompt !== void 0) evidence.prompt = prompt;
8413
+ const stdout = stringValue10(bundle.stdout);
8414
+ if (stdout !== void 0) evidence.stdout = stdout;
8415
+ const stderr = stringValue10(bundle.stderr);
8416
+ if (stderr !== void 0) evidence.stderr = stderr;
8417
+ if (typeof bundle.exitCode === "number" || bundle.exitCode === null) {
8418
+ evidence.exitCode = bundle.exitCode;
8419
+ }
8420
+ const response = stringValue10(bundle.response);
8421
+ if (response !== void 0) evidence.response = response;
8422
+ if (Array.isArray(bundle.toolInvocations)) {
8423
+ for (const value of bundle.toolInvocations) {
8424
+ const invocation = parseToolInvocation(value);
8425
+ if (!invocation) {
8426
+ evidence.anomalies.push({
8427
+ code: "agy_tool_invocation_malformed",
8428
+ message: "agy tool invocation row is malformed"
8429
+ });
8430
+ evidence.gaps.push({
8431
+ category: "agy_tool_invocation",
8432
+ reason: "correlation_failed"
8433
+ });
8434
+ continue;
8435
+ }
8436
+ evidence.toolInvocations.push(invocation);
8437
+ }
8438
+ evidence.toolInvocations.sort(
8439
+ (left, right) => left.sequence - right.sequence
8440
+ );
8441
+ }
8442
+ }
8443
+ const logPath = stringValue10(job.boundary.transcriptPath);
8444
+ const logStart = offsetValue(job.boundary.transcriptStartOffset);
8445
+ const logEnd = offsetValue(job.boundary.transcriptEndOffset);
8446
+ if (logPath) {
8447
+ evidence.logPath = logPath;
8448
+ try {
8449
+ const raw = await readFile5(logPath);
8450
+ const start = logStart !== void 0 && logStart <= raw.length ? logStart : 0;
8451
+ const end = logEnd !== void 0 && logEnd >= start && logEnd <= raw.length ? logEnd : raw.length;
8452
+ evidence.logStartOffset = start;
8453
+ evidence.logEndOffset = end;
8454
+ const excerpt = raw.subarray(start, end).toString("utf-8");
8455
+ evidence.logExcerpt = excerpt.length > AGY_LOG_EXCERPT_MAX_CHARS ? excerpt.slice(0, AGY_LOG_EXCERPT_MAX_CHARS) : excerpt;
8456
+ } catch (error) {
8457
+ evidence.anomalies.push({
8458
+ code: "agy_log_unreadable",
8459
+ message: error instanceof Error ? error.message : String(error)
8460
+ });
8461
+ evidence.gaps.push({
8462
+ category: "agy_log",
8463
+ reason: "source_log_missing",
8464
+ detail: logPath
8465
+ });
8466
+ }
8467
+ }
8468
+ return evidence;
8469
+ }
8470
+ async normalize(job, rawEvidence) {
8471
+ const collection = rawEvidence;
8472
+ const capture = captureOptions11(job);
8473
+ const spans = [];
8474
+ const contents = [];
8475
+ const seen = /* @__PURE__ */ new Map();
8476
+ let sequence = 0;
8477
+ const turnSpanId = `agy:${job.turnId}:turn`;
8478
+ const turn = makeSpan8({
8479
+ job,
8480
+ spanId: turnSpanId,
8481
+ kind: "turn",
8482
+ name: "agy audited turn",
8483
+ sequence: sequence++,
8484
+ status: job.outcome === "completed" ? "completed" : job.outcome === "cancelled" ? "cancelled" : "failed",
8485
+ nativeEventType: "print_turn",
8486
+ nativeIds: {
8487
+ providerSessionId: stringValue10(job.boundary.providerSessionId)
8488
+ }
8489
+ });
8490
+ spans.push(turn);
8491
+ const runtimeInput = capture.inputOutput && job.input ? addContent11(contents, seen, {
8492
+ ...job.input,
8493
+ captureLevel: job.input.captureLevel ?? "runtime_exact"
8494
+ }) : void 0;
8495
+ append5(turn.inputRefs, runtimeInput);
8496
+ if (capture.inputOutput && job.finalOutput) {
8497
+ append5(turn.outputRefs, addContent11(contents, seen, {
8498
+ ...job.finalOutput,
8499
+ captureLevel: job.finalOutput.captureLevel ?? "runtime_exact"
8500
+ }));
8501
+ }
8502
+ const request = makeSpan8({
8503
+ job,
8504
+ spanId: `agy:${job.sessionId}:request:${job.turnId}`,
8505
+ parentSpanId: turnSpanId,
8506
+ kind: "llm_request",
8507
+ name: "agy print request",
8508
+ sequence: sequence++,
8509
+ status: job.outcome === "completed" ? "completed" : "failed",
8510
+ nativeEventType: "print_process",
8511
+ nativeIds: {
8512
+ providerSessionId: stringValue10(job.boundary.providerSessionId)
8513
+ },
8514
+ rawAttributes: {
8515
+ ...collection.exitCode === void 0 ? {} : { exitCode: collection.exitCode },
8516
+ ...collection.logPath ? { logPath: collection.logPath } : {},
8517
+ ...collection.logStartOffset === void 0 ? {} : { logStartOffset: collection.logStartOffset },
8518
+ ...collection.logEndOffset === void 0 ? {} : { logEndOffset: collection.logEndOffset },
8519
+ ...collection.stderr ? { stderr: collection.stderr.slice(0, 2e3) } : {}
8520
+ }
8521
+ });
8522
+ append5(request.inputRefs, runtimeInput);
8523
+ if (capture.inputOutput && collection.prompt) {
8524
+ append5(request.inputRefs, addContent11(contents, seen, {
8525
+ role: "model_request",
8526
+ format: "text",
8527
+ value: collection.prompt,
8528
+ captureLevel: "provider_exact"
8529
+ }));
8530
+ }
8531
+ const outputText2 = collection.response ?? collection.stdout;
8532
+ if (capture.inputOutput && outputText2) {
8533
+ append5(request.outputRefs, addContent11(contents, seen, {
8534
+ role: "assistant_text",
8535
+ format: "text",
8536
+ value: outputText2,
8537
+ captureLevel: "provider_exact"
8538
+ }));
8539
+ }
8540
+ if (capture.rawProviderBody && collection.logExcerpt) {
8541
+ append5(request.outputRefs, addContent11(contents, seen, {
8542
+ role: "model_response",
8543
+ format: "text",
8544
+ value: collection.logExcerpt,
8545
+ sourcePath: collection.logPath,
8546
+ sourceOffset: collection.logStartOffset,
8547
+ captureLevel: "provider_exact"
8548
+ }));
8549
+ }
8550
+ spans.push(request);
8551
+ if (capture.tools) {
8552
+ for (const invocation of collection.toolInvocations) {
8553
+ const tool = makeSpan8({
8554
+ job,
8555
+ spanId: `agy:${job.sessionId}:tool:${invocation.sequence}`,
8556
+ parentSpanId: request.spanId,
8557
+ kind: "tool_call",
8558
+ name: invocation.action,
8559
+ sequence: sequence++,
8560
+ status: invocation.error ? "failed" : invocation.completedAt ? "completed" : "running",
8561
+ startedAt: timestamp4(invocation.observedAt, job.startedAt),
8562
+ endedAt: timestamp4(invocation.completedAt, job.endedAt),
8563
+ nativeEventType: "grix_tool_invoke",
8564
+ nativeIds: { toolSequence: String(invocation.sequence) },
8565
+ rawAttributes: { toolInvocation: invocation }
8566
+ });
8567
+ if (invocation.params !== void 0) {
8568
+ append5(tool.inputRefs, addContent11(contents, seen, {
8569
+ role: "tool_arguments",
8570
+ format: "json",
8571
+ value: typeof invocation.params === "string" ? invocation.params : JSON.stringify(invocation.params),
8572
+ captureLevel: "runtime_exact"
8573
+ }));
8574
+ }
8575
+ const result = invocation.result ?? invocation.error;
8576
+ if (result !== void 0) {
8577
+ append5(tool.outputRefs, addContent11(contents, seen, {
8578
+ role: "tool_result",
8579
+ format: typeof result === "string" ? "text" : "json",
8580
+ value: typeof result === "string" ? result : JSON.stringify(result),
8581
+ captureLevel: "runtime_exact"
8582
+ }));
8583
+ }
8584
+ spans.push(tool);
8585
+ }
8586
+ }
8587
+ collection.gaps.push({
8588
+ category: "provider_usage",
8589
+ reason: "provider_usage_missing",
8590
+ detail: "agy print mode does not report token usage"
8591
+ });
8592
+ return {
8593
+ spans,
8594
+ contents,
8595
+ anomalies: collection.anomalies,
8596
+ collection,
8597
+ capture
8598
+ };
8599
+ }
8600
+ async correlate(_job, evidence) {
8601
+ return evidence;
8602
+ }
8603
+ validate(job, normalized) {
8604
+ const evidence = normalized;
8605
+ const requests = evidence.spans.filter(
8606
+ (item) => item.kind === "llm_request"
8607
+ );
8608
+ const tools = evidence.spans.filter((item) => item.kind === "tool_call");
8609
+ const inputComplete = !evidence.capture.inputOutput || job.input !== void 0 || evidence.collection.prompt !== void 0;
8610
+ const outputComplete = !evidence.capture.inputOutput || job.finalOutput !== void 0 || requests.some((request) => request.outputRefs.length > 0);
8611
+ const toolCallsComplete = !evidence.capture.tools || tools.every((tool) => tool.status !== "running");
8612
+ const usageComplete = false;
8613
+ const gaps = [...evidence.collection.gaps];
8614
+ if (evidence.capture.rawProviderBody) {
8615
+ gaps.push({
8616
+ category: "raw_provider_body",
8617
+ reason: "raw_capture_disabled",
8618
+ detail: "agy print mode exposes prompt/stdout and the CLI log, not raw model HTTP bodies"
8619
+ });
8620
+ }
8621
+ const complete = inputComplete && outputComplete && toolCallsComplete && usageComplete && gaps.length === 0;
8622
+ return {
8623
+ status: requests.length === 0 ? "failed" : complete ? "complete" : "partial",
8624
+ inputComplete,
8625
+ outputComplete,
8626
+ toolCallsComplete,
8627
+ subagentsComplete: true,
8628
+ usageComplete,
8629
+ rawRequestsComplete: false,
8630
+ gaps
8631
+ };
8632
+ }
8633
+ };
8634
+
8635
+ // src/audit/adapters/openclaw/openclaw-audit-adapter.ts
8636
+ import { readFile as readFile6, readdir as readdir4, stat as stat7 } from "node:fs/promises";
8637
+ import { basename as basename6, dirname as dirname2, join as join4 } from "node:path";
8638
+ function isRecord15(value) {
8639
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8640
+ }
8641
+ function replaceTranscriptPath(boundary, transcriptPath) {
8642
+ const next = { ...boundary, transcriptPath };
8643
+ delete next.transcriptStartOffset;
8644
+ delete next.transcriptEndOffset;
8645
+ delete next.transcriptFileIdentity;
8646
+ delete next.transcriptPrefixFingerprint;
8647
+ return next;
8648
+ }
8649
+ async function fileIdentity(path) {
8650
+ try {
8651
+ const source = await stat7(path);
8652
+ return `${source.dev}:${source.ino}`;
8653
+ } catch {
8654
+ return void 0;
8655
+ }
8656
+ }
8657
+ async function resolveResetTranscriptPath(transcriptPath, expectedIdentity) {
8658
+ if (!expectedIdentity) return void 0;
8659
+ try {
8660
+ const directory = dirname2(transcriptPath);
8661
+ const prefix = `${basename6(transcriptPath)}.reset`;
8662
+ const candidates = (await readdir4(directory)).filter((entry) => entry.startsWith(prefix)).sort().reverse();
8663
+ for (const entry of candidates) {
8664
+ const candidate = join4(directory, entry);
8665
+ if (await fileIdentity(candidate) === expectedIdentity) return candidate;
8666
+ }
8667
+ } catch {
8668
+ }
8669
+ return void 0;
8670
+ }
8671
+ async function resolveCurrentTranscriptPath(boundary) {
8242
8672
  const storePath = typeof boundary.sessionStorePath === "string" ? boundary.sessionStorePath : void 0;
8243
8673
  const sessionKey = typeof boundary.routeSessionKey === "string" ? boundary.routeSessionKey : void 0;
8244
- if (!storePath || !sessionKey) return boundary;
8674
+ if (!storePath || !sessionKey) return void 0;
8245
8675
  try {
8246
- const parsed = JSON.parse(await readFile5(storePath, "utf8"));
8247
- if (!isRecord14(parsed) || !isRecord14(parsed[sessionKey])) return boundary;
8676
+ const parsed = JSON.parse(await readFile6(storePath, "utf8"));
8677
+ if (!isRecord15(parsed) || !isRecord15(parsed[sessionKey])) return void 0;
8248
8678
  const session = parsed[sessionKey];
8249
- const sessionFile = typeof session.sessionFile === "string" ? session.sessionFile : typeof session.sessionId === "string" ? join4(dirname2(storePath), `${session.sessionId}.jsonl`) : void 0;
8250
- return sessionFile ? { ...boundary, transcriptPath: sessionFile } : boundary;
8679
+ return typeof session.sessionFile === "string" ? session.sessionFile : typeof session.sessionId === "string" ? join4(dirname2(storePath), `${session.sessionId}.jsonl`) : void 0;
8251
8680
  } catch {
8681
+ return void 0;
8682
+ }
8683
+ }
8684
+ async function resolveTranscriptBoundary(boundary) {
8685
+ const transcriptPath = typeof boundary.transcriptPath === "string" ? boundary.transcriptPath : void 0;
8686
+ if (!transcriptPath) {
8687
+ const currentTranscriptPath = await resolveCurrentTranscriptPath(boundary);
8688
+ return currentTranscriptPath ? replaceTranscriptPath(boundary, currentTranscriptPath) : boundary;
8689
+ }
8690
+ try {
8691
+ await stat7(transcriptPath);
8692
+ return boundary;
8693
+ } catch {
8694
+ const expectedIdentity = typeof boundary.transcriptFileIdentity === "string" ? boundary.transcriptFileIdentity : void 0;
8695
+ const resetTranscriptPath = await resolveResetTranscriptPath(
8696
+ transcriptPath,
8697
+ expectedIdentity
8698
+ );
8699
+ if (resetTranscriptPath) {
8700
+ return { ...boundary, transcriptPath: resetTranscriptPath };
8701
+ }
8702
+ const currentTranscriptPath = await resolveCurrentTranscriptPath(boundary);
8703
+ if (currentTranscriptPath && expectedIdentity && await fileIdentity(currentTranscriptPath) === expectedIdentity) {
8704
+ return { ...boundary, transcriptPath: currentTranscriptPath };
8705
+ }
8252
8706
  return boundary;
8253
8707
  }
8254
8708
  }
8255
8709
  function recordTimestamp(record4) {
8256
8710
  const direct = typeof record4.timestamp === "string" ? Date.parse(record4.timestamp) : Number(record4.timestamp);
8257
8711
  if (Number.isFinite(direct) && direct > 0) return direct;
8258
- const message = isRecord14(record4.message) ? record4.message : void 0;
8712
+ const message = isRecord15(record4.message) ? record4.message : void 0;
8259
8713
  const nested = Number(message?.timestamp);
8260
8714
  return Number.isFinite(nested) && nested > 0 ? nested : void 0;
8261
8715
  }
@@ -8317,20 +8771,20 @@ var OpenClawAuditAdapter = class {
8317
8771
 
8318
8772
  // src/audit/storage/file-audit-replay-store.ts
8319
8773
  import {
8320
- createHash as createHash3,
8774
+ createHash as createHash4,
8321
8775
  randomUUID
8322
8776
  } from "node:crypto";
8323
8777
  import {
8324
8778
  access,
8325
8779
  open as open5,
8326
8780
  mkdir,
8327
- readFile as readFile6,
8328
- readdir as readdir4,
8781
+ readFile as readFile7,
8782
+ readdir as readdir5,
8329
8783
  rename,
8330
8784
  rm,
8331
8785
  writeFile
8332
8786
  } from "node:fs/promises";
8333
- import { basename as basename6, dirname as dirname3, join as join5, relative, resolve as resolve3, sep as sep3 } from "node:path";
8787
+ import { basename as basename7, dirname as dirname3, join as join5, relative, resolve as resolve3, sep as sep3 } from "node:path";
8334
8788
  var SHA256_PATTERN = /^[a-f0-9]{64}$/;
8335
8789
  var NO_CAPTURE = Object.freeze({
8336
8790
  inputOutput: false,
@@ -8573,7 +9027,7 @@ var FileAuditReplayStore = class {
8573
9027
  if (!SHA256_PATTERN.test(contentId)) {
8574
9028
  throw new Error("Invalid audit content id");
8575
9029
  }
8576
- const plaintext = await readFile6(this.blobPath(contentId));
9030
+ const plaintext = await readFile7(this.blobPath(contentId));
8577
9031
  if (sha256(plaintext) !== contentId) {
8578
9032
  throw new Error("Audit blob content hash mismatch");
8579
9033
  }
@@ -8714,7 +9168,7 @@ var FileAuditReplayStore = class {
8714
9168
  }
8715
9169
  async storePlaintextBlob(path, contentId, plaintext) {
8716
9170
  if (await pathExists(path)) {
8717
- const existing = await readFile6(path);
9171
+ const existing = await readFile7(path);
8718
9172
  if (sha256(existing) === contentId) return;
8719
9173
  }
8720
9174
  await this.atomicWrite(path, plaintext);
@@ -8728,7 +9182,7 @@ var FileAuditReplayStore = class {
8728
9182
  await mkdir(directory, { recursive: true, mode: 448 });
8729
9183
  const temporary = join5(
8730
9184
  directory,
8731
- `.${basename6(path)}.${process.pid}.${randomUUID()}.tmp`
9185
+ `.${basename7(path)}.${process.pid}.${randomUUID()}.tmp`
8732
9186
  );
8733
9187
  try {
8734
9188
  await writeFile(temporary, body, { mode: 384, flag: "wx" });
@@ -8796,7 +9250,7 @@ var FileAuditReplayStore = class {
8796
9250
  }
8797
9251
  async readReplay(manifest) {
8798
9252
  const path = this.resolveStoredPath(manifest.replayPath);
8799
- const bytes = await readFile6(path);
9253
+ const bytes = await readFile7(path);
8800
9254
  if (sha256(bytes) !== manifest.replaySha256) {
8801
9255
  throw new Error("Audit replay document hash mismatch");
8802
9256
  }
@@ -8860,7 +9314,7 @@ function encodeJson(value) {
8860
9314
  `, "utf8");
8861
9315
  }
8862
9316
  function sha256(value) {
8863
- return createHash3("sha256").update(value).digest("hex");
9317
+ return createHash4("sha256").update(value).digest("hex");
8864
9318
  }
8865
9319
  function idKey(id) {
8866
9320
  return sha256(Buffer.from(id, "utf8"));
@@ -8876,7 +9330,7 @@ async function pathExists(path) {
8876
9330
  }
8877
9331
  async function readDirectory(path) {
8878
9332
  try {
8879
- return await readdir4(path);
9333
+ return await readdir5(path);
8880
9334
  } catch (error) {
8881
9335
  if (isNotFound(error)) return [];
8882
9336
  throw error;
@@ -8884,7 +9338,7 @@ async function readDirectory(path) {
8884
9338
  }
8885
9339
  async function readJsonIfPresent(path) {
8886
9340
  try {
8887
- return JSON.parse(await readFile6(path, "utf8"));
9341
+ return JSON.parse(await readFile7(path, "utf8"));
8888
9342
  } catch (error) {
8889
9343
  if (isNotFound(error)) return void 0;
8890
9344
  throw error;
@@ -8897,12 +9351,12 @@ function isNotFound(error) {
8897
9351
  // src/audit/worker/audit-recorder-ipc-protocol.ts
8898
9352
  var AUDIT_RECORDER_PROTOCOL_VERSION = 3;
8899
9353
  function isAuditRecorderParentMessage(value) {
8900
- if (!isRecord15(value) || typeof value.type !== "string") return false;
9354
+ if (!isRecord16(value) || typeof value.type !== "string") return false;
8901
9355
  switch (value.type) {
8902
9356
  case "audit_recorder_initialize":
8903
9357
  return value.protocolVersion === AUDIT_RECORDER_PROTOCOL_VERSION && isProcessConfig(value.config);
8904
9358
  case "audit_recorder_job":
8905
- return typeof value.deliveryId === "string" && isRecord15(value.job);
9359
+ return typeof value.deliveryId === "string" && isRecord16(value.job);
8906
9360
  case "audit_recorder_flush":
8907
9361
  case "audit_recorder_stop":
8908
9362
  return typeof value.requestId === "string";
@@ -8911,10 +9365,10 @@ function isAuditRecorderParentMessage(value) {
8911
9365
  }
8912
9366
  }
8913
9367
  function isProcessConfig(value) {
8914
- if (!isRecord15(value)) return false;
9368
+ if (!isRecord16(value)) return false;
8915
9369
  return typeof value.storageRootDir === "string" && (value.maxWorkerQueueSize === void 0 || typeof value.maxWorkerQueueSize === "number" && Number.isSafeInteger(value.maxWorkerQueueSize) && value.maxWorkerQueueSize > 0);
8916
9370
  }
8917
- function isRecord15(value) {
9371
+ function isRecord16(value) {
8918
9372
  return typeof value === "object" && value !== null && !Array.isArray(value);
8919
9373
  }
8920
9374
 
@@ -9067,6 +9521,7 @@ function createJobFinalizer(config) {
9067
9521
  registry.register(new CursorAuditAdapter());
9068
9522
  registry.register(new OpenCodeAuditAdapter());
9069
9523
  registry.register(new DeepSeekHarnessAuditAdapter());
9524
+ registry.register(new AgyAuditAdapter());
9070
9525
  registry.register(new OpenClawAuditAdapter());
9071
9526
  return {
9072
9527
  finalizer: new ReplayFinalizer(registry, store),