@gitroll/tacitt-cli 0.0.0-stage → 0.1.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 (140) hide show
  1. package/README.md +84 -2
  2. package/bin/INDEX.md +9 -0
  3. package/bin/tacitt.cjs +16 -0
  4. package/dist/agent-setup-B85GaVIz.mjs +71 -0
  5. package/dist/agent-setup-worker.mjs +56 -0
  6. package/dist/cli.mjs +1343 -0
  7. package/dist/codex-title-worker.mjs +215 -0
  8. package/dist/configured-preview-worker.mjs +133 -0
  9. package/dist/configured-session-worker.mjs +117 -0
  10. package/dist/frame-D1j9R8xX.mjs +84 -0
  11. package/dist/heap-1FYhGds4.mjs +75 -0
  12. package/dist/heap-tfU61Ehy.mjs +7253 -0
  13. package/dist/job--TceKk0l.mjs +194 -0
  14. package/dist/locate-Bn32k2se.mjs +10647 -0
  15. package/dist/model-7Nu7szNP.mjs +41 -0
  16. package/dist/operation-executor.mjs +181 -0
  17. package/dist/preview-worker.mjs +22 -0
  18. package/dist/privacy-validator.mjs +46 -0
  19. package/dist/query-Da-KDbSV.mjs +14511 -0
  20. package/dist/run-CCATsHS2.mjs +916 -0
  21. package/dist/session-process.mjs +90 -0
  22. package/dist/src-BngGpFKd.mjs +16416 -0
  23. package/dist/src-CPPjOyHZ.mjs +12782 -0
  24. package/dist/src-DynBRDBc.mjs +6590 -0
  25. package/dist/store-database-worker.mjs +14 -0
  26. package/dist/web/THIRD_PARTY_LICENSES.md +388 -0
  27. package/dist/web/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2 +0 -0
  28. package/dist/web/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff +0 -0
  29. package/dist/web/assets/ibm-plex-mono-cyrillic-500-normal-Ael50iVv.woff +0 -0
  30. package/dist/web/assets/ibm-plex-mono-cyrillic-500-normal-Bq9vWWag.woff2 +0 -0
  31. package/dist/web/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff +0 -0
  32. package/dist/web/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2 +0 -0
  33. package/dist/web/assets/ibm-plex-mono-cyrillic-ext-500-normal-BIfNGwUT.woff +0 -0
  34. package/dist/web/assets/ibm-plex-mono-cyrillic-ext-500-normal-BqneJy0T.woff2 +0 -0
  35. package/dist/web/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  36. package/dist/web/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  37. package/dist/web/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  38. package/dist/web/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  39. package/dist/web/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2 +0 -0
  40. package/dist/web/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff +0 -0
  41. package/dist/web/assets/ibm-plex-mono-latin-ext-500-normal-CAhNIIs5.woff2 +0 -0
  42. package/dist/web/assets/ibm-plex-mono-latin-ext-500-normal-CZ70TYgx.woff +0 -0
  43. package/dist/web/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2 +0 -0
  44. package/dist/web/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff +0 -0
  45. package/dist/web/assets/ibm-plex-mono-vietnamese-500-normal-C8zxqsMH.woff +0 -0
  46. package/dist/web/assets/ibm-plex-mono-vietnamese-500-normal-DZ4AoWbu.woff2 +0 -0
  47. package/dist/web/assets/ibm-plex-sans-cyrillic-400-normal-BTotfTJu.woff +0 -0
  48. package/dist/web/assets/ibm-plex-sans-cyrillic-400-normal-DZqxrq2p.woff2 +0 -0
  49. package/dist/web/assets/ibm-plex-sans-cyrillic-500-normal-ByOcLdNv.woff +0 -0
  50. package/dist/web/assets/ibm-plex-sans-cyrillic-500-normal-CocWQlwt.woff2 +0 -0
  51. package/dist/web/assets/ibm-plex-sans-cyrillic-600-normal-71GNu3SW.woff2 +0 -0
  52. package/dist/web/assets/ibm-plex-sans-cyrillic-600-normal-BGq0mW3O.woff +0 -0
  53. package/dist/web/assets/ibm-plex-sans-cyrillic-700-normal-D_uavGvn.woff2 +0 -0
  54. package/dist/web/assets/ibm-plex-sans-cyrillic-700-normal-RFb1v-CK.woff +0 -0
  55. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-400-normal-Dsrv2Tcn.woff +0 -0
  56. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-400-normal-g30qAdWV.woff2 +0 -0
  57. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-500-normal-Cs5J6C77.woff2 +0 -0
  58. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-500-normal-DB5PtV2g.woff +0 -0
  59. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-600-normal-Bz0x94Yp.woff +0 -0
  60. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-600-normal-DUMzJB7m.woff2 +0 -0
  61. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-700-normal-BmRLXWpJ.woff2 +0 -0
  62. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-700-normal-DCQwxkRk.woff +0 -0
  63. package/dist/web/assets/ibm-plex-sans-greek-400-normal-D9ESIMu3.woff +0 -0
  64. package/dist/web/assets/ibm-plex-sans-greek-400-normal-_efipK4i.woff2 +0 -0
  65. package/dist/web/assets/ibm-plex-sans-greek-500-normal-CuWXN6rf.woff +0 -0
  66. package/dist/web/assets/ibm-plex-sans-greek-500-normal-JMMifIXV.woff2 +0 -0
  67. package/dist/web/assets/ibm-plex-sans-greek-600-normal-D-CqTdkO.woff +0 -0
  68. package/dist/web/assets/ibm-plex-sans-greek-600-normal-DzTrcv_p.woff2 +0 -0
  69. package/dist/web/assets/ibm-plex-sans-greek-700-normal-CkZN0sRy.woff +0 -0
  70. package/dist/web/assets/ibm-plex-sans-greek-700-normal-wyJ6jzdA.woff2 +0 -0
  71. package/dist/web/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  72. package/dist/web/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  73. package/dist/web/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  74. package/dist/web/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  75. package/dist/web/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  76. package/dist/web/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  77. package/dist/web/assets/ibm-plex-sans-latin-700-normal-Bth3BMcD.woff +0 -0
  78. package/dist/web/assets/ibm-plex-sans-latin-700-normal-Bxkt5Cjx.woff2 +0 -0
  79. package/dist/web/assets/ibm-plex-sans-latin-ext-400-normal-C5H60-Va.woff2 +0 -0
  80. package/dist/web/assets/ibm-plex-sans-latin-ext-400-normal-RBey6euL.woff +0 -0
  81. package/dist/web/assets/ibm-plex-sans-latin-ext-500-normal-D0aIdm-b.woff +0 -0
  82. package/dist/web/assets/ibm-plex-sans-latin-ext-500-normal-DakdToA3.woff2 +0 -0
  83. package/dist/web/assets/ibm-plex-sans-latin-ext-600-normal-DIrixKbi.woff +0 -0
  84. package/dist/web/assets/ibm-plex-sans-latin-ext-600-normal-DOrvGEcy.woff2 +0 -0
  85. package/dist/web/assets/ibm-plex-sans-latin-ext-700-normal-DZH6Xh-4.woff +0 -0
  86. package/dist/web/assets/ibm-plex-sans-latin-ext-700-normal-aMgXseD4.woff2 +0 -0
  87. package/dist/web/assets/ibm-plex-sans-vietnamese-400-normal-DG4YqDda.woff2 +0 -0
  88. package/dist/web/assets/ibm-plex-sans-vietnamese-400-normal-fK1oJ5dG.woff +0 -0
  89. package/dist/web/assets/ibm-plex-sans-vietnamese-500-normal-BEb3_waV.woff +0 -0
  90. package/dist/web/assets/ibm-plex-sans-vietnamese-500-normal-e4dixQRQ.woff2 +0 -0
  91. package/dist/web/assets/ibm-plex-sans-vietnamese-600-normal-DgdngZtN.woff +0 -0
  92. package/dist/web/assets/ibm-plex-sans-vietnamese-600-normal-DpPYBSTl.woff2 +0 -0
  93. package/dist/web/assets/ibm-plex-sans-vietnamese-700-normal-BV5B8Are.woff +0 -0
  94. package/dist/web/assets/ibm-plex-sans-vietnamese-700-normal-CkEo6LDy.woff2 +0 -0
  95. package/dist/web/assets/index-CWQ05PFl.js +67 -0
  96. package/dist/web/assets/index-J-AWt_cW.css +1 -0
  97. package/dist/web/index.html +14 -0
  98. package/package.json +56 -3
  99. package/skills/INDEX.md +9 -0
  100. package/skills/tacitt/INDEX.md +11 -0
  101. package/skills/tacitt/SKILL.md +42 -0
  102. package/skills/tacitt/references/INDEX.md +15 -0
  103. package/skills/tacitt/references/b-method.md +22 -0
  104. package/skills/tacitt/references/bootstrap.md +109 -0
  105. package/skills/tacitt/references/classification.md +83 -0
  106. package/skills/tacitt/references/commands.md +147 -0
  107. package/skills/tacitt/references/journey.md +52 -0
  108. package/skills/tacitt/references/parallel-review.md +64 -0
  109. package/skills/tacitt/references/send.md +30 -0
  110. package/skills/tacitt/scripts/INDEX.md +43 -0
  111. package/skills/tacitt/scripts/answer.mjs +257 -0
  112. package/skills/tacitt/scripts/describe.mjs +55 -0
  113. package/skills/tacitt/scripts/journey-card-consolidation.d.mts +8 -0
  114. package/skills/tacitt/scripts/journey-card-consolidation.mjs +146 -0
  115. package/skills/tacitt/scripts/journey-classification-metadata.d.mts +16 -0
  116. package/skills/tacitt/scripts/journey-classification-metadata.mjs +111 -0
  117. package/skills/tacitt/scripts/journey-classification-progress.mjs +194 -0
  118. package/skills/tacitt/scripts/journey-classification-tasks.d.mts +18 -0
  119. package/skills/tacitt/scripts/journey-classification-tasks.mjs +345 -0
  120. package/skills/tacitt/scripts/journey-classification-validation.d.mts +20 -0
  121. package/skills/tacitt/scripts/journey-classification-validation.mjs +219 -0
  122. package/skills/tacitt/scripts/journey-classification.mjs +145 -0
  123. package/skills/tacitt/scripts/journey-consolidation-submit.mjs +190 -0
  124. package/skills/tacitt/scripts/journey-consolidation.d.mts +9 -0
  125. package/skills/tacitt/scripts/journey-consolidation.mjs +224 -0
  126. package/skills/tacitt/scripts/journey-scan-timing.mjs +143 -0
  127. package/skills/tacitt/scripts/journey-state.d.mts +42 -0
  128. package/skills/tacitt/scripts/journey-state.mjs +268 -0
  129. package/skills/tacitt/scripts/journey-tasks.d.mts +26 -0
  130. package/skills/tacitt/scripts/journey-tasks.mjs +183 -0
  131. package/skills/tacitt/scripts/journey.d.mts +38 -0
  132. package/skills/tacitt/scripts/journey.mjs +451 -0
  133. package/skills/tacitt/scripts/local-cli.d.mts +18 -0
  134. package/skills/tacitt/scripts/local-cli.mjs +116 -0
  135. package/skills/tacitt/scripts/privacy-validator.mjs +10350 -0
  136. package/skills/tacitt/scripts/review-stream-client.d.mts +22 -0
  137. package/skills/tacitt/scripts/review-stream-client.mjs +194 -0
  138. package/skills/tacitt/scripts/review.d.mts +87 -0
  139. package/skills/tacitt/scripts/review.mjs +1589 -0
  140. package/skills/tacitt/scripts/verify-cli.mjs +10 -0
@@ -0,0 +1,916 @@
1
+ import { tn as sessionSchema } from "./locate-Bn32k2se.mjs";
2
+ import { t as createZstdFrameCheck$1 } from "./frame-D1j9R8xX.mjs";
3
+ import "./src-CPPjOyHZ.mjs";
4
+ import { a as isRecord } from "./model-7Nu7szNP.mjs";
5
+ import { constants } from "node:fs";
6
+ import { z } from "zod";
7
+ import { lstat, open, stat } from "node:fs/promises";
8
+ import { isIP } from "node:net";
9
+ import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
10
+ import { PassThrough, Readable } from "node:stream";
11
+ import { createHash } from "node:crypto";
12
+ import { pipeline } from "node:stream/promises";
13
+ import { constants as constants$1, createZstdDecompress } from "node:zlib";
14
+ import { getHeapStatistics } from "node:v8";
15
+ import { lintSource } from "@secretlint/core";
16
+ import { creator } from "@secretlint/secretlint-rule-aws";
17
+ import { creator as creator$1 } from "@secretlint/secretlint-rule-privatekey";
18
+ import { creator as creator$2 } from "@secretlint/secretlint-rule-basicauth";
19
+ import { creator as creator$3 } from "@secretlint/secretlint-rule-github";
20
+ //#region packages/harnesses/src/source/files.ts
21
+ async function noSymlinks(path) {
22
+ if (!isAbsolute(path) || path.length > 16384) throw new Error("UNSAFE_SOURCE_PATH");
23
+ let current = resolve(path);
24
+ let depth = 0;
25
+ while (true) {
26
+ if (++depth > 256) throw new Error("UNSAFE_SOURCE_PATH");
27
+ if ((await lstat(current)).isSymbolicLink()) throw new Error("UNSAFE_SOURCE_PATH");
28
+ const parent = dirname(current);
29
+ if (parent === current) return;
30
+ current = parent;
31
+ }
32
+ }
33
+ function matches(value, snapshot, mode = "snapshot") {
34
+ if (!value.isFile() || value.dev.toString() !== snapshot.dev || value.ino.toString() !== snapshot.ino) return false;
35
+ if (mode === "append" && value.size > BigInt(snapshot.size)) return true;
36
+ return value.size === BigInt(snapshot.size) && value.mtimeNs.toString() === snapshot.mtimeNs && value.ctimeNs.toString() === snapshot.ctimeNs;
37
+ }
38
+ async function fileSnapshot(path, target) {
39
+ const value = target ?? await stat(path, { bigint: true });
40
+ if (!value.isFile() || value.size > BigInt(Number.MAX_SAFE_INTEGER)) throw new Error("UNSAFE_SOURCE_PATH");
41
+ return {
42
+ dev: value.dev.toString(),
43
+ ino: value.ino.toString(),
44
+ size: Number(value.size),
45
+ mtimeNs: value.mtimeNs.toString(),
46
+ ctimeNs: value.ctimeNs.toString()
47
+ };
48
+ }
49
+ async function openSource(part, mode = "snapshot") {
50
+ const child = relative(resolve(part.root), resolve(part.path));
51
+ if (!isAbsolute(part.root) || !isAbsolute(part.path) || part.root.length > 16384 || part.path.length > 16384 || !child || isAbsolute(child) || child === ".." || child.startsWith(`..${sep}`)) throw new Error("UNSAFE_SOURCE_PATH");
52
+ if (!matches(await stat(part.path, { bigint: true }), part.snapshot, mode)) throw new Error("SOURCE_CHANGED");
53
+ const handle = await open(part.path, constants.O_RDONLY);
54
+ try {
55
+ if (!matches(await handle.stat({ bigint: true }), part.snapshot, mode)) throw new Error("SOURCE_CHANGED");
56
+ return handle;
57
+ } catch (error) {
58
+ try {
59
+ await handle.close();
60
+ } catch (cleanupError) {
61
+ throw new AggregateError([error, cleanupError], "SOURCE_METADATA_UNAVAILABLE", { cause: error });
62
+ }
63
+ throw error;
64
+ }
65
+ }
66
+ /** Returns true only when the source still matches the complete recorded snapshot. */
67
+ async function checkOpenSource(part, handle, mode = "snapshot") {
68
+ const opened = await handle.stat({ bigint: true });
69
+ const current = await stat(part.path, { bigint: true });
70
+ if (!matches(opened, part.snapshot, mode) || !matches(current, part.snapshot, mode)) throw new Error("SOURCE_CHANGED");
71
+ return matches(opened, part.snapshot) && matches(current, part.snapshot);
72
+ }
73
+ async function checkSource(part) {
74
+ await (await openSource(part)).close();
75
+ }
76
+ //#endregion
77
+ //#region packages/harnesses/src/preview/zstd/frame.ts
78
+ function createZstdFrameCheck() {
79
+ return createZstdFrameCheck$1(() => {
80
+ throw new Error("PREVIEW_DECODE_FAILED");
81
+ });
82
+ }
83
+ //#endregion
84
+ //#region packages/harnesses/src/preview/policy.ts
85
+ const previewPolicyVersion = "turn-preview-v2";
86
+ const previewLimits = {
87
+ recordBytes: 262144,
88
+ unitBytes: 65536,
89
+ messageBytes: 32768,
90
+ responseBytes: 131072,
91
+ pageUnits: 8,
92
+ completeUsers: 64,
93
+ gap: 8,
94
+ unitMilliseconds: 2e3,
95
+ requestMilliseconds: 3e4,
96
+ zstdWindowLogMax: 26
97
+ };
98
+ function previewSourceVersion(session) {
99
+ return createHash("sha256").update(JSON.stringify({
100
+ harness: session.harness,
101
+ sourceKey: session.sourceKey,
102
+ parts: session.parts.map((part) => ({
103
+ path: part.path,
104
+ root: part.root,
105
+ representation: part.representation,
106
+ snapshot: part.snapshot
107
+ }))
108
+ })).digest("hex");
109
+ }
110
+ function parsePreviewCursor(cursor, sourceVersion) {
111
+ if (cursor === null) return {
112
+ mode: "o",
113
+ ordinal: 0
114
+ };
115
+ if (cursor.length > 128) throw new Error("INVALID_PREVIEW_CURSOR");
116
+ const match = /^turn-preview-v2:([a-f0-9]{64}):([odr]):(0|[1-9][0-9]*)$/.exec(cursor);
117
+ const mode = match?.[2];
118
+ const ordinal = Number(match?.[3]);
119
+ if (!match || match[1] !== sourceVersion || mode !== "o" && mode !== "d" && mode !== "r" || !Number.isSafeInteger(ordinal) || mode === "d" && ordinal === 0) throw new Error("INVALID_PREVIEW_CURSOR");
120
+ return {
121
+ mode,
122
+ ordinal
123
+ };
124
+ }
125
+ function previewCursor(sourceVersion, mode, ordinal) {
126
+ return `${previewPolicyVersion}:${sourceVersion}:${mode}:${ordinal}`;
127
+ }
128
+ function selectedCount(total, mode) {
129
+ if (mode === "r") return 0;
130
+ if (total <= previewLimits.completeUsers) return total;
131
+ return Math.floor((total - 1) / previewLimits.gap) + 1 + ((total - 1) % previewLimits.gap === 0 ? 0 : 1);
132
+ }
133
+ function nextOrdinal(ordinal, total, mode) {
134
+ if (mode === "r" || ordinal >= total) return null;
135
+ if (ordinal === 0) return total > 0 ? 1 : null;
136
+ return mode === "d" || total <= previewLimits.completeUsers ? ordinal + 1 : Math.min(ordinal + previewLimits.gap, total);
137
+ }
138
+ function pageOrdinals(cursor, total, preamble) {
139
+ if (cursor.ordinal > total || cursor.mode === "d" && total === 0 || cursor.mode === "o" && total > previewLimits.completeUsers && cursor.ordinal > 0 && cursor.ordinal !== total && (cursor.ordinal - 1) % previewLimits.gap !== 0) throw new Error("INVALID_PREVIEW_CURSOR");
140
+ if (cursor.mode === "r") return [cursor.ordinal];
141
+ const result = [];
142
+ let ordinal = cursor.ordinal === 0 && !preamble && total > 0 ? 1 : cursor.ordinal;
143
+ while (ordinal !== null && result.length < previewLimits.pageUnits) {
144
+ result.push(ordinal);
145
+ ordinal = nextOrdinal(ordinal, total, cursor.mode);
146
+ }
147
+ return result;
148
+ }
149
+ //#endregion
150
+ //#region packages/harnesses/src/preview/protocol.ts
151
+ const previewInputSchema = z.object({
152
+ session: sessionSchema,
153
+ cursor: z.string().max(128).nullable()
154
+ });
155
+ const previewPageSchema = z.object({
156
+ processing: z.object({
157
+ kind: z.literal("configured"),
158
+ configurationId: z.string().max(128),
159
+ metadata: z.string().max(16384).nullable(),
160
+ metadataWithheld: z.boolean()
161
+ }).optional(),
162
+ policyVersion: z.literal(previewPolicyVersion),
163
+ sourceVersion: z.string().regex(/^[a-f0-9]{64}$/),
164
+ totalUserMessages: z.number().int().nonnegative(),
165
+ sampledUserMessages: z.number().int().nonnegative(),
166
+ skippedRanges: z.array(z.string().regex(/^[0-9]+-[0-9]+$/)).max(previewLimits.pageUnits),
167
+ incomplete: z.boolean(),
168
+ nextCursor: z.string().max(128).nullable(),
169
+ warnings: z.array(z.string().max(80)).max(32),
170
+ units: z.array(z.object({
171
+ ordinal: z.number().int().nonnegative(),
172
+ role: z.enum(["preamble", "user-turn"]),
173
+ text: z.string().nullable(),
174
+ detailsWithheld: z.boolean(),
175
+ conversation: z.object({
176
+ user: z.string().nullable(),
177
+ assistant: z.string().nullable(),
178
+ userWithheld: z.boolean(),
179
+ assistantWithheld: z.boolean(),
180
+ activities: z.array(z.string().max(80)).max(3)
181
+ }).nullable(),
182
+ withheld: z.boolean(),
183
+ warnings: z.array(z.string().max(80)).max(32)
184
+ })).max(previewLimits.pageUnits)
185
+ });
186
+ const previewMessageSchema = z.discriminatedUnion("kind", [
187
+ z.object({ kind: z.literal("processing-start") }),
188
+ z.object({ kind: z.literal("processing-end") }),
189
+ z.object({
190
+ kind: z.literal("unit-start"),
191
+ ordinal: z.number().int().nonnegative(),
192
+ timeoutPage: previewPageSchema
193
+ }),
194
+ z.object({
195
+ kind: z.literal("unit-end"),
196
+ ordinal: z.number().int().nonnegative()
197
+ }),
198
+ z.object({
199
+ kind: z.literal("result"),
200
+ page: previewPageSchema
201
+ }),
202
+ z.object({
203
+ kind: z.literal("error"),
204
+ code: z.enum([
205
+ "SOURCE_CHANGED",
206
+ "INVALID_PREVIEW_CURSOR",
207
+ "PREVIEW_WITHHELD",
208
+ "PREVIEW_ENVELOPE_CHANGED",
209
+ "PROCESSING_PROTECTED_CUSTOM_TERM"
210
+ ])
211
+ })
212
+ ]);
213
+ //#endregion
214
+ //#region packages/harnesses/src/preview/source-stream.ts
215
+ async function* previewChunks(part) {
216
+ const handle = await openSource(part);
217
+ const framing = part.representation === "jsonl.zst" ? createZstdFrameCheck() : void 0;
218
+ async function* source() {
219
+ let position = 0;
220
+ while (position < part.snapshot.size) {
221
+ const bytes = new Uint8Array(Math.min(65536, part.snapshot.size - position));
222
+ const { bytesRead } = await handle.read(bytes, 0, bytes.length, position);
223
+ if (!bytesRead) throw new Error("SOURCE_CHANGED");
224
+ position += bytesRead;
225
+ const chunk = bytes.subarray(0, bytesRead);
226
+ const boundaries = framing?.push(chunk) ?? [];
227
+ let start = 0;
228
+ for (const end of boundaries) {
229
+ if (end > start) yield chunk.subarray(start, end);
230
+ start = end;
231
+ }
232
+ if (start < chunk.length) yield chunk.subarray(start);
233
+ }
234
+ framing?.finish();
235
+ }
236
+ const input = Readable.from(source(), {
237
+ objectMode: false,
238
+ highWaterMark: 65536
239
+ });
240
+ const decoded = part.representation === "jsonl.zst" ? createZstdDecompress({
241
+ chunkSize: 65536,
242
+ params: { [constants$1.ZSTD_d_windowLogMax]: previewLimits.zstdWindowLogMax }
243
+ }) : new PassThrough({ highWaterMark: 65536 });
244
+ const cancellation = new AbortController();
245
+ const completion = pipeline(input, decoded, { signal: cancellation.signal }).then(() => true, () => false);
246
+ let failed = false;
247
+ try {
248
+ try {
249
+ for await (const chunk of decoded) {
250
+ if (!(chunk instanceof Uint8Array)) throw new Error("PREVIEW_DECODE_FAILED");
251
+ yield chunk;
252
+ }
253
+ failed = !await completion;
254
+ } catch {
255
+ failed = true;
256
+ }
257
+ if (failed) yield null;
258
+ } finally {
259
+ cancellation.abort();
260
+ await completion;
261
+ try {
262
+ await checkOpenSource(part, handle);
263
+ } finally {
264
+ await handle.close();
265
+ }
266
+ }
267
+ }
268
+ //#endregion
269
+ //#region packages/harnesses/src/preview/records.ts
270
+ async function* streamRecords(part) {
271
+ const decoder = new TextDecoder("utf-8", {
272
+ fatal: true,
273
+ ignoreBOM: true
274
+ });
275
+ let pieces = [];
276
+ let length = 0;
277
+ let oversized = false;
278
+ const finish = (newline) => {
279
+ const bytes = length + (newline ? 1 : 0);
280
+ let result;
281
+ if (oversized) result = {
282
+ kind: "unclassified",
283
+ warning: "PREVIEW_RECORD_LIMIT",
284
+ bytes
285
+ };
286
+ else try {
287
+ const text = decoder.decode(Buffer.concat(pieces, length));
288
+ if (/^[\t\r ]*$/.test(text)) result = null;
289
+ else result = {
290
+ kind: "record",
291
+ value: JSON.parse(text),
292
+ bytes
293
+ };
294
+ } catch {
295
+ result = {
296
+ kind: "unclassified",
297
+ warning: "MALFORMED_PREVIEW_RECORD",
298
+ bytes
299
+ };
300
+ }
301
+ pieces = [];
302
+ length = 0;
303
+ oversized = false;
304
+ return result;
305
+ };
306
+ for await (const chunk of previewChunks(part)) {
307
+ if (chunk === null) {
308
+ if (length > 0) {
309
+ pieces = [];
310
+ length = 0;
311
+ oversized = false;
312
+ }
313
+ yield {
314
+ kind: "unclassified",
315
+ warning: "PREVIEW_DECODE_FAILED",
316
+ bytes: 0
317
+ };
318
+ continue;
319
+ }
320
+ let start = 0;
321
+ while (start < chunk.length) {
322
+ const newline = chunk.indexOf(10, start);
323
+ const end = newline < 0 ? chunk.length : newline;
324
+ const piece = chunk.subarray(start, end);
325
+ length += piece.length;
326
+ if (!Number.isSafeInteger(length)) throw new Error("PREVIEW_WITHHELD");
327
+ if (length > previewLimits.recordBytes) {
328
+ oversized = true;
329
+ pieces = [];
330
+ } else if (!oversized && piece.length) pieces.push(piece);
331
+ if (newline >= 0) {
332
+ if (length > 0) {
333
+ const record = finish(true);
334
+ if (record) yield record;
335
+ }
336
+ start = newline + 1;
337
+ } else start = chunk.length;
338
+ }
339
+ }
340
+ if (length > 0) {
341
+ const record = finish(false);
342
+ if (record) yield record;
343
+ }
344
+ }
345
+ //#endregion
346
+ //#region packages/harnesses/src/preview/classify.ts
347
+ function classifyRecord(value, harness, sourceRole) {
348
+ if (!isRecord(value)) return {
349
+ responseUser: false,
350
+ eventUser: false,
351
+ known: false
352
+ };
353
+ if (harness === "claude") {
354
+ const message = isRecord(value["message"]) ? value["message"] : null;
355
+ const content = Array.isArray(message?.["content"]) ? message["content"] : null;
356
+ const toolOnly = content !== null && content.length > 0 && content.every((item) => isRecord(item) && item["type"] === "tool_result");
357
+ return {
358
+ responseUser: sourceRole !== "worker" && value["isSidechain"] !== true && value["type"] === "user" && !toolOnly && value["isMeta"] !== true,
359
+ eventUser: false,
360
+ known: [
361
+ "user",
362
+ "assistant",
363
+ "system",
364
+ "progress",
365
+ "summary",
366
+ "result",
367
+ "queue-operation",
368
+ "file-history-snapshot",
369
+ "last-prompt",
370
+ "custom-title",
371
+ "compact-boundary"
372
+ ].includes(String(value["type"]))
373
+ };
374
+ }
375
+ const payload = isRecord(value["payload"]) ? value["payload"] : null;
376
+ return {
377
+ responseUser: sourceRole !== "worker" && value["type"] === "response_item" && payload?.["role"] === "user" && (payload["type"] === "message" || payload["type"] === void 0),
378
+ eventUser: sourceRole !== "worker" && value["type"] === "event_msg" && payload?.["type"] === "user_message",
379
+ known: [
380
+ "session_meta",
381
+ "turn_context",
382
+ "compacted"
383
+ ].includes(String(value["type"])) || payload !== null && ["response_item", "event_msg"].includes(String(value["type"]))
384
+ };
385
+ }
386
+ //#endregion
387
+ //#region packages/harnesses/src/preview/conversation.ts
388
+ function emptyConversation() {
389
+ return {
390
+ user: null,
391
+ assistant: null,
392
+ userWithheld: false,
393
+ assistantWithheld: false,
394
+ assistantMessages: 0,
395
+ toolCalls: 0,
396
+ toolResults: 0,
397
+ attachments: 0
398
+ };
399
+ }
400
+ function contentText(value, conversation) {
401
+ if (typeof value === "string") return value;
402
+ if (!Array.isArray(value)) return null;
403
+ const parts = [];
404
+ for (const item of value) {
405
+ if (!isRecord(item)) continue;
406
+ if ([
407
+ "text",
408
+ "input_text",
409
+ "output_text"
410
+ ].includes(String(item["type"]))) {
411
+ if (typeof item["text"] === "string") parts.push(item["text"]);
412
+ } else if (item["type"] === "tool_use") conversation.toolCalls++;
413
+ else if (item["type"] === "tool_result") conversation.toolResults++;
414
+ else if ([
415
+ "image",
416
+ "input_image",
417
+ "document",
418
+ "attachment"
419
+ ].includes(String(item["type"]))) conversation.attachments++;
420
+ }
421
+ return parts.length > 0 ? parts.join("\n\n") : null;
422
+ }
423
+ function assignMessage(conversation, role, text) {
424
+ if (text === null || role !== "user" && role !== "assistant") return;
425
+ const withheld = Buffer.byteLength(text) > previewLimits.messageBytes;
426
+ if (role === "user") {
427
+ conversation.user = withheld ? null : text;
428
+ conversation.userWithheld = withheld;
429
+ } else {
430
+ conversation.assistantMessages++;
431
+ conversation.assistant = withheld ? null : text;
432
+ conversation.assistantWithheld = withheld;
433
+ }
434
+ }
435
+ function collectConversation(conversation, value, harness, mode, sourceRole) {
436
+ if (!isRecord(value)) return;
437
+ if (harness === "claude") {
438
+ const message = isRecord(value["message"]) ? value["message"] : null;
439
+ if (message && value["isMeta"] !== true && (value["type"] === "user" || value["type"] === "assistant")) {
440
+ const text = contentText(message["content"], conversation);
441
+ if (sourceRole !== "worker" && value["isSidechain"] !== true) assignMessage(conversation, value["type"], text);
442
+ }
443
+ return;
444
+ }
445
+ const payload = isRecord(value["payload"]) ? value["payload"] : null;
446
+ if (!payload) return;
447
+ const type = typeof payload["type"] === "string" ? payload["type"] : "";
448
+ if (value["type"] === "response_item") {
449
+ if ((payload["type"] === "message" || payload["type"] === void 0) && (payload["role"] === "user" || payload["role"] === "assistant")) {
450
+ const text = contentText(payload["content"], conversation);
451
+ if (sourceRole !== "worker") assignMessage(conversation, payload["role"], text);
452
+ } else if (["function_call", "custom_tool_call"].includes(type)) conversation.toolCalls++;
453
+ else if (["function_call_output", "custom_tool_call_output"].includes(type)) conversation.toolResults++;
454
+ } else if (value["type"] === "event_msg" && mode === "event") {
455
+ const role = payload["type"] === "user_message" ? "user" : payload["type"] === "agent_message" ? "assistant" : null;
456
+ const text = contentText(payload["message"], conversation);
457
+ if (sourceRole !== "worker") assignMessage(conversation, role, text);
458
+ }
459
+ }
460
+ function activitySummaries(conversation) {
461
+ const summaries = [];
462
+ const tools = Math.max(conversation.toolCalls, conversation.toolResults);
463
+ if (tools > 0) summaries.push(`${tools} tool ${tools === 1 ? "activity" : "activities"}`);
464
+ if (conversation.attachments > 0) summaries.push(`${conversation.attachments} ${conversation.attachments === 1 ? "attachment" : "attachments"}`);
465
+ const earlier = conversation.assistantMessages - 1;
466
+ if (earlier > 0) summaries.push(`${earlier} earlier assistant ${earlier === 1 ? "update" : "updates"}`);
467
+ return summaries;
468
+ }
469
+ //#endregion
470
+ //#region packages/harnesses/src/preview/sequence.ts
471
+ async function countSequence(session, stream = streamRecords) {
472
+ const parts = [];
473
+ const warnings = /* @__PURE__ */ new Set();
474
+ let totalUsers = 0;
475
+ let preamble = false;
476
+ let incomplete = false;
477
+ for (const part of session.parts) {
478
+ let responseUsers = 0;
479
+ let eventUsers = 0;
480
+ let responsePrefix = false;
481
+ let eventPrefix = false;
482
+ for await (const record of stream(part)) {
483
+ if (record.kind === "unclassified") {
484
+ incomplete = true;
485
+ warnings.add(record.warning);
486
+ responsePrefix ||= responseUsers === 0;
487
+ eventPrefix ||= eventUsers === 0;
488
+ continue;
489
+ }
490
+ const boundary = record.kind === "boundary" ? {
491
+ ...record,
492
+ known: true
493
+ } : classifyRecord(record.value, session.harness, record.sourceRole);
494
+ if (!boundary.known) {
495
+ incomplete = true;
496
+ warnings.add("UNKNOWN_PREVIEW_RECORD");
497
+ }
498
+ if (boundary.responseUser) responseUsers++;
499
+ else responsePrefix ||= responseUsers === 0;
500
+ if (boundary.eventUser) eventUsers++;
501
+ else eventPrefix ||= eventUsers === 0;
502
+ }
503
+ const mode = session.harness === "codex" && responseUsers === 0 && eventUsers > 0 ? "event" : "response";
504
+ const users = mode === "event" ? eventUsers : responseUsers;
505
+ if (totalUsers === 0) preamble ||= mode === "event" ? eventPrefix : responsePrefix;
506
+ totalUsers += users;
507
+ if (!Number.isSafeInteger(totalUsers)) throw new Error("PREVIEW_WITHHELD");
508
+ parts.push({
509
+ mode,
510
+ users
511
+ });
512
+ if (mode === "event") warnings.add("CODEX_EVENT_MESSAGE_FALLBACK");
513
+ }
514
+ if (incomplete) warnings.add("USER_COUNT_INCOMPLETE");
515
+ if (totalUsers === 0) {
516
+ preamble = true;
517
+ warnings.add("NO_RECOGNIZED_USER_MESSAGES");
518
+ }
519
+ return {
520
+ parts,
521
+ totalUsers,
522
+ preamble,
523
+ incomplete,
524
+ warnings: [...warnings]
525
+ };
526
+ }
527
+ async function retainUnits(session, summary, ordinals, details = false, stream = streamRecords) {
528
+ const units = new Map(ordinals.map((ordinal) => [ordinal, {
529
+ ordinal,
530
+ records: [],
531
+ bytes: 0,
532
+ withheld: false,
533
+ detailsWithheld: false,
534
+ conversation: emptyConversation(),
535
+ warnings: [],
536
+ seen: false
537
+ }]));
538
+ let ordinal = 0;
539
+ for (const [index, part] of session.parts.entries()) {
540
+ const mode = summary.parts[index]?.mode;
541
+ if (!mode) throw new Error("SOURCE_CHANGED");
542
+ for await (const record of stream(part)) {
543
+ if (record.kind === "record" || record.kind === "boundary") {
544
+ const boundary = record.kind === "boundary" ? record : classifyRecord(record.value, session.harness, record.sourceRole);
545
+ if (mode === "event" ? boundary.eventUser : boundary.responseUser) ordinal++;
546
+ }
547
+ const unit = units.get(ordinal);
548
+ if (!unit) continue;
549
+ unit.seen = true;
550
+ unit.bytes += record.bytes;
551
+ if (record.kind === "boundary") {
552
+ unit.withheld = true;
553
+ unit.warnings.push("PREVIEW_WITHHELD");
554
+ }
555
+ if (record.kind === "unclassified") {
556
+ unit.withheld = true;
557
+ if (!unit.warnings.includes(record.warning)) unit.warnings.push(record.warning);
558
+ }
559
+ if (unit.bytes > previewLimits.unitBytes) {
560
+ unit.detailsWithheld = true;
561
+ if (!unit.warnings.includes("PREVIEW_DETAILS_LIMIT")) unit.warnings.push("PREVIEW_DETAILS_LIMIT");
562
+ }
563
+ if (!details && !unit.withheld && record.kind === "record") collectConversation(unit.conversation, record.value, session.harness, mode, record.sourceRole);
564
+ if (unit.withheld || unit.detailsWithheld) unit.records = [];
565
+ else if (details && record.kind === "record") unit.records.push(record.value);
566
+ }
567
+ }
568
+ if (ordinal !== summary.totalUsers) throw new Error("SOURCE_CHANGED");
569
+ for (const unit of units.values()) {
570
+ if (!unit.seen) {
571
+ unit.withheld = true;
572
+ unit.warnings.push("EMPTY_PREVIEW_UNIT");
573
+ }
574
+ unit.warnings = [...new Set(unit.warnings)];
575
+ }
576
+ return [...units.values()];
577
+ }
578
+ //#endregion
579
+ //#region packages/harnesses/src/preview/page.ts
580
+ function previewPage(context, units) {
581
+ const { sourceVersion, cursor, summary } = context;
582
+ const last = units.at(-1)?.ordinal;
583
+ const next = last === void 0 ? cursor.ordinal : nextOrdinal(last, summary.totalUsers, cursor.mode);
584
+ const skippedRanges = [];
585
+ if (cursor.mode === "o" && summary.totalUsers > previewLimits.completeUsers) for (const unit of units) {
586
+ if (unit.ordinal === 0) continue;
587
+ const following = nextOrdinal(unit.ordinal, summary.totalUsers, cursor.mode);
588
+ if (following !== null && following > unit.ordinal + 1) skippedRanges.push(`${unit.ordinal + 1}-${following - 1}`);
589
+ }
590
+ const incomplete = summary.incomplete || (context.processing?.metadataWithheld ?? false) || units.some((unit) => unit.withheld || unit.detailsWithheld || unit.conversation?.userWithheld || unit.conversation?.assistantWithheld);
591
+ return {
592
+ ...context.processing ? { processing: context.processing } : {},
593
+ policyVersion: previewPolicyVersion,
594
+ sourceVersion,
595
+ totalUserMessages: summary.totalUsers,
596
+ sampledUserMessages: cursor.mode === "d" ? units.length : selectedCount(summary.totalUsers, cursor.mode),
597
+ skippedRanges,
598
+ incomplete,
599
+ units,
600
+ nextCursor: next === null ? null : previewCursor(sourceVersion, cursor.mode, next),
601
+ warnings: [
602
+ ...summary.warnings,
603
+ ...incomplete ? ["INCOMPLETE_PREVIEW"] : [],
604
+ ...cursor.mode === "d" ? ["CONSECUTIVE_DRILLDOWN"] : []
605
+ ]
606
+ };
607
+ }
608
+ function pageFits(page) {
609
+ return Buffer.byteLength(JSON.stringify(page)) <= previewLimits.responseBytes;
610
+ }
611
+ function withheldUnit(ordinal, warnings) {
612
+ return {
613
+ ordinal,
614
+ role: ordinal === 0 ? "preamble" : "user-turn",
615
+ text: null,
616
+ detailsWithheld: true,
617
+ conversation: null,
618
+ withheld: true,
619
+ warnings: [...new Set(warnings)]
620
+ };
621
+ }
622
+ //#endregion
623
+ //#region packages/harnesses/src/preview/worker/heap.ts
624
+ const previewHeapLimits = {
625
+ maxOldGenerationSizeMb: 128,
626
+ maxYoungGenerationSizeMb: 32
627
+ };
628
+ const maximumBytes = (previewHeapLimits.maxOldGenerationSizeMb + 96) * 1024 ** 2;
629
+ const minimumBytes = previewHeapLimits.maxOldGenerationSizeMb * 1024 ** 2;
630
+ /** Fails closed so no preview runs under a heap the Worker resource limits did not bound. */
631
+ function assertPreviewHeap(limitBytes = getHeapStatistics().heap_size_limit) {
632
+ if (limitBytes < minimumBytes || limitBytes > maximumBytes) throw new Error("PREVIEW_HEAP_LIMIT_INVALID");
633
+ }
634
+ //#endregion
635
+ //#region packages/harnesses/src/preview/guard/identifiers.ts
636
+ function luhn(value) {
637
+ let sum = 0;
638
+ let double = false;
639
+ for (let index = value.length - 1; index >= 0; index--) {
640
+ let digit = Number(value[index]);
641
+ if (double) {
642
+ digit *= 2;
643
+ if (digit > 9) digit -= 9;
644
+ }
645
+ sum += digit;
646
+ double = !double;
647
+ }
648
+ return sum % 10 === 0;
649
+ }
650
+ function redactIdentifiers(text) {
651
+ return text.replace(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi, "[EMAIL]").replace(/\b[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\b/gi, "[UUID]").replace(/\b(?:\d{1,3}\.){3}\d{1,3}\b/g, (candidate) => isIP(candidate) === 4 ? "[IP]" : candidate).replace(/(?<![\w:])\[?[0-9a-f.:]+(?:%[\w.-]+)?\]?(?![\w:])/gi, (candidate) => {
652
+ if (!candidate.includes(":")) return candidate;
653
+ const address = candidate.replace(/^\[|\]$/g, "").split("%")[0] ?? "";
654
+ return isIP(address) === 6 ? "[IP]" : candidate;
655
+ }).replace(/(?<!\d)(?:\d[ -]?){12,18}\d(?!\d)/g, (candidate) => {
656
+ const digits = candidate.replace(/[ -]/g, "");
657
+ return !/^(\d)\1+$/.test(digits) && luhn(digits) ? "[PAYMENT_CARD]" : candidate;
658
+ });
659
+ }
660
+ //#endregion
661
+ //#region packages/harnesses/src/preview/guard/context.ts
662
+ const sensitiveKeys = /* @__PURE__ */ new Set([
663
+ "password",
664
+ "passwd",
665
+ "pwd",
666
+ "secret",
667
+ "clientsecret",
668
+ "token",
669
+ "accesstoken",
670
+ "refreshtoken",
671
+ "idtoken",
672
+ "apikey",
673
+ "credential",
674
+ "credentials",
675
+ "privatekey",
676
+ "authorization",
677
+ "proxyauthorization",
678
+ "cookie",
679
+ "setcookie",
680
+ "xapikey",
681
+ "awsaccesskeyid",
682
+ "awssecretaccesskey",
683
+ "awssessiontoken",
684
+ "databasepassword"
685
+ ]);
686
+ const pathKeys = /* @__PURE__ */ new Set([
687
+ "cwd",
688
+ "workingdirectory",
689
+ "filepath",
690
+ "filename",
691
+ "directory",
692
+ "homedir",
693
+ "path"
694
+ ]);
695
+ const normalizeKey = (key) => key.toLowerCase().replace(/[^a-z0-9]/g, "");
696
+ function valueCategory(key, value) {
697
+ if (key === void 0) return null;
698
+ const normalized = normalizeKey(key);
699
+ if (sensitiveKeys.has(normalized)) return "[SECRET]";
700
+ if (typeof value === "string" && pathKeys.has(normalized) && /^(?:\/|[a-z]:[\\/]|\\\\|~[^/]*\/)/i.test(value)) return "[PATH]";
701
+ if (typeof value === "string" && [
702
+ "hostname",
703
+ "server",
704
+ "endpoint",
705
+ "host"
706
+ ].includes(normalized) && /^[a-z0-9.-]+(?::\d+)?$/i.test(value)) return "[HOST]";
707
+ return null;
708
+ }
709
+ function redactContext(text) {
710
+ return text.replace(/-----BEGIN [^-\r\n]*PRIVATE KEY-----[\s\S]*?(?:-----END [^-\r\n]*PRIVATE KEY-----|$)/g, "[PRIVATE_KEY]").replace(/\b(?:gh[pousr]_[a-z0-9_]{8,}|github_pat_[a-z0-9_]{8,}|sk-(?:ant-)?[a-z0-9_-]{8,}|AKIA[A-Z0-9]{16}|ASIA[A-Z0-9]{16})\b/gi, "[SECRET]").replace(/\beyJ[A-Za-z0-9_-]{2,}\.[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+\b/g, "[TOKEN]").replace(/\b(authorization|proxy-authorization|cookie|set-cookie)\s*["']?\s*[:=]\s*[^\r\n]+/gi, "$1: [SECRET]").replace(/\b((?:aws[_-]?)?(?:secret[_-]?access[_-]?key|access[_-]?key[_-]?id|session[_-]?token)|password|passwd|client[_-]?secret|secret|(?:access[_-]?|refresh[_-]?|id[_-]?)?token|api[_-]?key|credential|private[_-]?key)\s*["']?\s*[:=]\s*(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s,;\]}]+)/gi, "$1=[SECRET]").replace(/--(?:password|passwd|token|api-key|secret)(?:=|\s+)(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s]+)/gi, "--credential [SECRET]");
711
+ }
712
+ //#endregion
713
+ //#region packages/harnesses/src/preview/guard/paths.ts
714
+ const sensitiveQuery = /^(?:access_token|token|api[_-]?key|key|secret|password|signature|sig|credential|x-amz-.+|x-goog-.+)$/i;
715
+ function redactLocations(text, localRoots) {
716
+ let result = text;
717
+ for (const root of [...localRoots].filter((value) => value.length > 1).sort((a, b) => b.length - a.length)) {
718
+ const escaped = root.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
719
+ result = result.replace(new RegExp(`${escaped}(?![a-zA-Z0-9_.-])(?:[/\\\\][^\\s"'<>]*)?`, "g"), "[PATH]");
720
+ }
721
+ result = result.replace(/\b(?:https?|ssh|git|file|postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis|amqps?):\/\/[^\s<>"']+/gi, (candidate) => {
722
+ try {
723
+ const url = new URL(candidate);
724
+ if (url.protocol === "file:") return "[PATH]";
725
+ if (url.username || url.password || [...url.searchParams.keys()].some((key) => sensitiveQuery.test(key)) || url.hash) return "[PRIVATE_URL]";
726
+ if (["ssh:", "git:"].includes(url.protocol) || /\.git\/?$/.test(url.pathname) || /^(?:github\.com|gitlab\.com|bitbucket\.org|dev\.azure\.com)$/i.test(url.hostname)) return "[GIT_REMOTE]";
727
+ return candidate;
728
+ } catch {
729
+ return "[PRIVATE_URL]";
730
+ }
731
+ });
732
+ return result.replace(/\b[a-z]:[\\/][^\r\n"'<>]+/gi, "[PATH]").replace(/\\\\[^\s"'<>]+/g, "[PATH]").replace(/(?<![\w/])~[^\s/]*\/[^\s"'<>]+/g, "[PATH]").replace(/(?<![\w/:])\/(?:home|Users|tmp|var|opt|mnt|workspace|workspaces|private|root)\/[^\s"'<>]+/g, "[PATH]").replace(/\b[a-z0-9._-]+@[a-z0-9.-]+:[^\s"'<>]+/gi, "[GIT_REMOTE]").replace(/\bFile\s+["']\/[^"'\r\n]+["']/g, "File [PATH]");
733
+ }
734
+ //#endregion
735
+ //#region packages/harnesses/src/preview/guard/index.ts
736
+ const selected = [
737
+ creator,
738
+ creator$1,
739
+ creator$2,
740
+ creator$3
741
+ ];
742
+ const config = { rules: selected.map((rule) => ({
743
+ id: rule.meta.id,
744
+ rule,
745
+ options: rule === creator ? { enableIDScanRule: true } : {}
746
+ })) };
747
+ selected.map((rule) => rule.meta.id);
748
+ async function redact(text, roots) {
749
+ if (text.length > 65536) throw new Error("TEXT_LIMIT");
750
+ const spans = (await lintSource({
751
+ source: {
752
+ content: text,
753
+ filePath: "/virtual/session.txt",
754
+ contentType: "text"
755
+ },
756
+ options: {
757
+ config,
758
+ maskSecrets: true,
759
+ noPhysicFilePath: true
760
+ }
761
+ })).messages.map((message) => message.range).sort((a, b) => a[0] - b[0]);
762
+ let end = 0;
763
+ let output = "";
764
+ for (const span of spans) {
765
+ if (span[1] <= end) continue;
766
+ if (span[0] > end) output += text.slice(end, span[0]);
767
+ output += "[SECRET]";
768
+ end = span[1];
769
+ }
770
+ output += text.slice(end);
771
+ return redactIdentifiers(redactContext(redactLocations(output, roots)));
772
+ }
773
+ async function previewText(text, roots) {
774
+ try {
775
+ if (Buffer.byteLength(text) > previewLimits.messageBytes) return null;
776
+ const safe = await redact(text, roots);
777
+ return Buffer.byteLength(safe) <= previewLimits.messageBytes ? safe : null;
778
+ } catch {
779
+ return null;
780
+ }
781
+ }
782
+ async function preview(value, injectFailure = false, context = {}) {
783
+ let fields = 0;
784
+ const parts = [];
785
+ let outputBytes = 0;
786
+ const roots = context.localRoots ?? [];
787
+ const append = async (value) => {
788
+ const safe = await redact(value, roots);
789
+ outputBytes += Buffer.byteLength(safe) + 1;
790
+ if (outputBytes > 65536) throw new Error("PREVIEW_LIMIT");
791
+ parts.push(safe);
792
+ };
793
+ async function visit(input, depth, key) {
794
+ if (injectFailure) throw new Error("INJECTED_SCANNER_FAILURE");
795
+ if (depth > 32 || ++fields > 4096) throw new Error("STRUCTURE_LIMIT");
796
+ const category = valueCategory(key, input);
797
+ if (category) {
798
+ await append(`${key ?? ""}: ${category}`);
799
+ return;
800
+ }
801
+ if (Array.isArray(input)) {
802
+ if (key !== void 0) await append(key);
803
+ for (const item of input) await visit(item, depth + 1);
804
+ } else if (input !== null && typeof input === "object") {
805
+ if (key !== void 0) await append(key);
806
+ for (const [childKey, child] of Object.entries(input)) await visit(child, depth + 1, childKey);
807
+ } else await append(`${key === void 0 ? "" : `${key}: `}${String(input)}`);
808
+ }
809
+ try {
810
+ await visit(value, 0);
811
+ const text = parts.join("\n");
812
+ if (Buffer.byteLength(text) > 65536) throw new Error("PREVIEW_LIMIT");
813
+ return {
814
+ status: "ready",
815
+ text,
816
+ fields
817
+ };
818
+ } catch {
819
+ return {
820
+ status: "withheld",
821
+ fields
822
+ };
823
+ }
824
+ }
825
+ //#endregion
826
+ //#region packages/harnesses/src/preview/presentation.ts
827
+ async function presentUnit(item, details, localRoots, presentation = {
828
+ records: async (records) => {
829
+ const guarded = await preview(records, false, { localRoots });
830
+ return guarded.status === "withheld" ? null : guarded.text ?? null;
831
+ },
832
+ text: (text) => previewText(text, localRoots)
833
+ }) {
834
+ const warnings = [...item.warnings];
835
+ let text = null;
836
+ let detailsWithheld = item.detailsWithheld;
837
+ let conversation = null;
838
+ if (details && !detailsWithheld) {
839
+ text = await presentation.records(item.records);
840
+ detailsWithheld = text === null;
841
+ if (detailsWithheld) warnings.push("PREVIEW_DETAILS_WITHHELD");
842
+ } else if (!details && item.ordinal > 0) {
843
+ const body = item.conversation;
844
+ const user = body.user === null ? null : await presentation.text(body.user);
845
+ const assistant = body.assistant === null ? null : await presentation.text(body.assistant);
846
+ const userWithheld = body.userWithheld || body.user !== null && user === null;
847
+ const assistantWithheld = body.assistantWithheld || body.assistant !== null && assistant === null;
848
+ conversation = {
849
+ user,
850
+ assistant,
851
+ userWithheld,
852
+ assistantWithheld,
853
+ activities: activitySummaries(body)
854
+ };
855
+ if (userWithheld || assistantWithheld) warnings.push("PREVIEW_MESSAGE_WITHHELD");
856
+ }
857
+ return {
858
+ ordinal: item.ordinal,
859
+ role: item.ordinal === 0 ? "preamble" : "user-turn",
860
+ text,
861
+ detailsWithheld,
862
+ conversation,
863
+ withheld: false,
864
+ warnings
865
+ };
866
+ }
867
+ //#endregion
868
+ //#region packages/harnesses/src/preview/run.ts
869
+ async function runPreview(session, rawCursor, notify, processed) {
870
+ const sourceVersion = processed?.sourceVersion ?? previewSourceVersion(session);
871
+ const cursor = parsePreviewCursor(rawCursor, sourceVersion);
872
+ const stream = processed?.stream;
873
+ const summary = await countSequence(session, processed?.countStream ?? processed?.stream);
874
+ const ordinals = pageOrdinals(cursor, summary.totalUsers, summary.preamble);
875
+ processed?.select?.(summary, ordinals);
876
+ const retained = await retainUnits(session, summary, ordinals, cursor.mode === "r", stream);
877
+ const processing = processed?.processing();
878
+ const context = {
879
+ sourceVersion,
880
+ cursor,
881
+ summary,
882
+ ...processing ? { processing } : {}
883
+ };
884
+ const units = [];
885
+ const localRoots = [...new Set(session.parts.map((part) => part.root))];
886
+ for (const item of retained) {
887
+ let unit;
888
+ if (item.withheld) unit = withheldUnit(item.ordinal, item.warnings);
889
+ else {
890
+ const timeoutPage = previewPage(context, [...units, withheldUnit(item.ordinal, ["PREVIEW_UNIT_TIMEOUT"])]);
891
+ if (!pageFits(timeoutPage)) break;
892
+ notify({
893
+ kind: "unit-start",
894
+ ordinal: item.ordinal,
895
+ timeoutPage
896
+ });
897
+ unit = await presentUnit(item, cursor.mode === "r", localRoots, processed?.presentation);
898
+ notify({
899
+ kind: "unit-end",
900
+ ordinal: item.ordinal
901
+ });
902
+ item.records = [];
903
+ }
904
+ if (!pageFits(previewPage(context, [...units, unit]))) {
905
+ if (units.length > 0) break;
906
+ unit = withheldUnit(item.ordinal, ["PREVIEW_RESPONSE_LIMIT"]);
907
+ }
908
+ units.push(unit);
909
+ }
910
+ for (const part of session.parts) await checkSource(part);
911
+ const result = previewPage(context, units);
912
+ if (units.length === 0 || !pageFits(result)) throw new Error("PREVIEW_WITHHELD");
913
+ return result;
914
+ }
915
+ //#endregion
916
+ export { classifyRecord as a, previewLimits as c, checkOpenSource as d, checkSource as f, openSource as h, pageFits as i, previewSourceVersion as l, noSymlinks as m, assertPreviewHeap as n, previewInputSchema as o, fileSnapshot as p, previewHeapLimits as r, previewMessageSchema as s, runPreview as t, createZstdFrameCheck as u };