@askexenow/exe-os 0.9.7 → 0.9.9

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 (101) hide show
  1. package/dist/bin/backfill-conversations.js +953 -105
  2. package/dist/bin/backfill-responses.js +952 -104
  3. package/dist/bin/backfill-vectors.js +956 -108
  4. package/dist/bin/cleanup-stale-review-tasks.js +802 -58
  5. package/dist/bin/cli.js +2292 -1070
  6. package/dist/bin/exe-agent-config.js +157 -101
  7. package/dist/bin/exe-agent.js +55 -29
  8. package/dist/bin/exe-assign.js +940 -92
  9. package/dist/bin/exe-boot.js +1424 -442
  10. package/dist/bin/exe-call.js +240 -141
  11. package/dist/bin/exe-cloud.js +198 -70
  12. package/dist/bin/exe-dispatch.js +951 -192
  13. package/dist/bin/exe-doctor.js +791 -51
  14. package/dist/bin/exe-export-behaviors.js +790 -42
  15. package/dist/bin/exe-forget.js +771 -31
  16. package/dist/bin/exe-gateway.js +1592 -521
  17. package/dist/bin/exe-heartbeat.js +850 -109
  18. package/dist/bin/exe-kill.js +783 -35
  19. package/dist/bin/exe-launch-agent.js +1030 -107
  20. package/dist/bin/exe-link.js +916 -110
  21. package/dist/bin/exe-new-employee.js +526 -217
  22. package/dist/bin/exe-pending-messages.js +1046 -62
  23. package/dist/bin/exe-pending-notifications.js +1318 -111
  24. package/dist/bin/exe-pending-reviews.js +1040 -72
  25. package/dist/bin/exe-rename.js +772 -59
  26. package/dist/bin/exe-review.js +772 -32
  27. package/dist/bin/exe-search.js +982 -128
  28. package/dist/bin/exe-session-cleanup.js +1180 -306
  29. package/dist/bin/exe-settings.js +185 -105
  30. package/dist/bin/exe-start-codex.js +886 -132
  31. package/dist/bin/exe-start-opencode.js +873 -119
  32. package/dist/bin/exe-status.js +803 -59
  33. package/dist/bin/exe-team.js +772 -32
  34. package/dist/bin/git-sweep.js +1046 -223
  35. package/dist/bin/graph-backfill.js +779 -31
  36. package/dist/bin/graph-export.js +785 -37
  37. package/dist/bin/install.js +632 -200
  38. package/dist/bin/scan-tasks.js +1055 -232
  39. package/dist/bin/setup.js +1419 -320
  40. package/dist/bin/shard-migrate.js +783 -35
  41. package/dist/bin/update.js +138 -49
  42. package/dist/bin/wiki-sync.js +782 -34
  43. package/dist/gateway/index.js +1444 -449
  44. package/dist/hooks/bug-report-worker.js +1141 -269
  45. package/dist/hooks/codex-stop-task-finalizer.js +4678 -0
  46. package/dist/hooks/commit-complete.js +1044 -221
  47. package/dist/hooks/error-recall.js +989 -135
  48. package/dist/hooks/exe-heartbeat-hook.js +99 -75
  49. package/dist/hooks/ingest-worker.js +4176 -3226
  50. package/dist/hooks/ingest.js +920 -168
  51. package/dist/hooks/instructions-loaded.js +874 -70
  52. package/dist/hooks/notification.js +860 -56
  53. package/dist/hooks/post-compact.js +881 -73
  54. package/dist/hooks/pre-compact.js +1050 -227
  55. package/dist/hooks/pre-tool-use.js +1084 -159
  56. package/dist/hooks/prompt-ingest-worker.js +1089 -164
  57. package/dist/hooks/prompt-submit.js +1469 -515
  58. package/dist/hooks/response-ingest-worker.js +1104 -179
  59. package/dist/hooks/session-end.js +1085 -251
  60. package/dist/hooks/session-start.js +1241 -231
  61. package/dist/hooks/stop.js +935 -109
  62. package/dist/hooks/subagent-stop.js +881 -73
  63. package/dist/hooks/summary-worker.js +1323 -307
  64. package/dist/index.js +1449 -452
  65. package/dist/lib/agent-config.js +28 -6
  66. package/dist/lib/cloud-sync.js +909 -115
  67. package/dist/lib/config.js +30 -10
  68. package/dist/lib/consolidation.js +42 -9
  69. package/dist/lib/database.js +739 -33
  70. package/dist/lib/db-daemon-client.js +73 -19
  71. package/dist/lib/db.js +2359 -0
  72. package/dist/lib/device-registry.js +760 -47
  73. package/dist/lib/embedder.js +201 -73
  74. package/dist/lib/employee-templates.js +30 -4
  75. package/dist/lib/employees.js +290 -86
  76. package/dist/lib/exe-daemon-client.js +187 -83
  77. package/dist/lib/exe-daemon.js +1696 -616
  78. package/dist/lib/hybrid-search.js +982 -128
  79. package/dist/lib/identity.js +43 -13
  80. package/dist/lib/license.js +133 -48
  81. package/dist/lib/messaging.js +167 -80
  82. package/dist/lib/reminders.js +35 -5
  83. package/dist/lib/schedules.js +772 -32
  84. package/dist/lib/skill-learning.js +54 -7
  85. package/dist/lib/store.js +779 -31
  86. package/dist/lib/task-router.js +94 -73
  87. package/dist/lib/tasks.js +298 -225
  88. package/dist/lib/tmux-routing.js +246 -172
  89. package/dist/lib/token-spend.js +52 -14
  90. package/dist/mcp/server.js +2893 -850
  91. package/dist/mcp/tools/complete-reminder.js +35 -5
  92. package/dist/mcp/tools/create-reminder.js +35 -5
  93. package/dist/mcp/tools/create-task.js +507 -323
  94. package/dist/mcp/tools/deactivate-behavior.js +40 -10
  95. package/dist/mcp/tools/list-reminders.js +35 -5
  96. package/dist/mcp/tools/list-tasks.js +277 -104
  97. package/dist/mcp/tools/send-message.js +129 -56
  98. package/dist/mcp/tools/update-task.js +1864 -188
  99. package/dist/runtime/index.js +1083 -259
  100. package/dist/tui/App.js +1501 -434
  101. package/package.json +3 -2
@@ -3,21 +3,42 @@ import net from "net";
3
3
  import os2 from "os";
4
4
  import { spawn } from "child_process";
5
5
  import { randomUUID } from "crypto";
6
- import { existsSync as existsSync2, unlinkSync, readFileSync as readFileSync2, openSync, closeSync, statSync } from "fs";
7
- import path2 from "path";
6
+ import { existsSync as existsSync4, unlinkSync, readFileSync as readFileSync3, openSync, closeSync, statSync } from "fs";
7
+ import path3 from "path";
8
8
  import { fileURLToPath } from "url";
9
9
 
10
10
  // src/lib/config.ts
11
- import { readFile, writeFile, mkdir, chmod } from "fs/promises";
12
- import { readFileSync, existsSync, renameSync } from "fs";
11
+ import { readFile, writeFile } from "fs/promises";
12
+ import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
13
13
  import path from "path";
14
14
  import os from "os";
15
+
16
+ // src/lib/secure-files.ts
17
+ import { chmodSync, existsSync, mkdirSync } from "fs";
18
+ import { chmod, mkdir } from "fs/promises";
19
+ var PRIVATE_DIR_MODE = 448;
20
+ var PRIVATE_FILE_MODE = 384;
21
+ function ensurePrivateDirSync(dirPath) {
22
+ mkdirSync(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
23
+ try {
24
+ chmodSync(dirPath, PRIVATE_DIR_MODE);
25
+ } catch {
26
+ }
27
+ }
28
+ function enforcePrivateFileSync(filePath) {
29
+ try {
30
+ if (existsSync(filePath)) chmodSync(filePath, PRIVATE_FILE_MODE);
31
+ } catch {
32
+ }
33
+ }
34
+
35
+ // src/lib/config.ts
15
36
  function resolveDataDir() {
16
37
  if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
17
38
  if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
18
39
  const newDir = path.join(os.homedir(), ".exe-os");
19
40
  const legacyDir = path.join(os.homedir(), ".exe-mem");
20
- if (!existsSync(newDir) && existsSync(legacyDir)) {
41
+ if (!existsSync2(newDir) && existsSync2(legacyDir)) {
21
42
  try {
22
43
  renameSync(legacyDir, newDir);
23
44
  process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
@@ -92,13 +113,43 @@ var DEFAULT_CONFIG = {
92
113
  }
93
114
  };
94
115
 
116
+ // src/lib/daemon-auth.ts
117
+ import crypto from "crypto";
118
+ import path2 from "path";
119
+ import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync } from "fs";
120
+ var DAEMON_TOKEN_PATH = path2.join(EXE_AI_DIR, "exed.token");
121
+ function normalizeToken(token) {
122
+ if (!token) return null;
123
+ const trimmed = token.trim();
124
+ return trimmed.length > 0 ? trimmed : null;
125
+ }
126
+ function readDaemonToken() {
127
+ try {
128
+ if (!existsSync3(DAEMON_TOKEN_PATH)) return null;
129
+ return normalizeToken(readFileSync2(DAEMON_TOKEN_PATH, "utf8"));
130
+ } catch {
131
+ return null;
132
+ }
133
+ }
134
+ function ensureDaemonToken(seed) {
135
+ const existing = readDaemonToken();
136
+ if (existing) return existing;
137
+ const token = normalizeToken(seed) ?? crypto.randomBytes(32).toString("hex");
138
+ ensurePrivateDirSync(EXE_AI_DIR);
139
+ writeFileSync(DAEMON_TOKEN_PATH, `${token}
140
+ `, "utf8");
141
+ enforcePrivateFileSync(DAEMON_TOKEN_PATH);
142
+ return token;
143
+ }
144
+
95
145
  // src/lib/exe-daemon-client.ts
96
- var SOCKET_PATH = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path2.join(EXE_AI_DIR, "exed.sock");
97
- var PID_PATH = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path2.join(EXE_AI_DIR, "exed.pid");
98
- var SPAWN_LOCK_PATH = path2.join(EXE_AI_DIR, "exed-spawn.lock");
146
+ var SOCKET_PATH = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path3.join(EXE_AI_DIR, "exed.sock");
147
+ var PID_PATH = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path3.join(EXE_AI_DIR, "exed.pid");
148
+ var SPAWN_LOCK_PATH = path3.join(EXE_AI_DIR, "exed-spawn.lock");
99
149
  var SPAWN_LOCK_STALE_MS = 3e4;
100
150
  var CONNECT_TIMEOUT_MS = 15e3;
101
151
  var REQUEST_TIMEOUT_MS = 3e4;
152
+ var DAEMON_TOKEN_ENV = "EXE_DAEMON_TOKEN";
102
153
  var _socket = null;
103
154
  var _connected = false;
104
155
  var _buffer = "";
@@ -130,9 +181,9 @@ function handleData(chunk) {
130
181
  }
131
182
  }
132
183
  function cleanupStaleFiles() {
133
- if (existsSync2(PID_PATH)) {
184
+ if (existsSync4(PID_PATH)) {
134
185
  try {
135
- const pid = parseInt(readFileSync2(PID_PATH, "utf8").trim(), 10);
186
+ const pid = parseInt(readFileSync3(PID_PATH, "utf8").trim(), 10);
136
187
  if (pid > 0) {
137
188
  try {
138
189
  process.kill(pid, 0);
@@ -153,11 +204,11 @@ function cleanupStaleFiles() {
153
204
  }
154
205
  }
155
206
  function findPackageRoot() {
156
- let dir = path2.dirname(fileURLToPath(import.meta.url));
157
- const { root } = path2.parse(dir);
207
+ let dir = path3.dirname(fileURLToPath(import.meta.url));
208
+ const { root } = path3.parse(dir);
158
209
  while (dir !== root) {
159
- if (existsSync2(path2.join(dir, "package.json"))) return dir;
160
- dir = path2.dirname(dir);
210
+ if (existsSync4(path3.join(dir, "package.json"))) return dir;
211
+ dir = path3.dirname(dir);
161
212
  }
162
213
  return null;
163
214
  }
@@ -183,16 +234,17 @@ function spawnDaemon() {
183
234
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
184
235
  return;
185
236
  }
186
- const daemonPath = path2.join(pkgRoot, "dist", "lib", "exe-daemon.js");
187
- if (!existsSync2(daemonPath)) {
237
+ const daemonPath = path3.join(pkgRoot, "dist", "lib", "exe-daemon.js");
238
+ if (!existsSync4(daemonPath)) {
188
239
  process.stderr.write(`[exed-client] WARN: daemon script not found at ${daemonPath}
189
240
  `);
190
241
  return;
191
242
  }
192
243
  const resolvedPath = daemonPath;
244
+ const daemonToken = ensureDaemonToken(process.env[DAEMON_TOKEN_ENV] ?? null);
193
245
  process.stderr.write(`[exed-client] Spawning daemon: ${resolvedPath}
194
246
  `);
195
- const logPath = path2.join(path2.dirname(SOCKET_PATH), "exed.log");
247
+ const logPath = path3.join(path3.dirname(SOCKET_PATH), "exed.log");
196
248
  let stderrFd = "ignore";
197
249
  try {
198
250
  stderrFd = openSync(logPath, "a");
@@ -210,7 +262,8 @@ function spawnDaemon() {
210
262
  TMUX_PANE: void 0,
211
263
  // Prevents resolveExeSession() from scoping to one session
212
264
  EXE_DAEMON_SOCK: SOCKET_PATH,
213
- EXE_DAEMON_PID: PID_PATH
265
+ EXE_DAEMON_PID: PID_PATH,
266
+ [DAEMON_TOKEN_ENV]: daemonToken
214
267
  }
215
268
  });
216
269
  child.unref();
@@ -317,13 +370,14 @@ function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
317
370
  return;
318
371
  }
319
372
  const id = randomUUID();
373
+ const token = process.env[DAEMON_TOKEN_ENV] ?? readDaemonToken();
320
374
  const timer = setTimeout(() => {
321
375
  _pending.delete(id);
322
376
  resolve({ error: "Request timeout" });
323
377
  }, timeoutMs);
324
378
  _pending.set(id, { resolve, timer });
325
379
  try {
326
- _socket.write(JSON.stringify({ id, ...payload }) + "\n");
380
+ _socket.write(JSON.stringify({ id, token, ...payload }) + "\n");
327
381
  } catch {
328
382
  clearTimeout(timer);
329
383
  _pending.delete(id);