@gobing-ai/ts-llm-jsonl-importer 0.4.39 → 0.4.40

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.
@@ -1 +1 @@
1
- {"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../src/importer.ts"],"names":[],"mappings":"AA0BA,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,CAkRrH"}
1
+ {"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../src/importer.ts"],"names":[],"mappings":"AA0BA,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,CAuRrH"}
package/dist/importer.js CHANGED
@@ -64,6 +64,7 @@ export async function runJsonlImport(source, options) {
64
64
  let importedRecords = 0;
65
65
  let skippedDuplicates = 0;
66
66
  let unknownRecords = 0;
67
+ let skippedCorruptLines = 0;
67
68
  let checkpointUpdates = 0;
68
69
  // Full-mode desired set (R1, task 0504): every record hash the current source produces.
69
70
  // ReconcileFullImport diffs this against the persisted ledger to retire stale rows.
@@ -80,9 +81,12 @@ export async function runJsonlImport(source, options) {
80
81
  if (line.length === 0 || lineNumber <= checkpoint)
81
82
  continue;
82
83
  processedLines += 1;
83
- const raw = parseJsonLine(line, file, lineNumber, parseErrors);
84
- if (raw === undefined)
84
+ const raw = parseJsonLine(line, file, lineNumber, parseErrors, definition.corruptLinePolicy);
85
+ if (raw === undefined) {
86
+ if (definition.corruptLinePolicy === 'skip')
87
+ skippedCorruptLines += 1;
85
88
  continue;
89
+ }
86
90
  const splitRecords = splitRawRecord(definition, raw, {
87
91
  source: resolvedSource,
88
92
  sourceFile: file,
@@ -244,6 +248,7 @@ export async function runJsonlImport(source, options) {
244
248
  processedLines,
245
249
  importedRecords,
246
250
  skippedDuplicates,
251
+ skippedCorruptLines,
247
252
  unknownRecords,
248
253
  parseErrors,
249
254
  validationErrors,
@@ -251,19 +256,28 @@ export async function runJsonlImport(source, options) {
251
256
  reconciliation,
252
257
  };
253
258
  }
254
- function parseJsonLine(line, sourceFile, sourceLine, parseErrors) {
259
+ function parseJsonLine(line, sourceFile, sourceLine, parseErrors, corruptLinePolicy = 'error') {
260
+ let parsed;
255
261
  try {
256
- const value = JSON.parse(line);
257
- if (value === null || typeof value !== 'object' || Array.isArray(value)) {
258
- parseErrors.push({ sourceFile, sourceLine, reason: 'JSONL row must be an object' });
259
- return undefined;
260
- }
261
- return value;
262
+ parsed = JSON.parse(line);
262
263
  }
263
264
  catch (error) {
264
- parseErrors.push({ sourceFile, sourceLine, reason: error instanceof Error ? error.message : 'Invalid JSON' });
265
+ if (corruptLinePolicy !== 'skip') {
266
+ parseErrors.push({
267
+ sourceFile,
268
+ sourceLine,
269
+ reason: error instanceof Error ? error.message : 'Invalid JSON',
270
+ });
271
+ }
272
+ return undefined;
273
+ }
274
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
275
+ if (corruptLinePolicy !== 'skip') {
276
+ parseErrors.push({ sourceFile, sourceLine, reason: 'JSONL row must be an object' });
277
+ }
265
278
  return undefined;
266
279
  }
280
+ return parsed;
267
281
  }
268
282
  function splitRawRecord(definition, raw, context) {
269
283
  const targetTable = targetTableFor(definition.targetTable);
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-importer.d.ts","sourceRoot":"","sources":["../src/opencode-importer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,SAAS,EAAkB,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAGH,KAAK,UAAU,EAEf,KAAK,YAAY,EACpB,MAAM,uBAAuB,CAAC;AAgB/B,OAAO,KAAK,EAAe,UAAU,EAAE,YAAY,EAAgC,aAAa,EAAE,MAAM,SAAS,CAAC;AAYlH,8EAA8E;AAC9E,MAAM,WAAW,qBAAqB;IAClC,EAAE,EAAE,SAAS,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wFAAwF;AACxF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,YAAY,CAAC,CAoI7F"}
1
+ {"version":3,"file":"opencode-importer.d.ts","sourceRoot":"","sources":["../src/opencode-importer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,SAAS,EAAkB,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAGH,KAAK,UAAU,EAEf,KAAK,YAAY,EACpB,MAAM,uBAAuB,CAAC;AAgB/B,OAAO,KAAK,EAAe,UAAU,EAAE,YAAY,EAAgC,aAAa,EAAE,MAAM,SAAS,CAAC;AAYlH,8EAA8E;AAC9E,MAAM,WAAW,qBAAqB;IAClC,EAAE,EAAE,SAAS,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wFAAwF;AACxF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,YAAY,CAAC,CAqI7F"}
@@ -124,6 +124,7 @@ export async function runOpenCodeImport(options) {
124
124
  processedLines,
125
125
  importedRecords,
126
126
  skippedDuplicates,
127
+ skippedCorruptLines: 0,
127
128
  unknownRecords: 0,
128
129
  parseErrors,
129
130
  validationErrors,
@@ -263,6 +264,7 @@ function emptyResult(mode) {
263
264
  processedLines: 0,
264
265
  importedRecords: 0,
265
266
  skippedDuplicates: 0,
267
+ skippedCorruptLines: 0,
266
268
  unknownRecords: 0,
267
269
  parseErrors: [],
268
270
  validationErrors: [],
@@ -1 +1 @@
1
- {"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../src/sources.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAA8B,cAAc,EAAE,gBAAgB,EAAoB,MAAM,SAAS,CAAC;AAsH9G;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,QAAsB,CAAC;AAEpD,8DAA8D;AAC9D,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,CA2DjF,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,gBAAgB,CAM5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,CA+BvF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,gBAAgB,CAK1F"}
1
+ {"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../src/sources.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAA8B,cAAc,EAAE,gBAAgB,EAAoB,MAAM,SAAS,CAAC;AAsH9G;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,QAAsB,CAAC;AAEpD,8DAA8D;AAC9D,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAiEjF,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,gBAAgB,CAM5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,CA+BvF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,gBAAgB,CAK1F"}
package/dist/sources.js CHANGED
@@ -103,7 +103,13 @@ export const SOURCE_DEFINITIONS = {
103
103
  codex: customSourceDefinition('codex', 'Codex', ['.codex/sessions'], ['*.jsonl'], codexSplit, CODEX_FIELD_MAP, CODEX_SCHEMA),
104
104
  omp: customSourceDefinition('omp', 'OMP', ['.omp/agent/sessions'], ['*.jsonl'], ompSplit, OMP_FIELD_MAP, OMP_SCHEMA),
105
105
  grok: customSourceDefinition('grok', 'Grok', ['.grok/sessions'], ['*.jsonl'], grokSplit, GROK_FIELD_MAP, GROK_SCHEMA),
106
- agy: customSourceDefinition('agy', 'Antigravity CLI', ['.gemini/antigravity-cli/brain'], ['*.jsonl'], agySplit, AGY_FIELD_MAP, AGY_SCHEMA),
106
+ agy: {
107
+ ...customSourceDefinition('agy', 'Antigravity CLI', ['.gemini/antigravity-cli/brain'], ['*.jsonl'], agySplit, AGY_FIELD_MAP, AGY_SCHEMA),
108
+ // agy's producer interleaves non-JSON fragments and torn tail writes into its
109
+ // brain jsonl (task 0623: 789/89,818 lines, all unrecoverable). Skipping keeps
110
+ // the 99%+ good records importable without degrading the whole source.
111
+ corruptLinePolicy: 'skip',
112
+ },
107
113
  gemini: customSourceDefinition('gemini', 'Gemini CLI', ['.gemini/tmp', '.config/gemini'], ['*.jsonl'], geminiSplit, GEMINI_FIELD_MAP, GEMINI_SCHEMA),
108
114
  opencode: sourceDefinition('opencode', 'OpenCode', ['.opencode', '.local/share/opencode'], ['*.jsonl']),
109
115
  antigravity: sourceDefinition('antigravity', 'Antigravity', ['.antigravity'], ['*.jsonl']),
package/dist/types.d.ts CHANGED
@@ -41,6 +41,13 @@ export interface SourceDefinition<TRecord extends JsonObject = JsonObject> {
41
41
  readonly displayName: string;
42
42
  readonly defaultRoots: readonly string[];
43
43
  readonly filePatterns: readonly string[];
44
+ /**
45
+ * Policy for lines that fail JSON parsing. `'error'` (default) records a parse error and
46
+ * degrades the import; `'skip'` counts the line and moves on — for producers whose logs
47
+ * are known to interleave non-JSON fragments and torn tail writes (agy task 0623:
48
+ * 789/89,818 lines unparseable, all unrecoverable garbage).
49
+ */
50
+ readonly corruptLinePolicy?: 'error' | 'skip';
44
51
  readonly targetTable: string;
45
52
  readonly splitConfig: SplitConfig;
46
53
  readonly fieldMap: Readonly<Record<string, string>>;
@@ -100,6 +107,8 @@ export interface ImportResult {
100
107
  readonly importedRecords: number;
101
108
  readonly skippedDuplicates: number;
102
109
  readonly unknownRecords: number;
110
+ /** Lines dropped by `corruptLinePolicy: 'skip'` instead of degrading the import. */
111
+ readonly skippedCorruptLines: number;
103
112
  readonly parseErrors: readonly ImportIssue[];
104
113
  readonly validationErrors: readonly ImportIssue[];
105
114
  readonly checkpointUpdates: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/ts-llm-jsonl-importer",
3
- "version": "0.4.39",
3
+ "version": "0.4.40",
4
4
  "description": "@gobing-ai/ts-llm-jsonl-importer — Generic JSONL importer for LLM agent history files.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -47,9 +47,9 @@
47
47
  "release": "echo 'Manual publish is disabled. Releases go through GitHub Actions via Trusted Publishing — push a tag: git tag @gobing-ai/ts-llm-jsonl-importer-v<version> && git push --tags' && exit 1"
48
48
  },
49
49
  "dependencies": {
50
- "@gobing-ai/ts-db": "^0.4.39",
51
- "@gobing-ai/ts-runtime": "^0.4.39",
52
- "@gobing-ai/ts-utils": "^0.4.39",
50
+ "@gobing-ai/ts-db": "^0.4.40",
51
+ "@gobing-ai/ts-runtime": "^0.4.40",
52
+ "@gobing-ai/ts-utils": "^0.4.40",
53
53
  "zod": "^4.1.0"
54
54
  },
55
55
  "devDependencies": {
package/src/importer.ts CHANGED
@@ -143,6 +143,7 @@ export async function runJsonlImport(source: string | SourceDefinition, options:
143
143
  let importedRecords = 0;
144
144
  let skippedDuplicates = 0;
145
145
  let unknownRecords = 0;
146
+ let skippedCorruptLines = 0;
146
147
  let checkpointUpdates = 0;
147
148
  // Full-mode desired set (R1, task 0504): every record hash the current source produces.
148
149
  // ReconcileFullImport diffs this against the persisted ledger to retire stale rows.
@@ -161,8 +162,11 @@ export async function runJsonlImport(source: string | SourceDefinition, options:
161
162
  if (line.length === 0 || lineNumber <= checkpoint) continue;
162
163
  processedLines += 1;
163
164
 
164
- const raw = parseJsonLine(line, file, lineNumber, parseErrors);
165
- if (raw === undefined) continue;
165
+ const raw = parseJsonLine(line, file, lineNumber, parseErrors, definition.corruptLinePolicy);
166
+ if (raw === undefined) {
167
+ if (definition.corruptLinePolicy === 'skip') skippedCorruptLines += 1;
168
+ continue;
169
+ }
166
170
 
167
171
  const splitRecords = splitRawRecord(definition, raw, {
168
172
  source: resolvedSource,
@@ -392,6 +396,7 @@ export async function runJsonlImport(source: string | SourceDefinition, options:
392
396
  processedLines,
393
397
  importedRecords,
394
398
  skippedDuplicates,
399
+ skippedCorruptLines,
395
400
  unknownRecords,
396
401
  parseErrors,
397
402
  validationErrors,
@@ -405,18 +410,28 @@ function parseJsonLine(
405
410
  sourceFile: string,
406
411
  sourceLine: number,
407
412
  parseErrors: ImportIssue[],
413
+ corruptLinePolicy: SourceDefinition['corruptLinePolicy'] = 'error',
408
414
  ): JsonObject | undefined {
415
+ let parsed: unknown;
409
416
  try {
410
- const value = JSON.parse(line);
411
- if (value === null || typeof value !== 'object' || Array.isArray(value)) {
417
+ parsed = JSON.parse(line);
418
+ } catch (error) {
419
+ if (corruptLinePolicy !== 'skip') {
420
+ parseErrors.push({
421
+ sourceFile,
422
+ sourceLine,
423
+ reason: error instanceof Error ? error.message : 'Invalid JSON',
424
+ });
425
+ }
426
+ return undefined;
427
+ }
428
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
429
+ if (corruptLinePolicy !== 'skip') {
412
430
  parseErrors.push({ sourceFile, sourceLine, reason: 'JSONL row must be an object' });
413
- return undefined;
414
431
  }
415
- return value as JsonObject;
416
- } catch (error) {
417
- parseErrors.push({ sourceFile, sourceLine, reason: error instanceof Error ? error.message : 'Invalid JSON' });
418
432
  return undefined;
419
433
  }
434
+ return parsed as JsonObject;
420
435
  }
421
436
 
422
437
  function splitRawRecord(
@@ -172,6 +172,7 @@ export async function runOpenCodeImport(options: OpenCodeImportOptions): Promise
172
172
  processedLines,
173
173
  importedRecords,
174
174
  skippedDuplicates,
175
+ skippedCorruptLines: 0,
175
176
  unknownRecords: 0,
176
177
  parseErrors,
177
178
  validationErrors,
@@ -331,6 +332,7 @@ function emptyResult(mode: ImportMode): ImportResult {
331
332
  processedLines: 0,
332
333
  importedRecords: 0,
333
334
  skippedDuplicates: 0,
335
+ skippedCorruptLines: 0,
334
336
  unknownRecords: 0,
335
337
  parseErrors: [],
336
338
  validationErrors: [],
package/src/sources.ts CHANGED
@@ -190,15 +190,21 @@ export const SOURCE_DEFINITIONS: Readonly<Record<LlmJsonlSource, SourceDefinitio
190
190
  GROK_FIELD_MAP,
191
191
  GROK_SCHEMA,
192
192
  ),
193
- agy: customSourceDefinition(
194
- 'agy',
195
- 'Antigravity CLI',
196
- ['.gemini/antigravity-cli/brain'],
197
- ['*.jsonl'],
198
- agySplit,
199
- AGY_FIELD_MAP,
200
- AGY_SCHEMA,
201
- ),
193
+ agy: {
194
+ ...customSourceDefinition(
195
+ 'agy',
196
+ 'Antigravity CLI',
197
+ ['.gemini/antigravity-cli/brain'],
198
+ ['*.jsonl'],
199
+ agySplit,
200
+ AGY_FIELD_MAP,
201
+ AGY_SCHEMA,
202
+ ),
203
+ // agy's producer interleaves non-JSON fragments and torn tail writes into its
204
+ // brain jsonl (task 0623: 789/89,818 lines, all unrecoverable). Skipping keeps
205
+ // the 99%+ good records importable without degrading the whole source.
206
+ corruptLinePolicy: 'skip',
207
+ },
202
208
  gemini: customSourceDefinition(
203
209
  'gemini',
204
210
  'Gemini CLI',
package/src/types.ts CHANGED
@@ -62,6 +62,13 @@ export interface SourceDefinition<TRecord extends JsonObject = JsonObject> {
62
62
  readonly displayName: string;
63
63
  readonly defaultRoots: readonly string[];
64
64
  readonly filePatterns: readonly string[];
65
+ /**
66
+ * Policy for lines that fail JSON parsing. `'error'` (default) records a parse error and
67
+ * degrades the import; `'skip'` counts the line and moves on — for producers whose logs
68
+ * are known to interleave non-JSON fragments and torn tail writes (agy task 0623:
69
+ * 789/89,818 lines unparseable, all unrecoverable garbage).
70
+ */
71
+ readonly corruptLinePolicy?: 'error' | 'skip';
65
72
  readonly targetTable: string;
66
73
  readonly splitConfig: SplitConfig;
67
74
  readonly fieldMap: Readonly<Record<string, string>>;
@@ -126,6 +133,8 @@ export interface ImportResult {
126
133
  readonly importedRecords: number;
127
134
  readonly skippedDuplicates: number;
128
135
  readonly unknownRecords: number;
136
+ /** Lines dropped by `corruptLinePolicy: 'skip'` instead of degrading the import. */
137
+ readonly skippedCorruptLines: number;
129
138
  readonly parseErrors: readonly ImportIssue[];
130
139
  readonly validationErrors: readonly ImportIssue[];
131
140
  readonly checkpointUpdates: number;