@optimuslabs/runtime 0.3.3
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/LICENSE +21 -0
- package/README.md +198 -0
- 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.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +203 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/client-event.d.ts +12 -0
- package/dist/lib/client-event.d.ts.map +1 -0
- package/dist/lib/client-event.js +140 -0
- package/dist/lib/client-event.js.map +1 -0
- package/dist/lib/endpoint-config.d.ts +2 -0
- package/dist/lib/endpoint-config.d.ts.map +1 -0
- package/dist/lib/endpoint-config.js +2 -0
- package/dist/lib/endpoint-config.js.map +1 -0
- package/dist/lib/hardware-uuid.d.ts +7 -0
- package/dist/lib/hardware-uuid.d.ts.map +1 -0
- package/dist/lib/hardware-uuid.js +52 -0
- package/dist/lib/hardware-uuid.js.map +1 -0
- package/dist/lib/machine-auth.d.ts +11 -0
- package/dist/lib/machine-auth.d.ts.map +1 -0
- package/dist/lib/machine-auth.js +46 -0
- package/dist/lib/machine-auth.js.map +1 -0
- package/dist/lib/pending-events.d.ts +49 -0
- package/dist/lib/pending-events.d.ts.map +1 -0
- package/dist/lib/pending-events.js +135 -0
- package/dist/lib/pending-events.js.map +1 -0
- package/dist/lib/startup-sync.d.ts +13 -0
- package/dist/lib/startup-sync.d.ts.map +1 -0
- package/dist/lib/startup-sync.js +164 -0
- package/dist/lib/startup-sync.js.map +1 -0
- package/dist/lib/streaming.d.ts +35 -0
- package/dist/lib/streaming.d.ts.map +1 -0
- package/dist/lib/streaming.js +326 -0
- package/dist/lib/streaming.js.map +1 -0
- package/dist/lib/telemetry/build-event.d.ts +10 -0
- package/dist/lib/telemetry/build-event.d.ts.map +1 -0
- package/dist/lib/telemetry/build-event.js +34 -0
- package/dist/lib/telemetry/build-event.js.map +1 -0
- 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 +9 -0
- package/dist/lib/telemetry/index.d.ts.map +1 -0
- package/dist/lib/telemetry/index.js +9 -0
- package/dist/lib/telemetry/index.js.map +1 -0
- package/dist/lib/telemetry/serialize.d.ts +3 -0
- package/dist/lib/telemetry/serialize.d.ts.map +1 -0
- package/dist/lib/telemetry/serialize.js +15 -0
- package/dist/lib/telemetry/serialize.js.map +1 -0
- package/dist/lib/telemetry/types.d.ts +35 -0
- package/dist/lib/telemetry/types.d.ts.map +1 -0
- package/dist/lib/telemetry/types.js +14 -0
- package/dist/lib/telemetry/types.js.map +1 -0
- package/dist/lib/telemetry/wire-metadata.d.ts +10 -0
- package/dist/lib/telemetry/wire-metadata.d.ts.map +1 -0
- package/dist/lib/telemetry/wire-metadata.js +28 -0
- package/dist/lib/telemetry/wire-metadata.js.map +1 -0
- package/dist/lib/telemetry.d.ts +2 -0
- package/dist/lib/telemetry.d.ts.map +1 -0
- package/dist/lib/telemetry.js +2 -0
- package/dist/lib/telemetry.js.map +1 -0
- package/dist/lib/tofu.d.ts +16 -0
- package/dist/lib/tofu.d.ts.map +1 -0
- package/dist/lib/tofu.js +44 -0
- package/dist/lib/tofu.js.map +1 -0
- package/dist/lib/user-profile.d.ts +17 -0
- package/dist/lib/user-profile.d.ts.map +1 -0
- package/dist/lib/user-profile.js +187 -0
- package/dist/lib/user-profile.js.map +1 -0
- 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 +138 -0
- package/dist/test/canonical.test.js.map +1 -0
- package/dist/test/endpoint-config.test.d.ts +2 -0
- package/dist/test/endpoint-config.test.d.ts.map +1 -0
- package/dist/test/endpoint-config.test.js +73 -0
- package/dist/test/endpoint-config.test.js.map +1 -0
- package/dist/test/index.test.d.ts +2 -0
- package/dist/test/index.test.d.ts.map +1 -0
- package/dist/test/index.test.js +376 -0
- package/dist/test/index.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 +176 -0
- package/dist/test/integration-canonical.test.js.map +1 -0
- package/dist/test/pending-events.test.d.ts +13 -0
- package/dist/test/pending-events.test.d.ts.map +1 -0
- package/dist/test/pending-events.test.js +265 -0
- package/dist/test/pending-events.test.js.map +1 -0
- package/dist/test/startup-sync.test.d.ts +2 -0
- package/dist/test/startup-sync.test.d.ts.map +1 -0
- package/dist/test/startup-sync.test.js +57 -0
- package/dist/test/startup-sync.test.js.map +1 -0
- package/dist/test/streaming-http.test.d.ts +11 -0
- package/dist/test/streaming-http.test.d.ts.map +1 -0
- package/dist/test/streaming-http.test.js +181 -0
- package/dist/test/streaming-http.test.js.map +1 -0
- package/dist/test/streaming.test.d.ts +2 -0
- package/dist/test/streaming.test.d.ts.map +1 -0
- package/dist/test/streaming.test.js +223 -0
- package/dist/test/streaming.test.js.map +1 -0
- package/dist/test/telemetry.test.d.ts +2 -0
- package/dist/test/telemetry.test.d.ts.map +1 -0
- package/dist/test/telemetry.test.js +201 -0
- package/dist/test/telemetry.test.js.map +1 -0
- package/package.json +54 -0
|
@@ -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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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry — tool invocations to audit events.
|
|
3
|
+
*/
|
|
4
|
+
export * from "./types.js";
|
|
5
|
+
export * from "./canonical.js";
|
|
6
|
+
export { eventToDict } from "./serialize.js";
|
|
7
|
+
export { buildTelemetryEvent } from "./build-event.js";
|
|
8
|
+
export { cloneToolCallMetadataForWire, SERVER_OWNED_TOOL_CALL_METADATA_KEYS, } from "./wire-metadata.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry — tool invocations to audit events.
|
|
3
|
+
*/
|
|
4
|
+
export * from "./types.js";
|
|
5
|
+
export * from "./canonical.js";
|
|
6
|
+
export { eventToDict } from "./serialize.js";
|
|
7
|
+
export { buildTelemetryEvent } from "./build-event.js";
|
|
8
|
+
export { cloneToolCallMetadataForWire, SERVER_OWNED_TOOL_CALL_METADATA_KEYS, } from "./wire-metadata.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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":"serialize.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/serialize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAa1E"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function eventToDict(event) {
|
|
2
|
+
return {
|
|
3
|
+
timestamp: event.timestamp,
|
|
4
|
+
agent_identity: event.agent_identity,
|
|
5
|
+
event_type: event.event_type,
|
|
6
|
+
session_id: event.session_id,
|
|
7
|
+
tool_use_id: event.tool_use_id,
|
|
8
|
+
hook_event_name: event.hook_event_name,
|
|
9
|
+
working_directory: event.working_directory,
|
|
10
|
+
tool_name: event.tool_call_metadata?.tool_name,
|
|
11
|
+
tool_input: event.tool_call_metadata?.tool_input,
|
|
12
|
+
user_prompt: event.tool_call_metadata?.user_prompt,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=serialize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../../src/lib/telemetry/serialize.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CAAC,KAAqB;IAC/C,OAAO;QACL,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,SAAS,EAAE,KAAK,CAAC,kBAAkB,EAAE,SAAS;QAC9C,UAAU,EAAE,KAAK,CAAC,kBAAkB,EAAE,UAAU;QAChD,WAAW,EAAE,KAAK,CAAC,kBAAkB,EAAE,WAAW;KACnD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare const SEVERITY_CRITICAL = "critical";
|
|
2
|
+
export declare const SEVERITY_HIGH = "high";
|
|
3
|
+
export declare const SEVERITY_MEDIUM = "medium";
|
|
4
|
+
export declare const SEVERITY_LOW = "low";
|
|
5
|
+
export declare const SEVERITY_INFO = "info";
|
|
6
|
+
export declare const SEVERITY_ORDER: string[];
|
|
7
|
+
export interface ToolInvocation {
|
|
8
|
+
tool_name: string;
|
|
9
|
+
tool_input: Record<string, unknown>;
|
|
10
|
+
tool_use_id?: string | null;
|
|
11
|
+
session_id?: string | null;
|
|
12
|
+
cwd?: string | null;
|
|
13
|
+
hook_event_name?: string | null;
|
|
14
|
+
model?: string | null;
|
|
15
|
+
agent_message?: string | null;
|
|
16
|
+
user_prompt?: string | null;
|
|
17
|
+
raw_event?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
export interface TelemetryEvent {
|
|
20
|
+
timestamp: string;
|
|
21
|
+
agent_identity: string;
|
|
22
|
+
event_type: string;
|
|
23
|
+
session_id?: string | null;
|
|
24
|
+
tool_use_id?: string | null;
|
|
25
|
+
hook_event_name?: string | null;
|
|
26
|
+
working_directory?: string | null;
|
|
27
|
+
tool_call_metadata: {
|
|
28
|
+
tool_name: string;
|
|
29
|
+
tool_input?: Record<string, unknown>;
|
|
30
|
+
user_prompt?: string | null;
|
|
31
|
+
raw_event?: Record<string, unknown>;
|
|
32
|
+
hook_hash?: string | null;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/types.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAC5C,eAAO,MAAM,aAAa,SAAS,CAAC;AACpC,eAAO,MAAM,eAAe,WAAW,CAAC;AACxC,eAAO,MAAM,YAAY,QAAQ,CAAC;AAClC,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC,eAAO,MAAM,cAAc,UAM1B,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IAEnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC,kBAAkB,EAAE;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,CAAC;CACH"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Severity levels
|
|
2
|
+
export const SEVERITY_CRITICAL = "critical";
|
|
3
|
+
export const SEVERITY_HIGH = "high";
|
|
4
|
+
export const SEVERITY_MEDIUM = "medium";
|
|
5
|
+
export const SEVERITY_LOW = "low";
|
|
6
|
+
export const SEVERITY_INFO = "info";
|
|
7
|
+
export const SEVERITY_ORDER = [
|
|
8
|
+
SEVERITY_CRITICAL,
|
|
9
|
+
SEVERITY_HIGH,
|
|
10
|
+
SEVERITY_MEDIUM,
|
|
11
|
+
SEVERITY_LOW,
|
|
12
|
+
SEVERITY_INFO,
|
|
13
|
+
];
|
|
14
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/telemetry/types.ts"],"names":[],"mappings":"AAAA,kBAAkB;AAClB,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAC5C,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC;AACpC,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC;AACxC,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC;AAClC,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC;AAEpC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,iBAAiB;IACjB,aAAa;IACb,eAAe;IACf,YAAY;IACZ,aAAa;CACd,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-call metadata keys owned by the Django ingest layer (`enrich_tool_call_metadata`).
|
|
3
|
+
* Keep in sync with the keys popped at the start of ``enrich_tool_call_metadata``.
|
|
4
|
+
* The sensor sends raw hook fields only; strip these before HTTP so spoofed values
|
|
5
|
+
* cannot influence the API.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SERVER_OWNED_TOOL_CALL_METADATA_KEYS: readonly ["user_profile", "hardware_uuid", "action_type", "command_components", "file_path", "pattern", "mcp_server", "mcp_tool"];
|
|
8
|
+
/** Return a shallow copy of metadata with server-owned keys removed. */
|
|
9
|
+
export declare function cloneToolCallMetadataForWire(meta: unknown): Record<string, unknown> | undefined;
|
|
10
|
+
//# sourceMappingURL=wire-metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wire-metadata.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/wire-metadata.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,oCAAoC,mIASvC,CAAC;AAEX,wEAAwE;AACxE,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAS/F"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-call metadata keys owned by the Django ingest layer (`enrich_tool_call_metadata`).
|
|
3
|
+
* Keep in sync with the keys popped at the start of ``enrich_tool_call_metadata``.
|
|
4
|
+
* The sensor sends raw hook fields only; strip these before HTTP so spoofed values
|
|
5
|
+
* cannot influence the API.
|
|
6
|
+
*/
|
|
7
|
+
export const SERVER_OWNED_TOOL_CALL_METADATA_KEYS = [
|
|
8
|
+
"user_profile",
|
|
9
|
+
"hardware_uuid",
|
|
10
|
+
"action_type",
|
|
11
|
+
"command_components",
|
|
12
|
+
"file_path",
|
|
13
|
+
"pattern",
|
|
14
|
+
"mcp_server",
|
|
15
|
+
"mcp_tool",
|
|
16
|
+
];
|
|
17
|
+
/** Return a shallow copy of metadata with server-owned keys removed. */
|
|
18
|
+
export function cloneToolCallMetadataForWire(meta) {
|
|
19
|
+
if (!meta || typeof meta !== "object" || Array.isArray(meta)) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const m = { ...meta };
|
|
23
|
+
for (const k of SERVER_OWNED_TOOL_CALL_METADATA_KEYS) {
|
|
24
|
+
delete m[k];
|
|
25
|
+
}
|
|
26
|
+
return m;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=wire-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wire-metadata.js","sourceRoot":"","sources":["../../../src/lib/telemetry/wire-metadata.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG;IAClD,cAAc;IACd,eAAe;IACf,aAAa;IACb,oBAAoB;IACpB,WAAW;IACX,SAAS;IACT,YAAY;IACZ,UAAU;CACF,CAAC;AAEX,wEAAwE;AACxE,MAAM,UAAU,4BAA4B,CAAC,IAAa;IACxD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7D,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,CAAC,GAAG,EAAE,GAAI,IAAgC,EAAE,CAAC;IACnD,KAAK,MAAM,CAAC,IAAI,oCAAoC,EAAE,CAAC;QACrD,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/lib/telemetry.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/lib/telemetry.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tofu shim — centralises all imports from @optimuslabs/tofu.
|
|
3
|
+
*
|
|
4
|
+
* Reads ~/.optimuslabs/management/optimus_dev.env at startup:
|
|
5
|
+
* - No file / unreadable → production (ignores OPTIMUS_ENVIRONMENT).
|
|
6
|
+
* - File present → environment= line in file, then OPTIMUS_ENVIRONMENT, then production.
|
|
7
|
+
* - environment=development → loads local dist (file-relative path)
|
|
8
|
+
* - anything else → loads the published npm package
|
|
9
|
+
*
|
|
10
|
+
* All other source files import from this module, never directly from
|
|
11
|
+
* "@optimuslabs/tofu", so the conditional lives in exactly one place.
|
|
12
|
+
*/
|
|
13
|
+
import type * as TofuTypes from "@optimuslabs/tofu";
|
|
14
|
+
export declare const loadEndpointBase: typeof TofuTypes.loadEndpointBase, buildStartupEndpointUrl: typeof TofuTypes.buildStartupEndpointUrl, createSignature: typeof TofuTypes.createSignature, persistAuthKey: typeof TofuTypes.persistAuthKey, readStoredAuthKey: typeof TofuTypes.readStoredAuthKey, ensureAuthentication: typeof TofuTypes.ensureAuthentication, getEndpointSource: typeof TofuTypes.getEndpointSource, canonicalizePayload: typeof TofuTypes.canonicalizePayload, getAuthKeyPath: typeof TofuTypes.getAuthKeyPath;
|
|
15
|
+
export type { EndpointResponse, StoredAuthKey } from "@optimuslabs/tofu";
|
|
16
|
+
//# sourceMappingURL=tofu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tofu.d.ts","sourceRoot":"","sources":["../../src/lib/tofu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAiCpD,eAAO,MACL,gBAAgB,qCAChB,uBAAuB,4CACvB,eAAe,oCACf,cAAc,mCACd,iBAAiB,sCACjB,oBAAoB,yCACpB,iBAAiB,sCACjB,mBAAmB,wCACnB,cAAc,iCACR,CAAC;AAET,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/lib/tofu.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tofu shim — centralises all imports from @optimuslabs/tofu.
|
|
3
|
+
*
|
|
4
|
+
* Reads ~/.optimuslabs/management/optimus_dev.env at startup:
|
|
5
|
+
* - No file / unreadable → production (ignores OPTIMUS_ENVIRONMENT).
|
|
6
|
+
* - File present → environment= line in file, then OPTIMUS_ENVIRONMENT, then production.
|
|
7
|
+
* - environment=development → loads local dist (file-relative path)
|
|
8
|
+
* - anything else → loads the published npm package
|
|
9
|
+
*
|
|
10
|
+
* All other source files import from this module, never directly from
|
|
11
|
+
* "@optimuslabs/tofu", so the conditional lives in exactly one place.
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync } from "fs";
|
|
14
|
+
import { homedir } from "os";
|
|
15
|
+
import path from "path";
|
|
16
|
+
import { fileURLToPath } from "url";
|
|
17
|
+
function readEnvironment() {
|
|
18
|
+
const envPath = path.join(homedir(), ".optimuslabs", "management", "optimus_dev.env");
|
|
19
|
+
let content;
|
|
20
|
+
try {
|
|
21
|
+
content = readFileSync(envPath, "utf8");
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// No management file: default production (ignore stale OPTIMUS_ENVIRONMENT).
|
|
25
|
+
return "production";
|
|
26
|
+
}
|
|
27
|
+
const match = content.match(/^(?:environment|ENVIRONMENT|OPTIMUS_ENVIRONMENT)\s*=\s*(.+)/m);
|
|
28
|
+
if (match)
|
|
29
|
+
return match[1].trim().toLowerCase();
|
|
30
|
+
const fromEnv = process.env.OPTIMUS_ENVIRONMENT?.trim().toLowerCase();
|
|
31
|
+
if (fromEnv)
|
|
32
|
+
return fromEnv;
|
|
33
|
+
return "production";
|
|
34
|
+
}
|
|
35
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
36
|
+
const isDevelopment = readEnvironment() === "development";
|
|
37
|
+
// In development: resolve local optimus-tofu dist relative to this file.
|
|
38
|
+
// dist/lib/tofu.js → ../../.. → npx_packages/staging/ → optimus-tofu/dist/index.js
|
|
39
|
+
const localTofuPath = path.join(__dirname, "../../../optimus-tofu/dist/index.js");
|
|
40
|
+
const tofu = (isDevelopment
|
|
41
|
+
? await import(localTofuPath)
|
|
42
|
+
: await import("@optimuslabs/tofu"));
|
|
43
|
+
export const { loadEndpointBase, buildStartupEndpointUrl, createSignature, persistAuthKey, readStoredAuthKey, ensureAuthentication, getEndpointSource, canonicalizePayload, getAuthKeyPath, } = tofu;
|
|
44
|
+
//# sourceMappingURL=tofu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tofu.js","sourceRoot":"","sources":["../../src/lib/tofu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAGpC,SAAS,eAAe;IACtB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,CAAC,CAAC;IACtF,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,6EAA6E;QAC7E,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CACzB,8DAA8D,CAC/D,CAAC;IACF,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAChD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACtE,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,aAAa,GAAG,eAAe,EAAE,KAAK,aAAa,CAAC;AAE1D,yEAAyE;AACzE,mFAAmF;AACnF,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qCAAqC,CAAC,CAAC;AAElF,MAAM,IAAI,GAAG,CACX,aAAa;IACX,CAAC,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC;IAC7B,CAAC,CAAC,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAClB,CAAC;AAEtB,MAAM,CAAC,MAAM,EACX,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,GACf,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local `user_profile` for startup POST — same probes as `log-llm-config` `resolveUserProfile`
|
|
3
|
+
* (`design_notes/user_profile_field_sources.md`).
|
|
4
|
+
*/
|
|
5
|
+
type UserProfile = {
|
|
6
|
+
generateduuid: string;
|
|
7
|
+
machineuuid: string;
|
|
8
|
+
mac_username: string;
|
|
9
|
+
machine_name: string;
|
|
10
|
+
github_username: string;
|
|
11
|
+
claude_email: string;
|
|
12
|
+
cursor_email: string;
|
|
13
|
+
};
|
|
14
|
+
/** Same as `log-llm-config` `resolveUserProfile` (design_notes). */
|
|
15
|
+
export declare function resolveUserProfile(): UserProfile;
|
|
16
|
+
export type { UserProfile };
|
|
17
|
+
//# sourceMappingURL=user-profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-profile.d.ts","sourceRoot":"","sources":["../../src/lib/user-profile.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,KAAK,WAAW,GAAG;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAyLF,oEAAoE;AACpE,wBAAgB,kBAAkB,IAAI,WAAW,CAEhD;AAED,YAAY,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local `user_profile` for startup POST — same probes as `log-llm-config` `resolveUserProfile`
|
|
3
|
+
* (`design_notes/user_profile_field_sources.md`).
|
|
4
|
+
*/
|
|
5
|
+
import { execFileSync } from "node:child_process";
|
|
6
|
+
import crypto from "node:crypto";
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import os from "node:os";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { readCommandOutput, resolveHardwareUuid } from "./hardware-uuid.js";
|
|
11
|
+
const safeJsonParse = (raw) => {
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(raw);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const readCursorCachedEmailFromVscdb = () => {
|
|
20
|
+
const dbPath = path.join(os.homedir(), "Library/Application Support/Cursor/User/globalStorage/state.vscdb");
|
|
21
|
+
if (!fs.existsSync(dbPath))
|
|
22
|
+
return "";
|
|
23
|
+
try {
|
|
24
|
+
const out = execFileSync("sqlite3", [dbPath, "select value from ItemTable where key='cursorAuth/cachedEmail';"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return "";
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const readCursorCachedEmailFromStorageJson = () => {
|
|
32
|
+
const fp = path.join(os.homedir(), "Library/Application Support/Cursor/User/globalStorage/storage.json");
|
|
33
|
+
if (!fs.existsSync(fp))
|
|
34
|
+
return "";
|
|
35
|
+
try {
|
|
36
|
+
const parsed = safeJsonParse(fs.readFileSync(fp, { encoding: "utf8" }));
|
|
37
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
38
|
+
return "";
|
|
39
|
+
const root = parsed;
|
|
40
|
+
const cursor = root.cursor;
|
|
41
|
+
if (!cursor || typeof cursor !== "object" || Array.isArray(cursor))
|
|
42
|
+
return "";
|
|
43
|
+
const auth = cursor.auth;
|
|
44
|
+
if (!auth || typeof auth !== "object" || Array.isArray(auth))
|
|
45
|
+
return "";
|
|
46
|
+
const email = auth.email;
|
|
47
|
+
return typeof email === "string" ? email.trim() : "";
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return "";
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const readCursorCachedEmail = () => readCursorCachedEmailFromVscdb() || readCursorCachedEmailFromStorageJson();
|
|
54
|
+
const readClaudeAuthEmailFromCli = () => {
|
|
55
|
+
try {
|
|
56
|
+
const out = execFileSync("claude", ["auth", "status"], {
|
|
57
|
+
encoding: "utf8",
|
|
58
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
59
|
+
}).trim();
|
|
60
|
+
if (!out)
|
|
61
|
+
return "";
|
|
62
|
+
const parsed = safeJsonParse(out);
|
|
63
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
64
|
+
const email = parsed.email;
|
|
65
|
+
return typeof email === "string" ? email.trim() : "";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
71
|
+
return "";
|
|
72
|
+
};
|
|
73
|
+
const readClaudeEmailFromHomeFiles = () => {
|
|
74
|
+
const candidates = [
|
|
75
|
+
path.join(os.homedir(), ".claude/.credentials.json"),
|
|
76
|
+
path.join(os.homedir(), ".claude/.claude.json"),
|
|
77
|
+
];
|
|
78
|
+
for (const fp of candidates) {
|
|
79
|
+
if (!fs.existsSync(fp))
|
|
80
|
+
continue;
|
|
81
|
+
try {
|
|
82
|
+
const parsed = safeJsonParse(fs.readFileSync(fp, { encoding: "utf8" }));
|
|
83
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
84
|
+
continue;
|
|
85
|
+
const email = parsed.email;
|
|
86
|
+
if (typeof email === "string" && email.includes("@"))
|
|
87
|
+
return email.trim();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
/* try next */
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return "";
|
|
94
|
+
};
|
|
95
|
+
const readClaudeAuthEmail = () => readClaudeAuthEmailFromCli().trim() || readClaudeEmailFromHomeFiles();
|
|
96
|
+
const readMachineName = () => {
|
|
97
|
+
const fromEnv = process.env.OPTIMUS_MACHINE_NAME?.trim();
|
|
98
|
+
if (fromEnv)
|
|
99
|
+
return fromEnv;
|
|
100
|
+
if (process.platform === "darwin") {
|
|
101
|
+
const name = readCommandOutput("scutil --get ComputerName");
|
|
102
|
+
if (name)
|
|
103
|
+
return name;
|
|
104
|
+
}
|
|
105
|
+
return os.hostname();
|
|
106
|
+
};
|
|
107
|
+
const readMacUsername = () => {
|
|
108
|
+
const fromEnv = process.env.OPTIMUS_MAC_USERNAME?.trim() ||
|
|
109
|
+
process.env.USER?.trim() ||
|
|
110
|
+
process.env.LOGNAME?.trim() ||
|
|
111
|
+
"";
|
|
112
|
+
if (fromEnv)
|
|
113
|
+
return fromEnv;
|
|
114
|
+
return readCommandOutput("id -un");
|
|
115
|
+
};
|
|
116
|
+
const readGithubUsername = () => {
|
|
117
|
+
try {
|
|
118
|
+
const out = execFileSync("gh", ["api", "user", "--jq", ".login"], {
|
|
119
|
+
encoding: "utf8",
|
|
120
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
121
|
+
maxBuffer: 1024 * 1024,
|
|
122
|
+
// CI often has `gh` installed; without a cap it can block on auth/network and hang callers.
|
|
123
|
+
timeout: 3500,
|
|
124
|
+
}).trim();
|
|
125
|
+
if (out)
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
/* gh missing or not authenticated */
|
|
130
|
+
}
|
|
131
|
+
return (process.env.GITHUB_USER?.trim() ||
|
|
132
|
+
process.env.GH_USER?.trim() ||
|
|
133
|
+
readCommandOutput("git config user.name"));
|
|
134
|
+
};
|
|
135
|
+
const readUserProfileFromEnvOrFile = () => {
|
|
136
|
+
const inline = process.env.OPTIMUS_USER_PROFILE_JSON?.trim();
|
|
137
|
+
if (inline) {
|
|
138
|
+
const parsed = safeJsonParse(inline);
|
|
139
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
140
|
+
return parsed;
|
|
141
|
+
}
|
|
142
|
+
const filePath = process.env.OPTIMUS_USER_PROFILE_FILE?.trim();
|
|
143
|
+
if (filePath && fs.existsSync(filePath)) {
|
|
144
|
+
const parsed = safeJsonParse(fs.readFileSync(filePath, { encoding: "utf8" }));
|
|
145
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
146
|
+
return parsed;
|
|
147
|
+
}
|
|
148
|
+
return null;
|
|
149
|
+
};
|
|
150
|
+
const isPlausibleUuid = (s) => /^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/i.test(s.trim());
|
|
151
|
+
const readMacAccountGeneratedUid = () => {
|
|
152
|
+
const env = process.env.OPTIMUS_MAC_GENERATED_UID?.trim();
|
|
153
|
+
if (env && isPlausibleUuid(env))
|
|
154
|
+
return env.trim().toLowerCase();
|
|
155
|
+
if (process.platform !== "darwin")
|
|
156
|
+
return "";
|
|
157
|
+
const user = readMacUsername();
|
|
158
|
+
if (!user || !/^[a-zA-Z0-9._-]+$/.test(user))
|
|
159
|
+
return "";
|
|
160
|
+
try {
|
|
161
|
+
const out = execFileSync("dscl", [".", "-read", `/Users/${user}`, "GeneratedUID"], {
|
|
162
|
+
encoding: "utf8",
|
|
163
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
164
|
+
});
|
|
165
|
+
const m = out.match(/GeneratedUID:\s*([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12})/);
|
|
166
|
+
if (m?.[1] && isPlausibleUuid(m[1]))
|
|
167
|
+
return m[1].toLowerCase();
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return "";
|
|
171
|
+
}
|
|
172
|
+
return "";
|
|
173
|
+
};
|
|
174
|
+
const buildDefaultUserProfile = () => ({
|
|
175
|
+
generateduuid: readMacAccountGeneratedUid() || crypto.randomUUID(),
|
|
176
|
+
machineuuid: resolveHardwareUuid(),
|
|
177
|
+
mac_username: readMacUsername(),
|
|
178
|
+
machine_name: readMachineName(),
|
|
179
|
+
github_username: readGithubUsername(),
|
|
180
|
+
claude_email: readClaudeAuthEmail(),
|
|
181
|
+
cursor_email: readCursorCachedEmail(),
|
|
182
|
+
});
|
|
183
|
+
/** Same as `log-llm-config` `resolveUserProfile` (design_notes). */
|
|
184
|
+
export function resolveUserProfile() {
|
|
185
|
+
return readUserProfileFromEnvOrFile() ?? buildDefaultUserProfile();
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=user-profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-profile.js","sourceRoot":"","sources":["../../src/lib/user-profile.ts"],"names":[],"mappings":"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"}
|