log-llm-config 1.3.77 → 1.3.79
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/cli.js
CHANGED
|
@@ -93,8 +93,10 @@ function parseAndSetLogUuidEnvVars() {
|
|
|
93
93
|
process.env.OPTIMUS_HARDWARE_UUID = uuidArg;
|
|
94
94
|
if (userArg)
|
|
95
95
|
process.env.GITHUB_USER = userArg;
|
|
96
|
-
if (repoArg)
|
|
96
|
+
if (repoArg) {
|
|
97
|
+
process.env.OPTIMUS_WORKSPACE_REPO = repoArg;
|
|
97
98
|
process.env.GITHUB_REPOSITORY = repoArg;
|
|
99
|
+
}
|
|
98
100
|
if (branchArg)
|
|
99
101
|
process.env.GITHUB_REF_NAME = branchArg;
|
|
100
102
|
if (agentArg)
|
|
@@ -16,8 +16,9 @@ import { collectWorkspaceVscdbs } from '../collection/mcp_tool_collector.js';
|
|
|
16
16
|
import { normalizePathSkipPrefixes } from '../paths/pattern_resolver.js';
|
|
17
17
|
import { sendConfigFile, sendConfigFilesBatch, sendHookRequestCreate, sendHookRequestUpdateManifest, sendIngestSessionStart, sendIngestSessionFinish, BATCH_CHUNK_SIZE } from '../sender/batch_sender.js';
|
|
18
18
|
import { canonicalCursorUserStateVscdbPath } from './remediation_config_path.js';
|
|
19
|
+
import { ensureWorkspaceRepoEnv, resolveProjectRoot } from './workspace_repo.js';
|
|
19
20
|
import { createSignature, canonicalizePayload } from '../sender/signing.js';
|
|
20
|
-
const PROJECT_ROOT =
|
|
21
|
+
const PROJECT_ROOT = resolveProjectRoot();
|
|
21
22
|
async function collectAllConfigFiles(endpointBase) {
|
|
22
23
|
const patternsUrl = `${endpointBase.replace(/\/+$/, '')}${FILE_PATH_REGISTRY_FILE_PATTERNS_PATH}`;
|
|
23
24
|
hookRunLog(`fetching patterns from ${patternsUrl}`);
|
|
@@ -84,8 +85,8 @@ async function addSensitivePathsAudit(endpointBase, configFiles) {
|
|
|
84
85
|
async function sendAllConfigFiles(configFiles, hardwareUuid, authKey) {
|
|
85
86
|
const hookTypeRaw = (process.env.OPTIMUS_HOOK_TYPE || 'claude').toLowerCase();
|
|
86
87
|
const hookType = hookTypeRaw === 'cursor' ? 'cursor' : 'claude';
|
|
87
|
-
const workspaceRepo = process.env.OPTIMUS_WORKSPACE_REPO || process.env.GITHUB_REPOSITORY || '';
|
|
88
88
|
const manifest = configFiles.map((c) => canonicalCursorUserStateVscdbPath(c.file_path));
|
|
89
|
+
const workspaceRepo = ensureWorkspaceRepoEnv(manifest);
|
|
89
90
|
const hookRequestId = await sendHookRequestCreate(hardwareUuid, authKey, hookType, workspaceRepo);
|
|
90
91
|
hookRunLog(`hook-request id=${hookRequestId ?? 'none'}`);
|
|
91
92
|
const ingestSessionId = await sendIngestSessionStart(hardwareUuid, authKey);
|
|
@@ -118,7 +119,7 @@ async function main() {
|
|
|
118
119
|
const endpointBase = loadEndpointBase();
|
|
119
120
|
hookRunLog(`start endpoint=${endpointBase} hardware_uuid=${hardwareUuid}`);
|
|
120
121
|
hookRunLog(`endpoint_source=${getEndpointSource()} cwd=${process.cwd()}`);
|
|
121
|
-
hookRunLog(`env: OPTIMUS_HOOK_TYPE=${process.env.OPTIMUS_HOOK_TYPE ? 'set' : 'unset'}
|
|
122
|
+
hookRunLog(`env: OPTIMUS_HOOK_TYPE=${process.env.OPTIMUS_HOOK_TYPE ? 'set' : 'unset'} OPTIMUS_PROJECT_DIR=${process.env.OPTIMUS_PROJECT_DIR ? 'set' : 'unset'} OPTIMUS_WORKSPACE_REPO=${process.env.OPTIMUS_WORKSPACE_REPO ? 'set' : 'unset'} OPTIMUS_ENDPOINT=${process.env.OPTIMUS_ENDPOINT ? 'set' : 'unset'}`);
|
|
122
123
|
let authKey;
|
|
123
124
|
try {
|
|
124
125
|
authKey = await ensureAuthentication(hardwareUuid);
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { hookRunLog } from './hook_logger.js';
|
|
6
|
+
const GIT_TIMEOUT_MS = 3000;
|
|
7
|
+
const MAX_WALK_UP = 25;
|
|
8
|
+
function gitRemoteInDir(dir) {
|
|
9
|
+
try {
|
|
10
|
+
return execFileSync('git', ['remote', '-v'], {
|
|
11
|
+
cwd: dir,
|
|
12
|
+
timeout: GIT_TIMEOUT_MS,
|
|
13
|
+
encoding: 'utf8',
|
|
14
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
15
|
+
}).trim();
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function gitToplevelFromDir(dir) {
|
|
22
|
+
try {
|
|
23
|
+
return execFileSync('git', ['rev-parse', '--show-toplevel'], {
|
|
24
|
+
cwd: dir,
|
|
25
|
+
timeout: GIT_TIMEOUT_MS,
|
|
26
|
+
encoding: 'utf8',
|
|
27
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
28
|
+
}).trim();
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function resolveProjectDirFromEnv() {
|
|
35
|
+
for (const candidate of [
|
|
36
|
+
process.env.OPTIMUS_PROJECT_DIR,
|
|
37
|
+
process.env.CLAUDE_PROJECT_DIR,
|
|
38
|
+
process.env.CURSOR_PROJECT_DIR,
|
|
39
|
+
]) {
|
|
40
|
+
const dir = (candidate || '').trim();
|
|
41
|
+
if (dir && fs.existsSync(dir))
|
|
42
|
+
return dir;
|
|
43
|
+
}
|
|
44
|
+
return '';
|
|
45
|
+
}
|
|
46
|
+
export function resolveWorkspaceRepoFromEnv() {
|
|
47
|
+
for (const candidate of [
|
|
48
|
+
process.env.OPTIMUS_WORKSPACE_REPO,
|
|
49
|
+
process.env.GITHUB_REPOSITORY,
|
|
50
|
+
process.env.GH_REPOSITORY,
|
|
51
|
+
]) {
|
|
52
|
+
const value = (candidate || '').trim();
|
|
53
|
+
if (value)
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
return '';
|
|
57
|
+
}
|
|
58
|
+
function expandManifestPath(filePath) {
|
|
59
|
+
const trimmed = (filePath || '').trim();
|
|
60
|
+
if (!trimmed)
|
|
61
|
+
return '';
|
|
62
|
+
if (trimmed.startsWith('/'))
|
|
63
|
+
return trimmed;
|
|
64
|
+
if (/^Users-[^/]+/.test(trimmed)) {
|
|
65
|
+
return path.join(os.homedir(), '.cursor', 'projects', trimmed);
|
|
66
|
+
}
|
|
67
|
+
return path.resolve(trimmed);
|
|
68
|
+
}
|
|
69
|
+
export function resolveRepoFromPath(filePath) {
|
|
70
|
+
const remote = gitRemoteFromPathWalk(filePath);
|
|
71
|
+
return remote || resolveWorkspaceRepoFromEnv();
|
|
72
|
+
}
|
|
73
|
+
function gitRemoteFromPathWalk(filePath) {
|
|
74
|
+
let dir = expandManifestPath(filePath);
|
|
75
|
+
if (!dir)
|
|
76
|
+
return '';
|
|
77
|
+
try {
|
|
78
|
+
if (fs.existsSync(dir) && fs.statSync(dir).isFile())
|
|
79
|
+
dir = path.dirname(dir);
|
|
80
|
+
else if (!fs.existsSync(dir))
|
|
81
|
+
dir = path.dirname(dir);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
dir = path.dirname(dir);
|
|
85
|
+
}
|
|
86
|
+
for (let i = 0; i < MAX_WALK_UP; i++) {
|
|
87
|
+
const remote = gitRemoteInDir(dir);
|
|
88
|
+
if (remote)
|
|
89
|
+
return remote;
|
|
90
|
+
const parent = path.dirname(dir);
|
|
91
|
+
if (parent === dir)
|
|
92
|
+
break;
|
|
93
|
+
dir = parent;
|
|
94
|
+
}
|
|
95
|
+
return '';
|
|
96
|
+
}
|
|
97
|
+
function manifestPathPriority(filePath) {
|
|
98
|
+
if (filePath.startsWith('/Users/') || filePath.startsWith('/home/'))
|
|
99
|
+
return 0;
|
|
100
|
+
if (filePath.startsWith('/'))
|
|
101
|
+
return 1;
|
|
102
|
+
if (/^Users-[^/]+/.test(filePath))
|
|
103
|
+
return 2;
|
|
104
|
+
return 3;
|
|
105
|
+
}
|
|
106
|
+
export function resolveWorkspaceRepoFromManifest(manifest) {
|
|
107
|
+
if (!manifest.length)
|
|
108
|
+
return '';
|
|
109
|
+
const candidates = [...manifest]
|
|
110
|
+
.map((entry) => (entry || '').trim())
|
|
111
|
+
.filter(Boolean)
|
|
112
|
+
.sort((a, b) => manifestPathPriority(a) - manifestPathPriority(b));
|
|
113
|
+
for (const candidate of candidates) {
|
|
114
|
+
const remote = resolveRepoFromPath(candidate);
|
|
115
|
+
if (remote)
|
|
116
|
+
return remote;
|
|
117
|
+
}
|
|
118
|
+
return '';
|
|
119
|
+
}
|
|
120
|
+
export function resolveWorkspaceRepo(manifest) {
|
|
121
|
+
const fromEnv = resolveWorkspaceRepoFromEnv();
|
|
122
|
+
if (fromEnv) {
|
|
123
|
+
hookRunLog(`workspace_repo: env (${fromEnv.slice(0, 80)}${fromEnv.length > 80 ? '…' : ''})`);
|
|
124
|
+
return fromEnv;
|
|
125
|
+
}
|
|
126
|
+
const projectDir = resolveProjectDirFromEnv();
|
|
127
|
+
if (projectDir) {
|
|
128
|
+
const remote = gitRemoteInDir(projectDir);
|
|
129
|
+
if (remote) {
|
|
130
|
+
hookRunLog(`workspace_repo: project_dir (${projectDir})`);
|
|
131
|
+
return remote;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const cwdRemote = gitRemoteInDir(process.cwd());
|
|
135
|
+
if (cwdRemote) {
|
|
136
|
+
hookRunLog(`workspace_repo: cwd (${process.cwd()})`);
|
|
137
|
+
return cwdRemote;
|
|
138
|
+
}
|
|
139
|
+
if (manifest?.length) {
|
|
140
|
+
const fromManifest = resolveWorkspaceRepoFromManifest(manifest);
|
|
141
|
+
if (fromManifest) {
|
|
142
|
+
hookRunLog('workspace_repo: manifest');
|
|
143
|
+
return fromManifest;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
hookRunLog(`workspace_repo: unresolved (project_dir=${projectDir || 'unset'} cwd=${process.cwd()})`);
|
|
147
|
+
return '';
|
|
148
|
+
}
|
|
149
|
+
export function resolveProjectRoot() {
|
|
150
|
+
const projectDir = resolveProjectDirFromEnv();
|
|
151
|
+
if (projectDir) {
|
|
152
|
+
const top = gitToplevelFromDir(projectDir);
|
|
153
|
+
if (top)
|
|
154
|
+
return top;
|
|
155
|
+
return projectDir;
|
|
156
|
+
}
|
|
157
|
+
const cwdTop = gitToplevelFromDir(process.cwd());
|
|
158
|
+
if (cwdTop)
|
|
159
|
+
return cwdTop;
|
|
160
|
+
return process.cwd();
|
|
161
|
+
}
|
|
162
|
+
export function ensureWorkspaceRepoEnv(manifest) {
|
|
163
|
+
const resolved = resolveWorkspaceRepo(manifest);
|
|
164
|
+
if (resolved) {
|
|
165
|
+
process.env.OPTIMUS_WORKSPACE_REPO = resolved;
|
|
166
|
+
if (!process.env.GITHUB_REPOSITORY)
|
|
167
|
+
process.env.GITHUB_REPOSITORY = resolved;
|
|
168
|
+
}
|
|
169
|
+
return resolved;
|
|
170
|
+
}
|
|
@@ -3,12 +3,14 @@ import { createSignature } from './signing.js';
|
|
|
3
3
|
import { loadEndpointBase } from './endpoint_config.js';
|
|
4
4
|
import { hookRunLog } from '../runtime/hook_logger.js';
|
|
5
5
|
import { canonicalCursorUserStateVscdbPath } from '../runtime/remediation_config_path.js';
|
|
6
|
+
import { resolveWorkspaceRepoFromEnv } from '../runtime/workspace_repo.js';
|
|
6
7
|
import fs from 'node:fs';
|
|
7
8
|
import os from 'node:os';
|
|
8
9
|
import path from 'node:path';
|
|
9
10
|
/** Chunk size per batch request. */
|
|
10
11
|
export const BATCH_CHUNK_SIZE = 20;
|
|
11
12
|
const MAX_BATCH_SIZE_BYTES = 500 * 1024; // 500KB
|
|
13
|
+
export { resolveRepoFromPath } from '../runtime/workspace_repo.js';
|
|
12
14
|
function resolveApiBase(endpoint) {
|
|
13
15
|
try {
|
|
14
16
|
return new URL(endpoint).origin;
|
|
@@ -86,7 +88,7 @@ function splitChunk(chunks, chunkIndex) {
|
|
|
86
88
|
async function sendConfigFilesBatch(configFiles, hardwareUuid, authKey, hookRequestId, ingestSessionId) {
|
|
87
89
|
const endpoint = loadEndpointBase();
|
|
88
90
|
const apiUrl = `${resolveApiBase(endpoint)}/endpoint_security/log-config-files/`;
|
|
89
|
-
const metadata = { org_identifier: process.env.GITHUB_ORG || process.env.GH_ORG || '', organization_uuid: readOrganizationUuid(), repo_identifier:
|
|
91
|
+
const metadata = { org_identifier: process.env.GITHUB_ORG || process.env.GH_ORG || '', organization_uuid: readOrganizationUuid(), repo_identifier: resolveWorkspaceRepoFromEnv() };
|
|
90
92
|
const basePayloadSize = JSON.stringify({ hardware_uuid: hardwareUuid, metadata }).length + 800;
|
|
91
93
|
const chunks = buildBatchChunks(configFiles, basePayloadSize);
|
|
92
94
|
const totals = { accepted: 0, failed: 0 };
|
|
@@ -169,13 +171,13 @@ async function sendIngestSessionFinish(hardwareUuid, authKey, ingestSessionId) {
|
|
|
169
171
|
return false;
|
|
170
172
|
}
|
|
171
173
|
}
|
|
172
|
-
async function sendConfigFile(configFile, hardwareUuid, authKey) {
|
|
174
|
+
async function sendConfigFile(configFile, hardwareUuid, authKey, repoIdentifier) {
|
|
173
175
|
const endpoint = loadEndpointBase();
|
|
174
176
|
const apiUrl = `${resolveApiBase(endpoint)}/endpoint_security/log-config-file/`;
|
|
175
177
|
const uploadPath = canonicalCursorUserStateVscdbPath(configFile.file_path);
|
|
176
178
|
const payload = { hardware_uuid: hardwareUuid, file_type: configFile.file_type, file_path: uploadPath, raw_content: configFile.raw_content };
|
|
177
179
|
const signature = createSignature(payload, authKey.key);
|
|
178
|
-
const body = { ...payload, signature, key_id: authKey.key_id || '', metadata: { org_identifier: process.env.GITHUB_ORG || process.env.GH_ORG || '', organization_uuid: readOrganizationUuid(), repo_identifier:
|
|
180
|
+
const body = { ...payload, signature, key_id: authKey.key_id || '', metadata: { org_identifier: process.env.GITHUB_ORG || process.env.GH_ORG || '', organization_uuid: readOrganizationUuid(), repo_identifier: repoIdentifier ?? resolveWorkspaceRepoFromEnv() } };
|
|
179
181
|
try {
|
|
180
182
|
const response = await postStartupPayload(apiUrl, body);
|
|
181
183
|
if (response.status !== 'accepted') {
|
|
@@ -3,6 +3,7 @@ import { classifyEndpointResponse, postStartupPayload } from '../endpoint_client
|
|
|
3
3
|
import { resolveHardwareUuid } from './hardware_uuid.js';
|
|
4
4
|
import { writeAuthKey, readStoredAuthKey, loadEndpointBase, buildStartupEndpointUrl } from './auth_key_store.js';
|
|
5
5
|
import { resolveUserProfile } from './user_profile.js';
|
|
6
|
+
import { resolveWorkspaceRepo } from '../log_config_files/runtime/workspace_repo.js';
|
|
6
7
|
import fs from 'node:fs';
|
|
7
8
|
import os from 'node:os';
|
|
8
9
|
import path from 'node:path';
|
|
@@ -51,7 +52,7 @@ const getMetadata = () => ({
|
|
|
51
52
|
github_username: process.env.GITHUB_USER || process.env.GH_USER || '',
|
|
52
53
|
org_identifier: process.env.GITHUB_ORG || '',
|
|
53
54
|
organization_uuid: readOrganizationUuid(),
|
|
54
|
-
repo_identifier:
|
|
55
|
+
repo_identifier: resolveWorkspaceRepo(),
|
|
55
56
|
branch: process.env.GITHUB_REF_NAME || process.env.BRANCH_NAME || '',
|
|
56
57
|
commit_sha: process.env.GITHUB_SHA || '',
|
|
57
58
|
agent_name: process.env.OPTIMUS_AGENT || '',
|