@askexenow/exe-os 0.8.108 → 0.9.0
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/dist/bin/cli.js +135 -1
- package/dist/bin/exe-boot.js +1 -1
- package/dist/bin/exe-dispatch.js +1 -1
- package/dist/bin/exe-gateway.js +1 -1
- package/dist/bin/exe-new-employee.js +134 -0
- package/dist/bin/exe-session-cleanup.js +1 -1
- package/dist/bin/exe-start-codex.js +47 -3
- package/dist/bin/git-sweep.js +1 -1
- package/dist/bin/install.js +133 -0
- package/dist/bin/scan-tasks.js +1 -1
- package/dist/gateway/index.js +1 -1
- package/dist/hooks/bug-report-worker.js +1 -1
- package/dist/hooks/commit-complete.js +1 -1
- package/dist/hooks/ingest-worker.js +1 -1
- package/dist/hooks/pre-compact.js +1 -1
- package/dist/hooks/prompt-submit.js +1 -1
- package/dist/hooks/session-end.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/cloudflare-dns.js +117 -0
- package/dist/lib/exe-daemon.js +22 -23
- package/dist/lib/tasks.js +1 -1
- package/dist/lib/tmux-routing.js +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/tools/create-task.js +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/tui/App.js +1 -1
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -607,6 +607,7 @@ var init_preferences = __esm({
|
|
|
607
607
|
// src/adapters/claude/installer.ts
|
|
608
608
|
var installer_exports = {};
|
|
609
609
|
__export(installer_exports, {
|
|
610
|
+
cleanOldShellFunctions: () => cleanOldShellFunctions,
|
|
610
611
|
copySlashCommands: () => copySlashCommands,
|
|
611
612
|
installStatusLine: () => installStatusLine,
|
|
612
613
|
mergeHooks: () => mergeHooks,
|
|
@@ -1015,6 +1016,132 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1015
1016
|
await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
1016
1017
|
return { added, skipped };
|
|
1017
1018
|
}
|
|
1019
|
+
async function cleanOldShellFunctions(homeDir = os5.homedir()) {
|
|
1020
|
+
const rosterPath = path5.join(homeDir, ".exe-os", "exe-employees.json");
|
|
1021
|
+
if (!existsSync5(rosterPath)) return 0;
|
|
1022
|
+
let employees;
|
|
1023
|
+
try {
|
|
1024
|
+
employees = JSON.parse(await readFile3(rosterPath, "utf-8"));
|
|
1025
|
+
} catch {
|
|
1026
|
+
return 0;
|
|
1027
|
+
}
|
|
1028
|
+
if (employees.length === 0) return 0;
|
|
1029
|
+
const names = employees.map((e) => e.name);
|
|
1030
|
+
const funcPatterns = names.map((n) => {
|
|
1031
|
+
const funcDef = new RegExp(`^\\s*(function\\s+)?${escapeRegExp(n)}\\d+\\s*\\(\\)`, "m");
|
|
1032
|
+
const forLoop = new RegExp(`${escapeRegExp(n)}\\$\\{?[a-zA-Z_][a-zA-Z0-9_]*\\}?`, "m");
|
|
1033
|
+
return { name: n, funcDef, forLoop };
|
|
1034
|
+
});
|
|
1035
|
+
const rcFiles = [
|
|
1036
|
+
path5.join(homeDir, ".zshrc"),
|
|
1037
|
+
path5.join(homeDir, ".bashrc")
|
|
1038
|
+
];
|
|
1039
|
+
const REMOVED_MARKER = "# Removed by exe-os \u2014 wrappers now at ~/.exe-os/bin/";
|
|
1040
|
+
let totalRemoved = 0;
|
|
1041
|
+
for (const rcPath of rcFiles) {
|
|
1042
|
+
if (!existsSync5(rcPath)) continue;
|
|
1043
|
+
let content;
|
|
1044
|
+
try {
|
|
1045
|
+
content = await readFile3(rcPath, "utf-8");
|
|
1046
|
+
} catch {
|
|
1047
|
+
continue;
|
|
1048
|
+
}
|
|
1049
|
+
if (content.includes(REMOVED_MARKER)) continue;
|
|
1050
|
+
const lines = content.split("\n");
|
|
1051
|
+
let changed = false;
|
|
1052
|
+
let inForLoop = false;
|
|
1053
|
+
let forLoopMatchesEmployee = false;
|
|
1054
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1055
|
+
const line = lines[i];
|
|
1056
|
+
const trimmed = line.trim();
|
|
1057
|
+
if (trimmed.startsWith("#")) continue;
|
|
1058
|
+
if (/^\s*for\s+/.test(trimmed)) {
|
|
1059
|
+
inForLoop = true;
|
|
1060
|
+
forLoopMatchesEmployee = false;
|
|
1061
|
+
for (const { forLoop } of funcPatterns) {
|
|
1062
|
+
if (forLoop.test(trimmed)) {
|
|
1063
|
+
forLoopMatchesEmployee = true;
|
|
1064
|
+
break;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
if (forLoopMatchesEmployee) {
|
|
1068
|
+
lines[i] = `${REMOVED_MARKER}
|
|
1069
|
+
# ${line}`;
|
|
1070
|
+
changed = true;
|
|
1071
|
+
totalRemoved++;
|
|
1072
|
+
continue;
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
if (inForLoop) {
|
|
1076
|
+
if (!forLoopMatchesEmployee) {
|
|
1077
|
+
for (const { forLoop } of funcPatterns) {
|
|
1078
|
+
if (forLoop.test(trimmed)) {
|
|
1079
|
+
forLoopMatchesEmployee = true;
|
|
1080
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
1081
|
+
if (/^\s*for\s+/.test(lines[j].replace(/^#\s*/, ""))) {
|
|
1082
|
+
if (!lines[j].startsWith("#")) {
|
|
1083
|
+
lines[j] = `${REMOVED_MARKER}
|
|
1084
|
+
# ${lines[j]}`;
|
|
1085
|
+
totalRemoved++;
|
|
1086
|
+
}
|
|
1087
|
+
break;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
break;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
if (forLoopMatchesEmployee && !trimmed.startsWith("#")) {
|
|
1095
|
+
lines[i] = `# ${line}`;
|
|
1096
|
+
changed = true;
|
|
1097
|
+
totalRemoved++;
|
|
1098
|
+
}
|
|
1099
|
+
if (trimmed === "done" || trimmed.startsWith("done;") || trimmed.startsWith("done ")) {
|
|
1100
|
+
inForLoop = false;
|
|
1101
|
+
forLoopMatchesEmployee = false;
|
|
1102
|
+
}
|
|
1103
|
+
continue;
|
|
1104
|
+
}
|
|
1105
|
+
for (const { funcDef } of funcPatterns) {
|
|
1106
|
+
if (funcDef.test(trimmed)) {
|
|
1107
|
+
lines[i] = `${REMOVED_MARKER}
|
|
1108
|
+
# ${line}`;
|
|
1109
|
+
changed = true;
|
|
1110
|
+
totalRemoved++;
|
|
1111
|
+
let braceDepth = 0;
|
|
1112
|
+
const hasBrace = trimmed.includes("{");
|
|
1113
|
+
if (hasBrace) braceDepth = 1;
|
|
1114
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
1115
|
+
const bodyLine = lines[j].trim();
|
|
1116
|
+
if (!hasBrace && braceDepth === 0) {
|
|
1117
|
+
if (bodyLine === "{") {
|
|
1118
|
+
braceDepth = 1;
|
|
1119
|
+
lines[j] = `# ${lines[j]}`;
|
|
1120
|
+
totalRemoved++;
|
|
1121
|
+
continue;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
if (braceDepth > 0) {
|
|
1125
|
+
braceDepth += (bodyLine.match(/{/g) ?? []).length;
|
|
1126
|
+
braceDepth -= (bodyLine.match(/}/g) ?? []).length;
|
|
1127
|
+
lines[j] = `# ${lines[j]}`;
|
|
1128
|
+
totalRemoved++;
|
|
1129
|
+
if (braceDepth <= 0) break;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
break;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
if (changed) {
|
|
1137
|
+
await writeFile3(rcPath, lines.join("\n"));
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
return totalRemoved;
|
|
1141
|
+
}
|
|
1142
|
+
function escapeRegExp(s) {
|
|
1143
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1144
|
+
}
|
|
1018
1145
|
async function injectOrchestrationRules(homeDir) {
|
|
1019
1146
|
const claudeDir = path5.join(homeDir, ".claude");
|
|
1020
1147
|
const claudeMdPath = path5.join(claudeDir, "CLAUDE.md");
|
|
@@ -1117,6 +1244,13 @@ async function runInstaller(homeDir) {
|
|
|
1117
1244
|
`Status line: ${statusLineResult}
|
|
1118
1245
|
`
|
|
1119
1246
|
);
|
|
1247
|
+
const shellFuncsCleaned = await cleanOldShellFunctions(resolvedHome);
|
|
1248
|
+
if (shellFuncsCleaned > 0) {
|
|
1249
|
+
process.stderr.write(
|
|
1250
|
+
`Shell cleanup: removed ${shellFuncsCleaned} old shell function(s) that were shadowing exe-os wrappers
|
|
1251
|
+
`
|
|
1252
|
+
);
|
|
1253
|
+
}
|
|
1120
1254
|
process.stderr.write(`
|
|
1121
1255
|
exe-os installed successfully.
|
|
1122
1256
|
`);
|
|
@@ -10181,7 +10315,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
10181
10315
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
10182
10316
|
`
|
|
10183
10317
|
);
|
|
10184
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
10318
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
10185
10319
|
} else if (useOpencode) {
|
|
10186
10320
|
const binName = `${employeeName}-opencode`;
|
|
10187
10321
|
process.stderr.write(
|
package/dist/bin/exe-boot.js
CHANGED
|
@@ -6268,7 +6268,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
6268
6268
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
6269
6269
|
`
|
|
6270
6270
|
);
|
|
6271
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
6271
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
6272
6272
|
} else if (useOpencode) {
|
|
6273
6273
|
const binName = `${employeeName}-opencode`;
|
|
6274
6274
|
process.stderr.write(
|
package/dist/bin/exe-dispatch.js
CHANGED
|
@@ -4434,7 +4434,7 @@ function spawnEmployee(employeeName2, exeSession2, projectDir2, opts) {
|
|
|
4434
4434
|
`[tmux-routing] agent-config: ${employeeName2} \u2192 codex (${agentRtConfig.model})
|
|
4435
4435
|
`
|
|
4436
4436
|
);
|
|
4437
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName2}${cleanupSuffix}`;
|
|
4437
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName2} --session ${sessionName}${cleanupSuffix}`;
|
|
4438
4438
|
} else if (useOpencode) {
|
|
4439
4439
|
const binName = `${employeeName2}-opencode`;
|
|
4440
4440
|
process.stderr.write(
|
package/dist/bin/exe-gateway.js
CHANGED
|
@@ -9159,7 +9159,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
9159
9159
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
9160
9160
|
`
|
|
9161
9161
|
);
|
|
9162
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
9162
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
9163
9163
|
} else if (useOpencode) {
|
|
9164
9164
|
const binName = `${employeeName}-opencode`;
|
|
9165
9165
|
process.stderr.write(
|
|
@@ -1020,6 +1020,7 @@ var init_preferences = __esm({
|
|
|
1020
1020
|
// src/adapters/claude/installer.ts
|
|
1021
1021
|
var installer_exports = {};
|
|
1022
1022
|
__export(installer_exports, {
|
|
1023
|
+
cleanOldShellFunctions: () => cleanOldShellFunctions,
|
|
1023
1024
|
copySlashCommands: () => copySlashCommands,
|
|
1024
1025
|
installStatusLine: () => installStatusLine,
|
|
1025
1026
|
mergeHooks: () => mergeHooks,
|
|
@@ -1428,6 +1429,132 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1428
1429
|
await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
1429
1430
|
return { added, skipped };
|
|
1430
1431
|
}
|
|
1432
|
+
async function cleanOldShellFunctions(homeDir = os5.homedir()) {
|
|
1433
|
+
const rosterPath = path9.join(homeDir, ".exe-os", "exe-employees.json");
|
|
1434
|
+
if (!existsSync9(rosterPath)) return 0;
|
|
1435
|
+
let employees;
|
|
1436
|
+
try {
|
|
1437
|
+
employees = JSON.parse(await readFile3(rosterPath, "utf-8"));
|
|
1438
|
+
} catch {
|
|
1439
|
+
return 0;
|
|
1440
|
+
}
|
|
1441
|
+
if (employees.length === 0) return 0;
|
|
1442
|
+
const names = employees.map((e) => e.name);
|
|
1443
|
+
const funcPatterns = names.map((n) => {
|
|
1444
|
+
const funcDef = new RegExp(`^\\s*(function\\s+)?${escapeRegExp(n)}\\d+\\s*\\(\\)`, "m");
|
|
1445
|
+
const forLoop = new RegExp(`${escapeRegExp(n)}\\$\\{?[a-zA-Z_][a-zA-Z0-9_]*\\}?`, "m");
|
|
1446
|
+
return { name: n, funcDef, forLoop };
|
|
1447
|
+
});
|
|
1448
|
+
const rcFiles = [
|
|
1449
|
+
path9.join(homeDir, ".zshrc"),
|
|
1450
|
+
path9.join(homeDir, ".bashrc")
|
|
1451
|
+
];
|
|
1452
|
+
const REMOVED_MARKER = "# Removed by exe-os \u2014 wrappers now at ~/.exe-os/bin/";
|
|
1453
|
+
let totalRemoved = 0;
|
|
1454
|
+
for (const rcPath of rcFiles) {
|
|
1455
|
+
if (!existsSync9(rcPath)) continue;
|
|
1456
|
+
let content;
|
|
1457
|
+
try {
|
|
1458
|
+
content = await readFile3(rcPath, "utf-8");
|
|
1459
|
+
} catch {
|
|
1460
|
+
continue;
|
|
1461
|
+
}
|
|
1462
|
+
if (content.includes(REMOVED_MARKER)) continue;
|
|
1463
|
+
const lines = content.split("\n");
|
|
1464
|
+
let changed = false;
|
|
1465
|
+
let inForLoop = false;
|
|
1466
|
+
let forLoopMatchesEmployee = false;
|
|
1467
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1468
|
+
const line = lines[i];
|
|
1469
|
+
const trimmed = line.trim();
|
|
1470
|
+
if (trimmed.startsWith("#")) continue;
|
|
1471
|
+
if (/^\s*for\s+/.test(trimmed)) {
|
|
1472
|
+
inForLoop = true;
|
|
1473
|
+
forLoopMatchesEmployee = false;
|
|
1474
|
+
for (const { forLoop } of funcPatterns) {
|
|
1475
|
+
if (forLoop.test(trimmed)) {
|
|
1476
|
+
forLoopMatchesEmployee = true;
|
|
1477
|
+
break;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
if (forLoopMatchesEmployee) {
|
|
1481
|
+
lines[i] = `${REMOVED_MARKER}
|
|
1482
|
+
# ${line}`;
|
|
1483
|
+
changed = true;
|
|
1484
|
+
totalRemoved++;
|
|
1485
|
+
continue;
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
if (inForLoop) {
|
|
1489
|
+
if (!forLoopMatchesEmployee) {
|
|
1490
|
+
for (const { forLoop } of funcPatterns) {
|
|
1491
|
+
if (forLoop.test(trimmed)) {
|
|
1492
|
+
forLoopMatchesEmployee = true;
|
|
1493
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
1494
|
+
if (/^\s*for\s+/.test(lines[j].replace(/^#\s*/, ""))) {
|
|
1495
|
+
if (!lines[j].startsWith("#")) {
|
|
1496
|
+
lines[j] = `${REMOVED_MARKER}
|
|
1497
|
+
# ${lines[j]}`;
|
|
1498
|
+
totalRemoved++;
|
|
1499
|
+
}
|
|
1500
|
+
break;
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
break;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
if (forLoopMatchesEmployee && !trimmed.startsWith("#")) {
|
|
1508
|
+
lines[i] = `# ${line}`;
|
|
1509
|
+
changed = true;
|
|
1510
|
+
totalRemoved++;
|
|
1511
|
+
}
|
|
1512
|
+
if (trimmed === "done" || trimmed.startsWith("done;") || trimmed.startsWith("done ")) {
|
|
1513
|
+
inForLoop = false;
|
|
1514
|
+
forLoopMatchesEmployee = false;
|
|
1515
|
+
}
|
|
1516
|
+
continue;
|
|
1517
|
+
}
|
|
1518
|
+
for (const { funcDef } of funcPatterns) {
|
|
1519
|
+
if (funcDef.test(trimmed)) {
|
|
1520
|
+
lines[i] = `${REMOVED_MARKER}
|
|
1521
|
+
# ${line}`;
|
|
1522
|
+
changed = true;
|
|
1523
|
+
totalRemoved++;
|
|
1524
|
+
let braceDepth = 0;
|
|
1525
|
+
const hasBrace = trimmed.includes("{");
|
|
1526
|
+
if (hasBrace) braceDepth = 1;
|
|
1527
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
1528
|
+
const bodyLine = lines[j].trim();
|
|
1529
|
+
if (!hasBrace && braceDepth === 0) {
|
|
1530
|
+
if (bodyLine === "{") {
|
|
1531
|
+
braceDepth = 1;
|
|
1532
|
+
lines[j] = `# ${lines[j]}`;
|
|
1533
|
+
totalRemoved++;
|
|
1534
|
+
continue;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
if (braceDepth > 0) {
|
|
1538
|
+
braceDepth += (bodyLine.match(/{/g) ?? []).length;
|
|
1539
|
+
braceDepth -= (bodyLine.match(/}/g) ?? []).length;
|
|
1540
|
+
lines[j] = `# ${lines[j]}`;
|
|
1541
|
+
totalRemoved++;
|
|
1542
|
+
if (braceDepth <= 0) break;
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
break;
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
if (changed) {
|
|
1550
|
+
await writeFile3(rcPath, lines.join("\n"));
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
return totalRemoved;
|
|
1554
|
+
}
|
|
1555
|
+
function escapeRegExp(s) {
|
|
1556
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1557
|
+
}
|
|
1431
1558
|
async function injectOrchestrationRules(homeDir) {
|
|
1432
1559
|
const claudeDir = path9.join(homeDir, ".claude");
|
|
1433
1560
|
const claudeMdPath = path9.join(claudeDir, "CLAUDE.md");
|
|
@@ -1530,6 +1657,13 @@ async function runInstaller(homeDir) {
|
|
|
1530
1657
|
`Status line: ${statusLineResult}
|
|
1531
1658
|
`
|
|
1532
1659
|
);
|
|
1660
|
+
const shellFuncsCleaned = await cleanOldShellFunctions(resolvedHome);
|
|
1661
|
+
if (shellFuncsCleaned > 0) {
|
|
1662
|
+
process.stderr.write(
|
|
1663
|
+
`Shell cleanup: removed ${shellFuncsCleaned} old shell function(s) that were shadowing exe-os wrappers
|
|
1664
|
+
`
|
|
1665
|
+
);
|
|
1666
|
+
}
|
|
1533
1667
|
process.stderr.write(`
|
|
1534
1668
|
exe-os installed successfully.
|
|
1535
1669
|
`);
|
|
@@ -6270,7 +6270,7 @@ function spawnEmployee(employeeName, exeSession2, projectDir, opts) {
|
|
|
6270
6270
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
6271
6271
|
`
|
|
6272
6272
|
);
|
|
6273
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
6273
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
6274
6274
|
} else if (useOpencode) {
|
|
6275
6275
|
const binName = `${employeeName}-opencode`;
|
|
6276
6276
|
process.stderr.write(
|
|
@@ -2791,8 +2791,17 @@ function resolveAgent(argv) {
|
|
|
2791
2791
|
);
|
|
2792
2792
|
}
|
|
2793
2793
|
const agent = rest[idx + 1].toLowerCase();
|
|
2794
|
-
const
|
|
2795
|
-
|
|
2794
|
+
const withoutAgent = [...rest.slice(0, idx), ...rest.slice(idx + 2)];
|
|
2795
|
+
const sessIdx = withoutAgent.indexOf("--session");
|
|
2796
|
+
let sessionName;
|
|
2797
|
+
let passthrough;
|
|
2798
|
+
if (sessIdx !== -1 && withoutAgent[sessIdx + 1]) {
|
|
2799
|
+
sessionName = withoutAgent[sessIdx + 1];
|
|
2800
|
+
passthrough = [...withoutAgent.slice(0, sessIdx), ...withoutAgent.slice(sessIdx + 2)];
|
|
2801
|
+
} else {
|
|
2802
|
+
passthrough = withoutAgent;
|
|
2803
|
+
}
|
|
2804
|
+
return { agent, passthrough, sessionName };
|
|
2796
2805
|
}
|
|
2797
2806
|
function loadIdentity(agent) {
|
|
2798
2807
|
const dir = path11.join(os9.homedir(), ".exe-os", "identity");
|
|
@@ -2839,8 +2848,9 @@ function writePromptFile(agent, identity, behaviorsPath) {
|
|
|
2839
2848
|
async function main() {
|
|
2840
2849
|
let agent;
|
|
2841
2850
|
let passthrough;
|
|
2851
|
+
let sessionName;
|
|
2842
2852
|
try {
|
|
2843
|
-
({ agent, passthrough } = resolveAgent(process.argv));
|
|
2853
|
+
({ agent, passthrough, sessionName } = resolveAgent(process.argv));
|
|
2844
2854
|
} catch (err) {
|
|
2845
2855
|
process.stderr.write(`${err.message}
|
|
2846
2856
|
`);
|
|
@@ -2941,6 +2951,37 @@ async function main() {
|
|
|
2941
2951
|
`
|
|
2942
2952
|
);
|
|
2943
2953
|
}
|
|
2954
|
+
const WORKTREE_ROLES = /* @__PURE__ */ new Set(["Principal Engineer", "Staff Code Reviewer"]);
|
|
2955
|
+
let worktreePath = null;
|
|
2956
|
+
const worktreeName = sessionName ? sessionName.split("-")[0] : agent;
|
|
2957
|
+
process.stderr.write(`[exe-start-codex] agent=${agent} session=${sessionName ?? "none"} worktree=${worktreeName} role="${empRole}" worktree-eligible=${WORKTREE_ROLES.has(empRole)}
|
|
2958
|
+
`);
|
|
2959
|
+
if (WORKTREE_ROLES.has(empRole)) {
|
|
2960
|
+
try {
|
|
2961
|
+
const { execSync: es } = await import("child_process");
|
|
2962
|
+
const worktreeDir = path11.join(process.cwd(), ".worktrees", worktreeName);
|
|
2963
|
+
const branchName = `${worktreeName}/codex-${Date.now()}`;
|
|
2964
|
+
if (existsSync10(worktreeDir)) {
|
|
2965
|
+
worktreePath = worktreeDir;
|
|
2966
|
+
process.stderr.write(`[exe-start-codex] Reusing worktree at ${worktreeDir}
|
|
2967
|
+
`);
|
|
2968
|
+
} else {
|
|
2969
|
+
mkdirSync7(path11.dirname(worktreeDir), { recursive: true });
|
|
2970
|
+
es(`git worktree add "${worktreeDir}" -b "${branchName}" HEAD`, {
|
|
2971
|
+
encoding: "utf-8",
|
|
2972
|
+
timeout: 3e4
|
|
2973
|
+
});
|
|
2974
|
+
worktreePath = worktreeDir;
|
|
2975
|
+
process.stderr.write(`[exe-start-codex] Created worktree at ${worktreeDir} (branch: ${branchName})
|
|
2976
|
+
`);
|
|
2977
|
+
}
|
|
2978
|
+
} catch (err) {
|
|
2979
|
+
process.stderr.write(
|
|
2980
|
+
`[exe-start-codex] Worktree creation failed for ${agent}: ${err instanceof Error ? err.message : String(err)}. Falling back to main checkout.
|
|
2981
|
+
`
|
|
2982
|
+
);
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2944
2985
|
const effectiveModel = process.env.EXE_AGENT_MODEL ?? CODEX.defaultModel;
|
|
2945
2986
|
const args = [
|
|
2946
2987
|
"-m",
|
|
@@ -2949,6 +2990,9 @@ async function main() {
|
|
|
2949
2990
|
CODEX.inlineFlag,
|
|
2950
2991
|
...passthrough
|
|
2951
2992
|
];
|
|
2993
|
+
if (worktreePath) {
|
|
2994
|
+
args.push("-C", worktreePath);
|
|
2995
|
+
}
|
|
2952
2996
|
if (promptPath) {
|
|
2953
2997
|
args.push("-c", `model_instructions_file="${promptPath}"`);
|
|
2954
2998
|
}
|
package/dist/bin/git-sweep.js
CHANGED
|
@@ -4922,7 +4922,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
4922
4922
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
4923
4923
|
`
|
|
4924
4924
|
);
|
|
4925
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
4925
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
4926
4926
|
} else if (useOpencode) {
|
|
4927
4927
|
const binName = `${employeeName}-opencode`;
|
|
4928
4928
|
process.stderr.write(
|
package/dist/bin/install.js
CHANGED
|
@@ -804,6 +804,132 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
804
804
|
await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
805
805
|
return { added, skipped };
|
|
806
806
|
}
|
|
807
|
+
async function cleanOldShellFunctions(homeDir = os5.homedir()) {
|
|
808
|
+
const rosterPath = path5.join(homeDir, ".exe-os", "exe-employees.json");
|
|
809
|
+
if (!existsSync5(rosterPath)) return 0;
|
|
810
|
+
let employees;
|
|
811
|
+
try {
|
|
812
|
+
employees = JSON.parse(await readFile3(rosterPath, "utf-8"));
|
|
813
|
+
} catch {
|
|
814
|
+
return 0;
|
|
815
|
+
}
|
|
816
|
+
if (employees.length === 0) return 0;
|
|
817
|
+
const names = employees.map((e) => e.name);
|
|
818
|
+
const funcPatterns = names.map((n) => {
|
|
819
|
+
const funcDef = new RegExp(`^\\s*(function\\s+)?${escapeRegExp(n)}\\d+\\s*\\(\\)`, "m");
|
|
820
|
+
const forLoop = new RegExp(`${escapeRegExp(n)}\\$\\{?[a-zA-Z_][a-zA-Z0-9_]*\\}?`, "m");
|
|
821
|
+
return { name: n, funcDef, forLoop };
|
|
822
|
+
});
|
|
823
|
+
const rcFiles = [
|
|
824
|
+
path5.join(homeDir, ".zshrc"),
|
|
825
|
+
path5.join(homeDir, ".bashrc")
|
|
826
|
+
];
|
|
827
|
+
const REMOVED_MARKER = "# Removed by exe-os \u2014 wrappers now at ~/.exe-os/bin/";
|
|
828
|
+
let totalRemoved = 0;
|
|
829
|
+
for (const rcPath of rcFiles) {
|
|
830
|
+
if (!existsSync5(rcPath)) continue;
|
|
831
|
+
let content;
|
|
832
|
+
try {
|
|
833
|
+
content = await readFile3(rcPath, "utf-8");
|
|
834
|
+
} catch {
|
|
835
|
+
continue;
|
|
836
|
+
}
|
|
837
|
+
if (content.includes(REMOVED_MARKER)) continue;
|
|
838
|
+
const lines = content.split("\n");
|
|
839
|
+
let changed = false;
|
|
840
|
+
let inForLoop = false;
|
|
841
|
+
let forLoopMatchesEmployee = false;
|
|
842
|
+
for (let i = 0; i < lines.length; i++) {
|
|
843
|
+
const line = lines[i];
|
|
844
|
+
const trimmed = line.trim();
|
|
845
|
+
if (trimmed.startsWith("#")) continue;
|
|
846
|
+
if (/^\s*for\s+/.test(trimmed)) {
|
|
847
|
+
inForLoop = true;
|
|
848
|
+
forLoopMatchesEmployee = false;
|
|
849
|
+
for (const { forLoop } of funcPatterns) {
|
|
850
|
+
if (forLoop.test(trimmed)) {
|
|
851
|
+
forLoopMatchesEmployee = true;
|
|
852
|
+
break;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
if (forLoopMatchesEmployee) {
|
|
856
|
+
lines[i] = `${REMOVED_MARKER}
|
|
857
|
+
# ${line}`;
|
|
858
|
+
changed = true;
|
|
859
|
+
totalRemoved++;
|
|
860
|
+
continue;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
if (inForLoop) {
|
|
864
|
+
if (!forLoopMatchesEmployee) {
|
|
865
|
+
for (const { forLoop } of funcPatterns) {
|
|
866
|
+
if (forLoop.test(trimmed)) {
|
|
867
|
+
forLoopMatchesEmployee = true;
|
|
868
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
869
|
+
if (/^\s*for\s+/.test(lines[j].replace(/^#\s*/, ""))) {
|
|
870
|
+
if (!lines[j].startsWith("#")) {
|
|
871
|
+
lines[j] = `${REMOVED_MARKER}
|
|
872
|
+
# ${lines[j]}`;
|
|
873
|
+
totalRemoved++;
|
|
874
|
+
}
|
|
875
|
+
break;
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
break;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
if (forLoopMatchesEmployee && !trimmed.startsWith("#")) {
|
|
883
|
+
lines[i] = `# ${line}`;
|
|
884
|
+
changed = true;
|
|
885
|
+
totalRemoved++;
|
|
886
|
+
}
|
|
887
|
+
if (trimmed === "done" || trimmed.startsWith("done;") || trimmed.startsWith("done ")) {
|
|
888
|
+
inForLoop = false;
|
|
889
|
+
forLoopMatchesEmployee = false;
|
|
890
|
+
}
|
|
891
|
+
continue;
|
|
892
|
+
}
|
|
893
|
+
for (const { funcDef } of funcPatterns) {
|
|
894
|
+
if (funcDef.test(trimmed)) {
|
|
895
|
+
lines[i] = `${REMOVED_MARKER}
|
|
896
|
+
# ${line}`;
|
|
897
|
+
changed = true;
|
|
898
|
+
totalRemoved++;
|
|
899
|
+
let braceDepth = 0;
|
|
900
|
+
const hasBrace = trimmed.includes("{");
|
|
901
|
+
if (hasBrace) braceDepth = 1;
|
|
902
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
903
|
+
const bodyLine = lines[j].trim();
|
|
904
|
+
if (!hasBrace && braceDepth === 0) {
|
|
905
|
+
if (bodyLine === "{") {
|
|
906
|
+
braceDepth = 1;
|
|
907
|
+
lines[j] = `# ${lines[j]}`;
|
|
908
|
+
totalRemoved++;
|
|
909
|
+
continue;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
if (braceDepth > 0) {
|
|
913
|
+
braceDepth += (bodyLine.match(/{/g) ?? []).length;
|
|
914
|
+
braceDepth -= (bodyLine.match(/}/g) ?? []).length;
|
|
915
|
+
lines[j] = `# ${lines[j]}`;
|
|
916
|
+
totalRemoved++;
|
|
917
|
+
if (braceDepth <= 0) break;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
break;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
if (changed) {
|
|
925
|
+
await writeFile3(rcPath, lines.join("\n"));
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
return totalRemoved;
|
|
929
|
+
}
|
|
930
|
+
function escapeRegExp(s) {
|
|
931
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
932
|
+
}
|
|
807
933
|
var EXE_SECTION_START = "<!-- exe-os:orchestration-start -->";
|
|
808
934
|
var EXE_SECTION_END = "<!-- exe-os:orchestration-end -->";
|
|
809
935
|
var ORCHESTRATION_RULES = `${EXE_SECTION_START}
|
|
@@ -919,6 +1045,13 @@ async function runInstaller(homeDir) {
|
|
|
919
1045
|
`Status line: ${statusLineResult}
|
|
920
1046
|
`
|
|
921
1047
|
);
|
|
1048
|
+
const shellFuncsCleaned = await cleanOldShellFunctions(resolvedHome);
|
|
1049
|
+
if (shellFuncsCleaned > 0) {
|
|
1050
|
+
process.stderr.write(
|
|
1051
|
+
`Shell cleanup: removed ${shellFuncsCleaned} old shell function(s) that were shadowing exe-os wrappers
|
|
1052
|
+
`
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
922
1055
|
process.stderr.write(`
|
|
923
1056
|
exe-os installed successfully.
|
|
924
1057
|
`);
|
package/dist/bin/scan-tasks.js
CHANGED
|
@@ -4927,7 +4927,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
4927
4927
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
4928
4928
|
`
|
|
4929
4929
|
);
|
|
4930
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
4930
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
4931
4931
|
} else if (useOpencode) {
|
|
4932
4932
|
const binName = `${employeeName}-opencode`;
|
|
4933
4933
|
process.stderr.write(
|
package/dist/gateway/index.js
CHANGED
|
@@ -7501,7 +7501,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
7501
7501
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
7502
7502
|
`
|
|
7503
7503
|
);
|
|
7504
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
7504
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
7505
7505
|
} else if (useOpencode) {
|
|
7506
7506
|
const binName = `${employeeName}-opencode`;
|
|
7507
7507
|
process.stderr.write(
|
|
@@ -3433,7 +3433,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3433
3433
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
3434
3434
|
`
|
|
3435
3435
|
);
|
|
3436
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
3436
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
3437
3437
|
} else if (useOpencode) {
|
|
3438
3438
|
const binName = `${employeeName}-opencode`;
|
|
3439
3439
|
process.stderr.write(
|
|
@@ -4921,7 +4921,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
4921
4921
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
4922
4922
|
`
|
|
4923
4923
|
);
|
|
4924
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
4924
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
4925
4925
|
} else if (useOpencode) {
|
|
4926
4926
|
const binName = `${employeeName}-opencode`;
|
|
4927
4927
|
process.stderr.write(
|
|
@@ -4300,7 +4300,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
4300
4300
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
4301
4301
|
`
|
|
4302
4302
|
);
|
|
4303
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
4303
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
4304
4304
|
} else if (useOpencode) {
|
|
4305
4305
|
const binName = `${employeeName}-opencode`;
|
|
4306
4306
|
process.stderr.write(
|
|
@@ -4905,7 +4905,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
4905
4905
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
4906
4906
|
`
|
|
4907
4907
|
);
|
|
4908
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
4908
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
4909
4909
|
} else if (useOpencode) {
|
|
4910
4910
|
const binName = `${employeeName}-opencode`;
|
|
4911
4911
|
process.stderr.write(
|
|
@@ -7405,7 +7405,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
7405
7405
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
7406
7406
|
`
|
|
7407
7407
|
);
|
|
7408
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
7408
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
7409
7409
|
} else if (useOpencode) {
|
|
7410
7410
|
const binName = `${employeeName}-opencode`;
|
|
7411
7411
|
process.stderr.write(
|
|
@@ -5107,7 +5107,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5107
5107
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
5108
5108
|
`
|
|
5109
5109
|
);
|
|
5110
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
5110
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
5111
5111
|
} else if (useOpencode) {
|
|
5112
5112
|
const binName = `${employeeName}-opencode`;
|
|
5113
5113
|
process.stderr.write(
|
package/dist/index.js
CHANGED
|
@@ -5339,7 +5339,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5339
5339
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
5340
5340
|
`
|
|
5341
5341
|
);
|
|
5342
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
5342
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
5343
5343
|
} else if (useOpencode) {
|
|
5344
5344
|
const binName = `${employeeName}-opencode`;
|
|
5345
5345
|
process.stderr.write(
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// src/lib/cloudflare-dns.ts
|
|
2
|
+
var CLOUDFLARE_API_BASE_URL = "https://api.cloudflare.com/client/v4";
|
|
3
|
+
var DNS_RECORD_TYPE_A = "A";
|
|
4
|
+
var DEFAULT_PROXIED = true;
|
|
5
|
+
var DEFAULT_TTL = 1;
|
|
6
|
+
var REQUEST_TIMEOUT_MS = 3e4;
|
|
7
|
+
var UNKNOWN_ERROR_CODE = "unknown";
|
|
8
|
+
async function createARecord(cfApiToken, zoneId, domain, ip, opts) {
|
|
9
|
+
const proxied = opts?.proxied ?? DEFAULT_PROXIED;
|
|
10
|
+
const ttl = opts?.ttl ?? DEFAULT_TTL;
|
|
11
|
+
const response = await requestCloudflare(cfApiToken, zoneId, {
|
|
12
|
+
method: "POST",
|
|
13
|
+
body: {
|
|
14
|
+
type: DNS_RECORD_TYPE_A,
|
|
15
|
+
name: domain,
|
|
16
|
+
content: ip,
|
|
17
|
+
proxied,
|
|
18
|
+
ttl
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return mapDnsRecord(response);
|
|
22
|
+
}
|
|
23
|
+
async function deleteARecord(cfApiToken, zoneId, recordId) {
|
|
24
|
+
await requestCloudflare(cfApiToken, zoneId, {
|
|
25
|
+
method: "DELETE",
|
|
26
|
+
path: `/dns_records/${recordId}`
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async function findARecord(cfApiToken, zoneId, name) {
|
|
30
|
+
const query = new URLSearchParams({
|
|
31
|
+
type: DNS_RECORD_TYPE_A,
|
|
32
|
+
name
|
|
33
|
+
});
|
|
34
|
+
const records = await requestCloudflare(cfApiToken, zoneId, {
|
|
35
|
+
method: "GET",
|
|
36
|
+
query
|
|
37
|
+
});
|
|
38
|
+
const record = records[0];
|
|
39
|
+
return record ? mapDnsRecord(record) : null;
|
|
40
|
+
}
|
|
41
|
+
async function requestCloudflare(cfApiToken, zoneId, options) {
|
|
42
|
+
const response = await fetch(buildUrl(zoneId, options.path, options.query), {
|
|
43
|
+
method: options.method,
|
|
44
|
+
headers: buildHeaders(cfApiToken),
|
|
45
|
+
body: options.body ? JSON.stringify(options.body) : void 0,
|
|
46
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
47
|
+
});
|
|
48
|
+
const envelope = await parseEnvelope(response);
|
|
49
|
+
if (!response.ok || !envelope.success) {
|
|
50
|
+
throw toCloudflareError(response, envelope);
|
|
51
|
+
}
|
|
52
|
+
return envelope.result;
|
|
53
|
+
}
|
|
54
|
+
function buildUrl(zoneId, path = "/dns_records", query) {
|
|
55
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
56
|
+
const url = new URL(
|
|
57
|
+
`${CLOUDFLARE_API_BASE_URL}/zones/${zoneId}${normalizedPath}`
|
|
58
|
+
);
|
|
59
|
+
if (query) {
|
|
60
|
+
url.search = query.toString();
|
|
61
|
+
}
|
|
62
|
+
return url.toString();
|
|
63
|
+
}
|
|
64
|
+
function buildHeaders(cfApiToken) {
|
|
65
|
+
return {
|
|
66
|
+
Authorization: `Bearer ${cfApiToken}`,
|
|
67
|
+
"Content-Type": "application/json",
|
|
68
|
+
Accept: "application/json"
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
async function parseEnvelope(response) {
|
|
72
|
+
try {
|
|
73
|
+
return await response.json();
|
|
74
|
+
} catch {
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
errors: [
|
|
78
|
+
{
|
|
79
|
+
code: UNKNOWN_ERROR_CODE,
|
|
80
|
+
message: `HTTP ${response.status}: ${response.statusText}`
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
messages: [],
|
|
84
|
+
result: null
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function toCloudflareError(response, envelope) {
|
|
89
|
+
const firstError = envelope.errors[0];
|
|
90
|
+
const errorCode = String(firstError?.code ?? UNKNOWN_ERROR_CODE);
|
|
91
|
+
const message = firstError?.message ?? `HTTP ${response.status}: ${response.statusText}`;
|
|
92
|
+
return new CloudflareError(response.status, errorCode, message);
|
|
93
|
+
}
|
|
94
|
+
function mapDnsRecord(record) {
|
|
95
|
+
return {
|
|
96
|
+
recordId: record.id,
|
|
97
|
+
name: record.name,
|
|
98
|
+
ip: record.content,
|
|
99
|
+
proxied: record.proxied
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
var CloudflareError = class extends Error {
|
|
103
|
+
status;
|
|
104
|
+
errorCode;
|
|
105
|
+
constructor(status, errorCode, message) {
|
|
106
|
+
super(message);
|
|
107
|
+
this.name = "CloudflareError";
|
|
108
|
+
this.status = status;
|
|
109
|
+
this.errorCode = errorCode;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
export {
|
|
113
|
+
CloudflareError,
|
|
114
|
+
createARecord,
|
|
115
|
+
deleteARecord,
|
|
116
|
+
findARecord
|
|
117
|
+
};
|
package/dist/lib/exe-daemon.js
CHANGED
|
@@ -2937,11 +2937,6 @@ var init_session_kill_telemetry = __esm({
|
|
|
2937
2937
|
});
|
|
2938
2938
|
|
|
2939
2939
|
// src/lib/task-scope.ts
|
|
2940
|
-
var task_scope_exports = {};
|
|
2941
|
-
__export(task_scope_exports, {
|
|
2942
|
-
getCurrentSessionScope: () => getCurrentSessionScope,
|
|
2943
|
-
sessionScopeFilter: () => sessionScopeFilter
|
|
2944
|
-
});
|
|
2945
2940
|
function getCurrentSessionScope() {
|
|
2946
2941
|
try {
|
|
2947
2942
|
return resolveExeSession();
|
|
@@ -5611,7 +5606,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5611
5606
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
5612
5607
|
`
|
|
5613
5608
|
);
|
|
5614
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
5609
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
5615
5610
|
} else if (useOpencode) {
|
|
5616
5611
|
const binName = `${employeeName}-opencode`;
|
|
5617
5612
|
process.stderr.write(
|
|
@@ -6482,6 +6477,7 @@ async function pollOrphanedTasks(deps, nowMs = Date.now()) {
|
|
|
6482
6477
|
const agent = deps.parseAgentFromSession(session);
|
|
6483
6478
|
if (agent) liveAgents.add(agent);
|
|
6484
6479
|
}
|
|
6480
|
+
const coordinatorSessions = liveSessions.filter((s) => isExeSession(s));
|
|
6485
6481
|
let tasksByAgent;
|
|
6486
6482
|
try {
|
|
6487
6483
|
tasksByAgent = await deps.queryTasksByAgent();
|
|
@@ -6490,12 +6486,17 @@ async function pollOrphanedTasks(deps, nowMs = Date.now()) {
|
|
|
6490
6486
|
}
|
|
6491
6487
|
const agentTasks = /* @__PURE__ */ new Map();
|
|
6492
6488
|
for (const t of tasksByAgent) {
|
|
6493
|
-
const
|
|
6494
|
-
|
|
6495
|
-
|
|
6489
|
+
const scope = t.sessionScope || coordinatorSessions[0] || null;
|
|
6490
|
+
if (!scope) continue;
|
|
6491
|
+
const key = `${t.agentId}::${scope}`;
|
|
6492
|
+
const existing = agentTasks.get(key) ?? [];
|
|
6493
|
+
existing.push({ taskId: t.taskId, priority: t.priority, sessionScope: scope });
|
|
6494
|
+
agentTasks.set(key, existing);
|
|
6496
6495
|
}
|
|
6497
6496
|
const woken = [];
|
|
6498
|
-
for (const [
|
|
6497
|
+
for (const [key, tasks] of agentTasks) {
|
|
6498
|
+
const agentId = key.split("::")[0];
|
|
6499
|
+
const sessionScope = tasks[0].sessionScope;
|
|
6499
6500
|
if (!shouldAutoWake({
|
|
6500
6501
|
agentId,
|
|
6501
6502
|
hasRunningSession: liveAgents.has(agentId),
|
|
@@ -6522,11 +6523,11 @@ async function pollOrphanedTasks(deps, nowMs = Date.now()) {
|
|
|
6522
6523
|
continue;
|
|
6523
6524
|
}
|
|
6524
6525
|
process.stderr.write(
|
|
6525
|
-
`[auto-wake] ${agentId} has ${tasks.length} pending task(s) but no session \u2014 spawning (attempt ${retries + 1} for task ${topTask.taskId})
|
|
6526
|
+
`[auto-wake] ${agentId} has ${tasks.length} pending task(s) but no session \u2014 spawning in ${sessionScope} (attempt ${retries + 1} for task ${topTask.taskId})
|
|
6526
6527
|
`
|
|
6527
6528
|
);
|
|
6528
6529
|
try {
|
|
6529
|
-
const result = deps.ensureEmployee(agentId);
|
|
6530
|
+
const result = deps.ensureEmployee(agentId, sessionScope);
|
|
6530
6531
|
if (result.status === "failed") {
|
|
6531
6532
|
process.stderr.write(
|
|
6532
6533
|
`[auto-wake] Failed to spawn ${agentId}: ${result.error ?? "unknown"}
|
|
@@ -6546,7 +6547,7 @@ async function pollOrphanedTasks(deps, nowMs = Date.now()) {
|
|
|
6546
6547
|
}
|
|
6547
6548
|
return woken;
|
|
6548
6549
|
}
|
|
6549
|
-
function createAutoWakeRealDeps(getClient2,
|
|
6550
|
+
function createAutoWakeRealDeps(getClient2, projectDir) {
|
|
6550
6551
|
return {
|
|
6551
6552
|
listTmuxSessions: () => {
|
|
6552
6553
|
const { listTmuxSessions: listTmuxSessions2 } = (init_tmux_status(), __toCommonJS(tmux_status_exports));
|
|
@@ -6554,24 +6555,24 @@ function createAutoWakeRealDeps(getClient2, sessionScope, projectDir) {
|
|
|
6554
6555
|
},
|
|
6555
6556
|
queryTasksByAgent: async () => {
|
|
6556
6557
|
const client = getClient2();
|
|
6557
|
-
const scope = sessionScopeFilter(sessionScope);
|
|
6558
6558
|
const result = await client.execute({
|
|
6559
|
-
sql: `SELECT assigned_to, id, priority FROM tasks
|
|
6560
|
-
WHERE status IN ('open', 'in_progress')
|
|
6559
|
+
sql: `SELECT assigned_to, id, priority, session_scope FROM tasks
|
|
6560
|
+
WHERE status IN ('open', 'in_progress')
|
|
6561
6561
|
ORDER BY
|
|
6562
6562
|
CASE priority WHEN 'p0' THEN 0 WHEN 'p1' THEN 1 WHEN 'p2' THEN 2 ELSE 3 END,
|
|
6563
6563
|
created_at ASC`,
|
|
6564
|
-
args: [
|
|
6564
|
+
args: []
|
|
6565
6565
|
});
|
|
6566
6566
|
return result.rows.map((r) => ({
|
|
6567
6567
|
agentId: String(r.assigned_to),
|
|
6568
6568
|
taskId: String(r.id),
|
|
6569
|
-
priority: String(r.priority)
|
|
6569
|
+
priority: String(r.priority),
|
|
6570
|
+
sessionScope: r.session_scope ? String(r.session_scope) : null
|
|
6570
6571
|
}));
|
|
6571
6572
|
},
|
|
6572
|
-
ensureEmployee: (agentName) => {
|
|
6573
|
+
ensureEmployee: (agentName, scope) => {
|
|
6573
6574
|
const { ensureEmployee: ensureEmployee2 } = (init_tmux_routing(), __toCommonJS(tmux_routing_exports));
|
|
6574
|
-
return ensureEmployee2(agentName,
|
|
6575
|
+
return ensureEmployee2(agentName, scope, projectDir);
|
|
6575
6576
|
},
|
|
6576
6577
|
markTaskBlocked: async (taskId, reason) => {
|
|
6577
6578
|
const client = getClient2();
|
|
@@ -10800,9 +10801,7 @@ function startAutoWake() {
|
|
|
10800
10801
|
try {
|
|
10801
10802
|
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
10802
10803
|
const { pollOrphanedTasks: pollOrphanedTasks2, createAutoWakeRealDeps: createAutoWakeRealDeps2 } = await Promise.resolve().then(() => (init_daemon_orchestration(), daemon_orchestration_exports));
|
|
10803
|
-
const
|
|
10804
|
-
const sessionScope = getCurrentSessionScope2() ?? "";
|
|
10805
|
-
const deps = createAutoWakeRealDeps2(getClient2, sessionScope, process.cwd());
|
|
10804
|
+
const deps = createAutoWakeRealDeps2(getClient2, process.cwd());
|
|
10806
10805
|
const woken = await pollOrphanedTasks2(deps);
|
|
10807
10806
|
for (const agent of woken) {
|
|
10808
10807
|
process.stderr.write(`[exed] Auto-wake: spawned ${agent}
|
package/dist/lib/tasks.js
CHANGED
|
@@ -1846,7 +1846,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
1846
1846
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
1847
1847
|
`
|
|
1848
1848
|
);
|
|
1849
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
1849
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
1850
1850
|
} else if (useOpencode) {
|
|
1851
1851
|
const binName = `${employeeName}-opencode`;
|
|
1852
1852
|
process.stderr.write(
|
package/dist/lib/tmux-routing.js
CHANGED
|
@@ -3426,7 +3426,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3426
3426
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
3427
3427
|
`
|
|
3428
3428
|
);
|
|
3429
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
3429
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
3430
3430
|
} else if (useOpencode) {
|
|
3431
3431
|
const binName = `${employeeName}-opencode`;
|
|
3432
3432
|
process.stderr.write(
|
package/dist/mcp/server.js
CHANGED
|
@@ -7156,7 +7156,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
7156
7156
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
7157
7157
|
`
|
|
7158
7158
|
);
|
|
7159
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
7159
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
7160
7160
|
} else if (useOpencode) {
|
|
7161
7161
|
const binName = `${employeeName}-opencode`;
|
|
7162
7162
|
process.stderr.write(
|
|
@@ -2051,7 +2051,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
2051
2051
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
2052
2052
|
`
|
|
2053
2053
|
);
|
|
2054
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
2054
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
2055
2055
|
} else if (useOpencode) {
|
|
2056
2056
|
const binName = `${employeeName}-opencode`;
|
|
2057
2057
|
process.stderr.write(
|
package/dist/runtime/index.js
CHANGED
|
@@ -5038,7 +5038,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5038
5038
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
5039
5039
|
`
|
|
5040
5040
|
);
|
|
5041
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
5041
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
5042
5042
|
} else if (useOpencode) {
|
|
5043
5043
|
const binName = `${employeeName}-opencode`;
|
|
5044
5044
|
process.stderr.write(
|
package/dist/tui/App.js
CHANGED
|
@@ -5544,7 +5544,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5544
5544
|
`[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
|
|
5545
5545
|
`
|
|
5546
5546
|
);
|
|
5547
|
-
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName}${cleanupSuffix}`;
|
|
5547
|
+
spawnCommand = `${envPrefix} exe-start-codex --agent ${employeeName} --session ${sessionName}${cleanupSuffix}`;
|
|
5548
5548
|
} else if (useOpencode) {
|
|
5549
5549
|
const binName = `${employeeName}-opencode`;
|
|
5550
5550
|
process.stderr.write(
|
package/package.json
CHANGED