log-llm-config 1.3.15 → 1.3.17
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.
|
@@ -100,12 +100,16 @@ export function readVscdbItemTableJson(dbPath, itemKey) {
|
|
|
100
100
|
return { [itemKey]: parsed };
|
|
101
101
|
}
|
|
102
102
|
// Bare JSON primitives. Scalar toggles must be wrapped so getByPath(key.field) works in compliance checks.
|
|
103
|
+
// Match coerceScalarForItemTableField in remediation_sync: Cursor may store toggles as JSON 0/1, not only booleans.
|
|
103
104
|
if (typeof parsed === 'boolean' || typeof parsed === 'number' || typeof parsed === 'string') {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (
|
|
105
|
+
const field = CURSOR_SCALAR_ITEMTABLE_FIELDS[itemKey];
|
|
106
|
+
if (field) {
|
|
107
|
+
if (typeof parsed === 'boolean') {
|
|
107
108
|
return { [itemKey]: { [field]: parsed } };
|
|
108
109
|
}
|
|
110
|
+
if (typeof parsed === 'number' && !Number.isNaN(parsed)) {
|
|
111
|
+
return { [itemKey]: { [field]: parsed !== 0 } };
|
|
112
|
+
}
|
|
109
113
|
}
|
|
110
114
|
return { [itemKey]: parsed };
|
|
111
115
|
}
|
|
@@ -334,26 +334,31 @@ function assertSafeSqliteIdentifiersForItemTable(table, keyColumn, valueColumn)
|
|
|
334
334
|
complianceRunnerDiag('sqlite_update: rejected unsafe SQL identifier(s)');
|
|
335
335
|
return false;
|
|
336
336
|
}
|
|
337
|
+
/**
|
|
338
|
+
* Canonical Cursor restart_command strings — single source for buildDeferredCursorRestartCommand + allowlist.
|
|
339
|
+
*
|
|
340
|
+
* - **SQLite / state.vscdb (deferred):** autofix queued ItemTable writes; restart runs `apply_deferred_vscdb` then reopens Cursor.
|
|
341
|
+
* - **JSON settings files:** autofix wrote normal config JSON; restart is kill + reopen only (no deferred apply).
|
|
342
|
+
*
|
|
343
|
+
* Exact-match only: `spawn('sh', ['-c', cmd])` runs the whole string; substring checks would allow
|
|
344
|
+
* appending `; arbitrary shell` after a trusted prefix.
|
|
345
|
+
*/
|
|
346
|
+
const TRUSTED_CURSOR_SQLITE_DEFERRED_RESTART_COMMAND = 'REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) && export REPO_ROOT CURSOR_PROJECT="$REPO_ROOT" && ' +
|
|
347
|
+
"nohup bash -c 'sleep 2; if [ -f \"$REPO_ROOT/npx_packages/log-llm-config/dist/apply_deferred_vscdb.js\" ]; then node \"$REPO_ROOT/npx_packages/log-llm-config/dist/apply_deferred_vscdb.js\"; else npx --yes -p log-llm-config apply-deferred-vscdb; fi || true; open -a Cursor \"$CURSOR_PROJECT\"' >/dev/null 2>&1 & killall -9 Cursor";
|
|
348
|
+
const TRUSTED_CURSOR_JSON_SETTINGS_RESTART_COMMAND = 'CURSOR_PROJECT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) && export CURSOR_PROJECT && nohup bash -c \'sleep 2 && open -a Cursor "$CURSOR_PROJECT"\' >/dev/null 2>&1 & killall -9 Cursor';
|
|
349
|
+
const TRUSTED_CLAUDE_RESTART_COMMAND = "nohup bash -c 'sleep 2 && open -a Claude' >/dev/null 2>&1 & pkill -x 'Claude'";
|
|
337
350
|
/**
|
|
338
351
|
* Autofix restart_command allowlist: manifest strings are attacker-controlled if JSON is tampered.
|
|
339
|
-
*
|
|
352
|
+
* SQLite-deferred Cursor path always uses {@link buildDeferredCursorRestartCommand}; manifests may still
|
|
353
|
+
* embed the JSON-settings-only Cursor template when `restart_required` applies to file-based autofix.
|
|
340
354
|
*/
|
|
341
355
|
export function isTrustedRestartCommandForAutofix(cmd) {
|
|
342
356
|
const t = cmd.trim();
|
|
343
357
|
if (!t)
|
|
344
358
|
return false;
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
const deferred = t.startsWith(deferredPrefix) &&
|
|
349
|
-
(t.includes('apply_deferred_vscdb') || t.includes('apply-deferred-vscdb')) &&
|
|
350
|
-
t.includes('killall -9 Cursor') &&
|
|
351
|
-
t.includes('open -a Cursor');
|
|
352
|
-
const legacyCursor = t.startsWith(legacyCursorPrefix) &&
|
|
353
|
-
t.includes(legacyCursorSnippet) &&
|
|
354
|
-
t.includes('killall -9 Cursor');
|
|
355
|
-
const claude = t.startsWith("nohup bash -c 'sleep 2 && open -a Claude'") && t.includes("pkill -x 'Claude'");
|
|
356
|
-
return deferred || legacyCursor || claude;
|
|
359
|
+
return (t === TRUSTED_CURSOR_SQLITE_DEFERRED_RESTART_COMMAND ||
|
|
360
|
+
t === TRUSTED_CURSOR_JSON_SETTINGS_RESTART_COMMAND ||
|
|
361
|
+
t === TRUSTED_CLAUDE_RESTART_COMMAND);
|
|
357
362
|
}
|
|
358
363
|
/** Legacy Cursor: dedicated ItemTable row `composerState`. Current Cursor: nested under reactive `applicationUser` blob. */
|
|
359
364
|
function cursorVscdbHasUsableComposerStateRow(dbPath, sqliteOp) {
|
|
@@ -711,17 +716,16 @@ export async function applyDeferredVscdbFromDisk() {
|
|
|
711
716
|
}
|
|
712
717
|
}
|
|
713
718
|
/**
|
|
714
|
-
* macOS Cursor:
|
|
719
|
+
* macOS Cursor: after deferred **SQLite / state.vscdb** autofix — apply queued writes, SIGKILL, reopen project.
|
|
715
720
|
*
|
|
716
|
-
* When
|
|
717
|
-
*
|
|
718
|
-
*
|
|
721
|
+
* When autofix used the deferred vscdb path, `applyAutofixViolations` replaces any manifest `restart_command`
|
|
722
|
+
* with this string (see compliance_check.ts). For **JSON settings-file** remediations only, the trusted template
|
|
723
|
+
* is the JSON-settings-only Cursor template (kill + reopen, no `apply_deferred_vscdb`).
|
|
719
724
|
*/
|
|
720
725
|
export function buildDeferredCursorRestartCommand() {
|
|
721
726
|
// Prefer monorepo path when hooks run from optimus-secure-fdn; otherwise `npx -p log-llm-config apply-deferred-vscdb`
|
|
722
727
|
// (package bin) so published installs work without a local npx_packages copy.
|
|
723
|
-
return
|
|
724
|
-
"nohup bash -c 'sleep 2; if [ -f \"$REPO_ROOT/npx_packages/log-llm-config/dist/apply_deferred_vscdb.js\" ]; then node \"$REPO_ROOT/npx_packages/log-llm-config/dist/apply_deferred_vscdb.js\"; else npx --yes -p log-llm-config apply-deferred-vscdb; fi || true; open -a Cursor \"$CURSOR_PROJECT\"' >/dev/null 2>&1 & killall -9 Cursor");
|
|
728
|
+
return TRUSTED_CURSOR_SQLITE_DEFERRED_RESTART_COMMAND;
|
|
725
729
|
}
|
|
726
730
|
function sqliteRowGroupKey(dbPath, op) {
|
|
727
731
|
return `${dbPath}|${op.table}|${op.key_column}|${op.value_column}|${op.target_key}`;
|