@askexenow/exe-os 0.8.59 → 0.8.61
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/assets/tmux.conf +37 -0
- package/dist/bin/cli.js +197 -122
- package/dist/bin/exe-boot.js +46 -11
- package/dist/bin/exe-cloud.js +35 -3
- package/dist/bin/exe-dispatch.js +13 -10
- package/dist/bin/exe-gateway.js +46 -11
- package/dist/bin/exe-new-employee.js +904 -115
- package/dist/bin/exe-start.sh +133 -0
- package/dist/bin/git-sweep.js +13 -10
- package/dist/bin/install.js +182 -20
- package/dist/bin/scan-tasks.js +13 -10
- package/dist/bin/setup.js +35 -3
- package/dist/bin/update.js +35 -3
- package/dist/gateway/index.js +13 -10
- package/dist/hooks/bug-report-worker.js +13 -10
- package/dist/hooks/commit-complete.js +13 -10
- package/dist/hooks/ingest-worker.js +55 -11
- package/dist/hooks/pre-compact.js +13 -10
- package/dist/hooks/prompt-ingest-worker.js +44 -3
- package/dist/hooks/prompt-submit.js +8 -5
- package/dist/hooks/response-ingest-worker.js +47 -4
- package/dist/hooks/summary-worker.js +38 -4
- package/dist/index.js +13 -10
- package/dist/lib/exe-daemon.js +13 -10
- package/dist/lib/license.js +35 -3
- package/dist/lib/messaging.js +8 -5
- package/dist/lib/session-wrappers.js +107 -0
- package/dist/lib/tasks.js +13 -10
- package/dist/lib/tmux-routing.js +13 -10
- package/dist/mcp/server.js +46 -11
- package/dist/mcp/tools/create-task.js +13 -10
- package/dist/mcp/tools/send-message.js +8 -5
- package/dist/runtime/index.js +13 -10
- package/dist/tui/App.js +46 -11
- package/package.json +3 -3
package/dist/bin/cli.js
CHANGED
|
@@ -509,12 +509,14 @@ __export(installer_exports, {
|
|
|
509
509
|
mergeHooks: () => mergeHooks,
|
|
510
510
|
registerMcpServer: () => registerMcpServer,
|
|
511
511
|
resolvePackageRoot: () => resolvePackageRoot,
|
|
512
|
-
runInstaller: () => runInstaller
|
|
512
|
+
runInstaller: () => runInstaller,
|
|
513
|
+
setupTmux: () => setupTmux
|
|
513
514
|
});
|
|
514
515
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
|
|
515
|
-
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
|
|
516
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync, copyFileSync, mkdirSync as mkdirSync2 } from "fs";
|
|
516
517
|
import path4 from "path";
|
|
517
518
|
import os3 from "os";
|
|
519
|
+
import { execSync as execSync2 } from "child_process";
|
|
518
520
|
import { fileURLToPath } from "url";
|
|
519
521
|
function resolvePackageRoot() {
|
|
520
522
|
const thisFile = fileURLToPath(import.meta.url);
|
|
@@ -961,6 +963,44 @@ async function runInstaller(homeDir) {
|
|
|
961
963
|
exe-os installed successfully.
|
|
962
964
|
`);
|
|
963
965
|
}
|
|
966
|
+
function setupTmux(home) {
|
|
967
|
+
const homeDir = home ?? os3.homedir();
|
|
968
|
+
const exeDir = path4.join(homeDir, ".exe-os");
|
|
969
|
+
const exeTmuxConf = path4.join(exeDir, "tmux.conf");
|
|
970
|
+
const userTmuxConf = path4.join(homeDir, ".tmux.conf");
|
|
971
|
+
const backupPath = path4.join(homeDir, ".tmux.conf.backup");
|
|
972
|
+
const sourceLine = "source-file ~/.exe-os/tmux.conf";
|
|
973
|
+
const pkgRoot = resolvePackageRoot();
|
|
974
|
+
const assetPath = path4.join(pkgRoot, "dist", "assets", "tmux.conf");
|
|
975
|
+
if (!existsSync4(assetPath)) {
|
|
976
|
+
process.stderr.write(`exe-os: tmux.conf asset not found at ${assetPath} \u2014 skipping tmux setup
|
|
977
|
+
`);
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
mkdirSync2(exeDir, { recursive: true });
|
|
981
|
+
copyFileSync(assetPath, exeTmuxConf);
|
|
982
|
+
if (existsSync4(userTmuxConf)) {
|
|
983
|
+
const existing = readFileSync3(userTmuxConf, "utf8");
|
|
984
|
+
if (!existing.includes(sourceLine)) {
|
|
985
|
+
if (!existsSync4(backupPath)) {
|
|
986
|
+
copyFileSync(userTmuxConf, backupPath);
|
|
987
|
+
process.stderr.write(`exe-os: backed up existing tmux config to ${backupPath}
|
|
988
|
+
`);
|
|
989
|
+
}
|
|
990
|
+
writeFileSync(userTmuxConf, `${sourceLine}
|
|
991
|
+
${existing}`);
|
|
992
|
+
}
|
|
993
|
+
} else {
|
|
994
|
+
writeFileSync(userTmuxConf, `# Exe OS tmux defaults \u2014 remove this line to use your own config
|
|
995
|
+
${sourceLine}
|
|
996
|
+
`);
|
|
997
|
+
}
|
|
998
|
+
try {
|
|
999
|
+
execSync2(`tmux source-file ${exeTmuxConf} 2>/dev/null`);
|
|
1000
|
+
} catch {
|
|
1001
|
+
}
|
|
1002
|
+
process.stderr.write("exe-os: tmux config installed\n");
|
|
1003
|
+
}
|
|
964
1004
|
function summarizeSymlinkResults(results) {
|
|
965
1005
|
if (results.length === 0) return "no employees in roster";
|
|
966
1006
|
const created = results.filter((r) => r.action === "created").length;
|
|
@@ -2149,12 +2189,12 @@ __export(shard_manager_exports, {
|
|
|
2149
2189
|
shardExists: () => shardExists
|
|
2150
2190
|
});
|
|
2151
2191
|
import path6 from "path";
|
|
2152
|
-
import { existsSync as existsSync6, mkdirSync as
|
|
2192
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readdirSync } from "fs";
|
|
2153
2193
|
import { createClient as createClient2 } from "@libsql/client";
|
|
2154
2194
|
function initShardManager(encryptionKey) {
|
|
2155
2195
|
_encryptionKey = encryptionKey;
|
|
2156
2196
|
if (!existsSync6(SHARDS_DIR)) {
|
|
2157
|
-
|
|
2197
|
+
mkdirSync3(SHARDS_DIR, { recursive: true });
|
|
2158
2198
|
}
|
|
2159
2199
|
_shardingEnabled = true;
|
|
2160
2200
|
}
|
|
@@ -4409,8 +4449,8 @@ __export(exe_rename_exports, {
|
|
|
4409
4449
|
main: () => main,
|
|
4410
4450
|
renameEmployee: () => renameEmployee
|
|
4411
4451
|
});
|
|
4412
|
-
import { readFileSync as readFileSync5, writeFileSync, renameSync as renameSync2, unlinkSync as unlinkSync2, existsSync as existsSync8 } from "fs";
|
|
4413
|
-
import { execSync as
|
|
4452
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, renameSync as renameSync2, unlinkSync as unlinkSync2, existsSync as existsSync8 } from "fs";
|
|
4453
|
+
import { execSync as execSync3 } from "child_process";
|
|
4414
4454
|
import path9 from "path";
|
|
4415
4455
|
import { homedir as homedir2 } from "os";
|
|
4416
4456
|
async function renameEmployee(oldName, newName, opts = {}) {
|
|
@@ -4442,7 +4482,7 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
4442
4482
|
undo: () => {
|
|
4443
4483
|
employee.name = originalName;
|
|
4444
4484
|
employee.systemPrompt = originalPrompt;
|
|
4445
|
-
|
|
4485
|
+
writeFileSync2(rosterPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
|
|
4446
4486
|
}
|
|
4447
4487
|
});
|
|
4448
4488
|
const oldIdentityPath = path9.join(identityDir, `${oldName}.md`);
|
|
@@ -4454,12 +4494,12 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
4454
4494
|
`$1${newName}`
|
|
4455
4495
|
);
|
|
4456
4496
|
renameSync2(oldIdentityPath, newIdentityPath);
|
|
4457
|
-
|
|
4497
|
+
writeFileSync2(newIdentityPath, updatedContent, "utf-8");
|
|
4458
4498
|
rollbackStack.push({
|
|
4459
4499
|
description: "restore identity file",
|
|
4460
4500
|
undo: () => {
|
|
4461
4501
|
if (existsSync8(newIdentityPath)) {
|
|
4462
|
-
|
|
4502
|
+
writeFileSync2(newIdentityPath, content, "utf-8");
|
|
4463
4503
|
renameSync2(newIdentityPath, oldIdentityPath);
|
|
4464
4504
|
}
|
|
4465
4505
|
}
|
|
@@ -4475,7 +4515,7 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
4475
4515
|
undo: () => {
|
|
4476
4516
|
if (existsSync8(newAgentPath)) {
|
|
4477
4517
|
renameSync2(newAgentPath, oldAgentPath);
|
|
4478
|
-
|
|
4518
|
+
writeFileSync2(oldAgentPath, agentContent, "utf-8");
|
|
4479
4519
|
}
|
|
4480
4520
|
}
|
|
4481
4521
|
});
|
|
@@ -4544,7 +4584,7 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
4544
4584
|
}
|
|
4545
4585
|
function findExeBin2() {
|
|
4546
4586
|
try {
|
|
4547
|
-
return
|
|
4587
|
+
return execSync3(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
|
|
4548
4588
|
} catch {
|
|
4549
4589
|
return null;
|
|
4550
4590
|
}
|
|
@@ -4778,7 +4818,7 @@ __export(license_exports, {
|
|
|
4778
4818
|
stopLicenseRevalidation: () => stopLicenseRevalidation,
|
|
4779
4819
|
validateLicense: () => validateLicense
|
|
4780
4820
|
});
|
|
4781
|
-
import { readFileSync as readFileSync6, writeFileSync as
|
|
4821
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, existsSync as existsSync10, mkdirSync as mkdirSync4 } from "fs";
|
|
4782
4822
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
4783
4823
|
import path11 from "path";
|
|
4784
4824
|
import { jwtVerify, importSPKI } from "jose";
|
|
@@ -4807,8 +4847,8 @@ function loadDeviceId() {
|
|
|
4807
4847
|
} catch {
|
|
4808
4848
|
}
|
|
4809
4849
|
const id = randomUUID3();
|
|
4810
|
-
|
|
4811
|
-
|
|
4850
|
+
mkdirSync4(EXE_AI_DIR, { recursive: true });
|
|
4851
|
+
writeFileSync3(DEVICE_ID_PATH, id, "utf8");
|
|
4812
4852
|
return id;
|
|
4813
4853
|
}
|
|
4814
4854
|
function loadLicense() {
|
|
@@ -4820,8 +4860,8 @@ function loadLicense() {
|
|
|
4820
4860
|
}
|
|
4821
4861
|
}
|
|
4822
4862
|
function saveLicense(apiKey) {
|
|
4823
|
-
|
|
4824
|
-
|
|
4863
|
+
mkdirSync4(EXE_AI_DIR, { recursive: true });
|
|
4864
|
+
writeFileSync3(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
|
|
4825
4865
|
}
|
|
4826
4866
|
async function verifyLicenseJwt(token) {
|
|
4827
4867
|
try {
|
|
@@ -4864,9 +4904,35 @@ function readCachedToken() {
|
|
|
4864
4904
|
return null;
|
|
4865
4905
|
}
|
|
4866
4906
|
}
|
|
4907
|
+
function getRawCachedPlan() {
|
|
4908
|
+
try {
|
|
4909
|
+
const token = readCachedToken();
|
|
4910
|
+
if (!token) return null;
|
|
4911
|
+
const parts = token.split(".");
|
|
4912
|
+
if (parts.length !== 3) return null;
|
|
4913
|
+
const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString());
|
|
4914
|
+
const plan = payload.plan ?? "free";
|
|
4915
|
+
const limits = PLAN_LIMITS[plan] ?? PLAN_LIMITS.free;
|
|
4916
|
+
process.stderr.write(
|
|
4917
|
+
`[license] WARN: using unverified cached plan (API unreachable, JWT expired). Plan: ${plan}
|
|
4918
|
+
`
|
|
4919
|
+
);
|
|
4920
|
+
return {
|
|
4921
|
+
valid: true,
|
|
4922
|
+
plan,
|
|
4923
|
+
email: payload.sub ?? "",
|
|
4924
|
+
expiresAt: payload.exp ? new Date(payload.exp * 1e3).toISOString() : null,
|
|
4925
|
+
deviceLimit: limits.devices,
|
|
4926
|
+
employeeLimit: limits.employees,
|
|
4927
|
+
memoryLimit: limits.memories
|
|
4928
|
+
};
|
|
4929
|
+
} catch {
|
|
4930
|
+
return null;
|
|
4931
|
+
}
|
|
4932
|
+
}
|
|
4867
4933
|
function cacheResponse(token) {
|
|
4868
4934
|
try {
|
|
4869
|
-
|
|
4935
|
+
writeFileSync3(CACHE_PATH, JSON.stringify({ token }), "utf8");
|
|
4870
4936
|
} catch {
|
|
4871
4937
|
}
|
|
4872
4938
|
}
|
|
@@ -4884,6 +4950,8 @@ async function validateLicense(apiKey, deviceId) {
|
|
|
4884
4950
|
if (data.error === "device_limit_exceeded") {
|
|
4885
4951
|
const cached2 = await getCachedLicense();
|
|
4886
4952
|
if (cached2) return cached2;
|
|
4953
|
+
const raw2 = getRawCachedPlan();
|
|
4954
|
+
if (raw2) return { ...raw2, valid: false };
|
|
4887
4955
|
return { ...FREE_LICENSE, valid: false, plan: "free" };
|
|
4888
4956
|
}
|
|
4889
4957
|
if (data.token) {
|
|
@@ -4904,10 +4972,14 @@ async function validateLicense(apiKey, deviceId) {
|
|
|
4904
4972
|
}
|
|
4905
4973
|
const cached = await getCachedLicense();
|
|
4906
4974
|
if (cached) return cached;
|
|
4975
|
+
const raw = getRawCachedPlan();
|
|
4976
|
+
if (raw) return raw;
|
|
4907
4977
|
return { ...FREE_LICENSE, valid: false, plan: "free" };
|
|
4908
4978
|
} catch {
|
|
4909
4979
|
const cached = await getCachedLicense();
|
|
4910
4980
|
if (cached) return cached;
|
|
4981
|
+
const rawFallback = getRawCachedPlan();
|
|
4982
|
+
if (rawFallback) return rawFallback;
|
|
4911
4983
|
return { ...FREE_LICENSE, valid: false, error: "offline" };
|
|
4912
4984
|
}
|
|
4913
4985
|
}
|
|
@@ -5096,8 +5168,8 @@ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
|
|
|
5096
5168
|
-----END PUBLIC KEY-----`;
|
|
5097
5169
|
LICENSE_JWT_ALG = "ES256";
|
|
5098
5170
|
PLAN_LIMITS = {
|
|
5099
|
-
free: { devices: 1, employees: 1, memories:
|
|
5100
|
-
pro: { devices: 2, employees: 5, memories:
|
|
5171
|
+
free: { devices: 1, employees: 1, memories: 5e4 },
|
|
5172
|
+
pro: { devices: 2, employees: 5, memories: 25e4 },
|
|
5101
5173
|
team: { devices: 10, employees: 20, memories: 1e6 },
|
|
5102
5174
|
agency: { devices: 50, employees: 100, memories: 1e7 },
|
|
5103
5175
|
enterprise: { devices: -1, employees: -1, memories: -1 }
|
|
@@ -5109,7 +5181,7 @@ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
|
|
|
5109
5181
|
expiresAt: null,
|
|
5110
5182
|
deviceLimit: 1,
|
|
5111
5183
|
employeeLimit: 1,
|
|
5112
|
-
memoryLimit:
|
|
5184
|
+
memoryLimit: 5e4
|
|
5113
5185
|
};
|
|
5114
5186
|
CACHE_MAX_AGE_MS = 36e5;
|
|
5115
5187
|
_revalTimer = null;
|
|
@@ -5125,13 +5197,13 @@ __export(identity_exports, {
|
|
|
5125
5197
|
listIdentities: () => listIdentities,
|
|
5126
5198
|
updateIdentity: () => updateIdentity
|
|
5127
5199
|
});
|
|
5128
|
-
import { existsSync as existsSync11, mkdirSync as
|
|
5200
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
|
|
5129
5201
|
import { readdirSync as readdirSync2 } from "fs";
|
|
5130
5202
|
import path12 from "path";
|
|
5131
5203
|
import { createHash as createHash2 } from "crypto";
|
|
5132
5204
|
function ensureDir() {
|
|
5133
5205
|
if (!existsSync11(IDENTITY_DIR)) {
|
|
5134
|
-
|
|
5206
|
+
mkdirSync5(IDENTITY_DIR, { recursive: true });
|
|
5135
5207
|
}
|
|
5136
5208
|
}
|
|
5137
5209
|
function identityPath(agentId) {
|
|
@@ -5191,7 +5263,7 @@ async function updateIdentity(agentId, content, updatedBy) {
|
|
|
5191
5263
|
ensureDir();
|
|
5192
5264
|
const filePath = identityPath(agentId);
|
|
5193
5265
|
const hash = contentHash(content);
|
|
5194
|
-
|
|
5266
|
+
writeFileSync4(filePath, content, "utf-8");
|
|
5195
5267
|
try {
|
|
5196
5268
|
const client = getClient();
|
|
5197
5269
|
await client.execute({
|
|
@@ -5788,7 +5860,7 @@ __export(setup_wizard_exports, {
|
|
|
5788
5860
|
validateModel: () => validateModel
|
|
5789
5861
|
});
|
|
5790
5862
|
import crypto3 from "crypto";
|
|
5791
|
-
import { existsSync as existsSync12, mkdirSync as
|
|
5863
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync5, unlinkSync as unlinkSync4 } from "fs";
|
|
5792
5864
|
import os5 from "os";
|
|
5793
5865
|
import path13 from "path";
|
|
5794
5866
|
import { createInterface as createInterface2 } from "readline";
|
|
@@ -5800,8 +5872,8 @@ function loadSetupState() {
|
|
|
5800
5872
|
}
|
|
5801
5873
|
}
|
|
5802
5874
|
function saveSetupState(state) {
|
|
5803
|
-
|
|
5804
|
-
|
|
5875
|
+
mkdirSync6(path13.dirname(SETUP_STATE_PATH), { recursive: true });
|
|
5876
|
+
writeFileSync5(SETUP_STATE_PATH, JSON.stringify(state, null, 2));
|
|
5805
5877
|
}
|
|
5806
5878
|
function clearSetupState() {
|
|
5807
5879
|
try {
|
|
@@ -5968,7 +6040,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
5968
6040
|
if (!projects[dir]) projects[dir] = {};
|
|
5969
6041
|
projects[dir].hasTrustDialogAccepted = true;
|
|
5970
6042
|
}
|
|
5971
|
-
|
|
6043
|
+
writeFileSync5(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
5972
6044
|
} catch {
|
|
5973
6045
|
}
|
|
5974
6046
|
state.completedSteps.push(5);
|
|
@@ -6020,9 +6092,9 @@ async function runSetupWizard(opts = {}) {
|
|
|
6020
6092
|
const cooIdentityContent = getIdentityTemplate("coo");
|
|
6021
6093
|
if (cooIdentityContent) {
|
|
6022
6094
|
const cooIdPath = identityPath2(cooName);
|
|
6023
|
-
|
|
6095
|
+
mkdirSync6(path13.dirname(cooIdPath), { recursive: true });
|
|
6024
6096
|
const replaced = cooIdentityContent.replace(/agent_id:\s*exe/g, `agent_id: ${cooName}`).replace(/\$\{agent_id\}/g, cooName);
|
|
6025
|
-
|
|
6097
|
+
writeFileSync5(cooIdPath, replaced, "utf-8");
|
|
6026
6098
|
}
|
|
6027
6099
|
registerBinSymlinks2(cooName);
|
|
6028
6100
|
createdEmployees.push({ name: cooName, role: "COO" });
|
|
@@ -6121,9 +6193,9 @@ async function runSetupWizard(opts = {}) {
|
|
|
6121
6193
|
const ctoIdentityContent = getIdentityTemplate("cto");
|
|
6122
6194
|
if (ctoIdentityContent) {
|
|
6123
6195
|
const ctoIdPath = identityPath2(ctoName);
|
|
6124
|
-
|
|
6196
|
+
mkdirSync6(path13.dirname(ctoIdPath), { recursive: true });
|
|
6125
6197
|
const replaced = ctoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${ctoName}`).replace(/\$\{agent_id\}/g, ctoName);
|
|
6126
|
-
|
|
6198
|
+
writeFileSync5(ctoIdPath, replaced, "utf-8");
|
|
6127
6199
|
}
|
|
6128
6200
|
registerBinSymlinks2(ctoName);
|
|
6129
6201
|
createdEmployees.push({ name: ctoName, role: "CTO" });
|
|
@@ -6149,9 +6221,9 @@ async function runSetupWizard(opts = {}) {
|
|
|
6149
6221
|
const cmoIdentityContent = getIdentityTemplate("cmo");
|
|
6150
6222
|
if (cmoIdentityContent) {
|
|
6151
6223
|
const cmoIdPath = identityPath2(cmoName);
|
|
6152
|
-
|
|
6224
|
+
mkdirSync6(path13.dirname(cmoIdPath), { recursive: true });
|
|
6153
6225
|
const replaced = cmoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${cmoName}`).replace(/\$\{agent_id\}/g, cmoName);
|
|
6154
|
-
|
|
6226
|
+
writeFileSync5(cmoIdPath, replaced, "utf-8");
|
|
6155
6227
|
}
|
|
6156
6228
|
registerBinSymlinks2(cmoName);
|
|
6157
6229
|
createdEmployees.push({ name: cmoName, role: "CMO" });
|
|
@@ -6213,7 +6285,7 @@ var init_setup_wizard = __esm({
|
|
|
6213
6285
|
});
|
|
6214
6286
|
|
|
6215
6287
|
// src/lib/update-check.ts
|
|
6216
|
-
import { execSync as
|
|
6288
|
+
import { execSync as execSync4 } from "child_process";
|
|
6217
6289
|
import { readFileSync as readFileSync9 } from "fs";
|
|
6218
6290
|
import path14 from "path";
|
|
6219
6291
|
function getLocalVersion(packageRoot) {
|
|
@@ -6223,7 +6295,7 @@ function getLocalVersion(packageRoot) {
|
|
|
6223
6295
|
}
|
|
6224
6296
|
function getRemoteVersion() {
|
|
6225
6297
|
try {
|
|
6226
|
-
const output =
|
|
6298
|
+
const output = execSync4("npm view @askexenow/exe-os version", {
|
|
6227
6299
|
encoding: "utf-8",
|
|
6228
6300
|
timeout: 15e3,
|
|
6229
6301
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -6262,7 +6334,7 @@ __export(update_exports, {
|
|
|
6262
6334
|
getRemoteVersion: () => getRemoteVersion,
|
|
6263
6335
|
runUpdate: () => runUpdate
|
|
6264
6336
|
});
|
|
6265
|
-
import { execSync as
|
|
6337
|
+
import { execSync as execSync5 } from "child_process";
|
|
6266
6338
|
import { createInterface as createInterface3 } from "readline";
|
|
6267
6339
|
async function runUpdate(cliArgs) {
|
|
6268
6340
|
const args2 = cliArgs ?? process.argv.slice(2);
|
|
@@ -6304,14 +6376,14 @@ async function runUpdate(cliArgs) {
|
|
|
6304
6376
|
}
|
|
6305
6377
|
console.log("\n\u{1F9F9} Clearing npm cache...");
|
|
6306
6378
|
try {
|
|
6307
|
-
|
|
6379
|
+
execSync5("npm cache clean --force", { stdio: "pipe" });
|
|
6308
6380
|
console.log(" Done");
|
|
6309
6381
|
} catch {
|
|
6310
6382
|
console.log(" Skipped (non-critical)");
|
|
6311
6383
|
}
|
|
6312
6384
|
console.log("\u{1F4E5} Installing @askexenow/exe-os@latest...");
|
|
6313
6385
|
try {
|
|
6314
|
-
|
|
6386
|
+
execSync5("npm install -g @askexenow/exe-os@latest", {
|
|
6315
6387
|
stdio: ["pipe", "pipe", "pipe"],
|
|
6316
6388
|
timeout: 12e4
|
|
6317
6389
|
});
|
|
@@ -6328,7 +6400,7 @@ async function runUpdate(cliArgs) {
|
|
|
6328
6400
|
newVersion = getLocalVersion(packageRoot);
|
|
6329
6401
|
} catch {
|
|
6330
6402
|
try {
|
|
6331
|
-
const out =
|
|
6403
|
+
const out = execSync5("npm list -g @askexenow/exe-os --depth=0 2>/dev/null", { encoding: "utf8" });
|
|
6332
6404
|
const match = out.match(/@askexenow\/exe-os@(\S+)/);
|
|
6333
6405
|
newVersion = match?.[1] ?? "unknown";
|
|
6334
6406
|
} catch {
|
|
@@ -12771,14 +12843,14 @@ __export(session_registry_exports, {
|
|
|
12771
12843
|
pruneStaleSessions: () => pruneStaleSessions,
|
|
12772
12844
|
registerSession: () => registerSession
|
|
12773
12845
|
});
|
|
12774
|
-
import { readFileSync as readFileSync11, writeFileSync as
|
|
12775
|
-
import { execSync as
|
|
12846
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, existsSync as existsSync14 } from "fs";
|
|
12847
|
+
import { execSync as execSync6 } from "child_process";
|
|
12776
12848
|
import path15 from "path";
|
|
12777
12849
|
import os6 from "os";
|
|
12778
12850
|
function registerSession(entry) {
|
|
12779
12851
|
const dir = path15.dirname(REGISTRY_PATH);
|
|
12780
12852
|
if (!existsSync14(dir)) {
|
|
12781
|
-
|
|
12853
|
+
mkdirSync7(dir, { recursive: true });
|
|
12782
12854
|
}
|
|
12783
12855
|
const sessions = listSessions();
|
|
12784
12856
|
const idx = sessions.findIndex((s) => s.windowName === entry.windowName);
|
|
@@ -12787,7 +12859,7 @@ function registerSession(entry) {
|
|
|
12787
12859
|
} else {
|
|
12788
12860
|
sessions.push(entry);
|
|
12789
12861
|
}
|
|
12790
|
-
|
|
12862
|
+
writeFileSync6(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
|
|
12791
12863
|
}
|
|
12792
12864
|
function listSessions() {
|
|
12793
12865
|
try {
|
|
@@ -12802,7 +12874,7 @@ function pruneStaleSessions() {
|
|
|
12802
12874
|
if (sessions.length === 0) return 0;
|
|
12803
12875
|
let liveSessions = [];
|
|
12804
12876
|
try {
|
|
12805
|
-
liveSessions =
|
|
12877
|
+
liveSessions = execSync6("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
|
|
12806
12878
|
encoding: "utf8"
|
|
12807
12879
|
}).trim().split("\n").filter(Boolean);
|
|
12808
12880
|
} catch {
|
|
@@ -12812,7 +12884,7 @@ function pruneStaleSessions() {
|
|
|
12812
12884
|
const alive = sessions.filter((s) => liveSet.has(s.windowName));
|
|
12813
12885
|
const pruned = sessions.length - alive.length;
|
|
12814
12886
|
if (pruned > 0) {
|
|
12815
|
-
|
|
12887
|
+
writeFileSync6(REGISTRY_PATH, JSON.stringify(alive, null, 2));
|
|
12816
12888
|
}
|
|
12817
12889
|
return pruned;
|
|
12818
12890
|
}
|
|
@@ -12825,13 +12897,13 @@ var init_session_registry = __esm({
|
|
|
12825
12897
|
});
|
|
12826
12898
|
|
|
12827
12899
|
// src/lib/session-key.ts
|
|
12828
|
-
import { execSync as
|
|
12900
|
+
import { execSync as execSync7 } from "child_process";
|
|
12829
12901
|
function getSessionKey() {
|
|
12830
12902
|
if (_cached) return _cached;
|
|
12831
12903
|
let pid = process.ppid;
|
|
12832
12904
|
for (let i = 0; i < 10; i++) {
|
|
12833
12905
|
try {
|
|
12834
|
-
const info =
|
|
12906
|
+
const info = execSync7(`ps -p ${pid} -o ppid=,comm=`, {
|
|
12835
12907
|
encoding: "utf8",
|
|
12836
12908
|
timeout: 2e3
|
|
12837
12909
|
}).trim();
|
|
@@ -12975,14 +13047,14 @@ var init_transport = __esm({
|
|
|
12975
13047
|
});
|
|
12976
13048
|
|
|
12977
13049
|
// src/lib/cc-agent-support.ts
|
|
12978
|
-
import { execSync as
|
|
13050
|
+
import { execSync as execSync8 } from "child_process";
|
|
12979
13051
|
function _resetCcAgentSupportCache() {
|
|
12980
13052
|
_cachedSupport = null;
|
|
12981
13053
|
}
|
|
12982
13054
|
function claudeSupportsAgentFlag() {
|
|
12983
13055
|
if (_cachedSupport !== null) return _cachedSupport;
|
|
12984
13056
|
try {
|
|
12985
|
-
const helpOutput =
|
|
13057
|
+
const helpOutput = execSync8("claude --help 2>&1", {
|
|
12986
13058
|
encoding: "utf-8",
|
|
12987
13059
|
timeout: 5e3
|
|
12988
13060
|
});
|
|
@@ -13025,12 +13097,12 @@ var init_provider_table = __esm({
|
|
|
13025
13097
|
});
|
|
13026
13098
|
|
|
13027
13099
|
// src/lib/intercom-queue.ts
|
|
13028
|
-
import { readFileSync as readFileSync12, writeFileSync as
|
|
13100
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, renameSync as renameSync4, existsSync as existsSync15, mkdirSync as mkdirSync8 } from "fs";
|
|
13029
13101
|
import path16 from "path";
|
|
13030
13102
|
import os7 from "os";
|
|
13031
13103
|
function ensureDir2() {
|
|
13032
13104
|
const dir = path16.dirname(QUEUE_PATH);
|
|
13033
|
-
if (!existsSync15(dir))
|
|
13105
|
+
if (!existsSync15(dir)) mkdirSync8(dir, { recursive: true });
|
|
13034
13106
|
}
|
|
13035
13107
|
function readQueue() {
|
|
13036
13108
|
try {
|
|
@@ -13043,7 +13115,7 @@ function readQueue() {
|
|
|
13043
13115
|
function writeQueue(queue) {
|
|
13044
13116
|
ensureDir2();
|
|
13045
13117
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
13046
|
-
|
|
13118
|
+
writeFileSync7(tmp, JSON.stringify(queue, null, 2));
|
|
13047
13119
|
renameSync4(tmp, QUEUE_PATH);
|
|
13048
13120
|
}
|
|
13049
13121
|
function queueIntercom(targetSession, reason) {
|
|
@@ -13255,7 +13327,7 @@ __export(tasks_crud_exports, {
|
|
|
13255
13327
|
});
|
|
13256
13328
|
import crypto6 from "crypto";
|
|
13257
13329
|
import path19 from "path";
|
|
13258
|
-
import { execSync as
|
|
13330
|
+
import { execSync as execSync9 } from "child_process";
|
|
13259
13331
|
import { mkdir as mkdir6, writeFile as writeFile5, appendFile } from "fs/promises";
|
|
13260
13332
|
import { existsSync as existsSync18, readFileSync as readFileSync15 } from "fs";
|
|
13261
13333
|
async function writeCheckpoint(input) {
|
|
@@ -13502,12 +13574,12 @@ function checkStaleCompletion(taskContext, taskCreatedAt) {
|
|
|
13502
13574
|
if (!DELEGATION_KEYWORDS.test(taskContext)) return null;
|
|
13503
13575
|
try {
|
|
13504
13576
|
const since = new Date(taskCreatedAt).toISOString();
|
|
13505
|
-
const branch =
|
|
13577
|
+
const branch = execSync9(
|
|
13506
13578
|
"git rev-parse --abbrev-ref HEAD 2>/dev/null",
|
|
13507
13579
|
{ encoding: "utf8", timeout: 3e3 }
|
|
13508
13580
|
).trim();
|
|
13509
13581
|
const branchArg = branch && branch !== "HEAD" ? branch : "";
|
|
13510
|
-
const commitCount =
|
|
13582
|
+
const commitCount = execSync9(
|
|
13511
13583
|
`git log --oneline --since="${since}" ${branchArg} 2>/dev/null | wc -l`,
|
|
13512
13584
|
{ encoding: "utf8", timeout: 5e3 }
|
|
13513
13585
|
).trim();
|
|
@@ -13961,7 +14033,7 @@ var init_tasks_chain = __esm({
|
|
|
13961
14033
|
});
|
|
13962
14034
|
|
|
13963
14035
|
// src/lib/project-name.ts
|
|
13964
|
-
import { execSync as
|
|
14036
|
+
import { execSync as execSync10 } from "child_process";
|
|
13965
14037
|
import path22 from "path";
|
|
13966
14038
|
function getProjectName(cwd2) {
|
|
13967
14039
|
const dir = cwd2 ?? process.cwd();
|
|
@@ -13969,7 +14041,7 @@ function getProjectName(cwd2) {
|
|
|
13969
14041
|
try {
|
|
13970
14042
|
let repoRoot;
|
|
13971
14043
|
try {
|
|
13972
|
-
const gitCommonDir =
|
|
14044
|
+
const gitCommonDir = execSync10("git rev-parse --path-format=absolute --git-common-dir", {
|
|
13973
14045
|
cwd: dir,
|
|
13974
14046
|
encoding: "utf8",
|
|
13975
14047
|
timeout: 2e3,
|
|
@@ -13977,7 +14049,7 @@ function getProjectName(cwd2) {
|
|
|
13977
14049
|
}).trim();
|
|
13978
14050
|
repoRoot = path22.dirname(gitCommonDir);
|
|
13979
14051
|
} catch {
|
|
13980
|
-
repoRoot =
|
|
14052
|
+
repoRoot = execSync10("git rev-parse --show-toplevel", {
|
|
13981
14053
|
cwd: dir,
|
|
13982
14054
|
encoding: "utf8",
|
|
13983
14055
|
timeout: 2e3,
|
|
@@ -14461,7 +14533,7 @@ __export(tasks_exports, {
|
|
|
14461
14533
|
writeCheckpoint: () => writeCheckpoint
|
|
14462
14534
|
});
|
|
14463
14535
|
import path23 from "path";
|
|
14464
|
-
import { writeFileSync as
|
|
14536
|
+
import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7 } from "fs";
|
|
14465
14537
|
async function createTask(input) {
|
|
14466
14538
|
const result = await createTaskCore(input);
|
|
14467
14539
|
if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
|
|
@@ -14483,8 +14555,8 @@ async function updateTask(input) {
|
|
|
14483
14555
|
const cacheDir = path23.join(EXE_AI_DIR, "session-cache");
|
|
14484
14556
|
const cachePath = path23.join(cacheDir, `current-task-${agent}.json`);
|
|
14485
14557
|
if (input.status === "in_progress") {
|
|
14486
|
-
|
|
14487
|
-
|
|
14558
|
+
mkdirSync9(cacheDir, { recursive: true });
|
|
14559
|
+
writeFileSync8(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
14488
14560
|
} else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled") {
|
|
14489
14561
|
try {
|
|
14490
14562
|
unlinkSync7(cachePath);
|
|
@@ -14928,8 +15000,8 @@ __export(tmux_routing_exports, {
|
|
|
14928
15000
|
spawnEmployee: () => spawnEmployee,
|
|
14929
15001
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
14930
15002
|
});
|
|
14931
|
-
import { execFileSync as execFileSync3, execSync as
|
|
14932
|
-
import { readFileSync as readFileSync16, writeFileSync as
|
|
15003
|
+
import { execFileSync as execFileSync3, execSync as execSync11 } from "child_process";
|
|
15004
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync9, mkdirSync as mkdirSync10, existsSync as existsSync20, appendFileSync } from "fs";
|
|
14933
15005
|
import path24 from "path";
|
|
14934
15006
|
import os9 from "os";
|
|
14935
15007
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
@@ -14947,7 +15019,7 @@ function isProcessAlive(pid) {
|
|
|
14947
15019
|
}
|
|
14948
15020
|
function acquireSpawnLock2(sessionName) {
|
|
14949
15021
|
if (!existsSync20(SPAWN_LOCK_DIR)) {
|
|
14950
|
-
|
|
15022
|
+
mkdirSync10(SPAWN_LOCK_DIR, { recursive: true });
|
|
14951
15023
|
}
|
|
14952
15024
|
const lockFile = spawnLockPath(sessionName);
|
|
14953
15025
|
if (existsSync20(lockFile)) {
|
|
@@ -14960,7 +15032,7 @@ function acquireSpawnLock2(sessionName) {
|
|
|
14960
15032
|
} catch {
|
|
14961
15033
|
}
|
|
14962
15034
|
}
|
|
14963
|
-
|
|
15035
|
+
writeFileSync9(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
|
|
14964
15036
|
return true;
|
|
14965
15037
|
}
|
|
14966
15038
|
function releaseSpawnLock2(sessionName) {
|
|
@@ -15004,18 +15076,21 @@ function exportBehaviorsSync(agentId, projectName, sessionKey) {
|
|
|
15004
15076
|
function getMySession() {
|
|
15005
15077
|
return getTransport().getMySession();
|
|
15006
15078
|
}
|
|
15079
|
+
function isRootSession(name) {
|
|
15080
|
+
return name.length > 0 && !name.includes("-");
|
|
15081
|
+
}
|
|
15007
15082
|
function employeeSessionName(employee, exeSession, instance) {
|
|
15008
|
-
if (
|
|
15083
|
+
if (!isRootSession(exeSession)) {
|
|
15009
15084
|
const root = extractRootExe(exeSession);
|
|
15010
15085
|
if (root) {
|
|
15011
15086
|
process.stderr.write(
|
|
15012
|
-
`[tmux-routing] WARN: exeSession="${exeSession}" is not a root
|
|
15087
|
+
`[tmux-routing] WARN: exeSession="${exeSession}" is not a root session, using "${root}" instead
|
|
15013
15088
|
`
|
|
15014
15089
|
);
|
|
15015
15090
|
exeSession = root;
|
|
15016
15091
|
} else {
|
|
15017
15092
|
throw new Error(
|
|
15018
|
-
`Invalid exeSession "${exeSession}" \u2014
|
|
15093
|
+
`Invalid exeSession "${exeSession}" \u2014 contains a dash but no recognizable root session. Pass a root session name (e.g., "exe1", "work", "yoda1")`
|
|
15019
15094
|
);
|
|
15020
15095
|
}
|
|
15021
15096
|
}
|
|
@@ -15023,7 +15098,7 @@ function employeeSessionName(employee, exeSession, instance) {
|
|
|
15023
15098
|
const name = `${employee}${suffix}-${exeSession}`;
|
|
15024
15099
|
if (!VALID_SESSION_NAME.test(name)) {
|
|
15025
15100
|
throw new Error(
|
|
15026
|
-
`Invalid session name "${name}" \u2014 must match {agent}-
|
|
15101
|
+
`Invalid session name "${name}" \u2014 must match {agent}-{rootSession} or {agent}{instance}-{rootSession}`
|
|
15027
15102
|
);
|
|
15028
15103
|
}
|
|
15029
15104
|
return name;
|
|
@@ -15040,11 +15115,11 @@ function extractRootExe(name) {
|
|
|
15040
15115
|
}
|
|
15041
15116
|
function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
15042
15117
|
if (!existsSync20(SESSION_CACHE)) {
|
|
15043
|
-
|
|
15118
|
+
mkdirSync10(SESSION_CACHE, { recursive: true });
|
|
15044
15119
|
}
|
|
15045
15120
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
15046
15121
|
const filePath = path24.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
15047
|
-
|
|
15122
|
+
writeFileSync9(filePath, JSON.stringify({
|
|
15048
15123
|
parentExe: rootExe,
|
|
15049
15124
|
dispatchedBy: dispatchedBy || rootExe,
|
|
15050
15125
|
registeredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -15130,8 +15205,8 @@ function readDebounceState() {
|
|
|
15130
15205
|
}
|
|
15131
15206
|
function writeDebounceState(state) {
|
|
15132
15207
|
try {
|
|
15133
|
-
if (!existsSync20(SESSION_CACHE))
|
|
15134
|
-
|
|
15208
|
+
if (!existsSync20(SESSION_CACHE)) mkdirSync10(SESSION_CACHE, { recursive: true });
|
|
15209
|
+
writeFileSync9(DEBOUNCE_FILE, JSON.stringify(state));
|
|
15135
15210
|
} catch {
|
|
15136
15211
|
}
|
|
15137
15212
|
}
|
|
@@ -15266,11 +15341,11 @@ function ensureEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
15266
15341
|
error: `Error: pass employee name ('${bare}'), not session name ('${employeeName}')`
|
|
15267
15342
|
};
|
|
15268
15343
|
}
|
|
15269
|
-
if (
|
|
15344
|
+
if (!isRootSession(exeSession)) {
|
|
15270
15345
|
const root = extractRootExe(exeSession);
|
|
15271
15346
|
if (root) {
|
|
15272
15347
|
process.stderr.write(
|
|
15273
|
-
`[ensureEmployee] WARN: caller passed exeSession="${exeSession}" (not a root
|
|
15348
|
+
`[ensureEmployee] WARN: caller passed exeSession="${exeSession}" (not a root session). Auto-correcting to "${root}".
|
|
15274
15349
|
`
|
|
15275
15350
|
);
|
|
15276
15351
|
exeSession = root;
|
|
@@ -15278,7 +15353,7 @@ function ensureEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
15278
15353
|
return {
|
|
15279
15354
|
status: "failed",
|
|
15280
15355
|
sessionName: "",
|
|
15281
|
-
error: `Invalid exeSession "${exeSession}" \u2014
|
|
15356
|
+
error: `Invalid exeSession "${exeSession}" \u2014 contains a dash but no recognizable root session. Pass a root session name (e.g., "exe1", "work", "yoda1")`
|
|
15282
15357
|
};
|
|
15283
15358
|
}
|
|
15284
15359
|
}
|
|
@@ -15323,7 +15398,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
15323
15398
|
const logDir = path24.join(os9.homedir(), ".exe-os", "session-logs");
|
|
15324
15399
|
const logFile = path24.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
15325
15400
|
if (!existsSync20(logDir)) {
|
|
15326
|
-
|
|
15401
|
+
mkdirSync10(logDir, { recursive: true });
|
|
15327
15402
|
}
|
|
15328
15403
|
transport.kill(sessionName);
|
|
15329
15404
|
let cleanupSuffix = "";
|
|
@@ -15347,7 +15422,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
15347
15422
|
const trustDir = opts?.cwd ?? projectDir;
|
|
15348
15423
|
if (!projects[trustDir]) projects[trustDir] = {};
|
|
15349
15424
|
projects[trustDir].hasTrustDialogAccepted = true;
|
|
15350
|
-
|
|
15425
|
+
writeFileSync9(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
15351
15426
|
} catch {
|
|
15352
15427
|
}
|
|
15353
15428
|
try {
|
|
@@ -15385,8 +15460,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
15385
15460
|
if (changed) {
|
|
15386
15461
|
perms.allow = allow;
|
|
15387
15462
|
settings.permissions = perms;
|
|
15388
|
-
|
|
15389
|
-
|
|
15463
|
+
mkdirSync10(projSettingsDir, { recursive: true });
|
|
15464
|
+
writeFileSync9(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
15390
15465
|
}
|
|
15391
15466
|
} catch {
|
|
15392
15467
|
}
|
|
@@ -15430,7 +15505,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
15430
15505
|
let sessionContextFlag = "";
|
|
15431
15506
|
try {
|
|
15432
15507
|
const ctxDir = path24.join(os9.homedir(), ".exe-os", "session-cache");
|
|
15433
|
-
|
|
15508
|
+
mkdirSync10(ctxDir, { recursive: true });
|
|
15434
15509
|
const ctxFile = path24.join(ctxDir, `session-context-${sessionName}.md`);
|
|
15435
15510
|
const ctxContent = [
|
|
15436
15511
|
`## Session Context`,
|
|
@@ -15438,7 +15513,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
15438
15513
|
`Your parent exe session is ${exeSession}.`,
|
|
15439
15514
|
`Your employees (if any) use the -${exeSession} suffix (e.g., tom-${exeSession}).`
|
|
15440
15515
|
].join("\n");
|
|
15441
|
-
|
|
15516
|
+
writeFileSync9(ctxFile, ctxContent);
|
|
15442
15517
|
sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
|
|
15443
15518
|
} catch {
|
|
15444
15519
|
}
|
|
@@ -15477,7 +15552,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
15477
15552
|
try {
|
|
15478
15553
|
const mySession = getMySession();
|
|
15479
15554
|
const dispatchInfo = path24.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
|
|
15480
|
-
|
|
15555
|
+
writeFileSync9(dispatchInfo, JSON.stringify({
|
|
15481
15556
|
dispatchedBy: mySession,
|
|
15482
15557
|
rootExe: exeSession,
|
|
15483
15558
|
provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : "anthropic",
|
|
@@ -15488,7 +15563,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
15488
15563
|
let booted = false;
|
|
15489
15564
|
for (let i = 0; i < 30; i++) {
|
|
15490
15565
|
try {
|
|
15491
|
-
|
|
15566
|
+
execSync11("sleep 0.5");
|
|
15492
15567
|
} catch {
|
|
15493
15568
|
}
|
|
15494
15569
|
try {
|
|
@@ -15543,7 +15618,7 @@ var init_tmux_routing = __esm({
|
|
|
15543
15618
|
SPAWN_LOCK_DIR = path24.join(os9.homedir(), ".exe-os", "spawn-locks");
|
|
15544
15619
|
SESSION_CACHE = path24.join(os9.homedir(), ".exe-os", "session-cache");
|
|
15545
15620
|
BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
|
|
15546
|
-
VALID_SESSION_NAME = /^[a-z]
|
|
15621
|
+
VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
|
|
15547
15622
|
VERIFY_PANE_LINES = 200;
|
|
15548
15623
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
15549
15624
|
INTERCOM_LOG2 = path24.join(os9.homedir(), ".exe-os", "intercom.log");
|
|
@@ -15664,13 +15739,13 @@ __export(tmux_status_exports, {
|
|
|
15664
15739
|
parseActivity: () => parseActivity,
|
|
15665
15740
|
parseContextPercentage: () => parseContextPercentage
|
|
15666
15741
|
});
|
|
15667
|
-
import { execSync as
|
|
15742
|
+
import { execSync as execSync12 } from "child_process";
|
|
15668
15743
|
function inTmux() {
|
|
15669
15744
|
if (process.env.TMUX || process.env.TMUX_PANE) return true;
|
|
15670
15745
|
const term = process.env.TERM ?? "";
|
|
15671
15746
|
if (term.startsWith("tmux") || term.startsWith("screen")) return true;
|
|
15672
15747
|
try {
|
|
15673
|
-
|
|
15748
|
+
execSync12("tmux display-message -p '#{session_name}' 2>/dev/null", {
|
|
15674
15749
|
encoding: "utf8",
|
|
15675
15750
|
timeout: 2e3
|
|
15676
15751
|
});
|
|
@@ -15680,12 +15755,12 @@ function inTmux() {
|
|
|
15680
15755
|
try {
|
|
15681
15756
|
let pid = process.ppid;
|
|
15682
15757
|
for (let depth = 0; depth < 8 && pid > 1; depth++) {
|
|
15683
|
-
const comm =
|
|
15758
|
+
const comm = execSync12(`ps -p ${pid} -o comm= 2>/dev/null`, {
|
|
15684
15759
|
encoding: "utf8",
|
|
15685
15760
|
timeout: 1e3
|
|
15686
15761
|
}).trim();
|
|
15687
15762
|
if (/tmux/.test(comm)) return true;
|
|
15688
|
-
const ppid =
|
|
15763
|
+
const ppid = execSync12(`ps -p ${pid} -o ppid= 2>/dev/null`, {
|
|
15689
15764
|
encoding: "utf8",
|
|
15690
15765
|
timeout: 1e3
|
|
15691
15766
|
}).trim();
|
|
@@ -15698,7 +15773,7 @@ function inTmux() {
|
|
|
15698
15773
|
}
|
|
15699
15774
|
function listTmuxSessions() {
|
|
15700
15775
|
try {
|
|
15701
|
-
const out =
|
|
15776
|
+
const out = execSync12("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
|
|
15702
15777
|
encoding: "utf8",
|
|
15703
15778
|
timeout: 3e3
|
|
15704
15779
|
});
|
|
@@ -15709,7 +15784,7 @@ function listTmuxSessions() {
|
|
|
15709
15784
|
}
|
|
15710
15785
|
function capturePaneLines(windowName, lines = 10) {
|
|
15711
15786
|
try {
|
|
15712
|
-
const out =
|
|
15787
|
+
const out = execSync12(
|
|
15713
15788
|
`tmux capture-pane -t ${JSON.stringify(windowName)} -p 2>/dev/null | tail -${lines}`,
|
|
15714
15789
|
{ encoding: "utf8", timeout: 3e3 }
|
|
15715
15790
|
);
|
|
@@ -15720,7 +15795,7 @@ function capturePaneLines(windowName, lines = 10) {
|
|
|
15720
15795
|
}
|
|
15721
15796
|
function getPaneCwd(windowName) {
|
|
15722
15797
|
try {
|
|
15723
|
-
const out =
|
|
15798
|
+
const out = execSync12(
|
|
15724
15799
|
`tmux display-message -t ${JSON.stringify(windowName)} -p '#{pane_current_path}' 2>/dev/null`,
|
|
15725
15800
|
{ encoding: "utf8", timeout: 3e3 }
|
|
15726
15801
|
);
|
|
@@ -15731,7 +15806,7 @@ function getPaneCwd(windowName) {
|
|
|
15731
15806
|
}
|
|
15732
15807
|
function projectFromPath(dir) {
|
|
15733
15808
|
try {
|
|
15734
|
-
const root =
|
|
15809
|
+
const root = execSync12("git -C " + JSON.stringify(dir) + " rev-parse --show-toplevel 2>/dev/null", {
|
|
15735
15810
|
encoding: "utf8",
|
|
15736
15811
|
timeout: 3e3
|
|
15737
15812
|
}).trim();
|
|
@@ -15800,7 +15875,7 @@ function getEmployeeStatuses(employeeNames) {
|
|
|
15800
15875
|
}
|
|
15801
15876
|
let paneAlive = true;
|
|
15802
15877
|
try {
|
|
15803
|
-
const paneStatus =
|
|
15878
|
+
const paneStatus = execSync12(
|
|
15804
15879
|
`tmux list-panes -t ${JSON.stringify(sessionName)} -F '#{pane_dead}' 2>/dev/null`,
|
|
15805
15880
|
{ encoding: "utf8", timeout: 3e3 }
|
|
15806
15881
|
).trim();
|
|
@@ -15990,8 +16065,8 @@ function Footer() {
|
|
|
15990
16065
|
setSessions(allSessions.length);
|
|
15991
16066
|
if (!currentSession) {
|
|
15992
16067
|
try {
|
|
15993
|
-
const { execSync:
|
|
15994
|
-
const name =
|
|
16068
|
+
const { execSync: execSync14 } = await import("child_process");
|
|
16069
|
+
const name = execSync14("tmux display-message -p '#{session_name}' 2>/dev/null", {
|
|
15995
16070
|
encoding: "utf8",
|
|
15996
16071
|
timeout: 2e3
|
|
15997
16072
|
}).trim();
|
|
@@ -19315,8 +19390,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
|
|
|
19315
19390
|
}
|
|
19316
19391
|
const capture = () => {
|
|
19317
19392
|
try {
|
|
19318
|
-
const { execSync:
|
|
19319
|
-
const output =
|
|
19393
|
+
const { execSync: execSync14 } = __require("child_process");
|
|
19394
|
+
const output = execSync14(
|
|
19320
19395
|
`tmux capture-pane -t ${JSON.stringify(sessionName)} -p -e 2>/dev/null | tail -${CAPTURE_LINES}`,
|
|
19321
19396
|
{ encoding: "utf8", timeout: 3e3 }
|
|
19322
19397
|
);
|
|
@@ -19340,8 +19415,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
|
|
|
19340
19415
|
if (key.return) {
|
|
19341
19416
|
if (!demo && inputBuffer.trim()) {
|
|
19342
19417
|
try {
|
|
19343
|
-
const { execSync:
|
|
19344
|
-
|
|
19418
|
+
const { execSync: execSync14 } = __require("child_process");
|
|
19419
|
+
execSync14(
|
|
19345
19420
|
`tmux send-keys -t ${JSON.stringify(sessionName)} ${JSON.stringify(inputBuffer)} Enter`,
|
|
19346
19421
|
{ timeout: 2e3 }
|
|
19347
19422
|
);
|
|
@@ -19349,8 +19424,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
|
|
|
19349
19424
|
}
|
|
19350
19425
|
} else if (!demo) {
|
|
19351
19426
|
try {
|
|
19352
|
-
const { execSync:
|
|
19353
|
-
|
|
19427
|
+
const { execSync: execSync14 } = __require("child_process");
|
|
19428
|
+
execSync14(`tmux send-keys -t ${JSON.stringify(sessionName)} Enter`, { timeout: 2e3 });
|
|
19354
19429
|
} catch {
|
|
19355
19430
|
}
|
|
19356
19431
|
}
|
|
@@ -20025,12 +20100,12 @@ function SessionsView({
|
|
|
20025
20100
|
return;
|
|
20026
20101
|
}
|
|
20027
20102
|
} else {
|
|
20028
|
-
const { execSync:
|
|
20103
|
+
const { execSync: execSync14 } = await import("child_process");
|
|
20029
20104
|
const dir = projectDir || process.cwd();
|
|
20030
|
-
|
|
20031
|
-
|
|
20105
|
+
execSync14(`tmux new-session -d -s ${JSON.stringify(entry.sessionName)} -c ${JSON.stringify(dir)}`, { timeout: 5e3 });
|
|
20106
|
+
execSync14(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "claude --dangerously-skip-permissions" Enter`, { timeout: 3e3 });
|
|
20032
20107
|
await new Promise((r) => setTimeout(r, 3e3));
|
|
20033
|
-
|
|
20108
|
+
execSync14(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "/exe" Enter`, { timeout: 3e3 });
|
|
20034
20109
|
}
|
|
20035
20110
|
const updated = { ...entry, status: "active", activity: "Starting...", attached: false };
|
|
20036
20111
|
setViewingEmployee(updated);
|
|
@@ -20132,7 +20207,7 @@ function SessionsView({
|
|
|
20132
20207
|
const { listSessions: listSessions2 } = await Promise.resolve().then(() => (init_session_registry(), session_registry_exports));
|
|
20133
20208
|
const { listTmuxSessions: listTmuxSessions2, inTmux: inTmux2, capturePaneLines: capturePaneLines2, parseActivity: parseActivity2 } = await Promise.resolve().then(() => (init_tmux_status(), tmux_status_exports));
|
|
20134
20209
|
const { loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
20135
|
-
const { execSync:
|
|
20210
|
+
const { execSync: execSync14 } = await import("child_process");
|
|
20136
20211
|
if (!inTmux2()) {
|
|
20137
20212
|
setTmuxAvailable(false);
|
|
20138
20213
|
setProjects([]);
|
|
@@ -20141,7 +20216,7 @@ function SessionsView({
|
|
|
20141
20216
|
setTmuxAvailable(true);
|
|
20142
20217
|
const attachedMap = /* @__PURE__ */ new Map();
|
|
20143
20218
|
try {
|
|
20144
|
-
const out =
|
|
20219
|
+
const out = execSync14("tmux list-sessions -F '#{session_name}:#{session_attached}' 2>/dev/null", {
|
|
20145
20220
|
encoding: "utf8",
|
|
20146
20221
|
timeout: 3e3
|
|
20147
20222
|
});
|
|
@@ -21091,8 +21166,8 @@ function upsertConversation(conversations, platform, senderId, message) {
|
|
|
21091
21166
|
async function loadGatewayConfig() {
|
|
21092
21167
|
const state = { running: false, port: 3100, adapters: [], agents: [], gatewayUrl: "" };
|
|
21093
21168
|
try {
|
|
21094
|
-
const { execSync:
|
|
21095
|
-
const ps =
|
|
21169
|
+
const { execSync: execSync14 } = await import("child_process");
|
|
21170
|
+
const ps = execSync14("pgrep -f exe-gateway 2>/dev/null", { encoding: "utf8", timeout: 3e3 });
|
|
21096
21171
|
state.running = ps.trim().length > 0;
|
|
21097
21172
|
} catch {
|
|
21098
21173
|
state.running = false;
|
|
@@ -21569,10 +21644,10 @@ var init_Gateway = __esm({
|
|
|
21569
21644
|
});
|
|
21570
21645
|
|
|
21571
21646
|
// src/tui/utils/agent-status.ts
|
|
21572
|
-
import { execSync as
|
|
21647
|
+
import { execSync as execSync13 } from "child_process";
|
|
21573
21648
|
function getAgentStatus(agentId) {
|
|
21574
21649
|
try {
|
|
21575
|
-
const sessions =
|
|
21650
|
+
const sessions = execSync13("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
|
|
21576
21651
|
encoding: "utf8",
|
|
21577
21652
|
timeout: 2e3
|
|
21578
21653
|
}).trim().split("\n");
|
|
@@ -21583,7 +21658,7 @@ function getAgentStatus(agentId) {
|
|
|
21583
21658
|
return /^\d?-/.test(suffix) || /^\d+$/.test(suffix);
|
|
21584
21659
|
});
|
|
21585
21660
|
if (!agentSession) return { label: "offline", color: "gray" };
|
|
21586
|
-
const pane =
|
|
21661
|
+
const pane = execSync13(`tmux capture-pane -t "${agentSession}" -p 2>/dev/null | tail -3`, {
|
|
21587
21662
|
encoding: "utf8",
|
|
21588
21663
|
timeout: 2e3
|
|
21589
21664
|
});
|
|
@@ -22548,8 +22623,8 @@ function SettingsView({ onBack }) {
|
|
|
22548
22623
|
};
|
|
22549
22624
|
});
|
|
22550
22625
|
try {
|
|
22551
|
-
const { execSync:
|
|
22552
|
-
|
|
22626
|
+
const { execSync: execSync14 } = await import("child_process");
|
|
22627
|
+
execSync14("curl -s --max-time 1 http://localhost:11434/api/tags", { timeout: 2e3 });
|
|
22553
22628
|
providerList.push({ name: "Ollama", configured: true, detail: "localhost:11434" });
|
|
22554
22629
|
} catch {
|
|
22555
22630
|
providerList.push({ name: "Ollama", configured: false, detail: "not running" });
|
|
@@ -23196,7 +23271,7 @@ Unhandled rejection: ${reason}
|
|
|
23196
23271
|
});
|
|
23197
23272
|
|
|
23198
23273
|
// src/bin/cli.ts
|
|
23199
|
-
import { existsSync as existsSync21, readFileSync as readFileSync17, writeFileSync as
|
|
23274
|
+
import { existsSync as existsSync21, readFileSync as readFileSync17, writeFileSync as writeFileSync10, readdirSync as readdirSync5, rmSync } from "fs";
|
|
23200
23275
|
import path33 from "path";
|
|
23201
23276
|
import os11 from "os";
|
|
23202
23277
|
var args = process.argv.slice(2);
|
|
@@ -23424,7 +23499,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
23424
23499
|
permCount = before - settings.permissions.allow.length;
|
|
23425
23500
|
}
|
|
23426
23501
|
if (!dryRun) {
|
|
23427
|
-
|
|
23502
|
+
writeFileSync10(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
23428
23503
|
}
|
|
23429
23504
|
log("\u2713 Removed exe-os hooks from settings.json");
|
|
23430
23505
|
if (permCount > 0) log(`\u2713 Removed ${permCount} MCP permission entries`);
|
|
@@ -23453,7 +23528,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
23453
23528
|
}
|
|
23454
23529
|
if (removedMcp) {
|
|
23455
23530
|
if (!dryRun) {
|
|
23456
|
-
|
|
23531
|
+
writeFileSync10(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
23457
23532
|
}
|
|
23458
23533
|
log("\u2713 Removed exe-os MCP server from claude.json");
|
|
23459
23534
|
removed++;
|
|
@@ -23489,7 +23564,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
23489
23564
|
const endIdx = content.indexOf(endMarker);
|
|
23490
23565
|
if (startIdx !== -1 && endIdx !== -1) {
|
|
23491
23566
|
const cleaned = (content.slice(0, startIdx) + content.slice(endIdx + endMarker.length)).replace(/\n{3,}/g, "\n\n").trim() + "\n";
|
|
23492
|
-
if (!dryRun)
|
|
23567
|
+
if (!dryRun) writeFileSync10(claudeMdPath, cleaned);
|
|
23493
23568
|
log("\u2713 Removed orchestration block from CLAUDE.md");
|
|
23494
23569
|
removed++;
|
|
23495
23570
|
}
|
|
@@ -23541,7 +23616,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
23541
23616
|
if (pSettings.permissions.allow.length < before) changed = true;
|
|
23542
23617
|
}
|
|
23543
23618
|
if (changed && !dryRun) {
|
|
23544
|
-
|
|
23619
|
+
writeFileSync10(projSettings, JSON.stringify(pSettings, null, 2) + "\n");
|
|
23545
23620
|
}
|
|
23546
23621
|
if (changed) projectCount++;
|
|
23547
23622
|
} catch {
|
|
@@ -23555,10 +23630,10 @@ async function runClaudeUninstall(flags = []) {
|
|
|
23555
23630
|
}
|
|
23556
23631
|
}
|
|
23557
23632
|
try {
|
|
23558
|
-
const { execSync:
|
|
23633
|
+
const { execSync: execSync14 } = await import("child_process");
|
|
23559
23634
|
const findExeBin3 = () => {
|
|
23560
23635
|
try {
|
|
23561
|
-
return
|
|
23636
|
+
return execSync14(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
|
|
23562
23637
|
} catch {
|
|
23563
23638
|
return null;
|
|
23564
23639
|
}
|