@tracemarketplace/shared 0.0.1 → 0.0.3

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.
@@ -0,0 +1,8 @@
1
+ import type { NormalizedTrace } from "./types.js";
2
+ /**
3
+ * Split a NormalizedTrace into chunks of at most maxOutputTokens output tokens.
4
+ * Always breaks at user-turn boundaries (never mid-assistant-response).
5
+ * If the session fits within one chunk, returns a single-element array with chunk_index=0.
6
+ */
7
+ export declare function chunkTrace(trace: NormalizedTrace, maxOutputTokens?: number): NormalizedTrace[];
8
+ //# sourceMappingURL=chunker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunker.d.ts","sourceRoot":"","sources":["../src/chunker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAQ,MAAM,YAAY,CAAC;AAuDxD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,eAAe,EACtB,eAAe,SAAoB,GAClC,eAAe,EAAE,CAwCnB"}
@@ -0,0 +1,68 @@
1
+ import { computeContentHash } from "./hash.js";
2
+ const MAX_OUTPUT_TOKENS = 100_000;
3
+ function sumOutputTokens(turns) {
4
+ return turns.reduce((sum, t) => sum + (t.usage?.output_tokens ?? 0), 0);
5
+ }
6
+ function buildChunk(base, turns, chunkIndex, chunkStartTurn) {
7
+ const inputTokens = turns.reduce((s, t) => s + (t.usage?.input_tokens ?? 0), 0);
8
+ const outputTokens = turns.reduce((s, t) => s + (t.usage?.output_tokens ?? 0), 0);
9
+ const toolCallCount = turns.reduce((s, t) => s + t.content.filter((b) => b.type === "tool_use").length, 0);
10
+ const chunk = {
11
+ ...base,
12
+ turns,
13
+ chunk_index: chunkIndex,
14
+ chunk_start_turn: chunkStartTurn,
15
+ turn_count: turns.length,
16
+ tool_call_count: toolCallCount,
17
+ has_tool_calls: toolCallCount > 0,
18
+ has_thinking_blocks: turns.some((t) => t.content.some((b) => b.type === "thinking")),
19
+ has_file_changes: turns.some((t) => t.content.some((b) => b.type === "tool_use" &&
20
+ (b.tool_name === "Edit" || b.tool_name === "Write" || b.tool_name === "MultiEdit"))),
21
+ has_shell_commands: turns.some((t) => t.content.some((b) => b.type === "tool_use" && b.tool_name === "Bash")),
22
+ total_input_tokens: inputTokens || null,
23
+ total_output_tokens: outputTokens || null,
24
+ started_at: turns.find((t) => t.timestamp)?.timestamp ?? base.started_at,
25
+ ended_at: [...turns].reverse().find((t) => t.timestamp)?.timestamp ?? base.ended_at,
26
+ };
27
+ // Recompute trace_id and content_hash for this chunk
28
+ chunk.trace_id = computeContentHash(chunk);
29
+ return chunk;
30
+ }
31
+ /**
32
+ * Split a NormalizedTrace into chunks of at most maxOutputTokens output tokens.
33
+ * Always breaks at user-turn boundaries (never mid-assistant-response).
34
+ * If the session fits within one chunk, returns a single-element array with chunk_index=0.
35
+ */
36
+ export function chunkTrace(trace, maxOutputTokens = MAX_OUTPUT_TOKENS) {
37
+ const totalOutput = trace.total_output_tokens ?? sumOutputTokens(trace.turns);
38
+ // Fast path: fits in one chunk
39
+ if (totalOutput <= maxOutputTokens) {
40
+ return [{ ...trace, chunk_index: 0, chunk_start_turn: 0 }];
41
+ }
42
+ const chunks = [];
43
+ let chunkStartTurn = 0;
44
+ let chunkOutputTokens = 0;
45
+ let chunkTurns = [];
46
+ let chunkIndex = 0;
47
+ for (let i = 0; i < trace.turns.length; i++) {
48
+ const turn = trace.turns[i];
49
+ // Break at user-turn boundary once we've accumulated enough
50
+ if (turn.role === "user" &&
51
+ chunkOutputTokens >= maxOutputTokens &&
52
+ chunkTurns.length > 0) {
53
+ chunks.push(buildChunk(trace, chunkTurns, chunkIndex, chunkStartTurn));
54
+ chunkIndex++;
55
+ chunkStartTurn = i;
56
+ chunkOutputTokens = 0;
57
+ chunkTurns = [];
58
+ }
59
+ chunkTurns.push(turn);
60
+ chunkOutputTokens += turn.usage?.output_tokens ?? 0;
61
+ }
62
+ // Final chunk (may be < maxOutputTokens — that's fine, 2-day rule handles it)
63
+ if (chunkTurns.length > 0) {
64
+ chunks.push(buildChunk(trace, chunkTurns, chunkIndex, chunkStartTurn));
65
+ }
66
+ return chunks;
67
+ }
68
+ //# sourceMappingURL=chunker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunker.js","sourceRoot":"","sources":["../src/chunker.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,8 @@ export * from "./hash.js";
3
3
  export * from "./scoring.js";
4
4
  export * from "./utils.js";
5
5
  export * from "./validators.js";
6
+ export * from "./redact.js";
7
+ export * from "./chunker.js";
6
8
  export { extractClaudeCode } from "./extractors/claude-code.js";
7
9
  export { extractCodex } from "./extractors/codex.js";
8
10
  export { extractCursor } from "./extractors/cursor.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -3,6 +3,8 @@ export * from "./hash.js";
3
3
  export * from "./scoring.js";
4
4
  export * from "./utils.js";
5
5
  export * from "./validators.js";
6
+ export * from "./redact.js";
7
+ export * from "./chunker.js";
6
8
  export { extractClaudeCode } from "./extractors/claude-code.js";
7
9
  export { extractCodex } from "./extractors/codex.js";
8
10
  export { extractCursor } from "./extractors/cursor.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { NormalizedTrace } from "./types.js";
2
+ export interface RedactOptions {
3
+ /** Pass os.homedir() from the CLI — strips absolute home paths from all strings. */
4
+ homeDir?: string;
5
+ }
6
+ /**
7
+ * Redact PII and secrets from a trace before it leaves the user's machine.
8
+ *
9
+ * Pass `homeDir: os.homedir()` from the CLI so absolute paths are stripped.
10
+ * The server runs a second pass (without homeDir) as a safety net.
11
+ */
12
+ export declare function redactTrace(trace: NormalizedTrace, opts?: RedactOptions): NormalizedTrace;
13
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAsB,MAAM,YAAY,CAAC;AAEtE,MAAM,WAAW,aAAa;IAC5B,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAoGD;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,eAAe,EACtB,IAAI,GAAE,aAAkB,GACvB,eAAe,CAuBjB"}
package/dist/redact.js ADDED
@@ -0,0 +1,114 @@
1
+ // ─── Secret patterns ────────────────────────────────────────────────────────
2
+ // Ordered from specific → generic to avoid partial matches being swallowed.
3
+ const SECRET_PATTERNS = [
4
+ // Anthropic
5
+ { re: /sk-ant-[a-zA-Z0-9\-_]{20,}/g, label: "ANTHROPIC_KEY" },
6
+ // OpenAI (must come before generic sk- catch-all)
7
+ { re: /sk-proj-[a-zA-Z0-9\-_]{20,}/g, label: "OPENAI_KEY" },
8
+ { re: /sk-[a-zA-Z0-9]{20,}/g, label: "OPENAI_KEY" },
9
+ // AWS
10
+ { re: /AKIA[0-9A-Z]{16}/g, label: "AWS_ACCESS_KEY" },
11
+ { re: /(aws_secret_access_key\s*[=:]\s*)[A-Za-z0-9/+]{40}/gi, label: "AWS_SECRET_KEY" },
12
+ // GitHub
13
+ { re: /github_pat_[a-zA-Z0-9_]{82}/g, label: "GITHUB_PAT" },
14
+ { re: /ghp_[a-zA-Z0-9]{36}/g, label: "GITHUB_TOKEN" },
15
+ { re: /ghs_[a-zA-Z0-9]{36}/g, label: "GITHUB_TOKEN" },
16
+ // Stripe
17
+ { re: /sk_live_[a-zA-Z0-9]{24,}/g, label: "STRIPE_SECRET_KEY" },
18
+ { re: /rk_live_[a-zA-Z0-9]{24,}/g, label: "STRIPE_RESTRICTED_KEY" },
19
+ // Resend
20
+ { re: /re_[a-zA-Z0-9]{32,}/g, label: "RESEND_KEY" },
21
+ // JWTs — eyJ<base64>.<base64>.<base64>
22
+ { re: /eyJ[a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]*/g, label: "JWT" },
23
+ // Bearer tokens in Authorization headers
24
+ { re: /(Bearer\s+)[a-zA-Z0-9\-._~+/]+=*/gi, label: "BEARER_TOKEN" },
25
+ // Passwords in URLs: https://user:PASSWORD@host
26
+ { re: /(https?:\/\/[^:@\s]+:)[^:@\s]+(@)/g, label: "URL_PASSWORD" },
27
+ // Database DSNs: postgres://user:PASSWORD@host
28
+ { re: /((?:postgres(?:ql)?|mysql|redis):\/\/[^:]+:)[^@\s]+(@)/g, label: "DB_PASSWORD" },
29
+ // Generic key/secret assignments: API_KEY=abc123... or secret: "abc123..."
30
+ {
31
+ re: /((?:api[_-]?key|api[_-]?secret|access[_-]?token|auth[_-]?token|private[_-]?key|client[_-]?secret)\s*[=:]\s*["']?)[a-zA-Z0-9\-_.+/]{16,}(["']?)/gi,
32
+ label: "SECRET_VALUE",
33
+ },
34
+ ];
35
+ // ─── Core string transforms ──────────────────────────────────────────────────
36
+ function stripHome(s, home) {
37
+ return home ? s.replaceAll(home, "~") : s;
38
+ }
39
+ function stripSecrets(s) {
40
+ let out = s;
41
+ for (const { re, label } of SECRET_PATTERNS) {
42
+ // Patterns with capture groups: preserve group 1 (key name), replace group 2 (value)
43
+ if (re.source.includes("(")) {
44
+ out = out.replace(re, (...args) => {
45
+ // Replace only the non-group parts; keep named prefixes intact
46
+ const groups = args.slice(1, -2);
47
+ if (groups.length === 1)
48
+ return `${groups[0]}[${label}]`;
49
+ if (groups.length === 2)
50
+ return `${groups[0]}[${label}]${groups[1]}`;
51
+ return `[${label}]`;
52
+ });
53
+ }
54
+ else {
55
+ out = out.replace(re, `[${label}]`);
56
+ }
57
+ re.lastIndex = 0; // reset stateful global regexes
58
+ }
59
+ return out;
60
+ }
61
+ function redactString(s, home) {
62
+ return stripSecrets(stripHome(s, home));
63
+ }
64
+ // ─── Content block traversal ─────────────────────────────────────────────────
65
+ function redactToolInput(input, home) {
66
+ return Object.fromEntries(Object.entries(input).map(([k, v]) => [
67
+ k,
68
+ typeof v === "string" ? redactString(v, home) : v,
69
+ ]));
70
+ }
71
+ function redactBlock(block, home) {
72
+ switch (block.type) {
73
+ case "text":
74
+ case "thinking":
75
+ return { ...block, text: redactString(block.text, home) };
76
+ case "tool_use":
77
+ return { ...block, tool_input: redactToolInput(block.tool_input, home) };
78
+ case "tool_result":
79
+ return {
80
+ ...block,
81
+ result_content: block.result_content
82
+ ? redactString(block.result_content, home)
83
+ : null,
84
+ };
85
+ default:
86
+ return block;
87
+ }
88
+ }
89
+ // ─── Public API ───────────────────────────────────────────────────────────────
90
+ /**
91
+ * Redact PII and secrets from a trace before it leaves the user's machine.
92
+ *
93
+ * Pass `homeDir: os.homedir()` from the CLI so absolute paths are stripped.
94
+ * The server runs a second pass (without homeDir) as a safety net.
95
+ */
96
+ export function redactTrace(trace, opts = {}) {
97
+ const home = opts.homeDir ?? "";
98
+ return {
99
+ ...trace,
100
+ turns: trace.turns.map((turn) => ({
101
+ ...turn,
102
+ content: turn.content.map((b) => redactBlock(b, home)),
103
+ })),
104
+ env_state: trace.env_state
105
+ ? {
106
+ ...trace.env_state,
107
+ inferred_file_tree: trace.env_state.inferred_file_tree?.map((p) => stripHome(p, home)) ?? null,
108
+ inferred_changed_files: trace.env_state.inferred_changed_files?.map((p) => stripHome(p, home)) ?? null,
109
+ inferred_error_files: trace.env_state.inferred_error_files?.map((p) => stripHome(p, home)) ?? null,
110
+ }
111
+ : null,
112
+ };
113
+ }
114
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -70,6 +70,8 @@ export interface NormalizedTrace {
70
70
  schema_version: string;
71
71
  source_tool: SourceTool;
72
72
  source_session_id: string;
73
+ chunk_index?: number;
74
+ chunk_start_turn?: number;
73
75
  source_version: string | null;
74
76
  submitted_by: string;
75
77
  submitted_at: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,8 @@ export declare const NormalizedTraceSchema: z.ZodObject<{
4
4
  schema_version: z.ZodOptional<z.ZodString>;
5
5
  source_tool: z.ZodEnum<["claude_code", "codex_cli", "cursor"]>;
6
6
  source_session_id: z.ZodString;
7
+ chunk_index: z.ZodDefault<z.ZodNumber>;
8
+ chunk_start_turn: z.ZodDefault<z.ZodNumber>;
7
9
  source_version: z.ZodOptional<z.ZodNullable<z.ZodString>>;
8
10
  submitted_by: z.ZodOptional<z.ZodString>;
9
11
  submitted_at: z.ZodOptional<z.ZodString>;
@@ -31,6 +33,8 @@ export declare const NormalizedTraceSchema: z.ZodObject<{
31
33
  }, "strip", z.ZodTypeAny, {
32
34
  source_tool: "claude_code" | "codex_cli" | "cursor";
33
35
  source_session_id: string;
36
+ chunk_index: number;
37
+ chunk_start_turn: number;
34
38
  trace_id?: string | undefined;
35
39
  schema_version?: string | undefined;
36
40
  source_version?: string | null | undefined;
@@ -62,6 +66,8 @@ export declare const NormalizedTraceSchema: z.ZodObject<{
62
66
  source_session_id: string;
63
67
  trace_id?: string | undefined;
64
68
  schema_version?: string | undefined;
69
+ chunk_index?: number | undefined;
70
+ chunk_start_turn?: number | undefined;
65
71
  source_version?: string | null | undefined;
66
72
  submitted_by?: string | undefined;
67
73
  submitted_at?: string | undefined;
@@ -94,6 +100,8 @@ export declare const BatchSubmitSchema: z.ZodObject<{
94
100
  schema_version: z.ZodOptional<z.ZodString>;
95
101
  source_tool: z.ZodEnum<["claude_code", "codex_cli", "cursor"]>;
96
102
  source_session_id: z.ZodString;
103
+ chunk_index: z.ZodDefault<z.ZodNumber>;
104
+ chunk_start_turn: z.ZodDefault<z.ZodNumber>;
97
105
  source_version: z.ZodOptional<z.ZodNullable<z.ZodString>>;
98
106
  submitted_by: z.ZodOptional<z.ZodString>;
99
107
  submitted_at: z.ZodOptional<z.ZodString>;
@@ -121,6 +129,8 @@ export declare const BatchSubmitSchema: z.ZodObject<{
121
129
  }, "strip", z.ZodTypeAny, {
122
130
  source_tool: "claude_code" | "codex_cli" | "cursor";
123
131
  source_session_id: string;
132
+ chunk_index: number;
133
+ chunk_start_turn: number;
124
134
  trace_id?: string | undefined;
125
135
  schema_version?: string | undefined;
126
136
  source_version?: string | null | undefined;
@@ -152,6 +162,8 @@ export declare const BatchSubmitSchema: z.ZodObject<{
152
162
  source_session_id: string;
153
163
  trace_id?: string | undefined;
154
164
  schema_version?: string | undefined;
165
+ chunk_index?: number | undefined;
166
+ chunk_start_turn?: number | undefined;
155
167
  source_version?: string | null | undefined;
156
168
  submitted_by?: string | undefined;
157
169
  submitted_at?: string | undefined;
@@ -182,6 +194,8 @@ export declare const BatchSubmitSchema: z.ZodObject<{
182
194
  traces: {
183
195
  source_tool: "claude_code" | "codex_cli" | "cursor";
184
196
  source_session_id: string;
197
+ chunk_index: number;
198
+ chunk_start_turn: number;
185
199
  trace_id?: string | undefined;
186
200
  schema_version?: string | undefined;
187
201
  source_version?: string | null | undefined;
@@ -216,6 +230,8 @@ export declare const BatchSubmitSchema: z.ZodObject<{
216
230
  source_session_id: string;
217
231
  trace_id?: string | undefined;
218
232
  schema_version?: string | undefined;
233
+ chunk_index?: number | undefined;
234
+ chunk_start_turn?: number | undefined;
219
235
  source_version?: string | null | undefined;
220
236
  submitted_by?: string | undefined;
221
237
  submitted_at?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BhC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEzE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG5B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BhC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEzE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG5B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
@@ -4,6 +4,8 @@ export const NormalizedTraceSchema = z.object({
4
4
  schema_version: z.string().optional(),
5
5
  source_tool: z.enum(["claude_code", "codex_cli", "cursor"]),
6
6
  source_session_id: z.string().min(1),
7
+ chunk_index: z.number().int().nonnegative().default(0),
8
+ chunk_start_turn: z.number().int().nonnegative().default(0),
7
9
  source_version: z.string().nullable().optional(),
8
10
  submitted_by: z.string().optional(),
9
11
  submitted_at: z.string().optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"validators.js","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validators.js","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tracemarketplace/shared",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
package/src/chunker.ts ADDED
@@ -0,0 +1,104 @@
1
+ import type { NormalizedTrace, Turn } from "./types.js";
2
+ import { computeContentHash } from "./hash.js";
3
+
4
+ const MAX_OUTPUT_TOKENS = 100_000;
5
+
6
+ function sumOutputTokens(turns: Turn[]): number {
7
+ return turns.reduce((sum, t) => sum + (t.usage?.output_tokens ?? 0), 0);
8
+ }
9
+
10
+ function buildChunk(
11
+ base: NormalizedTrace,
12
+ turns: Turn[],
13
+ chunkIndex: number,
14
+ chunkStartTurn: number,
15
+ ): NormalizedTrace {
16
+ const inputTokens = turns.reduce((s, t) => s + (t.usage?.input_tokens ?? 0), 0);
17
+ const outputTokens = turns.reduce((s, t) => s + (t.usage?.output_tokens ?? 0), 0);
18
+ const toolCallCount = turns.reduce(
19
+ (s, t) => s + t.content.filter((b) => b.type === "tool_use").length,
20
+ 0,
21
+ );
22
+
23
+ const chunk: NormalizedTrace = {
24
+ ...base,
25
+ turns,
26
+ chunk_index: chunkIndex,
27
+ chunk_start_turn: chunkStartTurn,
28
+ turn_count: turns.length,
29
+ tool_call_count: toolCallCount,
30
+ has_tool_calls: toolCallCount > 0,
31
+ has_thinking_blocks: turns.some((t) =>
32
+ t.content.some((b) => b.type === "thinking"),
33
+ ),
34
+ has_file_changes: turns.some((t) =>
35
+ t.content.some(
36
+ (b) =>
37
+ b.type === "tool_use" &&
38
+ (b.tool_name === "Edit" || b.tool_name === "Write" || b.tool_name === "MultiEdit"),
39
+ ),
40
+ ),
41
+ has_shell_commands: turns.some((t) =>
42
+ t.content.some((b) => b.type === "tool_use" && b.tool_name === "Bash"),
43
+ ),
44
+ total_input_tokens: inputTokens || null,
45
+ total_output_tokens: outputTokens || null,
46
+ started_at: turns.find((t) => t.timestamp)?.timestamp ?? base.started_at,
47
+ ended_at: [...turns].reverse().find((t) => t.timestamp)?.timestamp ?? base.ended_at,
48
+ };
49
+
50
+ // Recompute trace_id and content_hash for this chunk
51
+ chunk.trace_id = computeContentHash(chunk);
52
+
53
+ return chunk;
54
+ }
55
+
56
+ /**
57
+ * Split a NormalizedTrace into chunks of at most maxOutputTokens output tokens.
58
+ * Always breaks at user-turn boundaries (never mid-assistant-response).
59
+ * If the session fits within one chunk, returns a single-element array with chunk_index=0.
60
+ */
61
+ export function chunkTrace(
62
+ trace: NormalizedTrace,
63
+ maxOutputTokens = MAX_OUTPUT_TOKENS,
64
+ ): NormalizedTrace[] {
65
+ const totalOutput = trace.total_output_tokens ?? sumOutputTokens(trace.turns);
66
+
67
+ // Fast path: fits in one chunk
68
+ if (totalOutput <= maxOutputTokens) {
69
+ return [{ ...trace, chunk_index: 0, chunk_start_turn: 0 }];
70
+ }
71
+
72
+ const chunks: NormalizedTrace[] = [];
73
+ let chunkStartTurn = 0;
74
+ let chunkOutputTokens = 0;
75
+ let chunkTurns: Turn[] = [];
76
+ let chunkIndex = 0;
77
+
78
+ for (let i = 0; i < trace.turns.length; i++) {
79
+ const turn = trace.turns[i];
80
+
81
+ // Break at user-turn boundary once we've accumulated enough
82
+ if (
83
+ turn.role === "user" &&
84
+ chunkOutputTokens >= maxOutputTokens &&
85
+ chunkTurns.length > 0
86
+ ) {
87
+ chunks.push(buildChunk(trace, chunkTurns, chunkIndex, chunkStartTurn));
88
+ chunkIndex++;
89
+ chunkStartTurn = i;
90
+ chunkOutputTokens = 0;
91
+ chunkTurns = [];
92
+ }
93
+
94
+ chunkTurns.push(turn);
95
+ chunkOutputTokens += turn.usage?.output_tokens ?? 0;
96
+ }
97
+
98
+ // Final chunk (may be < maxOutputTokens — that's fine, 2-day rule handles it)
99
+ if (chunkTurns.length > 0) {
100
+ chunks.push(buildChunk(trace, chunkTurns, chunkIndex, chunkStartTurn));
101
+ }
102
+
103
+ return chunks;
104
+ }
package/src/index.ts CHANGED
@@ -3,6 +3,8 @@ export * from "./hash.js";
3
3
  export * from "./scoring.js";
4
4
  export * from "./utils.js";
5
5
  export * from "./validators.js";
6
+ export * from "./redact.js";
7
+ export * from "./chunker.js";
6
8
  export { extractClaudeCode } from "./extractors/claude-code.js";
7
9
  export { extractCodex } from "./extractors/codex.js";
8
10
  export { extractCursor } from "./extractors/cursor.js";
package/src/redact.ts ADDED
@@ -0,0 +1,138 @@
1
+ import type { NormalizedTrace, ContentBlock, Turn } from "./types.js";
2
+
3
+ export interface RedactOptions {
4
+ /** Pass os.homedir() from the CLI — strips absolute home paths from all strings. */
5
+ homeDir?: string;
6
+ }
7
+
8
+ // ─── Secret patterns ────────────────────────────────────────────────────────
9
+ // Ordered from specific → generic to avoid partial matches being swallowed.
10
+
11
+ const SECRET_PATTERNS: Array<{ re: RegExp; label: string }> = [
12
+ // Anthropic
13
+ { re: /sk-ant-[a-zA-Z0-9\-_]{20,}/g, label: "ANTHROPIC_KEY" },
14
+ // OpenAI (must come before generic sk- catch-all)
15
+ { re: /sk-proj-[a-zA-Z0-9\-_]{20,}/g, label: "OPENAI_KEY" },
16
+ { re: /sk-[a-zA-Z0-9]{20,}/g, label: "OPENAI_KEY" },
17
+ // AWS
18
+ { re: /AKIA[0-9A-Z]{16}/g, label: "AWS_ACCESS_KEY" },
19
+ { re: /(aws_secret_access_key\s*[=:]\s*)[A-Za-z0-9/+]{40}/gi, label: "AWS_SECRET_KEY" },
20
+ // GitHub
21
+ { re: /github_pat_[a-zA-Z0-9_]{82}/g, label: "GITHUB_PAT" },
22
+ { re: /ghp_[a-zA-Z0-9]{36}/g, label: "GITHUB_TOKEN" },
23
+ { re: /ghs_[a-zA-Z0-9]{36}/g, label: "GITHUB_TOKEN" },
24
+ // Stripe
25
+ { re: /sk_live_[a-zA-Z0-9]{24,}/g, label: "STRIPE_SECRET_KEY" },
26
+ { re: /rk_live_[a-zA-Z0-9]{24,}/g, label: "STRIPE_RESTRICTED_KEY" },
27
+ // Resend
28
+ { re: /re_[a-zA-Z0-9]{32,}/g, label: "RESEND_KEY" },
29
+ // JWTs — eyJ<base64>.<base64>.<base64>
30
+ { re: /eyJ[a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]*/g, label: "JWT" },
31
+ // Bearer tokens in Authorization headers
32
+ { re: /(Bearer\s+)[a-zA-Z0-9\-._~+/]+=*/gi, label: "BEARER_TOKEN" },
33
+ // Passwords in URLs: https://user:PASSWORD@host
34
+ { re: /(https?:\/\/[^:@\s]+:)[^:@\s]+(@)/g, label: "URL_PASSWORD" },
35
+ // Database DSNs: postgres://user:PASSWORD@host
36
+ { re: /((?:postgres(?:ql)?|mysql|redis):\/\/[^:]+:)[^@\s]+(@)/g, label: "DB_PASSWORD" },
37
+ // Generic key/secret assignments: API_KEY=abc123... or secret: "abc123..."
38
+ {
39
+ re: /((?:api[_-]?key|api[_-]?secret|access[_-]?token|auth[_-]?token|private[_-]?key|client[_-]?secret)\s*[=:]\s*["']?)[a-zA-Z0-9\-_.+/]{16,}(["']?)/gi,
40
+ label: "SECRET_VALUE",
41
+ },
42
+ ];
43
+
44
+ // ─── Core string transforms ──────────────────────────────────────────────────
45
+
46
+ function stripHome(s: string, home: string): string {
47
+ return home ? s.replaceAll(home, "~") : s;
48
+ }
49
+
50
+ function stripSecrets(s: string): string {
51
+ let out = s;
52
+ for (const { re, label } of SECRET_PATTERNS) {
53
+ // Patterns with capture groups: preserve group 1 (key name), replace group 2 (value)
54
+ if (re.source.includes("(")) {
55
+ out = out.replace(re, (...args) => {
56
+ // Replace only the non-group parts; keep named prefixes intact
57
+ const groups = args.slice(1, -2) as string[];
58
+ if (groups.length === 1) return `${groups[0]}[${label}]`;
59
+ if (groups.length === 2) return `${groups[0]}[${label}]${groups[1]}`;
60
+ return `[${label}]`;
61
+ });
62
+ } else {
63
+ out = out.replace(re, `[${label}]`);
64
+ }
65
+ re.lastIndex = 0; // reset stateful global regexes
66
+ }
67
+ return out;
68
+ }
69
+
70
+ function redactString(s: string, home: string): string {
71
+ return stripSecrets(stripHome(s, home));
72
+ }
73
+
74
+ // ─── Content block traversal ─────────────────────────────────────────────────
75
+
76
+ function redactToolInput(input: Record<string, unknown>, home: string): Record<string, unknown> {
77
+ return Object.fromEntries(
78
+ Object.entries(input).map(([k, v]) => [
79
+ k,
80
+ typeof v === "string" ? redactString(v, home) : v,
81
+ ])
82
+ );
83
+ }
84
+
85
+ function redactBlock(block: ContentBlock, home: string): ContentBlock {
86
+ switch (block.type) {
87
+ case "text":
88
+ case "thinking":
89
+ return { ...block, text: redactString(block.text, home) };
90
+ case "tool_use":
91
+ return { ...block, tool_input: redactToolInput(block.tool_input, home) };
92
+ case "tool_result":
93
+ return {
94
+ ...block,
95
+ result_content: block.result_content
96
+ ? redactString(block.result_content, home)
97
+ : null,
98
+ };
99
+ default:
100
+ return block;
101
+ }
102
+ }
103
+
104
+ // ─── Public API ───────────────────────────────────────────────────────────────
105
+
106
+ /**
107
+ * Redact PII and secrets from a trace before it leaves the user's machine.
108
+ *
109
+ * Pass `homeDir: os.homedir()` from the CLI so absolute paths are stripped.
110
+ * The server runs a second pass (without homeDir) as a safety net.
111
+ */
112
+ export function redactTrace(
113
+ trace: NormalizedTrace,
114
+ opts: RedactOptions = {}
115
+ ): NormalizedTrace {
116
+ const home = opts.homeDir ?? "";
117
+
118
+ return {
119
+ ...trace,
120
+ turns: trace.turns.map(
121
+ (turn): Turn => ({
122
+ ...turn,
123
+ content: turn.content.map((b) => redactBlock(b, home)),
124
+ })
125
+ ),
126
+ env_state: trace.env_state
127
+ ? {
128
+ ...trace.env_state,
129
+ inferred_file_tree:
130
+ trace.env_state.inferred_file_tree?.map((p) => stripHome(p, home)) ?? null,
131
+ inferred_changed_files:
132
+ trace.env_state.inferred_changed_files?.map((p) => stripHome(p, home)) ?? null,
133
+ inferred_error_files:
134
+ trace.env_state.inferred_error_files?.map((p) => stripHome(p, home)) ?? null,
135
+ }
136
+ : null,
137
+ };
138
+ }
package/src/types.ts CHANGED
@@ -69,6 +69,8 @@ export interface NormalizedTrace {
69
69
  schema_version: string;
70
70
  source_tool: SourceTool;
71
71
  source_session_id: string;
72
+ chunk_index?: number; // 0-based chunk within the session (set by chunkTrace, default 0)
73
+ chunk_start_turn?: number; // turn offset in the original session (set by chunkTrace, default 0)
72
74
  source_version: string | null;
73
75
  submitted_by: string;
74
76
  submitted_at: string;
package/src/validators.ts CHANGED
@@ -5,6 +5,8 @@ export const NormalizedTraceSchema = z.object({
5
5
  schema_version: z.string().optional(),
6
6
  source_tool: z.enum(["claude_code", "codex_cli", "cursor"]),
7
7
  source_session_id: z.string().min(1),
8
+ chunk_index: z.number().int().nonnegative().default(0),
9
+ chunk_start_turn: z.number().int().nonnegative().default(0),
8
10
  source_version: z.string().nullable().optional(),
9
11
  submitted_by: z.string().optional(),
10
12
  submitted_at: z.string().optional(),