@askexenow/exe-os 0.9.73 → 0.9.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +75 -50
- package/dist/bin/exe-new-employee.js +36 -11
- package/dist/bin/install.js +36 -11
- package/dist/bin/setup.js +35 -10
- package/dist/lib/session-wrappers.js +31 -6
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -3698,8 +3698,8 @@ function findPackageRoot() {
|
|
|
3698
3698
|
function getAvailableMemoryGB() {
|
|
3699
3699
|
if (process.platform === "darwin") {
|
|
3700
3700
|
try {
|
|
3701
|
-
const { execSync:
|
|
3702
|
-
const vmstat =
|
|
3701
|
+
const { execSync: execSync18 } = __require("child_process");
|
|
3702
|
+
const vmstat = execSync18("vm_stat", { encoding: "utf8" });
|
|
3703
3703
|
const pageSize = 16384;
|
|
3704
3704
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
3705
3705
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -18119,12 +18119,14 @@ import {
|
|
|
18119
18119
|
readdirSync as readdirSync9,
|
|
18120
18120
|
unlinkSync as unlinkSync14
|
|
18121
18121
|
} from "fs";
|
|
18122
|
+
import { execSync as execSync13 } from "child_process";
|
|
18122
18123
|
import path37 from "path";
|
|
18123
18124
|
import { homedir as homedir5 } from "os";
|
|
18124
18125
|
function generateSessionWrappers(packageRoot, homeDir) {
|
|
18125
18126
|
const home = homeDir ?? homedir5();
|
|
18126
18127
|
const binDir = path37.join(home, ".exe-os", "bin");
|
|
18127
18128
|
const rosterPath = path37.join(home, ".exe-os", "exe-employees.json");
|
|
18129
|
+
const shouldMirrorToGlobalBin = homeDir === void 0;
|
|
18128
18130
|
mkdirSync21(binDir, { recursive: true });
|
|
18129
18131
|
const exeStartDst = path37.join(binDir, "exe-start");
|
|
18130
18132
|
const candidates = [
|
|
@@ -18165,15 +18167,18 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
18165
18167
|
const wrapperContent = `#!/bin/bash
|
|
18166
18168
|
exec "${exeStartDst}" "$0" "$@"
|
|
18167
18169
|
`;
|
|
18170
|
+
const globalBinDir = shouldMirrorToGlobalBin ? resolveGlobalBinDir() : null;
|
|
18168
18171
|
for (const emp of employees) {
|
|
18169
18172
|
for (let n = 1; n <= MAX_N; n++) {
|
|
18170
|
-
|
|
18171
|
-
|
|
18172
|
-
|
|
18173
|
+
writeWrapper(path37.join(binDir, `${emp.name}${n}`), wrapperContent);
|
|
18174
|
+
if (globalBinDir) {
|
|
18175
|
+
writeWrapper(path37.join(globalBinDir, `${emp.name}${n}`), wrapperContent);
|
|
18176
|
+
}
|
|
18173
18177
|
created++;
|
|
18174
|
-
|
|
18175
|
-
|
|
18176
|
-
|
|
18178
|
+
writeWrapper(path37.join(binDir, `${emp.name}${n}-codex`), wrapperContent);
|
|
18179
|
+
if (globalBinDir) {
|
|
18180
|
+
writeWrapper(path37.join(globalBinDir, `${emp.name}${n}-codex`), wrapperContent);
|
|
18181
|
+
}
|
|
18177
18182
|
created++;
|
|
18178
18183
|
}
|
|
18179
18184
|
}
|
|
@@ -18202,6 +18207,26 @@ exec node "${codexLauncher}" --agent ${emp.name} "$@"
|
|
|
18202
18207
|
const pathConfigured = ensurePath(home, binDir);
|
|
18203
18208
|
return { created, pathConfigured };
|
|
18204
18209
|
}
|
|
18210
|
+
function writeWrapper(wrapperPath, content) {
|
|
18211
|
+
try {
|
|
18212
|
+
writeFileSync22(wrapperPath, content);
|
|
18213
|
+
chmodSync3(wrapperPath, 493);
|
|
18214
|
+
} catch {
|
|
18215
|
+
}
|
|
18216
|
+
}
|
|
18217
|
+
function resolveGlobalBinDir() {
|
|
18218
|
+
try {
|
|
18219
|
+
const exeOsPath = execSync13("command -v exe-os", { encoding: "utf8", timeout: 3e3 }).trim().split("\n")[0];
|
|
18220
|
+
if (exeOsPath) return path37.dirname(exeOsPath);
|
|
18221
|
+
} catch {
|
|
18222
|
+
}
|
|
18223
|
+
try {
|
|
18224
|
+
const prefix = execSync13("npm prefix -g", { encoding: "utf8", timeout: 3e3 }).trim();
|
|
18225
|
+
if (prefix) return path37.join(prefix, "bin");
|
|
18226
|
+
} catch {
|
|
18227
|
+
}
|
|
18228
|
+
return null;
|
|
18229
|
+
}
|
|
18205
18230
|
function ensurePath(home, binDir) {
|
|
18206
18231
|
if (process.env.PATH?.split(":").includes(binDir)) {
|
|
18207
18232
|
return false;
|
|
@@ -18303,8 +18328,8 @@ function ask3(rl, prompt) {
|
|
|
18303
18328
|
function getAvailableMemoryGB2() {
|
|
18304
18329
|
if (process.platform === "darwin") {
|
|
18305
18330
|
try {
|
|
18306
|
-
const { execSync:
|
|
18307
|
-
const vmstat =
|
|
18331
|
+
const { execSync: execSync18 } = __require("child_process");
|
|
18332
|
+
const vmstat = execSync18("vm_stat", { encoding: "utf8" });
|
|
18308
18333
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
18309
18334
|
const pageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : 16384;
|
|
18310
18335
|
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
@@ -19164,7 +19189,7 @@ var init_update_backup = __esm({
|
|
|
19164
19189
|
});
|
|
19165
19190
|
|
|
19166
19191
|
// src/lib/update-check.ts
|
|
19167
|
-
import { execSync as
|
|
19192
|
+
import { execSync as execSync14 } from "child_process";
|
|
19168
19193
|
import { readFileSync as readFileSync27 } from "fs";
|
|
19169
19194
|
import path40 from "path";
|
|
19170
19195
|
function getLocalVersion(packageRoot) {
|
|
@@ -19174,7 +19199,7 @@ function getLocalVersion(packageRoot) {
|
|
|
19174
19199
|
}
|
|
19175
19200
|
function getRemoteVersion() {
|
|
19176
19201
|
try {
|
|
19177
|
-
const output =
|
|
19202
|
+
const output = execSync14("npm view @askexenow/exe-os version", {
|
|
19178
19203
|
encoding: "utf-8",
|
|
19179
19204
|
timeout: 15e3,
|
|
19180
19205
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -19213,7 +19238,7 @@ __export(update_exports, {
|
|
|
19213
19238
|
getRemoteVersion: () => getRemoteVersion,
|
|
19214
19239
|
runUpdate: () => runUpdate
|
|
19215
19240
|
});
|
|
19216
|
-
import { execSync as
|
|
19241
|
+
import { execSync as execSync15 } from "child_process";
|
|
19217
19242
|
import { createInterface as createInterface5 } from "readline";
|
|
19218
19243
|
async function runRestore() {
|
|
19219
19244
|
console.log("\n\u{1F504} Restoring from update backup...");
|
|
@@ -19224,7 +19249,7 @@ async function runRestore() {
|
|
|
19224
19249
|
console.log(`
|
|
19225
19250
|
\u{1F4E5} Reinstalling @askexenow/exe-os@${manifest.version}...`);
|
|
19226
19251
|
try {
|
|
19227
|
-
|
|
19252
|
+
execSync15(`npm install -g @askexenow/exe-os@${manifest.version}`, {
|
|
19228
19253
|
stdio: ["pipe", "pipe", "inherit"],
|
|
19229
19254
|
timeout: 3e5
|
|
19230
19255
|
});
|
|
@@ -19301,7 +19326,7 @@ async function runUpdate(cliArgs) {
|
|
|
19301
19326
|
}
|
|
19302
19327
|
console.log("\u{1F9F9} Clearing npm cache...");
|
|
19303
19328
|
try {
|
|
19304
|
-
|
|
19329
|
+
execSync15("npm cache clean --force", { stdio: "pipe" });
|
|
19305
19330
|
console.log(" Done");
|
|
19306
19331
|
} catch {
|
|
19307
19332
|
console.log(" Skipped (non-critical)");
|
|
@@ -19309,7 +19334,7 @@ async function runUpdate(cliArgs) {
|
|
|
19309
19334
|
console.log("\u{1F4E5} Installing @askexenow/exe-os@latest...");
|
|
19310
19335
|
console.log(" This may take a minute...\n");
|
|
19311
19336
|
try {
|
|
19312
|
-
|
|
19337
|
+
execSync15("npm install -g @askexenow/exe-os@latest", {
|
|
19313
19338
|
stdio: ["pipe", "pipe", "inherit"],
|
|
19314
19339
|
timeout: 3e5
|
|
19315
19340
|
});
|
|
@@ -19327,7 +19352,7 @@ async function runUpdate(cliArgs) {
|
|
|
19327
19352
|
newVersion = getLocalVersion(packageRoot);
|
|
19328
19353
|
} catch {
|
|
19329
19354
|
try {
|
|
19330
|
-
const out =
|
|
19355
|
+
const out = execSync15("npm list -g @askexenow/exe-os --depth=0 2>/dev/null", { encoding: "utf8" });
|
|
19331
19356
|
const match = out.match(/@askexenow\/exe-os@(\S+)/);
|
|
19332
19357
|
newVersion = match?.[1] ?? "unknown";
|
|
19333
19358
|
} catch {
|
|
@@ -19356,7 +19381,7 @@ async function runUpdate(cliArgs) {
|
|
|
19356
19381
|
}
|
|
19357
19382
|
console.log("\u{1F527} Re-registering MCP, hooks, wrappers, and daemon...");
|
|
19358
19383
|
try {
|
|
19359
|
-
|
|
19384
|
+
execSync15("exe-os-install --global", {
|
|
19360
19385
|
stdio: ["pipe", "inherit", "inherit"],
|
|
19361
19386
|
timeout: 3e5
|
|
19362
19387
|
});
|
|
@@ -26693,13 +26718,13 @@ __export(tmux_status_exports, {
|
|
|
26693
26718
|
parseActivity: () => parseActivity,
|
|
26694
26719
|
parseContextPercentage: () => parseContextPercentage
|
|
26695
26720
|
});
|
|
26696
|
-
import { execSync as
|
|
26721
|
+
import { execSync as execSync16 } from "child_process";
|
|
26697
26722
|
function inTmux() {
|
|
26698
26723
|
if (process.env.TMUX || process.env.TMUX_PANE) return true;
|
|
26699
26724
|
const term = process.env.TERM ?? "";
|
|
26700
26725
|
if (term.startsWith("tmux") || term.startsWith("screen")) return true;
|
|
26701
26726
|
try {
|
|
26702
|
-
|
|
26727
|
+
execSync16("tmux display-message -p '#{session_name}' 2>/dev/null", {
|
|
26703
26728
|
encoding: "utf8",
|
|
26704
26729
|
timeout: 2e3
|
|
26705
26730
|
});
|
|
@@ -26709,12 +26734,12 @@ function inTmux() {
|
|
|
26709
26734
|
try {
|
|
26710
26735
|
let pid = process.ppid;
|
|
26711
26736
|
for (let depth = 0; depth < 8 && pid > 1; depth++) {
|
|
26712
|
-
const comm =
|
|
26737
|
+
const comm = execSync16(`ps -p ${pid} -o comm= 2>/dev/null`, {
|
|
26713
26738
|
encoding: "utf8",
|
|
26714
26739
|
timeout: 1e3
|
|
26715
26740
|
}).trim();
|
|
26716
26741
|
if (/tmux/.test(comm)) return true;
|
|
26717
|
-
const ppid =
|
|
26742
|
+
const ppid = execSync16(`ps -p ${pid} -o ppid= 2>/dev/null`, {
|
|
26718
26743
|
encoding: "utf8",
|
|
26719
26744
|
timeout: 1e3
|
|
26720
26745
|
}).trim();
|
|
@@ -26727,7 +26752,7 @@ function inTmux() {
|
|
|
26727
26752
|
}
|
|
26728
26753
|
function listTmuxSessions() {
|
|
26729
26754
|
try {
|
|
26730
|
-
const out =
|
|
26755
|
+
const out = execSync16("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
|
|
26731
26756
|
encoding: "utf8",
|
|
26732
26757
|
timeout: 3e3
|
|
26733
26758
|
});
|
|
@@ -26738,7 +26763,7 @@ function listTmuxSessions() {
|
|
|
26738
26763
|
}
|
|
26739
26764
|
function capturePaneLines(windowName, lines = 10) {
|
|
26740
26765
|
try {
|
|
26741
|
-
const out =
|
|
26766
|
+
const out = execSync16(
|
|
26742
26767
|
`tmux capture-pane -t ${JSON.stringify(windowName)} -p 2>/dev/null | tail -${lines}`,
|
|
26743
26768
|
{ encoding: "utf8", timeout: 3e3 }
|
|
26744
26769
|
);
|
|
@@ -26749,7 +26774,7 @@ function capturePaneLines(windowName, lines = 10) {
|
|
|
26749
26774
|
}
|
|
26750
26775
|
function getPaneCwd(windowName) {
|
|
26751
26776
|
try {
|
|
26752
|
-
const out =
|
|
26777
|
+
const out = execSync16(
|
|
26753
26778
|
`tmux display-message -t ${JSON.stringify(windowName)} -p '#{pane_current_path}' 2>/dev/null`,
|
|
26754
26779
|
{ encoding: "utf8", timeout: 3e3 }
|
|
26755
26780
|
);
|
|
@@ -26760,7 +26785,7 @@ function getPaneCwd(windowName) {
|
|
|
26760
26785
|
}
|
|
26761
26786
|
function projectFromPath(dir) {
|
|
26762
26787
|
try {
|
|
26763
|
-
const root =
|
|
26788
|
+
const root = execSync16("git -C " + JSON.stringify(dir) + " rev-parse --show-toplevel 2>/dev/null", {
|
|
26764
26789
|
encoding: "utf8",
|
|
26765
26790
|
timeout: 3e3
|
|
26766
26791
|
}).trim();
|
|
@@ -26829,7 +26854,7 @@ function getEmployeeStatuses(employeeNames) {
|
|
|
26829
26854
|
}
|
|
26830
26855
|
let paneAlive = true;
|
|
26831
26856
|
try {
|
|
26832
|
-
const paneStatus =
|
|
26857
|
+
const paneStatus = execSync16(
|
|
26833
26858
|
`tmux list-panes -t ${JSON.stringify(sessionName)} -F '#{pane_dead}' 2>/dev/null`,
|
|
26834
26859
|
{ encoding: "utf8", timeout: 3e3 }
|
|
26835
26860
|
).trim();
|
|
@@ -27019,8 +27044,8 @@ function Footer() {
|
|
|
27019
27044
|
setSessions(allSessions.length);
|
|
27020
27045
|
if (!currentSession) {
|
|
27021
27046
|
try {
|
|
27022
|
-
const { execSync:
|
|
27023
|
-
const name =
|
|
27047
|
+
const { execSync: execSync18 } = await import("child_process");
|
|
27048
|
+
const name = execSync18("tmux display-message -p '#{session_name}' 2>/dev/null", {
|
|
27024
27049
|
encoding: "utf8",
|
|
27025
27050
|
timeout: 2e3
|
|
27026
27051
|
}).trim();
|
|
@@ -30374,8 +30399,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
|
|
|
30374
30399
|
}
|
|
30375
30400
|
const capture = () => {
|
|
30376
30401
|
try {
|
|
30377
|
-
const { execSync:
|
|
30378
|
-
const output =
|
|
30402
|
+
const { execSync: execSync18 } = __require("child_process");
|
|
30403
|
+
const output = execSync18(
|
|
30379
30404
|
`tmux capture-pane -t ${JSON.stringify(sessionName)} -p -e 2>/dev/null | tail -${CAPTURE_LINES}`,
|
|
30380
30405
|
{ encoding: "utf8", timeout: 3e3 }
|
|
30381
30406
|
);
|
|
@@ -30399,8 +30424,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
|
|
|
30399
30424
|
if (key.return) {
|
|
30400
30425
|
if (!demo && inputBuffer.trim()) {
|
|
30401
30426
|
try {
|
|
30402
|
-
const { execSync:
|
|
30403
|
-
|
|
30427
|
+
const { execSync: execSync18 } = __require("child_process");
|
|
30428
|
+
execSync18(
|
|
30404
30429
|
`tmux send-keys -t ${JSON.stringify(sessionName)} ${JSON.stringify(inputBuffer)} Enter`,
|
|
30405
30430
|
{ timeout: 2e3 }
|
|
30406
30431
|
);
|
|
@@ -30408,8 +30433,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
|
|
|
30408
30433
|
}
|
|
30409
30434
|
} else if (!demo) {
|
|
30410
30435
|
try {
|
|
30411
|
-
const { execSync:
|
|
30412
|
-
|
|
30436
|
+
const { execSync: execSync18 } = __require("child_process");
|
|
30437
|
+
execSync18(`tmux send-keys -t ${JSON.stringify(sessionName)} Enter`, { timeout: 2e3 });
|
|
30413
30438
|
} catch {
|
|
30414
30439
|
}
|
|
30415
30440
|
}
|
|
@@ -31096,12 +31121,12 @@ function SessionsView({
|
|
|
31096
31121
|
return;
|
|
31097
31122
|
}
|
|
31098
31123
|
} else {
|
|
31099
|
-
const { execSync:
|
|
31124
|
+
const { execSync: execSync18 } = await import("child_process");
|
|
31100
31125
|
const dir = projectDir || process.cwd();
|
|
31101
|
-
|
|
31102
|
-
|
|
31126
|
+
execSync18(`tmux new-session -d -s ${JSON.stringify(entry.sessionName)} -c ${JSON.stringify(dir)}`, { timeout: 5e3 });
|
|
31127
|
+
execSync18(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "claude --dangerously-skip-permissions" Enter`, { timeout: 3e3 });
|
|
31103
31128
|
await new Promise((r) => setTimeout(r, 3e3));
|
|
31104
|
-
|
|
31129
|
+
execSync18(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "/exe" Enter`, { timeout: 3e3 });
|
|
31105
31130
|
}
|
|
31106
31131
|
const updated = { ...entry, status: "active", activity: "Starting...", attached: false };
|
|
31107
31132
|
setViewingEmployee(updated);
|
|
@@ -31204,7 +31229,7 @@ function SessionsView({
|
|
|
31204
31229
|
const { listTmuxSessions: listTmuxSessions2, inTmux: inTmux2, capturePaneLines: capturePaneLines2, parseActivity: parseActivity2 } = await Promise.resolve().then(() => (init_tmux_status(), tmux_status_exports));
|
|
31205
31230
|
const { getCoordinatorName: getCoordinatorName2, isCoordinatorRole: isCoordinatorRole2, loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
31206
31231
|
const { isExeSession: isExeSession2 } = await Promise.resolve().then(() => (init_tmux_routing(), tmux_routing_exports));
|
|
31207
|
-
const { execSync:
|
|
31232
|
+
const { execSync: execSync18 } = await import("child_process");
|
|
31208
31233
|
if (!inTmux2()) {
|
|
31209
31234
|
setTmuxAvailable(false);
|
|
31210
31235
|
setProjects([]);
|
|
@@ -31213,7 +31238,7 @@ function SessionsView({
|
|
|
31213
31238
|
setTmuxAvailable(true);
|
|
31214
31239
|
const attachedMap = /* @__PURE__ */ new Map();
|
|
31215
31240
|
try {
|
|
31216
|
-
const out =
|
|
31241
|
+
const out = execSync18("tmux list-sessions -F '#{session_name}:#{session_attached}' 2>/dev/null", {
|
|
31217
31242
|
encoding: "utf8",
|
|
31218
31243
|
timeout: 3e3
|
|
31219
31244
|
});
|
|
@@ -32249,8 +32274,8 @@ function upsertConversation(conversations, platform, senderId, message) {
|
|
|
32249
32274
|
async function loadGatewayConfig() {
|
|
32250
32275
|
const state = { running: false, port: 3100, adapters: [], agents: [], gatewayUrl: "" };
|
|
32251
32276
|
try {
|
|
32252
|
-
const { execSync:
|
|
32253
|
-
const ps =
|
|
32277
|
+
const { execSync: execSync18 } = await import("child_process");
|
|
32278
|
+
const ps = execSync18("pgrep -f exe-gateway 2>/dev/null", { encoding: "utf8", timeout: 3e3 });
|
|
32254
32279
|
state.running = ps.trim().length > 0;
|
|
32255
32280
|
} catch {
|
|
32256
32281
|
state.running = false;
|
|
@@ -32727,10 +32752,10 @@ var init_Gateway = __esm({
|
|
|
32727
32752
|
});
|
|
32728
32753
|
|
|
32729
32754
|
// src/tui/utils/agent-status.ts
|
|
32730
|
-
import { execSync as
|
|
32755
|
+
import { execSync as execSync17 } from "child_process";
|
|
32731
32756
|
function getAgentStatus(agentId) {
|
|
32732
32757
|
try {
|
|
32733
|
-
const sessions =
|
|
32758
|
+
const sessions = execSync17("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
|
|
32734
32759
|
encoding: "utf8",
|
|
32735
32760
|
timeout: 2e3
|
|
32736
32761
|
}).trim().split("\n");
|
|
@@ -32741,7 +32766,7 @@ function getAgentStatus(agentId) {
|
|
|
32741
32766
|
return /^\d?-/.test(suffix) || /^\d+$/.test(suffix);
|
|
32742
32767
|
});
|
|
32743
32768
|
if (!agentSession) return { label: "offline", color: "gray" };
|
|
32744
|
-
const pane =
|
|
32769
|
+
const pane = execSync17(`tmux capture-pane -t "${agentSession}" -p 2>/dev/null | tail -3`, {
|
|
32745
32770
|
encoding: "utf8",
|
|
32746
32771
|
timeout: 2e3
|
|
32747
32772
|
});
|
|
@@ -33664,8 +33689,8 @@ function SettingsView({ onBack }) {
|
|
|
33664
33689
|
};
|
|
33665
33690
|
});
|
|
33666
33691
|
try {
|
|
33667
|
-
const { execSync:
|
|
33668
|
-
|
|
33692
|
+
const { execSync: execSync18 } = await import("child_process");
|
|
33693
|
+
execSync18("curl -s --max-time 1 http://localhost:11434/api/tags", { timeout: 2e3 });
|
|
33669
33694
|
providerList.push({ name: "Ollama", configured: true, detail: "localhost:11434" });
|
|
33670
33695
|
} catch {
|
|
33671
33696
|
providerList.push({ name: "Ollama", configured: false, detail: "not running" });
|
|
@@ -36461,10 +36486,10 @@ async function runClaudeUninstall(flags = []) {
|
|
|
36461
36486
|
}
|
|
36462
36487
|
}
|
|
36463
36488
|
try {
|
|
36464
|
-
const { execSync:
|
|
36489
|
+
const { execSync: execSync18 } = await import("child_process");
|
|
36465
36490
|
const findExeBin3 = () => {
|
|
36466
36491
|
try {
|
|
36467
|
-
return
|
|
36492
|
+
return execSync18(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
|
|
36468
36493
|
} catch {
|
|
36469
36494
|
return null;
|
|
36470
36495
|
}
|
|
@@ -258,7 +258,7 @@ var init_agent_config = __esm({
|
|
|
258
258
|
// src/lib/employees.ts
|
|
259
259
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
260
260
|
import { existsSync as existsSync5, symlinkSync, readlinkSync, readFileSync as readFileSync4, renameSync as renameSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
261
|
-
import { execSync } from "child_process";
|
|
261
|
+
import { execSync as execSync2 } from "child_process";
|
|
262
262
|
import path4 from "path";
|
|
263
263
|
import os2 from "os";
|
|
264
264
|
function normalizeRole(role) {
|
|
@@ -364,7 +364,7 @@ async function hireEmployee(employee) {
|
|
|
364
364
|
}
|
|
365
365
|
function findExeBin() {
|
|
366
366
|
try {
|
|
367
|
-
return
|
|
367
|
+
return execSync2(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
|
|
368
368
|
} catch {
|
|
369
369
|
return null;
|
|
370
370
|
}
|
|
@@ -1486,7 +1486,7 @@ import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSy
|
|
|
1486
1486
|
import { createHash as createHash2 } from "crypto";
|
|
1487
1487
|
import path12 from "path";
|
|
1488
1488
|
import os8 from "os";
|
|
1489
|
-
import { execSync as
|
|
1489
|
+
import { execSync as execSync3 } from "child_process";
|
|
1490
1490
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1491
1491
|
function resolvePackageRoot() {
|
|
1492
1492
|
const thisFile = fileURLToPath2(import.meta.url);
|
|
@@ -2297,7 +2297,7 @@ ${sourceLine}
|
|
|
2297
2297
|
`);
|
|
2298
2298
|
}
|
|
2299
2299
|
try {
|
|
2300
|
-
|
|
2300
|
+
execSync3(`tmux source-file ${exeTmuxConf} 2>/dev/null`);
|
|
2301
2301
|
} catch {
|
|
2302
2302
|
}
|
|
2303
2303
|
process.stderr.write("exe-os: tmux config installed\n");
|
|
@@ -2308,7 +2308,7 @@ function setupGhostty(home) {
|
|
|
2308
2308
|
const macConfig = path12.join(homeDir, "Library", "Application Support", "com.mitchellh.ghostty");
|
|
2309
2309
|
const ghosttyInstalled = existsSync12(xdgConfig) || existsSync12(macConfig) || (() => {
|
|
2310
2310
|
try {
|
|
2311
|
-
|
|
2311
|
+
execSync3("which ghostty 2>/dev/null");
|
|
2312
2312
|
return true;
|
|
2313
2313
|
} catch {
|
|
2314
2314
|
return false;
|
|
@@ -2415,6 +2415,7 @@ import {
|
|
|
2415
2415
|
readdirSync,
|
|
2416
2416
|
unlinkSync
|
|
2417
2417
|
} from "fs";
|
|
2418
|
+
import { execSync } from "child_process";
|
|
2418
2419
|
import path from "path";
|
|
2419
2420
|
import { homedir } from "os";
|
|
2420
2421
|
var MAX_N = 9;
|
|
@@ -2422,6 +2423,7 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
2422
2423
|
const home = homeDir ?? homedir();
|
|
2423
2424
|
const binDir = path.join(home, ".exe-os", "bin");
|
|
2424
2425
|
const rosterPath = path.join(home, ".exe-os", "exe-employees.json");
|
|
2426
|
+
const shouldMirrorToGlobalBin = homeDir === void 0;
|
|
2425
2427
|
mkdirSync(binDir, { recursive: true });
|
|
2426
2428
|
const exeStartDst = path.join(binDir, "exe-start");
|
|
2427
2429
|
const candidates = [
|
|
@@ -2462,15 +2464,18 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
2462
2464
|
const wrapperContent = `#!/bin/bash
|
|
2463
2465
|
exec "${exeStartDst}" "$0" "$@"
|
|
2464
2466
|
`;
|
|
2467
|
+
const globalBinDir = shouldMirrorToGlobalBin ? resolveGlobalBinDir() : null;
|
|
2465
2468
|
for (const emp of employees) {
|
|
2466
2469
|
for (let n = 1; n <= MAX_N; n++) {
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
+
writeWrapper(path.join(binDir, `${emp.name}${n}`), wrapperContent);
|
|
2471
|
+
if (globalBinDir) {
|
|
2472
|
+
writeWrapper(path.join(globalBinDir, `${emp.name}${n}`), wrapperContent);
|
|
2473
|
+
}
|
|
2470
2474
|
created++;
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2475
|
+
writeWrapper(path.join(binDir, `${emp.name}${n}-codex`), wrapperContent);
|
|
2476
|
+
if (globalBinDir) {
|
|
2477
|
+
writeWrapper(path.join(globalBinDir, `${emp.name}${n}-codex`), wrapperContent);
|
|
2478
|
+
}
|
|
2474
2479
|
created++;
|
|
2475
2480
|
}
|
|
2476
2481
|
}
|
|
@@ -2499,6 +2504,26 @@ exec node "${codexLauncher}" --agent ${emp.name} "$@"
|
|
|
2499
2504
|
const pathConfigured = ensurePath(home, binDir);
|
|
2500
2505
|
return { created, pathConfigured };
|
|
2501
2506
|
}
|
|
2507
|
+
function writeWrapper(wrapperPath, content) {
|
|
2508
|
+
try {
|
|
2509
|
+
writeFileSync(wrapperPath, content);
|
|
2510
|
+
chmodSync(wrapperPath, 493);
|
|
2511
|
+
} catch {
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
function resolveGlobalBinDir() {
|
|
2515
|
+
try {
|
|
2516
|
+
const exeOsPath = execSync("command -v exe-os", { encoding: "utf8", timeout: 3e3 }).trim().split("\n")[0];
|
|
2517
|
+
if (exeOsPath) return path.dirname(exeOsPath);
|
|
2518
|
+
} catch {
|
|
2519
|
+
}
|
|
2520
|
+
try {
|
|
2521
|
+
const prefix = execSync("npm prefix -g", { encoding: "utf8", timeout: 3e3 }).trim();
|
|
2522
|
+
if (prefix) return path.join(prefix, "bin");
|
|
2523
|
+
} catch {
|
|
2524
|
+
}
|
|
2525
|
+
return null;
|
|
2526
|
+
}
|
|
2502
2527
|
function ensurePath(home, binDir) {
|
|
2503
2528
|
if (process.env.PATH?.split(":").includes(binDir)) {
|
|
2504
2529
|
return false;
|
package/dist/bin/install.js
CHANGED
|
@@ -2057,7 +2057,7 @@ var init_installer2 = __esm({
|
|
|
2057
2057
|
// src/bin/install.ts
|
|
2058
2058
|
init_installer();
|
|
2059
2059
|
import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7, unlinkSync as unlinkSync3, readdirSync as readdirSync2, openSync, closeSync } from "fs";
|
|
2060
|
-
import { spawn, execSync as
|
|
2060
|
+
import { spawn, execSync as execSync4 } from "child_process";
|
|
2061
2061
|
import path10 from "path";
|
|
2062
2062
|
import os8 from "os";
|
|
2063
2063
|
|
|
@@ -2071,6 +2071,7 @@ import {
|
|
|
2071
2071
|
readdirSync,
|
|
2072
2072
|
unlinkSync as unlinkSync2
|
|
2073
2073
|
} from "fs";
|
|
2074
|
+
import { execSync as execSync3 } from "child_process";
|
|
2074
2075
|
import path8 from "path";
|
|
2075
2076
|
import { homedir } from "os";
|
|
2076
2077
|
var MAX_N = 9;
|
|
@@ -2078,6 +2079,7 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
2078
2079
|
const home = homeDir ?? homedir();
|
|
2079
2080
|
const binDir = path8.join(home, ".exe-os", "bin");
|
|
2080
2081
|
const rosterPath = path8.join(home, ".exe-os", "exe-employees.json");
|
|
2082
|
+
const shouldMirrorToGlobalBin = homeDir === void 0;
|
|
2081
2083
|
mkdirSync5(binDir, { recursive: true });
|
|
2082
2084
|
const exeStartDst = path8.join(binDir, "exe-start");
|
|
2083
2085
|
const candidates = [
|
|
@@ -2118,15 +2120,18 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
2118
2120
|
const wrapperContent = `#!/bin/bash
|
|
2119
2121
|
exec "${exeStartDst}" "$0" "$@"
|
|
2120
2122
|
`;
|
|
2123
|
+
const globalBinDir = shouldMirrorToGlobalBin ? resolveGlobalBinDir() : null;
|
|
2121
2124
|
for (const emp of employees) {
|
|
2122
2125
|
for (let n = 1; n <= MAX_N; n++) {
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
+
writeWrapper(path8.join(binDir, `${emp.name}${n}`), wrapperContent);
|
|
2127
|
+
if (globalBinDir) {
|
|
2128
|
+
writeWrapper(path8.join(globalBinDir, `${emp.name}${n}`), wrapperContent);
|
|
2129
|
+
}
|
|
2126
2130
|
created++;
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2131
|
+
writeWrapper(path8.join(binDir, `${emp.name}${n}-codex`), wrapperContent);
|
|
2132
|
+
if (globalBinDir) {
|
|
2133
|
+
writeWrapper(path8.join(globalBinDir, `${emp.name}${n}-codex`), wrapperContent);
|
|
2134
|
+
}
|
|
2130
2135
|
created++;
|
|
2131
2136
|
}
|
|
2132
2137
|
}
|
|
@@ -2155,6 +2160,26 @@ exec node "${codexLauncher}" --agent ${emp.name} "$@"
|
|
|
2155
2160
|
const pathConfigured = ensurePath(home, binDir);
|
|
2156
2161
|
return { created, pathConfigured };
|
|
2157
2162
|
}
|
|
2163
|
+
function writeWrapper(wrapperPath, content) {
|
|
2164
|
+
try {
|
|
2165
|
+
writeFileSync6(wrapperPath, content);
|
|
2166
|
+
chmodSync3(wrapperPath, 493);
|
|
2167
|
+
} catch {
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
function resolveGlobalBinDir() {
|
|
2171
|
+
try {
|
|
2172
|
+
const exeOsPath = execSync3("command -v exe-os", { encoding: "utf8", timeout: 3e3 }).trim().split("\n")[0];
|
|
2173
|
+
if (exeOsPath) return path8.dirname(exeOsPath);
|
|
2174
|
+
} catch {
|
|
2175
|
+
}
|
|
2176
|
+
try {
|
|
2177
|
+
const prefix = execSync3("npm prefix -g", { encoding: "utf8", timeout: 3e3 }).trim();
|
|
2178
|
+
if (prefix) return path8.join(prefix, "bin");
|
|
2179
|
+
} catch {
|
|
2180
|
+
}
|
|
2181
|
+
return null;
|
|
2182
|
+
}
|
|
2158
2183
|
function ensurePath(home, binDir) {
|
|
2159
2184
|
if (process.env.PATH?.split(":").includes(binDir)) {
|
|
2160
2185
|
return false;
|
|
@@ -2213,7 +2238,7 @@ function restartDaemon() {
|
|
|
2213
2238
|
}
|
|
2214
2239
|
}
|
|
2215
2240
|
try {
|
|
2216
|
-
const pids =
|
|
2241
|
+
const pids = execSync4("pgrep -f 'exe-daemon.js' 2>/dev/null || true", { encoding: "utf8" }).trim().split("\n").filter(Boolean).map(Number).filter((n) => !isNaN(n) && n !== process.pid);
|
|
2217
2242
|
for (const pid of pids) {
|
|
2218
2243
|
try {
|
|
2219
2244
|
process.kill(pid, "SIGKILL");
|
|
@@ -2227,7 +2252,7 @@ function restartDaemon() {
|
|
|
2227
2252
|
} catch {
|
|
2228
2253
|
}
|
|
2229
2254
|
try {
|
|
2230
|
-
const pids =
|
|
2255
|
+
const pids = execSync4("pgrep -f 'backfill-vectors.js' 2>/dev/null || true", { encoding: "utf8" }).trim().split("\n").filter(Boolean).map(Number).filter((n) => !isNaN(n) && n !== process.pid);
|
|
2231
2256
|
for (const pid of pids) {
|
|
2232
2257
|
try {
|
|
2233
2258
|
process.kill(pid, "SIGKILL");
|
|
@@ -2264,7 +2289,7 @@ function restartDaemon() {
|
|
|
2264
2289
|
} catch {
|
|
2265
2290
|
}
|
|
2266
2291
|
try {
|
|
2267
|
-
|
|
2292
|
+
execSync4("sleep 0.5");
|
|
2268
2293
|
} catch {
|
|
2269
2294
|
}
|
|
2270
2295
|
} catch {
|
|
@@ -2357,7 +2382,7 @@ if (args.includes("--commands-only")) {
|
|
|
2357
2382
|
`);
|
|
2358
2383
|
}
|
|
2359
2384
|
try {
|
|
2360
|
-
|
|
2385
|
+
execSync4("which codex", { encoding: "utf8", timeout: 5e3 });
|
|
2361
2386
|
const { runCodexInstaller: runCodexInstaller2 } = await Promise.resolve().then(() => (init_installer2(), installer_exports));
|
|
2362
2387
|
await runCodexInstaller2();
|
|
2363
2388
|
} catch {
|
package/dist/bin/setup.js
CHANGED
|
@@ -911,8 +911,8 @@ function findPackageRoot() {
|
|
|
911
911
|
function getAvailableMemoryGB() {
|
|
912
912
|
if (process.platform === "darwin") {
|
|
913
913
|
try {
|
|
914
|
-
const { execSync:
|
|
915
|
-
const vmstat =
|
|
914
|
+
const { execSync: execSync4 } = __require("child_process");
|
|
915
|
+
const vmstat = execSync4("vm_stat", { encoding: "utf8" });
|
|
916
916
|
const pageSize = 16384;
|
|
917
917
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
918
918
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -7906,12 +7906,14 @@ import {
|
|
|
7906
7906
|
readdirSync as readdirSync4,
|
|
7907
7907
|
unlinkSync as unlinkSync7
|
|
7908
7908
|
} from "fs";
|
|
7909
|
+
import { execSync as execSync3 } from "child_process";
|
|
7909
7910
|
import path16 from "path";
|
|
7910
7911
|
import { homedir as homedir3 } from "os";
|
|
7911
7912
|
function generateSessionWrappers(packageRoot, homeDir) {
|
|
7912
7913
|
const home = homeDir ?? homedir3();
|
|
7913
7914
|
const binDir = path16.join(home, ".exe-os", "bin");
|
|
7914
7915
|
const rosterPath = path16.join(home, ".exe-os", "exe-employees.json");
|
|
7916
|
+
const shouldMirrorToGlobalBin = homeDir === void 0;
|
|
7915
7917
|
mkdirSync8(binDir, { recursive: true });
|
|
7916
7918
|
const exeStartDst = path16.join(binDir, "exe-start");
|
|
7917
7919
|
const candidates = [
|
|
@@ -7952,15 +7954,18 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
7952
7954
|
const wrapperContent = `#!/bin/bash
|
|
7953
7955
|
exec "${exeStartDst}" "$0" "$@"
|
|
7954
7956
|
`;
|
|
7957
|
+
const globalBinDir = shouldMirrorToGlobalBin ? resolveGlobalBinDir() : null;
|
|
7955
7958
|
for (const emp of employees) {
|
|
7956
7959
|
for (let n = 1; n <= MAX_N; n++) {
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
+
writeWrapper(path16.join(binDir, `${emp.name}${n}`), wrapperContent);
|
|
7961
|
+
if (globalBinDir) {
|
|
7962
|
+
writeWrapper(path16.join(globalBinDir, `${emp.name}${n}`), wrapperContent);
|
|
7963
|
+
}
|
|
7960
7964
|
created++;
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7965
|
+
writeWrapper(path16.join(binDir, `${emp.name}${n}-codex`), wrapperContent);
|
|
7966
|
+
if (globalBinDir) {
|
|
7967
|
+
writeWrapper(path16.join(globalBinDir, `${emp.name}${n}-codex`), wrapperContent);
|
|
7968
|
+
}
|
|
7964
7969
|
created++;
|
|
7965
7970
|
}
|
|
7966
7971
|
}
|
|
@@ -7989,6 +7994,26 @@ exec node "${codexLauncher}" --agent ${emp.name} "$@"
|
|
|
7989
7994
|
const pathConfigured = ensurePath(home, binDir);
|
|
7990
7995
|
return { created, pathConfigured };
|
|
7991
7996
|
}
|
|
7997
|
+
function writeWrapper(wrapperPath, content) {
|
|
7998
|
+
try {
|
|
7999
|
+
writeFileSync10(wrapperPath, content);
|
|
8000
|
+
chmodSync2(wrapperPath, 493);
|
|
8001
|
+
} catch {
|
|
8002
|
+
}
|
|
8003
|
+
}
|
|
8004
|
+
function resolveGlobalBinDir() {
|
|
8005
|
+
try {
|
|
8006
|
+
const exeOsPath = execSync3("command -v exe-os", { encoding: "utf8", timeout: 3e3 }).trim().split("\n")[0];
|
|
8007
|
+
if (exeOsPath) return path16.dirname(exeOsPath);
|
|
8008
|
+
} catch {
|
|
8009
|
+
}
|
|
8010
|
+
try {
|
|
8011
|
+
const prefix = execSync3("npm prefix -g", { encoding: "utf8", timeout: 3e3 }).trim();
|
|
8012
|
+
if (prefix) return path16.join(prefix, "bin");
|
|
8013
|
+
} catch {
|
|
8014
|
+
}
|
|
8015
|
+
return null;
|
|
8016
|
+
}
|
|
7992
8017
|
function ensurePath(home, binDir) {
|
|
7993
8018
|
if (process.env.PATH?.split(":").includes(binDir)) {
|
|
7994
8019
|
return false;
|
|
@@ -8177,8 +8202,8 @@ function ask(rl, prompt) {
|
|
|
8177
8202
|
function getAvailableMemoryGB2() {
|
|
8178
8203
|
if (process.platform === "darwin") {
|
|
8179
8204
|
try {
|
|
8180
|
-
const { execSync:
|
|
8181
|
-
const vmstat =
|
|
8205
|
+
const { execSync: execSync4 } = __require("child_process");
|
|
8206
|
+
const vmstat = execSync4("vm_stat", { encoding: "utf8" });
|
|
8182
8207
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
8183
8208
|
const pageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : 16384;
|
|
8184
8209
|
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
readdirSync,
|
|
9
9
|
unlinkSync
|
|
10
10
|
} from "fs";
|
|
11
|
+
import { execSync } from "child_process";
|
|
11
12
|
import path from "path";
|
|
12
13
|
import { homedir } from "os";
|
|
13
14
|
var MAX_N = 9;
|
|
@@ -15,6 +16,7 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
15
16
|
const home = homeDir ?? homedir();
|
|
16
17
|
const binDir = path.join(home, ".exe-os", "bin");
|
|
17
18
|
const rosterPath = path.join(home, ".exe-os", "exe-employees.json");
|
|
19
|
+
const shouldMirrorToGlobalBin = homeDir === void 0;
|
|
18
20
|
mkdirSync(binDir, { recursive: true });
|
|
19
21
|
const exeStartDst = path.join(binDir, "exe-start");
|
|
20
22
|
const candidates = [
|
|
@@ -55,15 +57,18 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
55
57
|
const wrapperContent = `#!/bin/bash
|
|
56
58
|
exec "${exeStartDst}" "$0" "$@"
|
|
57
59
|
`;
|
|
60
|
+
const globalBinDir = shouldMirrorToGlobalBin ? resolveGlobalBinDir() : null;
|
|
58
61
|
for (const emp of employees) {
|
|
59
62
|
for (let n = 1; n <= MAX_N; n++) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
writeWrapper(path.join(binDir, `${emp.name}${n}`), wrapperContent);
|
|
64
|
+
if (globalBinDir) {
|
|
65
|
+
writeWrapper(path.join(globalBinDir, `${emp.name}${n}`), wrapperContent);
|
|
66
|
+
}
|
|
63
67
|
created++;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
writeWrapper(path.join(binDir, `${emp.name}${n}-codex`), wrapperContent);
|
|
69
|
+
if (globalBinDir) {
|
|
70
|
+
writeWrapper(path.join(globalBinDir, `${emp.name}${n}-codex`), wrapperContent);
|
|
71
|
+
}
|
|
67
72
|
created++;
|
|
68
73
|
}
|
|
69
74
|
}
|
|
@@ -92,6 +97,26 @@ exec node "${codexLauncher}" --agent ${emp.name} "$@"
|
|
|
92
97
|
const pathConfigured = ensurePath(home, binDir);
|
|
93
98
|
return { created, pathConfigured };
|
|
94
99
|
}
|
|
100
|
+
function writeWrapper(wrapperPath, content) {
|
|
101
|
+
try {
|
|
102
|
+
writeFileSync(wrapperPath, content);
|
|
103
|
+
chmodSync(wrapperPath, 493);
|
|
104
|
+
} catch {
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function resolveGlobalBinDir() {
|
|
108
|
+
try {
|
|
109
|
+
const exeOsPath = execSync("command -v exe-os", { encoding: "utf8", timeout: 3e3 }).trim().split("\n")[0];
|
|
110
|
+
if (exeOsPath) return path.dirname(exeOsPath);
|
|
111
|
+
} catch {
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
const prefix = execSync("npm prefix -g", { encoding: "utf8", timeout: 3e3 }).trim();
|
|
115
|
+
if (prefix) return path.join(prefix, "bin");
|
|
116
|
+
} catch {
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
95
120
|
function ensurePath(home, binDir) {
|
|
96
121
|
if (process.env.PATH?.split(":").includes(binDir)) {
|
|
97
122
|
return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askexenow/exe-os",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.74",
|
|
4
4
|
"description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|