@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
package/dist/gateway/index.js
CHANGED
|
@@ -3366,9 +3366,10 @@ var init_intercom_queue = __esm({
|
|
|
3366
3366
|
|
|
3367
3367
|
// src/lib/employees.ts
|
|
3368
3368
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
3369
|
-
import { existsSync as existsSync7, symlinkSync, readlinkSync, readFileSync as readFileSync6 } from "fs";
|
|
3369
|
+
import { existsSync as existsSync7, symlinkSync, readlinkSync, readFileSync as readFileSync6, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
3370
3370
|
import { execSync as execSync3 } from "child_process";
|
|
3371
3371
|
import path8 from "path";
|
|
3372
|
+
import os6 from "os";
|
|
3372
3373
|
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
3373
3374
|
if (!existsSync7(employeesPath)) return [];
|
|
3374
3375
|
try {
|
|
@@ -3397,7 +3398,7 @@ var init_employees = __esm({
|
|
|
3397
3398
|
});
|
|
3398
3399
|
|
|
3399
3400
|
// src/lib/license.ts
|
|
3400
|
-
import { readFileSync as readFileSync7, writeFileSync as
|
|
3401
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, existsSync as existsSync8, mkdirSync as mkdirSync5 } from "fs";
|
|
3401
3402
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
3402
3403
|
import path9 from "path";
|
|
3403
3404
|
import { jwtVerify, importSPKI } from "jose";
|
|
@@ -3500,11 +3501,11 @@ var init_plan_limits = __esm({
|
|
|
3500
3501
|
// src/lib/notifications.ts
|
|
3501
3502
|
import crypto2 from "crypto";
|
|
3502
3503
|
import path11 from "path";
|
|
3503
|
-
import
|
|
3504
|
+
import os7 from "os";
|
|
3504
3505
|
import {
|
|
3505
3506
|
readFileSync as readFileSync9,
|
|
3506
3507
|
readdirSync as readdirSync2,
|
|
3507
|
-
unlinkSync as
|
|
3508
|
+
unlinkSync as unlinkSync3,
|
|
3508
3509
|
existsSync as existsSync10,
|
|
3509
3510
|
rmdirSync
|
|
3510
3511
|
} from "fs";
|
|
@@ -4025,7 +4026,7 @@ var init_tasks_crud = __esm({
|
|
|
4025
4026
|
|
|
4026
4027
|
// src/lib/tasks-review.ts
|
|
4027
4028
|
import path13 from "path";
|
|
4028
|
-
import { existsSync as existsSync12, readdirSync as readdirSync3, unlinkSync as
|
|
4029
|
+
import { existsSync as existsSync12, readdirSync as readdirSync3, unlinkSync as unlinkSync4 } from "fs";
|
|
4029
4030
|
async function countPendingReviews(sessionScope) {
|
|
4030
4031
|
const client = getClient();
|
|
4031
4032
|
if (sessionScope) {
|
|
@@ -4210,7 +4211,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
4210
4211
|
if (existsSync12(cacheDir)) {
|
|
4211
4212
|
for (const f of readdirSync3(cacheDir)) {
|
|
4212
4213
|
if (f.startsWith("review-notified-")) {
|
|
4213
|
-
|
|
4214
|
+
unlinkSync4(path13.join(cacheDir, f));
|
|
4214
4215
|
}
|
|
4215
4216
|
}
|
|
4216
4217
|
}
|
|
@@ -4816,7 +4817,7 @@ __export(tasks_exports, {
|
|
|
4816
4817
|
writeCheckpoint: () => writeCheckpoint
|
|
4817
4818
|
});
|
|
4818
4819
|
import path16 from "path";
|
|
4819
|
-
import { writeFileSync as
|
|
4820
|
+
import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, unlinkSync as unlinkSync5 } from "fs";
|
|
4820
4821
|
async function createTask(input) {
|
|
4821
4822
|
const result = await createTaskCore(input);
|
|
4822
4823
|
if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
|
|
@@ -4839,10 +4840,10 @@ async function updateTask(input) {
|
|
|
4839
4840
|
const cachePath = path16.join(cacheDir, `current-task-${agent}.json`);
|
|
4840
4841
|
if (input.status === "in_progress") {
|
|
4841
4842
|
mkdirSync6(cacheDir, { recursive: true });
|
|
4842
|
-
|
|
4843
|
+
writeFileSync5(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
4843
4844
|
} else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled") {
|
|
4844
4845
|
try {
|
|
4845
|
-
|
|
4846
|
+
unlinkSync5(cachePath);
|
|
4846
4847
|
} catch {
|
|
4847
4848
|
}
|
|
4848
4849
|
}
|
|
@@ -5284,11 +5285,11 @@ __export(tmux_routing_exports, {
|
|
|
5284
5285
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
5285
5286
|
});
|
|
5286
5287
|
import { execFileSync as execFileSync2, execSync as execSync6 } from "child_process";
|
|
5287
|
-
import { readFileSync as readFileSync11, writeFileSync as
|
|
5288
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, existsSync as existsSync13, appendFileSync } from "fs";
|
|
5288
5289
|
import path17 from "path";
|
|
5289
|
-
import
|
|
5290
|
+
import os8 from "os";
|
|
5290
5291
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
5291
|
-
import { unlinkSync as
|
|
5292
|
+
import { unlinkSync as unlinkSync6 } from "fs";
|
|
5292
5293
|
function spawnLockPath(sessionName) {
|
|
5293
5294
|
return path17.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
5294
5295
|
}
|
|
@@ -5315,12 +5316,12 @@ function acquireSpawnLock2(sessionName) {
|
|
|
5315
5316
|
} catch {
|
|
5316
5317
|
}
|
|
5317
5318
|
}
|
|
5318
|
-
|
|
5319
|
+
writeFileSync6(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
|
|
5319
5320
|
return true;
|
|
5320
5321
|
}
|
|
5321
5322
|
function releaseSpawnLock2(sessionName) {
|
|
5322
5323
|
try {
|
|
5323
|
-
|
|
5324
|
+
unlinkSync6(spawnLockPath(sessionName));
|
|
5324
5325
|
} catch {
|
|
5325
5326
|
}
|
|
5326
5327
|
}
|
|
@@ -5402,7 +5403,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
|
5402
5403
|
}
|
|
5403
5404
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
5404
5405
|
const filePath = path17.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
5405
|
-
|
|
5406
|
+
writeFileSync6(filePath, JSON.stringify({
|
|
5406
5407
|
parentExe: rootExe,
|
|
5407
5408
|
dispatchedBy: dispatchedBy || rootExe,
|
|
5408
5409
|
registeredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -5489,7 +5490,7 @@ function readDebounceState() {
|
|
|
5489
5490
|
function writeDebounceState(state) {
|
|
5490
5491
|
try {
|
|
5491
5492
|
if (!existsSync13(SESSION_CACHE)) mkdirSync7(SESSION_CACHE, { recursive: true });
|
|
5492
|
-
|
|
5493
|
+
writeFileSync6(DEBOUNCE_FILE, JSON.stringify(state));
|
|
5493
5494
|
} catch {
|
|
5494
5495
|
}
|
|
5495
5496
|
}
|
|
@@ -5678,7 +5679,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5678
5679
|
const transport = getTransport();
|
|
5679
5680
|
const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
|
|
5680
5681
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
5681
|
-
const logDir = path17.join(
|
|
5682
|
+
const logDir = path17.join(os8.homedir(), ".exe-os", "session-logs");
|
|
5682
5683
|
const logFile = path17.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
5683
5684
|
if (!existsSync13(logDir)) {
|
|
5684
5685
|
mkdirSync7(logDir, { recursive: true });
|
|
@@ -5694,7 +5695,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5694
5695
|
} catch {
|
|
5695
5696
|
}
|
|
5696
5697
|
try {
|
|
5697
|
-
const claudeJsonPath = path17.join(
|
|
5698
|
+
const claudeJsonPath = path17.join(os8.homedir(), ".claude.json");
|
|
5698
5699
|
let claudeJson = {};
|
|
5699
5700
|
try {
|
|
5700
5701
|
claudeJson = JSON.parse(readFileSync11(claudeJsonPath, "utf8"));
|
|
@@ -5705,11 +5706,11 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5705
5706
|
const trustDir = opts?.cwd ?? projectDir;
|
|
5706
5707
|
if (!projects[trustDir]) projects[trustDir] = {};
|
|
5707
5708
|
projects[trustDir].hasTrustDialogAccepted = true;
|
|
5708
|
-
|
|
5709
|
+
writeFileSync6(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
5709
5710
|
} catch {
|
|
5710
5711
|
}
|
|
5711
5712
|
try {
|
|
5712
|
-
const settingsDir = path17.join(
|
|
5713
|
+
const settingsDir = path17.join(os8.homedir(), ".claude", "projects");
|
|
5713
5714
|
const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
|
|
5714
5715
|
const projSettingsDir = path17.join(settingsDir, normalizedKey);
|
|
5715
5716
|
const settingsPath = path17.join(projSettingsDir, "settings.json");
|
|
@@ -5744,7 +5745,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5744
5745
|
perms.allow = allow;
|
|
5745
5746
|
settings.permissions = perms;
|
|
5746
5747
|
mkdirSync7(projSettingsDir, { recursive: true });
|
|
5747
|
-
|
|
5748
|
+
writeFileSync6(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
5748
5749
|
}
|
|
5749
5750
|
} catch {
|
|
5750
5751
|
}
|
|
@@ -5757,7 +5758,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5757
5758
|
let legacyFallbackWarned = false;
|
|
5758
5759
|
if (!useExeAgent && !useBinSymlink) {
|
|
5759
5760
|
const identityPath = path17.join(
|
|
5760
|
-
|
|
5761
|
+
os8.homedir(),
|
|
5761
5762
|
".exe-os",
|
|
5762
5763
|
"identity",
|
|
5763
5764
|
`${employeeName}.md`
|
|
@@ -5787,7 +5788,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5787
5788
|
}
|
|
5788
5789
|
let sessionContextFlag = "";
|
|
5789
5790
|
try {
|
|
5790
|
-
const ctxDir = path17.join(
|
|
5791
|
+
const ctxDir = path17.join(os8.homedir(), ".exe-os", "session-cache");
|
|
5791
5792
|
mkdirSync7(ctxDir, { recursive: true });
|
|
5792
5793
|
const ctxFile = path17.join(ctxDir, `session-context-${sessionName}.md`);
|
|
5793
5794
|
const ctxContent = [
|
|
@@ -5796,7 +5797,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5796
5797
|
`Your parent exe session is ${exeSession}.`,
|
|
5797
5798
|
`Your employees (if any) use the -${exeSession} suffix (e.g., tom-${exeSession}).`
|
|
5798
5799
|
].join("\n");
|
|
5799
|
-
|
|
5800
|
+
writeFileSync6(ctxFile, ctxContent);
|
|
5800
5801
|
sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
|
|
5801
5802
|
} catch {
|
|
5802
5803
|
}
|
|
@@ -5835,7 +5836,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
5835
5836
|
try {
|
|
5836
5837
|
const mySession = getMySession();
|
|
5837
5838
|
const dispatchInfo = path17.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
|
|
5838
|
-
|
|
5839
|
+
writeFileSync6(dispatchInfo, JSON.stringify({
|
|
5839
5840
|
dispatchedBy: mySession,
|
|
5840
5841
|
rootExe: exeSession,
|
|
5841
5842
|
provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : "anthropic",
|
|
@@ -5898,13 +5899,13 @@ var init_tmux_routing = __esm({
|
|
|
5898
5899
|
init_provider_table();
|
|
5899
5900
|
init_intercom_queue();
|
|
5900
5901
|
init_plan_limits();
|
|
5901
|
-
SPAWN_LOCK_DIR = path17.join(
|
|
5902
|
-
SESSION_CACHE = path17.join(
|
|
5902
|
+
SPAWN_LOCK_DIR = path17.join(os8.homedir(), ".exe-os", "spawn-locks");
|
|
5903
|
+
SESSION_CACHE = path17.join(os8.homedir(), ".exe-os", "session-cache");
|
|
5903
5904
|
BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
|
|
5904
5905
|
VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
|
|
5905
5906
|
VERIFY_PANE_LINES = 200;
|
|
5906
5907
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
5907
|
-
INTERCOM_LOG2 = path17.join(
|
|
5908
|
+
INTERCOM_LOG2 = path17.join(os8.homedir(), ".exe-os", "intercom.log");
|
|
5908
5909
|
DEBOUNCE_FILE = path17.join(SESSION_CACHE, "intercom-debounce.json");
|
|
5909
5910
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
5910
5911
|
BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
|
|
@@ -9763,11 +9764,11 @@ async function ensureCRMContact(info) {
|
|
|
9763
9764
|
}
|
|
9764
9765
|
|
|
9765
9766
|
// src/automation/trigger-engine.ts
|
|
9766
|
-
import { readFileSync as readFileSync12, writeFileSync as
|
|
9767
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, existsSync as existsSync14, mkdirSync as mkdirSync8 } from "fs";
|
|
9767
9768
|
import { randomUUID as randomUUID12 } from "crypto";
|
|
9768
9769
|
import path18 from "path";
|
|
9769
|
-
import
|
|
9770
|
-
var TRIGGERS_PATH = path18.join(
|
|
9770
|
+
import os9 from "os";
|
|
9771
|
+
var TRIGGERS_PATH = path18.join(os9.homedir(), ".exe-os", "triggers.json");
|
|
9771
9772
|
var GRAPH_API_VERSION = "v21.0";
|
|
9772
9773
|
function substituteTemplate(template, record) {
|
|
9773
9774
|
return template.replace(
|
|
@@ -1954,14 +1954,16 @@ __export(employees_exports, {
|
|
|
1954
1954
|
isMultiInstance: () => isMultiInstance,
|
|
1955
1955
|
loadEmployees: () => loadEmployees,
|
|
1956
1956
|
loadEmployeesSync: () => loadEmployeesSync,
|
|
1957
|
+
normalizeRosterCase: () => normalizeRosterCase,
|
|
1957
1958
|
registerBinSymlinks: () => registerBinSymlinks,
|
|
1958
1959
|
saveEmployees: () => saveEmployees,
|
|
1959
1960
|
validateEmployeeName: () => validateEmployeeName
|
|
1960
1961
|
});
|
|
1961
1962
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
1962
|
-
import { existsSync as existsSync7, symlinkSync, readlinkSync, readFileSync as readFileSync5 } from "fs";
|
|
1963
|
+
import { existsSync as existsSync7, symlinkSync, readlinkSync, readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
1963
1964
|
import { execSync as execSync3 } from "child_process";
|
|
1964
1965
|
import path7 from "path";
|
|
1966
|
+
import os6 from "os";
|
|
1965
1967
|
function validateEmployeeName(name) {
|
|
1966
1968
|
if (!name) {
|
|
1967
1969
|
return { valid: false, error: "Name is required" };
|
|
@@ -2029,6 +2031,36 @@ function addEmployee(employees, employee) {
|
|
|
2029
2031
|
}
|
|
2030
2032
|
return [...employees, normalized];
|
|
2031
2033
|
}
|
|
2034
|
+
async function normalizeRosterCase(rosterPath) {
|
|
2035
|
+
const employees = await loadEmployees(rosterPath);
|
|
2036
|
+
let changed = false;
|
|
2037
|
+
for (const emp of employees) {
|
|
2038
|
+
if (emp.name !== emp.name.toLowerCase()) {
|
|
2039
|
+
const oldName = emp.name;
|
|
2040
|
+
emp.name = emp.name.toLowerCase();
|
|
2041
|
+
changed = true;
|
|
2042
|
+
try {
|
|
2043
|
+
const identityDir = path7.join(os6.homedir(), ".exe-os", "identity");
|
|
2044
|
+
const oldPath = path7.join(identityDir, `${oldName}.md`);
|
|
2045
|
+
const newPath = path7.join(identityDir, `${emp.name}.md`);
|
|
2046
|
+
if (existsSync7(oldPath) && !existsSync7(newPath)) {
|
|
2047
|
+
renameSync3(oldPath, newPath);
|
|
2048
|
+
} else if (existsSync7(oldPath) && oldPath !== newPath) {
|
|
2049
|
+
const content = readFileSync5(oldPath, "utf-8");
|
|
2050
|
+
writeFileSync3(newPath, content, "utf-8");
|
|
2051
|
+
if (oldPath.toLowerCase() !== newPath.toLowerCase()) {
|
|
2052
|
+
unlinkSync2(oldPath);
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
} catch {
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
2059
|
+
if (changed) {
|
|
2060
|
+
await saveEmployees(employees, rosterPath);
|
|
2061
|
+
}
|
|
2062
|
+
return changed;
|
|
2063
|
+
}
|
|
2032
2064
|
function findExeBin() {
|
|
2033
2065
|
try {
|
|
2034
2066
|
return execSync3(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
|
|
@@ -2080,7 +2112,7 @@ var init_employees = __esm({
|
|
|
2080
2112
|
});
|
|
2081
2113
|
|
|
2082
2114
|
// src/lib/license.ts
|
|
2083
|
-
import { readFileSync as readFileSync6, writeFileSync as
|
|
2115
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
|
|
2084
2116
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2085
2117
|
import path8 from "path";
|
|
2086
2118
|
import { jwtVerify, importSPKI } from "jose";
|
|
@@ -2523,11 +2555,11 @@ __export(tmux_routing_exports, {
|
|
|
2523
2555
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
2524
2556
|
});
|
|
2525
2557
|
import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
|
|
2526
|
-
import { readFileSync as readFileSync8, writeFileSync as
|
|
2558
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync10, appendFileSync } from "fs";
|
|
2527
2559
|
import path10 from "path";
|
|
2528
|
-
import
|
|
2560
|
+
import os7 from "os";
|
|
2529
2561
|
import { fileURLToPath } from "url";
|
|
2530
|
-
import { unlinkSync as
|
|
2562
|
+
import { unlinkSync as unlinkSync3 } from "fs";
|
|
2531
2563
|
function spawnLockPath(sessionName) {
|
|
2532
2564
|
return path10.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
2533
2565
|
}
|
|
@@ -2554,12 +2586,12 @@ function acquireSpawnLock(sessionName) {
|
|
|
2554
2586
|
} catch {
|
|
2555
2587
|
}
|
|
2556
2588
|
}
|
|
2557
|
-
|
|
2589
|
+
writeFileSync5(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
|
|
2558
2590
|
return true;
|
|
2559
2591
|
}
|
|
2560
2592
|
function releaseSpawnLock(sessionName) {
|
|
2561
2593
|
try {
|
|
2562
|
-
|
|
2594
|
+
unlinkSync3(spawnLockPath(sessionName));
|
|
2563
2595
|
} catch {
|
|
2564
2596
|
}
|
|
2565
2597
|
}
|
|
@@ -2641,7 +2673,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
|
2641
2673
|
}
|
|
2642
2674
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
2643
2675
|
const filePath = path10.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
2644
|
-
|
|
2676
|
+
writeFileSync5(filePath, JSON.stringify({
|
|
2645
2677
|
parentExe: rootExe,
|
|
2646
2678
|
dispatchedBy: dispatchedBy || rootExe,
|
|
2647
2679
|
registeredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -2728,7 +2760,7 @@ function readDebounceState() {
|
|
|
2728
2760
|
function writeDebounceState(state) {
|
|
2729
2761
|
try {
|
|
2730
2762
|
if (!existsSync10(SESSION_CACHE)) mkdirSync5(SESSION_CACHE, { recursive: true });
|
|
2731
|
-
|
|
2763
|
+
writeFileSync5(DEBOUNCE_FILE, JSON.stringify(state));
|
|
2732
2764
|
} catch {
|
|
2733
2765
|
}
|
|
2734
2766
|
}
|
|
@@ -2917,7 +2949,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
2917
2949
|
const transport = getTransport();
|
|
2918
2950
|
const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
|
|
2919
2951
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
2920
|
-
const logDir = path10.join(
|
|
2952
|
+
const logDir = path10.join(os7.homedir(), ".exe-os", "session-logs");
|
|
2921
2953
|
const logFile = path10.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
2922
2954
|
if (!existsSync10(logDir)) {
|
|
2923
2955
|
mkdirSync5(logDir, { recursive: true });
|
|
@@ -2933,7 +2965,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
2933
2965
|
} catch {
|
|
2934
2966
|
}
|
|
2935
2967
|
try {
|
|
2936
|
-
const claudeJsonPath = path10.join(
|
|
2968
|
+
const claudeJsonPath = path10.join(os7.homedir(), ".claude.json");
|
|
2937
2969
|
let claudeJson = {};
|
|
2938
2970
|
try {
|
|
2939
2971
|
claudeJson = JSON.parse(readFileSync8(claudeJsonPath, "utf8"));
|
|
@@ -2944,11 +2976,11 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
2944
2976
|
const trustDir = opts?.cwd ?? projectDir;
|
|
2945
2977
|
if (!projects[trustDir]) projects[trustDir] = {};
|
|
2946
2978
|
projects[trustDir].hasTrustDialogAccepted = true;
|
|
2947
|
-
|
|
2979
|
+
writeFileSync5(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
2948
2980
|
} catch {
|
|
2949
2981
|
}
|
|
2950
2982
|
try {
|
|
2951
|
-
const settingsDir = path10.join(
|
|
2983
|
+
const settingsDir = path10.join(os7.homedir(), ".claude", "projects");
|
|
2952
2984
|
const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
|
|
2953
2985
|
const projSettingsDir = path10.join(settingsDir, normalizedKey);
|
|
2954
2986
|
const settingsPath = path10.join(projSettingsDir, "settings.json");
|
|
@@ -2983,7 +3015,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
2983
3015
|
perms.allow = allow;
|
|
2984
3016
|
settings.permissions = perms;
|
|
2985
3017
|
mkdirSync5(projSettingsDir, { recursive: true });
|
|
2986
|
-
|
|
3018
|
+
writeFileSync5(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
2987
3019
|
}
|
|
2988
3020
|
} catch {
|
|
2989
3021
|
}
|
|
@@ -2996,7 +3028,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
2996
3028
|
let legacyFallbackWarned = false;
|
|
2997
3029
|
if (!useExeAgent && !useBinSymlink) {
|
|
2998
3030
|
const identityPath = path10.join(
|
|
2999
|
-
|
|
3031
|
+
os7.homedir(),
|
|
3000
3032
|
".exe-os",
|
|
3001
3033
|
"identity",
|
|
3002
3034
|
`${employeeName}.md`
|
|
@@ -3026,7 +3058,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3026
3058
|
}
|
|
3027
3059
|
let sessionContextFlag = "";
|
|
3028
3060
|
try {
|
|
3029
|
-
const ctxDir = path10.join(
|
|
3061
|
+
const ctxDir = path10.join(os7.homedir(), ".exe-os", "session-cache");
|
|
3030
3062
|
mkdirSync5(ctxDir, { recursive: true });
|
|
3031
3063
|
const ctxFile = path10.join(ctxDir, `session-context-${sessionName}.md`);
|
|
3032
3064
|
const ctxContent = [
|
|
@@ -3035,7 +3067,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3035
3067
|
`Your parent exe session is ${exeSession}.`,
|
|
3036
3068
|
`Your employees (if any) use the -${exeSession} suffix (e.g., tom-${exeSession}).`
|
|
3037
3069
|
].join("\n");
|
|
3038
|
-
|
|
3070
|
+
writeFileSync5(ctxFile, ctxContent);
|
|
3039
3071
|
sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
|
|
3040
3072
|
} catch {
|
|
3041
3073
|
}
|
|
@@ -3074,7 +3106,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3074
3106
|
try {
|
|
3075
3107
|
const mySession = getMySession();
|
|
3076
3108
|
const dispatchInfo = path10.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
|
|
3077
|
-
|
|
3109
|
+
writeFileSync5(dispatchInfo, JSON.stringify({
|
|
3078
3110
|
dispatchedBy: mySession,
|
|
3079
3111
|
rootExe: exeSession,
|
|
3080
3112
|
provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : "anthropic",
|
|
@@ -3137,13 +3169,13 @@ var init_tmux_routing = __esm({
|
|
|
3137
3169
|
init_provider_table();
|
|
3138
3170
|
init_intercom_queue();
|
|
3139
3171
|
init_plan_limits();
|
|
3140
|
-
SPAWN_LOCK_DIR = path10.join(
|
|
3141
|
-
SESSION_CACHE = path10.join(
|
|
3172
|
+
SPAWN_LOCK_DIR = path10.join(os7.homedir(), ".exe-os", "spawn-locks");
|
|
3173
|
+
SESSION_CACHE = path10.join(os7.homedir(), ".exe-os", "session-cache");
|
|
3142
3174
|
BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
|
|
3143
3175
|
VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
|
|
3144
3176
|
VERIFY_PANE_LINES = 200;
|
|
3145
3177
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
3146
|
-
INTERCOM_LOG2 = path10.join(
|
|
3178
|
+
INTERCOM_LOG2 = path10.join(os7.homedir(), ".exe-os", "intercom.log");
|
|
3147
3179
|
DEBOUNCE_FILE = path10.join(SESSION_CACHE, "intercom-debounce.json");
|
|
3148
3180
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
3149
3181
|
BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
|
|
@@ -3592,7 +3624,7 @@ var init_tasks_crud = __esm({
|
|
|
3592
3624
|
|
|
3593
3625
|
// src/lib/tasks-review.ts
|
|
3594
3626
|
import path12 from "path";
|
|
3595
|
-
import { existsSync as existsSync12, readdirSync as readdirSync3, unlinkSync as
|
|
3627
|
+
import { existsSync as existsSync12, readdirSync as readdirSync3, unlinkSync as unlinkSync4 } from "fs";
|
|
3596
3628
|
async function countPendingReviews(sessionScope) {
|
|
3597
3629
|
const client = getClient();
|
|
3598
3630
|
if (sessionScope) {
|
|
@@ -3777,7 +3809,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
3777
3809
|
if (existsSync12(cacheDir)) {
|
|
3778
3810
|
for (const f of readdirSync3(cacheDir)) {
|
|
3779
3811
|
if (f.startsWith("review-notified-")) {
|
|
3780
|
-
|
|
3812
|
+
unlinkSync4(path12.join(cacheDir, f));
|
|
3781
3813
|
}
|
|
3782
3814
|
}
|
|
3783
3815
|
}
|
|
@@ -4383,7 +4415,7 @@ __export(tasks_exports, {
|
|
|
4383
4415
|
writeCheckpoint: () => writeCheckpoint
|
|
4384
4416
|
});
|
|
4385
4417
|
import path15 from "path";
|
|
4386
|
-
import { writeFileSync as
|
|
4418
|
+
import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, unlinkSync as unlinkSync5 } from "fs";
|
|
4387
4419
|
async function createTask(input) {
|
|
4388
4420
|
const result = await createTaskCore(input);
|
|
4389
4421
|
if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
|
|
@@ -4406,10 +4438,10 @@ async function updateTask(input) {
|
|
|
4406
4438
|
const cachePath = path15.join(cacheDir, `current-task-${agent}.json`);
|
|
4407
4439
|
if (input.status === "in_progress") {
|
|
4408
4440
|
mkdirSync6(cacheDir, { recursive: true });
|
|
4409
|
-
|
|
4441
|
+
writeFileSync6(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
4410
4442
|
} else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled") {
|
|
4411
4443
|
try {
|
|
4412
|
-
|
|
4444
|
+
unlinkSync5(cachePath);
|
|
4413
4445
|
} catch {
|
|
4414
4446
|
}
|
|
4415
4447
|
}
|