@askexenow/exe-os 0.8.65 → 0.8.68
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 +48 -16
- 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/bin/cli.js
CHANGED
|
@@ -286,14 +286,16 @@ __export(employees_exports, {
|
|
|
286
286
|
isMultiInstance: () => isMultiInstance,
|
|
287
287
|
loadEmployees: () => loadEmployees,
|
|
288
288
|
loadEmployeesSync: () => loadEmployeesSync,
|
|
289
|
+
normalizeRosterCase: () => normalizeRosterCase,
|
|
289
290
|
registerBinSymlinks: () => registerBinSymlinks,
|
|
290
291
|
saveEmployees: () => saveEmployees,
|
|
291
292
|
validateEmployeeName: () => validateEmployeeName
|
|
292
293
|
});
|
|
293
294
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
294
|
-
import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2 } from "fs";
|
|
295
|
+
import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
295
296
|
import { execSync } from "child_process";
|
|
296
297
|
import path2 from "path";
|
|
298
|
+
import os2 from "os";
|
|
297
299
|
function validateEmployeeName(name) {
|
|
298
300
|
if (!name) {
|
|
299
301
|
return { valid: false, error: "Name is required" };
|
|
@@ -361,6 +363,36 @@ function addEmployee(employees, employee) {
|
|
|
361
363
|
}
|
|
362
364
|
return [...employees, normalized];
|
|
363
365
|
}
|
|
366
|
+
async function normalizeRosterCase(rosterPath) {
|
|
367
|
+
const employees = await loadEmployees(rosterPath);
|
|
368
|
+
let changed = false;
|
|
369
|
+
for (const emp of employees) {
|
|
370
|
+
if (emp.name !== emp.name.toLowerCase()) {
|
|
371
|
+
const oldName = emp.name;
|
|
372
|
+
emp.name = emp.name.toLowerCase();
|
|
373
|
+
changed = true;
|
|
374
|
+
try {
|
|
375
|
+
const identityDir = path2.join(os2.homedir(), ".exe-os", "identity");
|
|
376
|
+
const oldPath = path2.join(identityDir, `${oldName}.md`);
|
|
377
|
+
const newPath = path2.join(identityDir, `${emp.name}.md`);
|
|
378
|
+
if (existsSync2(oldPath) && !existsSync2(newPath)) {
|
|
379
|
+
renameSync2(oldPath, newPath);
|
|
380
|
+
} else if (existsSync2(oldPath) && oldPath !== newPath) {
|
|
381
|
+
const content = readFileSync2(oldPath, "utf-8");
|
|
382
|
+
writeFileSync(newPath, content, "utf-8");
|
|
383
|
+
if (oldPath.toLowerCase() !== newPath.toLowerCase()) {
|
|
384
|
+
unlinkSync(oldPath);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
} catch {
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
if (changed) {
|
|
392
|
+
await saveEmployees(employees, rosterPath);
|
|
393
|
+
}
|
|
394
|
+
return changed;
|
|
395
|
+
}
|
|
364
396
|
function findExeBin() {
|
|
365
397
|
try {
|
|
366
398
|
return execSync(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
|
|
@@ -412,7 +444,7 @@ var init_employees = __esm({
|
|
|
412
444
|
});
|
|
413
445
|
|
|
414
446
|
// src/lib/agent-symlinks.ts
|
|
415
|
-
import
|
|
447
|
+
import os3 from "os";
|
|
416
448
|
import path3 from "path";
|
|
417
449
|
import {
|
|
418
450
|
existsSync as existsSync3,
|
|
@@ -430,7 +462,7 @@ function identitySourcePath(homeDir, agentId) {
|
|
|
430
462
|
function claudeAgentLinkPath(homeDir, agentId) {
|
|
431
463
|
return path3.join(claudeAgentsDir(homeDir), `${agentId}.md`);
|
|
432
464
|
}
|
|
433
|
-
function ensureAgentSymlink(agentId, homeDir =
|
|
465
|
+
function ensureAgentSymlink(agentId, homeDir = os3.homedir()) {
|
|
434
466
|
const target = identitySourcePath(homeDir, agentId);
|
|
435
467
|
const link = claudeAgentLinkPath(homeDir, agentId);
|
|
436
468
|
mkdirSync(claudeAgentsDir(homeDir), { recursive: true });
|
|
@@ -468,7 +500,7 @@ function ensureAgentSymlink(agentId, homeDir = os2.homedir()) {
|
|
|
468
500
|
}
|
|
469
501
|
return { agentId, action: "created", target, link };
|
|
470
502
|
}
|
|
471
|
-
async function ensureAllAgentSymlinks(homeDir =
|
|
503
|
+
async function ensureAllAgentSymlinks(homeDir = os3.homedir()) {
|
|
472
504
|
const employees = await loadEmployees();
|
|
473
505
|
return employees.map((emp) => ensureAgentSymlink(emp.name, homeDir));
|
|
474
506
|
}
|
|
@@ -513,9 +545,9 @@ __export(installer_exports, {
|
|
|
513
545
|
setupTmux: () => setupTmux
|
|
514
546
|
});
|
|
515
547
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
|
|
516
|
-
import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync, copyFileSync, mkdirSync as mkdirSync2 } from "fs";
|
|
548
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2, copyFileSync, mkdirSync as mkdirSync2 } from "fs";
|
|
517
549
|
import path4 from "path";
|
|
518
|
-
import
|
|
550
|
+
import os4 from "os";
|
|
519
551
|
import { execSync as execSync2 } from "child_process";
|
|
520
552
|
import { fileURLToPath } from "url";
|
|
521
553
|
function resolvePackageRoot() {
|
|
@@ -535,7 +567,7 @@ function resolvePackageRoot() {
|
|
|
535
567
|
}
|
|
536
568
|
return path4.resolve(path4.dirname(thisFile), "..", "..", "..");
|
|
537
569
|
}
|
|
538
|
-
async function copySlashCommands(packageRoot, homeDir =
|
|
570
|
+
async function copySlashCommands(packageRoot, homeDir = os4.homedir()) {
|
|
539
571
|
let copied = 0;
|
|
540
572
|
let skipped = 0;
|
|
541
573
|
const skillsBase = path4.join(homeDir, ".claude", "skills");
|
|
@@ -588,7 +620,7 @@ name: ${skillName}
|
|
|
588
620
|
await writeFile3(destPath, content);
|
|
589
621
|
return true;
|
|
590
622
|
}
|
|
591
|
-
async function registerMcpServer(packageRoot, homeDir =
|
|
623
|
+
async function registerMcpServer(packageRoot, homeDir = os4.homedir()) {
|
|
592
624
|
const claudeJsonPath = path4.join(homeDir, ".claude.json");
|
|
593
625
|
let claudeJson = {};
|
|
594
626
|
if (existsSync4(claudeJsonPath)) {
|
|
@@ -620,7 +652,7 @@ async function registerMcpServer(packageRoot, homeDir = os3.homedir()) {
|
|
|
620
652
|
await writeFile3(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
621
653
|
return true;
|
|
622
654
|
}
|
|
623
|
-
async function mergeHooks(packageRoot, homeDir =
|
|
655
|
+
async function mergeHooks(packageRoot, homeDir = os4.homedir()) {
|
|
624
656
|
const settingsPath = path4.join(homeDir, ".claude", "settings.json");
|
|
625
657
|
let settings = {};
|
|
626
658
|
if (existsSync4(settingsPath)) {
|
|
@@ -935,7 +967,7 @@ async function runInstaller(homeDir) {
|
|
|
935
967
|
`Hooks: ${hookResult.added} added, ${hookResult.skipped} unchanged
|
|
936
968
|
`
|
|
937
969
|
);
|
|
938
|
-
const resolvedHome = homeDir ??
|
|
970
|
+
const resolvedHome = homeDir ?? os4.homedir();
|
|
939
971
|
const exeWorkspace = path4.join(resolvedHome, "exe");
|
|
940
972
|
if (!existsSync4(exeWorkspace)) {
|
|
941
973
|
try {
|
|
@@ -964,7 +996,7 @@ exe-os installed successfully.
|
|
|
964
996
|
`);
|
|
965
997
|
}
|
|
966
998
|
function setupTmux(home) {
|
|
967
|
-
const homeDir = home ??
|
|
999
|
+
const homeDir = home ?? os4.homedir();
|
|
968
1000
|
const exeDir = path4.join(homeDir, ".exe-os");
|
|
969
1001
|
const exeTmuxConf = path4.join(exeDir, "tmux.conf");
|
|
970
1002
|
const userTmuxConf = path4.join(homeDir, ".tmux.conf");
|
|
@@ -987,11 +1019,11 @@ function setupTmux(home) {
|
|
|
987
1019
|
process.stderr.write(`exe-os: backed up existing tmux config to ${backupPath}
|
|
988
1020
|
`);
|
|
989
1021
|
}
|
|
990
|
-
|
|
1022
|
+
writeFileSync2(userTmuxConf, `${sourceLine}
|
|
991
1023
|
${existing}`);
|
|
992
1024
|
}
|
|
993
1025
|
} else {
|
|
994
|
-
|
|
1026
|
+
writeFileSync2(userTmuxConf, `# Exe OS tmux defaults \u2014 remove this line to use your own config
|
|
995
1027
|
${sourceLine}
|
|
996
1028
|
`);
|
|
997
1029
|
}
|
|
@@ -1985,9 +2017,9 @@ __export(keychain_exports, {
|
|
|
1985
2017
|
import { readFile as readFile4, writeFile as writeFile4, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
|
|
1986
2018
|
import { existsSync as existsSync5 } from "fs";
|
|
1987
2019
|
import path5 from "path";
|
|
1988
|
-
import
|
|
2020
|
+
import os5 from "os";
|
|
1989
2021
|
function getKeyDir() {
|
|
1990
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path5.join(
|
|
2022
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path5.join(os5.homedir(), ".exe-os");
|
|
1991
2023
|
}
|
|
1992
2024
|
function getKeyPath() {
|
|
1993
2025
|
return path5.join(getKeyDir(), "master.key");
|
|
@@ -3057,7 +3089,7 @@ var init_store = __esm({
|
|
|
3057
3089
|
import net from "net";
|
|
3058
3090
|
import { spawn } from "child_process";
|
|
3059
3091
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
3060
|
-
import { existsSync as existsSync7, unlinkSync, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
|
|
3092
|
+
import { existsSync as existsSync7, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
|
|
3061
3093
|
import path7 from "path";
|
|
3062
3094
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3063
3095
|
function handleData(chunk) {
|
|
@@ -3097,11 +3129,11 @@ function cleanupStaleFiles() {
|
|
|
3097
3129
|
} catch {
|
|
3098
3130
|
}
|
|
3099
3131
|
try {
|
|
3100
|
-
|
|
3132
|
+
unlinkSync2(PID_PATH);
|
|
3101
3133
|
} catch {
|
|
3102
3134
|
}
|
|
3103
3135
|
try {
|
|
3104
|
-
|
|
3136
|
+
unlinkSync2(SOCKET_PATH);
|
|
3105
3137
|
} catch {
|
|
3106
3138
|
}
|
|
3107
3139
|
}
|
|
@@ -3163,7 +3195,7 @@ function acquireSpawnLock() {
|
|
|
3163
3195
|
const stat2 = statSync(SPAWN_LOCK_PATH);
|
|
3164
3196
|
if (Date.now() - stat2.mtimeMs > SPAWN_LOCK_STALE_MS) {
|
|
3165
3197
|
try {
|
|
3166
|
-
|
|
3198
|
+
unlinkSync2(SPAWN_LOCK_PATH);
|
|
3167
3199
|
} catch {
|
|
3168
3200
|
}
|
|
3169
3201
|
try {
|
|
@@ -3180,7 +3212,7 @@ function acquireSpawnLock() {
|
|
|
3180
3212
|
}
|
|
3181
3213
|
function releaseSpawnLock() {
|
|
3182
3214
|
try {
|
|
3183
|
-
|
|
3215
|
+
unlinkSync2(SPAWN_LOCK_PATH);
|
|
3184
3216
|
} catch {
|
|
3185
3217
|
}
|
|
3186
3218
|
}
|
|
@@ -3311,11 +3343,11 @@ function killAndRespawnDaemon() {
|
|
|
3311
3343
|
_connected = false;
|
|
3312
3344
|
_buffer = "";
|
|
3313
3345
|
try {
|
|
3314
|
-
|
|
3346
|
+
unlinkSync2(PID_PATH);
|
|
3315
3347
|
} catch {
|
|
3316
3348
|
}
|
|
3317
3349
|
try {
|
|
3318
|
-
|
|
3350
|
+
unlinkSync2(SOCKET_PATH);
|
|
3319
3351
|
} catch {
|
|
3320
3352
|
}
|
|
3321
3353
|
spawnDaemon();
|
|
@@ -4417,7 +4449,7 @@ __export(exe_rename_exports, {
|
|
|
4417
4449
|
main: () => main,
|
|
4418
4450
|
renameEmployee: () => renameEmployee
|
|
4419
4451
|
});
|
|
4420
|
-
import { readFileSync as readFileSync5, writeFileSync as
|
|
4452
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync as renameSync3, unlinkSync as unlinkSync3, existsSync as existsSync8 } from "fs";
|
|
4421
4453
|
import { execSync as execSync3 } from "child_process";
|
|
4422
4454
|
import path9 from "path";
|
|
4423
4455
|
import { homedir as homedir2 } from "os";
|
|
@@ -4450,7 +4482,7 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
4450
4482
|
undo: () => {
|
|
4451
4483
|
employee.name = originalName;
|
|
4452
4484
|
employee.systemPrompt = originalPrompt;
|
|
4453
|
-
|
|
4485
|
+
writeFileSync3(rosterPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
|
|
4454
4486
|
}
|
|
4455
4487
|
});
|
|
4456
4488
|
const oldIdentityPath = path9.join(identityDir, `${oldName}.md`);
|
|
@@ -4461,14 +4493,14 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
4461
4493
|
/^(agent_id:\s*)\S+/m,
|
|
4462
4494
|
`$1${newName}`
|
|
4463
4495
|
);
|
|
4464
|
-
|
|
4465
|
-
|
|
4496
|
+
renameSync3(oldIdentityPath, newIdentityPath);
|
|
4497
|
+
writeFileSync3(newIdentityPath, updatedContent, "utf-8");
|
|
4466
4498
|
rollbackStack.push({
|
|
4467
4499
|
description: "restore identity file",
|
|
4468
4500
|
undo: () => {
|
|
4469
4501
|
if (existsSync8(newIdentityPath)) {
|
|
4470
|
-
|
|
4471
|
-
|
|
4502
|
+
writeFileSync3(newIdentityPath, content, "utf-8");
|
|
4503
|
+
renameSync3(newIdentityPath, oldIdentityPath);
|
|
4472
4504
|
}
|
|
4473
4505
|
}
|
|
4474
4506
|
});
|
|
@@ -4477,13 +4509,13 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
4477
4509
|
const newAgentPath = path9.join(agentsDir, `${newName}.md`);
|
|
4478
4510
|
if (existsSync8(oldAgentPath)) {
|
|
4479
4511
|
const agentContent = readFileSync5(oldAgentPath, "utf-8");
|
|
4480
|
-
|
|
4512
|
+
renameSync3(oldAgentPath, newAgentPath);
|
|
4481
4513
|
rollbackStack.push({
|
|
4482
4514
|
description: "restore agent file",
|
|
4483
4515
|
undo: () => {
|
|
4484
4516
|
if (existsSync8(newAgentPath)) {
|
|
4485
|
-
|
|
4486
|
-
|
|
4517
|
+
renameSync3(newAgentPath, oldAgentPath);
|
|
4518
|
+
writeFileSync3(oldAgentPath, agentContent, "utf-8");
|
|
4487
4519
|
}
|
|
4488
4520
|
}
|
|
4489
4521
|
});
|
|
@@ -4566,7 +4598,7 @@ function removeOldSymlinks(name) {
|
|
|
4566
4598
|
const linkPath = path9.join(binDir, `${name}${suffix}`);
|
|
4567
4599
|
if (existsSync8(linkPath)) {
|
|
4568
4600
|
try {
|
|
4569
|
-
|
|
4601
|
+
unlinkSync3(linkPath);
|
|
4570
4602
|
} catch {
|
|
4571
4603
|
}
|
|
4572
4604
|
}
|
|
@@ -4609,7 +4641,7 @@ var init_exe_rename = __esm({
|
|
|
4609
4641
|
});
|
|
4610
4642
|
|
|
4611
4643
|
// src/lib/model-downloader.ts
|
|
4612
|
-
import { createWriteStream, createReadStream as createReadStream2, existsSync as existsSync9, unlinkSync as
|
|
4644
|
+
import { createWriteStream, createReadStream as createReadStream2, existsSync as existsSync9, unlinkSync as unlinkSync4, renameSync as renameSync4 } from "fs";
|
|
4613
4645
|
import { mkdir as mkdir5 } from "fs/promises";
|
|
4614
4646
|
import { createHash } from "crypto";
|
|
4615
4647
|
import path10 from "path";
|
|
@@ -4630,7 +4662,7 @@ async function downloadModel(opts) {
|
|
|
4630
4662
|
let downloaded = 0;
|
|
4631
4663
|
for (let attempt = 1; attempt <= MAX_RETRIES2; attempt++) {
|
|
4632
4664
|
try {
|
|
4633
|
-
if (existsSync9(tmpPath))
|
|
4665
|
+
if (existsSync9(tmpPath)) unlinkSync4(tmpPath);
|
|
4634
4666
|
const response = await fetchFn(GGUF_URL, {
|
|
4635
4667
|
redirect: "follow",
|
|
4636
4668
|
signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)
|
|
@@ -4662,12 +4694,12 @@ async function downloadModel(opts) {
|
|
|
4662
4694
|
}
|
|
4663
4695
|
const actualHash = hash.digest("hex");
|
|
4664
4696
|
if (actualHash !== EXPECTED_SHA256) {
|
|
4665
|
-
|
|
4697
|
+
unlinkSync4(tmpPath);
|
|
4666
4698
|
throw new Error(
|
|
4667
4699
|
`SHA256 mismatch: expected ${EXPECTED_SHA256}, got ${actualHash}`
|
|
4668
4700
|
);
|
|
4669
4701
|
}
|
|
4670
|
-
|
|
4702
|
+
renameSync4(tmpPath, destPath);
|
|
4671
4703
|
return destPath;
|
|
4672
4704
|
} catch (err) {
|
|
4673
4705
|
lastErr = err instanceof Error ? err : new Error(String(err));
|
|
@@ -4675,7 +4707,7 @@ async function downloadModel(opts) {
|
|
|
4675
4707
|
process.stderr.write(`
|
|
4676
4708
|
Download attempt ${attempt} failed, retrying...
|
|
4677
4709
|
`);
|
|
4678
|
-
if (existsSync9(tmpPath))
|
|
4710
|
+
if (existsSync9(tmpPath)) unlinkSync4(tmpPath);
|
|
4679
4711
|
}
|
|
4680
4712
|
}
|
|
4681
4713
|
}
|
|
@@ -4786,7 +4818,7 @@ __export(license_exports, {
|
|
|
4786
4818
|
stopLicenseRevalidation: () => stopLicenseRevalidation,
|
|
4787
4819
|
validateLicense: () => validateLicense
|
|
4788
4820
|
});
|
|
4789
|
-
import { readFileSync as readFileSync6, writeFileSync as
|
|
4821
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync10, mkdirSync as mkdirSync4 } from "fs";
|
|
4790
4822
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
4791
4823
|
import path11 from "path";
|
|
4792
4824
|
import { jwtVerify, importSPKI } from "jose";
|
|
@@ -4816,7 +4848,7 @@ function loadDeviceId() {
|
|
|
4816
4848
|
}
|
|
4817
4849
|
const id = randomUUID3();
|
|
4818
4850
|
mkdirSync4(EXE_AI_DIR, { recursive: true });
|
|
4819
|
-
|
|
4851
|
+
writeFileSync4(DEVICE_ID_PATH, id, "utf8");
|
|
4820
4852
|
return id;
|
|
4821
4853
|
}
|
|
4822
4854
|
function loadLicense() {
|
|
@@ -4829,7 +4861,7 @@ function loadLicense() {
|
|
|
4829
4861
|
}
|
|
4830
4862
|
function saveLicense(apiKey) {
|
|
4831
4863
|
mkdirSync4(EXE_AI_DIR, { recursive: true });
|
|
4832
|
-
|
|
4864
|
+
writeFileSync4(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
|
|
4833
4865
|
}
|
|
4834
4866
|
async function verifyLicenseJwt(token) {
|
|
4835
4867
|
try {
|
|
@@ -4900,7 +4932,7 @@ function getRawCachedPlan() {
|
|
|
4900
4932
|
}
|
|
4901
4933
|
function cacheResponse(token) {
|
|
4902
4934
|
try {
|
|
4903
|
-
|
|
4935
|
+
writeFileSync4(CACHE_PATH, JSON.stringify({ token }), "utf8");
|
|
4904
4936
|
} catch {
|
|
4905
4937
|
}
|
|
4906
4938
|
}
|
|
@@ -5263,7 +5295,7 @@ __export(cloud_sync_exports, {
|
|
|
5263
5295
|
mergeRosterFromRemote: () => mergeRosterFromRemote,
|
|
5264
5296
|
recordRosterDeletion: () => recordRosterDeletion
|
|
5265
5297
|
});
|
|
5266
|
-
import { readFileSync as readFileSync7, writeFileSync as
|
|
5298
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync11, readdirSync as readdirSync2, mkdirSync as mkdirSync5, appendFileSync, unlinkSync as unlinkSync5, openSync as openSync2, closeSync as closeSync2 } from "fs";
|
|
5267
5299
|
import crypto3 from "crypto";
|
|
5268
5300
|
import path12 from "path";
|
|
5269
5301
|
import { homedir as homedir3 } from "os";
|
|
@@ -5282,7 +5314,7 @@ async function withRosterLock(fn) {
|
|
|
5282
5314
|
try {
|
|
5283
5315
|
const fd = openSync2(ROSTER_LOCK_PATH, "wx");
|
|
5284
5316
|
closeSync2(fd);
|
|
5285
|
-
|
|
5317
|
+
writeFileSync5(ROSTER_LOCK_PATH, String(Date.now()));
|
|
5286
5318
|
} catch (err) {
|
|
5287
5319
|
if (err.code === "EEXIST") {
|
|
5288
5320
|
try {
|
|
@@ -5290,10 +5322,10 @@ async function withRosterLock(fn) {
|
|
|
5290
5322
|
if (Date.now() - ts < LOCK_STALE_MS) {
|
|
5291
5323
|
throw new Error("Roster merge already in progress \u2014 another sync is running");
|
|
5292
5324
|
}
|
|
5293
|
-
|
|
5325
|
+
unlinkSync5(ROSTER_LOCK_PATH);
|
|
5294
5326
|
const fd = openSync2(ROSTER_LOCK_PATH, "wx");
|
|
5295
5327
|
closeSync2(fd);
|
|
5296
|
-
|
|
5328
|
+
writeFileSync5(ROSTER_LOCK_PATH, String(Date.now()));
|
|
5297
5329
|
} catch (retryErr) {
|
|
5298
5330
|
if (retryErr instanceof Error && retryErr.message.includes("already in progress")) throw retryErr;
|
|
5299
5331
|
throw new Error("Roster merge already in progress \u2014 another sync is running");
|
|
@@ -5306,7 +5338,7 @@ async function withRosterLock(fn) {
|
|
|
5306
5338
|
return await fn();
|
|
5307
5339
|
} finally {
|
|
5308
5340
|
try {
|
|
5309
|
-
|
|
5341
|
+
unlinkSync5(ROSTER_LOCK_PATH);
|
|
5310
5342
|
} catch {
|
|
5311
5343
|
}
|
|
5312
5344
|
}
|
|
@@ -5606,13 +5638,13 @@ function recordRosterDeletion(name) {
|
|
|
5606
5638
|
} catch {
|
|
5607
5639
|
}
|
|
5608
5640
|
if (!deletions.includes(name)) deletions.push(name);
|
|
5609
|
-
|
|
5641
|
+
writeFileSync5(ROSTER_DELETIONS_PATH, JSON.stringify(deletions));
|
|
5610
5642
|
}
|
|
5611
5643
|
function consumeRosterDeletions() {
|
|
5612
5644
|
try {
|
|
5613
5645
|
if (!existsSync11(ROSTER_DELETIONS_PATH)) return [];
|
|
5614
5646
|
const deletions = JSON.parse(readFileSync7(ROSTER_DELETIONS_PATH, "utf-8"));
|
|
5615
|
-
|
|
5647
|
+
writeFileSync5(ROSTER_DELETIONS_PATH, "[]");
|
|
5616
5648
|
return deletions;
|
|
5617
5649
|
} catch {
|
|
5618
5650
|
return [];
|
|
@@ -5728,7 +5760,7 @@ function mergeConfig(remoteConfig, configPath) {
|
|
|
5728
5760
|
const merged = { ...remoteConfig, ...local };
|
|
5729
5761
|
const dir = path12.dirname(cfgPath);
|
|
5730
5762
|
if (!existsSync11(dir)) mkdirSync5(dir, { recursive: true });
|
|
5731
|
-
|
|
5763
|
+
writeFileSync5(cfgPath, JSON.stringify(merged, null, 2), "utf-8");
|
|
5732
5764
|
}
|
|
5733
5765
|
async function mergeRosterFromRemote(remote, paths) {
|
|
5734
5766
|
return withRosterLock(async () => {
|
|
@@ -5748,7 +5780,11 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
5748
5780
|
} catch {
|
|
5749
5781
|
}
|
|
5750
5782
|
}
|
|
5751
|
-
const
|
|
5783
|
+
const lookupKey = `${remoteEmp.name}.md`;
|
|
5784
|
+
const matchedKey = Object.keys(remote.identities).find(
|
|
5785
|
+
(k) => k.toLowerCase() === lookupKey.toLowerCase()
|
|
5786
|
+
) ?? lookupKey;
|
|
5787
|
+
const remoteIdentity = remote.identities[matchedKey];
|
|
5752
5788
|
if (remoteIdentity) {
|
|
5753
5789
|
if (!existsSync11(identityDir)) mkdirSync5(identityDir, { recursive: true });
|
|
5754
5790
|
const idPath = path12.join(identityDir, `${remoteEmp.name}.md`);
|
|
@@ -5758,7 +5794,7 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
5758
5794
|
} catch {
|
|
5759
5795
|
}
|
|
5760
5796
|
if (localIdentity !== remoteIdentity) {
|
|
5761
|
-
|
|
5797
|
+
writeFileSync5(idPath, remoteIdentity, "utf-8");
|
|
5762
5798
|
identitiesUpdated++;
|
|
5763
5799
|
}
|
|
5764
5800
|
}
|
|
@@ -6230,7 +6266,7 @@ __export(identity_exports, {
|
|
|
6230
6266
|
listIdentities: () => listIdentities,
|
|
6231
6267
|
updateIdentity: () => updateIdentity
|
|
6232
6268
|
});
|
|
6233
|
-
import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as
|
|
6269
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
|
|
6234
6270
|
import { readdirSync as readdirSync3 } from "fs";
|
|
6235
6271
|
import path13 from "path";
|
|
6236
6272
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -6296,7 +6332,7 @@ async function updateIdentity(agentId, content, updatedBy) {
|
|
|
6296
6332
|
ensureDir();
|
|
6297
6333
|
const filePath = identityPath(agentId);
|
|
6298
6334
|
const hash = contentHash(content);
|
|
6299
|
-
|
|
6335
|
+
writeFileSync6(filePath, content, "utf-8");
|
|
6300
6336
|
try {
|
|
6301
6337
|
const client = getClient();
|
|
6302
6338
|
await client.execute({
|
|
@@ -6894,11 +6930,11 @@ __export(session_wrappers_exports, {
|
|
|
6894
6930
|
import {
|
|
6895
6931
|
existsSync as existsSync13,
|
|
6896
6932
|
readFileSync as readFileSync9,
|
|
6897
|
-
writeFileSync as
|
|
6933
|
+
writeFileSync as writeFileSync7,
|
|
6898
6934
|
mkdirSync as mkdirSync7,
|
|
6899
6935
|
chmodSync,
|
|
6900
6936
|
readdirSync as readdirSync4,
|
|
6901
|
-
unlinkSync as
|
|
6937
|
+
unlinkSync as unlinkSync6
|
|
6902
6938
|
} from "fs";
|
|
6903
6939
|
import path14 from "path";
|
|
6904
6940
|
import { homedir as homedir4 } from "os";
|
|
@@ -6914,7 +6950,7 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
6914
6950
|
];
|
|
6915
6951
|
for (const src of candidates) {
|
|
6916
6952
|
if (existsSync13(src)) {
|
|
6917
|
-
|
|
6953
|
+
writeFileSync7(exeStartDst, readFileSync9(src));
|
|
6918
6954
|
chmodSync(exeStartDst, 493);
|
|
6919
6955
|
break;
|
|
6920
6956
|
}
|
|
@@ -6935,7 +6971,7 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
6935
6971
|
try {
|
|
6936
6972
|
const content = readFileSync9(fPath, "utf8");
|
|
6937
6973
|
if (content.includes("exe-start")) {
|
|
6938
|
-
|
|
6974
|
+
unlinkSync6(fPath);
|
|
6939
6975
|
}
|
|
6940
6976
|
} catch {
|
|
6941
6977
|
}
|
|
@@ -6949,7 +6985,7 @@ exec "${exeStartDst}" "$0" "$@"
|
|
|
6949
6985
|
for (const emp of employees) {
|
|
6950
6986
|
for (let n = 1; n <= MAX_N; n++) {
|
|
6951
6987
|
const wrapperPath = path14.join(binDir, `${emp.name}${n}`);
|
|
6952
|
-
|
|
6988
|
+
writeFileSync7(wrapperPath, wrapperContent);
|
|
6953
6989
|
chmodSync(wrapperPath, 493);
|
|
6954
6990
|
created++;
|
|
6955
6991
|
}
|
|
@@ -6985,7 +7021,7 @@ export PATH="${binDir}:$PATH"
|
|
|
6985
7021
|
if (content.includes(".exe-os/bin")) {
|
|
6986
7022
|
return false;
|
|
6987
7023
|
}
|
|
6988
|
-
|
|
7024
|
+
writeFileSync7(profilePath, content + exportLine);
|
|
6989
7025
|
return true;
|
|
6990
7026
|
} catch {
|
|
6991
7027
|
continue;
|
|
@@ -7008,8 +7044,8 @@ __export(setup_wizard_exports, {
|
|
|
7008
7044
|
validateModel: () => validateModel
|
|
7009
7045
|
});
|
|
7010
7046
|
import crypto4 from "crypto";
|
|
7011
|
-
import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync10, writeFileSync as
|
|
7012
|
-
import
|
|
7047
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync8, unlinkSync as unlinkSync7 } from "fs";
|
|
7048
|
+
import os6 from "os";
|
|
7013
7049
|
import path15 from "path";
|
|
7014
7050
|
import { createInterface as createInterface2 } from "readline";
|
|
7015
7051
|
function findPackageRoot2() {
|
|
@@ -7037,11 +7073,11 @@ function loadSetupState() {
|
|
|
7037
7073
|
}
|
|
7038
7074
|
function saveSetupState(state) {
|
|
7039
7075
|
mkdirSync8(path15.dirname(SETUP_STATE_PATH), { recursive: true });
|
|
7040
|
-
|
|
7076
|
+
writeFileSync8(SETUP_STATE_PATH, JSON.stringify(state, null, 2));
|
|
7041
7077
|
}
|
|
7042
7078
|
function clearSetupState() {
|
|
7043
7079
|
try {
|
|
7044
|
-
|
|
7080
|
+
unlinkSync7(SETUP_STATE_PATH);
|
|
7045
7081
|
} catch {
|
|
7046
7082
|
}
|
|
7047
7083
|
}
|
|
@@ -7247,7 +7283,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
7247
7283
|
await saveConfig(config);
|
|
7248
7284
|
log("");
|
|
7249
7285
|
try {
|
|
7250
|
-
const claudeJsonPath = path15.join(
|
|
7286
|
+
const claudeJsonPath = path15.join(os6.homedir(), ".claude.json");
|
|
7251
7287
|
let claudeJson = {};
|
|
7252
7288
|
try {
|
|
7253
7289
|
claudeJson = JSON.parse(readFileSync10(claudeJsonPath, "utf8"));
|
|
@@ -7255,11 +7291,11 @@ async function runSetupWizard(opts = {}) {
|
|
|
7255
7291
|
}
|
|
7256
7292
|
if (!claudeJson.projects) claudeJson.projects = {};
|
|
7257
7293
|
const projects = claudeJson.projects;
|
|
7258
|
-
for (const dir of [process.cwd(),
|
|
7294
|
+
for (const dir of [process.cwd(), os6.homedir()]) {
|
|
7259
7295
|
if (!projects[dir]) projects[dir] = {};
|
|
7260
7296
|
projects[dir].hasTrustDialogAccepted = true;
|
|
7261
7297
|
}
|
|
7262
|
-
|
|
7298
|
+
writeFileSync8(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
7263
7299
|
} catch {
|
|
7264
7300
|
}
|
|
7265
7301
|
state.completedSteps.push(5);
|
|
@@ -7295,6 +7331,54 @@ async function runSetupWizard(opts = {}) {
|
|
|
7295
7331
|
log(`Team: ${teamList}`);
|
|
7296
7332
|
createdEmployees.push(...roster.map((e) => ({ name: e.name, role: e.role })));
|
|
7297
7333
|
}
|
|
7334
|
+
let missingIdentities = [];
|
|
7335
|
+
for (const emp of roster) {
|
|
7336
|
+
const idPath = identityPath2(emp.name);
|
|
7337
|
+
if (!existsSync14(idPath)) {
|
|
7338
|
+
missingIdentities.push(emp.name);
|
|
7339
|
+
}
|
|
7340
|
+
}
|
|
7341
|
+
if (missingIdentities.length > 0) {
|
|
7342
|
+
log("");
|
|
7343
|
+
log(`\u26A0 Identity files missing for: ${missingIdentities.join(", ")}`);
|
|
7344
|
+
log(" Your main device needs to push them to cloud first.");
|
|
7345
|
+
log("");
|
|
7346
|
+
log(" On your MAIN device, run: exe-os cloud sync");
|
|
7347
|
+
log(" Then come back here and press Enter to retry the pull.");
|
|
7348
|
+
log("");
|
|
7349
|
+
await ask(rl, "Press Enter after syncing from your main device... ");
|
|
7350
|
+
try {
|
|
7351
|
+
const { initSyncCrypto: retryInitCrypto } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
|
|
7352
|
+
const { cloudPullRoster: retryPull } = await Promise.resolve().then(() => (init_cloud_sync(), cloud_sync_exports));
|
|
7353
|
+
const retryKey = await getMasterKey();
|
|
7354
|
+
if (retryKey) {
|
|
7355
|
+
retryInitCrypto(retryKey);
|
|
7356
|
+
const retryConfig = await loadConfig();
|
|
7357
|
+
if (retryConfig.cloud?.apiKey && retryConfig.cloud?.endpoint) {
|
|
7358
|
+
const retryResult = await retryPull({
|
|
7359
|
+
apiKey: retryConfig.cloud.apiKey,
|
|
7360
|
+
endpoint: retryConfig.cloud.endpoint
|
|
7361
|
+
});
|
|
7362
|
+
if (retryResult.identitiesUpdated && retryResult.identitiesUpdated > 0) {
|
|
7363
|
+
log(`Pulled ${retryResult.identitiesUpdated} identity file(s) from cloud.`);
|
|
7364
|
+
}
|
|
7365
|
+
}
|
|
7366
|
+
}
|
|
7367
|
+
missingIdentities = [];
|
|
7368
|
+
for (const emp of roster) {
|
|
7369
|
+
if (!existsSync14(identityPath2(emp.name))) {
|
|
7370
|
+
missingIdentities.push(emp.name);
|
|
7371
|
+
}
|
|
7372
|
+
}
|
|
7373
|
+
if (missingIdentities.length > 0) {
|
|
7374
|
+
log(`\u26A0 Still missing: ${missingIdentities.join(", ")}. Identities will sync on next daemon cycle.`);
|
|
7375
|
+
} else {
|
|
7376
|
+
log("All identity files synced successfully.");
|
|
7377
|
+
}
|
|
7378
|
+
} catch {
|
|
7379
|
+
log("Retry pull failed \u2014 identities will sync when the daemon starts.");
|
|
7380
|
+
}
|
|
7381
|
+
}
|
|
7298
7382
|
for (const emp of roster) {
|
|
7299
7383
|
registerBinSymlinks2(emp.name);
|
|
7300
7384
|
}
|
|
@@ -7340,7 +7424,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
7340
7424
|
const cooIdPath = identityPath2(cooName);
|
|
7341
7425
|
mkdirSync8(path15.dirname(cooIdPath), { recursive: true });
|
|
7342
7426
|
const replaced = cooIdentityContent.replace(/agent_id:\s*exe/g, `agent_id: ${cooName}`).replace(/\$\{agent_id\}/g, cooName);
|
|
7343
|
-
|
|
7427
|
+
writeFileSync8(cooIdPath, replaced, "utf-8");
|
|
7344
7428
|
}
|
|
7345
7429
|
registerBinSymlinks2(cooName);
|
|
7346
7430
|
createdEmployees.push({ name: cooName, role: "COO" });
|
|
@@ -7441,7 +7525,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
7441
7525
|
const ctoIdPath = identityPath2(ctoName);
|
|
7442
7526
|
mkdirSync8(path15.dirname(ctoIdPath), { recursive: true });
|
|
7443
7527
|
const replaced = ctoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${ctoName}`).replace(/\$\{agent_id\}/g, ctoName);
|
|
7444
|
-
|
|
7528
|
+
writeFileSync8(ctoIdPath, replaced, "utf-8");
|
|
7445
7529
|
}
|
|
7446
7530
|
registerBinSymlinks2(ctoName);
|
|
7447
7531
|
createdEmployees.push({ name: ctoName, role: "CTO" });
|
|
@@ -7469,7 +7553,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
7469
7553
|
const cmoIdPath = identityPath2(cmoName);
|
|
7470
7554
|
mkdirSync8(path15.dirname(cmoIdPath), { recursive: true });
|
|
7471
7555
|
const replaced = cmoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${cmoName}`).replace(/\$\{agent_id\}/g, cmoName);
|
|
7472
|
-
|
|
7556
|
+
writeFileSync8(cmoIdPath, replaced, "utf-8");
|
|
7473
7557
|
}
|
|
7474
7558
|
registerBinSymlinks2(cmoName);
|
|
7475
7559
|
createdEmployees.push({ name: cmoName, role: "CMO" });
|
|
@@ -7541,7 +7625,7 @@ var init_setup_wizard = __esm({
|
|
|
7541
7625
|
init_config();
|
|
7542
7626
|
init_keychain();
|
|
7543
7627
|
init_model_downloader();
|
|
7544
|
-
SETUP_STATE_PATH = path15.join(
|
|
7628
|
+
SETUP_STATE_PATH = path15.join(os6.homedir(), ".exe-os", "setup-state.json");
|
|
7545
7629
|
}
|
|
7546
7630
|
});
|
|
7547
7631
|
|
|
@@ -14104,10 +14188,10 @@ __export(session_registry_exports, {
|
|
|
14104
14188
|
pruneStaleSessions: () => pruneStaleSessions,
|
|
14105
14189
|
registerSession: () => registerSession
|
|
14106
14190
|
});
|
|
14107
|
-
import { readFileSync as readFileSync13, writeFileSync as
|
|
14191
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9, existsSync as existsSync16 } from "fs";
|
|
14108
14192
|
import { execSync as execSync6 } from "child_process";
|
|
14109
14193
|
import path17 from "path";
|
|
14110
|
-
import
|
|
14194
|
+
import os7 from "os";
|
|
14111
14195
|
function registerSession(entry) {
|
|
14112
14196
|
const dir = path17.dirname(REGISTRY_PATH);
|
|
14113
14197
|
if (!existsSync16(dir)) {
|
|
@@ -14120,7 +14204,7 @@ function registerSession(entry) {
|
|
|
14120
14204
|
} else {
|
|
14121
14205
|
sessions.push(entry);
|
|
14122
14206
|
}
|
|
14123
|
-
|
|
14207
|
+
writeFileSync9(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
|
|
14124
14208
|
}
|
|
14125
14209
|
function listSessions() {
|
|
14126
14210
|
try {
|
|
@@ -14145,7 +14229,7 @@ function pruneStaleSessions() {
|
|
|
14145
14229
|
const alive = sessions.filter((s) => liveSet.has(s.windowName));
|
|
14146
14230
|
const pruned = sessions.length - alive.length;
|
|
14147
14231
|
if (pruned > 0) {
|
|
14148
|
-
|
|
14232
|
+
writeFileSync9(REGISTRY_PATH, JSON.stringify(alive, null, 2));
|
|
14149
14233
|
}
|
|
14150
14234
|
return pruned;
|
|
14151
14235
|
}
|
|
@@ -14153,7 +14237,7 @@ var REGISTRY_PATH;
|
|
|
14153
14237
|
var init_session_registry = __esm({
|
|
14154
14238
|
"src/lib/session-registry.ts"() {
|
|
14155
14239
|
"use strict";
|
|
14156
|
-
REGISTRY_PATH = path17.join(
|
|
14240
|
+
REGISTRY_PATH = path17.join(os7.homedir(), ".exe-os", "session-registry.json");
|
|
14157
14241
|
}
|
|
14158
14242
|
});
|
|
14159
14243
|
|
|
@@ -14358,9 +14442,9 @@ var init_provider_table = __esm({
|
|
|
14358
14442
|
});
|
|
14359
14443
|
|
|
14360
14444
|
// src/lib/intercom-queue.ts
|
|
14361
|
-
import { readFileSync as readFileSync14, writeFileSync as
|
|
14445
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync10, renameSync as renameSync5, existsSync as existsSync17, mkdirSync as mkdirSync10 } from "fs";
|
|
14362
14446
|
import path18 from "path";
|
|
14363
|
-
import
|
|
14447
|
+
import os8 from "os";
|
|
14364
14448
|
function ensureDir2() {
|
|
14365
14449
|
const dir = path18.dirname(QUEUE_PATH);
|
|
14366
14450
|
if (!existsSync17(dir)) mkdirSync10(dir, { recursive: true });
|
|
@@ -14376,8 +14460,8 @@ function readQueue() {
|
|
|
14376
14460
|
function writeQueue(queue) {
|
|
14377
14461
|
ensureDir2();
|
|
14378
14462
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
14379
|
-
|
|
14380
|
-
|
|
14463
|
+
writeFileSync10(tmp, JSON.stringify(queue, null, 2));
|
|
14464
|
+
renameSync5(tmp, QUEUE_PATH);
|
|
14381
14465
|
}
|
|
14382
14466
|
function queueIntercom(targetSession, reason) {
|
|
14383
14467
|
const queue = readQueue();
|
|
@@ -14400,9 +14484,9 @@ var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
|
14400
14484
|
var init_intercom_queue = __esm({
|
|
14401
14485
|
"src/lib/intercom-queue.ts"() {
|
|
14402
14486
|
"use strict";
|
|
14403
|
-
QUEUE_PATH = path18.join(
|
|
14487
|
+
QUEUE_PATH = path18.join(os8.homedir(), ".exe-os", "intercom-queue.json");
|
|
14404
14488
|
TTL_MS = 60 * 60 * 1e3;
|
|
14405
|
-
INTERCOM_LOG = path18.join(
|
|
14489
|
+
INTERCOM_LOG = path18.join(os8.homedir(), ".exe-os", "intercom.log");
|
|
14406
14490
|
}
|
|
14407
14491
|
});
|
|
14408
14492
|
|
|
@@ -14487,11 +14571,11 @@ var init_plan_limits = __esm({
|
|
|
14487
14571
|
// src/lib/notifications.ts
|
|
14488
14572
|
import crypto5 from "crypto";
|
|
14489
14573
|
import path20 from "path";
|
|
14490
|
-
import
|
|
14574
|
+
import os9 from "os";
|
|
14491
14575
|
import {
|
|
14492
14576
|
readFileSync as readFileSync16,
|
|
14493
14577
|
readdirSync as readdirSync5,
|
|
14494
|
-
unlinkSync as
|
|
14578
|
+
unlinkSync as unlinkSync8,
|
|
14495
14579
|
existsSync as existsSync19,
|
|
14496
14580
|
rmdirSync
|
|
14497
14581
|
} from "fs";
|
|
@@ -15003,7 +15087,7 @@ var init_tasks_crud = __esm({
|
|
|
15003
15087
|
|
|
15004
15088
|
// src/lib/tasks-review.ts
|
|
15005
15089
|
import path22 from "path";
|
|
15006
|
-
import { existsSync as existsSync21, readdirSync as readdirSync6, unlinkSync as
|
|
15090
|
+
import { existsSync as existsSync21, readdirSync as readdirSync6, unlinkSync as unlinkSync9 } from "fs";
|
|
15007
15091
|
async function countPendingReviews(sessionScope) {
|
|
15008
15092
|
const client = getClient();
|
|
15009
15093
|
if (sessionScope) {
|
|
@@ -15188,7 +15272,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
15188
15272
|
if (existsSync21(cacheDir)) {
|
|
15189
15273
|
for (const f of readdirSync6(cacheDir)) {
|
|
15190
15274
|
if (f.startsWith("review-notified-")) {
|
|
15191
|
-
|
|
15275
|
+
unlinkSync9(path22.join(cacheDir, f));
|
|
15192
15276
|
}
|
|
15193
15277
|
}
|
|
15194
15278
|
}
|
|
@@ -15794,7 +15878,7 @@ __export(tasks_exports, {
|
|
|
15794
15878
|
writeCheckpoint: () => writeCheckpoint
|
|
15795
15879
|
});
|
|
15796
15880
|
import path25 from "path";
|
|
15797
|
-
import { writeFileSync as
|
|
15881
|
+
import { writeFileSync as writeFileSync11, mkdirSync as mkdirSync11, unlinkSync as unlinkSync10 } from "fs";
|
|
15798
15882
|
async function createTask(input) {
|
|
15799
15883
|
const result = await createTaskCore(input);
|
|
15800
15884
|
if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
|
|
@@ -15817,10 +15901,10 @@ async function updateTask(input) {
|
|
|
15817
15901
|
const cachePath = path25.join(cacheDir, `current-task-${agent}.json`);
|
|
15818
15902
|
if (input.status === "in_progress") {
|
|
15819
15903
|
mkdirSync11(cacheDir, { recursive: true });
|
|
15820
|
-
|
|
15904
|
+
writeFileSync11(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
15821
15905
|
} else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled") {
|
|
15822
15906
|
try {
|
|
15823
|
-
|
|
15907
|
+
unlinkSync10(cachePath);
|
|
15824
15908
|
} catch {
|
|
15825
15909
|
}
|
|
15826
15910
|
}
|
|
@@ -16262,11 +16346,11 @@ __export(tmux_routing_exports, {
|
|
|
16262
16346
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
16263
16347
|
});
|
|
16264
16348
|
import { execFileSync as execFileSync3, execSync as execSync11 } from "child_process";
|
|
16265
|
-
import { readFileSync as readFileSync18, writeFileSync as
|
|
16349
|
+
import { readFileSync as readFileSync18, writeFileSync as writeFileSync12, mkdirSync as mkdirSync12, existsSync as existsSync22, appendFileSync as appendFileSync2 } from "fs";
|
|
16266
16350
|
import path26 from "path";
|
|
16267
|
-
import
|
|
16351
|
+
import os10 from "os";
|
|
16268
16352
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
16269
|
-
import { unlinkSync as
|
|
16353
|
+
import { unlinkSync as unlinkSync11 } from "fs";
|
|
16270
16354
|
function spawnLockPath(sessionName) {
|
|
16271
16355
|
return path26.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
16272
16356
|
}
|
|
@@ -16293,12 +16377,12 @@ function acquireSpawnLock2(sessionName) {
|
|
|
16293
16377
|
} catch {
|
|
16294
16378
|
}
|
|
16295
16379
|
}
|
|
16296
|
-
|
|
16380
|
+
writeFileSync12(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
|
|
16297
16381
|
return true;
|
|
16298
16382
|
}
|
|
16299
16383
|
function releaseSpawnLock2(sessionName) {
|
|
16300
16384
|
try {
|
|
16301
|
-
|
|
16385
|
+
unlinkSync11(spawnLockPath(sessionName));
|
|
16302
16386
|
} catch {
|
|
16303
16387
|
}
|
|
16304
16388
|
}
|
|
@@ -16380,7 +16464,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
|
16380
16464
|
}
|
|
16381
16465
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
16382
16466
|
const filePath = path26.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
16383
|
-
|
|
16467
|
+
writeFileSync12(filePath, JSON.stringify({
|
|
16384
16468
|
parentExe: rootExe,
|
|
16385
16469
|
dispatchedBy: dispatchedBy || rootExe,
|
|
16386
16470
|
registeredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -16467,7 +16551,7 @@ function readDebounceState() {
|
|
|
16467
16551
|
function writeDebounceState(state) {
|
|
16468
16552
|
try {
|
|
16469
16553
|
if (!existsSync22(SESSION_CACHE)) mkdirSync12(SESSION_CACHE, { recursive: true });
|
|
16470
|
-
|
|
16554
|
+
writeFileSync12(DEBOUNCE_FILE, JSON.stringify(state));
|
|
16471
16555
|
} catch {
|
|
16472
16556
|
}
|
|
16473
16557
|
}
|
|
@@ -16656,7 +16740,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
16656
16740
|
const transport = getTransport();
|
|
16657
16741
|
const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
|
|
16658
16742
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
16659
|
-
const logDir = path26.join(
|
|
16743
|
+
const logDir = path26.join(os10.homedir(), ".exe-os", "session-logs");
|
|
16660
16744
|
const logFile = path26.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
16661
16745
|
if (!existsSync22(logDir)) {
|
|
16662
16746
|
mkdirSync12(logDir, { recursive: true });
|
|
@@ -16672,7 +16756,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
16672
16756
|
} catch {
|
|
16673
16757
|
}
|
|
16674
16758
|
try {
|
|
16675
|
-
const claudeJsonPath = path26.join(
|
|
16759
|
+
const claudeJsonPath = path26.join(os10.homedir(), ".claude.json");
|
|
16676
16760
|
let claudeJson = {};
|
|
16677
16761
|
try {
|
|
16678
16762
|
claudeJson = JSON.parse(readFileSync18(claudeJsonPath, "utf8"));
|
|
@@ -16683,11 +16767,11 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
16683
16767
|
const trustDir = opts?.cwd ?? projectDir;
|
|
16684
16768
|
if (!projects[trustDir]) projects[trustDir] = {};
|
|
16685
16769
|
projects[trustDir].hasTrustDialogAccepted = true;
|
|
16686
|
-
|
|
16770
|
+
writeFileSync12(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
16687
16771
|
} catch {
|
|
16688
16772
|
}
|
|
16689
16773
|
try {
|
|
16690
|
-
const settingsDir = path26.join(
|
|
16774
|
+
const settingsDir = path26.join(os10.homedir(), ".claude", "projects");
|
|
16691
16775
|
const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
|
|
16692
16776
|
const projSettingsDir = path26.join(settingsDir, normalizedKey);
|
|
16693
16777
|
const settingsPath = path26.join(projSettingsDir, "settings.json");
|
|
@@ -16722,7 +16806,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
16722
16806
|
perms.allow = allow;
|
|
16723
16807
|
settings.permissions = perms;
|
|
16724
16808
|
mkdirSync12(projSettingsDir, { recursive: true });
|
|
16725
|
-
|
|
16809
|
+
writeFileSync12(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
16726
16810
|
}
|
|
16727
16811
|
} catch {
|
|
16728
16812
|
}
|
|
@@ -16735,7 +16819,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
16735
16819
|
let legacyFallbackWarned = false;
|
|
16736
16820
|
if (!useExeAgent && !useBinSymlink) {
|
|
16737
16821
|
const identityPath2 = path26.join(
|
|
16738
|
-
|
|
16822
|
+
os10.homedir(),
|
|
16739
16823
|
".exe-os",
|
|
16740
16824
|
"identity",
|
|
16741
16825
|
`${employeeName}.md`
|
|
@@ -16765,7 +16849,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
16765
16849
|
}
|
|
16766
16850
|
let sessionContextFlag = "";
|
|
16767
16851
|
try {
|
|
16768
|
-
const ctxDir = path26.join(
|
|
16852
|
+
const ctxDir = path26.join(os10.homedir(), ".exe-os", "session-cache");
|
|
16769
16853
|
mkdirSync12(ctxDir, { recursive: true });
|
|
16770
16854
|
const ctxFile = path26.join(ctxDir, `session-context-${sessionName}.md`);
|
|
16771
16855
|
const ctxContent = [
|
|
@@ -16774,7 +16858,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
16774
16858
|
`Your parent exe session is ${exeSession}.`,
|
|
16775
16859
|
`Your employees (if any) use the -${exeSession} suffix (e.g., tom-${exeSession}).`
|
|
16776
16860
|
].join("\n");
|
|
16777
|
-
|
|
16861
|
+
writeFileSync12(ctxFile, ctxContent);
|
|
16778
16862
|
sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
|
|
16779
16863
|
} catch {
|
|
16780
16864
|
}
|
|
@@ -16813,7 +16897,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
16813
16897
|
try {
|
|
16814
16898
|
const mySession = getMySession();
|
|
16815
16899
|
const dispatchInfo = path26.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
|
|
16816
|
-
|
|
16900
|
+
writeFileSync12(dispatchInfo, JSON.stringify({
|
|
16817
16901
|
dispatchedBy: mySession,
|
|
16818
16902
|
rootExe: exeSession,
|
|
16819
16903
|
provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : "anthropic",
|
|
@@ -16876,13 +16960,13 @@ var init_tmux_routing = __esm({
|
|
|
16876
16960
|
init_provider_table();
|
|
16877
16961
|
init_intercom_queue();
|
|
16878
16962
|
init_plan_limits();
|
|
16879
|
-
SPAWN_LOCK_DIR = path26.join(
|
|
16880
|
-
SESSION_CACHE = path26.join(
|
|
16963
|
+
SPAWN_LOCK_DIR = path26.join(os10.homedir(), ".exe-os", "spawn-locks");
|
|
16964
|
+
SESSION_CACHE = path26.join(os10.homedir(), ".exe-os", "session-cache");
|
|
16881
16965
|
BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
|
|
16882
16966
|
VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
|
|
16883
16967
|
VERIFY_PANE_LINES = 200;
|
|
16884
16968
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
16885
|
-
INTERCOM_LOG2 = path26.join(
|
|
16969
|
+
INTERCOM_LOG2 = path26.join(os10.homedir(), ".exe-os", "intercom.log");
|
|
16886
16970
|
DEBOUNCE_FILE = path26.join(SESSION_CACHE, "intercom-debounce.json");
|
|
16887
16971
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
16888
16972
|
BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
|
|
@@ -19340,7 +19424,7 @@ var init_hooks = __esm({
|
|
|
19340
19424
|
|
|
19341
19425
|
// src/runtime/safety-checks.ts
|
|
19342
19426
|
import path27 from "path";
|
|
19343
|
-
import
|
|
19427
|
+
import os11 from "os";
|
|
19344
19428
|
function checkPathSafety(filePath) {
|
|
19345
19429
|
const resolved = path27.resolve(filePath);
|
|
19346
19430
|
for (const { pattern, reason } of BYPASS_IMMUNE_PATTERNS) {
|
|
@@ -19367,7 +19451,7 @@ var HOME, BYPASS_IMMUNE_PATTERNS;
|
|
|
19367
19451
|
var init_safety_checks = __esm({
|
|
19368
19452
|
"src/runtime/safety-checks.ts"() {
|
|
19369
19453
|
"use strict";
|
|
19370
|
-
HOME =
|
|
19454
|
+
HOME = os11.homedir();
|
|
19371
19455
|
BYPASS_IMMUNE_PATTERNS = [
|
|
19372
19456
|
{
|
|
19373
19457
|
pattern: /\/\.git\/hooks\//,
|
|
@@ -24532,9 +24616,9 @@ Unhandled rejection: ${reason}
|
|
|
24532
24616
|
});
|
|
24533
24617
|
|
|
24534
24618
|
// src/bin/cli.ts
|
|
24535
|
-
import { existsSync as existsSync23, readFileSync as readFileSync19, writeFileSync as
|
|
24619
|
+
import { existsSync as existsSync23, readFileSync as readFileSync19, writeFileSync as writeFileSync13, readdirSync as readdirSync7, rmSync } from "fs";
|
|
24536
24620
|
import path35 from "path";
|
|
24537
|
-
import
|
|
24621
|
+
import os12 from "os";
|
|
24538
24622
|
var args = process.argv.slice(2);
|
|
24539
24623
|
if (args.includes("--global")) {
|
|
24540
24624
|
process.stderr.write(
|
|
@@ -24597,7 +24681,7 @@ if (args.includes("--global")) {
|
|
|
24597
24681
|
});
|
|
24598
24682
|
await init_App2().then(() => App_exports);
|
|
24599
24683
|
} else {
|
|
24600
|
-
const claudeDir = path35.join(
|
|
24684
|
+
const claudeDir = path35.join(os12.homedir(), ".claude");
|
|
24601
24685
|
const settingsPath = path35.join(claudeDir, "settings.json");
|
|
24602
24686
|
const hasClaudeCode = existsSync23(settingsPath) && (() => {
|
|
24603
24687
|
try {
|
|
@@ -24610,7 +24694,7 @@ if (args.includes("--global")) {
|
|
|
24610
24694
|
if (hasClaudeCode) {
|
|
24611
24695
|
let cooName = "exe";
|
|
24612
24696
|
try {
|
|
24613
|
-
const rosterPath = path35.join(
|
|
24697
|
+
const rosterPath = path35.join(os12.homedir(), ".exe-os", "exe-employees.json");
|
|
24614
24698
|
if (existsSync23(rosterPath)) {
|
|
24615
24699
|
const roster = JSON.parse(readFileSync19(rosterPath, "utf8"));
|
|
24616
24700
|
const coo = roster.find((e) => e.role === "COO");
|
|
@@ -24651,9 +24735,9 @@ async function runClaudeInstall() {
|
|
|
24651
24735
|
}
|
|
24652
24736
|
}
|
|
24653
24737
|
async function runClaudeCheck() {
|
|
24654
|
-
const claudeDir = path35.join(
|
|
24738
|
+
const claudeDir = path35.join(os12.homedir(), ".claude");
|
|
24655
24739
|
const settingsPath = path35.join(claudeDir, "settings.json");
|
|
24656
|
-
const claudeJsonPath = path35.join(
|
|
24740
|
+
const claudeJsonPath = path35.join(os12.homedir(), ".claude.json");
|
|
24657
24741
|
let ok = true;
|
|
24658
24742
|
if (existsSync23(settingsPath)) {
|
|
24659
24743
|
let settings;
|
|
@@ -24723,7 +24807,7 @@ async function runClaudeCheck() {
|
|
|
24723
24807
|
async function runClaudeUninstall(flags = []) {
|
|
24724
24808
|
const dryRun = flags.includes("--dry-run");
|
|
24725
24809
|
const purge = flags.includes("--purge");
|
|
24726
|
-
const homeDir =
|
|
24810
|
+
const homeDir = os12.homedir();
|
|
24727
24811
|
const claudeDir = path35.join(homeDir, ".claude");
|
|
24728
24812
|
const settingsPath = path35.join(claudeDir, "settings.json");
|
|
24729
24813
|
const claudeJsonPath = path35.join(homeDir, ".claude.json");
|
|
@@ -24771,7 +24855,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
24771
24855
|
permCount = before - settings.permissions.allow.length;
|
|
24772
24856
|
}
|
|
24773
24857
|
if (!dryRun) {
|
|
24774
|
-
|
|
24858
|
+
writeFileSync13(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
24775
24859
|
}
|
|
24776
24860
|
log("\u2713 Removed exe-os hooks from settings.json");
|
|
24777
24861
|
if (permCount > 0) log(`\u2713 Removed ${permCount} MCP permission entries`);
|
|
@@ -24800,7 +24884,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
24800
24884
|
}
|
|
24801
24885
|
if (removedMcp) {
|
|
24802
24886
|
if (!dryRun) {
|
|
24803
|
-
|
|
24887
|
+
writeFileSync13(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
24804
24888
|
}
|
|
24805
24889
|
log("\u2713 Removed exe-os MCP server from claude.json");
|
|
24806
24890
|
removed++;
|
|
@@ -24836,7 +24920,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
24836
24920
|
const endIdx = content.indexOf(endMarker);
|
|
24837
24921
|
if (startIdx !== -1 && endIdx !== -1) {
|
|
24838
24922
|
const cleaned = (content.slice(0, startIdx) + content.slice(endIdx + endMarker.length)).replace(/\n{3,}/g, "\n\n").trim() + "\n";
|
|
24839
|
-
if (!dryRun)
|
|
24923
|
+
if (!dryRun) writeFileSync13(claudeMdPath, cleaned);
|
|
24840
24924
|
log("\u2713 Removed orchestration block from CLAUDE.md");
|
|
24841
24925
|
removed++;
|
|
24842
24926
|
}
|
|
@@ -24888,7 +24972,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
24888
24972
|
if (pSettings.permissions.allow.length < before) changed = true;
|
|
24889
24973
|
}
|
|
24890
24974
|
if (changed && !dryRun) {
|
|
24891
|
-
|
|
24975
|
+
writeFileSync13(projSettings, JSON.stringify(pSettings, null, 2) + "\n");
|
|
24892
24976
|
}
|
|
24893
24977
|
if (changed) projectCount++;
|
|
24894
24978
|
} catch {
|