@askexenow/exe-os 0.8.62 → 0.8.64

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 (61) hide show
  1. package/dist/bin/backfill-conversations.js +2 -3
  2. package/dist/bin/backfill-responses.js +3 -4
  3. package/dist/bin/backfill-vectors.js +0 -1
  4. package/dist/bin/cleanup-stale-review-tasks.js +0 -1
  5. package/dist/bin/cli.js +52 -80
  6. package/dist/bin/exe-assign.js +0 -1
  7. package/dist/bin/exe-boot.js +40 -72
  8. package/dist/bin/exe-cloud.js +28 -60
  9. package/dist/bin/exe-dispatch.js +0 -1
  10. package/dist/bin/exe-doctor.js +0 -1
  11. package/dist/bin/exe-export-behaviors.js +1 -2
  12. package/dist/bin/exe-forget.js +0 -1
  13. package/dist/bin/exe-gateway.js +16 -17
  14. package/dist/bin/exe-heartbeat.js +1 -2
  15. package/dist/bin/exe-kill.js +2 -3
  16. package/dist/bin/exe-launch-agent.js +1 -2
  17. package/dist/bin/exe-link.js +28 -66
  18. package/dist/bin/exe-pending-messages.js +1 -2
  19. package/dist/bin/exe-pending-notifications.js +0 -1
  20. package/dist/bin/exe-pending-reviews.js +1 -2
  21. package/dist/bin/exe-review.js +0 -1
  22. package/dist/bin/exe-search.js +2 -3
  23. package/dist/bin/exe-session-cleanup.js +4 -5
  24. package/dist/bin/exe-status.js +0 -1
  25. package/dist/bin/exe-team.js +0 -1
  26. package/dist/bin/git-sweep.js +0 -1
  27. package/dist/bin/graph-backfill.js +5 -6
  28. package/dist/bin/graph-export.js +0 -1
  29. package/dist/bin/scan-tasks.js +0 -1
  30. package/dist/bin/setup.js +34 -62
  31. package/dist/bin/shard-migrate.js +0 -1
  32. package/dist/bin/wiki-sync.js +0 -1
  33. package/dist/gateway/index.js +16 -17
  34. package/dist/hooks/bug-report-worker.js +11 -12
  35. package/dist/hooks/commit-complete.js +0 -1
  36. package/dist/hooks/error-recall.js +2 -3
  37. package/dist/hooks/ingest-worker.js +14 -15
  38. package/dist/hooks/instructions-loaded.js +0 -1
  39. package/dist/hooks/notification.js +0 -1
  40. package/dist/hooks/post-compact.js +0 -1
  41. package/dist/hooks/pre-compact.js +2 -3
  42. package/dist/hooks/pre-tool-use.js +0 -1
  43. package/dist/hooks/prompt-ingest-worker.js +2 -3
  44. package/dist/hooks/prompt-submit.js +6 -7
  45. package/dist/hooks/response-ingest-worker.js +2 -3
  46. package/dist/hooks/session-end.js +3 -4
  47. package/dist/hooks/session-start.js +2 -3
  48. package/dist/hooks/stop.js +2 -3
  49. package/dist/hooks/subagent-stop.js +0 -1
  50. package/dist/hooks/summary-worker.js +30 -62
  51. package/dist/index.js +7 -8
  52. package/dist/lib/consolidation.js +0 -1
  53. package/dist/lib/exe-daemon.js +33 -65
  54. package/dist/lib/hybrid-search.js +2 -3
  55. package/dist/lib/keychain.js +19 -58
  56. package/dist/lib/schedules.js +2 -3
  57. package/dist/lib/store.js +0 -1
  58. package/dist/mcp/server.js +29 -30
  59. package/dist/runtime/index.js +2 -3
  60. package/dist/tui/App.js +24 -56
  61. package/package.json +1 -1
@@ -1528,7 +1528,7 @@ ${p.content}`).join("\n\n");
1528
1528
  });
1529
1529
 
1530
1530
  // src/bin/backfill-conversations.ts
1531
- import crypto2 from "crypto";
1531
+ import crypto from "crypto";
1532
1532
  import { createReadStream } from "fs";
1533
1533
  import { readdir, stat } from "fs/promises";
1534
1534
  import path5 from "path";
@@ -1547,7 +1547,6 @@ import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
1547
1547
  import { existsSync } from "fs";
1548
1548
  import path from "path";
1549
1549
  import os from "os";
1550
- import crypto from "crypto";
1551
1550
  var SERVICE = "exe-mem";
1552
1551
  var ACCOUNT = "master-key";
1553
1552
  function getKeyDir() {
@@ -2557,7 +2556,7 @@ async function backfillConversations(options) {
2557
2556
  }
2558
2557
  }
2559
2558
  await writeMemory({
2560
- id: crypto2.randomUUID(),
2559
+ id: crypto.randomUUID(),
2561
2560
  agent_id: conv.agentId,
2562
2561
  agent_role: conv.agentId === "exe" ? "COO" : "specialist",
2563
2562
  session_id: conv.sessionId,
@@ -1528,7 +1528,7 @@ ${p.content}`).join("\n\n");
1528
1528
  });
1529
1529
 
1530
1530
  // src/bin/backfill-responses.ts
1531
- import crypto2 from "crypto";
1531
+ import crypto from "crypto";
1532
1532
  import { createReadStream } from "fs";
1533
1533
  import { readdir, stat } from "fs/promises";
1534
1534
  import path5 from "path";
@@ -1546,7 +1546,6 @@ import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
1546
1546
  import { existsSync } from "fs";
1547
1547
  import path from "path";
1548
1548
  import os from "os";
1549
- import crypto from "crypto";
1550
1549
  var SERVICE = "exe-mem";
1551
1550
  var ACCOUNT = "master-key";
1552
1551
  function getKeyDir() {
@@ -2311,7 +2310,7 @@ function extractText(content) {
2311
2310
  return texts.join("\n");
2312
2311
  }
2313
2312
  function hashText(text) {
2314
- return crypto2.createHash("sha256").update(text).digest("hex");
2313
+ return crypto.createHash("sha256").update(text).digest("hex");
2315
2314
  }
2316
2315
  async function loadExistingHashes() {
2317
2316
  const client = getClient();
@@ -2377,7 +2376,7 @@ async function processFile(filePath, seenHashes, daemonConnected, stats) {
2377
2376
  }
2378
2377
  }
2379
2378
  await writeMemory({
2380
- id: crypto2.randomUUID(),
2379
+ id: crypto.randomUUID(),
2381
2380
  agent_id: agentId,
2382
2381
  agent_role: agentId === "exe" ? "COO" : "specialist",
2383
2382
  session_id: entry.sessionId ?? "backfill",
@@ -1541,7 +1541,6 @@ import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
1541
1541
  import { existsSync } from "fs";
1542
1542
  import path from "path";
1543
1543
  import os from "os";
1544
- import crypto from "crypto";
1545
1544
  var SERVICE = "exe-mem";
1546
1545
  var ACCOUNT = "master-key";
1547
1546
  function getKeyDir() {
@@ -1919,7 +1919,6 @@ import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
1919
1919
  import { existsSync } from "fs";
1920
1920
  import path from "path";
1921
1921
  import os from "os";
1922
- import crypto from "crypto";
1923
1922
  var SERVICE = "exe-mem";
1924
1923
  var ACCOUNT = "master-key";
1925
1924
  function getKeyDir() {
package/dist/bin/cli.js CHANGED
@@ -1986,7 +1986,6 @@ import { readFile as readFile4, writeFile as writeFile4, unlink, mkdir as mkdir4
1986
1986
  import { existsSync as existsSync5 } from "fs";
1987
1987
  import path5 from "path";
1988
1988
  import os4 from "os";
1989
- import crypto from "crypto";
1990
1989
  function getKeyDir() {
1991
1990
  return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path5.join(os4.homedir(), ".exe-os");
1992
1991
  }
@@ -2051,65 +2050,34 @@ async function deleteMasterKey() {
2051
2050
  await unlink(keyPath);
2052
2051
  }
2053
2052
  }
2054
- function exportMnemonic(key) {
2055
- if (key.length !== 32) {
2056
- throw new Error(`Key must be 32 bytes, got ${key.length}`);
2057
- }
2058
- const hash = crypto.createHash("sha256").update(key).digest();
2059
- const checksumByte = hash[0];
2060
- let bits = "";
2061
- for (const byte of key) {
2062
- bits += byte.toString(2).padStart(8, "0");
2063
- }
2064
- bits += checksumByte.toString(2).padStart(8, "0");
2065
- const words = [];
2066
- let wordlist;
2053
+ async function loadBip39() {
2067
2054
  try {
2068
- const bip39 = __require("bip39");
2069
- wordlist = bip39.wordlists?.english ?? bip39.default?.wordlists?.english;
2070
- if (!wordlist) throw new Error("no wordlist");
2055
+ return await import("bip39");
2071
2056
  } catch {
2072
- throw new Error("bip39 package required. Install with: npm install bip39");
2057
+ throw new Error(
2058
+ "bip39 package not found. Run: npm install -g bip39\nOr reinstall exe-os: npm install -g @askexenow/exe-os"
2059
+ );
2073
2060
  }
2074
- for (let i = 0; i < 264; i += 11) {
2075
- const index = parseInt(bits.slice(i, i + 11), 2);
2076
- words.push(wordlist[index]);
2061
+ }
2062
+ async function exportMnemonic(key) {
2063
+ if (key.length !== 32) {
2064
+ throw new Error(`Key must be 32 bytes, got ${key.length}`);
2077
2065
  }
2078
- return words.join(" ");
2066
+ const { entropyToMnemonic } = await loadBip39();
2067
+ return entropyToMnemonic(key.toString("hex"));
2079
2068
  }
2080
- function importMnemonic(mnemonic) {
2081
- const words = mnemonic.trim().split(/\s+/);
2069
+ async function importMnemonic(mnemonic) {
2070
+ const trimmed = mnemonic.trim();
2071
+ const words = trimmed.split(/\s+/);
2082
2072
  if (words.length !== 24) {
2083
2073
  throw new Error(`Expected 24 words, got ${words.length}`);
2084
2074
  }
2085
- let wordlist;
2086
- try {
2087
- const bip39 = __require("bip39");
2088
- wordlist = bip39.wordlists?.english ?? bip39.default?.wordlists?.english;
2089
- if (!wordlist) throw new Error("no wordlist");
2090
- } catch {
2091
- throw new Error("bip39 package required. Install with: npm install bip39");
2092
- }
2093
- let bits = "";
2094
- for (const word of words) {
2095
- const index = wordlist.indexOf(word.toLowerCase());
2096
- if (index === -1) {
2097
- throw new Error(`Invalid BIP39 word: "${word}"`);
2098
- }
2099
- bits += index.toString(2).padStart(11, "0");
2100
- }
2101
- const entropyBits = bits.slice(0, 256);
2102
- const checksumBits = bits.slice(256, 264);
2103
- const key = Buffer.alloc(32);
2104
- for (let i = 0; i < 32; i++) {
2105
- key[i] = parseInt(entropyBits.slice(i * 8, (i + 1) * 8), 2);
2075
+ const { validateMnemonic, mnemonicToEntropy } = await loadBip39();
2076
+ if (!validateMnemonic(trimmed)) {
2077
+ throw new Error("Invalid mnemonic \u2014 check for typos or missing words");
2106
2078
  }
2107
- const hash = crypto.createHash("sha256").update(key).digest();
2108
- const expectedChecksum = hash[0].toString(2).padStart(8, "0");
2109
- if (checksumBits !== expectedChecksum) {
2110
- throw new Error("Invalid mnemonic checksum");
2111
- }
2112
- return key;
2079
+ const entropy = mnemonicToEntropy(trimmed);
2080
+ return Buffer.from(entropy, "hex");
2113
2081
  }
2114
2082
  var SERVICE, ACCOUNT;
2115
2083
  var init_keychain = __esm({
@@ -3450,7 +3418,7 @@ var backfill_conversations_exports = {};
3450
3418
  __export(backfill_conversations_exports, {
3451
3419
  backfillConversations: () => backfillConversations
3452
3420
  });
3453
- import crypto2 from "crypto";
3421
+ import crypto from "crypto";
3454
3422
  import { createReadStream } from "fs";
3455
3423
  import { readdir as readdir2, stat } from "fs/promises";
3456
3424
  import path8 from "path";
@@ -3755,7 +3723,7 @@ async function backfillConversations(options) {
3755
3723
  }
3756
3724
  }
3757
3725
  await writeMemory({
3758
- id: crypto2.randomUUID(),
3726
+ id: crypto.randomUUID(),
3759
3727
  agent_id: conv.agentId,
3760
3728
  agent_role: conv.agentId === "exe" ? "COO" : "specialist",
3761
3729
  session_id: conv.sessionId,
@@ -5196,13 +5164,13 @@ __export(crypto_exports, {
5196
5164
  initSyncCrypto: () => initSyncCrypto,
5197
5165
  isSyncCryptoInitialized: () => isSyncCryptoInitialized
5198
5166
  });
5199
- import crypto3 from "crypto";
5167
+ import crypto2 from "crypto";
5200
5168
  function initSyncCrypto(masterKey) {
5201
5169
  if (masterKey.length !== 32) {
5202
5170
  throw new Error(`Master key must be 32 bytes, got ${masterKey.length}`);
5203
5171
  }
5204
5172
  _syncKey = Buffer.from(
5205
- crypto3.hkdfSync("sha256", masterKey, "", SYNC_HKDF_INFO, 32)
5173
+ crypto2.hkdfSync("sha256", masterKey, "", SYNC_HKDF_INFO, 32)
5206
5174
  );
5207
5175
  }
5208
5176
  function isSyncCryptoInitialized() {
@@ -5216,8 +5184,8 @@ function requireSyncKey() {
5216
5184
  }
5217
5185
  function encryptSyncBlob(data) {
5218
5186
  const key = requireSyncKey();
5219
- const iv = crypto3.randomBytes(IV_LENGTH);
5220
- const cipher = crypto3.createCipheriv(ALGORITHM, key, iv);
5187
+ const iv = crypto2.randomBytes(IV_LENGTH);
5188
+ const cipher = crypto2.createCipheriv(ALGORITHM, key, iv);
5221
5189
  const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
5222
5190
  const tag = cipher.getAuthTag();
5223
5191
  return Buffer.concat([iv, encrypted, tag]).toString("base64");
@@ -5231,7 +5199,7 @@ function decryptSyncBlob(ciphertext) {
5231
5199
  const iv = combined.subarray(0, IV_LENGTH);
5232
5200
  const tag = combined.subarray(combined.length - TAG_LENGTH);
5233
5201
  const encrypted = combined.subarray(IV_LENGTH, combined.length - TAG_LENGTH);
5234
- const decipher = crypto3.createDecipheriv(ALGORITHM, key, iv);
5202
+ const decipher = crypto2.createDecipheriv(ALGORITHM, key, iv);
5235
5203
  decipher.setAuthTag(tag);
5236
5204
  return Buffer.concat([decipher.update(encrypted), decipher.final()]);
5237
5205
  }
@@ -5296,7 +5264,7 @@ __export(cloud_sync_exports, {
5296
5264
  recordRosterDeletion: () => recordRosterDeletion
5297
5265
  });
5298
5266
  import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, existsSync as existsSync11, readdirSync as readdirSync2, mkdirSync as mkdirSync5, appendFileSync, unlinkSync as unlinkSync4, openSync as openSync2, closeSync as closeSync2 } from "fs";
5299
- import crypto4 from "crypto";
5267
+ import crypto3 from "crypto";
5300
5268
  import path12 from "path";
5301
5269
  import { homedir as homedir3 } from "os";
5302
5270
  function sqlSafe(v) {
@@ -5679,7 +5647,7 @@ function buildRosterBlob(paths) {
5679
5647
  }
5680
5648
  const deletedNames = consumeRosterDeletions();
5681
5649
  const content = JSON.stringify({ roster, identities, config, deletedNames });
5682
- const hash = crypto4.createHash("sha256").update(content).digest("hex").slice(0, 16);
5650
+ const hash = crypto3.createHash("sha256").update(content).digest("hex").slice(0, 16);
5683
5651
  return { roster, identities, config, deletedNames, version: hash };
5684
5652
  }
5685
5653
  async function cloudPushRoster(config) {
@@ -7039,7 +7007,7 @@ __export(setup_wizard_exports, {
7039
7007
  runSetupWizard: () => runSetupWizard,
7040
7008
  validateModel: () => validateModel
7041
7009
  });
7042
- import crypto5 from "crypto";
7010
+ import crypto4 from "crypto";
7043
7011
  import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync7, unlinkSync as unlinkSync6 } from "fs";
7044
7012
  import os5 from "os";
7045
7013
  import path15 from "path";
@@ -7121,7 +7089,7 @@ async function runSetupWizard(opts = {}) {
7121
7089
  const { importMnemonic: importMnemonic2 } = await Promise.resolve().then(() => (init_keychain(), keychain_exports));
7122
7090
  const mnemonic = await ask(rl, "Paste your 24-word recovery phrase: ");
7123
7091
  try {
7124
- const key = importMnemonic2(mnemonic);
7092
+ const key = await importMnemonic2(mnemonic);
7125
7093
  await setMasterKey(key);
7126
7094
  log("Master key imported and stored securely.");
7127
7095
  log("");
@@ -7179,7 +7147,7 @@ async function runSetupWizard(opts = {}) {
7179
7147
  log("Encryption key already exists \u2014 skipping generation.");
7180
7148
  } else {
7181
7149
  log("Generating 256-bit encryption key...");
7182
- const key = crypto5.randomBytes(32);
7150
+ const key = crypto4.randomBytes(32);
7183
7151
  await setMasterKey(key);
7184
7152
  log("Encryption key generated and stored securely.");
7185
7153
  }
@@ -7556,7 +7524,11 @@ async function runSetupWizard(opts = {}) {
7556
7524
  log("Team: " + createdEmployees.map((e) => `${e.name} (${e.role})`).join(", "));
7557
7525
  }
7558
7526
  log("");
7559
- log(`Type \`${cooName}1\` to start (Claude Code) or \`exe-os\` for dashboard.`);
7527
+ log("=== Next Steps ===");
7528
+ log("");
7529
+ log(" 1. Restart your terminal (or run: source ~/.zshrc)");
7530
+ log(` 2. cd into a project folder: cd ~/my-project`);
7531
+ log(` 3. Launch your COO: ${cooName}1`);
7560
7532
  log("");
7561
7533
  } finally {
7562
7534
  rl.close();
@@ -14513,7 +14485,7 @@ var init_plan_limits = __esm({
14513
14485
  });
14514
14486
 
14515
14487
  // src/lib/notifications.ts
14516
- import crypto6 from "crypto";
14488
+ import crypto5 from "crypto";
14517
14489
  import path20 from "path";
14518
14490
  import os8 from "os";
14519
14491
  import {
@@ -14526,7 +14498,7 @@ import {
14526
14498
  async function writeNotification(notification) {
14527
14499
  try {
14528
14500
  const client = getClient();
14529
- const id = crypto6.randomUUID();
14501
+ const id = crypto5.randomUUID();
14530
14502
  const now = (/* @__PURE__ */ new Date()).toISOString();
14531
14503
  await client.execute({
14532
14504
  sql: `INSERT INTO notifications (id, agent_id, agent_role, event, project, summary, task_file, read, created_at)
@@ -14565,7 +14537,7 @@ var init_notifications = __esm({
14565
14537
  });
14566
14538
 
14567
14539
  // src/lib/session-kill-telemetry.ts
14568
- import crypto7 from "crypto";
14540
+ import crypto6 from "crypto";
14569
14541
  async function recordSessionKill(input) {
14570
14542
  try {
14571
14543
  const client = getClient();
@@ -14575,7 +14547,7 @@ async function recordSessionKill(input) {
14575
14547
  ticks_idle, estimated_tokens_saved)
14576
14548
  VALUES (?, ?, ?, ?, ?, ?, ?)`,
14577
14549
  args: [
14578
- crypto7.randomUUID(),
14550
+ crypto6.randomUUID(),
14579
14551
  input.sessionName,
14580
14552
  input.agentId,
14581
14553
  (/* @__PURE__ */ new Date()).toISOString(),
@@ -14614,7 +14586,7 @@ __export(tasks_crud_exports, {
14614
14586
  updateTaskStatus: () => updateTaskStatus,
14615
14587
  writeCheckpoint: () => writeCheckpoint
14616
14588
  });
14617
- import crypto8 from "crypto";
14589
+ import crypto7 from "crypto";
14618
14590
  import path21 from "path";
14619
14591
  import { execSync as execSync9 } from "child_process";
14620
14592
  import { mkdir as mkdir6, writeFile as writeFile5, appendFile } from "fs/promises";
@@ -14705,7 +14677,7 @@ async function resolveTask(client, identifier, scopeSession) {
14705
14677
  }
14706
14678
  async function createTaskCore(input) {
14707
14679
  const client = getClient();
14708
- const id = crypto8.randomUUID();
14680
+ const id = crypto7.randomUUID();
14709
14681
  const now = (/* @__PURE__ */ new Date()).toISOString();
14710
14682
  const slug = slugify(input.title);
14711
14683
  const taskFile = input.taskFile ?? `exe/${input.assignedTo}/${slug}.md`;
@@ -15491,10 +15463,10 @@ var init_tasks_notify = __esm({
15491
15463
  });
15492
15464
 
15493
15465
  // src/lib/behaviors.ts
15494
- import crypto9 from "crypto";
15466
+ import crypto8 from "crypto";
15495
15467
  async function storeBehavior(opts) {
15496
15468
  const client = getClient();
15497
- const id = crypto9.randomUUID();
15469
+ const id = crypto8.randomUUID();
15498
15470
  const now = (/* @__PURE__ */ new Date()).toISOString();
15499
15471
  await client.execute({
15500
15472
  sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, priority, content, active, created_at, updated_at)
@@ -15523,7 +15495,7 @@ __export(skill_learning_exports, {
15523
15495
  storeTrajectory: () => storeTrajectory,
15524
15496
  sweepTrajectories: () => sweepTrajectories
15525
15497
  });
15526
- import crypto10 from "crypto";
15498
+ import crypto9 from "crypto";
15527
15499
  async function extractTrajectory(taskId, agentId) {
15528
15500
  const client = getClient();
15529
15501
  const result = await client.execute({
@@ -15552,11 +15524,11 @@ async function extractTrajectory(taskId, agentId) {
15552
15524
  return signature;
15553
15525
  }
15554
15526
  function hashSignature(signature) {
15555
- return crypto10.createHash("sha256").update(signature.join("|")).digest("hex").slice(0, 16);
15527
+ return crypto9.createHash("sha256").update(signature.join("|")).digest("hex").slice(0, 16);
15556
15528
  }
15557
15529
  async function storeTrajectory(opts) {
15558
15530
  const client = getClient();
15559
- const id = crypto10.randomUUID();
15531
+ const id = crypto9.randomUUID();
15560
15532
  const now = (/* @__PURE__ */ new Date()).toISOString();
15561
15533
  const signatureHash = hashSignature(opts.signature);
15562
15534
  await client.execute({
@@ -22093,16 +22065,16 @@ __export(ws_auth_exports, {
22093
22065
  deriveWsAuthToken: () => deriveWsAuthToken,
22094
22066
  hashAuthToken: () => hashAuthToken
22095
22067
  });
22096
- import crypto11 from "crypto";
22068
+ import crypto10 from "crypto";
22097
22069
  function deriveWsAuthToken(masterKey) {
22098
- return Buffer.from(crypto11.hkdfSync("sha256", masterKey, "", WS_AUTH_HKDF_INFO, 32));
22070
+ return Buffer.from(crypto10.hkdfSync("sha256", masterKey, "", WS_AUTH_HKDF_INFO, 32));
22099
22071
  }
22100
22072
  function deriveOrgId(masterKey) {
22101
- const raw = Buffer.from(crypto11.hkdfSync("sha256", masterKey, "", ORG_ID_HKDF_INFO, 32));
22102
- return crypto11.createHash("sha256").update(raw).digest("hex").slice(0, 32);
22073
+ const raw = Buffer.from(crypto10.hkdfSync("sha256", masterKey, "", ORG_ID_HKDF_INFO, 32));
22074
+ return crypto10.createHash("sha256").update(raw).digest("hex").slice(0, 32);
22103
22075
  }
22104
22076
  function hashAuthToken(token) {
22105
- return crypto11.createHash("sha256").update(token).digest("hex");
22077
+ return crypto10.createHash("sha256").update(token).digest("hex");
22106
22078
  }
22107
22079
  var WS_AUTH_HKDF_INFO, ORG_ID_HKDF_INFO;
22108
22080
  var init_ws_auth = __esm({
@@ -2022,7 +2022,6 @@ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3
2022
2022
  import { existsSync as existsSync4 } from "fs";
2023
2023
  import path4 from "path";
2024
2024
  import os2 from "os";
2025
- import crypto from "crypto";
2026
2025
  var SERVICE = "exe-mem";
2027
2026
  var ACCOUNT = "master-key";
2028
2027
  function getKeyDir() {
@@ -1472,7 +1472,6 @@ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3
1472
1472
  import { existsSync as existsSync3 } from "fs";
1473
1473
  import path3 from "path";
1474
1474
  import os2 from "os";
1475
- import crypto from "crypto";
1476
1475
  function getKeyDir() {
1477
1476
  return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path3.join(os2.homedir(), ".exe-os");
1478
1477
  }
@@ -1537,65 +1536,34 @@ async function deleteMasterKey() {
1537
1536
  await unlink(keyPath);
1538
1537
  }
1539
1538
  }
1540
- function exportMnemonic(key) {
1541
- if (key.length !== 32) {
1542
- throw new Error(`Key must be 32 bytes, got ${key.length}`);
1543
- }
1544
- const hash = crypto.createHash("sha256").update(key).digest();
1545
- const checksumByte = hash[0];
1546
- let bits = "";
1547
- for (const byte of key) {
1548
- bits += byte.toString(2).padStart(8, "0");
1549
- }
1550
- bits += checksumByte.toString(2).padStart(8, "0");
1551
- const words = [];
1552
- let wordlist;
1539
+ async function loadBip39() {
1553
1540
  try {
1554
- const bip39 = __require("bip39");
1555
- wordlist = bip39.wordlists?.english ?? bip39.default?.wordlists?.english;
1556
- if (!wordlist) throw new Error("no wordlist");
1541
+ return await import("bip39");
1557
1542
  } catch {
1558
- throw new Error("bip39 package required. Install with: npm install bip39");
1543
+ throw new Error(
1544
+ "bip39 package not found. Run: npm install -g bip39\nOr reinstall exe-os: npm install -g @askexenow/exe-os"
1545
+ );
1559
1546
  }
1560
- for (let i = 0; i < 264; i += 11) {
1561
- const index = parseInt(bits.slice(i, i + 11), 2);
1562
- words.push(wordlist[index]);
1547
+ }
1548
+ async function exportMnemonic(key) {
1549
+ if (key.length !== 32) {
1550
+ throw new Error(`Key must be 32 bytes, got ${key.length}`);
1563
1551
  }
1564
- return words.join(" ");
1552
+ const { entropyToMnemonic } = await loadBip39();
1553
+ return entropyToMnemonic(key.toString("hex"));
1565
1554
  }
1566
- function importMnemonic(mnemonic) {
1567
- const words = mnemonic.trim().split(/\s+/);
1555
+ async function importMnemonic(mnemonic) {
1556
+ const trimmed = mnemonic.trim();
1557
+ const words = trimmed.split(/\s+/);
1568
1558
  if (words.length !== 24) {
1569
1559
  throw new Error(`Expected 24 words, got ${words.length}`);
1570
1560
  }
1571
- let wordlist;
1572
- try {
1573
- const bip39 = __require("bip39");
1574
- wordlist = bip39.wordlists?.english ?? bip39.default?.wordlists?.english;
1575
- if (!wordlist) throw new Error("no wordlist");
1576
- } catch {
1577
- throw new Error("bip39 package required. Install with: npm install bip39");
1578
- }
1579
- let bits = "";
1580
- for (const word of words) {
1581
- const index = wordlist.indexOf(word.toLowerCase());
1582
- if (index === -1) {
1583
- throw new Error(`Invalid BIP39 word: "${word}"`);
1584
- }
1585
- bits += index.toString(2).padStart(11, "0");
1561
+ const { validateMnemonic, mnemonicToEntropy } = await loadBip39();
1562
+ if (!validateMnemonic(trimmed)) {
1563
+ throw new Error("Invalid mnemonic \u2014 check for typos or missing words");
1586
1564
  }
1587
- const entropyBits = bits.slice(0, 256);
1588
- const checksumBits = bits.slice(256, 264);
1589
- const key = Buffer.alloc(32);
1590
- for (let i = 0; i < 32; i++) {
1591
- key[i] = parseInt(entropyBits.slice(i * 8, (i + 1) * 8), 2);
1592
- }
1593
- const hash = crypto.createHash("sha256").update(key).digest();
1594
- const expectedChecksum = hash[0].toString(2).padStart(8, "0");
1595
- if (checksumBits !== expectedChecksum) {
1596
- throw new Error("Invalid mnemonic checksum");
1597
- }
1598
- return key;
1565
+ const entropy = mnemonicToEntropy(trimmed);
1566
+ return Buffer.from(entropy, "hex");
1599
1567
  }
1600
1568
  var SERVICE, ACCOUNT;
1601
1569
  var init_keychain = __esm({
@@ -2781,7 +2749,7 @@ var init_plan_limits = __esm({
2781
2749
  });
2782
2750
 
2783
2751
  // src/lib/notifications.ts
2784
- import crypto2 from "crypto";
2752
+ import crypto from "crypto";
2785
2753
  import path9 from "path";
2786
2754
  import os5 from "os";
2787
2755
  import {
@@ -2794,7 +2762,7 @@ import {
2794
2762
  async function writeNotification(notification) {
2795
2763
  try {
2796
2764
  const client = getClient();
2797
- const id = crypto2.randomUUID();
2765
+ const id = crypto.randomUUID();
2798
2766
  const now = (/* @__PURE__ */ new Date()).toISOString();
2799
2767
  await client.execute({
2800
2768
  sql: `INSERT INTO notifications (id, agent_id, agent_role, event, project, summary, task_file, read, created_at)
@@ -2917,7 +2885,7 @@ async function migrateJsonNotifications() {
2917
2885
  sql: `INSERT OR IGNORE INTO notifications (id, agent_id, agent_role, event, project, summary, task_file, read, created_at)
2918
2886
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2919
2887
  args: [
2920
- crypto2.randomUUID(),
2888
+ crypto.randomUUID(),
2921
2889
  data.agentId ?? "unknown",
2922
2890
  data.agentRole ?? "unknown",
2923
2891
  data.event ?? "session_summary",
@@ -2966,7 +2934,7 @@ __export(session_kill_telemetry_exports, {
2966
2934
  recordSessionKill: () => recordSessionKill,
2967
2935
  sumTokensSavedSince: () => sumTokensSavedSince
2968
2936
  });
2969
- import crypto3 from "crypto";
2937
+ import crypto2 from "crypto";
2970
2938
  async function recordSessionKill(input) {
2971
2939
  try {
2972
2940
  const client = getClient();
@@ -2976,7 +2944,7 @@ async function recordSessionKill(input) {
2976
2944
  ticks_idle, estimated_tokens_saved)
2977
2945
  VALUES (?, ?, ?, ?, ?, ?, ?)`,
2978
2946
  args: [
2979
- crypto3.randomUUID(),
2947
+ crypto2.randomUUID(),
2980
2948
  input.sessionName,
2981
2949
  input.agentId,
2982
2950
  (/* @__PURE__ */ new Date()).toISOString(),
@@ -3058,7 +3026,7 @@ var init_session_kill_telemetry = __esm({
3058
3026
  });
3059
3027
 
3060
3028
  // src/lib/tasks-crud.ts
3061
- import crypto4 from "crypto";
3029
+ import crypto3 from "crypto";
3062
3030
  import path10 from "path";
3063
3031
  import { execSync as execSync5 } from "child_process";
3064
3032
  import { mkdir as mkdir4, writeFile as writeFile4, appendFile } from "fs/promises";
@@ -3149,7 +3117,7 @@ async function resolveTask(client, identifier, scopeSession) {
3149
3117
  }
3150
3118
  async function createTaskCore(input) {
3151
3119
  const client = getClient();
3152
- const id = crypto4.randomUUID();
3120
+ const id = crypto3.randomUUID();
3153
3121
  const now = (/* @__PURE__ */ new Date()).toISOString();
3154
3122
  const slug = slugify(input.title);
3155
3123
  const taskFile = input.taskFile ?? `exe/${input.assignedTo}/${slug}.md`;
@@ -3944,10 +3912,10 @@ var init_tasks_notify = __esm({
3944
3912
  });
3945
3913
 
3946
3914
  // src/lib/behaviors.ts
3947
- import crypto5 from "crypto";
3915
+ import crypto4 from "crypto";
3948
3916
  async function storeBehavior(opts) {
3949
3917
  const client = getClient();
3950
- const id = crypto5.randomUUID();
3918
+ const id = crypto4.randomUUID();
3951
3919
  const now = (/* @__PURE__ */ new Date()).toISOString();
3952
3920
  await client.execute({
3953
3921
  sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, priority, content, active, created_at, updated_at)
@@ -3976,7 +3944,7 @@ __export(skill_learning_exports, {
3976
3944
  storeTrajectory: () => storeTrajectory,
3977
3945
  sweepTrajectories: () => sweepTrajectories
3978
3946
  });
3979
- import crypto6 from "crypto";
3947
+ import crypto5 from "crypto";
3980
3948
  async function extractTrajectory(taskId, agentId) {
3981
3949
  const client = getClient();
3982
3950
  const result = await client.execute({
@@ -4005,11 +3973,11 @@ async function extractTrajectory(taskId, agentId) {
4005
3973
  return signature;
4006
3974
  }
4007
3975
  function hashSignature(signature) {
4008
- return crypto6.createHash("sha256").update(signature.join("|")).digest("hex").slice(0, 16);
3976
+ return crypto5.createHash("sha256").update(signature.join("|")).digest("hex").slice(0, 16);
4009
3977
  }
4010
3978
  async function storeTrajectory(opts) {
4011
3979
  const client = getClient();
4012
- const id = crypto6.randomUUID();
3980
+ const id = crypto5.randomUUID();
4013
3981
  const now = (/* @__PURE__ */ new Date()).toISOString();
4014
3982
  const signatureHash = hashSignature(opts.signature);
4015
3983
  await client.execute({
@@ -5647,13 +5615,13 @@ __export(crypto_exports, {
5647
5615
  initSyncCrypto: () => initSyncCrypto,
5648
5616
  isSyncCryptoInitialized: () => isSyncCryptoInitialized
5649
5617
  });
5650
- import crypto7 from "crypto";
5618
+ import crypto6 from "crypto";
5651
5619
  function initSyncCrypto(masterKey) {
5652
5620
  if (masterKey.length !== 32) {
5653
5621
  throw new Error(`Master key must be 32 bytes, got ${masterKey.length}`);
5654
5622
  }
5655
5623
  _syncKey = Buffer.from(
5656
- crypto7.hkdfSync("sha256", masterKey, "", SYNC_HKDF_INFO, 32)
5624
+ crypto6.hkdfSync("sha256", masterKey, "", SYNC_HKDF_INFO, 32)
5657
5625
  );
5658
5626
  }
5659
5627
  function isSyncCryptoInitialized() {
@@ -5667,8 +5635,8 @@ function requireSyncKey() {
5667
5635
  }
5668
5636
  function encryptSyncBlob(data) {
5669
5637
  const key = requireSyncKey();
5670
- const iv = crypto7.randomBytes(IV_LENGTH);
5671
- const cipher = crypto7.createCipheriv(ALGORITHM, key, iv);
5638
+ const iv = crypto6.randomBytes(IV_LENGTH);
5639
+ const cipher = crypto6.createCipheriv(ALGORITHM, key, iv);
5672
5640
  const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
5673
5641
  const tag = cipher.getAuthTag();
5674
5642
  return Buffer.concat([iv, encrypted, tag]).toString("base64");
@@ -5682,7 +5650,7 @@ function decryptSyncBlob(ciphertext) {
5682
5650
  const iv = combined.subarray(0, IV_LENGTH);
5683
5651
  const tag = combined.subarray(combined.length - TAG_LENGTH);
5684
5652
  const encrypted = combined.subarray(IV_LENGTH, combined.length - TAG_LENGTH);
5685
- const decipher = crypto7.createDecipheriv(ALGORITHM, key, iv);
5653
+ const decipher = crypto6.createDecipheriv(ALGORITHM, key, iv);
5686
5654
  decipher.setAuthTag(tag);
5687
5655
  return Buffer.concat([decipher.update(encrypted), decipher.final()]);
5688
5656
  }
@@ -5747,7 +5715,7 @@ __export(cloud_sync_exports, {
5747
5715
  recordRosterDeletion: () => recordRosterDeletion
5748
5716
  });
5749
5717
  import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, existsSync as existsSync15, readdirSync as readdirSync7, mkdirSync as mkdirSync9, appendFileSync as appendFileSync2, unlinkSync as unlinkSync7, openSync, closeSync } from "fs";
5750
- import crypto8 from "crypto";
5718
+ import crypto7 from "crypto";
5751
5719
  import path19 from "path";
5752
5720
  import { homedir } from "os";
5753
5721
  function sqlSafe(v) {
@@ -6130,7 +6098,7 @@ function buildRosterBlob(paths) {
6130
6098
  }
6131
6099
  const deletedNames = consumeRosterDeletions();
6132
6100
  const content = JSON.stringify({ roster, identities, config, deletedNames });
6133
- const hash = crypto8.createHash("sha256").update(content).digest("hex").slice(0, 16);
6101
+ const hash = crypto7.createHash("sha256").update(content).digest("hex").slice(0, 16);
6134
6102
  return { roster, identities, config, deletedNames, version: hash };
6135
6103
  }
6136
6104
  async function cloudPushRoster(config) {
@@ -6712,7 +6680,7 @@ __export(schedules_exports, {
6712
6680
  listSchedules: () => listSchedules,
6713
6681
  parseHumanCron: () => parseHumanCron
6714
6682
  });
6715
- import crypto9 from "crypto";
6683
+ import crypto8 from "crypto";
6716
6684
  import { execSync as execSync10 } from "child_process";
6717
6685
  async function ensureDb() {
6718
6686
  if (!isInitialized()) {
@@ -6781,7 +6749,7 @@ function parseHumanCron(input) {
6781
6749
  async function createSchedule(input) {
6782
6750
  await ensureDb();
6783
6751
  const client = getClient();
6784
- const id = crypto9.randomUUID().slice(0, 8);
6752
+ const id = crypto8.randomUUID().slice(0, 8);
6785
6753
  const now = (/* @__PURE__ */ new Date()).toISOString();
6786
6754
  const prompt = input.prompt ?? input.description;
6787
6755
  await client.execute({