@askexenow/exe-os 0.8.65 → 0.8.69
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/cleanup-stale-review-tasks.js +8 -7
- package/dist/bin/cli.js +204 -120
- package/dist/bin/exe-assign.js +11 -10
- package/dist/bin/exe-boot.js +83 -78
- package/dist/bin/exe-call.js +33 -1
- package/dist/bin/exe-cloud.js +3 -2
- package/dist/bin/exe-dispatch.js +31 -30
- package/dist/bin/exe-gateway.js +33 -32
- package/dist/bin/exe-heartbeat.js +21 -20
- package/dist/bin/exe-launch-agent.js +84 -19
- package/dist/bin/exe-link.js +16 -11
- package/dist/bin/exe-new-employee.js +20 -19
- package/dist/bin/exe-pending-messages.js +7 -6
- package/dist/bin/exe-pending-reviews.js +16 -15
- package/dist/bin/exe-rename.js +12 -11
- package/dist/bin/exe-review.js +4 -3
- package/dist/bin/exe-session-cleanup.js +20 -19
- package/dist/bin/exe-settings.js +3 -2
- package/dist/bin/exe-status.js +16 -15
- package/dist/bin/exe-team.js +4 -3
- package/dist/bin/git-sweep.js +31 -30
- package/dist/bin/install.js +284 -113
- package/dist/bin/scan-tasks.js +33 -32
- package/dist/bin/setup.js +114 -30
- package/dist/gateway/index.js +32 -31
- package/dist/hooks/bug-report-worker.js +58 -26
- package/dist/hooks/commit-complete.js +31 -30
- package/dist/hooks/ingest-worker.js +58 -57
- package/dist/hooks/post-compact.js +10 -9
- package/dist/hooks/pre-compact.js +31 -30
- package/dist/hooks/pre-tool-use.js +46 -14
- package/dist/hooks/prompt-ingest-worker.js +15 -14
- package/dist/hooks/prompt-submit.js +15 -14
- package/dist/hooks/response-ingest-worker.js +8 -7
- package/dist/hooks/session-end.js +14 -13
- package/dist/hooks/session-start.js +10 -9
- package/dist/hooks/stop.js +10 -9
- package/dist/hooks/subagent-stop.js +10 -9
- package/dist/hooks/summary-worker.js +41 -36
- package/dist/index.js +43 -42
- package/dist/lib/cloud-sync.js +16 -11
- package/dist/lib/employees.js +33 -1
- package/dist/lib/exe-daemon.js +56 -55
- package/dist/lib/messaging.js +9 -8
- package/dist/lib/tasks.js +27 -26
- package/dist/lib/tmux-routing.js +29 -28
- package/dist/mcp/server.js +94 -62
- package/dist/mcp/tools/create-task.js +60 -28
- package/dist/mcp/tools/list-tasks.js +10 -9
- package/dist/mcp/tools/send-message.js +11 -10
- package/dist/mcp/tools/update-task.js +21 -20
- package/dist/runtime/index.js +31 -30
- package/dist/tui/App.js +67 -35
- package/package.json +1 -1
|
@@ -1437,9 +1437,10 @@ var init_config = __esm({
|
|
|
1437
1437
|
|
|
1438
1438
|
// src/lib/employees.ts
|
|
1439
1439
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
1440
|
-
import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync4 } from "fs";
|
|
1440
|
+
import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync4, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
1441
1441
|
import { execSync as execSync3 } from "child_process";
|
|
1442
1442
|
import path4 from "path";
|
|
1443
|
+
import os4 from "os";
|
|
1443
1444
|
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
1444
1445
|
if (!existsSync4(employeesPath)) return [];
|
|
1445
1446
|
try {
|
|
@@ -1468,7 +1469,7 @@ var init_employees = __esm({
|
|
|
1468
1469
|
});
|
|
1469
1470
|
|
|
1470
1471
|
// src/lib/license.ts
|
|
1471
|
-
import { readFileSync as readFileSync5, writeFileSync as
|
|
1472
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
|
|
1472
1473
|
import { randomUUID } from "crypto";
|
|
1473
1474
|
import path5 from "path";
|
|
1474
1475
|
import { jwtVerify, importSPKI } from "jose";
|
|
@@ -1571,11 +1572,11 @@ var init_plan_limits = __esm({
|
|
|
1571
1572
|
// src/lib/notifications.ts
|
|
1572
1573
|
import crypto from "crypto";
|
|
1573
1574
|
import path7 from "path";
|
|
1574
|
-
import
|
|
1575
|
+
import os5 from "os";
|
|
1575
1576
|
import {
|
|
1576
1577
|
readFileSync as readFileSync7,
|
|
1577
1578
|
readdirSync,
|
|
1578
|
-
unlinkSync,
|
|
1579
|
+
unlinkSync as unlinkSync2,
|
|
1579
1580
|
existsSync as existsSync7,
|
|
1580
1581
|
rmdirSync
|
|
1581
1582
|
} from "fs";
|
|
@@ -2142,7 +2143,7 @@ var init_tasks_crud = __esm({
|
|
|
2142
2143
|
|
|
2143
2144
|
// src/lib/tasks-review.ts
|
|
2144
2145
|
import path9 from "path";
|
|
2145
|
-
import { existsSync as existsSync9, readdirSync as readdirSync2, unlinkSync as
|
|
2146
|
+
import { existsSync as existsSync9, readdirSync as readdirSync2, unlinkSync as unlinkSync3 } from "fs";
|
|
2146
2147
|
async function countPendingReviews(sessionScope) {
|
|
2147
2148
|
const client = getClient();
|
|
2148
2149
|
if (sessionScope) {
|
|
@@ -2327,7 +2328,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
2327
2328
|
if (existsSync9(cacheDir)) {
|
|
2328
2329
|
for (const f of readdirSync2(cacheDir)) {
|
|
2329
2330
|
if (f.startsWith("review-notified-")) {
|
|
2330
|
-
|
|
2331
|
+
unlinkSync3(path9.join(cacheDir, f));
|
|
2331
2332
|
}
|
|
2332
2333
|
}
|
|
2333
2334
|
}
|
|
@@ -2933,7 +2934,7 @@ __export(tasks_exports, {
|
|
|
2933
2934
|
writeCheckpoint: () => writeCheckpoint
|
|
2934
2935
|
});
|
|
2935
2936
|
import path12 from "path";
|
|
2936
|
-
import { writeFileSync as
|
|
2937
|
+
import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, unlinkSync as unlinkSync4 } from "fs";
|
|
2937
2938
|
async function createTask(input) {
|
|
2938
2939
|
const result = await createTaskCore(input);
|
|
2939
2940
|
if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
|
|
@@ -2956,10 +2957,10 @@ async function updateTask(input) {
|
|
|
2956
2957
|
const cachePath = path12.join(cacheDir, `current-task-${agent}.json`);
|
|
2957
2958
|
if (input.status === "in_progress") {
|
|
2958
2959
|
mkdirSync4(cacheDir, { recursive: true });
|
|
2959
|
-
|
|
2960
|
+
writeFileSync5(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
2960
2961
|
} else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled") {
|
|
2961
2962
|
try {
|
|
2962
|
-
|
|
2963
|
+
unlinkSync4(cachePath);
|
|
2963
2964
|
} catch {
|
|
2964
2965
|
}
|
|
2965
2966
|
}
|
|
@@ -3401,11 +3402,11 @@ __export(tmux_routing_exports, {
|
|
|
3401
3402
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
3402
3403
|
});
|
|
3403
3404
|
import { execFileSync as execFileSync2, execSync as execSync6 } from "child_process";
|
|
3404
|
-
import { readFileSync as readFileSync9, writeFileSync as
|
|
3405
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync10, appendFileSync } from "fs";
|
|
3405
3406
|
import path13 from "path";
|
|
3406
|
-
import
|
|
3407
|
+
import os6 from "os";
|
|
3407
3408
|
import { fileURLToPath } from "url";
|
|
3408
|
-
import { unlinkSync as
|
|
3409
|
+
import { unlinkSync as unlinkSync5 } from "fs";
|
|
3409
3410
|
function spawnLockPath(sessionName) {
|
|
3410
3411
|
return path13.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
3411
3412
|
}
|
|
@@ -3432,12 +3433,12 @@ function acquireSpawnLock(sessionName) {
|
|
|
3432
3433
|
} catch {
|
|
3433
3434
|
}
|
|
3434
3435
|
}
|
|
3435
|
-
|
|
3436
|
+
writeFileSync6(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
|
|
3436
3437
|
return true;
|
|
3437
3438
|
}
|
|
3438
3439
|
function releaseSpawnLock(sessionName) {
|
|
3439
3440
|
try {
|
|
3440
|
-
|
|
3441
|
+
unlinkSync5(spawnLockPath(sessionName));
|
|
3441
3442
|
} catch {
|
|
3442
3443
|
}
|
|
3443
3444
|
}
|
|
@@ -3519,7 +3520,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
|
3519
3520
|
}
|
|
3520
3521
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
3521
3522
|
const filePath = path13.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
3522
|
-
|
|
3523
|
+
writeFileSync6(filePath, JSON.stringify({
|
|
3523
3524
|
parentExe: rootExe,
|
|
3524
3525
|
dispatchedBy: dispatchedBy || rootExe,
|
|
3525
3526
|
registeredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -3606,7 +3607,7 @@ function readDebounceState() {
|
|
|
3606
3607
|
function writeDebounceState(state) {
|
|
3607
3608
|
try {
|
|
3608
3609
|
if (!existsSync10(SESSION_CACHE)) mkdirSync5(SESSION_CACHE, { recursive: true });
|
|
3609
|
-
|
|
3610
|
+
writeFileSync6(DEBOUNCE_FILE, JSON.stringify(state));
|
|
3610
3611
|
} catch {
|
|
3611
3612
|
}
|
|
3612
3613
|
}
|
|
@@ -3795,7 +3796,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3795
3796
|
const transport = getTransport();
|
|
3796
3797
|
const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
|
|
3797
3798
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
3798
|
-
const logDir = path13.join(
|
|
3799
|
+
const logDir = path13.join(os6.homedir(), ".exe-os", "session-logs");
|
|
3799
3800
|
const logFile = path13.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
3800
3801
|
if (!existsSync10(logDir)) {
|
|
3801
3802
|
mkdirSync5(logDir, { recursive: true });
|
|
@@ -3811,7 +3812,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3811
3812
|
} catch {
|
|
3812
3813
|
}
|
|
3813
3814
|
try {
|
|
3814
|
-
const claudeJsonPath = path13.join(
|
|
3815
|
+
const claudeJsonPath = path13.join(os6.homedir(), ".claude.json");
|
|
3815
3816
|
let claudeJson = {};
|
|
3816
3817
|
try {
|
|
3817
3818
|
claudeJson = JSON.parse(readFileSync9(claudeJsonPath, "utf8"));
|
|
@@ -3822,11 +3823,11 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3822
3823
|
const trustDir = opts?.cwd ?? projectDir;
|
|
3823
3824
|
if (!projects[trustDir]) projects[trustDir] = {};
|
|
3824
3825
|
projects[trustDir].hasTrustDialogAccepted = true;
|
|
3825
|
-
|
|
3826
|
+
writeFileSync6(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
3826
3827
|
} catch {
|
|
3827
3828
|
}
|
|
3828
3829
|
try {
|
|
3829
|
-
const settingsDir = path13.join(
|
|
3830
|
+
const settingsDir = path13.join(os6.homedir(), ".claude", "projects");
|
|
3830
3831
|
const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
|
|
3831
3832
|
const projSettingsDir = path13.join(settingsDir, normalizedKey);
|
|
3832
3833
|
const settingsPath = path13.join(projSettingsDir, "settings.json");
|
|
@@ -3861,7 +3862,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3861
3862
|
perms.allow = allow;
|
|
3862
3863
|
settings.permissions = perms;
|
|
3863
3864
|
mkdirSync5(projSettingsDir, { recursive: true });
|
|
3864
|
-
|
|
3865
|
+
writeFileSync6(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
3865
3866
|
}
|
|
3866
3867
|
} catch {
|
|
3867
3868
|
}
|
|
@@ -3874,7 +3875,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3874
3875
|
let legacyFallbackWarned = false;
|
|
3875
3876
|
if (!useExeAgent && !useBinSymlink) {
|
|
3876
3877
|
const identityPath = path13.join(
|
|
3877
|
-
|
|
3878
|
+
os6.homedir(),
|
|
3878
3879
|
".exe-os",
|
|
3879
3880
|
"identity",
|
|
3880
3881
|
`${employeeName}.md`
|
|
@@ -3904,7 +3905,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3904
3905
|
}
|
|
3905
3906
|
let sessionContextFlag = "";
|
|
3906
3907
|
try {
|
|
3907
|
-
const ctxDir = path13.join(
|
|
3908
|
+
const ctxDir = path13.join(os6.homedir(), ".exe-os", "session-cache");
|
|
3908
3909
|
mkdirSync5(ctxDir, { recursive: true });
|
|
3909
3910
|
const ctxFile = path13.join(ctxDir, `session-context-${sessionName}.md`);
|
|
3910
3911
|
const ctxContent = [
|
|
@@ -3913,7 +3914,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3913
3914
|
`Your parent exe session is ${exeSession}.`,
|
|
3914
3915
|
`Your employees (if any) use the -${exeSession} suffix (e.g., tom-${exeSession}).`
|
|
3915
3916
|
].join("\n");
|
|
3916
|
-
|
|
3917
|
+
writeFileSync6(ctxFile, ctxContent);
|
|
3917
3918
|
sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
|
|
3918
3919
|
} catch {
|
|
3919
3920
|
}
|
|
@@ -3952,7 +3953,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3952
3953
|
try {
|
|
3953
3954
|
const mySession = getMySession();
|
|
3954
3955
|
const dispatchInfo = path13.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
|
|
3955
|
-
|
|
3956
|
+
writeFileSync6(dispatchInfo, JSON.stringify({
|
|
3956
3957
|
dispatchedBy: mySession,
|
|
3957
3958
|
rootExe: exeSession,
|
|
3958
3959
|
provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : "anthropic",
|
|
@@ -4015,13 +4016,13 @@ var init_tmux_routing = __esm({
|
|
|
4015
4016
|
init_provider_table();
|
|
4016
4017
|
init_intercom_queue();
|
|
4017
4018
|
init_plan_limits();
|
|
4018
|
-
SPAWN_LOCK_DIR = path13.join(
|
|
4019
|
-
SESSION_CACHE = path13.join(
|
|
4019
|
+
SPAWN_LOCK_DIR = path13.join(os6.homedir(), ".exe-os", "spawn-locks");
|
|
4020
|
+
SESSION_CACHE = path13.join(os6.homedir(), ".exe-os", "session-cache");
|
|
4020
4021
|
BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
|
|
4021
4022
|
VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
|
|
4022
4023
|
VERIFY_PANE_LINES = 200;
|
|
4023
4024
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
4024
|
-
INTERCOM_LOG2 = path13.join(
|
|
4025
|
+
INTERCOM_LOG2 = path13.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
4025
4026
|
DEBOUNCE_FILE = path13.join(SESSION_CACHE, "intercom-debounce.json");
|
|
4026
4027
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
4027
4028
|
BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
|
|
@@ -4065,9 +4066,9 @@ var init_memory = __esm({
|
|
|
4065
4066
|
import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
|
|
4066
4067
|
import { existsSync as existsSync11 } from "fs";
|
|
4067
4068
|
import path14 from "path";
|
|
4068
|
-
import
|
|
4069
|
+
import os7 from "os";
|
|
4069
4070
|
function getKeyDir() {
|
|
4070
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path14.join(
|
|
4071
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path14.join(os7.homedir(), ".exe-os");
|
|
4071
4072
|
}
|
|
4072
4073
|
function getKeyPath() {
|
|
4073
4074
|
return path14.join(getKeyDir(), "master.key");
|
|
@@ -1817,9 +1817,10 @@ var init_notifications = __esm({
|
|
|
1817
1817
|
|
|
1818
1818
|
// src/lib/employees.ts
|
|
1819
1819
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
1820
|
-
import { existsSync as existsSync6, symlinkSync, readlinkSync, readFileSync as readFileSync4 } from "fs";
|
|
1820
|
+
import { existsSync as existsSync6, symlinkSync, readlinkSync, readFileSync as readFileSync4, renameSync as renameSync2, unlinkSync as unlinkSync2, writeFileSync } from "fs";
|
|
1821
1821
|
import { execSync as execSync3 } from "child_process";
|
|
1822
1822
|
import path7 from "path";
|
|
1823
|
+
import os4 from "os";
|
|
1823
1824
|
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
1824
1825
|
if (!existsSync6(employeesPath)) return [];
|
|
1825
1826
|
try {
|
|
@@ -1848,7 +1849,7 @@ var init_employees = __esm({
|
|
|
1848
1849
|
});
|
|
1849
1850
|
|
|
1850
1851
|
// src/lib/license.ts
|
|
1851
|
-
import { readFileSync as readFileSync5, writeFileSync, existsSync as existsSync7, mkdirSync as mkdirSync2 } from "fs";
|
|
1852
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, existsSync as existsSync7, mkdirSync as mkdirSync2 } from "fs";
|
|
1852
1853
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
1853
1854
|
import path8 from "path";
|
|
1854
1855
|
import { jwtVerify, importSPKI } from "jose";
|
|
@@ -1878,7 +1879,7 @@ function loadDeviceId() {
|
|
|
1878
1879
|
}
|
|
1879
1880
|
const id = randomUUID2();
|
|
1880
1881
|
mkdirSync2(EXE_AI_DIR, { recursive: true });
|
|
1881
|
-
|
|
1882
|
+
writeFileSync2(DEVICE_ID_PATH, id, "utf8");
|
|
1882
1883
|
return id;
|
|
1883
1884
|
}
|
|
1884
1885
|
function loadLicense() {
|
|
@@ -1891,7 +1892,7 @@ function loadLicense() {
|
|
|
1891
1892
|
}
|
|
1892
1893
|
function saveLicense(apiKey) {
|
|
1893
1894
|
mkdirSync2(EXE_AI_DIR, { recursive: true });
|
|
1894
|
-
|
|
1895
|
+
writeFileSync2(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
|
|
1895
1896
|
}
|
|
1896
1897
|
async function verifyLicenseJwt(token) {
|
|
1897
1898
|
try {
|
|
@@ -1962,7 +1963,7 @@ function getRawCachedPlan() {
|
|
|
1962
1963
|
}
|
|
1963
1964
|
function cacheResponse(token) {
|
|
1964
1965
|
try {
|
|
1965
|
-
|
|
1966
|
+
writeFileSync2(CACHE_PATH, JSON.stringify({ token }), "utf8");
|
|
1966
1967
|
} catch {
|
|
1967
1968
|
}
|
|
1968
1969
|
}
|
|
@@ -2180,7 +2181,7 @@ var init_plan_limits = __esm({
|
|
|
2180
2181
|
import net from "net";
|
|
2181
2182
|
import { spawn } from "child_process";
|
|
2182
2183
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
2183
|
-
import { existsSync as existsSync9, unlinkSync as
|
|
2184
|
+
import { existsSync as existsSync9, unlinkSync as unlinkSync3, readFileSync as readFileSync7, openSync, closeSync, statSync as statSync2 } from "fs";
|
|
2184
2185
|
import path10 from "path";
|
|
2185
2186
|
import { fileURLToPath } from "url";
|
|
2186
2187
|
function handleData(chunk) {
|
|
@@ -2220,11 +2221,11 @@ function cleanupStaleFiles() {
|
|
|
2220
2221
|
} catch {
|
|
2221
2222
|
}
|
|
2222
2223
|
try {
|
|
2223
|
-
|
|
2224
|
+
unlinkSync3(PID_PATH);
|
|
2224
2225
|
} catch {
|
|
2225
2226
|
}
|
|
2226
2227
|
try {
|
|
2227
|
-
|
|
2228
|
+
unlinkSync3(SOCKET_PATH);
|
|
2228
2229
|
} catch {
|
|
2229
2230
|
}
|
|
2230
2231
|
}
|
|
@@ -2286,7 +2287,7 @@ function acquireSpawnLock() {
|
|
|
2286
2287
|
const stat = statSync2(SPAWN_LOCK_PATH);
|
|
2287
2288
|
if (Date.now() - stat.mtimeMs > SPAWN_LOCK_STALE_MS) {
|
|
2288
2289
|
try {
|
|
2289
|
-
|
|
2290
|
+
unlinkSync3(SPAWN_LOCK_PATH);
|
|
2290
2291
|
} catch {
|
|
2291
2292
|
}
|
|
2292
2293
|
try {
|
|
@@ -2303,7 +2304,7 @@ function acquireSpawnLock() {
|
|
|
2303
2304
|
}
|
|
2304
2305
|
function releaseSpawnLock() {
|
|
2305
2306
|
try {
|
|
2306
|
-
|
|
2307
|
+
unlinkSync3(SPAWN_LOCK_PATH);
|
|
2307
2308
|
} catch {
|
|
2308
2309
|
}
|
|
2309
2310
|
}
|
|
@@ -2434,11 +2435,11 @@ function killAndRespawnDaemon() {
|
|
|
2434
2435
|
_connected = false;
|
|
2435
2436
|
_buffer = "";
|
|
2436
2437
|
try {
|
|
2437
|
-
|
|
2438
|
+
unlinkSync3(PID_PATH);
|
|
2438
2439
|
} catch {
|
|
2439
2440
|
}
|
|
2440
2441
|
try {
|
|
2441
|
-
|
|
2442
|
+
unlinkSync3(SOCKET_PATH);
|
|
2442
2443
|
} catch {
|
|
2443
2444
|
}
|
|
2444
2445
|
spawnDaemon();
|
|
@@ -2586,9 +2587,9 @@ var init_embedder = __esm({
|
|
|
2586
2587
|
});
|
|
2587
2588
|
|
|
2588
2589
|
// src/lib/session-registry.ts
|
|
2589
|
-
import { readFileSync as readFileSync8, writeFileSync as
|
|
2590
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync10 } from "fs";
|
|
2590
2591
|
import path11 from "path";
|
|
2591
|
-
import
|
|
2592
|
+
import os5 from "os";
|
|
2592
2593
|
function registerSession(entry) {
|
|
2593
2594
|
const dir = path11.dirname(REGISTRY_PATH);
|
|
2594
2595
|
if (!existsSync10(dir)) {
|
|
@@ -2601,7 +2602,7 @@ function registerSession(entry) {
|
|
|
2601
2602
|
} else {
|
|
2602
2603
|
sessions.push(entry);
|
|
2603
2604
|
}
|
|
2604
|
-
|
|
2605
|
+
writeFileSync3(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
|
|
2605
2606
|
}
|
|
2606
2607
|
function listSessions() {
|
|
2607
2608
|
try {
|
|
@@ -2615,7 +2616,7 @@ var REGISTRY_PATH;
|
|
|
2615
2616
|
var init_session_registry = __esm({
|
|
2616
2617
|
"src/lib/session-registry.ts"() {
|
|
2617
2618
|
"use strict";
|
|
2618
|
-
REGISTRY_PATH = path11.join(
|
|
2619
|
+
REGISTRY_PATH = path11.join(os5.homedir(), ".exe-os", "session-registry.json");
|
|
2619
2620
|
}
|
|
2620
2621
|
});
|
|
2621
2622
|
|
|
@@ -2812,9 +2813,9 @@ var init_provider_table = __esm({
|
|
|
2812
2813
|
});
|
|
2813
2814
|
|
|
2814
2815
|
// src/lib/intercom-queue.ts
|
|
2815
|
-
import { readFileSync as readFileSync9, writeFileSync as
|
|
2816
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync11, mkdirSync as mkdirSync4 } from "fs";
|
|
2816
2817
|
import path12 from "path";
|
|
2817
|
-
import
|
|
2818
|
+
import os6 from "os";
|
|
2818
2819
|
function ensureDir() {
|
|
2819
2820
|
const dir = path12.dirname(QUEUE_PATH);
|
|
2820
2821
|
if (!existsSync11(dir)) mkdirSync4(dir, { recursive: true });
|
|
@@ -2830,8 +2831,8 @@ function readQueue() {
|
|
|
2830
2831
|
function writeQueue(queue) {
|
|
2831
2832
|
ensureDir();
|
|
2832
2833
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
2833
|
-
|
|
2834
|
-
|
|
2834
|
+
writeFileSync4(tmp, JSON.stringify(queue, null, 2));
|
|
2835
|
+
renameSync3(tmp, QUEUE_PATH);
|
|
2835
2836
|
}
|
|
2836
2837
|
function queueIntercom(targetSession, reason) {
|
|
2837
2838
|
const queue = readQueue();
|
|
@@ -2854,9 +2855,9 @@ var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
|
2854
2855
|
var init_intercom_queue = __esm({
|
|
2855
2856
|
"src/lib/intercom-queue.ts"() {
|
|
2856
2857
|
"use strict";
|
|
2857
|
-
QUEUE_PATH = path12.join(
|
|
2858
|
+
QUEUE_PATH = path12.join(os6.homedir(), ".exe-os", "intercom-queue.json");
|
|
2858
2859
|
TTL_MS = 60 * 60 * 1e3;
|
|
2859
|
-
INTERCOM_LOG = path12.join(
|
|
2860
|
+
INTERCOM_LOG = path12.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
2860
2861
|
}
|
|
2861
2862
|
});
|
|
2862
2863
|
|
|
@@ -3203,11 +3204,11 @@ __export(tmux_routing_exports, {
|
|
|
3203
3204
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
3204
3205
|
});
|
|
3205
3206
|
import { execFileSync as execFileSync2, execSync as execSync6 } from "child_process";
|
|
3206
|
-
import { readFileSync as readFileSync10, writeFileSync as
|
|
3207
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync12, appendFileSync } from "fs";
|
|
3207
3208
|
import path13 from "path";
|
|
3208
|
-
import
|
|
3209
|
+
import os7 from "os";
|
|
3209
3210
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3210
|
-
import { unlinkSync as
|
|
3211
|
+
import { unlinkSync as unlinkSync4 } from "fs";
|
|
3211
3212
|
function spawnLockPath(sessionName) {
|
|
3212
3213
|
return path13.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
3213
3214
|
}
|
|
@@ -3234,12 +3235,12 @@ function acquireSpawnLock2(sessionName) {
|
|
|
3234
3235
|
} catch {
|
|
3235
3236
|
}
|
|
3236
3237
|
}
|
|
3237
|
-
|
|
3238
|
+
writeFileSync5(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
|
|
3238
3239
|
return true;
|
|
3239
3240
|
}
|
|
3240
3241
|
function releaseSpawnLock2(sessionName) {
|
|
3241
3242
|
try {
|
|
3242
|
-
|
|
3243
|
+
unlinkSync4(spawnLockPath(sessionName));
|
|
3243
3244
|
} catch {
|
|
3244
3245
|
}
|
|
3245
3246
|
}
|
|
@@ -3321,7 +3322,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
|
3321
3322
|
}
|
|
3322
3323
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
3323
3324
|
const filePath = path13.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
3324
|
-
|
|
3325
|
+
writeFileSync5(filePath, JSON.stringify({
|
|
3325
3326
|
parentExe: rootExe,
|
|
3326
3327
|
dispatchedBy: dispatchedBy || rootExe,
|
|
3327
3328
|
registeredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -3408,7 +3409,7 @@ function readDebounceState() {
|
|
|
3408
3409
|
function writeDebounceState(state) {
|
|
3409
3410
|
try {
|
|
3410
3411
|
if (!existsSync12(SESSION_CACHE)) mkdirSync5(SESSION_CACHE, { recursive: true });
|
|
3411
|
-
|
|
3412
|
+
writeFileSync5(DEBOUNCE_FILE, JSON.stringify(state));
|
|
3412
3413
|
} catch {
|
|
3413
3414
|
}
|
|
3414
3415
|
}
|
|
@@ -3597,7 +3598,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3597
3598
|
const transport = getTransport();
|
|
3598
3599
|
const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
|
|
3599
3600
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
3600
|
-
const logDir = path13.join(
|
|
3601
|
+
const logDir = path13.join(os7.homedir(), ".exe-os", "session-logs");
|
|
3601
3602
|
const logFile = path13.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
3602
3603
|
if (!existsSync12(logDir)) {
|
|
3603
3604
|
mkdirSync5(logDir, { recursive: true });
|
|
@@ -3613,7 +3614,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3613
3614
|
} catch {
|
|
3614
3615
|
}
|
|
3615
3616
|
try {
|
|
3616
|
-
const claudeJsonPath = path13.join(
|
|
3617
|
+
const claudeJsonPath = path13.join(os7.homedir(), ".claude.json");
|
|
3617
3618
|
let claudeJson = {};
|
|
3618
3619
|
try {
|
|
3619
3620
|
claudeJson = JSON.parse(readFileSync10(claudeJsonPath, "utf8"));
|
|
@@ -3624,11 +3625,11 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3624
3625
|
const trustDir = opts?.cwd ?? projectDir;
|
|
3625
3626
|
if (!projects[trustDir]) projects[trustDir] = {};
|
|
3626
3627
|
projects[trustDir].hasTrustDialogAccepted = true;
|
|
3627
|
-
|
|
3628
|
+
writeFileSync5(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
3628
3629
|
} catch {
|
|
3629
3630
|
}
|
|
3630
3631
|
try {
|
|
3631
|
-
const settingsDir = path13.join(
|
|
3632
|
+
const settingsDir = path13.join(os7.homedir(), ".claude", "projects");
|
|
3632
3633
|
const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
|
|
3633
3634
|
const projSettingsDir = path13.join(settingsDir, normalizedKey);
|
|
3634
3635
|
const settingsPath = path13.join(projSettingsDir, "settings.json");
|
|
@@ -3663,7 +3664,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3663
3664
|
perms.allow = allow;
|
|
3664
3665
|
settings.permissions = perms;
|
|
3665
3666
|
mkdirSync5(projSettingsDir, { recursive: true });
|
|
3666
|
-
|
|
3667
|
+
writeFileSync5(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
3667
3668
|
}
|
|
3668
3669
|
} catch {
|
|
3669
3670
|
}
|
|
@@ -3676,7 +3677,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3676
3677
|
let legacyFallbackWarned = false;
|
|
3677
3678
|
if (!useExeAgent && !useBinSymlink) {
|
|
3678
3679
|
const identityPath = path13.join(
|
|
3679
|
-
|
|
3680
|
+
os7.homedir(),
|
|
3680
3681
|
".exe-os",
|
|
3681
3682
|
"identity",
|
|
3682
3683
|
`${employeeName}.md`
|
|
@@ -3706,7 +3707,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3706
3707
|
}
|
|
3707
3708
|
let sessionContextFlag = "";
|
|
3708
3709
|
try {
|
|
3709
|
-
const ctxDir = path13.join(
|
|
3710
|
+
const ctxDir = path13.join(os7.homedir(), ".exe-os", "session-cache");
|
|
3710
3711
|
mkdirSync5(ctxDir, { recursive: true });
|
|
3711
3712
|
const ctxFile = path13.join(ctxDir, `session-context-${sessionName}.md`);
|
|
3712
3713
|
const ctxContent = [
|
|
@@ -3715,7 +3716,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3715
3716
|
`Your parent exe session is ${exeSession}.`,
|
|
3716
3717
|
`Your employees (if any) use the -${exeSession} suffix (e.g., tom-${exeSession}).`
|
|
3717
3718
|
].join("\n");
|
|
3718
|
-
|
|
3719
|
+
writeFileSync5(ctxFile, ctxContent);
|
|
3719
3720
|
sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
|
|
3720
3721
|
} catch {
|
|
3721
3722
|
}
|
|
@@ -3754,7 +3755,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3754
3755
|
try {
|
|
3755
3756
|
const mySession = getMySession();
|
|
3756
3757
|
const dispatchInfo = path13.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
|
|
3757
|
-
|
|
3758
|
+
writeFileSync5(dispatchInfo, JSON.stringify({
|
|
3758
3759
|
dispatchedBy: mySession,
|
|
3759
3760
|
rootExe: exeSession,
|
|
3760
3761
|
provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : "anthropic",
|
|
@@ -3817,13 +3818,13 @@ var init_tmux_routing = __esm({
|
|
|
3817
3818
|
init_provider_table();
|
|
3818
3819
|
init_intercom_queue();
|
|
3819
3820
|
init_plan_limits();
|
|
3820
|
-
SPAWN_LOCK_DIR = path13.join(
|
|
3821
|
-
SESSION_CACHE = path13.join(
|
|
3821
|
+
SPAWN_LOCK_DIR = path13.join(os7.homedir(), ".exe-os", "spawn-locks");
|
|
3822
|
+
SESSION_CACHE = path13.join(os7.homedir(), ".exe-os", "session-cache");
|
|
3822
3823
|
BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
|
|
3823
3824
|
VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
|
|
3824
3825
|
VERIFY_PANE_LINES = 200;
|
|
3825
3826
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
3826
|
-
INTERCOM_LOG2 = path13.join(
|
|
3827
|
+
INTERCOM_LOG2 = path13.join(os7.homedir(), ".exe-os", "intercom.log");
|
|
3827
3828
|
DEBOUNCE_FILE = path13.join(SESSION_CACHE, "intercom-debounce.json");
|
|
3828
3829
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
3829
3830
|
BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
|
|
@@ -4272,7 +4273,7 @@ var init_tasks_crud = __esm({
|
|
|
4272
4273
|
|
|
4273
4274
|
// src/lib/tasks-review.ts
|
|
4274
4275
|
import path15 from "path";
|
|
4275
|
-
import { existsSync as existsSync14, readdirSync as readdirSync4, unlinkSync as
|
|
4276
|
+
import { existsSync as existsSync14, readdirSync as readdirSync4, unlinkSync as unlinkSync5 } from "fs";
|
|
4276
4277
|
async function countPendingReviews(sessionScope) {
|
|
4277
4278
|
const client = getClient();
|
|
4278
4279
|
if (sessionScope) {
|
|
@@ -4457,7 +4458,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
4457
4458
|
if (existsSync14(cacheDir)) {
|
|
4458
4459
|
for (const f of readdirSync4(cacheDir)) {
|
|
4459
4460
|
if (f.startsWith("review-notified-")) {
|
|
4460
|
-
|
|
4461
|
+
unlinkSync5(path15.join(cacheDir, f));
|
|
4461
4462
|
}
|
|
4462
4463
|
}
|
|
4463
4464
|
}
|
|
@@ -5021,7 +5022,7 @@ __export(tasks_exports, {
|
|
|
5021
5022
|
writeCheckpoint: () => writeCheckpoint
|
|
5022
5023
|
});
|
|
5023
5024
|
import path17 from "path";
|
|
5024
|
-
import { writeFileSync as
|
|
5025
|
+
import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, unlinkSync as unlinkSync6 } from "fs";
|
|
5025
5026
|
async function createTask(input2) {
|
|
5026
5027
|
const result = await createTaskCore(input2);
|
|
5027
5028
|
if (!input2.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
|
|
@@ -5044,10 +5045,10 @@ async function updateTask(input2) {
|
|
|
5044
5045
|
const cachePath = path17.join(cacheDir, `current-task-${agent}.json`);
|
|
5045
5046
|
if (input2.status === "in_progress") {
|
|
5046
5047
|
mkdirSync6(cacheDir, { recursive: true });
|
|
5047
|
-
|
|
5048
|
+
writeFileSync6(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
5048
5049
|
} else if (input2.status === "done" || input2.status === "blocked" || input2.status === "cancelled") {
|
|
5049
5050
|
try {
|
|
5050
|
-
|
|
5051
|
+
unlinkSync6(cachePath);
|
|
5051
5052
|
} catch {
|
|
5052
5053
|
}
|
|
5053
5054
|
}
|
|
@@ -5190,14 +5191,14 @@ __export(worker_gate_exports, {
|
|
|
5190
5191
|
tryAcquireBackfillLock: () => tryAcquireBackfillLock,
|
|
5191
5192
|
tryAcquireWorkerSlot: () => tryAcquireWorkerSlot
|
|
5192
5193
|
});
|
|
5193
|
-
import { readdirSync as readdirSync5, writeFileSync as
|
|
5194
|
+
import { readdirSync as readdirSync5, writeFileSync as writeFileSync7, unlinkSync as unlinkSync7, mkdirSync as mkdirSync7, existsSync as existsSync15 } from "fs";
|
|
5194
5195
|
import path18 from "path";
|
|
5195
5196
|
function tryAcquireWorkerSlot() {
|
|
5196
5197
|
try {
|
|
5197
5198
|
mkdirSync7(WORKER_PID_DIR, { recursive: true });
|
|
5198
5199
|
const reservationId = `res-${process.pid}-${Date.now()}`;
|
|
5199
5200
|
const reservationPath = path18.join(WORKER_PID_DIR, `${reservationId}.pid`);
|
|
5200
|
-
|
|
5201
|
+
writeFileSync7(reservationPath, String(process.pid));
|
|
5201
5202
|
const files = readdirSync5(WORKER_PID_DIR);
|
|
5202
5203
|
let alive = 0;
|
|
5203
5204
|
for (const f of files) {
|
|
@@ -5214,20 +5215,20 @@ function tryAcquireWorkerSlot() {
|
|
|
5214
5215
|
alive++;
|
|
5215
5216
|
} catch {
|
|
5216
5217
|
try {
|
|
5217
|
-
|
|
5218
|
+
unlinkSync7(path18.join(WORKER_PID_DIR, f));
|
|
5218
5219
|
} catch {
|
|
5219
5220
|
}
|
|
5220
5221
|
}
|
|
5221
5222
|
}
|
|
5222
5223
|
if (alive > MAX_CONCURRENT_WORKERS) {
|
|
5223
5224
|
try {
|
|
5224
|
-
|
|
5225
|
+
unlinkSync7(reservationPath);
|
|
5225
5226
|
} catch {
|
|
5226
5227
|
}
|
|
5227
5228
|
return false;
|
|
5228
5229
|
}
|
|
5229
5230
|
try {
|
|
5230
|
-
|
|
5231
|
+
unlinkSync7(reservationPath);
|
|
5231
5232
|
} catch {
|
|
5232
5233
|
}
|
|
5233
5234
|
return true;
|
|
@@ -5238,13 +5239,13 @@ function tryAcquireWorkerSlot() {
|
|
|
5238
5239
|
function registerWorkerPid(pid) {
|
|
5239
5240
|
try {
|
|
5240
5241
|
mkdirSync7(WORKER_PID_DIR, { recursive: true });
|
|
5241
|
-
|
|
5242
|
+
writeFileSync7(path18.join(WORKER_PID_DIR, `worker-${pid}.pid`), String(pid));
|
|
5242
5243
|
} catch {
|
|
5243
5244
|
}
|
|
5244
5245
|
}
|
|
5245
5246
|
function cleanupWorkerPid() {
|
|
5246
5247
|
try {
|
|
5247
|
-
|
|
5248
|
+
unlinkSync7(path18.join(WORKER_PID_DIR, `worker-${process.pid}.pid`));
|
|
5248
5249
|
} catch {
|
|
5249
5250
|
}
|
|
5250
5251
|
}
|
|
@@ -5267,7 +5268,7 @@ function tryAcquireBackfillLock() {
|
|
|
5267
5268
|
} catch {
|
|
5268
5269
|
}
|
|
5269
5270
|
}
|
|
5270
|
-
|
|
5271
|
+
writeFileSync7(BACKFILL_LOCK, String(process.pid));
|
|
5271
5272
|
return true;
|
|
5272
5273
|
} catch {
|
|
5273
5274
|
return true;
|
|
@@ -5275,7 +5276,7 @@ function tryAcquireBackfillLock() {
|
|
|
5275
5276
|
}
|
|
5276
5277
|
function releaseBackfillLock() {
|
|
5277
5278
|
try {
|
|
5278
|
-
|
|
5279
|
+
unlinkSync7(BACKFILL_LOCK);
|
|
5279
5280
|
} catch {
|
|
5280
5281
|
}
|
|
5281
5282
|
}
|
|
@@ -5293,7 +5294,7 @@ var init_worker_gate = __esm({
|
|
|
5293
5294
|
// src/adapters/claude/hooks/ingest-worker.ts
|
|
5294
5295
|
import crypto7 from "crypto";
|
|
5295
5296
|
import { execSync as execSync8 } from "child_process";
|
|
5296
|
-
import { mkdirSync as mkdirSync8, writeFileSync as
|
|
5297
|
+
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
|
|
5297
5298
|
import path19 from "path";
|
|
5298
5299
|
|
|
5299
5300
|
// src/lib/error-detector.ts
|
|
@@ -5998,7 +5999,7 @@ process.stdin.on("end", async () => {
|
|
|
5998
5999
|
try {
|
|
5999
6000
|
const { EXE_AI_DIR: exeDir } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
6000
6001
|
const flagPath = path19.join(exeDir, "session-cache", "needs-backfill");
|
|
6001
|
-
|
|
6002
|
+
writeFileSync8(flagPath, "1");
|
|
6002
6003
|
} catch (err) {
|
|
6003
6004
|
process.stderr.write(`[ingest-worker] backfill flag write failed: ${err instanceof Error ? err.message : String(err)}
|
|
6004
6005
|
`);
|