log-llm-config 1.3.72 → 1.3.74
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.
|
@@ -8,12 +8,14 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { applyAutofixViolations, normalizeAgentToken, pruneSatisfiedOneTimeRemediations, runLocalRemediationComplianceCheck, } from './log_config_files/runtime/compliance_check.js';
|
|
10
10
|
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
11
|
-
import { getRemediationInstructionsPath } from './log_config_files/runtime/management_storage.js';
|
|
11
|
+
import { getRemediationInstructionsPath, readRemediationInstructionsFile } from './log_config_files/runtime/management_storage.js';
|
|
12
12
|
import { hookLogSessionBanner, hookRunLog, logRemediationApplyFailure } from './log_config_files/runtime/hook_logger.js';
|
|
13
13
|
import { isThisCliModule } from './cli_invocation_match.js';
|
|
14
14
|
import { ensureAuthentication } from './log_config_files/auth/auth_flow.js';
|
|
15
15
|
import { sendConfigFile } from './log_config_files/sender/batch_sender.js';
|
|
16
16
|
import { tryResolveHardwareUuid } from './log_config_files/runtime/hardware_uuid.js';
|
|
17
|
+
import { syncRemediations } from './log_config_files/runtime/remediation_sync.js';
|
|
18
|
+
import { loadEndpointBase } from './log_config_files/sender/endpoint_config.js';
|
|
17
19
|
const MANIFEST_STALE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
18
20
|
function parseIde() {
|
|
19
21
|
const eq = process.argv.find((a) => a.startsWith('--ide='));
|
|
@@ -90,6 +92,19 @@ function autofixDialogLine(v) {
|
|
|
90
92
|
const short = d.length > 160 ? `${d.slice(0, 157)}…` : d;
|
|
91
93
|
return `• [${v.finding_formatted_id}] ${short}`;
|
|
92
94
|
}
|
|
95
|
+
/** Cursor restart dialog after enforced/preventive remediation is applied locally. */
|
|
96
|
+
export function formatCursorRestartAutofixDialog(appliedViolations) {
|
|
97
|
+
const policyNames = [
|
|
98
|
+
...new Set(appliedViolations
|
|
99
|
+
.map((v) => v.policy_name?.trim() || v.finding_title?.trim() || '')
|
|
100
|
+
.filter(Boolean)),
|
|
101
|
+
];
|
|
102
|
+
const policyLabel = policyNames.length > 0 ? policyNames.join('\n\n') : 'Agent security policy';
|
|
103
|
+
return ('Optimus Labs enforced a preventive agent security policy as determined by your security team:\n\n' +
|
|
104
|
+
`${policyLabel}\n\n` +
|
|
105
|
+
'Cursor will now restart to apply this policy, and your context will be retained.\n\n' +
|
|
106
|
+
'Click OK to continue');
|
|
107
|
+
}
|
|
93
108
|
/**
|
|
94
109
|
* Upload a secondary compliance file to the backend so the server can resolve the finding.
|
|
95
110
|
* Fire-and-forget: upload runs in background; any failure is logged but does not block the gate.
|
|
@@ -135,6 +150,24 @@ export async function runCompliancePromptGate() {
|
|
|
135
150
|
const ide = parseIde();
|
|
136
151
|
const agent = parseAgent(ide);
|
|
137
152
|
hookLogSessionBanner('compliance_prompt_gate (before submit)');
|
|
153
|
+
// Sync before checking so server-side changes (enforce/unenforce) propagate on every prompt
|
|
154
|
+
// without waiting for the background runner. Race against a 3 s timeout so a slow or
|
|
155
|
+
// unavailable server never delays the gate significantly.
|
|
156
|
+
const hw = tryResolveHardwareUuid();
|
|
157
|
+
if (hw) {
|
|
158
|
+
const { remediations } = readRemediationInstructionsFile();
|
|
159
|
+
if (Array.isArray(remediations) && remediations.length > 0) {
|
|
160
|
+
try {
|
|
161
|
+
await Promise.race([
|
|
162
|
+
syncRemediations(loadEndpointBase(), hw),
|
|
163
|
+
new Promise((resolve) => setTimeout(resolve, 3000)),
|
|
164
|
+
]);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// Network or auth failure — fall back to local file state.
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
138
171
|
const status = runLocalRemediationComplianceCheck(agent);
|
|
139
172
|
// Secondary-satisfied: primary checks failed but settings.json (or equiv) has the fix.
|
|
140
173
|
// Upload those files fire-and-forget so the backend can resolve the finding immediately.
|
|
@@ -189,9 +222,11 @@ export async function runCompliancePromptGate() {
|
|
|
189
222
|
}
|
|
190
223
|
if (deferredSqlitePending || recheckOk || claudeRecheckStaleAfterImmediateApply) {
|
|
191
224
|
const violationLabel = fixed === 1 ? 'policy violation' : 'policy violations';
|
|
192
|
-
const autofixMessage =
|
|
193
|
-
|
|
194
|
-
|
|
225
|
+
const autofixMessage = ide === 'cursor' && restartCommands.length > 0
|
|
226
|
+
? formatCursorRestartAutofixDialog(appliedViolations)
|
|
227
|
+
: `Optimus Labs auto-fixed ${fixed} ${violationLabel}:\n\n${appliedViolations
|
|
228
|
+
.map((v) => autofixDialogLine(v))
|
|
229
|
+
.join('\n')}`;
|
|
195
230
|
const payload = { __optimus_autofix: true, autofix_message: autofixMessage };
|
|
196
231
|
if (restartCommands.length > 0)
|
|
197
232
|
payload.restart_commands = restartCommands;
|
|
@@ -325,6 +325,7 @@ export function runLocalRemediationComplianceCheck(agent = 'cursor') {
|
|
|
325
325
|
description: check.description,
|
|
326
326
|
finding_title: entry.finding_title,
|
|
327
327
|
finding_description: entry.finding_description,
|
|
328
|
+
policy_name: entry.policy_name,
|
|
328
329
|
severity: compliance.severity,
|
|
329
330
|
autofix_allowed: compliance.autofix_allowed,
|
|
330
331
|
config_file_path: entry.config_file_path,
|
|
@@ -347,6 +348,7 @@ export function runLocalRemediationComplianceCheck(agent = 'cursor') {
|
|
|
347
348
|
description: check.description,
|
|
348
349
|
finding_title: entry.finding_title,
|
|
349
350
|
finding_description: entry.finding_description,
|
|
351
|
+
policy_name: entry.policy_name,
|
|
350
352
|
severity: compliance.severity,
|
|
351
353
|
autofix_allowed: compliance.autofix_allowed,
|
|
352
354
|
config_file_path: entry.config_file_path,
|
|
@@ -371,6 +373,7 @@ export function runLocalRemediationComplianceCheck(agent = 'cursor') {
|
|
|
371
373
|
description: check.description,
|
|
372
374
|
finding_title: entry.finding_title,
|
|
373
375
|
finding_description: entry.finding_description,
|
|
376
|
+
policy_name: entry.policy_name,
|
|
374
377
|
severity: compliance.severity,
|
|
375
378
|
autofix_allowed: compliance.autofix_allowed,
|
|
376
379
|
config_file_path: entry.config_file_path,
|
|
@@ -51,7 +51,7 @@ const getMetadata = () => ({
|
|
|
51
51
|
github_username: process.env.GITHUB_USER || process.env.GH_USER || '',
|
|
52
52
|
org_identifier: process.env.GITHUB_ORG || '',
|
|
53
53
|
organization_uuid: readOrganizationUuid(),
|
|
54
|
-
repo_identifier: process.env.GITHUB_REPOSITORY || '',
|
|
54
|
+
repo_identifier: process.env.OPTIMUS_WORKSPACE_REPO || process.env.GITHUB_REPOSITORY || '',
|
|
55
55
|
branch: process.env.GITHUB_REF_NAME || process.env.BRANCH_NAME || '',
|
|
56
56
|
commit_sha: process.env.GITHUB_SHA || '',
|
|
57
57
|
agent_name: process.env.OPTIMUS_AGENT || '',
|