@askexenow/exe-os 0.9.113 → 0.9.114

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 (79) hide show
  1. package/dist/bin/agentic-ontology-backfill.js +24 -12
  2. package/dist/bin/agentic-reflection-backfill.js +24 -12
  3. package/dist/bin/agentic-semantic-label.js +24 -12
  4. package/dist/bin/backfill-conversations.js +24 -12
  5. package/dist/bin/backfill-responses.js +24 -12
  6. package/dist/bin/backfill-vectors.js +24 -12
  7. package/dist/bin/bulk-sync-postgres.js +24 -12
  8. package/dist/bin/cleanup-stale-review-tasks.js +24 -12
  9. package/dist/bin/cli.js +96 -22
  10. package/dist/bin/exe-agent.js +27 -0
  11. package/dist/bin/exe-assign.js +24 -12
  12. package/dist/bin/exe-boot.js +44 -15
  13. package/dist/bin/exe-call.js +8 -0
  14. package/dist/bin/exe-cloud.js +34 -11
  15. package/dist/bin/exe-dispatch.js +34 -16
  16. package/dist/bin/exe-doctor.js +24 -12
  17. package/dist/bin/exe-export-behaviors.js +24 -12
  18. package/dist/bin/exe-forget.js +24 -12
  19. package/dist/bin/exe-gateway.js +33 -15
  20. package/dist/bin/exe-heartbeat.js +24 -12
  21. package/dist/bin/exe-kill.js +24 -12
  22. package/dist/bin/exe-launch-agent.js +103 -17
  23. package/dist/bin/exe-new-employee.js +9 -1
  24. package/dist/bin/exe-pending-messages.js +24 -12
  25. package/dist/bin/exe-pending-notifications.js +24 -12
  26. package/dist/bin/exe-pending-reviews.js +24 -12
  27. package/dist/bin/exe-rename.js +24 -12
  28. package/dist/bin/exe-review.js +24 -12
  29. package/dist/bin/exe-search.js +24 -12
  30. package/dist/bin/exe-session-cleanup.js +33 -15
  31. package/dist/bin/exe-start-codex.js +33 -13
  32. package/dist/bin/exe-start-opencode.js +33 -13
  33. package/dist/bin/exe-status.js +24 -12
  34. package/dist/bin/exe-team.js +24 -12
  35. package/dist/bin/git-sweep.js +34 -16
  36. package/dist/bin/graph-backfill.js +24 -12
  37. package/dist/bin/graph-export.js +24 -12
  38. package/dist/bin/install.js +9 -1
  39. package/dist/bin/intercom-check.js +33 -15
  40. package/dist/bin/scan-tasks.js +34 -16
  41. package/dist/bin/setup.js +60 -11
  42. package/dist/bin/shard-migrate.js +24 -12
  43. package/dist/gateway/index.js +33 -15
  44. package/dist/hooks/bug-report-worker.js +33 -15
  45. package/dist/hooks/codex-stop-task-finalizer.js +32 -12
  46. package/dist/hooks/commit-complete.js +34 -16
  47. package/dist/hooks/error-recall.js +24 -12
  48. package/dist/hooks/ingest.js +33 -15
  49. package/dist/hooks/instructions-loaded.js +24 -12
  50. package/dist/hooks/notification.js +24 -12
  51. package/dist/hooks/post-compact.js +24 -12
  52. package/dist/hooks/post-tool-combined.js +24 -12
  53. package/dist/hooks/pre-compact.js +34 -16
  54. package/dist/hooks/pre-tool-use.js +58 -11
  55. package/dist/hooks/prompt-submit.js +33 -15
  56. package/dist/hooks/session-end.js +34 -16
  57. package/dist/hooks/session-start.js +32 -12
  58. package/dist/hooks/stop.js +24 -12
  59. package/dist/hooks/subagent-stop.js +24 -12
  60. package/dist/hooks/summary-worker.js +34 -11
  61. package/dist/index.js +60 -15
  62. package/dist/lib/agent-config.js +8 -0
  63. package/dist/lib/cloud-sync.js +34 -11
  64. package/dist/lib/consolidation.js +9 -1
  65. package/dist/lib/employees.js +8 -0
  66. package/dist/lib/exe-daemon.js +174 -17
  67. package/dist/lib/hybrid-search.js +24 -12
  68. package/dist/lib/keychain.js +24 -12
  69. package/dist/lib/schedules.js +24 -12
  70. package/dist/lib/skill-learning.js +8 -0
  71. package/dist/lib/store.js +24 -12
  72. package/dist/lib/tasks.js +10 -4
  73. package/dist/lib/tmux-routing.js +10 -4
  74. package/dist/mcp/server.js +44 -15
  75. package/dist/mcp/tools/create-task.js +10 -4
  76. package/dist/mcp/tools/update-task.js +10 -4
  77. package/dist/runtime/index.js +60 -15
  78. package/dist/tui/App.js +61 -16
  79. package/package.json +1 -1
@@ -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();
@@ -3948,7 +3948,7 @@ init_memory();
3948
3948
  init_database();
3949
3949
 
3950
3950
  // src/lib/keychain.ts
3951
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3951
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
3952
3952
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
3953
3953
  import { execSync as execSync3 } from "child_process";
3954
3954
  import path6 from "path";
@@ -3987,12 +3987,14 @@ function linuxSecretAvailable() {
3987
3987
  function isRootOnlyTrustedServerKeyFile(keyPath) {
3988
3988
  if (process.platform !== "linux") return false;
3989
3989
  try {
3990
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3991
3990
  const st = statSync3(keyPath);
3992
3991
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
3992
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3993
3993
  if (uid === 0) return true;
3994
3994
  const exeOsDir = process.env.EXE_OS_DIR;
3995
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
3995
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
3996
+ if (!linuxSecretAvailable()) return true;
3997
+ return false;
3996
3998
  } catch {
3997
3999
  return false;
3998
4000
  }
@@ -4143,15 +4145,25 @@ async function writeMachineBoundFileFallback(b64) {
4143
4145
  await mkdir3(dir, { recursive: true });
4144
4146
  const keyPath = getKeyPath();
4145
4147
  const machineKey = deriveMachineKey();
4146
- if (machineKey) {
4147
- const encrypted = encryptWithMachineKey(b64, machineKey);
4148
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
4149
- await chmod2(keyPath, 384);
4150
- return "encrypted";
4151
- }
4152
- await writeFile3(keyPath, b64 + "\n", "utf-8");
4153
- await chmod2(keyPath, 384);
4154
- return "plaintext";
4148
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
4149
+ const result = machineKey ? "encrypted" : "plaintext";
4150
+ const tmpPath = keyPath + ".tmp";
4151
+ try {
4152
+ if (existsSync7(keyPath)) {
4153
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
4154
+ });
4155
+ }
4156
+ await writeFile3(tmpPath, content, "utf-8");
4157
+ await chmod2(tmpPath, 384);
4158
+ await rename(tmpPath, keyPath);
4159
+ } catch (err) {
4160
+ try {
4161
+ await unlink(tmpPath);
4162
+ } catch {
4163
+ }
4164
+ throw err;
4165
+ }
4166
+ return result;
4155
4167
  }
4156
4168
  async function getMasterKey() {
4157
4169
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -356,6 +356,7 @@ __export(agent_config_exports, {
356
356
  clearAgentRuntime: () => clearAgentRuntime,
357
357
  getAgentRuntime: () => getAgentRuntime,
358
358
  loadAgentConfig: () => loadAgentConfig,
359
+ normalizeCcModelName: () => normalizeCcModelName,
359
360
  saveAgentConfig: () => saveAgentConfig,
360
361
  setAgentMcps: () => setAgentMcps,
361
362
  setAgentRuntime: () => setAgentRuntime
@@ -384,6 +385,13 @@ function getAgentRuntime(agentId) {
384
385
  if (orgDefault) return orgDefault;
385
386
  return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
386
387
  }
388
+ function normalizeCcModelName(model) {
389
+ let ccModel = model.replace(/(\d+)\.(\d+)/g, "$1-$2");
390
+ if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
391
+ ccModel += "[1m]";
392
+ }
393
+ return ccModel;
394
+ }
387
395
  function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
388
396
  const knownModels = KNOWN_RUNTIMES[runtime];
389
397
  if (!knownModels) {
package/dist/lib/store.js CHANGED
@@ -4384,7 +4384,7 @@ init_memory();
4384
4384
  init_database();
4385
4385
 
4386
4386
  // src/lib/keychain.ts
4387
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
4387
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
4388
4388
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
4389
4389
  import { execSync as execSync3 } from "child_process";
4390
4390
  import path6 from "path";
@@ -4423,12 +4423,14 @@ function linuxSecretAvailable() {
4423
4423
  function isRootOnlyTrustedServerKeyFile(keyPath) {
4424
4424
  if (process.platform !== "linux") return false;
4425
4425
  try {
4426
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4427
4426
  const st = statSync3(keyPath);
4428
4427
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
4428
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4429
4429
  if (uid === 0) return true;
4430
4430
  const exeOsDir = process.env.EXE_OS_DIR;
4431
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
4431
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
4432
+ if (!linuxSecretAvailable()) return true;
4433
+ return false;
4432
4434
  } catch {
4433
4435
  return false;
4434
4436
  }
@@ -4579,15 +4581,25 @@ async function writeMachineBoundFileFallback(b64) {
4579
4581
  await mkdir3(dir, { recursive: true });
4580
4582
  const keyPath = getKeyPath();
4581
4583
  const machineKey = deriveMachineKey();
4582
- if (machineKey) {
4583
- const encrypted = encryptWithMachineKey(b64, machineKey);
4584
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
4585
- await chmod2(keyPath, 384);
4586
- return "encrypted";
4587
- }
4588
- await writeFile3(keyPath, b64 + "\n", "utf-8");
4589
- await chmod2(keyPath, 384);
4590
- return "plaintext";
4584
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
4585
+ const result = machineKey ? "encrypted" : "plaintext";
4586
+ const tmpPath = keyPath + ".tmp";
4587
+ try {
4588
+ if (existsSync7(keyPath)) {
4589
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
4590
+ });
4591
+ }
4592
+ await writeFile3(tmpPath, content, "utf-8");
4593
+ await chmod2(tmpPath, 384);
4594
+ await rename(tmpPath, keyPath);
4595
+ } catch (err) {
4596
+ try {
4597
+ await unlink(tmpPath);
4598
+ } catch {
4599
+ }
4600
+ throw err;
4601
+ }
4602
+ return result;
4591
4603
  }
4592
4604
  async function getMasterKey() {
4593
4605
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
package/dist/lib/tasks.js CHANGED
@@ -374,6 +374,7 @@ __export(agent_config_exports, {
374
374
  clearAgentRuntime: () => clearAgentRuntime,
375
375
  getAgentRuntime: () => getAgentRuntime,
376
376
  loadAgentConfig: () => loadAgentConfig,
377
+ normalizeCcModelName: () => normalizeCcModelName,
377
378
  saveAgentConfig: () => saveAgentConfig,
378
379
  setAgentMcps: () => setAgentMcps,
379
380
  setAgentRuntime: () => setAgentRuntime
@@ -402,6 +403,13 @@ function getAgentRuntime(agentId) {
402
403
  if (orgDefault) return orgDefault;
403
404
  return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
404
405
  }
406
+ function normalizeCcModelName(model) {
407
+ let ccModel = model.replace(/(\d+)\.(\d+)/g, "$1-$2");
408
+ if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
409
+ ccModel += "[1m]";
410
+ }
411
+ return ccModel;
412
+ }
405
413
  function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
406
414
  const knownModels = KNOWN_RUNTIMES[runtime];
407
415
  if (!knownModels) {
@@ -3255,10 +3263,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3255
3263
  }
3256
3264
  if (!useExeAgent && !useCodex && !useOpencode && !useBinSymlink) {
3257
3265
  if (agentRtConfig.runtime === "claude" && agentRtConfig.model) {
3258
- let ccModel = agentRtConfig.model.replace(/(\d+)\.(\d+)/g, "$1-$2");
3259
- if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
3260
- ccModel += "[1m]";
3261
- }
3266
+ const { normalizeCcModelName: normalizeCcModelName2 } = (init_agent_config(), __toCommonJS(agent_config_exports));
3267
+ const ccModel = normalizeCcModelName2(agentRtConfig.model);
3262
3268
  envPrefix = `${envPrefix} ANTHROPIC_MODEL=${ccModel}`;
3263
3269
  }
3264
3270
  }
@@ -659,6 +659,7 @@ __export(agent_config_exports, {
659
659
  clearAgentRuntime: () => clearAgentRuntime,
660
660
  getAgentRuntime: () => getAgentRuntime,
661
661
  loadAgentConfig: () => loadAgentConfig,
662
+ normalizeCcModelName: () => normalizeCcModelName,
662
663
  saveAgentConfig: () => saveAgentConfig,
663
664
  setAgentMcps: () => setAgentMcps,
664
665
  setAgentRuntime: () => setAgentRuntime
@@ -687,6 +688,13 @@ function getAgentRuntime(agentId) {
687
688
  if (orgDefault) return orgDefault;
688
689
  return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
689
690
  }
691
+ function normalizeCcModelName(model) {
692
+ let ccModel = model.replace(/(\d+)\.(\d+)/g, "$1-$2");
693
+ if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
694
+ ccModel += "[1m]";
695
+ }
696
+ return ccModel;
697
+ }
690
698
  function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
691
699
  const knownModels = KNOWN_RUNTIMES[runtime];
692
700
  if (!knownModels) {
@@ -5322,10 +5330,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5322
5330
  }
5323
5331
  if (!useExeAgent && !useCodex && !useOpencode && !useBinSymlink) {
5324
5332
  if (agentRtConfig.runtime === "claude" && agentRtConfig.model) {
5325
- let ccModel = agentRtConfig.model.replace(/(\d+)\.(\d+)/g, "$1-$2");
5326
- if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
5327
- ccModel += "[1m]";
5328
- }
5333
+ const { normalizeCcModelName: normalizeCcModelName2 } = (init_agent_config(), __toCommonJS(agent_config_exports));
5334
+ const ccModel = normalizeCcModelName2(agentRtConfig.model);
5329
5335
  envPrefix = `${envPrefix} ANTHROPIC_MODEL=${ccModel}`;
5330
5336
  }
5331
5337
  }
@@ -982,6 +982,7 @@ __export(agent_config_exports, {
982
982
  clearAgentRuntime: () => clearAgentRuntime,
983
983
  getAgentRuntime: () => getAgentRuntime,
984
984
  loadAgentConfig: () => loadAgentConfig,
985
+ normalizeCcModelName: () => normalizeCcModelName,
985
986
  saveAgentConfig: () => saveAgentConfig,
986
987
  setAgentMcps: () => setAgentMcps,
987
988
  setAgentRuntime: () => setAgentRuntime
@@ -1010,6 +1011,13 @@ function getAgentRuntime(agentId) {
1010
1011
  if (orgDefault) return orgDefault;
1011
1012
  return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
1012
1013
  }
1014
+ function normalizeCcModelName(model) {
1015
+ let ccModel = model.replace(/(\d+)\.(\d+)/g, "$1-$2");
1016
+ if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
1017
+ ccModel += "[1m]";
1018
+ }
1019
+ return ccModel;
1020
+ }
1013
1021
  function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
1014
1022
  const knownModels = KNOWN_RUNTIMES[runtime];
1015
1023
  if (!knownModels) {
@@ -3818,7 +3826,7 @@ __export(keychain_exports, {
3818
3826
  importMnemonic: () => importMnemonic,
3819
3827
  setMasterKey: () => setMasterKey
3820
3828
  });
3821
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3829
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
3822
3830
  import { existsSync as existsSync8, statSync as statSync3 } from "fs";
3823
3831
  import { execSync as execSync3 } from "child_process";
3824
3832
  import path7 from "path";
@@ -3853,12 +3861,14 @@ function linuxSecretAvailable() {
3853
3861
  function isRootOnlyTrustedServerKeyFile(keyPath) {
3854
3862
  if (process.platform !== "linux") return false;
3855
3863
  try {
3856
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3857
3864
  const st = statSync3(keyPath);
3858
3865
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
3866
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3859
3867
  if (uid === 0) return true;
3860
3868
  const exeOsDir = process.env.EXE_OS_DIR;
3861
- return Boolean(exeOsDir && path7.resolve(keyPath).startsWith(path7.resolve(exeOsDir) + path7.sep));
3869
+ if (exeOsDir && path7.resolve(keyPath).startsWith(path7.resolve(exeOsDir) + path7.sep)) return true;
3870
+ if (!linuxSecretAvailable()) return true;
3871
+ return false;
3862
3872
  } catch {
3863
3873
  return false;
3864
3874
  }
@@ -4008,15 +4018,25 @@ async function writeMachineBoundFileFallback(b64) {
4008
4018
  await mkdir3(dir, { recursive: true });
4009
4019
  const keyPath = getKeyPath();
4010
4020
  const machineKey = deriveMachineKey();
4011
- if (machineKey) {
4012
- const encrypted = encryptWithMachineKey(b64, machineKey);
4013
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
4014
- await chmod2(keyPath, 384);
4015
- return "encrypted";
4021
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
4022
+ const result3 = machineKey ? "encrypted" : "plaintext";
4023
+ const tmpPath = keyPath + ".tmp";
4024
+ try {
4025
+ if (existsSync8(keyPath)) {
4026
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
4027
+ });
4028
+ }
4029
+ await writeFile3(tmpPath, content, "utf-8");
4030
+ await chmod2(tmpPath, 384);
4031
+ await rename(tmpPath, keyPath);
4032
+ } catch (err) {
4033
+ try {
4034
+ await unlink(tmpPath);
4035
+ } catch {
4036
+ }
4037
+ throw err;
4016
4038
  }
4017
- await writeFile3(keyPath, b64 + "\n", "utf-8");
4018
- await chmod2(keyPath, 384);
4019
- return "plaintext";
4039
+ return result3;
4020
4040
  }
4021
4041
  async function getMasterKey() {
4022
4042
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -11478,10 +11498,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
11478
11498
  }
11479
11499
  if (!useExeAgent && !useCodex && !useOpencode && !useBinSymlink) {
11480
11500
  if (agentRtConfig.runtime === "claude" && agentRtConfig.model) {
11481
- let ccModel = agentRtConfig.model.replace(/(\d+)\.(\d+)/g, "$1-$2");
11482
- if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
11483
- ccModel += "[1m]";
11484
- }
11501
+ const { normalizeCcModelName: normalizeCcModelName2 } = (init_agent_config(), __toCommonJS(agent_config_exports));
11502
+ const ccModel = normalizeCcModelName2(agentRtConfig.model);
11485
11503
  envPrefix = `${envPrefix} ANTHROPIC_MODEL=${ccModel}`;
11486
11504
  }
11487
11505
  }
@@ -20871,6 +20889,7 @@ var IDLE_KILL_INTERCOM_ACK_WINDOW_MS = Number(process.env.EXE_INTERCOM_ACK_WINDO
20871
20889
  var NUDGE_STATE_PATH = join4(homedir6(), ".exe-os", "review-nudge-state.json");
20872
20890
  var AUTO_WAKE_COOLDOWN_MS = 5 * 60 * 1e3;
20873
20891
  var AUTO_WAKE_MAX_RETRIES = 3;
20892
+ var STUCK_TASK_GRACE_MS = 30 * 60 * 1e3;
20874
20893
 
20875
20894
  // src/mcp/tools/get-auto-wake-status.ts
20876
20895
  init_employees();
@@ -22569,6 +22588,15 @@ async function fetchWithRetry(url, init) {
22569
22588
  }
22570
22589
  throw lastError;
22571
22590
  }
22591
+ function migrateEndpoint(endpoint2) {
22592
+ if (endpoint2 === "https://askexe.com/cloud" || endpoint2 === "https://askexe.com/cloud/") {
22593
+ process.stderr.write(
22594
+ "[cloud-sync] Auto-migrating endpoint from askexe.com/cloud to cloud.askexe.com (bypasses Cloudflare WAF for datacenter IPs)\n"
22595
+ );
22596
+ return "https://cloud.askexe.com";
22597
+ }
22598
+ return endpoint2;
22599
+ }
22572
22600
  function assertSecureEndpoint(endpoint2) {
22573
22601
  if (endpoint2.startsWith("https://")) return;
22574
22602
  if (endpoint2.startsWith("http://")) {
@@ -22690,6 +22718,7 @@ async function markCloudReuploadRequired(client = getClient()) {
22690
22718
  await client.execute("INSERT OR REPLACE INTO sync_meta (key, value) VALUES ('cloud_reupload_required', '1')");
22691
22719
  }
22692
22720
  async function cloudSync(config2) {
22721
+ config2 = { ...config2, endpoint: migrateEndpoint(config2.endpoint) };
22693
22722
  if (!isSyncCryptoInitialized()) {
22694
22723
  try {
22695
22724
  const { getMasterKey: getMasterKey2 } = await Promise.resolve().then(() => (init_keychain(), keychain_exports));
@@ -374,6 +374,7 @@ __export(agent_config_exports, {
374
374
  clearAgentRuntime: () => clearAgentRuntime,
375
375
  getAgentRuntime: () => getAgentRuntime,
376
376
  loadAgentConfig: () => loadAgentConfig,
377
+ normalizeCcModelName: () => normalizeCcModelName,
377
378
  saveAgentConfig: () => saveAgentConfig,
378
379
  setAgentMcps: () => setAgentMcps,
379
380
  setAgentRuntime: () => setAgentRuntime
@@ -402,6 +403,13 @@ function getAgentRuntime(agentId) {
402
403
  if (orgDefault) return orgDefault;
403
404
  return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
404
405
  }
406
+ function normalizeCcModelName(model) {
407
+ let ccModel = model.replace(/(\d+)\.(\d+)/g, "$1-$2");
408
+ if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
409
+ ccModel += "[1m]";
410
+ }
411
+ return ccModel;
412
+ }
405
413
  function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
406
414
  const knownModels = KNOWN_RUNTIMES[runtime];
407
415
  if (!knownModels) {
@@ -3255,10 +3263,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3255
3263
  }
3256
3264
  if (!useExeAgent && !useCodex && !useOpencode && !useBinSymlink) {
3257
3265
  if (agentRtConfig.runtime === "claude" && agentRtConfig.model) {
3258
- let ccModel = agentRtConfig.model.replace(/(\d+)\.(\d+)/g, "$1-$2");
3259
- if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
3260
- ccModel += "[1m]";
3261
- }
3266
+ const { normalizeCcModelName: normalizeCcModelName2 } = (init_agent_config(), __toCommonJS(agent_config_exports));
3267
+ const ccModel = normalizeCcModelName2(agentRtConfig.model);
3262
3268
  envPrefix = `${envPrefix} ANTHROPIC_MODEL=${ccModel}`;
3263
3269
  }
3264
3270
  }
@@ -374,6 +374,7 @@ __export(agent_config_exports, {
374
374
  clearAgentRuntime: () => clearAgentRuntime,
375
375
  getAgentRuntime: () => getAgentRuntime,
376
376
  loadAgentConfig: () => loadAgentConfig,
377
+ normalizeCcModelName: () => normalizeCcModelName,
377
378
  saveAgentConfig: () => saveAgentConfig,
378
379
  setAgentMcps: () => setAgentMcps,
379
380
  setAgentRuntime: () => setAgentRuntime
@@ -402,6 +403,13 @@ function getAgentRuntime(agentId) {
402
403
  if (orgDefault) return orgDefault;
403
404
  return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
404
405
  }
406
+ function normalizeCcModelName(model) {
407
+ let ccModel = model.replace(/(\d+)\.(\d+)/g, "$1-$2");
408
+ if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
409
+ ccModel += "[1m]";
410
+ }
411
+ return ccModel;
412
+ }
405
413
  function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
406
414
  const knownModels = KNOWN_RUNTIMES[runtime];
407
415
  if (!knownModels) {
@@ -3255,10 +3263,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3255
3263
  }
3256
3264
  if (!useExeAgent && !useCodex && !useOpencode && !useBinSymlink) {
3257
3265
  if (agentRtConfig.runtime === "claude" && agentRtConfig.model) {
3258
- let ccModel = agentRtConfig.model.replace(/(\d+)\.(\d+)/g, "$1-$2");
3259
- if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
3260
- ccModel += "[1m]";
3261
- }
3266
+ const { normalizeCcModelName: normalizeCcModelName2 } = (init_agent_config(), __toCommonJS(agent_config_exports));
3267
+ const ccModel = normalizeCcModelName2(agentRtConfig.model);
3262
3268
  envPrefix = `${envPrefix} ANTHROPIC_MODEL=${ccModel}`;
3263
3269
  }
3264
3270
  }
@@ -367,6 +367,7 @@ __export(agent_config_exports, {
367
367
  clearAgentRuntime: () => clearAgentRuntime,
368
368
  getAgentRuntime: () => getAgentRuntime,
369
369
  loadAgentConfig: () => loadAgentConfig,
370
+ normalizeCcModelName: () => normalizeCcModelName,
370
371
  saveAgentConfig: () => saveAgentConfig,
371
372
  setAgentMcps: () => setAgentMcps,
372
373
  setAgentRuntime: () => setAgentRuntime
@@ -395,6 +396,13 @@ function getAgentRuntime(agentId) {
395
396
  if (orgDefault) return orgDefault;
396
397
  return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
397
398
  }
399
+ function normalizeCcModelName(model) {
400
+ let ccModel = model.replace(/(\d+)\.(\d+)/g, "$1-$2");
401
+ if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
402
+ ccModel += "[1m]";
403
+ }
404
+ return ccModel;
405
+ }
398
406
  function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
399
407
  const knownModels = KNOWN_RUNTIMES[runtime];
400
408
  if (!knownModels) {
@@ -7869,10 +7877,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
7869
7877
  }
7870
7878
  if (!useExeAgent && !useCodex && !useOpencode && !useBinSymlink) {
7871
7879
  if (agentRtConfig.runtime === "claude" && agentRtConfig.model) {
7872
- let ccModel = agentRtConfig.model.replace(/(\d+)\.(\d+)/g, "$1-$2");
7873
- if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
7874
- ccModel += "[1m]";
7875
- }
7880
+ const { normalizeCcModelName: normalizeCcModelName2 } = (init_agent_config(), __toCommonJS(agent_config_exports));
7881
+ const ccModel = normalizeCcModelName2(agentRtConfig.model);
7876
7882
  envPrefix = `${envPrefix} ANTHROPIC_MODEL=${ccModel}`;
7877
7883
  }
7878
7884
  }
@@ -8004,7 +8010,7 @@ var init_tmux_routing = __esm({
8004
8010
  });
8005
8011
 
8006
8012
  // src/lib/keychain.ts
8007
- import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
8013
+ import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2, rename, copyFile } from "fs/promises";
8008
8014
  import { existsSync as existsSync17, statSync as statSync3 } from "fs";
8009
8015
  import { execSync as execSync9 } from "child_process";
8010
8016
  import path20 from "path";
@@ -8039,12 +8045,14 @@ function linuxSecretAvailable() {
8039
8045
  function isRootOnlyTrustedServerKeyFile(keyPath) {
8040
8046
  if (process.platform !== "linux") return false;
8041
8047
  try {
8042
- const uid = typeof os13.userInfo().uid === "number" ? os13.userInfo().uid : -1;
8043
8048
  const st = statSync3(keyPath);
8044
8049
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
8050
+ const uid = typeof os13.userInfo().uid === "number" ? os13.userInfo().uid : -1;
8045
8051
  if (uid === 0) return true;
8046
8052
  const exeOsDir = process.env.EXE_OS_DIR;
8047
- return Boolean(exeOsDir && path20.resolve(keyPath).startsWith(path20.resolve(exeOsDir) + path20.sep));
8053
+ if (exeOsDir && path20.resolve(keyPath).startsWith(path20.resolve(exeOsDir) + path20.sep)) return true;
8054
+ if (!linuxSecretAvailable()) return true;
8055
+ return false;
8048
8056
  } catch {
8049
8057
  return false;
8050
8058
  }
@@ -8194,15 +8202,25 @@ async function writeMachineBoundFileFallback(b64) {
8194
8202
  await mkdir4(dir, { recursive: true });
8195
8203
  const keyPath = getKeyPath();
8196
8204
  const machineKey = deriveMachineKey();
8197
- if (machineKey) {
8198
- const encrypted = encryptWithMachineKey(b64, machineKey);
8199
- await writeFile5(keyPath, encrypted + "\n", "utf-8");
8200
- await chmod2(keyPath, 384);
8201
- return "encrypted";
8205
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
8206
+ const result = machineKey ? "encrypted" : "plaintext";
8207
+ const tmpPath = keyPath + ".tmp";
8208
+ try {
8209
+ if (existsSync17(keyPath)) {
8210
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
8211
+ });
8212
+ }
8213
+ await writeFile5(tmpPath, content, "utf-8");
8214
+ await chmod2(tmpPath, 384);
8215
+ await rename(tmpPath, keyPath);
8216
+ } catch (err) {
8217
+ try {
8218
+ await unlink(tmpPath);
8219
+ } catch {
8220
+ }
8221
+ throw err;
8202
8222
  }
8203
- await writeFile5(keyPath, b64 + "\n", "utf-8");
8204
- await chmod2(keyPath, 384);
8205
- return "plaintext";
8223
+ return result;
8206
8224
  }
8207
8225
  async function getMasterKey() {
8208
8226
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -11785,6 +11803,33 @@ var DANGEROUS_PATTERNS = [
11785
11803
  regex: /\bkill\s+-9\b/,
11786
11804
  severity: "warning",
11787
11805
  reason: "Force kill signal"
11806
+ },
11807
+ // MCP bypass — agents must use MCP tools, never access the DB directly.
11808
+ // These patterns catch attempts to work around a disconnected MCP server.
11809
+ {
11810
+ regex: /\bsqlite3\b.*\bmemories\.db\b/,
11811
+ severity: "critical",
11812
+ reason: "Direct SQLite access bypasses MCP contract boundary \u2014 use MCP tools"
11813
+ },
11814
+ {
11815
+ regex: /\bsqlite3\b.*\.exe-os\b/,
11816
+ severity: "critical",
11817
+ reason: "Direct SQLite access to exe-os database \u2014 use MCP tools"
11818
+ },
11819
+ {
11820
+ regex: /\bnode\s+-e\b.*\b(better-sqlite3|libsql|sqlite3)\b/,
11821
+ severity: "critical",
11822
+ reason: "Inline Node.js script accessing SQLite directly \u2014 use MCP tools"
11823
+ },
11824
+ {
11825
+ regex: /\brequire\s*\(\s*['"].*memories\.db['"]\s*\)/,
11826
+ severity: "critical",
11827
+ reason: "Direct require of memories database \u2014 use MCP tools"
11828
+ },
11829
+ {
11830
+ regex: /\bcat\b.*\bmemories\.db\b/,
11831
+ severity: "warning",
11832
+ reason: "Reading raw database file \u2014 encrypted data, use MCP tools instead"
11788
11833
  }
11789
11834
  ];
11790
11835
  function checkDangerousPatterns(command) {