log-llm-config 1.3.72 → 1.3.75

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,29 @@ 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
+ /** Policy name(s) for preventive enforcement dialog copy. */
96
+ function uniquePolicyLabelsFromViolations(appliedViolations) {
97
+ const policyNames = [
98
+ ...new Set(appliedViolations
99
+ .map((v) => v.policy_name?.trim() || v.finding_title?.trim() || '')
100
+ .filter(Boolean)),
101
+ ];
102
+ return policyNames.length > 0 ? policyNames.join('\n\n') : 'Agent security policy';
103
+ }
104
+ function formatPreventiveAutofixDialog(appliedViolations, applyLine) {
105
+ return ('Optimus Labs enforced a preventive agent security policy as determined by your security team:\n\n' +
106
+ `${uniquePolicyLabelsFromViolations(appliedViolations)}\n\n` +
107
+ `${applyLine}\n\n` +
108
+ 'Click OK to continue');
109
+ }
110
+ /** Claude dialog after enforced/preventive remediation is applied locally. */
111
+ export function formatClaudeAutofixDialog(appliedViolations) {
112
+ return formatPreventiveAutofixDialog(appliedViolations, 'Claude will now apply this policy to your environment.');
113
+ }
114
+ /** Cursor restart dialog after enforced/preventive remediation is applied locally. */
115
+ export function formatCursorRestartAutofixDialog(appliedViolations) {
116
+ return formatPreventiveAutofixDialog(appliedViolations, 'Cursor will now restart to apply this policy, and your context will be retained.');
117
+ }
93
118
  /**
94
119
  * Upload a secondary compliance file to the backend so the server can resolve the finding.
95
120
  * Fire-and-forget: upload runs in background; any failure is logged but does not block the gate.
@@ -135,6 +160,24 @@ export async function runCompliancePromptGate() {
135
160
  const ide = parseIde();
136
161
  const agent = parseAgent(ide);
137
162
  hookLogSessionBanner('compliance_prompt_gate (before submit)');
163
+ // Sync before checking so server-side changes (enforce/unenforce) propagate on every prompt
164
+ // without waiting for the background runner. Race against a 3 s timeout so a slow or
165
+ // unavailable server never delays the gate significantly.
166
+ const hw = tryResolveHardwareUuid();
167
+ if (hw) {
168
+ const { remediations } = readRemediationInstructionsFile();
169
+ if (Array.isArray(remediations) && remediations.length > 0) {
170
+ try {
171
+ await Promise.race([
172
+ syncRemediations(loadEndpointBase(), hw),
173
+ new Promise((resolve) => setTimeout(resolve, 3000)),
174
+ ]);
175
+ }
176
+ catch {
177
+ // Network or auth failure — fall back to local file state.
178
+ }
179
+ }
180
+ }
138
181
  const status = runLocalRemediationComplianceCheck(agent);
139
182
  // Secondary-satisfied: primary checks failed but settings.json (or equiv) has the fix.
140
183
  // Upload those files fire-and-forget so the backend can resolve the finding immediately.
@@ -188,10 +231,13 @@ export async function runCompliancePromptGate() {
188
231
  hookRunLog('compliance_prompt_gate: Claude — autofix wrote JSON; recheck still flags same UUID(s) — proceeding (immediate apply)');
189
232
  }
190
233
  if (deferredSqlitePending || recheckOk || claudeRecheckStaleAfterImmediateApply) {
191
- const violationLabel = fixed === 1 ? 'policy violation' : 'policy violations';
192
- const autofixMessage = `Optimus Labs auto-fixed ${fixed} ${violationLabel}:\n\n${appliedViolations
193
- .map((v) => autofixDialogLine(v))
194
- .join('\n')}`;
234
+ const autofixMessage = ide === 'cursor' && restartCommands.length > 0
235
+ ? formatCursorRestartAutofixDialog(appliedViolations)
236
+ : ide === 'claude'
237
+ ? formatClaudeAutofixDialog(appliedViolations)
238
+ : `Optimus Labs auto-fixed ${fixed} ${fixed === 1 ? 'policy violation' : 'policy violations'}:\n\n${appliedViolations
239
+ .map((v) => autofixDialogLine(v))
240
+ .join('\n')}`;
195
241
  const payload = { __optimus_autofix: true, autofix_message: autofixMessage };
196
242
  if (restartCommands.length > 0)
197
243
  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 || '',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "log-llm-config",
3
- "version": "1.3.72",
3
+ "version": "1.3.75",
4
4
  "description": "CLI helpers for logging hardware UUIDs and posting startup payloads to Optimus Security.",
5
5
  "type": "module",
6
6
  "bin": {