@optimuslabs/runtime 0.3.3 → 0.3.10

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 (57) hide show
  1. package/dist/index.js +36 -70
  2. package/dist/index.js.map +1 -1
  3. package/dist/lib/login.d.ts +15 -0
  4. package/dist/lib/login.d.ts.map +1 -0
  5. package/dist/lib/login.js +109 -0
  6. package/dist/lib/login.js.map +1 -0
  7. package/dist/lib/pending-events.d.ts +9 -4
  8. package/dist/lib/pending-events.d.ts.map +1 -1
  9. package/dist/lib/pending-events.js +75 -8
  10. package/dist/lib/pending-events.js.map +1 -1
  11. package/dist/lib/prompt-collection-policy.d.ts +5 -0
  12. package/dist/lib/prompt-collection-policy.d.ts.map +1 -0
  13. package/dist/lib/prompt-collection-policy.js +58 -0
  14. package/dist/lib/prompt-collection-policy.js.map +1 -0
  15. package/dist/lib/startup-sync.d.ts.map +1 -1
  16. package/dist/lib/startup-sync.js +2 -0
  17. package/dist/lib/startup-sync.js.map +1 -1
  18. package/dist/lib/telemetry/build-event.d.ts.map +1 -1
  19. package/dist/lib/telemetry/build-event.js +58 -6
  20. package/dist/lib/telemetry/build-event.js.map +1 -1
  21. package/dist/lib/telemetry/canonical.d.ts +1 -1
  22. package/dist/lib/telemetry/canonical.d.ts.map +1 -1
  23. package/dist/lib/telemetry/canonical.js +28 -15
  24. package/dist/lib/telemetry/canonical.js.map +1 -1
  25. package/dist/lib/telemetry/prompt-privacy.d.ts +5 -0
  26. package/dist/lib/telemetry/prompt-privacy.d.ts.map +1 -0
  27. package/dist/lib/telemetry/prompt-privacy.js +37 -0
  28. package/dist/lib/telemetry/prompt-privacy.js.map +1 -0
  29. package/dist/lib/telemetry/types.d.ts +8 -0
  30. package/dist/lib/telemetry/types.d.ts.map +1 -1
  31. package/dist/lib/tofu.js +3 -3
  32. package/dist/lib/tofu.js.map +1 -1
  33. package/dist/lib/transcript.d.ts +33 -0
  34. package/dist/lib/transcript.d.ts.map +1 -0
  35. package/dist/lib/transcript.js +217 -0
  36. package/dist/lib/transcript.js.map +1 -0
  37. package/dist/test/canonical.test.js +41 -0
  38. package/dist/test/canonical.test.js.map +1 -1
  39. package/dist/test/endpoint-config.test.js +1 -1
  40. package/dist/test/endpoint-config.test.js.map +1 -1
  41. package/dist/test/login.test.d.ts +2 -0
  42. package/dist/test/login.test.d.ts.map +1 -0
  43. package/dist/test/login.test.js +60 -0
  44. package/dist/test/login.test.js.map +1 -0
  45. package/dist/test/pending-events.test.js +34 -1
  46. package/dist/test/pending-events.test.js.map +1 -1
  47. package/dist/test/prompt-privacy.test.d.ts +2 -0
  48. package/dist/test/prompt-privacy.test.d.ts.map +1 -0
  49. package/dist/test/prompt-privacy.test.js +33 -0
  50. package/dist/test/prompt-privacy.test.js.map +1 -0
  51. package/dist/test/telemetry.test.js +57 -0
  52. package/dist/test/telemetry.test.js.map +1 -1
  53. package/dist/test/transcript.test.d.ts +2 -0
  54. package/dist/test/transcript.test.d.ts.map +1 -0
  55. package/dist/test/transcript.test.js +162 -0
  56. package/dist/test/transcript.test.js.map +1 -0
  57. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"build-event.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/build-event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EACtC,aAAa,GAAE,MAAkB,EACjC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,cAAc,GAAG,IAAI,CA6BvB"}
1
+ {"version":3,"file":"build-event.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/build-event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA0DjE;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EACtC,aAAa,GAAE,MAAkB,EACjC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,cAAc,GAAG,IAAI,CA4BvB"}
@@ -1,3 +1,58 @@
1
+ import { readCollectPrompts } from "../prompt-collection-policy.js";
2
+ import { applyPromptCollectionToMetadata } from "./prompt-privacy.js";
3
+ import { readLogin } from "../login.js";
4
+ import { readAgentProduct, readCopilotProduct } from "../transcript.js";
5
+ /**
6
+ * Every Optimus hook's hash for this agent, from the tool-call hook (OPTIMUS_HOOK_MANIFEST,
7
+ * `{"<agent>/<hook>": "<sha256>"}`), or null when absent or malformed. It travels inside the signed
8
+ * events, so the server can record a tampered or restored hook at this tool call.
9
+ */
10
+ function hookManifest() {
11
+ const raw = (process.env.OPTIMUS_HOOK_MANIFEST || "").trim();
12
+ if (!raw)
13
+ return null;
14
+ try {
15
+ const parsed = JSON.parse(raw);
16
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
17
+ return null;
18
+ const entries = Object.entries(parsed).filter((entry) => typeof entry[1] === "string" && entry[1] !== "");
19
+ return entries.length ? Object.fromEntries(entries) : null;
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
25
+ /**
26
+ * Which product of the agent's family ran the tool (OPT-1488). Codex's CLI, desktop app, ChatGPT
27
+ * Work and VS Code send identical hook fields, so it is read from the session file Codex names in
28
+ * `transcript_path`; Copilot's from its session folder or VS Code's transcript.
29
+ */
30
+ function agentProduct(inv, agentIdentity) {
31
+ const transcriptPath = inv.raw_event?.transcript_path;
32
+ let product = null;
33
+ if (agentIdentity === "codex" && typeof transcriptPath === "string") {
34
+ product = readAgentProduct(transcriptPath);
35
+ }
36
+ else if (agentIdentity === "copilot") {
37
+ product = readCopilotProduct(inv.session_id, typeof transcriptPath === "string" ? transcriptPath : null);
38
+ }
39
+ return product ? { agent_product: product } : {};
40
+ }
41
+ /** The metadata fields an invocation only sometimes has, each left out when empty. */
42
+ function optionalMetadata(inv, agentIdentity) {
43
+ const hookHash = (process.env.OPTIMUS_HOOK_HASH || "").trim() || null;
44
+ const manifest = hookManifest();
45
+ // Tenant and email the agent is signed in with, read on every call; absent when unreadable.
46
+ const login = readLogin(agentIdentity);
47
+ return {
48
+ ...(inv.user_prompt ? { user_prompt: inv.user_prompt } : {}),
49
+ ...(inv.raw_event ? { raw_event: inv.raw_event } : {}),
50
+ ...agentProduct(inv, agentIdentity),
51
+ ...(hookHash ? { hook_hash: hookHash } : {}),
52
+ ...(manifest ? { hook_manifest: manifest } : {}),
53
+ ...(login ? { login } : {}),
54
+ };
55
+ }
1
56
  /**
2
57
  * Build a telemetry event from a tool invocation.
3
58
  *
@@ -12,14 +67,11 @@ export function buildTelemetryEvent(inv, agentIdentity = "unknown", sessionId) {
12
67
  const toolName = inv.tool_name;
13
68
  const toolNameNorm = typeof toolName === "string" ? toolName.trim() : "";
14
69
  const normalizedToolInput = inv.tool_input || {};
15
- const hookHash = (process.env.OPTIMUS_HOOK_HASH || "").trim() || null;
16
- const meta = {
70
+ const meta = applyPromptCollectionToMetadata({
17
71
  tool_name: toolNameNorm || toolName,
18
72
  tool_input: normalizedToolInput,
19
- ...(inv.user_prompt ? { user_prompt: inv.user_prompt } : {}),
20
- ...(inv.raw_event ? { raw_event: inv.raw_event } : {}),
21
- ...(hookHash ? { hook_hash: hookHash } : {}),
22
- };
73
+ ...optionalMetadata(inv, agentIdentity),
74
+ }, !readCollectPrompts());
23
75
  return {
24
76
  timestamp: new Date().toISOString(),
25
77
  agent_identity: agentIdentity,
@@ -1 +1 @@
1
- {"version":3,"file":"build-event.js","sourceRoot":"","sources":["../../../src/lib/telemetry/build-event.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAsC,EACtC,gBAAwB,SAAS,EACjC,SAAyB;IAEzB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC;IAC/B,MAAM,YAAY,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,MAAM,mBAAmB,GAA4B,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC;IAE1E,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;IAEtE,MAAM,IAAI,GAAyC;QACjD,SAAS,EAAE,YAAY,IAAI,QAAQ;QACnC,UAAU,EAAE,mBAAmB;QAC/B,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7C,CAAC;IAEF,OAAO;QACL,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,cAAc,EAAE,aAAa;QAC7B,UAAU,EAAE,WAAW;QACvB,UAAU,EAAE,SAAS;QACrB,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,IAAI;QACpC,eAAe,EAAE,GAAG,CAAC,eAAe,IAAI,IAAI;QAC5C,iBAAiB,EAAE,GAAG,CAAC,GAAG,IAAI,IAAI;QAClC,kBAAkB,EAAE,IAAI;KACzB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"build-event.js","sourceRoot":"","sources":["../../../src/lib/telemetry/build-event.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,7 @@
11
11
  * - user_prompt extraction (requires reading local files the backend cannot access)
12
12
  */
13
13
  export interface CanonicalHookInput {
14
- agent: "claude" | "cursor" | "unknown";
14
+ agent: "claude" | "cursor" | "codex" | "copilot" | "unknown";
15
15
  hook_event_name: string;
16
16
  tool_name: string;
17
17
  tool_input: Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/canonical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IACvC,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,CAmBrF"}
1
+ {"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/canonical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IAC7D,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,CAuBrF"}
@@ -19,6 +19,10 @@ export function normalizeToCanonical(raw) {
19
19
  const toolInfo = extractToolInfo(raw, hookEventName);
20
20
  const sessionId = extractSessionId(raw);
21
21
  const userPrompt = extractUserPrompt(raw);
22
+ const rawEvent = { ...raw };
23
+ delete rawEvent.user_prompt;
24
+ delete rawEvent.userPrompt;
25
+ delete rawEvent.prompt;
22
26
  return {
23
27
  agent,
24
28
  hook_event_name: hookEventName,
@@ -29,33 +33,42 @@ export function normalizeToCanonical(raw) {
29
33
  cwd: extractValue(raw, ["cwd", "workingDirectory"]) || null,
30
34
  model: extractValue(raw, ["model"]) || null,
31
35
  user_prompt: userPrompt,
32
- raw_event: raw,
36
+ raw_event: rawEvent,
33
37
  };
34
38
  }
35
- function detectAgent(raw) {
39
+ /** Claude hook names are PascalCase; Cursor uses camelCase. */
40
+ const CLAUDE_HOOK_EVENTS = new Set([
41
+ "PreToolUse", "SessionStart", "SessionEnd", "PostToolUse", "PostToolUseFailure", "PermissionRequest",
42
+ ]);
43
+ const CURSOR_HOOK_EVENTS = new Set(["preToolUse", "beforeShellExecution", "beforePromptSubmit"]);
44
+ /** The agent the hook's environment names, or null when it names none. */
45
+ function agentFromEnv() {
46
+ // Codex's and Copilot's hooks say so: their payloads are shaped like Claude's, so nothing else
47
+ // can tell them apart. Checked first because either started from a Claude Code terminal
48
+ // inherits CLAUDE_CODE_SESSION_ID.
49
+ const named = (process.env.OPTIMUS_AGENT || "").trim().toLowerCase();
50
+ if (named === "codex" || named === "copilot")
51
+ return named;
36
52
  // Environment variable is the most reliable signal
37
53
  if (process.env.CLAUDE_CODE_SESSION_ID)
38
54
  return "claude";
39
55
  if (process.env.CURSOR_SESSION_ID || process.env.CURSOR)
40
56
  return "cursor";
41
- const hookEventName = extractValue(raw, ["hook_event_name", "hookEventName", "hook_event"]);
42
- // Claude hook names are PascalCase; Cursor uses camelCase
43
- if (hookEventName === "PreToolUse" || hookEventName === "SessionStart" ||
44
- hookEventName === "SessionEnd" || hookEventName === "PostToolUse" ||
45
- hookEventName === "PostToolUseFailure" || hookEventName === "PermissionRequest") {
57
+ return null;
58
+ }
59
+ function detectAgent(raw) {
60
+ const fromEnv = agentFromEnv();
61
+ if (fromEnv)
62
+ return fromEnv;
63
+ const hookEventName = extractValue(raw, ["hook_event_name", "hookEventName", "hook_event"]) ?? "";
64
+ if (CLAUDE_HOOK_EVENTS.has(hookEventName))
46
65
  return "claude";
47
- }
48
- if (hookEventName === "preToolUse" || hookEventName === "beforeShellExecution" ||
49
- hookEventName === "beforePromptSubmit") {
66
+ if (CURSOR_HOOK_EVENTS.has(hookEventName))
50
67
  return "cursor";
51
- }
52
- // Field naming convention fallback
68
+ // Field naming convention fallback: camelCase is Cursor; anything else (snake_case or none) is Claude.
53
69
  if (raw.toolUse || raw.toolName || (raw.sessionId && typeof raw.sessionId === "string")) {
54
70
  return "cursor";
55
71
  }
56
- if (raw.tool_use_id || raw.session_id || raw.hook_event_name) {
57
- return "claude";
58
- }
59
72
  return "claude";
60
73
  }
61
74
  function extractHookEventName(raw, agent) {
@@ -1 +1 @@
1
- {"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../../src/lib/telemetry/canonical.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../../src/lib/telemetry/canonical.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare const RAW_EVENT_PROMPT_KEYS: readonly ["user_prompt", "userPrompt", "prompt"];
2
+ export declare function sha256UserPrompt(text: string): string;
3
+ export declare function stripRawEventPromptFields(rawEvent: Record<string, unknown> | undefined | null): Record<string, unknown> | undefined;
4
+ export declare function applyPromptCollectionToMetadata(meta: Record<string, unknown>, hashPrompts: boolean): Record<string, unknown>;
5
+ //# sourceMappingURL=prompt-privacy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-privacy.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/prompt-privacy.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,qBAAqB,kDAAmD,CAAC;AAEtF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,GACnD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CASrC;AAED,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,WAAW,EAAE,OAAO,GACnB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBzB"}
@@ -0,0 +1,37 @@
1
+ import { createHash } from "node:crypto";
2
+ export const RAW_EVENT_PROMPT_KEYS = ["user_prompt", "userPrompt", "prompt"];
3
+ export function sha256UserPrompt(text) {
4
+ return createHash("sha256").update(text.trim(), "utf8").digest("hex");
5
+ }
6
+ export function stripRawEventPromptFields(rawEvent) {
7
+ if (!rawEvent || typeof rawEvent !== "object" || Array.isArray(rawEvent)) {
8
+ return rawEvent ?? undefined;
9
+ }
10
+ const out = { ...rawEvent };
11
+ for (const key of RAW_EVENT_PROMPT_KEYS) {
12
+ delete out[key];
13
+ }
14
+ return out;
15
+ }
16
+ export function applyPromptCollectionToMetadata(meta, hashPrompts) {
17
+ const out = { ...meta };
18
+ const raw = out.raw_event;
19
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
20
+ out.raw_event = stripRawEventPromptFields(raw);
21
+ }
22
+ const plaintext = typeof out.user_prompt === "string" ? out.user_prompt.trim() : "";
23
+ if (!hashPrompts) {
24
+ if (plaintext)
25
+ out.user_prompt = plaintext;
26
+ else
27
+ delete out.user_prompt;
28
+ delete out.user_prompt_hash;
29
+ return out;
30
+ }
31
+ if (plaintext) {
32
+ out.user_prompt_hash = sha256UserPrompt(plaintext);
33
+ }
34
+ delete out.user_prompt;
35
+ return out;
36
+ }
37
+ //# sourceMappingURL=prompt-privacy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-privacy.js","sourceRoot":"","sources":["../../../src/lib/telemetry/prompt-privacy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,aAAa,EAAE,YAAY,EAAE,QAAQ,CAAU,CAAC;AAEtF,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,QAAoD;IAEpD,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzE,OAAO,QAAQ,IAAI,SAAS,CAAC;IAC/B,CAAC;IACD,MAAM,GAAG,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC5B,KAAK,MAAM,GAAG,IAAI,qBAAqB,EAAE,CAAC;QACxC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,IAA6B,EAC7B,WAAoB;IAEpB,MAAM,GAAG,GAA4B,EAAE,GAAG,IAAI,EAAE,CAAC;IACjD,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC;IAC1B,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1D,GAAG,CAAC,SAAS,GAAG,yBAAyB,CAAC,GAA8B,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,IAAI,SAAS;YAAE,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC;;YACtC,OAAO,GAAG,CAAC,WAAW,CAAC;QAC5B,OAAO,GAAG,CAAC,gBAAgB,CAAC;QAC5B,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,SAAS,EAAE,CAAC;QACd,GAAG,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,GAAG,CAAC,WAAW,CAAC;IACvB,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -28,8 +28,16 @@ export interface TelemetryEvent {
28
28
  tool_name: string;
29
29
  tool_input?: Record<string, unknown>;
30
30
  user_prompt?: string | null;
31
+ user_prompt_hash?: string | null;
31
32
  raw_event?: Record<string, unknown>;
32
33
  hook_hash?: string | null;
34
+ /** Every Optimus hook's hash for this agent, `{"<agent>/<hook>": "<sha256>"}`. */
35
+ hook_manifest?: Record<string, string>;
36
+ /** Which Codex product ran the tool, from its session file (OPT-1488). */
37
+ agent_product?: {
38
+ originator: string;
39
+ version?: string;
40
+ };
33
41
  };
34
42
  }
35
43
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/types.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAC5C,eAAO,MAAM,aAAa,SAAS,CAAC;AACpC,eAAO,MAAM,eAAe,WAAW,CAAC;AACxC,eAAO,MAAM,YAAY,QAAQ,CAAC;AAClC,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC,eAAO,MAAM,cAAc,UAM1B,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IAEnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC,kBAAkB,EAAE;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,CAAC;CACH"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/types.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAC5C,eAAO,MAAM,aAAa,SAAS,CAAC;AACpC,eAAO,MAAM,eAAe,WAAW,CAAC;AACxC,eAAO,MAAM,YAAY,QAAQ,CAAC;AAClC,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC,eAAO,MAAM,cAAc,UAM1B,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IAEnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC,kBAAkB,EAAE;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,kFAAkF;QAClF,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvC,0EAA0E;QAC1E,aAAa,CAAC,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC1D,CAAC;CACH"}
package/dist/lib/tofu.js CHANGED
@@ -34,9 +34,9 @@ function readEnvironment() {
34
34
  }
35
35
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
36
36
  const isDevelopment = readEnvironment() === "development";
37
- // In development: resolve local optimus-tofu dist relative to this file.
38
- // dist/lib/tofu.js → ../../.. → npx_packages/staging/ → optimus-tofu/dist/index.js
39
- const localTofuPath = path.join(__dirname, "../../../optimus-tofu/dist/index.js");
37
+ // In development: resolve local tofu dist relative to this file.
38
+ // dist/lib/tofu.js → ../../.. → optimuslabs/tofu/dist/index.js
39
+ const localTofuPath = path.join(__dirname, "../../../tofu/dist/index.js");
40
40
  const tofu = (isDevelopment
41
41
  ? await import(localTofuPath)
42
42
  : await import("@optimuslabs/tofu"));
@@ -1 +1 @@
1
- {"version":3,"file":"tofu.js","sourceRoot":"","sources":["../../src/lib/tofu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAGpC,SAAS,eAAe;IACtB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,CAAC,CAAC;IACtF,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,6EAA6E;QAC7E,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CACzB,8DAA8D,CAC/D,CAAC;IACF,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAChD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACtE,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,aAAa,GAAG,eAAe,EAAE,KAAK,aAAa,CAAC;AAE1D,yEAAyE;AACzE,mFAAmF;AACnF,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qCAAqC,CAAC,CAAC;AAElF,MAAM,IAAI,GAAG,CACX,aAAa;IACX,CAAC,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC;IAC7B,CAAC,CAAC,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAClB,CAAC;AAEtB,MAAM,CAAC,MAAM,EACX,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,GACf,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"tofu.js","sourceRoot":"","sources":["../../src/lib/tofu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAGpC,SAAS,eAAe;IACtB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,CAAC,CAAC;IACtF,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,6EAA6E;QAC7E,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CACzB,8DAA8D,CAC/D,CAAC;IACF,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAChD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACtE,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,aAAa,GAAG,eAAe,EAAE,KAAK,aAAa,CAAC;AAE1D,iEAAiE;AACjE,+DAA+D;AAC/D,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,6BAA6B,CAAC,CAAC;AAE1E,MAAM,IAAI,GAAG,CACX,aAAa;IACX,CAAC,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC;IAC7B,CAAC,CAAC,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAClB,CAAC;AAEtB,MAAM,CAAC,MAAM,EACX,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,GACf,GAAG,IAAI,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The last prompt the person typed. Read from the end, because the latest prompt is near it: the
3
+ * cost stays the same however large the transcript grows. Reading the whole file into one string
4
+ * failed outright past Node's string limit (about 512 MB) and took seconds on every tool call well
5
+ * before that.
6
+ */
7
+ export declare function readLastUserPrompt(transcriptPath: string): string | null;
8
+ /** Which product of an agent family wrote a transcript, and that product's engine version. */
9
+ export interface AgentProduct {
10
+ originator: string;
11
+ version?: string;
12
+ }
13
+ /**
14
+ * The product that wrote this Codex session (OPT-1488), from its `session_meta` line: `originator`
15
+ * is `codex-tui` (CLI), `Codex Desktop`, `codex_work_desktop` (ChatGPT Work) or `codex_vscode`, and
16
+ * `cli_version` is that product's engine. Inventory lists ChatGPT Work from it, since Work has no
17
+ * install of its own. Only the start is read, by pattern: the first line also carries Codex's
18
+ * instructions and runs to tens of KB, so it is not parsed whole. Null for any other transcript.
19
+ */
20
+ export declare function readAgentProduct(transcriptPath: string): AgentProduct | null;
21
+ /**
22
+ * The events file of a Copilot CLI or Copilot app session, where the person's prompts are kept.
23
+ * These products send no `transcript_path`, so this is where their prompt is read from.
24
+ */
25
+ export declare function copilotSessionEventsPath(sessionId: string | null | undefined, home?: string): string | null;
26
+ /**
27
+ * Which GitHub Copilot product ran the tool (OPT-1488). VS Code's Copilot Chat keeps its sessions
28
+ * in VS Code's own storage and names it in `transcript_path`. The CLI and the GitHub Copilot app
29
+ * share `~/.copilot/session-state/<session id>/`, whose `workspace.yaml` names the client:
30
+ * `github/cli` or `github/autopilot` (the app). Null when neither can be read.
31
+ */
32
+ export declare function readCopilotProduct(sessionId: string | null | undefined, transcriptPath: string | null | undefined, home?: string): AgentProduct | null;
33
+ //# sourceMappingURL=transcript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src/lib/transcript.ts"],"names":[],"mappings":"AA0GA;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYxE;AAKD,8FAA8F;AAC9F,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAoB5E;AA+BD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,IAAI,GAAE,MAA+B,GACpC,MAAM,GAAG,IAAI,CAGf;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,IAAI,GAAE,MAA+B,GACpC,YAAY,GAAG,IAAI,CAWrB"}
@@ -0,0 +1,217 @@
1
+ import fs from "fs";
2
+ /** Context Codex injects as "user" messages; never what the person typed. */
3
+ const CODEX_INJECTED_PREFIXES = ["# AGENTS.md instructions", "<environment_context>", "<user_instructions>"];
4
+ /** The `text` of every block of this type, joined by newlines and trimmed. */
5
+ function joinTextBlocks(blocks, type) {
6
+ return (Array.isArray(blocks) ? blocks : [])
7
+ .filter((c) => c.type === type && typeof c.text === "string")
8
+ .map((c) => c.text)
9
+ .join("\n")
10
+ .trim();
11
+ }
12
+ /** A Codex user message's text, or null for Codex's injected context (AGENTS.md, <environment_context>). */
13
+ function codexPrompt(payload) {
14
+ const text = joinTextBlocks(payload.content, "input_text");
15
+ return text && !CODEX_INJECTED_PREFIXES.some((prefix) => text.startsWith(prefix)) ? text : null;
16
+ }
17
+ /** A Claude user message's text, or null for an empty one or a tool_result turn. */
18
+ function claudePrompt(msg) {
19
+ const content = msg.content;
20
+ if (typeof content === "string")
21
+ return content.trim() || null;
22
+ if (!Array.isArray(content))
23
+ return null;
24
+ const blocks = content;
25
+ // Skip tool_result turns — those are API feedback, not user-typed messages
26
+ if (blocks.some((c) => c.type === "tool_result"))
27
+ return null;
28
+ return joinTextBlocks(blocks, "text") || null;
29
+ }
30
+ /** What the person typed in this transcript entry, or null when it is not a typed user message. */
31
+ function promptFromEntry(entry) {
32
+ // Codex rollout: {"type":"response_item","payload":{"type":"message","role":"user",
33
+ // "content":[{"type":"input_text","text":...}]}}.
34
+ const payload = entry.payload;
35
+ if (entry.type === "response_item" && payload?.type === "message" && payload.role === "user") {
36
+ return codexPrompt(payload);
37
+ }
38
+ // Copilot CLI and Copilot app session events: {"type":"user.message","data":{"content":...}}.
39
+ if (entry.type === "user.message") {
40
+ const content = entry.data?.content;
41
+ return typeof content === "string" ? content.trim() || null : null;
42
+ }
43
+ const msg = entry.message;
44
+ if (entry.type !== "user" || !msg || msg.role !== "user")
45
+ return null;
46
+ return claudePrompt(msg);
47
+ }
48
+ function promptFromLine(line) {
49
+ try {
50
+ return promptFromEntry(JSON.parse(line));
51
+ }
52
+ catch {
53
+ // skip malformed lines
54
+ return null;
55
+ }
56
+ }
57
+ /** Bytes read from the end of a transcript at a time. */
58
+ const TAIL_CHUNK_BYTES = 2 * 1024 * 1024;
59
+ const NEWLINE = 0x0a;
60
+ /** The prompt on this JSONL line, if it is one the person typed. */
61
+ function promptFromBytes(bytes) {
62
+ const line = bytes.toString("utf-8").trim();
63
+ return line ? promptFromLine(line) : null;
64
+ }
65
+ /** Where the last newline before `end` is in `chunk`, or -1. */
66
+ function lastNewline(chunk, end) {
67
+ return end > 0 ? chunk.lastIndexOf(NEWLINE, end - 1) : -1;
68
+ }
69
+ /**
70
+ * The transcript's lines, last first, read backwards a chunk at a time. Lines are split on newline
71
+ * bytes, which never occur inside a multi-byte character, so a character is never cut.
72
+ */
73
+ function* linesFromEnd(fd) {
74
+ let position = fs.fstatSync(fd).size;
75
+ // The end of the line being read, whose start is further back in the file.
76
+ let tail = [];
77
+ while (position > 0) {
78
+ const length = Math.min(TAIL_CHUNK_BYTES, position);
79
+ position -= length;
80
+ const chunk = Buffer.alloc(length);
81
+ let end = fs.readSync(fd, chunk, 0, length, position);
82
+ for (let newline = lastNewline(chunk, end); newline >= 0; newline = lastNewline(chunk, end)) {
83
+ yield Buffer.concat([chunk.subarray(newline + 1, end), ...tail]);
84
+ tail = [];
85
+ end = newline;
86
+ }
87
+ tail.unshift(chunk.subarray(0, end));
88
+ }
89
+ yield Buffer.concat(tail);
90
+ }
91
+ /** The first line from the end that the person typed. */
92
+ function lastPromptIn(fd) {
93
+ for (const line of linesFromEnd(fd)) {
94
+ const prompt = promptFromBytes(line);
95
+ if (prompt)
96
+ return prompt;
97
+ }
98
+ return null;
99
+ }
100
+ /**
101
+ * The last prompt the person typed. Read from the end, because the latest prompt is near it: the
102
+ * cost stays the same however large the transcript grows. Reading the whole file into one string
103
+ * failed outright past Node's string limit (about 512 MB) and took seconds on every tool call well
104
+ * before that.
105
+ */
106
+ export function readLastUserPrompt(transcriptPath) {
107
+ let fd;
108
+ try {
109
+ fd = fs.openSync(transcriptPath, "r");
110
+ return lastPromptIn(fd);
111
+ }
112
+ catch (error) {
113
+ // A missing or unreadable transcript is non-fatal: the tool call goes out without a prompt.
114
+ if (process.env.OPTIMUS_DEBUG)
115
+ console.error("[optimus-tool-call] Could not read the transcript:", error);
116
+ return null;
117
+ }
118
+ finally {
119
+ if (fd !== undefined)
120
+ fs.closeSync(fd);
121
+ }
122
+ }
123
+ /** Bytes read from the start of a Codex session file, where its session metadata sits. */
124
+ const SESSION_HEAD_BYTES = 8 * 1024;
125
+ /**
126
+ * The product that wrote this Codex session (OPT-1488), from its `session_meta` line: `originator`
127
+ * is `codex-tui` (CLI), `Codex Desktop`, `codex_work_desktop` (ChatGPT Work) or `codex_vscode`, and
128
+ * `cli_version` is that product's engine. Inventory lists ChatGPT Work from it, since Work has no
129
+ * install of its own. Only the start is read, by pattern: the first line also carries Codex's
130
+ * instructions and runs to tens of KB, so it is not parsed whole. Null for any other transcript.
131
+ */
132
+ export function readAgentProduct(transcriptPath) {
133
+ let fd;
134
+ try {
135
+ fd = fs.openSync(transcriptPath, "r");
136
+ const head = Buffer.alloc(SESSION_HEAD_BYTES);
137
+ const read = fs.readSync(fd, head, 0, SESSION_HEAD_BYTES, 0);
138
+ const text = head.subarray(0, read).toString("utf8");
139
+ const firstLine = text.split("\n", 1)[0];
140
+ if (!/"type"\s*:\s*"session_meta"/.test(firstLine))
141
+ return null;
142
+ const originator = firstLine.match(/"originator"\s*:\s*"([^"\\]{1,100})"/)?.[1];
143
+ if (!originator)
144
+ return null;
145
+ const version = firstLine.match(/"cli_version"\s*:\s*"([^"\\]{1,100})"/)?.[1];
146
+ return version ? { originator, version } : { originator };
147
+ }
148
+ catch (error) {
149
+ // A missing or unreadable transcript is non-fatal: the tool call goes out without a product.
150
+ if (process.env.OPTIMUS_DEBUG)
151
+ console.error("[optimus-tool-call] Could not read the session head:", error);
152
+ return null;
153
+ }
154
+ finally {
155
+ if (fd !== undefined)
156
+ fs.closeSync(fd);
157
+ }
158
+ }
159
+ /** A Copilot product's first event and settings files, read from the start only. */
160
+ const COPILOT_HEAD_BYTES = 8 * 1024;
161
+ function readFileHead(filePath) {
162
+ let fd;
163
+ try {
164
+ fd = fs.openSync(filePath, "r");
165
+ const head = Buffer.alloc(COPILOT_HEAD_BYTES);
166
+ return head.subarray(0, fs.readSync(fd, head, 0, COPILOT_HEAD_BYTES, 0)).toString("utf8");
167
+ }
168
+ catch (error) {
169
+ // A missing or unreadable file is non-fatal: the tool call goes out without a product.
170
+ if (process.env.OPTIMUS_DEBUG)
171
+ console.error("[optimus-tool-call] Could not read the Copilot session:", error);
172
+ return "";
173
+ }
174
+ finally {
175
+ if (fd !== undefined)
176
+ fs.closeSync(fd);
177
+ }
178
+ }
179
+ /** `copilotVersion` from a Copilot session's first event (`session.start`). */
180
+ function copilotVersion(eventsPath) {
181
+ return readFileHead(eventsPath).match(/"copilotVersion"\s*:\s*"([^"\\]{1,100})"/)?.[1];
182
+ }
183
+ /** `~/.copilot/session-state/<session id>`, shared by the CLI and the Copilot app, or null for an id that is not one. */
184
+ function copilotSessionDir(sessionId, home) {
185
+ if (!sessionId || !/^[A-Za-z0-9-]{8,64}$/.test(sessionId) || !home)
186
+ return null;
187
+ return `${home}/.copilot/session-state/${sessionId}`;
188
+ }
189
+ /**
190
+ * The events file of a Copilot CLI or Copilot app session, where the person's prompts are kept.
191
+ * These products send no `transcript_path`, so this is where their prompt is read from.
192
+ */
193
+ export function copilotSessionEventsPath(sessionId, home = process.env.HOME || "") {
194
+ const sessionDir = copilotSessionDir(sessionId, home);
195
+ return sessionDir ? `${sessionDir}/events.jsonl` : null;
196
+ }
197
+ /**
198
+ * Which GitHub Copilot product ran the tool (OPT-1488). VS Code's Copilot Chat keeps its sessions
199
+ * in VS Code's own storage and names it in `transcript_path`. The CLI and the GitHub Copilot app
200
+ * share `~/.copilot/session-state/<session id>/`, whose `workspace.yaml` names the client:
201
+ * `github/cli` or `github/autopilot` (the app). Null when neither can be read.
202
+ */
203
+ export function readCopilotProduct(sessionId, transcriptPath, home = process.env.HOME || "") {
204
+ if (typeof transcriptPath === "string" && transcriptPath.includes("/GitHub.copilot-chat/")) {
205
+ const version = copilotVersion(transcriptPath);
206
+ return version ? { originator: "vscode", version } : { originator: "vscode" };
207
+ }
208
+ const sessionDir = copilotSessionDir(sessionId, home);
209
+ if (!sessionDir)
210
+ return null;
211
+ const originator = readFileHead(`${sessionDir}/workspace.yaml`).match(/^client_name:\s*(\S{1,100})\s*$/m)?.[1];
212
+ if (!originator)
213
+ return null;
214
+ const version = copilotVersion(`${sessionDir}/events.jsonl`);
215
+ return version ? { originator, version } : { originator };
216
+ }
217
+ //# sourceMappingURL=transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/lib/transcript.ts"],"names":[],"mappings":"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"}