@askexenow/exe-os 0.8.89 → 0.8.91

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.
Files changed (44) hide show
  1. package/dist/bin/backfill-conversations.js +10 -0
  2. package/dist/bin/backfill-responses.js +10 -0
  3. package/dist/bin/backfill-vectors.js +10 -0
  4. package/dist/bin/cli.js +75 -30
  5. package/dist/bin/exe-assign.js +13 -3
  6. package/dist/bin/exe-boot.js +34 -24
  7. package/dist/bin/exe-gateway.js +36 -26
  8. package/dist/bin/exe-link.js +10 -0
  9. package/dist/bin/exe-rename.js +10 -0
  10. package/dist/bin/exe-search.js +10 -0
  11. package/dist/bin/exe-session-cleanup.js +30 -20
  12. package/dist/bin/git-sweep.js +25 -15
  13. package/dist/bin/scan-tasks.js +27 -17
  14. package/dist/bin/setup.js +52 -7
  15. package/dist/gateway/index.js +34 -24
  16. package/dist/hooks/commit-complete.js +25 -15
  17. package/dist/hooks/error-recall.js +10 -0
  18. package/dist/hooks/ingest-worker.js +30 -20
  19. package/dist/hooks/instructions-loaded.js +15 -5
  20. package/dist/hooks/notification.js +13 -3
  21. package/dist/hooks/post-compact.js +17 -7
  22. package/dist/hooks/pre-compact.js +25 -15
  23. package/dist/hooks/pre-tool-use.js +20 -10
  24. package/dist/hooks/prompt-ingest-worker.js +10 -0
  25. package/dist/hooks/prompt-submit.js +20 -10
  26. package/dist/hooks/response-ingest-worker.js +10 -0
  27. package/dist/hooks/session-end.js +26 -16
  28. package/dist/hooks/session-start.js +19 -9
  29. package/dist/hooks/stop.js +17 -7
  30. package/dist/hooks/subagent-stop.js +17 -7
  31. package/dist/hooks/summary-worker.js +23 -13
  32. package/dist/index.js +29 -19
  33. package/dist/lib/cloud-sync.js +13 -3
  34. package/dist/lib/database.js +10 -0
  35. package/dist/lib/db-daemon-client.js +10 -0
  36. package/dist/lib/device-registry.js +12 -2
  37. package/dist/lib/embedder.js +10 -0
  38. package/dist/lib/exe-daemon-client.js +10 -0
  39. package/dist/lib/exe-daemon.js +31 -21
  40. package/dist/lib/hybrid-search.js +10 -0
  41. package/dist/mcp/server.js +38 -28
  42. package/dist/runtime/index.js +25 -15
  43. package/dist/tui/App.js +27 -17
  44. package/package.json +1 -1
@@ -1835,6 +1835,7 @@ var init_memory = __esm({
1835
1835
 
1836
1836
  // src/lib/exe-daemon-client.ts
1837
1837
  import net from "net";
1838
+ import os3 from "os";
1838
1839
  import { spawn } from "child_process";
1839
1840
  import { randomUUID } from "crypto";
1840
1841
  import { existsSync as existsSync3, unlinkSync as unlinkSync2, readFileSync as readFileSync3, openSync, closeSync, statSync } from "fs";
@@ -1898,6 +1899,15 @@ function findPackageRoot() {
1898
1899
  return null;
1899
1900
  }
1900
1901
  function spawnDaemon() {
1902
+ const freeGB = os3.freemem() / (1024 * 1024 * 1024);
1903
+ const totalGB = os3.totalmem() / (1024 * 1024 * 1024);
1904
+ if (freeGB < 1.5 && totalGB <= 8) {
1905
+ process.stderr.write(
1906
+ `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB free / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only. Close other apps and retry.
1907
+ `
1908
+ );
1909
+ return;
1910
+ }
1901
1911
  const pkgRoot = findPackageRoot();
1902
1912
  if (!pkgRoot) {
1903
1913
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -2236,9 +2246,9 @@ var init_embedder = __esm({
2236
2246
  import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
2237
2247
  import { existsSync as existsSync4 } from "fs";
2238
2248
  import path4 from "path";
2239
- import os3 from "os";
2249
+ import os4 from "os";
2240
2250
  function getKeyDir() {
2241
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path4.join(os3.homedir(), ".exe-os");
2251
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path4.join(os4.homedir(), ".exe-os");
2242
2252
  }
2243
2253
  function getKeyPath() {
2244
2254
  return path4.join(getKeyDir(), "master.key");
@@ -2264,7 +2274,7 @@ async function getMasterKey() {
2264
2274
  const keyPath = getKeyPath();
2265
2275
  if (!existsSync4(keyPath)) {
2266
2276
  process.stderr.write(
2267
- `[keychain] Key not found at ${keyPath} (HOME=${os3.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
2277
+ `[keychain] Key not found at ${keyPath} (HOME=${os4.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
2268
2278
  `
2269
2279
  );
2270
2280
  return null;
@@ -5594,7 +5604,7 @@ __export(imessage_exports, {
5594
5604
  });
5595
5605
  import { execFile } from "child_process";
5596
5606
  import { promisify } from "util";
5597
- import os4 from "os";
5607
+ import os5 from "os";
5598
5608
  import path7 from "path";
5599
5609
  var execFileAsync, POLL_INTERVAL_MS, MESSAGES_DB_PATH, IMessageAdapter;
5600
5610
  var init_imessage = __esm({
@@ -5603,7 +5613,7 @@ var init_imessage = __esm({
5603
5613
  execFileAsync = promisify(execFile);
5604
5614
  POLL_INTERVAL_MS = 5e3;
5605
5615
  MESSAGES_DB_PATH = path7.join(
5606
- process.env.HOME ?? os4.homedir(),
5616
+ process.env.HOME ?? os5.homedir(),
5607
5617
  "Library/Messages/chat.db"
5608
5618
  );
5609
5619
  IMessageAdapter = class {
@@ -6069,7 +6079,7 @@ var init_whatsapp_accounts = __esm({
6069
6079
  // src/lib/session-registry.ts
6070
6080
  import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, existsSync as existsSync7 } from "fs";
6071
6081
  import path8 from "path";
6072
- import os5 from "os";
6082
+ import os6 from "os";
6073
6083
  function registerSession(entry) {
6074
6084
  const dir = path8.dirname(REGISTRY_PATH);
6075
6085
  if (!existsSync7(dir)) {
@@ -6096,7 +6106,7 @@ var REGISTRY_PATH;
6096
6106
  var init_session_registry = __esm({
6097
6107
  "src/lib/session-registry.ts"() {
6098
6108
  "use strict";
6099
- REGISTRY_PATH = path8.join(os5.homedir(), ".exe-os", "session-registry.json");
6109
+ REGISTRY_PATH = path8.join(os6.homedir(), ".exe-os", "session-registry.json");
6100
6110
  }
6101
6111
  });
6102
6112
 
@@ -6369,7 +6379,7 @@ var init_agent_config = __esm({
6369
6379
  // src/lib/intercom-queue.ts
6370
6380
  import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, renameSync as renameSync3, existsSync as existsSync9, mkdirSync as mkdirSync6 } from "fs";
6371
6381
  import path10 from "path";
6372
- import os6 from "os";
6382
+ import os7 from "os";
6373
6383
  function ensureDir() {
6374
6384
  const dir = path10.dirname(QUEUE_PATH);
6375
6385
  if (!existsSync9(dir)) mkdirSync6(dir, { recursive: true });
@@ -6409,9 +6419,9 @@ var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
6409
6419
  var init_intercom_queue = __esm({
6410
6420
  "src/lib/intercom-queue.ts"() {
6411
6421
  "use strict";
6412
- QUEUE_PATH = path10.join(os6.homedir(), ".exe-os", "intercom-queue.json");
6422
+ QUEUE_PATH = path10.join(os7.homedir(), ".exe-os", "intercom-queue.json");
6413
6423
  TTL_MS = 60 * 60 * 1e3;
6414
- INTERCOM_LOG = path10.join(os6.homedir(), ".exe-os", "intercom.log");
6424
+ INTERCOM_LOG = path10.join(os7.homedir(), ".exe-os", "intercom.log");
6415
6425
  }
6416
6426
  });
6417
6427
 
@@ -6496,7 +6506,7 @@ var init_plan_limits = __esm({
6496
6506
  // src/lib/notifications.ts
6497
6507
  import crypto3 from "crypto";
6498
6508
  import path12 from "path";
6499
- import os7 from "os";
6509
+ import os8 from "os";
6500
6510
  import {
6501
6511
  readFileSync as readFileSync10,
6502
6512
  readdirSync as readdirSync2,
@@ -6606,7 +6616,7 @@ var init_task_scope = __esm({
6606
6616
  // src/lib/tasks-crud.ts
6607
6617
  import crypto5 from "crypto";
6608
6618
  import path13 from "path";
6609
- import os8 from "os";
6619
+ import os9 from "os";
6610
6620
  import { execSync as execSync4 } from "child_process";
6611
6621
  import { mkdir as mkdir4, writeFile as writeFile4, appendFile } from "fs/promises";
6612
6622
  import { existsSync as existsSync12, readFileSync as readFileSync11 } from "fs";
@@ -6821,7 +6831,7 @@ ${laneWarning}` : laneWarning;
6821
6831
  });
6822
6832
  if (input.baseDir) {
6823
6833
  try {
6824
- const EXE_OS_DIR = path13.join(os8.homedir(), ".exe-os");
6834
+ const EXE_OS_DIR = path13.join(os9.homedir(), ".exe-os");
6825
6835
  const mdPath = path13.join(EXE_OS_DIR, taskFile);
6826
6836
  const mdDir = path13.dirname(mdPath);
6827
6837
  if (!existsSync12(mdDir)) await mkdir4(mdDir, { recursive: true });
@@ -8467,7 +8477,7 @@ __export(tmux_routing_exports, {
8467
8477
  import { execFileSync as execFileSync2, execSync as execSync6 } from "child_process";
8468
8478
  import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, mkdirSync as mkdirSync8, existsSync as existsSync14, appendFileSync } from "fs";
8469
8479
  import path18 from "path";
8470
- import os9 from "os";
8480
+ import os10 from "os";
8471
8481
  import { fileURLToPath as fileURLToPath2 } from "url";
8472
8482
  import { unlinkSync as unlinkSync6 } from "fs";
8473
8483
  function spawnLockPath(sessionName) {
@@ -8881,7 +8891,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
8881
8891
  const transport = getTransport();
8882
8892
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
8883
8893
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
8884
- const logDir = path18.join(os9.homedir(), ".exe-os", "session-logs");
8894
+ const logDir = path18.join(os10.homedir(), ".exe-os", "session-logs");
8885
8895
  const logFile = path18.join(logDir, `${instanceLabel}-${Date.now()}.log`);
8886
8896
  if (!existsSync14(logDir)) {
8887
8897
  mkdirSync8(logDir, { recursive: true });
@@ -8897,7 +8907,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
8897
8907
  } catch {
8898
8908
  }
8899
8909
  try {
8900
- const claudeJsonPath = path18.join(os9.homedir(), ".claude.json");
8910
+ const claudeJsonPath = path18.join(os10.homedir(), ".claude.json");
8901
8911
  let claudeJson = {};
8902
8912
  try {
8903
8913
  claudeJson = JSON.parse(readFileSync12(claudeJsonPath, "utf8"));
@@ -8912,7 +8922,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
8912
8922
  } catch {
8913
8923
  }
8914
8924
  try {
8915
- const settingsDir = path18.join(os9.homedir(), ".claude", "projects");
8925
+ const settingsDir = path18.join(os10.homedir(), ".claude", "projects");
8916
8926
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
8917
8927
  const projSettingsDir = path18.join(settingsDir, normalizedKey);
8918
8928
  const settingsPath = path18.join(projSettingsDir, "settings.json");
@@ -8963,7 +8973,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
8963
8973
  let legacyFallbackWarned = false;
8964
8974
  if (!useExeAgent && !useBinSymlink) {
8965
8975
  const identityPath = path18.join(
8966
- os9.homedir(),
8976
+ os10.homedir(),
8967
8977
  ".exe-os",
8968
8978
  "identity",
8969
8979
  `${employeeName}.md`
@@ -8993,7 +9003,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
8993
9003
  }
8994
9004
  let sessionContextFlag = "";
8995
9005
  try {
8996
- const ctxDir = path18.join(os9.homedir(), ".exe-os", "session-cache");
9006
+ const ctxDir = path18.join(os10.homedir(), ".exe-os", "session-cache");
8997
9007
  mkdirSync8(ctxDir, { recursive: true });
8998
9008
  const ctxFile = path18.join(ctxDir, `session-context-${sessionName}.md`);
8999
9009
  const ctxContent = [
@@ -9154,13 +9164,13 @@ var init_tmux_routing = __esm({
9154
9164
  init_intercom_queue();
9155
9165
  init_plan_limits();
9156
9166
  init_employees();
9157
- SPAWN_LOCK_DIR = path18.join(os9.homedir(), ".exe-os", "spawn-locks");
9158
- SESSION_CACHE = path18.join(os9.homedir(), ".exe-os", "session-cache");
9167
+ SPAWN_LOCK_DIR = path18.join(os10.homedir(), ".exe-os", "spawn-locks");
9168
+ SESSION_CACHE = path18.join(os10.homedir(), ".exe-os", "session-cache");
9159
9169
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
9160
9170
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
9161
9171
  VERIFY_PANE_LINES = 200;
9162
9172
  INTERCOM_DEBOUNCE_MS = 3e4;
9163
- INTERCOM_LOG2 = path18.join(os9.homedir(), ".exe-os", "intercom.log");
9173
+ INTERCOM_LOG2 = path18.join(os10.homedir(), ".exe-os", "intercom.log");
9164
9174
  DEBOUNCE_FILE = path18.join(SESSION_CACHE, "intercom-debounce.json");
9165
9175
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
9166
9176
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
@@ -9422,7 +9432,7 @@ var init_messaging = __esm({
9422
9432
  import { readFileSync as readFileSync13, writeFileSync as writeFileSync8, existsSync as existsSync15, mkdirSync as mkdirSync9 } from "fs";
9423
9433
  import { randomUUID as randomUUID8 } from "crypto";
9424
9434
  import path19 from "path";
9425
- import os10 from "os";
9435
+ import os11 from "os";
9426
9436
  function substituteTemplate(template, record) {
9427
9437
  return template.replace(
9428
9438
  /\{\{(\w+(?:\.\w+)*)\}\}/g,
@@ -9717,7 +9727,7 @@ var TRIGGERS_PATH, GRAPH_API_VERSION;
9717
9727
  var init_trigger_engine = __esm({
9718
9728
  "src/automation/trigger-engine.ts"() {
9719
9729
  "use strict";
9720
- TRIGGERS_PATH = path19.join(os10.homedir(), ".exe-os", "triggers.json");
9730
+ TRIGGERS_PATH = path19.join(os11.homedir(), ".exe-os", "triggers.json");
9721
9731
  GRAPH_API_VERSION = "v21.0";
9722
9732
  }
9723
9733
  });
@@ -9782,7 +9792,7 @@ var init_crm_webhook = __esm({
9782
9792
  // src/bin/exe-gateway.ts
9783
9793
  import { existsSync as existsSync16, readFileSync as readFileSync14 } from "fs";
9784
9794
  import path20 from "path";
9785
- import os11 from "os";
9795
+ import os12 from "os";
9786
9796
 
9787
9797
  // src/gateway/webhook-server.ts
9788
9798
  import {
@@ -10748,7 +10758,7 @@ var BotRegistry = class {
10748
10758
 
10749
10759
  // src/bin/exe-gateway.ts
10750
10760
  init_employees();
10751
- var CONFIG_DIR = path20.join(os11.homedir(), ".exe-os");
10761
+ var CONFIG_DIR = path20.join(os12.homedir(), ".exe-os");
10752
10762
  var CONFIG_PATH3 = path20.join(CONFIG_DIR, "gateway.json");
10753
10763
  var DEFAULT_PORT = 3100;
10754
10764
  function loadConfig2() {
@@ -580,6 +580,7 @@ var init_employees = __esm({
580
580
 
581
581
  // src/lib/exe-daemon-client.ts
582
582
  import net from "net";
583
+ import os4 from "os";
583
584
  import { spawn } from "child_process";
584
585
  import { randomUUID } from "crypto";
585
586
  import { existsSync as existsSync4, unlinkSync as unlinkSync2, readFileSync as readFileSync3, openSync, closeSync, statSync } from "fs";
@@ -643,6 +644,15 @@ function findPackageRoot() {
643
644
  return null;
644
645
  }
645
646
  function spawnDaemon() {
647
+ const freeGB = os4.freemem() / (1024 * 1024 * 1024);
648
+ const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
649
+ if (freeGB < 1.5 && totalGB <= 8) {
650
+ process.stderr.write(
651
+ `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB free / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only. Close other apps and retry.
652
+ `
653
+ );
654
+ return;
655
+ }
646
656
  const pkgRoot = findPackageRoot();
647
657
  if (!pkgRoot) {
648
658
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -264,6 +264,7 @@ var init_db_retry = __esm({
264
264
 
265
265
  // src/lib/exe-daemon-client.ts
266
266
  import net from "net";
267
+ import os3 from "os";
267
268
  import { spawn } from "child_process";
268
269
  import { randomUUID } from "crypto";
269
270
  import { existsSync as existsSync3, unlinkSync as unlinkSync2, readFileSync as readFileSync3, openSync, closeSync, statSync } from "fs";
@@ -327,6 +328,15 @@ function findPackageRoot() {
327
328
  return null;
328
329
  }
329
330
  function spawnDaemon() {
331
+ const freeGB = os3.freemem() / (1024 * 1024 * 1024);
332
+ const totalGB = os3.totalmem() / (1024 * 1024 * 1024);
333
+ if (freeGB < 1.5 && totalGB <= 8) {
334
+ process.stderr.write(
335
+ `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB free / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only. Close other apps and retry.
336
+ `
337
+ );
338
+ return;
339
+ }
330
340
  const pkgRoot = findPackageRoot();
331
341
  if (!pkgRoot) {
332
342
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -2661,6 +2661,7 @@ var init_reranker = __esm({
2661
2661
 
2662
2662
  // src/lib/exe-daemon-client.ts
2663
2663
  import net from "net";
2664
+ import os4 from "os";
2664
2665
  import { spawn } from "child_process";
2665
2666
  import { randomUUID as randomUUID2 } from "crypto";
2666
2667
  import { existsSync as existsSync6, unlinkSync as unlinkSync2, readFileSync as readFileSync3, openSync, closeSync, statSync } from "fs";
@@ -2724,6 +2725,15 @@ function findPackageRoot() {
2724
2725
  return null;
2725
2726
  }
2726
2727
  function spawnDaemon() {
2728
+ const freeGB = os4.freemem() / (1024 * 1024 * 1024);
2729
+ const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
2730
+ if (freeGB < 1.5 && totalGB <= 8) {
2731
+ process.stderr.write(
2732
+ `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB free / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only. Close other apps and retry.
2733
+ `
2734
+ );
2735
+ return;
2736
+ }
2727
2737
  const pkgRoot = findPackageRoot();
2728
2738
  if (!pkgRoot) {
2729
2739
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -388,6 +388,7 @@ var init_employees = __esm({
388
388
 
389
389
  // src/lib/exe-daemon-client.ts
390
390
  import net from "net";
391
+ import os3 from "os";
391
392
  import { spawn } from "child_process";
392
393
  import { randomUUID } from "crypto";
393
394
  import { existsSync as existsSync3, unlinkSync as unlinkSync2, readFileSync as readFileSync3, openSync, closeSync, statSync } from "fs";
@@ -451,6 +452,15 @@ function findPackageRoot() {
451
452
  return null;
452
453
  }
453
454
  function spawnDaemon() {
455
+ const freeGB = os3.freemem() / (1024 * 1024 * 1024);
456
+ const totalGB = os3.totalmem() / (1024 * 1024 * 1024);
457
+ if (freeGB < 1.5 && totalGB <= 8) {
458
+ process.stderr.write(
459
+ `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB free / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only. Close other apps and retry.
460
+ `
461
+ );
462
+ return;
463
+ }
454
464
  const pkgRoot = findPackageRoot();
455
465
  if (!pkgRoot) {
456
466
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -1936,9 +1946,9 @@ var init_database = __esm({
1936
1946
  import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
1937
1947
  import { existsSync as existsSync4 } from "fs";
1938
1948
  import path4 from "path";
1939
- import os3 from "os";
1949
+ import os4 from "os";
1940
1950
  function getKeyDir() {
1941
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path4.join(os3.homedir(), ".exe-os");
1951
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path4.join(os4.homedir(), ".exe-os");
1942
1952
  }
1943
1953
  function getKeyPath() {
1944
1954
  return path4.join(getKeyDir(), "master.key");
@@ -1964,7 +1974,7 @@ async function getMasterKey() {
1964
1974
  const keyPath = getKeyPath();
1965
1975
  if (!existsSync4(keyPath)) {
1966
1976
  process.stderr.write(
1967
- `[keychain] Key not found at ${keyPath} (HOME=${os3.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
1977
+ `[keychain] Key not found at ${keyPath} (HOME=${os4.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
1968
1978
  `
1969
1979
  );
1970
1980
  return null;
@@ -3041,7 +3051,7 @@ var init_store = __esm({
3041
3051
  // src/lib/session-registry.ts
3042
3052
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync6 } from "fs";
3043
3053
  import path6 from "path";
3044
- import os4 from "os";
3054
+ import os5 from "os";
3045
3055
  function registerSession(entry) {
3046
3056
  const dir = path6.dirname(REGISTRY_PATH);
3047
3057
  if (!existsSync6(dir)) {
@@ -3068,7 +3078,7 @@ var REGISTRY_PATH;
3068
3078
  var init_session_registry = __esm({
3069
3079
  "src/lib/session-registry.ts"() {
3070
3080
  "use strict";
3071
- REGISTRY_PATH = path6.join(os4.homedir(), ".exe-os", "session-registry.json");
3081
+ REGISTRY_PATH = path6.join(os5.homedir(), ".exe-os", "session-registry.json");
3072
3082
  }
3073
3083
  });
3074
3084
 
@@ -3341,7 +3351,7 @@ var init_agent_config = __esm({
3341
3351
  // src/lib/intercom-queue.ts
3342
3352
  import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
3343
3353
  import path8 from "path";
3344
- import os5 from "os";
3354
+ import os6 from "os";
3345
3355
  function ensureDir() {
3346
3356
  const dir = path8.dirname(QUEUE_PATH);
3347
3357
  if (!existsSync8(dir)) mkdirSync4(dir, { recursive: true });
@@ -3381,9 +3391,9 @@ var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
3381
3391
  var init_intercom_queue = __esm({
3382
3392
  "src/lib/intercom-queue.ts"() {
3383
3393
  "use strict";
3384
- QUEUE_PATH = path8.join(os5.homedir(), ".exe-os", "intercom-queue.json");
3394
+ QUEUE_PATH = path8.join(os6.homedir(), ".exe-os", "intercom-queue.json");
3385
3395
  TTL_MS = 60 * 60 * 1e3;
3386
- INTERCOM_LOG = path8.join(os5.homedir(), ".exe-os", "intercom.log");
3396
+ INTERCOM_LOG = path8.join(os6.homedir(), ".exe-os", "intercom.log");
3387
3397
  }
3388
3398
  });
3389
3399
 
@@ -3491,7 +3501,7 @@ var init_plan_limits = __esm({
3491
3501
  // src/lib/notifications.ts
3492
3502
  import crypto from "crypto";
3493
3503
  import path11 from "path";
3494
- import os6 from "os";
3504
+ import os7 from "os";
3495
3505
  import {
3496
3506
  readFileSync as readFileSync9,
3497
3507
  readdirSync as readdirSync2,
@@ -3593,7 +3603,7 @@ __export(tasks_crud_exports, {
3593
3603
  });
3594
3604
  import crypto3 from "crypto";
3595
3605
  import path12 from "path";
3596
- import os7 from "os";
3606
+ import os8 from "os";
3597
3607
  import { execSync as execSync4 } from "child_process";
3598
3608
  import { mkdir as mkdir4, writeFile as writeFile4, appendFile } from "fs/promises";
3599
3609
  import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
@@ -3808,7 +3818,7 @@ ${laneWarning}` : laneWarning;
3808
3818
  });
3809
3819
  if (input.baseDir) {
3810
3820
  try {
3811
- const EXE_OS_DIR = path12.join(os7.homedir(), ".exe-os");
3821
+ const EXE_OS_DIR = path12.join(os8.homedir(), ".exe-os");
3812
3822
  const mdPath = path12.join(EXE_OS_DIR, taskFile);
3813
3823
  const mdDir = path12.dirname(mdPath);
3814
3824
  if (!existsSync12(mdDir)) await mkdir4(mdDir, { recursive: true });
@@ -5553,7 +5563,7 @@ __export(tmux_routing_exports, {
5553
5563
  import { execFileSync as execFileSync2, execSync as execSync6 } from "child_process";
5554
5564
  import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, existsSync as existsSync14, appendFileSync } from "fs";
5555
5565
  import path17 from "path";
5556
- import os8 from "os";
5566
+ import os9 from "os";
5557
5567
  import { fileURLToPath as fileURLToPath2 } from "url";
5558
5568
  import { unlinkSync as unlinkSync6 } from "fs";
5559
5569
  function spawnLockPath(sessionName) {
@@ -5967,7 +5977,7 @@ function spawnEmployee(employeeName, exeSession2, projectDir, opts) {
5967
5977
  const transport = getTransport();
5968
5978
  const sessionName = employeeSessionName(employeeName, exeSession2, opts?.instance);
5969
5979
  const instanceLabel2 = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
5970
- const logDir = path17.join(os8.homedir(), ".exe-os", "session-logs");
5980
+ const logDir = path17.join(os9.homedir(), ".exe-os", "session-logs");
5971
5981
  const logFile = path17.join(logDir, `${instanceLabel2}-${Date.now()}.log`);
5972
5982
  if (!existsSync14(logDir)) {
5973
5983
  mkdirSync7(logDir, { recursive: true });
@@ -5983,7 +5993,7 @@ function spawnEmployee(employeeName, exeSession2, projectDir, opts) {
5983
5993
  } catch {
5984
5994
  }
5985
5995
  try {
5986
- const claudeJsonPath = path17.join(os8.homedir(), ".claude.json");
5996
+ const claudeJsonPath = path17.join(os9.homedir(), ".claude.json");
5987
5997
  let claudeJson = {};
5988
5998
  try {
5989
5999
  claudeJson = JSON.parse(readFileSync11(claudeJsonPath, "utf8"));
@@ -5998,7 +6008,7 @@ function spawnEmployee(employeeName, exeSession2, projectDir, opts) {
5998
6008
  } catch {
5999
6009
  }
6000
6010
  try {
6001
- const settingsDir = path17.join(os8.homedir(), ".claude", "projects");
6011
+ const settingsDir = path17.join(os9.homedir(), ".claude", "projects");
6002
6012
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
6003
6013
  const projSettingsDir = path17.join(settingsDir, normalizedKey);
6004
6014
  const settingsPath = path17.join(projSettingsDir, "settings.json");
@@ -6049,7 +6059,7 @@ function spawnEmployee(employeeName, exeSession2, projectDir, opts) {
6049
6059
  let legacyFallbackWarned = false;
6050
6060
  if (!useExeAgent && !useBinSymlink) {
6051
6061
  const identityPath = path17.join(
6052
- os8.homedir(),
6062
+ os9.homedir(),
6053
6063
  ".exe-os",
6054
6064
  "identity",
6055
6065
  `${employeeName}.md`
@@ -6079,7 +6089,7 @@ function spawnEmployee(employeeName, exeSession2, projectDir, opts) {
6079
6089
  }
6080
6090
  let sessionContextFlag = "";
6081
6091
  try {
6082
- const ctxDir = path17.join(os8.homedir(), ".exe-os", "session-cache");
6092
+ const ctxDir = path17.join(os9.homedir(), ".exe-os", "session-cache");
6083
6093
  mkdirSync7(ctxDir, { recursive: true });
6084
6094
  const ctxFile = path17.join(ctxDir, `session-context-${sessionName}.md`);
6085
6095
  const ctxContent = [
@@ -6240,13 +6250,13 @@ var init_tmux_routing = __esm({
6240
6250
  init_intercom_queue();
6241
6251
  init_plan_limits();
6242
6252
  init_employees();
6243
- SPAWN_LOCK_DIR = path17.join(os8.homedir(), ".exe-os", "spawn-locks");
6244
- SESSION_CACHE = path17.join(os8.homedir(), ".exe-os", "session-cache");
6253
+ SPAWN_LOCK_DIR = path17.join(os9.homedir(), ".exe-os", "spawn-locks");
6254
+ SESSION_CACHE = path17.join(os9.homedir(), ".exe-os", "session-cache");
6245
6255
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
6246
6256
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
6247
6257
  VERIFY_PANE_LINES = 200;
6248
6258
  INTERCOM_DEBOUNCE_MS = 3e4;
6249
- INTERCOM_LOG2 = path17.join(os8.homedir(), ".exe-os", "intercom.log");
6259
+ INTERCOM_LOG2 = path17.join(os9.homedir(), ".exe-os", "intercom.log");
6250
6260
  DEBOUNCE_FILE = path17.join(SESSION_CACHE, "intercom-debounce.json");
6251
6261
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
6252
6262
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
@@ -660,6 +660,7 @@ var init_employees = __esm({
660
660
 
661
661
  // src/lib/exe-daemon-client.ts
662
662
  import net from "net";
663
+ import os5 from "os";
663
664
  import { spawn } from "child_process";
664
665
  import { randomUUID } from "crypto";
665
666
  import { existsSync as existsSync6, unlinkSync as unlinkSync2, readFileSync as readFileSync6, openSync, closeSync, statSync } from "fs";
@@ -723,6 +724,15 @@ function findPackageRoot() {
723
724
  return null;
724
725
  }
725
726
  function spawnDaemon() {
727
+ const freeGB = os5.freemem() / (1024 * 1024 * 1024);
728
+ const totalGB = os5.totalmem() / (1024 * 1024 * 1024);
729
+ if (freeGB < 1.5 && totalGB <= 8) {
730
+ process.stderr.write(
731
+ `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB free / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only. Close other apps and retry.
732
+ `
733
+ );
734
+ return;
735
+ }
726
736
  const pkgRoot = findPackageRoot();
727
737
  if (!pkgRoot) {
728
738
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -2212,7 +2222,7 @@ var init_plan_limits = __esm({
2212
2222
  // src/lib/notifications.ts
2213
2223
  import crypto from "crypto";
2214
2224
  import path9 from "path";
2215
- import os5 from "os";
2225
+ import os6 from "os";
2216
2226
  import {
2217
2227
  readFileSync as readFileSync9,
2218
2228
  readdirSync,
@@ -2369,7 +2379,7 @@ __export(tasks_crud_exports, {
2369
2379
  });
2370
2380
  import crypto3 from "crypto";
2371
2381
  import path10 from "path";
2372
- import os6 from "os";
2382
+ import os7 from "os";
2373
2383
  import { execSync as execSync4 } from "child_process";
2374
2384
  import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
2375
2385
  import { existsSync as existsSync10, readFileSync as readFileSync10 } from "fs";
@@ -2584,7 +2594,7 @@ ${laneWarning}` : laneWarning;
2584
2594
  });
2585
2595
  if (input.baseDir) {
2586
2596
  try {
2587
- const EXE_OS_DIR = path10.join(os6.homedir(), ".exe-os");
2597
+ const EXE_OS_DIR = path10.join(os7.homedir(), ".exe-os");
2588
2598
  const mdPath = path10.join(EXE_OS_DIR, taskFile);
2589
2599
  const mdDir = path10.dirname(mdPath);
2590
2600
  if (!existsSync10(mdDir)) await mkdir3(mdDir, { recursive: true });
@@ -4230,7 +4240,7 @@ __export(tmux_routing_exports, {
4230
4240
  import { execFileSync as execFileSync2, execSync as execSync6 } from "child_process";
4231
4241
  import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, existsSync as existsSync12, appendFileSync } from "fs";
4232
4242
  import path15 from "path";
4233
- import os7 from "os";
4243
+ import os8 from "os";
4234
4244
  import { fileURLToPath as fileURLToPath2 } from "url";
4235
4245
  import { unlinkSync as unlinkSync6 } from "fs";
4236
4246
  function spawnLockPath(sessionName) {
@@ -4644,7 +4654,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4644
4654
  const transport = getTransport();
4645
4655
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
4646
4656
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
4647
- const logDir = path15.join(os7.homedir(), ".exe-os", "session-logs");
4657
+ const logDir = path15.join(os8.homedir(), ".exe-os", "session-logs");
4648
4658
  const logFile = path15.join(logDir, `${instanceLabel}-${Date.now()}.log`);
4649
4659
  if (!existsSync12(logDir)) {
4650
4660
  mkdirSync6(logDir, { recursive: true });
@@ -4660,7 +4670,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4660
4670
  } catch {
4661
4671
  }
4662
4672
  try {
4663
- const claudeJsonPath = path15.join(os7.homedir(), ".claude.json");
4673
+ const claudeJsonPath = path15.join(os8.homedir(), ".claude.json");
4664
4674
  let claudeJson = {};
4665
4675
  try {
4666
4676
  claudeJson = JSON.parse(readFileSync11(claudeJsonPath, "utf8"));
@@ -4675,7 +4685,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4675
4685
  } catch {
4676
4686
  }
4677
4687
  try {
4678
- const settingsDir = path15.join(os7.homedir(), ".claude", "projects");
4688
+ const settingsDir = path15.join(os8.homedir(), ".claude", "projects");
4679
4689
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
4680
4690
  const projSettingsDir = path15.join(settingsDir, normalizedKey);
4681
4691
  const settingsPath = path15.join(projSettingsDir, "settings.json");
@@ -4726,7 +4736,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4726
4736
  let legacyFallbackWarned = false;
4727
4737
  if (!useExeAgent && !useBinSymlink) {
4728
4738
  const identityPath = path15.join(
4729
- os7.homedir(),
4739
+ os8.homedir(),
4730
4740
  ".exe-os",
4731
4741
  "identity",
4732
4742
  `${employeeName}.md`
@@ -4756,7 +4766,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4756
4766
  }
4757
4767
  let sessionContextFlag = "";
4758
4768
  try {
4759
- const ctxDir = path15.join(os7.homedir(), ".exe-os", "session-cache");
4769
+ const ctxDir = path15.join(os8.homedir(), ".exe-os", "session-cache");
4760
4770
  mkdirSync6(ctxDir, { recursive: true });
4761
4771
  const ctxFile = path15.join(ctxDir, `session-context-${sessionName}.md`);
4762
4772
  const ctxContent = [
@@ -4917,13 +4927,13 @@ var init_tmux_routing = __esm({
4917
4927
  init_intercom_queue();
4918
4928
  init_plan_limits();
4919
4929
  init_employees();
4920
- SPAWN_LOCK_DIR = path15.join(os7.homedir(), ".exe-os", "spawn-locks");
4921
- SESSION_CACHE = path15.join(os7.homedir(), ".exe-os", "session-cache");
4930
+ SPAWN_LOCK_DIR = path15.join(os8.homedir(), ".exe-os", "spawn-locks");
4931
+ SESSION_CACHE = path15.join(os8.homedir(), ".exe-os", "session-cache");
4922
4932
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
4923
4933
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
4924
4934
  VERIFY_PANE_LINES = 200;
4925
4935
  INTERCOM_DEBOUNCE_MS = 3e4;
4926
- INTERCOM_LOG2 = path15.join(os7.homedir(), ".exe-os", "intercom.log");
4936
+ INTERCOM_LOG2 = path15.join(os8.homedir(), ".exe-os", "intercom.log");
4927
4937
  DEBOUNCE_FILE = path15.join(SESSION_CACHE, "intercom-debounce.json");
4928
4938
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
4929
4939
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
@@ -4967,9 +4977,9 @@ var init_memory = __esm({
4967
4977
  import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
4968
4978
  import { existsSync as existsSync13 } from "fs";
4969
4979
  import path16 from "path";
4970
- import os8 from "os";
4980
+ import os9 from "os";
4971
4981
  function getKeyDir() {
4972
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path16.join(os8.homedir(), ".exe-os");
4982
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path16.join(os9.homedir(), ".exe-os");
4973
4983
  }
4974
4984
  function getKeyPath() {
4975
4985
  return path16.join(getKeyDir(), "master.key");
@@ -4995,7 +5005,7 @@ async function getMasterKey() {
4995
5005
  const keyPath = getKeyPath();
4996
5006
  if (!existsSync13(keyPath)) {
4997
5007
  process.stderr.write(
4998
- `[keychain] Key not found at ${keyPath} (HOME=${os8.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
5008
+ `[keychain] Key not found at ${keyPath} (HOME=${os9.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
4999
5009
  `
5000
5010
  );
5001
5011
  return null;