open-walnut 0.3.0 → 0.3.2

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.
package/dist/cli.js CHANGED
@@ -7234,9 +7234,11 @@ const SESSION_IDLE_KILL_MS = 2 * 60 * 60 * 1000; // 2 hours
7234
7234
  const SESSION_CRON_IDLE_KILL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
7235
7235
  // Sessions with a running background task: wait-style bash tasks write to
7236
7236
  // output_file, not the JSONL, so the session looks idle for the task's whole
7237
- // lifetime (incident inc-1786222771315). Extended, not disabled \u2014 capped at
7238
- // 24h so a lost terminal event can't make the process immortal.
7239
- const SESSION_BG_IDLE_KILL_MS = 24 * 60 * 60 * 1000; // 24 hours
7237
+ // lifetime (incident inc-1786222771315). PRINCIPLE: never reap running bg
7238
+ // work \u2014 this 3-day cap exists only for a wedged task framework that will
7239
+ // never emit a terminal event (immortal-process backstop). See
7240
+ // daemon-standalone.ts for the full rationale.
7241
+ const SESSION_BG_IDLE_KILL_MS = 3 * 24 * 60 * 60 * 1000; // 3 days
7240
7242
  const SESSION_SCAN_INTERVAL_MS = 60000; // every 60s
7241
7243
 
7242
7244
  // Last-resort cron evidence: the CLI scheduler's own debug log in HOME
@@ -14048,6 +14050,16 @@ var init_acp_session = __esm({
14048
14050
  ...configId === "model" ? { acpModel: value } : {},
14049
14051
  acpConfig: { ...record?.acpConfig ?? this.cfg.acpConfig ?? {}, [configId]: value }
14050
14052
  });
14053
+ if (configId === "mode" && value === "agent-full-access" && this._pendingPermissions.size > 0) {
14054
+ const pending2 = [...this._pendingPermissions.keys()];
14055
+ log.session.info("acp: full access selected \u2014 auto-allowing pending permissions", {
14056
+ sessionId: this.trackingId(),
14057
+ requestIds: pending2
14058
+ });
14059
+ for (const requestId of pending2) {
14060
+ await this.resolvePermissionRequest(requestId, true).catch(() => false);
14061
+ }
14062
+ }
14051
14063
  return true;
14052
14064
  }
14053
14065
  /** Switch the model for the next Codex turn through standard ACP config.
@@ -18022,12 +18034,31 @@ __export(qmd_store_exports, {
18022
18034
  getSessionStore: () => getSessionStore,
18023
18035
  getTaskStore: () => getTaskStore,
18024
18036
  initQmdStores: () => initQmdStores,
18037
+ isQmdAvailable: () => isQmdAvailable,
18025
18038
  qmdStoresRequireModelReset: () => qmdStoresRequireModelReset
18026
18039
  });
18027
- import { createStore } from "@tobilu/qmd";
18028
18040
  import Database from "better-sqlite3";
18029
18041
  import fs25 from "fs";
18030
18042
  import path27 from "path";
18043
+ async function loadQmd() {
18044
+ if (!qmdModulePromise) {
18045
+ qmdModulePromise = import("@tobilu/qmd").catch((err2) => {
18046
+ qmdModulePromise = null;
18047
+ throw new Error(
18048
+ `semantic search unavailable: @tobilu/qmd failed to load (${err2 instanceof Error ? err2.message : err2}). This host may lack glibc \u2265 2.28 or the optional dependency was skipped at install.`
18049
+ );
18050
+ });
18051
+ }
18052
+ return qmdModulePromise;
18053
+ }
18054
+ async function isQmdAvailable() {
18055
+ try {
18056
+ await loadQmd();
18057
+ return true;
18058
+ } catch {
18059
+ return false;
18060
+ }
18061
+ }
18031
18062
  function qmdStoresRequireModelReset(currentModel) {
18032
18063
  const expectedDimensions = KNOWN_QMD_MODEL_DIMENSIONS[currentModel];
18033
18064
  for (const filename of QMD_DB_FILES) {
@@ -18178,7 +18209,7 @@ async function embedQmdStore(store3, label, options) {
18178
18209
  async function getMemoryStore() {
18179
18210
  if (memoryStore) return memoryStore;
18180
18211
  if (!memoryStorePromise) {
18181
- const model = await initializeQmdRuntimeModel();
18212
+ const [{ createStore }, model] = await Promise.all([loadQmd(), initializeQmdRuntimeModel()]);
18182
18213
  if (memoryStore) return memoryStore;
18183
18214
  if (memoryStorePromise) return memoryStorePromise;
18184
18215
  memoryStorePromise = createStore({
@@ -18217,7 +18248,7 @@ async function getMemoryStore() {
18217
18248
  async function getNotesStore() {
18218
18249
  if (notesStore) return notesStore;
18219
18250
  if (!notesStorePromise) {
18220
- const model = await initializeQmdRuntimeModel();
18251
+ const [{ createStore }, model] = await Promise.all([loadQmd(), initializeQmdRuntimeModel()]);
18221
18252
  if (notesStore) return notesStore;
18222
18253
  if (notesStorePromise) return notesStorePromise;
18223
18254
  notesStorePromise = createStore({
@@ -18250,7 +18281,7 @@ async function getNotesStore() {
18250
18281
  async function getTaskStore() {
18251
18282
  if (taskStore) return taskStore;
18252
18283
  if (!taskStorePromise) {
18253
- const model = await initializeQmdRuntimeModel();
18284
+ const [{ createStore }, model] = await Promise.all([loadQmd(), initializeQmdRuntimeModel()]);
18254
18285
  if (taskStore) return taskStore;
18255
18286
  if (taskStorePromise) return taskStorePromise;
18256
18287
  taskStorePromise = createStore({
@@ -18275,7 +18306,7 @@ async function getTaskStore() {
18275
18306
  async function getSessionStore() {
18276
18307
  if (sessionStore) return sessionStore;
18277
18308
  if (!sessionStorePromise) {
18278
- const model = await initializeQmdRuntimeModel();
18309
+ const [{ createStore }, model] = await Promise.all([loadQmd(), initializeQmdRuntimeModel()]);
18279
18310
  if (sessionStore) return sessionStore;
18280
18311
  if (sessionStorePromise) return sessionStorePromise;
18281
18312
  sessionStorePromise = createStore({
@@ -18418,7 +18449,7 @@ async function closeQmdStores() {
18418
18449
  taskStorePromise = null;
18419
18450
  sessionStorePromise = null;
18420
18451
  }
18421
- var KNOWN_QMD_MODEL_DIMENSIONS, EMBED_RUN_TABLE, QMD_DB_FILES, memoryStore, memoryStorePromise, notesStore, notesStorePromise, taskStore, taskStorePromise, sessionStore, sessionStorePromise;
18452
+ var KNOWN_QMD_MODEL_DIMENSIONS, EMBED_RUN_TABLE, QMD_DB_FILES, qmdModulePromise, memoryStore, memoryStorePromise, notesStore, notesStorePromise, taskStore, taskStorePromise, sessionStore, sessionStorePromise;
18422
18453
  var init_qmd_store = __esm({
18423
18454
  "src/core/qmd-store.ts"() {
18424
18455
  "use strict";
@@ -18438,6 +18469,7 @@ var init_qmd_store = __esm({
18438
18469
  "task-search.sqlite",
18439
18470
  "session-search.sqlite"
18440
18471
  ];
18472
+ qmdModulePromise = null;
18441
18473
  memoryStore = null;
18442
18474
  memoryStorePromise = null;
18443
18475
  notesStore = null;
@@ -27559,7 +27591,6 @@ __export(qmd_maintenance_exports, {
27559
27591
  rebuildQmdCorpus: () => rebuildQmdCorpus,
27560
27592
  runQmdIncrementalWork: () => runQmdIncrementalWork
27561
27593
  });
27562
- import { Maintenance } from "@tobilu/qmd";
27563
27594
  async function rebuildQmdCorpus(options = {}) {
27564
27595
  const onProgress = options.onProgress;
27565
27596
  if (options.initialize) {
@@ -27649,7 +27680,7 @@ async function runQmdIncrementalWork(work, options = {}) {
27649
27680
  });
27650
27681
  }
27651
27682
  }
27652
- function compactQmdStoreIfNeeded(store3, label) {
27683
+ async function compactQmdStoreIfNeeded(store3, label) {
27653
27684
  const db5 = store3.internal.db;
27654
27685
  const pageCount = db5.pragma("page_count", { simple: true });
27655
27686
  const freePages = db5.pragma("freelist_count", { simple: true });
@@ -27661,6 +27692,7 @@ function compactQmdStoreIfNeeded(store3, label) {
27661
27692
  return null;
27662
27693
  }
27663
27694
  const startedAt = Date.now();
27695
+ const { Maintenance } = await import("@tobilu/qmd");
27664
27696
  new Maintenance(store3.internal).vacuum();
27665
27697
  const afterBytes = db5.pragma("page_count", { simple: true }) * pageSize;
27666
27698
  const stats = {
@@ -27692,7 +27724,7 @@ async function cleanupQmdCorpus(options = {}) {
27692
27724
  const cleanup = cleanupOrphanedQmdData(store3);
27693
27725
  if (!options.compact) return cleanup;
27694
27726
  try {
27695
- const compaction = compactQmdStoreIfNeeded(store3, name);
27727
+ const compaction = await compactQmdStoreIfNeeded(store3, name);
27696
27728
  return compaction ? { ...cleanup, compaction } : cleanup;
27697
27729
  } catch (error) {
27698
27730
  log.memory.warn("QMD store compaction failed", {
@@ -102680,7 +102712,7 @@ ${trimmed.slice(0, 500)}`
102680
102712
  const startDate = snap(validLocalDueDate(parsed.start_date));
102681
102713
  if (startDate) output.start_date = startDate;
102682
102714
  const endDate = snap(validLocalDueDate(parsed.end_date));
102683
- if (endDate && startDate) output.end_date = endDate;
102715
+ if (endDate && startDate && endDate > startDate) output.end_date = endDate;
102684
102716
  if (parsed.pinTier === "focus" || parsed.pinTier === "satellite" || parsed.pinTier === "backlog" || parsed.pinTier === "wait") {
102685
102717
  output.pinTier = parsed.pinTier;
102686
102718
  } else if (typeof parsed.pinTier === "string" && opts.customTiers?.length) {
@@ -134433,6 +134465,8 @@ async function startServer(options = {}) {
134433
134465
  log.memory.info("QMD search disabled via WALNUT_DISABLE_SEARCH=1 \u2014 skipping embedding model init");
134434
134466
  } else if (CLOUD_MODE) {
134435
134467
  log.memory.info("cloud mode: skipping QMD semantic index init");
134468
+ } else if (!await (await Promise.resolve().then(() => (init_qmd_store(), qmd_store_exports))).isQmdAvailable()) {
134469
+ log.memory.warn("QMD semantic search unavailable on this host (optional dependency not installed) \u2014 keyword search only");
134436
134470
  } else try {
134437
134471
  const { startQmdWatcher: startQmdWatcher2 } = await Promise.resolve().then(() => (init_qmd_watcher(), qmd_watcher_exports));
134438
134472
  const {
@@ -1 +1 @@
1
- walnut-daemon-e146d633443b
1
+ walnut-daemon-9df902e189a2
@@ -10999,9 +10999,11 @@ const SESSION_IDLE_KILL_MS = 2 * 60 * 60 * 1000; // 2 hours
10999
10999
  const SESSION_CRON_IDLE_KILL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
11000
11000
  // Sessions with a running background task: wait-style bash tasks write to
11001
11001
  // output_file, not the JSONL, so the session looks idle for the task's whole
11002
- // lifetime (incident inc-1786222771315). Extended, not disabled \u2014 capped at
11003
- // 24h so a lost terminal event can't make the process immortal.
11004
- const SESSION_BG_IDLE_KILL_MS = 24 * 60 * 60 * 1000; // 24 hours
11002
+ // lifetime (incident inc-1786222771315). PRINCIPLE: never reap running bg
11003
+ // work \u2014 this 3-day cap exists only for a wedged task framework that will
11004
+ // never emit a terminal event (immortal-process backstop). See
11005
+ // daemon-standalone.ts for the full rationale.
11006
+ const SESSION_BG_IDLE_KILL_MS = 3 * 24 * 60 * 60 * 1000; // 3 days
11005
11007
  const SESSION_SCAN_INTERVAL_MS = 60000; // every 60s
11006
11008
 
11007
11009
  // Last-resort cron evidence: the CLI scheduler's own debug log in HOME
@@ -17813,6 +17815,16 @@ var init_acp_session = __esm({
17813
17815
  ...configId === "model" ? { acpModel: value } : {},
17814
17816
  acpConfig: { ...record?.acpConfig ?? this.cfg.acpConfig ?? {}, [configId]: value }
17815
17817
  });
17818
+ if (configId === "mode" && value === "agent-full-access" && this._pendingPermissions.size > 0) {
17819
+ const pending2 = [...this._pendingPermissions.keys()];
17820
+ log.session.info("acp: full access selected \u2014 auto-allowing pending permissions", {
17821
+ sessionId: this.trackingId(),
17822
+ requestIds: pending2
17823
+ });
17824
+ for (const requestId of pending2) {
17825
+ await this.resolvePermissionRequest(requestId, true).catch(() => false);
17826
+ }
17827
+ }
17816
17828
  return true;
17817
17829
  }
17818
17830
  /** Switch the model for the next Codex turn through standard ACP config.
@@ -21787,12 +21799,31 @@ __export(qmd_store_exports, {
21787
21799
  getSessionStore: () => getSessionStore,
21788
21800
  getTaskStore: () => getTaskStore,
21789
21801
  initQmdStores: () => initQmdStores,
21802
+ isQmdAvailable: () => isQmdAvailable,
21790
21803
  qmdStoresRequireModelReset: () => qmdStoresRequireModelReset
21791
21804
  });
21792
- import { createStore } from "@tobilu/qmd";
21793
21805
  import Database2 from "better-sqlite3";
21794
21806
  import fs29 from "fs";
21795
21807
  import path32 from "path";
21808
+ async function loadQmd() {
21809
+ if (!qmdModulePromise) {
21810
+ qmdModulePromise = import("@tobilu/qmd").catch((err2) => {
21811
+ qmdModulePromise = null;
21812
+ throw new Error(
21813
+ `semantic search unavailable: @tobilu/qmd failed to load (${err2 instanceof Error ? err2.message : err2}). This host may lack glibc \u2265 2.28 or the optional dependency was skipped at install.`
21814
+ );
21815
+ });
21816
+ }
21817
+ return qmdModulePromise;
21818
+ }
21819
+ async function isQmdAvailable() {
21820
+ try {
21821
+ await loadQmd();
21822
+ return true;
21823
+ } catch {
21824
+ return false;
21825
+ }
21826
+ }
21796
21827
  function qmdStoresRequireModelReset(currentModel) {
21797
21828
  const expectedDimensions = KNOWN_QMD_MODEL_DIMENSIONS[currentModel];
21798
21829
  for (const filename of QMD_DB_FILES) {
@@ -21943,7 +21974,7 @@ async function embedQmdStore(store3, label, options) {
21943
21974
  async function getMemoryStore() {
21944
21975
  if (memoryStore) return memoryStore;
21945
21976
  if (!memoryStorePromise) {
21946
- const model = await initializeQmdRuntimeModel();
21977
+ const [{ createStore }, model] = await Promise.all([loadQmd(), initializeQmdRuntimeModel()]);
21947
21978
  if (memoryStore) return memoryStore;
21948
21979
  if (memoryStorePromise) return memoryStorePromise;
21949
21980
  memoryStorePromise = createStore({
@@ -21982,7 +22013,7 @@ async function getMemoryStore() {
21982
22013
  async function getNotesStore() {
21983
22014
  if (notesStore) return notesStore;
21984
22015
  if (!notesStorePromise) {
21985
- const model = await initializeQmdRuntimeModel();
22016
+ const [{ createStore }, model] = await Promise.all([loadQmd(), initializeQmdRuntimeModel()]);
21986
22017
  if (notesStore) return notesStore;
21987
22018
  if (notesStorePromise) return notesStorePromise;
21988
22019
  notesStorePromise = createStore({
@@ -22015,7 +22046,7 @@ async function getNotesStore() {
22015
22046
  async function getTaskStore() {
22016
22047
  if (taskStore) return taskStore;
22017
22048
  if (!taskStorePromise) {
22018
- const model = await initializeQmdRuntimeModel();
22049
+ const [{ createStore }, model] = await Promise.all([loadQmd(), initializeQmdRuntimeModel()]);
22019
22050
  if (taskStore) return taskStore;
22020
22051
  if (taskStorePromise) return taskStorePromise;
22021
22052
  taskStorePromise = createStore({
@@ -22040,7 +22071,7 @@ async function getTaskStore() {
22040
22071
  async function getSessionStore() {
22041
22072
  if (sessionStore) return sessionStore;
22042
22073
  if (!sessionStorePromise) {
22043
- const model = await initializeQmdRuntimeModel();
22074
+ const [{ createStore }, model] = await Promise.all([loadQmd(), initializeQmdRuntimeModel()]);
22044
22075
  if (sessionStore) return sessionStore;
22045
22076
  if (sessionStorePromise) return sessionStorePromise;
22046
22077
  sessionStorePromise = createStore({
@@ -22183,7 +22214,7 @@ async function closeQmdStores() {
22183
22214
  taskStorePromise = null;
22184
22215
  sessionStorePromise = null;
22185
22216
  }
22186
- var KNOWN_QMD_MODEL_DIMENSIONS, EMBED_RUN_TABLE, QMD_DB_FILES, memoryStore, memoryStorePromise, notesStore, notesStorePromise, taskStore, taskStorePromise, sessionStore, sessionStorePromise;
22217
+ var KNOWN_QMD_MODEL_DIMENSIONS, EMBED_RUN_TABLE, QMD_DB_FILES, qmdModulePromise, memoryStore, memoryStorePromise, notesStore, notesStorePromise, taskStore, taskStorePromise, sessionStore, sessionStorePromise;
22187
22218
  var init_qmd_store = __esm({
22188
22219
  "src/core/qmd-store.ts"() {
22189
22220
  "use strict";
@@ -22203,6 +22234,7 @@ var init_qmd_store = __esm({
22203
22234
  "task-search.sqlite",
22204
22235
  "session-search.sqlite"
22205
22236
  ];
22237
+ qmdModulePromise = null;
22206
22238
  memoryStore = null;
22207
22239
  memoryStorePromise = null;
22208
22240
  notesStore = null;
@@ -31324,7 +31356,6 @@ __export(qmd_maintenance_exports, {
31324
31356
  rebuildQmdCorpus: () => rebuildQmdCorpus,
31325
31357
  runQmdIncrementalWork: () => runQmdIncrementalWork
31326
31358
  });
31327
- import { Maintenance } from "@tobilu/qmd";
31328
31359
  async function rebuildQmdCorpus(options = {}) {
31329
31360
  const onProgress = options.onProgress;
31330
31361
  if (options.initialize) {
@@ -31414,7 +31445,7 @@ async function runQmdIncrementalWork(work, options = {}) {
31414
31445
  });
31415
31446
  }
31416
31447
  }
31417
- function compactQmdStoreIfNeeded(store3, label) {
31448
+ async function compactQmdStoreIfNeeded(store3, label) {
31418
31449
  const db5 = store3.internal.db;
31419
31450
  const pageCount = db5.pragma("page_count", { simple: true });
31420
31451
  const freePages = db5.pragma("freelist_count", { simple: true });
@@ -31426,6 +31457,7 @@ function compactQmdStoreIfNeeded(store3, label) {
31426
31457
  return null;
31427
31458
  }
31428
31459
  const startedAt = Date.now();
31460
+ const { Maintenance } = await import("@tobilu/qmd");
31429
31461
  new Maintenance(store3.internal).vacuum();
31430
31462
  const afterBytes = db5.pragma("page_count", { simple: true }) * pageSize;
31431
31463
  const stats = {
@@ -31457,7 +31489,7 @@ async function cleanupQmdCorpus(options = {}) {
31457
31489
  const cleanup = cleanupOrphanedQmdData(store3);
31458
31490
  if (!options.compact) return cleanup;
31459
31491
  try {
31460
- const compaction = compactQmdStoreIfNeeded(store3, name);
31492
+ const compaction = await compactQmdStoreIfNeeded(store3, name);
31461
31493
  return compaction ? { ...cleanup, compaction } : cleanup;
31462
31494
  } catch (error) {
31463
31495
  log.memory.warn("QMD store compaction failed", {
@@ -101421,7 +101453,7 @@ ${trimmed.slice(0, 500)}`
101421
101453
  const startDate = snap(validLocalDueDate(parsed.start_date));
101422
101454
  if (startDate) output.start_date = startDate;
101423
101455
  const endDate = snap(validLocalDueDate(parsed.end_date));
101424
- if (endDate && startDate) output.end_date = endDate;
101456
+ if (endDate && startDate && endDate > startDate) output.end_date = endDate;
101425
101457
  if (parsed.pinTier === "focus" || parsed.pinTier === "satellite" || parsed.pinTier === "backlog" || parsed.pinTier === "wait") {
101426
101458
  output.pinTier = parsed.pinTier;
101427
101459
  } else if (typeof parsed.pinTier === "string" && opts.customTiers?.length) {
@@ -133367,6 +133399,8 @@ async function startServer(options = {}) {
133367
133399
  log.memory.info("QMD search disabled via WALNUT_DISABLE_SEARCH=1 \u2014 skipping embedding model init");
133368
133400
  } else if (CLOUD_MODE) {
133369
133401
  log.memory.info("cloud mode: skipping QMD semantic index init");
133402
+ } else if (!await (await Promise.resolve().then(() => (init_qmd_store(), qmd_store_exports))).isQmdAvailable()) {
133403
+ log.memory.warn("QMD semantic search unavailable on this host (optional dependency not installed) \u2014 keyword search only");
133370
133404
  } else try {
133371
133405
  const { startQmdWatcher: startQmdWatcher2 } = await Promise.resolve().then(() => (init_qmd_watcher(), qmd_watcher_exports));
133372
133406
  const {
@@ -1794,12 +1794,31 @@ __export(qmd_store_exports, {
1794
1794
  getSessionStore: () => getSessionStore,
1795
1795
  getTaskStore: () => getTaskStore,
1796
1796
  initQmdStores: () => initQmdStores,
1797
+ isQmdAvailable: () => isQmdAvailable,
1797
1798
  qmdStoresRequireModelReset: () => qmdStoresRequireModelReset
1798
1799
  });
1799
- import { createStore } from "@tobilu/qmd";
1800
1800
  import Database from "better-sqlite3";
1801
1801
  import fs5 from "fs";
1802
1802
  import path4 from "path";
1803
+ async function loadQmd() {
1804
+ if (!qmdModulePromise) {
1805
+ qmdModulePromise = import("@tobilu/qmd").catch((err2) => {
1806
+ qmdModulePromise = null;
1807
+ throw new Error(
1808
+ `semantic search unavailable: @tobilu/qmd failed to load (${err2 instanceof Error ? err2.message : err2}). This host may lack glibc \u2265 2.28 or the optional dependency was skipped at install.`
1809
+ );
1810
+ });
1811
+ }
1812
+ return qmdModulePromise;
1813
+ }
1814
+ async function isQmdAvailable() {
1815
+ try {
1816
+ await loadQmd();
1817
+ return true;
1818
+ } catch {
1819
+ return false;
1820
+ }
1821
+ }
1803
1822
  function qmdStoresRequireModelReset(currentModel) {
1804
1823
  const expectedDimensions = KNOWN_QMD_MODEL_DIMENSIONS[currentModel];
1805
1824
  for (const filename of QMD_DB_FILES) {
@@ -1950,7 +1969,7 @@ async function embedQmdStore(store3, label, options) {
1950
1969
  async function getMemoryStore() {
1951
1970
  if (memoryStore) return memoryStore;
1952
1971
  if (!memoryStorePromise) {
1953
- const model = await initializeQmdRuntimeModel();
1972
+ const [{ createStore }, model] = await Promise.all([loadQmd(), initializeQmdRuntimeModel()]);
1954
1973
  if (memoryStore) return memoryStore;
1955
1974
  if (memoryStorePromise) return memoryStorePromise;
1956
1975
  memoryStorePromise = createStore({
@@ -1989,7 +2008,7 @@ async function getMemoryStore() {
1989
2008
  async function getNotesStore() {
1990
2009
  if (notesStore) return notesStore;
1991
2010
  if (!notesStorePromise) {
1992
- const model = await initializeQmdRuntimeModel();
2011
+ const [{ createStore }, model] = await Promise.all([loadQmd(), initializeQmdRuntimeModel()]);
1993
2012
  if (notesStore) return notesStore;
1994
2013
  if (notesStorePromise) return notesStorePromise;
1995
2014
  notesStorePromise = createStore({
@@ -2022,7 +2041,7 @@ async function getNotesStore() {
2022
2041
  async function getTaskStore() {
2023
2042
  if (taskStore) return taskStore;
2024
2043
  if (!taskStorePromise) {
2025
- const model = await initializeQmdRuntimeModel();
2044
+ const [{ createStore }, model] = await Promise.all([loadQmd(), initializeQmdRuntimeModel()]);
2026
2045
  if (taskStore) return taskStore;
2027
2046
  if (taskStorePromise) return taskStorePromise;
2028
2047
  taskStorePromise = createStore({
@@ -2047,7 +2066,7 @@ async function getTaskStore() {
2047
2066
  async function getSessionStore() {
2048
2067
  if (sessionStore) return sessionStore;
2049
2068
  if (!sessionStorePromise) {
2050
- const model = await initializeQmdRuntimeModel();
2069
+ const [{ createStore }, model] = await Promise.all([loadQmd(), initializeQmdRuntimeModel()]);
2051
2070
  if (sessionStore) return sessionStore;
2052
2071
  if (sessionStorePromise) return sessionStorePromise;
2053
2072
  sessionStorePromise = createStore({
@@ -2190,7 +2209,7 @@ async function closeQmdStores() {
2190
2209
  taskStorePromise = null;
2191
2210
  sessionStorePromise = null;
2192
2211
  }
2193
- var KNOWN_QMD_MODEL_DIMENSIONS, EMBED_RUN_TABLE, QMD_DB_FILES, memoryStore, memoryStorePromise, notesStore, notesStorePromise, taskStore, taskStorePromise, sessionStore, sessionStorePromise;
2212
+ var KNOWN_QMD_MODEL_DIMENSIONS, EMBED_RUN_TABLE, QMD_DB_FILES, qmdModulePromise, memoryStore, memoryStorePromise, notesStore, notesStorePromise, taskStore, taskStorePromise, sessionStore, sessionStorePromise;
2194
2213
  var init_qmd_store = __esm({
2195
2214
  "src/core/qmd-store.ts"() {
2196
2215
  "use strict";
@@ -2210,6 +2229,7 @@ var init_qmd_store = __esm({
2210
2229
  "task-search.sqlite",
2211
2230
  "session-search.sqlite"
2212
2231
  ];
2232
+ qmdModulePromise = null;
2213
2233
  memoryStore = null;
2214
2234
  memoryStorePromise = null;
2215
2235
  notesStore = null;
@@ -7771,9 +7791,11 @@ const SESSION_IDLE_KILL_MS = 2 * 60 * 60 * 1000; // 2 hours
7771
7791
  const SESSION_CRON_IDLE_KILL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
7772
7792
  // Sessions with a running background task: wait-style bash tasks write to
7773
7793
  // output_file, not the JSONL, so the session looks idle for the task's whole
7774
- // lifetime (incident inc-1786222771315). Extended, not disabled \u2014 capped at
7775
- // 24h so a lost terminal event can't make the process immortal.
7776
- const SESSION_BG_IDLE_KILL_MS = 24 * 60 * 60 * 1000; // 24 hours
7794
+ // lifetime (incident inc-1786222771315). PRINCIPLE: never reap running bg
7795
+ // work \u2014 this 3-day cap exists only for a wedged task framework that will
7796
+ // never emit a terminal event (immortal-process backstop). See
7797
+ // daemon-standalone.ts for the full rationale.
7798
+ const SESSION_BG_IDLE_KILL_MS = 3 * 24 * 60 * 60 * 1000; // 3 days
7777
7799
  const SESSION_SCAN_INTERVAL_MS = 60000; // every 60s
7778
7800
 
7779
7801
  // Last-resort cron evidence: the CLI scheduler's own debug log in HOME
@@ -13151,6 +13173,16 @@ var init_acp_session = __esm({
13151
13173
  ...configId === "model" ? { acpModel: value } : {},
13152
13174
  acpConfig: { ...record?.acpConfig ?? this.cfg.acpConfig ?? {}, [configId]: value }
13153
13175
  });
13176
+ if (configId === "mode" && value === "agent-full-access" && this._pendingPermissions.size > 0) {
13177
+ const pending2 = [...this._pendingPermissions.keys()];
13178
+ log.session.info("acp: full access selected \u2014 auto-allowing pending permissions", {
13179
+ sessionId: this.trackingId(),
13180
+ requestIds: pending2
13181
+ });
13182
+ for (const requestId of pending2) {
13183
+ await this.resolvePermissionRequest(requestId, true).catch(() => false);
13184
+ }
13185
+ }
13154
13186
  return true;
13155
13187
  }
13156
13188
  /** Switch the model for the next Codex turn through standard ACP config.
@@ -96905,7 +96937,6 @@ __export(qmd_maintenance_exports, {
96905
96937
  rebuildQmdCorpus: () => rebuildQmdCorpus,
96906
96938
  runQmdIncrementalWork: () => runQmdIncrementalWork
96907
96939
  });
96908
- import { Maintenance } from "@tobilu/qmd";
96909
96940
  async function rebuildQmdCorpus(options = {}) {
96910
96941
  const onProgress = options.onProgress;
96911
96942
  if (options.initialize) {
@@ -96995,7 +97026,7 @@ async function runQmdIncrementalWork(work, options = {}) {
96995
97026
  });
96996
97027
  }
96997
97028
  }
96998
- function compactQmdStoreIfNeeded(store3, label) {
97029
+ async function compactQmdStoreIfNeeded(store3, label) {
96999
97030
  const db4 = store3.internal.db;
97000
97031
  const pageCount = db4.pragma("page_count", { simple: true });
97001
97032
  const freePages = db4.pragma("freelist_count", { simple: true });
@@ -97007,6 +97038,7 @@ function compactQmdStoreIfNeeded(store3, label) {
97007
97038
  return null;
97008
97039
  }
97009
97040
  const startedAt = Date.now();
97041
+ const { Maintenance } = await import("@tobilu/qmd");
97010
97042
  new Maintenance(store3.internal).vacuum();
97011
97043
  const afterBytes = db4.pragma("page_count", { simple: true }) * pageSize;
97012
97044
  const stats = {
@@ -97038,7 +97070,7 @@ async function cleanupQmdCorpus(options = {}) {
97038
97070
  const cleanup = cleanupOrphanedQmdData(store3);
97039
97071
  if (!options.compact) return cleanup;
97040
97072
  try {
97041
- const compaction = compactQmdStoreIfNeeded(store3, name);
97073
+ const compaction = await compactQmdStoreIfNeeded(store3, name);
97042
97074
  return compaction ? { ...cleanup, compaction } : cleanup;
97043
97075
  } catch (error) {
97044
97076
  log.memory.warn("QMD store compaction failed", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-walnut",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Personal AI butler powered by Claude — task management, Claude Code sessions, memory system, and web UI",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/EvanZhang008/open-walnut",
@@ -92,11 +92,9 @@
92
92
  "@aws-sdk/client-sts": "^3.996.0",
93
93
  "@azure/msal-node": "^5.0.3",
94
94
  "@google/generative-ai": "^0.24.1",
95
- "@homebridge/node-pty-prebuilt-multiarch": "^0.12.0",
96
95
  "@mozilla/readability": "^0.6.0",
97
96
  "@slack/web-api": "^7.14.0",
98
97
  "@tiptap/extension-image": "^3.20.1",
99
- "@tobilu/qmd": "2.1.0",
100
98
  "better-sqlite3": "^12.6.2",
101
99
  "chalk": "^5.4.1",
102
100
  "commander": "^14.0.0",
@@ -115,6 +113,8 @@
115
113
  "ws": "^8.19.0"
116
114
  },
117
115
  "optionalDependencies": {
116
+ "@homebridge/node-pty-prebuilt-multiarch": "^0.12.0",
117
+ "@tobilu/qmd": "2.1.0",
118
118
  "screencapturekit-audio-capture": "^1.3.6"
119
119
  },
120
120
  "devDependencies": {