@askexenow/exe-os 0.9.66 → 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 (99) 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} +1523 -2275
  6. package/dist/bin/backfill-conversations.js +506 -20
  7. package/dist/bin/backfill-responses.js +506 -20
  8. package/dist/bin/backfill-vectors.js +233 -20
  9. package/dist/bin/bulk-sync-postgres.js +4876 -0
  10. package/dist/bin/cleanup-stale-review-tasks.js +507 -21
  11. package/dist/bin/cli.js +2450 -1530
  12. package/dist/bin/exe-assign.js +506 -20
  13. package/dist/bin/exe-boot.js +410 -60
  14. package/dist/bin/exe-cloud.js +795 -105
  15. package/dist/bin/exe-dispatch.js +516 -22
  16. package/dist/bin/exe-doctor.js +587 -30
  17. package/dist/bin/exe-export-behaviors.js +518 -24
  18. package/dist/bin/exe-forget.js +507 -21
  19. package/dist/bin/exe-gateway.js +571 -25
  20. package/dist/bin/exe-heartbeat.js +518 -24
  21. package/dist/bin/exe-kill.js +507 -21
  22. package/dist/bin/exe-launch-agent.js +2312 -1069
  23. package/dist/bin/exe-new-employee.js +197 -165
  24. package/dist/bin/exe-pending-messages.js +507 -21
  25. package/dist/bin/exe-pending-notifications.js +507 -21
  26. package/dist/bin/exe-pending-reviews.js +507 -21
  27. package/dist/bin/exe-rename.js +507 -21
  28. package/dist/bin/exe-review.js +507 -21
  29. package/dist/bin/exe-search.js +518 -24
  30. package/dist/bin/exe-session-cleanup.js +516 -22
  31. package/dist/bin/exe-settings.js +4 -0
  32. package/dist/bin/exe-start-codex.js +682 -143
  33. package/dist/bin/exe-start-opencode.js +627 -79
  34. package/dist/bin/exe-status.js +507 -21
  35. package/dist/bin/exe-team.js +507 -21
  36. package/dist/bin/git-sweep.js +516 -22
  37. package/dist/bin/graph-backfill.js +558 -21
  38. package/dist/bin/graph-export.js +507 -21
  39. package/dist/bin/graph-layer-benchmark.js +109 -0
  40. package/dist/bin/install.js +305 -288
  41. package/dist/bin/intercom-check.js +516 -22
  42. package/dist/bin/postgres-agentic-reflection-backfill.js +187 -0
  43. package/dist/bin/postgres-agentic-semantic-backfill.js +237 -0
  44. package/dist/bin/scan-tasks.js +516 -22
  45. package/dist/bin/setup.js +412 -62
  46. package/dist/bin/shard-migrate.js +506 -20
  47. package/dist/gateway/index.js +569 -23
  48. package/dist/hooks/bug-report-worker.js +519 -25
  49. package/dist/hooks/codex-stop-task-finalizer.js +516 -22
  50. package/dist/hooks/commit-complete.js +516 -22
  51. package/dist/hooks/error-recall.js +518 -24
  52. package/dist/hooks/ingest.js +516 -22
  53. package/dist/hooks/instructions-loaded.js +507 -21
  54. package/dist/hooks/notification.js +507 -21
  55. package/dist/hooks/post-compact.js +507 -21
  56. package/dist/hooks/post-tool-combined.js +519 -25
  57. package/dist/hooks/pre-compact.js +516 -22
  58. package/dist/hooks/pre-tool-use.js +507 -21
  59. package/dist/hooks/prompt-submit.js +519 -25
  60. package/dist/hooks/session-end.js +516 -22
  61. package/dist/hooks/session-start.js +520 -26
  62. package/dist/hooks/stop.js +517 -23
  63. package/dist/hooks/subagent-stop.js +507 -21
  64. package/dist/hooks/summary-worker.js +411 -61
  65. package/dist/index.js +569 -23
  66. package/dist/lib/cloud-sync.js +391 -53
  67. package/dist/lib/config.js +13 -1
  68. package/dist/lib/consolidation.js +1 -1
  69. package/dist/lib/database.js +124 -0
  70. package/dist/lib/db.js +124 -0
  71. package/dist/lib/device-registry.js +124 -0
  72. package/dist/lib/embedder.js +13 -1
  73. package/dist/lib/exe-daemon.js +2184 -561
  74. package/dist/lib/hybrid-search.js +518 -24
  75. package/dist/lib/identity.js +3 -0
  76. package/dist/lib/keychain.js +178 -22
  77. package/dist/lib/messaging.js +3 -0
  78. package/dist/lib/reminders.js +3 -0
  79. package/dist/lib/schedules.js +233 -20
  80. package/dist/lib/skill-learning.js +16 -1
  81. package/dist/lib/store.js +506 -20
  82. package/dist/lib/tasks.js +16 -1
  83. package/dist/lib/tmux-routing.js +16 -1
  84. package/dist/lib/token-spend.js +3 -0
  85. package/dist/mcp/server.js +1757 -428
  86. package/dist/mcp/tools/complete-reminder.js +3 -0
  87. package/dist/mcp/tools/create-reminder.js +3 -0
  88. package/dist/mcp/tools/create-task.js +16 -1
  89. package/dist/mcp/tools/deactivate-behavior.js +3 -0
  90. package/dist/mcp/tools/list-reminders.js +3 -0
  91. package/dist/mcp/tools/list-tasks.js +3 -0
  92. package/dist/mcp/tools/send-message.js +3 -0
  93. package/dist/mcp/tools/update-task.js +16 -1
  94. package/dist/runtime/index.js +516 -22
  95. package/dist/tui/App.js +594 -29
  96. package/package.json +8 -5
  97. package/src/commands/exe/cloud.md +6 -10
  98. package/stack.release.json +3 -3
  99. package/src/commands/exe/link.md +0 -18
@@ -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
  };
@@ -612,6 +606,63 @@ var init_preferences = __esm({
612
606
  }
613
607
  });
614
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
+
615
666
  // src/adapters/runtime-hook-manifest.ts
616
667
  function commandHasAnyMarker(command, markers) {
617
668
  return markers.some((marker) => command.includes(marker));
@@ -756,54 +807,58 @@ var init_runtime_hook_manifest = __esm({
756
807
  });
757
808
 
758
809
  // src/adapters/claude/installer.ts
759
- import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
760
- import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4, copyFileSync, mkdirSync as mkdirSync3, chmodSync as chmodSync2 } from "fs";
761
- import { createHash, randomBytes } from "crypto";
762
- import path6 from "path";
763
- 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";
764
815
  import { execSync as execSync2 } from "child_process";
765
816
  import { fileURLToPath } from "url";
766
817
  function resolvePackageRoot() {
767
818
  const thisFile = fileURLToPath(import.meta.url);
768
- let dir = path6.dirname(thisFile);
769
- const root = path6.parse(dir).root;
819
+ let dir = path7.dirname(thisFile);
820
+ const root = path7.parse(dir).root;
770
821
  while (dir !== root) {
771
- const pkgPath = path6.join(dir, "package.json");
772
- if (existsSync7(pkgPath)) {
822
+ const pkgPath = path7.join(dir, "package.json");
823
+ if (existsSync8(pkgPath)) {
773
824
  try {
774
- const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
825
+ const pkg = JSON.parse(readFileSync6(pkgPath, "utf-8"));
775
826
  if (pkg.name === "@askexenow/exe-os" || pkg.name === "exe-os") return dir;
776
827
  } catch {
777
828
  }
778
829
  }
779
- dir = path6.dirname(dir);
830
+ dir = path7.dirname(dir);
780
831
  }
781
- return path6.resolve(path6.dirname(thisFile), "..", "..", "..");
832
+ return path7.resolve(path7.dirname(thisFile), "..", "..", "..");
782
833
  }
783
- async function copySlashCommands(packageRoot, homeDir = os5.homedir()) {
834
+ async function copySlashCommands(packageRoot, homeDir = os6.homedir()) {
784
835
  let copied = 0;
785
836
  let skipped = 0;
786
- const skillsBase = path6.join(homeDir, ".claude", "skills");
787
- const exeDir = path6.join(packageRoot, "src", "commands", "exe");
788
- 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)) {
789
844
  const entries = await readdir(exeDir);
790
845
  const mdFiles = entries.filter((f) => f.endsWith(".md"));
791
846
  for (const file of mdFiles) {
792
847
  const name = file.replace(".md", "");
793
- const destDir = path6.join(skillsBase, `exe-${name}`);
848
+ const destDir = path7.join(skillsBase, `exe-${name}`);
794
849
  await mkdir3(destDir, { recursive: true });
795
- const srcPath = path6.join(exeDir, file);
796
- const destPath = path6.join(destDir, "SKILL.md");
850
+ const srcPath = path7.join(exeDir, file);
851
+ const destPath = path7.join(destDir, "SKILL.md");
797
852
  const result = await copyAsSkill(srcPath, destPath, `exe-${name}`);
798
853
  if (result) copied++;
799
854
  else skipped++;
800
855
  }
801
856
  }
802
- const topLevelSrc = path6.join(packageRoot, "src", "commands", "exe.md");
803
- if (existsSync7(topLevelSrc)) {
804
- 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");
805
860
  await mkdir3(destDir, { recursive: true });
806
- const destPath = path6.join(destDir, "SKILL.md");
861
+ const destPath = path7.join(destDir, "SKILL.md");
807
862
  const result = await copyAsSkill(topLevelSrc, destPath, "exe");
808
863
  if (result) copied++;
809
864
  else skipped++;
@@ -826,7 +881,7 @@ name: ${skillName}
826
881
  `);
827
882
  }
828
883
  }
829
- if (existsSync7(destPath)) {
884
+ if (existsSync8(destPath)) {
830
885
  const existing = await readFile3(destPath, "utf-8");
831
886
  if (existing === content) return false;
832
887
  }
@@ -835,32 +890,32 @@ name: ${skillName}
835
890
  }
836
891
  function readJsonFile(filePath) {
837
892
  try {
838
- return JSON.parse(readFileSync5(filePath, "utf-8"));
893
+ return JSON.parse(readFileSync6(filePath, "utf-8"));
839
894
  } catch {
840
895
  return null;
841
896
  }
842
897
  }
843
898
  function findAncestorMcpJsons(startDir, homeDir) {
844
899
  const files = [];
845
- let dir = path6.resolve(startDir);
846
- const root = path6.parse(dir).root;
847
- const stop = path6.resolve(homeDir);
900
+ let dir = path7.resolve(startDir);
901
+ const root = path7.parse(dir).root;
902
+ const stop = path7.resolve(homeDir);
848
903
  while (dir !== root) {
849
- const candidate = path6.join(dir, ".mcp.json");
850
- if (existsSync7(candidate)) files.push(candidate);
904
+ const candidate = path7.join(dir, ".mcp.json");
905
+ if (existsSync8(candidate)) files.push(candidate);
851
906
  if (dir === stop) break;
852
- dir = path6.dirname(dir);
907
+ dir = path7.dirname(dir);
853
908
  }
854
909
  return files;
855
910
  }
856
911
  function pathApplies(projectPath, cwd) {
857
- const project = path6.resolve(projectPath);
858
- const current = path6.resolve(cwd);
859
- 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);
860
915
  }
861
- function detectMcpNameCollisions(homeDir = os5.homedir(), cwd = process.cwd()) {
862
- const claudeJsonPath = path6.join(homeDir, ".claude.json");
863
- 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 [];
864
919
  const claudeJson = readJsonFile(claudeJsonPath);
865
920
  if (!claudeJson?.projects) return [];
866
921
  const collisions = [];
@@ -887,44 +942,11 @@ function detectMcpNameCollisions(homeDir = os5.homedir(), cwd = process.cwd()) {
887
942
  }
888
943
  return collisions;
889
944
  }
890
- function readOrCreateDaemonToken(homeDir) {
891
- const exeDir = path6.join(homeDir, ".exe-os");
892
- const tokenPath = path6.join(exeDir, "exed.token");
893
- try {
894
- if (existsSync7(tokenPath)) {
895
- const token2 = readFileSync5(tokenPath, "utf-8").trim();
896
- if (token2) return token2;
897
- }
898
- } catch {
899
- }
900
- const token = randomBytes(32).toString("hex");
901
- mkdirSync3(exeDir, { recursive: true });
902
- writeFileSync4(tokenPath, `${token}
903
- `, "utf-8");
904
- try {
905
- chmodSync2(tokenPath, 384);
906
- } catch {
907
- }
908
- return token;
909
- }
910
- function buildHttpMcpEntry(homeDir) {
911
- const port = process.env.EXE_MCP_PORT || "48739";
912
- const token = readOrCreateDaemonToken(homeDir);
913
- return {
914
- type: "http",
915
- url: `http://127.0.0.1:${port}/mcp`,
916
- headers: {
917
- Authorization: `Bearer ${token}`,
918
- "X-Agent-Id": "${AGENT_ID:-exe}",
919
- "X-Agent-Role": "${AGENT_ROLE:-COO}"
920
- }
921
- };
922
- }
923
945
  function buildStdioMcpEntry(packageRoot) {
924
946
  return {
925
947
  type: "stdio",
926
948
  command: "node",
927
- args: [path6.join(packageRoot, "dist", "mcp", "server.js")],
949
+ args: [path7.join(packageRoot, "dist", "mcp", "server.js")],
928
950
  env: {}
929
951
  };
930
952
  }
@@ -932,14 +954,14 @@ function mcpTransportMode() {
932
954
  const value = process.env.EXE_OS_MCP_TRANSPORT?.trim().toLowerCase();
933
955
  if (value === "stdio") return "stdio";
934
956
  if (value === "http") return "http";
935
- const totalGB = os5.totalmem() / (1024 * 1024 * 1024);
957
+ const totalGB = os6.totalmem() / (1024 * 1024 * 1024);
936
958
  if (totalGB <= 8) return "stdio";
937
959
  return "http";
938
960
  }
939
- async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
940
- const claudeJsonPath = path6.join(homeDir, ".claude.json");
961
+ async function registerMcpServer(packageRoot, homeDir = os6.homedir()) {
962
+ const claudeJsonPath = path7.join(homeDir, ".claude.json");
941
963
  let claudeJson = {};
942
- if (existsSync7(claudeJsonPath)) {
964
+ if (existsSync8(claudeJsonPath)) {
943
965
  try {
944
966
  claudeJson = JSON.parse(await readFile3(claudeJsonPath, "utf-8"));
945
967
  } catch {
@@ -949,7 +971,7 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
949
971
  if (!claudeJson.mcpServers) {
950
972
  claudeJson.mcpServers = {};
951
973
  }
952
- const newEntry = mcpTransportMode() === "stdio" ? buildStdioMcpEntry(packageRoot) : buildHttpMcpEntry(homeDir);
974
+ const newEntry = mcpTransportMode() === "stdio" ? buildStdioMcpEntry(packageRoot) : buildClaudeHttpMcpEntry(homeDir);
953
975
  if (claudeJson.mcpServers[MCP_LEGACY_KEY]) {
954
976
  delete claudeJson.mcpServers[MCP_LEGACY_KEY];
955
977
  process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
@@ -957,8 +979,8 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
957
979
  const currentOs = claudeJson.mcpServers[MCP_PRIMARY_KEY];
958
980
  const osMatches = currentOs && JSON.stringify(currentOs) === JSON.stringify(newEntry);
959
981
  if (osMatches) {
960
- await cleanSettingsJsonMcp(path6.join(homeDir, ".claude", "settings.json"));
961
- 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"));
962
984
  const collisions2 = detectMcpNameCollisions(homeDir, packageRoot).filter((c) => c.serverName === MCP_PRIMARY_KEY || c.serverName === MCP_LEGACY_KEY);
963
985
  for (const c of collisions2) {
964
986
  process.stderr.write(
@@ -970,8 +992,8 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
970
992
  }
971
993
  claudeJson.mcpServers[MCP_PRIMARY_KEY] = newEntry;
972
994
  await writeFile3(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
973
- await cleanSettingsJsonMcp(path6.join(homeDir, ".claude", "settings.json"));
974
- 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"));
975
997
  const collisions = detectMcpNameCollisions(homeDir, packageRoot).filter((c) => c.serverName === MCP_PRIMARY_KEY || c.serverName === MCP_LEGACY_KEY);
976
998
  for (const c of collisions) {
977
999
  process.stderr.write(
@@ -982,7 +1004,7 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
982
1004
  return true;
983
1005
  }
984
1006
  async function cleanSettingsJsonMcp(settingsPath) {
985
- if (!existsSync7(settingsPath)) return;
1007
+ if (!existsSync8(settingsPath)) return;
986
1008
  try {
987
1009
  const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
988
1010
  const servers = settings.mcpServers;
@@ -1003,7 +1025,7 @@ async function cleanSettingsJsonMcp(settingsPath) {
1003
1025
  }
1004
1026
  }
1005
1027
  async function migratePermissionsToExeOs(settingsPath) {
1006
- if (!existsSync7(settingsPath)) return;
1028
+ if (!existsSync8(settingsPath)) return;
1007
1029
  try {
1008
1030
  const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1009
1031
  const permissions = settings.permissions;
@@ -1031,14 +1053,14 @@ async function migratePermissionsToExeOs(settingsPath) {
1031
1053
  } catch {
1032
1054
  }
1033
1055
  }
1034
- async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1035
- const settingsPath = path6.join(homeDir, ".claude", "settings.json");
1036
- const logsDir = path6.join(homeDir, ".exe-os", "logs");
1037
- 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");
1038
1060
  const logSuffix = ` 2>> "${hookLogPath}"`;
1039
1061
  await mkdir3(logsDir, { recursive: true });
1040
1062
  let settings = {};
1041
- if (existsSync7(settingsPath)) {
1063
+ if (existsSync8(settingsPath)) {
1042
1064
  try {
1043
1065
  settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1044
1066
  } catch {
@@ -1060,7 +1082,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1060
1082
  hooks: [
1061
1083
  {
1062
1084
  type: "command",
1063
- 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}`
1064
1086
  }
1065
1087
  ]
1066
1088
  },
@@ -1072,7 +1094,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1072
1094
  hooks: [
1073
1095
  {
1074
1096
  type: "command",
1075
- command: `node "${path6.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
1097
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
1076
1098
  timeout: 1e4
1077
1099
  }
1078
1100
  ]
@@ -1085,7 +1107,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1085
1107
  hooks: [
1086
1108
  {
1087
1109
  type: "command",
1088
- command: `node "${path6.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
1110
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
1089
1111
  }
1090
1112
  ]
1091
1113
  },
@@ -1097,7 +1119,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1097
1119
  hooks: [
1098
1120
  {
1099
1121
  type: "command",
1100
- 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}`,
1101
1123
  timeout: 5e3
1102
1124
  }
1103
1125
  ]
@@ -1110,7 +1132,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1110
1132
  hooks: [
1111
1133
  {
1112
1134
  type: "command",
1113
- command: `node "${path6.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
1135
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
1114
1136
  }
1115
1137
  ]
1116
1138
  },
@@ -1123,7 +1145,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1123
1145
  hooks: [
1124
1146
  {
1125
1147
  type: "command",
1126
- 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}`
1127
1149
  }
1128
1150
  ]
1129
1151
  },
@@ -1135,7 +1157,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1135
1157
  hooks: [
1136
1158
  {
1137
1159
  type: "command",
1138
- command: `node "${path6.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
1160
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
1139
1161
  }
1140
1162
  ]
1141
1163
  },
@@ -1147,7 +1169,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1147
1169
  hooks: [
1148
1170
  {
1149
1171
  type: "command",
1150
- command: `node "${path6.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
1172
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
1151
1173
  timeout: 1e4
1152
1174
  }
1153
1175
  ]
@@ -1160,7 +1182,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1160
1182
  hooks: [
1161
1183
  {
1162
1184
  type: "command",
1163
- command: `node "${path6.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
1185
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
1164
1186
  }
1165
1187
  ]
1166
1188
  },
@@ -1172,7 +1194,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1172
1194
  hooks: [
1173
1195
  {
1174
1196
  type: "command",
1175
- command: `node "${path6.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
1197
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
1176
1198
  }
1177
1199
  ]
1178
1200
  },
@@ -1184,7 +1206,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1184
1206
  hooks: [
1185
1207
  {
1186
1208
  type: "command",
1187
- command: `node "${path6.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
1209
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
1188
1210
  timeout: 1e4
1189
1211
  }
1190
1212
  ]
@@ -1197,7 +1219,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1197
1219
  hooks: [
1198
1220
  {
1199
1221
  type: "command",
1200
- command: `node "${path6.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
1222
+ command: `node "${path7.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
1201
1223
  }
1202
1224
  ]
1203
1225
  },
@@ -1302,13 +1324,13 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1302
1324
  allowList.push(fullName);
1303
1325
  }
1304
1326
  }
1305
- await mkdir3(path6.dirname(settingsPath), { recursive: true });
1327
+ await mkdir3(path7.dirname(settingsPath), { recursive: true });
1306
1328
  await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
1307
1329
  return { added, skipped };
1308
1330
  }
1309
- async function cleanOldShellFunctions(homeDir = os5.homedir()) {
1310
- const rosterPath = path6.join(homeDir, ".exe-os", "exe-employees.json");
1311
- 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;
1312
1334
  let employees;
1313
1335
  try {
1314
1336
  employees = JSON.parse(await readFile3(rosterPath, "utf-8"));
@@ -1323,13 +1345,13 @@ async function cleanOldShellFunctions(homeDir = os5.homedir()) {
1323
1345
  return { name: n, funcDef, forLoop };
1324
1346
  });
1325
1347
  const rcFiles = [
1326
- path6.join(homeDir, ".zshrc"),
1327
- path6.join(homeDir, ".bashrc")
1348
+ path7.join(homeDir, ".zshrc"),
1349
+ path7.join(homeDir, ".bashrc")
1328
1350
  ];
1329
1351
  const REMOVED_MARKER = "# Removed by exe-os \u2014 wrappers now at ~/.exe-os/bin/";
1330
1352
  let totalRemoved = 0;
1331
1353
  for (const rcPath of rcFiles) {
1332
- if (!existsSync7(rcPath)) continue;
1354
+ if (!existsSync8(rcPath)) continue;
1333
1355
  let content;
1334
1356
  try {
1335
1357
  content = await readFile3(rcPath, "utf-8");
@@ -1433,8 +1455,8 @@ function escapeRegExp(s) {
1433
1455
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1434
1456
  }
1435
1457
  async function injectOrchestrationRules(homeDir) {
1436
- const claudeDir = path6.join(homeDir, ".claude");
1437
- const claudeMdPath = path6.join(claudeDir, "CLAUDE.md");
1458
+ const claudeDir = path7.join(homeDir, ".claude");
1459
+ const claudeMdPath = path7.join(claudeDir, "CLAUDE.md");
1438
1460
  await mkdir3(claudeDir, { recursive: true });
1439
1461
  let existing = "";
1440
1462
  try {
@@ -1456,19 +1478,19 @@ async function injectOrchestrationRules(homeDir) {
1456
1478
  await writeFile3(claudeMdPath, existing + separator + ORCHESTRATION_RULES + "\n", "utf-8");
1457
1479
  return "injected";
1458
1480
  }
1459
- async function installStatusLine(packageRoot, homeDir = os5.homedir()) {
1481
+ async function installStatusLine(packageRoot, homeDir = os6.homedir()) {
1460
1482
  const prefs = loadPreferences(homeDir);
1461
1483
  if (prefs.ccStatusLine === false) return "opted-out";
1462
- const claudeDir = path6.join(homeDir, ".claude");
1484
+ const claudeDir = path7.join(homeDir, ".claude");
1463
1485
  await mkdir3(claudeDir, { recursive: true });
1464
- const assetPath = path6.join(packageRoot, "dist", "assets", "statusline-command.sh");
1465
- if (!existsSync7(assetPath)) return "asset-missing";
1466
- 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");
1467
1489
  const assetContent = await readFile3(assetPath, "utf-8");
1468
1490
  await writeFile3(destScript, assetContent, { mode: 493 });
1469
- const settingsPath = path6.join(claudeDir, "settings.json");
1491
+ const settingsPath = path7.join(claudeDir, "settings.json");
1470
1492
  let settings = {};
1471
- if (existsSync7(settingsPath)) {
1493
+ if (existsSync8(settingsPath)) {
1472
1494
  try {
1473
1495
  settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1474
1496
  } catch {
@@ -1505,13 +1527,13 @@ async function runInstaller(homeDir) {
1505
1527
  `Hooks: ${hookResult.added} added, ${hookResult.skipped} unchanged
1506
1528
  `
1507
1529
  );
1508
- const resolvedHome = homeDir ?? os5.homedir();
1509
- const exeWorkspace = path6.join(resolvedHome, "exe");
1510
- if (!existsSync7(exeWorkspace)) {
1530
+ const resolvedHome = homeDir ?? os6.homedir();
1531
+ const exeWorkspace = path7.join(resolvedHome, "exe");
1532
+ if (!existsSync8(exeWorkspace)) {
1511
1533
  try {
1512
- await mkdir3(path6.join(exeWorkspace, "content"), { recursive: true });
1513
- await mkdir3(path6.join(exeWorkspace, "operations"), { recursive: true });
1514
- 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 });
1515
1537
  process.stderr.write(
1516
1538
  `Created ~/exe/ \u2014 your automation workspace for non-code projects
1517
1539
  `
@@ -1546,57 +1568,57 @@ exe-os installed successfully.
1546
1568
  `);
1547
1569
  }
1548
1570
  function setupTmux(home) {
1549
- const homeDir = home ?? os5.homedir();
1550
- const exeDir = path6.join(homeDir, ".exe-os");
1551
- const exeTmuxConf = path6.join(exeDir, "tmux.conf");
1552
- const userTmuxConf = path6.join(homeDir, ".tmux.conf");
1553
- 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");
1554
1576
  const sourceLine = "source-file ~/.exe-os/tmux.conf";
1555
1577
  const pkgRoot = resolvePackageRoot();
1556
- const assetPath = path6.join(pkgRoot, "dist", "assets", "tmux.conf");
1557
- if (!existsSync7(assetPath)) {
1578
+ const assetPath = path7.join(pkgRoot, "dist", "assets", "tmux.conf");
1579
+ if (!existsSync8(assetPath)) {
1558
1580
  process.stderr.write(`exe-os: tmux.conf asset not found at ${assetPath} \u2014 skipping tmux setup
1559
1581
  `);
1560
1582
  return;
1561
1583
  }
1562
- mkdirSync3(exeDir, { recursive: true });
1563
- if (existsSync7(exeTmuxConf)) {
1564
- const currentContent = readFileSync5(exeTmuxConf, "utf8");
1565
- 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");
1566
1588
  const currentHash = createHash("sha256").update(currentContent).digest("hex");
1567
1589
  const newHash = createHash("sha256").update(newContent).digest("hex");
1568
1590
  if (currentHash !== newHash) {
1569
- const shippedPath = path6.join(exeDir, ".tmux.conf.shipped-hash");
1570
- 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() : "";
1571
1593
  if (lastShippedHash && currentHash !== lastShippedHash) {
1572
1594
  process.stderr.write("exe-os: tmux config has user customizations \u2014 skipping overwrite\n");
1573
1595
  } else {
1574
1596
  copyFileSync(assetPath, exeTmuxConf);
1575
1597
  process.stderr.write("exe-os: tmux config updated\n");
1576
1598
  }
1577
- writeFileSync4(shippedPath, newHash, "utf8");
1599
+ writeFileSync5(shippedPath, newHash, "utf8");
1578
1600
  } else {
1579
1601
  process.stderr.write("exe-os: tmux config already up to date\n");
1580
1602
  }
1581
1603
  } else {
1582
1604
  copyFileSync(assetPath, exeTmuxConf);
1583
- const newContent = readFileSync5(assetPath, "utf8");
1605
+ const newContent = readFileSync6(assetPath, "utf8");
1584
1606
  const newHash = createHash("sha256").update(newContent).digest("hex");
1585
- writeFileSync4(path6.join(exeDir, ".tmux.conf.shipped-hash"), newHash, "utf8");
1607
+ writeFileSync5(path7.join(exeDir, ".tmux.conf.shipped-hash"), newHash, "utf8");
1586
1608
  }
1587
- if (existsSync7(userTmuxConf)) {
1588
- const existing = readFileSync5(userTmuxConf, "utf8");
1609
+ if (existsSync8(userTmuxConf)) {
1610
+ const existing = readFileSync6(userTmuxConf, "utf8");
1589
1611
  if (!existing.includes(sourceLine)) {
1590
- if (!existsSync7(backupPath)) {
1612
+ if (!existsSync8(backupPath)) {
1591
1613
  copyFileSync(userTmuxConf, backupPath);
1592
1614
  process.stderr.write(`exe-os: backed up existing tmux config to ${backupPath}
1593
1615
  `);
1594
1616
  }
1595
- writeFileSync4(userTmuxConf, `${sourceLine}
1617
+ writeFileSync5(userTmuxConf, `${sourceLine}
1596
1618
  ${existing}`);
1597
1619
  }
1598
1620
  } else {
1599
- 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
1600
1622
  ${sourceLine}
1601
1623
  `);
1602
1624
  }
@@ -1607,10 +1629,10 @@ ${sourceLine}
1607
1629
  process.stderr.write("exe-os: tmux config installed\n");
1608
1630
  }
1609
1631
  function setupGhostty(home) {
1610
- const homeDir = home ?? os5.homedir();
1611
- const xdgConfig = path6.join(homeDir, ".config", "ghostty");
1612
- const macConfig = path6.join(homeDir, "Library", "Application Support", "com.mitchellh.ghostty");
1613
- 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) || (() => {
1614
1636
  try {
1615
1637
  execSync2("which ghostty 2>/dev/null");
1616
1638
  return true;
@@ -1622,48 +1644,48 @@ function setupGhostty(home) {
1622
1644
  return;
1623
1645
  }
1624
1646
  const pkgRoot = resolvePackageRoot();
1625
- const assetPath = path6.join(pkgRoot, "dist", "assets", "ghostty.conf");
1626
- if (!existsSync7(assetPath)) {
1647
+ const assetPath = path7.join(pkgRoot, "dist", "assets", "ghostty.conf");
1648
+ if (!existsSync8(assetPath)) {
1627
1649
  process.stderr.write("exe-os: ghostty.conf asset not found \u2014 skipping Ghostty setup\n");
1628
1650
  return;
1629
1651
  }
1630
1652
  const configDir = xdgConfig;
1631
- const configPath = path6.join(configDir, "config");
1632
- const backupPath = path6.join(configDir, "config.backup");
1633
- mkdirSync3(configDir, { recursive: true });
1653
+ const configPath = path7.join(configDir, "config");
1654
+ const backupPath = path7.join(configDir, "config.backup");
1655
+ mkdirSync4(configDir, { recursive: true });
1634
1656
  const START_MARKER = "# \u2500\u2500 exe-os:ghostty-start \u2500\u2500";
1635
1657
  const END_MARKER = "# \u2500\u2500 exe-os:ghostty-end \u2500\u2500";
1636
- const assetContent = readFileSync5(assetPath, "utf8").trim();
1658
+ const assetContent = readFileSync6(assetPath, "utf8").trim();
1637
1659
  const markedSection = `${START_MARKER}
1638
1660
  ${assetContent}
1639
1661
  ${END_MARKER}`;
1640
- if (existsSync7(configPath)) {
1641
- const existing = readFileSync5(configPath, "utf8");
1662
+ if (existsSync8(configPath)) {
1663
+ const existing = readFileSync6(configPath, "utf8");
1642
1664
  if (existing.includes(START_MARKER) && existing.includes(END_MARKER)) {
1643
1665
  process.stderr.write("exe-os: Ghostty config already installed \u2014 preserving local settings\n");
1644
1666
  return;
1645
1667
  } else if (existing.includes("Exe OS")) {
1646
- if (!existsSync7(backupPath)) {
1668
+ if (!existsSync8(backupPath)) {
1647
1669
  copyFileSync(configPath, backupPath);
1648
1670
  process.stderr.write(`exe-os: backed up existing Ghostty config to ${backupPath}
1649
1671
  `);
1650
1672
  }
1651
- writeFileSync4(configPath, `${START_MARKER}
1673
+ writeFileSync5(configPath, `${START_MARKER}
1652
1674
  ${existing.trim()}
1653
1675
  ${END_MARKER}
1654
1676
  `);
1655
1677
  } else {
1656
- if (!existsSync7(backupPath)) {
1678
+ if (!existsSync8(backupPath)) {
1657
1679
  copyFileSync(configPath, backupPath);
1658
1680
  process.stderr.write(`exe-os: backed up existing Ghostty config to ${backupPath}
1659
1681
  `);
1660
1682
  }
1661
- writeFileSync4(configPath, `${markedSection}
1683
+ writeFileSync5(configPath, `${markedSection}
1662
1684
 
1663
1685
  ${existing}`);
1664
1686
  }
1665
1687
  } else {
1666
- writeFileSync4(configPath, `${markedSection}
1688
+ writeFileSync5(configPath, `${markedSection}
1667
1689
  `);
1668
1690
  }
1669
1691
  process.stderr.write("exe-os: Ghostty config installed\n");
@@ -1687,6 +1709,7 @@ var init_installer = __esm({
1687
1709
  init_agent_symlinks();
1688
1710
  init_mcp_prefix();
1689
1711
  init_preferences();
1712
+ init_mcp_http_config();
1690
1713
  init_runtime_hook_manifest();
1691
1714
  EXE_SECTION_START = "<!-- exe-os:orchestration-start -->";
1692
1715
  EXE_SECTION_END = "<!-- exe-os:orchestration-end -->";
@@ -1715,19 +1738,19 @@ __export(installer_exports, {
1715
1738
  verifyCodexHooks: () => verifyCodexHooks
1716
1739
  });
1717
1740
  import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir4 } from "fs/promises";
1718
- import { existsSync as existsSync9 } from "fs";
1719
- import path8 from "path";
1720
- import os6 from "os";
1721
- async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1722
- const codexDir = path8.join(homeDir, ".codex");
1723
- const hooksPath = path8.join(codexDir, "hooks.json");
1724
- const logsDir = path8.join(homeDir, ".exe-os", "logs");
1725
- 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");
1726
1749
  const logSuffix = ` 2>> "${hookLogPath}"`;
1727
1750
  await mkdir4(codexDir, { recursive: true });
1728
1751
  await mkdir4(logsDir, { recursive: true });
1729
1752
  let hooksJson = {};
1730
- if (existsSync9(hooksPath)) {
1753
+ if (existsSync10(hooksPath)) {
1731
1754
  try {
1732
1755
  hooksJson = JSON.parse(await readFile4(hooksPath, "utf-8"));
1733
1756
  } catch {
@@ -1738,19 +1761,6 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1738
1761
  hooksJson.hooks = {};
1739
1762
  }
1740
1763
  const hooksToRegister = [
1741
- {
1742
- event: "SessionStart",
1743
- group: {
1744
- hooks: [
1745
- {
1746
- type: "command",
1747
- command: `node "${path8.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
1748
- timeout: 30
1749
- }
1750
- ]
1751
- },
1752
- marker: EXE_HOOKS.sessionStart
1753
- },
1754
1764
  {
1755
1765
  event: "PostToolUse",
1756
1766
  group: {
@@ -1760,7 +1770,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1760
1770
  // Combined hook: runs ingest + error-recall in one Node process.
1761
1771
  // Eliminates a cold-start cycle per tool call (~3-6s savings on Codex).
1762
1772
  type: "command",
1763
- 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}`
1764
1774
  }
1765
1775
  ]
1766
1776
  },
@@ -1774,7 +1784,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1774
1784
  // Single hook: prompt-submit handles memory retrieval + entity boost.
1775
1785
  // exe-heartbeat-hook is CC-specific (intercom) — omitted on Codex.
1776
1786
  type: "command",
1777
- command: `node "${path8.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
1787
+ command: `node "${path9.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
1778
1788
  }
1779
1789
  ]
1780
1790
  },
@@ -1786,7 +1796,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1786
1796
  hooks: [
1787
1797
  {
1788
1798
  type: "command",
1789
- command: `node "${path8.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
1799
+ command: `node "${path9.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
1790
1800
  }
1791
1801
  ]
1792
1802
  },
@@ -1799,7 +1809,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1799
1809
  hooks: [
1800
1810
  {
1801
1811
  type: "command",
1802
- 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}`
1803
1813
  }
1804
1814
  ]
1805
1815
  },
@@ -1808,6 +1818,16 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1808
1818
  ];
1809
1819
  let added = 0;
1810
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
+ }
1811
1831
  const postToolGroups = hooksJson.hooks["PostToolUse"];
1812
1832
  if (Array.isArray(postToolGroups)) {
1813
1833
  hooksJson.hooks["PostToolUse"] = postToolGroups.map((g) => ({
@@ -1837,15 +1857,13 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1837
1857
  await writeFile4(hooksPath, JSON.stringify(hooksJson, null, 2) + "\n");
1838
1858
  return { added, skipped };
1839
1859
  }
1840
- function verifyCodexHooks(homeDir = os6.homedir()) {
1841
- const hooksPath = path8.join(homeDir, ".codex", "hooks.json");
1842
- 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;
1843
1863
  try {
1844
- const hooksJson = JSON.parse(
1845
- __require("fs").readFileSync(hooksPath, "utf-8")
1846
- );
1864
+ const hooksJson = JSON.parse(readFileSync8(hooksPath, "utf-8"));
1847
1865
  if (!hooksJson.hooks) return false;
1848
- const required = ["SessionStart", "PostToolUse", "UserPromptSubmit", "Stop", "PreToolUse"];
1866
+ const required = ["PostToolUse", "UserPromptSubmit", "Stop", "PreToolUse"];
1849
1867
  for (const event of required) {
1850
1868
  const groups = hooksJson.hooks[event];
1851
1869
  if (!groups || !groups.some(
@@ -1863,19 +1881,23 @@ function verifyCodexHooks(homeDir = os6.homedir()) {
1863
1881
  )) {
1864
1882
  return false;
1865
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
+ }
1866
1888
  return true;
1867
1889
  } catch {
1868
1890
  return false;
1869
1891
  }
1870
1892
  }
1871
- async function installCodexStatusLine(homeDir = os6.homedir()) {
1893
+ async function installCodexStatusLine(homeDir = os7.homedir()) {
1872
1894
  const prefs = loadPreferences(homeDir);
1873
1895
  if (prefs.codexStatusLine === false) return "opted-out";
1874
- const codexDir = path8.join(homeDir, ".codex");
1875
- const configPath = path8.join(codexDir, "config.toml");
1896
+ const codexDir = path9.join(homeDir, ".codex");
1897
+ const configPath = path9.join(codexDir, "config.toml");
1876
1898
  await mkdir4(codexDir, { recursive: true });
1877
1899
  let content = "";
1878
- if (existsSync9(configPath)) {
1900
+ if (existsSync10(configPath)) {
1879
1901
  content = await readFile4(configPath, "utf-8");
1880
1902
  if (/\[tui\][\s\S]*?status_line\s*=/.test(content)) {
1881
1903
  return "already-configured";
@@ -1892,53 +1914,47 @@ status_line = [${DEFAULT_CODEX_STATUS_LINE.map((s) => `"${s}"`).join(", ")}]`;
1892
1914
  await writeFile4(configPath, content);
1893
1915
  return "installed";
1894
1916
  }
1895
- 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) {
1896
1925
  return [
1897
1926
  "[mcp_servers.exe-os]",
1898
- `command = "node"`,
1899
- `args = ["${serverJsPath}"]`,
1927
+ `url = ${tomlString(mcpHttpUrl())}`,
1928
+ `http_headers = ${codexHttpHeadersToml(homeDir)}`,
1900
1929
  `startup_timeout_sec = ${CODEX_EXE_MCP_STARTUP_TIMEOUT_SEC}`,
1901
1930
  `tool_timeout_sec = ${CODEX_EXE_MCP_TOOL_TIMEOUT_SEC}`,
1902
1931
  ""
1903
1932
  ].join("\n");
1904
1933
  }
1905
- function reconcileCodexMcpSection(sectionContent, serverJsPath) {
1934
+ function reconcileCodexMcpSection(sectionContent, homeDir) {
1906
1935
  const desiredLines = {
1907
- command: `command = "node"`,
1908
- args: `args = ["${serverJsPath}"]`,
1936
+ url: `url = ${tomlString(mcpHttpUrl())}`,
1937
+ headers: `http_headers = ${codexHttpHeadersToml(homeDir)}`,
1909
1938
  startup: `startup_timeout_sec = ${CODEX_EXE_MCP_STARTUP_TIMEOUT_SEC}`,
1910
1939
  tool: `tool_timeout_sec = ${CODEX_EXE_MCP_TOOL_TIMEOUT_SEC}`
1911
1940
  };
1912
1941
  let next = sectionContent;
1913
- let changed = false;
1914
- const replaceOrAppend = (regex, desired) => {
1915
- if (regex.test(next)) {
1916
- const updated = next.replace(regex, desired);
1917
- if (updated !== next) {
1918
- next = updated;
1919
- changed = true;
1920
- }
1921
- return;
1922
- }
1923
- 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}
1924
1945
  ` : `${next}
1925
- ${desired}
1946
+ ${line}
1926
1947
  `;
1927
- changed = true;
1928
- };
1929
- replaceOrAppend(/^command\s*=.*$/m, desiredLines.command);
1930
- replaceOrAppend(/^args\s*=.*$/m, desiredLines.args);
1931
- replaceOrAppend(/^startup_timeout_sec\s*=.*$/m, desiredLines.startup);
1932
- replaceOrAppend(/^tool_timeout_sec\s*=.*$/m, desiredLines.tool);
1933
- return { content: next, changed };
1934
- }
1935
- async function registerCodexMcpServer(packageRoot, homeDir = os6.homedir()) {
1936
- const codexDir = path8.join(homeDir, ".codex");
1937
- const configPath = path8.join(codexDir, "config.toml");
1938
- 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;
1939
1955
  await mkdir4(codexDir, { recursive: true });
1940
1956
  let content = "";
1941
- if (existsSync9(configPath)) {
1957
+ if (existsSync10(configPath)) {
1942
1958
  content = await readFile4(configPath, "utf-8");
1943
1959
  }
1944
1960
  const sectionHeader = "[mcp_servers.exe-os]";
@@ -1948,7 +1964,7 @@ async function registerCodexMcpServer(packageRoot, homeDir = os6.homedir()) {
1948
1964
  const nextSectionMatch = afterHeader.match(/\n\[(?!mcp_servers\.exe-os)/);
1949
1965
  const sectionEnd = nextSectionMatch ? headerIndex + sectionHeader.length + nextSectionMatch.index : content.length;
1950
1966
  const sectionContent = content.slice(headerIndex, sectionEnd);
1951
- const reconciled = reconcileCodexMcpSection(sectionContent, serverJsPath);
1967
+ const reconciled = reconcileCodexMcpSection(sectionContent, homeDir);
1952
1968
  if (!reconciled.changed) {
1953
1969
  return "already-registered";
1954
1970
  }
@@ -1956,17 +1972,17 @@ async function registerCodexMcpServer(packageRoot, homeDir = os6.homedir()) {
1956
1972
  await writeFile4(configPath, content);
1957
1973
  return "updated";
1958
1974
  }
1959
- const newSection = desiredCodexMcpSection(serverJsPath);
1975
+ const newSection = desiredCodexMcpSection(homeDir);
1960
1976
  const separator = content.length > 0 && !content.endsWith("\n") ? "\n\n" : content.length > 0 ? "\n" : "";
1961
1977
  content = content + separator + newSection;
1962
1978
  await writeFile4(configPath, content);
1963
1979
  return "registered";
1964
1980
  }
1965
- async function ensureCodexHooksFeature(homeDir = os6.homedir()) {
1966
- const configPath = path8.join(homeDir, ".codex", "config.toml");
1967
- 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 });
1968
1984
  let content = "";
1969
- if (existsSync9(configPath)) {
1985
+ if (existsSync10(configPath)) {
1970
1986
  content = await readFile4(configPath, "utf-8");
1971
1987
  }
1972
1988
  if (/\[features\][\s\S]*?codex_hooks\s*=\s*true/.test(content)) {
@@ -2021,6 +2037,7 @@ var init_installer2 = __esm({
2021
2037
  init_installer();
2022
2038
  init_preferences();
2023
2039
  init_runtime_hook_manifest();
2040
+ init_mcp_http_config();
2024
2041
  DEFAULT_CODEX_STATUS_LINE = [
2025
2042
  "model-with-reasoning",
2026
2043
  "current-dir",
@@ -2036,44 +2053,44 @@ var init_installer2 = __esm({
2036
2053
 
2037
2054
  // src/bin/install.ts
2038
2055
  init_installer();
2039
- 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";
2040
2057
  import { spawn, execSync as execSync3 } from "child_process";
2041
- import path9 from "path";
2042
- import os7 from "os";
2058
+ import path10 from "path";
2059
+ import os8 from "os";
2043
2060
 
2044
2061
  // src/lib/session-wrappers.ts
2045
2062
  import {
2046
- existsSync as existsSync8,
2047
- readFileSync as readFileSync6,
2048
- writeFileSync as writeFileSync5,
2049
- mkdirSync as mkdirSync4,
2063
+ existsSync as existsSync9,
2064
+ readFileSync as readFileSync7,
2065
+ writeFileSync as writeFileSync6,
2066
+ mkdirSync as mkdirSync5,
2050
2067
  chmodSync as chmodSync3,
2051
2068
  readdirSync,
2052
2069
  unlinkSync as unlinkSync2
2053
2070
  } from "fs";
2054
- import path7 from "path";
2071
+ import path8 from "path";
2055
2072
  import { homedir } from "os";
2056
2073
  var MAX_N = 9;
2057
2074
  function generateSessionWrappers(packageRoot, homeDir) {
2058
2075
  const home = homeDir ?? homedir();
2059
- const binDir = path7.join(home, ".exe-os", "bin");
2060
- const rosterPath = path7.join(home, ".exe-os", "exe-employees.json");
2061
- mkdirSync4(binDir, { recursive: true });
2062
- 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");
2063
2080
  const candidates = [
2064
- path7.join(packageRoot, "dist", "bin", "exe-start.sh"),
2065
- 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")
2066
2083
  ];
2067
2084
  for (const src of candidates) {
2068
- if (existsSync8(src)) {
2069
- writeFileSync5(exeStartDst, readFileSync6(src));
2085
+ if (existsSync9(src)) {
2086
+ writeFileSync6(exeStartDst, readFileSync7(src));
2070
2087
  chmodSync3(exeStartDst, 493);
2071
2088
  break;
2072
2089
  }
2073
2090
  }
2074
2091
  let employees = [];
2075
2092
  try {
2076
- employees = JSON.parse(readFileSync6(rosterPath, "utf8"));
2093
+ employees = JSON.parse(readFileSync7(rosterPath, "utf8"));
2077
2094
  } catch {
2078
2095
  return { created: 0, pathConfigured: false };
2079
2096
  }
@@ -2083,9 +2100,9 @@ function generateSessionWrappers(packageRoot, homeDir) {
2083
2100
  try {
2084
2101
  for (const f of readdirSync(binDir)) {
2085
2102
  if (f === "exe-start") continue;
2086
- const fPath = path7.join(binDir, f);
2103
+ const fPath = path8.join(binDir, f);
2087
2104
  try {
2088
- const content = readFileSync6(fPath, "utf8");
2105
+ const content = readFileSync7(fPath, "utf8");
2089
2106
  if (content.includes("exe-start")) {
2090
2107
  unlinkSync2(fPath);
2091
2108
  }
@@ -2100,34 +2117,34 @@ exec "${exeStartDst}" "$0" "$@"
2100
2117
  `;
2101
2118
  for (const emp of employees) {
2102
2119
  for (let n = 1; n <= MAX_N; n++) {
2103
- const wrapperPath = path7.join(binDir, `${emp.name}${n}`);
2104
- writeFileSync5(wrapperPath, wrapperContent);
2120
+ const wrapperPath = path8.join(binDir, `${emp.name}${n}`);
2121
+ writeFileSync6(wrapperPath, wrapperContent);
2105
2122
  chmodSync3(wrapperPath, 493);
2106
2123
  created++;
2107
- const codexPath = path7.join(binDir, `${emp.name}${n}-codex`);
2108
- writeFileSync5(codexPath, wrapperContent);
2124
+ const codexPath = path8.join(binDir, `${emp.name}${n}-codex`);
2125
+ writeFileSync6(codexPath, wrapperContent);
2109
2126
  chmodSync3(codexPath, 493);
2110
2127
  created++;
2111
2128
  }
2112
2129
  }
2113
2130
  const codexLauncherCandidates = [
2114
- path7.join(packageRoot, "dist", "bin", "exe-start-codex.js"),
2115
- 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")
2116
2133
  ];
2117
2134
  let codexLauncher = null;
2118
2135
  for (const c of codexLauncherCandidates) {
2119
- if (existsSync8(c)) {
2136
+ if (existsSync9(c)) {
2120
2137
  codexLauncher = c;
2121
2138
  break;
2122
2139
  }
2123
2140
  }
2124
2141
  if (codexLauncher) {
2125
2142
  for (const emp of employees) {
2126
- const wrapperPath = path7.join(binDir, `${emp.name}-codex`);
2143
+ const wrapperPath = path8.join(binDir, `${emp.name}-codex`);
2127
2144
  const content = `#!/bin/bash
2128
2145
  exec node "${codexLauncher}" --agent ${emp.name} "$@"
2129
2146
  `;
2130
- writeFileSync5(wrapperPath, content);
2147
+ writeFileSync6(wrapperPath, content);
2131
2148
  chmodSync3(wrapperPath, 493);
2132
2149
  created++;
2133
2150
  }
@@ -2146,24 +2163,24 @@ export PATH="${binDir}:$PATH"
2146
2163
  const shell = process.env.SHELL ?? "/bin/bash";
2147
2164
  const profilePaths = [];
2148
2165
  if (shell.includes("zsh")) {
2149
- profilePaths.push(path7.join(home, ".zshrc"));
2166
+ profilePaths.push(path8.join(home, ".zshrc"));
2150
2167
  } else if (shell.includes("bash")) {
2151
- profilePaths.push(path7.join(home, ".bashrc"));
2152
- profilePaths.push(path7.join(home, ".bash_profile"));
2168
+ profilePaths.push(path8.join(home, ".bashrc"));
2169
+ profilePaths.push(path8.join(home, ".bash_profile"));
2153
2170
  } else {
2154
- profilePaths.push(path7.join(home, ".profile"));
2171
+ profilePaths.push(path8.join(home, ".profile"));
2155
2172
  }
2156
2173
  for (const profilePath of profilePaths) {
2157
2174
  try {
2158
2175
  let content = "";
2159
2176
  try {
2160
- content = readFileSync6(profilePath, "utf8");
2177
+ content = readFileSync7(profilePath, "utf8");
2161
2178
  } catch {
2162
2179
  }
2163
2180
  if (content.includes(".exe-os/bin")) {
2164
2181
  return false;
2165
2182
  }
2166
- writeFileSync5(profilePath, content + exportLine);
2183
+ writeFileSync6(profilePath, content + exportLine);
2167
2184
  return true;
2168
2185
  } catch {
2169
2186
  continue;
@@ -2173,14 +2190,14 @@ export PATH="${binDir}:$PATH"
2173
2190
  }
2174
2191
 
2175
2192
  // src/bin/install.ts
2176
- var homedir2 = os7.homedir;
2177
- var EXE_DIR = path9.join(homedir2(), ".exe-os");
2193
+ var homedir2 = os8.homedir;
2194
+ var EXE_DIR = path10.join(homedir2(), ".exe-os");
2178
2195
  function restartDaemon() {
2179
- const pidPath = path9.join(EXE_DIR, "exed.pid");
2180
- 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");
2181
2198
  try {
2182
- if (existsSync10(pidPath)) {
2183
- const pid = parseInt(readFileSync7(pidPath, "utf8").trim(), 10);
2199
+ if (existsSync11(pidPath)) {
2200
+ const pid = parseInt(readFileSync9(pidPath, "utf8").trim(), 10);
2184
2201
  if (!isNaN(pid) && pid > 0) {
2185
2202
  try {
2186
2203
  process.kill(pid, "SIGKILL");
@@ -2221,18 +2238,18 @@ function restartDaemon() {
2221
2238
  } catch {
2222
2239
  }
2223
2240
  try {
2224
- const versionPath = path9.join(EXE_DIR, "mcp-version");
2225
- writeFileSync6(versionPath, `deploy-${Date.now()}`);
2241
+ const versionPath = path10.join(EXE_DIR, "mcp-version");
2242
+ writeFileSync7(versionPath, `deploy-${Date.now()}`);
2226
2243
  process.stderr.write(`exe-os: MCP version marker updated \u2014 servers will hot-reload within 10s
2227
2244
  `);
2228
2245
  } catch {
2229
2246
  }
2230
2247
  try {
2231
- const wpDir = path9.join(EXE_DIR, "worker-pids");
2232
- if (existsSync10(wpDir)) {
2248
+ const wpDir = path10.join(EXE_DIR, "worker-pids");
2249
+ if (existsSync11(wpDir)) {
2233
2250
  for (const f of readdirSync2(wpDir)) {
2234
2251
  try {
2235
- unlinkSync3(path9.join(wpDir, f));
2252
+ unlinkSync3(path10.join(wpDir, f));
2236
2253
  } catch {
2237
2254
  }
2238
2255
  }
@@ -2249,7 +2266,7 @@ function restartDaemon() {
2249
2266
  }
2250
2267
  } catch {
2251
2268
  }
2252
- const totalGB = os7.totalmem() / (1024 * 1024 * 1024);
2269
+ const totalGB = os8.totalmem() / (1024 * 1024 * 1024);
2253
2270
  if (totalGB <= 8) {
2254
2271
  process.stderr.write(
2255
2272
  `exe-os: ${totalGB.toFixed(0)}GB system \u2014 skipping daemon spawn (keyword search mode)
@@ -2259,13 +2276,13 @@ function restartDaemon() {
2259
2276
  }
2260
2277
  try {
2261
2278
  const pkgRoot = resolvePackageRoot();
2262
- const daemonPath = path9.join(pkgRoot, "dist", "lib", "exe-daemon.js");
2263
- if (!existsSync10(daemonPath)) {
2279
+ const daemonPath = path10.join(pkgRoot, "dist", "lib", "exe-daemon.js");
2280
+ if (!existsSync11(daemonPath)) {
2264
2281
  process.stderr.write(`exe-os: daemon not found at ${daemonPath} \u2014 skipping respawn
2265
2282
  `);
2266
2283
  return;
2267
2284
  }
2268
- const logPath = path9.join(EXE_DIR, "exed.log");
2285
+ const logPath = path10.join(EXE_DIR, "exed.log");
2269
2286
  let stderrFd = "ignore";
2270
2287
  try {
2271
2288
  stderrFd = openSync(logPath, "a");