@bli-cockpit/telemetry-core 0.1.3 → 0.1.5

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,224 @@
1
+ import { z } from "zod";
2
+ export declare const AGENT_IMAGE_ARTIFACT_MAX_FILE_BYTES: number;
3
+ export declare const AGENT_IMAGE_ARTIFACT_MAX_REPORT_ITEMS = 100;
4
+ export declare const AgentArtifactSourceSchema: z.ZodEnum<{
5
+ codex: "codex";
6
+ claude_code: "claude_code";
7
+ }>;
8
+ export type AgentArtifactSource = z.infer<typeof AgentArtifactSourceSchema>;
9
+ export declare const AgentArtifactKindSchema: z.ZodEnum<{
10
+ screenshot: "screenshot";
11
+ image_attachment: "image_attachment";
12
+ }>;
13
+ export type AgentArtifactKind = z.infer<typeof AgentArtifactKindSchema>;
14
+ export declare const AgentArtifactCaptureOriginSchema: z.ZodEnum<{
15
+ agent_session_attachment: "agent_session_attachment";
16
+ }>;
17
+ export type AgentArtifactCaptureOrigin = z.infer<typeof AgentArtifactCaptureOriginSchema>;
18
+ export declare const AgentArtifactRedactionStatusSchema: z.ZodEnum<{
19
+ not_started: "not_started";
20
+ pending: "pending";
21
+ redacted: "redacted";
22
+ safe_for_metadata: "safe_for_metadata";
23
+ blocked: "blocked";
24
+ }>;
25
+ export type AgentArtifactRedactionStatus = z.infer<typeof AgentArtifactRedactionStatusSchema>;
26
+ export declare const AgentArtifactOcrStatusSchema: z.ZodEnum<{
27
+ not_started: "not_started";
28
+ pending: "pending";
29
+ completed: "completed";
30
+ failed: "failed";
31
+ skipped: "skipped";
32
+ }>;
33
+ export type AgentArtifactOcrStatus = z.infer<typeof AgentArtifactOcrStatusSchema>;
34
+ export declare const AgentImageArtifactMediaTypeSchema: z.ZodEnum<{
35
+ "image/png": "image/png";
36
+ "image/jpeg": "image/jpeg";
37
+ }>;
38
+ export type AgentImageArtifactMediaType = z.infer<typeof AgentImageArtifactMediaTypeSchema>;
39
+ export declare const AgentImageArtifactStorageBucketSchema: z.ZodLiteral<"ambient-raw-evidence">;
40
+ export type AgentImageArtifactStorageBucket = z.infer<typeof AgentImageArtifactStorageBucketSchema>;
41
+ export declare const AgentImageArtifactStorageMetadataSchema: z.ZodObject<{
42
+ storage_bucket: z.ZodLiteral<"ambient-raw-evidence">;
43
+ object_key: z.ZodString;
44
+ content_hash_sha256: z.ZodString;
45
+ byte_size: z.ZodNumber;
46
+ media_type: z.ZodEnum<{
47
+ "image/png": "image/png";
48
+ "image/jpeg": "image/jpeg";
49
+ }>;
50
+ width: z.ZodOptional<z.ZodNumber>;
51
+ height: z.ZodOptional<z.ZodNumber>;
52
+ perceptual_hash: z.ZodOptional<z.ZodString>;
53
+ }, z.core.$strict>;
54
+ export type AgentImageArtifactStorageMetadata = z.infer<typeof AgentImageArtifactStorageMetadataSchema>;
55
+ export declare const AgentImageArtifactBindingSchema: z.ZodObject<{
56
+ operator_user_id: z.ZodOptional<z.ZodString>;
57
+ team_id: z.ZodOptional<z.ZodString>;
58
+ work_session_id: z.ZodOptional<z.ZodString>;
59
+ task_id: z.ZodOptional<z.ZodString>;
60
+ ticket_id: z.ZodOptional<z.ZodString>;
61
+ repo_fingerprint: z.ZodOptional<z.ZodString>;
62
+ worktree_fingerprint: z.ZodOptional<z.ZodString>;
63
+ }, z.core.$strict>;
64
+ export type AgentImageArtifactBinding = z.infer<typeof AgentImageArtifactBindingSchema>;
65
+ export declare const AgentImageArtifactSchema: z.ZodObject<{
66
+ storage_bucket: z.ZodLiteral<"ambient-raw-evidence">;
67
+ object_key: z.ZodString;
68
+ content_hash_sha256: z.ZodString;
69
+ byte_size: z.ZodNumber;
70
+ media_type: z.ZodEnum<{
71
+ "image/png": "image/png";
72
+ "image/jpeg": "image/jpeg";
73
+ }>;
74
+ width: z.ZodOptional<z.ZodNumber>;
75
+ height: z.ZodOptional<z.ZodNumber>;
76
+ perceptual_hash: z.ZodOptional<z.ZodString>;
77
+ operator_user_id: z.ZodOptional<z.ZodString>;
78
+ team_id: z.ZodOptional<z.ZodString>;
79
+ work_session_id: z.ZodOptional<z.ZodString>;
80
+ task_id: z.ZodOptional<z.ZodString>;
81
+ ticket_id: z.ZodOptional<z.ZodString>;
82
+ repo_fingerprint: z.ZodOptional<z.ZodString>;
83
+ worktree_fingerprint: z.ZodOptional<z.ZodString>;
84
+ artifact_id: z.ZodOptional<z.ZodString>;
85
+ raw_evidence_pointer_id: z.ZodString;
86
+ agent_source: z.ZodEnum<{
87
+ codex: "codex";
88
+ claude_code: "claude_code";
89
+ }>;
90
+ source_session_id: z.ZodString;
91
+ source_message_id: z.ZodOptional<z.ZodString>;
92
+ turn_index: z.ZodOptional<z.ZodNumber>;
93
+ occurred_at: z.ZodString;
94
+ artifact_kind: z.ZodDefault<z.ZodEnum<{
95
+ screenshot: "screenshot";
96
+ image_attachment: "image_attachment";
97
+ }>>;
98
+ capture_origin: z.ZodDefault<z.ZodEnum<{
99
+ agent_session_attachment: "agent_session_attachment";
100
+ }>>;
101
+ redaction_status: z.ZodDefault<z.ZodEnum<{
102
+ not_started: "not_started";
103
+ pending: "pending";
104
+ redacted: "redacted";
105
+ safe_for_metadata: "safe_for_metadata";
106
+ blocked: "blocked";
107
+ }>>;
108
+ ocr_status: z.ZodDefault<z.ZodEnum<{
109
+ not_started: "not_started";
110
+ pending: "pending";
111
+ completed: "completed";
112
+ failed: "failed";
113
+ skipped: "skipped";
114
+ }>>;
115
+ ocr_text_redacted: z.ZodOptional<z.ZodString>;
116
+ labels: z.ZodDefault<z.ZodObject<{
117
+ attachment_role: z.ZodOptional<z.ZodString>;
118
+ collector_upload_state: z.ZodOptional<z.ZodEnum<{
119
+ uploaded: "uploaded";
120
+ reused_existing: "reused_existing";
121
+ }>>;
122
+ source_sidecar_id: z.ZodOptional<z.ZodString>;
123
+ }, z.core.$strict>>;
124
+ }, z.core.$strict>;
125
+ export type AgentImageArtifact = z.infer<typeof AgentImageArtifactSchema>;
126
+ export declare const AgentImageArtifactReportRequestSchema: z.ZodObject<{
127
+ schema_version: z.ZodLiteral<"ambient-agent-image-artifacts.v1">;
128
+ generated_at: z.ZodString;
129
+ provenance: z.ZodObject<{
130
+ capture_source: z.ZodEnum<{
131
+ unknown: "unknown";
132
+ codex_jsonl: "codex_jsonl";
133
+ codex_otel: "codex_otel";
134
+ car_state: "car_state";
135
+ git_state: "git_state";
136
+ github_state: "github_state";
137
+ linear_state: "linear_state";
138
+ mcp_local: "mcp_local";
139
+ claude_jsonl: "claude_jsonl";
140
+ claude_hooks: "claude_hooks";
141
+ manual_event: "manual_event";
142
+ collector_runtime: "collector_runtime";
143
+ }>;
144
+ capture_adapter_version: z.ZodString;
145
+ collector_version: z.ZodString;
146
+ repo: z.ZodString;
147
+ branch: z.ZodString;
148
+ repo_label: z.ZodOptional<z.ZodString>;
149
+ repo_fingerprint: z.ZodOptional<z.ZodString>;
150
+ repo_origin_url: z.ZodOptional<z.ZodString>;
151
+ worktree_label: z.ZodOptional<z.ZodString>;
152
+ worktree_fingerprint: z.ZodOptional<z.ZodString>;
153
+ worktree_is_primary: z.ZodOptional<z.ZodBoolean>;
154
+ operator_id: z.ZodString;
155
+ session_id: z.ZodString;
156
+ work_context_id: z.ZodString;
157
+ }, z.core.$strict>;
158
+ artifacts: z.ZodArray<z.ZodObject<{
159
+ storage_bucket: z.ZodLiteral<"ambient-raw-evidence">;
160
+ object_key: z.ZodString;
161
+ content_hash_sha256: z.ZodString;
162
+ byte_size: z.ZodNumber;
163
+ media_type: z.ZodEnum<{
164
+ "image/png": "image/png";
165
+ "image/jpeg": "image/jpeg";
166
+ }>;
167
+ width: z.ZodOptional<z.ZodNumber>;
168
+ height: z.ZodOptional<z.ZodNumber>;
169
+ perceptual_hash: z.ZodOptional<z.ZodString>;
170
+ operator_user_id: z.ZodOptional<z.ZodString>;
171
+ team_id: z.ZodOptional<z.ZodString>;
172
+ work_session_id: z.ZodOptional<z.ZodString>;
173
+ task_id: z.ZodOptional<z.ZodString>;
174
+ ticket_id: z.ZodOptional<z.ZodString>;
175
+ repo_fingerprint: z.ZodOptional<z.ZodString>;
176
+ worktree_fingerprint: z.ZodOptional<z.ZodString>;
177
+ artifact_id: z.ZodOptional<z.ZodString>;
178
+ raw_evidence_pointer_id: z.ZodString;
179
+ agent_source: z.ZodEnum<{
180
+ codex: "codex";
181
+ claude_code: "claude_code";
182
+ }>;
183
+ source_session_id: z.ZodString;
184
+ source_message_id: z.ZodOptional<z.ZodString>;
185
+ turn_index: z.ZodOptional<z.ZodNumber>;
186
+ occurred_at: z.ZodString;
187
+ artifact_kind: z.ZodDefault<z.ZodEnum<{
188
+ screenshot: "screenshot";
189
+ image_attachment: "image_attachment";
190
+ }>>;
191
+ capture_origin: z.ZodDefault<z.ZodEnum<{
192
+ agent_session_attachment: "agent_session_attachment";
193
+ }>>;
194
+ redaction_status: z.ZodDefault<z.ZodEnum<{
195
+ not_started: "not_started";
196
+ pending: "pending";
197
+ redacted: "redacted";
198
+ safe_for_metadata: "safe_for_metadata";
199
+ blocked: "blocked";
200
+ }>>;
201
+ ocr_status: z.ZodDefault<z.ZodEnum<{
202
+ not_started: "not_started";
203
+ pending: "pending";
204
+ completed: "completed";
205
+ failed: "failed";
206
+ skipped: "skipped";
207
+ }>>;
208
+ ocr_text_redacted: z.ZodOptional<z.ZodString>;
209
+ labels: z.ZodDefault<z.ZodObject<{
210
+ attachment_role: z.ZodOptional<z.ZodString>;
211
+ collector_upload_state: z.ZodOptional<z.ZodEnum<{
212
+ uploaded: "uploaded";
213
+ reused_existing: "reused_existing";
214
+ }>>;
215
+ source_sidecar_id: z.ZodOptional<z.ZodString>;
216
+ }, z.core.$strict>>;
217
+ }, z.core.$strict>>;
218
+ }, z.core.$strict>;
219
+ export type AgentImageArtifactReportRequest = z.infer<typeof AgentImageArtifactReportRequestSchema>;
220
+ export declare const AgentImageArtifactReportResponseSchema: z.ZodObject<{
221
+ ok: z.ZodLiteral<true>;
222
+ recorded_count: z.ZodNumber;
223
+ }, z.core.$strict>;
224
+ export type AgentImageArtifactReportResponse = z.infer<typeof AgentImageArtifactReportResponseSchema>;
@@ -0,0 +1,141 @@
1
+ import { z } from "zod";
2
+ import { CaptureProvenanceSchema, IsoDateTimeSchema, NonEmptyStringSchema, Sha256Schema, } from "./common.js";
3
+ export const AGENT_IMAGE_ARTIFACT_MAX_FILE_BYTES = 10 * 1024 * 1024;
4
+ export const AGENT_IMAGE_ARTIFACT_MAX_REPORT_ITEMS = 100;
5
+ const UuidSchema = z.string().uuid();
6
+ export const AgentArtifactSourceSchema = z.enum(["codex", "claude_code"]);
7
+ export const AgentArtifactKindSchema = z.enum([
8
+ "screenshot",
9
+ "image_attachment",
10
+ ]);
11
+ export const AgentArtifactCaptureOriginSchema = z.enum([
12
+ "agent_session_attachment",
13
+ ]);
14
+ export const AgentArtifactRedactionStatusSchema = z.enum([
15
+ "not_started",
16
+ "pending",
17
+ "redacted",
18
+ "safe_for_metadata",
19
+ "blocked",
20
+ ]);
21
+ export const AgentArtifactOcrStatusSchema = z.enum([
22
+ "not_started",
23
+ "pending",
24
+ "completed",
25
+ "failed",
26
+ "skipped",
27
+ ]);
28
+ export const AgentImageArtifactMediaTypeSchema = z.enum([
29
+ "image/png",
30
+ "image/jpeg",
31
+ ]);
32
+ export const AgentImageArtifactStorageBucketSchema = z.literal("ambient-raw-evidence");
33
+ const AgentImageArtifactLabelsSchema = z
34
+ .object({
35
+ attachment_role: NonEmptyStringSchema.max(160).optional(),
36
+ collector_upload_state: z
37
+ .enum(["uploaded", "reused_existing"])
38
+ .optional(),
39
+ source_sidecar_id: NonEmptyStringSchema.max(160).optional(),
40
+ })
41
+ .strict();
42
+ const AgentImageArtifactStorageMetadataShape = {
43
+ storage_bucket: AgentImageArtifactStorageBucketSchema,
44
+ object_key: NonEmptyStringSchema,
45
+ content_hash_sha256: Sha256Schema,
46
+ byte_size: z
47
+ .number()
48
+ .int()
49
+ .positive()
50
+ .max(AGENT_IMAGE_ARTIFACT_MAX_FILE_BYTES),
51
+ media_type: AgentImageArtifactMediaTypeSchema,
52
+ width: z.number().int().positive().optional(),
53
+ height: z.number().int().positive().optional(),
54
+ perceptual_hash: NonEmptyStringSchema.optional(),
55
+ };
56
+ export const AgentImageArtifactStorageMetadataSchema = z
57
+ .object(AgentImageArtifactStorageMetadataShape)
58
+ .strict()
59
+ .superRefine((metadata, context) => {
60
+ if ((metadata.width === undefined && metadata.height !== undefined) ||
61
+ (metadata.width !== undefined && metadata.height === undefined)) {
62
+ context.addIssue({
63
+ code: "custom",
64
+ message: "image dimensions must include both width and height",
65
+ path: metadata.width === undefined ? ["width"] : ["height"],
66
+ });
67
+ }
68
+ });
69
+ const AgentImageArtifactBindingShape = {
70
+ operator_user_id: UuidSchema.optional(),
71
+ team_id: UuidSchema.optional(),
72
+ work_session_id: UuidSchema.optional(),
73
+ task_id: UuidSchema.optional(),
74
+ ticket_id: NonEmptyStringSchema.max(80).optional(),
75
+ repo_fingerprint: NonEmptyStringSchema.max(160).optional(),
76
+ worktree_fingerprint: NonEmptyStringSchema.max(160).optional(),
77
+ };
78
+ export const AgentImageArtifactBindingSchema = z
79
+ .object(AgentImageArtifactBindingShape)
80
+ .strict();
81
+ export const AgentImageArtifactSchema = z
82
+ .object({
83
+ artifact_id: UuidSchema.optional(),
84
+ raw_evidence_pointer_id: NonEmptyStringSchema,
85
+ agent_source: AgentArtifactSourceSchema,
86
+ source_session_id: NonEmptyStringSchema.max(160),
87
+ source_message_id: NonEmptyStringSchema.max(240).optional(),
88
+ turn_index: z.number().int().nonnegative().optional(),
89
+ occurred_at: IsoDateTimeSchema,
90
+ artifact_kind: AgentArtifactKindSchema.default("image_attachment"),
91
+ capture_origin: AgentArtifactCaptureOriginSchema.default("agent_session_attachment"),
92
+ redaction_status: AgentArtifactRedactionStatusSchema.default("not_started"),
93
+ ocr_status: AgentArtifactOcrStatusSchema.default("not_started"),
94
+ ocr_text_redacted: z.string().trim().min(1).max(50000).optional(),
95
+ labels: AgentImageArtifactLabelsSchema.default({}),
96
+ ...AgentImageArtifactBindingShape,
97
+ ...AgentImageArtifactStorageMetadataShape,
98
+ })
99
+ .strict()
100
+ .superRefine((artifact, context) => {
101
+ if ((artifact.width === undefined && artifact.height !== undefined) ||
102
+ (artifact.width !== undefined && artifact.height === undefined)) {
103
+ context.addIssue({
104
+ code: "custom",
105
+ message: "image dimensions must include both width and height",
106
+ path: artifact.width === undefined ? ["width"] : ["height"],
107
+ });
108
+ }
109
+ if (artifact.ocr_text_redacted && artifact.ocr_status !== "completed") {
110
+ context.addIssue({
111
+ code: "custom",
112
+ message: "redacted OCR text requires completed OCR status",
113
+ path: ["ocr_status"],
114
+ });
115
+ }
116
+ if (artifact.ocr_text_redacted &&
117
+ !["redacted", "safe_for_metadata"].includes(artifact.redaction_status)) {
118
+ context.addIssue({
119
+ code: "custom",
120
+ message: "redacted OCR text requires redacted metadata status",
121
+ path: ["redaction_status"],
122
+ });
123
+ }
124
+ });
125
+ export const AgentImageArtifactReportRequestSchema = z
126
+ .object({
127
+ schema_version: z.literal("ambient-agent-image-artifacts.v1"),
128
+ generated_at: IsoDateTimeSchema,
129
+ provenance: CaptureProvenanceSchema,
130
+ artifacts: z
131
+ .array(AgentImageArtifactSchema)
132
+ .min(1)
133
+ .max(AGENT_IMAGE_ARTIFACT_MAX_REPORT_ITEMS),
134
+ })
135
+ .strict();
136
+ export const AgentImageArtifactReportResponseSchema = z
137
+ .object({
138
+ ok: z.literal(true),
139
+ recorded_count: z.number().int().nonnegative(),
140
+ })
141
+ .strict();
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";
@@ -262,10 +265,10 @@ export type RawEvidenceUploadCommitResponse = z.infer<typeof RawEvidenceUploadCo
262
265
  * pack or silently dropped. No content-bearing fields are allowed.
263
266
  */
264
267
  export declare const CodexSessionAttributionStateSchema: z.ZodEnum<{
268
+ skipped: "skipped";
265
269
  attributed: "attributed";
266
270
  ambiguous: "ambiguous";
267
271
  unattributed: "unattributed";
268
- skipped: "skipped";
269
272
  }>;
270
273
  export type CodexSessionAttributionState = z.infer<typeof CodexSessionAttributionStateSchema>;
271
274
  export declare const CodexSessionUploadStateSchema: z.ZodEnum<{
@@ -275,14 +278,29 @@ 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<{
300
+ skipped: "skipped";
282
301
  attributed: "attributed";
283
302
  ambiguous: "ambiguous";
284
303
  unattributed: "unattributed";
285
- skipped: "skipped";
286
304
  }>;
287
305
  attribution_reason: z.ZodString;
288
306
  attribution_score: z.ZodOptional<z.ZodNumber>;
@@ -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,12 +358,16 @@ 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<{
367
+ skipped: "skipped";
344
368
  attributed: "attributed";
345
369
  ambiguous: "ambiguous";
346
370
  unattributed: "unattributed";
347
- skipped: "skipped";
348
371
  }>;
349
372
  attribution_reason: z.ZodString;
350
373
  attribution_score: z.ZodOptional<z.ZodNumber>;
@@ -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,
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from "./agent-artifacts.js";
1
2
  export * from "./common.js";
2
3
  export * from "./evidence-upload.js";
3
4
  export * from "./ingest-dto.js";
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export * from "./agent-artifacts.js";
1
2
  export * from "./common.js";
2
3
  export * from "./evidence-upload.js";
3
4
  export * from "./ingest-dto.js";
@@ -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";
@@ -73,8 +74,8 @@ export declare const TelemetryIngestEventDtoSchema: z.ZodObject<{
73
74
  remote_durable_raw_evidence: "remote_durable_raw_evidence";
74
75
  }>;
75
76
  redaction_status: z.ZodEnum<{
76
- metadata_only: "metadata_only";
77
77
  redacted: "redacted";
78
+ metadata_only: "metadata_only";
78
79
  raw_local_only: "raw_local_only";
79
80
  raw_remote_short_retention: "raw_remote_short_retention";
80
81
  raw_remote_durable: "raw_remote_durable";
@@ -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";
@@ -393,8 +397,8 @@ export declare const TelemetryIngestEnvelopeSchema: z.ZodObject<{
393
397
  remote_durable_raw_evidence: "remote_durable_raw_evidence";
394
398
  }>;
395
399
  redaction_status: z.ZodEnum<{
396
- metadata_only: "metadata_only";
397
400
  redacted: "redacted";
401
+ metadata_only: "metadata_only";
398
402
  raw_local_only: "raw_local_only";
399
403
  raw_remote_short_retention: "raw_remote_short_retention";
400
404
  raw_remote_durable: "raw_remote_durable";
@@ -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";
@@ -584,10 +590,10 @@ export declare const TelemetryIngestEnvelopeSchema: z.ZodObject<{
584
590
  }, z.core.$strict>;
585
591
  work_context_id: z.ZodOptional<z.ZodString>;
586
592
  status: z.ZodEnum<{
587
- ok: "ok";
593
+ failed: "failed";
588
594
  skipped: "skipped";
595
+ ok: "ok";
589
596
  partial: "partial";
590
- failed: "failed";
591
597
  }>;
592
598
  started_at: z.ZodString;
593
599
  finished_at: z.ZodOptional<z.ZodString>;
@@ -605,8 +611,8 @@ export declare const TelemetryIngestEnvelopeSchema: z.ZodObject<{
605
611
  remote_durable_raw_evidence: "remote_durable_raw_evidence";
606
612
  }>;
607
613
  redaction_status: z.ZodEnum<{
608
- metadata_only: "metadata_only";
609
614
  redacted: "redacted";
615
+ metadata_only: "metadata_only";
610
616
  raw_local_only: "raw_local_only";
611
617
  raw_remote_short_retention: "raw_remote_short_retention";
612
618
  raw_remote_durable: "raw_remote_durable";
@@ -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
  })
package/dist/privacy.d.ts CHANGED
@@ -77,8 +77,8 @@ export declare const RedactionMetadataSchema: z.ZodObject<{
77
77
  remote_durable_raw_evidence: "remote_durable_raw_evidence";
78
78
  }>;
79
79
  redaction_status: z.ZodEnum<{
80
- metadata_only: "metadata_only";
81
80
  redacted: "redacted";
81
+ metadata_only: "metadata_only";
82
82
  raw_local_only: "raw_local_only";
83
83
  raw_remote_short_retention: "raw_remote_short_retention";
84
84
  raw_remote_durable: "raw_remote_durable";
@@ -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";
@@ -30,8 +31,8 @@ export declare const SourceScanEventSummarySchema: z.ZodObject<{
30
31
  remote_durable_raw_evidence: "remote_durable_raw_evidence";
31
32
  }>;
32
33
  redaction_status: z.ZodEnum<{
33
- metadata_only: "metadata_only";
34
34
  redacted: "redacted";
35
+ metadata_only: "metadata_only";
35
36
  raw_local_only: "raw_local_only";
36
37
  raw_remote_short_retention: "raw_remote_short_retention";
37
38
  raw_remote_durable: "raw_remote_durable";
@@ -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";
@@ -96,10 +98,10 @@ export declare const SourceScanResultSchema: z.ZodObject<{
96
98
  }, z.core.$strict>;
97
99
  work_context_id: z.ZodOptional<z.ZodString>;
98
100
  status: z.ZodEnum<{
99
- ok: "ok";
101
+ failed: "failed";
100
102
  skipped: "skipped";
103
+ ok: "ok";
101
104
  partial: "partial";
102
- failed: "failed";
103
105
  }>;
104
106
  started_at: z.ZodString;
105
107
  finished_at: z.ZodOptional<z.ZodString>;
@@ -117,8 +119,8 @@ export declare const SourceScanResultSchema: z.ZodObject<{
117
119
  remote_durable_raw_evidence: "remote_durable_raw_evidence";
118
120
  }>;
119
121
  redaction_status: z.ZodEnum<{
120
- metadata_only: "metadata_only";
121
122
  redacted: "redacted";
123
+ metadata_only: "metadata_only";
122
124
  raw_local_only: "raw_local_only";
123
125
  raw_remote_short_retention: "raw_remote_short_retention";
124
126
  raw_remote_durable: "raw_remote_durable";
@@ -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.5",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",