@askexenow/exe-os 0.9.47 → 0.9.49
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 +354 -107
- package/dist/bin/exe-new-employee.js +52 -8
- package/dist/bin/exe-start-codex.js +2 -2
- package/dist/bin/exe-start-opencode.js +2 -2
- package/dist/bin/install.js +57 -13
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -825,8 +825,8 @@ __export(installer_exports, {
|
|
|
825
825
|
setupTmux: () => setupTmux
|
|
826
826
|
});
|
|
827
827
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
|
|
828
|
-
import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4, copyFileSync, mkdirSync as mkdirSync3 } from "fs";
|
|
829
|
-
import { createHash } from "crypto";
|
|
828
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4, copyFileSync, mkdirSync as mkdirSync3, chmodSync as chmodSync2 } from "fs";
|
|
829
|
+
import { createHash, randomBytes } from "crypto";
|
|
830
830
|
import path6 from "path";
|
|
831
831
|
import os5 from "os";
|
|
832
832
|
import { execSync as execSync2 } from "child_process";
|
|
@@ -955,6 +955,55 @@ function detectMcpNameCollisions(homeDir = os5.homedir(), cwd2 = process.cwd())
|
|
|
955
955
|
}
|
|
956
956
|
return collisions;
|
|
957
957
|
}
|
|
958
|
+
function readOrCreateDaemonToken(homeDir) {
|
|
959
|
+
const exeDir = path6.join(homeDir, ".exe-os");
|
|
960
|
+
const tokenPath = path6.join(exeDir, "exed.token");
|
|
961
|
+
try {
|
|
962
|
+
if (existsSync7(tokenPath)) {
|
|
963
|
+
const token2 = readFileSync5(tokenPath, "utf-8").trim();
|
|
964
|
+
if (token2) return token2;
|
|
965
|
+
}
|
|
966
|
+
} catch {
|
|
967
|
+
}
|
|
968
|
+
const token = randomBytes(32).toString("hex");
|
|
969
|
+
mkdirSync3(exeDir, { recursive: true });
|
|
970
|
+
writeFileSync4(tokenPath, `${token}
|
|
971
|
+
`, "utf-8");
|
|
972
|
+
try {
|
|
973
|
+
chmodSync2(tokenPath, 384);
|
|
974
|
+
} catch {
|
|
975
|
+
}
|
|
976
|
+
return token;
|
|
977
|
+
}
|
|
978
|
+
function buildHttpMcpEntry(homeDir) {
|
|
979
|
+
const port = process.env.EXE_MCP_PORT || "48739";
|
|
980
|
+
const token = readOrCreateDaemonToken(homeDir);
|
|
981
|
+
return {
|
|
982
|
+
type: "http",
|
|
983
|
+
url: `http://127.0.0.1:${port}/mcp`,
|
|
984
|
+
headers: {
|
|
985
|
+
Authorization: `Bearer ${token}`,
|
|
986
|
+
"X-Agent-Id": "${AGENT_ID:-exe}",
|
|
987
|
+
"X-Agent-Role": "${AGENT_ROLE:-COO}"
|
|
988
|
+
}
|
|
989
|
+
};
|
|
990
|
+
}
|
|
991
|
+
function buildStdioMcpEntry(packageRoot) {
|
|
992
|
+
return {
|
|
993
|
+
type: "stdio",
|
|
994
|
+
command: "node",
|
|
995
|
+
args: [path6.join(packageRoot, "dist", "mcp", "server.js")],
|
|
996
|
+
env: {}
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
function mcpTransportMode() {
|
|
1000
|
+
const value = process.env.EXE_OS_MCP_TRANSPORT?.trim().toLowerCase();
|
|
1001
|
+
if (value === "stdio") return "stdio";
|
|
1002
|
+
if (value === "http") return "http";
|
|
1003
|
+
const totalGB = os5.totalmem() / (1024 * 1024 * 1024);
|
|
1004
|
+
if (totalGB <= 8) return "stdio";
|
|
1005
|
+
return "http";
|
|
1006
|
+
}
|
|
958
1007
|
async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
|
|
959
1008
|
const claudeJsonPath = path6.join(homeDir, ".claude.json");
|
|
960
1009
|
let claudeJson = {};
|
|
@@ -968,12 +1017,7 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
|
|
|
968
1017
|
if (!claudeJson.mcpServers) {
|
|
969
1018
|
claudeJson.mcpServers = {};
|
|
970
1019
|
}
|
|
971
|
-
const newEntry =
|
|
972
|
-
type: "stdio",
|
|
973
|
-
command: "node",
|
|
974
|
-
args: [path6.join(packageRoot, "dist", "mcp", "server.js")],
|
|
975
|
-
env: {}
|
|
976
|
-
};
|
|
1020
|
+
const newEntry = mcpTransportMode() === "stdio" ? buildStdioMcpEntry(packageRoot) : buildHttpMcpEntry(homeDir);
|
|
977
1021
|
if (claudeJson.mcpServers[MCP_LEGACY_KEY]) {
|
|
978
1022
|
delete claudeJson.mcpServers[MCP_LEGACY_KEY];
|
|
979
1023
|
process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
|
|
@@ -1842,8 +1886,8 @@ function deriveMachineKey() {
|
|
|
1842
1886
|
}
|
|
1843
1887
|
function readMachineId() {
|
|
1844
1888
|
try {
|
|
1845
|
-
const { readFileSync:
|
|
1846
|
-
return
|
|
1889
|
+
const { readFileSync: readFileSync31 } = __require("fs");
|
|
1890
|
+
return readFileSync31("/etc/machine-id", "utf-8").trim();
|
|
1847
1891
|
} catch {
|
|
1848
1892
|
return "";
|
|
1849
1893
|
}
|
|
@@ -9096,9 +9140,9 @@ Unclassified: ${unclassified}
|
|
|
9096
9140
|
}
|
|
9097
9141
|
async function exportBatches(options) {
|
|
9098
9142
|
const fs8 = await import("fs");
|
|
9099
|
-
const
|
|
9143
|
+
const path50 = await import("path");
|
|
9100
9144
|
const client = getClient();
|
|
9101
|
-
const outDir =
|
|
9145
|
+
const outDir = path50.join(process.cwd(), "exe/output/classifications/input");
|
|
9102
9146
|
fs8.mkdirSync(outDir, { recursive: true });
|
|
9103
9147
|
const countResult = await client.execute({
|
|
9104
9148
|
sql: "SELECT COUNT(*) as cnt FROM memories WHERE intent IS NULL AND outcome IS NULL AND domain IS NULL",
|
|
@@ -9122,7 +9166,7 @@ async function exportBatches(options) {
|
|
|
9122
9166
|
const text = String(row.text || "").replace(/\n/g, " ");
|
|
9123
9167
|
return JSON.stringify({ id: row.id, text });
|
|
9124
9168
|
});
|
|
9125
|
-
const batchFile =
|
|
9169
|
+
const batchFile = path50.join(outDir, `batch-${String(batchNum).padStart(4, "0")}.jsonl`);
|
|
9126
9170
|
fs8.writeFileSync(batchFile, lines.join("\n") + "\n");
|
|
9127
9171
|
exported += batch.rows.length;
|
|
9128
9172
|
offset += options.batchSize;
|
|
@@ -9138,7 +9182,7 @@ async function exportBatches(options) {
|
|
|
9138
9182
|
}
|
|
9139
9183
|
async function importClassifications(importDir) {
|
|
9140
9184
|
const fs8 = await import("fs");
|
|
9141
|
-
const
|
|
9185
|
+
const path50 = await import("path");
|
|
9142
9186
|
const client = getClient();
|
|
9143
9187
|
const files = fs8.readdirSync(importDir).filter((f) => f.endsWith(".jsonl")).sort();
|
|
9144
9188
|
process.stderr.write(`[backfill-metadata] Found ${files.length} JSONL files to import from ${importDir}
|
|
@@ -9146,7 +9190,7 @@ async function importClassifications(importDir) {
|
|
|
9146
9190
|
let imported = 0;
|
|
9147
9191
|
let invalid = 0;
|
|
9148
9192
|
for (const file of files) {
|
|
9149
|
-
const lines = fs8.readFileSync(
|
|
9193
|
+
const lines = fs8.readFileSync(path50.join(importDir, file), "utf-8").split("\n").filter(Boolean);
|
|
9150
9194
|
for (const line of lines) {
|
|
9151
9195
|
try {
|
|
9152
9196
|
const rec = JSON.parse(line);
|
|
@@ -11784,10 +11828,10 @@ async function disposeEmbedder() {
|
|
|
11784
11828
|
async function embedDirect(text) {
|
|
11785
11829
|
const llamaCpp = await import("node-llama-cpp");
|
|
11786
11830
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
11787
|
-
const { existsSync:
|
|
11788
|
-
const
|
|
11789
|
-
const modelPath =
|
|
11790
|
-
if (!
|
|
11831
|
+
const { existsSync: existsSync36 } = await import("fs");
|
|
11832
|
+
const path50 = await import("path");
|
|
11833
|
+
const modelPath = path50.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
11834
|
+
if (!existsSync36(modelPath)) {
|
|
11791
11835
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
11792
11836
|
}
|
|
11793
11837
|
const llama = await llamaCpp.getLlama();
|
|
@@ -15365,7 +15409,7 @@ import {
|
|
|
15365
15409
|
readFileSync as readFileSync22,
|
|
15366
15410
|
writeFileSync as writeFileSync18,
|
|
15367
15411
|
mkdirSync as mkdirSync17,
|
|
15368
|
-
chmodSync as
|
|
15412
|
+
chmodSync as chmodSync3,
|
|
15369
15413
|
readdirSync as readdirSync9,
|
|
15370
15414
|
unlinkSync as unlinkSync13
|
|
15371
15415
|
} from "fs";
|
|
@@ -15384,7 +15428,7 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
15384
15428
|
for (const src of candidates) {
|
|
15385
15429
|
if (existsSync27(src)) {
|
|
15386
15430
|
writeFileSync18(exeStartDst, readFileSync22(src));
|
|
15387
|
-
|
|
15431
|
+
chmodSync3(exeStartDst, 493);
|
|
15388
15432
|
break;
|
|
15389
15433
|
}
|
|
15390
15434
|
}
|
|
@@ -15419,11 +15463,11 @@ exec "${exeStartDst}" "$0" "$@"
|
|
|
15419
15463
|
for (let n = 1; n <= MAX_N; n++) {
|
|
15420
15464
|
const wrapperPath = path33.join(binDir, `${emp.name}${n}`);
|
|
15421
15465
|
writeFileSync18(wrapperPath, wrapperContent);
|
|
15422
|
-
|
|
15466
|
+
chmodSync3(wrapperPath, 493);
|
|
15423
15467
|
created++;
|
|
15424
15468
|
const codexPath = path33.join(binDir, `${emp.name}${n}-codex`);
|
|
15425
15469
|
writeFileSync18(codexPath, wrapperContent);
|
|
15426
|
-
|
|
15470
|
+
chmodSync3(codexPath, 493);
|
|
15427
15471
|
created++;
|
|
15428
15472
|
}
|
|
15429
15473
|
}
|
|
@@ -15445,7 +15489,7 @@ exec "${exeStartDst}" "$0" "$@"
|
|
|
15445
15489
|
exec node "${codexLauncher}" --agent ${emp.name} "$@"
|
|
15446
15490
|
`;
|
|
15447
15491
|
writeFileSync18(wrapperPath, content);
|
|
15448
|
-
|
|
15492
|
+
chmodSync3(wrapperPath, 493);
|
|
15449
15493
|
created++;
|
|
15450
15494
|
}
|
|
15451
15495
|
}
|
|
@@ -21264,8 +21308,8 @@ var init_ErrorOverview = __esm({
|
|
|
21264
21308
|
"use strict";
|
|
21265
21309
|
init_Box();
|
|
21266
21310
|
init_Text();
|
|
21267
|
-
cleanupPath = (
|
|
21268
|
-
return
|
|
21311
|
+
cleanupPath = (path50) => {
|
|
21312
|
+
return path50?.replace(`file://${cwd()}/`, "");
|
|
21269
21313
|
};
|
|
21270
21314
|
stackUtils = new StackUtils({
|
|
21271
21315
|
cwd: cwd(),
|
|
@@ -23673,11 +23717,11 @@ function Footer() {
|
|
|
23673
23717
|
} catch {
|
|
23674
23718
|
}
|
|
23675
23719
|
try {
|
|
23676
|
-
const { existsSync:
|
|
23720
|
+
const { existsSync: existsSync36 } = await import("fs");
|
|
23677
23721
|
const { join } = await import("path");
|
|
23678
23722
|
const home = process.env.HOME ?? "";
|
|
23679
23723
|
const pidPath = join(home, ".exe-os", "exed.pid");
|
|
23680
|
-
setDaemon(
|
|
23724
|
+
setDaemon(existsSync36(pidPath) ? "running" : "stopped");
|
|
23681
23725
|
} catch {
|
|
23682
23726
|
setDaemon("unknown");
|
|
23683
23727
|
}
|
|
@@ -26461,15 +26505,15 @@ function CommandCenterView({
|
|
|
26461
26505
|
const { createPermissionsFromPreset: createPermissionsFromPreset2, EMPLOYEE_PERMISSIONS: EMPLOYEE_PERMISSIONS2 } = await Promise.resolve().then(() => (init_permissions(), permissions_exports));
|
|
26462
26506
|
const { getPresetByRole: getPresetByRole2 } = await Promise.resolve().then(() => (init_permission_presets(), permission_presets_exports));
|
|
26463
26507
|
const { createDefaultHooks: createDefaultHooks2 } = await Promise.resolve().then(() => (init_hooks(), hooks_exports));
|
|
26464
|
-
const { readFileSync:
|
|
26508
|
+
const { readFileSync: readFileSync31, existsSync: existsSync36 } = await import("fs");
|
|
26465
26509
|
const { join } = await import("path");
|
|
26466
26510
|
const { homedir: homedir8 } = await import("os");
|
|
26467
26511
|
const configPath = join(homedir8(), ".exe-os", "config.json");
|
|
26468
26512
|
let failoverChain = ["anthropic", "opencode", "gemini", "openai"];
|
|
26469
26513
|
let providerConfigs = {};
|
|
26470
|
-
if (
|
|
26514
|
+
if (existsSync36(configPath)) {
|
|
26471
26515
|
try {
|
|
26472
|
-
const raw = JSON.parse(
|
|
26516
|
+
const raw = JSON.parse(readFileSync31(configPath, "utf8"));
|
|
26473
26517
|
if (Array.isArray(raw.failoverChain)) failoverChain = raw.failoverChain;
|
|
26474
26518
|
if (raw.providers && typeof raw.providers === "object") {
|
|
26475
26519
|
providerConfigs = raw.providers;
|
|
@@ -26530,7 +26574,7 @@ function CommandCenterView({
|
|
|
26530
26574
|
const markerDir = join(homedir8(), ".exe-os", "session-cache");
|
|
26531
26575
|
const agentFiles = (await import("fs")).readdirSync(markerDir).filter((f) => f.startsWith("active-agent-"));
|
|
26532
26576
|
for (const f of agentFiles) {
|
|
26533
|
-
const data = JSON.parse(
|
|
26577
|
+
const data = JSON.parse(readFileSync31(join(markerDir, f), "utf8"));
|
|
26534
26578
|
if (data.agentRole) {
|
|
26535
26579
|
agentRole = data.agentRole;
|
|
26536
26580
|
break;
|
|
@@ -26713,7 +26757,7 @@ function CommandCenterView({
|
|
|
26713
26757
|
const { listSessions: listSessions2 } = await Promise.resolve().then(() => (init_session_registry(), session_registry_exports));
|
|
26714
26758
|
const { listTmuxSessions: listTmuxSessions2, inTmux: inTmux2 } = await Promise.resolve().then(() => (init_tmux_status(), tmux_status_exports));
|
|
26715
26759
|
const { loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
26716
|
-
const { existsSync:
|
|
26760
|
+
const { existsSync: existsSync36 } = await import("fs");
|
|
26717
26761
|
const { join } = await import("path");
|
|
26718
26762
|
const client = getClient2();
|
|
26719
26763
|
if (!client) {
|
|
@@ -26784,7 +26828,7 @@ function CommandCenterView({
|
|
|
26784
26828
|
}
|
|
26785
26829
|
const memoryCount = memoryCounts.get(name) ?? 0;
|
|
26786
26830
|
const openTaskCount = openTaskCounts.get(name) ?? 0;
|
|
26787
|
-
const hasGit = projectDir ?
|
|
26831
|
+
const hasGit = projectDir ? existsSync36(join(projectDir, ".git")) : false;
|
|
26788
26832
|
const type = hasGit ? "code" : memoryCount > 0 ? "code" : "automation";
|
|
26789
26833
|
projectList.push({
|
|
26790
26834
|
projectName: name,
|
|
@@ -26809,7 +26853,7 @@ function CommandCenterView({
|
|
|
26809
26853
|
setHealth((h) => ({ ...h, memories: Number(totalResult.rows[0]?.cnt ?? 0) }));
|
|
26810
26854
|
try {
|
|
26811
26855
|
const pidPath = join(process.env.HOME ?? "", ".exe-os", "exed.pid");
|
|
26812
|
-
setHealth((h) => ({ ...h, daemon:
|
|
26856
|
+
setHealth((h) => ({ ...h, daemon: existsSync36(pidPath) ? "running" : "stopped" }));
|
|
26813
26857
|
} catch {
|
|
26814
26858
|
}
|
|
26815
26859
|
const activityResult = await client.execute(
|
|
@@ -28932,12 +28976,12 @@ async function loadGatewayConfig() {
|
|
|
28932
28976
|
state.running = false;
|
|
28933
28977
|
}
|
|
28934
28978
|
try {
|
|
28935
|
-
const { existsSync:
|
|
28979
|
+
const { existsSync: existsSync36, readFileSync: readFileSync31 } = await import("fs");
|
|
28936
28980
|
const { join } = await import("path");
|
|
28937
28981
|
const home = process.env.HOME ?? "";
|
|
28938
28982
|
const configPath = join(home, ".exe-os", "gateway.json");
|
|
28939
|
-
if (
|
|
28940
|
-
const raw = JSON.parse(
|
|
28983
|
+
if (existsSync36(configPath)) {
|
|
28984
|
+
const raw = JSON.parse(readFileSync31(configPath, "utf8"));
|
|
28941
28985
|
state.port = raw.port ?? 3100;
|
|
28942
28986
|
state.gatewayUrl = raw.gatewayUrl ?? "";
|
|
28943
28987
|
if (raw.adapters) {
|
|
@@ -29535,12 +29579,12 @@ function TeamView({ onBack, onViewSessions }) {
|
|
|
29535
29579
|
setMembers(teamData);
|
|
29536
29580
|
setDbError(null);
|
|
29537
29581
|
try {
|
|
29538
|
-
const { existsSync:
|
|
29582
|
+
const { existsSync: existsSync36, readFileSync: readFileSync31 } = await import("fs");
|
|
29539
29583
|
const { join } = await import("path");
|
|
29540
29584
|
const home = process.env.HOME ?? "";
|
|
29541
29585
|
const gatewayConfig = join(home, ".exe-os", "gateway.json");
|
|
29542
|
-
if (
|
|
29543
|
-
const raw = JSON.parse(
|
|
29586
|
+
if (existsSync36(gatewayConfig)) {
|
|
29587
|
+
const raw = JSON.parse(readFileSync31(gatewayConfig, "utf8"));
|
|
29544
29588
|
if (raw.agents && raw.agents.length > 0) {
|
|
29545
29589
|
setExternals(raw.agents.map((a) => ({
|
|
29546
29590
|
name: a.name,
|
|
@@ -29720,8 +29764,8 @@ __export(wiki_client_exports, {
|
|
|
29720
29764
|
listDocuments: () => listDocuments,
|
|
29721
29765
|
listWorkspaces: () => listWorkspaces
|
|
29722
29766
|
});
|
|
29723
|
-
async function wikiFetch(config,
|
|
29724
|
-
const url = `${config.baseUrl}/api/v1${
|
|
29767
|
+
async function wikiFetch(config, path50, method = "GET", body) {
|
|
29768
|
+
const url = `${config.baseUrl}/api/v1${path50}`;
|
|
29725
29769
|
const headers = {
|
|
29726
29770
|
Authorization: `Bearer ${config.apiKey}`,
|
|
29727
29771
|
"Content-Type": "application/json"
|
|
@@ -29754,7 +29798,7 @@ async function wikiFetch(config, path49, method = "GET", body) {
|
|
|
29754
29798
|
}
|
|
29755
29799
|
}
|
|
29756
29800
|
if (!response.ok) {
|
|
29757
|
-
throw new Error(`Wiki API ${method} ${
|
|
29801
|
+
throw new Error(`Wiki API ${method} ${path50}: ${response.status} ${response.statusText}`);
|
|
29758
29802
|
}
|
|
29759
29803
|
return response.json();
|
|
29760
29804
|
} finally {
|
|
@@ -30348,12 +30392,12 @@ function SettingsView({ onBack }) {
|
|
|
30348
30392
|
}
|
|
30349
30393
|
setProviders(providerList);
|
|
30350
30394
|
try {
|
|
30351
|
-
const { existsSync:
|
|
30395
|
+
const { existsSync: existsSync36 } = await import("fs");
|
|
30352
30396
|
const { join } = await import("path");
|
|
30353
30397
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
30354
30398
|
const cfg = await loadConfig2();
|
|
30355
30399
|
const home = process.env.HOME ?? "";
|
|
30356
|
-
const hasKey =
|
|
30400
|
+
const hasKey = existsSync36(join(home, ".exe-os", "master.key"));
|
|
30357
30401
|
if (cfg.cloud) {
|
|
30358
30402
|
setCloud({
|
|
30359
30403
|
configured: true,
|
|
@@ -30366,22 +30410,22 @@ function SettingsView({ onBack }) {
|
|
|
30366
30410
|
const pidPath = join(home, ".exe-os", "exed.pid");
|
|
30367
30411
|
let daemon = "unknown";
|
|
30368
30412
|
try {
|
|
30369
|
-
daemon =
|
|
30413
|
+
daemon = existsSync36(pidPath) ? "running" : "stopped";
|
|
30370
30414
|
} catch {
|
|
30371
30415
|
}
|
|
30372
30416
|
let version = "unknown";
|
|
30373
30417
|
try {
|
|
30374
|
-
const { readFileSync:
|
|
30418
|
+
const { readFileSync: readFileSync31 } = await import("fs");
|
|
30375
30419
|
const { createRequire: createRequire3 } = await import("module");
|
|
30376
30420
|
const require2 = createRequire3(import.meta.url);
|
|
30377
30421
|
const pkgPath = require2.resolve("@askexenow/exe-os/package.json");
|
|
30378
|
-
const pkg = JSON.parse(
|
|
30422
|
+
const pkg = JSON.parse(readFileSync31(pkgPath, "utf8"));
|
|
30379
30423
|
version = pkg.version;
|
|
30380
30424
|
} catch {
|
|
30381
30425
|
try {
|
|
30382
|
-
const { readFileSync:
|
|
30426
|
+
const { readFileSync: readFileSync31 } = await import("fs");
|
|
30383
30427
|
const { join: joinPath } = await import("path");
|
|
30384
|
-
const pkg = JSON.parse(
|
|
30428
|
+
const pkg = JSON.parse(readFileSync31(joinPath(process.cwd(), "package.json"), "utf8"));
|
|
30385
30429
|
version = pkg.version;
|
|
30386
30430
|
} catch {
|
|
30387
30431
|
}
|
|
@@ -31580,15 +31624,199 @@ var init_installer3 = __esm({
|
|
|
31580
31624
|
}
|
|
31581
31625
|
});
|
|
31582
31626
|
|
|
31583
|
-
// src/
|
|
31584
|
-
|
|
31627
|
+
// src/adapters/claude/mcp-diagnostics.ts
|
|
31628
|
+
var mcp_diagnostics_exports = {};
|
|
31629
|
+
__export(mcp_diagnostics_exports, {
|
|
31630
|
+
diagnoseClaudeMcpConfig: () => diagnoseClaudeMcpConfig,
|
|
31631
|
+
formatMcpDiagnosticReport: () => formatMcpDiagnosticReport
|
|
31632
|
+
});
|
|
31633
|
+
import { existsSync as existsSync34, readFileSync as readFileSync29 } from "fs";
|
|
31585
31634
|
import path48 from "path";
|
|
31586
31635
|
import os21 from "os";
|
|
31636
|
+
function readJson(filePath) {
|
|
31637
|
+
if (!existsSync34(filePath)) return null;
|
|
31638
|
+
try {
|
|
31639
|
+
return JSON.parse(readFileSync29(filePath, "utf8"));
|
|
31640
|
+
} catch {
|
|
31641
|
+
return null;
|
|
31642
|
+
}
|
|
31643
|
+
}
|
|
31644
|
+
function pathApplies2(projectPath, cwd2) {
|
|
31645
|
+
const project = path48.resolve(projectPath);
|
|
31646
|
+
const current = path48.resolve(cwd2);
|
|
31647
|
+
return current === project || current.startsWith(project + path48.sep);
|
|
31648
|
+
}
|
|
31649
|
+
function findAncestorMcpJsons2(cwd2, homeDir) {
|
|
31650
|
+
const files = [];
|
|
31651
|
+
let dir = path48.resolve(cwd2);
|
|
31652
|
+
const root = path48.parse(dir).root;
|
|
31653
|
+
const stop = path48.resolve(homeDir);
|
|
31654
|
+
while (dir !== root) {
|
|
31655
|
+
const candidate = path48.join(dir, ".mcp.json");
|
|
31656
|
+
if (existsSync34(candidate)) files.push(candidate);
|
|
31657
|
+
if (dir === stop) break;
|
|
31658
|
+
dir = path48.dirname(dir);
|
|
31659
|
+
}
|
|
31660
|
+
return files;
|
|
31661
|
+
}
|
|
31662
|
+
function extractPermissionPrefixes(settings) {
|
|
31663
|
+
const allow = settings?.permissions?.allow ?? [];
|
|
31664
|
+
const prefixes = /* @__PURE__ */ new Set();
|
|
31665
|
+
for (const entry of allow) {
|
|
31666
|
+
const match = entry.match(/^mcp__(.+?)__/);
|
|
31667
|
+
if (match?.[1]) prefixes.add(match[1]);
|
|
31668
|
+
}
|
|
31669
|
+
return [...prefixes].sort();
|
|
31670
|
+
}
|
|
31671
|
+
function serverAllowedByPermissions(serverName, prefixes) {
|
|
31672
|
+
return prefixes.has(serverName) || prefixes.has(serverName.replace(/-/g, "_"));
|
|
31673
|
+
}
|
|
31674
|
+
function diagnoseClaudeMcpConfig(homeDir = os21.homedir(), cwd2 = process.cwd(), env = process.env) {
|
|
31675
|
+
const claudeJsonPath = path48.join(homeDir, ".claude.json");
|
|
31676
|
+
const settingsPath = path48.join(homeDir, ".claude", "settings.json");
|
|
31677
|
+
const claudeJson = readJson(claudeJsonPath);
|
|
31678
|
+
const settings = readJson(settingsPath);
|
|
31679
|
+
const issues = [];
|
|
31680
|
+
if (!claudeJson) {
|
|
31681
|
+
issues.push({
|
|
31682
|
+
severity: "error",
|
|
31683
|
+
code: "claude-json-missing-or-invalid",
|
|
31684
|
+
message: "~/.claude.json is missing or invalid, so Claude MCP server config cannot be audited.",
|
|
31685
|
+
fix: "Run exe-os claude install, then re-open Claude Code."
|
|
31686
|
+
});
|
|
31687
|
+
}
|
|
31688
|
+
if (!settings) {
|
|
31689
|
+
issues.push({
|
|
31690
|
+
severity: "warn",
|
|
31691
|
+
code: "settings-json-missing-or-invalid",
|
|
31692
|
+
message: "~/.claude/settings.json is missing or invalid; MCP permissions cannot be audited.",
|
|
31693
|
+
fix: "Run exe-os claude install, then re-open Claude Code."
|
|
31694
|
+
});
|
|
31695
|
+
}
|
|
31696
|
+
const globalServers = Object.keys(claudeJson?.mcpServers ?? {}).sort();
|
|
31697
|
+
const projectServers = [];
|
|
31698
|
+
const applicableProjects = [];
|
|
31699
|
+
for (const [projectPath, projectConfig] of Object.entries(claudeJson?.projects ?? {})) {
|
|
31700
|
+
if (!pathApplies2(projectPath, cwd2)) continue;
|
|
31701
|
+
applicableProjects.push([projectPath, projectConfig]);
|
|
31702
|
+
for (const name of Object.keys(projectConfig.mcpServers ?? {})) {
|
|
31703
|
+
projectServers.push({ name, source: "project", path: projectPath });
|
|
31704
|
+
}
|
|
31705
|
+
if (Array.isArray(projectConfig.enabledMcpServers)) {
|
|
31706
|
+
issues.push({
|
|
31707
|
+
severity: projectConfig.enabledMcpServers.length === 0 ? "warn" : "info",
|
|
31708
|
+
code: "enabled-mcp-servers-present",
|
|
31709
|
+
message: `Project ${projectPath} contains enabledMcpServers=${JSON.stringify(projectConfig.enabledMcpServers)}. This key is not the same as enabledMcpjsonServers and has caused confusing /mcp debugging reports.`,
|
|
31710
|
+
fix: "If MCP tools are hidden, back up ~/.claude.json, remove only this key, restart Claude Code, and compare /mcp + ToolSearch."
|
|
31711
|
+
});
|
|
31712
|
+
}
|
|
31713
|
+
}
|
|
31714
|
+
const mcpJsonServers = [];
|
|
31715
|
+
for (const mcpJsonPath of findAncestorMcpJsons2(cwd2, homeDir)) {
|
|
31716
|
+
const mcpJson = readJson(mcpJsonPath);
|
|
31717
|
+
for (const name of Object.keys(mcpJson?.mcpServers ?? {})) {
|
|
31718
|
+
mcpJsonServers.push({ name, source: "mcp.json", path: mcpJsonPath });
|
|
31719
|
+
}
|
|
31720
|
+
}
|
|
31721
|
+
const permissionPrefixes = extractPermissionPrefixes(settings);
|
|
31722
|
+
const permissionPrefixSet = new Set(permissionPrefixes);
|
|
31723
|
+
const allConfiguredServerNames = [...globalServers, ...projectServers.map((s) => s.name), ...mcpJsonServers.map((s) => s.name)];
|
|
31724
|
+
const configuredServers = [...new Set(allConfiguredServerNames)].sort();
|
|
31725
|
+
const nonExeServers = configuredServers.filter((s) => s !== "exe-os" && s !== "exe-mem");
|
|
31726
|
+
const nonExeWithoutPermissions = nonExeServers.filter((s) => !serverAllowedByPermissions(s, permissionPrefixSet));
|
|
31727
|
+
if (nonExeWithoutPermissions.length > 0 && permissionPrefixes.some((p) => p === "exe-os" || p === "exe-mem")) {
|
|
31728
|
+
issues.push({
|
|
31729
|
+
severity: "warn",
|
|
31730
|
+
code: "non-exe-mcp-not-permission-allowlisted",
|
|
31731
|
+
message: `Interactive Claude Code may only surface/auto-run permission-allowed MCP tools. exe-os is allowlisted, but these configured servers are not: ${nonExeWithoutPermissions.join(", ")}.`,
|
|
31732
|
+
fix: "In Claude Code, run /permissions and allow the needed MCP server tools (for example mcp__figma__*), then restart. As a diagnostic only, test ENABLE_TOOL_SEARCH=false claude to compare tool injection."
|
|
31733
|
+
});
|
|
31734
|
+
}
|
|
31735
|
+
const duplicateNames = allConfiguredServerNames.filter((name, index, arr) => arr.indexOf(name) !== index);
|
|
31736
|
+
if (duplicateNames.length > 0) {
|
|
31737
|
+
issues.push({
|
|
31738
|
+
severity: "warn",
|
|
31739
|
+
code: "duplicate-mcp-server-names",
|
|
31740
|
+
message: `Duplicate MCP server names exist across global/project/.mcp.json scopes: ${[...new Set(duplicateNames)].join(", ")}. Claude Code can show Connected while dropping tools when scopes collide.`,
|
|
31741
|
+
fix: "Use one source of truth per MCP server name; remove or rename duplicates."
|
|
31742
|
+
});
|
|
31743
|
+
}
|
|
31744
|
+
for (const server of mcpJsonServers) {
|
|
31745
|
+
for (const [projectPath, projectConfig] of applicableProjects) {
|
|
31746
|
+
if (!projectConfig.mcpServers?.[server.name]) continue;
|
|
31747
|
+
const enabled = new Set(projectConfig.enabledMcpjsonServers ?? []);
|
|
31748
|
+
if (!enabled.has(server.name)) {
|
|
31749
|
+
issues.push({
|
|
31750
|
+
severity: "error",
|
|
31751
|
+
code: "disabled-mcp-json-shadows-project-server",
|
|
31752
|
+
message: `${server.name} appears in ${server.path} and project ${projectPath}, but is not enabled in enabledMcpjsonServers. This can shadow the project server and yield Connected/0 tools.`,
|
|
31753
|
+
fix: "Remove/rename the duplicate .mcp.json entry or enable that .mcp.json server explicitly."
|
|
31754
|
+
});
|
|
31755
|
+
}
|
|
31756
|
+
}
|
|
31757
|
+
}
|
|
31758
|
+
if (env.ENABLE_TOOL_SEARCH && env.ENABLE_TOOL_SEARCH !== "auto") {
|
|
31759
|
+
issues.push({
|
|
31760
|
+
severity: "info",
|
|
31761
|
+
code: "enable-tool-search-env-set",
|
|
31762
|
+
message: `ENABLE_TOOL_SEARCH is set to ${env.ENABLE_TOOL_SEARCH}. This changes Claude Code's deferred tool injection path.`,
|
|
31763
|
+
fix: "For debugging, compare interactive launches with ENABLE_TOOL_SEARCH=false, ENABLE_TOOL_SEARCH=auto, and unset."
|
|
31764
|
+
});
|
|
31765
|
+
}
|
|
31766
|
+
if (configuredServers.length > 8) {
|
|
31767
|
+
issues.push({
|
|
31768
|
+
severity: "info",
|
|
31769
|
+
code: "large-mcp-surface",
|
|
31770
|
+
message: `${configuredServers.length} MCP servers are configured for this project. If pipe mode sees tools but interactive mode does not, reduce scope temporarily or enable only needed servers while debugging Claude Code tool injection.`,
|
|
31771
|
+
fix: "Keep exe-os global, move project/design tools into the active project only, and use /permissions for the servers needed in that session."
|
|
31772
|
+
});
|
|
31773
|
+
}
|
|
31774
|
+
return {
|
|
31775
|
+
cwd: path48.resolve(cwd2),
|
|
31776
|
+
globalServers,
|
|
31777
|
+
projectServers: projectServers.sort((a, b) => a.name.localeCompare(b.name)),
|
|
31778
|
+
mcpJsonServers: mcpJsonServers.sort((a, b) => a.name.localeCompare(b.name)),
|
|
31779
|
+
permissionPrefixes,
|
|
31780
|
+
issues
|
|
31781
|
+
};
|
|
31782
|
+
}
|
|
31783
|
+
function formatMcpDiagnosticReport(report) {
|
|
31784
|
+
const lines = [];
|
|
31785
|
+
lines.push("Claude MCP Diagnostic");
|
|
31786
|
+
lines.push(`cwd: ${report.cwd}`);
|
|
31787
|
+
lines.push("");
|
|
31788
|
+
lines.push(`global servers: ${report.globalServers.length ? report.globalServers.join(", ") : "none"}`);
|
|
31789
|
+
lines.push(`project servers: ${report.projectServers.length ? report.projectServers.map((s) => `${s.name} (${s.path})`).join(", ") : "none"}`);
|
|
31790
|
+
lines.push(`.mcp.json servers: ${report.mcpJsonServers.length ? report.mcpJsonServers.map((s) => `${s.name} (${s.path})`).join(", ") : "none"}`);
|
|
31791
|
+
lines.push(`permission MCP prefixes: ${report.permissionPrefixes.length ? report.permissionPrefixes.join(", ") : "none"}`);
|
|
31792
|
+
lines.push("");
|
|
31793
|
+
if (report.issues.length === 0) {
|
|
31794
|
+
lines.push("\u2713 No obvious MCP config hazards detected.");
|
|
31795
|
+
return lines.join("\n");
|
|
31796
|
+
}
|
|
31797
|
+
lines.push("Issues / clues:");
|
|
31798
|
+
for (const issue of report.issues) {
|
|
31799
|
+
const icon = issue.severity === "error" ? "\u2717" : issue.severity === "warn" ? "!" : "i";
|
|
31800
|
+
lines.push(`${icon} [${issue.code}] ${issue.message}`);
|
|
31801
|
+
if (issue.fix) lines.push(` Fix/test: ${issue.fix}`);
|
|
31802
|
+
}
|
|
31803
|
+
return lines.join("\n");
|
|
31804
|
+
}
|
|
31805
|
+
var init_mcp_diagnostics = __esm({
|
|
31806
|
+
"src/adapters/claude/mcp-diagnostics.ts"() {
|
|
31807
|
+
"use strict";
|
|
31808
|
+
}
|
|
31809
|
+
});
|
|
31810
|
+
|
|
31811
|
+
// src/bin/cli.ts
|
|
31812
|
+
import { existsSync as existsSync35, readFileSync as readFileSync30, writeFileSync as writeFileSync21, readdirSync as readdirSync10, rmSync } from "fs";
|
|
31813
|
+
import path49 from "path";
|
|
31814
|
+
import os22 from "os";
|
|
31587
31815
|
var args = process.argv.slice(2);
|
|
31588
31816
|
if (args.includes("--version") || args.includes("-v")) {
|
|
31589
31817
|
try {
|
|
31590
|
-
const pkgPath =
|
|
31591
|
-
const pkg = JSON.parse(
|
|
31818
|
+
const pkgPath = path49.join(path49.dirname(new URL(import.meta.url).pathname), "..", "..", "package.json");
|
|
31819
|
+
const pkg = JSON.parse(readFileSync30(pkgPath, "utf8"));
|
|
31592
31820
|
console.log(pkg.version);
|
|
31593
31821
|
} catch {
|
|
31594
31822
|
console.log("unknown");
|
|
@@ -31622,6 +31850,17 @@ if (args.includes("--global")) {
|
|
|
31622
31850
|
case "check":
|
|
31623
31851
|
await runClaudeCheck();
|
|
31624
31852
|
break;
|
|
31853
|
+
case "mcp-doctor":
|
|
31854
|
+
await runClaudeMcpDoctor();
|
|
31855
|
+
break;
|
|
31856
|
+
case "mcp":
|
|
31857
|
+
if (args[2] === "doctor") {
|
|
31858
|
+
await runClaudeMcpDoctor();
|
|
31859
|
+
} else {
|
|
31860
|
+
console.error("Usage: exe-os claude mcp-doctor");
|
|
31861
|
+
process.exit(1);
|
|
31862
|
+
}
|
|
31863
|
+
break;
|
|
31625
31864
|
case "uninstall":
|
|
31626
31865
|
await runClaudeUninstall(args.slice(2));
|
|
31627
31866
|
break;
|
|
@@ -31755,11 +31994,11 @@ ID: ${result.id}`);
|
|
|
31755
31994
|
});
|
|
31756
31995
|
await init_App2().then(() => App_exports);
|
|
31757
31996
|
} else {
|
|
31758
|
-
const claudeDir =
|
|
31759
|
-
const settingsPath =
|
|
31760
|
-
const hasClaudeCode =
|
|
31997
|
+
const claudeDir = path49.join(os22.homedir(), ".claude");
|
|
31998
|
+
const settingsPath = path49.join(claudeDir, "settings.json");
|
|
31999
|
+
const hasClaudeCode = existsSync35(settingsPath) && (() => {
|
|
31761
32000
|
try {
|
|
31762
|
-
const raw =
|
|
32001
|
+
const raw = readFileSync30(settingsPath, "utf8");
|
|
31763
32002
|
return raw.includes("exe-os") || raw.includes("exe-mem");
|
|
31764
32003
|
} catch {
|
|
31765
32004
|
return false;
|
|
@@ -31769,9 +32008,9 @@ ID: ${result.id}`);
|
|
|
31769
32008
|
const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
31770
32009
|
let cooName = DEFAULT_COORDINATOR_TEMPLATE_NAME2;
|
|
31771
32010
|
try {
|
|
31772
|
-
const rosterPath =
|
|
31773
|
-
if (
|
|
31774
|
-
const roster = JSON.parse(
|
|
32011
|
+
const rosterPath = path49.join(os22.homedir(), ".exe-os", "exe-employees.json");
|
|
32012
|
+
if (existsSync35(rosterPath)) {
|
|
32013
|
+
const roster = JSON.parse(readFileSync30(rosterPath, "utf8"));
|
|
31775
32014
|
const coo = roster.find((e) => e.role === "COO");
|
|
31776
32015
|
if (coo) cooName = coo.name;
|
|
31777
32016
|
}
|
|
@@ -31789,6 +32028,7 @@ cd into a project folder and run \x1B[1m${cooName}1\x1B[0m to boot your COO.
|
|
|
31789
32028
|
exe-os setup Re-run setup wizard
|
|
31790
32029
|
exe-os cloud sync Sync all data with Exe Cloud
|
|
31791
32030
|
exe-os claude check Verify Claude Code integration
|
|
32031
|
+
exe-os claude mcp-doctor Diagnose Claude MCP tool visibility
|
|
31792
32032
|
exe-os tui Launch TUI dashboard (Mode 2)
|
|
31793
32033
|
exe-os --help Show all commands
|
|
31794
32034
|
`);
|
|
@@ -31836,14 +32076,14 @@ async function runCodexInstall() {
|
|
|
31836
32076
|
}
|
|
31837
32077
|
async function runClaudeCheck() {
|
|
31838
32078
|
const { detectMcpNameCollisions: detectMcpNameCollisions2 } = await Promise.resolve().then(() => (init_installer(), installer_exports));
|
|
31839
|
-
const claudeDir =
|
|
31840
|
-
const settingsPath =
|
|
31841
|
-
const claudeJsonPath =
|
|
32079
|
+
const claudeDir = path49.join(os22.homedir(), ".claude");
|
|
32080
|
+
const settingsPath = path49.join(claudeDir, "settings.json");
|
|
32081
|
+
const claudeJsonPath = path49.join(os22.homedir(), ".claude.json");
|
|
31842
32082
|
let ok = true;
|
|
31843
|
-
if (
|
|
32083
|
+
if (existsSync35(settingsPath)) {
|
|
31844
32084
|
let settings;
|
|
31845
32085
|
try {
|
|
31846
|
-
settings = JSON.parse(
|
|
32086
|
+
settings = JSON.parse(readFileSync30(settingsPath, "utf8"));
|
|
31847
32087
|
} catch {
|
|
31848
32088
|
console.log("\x1B[31m\u2717\x1B[0m settings.json is malformed (invalid JSON)");
|
|
31849
32089
|
ok = false;
|
|
@@ -31869,10 +32109,10 @@ async function runClaudeCheck() {
|
|
|
31869
32109
|
console.log("\x1B[31m\u2717\x1B[0m settings.json not found");
|
|
31870
32110
|
ok = false;
|
|
31871
32111
|
}
|
|
31872
|
-
if (
|
|
32112
|
+
if (existsSync35(claudeJsonPath)) {
|
|
31873
32113
|
let claudeJson;
|
|
31874
32114
|
try {
|
|
31875
|
-
claudeJson = JSON.parse(
|
|
32115
|
+
claudeJson = JSON.parse(readFileSync30(claudeJsonPath, "utf8"));
|
|
31876
32116
|
} catch {
|
|
31877
32117
|
console.log("\x1B[31m\u2717\x1B[0m claude.json is malformed (invalid JSON)");
|
|
31878
32118
|
ok = false;
|
|
@@ -31891,7 +32131,7 @@ async function runClaudeCheck() {
|
|
|
31891
32131
|
console.log("\x1B[31m\u2717\x1B[0m claude.json not found");
|
|
31892
32132
|
ok = false;
|
|
31893
32133
|
}
|
|
31894
|
-
const collisions = detectMcpNameCollisions2(
|
|
32134
|
+
const collisions = detectMcpNameCollisions2(os22.homedir(), process.cwd());
|
|
31895
32135
|
const disabledCollisions = collisions.filter((c) => c.disabledInMcpJson);
|
|
31896
32136
|
if (disabledCollisions.length > 0) {
|
|
31897
32137
|
console.log("\x1B[31m\u2717\x1B[0m MCP name collision: disabled .mcp.json entries shadow project MCP servers");
|
|
@@ -31905,8 +32145,8 @@ async function runClaudeCheck() {
|
|
|
31905
32145
|
} else {
|
|
31906
32146
|
console.log("\x1B[32m\u2713\x1B[0m No .mcp.json/project MCP name collisions detected");
|
|
31907
32147
|
}
|
|
31908
|
-
const skillsDir =
|
|
31909
|
-
if (
|
|
32148
|
+
const skillsDir = path49.join(claudeDir, "skills");
|
|
32149
|
+
if (existsSync35(skillsDir)) {
|
|
31910
32150
|
console.log("\x1B[32m\u2713\x1B[0m Slash skills directory exists");
|
|
31911
32151
|
} else {
|
|
31912
32152
|
console.log("\x1B[31m\u2717\x1B[0m Slash skills directory missing");
|
|
@@ -31919,20 +32159,27 @@ async function runClaudeCheck() {
|
|
|
31919
32159
|
console.log("\nAll checks passed.");
|
|
31920
32160
|
}
|
|
31921
32161
|
}
|
|
32162
|
+
async function runClaudeMcpDoctor() {
|
|
32163
|
+
const { diagnoseClaudeMcpConfig: diagnoseClaudeMcpConfig2, formatMcpDiagnosticReport: formatMcpDiagnosticReport2 } = await Promise.resolve().then(() => (init_mcp_diagnostics(), mcp_diagnostics_exports));
|
|
32164
|
+
const report = diagnoseClaudeMcpConfig2(os22.homedir(), process.cwd(), process.env);
|
|
32165
|
+
console.log(formatMcpDiagnosticReport2(report));
|
|
32166
|
+
const hasError = report.issues.some((issue) => issue.severity === "error");
|
|
32167
|
+
process.exit(hasError ? 1 : 0);
|
|
32168
|
+
}
|
|
31922
32169
|
async function runClaudeUninstall(flags = []) {
|
|
31923
32170
|
const dryRun = flags.includes("--dry-run");
|
|
31924
32171
|
const purge = flags.includes("--purge");
|
|
31925
|
-
const homeDir =
|
|
31926
|
-
const claudeDir =
|
|
31927
|
-
const settingsPath =
|
|
31928
|
-
const claudeJsonPath =
|
|
31929
|
-
const exeOsDir =
|
|
32172
|
+
const homeDir = os22.homedir();
|
|
32173
|
+
const claudeDir = path49.join(homeDir, ".claude");
|
|
32174
|
+
const settingsPath = path49.join(claudeDir, "settings.json");
|
|
32175
|
+
const claudeJsonPath = path49.join(homeDir, ".claude.json");
|
|
32176
|
+
const exeOsDir = path49.join(homeDir, ".exe-os");
|
|
31930
32177
|
let removed = 0;
|
|
31931
32178
|
const log = (msg) => console.log(dryRun ? `[dry-run] ${msg}` : msg);
|
|
31932
32179
|
let settings = {};
|
|
31933
|
-
if (
|
|
32180
|
+
if (existsSync35(settingsPath)) {
|
|
31934
32181
|
try {
|
|
31935
|
-
settings = JSON.parse(
|
|
32182
|
+
settings = JSON.parse(readFileSync30(settingsPath, "utf8"));
|
|
31936
32183
|
} catch {
|
|
31937
32184
|
console.error("Your ~/.claude/settings.json appears malformed.");
|
|
31938
32185
|
if (purge) {
|
|
@@ -31977,8 +32224,8 @@ async function runClaudeUninstall(flags = []) {
|
|
|
31977
32224
|
removed++;
|
|
31978
32225
|
}
|
|
31979
32226
|
}
|
|
31980
|
-
if (
|
|
31981
|
-
const raw =
|
|
32227
|
+
if (existsSync35(claudeJsonPath)) {
|
|
32228
|
+
const raw = readFileSync30(claudeJsonPath, "utf8");
|
|
31982
32229
|
if (raw.length > 1e6) {
|
|
31983
32230
|
console.error("claude.json exceeds 1 MB \u2014 skipping parse.");
|
|
31984
32231
|
} else {
|
|
@@ -32007,14 +32254,14 @@ async function runClaudeUninstall(flags = []) {
|
|
|
32007
32254
|
}
|
|
32008
32255
|
}
|
|
32009
32256
|
}
|
|
32010
|
-
const skillsDir =
|
|
32011
|
-
if (
|
|
32257
|
+
const skillsDir = path49.join(claudeDir, "skills");
|
|
32258
|
+
if (existsSync35(skillsDir)) {
|
|
32012
32259
|
let skillCount = 0;
|
|
32013
32260
|
try {
|
|
32014
32261
|
const entries = readdirSync10(skillsDir);
|
|
32015
32262
|
for (const entry of entries) {
|
|
32016
32263
|
if (entry.startsWith("exe")) {
|
|
32017
|
-
const fullPath =
|
|
32264
|
+
const fullPath = path49.join(skillsDir, entry);
|
|
32018
32265
|
if (!dryRun) rmSync(fullPath, { recursive: true, force: true });
|
|
32019
32266
|
skillCount++;
|
|
32020
32267
|
}
|
|
@@ -32026,9 +32273,9 @@ async function runClaudeUninstall(flags = []) {
|
|
|
32026
32273
|
removed++;
|
|
32027
32274
|
}
|
|
32028
32275
|
}
|
|
32029
|
-
const claudeMdPath =
|
|
32030
|
-
if (
|
|
32031
|
-
const content =
|
|
32276
|
+
const claudeMdPath = path49.join(claudeDir, "CLAUDE.md");
|
|
32277
|
+
if (existsSync35(claudeMdPath)) {
|
|
32278
|
+
const content = readFileSync30(claudeMdPath, "utf8");
|
|
32032
32279
|
const startMarker = "<!-- exe-os:orchestration-start -->";
|
|
32033
32280
|
const endMarker = "<!-- exe-os:orchestration-end -->";
|
|
32034
32281
|
const startIdx = content.indexOf(startMarker);
|
|
@@ -32040,16 +32287,16 @@ async function runClaudeUninstall(flags = []) {
|
|
|
32040
32287
|
removed++;
|
|
32041
32288
|
}
|
|
32042
32289
|
}
|
|
32043
|
-
const agentsDir =
|
|
32044
|
-
if (
|
|
32290
|
+
const agentsDir = path49.join(claudeDir, "agents");
|
|
32291
|
+
if (existsSync35(agentsDir)) {
|
|
32045
32292
|
let agentCount = 0;
|
|
32046
32293
|
try {
|
|
32047
32294
|
const entries = readdirSync10(agentsDir).filter((f) => f.endsWith(".md"));
|
|
32048
32295
|
let knownNames = /* @__PURE__ */ new Set();
|
|
32049
|
-
const rosterPath =
|
|
32050
|
-
if (
|
|
32296
|
+
const rosterPath = path49.join(exeOsDir, "exe-employees.json");
|
|
32297
|
+
if (existsSync35(rosterPath)) {
|
|
32051
32298
|
try {
|
|
32052
|
-
const roster = JSON.parse(
|
|
32299
|
+
const roster = JSON.parse(readFileSync30(rosterPath, "utf8"));
|
|
32053
32300
|
knownNames = new Set(roster.map((e) => e.name));
|
|
32054
32301
|
} catch {
|
|
32055
32302
|
}
|
|
@@ -32057,7 +32304,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
32057
32304
|
for (const entry of entries) {
|
|
32058
32305
|
const name = entry.replace(/\.md$/, "");
|
|
32059
32306
|
if (knownNames.has(name)) {
|
|
32060
|
-
if (!dryRun) rmSync(
|
|
32307
|
+
if (!dryRun) rmSync(path49.join(agentsDir, entry), { force: true });
|
|
32061
32308
|
agentCount++;
|
|
32062
32309
|
}
|
|
32063
32310
|
}
|
|
@@ -32068,16 +32315,16 @@ async function runClaudeUninstall(flags = []) {
|
|
|
32068
32315
|
removed++;
|
|
32069
32316
|
}
|
|
32070
32317
|
}
|
|
32071
|
-
const projectsDir =
|
|
32072
|
-
if (
|
|
32318
|
+
const projectsDir = path49.join(claudeDir, "projects");
|
|
32319
|
+
if (existsSync35(projectsDir)) {
|
|
32073
32320
|
let projectCount = 0;
|
|
32074
32321
|
try {
|
|
32075
32322
|
const projects = readdirSync10(projectsDir);
|
|
32076
32323
|
for (const proj of projects) {
|
|
32077
|
-
const projSettings =
|
|
32078
|
-
if (!
|
|
32324
|
+
const projSettings = path49.join(projectsDir, proj, "settings.json");
|
|
32325
|
+
if (!existsSync35(projSettings)) continue;
|
|
32079
32326
|
try {
|
|
32080
|
-
const pSettings = JSON.parse(
|
|
32327
|
+
const pSettings = JSON.parse(readFileSync30(projSettings, "utf8"));
|
|
32081
32328
|
let changed = false;
|
|
32082
32329
|
if (Array.isArray(pSettings.permissions?.allow)) {
|
|
32083
32330
|
const before = pSettings.permissions.allow.length;
|
|
@@ -32111,18 +32358,18 @@ async function runClaudeUninstall(flags = []) {
|
|
|
32111
32358
|
};
|
|
32112
32359
|
const exeBinPath = findExeBin3();
|
|
32113
32360
|
if (!exeBinPath) throw new Error("exe-os not found in PATH");
|
|
32114
|
-
const binDir =
|
|
32361
|
+
const binDir = path49.dirname(exeBinPath);
|
|
32115
32362
|
let symlinkCount = 0;
|
|
32116
|
-
const rosterPath =
|
|
32117
|
-
if (
|
|
32118
|
-
const roster = JSON.parse(
|
|
32363
|
+
const rosterPath = path49.join(exeOsDir, "exe-employees.json");
|
|
32364
|
+
if (existsSync35(rosterPath)) {
|
|
32365
|
+
const roster = JSON.parse(readFileSync30(rosterPath, "utf8"));
|
|
32119
32366
|
const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
32120
32367
|
const coordinatorName = roster.find((e) => e.role?.toLowerCase() === "coo")?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME2;
|
|
32121
32368
|
for (const emp of roster) {
|
|
32122
32369
|
if (emp.name === coordinatorName) continue;
|
|
32123
32370
|
for (const suffix of ["", "-opencode"]) {
|
|
32124
|
-
const linkPath =
|
|
32125
|
-
if (
|
|
32371
|
+
const linkPath = path49.join(binDir, `${emp.name}${suffix}`);
|
|
32372
|
+
if (existsSync35(linkPath)) {
|
|
32126
32373
|
if (!dryRun) rmSync(linkPath, { force: true });
|
|
32127
32374
|
symlinkCount++;
|
|
32128
32375
|
}
|
|
@@ -32135,7 +32382,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
32135
32382
|
}
|
|
32136
32383
|
} catch {
|
|
32137
32384
|
}
|
|
32138
|
-
if (purge &&
|
|
32385
|
+
if (purge && existsSync35(exeOsDir)) {
|
|
32139
32386
|
if (!dryRun) {
|
|
32140
32387
|
process.stdout.write("\x1B[33m\u26A0 This will delete all memories, identities, and agent data.\x1B[0m\n");
|
|
32141
32388
|
process.stdout.write(" Removing ~/.exe-os...\n");
|
|
@@ -32160,7 +32407,7 @@ async function checkForUpdateOnBoot() {
|
|
|
32160
32407
|
const config = await loadConfig2();
|
|
32161
32408
|
if (!config.autoUpdate.checkOnBoot) return;
|
|
32162
32409
|
const { checkForUpdate: checkForUpdate2 } = await Promise.resolve().then(() => (init_update(), update_exports));
|
|
32163
|
-
const packageRoot =
|
|
32410
|
+
const packageRoot = path49.resolve(
|
|
32164
32411
|
new URL("../..", import.meta.url).pathname
|
|
32165
32412
|
);
|
|
32166
32413
|
const result = checkForUpdate2(packageRoot);
|
|
@@ -32221,7 +32468,7 @@ async function runActivate(key) {
|
|
|
32221
32468
|
const idTemplate = getIdentityTemplate(identityKey);
|
|
32222
32469
|
if (idTemplate) {
|
|
32223
32470
|
const idPath = identityPath2(name);
|
|
32224
|
-
const dir =
|
|
32471
|
+
const dir = path49.dirname(idPath);
|
|
32225
32472
|
if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
|
|
32226
32473
|
fs8.writeFileSync(idPath, idTemplate.replace(/^agent_id: \w+/m, `agent_id: ${name}`), "utf-8");
|
|
32227
32474
|
}
|
|
@@ -1272,8 +1272,8 @@ __export(installer_exports, {
|
|
|
1272
1272
|
setupTmux: () => setupTmux
|
|
1273
1273
|
});
|
|
1274
1274
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
|
|
1275
|
-
import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7, copyFileSync, mkdirSync as mkdirSync6 } from "fs";
|
|
1276
|
-
import { createHash as createHash2 } from "crypto";
|
|
1275
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7, copyFileSync, mkdirSync as mkdirSync6, chmodSync as chmodSync3 } from "fs";
|
|
1276
|
+
import { createHash as createHash2, randomBytes } from "crypto";
|
|
1277
1277
|
import path11 from "path";
|
|
1278
1278
|
import os7 from "os";
|
|
1279
1279
|
import { execSync as execSync2 } from "child_process";
|
|
@@ -1402,6 +1402,55 @@ function detectMcpNameCollisions(homeDir = os7.homedir(), cwd = process.cwd()) {
|
|
|
1402
1402
|
}
|
|
1403
1403
|
return collisions;
|
|
1404
1404
|
}
|
|
1405
|
+
function readOrCreateDaemonToken(homeDir) {
|
|
1406
|
+
const exeDir = path11.join(homeDir, ".exe-os");
|
|
1407
|
+
const tokenPath = path11.join(exeDir, "exed.token");
|
|
1408
|
+
try {
|
|
1409
|
+
if (existsSync11(tokenPath)) {
|
|
1410
|
+
const token2 = readFileSync9(tokenPath, "utf-8").trim();
|
|
1411
|
+
if (token2) return token2;
|
|
1412
|
+
}
|
|
1413
|
+
} catch {
|
|
1414
|
+
}
|
|
1415
|
+
const token = randomBytes(32).toString("hex");
|
|
1416
|
+
mkdirSync6(exeDir, { recursive: true });
|
|
1417
|
+
writeFileSync7(tokenPath, `${token}
|
|
1418
|
+
`, "utf-8");
|
|
1419
|
+
try {
|
|
1420
|
+
chmodSync3(tokenPath, 384);
|
|
1421
|
+
} catch {
|
|
1422
|
+
}
|
|
1423
|
+
return token;
|
|
1424
|
+
}
|
|
1425
|
+
function buildHttpMcpEntry(homeDir) {
|
|
1426
|
+
const port = process.env.EXE_MCP_PORT || "48739";
|
|
1427
|
+
const token = readOrCreateDaemonToken(homeDir);
|
|
1428
|
+
return {
|
|
1429
|
+
type: "http",
|
|
1430
|
+
url: `http://127.0.0.1:${port}/mcp`,
|
|
1431
|
+
headers: {
|
|
1432
|
+
Authorization: `Bearer ${token}`,
|
|
1433
|
+
"X-Agent-Id": "${AGENT_ID:-exe}",
|
|
1434
|
+
"X-Agent-Role": "${AGENT_ROLE:-COO}"
|
|
1435
|
+
}
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
function buildStdioMcpEntry(packageRoot) {
|
|
1439
|
+
return {
|
|
1440
|
+
type: "stdio",
|
|
1441
|
+
command: "node",
|
|
1442
|
+
args: [path11.join(packageRoot, "dist", "mcp", "server.js")],
|
|
1443
|
+
env: {}
|
|
1444
|
+
};
|
|
1445
|
+
}
|
|
1446
|
+
function mcpTransportMode() {
|
|
1447
|
+
const value = process.env.EXE_OS_MCP_TRANSPORT?.trim().toLowerCase();
|
|
1448
|
+
if (value === "stdio") return "stdio";
|
|
1449
|
+
if (value === "http") return "http";
|
|
1450
|
+
const totalGB = os7.totalmem() / (1024 * 1024 * 1024);
|
|
1451
|
+
if (totalGB <= 8) return "stdio";
|
|
1452
|
+
return "http";
|
|
1453
|
+
}
|
|
1405
1454
|
async function registerMcpServer(packageRoot, homeDir = os7.homedir()) {
|
|
1406
1455
|
const claudeJsonPath = path11.join(homeDir, ".claude.json");
|
|
1407
1456
|
let claudeJson = {};
|
|
@@ -1415,12 +1464,7 @@ async function registerMcpServer(packageRoot, homeDir = os7.homedir()) {
|
|
|
1415
1464
|
if (!claudeJson.mcpServers) {
|
|
1416
1465
|
claudeJson.mcpServers = {};
|
|
1417
1466
|
}
|
|
1418
|
-
const newEntry =
|
|
1419
|
-
type: "stdio",
|
|
1420
|
-
command: "node",
|
|
1421
|
-
args: [path11.join(packageRoot, "dist", "mcp", "server.js")],
|
|
1422
|
-
env: {}
|
|
1423
|
-
};
|
|
1467
|
+
const newEntry = mcpTransportMode() === "stdio" ? buildStdioMcpEntry(packageRoot) : buildHttpMcpEntry(homeDir);
|
|
1424
1468
|
if (claudeJson.mcpServers[MCP_LEGACY_KEY]) {
|
|
1425
1469
|
delete claudeJson.mcpServers[MCP_LEGACY_KEY];
|
|
1426
1470
|
process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
|
|
@@ -3608,8 +3608,8 @@ var init_preferences = __esm({
|
|
|
3608
3608
|
|
|
3609
3609
|
// src/adapters/claude/installer.ts
|
|
3610
3610
|
import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir4, readdir } from "fs/promises";
|
|
3611
|
-
import { existsSync as existsSync11, readFileSync as readFileSync7, writeFileSync as writeFileSync6, copyFileSync, mkdirSync as mkdirSync6 } from "fs";
|
|
3612
|
-
import { createHash as createHash2 } from "crypto";
|
|
3611
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7, writeFileSync as writeFileSync6, copyFileSync, mkdirSync as mkdirSync6, chmodSync as chmodSync2 } from "fs";
|
|
3612
|
+
import { createHash as createHash2, randomBytes } from "crypto";
|
|
3613
3613
|
import path12 from "path";
|
|
3614
3614
|
import os9 from "os";
|
|
3615
3615
|
import { execSync as execSync5 } from "child_process";
|
|
@@ -3597,8 +3597,8 @@ var init_preferences = __esm({
|
|
|
3597
3597
|
|
|
3598
3598
|
// src/adapters/claude/installer.ts
|
|
3599
3599
|
import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir4, readdir } from "fs/promises";
|
|
3600
|
-
import { existsSync as existsSync11, readFileSync as readFileSync7, writeFileSync as writeFileSync6, copyFileSync, mkdirSync as mkdirSync6 } from "fs";
|
|
3601
|
-
import { createHash as createHash2 } from "crypto";
|
|
3600
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7, writeFileSync as writeFileSync6, copyFileSync, mkdirSync as mkdirSync6, chmodSync as chmodSync2 } from "fs";
|
|
3601
|
+
import { createHash as createHash2, randomBytes } from "crypto";
|
|
3602
3602
|
import path12 from "path";
|
|
3603
3603
|
import os9 from "os";
|
|
3604
3604
|
import { execSync as execSync5 } from "child_process";
|
package/dist/bin/install.js
CHANGED
|
@@ -610,8 +610,8 @@ var init_preferences = __esm({
|
|
|
610
610
|
|
|
611
611
|
// src/adapters/claude/installer.ts
|
|
612
612
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
|
|
613
|
-
import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4, copyFileSync, mkdirSync as mkdirSync3 } from "fs";
|
|
614
|
-
import { createHash } from "crypto";
|
|
613
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4, copyFileSync, mkdirSync as mkdirSync3, chmodSync as chmodSync2 } from "fs";
|
|
614
|
+
import { createHash, randomBytes } from "crypto";
|
|
615
615
|
import path6 from "path";
|
|
616
616
|
import os5 from "os";
|
|
617
617
|
import { execSync as execSync2 } from "child_process";
|
|
@@ -740,6 +740,55 @@ function detectMcpNameCollisions(homeDir = os5.homedir(), cwd = process.cwd()) {
|
|
|
740
740
|
}
|
|
741
741
|
return collisions;
|
|
742
742
|
}
|
|
743
|
+
function readOrCreateDaemonToken(homeDir) {
|
|
744
|
+
const exeDir = path6.join(homeDir, ".exe-os");
|
|
745
|
+
const tokenPath = path6.join(exeDir, "exed.token");
|
|
746
|
+
try {
|
|
747
|
+
if (existsSync7(tokenPath)) {
|
|
748
|
+
const token2 = readFileSync5(tokenPath, "utf-8").trim();
|
|
749
|
+
if (token2) return token2;
|
|
750
|
+
}
|
|
751
|
+
} catch {
|
|
752
|
+
}
|
|
753
|
+
const token = randomBytes(32).toString("hex");
|
|
754
|
+
mkdirSync3(exeDir, { recursive: true });
|
|
755
|
+
writeFileSync4(tokenPath, `${token}
|
|
756
|
+
`, "utf-8");
|
|
757
|
+
try {
|
|
758
|
+
chmodSync2(tokenPath, 384);
|
|
759
|
+
} catch {
|
|
760
|
+
}
|
|
761
|
+
return token;
|
|
762
|
+
}
|
|
763
|
+
function buildHttpMcpEntry(homeDir) {
|
|
764
|
+
const port = process.env.EXE_MCP_PORT || "48739";
|
|
765
|
+
const token = readOrCreateDaemonToken(homeDir);
|
|
766
|
+
return {
|
|
767
|
+
type: "http",
|
|
768
|
+
url: `http://127.0.0.1:${port}/mcp`,
|
|
769
|
+
headers: {
|
|
770
|
+
Authorization: `Bearer ${token}`,
|
|
771
|
+
"X-Agent-Id": "${AGENT_ID:-exe}",
|
|
772
|
+
"X-Agent-Role": "${AGENT_ROLE:-COO}"
|
|
773
|
+
}
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
function buildStdioMcpEntry(packageRoot) {
|
|
777
|
+
return {
|
|
778
|
+
type: "stdio",
|
|
779
|
+
command: "node",
|
|
780
|
+
args: [path6.join(packageRoot, "dist", "mcp", "server.js")],
|
|
781
|
+
env: {}
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
function mcpTransportMode() {
|
|
785
|
+
const value = process.env.EXE_OS_MCP_TRANSPORT?.trim().toLowerCase();
|
|
786
|
+
if (value === "stdio") return "stdio";
|
|
787
|
+
if (value === "http") return "http";
|
|
788
|
+
const totalGB = os5.totalmem() / (1024 * 1024 * 1024);
|
|
789
|
+
if (totalGB <= 8) return "stdio";
|
|
790
|
+
return "http";
|
|
791
|
+
}
|
|
743
792
|
async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
|
|
744
793
|
const claudeJsonPath = path6.join(homeDir, ".claude.json");
|
|
745
794
|
let claudeJson = {};
|
|
@@ -753,12 +802,7 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
|
|
|
753
802
|
if (!claudeJson.mcpServers) {
|
|
754
803
|
claudeJson.mcpServers = {};
|
|
755
804
|
}
|
|
756
|
-
const newEntry =
|
|
757
|
-
type: "stdio",
|
|
758
|
-
command: "node",
|
|
759
|
-
args: [path6.join(packageRoot, "dist", "mcp", "server.js")],
|
|
760
|
-
env: {}
|
|
761
|
-
};
|
|
805
|
+
const newEntry = mcpTransportMode() === "stdio" ? buildStdioMcpEntry(packageRoot) : buildHttpMcpEntry(homeDir);
|
|
762
806
|
if (claudeJson.mcpServers[MCP_LEGACY_KEY]) {
|
|
763
807
|
delete claudeJson.mcpServers[MCP_LEGACY_KEY];
|
|
764
808
|
process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
|
|
@@ -1831,7 +1875,7 @@ import {
|
|
|
1831
1875
|
readFileSync as readFileSync6,
|
|
1832
1876
|
writeFileSync as writeFileSync5,
|
|
1833
1877
|
mkdirSync as mkdirSync4,
|
|
1834
|
-
chmodSync as
|
|
1878
|
+
chmodSync as chmodSync3,
|
|
1835
1879
|
readdirSync,
|
|
1836
1880
|
unlinkSync as unlinkSync2
|
|
1837
1881
|
} from "fs";
|
|
@@ -1851,7 +1895,7 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
1851
1895
|
for (const src of candidates) {
|
|
1852
1896
|
if (existsSync8(src)) {
|
|
1853
1897
|
writeFileSync5(exeStartDst, readFileSync6(src));
|
|
1854
|
-
|
|
1898
|
+
chmodSync3(exeStartDst, 493);
|
|
1855
1899
|
break;
|
|
1856
1900
|
}
|
|
1857
1901
|
}
|
|
@@ -1886,11 +1930,11 @@ exec "${exeStartDst}" "$0" "$@"
|
|
|
1886
1930
|
for (let n = 1; n <= MAX_N; n++) {
|
|
1887
1931
|
const wrapperPath = path7.join(binDir, `${emp.name}${n}`);
|
|
1888
1932
|
writeFileSync5(wrapperPath, wrapperContent);
|
|
1889
|
-
|
|
1933
|
+
chmodSync3(wrapperPath, 493);
|
|
1890
1934
|
created++;
|
|
1891
1935
|
const codexPath = path7.join(binDir, `${emp.name}${n}-codex`);
|
|
1892
1936
|
writeFileSync5(codexPath, wrapperContent);
|
|
1893
|
-
|
|
1937
|
+
chmodSync3(codexPath, 493);
|
|
1894
1938
|
created++;
|
|
1895
1939
|
}
|
|
1896
1940
|
}
|
|
@@ -1912,7 +1956,7 @@ exec "${exeStartDst}" "$0" "$@"
|
|
|
1912
1956
|
exec node "${codexLauncher}" --agent ${emp.name} "$@"
|
|
1913
1957
|
`;
|
|
1914
1958
|
writeFileSync5(wrapperPath, content);
|
|
1915
|
-
|
|
1959
|
+
chmodSync3(wrapperPath, 493);
|
|
1916
1960
|
created++;
|
|
1917
1961
|
}
|
|
1918
1962
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askexenow/exe-os",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.49",
|
|
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",
|