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
- node = node[p];
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 arr = container[arrayKey];
487
- if (!Array.isArray(arr))
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 < 0)
515
+ if (idx >= 0) {
516
+ Object.assign(arr[idx], sqliteOp.updates);
496
517
  return;
497
- Object.assign(arr[idx], sqliteOp.updates);
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 false;
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 false;
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 false;
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 false;
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 ok = queueDeferredSqliteOpsMerged(inst.config_file_path, ops, postApplyUpload);
936
- if (!ok) {
937
- return fail('deferred state.vscdb queue failed (database missing, sqlite3 unavailable, or read/merge error — see sqlite_update lines above in hook_log)', { config_file_path: inst.config_file_path });
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: ok };
979
+ return { ok: true, deferredSqlite: true };
940
980
  }
941
981
  let allSuccess = true;
942
982
  for (const check of sqliteOps) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "log-llm-config",
3
- "version": "1.3.21",
3
+ "version": "1.3.22",
4
4
  "description": "CLI helpers for logging hardware UUIDs and posting startup payloads to Optimus Security.",
5
5
  "type": "module",
6
6
  "bin": {