@askexenow/exe-os 0.8.101 → 0.8.102
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cleanup-stale-review-tasks.js +1 -1
- package/dist/bin/cli.js +265 -84
- package/dist/bin/exe-agent-config.js +1 -1
- package/dist/bin/exe-boot.js +1 -1
- package/dist/bin/exe-dispatch.js +1 -1
- package/dist/bin/exe-gateway.js +1 -1
- package/dist/bin/exe-heartbeat.js +1 -1
- package/dist/bin/exe-pending-messages.js +1 -1
- package/dist/bin/exe-pending-reviews.js +1 -1
- package/dist/bin/exe-session-cleanup.js +1 -1
- package/dist/bin/exe-start-codex.js +298 -31
- package/dist/bin/exe-status.js +1 -1
- package/dist/bin/git-sweep.js +1 -1
- package/dist/bin/scan-tasks.js +1 -1
- package/dist/bin/setup.js +6 -9
- package/dist/gateway/index.js +1 -1
- package/dist/hooks/bug-report-worker.js +1 -1
- package/dist/hooks/commit-complete.js +1 -1
- package/dist/hooks/ingest-worker.js +1 -1
- package/dist/hooks/ingest.js +4 -4
- package/dist/hooks/post-compact.js +1 -1
- package/dist/hooks/pre-compact.js +1 -1
- package/dist/hooks/pre-tool-use.js +1 -1
- package/dist/hooks/prompt-submit.js +1 -1
- package/dist/hooks/session-end.js +1 -1
- package/dist/hooks/session-start.js +1 -1
- package/dist/hooks/stop.js +1 -1
- package/dist/hooks/subagent-stop.js +1 -1
- package/dist/hooks/summary-worker.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/agent-config.js +1 -1
- package/dist/lib/exe-daemon.js +1 -1
- package/dist/lib/messaging.js +1 -1
- package/dist/lib/runtime-table.js +1 -1
- package/dist/lib/tasks.js +1 -1
- package/dist/lib/tmux-routing.js +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/tools/create-task.js +1 -1
- package/dist/mcp/tools/list-tasks.js +1 -1
- package/dist/mcp/tools/send-message.js +1 -1
- package/dist/mcp/tools/update-task.js +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/tui/App.js +1 -1
- package/package.json +1 -1
|
@@ -1939,7 +1939,7 @@ var init_runtime_table = __esm({
|
|
|
1939
1939
|
RUNTIME_TABLE = {
|
|
1940
1940
|
codex: {
|
|
1941
1941
|
binary: "codex",
|
|
1942
|
-
launchMode: "
|
|
1942
|
+
launchMode: "interactive",
|
|
1943
1943
|
autoApproveFlag: "--full-auto",
|
|
1944
1944
|
inlineFlag: "--no-alt-screen",
|
|
1945
1945
|
apiKeyEnv: "OPENAI_API_KEY",
|
package/dist/bin/cli.js
CHANGED
|
@@ -6802,9 +6802,9 @@ Unclassified: ${unclassified}
|
|
|
6802
6802
|
}
|
|
6803
6803
|
async function exportBatches(options) {
|
|
6804
6804
|
const fs8 = await import("fs");
|
|
6805
|
-
const
|
|
6805
|
+
const path40 = await import("path");
|
|
6806
6806
|
const client = getClient();
|
|
6807
|
-
const outDir =
|
|
6807
|
+
const outDir = path40.join(process.cwd(), "exe/output/classifications/input");
|
|
6808
6808
|
fs8.mkdirSync(outDir, { recursive: true });
|
|
6809
6809
|
const countResult = await client.execute({
|
|
6810
6810
|
sql: "SELECT COUNT(*) as cnt FROM memories WHERE intent IS NULL AND outcome IS NULL AND domain IS NULL",
|
|
@@ -6828,7 +6828,7 @@ async function exportBatches(options) {
|
|
|
6828
6828
|
const text = String(row.text || "").replace(/\n/g, " ");
|
|
6829
6829
|
return JSON.stringify({ id: row.id, text });
|
|
6830
6830
|
});
|
|
6831
|
-
const batchFile =
|
|
6831
|
+
const batchFile = path40.join(outDir, `batch-${String(batchNum).padStart(4, "0")}.jsonl`);
|
|
6832
6832
|
fs8.writeFileSync(batchFile, lines.join("\n") + "\n");
|
|
6833
6833
|
exported += batch.rows.length;
|
|
6834
6834
|
offset += options.batchSize;
|
|
@@ -6844,7 +6844,7 @@ async function exportBatches(options) {
|
|
|
6844
6844
|
}
|
|
6845
6845
|
async function importClassifications(importDir) {
|
|
6846
6846
|
const fs8 = await import("fs");
|
|
6847
|
-
const
|
|
6847
|
+
const path40 = await import("path");
|
|
6848
6848
|
const client = getClient();
|
|
6849
6849
|
const files = fs8.readdirSync(importDir).filter((f) => f.endsWith(".jsonl")).sort();
|
|
6850
6850
|
process.stderr.write(`[backfill-metadata] Found ${files.length} JSONL files to import from ${importDir}
|
|
@@ -6852,7 +6852,7 @@ async function importClassifications(importDir) {
|
|
|
6852
6852
|
let imported = 0;
|
|
6853
6853
|
let invalid = 0;
|
|
6854
6854
|
for (const file of files) {
|
|
6855
|
-
const lines = fs8.readFileSync(
|
|
6855
|
+
const lines = fs8.readFileSync(path40.join(importDir, file), "utf-8").split("\n").filter(Boolean);
|
|
6856
6856
|
for (const line of lines) {
|
|
6857
6857
|
try {
|
|
6858
6858
|
const rec = JSON.parse(line);
|
|
@@ -7249,7 +7249,7 @@ var init_runtime_table = __esm({
|
|
|
7249
7249
|
RUNTIME_TABLE = {
|
|
7250
7250
|
codex: {
|
|
7251
7251
|
binary: "codex",
|
|
7252
|
-
launchMode: "
|
|
7252
|
+
launchMode: "interactive",
|
|
7253
7253
|
autoApproveFlag: "--full-auto",
|
|
7254
7254
|
inlineFlag: "--no-alt-screen",
|
|
7255
7255
|
apiKeyEnv: "OPENAI_API_KEY",
|
|
@@ -11495,10 +11495,10 @@ async function disposeEmbedder() {
|
|
|
11495
11495
|
async function embedDirect(text) {
|
|
11496
11496
|
const llamaCpp = await import("node-llama-cpp");
|
|
11497
11497
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
11498
|
-
const { existsSync:
|
|
11499
|
-
const
|
|
11500
|
-
const modelPath =
|
|
11501
|
-
if (!
|
|
11498
|
+
const { existsSync: existsSync27 } = await import("fs");
|
|
11499
|
+
const path40 = await import("path");
|
|
11500
|
+
const modelPath = path40.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
11501
|
+
if (!existsSync27(modelPath)) {
|
|
11502
11502
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
11503
11503
|
}
|
|
11504
11504
|
const llama = await llamaCpp.getLlama();
|
|
@@ -12994,16 +12994,13 @@ async function runSetupWizard(opts = {}) {
|
|
|
12994
12994
|
} catch {
|
|
12995
12995
|
}
|
|
12996
12996
|
}
|
|
12997
|
-
const W = 27;
|
|
12998
|
-
const center = (s) => {
|
|
12999
|
-
const pad = W - s.length;
|
|
13000
|
-
return " ".repeat(Math.floor(pad / 2)) + s + " ".repeat(Math.ceil(pad / 2));
|
|
13001
|
-
};
|
|
13002
12997
|
log("");
|
|
13003
|
-
log(
|
|
13004
|
-
log(
|
|
13005
|
-
|
|
13006
|
-
log(
|
|
12998
|
+
log(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588");
|
|
12999
|
+
log(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ");
|
|
13000
|
+
log(" \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588");
|
|
13001
|
+
log(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588");
|
|
13002
|
+
log(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588");
|
|
13003
|
+
if (version) log(`${"".padStart(18)}v${version}`);
|
|
13007
13004
|
log("");
|
|
13008
13005
|
log("=== Next Steps ===");
|
|
13009
13006
|
log("");
|
|
@@ -13168,14 +13165,14 @@ async function runUpdate(cliArgs) {
|
|
|
13168
13165
|
}
|
|
13169
13166
|
console.log(" Hooks re-wired, daemon restarted automatically.");
|
|
13170
13167
|
try {
|
|
13171
|
-
const { existsSync: exists, readFileSync:
|
|
13168
|
+
const { existsSync: exists, readFileSync: readFile7 } = await import("fs");
|
|
13172
13169
|
const p = await import("path");
|
|
13173
13170
|
const { homedir: home } = await import("os");
|
|
13174
13171
|
const exeDir = p.default.join(home(), ".exe-os");
|
|
13175
13172
|
const licKeyPath = p.default.join(exeDir, "license.key");
|
|
13176
13173
|
const configPath = p.default.join(exeDir, "config.json");
|
|
13177
13174
|
if (!exists(licKeyPath) && exists(configPath)) {
|
|
13178
|
-
const cfg = JSON.parse(
|
|
13175
|
+
const cfg = JSON.parse(readFile7(configPath, "utf8"));
|
|
13179
13176
|
const cloud = cfg.cloud;
|
|
13180
13177
|
if (cloud?.apiKey) {
|
|
13181
13178
|
const { mirrorLicenseKey: mirrorLicenseKey2 } = await Promise.resolve().then(() => (init_license(), license_exports));
|
|
@@ -17560,8 +17557,8 @@ var init_ErrorOverview = __esm({
|
|
|
17560
17557
|
"use strict";
|
|
17561
17558
|
init_Box();
|
|
17562
17559
|
init_Text();
|
|
17563
|
-
cleanupPath = (
|
|
17564
|
-
return
|
|
17560
|
+
cleanupPath = (path40) => {
|
|
17561
|
+
return path40?.replace(`file://${cwd()}/`, "");
|
|
17565
17562
|
};
|
|
17566
17563
|
stackUtils = new StackUtils({
|
|
17567
17564
|
cwd: cwd(),
|
|
@@ -19969,11 +19966,11 @@ function Footer() {
|
|
|
19969
19966
|
} catch {
|
|
19970
19967
|
}
|
|
19971
19968
|
try {
|
|
19972
|
-
const { existsSync:
|
|
19969
|
+
const { existsSync: existsSync27 } = await import("fs");
|
|
19973
19970
|
const { join } = await import("path");
|
|
19974
19971
|
const home = process.env.HOME ?? "";
|
|
19975
19972
|
const pidPath = join(home, ".exe-os", "exed.pid");
|
|
19976
|
-
setDaemon(
|
|
19973
|
+
setDaemon(existsSync27(pidPath) ? "running" : "stopped");
|
|
19977
19974
|
} catch {
|
|
19978
19975
|
setDaemon("unknown");
|
|
19979
19976
|
}
|
|
@@ -22737,13 +22734,13 @@ function CommandCenterView({
|
|
|
22737
22734
|
const { createPermissionsFromPreset: createPermissionsFromPreset2, EMPLOYEE_PERMISSIONS: EMPLOYEE_PERMISSIONS2 } = await Promise.resolve().then(() => (init_permissions(), permissions_exports));
|
|
22738
22735
|
const { getPresetByRole: getPresetByRole2 } = await Promise.resolve().then(() => (init_permission_presets(), permission_presets_exports));
|
|
22739
22736
|
const { createDefaultHooks: createDefaultHooks2 } = await Promise.resolve().then(() => (init_hooks(), hooks_exports));
|
|
22740
|
-
const { readFileSync: readFileSync23, existsSync:
|
|
22737
|
+
const { readFileSync: readFileSync23, existsSync: existsSync27 } = await import("fs");
|
|
22741
22738
|
const { join } = await import("path");
|
|
22742
22739
|
const { homedir: homedir8 } = await import("os");
|
|
22743
22740
|
const configPath = join(homedir8(), ".exe-os", "config.json");
|
|
22744
22741
|
let failoverChain = ["anthropic", "opencode", "gemini", "openai"];
|
|
22745
22742
|
let providerConfigs = {};
|
|
22746
|
-
if (
|
|
22743
|
+
if (existsSync27(configPath)) {
|
|
22747
22744
|
try {
|
|
22748
22745
|
const raw = JSON.parse(readFileSync23(configPath, "utf8"));
|
|
22749
22746
|
if (Array.isArray(raw.failoverChain)) failoverChain = raw.failoverChain;
|
|
@@ -22989,7 +22986,7 @@ function CommandCenterView({
|
|
|
22989
22986
|
const { listSessions: listSessions2 } = await Promise.resolve().then(() => (init_session_registry(), session_registry_exports));
|
|
22990
22987
|
const { listTmuxSessions: listTmuxSessions2, inTmux: inTmux2 } = await Promise.resolve().then(() => (init_tmux_status(), tmux_status_exports));
|
|
22991
22988
|
const { loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
22992
|
-
const { existsSync:
|
|
22989
|
+
const { existsSync: existsSync27 } = await import("fs");
|
|
22993
22990
|
const { join } = await import("path");
|
|
22994
22991
|
const client = getClient2();
|
|
22995
22992
|
if (!client) {
|
|
@@ -23060,7 +23057,7 @@ function CommandCenterView({
|
|
|
23060
23057
|
}
|
|
23061
23058
|
const memoryCount = memoryCounts.get(name) ?? 0;
|
|
23062
23059
|
const openTaskCount = openTaskCounts.get(name) ?? 0;
|
|
23063
|
-
const hasGit = projectDir ?
|
|
23060
|
+
const hasGit = projectDir ? existsSync27(join(projectDir, ".git")) : false;
|
|
23064
23061
|
const type = hasGit ? "code" : memoryCount > 0 ? "code" : "automation";
|
|
23065
23062
|
projectList.push({
|
|
23066
23063
|
projectName: name,
|
|
@@ -23085,7 +23082,7 @@ function CommandCenterView({
|
|
|
23085
23082
|
setHealth((h) => ({ ...h, memories: Number(totalResult.rows[0]?.cnt ?? 0) }));
|
|
23086
23083
|
try {
|
|
23087
23084
|
const pidPath = join(process.env.HOME ?? "", ".exe-os", "exed.pid");
|
|
23088
|
-
setHealth((h) => ({ ...h, daemon:
|
|
23085
|
+
setHealth((h) => ({ ...h, daemon: existsSync27(pidPath) ? "running" : "stopped" }));
|
|
23089
23086
|
} catch {
|
|
23090
23087
|
}
|
|
23091
23088
|
const activityResult = await client.execute(
|
|
@@ -25096,11 +25093,11 @@ async function loadGatewayConfig() {
|
|
|
25096
25093
|
state.running = false;
|
|
25097
25094
|
}
|
|
25098
25095
|
try {
|
|
25099
|
-
const { existsSync:
|
|
25096
|
+
const { existsSync: existsSync27, readFileSync: readFileSync23 } = await import("fs");
|
|
25100
25097
|
const { join } = await import("path");
|
|
25101
25098
|
const home = process.env.HOME ?? "";
|
|
25102
25099
|
const configPath = join(home, ".exe-os", "gateway.json");
|
|
25103
|
-
if (
|
|
25100
|
+
if (existsSync27(configPath)) {
|
|
25104
25101
|
const raw = JSON.parse(readFileSync23(configPath, "utf8"));
|
|
25105
25102
|
state.port = raw.port ?? 3100;
|
|
25106
25103
|
state.gatewayUrl = raw.gatewayUrl ?? "";
|
|
@@ -25724,11 +25721,11 @@ function TeamView({ onBack, onViewSessions }) {
|
|
|
25724
25721
|
setMembers(teamData);
|
|
25725
25722
|
setDbError(null);
|
|
25726
25723
|
try {
|
|
25727
|
-
const { existsSync:
|
|
25724
|
+
const { existsSync: existsSync27, readFileSync: readFileSync23 } = await import("fs");
|
|
25728
25725
|
const { join } = await import("path");
|
|
25729
25726
|
const home = process.env.HOME ?? "";
|
|
25730
25727
|
const gatewayConfig = join(home, ".exe-os", "gateway.json");
|
|
25731
|
-
if (
|
|
25728
|
+
if (existsSync27(gatewayConfig)) {
|
|
25732
25729
|
const raw = JSON.parse(readFileSync23(gatewayConfig, "utf8"));
|
|
25733
25730
|
if (raw.agents && raw.agents.length > 0) {
|
|
25734
25731
|
setExternals(raw.agents.map((a) => ({
|
|
@@ -25910,8 +25907,8 @@ __export(wiki_client_exports, {
|
|
|
25910
25907
|
listDocuments: () => listDocuments,
|
|
25911
25908
|
listWorkspaces: () => listWorkspaces
|
|
25912
25909
|
});
|
|
25913
|
-
async function wikiFetch(config,
|
|
25914
|
-
const url = `${config.baseUrl}/api/v1${
|
|
25910
|
+
async function wikiFetch(config, path40, method = "GET", body) {
|
|
25911
|
+
const url = `${config.baseUrl}/api/v1${path40}`;
|
|
25915
25912
|
const headers = {
|
|
25916
25913
|
Authorization: `Bearer ${config.apiKey}`,
|
|
25917
25914
|
"Content-Type": "application/json"
|
|
@@ -25944,7 +25941,7 @@ async function wikiFetch(config, path39, method = "GET", body) {
|
|
|
25944
25941
|
}
|
|
25945
25942
|
}
|
|
25946
25943
|
if (!response.ok) {
|
|
25947
|
-
throw new Error(`Wiki API ${method} ${
|
|
25944
|
+
throw new Error(`Wiki API ${method} ${path40}: ${response.status} ${response.statusText}`);
|
|
25948
25945
|
}
|
|
25949
25946
|
return response.json();
|
|
25950
25947
|
} finally {
|
|
@@ -26554,12 +26551,12 @@ function SettingsView({ onBack }) {
|
|
|
26554
26551
|
}
|
|
26555
26552
|
setProviders(providerList);
|
|
26556
26553
|
try {
|
|
26557
|
-
const { existsSync:
|
|
26554
|
+
const { existsSync: existsSync27 } = await import("fs");
|
|
26558
26555
|
const { join } = await import("path");
|
|
26559
26556
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
26560
26557
|
const cfg = await loadConfig2();
|
|
26561
26558
|
const home = process.env.HOME ?? "";
|
|
26562
|
-
const hasKey =
|
|
26559
|
+
const hasKey = existsSync27(join(home, ".exe-os", "master.key"));
|
|
26563
26560
|
if (cfg.cloud) {
|
|
26564
26561
|
setCloud({
|
|
26565
26562
|
configured: true,
|
|
@@ -26572,7 +26569,7 @@ function SettingsView({ onBack }) {
|
|
|
26572
26569
|
const pidPath = join(home, ".exe-os", "exed.pid");
|
|
26573
26570
|
let daemon = "unknown";
|
|
26574
26571
|
try {
|
|
26575
|
-
daemon =
|
|
26572
|
+
daemon = existsSync27(pidPath) ? "running" : "stopped";
|
|
26576
26573
|
} catch {
|
|
26577
26574
|
}
|
|
26578
26575
|
let version = "unknown";
|
|
@@ -27195,14 +27192,176 @@ Unhandled rejection: ${reason}
|
|
|
27195
27192
|
}
|
|
27196
27193
|
});
|
|
27197
27194
|
|
|
27198
|
-
// src/
|
|
27199
|
-
|
|
27195
|
+
// src/adapters/codex/installer.ts
|
|
27196
|
+
var installer_exports2 = {};
|
|
27197
|
+
__export(installer_exports2, {
|
|
27198
|
+
mergeCodexHooks: () => mergeCodexHooks,
|
|
27199
|
+
runCodexInstaller: () => runCodexInstaller,
|
|
27200
|
+
verifyCodexHooks: () => verifyCodexHooks
|
|
27201
|
+
});
|
|
27202
|
+
import { readFile as readFile6, writeFile as writeFile7, mkdir as mkdir7 } from "fs/promises";
|
|
27203
|
+
import { existsSync as existsSync25 } from "fs";
|
|
27200
27204
|
import path38 from "path";
|
|
27201
27205
|
import os14 from "os";
|
|
27206
|
+
async function mergeCodexHooks(packageRoot, homeDir = os14.homedir()) {
|
|
27207
|
+
const codexDir = path38.join(homeDir, ".codex");
|
|
27208
|
+
const hooksPath = path38.join(codexDir, "hooks.json");
|
|
27209
|
+
await mkdir7(codexDir, { recursive: true });
|
|
27210
|
+
let hooksJson = {};
|
|
27211
|
+
if (existsSync25(hooksPath)) {
|
|
27212
|
+
try {
|
|
27213
|
+
hooksJson = JSON.parse(await readFile6(hooksPath, "utf-8"));
|
|
27214
|
+
} catch {
|
|
27215
|
+
hooksJson = {};
|
|
27216
|
+
}
|
|
27217
|
+
}
|
|
27218
|
+
if (!hooksJson.hooks) {
|
|
27219
|
+
hooksJson.hooks = {};
|
|
27220
|
+
}
|
|
27221
|
+
const hooksToRegister = [
|
|
27222
|
+
{
|
|
27223
|
+
event: "SessionStart",
|
|
27224
|
+
group: {
|
|
27225
|
+
hooks: [
|
|
27226
|
+
{
|
|
27227
|
+
type: "command",
|
|
27228
|
+
command: `node "${path38.join(packageRoot, "dist", "hooks", "session-start.js")}"`,
|
|
27229
|
+
timeout: 10,
|
|
27230
|
+
statusMessage: "exe-os: loading memory brief"
|
|
27231
|
+
}
|
|
27232
|
+
]
|
|
27233
|
+
},
|
|
27234
|
+
marker: "dist/hooks/session-start.js"
|
|
27235
|
+
},
|
|
27236
|
+
{
|
|
27237
|
+
event: "PostToolUse",
|
|
27238
|
+
group: {
|
|
27239
|
+
matcher: "Bash|apply_patch|Edit|Write|Read|Glob|Grep|mcp__.*",
|
|
27240
|
+
hooks: [
|
|
27241
|
+
{
|
|
27242
|
+
type: "command",
|
|
27243
|
+
command: `node "${path38.join(packageRoot, "dist", "hooks", "ingest.js")}"`
|
|
27244
|
+
},
|
|
27245
|
+
{
|
|
27246
|
+
type: "command",
|
|
27247
|
+
command: `node "${path38.join(packageRoot, "dist", "hooks", "error-recall.js")}"`
|
|
27248
|
+
}
|
|
27249
|
+
]
|
|
27250
|
+
},
|
|
27251
|
+
marker: "dist/hooks/ingest.js"
|
|
27252
|
+
},
|
|
27253
|
+
{
|
|
27254
|
+
event: "UserPromptSubmit",
|
|
27255
|
+
group: {
|
|
27256
|
+
hooks: [
|
|
27257
|
+
{
|
|
27258
|
+
type: "command",
|
|
27259
|
+
command: `node "${path38.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"`
|
|
27260
|
+
},
|
|
27261
|
+
{
|
|
27262
|
+
type: "command",
|
|
27263
|
+
command: `node "${path38.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"`,
|
|
27264
|
+
timeout: 5
|
|
27265
|
+
}
|
|
27266
|
+
]
|
|
27267
|
+
},
|
|
27268
|
+
marker: "dist/hooks/prompt-submit.js"
|
|
27269
|
+
},
|
|
27270
|
+
{
|
|
27271
|
+
event: "Stop",
|
|
27272
|
+
group: {
|
|
27273
|
+
hooks: [
|
|
27274
|
+
{
|
|
27275
|
+
type: "command",
|
|
27276
|
+
command: `node "${path38.join(packageRoot, "dist", "hooks", "stop.js")}"`
|
|
27277
|
+
}
|
|
27278
|
+
]
|
|
27279
|
+
},
|
|
27280
|
+
marker: "dist/hooks/stop.js"
|
|
27281
|
+
},
|
|
27282
|
+
{
|
|
27283
|
+
event: "PreToolUse",
|
|
27284
|
+
group: {
|
|
27285
|
+
matcher: "Bash|apply_patch",
|
|
27286
|
+
hooks: [
|
|
27287
|
+
{
|
|
27288
|
+
type: "command",
|
|
27289
|
+
command: `node "${path38.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"`
|
|
27290
|
+
}
|
|
27291
|
+
]
|
|
27292
|
+
},
|
|
27293
|
+
marker: "dist/hooks/pre-tool-use.js"
|
|
27294
|
+
}
|
|
27295
|
+
];
|
|
27296
|
+
let added = 0;
|
|
27297
|
+
let skipped = 0;
|
|
27298
|
+
for (const { event, group, marker } of hooksToRegister) {
|
|
27299
|
+
if (!hooksJson.hooks[event]) {
|
|
27300
|
+
hooksJson.hooks[event] = [];
|
|
27301
|
+
}
|
|
27302
|
+
const existing = hooksJson.hooks[event];
|
|
27303
|
+
const correctCommand = group.hooks[0]?.command ?? "";
|
|
27304
|
+
const alreadyCorrect = existing.some(
|
|
27305
|
+
(g) => g.hooks.some((h) => h.command === correctCommand)
|
|
27306
|
+
);
|
|
27307
|
+
if (alreadyCorrect) {
|
|
27308
|
+
skipped++;
|
|
27309
|
+
} else {
|
|
27310
|
+
hooksJson.hooks[event] = existing.filter(
|
|
27311
|
+
(g) => !g.hooks.some((h) => h.command.includes(marker))
|
|
27312
|
+
);
|
|
27313
|
+
hooksJson.hooks[event].push(group);
|
|
27314
|
+
added++;
|
|
27315
|
+
}
|
|
27316
|
+
}
|
|
27317
|
+
await writeFile7(hooksPath, JSON.stringify(hooksJson, null, 2) + "\n");
|
|
27318
|
+
return { added, skipped };
|
|
27319
|
+
}
|
|
27320
|
+
function verifyCodexHooks(homeDir = os14.homedir()) {
|
|
27321
|
+
const hooksPath = path38.join(homeDir, ".codex", "hooks.json");
|
|
27322
|
+
if (!existsSync25(hooksPath)) return false;
|
|
27323
|
+
try {
|
|
27324
|
+
const hooksJson = JSON.parse(
|
|
27325
|
+
__require("fs").readFileSync(hooksPath, "utf-8")
|
|
27326
|
+
);
|
|
27327
|
+
if (!hooksJson.hooks) return false;
|
|
27328
|
+
const required = ["SessionStart", "PostToolUse", "UserPromptSubmit", "Stop"];
|
|
27329
|
+
for (const event of required) {
|
|
27330
|
+
const groups = hooksJson.hooks[event];
|
|
27331
|
+
if (!groups || !groups.some(
|
|
27332
|
+
(g) => g.hooks.some((h) => h.command.includes("dist/hooks/"))
|
|
27333
|
+
)) {
|
|
27334
|
+
return false;
|
|
27335
|
+
}
|
|
27336
|
+
}
|
|
27337
|
+
return true;
|
|
27338
|
+
} catch {
|
|
27339
|
+
return false;
|
|
27340
|
+
}
|
|
27341
|
+
}
|
|
27342
|
+
async function runCodexInstaller(homeDir) {
|
|
27343
|
+
const packageRoot = resolvePackageRoot();
|
|
27344
|
+
const result = await mergeCodexHooks(packageRoot, homeDir);
|
|
27345
|
+
process.stderr.write(
|
|
27346
|
+
`[exe-os] Codex hooks: ${result.added} added, ${result.skipped} unchanged
|
|
27347
|
+
`
|
|
27348
|
+
);
|
|
27349
|
+
}
|
|
27350
|
+
var init_installer2 = __esm({
|
|
27351
|
+
"src/adapters/codex/installer.ts"() {
|
|
27352
|
+
"use strict";
|
|
27353
|
+
init_installer();
|
|
27354
|
+
}
|
|
27355
|
+
});
|
|
27356
|
+
|
|
27357
|
+
// src/bin/cli.ts
|
|
27358
|
+
import { existsSync as existsSync26, readFileSync as readFileSync22, writeFileSync as writeFileSync16, readdirSync as readdirSync8, rmSync } from "fs";
|
|
27359
|
+
import path39 from "path";
|
|
27360
|
+
import os15 from "os";
|
|
27202
27361
|
var args = process.argv.slice(2);
|
|
27203
27362
|
if (args.includes("--version") || args.includes("-v")) {
|
|
27204
27363
|
try {
|
|
27205
|
-
const pkgPath =
|
|
27364
|
+
const pkgPath = path39.join(path39.dirname(new URL(import.meta.url).pathname), "..", "..", "package.json");
|
|
27206
27365
|
const pkg = JSON.parse(readFileSync22(pkgPath, "utf8"));
|
|
27207
27366
|
console.log(pkg.version);
|
|
27208
27367
|
} catch {
|
|
@@ -27244,6 +27403,16 @@ if (args.includes("--global")) {
|
|
|
27244
27403
|
await runClaudeInstall();
|
|
27245
27404
|
break;
|
|
27246
27405
|
}
|
|
27406
|
+
} else if (args[0] === "codex") {
|
|
27407
|
+
const sub = args[1];
|
|
27408
|
+
switch (sub) {
|
|
27409
|
+
case "install":
|
|
27410
|
+
await runCodexInstall();
|
|
27411
|
+
break;
|
|
27412
|
+
default:
|
|
27413
|
+
await runCodexInstall();
|
|
27414
|
+
break;
|
|
27415
|
+
}
|
|
27247
27416
|
} else if (args[0] === "cloud") {
|
|
27248
27417
|
const sub = args[1];
|
|
27249
27418
|
if (sub === "sync") {
|
|
@@ -27341,9 +27510,9 @@ ID: ${result.id}`);
|
|
|
27341
27510
|
});
|
|
27342
27511
|
await init_App2().then(() => App_exports);
|
|
27343
27512
|
} else {
|
|
27344
|
-
const claudeDir =
|
|
27345
|
-
const settingsPath =
|
|
27346
|
-
const hasClaudeCode =
|
|
27513
|
+
const claudeDir = path39.join(os15.homedir(), ".claude");
|
|
27514
|
+
const settingsPath = path39.join(claudeDir, "settings.json");
|
|
27515
|
+
const hasClaudeCode = existsSync26(settingsPath) && (() => {
|
|
27347
27516
|
try {
|
|
27348
27517
|
const raw = readFileSync22(settingsPath, "utf8");
|
|
27349
27518
|
return raw.includes("exe-os") || raw.includes("exe-mem");
|
|
@@ -27354,8 +27523,8 @@ ID: ${result.id}`);
|
|
|
27354
27523
|
if (hasClaudeCode) {
|
|
27355
27524
|
let cooName = "exe";
|
|
27356
27525
|
try {
|
|
27357
|
-
const rosterPath =
|
|
27358
|
-
if (
|
|
27526
|
+
const rosterPath = path39.join(os15.homedir(), ".exe-os", "exe-employees.json");
|
|
27527
|
+
if (existsSync26(rosterPath)) {
|
|
27359
27528
|
const roster = JSON.parse(readFileSync22(rosterPath, "utf8"));
|
|
27360
27529
|
const coo = roster.find((e) => e.role === "COO");
|
|
27361
27530
|
if (coo) cooName = coo.name;
|
|
@@ -27395,12 +27564,24 @@ async function runClaudeInstall() {
|
|
|
27395
27564
|
process.exit(1);
|
|
27396
27565
|
}
|
|
27397
27566
|
}
|
|
27567
|
+
async function runCodexInstall() {
|
|
27568
|
+
const { runCodexInstaller: runCodexInstaller2 } = await Promise.resolve().then(() => (init_installer2(), installer_exports2));
|
|
27569
|
+
try {
|
|
27570
|
+
await runCodexInstaller2();
|
|
27571
|
+
} catch (err) {
|
|
27572
|
+
console.error(
|
|
27573
|
+
"Codex hook installation failed:",
|
|
27574
|
+
err instanceof Error ? err.message : String(err)
|
|
27575
|
+
);
|
|
27576
|
+
process.exit(1);
|
|
27577
|
+
}
|
|
27578
|
+
}
|
|
27398
27579
|
async function runClaudeCheck() {
|
|
27399
|
-
const claudeDir =
|
|
27400
|
-
const settingsPath =
|
|
27401
|
-
const claudeJsonPath =
|
|
27580
|
+
const claudeDir = path39.join(os15.homedir(), ".claude");
|
|
27581
|
+
const settingsPath = path39.join(claudeDir, "settings.json");
|
|
27582
|
+
const claudeJsonPath = path39.join(os15.homedir(), ".claude.json");
|
|
27402
27583
|
let ok = true;
|
|
27403
|
-
if (
|
|
27584
|
+
if (existsSync26(settingsPath)) {
|
|
27404
27585
|
let settings;
|
|
27405
27586
|
try {
|
|
27406
27587
|
settings = JSON.parse(readFileSync22(settingsPath, "utf8"));
|
|
@@ -27429,7 +27610,7 @@ async function runClaudeCheck() {
|
|
|
27429
27610
|
console.log("\x1B[31m\u2717\x1B[0m settings.json not found");
|
|
27430
27611
|
ok = false;
|
|
27431
27612
|
}
|
|
27432
|
-
if (
|
|
27613
|
+
if (existsSync26(claudeJsonPath)) {
|
|
27433
27614
|
let claudeJson;
|
|
27434
27615
|
try {
|
|
27435
27616
|
claudeJson = JSON.parse(readFileSync22(claudeJsonPath, "utf8"));
|
|
@@ -27451,8 +27632,8 @@ async function runClaudeCheck() {
|
|
|
27451
27632
|
console.log("\x1B[31m\u2717\x1B[0m claude.json not found");
|
|
27452
27633
|
ok = false;
|
|
27453
27634
|
}
|
|
27454
|
-
const skillsDir =
|
|
27455
|
-
if (
|
|
27635
|
+
const skillsDir = path39.join(claudeDir, "skills");
|
|
27636
|
+
if (existsSync26(skillsDir)) {
|
|
27456
27637
|
console.log("\x1B[32m\u2713\x1B[0m Slash skills directory exists");
|
|
27457
27638
|
} else {
|
|
27458
27639
|
console.log("\x1B[31m\u2717\x1B[0m Slash skills directory missing");
|
|
@@ -27468,15 +27649,15 @@ async function runClaudeCheck() {
|
|
|
27468
27649
|
async function runClaudeUninstall(flags = []) {
|
|
27469
27650
|
const dryRun = flags.includes("--dry-run");
|
|
27470
27651
|
const purge = flags.includes("--purge");
|
|
27471
|
-
const homeDir =
|
|
27472
|
-
const claudeDir =
|
|
27473
|
-
const settingsPath =
|
|
27474
|
-
const claudeJsonPath =
|
|
27475
|
-
const exeOsDir =
|
|
27652
|
+
const homeDir = os15.homedir();
|
|
27653
|
+
const claudeDir = path39.join(homeDir, ".claude");
|
|
27654
|
+
const settingsPath = path39.join(claudeDir, "settings.json");
|
|
27655
|
+
const claudeJsonPath = path39.join(homeDir, ".claude.json");
|
|
27656
|
+
const exeOsDir = path39.join(homeDir, ".exe-os");
|
|
27476
27657
|
let removed = 0;
|
|
27477
27658
|
const log = (msg) => console.log(dryRun ? `[dry-run] ${msg}` : msg);
|
|
27478
27659
|
let settings = {};
|
|
27479
|
-
if (
|
|
27660
|
+
if (existsSync26(settingsPath)) {
|
|
27480
27661
|
try {
|
|
27481
27662
|
settings = JSON.parse(readFileSync22(settingsPath, "utf8"));
|
|
27482
27663
|
} catch {
|
|
@@ -27523,7 +27704,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
27523
27704
|
removed++;
|
|
27524
27705
|
}
|
|
27525
27706
|
}
|
|
27526
|
-
if (
|
|
27707
|
+
if (existsSync26(claudeJsonPath)) {
|
|
27527
27708
|
const raw = readFileSync22(claudeJsonPath, "utf8");
|
|
27528
27709
|
if (raw.length > 1e6) {
|
|
27529
27710
|
console.error("claude.json exceeds 1 MB \u2014 skipping parse.");
|
|
@@ -27553,14 +27734,14 @@ async function runClaudeUninstall(flags = []) {
|
|
|
27553
27734
|
}
|
|
27554
27735
|
}
|
|
27555
27736
|
}
|
|
27556
|
-
const skillsDir =
|
|
27557
|
-
if (
|
|
27737
|
+
const skillsDir = path39.join(claudeDir, "skills");
|
|
27738
|
+
if (existsSync26(skillsDir)) {
|
|
27558
27739
|
let skillCount = 0;
|
|
27559
27740
|
try {
|
|
27560
27741
|
const entries = readdirSync8(skillsDir);
|
|
27561
27742
|
for (const entry of entries) {
|
|
27562
27743
|
if (entry.startsWith("exe")) {
|
|
27563
|
-
const fullPath =
|
|
27744
|
+
const fullPath = path39.join(skillsDir, entry);
|
|
27564
27745
|
if (!dryRun) rmSync(fullPath, { recursive: true, force: true });
|
|
27565
27746
|
skillCount++;
|
|
27566
27747
|
}
|
|
@@ -27572,8 +27753,8 @@ async function runClaudeUninstall(flags = []) {
|
|
|
27572
27753
|
removed++;
|
|
27573
27754
|
}
|
|
27574
27755
|
}
|
|
27575
|
-
const claudeMdPath =
|
|
27576
|
-
if (
|
|
27756
|
+
const claudeMdPath = path39.join(claudeDir, "CLAUDE.md");
|
|
27757
|
+
if (existsSync26(claudeMdPath)) {
|
|
27577
27758
|
const content = readFileSync22(claudeMdPath, "utf8");
|
|
27578
27759
|
const startMarker = "<!-- exe-os:orchestration-start -->";
|
|
27579
27760
|
const endMarker = "<!-- exe-os:orchestration-end -->";
|
|
@@ -27586,14 +27767,14 @@ async function runClaudeUninstall(flags = []) {
|
|
|
27586
27767
|
removed++;
|
|
27587
27768
|
}
|
|
27588
27769
|
}
|
|
27589
|
-
const agentsDir =
|
|
27590
|
-
if (
|
|
27770
|
+
const agentsDir = path39.join(claudeDir, "agents");
|
|
27771
|
+
if (existsSync26(agentsDir)) {
|
|
27591
27772
|
let agentCount = 0;
|
|
27592
27773
|
try {
|
|
27593
27774
|
const entries = readdirSync8(agentsDir).filter((f) => f.endsWith(".md"));
|
|
27594
27775
|
let knownNames = /* @__PURE__ */ new Set();
|
|
27595
|
-
const rosterPath =
|
|
27596
|
-
if (
|
|
27776
|
+
const rosterPath = path39.join(exeOsDir, "exe-employees.json");
|
|
27777
|
+
if (existsSync26(rosterPath)) {
|
|
27597
27778
|
try {
|
|
27598
27779
|
const roster = JSON.parse(readFileSync22(rosterPath, "utf8"));
|
|
27599
27780
|
knownNames = new Set(roster.map((e) => e.name));
|
|
@@ -27603,7 +27784,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
27603
27784
|
for (const entry of entries) {
|
|
27604
27785
|
const name = entry.replace(/\.md$/, "");
|
|
27605
27786
|
if (knownNames.has(name)) {
|
|
27606
|
-
if (!dryRun) rmSync(
|
|
27787
|
+
if (!dryRun) rmSync(path39.join(agentsDir, entry), { force: true });
|
|
27607
27788
|
agentCount++;
|
|
27608
27789
|
}
|
|
27609
27790
|
}
|
|
@@ -27614,14 +27795,14 @@ async function runClaudeUninstall(flags = []) {
|
|
|
27614
27795
|
removed++;
|
|
27615
27796
|
}
|
|
27616
27797
|
}
|
|
27617
|
-
const projectsDir =
|
|
27618
|
-
if (
|
|
27798
|
+
const projectsDir = path39.join(claudeDir, "projects");
|
|
27799
|
+
if (existsSync26(projectsDir)) {
|
|
27619
27800
|
let projectCount = 0;
|
|
27620
27801
|
try {
|
|
27621
27802
|
const projects = readdirSync8(projectsDir);
|
|
27622
27803
|
for (const proj of projects) {
|
|
27623
|
-
const projSettings =
|
|
27624
|
-
if (!
|
|
27804
|
+
const projSettings = path39.join(projectsDir, proj, "settings.json");
|
|
27805
|
+
if (!existsSync26(projSettings)) continue;
|
|
27625
27806
|
try {
|
|
27626
27807
|
const pSettings = JSON.parse(readFileSync22(projSettings, "utf8"));
|
|
27627
27808
|
let changed = false;
|
|
@@ -27657,17 +27838,17 @@ async function runClaudeUninstall(flags = []) {
|
|
|
27657
27838
|
};
|
|
27658
27839
|
const exeBinPath = findExeBin3();
|
|
27659
27840
|
if (!exeBinPath) throw new Error("exe-os not found in PATH");
|
|
27660
|
-
const binDir =
|
|
27841
|
+
const binDir = path39.dirname(exeBinPath);
|
|
27661
27842
|
let symlinkCount = 0;
|
|
27662
|
-
const rosterPath =
|
|
27663
|
-
if (
|
|
27843
|
+
const rosterPath = path39.join(exeOsDir, "exe-employees.json");
|
|
27844
|
+
if (existsSync26(rosterPath)) {
|
|
27664
27845
|
const roster = JSON.parse(readFileSync22(rosterPath, "utf8"));
|
|
27665
27846
|
const coordinatorName = roster.find((e) => e.role?.toLowerCase() === "coo")?.name ?? "exe";
|
|
27666
27847
|
for (const emp of roster) {
|
|
27667
27848
|
if (emp.name === coordinatorName) continue;
|
|
27668
27849
|
for (const suffix of ["", "-opencode"]) {
|
|
27669
|
-
const linkPath =
|
|
27670
|
-
if (
|
|
27850
|
+
const linkPath = path39.join(binDir, `${emp.name}${suffix}`);
|
|
27851
|
+
if (existsSync26(linkPath)) {
|
|
27671
27852
|
if (!dryRun) rmSync(linkPath, { force: true });
|
|
27672
27853
|
symlinkCount++;
|
|
27673
27854
|
}
|
|
@@ -27680,7 +27861,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
27680
27861
|
}
|
|
27681
27862
|
} catch {
|
|
27682
27863
|
}
|
|
27683
|
-
if (purge &&
|
|
27864
|
+
if (purge && existsSync26(exeOsDir)) {
|
|
27684
27865
|
if (!dryRun) {
|
|
27685
27866
|
process.stdout.write("\x1B[33m\u26A0 This will delete all memories, identities, and agent data.\x1B[0m\n");
|
|
27686
27867
|
process.stdout.write(" Removing ~/.exe-os...\n");
|
|
@@ -27705,7 +27886,7 @@ async function checkForUpdateOnBoot() {
|
|
|
27705
27886
|
const config = await loadConfig2();
|
|
27706
27887
|
if (!config.autoUpdate.checkOnBoot) return;
|
|
27707
27888
|
const { checkForUpdate: checkForUpdate2 } = await Promise.resolve().then(() => (init_update(), update_exports));
|
|
27708
|
-
const packageRoot =
|
|
27889
|
+
const packageRoot = path39.resolve(
|
|
27709
27890
|
new URL("../..", import.meta.url).pathname
|
|
27710
27891
|
);
|
|
27711
27892
|
const result = checkForUpdate2(packageRoot);
|
|
@@ -27764,7 +27945,7 @@ async function runActivate(key) {
|
|
|
27764
27945
|
const idTemplate = getIdentityTemplate(identityKey);
|
|
27765
27946
|
if (idTemplate) {
|
|
27766
27947
|
const idPath = identityPath2(name);
|
|
27767
|
-
const dir =
|
|
27948
|
+
const dir = path39.dirname(idPath);
|
|
27768
27949
|
if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
|
|
27769
27950
|
fs8.writeFileSync(idPath, idTemplate.replace(/^agent_id: \w+/m, `agent_id: ${name}`), "utf-8");
|
|
27770
27951
|
}
|