log-llm-config 1.3.21 → 1.3.22
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.
|
@@ -476,25 +476,49 @@ function mergeSqliteOpIntoJson(currentJson, sqliteOp) {
|
|
|
476
476
|
const parentParts = parts.slice(0, -1);
|
|
477
477
|
let node = currentJson;
|
|
478
478
|
for (const p of parentParts) {
|
|
479
|
-
if (node == null || typeof node !== 'object')
|
|
479
|
+
if (node == null || typeof node !== 'object' || Array.isArray(node))
|
|
480
480
|
return;
|
|
481
|
-
|
|
481
|
+
const rec = node;
|
|
482
|
+
const child = rec[p];
|
|
483
|
+
if (child == null) {
|
|
484
|
+
rec[p] = {};
|
|
485
|
+
node = rec[p];
|
|
486
|
+
}
|
|
487
|
+
else if (typeof child === 'object' && !Array.isArray(child)) {
|
|
488
|
+
node = child;
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
482
493
|
}
|
|
483
494
|
if (node == null || typeof node !== 'object' || Array.isArray(node))
|
|
484
495
|
return;
|
|
485
496
|
const container = node;
|
|
486
|
-
const
|
|
487
|
-
|
|
497
|
+
const existing = container[arrayKey];
|
|
498
|
+
let arr;
|
|
499
|
+
if (Array.isArray(existing)) {
|
|
500
|
+
arr = existing;
|
|
501
|
+
}
|
|
502
|
+
else if (existing == null) {
|
|
503
|
+
arr = [];
|
|
504
|
+
container[arrayKey] = arr;
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
488
507
|
return;
|
|
508
|
+
}
|
|
489
509
|
const idx = arr.findIndex((item) => {
|
|
490
510
|
if (item === null || typeof item !== 'object')
|
|
491
511
|
return false;
|
|
492
512
|
const o = item;
|
|
493
513
|
return Object.entries(where).every(([k, v]) => o[k] === v);
|
|
494
514
|
});
|
|
495
|
-
if (idx
|
|
515
|
+
if (idx >= 0) {
|
|
516
|
+
Object.assign(arr[idx], sqliteOp.updates);
|
|
496
517
|
return;
|
|
497
|
-
|
|
518
|
+
}
|
|
519
|
+
const newItem = { ...where };
|
|
520
|
+
Object.assign(newItem, sqliteOp.updates);
|
|
521
|
+
arr.push(newItem);
|
|
498
522
|
return;
|
|
499
523
|
}
|
|
500
524
|
mergeJsonAtSqlitePath(currentJson, sqliteOp.json_path, sqliteOp.updates);
|
|
@@ -750,10 +774,17 @@ function queueDeferredSqliteOpsMerged(configPath, sqliteOps, postApplyUpload) {
|
|
|
750
774
|
const line = `sqlite_update: database not found at ${dbPath}`;
|
|
751
775
|
hookRunLog(line);
|
|
752
776
|
complianceRunnerDiag(line);
|
|
753
|
-
return
|
|
777
|
+
return {
|
|
778
|
+
ok: false,
|
|
779
|
+
reason: `state.vscdb not on disk at ${dbPath} (Cursor may not have created globalStorage yet — open Cursor once).`,
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
if (!assertSqlite3Available()) {
|
|
783
|
+
return {
|
|
784
|
+
ok: false,
|
|
785
|
+
reason: 'sqlite3 CLI not found in PATH (IDE hooks often inherit a minimal PATH; install Xcode CLT / sqlite3 or fix PATH).',
|
|
786
|
+
};
|
|
754
787
|
}
|
|
755
|
-
if (!assertSqlite3Available())
|
|
756
|
-
return false;
|
|
757
788
|
const resolvedOps = sqliteOps.map((op) => resolveCursorComposerSqliteOp(dbPath, op));
|
|
758
789
|
const groups = new Map();
|
|
759
790
|
for (const op of resolvedOps) {
|
|
@@ -771,7 +802,7 @@ function queueDeferredSqliteOpsMerged(configPath, sqliteOps, postApplyUpload) {
|
|
|
771
802
|
const line = `sqlite_update: rejected unsafe or empty target_key for deferred queue (refusing to write state.vscdb)`;
|
|
772
803
|
hookRunLog(line);
|
|
773
804
|
complianceRunnerDiag(`${line} target_key_preview=${first.target_key.slice(0, 80)}`);
|
|
774
|
-
return false;
|
|
805
|
+
return { ok: false, reason: 'unsafe or empty ItemTable target_key (see hook_log).' };
|
|
775
806
|
}
|
|
776
807
|
complianceRunnerDiag(`sqlite_update: deferred merge db=${dbPath} target_key=${first.target_key} operations=${ops.length}`);
|
|
777
808
|
let currentJson = {};
|
|
@@ -786,7 +817,10 @@ function queueDeferredSqliteOpsMerged(configPath, sqliteOps, postApplyUpload) {
|
|
|
786
817
|
const line = `sqlite_update: error querying database: ${e instanceof Error ? e.message : String(e)}`;
|
|
787
818
|
hookRunLog(line);
|
|
788
819
|
complianceRunnerDiag(line);
|
|
789
|
-
return
|
|
820
|
+
return {
|
|
821
|
+
ok: false,
|
|
822
|
+
reason: `sqlite read/parse failed: ${e instanceof Error ? e.message : String(e)}`,
|
|
823
|
+
};
|
|
790
824
|
}
|
|
791
825
|
for (const op of ops) {
|
|
792
826
|
mergeSqliteOpIntoJson(currentJson, op);
|
|
@@ -797,7 +831,10 @@ function queueDeferredSqliteOpsMerged(configPath, sqliteOps, postApplyUpload) {
|
|
|
797
831
|
const line = `sqlite_update: deferred merge produced empty JSON — refusing to queue (would wipe ItemTable row)`;
|
|
798
832
|
hookRunLog(line);
|
|
799
833
|
complianceRunnerDiag(line);
|
|
800
|
-
return
|
|
834
|
+
return {
|
|
835
|
+
ok: false,
|
|
836
|
+
reason: 'merge produced empty JSON (no-op merge — often missing modes4/agent structure or outdated log-llm-config; publish latest package and retry).',
|
|
837
|
+
};
|
|
801
838
|
}
|
|
802
839
|
queueDeferredVscdbItem({
|
|
803
840
|
dbPath,
|
|
@@ -811,13 +848,16 @@ function queueDeferredSqliteOpsMerged(configPath, sqliteOps, postApplyUpload) {
|
|
|
811
848
|
hookRunLog(okLine);
|
|
812
849
|
complianceRunnerDiag(okLine);
|
|
813
850
|
}
|
|
814
|
-
return true;
|
|
851
|
+
return { ok: true };
|
|
815
852
|
}
|
|
816
853
|
catch (err) {
|
|
817
854
|
const line = `sqlite_update: unexpected error: ${err instanceof Error ? err.message : String(err)}`;
|
|
818
855
|
hookRunLog(line);
|
|
819
856
|
complianceRunnerDiag(line);
|
|
820
|
-
return
|
|
857
|
+
return {
|
|
858
|
+
ok: false,
|
|
859
|
+
reason: `unexpected: ${err instanceof Error ? err.message : String(err)}`,
|
|
860
|
+
};
|
|
821
861
|
}
|
|
822
862
|
}
|
|
823
863
|
/**
|
|
@@ -932,11 +972,11 @@ export function enforceRemediation(instruction) {
|
|
|
932
972
|
const postApplyUpload = ft && inst.config_file_path.includes('#')
|
|
933
973
|
? { file_path: inst.config_file_path, file_type: ft }
|
|
934
974
|
: undefined;
|
|
935
|
-
const
|
|
936
|
-
if (!ok) {
|
|
937
|
-
return fail(
|
|
975
|
+
const q = queueDeferredSqliteOpsMerged(inst.config_file_path, ops, postApplyUpload);
|
|
976
|
+
if (!q.ok) {
|
|
977
|
+
return fail(`deferred state.vscdb queue failed — ${q.reason} (see sqlite_update lines in ~/opt-ai-sec/management/hook_log.txt)`, { config_file_path: inst.config_file_path });
|
|
938
978
|
}
|
|
939
|
-
return { ok, deferredSqlite:
|
|
979
|
+
return { ok: true, deferredSqlite: true };
|
|
940
980
|
}
|
|
941
981
|
let allSuccess = true;
|
|
942
982
|
for (const check of sqliteOps) {
|