@askexenow/exe-os 0.9.7 → 0.9.8

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 (95) hide show
  1. package/dist/bin/backfill-conversations.js +754 -79
  2. package/dist/bin/backfill-responses.js +752 -77
  3. package/dist/bin/backfill-vectors.js +752 -77
  4. package/dist/bin/cleanup-stale-review-tasks.js +657 -35
  5. package/dist/bin/cli.js +1388 -605
  6. package/dist/bin/exe-agent-config.js +123 -95
  7. package/dist/bin/exe-agent.js +41 -25
  8. package/dist/bin/exe-assign.js +732 -57
  9. package/dist/bin/exe-boot.js +784 -153
  10. package/dist/bin/exe-call.js +209 -138
  11. package/dist/bin/exe-cloud.js +35 -12
  12. package/dist/bin/exe-dispatch.js +692 -70
  13. package/dist/bin/exe-doctor.js +648 -26
  14. package/dist/bin/exe-export-behaviors.js +650 -20
  15. package/dist/bin/exe-forget.js +635 -13
  16. package/dist/bin/exe-gateway.js +1053 -271
  17. package/dist/bin/exe-heartbeat.js +665 -43
  18. package/dist/bin/exe-kill.js +646 -16
  19. package/dist/bin/exe-launch-agent.js +887 -97
  20. package/dist/bin/exe-link.js +658 -43
  21. package/dist/bin/exe-new-employee.js +378 -177
  22. package/dist/bin/exe-pending-messages.js +656 -34
  23. package/dist/bin/exe-pending-notifications.js +635 -13
  24. package/dist/bin/exe-pending-reviews.js +659 -37
  25. package/dist/bin/exe-rename.js +645 -30
  26. package/dist/bin/exe-review.js +635 -13
  27. package/dist/bin/exe-search.js +771 -88
  28. package/dist/bin/exe-session-cleanup.js +834 -150
  29. package/dist/bin/exe-settings.js +127 -91
  30. package/dist/bin/exe-start-codex.js +729 -94
  31. package/dist/bin/exe-start-opencode.js +717 -82
  32. package/dist/bin/exe-status.js +657 -35
  33. package/dist/bin/exe-team.js +635 -13
  34. package/dist/bin/git-sweep.js +720 -89
  35. package/dist/bin/graph-backfill.js +643 -13
  36. package/dist/bin/graph-export.js +646 -16
  37. package/dist/bin/install.js +596 -193
  38. package/dist/bin/scan-tasks.js +724 -93
  39. package/dist/bin/setup.js +1038 -210
  40. package/dist/bin/shard-migrate.js +645 -15
  41. package/dist/bin/wiki-sync.js +646 -16
  42. package/dist/gateway/index.js +1027 -245
  43. package/dist/hooks/bug-report-worker.js +891 -170
  44. package/dist/hooks/commit-complete.js +718 -87
  45. package/dist/hooks/error-recall.js +776 -93
  46. package/dist/hooks/exe-heartbeat-hook.js +85 -71
  47. package/dist/hooks/ingest-worker.js +840 -156
  48. package/dist/hooks/ingest.js +90 -73
  49. package/dist/hooks/instructions-loaded.js +669 -38
  50. package/dist/hooks/notification.js +661 -30
  51. package/dist/hooks/post-compact.js +674 -43
  52. package/dist/hooks/pre-compact.js +718 -87
  53. package/dist/hooks/pre-tool-use.js +872 -125
  54. package/dist/hooks/prompt-ingest-worker.js +758 -83
  55. package/dist/hooks/prompt-submit.js +1060 -319
  56. package/dist/hooks/response-ingest-worker.js +758 -83
  57. package/dist/hooks/session-end.js +721 -90
  58. package/dist/hooks/session-start.js +1031 -207
  59. package/dist/hooks/stop.js +680 -49
  60. package/dist/hooks/subagent-stop.js +674 -43
  61. package/dist/hooks/summary-worker.js +816 -132
  62. package/dist/index.js +1015 -232
  63. package/dist/lib/cloud-sync.js +663 -48
  64. package/dist/lib/consolidation.js +26 -3
  65. package/dist/lib/database.js +626 -18
  66. package/dist/lib/db.js +2261 -0
  67. package/dist/lib/device-registry.js +640 -25
  68. package/dist/lib/embedder.js +96 -43
  69. package/dist/lib/employee-templates.js +16 -0
  70. package/dist/lib/employees.js +259 -83
  71. package/dist/lib/exe-daemon-client.js +101 -63
  72. package/dist/lib/exe-daemon.js +894 -162
  73. package/dist/lib/hybrid-search.js +771 -88
  74. package/dist/lib/identity.js +27 -7
  75. package/dist/lib/messaging.js +55 -28
  76. package/dist/lib/reminders.js +21 -1
  77. package/dist/lib/schedules.js +636 -14
  78. package/dist/lib/skill-learning.js +21 -1
  79. package/dist/lib/store.js +643 -13
  80. package/dist/lib/task-router.js +82 -71
  81. package/dist/lib/tasks.js +98 -71
  82. package/dist/lib/tmux-routing.js +87 -60
  83. package/dist/lib/token-spend.js +26 -6
  84. package/dist/mcp/server.js +1784 -458
  85. package/dist/mcp/tools/complete-reminder.js +21 -1
  86. package/dist/mcp/tools/create-reminder.js +21 -1
  87. package/dist/mcp/tools/create-task.js +290 -164
  88. package/dist/mcp/tools/deactivate-behavior.js +24 -4
  89. package/dist/mcp/tools/list-reminders.js +21 -1
  90. package/dist/mcp/tools/list-tasks.js +195 -38
  91. package/dist/mcp/tools/send-message.js +58 -31
  92. package/dist/mcp/tools/update-task.js +75 -48
  93. package/dist/runtime/index.js +720 -89
  94. package/dist/tui/App.js +853 -123
  95. package/package.json +3 -2
@@ -98,7 +98,7 @@ var init_config = __esm({
98
98
  init_config();
99
99
  import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
100
100
  import { readdirSync } from "fs";
101
- import path3 from "path";
101
+ import path4 from "path";
102
102
  import { createHash } from "crypto";
103
103
 
104
104
  // src/lib/database.ts
@@ -112,14 +112,34 @@ import { execSync } from "child_process";
112
112
  import path2 from "path";
113
113
  import os2 from "os";
114
114
  var EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
115
+ var IDENTITY_DIR = path2.join(EXE_AI_DIR, "identity");
116
+
117
+ // src/lib/database-adapter.ts
118
+ import os3 from "os";
119
+ import path3 from "path";
120
+ import { createRequire } from "module";
121
+ import { pathToFileURL } from "url";
122
+ var BOOLEAN_COLUMNS_BY_TABLE = {
123
+ memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
124
+ behaviors: /* @__PURE__ */ new Set(["active"]),
125
+ notifications: /* @__PURE__ */ new Set(["read"]),
126
+ users: /* @__PURE__ */ new Set(["has_personal_memory"])
127
+ };
128
+ var BOOLEAN_COLUMN_NAMES = new Set(
129
+ Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
130
+ );
115
131
 
116
132
  // src/lib/database.ts
117
133
  var _resilientClient = null;
118
134
  var _daemonClient = null;
135
+ var _adapterClient = null;
119
136
  function getClient() {
120
- if (!_resilientClient) {
137
+ if (!_adapterClient) {
121
138
  throw new Error("Database client not initialized. Call initDatabase() first.");
122
139
  }
140
+ if (process.env.DATABASE_URL) {
141
+ return _adapterClient;
142
+ }
123
143
  if (process.env.EXE_IS_DAEMON === "1") {
124
144
  return _resilientClient;
125
145
  }
@@ -130,14 +150,14 @@ function getClient() {
130
150
  }
131
151
 
132
152
  // src/lib/identity.ts
133
- var IDENTITY_DIR = path3.join(EXE_AI_DIR, "identity");
153
+ var IDENTITY_DIR2 = path4.join(EXE_AI_DIR, "identity");
134
154
  function ensureDir() {
135
- if (!existsSync3(IDENTITY_DIR)) {
136
- mkdirSync(IDENTITY_DIR, { recursive: true });
155
+ if (!existsSync3(IDENTITY_DIR2)) {
156
+ mkdirSync(IDENTITY_DIR2, { recursive: true });
137
157
  }
138
158
  }
139
159
  function identityPath(agentId) {
140
- return path3.join(IDENTITY_DIR, `${agentId}.md`);
160
+ return path4.join(IDENTITY_DIR2, `${agentId}.md`);
141
161
  }
142
162
  function parseFrontmatter(raw) {
143
163
  const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
@@ -210,7 +230,7 @@ async function updateIdentity(agentId, content, updatedBy) {
210
230
  }
211
231
  function listIdentities() {
212
232
  ensureDir();
213
- const files = readdirSync(IDENTITY_DIR).filter((f) => f.endsWith(".md"));
233
+ const files = readdirSync(IDENTITY_DIR2).filter((f) => f.endsWith(".md"));
214
234
  const results = [];
215
235
  for (const file of files) {
216
236
  const agentId = file.replace(".md", "");
@@ -154,7 +154,7 @@ function baseAgentName(name, employees) {
154
154
  if (getEmployee(roster, base)) return base;
155
155
  return name;
156
156
  }
157
- var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE;
157
+ var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, IDENTITY_DIR;
158
158
  var init_employees = __esm({
159
159
  "src/lib/employees.ts"() {
160
160
  "use strict";
@@ -162,15 +162,40 @@ var init_employees = __esm({
162
162
  EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
163
163
  DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
164
164
  COORDINATOR_ROLE = "COO";
165
+ IDENTITY_DIR = path2.join(EXE_AI_DIR, "identity");
166
+ }
167
+ });
168
+
169
+ // src/lib/database-adapter.ts
170
+ import os3 from "os";
171
+ import path3 from "path";
172
+ import { createRequire } from "module";
173
+ import { pathToFileURL } from "url";
174
+ var BOOLEAN_COLUMNS_BY_TABLE, BOOLEAN_COLUMN_NAMES;
175
+ var init_database_adapter = __esm({
176
+ "src/lib/database-adapter.ts"() {
177
+ "use strict";
178
+ BOOLEAN_COLUMNS_BY_TABLE = {
179
+ memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
180
+ behaviors: /* @__PURE__ */ new Set(["active"]),
181
+ notifications: /* @__PURE__ */ new Set(["read"]),
182
+ users: /* @__PURE__ */ new Set(["has_personal_memory"])
183
+ };
184
+ BOOLEAN_COLUMN_NAMES = new Set(
185
+ Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
186
+ );
165
187
  }
166
188
  });
167
189
 
168
190
  // src/lib/database.ts
169
191
  import { createClient } from "@libsql/client";
170
192
  function getClient() {
171
- if (!_resilientClient) {
193
+ if (!_adapterClient) {
172
194
  throw new Error("Database client not initialized. Call initDatabase() first.");
173
195
  }
196
+ if (process.env.DATABASE_URL) {
197
+ return _adapterClient;
198
+ }
174
199
  if (process.env.EXE_IS_DAEMON === "1") {
175
200
  return _resilientClient;
176
201
  }
@@ -179,25 +204,27 @@ function getClient() {
179
204
  }
180
205
  return _resilientClient;
181
206
  }
182
- var _resilientClient, _daemonClient;
207
+ var _resilientClient, _daemonClient, _adapterClient;
183
208
  var init_database = __esm({
184
209
  "src/lib/database.ts"() {
185
210
  "use strict";
186
211
  init_db_retry();
187
212
  init_employees();
213
+ init_database_adapter();
188
214
  _resilientClient = null;
189
215
  _daemonClient = null;
216
+ _adapterClient = null;
190
217
  }
191
218
  });
192
219
 
193
220
  // src/lib/session-registry.ts
194
- import path3 from "path";
195
- import os3 from "os";
221
+ import path4 from "path";
222
+ import os4 from "os";
196
223
  var REGISTRY_PATH;
197
224
  var init_session_registry = __esm({
198
225
  "src/lib/session-registry.ts"() {
199
226
  "use strict";
200
- REGISTRY_PATH = path3.join(os3.homedir(), ".exe-os", "session-registry.json");
227
+ REGISTRY_PATH = path4.join(os4.homedir(), ".exe-os", "session-registry.json");
201
228
  }
202
229
  });
203
230
 
@@ -434,7 +461,7 @@ var init_runtime_table = __esm({
434
461
 
435
462
  // src/lib/agent-config.ts
436
463
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync } from "fs";
437
- import path4 from "path";
464
+ import path5 from "path";
438
465
  function loadAgentConfig() {
439
466
  if (!existsSync3(AGENT_CONFIG_PATH)) return {};
440
467
  try {
@@ -457,7 +484,7 @@ var init_agent_config = __esm({
457
484
  "use strict";
458
485
  init_config();
459
486
  init_runtime_table();
460
- AGENT_CONFIG_PATH = path4.join(EXE_AI_DIR, "agent-config.json");
487
+ AGENT_CONFIG_PATH = path5.join(EXE_AI_DIR, "agent-config.json");
461
488
  DEFAULT_MODELS = {
462
489
  claude: "claude-opus-4",
463
490
  codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
@@ -468,10 +495,10 @@ var init_agent_config = __esm({
468
495
 
469
496
  // src/lib/intercom-queue.ts
470
497
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
471
- import path5 from "path";
472
- import os4 from "os";
498
+ import path6 from "path";
499
+ import os5 from "os";
473
500
  function ensureDir() {
474
- const dir = path5.dirname(QUEUE_PATH);
501
+ const dir = path6.dirname(QUEUE_PATH);
475
502
  if (!existsSync4(dir)) mkdirSync2(dir, { recursive: true });
476
503
  }
477
504
  function readQueue() {
@@ -509,31 +536,31 @@ var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
509
536
  var init_intercom_queue = __esm({
510
537
  "src/lib/intercom-queue.ts"() {
511
538
  "use strict";
512
- QUEUE_PATH = path5.join(os4.homedir(), ".exe-os", "intercom-queue.json");
539
+ QUEUE_PATH = path6.join(os5.homedir(), ".exe-os", "intercom-queue.json");
513
540
  TTL_MS = 60 * 60 * 1e3;
514
- INTERCOM_LOG = path5.join(os4.homedir(), ".exe-os", "intercom.log");
541
+ INTERCOM_LOG = path6.join(os5.homedir(), ".exe-os", "intercom.log");
515
542
  }
516
543
  });
517
544
 
518
545
  // src/lib/license.ts
519
546
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
520
547
  import { randomUUID } from "crypto";
521
- import path6 from "path";
548
+ import path7 from "path";
522
549
  import { jwtVerify, importSPKI } from "jose";
523
550
  var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
524
551
  var init_license = __esm({
525
552
  "src/lib/license.ts"() {
526
553
  "use strict";
527
554
  init_config();
528
- LICENSE_PATH = path6.join(EXE_AI_DIR, "license.key");
529
- CACHE_PATH = path6.join(EXE_AI_DIR, "license-cache.json");
530
- DEVICE_ID_PATH = path6.join(EXE_AI_DIR, "device-id");
555
+ LICENSE_PATH = path7.join(EXE_AI_DIR, "license.key");
556
+ CACHE_PATH = path7.join(EXE_AI_DIR, "license-cache.json");
557
+ DEVICE_ID_PATH = path7.join(EXE_AI_DIR, "device-id");
531
558
  }
532
559
  });
533
560
 
534
561
  // src/lib/plan-limits.ts
535
562
  import { readFileSync as readFileSync6, existsSync as existsSync6 } from "fs";
536
- import path7 from "path";
563
+ import path8 from "path";
537
564
  var CACHE_PATH2;
538
565
  var init_plan_limits = __esm({
539
566
  "src/lib/plan-limits.ts"() {
@@ -542,15 +569,15 @@ var init_plan_limits = __esm({
542
569
  init_employees();
543
570
  init_license();
544
571
  init_config();
545
- CACHE_PATH2 = path7.join(EXE_AI_DIR, "license-cache.json");
572
+ CACHE_PATH2 = path8.join(EXE_AI_DIR, "license-cache.json");
546
573
  }
547
574
  });
548
575
 
549
576
  // src/lib/tmux-routing.ts
550
577
  import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
551
578
  import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync7, appendFileSync, readdirSync } from "fs";
552
- import path8 from "path";
553
- import os5 from "os";
579
+ import path9 from "path";
580
+ import os6 from "os";
554
581
  import { fileURLToPath } from "url";
555
582
  function getMySession() {
556
583
  return getTransport().getMySession();
@@ -590,7 +617,7 @@ function extractRootExe(name) {
590
617
  }
591
618
  function getParentExe(sessionKey) {
592
619
  try {
593
- const data = JSON.parse(readFileSync7(path8.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
620
+ const data = JSON.parse(readFileSync7(path9.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
594
621
  return data.parentExe || null;
595
622
  } catch {
596
623
  return null;
@@ -735,7 +762,7 @@ function sendIntercom(targetSession) {
735
762
  try {
736
763
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
737
764
  const agent = baseAgentName(rawAgent);
738
- const markerPath = path8.join(SESSION_CACHE, `current-task-${agent}.json`);
765
+ const markerPath = path9.join(SESSION_CACHE, `current-task-${agent}.json`);
739
766
  if (existsSync7(markerPath)) {
740
767
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker \u2014 will auto-chain)`);
741
768
  return "debounced";
@@ -745,7 +772,7 @@ function sendIntercom(targetSession) {
745
772
  try {
746
773
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
747
774
  const agent = baseAgentName(rawAgent);
748
- const taskDir = path8.join(process.cwd(), "exe", agent);
775
+ const taskDir = path9.join(process.cwd(), "exe", agent);
749
776
  if (existsSync7(taskDir)) {
750
777
  const files = readdirSync(taskDir).filter(
751
778
  (f) => f.endsWith(".md") && f !== "DONE.txt"
@@ -799,13 +826,13 @@ var init_tmux_routing = __esm({
799
826
  init_intercom_queue();
800
827
  init_plan_limits();
801
828
  init_employees();
802
- SPAWN_LOCK_DIR = path8.join(os5.homedir(), ".exe-os", "spawn-locks");
803
- SESSION_CACHE = path8.join(os5.homedir(), ".exe-os", "session-cache");
829
+ SPAWN_LOCK_DIR = path9.join(os6.homedir(), ".exe-os", "spawn-locks");
830
+ SESSION_CACHE = path9.join(os6.homedir(), ".exe-os", "session-cache");
804
831
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
805
832
  INTERCOM_DEBOUNCE_MS = 3e4;
806
833
  CODEX_DEBOUNCE_MS = 12e4;
807
- INTERCOM_LOG2 = path8.join(os5.homedir(), ".exe-os", "intercom.log");
808
- DEBOUNCE_FILE = path8.join(SESSION_CACHE, "intercom-debounce.json");
834
+ INTERCOM_LOG2 = path9.join(os6.homedir(), ".exe-os", "intercom.log");
835
+ DEBOUNCE_FILE = path9.join(SESSION_CACHE, "intercom-debounce.json");
809
836
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
810
837
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
811
838
  }
@@ -108,14 +108,34 @@ import { execSync } from "child_process";
108
108
  import path2 from "path";
109
109
  import os2 from "os";
110
110
  var EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
111
+ var IDENTITY_DIR = path2.join(EXE_AI_DIR, "identity");
112
+
113
+ // src/lib/database-adapter.ts
114
+ import os3 from "os";
115
+ import path3 from "path";
116
+ import { createRequire } from "module";
117
+ import { pathToFileURL } from "url";
118
+ var BOOLEAN_COLUMNS_BY_TABLE = {
119
+ memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
120
+ behaviors: /* @__PURE__ */ new Set(["active"]),
121
+ notifications: /* @__PURE__ */ new Set(["read"]),
122
+ users: /* @__PURE__ */ new Set(["has_personal_memory"])
123
+ };
124
+ var BOOLEAN_COLUMN_NAMES = new Set(
125
+ Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
126
+ );
111
127
 
112
128
  // src/lib/database.ts
113
129
  var _resilientClient = null;
114
130
  var _daemonClient = null;
131
+ var _adapterClient = null;
115
132
  function getClient() {
116
- if (!_resilientClient) {
133
+ if (!_adapterClient) {
117
134
  throw new Error("Database client not initialized. Call initDatabase() first.");
118
135
  }
136
+ if (process.env.DATABASE_URL) {
137
+ return _adapterClient;
138
+ }
119
139
  if (process.env.EXE_IS_DAEMON === "1") {
120
140
  return _resilientClient;
121
141
  }