@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.
- package/deploy/stack-manifests/v0.9.json +54 -5
- package/dist/bin/age-ontology-load.js +61 -0
- package/dist/bin/agentic-ontology-backfill.js +4708 -0
- package/dist/bin/agentic-reflection-backfill.js +4144 -0
- package/dist/bin/{exe-link.js → agentic-semantic-label.js} +1523 -2275
- package/dist/bin/backfill-conversations.js +506 -20
- package/dist/bin/backfill-responses.js +506 -20
- package/dist/bin/backfill-vectors.js +233 -20
- package/dist/bin/bulk-sync-postgres.js +4876 -0
- package/dist/bin/cleanup-stale-review-tasks.js +507 -21
- package/dist/bin/cli.js +2450 -1530
- package/dist/bin/exe-assign.js +506 -20
- package/dist/bin/exe-boot.js +410 -60
- package/dist/bin/exe-cloud.js +795 -105
- package/dist/bin/exe-dispatch.js +516 -22
- package/dist/bin/exe-doctor.js +587 -30
- package/dist/bin/exe-export-behaviors.js +518 -24
- package/dist/bin/exe-forget.js +507 -21
- package/dist/bin/exe-gateway.js +571 -25
- package/dist/bin/exe-heartbeat.js +518 -24
- package/dist/bin/exe-kill.js +507 -21
- package/dist/bin/exe-launch-agent.js +2312 -1069
- package/dist/bin/exe-new-employee.js +197 -165
- package/dist/bin/exe-pending-messages.js +507 -21
- package/dist/bin/exe-pending-notifications.js +507 -21
- package/dist/bin/exe-pending-reviews.js +507 -21
- package/dist/bin/exe-rename.js +507 -21
- package/dist/bin/exe-review.js +507 -21
- package/dist/bin/exe-search.js +518 -24
- package/dist/bin/exe-session-cleanup.js +516 -22
- package/dist/bin/exe-settings.js +4 -0
- package/dist/bin/exe-start-codex.js +682 -143
- package/dist/bin/exe-start-opencode.js +627 -79
- package/dist/bin/exe-status.js +507 -21
- package/dist/bin/exe-team.js +507 -21
- package/dist/bin/git-sweep.js +516 -22
- package/dist/bin/graph-backfill.js +558 -21
- package/dist/bin/graph-export.js +507 -21
- package/dist/bin/graph-layer-benchmark.js +109 -0
- package/dist/bin/install.js +305 -288
- package/dist/bin/intercom-check.js +516 -22
- package/dist/bin/postgres-agentic-reflection-backfill.js +187 -0
- package/dist/bin/postgres-agentic-semantic-backfill.js +237 -0
- package/dist/bin/scan-tasks.js +516 -22
- package/dist/bin/setup.js +412 -62
- package/dist/bin/shard-migrate.js +506 -20
- package/dist/gateway/index.js +569 -23
- package/dist/hooks/bug-report-worker.js +519 -25
- package/dist/hooks/codex-stop-task-finalizer.js +516 -22
- package/dist/hooks/commit-complete.js +516 -22
- package/dist/hooks/error-recall.js +518 -24
- package/dist/hooks/ingest.js +516 -22
- package/dist/hooks/instructions-loaded.js +507 -21
- package/dist/hooks/notification.js +507 -21
- package/dist/hooks/post-compact.js +507 -21
- package/dist/hooks/post-tool-combined.js +519 -25
- package/dist/hooks/pre-compact.js +516 -22
- package/dist/hooks/pre-tool-use.js +507 -21
- package/dist/hooks/prompt-submit.js +519 -25
- package/dist/hooks/session-end.js +516 -22
- package/dist/hooks/session-start.js +520 -26
- package/dist/hooks/stop.js +517 -23
- package/dist/hooks/subagent-stop.js +507 -21
- package/dist/hooks/summary-worker.js +411 -61
- package/dist/index.js +569 -23
- package/dist/lib/cloud-sync.js +391 -53
- package/dist/lib/config.js +13 -1
- package/dist/lib/consolidation.js +1 -1
- package/dist/lib/database.js +124 -0
- package/dist/lib/db.js +124 -0
- package/dist/lib/device-registry.js +124 -0
- package/dist/lib/embedder.js +13 -1
- package/dist/lib/exe-daemon.js +2184 -561
- package/dist/lib/hybrid-search.js +518 -24
- package/dist/lib/identity.js +3 -0
- package/dist/lib/keychain.js +178 -22
- package/dist/lib/messaging.js +3 -0
- package/dist/lib/reminders.js +3 -0
- package/dist/lib/schedules.js +233 -20
- package/dist/lib/skill-learning.js +16 -1
- package/dist/lib/store.js +506 -20
- package/dist/lib/tasks.js +16 -1
- package/dist/lib/tmux-routing.js +16 -1
- package/dist/lib/token-spend.js +3 -0
- package/dist/mcp/server.js +1757 -428
- package/dist/mcp/tools/complete-reminder.js +3 -0
- package/dist/mcp/tools/create-reminder.js +3 -0
- package/dist/mcp/tools/create-task.js +16 -1
- package/dist/mcp/tools/deactivate-behavior.js +3 -0
- package/dist/mcp/tools/list-reminders.js +3 -0
- package/dist/mcp/tools/list-tasks.js +3 -0
- package/dist/mcp/tools/send-message.js +3 -0
- package/dist/mcp/tools/update-task.js +16 -1
- package/dist/runtime/index.js +516 -22
- package/dist/tui/App.js +594 -29
- package/package.json +8 -5
- package/src/commands/exe/cloud.md +6 -10
- package/stack.release.json +3 -3
- package/src/commands/exe/link.md +0 -18
|
@@ -461,6 +461,9 @@ function getClient() {
|
|
|
461
461
|
if (_daemonClient && _daemonClient._isDaemonActive()) {
|
|
462
462
|
return _daemonClient;
|
|
463
463
|
}
|
|
464
|
+
if (!_resilientClient) {
|
|
465
|
+
return _adapterClient;
|
|
466
|
+
}
|
|
464
467
|
return _resilientClient;
|
|
465
468
|
}
|
|
466
469
|
var _resilientClient, _daemonClient, _adapterClient;
|
|
@@ -1261,6 +1264,63 @@ var init_preferences = __esm({
|
|
|
1261
1264
|
}
|
|
1262
1265
|
});
|
|
1263
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
|
+
|
|
1264
1324
|
// src/adapters/runtime-hook-manifest.ts
|
|
1265
1325
|
function commandHasAnyMarker(command, markers) {
|
|
1266
1326
|
return markers.some((marker) => command.includes(marker));
|
|
@@ -1418,54 +1478,58 @@ __export(installer_exports, {
|
|
|
1418
1478
|
setupGhostty: () => setupGhostty,
|
|
1419
1479
|
setupTmux: () => setupTmux
|
|
1420
1480
|
});
|
|
1421
|
-
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
|
|
1422
|
-
import { existsSync as
|
|
1423
|
-
import { createHash as createHash2
|
|
1424
|
-
import
|
|
1425
|
-
import
|
|
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";
|
|
1426
1486
|
import { execSync as execSync2 } from "child_process";
|
|
1427
1487
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1428
1488
|
function resolvePackageRoot() {
|
|
1429
1489
|
const thisFile = fileURLToPath2(import.meta.url);
|
|
1430
|
-
let dir =
|
|
1431
|
-
const root =
|
|
1490
|
+
let dir = path12.dirname(thisFile);
|
|
1491
|
+
const root = path12.parse(dir).root;
|
|
1432
1492
|
while (dir !== root) {
|
|
1433
|
-
const pkgPath =
|
|
1434
|
-
if (
|
|
1493
|
+
const pkgPath = path12.join(dir, "package.json");
|
|
1494
|
+
if (existsSync12(pkgPath)) {
|
|
1435
1495
|
try {
|
|
1436
|
-
const pkg = JSON.parse(
|
|
1496
|
+
const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
|
|
1437
1497
|
if (pkg.name === "@askexenow/exe-os" || pkg.name === "exe-os") return dir;
|
|
1438
1498
|
} catch {
|
|
1439
1499
|
}
|
|
1440
1500
|
}
|
|
1441
|
-
dir =
|
|
1501
|
+
dir = path12.dirname(dir);
|
|
1442
1502
|
}
|
|
1443
|
-
return
|
|
1503
|
+
return path12.resolve(path12.dirname(thisFile), "..", "..", "..");
|
|
1444
1504
|
}
|
|
1445
|
-
async function copySlashCommands(packageRoot, homeDir =
|
|
1505
|
+
async function copySlashCommands(packageRoot, homeDir = os8.homedir()) {
|
|
1446
1506
|
let copied = 0;
|
|
1447
1507
|
let skipped = 0;
|
|
1448
|
-
const skillsBase =
|
|
1449
|
-
const
|
|
1450
|
-
if (
|
|
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)) {
|
|
1451
1515
|
const entries = await readdir(exeDir);
|
|
1452
1516
|
const mdFiles = entries.filter((f) => f.endsWith(".md"));
|
|
1453
1517
|
for (const file of mdFiles) {
|
|
1454
1518
|
const name = file.replace(".md", "");
|
|
1455
|
-
const destDir =
|
|
1519
|
+
const destDir = path12.join(skillsBase, `exe-${name}`);
|
|
1456
1520
|
await mkdir3(destDir, { recursive: true });
|
|
1457
|
-
const srcPath =
|
|
1458
|
-
const destPath =
|
|
1521
|
+
const srcPath = path12.join(exeDir, file);
|
|
1522
|
+
const destPath = path12.join(destDir, "SKILL.md");
|
|
1459
1523
|
const result = await copyAsSkill(srcPath, destPath, `exe-${name}`);
|
|
1460
1524
|
if (result) copied++;
|
|
1461
1525
|
else skipped++;
|
|
1462
1526
|
}
|
|
1463
1527
|
}
|
|
1464
|
-
const topLevelSrc =
|
|
1465
|
-
if (
|
|
1466
|
-
const destDir =
|
|
1528
|
+
const topLevelSrc = path12.join(packageRoot, "src", "commands", "exe.md");
|
|
1529
|
+
if (existsSync12(topLevelSrc)) {
|
|
1530
|
+
const destDir = path12.join(skillsBase, "exe");
|
|
1467
1531
|
await mkdir3(destDir, { recursive: true });
|
|
1468
|
-
const destPath =
|
|
1532
|
+
const destPath = path12.join(destDir, "SKILL.md");
|
|
1469
1533
|
const result = await copyAsSkill(topLevelSrc, destPath, "exe");
|
|
1470
1534
|
if (result) copied++;
|
|
1471
1535
|
else skipped++;
|
|
@@ -1488,7 +1552,7 @@ name: ${skillName}
|
|
|
1488
1552
|
`);
|
|
1489
1553
|
}
|
|
1490
1554
|
}
|
|
1491
|
-
if (
|
|
1555
|
+
if (existsSync12(destPath)) {
|
|
1492
1556
|
const existing = await readFile3(destPath, "utf-8");
|
|
1493
1557
|
if (existing === content) return false;
|
|
1494
1558
|
}
|
|
@@ -1497,32 +1561,32 @@ name: ${skillName}
|
|
|
1497
1561
|
}
|
|
1498
1562
|
function readJsonFile(filePath) {
|
|
1499
1563
|
try {
|
|
1500
|
-
return JSON.parse(
|
|
1564
|
+
return JSON.parse(readFileSync10(filePath, "utf-8"));
|
|
1501
1565
|
} catch {
|
|
1502
1566
|
return null;
|
|
1503
1567
|
}
|
|
1504
1568
|
}
|
|
1505
1569
|
function findAncestorMcpJsons(startDir, homeDir) {
|
|
1506
1570
|
const files = [];
|
|
1507
|
-
let dir =
|
|
1508
|
-
const root =
|
|
1509
|
-
const stop =
|
|
1571
|
+
let dir = path12.resolve(startDir);
|
|
1572
|
+
const root = path12.parse(dir).root;
|
|
1573
|
+
const stop = path12.resolve(homeDir);
|
|
1510
1574
|
while (dir !== root) {
|
|
1511
|
-
const candidate =
|
|
1512
|
-
if (
|
|
1575
|
+
const candidate = path12.join(dir, ".mcp.json");
|
|
1576
|
+
if (existsSync12(candidate)) files.push(candidate);
|
|
1513
1577
|
if (dir === stop) break;
|
|
1514
|
-
dir =
|
|
1578
|
+
dir = path12.dirname(dir);
|
|
1515
1579
|
}
|
|
1516
1580
|
return files;
|
|
1517
1581
|
}
|
|
1518
1582
|
function pathApplies(projectPath, cwd) {
|
|
1519
|
-
const project =
|
|
1520
|
-
const current =
|
|
1521
|
-
return current === project || current.startsWith(project +
|
|
1583
|
+
const project = path12.resolve(projectPath);
|
|
1584
|
+
const current = path12.resolve(cwd);
|
|
1585
|
+
return current === project || current.startsWith(project + path12.sep);
|
|
1522
1586
|
}
|
|
1523
|
-
function detectMcpNameCollisions(homeDir =
|
|
1524
|
-
const claudeJsonPath =
|
|
1525
|
-
if (!
|
|
1587
|
+
function detectMcpNameCollisions(homeDir = os8.homedir(), cwd = process.cwd()) {
|
|
1588
|
+
const claudeJsonPath = path12.join(homeDir, ".claude.json");
|
|
1589
|
+
if (!existsSync12(claudeJsonPath)) return [];
|
|
1526
1590
|
const claudeJson = readJsonFile(claudeJsonPath);
|
|
1527
1591
|
if (!claudeJson?.projects) return [];
|
|
1528
1592
|
const collisions = [];
|
|
@@ -1549,44 +1613,11 @@ function detectMcpNameCollisions(homeDir = os7.homedir(), cwd = process.cwd()) {
|
|
|
1549
1613
|
}
|
|
1550
1614
|
return collisions;
|
|
1551
1615
|
}
|
|
1552
|
-
function readOrCreateDaemonToken(homeDir) {
|
|
1553
|
-
const exeDir = path11.join(homeDir, ".exe-os");
|
|
1554
|
-
const tokenPath = path11.join(exeDir, "exed.token");
|
|
1555
|
-
try {
|
|
1556
|
-
if (existsSync11(tokenPath)) {
|
|
1557
|
-
const token2 = readFileSync9(tokenPath, "utf-8").trim();
|
|
1558
|
-
if (token2) return token2;
|
|
1559
|
-
}
|
|
1560
|
-
} catch {
|
|
1561
|
-
}
|
|
1562
|
-
const token = randomBytes(32).toString("hex");
|
|
1563
|
-
mkdirSync6(exeDir, { recursive: true });
|
|
1564
|
-
writeFileSync7(tokenPath, `${token}
|
|
1565
|
-
`, "utf-8");
|
|
1566
|
-
try {
|
|
1567
|
-
chmodSync3(tokenPath, 384);
|
|
1568
|
-
} catch {
|
|
1569
|
-
}
|
|
1570
|
-
return token;
|
|
1571
|
-
}
|
|
1572
|
-
function buildHttpMcpEntry(homeDir) {
|
|
1573
|
-
const port = process.env.EXE_MCP_PORT || "48739";
|
|
1574
|
-
const token = readOrCreateDaemonToken(homeDir);
|
|
1575
|
-
return {
|
|
1576
|
-
type: "http",
|
|
1577
|
-
url: `http://127.0.0.1:${port}/mcp`,
|
|
1578
|
-
headers: {
|
|
1579
|
-
Authorization: `Bearer ${token}`,
|
|
1580
|
-
"X-Agent-Id": "${AGENT_ID:-exe}",
|
|
1581
|
-
"X-Agent-Role": "${AGENT_ROLE:-COO}"
|
|
1582
|
-
}
|
|
1583
|
-
};
|
|
1584
|
-
}
|
|
1585
1616
|
function buildStdioMcpEntry(packageRoot) {
|
|
1586
1617
|
return {
|
|
1587
1618
|
type: "stdio",
|
|
1588
1619
|
command: "node",
|
|
1589
|
-
args: [
|
|
1620
|
+
args: [path12.join(packageRoot, "dist", "mcp", "server.js")],
|
|
1590
1621
|
env: {}
|
|
1591
1622
|
};
|
|
1592
1623
|
}
|
|
@@ -1594,14 +1625,14 @@ function mcpTransportMode() {
|
|
|
1594
1625
|
const value = process.env.EXE_OS_MCP_TRANSPORT?.trim().toLowerCase();
|
|
1595
1626
|
if (value === "stdio") return "stdio";
|
|
1596
1627
|
if (value === "http") return "http";
|
|
1597
|
-
const totalGB =
|
|
1628
|
+
const totalGB = os8.totalmem() / (1024 * 1024 * 1024);
|
|
1598
1629
|
if (totalGB <= 8) return "stdio";
|
|
1599
1630
|
return "http";
|
|
1600
1631
|
}
|
|
1601
|
-
async function registerMcpServer(packageRoot, homeDir =
|
|
1602
|
-
const claudeJsonPath =
|
|
1632
|
+
async function registerMcpServer(packageRoot, homeDir = os8.homedir()) {
|
|
1633
|
+
const claudeJsonPath = path12.join(homeDir, ".claude.json");
|
|
1603
1634
|
let claudeJson = {};
|
|
1604
|
-
if (
|
|
1635
|
+
if (existsSync12(claudeJsonPath)) {
|
|
1605
1636
|
try {
|
|
1606
1637
|
claudeJson = JSON.parse(await readFile3(claudeJsonPath, "utf-8"));
|
|
1607
1638
|
} catch {
|
|
@@ -1611,7 +1642,7 @@ async function registerMcpServer(packageRoot, homeDir = os7.homedir()) {
|
|
|
1611
1642
|
if (!claudeJson.mcpServers) {
|
|
1612
1643
|
claudeJson.mcpServers = {};
|
|
1613
1644
|
}
|
|
1614
|
-
const newEntry = mcpTransportMode() === "stdio" ? buildStdioMcpEntry(packageRoot) :
|
|
1645
|
+
const newEntry = mcpTransportMode() === "stdio" ? buildStdioMcpEntry(packageRoot) : buildClaudeHttpMcpEntry(homeDir);
|
|
1615
1646
|
if (claudeJson.mcpServers[MCP_LEGACY_KEY]) {
|
|
1616
1647
|
delete claudeJson.mcpServers[MCP_LEGACY_KEY];
|
|
1617
1648
|
process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
|
|
@@ -1619,8 +1650,8 @@ async function registerMcpServer(packageRoot, homeDir = os7.homedir()) {
|
|
|
1619
1650
|
const currentOs = claudeJson.mcpServers[MCP_PRIMARY_KEY];
|
|
1620
1651
|
const osMatches = currentOs && JSON.stringify(currentOs) === JSON.stringify(newEntry);
|
|
1621
1652
|
if (osMatches) {
|
|
1622
|
-
await cleanSettingsJsonMcp(
|
|
1623
|
-
await migratePermissionsToExeOs(
|
|
1653
|
+
await cleanSettingsJsonMcp(path12.join(homeDir, ".claude", "settings.json"));
|
|
1654
|
+
await migratePermissionsToExeOs(path12.join(homeDir, ".claude", "settings.json"));
|
|
1624
1655
|
const collisions2 = detectMcpNameCollisions(homeDir, packageRoot).filter((c) => c.serverName === MCP_PRIMARY_KEY || c.serverName === MCP_LEGACY_KEY);
|
|
1625
1656
|
for (const c of collisions2) {
|
|
1626
1657
|
process.stderr.write(
|
|
@@ -1632,8 +1663,8 @@ async function registerMcpServer(packageRoot, homeDir = os7.homedir()) {
|
|
|
1632
1663
|
}
|
|
1633
1664
|
claudeJson.mcpServers[MCP_PRIMARY_KEY] = newEntry;
|
|
1634
1665
|
await writeFile3(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
1635
|
-
await cleanSettingsJsonMcp(
|
|
1636
|
-
await migratePermissionsToExeOs(
|
|
1666
|
+
await cleanSettingsJsonMcp(path12.join(homeDir, ".claude", "settings.json"));
|
|
1667
|
+
await migratePermissionsToExeOs(path12.join(homeDir, ".claude", "settings.json"));
|
|
1637
1668
|
const collisions = detectMcpNameCollisions(homeDir, packageRoot).filter((c) => c.serverName === MCP_PRIMARY_KEY || c.serverName === MCP_LEGACY_KEY);
|
|
1638
1669
|
for (const c of collisions) {
|
|
1639
1670
|
process.stderr.write(
|
|
@@ -1644,7 +1675,7 @@ async function registerMcpServer(packageRoot, homeDir = os7.homedir()) {
|
|
|
1644
1675
|
return true;
|
|
1645
1676
|
}
|
|
1646
1677
|
async function cleanSettingsJsonMcp(settingsPath) {
|
|
1647
|
-
if (!
|
|
1678
|
+
if (!existsSync12(settingsPath)) return;
|
|
1648
1679
|
try {
|
|
1649
1680
|
const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
|
|
1650
1681
|
const servers = settings.mcpServers;
|
|
@@ -1665,7 +1696,7 @@ async function cleanSettingsJsonMcp(settingsPath) {
|
|
|
1665
1696
|
}
|
|
1666
1697
|
}
|
|
1667
1698
|
async function migratePermissionsToExeOs(settingsPath) {
|
|
1668
|
-
if (!
|
|
1699
|
+
if (!existsSync12(settingsPath)) return;
|
|
1669
1700
|
try {
|
|
1670
1701
|
const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
|
|
1671
1702
|
const permissions = settings.permissions;
|
|
@@ -1693,14 +1724,14 @@ async function migratePermissionsToExeOs(settingsPath) {
|
|
|
1693
1724
|
} catch {
|
|
1694
1725
|
}
|
|
1695
1726
|
}
|
|
1696
|
-
async function mergeHooks(packageRoot, homeDir =
|
|
1697
|
-
const settingsPath =
|
|
1698
|
-
const logsDir =
|
|
1699
|
-
const hookLogPath =
|
|
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");
|
|
1700
1731
|
const logSuffix = ` 2>> "${hookLogPath}"`;
|
|
1701
1732
|
await mkdir3(logsDir, { recursive: true });
|
|
1702
1733
|
let settings = {};
|
|
1703
|
-
if (
|
|
1734
|
+
if (existsSync12(settingsPath)) {
|
|
1704
1735
|
try {
|
|
1705
1736
|
settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
|
|
1706
1737
|
} catch {
|
|
@@ -1722,7 +1753,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1722
1753
|
hooks: [
|
|
1723
1754
|
{
|
|
1724
1755
|
type: "command",
|
|
1725
|
-
command: `node "${
|
|
1756
|
+
command: `node "${path12.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
|
|
1726
1757
|
}
|
|
1727
1758
|
]
|
|
1728
1759
|
},
|
|
@@ -1734,7 +1765,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1734
1765
|
hooks: [
|
|
1735
1766
|
{
|
|
1736
1767
|
type: "command",
|
|
1737
|
-
command: `node "${
|
|
1768
|
+
command: `node "${path12.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
|
|
1738
1769
|
timeout: 1e4
|
|
1739
1770
|
}
|
|
1740
1771
|
]
|
|
@@ -1747,7 +1778,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1747
1778
|
hooks: [
|
|
1748
1779
|
{
|
|
1749
1780
|
type: "command",
|
|
1750
|
-
command: `node "${
|
|
1781
|
+
command: `node "${path12.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
|
|
1751
1782
|
}
|
|
1752
1783
|
]
|
|
1753
1784
|
},
|
|
@@ -1759,7 +1790,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1759
1790
|
hooks: [
|
|
1760
1791
|
{
|
|
1761
1792
|
type: "command",
|
|
1762
|
-
command: `node "${
|
|
1793
|
+
command: `node "${path12.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
|
|
1763
1794
|
timeout: 5e3
|
|
1764
1795
|
}
|
|
1765
1796
|
]
|
|
@@ -1772,7 +1803,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1772
1803
|
hooks: [
|
|
1773
1804
|
{
|
|
1774
1805
|
type: "command",
|
|
1775
|
-
command: `node "${
|
|
1806
|
+
command: `node "${path12.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
|
|
1776
1807
|
}
|
|
1777
1808
|
]
|
|
1778
1809
|
},
|
|
@@ -1785,7 +1816,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1785
1816
|
hooks: [
|
|
1786
1817
|
{
|
|
1787
1818
|
type: "command",
|
|
1788
|
-
command: `node "${
|
|
1819
|
+
command: `node "${path12.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
|
|
1789
1820
|
}
|
|
1790
1821
|
]
|
|
1791
1822
|
},
|
|
@@ -1797,7 +1828,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1797
1828
|
hooks: [
|
|
1798
1829
|
{
|
|
1799
1830
|
type: "command",
|
|
1800
|
-
command: `node "${
|
|
1831
|
+
command: `node "${path12.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
|
|
1801
1832
|
}
|
|
1802
1833
|
]
|
|
1803
1834
|
},
|
|
@@ -1809,7 +1840,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1809
1840
|
hooks: [
|
|
1810
1841
|
{
|
|
1811
1842
|
type: "command",
|
|
1812
|
-
command: `node "${
|
|
1843
|
+
command: `node "${path12.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
|
|
1813
1844
|
timeout: 1e4
|
|
1814
1845
|
}
|
|
1815
1846
|
]
|
|
@@ -1822,7 +1853,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1822
1853
|
hooks: [
|
|
1823
1854
|
{
|
|
1824
1855
|
type: "command",
|
|
1825
|
-
command: `node "${
|
|
1856
|
+
command: `node "${path12.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
|
|
1826
1857
|
}
|
|
1827
1858
|
]
|
|
1828
1859
|
},
|
|
@@ -1834,7 +1865,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1834
1865
|
hooks: [
|
|
1835
1866
|
{
|
|
1836
1867
|
type: "command",
|
|
1837
|
-
command: `node "${
|
|
1868
|
+
command: `node "${path12.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
|
|
1838
1869
|
}
|
|
1839
1870
|
]
|
|
1840
1871
|
},
|
|
@@ -1846,7 +1877,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1846
1877
|
hooks: [
|
|
1847
1878
|
{
|
|
1848
1879
|
type: "command",
|
|
1849
|
-
command: `node "${
|
|
1880
|
+
command: `node "${path12.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
|
|
1850
1881
|
timeout: 1e4
|
|
1851
1882
|
}
|
|
1852
1883
|
]
|
|
@@ -1859,7 +1890,7 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1859
1890
|
hooks: [
|
|
1860
1891
|
{
|
|
1861
1892
|
type: "command",
|
|
1862
|
-
command: `node "${
|
|
1893
|
+
command: `node "${path12.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
|
|
1863
1894
|
}
|
|
1864
1895
|
]
|
|
1865
1896
|
},
|
|
@@ -1964,13 +1995,13 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
|
|
|
1964
1995
|
allowList.push(fullName);
|
|
1965
1996
|
}
|
|
1966
1997
|
}
|
|
1967
|
-
await mkdir3(
|
|
1998
|
+
await mkdir3(path12.dirname(settingsPath), { recursive: true });
|
|
1968
1999
|
await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
1969
2000
|
return { added, skipped };
|
|
1970
2001
|
}
|
|
1971
|
-
async function cleanOldShellFunctions(homeDir =
|
|
1972
|
-
const rosterPath =
|
|
1973
|
-
if (!
|
|
2002
|
+
async function cleanOldShellFunctions(homeDir = os8.homedir()) {
|
|
2003
|
+
const rosterPath = path12.join(homeDir, ".exe-os", "exe-employees.json");
|
|
2004
|
+
if (!existsSync12(rosterPath)) return 0;
|
|
1974
2005
|
let employees;
|
|
1975
2006
|
try {
|
|
1976
2007
|
employees = JSON.parse(await readFile3(rosterPath, "utf-8"));
|
|
@@ -1985,13 +2016,13 @@ async function cleanOldShellFunctions(homeDir = os7.homedir()) {
|
|
|
1985
2016
|
return { name: n, funcDef, forLoop };
|
|
1986
2017
|
});
|
|
1987
2018
|
const rcFiles = [
|
|
1988
|
-
|
|
1989
|
-
|
|
2019
|
+
path12.join(homeDir, ".zshrc"),
|
|
2020
|
+
path12.join(homeDir, ".bashrc")
|
|
1990
2021
|
];
|
|
1991
2022
|
const REMOVED_MARKER = "# Removed by exe-os \u2014 wrappers now at ~/.exe-os/bin/";
|
|
1992
2023
|
let totalRemoved = 0;
|
|
1993
2024
|
for (const rcPath of rcFiles) {
|
|
1994
|
-
if (!
|
|
2025
|
+
if (!existsSync12(rcPath)) continue;
|
|
1995
2026
|
let content;
|
|
1996
2027
|
try {
|
|
1997
2028
|
content = await readFile3(rcPath, "utf-8");
|
|
@@ -2095,8 +2126,8 @@ function escapeRegExp(s) {
|
|
|
2095
2126
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2096
2127
|
}
|
|
2097
2128
|
async function injectOrchestrationRules(homeDir) {
|
|
2098
|
-
const claudeDir =
|
|
2099
|
-
const claudeMdPath =
|
|
2129
|
+
const claudeDir = path12.join(homeDir, ".claude");
|
|
2130
|
+
const claudeMdPath = path12.join(claudeDir, "CLAUDE.md");
|
|
2100
2131
|
await mkdir3(claudeDir, { recursive: true });
|
|
2101
2132
|
let existing = "";
|
|
2102
2133
|
try {
|
|
@@ -2118,19 +2149,19 @@ async function injectOrchestrationRules(homeDir) {
|
|
|
2118
2149
|
await writeFile3(claudeMdPath, existing + separator + ORCHESTRATION_RULES + "\n", "utf-8");
|
|
2119
2150
|
return "injected";
|
|
2120
2151
|
}
|
|
2121
|
-
async function installStatusLine(packageRoot, homeDir =
|
|
2152
|
+
async function installStatusLine(packageRoot, homeDir = os8.homedir()) {
|
|
2122
2153
|
const prefs = loadPreferences(homeDir);
|
|
2123
2154
|
if (prefs.ccStatusLine === false) return "opted-out";
|
|
2124
|
-
const claudeDir =
|
|
2155
|
+
const claudeDir = path12.join(homeDir, ".claude");
|
|
2125
2156
|
await mkdir3(claudeDir, { recursive: true });
|
|
2126
|
-
const assetPath =
|
|
2127
|
-
if (!
|
|
2128
|
-
const destScript =
|
|
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");
|
|
2129
2160
|
const assetContent = await readFile3(assetPath, "utf-8");
|
|
2130
2161
|
await writeFile3(destScript, assetContent, { mode: 493 });
|
|
2131
|
-
const settingsPath =
|
|
2162
|
+
const settingsPath = path12.join(claudeDir, "settings.json");
|
|
2132
2163
|
let settings = {};
|
|
2133
|
-
if (
|
|
2164
|
+
if (existsSync12(settingsPath)) {
|
|
2134
2165
|
try {
|
|
2135
2166
|
settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
|
|
2136
2167
|
} catch {
|
|
@@ -2167,13 +2198,13 @@ async function runInstaller(homeDir) {
|
|
|
2167
2198
|
`Hooks: ${hookResult.added} added, ${hookResult.skipped} unchanged
|
|
2168
2199
|
`
|
|
2169
2200
|
);
|
|
2170
|
-
const resolvedHome = homeDir ??
|
|
2171
|
-
const exeWorkspace =
|
|
2172
|
-
if (!
|
|
2201
|
+
const resolvedHome = homeDir ?? os8.homedir();
|
|
2202
|
+
const exeWorkspace = path12.join(resolvedHome, "exe");
|
|
2203
|
+
if (!existsSync12(exeWorkspace)) {
|
|
2173
2204
|
try {
|
|
2174
|
-
await mkdir3(
|
|
2175
|
-
await mkdir3(
|
|
2176
|
-
await mkdir3(
|
|
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 });
|
|
2177
2208
|
process.stderr.write(
|
|
2178
2209
|
`Created ~/exe/ \u2014 your automation workspace for non-code projects
|
|
2179
2210
|
`
|
|
@@ -2208,57 +2239,57 @@ exe-os installed successfully.
|
|
|
2208
2239
|
`);
|
|
2209
2240
|
}
|
|
2210
2241
|
function setupTmux(home) {
|
|
2211
|
-
const homeDir = home ??
|
|
2212
|
-
const exeDir =
|
|
2213
|
-
const exeTmuxConf =
|
|
2214
|
-
const userTmuxConf =
|
|
2215
|
-
const backupPath =
|
|
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");
|
|
2216
2247
|
const sourceLine = "source-file ~/.exe-os/tmux.conf";
|
|
2217
2248
|
const pkgRoot = resolvePackageRoot();
|
|
2218
|
-
const assetPath =
|
|
2219
|
-
if (!
|
|
2249
|
+
const assetPath = path12.join(pkgRoot, "dist", "assets", "tmux.conf");
|
|
2250
|
+
if (!existsSync12(assetPath)) {
|
|
2220
2251
|
process.stderr.write(`exe-os: tmux.conf asset not found at ${assetPath} \u2014 skipping tmux setup
|
|
2221
2252
|
`);
|
|
2222
2253
|
return;
|
|
2223
2254
|
}
|
|
2224
|
-
|
|
2225
|
-
if (
|
|
2226
|
-
const currentContent =
|
|
2227
|
-
const newContent =
|
|
2255
|
+
mkdirSync7(exeDir, { recursive: true });
|
|
2256
|
+
if (existsSync12(exeTmuxConf)) {
|
|
2257
|
+
const currentContent = readFileSync10(exeTmuxConf, "utf8");
|
|
2258
|
+
const newContent = readFileSync10(assetPath, "utf8");
|
|
2228
2259
|
const currentHash = createHash2("sha256").update(currentContent).digest("hex");
|
|
2229
2260
|
const newHash = createHash2("sha256").update(newContent).digest("hex");
|
|
2230
2261
|
if (currentHash !== newHash) {
|
|
2231
|
-
const shippedPath =
|
|
2232
|
-
const lastShippedHash =
|
|
2262
|
+
const shippedPath = path12.join(exeDir, ".tmux.conf.shipped-hash");
|
|
2263
|
+
const lastShippedHash = existsSync12(shippedPath) ? readFileSync10(shippedPath, "utf8").trim() : "";
|
|
2233
2264
|
if (lastShippedHash && currentHash !== lastShippedHash) {
|
|
2234
2265
|
process.stderr.write("exe-os: tmux config has user customizations \u2014 skipping overwrite\n");
|
|
2235
2266
|
} else {
|
|
2236
2267
|
copyFileSync(assetPath, exeTmuxConf);
|
|
2237
2268
|
process.stderr.write("exe-os: tmux config updated\n");
|
|
2238
2269
|
}
|
|
2239
|
-
|
|
2270
|
+
writeFileSync8(shippedPath, newHash, "utf8");
|
|
2240
2271
|
} else {
|
|
2241
2272
|
process.stderr.write("exe-os: tmux config already up to date\n");
|
|
2242
2273
|
}
|
|
2243
2274
|
} else {
|
|
2244
2275
|
copyFileSync(assetPath, exeTmuxConf);
|
|
2245
|
-
const newContent =
|
|
2276
|
+
const newContent = readFileSync10(assetPath, "utf8");
|
|
2246
2277
|
const newHash = createHash2("sha256").update(newContent).digest("hex");
|
|
2247
|
-
|
|
2278
|
+
writeFileSync8(path12.join(exeDir, ".tmux.conf.shipped-hash"), newHash, "utf8");
|
|
2248
2279
|
}
|
|
2249
|
-
if (
|
|
2250
|
-
const existing =
|
|
2280
|
+
if (existsSync12(userTmuxConf)) {
|
|
2281
|
+
const existing = readFileSync10(userTmuxConf, "utf8");
|
|
2251
2282
|
if (!existing.includes(sourceLine)) {
|
|
2252
|
-
if (!
|
|
2283
|
+
if (!existsSync12(backupPath)) {
|
|
2253
2284
|
copyFileSync(userTmuxConf, backupPath);
|
|
2254
2285
|
process.stderr.write(`exe-os: backed up existing tmux config to ${backupPath}
|
|
2255
2286
|
`);
|
|
2256
2287
|
}
|
|
2257
|
-
|
|
2288
|
+
writeFileSync8(userTmuxConf, `${sourceLine}
|
|
2258
2289
|
${existing}`);
|
|
2259
2290
|
}
|
|
2260
2291
|
} else {
|
|
2261
|
-
|
|
2292
|
+
writeFileSync8(userTmuxConf, `# Exe OS tmux defaults \u2014 remove this line to use your own config
|
|
2262
2293
|
${sourceLine}
|
|
2263
2294
|
`);
|
|
2264
2295
|
}
|
|
@@ -2269,10 +2300,10 @@ ${sourceLine}
|
|
|
2269
2300
|
process.stderr.write("exe-os: tmux config installed\n");
|
|
2270
2301
|
}
|
|
2271
2302
|
function setupGhostty(home) {
|
|
2272
|
-
const homeDir = home ??
|
|
2273
|
-
const xdgConfig =
|
|
2274
|
-
const macConfig =
|
|
2275
|
-
const ghosttyInstalled =
|
|
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) || (() => {
|
|
2276
2307
|
try {
|
|
2277
2308
|
execSync2("which ghostty 2>/dev/null");
|
|
2278
2309
|
return true;
|
|
@@ -2284,48 +2315,48 @@ function setupGhostty(home) {
|
|
|
2284
2315
|
return;
|
|
2285
2316
|
}
|
|
2286
2317
|
const pkgRoot = resolvePackageRoot();
|
|
2287
|
-
const assetPath =
|
|
2288
|
-
if (!
|
|
2318
|
+
const assetPath = path12.join(pkgRoot, "dist", "assets", "ghostty.conf");
|
|
2319
|
+
if (!existsSync12(assetPath)) {
|
|
2289
2320
|
process.stderr.write("exe-os: ghostty.conf asset not found \u2014 skipping Ghostty setup\n");
|
|
2290
2321
|
return;
|
|
2291
2322
|
}
|
|
2292
2323
|
const configDir = xdgConfig;
|
|
2293
|
-
const configPath =
|
|
2294
|
-
const backupPath =
|
|
2295
|
-
|
|
2324
|
+
const configPath = path12.join(configDir, "config");
|
|
2325
|
+
const backupPath = path12.join(configDir, "config.backup");
|
|
2326
|
+
mkdirSync7(configDir, { recursive: true });
|
|
2296
2327
|
const START_MARKER = "# \u2500\u2500 exe-os:ghostty-start \u2500\u2500";
|
|
2297
2328
|
const END_MARKER = "# \u2500\u2500 exe-os:ghostty-end \u2500\u2500";
|
|
2298
|
-
const assetContent =
|
|
2329
|
+
const assetContent = readFileSync10(assetPath, "utf8").trim();
|
|
2299
2330
|
const markedSection = `${START_MARKER}
|
|
2300
2331
|
${assetContent}
|
|
2301
2332
|
${END_MARKER}`;
|
|
2302
|
-
if (
|
|
2303
|
-
const existing =
|
|
2333
|
+
if (existsSync12(configPath)) {
|
|
2334
|
+
const existing = readFileSync10(configPath, "utf8");
|
|
2304
2335
|
if (existing.includes(START_MARKER) && existing.includes(END_MARKER)) {
|
|
2305
2336
|
process.stderr.write("exe-os: Ghostty config already installed \u2014 preserving local settings\n");
|
|
2306
2337
|
return;
|
|
2307
2338
|
} else if (existing.includes("Exe OS")) {
|
|
2308
|
-
if (!
|
|
2339
|
+
if (!existsSync12(backupPath)) {
|
|
2309
2340
|
copyFileSync(configPath, backupPath);
|
|
2310
2341
|
process.stderr.write(`exe-os: backed up existing Ghostty config to ${backupPath}
|
|
2311
2342
|
`);
|
|
2312
2343
|
}
|
|
2313
|
-
|
|
2344
|
+
writeFileSync8(configPath, `${START_MARKER}
|
|
2314
2345
|
${existing.trim()}
|
|
2315
2346
|
${END_MARKER}
|
|
2316
2347
|
`);
|
|
2317
2348
|
} else {
|
|
2318
|
-
if (!
|
|
2349
|
+
if (!existsSync12(backupPath)) {
|
|
2319
2350
|
copyFileSync(configPath, backupPath);
|
|
2320
2351
|
process.stderr.write(`exe-os: backed up existing Ghostty config to ${backupPath}
|
|
2321
2352
|
`);
|
|
2322
2353
|
}
|
|
2323
|
-
|
|
2354
|
+
writeFileSync8(configPath, `${markedSection}
|
|
2324
2355
|
|
|
2325
2356
|
${existing}`);
|
|
2326
2357
|
}
|
|
2327
2358
|
} else {
|
|
2328
|
-
|
|
2359
|
+
writeFileSync8(configPath, `${markedSection}
|
|
2329
2360
|
`);
|
|
2330
2361
|
}
|
|
2331
2362
|
process.stderr.write("exe-os: Ghostty config installed\n");
|
|
@@ -2349,6 +2380,7 @@ var init_installer = __esm({
|
|
|
2349
2380
|
init_agent_symlinks();
|
|
2350
2381
|
init_mcp_prefix();
|
|
2351
2382
|
init_preferences();
|
|
2383
|
+
init_mcp_http_config();
|
|
2352
2384
|
init_runtime_hook_manifest();
|
|
2353
2385
|
EXE_SECTION_START = "<!-- exe-os:orchestration-start -->";
|
|
2354
2386
|
EXE_SECTION_END = "<!-- exe-os:orchestration-end -->";
|
|
@@ -2367,8 +2399,8 @@ ${EXE_SECTION_END}`;
|
|
|
2367
2399
|
});
|
|
2368
2400
|
|
|
2369
2401
|
// src/bin/exe-new-employee.ts
|
|
2370
|
-
import { existsSync as
|
|
2371
|
-
import
|
|
2402
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync8 } from "fs";
|
|
2403
|
+
import path13 from "path";
|
|
2372
2404
|
|
|
2373
2405
|
// src/lib/session-wrappers.ts
|
|
2374
2406
|
import {
|
|
@@ -3477,7 +3509,7 @@ async function main() {
|
|
|
3477
3509
|
const templateKey = roleMap[effectiveTemplate] ?? null;
|
|
3478
3510
|
const identityTemplate = templateKey ? getIdentityTemplate(templateKey) : null;
|
|
3479
3511
|
const idPath = identityPath2(name);
|
|
3480
|
-
const dir =
|
|
3512
|
+
const dir = path13.dirname(idPath);
|
|
3481
3513
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
3482
3514
|
if (identityTemplate) {
|
|
3483
3515
|
const content = identityTemplate.replace(/^agent_id: \w+/m, `agent_id: ${name}`);
|
|
@@ -3499,9 +3531,9 @@ ${rolePrompt}`;
|
|
|
3499
3531
|
}
|
|
3500
3532
|
} catch {
|
|
3501
3533
|
}
|
|
3502
|
-
const taskDir =
|
|
3503
|
-
if (!
|
|
3504
|
-
|
|
3534
|
+
const taskDir = path13.join(process.cwd(), "exe", name);
|
|
3535
|
+
if (!existsSync13(taskDir)) {
|
|
3536
|
+
mkdirSync8(taskDir, { recursive: true });
|
|
3505
3537
|
}
|
|
3506
3538
|
const bins = registerBinSymlinks(newEmployee.name);
|
|
3507
3539
|
if (bins.created.length > 0) {
|