@askexenow/exe-os 0.8.83 → 0.8.86

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 (103) hide show
  1. package/dist/bin/backfill-conversations.js +746 -595
  2. package/dist/bin/backfill-responses.js +745 -594
  3. package/dist/bin/backfill-vectors.js +312 -226
  4. package/dist/bin/cleanup-stale-review-tasks.js +154 -21
  5. package/dist/bin/cli.js +14678 -12676
  6. package/dist/bin/exe-agent-config.js +242 -0
  7. package/dist/bin/exe-agent.js +100 -91
  8. package/dist/bin/exe-assign.js +1003 -854
  9. package/dist/bin/exe-boot.js +1420 -485
  10. package/dist/bin/exe-call.js +10 -0
  11. package/dist/bin/exe-cloud.js +29 -6
  12. package/dist/bin/exe-dispatch.js +572 -271
  13. package/dist/bin/exe-doctor.js +403 -6
  14. package/dist/bin/exe-export-behaviors.js +175 -72
  15. package/dist/bin/exe-forget.js +102 -3
  16. package/dist/bin/exe-gateway.js +796 -292
  17. package/dist/bin/exe-healthcheck.js +134 -1
  18. package/dist/bin/exe-heartbeat.js +172 -36
  19. package/dist/bin/exe-kill.js +175 -72
  20. package/dist/bin/exe-launch-agent.js +189 -76
  21. package/dist/bin/exe-link.js +927 -82
  22. package/dist/bin/exe-new-employee.js +60 -8
  23. package/dist/bin/exe-pending-messages.js +151 -19
  24. package/dist/bin/exe-pending-notifications.js +97 -2
  25. package/dist/bin/exe-pending-reviews.js +155 -22
  26. package/dist/bin/exe-rename.js +564 -23
  27. package/dist/bin/exe-review.js +231 -73
  28. package/dist/bin/exe-search.js +995 -228
  29. package/dist/bin/exe-session-cleanup.js +4930 -1664
  30. package/dist/bin/exe-settings.js +20 -5
  31. package/dist/bin/exe-start-codex.js +2598 -0
  32. package/dist/bin/exe-start.sh +15 -3
  33. package/dist/bin/exe-status.js +154 -21
  34. package/dist/bin/exe-team.js +97 -2
  35. package/dist/bin/git-sweep.js +1180 -363
  36. package/dist/bin/graph-backfill.js +175 -72
  37. package/dist/bin/graph-export.js +175 -72
  38. package/dist/bin/install.js +60 -7
  39. package/dist/bin/list-providers.js +1 -0
  40. package/dist/bin/scan-tasks.js +1185 -367
  41. package/dist/bin/setup.js +914 -270
  42. package/dist/bin/shard-migrate.js +175 -72
  43. package/dist/bin/update.js +1 -0
  44. package/dist/bin/wiki-sync.js +175 -72
  45. package/dist/gateway/index.js +792 -285
  46. package/dist/hooks/bug-report-worker.js +445 -135
  47. package/dist/hooks/commit-complete.js +1178 -361
  48. package/dist/hooks/error-recall.js +994 -228
  49. package/dist/hooks/ingest-worker.js +1799 -1234
  50. package/dist/hooks/ingest.js +3 -0
  51. package/dist/hooks/instructions-loaded.js +707 -97
  52. package/dist/hooks/notification.js +699 -89
  53. package/dist/hooks/post-compact.js +757 -109
  54. package/dist/hooks/pre-compact.js +1061 -244
  55. package/dist/hooks/pre-tool-use.js +787 -130
  56. package/dist/hooks/prompt-ingest-worker.js +242 -101
  57. package/dist/hooks/prompt-submit.js +1121 -299
  58. package/dist/hooks/response-ingest-worker.js +242 -101
  59. package/dist/hooks/session-end.js +4063 -397
  60. package/dist/hooks/session-start.js +1071 -254
  61. package/dist/hooks/stop.js +768 -120
  62. package/dist/hooks/subagent-stop.js +757 -109
  63. package/dist/hooks/summary-worker.js +1706 -1011
  64. package/dist/index.js +1821 -1098
  65. package/dist/lib/agent-config.js +167 -0
  66. package/dist/lib/cloud-sync.js +932 -88
  67. package/dist/lib/consolidation.js +2 -1
  68. package/dist/lib/database.js +642 -87
  69. package/dist/lib/db-daemon-client.js +503 -0
  70. package/dist/lib/device-registry.js +547 -7
  71. package/dist/lib/embedder.js +14 -28
  72. package/dist/lib/employee-templates.js +84 -74
  73. package/dist/lib/employees.js +9 -0
  74. package/dist/lib/exe-daemon-client.js +16 -29
  75. package/dist/lib/exe-daemon.js +2733 -1575
  76. package/dist/lib/hybrid-search.js +995 -228
  77. package/dist/lib/identity.js +87 -67
  78. package/dist/lib/keychain.js +9 -1
  79. package/dist/lib/messaging.js +103 -40
  80. package/dist/lib/reminders.js +91 -74
  81. package/dist/lib/runtime-table.js +16 -0
  82. package/dist/lib/schedules.js +96 -2
  83. package/dist/lib/session-wrappers.js +22 -0
  84. package/dist/lib/skill-learning.js +103 -85
  85. package/dist/lib/store.js +234 -73
  86. package/dist/lib/tasks.js +348 -134
  87. package/dist/lib/tmux-routing.js +422 -208
  88. package/dist/lib/token-spend.js +273 -0
  89. package/dist/lib/ws-client.js +11 -0
  90. package/dist/mcp/server.js +5742 -696
  91. package/dist/mcp/tools/complete-reminder.js +94 -77
  92. package/dist/mcp/tools/create-reminder.js +94 -77
  93. package/dist/mcp/tools/create-task.js +375 -152
  94. package/dist/mcp/tools/deactivate-behavior.js +95 -77
  95. package/dist/mcp/tools/list-reminders.js +94 -77
  96. package/dist/mcp/tools/list-tasks.js +99 -31
  97. package/dist/mcp/tools/send-message.js +108 -45
  98. package/dist/mcp/tools/update-task.js +162 -77
  99. package/dist/runtime/index.js +1075 -258
  100. package/dist/tui/App.js +1333 -506
  101. package/package.json +6 -1
  102. package/src/commands/exe/agent-config.md +27 -0
  103. package/src/commands/exe/cc-doctor.md +10 -0
@@ -305,6 +305,12 @@ function getClient() {
305
305
  if (!_resilientClient) {
306
306
  throw new Error("Database client not initialized. Call initDatabase() first.");
307
307
  }
308
+ if (process.env.EXE_IS_DAEMON === "1") {
309
+ return _resilientClient;
310
+ }
311
+ if (_daemonClient && _daemonClient._isDaemonActive()) {
312
+ return _daemonClient;
313
+ }
308
314
  return _resilientClient;
309
315
  }
310
316
  function getRawClient() {
@@ -793,6 +799,12 @@ async function ensureSchema() {
793
799
  } catch {
794
800
  }
795
801
  }
802
+ try {
803
+ await client.execute(
804
+ `CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
805
+ );
806
+ } catch {
807
+ }
796
808
  await client.executeMultiple(`
797
809
  CREATE TABLE IF NOT EXISTS entities (
798
810
  id TEXT PRIMARY KEY,
@@ -845,7 +857,30 @@ async function ensureSchema() {
845
857
  entity_id TEXT NOT NULL,
846
858
  PRIMARY KEY (hyperedge_id, entity_id)
847
859
  );
860
+
861
+ CREATE VIRTUAL TABLE IF NOT EXISTS entities_fts USING fts5(
862
+ name,
863
+ content=entities,
864
+ content_rowid=rowid
865
+ );
866
+
867
+ CREATE TRIGGER IF NOT EXISTS entities_fts_ai AFTER INSERT ON entities BEGIN
868
+ INSERT INTO entities_fts(rowid, name) VALUES (new.rowid, new.name);
869
+ END;
870
+
871
+ CREATE TRIGGER IF NOT EXISTS entities_fts_ad AFTER DELETE ON entities BEGIN
872
+ INSERT INTO entities_fts(entities_fts, rowid, name) VALUES('delete', old.rowid, old.name);
873
+ END;
874
+
875
+ CREATE TRIGGER IF NOT EXISTS entities_fts_au AFTER UPDATE ON entities BEGIN
876
+ INSERT INTO entities_fts(entities_fts, rowid, name) VALUES('delete', old.rowid, old.name);
877
+ INSERT INTO entities_fts(rowid, name) VALUES (new.rowid, new.name);
878
+ END;
848
879
  `);
880
+ try {
881
+ await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
882
+ } catch {
883
+ }
849
884
  await client.executeMultiple(`
850
885
  CREATE TABLE IF NOT EXISTS entity_aliases (
851
886
  alias TEXT NOT NULL PRIMARY KEY,
@@ -1026,6 +1061,33 @@ async function ensureSchema() {
1026
1061
  CREATE INDEX IF NOT EXISTS idx_conversations_channel
1027
1062
  ON conversations(channel_id);
1028
1063
  `);
1064
+ await client.executeMultiple(`
1065
+ CREATE TABLE IF NOT EXISTS session_agent_map (
1066
+ session_uuid TEXT PRIMARY KEY,
1067
+ agent_id TEXT NOT NULL,
1068
+ session_name TEXT,
1069
+ task_id TEXT,
1070
+ project_name TEXT,
1071
+ started_at TEXT NOT NULL
1072
+ );
1073
+
1074
+ CREATE INDEX IF NOT EXISTS idx_session_agent_map_agent
1075
+ ON session_agent_map(agent_id);
1076
+ `);
1077
+ try {
1078
+ const mapCount = await client.execute({ sql: `SELECT COUNT(*) as cnt FROM session_agent_map`, args: [] });
1079
+ if (Number(mapCount.rows[0]?.cnt ?? 0) === 0) {
1080
+ await client.execute({
1081
+ sql: `INSERT OR IGNORE INTO session_agent_map (session_uuid, agent_id, session_name, started_at)
1082
+ SELECT session_id, agent_id, '', MIN(timestamp)
1083
+ FROM memories
1084
+ WHERE session_id IS NOT NULL AND session_id != '' AND agent_id IS NOT NULL AND agent_id != ''
1085
+ GROUP BY session_id, agent_id`,
1086
+ args: []
1087
+ });
1088
+ }
1089
+ } catch {
1090
+ }
1029
1091
  try {
1030
1092
  await client.execute({
1031
1093
  sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
@@ -1159,8 +1221,30 @@ async function ensureSchema() {
1159
1221
  });
1160
1222
  } catch {
1161
1223
  }
1224
+ for (const col of [
1225
+ "ALTER TABLE memories ADD COLUMN intent TEXT",
1226
+ "ALTER TABLE memories ADD COLUMN outcome TEXT",
1227
+ "ALTER TABLE memories ADD COLUMN domain TEXT",
1228
+ "ALTER TABLE memories ADD COLUMN referenced_entities TEXT",
1229
+ "ALTER TABLE memories ADD COLUMN retrieval_count INTEGER DEFAULT 0",
1230
+ "ALTER TABLE memories ADD COLUMN chain_position TEXT",
1231
+ "ALTER TABLE memories ADD COLUMN review_status TEXT",
1232
+ "ALTER TABLE memories ADD COLUMN context_window_pct INTEGER",
1233
+ "ALTER TABLE memories ADD COLUMN file_paths TEXT",
1234
+ "ALTER TABLE memories ADD COLUMN commit_hash TEXT",
1235
+ "ALTER TABLE memories ADD COLUMN duration_ms INTEGER",
1236
+ "ALTER TABLE memories ADD COLUMN token_cost REAL",
1237
+ "ALTER TABLE memories ADD COLUMN audience TEXT",
1238
+ "ALTER TABLE memories ADD COLUMN language_type TEXT",
1239
+ "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
1240
+ ]) {
1241
+ try {
1242
+ await client.execute(col);
1243
+ } catch {
1244
+ }
1245
+ }
1162
1246
  }
1163
- var _client, _resilientClient, initTurso;
1247
+ var _client, _resilientClient, _daemonClient, initTurso;
1164
1248
  var init_database = __esm({
1165
1249
  "src/lib/database.ts"() {
1166
1250
  "use strict";
@@ -1168,6 +1252,7 @@ var init_database = __esm({
1168
1252
  init_employees();
1169
1253
  _client = null;
1170
1254
  _resilientClient = null;
1255
+ _daemonClient = null;
1171
1256
  initTurso = initDatabase;
1172
1257
  }
1173
1258
  });
@@ -1726,39 +1811,75 @@ var init_provider_table = __esm({
1726
1811
  }
1727
1812
  });
1728
1813
 
1729
- // src/lib/intercom-queue.ts
1730
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, renameSync as renameSync3, existsSync as existsSync6, mkdirSync as mkdirSync2 } from "fs";
1814
+ // src/lib/runtime-table.ts
1815
+ var RUNTIME_TABLE;
1816
+ var init_runtime_table = __esm({
1817
+ "src/lib/runtime-table.ts"() {
1818
+ "use strict";
1819
+ RUNTIME_TABLE = {
1820
+ codex: {
1821
+ binary: "codex",
1822
+ launchMode: "exec",
1823
+ autoApproveFlag: "--full-auto",
1824
+ inlineFlag: "--no-alt-screen",
1825
+ apiKeyEnv: "OPENAI_API_KEY",
1826
+ defaultModel: "gpt-5.4"
1827
+ }
1828
+ };
1829
+ }
1830
+ });
1831
+
1832
+ // src/lib/agent-config.ts
1833
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, existsSync as existsSync6, mkdirSync as mkdirSync2 } from "fs";
1731
1834
  import path7 from "path";
1835
+ var AGENT_CONFIG_PATH, DEFAULT_MODELS;
1836
+ var init_agent_config = __esm({
1837
+ "src/lib/agent-config.ts"() {
1838
+ "use strict";
1839
+ init_config();
1840
+ init_runtime_table();
1841
+ AGENT_CONFIG_PATH = path7.join(EXE_AI_DIR, "agent-config.json");
1842
+ DEFAULT_MODELS = {
1843
+ claude: "claude-opus-4",
1844
+ codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
1845
+ opencode: "minimax-m2.7"
1846
+ };
1847
+ }
1848
+ });
1849
+
1850
+ // src/lib/intercom-queue.ts
1851
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync7, mkdirSync as mkdirSync3 } from "fs";
1852
+ import path8 from "path";
1732
1853
  import os6 from "os";
1733
1854
  var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
1734
1855
  var init_intercom_queue = __esm({
1735
1856
  "src/lib/intercom-queue.ts"() {
1736
1857
  "use strict";
1737
- QUEUE_PATH = path7.join(os6.homedir(), ".exe-os", "intercom-queue.json");
1858
+ QUEUE_PATH = path8.join(os6.homedir(), ".exe-os", "intercom-queue.json");
1738
1859
  TTL_MS = 60 * 60 * 1e3;
1739
- INTERCOM_LOG = path7.join(os6.homedir(), ".exe-os", "intercom.log");
1860
+ INTERCOM_LOG = path8.join(os6.homedir(), ".exe-os", "intercom.log");
1740
1861
  }
1741
1862
  });
1742
1863
 
1743
1864
  // src/lib/license.ts
1744
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync7, mkdirSync as mkdirSync3 } from "fs";
1865
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
1745
1866
  import { randomUUID as randomUUID2 } from "crypto";
1746
- import path8 from "path";
1867
+ import path9 from "path";
1747
1868
  import { jwtVerify, importSPKI } from "jose";
1748
1869
  var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
1749
1870
  var init_license = __esm({
1750
1871
  "src/lib/license.ts"() {
1751
1872
  "use strict";
1752
1873
  init_config();
1753
- LICENSE_PATH = path8.join(EXE_AI_DIR, "license.key");
1754
- CACHE_PATH = path8.join(EXE_AI_DIR, "license-cache.json");
1755
- DEVICE_ID_PATH = path8.join(EXE_AI_DIR, "device-id");
1874
+ LICENSE_PATH = path9.join(EXE_AI_DIR, "license.key");
1875
+ CACHE_PATH = path9.join(EXE_AI_DIR, "license-cache.json");
1876
+ DEVICE_ID_PATH = path9.join(EXE_AI_DIR, "device-id");
1756
1877
  }
1757
1878
  });
1758
1879
 
1759
1880
  // src/lib/plan-limits.ts
1760
- import { readFileSync as readFileSync6, existsSync as existsSync8 } from "fs";
1761
- import path9 from "path";
1881
+ import { readFileSync as readFileSync7, existsSync as existsSync9 } from "fs";
1882
+ import path10 from "path";
1762
1883
  var CACHE_PATH2;
1763
1884
  var init_plan_limits = __esm({
1764
1885
  "src/lib/plan-limits.ts"() {
@@ -1767,12 +1888,12 @@ var init_plan_limits = __esm({
1767
1888
  init_employees();
1768
1889
  init_license();
1769
1890
  init_config();
1770
- CACHE_PATH2 = path9.join(EXE_AI_DIR, "license-cache.json");
1891
+ CACHE_PATH2 = path10.join(EXE_AI_DIR, "license-cache.json");
1771
1892
  }
1772
1893
  });
1773
1894
 
1774
1895
  // src/lib/tmux-routing.ts
1775
- import path10 from "path";
1896
+ import path11 from "path";
1776
1897
  import os7 from "os";
1777
1898
  import { fileURLToPath as fileURLToPath2 } from "url";
1778
1899
  function extractRootExe(name) {
@@ -1796,27 +1917,29 @@ var init_tmux_routing = __esm({
1796
1917
  init_cc_agent_support();
1797
1918
  init_mcp_prefix();
1798
1919
  init_provider_table();
1920
+ init_agent_config();
1921
+ init_runtime_table();
1799
1922
  init_intercom_queue();
1800
1923
  init_plan_limits();
1801
1924
  init_employees();
1802
- SPAWN_LOCK_DIR = path10.join(os7.homedir(), ".exe-os", "spawn-locks");
1803
- SESSION_CACHE = path10.join(os7.homedir(), ".exe-os", "session-cache");
1804
- INTERCOM_LOG2 = path10.join(os7.homedir(), ".exe-os", "intercom.log");
1805
- DEBOUNCE_FILE = path10.join(SESSION_CACHE, "intercom-debounce.json");
1925
+ SPAWN_LOCK_DIR = path11.join(os7.homedir(), ".exe-os", "spawn-locks");
1926
+ SESSION_CACHE = path11.join(os7.homedir(), ".exe-os", "session-cache");
1927
+ INTERCOM_LOG2 = path11.join(os7.homedir(), ".exe-os", "intercom.log");
1928
+ DEBOUNCE_FILE = path11.join(SESSION_CACHE, "intercom-debounce.json");
1806
1929
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
1807
1930
  }
1808
1931
  });
1809
1932
 
1810
1933
  // src/lib/tasks-review.ts
1811
- import path11 from "path";
1812
- import { existsSync as existsSync9, readdirSync as readdirSync3, unlinkSync as unlinkSync3 } from "fs";
1934
+ import path12 from "path";
1935
+ import { existsSync as existsSync10, readdirSync as readdirSync3, unlinkSync as unlinkSync3 } from "fs";
1813
1936
  async function listPendingReviews(limit, sessionScope) {
1814
1937
  const client = getClient();
1815
1938
  if (sessionScope) {
1816
1939
  const result2 = await client.execute({
1817
1940
  sql: `SELECT title, assigned_to, project_name FROM tasks
1818
1941
  WHERE status = 'needs_review'
1819
- AND (session_scope = ? OR session_scope IS NULL)
1942
+ AND session_scope = ?
1820
1943
  ORDER BY priority ASC, created_at DESC LIMIT ?`,
1821
1944
  args: [sessionScope, limit]
1822
1945
  });
@@ -1879,6 +2002,7 @@ var init_tasks_review = __esm({
1879
2002
  });
1880
2003
 
1881
2004
  // src/lib/store.ts
2005
+ import { createHash } from "crypto";
1882
2006
  init_database();
1883
2007
 
1884
2008
  // src/lib/keychain.ts
@@ -1914,12 +2038,20 @@ async function getMasterKey() {
1914
2038
  }
1915
2039
  const keyPath = getKeyPath();
1916
2040
  if (!existsSync3(keyPath)) {
2041
+ process.stderr.write(
2042
+ `[keychain] Key not found at ${keyPath} (HOME=${os3.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
2043
+ `
2044
+ );
1917
2045
  return null;
1918
2046
  }
1919
2047
  try {
1920
2048
  const content = await readFile3(keyPath, "utf-8");
1921
2049
  return Buffer.from(content.trim(), "base64");
1922
- } catch {
2050
+ } catch (err) {
2051
+ process.stderr.write(
2052
+ `[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
2053
+ `
2054
+ );
1923
2055
  return null;
1924
2056
  }
1925
2057
  }
@@ -2009,6 +2141,7 @@ import { realpathSync } from "fs";
2009
2141
  import { fileURLToPath } from "url";
2010
2142
  function isMainModule(importMetaUrl) {
2011
2143
  if (process.argv[1] == null) return false;
2144
+ if (process.argv[1].includes("mcp/server")) return false;
2012
2145
  try {
2013
2146
  const scriptPath = realpathSync(process.argv[1]);
2014
2147
  const modulePath = realpathSync(fileURLToPath(importMetaUrl));