@askexenow/exe-os 0.9.65 → 0.9.67

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 (113) hide show
  1. package/deploy/stack-manifests/v0.9.json +54 -5
  2. package/dist/bin/age-ontology-load.js +61 -0
  3. package/dist/bin/agentic-ontology-backfill.js +4708 -0
  4. package/dist/bin/agentic-reflection-backfill.js +4144 -0
  5. package/dist/bin/{exe-link.js → agentic-semantic-label.js} +1532 -2173
  6. package/dist/bin/backfill-conversations.js +528 -20
  7. package/dist/bin/backfill-responses.js +528 -20
  8. package/dist/bin/backfill-vectors.js +255 -20
  9. package/dist/bin/bulk-sync-postgres.js +4876 -0
  10. package/dist/bin/cleanup-stale-review-tasks.js +529 -21
  11. package/dist/bin/cli.js +3471 -1491
  12. package/dist/bin/exe-agent-config.js +4 -0
  13. package/dist/bin/exe-agent.js +16 -0
  14. package/dist/bin/exe-assign.js +528 -20
  15. package/dist/bin/exe-boot.js +492 -54
  16. package/dist/bin/exe-call.js +16 -0
  17. package/dist/bin/exe-cloud.js +7415 -518
  18. package/dist/bin/exe-dispatch.js +540 -22
  19. package/dist/bin/exe-doctor.js +3404 -1225
  20. package/dist/bin/exe-export-behaviors.js +542 -24
  21. package/dist/bin/exe-forget.js +529 -21
  22. package/dist/bin/exe-gateway.js +595 -25
  23. package/dist/bin/exe-heartbeat.js +541 -24
  24. package/dist/bin/exe-kill.js +529 -21
  25. package/dist/bin/exe-launch-agent.js +2334 -1067
  26. package/dist/bin/exe-new-employee.js +324 -166
  27. package/dist/bin/exe-pending-messages.js +529 -21
  28. package/dist/bin/exe-pending-notifications.js +529 -21
  29. package/dist/bin/exe-pending-reviews.js +529 -21
  30. package/dist/bin/exe-rename.js +529 -21
  31. package/dist/bin/exe-review.js +529 -21
  32. package/dist/bin/exe-search.js +542 -24
  33. package/dist/bin/exe-session-cleanup.js +540 -22
  34. package/dist/bin/exe-settings.js +14 -0
  35. package/dist/bin/exe-start-codex.js +817 -144
  36. package/dist/bin/exe-start-opencode.js +776 -80
  37. package/dist/bin/exe-status.js +529 -21
  38. package/dist/bin/exe-team.js +529 -21
  39. package/dist/bin/git-sweep.js +540 -22
  40. package/dist/bin/graph-backfill.js +580 -21
  41. package/dist/bin/graph-export.js +529 -21
  42. package/dist/bin/graph-layer-benchmark.js +109 -0
  43. package/dist/bin/install.js +420 -289
  44. package/dist/bin/intercom-check.js +540 -22
  45. package/dist/bin/postgres-agentic-reflection-backfill.js +187 -0
  46. package/dist/bin/postgres-agentic-semantic-backfill.js +237 -0
  47. package/dist/bin/scan-tasks.js +540 -22
  48. package/dist/bin/setup.js +790 -206
  49. package/dist/bin/shard-migrate.js +528 -20
  50. package/dist/bin/update.js +4 -0
  51. package/dist/gateway/index.js +593 -23
  52. package/dist/hooks/bug-report-worker.js +651 -64
  53. package/dist/hooks/codex-stop-task-finalizer.js +540 -22
  54. package/dist/hooks/commit-complete.js +540 -22
  55. package/dist/hooks/error-recall.js +542 -24
  56. package/dist/hooks/exe-heartbeat-hook.js +4 -0
  57. package/dist/hooks/ingest-worker.js +4 -0
  58. package/dist/hooks/ingest.js +539 -22
  59. package/dist/hooks/instructions-loaded.js +529 -21
  60. package/dist/hooks/notification.js +529 -21
  61. package/dist/hooks/post-compact.js +529 -21
  62. package/dist/hooks/post-tool-combined.js +543 -25
  63. package/dist/hooks/pre-compact.js +772 -127
  64. package/dist/hooks/pre-tool-use.js +529 -21
  65. package/dist/hooks/prompt-submit.js +543 -25
  66. package/dist/hooks/session-end.js +673 -140
  67. package/dist/hooks/session-start.js +662 -26
  68. package/dist/hooks/stop.js +540 -23
  69. package/dist/hooks/subagent-stop.js +529 -21
  70. package/dist/hooks/summary-worker.js +571 -126
  71. package/dist/index.js +593 -23
  72. package/dist/lib/agent-config.js +4 -0
  73. package/dist/lib/cloud-sync.js +408 -47
  74. package/dist/lib/config.js +25 -1
  75. package/dist/lib/consolidation.js +5 -1
  76. package/dist/lib/database.js +128 -0
  77. package/dist/lib/db-daemon-client.js +4 -0
  78. package/dist/lib/db.js +128 -0
  79. package/dist/lib/device-registry.js +128 -0
  80. package/dist/lib/embedder.js +25 -1
  81. package/dist/lib/employee-templates.js +16 -0
  82. package/dist/lib/employees.js +4 -0
  83. package/dist/lib/exe-daemon-client.js +4 -0
  84. package/dist/lib/exe-daemon.js +3158 -930
  85. package/dist/lib/hybrid-search.js +542 -24
  86. package/dist/lib/identity.js +7 -0
  87. package/dist/lib/keychain.js +178 -22
  88. package/dist/lib/license.js +4 -0
  89. package/dist/lib/messaging.js +7 -0
  90. package/dist/lib/reminders.js +7 -0
  91. package/dist/lib/schedules.js +255 -20
  92. package/dist/lib/skill-learning.js +28 -1
  93. package/dist/lib/status-brief.js +39 -0
  94. package/dist/lib/store.js +528 -20
  95. package/dist/lib/task-router.js +4 -0
  96. package/dist/lib/tasks.js +28 -1
  97. package/dist/lib/tmux-routing.js +28 -1
  98. package/dist/lib/token-spend.js +7 -0
  99. package/dist/mcp/server.js +2739 -813
  100. package/dist/mcp/tools/complete-reminder.js +7 -0
  101. package/dist/mcp/tools/create-reminder.js +7 -0
  102. package/dist/mcp/tools/create-task.js +28 -1
  103. package/dist/mcp/tools/deactivate-behavior.js +7 -0
  104. package/dist/mcp/tools/list-reminders.js +7 -0
  105. package/dist/mcp/tools/list-tasks.js +7 -0
  106. package/dist/mcp/tools/send-message.js +7 -0
  107. package/dist/mcp/tools/update-task.js +28 -1
  108. package/dist/runtime/index.js +540 -22
  109. package/dist/tui/App.js +618 -29
  110. package/package.json +9 -5
  111. package/src/commands/exe/cloud.md +11 -8
  112. package/stack.release.json +3 -3
  113. package/src/commands/exe/link.md +0 -17
@@ -1,12 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
- }) : x)(function(x) {
7
- if (typeof require !== "undefined") return require.apply(this, arguments);
8
- throw Error('Dynamic require of "' + x + '" is not supported');
9
- });
10
4
  var __esm = (fn, res) => function __init() {
11
5
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
6
  };
@@ -127,6 +121,10 @@ var init_config = __esm({
127
121
  checkOnBoot: true,
128
122
  autoInstall: false,
129
123
  checkIntervalMs: 24 * 60 * 60 * 1e3
124
+ },
125
+ orchestration: {
126
+ phase: "phase_1_coo",
127
+ phaseSetBy: "default"
130
128
  }
131
129
  };
132
130
  }
@@ -608,6 +606,63 @@ var init_preferences = __esm({
608
606
  }
609
607
  });
610
608
 
609
+ // src/adapters/mcp-http-config.ts
610
+ import { chmodSync as chmodSync2, existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
611
+ import { randomBytes } from "crypto";
612
+ import path6 from "path";
613
+ import os5 from "os";
614
+ function mcpHttpPort() {
615
+ return process.env.EXE_MCP_PORT || DEFAULT_MCP_HTTP_PORT;
616
+ }
617
+ function mcpHttpUrl() {
618
+ return `http://127.0.0.1:${mcpHttpPort()}/mcp`;
619
+ }
620
+ function readOrCreateDaemonToken(homeDir = os5.homedir()) {
621
+ const exeDir = path6.join(homeDir, ".exe-os");
622
+ const tokenPath = path6.join(exeDir, "exed.token");
623
+ if (existsSync7(tokenPath)) {
624
+ try {
625
+ const token2 = readFileSync5(tokenPath, "utf-8").trim();
626
+ if (/^[a-f0-9]{64}$/i.test(token2)) return token2;
627
+ } catch {
628
+ }
629
+ }
630
+ const token = randomBytes(32).toString("hex");
631
+ mkdirSync3(exeDir, { recursive: true });
632
+ writeFileSync4(tokenPath, `${token}
633
+ `, "utf-8");
634
+ try {
635
+ chmodSync2(tokenPath, 384);
636
+ } catch {
637
+ }
638
+ return token;
639
+ }
640
+ function buildMcpHttpHeaders(homeDir = os5.homedir(), opts = {}) {
641
+ const agentId = opts.useShellPlaceholders ? "${AGENT_ID:-exe}" : opts.agentId ?? DEFAULT_MCP_HTTP_AGENT_ID;
642
+ const agentRole = opts.useShellPlaceholders ? "${AGENT_ROLE:-COO}" : opts.agentRole ?? DEFAULT_MCP_HTTP_AGENT_ROLE;
643
+ return {
644
+ Authorization: `Bearer ${readOrCreateDaemonToken(homeDir)}`,
645
+ "X-Agent-Id": agentId,
646
+ "X-Agent-Role": agentRole
647
+ };
648
+ }
649
+ function buildClaudeHttpMcpEntry(homeDir = os5.homedir()) {
650
+ return {
651
+ type: "http",
652
+ url: mcpHttpUrl(),
653
+ headers: buildMcpHttpHeaders(homeDir, { useShellPlaceholders: true })
654
+ };
655
+ }
656
+ var DEFAULT_MCP_HTTP_PORT, DEFAULT_MCP_HTTP_AGENT_ID, DEFAULT_MCP_HTTP_AGENT_ROLE;
657
+ var init_mcp_http_config = __esm({
658
+ "src/adapters/mcp-http-config.ts"() {
659
+ "use strict";
660
+ DEFAULT_MCP_HTTP_PORT = "48739";
661
+ DEFAULT_MCP_HTTP_AGENT_ID = "exe";
662
+ DEFAULT_MCP_HTTP_AGENT_ROLE = "COO";
663
+ }
664
+ });
665
+
611
666
  // src/adapters/runtime-hook-manifest.ts
612
667
  function commandHasAnyMarker(command, markers) {
613
668
  return markers.some((marker) => command.includes(marker));
@@ -615,7 +670,7 @@ function commandHasAnyMarker(command, markers) {
615
670
  function isLegacySplitPostToolCommand(command) {
616
671
  return commandHasAnyMarker(command, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS);
617
672
  }
618
- var EXE_HOOKS, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
673
+ var EXE_HOOKS, EXE_HOOK_MANIFEST, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
619
674
  var init_runtime_hook_manifest = __esm({
620
675
  "src/adapters/runtime-hook-manifest.ts"() {
621
676
  "use strict";
@@ -633,6 +688,116 @@ var init_runtime_hook_manifest = __esm({
633
688
  notification: "dist/hooks/notification.js",
634
689
  instructionsLoaded: "dist/hooks/instructions-loaded.js"
635
690
  };
691
+ EXE_HOOK_MANIFEST = [
692
+ {
693
+ key: "postToolCombined",
694
+ event: "PostToolUse",
695
+ commandMarker: EXE_HOOKS.postToolCombined,
696
+ owner: "exe-os",
697
+ purpose: "Single PostToolUse entrypoint for ingestion, error recall, summaries, and bug detection.",
698
+ runtimes: ["claude", "codex", "opencode"],
699
+ checkpointRole: "none"
700
+ },
701
+ {
702
+ key: "sessionStart",
703
+ event: "SessionStart",
704
+ commandMarker: EXE_HOOKS.sessionStart,
705
+ owner: "exe-os",
706
+ purpose: "Loads agent identity, procedures, and boot context.",
707
+ runtimes: ["claude", "codex", "opencode"],
708
+ checkpointRole: "none"
709
+ },
710
+ {
711
+ key: "promptSubmit",
712
+ event: "UserPromptSubmit",
713
+ commandMarker: EXE_HOOKS.promptSubmit,
714
+ owner: "exe-os",
715
+ purpose: "Injects current tasks, pending reviews, and local context before each prompt.",
716
+ runtimes: ["claude", "codex", "opencode"],
717
+ checkpointRole: "none"
718
+ },
719
+ {
720
+ key: "heartbeat",
721
+ event: "UserPromptSubmit",
722
+ commandMarker: EXE_HOOKS.heartbeat,
723
+ owner: "exe-os",
724
+ purpose: "Lightweight heartbeat/status sidecar for Claude Code sessions.",
725
+ runtimes: ["claude"],
726
+ checkpointRole: "none"
727
+ },
728
+ {
729
+ key: "stop",
730
+ event: "Stop",
731
+ commandMarker: EXE_HOOKS.stop,
732
+ owner: "exe-os",
733
+ purpose: "Finalizes task state, capacity signals, and emergency checkpointing.",
734
+ runtimes: ["claude", "codex", "opencode"],
735
+ checkpointRole: "capacity_checkpoint"
736
+ },
737
+ {
738
+ key: "preToolUse",
739
+ event: "PreToolUse",
740
+ commandMarker: EXE_HOOKS.preToolUse,
741
+ owner: "exe-os",
742
+ purpose: "Preflight guardrails before shell/tool execution.",
743
+ runtimes: ["claude", "codex", "opencode"],
744
+ checkpointRole: "none"
745
+ },
746
+ {
747
+ key: "subagentStop",
748
+ event: "SubagentStop",
749
+ commandMarker: EXE_HOOKS.subagentStop,
750
+ owner: "exe-os",
751
+ purpose: "Captures subagent completion context.",
752
+ runtimes: ["claude"],
753
+ checkpointRole: "none"
754
+ },
755
+ {
756
+ key: "preCompact",
757
+ event: "PreCompact",
758
+ commandMarker: EXE_HOOKS.preCompact,
759
+ owner: "exe-os",
760
+ purpose: "Writes active-task snapshot and compaction recovery context.",
761
+ runtimes: ["claude"],
762
+ checkpointRole: "recovery_context"
763
+ },
764
+ {
765
+ key: "postCompact",
766
+ event: "PostCompact",
767
+ commandMarker: EXE_HOOKS.postCompact,
768
+ owner: "exe-os",
769
+ purpose: "Rehydrates recovery context after compaction.",
770
+ runtimes: ["claude"],
771
+ checkpointRole: "recovery_context"
772
+ },
773
+ {
774
+ key: "sessionEnd",
775
+ event: "SessionEnd",
776
+ commandMarker: EXE_HOOKS.sessionEnd,
777
+ owner: "exe-os",
778
+ purpose: "Stores session-end checkpoint and triages orphaned in-progress tasks.",
779
+ runtimes: ["claude"],
780
+ checkpointRole: "session_summary"
781
+ },
782
+ {
783
+ key: "notification",
784
+ event: "Notification",
785
+ commandMarker: EXE_HOOKS.notification,
786
+ owner: "exe-os",
787
+ purpose: "Captures runtime notifications and nudges.",
788
+ runtimes: ["claude"],
789
+ checkpointRole: "none"
790
+ },
791
+ {
792
+ key: "instructionsLoaded",
793
+ event: "InstructionsLoaded",
794
+ commandMarker: EXE_HOOKS.instructionsLoaded,
795
+ owner: "exe-os",
796
+ purpose: "Applies runtime instruction post-processing.",
797
+ runtimes: ["claude"],
798
+ checkpointRole: "none"
799
+ }
800
+ ];
636
801
  LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS = [
637
802
  "dist/hooks/ingest.js",
638
803
  "dist/hooks/error-recall.js",
@@ -642,54 +807,58 @@ var init_runtime_hook_manifest = __esm({
642
807
  });
643
808
 
644
809
  // src/adapters/claude/installer.ts
645
- import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
646
- import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4, copyFileSync, mkdirSync as mkdirSync3, chmodSync as chmodSync2 } from "fs";
647
- import { createHash, randomBytes } from "crypto";
648
- import path6 from "path";
649
- import os5 from "os";
810
+ import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir, rm } from "fs/promises";
811
+ import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync5, copyFileSync, mkdirSync as mkdirSync4 } from "fs";
812
+ import { createHash } from "crypto";
813
+ import path7 from "path";
814
+ import os6 from "os";
650
815
  import { execSync as execSync2 } from "child_process";
651
816
  import { fileURLToPath } from "url";
652
817
  function resolvePackageRoot() {
653
818
  const thisFile = fileURLToPath(import.meta.url);
654
- let dir = path6.dirname(thisFile);
655
- const root = path6.parse(dir).root;
819
+ let dir = path7.dirname(thisFile);
820
+ const root = path7.parse(dir).root;
656
821
  while (dir !== root) {
657
- const pkgPath = path6.join(dir, "package.json");
658
- if (existsSync7(pkgPath)) {
822
+ const pkgPath = path7.join(dir, "package.json");
823
+ if (existsSync8(pkgPath)) {
659
824
  try {
660
- const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
825
+ const pkg = JSON.parse(readFileSync6(pkgPath, "utf-8"));
661
826
  if (pkg.name === "@askexenow/exe-os" || pkg.name === "exe-os") return dir;
662
827
  } catch {
663
828
  }
664
829
  }
665
- dir = path6.dirname(dir);
830
+ dir = path7.dirname(dir);
666
831
  }
667
- return path6.resolve(path6.dirname(thisFile), "..", "..", "..");
832
+ return path7.resolve(path7.dirname(thisFile), "..", "..", "..");
668
833
  }
669
- async function copySlashCommands(packageRoot, homeDir = os5.homedir()) {
834
+ async function copySlashCommands(packageRoot, homeDir = os6.homedir()) {
670
835
  let copied = 0;
671
836
  let skipped = 0;
672
- const skillsBase = path6.join(homeDir, ".claude", "skills");
673
- const exeDir = path6.join(packageRoot, "src", "commands", "exe");
674
- if (existsSync7(exeDir)) {
837
+ const skillsBase = path7.join(homeDir, ".claude", "skills");
838
+ const deprecatedExeLink = path7.join(skillsBase, "exe-link");
839
+ if (existsSync8(deprecatedExeLink)) {
840
+ await rm(deprecatedExeLink, { recursive: true, force: true });
841
+ }
842
+ const exeDir = path7.join(packageRoot, "src", "commands", "exe");
843
+ if (existsSync8(exeDir)) {
675
844
  const entries = await readdir(exeDir);
676
845
  const mdFiles = entries.filter((f) => f.endsWith(".md"));
677
846
  for (const file of mdFiles) {
678
847
  const name = file.replace(".md", "");
679
- const destDir = path6.join(skillsBase, `exe-${name}`);
848
+ const destDir = path7.join(skillsBase, `exe-${name}`);
680
849
  await mkdir3(destDir, { recursive: true });
681
- const srcPath = path6.join(exeDir, file);
682
- const destPath = path6.join(destDir, "SKILL.md");
850
+ const srcPath = path7.join(exeDir, file);
851
+ const destPath = path7.join(destDir, "SKILL.md");
683
852
  const result = await copyAsSkill(srcPath, destPath, `exe-${name}`);
684
853
  if (result) copied++;
685
854
  else skipped++;
686
855
  }
687
856
  }
688
- const topLevelSrc = path6.join(packageRoot, "src", "commands", "exe.md");
689
- if (existsSync7(topLevelSrc)) {
690
- const destDir = path6.join(skillsBase, "exe");
857
+ const topLevelSrc = path7.join(packageRoot, "src", "commands", "exe.md");
858
+ if (existsSync8(topLevelSrc)) {
859
+ const destDir = path7.join(skillsBase, "exe");
691
860
  await mkdir3(destDir, { recursive: true });
692
- const destPath = path6.join(destDir, "SKILL.md");
861
+ const destPath = path7.join(destDir, "SKILL.md");
693
862
  const result = await copyAsSkill(topLevelSrc, destPath, "exe");
694
863
  if (result) copied++;
695
864
  else skipped++;
@@ -712,7 +881,7 @@ name: ${skillName}
712
881
  `);
713
882
  }
714
883
  }
715
- if (existsSync7(destPath)) {
884
+ if (existsSync8(destPath)) {
716
885
  const existing = await readFile3(destPath, "utf-8");
717
886
  if (existing === content) return false;
718
887
  }
@@ -721,32 +890,32 @@ name: ${skillName}
721
890
  }
722
891
  function readJsonFile(filePath) {
723
892
  try {
724
- return JSON.parse(readFileSync5(filePath, "utf-8"));
893
+ return JSON.parse(readFileSync6(filePath, "utf-8"));
725
894
  } catch {
726
895
  return null;
727
896
  }
728
897
  }
729
898
  function findAncestorMcpJsons(startDir, homeDir) {
730
899
  const files = [];
731
- let dir = path6.resolve(startDir);
732
- const root = path6.parse(dir).root;
733
- const stop = path6.resolve(homeDir);
900
+ let dir = path7.resolve(startDir);
901
+ const root = path7.parse(dir).root;
902
+ const stop = path7.resolve(homeDir);
734
903
  while (dir !== root) {
735
- const candidate = path6.join(dir, ".mcp.json");
736
- if (existsSync7(candidate)) files.push(candidate);
904
+ const candidate = path7.join(dir, ".mcp.json");
905
+ if (existsSync8(candidate)) files.push(candidate);
737
906
  if (dir === stop) break;
738
- dir = path6.dirname(dir);
907
+ dir = path7.dirname(dir);
739
908
  }
740
909
  return files;
741
910
  }
742
911
  function pathApplies(projectPath, cwd) {
743
- const project = path6.resolve(projectPath);
744
- const current = path6.resolve(cwd);
745
- return current === project || current.startsWith(project + path6.sep);
912
+ const project = path7.resolve(projectPath);
913
+ const current = path7.resolve(cwd);
914
+ return current === project || current.startsWith(project + path7.sep);
746
915
  }
747
- function detectMcpNameCollisions(homeDir = os5.homedir(), cwd = process.cwd()) {
748
- const claudeJsonPath = path6.join(homeDir, ".claude.json");
749
- if (!existsSync7(claudeJsonPath)) return [];
916
+ function detectMcpNameCollisions(homeDir = os6.homedir(), cwd = process.cwd()) {
917
+ const claudeJsonPath = path7.join(homeDir, ".claude.json");
918
+ if (!existsSync8(claudeJsonPath)) return [];
750
919
  const claudeJson = readJsonFile(claudeJsonPath);
751
920
  if (!claudeJson?.projects) return [];
752
921
  const collisions = [];
@@ -773,44 +942,11 @@ function detectMcpNameCollisions(homeDir = os5.homedir(), cwd = process.cwd()) {
773
942
  }
774
943
  return collisions;
775
944
  }
776
- function readOrCreateDaemonToken(homeDir) {
777
- const exeDir = path6.join(homeDir, ".exe-os");
778
- const tokenPath = path6.join(exeDir, "exed.token");
779
- try {
780
- if (existsSync7(tokenPath)) {
781
- const token2 = readFileSync5(tokenPath, "utf-8").trim();
782
- if (token2) return token2;
783
- }
784
- } catch {
785
- }
786
- const token = randomBytes(32).toString("hex");
787
- mkdirSync3(exeDir, { recursive: true });
788
- writeFileSync4(tokenPath, `${token}
789
- `, "utf-8");
790
- try {
791
- chmodSync2(tokenPath, 384);
792
- } catch {
793
- }
794
- return token;
795
- }
796
- function buildHttpMcpEntry(homeDir) {
797
- const port = process.env.EXE_MCP_PORT || "48739";
798
- const token = readOrCreateDaemonToken(homeDir);
799
- return {
800
- type: "http",
801
- url: `http://127.0.0.1:${port}/mcp`,
802
- headers: {
803
- Authorization: `Bearer ${token}`,
804
- "X-Agent-Id": "${AGENT_ID:-exe}",
805
- "X-Agent-Role": "${AGENT_ROLE:-COO}"
806
- }
807
- };
808
- }
809
945
  function buildStdioMcpEntry(packageRoot) {
810
946
  return {
811
947
  type: "stdio",
812
948
  command: "node",
813
- args: [path6.join(packageRoot, "dist", "mcp", "server.js")],
949
+ args: [path7.join(packageRoot, "dist", "mcp", "server.js")],
814
950
  env: {}
815
951
  };
816
952
  }
@@ -818,14 +954,14 @@ function mcpTransportMode() {
818
954
  const value = process.env.EXE_OS_MCP_TRANSPORT?.trim().toLowerCase();
819
955
  if (value === "stdio") return "stdio";
820
956
  if (value === "http") return "http";
821
- const totalGB = os5.totalmem() / (1024 * 1024 * 1024);
957
+ const totalGB = os6.totalmem() / (1024 * 1024 * 1024);
822
958
  if (totalGB <= 8) return "stdio";
823
959
  return "http";
824
960
  }
825
- async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
826
- const claudeJsonPath = path6.join(homeDir, ".claude.json");
961
+ async function registerMcpServer(packageRoot, homeDir = os6.homedir()) {
962
+ const claudeJsonPath = path7.join(homeDir, ".claude.json");
827
963
  let claudeJson = {};
828
- if (existsSync7(claudeJsonPath)) {
964
+ if (existsSync8(claudeJsonPath)) {
829
965
  try {
830
966
  claudeJson = JSON.parse(await readFile3(claudeJsonPath, "utf-8"));
831
967
  } catch {
@@ -835,7 +971,7 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
835
971
  if (!claudeJson.mcpServers) {
836
972
  claudeJson.mcpServers = {};
837
973
  }
838
- const newEntry = mcpTransportMode() === "stdio" ? buildStdioMcpEntry(packageRoot) : buildHttpMcpEntry(homeDir);
974
+ const newEntry = mcpTransportMode() === "stdio" ? buildStdioMcpEntry(packageRoot) : buildClaudeHttpMcpEntry(homeDir);
839
975
  if (claudeJson.mcpServers[MCP_LEGACY_KEY]) {
840
976
  delete claudeJson.mcpServers[MCP_LEGACY_KEY];
841
977
  process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
@@ -843,8 +979,8 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
843
979
  const currentOs = claudeJson.mcpServers[MCP_PRIMARY_KEY];
844
980
  const osMatches = currentOs && JSON.stringify(currentOs) === JSON.stringify(newEntry);
845
981
  if (osMatches) {
846
- await cleanSettingsJsonMcp(path6.join(homeDir, ".claude", "settings.json"));
847
- await migratePermissionsToExeOs(path6.join(homeDir, ".claude", "settings.json"));
982
+ await cleanSettingsJsonMcp(path7.join(homeDir, ".claude", "settings.json"));
983
+ await migratePermissionsToExeOs(path7.join(homeDir, ".claude", "settings.json"));
848
984
  const collisions2 = detectMcpNameCollisions(homeDir, packageRoot).filter((c) => c.serverName === MCP_PRIMARY_KEY || c.serverName === MCP_LEGACY_KEY);
849
985
  for (const c of collisions2) {
850
986
  process.stderr.write(
@@ -856,8 +992,8 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
856
992
  }
857
993
  claudeJson.mcpServers[MCP_PRIMARY_KEY] = newEntry;
858
994
  await writeFile3(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
859
- await cleanSettingsJsonMcp(path6.join(homeDir, ".claude", "settings.json"));
860
- await migratePermissionsToExeOs(path6.join(homeDir, ".claude", "settings.json"));
995
+ await cleanSettingsJsonMcp(path7.join(homeDir, ".claude", "settings.json"));
996
+ await migratePermissionsToExeOs(path7.join(homeDir, ".claude", "settings.json"));
861
997
  const collisions = detectMcpNameCollisions(homeDir, packageRoot).filter((c) => c.serverName === MCP_PRIMARY_KEY || c.serverName === MCP_LEGACY_KEY);
862
998
  for (const c of collisions) {
863
999
  process.stderr.write(
@@ -868,7 +1004,7 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
868
1004
  return true;
869
1005
  }
870
1006
  async function cleanSettingsJsonMcp(settingsPath) {
871
- if (!existsSync7(settingsPath)) return;
1007
+ if (!existsSync8(settingsPath)) return;
872
1008
  try {
873
1009
  const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
874
1010
  const servers = settings.mcpServers;
@@ -889,7 +1025,7 @@ async function cleanSettingsJsonMcp(settingsPath) {
889
1025
  }
890
1026
  }
891
1027
  async function migratePermissionsToExeOs(settingsPath) {
892
- if (!existsSync7(settingsPath)) return;
1028
+ if (!existsSync8(settingsPath)) return;
893
1029
  try {
894
1030
  const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
895
1031
  const permissions = settings.permissions;
@@ -917,14 +1053,14 @@ async function migratePermissionsToExeOs(settingsPath) {
917
1053
  } catch {
918
1054
  }
919
1055
  }
920
- async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
921
- const settingsPath = path6.join(homeDir, ".claude", "settings.json");
922
- const logsDir = path6.join(homeDir, ".exe-os", "logs");
923
- const hookLogPath = path6.join(logsDir, "hooks.log");
1056
+ async function mergeHooks(packageRoot, homeDir = os6.homedir()) {
1057
+ const settingsPath = path7.join(homeDir, ".claude", "settings.json");
1058
+ const logsDir = path7.join(homeDir, ".exe-os", "logs");
1059
+ const hookLogPath = path7.join(logsDir, "hooks.log");
924
1060
  const logSuffix = ` 2>> "${hookLogPath}"`;
925
1061
  await mkdir3(logsDir, { recursive: true });
926
1062
  let settings = {};
927
- if (existsSync7(settingsPath)) {
1063
+ if (existsSync8(settingsPath)) {
928
1064
  try {
929
1065
  settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
930
1066
  } catch {
@@ -946,7 +1082,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
946
1082
  hooks: [
947
1083
  {
948
1084
  type: "command",
949
- command: `node "${path6.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
1085
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
950
1086
  }
951
1087
  ]
952
1088
  },
@@ -958,7 +1094,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
958
1094
  hooks: [
959
1095
  {
960
1096
  type: "command",
961
- command: `node "${path6.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
1097
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
962
1098
  timeout: 1e4
963
1099
  }
964
1100
  ]
@@ -971,7 +1107,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
971
1107
  hooks: [
972
1108
  {
973
1109
  type: "command",
974
- command: `node "${path6.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
1110
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
975
1111
  }
976
1112
  ]
977
1113
  },
@@ -983,7 +1119,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
983
1119
  hooks: [
984
1120
  {
985
1121
  type: "command",
986
- command: `node "${path6.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
1122
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
987
1123
  timeout: 5e3
988
1124
  }
989
1125
  ]
@@ -996,7 +1132,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
996
1132
  hooks: [
997
1133
  {
998
1134
  type: "command",
999
- command: `node "${path6.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
1135
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
1000
1136
  }
1001
1137
  ]
1002
1138
  },
@@ -1009,7 +1145,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1009
1145
  hooks: [
1010
1146
  {
1011
1147
  type: "command",
1012
- command: `node "${path6.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
1148
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
1013
1149
  }
1014
1150
  ]
1015
1151
  },
@@ -1021,7 +1157,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1021
1157
  hooks: [
1022
1158
  {
1023
1159
  type: "command",
1024
- command: `node "${path6.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
1160
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
1025
1161
  }
1026
1162
  ]
1027
1163
  },
@@ -1033,7 +1169,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1033
1169
  hooks: [
1034
1170
  {
1035
1171
  type: "command",
1036
- command: `node "${path6.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
1172
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
1037
1173
  timeout: 1e4
1038
1174
  }
1039
1175
  ]
@@ -1046,7 +1182,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1046
1182
  hooks: [
1047
1183
  {
1048
1184
  type: "command",
1049
- command: `node "${path6.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
1185
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
1050
1186
  }
1051
1187
  ]
1052
1188
  },
@@ -1058,7 +1194,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1058
1194
  hooks: [
1059
1195
  {
1060
1196
  type: "command",
1061
- command: `node "${path6.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
1197
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
1062
1198
  }
1063
1199
  ]
1064
1200
  },
@@ -1070,7 +1206,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1070
1206
  hooks: [
1071
1207
  {
1072
1208
  type: "command",
1073
- command: `node "${path6.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
1209
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
1074
1210
  timeout: 1e4
1075
1211
  }
1076
1212
  ]
@@ -1083,7 +1219,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1083
1219
  hooks: [
1084
1220
  {
1085
1221
  type: "command",
1086
- command: `node "${path6.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
1222
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
1087
1223
  }
1088
1224
  ]
1089
1225
  },
@@ -1188,13 +1324,13 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1188
1324
  allowList.push(fullName);
1189
1325
  }
1190
1326
  }
1191
- await mkdir3(path6.dirname(settingsPath), { recursive: true });
1327
+ await mkdir3(path7.dirname(settingsPath), { recursive: true });
1192
1328
  await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
1193
1329
  return { added, skipped };
1194
1330
  }
1195
- async function cleanOldShellFunctions(homeDir = os5.homedir()) {
1196
- const rosterPath = path6.join(homeDir, ".exe-os", "exe-employees.json");
1197
- if (!existsSync7(rosterPath)) return 0;
1331
+ async function cleanOldShellFunctions(homeDir = os6.homedir()) {
1332
+ const rosterPath = path7.join(homeDir, ".exe-os", "exe-employees.json");
1333
+ if (!existsSync8(rosterPath)) return 0;
1198
1334
  let employees;
1199
1335
  try {
1200
1336
  employees = JSON.parse(await readFile3(rosterPath, "utf-8"));
@@ -1209,13 +1345,13 @@ async function cleanOldShellFunctions(homeDir = os5.homedir()) {
1209
1345
  return { name: n, funcDef, forLoop };
1210
1346
  });
1211
1347
  const rcFiles = [
1212
- path6.join(homeDir, ".zshrc"),
1213
- path6.join(homeDir, ".bashrc")
1348
+ path7.join(homeDir, ".zshrc"),
1349
+ path7.join(homeDir, ".bashrc")
1214
1350
  ];
1215
1351
  const REMOVED_MARKER = "# Removed by exe-os \u2014 wrappers now at ~/.exe-os/bin/";
1216
1352
  let totalRemoved = 0;
1217
1353
  for (const rcPath of rcFiles) {
1218
- if (!existsSync7(rcPath)) continue;
1354
+ if (!existsSync8(rcPath)) continue;
1219
1355
  let content;
1220
1356
  try {
1221
1357
  content = await readFile3(rcPath, "utf-8");
@@ -1319,8 +1455,8 @@ function escapeRegExp(s) {
1319
1455
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1320
1456
  }
1321
1457
  async function injectOrchestrationRules(homeDir) {
1322
- const claudeDir = path6.join(homeDir, ".claude");
1323
- const claudeMdPath = path6.join(claudeDir, "CLAUDE.md");
1458
+ const claudeDir = path7.join(homeDir, ".claude");
1459
+ const claudeMdPath = path7.join(claudeDir, "CLAUDE.md");
1324
1460
  await mkdir3(claudeDir, { recursive: true });
1325
1461
  let existing = "";
1326
1462
  try {
@@ -1342,19 +1478,19 @@ async function injectOrchestrationRules(homeDir) {
1342
1478
  await writeFile3(claudeMdPath, existing + separator + ORCHESTRATION_RULES + "\n", "utf-8");
1343
1479
  return "injected";
1344
1480
  }
1345
- async function installStatusLine(packageRoot, homeDir = os5.homedir()) {
1481
+ async function installStatusLine(packageRoot, homeDir = os6.homedir()) {
1346
1482
  const prefs = loadPreferences(homeDir);
1347
1483
  if (prefs.ccStatusLine === false) return "opted-out";
1348
- const claudeDir = path6.join(homeDir, ".claude");
1484
+ const claudeDir = path7.join(homeDir, ".claude");
1349
1485
  await mkdir3(claudeDir, { recursive: true });
1350
- const assetPath = path6.join(packageRoot, "dist", "assets", "statusline-command.sh");
1351
- if (!existsSync7(assetPath)) return "asset-missing";
1352
- const destScript = path6.join(claudeDir, "statusline-command.sh");
1486
+ const assetPath = path7.join(packageRoot, "dist", "assets", "statusline-command.sh");
1487
+ if (!existsSync8(assetPath)) return "asset-missing";
1488
+ const destScript = path7.join(claudeDir, "statusline-command.sh");
1353
1489
  const assetContent = await readFile3(assetPath, "utf-8");
1354
1490
  await writeFile3(destScript, assetContent, { mode: 493 });
1355
- const settingsPath = path6.join(claudeDir, "settings.json");
1491
+ const settingsPath = path7.join(claudeDir, "settings.json");
1356
1492
  let settings = {};
1357
- if (existsSync7(settingsPath)) {
1493
+ if (existsSync8(settingsPath)) {
1358
1494
  try {
1359
1495
  settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1360
1496
  } catch {
@@ -1391,13 +1527,13 @@ async function runInstaller(homeDir) {
1391
1527
  `Hooks: ${hookResult.added} added, ${hookResult.skipped} unchanged
1392
1528
  `
1393
1529
  );
1394
- const resolvedHome = homeDir ?? os5.homedir();
1395
- const exeWorkspace = path6.join(resolvedHome, "exe");
1396
- if (!existsSync7(exeWorkspace)) {
1530
+ const resolvedHome = homeDir ?? os6.homedir();
1531
+ const exeWorkspace = path7.join(resolvedHome, "exe");
1532
+ if (!existsSync8(exeWorkspace)) {
1397
1533
  try {
1398
- await mkdir3(path6.join(exeWorkspace, "content"), { recursive: true });
1399
- await mkdir3(path6.join(exeWorkspace, "operations"), { recursive: true });
1400
- await mkdir3(path6.join(exeWorkspace, "output"), { recursive: true });
1534
+ await mkdir3(path7.join(exeWorkspace, "content"), { recursive: true });
1535
+ await mkdir3(path7.join(exeWorkspace, "operations"), { recursive: true });
1536
+ await mkdir3(path7.join(exeWorkspace, "output"), { recursive: true });
1401
1537
  process.stderr.write(
1402
1538
  `Created ~/exe/ \u2014 your automation workspace for non-code projects
1403
1539
  `
@@ -1432,57 +1568,57 @@ exe-os installed successfully.
1432
1568
  `);
1433
1569
  }
1434
1570
  function setupTmux(home) {
1435
- const homeDir = home ?? os5.homedir();
1436
- const exeDir = path6.join(homeDir, ".exe-os");
1437
- const exeTmuxConf = path6.join(exeDir, "tmux.conf");
1438
- const userTmuxConf = path6.join(homeDir, ".tmux.conf");
1439
- const backupPath = path6.join(homeDir, ".tmux.conf.backup");
1571
+ const homeDir = home ?? os6.homedir();
1572
+ const exeDir = path7.join(homeDir, ".exe-os");
1573
+ const exeTmuxConf = path7.join(exeDir, "tmux.conf");
1574
+ const userTmuxConf = path7.join(homeDir, ".tmux.conf");
1575
+ const backupPath = path7.join(homeDir, ".tmux.conf.backup");
1440
1576
  const sourceLine = "source-file ~/.exe-os/tmux.conf";
1441
1577
  const pkgRoot = resolvePackageRoot();
1442
- const assetPath = path6.join(pkgRoot, "dist", "assets", "tmux.conf");
1443
- if (!existsSync7(assetPath)) {
1578
+ const assetPath = path7.join(pkgRoot, "dist", "assets", "tmux.conf");
1579
+ if (!existsSync8(assetPath)) {
1444
1580
  process.stderr.write(`exe-os: tmux.conf asset not found at ${assetPath} \u2014 skipping tmux setup
1445
1581
  `);
1446
1582
  return;
1447
1583
  }
1448
- mkdirSync3(exeDir, { recursive: true });
1449
- if (existsSync7(exeTmuxConf)) {
1450
- const currentContent = readFileSync5(exeTmuxConf, "utf8");
1451
- const newContent = readFileSync5(assetPath, "utf8");
1584
+ mkdirSync4(exeDir, { recursive: true });
1585
+ if (existsSync8(exeTmuxConf)) {
1586
+ const currentContent = readFileSync6(exeTmuxConf, "utf8");
1587
+ const newContent = readFileSync6(assetPath, "utf8");
1452
1588
  const currentHash = createHash("sha256").update(currentContent).digest("hex");
1453
1589
  const newHash = createHash("sha256").update(newContent).digest("hex");
1454
1590
  if (currentHash !== newHash) {
1455
- const shippedPath = path6.join(exeDir, ".tmux.conf.shipped-hash");
1456
- const lastShippedHash = existsSync7(shippedPath) ? readFileSync5(shippedPath, "utf8").trim() : "";
1591
+ const shippedPath = path7.join(exeDir, ".tmux.conf.shipped-hash");
1592
+ const lastShippedHash = existsSync8(shippedPath) ? readFileSync6(shippedPath, "utf8").trim() : "";
1457
1593
  if (lastShippedHash && currentHash !== lastShippedHash) {
1458
1594
  process.stderr.write("exe-os: tmux config has user customizations \u2014 skipping overwrite\n");
1459
1595
  } else {
1460
1596
  copyFileSync(assetPath, exeTmuxConf);
1461
1597
  process.stderr.write("exe-os: tmux config updated\n");
1462
1598
  }
1463
- writeFileSync4(shippedPath, newHash, "utf8");
1599
+ writeFileSync5(shippedPath, newHash, "utf8");
1464
1600
  } else {
1465
1601
  process.stderr.write("exe-os: tmux config already up to date\n");
1466
1602
  }
1467
1603
  } else {
1468
1604
  copyFileSync(assetPath, exeTmuxConf);
1469
- const newContent = readFileSync5(assetPath, "utf8");
1605
+ const newContent = readFileSync6(assetPath, "utf8");
1470
1606
  const newHash = createHash("sha256").update(newContent).digest("hex");
1471
- writeFileSync4(path6.join(exeDir, ".tmux.conf.shipped-hash"), newHash, "utf8");
1607
+ writeFileSync5(path7.join(exeDir, ".tmux.conf.shipped-hash"), newHash, "utf8");
1472
1608
  }
1473
- if (existsSync7(userTmuxConf)) {
1474
- const existing = readFileSync5(userTmuxConf, "utf8");
1609
+ if (existsSync8(userTmuxConf)) {
1610
+ const existing = readFileSync6(userTmuxConf, "utf8");
1475
1611
  if (!existing.includes(sourceLine)) {
1476
- if (!existsSync7(backupPath)) {
1612
+ if (!existsSync8(backupPath)) {
1477
1613
  copyFileSync(userTmuxConf, backupPath);
1478
1614
  process.stderr.write(`exe-os: backed up existing tmux config to ${backupPath}
1479
1615
  `);
1480
1616
  }
1481
- writeFileSync4(userTmuxConf, `${sourceLine}
1617
+ writeFileSync5(userTmuxConf, `${sourceLine}
1482
1618
  ${existing}`);
1483
1619
  }
1484
1620
  } else {
1485
- writeFileSync4(userTmuxConf, `# Exe OS tmux defaults \u2014 remove this line to use your own config
1621
+ writeFileSync5(userTmuxConf, `# Exe OS tmux defaults \u2014 remove this line to use your own config
1486
1622
  ${sourceLine}
1487
1623
  `);
1488
1624
  }
@@ -1493,10 +1629,10 @@ ${sourceLine}
1493
1629
  process.stderr.write("exe-os: tmux config installed\n");
1494
1630
  }
1495
1631
  function setupGhostty(home) {
1496
- const homeDir = home ?? os5.homedir();
1497
- const xdgConfig = path6.join(homeDir, ".config", "ghostty");
1498
- const macConfig = path6.join(homeDir, "Library", "Application Support", "com.mitchellh.ghostty");
1499
- const ghosttyInstalled = existsSync7(xdgConfig) || existsSync7(macConfig) || (() => {
1632
+ const homeDir = home ?? os6.homedir();
1633
+ const xdgConfig = path7.join(homeDir, ".config", "ghostty");
1634
+ const macConfig = path7.join(homeDir, "Library", "Application Support", "com.mitchellh.ghostty");
1635
+ const ghosttyInstalled = existsSync8(xdgConfig) || existsSync8(macConfig) || (() => {
1500
1636
  try {
1501
1637
  execSync2("which ghostty 2>/dev/null");
1502
1638
  return true;
@@ -1508,48 +1644,48 @@ function setupGhostty(home) {
1508
1644
  return;
1509
1645
  }
1510
1646
  const pkgRoot = resolvePackageRoot();
1511
- const assetPath = path6.join(pkgRoot, "dist", "assets", "ghostty.conf");
1512
- if (!existsSync7(assetPath)) {
1647
+ const assetPath = path7.join(pkgRoot, "dist", "assets", "ghostty.conf");
1648
+ if (!existsSync8(assetPath)) {
1513
1649
  process.stderr.write("exe-os: ghostty.conf asset not found \u2014 skipping Ghostty setup\n");
1514
1650
  return;
1515
1651
  }
1516
1652
  const configDir = xdgConfig;
1517
- const configPath = path6.join(configDir, "config");
1518
- const backupPath = path6.join(configDir, "config.backup");
1519
- mkdirSync3(configDir, { recursive: true });
1653
+ const configPath = path7.join(configDir, "config");
1654
+ const backupPath = path7.join(configDir, "config.backup");
1655
+ mkdirSync4(configDir, { recursive: true });
1520
1656
  const START_MARKER = "# \u2500\u2500 exe-os:ghostty-start \u2500\u2500";
1521
1657
  const END_MARKER = "# \u2500\u2500 exe-os:ghostty-end \u2500\u2500";
1522
- const assetContent = readFileSync5(assetPath, "utf8").trim();
1658
+ const assetContent = readFileSync6(assetPath, "utf8").trim();
1523
1659
  const markedSection = `${START_MARKER}
1524
1660
  ${assetContent}
1525
1661
  ${END_MARKER}`;
1526
- if (existsSync7(configPath)) {
1527
- const existing = readFileSync5(configPath, "utf8");
1662
+ if (existsSync8(configPath)) {
1663
+ const existing = readFileSync6(configPath, "utf8");
1528
1664
  if (existing.includes(START_MARKER) && existing.includes(END_MARKER)) {
1529
1665
  process.stderr.write("exe-os: Ghostty config already installed \u2014 preserving local settings\n");
1530
1666
  return;
1531
1667
  } else if (existing.includes("Exe OS")) {
1532
- if (!existsSync7(backupPath)) {
1668
+ if (!existsSync8(backupPath)) {
1533
1669
  copyFileSync(configPath, backupPath);
1534
1670
  process.stderr.write(`exe-os: backed up existing Ghostty config to ${backupPath}
1535
1671
  `);
1536
1672
  }
1537
- writeFileSync4(configPath, `${START_MARKER}
1673
+ writeFileSync5(configPath, `${START_MARKER}
1538
1674
  ${existing.trim()}
1539
1675
  ${END_MARKER}
1540
1676
  `);
1541
1677
  } else {
1542
- if (!existsSync7(backupPath)) {
1678
+ if (!existsSync8(backupPath)) {
1543
1679
  copyFileSync(configPath, backupPath);
1544
1680
  process.stderr.write(`exe-os: backed up existing Ghostty config to ${backupPath}
1545
1681
  `);
1546
1682
  }
1547
- writeFileSync4(configPath, `${markedSection}
1683
+ writeFileSync5(configPath, `${markedSection}
1548
1684
 
1549
1685
  ${existing}`);
1550
1686
  }
1551
1687
  } else {
1552
- writeFileSync4(configPath, `${markedSection}
1688
+ writeFileSync5(configPath, `${markedSection}
1553
1689
  `);
1554
1690
  }
1555
1691
  process.stderr.write("exe-os: Ghostty config installed\n");
@@ -1573,6 +1709,7 @@ var init_installer = __esm({
1573
1709
  init_agent_symlinks();
1574
1710
  init_mcp_prefix();
1575
1711
  init_preferences();
1712
+ init_mcp_http_config();
1576
1713
  init_runtime_hook_manifest();
1577
1714
  EXE_SECTION_START = "<!-- exe-os:orchestration-start -->";
1578
1715
  EXE_SECTION_END = "<!-- exe-os:orchestration-end -->";
@@ -1601,19 +1738,19 @@ __export(installer_exports, {
1601
1738
  verifyCodexHooks: () => verifyCodexHooks
1602
1739
  });
1603
1740
  import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir4 } from "fs/promises";
1604
- import { existsSync as existsSync9 } from "fs";
1605
- import path8 from "path";
1606
- import os6 from "os";
1607
- async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1608
- const codexDir = path8.join(homeDir, ".codex");
1609
- const hooksPath = path8.join(codexDir, "hooks.json");
1610
- const logsDir = path8.join(homeDir, ".exe-os", "logs");
1611
- const hookLogPath = path8.join(logsDir, "hooks.log");
1741
+ import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
1742
+ import path9 from "path";
1743
+ import os7 from "os";
1744
+ async function mergeCodexHooks(packageRoot, homeDir = os7.homedir()) {
1745
+ const codexDir = path9.join(homeDir, ".codex");
1746
+ const hooksPath = path9.join(codexDir, "hooks.json");
1747
+ const logsDir = path9.join(homeDir, ".exe-os", "logs");
1748
+ const hookLogPath = path9.join(logsDir, "hooks.log");
1612
1749
  const logSuffix = ` 2>> "${hookLogPath}"`;
1613
1750
  await mkdir4(codexDir, { recursive: true });
1614
1751
  await mkdir4(logsDir, { recursive: true });
1615
1752
  let hooksJson = {};
1616
- if (existsSync9(hooksPath)) {
1753
+ if (existsSync10(hooksPath)) {
1617
1754
  try {
1618
1755
  hooksJson = JSON.parse(await readFile4(hooksPath, "utf-8"));
1619
1756
  } catch {
@@ -1624,19 +1761,6 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1624
1761
  hooksJson.hooks = {};
1625
1762
  }
1626
1763
  const hooksToRegister = [
1627
- {
1628
- event: "SessionStart",
1629
- group: {
1630
- hooks: [
1631
- {
1632
- type: "command",
1633
- command: `node "${path8.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
1634
- timeout: 30
1635
- }
1636
- ]
1637
- },
1638
- marker: EXE_HOOKS.sessionStart
1639
- },
1640
1764
  {
1641
1765
  event: "PostToolUse",
1642
1766
  group: {
@@ -1646,7 +1770,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1646
1770
  // Combined hook: runs ingest + error-recall in one Node process.
1647
1771
  // Eliminates a cold-start cycle per tool call (~3-6s savings on Codex).
1648
1772
  type: "command",
1649
- command: `node "${path8.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
1773
+ command: `node "${path9.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
1650
1774
  }
1651
1775
  ]
1652
1776
  },
@@ -1660,7 +1784,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1660
1784
  // Single hook: prompt-submit handles memory retrieval + entity boost.
1661
1785
  // exe-heartbeat-hook is CC-specific (intercom) — omitted on Codex.
1662
1786
  type: "command",
1663
- command: `node "${path8.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
1787
+ command: `node "${path9.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
1664
1788
  }
1665
1789
  ]
1666
1790
  },
@@ -1672,7 +1796,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1672
1796
  hooks: [
1673
1797
  {
1674
1798
  type: "command",
1675
- command: `node "${path8.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
1799
+ command: `node "${path9.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
1676
1800
  }
1677
1801
  ]
1678
1802
  },
@@ -1685,7 +1809,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1685
1809
  hooks: [
1686
1810
  {
1687
1811
  type: "command",
1688
- command: `node "${path8.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
1812
+ command: `node "${path9.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
1689
1813
  }
1690
1814
  ]
1691
1815
  },
@@ -1694,6 +1818,16 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1694
1818
  ];
1695
1819
  let added = 0;
1696
1820
  let skipped = 0;
1821
+ const sessionStartGroups = hooksJson.hooks["SessionStart"];
1822
+ if (Array.isArray(sessionStartGroups)) {
1823
+ hooksJson.hooks["SessionStart"] = sessionStartGroups.map((g) => ({
1824
+ ...g,
1825
+ hooks: g.hooks.filter((h) => !h.command.includes(EXE_HOOKS.sessionStart))
1826
+ })).filter((g) => g.hooks.length > 0);
1827
+ if (hooksJson.hooks["SessionStart"].length === 0) {
1828
+ delete hooksJson.hooks["SessionStart"];
1829
+ }
1830
+ }
1697
1831
  const postToolGroups = hooksJson.hooks["PostToolUse"];
1698
1832
  if (Array.isArray(postToolGroups)) {
1699
1833
  hooksJson.hooks["PostToolUse"] = postToolGroups.map((g) => ({
@@ -1723,15 +1857,13 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1723
1857
  await writeFile4(hooksPath, JSON.stringify(hooksJson, null, 2) + "\n");
1724
1858
  return { added, skipped };
1725
1859
  }
1726
- function verifyCodexHooks(homeDir = os6.homedir()) {
1727
- const hooksPath = path8.join(homeDir, ".codex", "hooks.json");
1728
- if (!existsSync9(hooksPath)) return false;
1860
+ function verifyCodexHooks(homeDir = os7.homedir()) {
1861
+ const hooksPath = path9.join(homeDir, ".codex", "hooks.json");
1862
+ if (!existsSync10(hooksPath)) return false;
1729
1863
  try {
1730
- const hooksJson = JSON.parse(
1731
- __require("fs").readFileSync(hooksPath, "utf-8")
1732
- );
1864
+ const hooksJson = JSON.parse(readFileSync8(hooksPath, "utf-8"));
1733
1865
  if (!hooksJson.hooks) return false;
1734
- const required = ["SessionStart", "PostToolUse", "UserPromptSubmit", "Stop", "PreToolUse"];
1866
+ const required = ["PostToolUse", "UserPromptSubmit", "Stop", "PreToolUse"];
1735
1867
  for (const event of required) {
1736
1868
  const groups = hooksJson.hooks[event];
1737
1869
  if (!groups || !groups.some(
@@ -1749,19 +1881,23 @@ function verifyCodexHooks(homeDir = os6.homedir()) {
1749
1881
  )) {
1750
1882
  return false;
1751
1883
  }
1884
+ const sessionStartCommands = (hooksJson.hooks.SessionStart ?? []).flatMap((g) => g.hooks.map((h) => h.command));
1885
+ if (sessionStartCommands.some((cmd) => cmd.includes(EXE_HOOKS.sessionStart))) {
1886
+ return false;
1887
+ }
1752
1888
  return true;
1753
1889
  } catch {
1754
1890
  return false;
1755
1891
  }
1756
1892
  }
1757
- async function installCodexStatusLine(homeDir = os6.homedir()) {
1893
+ async function installCodexStatusLine(homeDir = os7.homedir()) {
1758
1894
  const prefs = loadPreferences(homeDir);
1759
1895
  if (prefs.codexStatusLine === false) return "opted-out";
1760
- const codexDir = path8.join(homeDir, ".codex");
1761
- const configPath = path8.join(codexDir, "config.toml");
1896
+ const codexDir = path9.join(homeDir, ".codex");
1897
+ const configPath = path9.join(codexDir, "config.toml");
1762
1898
  await mkdir4(codexDir, { recursive: true });
1763
1899
  let content = "";
1764
- if (existsSync9(configPath)) {
1900
+ if (existsSync10(configPath)) {
1765
1901
  content = await readFile4(configPath, "utf-8");
1766
1902
  if (/\[tui\][\s\S]*?status_line\s*=/.test(content)) {
1767
1903
  return "already-configured";
@@ -1778,53 +1914,47 @@ status_line = [${DEFAULT_CODEX_STATUS_LINE.map((s) => `"${s}"`).join(", ")}]`;
1778
1914
  await writeFile4(configPath, content);
1779
1915
  return "installed";
1780
1916
  }
1781
- function desiredCodexMcpSection(serverJsPath) {
1917
+ function tomlString(value) {
1918
+ return JSON.stringify(value);
1919
+ }
1920
+ function codexHttpHeadersToml(homeDir) {
1921
+ const headers = buildMcpHttpHeaders(homeDir);
1922
+ return `{ ${Object.entries(headers).map(([key, value]) => `${tomlString(key)} = ${tomlString(value)}`).join(", ")} }`;
1923
+ }
1924
+ function desiredCodexMcpSection(homeDir) {
1782
1925
  return [
1783
1926
  "[mcp_servers.exe-os]",
1784
- `command = "node"`,
1785
- `args = ["${serverJsPath}"]`,
1927
+ `url = ${tomlString(mcpHttpUrl())}`,
1928
+ `http_headers = ${codexHttpHeadersToml(homeDir)}`,
1786
1929
  `startup_timeout_sec = ${CODEX_EXE_MCP_STARTUP_TIMEOUT_SEC}`,
1787
1930
  `tool_timeout_sec = ${CODEX_EXE_MCP_TOOL_TIMEOUT_SEC}`,
1788
1931
  ""
1789
1932
  ].join("\n");
1790
1933
  }
1791
- function reconcileCodexMcpSection(sectionContent, serverJsPath) {
1934
+ function reconcileCodexMcpSection(sectionContent, homeDir) {
1792
1935
  const desiredLines = {
1793
- command: `command = "node"`,
1794
- args: `args = ["${serverJsPath}"]`,
1936
+ url: `url = ${tomlString(mcpHttpUrl())}`,
1937
+ headers: `http_headers = ${codexHttpHeadersToml(homeDir)}`,
1795
1938
  startup: `startup_timeout_sec = ${CODEX_EXE_MCP_STARTUP_TIMEOUT_SEC}`,
1796
1939
  tool: `tool_timeout_sec = ${CODEX_EXE_MCP_TOOL_TIMEOUT_SEC}`
1797
1940
  };
1798
1941
  let next = sectionContent;
1799
- let changed = false;
1800
- const replaceOrAppend = (regex, desired) => {
1801
- if (regex.test(next)) {
1802
- const updated = next.replace(regex, desired);
1803
- if (updated !== next) {
1804
- next = updated;
1805
- changed = true;
1806
- }
1807
- return;
1808
- }
1809
- next = next.endsWith("\n") ? `${next}${desired}
1942
+ next = next.split("\n").filter((line) => !/^(command|args|env|type|url|http_headers|startup_timeout_sec|tool_timeout_sec)\s*=/.test(line.trim())).join("\n").replace(/\n{3,}/g, "\n\n");
1943
+ for (const line of [desiredLines.url, desiredLines.headers, desiredLines.startup, desiredLines.tool]) {
1944
+ next = next.endsWith("\n") ? `${next}${line}
1810
1945
  ` : `${next}
1811
- ${desired}
1946
+ ${line}
1812
1947
  `;
1813
- changed = true;
1814
- };
1815
- replaceOrAppend(/^command\s*=.*$/m, desiredLines.command);
1816
- replaceOrAppend(/^args\s*=.*$/m, desiredLines.args);
1817
- replaceOrAppend(/^startup_timeout_sec\s*=.*$/m, desiredLines.startup);
1818
- replaceOrAppend(/^tool_timeout_sec\s*=.*$/m, desiredLines.tool);
1819
- return { content: next, changed };
1820
- }
1821
- async function registerCodexMcpServer(packageRoot, homeDir = os6.homedir()) {
1822
- const codexDir = path8.join(homeDir, ".codex");
1823
- const configPath = path8.join(codexDir, "config.toml");
1824
- const serverJsPath = path8.join(packageRoot, "dist", "mcp", "server.js");
1948
+ }
1949
+ return { content: next, changed: next !== sectionContent };
1950
+ }
1951
+ async function registerCodexMcpServer(packageRoot, homeDir = os7.homedir()) {
1952
+ const codexDir = path9.join(homeDir, ".codex");
1953
+ const configPath = path9.join(codexDir, "config.toml");
1954
+ void packageRoot;
1825
1955
  await mkdir4(codexDir, { recursive: true });
1826
1956
  let content = "";
1827
- if (existsSync9(configPath)) {
1957
+ if (existsSync10(configPath)) {
1828
1958
  content = await readFile4(configPath, "utf-8");
1829
1959
  }
1830
1960
  const sectionHeader = "[mcp_servers.exe-os]";
@@ -1834,7 +1964,7 @@ async function registerCodexMcpServer(packageRoot, homeDir = os6.homedir()) {
1834
1964
  const nextSectionMatch = afterHeader.match(/\n\[(?!mcp_servers\.exe-os)/);
1835
1965
  const sectionEnd = nextSectionMatch ? headerIndex + sectionHeader.length + nextSectionMatch.index : content.length;
1836
1966
  const sectionContent = content.slice(headerIndex, sectionEnd);
1837
- const reconciled = reconcileCodexMcpSection(sectionContent, serverJsPath);
1967
+ const reconciled = reconcileCodexMcpSection(sectionContent, homeDir);
1838
1968
  if (!reconciled.changed) {
1839
1969
  return "already-registered";
1840
1970
  }
@@ -1842,17 +1972,17 @@ async function registerCodexMcpServer(packageRoot, homeDir = os6.homedir()) {
1842
1972
  await writeFile4(configPath, content);
1843
1973
  return "updated";
1844
1974
  }
1845
- const newSection = desiredCodexMcpSection(serverJsPath);
1975
+ const newSection = desiredCodexMcpSection(homeDir);
1846
1976
  const separator = content.length > 0 && !content.endsWith("\n") ? "\n\n" : content.length > 0 ? "\n" : "";
1847
1977
  content = content + separator + newSection;
1848
1978
  await writeFile4(configPath, content);
1849
1979
  return "registered";
1850
1980
  }
1851
- async function ensureCodexHooksFeature(homeDir = os6.homedir()) {
1852
- const configPath = path8.join(homeDir, ".codex", "config.toml");
1853
- await mkdir4(path8.join(homeDir, ".codex"), { recursive: true });
1981
+ async function ensureCodexHooksFeature(homeDir = os7.homedir()) {
1982
+ const configPath = path9.join(homeDir, ".codex", "config.toml");
1983
+ await mkdir4(path9.join(homeDir, ".codex"), { recursive: true });
1854
1984
  let content = "";
1855
- if (existsSync9(configPath)) {
1985
+ if (existsSync10(configPath)) {
1856
1986
  content = await readFile4(configPath, "utf-8");
1857
1987
  }
1858
1988
  if (/\[features\][\s\S]*?codex_hooks\s*=\s*true/.test(content)) {
@@ -1907,6 +2037,7 @@ var init_installer2 = __esm({
1907
2037
  init_installer();
1908
2038
  init_preferences();
1909
2039
  init_runtime_hook_manifest();
2040
+ init_mcp_http_config();
1910
2041
  DEFAULT_CODEX_STATUS_LINE = [
1911
2042
  "model-with-reasoning",
1912
2043
  "current-dir",
@@ -1922,44 +2053,44 @@ var init_installer2 = __esm({
1922
2053
 
1923
2054
  // src/bin/install.ts
1924
2055
  init_installer();
1925
- import { existsSync as existsSync10, readFileSync as readFileSync7, writeFileSync as writeFileSync6, unlinkSync as unlinkSync3, readdirSync as readdirSync2, openSync, closeSync } from "fs";
2056
+ import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7, unlinkSync as unlinkSync3, readdirSync as readdirSync2, openSync, closeSync } from "fs";
1926
2057
  import { spawn, execSync as execSync3 } from "child_process";
1927
- import path9 from "path";
1928
- import os7 from "os";
2058
+ import path10 from "path";
2059
+ import os8 from "os";
1929
2060
 
1930
2061
  // src/lib/session-wrappers.ts
1931
2062
  import {
1932
- existsSync as existsSync8,
1933
- readFileSync as readFileSync6,
1934
- writeFileSync as writeFileSync5,
1935
- mkdirSync as mkdirSync4,
2063
+ existsSync as existsSync9,
2064
+ readFileSync as readFileSync7,
2065
+ writeFileSync as writeFileSync6,
2066
+ mkdirSync as mkdirSync5,
1936
2067
  chmodSync as chmodSync3,
1937
2068
  readdirSync,
1938
2069
  unlinkSync as unlinkSync2
1939
2070
  } from "fs";
1940
- import path7 from "path";
2071
+ import path8 from "path";
1941
2072
  import { homedir } from "os";
1942
2073
  var MAX_N = 9;
1943
2074
  function generateSessionWrappers(packageRoot, homeDir) {
1944
2075
  const home = homeDir ?? homedir();
1945
- const binDir = path7.join(home, ".exe-os", "bin");
1946
- const rosterPath = path7.join(home, ".exe-os", "exe-employees.json");
1947
- mkdirSync4(binDir, { recursive: true });
1948
- const exeStartDst = path7.join(binDir, "exe-start");
2076
+ const binDir = path8.join(home, ".exe-os", "bin");
2077
+ const rosterPath = path8.join(home, ".exe-os", "exe-employees.json");
2078
+ mkdirSync5(binDir, { recursive: true });
2079
+ const exeStartDst = path8.join(binDir, "exe-start");
1949
2080
  const candidates = [
1950
- path7.join(packageRoot, "dist", "bin", "exe-start.sh"),
1951
- path7.join(packageRoot, "src", "bin", "exe-start.sh")
2081
+ path8.join(packageRoot, "dist", "bin", "exe-start.sh"),
2082
+ path8.join(packageRoot, "src", "bin", "exe-start.sh")
1952
2083
  ];
1953
2084
  for (const src of candidates) {
1954
- if (existsSync8(src)) {
1955
- writeFileSync5(exeStartDst, readFileSync6(src));
2085
+ if (existsSync9(src)) {
2086
+ writeFileSync6(exeStartDst, readFileSync7(src));
1956
2087
  chmodSync3(exeStartDst, 493);
1957
2088
  break;
1958
2089
  }
1959
2090
  }
1960
2091
  let employees = [];
1961
2092
  try {
1962
- employees = JSON.parse(readFileSync6(rosterPath, "utf8"));
2093
+ employees = JSON.parse(readFileSync7(rosterPath, "utf8"));
1963
2094
  } catch {
1964
2095
  return { created: 0, pathConfigured: false };
1965
2096
  }
@@ -1969,9 +2100,9 @@ function generateSessionWrappers(packageRoot, homeDir) {
1969
2100
  try {
1970
2101
  for (const f of readdirSync(binDir)) {
1971
2102
  if (f === "exe-start") continue;
1972
- const fPath = path7.join(binDir, f);
2103
+ const fPath = path8.join(binDir, f);
1973
2104
  try {
1974
- const content = readFileSync6(fPath, "utf8");
2105
+ const content = readFileSync7(fPath, "utf8");
1975
2106
  if (content.includes("exe-start")) {
1976
2107
  unlinkSync2(fPath);
1977
2108
  }
@@ -1986,34 +2117,34 @@ exec "${exeStartDst}" "$0" "$@"
1986
2117
  `;
1987
2118
  for (const emp of employees) {
1988
2119
  for (let n = 1; n <= MAX_N; n++) {
1989
- const wrapperPath = path7.join(binDir, `${emp.name}${n}`);
1990
- writeFileSync5(wrapperPath, wrapperContent);
2120
+ const wrapperPath = path8.join(binDir, `${emp.name}${n}`);
2121
+ writeFileSync6(wrapperPath, wrapperContent);
1991
2122
  chmodSync3(wrapperPath, 493);
1992
2123
  created++;
1993
- const codexPath = path7.join(binDir, `${emp.name}${n}-codex`);
1994
- writeFileSync5(codexPath, wrapperContent);
2124
+ const codexPath = path8.join(binDir, `${emp.name}${n}-codex`);
2125
+ writeFileSync6(codexPath, wrapperContent);
1995
2126
  chmodSync3(codexPath, 493);
1996
2127
  created++;
1997
2128
  }
1998
2129
  }
1999
2130
  const codexLauncherCandidates = [
2000
- path7.join(packageRoot, "dist", "bin", "exe-start-codex.js"),
2001
- path7.join(packageRoot, "src", "bin", "exe-start-codex.ts")
2131
+ path8.join(packageRoot, "dist", "bin", "exe-start-codex.js"),
2132
+ path8.join(packageRoot, "src", "bin", "exe-start-codex.ts")
2002
2133
  ];
2003
2134
  let codexLauncher = null;
2004
2135
  for (const c of codexLauncherCandidates) {
2005
- if (existsSync8(c)) {
2136
+ if (existsSync9(c)) {
2006
2137
  codexLauncher = c;
2007
2138
  break;
2008
2139
  }
2009
2140
  }
2010
2141
  if (codexLauncher) {
2011
2142
  for (const emp of employees) {
2012
- const wrapperPath = path7.join(binDir, `${emp.name}-codex`);
2143
+ const wrapperPath = path8.join(binDir, `${emp.name}-codex`);
2013
2144
  const content = `#!/bin/bash
2014
2145
  exec node "${codexLauncher}" --agent ${emp.name} "$@"
2015
2146
  `;
2016
- writeFileSync5(wrapperPath, content);
2147
+ writeFileSync6(wrapperPath, content);
2017
2148
  chmodSync3(wrapperPath, 493);
2018
2149
  created++;
2019
2150
  }
@@ -2032,24 +2163,24 @@ export PATH="${binDir}:$PATH"
2032
2163
  const shell = process.env.SHELL ?? "/bin/bash";
2033
2164
  const profilePaths = [];
2034
2165
  if (shell.includes("zsh")) {
2035
- profilePaths.push(path7.join(home, ".zshrc"));
2166
+ profilePaths.push(path8.join(home, ".zshrc"));
2036
2167
  } else if (shell.includes("bash")) {
2037
- profilePaths.push(path7.join(home, ".bashrc"));
2038
- profilePaths.push(path7.join(home, ".bash_profile"));
2168
+ profilePaths.push(path8.join(home, ".bashrc"));
2169
+ profilePaths.push(path8.join(home, ".bash_profile"));
2039
2170
  } else {
2040
- profilePaths.push(path7.join(home, ".profile"));
2171
+ profilePaths.push(path8.join(home, ".profile"));
2041
2172
  }
2042
2173
  for (const profilePath of profilePaths) {
2043
2174
  try {
2044
2175
  let content = "";
2045
2176
  try {
2046
- content = readFileSync6(profilePath, "utf8");
2177
+ content = readFileSync7(profilePath, "utf8");
2047
2178
  } catch {
2048
2179
  }
2049
2180
  if (content.includes(".exe-os/bin")) {
2050
2181
  return false;
2051
2182
  }
2052
- writeFileSync5(profilePath, content + exportLine);
2183
+ writeFileSync6(profilePath, content + exportLine);
2053
2184
  return true;
2054
2185
  } catch {
2055
2186
  continue;
@@ -2059,14 +2190,14 @@ export PATH="${binDir}:$PATH"
2059
2190
  }
2060
2191
 
2061
2192
  // src/bin/install.ts
2062
- var homedir2 = os7.homedir;
2063
- var EXE_DIR = path9.join(homedir2(), ".exe-os");
2193
+ var homedir2 = os8.homedir;
2194
+ var EXE_DIR = path10.join(homedir2(), ".exe-os");
2064
2195
  function restartDaemon() {
2065
- const pidPath = path9.join(EXE_DIR, "exed.pid");
2066
- const sockPath = path9.join(EXE_DIR, "exed.sock");
2196
+ const pidPath = path10.join(EXE_DIR, "exed.pid");
2197
+ const sockPath = path10.join(EXE_DIR, "exed.sock");
2067
2198
  try {
2068
- if (existsSync10(pidPath)) {
2069
- const pid = parseInt(readFileSync7(pidPath, "utf8").trim(), 10);
2199
+ if (existsSync11(pidPath)) {
2200
+ const pid = parseInt(readFileSync9(pidPath, "utf8").trim(), 10);
2070
2201
  if (!isNaN(pid) && pid > 0) {
2071
2202
  try {
2072
2203
  process.kill(pid, "SIGKILL");
@@ -2107,18 +2238,18 @@ function restartDaemon() {
2107
2238
  } catch {
2108
2239
  }
2109
2240
  try {
2110
- const versionPath = path9.join(EXE_DIR, "mcp-version");
2111
- writeFileSync6(versionPath, `deploy-${Date.now()}`);
2241
+ const versionPath = path10.join(EXE_DIR, "mcp-version");
2242
+ writeFileSync7(versionPath, `deploy-${Date.now()}`);
2112
2243
  process.stderr.write(`exe-os: MCP version marker updated \u2014 servers will hot-reload within 10s
2113
2244
  `);
2114
2245
  } catch {
2115
2246
  }
2116
2247
  try {
2117
- const wpDir = path9.join(EXE_DIR, "worker-pids");
2118
- if (existsSync10(wpDir)) {
2248
+ const wpDir = path10.join(EXE_DIR, "worker-pids");
2249
+ if (existsSync11(wpDir)) {
2119
2250
  for (const f of readdirSync2(wpDir)) {
2120
2251
  try {
2121
- unlinkSync3(path9.join(wpDir, f));
2252
+ unlinkSync3(path10.join(wpDir, f));
2122
2253
  } catch {
2123
2254
  }
2124
2255
  }
@@ -2135,7 +2266,7 @@ function restartDaemon() {
2135
2266
  }
2136
2267
  } catch {
2137
2268
  }
2138
- const totalGB = os7.totalmem() / (1024 * 1024 * 1024);
2269
+ const totalGB = os8.totalmem() / (1024 * 1024 * 1024);
2139
2270
  if (totalGB <= 8) {
2140
2271
  process.stderr.write(
2141
2272
  `exe-os: ${totalGB.toFixed(0)}GB system \u2014 skipping daemon spawn (keyword search mode)
@@ -2145,13 +2276,13 @@ function restartDaemon() {
2145
2276
  }
2146
2277
  try {
2147
2278
  const pkgRoot = resolvePackageRoot();
2148
- const daemonPath = path9.join(pkgRoot, "dist", "lib", "exe-daemon.js");
2149
- if (!existsSync10(daemonPath)) {
2279
+ const daemonPath = path10.join(pkgRoot, "dist", "lib", "exe-daemon.js");
2280
+ if (!existsSync11(daemonPath)) {
2150
2281
  process.stderr.write(`exe-os: daemon not found at ${daemonPath} \u2014 skipping respawn
2151
2282
  `);
2152
2283
  return;
2153
2284
  }
2154
- const logPath = path9.join(EXE_DIR, "exed.log");
2285
+ const logPath = path10.join(EXE_DIR, "exed.log");
2155
2286
  let stderrFd = "ignore";
2156
2287
  try {
2157
2288
  stderrFd = openSync(logPath, "a");