@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
@@ -1094,7 +1094,8 @@ var OllamaProvider = class {
1094
1094
  const res = await fetch(`${this.host}/api/chat`, {
1095
1095
  method: "POST",
1096
1096
  headers: { "Content-Type": "application/json" },
1097
- body: JSON.stringify(body)
1097
+ body: JSON.stringify(body),
1098
+ signal: AbortSignal.timeout(3e4)
1098
1099
  });
1099
1100
  if (!res.ok) {
1100
1101
  throw new Error(`Ollama API error: ${res.status} ${await res.text()}`);
@@ -1425,10 +1426,19 @@ var BashTool = {
1425
1426
  stdio: ["ignore", "pipe", "pipe"],
1426
1427
  env: { ...process.env }
1427
1428
  });
1429
+ const MAX_OUTPUT_SIZE = 5242880;
1428
1430
  const stdoutChunks = [];
1429
1431
  const stderrChunks = [];
1430
- child.stdout.on("data", (chunk) => stdoutChunks.push(chunk));
1431
- child.stderr.on("data", (chunk) => stderrChunks.push(chunk));
1432
+ let stdoutSize = 0;
1433
+ let stderrSize = 0;
1434
+ child.stdout.on("data", (chunk) => {
1435
+ if (stdoutSize < MAX_OUTPUT_SIZE) stdoutChunks.push(chunk);
1436
+ stdoutSize += chunk.length;
1437
+ });
1438
+ child.stderr.on("data", (chunk) => {
1439
+ if (stderrSize < MAX_OUTPUT_SIZE) stderrChunks.push(chunk);
1440
+ stderrSize += chunk.length;
1441
+ });
1432
1442
  const onAbort = () => {
1433
1443
  child.kill("SIGTERM");
1434
1444
  setTimeout(() => {
@@ -1829,8 +1839,13 @@ function runRipgrep(input, searchPath, context) {
1829
1839
  timeout: 3e4,
1830
1840
  stdio: ["ignore", "pipe", "pipe"]
1831
1841
  });
1842
+ const MAX_OUTPUT = 1e7;
1832
1843
  const chunks = [];
1833
- child.stdout.on("data", (chunk) => chunks.push(chunk));
1844
+ let totalSize = 0;
1845
+ child.stdout.on("data", (chunk) => {
1846
+ totalSize += chunk.length;
1847
+ if (totalSize <= MAX_OUTPUT) chunks.push(chunk);
1848
+ });
1834
1849
  const onAbort = () => child.kill("SIGTERM");
1835
1850
  context.abortSignal.addEventListener("abort", onAbort, { once: true });
1836
1851
  child.on("close", (code) => {
@@ -1,12 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
- }) : x)(function(x) {
7
- if (typeof require !== "undefined") return require.apply(this, arguments);
8
- throw Error('Dynamic require of "' + x + '" is not supported');
9
- });
10
4
  var __esm = (fn, res) => function __init() {
11
5
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
6
  };
@@ -16,7 +10,7 @@ var __export = (target, all) => {
16
10
  };
17
11
 
18
12
  // src/lib/config.ts
19
- import { readFile, writeFile, mkdir } from "fs/promises";
13
+ import { readFile, writeFile, mkdir, chmod } from "fs/promises";
20
14
  import { readFileSync, existsSync, renameSync } from "fs";
21
15
  import path from "path";
22
16
  import os from "os";
@@ -218,7 +212,7 @@ __export(shard_manager_exports, {
218
212
  shardExists: () => shardExists
219
213
  });
220
214
  import path5 from "path";
221
- import { existsSync as existsSync5, mkdirSync } from "fs";
215
+ import { existsSync as existsSync5, mkdirSync, readdirSync } from "fs";
222
216
  import { createClient as createClient2 } from "@libsql/client";
223
217
  function initShardManager(encryptionKey) {
224
218
  _encryptionKey = encryptionKey;
@@ -257,7 +251,6 @@ function shardExists(projectName) {
257
251
  }
258
252
  function listShards() {
259
253
  if (!existsSync5(SHARDS_DIR)) return [];
260
- const { readdirSync } = __require("fs");
261
254
  return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
262
255
  }
263
256
  async function ensureShardSchema(client) {
@@ -614,8 +607,13 @@ var _buffer = "";
614
607
  var _requestCount = 0;
615
608
  var HEALTH_CHECK_INTERVAL = 100;
616
609
  var _pending = /* @__PURE__ */ new Map();
610
+ var MAX_BUFFER = 1e7;
617
611
  function handleData(chunk) {
618
612
  _buffer += chunk.toString();
613
+ if (_buffer.length > MAX_BUFFER) {
614
+ _buffer = "";
615
+ return;
616
+ }
619
617
  let newlineIdx;
620
618
  while ((newlineIdx = _buffer.indexOf("\n")) !== -1) {
621
619
  const line = _buffer.slice(0, newlineIdx).trim();
@@ -1015,6 +1013,7 @@ async function ensureSchema() {
1015
1013
  const client = getRawClient();
1016
1014
  await client.execute("PRAGMA journal_mode = WAL");
1017
1015
  await client.execute("PRAGMA busy_timeout = 30000");
1016
+ await client.execute("PRAGMA wal_autocheckpoint = 1000");
1018
1017
  try {
1019
1018
  await client.execute("PRAGMA libsql_vector_search_ef = 128");
1020
1019
  } catch {
@@ -1805,14 +1804,15 @@ async function ensureSchema() {
1805
1804
  }
1806
1805
 
1807
1806
  // src/lib/keychain.ts
1808
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod } from "fs/promises";
1807
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
1809
1808
  import { existsSync as existsSync4 } from "fs";
1810
1809
  import path4 from "path";
1810
+ import os2 from "os";
1811
1811
  import crypto from "crypto";
1812
1812
  var SERVICE = "exe-mem";
1813
1813
  var ACCOUNT = "master-key";
1814
1814
  function getKeyDir() {
1815
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path4.join(process.env.HOME ?? "/tmp", ".exe-os");
1815
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path4.join(os2.homedir(), ".exe-os");
1816
1816
  }
1817
1817
  function getKeyPath() {
1818
1818
  return path4.join(getKeyDir(), "master.key");
@@ -1849,6 +1849,30 @@ async function getMasterKey() {
1849
1849
 
1850
1850
  // src/lib/store.ts
1851
1851
  init_config();
1852
+ var INIT_MAX_RETRIES = 3;
1853
+ var INIT_RETRY_DELAY_MS = 1e3;
1854
+ function isBusyError2(err) {
1855
+ if (err instanceof Error) {
1856
+ const msg = err.message.toLowerCase();
1857
+ return msg.includes("sqlite_busy") || msg.includes("database is locked");
1858
+ }
1859
+ return false;
1860
+ }
1861
+ async function retryOnBusy2(fn, label) {
1862
+ for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
1863
+ try {
1864
+ return await fn();
1865
+ } catch (err) {
1866
+ if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
1867
+ process.stderr.write(
1868
+ `[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
1869
+ `
1870
+ );
1871
+ await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
1872
+ }
1873
+ }
1874
+ throw new Error("unreachable");
1875
+ }
1852
1876
  var _pendingRecords = [];
1853
1877
  var _batchSize = 20;
1854
1878
  var _flushIntervalMs = 1e4;
@@ -1883,14 +1907,17 @@ async function initStore(options) {
1883
1907
  dbPath,
1884
1908
  encryptionKey: hexKey
1885
1909
  });
1886
- await ensureSchema();
1910
+ await retryOnBusy2(() => ensureSchema(), "ensureSchema");
1887
1911
  try {
1888
1912
  const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
1889
1913
  initShardManager2(hexKey);
1890
1914
  } catch {
1891
1915
  }
1892
1916
  const client = getClient();
1893
- const vResult = await client.execute("SELECT MAX(version) as max_v FROM memories");
1917
+ const vResult = await retryOnBusy2(
1918
+ () => client.execute("SELECT MAX(version) as max_v FROM memories"),
1919
+ "version-query"
1920
+ );
1894
1921
  _nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
1895
1922
  }
1896
1923
  function classifyTier(record) {
@@ -1933,6 +1960,12 @@ async function writeMemory(record) {
1933
1960
  supersedes_id: record.supersedes_id ?? null
1934
1961
  };
1935
1962
  _pendingRecords.push(dbRow);
1963
+ const MAX_PENDING = 1e3;
1964
+ if (_pendingRecords.length > MAX_PENDING) {
1965
+ const dropped = _pendingRecords.length - MAX_PENDING;
1966
+ _pendingRecords = _pendingRecords.slice(-MAX_PENDING);
1967
+ console.warn(`[store] Dropped ${dropped} oldest pending records (overflow)`);
1968
+ }
1936
1969
  if (_flushTimer === null) {
1937
1970
  _flushTimer = setInterval(() => {
1938
1971
  void flushBatch();