@askexenow/exe-os 0.9.6 → 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 +668 -37
  5. package/dist/bin/cli.js +1399 -607
  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 +795 -155
  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 +703 -72
  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 +1064 -273
  17. package/dist/bin/exe-heartbeat.js +676 -45
  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 +845 -152
  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 +668 -37
  33. package/dist/bin/exe-team.js +635 -13
  34. package/dist/bin/git-sweep.js +731 -91
  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 +735 -95
  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 +1038 -247
  43. package/dist/hooks/bug-report-worker.js +902 -172
  44. package/dist/hooks/commit-complete.js +729 -89
  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 +851 -158
  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 +685 -45
  52. package/dist/hooks/pre-compact.js +729 -89
  53. package/dist/hooks/pre-tool-use.js +883 -127
  54. package/dist/hooks/prompt-ingest-worker.js +758 -83
  55. package/dist/hooks/prompt-submit.js +1071 -321
  56. package/dist/hooks/response-ingest-worker.js +758 -83
  57. package/dist/hooks/session-end.js +732 -92
  58. package/dist/hooks/session-start.js +1042 -209
  59. package/dist/hooks/stop.js +691 -51
  60. package/dist/hooks/subagent-stop.js +685 -45
  61. package/dist/hooks/summary-worker.js +827 -134
  62. package/dist/index.js +1026 -234
  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 +905 -164
  73. package/dist/lib/hybrid-search.js +771 -88
  74. package/dist/lib/identity.js +27 -7
  75. package/dist/lib/messaging.js +66 -30
  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 +109 -73
  82. package/dist/lib/tmux-routing.js +98 -62
  83. package/dist/lib/token-spend.js +26 -6
  84. package/dist/mcp/server.js +1807 -472
  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 +301 -166
  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 +206 -40
  91. package/dist/mcp/tools/send-message.js +69 -33
  92. package/dist/mcp/tools/update-task.js +86 -50
  93. package/dist/runtime/index.js +731 -91
  94. package/dist/tui/App.js +864 -125
  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;
2669
+ }
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);
1894
2700
  }
1895
- spawnDaemon();
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;
@@ -10571,15 +11354,24 @@ function getDispatchedBy(sessionKey) {
10571
11354
  function resolveExeSession() {
10572
11355
  const mySession = getMySession();
10573
11356
  if (!mySession) return null;
11357
+ const fromSessionName = extractRootExe(mySession);
10574
11358
  try {
10575
11359
  const key = getSessionKey();
10576
11360
  const parentExe = getParentExe(key);
10577
11361
  if (parentExe) {
10578
- return extractRootExe(parentExe) ?? parentExe;
11362
+ const fromCache = extractRootExe(parentExe) ?? parentExe;
11363
+ if (fromSessionName && fromCache !== fromSessionName) {
11364
+ process.stderr.write(
11365
+ `[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
11366
+ `
11367
+ );
11368
+ return fromSessionName;
11369
+ }
11370
+ return fromCache;
10579
11371
  }
10580
11372
  } catch {
10581
11373
  }
10582
- return extractRootExe(mySession) ?? mySession;
11374
+ return fromSessionName ?? mySession;
10583
11375
  }
10584
11376
  function isEmployeeAlive(sessionName) {
10585
11377
  return getTransport().isAlive(sessionName);
@@ -10737,7 +11529,7 @@ function sendIntercom(targetSession) {
10737
11529
  try {
10738
11530
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
10739
11531
  const agent = baseAgentName(rawAgent);
10740
- const markerPath = path26.join(SESSION_CACHE, `current-task-${agent}.json`);
11532
+ const markerPath = path27.join(SESSION_CACHE, `current-task-${agent}.json`);
10741
11533
  if (existsSync21(markerPath)) {
10742
11534
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker \u2014 will auto-chain)`);
10743
11535
  return "debounced";
@@ -10747,7 +11539,7 @@ function sendIntercom(targetSession) {
10747
11539
  try {
10748
11540
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
10749
11541
  const agent = baseAgentName(rawAgent);
10750
- const taskDir = path26.join(process.cwd(), "exe", agent);
11542
+ const taskDir = path27.join(process.cwd(), "exe", agent);
10751
11543
  if (existsSync21(taskDir)) {
10752
11544
  const files = readdirSync6(taskDir).filter(
10753
11545
  (f) => f.endsWith(".md") && f !== "DONE.txt"
@@ -10881,8 +11673,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
10881
11673
  const transport = getTransport();
10882
11674
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
10883
11675
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
10884
- const logDir = path26.join(os13.homedir(), ".exe-os", "session-logs");
10885
- 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`);
10886
11678
  if (!existsSync21(logDir)) {
10887
11679
  mkdirSync15(logDir, { recursive: true });
10888
11680
  }
@@ -10890,14 +11682,14 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
10890
11682
  let cleanupSuffix = "";
10891
11683
  try {
10892
11684
  const thisFile = fileURLToPath4(import.meta.url);
10893
- 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");
10894
11686
  if (existsSync21(cleanupScript)) {
10895
11687
  cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
10896
11688
  }
10897
11689
  } catch {
10898
11690
  }
10899
11691
  try {
10900
- const claudeJsonPath = path26.join(os13.homedir(), ".claude.json");
11692
+ const claudeJsonPath = path27.join(os14.homedir(), ".claude.json");
10901
11693
  let claudeJson = {};
10902
11694
  try {
10903
11695
  claudeJson = JSON.parse(readFileSync18(claudeJsonPath, "utf8"));
@@ -10912,10 +11704,10 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
10912
11704
  } catch {
10913
11705
  }
10914
11706
  try {
10915
- const settingsDir = path26.join(os13.homedir(), ".claude", "projects");
11707
+ const settingsDir = path27.join(os14.homedir(), ".claude", "projects");
10916
11708
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
10917
- const projSettingsDir = path26.join(settingsDir, normalizedKey);
10918
- const settingsPath = path26.join(projSettingsDir, "settings.json");
11709
+ const projSettingsDir = path27.join(settingsDir, normalizedKey);
11710
+ const settingsPath = path27.join(projSettingsDir, "settings.json");
10919
11711
  let settings = {};
10920
11712
  try {
10921
11713
  settings = JSON.parse(readFileSync18(settingsPath, "utf8"));
@@ -10962,8 +11754,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
10962
11754
  let behaviorsFlag = "";
10963
11755
  let legacyFallbackWarned = false;
10964
11756
  if (!useExeAgent && !useBinSymlink) {
10965
- const identityPath2 = path26.join(
10966
- os13.homedir(),
11757
+ const identityPath2 = path27.join(
11758
+ os14.homedir(),
10967
11759
  ".exe-os",
10968
11760
  "identity",
10969
11761
  `${employeeName}.md`
@@ -10978,7 +11770,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
10978
11770
  }
10979
11771
  const behaviorsFile = exportBehaviorsSync(
10980
11772
  employeeName,
10981
- path26.basename(spawnCwd),
11773
+ path27.basename(spawnCwd),
10982
11774
  sessionName
10983
11775
  );
10984
11776
  if (behaviorsFile) {
@@ -10993,9 +11785,9 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
10993
11785
  }
10994
11786
  let sessionContextFlag = "";
10995
11787
  try {
10996
- const ctxDir = path26.join(os13.homedir(), ".exe-os", "session-cache");
11788
+ const ctxDir = path27.join(os14.homedir(), ".exe-os", "session-cache");
10997
11789
  mkdirSync15(ctxDir, { recursive: true });
10998
- const ctxFile = path26.join(ctxDir, `session-context-${sessionName}.md`);
11790
+ const ctxFile = path27.join(ctxDir, `session-context-${sessionName}.md`);
10999
11791
  const ctxContent = [
11000
11792
  `## Session Context`,
11001
11793
  `You are running in tmux session: ${sessionName}.`,
@@ -11079,7 +11871,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
11079
11871
  transport.pipeLog(sessionName, logFile);
11080
11872
  try {
11081
11873
  const mySession = getMySession();
11082
- const dispatchInfo = path26.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
11874
+ const dispatchInfo = path27.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
11083
11875
  writeFileSync14(dispatchInfo, JSON.stringify({
11084
11876
  dispatchedBy: mySession,
11085
11877
  rootExe: exeSession,
@@ -11154,15 +11946,15 @@ var init_tmux_routing = __esm({
11154
11946
  init_intercom_queue();
11155
11947
  init_plan_limits();
11156
11948
  init_employees();
11157
- SPAWN_LOCK_DIR = path26.join(os13.homedir(), ".exe-os", "spawn-locks");
11158
- 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");
11159
11951
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
11160
11952
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
11161
11953
  VERIFY_PANE_LINES = 200;
11162
11954
  INTERCOM_DEBOUNCE_MS = 3e4;
11163
11955
  CODEX_DEBOUNCE_MS = 12e4;
11164
- INTERCOM_LOG2 = path26.join(os13.homedir(), ".exe-os", "intercom.log");
11165
- 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");
11166
11958
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
11167
11959
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
11168
11960
  }
@@ -11431,7 +12223,7 @@ __export(active_agent_exports, {
11431
12223
  });
11432
12224
  import { readFileSync as readFileSync19, writeFileSync as writeFileSync15, mkdirSync as mkdirSync16, unlinkSync as unlinkSync9, readdirSync as readdirSync7 } from "fs";
11433
12225
  import { execSync as execSync9 } from "child_process";
11434
- import path27 from "path";
12226
+ import path28 from "path";
11435
12227
  function isNameWithOptionalInstance(candidate, baseName) {
11436
12228
  if (candidate === baseName) return true;
11437
12229
  if (!candidate.startsWith(baseName)) return false;
@@ -11475,7 +12267,7 @@ function resolveActiveAgentFromTmuxSession(sessionName) {
11475
12267
  return null;
11476
12268
  }
11477
12269
  function getMarkerPath() {
11478
- return path27.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
12270
+ return path28.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
11479
12271
  }
11480
12272
  function writeActiveAgent(agentId, agentRole) {
11481
12273
  try {
@@ -11544,14 +12336,14 @@ function getAllActiveAgents() {
11544
12336
  const key = file.slice("active-agent-".length, -".json".length);
11545
12337
  if (key === "undefined") continue;
11546
12338
  try {
11547
- const raw = readFileSync19(path27.join(CACHE_DIR, file), "utf8");
12339
+ const raw = readFileSync19(path28.join(CACHE_DIR, file), "utf8");
11548
12340
  const data = JSON.parse(raw);
11549
12341
  if (!data.agentId) continue;
11550
12342
  if (data.startedAt) {
11551
12343
  const age = Date.now() - new Date(data.startedAt).getTime();
11552
12344
  if (age > STALE_MS) {
11553
12345
  try {
11554
- unlinkSync9(path27.join(CACHE_DIR, file));
12346
+ unlinkSync9(path28.join(CACHE_DIR, file));
11555
12347
  } catch {
11556
12348
  }
11557
12349
  continue;
@@ -11574,11 +12366,11 @@ function getAllActiveAgents() {
11574
12366
  function cleanupSessionMarkers() {
11575
12367
  const key = getSessionKey();
11576
12368
  try {
11577
- unlinkSync9(path27.join(CACHE_DIR, `active-agent-${key}.json`));
12369
+ unlinkSync9(path28.join(CACHE_DIR, `active-agent-${key}.json`));
11578
12370
  } catch {
11579
12371
  }
11580
12372
  try {
11581
- unlinkSync9(path27.join(CACHE_DIR, "active-agent-undefined.json"));
12373
+ unlinkSync9(path28.join(CACHE_DIR, "active-agent-undefined.json"));
11582
12374
  } catch {
11583
12375
  }
11584
12376
  }
@@ -11589,7 +12381,7 @@ var init_active_agent = __esm({
11589
12381
  init_config();
11590
12382
  init_session_key();
11591
12383
  init_employees();
11592
- CACHE_DIR = path27.join(EXE_AI_DIR, "session-cache");
12384
+ CACHE_DIR = path28.join(EXE_AI_DIR, "session-cache");
11593
12385
  STALE_MS = 24 * 60 * 60 * 1e3;
11594
12386
  }
11595
12387
  });
@@ -12219,12 +13011,12 @@ __export(exe_rename_exports, {
12219
13011
  });
12220
13012
  import { readFileSync as readFileSync20, writeFileSync as writeFileSync16, renameSync as renameSync4, unlinkSync as unlinkSync10, existsSync as existsSync22 } from "fs";
12221
13013
  import { execSync as execSync10 } from "child_process";
12222
- import path28 from "path";
13014
+ import path29 from "path";
12223
13015
  import { homedir as homedir4 } from "os";
12224
13016
  async function renameEmployee(oldName, newName, opts = {}) {
12225
- const rosterPath = opts.rosterPath ?? path28.join(homedir4(), ".exe-os", "exe-employees.json");
12226
- const identityDir = opts.identityDir ?? path28.join(homedir4(), ".exe-os", "identity");
12227
- 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");
12228
13020
  const validation = validateEmployeeName(newName);
12229
13021
  if (!validation.valid) {
12230
13022
  return { success: false, error: validation.error };
@@ -12256,8 +13048,8 @@ async function renameEmployee(oldName, newName, opts = {}) {
12256
13048
  writeFileSync16(rosterPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
12257
13049
  }
12258
13050
  });
12259
- const oldIdentityPath = path28.join(identityDir, `${rosterOldName}.md`);
12260
- const newIdentityPath = path28.join(identityDir, `${newName}.md`);
13051
+ const oldIdentityPath = path29.join(identityDir, `${rosterOldName}.md`);
13052
+ const newIdentityPath = path29.join(identityDir, `${newName}.md`);
12261
13053
  if (existsSync22(oldIdentityPath)) {
12262
13054
  const content = readFileSync20(oldIdentityPath, "utf-8");
12263
13055
  const updatedContent = content.replace(
@@ -12276,8 +13068,8 @@ async function renameEmployee(oldName, newName, opts = {}) {
12276
13068
  }
12277
13069
  });
12278
13070
  }
12279
- const oldAgentPath = path28.join(agentsDir, `${rosterOldName}.md`);
12280
- const newAgentPath = path28.join(agentsDir, `${newName}.md`);
13071
+ const oldAgentPath = path29.join(agentsDir, `${rosterOldName}.md`);
13072
+ const newAgentPath = path29.join(agentsDir, `${newName}.md`);
12281
13073
  if (existsSync22(oldAgentPath)) {
12282
13074
  const agentContent = readFileSync20(oldAgentPath, "utf-8");
12283
13075
  renameSync4(oldAgentPath, newAgentPath);
@@ -12364,9 +13156,9 @@ function removeOldSymlinks(name) {
12364
13156
  try {
12365
13157
  const exeBinPath = findExeBin2();
12366
13158
  if (!exeBinPath) return;
12367
- const binDir = path28.dirname(exeBinPath);
13159
+ const binDir = path29.dirname(exeBinPath);
12368
13160
  for (const suffix of ["", "-opencode"]) {
12369
- const linkPath = path28.join(binDir, `${name}${suffix}`);
13161
+ const linkPath = path29.join(binDir, `${name}${suffix}`);
12370
13162
  if (existsSync22(linkPath)) {
12371
13163
  try {
12372
13164
  unlinkSync10(linkPath);
@@ -12415,10 +13207,10 @@ var init_exe_rename = __esm({
12415
13207
  import { createWriteStream, createReadStream as createReadStream2, existsSync as existsSync23, unlinkSync as unlinkSync11, renameSync as renameSync5 } from "fs";
12416
13208
  import { mkdir as mkdir6 } from "fs/promises";
12417
13209
  import { createHash as createHash3 } from "crypto";
12418
- import path29 from "path";
13210
+ import path30 from "path";
12419
13211
  async function downloadModel(opts) {
12420
13212
  const { destDir, onProgress, fetchFn = globalThis.fetch } = opts;
12421
- const destPath = path29.join(destDir, LOCAL_FILENAME);
13213
+ const destPath = path30.join(destDir, LOCAL_FILENAME);
12422
13214
  const tmpPath = destPath + ".tmp";
12423
13215
  await mkdir6(destDir, { recursive: true });
12424
13216
  if (existsSync23(destPath)) {
@@ -12542,8 +13334,8 @@ async function embedDirect(text) {
12542
13334
  const llamaCpp = await import("node-llama-cpp");
12543
13335
  const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
12544
13336
  const { existsSync: existsSync30 } = await import("fs");
12545
- const path44 = await import("path");
12546
- 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");
12547
13339
  if (!existsSync30(modelPath)) {
12548
13340
  throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
12549
13341
  }
@@ -13127,17 +13919,17 @@ import {
13127
13919
  readdirSync as readdirSync8,
13128
13920
  unlinkSync as unlinkSync12
13129
13921
  } from "fs";
13130
- import path30 from "path";
13922
+ import path31 from "path";
13131
13923
  import { homedir as homedir5 } from "os";
13132
13924
  function generateSessionWrappers(packageRoot, homeDir) {
13133
13925
  const home = homeDir ?? homedir5();
13134
- const binDir = path30.join(home, ".exe-os", "bin");
13135
- 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");
13136
13928
  mkdirSync17(binDir, { recursive: true });
13137
- const exeStartDst = path30.join(binDir, "exe-start");
13929
+ const exeStartDst = path31.join(binDir, "exe-start");
13138
13930
  const candidates = [
13139
- path30.join(packageRoot, "dist", "bin", "exe-start.sh"),
13140
- 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")
13141
13933
  ];
13142
13934
  for (const src of candidates) {
13143
13935
  if (existsSync24(src)) {
@@ -13158,7 +13950,7 @@ function generateSessionWrappers(packageRoot, homeDir) {
13158
13950
  try {
13159
13951
  for (const f of readdirSync8(binDir)) {
13160
13952
  if (f === "exe-start") continue;
13161
- const fPath = path30.join(binDir, f);
13953
+ const fPath = path31.join(binDir, f);
13162
13954
  try {
13163
13955
  const content = readFileSync21(fPath, "utf8");
13164
13956
  if (content.includes("exe-start")) {
@@ -13175,15 +13967,15 @@ exec "${exeStartDst}" "$0" "$@"
13175
13967
  `;
13176
13968
  for (const emp of employees) {
13177
13969
  for (let n = 1; n <= MAX_N; n++) {
13178
- const wrapperPath = path30.join(binDir, `${emp.name}${n}`);
13970
+ const wrapperPath = path31.join(binDir, `${emp.name}${n}`);
13179
13971
  writeFileSync17(wrapperPath, wrapperContent);
13180
13972
  chmodSync(wrapperPath, 493);
13181
13973
  created++;
13182
13974
  }
13183
13975
  }
13184
13976
  const codexLauncherCandidates = [
13185
- path30.join(packageRoot, "dist", "bin", "exe-start-codex.js"),
13186
- 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")
13187
13979
  ];
13188
13980
  let codexLauncher = null;
13189
13981
  for (const c of codexLauncherCandidates) {
@@ -13194,7 +13986,7 @@ exec "${exeStartDst}" "$0" "$@"
13194
13986
  }
13195
13987
  if (codexLauncher) {
13196
13988
  for (const emp of employees) {
13197
- const wrapperPath = path30.join(binDir, `${emp.name}-codex`);
13989
+ const wrapperPath = path31.join(binDir, `${emp.name}-codex`);
13198
13990
  const content = `#!/bin/bash
13199
13991
  exec node "${codexLauncher}" --agent ${emp.name} "$@"
13200
13992
  `;
@@ -13217,12 +14009,12 @@ export PATH="${binDir}:$PATH"
13217
14009
  const shell = process.env.SHELL ?? "/bin/bash";
13218
14010
  const profilePaths = [];
13219
14011
  if (shell.includes("zsh")) {
13220
- profilePaths.push(path30.join(home, ".zshrc"));
14012
+ profilePaths.push(path31.join(home, ".zshrc"));
13221
14013
  } else if (shell.includes("bash")) {
13222
- profilePaths.push(path30.join(home, ".bashrc"));
13223
- profilePaths.push(path30.join(home, ".bash_profile"));
14014
+ profilePaths.push(path31.join(home, ".bashrc"));
14015
+ profilePaths.push(path31.join(home, ".bash_profile"));
13224
14016
  } else {
13225
- profilePaths.push(path30.join(home, ".profile"));
14017
+ profilePaths.push(path31.join(home, ".profile"));
13226
14018
  }
13227
14019
  for (const profilePath of profilePaths) {
13228
14020
  try {
@@ -13258,14 +14050,14 @@ __export(setup_wizard_exports, {
13258
14050
  });
13259
14051
  import crypto11 from "crypto";
13260
14052
  import { existsSync as existsSync25, mkdirSync as mkdirSync18, readFileSync as readFileSync22, writeFileSync as writeFileSync18, unlinkSync as unlinkSync13 } from "fs";
13261
- import os14 from "os";
13262
- import path31 from "path";
14053
+ import os15 from "os";
14054
+ import path32 from "path";
13263
14055
  import { createInterface as createInterface3 } from "readline";
13264
14056
  function findPackageRoot2() {
13265
- let dir = path31.dirname(new URL(import.meta.url).pathname);
13266
- const root = path31.parse(dir).root;
14057
+ let dir = path32.dirname(new URL(import.meta.url).pathname);
14058
+ const root = path32.parse(dir).root;
13267
14059
  while (dir !== root) {
13268
- const pkgPath = path31.join(dir, "package.json");
14060
+ const pkgPath = path32.join(dir, "package.json");
13269
14061
  if (existsSync25(pkgPath)) {
13270
14062
  try {
13271
14063
  const pkg = JSON.parse(readFileSync22(pkgPath, "utf-8"));
@@ -13273,7 +14065,7 @@ function findPackageRoot2() {
13273
14065
  } catch {
13274
14066
  }
13275
14067
  }
13276
- dir = path31.dirname(dir);
14068
+ dir = path32.dirname(dir);
13277
14069
  }
13278
14070
  return null;
13279
14071
  }
@@ -13285,7 +14077,7 @@ function loadSetupState() {
13285
14077
  }
13286
14078
  }
13287
14079
  function saveSetupState(state) {
13288
- mkdirSync18(path31.dirname(SETUP_STATE_PATH), { recursive: true });
14080
+ mkdirSync18(path32.dirname(SETUP_STATE_PATH), { recursive: true });
13289
14081
  writeFileSync18(SETUP_STATE_PATH, JSON.stringify(state, null, 2));
13290
14082
  }
13291
14083
  function clearSetupState() {
@@ -13305,10 +14097,10 @@ function ask2(rl, prompt) {
13305
14097
  });
13306
14098
  }
13307
14099
  function getAvailableMemoryGB() {
13308
- return os14.freemem() / (1024 * 1024 * 1024);
14100
+ return os15.freemem() / (1024 * 1024 * 1024);
13309
14101
  }
13310
14102
  function getTotalMemoryGB() {
13311
- return os14.totalmem() / (1024 * 1024 * 1024);
14103
+ return os15.totalmem() / (1024 * 1024 * 1024);
13312
14104
  }
13313
14105
  function isLowMemory() {
13314
14106
  return getAvailableMemoryGB() < 2;
@@ -13319,7 +14111,7 @@ async function validateModel(log) {
13319
14111
  if (totalGB <= 8 || isLowMemory()) {
13320
14112
  log(`System memory: ${totalGB.toFixed(0)}GB total, ${freeGB.toFixed(1)}GB free`);
13321
14113
  log("Skipping in-memory model validation (low memory \u2014 will validate on first use).");
13322
- const modelPath = path31.join(MODELS_DIR, LOCAL_FILENAME);
14114
+ const modelPath = path32.join(MODELS_DIR, LOCAL_FILENAME);
13323
14115
  if (existsSync25(modelPath)) {
13324
14116
  const { statSync: statSync2 } = await import("fs");
13325
14117
  const size = statSync2(modelPath).size;
@@ -13575,7 +14367,7 @@ async function runSetupWizard(opts = {}) {
13575
14367
  await saveConfig(config);
13576
14368
  log("");
13577
14369
  try {
13578
- const claudeJsonPath = path31.join(os14.homedir(), ".claude.json");
14370
+ const claudeJsonPath = path32.join(os15.homedir(), ".claude.json");
13579
14371
  let claudeJson = {};
13580
14372
  try {
13581
14373
  claudeJson = JSON.parse(readFileSync22(claudeJsonPath, "utf8"));
@@ -13583,7 +14375,7 @@ async function runSetupWizard(opts = {}) {
13583
14375
  }
13584
14376
  if (!claudeJson.projects) claudeJson.projects = {};
13585
14377
  const projects = claudeJson.projects;
13586
- for (const dir of [process.cwd(), os14.homedir()]) {
14378
+ for (const dir of [process.cwd(), os15.homedir()]) {
13587
14379
  if (!projects[dir]) projects[dir] = {};
13588
14380
  projects[dir].hasTrustDialogAccepted = true;
13589
14381
  }
@@ -13601,7 +14393,7 @@ async function runSetupWizard(opts = {}) {
13601
14393
  const prefs = { ...existingPrefs };
13602
14394
  log("=== Config Defaults ===");
13603
14395
  log("");
13604
- 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"));
13605
14397
  if (ghosttyDetected) {
13606
14398
  const ghosttyAnswer = await ask2(rl, "Detected Ghostty terminal. Use exe-os Ghostty defaults? (Y/n) ");
13607
14399
  prefs.ghostty = ghosttyAnswer.toLowerCase() !== "n";
@@ -13745,7 +14537,7 @@ async function runSetupWizard(opts = {}) {
13745
14537
  const cooIdentityContent = getIdentityTemplate("coo");
13746
14538
  if (cooIdentityContent) {
13747
14539
  const cooIdPath = identityPath2(cooName);
13748
- mkdirSync18(path31.dirname(cooIdPath), { recursive: true });
14540
+ mkdirSync18(path32.dirname(cooIdPath), { recursive: true });
13749
14541
  const replaced = cooIdentityContent.replace(/agent_id:\s*exe/g, `agent_id: ${cooName}`).replace(/\$\{agent_id\}/g, cooName);
13750
14542
  writeFileSync18(cooIdPath, replaced, "utf-8");
13751
14543
  }
@@ -13841,7 +14633,7 @@ async function runSetupWizard(opts = {}) {
13841
14633
  const ctoIdentityContent = getIdentityTemplate("cto");
13842
14634
  if (ctoIdentityContent) {
13843
14635
  const ctoIdPath = identityPath2(ctoName);
13844
- mkdirSync18(path31.dirname(ctoIdPath), { recursive: true });
14636
+ mkdirSync18(path32.dirname(ctoIdPath), { recursive: true });
13845
14637
  const replaced = ctoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${ctoName}`).replace(/\$\{agent_id\}/g, ctoName);
13846
14638
  writeFileSync18(ctoIdPath, replaced, "utf-8");
13847
14639
  }
@@ -13864,7 +14656,7 @@ async function runSetupWizard(opts = {}) {
13864
14656
  const cmoIdentityContent = getIdentityTemplate("cmo");
13865
14657
  if (cmoIdentityContent) {
13866
14658
  const cmoIdPath = identityPath2(cmoName);
13867
- mkdirSync18(path31.dirname(cmoIdPath), { recursive: true });
14659
+ mkdirSync18(path32.dirname(cmoIdPath), { recursive: true });
13868
14660
  const replaced = cmoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${cmoName}`).replace(/\$\{agent_id\}/g, cmoName);
13869
14661
  writeFileSync18(cmoIdPath, replaced, "utf-8");
13870
14662
  }
@@ -13888,7 +14680,7 @@ async function runSetupWizard(opts = {}) {
13888
14680
  log(`Session shortcuts generated (${cooName}1, ${cooName}2, ...)`);
13889
14681
  }
13890
14682
  if (wrapResult.pathConfigured) {
13891
- const binDir = path31.join(os14.homedir(), ".exe-os", "bin");
14683
+ const binDir = path32.join(os15.homedir(), ".exe-os", "bin");
13892
14684
  process.env.PATH = `${binDir}:${process.env.PATH ?? ""}`;
13893
14685
  pathJustConfigured = true;
13894
14686
  }
@@ -13931,7 +14723,7 @@ async function runSetupWizard(opts = {}) {
13931
14723
  const pkgRoot2 = findPackageRoot2();
13932
14724
  if (pkgRoot2) {
13933
14725
  try {
13934
- 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;
13935
14727
  } catch {
13936
14728
  }
13937
14729
  }
@@ -13965,16 +14757,16 @@ var init_setup_wizard = __esm({
13965
14757
  init_config();
13966
14758
  init_keychain();
13967
14759
  init_model_downloader();
13968
- 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");
13969
14761
  }
13970
14762
  });
13971
14763
 
13972
14764
  // src/lib/update-check.ts
13973
14765
  import { execSync as execSync11 } from "child_process";
13974
14766
  import { readFileSync as readFileSync23 } from "fs";
13975
- import path32 from "path";
14767
+ import path33 from "path";
13976
14768
  function getLocalVersion(packageRoot) {
13977
- const pkgPath = path32.join(packageRoot, "package.json");
14769
+ const pkgPath = path33.join(packageRoot, "package.json");
13978
14770
  const pkg = JSON.parse(readFileSync23(pkgPath, "utf-8"));
13979
14771
  return pkg.version;
13980
14772
  }
@@ -18499,8 +19291,8 @@ var init_ErrorOverview = __esm({
18499
19291
  "use strict";
18500
19292
  init_Box();
18501
19293
  init_Text();
18502
- cleanupPath = (path44) => {
18503
- return path44?.replace(`file://${cwd()}/`, "");
19294
+ cleanupPath = (path45) => {
19295
+ return path45?.replace(`file://${cwd()}/`, "");
18504
19296
  };
18505
19297
  stackUtils = new StackUtils({
18506
19298
  cwd: cwd(),
@@ -22954,10 +23746,10 @@ var init_hooks = __esm({
22954
23746
  });
22955
23747
 
22956
23748
  // src/runtime/safety-checks.ts
22957
- import path33 from "path";
22958
- import os15 from "os";
23749
+ import path34 from "path";
23750
+ import os16 from "os";
22959
23751
  function checkPathSafety(filePath) {
22960
- const resolved = path33.resolve(filePath);
23752
+ const resolved = path34.resolve(filePath);
22961
23753
  for (const { pattern, reason } of BYPASS_IMMUNE_PATTERNS) {
22962
23754
  const matches = typeof pattern === "function" ? pattern(resolved) : pattern.test(resolved);
22963
23755
  if (matches) {
@@ -22967,7 +23759,7 @@ function checkPathSafety(filePath) {
22967
23759
  return { safe: true, bypassImmune: true };
22968
23760
  }
22969
23761
  function checkReadPathSafety(filePath) {
22970
- const resolved = path33.resolve(filePath);
23762
+ const resolved = path34.resolve(filePath);
22971
23763
  const credPatterns = BYPASS_IMMUNE_PATTERNS.filter(
22972
23764
  (p) => typeof p.pattern !== "function" && (p.reason.includes("secrets") || p.reason.includes("Private key") || p.reason.includes("Credential"))
22973
23765
  );
@@ -22982,7 +23774,7 @@ var HOME, BYPASS_IMMUNE_PATTERNS;
22982
23774
  var init_safety_checks = __esm({
22983
23775
  "src/runtime/safety-checks.ts"() {
22984
23776
  "use strict";
22985
- HOME = os15.homedir();
23777
+ HOME = os16.homedir();
22986
23778
  BYPASS_IMMUNE_PATTERNS = [
22987
23779
  {
22988
23780
  pattern: /\/\.git\/hooks\//,
@@ -22993,11 +23785,11 @@ var init_safety_checks = __esm({
22993
23785
  reason: "Git config can set hooks and command execution"
22994
23786
  },
22995
23787
  {
22996
- pattern: (p) => p.startsWith(path33.join(HOME, ".claude")),
23788
+ pattern: (p) => p.startsWith(path34.join(HOME, ".claude")),
22997
23789
  reason: "Claude configuration files are protected"
22998
23790
  },
22999
23791
  {
23000
- pattern: (p) => p.startsWith(path33.join(HOME, ".exe-os")),
23792
+ pattern: (p) => p.startsWith(path34.join(HOME, ".exe-os")),
23001
23793
  reason: "exe-os configuration files are protected"
23002
23794
  },
23003
23795
  {
@@ -23014,7 +23806,7 @@ var init_safety_checks = __esm({
23014
23806
  },
23015
23807
  {
23016
23808
  pattern: (p) => {
23017
- const name = path33.basename(p);
23809
+ const name = path34.basename(p);
23018
23810
  return [".bashrc", ".zshrc", ".profile", ".bash_profile", ".zprofile", ".zshenv"].includes(name);
23019
23811
  },
23020
23812
  reason: "Shell configuration files can execute arbitrary code on login"
@@ -23041,7 +23833,7 @@ __export(file_read_exports, {
23041
23833
  FileReadTool: () => FileReadTool
23042
23834
  });
23043
23835
  import fs3 from "fs/promises";
23044
- import path34 from "path";
23836
+ import path35 from "path";
23045
23837
  import { z } from "zod";
23046
23838
  function isBinary(buf) {
23047
23839
  for (let i = 0; i < buf.length; i++) {
@@ -23077,7 +23869,7 @@ var init_file_read = __esm({
23077
23869
  return { behavior: "allow" };
23078
23870
  },
23079
23871
  async call(input, context) {
23080
- 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);
23081
23873
  let stat2;
23082
23874
  try {
23083
23875
  stat2 = await fs3.stat(filePath);
@@ -23117,7 +23909,7 @@ __export(glob_exports, {
23117
23909
  GlobTool: () => GlobTool
23118
23910
  });
23119
23911
  import fs4 from "fs/promises";
23120
- import path35 from "path";
23912
+ import path36 from "path";
23121
23913
  import { z as z2 } from "zod";
23122
23914
  async function walkDir(dir, maxDepth = 10) {
23123
23915
  const results = [];
@@ -23133,7 +23925,7 @@ async function walkDir(dir, maxDepth = 10) {
23133
23925
  if (entry.isDirectory() && (entry.name === "node_modules" || entry.name === ".git")) {
23134
23926
  continue;
23135
23927
  }
23136
- const fullPath = path35.join(current, entry.name);
23928
+ const fullPath = path36.join(current, entry.name);
23137
23929
  if (entry.isDirectory()) {
23138
23930
  await walk(fullPath, depth + 1);
23139
23931
  } else {
@@ -23167,11 +23959,11 @@ var init_glob = __esm({
23167
23959
  inputSchema: inputSchema2,
23168
23960
  isReadOnly: true,
23169
23961
  async call(input, context) {
23170
- 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;
23171
23963
  try {
23172
23964
  const entries = await walkDir(baseDir);
23173
23965
  const matched = entries.filter(
23174
- (e) => simpleGlobMatch(path35.relative(baseDir, e.path), input.pattern)
23966
+ (e) => simpleGlobMatch(path36.relative(baseDir, e.path), input.pattern)
23175
23967
  );
23176
23968
  matched.sort((a, b) => b.mtime - a.mtime);
23177
23969
  if (matched.length === 0) {
@@ -23197,7 +23989,7 @@ __export(grep_exports, {
23197
23989
  });
23198
23990
  import { spawn as spawn2 } from "child_process";
23199
23991
  import fs5 from "fs/promises";
23200
- import path36 from "path";
23992
+ import path37 from "path";
23201
23993
  import { z as z3 } from "zod";
23202
23994
  function runRipgrep(input, searchPath, context) {
23203
23995
  return new Promise((resolve, reject) => {
@@ -23251,7 +24043,7 @@ async function nodeGrep(input, searchPath) {
23251
24043
  }
23252
24044
  for (const entry of entries) {
23253
24045
  if (entry.name === "node_modules" || entry.name === ".git") continue;
23254
- const fullPath = path36.join(dir, entry.name);
24046
+ const fullPath = path37.join(dir, entry.name);
23255
24047
  if (entry.isDirectory()) {
23256
24048
  await walk(fullPath);
23257
24049
  } else {
@@ -23297,7 +24089,7 @@ var init_grep = __esm({
23297
24089
  inputSchema: inputSchema3,
23298
24090
  isReadOnly: true,
23299
24091
  async call(input, context) {
23300
- 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;
23301
24093
  try {
23302
24094
  const result = await runRipgrep(input, searchPath, context);
23303
24095
  return result;
@@ -23322,7 +24114,7 @@ __export(file_write_exports, {
23322
24114
  FileWriteTool: () => FileWriteTool
23323
24115
  });
23324
24116
  import fs6 from "fs/promises";
23325
- import path37 from "path";
24117
+ import path38 from "path";
23326
24118
  import { z as z4 } from "zod";
23327
24119
  var inputSchema4, FileWriteTool;
23328
24120
  var init_file_write = __esm({
@@ -23350,8 +24142,8 @@ var init_file_write = __esm({
23350
24142
  return { behavior: "allow" };
23351
24143
  },
23352
24144
  async call(input, context) {
23353
- const filePath = path37.isAbsolute(input.file_path) ? input.file_path : path37.resolve(context.cwd, input.file_path);
23354
- 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);
23355
24147
  await fs6.mkdir(dir, { recursive: true });
23356
24148
  await fs6.writeFile(filePath, input.content, "utf-8");
23357
24149
  return {
@@ -23369,7 +24161,7 @@ __export(file_edit_exports, {
23369
24161
  FileEditTool: () => FileEditTool
23370
24162
  });
23371
24163
  import fs7 from "fs/promises";
23372
- import path38 from "path";
24164
+ import path39 from "path";
23373
24165
  import { z as z5 } from "zod";
23374
24166
  function countOccurrences(haystack, needle) {
23375
24167
  let count = 0;
@@ -23410,7 +24202,7 @@ var init_file_edit = __esm({
23410
24202
  return { behavior: "allow" };
23411
24203
  },
23412
24204
  async call(input, context) {
23413
- 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);
23414
24206
  let content;
23415
24207
  try {
23416
24208
  content = await fs7.readFile(filePath, "utf-8");
@@ -23652,7 +24444,7 @@ var init_bash = __esm({
23652
24444
  // src/tui/views/CommandCenter.tsx
23653
24445
  import { useState as useState6, useEffect as useEffect8, useMemo as useMemo4, useCallback as useCallback4, useRef as useRef4 } from "react";
23654
24446
  import TextInput from "ink-text-input";
23655
- import path39 from "path";
24447
+ import path40 from "path";
23656
24448
  import { homedir as homedir6 } from "os";
23657
24449
  import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
23658
24450
  function CommandCenterView({
@@ -23901,7 +24693,7 @@ function CommandCenterView({
23901
24693
  const demoEntries = DEMO_PROJECTS.map((p) => ({
23902
24694
  projectName: p.projectName,
23903
24695
  exeSession: p.exeSession,
23904
- projectDir: path39.join(homedir6(), p.projectName),
24696
+ projectDir: path40.join(homedir6(), p.projectName),
23905
24697
  employeeCount: p.employees.length,
23906
24698
  activeCount: p.employees.filter((e) => e.status === "active").length,
23907
24699
  memoryCount: p.employees.length * 4e3,
@@ -24905,7 +25697,7 @@ var init_useOrchestrator = __esm({
24905
25697
 
24906
25698
  // src/tui/views/Sessions.tsx
24907
25699
  import React19, { useState as useState9, useEffect as useEffect11, useCallback as useCallback6 } from "react";
24908
- import path40 from "path";
25700
+ import path41 from "path";
24909
25701
  import { homedir as homedir7 } from "os";
24910
25702
  import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
24911
25703
  function isCoordinatorEntry(entry) {
@@ -24943,7 +25735,7 @@ function SessionsView({
24943
25735
  if (demo) {
24944
25736
  setProjects(DEMO_PROJECTS.map((p) => ({
24945
25737
  ...p,
24946
- projectDir: path40.join(homedir7(), p.projectName),
25738
+ projectDir: path41.join(homedir7(), p.projectName),
24947
25739
  employees: p.employees.map((e) => ({ ...e, attached: e.status === "active" }))
24948
25740
  })));
24949
25741
  return;
@@ -26861,8 +27653,8 @@ __export(wiki_client_exports, {
26861
27653
  listDocuments: () => listDocuments,
26862
27654
  listWorkspaces: () => listWorkspaces
26863
27655
  });
26864
- async function wikiFetch(config, path44, method = "GET", body) {
26865
- const url = `${config.baseUrl}/api/v1${path44}`;
27656
+ async function wikiFetch(config, path45, method = "GET", body) {
27657
+ const url = `${config.baseUrl}/api/v1${path45}`;
26866
27658
  const headers = {
26867
27659
  Authorization: `Bearer ${config.apiKey}`,
26868
27660
  "Content-Type": "application/json"
@@ -26895,7 +27687,7 @@ async function wikiFetch(config, path44, method = "GET", body) {
26895
27687
  }
26896
27688
  }
26897
27689
  if (!response.ok) {
26898
- throw new Error(`Wiki API ${method} ${path44}: ${response.status} ${response.statusText}`);
27690
+ throw new Error(`Wiki API ${method} ${path45}: ${response.status} ${response.statusText}`);
26899
27691
  }
26900
27692
  return response.json();
26901
27693
  } finally {
@@ -27529,8 +28321,8 @@ function SettingsView({ onBack }) {
27529
28321
  let version = "unknown";
27530
28322
  try {
27531
28323
  const { readFileSync: readFileSync27 } = await import("fs");
27532
- const { createRequire } = await import("module");
27533
- const require2 = createRequire(import.meta.url);
28324
+ const { createRequire: createRequire2 } = await import("module");
28325
+ const require2 = createRequire2(import.meta.url);
27534
28326
  const pkgPath = require2.resolve("@askexenow/exe-os/package.json");
27535
28327
  const pkg = JSON.parse(readFileSync27(pkgPath, "utf8"));
27536
28328
  version = pkg.version;
@@ -28340,11 +29132,11 @@ __export(installer_exports2, {
28340
29132
  });
28341
29133
  import { readFile as readFile6, writeFile as writeFile7, mkdir as mkdir7 } from "fs/promises";
28342
29134
  import { existsSync as existsSync27, readFileSync as readFileSync25 } from "fs";
28343
- import path41 from "path";
28344
- import os16 from "os";
28345
- async function registerOpenCodeMcp(packageRoot, homeDir = os16.homedir()) {
28346
- const configDir = path41.join(homeDir, ".config", "opencode");
28347
- 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");
28348
29140
  await mkdir7(configDir, { recursive: true });
28349
29141
  let config = {};
28350
29142
  if (existsSync27(configPath)) {
@@ -28359,7 +29151,7 @@ async function registerOpenCodeMcp(packageRoot, homeDir = os16.homedir()) {
28359
29151
  }
28360
29152
  const newEntry = {
28361
29153
  type: "local",
28362
- command: ["node", path41.join(packageRoot, "dist", "mcp", "server.js")],
29154
+ command: ["node", path42.join(packageRoot, "dist", "mcp", "server.js")],
28363
29155
  enabled: true
28364
29156
  };
28365
29157
  const current = config.mcp["exe-os"];
@@ -28373,9 +29165,9 @@ async function registerOpenCodeMcp(packageRoot, homeDir = os16.homedir()) {
28373
29165
  await writeFile7(configPath, JSON.stringify(config, null, 2) + "\n");
28374
29166
  return true;
28375
29167
  }
28376
- async function installOpenCodePlugin(packageRoot, homeDir = os16.homedir()) {
28377
- const pluginDir = path41.join(homeDir, ".config", "opencode", "plugins");
28378
- 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");
28379
29171
  await mkdir7(pluginDir, { recursive: true });
28380
29172
  const pluginContent = PLUGIN_TEMPLATE.replace(
28381
29173
  /__PACKAGE_ROOT__/g,
@@ -28390,9 +29182,9 @@ async function installOpenCodePlugin(packageRoot, homeDir = os16.homedir()) {
28390
29182
  await writeFile7(pluginPath, pluginContent);
28391
29183
  return true;
28392
29184
  }
28393
- function verifyOpenCodeHooks(homeDir = os16.homedir()) {
28394
- const configPath = path41.join(homeDir, ".config", "opencode", "opencode.json");
28395
- 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");
28396
29188
  if (!existsSync27(configPath)) return false;
28397
29189
  try {
28398
29190
  const config = JSON.parse(readFileSync25(configPath, "utf-8"));
@@ -28434,13 +29226,13 @@ __export(installer_exports3, {
28434
29226
  });
28435
29227
  import { readFile as readFile7, writeFile as writeFile8, mkdir as mkdir8 } from "fs/promises";
28436
29228
  import { existsSync as existsSync28 } from "fs";
28437
- import path42 from "path";
28438
- import os17 from "os";
28439
- async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28440
- const codexDir = path42.join(homeDir, ".codex");
28441
- const hooksPath = path42.join(codexDir, "hooks.json");
28442
- const logsDir = path42.join(homeDir, ".exe-os", "logs");
28443
- 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");
28444
29236
  const logSuffix = ` 2>> "${hookLogPath}"`;
28445
29237
  await mkdir8(codexDir, { recursive: true });
28446
29238
  await mkdir8(logsDir, { recursive: true });
@@ -28462,7 +29254,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28462
29254
  hooks: [
28463
29255
  {
28464
29256
  type: "command",
28465
- command: `node "${path42.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
29257
+ command: `node "${path43.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
28466
29258
  timeout: 30,
28467
29259
  statusMessage: "exe-os: loading memory brief"
28468
29260
  }
@@ -28477,11 +29269,11 @@ async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28477
29269
  hooks: [
28478
29270
  {
28479
29271
  type: "command",
28480
- command: `node "${path42.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
29272
+ command: `node "${path43.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
28481
29273
  },
28482
29274
  {
28483
29275
  type: "command",
28484
- command: `node "${path42.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
29276
+ command: `node "${path43.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
28485
29277
  }
28486
29278
  ]
28487
29279
  },
@@ -28493,11 +29285,11 @@ async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28493
29285
  hooks: [
28494
29286
  {
28495
29287
  type: "command",
28496
- command: `node "${path42.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
29288
+ command: `node "${path43.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
28497
29289
  },
28498
29290
  {
28499
29291
  type: "command",
28500
- 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}`,
28501
29293
  timeout: 5
28502
29294
  }
28503
29295
  ]
@@ -28510,7 +29302,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28510
29302
  hooks: [
28511
29303
  {
28512
29304
  type: "command",
28513
- command: `node "${path42.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
29305
+ command: `node "${path43.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
28514
29306
  }
28515
29307
  ]
28516
29308
  },
@@ -28523,7 +29315,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28523
29315
  hooks: [
28524
29316
  {
28525
29317
  type: "command",
28526
- 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}`
28527
29319
  }
28528
29320
  ]
28529
29321
  },
@@ -28554,15 +29346,15 @@ async function mergeCodexHooks(packageRoot, homeDir = os17.homedir()) {
28554
29346
  await writeFile8(hooksPath, JSON.stringify(hooksJson, null, 2) + "\n");
28555
29347
  return { added, skipped };
28556
29348
  }
28557
- function verifyCodexHooks(homeDir = os17.homedir()) {
28558
- const hooksPath = path42.join(homeDir, ".codex", "hooks.json");
29349
+ function verifyCodexHooks(homeDir = os18.homedir()) {
29350
+ const hooksPath = path43.join(homeDir, ".codex", "hooks.json");
28559
29351
  if (!existsSync28(hooksPath)) return false;
28560
29352
  try {
28561
29353
  const hooksJson = JSON.parse(
28562
29354
  __require("fs").readFileSync(hooksPath, "utf-8")
28563
29355
  );
28564
29356
  if (!hooksJson.hooks) return false;
28565
- const required = ["SessionStart", "PostToolUse", "UserPromptSubmit", "Stop"];
29357
+ const required = ["SessionStart", "PostToolUse", "UserPromptSubmit", "Stop", "PreToolUse"];
28566
29358
  for (const event of required) {
28567
29359
  const groups = hooksJson.hooks[event];
28568
29360
  if (!groups || !groups.some(
@@ -28576,11 +29368,11 @@ function verifyCodexHooks(homeDir = os17.homedir()) {
28576
29368
  return false;
28577
29369
  }
28578
29370
  }
28579
- async function installCodexStatusLine(homeDir = os17.homedir()) {
29371
+ async function installCodexStatusLine(homeDir = os18.homedir()) {
28580
29372
  const prefs = loadPreferences(homeDir);
28581
29373
  if (prefs.codexStatusLine === false) return "opted-out";
28582
- const codexDir = path42.join(homeDir, ".codex");
28583
- const configPath = path42.join(codexDir, "config.toml");
29374
+ const codexDir = path43.join(homeDir, ".codex");
29375
+ const configPath = path43.join(codexDir, "config.toml");
28584
29376
  await mkdir8(codexDir, { recursive: true });
28585
29377
  let content = "";
28586
29378
  if (existsSync28(configPath)) {
@@ -28632,12 +29424,12 @@ var init_installer3 = __esm({
28632
29424
 
28633
29425
  // src/bin/cli.ts
28634
29426
  import { existsSync as existsSync29, readFileSync as readFileSync26, writeFileSync as writeFileSync19, readdirSync as readdirSync9, rmSync } from "fs";
28635
- import path43 from "path";
28636
- import os18 from "os";
29427
+ import path44 from "path";
29428
+ import os19 from "os";
28637
29429
  var args = process.argv.slice(2);
28638
29430
  if (args.includes("--version") || args.includes("-v")) {
28639
29431
  try {
28640
- 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");
28641
29433
  const pkg = JSON.parse(readFileSync26(pkgPath, "utf8"));
28642
29434
  console.log(pkg.version);
28643
29435
  } catch {
@@ -28802,8 +29594,8 @@ ID: ${result.id}`);
28802
29594
  });
28803
29595
  await init_App2().then(() => App_exports);
28804
29596
  } else {
28805
- const claudeDir = path43.join(os18.homedir(), ".claude");
28806
- const settingsPath = path43.join(claudeDir, "settings.json");
29597
+ const claudeDir = path44.join(os19.homedir(), ".claude");
29598
+ const settingsPath = path44.join(claudeDir, "settings.json");
28807
29599
  const hasClaudeCode = existsSync29(settingsPath) && (() => {
28808
29600
  try {
28809
29601
  const raw = readFileSync26(settingsPath, "utf8");
@@ -28816,7 +29608,7 @@ ID: ${result.id}`);
28816
29608
  const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
28817
29609
  let cooName = DEFAULT_COORDINATOR_TEMPLATE_NAME2;
28818
29610
  try {
28819
- const rosterPath = path43.join(os18.homedir(), ".exe-os", "exe-employees.json");
29611
+ const rosterPath = path44.join(os19.homedir(), ".exe-os", "exe-employees.json");
28820
29612
  if (existsSync29(rosterPath)) {
28821
29613
  const roster = JSON.parse(readFileSync26(rosterPath, "utf8"));
28822
29614
  const coo = roster.find((e) => e.role === "COO");
@@ -28882,9 +29674,9 @@ async function runCodexInstall() {
28882
29674
  }
28883
29675
  }
28884
29676
  async function runClaudeCheck() {
28885
- const claudeDir = path43.join(os18.homedir(), ".claude");
28886
- const settingsPath = path43.join(claudeDir, "settings.json");
28887
- 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");
28888
29680
  let ok = true;
28889
29681
  if (existsSync29(settingsPath)) {
28890
29682
  let settings;
@@ -28937,7 +29729,7 @@ async function runClaudeCheck() {
28937
29729
  console.log("\x1B[31m\u2717\x1B[0m claude.json not found");
28938
29730
  ok = false;
28939
29731
  }
28940
- const skillsDir = path43.join(claudeDir, "skills");
29732
+ const skillsDir = path44.join(claudeDir, "skills");
28941
29733
  if (existsSync29(skillsDir)) {
28942
29734
  console.log("\x1B[32m\u2713\x1B[0m Slash skills directory exists");
28943
29735
  } else {
@@ -28954,11 +29746,11 @@ async function runClaudeCheck() {
28954
29746
  async function runClaudeUninstall(flags = []) {
28955
29747
  const dryRun = flags.includes("--dry-run");
28956
29748
  const purge = flags.includes("--purge");
28957
- const homeDir = os18.homedir();
28958
- const claudeDir = path43.join(homeDir, ".claude");
28959
- const settingsPath = path43.join(claudeDir, "settings.json");
28960
- const claudeJsonPath = path43.join(homeDir, ".claude.json");
28961
- 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");
28962
29754
  let removed = 0;
28963
29755
  const log = (msg) => console.log(dryRun ? `[dry-run] ${msg}` : msg);
28964
29756
  let settings = {};
@@ -29039,14 +29831,14 @@ async function runClaudeUninstall(flags = []) {
29039
29831
  }
29040
29832
  }
29041
29833
  }
29042
- const skillsDir = path43.join(claudeDir, "skills");
29834
+ const skillsDir = path44.join(claudeDir, "skills");
29043
29835
  if (existsSync29(skillsDir)) {
29044
29836
  let skillCount = 0;
29045
29837
  try {
29046
29838
  const entries = readdirSync9(skillsDir);
29047
29839
  for (const entry of entries) {
29048
29840
  if (entry.startsWith("exe")) {
29049
- const fullPath = path43.join(skillsDir, entry);
29841
+ const fullPath = path44.join(skillsDir, entry);
29050
29842
  if (!dryRun) rmSync(fullPath, { recursive: true, force: true });
29051
29843
  skillCount++;
29052
29844
  }
@@ -29058,7 +29850,7 @@ async function runClaudeUninstall(flags = []) {
29058
29850
  removed++;
29059
29851
  }
29060
29852
  }
29061
- const claudeMdPath = path43.join(claudeDir, "CLAUDE.md");
29853
+ const claudeMdPath = path44.join(claudeDir, "CLAUDE.md");
29062
29854
  if (existsSync29(claudeMdPath)) {
29063
29855
  const content = readFileSync26(claudeMdPath, "utf8");
29064
29856
  const startMarker = "<!-- exe-os:orchestration-start -->";
@@ -29072,13 +29864,13 @@ async function runClaudeUninstall(flags = []) {
29072
29864
  removed++;
29073
29865
  }
29074
29866
  }
29075
- const agentsDir = path43.join(claudeDir, "agents");
29867
+ const agentsDir = path44.join(claudeDir, "agents");
29076
29868
  if (existsSync29(agentsDir)) {
29077
29869
  let agentCount = 0;
29078
29870
  try {
29079
29871
  const entries = readdirSync9(agentsDir).filter((f) => f.endsWith(".md"));
29080
29872
  let knownNames = /* @__PURE__ */ new Set();
29081
- const rosterPath = path43.join(exeOsDir, "exe-employees.json");
29873
+ const rosterPath = path44.join(exeOsDir, "exe-employees.json");
29082
29874
  if (existsSync29(rosterPath)) {
29083
29875
  try {
29084
29876
  const roster = JSON.parse(readFileSync26(rosterPath, "utf8"));
@@ -29089,7 +29881,7 @@ async function runClaudeUninstall(flags = []) {
29089
29881
  for (const entry of entries) {
29090
29882
  const name = entry.replace(/\.md$/, "");
29091
29883
  if (knownNames.has(name)) {
29092
- if (!dryRun) rmSync(path43.join(agentsDir, entry), { force: true });
29884
+ if (!dryRun) rmSync(path44.join(agentsDir, entry), { force: true });
29093
29885
  agentCount++;
29094
29886
  }
29095
29887
  }
@@ -29100,13 +29892,13 @@ async function runClaudeUninstall(flags = []) {
29100
29892
  removed++;
29101
29893
  }
29102
29894
  }
29103
- const projectsDir = path43.join(claudeDir, "projects");
29895
+ const projectsDir = path44.join(claudeDir, "projects");
29104
29896
  if (existsSync29(projectsDir)) {
29105
29897
  let projectCount = 0;
29106
29898
  try {
29107
29899
  const projects = readdirSync9(projectsDir);
29108
29900
  for (const proj of projects) {
29109
- const projSettings = path43.join(projectsDir, proj, "settings.json");
29901
+ const projSettings = path44.join(projectsDir, proj, "settings.json");
29110
29902
  if (!existsSync29(projSettings)) continue;
29111
29903
  try {
29112
29904
  const pSettings = JSON.parse(readFileSync26(projSettings, "utf8"));
@@ -29143,9 +29935,9 @@ async function runClaudeUninstall(flags = []) {
29143
29935
  };
29144
29936
  const exeBinPath = findExeBin3();
29145
29937
  if (!exeBinPath) throw new Error("exe-os not found in PATH");
29146
- const binDir = path43.dirname(exeBinPath);
29938
+ const binDir = path44.dirname(exeBinPath);
29147
29939
  let symlinkCount = 0;
29148
- const rosterPath = path43.join(exeOsDir, "exe-employees.json");
29940
+ const rosterPath = path44.join(exeOsDir, "exe-employees.json");
29149
29941
  if (existsSync29(rosterPath)) {
29150
29942
  const roster = JSON.parse(readFileSync26(rosterPath, "utf8"));
29151
29943
  const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
@@ -29153,7 +29945,7 @@ async function runClaudeUninstall(flags = []) {
29153
29945
  for (const emp of roster) {
29154
29946
  if (emp.name === coordinatorName) continue;
29155
29947
  for (const suffix of ["", "-opencode"]) {
29156
- const linkPath = path43.join(binDir, `${emp.name}${suffix}`);
29948
+ const linkPath = path44.join(binDir, `${emp.name}${suffix}`);
29157
29949
  if (existsSync29(linkPath)) {
29158
29950
  if (!dryRun) rmSync(linkPath, { force: true });
29159
29951
  symlinkCount++;
@@ -29192,7 +29984,7 @@ async function checkForUpdateOnBoot() {
29192
29984
  const config = await loadConfig2();
29193
29985
  if (!config.autoUpdate.checkOnBoot) return;
29194
29986
  const { checkForUpdate: checkForUpdate2 } = await Promise.resolve().then(() => (init_update(), update_exports));
29195
- const packageRoot = path43.resolve(
29987
+ const packageRoot = path44.resolve(
29196
29988
  new URL("../..", import.meta.url).pathname
29197
29989
  );
29198
29990
  const result = checkForUpdate2(packageRoot);
@@ -29252,7 +30044,7 @@ async function runActivate(key) {
29252
30044
  const idTemplate = getIdentityTemplate(identityKey);
29253
30045
  if (idTemplate) {
29254
30046
  const idPath = identityPath2(name);
29255
- const dir = path43.dirname(idPath);
30047
+ const dir = path44.dirname(idPath);
29256
30048
  if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
29257
30049
  fs8.writeFileSync(idPath, idTemplate.replace(/^agent_id: \w+/m, `agent_id: ${name}`), "utf-8");
29258
30050
  }