@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
@@ -128,6 +128,17 @@ function normalizeOrchestration(raw) {
128
128
  const userOrg = raw.orchestration ?? {};
129
129
  raw.orchestration = { ...defaultOrg, ...userOrg };
130
130
  }
131
+ function normalizeCloudEndpoint(raw) {
132
+ const cloud = raw.cloud;
133
+ if (!cloud?.endpoint) return;
134
+ const ep = String(cloud.endpoint);
135
+ if (ep === "https://askexe.com/cloud" || ep === "https://askexe.com/cloud/") {
136
+ cloud.endpoint = "https://cloud.askexe.com";
137
+ process.stderr.write(
138
+ "[config] Auto-migrated cloud endpoint: askexe.com/cloud \u2192 cloud.askexe.com\n"
139
+ );
140
+ }
141
+ }
131
142
  async function loadConfig() {
132
143
  const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
133
144
  await ensurePrivateDir(dir);
@@ -153,6 +164,7 @@ async function loadConfig() {
153
164
  normalizeSessionLifecycle(migratedCfg);
154
165
  normalizeAutoUpdate(migratedCfg);
155
166
  normalizeOrchestration(migratedCfg);
167
+ normalizeCloudEndpoint(migratedCfg);
156
168
  const config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
157
169
  if (config.dbPath.startsWith("~")) {
158
170
  config.dbPath = config.dbPath.replace(/^~/, os.homedir());
@@ -3318,7 +3330,7 @@ var init_database = __esm({
3318
3330
  });
3319
3331
 
3320
3332
  // src/lib/keychain.ts
3321
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3333
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
3322
3334
  import { existsSync as existsSync8, statSync as statSync3 } from "fs";
3323
3335
  import { execSync as execSync5 } from "child_process";
3324
3336
  import path8 from "path";
@@ -3353,12 +3365,14 @@ function linuxSecretAvailable() {
3353
3365
  function isRootOnlyTrustedServerKeyFile(keyPath) {
3354
3366
  if (process.platform !== "linux") return false;
3355
3367
  try {
3356
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3357
3368
  const st = statSync3(keyPath);
3358
3369
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
3370
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3359
3371
  if (uid === 0) return true;
3360
3372
  const exeOsDir = process.env.EXE_OS_DIR;
3361
- return Boolean(exeOsDir && path8.resolve(keyPath).startsWith(path8.resolve(exeOsDir) + path8.sep));
3373
+ if (exeOsDir && path8.resolve(keyPath).startsWith(path8.resolve(exeOsDir) + path8.sep)) return true;
3374
+ if (!linuxSecretAvailable()) return true;
3375
+ return false;
3362
3376
  } catch {
3363
3377
  return false;
3364
3378
  }
@@ -3508,15 +3522,25 @@ async function writeMachineBoundFileFallback(b64) {
3508
3522
  await mkdir3(dir, { recursive: true });
3509
3523
  const keyPath = getKeyPath();
3510
3524
  const machineKey = deriveMachineKey();
3511
- if (machineKey) {
3512
- const encrypted = encryptWithMachineKey(b64, machineKey);
3513
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
3514
- await chmod2(keyPath, 384);
3515
- return "encrypted";
3525
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
3526
+ const result = machineKey ? "encrypted" : "plaintext";
3527
+ const tmpPath = keyPath + ".tmp";
3528
+ try {
3529
+ if (existsSync8(keyPath)) {
3530
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
3531
+ });
3532
+ }
3533
+ await writeFile3(tmpPath, content, "utf-8");
3534
+ await chmod2(tmpPath, 384);
3535
+ await rename(tmpPath, keyPath);
3536
+ } catch (err) {
3537
+ try {
3538
+ await unlink(tmpPath);
3539
+ } catch {
3540
+ }
3541
+ throw err;
3516
3542
  }
3517
- await writeFile3(keyPath, b64 + "\n", "utf-8");
3518
- await chmod2(keyPath, 384);
3519
- return "plaintext";
3543
+ return result;
3520
3544
  }
3521
3545
  async function getMasterKey() {
3522
3546
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -3583,7 +3607,7 @@ async function getMasterKey() {
3583
3607
  b64Value = content;
3584
3608
  }
3585
3609
  const key = Buffer.from(b64Value, "base64");
3586
- if (!content.startsWith(ENCRYPTED_PREFIX) && isRootOnlyTrustedServerKeyFile(keyPath)) {
3610
+ if (isRootOnlyTrustedServerKeyFile(keyPath)) {
3587
3611
  return key;
3588
3612
  }
3589
3613
  const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
@@ -128,6 +128,17 @@ function normalizeOrchestration(raw) {
128
128
  const userOrg = raw.orchestration ?? {};
129
129
  raw.orchestration = { ...defaultOrg, ...userOrg };
130
130
  }
131
+ function normalizeCloudEndpoint(raw) {
132
+ const cloud = raw.cloud;
133
+ if (!cloud?.endpoint) return;
134
+ const ep = String(cloud.endpoint);
135
+ if (ep === "https://askexe.com/cloud" || ep === "https://askexe.com/cloud/") {
136
+ cloud.endpoint = "https://cloud.askexe.com";
137
+ process.stderr.write(
138
+ "[config] Auto-migrated cloud endpoint: askexe.com/cloud \u2192 cloud.askexe.com\n"
139
+ );
140
+ }
141
+ }
131
142
  async function loadConfig() {
132
143
  const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
133
144
  await ensurePrivateDir(dir);
@@ -153,6 +164,7 @@ async function loadConfig() {
153
164
  normalizeSessionLifecycle(migratedCfg);
154
165
  normalizeAutoUpdate(migratedCfg);
155
166
  normalizeOrchestration(migratedCfg);
167
+ normalizeCloudEndpoint(migratedCfg);
156
168
  const config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
157
169
  if (config.dbPath.startsWith("~")) {
158
170
  config.dbPath = config.dbPath.replace(/^~/, os.homedir());
@@ -3318,7 +3330,7 @@ var init_database = __esm({
3318
3330
  });
3319
3331
 
3320
3332
  // src/lib/keychain.ts
3321
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3333
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
3322
3334
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
3323
3335
  import { execSync as execSync5 } from "child_process";
3324
3336
  import path7 from "path";
@@ -3353,12 +3365,14 @@ function linuxSecretAvailable() {
3353
3365
  function isRootOnlyTrustedServerKeyFile(keyPath) {
3354
3366
  if (process.platform !== "linux") return false;
3355
3367
  try {
3356
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3357
3368
  const st = statSync3(keyPath);
3358
3369
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
3370
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3359
3371
  if (uid === 0) return true;
3360
3372
  const exeOsDir = process.env.EXE_OS_DIR;
3361
- return Boolean(exeOsDir && path7.resolve(keyPath).startsWith(path7.resolve(exeOsDir) + path7.sep));
3373
+ if (exeOsDir && path7.resolve(keyPath).startsWith(path7.resolve(exeOsDir) + path7.sep)) return true;
3374
+ if (!linuxSecretAvailable()) return true;
3375
+ return false;
3362
3376
  } catch {
3363
3377
  return false;
3364
3378
  }
@@ -3508,15 +3522,25 @@ async function writeMachineBoundFileFallback(b64) {
3508
3522
  await mkdir3(dir, { recursive: true });
3509
3523
  const keyPath = getKeyPath();
3510
3524
  const machineKey = deriveMachineKey();
3511
- if (machineKey) {
3512
- const encrypted = encryptWithMachineKey(b64, machineKey);
3513
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
3514
- await chmod2(keyPath, 384);
3515
- return "encrypted";
3525
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
3526
+ const result = machineKey ? "encrypted" : "plaintext";
3527
+ const tmpPath = keyPath + ".tmp";
3528
+ try {
3529
+ if (existsSync7(keyPath)) {
3530
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
3531
+ });
3532
+ }
3533
+ await writeFile3(tmpPath, content, "utf-8");
3534
+ await chmod2(tmpPath, 384);
3535
+ await rename(tmpPath, keyPath);
3536
+ } catch (err) {
3537
+ try {
3538
+ await unlink(tmpPath);
3539
+ } catch {
3540
+ }
3541
+ throw err;
3516
3542
  }
3517
- await writeFile3(keyPath, b64 + "\n", "utf-8");
3518
- await chmod2(keyPath, 384);
3519
- return "plaintext";
3543
+ return result;
3520
3544
  }
3521
3545
  async function getMasterKey() {
3522
3546
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -3583,7 +3607,7 @@ async function getMasterKey() {
3583
3607
  b64Value = content;
3584
3608
  }
3585
3609
  const key = Buffer.from(b64Value, "base64");
3586
- if (!content.startsWith(ENCRYPTED_PREFIX) && isRootOnlyTrustedServerKeyFile(keyPath)) {
3610
+ if (isRootOnlyTrustedServerKeyFile(keyPath)) {
3587
3611
  return key;
3588
3612
  }
3589
3613
  const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);