optimus-tool-call 0.2.1 → 0.2.4

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.
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * optimus-capture-prompt — Cursor hook to capture and store prompt text
4
+ *
5
+ * Runs on beforeSubmitPrompt hook. Reads the prompt from stdin (if available),
6
+ * stores it in a temp file keyed by session ID, so that the tool-call hook
7
+ * can retrieve it when processing tool invocations.
8
+ *
9
+ * Cursor hook protocol for beforeSubmitPrompt:
10
+ * - stdin: JSON with prompt text (format varies by Cursor version)
11
+ * - stdout: {"continue": true|false} JSON
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=capture-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-prompt.d.ts","sourceRoot":"","sources":["../src/capture-prompt.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG"}
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * optimus-capture-prompt — Cursor hook to capture and store prompt text
4
+ *
5
+ * Runs on beforeSubmitPrompt hook. Reads the prompt from stdin (if available),
6
+ * stores it in a temp file keyed by session ID, so that the tool-call hook
7
+ * can retrieve it when processing tool invocations.
8
+ *
9
+ * Cursor hook protocol for beforeSubmitPrompt:
10
+ * - stdin: JSON with prompt text (format varies by Cursor version)
11
+ * - stdout: {"continue": true|false} JSON
12
+ */
13
+ import fs from "fs";
14
+ import os from "os";
15
+ import path from "path";
16
+ const dbg = (...args) => { if (process.env.OPTIMUS_DEBUG)
17
+ console.error(...args); };
18
+ async function main() {
19
+ const stdinData = await readStdin();
20
+ dbg("[optimus-capture-prompt] ===== HOOK STARTED =====");
21
+ dbg("[optimus-capture-prompt] stdin length:", stdinData.length);
22
+ dbg("[optimus-capture-prompt] stdin preview:", stdinData.slice(0, 200));
23
+ let promptText = null;
24
+ let payloadSessionId = null;
25
+ try {
26
+ const raw = JSON.parse(stdinData);
27
+ dbg("[optimus-capture-prompt] Parsed JSON successfully");
28
+ dbg("[optimus-capture-prompt] Raw keys:", Object.keys(raw));
29
+ dbg("[optimus-capture-prompt] Raw payload:", JSON.stringify(raw, null, 2).slice(0, 500));
30
+ // Extract session ID for Cursor (from conversation_id or session_id in payload)
31
+ payloadSessionId =
32
+ (typeof raw.conversation_id === "string" && raw.conversation_id) ||
33
+ (typeof raw.session_id === "string" && raw.session_id) ||
34
+ null;
35
+ // Extract prompt from various possible locations in the hook payload
36
+ promptText =
37
+ extractValue(raw, ["prompt"]) ||
38
+ extractValue(raw, ["text"]) ||
39
+ extractValue(raw, ["message"]) ||
40
+ extractValue(raw, ["input"]) ||
41
+ null;
42
+ // Try to extract from nested message structure
43
+ if (!promptText) {
44
+ const msg = raw.message;
45
+ if (msg && typeof msg === "object") {
46
+ promptText =
47
+ extractValue(msg, ["content"]) ||
48
+ extractValue(msg, ["text"]) ||
49
+ extractValue(msg, ["prompt"]) ||
50
+ null;
51
+ }
52
+ }
53
+ dbg("[optimus-capture-prompt] Extracted prompt text:", promptText ? `"${promptText.slice(0, 100)}..."` : "null");
54
+ }
55
+ catch (error) {
56
+ // Not valid JSON — might not have prompt in this hook payload
57
+ console.error("[optimus-capture-prompt] Failed to parse JSON:", error);
58
+ }
59
+ // If we have a prompt, store it in a temp file keyed by session ID
60
+ if (promptText) {
61
+ dbg("[optimus-capture-prompt] Storing prompt...");
62
+ try {
63
+ const sessionId = payloadSessionId ||
64
+ process.env.CURSOR_SESSION_ID ||
65
+ process.env.CURSOR_CODE_SESSION_ID ||
66
+ process.env.CLAUDE_CODE_SESSION_ID ||
67
+ "unknown";
68
+ const promptCacheDir = path.join(os.tmpdir(), "optimus-prompt-cache");
69
+ dbg("[optimus-capture-prompt] Session ID:", sessionId);
70
+ dbg("[optimus-capture-prompt] Cache dir:", promptCacheDir);
71
+ // Create cache directory if it doesn't exist
72
+ if (!fs.existsSync(promptCacheDir)) {
73
+ dbg("[optimus-capture-prompt] Creating cache directory...");
74
+ fs.mkdirSync(promptCacheDir, { recursive: true });
75
+ }
76
+ // Write prompt to temp file (with short TTL via filename timestamp)
77
+ const timestamp = Date.now();
78
+ const promptFile = path.join(promptCacheDir, `prompt-${sessionId}-${timestamp}.txt`);
79
+ fs.writeFileSync(promptFile, promptText, "utf-8");
80
+ dbg(`[optimus-capture-prompt] Wrote prompt file: ${promptFile}`);
81
+ // Also write a "latest" symlink for easy access
82
+ const latestFile = path.join(promptCacheDir, `prompt-${sessionId}.txt`);
83
+ try {
84
+ fs.unlinkSync(latestFile);
85
+ }
86
+ catch {
87
+ // File might not exist
88
+ }
89
+ try {
90
+ fs.symlinkSync(promptFile, latestFile);
91
+ dbg(`[optimus-capture-prompt] Created symlink: ${latestFile}`);
92
+ }
93
+ catch (e) {
94
+ dbg(`[optimus-capture-prompt] Symlink creation failed (non-fatal):`, e);
95
+ }
96
+ dbg(`[optimus-capture-prompt] SUCCESS: Stored prompt at ${promptFile}`);
97
+ // Clean up old prompt files (older than 5 minutes)
98
+ cleanupOldPromptFiles(promptCacheDir, sessionId);
99
+ }
100
+ catch (error) {
101
+ // Non-fatal — if we can't cache the prompt, the tool-call hook just won't have it
102
+ console.error("[optimus-capture-prompt] ERROR: Failed to store prompt:", error);
103
+ }
104
+ }
105
+ else {
106
+ dbg("[optimus-capture-prompt] No prompt text found in hook payload");
107
+ }
108
+ // Always allow — never block on prompt capture
109
+ const response = { continue: true };
110
+ dbg("[optimus-capture-prompt] Returning response:", JSON.stringify(response));
111
+ console.log(JSON.stringify(response));
112
+ }
113
+ async function readStdin() {
114
+ return new Promise((resolve) => {
115
+ let data = "";
116
+ process.stdin.setEncoding("utf8");
117
+ process.stdin.on("readable", () => {
118
+ let chunk;
119
+ while ((chunk = process.stdin.read()) !== null) {
120
+ data += chunk;
121
+ }
122
+ });
123
+ process.stdin.on("end", () => {
124
+ resolve(data);
125
+ });
126
+ process.stdin.on("error", () => {
127
+ resolve("");
128
+ });
129
+ });
130
+ }
131
+ function extractValue(obj, keys) {
132
+ for (const key of keys) {
133
+ const value = obj[key];
134
+ if (value !== undefined && value !== null && typeof value === "string") {
135
+ return value;
136
+ }
137
+ }
138
+ return null;
139
+ }
140
+ function cleanupOldPromptFiles(dir, sessionId) {
141
+ try {
142
+ const files = fs.readdirSync(dir);
143
+ const now = Date.now();
144
+ const maxAge = 5 * 60 * 1000; // 5 minutes
145
+ for (const file of files) {
146
+ // Only clean up files for this session
147
+ if (!file.startsWith(`prompt-${sessionId}-`))
148
+ continue;
149
+ const filePath = path.join(dir, file);
150
+ try {
151
+ const stat = fs.statSync(filePath);
152
+ if (now - stat.mtimeMs > maxAge) {
153
+ fs.unlinkSync(filePath);
154
+ }
155
+ }
156
+ catch {
157
+ // Ignore errors during cleanup
158
+ }
159
+ }
160
+ }
161
+ catch {
162
+ // Ignore errors during cleanup
163
+ }
164
+ }
165
+ main().catch((err) => {
166
+ if (process.env.OPTIMUS_DEBUG) {
167
+ console.error("[optimus-capture-prompt] Fatal error:", err);
168
+ }
169
+ const response = { continue: true };
170
+ console.log(JSON.stringify(response));
171
+ process.exit(0);
172
+ });
173
+ //# sourceMappingURL=capture-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-prompt.js","sourceRoot":"","sources":["../src/capture-prompt.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,GAAG,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa;IAAE,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAE/F,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,MAAM,SAAS,EAAE,CAAC;IAEpC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACzD,GAAG,CAAC,wCAAwC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAChE,GAAG,CAAC,yCAAyC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAExE,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,gBAAgB,GAAkB,IAAI,CAAC;IAE3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAElC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACzD,GAAG,CAAC,oCAAoC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5D,GAAG,CAAC,uCAAuC,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAEzF,gFAAgF;QAChF,gBAAgB;YACd,CAAC,OAAO,GAAG,CAAC,eAAe,KAAK,QAAQ,IAAI,GAAG,CAAC,eAAe,CAAC;gBAChE,CAAC,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC;gBACtD,IAAI,CAAC;QAEP,qEAAqE;QACrE,UAAU;YACR,YAAY,CAAS,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;gBACrC,YAAY,CAAS,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;gBACnC,YAAY,CAAS,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBACtC,YAAY,CAAS,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;gBACpC,IAAI,CAAC;QAEP,+CAA+C;QAC/C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC;YACxB,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACnC,UAAU;oBACR,YAAY,CAAS,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;wBACtC,YAAY,CAAS,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;wBACnC,YAAY,CAAS,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;wBACrC,IAAI,CAAC;YACT,CAAC;QACH,CAAC;QAED,GAAG,CAAC,iDAAiD,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACnH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,8DAA8D;QAC9D,OAAO,CAAC,KAAK,CAAC,gDAAgD,EAAE,KAAK,CAAC,CAAC;IACzE,CAAC;IAED,mEAAmE;IACnE,IAAI,UAAU,EAAE,CAAC;QACf,GAAG,CAAC,4CAA4C,CAAC,CAAC;QAClD,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,gBAAgB;gBAChC,OAAO,CAAC,GAAG,CAAC,iBAAiB;gBAC7B,OAAO,CAAC,GAAG,CAAC,sBAAsB;gBAClC,OAAO,CAAC,GAAG,CAAC,sBAAsB;gBAClC,SAAS,CAAC;YAEZ,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC;YAEtE,GAAG,CAAC,sCAAsC,EAAE,SAAS,CAAC,CAAC;YACvD,GAAG,CAAC,qCAAqC,EAAE,cAAc,CAAC,CAAC;YAE3D,6CAA6C;YAC7C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;gBACnC,GAAG,CAAC,sDAAsD,CAAC,CAAC;gBAC5D,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACpD,CAAC;YAED,oEAAoE;YACpE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,SAAS,IAAI,SAAS,MAAM,CAAC,CAAC;YACrF,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;YAClD,GAAG,CAAC,+CAA+C,UAAU,EAAE,CAAC,CAAC;YAEjE,gDAAgD;YAChD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,SAAS,MAAM,CAAC,CAAC;YACxE,IAAI,CAAC;gBACH,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,uBAAuB;YACzB,CAAC;YACD,IAAI,CAAC;gBACH,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;gBACvC,GAAG,CAAC,6CAA6C,UAAU,EAAE,CAAC,CAAC;YACjE,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,GAAG,CAAC,+DAA+D,EAAE,CAAC,CAAC,CAAC;YAC1E,CAAC;YAED,GAAG,CAAC,sDAAsD,UAAU,EAAE,CAAC,CAAC;YAExE,mDAAmD;YACnD,qBAAqB,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,kFAAkF;YAClF,OAAO,CAAC,KAAK,CAAC,yDAAyD,EAAE,KAAK,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,+DAA+D,CAAC,CAAC;IACvE,CAAC;IAED,+CAA+C;IAC/C,MAAM,QAAQ,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACpC,GAAG,CAAC,8CAA8C,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,KAAK,UAAU,SAAS;IACtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAElC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE;YAChC,IAAI,KAAoB,CAAC;YACzB,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC/C,IAAI,IAAI,KAAK,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAC7B,OAAO,CAAC,EAAE,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAI,GAA4B,EAAE,IAAc;IACnE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvE,OAAO,KAAU,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,qBAAqB,CAAC,GAAW,EAAE,SAAiB;IAC3D,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;QAE1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,uCAAuC;YACvC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,SAAS,GAAG,CAAC;gBAAE,SAAS;YAEvD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACtC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACnC,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,MAAM,EAAE,CAAC;oBAChC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,+BAA+B;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,+BAA+B;IACjC,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,GAAG,CAAC,CAAC;IAC9D,CAAC;IACD,MAAM,QAAQ,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/dist/index.js CHANGED
@@ -8,43 +8,70 @@
8
8
  import fs from "fs";
9
9
  import { buildTelemetryEvent, eventToDict } from "./lib/telemetry.js";
10
10
  import { queueEvent, ensureShutdown } from "./lib/streaming.js";
11
+ import { normalizeToCanonical } from "./lib/telemetry/canonical.js";
12
+ const dbg = (...args) => { if (process.env.OPTIMUS_DEBUG)
13
+ console.error(...args); };
11
14
  async function main() {
15
+ dbg("[optimus-tool-call] ===== HOOK STARTED =====");
16
+ dbg("[optimus-tool-call] NODE_ENV:", process.env.NODE_ENV);
17
+ dbg("[optimus-tool-call] CURSOR:", process.env.CURSOR);
18
+ dbg("[optimus-tool-call] CURSOR_SESSION_ID:", process.env.CURSOR_SESSION_ID);
19
+ dbg("[optimus-tool-call] CLAUDE_CODE_SESSION_ID:", process.env.CLAUDE_CODE_SESSION_ID);
12
20
  // Setup shutdown handling
13
21
  ensureShutdown();
14
22
  // Read stdin
15
23
  const stdinData = await readStdin();
16
- // Parse JSON hook payload
17
- let invocation;
24
+ dbg("[optimus-tool-call] stdin length:", stdinData.length);
25
+ dbg("[optimus-tool-call] stdin preview:", stdinData.slice(0, 300));
26
+ // Parse and normalize to canonical format
27
+ let canonical;
18
28
  try {
19
29
  const raw = JSON.parse(stdinData);
20
- // DEBUG: Log raw hook payload to see actual tool_name and structure
21
- if (process.env.OPTIMUS_DEBUG) {
22
- console.error("[optimus-tool-call] Raw hook payload:", JSON.stringify(raw, null, 2));
23
- }
24
- invocation = parseHookPayload(raw);
25
- // Extract the user's original prompt from the session transcript
26
- const transcriptPath = typeof raw.transcript_path === "string" ? raw.transcript_path : null;
27
- if (transcriptPath) {
28
- const userPrompt = readLastUserPrompt(transcriptPath);
29
- if (userPrompt) {
30
- invocation = { ...invocation, user_prompt: userPrompt };
30
+ dbg("[optimus-tool-call] Parsed JSON successfully");
31
+ dbg("[optimus-tool-call] Raw keys:", Object.keys(raw));
32
+ // Normalize to canonical format (works for both Claude and Cursor)
33
+ canonical = normalizeToCanonical(raw);
34
+ dbg("[optimus-tool-call] Detected agent:", canonical.agent);
35
+ dbg("[optimus-tool-call] Hook event name:", canonical.hook_event_name);
36
+ dbg("[optimus-tool-call] Tool name:", canonical.tool_name);
37
+ // Try to extract user prompt from transcript file (works for both Claude and Cursor)
38
+ if (!canonical.user_prompt) {
39
+ const transcriptPath = typeof raw.transcript_path === "string" ? raw.transcript_path : null;
40
+ if (transcriptPath) {
41
+ const userPrompt = readLastUserPrompt(transcriptPath);
42
+ if (userPrompt) {
43
+ canonical = { ...canonical, user_prompt: userPrompt };
44
+ }
31
45
  }
32
46
  }
33
- // DEBUG: Log parsed invocation
34
- if (process.env.OPTIMUS_DEBUG) {
35
- console.error("[optimus-tool-call] Parsed invocation tool_name:", invocation.tool_name);
36
- console.error("[optimus-tool-call] User prompt:", invocation.user_prompt?.slice(0, 100));
37
- }
47
+ dbg("[optimus-tool-call] Canonical event:", {
48
+ agent: canonical.agent,
49
+ hook_event_name: canonical.hook_event_name,
50
+ tool_name: canonical.tool_name,
51
+ user_prompt_preview: canonical.user_prompt?.slice(0, 100),
52
+ });
38
53
  }
39
54
  catch (error) {
40
55
  // Invalid JSON or parse error — allow and return
56
+ console.error("[optimus-tool-call] ERROR: Failed to parse:", error);
41
57
  const response = { continue: true, permission: "allow" };
42
58
  console.log(JSON.stringify(response));
43
59
  return;
44
60
  }
61
+ // Convert canonical to ToolInvocation (for backward compatibility with existing code)
62
+ const invocation = {
63
+ tool_name: canonical.tool_name,
64
+ tool_input: canonical.tool_input,
65
+ tool_use_id: canonical.tool_use_id,
66
+ session_id: canonical.session_id,
67
+ cwd: canonical.cwd,
68
+ hook_event_name: canonical.hook_event_name,
69
+ model: canonical.model,
70
+ user_prompt: canonical.user_prompt,
71
+ raw_event: canonical.raw_event,
72
+ };
45
73
  // Build telemetry event
46
- const agentIdentity = detectAgent();
47
- const event = buildTelemetryEvent(invocation, agentIdentity, undefined);
74
+ const event = buildTelemetryEvent(invocation, canonical.agent, canonical.session_id);
48
75
  if (event) {
49
76
  // Server classifies `action_type`; queue raw invocation for all non-null events.
50
77
  await queueEvent(event);
@@ -78,54 +105,6 @@ async function readStdin() {
78
105
  });
79
106
  });
80
107
  }
81
- function parseHookPayload(raw) {
82
- /**
83
- * Normalize raw hook payload to ToolInvocation.
84
- * Handles different hook formats (preToolUse, beforeShellExecution, etc.).
85
- */
86
- const getObj = (value) => value && typeof value === "object" && !Array.isArray(value)
87
- ? value
88
- : null;
89
- const getStr = (value) => typeof value === "string" && value.length > 0 ? value : null;
90
- const toolUse = getObj(raw.toolUse);
91
- const tool = getObj(raw.tool);
92
- const toolInput = getObj(raw.tool_input) ??
93
- getObj(raw.toolInput) ??
94
- getObj(toolUse?.input) ??
95
- getObj(tool?.input) ??
96
- {};
97
- const hookEventName = getStr(raw.hook_event_name) ?? getStr(raw.hookEventName) ?? getStr(raw.hook_event);
98
- const commandFromTop = getStr(raw.command);
99
- const commandFromInput = getStr(toolInput.command) ?? getStr(toolInput.cmd);
100
- const inferredShellCommand = commandFromTop ?? commandFromInput;
101
- const toolName = getStr(raw.tool_name) ??
102
- getStr(raw.toolName) ??
103
- getStr(toolUse?.name) ??
104
- getStr(tool?.name) ??
105
- (hookEventName === "beforeShellExecution" || inferredShellCommand ? "Bash" : "Unknown");
106
- // DEBUG: Log tool name resolution
107
- if (process.env.OPTIMUS_DEBUG) {
108
- console.error("[optimus-tool-call] Tool name resolution:");
109
- console.error(" raw.tool_name:", raw.tool_name);
110
- console.error(" raw.toolName:", raw.toolName);
111
- console.error(" toolUse?.name:", toolUse?.name);
112
- console.error(" tool?.name:", tool?.name);
113
- console.error(" Final toolName:", toolName);
114
- }
115
- const normalizedToolInput = inferredShellCommand && !("command" in toolInput)
116
- ? { ...toolInput, command: inferredShellCommand }
117
- : toolInput;
118
- return {
119
- tool_name: toolName,
120
- tool_input: normalizedToolInput,
121
- tool_use_id: getStr(raw.tool_use_id) ?? getStr(raw.toolUseId),
122
- cwd: getStr(raw.cwd),
123
- hook_event_name: hookEventName,
124
- model: getStr(raw.model),
125
- agent_message: getStr(raw.agent_message) ?? getStr(raw.agentMessage),
126
- raw_event: raw,
127
- };
128
- }
129
108
  /**
130
109
  * Read the Claude Code session transcript (JSONL) and return the text of the
131
110
  * last user-typed message. Each line is a JSON object; user turns look like:
@@ -175,24 +154,6 @@ function readLastUserPrompt(transcriptPath) {
175
154
  }
176
155
  return null;
177
156
  }
178
- function detectAgent() {
179
- /**
180
- * Detect which agent is running this hook.
181
- * Can be extended with environment variables or other signals.
182
- */
183
- // Check environment variables for agent identification
184
- if (process.env.CLAUDE_CODE_SESSION_ID) {
185
- return "claude";
186
- }
187
- if (process.env.CURSOR_SESSION_ID || process.env.CURSOR) {
188
- return "cursor";
189
- }
190
- if (process.env.GITHUB_COPILOT) {
191
- return "copilot";
192
- }
193
- // Default to claude for Claude Code CLI
194
- return "claude";
195
- }
196
157
  // Run
197
158
  main().catch((err) => {
198
159
  console.error("[optimus-tool-call] Fatal error:", err);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../src/lib/streaming.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAchD;;GAEG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBrE;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAyBjD;AAwJD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CA0BrC"}
1
+ {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../src/lib/streaming.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAiBhD;;GAEG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBrE;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAyBjD;AAiLD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CA0BrC"}
@@ -7,6 +7,9 @@ import { ensureStartupMetadataSynced } from "./startup-sync.js";
7
7
  import { cloneToolCallMetadataForWire } from "./telemetry/wire-metadata.js";
8
8
  import { loadEndpointBase } from "./endpoint-config.js";
9
9
  import { tryResolveHardwareUuid } from "./hardware-uuid.js";
10
+ const DEBUG = !!process.env.OPTIMUS_DEBUG;
11
+ const dbg = (...args) => { if (DEBUG)
12
+ console.error(...args); };
10
13
  // Backend configuration
11
14
  const OPTIMUS_API_BASE = loadEndpointBase();
12
15
  const BATCH_SIZE = parseInt(process.env.OPTIMUS_BATCH_SIZE || "1", 10); // Default to 1 for testing
@@ -82,17 +85,32 @@ async function sendBatch(events) {
82
85
  if (events.length === 0) {
83
86
  return;
84
87
  }
88
+ dbg(`[optimus-tool-call] Sending ${events.length} events to backend...`);
89
+ dbg(`[optimus-tool-call] Event agents:`, events.map(e => e.agent_identity).join(", "));
85
90
  const hardwareUuid = tryResolveHardwareUuid();
86
91
  if (!hardwareUuid) {
87
- throw new Error("Cannot send tool-call telemetry: set OPTIMUS_HARDWARE_UUID or run on a host with a hardware UUID.");
92
+ const err = "Cannot send tool-call telemetry: set OPTIMUS_HARDWARE_UUID or run on a host with a hardware UUID.";
93
+ console.error(`[optimus-tool-call] ERROR: ${err}`);
94
+ throw new Error(err);
95
+ }
96
+ dbg(`[optimus-tool-call] Hardware UUID: ${hardwareUuid}`);
97
+ try {
98
+ await ensureStartupMetadataSynced(hardwareUuid);
99
+ dbg(`[optimus-tool-call] Startup metadata synced`);
100
+ }
101
+ catch (err) {
102
+ console.error(`[optimus-tool-call] ERROR syncing startup metadata:`, err);
103
+ throw err;
88
104
  }
89
- await ensureStartupMetadataSynced(hardwareUuid);
90
- const auth = await ensureToolCallAuth(hardwareUuid);
91
105
  const eventsWire = eventsWireFromTelemetry(events);
106
+ dbg(`[optimus-tool-call] Events wire:`, JSON.stringify(eventsWire, null, 2).slice(0, 500));
92
107
  const signingPayload = {
93
108
  hardware_uuid: hardwareUuid,
94
109
  events: eventsWire,
95
110
  };
111
+ dbg(`[optimus-tool-call] Payload ready, signing...`);
112
+ const auth = await ensureToolCallAuth(hardwareUuid);
113
+ dbg(`[optimus-tool-call] Auth obtained, key_id: ${auth.key_id}`);
96
114
  const signature = createSignature(signingPayload, auth.key);
97
115
  const payload = {
98
116
  ...signingPayload,
@@ -100,12 +118,15 @@ async function sendBatch(events) {
100
118
  key_id: auth.key_id || "",
101
119
  };
102
120
  const endpoint = new URL("api/tool-calls/events/batch_create/", OPTIMUS_API_BASE).toString();
121
+ dbg(`[optimus-tool-call] Endpoint: ${endpoint}`);
122
+ dbg(`[optimus-tool-call] Payload size: ${JSON.stringify(payload).length} bytes`);
103
123
  const headers = {
104
124
  "Content-Type": "application/json",
105
125
  };
106
126
  try {
107
127
  // Use fetch if available (Node 18+), fall back to node:http
108
128
  if (typeof fetch !== "undefined") {
129
+ dbg(`[optimus-tool-call] Using fetch to send...`);
109
130
  const controller = new AbortController();
110
131
  const timeoutId = setTimeout(() => controller.abort(), 5000);
111
132
  try {
@@ -115,10 +136,13 @@ async function sendBatch(events) {
115
136
  body: JSON.stringify(payload),
116
137
  signal: controller.signal,
117
138
  });
139
+ dbg(`[optimus-tool-call] Response status: ${response.status} ${response.statusText}`);
118
140
  if (!response.ok) {
119
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
141
+ const responseText = await response.text();
142
+ dbg(`[optimus-tool-call] Response body: ${responseText}`);
143
+ throw new Error(`HTTP ${response.status}: ${response.statusText} - ${responseText}`);
120
144
  }
121
- // Successfully sent
145
+ dbg(`[optimus-tool-call] ✅ Successfully sent ${events.length} events`);
122
146
  }
123
147
  finally {
124
148
  clearTimeout(timeoutId);
@@ -126,11 +150,14 @@ async function sendBatch(events) {
126
150
  }
127
151
  else {
128
152
  // Fallback for older Node versions
153
+ dbg(`[optimus-tool-call] Using http fallback...`);
129
154
  await sendViaHttp(endpoint, headers, payload);
130
155
  }
131
156
  }
132
157
  catch (err) {
133
- throw new Error(`Failed to send events to ${endpoint}: ${err instanceof Error ? err.message : String(err)}`);
158
+ const errorMsg = `Failed to send events to ${endpoint}: ${err instanceof Error ? err.message : String(err)}`;
159
+ console.error(`[optimus-tool-call] ❌ ${errorMsg}`);
160
+ throw new Error(errorMsg);
134
161
  }
135
162
  }
136
163
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../src/lib/streaming.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../src/lib/streaming.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Canonical event schema — minimal field extraction from Claude and Cursor hook payloads.
3
+ *
4
+ * No normalization happens here. Raw tool_name, tool_input, and the full raw_event
5
+ * are forwarded to the backend, which owns all agent-specific canonicalization and
6
+ * rule evaluation (see tool_call_audit/classification/enrich.py).
7
+ *
8
+ * The only client-side work is:
9
+ * - agent detection (to set agent_identity)
10
+ * - session_id / tool_use_id extraction (needed for auth and dedup)
11
+ * - user_prompt extraction (requires reading local files the backend cannot access)
12
+ */
13
+ export interface CanonicalHookInput {
14
+ agent: "claude" | "cursor" | "unknown";
15
+ hook_event_name: string;
16
+ tool_name: string;
17
+ tool_input: Record<string, unknown>;
18
+ tool_use_id?: string | null;
19
+ session_id?: string | null;
20
+ cwd?: string | null;
21
+ model?: string | null;
22
+ user_prompt?: string | null;
23
+ raw_event: Record<string, unknown>;
24
+ }
25
+ export declare function normalizeToCanonical(raw: Record<string, unknown>): CanonicalHookInput;
26
+ //# sourceMappingURL=canonical.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Canonical event schema — minimal field extraction from Claude and Cursor hook payloads.
3
+ *
4
+ * No normalization happens here. Raw tool_name, tool_input, and the full raw_event
5
+ * are forwarded to the backend, which owns all agent-specific canonicalization and
6
+ * rule evaluation (see tool_call_audit/classification/enrich.py).
7
+ *
8
+ * The only client-side work is:
9
+ * - agent detection (to set agent_identity)
10
+ * - session_id / tool_use_id extraction (needed for auth and dedup)
11
+ * - user_prompt extraction (requires reading local files the backend cannot access)
12
+ */
13
+ import fs from "fs";
14
+ import os from "os";
15
+ import path from "path";
16
+ export function normalizeToCanonical(raw) {
17
+ const agent = detectAgent(raw);
18
+ const hookEventName = extractHookEventName(raw, agent);
19
+ const toolInfo = extractToolInfo(raw, hookEventName);
20
+ const sessionId = extractSessionId(raw);
21
+ const userPrompt = extractUserPrompt(raw);
22
+ return {
23
+ agent,
24
+ hook_event_name: hookEventName,
25
+ tool_name: toolInfo.tool_name,
26
+ tool_input: toolInfo.tool_input,
27
+ tool_use_id: extractValue(raw, ["tool_use_id", "toolUseId"]) || null,
28
+ session_id: sessionId,
29
+ cwd: extractValue(raw, ["cwd", "workingDirectory"]) || null,
30
+ model: extractValue(raw, ["model"]) || null,
31
+ user_prompt: userPrompt,
32
+ raw_event: raw,
33
+ };
34
+ }
35
+ function detectAgent(raw) {
36
+ // Environment variable is the most reliable signal
37
+ if (process.env.CLAUDE_CODE_SESSION_ID)
38
+ return "claude";
39
+ if (process.env.CURSOR_SESSION_ID || process.env.CURSOR)
40
+ 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") {
46
+ return "claude";
47
+ }
48
+ if (hookEventName === "preToolUse" || hookEventName === "beforeShellExecution" ||
49
+ hookEventName === "beforePromptSubmit") {
50
+ return "cursor";
51
+ }
52
+ // Field naming convention fallback
53
+ if (raw.toolUse || raw.toolName || (raw.sessionId && typeof raw.sessionId === "string")) {
54
+ return "cursor";
55
+ }
56
+ if (raw.tool_use_id || raw.session_id || raw.hook_event_name) {
57
+ return "claude";
58
+ }
59
+ return "claude";
60
+ }
61
+ function extractHookEventName(raw, agent) {
62
+ const explicit = extractValue(raw, ["hook_event_name", "hookEventName", "hook_event"]);
63
+ if (explicit)
64
+ return explicit;
65
+ if (agent === "cursor") {
66
+ if (raw.toolUse || raw.toolName)
67
+ return "preToolUse";
68
+ if (typeof raw.command === "string" && raw.command)
69
+ return "beforeShellExecution";
70
+ }
71
+ return "Unknown";
72
+ }
73
+ function extractToolInfo(raw, hookEventName) {
74
+ const getObj = (value) => value && typeof value === "object" && !Array.isArray(value)
75
+ ? value
76
+ : null;
77
+ const getStr = (value) => typeof value === "string" && value.length > 0 ? value : null;
78
+ // Extract tool_input as-is from wherever it lives in the payload
79
+ const toolUse = getObj(raw.toolUse);
80
+ const tool = getObj(raw.tool);
81
+ const toolInput = getObj(raw.tool_input) ??
82
+ getObj(raw.toolInput) ??
83
+ getObj(toolUse?.input) ??
84
+ getObj(tool?.input) ??
85
+ {};
86
+ // Promote a top-level command field into tool_input if not already there
87
+ const commandFromTop = getStr(raw.command);
88
+ const finalToolInput = commandFromTop && !("command" in toolInput)
89
+ ? { ...toolInput, command: commandFromTop }
90
+ : toolInput;
91
+ // Extract tool_name as-is — no mapping, backend owns normalization
92
+ const toolName = getStr(raw.tool_name) ??
93
+ getStr(raw.toolName) ??
94
+ getStr(toolUse?.name) ??
95
+ getStr(tool?.name) ??
96
+ (hookEventName === "beforeShellExecution" || commandFromTop ? "Bash" : "Unknown");
97
+ return { tool_name: toolName, tool_input: finalToolInput };
98
+ }
99
+ function extractSessionId(raw) {
100
+ return (extractValue(raw, ["session_id", "sessionId", "conversation_id"]) ??
101
+ process.env.CLAUDE_CODE_SESSION_ID ??
102
+ process.env.CURSOR_SESSION_ID ??
103
+ null);
104
+ }
105
+ function extractUserPrompt(raw) {
106
+ // Direct field in payload
107
+ const prompt = extractValue(raw, ["user_prompt", "userPrompt", "prompt"]);
108
+ if (prompt)
109
+ return prompt;
110
+ // Cursor: explicit prompt file path
111
+ const promptFilePath = extractValue(raw, ["prompt_file_path", "promptFilePath"]);
112
+ if (promptFilePath) {
113
+ try {
114
+ const content = fs.readFileSync(promptFilePath, "utf-8").trim();
115
+ return content || null;
116
+ }
117
+ catch {
118
+ // not readable — continue
119
+ }
120
+ }
121
+ // Cursor: read from temp cache written by the beforeSubmitPrompt hook
122
+ const sessionId = extractSessionId(raw);
123
+ if (sessionId) {
124
+ const cachedPrompt = readCachedPrompt(sessionId);
125
+ if (cachedPrompt)
126
+ return cachedPrompt;
127
+ }
128
+ return null;
129
+ }
130
+ function readCachedPrompt(sessionId) {
131
+ try {
132
+ const promptCacheDir = path.join(os.tmpdir(), "optimus-prompt-cache");
133
+ const latestFile = path.join(promptCacheDir, `prompt-${sessionId}.txt`);
134
+ if (fs.existsSync(latestFile)) {
135
+ const content = fs.readFileSync(latestFile, "utf-8").trim();
136
+ return content || null;
137
+ }
138
+ }
139
+ catch {
140
+ // non-fatal
141
+ }
142
+ return null;
143
+ }
144
+ function extractValue(obj, keys) {
145
+ for (const key of keys) {
146
+ const value = obj[key];
147
+ if (value !== undefined && value !== null) {
148
+ return value;
149
+ }
150
+ }
151
+ return undefined;
152
+ }
153
+ //# sourceMappingURL=canonical.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../../src/lib/telemetry/canonical.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  * Telemetry — tool invocations to audit events.
3
3
  */
4
4
  export * from "./types.js";
5
+ export * from "./canonical.js";
5
6
  export { eventToDict } from "./serialize.js";
6
7
  export { buildTelemetryEvent } from "./build-event.js";
7
8
  export { cloneToolCallMetadataForWire, SERVER_OWNED_TOOL_CALL_METADATA_KEYS, } from "./wire-metadata.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,4BAA4B,EAC5B,oCAAoC,GACrC,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,4BAA4B,EAC5B,oCAAoC,GACrC,MAAM,oBAAoB,CAAC"}
@@ -2,6 +2,7 @@
2
2
  * Telemetry — tool invocations to audit events.
3
3
  */
4
4
  export * from "./types.js";
5
+ export * from "./canonical.js";
5
6
  export { eventToDict } from "./serialize.js";
6
7
  export { buildTelemetryEvent } from "./build-event.js";
7
8
  export { cloneToolCallMetadataForWire, SERVER_OWNED_TOOL_CALL_METADATA_KEYS, } from "./wire-metadata.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/telemetry/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,4BAA4B,EAC5B,oCAAoC,GACrC,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/telemetry/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,4BAA4B,EAC5B,oCAAoC,GACrC,MAAM,oBAAoB,CAAC"}
@@ -8,6 +8,7 @@ export interface ToolInvocation {
8
8
  tool_name: string;
9
9
  tool_input: Record<string, unknown>;
10
10
  tool_use_id?: string | null;
11
+ session_id?: string | null;
11
12
  cwd?: string | null;
12
13
  hook_event_name?: string | null;
13
14
  model?: string | null;
@@ -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,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;KACrC,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,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACrC,CAAC;CACH"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=canonical.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.test.d.ts","sourceRoot":"","sources":["../../src/test/canonical.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,117 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert";
3
+ import { normalizeToCanonical } from "../lib/telemetry/canonical.js";
4
+ test("normalizeToCanonical - Claude PreToolUse hook", () => {
5
+ const raw = {
6
+ hook_event_name: "PreToolUse",
7
+ tool_name: "Read",
8
+ tool_input: { file_path: "/etc/passwd" },
9
+ session_id: "claude-session-123",
10
+ cwd: "/home/user",
11
+ };
12
+ const canonical = normalizeToCanonical(raw);
13
+ assert.strictEqual(canonical.agent, "claude");
14
+ assert.strictEqual(canonical.hook_event_name, "PreToolUse");
15
+ assert.strictEqual(canonical.tool_name, "Read");
16
+ assert.strictEqual(canonical.session_id, "claude-session-123");
17
+ assert.strictEqual(canonical.cwd, "/home/user");
18
+ });
19
+ test("normalizeToCanonical - Claude with user_prompt", () => {
20
+ const raw = {
21
+ hook_event_name: "PreToolUse",
22
+ tool_name: "Bash",
23
+ tool_input: { command: "ls" },
24
+ user_prompt: "list the files",
25
+ };
26
+ const canonical = normalizeToCanonical(raw);
27
+ assert.strictEqual(canonical.agent, "claude");
28
+ assert.strictEqual(canonical.user_prompt, "list the files");
29
+ });
30
+ test("normalizeToCanonical - Cursor preToolUse hook", () => {
31
+ const raw = {
32
+ toolUse: {
33
+ name: "Read",
34
+ input: { file_path: "/etc/passwd" },
35
+ },
36
+ sessionId: "cursor-session-456",
37
+ };
38
+ const canonical = normalizeToCanonical(raw);
39
+ assert.strictEqual(canonical.agent, "cursor");
40
+ assert.strictEqual(canonical.hook_event_name, "preToolUse");
41
+ assert.strictEqual(canonical.tool_name, "Read");
42
+ assert.strictEqual(canonical.session_id, "cursor-session-456");
43
+ });
44
+ test("normalizeToCanonical - Cursor beforeShellExecution hook", () => {
45
+ const raw = {
46
+ command: "rm -rf /tmp/test",
47
+ sessionId: "cursor-session-789",
48
+ cwd: "/home/user",
49
+ };
50
+ const canonical = normalizeToCanonical(raw);
51
+ assert.strictEqual(canonical.agent, "cursor");
52
+ assert.strictEqual(canonical.hook_event_name, "beforeShellExecution");
53
+ assert.strictEqual(canonical.tool_name, "Bash");
54
+ assert.deepEqual(canonical.tool_input, { command: "rm -rf /tmp/test" });
55
+ });
56
+ test("normalizeToCanonical - Both agents produce compatible structure", () => {
57
+ const claudeRaw = {
58
+ hook_event_name: "PreToolUse",
59
+ tool_name: "Bash",
60
+ tool_input: { command: "echo hello" },
61
+ user_prompt: "print hello",
62
+ };
63
+ const cursorRaw = {
64
+ command: "echo hello",
65
+ toolName: "Bash", // Cursor uses camelCase
66
+ userPrompt: "print hello", // Cursor uses camelCase
67
+ };
68
+ const claudeCanonical = normalizeToCanonical(claudeRaw);
69
+ const cursorCanonical = normalizeToCanonical(cursorRaw);
70
+ // Both should have same tool info
71
+ assert.strictEqual(claudeCanonical.tool_name, cursorCanonical.tool_name);
72
+ assert.deepEqual(claudeCanonical.tool_input, cursorCanonical.tool_input);
73
+ assert.strictEqual(claudeCanonical.user_prompt, cursorCanonical.user_prompt);
74
+ assert.strictEqual(claudeCanonical.agent, "claude");
75
+ assert.strictEqual(cursorCanonical.agent, "cursor");
76
+ });
77
+ test("normalizeToCanonical - Cursor with alt field names (camelCase)", () => {
78
+ const raw = {
79
+ toolUse: {
80
+ name: "Write",
81
+ input: { file_path: "/tmp/test.txt" },
82
+ },
83
+ toolUseId: "tool-123",
84
+ sessionId: "cursor-session",
85
+ };
86
+ const canonical = normalizeToCanonical(raw);
87
+ assert.strictEqual(canonical.tool_name, "Write");
88
+ assert.strictEqual(canonical.tool_use_id, "tool-123");
89
+ assert.strictEqual(canonical.session_id, "cursor-session");
90
+ });
91
+ test("normalizeToCanonical - MCP tool calls from both agents", () => {
92
+ const claudeRaw = {
93
+ hook_event_name: "PreToolUse",
94
+ tool_name: "mcp__sequential_thinking__think",
95
+ tool_input: { thought: "analyze this" },
96
+ };
97
+ const cursorRaw = {
98
+ toolName: "mcp__sequential_thinking__think",
99
+ toolInput: { thought: "analyze this" },
100
+ };
101
+ const claudeCanonical = normalizeToCanonical(claudeRaw);
102
+ const cursorCanonical = normalizeToCanonical(cursorRaw);
103
+ assert.strictEqual(claudeCanonical.tool_name, "mcp__sequential_thinking__think");
104
+ assert.strictEqual(cursorCanonical.tool_name, "mcp__sequential_thinking__think");
105
+ });
106
+ test("normalizeToCanonical - Handles missing fields gracefully", () => {
107
+ const raw = {
108
+ tool_name: "Read",
109
+ tool_input: {},
110
+ };
111
+ const canonical = normalizeToCanonical(raw);
112
+ assert.strictEqual(canonical.tool_name, "Read");
113
+ assert.deepEqual(canonical.tool_input, {});
114
+ assert.strictEqual(canonical.session_id, null);
115
+ assert.strictEqual(canonical.user_prompt, null);
116
+ });
117
+ //# sourceMappingURL=canonical.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.test.js","sourceRoot":"","sources":["../../src/test/canonical.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=integration-canonical.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-canonical.test.d.ts","sourceRoot":"","sources":["../../src/test/integration-canonical.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,157 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert";
3
+ import { buildTelemetryEvent } from "../lib/telemetry.js";
4
+ import { normalizeToCanonical } from "../lib/telemetry/canonical.js";
5
+ /**
6
+ * Integration tests verifying that Claude and Cursor produce identical
7
+ * telemetry events for the same tool invocations.
8
+ */
9
+ test("Integration: Read /etc/passwd from both agents produces same event", () => {
10
+ // Claude hook payload
11
+ const claudeRaw = {
12
+ hook_event_name: "PreToolUse",
13
+ tool_name: "Read",
14
+ tool_input: { file_path: "/etc/passwd" },
15
+ session_id: "session-123",
16
+ cwd: "/home/user",
17
+ };
18
+ // Cursor hook payload (same action, different format)
19
+ const cursorRaw = {
20
+ toolUse: { name: "Read", input: { file_path: "/etc/passwd" } },
21
+ sessionId: "session-123",
22
+ cwd: "/home/user",
23
+ };
24
+ // Normalize both
25
+ const claudeCanonical = normalizeToCanonical(claudeRaw);
26
+ const cursorCanonical = normalizeToCanonical(cursorRaw);
27
+ // Build telemetry events
28
+ const claudeEvent = buildTelemetryEvent({
29
+ tool_name: claudeCanonical.tool_name,
30
+ tool_input: claudeCanonical.tool_input,
31
+ session_id: claudeCanonical.session_id,
32
+ cwd: claudeCanonical.cwd,
33
+ hook_event_name: claudeCanonical.hook_event_name,
34
+ raw_event: claudeCanonical.raw_event,
35
+ }, "claude", claudeCanonical.session_id);
36
+ const cursorEvent = buildTelemetryEvent({
37
+ tool_name: cursorCanonical.tool_name,
38
+ tool_input: cursorCanonical.tool_input,
39
+ session_id: cursorCanonical.session_id,
40
+ cwd: cursorCanonical.cwd,
41
+ hook_event_name: cursorCanonical.hook_event_name,
42
+ raw_event: cursorCanonical.raw_event,
43
+ }, "cursor", cursorCanonical.session_id);
44
+ // Verify critical fields match (except agent_identity which should differ)
45
+ assert(claudeEvent);
46
+ assert(cursorEvent);
47
+ assert.strictEqual(claudeEvent.event_type, cursorEvent.event_type);
48
+ assert.strictEqual(claudeEvent.session_id, cursorEvent.session_id);
49
+ assert.strictEqual(claudeEvent.working_directory, cursorEvent.working_directory);
50
+ assert.strictEqual(claudeEvent.tool_call_metadata.tool_name, cursorEvent.tool_call_metadata.tool_name);
51
+ assert.deepEqual(claudeEvent.tool_call_metadata.tool_input, cursorEvent.tool_call_metadata.tool_input);
52
+ // Agent identity should be different
53
+ assert.strictEqual(claudeEvent.agent_identity, "claude");
54
+ assert.strictEqual(cursorEvent.agent_identity, "cursor");
55
+ });
56
+ test("Integration: Dangerous shell command from both agents", () => {
57
+ // Claude preToolUse with bash command
58
+ const claudeRaw = {
59
+ hook_event_name: "PreToolUse",
60
+ tool_name: "Bash",
61
+ tool_input: { command: "rm -rf /var/log" },
62
+ user_prompt: "clean up logs",
63
+ session_id: "claude-sess",
64
+ };
65
+ // Cursor preToolUse with bash command (different field names)
66
+ const cursorRaw = {
67
+ toolUse: {
68
+ name: "Bash",
69
+ input: { command: "rm -rf /var/log" },
70
+ },
71
+ user_prompt: "clean up logs",
72
+ sessionId: "cursor-sess",
73
+ };
74
+ const claudeCanonical = normalizeToCanonical(claudeRaw);
75
+ const cursorCanonical = normalizeToCanonical(cursorRaw);
76
+ // Tool information should be identical
77
+ assert.strictEqual(claudeCanonical.tool_name, cursorCanonical.tool_name);
78
+ assert.strictEqual(claudeCanonical.tool_name, "Bash");
79
+ assert.deepEqual(claudeCanonical.tool_input.command, cursorCanonical.tool_input.command);
80
+ assert.strictEqual(claudeCanonical.user_prompt, cursorCanonical.user_prompt);
81
+ // But agents should be detected correctly
82
+ assert.strictEqual(claudeCanonical.agent, "claude");
83
+ assert.strictEqual(cursorCanonical.agent, "cursor");
84
+ });
85
+ test("Integration: Web operations from both agents", () => {
86
+ const claudeRaw = {
87
+ hook_event_name: "PreToolUse",
88
+ tool_name: "WebFetch",
89
+ tool_input: { url: "https://api.github.com/user", prompt: "check auth" },
90
+ user_prompt: "verify github access",
91
+ };
92
+ const cursorRaw = {
93
+ toolName: "WebFetch",
94
+ toolInput: { url: "https://api.github.com/user", prompt: "check auth" },
95
+ userPrompt: "verify github access",
96
+ };
97
+ const claudeCanonical = normalizeToCanonical(claudeRaw);
98
+ const cursorCanonical = normalizeToCanonical(cursorRaw);
99
+ assert.strictEqual(claudeCanonical.tool_name, "WebFetch");
100
+ assert.strictEqual(cursorCanonical.tool_name, "WebFetch");
101
+ assert.deepEqual(claudeCanonical.tool_input, cursorCanonical.tool_input);
102
+ });
103
+ test("Integration: MCP tool invocations from both agents", () => {
104
+ const claudeRaw = {
105
+ hook_event_name: "PreToolUse",
106
+ tool_name: "mcp__sequential_thinking__think",
107
+ tool_input: { thought: "this is complex" },
108
+ };
109
+ const cursorRaw = {
110
+ toolName: "mcp__sequential_thinking__think",
111
+ toolInput: { thought: "this is complex" },
112
+ };
113
+ const claudeCanonical = normalizeToCanonical(claudeRaw);
114
+ const cursorCanonical = normalizeToCanonical(cursorRaw);
115
+ assert.strictEqual(claudeCanonical.tool_name, cursorCanonical.tool_name);
116
+ assert.deepEqual(claudeCanonical.tool_input, cursorCanonical.tool_input);
117
+ });
118
+ test("Integration: Cursor beforeShellExecution maps to same canonical as Claude preToolUse Bash", () => {
119
+ // Claude preToolUse with Bash
120
+ const claudeRaw = {
121
+ hook_event_name: "PreToolUse",
122
+ tool_name: "Bash",
123
+ tool_input: { command: "curl -X GET https://api.example.com" },
124
+ };
125
+ // Cursor beforeShellExecution with same command
126
+ const cursorRaw = {
127
+ command: "curl -X GET https://api.example.com",
128
+ };
129
+ const claudeCanonical = normalizeToCanonical(claudeRaw);
130
+ const cursorCanonical = normalizeToCanonical(cursorRaw);
131
+ // Both should identify as shell operations
132
+ assert.strictEqual(claudeCanonical.tool_name, "Bash");
133
+ assert.strictEqual(cursorCanonical.tool_name, "Bash");
134
+ // Tool input should be normalized the same way
135
+ assert.deepEqual(claudeCanonical.tool_input, cursorCanonical.tool_input);
136
+ assert.strictEqual(claudeCanonical.tool_input.command, "curl -X GET https://api.example.com");
137
+ });
138
+ test("Integration: Write operations with sensitivity", () => {
139
+ const claudeRaw = {
140
+ hook_event_name: "PreToolUse",
141
+ tool_name: "Write",
142
+ tool_input: { file_path: "~/.ssh/authorized_keys" },
143
+ user_prompt: "add SSH key",
144
+ };
145
+ const cursorRaw = {
146
+ tool: { name: "Write", input: { file_path: "~/.ssh/authorized_keys" } },
147
+ userPrompt: "add SSH key",
148
+ };
149
+ const claudeCanonical = normalizeToCanonical(claudeRaw);
150
+ const cursorCanonical = normalizeToCanonical(cursorRaw);
151
+ // Sensitive path should be preserved identically
152
+ assert.strictEqual(claudeCanonical.tool_name, "Write");
153
+ assert.strictEqual(cursorCanonical.tool_name, "Write");
154
+ assert.deepEqual(claudeCanonical.tool_input, cursorCanonical.tool_input);
155
+ assert.strictEqual(claudeCanonical.tool_input.file_path, "~/.ssh/authorized_keys");
156
+ });
157
+ //# sourceMappingURL=integration-canonical.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-canonical.test.js","sourceRoot":"","sources":["../../src/test/integration-canonical.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "optimus-tool-call",
3
- "version": "0.2.1",
3
+ "version": "0.2.4",
4
4
  "description": "Agentic audit sensor — streams raw tool call metadata; the Optimus backend classifies on ingest",
5
5
  "type": "module",
6
6
  "bin": {
7
- "optimus-tool-call": "./dist/index.js"
7
+ "optimus-tool-call": "./dist/index.js",
8
+ "optimus-capture-prompt": "./dist/capture-prompt.js"
8
9
  },
9
10
  "main": "./dist/index.js",
10
11
  "scripts": {