@askexenow/exe-os 0.9.113 → 0.9.115

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 (86) hide show
  1. package/dist/bin/agentic-ontology-backfill.js +36 -12
  2. package/dist/bin/agentic-reflection-backfill.js +36 -12
  3. package/dist/bin/agentic-semantic-label.js +36 -12
  4. package/dist/bin/backfill-conversations.js +36 -12
  5. package/dist/bin/backfill-responses.js +36 -12
  6. package/dist/bin/backfill-vectors.js +36 -12
  7. package/dist/bin/bulk-sync-postgres.js +36 -12
  8. package/dist/bin/cleanup-stale-review-tasks.js +470 -113
  9. package/dist/bin/cli.js +413 -62
  10. package/dist/bin/exe-agent.js +27 -0
  11. package/dist/bin/exe-assign.js +36 -12
  12. package/dist/bin/exe-boot.js +246 -54
  13. package/dist/bin/exe-call.js +8 -0
  14. package/dist/bin/exe-cloud.js +47 -12
  15. package/dist/bin/exe-dispatch.js +348 -53
  16. package/dist/bin/exe-doctor.js +51 -13
  17. package/dist/bin/exe-export-behaviors.js +37 -12
  18. package/dist/bin/exe-forget.js +36 -12
  19. package/dist/bin/exe-gateway.js +348 -53
  20. package/dist/bin/exe-heartbeat.js +471 -113
  21. package/dist/bin/exe-kill.js +36 -12
  22. package/dist/bin/exe-launch-agent.js +117 -18
  23. package/dist/bin/exe-new-employee.js +9 -1
  24. package/dist/bin/exe-pending-messages.js +452 -95
  25. package/dist/bin/exe-pending-notifications.js +452 -95
  26. package/dist/bin/exe-pending-reviews.js +452 -95
  27. package/dist/bin/exe-rename.js +36 -12
  28. package/dist/bin/exe-review.js +36 -12
  29. package/dist/bin/exe-search.js +37 -12
  30. package/dist/bin/exe-session-cleanup.js +348 -53
  31. package/dist/bin/exe-settings.js +12 -0
  32. package/dist/bin/exe-start-codex.js +46 -13
  33. package/dist/bin/exe-start-opencode.js +46 -13
  34. package/dist/bin/exe-status.js +460 -114
  35. package/dist/bin/exe-support.js +12 -0
  36. package/dist/bin/exe-team.js +36 -12
  37. package/dist/bin/git-sweep.js +348 -53
  38. package/dist/bin/graph-backfill.js +36 -12
  39. package/dist/bin/graph-export.js +36 -12
  40. package/dist/bin/install.js +9 -1
  41. package/dist/bin/intercom-check.js +255 -53
  42. package/dist/bin/scan-tasks.js +348 -53
  43. package/dist/bin/setup.js +74 -12
  44. package/dist/bin/shard-migrate.js +36 -12
  45. package/dist/gateway/index.js +348 -53
  46. package/dist/hooks/bug-report-worker.js +348 -53
  47. package/dist/hooks/codex-stop-task-finalizer.js +308 -37
  48. package/dist/hooks/commit-complete.js +348 -53
  49. package/dist/hooks/error-recall.js +37 -12
  50. package/dist/hooks/ingest.js +363 -54
  51. package/dist/hooks/instructions-loaded.js +36 -12
  52. package/dist/hooks/notification.js +36 -12
  53. package/dist/hooks/post-compact.js +426 -72
  54. package/dist/hooks/post-tool-combined.js +501 -146
  55. package/dist/hooks/pre-compact.js +348 -53
  56. package/dist/hooks/pre-tool-use.js +92 -13
  57. package/dist/hooks/prompt-submit.js +348 -53
  58. package/dist/hooks/session-end.js +158 -53
  59. package/dist/hooks/session-start.js +66 -13
  60. package/dist/hooks/stop.js +420 -72
  61. package/dist/hooks/subagent-stop.js +419 -72
  62. package/dist/hooks/summary-worker.js +442 -121
  63. package/dist/index.js +375 -53
  64. package/dist/lib/agent-config.js +8 -0
  65. package/dist/lib/cloud-sync.js +35 -12
  66. package/dist/lib/config.js +13 -0
  67. package/dist/lib/consolidation.js +9 -1
  68. package/dist/lib/embedder.js +13 -0
  69. package/dist/lib/employees.js +8 -0
  70. package/dist/lib/exe-daemon.js +524 -60
  71. package/dist/lib/hybrid-search.js +37 -12
  72. package/dist/lib/keychain.js +25 -13
  73. package/dist/lib/messaging.js +395 -74
  74. package/dist/lib/schedules.js +36 -12
  75. package/dist/lib/skill-learning.js +21 -0
  76. package/dist/lib/store.js +36 -12
  77. package/dist/lib/tasks.js +324 -41
  78. package/dist/lib/tmux-routing.js +324 -41
  79. package/dist/mcp/server.js +374 -54
  80. package/dist/mcp/tools/create-task.js +324 -41
  81. package/dist/mcp/tools/list-tasks.js +406 -57
  82. package/dist/mcp/tools/send-message.js +395 -74
  83. package/dist/mcp/tools/update-task.js +324 -41
  84. package/dist/runtime/index.js +375 -53
  85. package/dist/tui/App.js +377 -55
  86. package/package.json +1 -1
@@ -207,6 +207,17 @@ function normalizeOrchestration(raw) {
207
207
  const userOrg = raw.orchestration ?? {};
208
208
  raw.orchestration = { ...defaultOrg, ...userOrg };
209
209
  }
210
+ function normalizeCloudEndpoint(raw) {
211
+ const cloud = raw.cloud;
212
+ if (!cloud?.endpoint) return;
213
+ const ep = String(cloud.endpoint);
214
+ if (ep === "https://askexe.com/cloud" || ep === "https://askexe.com/cloud/") {
215
+ cloud.endpoint = "https://cloud.askexe.com";
216
+ process.stderr.write(
217
+ "[config] Auto-migrated cloud endpoint: askexe.com/cloud \u2192 cloud.askexe.com\n"
218
+ );
219
+ }
220
+ }
210
221
  async function loadConfig() {
211
222
  const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
212
223
  await ensurePrivateDir(dir);
@@ -232,6 +243,7 @@ async function loadConfig() {
232
243
  normalizeSessionLifecycle(migratedCfg);
233
244
  normalizeAutoUpdate(migratedCfg);
234
245
  normalizeOrchestration(migratedCfg);
246
+ normalizeCloudEndpoint(migratedCfg);
235
247
  const config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
236
248
  if (config.dbPath.startsWith("~")) {
237
249
  config.dbPath = config.dbPath.replace(/^~/, os.homedir());
@@ -260,6 +272,7 @@ function loadConfigSync() {
260
272
  normalizeSessionLifecycle(migratedCfg);
261
273
  normalizeAutoUpdate(migratedCfg);
262
274
  normalizeOrchestration(migratedCfg);
275
+ normalizeCloudEndpoint(migratedCfg);
263
276
  const config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
264
277
  if (config.dbPath.startsWith("~")) {
265
278
  config.dbPath = config.dbPath.replace(/^~/, os.homedir());
@@ -3314,7 +3327,7 @@ var init_database = __esm({
3314
3327
  });
3315
3328
 
3316
3329
  // src/lib/keychain.ts
3317
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3330
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
3318
3331
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
3319
3332
  import { execSync as execSync3 } from "child_process";
3320
3333
  import path6 from "path";
@@ -3349,12 +3362,14 @@ function linuxSecretAvailable() {
3349
3362
  function isRootOnlyTrustedServerKeyFile(keyPath) {
3350
3363
  if (process.platform !== "linux") return false;
3351
3364
  try {
3352
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3353
3365
  const st = statSync3(keyPath);
3354
3366
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
3367
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3355
3368
  if (uid === 0) return true;
3356
3369
  const exeOsDir = process.env.EXE_OS_DIR;
3357
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
3370
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
3371
+ if (!linuxSecretAvailable()) return true;
3372
+ return false;
3358
3373
  } catch {
3359
3374
  return false;
3360
3375
  }
@@ -3504,15 +3519,25 @@ async function writeMachineBoundFileFallback(b64) {
3504
3519
  await mkdir3(dir, { recursive: true });
3505
3520
  const keyPath = getKeyPath();
3506
3521
  const machineKey = deriveMachineKey();
3507
- if (machineKey) {
3508
- const encrypted = encryptWithMachineKey(b64, machineKey);
3509
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
3510
- await chmod2(keyPath, 384);
3511
- return "encrypted";
3522
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
3523
+ const result = machineKey ? "encrypted" : "plaintext";
3524
+ const tmpPath = keyPath + ".tmp";
3525
+ try {
3526
+ if (existsSync7(keyPath)) {
3527
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
3528
+ });
3529
+ }
3530
+ await writeFile3(tmpPath, content, "utf-8");
3531
+ await chmod2(tmpPath, 384);
3532
+ await rename(tmpPath, keyPath);
3533
+ } catch (err) {
3534
+ try {
3535
+ await unlink(tmpPath);
3536
+ } catch {
3537
+ }
3538
+ throw err;
3512
3539
  }
3513
- await writeFile3(keyPath, b64 + "\n", "utf-8");
3514
- await chmod2(keyPath, 384);
3515
- return "plaintext";
3540
+ return result;
3516
3541
  }
3517
3542
  async function getMasterKey() {
3518
3543
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -3579,7 +3604,7 @@ async function getMasterKey() {
3579
3604
  b64Value = content;
3580
3605
  }
3581
3606
  const key = Buffer.from(b64Value, "base64");
3582
- if (!content.startsWith(ENCRYPTED_PREFIX) && isRootOnlyTrustedServerKeyFile(keyPath)) {
3607
+ if (isRootOnlyTrustedServerKeyFile(keyPath)) {
3583
3608
  return key;
3584
3609
  }
3585
3610
  const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
@@ -6,7 +6,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
6
6
  });
7
7
 
8
8
  // src/lib/keychain.ts
9
- import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
9
+ import { readFile, writeFile, unlink, mkdir, chmod, rename, copyFile } from "fs/promises";
10
10
  import { existsSync, statSync } from "fs";
11
11
  import { execSync } from "child_process";
12
12
  import path from "path";
@@ -45,12 +45,14 @@ function linuxSecretAvailable() {
45
45
  function isRootOnlyTrustedServerKeyFile(keyPath) {
46
46
  if (process.platform !== "linux") return false;
47
47
  try {
48
- const uid = typeof os.userInfo().uid === "number" ? os.userInfo().uid : -1;
49
48
  const st = statSync(keyPath);
50
49
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
50
+ const uid = typeof os.userInfo().uid === "number" ? os.userInfo().uid : -1;
51
51
  if (uid === 0) return true;
52
52
  const exeOsDir = process.env.EXE_OS_DIR;
53
- return Boolean(exeOsDir && path.resolve(keyPath).startsWith(path.resolve(exeOsDir) + path.sep));
53
+ if (exeOsDir && path.resolve(keyPath).startsWith(path.resolve(exeOsDir) + path.sep)) return true;
54
+ if (!linuxSecretAvailable()) return true;
55
+ return false;
54
56
  } catch {
55
57
  return false;
56
58
  }
@@ -201,15 +203,25 @@ async function writeMachineBoundFileFallback(b64) {
201
203
  await mkdir(dir, { recursive: true });
202
204
  const keyPath = getKeyPath();
203
205
  const machineKey = deriveMachineKey();
204
- if (machineKey) {
205
- const encrypted = encryptWithMachineKey(b64, machineKey);
206
- await writeFile(keyPath, encrypted + "\n", "utf-8");
207
- await chmod(keyPath, 384);
208
- return "encrypted";
209
- }
210
- await writeFile(keyPath, b64 + "\n", "utf-8");
211
- await chmod(keyPath, 384);
212
- return "plaintext";
206
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
207
+ const result = machineKey ? "encrypted" : "plaintext";
208
+ const tmpPath = keyPath + ".tmp";
209
+ try {
210
+ if (existsSync(keyPath)) {
211
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
212
+ });
213
+ }
214
+ await writeFile(tmpPath, content, "utf-8");
215
+ await chmod(tmpPath, 384);
216
+ await rename(tmpPath, keyPath);
217
+ } catch (err) {
218
+ try {
219
+ await unlink(tmpPath);
220
+ } catch {
221
+ }
222
+ throw err;
223
+ }
224
+ return result;
213
225
  }
214
226
  async function getMasterKey() {
215
227
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -276,7 +288,7 @@ async function getMasterKey() {
276
288
  b64Value = content;
277
289
  }
278
290
  const key = Buffer.from(b64Value, "base64");
279
- if (!content.startsWith(ENCRYPTED_PREFIX) && isRootOnlyTrustedServerKeyFile(keyPath)) {
291
+ if (isRootOnlyTrustedServerKeyFile(keyPath)) {
280
292
  return key;
281
293
  }
282
294
  const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);