optimus-tool-call 0.2.2 → 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.
- package/dist/capture-prompt.d.ts +14 -0
- package/dist/capture-prompt.d.ts.map +1 -0
- package/dist/capture-prompt.js +173 -0
- package/dist/capture-prompt.js.map +1 -0
- package/dist/index.js +47 -91
- package/dist/index.js.map +1 -1
- package/dist/lib/streaming.d.ts.map +1 -1
- package/dist/lib/streaming.js +33 -6
- package/dist/lib/streaming.js.map +1 -1
- package/dist/lib/telemetry/canonical.d.ts +26 -0
- package/dist/lib/telemetry/canonical.d.ts.map +1 -0
- package/dist/lib/telemetry/canonical.js +153 -0
- package/dist/lib/telemetry/canonical.js.map +1 -0
- package/dist/lib/telemetry/index.d.ts +1 -0
- package/dist/lib/telemetry/index.d.ts.map +1 -1
- package/dist/lib/telemetry/index.js +1 -0
- package/dist/lib/telemetry/index.js.map +1 -1
- package/dist/test/canonical.test.d.ts +2 -0
- package/dist/test/canonical.test.d.ts.map +1 -0
- package/dist/test/canonical.test.js +117 -0
- package/dist/test/canonical.test.js.map +1 -0
- package/dist/test/integration-canonical.test.d.ts +2 -0
- package/dist/test/integration-canonical.test.d.ts.map +1 -0
- package/dist/test/integration-canonical.test.js +157 -0
- package/dist/test/integration-canonical.test.js.map +1 -0
- package/package.json +3 -2
|
@@ -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":"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"}
|
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
|
-
|
|
17
|
-
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
|
47
|
-
const event = buildTelemetryEvent(invocation, agentIdentity, invocation.session_id);
|
|
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,59 +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
|
-
const sessionId = getStr(raw.session_id) ??
|
|
119
|
-
getStr(raw.sessionId) ??
|
|
120
|
-
getStr(process.env.CLAUDE_CODE_SESSION_ID ?? null) ??
|
|
121
|
-
null;
|
|
122
|
-
return {
|
|
123
|
-
tool_name: toolName,
|
|
124
|
-
tool_input: normalizedToolInput,
|
|
125
|
-
tool_use_id: getStr(raw.tool_use_id) ?? getStr(raw.toolUseId),
|
|
126
|
-
session_id: sessionId,
|
|
127
|
-
cwd: getStr(raw.cwd),
|
|
128
|
-
hook_event_name: hookEventName,
|
|
129
|
-
model: getStr(raw.model),
|
|
130
|
-
agent_message: getStr(raw.agent_message) ?? getStr(raw.agentMessage),
|
|
131
|
-
raw_event: raw,
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
108
|
/**
|
|
135
109
|
* Read the Claude Code session transcript (JSONL) and return the text of the
|
|
136
110
|
* last user-typed message. Each line is a JSON object; user turns look like:
|
|
@@ -180,24 +154,6 @@ function readLastUserPrompt(transcriptPath) {
|
|
|
180
154
|
}
|
|
181
155
|
return null;
|
|
182
156
|
}
|
|
183
|
-
function detectAgent() {
|
|
184
|
-
/**
|
|
185
|
-
* Detect which agent is running this hook.
|
|
186
|
-
* Can be extended with environment variables or other signals.
|
|
187
|
-
*/
|
|
188
|
-
// Check environment variables for agent identification
|
|
189
|
-
if (process.env.CLAUDE_CODE_SESSION_ID) {
|
|
190
|
-
return "claude";
|
|
191
|
-
}
|
|
192
|
-
if (process.env.CURSOR_SESSION_ID || process.env.CURSOR) {
|
|
193
|
-
return "cursor";
|
|
194
|
-
}
|
|
195
|
-
if (process.env.GITHUB_COPILOT) {
|
|
196
|
-
return "copilot";
|
|
197
|
-
}
|
|
198
|
-
// Default to claude for Claude Code CLI
|
|
199
|
-
return "claude";
|
|
200
|
-
}
|
|
201
157
|
// Run
|
|
202
158
|
main().catch((err) => {
|
|
203
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":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAuB,MAAM,oBAAoB,CAAC;AAC3F,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;
|
|
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;
|
|
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"}
|
package/dist/lib/streaming.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAexB,MAAM,UAAU,oBAAoB,CAAC,GAA4B;IAC/D,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,aAAa,GAAG,oBAAoB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAE1C,OAAO;QACL,KAAK;QACL,eAAe,EAAE,aAAa;QAC9B,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,WAAW,EAAE,YAAY,CAAS,GAAG,EAAE,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC,IAAI,IAAI;QAC5E,UAAU,EAAE,SAAS;QACrB,GAAG,EAAE,YAAY,CAAS,GAAG,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC,IAAI,IAAI;QACnE,KAAK,EAAE,YAAY,CAAS,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI;QACnD,WAAW,EAAE,UAAU;QACvB,SAAS,EAAE,GAAG;KACf,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,GAA4B;IAC/C,mDAAmD;IACnD,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB;QAAE,OAAO,QAAQ,CAAC;IACxD,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC;IAEzE,MAAM,aAAa,GAAG,YAAY,CAAS,GAAG,EAAE,CAAC,iBAAiB,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC,CAAC;IAEpG,0DAA0D;IAC1D,IAAI,aAAa,KAAK,YAAY,IAAI,aAAa,KAAK,cAAc;QAClE,aAAa,KAAK,YAAY,IAAI,aAAa,KAAK,aAAa;QACjE,aAAa,KAAK,oBAAoB,IAAI,aAAa,KAAK,mBAAmB,EAAE,CAAC;QACpF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,aAAa,KAAK,YAAY,IAAI,aAAa,KAAK,sBAAsB;QAC1E,aAAa,KAAK,oBAAoB,EAAE,CAAC;QAC3C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,mCAAmC;IACnC,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,SAAS,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC,EAAE,CAAC;QACxF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;QAC7D,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,oBAAoB,CAAC,GAA4B,EAAE,KAAuC;IACjG,MAAM,QAAQ,GAAG,YAAY,CAAS,GAAG,EAAE,CAAC,iBAAiB,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC,CAAC;IAC/F,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,QAAQ;YAAE,OAAO,YAAY,CAAC;QACrD,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO;YAAE,OAAO,sBAAsB,CAAC;IACpF,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CACtB,GAA4B,EAC5B,aAAqB;IAErB,MAAM,MAAM,GAAG,CAAC,KAAc,EAAkC,EAAE,CAChE,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACzD,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,IAAI,CAAC;IAEX,MAAM,MAAM,GAAG,CAAC,KAAc,EAAiB,EAAE,CAC/C,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAE/D,iEAAiE;IACjE,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,SAAS,GACb,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;QACrB,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC;QACtB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC;QACnB,EAAE,CAAC;IAEL,yEAAyE;IACzE,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,cAAc,GAClB,cAAc,IAAI,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC;QACzC,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE;QAC3C,CAAC,CAAC,SAAS,CAAC;IAEhB,mEAAmE;IACnE,MAAM,QAAQ,GACZ,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;QACrB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACpB,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC;QACrB,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC;QAClB,CAAC,aAAa,KAAK,sBAAsB,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEpF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC;AAC7D,CAAC;AAED,SAAS,gBAAgB,CAAC,GAA4B;IACpD,OAAO,CACL,YAAY,CAAS,GAAG,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,sBAAsB;QAClC,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC7B,IAAI,CACL,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,GAA4B;IACrD,0BAA0B;IAC1B,MAAM,MAAM,GAAG,YAAY,CAAS,GAAG,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAClF,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,oCAAoC;IACpC,MAAM,cAAc,GAAG,YAAY,CAAS,GAAG,EAAE,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACzF,IAAI,cAAc,EAAE,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YAChE,OAAO,OAAO,IAAI,IAAI,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,0BAA0B;QAC5B,CAAC;IACH,CAAC;IAED,sEAAsE;IACtE,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,YAAY,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,YAAY;YAAE,OAAO,YAAY,CAAC;IACxC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAiB;IACzC,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC;QACtE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,SAAS,MAAM,CAAC,CAAC;QACxE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5D,OAAO,OAAO,IAAI,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,YAAY,CACnB,GAA4B,EAC5B,IAAc;IAEd,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,EAAE,CAAC;YAC1C,OAAO,KAAU,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,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.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"}
|
|
@@ -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":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAA2B,MAAM,+BAA+B,CAAC;AAE9F,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;IACzD,MAAM,GAAG,GAAG;QACV,eAAe,EAAE,YAAY;QAC7B,SAAS,EAAE,MAAM;QACjB,UAAU,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE;QACxC,UAAU,EAAE,oBAAoB;QAChC,GAAG,EAAE,YAAY;KAClB,CAAC;IAEF,MAAM,SAAS,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;IAC5D,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IAC/D,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC1D,MAAM,GAAG,GAAG;QACV,eAAe,EAAE,YAAY;QAC7B,SAAS,EAAE,MAAM;QACjB,UAAU,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;QAC7B,WAAW,EAAE,gBAAgB;KAC9B,CAAC;IAEF,MAAM,SAAS,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;IACzD,MAAM,GAAG,GAAG;QACV,OAAO,EAAE;YACP,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE;SACpC;QACD,SAAS,EAAE,oBAAoB;KAChC,CAAC;IAEF,MAAM,SAAS,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;IAC5D,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;AACjE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yDAAyD,EAAE,GAAG,EAAE;IACnE,MAAM,GAAG,GAAG;QACV,OAAO,EAAE,kBAAkB;QAC3B,SAAS,EAAE,oBAAoB;QAC/B,GAAG,EAAE,YAAY;KAClB,CAAC;IAEF,MAAM,SAAS,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAAC;IACtE,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;AAC1E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iEAAiE,EAAE,GAAG,EAAE;IAC3E,MAAM,SAAS,GAAG;QAChB,eAAe,EAAE,YAAY;QAC7B,SAAS,EAAE,MAAM;QACjB,UAAU,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE;QACrC,WAAW,EAAE,aAAa;KAC3B,CAAC;IAEF,MAAM,SAAS,GAAG;QAChB,OAAO,EAAE,YAAY;QACrB,QAAQ,EAAE,MAAM,EAAE,wBAAwB;QAC1C,UAAU,EAAE,aAAa,EAAE,wBAAwB;KACpD,CAAC;IAEF,MAAM,eAAe,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;IACxD,MAAM,eAAe,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAExD,kCAAkC;IAClC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,SAAS,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;IACzE,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,UAAU,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;IACzE,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,WAAW,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC;IAC7E,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACpD,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gEAAgE,EAAE,GAAG,EAAE;IAC1E,MAAM,GAAG,GAAG;QACV,OAAO,EAAE;YACP,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE;SACtC;QACD,SAAS,EAAE,UAAU;QACrB,SAAS,EAAE,gBAAgB;KAC5B,CAAC;IAEF,MAAM,SAAS,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACtD,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wDAAwD,EAAE,GAAG,EAAE;IAClE,MAAM,SAAS,GAAG;QAChB,eAAe,EAAE,YAAY;QAC7B,SAAS,EAAE,iCAAiC;QAC5C,UAAU,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE;KACxC,CAAC;IAEF,MAAM,SAAS,GAAG;QAChB,QAAQ,EAAE,iCAAiC;QAC3C,SAAS,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE;KACvC,CAAC;IAEF,MAAM,eAAe,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;IACxD,MAAM,eAAe,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAExD,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,SAAS,EAAE,iCAAiC,CAAC,CAAC;IACjF,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,SAAS,EAAE,iCAAiC,CAAC,CAAC;AACnF,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0DAA0D,EAAE,GAAG,EAAE;IACpE,MAAM,GAAG,GAAG;QACV,SAAS,EAAE,MAAM;QACjB,UAAU,EAAE,EAAE;KACf,CAAC;IAEF,MAAM,SAAS,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC/C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC"}
|
|
@@ -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.
|
|
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": {
|