@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
@@ -127,6 +127,10 @@ var init_config = __esm({
127
127
  checkOnBoot: true,
128
128
  autoInstall: false,
129
129
  checkIntervalMs: 24 * 60 * 60 * 1e3
130
+ },
131
+ orchestration: {
132
+ phase: "phase_1_coo",
133
+ phaseSetBy: "default"
130
134
  }
131
135
  };
132
136
  }
@@ -457,6 +461,9 @@ function getClient() {
457
461
  if (_daemonClient && _daemonClient._isDaemonActive()) {
458
462
  return _daemonClient;
459
463
  }
464
+ if (!_resilientClient) {
465
+ return _adapterClient;
466
+ }
460
467
  return _resilientClient;
461
468
  }
462
469
  var _resilientClient, _daemonClient, _adapterClient;
@@ -1257,6 +1264,63 @@ var init_preferences = __esm({
1257
1264
  }
1258
1265
  });
1259
1266
 
1267
+ // src/adapters/mcp-http-config.ts
1268
+ import { chmodSync as chmodSync3, existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
1269
+ import { randomBytes } from "crypto";
1270
+ import path11 from "path";
1271
+ import os7 from "os";
1272
+ function mcpHttpPort() {
1273
+ return process.env.EXE_MCP_PORT || DEFAULT_MCP_HTTP_PORT;
1274
+ }
1275
+ function mcpHttpUrl() {
1276
+ return `http://127.0.0.1:${mcpHttpPort()}/mcp`;
1277
+ }
1278
+ function readOrCreateDaemonToken(homeDir = os7.homedir()) {
1279
+ const exeDir = path11.join(homeDir, ".exe-os");
1280
+ const tokenPath = path11.join(exeDir, "exed.token");
1281
+ if (existsSync11(tokenPath)) {
1282
+ try {
1283
+ const token2 = readFileSync9(tokenPath, "utf-8").trim();
1284
+ if (/^[a-f0-9]{64}$/i.test(token2)) return token2;
1285
+ } catch {
1286
+ }
1287
+ }
1288
+ const token = randomBytes(32).toString("hex");
1289
+ mkdirSync6(exeDir, { recursive: true });
1290
+ writeFileSync7(tokenPath, `${token}
1291
+ `, "utf-8");
1292
+ try {
1293
+ chmodSync3(tokenPath, 384);
1294
+ } catch {
1295
+ }
1296
+ return token;
1297
+ }
1298
+ function buildMcpHttpHeaders(homeDir = os7.homedir(), opts = {}) {
1299
+ const agentId = opts.useShellPlaceholders ? "${AGENT_ID:-exe}" : opts.agentId ?? DEFAULT_MCP_HTTP_AGENT_ID;
1300
+ const agentRole = opts.useShellPlaceholders ? "${AGENT_ROLE:-COO}" : opts.agentRole ?? DEFAULT_MCP_HTTP_AGENT_ROLE;
1301
+ return {
1302
+ Authorization: `Bearer ${readOrCreateDaemonToken(homeDir)}`,
1303
+ "X-Agent-Id": agentId,
1304
+ "X-Agent-Role": agentRole
1305
+ };
1306
+ }
1307
+ function buildClaudeHttpMcpEntry(homeDir = os7.homedir()) {
1308
+ return {
1309
+ type: "http",
1310
+ url: mcpHttpUrl(),
1311
+ headers: buildMcpHttpHeaders(homeDir, { useShellPlaceholders: true })
1312
+ };
1313
+ }
1314
+ var DEFAULT_MCP_HTTP_PORT, DEFAULT_MCP_HTTP_AGENT_ID, DEFAULT_MCP_HTTP_AGENT_ROLE;
1315
+ var init_mcp_http_config = __esm({
1316
+ "src/adapters/mcp-http-config.ts"() {
1317
+ "use strict";
1318
+ DEFAULT_MCP_HTTP_PORT = "48739";
1319
+ DEFAULT_MCP_HTTP_AGENT_ID = "exe";
1320
+ DEFAULT_MCP_HTTP_AGENT_ROLE = "COO";
1321
+ }
1322
+ });
1323
+
1260
1324
  // src/adapters/runtime-hook-manifest.ts
1261
1325
  function commandHasAnyMarker(command, markers) {
1262
1326
  return markers.some((marker) => command.includes(marker));
@@ -1264,7 +1328,7 @@ function commandHasAnyMarker(command, markers) {
1264
1328
  function isLegacySplitPostToolCommand(command) {
1265
1329
  return commandHasAnyMarker(command, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS);
1266
1330
  }
1267
- var EXE_HOOKS, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
1331
+ var EXE_HOOKS, EXE_HOOK_MANIFEST, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
1268
1332
  var init_runtime_hook_manifest = __esm({
1269
1333
  "src/adapters/runtime-hook-manifest.ts"() {
1270
1334
  "use strict";
@@ -1282,6 +1346,116 @@ var init_runtime_hook_manifest = __esm({
1282
1346
  notification: "dist/hooks/notification.js",
1283
1347
  instructionsLoaded: "dist/hooks/instructions-loaded.js"
1284
1348
  };
1349
+ EXE_HOOK_MANIFEST = [
1350
+ {
1351
+ key: "postToolCombined",
1352
+ event: "PostToolUse",
1353
+ commandMarker: EXE_HOOKS.postToolCombined,
1354
+ owner: "exe-os",
1355
+ purpose: "Single PostToolUse entrypoint for ingestion, error recall, summaries, and bug detection.",
1356
+ runtimes: ["claude", "codex", "opencode"],
1357
+ checkpointRole: "none"
1358
+ },
1359
+ {
1360
+ key: "sessionStart",
1361
+ event: "SessionStart",
1362
+ commandMarker: EXE_HOOKS.sessionStart,
1363
+ owner: "exe-os",
1364
+ purpose: "Loads agent identity, procedures, and boot context.",
1365
+ runtimes: ["claude", "codex", "opencode"],
1366
+ checkpointRole: "none"
1367
+ },
1368
+ {
1369
+ key: "promptSubmit",
1370
+ event: "UserPromptSubmit",
1371
+ commandMarker: EXE_HOOKS.promptSubmit,
1372
+ owner: "exe-os",
1373
+ purpose: "Injects current tasks, pending reviews, and local context before each prompt.",
1374
+ runtimes: ["claude", "codex", "opencode"],
1375
+ checkpointRole: "none"
1376
+ },
1377
+ {
1378
+ key: "heartbeat",
1379
+ event: "UserPromptSubmit",
1380
+ commandMarker: EXE_HOOKS.heartbeat,
1381
+ owner: "exe-os",
1382
+ purpose: "Lightweight heartbeat/status sidecar for Claude Code sessions.",
1383
+ runtimes: ["claude"],
1384
+ checkpointRole: "none"
1385
+ },
1386
+ {
1387
+ key: "stop",
1388
+ event: "Stop",
1389
+ commandMarker: EXE_HOOKS.stop,
1390
+ owner: "exe-os",
1391
+ purpose: "Finalizes task state, capacity signals, and emergency checkpointing.",
1392
+ runtimes: ["claude", "codex", "opencode"],
1393
+ checkpointRole: "capacity_checkpoint"
1394
+ },
1395
+ {
1396
+ key: "preToolUse",
1397
+ event: "PreToolUse",
1398
+ commandMarker: EXE_HOOKS.preToolUse,
1399
+ owner: "exe-os",
1400
+ purpose: "Preflight guardrails before shell/tool execution.",
1401
+ runtimes: ["claude", "codex", "opencode"],
1402
+ checkpointRole: "none"
1403
+ },
1404
+ {
1405
+ key: "subagentStop",
1406
+ event: "SubagentStop",
1407
+ commandMarker: EXE_HOOKS.subagentStop,
1408
+ owner: "exe-os",
1409
+ purpose: "Captures subagent completion context.",
1410
+ runtimes: ["claude"],
1411
+ checkpointRole: "none"
1412
+ },
1413
+ {
1414
+ key: "preCompact",
1415
+ event: "PreCompact",
1416
+ commandMarker: EXE_HOOKS.preCompact,
1417
+ owner: "exe-os",
1418
+ purpose: "Writes active-task snapshot and compaction recovery context.",
1419
+ runtimes: ["claude"],
1420
+ checkpointRole: "recovery_context"
1421
+ },
1422
+ {
1423
+ key: "postCompact",
1424
+ event: "PostCompact",
1425
+ commandMarker: EXE_HOOKS.postCompact,
1426
+ owner: "exe-os",
1427
+ purpose: "Rehydrates recovery context after compaction.",
1428
+ runtimes: ["claude"],
1429
+ checkpointRole: "recovery_context"
1430
+ },
1431
+ {
1432
+ key: "sessionEnd",
1433
+ event: "SessionEnd",
1434
+ commandMarker: EXE_HOOKS.sessionEnd,
1435
+ owner: "exe-os",
1436
+ purpose: "Stores session-end checkpoint and triages orphaned in-progress tasks.",
1437
+ runtimes: ["claude"],
1438
+ checkpointRole: "session_summary"
1439
+ },
1440
+ {
1441
+ key: "notification",
1442
+ event: "Notification",
1443
+ commandMarker: EXE_HOOKS.notification,
1444
+ owner: "exe-os",
1445
+ purpose: "Captures runtime notifications and nudges.",
1446
+ runtimes: ["claude"],
1447
+ checkpointRole: "none"
1448
+ },
1449
+ {
1450
+ key: "instructionsLoaded",
1451
+ event: "InstructionsLoaded",
1452
+ commandMarker: EXE_HOOKS.instructionsLoaded,
1453
+ owner: "exe-os",
1454
+ purpose: "Applies runtime instruction post-processing.",
1455
+ runtimes: ["claude"],
1456
+ checkpointRole: "none"
1457
+ }
1458
+ ];
1285
1459
  LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS = [
1286
1460
  "dist/hooks/ingest.js",
1287
1461
  "dist/hooks/error-recall.js",
@@ -1304,54 +1478,58 @@ __export(installer_exports, {
1304
1478
  setupGhostty: () => setupGhostty,
1305
1479
  setupTmux: () => setupTmux
1306
1480
  });
1307
- import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
1308
- import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7, copyFileSync, mkdirSync as mkdirSync6, chmodSync as chmodSync3 } from "fs";
1309
- import { createHash as createHash2, randomBytes } from "crypto";
1310
- import path11 from "path";
1311
- import os7 from "os";
1481
+ import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir, rm } from "fs/promises";
1482
+ import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync8, copyFileSync, mkdirSync as mkdirSync7 } from "fs";
1483
+ import { createHash as createHash2 } from "crypto";
1484
+ import path12 from "path";
1485
+ import os8 from "os";
1312
1486
  import { execSync as execSync2 } from "child_process";
1313
1487
  import { fileURLToPath as fileURLToPath2 } from "url";
1314
1488
  function resolvePackageRoot() {
1315
1489
  const thisFile = fileURLToPath2(import.meta.url);
1316
- let dir = path11.dirname(thisFile);
1317
- const root = path11.parse(dir).root;
1490
+ let dir = path12.dirname(thisFile);
1491
+ const root = path12.parse(dir).root;
1318
1492
  while (dir !== root) {
1319
- const pkgPath = path11.join(dir, "package.json");
1320
- if (existsSync11(pkgPath)) {
1493
+ const pkgPath = path12.join(dir, "package.json");
1494
+ if (existsSync12(pkgPath)) {
1321
1495
  try {
1322
- const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
1496
+ const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
1323
1497
  if (pkg.name === "@askexenow/exe-os" || pkg.name === "exe-os") return dir;
1324
1498
  } catch {
1325
1499
  }
1326
1500
  }
1327
- dir = path11.dirname(dir);
1501
+ dir = path12.dirname(dir);
1328
1502
  }
1329
- return path11.resolve(path11.dirname(thisFile), "..", "..", "..");
1503
+ return path12.resolve(path12.dirname(thisFile), "..", "..", "..");
1330
1504
  }
1331
- async function copySlashCommands(packageRoot, homeDir = os7.homedir()) {
1505
+ async function copySlashCommands(packageRoot, homeDir = os8.homedir()) {
1332
1506
  let copied = 0;
1333
1507
  let skipped = 0;
1334
- const skillsBase = path11.join(homeDir, ".claude", "skills");
1335
- const exeDir = path11.join(packageRoot, "src", "commands", "exe");
1336
- if (existsSync11(exeDir)) {
1508
+ const skillsBase = path12.join(homeDir, ".claude", "skills");
1509
+ const deprecatedExeLink = path12.join(skillsBase, "exe-link");
1510
+ if (existsSync12(deprecatedExeLink)) {
1511
+ await rm(deprecatedExeLink, { recursive: true, force: true });
1512
+ }
1513
+ const exeDir = path12.join(packageRoot, "src", "commands", "exe");
1514
+ if (existsSync12(exeDir)) {
1337
1515
  const entries = await readdir(exeDir);
1338
1516
  const mdFiles = entries.filter((f) => f.endsWith(".md"));
1339
1517
  for (const file of mdFiles) {
1340
1518
  const name = file.replace(".md", "");
1341
- const destDir = path11.join(skillsBase, `exe-${name}`);
1519
+ const destDir = path12.join(skillsBase, `exe-${name}`);
1342
1520
  await mkdir3(destDir, { recursive: true });
1343
- const srcPath = path11.join(exeDir, file);
1344
- const destPath = path11.join(destDir, "SKILL.md");
1521
+ const srcPath = path12.join(exeDir, file);
1522
+ const destPath = path12.join(destDir, "SKILL.md");
1345
1523
  const result = await copyAsSkill(srcPath, destPath, `exe-${name}`);
1346
1524
  if (result) copied++;
1347
1525
  else skipped++;
1348
1526
  }
1349
1527
  }
1350
- const topLevelSrc = path11.join(packageRoot, "src", "commands", "exe.md");
1351
- if (existsSync11(topLevelSrc)) {
1352
- const destDir = path11.join(skillsBase, "exe");
1528
+ const topLevelSrc = path12.join(packageRoot, "src", "commands", "exe.md");
1529
+ if (existsSync12(topLevelSrc)) {
1530
+ const destDir = path12.join(skillsBase, "exe");
1353
1531
  await mkdir3(destDir, { recursive: true });
1354
- const destPath = path11.join(destDir, "SKILL.md");
1532
+ const destPath = path12.join(destDir, "SKILL.md");
1355
1533
  const result = await copyAsSkill(topLevelSrc, destPath, "exe");
1356
1534
  if (result) copied++;
1357
1535
  else skipped++;
@@ -1374,7 +1552,7 @@ name: ${skillName}
1374
1552
  `);
1375
1553
  }
1376
1554
  }
1377
- if (existsSync11(destPath)) {
1555
+ if (existsSync12(destPath)) {
1378
1556
  const existing = await readFile3(destPath, "utf-8");
1379
1557
  if (existing === content) return false;
1380
1558
  }
@@ -1383,32 +1561,32 @@ name: ${skillName}
1383
1561
  }
1384
1562
  function readJsonFile(filePath) {
1385
1563
  try {
1386
- return JSON.parse(readFileSync9(filePath, "utf-8"));
1564
+ return JSON.parse(readFileSync10(filePath, "utf-8"));
1387
1565
  } catch {
1388
1566
  return null;
1389
1567
  }
1390
1568
  }
1391
1569
  function findAncestorMcpJsons(startDir, homeDir) {
1392
1570
  const files = [];
1393
- let dir = path11.resolve(startDir);
1394
- const root = path11.parse(dir).root;
1395
- const stop = path11.resolve(homeDir);
1571
+ let dir = path12.resolve(startDir);
1572
+ const root = path12.parse(dir).root;
1573
+ const stop = path12.resolve(homeDir);
1396
1574
  while (dir !== root) {
1397
- const candidate = path11.join(dir, ".mcp.json");
1398
- if (existsSync11(candidate)) files.push(candidate);
1575
+ const candidate = path12.join(dir, ".mcp.json");
1576
+ if (existsSync12(candidate)) files.push(candidate);
1399
1577
  if (dir === stop) break;
1400
- dir = path11.dirname(dir);
1578
+ dir = path12.dirname(dir);
1401
1579
  }
1402
1580
  return files;
1403
1581
  }
1404
1582
  function pathApplies(projectPath, cwd) {
1405
- const project = path11.resolve(projectPath);
1406
- const current = path11.resolve(cwd);
1407
- return current === project || current.startsWith(project + path11.sep);
1583
+ const project = path12.resolve(projectPath);
1584
+ const current = path12.resolve(cwd);
1585
+ return current === project || current.startsWith(project + path12.sep);
1408
1586
  }
1409
- function detectMcpNameCollisions(homeDir = os7.homedir(), cwd = process.cwd()) {
1410
- const claudeJsonPath = path11.join(homeDir, ".claude.json");
1411
- if (!existsSync11(claudeJsonPath)) return [];
1587
+ function detectMcpNameCollisions(homeDir = os8.homedir(), cwd = process.cwd()) {
1588
+ const claudeJsonPath = path12.join(homeDir, ".claude.json");
1589
+ if (!existsSync12(claudeJsonPath)) return [];
1412
1590
  const claudeJson = readJsonFile(claudeJsonPath);
1413
1591
  if (!claudeJson?.projects) return [];
1414
1592
  const collisions = [];
@@ -1435,44 +1613,11 @@ function detectMcpNameCollisions(homeDir = os7.homedir(), cwd = process.cwd()) {
1435
1613
  }
1436
1614
  return collisions;
1437
1615
  }
1438
- function readOrCreateDaemonToken(homeDir) {
1439
- const exeDir = path11.join(homeDir, ".exe-os");
1440
- const tokenPath = path11.join(exeDir, "exed.token");
1441
- try {
1442
- if (existsSync11(tokenPath)) {
1443
- const token2 = readFileSync9(tokenPath, "utf-8").trim();
1444
- if (token2) return token2;
1445
- }
1446
- } catch {
1447
- }
1448
- const token = randomBytes(32).toString("hex");
1449
- mkdirSync6(exeDir, { recursive: true });
1450
- writeFileSync7(tokenPath, `${token}
1451
- `, "utf-8");
1452
- try {
1453
- chmodSync3(tokenPath, 384);
1454
- } catch {
1455
- }
1456
- return token;
1457
- }
1458
- function buildHttpMcpEntry(homeDir) {
1459
- const port = process.env.EXE_MCP_PORT || "48739";
1460
- const token = readOrCreateDaemonToken(homeDir);
1461
- return {
1462
- type: "http",
1463
- url: `http://127.0.0.1:${port}/mcp`,
1464
- headers: {
1465
- Authorization: `Bearer ${token}`,
1466
- "X-Agent-Id": "${AGENT_ID:-exe}",
1467
- "X-Agent-Role": "${AGENT_ROLE:-COO}"
1468
- }
1469
- };
1470
- }
1471
1616
  function buildStdioMcpEntry(packageRoot) {
1472
1617
  return {
1473
1618
  type: "stdio",
1474
1619
  command: "node",
1475
- args: [path11.join(packageRoot, "dist", "mcp", "server.js")],
1620
+ args: [path12.join(packageRoot, "dist", "mcp", "server.js")],
1476
1621
  env: {}
1477
1622
  };
1478
1623
  }
@@ -1480,14 +1625,14 @@ function mcpTransportMode() {
1480
1625
  const value = process.env.EXE_OS_MCP_TRANSPORT?.trim().toLowerCase();
1481
1626
  if (value === "stdio") return "stdio";
1482
1627
  if (value === "http") return "http";
1483
- const totalGB = os7.totalmem() / (1024 * 1024 * 1024);
1628
+ const totalGB = os8.totalmem() / (1024 * 1024 * 1024);
1484
1629
  if (totalGB <= 8) return "stdio";
1485
1630
  return "http";
1486
1631
  }
1487
- async function registerMcpServer(packageRoot, homeDir = os7.homedir()) {
1488
- const claudeJsonPath = path11.join(homeDir, ".claude.json");
1632
+ async function registerMcpServer(packageRoot, homeDir = os8.homedir()) {
1633
+ const claudeJsonPath = path12.join(homeDir, ".claude.json");
1489
1634
  let claudeJson = {};
1490
- if (existsSync11(claudeJsonPath)) {
1635
+ if (existsSync12(claudeJsonPath)) {
1491
1636
  try {
1492
1637
  claudeJson = JSON.parse(await readFile3(claudeJsonPath, "utf-8"));
1493
1638
  } catch {
@@ -1497,7 +1642,7 @@ async function registerMcpServer(packageRoot, homeDir = os7.homedir()) {
1497
1642
  if (!claudeJson.mcpServers) {
1498
1643
  claudeJson.mcpServers = {};
1499
1644
  }
1500
- const newEntry = mcpTransportMode() === "stdio" ? buildStdioMcpEntry(packageRoot) : buildHttpMcpEntry(homeDir);
1645
+ const newEntry = mcpTransportMode() === "stdio" ? buildStdioMcpEntry(packageRoot) : buildClaudeHttpMcpEntry(homeDir);
1501
1646
  if (claudeJson.mcpServers[MCP_LEGACY_KEY]) {
1502
1647
  delete claudeJson.mcpServers[MCP_LEGACY_KEY];
1503
1648
  process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
@@ -1505,8 +1650,8 @@ async function registerMcpServer(packageRoot, homeDir = os7.homedir()) {
1505
1650
  const currentOs = claudeJson.mcpServers[MCP_PRIMARY_KEY];
1506
1651
  const osMatches = currentOs && JSON.stringify(currentOs) === JSON.stringify(newEntry);
1507
1652
  if (osMatches) {
1508
- await cleanSettingsJsonMcp(path11.join(homeDir, ".claude", "settings.json"));
1509
- await migratePermissionsToExeOs(path11.join(homeDir, ".claude", "settings.json"));
1653
+ await cleanSettingsJsonMcp(path12.join(homeDir, ".claude", "settings.json"));
1654
+ await migratePermissionsToExeOs(path12.join(homeDir, ".claude", "settings.json"));
1510
1655
  const collisions2 = detectMcpNameCollisions(homeDir, packageRoot).filter((c) => c.serverName === MCP_PRIMARY_KEY || c.serverName === MCP_LEGACY_KEY);
1511
1656
  for (const c of collisions2) {
1512
1657
  process.stderr.write(
@@ -1518,8 +1663,8 @@ async function registerMcpServer(packageRoot, homeDir = os7.homedir()) {
1518
1663
  }
1519
1664
  claudeJson.mcpServers[MCP_PRIMARY_KEY] = newEntry;
1520
1665
  await writeFile3(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
1521
- await cleanSettingsJsonMcp(path11.join(homeDir, ".claude", "settings.json"));
1522
- await migratePermissionsToExeOs(path11.join(homeDir, ".claude", "settings.json"));
1666
+ await cleanSettingsJsonMcp(path12.join(homeDir, ".claude", "settings.json"));
1667
+ await migratePermissionsToExeOs(path12.join(homeDir, ".claude", "settings.json"));
1523
1668
  const collisions = detectMcpNameCollisions(homeDir, packageRoot).filter((c) => c.serverName === MCP_PRIMARY_KEY || c.serverName === MCP_LEGACY_KEY);
1524
1669
  for (const c of collisions) {
1525
1670
  process.stderr.write(
@@ -1530,7 +1675,7 @@ async function registerMcpServer(packageRoot, homeDir = os7.homedir()) {
1530
1675
  return true;
1531
1676
  }
1532
1677
  async function cleanSettingsJsonMcp(settingsPath) {
1533
- if (!existsSync11(settingsPath)) return;
1678
+ if (!existsSync12(settingsPath)) return;
1534
1679
  try {
1535
1680
  const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1536
1681
  const servers = settings.mcpServers;
@@ -1551,7 +1696,7 @@ async function cleanSettingsJsonMcp(settingsPath) {
1551
1696
  }
1552
1697
  }
1553
1698
  async function migratePermissionsToExeOs(settingsPath) {
1554
- if (!existsSync11(settingsPath)) return;
1699
+ if (!existsSync12(settingsPath)) return;
1555
1700
  try {
1556
1701
  const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1557
1702
  const permissions = settings.permissions;
@@ -1579,14 +1724,14 @@ async function migratePermissionsToExeOs(settingsPath) {
1579
1724
  } catch {
1580
1725
  }
1581
1726
  }
1582
- async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1583
- const settingsPath = path11.join(homeDir, ".claude", "settings.json");
1584
- const logsDir = path11.join(homeDir, ".exe-os", "logs");
1585
- const hookLogPath = path11.join(logsDir, "hooks.log");
1727
+ async function mergeHooks(packageRoot, homeDir = os8.homedir()) {
1728
+ const settingsPath = path12.join(homeDir, ".claude", "settings.json");
1729
+ const logsDir = path12.join(homeDir, ".exe-os", "logs");
1730
+ const hookLogPath = path12.join(logsDir, "hooks.log");
1586
1731
  const logSuffix = ` 2>> "${hookLogPath}"`;
1587
1732
  await mkdir3(logsDir, { recursive: true });
1588
1733
  let settings = {};
1589
- if (existsSync11(settingsPath)) {
1734
+ if (existsSync12(settingsPath)) {
1590
1735
  try {
1591
1736
  settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1592
1737
  } catch {
@@ -1608,7 +1753,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1608
1753
  hooks: [
1609
1754
  {
1610
1755
  type: "command",
1611
- command: `node "${path11.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
1756
+ command: `node "${path12.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
1612
1757
  }
1613
1758
  ]
1614
1759
  },
@@ -1620,7 +1765,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1620
1765
  hooks: [
1621
1766
  {
1622
1767
  type: "command",
1623
- command: `node "${path11.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
1768
+ command: `node "${path12.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
1624
1769
  timeout: 1e4
1625
1770
  }
1626
1771
  ]
@@ -1633,7 +1778,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1633
1778
  hooks: [
1634
1779
  {
1635
1780
  type: "command",
1636
- command: `node "${path11.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
1781
+ command: `node "${path12.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
1637
1782
  }
1638
1783
  ]
1639
1784
  },
@@ -1645,7 +1790,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1645
1790
  hooks: [
1646
1791
  {
1647
1792
  type: "command",
1648
- command: `node "${path11.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
1793
+ command: `node "${path12.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
1649
1794
  timeout: 5e3
1650
1795
  }
1651
1796
  ]
@@ -1658,7 +1803,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1658
1803
  hooks: [
1659
1804
  {
1660
1805
  type: "command",
1661
- command: `node "${path11.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
1806
+ command: `node "${path12.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
1662
1807
  }
1663
1808
  ]
1664
1809
  },
@@ -1671,7 +1816,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1671
1816
  hooks: [
1672
1817
  {
1673
1818
  type: "command",
1674
- command: `node "${path11.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
1819
+ command: `node "${path12.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
1675
1820
  }
1676
1821
  ]
1677
1822
  },
@@ -1683,7 +1828,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1683
1828
  hooks: [
1684
1829
  {
1685
1830
  type: "command",
1686
- command: `node "${path11.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
1831
+ command: `node "${path12.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
1687
1832
  }
1688
1833
  ]
1689
1834
  },
@@ -1695,7 +1840,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1695
1840
  hooks: [
1696
1841
  {
1697
1842
  type: "command",
1698
- command: `node "${path11.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
1843
+ command: `node "${path12.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
1699
1844
  timeout: 1e4
1700
1845
  }
1701
1846
  ]
@@ -1708,7 +1853,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1708
1853
  hooks: [
1709
1854
  {
1710
1855
  type: "command",
1711
- command: `node "${path11.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
1856
+ command: `node "${path12.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
1712
1857
  }
1713
1858
  ]
1714
1859
  },
@@ -1720,7 +1865,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1720
1865
  hooks: [
1721
1866
  {
1722
1867
  type: "command",
1723
- command: `node "${path11.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
1868
+ command: `node "${path12.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
1724
1869
  }
1725
1870
  ]
1726
1871
  },
@@ -1732,7 +1877,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1732
1877
  hooks: [
1733
1878
  {
1734
1879
  type: "command",
1735
- command: `node "${path11.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
1880
+ command: `node "${path12.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
1736
1881
  timeout: 1e4
1737
1882
  }
1738
1883
  ]
@@ -1745,7 +1890,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1745
1890
  hooks: [
1746
1891
  {
1747
1892
  type: "command",
1748
- command: `node "${path11.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
1893
+ command: `node "${path12.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
1749
1894
  }
1750
1895
  ]
1751
1896
  },
@@ -1850,13 +1995,13 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1850
1995
  allowList.push(fullName);
1851
1996
  }
1852
1997
  }
1853
- await mkdir3(path11.dirname(settingsPath), { recursive: true });
1998
+ await mkdir3(path12.dirname(settingsPath), { recursive: true });
1854
1999
  await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
1855
2000
  return { added, skipped };
1856
2001
  }
1857
- async function cleanOldShellFunctions(homeDir = os7.homedir()) {
1858
- const rosterPath = path11.join(homeDir, ".exe-os", "exe-employees.json");
1859
- if (!existsSync11(rosterPath)) return 0;
2002
+ async function cleanOldShellFunctions(homeDir = os8.homedir()) {
2003
+ const rosterPath = path12.join(homeDir, ".exe-os", "exe-employees.json");
2004
+ if (!existsSync12(rosterPath)) return 0;
1860
2005
  let employees;
1861
2006
  try {
1862
2007
  employees = JSON.parse(await readFile3(rosterPath, "utf-8"));
@@ -1871,13 +2016,13 @@ async function cleanOldShellFunctions(homeDir = os7.homedir()) {
1871
2016
  return { name: n, funcDef, forLoop };
1872
2017
  });
1873
2018
  const rcFiles = [
1874
- path11.join(homeDir, ".zshrc"),
1875
- path11.join(homeDir, ".bashrc")
2019
+ path12.join(homeDir, ".zshrc"),
2020
+ path12.join(homeDir, ".bashrc")
1876
2021
  ];
1877
2022
  const REMOVED_MARKER = "# Removed by exe-os \u2014 wrappers now at ~/.exe-os/bin/";
1878
2023
  let totalRemoved = 0;
1879
2024
  for (const rcPath of rcFiles) {
1880
- if (!existsSync11(rcPath)) continue;
2025
+ if (!existsSync12(rcPath)) continue;
1881
2026
  let content;
1882
2027
  try {
1883
2028
  content = await readFile3(rcPath, "utf-8");
@@ -1981,8 +2126,8 @@ function escapeRegExp(s) {
1981
2126
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1982
2127
  }
1983
2128
  async function injectOrchestrationRules(homeDir) {
1984
- const claudeDir = path11.join(homeDir, ".claude");
1985
- const claudeMdPath = path11.join(claudeDir, "CLAUDE.md");
2129
+ const claudeDir = path12.join(homeDir, ".claude");
2130
+ const claudeMdPath = path12.join(claudeDir, "CLAUDE.md");
1986
2131
  await mkdir3(claudeDir, { recursive: true });
1987
2132
  let existing = "";
1988
2133
  try {
@@ -2004,19 +2149,19 @@ async function injectOrchestrationRules(homeDir) {
2004
2149
  await writeFile3(claudeMdPath, existing + separator + ORCHESTRATION_RULES + "\n", "utf-8");
2005
2150
  return "injected";
2006
2151
  }
2007
- async function installStatusLine(packageRoot, homeDir = os7.homedir()) {
2152
+ async function installStatusLine(packageRoot, homeDir = os8.homedir()) {
2008
2153
  const prefs = loadPreferences(homeDir);
2009
2154
  if (prefs.ccStatusLine === false) return "opted-out";
2010
- const claudeDir = path11.join(homeDir, ".claude");
2155
+ const claudeDir = path12.join(homeDir, ".claude");
2011
2156
  await mkdir3(claudeDir, { recursive: true });
2012
- const assetPath = path11.join(packageRoot, "dist", "assets", "statusline-command.sh");
2013
- if (!existsSync11(assetPath)) return "asset-missing";
2014
- const destScript = path11.join(claudeDir, "statusline-command.sh");
2157
+ const assetPath = path12.join(packageRoot, "dist", "assets", "statusline-command.sh");
2158
+ if (!existsSync12(assetPath)) return "asset-missing";
2159
+ const destScript = path12.join(claudeDir, "statusline-command.sh");
2015
2160
  const assetContent = await readFile3(assetPath, "utf-8");
2016
2161
  await writeFile3(destScript, assetContent, { mode: 493 });
2017
- const settingsPath = path11.join(claudeDir, "settings.json");
2162
+ const settingsPath = path12.join(claudeDir, "settings.json");
2018
2163
  let settings = {};
2019
- if (existsSync11(settingsPath)) {
2164
+ if (existsSync12(settingsPath)) {
2020
2165
  try {
2021
2166
  settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
2022
2167
  } catch {
@@ -2053,13 +2198,13 @@ async function runInstaller(homeDir) {
2053
2198
  `Hooks: ${hookResult.added} added, ${hookResult.skipped} unchanged
2054
2199
  `
2055
2200
  );
2056
- const resolvedHome = homeDir ?? os7.homedir();
2057
- const exeWorkspace = path11.join(resolvedHome, "exe");
2058
- if (!existsSync11(exeWorkspace)) {
2201
+ const resolvedHome = homeDir ?? os8.homedir();
2202
+ const exeWorkspace = path12.join(resolvedHome, "exe");
2203
+ if (!existsSync12(exeWorkspace)) {
2059
2204
  try {
2060
- await mkdir3(path11.join(exeWorkspace, "content"), { recursive: true });
2061
- await mkdir3(path11.join(exeWorkspace, "operations"), { recursive: true });
2062
- await mkdir3(path11.join(exeWorkspace, "output"), { recursive: true });
2205
+ await mkdir3(path12.join(exeWorkspace, "content"), { recursive: true });
2206
+ await mkdir3(path12.join(exeWorkspace, "operations"), { recursive: true });
2207
+ await mkdir3(path12.join(exeWorkspace, "output"), { recursive: true });
2063
2208
  process.stderr.write(
2064
2209
  `Created ~/exe/ \u2014 your automation workspace for non-code projects
2065
2210
  `
@@ -2094,57 +2239,57 @@ exe-os installed successfully.
2094
2239
  `);
2095
2240
  }
2096
2241
  function setupTmux(home) {
2097
- const homeDir = home ?? os7.homedir();
2098
- const exeDir = path11.join(homeDir, ".exe-os");
2099
- const exeTmuxConf = path11.join(exeDir, "tmux.conf");
2100
- const userTmuxConf = path11.join(homeDir, ".tmux.conf");
2101
- const backupPath = path11.join(homeDir, ".tmux.conf.backup");
2242
+ const homeDir = home ?? os8.homedir();
2243
+ const exeDir = path12.join(homeDir, ".exe-os");
2244
+ const exeTmuxConf = path12.join(exeDir, "tmux.conf");
2245
+ const userTmuxConf = path12.join(homeDir, ".tmux.conf");
2246
+ const backupPath = path12.join(homeDir, ".tmux.conf.backup");
2102
2247
  const sourceLine = "source-file ~/.exe-os/tmux.conf";
2103
2248
  const pkgRoot = resolvePackageRoot();
2104
- const assetPath = path11.join(pkgRoot, "dist", "assets", "tmux.conf");
2105
- if (!existsSync11(assetPath)) {
2249
+ const assetPath = path12.join(pkgRoot, "dist", "assets", "tmux.conf");
2250
+ if (!existsSync12(assetPath)) {
2106
2251
  process.stderr.write(`exe-os: tmux.conf asset not found at ${assetPath} \u2014 skipping tmux setup
2107
2252
  `);
2108
2253
  return;
2109
2254
  }
2110
- mkdirSync6(exeDir, { recursive: true });
2111
- if (existsSync11(exeTmuxConf)) {
2112
- const currentContent = readFileSync9(exeTmuxConf, "utf8");
2113
- const newContent = readFileSync9(assetPath, "utf8");
2255
+ mkdirSync7(exeDir, { recursive: true });
2256
+ if (existsSync12(exeTmuxConf)) {
2257
+ const currentContent = readFileSync10(exeTmuxConf, "utf8");
2258
+ const newContent = readFileSync10(assetPath, "utf8");
2114
2259
  const currentHash = createHash2("sha256").update(currentContent).digest("hex");
2115
2260
  const newHash = createHash2("sha256").update(newContent).digest("hex");
2116
2261
  if (currentHash !== newHash) {
2117
- const shippedPath = path11.join(exeDir, ".tmux.conf.shipped-hash");
2118
- const lastShippedHash = existsSync11(shippedPath) ? readFileSync9(shippedPath, "utf8").trim() : "";
2262
+ const shippedPath = path12.join(exeDir, ".tmux.conf.shipped-hash");
2263
+ const lastShippedHash = existsSync12(shippedPath) ? readFileSync10(shippedPath, "utf8").trim() : "";
2119
2264
  if (lastShippedHash && currentHash !== lastShippedHash) {
2120
2265
  process.stderr.write("exe-os: tmux config has user customizations \u2014 skipping overwrite\n");
2121
2266
  } else {
2122
2267
  copyFileSync(assetPath, exeTmuxConf);
2123
2268
  process.stderr.write("exe-os: tmux config updated\n");
2124
2269
  }
2125
- writeFileSync7(shippedPath, newHash, "utf8");
2270
+ writeFileSync8(shippedPath, newHash, "utf8");
2126
2271
  } else {
2127
2272
  process.stderr.write("exe-os: tmux config already up to date\n");
2128
2273
  }
2129
2274
  } else {
2130
2275
  copyFileSync(assetPath, exeTmuxConf);
2131
- const newContent = readFileSync9(assetPath, "utf8");
2276
+ const newContent = readFileSync10(assetPath, "utf8");
2132
2277
  const newHash = createHash2("sha256").update(newContent).digest("hex");
2133
- writeFileSync7(path11.join(exeDir, ".tmux.conf.shipped-hash"), newHash, "utf8");
2278
+ writeFileSync8(path12.join(exeDir, ".tmux.conf.shipped-hash"), newHash, "utf8");
2134
2279
  }
2135
- if (existsSync11(userTmuxConf)) {
2136
- const existing = readFileSync9(userTmuxConf, "utf8");
2280
+ if (existsSync12(userTmuxConf)) {
2281
+ const existing = readFileSync10(userTmuxConf, "utf8");
2137
2282
  if (!existing.includes(sourceLine)) {
2138
- if (!existsSync11(backupPath)) {
2283
+ if (!existsSync12(backupPath)) {
2139
2284
  copyFileSync(userTmuxConf, backupPath);
2140
2285
  process.stderr.write(`exe-os: backed up existing tmux config to ${backupPath}
2141
2286
  `);
2142
2287
  }
2143
- writeFileSync7(userTmuxConf, `${sourceLine}
2288
+ writeFileSync8(userTmuxConf, `${sourceLine}
2144
2289
  ${existing}`);
2145
2290
  }
2146
2291
  } else {
2147
- writeFileSync7(userTmuxConf, `# Exe OS tmux defaults \u2014 remove this line to use your own config
2292
+ writeFileSync8(userTmuxConf, `# Exe OS tmux defaults \u2014 remove this line to use your own config
2148
2293
  ${sourceLine}
2149
2294
  `);
2150
2295
  }
@@ -2155,10 +2300,10 @@ ${sourceLine}
2155
2300
  process.stderr.write("exe-os: tmux config installed\n");
2156
2301
  }
2157
2302
  function setupGhostty(home) {
2158
- const homeDir = home ?? os7.homedir();
2159
- const xdgConfig = path11.join(homeDir, ".config", "ghostty");
2160
- const macConfig = path11.join(homeDir, "Library", "Application Support", "com.mitchellh.ghostty");
2161
- const ghosttyInstalled = existsSync11(xdgConfig) || existsSync11(macConfig) || (() => {
2303
+ const homeDir = home ?? os8.homedir();
2304
+ const xdgConfig = path12.join(homeDir, ".config", "ghostty");
2305
+ const macConfig = path12.join(homeDir, "Library", "Application Support", "com.mitchellh.ghostty");
2306
+ const ghosttyInstalled = existsSync12(xdgConfig) || existsSync12(macConfig) || (() => {
2162
2307
  try {
2163
2308
  execSync2("which ghostty 2>/dev/null");
2164
2309
  return true;
@@ -2170,48 +2315,48 @@ function setupGhostty(home) {
2170
2315
  return;
2171
2316
  }
2172
2317
  const pkgRoot = resolvePackageRoot();
2173
- const assetPath = path11.join(pkgRoot, "dist", "assets", "ghostty.conf");
2174
- if (!existsSync11(assetPath)) {
2318
+ const assetPath = path12.join(pkgRoot, "dist", "assets", "ghostty.conf");
2319
+ if (!existsSync12(assetPath)) {
2175
2320
  process.stderr.write("exe-os: ghostty.conf asset not found \u2014 skipping Ghostty setup\n");
2176
2321
  return;
2177
2322
  }
2178
2323
  const configDir = xdgConfig;
2179
- const configPath = path11.join(configDir, "config");
2180
- const backupPath = path11.join(configDir, "config.backup");
2181
- mkdirSync6(configDir, { recursive: true });
2324
+ const configPath = path12.join(configDir, "config");
2325
+ const backupPath = path12.join(configDir, "config.backup");
2326
+ mkdirSync7(configDir, { recursive: true });
2182
2327
  const START_MARKER = "# \u2500\u2500 exe-os:ghostty-start \u2500\u2500";
2183
2328
  const END_MARKER = "# \u2500\u2500 exe-os:ghostty-end \u2500\u2500";
2184
- const assetContent = readFileSync9(assetPath, "utf8").trim();
2329
+ const assetContent = readFileSync10(assetPath, "utf8").trim();
2185
2330
  const markedSection = `${START_MARKER}
2186
2331
  ${assetContent}
2187
2332
  ${END_MARKER}`;
2188
- if (existsSync11(configPath)) {
2189
- const existing = readFileSync9(configPath, "utf8");
2333
+ if (existsSync12(configPath)) {
2334
+ const existing = readFileSync10(configPath, "utf8");
2190
2335
  if (existing.includes(START_MARKER) && existing.includes(END_MARKER)) {
2191
2336
  process.stderr.write("exe-os: Ghostty config already installed \u2014 preserving local settings\n");
2192
2337
  return;
2193
2338
  } else if (existing.includes("Exe OS")) {
2194
- if (!existsSync11(backupPath)) {
2339
+ if (!existsSync12(backupPath)) {
2195
2340
  copyFileSync(configPath, backupPath);
2196
2341
  process.stderr.write(`exe-os: backed up existing Ghostty config to ${backupPath}
2197
2342
  `);
2198
2343
  }
2199
- writeFileSync7(configPath, `${START_MARKER}
2344
+ writeFileSync8(configPath, `${START_MARKER}
2200
2345
  ${existing.trim()}
2201
2346
  ${END_MARKER}
2202
2347
  `);
2203
2348
  } else {
2204
- if (!existsSync11(backupPath)) {
2349
+ if (!existsSync12(backupPath)) {
2205
2350
  copyFileSync(configPath, backupPath);
2206
2351
  process.stderr.write(`exe-os: backed up existing Ghostty config to ${backupPath}
2207
2352
  `);
2208
2353
  }
2209
- writeFileSync7(configPath, `${markedSection}
2354
+ writeFileSync8(configPath, `${markedSection}
2210
2355
 
2211
2356
  ${existing}`);
2212
2357
  }
2213
2358
  } else {
2214
- writeFileSync7(configPath, `${markedSection}
2359
+ writeFileSync8(configPath, `${markedSection}
2215
2360
  `);
2216
2361
  }
2217
2362
  process.stderr.write("exe-os: Ghostty config installed\n");
@@ -2235,6 +2380,7 @@ var init_installer = __esm({
2235
2380
  init_agent_symlinks();
2236
2381
  init_mcp_prefix();
2237
2382
  init_preferences();
2383
+ init_mcp_http_config();
2238
2384
  init_runtime_hook_manifest();
2239
2385
  EXE_SECTION_START = "<!-- exe-os:orchestration-start -->";
2240
2386
  EXE_SECTION_END = "<!-- exe-os:orchestration-end -->";
@@ -2253,8 +2399,8 @@ ${EXE_SECTION_END}`;
2253
2399
  });
2254
2400
 
2255
2401
  // src/bin/exe-new-employee.ts
2256
- import { existsSync as existsSync12, mkdirSync as mkdirSync7 } from "fs";
2257
- import path12 from "path";
2402
+ import { existsSync as existsSync13, mkdirSync as mkdirSync8 } from "fs";
2403
+ import path13 from "path";
2258
2404
 
2259
2405
  // src/lib/session-wrappers.ts
2260
2406
  import {
@@ -2428,6 +2574,12 @@ var PLATFORM_PROCEDURES = [
2428
2574
  priority: "p0",
2429
2575
  content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
2430
2576
  },
2577
+ {
2578
+ title: "Customer orchestration maturity \u2014 recommend, never trap",
2579
+ domain: "workflow",
2580
+ priority: "p1",
2581
+ content: "New customers start best in Phase 1: founder \u2194 coordinator/Chief of Staff, building company context. Suggest Phase 2 executives when domain work repeats; suggest Phase 3 parallel execution only when review/permission gates are ready. This is guidance, not a blocker: users may jump phases anytime. Never overwrite their phase, role titles, identities, or custom org design."
2582
+ },
2431
2583
  {
2432
2584
  title: "Single dispatch path \u2014 create_task only",
2433
2585
  domain: "workflow",
@@ -2486,6 +2638,12 @@ var PLATFORM_PROCEDURES = [
2486
2638
  priority: "p0",
2487
2639
  content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
2488
2640
  },
2641
+ {
2642
+ title: "Commit discipline \u2014 never leave verified work floating",
2643
+ domain: "workflow",
2644
+ priority: "p1",
2645
+ content: "After any code-change batch passes typecheck/tests/build, run git status, summarize changed files, and commit with a clear message before ending the session. If work must remain uncommitted for review/dogfood, explicitly say so, list the files, and state the blocker. Never imply work is complete while verified changes are still floating locally."
2646
+ },
2489
2647
  {
2490
2648
  title: "Desktop and TUI are the same product",
2491
2649
  domain: "architecture",
@@ -3351,7 +3509,7 @@ async function main() {
3351
3509
  const templateKey = roleMap[effectiveTemplate] ?? null;
3352
3510
  const identityTemplate = templateKey ? getIdentityTemplate(templateKey) : null;
3353
3511
  const idPath = identityPath2(name);
3354
- const dir = path12.dirname(idPath);
3512
+ const dir = path13.dirname(idPath);
3355
3513
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
3356
3514
  if (identityTemplate) {
3357
3515
  const content = identityTemplate.replace(/^agent_id: \w+/m, `agent_id: ${name}`);
@@ -3373,9 +3531,9 @@ ${rolePrompt}`;
3373
3531
  }
3374
3532
  } catch {
3375
3533
  }
3376
- const taskDir = path12.join(process.cwd(), "exe", name);
3377
- if (!existsSync12(taskDir)) {
3378
- mkdirSync7(taskDir, { recursive: true });
3534
+ const taskDir = path13.join(process.cwd(), "exe", name);
3535
+ if (!existsSync13(taskDir)) {
3536
+ mkdirSync8(taskDir, { recursive: true });
3379
3537
  }
3380
3538
  const bins = registerBinSymlinks(newEmployee.name);
3381
3539
  if (bins.created.length > 0) {