@askexenow/exe-os 0.9.7 → 0.9.8

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 (95) hide show
  1. package/dist/bin/backfill-conversations.js +754 -79
  2. package/dist/bin/backfill-responses.js +752 -77
  3. package/dist/bin/backfill-vectors.js +752 -77
  4. package/dist/bin/cleanup-stale-review-tasks.js +657 -35
  5. package/dist/bin/cli.js +1388 -605
  6. package/dist/bin/exe-agent-config.js +123 -95
  7. package/dist/bin/exe-agent.js +41 -25
  8. package/dist/bin/exe-assign.js +732 -57
  9. package/dist/bin/exe-boot.js +784 -153
  10. package/dist/bin/exe-call.js +209 -138
  11. package/dist/bin/exe-cloud.js +35 -12
  12. package/dist/bin/exe-dispatch.js +692 -70
  13. package/dist/bin/exe-doctor.js +648 -26
  14. package/dist/bin/exe-export-behaviors.js +650 -20
  15. package/dist/bin/exe-forget.js +635 -13
  16. package/dist/bin/exe-gateway.js +1053 -271
  17. package/dist/bin/exe-heartbeat.js +665 -43
  18. package/dist/bin/exe-kill.js +646 -16
  19. package/dist/bin/exe-launch-agent.js +887 -97
  20. package/dist/bin/exe-link.js +658 -43
  21. package/dist/bin/exe-new-employee.js +378 -177
  22. package/dist/bin/exe-pending-messages.js +656 -34
  23. package/dist/bin/exe-pending-notifications.js +635 -13
  24. package/dist/bin/exe-pending-reviews.js +659 -37
  25. package/dist/bin/exe-rename.js +645 -30
  26. package/dist/bin/exe-review.js +635 -13
  27. package/dist/bin/exe-search.js +771 -88
  28. package/dist/bin/exe-session-cleanup.js +834 -150
  29. package/dist/bin/exe-settings.js +127 -91
  30. package/dist/bin/exe-start-codex.js +729 -94
  31. package/dist/bin/exe-start-opencode.js +717 -82
  32. package/dist/bin/exe-status.js +657 -35
  33. package/dist/bin/exe-team.js +635 -13
  34. package/dist/bin/git-sweep.js +720 -89
  35. package/dist/bin/graph-backfill.js +643 -13
  36. package/dist/bin/graph-export.js +646 -16
  37. package/dist/bin/install.js +596 -193
  38. package/dist/bin/scan-tasks.js +724 -93
  39. package/dist/bin/setup.js +1038 -210
  40. package/dist/bin/shard-migrate.js +645 -15
  41. package/dist/bin/wiki-sync.js +646 -16
  42. package/dist/gateway/index.js +1027 -245
  43. package/dist/hooks/bug-report-worker.js +891 -170
  44. package/dist/hooks/commit-complete.js +718 -87
  45. package/dist/hooks/error-recall.js +776 -93
  46. package/dist/hooks/exe-heartbeat-hook.js +85 -71
  47. package/dist/hooks/ingest-worker.js +840 -156
  48. package/dist/hooks/ingest.js +90 -73
  49. package/dist/hooks/instructions-loaded.js +669 -38
  50. package/dist/hooks/notification.js +661 -30
  51. package/dist/hooks/post-compact.js +674 -43
  52. package/dist/hooks/pre-compact.js +718 -87
  53. package/dist/hooks/pre-tool-use.js +872 -125
  54. package/dist/hooks/prompt-ingest-worker.js +758 -83
  55. package/dist/hooks/prompt-submit.js +1060 -319
  56. package/dist/hooks/response-ingest-worker.js +758 -83
  57. package/dist/hooks/session-end.js +721 -90
  58. package/dist/hooks/session-start.js +1031 -207
  59. package/dist/hooks/stop.js +680 -49
  60. package/dist/hooks/subagent-stop.js +674 -43
  61. package/dist/hooks/summary-worker.js +816 -132
  62. package/dist/index.js +1015 -232
  63. package/dist/lib/cloud-sync.js +663 -48
  64. package/dist/lib/consolidation.js +26 -3
  65. package/dist/lib/database.js +626 -18
  66. package/dist/lib/db.js +2261 -0
  67. package/dist/lib/device-registry.js +640 -25
  68. package/dist/lib/embedder.js +96 -43
  69. package/dist/lib/employee-templates.js +16 -0
  70. package/dist/lib/employees.js +259 -83
  71. package/dist/lib/exe-daemon-client.js +101 -63
  72. package/dist/lib/exe-daemon.js +894 -162
  73. package/dist/lib/hybrid-search.js +771 -88
  74. package/dist/lib/identity.js +27 -7
  75. package/dist/lib/messaging.js +55 -28
  76. package/dist/lib/reminders.js +21 -1
  77. package/dist/lib/schedules.js +636 -14
  78. package/dist/lib/skill-learning.js +21 -1
  79. package/dist/lib/store.js +643 -13
  80. package/dist/lib/task-router.js +82 -71
  81. package/dist/lib/tasks.js +98 -71
  82. package/dist/lib/tmux-routing.js +87 -60
  83. package/dist/lib/token-spend.js +26 -6
  84. package/dist/mcp/server.js +1784 -458
  85. package/dist/mcp/tools/complete-reminder.js +21 -1
  86. package/dist/mcp/tools/create-reminder.js +21 -1
  87. package/dist/mcp/tools/create-task.js +290 -164
  88. package/dist/mcp/tools/deactivate-behavior.js +24 -4
  89. package/dist/mcp/tools/list-reminders.js +21 -1
  90. package/dist/mcp/tools/list-tasks.js +195 -38
  91. package/dist/mcp/tools/send-message.js +58 -31
  92. package/dist/mcp/tools/update-task.js +75 -48
  93. package/dist/runtime/index.js +720 -89
  94. package/dist/tui/App.js +853 -123
  95. package/package.json +3 -2
package/dist/bin/cli.js CHANGED
@@ -266,6 +266,118 @@ var init_config = __esm({
266
266
  }
267
267
  });
268
268
 
269
+ // src/lib/runtime-table.ts
270
+ var RUNTIME_TABLE, DEFAULT_RUNTIME;
271
+ var init_runtime_table = __esm({
272
+ "src/lib/runtime-table.ts"() {
273
+ "use strict";
274
+ RUNTIME_TABLE = {
275
+ codex: {
276
+ binary: "codex",
277
+ launchMode: "interactive",
278
+ autoApproveFlag: "--dangerously-bypass-approvals-and-sandbox",
279
+ inlineFlag: "--no-alt-screen",
280
+ apiKeyEnv: "OPENAI_API_KEY",
281
+ defaultModel: "gpt-5.4"
282
+ },
283
+ opencode: {
284
+ binary: "opencode",
285
+ launchMode: "exec",
286
+ autoApproveFlag: "--dangerously-skip-permissions",
287
+ inlineFlag: "",
288
+ apiKeyEnv: "ANTHROPIC_API_KEY",
289
+ defaultModel: "anthropic/claude-sonnet-4-6"
290
+ }
291
+ };
292
+ DEFAULT_RUNTIME = "claude";
293
+ }
294
+ });
295
+
296
+ // src/lib/agent-config.ts
297
+ var agent_config_exports = {};
298
+ __export(agent_config_exports, {
299
+ AGENT_CONFIG_PATH: () => AGENT_CONFIG_PATH,
300
+ DEFAULT_MODELS: () => DEFAULT_MODELS,
301
+ KNOWN_RUNTIMES: () => KNOWN_RUNTIMES,
302
+ RUNTIME_LABELS: () => RUNTIME_LABELS,
303
+ clearAgentRuntime: () => clearAgentRuntime,
304
+ getAgentRuntime: () => getAgentRuntime,
305
+ loadAgentConfig: () => loadAgentConfig,
306
+ saveAgentConfig: () => saveAgentConfig,
307
+ setAgentRuntime: () => setAgentRuntime
308
+ });
309
+ import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2, mkdirSync } from "fs";
310
+ import path2 from "path";
311
+ function loadAgentConfig() {
312
+ if (!existsSync2(AGENT_CONFIG_PATH)) return {};
313
+ try {
314
+ return JSON.parse(readFileSync2(AGENT_CONFIG_PATH, "utf-8"));
315
+ } catch {
316
+ return {};
317
+ }
318
+ }
319
+ function saveAgentConfig(config) {
320
+ const dir = path2.dirname(AGENT_CONFIG_PATH);
321
+ if (!existsSync2(dir)) mkdirSync(dir, { recursive: true });
322
+ writeFileSync(AGENT_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
323
+ }
324
+ function getAgentRuntime(agentId) {
325
+ const config = loadAgentConfig();
326
+ const entry = config[agentId];
327
+ if (entry) return entry;
328
+ const orgDefault = config["default"];
329
+ if (orgDefault) return orgDefault;
330
+ return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
331
+ }
332
+ function setAgentRuntime(agentId, runtime, model) {
333
+ const knownModels = KNOWN_RUNTIMES[runtime];
334
+ if (!knownModels) {
335
+ return {
336
+ ok: false,
337
+ error: `Unknown runtime "${runtime}". Valid: ${Object.keys(KNOWN_RUNTIMES).join(", ")}`
338
+ };
339
+ }
340
+ if (!knownModels.includes(model)) {
341
+ return {
342
+ ok: false,
343
+ error: `Unknown model "${model}" for runtime "${runtime}". Valid: ${knownModels.join(", ")}`
344
+ };
345
+ }
346
+ const config = loadAgentConfig();
347
+ config[agentId] = { runtime, model };
348
+ saveAgentConfig(config);
349
+ return { ok: true };
350
+ }
351
+ function clearAgentRuntime(agentId) {
352
+ const config = loadAgentConfig();
353
+ delete config[agentId];
354
+ saveAgentConfig(config);
355
+ }
356
+ var AGENT_CONFIG_PATH, KNOWN_RUNTIMES, RUNTIME_LABELS, DEFAULT_MODELS;
357
+ var init_agent_config = __esm({
358
+ "src/lib/agent-config.ts"() {
359
+ "use strict";
360
+ init_config();
361
+ init_runtime_table();
362
+ AGENT_CONFIG_PATH = path2.join(EXE_AI_DIR, "agent-config.json");
363
+ KNOWN_RUNTIMES = {
364
+ claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
365
+ codex: ["gpt-5.4", "gpt-5.5", "gpt-5.3-codex-spark", "o3", "o4-mini"],
366
+ opencode: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4", "google/gemini-2.5-pro", "deepseek/deepseek-r3", "minimax/minimax-m2.5"]
367
+ };
368
+ RUNTIME_LABELS = {
369
+ claude: "Claude Code (Anthropic)",
370
+ codex: "Codex (OpenAI)",
371
+ opencode: "OpenCode (open source)"
372
+ };
373
+ DEFAULT_MODELS = {
374
+ claude: "claude-opus-4",
375
+ codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
376
+ opencode: RUNTIME_TABLE.opencode?.defaultModel ?? "anthropic/claude-sonnet-4-6"
377
+ };
378
+ }
379
+ });
380
+
269
381
  // src/lib/employees.ts
270
382
  var employees_exports = {};
271
383
  __export(employees_exports, {
@@ -281,6 +393,7 @@ __export(employees_exports, {
281
393
  getEmployeeByRole: () => getEmployeeByRole,
282
394
  getEmployeeNamesByRole: () => getEmployeeNamesByRole,
283
395
  hasRole: () => hasRole,
396
+ hireEmployee: () => hireEmployee,
284
397
  isCoordinatorName: () => isCoordinatorName,
285
398
  isCoordinatorRole: () => isCoordinatorRole,
286
399
  isMultiInstance: () => isMultiInstance,
@@ -293,9 +406,9 @@ __export(employees_exports, {
293
406
  validateEmployeeName: () => validateEmployeeName
294
407
  });
295
408
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
296
- import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
409
+ import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync3, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
297
410
  import { execSync } from "child_process";
298
- import path2 from "path";
411
+ import path3 from "path";
299
412
  import os2 from "os";
300
413
  function normalizeRole(role) {
301
414
  return (role ?? "").trim().toLowerCase();
@@ -332,7 +445,7 @@ function validateEmployeeName(name) {
332
445
  return { valid: true };
333
446
  }
334
447
  async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
335
- if (!existsSync2(employeesPath)) {
448
+ if (!existsSync3(employeesPath)) {
336
449
  return [];
337
450
  }
338
451
  const raw = await readFile2(employeesPath, "utf-8");
@@ -343,13 +456,13 @@ async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
343
456
  }
344
457
  }
345
458
  async function saveEmployees(employees, employeesPath = EMPLOYEES_PATH) {
346
- await mkdir2(path2.dirname(employeesPath), { recursive: true });
459
+ await mkdir2(path3.dirname(employeesPath), { recursive: true });
347
460
  await writeFile2(employeesPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
348
461
  }
349
462
  function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
350
- if (!existsSync2(employeesPath)) return [];
463
+ if (!existsSync3(employeesPath)) return [];
351
464
  try {
352
- return JSON.parse(readFileSync2(employeesPath, "utf-8"));
465
+ return JSON.parse(readFileSync3(employeesPath, "utf-8"));
353
466
  } catch {
354
467
  return [];
355
468
  }
@@ -391,6 +504,52 @@ function addEmployee(employees, employee) {
391
504
  }
392
505
  return [...employees, normalized];
393
506
  }
507
+ function appendToCoordinatorTeam(employee) {
508
+ const coordinator = getCoordinatorEmployee(loadEmployeesSync());
509
+ if (!coordinator) return;
510
+ const idPath = path3.join(IDENTITY_DIR, `${coordinator.name}.md`);
511
+ if (!existsSync3(idPath)) return;
512
+ const content = readFileSync3(idPath, "utf-8");
513
+ if (content.includes(`**${capitalize(employee.name)}`)) return;
514
+ const teamMatch = content.match(TEAM_SECTION_RE);
515
+ if (!teamMatch || teamMatch.index === void 0) return;
516
+ const afterTeam = content.slice(teamMatch.index + teamMatch[0].length);
517
+ const nextHeading = afterTeam.match(/\n## /);
518
+ const entry = `
519
+ **${capitalize(employee.name)} (${employee.role}):** Newly hired. Update this description as the role develops.
520
+ `;
521
+ let updated;
522
+ if (nextHeading && nextHeading.index !== void 0) {
523
+ const insertAt = teamMatch.index + teamMatch[0].length + nextHeading.index;
524
+ updated = content.slice(0, insertAt) + entry + content.slice(insertAt);
525
+ } else {
526
+ updated = content.trimEnd() + "\n" + entry;
527
+ }
528
+ writeFileSync2(idPath, updated, "utf-8");
529
+ }
530
+ function capitalize(s) {
531
+ return s.charAt(0).toUpperCase() + s.slice(1);
532
+ }
533
+ async function hireEmployee(employee) {
534
+ const employees = await loadEmployees();
535
+ const updated = addEmployee(employees, employee);
536
+ await saveEmployees(updated);
537
+ try {
538
+ appendToCoordinatorTeam(employee);
539
+ } catch {
540
+ }
541
+ try {
542
+ const { loadAgentConfig: loadAgentConfig2, saveAgentConfig: saveAgentConfig2 } = await Promise.resolve().then(() => (init_agent_config(), agent_config_exports));
543
+ const config = loadAgentConfig2();
544
+ const name = employee.name.toLowerCase();
545
+ if (!config[name] && config["default"]) {
546
+ config[name] = { ...config["default"] };
547
+ saveAgentConfig2(config);
548
+ }
549
+ } catch {
550
+ }
551
+ return updated;
552
+ }
394
553
  async function normalizeRosterCase(rosterPath) {
395
554
  const employees = await loadEmployees(rosterPath);
396
555
  let changed = false;
@@ -400,14 +559,14 @@ async function normalizeRosterCase(rosterPath) {
400
559
  emp.name = emp.name.toLowerCase();
401
560
  changed = true;
402
561
  try {
403
- const identityDir = path2.join(os2.homedir(), ".exe-os", "identity");
404
- const oldPath = path2.join(identityDir, `${oldName}.md`);
405
- const newPath = path2.join(identityDir, `${emp.name}.md`);
406
- if (existsSync2(oldPath) && !existsSync2(newPath)) {
562
+ const identityDir = path3.join(os2.homedir(), ".exe-os", "identity");
563
+ const oldPath = path3.join(identityDir, `${oldName}.md`);
564
+ const newPath = path3.join(identityDir, `${emp.name}.md`);
565
+ if (existsSync3(oldPath) && !existsSync3(newPath)) {
407
566
  renameSync2(oldPath, newPath);
408
- } else if (existsSync2(oldPath) && oldPath !== newPath) {
409
- const content = readFileSync2(oldPath, "utf-8");
410
- writeFileSync(newPath, content, "utf-8");
567
+ } else if (existsSync3(oldPath) && oldPath !== newPath) {
568
+ const content = readFileSync3(oldPath, "utf-8");
569
+ writeFileSync2(newPath, content, "utf-8");
411
570
  if (oldPath.toLowerCase() !== newPath.toLowerCase()) {
412
571
  unlinkSync(oldPath);
413
572
  }
@@ -437,7 +596,7 @@ function registerBinSymlinks(name) {
437
596
  errors.push("Could not find 'exe-os' in PATH");
438
597
  return { created, skipped, errors };
439
598
  }
440
- const binDir = path2.dirname(exeBinPath);
599
+ const binDir = path3.dirname(exeBinPath);
441
600
  let target;
442
601
  try {
443
602
  target = readlinkSync(exeBinPath);
@@ -447,8 +606,8 @@ function registerBinSymlinks(name) {
447
606
  }
448
607
  for (const suffix of ["", "-opencode"]) {
449
608
  const linkName = `${name}${suffix}`;
450
- const linkPath = path2.join(binDir, linkName);
451
- if (existsSync2(linkPath)) {
609
+ const linkPath = path3.join(binDir, linkName);
610
+ if (existsSync3(linkPath)) {
452
611
  skipped.push(linkName);
453
612
  continue;
454
613
  }
@@ -461,42 +620,44 @@ function registerBinSymlinks(name) {
461
620
  }
462
621
  return { created, skipped, errors };
463
622
  }
464
- var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, MULTI_INSTANCE_ROLES;
623
+ var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, MULTI_INSTANCE_ROLES, IDENTITY_DIR, TEAM_SECTION_RE;
465
624
  var init_employees = __esm({
466
625
  "src/lib/employees.ts"() {
467
626
  "use strict";
468
627
  init_config();
469
- EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
628
+ EMPLOYEES_PATH = path3.join(EXE_AI_DIR, "exe-employees.json");
470
629
  DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
471
630
  COORDINATOR_ROLE = "COO";
472
631
  MULTI_INSTANCE_ROLES = /* @__PURE__ */ new Set(["principal engineer", "content production specialist", "staff code reviewer"]);
632
+ IDENTITY_DIR = path3.join(EXE_AI_DIR, "identity");
633
+ TEAM_SECTION_RE = /^## Team\b.*$/m;
473
634
  }
474
635
  });
475
636
 
476
637
  // src/lib/agent-symlinks.ts
477
638
  import os3 from "os";
478
- import path3 from "path";
639
+ import path4 from "path";
479
640
  import {
480
- existsSync as existsSync3,
641
+ existsSync as existsSync4,
481
642
  lstatSync,
482
- mkdirSync,
643
+ mkdirSync as mkdirSync2,
483
644
  readlinkSync as readlinkSync2,
484
645
  symlinkSync as symlinkSync2
485
646
  } from "fs";
486
647
  function claudeAgentsDir(homeDir) {
487
- return path3.join(homeDir, ".claude", "agents");
648
+ return path4.join(homeDir, ".claude", "agents");
488
649
  }
489
650
  function identitySourcePath(homeDir, agentId) {
490
- return path3.join(homeDir, ".exe-os", "identity", `${agentId}.md`);
651
+ return path4.join(homeDir, ".exe-os", "identity", `${agentId}.md`);
491
652
  }
492
653
  function claudeAgentLinkPath(homeDir, agentId) {
493
- return path3.join(claudeAgentsDir(homeDir), `${agentId}.md`);
654
+ return path4.join(claudeAgentsDir(homeDir), `${agentId}.md`);
494
655
  }
495
656
  function ensureAgentSymlink(agentId, homeDir = os3.homedir()) {
496
657
  const target = identitySourcePath(homeDir, agentId);
497
658
  const link = claudeAgentLinkPath(homeDir, agentId);
498
- mkdirSync(claudeAgentsDir(homeDir), { recursive: true });
499
- if (existsSync3(link)) {
659
+ mkdirSync2(claudeAgentsDir(homeDir), { recursive: true });
660
+ if (existsSync4(link)) {
500
661
  let stat2;
501
662
  try {
502
663
  stat2 = lstatSync(link);
@@ -570,33 +731,33 @@ __export(preferences_exports, {
570
731
  loadPreferences: () => loadPreferences,
571
732
  savePreferences: () => savePreferences
572
733
  });
573
- import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
574
- import path4 from "path";
734
+ import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
735
+ import path5 from "path";
575
736
  import os4 from "os";
576
737
  function loadPreferences(homeDir = os4.homedir()) {
577
- const configPath = path4.join(homeDir, ".exe-os", "config.json");
578
- if (!existsSync4(configPath)) return {};
738
+ const configPath = path5.join(homeDir, ".exe-os", "config.json");
739
+ if (!existsSync5(configPath)) return {};
579
740
  try {
580
- const config = JSON.parse(readFileSync3(configPath, "utf-8"));
741
+ const config = JSON.parse(readFileSync4(configPath, "utf-8"));
581
742
  return config.preferences ?? {};
582
743
  } catch {
583
744
  return {};
584
745
  }
585
746
  }
586
747
  function savePreferences(prefs, homeDir = os4.homedir()) {
587
- const configDir = path4.join(homeDir, ".exe-os");
588
- const configPath = path4.join(configDir, "config.json");
589
- mkdirSync2(configDir, { recursive: true });
748
+ const configDir = path5.join(homeDir, ".exe-os");
749
+ const configPath = path5.join(configDir, "config.json");
750
+ mkdirSync3(configDir, { recursive: true });
590
751
  let config = {};
591
- if (existsSync4(configPath)) {
752
+ if (existsSync5(configPath)) {
592
753
  try {
593
- config = JSON.parse(readFileSync3(configPath, "utf-8"));
754
+ config = JSON.parse(readFileSync4(configPath, "utf-8"));
594
755
  } catch {
595
756
  config = {};
596
757
  }
597
758
  }
598
759
  config.preferences = prefs;
599
- writeFileSync2(configPath, JSON.stringify(config, null, 2) + "\n");
760
+ writeFileSync3(configPath, JSON.stringify(config, null, 2) + "\n");
600
761
  }
601
762
  var init_preferences = __esm({
602
763
  "src/lib/preferences.ts"() {
@@ -618,52 +779,52 @@ __export(installer_exports, {
618
779
  setupTmux: () => setupTmux
619
780
  });
620
781
  import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
621
- import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3, copyFileSync, mkdirSync as mkdirSync3 } from "fs";
622
- import path5 from "path";
782
+ import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync4, copyFileSync, mkdirSync as mkdirSync4 } from "fs";
783
+ import path6 from "path";
623
784
  import os5 from "os";
624
785
  import { execSync as execSync2 } from "child_process";
625
786
  import { fileURLToPath } from "url";
626
787
  function resolvePackageRoot() {
627
788
  const thisFile = fileURLToPath(import.meta.url);
628
- let dir = path5.dirname(thisFile);
629
- const root = path5.parse(dir).root;
789
+ let dir = path6.dirname(thisFile);
790
+ const root = path6.parse(dir).root;
630
791
  while (dir !== root) {
631
- const pkgPath = path5.join(dir, "package.json");
632
- if (existsSync5(pkgPath)) {
792
+ const pkgPath = path6.join(dir, "package.json");
793
+ if (existsSync6(pkgPath)) {
633
794
  try {
634
- const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
795
+ const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
635
796
  if (pkg.name === "@askexenow/exe-os" || pkg.name === "exe-os") return dir;
636
797
  } catch {
637
798
  }
638
799
  }
639
- dir = path5.dirname(dir);
800
+ dir = path6.dirname(dir);
640
801
  }
641
- return path5.resolve(path5.dirname(thisFile), "..", "..", "..");
802
+ return path6.resolve(path6.dirname(thisFile), "..", "..", "..");
642
803
  }
643
804
  async function copySlashCommands(packageRoot, homeDir = os5.homedir()) {
644
805
  let copied = 0;
645
806
  let skipped = 0;
646
- const skillsBase = path5.join(homeDir, ".claude", "skills");
647
- const exeDir = path5.join(packageRoot, "src", "commands", "exe");
648
- if (existsSync5(exeDir)) {
807
+ const skillsBase = path6.join(homeDir, ".claude", "skills");
808
+ const exeDir = path6.join(packageRoot, "src", "commands", "exe");
809
+ if (existsSync6(exeDir)) {
649
810
  const entries = await readdir(exeDir);
650
811
  const mdFiles = entries.filter((f) => f.endsWith(".md"));
651
812
  for (const file of mdFiles) {
652
813
  const name = file.replace(".md", "");
653
- const destDir = path5.join(skillsBase, `exe-${name}`);
814
+ const destDir = path6.join(skillsBase, `exe-${name}`);
654
815
  await mkdir3(destDir, { recursive: true });
655
- const srcPath = path5.join(exeDir, file);
656
- const destPath = path5.join(destDir, "SKILL.md");
816
+ const srcPath = path6.join(exeDir, file);
817
+ const destPath = path6.join(destDir, "SKILL.md");
657
818
  const result = await copyAsSkill(srcPath, destPath, `exe-${name}`);
658
819
  if (result) copied++;
659
820
  else skipped++;
660
821
  }
661
822
  }
662
- const topLevelSrc = path5.join(packageRoot, "src", "commands", "exe.md");
663
- if (existsSync5(topLevelSrc)) {
664
- const destDir = path5.join(skillsBase, "exe");
823
+ const topLevelSrc = path6.join(packageRoot, "src", "commands", "exe.md");
824
+ if (existsSync6(topLevelSrc)) {
825
+ const destDir = path6.join(skillsBase, "exe");
665
826
  await mkdir3(destDir, { recursive: true });
666
- const destPath = path5.join(destDir, "SKILL.md");
827
+ const destPath = path6.join(destDir, "SKILL.md");
667
828
  const result = await copyAsSkill(topLevelSrc, destPath, "exe");
668
829
  if (result) copied++;
669
830
  else skipped++;
@@ -686,7 +847,7 @@ name: ${skillName}
686
847
  `);
687
848
  }
688
849
  }
689
- if (existsSync5(destPath)) {
850
+ if (existsSync6(destPath)) {
690
851
  const existing = await readFile3(destPath, "utf-8");
691
852
  if (existing === content) return false;
692
853
  }
@@ -694,9 +855,9 @@ name: ${skillName}
694
855
  return true;
695
856
  }
696
857
  async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
697
- const claudeJsonPath = path5.join(homeDir, ".claude.json");
858
+ const claudeJsonPath = path6.join(homeDir, ".claude.json");
698
859
  let claudeJson = {};
699
- if (existsSync5(claudeJsonPath)) {
860
+ if (existsSync6(claudeJsonPath)) {
700
861
  try {
701
862
  claudeJson = JSON.parse(await readFile3(claudeJsonPath, "utf-8"));
702
863
  } catch {
@@ -709,7 +870,7 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
709
870
  const newEntry = {
710
871
  type: "stdio",
711
872
  command: "node",
712
- args: [path5.join(packageRoot, "dist", "mcp", "server.js")],
873
+ args: [path6.join(packageRoot, "dist", "mcp", "server.js")],
713
874
  env: {}
714
875
  };
715
876
  const currentMem = claudeJson.mcpServers[MCP_LEGACY_KEY];
@@ -717,17 +878,17 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
717
878
  const memMatches = currentMem && JSON.stringify(currentMem) === JSON.stringify(newEntry);
718
879
  const osMatches = currentOs && JSON.stringify(currentOs) === JSON.stringify(newEntry);
719
880
  if (memMatches && osMatches) {
720
- await cleanSettingsJsonMcp(path5.join(homeDir, ".claude", "settings.json"));
881
+ await cleanSettingsJsonMcp(path6.join(homeDir, ".claude", "settings.json"));
721
882
  return false;
722
883
  }
723
884
  claudeJson.mcpServers[MCP_LEGACY_KEY] = newEntry;
724
885
  claudeJson.mcpServers[MCP_PRIMARY_KEY] = newEntry;
725
886
  await writeFile3(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
726
- await cleanSettingsJsonMcp(path5.join(homeDir, ".claude", "settings.json"));
887
+ await cleanSettingsJsonMcp(path6.join(homeDir, ".claude", "settings.json"));
727
888
  return true;
728
889
  }
729
890
  async function cleanSettingsJsonMcp(settingsPath) {
730
- if (!existsSync5(settingsPath)) return;
891
+ if (!existsSync6(settingsPath)) return;
731
892
  try {
732
893
  const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
733
894
  const servers = settings.mcpServers;
@@ -748,13 +909,13 @@ async function cleanSettingsJsonMcp(settingsPath) {
748
909
  }
749
910
  }
750
911
  async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
751
- const settingsPath = path5.join(homeDir, ".claude", "settings.json");
752
- const logsDir = path5.join(homeDir, ".exe-os", "logs");
753
- const hookLogPath = path5.join(logsDir, "hooks.log");
912
+ const settingsPath = path6.join(homeDir, ".claude", "settings.json");
913
+ const logsDir = path6.join(homeDir, ".exe-os", "logs");
914
+ const hookLogPath = path6.join(logsDir, "hooks.log");
754
915
  const logSuffix = ` 2>> "${hookLogPath}"`;
755
916
  await mkdir3(logsDir, { recursive: true });
756
917
  let settings = {};
757
- if (existsSync5(settingsPath)) {
918
+ if (existsSync6(settingsPath)) {
758
919
  try {
759
920
  settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
760
921
  } catch {
@@ -776,11 +937,11 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
776
937
  hooks: [
777
938
  {
778
939
  type: "command",
779
- command: `node "${path5.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
940
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
780
941
  },
781
942
  {
782
943
  type: "command",
783
- command: `node "${path5.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
944
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
784
945
  }
785
946
  ]
786
947
  },
@@ -792,7 +953,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
792
953
  hooks: [
793
954
  {
794
955
  type: "command",
795
- command: `node "${path5.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
956
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
796
957
  timeout: 1e4
797
958
  }
798
959
  ]
@@ -805,7 +966,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
805
966
  hooks: [
806
967
  {
807
968
  type: "command",
808
- command: `node "${path5.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
969
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
809
970
  }
810
971
  ]
811
972
  },
@@ -817,7 +978,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
817
978
  hooks: [
818
979
  {
819
980
  type: "command",
820
- command: `node "${path5.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
981
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
821
982
  timeout: 5e3
822
983
  }
823
984
  ]
@@ -830,7 +991,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
830
991
  hooks: [
831
992
  {
832
993
  type: "command",
833
- command: `node "${path5.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
994
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
834
995
  }
835
996
  ]
836
997
  },
@@ -843,7 +1004,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
843
1004
  hooks: [
844
1005
  {
845
1006
  type: "command",
846
- command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
1007
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
847
1008
  }
848
1009
  ]
849
1010
  },
@@ -855,7 +1016,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
855
1016
  hooks: [
856
1017
  {
857
1018
  type: "command",
858
- command: `node "${path5.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
1019
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
859
1020
  }
860
1021
  ]
861
1022
  },
@@ -867,7 +1028,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
867
1028
  hooks: [
868
1029
  {
869
1030
  type: "command",
870
- command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
1031
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
871
1032
  timeout: 1e4
872
1033
  }
873
1034
  ]
@@ -880,7 +1041,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
880
1041
  hooks: [
881
1042
  {
882
1043
  type: "command",
883
- command: `node "${path5.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
1044
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
884
1045
  }
885
1046
  ]
886
1047
  },
@@ -892,7 +1053,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
892
1053
  hooks: [
893
1054
  {
894
1055
  type: "command",
895
- command: `node "${path5.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
1056
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
896
1057
  }
897
1058
  ]
898
1059
  },
@@ -904,7 +1065,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
904
1065
  hooks: [
905
1066
  {
906
1067
  type: "command",
907
- command: `node "${path5.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
1068
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
908
1069
  timeout: 1e4
909
1070
  }
910
1071
  ]
@@ -917,7 +1078,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
917
1078
  hooks: [
918
1079
  {
919
1080
  type: "command",
920
- command: `node "${path5.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
1081
+ command: `node "${path6.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
921
1082
  }
922
1083
  ]
923
1084
  },
@@ -1016,13 +1177,13 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1016
1177
  allowList.push(tool);
1017
1178
  }
1018
1179
  }
1019
- await mkdir3(path5.dirname(settingsPath), { recursive: true });
1180
+ await mkdir3(path6.dirname(settingsPath), { recursive: true });
1020
1181
  await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
1021
1182
  return { added, skipped };
1022
1183
  }
1023
1184
  async function cleanOldShellFunctions(homeDir = os5.homedir()) {
1024
- const rosterPath = path5.join(homeDir, ".exe-os", "exe-employees.json");
1025
- if (!existsSync5(rosterPath)) return 0;
1185
+ const rosterPath = path6.join(homeDir, ".exe-os", "exe-employees.json");
1186
+ if (!existsSync6(rosterPath)) return 0;
1026
1187
  let employees;
1027
1188
  try {
1028
1189
  employees = JSON.parse(await readFile3(rosterPath, "utf-8"));
@@ -1037,13 +1198,13 @@ async function cleanOldShellFunctions(homeDir = os5.homedir()) {
1037
1198
  return { name: n, funcDef, forLoop };
1038
1199
  });
1039
1200
  const rcFiles = [
1040
- path5.join(homeDir, ".zshrc"),
1041
- path5.join(homeDir, ".bashrc")
1201
+ path6.join(homeDir, ".zshrc"),
1202
+ path6.join(homeDir, ".bashrc")
1042
1203
  ];
1043
1204
  const REMOVED_MARKER = "# Removed by exe-os \u2014 wrappers now at ~/.exe-os/bin/";
1044
1205
  let totalRemoved = 0;
1045
1206
  for (const rcPath of rcFiles) {
1046
- if (!existsSync5(rcPath)) continue;
1207
+ if (!existsSync6(rcPath)) continue;
1047
1208
  let content;
1048
1209
  try {
1049
1210
  content = await readFile3(rcPath, "utf-8");
@@ -1147,8 +1308,8 @@ function escapeRegExp(s) {
1147
1308
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1148
1309
  }
1149
1310
  async function injectOrchestrationRules(homeDir) {
1150
- const claudeDir = path5.join(homeDir, ".claude");
1151
- const claudeMdPath = path5.join(claudeDir, "CLAUDE.md");
1311
+ const claudeDir = path6.join(homeDir, ".claude");
1312
+ const claudeMdPath = path6.join(claudeDir, "CLAUDE.md");
1152
1313
  await mkdir3(claudeDir, { recursive: true });
1153
1314
  let existing = "";
1154
1315
  try {
@@ -1173,16 +1334,16 @@ async function injectOrchestrationRules(homeDir) {
1173
1334
  async function installStatusLine(packageRoot, homeDir = os5.homedir()) {
1174
1335
  const prefs = loadPreferences(homeDir);
1175
1336
  if (prefs.ccStatusLine === false) return "opted-out";
1176
- const claudeDir = path5.join(homeDir, ".claude");
1337
+ const claudeDir = path6.join(homeDir, ".claude");
1177
1338
  await mkdir3(claudeDir, { recursive: true });
1178
- const assetPath = path5.join(packageRoot, "dist", "assets", "statusline-command.sh");
1179
- if (!existsSync5(assetPath)) return "asset-missing";
1180
- const destScript = path5.join(claudeDir, "statusline-command.sh");
1339
+ const assetPath = path6.join(packageRoot, "dist", "assets", "statusline-command.sh");
1340
+ if (!existsSync6(assetPath)) return "asset-missing";
1341
+ const destScript = path6.join(claudeDir, "statusline-command.sh");
1181
1342
  const assetContent = await readFile3(assetPath, "utf-8");
1182
1343
  await writeFile3(destScript, assetContent, { mode: 493 });
1183
- const settingsPath = path5.join(claudeDir, "settings.json");
1344
+ const settingsPath = path6.join(claudeDir, "settings.json");
1184
1345
  let settings = {};
1185
- if (existsSync5(settingsPath)) {
1346
+ if (existsSync6(settingsPath)) {
1186
1347
  try {
1187
1348
  settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1188
1349
  } catch {
@@ -1220,12 +1381,12 @@ async function runInstaller(homeDir) {
1220
1381
  `
1221
1382
  );
1222
1383
  const resolvedHome = homeDir ?? os5.homedir();
1223
- const exeWorkspace = path5.join(resolvedHome, "exe");
1224
- if (!existsSync5(exeWorkspace)) {
1384
+ const exeWorkspace = path6.join(resolvedHome, "exe");
1385
+ if (!existsSync6(exeWorkspace)) {
1225
1386
  try {
1226
- await mkdir3(path5.join(exeWorkspace, "content"), { recursive: true });
1227
- await mkdir3(path5.join(exeWorkspace, "operations"), { recursive: true });
1228
- await mkdir3(path5.join(exeWorkspace, "output"), { recursive: true });
1387
+ await mkdir3(path6.join(exeWorkspace, "content"), { recursive: true });
1388
+ await mkdir3(path6.join(exeWorkspace, "operations"), { recursive: true });
1389
+ await mkdir3(path6.join(exeWorkspace, "output"), { recursive: true });
1229
1390
  process.stderr.write(
1230
1391
  `Created ~/exe/ \u2014 your automation workspace for non-code projects
1231
1392
  `
@@ -1261,33 +1422,33 @@ exe-os installed successfully.
1261
1422
  }
1262
1423
  function setupTmux(home) {
1263
1424
  const homeDir = home ?? os5.homedir();
1264
- const exeDir = path5.join(homeDir, ".exe-os");
1265
- const exeTmuxConf = path5.join(exeDir, "tmux.conf");
1266
- const userTmuxConf = path5.join(homeDir, ".tmux.conf");
1267
- const backupPath = path5.join(homeDir, ".tmux.conf.backup");
1425
+ const exeDir = path6.join(homeDir, ".exe-os");
1426
+ const exeTmuxConf = path6.join(exeDir, "tmux.conf");
1427
+ const userTmuxConf = path6.join(homeDir, ".tmux.conf");
1428
+ const backupPath = path6.join(homeDir, ".tmux.conf.backup");
1268
1429
  const sourceLine = "source-file ~/.exe-os/tmux.conf";
1269
1430
  const pkgRoot = resolvePackageRoot();
1270
- const assetPath = path5.join(pkgRoot, "dist", "assets", "tmux.conf");
1271
- if (!existsSync5(assetPath)) {
1431
+ const assetPath = path6.join(pkgRoot, "dist", "assets", "tmux.conf");
1432
+ if (!existsSync6(assetPath)) {
1272
1433
  process.stderr.write(`exe-os: tmux.conf asset not found at ${assetPath} \u2014 skipping tmux setup
1273
1434
  `);
1274
1435
  return;
1275
1436
  }
1276
- mkdirSync3(exeDir, { recursive: true });
1437
+ mkdirSync4(exeDir, { recursive: true });
1277
1438
  copyFileSync(assetPath, exeTmuxConf);
1278
- if (existsSync5(userTmuxConf)) {
1279
- const existing = readFileSync4(userTmuxConf, "utf8");
1439
+ if (existsSync6(userTmuxConf)) {
1440
+ const existing = readFileSync5(userTmuxConf, "utf8");
1280
1441
  if (!existing.includes(sourceLine)) {
1281
- if (!existsSync5(backupPath)) {
1442
+ if (!existsSync6(backupPath)) {
1282
1443
  copyFileSync(userTmuxConf, backupPath);
1283
1444
  process.stderr.write(`exe-os: backed up existing tmux config to ${backupPath}
1284
1445
  `);
1285
1446
  }
1286
- writeFileSync3(userTmuxConf, `${sourceLine}
1447
+ writeFileSync4(userTmuxConf, `${sourceLine}
1287
1448
  ${existing}`);
1288
1449
  }
1289
1450
  } else {
1290
- writeFileSync3(userTmuxConf, `# Exe OS tmux defaults \u2014 remove this line to use your own config
1451
+ writeFileSync4(userTmuxConf, `# Exe OS tmux defaults \u2014 remove this line to use your own config
1291
1452
  ${sourceLine}
1292
1453
  `);
1293
1454
  }
@@ -1299,9 +1460,9 @@ ${sourceLine}
1299
1460
  }
1300
1461
  function setupGhostty(home) {
1301
1462
  const homeDir = home ?? os5.homedir();
1302
- const xdgConfig = path5.join(homeDir, ".config", "ghostty");
1303
- const macConfig = path5.join(homeDir, "Library", "Application Support", "com.mitchellh.ghostty");
1304
- const ghosttyInstalled = existsSync5(xdgConfig) || existsSync5(macConfig) || (() => {
1463
+ const xdgConfig = path6.join(homeDir, ".config", "ghostty");
1464
+ const macConfig = path6.join(homeDir, "Library", "Application Support", "com.mitchellh.ghostty");
1465
+ const ghosttyInstalled = existsSync6(xdgConfig) || existsSync6(macConfig) || (() => {
1305
1466
  try {
1306
1467
  execSync2("which ghostty 2>/dev/null");
1307
1468
  return true;
@@ -1313,47 +1474,47 @@ function setupGhostty(home) {
1313
1474
  return;
1314
1475
  }
1315
1476
  const pkgRoot = resolvePackageRoot();
1316
- const assetPath = path5.join(pkgRoot, "dist", "assets", "ghostty.conf");
1317
- if (!existsSync5(assetPath)) {
1477
+ const assetPath = path6.join(pkgRoot, "dist", "assets", "ghostty.conf");
1478
+ if (!existsSync6(assetPath)) {
1318
1479
  process.stderr.write("exe-os: ghostty.conf asset not found \u2014 skipping Ghostty setup\n");
1319
1480
  return;
1320
1481
  }
1321
1482
  const configDir = xdgConfig;
1322
- const configPath = path5.join(configDir, "config");
1323
- const backupPath = path5.join(configDir, "config.backup");
1324
- mkdirSync3(configDir, { recursive: true });
1483
+ const configPath = path6.join(configDir, "config");
1484
+ const backupPath = path6.join(configDir, "config.backup");
1485
+ mkdirSync4(configDir, { recursive: true });
1325
1486
  const START_MARKER = "# \u2500\u2500 exe-os:ghostty-start \u2500\u2500";
1326
1487
  const END_MARKER = "# \u2500\u2500 exe-os:ghostty-end \u2500\u2500";
1327
- const assetContent = readFileSync4(assetPath, "utf8").trim();
1488
+ const assetContent = readFileSync5(assetPath, "utf8").trim();
1328
1489
  const markedSection = `${START_MARKER}
1329
1490
  ${assetContent}
1330
1491
  ${END_MARKER}`;
1331
- if (existsSync5(configPath)) {
1332
- const existing = readFileSync4(configPath, "utf8");
1492
+ if (existsSync6(configPath)) {
1493
+ const existing = readFileSync5(configPath, "utf8");
1333
1494
  if (existing.includes(START_MARKER) && existing.includes(END_MARKER)) {
1334
1495
  const before = existing.slice(0, existing.indexOf(START_MARKER));
1335
1496
  const after = existing.slice(existing.indexOf(END_MARKER) + END_MARKER.length);
1336
- writeFileSync3(configPath, `${before}${markedSection}${after}`);
1497
+ writeFileSync4(configPath, `${before}${markedSection}${after}`);
1337
1498
  } else if (existing.includes("Exe OS")) {
1338
- if (!existsSync5(backupPath)) {
1499
+ if (!existsSync6(backupPath)) {
1339
1500
  copyFileSync(configPath, backupPath);
1340
1501
  process.stderr.write(`exe-os: backed up existing Ghostty config to ${backupPath}
1341
1502
  `);
1342
1503
  }
1343
- writeFileSync3(configPath, `${markedSection}
1504
+ writeFileSync4(configPath, `${markedSection}
1344
1505
  `);
1345
1506
  } else {
1346
- if (!existsSync5(backupPath)) {
1507
+ if (!existsSync6(backupPath)) {
1347
1508
  copyFileSync(configPath, backupPath);
1348
1509
  process.stderr.write(`exe-os: backed up existing Ghostty config to ${backupPath}
1349
1510
  `);
1350
1511
  }
1351
- writeFileSync3(configPath, `${markedSection}
1512
+ writeFileSync4(configPath, `${markedSection}
1352
1513
 
1353
1514
  ${existing}`);
1354
1515
  }
1355
1516
  } else {
1356
- writeFileSync3(configPath, `${markedSection}
1517
+ writeFileSync4(configPath, `${markedSection}
1357
1518
  `);
1358
1519
  }
1359
1520
  process.stderr.write("exe-os: Ghostty config installed\n");
@@ -1403,14 +1564,14 @@ __export(keychain_exports, {
1403
1564
  setMasterKey: () => setMasterKey
1404
1565
  });
1405
1566
  import { readFile as readFile4, writeFile as writeFile4, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
1406
- import { existsSync as existsSync6 } from "fs";
1407
- import path6 from "path";
1567
+ import { existsSync as existsSync7 } from "fs";
1568
+ import path7 from "path";
1408
1569
  import os6 from "os";
1409
1570
  function getKeyDir() {
1410
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path6.join(os6.homedir(), ".exe-os");
1571
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path7.join(os6.homedir(), ".exe-os");
1411
1572
  }
1412
1573
  function getKeyPath() {
1413
- return path6.join(getKeyDir(), "master.key");
1574
+ return path7.join(getKeyDir(), "master.key");
1414
1575
  }
1415
1576
  async function tryKeytar() {
1416
1577
  try {
@@ -1431,7 +1592,7 @@ async function getMasterKey() {
1431
1592
  }
1432
1593
  }
1433
1594
  const keyPath = getKeyPath();
1434
- if (!existsSync6(keyPath)) {
1595
+ if (!existsSync7(keyPath)) {
1435
1596
  process.stderr.write(
1436
1597
  `[keychain] Key not found at ${keyPath} (HOME=${os6.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
1437
1598
  `
@@ -1474,7 +1635,7 @@ async function deleteMasterKey() {
1474
1635
  }
1475
1636
  }
1476
1637
  const keyPath = getKeyPath();
1477
- if (existsSync6(keyPath)) {
1638
+ if (existsSync7(keyPath)) {
1478
1639
  await unlink(keyPath);
1479
1640
  }
1480
1641
  }
@@ -1618,13 +1779,597 @@ var init_db_retry = __esm({
1618
1779
  }
1619
1780
  });
1620
1781
 
1782
+ // src/lib/database-adapter.ts
1783
+ import os7 from "os";
1784
+ import path8 from "path";
1785
+ import { createRequire } from "module";
1786
+ import { pathToFileURL } from "url";
1787
+ function quotedIdentifier(identifier) {
1788
+ return `"${identifier.replace(/"/g, '""')}"`;
1789
+ }
1790
+ function unqualifiedTableName(name) {
1791
+ const raw = name.trim().replace(/^"|"$/g, "");
1792
+ const parts = raw.split(".");
1793
+ return parts[parts.length - 1].replace(/^"|"$/g, "").toLowerCase();
1794
+ }
1795
+ function stripTrailingSemicolon(sql) {
1796
+ return sql.trim().replace(/;+\s*$/u, "");
1797
+ }
1798
+ function appendClause(sql, clause) {
1799
+ const trimmed = stripTrailingSemicolon(sql);
1800
+ const returningMatch = /\sRETURNING\b[\s\S]*$/iu.exec(trimmed);
1801
+ if (!returningMatch) {
1802
+ return `${trimmed}${clause}`;
1803
+ }
1804
+ const idx = returningMatch.index;
1805
+ return `${trimmed.slice(0, idx)}${clause}${trimmed.slice(idx)}`;
1806
+ }
1807
+ function normalizeStatement(stmt) {
1808
+ if (typeof stmt === "string") {
1809
+ return { kind: "positional", sql: stmt, args: [] };
1810
+ }
1811
+ const sql = stmt.sql;
1812
+ if (Array.isArray(stmt.args) || stmt.args === void 0) {
1813
+ return { kind: "positional", sql, args: stmt.args ?? [] };
1814
+ }
1815
+ return { kind: "named", sql, args: stmt.args };
1816
+ }
1817
+ function rewriteBooleanLiterals(sql) {
1818
+ let out = sql;
1819
+ for (const column of BOOLEAN_COLUMN_NAMES) {
1820
+ const scoped = `((?:\\b[a-z_][a-z0-9_]*\\.)?${column})`;
1821
+ out = out.replace(new RegExp(`${scoped}\\s*=\\s*0\\b`, "giu"), "$1 = FALSE");
1822
+ out = out.replace(new RegExp(`${scoped}\\s*=\\s*1\\b`, "giu"), "$1 = TRUE");
1823
+ out = out.replace(new RegExp(`${scoped}\\s*!=\\s*0\\b`, "giu"), "$1 != FALSE");
1824
+ out = out.replace(new RegExp(`${scoped}\\s*!=\\s*1\\b`, "giu"), "$1 != TRUE");
1825
+ out = out.replace(new RegExp(`${scoped}\\s*<>\\s*0\\b`, "giu"), "$1 <> FALSE");
1826
+ out = out.replace(new RegExp(`${scoped}\\s*<>\\s*1\\b`, "giu"), "$1 <> TRUE");
1827
+ }
1828
+ return out;
1829
+ }
1830
+ function rewriteInsertOrIgnore(sql) {
1831
+ if (!/^\s*INSERT\s+OR\s+IGNORE\s+INTO\b/iu.test(sql)) {
1832
+ return sql;
1833
+ }
1834
+ const replaced = sql.replace(/^\s*INSERT\s+OR\s+IGNORE\s+INTO\b/iu, "INSERT INTO");
1835
+ return /\bON\s+CONFLICT\b/iu.test(replaced) ? replaced : appendClause(replaced, " ON CONFLICT DO NOTHING");
1836
+ }
1837
+ function rewriteInsertOrReplace(sql) {
1838
+ const match = /^\s*INSERT\s+OR\s+REPLACE\s+INTO\s+([A-Za-z0-9_."]+)\s*\(([^)]+)\)([\s\S]*)$/iu.exec(sql);
1839
+ if (!match) {
1840
+ return sql;
1841
+ }
1842
+ const rawTable = match[1];
1843
+ const rawColumns = match[2];
1844
+ const remainder = match[3];
1845
+ const tableName = unqualifiedTableName(rawTable);
1846
+ const conflictKeys = UPSERT_KEYS[tableName];
1847
+ if (!conflictKeys?.length) {
1848
+ return sql;
1849
+ }
1850
+ const columns = rawColumns.split(",").map((col) => col.trim().replace(/^"|"$/g, ""));
1851
+ const updateColumns = columns.filter((col) => !conflictKeys.includes(col));
1852
+ const conflictTarget = conflictKeys.map(quotedIdentifier).join(", ");
1853
+ const updateClause = updateColumns.length === 0 ? " DO NOTHING" : ` DO UPDATE SET ${updateColumns.map((col) => `${quotedIdentifier(col)} = EXCLUDED.${quotedIdentifier(col)}`).join(", ")}`;
1854
+ return `INSERT INTO ${rawTable} (${rawColumns})${appendClause(remainder, ` ON CONFLICT (${conflictTarget})${updateClause}`)}`;
1855
+ }
1856
+ function rewriteSql(sql) {
1857
+ let out = sql;
1858
+ out = out.replace(/\bdatetime\(\s*['"]now['"]\s*\)/giu, "CURRENT_TIMESTAMP");
1859
+ out = out.replace(/\bvector32\s*\(\s*\?\s*\)/giu, "?");
1860
+ out = rewriteBooleanLiterals(out);
1861
+ out = rewriteInsertOrReplace(out);
1862
+ out = rewriteInsertOrIgnore(out);
1863
+ return stripTrailingSemicolon(out);
1864
+ }
1865
+ function toBoolean(value) {
1866
+ if (value === null || value === void 0) return value;
1867
+ if (typeof value === "boolean") return value;
1868
+ if (typeof value === "number") return value !== 0;
1869
+ if (typeof value === "bigint") return value !== 0n;
1870
+ if (typeof value === "string") {
1871
+ const normalized = value.trim().toLowerCase();
1872
+ if (normalized === "0" || normalized === "false") return false;
1873
+ if (normalized === "1" || normalized === "true") return true;
1874
+ }
1875
+ return Boolean(value);
1876
+ }
1877
+ function countQuestionMarks(sql, end) {
1878
+ let count = 0;
1879
+ let inSingle = false;
1880
+ let inDouble = false;
1881
+ let inLineComment = false;
1882
+ let inBlockComment = false;
1883
+ for (let i = 0; i < end; i++) {
1884
+ const ch = sql[i];
1885
+ const next = sql[i + 1];
1886
+ if (inLineComment) {
1887
+ if (ch === "\n") inLineComment = false;
1888
+ continue;
1889
+ }
1890
+ if (inBlockComment) {
1891
+ if (ch === "*" && next === "/") {
1892
+ inBlockComment = false;
1893
+ i += 1;
1894
+ }
1895
+ continue;
1896
+ }
1897
+ if (!inSingle && !inDouble && ch === "-" && next === "-") {
1898
+ inLineComment = true;
1899
+ i += 1;
1900
+ continue;
1901
+ }
1902
+ if (!inSingle && !inDouble && ch === "/" && next === "*") {
1903
+ inBlockComment = true;
1904
+ i += 1;
1905
+ continue;
1906
+ }
1907
+ if (!inDouble && ch === "'" && sql[i - 1] !== "\\") {
1908
+ inSingle = !inSingle;
1909
+ continue;
1910
+ }
1911
+ if (!inSingle && ch === '"' && sql[i - 1] !== "\\") {
1912
+ inDouble = !inDouble;
1913
+ continue;
1914
+ }
1915
+ if (!inSingle && !inDouble && ch === "?") {
1916
+ count += 1;
1917
+ }
1918
+ }
1919
+ return count;
1920
+ }
1921
+ function findBooleanPlaceholderIndexes(sql) {
1922
+ const indexes = /* @__PURE__ */ new Set();
1923
+ for (const column of BOOLEAN_COLUMN_NAMES) {
1924
+ const pattern = new RegExp(`(?:\\b[a-z_][a-z0-9_]*\\.)?${column}\\s*=\\s*\\?`, "giu");
1925
+ for (const match of sql.matchAll(pattern)) {
1926
+ const matchText = match[0];
1927
+ const qIndex = match.index + matchText.lastIndexOf("?");
1928
+ indexes.add(countQuestionMarks(sql, qIndex + 1));
1929
+ }
1930
+ }
1931
+ return indexes;
1932
+ }
1933
+ function coerceInsertBooleanArgs(sql, args2) {
1934
+ const match = /^\s*INSERT(?:\s+OR\s+(?:IGNORE|REPLACE))?\s+INTO\s+([A-Za-z0-9_."]+)\s*\(([^)]+)\)/iu.exec(sql);
1935
+ if (!match) return;
1936
+ const rawTable = match[1];
1937
+ const rawColumns = match[2];
1938
+ const boolColumns = BOOLEAN_COLUMNS_BY_TABLE[unqualifiedTableName(rawTable)];
1939
+ if (!boolColumns?.size) return;
1940
+ const columns = rawColumns.split(",").map((col) => col.trim().replace(/^"|"$/g, ""));
1941
+ for (const [index, column] of columns.entries()) {
1942
+ if (boolColumns.has(column) && index < args2.length) {
1943
+ args2[index] = toBoolean(args2[index]);
1944
+ }
1945
+ }
1946
+ }
1947
+ function coerceUpdateBooleanArgs(sql, args2) {
1948
+ const match = /^\s*UPDATE\s+([A-Za-z0-9_."]+)\s+SET\s+([\s\S]+?)(?:\s+WHERE\b|$)/iu.exec(sql);
1949
+ if (!match) return;
1950
+ const rawTable = match[1];
1951
+ const setClause = match[2];
1952
+ const boolColumns = BOOLEAN_COLUMNS_BY_TABLE[unqualifiedTableName(rawTable)];
1953
+ if (!boolColumns?.size) return;
1954
+ const assignments = setClause.split(",");
1955
+ let placeholderIndex = 0;
1956
+ for (const assignment of assignments) {
1957
+ if (!assignment.includes("?")) continue;
1958
+ placeholderIndex += 1;
1959
+ const colMatch = /^\s*(?:[A-Za-z_][A-Za-z0-9_]*\.)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*\?/iu.exec(assignment);
1960
+ if (colMatch && boolColumns.has(colMatch[1])) {
1961
+ args2[placeholderIndex - 1] = toBoolean(args2[placeholderIndex - 1]);
1962
+ }
1963
+ }
1964
+ }
1965
+ function coerceBooleanArgs(sql, args2) {
1966
+ const nextArgs = [...args2];
1967
+ coerceInsertBooleanArgs(sql, nextArgs);
1968
+ coerceUpdateBooleanArgs(sql, nextArgs);
1969
+ const placeholderIndexes = findBooleanPlaceholderIndexes(sql);
1970
+ for (const index of placeholderIndexes) {
1971
+ if (index > 0 && index <= nextArgs.length) {
1972
+ nextArgs[index - 1] = toBoolean(nextArgs[index - 1]);
1973
+ }
1974
+ }
1975
+ return nextArgs;
1976
+ }
1977
+ function convertQuestionMarksToDollarParams(sql) {
1978
+ let out = "";
1979
+ let placeholder = 0;
1980
+ let inSingle = false;
1981
+ let inDouble = false;
1982
+ let inLineComment = false;
1983
+ let inBlockComment = false;
1984
+ for (let i = 0; i < sql.length; i++) {
1985
+ const ch = sql[i];
1986
+ const next = sql[i + 1];
1987
+ if (inLineComment) {
1988
+ out += ch;
1989
+ if (ch === "\n") inLineComment = false;
1990
+ continue;
1991
+ }
1992
+ if (inBlockComment) {
1993
+ out += ch;
1994
+ if (ch === "*" && next === "/") {
1995
+ out += next;
1996
+ inBlockComment = false;
1997
+ i += 1;
1998
+ }
1999
+ continue;
2000
+ }
2001
+ if (!inSingle && !inDouble && ch === "-" && next === "-") {
2002
+ out += ch + next;
2003
+ inLineComment = true;
2004
+ i += 1;
2005
+ continue;
2006
+ }
2007
+ if (!inSingle && !inDouble && ch === "/" && next === "*") {
2008
+ out += ch + next;
2009
+ inBlockComment = true;
2010
+ i += 1;
2011
+ continue;
2012
+ }
2013
+ if (!inDouble && ch === "'" && sql[i - 1] !== "\\") {
2014
+ inSingle = !inSingle;
2015
+ out += ch;
2016
+ continue;
2017
+ }
2018
+ if (!inSingle && ch === '"' && sql[i - 1] !== "\\") {
2019
+ inDouble = !inDouble;
2020
+ out += ch;
2021
+ continue;
2022
+ }
2023
+ if (!inSingle && !inDouble && ch === "?") {
2024
+ placeholder += 1;
2025
+ out += `$${placeholder}`;
2026
+ continue;
2027
+ }
2028
+ out += ch;
2029
+ }
2030
+ return out;
2031
+ }
2032
+ function translateStatementForPostgres(stmt) {
2033
+ const normalized = normalizeStatement(stmt);
2034
+ if (normalized.kind === "named") {
2035
+ throw new Error("Named SQL parameters are not supported by the Prisma adapter.");
2036
+ }
2037
+ const rewrittenSql = rewriteSql(normalized.sql);
2038
+ const coercedArgs = coerceBooleanArgs(rewrittenSql, normalized.args);
2039
+ return {
2040
+ sql: convertQuestionMarksToDollarParams(rewrittenSql),
2041
+ args: coercedArgs
2042
+ };
2043
+ }
2044
+ function shouldBypassPostgres(stmt) {
2045
+ const normalized = normalizeStatement(stmt);
2046
+ if (normalized.kind === "named") {
2047
+ return true;
2048
+ }
2049
+ return IMMEDIATE_FALLBACK_PATTERNS.some((pattern) => pattern.test(normalized.sql));
2050
+ }
2051
+ function shouldFallbackOnError(error) {
2052
+ const message = error instanceof Error ? error.message : String(error);
2053
+ return /42P01|42883|42601|does not exist|syntax error|not supported|Named SQL parameters are not supported/iu.test(message);
2054
+ }
2055
+ function isReadQuery(sql) {
2056
+ const trimmed = sql.trimStart();
2057
+ return /^(SELECT|WITH|SHOW|EXPLAIN|VALUES)\b/iu.test(trimmed) || /\bRETURNING\b/iu.test(trimmed);
2058
+ }
2059
+ function buildRow(row, columns) {
2060
+ const values = columns.map((column) => row[column]);
2061
+ return Object.assign(values, row);
2062
+ }
2063
+ function buildResultSet(rows, rowsAffected = 0) {
2064
+ const columns = rows[0] ? Object.keys(rows[0]) : [];
2065
+ const resultRows = rows.map((row) => buildRow(row, columns));
2066
+ return {
2067
+ columns,
2068
+ columnTypes: columns.map(() => ""),
2069
+ rows: resultRows,
2070
+ rowsAffected,
2071
+ lastInsertRowid: void 0,
2072
+ toJSON() {
2073
+ return {
2074
+ columns,
2075
+ columnTypes: columns.map(() => ""),
2076
+ rows,
2077
+ rowsAffected,
2078
+ lastInsertRowid: void 0
2079
+ };
2080
+ }
2081
+ };
2082
+ }
2083
+ async function loadPrismaClient() {
2084
+ if (!prismaClientPromise) {
2085
+ prismaClientPromise = (async () => {
2086
+ const explicitPath = process.env.EXE_OS_PRISMA_CLIENT_PATH;
2087
+ if (explicitPath) {
2088
+ const module2 = await import(pathToFileURL(explicitPath).href);
2089
+ const PrismaClient2 = module2.PrismaClient ?? module2.default?.PrismaClient;
2090
+ if (!PrismaClient2) {
2091
+ throw new Error(`No PrismaClient export found at ${explicitPath}`);
2092
+ }
2093
+ return new PrismaClient2();
2094
+ }
2095
+ const exeDbRoot = process.env.EXE_DB_ROOT ?? path8.join(os7.homedir(), "exe-db");
2096
+ const requireFromExeDb = createRequire(path8.join(exeDbRoot, "package.json"));
2097
+ const prismaEntry = requireFromExeDb.resolve("@prisma/client");
2098
+ const module = await import(pathToFileURL(prismaEntry).href);
2099
+ const PrismaClient = module.PrismaClient ?? module.default?.PrismaClient;
2100
+ if (!PrismaClient) {
2101
+ throw new Error(`No PrismaClient export found in ${prismaEntry}`);
2102
+ }
2103
+ return new PrismaClient();
2104
+ })();
2105
+ }
2106
+ return prismaClientPromise;
2107
+ }
2108
+ async function ensureCompatibilityViews(prisma) {
2109
+ if (!compatibilityBootstrapPromise) {
2110
+ compatibilityBootstrapPromise = (async () => {
2111
+ for (const mapping of VIEW_MAPPINGS) {
2112
+ const relation = mapping.source.replace(/"/g, "");
2113
+ const rows = await prisma.$queryRawUnsafe(
2114
+ "SELECT to_regclass($1) AS regclass",
2115
+ relation
2116
+ );
2117
+ if (!rows[0]?.regclass) {
2118
+ continue;
2119
+ }
2120
+ await prisma.$executeRawUnsafe(
2121
+ `CREATE OR REPLACE VIEW public.${quotedIdentifier(mapping.view)} AS SELECT * FROM ${mapping.source}`
2122
+ );
2123
+ }
2124
+ })();
2125
+ }
2126
+ return compatibilityBootstrapPromise;
2127
+ }
2128
+ async function executeOnPrisma(executor, stmt) {
2129
+ const translated = translateStatementForPostgres(stmt);
2130
+ if (isReadQuery(translated.sql)) {
2131
+ const rows = await executor.$queryRawUnsafe(
2132
+ translated.sql,
2133
+ ...translated.args
2134
+ );
2135
+ return buildResultSet(rows, /\bRETURNING\b/iu.test(translated.sql) ? rows.length : 0);
2136
+ }
2137
+ const rowsAffected = await executor.$executeRawUnsafe(translated.sql, ...translated.args);
2138
+ return buildResultSet([], rowsAffected);
2139
+ }
2140
+ function splitSqlStatements(sql) {
2141
+ const parts = [];
2142
+ let current = "";
2143
+ let inSingle = false;
2144
+ let inDouble = false;
2145
+ let inLineComment = false;
2146
+ let inBlockComment = false;
2147
+ for (let i = 0; i < sql.length; i++) {
2148
+ const ch = sql[i];
2149
+ const next = sql[i + 1];
2150
+ if (inLineComment) {
2151
+ current += ch;
2152
+ if (ch === "\n") inLineComment = false;
2153
+ continue;
2154
+ }
2155
+ if (inBlockComment) {
2156
+ current += ch;
2157
+ if (ch === "*" && next === "/") {
2158
+ current += next;
2159
+ inBlockComment = false;
2160
+ i += 1;
2161
+ }
2162
+ continue;
2163
+ }
2164
+ if (!inSingle && !inDouble && ch === "-" && next === "-") {
2165
+ current += ch + next;
2166
+ inLineComment = true;
2167
+ i += 1;
2168
+ continue;
2169
+ }
2170
+ if (!inSingle && !inDouble && ch === "/" && next === "*") {
2171
+ current += ch + next;
2172
+ inBlockComment = true;
2173
+ i += 1;
2174
+ continue;
2175
+ }
2176
+ if (!inDouble && ch === "'" && sql[i - 1] !== "\\") {
2177
+ inSingle = !inSingle;
2178
+ current += ch;
2179
+ continue;
2180
+ }
2181
+ if (!inSingle && ch === '"' && sql[i - 1] !== "\\") {
2182
+ inDouble = !inDouble;
2183
+ current += ch;
2184
+ continue;
2185
+ }
2186
+ if (!inSingle && !inDouble && ch === ";") {
2187
+ if (current.trim()) {
2188
+ parts.push(current.trim());
2189
+ }
2190
+ current = "";
2191
+ continue;
2192
+ }
2193
+ current += ch;
2194
+ }
2195
+ if (current.trim()) {
2196
+ parts.push(current.trim());
2197
+ }
2198
+ return parts;
2199
+ }
2200
+ async function createPrismaDbAdapter(fallbackClient) {
2201
+ const prisma = await loadPrismaClient();
2202
+ await ensureCompatibilityViews(prisma);
2203
+ let closed = false;
2204
+ let adapter;
2205
+ const fallbackExecute = async (stmt, error) => {
2206
+ if (!fallbackClient) {
2207
+ if (error) throw error;
2208
+ throw new Error("No fallback SQLite client is available for this Prisma-routed query.");
2209
+ }
2210
+ if (error) {
2211
+ process.stderr.write(
2212
+ `[database-adapter] Falling back to SQLite: ${error instanceof Error ? error.message : String(error)}
2213
+ `
2214
+ );
2215
+ }
2216
+ return fallbackClient.execute(stmt);
2217
+ };
2218
+ adapter = {
2219
+ async execute(stmt) {
2220
+ if (shouldBypassPostgres(stmt)) {
2221
+ return fallbackExecute(stmt);
2222
+ }
2223
+ try {
2224
+ return await executeOnPrisma(prisma, stmt);
2225
+ } catch (error) {
2226
+ if (shouldFallbackOnError(error)) {
2227
+ return fallbackExecute(stmt, error);
2228
+ }
2229
+ throw error;
2230
+ }
2231
+ },
2232
+ async batch(stmts, mode) {
2233
+ if (stmts.some((stmt) => shouldBypassPostgres(stmt))) {
2234
+ if (!fallbackClient) {
2235
+ throw new Error("Cannot batch unsupported SQLite-only statements without a fallback client.");
2236
+ }
2237
+ return fallbackClient.batch(stmts, mode);
2238
+ }
2239
+ try {
2240
+ if (prisma.$transaction) {
2241
+ return await prisma.$transaction(async (tx) => {
2242
+ const results2 = [];
2243
+ for (const stmt of stmts) {
2244
+ results2.push(await executeOnPrisma(tx, stmt));
2245
+ }
2246
+ return results2;
2247
+ });
2248
+ }
2249
+ const results = [];
2250
+ for (const stmt of stmts) {
2251
+ results.push(await executeOnPrisma(prisma, stmt));
2252
+ }
2253
+ return results;
2254
+ } catch (error) {
2255
+ if (fallbackClient && shouldFallbackOnError(error)) {
2256
+ process.stderr.write(
2257
+ `[database-adapter] Falling back batch to SQLite: ${error instanceof Error ? error.message : String(error)}
2258
+ `
2259
+ );
2260
+ return fallbackClient.batch(stmts, mode);
2261
+ }
2262
+ throw error;
2263
+ }
2264
+ },
2265
+ async migrate(stmts) {
2266
+ if (fallbackClient) {
2267
+ return fallbackClient.migrate(stmts);
2268
+ }
2269
+ return adapter.batch(stmts, "deferred");
2270
+ },
2271
+ async transaction(mode) {
2272
+ if (!fallbackClient) {
2273
+ throw new Error("Interactive transactions are only supported on the SQLite fallback client.");
2274
+ }
2275
+ return fallbackClient.transaction(mode);
2276
+ },
2277
+ async executeMultiple(sql) {
2278
+ if (fallbackClient && shouldBypassPostgres(sql)) {
2279
+ return fallbackClient.executeMultiple(sql);
2280
+ }
2281
+ for (const statement of splitSqlStatements(sql)) {
2282
+ await adapter.execute(statement);
2283
+ }
2284
+ },
2285
+ async sync() {
2286
+ if (fallbackClient) {
2287
+ return fallbackClient.sync();
2288
+ }
2289
+ return { frame_no: 0, frames_synced: 0 };
2290
+ },
2291
+ close() {
2292
+ closed = true;
2293
+ prismaClientPromise = null;
2294
+ compatibilityBootstrapPromise = null;
2295
+ void prisma.$disconnect?.();
2296
+ },
2297
+ get closed() {
2298
+ return closed;
2299
+ },
2300
+ get protocol() {
2301
+ return "prisma-postgres";
2302
+ }
2303
+ };
2304
+ return adapter;
2305
+ }
2306
+ var VIEW_MAPPINGS, UPSERT_KEYS, BOOLEAN_COLUMNS_BY_TABLE, BOOLEAN_COLUMN_NAMES, IMMEDIATE_FALLBACK_PATTERNS, prismaClientPromise, compatibilityBootstrapPromise;
2307
+ var init_database_adapter = __esm({
2308
+ "src/lib/database-adapter.ts"() {
2309
+ "use strict";
2310
+ VIEW_MAPPINGS = [
2311
+ { view: "memories", source: "memory.memory_records" },
2312
+ { view: "tasks", source: "memory.tasks" },
2313
+ { view: "behaviors", source: "memory.behaviors" },
2314
+ { view: "entities", source: "memory.entities" },
2315
+ { view: "relationships", source: "memory.relationships" },
2316
+ { view: "entity_memories", source: "memory.entity_memories" },
2317
+ { view: "entity_aliases", source: "memory.entity_aliases" },
2318
+ { view: "notifications", source: "memory.notifications" },
2319
+ { view: "messages", source: "memory.messages" },
2320
+ { view: "users", source: "wiki.users" },
2321
+ { view: "workspaces", source: "wiki.workspaces" },
2322
+ { view: "workspace_users", source: "wiki.workspace_users" },
2323
+ { view: "documents", source: "wiki.workspace_documents" },
2324
+ { view: "chats", source: "wiki.workspace_chats" }
2325
+ ];
2326
+ UPSERT_KEYS = {
2327
+ memories: ["id"],
2328
+ tasks: ["id"],
2329
+ behaviors: ["id"],
2330
+ entities: ["id"],
2331
+ relationships: ["id"],
2332
+ entity_aliases: ["alias"],
2333
+ notifications: ["id"],
2334
+ messages: ["id"],
2335
+ users: ["id"],
2336
+ workspaces: ["id"],
2337
+ workspace_users: ["id"],
2338
+ documents: ["id"],
2339
+ chats: ["id"]
2340
+ };
2341
+ BOOLEAN_COLUMNS_BY_TABLE = {
2342
+ memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
2343
+ behaviors: /* @__PURE__ */ new Set(["active"]),
2344
+ notifications: /* @__PURE__ */ new Set(["read"]),
2345
+ users: /* @__PURE__ */ new Set(["has_personal_memory"])
2346
+ };
2347
+ BOOLEAN_COLUMN_NAMES = new Set(
2348
+ Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
2349
+ );
2350
+ IMMEDIATE_FALLBACK_PATTERNS = [
2351
+ /\bPRAGMA\b/i,
2352
+ /\bsqlite_master\b/i,
2353
+ /(?:^|[.\s])(?:memories|conversations|entities)_fts\b/i,
2354
+ /\bMATCH\b/i,
2355
+ /\bvector_distance_cos\s*\(/i,
2356
+ /\bjson_extract\s*\(/i,
2357
+ /\bjulianday\s*\(/i,
2358
+ /\bstrftime\s*\(/i,
2359
+ /\blast_insert_rowid\s*\(/i
2360
+ ];
2361
+ prismaClientPromise = null;
2362
+ compatibilityBootstrapPromise = null;
2363
+ }
2364
+ });
2365
+
1621
2366
  // src/lib/exe-daemon-client.ts
1622
2367
  import net from "net";
1623
- import os7 from "os";
2368
+ import os8 from "os";
1624
2369
  import { spawn } from "child_process";
1625
2370
  import { randomUUID } from "crypto";
1626
- import { existsSync as existsSync7, unlinkSync as unlinkSync2, readFileSync as readFileSync5, openSync, closeSync, statSync } from "fs";
1627
- import path7 from "path";
2371
+ import { existsSync as existsSync8, unlinkSync as unlinkSync2, readFileSync as readFileSync6, openSync, closeSync, statSync } from "fs";
2372
+ import path9 from "path";
1628
2373
  import { fileURLToPath as fileURLToPath3 } from "url";
1629
2374
  function handleData(chunk) {
1630
2375
  _buffer += chunk.toString();
@@ -1652,9 +2397,9 @@ function handleData(chunk) {
1652
2397
  }
1653
2398
  }
1654
2399
  function cleanupStaleFiles() {
1655
- if (existsSync7(PID_PATH)) {
2400
+ if (existsSync8(PID_PATH)) {
1656
2401
  try {
1657
- const pid = parseInt(readFileSync5(PID_PATH, "utf8").trim(), 10);
2402
+ const pid = parseInt(readFileSync6(PID_PATH, "utf8").trim(), 10);
1658
2403
  if (pid > 0) {
1659
2404
  try {
1660
2405
  process.kill(pid, 0);
@@ -1675,17 +2420,17 @@ function cleanupStaleFiles() {
1675
2420
  }
1676
2421
  }
1677
2422
  function findPackageRoot() {
1678
- let dir = path7.dirname(fileURLToPath3(import.meta.url));
1679
- const { root } = path7.parse(dir);
2423
+ let dir = path9.dirname(fileURLToPath3(import.meta.url));
2424
+ const { root } = path9.parse(dir);
1680
2425
  while (dir !== root) {
1681
- if (existsSync7(path7.join(dir, "package.json"))) return dir;
1682
- dir = path7.dirname(dir);
2426
+ if (existsSync8(path9.join(dir, "package.json"))) return dir;
2427
+ dir = path9.dirname(dir);
1683
2428
  }
1684
2429
  return null;
1685
2430
  }
1686
2431
  function spawnDaemon() {
1687
- const freeGB = os7.freemem() / (1024 * 1024 * 1024);
1688
- const totalGB = os7.totalmem() / (1024 * 1024 * 1024);
2432
+ const freeGB = os8.freemem() / (1024 * 1024 * 1024);
2433
+ const totalGB = os8.totalmem() / (1024 * 1024 * 1024);
1689
2434
  if (totalGB <= 8) {
1690
2435
  process.stderr.write(
1691
2436
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
@@ -1705,8 +2450,8 @@ function spawnDaemon() {
1705
2450
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
1706
2451
  return;
1707
2452
  }
1708
- const daemonPath = path7.join(pkgRoot, "dist", "lib", "exe-daemon.js");
1709
- if (!existsSync7(daemonPath)) {
2453
+ const daemonPath = path9.join(pkgRoot, "dist", "lib", "exe-daemon.js");
2454
+ if (!existsSync8(daemonPath)) {
1710
2455
  process.stderr.write(`[exed-client] WARN: daemon script not found at ${daemonPath}
1711
2456
  `);
1712
2457
  return;
@@ -1714,7 +2459,7 @@ function spawnDaemon() {
1714
2459
  const resolvedPath = daemonPath;
1715
2460
  process.stderr.write(`[exed-client] Spawning daemon: ${resolvedPath}
1716
2461
  `);
1717
- const logPath = path7.join(path7.dirname(SOCKET_PATH), "exed.log");
2462
+ const logPath = path9.join(path9.dirname(SOCKET_PATH), "exed.log");
1718
2463
  let stderrFd = "ignore";
1719
2464
  try {
1720
2465
  stderrFd = openSync(logPath, "a");
@@ -1865,74 +2610,123 @@ async function pingDaemon() {
1865
2610
  return null;
1866
2611
  }
1867
2612
  function killAndRespawnDaemon() {
1868
- process.stderr.write("[exed-client] Killing daemon for restart...\n");
1869
- if (existsSync7(PID_PATH)) {
1870
- try {
1871
- const pid = parseInt(readFileSync5(PID_PATH, "utf8").trim(), 10);
1872
- if (pid > 0) {
1873
- try {
1874
- process.kill(pid, "SIGKILL");
1875
- } catch {
2613
+ if (!acquireSpawnLock()) {
2614
+ process.stderr.write("[exed-client] Another process is already restarting daemon \u2014 skipping\n");
2615
+ if (_socket) {
2616
+ _socket.destroy();
2617
+ _socket = null;
2618
+ }
2619
+ _connected = false;
2620
+ _buffer = "";
2621
+ return;
2622
+ }
2623
+ try {
2624
+ process.stderr.write("[exed-client] Killing daemon for restart...\n");
2625
+ if (existsSync8(PID_PATH)) {
2626
+ try {
2627
+ const pid = parseInt(readFileSync6(PID_PATH, "utf8").trim(), 10);
2628
+ if (pid > 0) {
2629
+ try {
2630
+ process.kill(pid, "SIGKILL");
2631
+ } catch {
2632
+ }
1876
2633
  }
2634
+ } catch {
1877
2635
  }
2636
+ }
2637
+ if (_socket) {
2638
+ _socket.destroy();
2639
+ _socket = null;
2640
+ }
2641
+ _connected = false;
2642
+ _buffer = "";
2643
+ try {
2644
+ unlinkSync2(PID_PATH);
1878
2645
  } catch {
1879
2646
  }
2647
+ try {
2648
+ unlinkSync2(SOCKET_PATH);
2649
+ } catch {
2650
+ }
2651
+ spawnDaemon();
2652
+ } finally {
2653
+ releaseSpawnLock();
1880
2654
  }
1881
- if (_socket) {
1882
- _socket.destroy();
1883
- _socket = null;
1884
- }
1885
- _connected = false;
1886
- _buffer = "";
2655
+ }
2656
+ function isDaemonTooYoung() {
1887
2657
  try {
1888
- unlinkSync2(PID_PATH);
2658
+ const stat2 = statSync(PID_PATH);
2659
+ return Date.now() - stat2.mtimeMs < MIN_DAEMON_AGE_MS;
1889
2660
  } catch {
2661
+ return false;
1890
2662
  }
1891
- try {
1892
- unlinkSync2(SOCKET_PATH);
1893
- } catch {
2663
+ }
2664
+ async function retryThenRestart(doRequest, label) {
2665
+ const result = await doRequest();
2666
+ if (!result.error) {
2667
+ _consecutiveFailures = 0;
2668
+ return result;
1894
2669
  }
1895
- spawnDaemon();
2670
+ _consecutiveFailures++;
2671
+ for (let i = 0; i < MAX_RETRIES_BEFORE_RESTART; i++) {
2672
+ const delayMs = RETRY_DELAYS_MS[i] ?? 5e3;
2673
+ process.stderr.write(`[exed-client] ${label} failed (${result.error}), retry ${i + 1}/${MAX_RETRIES_BEFORE_RESTART} in ${delayMs}ms
2674
+ `);
2675
+ await new Promise((r) => setTimeout(r, delayMs));
2676
+ if (!_connected) {
2677
+ if (!await connectToSocket()) continue;
2678
+ }
2679
+ const retry = await doRequest();
2680
+ if (!retry.error) {
2681
+ _consecutiveFailures = 0;
2682
+ return retry;
2683
+ }
2684
+ _consecutiveFailures++;
2685
+ }
2686
+ if (isDaemonTooYoung()) {
2687
+ process.stderr.write(`[exed-client] ${label}: daemon too young (< ${MIN_DAEMON_AGE_MS / 1e3}s) \u2014 skipping restart
2688
+ `);
2689
+ return { error: result.error };
2690
+ }
2691
+ process.stderr.write(`[exed-client] ${label}: ${_consecutiveFailures} consecutive failures \u2014 restarting daemon
2692
+ `);
2693
+ killAndRespawnDaemon();
2694
+ const start = Date.now();
2695
+ let delay2 = 200;
2696
+ while (Date.now() - start < CONNECT_TIMEOUT_MS) {
2697
+ await new Promise((r) => setTimeout(r, delay2));
2698
+ if (await connectToSocket()) break;
2699
+ delay2 = Math.min(delay2 * 2, 3e3);
2700
+ }
2701
+ if (!_connected) return { error: "Daemon restart failed" };
2702
+ const final = await doRequest();
2703
+ if (!final.error) _consecutiveFailures = 0;
2704
+ return final;
1896
2705
  }
1897
2706
  async function embedViaClient(text, priority = "high") {
1898
2707
  if (!_connected && !await connectEmbedDaemon()) return null;
1899
2708
  _requestCount++;
1900
2709
  if (_requestCount % HEALTH_CHECK_INTERVAL === 0) {
1901
2710
  const health = await pingDaemon();
1902
- if (!health) {
2711
+ if (!health && !isDaemonTooYoung()) {
1903
2712
  process.stderr.write(`[exed-client] Periodic health check failed at request ${_requestCount} \u2014 restarting daemon
1904
2713
  `);
1905
2714
  killAndRespawnDaemon();
1906
2715
  const start = Date.now();
1907
- let delay2 = 200;
2716
+ let d = 200;
1908
2717
  while (Date.now() - start < CONNECT_TIMEOUT_MS) {
1909
- await new Promise((r) => setTimeout(r, delay2));
2718
+ await new Promise((r) => setTimeout(r, d));
1910
2719
  if (await connectToSocket()) break;
1911
- delay2 = Math.min(delay2 * 2, 3e3);
2720
+ d = Math.min(d * 2, 3e3);
1912
2721
  }
1913
2722
  if (!_connected) return null;
1914
2723
  }
1915
2724
  }
1916
- const result = await sendRequest([text], priority);
1917
- if (!result.error && result.vectors?.[0]) return result.vectors[0];
1918
- if (result.error) {
1919
- process.stderr.write(`[exed-client] Embed failed (${result.error}) \u2014 attempting restart
1920
- `);
1921
- killAndRespawnDaemon();
1922
- const start = Date.now();
1923
- let delay2 = 200;
1924
- while (Date.now() - start < CONNECT_TIMEOUT_MS) {
1925
- await new Promise((r) => setTimeout(r, delay2));
1926
- if (await connectToSocket()) break;
1927
- delay2 = Math.min(delay2 * 2, 3e3);
1928
- }
1929
- if (!_connected) return null;
1930
- const retry = await sendRequest([text], priority);
1931
- if (!retry.error && retry.vectors?.[0]) return retry.vectors[0];
1932
- process.stderr.write(`[exed-client] Embed retry also failed: ${retry.error ?? "no vector"}
1933
- `);
1934
- }
1935
- return null;
2725
+ const result = await retryThenRestart(
2726
+ () => sendRequest([text], priority),
2727
+ "Embed"
2728
+ );
2729
+ return !result.error && result.vectors?.[0] ? result.vectors[0] : null;
1936
2730
  }
1937
2731
  function disconnectClient() {
1938
2732
  if (_socket) {
@@ -1950,14 +2744,14 @@ function disconnectClient() {
1950
2744
  function isClientConnected() {
1951
2745
  return _connected;
1952
2746
  }
1953
- var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, _socket, _connected, _buffer, _requestCount, HEALTH_CHECK_INTERVAL, _pending, MAX_BUFFER;
2747
+ var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, _socket, _connected, _buffer, _requestCount, _consecutiveFailures, HEALTH_CHECK_INTERVAL, MAX_RETRIES_BEFORE_RESTART, RETRY_DELAYS_MS, MIN_DAEMON_AGE_MS, _pending, MAX_BUFFER;
1954
2748
  var init_exe_daemon_client = __esm({
1955
2749
  "src/lib/exe-daemon-client.ts"() {
1956
2750
  "use strict";
1957
2751
  init_config();
1958
- SOCKET_PATH = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path7.join(EXE_AI_DIR, "exed.sock");
1959
- PID_PATH = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path7.join(EXE_AI_DIR, "exed.pid");
1960
- SPAWN_LOCK_PATH = path7.join(EXE_AI_DIR, "exed-spawn.lock");
2752
+ SOCKET_PATH = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path9.join(EXE_AI_DIR, "exed.sock");
2753
+ PID_PATH = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path9.join(EXE_AI_DIR, "exed.pid");
2754
+ SPAWN_LOCK_PATH = path9.join(EXE_AI_DIR, "exed-spawn.lock");
1961
2755
  SPAWN_LOCK_STALE_MS = 3e4;
1962
2756
  CONNECT_TIMEOUT_MS = 15e3;
1963
2757
  REQUEST_TIMEOUT_MS = 3e4;
@@ -1965,7 +2759,11 @@ var init_exe_daemon_client = __esm({
1965
2759
  _connected = false;
1966
2760
  _buffer = "";
1967
2761
  _requestCount = 0;
2762
+ _consecutiveFailures = 0;
1968
2763
  HEALTH_CHECK_INTERVAL = 100;
2764
+ MAX_RETRIES_BEFORE_RESTART = 3;
2765
+ RETRY_DELAYS_MS = [1e3, 3e3, 5e3];
2766
+ MIN_DAEMON_AGE_MS = 3e4;
1969
2767
  _pending = /* @__PURE__ */ new Map();
1970
2768
  MAX_BUFFER = 1e7;
1971
2769
  }
@@ -2041,7 +2839,7 @@ __export(db_daemon_client_exports, {
2041
2839
  createDaemonDbClient: () => createDaemonDbClient,
2042
2840
  initDaemonDbClient: () => initDaemonDbClient
2043
2841
  });
2044
- function normalizeStatement(stmt) {
2842
+ function normalizeStatement2(stmt) {
2045
2843
  if (typeof stmt === "string") {
2046
2844
  return { sql: stmt, args: [] };
2047
2845
  }
@@ -2065,7 +2863,7 @@ function createDaemonDbClient(fallbackClient) {
2065
2863
  if (!_useDaemon || !isClientConnected()) {
2066
2864
  return fallbackClient.execute(stmt);
2067
2865
  }
2068
- const { sql, args: args2 } = normalizeStatement(stmt);
2866
+ const { sql, args: args2 } = normalizeStatement2(stmt);
2069
2867
  const response = await sendDaemonRequest({
2070
2868
  type: "db-execute",
2071
2869
  sql,
@@ -2090,7 +2888,7 @@ function createDaemonDbClient(fallbackClient) {
2090
2888
  if (!_useDaemon || !isClientConnected()) {
2091
2889
  return fallbackClient.batch(stmts, mode);
2092
2890
  }
2093
- const statements = stmts.map(normalizeStatement);
2891
+ const statements = stmts.map(normalizeStatement2);
2094
2892
  const response = await sendDaemonRequest({
2095
2893
  type: "db-batch",
2096
2894
  statements,
@@ -2185,6 +2983,18 @@ __export(database_exports, {
2185
2983
  });
2186
2984
  import { createClient } from "@libsql/client";
2187
2985
  async function initDatabase(config) {
2986
+ if (_walCheckpointTimer) {
2987
+ clearInterval(_walCheckpointTimer);
2988
+ _walCheckpointTimer = null;
2989
+ }
2990
+ if (_daemonClient) {
2991
+ _daemonClient.close();
2992
+ _daemonClient = null;
2993
+ }
2994
+ if (_adapterClient && _adapterClient !== _resilientClient) {
2995
+ _adapterClient.close();
2996
+ }
2997
+ _adapterClient = null;
2188
2998
  if (_client) {
2189
2999
  _client.close();
2190
3000
  _client = null;
@@ -2198,6 +3008,7 @@ async function initDatabase(config) {
2198
3008
  }
2199
3009
  _client = createClient(opts);
2200
3010
  _resilientClient = wrapWithRetry(_client);
3011
+ _adapterClient = _resilientClient;
2201
3012
  _client.execute("PRAGMA busy_timeout = 30000").catch(() => {
2202
3013
  });
2203
3014
  _client.execute("PRAGMA journal_mode = WAL").catch(() => {
@@ -2208,14 +3019,20 @@ async function initDatabase(config) {
2208
3019
  });
2209
3020
  }, 3e4);
2210
3021
  _walCheckpointTimer.unref();
3022
+ if (process.env.DATABASE_URL) {
3023
+ _adapterClient = await createPrismaDbAdapter(_resilientClient);
3024
+ }
2211
3025
  }
2212
3026
  function isInitialized() {
2213
- return _client !== null;
3027
+ return _adapterClient !== null || _client !== null;
2214
3028
  }
2215
3029
  function getClient() {
2216
- if (!_resilientClient) {
3030
+ if (!_adapterClient) {
2217
3031
  throw new Error("Database client not initialized. Call initDatabase() first.");
2218
3032
  }
3033
+ if (process.env.DATABASE_URL) {
3034
+ return _adapterClient;
3035
+ }
2219
3036
  if (process.env.EXE_IS_DAEMON === "1") {
2220
3037
  return _resilientClient;
2221
3038
  }
@@ -2225,6 +3042,7 @@ function getClient() {
2225
3042
  return _resilientClient;
2226
3043
  }
2227
3044
  async function initDaemonClient() {
3045
+ if (process.env.DATABASE_URL) return;
2228
3046
  if (process.env.EXE_IS_DAEMON === "1") return;
2229
3047
  if (!_resilientClient) return;
2230
3048
  try {
@@ -3169,26 +3987,36 @@ async function ensureSchema() {
3169
3987
  }
3170
3988
  }
3171
3989
  async function disposeDatabase() {
3990
+ if (_walCheckpointTimer) {
3991
+ clearInterval(_walCheckpointTimer);
3992
+ _walCheckpointTimer = null;
3993
+ }
3172
3994
  if (_daemonClient) {
3173
3995
  _daemonClient.close();
3174
3996
  _daemonClient = null;
3175
3997
  }
3998
+ if (_adapterClient && _adapterClient !== _resilientClient) {
3999
+ _adapterClient.close();
4000
+ }
4001
+ _adapterClient = null;
3176
4002
  if (_client) {
3177
4003
  _client.close();
3178
4004
  _client = null;
3179
4005
  _resilientClient = null;
3180
4006
  }
3181
4007
  }
3182
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, initTurso, disposeTurso;
4008
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3183
4009
  var init_database = __esm({
3184
4010
  "src/lib/database.ts"() {
3185
4011
  "use strict";
3186
4012
  init_db_retry();
3187
4013
  init_employees();
4014
+ init_database_adapter();
3188
4015
  _client = null;
3189
4016
  _resilientClient = null;
3190
4017
  _walCheckpointTimer = null;
3191
4018
  _daemonClient = null;
4019
+ _adapterClient = null;
3192
4020
  initTurso = initDatabase;
3193
4021
  disposeTurso = disposeDatabase;
3194
4022
  }
@@ -3290,9 +4118,9 @@ __export(license_exports, {
3290
4118
  stopLicenseRevalidation: () => stopLicenseRevalidation,
3291
4119
  validateLicense: () => validateLicense
3292
4120
  });
3293
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
4121
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync9, mkdirSync as mkdirSync5 } from "fs";
3294
4122
  import { randomUUID as randomUUID2 } from "crypto";
3295
- import path8 from "path";
4123
+ import path10 from "path";
3296
4124
  import { jwtVerify, importSPKI } from "jose";
3297
4125
  async function fetchRetry(url, init) {
3298
4126
  try {
@@ -3303,37 +4131,37 @@ async function fetchRetry(url, init) {
3303
4131
  }
3304
4132
  }
3305
4133
  function loadDeviceId() {
3306
- const deviceJsonPath = path8.join(EXE_AI_DIR, "device.json");
4134
+ const deviceJsonPath = path10.join(EXE_AI_DIR, "device.json");
3307
4135
  try {
3308
- if (existsSync8(deviceJsonPath)) {
3309
- const data = JSON.parse(readFileSync6(deviceJsonPath, "utf8"));
4136
+ if (existsSync9(deviceJsonPath)) {
4137
+ const data = JSON.parse(readFileSync7(deviceJsonPath, "utf8"));
3310
4138
  if (data.deviceId) return data.deviceId;
3311
4139
  }
3312
4140
  } catch {
3313
4141
  }
3314
4142
  try {
3315
- if (existsSync8(DEVICE_ID_PATH)) {
3316
- const id2 = readFileSync6(DEVICE_ID_PATH, "utf8").trim();
4143
+ if (existsSync9(DEVICE_ID_PATH)) {
4144
+ const id2 = readFileSync7(DEVICE_ID_PATH, "utf8").trim();
3317
4145
  if (id2) return id2;
3318
4146
  }
3319
4147
  } catch {
3320
4148
  }
3321
4149
  const id = randomUUID2();
3322
- mkdirSync4(EXE_AI_DIR, { recursive: true });
3323
- writeFileSync4(DEVICE_ID_PATH, id, "utf8");
4150
+ mkdirSync5(EXE_AI_DIR, { recursive: true });
4151
+ writeFileSync5(DEVICE_ID_PATH, id, "utf8");
3324
4152
  return id;
3325
4153
  }
3326
4154
  function loadLicense() {
3327
4155
  try {
3328
- if (!existsSync8(LICENSE_PATH)) return null;
3329
- return readFileSync6(LICENSE_PATH, "utf8").trim();
4156
+ if (!existsSync9(LICENSE_PATH)) return null;
4157
+ return readFileSync7(LICENSE_PATH, "utf8").trim();
3330
4158
  } catch {
3331
4159
  return null;
3332
4160
  }
3333
4161
  }
3334
4162
  function saveLicense(apiKey) {
3335
- mkdirSync4(EXE_AI_DIR, { recursive: true });
3336
- writeFileSync4(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
4163
+ mkdirSync5(EXE_AI_DIR, { recursive: true });
4164
+ writeFileSync5(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
3337
4165
  }
3338
4166
  async function verifyLicenseJwt(token) {
3339
4167
  try {
@@ -3359,8 +4187,8 @@ async function verifyLicenseJwt(token) {
3359
4187
  }
3360
4188
  async function getCachedLicense() {
3361
4189
  try {
3362
- if (!existsSync8(CACHE_PATH)) return null;
3363
- const raw = JSON.parse(readFileSync6(CACHE_PATH, "utf8"));
4190
+ if (!existsSync9(CACHE_PATH)) return null;
4191
+ const raw = JSON.parse(readFileSync7(CACHE_PATH, "utf8"));
3364
4192
  if (!raw.token || typeof raw.token !== "string") return null;
3365
4193
  return await verifyLicenseJwt(raw.token);
3366
4194
  } catch {
@@ -3369,8 +4197,8 @@ async function getCachedLicense() {
3369
4197
  }
3370
4198
  function readCachedToken() {
3371
4199
  try {
3372
- if (!existsSync8(CACHE_PATH)) return null;
3373
- const raw = JSON.parse(readFileSync6(CACHE_PATH, "utf8"));
4200
+ if (!existsSync9(CACHE_PATH)) return null;
4201
+ const raw = JSON.parse(readFileSync7(CACHE_PATH, "utf8"));
3374
4202
  return typeof raw.token === "string" ? raw.token : null;
3375
4203
  } catch {
3376
4204
  return null;
@@ -3404,7 +4232,7 @@ function getRawCachedPlan() {
3404
4232
  }
3405
4233
  function cacheResponse(token) {
3406
4234
  try {
3407
- writeFileSync4(CACHE_PATH, JSON.stringify({ token }), "utf8");
4235
+ writeFileSync5(CACHE_PATH, JSON.stringify({ token }), "utf8");
3408
4236
  } catch {
3409
4237
  }
3410
4238
  }
@@ -3468,9 +4296,9 @@ async function checkLicense() {
3468
4296
  let key = loadLicense();
3469
4297
  if (!key) {
3470
4298
  try {
3471
- const configPath = path8.join(EXE_AI_DIR, "config.json");
3472
- if (existsSync8(configPath)) {
3473
- const raw = JSON.parse(readFileSync6(configPath, "utf8"));
4299
+ const configPath = path10.join(EXE_AI_DIR, "config.json");
4300
+ if (existsSync9(configPath)) {
4301
+ const raw = JSON.parse(readFileSync7(configPath, "utf8"));
3474
4302
  const cloud = raw.cloud;
3475
4303
  if (cloud?.apiKey) {
3476
4304
  key = cloud.apiKey;
@@ -3629,9 +4457,9 @@ var init_license = __esm({
3629
4457
  "src/lib/license.ts"() {
3630
4458
  "use strict";
3631
4459
  init_config();
3632
- LICENSE_PATH = path8.join(EXE_AI_DIR, "license.key");
3633
- CACHE_PATH = path8.join(EXE_AI_DIR, "license-cache.json");
3634
- DEVICE_ID_PATH = path8.join(EXE_AI_DIR, "device-id");
4460
+ LICENSE_PATH = path10.join(EXE_AI_DIR, "license.key");
4461
+ CACHE_PATH = path10.join(EXE_AI_DIR, "license-cache.json");
4462
+ DEVICE_ID_PATH = path10.join(EXE_AI_DIR, "device-id");
3635
4463
  API_BASE = "https://askexe.com/cloud";
3636
4464
  RETRY_DELAY_MS = 500;
3637
4465
  LICENSE_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
@@ -3679,8 +4507,8 @@ __export(crdt_sync_exports, {
3679
4507
  rebuildFromDb: () => rebuildFromDb
3680
4508
  });
3681
4509
  import * as Y from "yjs";
3682
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync9, mkdirSync as mkdirSync5, unlinkSync as unlinkSync3 } from "fs";
3683
- import path9 from "path";
4510
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync10, mkdirSync as mkdirSync6, unlinkSync as unlinkSync3 } from "fs";
4511
+ import path11 from "path";
3684
4512
  import { homedir } from "os";
3685
4513
  function getStatePath() {
3686
4514
  return _statePathOverride ?? DEFAULT_STATE_PATH;
@@ -3692,9 +4520,9 @@ function initCrdtDoc() {
3692
4520
  if (doc) return doc;
3693
4521
  doc = new Y.Doc();
3694
4522
  const sp = getStatePath();
3695
- if (existsSync9(sp)) {
4523
+ if (existsSync10(sp)) {
3696
4524
  try {
3697
- const state = readFileSync7(sp);
4525
+ const state = readFileSync8(sp);
3698
4526
  Y.applyUpdate(doc, new Uint8Array(state));
3699
4527
  } catch {
3700
4528
  console.warn("[crdt-sync] WARN: corrupted state file, rebuilding from DB");
@@ -3836,10 +4664,10 @@ function persistState() {
3836
4664
  if (!doc) return;
3837
4665
  try {
3838
4666
  const sp = getStatePath();
3839
- const dir = path9.dirname(sp);
3840
- if (!existsSync9(dir)) mkdirSync5(dir, { recursive: true });
4667
+ const dir = path11.dirname(sp);
4668
+ if (!existsSync10(dir)) mkdirSync6(dir, { recursive: true });
3841
4669
  const state = Y.encodeStateAsUpdate(doc);
3842
- writeFileSync5(sp, Buffer.from(state));
4670
+ writeFileSync6(sp, Buffer.from(state));
3843
4671
  } catch {
3844
4672
  }
3845
4673
  }
@@ -3880,7 +4708,7 @@ var DEFAULT_STATE_PATH, _statePathOverride, doc;
3880
4708
  var init_crdt_sync = __esm({
3881
4709
  "src/lib/crdt-sync.ts"() {
3882
4710
  "use strict";
3883
- DEFAULT_STATE_PATH = path9.join(homedir(), ".exe-os", "crdt-state.bin");
4711
+ DEFAULT_STATE_PATH = path11.join(homedir(), ".exe-os", "crdt-state.bin");
3884
4712
  _statePathOverride = null;
3885
4713
  doc = null;
3886
4714
  }
@@ -3914,16 +4742,16 @@ __export(cloud_sync_exports, {
3914
4742
  mergeRosterFromRemote: () => mergeRosterFromRemote,
3915
4743
  recordRosterDeletion: () => recordRosterDeletion
3916
4744
  });
3917
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync10, readdirSync, mkdirSync as mkdirSync6, appendFileSync, unlinkSync as unlinkSync4, openSync as openSync2, closeSync as closeSync2 } from "fs";
4745
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync7, existsSync as existsSync11, readdirSync, mkdirSync as mkdirSync7, appendFileSync, unlinkSync as unlinkSync4, openSync as openSync2, closeSync as closeSync2 } from "fs";
3918
4746
  import crypto3 from "crypto";
3919
- import path10 from "path";
4747
+ import path12 from "path";
3920
4748
  import { homedir as homedir2 } from "os";
3921
4749
  function sqlSafe(v) {
3922
4750
  return v === void 0 ? null : v;
3923
4751
  }
3924
4752
  function logError(msg) {
3925
4753
  try {
3926
- const logPath = path10.join(homedir2(), ".exe-os", "workers.log");
4754
+ const logPath = path12.join(homedir2(), ".exe-os", "workers.log");
3927
4755
  appendFileSync(logPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
3928
4756
  `);
3929
4757
  } catch {
@@ -3933,18 +4761,18 @@ async function withRosterLock(fn) {
3933
4761
  try {
3934
4762
  const fd = openSync2(ROSTER_LOCK_PATH, "wx");
3935
4763
  closeSync2(fd);
3936
- writeFileSync6(ROSTER_LOCK_PATH, String(Date.now()));
4764
+ writeFileSync7(ROSTER_LOCK_PATH, String(Date.now()));
3937
4765
  } catch (err) {
3938
4766
  if (err.code === "EEXIST") {
3939
4767
  try {
3940
- const ts = parseInt(readFileSync8(ROSTER_LOCK_PATH, "utf-8"), 10);
4768
+ const ts = parseInt(readFileSync9(ROSTER_LOCK_PATH, "utf-8"), 10);
3941
4769
  if (Date.now() - ts < LOCK_STALE_MS) {
3942
4770
  throw new Error("Roster merge already in progress \u2014 another sync is running");
3943
4771
  }
3944
4772
  unlinkSync4(ROSTER_LOCK_PATH);
3945
4773
  const fd = openSync2(ROSTER_LOCK_PATH, "wx");
3946
4774
  closeSync2(fd);
3947
- writeFileSync6(ROSTER_LOCK_PATH, String(Date.now()));
4775
+ writeFileSync7(ROSTER_LOCK_PATH, String(Date.now()));
3948
4776
  } catch (retryErr) {
3949
4777
  if (retryErr instanceof Error && retryErr.message.includes("already in progress")) throw retryErr;
3950
4778
  throw new Error("Roster merge already in progress \u2014 another sync is running");
@@ -4318,8 +5146,8 @@ async function cloudSync(config) {
4318
5146
  try {
4319
5147
  const employees = await loadEmployees();
4320
5148
  rosterResult.employees = employees.length;
4321
- const idDir = path10.join(EXE_AI_DIR, "identity");
4322
- if (existsSync10(idDir)) {
5149
+ const idDir = path12.join(EXE_AI_DIR, "identity");
5150
+ if (existsSync11(idDir)) {
4323
5151
  rosterResult.identities = readdirSync(idDir).filter((f) => f.endsWith(".md")).length;
4324
5152
  }
4325
5153
  } catch {
@@ -4340,56 +5168,56 @@ async function cloudSync(config) {
4340
5168
  function recordRosterDeletion(name) {
4341
5169
  let deletions = [];
4342
5170
  try {
4343
- if (existsSync10(ROSTER_DELETIONS_PATH)) {
4344
- deletions = JSON.parse(readFileSync8(ROSTER_DELETIONS_PATH, "utf-8"));
5171
+ if (existsSync11(ROSTER_DELETIONS_PATH)) {
5172
+ deletions = JSON.parse(readFileSync9(ROSTER_DELETIONS_PATH, "utf-8"));
4345
5173
  }
4346
5174
  } catch {
4347
5175
  }
4348
5176
  if (!deletions.includes(name)) deletions.push(name);
4349
- writeFileSync6(ROSTER_DELETIONS_PATH, JSON.stringify(deletions));
5177
+ writeFileSync7(ROSTER_DELETIONS_PATH, JSON.stringify(deletions));
4350
5178
  }
4351
5179
  function consumeRosterDeletions() {
4352
5180
  try {
4353
- if (!existsSync10(ROSTER_DELETIONS_PATH)) return [];
4354
- const deletions = JSON.parse(readFileSync8(ROSTER_DELETIONS_PATH, "utf-8"));
4355
- writeFileSync6(ROSTER_DELETIONS_PATH, "[]");
5181
+ if (!existsSync11(ROSTER_DELETIONS_PATH)) return [];
5182
+ const deletions = JSON.parse(readFileSync9(ROSTER_DELETIONS_PATH, "utf-8"));
5183
+ writeFileSync7(ROSTER_DELETIONS_PATH, "[]");
4356
5184
  return deletions;
4357
5185
  } catch {
4358
5186
  return [];
4359
5187
  }
4360
5188
  }
4361
5189
  function buildRosterBlob(paths) {
4362
- const rosterPath = paths?.rosterPath ?? path10.join(EXE_AI_DIR, "exe-employees.json");
4363
- const identityDir = paths?.identityDir ?? path10.join(EXE_AI_DIR, "identity");
4364
- const configPath = paths?.configPath ?? path10.join(EXE_AI_DIR, "config.json");
5190
+ const rosterPath = paths?.rosterPath ?? path12.join(EXE_AI_DIR, "exe-employees.json");
5191
+ const identityDir = paths?.identityDir ?? path12.join(EXE_AI_DIR, "identity");
5192
+ const configPath = paths?.configPath ?? path12.join(EXE_AI_DIR, "config.json");
4365
5193
  let roster = [];
4366
- if (existsSync10(rosterPath)) {
5194
+ if (existsSync11(rosterPath)) {
4367
5195
  try {
4368
- roster = JSON.parse(readFileSync8(rosterPath, "utf-8"));
5196
+ roster = JSON.parse(readFileSync9(rosterPath, "utf-8"));
4369
5197
  } catch {
4370
5198
  }
4371
5199
  }
4372
5200
  const identities = {};
4373
- if (existsSync10(identityDir)) {
5201
+ if (existsSync11(identityDir)) {
4374
5202
  for (const file of readdirSync(identityDir).filter((f) => f.endsWith(".md"))) {
4375
5203
  try {
4376
- identities[file] = readFileSync8(path10.join(identityDir, file), "utf-8");
5204
+ identities[file] = readFileSync9(path12.join(identityDir, file), "utf-8");
4377
5205
  } catch {
4378
5206
  }
4379
5207
  }
4380
5208
  }
4381
5209
  let config;
4382
- if (existsSync10(configPath)) {
5210
+ if (existsSync11(configPath)) {
4383
5211
  try {
4384
- config = JSON.parse(readFileSync8(configPath, "utf-8"));
5212
+ config = JSON.parse(readFileSync9(configPath, "utf-8"));
4385
5213
  } catch {
4386
5214
  }
4387
5215
  }
4388
5216
  let agentConfig;
4389
- const agentConfigPath = path10.join(EXE_AI_DIR, "agent-config.json");
4390
- if (existsSync10(agentConfigPath)) {
5217
+ const agentConfigPath = path12.join(EXE_AI_DIR, "agent-config.json");
5218
+ if (existsSync11(agentConfigPath)) {
4391
5219
  try {
4392
- agentConfig = JSON.parse(readFileSync8(agentConfigPath, "utf-8"));
5220
+ agentConfig = JSON.parse(readFileSync9(agentConfigPath, "utf-8"));
4393
5221
  } catch {
4394
5222
  }
4395
5223
  }
@@ -4465,23 +5293,23 @@ async function cloudPullRoster(config) {
4465
5293
  }
4466
5294
  }
4467
5295
  function mergeConfig(remoteConfig, configPath) {
4468
- const cfgPath = configPath ?? path10.join(EXE_AI_DIR, "config.json");
5296
+ const cfgPath = configPath ?? path12.join(EXE_AI_DIR, "config.json");
4469
5297
  let local = {};
4470
- if (existsSync10(cfgPath)) {
5298
+ if (existsSync11(cfgPath)) {
4471
5299
  try {
4472
- local = JSON.parse(readFileSync8(cfgPath, "utf-8"));
5300
+ local = JSON.parse(readFileSync9(cfgPath, "utf-8"));
4473
5301
  } catch {
4474
5302
  }
4475
5303
  }
4476
5304
  const merged = { ...remoteConfig, ...local };
4477
- const dir = path10.dirname(cfgPath);
4478
- if (!existsSync10(dir)) mkdirSync6(dir, { recursive: true });
4479
- writeFileSync6(cfgPath, JSON.stringify(merged, null, 2), "utf-8");
5305
+ const dir = path12.dirname(cfgPath);
5306
+ if (!existsSync11(dir)) mkdirSync7(dir, { recursive: true });
5307
+ writeFileSync7(cfgPath, JSON.stringify(merged, null, 2), "utf-8");
4480
5308
  }
4481
5309
  async function mergeRosterFromRemote(remote, paths) {
4482
5310
  return withRosterLock(async () => {
4483
5311
  const rosterPath = paths?.rosterPath ?? void 0;
4484
- const identityDir = paths?.identityDir ?? path10.join(EXE_AI_DIR, "identity");
5312
+ const identityDir = paths?.identityDir ?? path12.join(EXE_AI_DIR, "identity");
4485
5313
  const localEmployees = await loadEmployees(rosterPath);
4486
5314
  const localNames = new Set(localEmployees.map((e) => e.name));
4487
5315
  let added = 0;
@@ -4502,15 +5330,15 @@ async function mergeRosterFromRemote(remote, paths) {
4502
5330
  ) ?? lookupKey;
4503
5331
  const remoteIdentity = remote.identities[matchedKey];
4504
5332
  if (remoteIdentity) {
4505
- if (!existsSync10(identityDir)) mkdirSync6(identityDir, { recursive: true });
4506
- const idPath = path10.join(identityDir, `${remoteEmp.name}.md`);
5333
+ if (!existsSync11(identityDir)) mkdirSync7(identityDir, { recursive: true });
5334
+ const idPath = path12.join(identityDir, `${remoteEmp.name}.md`);
4507
5335
  let localIdentity = null;
4508
5336
  try {
4509
- localIdentity = existsSync10(idPath) ? readFileSync8(idPath, "utf-8") : null;
5337
+ localIdentity = existsSync11(idPath) ? readFileSync9(idPath, "utf-8") : null;
4510
5338
  } catch {
4511
5339
  }
4512
5340
  if (localIdentity !== remoteIdentity) {
4513
- writeFileSync6(idPath, remoteIdentity, "utf-8");
5341
+ writeFileSync7(idPath, remoteIdentity, "utf-8");
4514
5342
  identitiesUpdated++;
4515
5343
  }
4516
5344
  }
@@ -4536,16 +5364,16 @@ async function mergeRosterFromRemote(remote, paths) {
4536
5364
  }
4537
5365
  if (remote.agentConfig && Object.keys(remote.agentConfig).length > 0) {
4538
5366
  try {
4539
- const agentConfigPath = path10.join(EXE_AI_DIR, "agent-config.json");
5367
+ const agentConfigPath = path12.join(EXE_AI_DIR, "agent-config.json");
4540
5368
  let local = {};
4541
- if (existsSync10(agentConfigPath)) {
5369
+ if (existsSync11(agentConfigPath)) {
4542
5370
  try {
4543
- local = JSON.parse(readFileSync8(agentConfigPath, "utf-8"));
5371
+ local = JSON.parse(readFileSync9(agentConfigPath, "utf-8"));
4544
5372
  } catch {
4545
5373
  }
4546
5374
  }
4547
5375
  const merged = { ...remote.agentConfig, ...local };
4548
- writeFileSync6(agentConfigPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
5376
+ writeFileSync7(agentConfigPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
4549
5377
  } catch {
4550
5378
  }
4551
5379
  }
@@ -4983,9 +5811,9 @@ var init_cloud_sync = __esm({
4983
5811
  LOCALHOST_PATTERNS = /^(localhost|127\.0\.0\.1|\[::1\])$/i;
4984
5812
  FETCH_TIMEOUT_MS = 3e4;
4985
5813
  PUSH_BATCH_SIZE = 5e3;
4986
- ROSTER_LOCK_PATH = path10.join(EXE_AI_DIR, "roster-merge.lock");
5814
+ ROSTER_LOCK_PATH = path12.join(EXE_AI_DIR, "roster-merge.lock");
4987
5815
  LOCK_STALE_MS = 3e4;
4988
- ROSTER_DELETIONS_PATH = path10.join(EXE_AI_DIR, "roster-deletions.json");
5816
+ ROSTER_DELETIONS_PATH = path12.join(EXE_AI_DIR, "roster-deletions.json");
4989
5817
  }
4990
5818
  });
4991
5819
 
@@ -5291,13 +6119,13 @@ __export(shard_manager_exports, {
5291
6119
  listShards: () => listShards,
5292
6120
  shardExists: () => shardExists
5293
6121
  });
5294
- import path11 from "path";
5295
- import { existsSync as existsSync11, mkdirSync as mkdirSync7, readdirSync as readdirSync2 } from "fs";
6122
+ import path13 from "path";
6123
+ import { existsSync as existsSync12, mkdirSync as mkdirSync8, readdirSync as readdirSync2 } from "fs";
5296
6124
  import { createClient as createClient2 } from "@libsql/client";
5297
6125
  function initShardManager(encryptionKey) {
5298
6126
  _encryptionKey = encryptionKey;
5299
- if (!existsSync11(SHARDS_DIR)) {
5300
- mkdirSync7(SHARDS_DIR, { recursive: true });
6127
+ if (!existsSync12(SHARDS_DIR)) {
6128
+ mkdirSync8(SHARDS_DIR, { recursive: true });
5301
6129
  }
5302
6130
  _shardingEnabled = true;
5303
6131
  }
@@ -5317,7 +6145,7 @@ function getShardClient(projectName) {
5317
6145
  }
5318
6146
  const cached = _shards.get(safeName);
5319
6147
  if (cached) return cached;
5320
- const dbPath = path11.join(SHARDS_DIR, `${safeName}.db`);
6148
+ const dbPath = path13.join(SHARDS_DIR, `${safeName}.db`);
5321
6149
  const client = createClient2({
5322
6150
  url: `file:${dbPath}`,
5323
6151
  encryptionKey: _encryptionKey
@@ -5327,10 +6155,10 @@ function getShardClient(projectName) {
5327
6155
  }
5328
6156
  function shardExists(projectName) {
5329
6157
  const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
5330
- return existsSync11(path11.join(SHARDS_DIR, `${safeName}.db`));
6158
+ return existsSync12(path13.join(SHARDS_DIR, `${safeName}.db`));
5331
6159
  }
5332
6160
  function listShards() {
5333
- if (!existsSync11(SHARDS_DIR)) return [];
6161
+ if (!existsSync12(SHARDS_DIR)) return [];
5334
6162
  return readdirSync2(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
5335
6163
  }
5336
6164
  async function ensureShardSchema(client) {
@@ -5404,7 +6232,23 @@ async function ensureShardSchema(client) {
5404
6232
  // MS-11: draft staging, MS-6a: memory_type, MS-7: trajectory
5405
6233
  "ALTER TABLE memories ADD COLUMN draft INTEGER DEFAULT 0",
5406
6234
  "ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'",
5407
- "ALTER TABLE memories ADD COLUMN trajectory TEXT"
6235
+ "ALTER TABLE memories ADD COLUMN trajectory TEXT",
6236
+ // Metadata enrichment columns (must match database.ts)
6237
+ "ALTER TABLE memories ADD COLUMN intent TEXT",
6238
+ "ALTER TABLE memories ADD COLUMN outcome TEXT",
6239
+ "ALTER TABLE memories ADD COLUMN domain TEXT",
6240
+ "ALTER TABLE memories ADD COLUMN referenced_entities TEXT",
6241
+ "ALTER TABLE memories ADD COLUMN retrieval_count INTEGER DEFAULT 0",
6242
+ "ALTER TABLE memories ADD COLUMN chain_position TEXT",
6243
+ "ALTER TABLE memories ADD COLUMN review_status TEXT",
6244
+ "ALTER TABLE memories ADD COLUMN context_window_pct INTEGER",
6245
+ "ALTER TABLE memories ADD COLUMN file_paths TEXT",
6246
+ "ALTER TABLE memories ADD COLUMN commit_hash TEXT",
6247
+ "ALTER TABLE memories ADD COLUMN duration_ms INTEGER",
6248
+ "ALTER TABLE memories ADD COLUMN token_cost REAL",
6249
+ "ALTER TABLE memories ADD COLUMN audience TEXT",
6250
+ "ALTER TABLE memories ADD COLUMN language_type TEXT",
6251
+ "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
5408
6252
  ]) {
5409
6253
  try {
5410
6254
  await client.execute(col);
@@ -5516,7 +6360,7 @@ var init_shard_manager = __esm({
5516
6360
  "src/lib/shard-manager.ts"() {
5517
6361
  "use strict";
5518
6362
  init_config();
5519
- SHARDS_DIR = path11.join(EXE_AI_DIR, "shards");
6363
+ SHARDS_DIR = path13.join(EXE_AI_DIR, "shards");
5520
6364
  _shards = /* @__PURE__ */ new Map();
5521
6365
  _encryptionKey = null;
5522
6366
  _shardingEnabled = false;
@@ -6288,12 +7132,12 @@ __export(backfill_conversations_exports, {
6288
7132
  import crypto4 from "crypto";
6289
7133
  import { createReadStream } from "fs";
6290
7134
  import { readdir as readdir2, stat } from "fs/promises";
6291
- import path12 from "path";
7135
+ import path14 from "path";
6292
7136
  import { createInterface as createInterface2 } from "readline";
6293
7137
  import { homedir as homedir3 } from "os";
6294
7138
  import { parseArgs } from "util";
6295
7139
  async function findJsonlFiles(sinceDate, projectFilter) {
6296
- const projectsDir = path12.join(homedir3(), ".claude", "projects");
7140
+ const projectsDir = path14.join(homedir3(), ".claude", "projects");
6297
7141
  const files = [];
6298
7142
  async function walk(dir, depth = 0) {
6299
7143
  if (depth > MAX_WALK_DEPTH) return;
@@ -6304,7 +7148,7 @@ async function findJsonlFiles(sinceDate, projectFilter) {
6304
7148
  return;
6305
7149
  }
6306
7150
  for (const entry of entries) {
6307
- const full = path12.join(dir, entry.name);
7151
+ const full = path14.join(dir, entry.name);
6308
7152
  if (entry.isDirectory()) {
6309
7153
  if (entry.name === "subagents" || entry.name === "tool-results") continue;
6310
7154
  await walk(full, depth + 1);
@@ -6329,7 +7173,7 @@ async function findJsonlFiles(sinceDate, projectFilter) {
6329
7173
  if (!entry.isDirectory()) continue;
6330
7174
  const decoded = decodeProjectDir(entry.name);
6331
7175
  if (decoded.toLowerCase().includes(projectFilter.toLowerCase())) {
6332
- await walk(path12.join(projectsDir, entry.name));
7176
+ await walk(path14.join(projectsDir, entry.name));
6333
7177
  }
6334
7178
  }
6335
7179
  } else {
@@ -6346,14 +7190,14 @@ function decodeProjectDir(dirName) {
6346
7190
  return dirName;
6347
7191
  }
6348
7192
  function projectNameFromPath(filePath) {
6349
- const projectsDir = path12.join(homedir3(), ".claude", "projects");
6350
- const relative = path12.relative(projectsDir, filePath);
6351
- const projectDir = relative.split(path12.sep)[0] ?? "unknown";
7193
+ const projectsDir = path14.join(homedir3(), ".claude", "projects");
7194
+ const relative = path14.relative(projectsDir, filePath);
7195
+ const projectDir = relative.split(path14.sep)[0] ?? "unknown";
6352
7196
  return decodeProjectDir(projectDir);
6353
7197
  }
6354
7198
  async function parseConversation(filePath) {
6355
7199
  const conv = {
6356
- sessionId: path12.basename(filePath, ".jsonl"),
7200
+ sessionId: path14.basename(filePath, ".jsonl"),
6357
7201
  projectName: projectNameFromPath(filePath),
6358
7202
  cwd: void 0,
6359
7203
  startTime: void 0,
@@ -6417,7 +7261,7 @@ async function parseConversation(filePath) {
6417
7261
  }
6418
7262
  }
6419
7263
  if (conv.cwd) {
6420
- conv.projectName = path12.basename(conv.cwd);
7264
+ conv.projectName = path14.basename(conv.cwd);
6421
7265
  const worktreeMatch = conv.cwd.match(/\.worktrees\/([^/]+)/);
6422
7266
  if (worktreeMatch?.[1]) {
6423
7267
  conv.agentId = worktreeMatch[1];
@@ -7069,9 +7913,9 @@ Unclassified: ${unclassified}
7069
7913
  }
7070
7914
  async function exportBatches(options) {
7071
7915
  const fs8 = await import("fs");
7072
- const path44 = await import("path");
7916
+ const path45 = await import("path");
7073
7917
  const client = getClient();
7074
- const outDir = path44.join(process.cwd(), "exe/output/classifications/input");
7918
+ const outDir = path45.join(process.cwd(), "exe/output/classifications/input");
7075
7919
  fs8.mkdirSync(outDir, { recursive: true });
7076
7920
  const countResult = await client.execute({
7077
7921
  sql: "SELECT COUNT(*) as cnt FROM memories WHERE intent IS NULL AND outcome IS NULL AND domain IS NULL",
@@ -7095,7 +7939,7 @@ async function exportBatches(options) {
7095
7939
  const text = String(row.text || "").replace(/\n/g, " ");
7096
7940
  return JSON.stringify({ id: row.id, text });
7097
7941
  });
7098
- const batchFile = path44.join(outDir, `batch-${String(batchNum).padStart(4, "0")}.jsonl`);
7942
+ const batchFile = path45.join(outDir, `batch-${String(batchNum).padStart(4, "0")}.jsonl`);
7099
7943
  fs8.writeFileSync(batchFile, lines.join("\n") + "\n");
7100
7944
  exported += batch.rows.length;
7101
7945
  offset += options.batchSize;
@@ -7111,7 +7955,7 @@ async function exportBatches(options) {
7111
7955
  }
7112
7956
  async function importClassifications(importDir) {
7113
7957
  const fs8 = await import("fs");
7114
- const path44 = await import("path");
7958
+ const path45 = await import("path");
7115
7959
  const client = getClient();
7116
7960
  const files = fs8.readdirSync(importDir).filter((f) => f.endsWith(".jsonl")).sort();
7117
7961
  process.stderr.write(`[backfill-metadata] Found ${files.length} JSONL files to import from ${importDir}
@@ -7119,7 +7963,7 @@ async function importClassifications(importDir) {
7119
7963
  let imported = 0;
7120
7964
  let invalid = 0;
7121
7965
  for (const file of files) {
7122
- const lines = fs8.readFileSync(path44.join(importDir, file), "utf-8").split("\n").filter(Boolean);
7966
+ const lines = fs8.readFileSync(path45.join(importDir, file), "utf-8").split("\n").filter(Boolean);
7123
7967
  for (const line of lines) {
7124
7968
  try {
7125
7969
  const rec = JSON.parse(line);
@@ -7260,17 +8104,17 @@ __export(identity_exports, {
7260
8104
  listIdentities: () => listIdentities,
7261
8105
  updateIdentity: () => updateIdentity
7262
8106
  });
7263
- import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
8107
+ import { existsSync as existsSync13, mkdirSync as mkdirSync9, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
7264
8108
  import { readdirSync as readdirSync3 } from "fs";
7265
- import path13 from "path";
8109
+ import path15 from "path";
7266
8110
  import { createHash as createHash2 } from "crypto";
7267
8111
  function ensureDir() {
7268
- if (!existsSync12(IDENTITY_DIR)) {
7269
- mkdirSync8(IDENTITY_DIR, { recursive: true });
8112
+ if (!existsSync13(IDENTITY_DIR2)) {
8113
+ mkdirSync9(IDENTITY_DIR2, { recursive: true });
7270
8114
  }
7271
8115
  }
7272
8116
  function identityPath(agentId) {
7273
- return path13.join(IDENTITY_DIR, `${agentId}.md`);
8117
+ return path15.join(IDENTITY_DIR2, `${agentId}.md`);
7274
8118
  }
7275
8119
  function parseFrontmatter(raw) {
7276
8120
  const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
@@ -7311,8 +8155,8 @@ function contentHash(content) {
7311
8155
  }
7312
8156
  function getIdentity(agentId) {
7313
8157
  const filePath = identityPath(agentId);
7314
- if (!existsSync12(filePath)) return null;
7315
- const raw = readFileSync9(filePath, "utf-8");
8158
+ if (!existsSync13(filePath)) return null;
8159
+ const raw = readFileSync10(filePath, "utf-8");
7316
8160
  const { frontmatter, body } = parseFrontmatter(raw);
7317
8161
  return {
7318
8162
  agentId,
@@ -7326,7 +8170,7 @@ async function updateIdentity(agentId, content, updatedBy) {
7326
8170
  ensureDir();
7327
8171
  const filePath = identityPath(agentId);
7328
8172
  const hash = contentHash(content);
7329
- writeFileSync7(filePath, content, "utf-8");
8173
+ writeFileSync8(filePath, content, "utf-8");
7330
8174
  try {
7331
8175
  const client = getClient();
7332
8176
  await client.execute({
@@ -7343,7 +8187,7 @@ async function updateIdentity(agentId, content, updatedBy) {
7343
8187
  }
7344
8188
  function listIdentities() {
7345
8189
  ensureDir();
7346
- const files = readdirSync3(IDENTITY_DIR).filter((f) => f.endsWith(".md"));
8190
+ const files = readdirSync3(IDENTITY_DIR2).filter((f) => f.endsWith(".md"));
7347
8191
  const results = [];
7348
8192
  for (const file of files) {
7349
8193
  const agentId = file.replace(".md", "");
@@ -7376,21 +8220,21 @@ ${teamLines.join("\n")}`);
7376
8220
  }
7377
8221
  return parts.join("\n\n");
7378
8222
  }
7379
- var IDENTITY_DIR;
8223
+ var IDENTITY_DIR2;
7380
8224
  var init_identity = __esm({
7381
8225
  "src/lib/identity.ts"() {
7382
8226
  "use strict";
7383
8227
  init_config();
7384
8228
  init_database();
7385
- IDENTITY_DIR = path13.join(EXE_AI_DIR, "identity");
8229
+ IDENTITY_DIR2 = path15.join(EXE_AI_DIR, "identity");
7386
8230
  }
7387
8231
  });
7388
8232
 
7389
8233
  // src/lib/orchestration-package.ts
7390
8234
  import { randomUUID as randomUUID4 } from "crypto";
7391
- import { copyFileSync as copyFileSync2, existsSync as existsSync13, mkdirSync as mkdirSync9, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
7392
- import os8 from "os";
7393
- import path14 from "path";
8235
+ import { copyFileSync as copyFileSync2, existsSync as existsSync14, mkdirSync as mkdirSync10, readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "fs";
8236
+ import os9 from "os";
8237
+ import path16 from "path";
7394
8238
  function ensureObject(value, label) {
7395
8239
  if (value == null || Array.isArray(value) || typeof value !== "object") {
7396
8240
  throw new Error(`${label} must be an object`);
@@ -7449,15 +8293,15 @@ function validateProcedureEntry(value, index) {
7449
8293
  };
7450
8294
  }
7451
8295
  function getRosterPath() {
7452
- return path14.join(os8.homedir(), EXE_OS_DIRNAME, ROSTER_FILENAME);
8296
+ return path16.join(os9.homedir(), EXE_OS_DIRNAME, ROSTER_FILENAME);
7453
8297
  }
7454
8298
  function getBackupPath() {
7455
- return path14.join(os8.homedir(), EXE_OS_DIRNAME, ROSTER_BACKUP_FILENAME);
8299
+ return path16.join(os9.homedir(), EXE_OS_DIRNAME, ROSTER_BACKUP_FILENAME);
7456
8300
  }
7457
8301
  function readRosterFile() {
7458
8302
  const rosterPath = getRosterPath();
7459
- if (!existsSync13(rosterPath)) return [];
7460
- const raw = readFileSync10(rosterPath, "utf-8");
8303
+ if (!existsSync14(rosterPath)) return [];
8304
+ const raw = readFileSync11(rosterPath, "utf-8");
7461
8305
  const parsed = JSON.parse(raw);
7462
8306
  if (!Array.isArray(parsed)) {
7463
8307
  throw new Error("Roster file must contain a JSON array");
@@ -7469,8 +8313,8 @@ function writeRosterFile(roster) {
7469
8313
  throw new Error("Refusing to write empty roster \u2014 this would delete all employees");
7470
8314
  }
7471
8315
  const rosterPath = getRosterPath();
7472
- mkdirSync9(path14.dirname(rosterPath), { recursive: true });
7473
- if (existsSync13(rosterPath)) {
8316
+ mkdirSync10(path16.dirname(rosterPath), { recursive: true });
8317
+ if (existsSync14(rosterPath)) {
7474
8318
  const currentRoster = readRosterFile();
7475
8319
  if (roster.length < currentRoster.length) {
7476
8320
  throw new Error(
@@ -7479,7 +8323,7 @@ function writeRosterFile(roster) {
7479
8323
  }
7480
8324
  copyFileSync2(rosterPath, getBackupPath());
7481
8325
  }
7482
- writeFileSync8(rosterPath, `${JSON.stringify(roster, null, 2)}
8326
+ writeFileSync9(rosterPath, `${JSON.stringify(roster, null, 2)}
7483
8327
  `, "utf-8");
7484
8328
  }
7485
8329
  function buildImportedRosterEntries(roster, timestamp) {
@@ -7746,8 +8590,8 @@ var exe_export_exports = {};
7746
8590
  __export(exe_export_exports, {
7747
8591
  runExeExport: () => runExeExport
7748
8592
  });
7749
- import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync9 } from "fs";
7750
- import path15 from "path";
8593
+ import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync10 } from "fs";
8594
+ import path17 from "path";
7751
8595
  function printUsage() {
7752
8596
  process.stdout.write("Usage: exe-os export --output <path>\n");
7753
8597
  }
@@ -7768,8 +8612,8 @@ async function runExeExport(argv = process.argv.slice(2)) {
7768
8612
  await initStore();
7769
8613
  try {
7770
8614
  const pkg = await exportOrchestration("cli");
7771
- mkdirSync10(path15.dirname(outputPath), { recursive: true });
7772
- writeFileSync9(outputPath, `${JSON.stringify(pkg, null, 2)}
8615
+ mkdirSync11(path17.dirname(outputPath), { recursive: true });
8616
+ writeFileSync10(outputPath, `${JSON.stringify(pkg, null, 2)}
7773
8617
  `, "utf-8");
7774
8618
  process.stdout.write(
7775
8619
  `Exported ${pkg.roster.length} roster entries, ${Object.keys(pkg.identities).length} identities, ${pkg.behaviors.length} behaviors, ${pkg.procedures.length} procedures to ${outputPath}
@@ -7805,7 +8649,7 @@ var exe_import_exports = {};
7805
8649
  __export(exe_import_exports, {
7806
8650
  runExeImport: () => runExeImport
7807
8651
  });
7808
- import { readFileSync as readFileSync11 } from "fs";
8652
+ import { readFileSync as readFileSync12 } from "fs";
7809
8653
  function printUsage2() {
7810
8654
  process.stdout.write("Usage: exe-os import --from <path> [--merge]\n");
7811
8655
  }
@@ -7828,7 +8672,7 @@ async function runExeImport(argv = process.argv.slice(2)) {
7828
8672
  if (parsed == null) return;
7829
8673
  await initStore();
7830
8674
  try {
7831
- const raw = readFileSync11(parsed.packagePath, "utf-8");
8675
+ const raw = readFileSync12(parsed.packagePath, "utf-8");
7832
8676
  const pkg = validatePackage(JSON.parse(raw));
7833
8677
  const result = await importOrchestration(pkg, parsed.strategy);
7834
8678
  process.stdout.write(
@@ -7868,14 +8712,14 @@ __export(session_registry_exports, {
7868
8712
  pruneStaleSessions: () => pruneStaleSessions,
7869
8713
  registerSession: () => registerSession
7870
8714
  });
7871
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync10, mkdirSync as mkdirSync11, existsSync as existsSync14 } from "fs";
8715
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync11, mkdirSync as mkdirSync12, existsSync as existsSync15 } from "fs";
7872
8716
  import { execSync as execSync3 } from "child_process";
7873
- import path16 from "path";
7874
- import os9 from "os";
8717
+ import path18 from "path";
8718
+ import os10 from "os";
7875
8719
  function registerSession(entry) {
7876
- const dir = path16.dirname(REGISTRY_PATH);
7877
- if (!existsSync14(dir)) {
7878
- mkdirSync11(dir, { recursive: true });
8720
+ const dir = path18.dirname(REGISTRY_PATH);
8721
+ if (!existsSync15(dir)) {
8722
+ mkdirSync12(dir, { recursive: true });
7879
8723
  }
7880
8724
  const sessions = listSessions();
7881
8725
  const idx = sessions.findIndex((s) => s.windowName === entry.windowName);
@@ -7884,11 +8728,11 @@ function registerSession(entry) {
7884
8728
  } else {
7885
8729
  sessions.push(entry);
7886
8730
  }
7887
- writeFileSync10(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
8731
+ writeFileSync11(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
7888
8732
  }
7889
8733
  function listSessions() {
7890
8734
  try {
7891
- const raw = readFileSync12(REGISTRY_PATH, "utf8");
8735
+ const raw = readFileSync13(REGISTRY_PATH, "utf8");
7892
8736
  return JSON.parse(raw);
7893
8737
  } catch {
7894
8738
  return [];
@@ -7909,7 +8753,7 @@ function pruneStaleSessions() {
7909
8753
  const alive = sessions.filter((s) => liveSet.has(s.windowName));
7910
8754
  const pruned = sessions.length - alive.length;
7911
8755
  if (pruned > 0) {
7912
- writeFileSync10(REGISTRY_PATH, JSON.stringify(alive, null, 2));
8756
+ writeFileSync11(REGISTRY_PATH, JSON.stringify(alive, null, 2));
7913
8757
  }
7914
8758
  return pruned;
7915
8759
  }
@@ -7917,7 +8761,7 @@ var REGISTRY_PATH;
7917
8761
  var init_session_registry = __esm({
7918
8762
  "src/lib/session-registry.ts"() {
7919
8763
  "use strict";
7920
- REGISTRY_PATH = path16.join(os9.homedir(), ".exe-os", "session-registry.json");
8764
+ REGISTRY_PATH = path18.join(os10.homedir(), ".exe-os", "session-registry.json");
7921
8765
  }
7922
8766
  });
7923
8767
 
@@ -8154,67 +8998,6 @@ var init_provider_table = __esm({
8154
8998
  }
8155
8999
  });
8156
9000
 
8157
- // src/lib/runtime-table.ts
8158
- var RUNTIME_TABLE, DEFAULT_RUNTIME;
8159
- var init_runtime_table = __esm({
8160
- "src/lib/runtime-table.ts"() {
8161
- "use strict";
8162
- RUNTIME_TABLE = {
8163
- codex: {
8164
- binary: "codex",
8165
- launchMode: "interactive",
8166
- autoApproveFlag: "--dangerously-bypass-approvals-and-sandbox",
8167
- inlineFlag: "--no-alt-screen",
8168
- apiKeyEnv: "OPENAI_API_KEY",
8169
- defaultModel: "gpt-5.4"
8170
- },
8171
- opencode: {
8172
- binary: "opencode",
8173
- launchMode: "exec",
8174
- autoApproveFlag: "--dangerously-skip-permissions",
8175
- inlineFlag: "",
8176
- apiKeyEnv: "ANTHROPIC_API_KEY",
8177
- defaultModel: "anthropic/claude-sonnet-4-6"
8178
- }
8179
- };
8180
- DEFAULT_RUNTIME = "claude";
8181
- }
8182
- });
8183
-
8184
- // src/lib/agent-config.ts
8185
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync11, existsSync as existsSync15, mkdirSync as mkdirSync12 } from "fs";
8186
- import path17 from "path";
8187
- function loadAgentConfig() {
8188
- if (!existsSync15(AGENT_CONFIG_PATH)) return {};
8189
- try {
8190
- return JSON.parse(readFileSync13(AGENT_CONFIG_PATH, "utf-8"));
8191
- } catch {
8192
- return {};
8193
- }
8194
- }
8195
- function getAgentRuntime(agentId) {
8196
- const config = loadAgentConfig();
8197
- const entry = config[agentId];
8198
- if (entry) return entry;
8199
- const orgDefault = config["default"];
8200
- if (orgDefault) return orgDefault;
8201
- return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
8202
- }
8203
- var AGENT_CONFIG_PATH, DEFAULT_MODELS;
8204
- var init_agent_config = __esm({
8205
- "src/lib/agent-config.ts"() {
8206
- "use strict";
8207
- init_config();
8208
- init_runtime_table();
8209
- AGENT_CONFIG_PATH = path17.join(EXE_AI_DIR, "agent-config.json");
8210
- DEFAULT_MODELS = {
8211
- claude: "claude-opus-4",
8212
- codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
8213
- opencode: RUNTIME_TABLE.opencode?.defaultModel ?? "anthropic/claude-sonnet-4-6"
8214
- };
8215
- }
8216
- });
8217
-
8218
9001
  // src/lib/intercom-queue.ts
8219
9002
  var intercom_queue_exports = {};
8220
9003
  __export(intercom_queue_exports, {
@@ -8225,10 +9008,10 @@ __export(intercom_queue_exports, {
8225
9008
  readQueue: () => readQueue
8226
9009
  });
8227
9010
  import { readFileSync as readFileSync14, writeFileSync as writeFileSync12, renameSync as renameSync3, existsSync as existsSync16, mkdirSync as mkdirSync13 } from "fs";
8228
- import path18 from "path";
8229
- import os10 from "os";
9011
+ import path19 from "path";
9012
+ import os11 from "os";
8230
9013
  function ensureDir2() {
8231
- const dir = path18.dirname(QUEUE_PATH);
9014
+ const dir = path19.dirname(QUEUE_PATH);
8232
9015
  if (!existsSync16(dir)) mkdirSync13(dir, { recursive: true });
8233
9016
  }
8234
9017
  function readQueue() {
@@ -8334,16 +9117,16 @@ var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
8334
9117
  var init_intercom_queue = __esm({
8335
9118
  "src/lib/intercom-queue.ts"() {
8336
9119
  "use strict";
8337
- QUEUE_PATH = path18.join(os10.homedir(), ".exe-os", "intercom-queue.json");
9120
+ QUEUE_PATH = path19.join(os11.homedir(), ".exe-os", "intercom-queue.json");
8338
9121
  MAX_RETRIES2 = 5;
8339
9122
  TTL_MS = 60 * 60 * 1e3;
8340
- INTERCOM_LOG = path18.join(os10.homedir(), ".exe-os", "intercom.log");
9123
+ INTERCOM_LOG = path19.join(os11.homedir(), ".exe-os", "intercom.log");
8341
9124
  }
8342
9125
  });
8343
9126
 
8344
9127
  // src/lib/plan-limits.ts
8345
9128
  import { readFileSync as readFileSync15, existsSync as existsSync17 } from "fs";
8346
- import path19 from "path";
9129
+ import path20 from "path";
8347
9130
  function getLicenseSync() {
8348
9131
  try {
8349
9132
  if (!existsSync17(CACHE_PATH2)) return freeLicense();
@@ -8415,14 +9198,14 @@ var init_plan_limits = __esm({
8415
9198
  this.name = "PlanLimitError";
8416
9199
  }
8417
9200
  };
8418
- CACHE_PATH2 = path19.join(EXE_AI_DIR, "license-cache.json");
9201
+ CACHE_PATH2 = path20.join(EXE_AI_DIR, "license-cache.json");
8419
9202
  }
8420
9203
  });
8421
9204
 
8422
9205
  // src/lib/notifications.ts
8423
9206
  import crypto5 from "crypto";
8424
- import path20 from "path";
8425
- import os11 from "os";
9207
+ import path21 from "path";
9208
+ import os12 from "os";
8426
9209
  import {
8427
9210
  readFileSync as readFileSync16,
8428
9211
  readdirSync as readdirSync4,
@@ -8552,8 +9335,8 @@ __export(tasks_crud_exports, {
8552
9335
  writeCheckpoint: () => writeCheckpoint
8553
9336
  });
8554
9337
  import crypto7 from "crypto";
8555
- import path21 from "path";
8556
- import os12 from "os";
9338
+ import path22 from "path";
9339
+ import os13 from "os";
8557
9340
  import { execSync as execSync6 } from "child_process";
8558
9341
  import { mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
8559
9342
  import { existsSync as existsSync19, readFileSync as readFileSync17 } from "fs";
@@ -8731,8 +9514,8 @@ ${laneWarning}` : laneWarning;
8731
9514
  }
8732
9515
  if (input.baseDir) {
8733
9516
  try {
8734
- await mkdir5(path21.join(input.baseDir, "exe", "output"), { recursive: true });
8735
- await mkdir5(path21.join(input.baseDir, "exe", "research"), { recursive: true });
9517
+ await mkdir5(path22.join(input.baseDir, "exe", "output"), { recursive: true });
9518
+ await mkdir5(path22.join(input.baseDir, "exe", "research"), { recursive: true });
8736
9519
  await ensureArchitectureDoc(input.baseDir, input.projectName);
8737
9520
  await ensureGitignoreExe(input.baseDir);
8738
9521
  } catch {
@@ -8768,9 +9551,9 @@ ${laneWarning}` : laneWarning;
8768
9551
  });
8769
9552
  if (input.baseDir) {
8770
9553
  try {
8771
- const EXE_OS_DIR = path21.join(os12.homedir(), ".exe-os");
8772
- const mdPath = path21.join(EXE_OS_DIR, taskFile);
8773
- const mdDir = path21.dirname(mdPath);
9554
+ const EXE_OS_DIR = path22.join(os13.homedir(), ".exe-os");
9555
+ const mdPath = path22.join(EXE_OS_DIR, taskFile);
9556
+ const mdDir = path22.dirname(mdPath);
8774
9557
  if (!existsSync19(mdDir)) await mkdir5(mdDir, { recursive: true });
8775
9558
  const reviewer = input.reviewer ?? input.assignedBy;
8776
9559
  const mdContent = `# ${input.title}
@@ -9071,7 +9854,7 @@ async function deleteTaskCore(taskId, _baseDir) {
9071
9854
  return { taskFile, assignedTo, assignedBy, taskSlug };
9072
9855
  }
9073
9856
  async function ensureArchitectureDoc(baseDir, projectName) {
9074
- const archPath = path21.join(baseDir, "exe", "ARCHITECTURE.md");
9857
+ const archPath = path22.join(baseDir, "exe", "ARCHITECTURE.md");
9075
9858
  try {
9076
9859
  if (existsSync19(archPath)) return;
9077
9860
  const template = [
@@ -9106,7 +9889,7 @@ async function ensureArchitectureDoc(baseDir, projectName) {
9106
9889
  }
9107
9890
  }
9108
9891
  async function ensureGitignoreExe(baseDir) {
9109
- const gitignorePath = path21.join(baseDir, ".gitignore");
9892
+ const gitignorePath = path22.join(baseDir, ".gitignore");
9110
9893
  try {
9111
9894
  if (existsSync19(gitignorePath)) {
9112
9895
  const content = readFileSync17(gitignorePath, "utf-8");
@@ -9140,13 +9923,13 @@ var init_tasks_crud = __esm({
9140
9923
  });
9141
9924
 
9142
9925
  // src/lib/tasks-review.ts
9143
- import path22 from "path";
9926
+ import path23 from "path";
9144
9927
  import { existsSync as existsSync20, readdirSync as readdirSync5, unlinkSync as unlinkSync6 } from "fs";
9145
9928
  async function countPendingReviews(sessionScope) {
9146
9929
  const client = getClient();
9147
9930
  if (sessionScope) {
9148
9931
  const result2 = await client.execute({
9149
- sql: "SELECT COUNT(*) as cnt FROM tasks WHERE status = 'needs_review' AND (session_scope = ? OR session_scope IS NULL)",
9932
+ sql: "SELECT COUNT(*) as cnt FROM tasks WHERE status = 'needs_review' AND session_scope = ?",
9150
9933
  args: [sessionScope]
9151
9934
  });
9152
9935
  return Number(result2.rows[0]?.cnt) || 0;
@@ -9322,11 +10105,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
9322
10105
  );
9323
10106
  }
9324
10107
  try {
9325
- const cacheDir = path22.join(EXE_AI_DIR, "session-cache");
10108
+ const cacheDir = path23.join(EXE_AI_DIR, "session-cache");
9326
10109
  if (existsSync20(cacheDir)) {
9327
10110
  for (const f of readdirSync5(cacheDir)) {
9328
10111
  if (f.startsWith("review-notified-")) {
9329
- unlinkSync6(path22.join(cacheDir, f));
10112
+ unlinkSync6(path23.join(cacheDir, f));
9330
10113
  }
9331
10114
  }
9332
10115
  }
@@ -9347,7 +10130,7 @@ var init_tasks_review = __esm({
9347
10130
  });
9348
10131
 
9349
10132
  // src/lib/tasks-chain.ts
9350
- import path23 from "path";
10133
+ import path24 from "path";
9351
10134
  import { readFile as readFile5, writeFile as writeFile6 } from "fs/promises";
9352
10135
  async function cascadeUnblock(taskId, baseDir, now) {
9353
10136
  const client = getClient();
@@ -9364,7 +10147,7 @@ async function cascadeUnblock(taskId, baseDir, now) {
9364
10147
  });
9365
10148
  for (const ur of unblockedRows.rows) {
9366
10149
  try {
9367
- const ubFile = path23.join(baseDir, String(ur.task_file));
10150
+ const ubFile = path24.join(baseDir, String(ur.task_file));
9368
10151
  let ubContent = await readFile5(ubFile, "utf-8");
9369
10152
  ubContent = ubContent.replace(/\*\*Status:\*\* blocked/, "**Status:** open");
9370
10153
  ubContent = ubContent.replace(/\n\*\*Blocked by:\*\*.*\n/, "\n");
@@ -9433,7 +10216,7 @@ var init_tasks_chain = __esm({
9433
10216
 
9434
10217
  // src/lib/project-name.ts
9435
10218
  import { execSync as execSync7 } from "child_process";
9436
- import path24 from "path";
10219
+ import path25 from "path";
9437
10220
  function getProjectName(cwd2) {
9438
10221
  const dir = cwd2 ?? process.cwd();
9439
10222
  if (_cached2 && _cachedCwd === dir) return _cached2;
@@ -9446,7 +10229,7 @@ function getProjectName(cwd2) {
9446
10229
  timeout: 2e3,
9447
10230
  stdio: ["pipe", "pipe", "pipe"]
9448
10231
  }).trim();
9449
- repoRoot = path24.dirname(gitCommonDir);
10232
+ repoRoot = path25.dirname(gitCommonDir);
9450
10233
  } catch {
9451
10234
  repoRoot = execSync7("git rev-parse --show-toplevel", {
9452
10235
  cwd: dir,
@@ -9455,11 +10238,11 @@ function getProjectName(cwd2) {
9455
10238
  stdio: ["pipe", "pipe", "pipe"]
9456
10239
  }).trim();
9457
10240
  }
9458
- _cached2 = path24.basename(repoRoot);
10241
+ _cached2 = path25.basename(repoRoot);
9459
10242
  _cachedCwd = dir;
9460
10243
  return _cached2;
9461
10244
  } catch {
9462
- _cached2 = path24.basename(dir);
10245
+ _cached2 = path25.basename(dir);
9463
10246
  _cachedCwd = dir;
9464
10247
  return _cached2;
9465
10248
  }
@@ -9932,7 +10715,7 @@ __export(tasks_exports, {
9932
10715
  updateTaskStatus: () => updateTaskStatus,
9933
10716
  writeCheckpoint: () => writeCheckpoint
9934
10717
  });
9935
- import path25 from "path";
10718
+ import path26 from "path";
9936
10719
  import { writeFileSync as writeFileSync13, mkdirSync as mkdirSync14, unlinkSync as unlinkSync7 } from "fs";
9937
10720
  async function createTask(input) {
9938
10721
  const result = await createTaskCore(input);
@@ -9952,8 +10735,8 @@ async function updateTask(input) {
9952
10735
  const { row, taskFile, now, taskId } = await updateTaskStatus(input);
9953
10736
  try {
9954
10737
  const agent = String(row.assigned_to);
9955
- const cacheDir = path25.join(EXE_AI_DIR, "session-cache");
9956
- const cachePath = path25.join(cacheDir, `current-task-${agent}.json`);
10738
+ const cacheDir = path26.join(EXE_AI_DIR, "session-cache");
10739
+ const cachePath = path26.join(cacheDir, `current-task-${agent}.json`);
9957
10740
  if (input.status === "in_progress") {
9958
10741
  mkdirSync14(cacheDir, { recursive: true });
9959
10742
  writeFileSync13(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
@@ -10424,12 +11207,12 @@ __export(tmux_routing_exports, {
10424
11207
  });
10425
11208
  import { execFileSync as execFileSync2, execSync as execSync8 } from "child_process";
10426
11209
  import { readFileSync as readFileSync18, writeFileSync as writeFileSync14, mkdirSync as mkdirSync15, existsSync as existsSync21, appendFileSync as appendFileSync2, readdirSync as readdirSync6 } from "fs";
10427
- import path26 from "path";
10428
- import os13 from "os";
11210
+ import path27 from "path";
11211
+ import os14 from "os";
10429
11212
  import { fileURLToPath as fileURLToPath4 } from "url";
10430
11213
  import { unlinkSync as unlinkSync8 } from "fs";
10431
11214
  function spawnLockPath(sessionName) {
10432
- return path26.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
11215
+ return path27.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
10433
11216
  }
10434
11217
  function isProcessAlive(pid) {
10435
11218
  try {
@@ -10466,8 +11249,8 @@ function releaseSpawnLock2(sessionName) {
10466
11249
  function resolveBehaviorsExporterScript() {
10467
11250
  try {
10468
11251
  const thisFile = fileURLToPath4(import.meta.url);
10469
- const scriptPath = path26.join(
10470
- path26.dirname(thisFile),
11252
+ const scriptPath = path27.join(
11253
+ path27.dirname(thisFile),
10471
11254
  "..",
10472
11255
  "bin",
10473
11256
  "exe-export-behaviors.js"
@@ -10542,7 +11325,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
10542
11325
  mkdirSync15(SESSION_CACHE, { recursive: true });
10543
11326
  }
10544
11327
  const rootExe = extractRootExe(parentExe) ?? parentExe;
10545
- const filePath = path26.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
11328
+ const filePath = path27.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
10546
11329
  writeFileSync14(filePath, JSON.stringify({
10547
11330
  parentExe: rootExe,
10548
11331
  dispatchedBy: dispatchedBy || rootExe,
@@ -10551,7 +11334,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
10551
11334
  }
10552
11335
  function getParentExe(sessionKey) {
10553
11336
  try {
10554
- const data = JSON.parse(readFileSync18(path26.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
11337
+ const data = JSON.parse(readFileSync18(path27.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
10555
11338
  return data.parentExe || null;
10556
11339
  } catch {
10557
11340
  return null;
@@ -10560,7 +11343,7 @@ function getParentExe(sessionKey) {
10560
11343
  function getDispatchedBy(sessionKey) {
10561
11344
  try {
10562
11345
  const data = JSON.parse(readFileSync18(
10563
- path26.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
11346
+ path27.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
10564
11347
  "utf8"
10565
11348
  ));
10566
11349
  return data.dispatchedBy ?? data.parentExe ?? null;
@@ -10746,7 +11529,7 @@ function sendIntercom(targetSession) {
10746
11529
  try {
10747
11530
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
10748
11531
  const agent = baseAgentName(rawAgent);
10749
- const markerPath = path26.join(SESSION_CACHE, `current-task-${agent}.json`);
11532
+ const markerPath = path27.join(SESSION_CACHE, `current-task-${agent}.json`);
10750
11533
  if (existsSync21(markerPath)) {
10751
11534
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker \u2014 will auto-chain)`);
10752
11535
  return "debounced";
@@ -10756,7 +11539,7 @@ function sendIntercom(targetSession) {
10756
11539
  try {
10757
11540
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
10758
11541
  const agent = baseAgentName(rawAgent);
10759
- const taskDir = path26.join(process.cwd(), "exe", agent);
11542
+ const taskDir = path27.join(process.cwd(), "exe", agent);
10760
11543
  if (existsSync21(taskDir)) {
10761
11544
  const files = readdirSync6(taskDir).filter(
10762
11545
  (f) => f.endsWith(".md") && f !== "DONE.txt"
@@ -10890,8 +11673,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
10890
11673
  const transport = getTransport();
10891
11674
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
10892
11675
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
10893
- const logDir = path26.join(os13.homedir(), ".exe-os", "session-logs");
10894
- const logFile = path26.join(logDir, `${instanceLabel}-${Date.now()}.log`);
11676
+ const logDir = path27.join(os14.homedir(), ".exe-os", "session-logs");
11677
+ const logFile = path27.join(logDir, `${instanceLabel}-${Date.now()}.log`);
10895
11678
  if (!existsSync21(logDir)) {
10896
11679
  mkdirSync15(logDir, { recursive: true });
10897
11680
  }
@@ -10899,14 +11682,14 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
10899
11682
  let cleanupSuffix = "";
10900
11683
  try {
10901
11684
  const thisFile = fileURLToPath4(import.meta.url);
10902
- const cleanupScript = path26.join(path26.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
11685
+ const cleanupScript = path27.join(path27.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
10903
11686
  if (existsSync21(cleanupScript)) {
10904
11687
  cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
10905
11688
  }
10906
11689
  } catch {
10907
11690
  }
10908
11691
  try {
10909
- const claudeJsonPath = path26.join(os13.homedir(), ".claude.json");
11692
+ const claudeJsonPath = path27.join(os14.homedir(), ".claude.json");
10910
11693
  let claudeJson = {};
10911
11694
  try {
10912
11695
  claudeJson = JSON.parse(readFileSync18(claudeJsonPath, "utf8"));
@@ -10921,10 +11704,10 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
10921
11704
  } catch {
10922
11705
  }
10923
11706
  try {
10924
- const settingsDir = path26.join(os13.homedir(), ".claude", "projects");
11707
+ const settingsDir = path27.join(os14.homedir(), ".claude", "projects");
10925
11708
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
10926
- const projSettingsDir = path26.join(settingsDir, normalizedKey);
10927
- const settingsPath = path26.join(projSettingsDir, "settings.json");
11709
+ const projSettingsDir = path27.join(settingsDir, normalizedKey);
11710
+ const settingsPath = path27.join(projSettingsDir, "settings.json");
10928
11711
  let settings = {};
10929
11712
  try {
10930
11713
  settings = JSON.parse(readFileSync18(settingsPath, "utf8"));
@@ -10971,8 +11754,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
10971
11754
  let behaviorsFlag = "";
10972
11755
  let legacyFallbackWarned = false;
10973
11756
  if (!useExeAgent && !useBinSymlink) {
10974
- const identityPath2 = path26.join(
10975
- os13.homedir(),
11757
+ const identityPath2 = path27.join(
11758
+ os14.homedir(),
10976
11759
  ".exe-os",
10977
11760
  "identity",
10978
11761
  `${employeeName}.md`
@@ -10987,7 +11770,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
10987
11770
  }
10988
11771
  const behaviorsFile = exportBehaviorsSync(
10989
11772
  employeeName,
10990
- path26.basename(spawnCwd),
11773
+ path27.basename(spawnCwd),
10991
11774
  sessionName
10992
11775
  );
10993
11776
  if (behaviorsFile) {
@@ -11002,9 +11785,9 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
11002
11785
  }
11003
11786
  let sessionContextFlag = "";
11004
11787
  try {
11005
- const ctxDir = path26.join(os13.homedir(), ".exe-os", "session-cache");
11788
+ const ctxDir = path27.join(os14.homedir(), ".exe-os", "session-cache");
11006
11789
  mkdirSync15(ctxDir, { recursive: true });
11007
- const ctxFile = path26.join(ctxDir, `session-context-${sessionName}.md`);
11790
+ const ctxFile = path27.join(ctxDir, `session-context-${sessionName}.md`);
11008
11791
  const ctxContent = [
11009
11792
  `## Session Context`,
11010
11793
  `You are running in tmux session: ${sessionName}.`,
@@ -11088,7 +11871,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
11088
11871
  transport.pipeLog(sessionName, logFile);
11089
11872
  try {
11090
11873
  const mySession = getMySession();
11091
- const dispatchInfo = path26.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
11874
+ const dispatchInfo = path27.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
11092
11875
  writeFileSync14(dispatchInfo, JSON.stringify({
11093
11876
  dispatchedBy: mySession,
11094
11877
  rootExe: exeSession,
@@ -11163,15 +11946,15 @@ var init_tmux_routing = __esm({
11163
11946
  init_intercom_queue();
11164
11947
  init_plan_limits();
11165
11948
  init_employees();
11166
- SPAWN_LOCK_DIR = path26.join(os13.homedir(), ".exe-os", "spawn-locks");
11167
- SESSION_CACHE = path26.join(os13.homedir(), ".exe-os", "session-cache");
11949
+ SPAWN_LOCK_DIR = path27.join(os14.homedir(), ".exe-os", "spawn-locks");
11950
+ SESSION_CACHE = path27.join(os14.homedir(), ".exe-os", "session-cache");
11168
11951
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
11169
11952
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
11170
11953
  VERIFY_PANE_LINES = 200;
11171
11954
  INTERCOM_DEBOUNCE_MS = 3e4;
11172
11955
  CODEX_DEBOUNCE_MS = 12e4;
11173
- INTERCOM_LOG2 = path26.join(os13.homedir(), ".exe-os", "intercom.log");
11174
- DEBOUNCE_FILE = path26.join(SESSION_CACHE, "intercom-debounce.json");
11956
+ INTERCOM_LOG2 = path27.join(os14.homedir(), ".exe-os", "intercom.log");
11957
+ DEBOUNCE_FILE = path27.join(SESSION_CACHE, "intercom-debounce.json");
11175
11958
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
11176
11959
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
11177
11960
  }
@@ -11440,7 +12223,7 @@ __export(active_agent_exports, {
11440
12223
  });
11441
12224
  import { readFileSync as readFileSync19, writeFileSync as writeFileSync15, mkdirSync as mkdirSync16, unlinkSync as unlinkSync9, readdirSync as readdirSync7 } from "fs";
11442
12225
  import { execSync as execSync9 } from "child_process";
11443
- import path27 from "path";
12226
+ import path28 from "path";
11444
12227
  function isNameWithOptionalInstance(candidate, baseName) {
11445
12228
  if (candidate === baseName) return true;
11446
12229
  if (!candidate.startsWith(baseName)) return false;
@@ -11484,7 +12267,7 @@ function resolveActiveAgentFromTmuxSession(sessionName) {
11484
12267
  return null;
11485
12268
  }
11486
12269
  function getMarkerPath() {
11487
- return path27.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
12270
+ return path28.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
11488
12271
  }
11489
12272
  function writeActiveAgent(agentId, agentRole) {
11490
12273
  try {
@@ -11553,14 +12336,14 @@ function getAllActiveAgents() {
11553
12336
  const key = file.slice("active-agent-".length, -".json".length);
11554
12337
  if (key === "undefined") continue;
11555
12338
  try {
11556
- const raw = readFileSync19(path27.join(CACHE_DIR, file), "utf8");
12339
+ const raw = readFileSync19(path28.join(CACHE_DIR, file), "utf8");
11557
12340
  const data = JSON.parse(raw);
11558
12341
  if (!data.agentId) continue;
11559
12342
  if (data.startedAt) {
11560
12343
  const age = Date.now() - new Date(data.startedAt).getTime();
11561
12344
  if (age > STALE_MS) {
11562
12345
  try {
11563
- unlinkSync9(path27.join(CACHE_DIR, file));
12346
+ unlinkSync9(path28.join(CACHE_DIR, file));
11564
12347
  } catch {
11565
12348
  }
11566
12349
  continue;
@@ -11583,11 +12366,11 @@ function getAllActiveAgents() {
11583
12366
  function cleanupSessionMarkers() {
11584
12367
  const key = getSessionKey();
11585
12368
  try {
11586
- unlinkSync9(path27.join(CACHE_DIR, `active-agent-${key}.json`));
12369
+ unlinkSync9(path28.join(CACHE_DIR, `active-agent-${key}.json`));
11587
12370
  } catch {
11588
12371
  }
11589
12372
  try {
11590
- unlinkSync9(path27.join(CACHE_DIR, "active-agent-undefined.json"));
12373
+ unlinkSync9(path28.join(CACHE_DIR, "active-agent-undefined.json"));
11591
12374
  } catch {
11592
12375
  }
11593
12376
  }
@@ -11598,7 +12381,7 @@ var init_active_agent = __esm({
11598
12381
  init_config();
11599
12382
  init_session_key();
11600
12383
  init_employees();
11601
- CACHE_DIR = path27.join(EXE_AI_DIR, "session-cache");
12384
+ CACHE_DIR = path28.join(EXE_AI_DIR, "session-cache");
11602
12385
  STALE_MS = 24 * 60 * 60 * 1e3;
11603
12386
  }
11604
12387
  });
@@ -12228,12 +13011,12 @@ __export(exe_rename_exports, {
12228
13011
  });
12229
13012
  import { readFileSync as readFileSync20, writeFileSync as writeFileSync16, renameSync as renameSync4, unlinkSync as unlinkSync10, existsSync as existsSync22 } from "fs";
12230
13013
  import { execSync as execSync10 } from "child_process";
12231
- import path28 from "path";
13014
+ import path29 from "path";
12232
13015
  import { homedir as homedir4 } from "os";
12233
13016
  async function renameEmployee(oldName, newName, opts = {}) {
12234
- const rosterPath = opts.rosterPath ?? path28.join(homedir4(), ".exe-os", "exe-employees.json");
12235
- const identityDir = opts.identityDir ?? path28.join(homedir4(), ".exe-os", "identity");
12236
- const agentsDir = opts.agentsDir ?? path28.join(homedir4(), ".claude", "agents");
13017
+ const rosterPath = opts.rosterPath ?? path29.join(homedir4(), ".exe-os", "exe-employees.json");
13018
+ const identityDir = opts.identityDir ?? path29.join(homedir4(), ".exe-os", "identity");
13019
+ const agentsDir = opts.agentsDir ?? path29.join(homedir4(), ".claude", "agents");
12237
13020
  const validation = validateEmployeeName(newName);
12238
13021
  if (!validation.valid) {
12239
13022
  return { success: false, error: validation.error };
@@ -12265,8 +13048,8 @@ async function renameEmployee(oldName, newName, opts = {}) {
12265
13048
  writeFileSync16(rosterPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
12266
13049
  }
12267
13050
  });
12268
- const oldIdentityPath = path28.join(identityDir, `${rosterOldName}.md`);
12269
- const newIdentityPath = path28.join(identityDir, `${newName}.md`);
13051
+ const oldIdentityPath = path29.join(identityDir, `${rosterOldName}.md`);
13052
+ const newIdentityPath = path29.join(identityDir, `${newName}.md`);
12270
13053
  if (existsSync22(oldIdentityPath)) {
12271
13054
  const content = readFileSync20(oldIdentityPath, "utf-8");
12272
13055
  const updatedContent = content.replace(
@@ -12285,8 +13068,8 @@ async function renameEmployee(oldName, newName, opts = {}) {
12285
13068
  }
12286
13069
  });
12287
13070
  }
12288
- const oldAgentPath = path28.join(agentsDir, `${rosterOldName}.md`);
12289
- const newAgentPath = path28.join(agentsDir, `${newName}.md`);
13071
+ const oldAgentPath = path29.join(agentsDir, `${rosterOldName}.md`);
13072
+ const newAgentPath = path29.join(agentsDir, `${newName}.md`);
12290
13073
  if (existsSync22(oldAgentPath)) {
12291
13074
  const agentContent = readFileSync20(oldAgentPath, "utf-8");
12292
13075
  renameSync4(oldAgentPath, newAgentPath);
@@ -12373,9 +13156,9 @@ function removeOldSymlinks(name) {
12373
13156
  try {
12374
13157
  const exeBinPath = findExeBin2();
12375
13158
  if (!exeBinPath) return;
12376
- const binDir = path28.dirname(exeBinPath);
13159
+ const binDir = path29.dirname(exeBinPath);
12377
13160
  for (const suffix of ["", "-opencode"]) {
12378
- const linkPath = path28.join(binDir, `${name}${suffix}`);
13161
+ const linkPath = path29.join(binDir, `${name}${suffix}`);
12379
13162
  if (existsSync22(linkPath)) {
12380
13163
  try {
12381
13164
  unlinkSync10(linkPath);
@@ -12424,10 +13207,10 @@ var init_exe_rename = __esm({
12424
13207
  import { createWriteStream, createReadStream as createReadStream2, existsSync as existsSync23, unlinkSync as unlinkSync11, renameSync as renameSync5 } from "fs";
12425
13208
  import { mkdir as mkdir6 } from "fs/promises";
12426
13209
  import { createHash as createHash3 } from "crypto";
12427
- import path29 from "path";
13210
+ import path30 from "path";
12428
13211
  async function downloadModel(opts) {
12429
13212
  const { destDir, onProgress, fetchFn = globalThis.fetch } = opts;
12430
- const destPath = path29.join(destDir, LOCAL_FILENAME);
13213
+ const destPath = path30.join(destDir, LOCAL_FILENAME);
12431
13214
  const tmpPath = destPath + ".tmp";
12432
13215
  await mkdir6(destDir, { recursive: true });
12433
13216
  if (existsSync23(destPath)) {
@@ -12551,8 +13334,8 @@ async function embedDirect(text) {
12551
13334
  const llamaCpp = await import("node-llama-cpp");
12552
13335
  const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
12553
13336
  const { existsSync: existsSync30 } = await import("fs");
12554
- const path44 = await import("path");
12555
- const modelPath = path44.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
13337
+ const path45 = await import("path");
13338
+ const modelPath = path45.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
12556
13339
  if (!existsSync30(modelPath)) {
12557
13340
  throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
12558
13341
  }
@@ -13136,17 +13919,17 @@ import {
13136
13919
  readdirSync as readdirSync8,
13137
13920
  unlinkSync as unlinkSync12
13138
13921
  } from "fs";
13139
- import path30 from "path";
13922
+ import path31 from "path";
13140
13923
  import { homedir as homedir5 } from "os";
13141
13924
  function generateSessionWrappers(packageRoot, homeDir) {
13142
13925
  const home = homeDir ?? homedir5();
13143
- const binDir = path30.join(home, ".exe-os", "bin");
13144
- const rosterPath = path30.join(home, ".exe-os", "exe-employees.json");
13926
+ const binDir = path31.join(home, ".exe-os", "bin");
13927
+ const rosterPath = path31.join(home, ".exe-os", "exe-employees.json");
13145
13928
  mkdirSync17(binDir, { recursive: true });
13146
- const exeStartDst = path30.join(binDir, "exe-start");
13929
+ const exeStartDst = path31.join(binDir, "exe-start");
13147
13930
  const candidates = [
13148
- path30.join(packageRoot, "dist", "bin", "exe-start.sh"),
13149
- path30.join(packageRoot, "src", "bin", "exe-start.sh")
13931
+ path31.join(packageRoot, "dist", "bin", "exe-start.sh"),
13932
+ path31.join(packageRoot, "src", "bin", "exe-start.sh")
13150
13933
  ];
13151
13934
  for (const src of candidates) {
13152
13935
  if (existsSync24(src)) {
@@ -13167,7 +13950,7 @@ function generateSessionWrappers(packageRoot, homeDir) {
13167
13950
  try {
13168
13951
  for (const f of readdirSync8(binDir)) {
13169
13952
  if (f === "exe-start") continue;
13170
- const fPath = path30.join(binDir, f);
13953
+ const fPath = path31.join(binDir, f);
13171
13954
  try {
13172
13955
  const content = readFileSync21(fPath, "utf8");
13173
13956
  if (content.includes("exe-start")) {
@@ -13184,15 +13967,15 @@ exec "${exeStartDst}" "$0" "$@"
13184
13967
  `;
13185
13968
  for (const emp of employees) {
13186
13969
  for (let n = 1; n <= MAX_N; n++) {
13187
- const wrapperPath = path30.join(binDir, `${emp.name}${n}`);
13970
+ const wrapperPath = path31.join(binDir, `${emp.name}${n}`);
13188
13971
  writeFileSync17(wrapperPath, wrapperContent);
13189
13972
  chmodSync(wrapperPath, 493);
13190
13973
  created++;
13191
13974
  }
13192
13975
  }
13193
13976
  const codexLauncherCandidates = [
13194
- path30.join(packageRoot, "dist", "bin", "exe-start-codex.js"),
13195
- path30.join(packageRoot, "src", "bin", "exe-start-codex.ts")
13977
+ path31.join(packageRoot, "dist", "bin", "exe-start-codex.js"),
13978
+ path31.join(packageRoot, "src", "bin", "exe-start-codex.ts")
13196
13979
  ];
13197
13980
  let codexLauncher = null;
13198
13981
  for (const c of codexLauncherCandidates) {
@@ -13203,7 +13986,7 @@ exec "${exeStartDst}" "$0" "$@"
13203
13986
  }
13204
13987
  if (codexLauncher) {
13205
13988
  for (const emp of employees) {
13206
- const wrapperPath = path30.join(binDir, `${emp.name}-codex`);
13989
+ const wrapperPath = path31.join(binDir, `${emp.name}-codex`);
13207
13990
  const content = `#!/bin/bash
13208
13991
  exec node "${codexLauncher}" --agent ${emp.name} "$@"
13209
13992
  `;
@@ -13226,12 +14009,12 @@ export PATH="${binDir}:$PATH"
13226
14009
  const shell = process.env.SHELL ?? "/bin/bash";
13227
14010
  const profilePaths = [];
13228
14011
  if (shell.includes("zsh")) {
13229
- profilePaths.push(path30.join(home, ".zshrc"));
14012
+ profilePaths.push(path31.join(home, ".zshrc"));
13230
14013
  } else if (shell.includes("bash")) {
13231
- profilePaths.push(path30.join(home, ".bashrc"));
13232
- profilePaths.push(path30.join(home, ".bash_profile"));
14014
+ profilePaths.push(path31.join(home, ".bashrc"));
14015
+ profilePaths.push(path31.join(home, ".bash_profile"));
13233
14016
  } else {
13234
- profilePaths.push(path30.join(home, ".profile"));
14017
+ profilePaths.push(path31.join(home, ".profile"));
13235
14018
  }
13236
14019
  for (const profilePath of profilePaths) {
13237
14020
  try {
@@ -13267,14 +14050,14 @@ __export(setup_wizard_exports, {
13267
14050
  });
13268
14051
  import crypto11 from "crypto";
13269
14052
  import { existsSync as existsSync25, mkdirSync as mkdirSync18, readFileSync as readFileSync22, writeFileSync as writeFileSync18, unlinkSync as unlinkSync13 } from "fs";
13270
- import os14 from "os";
13271
- import path31 from "path";
14053
+ import os15 from "os";
14054
+ import path32 from "path";
13272
14055
  import { createInterface as createInterface3 } from "readline";
13273
14056
  function findPackageRoot2() {
13274
- let dir = path31.dirname(new URL(import.meta.url).pathname);
13275
- const root = path31.parse(dir).root;
14057
+ let dir = path32.dirname(new URL(import.meta.url).pathname);
14058
+ const root = path32.parse(dir).root;
13276
14059
  while (dir !== root) {
13277
- const pkgPath = path31.join(dir, "package.json");
14060
+ const pkgPath = path32.join(dir, "package.json");
13278
14061
  if (existsSync25(pkgPath)) {
13279
14062
  try {
13280
14063
  const pkg = JSON.parse(readFileSync22(pkgPath, "utf-8"));
@@ -13282,7 +14065,7 @@ function findPackageRoot2() {
13282
14065
  } catch {
13283
14066
  }
13284
14067
  }
13285
- dir = path31.dirname(dir);
14068
+ dir = path32.dirname(dir);
13286
14069
  }
13287
14070
  return null;
13288
14071
  }
@@ -13294,7 +14077,7 @@ function loadSetupState() {
13294
14077
  }
13295
14078
  }
13296
14079
  function saveSetupState(state) {
13297
- mkdirSync18(path31.dirname(SETUP_STATE_PATH), { recursive: true });
14080
+ mkdirSync18(path32.dirname(SETUP_STATE_PATH), { recursive: true });
13298
14081
  writeFileSync18(SETUP_STATE_PATH, JSON.stringify(state, null, 2));
13299
14082
  }
13300
14083
  function clearSetupState() {
@@ -13314,10 +14097,10 @@ function ask2(rl, prompt) {
13314
14097
  });
13315
14098
  }
13316
14099
  function getAvailableMemoryGB() {
13317
- return os14.freemem() / (1024 * 1024 * 1024);
14100
+ return os15.freemem() / (1024 * 1024 * 1024);
13318
14101
  }
13319
14102
  function getTotalMemoryGB() {
13320
- return os14.totalmem() / (1024 * 1024 * 1024);
14103
+ return os15.totalmem() / (1024 * 1024 * 1024);
13321
14104
  }
13322
14105
  function isLowMemory() {
13323
14106
  return getAvailableMemoryGB() < 2;
@@ -13328,7 +14111,7 @@ async function validateModel(log) {
13328
14111
  if (totalGB <= 8 || isLowMemory()) {
13329
14112
  log(`System memory: ${totalGB.toFixed(0)}GB total, ${freeGB.toFixed(1)}GB free`);
13330
14113
  log("Skipping in-memory model validation (low memory \u2014 will validate on first use).");
13331
- const modelPath = path31.join(MODELS_DIR, LOCAL_FILENAME);
14114
+ const modelPath = path32.join(MODELS_DIR, LOCAL_FILENAME);
13332
14115
  if (existsSync25(modelPath)) {
13333
14116
  const { statSync: statSync2 } = await import("fs");
13334
14117
  const size = statSync2(modelPath).size;
@@ -13584,7 +14367,7 @@ async function runSetupWizard(opts = {}) {
13584
14367
  await saveConfig(config);
13585
14368
  log("");
13586
14369
  try {
13587
- const claudeJsonPath = path31.join(os14.homedir(), ".claude.json");
14370
+ const claudeJsonPath = path32.join(os15.homedir(), ".claude.json");
13588
14371
  let claudeJson = {};
13589
14372
  try {
13590
14373
  claudeJson = JSON.parse(readFileSync22(claudeJsonPath, "utf8"));
@@ -13592,7 +14375,7 @@ async function runSetupWizard(opts = {}) {
13592
14375
  }
13593
14376
  if (!claudeJson.projects) claudeJson.projects = {};
13594
14377
  const projects = claudeJson.projects;
13595
- for (const dir of [process.cwd(), os14.homedir()]) {
14378
+ for (const dir of [process.cwd(), os15.homedir()]) {
13596
14379
  if (!projects[dir]) projects[dir] = {};
13597
14380
  projects[dir].hasTrustDialogAccepted = true;
13598
14381
  }
@@ -13610,7 +14393,7 @@ async function runSetupWizard(opts = {}) {
13610
14393
  const prefs = { ...existingPrefs };
13611
14394
  log("=== Config Defaults ===");
13612
14395
  log("");
13613
- const ghosttyDetected = existsSync25(path31.join(os14.homedir(), ".config", "ghostty")) || existsSync25(path31.join(os14.homedir(), "Library", "Application Support", "com.mitchellh.ghostty"));
14396
+ const ghosttyDetected = existsSync25(path32.join(os15.homedir(), ".config", "ghostty")) || existsSync25(path32.join(os15.homedir(), "Library", "Application Support", "com.mitchellh.ghostty"));
13614
14397
  if (ghosttyDetected) {
13615
14398
  const ghosttyAnswer = await ask2(rl, "Detected Ghostty terminal. Use exe-os Ghostty defaults? (Y/n) ");
13616
14399
  prefs.ghostty = ghosttyAnswer.toLowerCase() !== "n";
@@ -13754,7 +14537,7 @@ async function runSetupWizard(opts = {}) {
13754
14537
  const cooIdentityContent = getIdentityTemplate("coo");
13755
14538
  if (cooIdentityContent) {
13756
14539
  const cooIdPath = identityPath2(cooName);
13757
- mkdirSync18(path31.dirname(cooIdPath), { recursive: true });
14540
+ mkdirSync18(path32.dirname(cooIdPath), { recursive: true });
13758
14541
  const replaced = cooIdentityContent.replace(/agent_id:\s*exe/g, `agent_id: ${cooName}`).replace(/\$\{agent_id\}/g, cooName);
13759
14542
  writeFileSync18(cooIdPath, replaced, "utf-8");
13760
14543
  }
@@ -13850,7 +14633,7 @@ async function runSetupWizard(opts = {}) {
13850
14633
  const ctoIdentityContent = getIdentityTemplate("cto");
13851
14634
  if (ctoIdentityContent) {
13852
14635
  const ctoIdPath = identityPath2(ctoName);
13853
- mkdirSync18(path31.dirname(ctoIdPath), { recursive: true });
14636
+ mkdirSync18(path32.dirname(ctoIdPath), { recursive: true });
13854
14637
  const replaced = ctoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${ctoName}`).replace(/\$\{agent_id\}/g, ctoName);
13855
14638
  writeFileSync18(ctoIdPath, replaced, "utf-8");
13856
14639
  }
@@ -13873,7 +14656,7 @@ async function runSetupWizard(opts = {}) {
13873
14656
  const cmoIdentityContent = getIdentityTemplate("cmo");
13874
14657
  if (cmoIdentityContent) {
13875
14658
  const cmoIdPath = identityPath2(cmoName);
13876
- mkdirSync18(path31.dirname(cmoIdPath), { recursive: true });
14659
+ mkdirSync18(path32.dirname(cmoIdPath), { recursive: true });
13877
14660
  const replaced = cmoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${cmoName}`).replace(/\$\{agent_id\}/g, cmoName);
13878
14661
  writeFileSync18(cmoIdPath, replaced, "utf-8");
13879
14662
  }
@@ -13897,7 +14680,7 @@ async function runSetupWizard(opts = {}) {
13897
14680
  log(`Session shortcuts generated (${cooName}1, ${cooName}2, ...)`);
13898
14681
  }
13899
14682
  if (wrapResult.pathConfigured) {
13900
- const binDir = path31.join(os14.homedir(), ".exe-os", "bin");
14683
+ const binDir = path32.join(os15.homedir(), ".exe-os", "bin");
13901
14684
  process.env.PATH = `${binDir}:${process.env.PATH ?? ""}`;
13902
14685
  pathJustConfigured = true;
13903
14686
  }
@@ -13940,7 +14723,7 @@ async function runSetupWizard(opts = {}) {
13940
14723
  const pkgRoot2 = findPackageRoot2();
13941
14724
  if (pkgRoot2) {
13942
14725
  try {
13943
- version = JSON.parse(readFileSync22(path31.join(pkgRoot2, "package.json"), "utf-8")).version;
14726
+ version = JSON.parse(readFileSync22(path32.join(pkgRoot2, "package.json"), "utf-8")).version;
13944
14727
  } catch {
13945
14728
  }
13946
14729
  }
@@ -13974,16 +14757,16 @@ var init_setup_wizard = __esm({
13974
14757
  init_config();
13975
14758
  init_keychain();
13976
14759
  init_model_downloader();
13977
- SETUP_STATE_PATH = path31.join(os14.homedir(), ".exe-os", "setup-state.json");
14760
+ SETUP_STATE_PATH = path32.join(os15.homedir(), ".exe-os", "setup-state.json");
13978
14761
  }
13979
14762
  });
13980
14763
 
13981
14764
  // src/lib/update-check.ts
13982
14765
  import { execSync as execSync11 } from "child_process";
13983
14766
  import { readFileSync as readFileSync23 } from "fs";
13984
- import path32 from "path";
14767
+ import path33 from "path";
13985
14768
  function getLocalVersion(packageRoot) {
13986
- const pkgPath = path32.join(packageRoot, "package.json");
14769
+ const pkgPath = path33.join(packageRoot, "package.json");
13987
14770
  const pkg = JSON.parse(readFileSync23(pkgPath, "utf-8"));
13988
14771
  return pkg.version;
13989
14772
  }
@@ -18508,8 +19291,8 @@ var init_ErrorOverview = __esm({
18508
19291
  "use strict";
18509
19292
  init_Box();
18510
19293
  init_Text();
18511
- cleanupPath = (path44) => {
18512
- return path44?.replace(`file://${cwd()}/`, "");
19294
+ cleanupPath = (path45) => {
19295
+ return path45?.replace(`file://${cwd()}/`, "");
18513
19296
  };
18514
19297
  stackUtils = new StackUtils({
18515
19298
  cwd: cwd(),
@@ -22963,10 +23746,10 @@ var init_hooks = __esm({
22963
23746
  });
22964
23747
 
22965
23748
  // src/runtime/safety-checks.ts
22966
- import path33 from "path";
22967
- import os15 from "os";
23749
+ import path34 from "path";
23750
+ import os16 from "os";
22968
23751
  function checkPathSafety(filePath) {
22969
- const resolved = path33.resolve(filePath);
23752
+ const resolved = path34.resolve(filePath);
22970
23753
  for (const { pattern, reason } of BYPASS_IMMUNE_PATTERNS) {
22971
23754
  const matches = typeof pattern === "function" ? pattern(resolved) : pattern.test(resolved);
22972
23755
  if (matches) {
@@ -22976,7 +23759,7 @@ function checkPathSafety(filePath) {
22976
23759
  return { safe: true, bypassImmune: true };
22977
23760
  }
22978
23761
  function checkReadPathSafety(filePath) {
22979
- const resolved = path33.resolve(filePath);
23762
+ const resolved = path34.resolve(filePath);
22980
23763
  const credPatterns = BYPASS_IMMUNE_PATTERNS.filter(
22981
23764
  (p) => typeof p.pattern !== "function" && (p.reason.includes("secrets") || p.reason.includes("Private key") || p.reason.includes("Credential"))
22982
23765
  );
@@ -22991,7 +23774,7 @@ var HOME, BYPASS_IMMUNE_PATTERNS;
22991
23774
  var init_safety_checks = __esm({
22992
23775
  "src/runtime/safety-checks.ts"() {
22993
23776
  "use strict";
22994
- HOME = os15.homedir();
23777
+ HOME = os16.homedir();
22995
23778
  BYPASS_IMMUNE_PATTERNS = [
22996
23779
  {
22997
23780
  pattern: /\/\.git\/hooks\//,
@@ -23002,11 +23785,11 @@ var init_safety_checks = __esm({
23002
23785
  reason: "Git config can set hooks and command execution"
23003
23786
  },
23004
23787
  {
23005
- pattern: (p) => p.startsWith(path33.join(HOME, ".claude")),
23788
+ pattern: (p) => p.startsWith(path34.join(HOME, ".claude")),
23006
23789
  reason: "Claude configuration files are protected"
23007
23790
  },
23008
23791
  {
23009
- pattern: (p) => p.startsWith(path33.join(HOME, ".exe-os")),
23792
+ pattern: (p) => p.startsWith(path34.join(HOME, ".exe-os")),
23010
23793
  reason: "exe-os configuration files are protected"
23011
23794
  },
23012
23795
  {
@@ -23023,7 +23806,7 @@ var init_safety_checks = __esm({
23023
23806
  },
23024
23807
  {
23025
23808
  pattern: (p) => {
23026
- const name = path33.basename(p);
23809
+ const name = path34.basename(p);
23027
23810
  return [".bashrc", ".zshrc", ".profile", ".bash_profile", ".zprofile", ".zshenv"].includes(name);
23028
23811
  },
23029
23812
  reason: "Shell configuration files can execute arbitrary code on login"
@@ -23050,7 +23833,7 @@ __export(file_read_exports, {
23050
23833
  FileReadTool: () => FileReadTool
23051
23834
  });
23052
23835
  import fs3 from "fs/promises";
23053
- import path34 from "path";
23836
+ import path35 from "path";
23054
23837
  import { z } from "zod";
23055
23838
  function isBinary(buf) {
23056
23839
  for (let i = 0; i < buf.length; i++) {
@@ -23086,7 +23869,7 @@ var init_file_read = __esm({
23086
23869
  return { behavior: "allow" };
23087
23870
  },
23088
23871
  async call(input, context) {
23089
- const filePath = path34.isAbsolute(input.file_path) ? input.file_path : path34.resolve(context.cwd, input.file_path);
23872
+ const filePath = path35.isAbsolute(input.file_path) ? input.file_path : path35.resolve(context.cwd, input.file_path);
23090
23873
  let stat2;
23091
23874
  try {
23092
23875
  stat2 = await fs3.stat(filePath);
@@ -23126,7 +23909,7 @@ __export(glob_exports, {
23126
23909
  GlobTool: () => GlobTool
23127
23910
  });
23128
23911
  import fs4 from "fs/promises";
23129
- import path35 from "path";
23912
+ import path36 from "path";
23130
23913
  import { z as z2 } from "zod";
23131
23914
  async function walkDir(dir, maxDepth = 10) {
23132
23915
  const results = [];
@@ -23142,7 +23925,7 @@ async function walkDir(dir, maxDepth = 10) {
23142
23925
  if (entry.isDirectory() && (entry.name === "node_modules" || entry.name === ".git")) {
23143
23926
  continue;
23144
23927
  }
23145
- const fullPath = path35.join(current, entry.name);
23928
+ const fullPath = path36.join(current, entry.name);
23146
23929
  if (entry.isDirectory()) {
23147
23930
  await walk(fullPath, depth + 1);
23148
23931
  } else {
@@ -23176,11 +23959,11 @@ var init_glob = __esm({
23176
23959
  inputSchema: inputSchema2,
23177
23960
  isReadOnly: true,
23178
23961
  async call(input, context) {
23179
- const baseDir = input.path ? path35.isAbsolute(input.path) ? input.path : path35.resolve(context.cwd, input.path) : context.cwd;
23962
+ const baseDir = input.path ? path36.isAbsolute(input.path) ? input.path : path36.resolve(context.cwd, input.path) : context.cwd;
23180
23963
  try {
23181
23964
  const entries = await walkDir(baseDir);
23182
23965
  const matched = entries.filter(
23183
- (e) => simpleGlobMatch(path35.relative(baseDir, e.path), input.pattern)
23966
+ (e) => simpleGlobMatch(path36.relative(baseDir, e.path), input.pattern)
23184
23967
  );
23185
23968
  matched.sort((a, b) => b.mtime - a.mtime);
23186
23969
  if (matched.length === 0) {
@@ -23206,7 +23989,7 @@ __export(grep_exports, {
23206
23989
  });
23207
23990
  import { spawn as spawn2 } from "child_process";
23208
23991
  import fs5 from "fs/promises";
23209
- import path36 from "path";
23992
+ import path37 from "path";
23210
23993
  import { z as z3 } from "zod";
23211
23994
  function runRipgrep(input, searchPath, context) {
23212
23995
  return new Promise((resolve, reject) => {
@@ -23260,7 +24043,7 @@ async function nodeGrep(input, searchPath) {
23260
24043
  }
23261
24044
  for (const entry of entries) {
23262
24045
  if (entry.name === "node_modules" || entry.name === ".git") continue;
23263
- const fullPath = path36.join(dir, entry.name);
24046
+ const fullPath = path37.join(dir, entry.name);
23264
24047
  if (entry.isDirectory()) {
23265
24048
  await walk(fullPath);
23266
24049
  } else {
@@ -23306,7 +24089,7 @@ var init_grep = __esm({
23306
24089
  inputSchema: inputSchema3,
23307
24090
  isReadOnly: true,
23308
24091
  async call(input, context) {
23309
- const searchPath = input.path ? path36.isAbsolute(input.path) ? input.path : path36.resolve(context.cwd, input.path) : context.cwd;
24092
+ const searchPath = input.path ? path37.isAbsolute(input.path) ? input.path : path37.resolve(context.cwd, input.path) : context.cwd;
23310
24093
  try {
23311
24094
  const result = await runRipgrep(input, searchPath, context);
23312
24095
  return result;
@@ -23331,7 +24114,7 @@ __export(file_write_exports, {
23331
24114
  FileWriteTool: () => FileWriteTool
23332
24115
  });
23333
24116
  import fs6 from "fs/promises";
23334
- import path37 from "path";
24117
+ import path38 from "path";
23335
24118
  import { z as z4 } from "zod";
23336
24119
  var inputSchema4, FileWriteTool;
23337
24120
  var init_file_write = __esm({
@@ -23359,8 +24142,8 @@ var init_file_write = __esm({
23359
24142
  return { behavior: "allow" };
23360
24143
  },
23361
24144
  async call(input, context) {
23362
- const filePath = path37.isAbsolute(input.file_path) ? input.file_path : path37.resolve(context.cwd, input.file_path);
23363
- const dir = path37.dirname(filePath);
24145
+ const filePath = path38.isAbsolute(input.file_path) ? input.file_path : path38.resolve(context.cwd, input.file_path);
24146
+ const dir = path38.dirname(filePath);
23364
24147
  await fs6.mkdir(dir, { recursive: true });
23365
24148
  await fs6.writeFile(filePath, input.content, "utf-8");
23366
24149
  return {
@@ -23378,7 +24161,7 @@ __export(file_edit_exports, {
23378
24161
  FileEditTool: () => FileEditTool
23379
24162
  });
23380
24163
  import fs7 from "fs/promises";
23381
- import path38 from "path";
24164
+ import path39 from "path";
23382
24165
  import { z as z5 } from "zod";
23383
24166
  function countOccurrences(haystack, needle) {
23384
24167
  let count = 0;
@@ -23419,7 +24202,7 @@ var init_file_edit = __esm({
23419
24202
  return { behavior: "allow" };
23420
24203
  },
23421
24204
  async call(input, context) {
23422
- const filePath = path38.isAbsolute(input.file_path) ? input.file_path : path38.resolve(context.cwd, input.file_path);
24205
+ const filePath = path39.isAbsolute(input.file_path) ? input.file_path : path39.resolve(context.cwd, input.file_path);
23423
24206
  let content;
23424
24207
  try {
23425
24208
  content = await fs7.readFile(filePath, "utf-8");
@@ -23661,7 +24444,7 @@ var init_bash = __esm({
23661
24444
  // src/tui/views/CommandCenter.tsx
23662
24445
  import { useState as useState6, useEffect as useEffect8, useMemo as useMemo4, useCallback as useCallback4, useRef as useRef4 } from "react";
23663
24446
  import TextInput from "ink-text-input";
23664
- import path39 from "path";
24447
+ import path40 from "path";
23665
24448
  import { homedir as homedir6 } from "os";
23666
24449
  import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
23667
24450
  function CommandCenterView({
@@ -23910,7 +24693,7 @@ function CommandCenterView({
23910
24693
  const demoEntries = DEMO_PROJECTS.map((p) => ({
23911
24694
  projectName: p.projectName,
23912
24695
  exeSession: p.exeSession,
23913
- projectDir: path39.join(homedir6(), p.projectName),
24696
+ projectDir: path40.join(homedir6(), p.projectName),
23914
24697
  employeeCount: p.employees.length,
23915
24698
  activeCount: p.employees.filter((e) => e.status === "active").length,
23916
24699
  memoryCount: p.employees.length * 4e3,
@@ -24914,7 +25697,7 @@ var init_useOrchestrator = __esm({
24914
25697
 
24915
25698
  // src/tui/views/Sessions.tsx
24916
25699
  import React19, { useState as useState9, useEffect as useEffect11, useCallback as useCallback6 } from "react";
24917
- import path40 from "path";
25700
+ import path41 from "path";
24918
25701
  import { homedir as homedir7 } from "os";
24919
25702
  import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
24920
25703
  function isCoordinatorEntry(entry) {
@@ -24952,7 +25735,7 @@ function SessionsView({
24952
25735
  if (demo) {
24953
25736
  setProjects(DEMO_PROJECTS.map((p) => ({
24954
25737
  ...p,
24955
- projectDir: path40.join(homedir7(), p.projectName),
25738
+ projectDir: path41.join(homedir7(), p.projectName),
24956
25739
  employees: p.employees.map((e) => ({ ...e, attached: e.status === "active" }))
24957
25740
  })));
24958
25741
  return;
@@ -26870,8 +27653,8 @@ __export(wiki_client_exports, {
26870
27653
  listDocuments: () => listDocuments,
26871
27654
  listWorkspaces: () => listWorkspaces
26872
27655
  });
26873
- async function wikiFetch(config, path44, method = "GET", body) {
26874
- const url = `${config.baseUrl}/api/v1${path44}`;
27656
+ async function wikiFetch(config, path45, method = "GET", body) {
27657
+ const url = `${config.baseUrl}/api/v1${path45}`;
26875
27658
  const headers = {
26876
27659
  Authorization: `Bearer ${config.apiKey}`,
26877
27660
  "Content-Type": "application/json"
@@ -26904,7 +27687,7 @@ async function wikiFetch(config, path44, method = "GET", body) {
26904
27687
  }
26905
27688
  }
26906
27689
  if (!response.ok) {
26907
- throw new Error(`Wiki API ${method} ${path44}: ${response.status} ${response.statusText}`);
27690
+ throw new Error(`Wiki API ${method} ${path45}: ${response.status} ${response.statusText}`);
26908
27691
  }
26909
27692
  return response.json();
26910
27693
  } finally {
@@ -27538,8 +28321,8 @@ function SettingsView({ onBack }) {
27538
28321
  let version = "unknown";
27539
28322
  try {
27540
28323
  const { readFileSync: readFileSync27 } = await import("fs");
27541
- const { createRequire } = await import("module");
27542
- const require2 = createRequire(import.meta.url);
28324
+ const { createRequire: createRequire2 } = await import("module");
28325
+ const require2 = createRequire2(import.meta.url);
27543
28326
  const pkgPath = require2.resolve("@askexenow/exe-os/package.json");
27544
28327
  const pkg = JSON.parse(readFileSync27(pkgPath, "utf8"));
27545
28328
  version = pkg.version;
@@ -28349,11 +29132,11 @@ __export(installer_exports2, {
28349
29132
  });
28350
29133
  import { readFile as readFile6, writeFile as writeFile7, mkdir as mkdir7 } from "fs/promises";
28351
29134
  import { existsSync as existsSync27, readFileSync as readFileSync25 } from "fs";
28352
- import path41 from "path";
28353
- import os16 from "os";
28354
- async function registerOpenCodeMcp(packageRoot, homeDir = os16.homedir()) {
28355
- const configDir = path41.join(homeDir, ".config", "opencode");
28356
- const configPath = path41.join(configDir, "opencode.json");
29135
+ import path42 from "path";
29136
+ import os17 from "os";
29137
+ async function registerOpenCodeMcp(packageRoot, homeDir = os17.homedir()) {
29138
+ const configDir = path42.join(homeDir, ".config", "opencode");
29139
+ const configPath = path42.join(configDir, "opencode.json");
28357
29140
  await mkdir7(configDir, { recursive: true });
28358
29141
  let config = {};
28359
29142
  if (existsSync27(configPath)) {
@@ -28368,7 +29151,7 @@ async function registerOpenCodeMcp(packageRoot, homeDir = os16.homedir()) {
28368
29151
  }
28369
29152
  const newEntry = {
28370
29153
  type: "local",
28371
- command: ["node", path41.join(packageRoot, "dist", "mcp", "server.js")],
29154
+ command: ["node", path42.join(packageRoot, "dist", "mcp", "server.js")],
28372
29155
  enabled: true
28373
29156
  };
28374
29157
  const current = config.mcp["exe-os"];
@@ -28382,9 +29165,9 @@ async function registerOpenCodeMcp(packageRoot, homeDir = os16.homedir()) {
28382
29165
  await writeFile7(configPath, JSON.stringify(config, null, 2) + "\n");
28383
29166
  return true;
28384
29167
  }
28385
- async function installOpenCodePlugin(packageRoot, homeDir = os16.homedir()) {
28386
- const pluginDir = path41.join(homeDir, ".config", "opencode", "plugins");
28387
- const pluginPath = path41.join(pluginDir, "exe-os.mjs");
29168
+ async function installOpenCodePlugin(packageRoot, homeDir = os17.homedir()) {
29169
+ const pluginDir = path42.join(homeDir, ".config", "opencode", "plugins");
29170
+ const pluginPath = path42.join(pluginDir, "exe-os.mjs");
28388
29171
  await mkdir7(pluginDir, { recursive: true });
28389
29172
  const pluginContent = PLUGIN_TEMPLATE.replace(
28390
29173
  /__PACKAGE_ROOT__/g,
@@ -28399,9 +29182,9 @@ async function installOpenCodePlugin(packageRoot, homeDir = os16.homedir()) {
28399
29182
  await writeFile7(pluginPath, pluginContent);
28400
29183
  return true;
28401
29184
  }
28402
- function verifyOpenCodeHooks(homeDir = os16.homedir()) {
28403
- const configPath = path41.join(homeDir, ".config", "opencode", "opencode.json");
28404
- const pluginPath = path41.join(homeDir, ".config", "opencode", "plugins", "exe-os.mjs");
29185
+ function verifyOpenCodeHooks(homeDir = os17.homedir()) {
29186
+ const configPath = path42.join(homeDir, ".config", "opencode", "opencode.json");
29187
+ const pluginPath = path42.join(homeDir, ".config", "opencode", "plugins", "exe-os.mjs");
28405
29188
  if (!existsSync27(configPath)) return false;
28406
29189
  try {
28407
29190
  const config = JSON.parse(readFileSync25(configPath, "utf-8"));
@@ -28443,13 +29226,13 @@ __export(installer_exports3, {
28443
29226
  });
28444
29227
  import { readFile as readFile7, writeFile as writeFile8, mkdir as mkdir8 } from "fs/promises";
28445
29228
  import { existsSync as existsSync28 } from "fs";
28446
- import path42 from "path";
28447
- import os17 from "os";
28448
- async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28449
- const codexDir = path42.join(homeDir, ".codex");
28450
- const hooksPath = path42.join(codexDir, "hooks.json");
28451
- const logsDir = path42.join(homeDir, ".exe-os", "logs");
28452
- const hookLogPath = path42.join(logsDir, "hooks.log");
29229
+ import path43 from "path";
29230
+ import os18 from "os";
29231
+ async function mergeCodexHooks(packageRoot, homeDir = os18.homedir()) {
29232
+ const codexDir = path43.join(homeDir, ".codex");
29233
+ const hooksPath = path43.join(codexDir, "hooks.json");
29234
+ const logsDir = path43.join(homeDir, ".exe-os", "logs");
29235
+ const hookLogPath = path43.join(logsDir, "hooks.log");
28453
29236
  const logSuffix = ` 2>> "${hookLogPath}"`;
28454
29237
  await mkdir8(codexDir, { recursive: true });
28455
29238
  await mkdir8(logsDir, { recursive: true });
@@ -28471,7 +29254,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28471
29254
  hooks: [
28472
29255
  {
28473
29256
  type: "command",
28474
- command: `node "${path42.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
29257
+ command: `node "${path43.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
28475
29258
  timeout: 30,
28476
29259
  statusMessage: "exe-os: loading memory brief"
28477
29260
  }
@@ -28486,11 +29269,11 @@ async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28486
29269
  hooks: [
28487
29270
  {
28488
29271
  type: "command",
28489
- command: `node "${path42.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
29272
+ command: `node "${path43.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
28490
29273
  },
28491
29274
  {
28492
29275
  type: "command",
28493
- command: `node "${path42.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
29276
+ command: `node "${path43.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
28494
29277
  }
28495
29278
  ]
28496
29279
  },
@@ -28502,11 +29285,11 @@ async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28502
29285
  hooks: [
28503
29286
  {
28504
29287
  type: "command",
28505
- command: `node "${path42.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
29288
+ command: `node "${path43.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
28506
29289
  },
28507
29290
  {
28508
29291
  type: "command",
28509
- command: `node "${path42.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
29292
+ command: `node "${path43.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
28510
29293
  timeout: 5
28511
29294
  }
28512
29295
  ]
@@ -28519,7 +29302,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28519
29302
  hooks: [
28520
29303
  {
28521
29304
  type: "command",
28522
- command: `node "${path42.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
29305
+ command: `node "${path43.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
28523
29306
  }
28524
29307
  ]
28525
29308
  },
@@ -28532,7 +29315,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28532
29315
  hooks: [
28533
29316
  {
28534
29317
  type: "command",
28535
- command: `node "${path42.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
29318
+ command: `node "${path43.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
28536
29319
  }
28537
29320
  ]
28538
29321
  },
@@ -28563,15 +29346,15 @@ async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28563
29346
  await writeFile8(hooksPath, JSON.stringify(hooksJson, null, 2) + "\n");
28564
29347
  return { added, skipped };
28565
29348
  }
28566
- function verifyCodexHooks(homeDir = os17.homedir()) {
28567
- const hooksPath = path42.join(homeDir, ".codex", "hooks.json");
29349
+ function verifyCodexHooks(homeDir = os18.homedir()) {
29350
+ const hooksPath = path43.join(homeDir, ".codex", "hooks.json");
28568
29351
  if (!existsSync28(hooksPath)) return false;
28569
29352
  try {
28570
29353
  const hooksJson = JSON.parse(
28571
29354
  __require("fs").readFileSync(hooksPath, "utf-8")
28572
29355
  );
28573
29356
  if (!hooksJson.hooks) return false;
28574
- const required = ["SessionStart", "PostToolUse", "UserPromptSubmit", "Stop"];
29357
+ const required = ["SessionStart", "PostToolUse", "UserPromptSubmit", "Stop", "PreToolUse"];
28575
29358
  for (const event of required) {
28576
29359
  const groups = hooksJson.hooks[event];
28577
29360
  if (!groups || !groups.some(
@@ -28585,11 +29368,11 @@ function verifyCodexHooks(homeDir = os17.homedir()) {
28585
29368
  return false;
28586
29369
  }
28587
29370
  }
28588
- async function installCodexStatusLine(homeDir = os17.homedir()) {
29371
+ async function installCodexStatusLine(homeDir = os18.homedir()) {
28589
29372
  const prefs = loadPreferences(homeDir);
28590
29373
  if (prefs.codexStatusLine === false) return "opted-out";
28591
- const codexDir = path42.join(homeDir, ".codex");
28592
- const configPath = path42.join(codexDir, "config.toml");
29374
+ const codexDir = path43.join(homeDir, ".codex");
29375
+ const configPath = path43.join(codexDir, "config.toml");
28593
29376
  await mkdir8(codexDir, { recursive: true });
28594
29377
  let content = "";
28595
29378
  if (existsSync28(configPath)) {
@@ -28641,12 +29424,12 @@ var init_installer3 = __esm({
28641
29424
 
28642
29425
  // src/bin/cli.ts
28643
29426
  import { existsSync as existsSync29, readFileSync as readFileSync26, writeFileSync as writeFileSync19, readdirSync as readdirSync9, rmSync } from "fs";
28644
- import path43 from "path";
28645
- import os18 from "os";
29427
+ import path44 from "path";
29428
+ import os19 from "os";
28646
29429
  var args = process.argv.slice(2);
28647
29430
  if (args.includes("--version") || args.includes("-v")) {
28648
29431
  try {
28649
- const pkgPath = path43.join(path43.dirname(new URL(import.meta.url).pathname), "..", "..", "package.json");
29432
+ const pkgPath = path44.join(path44.dirname(new URL(import.meta.url).pathname), "..", "..", "package.json");
28650
29433
  const pkg = JSON.parse(readFileSync26(pkgPath, "utf8"));
28651
29434
  console.log(pkg.version);
28652
29435
  } catch {
@@ -28811,8 +29594,8 @@ ID: ${result.id}`);
28811
29594
  });
28812
29595
  await init_App2().then(() => App_exports);
28813
29596
  } else {
28814
- const claudeDir = path43.join(os18.homedir(), ".claude");
28815
- const settingsPath = path43.join(claudeDir, "settings.json");
29597
+ const claudeDir = path44.join(os19.homedir(), ".claude");
29598
+ const settingsPath = path44.join(claudeDir, "settings.json");
28816
29599
  const hasClaudeCode = existsSync29(settingsPath) && (() => {
28817
29600
  try {
28818
29601
  const raw = readFileSync26(settingsPath, "utf8");
@@ -28825,7 +29608,7 @@ ID: ${result.id}`);
28825
29608
  const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
28826
29609
  let cooName = DEFAULT_COORDINATOR_TEMPLATE_NAME2;
28827
29610
  try {
28828
- const rosterPath = path43.join(os18.homedir(), ".exe-os", "exe-employees.json");
29611
+ const rosterPath = path44.join(os19.homedir(), ".exe-os", "exe-employees.json");
28829
29612
  if (existsSync29(rosterPath)) {
28830
29613
  const roster = JSON.parse(readFileSync26(rosterPath, "utf8"));
28831
29614
  const coo = roster.find((e) => e.role === "COO");
@@ -28891,9 +29674,9 @@ async function runCodexInstall() {
28891
29674
  }
28892
29675
  }
28893
29676
  async function runClaudeCheck() {
28894
- const claudeDir = path43.join(os18.homedir(), ".claude");
28895
- const settingsPath = path43.join(claudeDir, "settings.json");
28896
- const claudeJsonPath = path43.join(os18.homedir(), ".claude.json");
29677
+ const claudeDir = path44.join(os19.homedir(), ".claude");
29678
+ const settingsPath = path44.join(claudeDir, "settings.json");
29679
+ const claudeJsonPath = path44.join(os19.homedir(), ".claude.json");
28897
29680
  let ok = true;
28898
29681
  if (existsSync29(settingsPath)) {
28899
29682
  let settings;
@@ -28946,7 +29729,7 @@ async function runClaudeCheck() {
28946
29729
  console.log("\x1B[31m\u2717\x1B[0m claude.json not found");
28947
29730
  ok = false;
28948
29731
  }
28949
- const skillsDir = path43.join(claudeDir, "skills");
29732
+ const skillsDir = path44.join(claudeDir, "skills");
28950
29733
  if (existsSync29(skillsDir)) {
28951
29734
  console.log("\x1B[32m\u2713\x1B[0m Slash skills directory exists");
28952
29735
  } else {
@@ -28963,11 +29746,11 @@ async function runClaudeCheck() {
28963
29746
  async function runClaudeUninstall(flags = []) {
28964
29747
  const dryRun = flags.includes("--dry-run");
28965
29748
  const purge = flags.includes("--purge");
28966
- const homeDir = os18.homedir();
28967
- const claudeDir = path43.join(homeDir, ".claude");
28968
- const settingsPath = path43.join(claudeDir, "settings.json");
28969
- const claudeJsonPath = path43.join(homeDir, ".claude.json");
28970
- const exeOsDir = path43.join(homeDir, ".exe-os");
29749
+ const homeDir = os19.homedir();
29750
+ const claudeDir = path44.join(homeDir, ".claude");
29751
+ const settingsPath = path44.join(claudeDir, "settings.json");
29752
+ const claudeJsonPath = path44.join(homeDir, ".claude.json");
29753
+ const exeOsDir = path44.join(homeDir, ".exe-os");
28971
29754
  let removed = 0;
28972
29755
  const log = (msg) => console.log(dryRun ? `[dry-run] ${msg}` : msg);
28973
29756
  let settings = {};
@@ -29048,14 +29831,14 @@ async function runClaudeUninstall(flags = []) {
29048
29831
  }
29049
29832
  }
29050
29833
  }
29051
- const skillsDir = path43.join(claudeDir, "skills");
29834
+ const skillsDir = path44.join(claudeDir, "skills");
29052
29835
  if (existsSync29(skillsDir)) {
29053
29836
  let skillCount = 0;
29054
29837
  try {
29055
29838
  const entries = readdirSync9(skillsDir);
29056
29839
  for (const entry of entries) {
29057
29840
  if (entry.startsWith("exe")) {
29058
- const fullPath = path43.join(skillsDir, entry);
29841
+ const fullPath = path44.join(skillsDir, entry);
29059
29842
  if (!dryRun) rmSync(fullPath, { recursive: true, force: true });
29060
29843
  skillCount++;
29061
29844
  }
@@ -29067,7 +29850,7 @@ async function runClaudeUninstall(flags = []) {
29067
29850
  removed++;
29068
29851
  }
29069
29852
  }
29070
- const claudeMdPath = path43.join(claudeDir, "CLAUDE.md");
29853
+ const claudeMdPath = path44.join(claudeDir, "CLAUDE.md");
29071
29854
  if (existsSync29(claudeMdPath)) {
29072
29855
  const content = readFileSync26(claudeMdPath, "utf8");
29073
29856
  const startMarker = "<!-- exe-os:orchestration-start -->";
@@ -29081,13 +29864,13 @@ async function runClaudeUninstall(flags = []) {
29081
29864
  removed++;
29082
29865
  }
29083
29866
  }
29084
- const agentsDir = path43.join(claudeDir, "agents");
29867
+ const agentsDir = path44.join(claudeDir, "agents");
29085
29868
  if (existsSync29(agentsDir)) {
29086
29869
  let agentCount = 0;
29087
29870
  try {
29088
29871
  const entries = readdirSync9(agentsDir).filter((f) => f.endsWith(".md"));
29089
29872
  let knownNames = /* @__PURE__ */ new Set();
29090
- const rosterPath = path43.join(exeOsDir, "exe-employees.json");
29873
+ const rosterPath = path44.join(exeOsDir, "exe-employees.json");
29091
29874
  if (existsSync29(rosterPath)) {
29092
29875
  try {
29093
29876
  const roster = JSON.parse(readFileSync26(rosterPath, "utf8"));
@@ -29098,7 +29881,7 @@ async function runClaudeUninstall(flags = []) {
29098
29881
  for (const entry of entries) {
29099
29882
  const name = entry.replace(/\.md$/, "");
29100
29883
  if (knownNames.has(name)) {
29101
- if (!dryRun) rmSync(path43.join(agentsDir, entry), { force: true });
29884
+ if (!dryRun) rmSync(path44.join(agentsDir, entry), { force: true });
29102
29885
  agentCount++;
29103
29886
  }
29104
29887
  }
@@ -29109,13 +29892,13 @@ async function runClaudeUninstall(flags = []) {
29109
29892
  removed++;
29110
29893
  }
29111
29894
  }
29112
- const projectsDir = path43.join(claudeDir, "projects");
29895
+ const projectsDir = path44.join(claudeDir, "projects");
29113
29896
  if (existsSync29(projectsDir)) {
29114
29897
  let projectCount = 0;
29115
29898
  try {
29116
29899
  const projects = readdirSync9(projectsDir);
29117
29900
  for (const proj of projects) {
29118
- const projSettings = path43.join(projectsDir, proj, "settings.json");
29901
+ const projSettings = path44.join(projectsDir, proj, "settings.json");
29119
29902
  if (!existsSync29(projSettings)) continue;
29120
29903
  try {
29121
29904
  const pSettings = JSON.parse(readFileSync26(projSettings, "utf8"));
@@ -29152,9 +29935,9 @@ async function runClaudeUninstall(flags = []) {
29152
29935
  };
29153
29936
  const exeBinPath = findExeBin3();
29154
29937
  if (!exeBinPath) throw new Error("exe-os not found in PATH");
29155
- const binDir = path43.dirname(exeBinPath);
29938
+ const binDir = path44.dirname(exeBinPath);
29156
29939
  let symlinkCount = 0;
29157
- const rosterPath = path43.join(exeOsDir, "exe-employees.json");
29940
+ const rosterPath = path44.join(exeOsDir, "exe-employees.json");
29158
29941
  if (existsSync29(rosterPath)) {
29159
29942
  const roster = JSON.parse(readFileSync26(rosterPath, "utf8"));
29160
29943
  const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
@@ -29162,7 +29945,7 @@ async function runClaudeUninstall(flags = []) {
29162
29945
  for (const emp of roster) {
29163
29946
  if (emp.name === coordinatorName) continue;
29164
29947
  for (const suffix of ["", "-opencode"]) {
29165
- const linkPath = path43.join(binDir, `${emp.name}${suffix}`);
29948
+ const linkPath = path44.join(binDir, `${emp.name}${suffix}`);
29166
29949
  if (existsSync29(linkPath)) {
29167
29950
  if (!dryRun) rmSync(linkPath, { force: true });
29168
29951
  symlinkCount++;
@@ -29201,7 +29984,7 @@ async function checkForUpdateOnBoot() {
29201
29984
  const config = await loadConfig2();
29202
29985
  if (!config.autoUpdate.checkOnBoot) return;
29203
29986
  const { checkForUpdate: checkForUpdate2 } = await Promise.resolve().then(() => (init_update(), update_exports));
29204
- const packageRoot = path43.resolve(
29987
+ const packageRoot = path44.resolve(
29205
29988
  new URL("../..", import.meta.url).pathname
29206
29989
  );
29207
29990
  const result = checkForUpdate2(packageRoot);
@@ -29261,7 +30044,7 @@ async function runActivate(key) {
29261
30044
  const idTemplate = getIdentityTemplate(identityKey);
29262
30045
  if (idTemplate) {
29263
30046
  const idPath = identityPath2(name);
29264
- const dir = path43.dirname(idPath);
30047
+ const dir = path44.dirname(idPath);
29265
30048
  if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
29266
30049
  fs8.writeFileSync(idPath, idTemplate.replace(/^agent_id: \w+/m, `agent_id: ${name}`), "utf-8");
29267
30050
  }