@bli-cockpit/telemetry-core 0.1.3 → 0.1.4

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.
package/dist/common.d.ts CHANGED
@@ -15,6 +15,7 @@ export declare const CaptureSourceSchema: z.ZodEnum<{
15
15
  github_state: "github_state";
16
16
  linear_state: "linear_state";
17
17
  mcp_local: "mcp_local";
18
+ claude_jsonl: "claude_jsonl";
18
19
  claude_hooks: "claude_hooks";
19
20
  manual_event: "manual_event";
20
21
  collector_runtime: "collector_runtime";
@@ -30,6 +31,7 @@ export declare const CaptureProvenanceSchema: z.ZodObject<{
30
31
  github_state: "github_state";
31
32
  linear_state: "linear_state";
32
33
  mcp_local: "mcp_local";
34
+ claude_jsonl: "claude_jsonl";
33
35
  claude_hooks: "claude_hooks";
34
36
  manual_event: "manual_event";
35
37
  collector_runtime: "collector_runtime";
package/dist/common.js CHANGED
@@ -22,6 +22,7 @@ export const CaptureSourceSchema = z.enum([
22
22
  "github_state",
23
23
  "linear_state",
24
24
  "mcp_local",
25
+ "claude_jsonl",
25
26
  "claude_hooks",
26
27
  "manual_event",
27
28
  "collector_runtime",
@@ -64,6 +64,7 @@ export declare const RawEvidenceUploadBeginRequestSchema: z.ZodObject<{
64
64
  github_state: "github_state";
65
65
  linear_state: "linear_state";
66
66
  mcp_local: "mcp_local";
67
+ claude_jsonl: "claude_jsonl";
67
68
  claude_hooks: "claude_hooks";
68
69
  manual_event: "manual_event";
69
70
  collector_runtime: "collector_runtime";
@@ -172,6 +173,7 @@ export declare const RawEvidenceUploadChunkRequestSchema: z.ZodObject<{
172
173
  github_state: "github_state";
173
174
  linear_state: "linear_state";
174
175
  mcp_local: "mcp_local";
176
+ claude_jsonl: "claude_jsonl";
175
177
  claude_hooks: "claude_hooks";
176
178
  manual_event: "manual_event";
177
179
  collector_runtime: "collector_runtime";
@@ -218,6 +220,7 @@ export declare const RawEvidenceUploadCommitRequestSchema: z.ZodObject<{
218
220
  github_state: "github_state";
219
221
  linear_state: "linear_state";
220
222
  mcp_local: "mcp_local";
223
+ claude_jsonl: "claude_jsonl";
221
224
  claude_hooks: "claude_hooks";
222
225
  manual_event: "manual_event";
223
226
  collector_runtime: "collector_runtime";
@@ -275,8 +278,23 @@ export declare const CodexSessionUploadStateSchema: z.ZodEnum<{
275
278
  not_uploaded: "not_uploaded";
276
279
  }>;
277
280
  export type CodexSessionUploadState = z.infer<typeof CodexSessionUploadStateSchema>;
281
+ /**
282
+ * The agent that produced a session transcript. `codex_session_id` keeps its
283
+ * historical name across sources; `source` disambiguates. Defaulting to
284
+ * `"codex"` keeps already-published CLI versions (which never send the field)
285
+ * working unchanged after this schema lands.
286
+ */
287
+ export declare const AgentSessionSourceSchema: z.ZodDefault<z.ZodEnum<{
288
+ codex: "codex";
289
+ claude_code: "claude_code";
290
+ }>>;
291
+ export type AgentSessionSource = z.infer<typeof AgentSessionSourceSchema>;
278
292
  export declare const CodexSessionAttributionSchema: z.ZodObject<{
279
293
  codex_session_id: z.ZodString;
294
+ source: z.ZodDefault<z.ZodEnum<{
295
+ codex: "codex";
296
+ claude_code: "claude_code";
297
+ }>>;
280
298
  observed_at: z.ZodString;
281
299
  attribution_state: z.ZodEnum<{
282
300
  attributed: "attributed";
@@ -319,6 +337,7 @@ export declare const CodexSessionAttributionReportRequestSchema: z.ZodObject<{
319
337
  github_state: "github_state";
320
338
  linear_state: "linear_state";
321
339
  mcp_local: "mcp_local";
340
+ claude_jsonl: "claude_jsonl";
322
341
  claude_hooks: "claude_hooks";
323
342
  manual_event: "manual_event";
324
343
  collector_runtime: "collector_runtime";
@@ -339,6 +358,10 @@ export declare const CodexSessionAttributionReportRequestSchema: z.ZodObject<{
339
358
  }, z.core.$strict>;
340
359
  sessions: z.ZodArray<z.ZodObject<{
341
360
  codex_session_id: z.ZodString;
361
+ source: z.ZodDefault<z.ZodEnum<{
362
+ codex: "codex";
363
+ claude_code: "claude_code";
364
+ }>>;
342
365
  observed_at: z.ZodString;
343
366
  attribution_state: z.ZodEnum<{
344
367
  attributed: "attributed";
@@ -140,9 +140,19 @@ export const CodexSessionUploadStateSchema = z.enum([
140
140
  "upload_failed",
141
141
  "not_uploaded",
142
142
  ]);
143
+ /**
144
+ * The agent that produced a session transcript. `codex_session_id` keeps its
145
+ * historical name across sources; `source` disambiguates. Defaulting to
146
+ * `"codex"` keeps already-published CLI versions (which never send the field)
147
+ * working unchanged after this schema lands.
148
+ */
149
+ export const AgentSessionSourceSchema = z
150
+ .enum(["codex", "claude_code"])
151
+ .default("codex");
143
152
  export const CodexSessionAttributionSchema = z
144
153
  .object({
145
154
  codex_session_id: NonEmptyStringSchema.max(120),
155
+ source: AgentSessionSourceSchema,
146
156
  observed_at: IsoDateTimeSchema,
147
157
  attribution_state: CodexSessionAttributionStateSchema,
148
158
  attribution_reason: SafeLabelSchema,
@@ -39,6 +39,7 @@ export declare const TelemetryIngestEventDtoSchema: z.ZodObject<{
39
39
  github_state: "github_state";
40
40
  linear_state: "linear_state";
41
41
  mcp_local: "mcp_local";
42
+ claude_jsonl: "claude_jsonl";
42
43
  claude_hooks: "claude_hooks";
43
44
  manual_event: "manual_event";
44
45
  collector_runtime: "collector_runtime";
@@ -154,6 +155,7 @@ export declare const TelemetryIngestEventDtoSchema: z.ZodObject<{
154
155
  github_state: "github_state";
155
156
  linear_state: "linear_state";
156
157
  mcp_local: "mcp_local";
158
+ claude_jsonl: "claude_jsonl";
157
159
  claude_hooks: "claude_hooks";
158
160
  manual_event: "manual_event";
159
161
  collector_runtime: "collector_runtime";
@@ -314,6 +316,7 @@ export declare const TelemetryIngestEnvelopeSchema: z.ZodObject<{
314
316
  github_state: "github_state";
315
317
  linear_state: "linear_state";
316
318
  mcp_local: "mcp_local";
319
+ claude_jsonl: "claude_jsonl";
317
320
  claude_hooks: "claude_hooks";
318
321
  manual_event: "manual_event";
319
322
  collector_runtime: "collector_runtime";
@@ -359,6 +362,7 @@ export declare const TelemetryIngestEnvelopeSchema: z.ZodObject<{
359
362
  github_state: "github_state";
360
363
  linear_state: "linear_state";
361
364
  mcp_local: "mcp_local";
365
+ claude_jsonl: "claude_jsonl";
362
366
  claude_hooks: "claude_hooks";
363
367
  manual_event: "manual_event";
364
368
  collector_runtime: "collector_runtime";
@@ -474,6 +478,7 @@ export declare const TelemetryIngestEnvelopeSchema: z.ZodObject<{
474
478
  github_state: "github_state";
475
479
  linear_state: "linear_state";
476
480
  mcp_local: "mcp_local";
481
+ claude_jsonl: "claude_jsonl";
477
482
  claude_hooks: "claude_hooks";
478
483
  manual_event: "manual_event";
479
484
  collector_runtime: "collector_runtime";
@@ -575,6 +580,7 @@ export declare const TelemetryIngestEnvelopeSchema: z.ZodObject<{
575
580
  github_state: "github_state";
576
581
  linear_state: "linear_state";
577
582
  mcp_local: "mcp_local";
583
+ claude_jsonl: "claude_jsonl";
578
584
  claude_hooks: "claude_hooks";
579
585
  manual_event: "manual_event";
580
586
  collector_runtime: "collector_runtime";
@@ -717,6 +723,7 @@ export declare const TelemetryIngestEnvelopeSchema: z.ZodObject<{
717
723
  github_state: "github_state";
718
724
  linear_state: "linear_state";
719
725
  mcp_local: "mcp_local";
726
+ claude_jsonl: "claude_jsonl";
720
727
  claude_hooks: "claude_hooks";
721
728
  manual_event: "manual_event";
722
729
  collector_runtime: "collector_runtime";
@@ -14,6 +14,7 @@ export declare const LocalCollectorConfigSchema: z.ZodObject<{
14
14
  remote_short_retention_opt_in: "remote_short_retention_opt_in";
15
15
  remote_durable_opt_in: "remote_durable_opt_in";
16
16
  }>>;
17
+ collect_claude_jsonl: z.ZodDefault<z.ZodBoolean>;
17
18
  session_file_path: z.ZodOptional<z.ZodString>;
18
19
  state_dir_path: z.ZodOptional<z.ZodString>;
19
20
  }, z.core.$strict>;
@@ -18,6 +18,10 @@ export const LocalCollectorConfigSchema = z
18
18
  "remote_durable_opt_in",
19
19
  ])
20
20
  .default("remote_durable_opt_in"),
21
+ // Per-machine escape hatch (D31): promoting the CLI to `latest` enables
22
+ // Claude transcript harvesting fleet-wide, so an operator can opt a single
23
+ // machine out without a version pin. Defaults on.
24
+ collect_claude_jsonl: z.boolean().default(true),
21
25
  session_file_path: NonEmptyStringSchema.optional(),
22
26
  state_dir_path: NonEmptyStringSchema.optional(),
23
27
  })
@@ -86,6 +86,7 @@ export declare const RiskFlagSchema: z.ZodObject<{
86
86
  github_state: "github_state";
87
87
  linear_state: "linear_state";
88
88
  mcp_local: "mcp_local";
89
+ claude_jsonl: "claude_jsonl";
89
90
  claude_hooks: "claude_hooks";
90
91
  manual_event: "manual_event";
91
92
  collector_runtime: "collector_runtime";
@@ -1 +1,26 @@
1
+ /**
2
+ * Secret-like content + file-name guards shared by the local collector
3
+ * (attribution, collection) and the dashboard commit-time guard. Keeping a
4
+ * single home means the client and server agree on exactly which transcripts
5
+ * are skipped.
6
+ *
7
+ * D13 precision: prose-shaped credential NAMES (SERVICE_ROLE, SUPABASE_ANON_KEY,
8
+ * LANGFUSE_*_KEY, api_key, ...) only trip the content guard when they carry an
9
+ * assignment + a value. A bare keyword in source code, a SQL grant, a migration
10
+ * comment, or a runbook is not a leak — and flagging it would skip every session
11
+ * that merely READ a cockpit source file, which is differential censoring
12
+ * correlated with repo and task type (the cockpit-development sessions the
13
+ * harvest cares most about). Value-shaped tokens (JWT, sk-, ghp_, PEM blocks,
14
+ * AWS key ids, Slack/Linear/Langfuse tokens) are self-identifying and stay
15
+ * blocked regardless of surrounding context.
16
+ */
17
+ /**
18
+ * File-path / file-name segments that must never be read at all. This is a
19
+ * NAME matcher (it never reads file content), so it stays broad: a file called
20
+ * `service-role.json` or a dotenv file is skipped on its name alone. The
21
+ * collector imports this instead of re-declaring it, so attribution,
22
+ * collection, and the path walk share one definition.
23
+ */
24
+ export declare const SECRET_FILE_SEGMENT_PATTERN: RegExp;
25
+ export declare function isSecretLikePathSegment(value: string): boolean;
1
26
  export declare function containsSecretLikeContent(value: string): boolean;
@@ -1,9 +1,58 @@
1
- const PRIVILEGED_SUPABASE_KEY_NAME_PATTERN = new RegExp(`\\b${["SUPABASE", "SERVICE", "ROLE", "KEY"].join("_")}\\b`, "i");
2
- const SECRET_LIKE_CONTENT_PATTERNS = [
3
- /\b(?:NEXT_PUBLIC_)?SUPABASE_ANON_KEY\b/i,
4
- PRIVILEGED_SUPABASE_KEY_NAME_PATTERN,
5
- /\bSERVICE[_\s-]?ROLE\b/i,
6
- /\b(?:api[_-]?key|access[_-]?token|refresh[_-]?token|private[_-]?key|client[_-]?secret|secret[_-]?access[_-]?key)\s*[:=]\s*["']?[A-Za-z0-9_./+=-]{12,}/i,
1
+ /**
2
+ * Secret-like content + file-name guards shared by the local collector
3
+ * (attribution, collection) and the dashboard commit-time guard. Keeping a
4
+ * single home means the client and server agree on exactly which transcripts
5
+ * are skipped.
6
+ *
7
+ * D13 precision: prose-shaped credential NAMES (SERVICE_ROLE, SUPABASE_ANON_KEY,
8
+ * LANGFUSE_*_KEY, api_key, ...) only trip the content guard when they carry an
9
+ * assignment + a value. A bare keyword in source code, a SQL grant, a migration
10
+ * comment, or a runbook is not a leak — and flagging it would skip every session
11
+ * that merely READ a cockpit source file, which is differential censoring
12
+ * correlated with repo and task type (the cockpit-development sessions the
13
+ * harvest cares most about). Value-shaped tokens (JWT, sk-, ghp_, PEM blocks,
14
+ * AWS key ids, Slack/Linear/Langfuse tokens) are self-identifying and stay
15
+ * blocked regardless of surrounding context.
16
+ */
17
+ /**
18
+ * File-path / file-name segments that must never be read at all. This is a
19
+ * NAME matcher (it never reads file content), so it stays broad: a file called
20
+ * `service-role.json` or a dotenv file is skipped on its name alone. The
21
+ * collector imports this instead of re-declaring it, so attribution,
22
+ * collection, and the path walk share one definition.
23
+ */
24
+ export const SECRET_FILE_SEGMENT_PATTERN = /(^|[/\\])(?:\.env(?:\..*)?|.*(?:secret|credential|private[_-]?key|service[_-]?role).*)$/i;
25
+ export function isSecretLikePathSegment(value) {
26
+ return SECRET_FILE_SEGMENT_PATTERN.test(value);
27
+ }
28
+ // Constructed from parts so the literal privileged key name never appears in
29
+ // this source file (the public-package pack scanner bans it as a content
30
+ // pattern, just as the original guard did).
31
+ const PRIVILEGED_SUPABASE_KEY_NAME = ["SUPABASE", "SERVICE", "ROLE", "KEY"].join("_");
32
+ /**
33
+ * Credential names that are only a leak when assigned a value (D13). The value
34
+ * shape mirrors the long-standing generic pattern: an assignment operator
35
+ * followed by a 12+ char opaque value. A bare env var reference (name only) and
36
+ * `GRANT ... TO service_role` (no assignment) do not match; the same name with
37
+ * an assigned value does.
38
+ */
39
+ const SECRET_NAME_WITH_VALUE_PATTERN = new RegExp(`\\b(?:${[
40
+ "(?:NEXT_PUBLIC_)?SUPABASE_ANON_KEY",
41
+ PRIVILEGED_SUPABASE_KEY_NAME,
42
+ "SERVICE[_\\s-]?ROLE(?:[_\\s-]?KEY)?",
43
+ "LANGFUSE_(?:PUBLIC|SECRET)_KEY",
44
+ "api[_-]?key",
45
+ "access[_-]?token",
46
+ "refresh[_-]?token",
47
+ "private[_-]?key",
48
+ "client[_-]?secret",
49
+ "secret[_-]?access[_-]?key",
50
+ ].join("|")})\\b\\s*[:=]\\s*["']?[A-Za-z0-9_./+=-]{12,}`, "i");
51
+ /**
52
+ * Self-identifying secret values — blocked regardless of context because the
53
+ * token shape itself is the credential, with no benign reading.
54
+ */
55
+ const SECRET_VALUE_PATTERNS = [
7
56
  /-----BEGIN [A-Z ]*PRIVATE KEY-----/,
8
57
  /\bBearer\s+[A-Za-z0-9._~+/=-]{16,}/,
9
58
  /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/,
@@ -15,9 +64,12 @@ const SECRET_LIKE_CONTENT_PATTERNS = [
15
64
  /\bsb_secret_[A-Za-z0-9_]{16,}/,
16
65
  /\bxox[baprs]-[A-Za-z0-9-]{16,}/,
17
66
  /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/,
18
- /\bLANGFUSE_(?:PUBLIC|SECRET)_KEY\b/i,
19
67
  /\b(?:pk|sk)-lf-[A-Za-z0-9_-]{16,}\b/i,
20
68
  ];
69
+ const SECRET_LIKE_CONTENT_PATTERNS = [
70
+ SECRET_NAME_WITH_VALUE_PATTERN,
71
+ ...SECRET_VALUE_PATTERNS,
72
+ ];
21
73
  export function containsSecretLikeContent(value) {
22
74
  return SECRET_LIKE_CONTENT_PATTERNS.some((pattern) => pattern.test(value));
23
75
  }
@@ -9,6 +9,7 @@ export declare const SourceAdapterIdentitySchema: z.ZodObject<{
9
9
  github_state: "github_state";
10
10
  linear_state: "linear_state";
11
11
  mcp_local: "mcp_local";
12
+ claude_jsonl: "claude_jsonl";
12
13
  claude_hooks: "claude_hooks";
13
14
  manual_event: "manual_event";
14
15
  collector_runtime: "collector_runtime";
@@ -87,6 +88,7 @@ export declare const SourceScanResultSchema: z.ZodObject<{
87
88
  github_state: "github_state";
88
89
  linear_state: "linear_state";
89
90
  mcp_local: "mcp_local";
91
+ claude_jsonl: "claude_jsonl";
90
92
  claude_hooks: "claude_hooks";
91
93
  manual_event: "manual_event";
92
94
  collector_runtime: "collector_runtime";
@@ -229,6 +231,7 @@ export declare const SourceScanResultSchema: z.ZodObject<{
229
231
  github_state: "github_state";
230
232
  linear_state: "linear_state";
231
233
  mcp_local: "mcp_local";
234
+ claude_jsonl: "claude_jsonl";
232
235
  claude_hooks: "claude_hooks";
233
236
  manual_event: "manual_event";
234
237
  collector_runtime: "collector_runtime";
@@ -67,6 +67,7 @@ export declare const LocalWorkContextSchema: z.ZodObject<{
67
67
  github_state: "github_state";
68
68
  linear_state: "linear_state";
69
69
  mcp_local: "mcp_local";
70
+ claude_jsonl: "claude_jsonl";
70
71
  claude_hooks: "claude_hooks";
71
72
  manual_event: "manual_event";
72
73
  collector_runtime: "collector_runtime";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bli-cockpit/telemetry-core",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",