@askexenow/exe-os 0.8.37 → 0.8.39

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 (93) hide show
  1. package/README.md +17 -8
  2. package/dist/bin/backfill-conversations.js +112 -70
  3. package/dist/bin/backfill-responses.js +53 -18
  4. package/dist/bin/backfill-vectors.js +43 -16
  5. package/dist/bin/cleanup-stale-review-tasks.js +38 -16
  6. package/dist/bin/cli.js +790 -468
  7. package/dist/bin/exe-agent.js +19 -4
  8. package/dist/bin/exe-assign.js +46 -13
  9. package/dist/bin/exe-boot.js +288 -129
  10. package/dist/bin/exe-call.js +20 -10
  11. package/dist/bin/exe-cloud.js +135 -30
  12. package/dist/bin/exe-dispatch.js +1 -1
  13. package/dist/bin/exe-doctor.js +38 -16
  14. package/dist/bin/exe-export-behaviors.js +43 -21
  15. package/dist/bin/exe-forget.js +39 -17
  16. package/dist/bin/exe-gateway.js +159 -50
  17. package/dist/bin/exe-heartbeat.js +53 -31
  18. package/dist/bin/exe-kill.js +40 -18
  19. package/dist/bin/exe-launch-agent.js +109 -36
  20. package/dist/bin/exe-link.js +196 -87
  21. package/dist/bin/exe-new-employee.js +56 -17
  22. package/dist/bin/exe-pending-messages.js +47 -25
  23. package/dist/bin/exe-pending-notifications.js +38 -16
  24. package/dist/bin/exe-pending-reviews.js +51 -29
  25. package/dist/bin/exe-rename.js +21 -7
  26. package/dist/bin/exe-review.js +41 -13
  27. package/dist/bin/exe-search.js +57 -21
  28. package/dist/bin/exe-session-cleanup.js +67 -31
  29. package/dist/bin/exe-settings.js +63 -2
  30. package/dist/bin/exe-status.js +35 -13
  31. package/dist/bin/exe-team.js +35 -13
  32. package/dist/bin/git-sweep.js +45 -17
  33. package/dist/bin/graph-backfill.js +38 -16
  34. package/dist/bin/graph-export.js +38 -16
  35. package/dist/bin/install.js +10 -1
  36. package/dist/bin/scan-tasks.js +47 -19
  37. package/dist/bin/setup.js +444 -259
  38. package/dist/bin/shard-migrate.js +38 -16
  39. package/dist/bin/wiki-sync.js +40 -17
  40. package/dist/gateway/index.js +113 -48
  41. package/dist/hooks/bug-report-worker.js +66 -39
  42. package/dist/hooks/commit-complete.js +45 -17
  43. package/dist/hooks/error-recall.js +60 -20
  44. package/dist/hooks/exe-heartbeat-hook.js +3 -2
  45. package/dist/hooks/ingest-worker.js +174 -45
  46. package/dist/hooks/ingest.js +74 -28
  47. package/dist/hooks/instructions-loaded.js +46 -17
  48. package/dist/hooks/notification.js +44 -15
  49. package/dist/hooks/post-compact.js +44 -15
  50. package/dist/hooks/pre-compact.js +42 -14
  51. package/dist/hooks/pre-tool-use.js +59 -22
  52. package/dist/hooks/prompt-ingest-worker.js +75 -14
  53. package/dist/hooks/prompt-submit.js +75 -32
  54. package/dist/hooks/response-ingest-worker.js +76 -15
  55. package/dist/hooks/session-end.js +54 -22
  56. package/dist/hooks/session-start.js +57 -20
  57. package/dist/hooks/stop.js +44 -15
  58. package/dist/hooks/subagent-stop.js +44 -15
  59. package/dist/hooks/summary-worker.js +339 -106
  60. package/dist/index.js +94 -23
  61. package/dist/lib/cloud-sync.js +191 -80
  62. package/dist/lib/config.js +4 -1
  63. package/dist/lib/consolidation.js +5 -4
  64. package/dist/lib/database.js +1 -0
  65. package/dist/lib/device-registry.js +2 -1
  66. package/dist/lib/embedder.js +9 -1
  67. package/dist/lib/employee-templates.js +5 -0
  68. package/dist/lib/employees.js +11 -6
  69. package/dist/lib/exe-daemon-client.js +6 -1
  70. package/dist/lib/exe-daemon.js +95 -36
  71. package/dist/lib/hybrid-search.js +57 -21
  72. package/dist/lib/identity-templates.js +16 -7
  73. package/dist/lib/identity.js +1 -1
  74. package/dist/lib/keychain.js +2 -1
  75. package/dist/lib/license.js +56 -6
  76. package/dist/lib/messaging.js +1 -1
  77. package/dist/lib/reminders.js +2 -2
  78. package/dist/lib/schedules.js +38 -16
  79. package/dist/lib/skill-learning.js +1 -1
  80. package/dist/lib/store.js +44 -16
  81. package/dist/lib/tasks.js +1 -1
  82. package/dist/lib/tmux-routing.js +1 -1
  83. package/dist/mcp/server.js +280 -155
  84. package/dist/mcp/tools/complete-reminder.js +1 -1
  85. package/dist/mcp/tools/create-task.js +14 -6
  86. package/dist/mcp/tools/deactivate-behavior.js +2 -2
  87. package/dist/mcp/tools/list-reminders.js +1 -1
  88. package/dist/mcp/tools/list-tasks.js +36 -28
  89. package/dist/mcp/tools/send-message.js +1 -1
  90. package/dist/mcp/tools/update-task.js +1 -1
  91. package/dist/runtime/index.js +42 -8
  92. package/dist/tui/App.js +220 -99
  93. package/package.json +5 -3
@@ -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
  };
@@ -15,7 +9,7 @@ var __export = (target, all) => {
15
9
  };
16
10
 
17
11
  // src/lib/config.ts
18
- import { readFile, writeFile, mkdir } from "fs/promises";
12
+ import { readFile, writeFile, mkdir, chmod } from "fs/promises";
19
13
  import { readFileSync, existsSync, renameSync } from "fs";
20
14
  import path from "path";
21
15
  import os from "os";
@@ -333,6 +327,7 @@ async function ensureSchema() {
333
327
  const client = getRawClient();
334
328
  await client.execute("PRAGMA journal_mode = WAL");
335
329
  await client.execute("PRAGMA busy_timeout = 30000");
330
+ await client.execute("PRAGMA wal_autocheckpoint = 1000");
336
331
  try {
337
332
  await client.execute("PRAGMA libsql_vector_search_ef = 128");
338
333
  } catch {
@@ -1141,12 +1136,13 @@ var init_database = __esm({
1141
1136
  });
1142
1137
 
1143
1138
  // src/lib/keychain.ts
1144
- import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod } from "fs/promises";
1139
+ import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
1145
1140
  import { existsSync as existsSync2 } from "fs";
1146
1141
  import path3 from "path";
1142
+ import os2 from "os";
1147
1143
  import crypto from "crypto";
1148
1144
  function getKeyDir() {
1149
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path3.join(process.env.HOME ?? "/tmp", ".exe-os");
1145
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path3.join(os2.homedir(), ".exe-os");
1150
1146
  }
1151
1147
  function getKeyPath() {
1152
1148
  return path3.join(getKeyDir(), "master.key");
@@ -1203,7 +1199,7 @@ __export(shard_manager_exports, {
1203
1199
  shardExists: () => shardExists
1204
1200
  });
1205
1201
  import path4 from "path";
1206
- import { existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
1202
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync as readdirSync2 } from "fs";
1207
1203
  import { createClient as createClient2 } from "@libsql/client";
1208
1204
  function initShardManager(encryptionKey) {
1209
1205
  _encryptionKey = encryptionKey;
@@ -1242,7 +1238,6 @@ function shardExists(projectName) {
1242
1238
  }
1243
1239
  function listShards() {
1244
1240
  if (!existsSync3(SHARDS_DIR)) return [];
1245
- const { readdirSync: readdirSync2 } = __require("fs");
1246
1241
  return readdirSync2(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
1247
1242
  }
1248
1243
  async function ensureShardSchema(client) {
@@ -1448,6 +1443,28 @@ __export(store_exports, {
1448
1443
  vectorToBlob: () => vectorToBlob,
1449
1444
  writeMemory: () => writeMemory
1450
1445
  });
1446
+ function isBusyError2(err) {
1447
+ if (err instanceof Error) {
1448
+ const msg = err.message.toLowerCase();
1449
+ return msg.includes("sqlite_busy") || msg.includes("database is locked");
1450
+ }
1451
+ return false;
1452
+ }
1453
+ async function retryOnBusy2(fn, label) {
1454
+ for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
1455
+ try {
1456
+ return await fn();
1457
+ } catch (err) {
1458
+ if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
1459
+ process.stderr.write(
1460
+ `[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
1461
+ `
1462
+ );
1463
+ await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
1464
+ }
1465
+ }
1466
+ throw new Error("unreachable");
1467
+ }
1451
1468
  async function initStore(options) {
1452
1469
  if (_flushTimer !== null) {
1453
1470
  clearInterval(_flushTimer);
@@ -1476,14 +1493,17 @@ async function initStore(options) {
1476
1493
  dbPath,
1477
1494
  encryptionKey: hexKey
1478
1495
  });
1479
- await ensureSchema();
1496
+ await retryOnBusy2(() => ensureSchema(), "ensureSchema");
1480
1497
  try {
1481
1498
  const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
1482
1499
  initShardManager2(hexKey);
1483
1500
  } catch {
1484
1501
  }
1485
1502
  const client = getClient();
1486
- const vResult = await client.execute("SELECT MAX(version) as max_v FROM memories");
1503
+ const vResult = await retryOnBusy2(
1504
+ () => client.execute("SELECT MAX(version) as max_v FROM memories"),
1505
+ "version-query"
1506
+ );
1487
1507
  _nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
1488
1508
  }
1489
1509
  function classifyTier(record) {
@@ -1526,6 +1546,12 @@ async function writeMemory(record) {
1526
1546
  supersedes_id: record.supersedes_id ?? null
1527
1547
  };
1528
1548
  _pendingRecords.push(dbRow);
1549
+ const MAX_PENDING = 1e3;
1550
+ if (_pendingRecords.length > MAX_PENDING) {
1551
+ const dropped = _pendingRecords.length - MAX_PENDING;
1552
+ _pendingRecords = _pendingRecords.slice(-MAX_PENDING);
1553
+ console.warn(`[store] Dropped ${dropped} oldest pending records (overflow)`);
1554
+ }
1529
1555
  if (_flushTimer === null) {
1530
1556
  _flushTimer = setInterval(() => {
1531
1557
  void flushBatch();
@@ -1857,7 +1883,7 @@ async function getMemoryCardinality(agentId) {
1857
1883
  return 0;
1858
1884
  }
1859
1885
  }
1860
- var _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
1886
+ var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
1861
1887
  var init_store = __esm({
1862
1888
  "src/lib/store.ts"() {
1863
1889
  "use strict";
@@ -1865,6 +1891,8 @@ var init_store = __esm({
1865
1891
  init_database();
1866
1892
  init_keychain();
1867
1893
  init_config();
1894
+ INIT_MAX_RETRIES = 3;
1895
+ INIT_RETRY_DELAY_MS = 1e3;
1868
1896
  _pendingRecords = [];
1869
1897
  _batchSize = 20;
1870
1898
  _flushIntervalMs = 1e4;
@@ -1992,10 +2020,11 @@ var timeout = setTimeout(() => {
1992
2020
  process.exit(0);
1993
2021
  }, 5e3);
1994
2022
  timeout.unref();
2023
+ var MAX_INPUT_SIZE = 1e6;
1995
2024
  var input = "";
1996
2025
  process.stdin.setEncoding("utf8");
1997
2026
  process.stdin.on("data", (chunk) => {
1998
- input += chunk;
2027
+ if (input.length < MAX_INPUT_SIZE) input += chunk;
1999
2028
  });
2000
2029
  process.stdin.on("end", () => {
2001
2030
  try {
@@ -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
  };
@@ -15,7 +9,7 @@ var __export = (target, all) => {
15
9
  };
16
10
 
17
11
  // src/lib/config.ts
18
- import { readFile, writeFile, mkdir } from "fs/promises";
12
+ import { readFile, writeFile, mkdir, chmod } from "fs/promises";
19
13
  import { readFileSync, existsSync, renameSync } from "fs";
20
14
  import path from "path";
21
15
  import os from "os";
@@ -314,6 +308,7 @@ async function ensureSchema() {
314
308
  const client = getRawClient();
315
309
  await client.execute("PRAGMA journal_mode = WAL");
316
310
  await client.execute("PRAGMA busy_timeout = 30000");
311
+ await client.execute("PRAGMA wal_autocheckpoint = 1000");
317
312
  try {
318
313
  await client.execute("PRAGMA libsql_vector_search_ef = 128");
319
314
  } catch {
@@ -1122,12 +1117,13 @@ var init_database = __esm({
1122
1117
  });
1123
1118
 
1124
1119
  // src/lib/keychain.ts
1125
- import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod } from "fs/promises";
1120
+ import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
1126
1121
  import { existsSync as existsSync2 } from "fs";
1127
1122
  import path3 from "path";
1123
+ import os2 from "os";
1128
1124
  import crypto from "crypto";
1129
1125
  function getKeyDir() {
1130
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path3.join(process.env.HOME ?? "/tmp", ".exe-os");
1126
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path3.join(os2.homedir(), ".exe-os");
1131
1127
  }
1132
1128
  function getKeyPath() {
1133
1129
  return path3.join(getKeyDir(), "master.key");
@@ -1184,7 +1180,7 @@ __export(shard_manager_exports, {
1184
1180
  shardExists: () => shardExists
1185
1181
  });
1186
1182
  import path4 from "path";
1187
- import { existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
1183
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync as readdirSync2 } from "fs";
1188
1184
  import { createClient as createClient2 } from "@libsql/client";
1189
1185
  function initShardManager(encryptionKey) {
1190
1186
  _encryptionKey = encryptionKey;
@@ -1223,7 +1219,6 @@ function shardExists(projectName) {
1223
1219
  }
1224
1220
  function listShards() {
1225
1221
  if (!existsSync3(SHARDS_DIR)) return [];
1226
- const { readdirSync: readdirSync2 } = __require("fs");
1227
1222
  return readdirSync2(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
1228
1223
  }
1229
1224
  async function ensureShardSchema(client) {
@@ -1429,6 +1424,28 @@ __export(store_exports, {
1429
1424
  vectorToBlob: () => vectorToBlob,
1430
1425
  writeMemory: () => writeMemory
1431
1426
  });
1427
+ function isBusyError2(err) {
1428
+ if (err instanceof Error) {
1429
+ const msg = err.message.toLowerCase();
1430
+ return msg.includes("sqlite_busy") || msg.includes("database is locked");
1431
+ }
1432
+ return false;
1433
+ }
1434
+ async function retryOnBusy2(fn, label) {
1435
+ for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
1436
+ try {
1437
+ return await fn();
1438
+ } catch (err) {
1439
+ if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
1440
+ process.stderr.write(
1441
+ `[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
1442
+ `
1443
+ );
1444
+ await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
1445
+ }
1446
+ }
1447
+ throw new Error("unreachable");
1448
+ }
1432
1449
  async function initStore(options) {
1433
1450
  if (_flushTimer !== null) {
1434
1451
  clearInterval(_flushTimer);
@@ -1457,14 +1474,17 @@ async function initStore(options) {
1457
1474
  dbPath,
1458
1475
  encryptionKey: hexKey
1459
1476
  });
1460
- await ensureSchema();
1477
+ await retryOnBusy2(() => ensureSchema(), "ensureSchema");
1461
1478
  try {
1462
1479
  const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
1463
1480
  initShardManager2(hexKey);
1464
1481
  } catch {
1465
1482
  }
1466
1483
  const client = getClient();
1467
- const vResult = await client.execute("SELECT MAX(version) as max_v FROM memories");
1484
+ const vResult = await retryOnBusy2(
1485
+ () => client.execute("SELECT MAX(version) as max_v FROM memories"),
1486
+ "version-query"
1487
+ );
1468
1488
  _nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
1469
1489
  }
1470
1490
  function classifyTier(record) {
@@ -1507,6 +1527,12 @@ async function writeMemory(record) {
1507
1527
  supersedes_id: record.supersedes_id ?? null
1508
1528
  };
1509
1529
  _pendingRecords.push(dbRow);
1530
+ const MAX_PENDING = 1e3;
1531
+ if (_pendingRecords.length > MAX_PENDING) {
1532
+ const dropped = _pendingRecords.length - MAX_PENDING;
1533
+ _pendingRecords = _pendingRecords.slice(-MAX_PENDING);
1534
+ console.warn(`[store] Dropped ${dropped} oldest pending records (overflow)`);
1535
+ }
1510
1536
  if (_flushTimer === null) {
1511
1537
  _flushTimer = setInterval(() => {
1512
1538
  void flushBatch();
@@ -1838,7 +1864,7 @@ async function getMemoryCardinality(agentId) {
1838
1864
  return 0;
1839
1865
  }
1840
1866
  }
1841
- var _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
1867
+ var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
1842
1868
  var init_store = __esm({
1843
1869
  "src/lib/store.ts"() {
1844
1870
  "use strict";
@@ -1846,6 +1872,8 @@ var init_store = __esm({
1846
1872
  init_database();
1847
1873
  init_keychain();
1848
1874
  init_config();
1875
+ INIT_MAX_RETRIES = 3;
1876
+ INIT_RETRY_DELAY_MS = 1e3;
1849
1877
  _pendingRecords = [];
1850
1878
  _batchSize = 20;
1851
1879
  _flushIntervalMs = 1e4;
@@ -1953,10 +1981,11 @@ var timeout = setTimeout(() => {
1953
1981
  process.exit(0);
1954
1982
  }, 5e3);
1955
1983
  timeout.unref();
1984
+ var MAX_INPUT_SIZE = 1e6;
1956
1985
  var input = "";
1957
1986
  process.stdin.setEncoding("utf8");
1958
1987
  process.stdin.on("data", (chunk) => {
1959
- input += chunk;
1988
+ if (input.length < MAX_INPUT_SIZE) input += chunk;
1960
1989
  });
1961
1990
  process.stdin.on("end", async () => {
1962
1991
  try {