@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
@@ -193,6 +193,17 @@ function normalizeOrchestration(raw) {
193
193
  const userOrg = raw.orchestration ?? {};
194
194
  raw.orchestration = { ...defaultOrg, ...userOrg };
195
195
  }
196
+ function normalizeCloudEndpoint(raw) {
197
+ const cloud = raw.cloud;
198
+ if (!cloud?.endpoint) return;
199
+ const ep = String(cloud.endpoint);
200
+ if (ep === "https://askexe.com/cloud" || ep === "https://askexe.com/cloud/") {
201
+ cloud.endpoint = "https://cloud.askexe.com";
202
+ process.stderr.write(
203
+ "[config] Auto-migrated cloud endpoint: askexe.com/cloud \u2192 cloud.askexe.com\n"
204
+ );
205
+ }
206
+ }
196
207
  async function loadConfig() {
197
208
  const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
198
209
  await ensurePrivateDir(dir);
@@ -218,6 +229,7 @@ async function loadConfig() {
218
229
  normalizeSessionLifecycle(migratedCfg);
219
230
  normalizeAutoUpdate(migratedCfg);
220
231
  normalizeOrchestration(migratedCfg);
232
+ normalizeCloudEndpoint(migratedCfg);
221
233
  const config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
222
234
  if (config.dbPath.startsWith("~")) {
223
235
  config.dbPath = config.dbPath.replace(/^~/, os.homedir());
@@ -4385,7 +4397,7 @@ init_memory();
4385
4397
  init_database();
4386
4398
 
4387
4399
  // src/lib/keychain.ts
4388
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
4400
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
4389
4401
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
4390
4402
  import { execSync as execSync3 } from "child_process";
4391
4403
  import path6 from "path";
@@ -4424,12 +4436,14 @@ function linuxSecretAvailable() {
4424
4436
  function isRootOnlyTrustedServerKeyFile(keyPath) {
4425
4437
  if (process.platform !== "linux") return false;
4426
4438
  try {
4427
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4428
4439
  const st = statSync3(keyPath);
4429
4440
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
4441
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4430
4442
  if (uid === 0) return true;
4431
4443
  const exeOsDir = process.env.EXE_OS_DIR;
4432
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
4444
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
4445
+ if (!linuxSecretAvailable()) return true;
4446
+ return false;
4433
4447
  } catch {
4434
4448
  return false;
4435
4449
  }
@@ -4580,15 +4594,25 @@ async function writeMachineBoundFileFallback(b64) {
4580
4594
  await mkdir3(dir, { recursive: true });
4581
4595
  const keyPath = getKeyPath();
4582
4596
  const machineKey = deriveMachineKey();
4583
- if (machineKey) {
4584
- const encrypted = encryptWithMachineKey(b64, machineKey);
4585
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
4586
- await chmod2(keyPath, 384);
4587
- return "encrypted";
4597
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
4598
+ const result = machineKey ? "encrypted" : "plaintext";
4599
+ const tmpPath = keyPath + ".tmp";
4600
+ try {
4601
+ if (existsSync7(keyPath)) {
4602
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
4603
+ });
4604
+ }
4605
+ await writeFile3(tmpPath, content, "utf-8");
4606
+ await chmod2(tmpPath, 384);
4607
+ await rename(tmpPath, keyPath);
4608
+ } catch (err) {
4609
+ try {
4610
+ await unlink(tmpPath);
4611
+ } catch {
4612
+ }
4613
+ throw err;
4588
4614
  }
4589
- await writeFile3(keyPath, b64 + "\n", "utf-8");
4590
- await chmod2(keyPath, 384);
4591
- return "plaintext";
4615
+ return result;
4592
4616
  }
4593
4617
  async function getMasterKey() {
4594
4618
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -4655,7 +4679,7 @@ async function getMasterKey() {
4655
4679
  b64Value = content;
4656
4680
  }
4657
4681
  const key = Buffer.from(b64Value, "base64");
4658
- if (!content.startsWith(ENCRYPTED_PREFIX) && isRootOnlyTrustedServerKeyFile(keyPath)) {
4682
+ if (isRootOnlyTrustedServerKeyFile(keyPath)) {
4659
4683
  return key;
4660
4684
  }
4661
4685
  const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
@@ -193,6 +193,17 @@ function normalizeOrchestration(raw) {
193
193
  const userOrg = raw.orchestration ?? {};
194
194
  raw.orchestration = { ...defaultOrg, ...userOrg };
195
195
  }
196
+ function normalizeCloudEndpoint(raw) {
197
+ const cloud = raw.cloud;
198
+ if (!cloud?.endpoint) return;
199
+ const ep = String(cloud.endpoint);
200
+ if (ep === "https://askexe.com/cloud" || ep === "https://askexe.com/cloud/") {
201
+ cloud.endpoint = "https://cloud.askexe.com";
202
+ process.stderr.write(
203
+ "[config] Auto-migrated cloud endpoint: askexe.com/cloud \u2192 cloud.askexe.com\n"
204
+ );
205
+ }
206
+ }
196
207
  async function loadConfig() {
197
208
  const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
198
209
  await ensurePrivateDir(dir);
@@ -218,6 +229,7 @@ async function loadConfig() {
218
229
  normalizeSessionLifecycle(migratedCfg);
219
230
  normalizeAutoUpdate(migratedCfg);
220
231
  normalizeOrchestration(migratedCfg);
232
+ normalizeCloudEndpoint(migratedCfg);
221
233
  const config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
222
234
  if (config.dbPath.startsWith("~")) {
223
235
  config.dbPath = config.dbPath.replace(/^~/, os.homedir());
@@ -3316,7 +3328,7 @@ var init_database = __esm({
3316
3328
  });
3317
3329
 
3318
3330
  // src/lib/keychain.ts
3319
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3331
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
3320
3332
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
3321
3333
  import { execSync as execSync3 } from "child_process";
3322
3334
  import path6 from "path";
@@ -3351,12 +3363,14 @@ function linuxSecretAvailable() {
3351
3363
  function isRootOnlyTrustedServerKeyFile(keyPath) {
3352
3364
  if (process.platform !== "linux") return false;
3353
3365
  try {
3354
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3355
3366
  const st = statSync3(keyPath);
3356
3367
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
3368
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3357
3369
  if (uid === 0) return true;
3358
3370
  const exeOsDir = process.env.EXE_OS_DIR;
3359
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
3371
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
3372
+ if (!linuxSecretAvailable()) return true;
3373
+ return false;
3360
3374
  } catch {
3361
3375
  return false;
3362
3376
  }
@@ -3506,15 +3520,25 @@ async function writeMachineBoundFileFallback(b64) {
3506
3520
  await mkdir3(dir, { recursive: true });
3507
3521
  const keyPath = getKeyPath();
3508
3522
  const machineKey = deriveMachineKey();
3509
- if (machineKey) {
3510
- const encrypted = encryptWithMachineKey(b64, machineKey);
3511
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
3512
- await chmod2(keyPath, 384);
3513
- return "encrypted";
3523
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
3524
+ const result = machineKey ? "encrypted" : "plaintext";
3525
+ const tmpPath = keyPath + ".tmp";
3526
+ try {
3527
+ if (existsSync7(keyPath)) {
3528
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
3529
+ });
3530
+ }
3531
+ await writeFile3(tmpPath, content, "utf-8");
3532
+ await chmod2(tmpPath, 384);
3533
+ await rename(tmpPath, keyPath);
3534
+ } catch (err) {
3535
+ try {
3536
+ await unlink(tmpPath);
3537
+ } catch {
3538
+ }
3539
+ throw err;
3514
3540
  }
3515
- await writeFile3(keyPath, b64 + "\n", "utf-8");
3516
- await chmod2(keyPath, 384);
3517
- return "plaintext";
3541
+ return result;
3518
3542
  }
3519
3543
  async function getMasterKey() {
3520
3544
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -3581,7 +3605,7 @@ async function getMasterKey() {
3581
3605
  b64Value = content;
3582
3606
  }
3583
3607
  const key = Buffer.from(b64Value, "base64");
3584
- if (!content.startsWith(ENCRYPTED_PREFIX) && isRootOnlyTrustedServerKeyFile(keyPath)) {
3608
+ if (isRootOnlyTrustedServerKeyFile(keyPath)) {
3585
3609
  return key;
3586
3610
  }
3587
3611
  const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
@@ -181,6 +181,7 @@ __export(agent_config_exports, {
181
181
  clearAgentRuntime: () => clearAgentRuntime,
182
182
  getAgentRuntime: () => getAgentRuntime,
183
183
  loadAgentConfig: () => loadAgentConfig,
184
+ normalizeCcModelName: () => normalizeCcModelName,
184
185
  saveAgentConfig: () => saveAgentConfig,
185
186
  setAgentMcps: () => setAgentMcps,
186
187
  setAgentRuntime: () => setAgentRuntime
@@ -209,6 +210,13 @@ function getAgentRuntime(agentId) {
209
210
  if (orgDefault) return orgDefault;
210
211
  return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
211
212
  }
213
+ function normalizeCcModelName(model) {
214
+ let ccModel = model.replace(/(\d+)\.(\d+)/g, "$1-$2");
215
+ if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
216
+ ccModel += "[1m]";
217
+ }
218
+ return ccModel;
219
+ }
212
220
  function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
213
221
  const knownModels = KNOWN_RUNTIMES[runtime];
214
222
  if (!knownModels) {
@@ -679,7 +687,7 @@ function readOrCreateDaemonToken(homeDir = os5.homedir()) {
679
687
  function buildMcpHttpHeaders(homeDir = os5.homedir(), opts = {}) {
680
688
  const agentId = opts.useShellPlaceholders ? "${AGENT_ID:-exe}" : opts.agentId ?? DEFAULT_MCP_HTTP_AGENT_ID;
681
689
  const agentRole = opts.useShellPlaceholders ? "${AGENT_ROLE:-COO}" : opts.agentRole ?? DEFAULT_MCP_HTTP_AGENT_ROLE;
682
- const sessionName = opts.useShellPlaceholders ? "$(tmux display-message -p '#{session_name}' 2>/dev/null || echo '')" : process.env.EXE_SESSION_NAME ?? "";
690
+ const sessionName = opts.useShellPlaceholders ? "" : process.env.EXE_SESSION_NAME ?? "";
683
691
  const headers = {
684
692
  Authorization: `Bearer ${readOrCreateDaemonToken(homeDir)}`,
685
693
  "X-Agent-Id": agentId,