@openpond/evals 0.11.18 → 0.11.20

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.
Files changed (140) hide show
  1. package/dist/connected-evidence/contracts.js +15 -5
  2. package/dist/connected-evidence/imports.js +78 -17
  3. package/dist/connected-evidence/normalize.js +18 -7
  4. package/dist/connected-evidence/sources/claude-branches.js +52 -0
  5. package/dist/connected-evidence/sources/claude-code.js +7 -29
  6. package/dist/connected-evidence/sources/codex-authorization.js +40 -0
  7. package/dist/connected-evidence/sources/codex.js +7 -3
  8. package/dist/connected-evidence/sources/grok-build.js +137 -0
  9. package/dist/connected-evidence/sources/opencode.js +101 -0
  10. package/dist/connected-evidence/sources/pi.js +187 -0
  11. package/dist/graders.js +11 -1
  12. package/dist/learning/budgeted-reward-fixtures.js +1 -0
  13. package/dist/learning/contracts.js +10 -0
  14. package/dist/learning/index.js +1 -0
  15. package/dist/learning/model-judge.js +22 -5
  16. package/dist/learning/reward-calibration-closure.js +110 -0
  17. package/dist/learning/reward-calibration.js +20 -10
  18. package/dist/learning/reward-checks.js +1 -0
  19. package/dist/native-conversations/appimage-runtime.js +131 -0
  20. package/dist/native-conversations/collector-branches.js +79 -0
  21. package/dist/native-conversations/collector-contracts.js +9 -0
  22. package/dist/native-conversations/collector-destinations.js +27 -0
  23. package/dist/native-conversations/collector-errors.js +42 -0
  24. package/dist/native-conversations/collector-progress.js +114 -0
  25. package/dist/native-conversations/collector-store.js +251 -0
  26. package/dist/native-conversations/collector-sync-requests.js +52 -0
  27. package/dist/native-conversations/collector.js +329 -0
  28. package/dist/native-conversations/contracts.js +11 -0
  29. package/dist/native-conversations/database.js +149 -0
  30. package/dist/native-conversations/discovery.js +135 -0
  31. package/dist/native-conversations/history.js +327 -0
  32. package/dist/native-conversations/index.js +11 -0
  33. package/dist/native-conversations/location.js +29 -0
  34. package/dist/native-conversations/openclaw-cold-archive.js +91 -0
  35. package/dist/native-conversations/openclaw-database.js +130 -0
  36. package/dist/native-conversations/readiness.js +4 -0
  37. package/dist/native-conversations/source-locations.js +112 -0
  38. package/dist/native-conversations/supervisor.js +208 -0
  39. package/dist/native-conversations/titles.js +38 -0
  40. package/dist/rewards.js +1 -1
  41. package/dist/types/connected-evidence/contracts.d.ts +15 -0
  42. package/dist/types/connected-evidence/contracts.d.ts.map +1 -1
  43. package/dist/types/connected-evidence/imports.d.ts +7 -0
  44. package/dist/types/connected-evidence/imports.d.ts.map +1 -1
  45. package/dist/types/connected-evidence/normalize.d.ts +7 -0
  46. package/dist/types/connected-evidence/normalize.d.ts.map +1 -1
  47. package/dist/types/connected-evidence/sources/claude-branches.d.ts +19 -0
  48. package/dist/types/connected-evidence/sources/claude-branches.d.ts.map +1 -0
  49. package/dist/types/connected-evidence/sources/claude-code.d.ts +5 -1
  50. package/dist/types/connected-evidence/sources/claude-code.d.ts.map +1 -1
  51. package/dist/types/connected-evidence/sources/codex-authorization.d.ts +18 -0
  52. package/dist/types/connected-evidence/sources/codex-authorization.d.ts.map +1 -0
  53. package/dist/types/connected-evidence/sources/codex.d.ts +5 -1
  54. package/dist/types/connected-evidence/sources/codex.d.ts.map +1 -1
  55. package/dist/types/connected-evidence/sources/grok-build.d.ts +79 -0
  56. package/dist/types/connected-evidence/sources/grok-build.d.ts.map +1 -0
  57. package/dist/types/connected-evidence/sources/history.d.ts +10 -2
  58. package/dist/types/connected-evidence/sources/history.d.ts.map +1 -1
  59. package/dist/types/connected-evidence/sources/opencode.d.ts +78 -0
  60. package/dist/types/connected-evidence/sources/opencode.d.ts.map +1 -0
  61. package/dist/types/connected-evidence/sources/pi.d.ts +79 -0
  62. package/dist/types/connected-evidence/sources/pi.d.ts.map +1 -0
  63. package/dist/types/graders.d.ts +81 -0
  64. package/dist/types/graders.d.ts.map +1 -1
  65. package/dist/types/learning/budgeted-reward-fixtures.d.ts +2 -1
  66. package/dist/types/learning/budgeted-reward-fixtures.d.ts.map +1 -1
  67. package/dist/types/learning/contracts.d.ts +167 -0
  68. package/dist/types/learning/contracts.d.ts.map +1 -1
  69. package/dist/types/learning/index.d.ts +1 -0
  70. package/dist/types/learning/index.d.ts.map +1 -1
  71. package/dist/types/learning/judge-budget.d.ts +3 -0
  72. package/dist/types/learning/judge-budget.d.ts.map +1 -1
  73. package/dist/types/learning/model-judge.d.ts +6 -1
  74. package/dist/types/learning/model-judge.d.ts.map +1 -1
  75. package/dist/types/learning/operations.d.ts +44 -0
  76. package/dist/types/learning/operations.d.ts.map +1 -1
  77. package/dist/types/learning/repository.d.ts +81 -0
  78. package/dist/types/learning/repository.d.ts.map +1 -1
  79. package/dist/types/learning/reward-calibration-closure.d.ts +2323 -0
  80. package/dist/types/learning/reward-calibration-closure.d.ts.map +1 -0
  81. package/dist/types/learning/reward-calibration.d.ts +1 -1
  82. package/dist/types/learning/reward-calibration.d.ts.map +1 -1
  83. package/dist/types/learning/reward-checks.d.ts +35 -0
  84. package/dist/types/learning/reward-checks.d.ts.map +1 -1
  85. package/dist/types/learning/transport.d.ts +103 -0
  86. package/dist/types/learning/transport.d.ts.map +1 -1
  87. package/dist/types/native-conversations/appimage-runtime.d.ts +12 -0
  88. package/dist/types/native-conversations/appimage-runtime.d.ts.map +1 -0
  89. package/dist/types/native-conversations/collector-branches.d.ts +22 -0
  90. package/dist/types/native-conversations/collector-branches.d.ts.map +1 -0
  91. package/dist/types/native-conversations/collector-contracts.d.ts +92 -0
  92. package/dist/types/native-conversations/collector-contracts.d.ts.map +1 -0
  93. package/dist/types/native-conversations/collector-destinations.d.ts +18 -0
  94. package/dist/types/native-conversations/collector-destinations.d.ts.map +1 -0
  95. package/dist/types/native-conversations/collector-errors.d.ts +13 -0
  96. package/dist/types/native-conversations/collector-errors.d.ts.map +1 -0
  97. package/dist/types/native-conversations/collector-progress.d.ts +24 -0
  98. package/dist/types/native-conversations/collector-progress.d.ts.map +1 -0
  99. package/dist/types/native-conversations/collector-store.d.ts +31 -0
  100. package/dist/types/native-conversations/collector-store.d.ts.map +1 -0
  101. package/dist/types/native-conversations/collector-sync-requests.d.ts +25 -0
  102. package/dist/types/native-conversations/collector-sync-requests.d.ts.map +1 -0
  103. package/dist/types/native-conversations/collector.d.ts +8 -0
  104. package/dist/types/native-conversations/collector.d.ts.map +1 -0
  105. package/dist/types/native-conversations/contracts.d.ts +47 -0
  106. package/dist/types/native-conversations/contracts.d.ts.map +1 -0
  107. package/dist/types/native-conversations/database.d.ts +14 -0
  108. package/dist/types/native-conversations/database.d.ts.map +1 -0
  109. package/dist/types/native-conversations/discovery.d.ts +9 -0
  110. package/dist/types/native-conversations/discovery.d.ts.map +1 -0
  111. package/dist/types/native-conversations/history.d.ts +23 -0
  112. package/dist/types/native-conversations/history.d.ts.map +1 -0
  113. package/dist/types/native-conversations/index.d.ts +12 -0
  114. package/dist/types/native-conversations/index.d.ts.map +1 -0
  115. package/dist/types/native-conversations/location.d.ts +3 -0
  116. package/dist/types/native-conversations/location.d.ts.map +1 -0
  117. package/dist/types/native-conversations/openclaw-cold-archive.d.ts +8 -0
  118. package/dist/types/native-conversations/openclaw-cold-archive.d.ts.map +1 -0
  119. package/dist/types/native-conversations/openclaw-database.d.ts +14 -0
  120. package/dist/types/native-conversations/openclaw-database.d.ts.map +1 -0
  121. package/dist/types/native-conversations/readiness.d.ts +5 -0
  122. package/dist/types/native-conversations/readiness.d.ts.map +1 -0
  123. package/dist/types/native-conversations/source-locations.d.ts +8 -0
  124. package/dist/types/native-conversations/source-locations.d.ts.map +1 -0
  125. package/dist/types/native-conversations/supervisor.d.ts +21 -0
  126. package/dist/types/native-conversations/supervisor.d.ts.map +1 -0
  127. package/dist/types/native-conversations/titles.d.ts +4 -0
  128. package/dist/types/native-conversations/titles.d.ts.map +1 -0
  129. package/dist/types/rewards.d.ts +50 -0
  130. package/dist/types/rewards.d.ts.map +1 -1
  131. package/dist/types/telemetry-analysis.d.ts +1 -1
  132. package/dist/types/telemetry-bundle.d.ts +2 -2
  133. package/dist/types/telemetry-catalog.d.ts +21 -21
  134. package/dist/types/telemetry.d.ts +2 -2
  135. package/package.json +11 -3
  136. package/schemas/learning/v1/command-request.schema.json +122 -91
  137. package/schemas/learning/v1/decision.schema.json +63 -0
  138. package/schemas/learning/v1/grade.schema.json +91 -0
  139. package/schemas/learning/v1/reward_check.schema.json +91 -0
  140. package/schemas/learning/v1/source.schema.json +28 -0
@@ -0,0 +1,130 @@
1
+ import { DatabaseSync } from "node:sqlite";
2
+ import { zstdDecompressSync } from "node:zlib";
3
+ import { createHash } from "node:crypto";
4
+ import { readOpenClawColdArchive } from "./openclaw-cold-archive.js";
5
+ import { NATIVE_READ_LIMIT, } from "./contracts.js";
6
+ function open(source) {
7
+ const database = new DatabaseSync(source.root, {
8
+ readOnly: true,
9
+ allowExtension: false,
10
+ enableDoubleQuotedStringLiterals: false,
11
+ });
12
+ database.exec("PRAGMA query_only=ON; PRAGMA busy_timeout=1000; BEGIN");
13
+ return database;
14
+ }
15
+ function has(database, table) {
16
+ return !!database
17
+ .prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?")
18
+ .get(table);
19
+ }
20
+ export function listOpenClawSessions(source, input) {
21
+ const database = open(source);
22
+ try {
23
+ // Every hot transcript retains a native session header, including prior reset windows.
24
+ const archiveUnion = has(database, "session_transcript_archives")
25
+ ? "UNION ALL SELECT session_id AS id,created_at AS updated,archive_sha256 AS revision FROM session_transcript_archives"
26
+ : "";
27
+ const coldUnion = has(database, "session_transcript_cold_archives")
28
+ ? "UNION ALL SELECT session_id AS id,archived_at AS updated,archive_sha256 AS revision FROM session_transcript_cold_archives"
29
+ : "";
30
+ const rows = database
31
+ .prepare(`SELECT id,MAX(updated) AS updated,MAX(revision) AS revision FROM (
32
+ SELECT session_id AS id,MAX(created_at) AS updated,CAST(MAX(seq) AS TEXT) AS revision FROM transcript_events GROUP BY session_id
33
+ ${archiveUnion} ${coldUnion}) WHERE id > ? GROUP BY id ORDER BY id LIMIT ?`)
34
+ .all(input.cursor ?? "", input.limit + 1);
35
+ const items = rows.slice(0, input.limit).map((row) => ({
36
+ nativeSessionId: String(row.id),
37
+ sourceInstanceId: source.instanceId,
38
+ path: String(row.id),
39
+ title: String(row.id),
40
+ cwd: null,
41
+ updatedAt: new Date(Number(row.updated) || 0).toISOString(),
42
+ }));
43
+ return {
44
+ items,
45
+ nextCursor: rows.length > input.limit ? items.at(-1).nativeSessionId : null,
46
+ };
47
+ }
48
+ finally {
49
+ database.close();
50
+ }
51
+ }
52
+ export function readOpenClawSession(source, sessionId) {
53
+ const database = open(source);
54
+ try {
55
+ if (has(database, "session_transcript_cold_archives")) {
56
+ const cold = readOpenClawColdArchive(database, source, sessionId);
57
+ if (cold)
58
+ return cold;
59
+ }
60
+ const hasHot = database
61
+ .prepare("SELECT 1 FROM transcript_events WHERE session_id=? LIMIT 1")
62
+ .get(sessionId);
63
+ if (!hasHot) {
64
+ if (!has(database, "session_transcript_archives"))
65
+ throw new Error("OpenClaw archive is unavailable.");
66
+ const metadata = database
67
+ .prepare("SELECT archive_name,length(archive_blob) AS bytes FROM session_transcript_archives WHERE session_id=? ORDER BY created_at DESC LIMIT 1")
68
+ .get(sessionId);
69
+ if (!metadata || Number(metadata.bytes) > NATIVE_READ_LIMIT)
70
+ throw new Error("OpenClaw archive is missing or exceeds the retained byte limit.");
71
+ const archive = database
72
+ .prepare("SELECT archive_blob,archive_sha256,encoding FROM session_transcript_archives WHERE archive_name=? AND session_id=?")
73
+ .get(String(metadata.archive_name), sessionId);
74
+ if (!(archive.archive_blob instanceof Uint8Array) ||
75
+ createHash("sha256").update(archive.archive_blob).digest("hex") !==
76
+ archive.archive_sha256)
77
+ throw new Error("OpenClaw archive checksum differs from its retained receipt.");
78
+ if (archive.encoding !== "zstd" && archive.encoding !== "identity")
79
+ throw new Error("Unsupported OpenClaw archive encoding.");
80
+ const bytes = archive.encoding === "zstd"
81
+ ? zstdDecompressSync(archive.archive_blob, {
82
+ maxOutputLength: NATIVE_READ_LIMIT,
83
+ })
84
+ : archive.archive_blob;
85
+ const text = new TextDecoder("utf8", { fatal: true }).decode(bytes);
86
+ const header = JSON.parse(text.split("\n", 1)[0]);
87
+ if (header.type !== "session" || header.id !== sessionId)
88
+ throw new Error("OpenClaw archive identity differs from selected session.");
89
+ return { path: `${sessionId}.jsonl`, text };
90
+ }
91
+ const total = database
92
+ .prepare("SELECT COUNT(*) AS n,SUM(COALESCE(event_utf8_bytes,length(CAST(event_json AS BLOB)),0)) AS bytes FROM transcript_events WHERE session_id=?")
93
+ .get(sessionId);
94
+ if (Number(total.n) > 100000 || Number(total.bytes) > NATIVE_READ_LIMIT)
95
+ throw new Error("OpenClaw transcript exceeds the retained size limit.");
96
+ const rows = database
97
+ .prepare("SELECT seq,event_json,event_zstd,event_utf8_bytes FROM transcript_events WHERE session_id=? ORDER BY seq LIMIT 100001")
98
+ .all(sessionId);
99
+ let bytes = 0;
100
+ const lines = rows.map((row) => {
101
+ let text;
102
+ if (typeof row.event_json === "string")
103
+ text = row.event_json;
104
+ else {
105
+ if (!(row.event_zstd instanceof Uint8Array) ||
106
+ Number(row.event_utf8_bytes) > NATIVE_READ_LIMIT)
107
+ throw new Error("Unsupported OpenClaw compressed transcript record.");
108
+ const decoded = zstdDecompressSync(row.event_zstd, {
109
+ maxOutputLength: NATIVE_READ_LIMIT,
110
+ });
111
+ if (decoded.length !== Number(row.event_utf8_bytes))
112
+ throw new Error("OpenClaw compressed transcript size differs from its receipt.");
113
+ text = new TextDecoder("utf8", { fatal: true }).decode(decoded);
114
+ }
115
+ bytes += Buffer.byteLength(text);
116
+ if (bytes > NATIVE_READ_LIMIT)
117
+ throw new Error("OpenClaw transcript exceeds retained size limit.");
118
+ return text;
119
+ });
120
+ if (!lines.length)
121
+ throw new Error("OpenClaw transcript is unavailable.");
122
+ const header = JSON.parse(lines[0]);
123
+ if (header.type !== "session" || header.id !== sessionId)
124
+ throw new Error("OpenClaw transcript identity differs from selected session.");
125
+ return { path: `${sessionId}.jsonl`, text: lines.join("\n") + "\n" };
126
+ }
127
+ finally {
128
+ database.close();
129
+ }
130
+ }
@@ -0,0 +1,4 @@
1
+ /** An empty/incomplete session is discovered history, but not a training case. */
2
+ export class NativeSessionNotReadyError extends Error {
3
+ constructor() { super("This session has no retained user request yet."); }
4
+ }
@@ -0,0 +1,112 @@
1
+ import { opendir, readFile, stat } from "node:fs/promises";
2
+ import { basename, dirname, join, resolve } from "node:path";
3
+ export function hermesHome(home, env) {
4
+ const configured = env.HERMES_HOME?.trim();
5
+ if (configured) {
6
+ const expanded = configured.replace(/\$(\w+)|\$\{([^}]+)\}/gu, (match, bare, braced) => env[bare || braced] ?? match);
7
+ return resolve(expanded === "~" ? home : expanded.startsWith("~/") ? join(home, expanded.slice(2)) : expanded);
8
+ }
9
+ const suffix = env.HERMES_DATA_DIR_SUFFIX || "";
10
+ return process.platform === "win32"
11
+ ? join(env.LOCALAPPDATA?.trim() || join(home, "AppData", "Local"), `hermes${suffix}`)
12
+ : join(home, `.hermes${suffix}`);
13
+ }
14
+ const isDirectory = (path) => stat(path).then((s) => s.isDirectory()).catch(() => false);
15
+ const isFile = (path) => stat(path).then((s) => s.isFile()).catch(() => false);
16
+ /** A bounded metadata-only inventory. No profile config or credential files are read. */
17
+ async function profileNames(root, valid) {
18
+ const names = [];
19
+ const directory = await opendir(root).catch(() => null);
20
+ if (!directory)
21
+ return names;
22
+ let entries = 0;
23
+ for await (const entry of directory) {
24
+ if (++entries > 100)
25
+ throw new Error("More than 100 profile entries. Select the exact --source-path.");
26
+ if (entry.isDirectory() && !entry.isSymbolicLink() && valid(entry.name))
27
+ names.push(entry.name);
28
+ }
29
+ return names.sort();
30
+ }
31
+ export async function hermesLocations(root) {
32
+ // A launcher may already have selected a named profile. Never enumerate its siblings.
33
+ if (basename(dirname(root)) === "profiles")
34
+ return [{ root }];
35
+ const profiles = join(root, "profiles");
36
+ try {
37
+ const names = await profileNames(profiles, (name) => /^[a-z0-9][a-z0-9_-]{0,63}$/u.test(name));
38
+ const locations = [];
39
+ // Retained state.db is the only identity marker relevant to this history reader.
40
+ // Deleted profiles are deliberately excluded, even if their old DB remains.
41
+ for (const name of names) {
42
+ if (await stat(join(profiles, ".deleted", name)).then(() => true).catch(() => false))
43
+ continue;
44
+ if (await isFile(join(profiles, name, "state.db")))
45
+ locations.push({ root: join(profiles, name) });
46
+ }
47
+ let active = "";
48
+ const activeFile = join(root, "active_profile");
49
+ if (await stat(activeFile).then((s) => s.isFile() && s.size <= 1024).catch(() => false))
50
+ active = (await readFile(activeFile, "utf8")).replace(/^\uFEFF/u, "").trim().toLowerCase();
51
+ if (active && active !== "default") {
52
+ if (!/^[a-z0-9][a-z0-9_-]{0,63}$/u.test(active))
53
+ return [{ root, reason: "Hermes active profile is invalid. Select the exact --source-path." }];
54
+ const selected = locations.findIndex((location) => location.root === join(profiles, active));
55
+ if (selected < 0)
56
+ locations.unshift({ root: join(profiles, active), reason: "Hermes active profile has no retained live state database. Select a profile explicitly." });
57
+ else
58
+ locations.unshift(...locations.splice(selected, 1));
59
+ }
60
+ if (await isFile(join(root, "state.db")) || !locations.length)
61
+ locations.push({ root });
62
+ return locations;
63
+ }
64
+ catch (error) {
65
+ return [{ root, reason: error instanceof Error ? error.message : "Cannot inventory Hermes profiles. Select the exact --source-path." }];
66
+ }
67
+ }
68
+ function validOmpProfile(name) {
69
+ return /^[a-z0-9][a-z0-9._-]{0,63}$/u.test(name) && !name.endsWith(".") &&
70
+ !/^(?:con|prn|aux|nul|com[0-9]|lpt[0-9])(?:\.|$)/iu.test(name);
71
+ }
72
+ export async function ompLocations(home, env) {
73
+ const base = join(home, env.PI_CONFIG_DIR || ".omp");
74
+ const selected = (env.OMP_PROFILE !== undefined ? env.OMP_PROFILE : env.PI_PROFILE)?.trim();
75
+ if (selected && selected !== "default" && !validOmpProfile(selected))
76
+ return [{ root: base, reason: "Oh My Pi profile is invalid. Select the exact --source-path." }];
77
+ // Launch-time session override has higher priority than the agent directory.
78
+ if (env.PI_CODING_AGENT_SESSION_DIR)
79
+ return [{ root: resolve(env.PI_CODING_AGENT_SESSION_DIR) }];
80
+ const xdg = (process.platform === "linux" || process.platform === "darwin") && env.XDG_DATA_HOME
81
+ ? join(env.XDG_DATA_HOME, "omp") : undefined;
82
+ async function location(profile) {
83
+ const standard = profile ? join(base, "profiles", profile, "agent") : join(base, "agent");
84
+ // Named profiles ignore the default-profile agent override. A native launch
85
+ // may export its own profile-derived value; explicit empty OMP_PROFILE clears it.
86
+ const inheritedProfile = env.PI_PROFILE?.trim();
87
+ const inherited = inheritedProfile && validOmpProfile(inheritedProfile)
88
+ ? join(base, "profiles", inheritedProfile, "agent") : undefined;
89
+ const override = !profile && env.PI_CODING_AGENT_DIR && env.PI_CODING_AGENT_DIR !== inherited
90
+ ? resolve(env.PI_CODING_AGENT_DIR) : undefined;
91
+ const candidate = xdg && (profile ? join(xdg, "profiles", profile) : xdg);
92
+ return { root: (!override || override === standard) && candidate && await isDirectory(candidate) ? candidate : override || standard };
93
+ }
94
+ if (selected || env.OMP_PROFILE !== undefined || env.PI_PROFILE !== undefined || env.PI_CODING_AGENT_DIR)
95
+ return [await location(selected && selected !== "default" ? selected : undefined)];
96
+ try {
97
+ const names = new Set(await profileNames(join(base, "profiles"), validOmpProfile));
98
+ if (xdg)
99
+ for (const name of await profileNames(join(xdg, "profiles"), validOmpProfile))
100
+ names.add(name);
101
+ const result = [await location()];
102
+ for (const name of [...names].sort()) {
103
+ const candidate = await location(name);
104
+ if (await isDirectory(join(candidate.root, "sessions")))
105
+ result.push(candidate);
106
+ }
107
+ return result;
108
+ }
109
+ catch (error) {
110
+ return [{ root: base, reason: error instanceof Error ? error.message : "Cannot inventory Oh My Pi profiles. Select the exact --source-path." }];
111
+ }
112
+ }
@@ -0,0 +1,208 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { retainAppImageRuntime, removeAppImageRuntimes } from "./appimage-runtime.js";
3
+ import { execFile } from "node:child_process";
4
+ import { promisify } from "node:util";
5
+ import { mkdir, writeFile, rm, rename } from "node:fs/promises";
6
+ import { homedir } from "node:os";
7
+ import { isAbsolute, join } from "node:path";
8
+ import { contentHash } from "@openpond/harness";
9
+ import { CollectorStore } from "./collector-store.js";
10
+ const execute = promisify(execFile);
11
+ const command = async (file, args) => {
12
+ await execute(file, args, {
13
+ timeout: 15000,
14
+ maxBuffer: 16384,
15
+ windowsHide: true,
16
+ });
17
+ };
18
+ const xml = (value) => value
19
+ .replace(/&/gu, "&amp;")
20
+ .replace(/</gu, "&lt;")
21
+ .replace(/>/gu, "&gt;")
22
+ .replace(/"/gu, "&quot;");
23
+ const systemd = (value) => `"${value.replace(/\\/gu, "\\\\").replace(/"/gu, '\\"').replace(/%/gu, "%%").replace(/\$/gu, "$$")}"`;
24
+ function identity(directory) {
25
+ return `openpond-import-${contentHash(directory).slice(0, 16)}`;
26
+ }
27
+ export async function configureCollector(directory, connection) {
28
+ const store = await CollectorStore.open(directory);
29
+ try {
30
+ store.put(connection);
31
+ }
32
+ finally {
33
+ store.close();
34
+ }
35
+ }
36
+ export async function collectorStatus(directory) {
37
+ const store = await CollectorStore.open(directory);
38
+ try {
39
+ return store.status();
40
+ }
41
+ finally {
42
+ store.close();
43
+ }
44
+ }
45
+ export async function controlCollector(directory, action, connectionId) {
46
+ const store = await CollectorStore.open(directory);
47
+ try {
48
+ if (action === "start" || action === "stop")
49
+ store.set("desiredState", action === "start" ? "running" : "stopped");
50
+ else if (action === "sync")
51
+ store.set("syncNow", "yes");
52
+ else {
53
+ const connection = store
54
+ .connections()
55
+ .find((item) => item.id === connectionId);
56
+ if (!connection)
57
+ throw new Error("Select a retained connection.");
58
+ store.put({
59
+ ...connection,
60
+ state: action === "pause"
61
+ ? "paused"
62
+ : action === "resume"
63
+ ? "active"
64
+ : "disconnected",
65
+ });
66
+ }
67
+ return store.status();
68
+ }
69
+ finally {
70
+ store.close();
71
+ }
72
+ }
73
+ /** Per-user logon supervision. Installing does not override the retained Stop intent. */
74
+ export async function installCollectorService(input) {
75
+ if (!isAbsolute(input.directory) ||
76
+ !isAbsolute(input.executable) ||
77
+ [input.directory, input.executable, ...input.args].some((value) => /[\r\n\0]/u.test(value)))
78
+ throw new Error("Collector service requires absolute paths and single-line arguments.");
79
+ const retainedRuntime = await retainAppImageRuntime(input);
80
+ if (retainedRuntime)
81
+ input = { ...input, ...retainedRuntime, environment: { ...input.environment, ELECTRON_RUN_AS_NODE: "1", APPIMAGE_EXTRACT_AND_RUN: "1" } };
82
+ const environment = Object.entries(input.environment ?? {});
83
+ if (environment.some(([key, value]) => !["OPENPOND_HOME", "ELECTRON_RUN_AS_NODE", "APPIMAGE_EXTRACT_AND_RUN"].includes(key) ||
84
+ typeof value !== "string" ||
85
+ /[\r\n\0]/u.test(value)))
86
+ throw new Error("Unsupported service environment setting.");
87
+ const home = input.home ?? homedir(), name = identity(input.directory);
88
+ const launch = [
89
+ ...input.args,
90
+ "import",
91
+ "service",
92
+ "run",
93
+ "--collector-dir",
94
+ input.directory,
95
+ ];
96
+ if (process.platform === "linux") {
97
+ const directory = join(home, ".config/systemd/user");
98
+ await mkdir(directory, { recursive: true, mode: 0o700 });
99
+ await atomicServiceFile(join(directory, `${name}.service`), `[Unit]\nDescription=OpenPond conversation importer\nAfter=network-online.target\n[Service]\nType=simple\n${environment.map(([key, value]) => `Environment=${systemd(`${key}=${value}`)}`).join("\n")}\nExecStart=${[input.executable, ...launch].map(systemd).join(" ")}\nRestart=on-failure\nRestartSec=5\nUMask=0077\nNoNewPrivileges=true\n[Install]\nWantedBy=default.target\n`, { mode: 0o600 });
100
+ await command("systemctl", ["--user", "daemon-reload"]);
101
+ await command("systemctl", ["--user", "enable", `${name}.service`]);
102
+ }
103
+ else if (process.platform === "darwin") {
104
+ const directory = join(home, "Library/LaunchAgents");
105
+ await mkdir(directory, { recursive: true, mode: 0o700 });
106
+ const file = join(directory, `${name}.plist`);
107
+ let loaded = false;
108
+ try {
109
+ await command("launchctl", ["print", `gui/${process.getuid()}/${name}`]);
110
+ loaded = true;
111
+ }
112
+ catch {
113
+ /* A first installation has no loaded job. Bootstrap below reports actual setup errors. */
114
+ }
115
+ if (loaded)
116
+ await command("launchctl", [
117
+ "bootout",
118
+ `gui/${process.getuid()}/${name}`,
119
+ ]);
120
+ await writeFile(file, `<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>Label</key><string>${name}</string><key>ProgramArguments</key><array>${[input.executable, ...launch].map((value) => `<string>${xml(value)}</string>`).join("")}</array><key>EnvironmentVariables</key><dict>${environment.map(([key, value]) => `<key>${xml(key)}</key><string>${xml(value)}</string>`).join("")}</dict><key>RunAtLoad</key><true/><key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict><key>ThrottleInterval</key><integer>5</integer></dict></plist>`, { mode: 0o600 });
121
+ await command("launchctl", ["bootstrap", `gui/${process.getuid()}`, file]);
122
+ }
123
+ else if (process.platform === "win32") {
124
+ const user = (await execute("whoami", [], { timeout: 5000, maxBuffer: 1024 })).stdout.trim();
125
+ const file = join(input.directory, "scheduled-task.xml");
126
+ await mkdir(input.directory, { recursive: true });
127
+ const quoted = (value) => `"${value.replace(/(\\*)"/gu, '$1$1\\"').replace(/(\\+)$/u, "$1$1")}"`;
128
+ const script = join(input.directory, "start-collector.ps1");
129
+ const ps = (value) => `'${value.replace(/'/gu, "''")}'`;
130
+ await writeFile(script, `${environment.map(([key, value]) => `$env:${key} = ${ps(value)}`).join("\n")}\n& ${[input.executable, ...launch].map(ps).join(" ")}\nexit $LASTEXITCODE\n`, { mode: 0o600 });
131
+ await writeFile(file, `<?xml version="1.0"?><Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"><Triggers><LogonTrigger><Enabled>true</Enabled><UserId>${xml(user)}</UserId></LogonTrigger></Triggers><Principals><Principal id="Owner"><UserId>${xml(user)}</UserId><LogonType>InteractiveToken</LogonType><RunLevel>LeastPrivilege</RunLevel></Principal></Principals><Settings><MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><ExecutionTimeLimit>PT0S</ExecutionTimeLimit><RestartOnFailure><Interval>PT1M</Interval><Count>999</Count></RestartOnFailure></Settings><Actions Context="Owner"><Exec><Command>powershell.exe</Command><Arguments>${xml(["-NoProfile", "-NonInteractive", "-File", script].map(quoted).join(" "))}</Arguments></Exec></Actions></Task>`, { mode: 0o600 });
132
+ await command("schtasks", ["/Create", "/TN", name, "/XML", file, "/F"]);
133
+ }
134
+ else
135
+ throw new Error("This OS has no qualified per-user supervisor. Run the collector in the foreground.");
136
+ return {
137
+ name,
138
+ platform: process.platform,
139
+ status: await collectorStatus(input.directory),
140
+ };
141
+ }
142
+ /** Removing supervision preserves receipts, pending uploads and retained datasets. */
143
+ export async function uninstallCollectorService(directory, home = homedir()) {
144
+ await controlCollector(directory, "stop");
145
+ const name = identity(directory);
146
+ if (process.platform === "linux") {
147
+ await command("systemctl", [
148
+ "--user",
149
+ "disable",
150
+ "--now",
151
+ `${name}.service`,
152
+ ]);
153
+ await rm(join(home, ".config/systemd/user", `${name}.service`), {
154
+ force: true,
155
+ });
156
+ await command("systemctl", ["--user", "daemon-reload"]);
157
+ }
158
+ else if (process.platform === "darwin") {
159
+ await command("launchctl", ["bootout", `gui/${process.getuid()}/${name}`]);
160
+ await rm(join(home, "Library/LaunchAgents", `${name}.plist`), {
161
+ force: true,
162
+ });
163
+ }
164
+ else if (process.platform === "win32") {
165
+ await command("schtasks", ["/End", "/TN", name]);
166
+ await command("schtasks", ["/Delete", "/TN", name, "/F"]);
167
+ await rm(join(directory, "scheduled-task.xml"), { force: true });
168
+ await rm(join(directory, "start-collector.ps1"), { force: true });
169
+ }
170
+ else
171
+ throw new Error("No per-user supervisor is available.");
172
+ if (process.platform === "linux")
173
+ await removeAppImageRuntimes(directory);
174
+ return collectorStatus(directory);
175
+ }
176
+ export async function startCollectorService(directory) {
177
+ await controlCollector(directory, "start");
178
+ const name = identity(directory);
179
+ try {
180
+ if (process.platform === "linux")
181
+ await command("systemctl", ["--user", "restart", `${name}.service`]);
182
+ else if (process.platform === "darwin")
183
+ await command("launchctl", [
184
+ "kickstart",
185
+ "-k",
186
+ `gui/${process.getuid()}/${name}`,
187
+ ]);
188
+ else if (process.platform === "win32")
189
+ await command("schtasks", ["/Run", "/TN", name]);
190
+ else
191
+ throw new Error("No per-user supervisor is available.");
192
+ }
193
+ catch (error) {
194
+ await controlCollector(directory, "stop");
195
+ throw error;
196
+ }
197
+ return collectorStatus(directory);
198
+ }
199
+ async function atomicServiceFile(file, text, options) {
200
+ const temporary = `${file}.${randomUUID()}.tmp`;
201
+ try {
202
+ await writeFile(temporary, text, { ...options, flag: "wx" });
203
+ await rename(temporary, file);
204
+ }
205
+ finally {
206
+ await rm(temporary, { force: true });
207
+ }
208
+ }
@@ -0,0 +1,38 @@
1
+ import { object } from "../connected-evidence/normalize.js";
2
+ function titleText(value) {
3
+ if (typeof value !== "string")
4
+ return null;
5
+ return value.replace(/\s+/gu, " ").trim().slice(0, 160) || null;
6
+ }
7
+ /** Retained provider titles take precedence over a preview of the first real user prompt. */
8
+ export function claudeConversationTitle(rows, sessionId) {
9
+ const owned = rows.filter((row) => row.sessionId === undefined || row.sessionId === sessionId);
10
+ for (const row of [...owned].reverse()) {
11
+ if (row.type === "custom-title") {
12
+ const title = titleText(row.customTitle);
13
+ if (title)
14
+ return title;
15
+ }
16
+ }
17
+ for (const row of [...owned].reverse()) {
18
+ if (row.type === "summary") {
19
+ const title = titleText(row.summary);
20
+ if (title)
21
+ return title;
22
+ }
23
+ }
24
+ for (const row of owned) {
25
+ if (row.type !== "user" || row.sessionId !== sessionId || row.isMeta || row.isSidechain)
26
+ continue;
27
+ const content = object(row.message).content;
28
+ const title = titleText(Array.isArray(content)
29
+ ? content.filter((part) => object(part).type === "text").map((part) => object(part).text).filter((part) => typeof part === "string").join(" ")
30
+ : content);
31
+ if (title)
32
+ return title;
33
+ }
34
+ return sessionId;
35
+ }
36
+ export function retainedConversationTitle(value, sessionId) {
37
+ return titleText(value) ?? sessionId;
38
+ }
package/dist/rewards.js CHANGED
@@ -163,7 +163,7 @@ export async function executeRewardBinding(input) {
163
163
  }
164
164
  }
165
165
  else {
166
- const [evidence] = await gradeEvidence({ task: input.task, evidence: input.evidence, graders: [compileSource(source, reward)], modelJudge: input.modelJudge, customVerifier: input.customVerifier, purpose: input.purpose, signal: input.signal });
166
+ const [evidence] = await gradeEvidence({ task: input.task, evidence: input.evidence, evaluatorContext: input.evaluatorContext, graders: [compileSource(source, reward)], modelJudge: input.modelJudge, customVerifier: input.customVerifier, purpose: input.purpose, signal: input.signal });
167
167
  if (!evidence)
168
168
  throw new LearningDomainError("reward_evidence_missing");
169
169
  Object.assign(result, { status: evidence.score === null ? "unavailable" : "scored", rawScore: evidence.score, passed: evidence.score === null ? null : evidence.passed, evidenceHashes: [evidence.contentHash], graderEvidence: evidence, message: evidence.feedback.join("\n") });
@@ -18,6 +18,10 @@ export declare const ConnectedSourceKindSchema: z.ZodEnum<{
18
18
  native_work: "native_work";
19
19
  codex: "codex";
20
20
  claude_code: "claude_code";
21
+ opencode: "opencode";
22
+ grok_build: "grok_build";
23
+ pi: "pi";
24
+ oh_my_pi: "oh_my_pi";
21
25
  }>;
22
26
  export declare const ConnectedUsageSchema: z.ZodObject<{
23
27
  invocationId: z.ZodString;
@@ -117,11 +121,19 @@ export declare const ConnectedSessionSchema: z.ZodObject<{
117
121
  native_work: "native_work";
118
122
  codex: "codex";
119
123
  claude_code: "claude_code";
124
+ opencode: "opencode";
125
+ grok_build: "grok_build";
126
+ pi: "pi";
127
+ oh_my_pi: "oh_my_pi";
120
128
  }>;
121
129
  sessionId: z.ZodString;
122
130
  branchId: z.ZodNullable<z.ZodString>;
123
131
  parentSessionId: z.ZodNullable<z.ZodString>;
124
132
  exporterVersion: z.ZodNullable<z.ZodString>;
133
+ acquisition: z.ZodOptional<z.ZodObject<{
134
+ machineId: z.ZodString;
135
+ sourceInstanceId: z.ZodString;
136
+ }, z.core.$strict>>;
125
137
  sourceFiles: z.ZodArray<z.ZodObject<{
126
138
  path: z.ZodString;
127
139
  contentHash: z.ZodString;
@@ -252,6 +264,9 @@ export type ConnectedFile = {
252
264
  text: string;
253
265
  };
254
266
  export declare function hasRecordedConnectedAnswer(event: ConnectedEvent): boolean;
267
+ /** Status/discovery returns no evaluator payload. Large retained histories still
268
+ * require the exact session, input, observed-output and answer hashes to match. */
269
+ export declare function resolveConnectedBoundaryMetadata(sessionValue: unknown, boundaryId: string): ConnectedBoundary;
255
270
  /** Bytes stay in one immutable snapshot; cases retain cutoffs, not copied history. */
256
271
  export declare function resolveConnectedBoundary(sessionValue: unknown, boundaryId: string): {
257
272
  input: {
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../../../src/connected-evidence/contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,0BAA0B,EAAG,+BAAwC,CAAC;AACnF,eAAO,MAAM,4BAA4B,EAAG,sBAA+B,CAAC;AAC5E,eAAO,MAAM,yBAAyB;;;;;;;;;CACuF,CAAC;AAK9H,eAAO,MAAM,yBAAyB;;;;;;;EAAuF,CAAC;AAC9H,eAAO,MAAM,oBAAoB;;;;;;;;;;;kBAGtB,CAAC;AACZ,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAMtB,CAAC;AACZ,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAQzB,CAAC;AACZ,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBASxB,CAAC;AACZ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC5E,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAC3D,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,cAAc,WAK/D;AAED,sFAAsF;AACtF,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBjF"}
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../../../src/connected-evidence/contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,0BAA0B,EAAG,+BAAwC,CAAC;AACnF,eAAO,MAAM,4BAA4B,EAAG,sBAA+B,CAAC;AAC5E,eAAO,MAAM,yBAAyB;;;;;;;;;CACwF,CAAC;AAK/H,eAAO,MAAM,yBAAyB;;;;;;;;;;;EAAmI,CAAC;AAC1K,eAAO,MAAM,oBAAoB;;;;;;;;;;;kBAGtB,CAAC;AACZ,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAMtB,CAAC;AACZ,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAQzB,CAAC;AACZ,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAUxB,CAAC;AACZ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC5E,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAC3D,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,cAAc,WAK/D;AAkBD;mFACmF;AACnF,wBAAgB,gCAAgC,CAAC,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,iBAAiB,CAE7G;AACD,sFAAsF;AACtF,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKjF"}
@@ -1,5 +1,7 @@
1
1
  import { type ConnectedFile, type ConnectedSession, type ConnectedSourceKind } from "./contracts.js";
2
2
  export type ExternalAgentSource = Exclude<ConnectedSourceKind, "native_chat" | "native_work">;
3
+ /** Cache identity includes source projection policy, independent of file mtimes. */
4
+ export declare function agentImportNormalizerRevision(source: ExternalAgentSource): string;
3
5
  export type AgentImportPreview = {
4
6
  schemaVersion: "openpond.agentImportPreview.v1";
5
7
  source: ExternalAgentSource;
@@ -8,6 +10,7 @@ export type AgentImportPreview = {
8
10
  issues: {
9
11
  file: string;
10
12
  message: string;
13
+ code?: "no_user_request";
11
14
  }[];
12
15
  };
13
16
  /** Never admits malformed files partly or executes referenced paths/commands. */
@@ -15,5 +18,9 @@ export declare function previewAgentImport(input: {
15
18
  source: ExternalAgentSource;
16
19
  files: ConnectedFile[];
17
20
  branchLeafId?: string;
21
+ acquisition?: {
22
+ machineId: string;
23
+ sourceInstanceId: string;
24
+ };
18
25
  }): AgentImportPreview;
19
26
  //# sourceMappingURL=imports.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../../../../../src/connected-evidence/imports.ts"],"names":[],"mappings":"AACA,OAAO,EAA6B,KAAK,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAMhI,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,EAAE,aAAa,GAAG,aAAa,CAAC,CAAC;AAC9F,MAAM,MAAM,kBAAkB,GAAG;IAC/B,aAAa,EAAE,gCAAgC,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IACjG,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3E,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IAAE,MAAM,EAAE,mBAAmB,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,kBAAkB,CA8C5I"}
1
+ {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../../../../../src/connected-evidence/imports.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACzB,MAAM,gBAAgB,CAAC;AAaxB,MAAM,MAAM,mBAAmB,GAAG,OAAO,CACvC,mBAAmB,EACnB,aAAa,GAAG,aAAa,CAC9B,CAAC;AACF,oFAAoF;AACpF,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,mBAAmB,UAExE;AACD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,aAAa,EAAE,gCAAgC,CAAC;IAChD,MAAM,EAAE,mBAAmB,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,iBAAiB,CAAA;KAAE,EAAE,CAAC;CACvE,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/D,GAAG,kBAAkB,CAgJrB"}
@@ -1,4 +1,7 @@
1
1
  import { type ConnectedEvent, type ConnectedFile, type ConnectedSession, type ConnectedSourceKind } from "./contracts.js";
2
+ export declare class ConnectedSessionWithoutUserRequestError extends Error {
3
+ constructor();
4
+ }
2
5
  export declare function connectedTimestamp(value: unknown, units?: "seconds" | "milliseconds"): string | null;
3
6
  export declare function connectedFileIdentity(file: ConnectedFile): {
4
7
  path: string;
@@ -17,6 +20,10 @@ export declare function normalizeConnectedSession(input: {
17
20
  contextComplete?: boolean;
18
21
  includeConversation?: boolean;
19
22
  unmappedEvents?: ConnectedEvent[];
23
+ acquisition?: {
24
+ machineId: string;
25
+ sourceInstanceId: string;
26
+ };
20
27
  }): ConnectedSession;
21
28
  export declare function connectedJsonLines(file: ConnectedFile): Record<string, unknown>[];
22
29
  export declare function object(value: unknown): Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../../src/connected-evidence/normalize.ts"],"names":[],"mappings":"AACA,OAAO,EACmB,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE3I,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,GAAE,SAAS,GAAG,cAA+B,GAAG,MAAM,GAAG,IAAI,CAIpH;AACD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,aAAa;;;;EAExD;AACD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,MAAM,EAAE,mBAAmB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1G,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAC;IAAC,MAAM,EAAE,cAAc,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACjK,cAAc,CAAC,EAAE,cAAc,EAAE,CAAC;CACnC,GAAG,gBAAgB,CAoDnB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAWjF;AACD,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAE9D;AACD,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,cAAc,CAEtH;AACD,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,CAAsD"}
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../../src/connected-evidence/normalize.ts"],"names":[],"mappings":"AACA,OAAO,EACmB,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE3I,qBAAa,uCAAwC,SAAQ,KAAK;;CAEjE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,GAAE,SAAS,GAAG,cAA+B,GAAG,MAAM,GAAG,IAAI,CAIpH;AACD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,aAAa;;;;EAExD;AACD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,MAAM,EAAE,mBAAmB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1G,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAC;IAAC,MAAM,EAAE,cAAc,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACjK,cAAc,CAAC,EAAE,cAAc,EAAE,CAAC;IAAC,WAAW,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;CAClG,GAAG,gBAAgB,CAuDnB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAgBjF;AACD,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAE9D;AACD,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,cAAc,CAEtH;AACD,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,CAAsD"}
@@ -0,0 +1,19 @@
1
+ export type ClaudeBranch = {
2
+ leafId: string;
3
+ chainHash: string;
4
+ title: string;
5
+ updatedAt: string | null;
6
+ messages: number;
7
+ };
8
+ /** One native graph owns selection, import and Desktop inspection semantics. */
9
+ export declare function claudeGraph(rows: Record<string, unknown>[]): {
10
+ sessionId: string;
11
+ leaves: Record<string, unknown>[];
12
+ select: (leafId: string) => {
13
+ chain: Record<string, unknown>[];
14
+ missingParent: boolean;
15
+ chainHash: string;
16
+ };
17
+ branches: () => ClaudeBranch[];
18
+ };
19
+ //# sourceMappingURL=claude-branches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-branches.d.ts","sourceRoot":"","sources":["../../../../../../src/connected-evidence/sources/claude-branches.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5H,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;;;qBAWjC,MAAM;;;;;oBAeT,YAAY,EAAE;EAYpC"}