@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
package/dist/index.js CHANGED
@@ -914,6 +914,7 @@ var init_db_retry = __esm({
914
914
 
915
915
  // src/lib/exe-daemon-client.ts
916
916
  import net from "net";
917
+ import os6 from "os";
917
918
  import { spawn } from "child_process";
918
919
  import { randomUUID as randomUUID2 } from "crypto";
919
920
  import { existsSync as existsSync6, unlinkSync as unlinkSync2, readFileSync as readFileSync6, openSync, closeSync, statSync } from "fs";
@@ -977,6 +978,15 @@ function findPackageRoot() {
977
978
  return null;
978
979
  }
979
980
  function spawnDaemon() {
981
+ const freeGB = os6.freemem() / (1024 * 1024 * 1024);
982
+ const totalGB = os6.totalmem() / (1024 * 1024 * 1024);
983
+ if (freeGB < 1.5 && totalGB <= 8) {
984
+ process.stderr.write(
985
+ `[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.
986
+ `
987
+ );
988
+ return;
989
+ }
980
990
  const pkgRoot = findPackageRoot();
981
991
  if (!pkgRoot) {
982
992
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -2562,7 +2572,7 @@ var init_plan_limits = __esm({
2562
2572
  // src/lib/notifications.ts
2563
2573
  import crypto from "crypto";
2564
2574
  import path10 from "path";
2565
- import os6 from "os";
2575
+ import os7 from "os";
2566
2576
  import {
2567
2577
  readFileSync as readFileSync9,
2568
2578
  readdirSync,
@@ -2732,7 +2742,7 @@ var init_state_bus = __esm({
2732
2742
  // src/lib/tasks-crud.ts
2733
2743
  import crypto3 from "crypto";
2734
2744
  import path11 from "path";
2735
- import os7 from "os";
2745
+ import os8 from "os";
2736
2746
  import { execSync as execSync5 } from "child_process";
2737
2747
  import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
2738
2748
  import { existsSync as existsSync10, readFileSync as readFileSync10 } from "fs";
@@ -2947,7 +2957,7 @@ ${laneWarning}` : laneWarning;
2947
2957
  });
2948
2958
  if (input.baseDir) {
2949
2959
  try {
2950
- const EXE_OS_DIR = path11.join(os7.homedir(), ".exe-os");
2960
+ const EXE_OS_DIR = path11.join(os8.homedir(), ".exe-os");
2951
2961
  const mdPath = path11.join(EXE_OS_DIR, taskFile);
2952
2962
  const mdDir = path11.dirname(mdPath);
2953
2963
  if (!existsSync10(mdDir)) await mkdir3(mdDir, { recursive: true });
@@ -4655,7 +4665,7 @@ __export(tmux_routing_exports, {
4655
4665
  import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
4656
4666
  import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, existsSync as existsSync12, appendFileSync } from "fs";
4657
4667
  import path16 from "path";
4658
- import os8 from "os";
4668
+ import os9 from "os";
4659
4669
  import { fileURLToPath as fileURLToPath2 } from "url";
4660
4670
  import { unlinkSync as unlinkSync6 } from "fs";
4661
4671
  function spawnLockPath(sessionName) {
@@ -5069,7 +5079,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5069
5079
  const transport = getTransport();
5070
5080
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
5071
5081
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
5072
- const logDir = path16.join(os8.homedir(), ".exe-os", "session-logs");
5082
+ const logDir = path16.join(os9.homedir(), ".exe-os", "session-logs");
5073
5083
  const logFile = path16.join(logDir, `${instanceLabel}-${Date.now()}.log`);
5074
5084
  if (!existsSync12(logDir)) {
5075
5085
  mkdirSync6(logDir, { recursive: true });
@@ -5085,7 +5095,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5085
5095
  } catch {
5086
5096
  }
5087
5097
  try {
5088
- const claudeJsonPath = path16.join(os8.homedir(), ".claude.json");
5098
+ const claudeJsonPath = path16.join(os9.homedir(), ".claude.json");
5089
5099
  let claudeJson = {};
5090
5100
  try {
5091
5101
  claudeJson = JSON.parse(readFileSync11(claudeJsonPath, "utf8"));
@@ -5100,7 +5110,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5100
5110
  } catch {
5101
5111
  }
5102
5112
  try {
5103
- const settingsDir = path16.join(os8.homedir(), ".claude", "projects");
5113
+ const settingsDir = path16.join(os9.homedir(), ".claude", "projects");
5104
5114
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
5105
5115
  const projSettingsDir = path16.join(settingsDir, normalizedKey);
5106
5116
  const settingsPath = path16.join(projSettingsDir, "settings.json");
@@ -5151,7 +5161,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5151
5161
  let legacyFallbackWarned = false;
5152
5162
  if (!useExeAgent && !useBinSymlink) {
5153
5163
  const identityPath = path16.join(
5154
- os8.homedir(),
5164
+ os9.homedir(),
5155
5165
  ".exe-os",
5156
5166
  "identity",
5157
5167
  `${employeeName}.md`
@@ -5181,7 +5191,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5181
5191
  }
5182
5192
  let sessionContextFlag = "";
5183
5193
  try {
5184
- const ctxDir = path16.join(os8.homedir(), ".exe-os", "session-cache");
5194
+ const ctxDir = path16.join(os9.homedir(), ".exe-os", "session-cache");
5185
5195
  mkdirSync6(ctxDir, { recursive: true });
5186
5196
  const ctxFile = path16.join(ctxDir, `session-context-${sessionName}.md`);
5187
5197
  const ctxContent = [
@@ -5342,13 +5352,13 @@ var init_tmux_routing = __esm({
5342
5352
  init_intercom_queue();
5343
5353
  init_plan_limits();
5344
5354
  init_employees();
5345
- SPAWN_LOCK_DIR = path16.join(os8.homedir(), ".exe-os", "spawn-locks");
5346
- SESSION_CACHE = path16.join(os8.homedir(), ".exe-os", "session-cache");
5355
+ SPAWN_LOCK_DIR = path16.join(os9.homedir(), ".exe-os", "spawn-locks");
5356
+ SESSION_CACHE = path16.join(os9.homedir(), ".exe-os", "session-cache");
5347
5357
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
5348
5358
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
5349
5359
  VERIFY_PANE_LINES = 200;
5350
5360
  INTERCOM_DEBOUNCE_MS = 3e4;
5351
- INTERCOM_LOG2 = path16.join(os8.homedir(), ".exe-os", "intercom.log");
5361
+ INTERCOM_LOG2 = path16.join(os9.homedir(), ".exe-os", "intercom.log");
5352
5362
  DEBOUNCE_FILE = path16.join(SESSION_CACHE, "intercom-debounce.json");
5353
5363
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
5354
5364
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
@@ -5368,9 +5378,9 @@ var init_memory = __esm({
5368
5378
  import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
5369
5379
  import { existsSync as existsSync13 } from "fs";
5370
5380
  import path17 from "path";
5371
- import os9 from "os";
5381
+ import os10 from "os";
5372
5382
  function getKeyDir() {
5373
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path17.join(os9.homedir(), ".exe-os");
5383
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path17.join(os10.homedir(), ".exe-os");
5374
5384
  }
5375
5385
  function getKeyPath() {
5376
5386
  return path17.join(getKeyDir(), "master.key");
@@ -5396,7 +5406,7 @@ async function getMasterKey() {
5396
5406
  const keyPath = getKeyPath();
5397
5407
  if (!existsSync13(keyPath)) {
5398
5408
  process.stderr.write(
5399
- `[keychain] Key not found at ${keyPath} (HOME=${os9.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
5409
+ `[keychain] Key not found at ${keyPath} (HOME=${os10.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
5400
5410
  `
5401
5411
  );
5402
5412
  return null;
@@ -13645,12 +13655,12 @@ var SlackAdapter = class {
13645
13655
  // src/gateway/adapters/imessage.ts
13646
13656
  import { execFile } from "child_process";
13647
13657
  import { promisify } from "util";
13648
- import os10 from "os";
13658
+ import os11 from "os";
13649
13659
  import path19 from "path";
13650
13660
  var execFileAsync = promisify(execFile);
13651
13661
  var POLL_INTERVAL_MS = 5e3;
13652
13662
  var MESSAGES_DB_PATH = path19.join(
13653
- process.env.HOME ?? os10.homedir(),
13663
+ process.env.HOME ?? os11.homedir(),
13654
13664
  "Library/Messages/chat.db"
13655
13665
  );
13656
13666
  var IMessageAdapter = class {
@@ -14496,8 +14506,8 @@ async function ensureCRMContact(info) {
14496
14506
  import { readFileSync as readFileSync13, writeFileSync as writeFileSync8, existsSync as existsSync15, mkdirSync as mkdirSync9 } from "fs";
14497
14507
  import { randomUUID as randomUUID15 } from "crypto";
14498
14508
  import path20 from "path";
14499
- import os11 from "os";
14500
- var TRIGGERS_PATH = path20.join(os11.homedir(), ".exe-os", "triggers.json");
14509
+ import os12 from "os";
14510
+ var TRIGGERS_PATH = path20.join(os12.homedir(), ".exe-os", "triggers.json");
14501
14511
  var GRAPH_API_VERSION = "v21.0";
14502
14512
  function substituteTemplate(template, record) {
14503
14513
  return template.replace(
@@ -248,6 +248,7 @@ var init_employees = __esm({
248
248
 
249
249
  // src/lib/exe-daemon-client.ts
250
250
  import net from "net";
251
+ import os3 from "os";
251
252
  import { spawn } from "child_process";
252
253
  import { randomUUID } from "crypto";
253
254
  import { existsSync as existsSync3, unlinkSync as unlinkSync2, readFileSync as readFileSync3, openSync, closeSync, statSync } from "fs";
@@ -311,6 +312,15 @@ function findPackageRoot() {
311
312
  return null;
312
313
  }
313
314
  function spawnDaemon() {
315
+ const freeGB = os3.freemem() / (1024 * 1024 * 1024);
316
+ const totalGB = os3.totalmem() / (1024 * 1024 * 1024);
317
+ if (freeGB < 1.5 && totalGB <= 8) {
318
+ process.stderr.write(
319
+ `[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.
320
+ `
321
+ );
322
+ return;
323
+ }
314
324
  const pkgRoot = findPackageRoot();
315
325
  if (!pkgRoot) {
316
326
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -1934,9 +1944,9 @@ __export(keychain_exports, {
1934
1944
  import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
1935
1945
  import { existsSync as existsSync6 } from "fs";
1936
1946
  import path6 from "path";
1937
- import os3 from "os";
1947
+ import os4 from "os";
1938
1948
  function getKeyDir() {
1939
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path6.join(os3.homedir(), ".exe-os");
1949
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path6.join(os4.homedir(), ".exe-os");
1940
1950
  }
1941
1951
  function getKeyPath() {
1942
1952
  return path6.join(getKeyDir(), "master.key");
@@ -1962,7 +1972,7 @@ async function getMasterKey() {
1962
1972
  const keyPath = getKeyPath();
1963
1973
  if (!existsSync6(keyPath)) {
1964
1974
  process.stderr.write(
1965
- `[keychain] Key not found at ${keyPath} (HOME=${os3.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
1975
+ `[keychain] Key not found at ${keyPath} (HOME=${os4.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
1966
1976
  `
1967
1977
  );
1968
1978
  return null;
@@ -101,6 +101,7 @@ var init_config = __esm({
101
101
 
102
102
  // src/lib/exe-daemon-client.ts
103
103
  import net from "net";
104
+ import os3 from "os";
104
105
  import { spawn } from "child_process";
105
106
  import { randomUUID } from "crypto";
106
107
  import { existsSync as existsSync3, unlinkSync as unlinkSync2, readFileSync as readFileSync3, openSync, closeSync, statSync } from "fs";
@@ -164,6 +165,15 @@ function findPackageRoot() {
164
165
  return null;
165
166
  }
166
167
  function spawnDaemon() {
168
+ const freeGB = os3.freemem() / (1024 * 1024 * 1024);
169
+ const totalGB = os3.totalmem() / (1024 * 1024 * 1024);
170
+ if (freeGB < 1.5 && totalGB <= 8) {
171
+ process.stderr.write(
172
+ `[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.
173
+ `
174
+ );
175
+ return;
176
+ }
167
177
  const pkgRoot = findPackageRoot();
168
178
  if (!pkgRoot) {
169
179
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -1,5 +1,6 @@
1
1
  // src/lib/exe-daemon-client.ts
2
2
  import net from "net";
3
+ import os2 from "os";
3
4
  import { spawn } from "child_process";
4
5
  import { randomUUID } from "crypto";
5
6
  import { existsSync as existsSync2, unlinkSync, readFileSync as readFileSync2, openSync, closeSync, statSync } from "fs";
@@ -161,6 +162,15 @@ function findPackageRoot() {
161
162
  return null;
162
163
  }
163
164
  function spawnDaemon() {
165
+ const freeGB = os2.freemem() / (1024 * 1024 * 1024);
166
+ const totalGB = os2.totalmem() / (1024 * 1024 * 1024);
167
+ if (freeGB < 1.5 && totalGB <= 8) {
168
+ process.stderr.write(
169
+ `[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.
170
+ `
171
+ );
172
+ return;
173
+ }
164
174
  const pkgRoot = findPackageRoot();
165
175
  if (!pkgRoot) {
166
176
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -193,6 +193,7 @@ var init_employees = __esm({
193
193
 
194
194
  // src/lib/exe-daemon-client.ts
195
195
  import net from "net";
196
+ import os3 from "os";
196
197
  import { spawn } from "child_process";
197
198
  import { randomUUID } from "crypto";
198
199
  import { existsSync as existsSync3, unlinkSync as unlinkSync2, readFileSync as readFileSync3, openSync, closeSync, statSync } from "fs";
@@ -256,6 +257,15 @@ function findPackageRoot() {
256
257
  return null;
257
258
  }
258
259
  function spawnDaemon() {
260
+ const freeGB = os3.freemem() / (1024 * 1024 * 1024);
261
+ const totalGB = os3.totalmem() / (1024 * 1024 * 1024);
262
+ if (freeGB < 1.5 && totalGB <= 8) {
263
+ process.stderr.write(
264
+ `[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.
265
+ `
266
+ );
267
+ return;
268
+ }
259
269
  const pkgRoot = findPackageRoot();
260
270
  if (!pkgRoot) {
261
271
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -1644,7 +1654,7 @@ var init_database = __esm({
1644
1654
  // src/lib/device-registry.ts
1645
1655
  init_config();
1646
1656
  import crypto from "crypto";
1647
- import os3 from "os";
1657
+ import os4 from "os";
1648
1658
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync, existsSync as existsSync4 } from "fs";
1649
1659
  import path4 from "path";
1650
1660
  var DEVICE_JSON_PATH = path4.join(EXE_AI_DIR, "device.json");
@@ -1659,7 +1669,7 @@ function getDeviceInfo() {
1659
1669
  } catch {
1660
1670
  }
1661
1671
  }
1662
- const hostname = os3.hostname();
1672
+ const hostname = os4.hostname();
1663
1673
  const info = {
1664
1674
  deviceId: crypto.randomUUID(),
1665
1675
  friendlyName: hostname.replace(/\./g, "-").toLowerCase(),
@@ -254,6 +254,7 @@ var EMBEDDING_DIM = 1024;
254
254
  // src/lib/exe-daemon-client.ts
255
255
  init_config();
256
256
  import net from "net";
257
+ import os2 from "os";
257
258
  import { spawn } from "child_process";
258
259
  import { randomUUID } from "crypto";
259
260
  import { existsSync as existsSync2, unlinkSync, readFileSync as readFileSync2, openSync, closeSync, statSync } from "fs";
@@ -330,6 +331,15 @@ function findPackageRoot() {
330
331
  return null;
331
332
  }
332
333
  function spawnDaemon() {
334
+ const freeGB = os2.freemem() / (1024 * 1024 * 1024);
335
+ const totalGB = os2.totalmem() / (1024 * 1024 * 1024);
336
+ if (freeGB < 1.5 && totalGB <= 8) {
337
+ process.stderr.write(
338
+ `[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.
339
+ `
340
+ );
341
+ return;
342
+ }
333
343
  const pkgRoot = findPackageRoot();
334
344
  if (!pkgRoot) {
335
345
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -1,5 +1,6 @@
1
1
  // src/lib/exe-daemon-client.ts
2
2
  import net from "net";
3
+ import os2 from "os";
3
4
  import { spawn } from "child_process";
4
5
  import { randomUUID } from "crypto";
5
6
  import { existsSync as existsSync2, unlinkSync, readFileSync as readFileSync2, openSync, closeSync, statSync } from "fs";
@@ -163,6 +164,15 @@ function findPackageRoot() {
163
164
  return null;
164
165
  }
165
166
  function spawnDaemon() {
167
+ const freeGB = os2.freemem() / (1024 * 1024 * 1024);
168
+ const totalGB = os2.totalmem() / (1024 * 1024 * 1024);
169
+ if (freeGB < 1.5 && totalGB <= 8) {
170
+ process.stderr.write(
171
+ `[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.
172
+ `
173
+ );
174
+ return;
175
+ }
166
176
  const pkgRoot = findPackageRoot();
167
177
  if (!pkgRoot) {
168
178
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -1075,6 +1075,7 @@ var init_employees = __esm({
1075
1075
 
1076
1076
  // src/lib/exe-daemon-client.ts
1077
1077
  import net from "net";
1078
+ import os5 from "os";
1078
1079
  import { spawn } from "child_process";
1079
1080
  import { randomUUID } from "crypto";
1080
1081
  import { existsSync as existsSync6, unlinkSync as unlinkSync2, readFileSync as readFileSync6, openSync, closeSync, statSync } from "fs";
@@ -1138,6 +1139,15 @@ function findPackageRoot() {
1138
1139
  return null;
1139
1140
  }
1140
1141
  function spawnDaemon() {
1142
+ const freeGB = os5.freemem() / (1024 * 1024 * 1024);
1143
+ const totalGB = os5.totalmem() / (1024 * 1024 * 1024);
1144
+ if (freeGB < 1.5 && totalGB <= 8) {
1145
+ process.stderr.write(
1146
+ `[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.
1147
+ `
1148
+ );
1149
+ return;
1150
+ }
1141
1151
  const pkgRoot = findPackageRoot();
1142
1152
  if (!pkgRoot) {
1143
1153
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
@@ -2659,7 +2669,7 @@ var init_plan_limits = __esm({
2659
2669
  // src/lib/notifications.ts
2660
2670
  import crypto from "crypto";
2661
2671
  import path9 from "path";
2662
- import os5 from "os";
2672
+ import os6 from "os";
2663
2673
  import {
2664
2674
  readFileSync as readFileSync9,
2665
2675
  readdirSync,
@@ -2899,7 +2909,7 @@ var init_state_bus = __esm({
2899
2909
  // src/lib/tasks-crud.ts
2900
2910
  import crypto3 from "crypto";
2901
2911
  import path10 from "path";
2902
- import os6 from "os";
2912
+ import os7 from "os";
2903
2913
  import { execSync as execSync5 } from "child_process";
2904
2914
  import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
2905
2915
  import { existsSync as existsSync10, readFileSync as readFileSync10 } from "fs";
@@ -3114,7 +3124,7 @@ ${laneWarning}` : laneWarning;
3114
3124
  });
3115
3125
  if (input.baseDir) {
3116
3126
  try {
3117
- const EXE_OS_DIR = path10.join(os6.homedir(), ".exe-os");
3127
+ const EXE_OS_DIR = path10.join(os7.homedir(), ".exe-os");
3118
3128
  const mdPath = path10.join(EXE_OS_DIR, taskFile);
3119
3129
  const mdDir = path10.dirname(mdPath);
3120
3130
  if (!existsSync10(mdDir)) await mkdir3(mdDir, { recursive: true });
@@ -4859,7 +4869,7 @@ __export(tmux_routing_exports, {
4859
4869
  import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
4860
4870
  import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, existsSync as existsSync12, appendFileSync } from "fs";
4861
4871
  import path15 from "path";
4862
- import os7 from "os";
4872
+ import os8 from "os";
4863
4873
  import { fileURLToPath as fileURLToPath2 } from "url";
4864
4874
  import { unlinkSync as unlinkSync6 } from "fs";
4865
4875
  function spawnLockPath(sessionName) {
@@ -5273,7 +5283,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5273
5283
  const transport = getTransport();
5274
5284
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
5275
5285
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
5276
- const logDir = path15.join(os7.homedir(), ".exe-os", "session-logs");
5286
+ const logDir = path15.join(os8.homedir(), ".exe-os", "session-logs");
5277
5287
  const logFile = path15.join(logDir, `${instanceLabel}-${Date.now()}.log`);
5278
5288
  if (!existsSync12(logDir)) {
5279
5289
  mkdirSync6(logDir, { recursive: true });
@@ -5289,7 +5299,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5289
5299
  } catch {
5290
5300
  }
5291
5301
  try {
5292
- const claudeJsonPath = path15.join(os7.homedir(), ".claude.json");
5302
+ const claudeJsonPath = path15.join(os8.homedir(), ".claude.json");
5293
5303
  let claudeJson = {};
5294
5304
  try {
5295
5305
  claudeJson = JSON.parse(readFileSync11(claudeJsonPath, "utf8"));
@@ -5304,7 +5314,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5304
5314
  } catch {
5305
5315
  }
5306
5316
  try {
5307
- const settingsDir = path15.join(os7.homedir(), ".claude", "projects");
5317
+ const settingsDir = path15.join(os8.homedir(), ".claude", "projects");
5308
5318
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
5309
5319
  const projSettingsDir = path15.join(settingsDir, normalizedKey);
5310
5320
  const settingsPath = path15.join(projSettingsDir, "settings.json");
@@ -5355,7 +5365,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5355
5365
  let legacyFallbackWarned = false;
5356
5366
  if (!useExeAgent && !useBinSymlink) {
5357
5367
  const identityPath = path15.join(
5358
- os7.homedir(),
5368
+ os8.homedir(),
5359
5369
  ".exe-os",
5360
5370
  "identity",
5361
5371
  `${employeeName}.md`
@@ -5385,7 +5395,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5385
5395
  }
5386
5396
  let sessionContextFlag = "";
5387
5397
  try {
5388
- const ctxDir = path15.join(os7.homedir(), ".exe-os", "session-cache");
5398
+ const ctxDir = path15.join(os8.homedir(), ".exe-os", "session-cache");
5389
5399
  mkdirSync6(ctxDir, { recursive: true });
5390
5400
  const ctxFile = path15.join(ctxDir, `session-context-${sessionName}.md`);
5391
5401
  const ctxContent = [
@@ -5546,13 +5556,13 @@ var init_tmux_routing = __esm({
5546
5556
  init_intercom_queue();
5547
5557
  init_plan_limits();
5548
5558
  init_employees();
5549
- SPAWN_LOCK_DIR = path15.join(os7.homedir(), ".exe-os", "spawn-locks");
5550
- SESSION_CACHE = path15.join(os7.homedir(), ".exe-os", "session-cache");
5559
+ SPAWN_LOCK_DIR = path15.join(os8.homedir(), ".exe-os", "spawn-locks");
5560
+ SESSION_CACHE = path15.join(os8.homedir(), ".exe-os", "session-cache");
5551
5561
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
5552
5562
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
5553
5563
  VERIFY_PANE_LINES = 200;
5554
5564
  INTERCOM_DEBOUNCE_MS = 3e4;
5555
- INTERCOM_LOG2 = path15.join(os7.homedir(), ".exe-os", "intercom.log");
5565
+ INTERCOM_LOG2 = path15.join(os8.homedir(), ".exe-os", "intercom.log");
5556
5566
  DEBOUNCE_FILE = path15.join(SESSION_CACHE, "intercom-debounce.json");
5557
5567
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
5558
5568
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
@@ -5838,7 +5848,7 @@ __export(agent_signals_exports, {
5838
5848
  hasUnreadInbox: () => hasUnreadInbox
5839
5849
  });
5840
5850
  import { readFileSync as readFileSync12, existsSync as existsSync13 } from "fs";
5841
- import os8 from "os";
5851
+ import os9 from "os";
5842
5852
  import path16 from "path";
5843
5853
  async function hasOpenTasks(client, agentId) {
5844
5854
  try {
@@ -5881,7 +5891,7 @@ async function hasUnreadInbox(client, agentId) {
5881
5891
  return CONSERVATIVE_ON_ERROR;
5882
5892
  }
5883
5893
  }
5884
- function hadRecentIntercomAck(sessionName, windowMs, nowMs = Date.now(), intercomLog = path16.join(os8.homedir(), ".exe-os", "intercom.log")) {
5894
+ function hadRecentIntercomAck(sessionName, windowMs, nowMs = Date.now(), intercomLog = path16.join(os9.homedir(), ".exe-os", "intercom.log")) {
5885
5895
  if (!existsSync13(intercomLog)) return false;
5886
5896
  try {
5887
5897
  const raw = readFileSync12(intercomLog, "utf8");
@@ -6507,9 +6517,9 @@ __export(keychain_exports, {
6507
6517
  import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
6508
6518
  import { existsSync as existsSync15 } from "fs";
6509
6519
  import path17 from "path";
6510
- import os9 from "os";
6520
+ import os10 from "os";
6511
6521
  function getKeyDir() {
6512
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path17.join(os9.homedir(), ".exe-os");
6522
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path17.join(os10.homedir(), ".exe-os");
6513
6523
  }
6514
6524
  function getKeyPath() {
6515
6525
  return path17.join(getKeyDir(), "master.key");
@@ -6535,7 +6545,7 @@ async function getMasterKey() {
6535
6545
  const keyPath = getKeyPath();
6536
6546
  if (!existsSync15(keyPath)) {
6537
6547
  process.stderr.write(
6538
- `[keychain] Key not found at ${keyPath} (HOME=${os9.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
6548
+ `[keychain] Key not found at ${keyPath} (HOME=${os10.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
6539
6549
  `
6540
6550
  );
6541
6551
  return null;
@@ -9072,7 +9082,7 @@ import { readdir } from "fs/promises";
9072
9082
  import { createReadStream } from "fs";
9073
9083
  import { createInterface } from "readline";
9074
9084
  import path19 from "path";
9075
- import os10 from "os";
9085
+ import os11 from "os";
9076
9086
  function getPricing(model) {
9077
9087
  if (MODEL_PRICING[model]) return MODEL_PRICING[model];
9078
9088
  const stripped = model.replace(/-\d{8}$/, "");
@@ -9095,7 +9105,7 @@ async function getAgentSpend(period = "7d") {
9095
9105
  for (const row of result.rows) {
9096
9106
  sessionAgent.set(row.session_uuid, row.agent_id);
9097
9107
  }
9098
- const claudeDir = path19.join(os10.homedir(), ".claude", "projects");
9108
+ const claudeDir = path19.join(os11.homedir(), ".claude", "projects");
9099
9109
  let projectDirs = [];
9100
9110
  try {
9101
9111
  const entries = await readdir(claudeDir);
@@ -9302,7 +9312,7 @@ __export(device_registry_exports, {
9302
9312
  setFriendlyName: () => setFriendlyName
9303
9313
  });
9304
9314
  import crypto8 from "crypto";
9305
- import os11 from "os";
9315
+ import os12 from "os";
9306
9316
  import { readFileSync as readFileSync15, writeFileSync as writeFileSync9, mkdirSync as mkdirSync8, existsSync as existsSync17 } from "fs";
9307
9317
  import path21 from "path";
9308
9318
  function getDeviceInfo() {
@@ -9316,7 +9326,7 @@ function getDeviceInfo() {
9316
9326
  } catch {
9317
9327
  }
9318
9328
  }
9319
- const hostname = os11.hostname();
9329
+ const hostname = os12.hostname();
9320
9330
  const info = {
9321
9331
  deviceId: crypto8.randomUUID(),
9322
9332
  friendlyName: hostname.replace(/\./g, "-").toLowerCase(),
@@ -2660,6 +2660,7 @@ var init_reranker = __esm({
2660
2660
 
2661
2661
  // src/lib/exe-daemon-client.ts
2662
2662
  import net from "net";
2663
+ import os4 from "os";
2663
2664
  import { spawn } from "child_process";
2664
2665
  import { randomUUID as randomUUID2 } from "crypto";
2665
2666
  import { existsSync as existsSync6, unlinkSync as unlinkSync2, readFileSync as readFileSync3, openSync, closeSync, statSync } from "fs";
@@ -2723,6 +2724,15 @@ function findPackageRoot() {
2723
2724
  return null;
2724
2725
  }
2725
2726
  function spawnDaemon() {
2727
+ const freeGB = os4.freemem() / (1024 * 1024 * 1024);
2728
+ const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
2729
+ if (freeGB < 1.5 && totalGB <= 8) {
2730
+ process.stderr.write(
2731
+ `[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.
2732
+ `
2733
+ );
2734
+ return;
2735
+ }
2726
2736
  const pkgRoot = findPackageRoot();
2727
2737
  if (!pkgRoot) {
2728
2738
  process.stderr.write("[exed-client] WARN: cannot find package root\n");