@gobing-ai/ts-llm-jsonl-importer 0.4.41 → 0.4.43

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/README.md CHANGED
@@ -9,7 +9,7 @@ Generic JSONL import pipeline for AI-agent history-style files: discover files,
9
9
  | Export | Purpose |
10
10
  |--------|---------|
11
11
  | `runJsonlImport()` | Runs discovery, parsing, validation, redaction, dedupe, and persistence. Accepts a built-in source string **or** a custom `SourceDefinition`. |
12
- | `applyHistoryImportSchema()` | Installs importer-owned checkpoint, ledger, and ETL tables |
12
+ | `applyHistoryImportSchema()` | Installs importer-owned checkpoint, ledger, and typed contract tables |
13
13
  | `SOURCE_DEFINITIONS` | Built-in source definitions |
14
14
  | `getSourceDefinition()` | Returns one built-in definition by key (throws `HistoryImportError` for unknown keys) |
15
15
  | `resolveSourceDefinition()` | Resolves a `string \| SourceDefinition` into a validated definition |
@@ -19,7 +19,7 @@ Generic JSONL import pipeline for AI-agent history-style files: discover files,
19
19
  | `sha256()` / `stableJson()` | Stable hash helpers used by the ledger |
20
20
  | `HISTORY_IMPORT_SCHEMA_SQL` | SQL schema string for explicit migration flows |
21
21
 
22
- Built-in source keys are `claude`, `codex`, `gemini`, `pi`, `opencode`, `antigravity`, and `openclaw`.
22
+ Built-in source keys are `claude`, `codex`, `gemini`, `pi`, `opencode`, `antigravity`, `openclaw`, `omp`, `grok`, and `agy`.
23
23
 
24
24
  ## Installation
25
25
 
@@ -127,13 +127,18 @@ The schema contains:
127
127
  |-------|---------|
128
128
  | `history_import_checkpoint` | Per-source/per-file last imported line |
129
129
  | `history_import_ledger` | Stable hash ledger for dedupe and provenance |
130
- | `history_etl_<source>` | Redacted normalized payloads for each built-in source |
130
+ | `history_message` | Typed normalized messages from built-in forensic mappers |
131
+ | `history_tool_call` | Typed normalized tool calls from built-in forensic mappers |
132
+ | `history_etl_<source>` | Redacted payloads for generic/custom definitions; created only after an accepted row targets one |
131
133
 
132
- ETL tables store the normalized payload JSON plus source file, source line, split index, hash, and timestamps.
134
+ Generic ETL tables store normalized payload JSON plus source file, source line, split index, hash, and timestamps.
135
+ Schema setup, empty scans, validation failures, and dry runs do not create empty ETL tables.
136
+ Claude tool results copy native `toolUseResult.durationMs` or `durationSeconds` into `duration_ms`; absent timing
137
+ stays `NULL` and is never inferred from message timestamps.
133
138
 
134
139
  ## Split Records
135
140
 
136
- Most sources are one input row to one ETL row. A source can also split one JSONL row into multiple ETL records. The built-in `pi` definition splits nested `messages` into one row per message when present.
141
+ A source can split one JSONL row into several typed or generic records. Built-in source mappers normalize supported records into `history_message` and `history_tool_call`; custom definitions may target a generic ETL table.
137
142
 
138
143
  ```ts
139
144
  const result = await runJsonlImport('pi', { db, files: ['session.jsonl'], mode: 'full' });
@@ -1 +1 @@
1
- {"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../src/importer.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAER,aAAa,EACb,YAAY,EAGZ,gBAAgB,EAEnB,MAAM,SAAS,CAAC;AAoFjB;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAsTrH"}
1
+ {"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../src/importer.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAER,aAAa,EACb,YAAY,EAGZ,gBAAgB,EAEnB,MAAM,SAAS,CAAC;AAoFjB;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CA0YrH"}
package/dist/importer.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ambientRuntimePaths, createNodeFileSystem, resolvePath, walkDir, } from '@gobing-ai/ts-runtime';
2
2
  import { sha256 } from './hash.js';
3
- import { applyHistoryImportSchema, checkpointUpsertOp, ensureTargetTables, ledgerExistingHashes, ledgerInsertOp, readCheckpoint, reconcileFullImport, recordInsertOp, resetCheckpoints, targetTableFor, toolCallDurationUpdateOp, toolCallResultBytesUpdateOp, } from './jsonl-importer-dao.js';
3
+ import { applyHistoryImportSchema, checkpointUpsertOp, ensureTargetTable, ledgerExistingHashes, ledgerInsertOp, loadSourceCheckpoints, reconcileFullImport, recordInsertOp, resetCheckpoints, targetTableFor, toolCallDurationUpdateOp, toolCallResultBytesUpdateOp, } from './jsonl-importer-dao.js';
4
4
  import { claudeToolResultTiming, ompToolResultTiming, timestampToEpochMs } from './mappers.js';
5
5
  import { redactRecord } from './redaction.js';
6
6
  import { resolveSourceDefinition } from './sources.js';
@@ -52,7 +52,6 @@ export async function runJsonlImport(source, options) {
52
52
  const resolvedSource = definition.source;
53
53
  const fileSystem = options.fileSystem ?? createNodeFileSystem();
54
54
  await applyHistoryImportSchema(options.db);
55
- await ensureTargetTables(options.db, definition);
56
55
  const mode = options.mode ?? 'incremental';
57
56
  const files = await discoverFiles(definition, options.roots, options.files, fileSystem, options.paths);
58
57
  if (mode === 'full' && !options.dryRun) {
@@ -65,15 +64,33 @@ export async function runJsonlImport(source, options) {
65
64
  let skippedDuplicates = 0;
66
65
  let unknownRecords = 0;
67
66
  let skippedCorruptLines = 0;
67
+ let skippedUnchangedFiles = 0;
68
68
  let checkpointUpdates = 0;
69
+ const ensuredTargetTables = new Set();
69
70
  // Full-mode desired set (R1, task 0504): every record hash the current source produces.
70
71
  // ReconcileFullImport diffs this against the persisted ledger to retire stale rows.
71
72
  const desiredHashes = new Set();
72
73
  // Task 0564 R1: tool-call rows emitted by earlier assistant lines, keyed by
73
74
  // (source, session_id, call_id) so a later toolResult line can attach its duration.
74
75
  const toolCallRows = new Map();
76
+ // 0678 R3: codex token_count events carry usage on a meta row; the numbers belong
77
+ // to the most recent assistant message of that session.
78
+ const codexLastAssistant = new Map();
79
+ // 0675 R5: one query per source replaces the per-file SELECT in this loop.
80
+ // Only incremental mode consults checkpoints; full/force-file read everything.
81
+ const checkpoints = mode === 'incremental' ? await loadSourceCheckpoints(options.db, resolvedSource) : undefined;
75
82
  for (const file of files) {
76
- const checkpoint = mode === 'incremental' ? await readCheckpoint(options.db, resolvedSource, file) : 0;
83
+ const entry = checkpoints?.get(file);
84
+ const checkpoint = entry?.line ?? 0;
85
+ if (checkpoints !== undefined && entry !== undefined && entry.size !== null && entry.mtimeMs !== null) {
86
+ // 0675 R2: identity short-circuit — skip the whole file when (size, mtimeMs) both match.
87
+ // Fail open on any stat problem; never applies to full/force-file (checkpoints is undefined there).
88
+ const stat = await safeStat(fileSystem, file);
89
+ if (stat !== null && stat.size === entry.size && stat.mtimeMs === entry.mtimeMs) {
90
+ skippedUnchangedFiles += 1;
91
+ continue;
92
+ }
93
+ }
77
94
  let lineNumber = 0;
78
95
  for await (const rawLine of readLines(fileSystem, file)) {
79
96
  lineNumber += 1;
@@ -177,6 +194,14 @@ export async function runJsonlImport(source, options) {
177
194
  }
178
195
  return true;
179
196
  });
197
+ if (!options.dryRun) {
198
+ for (const entry of accepted) {
199
+ if (ensuredTargetTables.has(entry.split.targetTable))
200
+ continue;
201
+ await ensureTargetTable(options.db, entry.split.targetTable);
202
+ ensuredTargetTables.add(entry.split.targetTable);
203
+ }
204
+ }
180
205
  // Second pass: resolve _messageSplitIndex → message_hash, then batch.
181
206
  const recordHashBySplitIndex = new Map(prepared.map((e) => [e.splitIndex, e.recordHash]));
182
207
  const ops = [];
@@ -195,10 +220,36 @@ export async function runJsonlImport(source, options) {
195
220
  }
196
221
  }
197
222
  if (!options.dryRun) {
223
+ // 0678 R3 (codex): a meta row carrying `_codexUsageCarrier` contributes its
224
+ // numbers to the latest assistant message instead of itself; with no known
225
+ // target the usage stays unattributed — never reattached to a wrong row.
226
+ const carrier = normalized._codexUsageCarrier;
227
+ delete normalized._codexUsageCarrier;
228
+ if (carrier !== undefined &&
229
+ typeof normalized.session_id === 'string' &&
230
+ codexLastAssistant.has(normalized.session_id)) {
231
+ ops.push({
232
+ sql: 'UPDATE history_message SET input_tokens = ?, output_tokens = ?, cache_read_tokens = ? WHERE record_hash = ?',
233
+ params: [
234
+ carrier.input,
235
+ carrier.output,
236
+ carrier.cacheRead,
237
+ codexLastAssistant.get(normalized.session_id),
238
+ ],
239
+ });
240
+ }
198
241
  // Record row + ledger row join one batch op pair — a crash between the two
199
242
  // writes is impossible (task 0060 F9).
200
243
  ops.push(recordInsertOp(split.targetTable, recordHash, file, lineNumber, splitIndex, normalized, options.now));
201
244
  ops.push(ledgerInsertOp(recordHash, resolvedSource, file, lineNumber, splitIndex, split.targetTable, options.now));
245
+ // 0678 R3 (codex): remember this session's latest assistant row so a
246
+ // following token_count meta row can attribute its usage to it.
247
+ if (definition.source === 'codex' &&
248
+ split.targetTable === 'history_message' &&
249
+ normalized.role === 'assistant' &&
250
+ typeof normalized.session_id === 'string') {
251
+ codexLastAssistant.set(normalized.session_id, recordHash);
252
+ }
202
253
  }
203
254
  importedRecords += 1;
204
255
  }
@@ -229,11 +280,10 @@ export async function runJsonlImport(source, options) {
229
280
  }
230
281
  }
231
282
  }
232
- // Task 0624 R2 (claude): attach result sizes from this line's
283
+ // Task 0624 R2 (claude): attach native durations and result sizes from this line's
233
284
  // tool_result blocks. Pairing is by `tool_use_id` → `call_id`
234
285
  // (source ∘ session ∘ call), the same key the omp branch uses.
235
- // No duration is written — claude has no native wall time and the
236
- // guarded timestamp fallback does not extend to it (0624 Design).
286
+ // Missing native timing stays NULL; the timestamp fallback does not extend to claude.
237
287
  if (definition.source === 'claude') {
238
288
  const timing = claudeToolResultTiming(raw);
239
289
  if (timing !== null) {
@@ -246,6 +296,9 @@ export async function runJsonlImport(source, options) {
246
296
  }
247
297
  if (pending !== undefined) {
248
298
  ops.push(toolCallResultBytesUpdateOp(pending.recordHash, timing.resultBytes));
299
+ if (timing.durationMs !== undefined) {
300
+ ops.push(toolCallDurationUpdateOp(pending.recordHash, null, null, timing.durationMs));
301
+ }
249
302
  }
250
303
  }
251
304
  }
@@ -258,11 +311,31 @@ export async function runJsonlImport(source, options) {
258
311
  checkpointUpdates += 1;
259
312
  }
260
313
  }
314
+ // 0675 R1/R4: stamp file identity once per READ file (never for skipped ones).
315
+ // This is also what self-heals legacy rows whose stored identity is NULL — without
316
+ // it a fully-imported database never arms the short-circuit. Skipped when nothing
317
+ // changed since the stored checkpoint to keep no-op runs write-free. Degraded
318
+ // entries (pre-migration database without identity columns, 0678 fail-open) keep
319
+ // the old line-only write shape via checkpointUpsertOp's optional identity.
320
+ if (!options.dryRun && mode === 'incremental') {
321
+ const statAfter = await safeStat(fileSystem, file);
322
+ // Degraded = a STORED entry without identity (pre-migration database, 0678
323
+ // fail-open). No stored entry means first-ever import: stamp normally.
324
+ const identityDegraded = entry !== undefined && entry.size === null && entry.mtimeMs === null;
325
+ const identityChanged = entry !== undefined &&
326
+ (entry.size !== (statAfter?.size ?? null) || entry.mtimeMs !== (statAfter?.mtimeMs ?? null));
327
+ if (statAfter !== null && !identityDegraded && (entry === undefined || identityChanged)) {
328
+ await options.db.batch([
329
+ checkpointUpsertOp(resolvedSource, file, Math.max(lineNumber, checkpoint), options.now, {
330
+ size: statAfter.size,
331
+ mtimeMs: statAfter.mtimeMs,
332
+ }),
333
+ ]);
334
+ checkpointUpdates += 1;
335
+ }
336
+ }
261
337
  }
262
338
  }
263
- // Full-mode reconciliation (R1, task 0504): diff the desired hash set against the
264
- // persisted ledger and retire stale derived rows (target, tool, ledger, checkpoint) in
265
- // one source-scoped batch. Dry-run computes the identical counts without mutation.
266
339
  let reconciliation;
267
340
  if (mode === 'full') {
268
341
  reconciliation = await reconcileFullImport(options.db, resolvedSource, desiredHashes, files, options.dryRun ?? false);
@@ -275,6 +348,7 @@ export async function runJsonlImport(source, options) {
275
348
  importedRecords,
276
349
  skippedDuplicates,
277
350
  skippedCorruptLines,
351
+ skippedUnchangedFiles,
278
352
  unknownRecords,
279
353
  parseErrors,
280
354
  validationErrors,
@@ -416,6 +490,19 @@ function matchesPattern(path, patterns) {
416
490
  return path.endsWith(pattern.replace(/^\*/, ''));
417
491
  });
418
492
  }
493
+ /**
494
+ * Stat a file for its identity, returning null on any failure (missing file, stat unsupported).
495
+ * 0675 R2: the short-circuit fails OPEN — any null falls through to the normal read path.
496
+ */
497
+ async function safeStat(fileSystem, file) {
498
+ try {
499
+ const stat = await fileSystem.stat(file);
500
+ return stat === null ? null : { size: stat.size, mtimeMs: stat.mtimeMs };
501
+ }
502
+ catch {
503
+ return null;
504
+ }
505
+ }
419
506
  /**
420
507
  * Yield lines from a file, streaming when the FileSystem supports it.
421
508
  *
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export { HistoryImportError } from './errors';
2
2
  export { sha256, stableJson } from './hash';
3
3
  export { runJsonlImport } from './importer';
4
4
  export { applyHistoryImportSchema, normalizeSourceFilePaths } from './jsonl-importer-dao';
5
+ export { sessionIdFromSourcePath } from './mappers';
5
6
  export { type OpenCodeImportOptions, runOpenCodeImport } from './opencode-importer';
6
7
  export { DEFAULT_REDACTION_RULES, redactRecord, redactValue } from './redaction';
7
8
  export { HISTORY_IMPORT_SCHEMA_SQL } from './schema-sql';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,KAAK,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EACH,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,GAC3B,MAAM,WAAW,CAAC;AACnB,YAAY,EACR,cAAc,EACd,WAAW,EACX,UAAU,EACV,aAAa,EACb,YAAY,EACZ,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,gBAAgB,GACnB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,KAAK,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EACH,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,GAC3B,MAAM,WAAW,CAAC;AACnB,YAAY,EACR,cAAc,EACd,WAAW,EACX,UAAU,EACV,aAAa,EACb,YAAY,EACZ,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,gBAAgB,GACnB,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ export { HistoryImportError } from './errors.js';
2
2
  export { sha256, stableJson } from './hash.js';
3
3
  export { runJsonlImport } from './importer.js';
4
4
  export { applyHistoryImportSchema, normalizeSourceFilePaths } from './jsonl-importer-dao.js';
5
+ export { sessionIdFromSourcePath } from './mappers.js';
5
6
  export { runOpenCodeImport } from './opencode-importer.js';
6
7
  export { DEFAULT_REDACTION_RULES, redactRecord, redactValue } from './redaction.js';
7
8
  export { HISTORY_IMPORT_SCHEMA_SQL } from './schema-sql.js';
@@ -2,6 +2,14 @@ import type { DbAdapter, DbBatchOp } from '@gobing-ai/ts-db';
2
2
  import type { ImportOptions, JsonObject, ReconcileSummary, SourceDefinition } from './types';
3
3
  interface CheckpointRow {
4
4
  readonly last_imported_line: number;
5
+ readonly source_size?: number | null;
6
+ readonly source_mtime_ms?: number | null;
7
+ }
8
+ /** File identity + line for one checkpoint row (0675 R1/R5). */
9
+ export interface SourceCheckpoint {
10
+ readonly line: number;
11
+ readonly size: number | null;
12
+ readonly mtimeMs: number | null;
5
13
  }
6
14
  declare function targetTableFor(table: string): string;
7
15
  declare function timestamp(now: ImportOptions['now']): string;
@@ -9,20 +17,19 @@ declare function ETL_TABLE_DDL(table: string): string;
9
17
  /**
10
18
  * Apply importer-owned schema to the target database.
11
19
  *
12
- * Creates the checkpoint, ledger, and typed contract tables from the static SQL, then materializes
13
- * every built-in `history_etl_*` table by looping {@link SOURCE_DEFINITIONS} through
14
- * {@link ensureTargetTables}. This keeps the migration contract "schema applied ⇒ all built-in ETL
15
- * tables exist" for callers who apply the schema and then raw-insert without a prior import.
16
- * Adding a new built-in source to {@link SOURCE_DEFINITIONS} is now the only edit needed.
20
+ * Creates the checkpoint, ledger, and typed contract tables from the static SQL.
21
+ * Generic ETL tables are created lazily with the first accepted row, so applying
22
+ * the schema or scanning an empty source never leaves vestigial empty tables.
17
23
  */
18
24
  export declare function applyHistoryImportSchema(db: ImportOptions['db']): Promise<void>;
25
+ /** Ensure one accepted record's target exists; typed targets come from the static schema. */
26
+ declare function ensureTargetTable(db: ImportOptions['db'], targetTable: string): Promise<void>;
19
27
  /**
20
28
  * Ensure the ETL table(s) for a source definition exist.
21
29
  *
22
30
  * WHY: the static {@link HISTORY_IMPORT_SCHEMA_SQL} creates only the checkpoint, ledger, and
23
- * typed contract tables. Every `history_etl_*` blob table — built-in and custom — is created here
24
- * (and by {@link applyHistoryImportSchema} looping {@link SOURCE_DEFINITIONS}). Built-in definitions
25
- * with a `splitConfig.targetTable` override also need their target table(s) created on demand. The
31
+ * typed contract tables. Callers that explicitly request a definition's generic targets use this
32
+ * helper; the import pipeline instead creates only targets reached by accepted rows. The
26
33
  * table name is already gated by
27
34
  * {@link VALID_TABLE_NAME} in {@link validateSourceDefinition} / {@link targetTableFor},
28
35
  * so it is safe to interpolate into DDL. `CREATE TABLE IF NOT EXISTS` is
@@ -30,6 +37,16 @@ export declare function applyHistoryImportSchema(db: ImportOptions['db']): Promi
30
37
  */
31
38
  declare function ensureTargetTables(db: ImportOptions['db'], definition: SourceDefinition): Promise<void>;
32
39
  declare function readCheckpoint(db: ImportOptions['db'], source: string, sourceFile: string): Promise<number>;
40
+ /**
41
+ * One query per source (0675 R5): all checkpoint rows for `source` keyed by file,
42
+ * replacing the per-file SELECT in the import loop.
43
+ *
44
+ * Fails open when the identity columns are missing (0678): a database created through a
45
+ * migration path that has not yet applied 0675's ALTERs would otherwise hard-fail every
46
+ * import. Line-level behavior degrades to pre-identity semantics — the short-circuit
47
+ * and identity stamping no-op until the columns exist.
48
+ */
49
+ export declare function loadSourceCheckpoints(db: ImportOptions['db'], source: string): Promise<Map<string, SourceCheckpoint>>;
33
50
  declare function resetCheckpoints(db: ImportOptions['db'], source: string, files: readonly string[]): Promise<void>;
34
51
  declare function writeCheckpoint(db: ImportOptions['db'], source: string, sourceFile: string, line: number, now: ImportOptions['now']): Promise<void>;
35
52
  declare function ledgerExists(db: ImportOptions['db'], recordHash: string): Promise<boolean>;
@@ -37,13 +54,16 @@ declare function ledgerExists(db: ImportOptions['db'], recordHash: string): Prom
37
54
  * INSERT op for one accepted record row (task 0060 F9). Pure builder so the
38
55
  * per-record batch path and the single-write `insertRecord` can never drift.
39
56
  * Typed tables validate unknown keys here; the caller must have ensured the
40
- * target table exists (`ensureTargetTables` runs at import start).
57
+ * target table exists (the import loop ensures accepted targets before batching).
41
58
  */
42
59
  export declare function recordInsertOp(targetTable: string, recordHash: string, sourceFile: string, sourceLine: number, splitIndex: number, payload: JsonObject, now: ImportOptions['now']): DbBatchOp;
43
60
  /** INSERT op for one ledger row (task 0060 F9). */
44
61
  export declare function ledgerInsertOp(recordHash: string, source: string, sourceFile: string, sourceLine: number, splitIndex: number, targetTable: string, now: ImportOptions['now']): DbBatchOp;
45
62
  /** UPSERT op for one checkpoint row (task 0060 F9: checkpoint joins the record batch). */
46
- export declare function checkpointUpsertOp(source: string, sourceFile: string, line: number, now: ImportOptions['now']): DbBatchOp;
63
+ export declare function checkpointUpsertOp(source: string, sourceFile: string, line: number, now: ImportOptions['now'], identity?: {
64
+ readonly size: number | null;
65
+ readonly mtimeMs: number | null;
66
+ }): DbBatchOp;
47
67
  /**
48
68
  * Targeted UPDATE op attaching a tool duration to a previously-inserted
49
69
  * `history_tool_call` row (task 0564 R1). Keyed by `record_hash` (PK), never an
@@ -141,5 +161,5 @@ export declare function deleteCheckpointOperation(source: string, sourceFile: st
141
161
  /** Build batched history, ledger, and checkpoint writes for OpenCode entries. */
142
162
  export declare function openCodeBulkWriteOperations(entries: readonly OpenCodeQueuedEntry[], checkpointFiles: readonly string[], now: ImportOptions['now']): DbBatchOp[];
143
163
  export type { CheckpointRow };
144
- export { ETL_TABLE_DDL, ensureTargetTables, insertLedger, insertRecord, ledgerExists, readCheckpoint, reconcileFullImport, resetCheckpoints, targetTableFor, timestamp, toolCallDurationUpdateOp, toolCallResultBytesUpdateOp, writeCheckpoint, };
164
+ export { ETL_TABLE_DDL, ensureTargetTable, ensureTargetTables, insertLedger, insertRecord, ledgerExists, readCheckpoint, reconcileFullImport, resetCheckpoints, targetTableFor, timestamp, toolCallDurationUpdateOp, toolCallResultBytesUpdateOp, writeCheckpoint, };
145
165
  //# sourceMappingURL=jsonl-importer-dao.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"jsonl-importer-dao.d.ts","sourceRoot":"","sources":["../src/jsonl-importer-dao.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAI7D,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE7F,UAAU,aAAa;IACnB,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACvC;AAwDD,iBAAS,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED,iBAAS,SAAS,CAAC,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,MAAM,CAEpD;AAED,iBAAS,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS5C;AAED;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAUrF;AAED;;;;;;;;;;;GAWG;AACH,iBAAe,kBAAkB,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAUtG;AAED,iBAAe,cAAc,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO1G;AAED,iBAAe,gBAAgB,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhH;AAED,iBAAe,eAAe,CAC1B,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,EACvB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,iBAAe,YAAY,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMzF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC1B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,EACnB,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,GAC1B,SAAS,CAmCX;AAED,mDAAmD;AACnD,wBAAgB,cAAc,CAC1B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,GAC1B,SAAS,CAMX;AAED,0FAA0F;AAC1F,wBAAgB,kBAAkB,CAC9B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,GAC1B,SAAS,CASX;AAED;;;;;;;;GAQG;AACH,iBAAS,wBAAwB,CAC7B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,GAC1B,SAAS,CAOX;AAED;;;GAGG;AACH,iBAAS,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,CAOvF;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAYnH;AAED,iBAAe,YAAY,CACvB,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,EACvB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,EACnB,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,iBAAe,YAAY,CACvB,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,EACvB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,wBAAwB,CAC1C,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,EACvB,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,GACnE,OAAO,CAAC,IAAI,CAAC,CAWf;AA6FD;;;;;;;;;;;GAWG;AACH,iBAAe,mBAAmB,CAC9B,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,EACvB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,EAClC,eAAe,EAAE,SAAS,MAAM,EAAE,EAClC,MAAM,EAAE,OAAO,GAChB,OAAO,CAAC,gBAAgB,CAAC,CA6C3B;AAID,4DAA4D;AAC5D,MAAM,WAAW,kBAAkB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,iDAAiD;AACjD,MAAM,WAAW,qBAAqB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,gEAAgE;AAChE,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,iBAAiB,GAAG,mBAAmB,CAAC;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,4EAA4E;AAC5E,wBAAsB,oBAAoB,CACtC,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACd,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAa/B;AAED,qEAAqE;AACrE,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAShH;AAED,0EAA0E;AAC1E,wBAAsB,2BAA2B,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,qBAAqB,EAAE,CAAC,CAAC,CAY9G;AAED,2EAA2E;AAC3E,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,GAAG,SAAS,EAAE,CAW/F;AAED,6DAA6D;AAC7D,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,CAKvF;AAED,iFAAiF;AACjF,wBAAgB,2BAA2B,CACvC,OAAO,EAAE,SAAS,mBAAmB,EAAE,EACvC,eAAe,EAAE,SAAS,MAAM,EAAE,EAClC,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,GAC1B,SAAS,EAAE,CA0Db;AAED,YAAY,EAAE,aAAa,EAAE,CAAC;AAC9B,OAAO,EACH,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,SAAS,EACT,wBAAwB,EACxB,2BAA2B,EAC3B,eAAe,GAClB,CAAC"}
1
+ {"version":3,"file":"jsonl-importer-dao.d.ts","sourceRoot":"","sources":["../src/jsonl-importer-dao.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { HistoryImportError } from './errors.js';
2
2
  import { HISTORY_IMPORT_SCHEMA_SQL } from './schema-sql.js';
3
- import { SOURCE_DEFINITIONS, VALID_TABLE_NAME } from './sources.js';
3
+ import { VALID_TABLE_NAME } from './sources.js';
4
4
  /** Column allowlist per typed contract table; order is the INSERT column order. */
5
5
  const TYPED_TABLE_COLUMNS = {
6
6
  history_message: [
@@ -75,11 +75,9 @@ function ETL_TABLE_DDL(table) {
75
75
  /**
76
76
  * Apply importer-owned schema to the target database.
77
77
  *
78
- * Creates the checkpoint, ledger, and typed contract tables from the static SQL, then materializes
79
- * every built-in `history_etl_*` table by looping {@link SOURCE_DEFINITIONS} through
80
- * {@link ensureTargetTables}. This keeps the migration contract "schema applied ⇒ all built-in ETL
81
- * tables exist" for callers who apply the schema and then raw-insert without a prior import.
82
- * Adding a new built-in source to {@link SOURCE_DEFINITIONS} is now the only edit needed.
78
+ * Creates the checkpoint, ledger, and typed contract tables from the static SQL.
79
+ * Generic ETL tables are created lazily with the first accepted row, so applying
80
+ * the schema or scanning an empty source never leaves vestigial empty tables.
83
81
  */
84
82
  export async function applyHistoryImportSchema(db) {
85
83
  for (const statement of HISTORY_IMPORT_SCHEMA_SQL.split(';')) {
@@ -88,17 +86,19 @@ export async function applyHistoryImportSchema(db) {
88
86
  await db.exec(sql);
89
87
  }
90
88
  }
91
- for (const definition of Object.values(SOURCE_DEFINITIONS)) {
92
- await ensureTargetTables(db, definition);
93
- }
89
+ }
90
+ /** Ensure one accepted record's target exists; typed targets come from the static schema. */
91
+ async function ensureTargetTable(db, targetTable) {
92
+ const table = targetTableFor(targetTable);
93
+ if (TYPED_TABLE_COLUMNS[table] === undefined)
94
+ await db.exec(ETL_TABLE_DDL(table));
94
95
  }
95
96
  /**
96
97
  * Ensure the ETL table(s) for a source definition exist.
97
98
  *
98
99
  * WHY: the static {@link HISTORY_IMPORT_SCHEMA_SQL} creates only the checkpoint, ledger, and
99
- * typed contract tables. Every `history_etl_*` blob table — built-in and custom — is created here
100
- * (and by {@link applyHistoryImportSchema} looping {@link SOURCE_DEFINITIONS}). Built-in definitions
101
- * with a `splitConfig.targetTable` override also need their target table(s) created on demand. The
100
+ * typed contract tables. Callers that explicitly request a definition's generic targets use this
101
+ * helper; the import pipeline instead creates only targets reached by accepted rows. The
102
102
  * table name is already gated by
103
103
  * {@link VALID_TABLE_NAME} in {@link validateSourceDefinition} / {@link targetTableFor},
104
104
  * so it is safe to interpolate into DDL. `CREATE TABLE IF NOT EXISTS` is
@@ -110,16 +110,43 @@ async function ensureTargetTables(db, definition) {
110
110
  tables.add(targetTableFor(definition.splitConfig.targetTable));
111
111
  }
112
112
  for (const table of tables) {
113
- // Typed tables are created by the static schema; use ETL DDL for custom tables.
114
- if (TYPED_TABLE_COLUMNS[table] !== undefined)
115
- continue;
116
- await db.exec(ETL_TABLE_DDL(table));
113
+ await ensureTargetTable(db, table);
117
114
  }
118
115
  }
119
116
  async function readCheckpoint(db, source, sourceFile) {
120
117
  const row = await db.queryFirst('SELECT last_imported_line FROM history_import_checkpoint WHERE source = ? AND source_file = ?', source, sourceFile);
121
118
  return row?.last_imported_line ?? 0;
122
119
  }
120
+ /**
121
+ * One query per source (0675 R5): all checkpoint rows for `source` keyed by file,
122
+ * replacing the per-file SELECT in the import loop.
123
+ *
124
+ * Fails open when the identity columns are missing (0678): a database created through a
125
+ * migration path that has not yet applied 0675's ALTERs would otherwise hard-fail every
126
+ * import. Line-level behavior degrades to pre-identity semantics — the short-circuit
127
+ * and identity stamping no-op until the columns exist.
128
+ */
129
+ export async function loadSourceCheckpoints(db, source) {
130
+ let rows;
131
+ try {
132
+ rows = await db.queryAll('SELECT source_file, last_imported_line, source_size, source_mtime_ms FROM history_import_checkpoint WHERE source = ?', source);
133
+ }
134
+ catch (err) {
135
+ if (!/no such column|source_size|source_mtime_ms/i.test(err.message))
136
+ throw err;
137
+ rows = (await db.queryAll('SELECT source_file, last_imported_line FROM history_import_checkpoint WHERE source = ?', source));
138
+ return new Map(rows.map((row) => [row.source_file, { line: row.last_imported_line, size: null, mtimeMs: null }]));
139
+ }
140
+ const map = new Map();
141
+ for (const row of rows) {
142
+ map.set(row.source_file, {
143
+ line: row.last_imported_line,
144
+ size: row.source_size ?? null,
145
+ mtimeMs: row.source_mtime_ms ?? null,
146
+ });
147
+ }
148
+ return map;
149
+ }
123
150
  async function resetCheckpoints(db, source, files) {
124
151
  for (const file of files) {
125
152
  await db.run('DELETE FROM history_import_checkpoint WHERE source = ? AND source_file = ?', source, file);
@@ -140,7 +167,7 @@ async function ledgerExists(db, recordHash) {
140
167
  * INSERT op for one accepted record row (task 0060 F9). Pure builder so the
141
168
  * per-record batch path and the single-write `insertRecord` can never drift.
142
169
  * Typed tables validate unknown keys here; the caller must have ensured the
143
- * target table exists (`ensureTargetTables` runs at import start).
170
+ * target table exists (the import loop ensures accepted targets before batching).
144
171
  */
145
172
  export function recordInsertOp(targetTable, recordHash, sourceFile, sourceLine, splitIndex, payload, now) {
146
173
  const table = targetTableFor(targetTable);
@@ -186,14 +213,16 @@ export function ledgerInsertOp(recordHash, source, sourceFile, sourceLine, split
186
213
  };
187
214
  }
188
215
  /** UPSERT op for one checkpoint row (task 0060 F9: checkpoint joins the record batch). */
189
- export function checkpointUpsertOp(source, sourceFile, line, now) {
216
+ export function checkpointUpsertOp(source, sourceFile, line, now, identity) {
190
217
  return {
191
- sql: `INSERT INTO history_import_checkpoint (source, source_file, last_imported_line, updated_at)
192
- VALUES (?, ?, ?, ?)
218
+ sql: `INSERT INTO history_import_checkpoint (source, source_file, last_imported_line, source_size, source_mtime_ms, updated_at)
219
+ VALUES (?, ?, ?, ?, ?, ?)
193
220
  ON CONFLICT(source, source_file) DO UPDATE SET
194
221
  last_imported_line = excluded.last_imported_line,
222
+ source_size = excluded.source_size,
223
+ source_mtime_ms = excluded.source_mtime_ms,
195
224
  updated_at = excluded.updated_at`,
196
- params: [source, sourceFile, line, timestamp(now)],
225
+ params: [source, sourceFile, line, identity?.size ?? null, identity?.mtimeMs ?? null, timestamp(now)],
197
226
  };
198
227
  }
199
228
  /**
@@ -242,11 +271,7 @@ export async function ledgerExistingHashes(db, hashes) {
242
271
  }
243
272
  async function insertRecord(db, targetTable, recordHash, sourceFile, sourceLine, splitIndex, payload, now) {
244
273
  const op = recordInsertOp(targetTable, recordHash, sourceFile, sourceLine, splitIndex, payload, now);
245
- if (TYPED_TABLE_COLUMNS[targetTableFor(targetTable)] === undefined) {
246
- // Custom ETL tables are created on demand; `CREATE TABLE IF NOT EXISTS` is idempotent,
247
- // so there is no process-global cache to go stale across adapter instances (task 0060 F8).
248
- await db.exec(ETL_TABLE_DDL(targetTableFor(targetTable)));
249
- }
274
+ await ensureTargetTable(db, targetTable);
250
275
  await db.run(op.sql, ...op.params);
251
276
  }
252
277
  async function insertLedger(db, recordHash, source, sourceFile, sourceLine, splitIndex, targetTable, now) {
@@ -300,7 +325,7 @@ async function listEtlTables(db) {
300
325
  * `(source, realpath)` by keeping the highest `last_imported_line`.
301
326
  */
302
327
  async function normalizeCheckpointPaths(db, resolveRealPath) {
303
- const rows = await db.queryAll('SELECT source, source_file, last_imported_line, updated_at FROM history_import_checkpoint');
328
+ const rows = await db.queryAll('SELECT source, source_file, last_imported_line, source_size, source_mtime_ms, updated_at FROM history_import_checkpoint');
304
329
  // Collapse per (source, realPath) keeping the highest last_imported_line.
305
330
  const collapsed = new Map();
306
331
  for (const row of rows) {
@@ -312,14 +337,16 @@ async function normalizeCheckpointPaths(db, resolveRealPath) {
312
337
  source: row.source,
313
338
  source_file: canonical,
314
339
  last_imported_line: row.last_imported_line,
340
+ source_size: row.source_size,
341
+ source_mtime_ms: row.source_mtime_ms,
315
342
  updated_at: row.updated_at,
316
343
  });
317
344
  }
318
345
  }
319
346
  await db.exec('DELETE FROM history_import_checkpoint');
320
347
  for (const row of collapsed.values()) {
321
- await db.run(`INSERT INTO history_import_checkpoint (source, source_file, last_imported_line, updated_at)
322
- VALUES (?, ?, ?, ?)`, row.source, row.source_file, row.last_imported_line, row.updated_at);
348
+ await db.run(`INSERT INTO history_import_checkpoint (source, source_file, last_imported_line, source_size, source_mtime_ms, updated_at)
349
+ VALUES (?, ?, ?, ?, ?, ?)`, row.source, row.source_file, row.last_imported_line, row.source_size, row.source_mtime_ms, row.updated_at);
323
350
  }
324
351
  }
325
352
  /** Normalize `source_file` in a table that stores it as a plain column. */
@@ -499,4 +526,4 @@ export function openCodeBulkWriteOperations(entries, checkpointFiles, now) {
499
526
  }
500
527
  return operations;
501
528
  }
502
- export { ETL_TABLE_DDL, ensureTargetTables, insertLedger, insertRecord, ledgerExists, readCheckpoint, reconcileFullImport, resetCheckpoints, targetTableFor, timestamp, toolCallDurationUpdateOp, toolCallResultBytesUpdateOp, writeCheckpoint, };
529
+ export { ETL_TABLE_DDL, ensureTargetTable, ensureTargetTables, insertLedger, insertRecord, ledgerExists, readCheckpoint, reconcileFullImport, resetCheckpoints, targetTableFor, timestamp, toolCallDurationUpdateOp, toolCallResultBytesUpdateOp, writeCheckpoint, };
package/dist/mappers.d.ts CHANGED
@@ -39,6 +39,8 @@ export interface ClaudeToolResultTiming {
39
39
  toolCallId: string;
40
40
  /** Message timestamp as epoch millis, when parseable. */
41
41
  timestampMs: number | undefined;
42
+ /** Native tool duration, when Claude Code emits one. */
43
+ durationMs: number | undefined;
42
44
  /** Serialized size in bytes of the tool result payload. */
43
45
  resultBytes: number;
44
46
  }
@@ -48,16 +50,24 @@ export interface ClaudeToolResultTiming {
48
50
  * `type: "user"` lines whose `message.content` holds `{type: "tool_result",
49
51
  * tool_use_id, content}` blocks; the top-level `toolUseResult` carries the raw
50
52
  * envelope. `resultBytes` prefers the model-visible block content and falls
51
- * back to `toolUseResult`; both are null-safe. No wall time exists natively —
52
- * claude `duration_ms` intentionally stays NULL (never-fabricate, 0624).
53
+ * back to `toolUseResult`; both are null-safe. Some tool results carry a native
54
+ * `durationMs` or `durationSeconds`; absent timing stays unmeasured.
53
55
  */
54
56
  export declare function claudeToolResultTiming(raw: Record<string, unknown>): ClaudeToolResultTiming | null;
55
57
  /** Map a Codex JSONL record into one or more ETL split entries. */
56
- export declare function codexSplit(raw: Record<string, unknown>): readonly SplitEntry[];
58
+ export declare function codexSplit(raw: Record<string, unknown>, context?: TransformContext): readonly SplitEntry[];
57
59
  /** Map an Antigravity (AGY) JSONL record into one or more ETL split entries. */
58
- export declare function agySplit(raw: Record<string, unknown>): readonly SplitEntry[];
60
+ export declare function agySplit(raw: Record<string, unknown>, context?: TransformContext): readonly SplitEntry[];
59
61
  /** Map Gemini CLI message, tool, and session-state events into the forensic contract tables. */
60
62
  export declare function geminiSplit(raw: Record<string, unknown>, context?: TransformContext): readonly SplitEntry[];
63
+ /**
64
+ * Pure helper extracting canonical session identity from source transcript paths (task 0638 R4).
65
+ *
66
+ * Normalizes POSIX/Windows separators and returns only valid UUID-shaped identifiers:
67
+ * - agy: segment immediately following `/brain/`
68
+ * - codex: trailing UUID before `.jsonl` in a filename beginning with `rollout-`
69
+ */
70
+ export declare function sessionIdFromSourcePath(source: string, sourceFile: string): string | undefined;
61
71
  /** Map a Grok JSONL record into one or more ETL split entries. */
62
72
  export declare function grokSplit(raw: Record<string, unknown>): readonly SplitEntry[];
63
73
  /** Compute a stable field-shape key from a JSON object: sorted, lowercased, +-joined top-level keys. */
@@ -1 +1 @@
1
- {"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"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"}