trajectories 0.0.0 → 0.1.2
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/CHANGELOG.md +36 -0
- package/LICENSE +201 -0
- package/README.md +288 -2
- package/dist/cli.js +30210 -0
- package/dist/convert.d.ts +31 -0
- package/dist/convert.js +431 -0
- package/dist/deepagents_checkpoint.py +362 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +8402 -0
- package/dist/log-baseline.d.ts +26 -0
- package/dist/log-baseline.js +104 -0
- package/dist/log-content.d.ts +16 -0
- package/dist/log-content.js +80 -0
- package/dist/log-io.d.ts +10 -0
- package/dist/log-io.js +121 -0
- package/dist/log-read.d.ts +24 -0
- package/dist/log-read.js +117 -0
- package/dist/log-reconcile.d.ts +5 -0
- package/dist/log-reconcile.js +38 -0
- package/dist/log-records.d.ts +35 -0
- package/dist/log-records.js +85 -0
- package/dist/log-recovery.d.ts +18 -0
- package/dist/log-recovery.js +123 -0
- package/dist/log-stage.d.ts +14 -0
- package/dist/log-stage.js +138 -0
- package/dist/log-state.d.ts +89 -0
- package/dist/log-state.js +92 -0
- package/dist/log-switch.d.ts +3 -0
- package/dist/log-switch.js +98 -0
- package/dist/log-types.d.ts +129 -0
- package/dist/log-types.js +8 -0
- package/dist/log.d.ts +8 -0
- package/dist/log.js +62 -0
- package/dist/migrate.d.ts +29 -0
- package/dist/migrate.js +173 -0
- package/dist/normalization-runtime.d.ts +1 -0
- package/dist/normalization-runtime.js +3150 -0
- package/dist/portable.d.ts +9 -0
- package/dist/portable.js +26 -0
- package/dist/readers/canonical.d.ts +13 -0
- package/dist/readers/canonical.js +54 -0
- package/dist/readers/cline.d.ts +10 -0
- package/dist/readers/cline.js +107 -0
- package/dist/readers/cursor.d.ts +20 -0
- package/dist/readers/cursor.js +374 -0
- package/dist/readers/deepagents.d.ts +41 -0
- package/dist/readers/deepagents.js +163 -0
- package/dist/readers/fx.d.ts +11 -0
- package/dist/readers/fx.js +573 -0
- package/dist/readers/github-copilot.d.ts +8 -0
- package/dist/readers/github-copilot.js +216 -0
- package/dist/readers/grok-build.d.ts +12 -0
- package/dist/readers/grok-build.js +391 -0
- package/dist/readers/guards.d.ts +4 -0
- package/dist/readers/guards.js +121 -0
- package/dist/readers/pi-compaction.d.ts +7 -0
- package/dist/readers/pi-compaction.js +112 -0
- package/dist/readers/pi-context.d.ts +13 -0
- package/dist/readers/pi-context.js +64 -0
- package/dist/store.d.ts +25 -0
- package/dist/store.js +218 -0
- package/dist/types.d.ts +91 -0
- package/dist/types.js +1 -0
- package/dist/writers/claude-code.d.ts +5 -0
- package/dist/writers/claude-code.js +51 -0
- package/dist/writers/cline.d.ts +3 -0
- package/dist/writers/cline.js +77 -0
- package/dist/writers/codex.d.ts +3 -0
- package/dist/writers/codex.js +32 -0
- package/dist/writers/cursor.d.ts +3 -0
- package/dist/writers/cursor.js +197 -0
- package/dist/writers/deepagents.d.ts +3 -0
- package/dist/writers/deepagents.js +116 -0
- package/dist/writers/entropy.d.ts +5 -0
- package/dist/writers/entropy.js +33 -0
- package/dist/writers/fx.d.ts +3 -0
- package/dist/writers/fx.js +135 -0
- package/dist/writers/github-copilot.d.ts +3 -0
- package/dist/writers/github-copilot.js +71 -0
- package/dist/writers/grok-build.d.ts +3 -0
- package/dist/writers/grok-build.js +43 -0
- package/dist/writers/helpers.d.ts +17 -0
- package/dist/writers/helpers.js +75 -0
- package/dist/writers/omp.d.ts +3 -0
- package/dist/writers/omp.js +7 -0
- package/dist/writers/opencode.d.ts +3 -0
- package/dist/writers/opencode.js +65 -0
- package/dist/writers/pi.d.ts +3 -0
- package/dist/writers/pi.js +45 -0
- package/docs/cline-native-format.md +43 -0
- package/docs/copilot-native-format.md +78 -0
- package/docs/cursor-native-format.md +103 -0
- package/docs/deepagents-native-format.md +98 -0
- package/docs/evidence-api.md +170 -0
- package/docs/fx-native-format.md +87 -0
- package/docs/harness-parity-bootstrap.md +78 -0
- package/docs/harness-support-parity.md +107 -0
- package/docs/inspirations.md +103 -0
- package/docs/ledger-migration.md +141 -0
- package/docs/pi-compaction-context.md +75 -0
- package/docs/pi-provider-context.md +76 -0
- package/docs/research/2026-10-06-huihua-and-oar.md +176 -0
- package/docs/research/ledger/README.md +96 -0
- package/docs/research/ledger/confer/2026-09-13-round-10/README.md +61 -0
- package/docs/research/ledger/confer/2026-09-13-round-2/cass.md +72 -0
- package/docs/research/ledger/confer/2026-09-13-round-3/README.md +70 -0
- package/docs/research/ledger/confer/2026-09-13-round-5/README.md +61 -0
- package/docs/research/ledger/confer/2026-09-13-round-6/README.md +68 -0
- package/docs/research/ledger/confer/2026-09-13-round-7/README.md +64 -0
- package/docs/research/ledger/confer/2026-09-13-round-9/README.md +59 -0
- package/docs/research/ledger/confer/2026-09-14-wake/wake.md +146 -0
- package/docs/research/ledger/docs/inspirations.md +320 -0
- package/docs/research/ledger/docs/pr2-pr6-integration.md +53 -0
- package/docs/research/ledger/docs/research/2026-09-07-confer-inspirations.md +163 -0
- package/docs/research/ledger/docs/research/2026-09-07-letta-continuous-service.md +104 -0
- package/docs/research/ledger/docs/research/2026-09-08-claude-history-retrieval.md +117 -0
- package/docs/research/ledger/docs/research/2026-09-09-agentsview-native-discovery.md +87 -0
- package/docs/research/ledger/docs/research/2026-09-09-daemon-observation.md +231 -0
- package/docs/research/ledger/docs/research/2026-09-09-discovery-pagination.md +114 -0
- package/docs/research/ledger/docs/research/2026-09-09-harness-transcript-contract.md +145 -0
- package/docs/research/ledger/docs/research/2026-09-09-native-history-discovery.md +180 -0
- package/docs/research/ledger/docs/research/2026-09-09-native-history-implementation.md +137 -0
- package/docs/research/ledger/docs/research/2026-09-09-other-inspirations.md +279 -0
- package/docs/research/ledger/docs/research/2026-09-09-trajectory-and-letta-code.md +128 -0
- package/docs/research/ledger/docs/research/2026-09-13-diagnostics-coverage.md +116 -0
- package/docs/research/ledger/docs/research/2026-09-13-fts-rebuild.md +83 -0
- package/docs/research/ledger/docs/research/2026-09-13-read-path-split.md +74 -0
- package/docs/research/ledger/docs/research/2026-09-13-runtime-rollout.md +102 -0
- package/docs/research/ledger/docs/research/2026-09-13-scan-outcomes.md +80 -0
- package/docs/research/ledger/docs/research/2026-09-13-search-quality.md +105 -0
- package/docs/research/ledger/docs/research/2026-09-13-source-coverage.md +64 -0
- package/docs/research/ledger/docs/research/2026-09-13-sync-wall-budget.md +82 -0
- package/docs/research/ledger/docs/research/2026-09-13-typed-read-gate.md +81 -0
- package/docs/research/ledger/docs/research/2026-09-13-writer-lease.md +84 -0
- package/docs/research/ledger/docs/research/2026-09-16-c1-copy-fallback.md +227 -0
- package/docs/research/ledger/docs/research/2026-09-16-c10-kimi.md +414 -0
- package/docs/research/ledger/docs/research/2026-09-16-c2-derive-counter.md +216 -0
- package/docs/research/ledger/docs/research/2026-09-16-c3-echo-filter.md +305 -0
- package/docs/research/ledger/docs/research/2026-09-16-c4-title-index.md +349 -0
- package/docs/research/ledger/docs/research/2026-09-16-c5-trigram.md +268 -0
- package/docs/research/ledger/docs/research/2026-09-16-c6-recency-prior.md +438 -0
- package/docs/research/ledger/docs/research/2026-09-16-c7-tombstones.md +467 -0
- package/docs/research/ledger/docs/research/2026-09-16-c8-remote-truth.md +390 -0
- package/docs/research/ledger/docs/research/2026-09-16-c9-grok.md +380 -0
- package/docs/research/ledger/docs/research/2026-09-16-wake-port-program.md +38 -0
- package/docs/research/ledger/docs/research/2026-09-17-cursor-blobstore.md +157 -0
- package/docs/research/ledger/manifest.json +540 -0
- package/legacy/NOTICE.md +50 -0
- package/legacy/bin/ledger-core.ts +7 -0
- package/legacy/bin/ledger.ts +7 -0
- package/legacy/bin/traj-bridge.ts +7 -0
- package/legacy/scripts/import-claude-history.ts +130 -0
- package/legacy/scripts/native-history-smoke.ts +52 -0
- package/legacy/scripts/observe-daemon.ts +570 -0
- package/legacy/scripts/retitle-sessions.md +19 -0
- package/legacy/scripts/verify-runtime-rollout.ts +151 -0
- package/legacy/src/canonical.ts +108 -0
- package/legacy/src/cli.ts +1293 -0
- package/legacy/src/db.ts +2254 -0
- package/legacy/src/diagnostics.ts +87 -0
- package/legacy/src/discovery.ts +56 -0
- package/legacy/src/embeddings.ts +382 -0
- package/legacy/src/filter.ts +602 -0
- package/legacy/src/gemini_embeddings.ts +103 -0
- package/legacy/src/identity.ts +9 -0
- package/legacy/src/index.ts +10 -0
- package/legacy/src/ingest.ts +791 -0
- package/legacy/src/managed.ts +178 -0
- package/legacy/src/native/common.ts +68 -0
- package/legacy/src/native/cursor.ts +647 -0
- package/legacy/src/native/grok.ts +540 -0
- package/legacy/src/native/kimi.ts +706 -0
- package/legacy/src/native/opencode.ts +470 -0
- package/legacy/src/native/sqlite-ro.ts +281 -0
- package/legacy/src/native.ts +97 -0
- package/legacy/src/normalizer.ts +457 -0
- package/legacy/src/parentage.ts +562 -0
- package/legacy/src/pressure.ts +162 -0
- package/legacy/src/private-storage.ts +74 -0
- package/legacy/src/reader.ts +1255 -0
- package/legacy/src/scanner.ts +591 -0
- package/legacy/src/schema-gate.ts +263 -0
- package/legacy/src/schema.ts +829 -0
- package/legacy/src/semantic-top-k.ts +71 -0
- package/legacy/src/session-hash.ts +49 -0
- package/legacy/src/store-status.ts +218 -0
- package/legacy/src/sync-preparation.ts +45 -0
- package/legacy/src/sync-truth.ts +843 -0
- package/legacy/src/sync.ts +1233 -0
- package/legacy/src/types.ts +436 -0
- package/legacy/src/vocab.txt +30522 -0
- package/legacy/src/watch.ts +673 -0
- package/legacy/src/writer-lease.ts +310 -0
- package/ops/README.md +150 -0
- package/ops/install-cli.sh +63 -0
- package/ops/install-native.sh +35 -0
- package/ops/install-release.sh +49 -0
- package/ops/linux/install-systemd-user.sh +103 -0
- package/ops/macos/install-launchd.sh +72 -0
- package/ops/sync-settings.sh +37 -0
- package/package.json +21 -5
- package/skills/trajectories/SKILL.md +138 -0
- package/skills/trajectories/scripts/trajectories_recent.sh +26 -0
- package/skills/trajectories/scripts/trajectories_search.sh +26 -0
- package/index.js +0 -1
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { normalizeToCanonical } from "@letta-ai/trajectory";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { createReadStream, mkdirSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { parseArgs } from "node:util";
|
|
6
|
+
import { TrajectoryDb } from "../src/db.js";
|
|
7
|
+
import { ledgerId } from "../src/identity.js";
|
|
8
|
+
import type { CanonicalDbRecord, SessionRecord } from "../src/types.js";
|
|
9
|
+
import { acquireWriterLease, isMemoryStorePath } from "../src/writer-lease.js";
|
|
10
|
+
|
|
11
|
+
type SliceOptions = { history: string; session: string; from: string; to: string };
|
|
12
|
+
const sha256 = (value: string | Buffer) => createHash("sha256").update(value).digest("hex");
|
|
13
|
+
|
|
14
|
+
async function* sourceLines(path: string) {
|
|
15
|
+
let pending = Buffer.alloc(0), offset = 0, line = 0;
|
|
16
|
+
for await (const chunk of createReadStream(path)) {
|
|
17
|
+
pending = Buffer.concat([pending, chunk as Buffer]);
|
|
18
|
+
let end: number;
|
|
19
|
+
while ((end = pending.indexOf(10)) !== -1) {
|
|
20
|
+
const bytes = pending.subarray(0, end + 1);
|
|
21
|
+
yield { bytes, offset, line: ++line };
|
|
22
|
+
offset += bytes.length;
|
|
23
|
+
pending = pending.subarray(end + 1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (pending.length) yield { bytes: pending, offset, line: ++line };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function prepareHistorySlice(options: SliceOptions) {
|
|
30
|
+
const from = Date.parse(options.from), to = Date.parse(options.to);
|
|
31
|
+
const zoned = /T.*(?:Z|[+-]\d{2}:\d{2})$/;
|
|
32
|
+
if (!zoned.test(options.from) || !zoned.test(options.to) || !Number.isFinite(from) || !Number.isFinite(to) || from >= to) {
|
|
33
|
+
throw new Error("from/to must be increasing ISO timestamps with explicit timezones");
|
|
34
|
+
}
|
|
35
|
+
if (!options.session) throw new Error("An explicit session ID is required");
|
|
36
|
+
const history = resolve(options.history);
|
|
37
|
+
const scope = { history, session: options.session, from: new Date(from).toISOString(), to: new Date(to).toISOString() };
|
|
38
|
+
const sliceId = `claude-history:${options.session}:${sha256(JSON.stringify(scope))}`;
|
|
39
|
+
const sessionId = ledgerId("claude-code", sliceId);
|
|
40
|
+
const records: CanonicalDbRecord[] = [];
|
|
41
|
+
const evidence: Array<{ record_id: string; line: number; byte_offset: number; byte_length: number; raw_sha256: string }> = [];
|
|
42
|
+
const rows: Buffer[] = [];
|
|
43
|
+
let scanned = 0, cwd: string | null = null;
|
|
44
|
+
for await (const { bytes, offset, line } of sourceLines(history)) {
|
|
45
|
+
scanned++;
|
|
46
|
+
let row;
|
|
47
|
+
try { row = JSON.parse(bytes.toString("utf8")); }
|
|
48
|
+
catch { throw new Error(`Invalid JSON in history at line ${line}`); }
|
|
49
|
+
if (row.sessionId !== options.session || typeof row.timestamp !== "number" || row.timestamp < from || row.timestamp >= to) continue;
|
|
50
|
+
if (typeof row.display !== "string" || !row.display.trim()) continue;
|
|
51
|
+
if (typeof row.project === "string") cwd ??= row.project;
|
|
52
|
+
|
|
53
|
+
// This is a partial prompt projection, not a recovered assistant transcript.
|
|
54
|
+
// Per-row normalization retains locations in the original file, not a reserialized envelope.
|
|
55
|
+
const result = normalizeToCanonical({
|
|
56
|
+
source: "claude-code",
|
|
57
|
+
transcript: JSON.stringify({ type: "user", timestamp: row.timestamp, message: { content: row.display } }),
|
|
58
|
+
sourceContext: { groupId: sliceId, baseByteOffset: offset, partial: true },
|
|
59
|
+
});
|
|
60
|
+
const users = result.records.filter((r) => r.record_type === "user");
|
|
61
|
+
if (users.length !== 1 || users[0].content !== row.display || users[0].source_timestamp !== new Date(row.timestamp).toISOString()) {
|
|
62
|
+
throw new Error(`History mapping changed text or timestamp at line ${line}`);
|
|
63
|
+
}
|
|
64
|
+
const r = users[0];
|
|
65
|
+
records.push({
|
|
66
|
+
id: ledgerId("claude-code", r.record_id), session_id: sessionId, source_type: r.source_type,
|
|
67
|
+
record_type: r.record_type, stable_source_record_id: r.stable_source_record_id ?? null,
|
|
68
|
+
source_identity_kind: r.source_identity_kind ?? null,
|
|
69
|
+
source_order_id: r.source_order_id, component_index: r.component_index,
|
|
70
|
+
record_timestamp: r.record_timestamp ?? null, source_timestamp: r.source_timestamp ?? null,
|
|
71
|
+
content: r.content ?? null, tool_call_id: null, tool_name: null,
|
|
72
|
+
tool_arguments_json: null, tool_result_json: null, tool_result_ok: null,
|
|
73
|
+
record_json: r.record_json, content_hash: r.content_hash, record_hash: r.record_hash,
|
|
74
|
+
});
|
|
75
|
+
rows.push(Buffer.from(bytes));
|
|
76
|
+
evidence.push({ record_id: ledgerId("claude-code", r.record_id), line, byte_offset: offset, byte_length: bytes.length, raw_sha256: sha256(bytes) });
|
|
77
|
+
}
|
|
78
|
+
if (!records.length) throw new Error("No prompts in the selected session/time window; nothing imported");
|
|
79
|
+
const raw = Buffer.concat(rows);
|
|
80
|
+
const timestamps = records.map((r) => r.source_timestamp!).sort();
|
|
81
|
+
const now = new Date().toISOString();
|
|
82
|
+
const session: SessionRecord = {
|
|
83
|
+
id: sessionId, source: "claude-code", source_path: history,
|
|
84
|
+
content_hash: sha256(JSON.stringify(records.map((r) => [r.id, r.record_hash]))),
|
|
85
|
+
title: `Claude prompt history (partial): ${scope.from} to ${scope.to}`,
|
|
86
|
+
cwd, model: null, started_at: timestamps[0], ended_at: timestamps.at(-1)!,
|
|
87
|
+
record_count: records.length, created_at: now, updated_at: now,
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
session, records, raw,
|
|
91
|
+
provenance: { mapping: "claude-history-prompt-slice-v1", partial: true, scope, scanned_lines: scanned,
|
|
92
|
+
selected_prompts: records.length, fixture_sha256: sha256(raw), records: evidence },
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function saveHistorySlice(slice: Awaited<ReturnType<typeof prepareHistorySlice>>, dbPath: string, evidenceDir: string) {
|
|
97
|
+
const lease = isMemoryStorePath(dbPath) ? null : acquireWriterLease(dbPath, { holder: "import-claude-history" });
|
|
98
|
+
try {
|
|
99
|
+
const directory = resolve(evidenceDir);
|
|
100
|
+
mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
101
|
+
writeFileSync(resolve(directory, "selected-history.jsonl"), slice.raw, { mode: 0o600 });
|
|
102
|
+
writeFileSync(resolve(directory, "provenance.json"), JSON.stringify(slice.provenance, null, 2) + "\n", { mode: 0o600 });
|
|
103
|
+
const db = new TrajectoryDb(dbPath);
|
|
104
|
+
try {
|
|
105
|
+
return { ...db.saveSession(slice.session, slice.records), session_id: slice.session.id,
|
|
106
|
+
prompts: slice.records.length, fixture_sha256: slice.provenance.fixture_sha256, evidence: directory };
|
|
107
|
+
} finally { db.close(); }
|
|
108
|
+
} finally { lease?.close(); }
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export async function runHistoryImport(argv: string[]): Promise<void> {
|
|
112
|
+
const { values } = parseArgs({ args: argv, options: {
|
|
113
|
+
history: { type: "string" }, session: { type: "string" }, from: { type: "string" },
|
|
114
|
+
to: { type: "string" }, db: { type: "string" }, evidence: { type: "string" },
|
|
115
|
+
robot: { type: "boolean" }, json: { type: "boolean" },
|
|
116
|
+
} });
|
|
117
|
+
if (!values.history || !values.session || !values.from || !values.to || !values.db || !values.evidence) {
|
|
118
|
+
throw new Error("Required: --history --session --from --to --db --evidence (local private directory)");
|
|
119
|
+
}
|
|
120
|
+
const started = performance.now(), cpu = process.cpuUsage(), baseline = process.memoryUsage().rss;
|
|
121
|
+
const slice = await prepareHistorySlice({ history: values.history, session: values.session, from: values.from, to: values.to });
|
|
122
|
+
const result = saveHistorySlice(slice, values.db, values.evidence);
|
|
123
|
+
const used = process.cpuUsage(cpu);
|
|
124
|
+
console.log(JSON.stringify({ ...result, wall_seconds: (performance.now() - started) / 1000,
|
|
125
|
+
cpu_seconds: (used.user + used.system) / 1e6, rss_baseline_bytes: baseline,
|
|
126
|
+
process_max_rss_bytes: process.resourceUsage().maxRSS * 1024,
|
|
127
|
+
rss_before_exit_bytes: process.memoryUsage().rss, embeddings: "not generated; lexical index only" }));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (import.meta.main) await runHistoryImport(process.argv.slice(2));
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { chmodSync, mkdtempSync, rmSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { TrajectoryDb } from "../src/db.js";
|
|
5
|
+
import { ingestDiscoveredSession, sessionNeedsIngest } from "../src/ingest.js";
|
|
6
|
+
import { scanSessions } from "../src/scanner.js";
|
|
7
|
+
import type { ScanOutcome } from "../src/types.js";
|
|
8
|
+
|
|
9
|
+
process.umask(0o077);
|
|
10
|
+
const [source, path] = process.argv.slice(2);
|
|
11
|
+
if (!["cursor", "opencode"].includes(source) || !path || !/\.(?:db|vscdb|sqlite|sqlite3)$/i.test(path)) {
|
|
12
|
+
throw new Error("Usage: bun scripts/native-history-smoke.ts <cursor|opencode> <native-database-path>");
|
|
13
|
+
}
|
|
14
|
+
const root = mkdtempSync(join(tmpdir(), "trajectories-native-smoke-"));
|
|
15
|
+
chmodSync(root, 0o700);
|
|
16
|
+
const db = new TrajectoryDb(join(root, "trajectories.sqlite"));
|
|
17
|
+
const report = {
|
|
18
|
+
source, candidateLimit: 3, byteLimit: 8 * 1024 * 1024, discovered: 0,
|
|
19
|
+
diagnostics: {} as Record<string, number>, outcomes: [] as ScanOutcome[],
|
|
20
|
+
attempted: 0, stored: 0,
|
|
21
|
+
records: 0, recordKinds: {} as Record<string, number>,
|
|
22
|
+
duplicateFree: false, unchanged: false, needsIngest: true,
|
|
23
|
+
};
|
|
24
|
+
try {
|
|
25
|
+
const { sessions: items, outcomes } = await scanSessions({ sources: [source], roots: { [source]: path }, limit: 3,
|
|
26
|
+
onDiagnostic: diagnostic => { report.diagnostics[diagnostic.code] = (report.diagnostics[diagnostic.code] ?? 0) + 1; },
|
|
27
|
+
});
|
|
28
|
+
report.outcomes = outcomes;
|
|
29
|
+
report.discovered = items.length;
|
|
30
|
+
for (const item of items) {
|
|
31
|
+
report.attempted++;
|
|
32
|
+
const result = await ingestDiscoveredSession(db, item, { embed: false, maxRecordBytes: report.byteLimit });
|
|
33
|
+
if (result.kind !== "imported" || !result.sessionId) continue;
|
|
34
|
+
const records = db.getSessionRecords(result.sessionId);
|
|
35
|
+
report.stored = db.getSessionCount();
|
|
36
|
+
if (!records.some(record => record.record_type !== "meta")) continue;
|
|
37
|
+
report.records = records.length;
|
|
38
|
+
for (const record of records) report.recordKinds[record.record_type] = (report.recordKinds[record.record_type] ?? 0) + 1;
|
|
39
|
+
report.duplicateFree = new Set(records.map(record => record.id)).size === records.length;
|
|
40
|
+
report.unchanged = (await ingestDiscoveredSession(db, item, { embed: false, maxRecordBytes: report.byteLimit })).kind === "unchanged";
|
|
41
|
+
report.needsIngest = sessionNeedsIngest(db, item, { maxRecordBytes: report.byteLimit });
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
console.log(JSON.stringify(report));
|
|
45
|
+
if (!report.records || !report.duplicateFree || !report.unchanged || report.needsIngest) process.exitCode = 1;
|
|
46
|
+
} catch {
|
|
47
|
+
console.log(JSON.stringify({ ...report, error: "native smoke failed; private error details suppressed" }));
|
|
48
|
+
process.exitCode = 1;
|
|
49
|
+
} finally {
|
|
50
|
+
db.close();
|
|
51
|
+
rmSync(root, { recursive: true, force: true });
|
|
52
|
+
}
|