@askexenow/exe-os 0.9.97 → 0.9.99

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 (81) hide show
  1. package/dist/bin/agentic-ontology-backfill.js +7 -29
  2. package/dist/bin/agentic-reflection-backfill.js +7 -29
  3. package/dist/bin/agentic-semantic-label.js +7 -29
  4. package/dist/bin/backfill-conversations.js +7 -29
  5. package/dist/bin/backfill-responses.js +7 -29
  6. package/dist/bin/backfill-vectors.js +7 -29
  7. package/dist/bin/bulk-sync-postgres.js +7 -29
  8. package/dist/bin/cleanup-stale-review-tasks.js +7 -29
  9. package/dist/bin/cli.js +11 -33
  10. package/dist/bin/exe-agent.js +7 -0
  11. package/dist/bin/exe-assign.js +7 -29
  12. package/dist/bin/exe-boot.js +7 -29
  13. package/dist/bin/exe-call.js +7 -0
  14. package/dist/bin/exe-cloud.js +7 -29
  15. package/dist/bin/exe-dispatch.js +7 -29
  16. package/dist/bin/exe-doctor.js +7 -29
  17. package/dist/bin/exe-export-behaviors.js +7 -29
  18. package/dist/bin/exe-forget.js +7 -29
  19. package/dist/bin/exe-gateway.js +7 -29
  20. package/dist/bin/exe-heartbeat.js +7 -29
  21. package/dist/bin/exe-kill.js +7 -29
  22. package/dist/bin/exe-launch-agent.js +7 -29
  23. package/dist/bin/exe-new-employee.js +7 -0
  24. package/dist/bin/exe-pending-messages.js +7 -29
  25. package/dist/bin/exe-pending-notifications.js +7 -29
  26. package/dist/bin/exe-pending-reviews.js +7 -29
  27. package/dist/bin/exe-rename.js +7 -29
  28. package/dist/bin/exe-review.js +7 -29
  29. package/dist/bin/exe-search.js +7 -29
  30. package/dist/bin/exe-session-cleanup.js +7 -29
  31. package/dist/bin/exe-start-codex.js +7 -29
  32. package/dist/bin/exe-start-opencode.js +7 -29
  33. package/dist/bin/exe-status.js +7 -29
  34. package/dist/bin/exe-team.js +7 -29
  35. package/dist/bin/git-sweep.js +7 -29
  36. package/dist/bin/graph-backfill.js +7 -29
  37. package/dist/bin/graph-export.js +7 -29
  38. package/dist/bin/intercom-check.js +7 -29
  39. package/dist/bin/scan-tasks.js +7 -29
  40. package/dist/bin/setup.js +11 -33
  41. package/dist/bin/shard-migrate.js +7 -29
  42. package/dist/gateway/index.js +7 -29
  43. package/dist/hooks/bug-report-worker.js +7 -29
  44. package/dist/hooks/codex-stop-task-finalizer.js +7 -29
  45. package/dist/hooks/commit-complete.js +7 -29
  46. package/dist/hooks/error-recall.js +7 -29
  47. package/dist/hooks/ingest.js +7 -29
  48. package/dist/hooks/instructions-loaded.js +7 -29
  49. package/dist/hooks/notification.js +7 -29
  50. package/dist/hooks/post-compact.js +7 -29
  51. package/dist/hooks/post-tool-combined.js +7 -29
  52. package/dist/hooks/pre-compact.js +7 -29
  53. package/dist/hooks/pre-tool-use.js +7 -29
  54. package/dist/hooks/prompt-submit.js +7 -29
  55. package/dist/hooks/session-end.js +7 -29
  56. package/dist/hooks/session-start.js +7 -29
  57. package/dist/hooks/stop.js +7 -29
  58. package/dist/hooks/subagent-stop.js +7 -29
  59. package/dist/hooks/summary-worker.js +7 -29
  60. package/dist/index.js +7 -29
  61. package/dist/lib/cloud-sync.js +0 -29
  62. package/dist/lib/database.js +0 -35
  63. package/dist/lib/db-daemon-client.js +0 -36
  64. package/dist/lib/db.js +0 -35
  65. package/dist/lib/device-registry.js +0 -35
  66. package/dist/lib/embedder.js +0 -35
  67. package/dist/lib/employee-templates.js +7 -0
  68. package/dist/lib/exe-daemon-client.js +0 -36
  69. package/dist/lib/exe-daemon.js +7 -29
  70. package/dist/lib/hybrid-search.js +7 -29
  71. package/dist/lib/schedules.js +7 -29
  72. package/dist/lib/skill-learning.js +0 -35
  73. package/dist/lib/store.js +7 -29
  74. package/dist/lib/tasks.js +0 -29
  75. package/dist/lib/tmux-routing.js +0 -29
  76. package/dist/mcp/server.js +7 -29
  77. package/dist/mcp/tools/create-task.js +0 -29
  78. package/dist/mcp/tools/update-task.js +0 -29
  79. package/dist/runtime/index.js +7 -29
  80. package/dist/tui/App.js +7 -29
  81. package/package.json +1 -1
@@ -1370,40 +1370,11 @@ function findPackageRoot() {
1370
1370
  }
1371
1371
  return null;
1372
1372
  }
1373
- function getAvailableMemoryGB() {
1374
- if (process.platform === "darwin") {
1375
- try {
1376
- const { execSync: execSync7 } = __require("child_process");
1377
- const vmstat = execSync7("vm_stat", { encoding: "utf8" });
1378
- const pageSize = 16384;
1379
- const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
1380
- const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
1381
- const free = vmstat.match(/Pages free:\s+(\d+)/);
1382
- const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
1383
- const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
1384
- const freePages = free ? parseInt(free[1], 10) : 0;
1385
- const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
1386
- const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
1387
- return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
1388
- } catch {
1389
- return os6.freemem() / (1024 * 1024 * 1024);
1390
- }
1391
- }
1392
- return os6.freemem() / (1024 * 1024 * 1024);
1393
- }
1394
1373
  function spawnDaemon() {
1395
- const freeGB = getAvailableMemoryGB();
1396
1374
  const totalGB = os6.totalmem() / (1024 * 1024 * 1024);
1397
1375
  if (totalGB <= 8) {
1398
1376
  process.stderr.write(
1399
1377
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
1400
- `
1401
- );
1402
- return;
1403
- }
1404
- if (totalGB <= 16 && freeGB < 2) {
1405
- process.stderr.write(
1406
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
1407
1378
  `
1408
1379
  );
1409
1380
  return;
@@ -4806,6 +4777,13 @@ var init_platform_procedures = __esm({
4806
4777
  priority: "p0",
4807
4778
  content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
4808
4779
  },
4780
+ // --- Encryption key + cloud sync ---
4781
+ {
4782
+ title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
4783
+ domain: "security",
4784
+ priority: "p0",
4785
+ content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
4786
+ },
4809
4787
  // --- MCP is the ONLY data interface ---
4810
4788
  {
4811
4789
  title: "MCP disconnect \u2014 ask the user, never work around it",
@@ -1192,40 +1192,11 @@ function findPackageRoot() {
1192
1192
  }
1193
1193
  return null;
1194
1194
  }
1195
- function getAvailableMemoryGB() {
1196
- if (process.platform === "darwin") {
1197
- try {
1198
- const { execSync: execSync7 } = __require("child_process");
1199
- const vmstat = execSync7("vm_stat", { encoding: "utf8" });
1200
- const pageSize = 16384;
1201
- const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
1202
- const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
1203
- const free = vmstat.match(/Pages free:\s+(\d+)/);
1204
- const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
1205
- const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
1206
- const freePages = free ? parseInt(free[1], 10) : 0;
1207
- const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
1208
- const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
1209
- return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
1210
- } catch {
1211
- return os4.freemem() / (1024 * 1024 * 1024);
1212
- }
1213
- }
1214
- return os4.freemem() / (1024 * 1024 * 1024);
1215
- }
1216
1195
  function spawnDaemon() {
1217
- const freeGB = getAvailableMemoryGB();
1218
1196
  const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
1219
1197
  if (totalGB <= 8) {
1220
1198
  process.stderr.write(
1221
1199
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
1222
- `
1223
- );
1224
- return;
1225
- }
1226
- if (totalGB <= 16 && freeGB < 2) {
1227
- process.stderr.write(
1228
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
1229
1200
  `
1230
1201
  );
1231
1202
  return;
@@ -4363,6 +4334,13 @@ var init_platform_procedures = __esm({
4363
4334
  priority: "p0",
4364
4335
  content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
4365
4336
  },
4337
+ // --- Encryption key + cloud sync ---
4338
+ {
4339
+ title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
4340
+ domain: "security",
4341
+ priority: "p0",
4342
+ content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
4343
+ },
4366
4344
  // --- MCP is the ONLY data interface ---
4367
4345
  {
4368
4346
  title: "MCP disconnect \u2014 ask the user, never work around it",
package/dist/index.js CHANGED
@@ -1930,40 +1930,11 @@ function findPackageRoot() {
1930
1930
  }
1931
1931
  return null;
1932
1932
  }
1933
- function getAvailableMemoryGB() {
1934
- if (process.platform === "darwin") {
1935
- try {
1936
- const { execSync: execSync10 } = __require("child_process");
1937
- const vmstat = execSync10("vm_stat", { encoding: "utf8" });
1938
- const pageSize = 16384;
1939
- const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
1940
- const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
1941
- const free = vmstat.match(/Pages free:\s+(\d+)/);
1942
- const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
1943
- const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
1944
- const freePages = free ? parseInt(free[1], 10) : 0;
1945
- const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
1946
- const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
1947
- return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
1948
- } catch {
1949
- return os7.freemem() / (1024 * 1024 * 1024);
1950
- }
1951
- }
1952
- return os7.freemem() / (1024 * 1024 * 1024);
1953
- }
1954
1933
  function spawnDaemon() {
1955
- const freeGB = getAvailableMemoryGB();
1956
1934
  const totalGB = os7.totalmem() / (1024 * 1024 * 1024);
1957
1935
  if (totalGB <= 8) {
1958
1936
  process.stderr.write(
1959
1937
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
1960
- `
1961
- );
1962
- return;
1963
- }
1964
- if (totalGB <= 16 && freeGB < 2) {
1965
- process.stderr.write(
1966
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
1967
1938
  `
1968
1939
  );
1969
1940
  return;
@@ -8432,6 +8403,13 @@ var init_platform_procedures = __esm({
8432
8403
  priority: "p0",
8433
8404
  content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
8434
8405
  },
8406
+ // --- Encryption key + cloud sync ---
8407
+ {
8408
+ title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
8409
+ domain: "security",
8410
+ priority: "p0",
8411
+ content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
8412
+ },
8435
8413
  // --- MCP is the ONLY data interface ---
8436
8414
  {
8437
8415
  title: "MCP disconnect \u2014 ask the user, never work around it",
@@ -993,40 +993,11 @@ function findPackageRoot() {
993
993
  }
994
994
  return null;
995
995
  }
996
- function getAvailableMemoryGB() {
997
- if (process.platform === "darwin") {
998
- try {
999
- const { execSync: execSync4 } = __require("child_process");
1000
- const vmstat = execSync4("vm_stat", { encoding: "utf8" });
1001
- const pageSize = 16384;
1002
- const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
1003
- const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
1004
- const free = vmstat.match(/Pages free:\s+(\d+)/);
1005
- const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
1006
- const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
1007
- const freePages = free ? parseInt(free[1], 10) : 0;
1008
- const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
1009
- const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
1010
- return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
1011
- } catch {
1012
- return os4.freemem() / (1024 * 1024 * 1024);
1013
- }
1014
- }
1015
- return os4.freemem() / (1024 * 1024 * 1024);
1016
- }
1017
996
  function spawnDaemon() {
1018
- const freeGB = getAvailableMemoryGB();
1019
997
  const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
1020
998
  if (totalGB <= 8) {
1021
999
  process.stderr.write(
1022
1000
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
1023
- `
1024
- );
1025
- return;
1026
- }
1027
- if (totalGB <= 16 && freeGB < 2) {
1028
- process.stderr.write(
1029
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
1030
1001
  `
1031
1002
  );
1032
1003
  return;
@@ -1,11 +1,5 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
- }) : x)(function(x) {
6
- if (typeof require !== "undefined") return require.apply(this, arguments);
7
- throw Error('Dynamic require of "' + x + '" is not supported');
8
- });
9
3
  var __esm = (fn, res) => function __init() {
10
4
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
5
  };
@@ -252,40 +246,11 @@ function findPackageRoot() {
252
246
  }
253
247
  return null;
254
248
  }
255
- function getAvailableMemoryGB() {
256
- if (process.platform === "darwin") {
257
- try {
258
- const { execSync: execSync3 } = __require("child_process");
259
- const vmstat = execSync3("vm_stat", { encoding: "utf8" });
260
- const pageSize = 16384;
261
- const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
262
- const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
263
- const free = vmstat.match(/Pages free:\s+(\d+)/);
264
- const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
265
- const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
266
- const freePages = free ? parseInt(free[1], 10) : 0;
267
- const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
268
- const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
269
- return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
270
- } catch {
271
- return os4.freemem() / (1024 * 1024 * 1024);
272
- }
273
- }
274
- return os4.freemem() / (1024 * 1024 * 1024);
275
- }
276
249
  function spawnDaemon() {
277
- const freeGB = getAvailableMemoryGB();
278
250
  const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
279
251
  if (totalGB <= 8) {
280
252
  process.stderr.write(
281
253
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
282
- `
283
- );
284
- return;
285
- }
286
- if (totalGB <= 16 && freeGB < 2) {
287
- process.stderr.write(
288
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
289
254
  `
290
255
  );
291
256
  return;
@@ -1,10 +1,3 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
1
  // src/lib/exe-daemon-client.ts
9
2
  import net from "net";
10
3
  import os2 from "os";
@@ -238,40 +231,11 @@ function findPackageRoot() {
238
231
  }
239
232
  return null;
240
233
  }
241
- function getAvailableMemoryGB() {
242
- if (process.platform === "darwin") {
243
- try {
244
- const { execSync: execSync2 } = __require("child_process");
245
- const vmstat = execSync2("vm_stat", { encoding: "utf8" });
246
- const pageSize = 16384;
247
- const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
248
- const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
249
- const free = vmstat.match(/Pages free:\s+(\d+)/);
250
- const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
251
- const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
252
- const freePages = free ? parseInt(free[1], 10) : 0;
253
- const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
254
- const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
255
- return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
256
- } catch {
257
- return os2.freemem() / (1024 * 1024 * 1024);
258
- }
259
- }
260
- return os2.freemem() / (1024 * 1024 * 1024);
261
- }
262
234
  function spawnDaemon() {
263
- const freeGB = getAvailableMemoryGB();
264
235
  const totalGB = os2.totalmem() / (1024 * 1024 * 1024);
265
236
  if (totalGB <= 8) {
266
237
  process.stderr.write(
267
238
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
268
- `
269
- );
270
- return;
271
- }
272
- if (totalGB <= 16 && freeGB < 2) {
273
- process.stderr.write(
274
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
275
239
  `
276
240
  );
277
241
  return;
package/dist/lib/db.js CHANGED
@@ -1,11 +1,5 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
- }) : x)(function(x) {
6
- if (typeof require !== "undefined") return require.apply(this, arguments);
7
- throw Error('Dynamic require of "' + x + '" is not supported');
8
- });
9
3
  var __esm = (fn, res) => function __init() {
10
4
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
5
  };
@@ -252,40 +246,11 @@ function findPackageRoot() {
252
246
  }
253
247
  return null;
254
248
  }
255
- function getAvailableMemoryGB() {
256
- if (process.platform === "darwin") {
257
- try {
258
- const { execSync: execSync3 } = __require("child_process");
259
- const vmstat = execSync3("vm_stat", { encoding: "utf8" });
260
- const pageSize = 16384;
261
- const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
262
- const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
263
- const free = vmstat.match(/Pages free:\s+(\d+)/);
264
- const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
265
- const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
266
- const freePages = free ? parseInt(free[1], 10) : 0;
267
- const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
268
- const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
269
- return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
270
- } catch {
271
- return os4.freemem() / (1024 * 1024 * 1024);
272
- }
273
- }
274
- return os4.freemem() / (1024 * 1024 * 1024);
275
- }
276
249
  function spawnDaemon() {
277
- const freeGB = getAvailableMemoryGB();
278
250
  const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
279
251
  if (totalGB <= 8) {
280
252
  process.stderr.write(
281
253
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
282
- `
283
- );
284
- return;
285
- }
286
- if (totalGB <= 16 && freeGB < 2) {
287
- process.stderr.write(
288
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
289
254
  `
290
255
  );
291
256
  return;
@@ -1,11 +1,5 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
- }) : x)(function(x) {
6
- if (typeof require !== "undefined") return require.apply(this, arguments);
7
- throw Error('Dynamic require of "' + x + '" is not supported');
8
- });
9
3
  var __esm = (fn, res) => function __init() {
10
4
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
5
  };
@@ -938,40 +932,11 @@ function findPackageRoot() {
938
932
  }
939
933
  return null;
940
934
  }
941
- function getAvailableMemoryGB() {
942
- if (process.platform === "darwin") {
943
- try {
944
- const { execSync: execSync3 } = __require("child_process");
945
- const vmstat = execSync3("vm_stat", { encoding: "utf8" });
946
- const pageSize = 16384;
947
- const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
948
- const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
949
- const free = vmstat.match(/Pages free:\s+(\d+)/);
950
- const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
951
- const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
952
- const freePages = free ? parseInt(free[1], 10) : 0;
953
- const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
954
- const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
955
- return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
956
- } catch {
957
- return os4.freemem() / (1024 * 1024 * 1024);
958
- }
959
- }
960
- return os4.freemem() / (1024 * 1024 * 1024);
961
- }
962
935
  function spawnDaemon() {
963
- const freeGB = getAvailableMemoryGB();
964
936
  const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
965
937
  if (totalGB <= 8) {
966
938
  process.stderr.write(
967
939
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
968
- `
969
- );
970
- return;
971
- }
972
- if (totalGB <= 16 && freeGB < 2) {
973
- process.stderr.write(
974
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
975
940
  `
976
941
  );
977
942
  return;
@@ -1,11 +1,5 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
- }) : x)(function(x) {
6
- if (typeof require !== "undefined") return require.apply(this, arguments);
7
- throw Error('Dynamic require of "' + x + '" is not supported');
8
- });
9
3
  var __esm = (fn, res) => function __init() {
10
4
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
5
  };
@@ -451,40 +445,11 @@ function findPackageRoot() {
451
445
  }
452
446
  return null;
453
447
  }
454
- function getAvailableMemoryGB() {
455
- if (process.platform === "darwin") {
456
- try {
457
- const { execSync: execSync2 } = __require("child_process");
458
- const vmstat = execSync2("vm_stat", { encoding: "utf8" });
459
- const pageSize = 16384;
460
- const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
461
- const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
462
- const free = vmstat.match(/Pages free:\s+(\d+)/);
463
- const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
464
- const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
465
- const freePages = free ? parseInt(free[1], 10) : 0;
466
- const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
467
- const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
468
- return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
469
- } catch {
470
- return os2.freemem() / (1024 * 1024 * 1024);
471
- }
472
- }
473
- return os2.freemem() / (1024 * 1024 * 1024);
474
- }
475
448
  function spawnDaemon() {
476
- const freeGB = getAvailableMemoryGB();
477
449
  const totalGB = os2.totalmem() / (1024 * 1024 * 1024);
478
450
  if (totalGB <= 8) {
479
451
  process.stderr.write(
480
452
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
481
- `
482
- );
483
- return;
484
- }
485
- if (totalGB <= 16 && freeGB < 2) {
486
- process.stderr.write(
487
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
488
453
  `
489
454
  );
490
455
  return;
@@ -337,6 +337,13 @@ var PLATFORM_PROCEDURES = [
337
337
  priority: "p0",
338
338
  content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
339
339
  },
340
+ // --- Encryption key + cloud sync ---
341
+ {
342
+ title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
343
+ domain: "security",
344
+ priority: "p0",
345
+ content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
346
+ },
340
347
  // --- MCP is the ONLY data interface ---
341
348
  {
342
349
  title: "MCP disconnect \u2014 ask the user, never work around it",
@@ -1,10 +1,3 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
1
  // src/lib/exe-daemon-client.ts
9
2
  import net from "net";
10
3
  import os2 from "os";
@@ -244,40 +237,11 @@ function findPackageRoot() {
244
237
  }
245
238
  return null;
246
239
  }
247
- function getAvailableMemoryGB() {
248
- if (process.platform === "darwin") {
249
- try {
250
- const { execSync: execSync2 } = __require("child_process");
251
- const vmstat = execSync2("vm_stat", { encoding: "utf8" });
252
- const pageSize = 16384;
253
- const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
254
- const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
255
- const free = vmstat.match(/Pages free:\s+(\d+)/);
256
- const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
257
- const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
258
- const freePages = free ? parseInt(free[1], 10) : 0;
259
- const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
260
- const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
261
- return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
262
- } catch {
263
- return os2.freemem() / (1024 * 1024 * 1024);
264
- }
265
- }
266
- return os2.freemem() / (1024 * 1024 * 1024);
267
- }
268
240
  function spawnDaemon() {
269
- const freeGB = getAvailableMemoryGB();
270
241
  const totalGB = os2.totalmem() / (1024 * 1024 * 1024);
271
242
  if (totalGB <= 8) {
272
243
  process.stderr.write(
273
244
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
274
- `
275
- );
276
- return;
277
- }
278
- if (totalGB <= 16 && freeGB < 2) {
279
- process.stderr.write(
280
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
281
245
  `
282
246
  );
283
247
  return;
@@ -1575,40 +1575,11 @@ function findPackageRoot() {
1575
1575
  }
1576
1576
  return null;
1577
1577
  }
1578
- function getAvailableMemoryGB() {
1579
- if (process.platform === "darwin") {
1580
- try {
1581
- const { execSync: execSync18 } = __require("child_process");
1582
- const vmstat = execSync18("vm_stat", { encoding: "utf8" });
1583
- const pageSize = 16384;
1584
- const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
1585
- const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
1586
- const free = vmstat.match(/Pages free:\s+(\d+)/);
1587
- const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
1588
- const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
1589
- const freePages = free ? parseInt(free[1], 10) : 0;
1590
- const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
1591
- const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
1592
- return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
1593
- } catch {
1594
- return os4.freemem() / (1024 * 1024 * 1024);
1595
- }
1596
- }
1597
- return os4.freemem() / (1024 * 1024 * 1024);
1598
- }
1599
1578
  function spawnDaemon() {
1600
- const freeGB = getAvailableMemoryGB();
1601
1579
  const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
1602
1580
  if (totalGB <= 8) {
1603
1581
  process.stderr.write(
1604
1582
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
1605
- `
1606
- );
1607
- return;
1608
- }
1609
- if (totalGB <= 16 && freeGB < 2) {
1610
- process.stderr.write(
1611
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
1612
1583
  `
1613
1584
  );
1614
1585
  return;
@@ -5998,6 +5969,13 @@ var init_platform_procedures = __esm({
5998
5969
  priority: "p0",
5999
5970
  content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
6000
5971
  },
5972
+ // --- Encryption key + cloud sync ---
5973
+ {
5974
+ title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
5975
+ domain: "security",
5976
+ priority: "p0",
5977
+ content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
5978
+ },
6001
5979
  // --- MCP is the ONLY data interface ---
6002
5980
  {
6003
5981
  title: "MCP disconnect \u2014 ask the user, never work around it",
@@ -1119,40 +1119,11 @@ function findPackageRoot() {
1119
1119
  }
1120
1120
  return null;
1121
1121
  }
1122
- function getAvailableMemoryGB() {
1123
- if (process.platform === "darwin") {
1124
- try {
1125
- const { execSync: execSync6 } = __require("child_process");
1126
- const vmstat = execSync6("vm_stat", { encoding: "utf8" });
1127
- const pageSize = 16384;
1128
- const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
1129
- const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
1130
- const free = vmstat.match(/Pages free:\s+(\d+)/);
1131
- const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
1132
- const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
1133
- const freePages = free ? parseInt(free[1], 10) : 0;
1134
- const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
1135
- const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
1136
- return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
1137
- } catch {
1138
- return os4.freemem() / (1024 * 1024 * 1024);
1139
- }
1140
- }
1141
- return os4.freemem() / (1024 * 1024 * 1024);
1142
- }
1143
1122
  function spawnDaemon() {
1144
- const freeGB = getAvailableMemoryGB();
1145
1123
  const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
1146
1124
  if (totalGB <= 8) {
1147
1125
  process.stderr.write(
1148
1126
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
1149
- `
1150
- );
1151
- return;
1152
- }
1153
- if (totalGB <= 16 && freeGB < 2) {
1154
- process.stderr.write(
1155
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
1156
1127
  `
1157
1128
  );
1158
1129
  return;
@@ -4315,6 +4286,13 @@ var init_platform_procedures = __esm({
4315
4286
  priority: "p0",
4316
4287
  content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
4317
4288
  },
4289
+ // --- Encryption key + cloud sync ---
4290
+ {
4291
+ title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
4292
+ domain: "security",
4293
+ priority: "p0",
4294
+ content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
4295
+ },
4318
4296
  // --- MCP is the ONLY data interface ---
4319
4297
  {
4320
4298
  title: "MCP disconnect \u2014 ask the user, never work around it",