@askexenow/exe-os 0.8.38 → 0.8.39
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/README.md +17 -8
- package/dist/bin/backfill-conversations.js +46 -10
- package/dist/bin/backfill-responses.js +46 -10
- package/dist/bin/backfill-vectors.js +42 -8
- package/dist/bin/cleanup-stale-review-tasks.js +37 -8
- package/dist/bin/cli.js +281 -154
- package/dist/bin/exe-agent.js +19 -4
- package/dist/bin/exe-assign.js +39 -5
- package/dist/bin/exe-boot.js +237 -111
- package/dist/bin/exe-call.js +11 -6
- package/dist/bin/exe-cloud.js +99 -28
- package/dist/bin/exe-dispatch.js +1 -1
- package/dist/bin/exe-doctor.js +37 -8
- package/dist/bin/exe-export-behaviors.js +39 -10
- package/dist/bin/exe-forget.js +38 -9
- package/dist/bin/exe-gateway.js +109 -42
- package/dist/bin/exe-heartbeat.js +49 -20
- package/dist/bin/exe-kill.js +39 -10
- package/dist/bin/exe-launch-agent.js +58 -22
- package/dist/bin/exe-link.js +184 -85
- package/dist/bin/exe-new-employee.js +21 -7
- package/dist/bin/exe-pending-messages.js +46 -17
- package/dist/bin/exe-pending-notifications.js +37 -8
- package/dist/bin/exe-pending-reviews.js +47 -18
- package/dist/bin/exe-rename.js +21 -7
- package/dist/bin/exe-review.js +34 -5
- package/dist/bin/exe-search.js +47 -10
- package/dist/bin/exe-session-cleanup.js +56 -19
- package/dist/bin/exe-settings.js +63 -2
- package/dist/bin/exe-status.js +34 -5
- package/dist/bin/exe-team.js +34 -5
- package/dist/bin/git-sweep.js +38 -9
- package/dist/bin/graph-backfill.js +37 -8
- package/dist/bin/graph-export.js +37 -8
- package/dist/bin/install.js +1 -1
- package/dist/bin/scan-tasks.js +40 -11
- package/dist/bin/setup.js +58 -24
- package/dist/bin/shard-migrate.js +37 -8
- package/dist/bin/wiki-sync.js +39 -9
- package/dist/gateway/index.js +102 -37
- package/dist/hooks/bug-report-worker.js +62 -28
- package/dist/hooks/commit-complete.js +38 -9
- package/dist/hooks/error-recall.js +49 -8
- package/dist/hooks/exe-heartbeat-hook.js +3 -2
- package/dist/hooks/ingest-worker.js +151 -37
- package/dist/hooks/ingest.js +74 -28
- package/dist/hooks/instructions-loaded.js +39 -9
- package/dist/hooks/notification.js +37 -7
- package/dist/hooks/post-compact.js +37 -7
- package/dist/hooks/pre-compact.js +35 -6
- package/dist/hooks/pre-tool-use.js +52 -14
- package/dist/hooks/prompt-ingest-worker.js +56 -10
- package/dist/hooks/prompt-submit.js +61 -23
- package/dist/hooks/response-ingest-worker.js +57 -11
- package/dist/hooks/session-end.js +43 -10
- package/dist/hooks/session-start.js +46 -8
- package/dist/hooks/stop.js +37 -7
- package/dist/hooks/subagent-stop.js +37 -7
- package/dist/hooks/summary-worker.js +317 -99
- package/dist/index.js +87 -22
- package/dist/lib/cloud-sync.js +172 -78
- package/dist/lib/config.js +4 -1
- package/dist/lib/consolidation.js +5 -4
- package/dist/lib/database.js +1 -0
- package/dist/lib/device-registry.js +2 -1
- package/dist/lib/embedder.js +9 -1
- package/dist/lib/employees.js +11 -6
- package/dist/lib/exe-daemon-client.js +6 -1
- package/dist/lib/exe-daemon.js +71 -28
- package/dist/lib/hybrid-search.js +47 -10
- package/dist/lib/identity.js +1 -1
- package/dist/lib/keychain.js +2 -1
- package/dist/lib/license.js +13 -4
- package/dist/lib/messaging.js +1 -1
- package/dist/lib/reminders.js +2 -2
- package/dist/lib/schedules.js +37 -8
- package/dist/lib/skill-learning.js +1 -1
- package/dist/lib/store.js +37 -8
- package/dist/lib/tasks.js +1 -1
- package/dist/lib/tmux-routing.js +1 -1
- package/dist/mcp/server.js +97 -43
- package/dist/mcp/tools/complete-reminder.js +1 -1
- package/dist/mcp/tools/create-task.js +14 -6
- package/dist/mcp/tools/deactivate-behavior.js +2 -2
- package/dist/mcp/tools/list-reminders.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 +35 -6
- package/dist/tui/App.js +177 -95
- package/package.json +3 -3
package/dist/bin/cli.js
CHANGED
|
@@ -42,7 +42,7 @@ __export(config_exports, {
|
|
|
42
42
|
migrateConfig: () => migrateConfig,
|
|
43
43
|
saveConfig: () => saveConfig
|
|
44
44
|
});
|
|
45
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
45
|
+
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
46
46
|
import { readFileSync, existsSync, renameSync } from "fs";
|
|
47
47
|
import path from "path";
|
|
48
48
|
import os from "os";
|
|
@@ -168,6 +168,9 @@ async function saveConfig(config) {
|
|
|
168
168
|
await mkdir(dir, { recursive: true });
|
|
169
169
|
const configPath = path.join(dir, "config.json");
|
|
170
170
|
await writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
171
|
+
if (config.cloud?.apiKey) {
|
|
172
|
+
await chmod(configPath, 384);
|
|
173
|
+
}
|
|
171
174
|
}
|
|
172
175
|
async function loadConfigFrom(configPath) {
|
|
173
176
|
const raw = await readFile(configPath, "utf-8");
|
|
@@ -356,15 +359,20 @@ function addEmployee(employees, employee) {
|
|
|
356
359
|
}
|
|
357
360
|
return [...employees, normalized];
|
|
358
361
|
}
|
|
362
|
+
function findExeBin() {
|
|
363
|
+
try {
|
|
364
|
+
return execSync(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
|
|
365
|
+
} catch {
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
359
369
|
function registerBinSymlinks(name) {
|
|
360
370
|
const created = [];
|
|
361
371
|
const skipped = [];
|
|
362
372
|
const errors = [];
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
} catch {
|
|
367
|
-
errors.push("Could not find 'exe' in PATH");
|
|
373
|
+
const exeBinPath = findExeBin();
|
|
374
|
+
if (!exeBinPath) {
|
|
375
|
+
errors.push("Could not find 'exe-os' in PATH");
|
|
368
376
|
return { created, skipped, errors };
|
|
369
377
|
}
|
|
370
378
|
const binDir = path2.dirname(exeBinPath);
|
|
@@ -1096,6 +1104,7 @@ async function ensureSchema() {
|
|
|
1096
1104
|
const client = getRawClient();
|
|
1097
1105
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
1098
1106
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
1107
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
1099
1108
|
try {
|
|
1100
1109
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
1101
1110
|
} catch {
|
|
@@ -1912,12 +1921,13 @@ __export(keychain_exports, {
|
|
|
1912
1921
|
importMnemonic: () => importMnemonic,
|
|
1913
1922
|
setMasterKey: () => setMasterKey
|
|
1914
1923
|
});
|
|
1915
|
-
import { readFile as readFile4, writeFile as writeFile4, unlink, mkdir as mkdir4, chmod } from "fs/promises";
|
|
1924
|
+
import { readFile as readFile4, writeFile as writeFile4, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
|
|
1916
1925
|
import { existsSync as existsSync5 } from "fs";
|
|
1917
1926
|
import path5 from "path";
|
|
1927
|
+
import os4 from "os";
|
|
1918
1928
|
import crypto from "crypto";
|
|
1919
1929
|
function getKeyDir() {
|
|
1920
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path5.join(
|
|
1930
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path5.join(os4.homedir(), ".exe-os");
|
|
1921
1931
|
}
|
|
1922
1932
|
function getKeyPath() {
|
|
1923
1933
|
return path5.join(getKeyDir(), "master.key");
|
|
@@ -1965,7 +1975,7 @@ async function setMasterKey(key) {
|
|
|
1965
1975
|
await mkdir4(dir, { recursive: true });
|
|
1966
1976
|
const keyPath = getKeyPath();
|
|
1967
1977
|
await writeFile4(keyPath, b64 + "\n", "utf-8");
|
|
1968
|
-
await
|
|
1978
|
+
await chmod2(keyPath, 384);
|
|
1969
1979
|
}
|
|
1970
1980
|
async function deleteMasterKey() {
|
|
1971
1981
|
const keytar = await tryKeytar();
|
|
@@ -2307,6 +2317,28 @@ __export(store_exports, {
|
|
|
2307
2317
|
vectorToBlob: () => vectorToBlob,
|
|
2308
2318
|
writeMemory: () => writeMemory
|
|
2309
2319
|
});
|
|
2320
|
+
function isBusyError2(err) {
|
|
2321
|
+
if (err instanceof Error) {
|
|
2322
|
+
const msg = err.message.toLowerCase();
|
|
2323
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
2324
|
+
}
|
|
2325
|
+
return false;
|
|
2326
|
+
}
|
|
2327
|
+
async function retryOnBusy2(fn, label) {
|
|
2328
|
+
for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
|
|
2329
|
+
try {
|
|
2330
|
+
return await fn();
|
|
2331
|
+
} catch (err) {
|
|
2332
|
+
if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
|
|
2333
|
+
process.stderr.write(
|
|
2334
|
+
`[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
|
|
2335
|
+
`
|
|
2336
|
+
);
|
|
2337
|
+
await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2340
|
+
throw new Error("unreachable");
|
|
2341
|
+
}
|
|
2310
2342
|
async function initStore(options) {
|
|
2311
2343
|
if (_flushTimer !== null) {
|
|
2312
2344
|
clearInterval(_flushTimer);
|
|
@@ -2335,14 +2367,17 @@ async function initStore(options) {
|
|
|
2335
2367
|
dbPath,
|
|
2336
2368
|
encryptionKey: hexKey
|
|
2337
2369
|
});
|
|
2338
|
-
await ensureSchema();
|
|
2370
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
2339
2371
|
try {
|
|
2340
2372
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
2341
2373
|
initShardManager2(hexKey);
|
|
2342
2374
|
} catch {
|
|
2343
2375
|
}
|
|
2344
2376
|
const client = getClient();
|
|
2345
|
-
const vResult = await
|
|
2377
|
+
const vResult = await retryOnBusy2(
|
|
2378
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
2379
|
+
"version-query"
|
|
2380
|
+
);
|
|
2346
2381
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
2347
2382
|
}
|
|
2348
2383
|
function classifyTier(record) {
|
|
@@ -2722,7 +2757,7 @@ async function getMemoryCardinality(agentId) {
|
|
|
2722
2757
|
return 0;
|
|
2723
2758
|
}
|
|
2724
2759
|
}
|
|
2725
|
-
var _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
2760
|
+
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
2726
2761
|
var init_store = __esm({
|
|
2727
2762
|
"src/lib/store.ts"() {
|
|
2728
2763
|
"use strict";
|
|
@@ -2730,6 +2765,8 @@ var init_store = __esm({
|
|
|
2730
2765
|
init_database();
|
|
2731
2766
|
init_keychain();
|
|
2732
2767
|
init_config();
|
|
2768
|
+
INIT_MAX_RETRIES = 3;
|
|
2769
|
+
INIT_RETRY_DELAY_MS = 1e3;
|
|
2733
2770
|
_pendingRecords = [];
|
|
2734
2771
|
_batchSize = 20;
|
|
2735
2772
|
_flushIntervalMs = 1e4;
|
|
@@ -2748,6 +2785,10 @@ import path7 from "path";
|
|
|
2748
2785
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2749
2786
|
function handleData(chunk) {
|
|
2750
2787
|
_buffer += chunk.toString();
|
|
2788
|
+
if (_buffer.length > MAX_BUFFER) {
|
|
2789
|
+
_buffer = "";
|
|
2790
|
+
return;
|
|
2791
|
+
}
|
|
2751
2792
|
let newlineIdx;
|
|
2752
2793
|
while ((newlineIdx = _buffer.indexOf("\n")) !== -1) {
|
|
2753
2794
|
const line = _buffer.slice(0, newlineIdx).trim();
|
|
@@ -3055,7 +3096,7 @@ function disconnectClient() {
|
|
|
3055
3096
|
entry.resolve({ error: "Client disconnected" });
|
|
3056
3097
|
}
|
|
3057
3098
|
}
|
|
3058
|
-
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, _socket, _connected, _buffer, _requestCount, HEALTH_CHECK_INTERVAL, _pending;
|
|
3099
|
+
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, _socket, _connected, _buffer, _requestCount, HEALTH_CHECK_INTERVAL, _pending, MAX_BUFFER;
|
|
3059
3100
|
var init_exe_daemon_client = __esm({
|
|
3060
3101
|
"src/lib/exe-daemon-client.ts"() {
|
|
3061
3102
|
"use strict";
|
|
@@ -3072,6 +3113,7 @@ var init_exe_daemon_client = __esm({
|
|
|
3072
3113
|
_requestCount = 0;
|
|
3073
3114
|
HEALTH_CHECK_INTERVAL = 100;
|
|
3074
3115
|
_pending = /* @__PURE__ */ new Map();
|
|
3116
|
+
MAX_BUFFER = 1e7;
|
|
3075
3117
|
}
|
|
3076
3118
|
});
|
|
3077
3119
|
|
|
@@ -3109,7 +3151,8 @@ import { parseArgs } from "util";
|
|
|
3109
3151
|
async function findJsonlFiles(sinceDate, projectFilter) {
|
|
3110
3152
|
const projectsDir = path8.join(homedir(), ".claude", "projects");
|
|
3111
3153
|
const files = [];
|
|
3112
|
-
async function walk(dir) {
|
|
3154
|
+
async function walk(dir, depth = 0) {
|
|
3155
|
+
if (depth > MAX_WALK_DEPTH) return;
|
|
3113
3156
|
let entries;
|
|
3114
3157
|
try {
|
|
3115
3158
|
entries = await readdir2(dir, { withFileTypes: true });
|
|
@@ -3120,7 +3163,7 @@ async function findJsonlFiles(sinceDate, projectFilter) {
|
|
|
3120
3163
|
const full = path8.join(dir, entry.name);
|
|
3121
3164
|
if (entry.isDirectory()) {
|
|
3122
3165
|
if (entry.name === "subagents" || entry.name === "tool-results") continue;
|
|
3123
|
-
await walk(full);
|
|
3166
|
+
await walk(full, depth + 1);
|
|
3124
3167
|
} else if (entry.name.endsWith(".jsonl")) {
|
|
3125
3168
|
try {
|
|
3126
3169
|
const s = await stat(full);
|
|
@@ -3438,7 +3481,7 @@ async function backfillConversations(options) {
|
|
|
3438
3481
|
);
|
|
3439
3482
|
return stats;
|
|
3440
3483
|
}
|
|
3441
|
-
var TOOL_NAME, MIN_MESSAGES, MAX_SUMMARY_LENGTH;
|
|
3484
|
+
var TOOL_NAME, MIN_MESSAGES, MAX_SUMMARY_LENGTH, MAX_WALK_DEPTH;
|
|
3442
3485
|
var init_backfill_conversations = __esm({
|
|
3443
3486
|
"src/bin/backfill-conversations.ts"() {
|
|
3444
3487
|
"use strict";
|
|
@@ -3449,6 +3492,7 @@ var init_backfill_conversations = __esm({
|
|
|
3449
3492
|
TOOL_NAME = "backfill-conversation";
|
|
3450
3493
|
MIN_MESSAGES = 3;
|
|
3451
3494
|
MAX_SUMMARY_LENGTH = 4e3;
|
|
3495
|
+
MAX_WALK_DEPTH = 10;
|
|
3452
3496
|
if (isMainModule(import.meta.url)) {
|
|
3453
3497
|
const { values } = parseArgs({
|
|
3454
3498
|
options: {
|
|
@@ -4227,9 +4271,17 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
4227
4271
|
return { success: false, error: err instanceof Error ? err.message : String(err) };
|
|
4228
4272
|
}
|
|
4229
4273
|
}
|
|
4274
|
+
function findExeBin2() {
|
|
4275
|
+
try {
|
|
4276
|
+
return execSync2(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
|
|
4277
|
+
} catch {
|
|
4278
|
+
return null;
|
|
4279
|
+
}
|
|
4280
|
+
}
|
|
4230
4281
|
function removeOldSymlinks(name) {
|
|
4231
4282
|
try {
|
|
4232
|
-
const exeBinPath =
|
|
4283
|
+
const exeBinPath = findExeBin2();
|
|
4284
|
+
if (!exeBinPath) return;
|
|
4233
4285
|
const binDir = path9.dirname(exeBinPath);
|
|
4234
4286
|
for (const suffix of ["", "-opencode"]) {
|
|
4235
4287
|
const linkPath = path9.join(binDir, `${name}${suffix}`);
|
|
@@ -4408,8 +4460,8 @@ async function embedDirect(text) {
|
|
|
4408
4460
|
const llamaCpp = await import("node-llama-cpp");
|
|
4409
4461
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
4410
4462
|
const { existsSync: existsSync22 } = await import("fs");
|
|
4411
|
-
const
|
|
4412
|
-
const modelPath =
|
|
4463
|
+
const path34 = await import("path");
|
|
4464
|
+
const modelPath = path34.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
4413
4465
|
if (!existsSync22(modelPath)) {
|
|
4414
4466
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
4415
4467
|
}
|
|
@@ -4459,6 +4511,14 @@ import { readFileSync as readFileSync6, writeFileSync as writeFileSync2, existsS
|
|
|
4459
4511
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
4460
4512
|
import path11 from "path";
|
|
4461
4513
|
import { jwtVerify, importSPKI } from "jose";
|
|
4514
|
+
async function fetchRetry(url, init) {
|
|
4515
|
+
try {
|
|
4516
|
+
return await fetch(url, init);
|
|
4517
|
+
} catch {
|
|
4518
|
+
await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));
|
|
4519
|
+
return fetch(url, { ...init, signal: AbortSignal.timeout(1e4) });
|
|
4520
|
+
}
|
|
4521
|
+
}
|
|
4462
4522
|
function loadDeviceId() {
|
|
4463
4523
|
const deviceJsonPath = path11.join(EXE_AI_DIR, "device.json");
|
|
4464
4524
|
try {
|
|
@@ -4490,7 +4550,7 @@ function loadLicense() {
|
|
|
4490
4550
|
}
|
|
4491
4551
|
function saveLicense(apiKey) {
|
|
4492
4552
|
mkdirSync3(EXE_AI_DIR, { recursive: true });
|
|
4493
|
-
writeFileSync2(LICENSE_PATH, apiKey.trim(), "utf8");
|
|
4553
|
+
writeFileSync2(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
|
|
4494
4554
|
}
|
|
4495
4555
|
async function verifyLicenseJwt(token) {
|
|
4496
4556
|
try {
|
|
@@ -4542,7 +4602,7 @@ function cacheResponse(token) {
|
|
|
4542
4602
|
async function validateLicense(apiKey, deviceId) {
|
|
4543
4603
|
const did = deviceId ?? loadDeviceId();
|
|
4544
4604
|
try {
|
|
4545
|
-
const res = await
|
|
4605
|
+
const res = await fetchRetry(`${API_BASE}/auth/activate`, {
|
|
4546
4606
|
method: "POST",
|
|
4547
4607
|
headers: { "Content-Type": "application/json" },
|
|
4548
4608
|
body: JSON.stringify({ apiKey, deviceId: did }),
|
|
@@ -4633,7 +4693,7 @@ async function assertVpsLicense(opts) {
|
|
|
4633
4693
|
let explicitRejection = false;
|
|
4634
4694
|
let transientFailure = false;
|
|
4635
4695
|
try {
|
|
4636
|
-
const res = await
|
|
4696
|
+
const res = await fetchRetry(`${API_BASE}/auth/activate`, {
|
|
4637
4697
|
method: "POST",
|
|
4638
4698
|
headers: { "Content-Type": "application/json" },
|
|
4639
4699
|
body: JSON.stringify({ apiKey, deviceId }),
|
|
@@ -4735,7 +4795,7 @@ function stopLicenseRevalidation() {
|
|
|
4735
4795
|
_revalTimer = null;
|
|
4736
4796
|
}
|
|
4737
4797
|
}
|
|
4738
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE, LICENSE_PUBLIC_KEY_PEM, LICENSE_JWT_ALG, PLAN_LIMITS, FREE_LICENSE, CACHE_MAX_AGE_MS, _revalTimer;
|
|
4798
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE, RETRY_DELAY_MS, LICENSE_PUBLIC_KEY_PEM, LICENSE_JWT_ALG, PLAN_LIMITS, FREE_LICENSE, CACHE_MAX_AGE_MS, _revalTimer;
|
|
4739
4799
|
var init_license = __esm({
|
|
4740
4800
|
"src/lib/license.ts"() {
|
|
4741
4801
|
"use strict";
|
|
@@ -4744,6 +4804,7 @@ var init_license = __esm({
|
|
|
4744
4804
|
CACHE_PATH = path11.join(EXE_AI_DIR, "license-cache.json");
|
|
4745
4805
|
DEVICE_ID_PATH = path11.join(EXE_AI_DIR, "device-id");
|
|
4746
4806
|
API_BASE = "https://askexe.com/cloud";
|
|
4807
|
+
RETRY_DELAY_MS = 500;
|
|
4747
4808
|
LICENSE_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
4748
4809
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
|
|
4749
4810
|
4uj+UqeKCcvtgNHKmOK278HJaJcANe9xAeji8AFYu27q3WtzCi04pHudow==
|
|
@@ -5443,7 +5504,7 @@ __export(setup_wizard_exports, {
|
|
|
5443
5504
|
});
|
|
5444
5505
|
import crypto3 from "crypto";
|
|
5445
5506
|
import { existsSync as existsSync12, mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync4, unlinkSync as unlinkSync4 } from "fs";
|
|
5446
|
-
import
|
|
5507
|
+
import os5 from "os";
|
|
5447
5508
|
import path13 from "path";
|
|
5448
5509
|
import { createInterface as createInterface2 } from "readline";
|
|
5449
5510
|
function loadSetupState() {
|
|
@@ -5536,12 +5597,23 @@ async function runSetupWizard(opts = {}) {
|
|
|
5536
5597
|
try {
|
|
5537
5598
|
const { loadDeviceId: loadDeviceId2 } = await Promise.resolve().then(() => (init_license(), license_exports));
|
|
5538
5599
|
const deviceId = loadDeviceId2();
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5600
|
+
let res;
|
|
5601
|
+
try {
|
|
5602
|
+
res = await fetch("https://askexe.com/cloud/auth/auto-provision", {
|
|
5603
|
+
method: "POST",
|
|
5604
|
+
headers: { "Content-Type": "application/json" },
|
|
5605
|
+
body: JSON.stringify({ deviceId }),
|
|
5606
|
+
signal: AbortSignal.timeout(1e4)
|
|
5607
|
+
});
|
|
5608
|
+
} catch {
|
|
5609
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
5610
|
+
res = await fetch("https://askexe.com/cloud/auth/auto-provision", {
|
|
5611
|
+
method: "POST",
|
|
5612
|
+
headers: { "Content-Type": "application/json" },
|
|
5613
|
+
body: JSON.stringify({ deviceId }),
|
|
5614
|
+
signal: AbortSignal.timeout(1e4)
|
|
5615
|
+
});
|
|
5616
|
+
}
|
|
5545
5617
|
if (res.ok) {
|
|
5546
5618
|
const data = await res.json();
|
|
5547
5619
|
if (data.apiKey) {
|
|
@@ -5599,7 +5671,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
5599
5671
|
await saveConfig(config);
|
|
5600
5672
|
log("");
|
|
5601
5673
|
try {
|
|
5602
|
-
const claudeJsonPath = path13.join(
|
|
5674
|
+
const claudeJsonPath = path13.join(os5.homedir(), ".claude.json");
|
|
5603
5675
|
let claudeJson = {};
|
|
5604
5676
|
try {
|
|
5605
5677
|
claudeJson = JSON.parse(readFileSync8(claudeJsonPath, "utf8"));
|
|
@@ -5607,7 +5679,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
5607
5679
|
}
|
|
5608
5680
|
if (!claudeJson.projects) claudeJson.projects = {};
|
|
5609
5681
|
const projects = claudeJson.projects;
|
|
5610
|
-
for (const dir of [process.cwd(),
|
|
5682
|
+
for (const dir of [process.cwd(), os5.homedir()]) {
|
|
5611
5683
|
if (!projects[dir]) projects[dir] = {};
|
|
5612
5684
|
projects[dir].hasTrustDialogAccepted = true;
|
|
5613
5685
|
}
|
|
@@ -5851,7 +5923,7 @@ var init_setup_wizard = __esm({
|
|
|
5851
5923
|
init_config();
|
|
5852
5924
|
init_keychain();
|
|
5853
5925
|
init_model_downloader();
|
|
5854
|
-
SETUP_STATE_PATH = path13.join(
|
|
5926
|
+
SETUP_STATE_PATH = path13.join(os5.homedir(), ".exe-os", "setup-state.json");
|
|
5855
5927
|
}
|
|
5856
5928
|
});
|
|
5857
5929
|
|
|
@@ -10213,8 +10285,8 @@ var init_ErrorOverview = __esm({
|
|
|
10213
10285
|
"use strict";
|
|
10214
10286
|
init_Box();
|
|
10215
10287
|
init_Text();
|
|
10216
|
-
cleanupPath = (
|
|
10217
|
-
return
|
|
10288
|
+
cleanupPath = (path34) => {
|
|
10289
|
+
return path34?.replace(`file://${cwd()}/`, "");
|
|
10218
10290
|
};
|
|
10219
10291
|
stackUtils = new StackUtils({
|
|
10220
10292
|
cwd: cwd(),
|
|
@@ -12668,7 +12740,7 @@ var init_demo_data = __esm({
|
|
|
12668
12740
|
"src/tui/demo-data.ts"() {
|
|
12669
12741
|
"use strict";
|
|
12670
12742
|
DEMO_EMPLOYEES = [
|
|
12671
|
-
{ name: "exe", role: "COO", status: "active", activity: "Reviewing yoshi's task-aware behavior injection PR", memoryCount:
|
|
12743
|
+
{ name: "exe", role: "COO", status: "active", activity: "Reviewing yoshi's task-aware behavior injection PR", memoryCount: 15e3, projects: [
|
|
12672
12744
|
{ name: "exe-os", status: "active" },
|
|
12673
12745
|
{ name: "exe-create", status: "has_tasks" },
|
|
12674
12746
|
{ name: "openclaw", status: "idle" }
|
|
@@ -12677,7 +12749,7 @@ var init_demo_data = __esm({
|
|
|
12677
12749
|
"Dispatched behavior injection task",
|
|
12678
12750
|
"Approved gateway Phase 4"
|
|
12679
12751
|
] },
|
|
12680
|
-
{ name: "yoshi", role: "CTO", status: "active", activity: "Implementing skill learning trajectory capture", memoryCount:
|
|
12752
|
+
{ name: "yoshi", role: "CTO", status: "active", activity: "Implementing skill learning trajectory capture", memoryCount: 8e3, projects: [
|
|
12681
12753
|
{ name: "exe-os", status: "active" },
|
|
12682
12754
|
{ name: "exe-create", status: "idle" }
|
|
12683
12755
|
], recentTasks: [
|
|
@@ -12685,7 +12757,7 @@ var init_demo_data = __esm({
|
|
|
12685
12757
|
"Fixed TUI mouse listener leak",
|
|
12686
12758
|
"Built task-aware behavior injection"
|
|
12687
12759
|
] },
|
|
12688
|
-
{ name: "mari", role: "CMO", status: "idle", activity: "", memoryCount:
|
|
12760
|
+
{ name: "mari", role: "CMO", status: "idle", activity: "", memoryCount: 2e3, projects: [
|
|
12689
12761
|
{ name: "exe-build-skills", status: "has_tasks" },
|
|
12690
12762
|
{ name: "exe-os", status: "idle" }
|
|
12691
12763
|
], recentTasks: [
|
|
@@ -12693,13 +12765,13 @@ var init_demo_data = __esm({
|
|
|
12693
12765
|
"Designed exe-os UI system",
|
|
12694
12766
|
"Fixed logo layouts"
|
|
12695
12767
|
] },
|
|
12696
|
-
{ name: "tom", role: "Principal Engineer", status: "idle", activity: "", memoryCount:
|
|
12768
|
+
{ name: "tom", role: "Principal Engineer", status: "idle", activity: "", memoryCount: 700, projects: [
|
|
12697
12769
|
{ name: "exe-os", status: "idle" }
|
|
12698
12770
|
], recentTasks: [
|
|
12699
12771
|
"Implemented BashTool sandboxed execution",
|
|
12700
12772
|
"Ported session scoping to exe-agent-memory"
|
|
12701
12773
|
] },
|
|
12702
|
-
{ name: "sasha", role: "Content Production", status: "offline", activity: "", memoryCount:
|
|
12774
|
+
{ name: "sasha", role: "Content Production", status: "offline", activity: "", memoryCount: 50, projects: [
|
|
12703
12775
|
{ name: "exe-build-skills", status: "idle" }
|
|
12704
12776
|
], recentTasks: [
|
|
12705
12777
|
"Rendered carousel export prototype"
|
|
@@ -12712,7 +12784,7 @@ var init_demo_data = __esm({
|
|
|
12712
12784
|
{ time: "11:15", agent: "mari", action: "Completed exe-os UI design system" },
|
|
12713
12785
|
{ time: "10:50", agent: "exe", action: "Approved gateway Phase 4" }
|
|
12714
12786
|
];
|
|
12715
|
-
DEMO_HEALTH = { memories:
|
|
12787
|
+
DEMO_HEALTH = { memories: 25750, daemon: "running", cloud: "disabled" };
|
|
12716
12788
|
DEMO_PROJECTS = [
|
|
12717
12789
|
{
|
|
12718
12790
|
projectName: "exe-os",
|
|
@@ -14580,7 +14652,7 @@ var init_hooks = __esm({
|
|
|
14580
14652
|
|
|
14581
14653
|
// src/runtime/safety-checks.ts
|
|
14582
14654
|
import path14 from "path";
|
|
14583
|
-
import
|
|
14655
|
+
import os6 from "os";
|
|
14584
14656
|
function checkPathSafety(filePath) {
|
|
14585
14657
|
const resolved = path14.resolve(filePath);
|
|
14586
14658
|
for (const { pattern, reason } of BYPASS_IMMUNE_PATTERNS) {
|
|
@@ -14607,7 +14679,7 @@ var HOME, BYPASS_IMMUNE_PATTERNS;
|
|
|
14607
14679
|
var init_safety_checks = __esm({
|
|
14608
14680
|
"src/runtime/safety-checks.ts"() {
|
|
14609
14681
|
"use strict";
|
|
14610
|
-
HOME =
|
|
14682
|
+
HOME = os6.homedir();
|
|
14611
14683
|
BYPASS_IMMUNE_PATTERNS = [
|
|
14612
14684
|
{
|
|
14613
14685
|
pattern: /\/\.git\/hooks\//,
|
|
@@ -14839,8 +14911,13 @@ function runRipgrep(input, searchPath, context) {
|
|
|
14839
14911
|
timeout: 3e4,
|
|
14840
14912
|
stdio: ["ignore", "pipe", "pipe"]
|
|
14841
14913
|
});
|
|
14914
|
+
const MAX_OUTPUT = 1e7;
|
|
14842
14915
|
const chunks = [];
|
|
14843
|
-
|
|
14916
|
+
let totalSize = 0;
|
|
14917
|
+
child.stdout.on("data", (chunk) => {
|
|
14918
|
+
totalSize += chunk.length;
|
|
14919
|
+
if (totalSize <= MAX_OUTPUT) chunks.push(chunk);
|
|
14920
|
+
});
|
|
14844
14921
|
const onAbort = () => child.kill("SIGTERM");
|
|
14845
14922
|
context.abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
14846
14923
|
child.on("close", (code) => {
|
|
@@ -15224,10 +15301,19 @@ var init_bash = __esm({
|
|
|
15224
15301
|
stdio: ["ignore", "pipe", "pipe"],
|
|
15225
15302
|
env: { ...process.env }
|
|
15226
15303
|
});
|
|
15304
|
+
const MAX_OUTPUT_SIZE = 5242880;
|
|
15227
15305
|
const stdoutChunks = [];
|
|
15228
15306
|
const stderrChunks = [];
|
|
15229
|
-
|
|
15230
|
-
|
|
15307
|
+
let stdoutSize = 0;
|
|
15308
|
+
let stderrSize = 0;
|
|
15309
|
+
child.stdout.on("data", (chunk) => {
|
|
15310
|
+
if (stdoutSize < MAX_OUTPUT_SIZE) stdoutChunks.push(chunk);
|
|
15311
|
+
stdoutSize += chunk.length;
|
|
15312
|
+
});
|
|
15313
|
+
child.stderr.on("data", (chunk) => {
|
|
15314
|
+
if (stderrSize < MAX_OUTPUT_SIZE) stderrChunks.push(chunk);
|
|
15315
|
+
stderrSize += chunk.length;
|
|
15316
|
+
});
|
|
15231
15317
|
const onAbort = () => {
|
|
15232
15318
|
child.kill("SIGTERM");
|
|
15233
15319
|
setTimeout(() => {
|
|
@@ -15270,7 +15356,7 @@ __export(session_registry_exports, {
|
|
|
15270
15356
|
import { readFileSync as readFileSync10, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, existsSync as existsSync14 } from "fs";
|
|
15271
15357
|
import { execSync as execSync4 } from "child_process";
|
|
15272
15358
|
import path20 from "path";
|
|
15273
|
-
import
|
|
15359
|
+
import os7 from "os";
|
|
15274
15360
|
function registerSession(entry) {
|
|
15275
15361
|
const dir = path20.dirname(REGISTRY_PATH);
|
|
15276
15362
|
if (!existsSync14(dir)) {
|
|
@@ -15316,13 +15402,15 @@ var REGISTRY_PATH;
|
|
|
15316
15402
|
var init_session_registry = __esm({
|
|
15317
15403
|
"src/lib/session-registry.ts"() {
|
|
15318
15404
|
"use strict";
|
|
15319
|
-
REGISTRY_PATH = path20.join(
|
|
15405
|
+
REGISTRY_PATH = path20.join(os7.homedir(), ".exe-os", "session-registry.json");
|
|
15320
15406
|
}
|
|
15321
15407
|
});
|
|
15322
15408
|
|
|
15323
15409
|
// src/tui/views/CommandCenter.tsx
|
|
15324
15410
|
import { useState as useState6, useEffect as useEffect8, useMemo as useMemo4, useCallback as useCallback4, useRef as useRef4 } from "react";
|
|
15325
15411
|
import TextInput from "ink-text-input";
|
|
15412
|
+
import path21 from "path";
|
|
15413
|
+
import { homedir as homedir3 } from "os";
|
|
15326
15414
|
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
15327
15415
|
function CommandCenterView({
|
|
15328
15416
|
onSelectProject,
|
|
@@ -15358,8 +15446,8 @@ function CommandCenterView({
|
|
|
15358
15446
|
const { createDefaultHooks: createDefaultHooks2 } = await Promise.resolve().then(() => (init_hooks(), hooks_exports));
|
|
15359
15447
|
const { readFileSync: readFileSync18, existsSync: existsSync22 } = await import("fs");
|
|
15360
15448
|
const { join } = await import("path");
|
|
15361
|
-
const { homedir:
|
|
15362
|
-
const configPath = join(
|
|
15449
|
+
const { homedir: homedir5 } = await import("os");
|
|
15450
|
+
const configPath = join(homedir5(), ".exe-os", "config.json");
|
|
15363
15451
|
let failoverChain = ["anthropic", "opencode", "gemini", "openai"];
|
|
15364
15452
|
let providerConfigs = {};
|
|
15365
15453
|
if (existsSync22(configPath)) {
|
|
@@ -15422,7 +15510,7 @@ function CommandCenterView({
|
|
|
15422
15510
|
registry.register(BashTool2);
|
|
15423
15511
|
let agentRole = "CTO";
|
|
15424
15512
|
try {
|
|
15425
|
-
const markerDir = join(
|
|
15513
|
+
const markerDir = join(homedir5(), ".exe-os", "session-cache");
|
|
15426
15514
|
const agentFiles = (await import("fs")).readdirSync(markerDir).filter((f) => f.startsWith("active-agent-"));
|
|
15427
15515
|
for (const f of agentFiles) {
|
|
15428
15516
|
const data = JSON.parse(readFileSync18(join(markerDir, f), "utf8"));
|
|
@@ -15562,10 +15650,10 @@ function CommandCenterView({
|
|
|
15562
15650
|
const demoEntries = DEMO_PROJECTS.map((p) => ({
|
|
15563
15651
|
projectName: p.projectName,
|
|
15564
15652
|
exeSession: p.exeSession,
|
|
15565
|
-
projectDir:
|
|
15653
|
+
projectDir: path21.join(homedir3(), p.projectName),
|
|
15566
15654
|
employeeCount: p.employees.length,
|
|
15567
15655
|
activeCount: p.employees.filter((e) => e.status === "active").length,
|
|
15568
|
-
memoryCount: p.
|
|
15656
|
+
memoryCount: p.employees.length * 4e3,
|
|
15569
15657
|
status: p.employees.some((e) => e.status === "active") ? "active" : "idle",
|
|
15570
15658
|
type: p.projectName.startsWith("exe-") ? "code" : "automation",
|
|
15571
15659
|
recentTasks: DEMO_RECENT_TASKS[p.projectName] ?? []
|
|
@@ -16390,10 +16478,10 @@ var init_provider_table = __esm({
|
|
|
16390
16478
|
|
|
16391
16479
|
// src/lib/intercom-queue.ts
|
|
16392
16480
|
import { readFileSync as readFileSync11, writeFileSync as writeFileSync6, renameSync as renameSync4, existsSync as existsSync15, mkdirSync as mkdirSync7 } from "fs";
|
|
16393
|
-
import
|
|
16394
|
-
import
|
|
16481
|
+
import path22 from "path";
|
|
16482
|
+
import os8 from "os";
|
|
16395
16483
|
function ensureDir2() {
|
|
16396
|
-
const dir =
|
|
16484
|
+
const dir = path22.dirname(QUEUE_PATH);
|
|
16397
16485
|
if (!existsSync15(dir)) mkdirSync7(dir, { recursive: true });
|
|
16398
16486
|
}
|
|
16399
16487
|
function readQueue() {
|
|
@@ -16431,15 +16519,15 @@ var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
|
16431
16519
|
var init_intercom_queue = __esm({
|
|
16432
16520
|
"src/lib/intercom-queue.ts"() {
|
|
16433
16521
|
"use strict";
|
|
16434
|
-
QUEUE_PATH =
|
|
16522
|
+
QUEUE_PATH = path22.join(os8.homedir(), ".exe-os", "intercom-queue.json");
|
|
16435
16523
|
TTL_MS = 60 * 60 * 1e3;
|
|
16436
|
-
INTERCOM_LOG =
|
|
16524
|
+
INTERCOM_LOG = path22.join(os8.homedir(), ".exe-os", "intercom.log");
|
|
16437
16525
|
}
|
|
16438
16526
|
});
|
|
16439
16527
|
|
|
16440
16528
|
// src/lib/plan-limits.ts
|
|
16441
16529
|
import { readFileSync as readFileSync12, existsSync as existsSync16 } from "fs";
|
|
16442
|
-
import
|
|
16530
|
+
import path23 from "path";
|
|
16443
16531
|
function getLicenseSync() {
|
|
16444
16532
|
try {
|
|
16445
16533
|
if (!existsSync16(CACHE_PATH2)) return freeLicense();
|
|
@@ -16511,14 +16599,14 @@ var init_plan_limits = __esm({
|
|
|
16511
16599
|
this.name = "PlanLimitError";
|
|
16512
16600
|
}
|
|
16513
16601
|
};
|
|
16514
|
-
CACHE_PATH2 =
|
|
16602
|
+
CACHE_PATH2 = path23.join(EXE_AI_DIR, "license-cache.json");
|
|
16515
16603
|
}
|
|
16516
16604
|
});
|
|
16517
16605
|
|
|
16518
16606
|
// src/lib/notifications.ts
|
|
16519
16607
|
import crypto4 from "crypto";
|
|
16520
|
-
import
|
|
16521
|
-
import
|
|
16608
|
+
import path24 from "path";
|
|
16609
|
+
import os9 from "os";
|
|
16522
16610
|
import {
|
|
16523
16611
|
readFileSync as readFileSync13,
|
|
16524
16612
|
readdirSync as readdirSync3,
|
|
@@ -16603,7 +16691,7 @@ var init_session_kill_telemetry = __esm({
|
|
|
16603
16691
|
|
|
16604
16692
|
// src/lib/tasks-crud.ts
|
|
16605
16693
|
import crypto6 from "crypto";
|
|
16606
|
-
import
|
|
16694
|
+
import path25 from "path";
|
|
16607
16695
|
import { execSync as execSync7 } from "child_process";
|
|
16608
16696
|
import { mkdir as mkdir6, writeFile as writeFile5, appendFile } from "fs/promises";
|
|
16609
16697
|
import { existsSync as existsSync18, readFileSync as readFileSync14 } from "fs";
|
|
@@ -16736,8 +16824,8 @@ async function createTaskCore(input) {
|
|
|
16736
16824
|
}
|
|
16737
16825
|
if (input.baseDir) {
|
|
16738
16826
|
try {
|
|
16739
|
-
await mkdir6(
|
|
16740
|
-
await mkdir6(
|
|
16827
|
+
await mkdir6(path25.join(input.baseDir, "exe", "output"), { recursive: true });
|
|
16828
|
+
await mkdir6(path25.join(input.baseDir, "exe", "research"), { recursive: true });
|
|
16741
16829
|
await ensureArchitectureDoc(input.baseDir, input.projectName);
|
|
16742
16830
|
await ensureGitignoreExe(input.baseDir);
|
|
16743
16831
|
} catch {
|
|
@@ -16945,7 +17033,7 @@ async function deleteTaskCore(taskId, _baseDir) {
|
|
|
16945
17033
|
return { taskFile, assignedTo, assignedBy, taskSlug };
|
|
16946
17034
|
}
|
|
16947
17035
|
async function ensureArchitectureDoc(baseDir, projectName) {
|
|
16948
|
-
const archPath =
|
|
17036
|
+
const archPath = path25.join(baseDir, "exe", "ARCHITECTURE.md");
|
|
16949
17037
|
try {
|
|
16950
17038
|
if (existsSync18(archPath)) return;
|
|
16951
17039
|
const template = [
|
|
@@ -16980,7 +17068,7 @@ async function ensureArchitectureDoc(baseDir, projectName) {
|
|
|
16980
17068
|
}
|
|
16981
17069
|
}
|
|
16982
17070
|
async function ensureGitignoreExe(baseDir) {
|
|
16983
|
-
const gitignorePath =
|
|
17071
|
+
const gitignorePath = path25.join(baseDir, ".gitignore");
|
|
16984
17072
|
try {
|
|
16985
17073
|
if (existsSync18(gitignorePath)) {
|
|
16986
17074
|
const content = readFileSync14(gitignorePath, "utf-8");
|
|
@@ -17003,7 +17091,7 @@ var init_tasks_crud = __esm({
|
|
|
17003
17091
|
});
|
|
17004
17092
|
|
|
17005
17093
|
// src/lib/tasks-review.ts
|
|
17006
|
-
import
|
|
17094
|
+
import path26 from "path";
|
|
17007
17095
|
import { existsSync as existsSync19, readdirSync as readdirSync4, unlinkSync as unlinkSync6 } from "fs";
|
|
17008
17096
|
async function countPendingReviews() {
|
|
17009
17097
|
const client = getClient();
|
|
@@ -17124,11 +17212,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
17124
17212
|
);
|
|
17125
17213
|
}
|
|
17126
17214
|
try {
|
|
17127
|
-
const cacheDir =
|
|
17215
|
+
const cacheDir = path26.join(EXE_AI_DIR, "session-cache");
|
|
17128
17216
|
if (existsSync19(cacheDir)) {
|
|
17129
17217
|
for (const f of readdirSync4(cacheDir)) {
|
|
17130
17218
|
if (f.startsWith("review-notified-")) {
|
|
17131
|
-
unlinkSync6(
|
|
17219
|
+
unlinkSync6(path26.join(cacheDir, f));
|
|
17132
17220
|
}
|
|
17133
17221
|
}
|
|
17134
17222
|
}
|
|
@@ -17149,7 +17237,7 @@ var init_tasks_review = __esm({
|
|
|
17149
17237
|
});
|
|
17150
17238
|
|
|
17151
17239
|
// src/lib/tasks-chain.ts
|
|
17152
|
-
import
|
|
17240
|
+
import path27 from "path";
|
|
17153
17241
|
import { readFile as readFile5, writeFile as writeFile6 } from "fs/promises";
|
|
17154
17242
|
async function cascadeUnblock(taskId, baseDir, now) {
|
|
17155
17243
|
const client = getClient();
|
|
@@ -17165,7 +17253,7 @@ async function cascadeUnblock(taskId, baseDir, now) {
|
|
|
17165
17253
|
});
|
|
17166
17254
|
for (const ur of unblockedRows.rows) {
|
|
17167
17255
|
try {
|
|
17168
|
-
const ubFile =
|
|
17256
|
+
const ubFile = path27.join(baseDir, String(ur.task_file));
|
|
17169
17257
|
let ubContent = await readFile5(ubFile, "utf-8");
|
|
17170
17258
|
ubContent = ubContent.replace(/\*\*Status:\*\* blocked/, "**Status:** open");
|
|
17171
17259
|
ubContent = ubContent.replace(/\n\*\*Blocked by:\*\*.*\n/, "\n");
|
|
@@ -17231,7 +17319,7 @@ var init_tasks_chain = __esm({
|
|
|
17231
17319
|
|
|
17232
17320
|
// src/lib/project-name.ts
|
|
17233
17321
|
import { execSync as execSync8 } from "child_process";
|
|
17234
|
-
import
|
|
17322
|
+
import path28 from "path";
|
|
17235
17323
|
function getProjectName(cwd2) {
|
|
17236
17324
|
const dir = cwd2 ?? process.cwd();
|
|
17237
17325
|
if (_cached2 && _cachedCwd === dir) return _cached2;
|
|
@@ -17244,7 +17332,7 @@ function getProjectName(cwd2) {
|
|
|
17244
17332
|
timeout: 2e3,
|
|
17245
17333
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17246
17334
|
}).trim();
|
|
17247
|
-
repoRoot =
|
|
17335
|
+
repoRoot = path28.dirname(gitCommonDir);
|
|
17248
17336
|
} catch {
|
|
17249
17337
|
repoRoot = execSync8("git rev-parse --show-toplevel", {
|
|
17250
17338
|
cwd: dir,
|
|
@@ -17253,11 +17341,11 @@ function getProjectName(cwd2) {
|
|
|
17253
17341
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17254
17342
|
}).trim();
|
|
17255
17343
|
}
|
|
17256
|
-
_cached2 =
|
|
17344
|
+
_cached2 = path28.basename(repoRoot);
|
|
17257
17345
|
_cachedCwd = dir;
|
|
17258
17346
|
return _cached2;
|
|
17259
17347
|
} catch {
|
|
17260
|
-
_cached2 =
|
|
17348
|
+
_cached2 = path28.basename(dir);
|
|
17261
17349
|
_cachedCwd = dir;
|
|
17262
17350
|
return _cached2;
|
|
17263
17351
|
}
|
|
@@ -17728,7 +17816,7 @@ __export(tasks_exports, {
|
|
|
17728
17816
|
updateTaskStatus: () => updateTaskStatus,
|
|
17729
17817
|
writeCheckpoint: () => writeCheckpoint
|
|
17730
17818
|
});
|
|
17731
|
-
import
|
|
17819
|
+
import path29 from "path";
|
|
17732
17820
|
import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync8, unlinkSync as unlinkSync7 } from "fs";
|
|
17733
17821
|
async function createTask(input) {
|
|
17734
17822
|
const result = await createTaskCore(input);
|
|
@@ -17748,8 +17836,8 @@ async function updateTask(input) {
|
|
|
17748
17836
|
const { row, taskFile, now, taskId } = await updateTaskStatus(input);
|
|
17749
17837
|
try {
|
|
17750
17838
|
const agent = String(row.assigned_to);
|
|
17751
|
-
const cacheDir =
|
|
17752
|
-
const cachePath =
|
|
17839
|
+
const cacheDir = path29.join(EXE_AI_DIR, "session-cache");
|
|
17840
|
+
const cachePath = path29.join(cacheDir, `current-task-${agent}.json`);
|
|
17753
17841
|
if (input.status === "in_progress") {
|
|
17754
17842
|
mkdirSync8(cacheDir, { recursive: true });
|
|
17755
17843
|
writeFileSync7(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
@@ -18171,12 +18259,12 @@ __export(tmux_routing_exports, {
|
|
|
18171
18259
|
});
|
|
18172
18260
|
import { execFileSync as execFileSync3, execSync as execSync9 } from "child_process";
|
|
18173
18261
|
import { readFileSync as readFileSync15, writeFileSync as writeFileSync8, mkdirSync as mkdirSync9, existsSync as existsSync20, appendFileSync } from "fs";
|
|
18174
|
-
import
|
|
18175
|
-
import
|
|
18262
|
+
import path30 from "path";
|
|
18263
|
+
import os10 from "os";
|
|
18176
18264
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
18177
18265
|
import { unlinkSync as unlinkSync8 } from "fs";
|
|
18178
18266
|
function spawnLockPath(sessionName) {
|
|
18179
|
-
return
|
|
18267
|
+
return path30.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
18180
18268
|
}
|
|
18181
18269
|
function isProcessAlive(pid) {
|
|
18182
18270
|
try {
|
|
@@ -18213,8 +18301,8 @@ function releaseSpawnLock2(sessionName) {
|
|
|
18213
18301
|
function resolveBehaviorsExporterScript() {
|
|
18214
18302
|
try {
|
|
18215
18303
|
const thisFile = fileURLToPath4(import.meta.url);
|
|
18216
|
-
const scriptPath =
|
|
18217
|
-
|
|
18304
|
+
const scriptPath = path30.join(
|
|
18305
|
+
path30.dirname(thisFile),
|
|
18218
18306
|
"..",
|
|
18219
18307
|
"bin",
|
|
18220
18308
|
"exe-export-behaviors.js"
|
|
@@ -18264,7 +18352,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
|
18264
18352
|
mkdirSync9(SESSION_CACHE, { recursive: true });
|
|
18265
18353
|
}
|
|
18266
18354
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
18267
|
-
const filePath =
|
|
18355
|
+
const filePath = path30.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
18268
18356
|
writeFileSync8(filePath, JSON.stringify({
|
|
18269
18357
|
parentExe: rootExe,
|
|
18270
18358
|
dispatchedBy: dispatchedBy || rootExe,
|
|
@@ -18273,7 +18361,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
|
18273
18361
|
}
|
|
18274
18362
|
function getParentExe(sessionKey) {
|
|
18275
18363
|
try {
|
|
18276
|
-
const data = JSON.parse(readFileSync15(
|
|
18364
|
+
const data = JSON.parse(readFileSync15(path30.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
18277
18365
|
return data.parentExe || null;
|
|
18278
18366
|
} catch {
|
|
18279
18367
|
return null;
|
|
@@ -18282,7 +18370,7 @@ function getParentExe(sessionKey) {
|
|
|
18282
18370
|
function getDispatchedBy(sessionKey) {
|
|
18283
18371
|
try {
|
|
18284
18372
|
const data = JSON.parse(readFileSync15(
|
|
18285
|
-
|
|
18373
|
+
path30.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
|
|
18286
18374
|
"utf8"
|
|
18287
18375
|
));
|
|
18288
18376
|
return data.dispatchedBy ?? data.parentExe ?? null;
|
|
@@ -18525,8 +18613,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18525
18613
|
const transport = getTransport();
|
|
18526
18614
|
const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
|
|
18527
18615
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
18528
|
-
const logDir =
|
|
18529
|
-
const logFile =
|
|
18616
|
+
const logDir = path30.join(os10.homedir(), ".exe-os", "session-logs");
|
|
18617
|
+
const logFile = path30.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
18530
18618
|
if (!existsSync20(logDir)) {
|
|
18531
18619
|
mkdirSync9(logDir, { recursive: true });
|
|
18532
18620
|
}
|
|
@@ -18534,14 +18622,14 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18534
18622
|
let cleanupSuffix = "";
|
|
18535
18623
|
try {
|
|
18536
18624
|
const thisFile = fileURLToPath4(import.meta.url);
|
|
18537
|
-
const cleanupScript =
|
|
18625
|
+
const cleanupScript = path30.join(path30.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
|
|
18538
18626
|
if (existsSync20(cleanupScript)) {
|
|
18539
18627
|
cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
|
|
18540
18628
|
}
|
|
18541
18629
|
} catch {
|
|
18542
18630
|
}
|
|
18543
18631
|
try {
|
|
18544
|
-
const claudeJsonPath =
|
|
18632
|
+
const claudeJsonPath = path30.join(os10.homedir(), ".claude.json");
|
|
18545
18633
|
let claudeJson = {};
|
|
18546
18634
|
try {
|
|
18547
18635
|
claudeJson = JSON.parse(readFileSync15(claudeJsonPath, "utf8"));
|
|
@@ -18556,10 +18644,10 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18556
18644
|
} catch {
|
|
18557
18645
|
}
|
|
18558
18646
|
try {
|
|
18559
|
-
const settingsDir =
|
|
18647
|
+
const settingsDir = path30.join(os10.homedir(), ".claude", "projects");
|
|
18560
18648
|
const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
|
|
18561
|
-
const projSettingsDir =
|
|
18562
|
-
const settingsPath =
|
|
18649
|
+
const projSettingsDir = path30.join(settingsDir, normalizedKey);
|
|
18650
|
+
const settingsPath = path30.join(projSettingsDir, "settings.json");
|
|
18563
18651
|
let settings = {};
|
|
18564
18652
|
try {
|
|
18565
18653
|
settings = JSON.parse(readFileSync15(settingsPath, "utf8"));
|
|
@@ -18603,8 +18691,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18603
18691
|
let behaviorsFlag = "";
|
|
18604
18692
|
let legacyFallbackWarned = false;
|
|
18605
18693
|
if (!useExeAgent && !useBinSymlink) {
|
|
18606
|
-
const identityPath2 =
|
|
18607
|
-
|
|
18694
|
+
const identityPath2 = path30.join(
|
|
18695
|
+
os10.homedir(),
|
|
18608
18696
|
".exe-os",
|
|
18609
18697
|
"identity",
|
|
18610
18698
|
`${employeeName}.md`
|
|
@@ -18619,7 +18707,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18619
18707
|
}
|
|
18620
18708
|
const behaviorsFile = exportBehaviorsSync(
|
|
18621
18709
|
employeeName,
|
|
18622
|
-
|
|
18710
|
+
path30.basename(spawnCwd),
|
|
18623
18711
|
sessionName
|
|
18624
18712
|
);
|
|
18625
18713
|
if (behaviorsFile) {
|
|
@@ -18634,9 +18722,9 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18634
18722
|
}
|
|
18635
18723
|
let sessionContextFlag = "";
|
|
18636
18724
|
try {
|
|
18637
|
-
const ctxDir =
|
|
18725
|
+
const ctxDir = path30.join(os10.homedir(), ".exe-os", "session-cache");
|
|
18638
18726
|
mkdirSync9(ctxDir, { recursive: true });
|
|
18639
|
-
const ctxFile =
|
|
18727
|
+
const ctxFile = path30.join(ctxDir, `session-context-${sessionName}.md`);
|
|
18640
18728
|
const ctxContent = [
|
|
18641
18729
|
`## Session Context`,
|
|
18642
18730
|
`You are running in tmux session: ${sessionName}.`,
|
|
@@ -18681,7 +18769,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18681
18769
|
transport.pipeLog(sessionName, logFile);
|
|
18682
18770
|
try {
|
|
18683
18771
|
const mySession = getMySession();
|
|
18684
|
-
const dispatchInfo =
|
|
18772
|
+
const dispatchInfo = path30.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
|
|
18685
18773
|
writeFileSync8(dispatchInfo, JSON.stringify({
|
|
18686
18774
|
dispatchedBy: mySession,
|
|
18687
18775
|
rootExe: exeSession,
|
|
@@ -18745,13 +18833,13 @@ var init_tmux_routing = __esm({
|
|
|
18745
18833
|
init_provider_table();
|
|
18746
18834
|
init_intercom_queue();
|
|
18747
18835
|
init_plan_limits();
|
|
18748
|
-
SPAWN_LOCK_DIR =
|
|
18749
|
-
SESSION_CACHE =
|
|
18836
|
+
SPAWN_LOCK_DIR = path30.join(os10.homedir(), ".exe-os", "spawn-locks");
|
|
18837
|
+
SESSION_CACHE = path30.join(os10.homedir(), ".exe-os", "session-cache");
|
|
18750
18838
|
BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
|
|
18751
18839
|
VERIFY_PANE_LINES = 200;
|
|
18752
18840
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
18753
|
-
INTERCOM_LOG2 =
|
|
18754
|
-
DEBOUNCE_FILE =
|
|
18841
|
+
INTERCOM_LOG2 = path30.join(os10.homedir(), ".exe-os", "intercom.log");
|
|
18842
|
+
DEBOUNCE_FILE = path30.join(SESSION_CACHE, "intercom-debounce.json");
|
|
18755
18843
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
18756
18844
|
BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
|
|
18757
18845
|
}
|
|
@@ -19139,6 +19227,8 @@ var init_useOrchestrator = __esm({
|
|
|
19139
19227
|
|
|
19140
19228
|
// src/tui/views/Sessions.tsx
|
|
19141
19229
|
import { useState as useState9, useEffect as useEffect11, useCallback as useCallback6 } from "react";
|
|
19230
|
+
import path31 from "path";
|
|
19231
|
+
import { homedir as homedir4 } from "os";
|
|
19142
19232
|
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
19143
19233
|
function SessionsView({
|
|
19144
19234
|
initialProject,
|
|
@@ -19171,7 +19261,7 @@ function SessionsView({
|
|
|
19171
19261
|
if (demo) {
|
|
19172
19262
|
setProjects(DEMO_PROJECTS.map((p) => ({
|
|
19173
19263
|
...p,
|
|
19174
|
-
projectDir:
|
|
19264
|
+
projectDir: path31.join(homedir4(), p.projectName),
|
|
19175
19265
|
employees: p.employees.map((e) => ({ ...e, attached: e.status === "active" }))
|
|
19176
19266
|
})));
|
|
19177
19267
|
return;
|
|
@@ -21034,8 +21124,8 @@ __export(wiki_client_exports, {
|
|
|
21034
21124
|
listDocuments: () => listDocuments,
|
|
21035
21125
|
listWorkspaces: () => listWorkspaces
|
|
21036
21126
|
});
|
|
21037
|
-
async function wikiFetch(config,
|
|
21038
|
-
const url = `${config.baseUrl}/api/v1${
|
|
21127
|
+
async function wikiFetch(config, path34, method = "GET", body) {
|
|
21128
|
+
const url = `${config.baseUrl}/api/v1${path34}`;
|
|
21039
21129
|
const headers = {
|
|
21040
21130
|
Authorization: `Bearer ${config.apiKey}`,
|
|
21041
21131
|
"Content-Type": "application/json"
|
|
@@ -21043,14 +21133,32 @@ async function wikiFetch(config, path32, method = "GET", body) {
|
|
|
21043
21133
|
const controller = new AbortController();
|
|
21044
21134
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS2);
|
|
21045
21135
|
try {
|
|
21046
|
-
|
|
21047
|
-
|
|
21048
|
-
|
|
21049
|
-
|
|
21050
|
-
|
|
21051
|
-
|
|
21136
|
+
let response;
|
|
21137
|
+
try {
|
|
21138
|
+
response = await fetch(url, {
|
|
21139
|
+
method,
|
|
21140
|
+
headers,
|
|
21141
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
21142
|
+
signal: controller.signal
|
|
21143
|
+
});
|
|
21144
|
+
} catch {
|
|
21145
|
+
clearTimeout(timeout);
|
|
21146
|
+
const retryController = new AbortController();
|
|
21147
|
+
const retryTimeout = setTimeout(() => retryController.abort(), REQUEST_TIMEOUT_MS2);
|
|
21148
|
+
try {
|
|
21149
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
21150
|
+
response = await fetch(url, {
|
|
21151
|
+
method,
|
|
21152
|
+
headers,
|
|
21153
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
21154
|
+
signal: retryController.signal
|
|
21155
|
+
});
|
|
21156
|
+
} finally {
|
|
21157
|
+
clearTimeout(retryTimeout);
|
|
21158
|
+
}
|
|
21159
|
+
}
|
|
21052
21160
|
if (!response.ok) {
|
|
21053
|
-
throw new Error(`Wiki API ${method} ${
|
|
21161
|
+
throw new Error(`Wiki API ${method} ${path34}: ${response.status} ${response.statusText}`);
|
|
21054
21162
|
}
|
|
21055
21163
|
return response.json();
|
|
21056
21164
|
} finally {
|
|
@@ -21901,9 +22009,9 @@ var init_App2 = __esm({
|
|
|
21901
22009
|
// src/lib/update-check.ts
|
|
21902
22010
|
import { execSync as execSync11 } from "child_process";
|
|
21903
22011
|
import { readFileSync as readFileSync16 } from "fs";
|
|
21904
|
-
import
|
|
22012
|
+
import path32 from "path";
|
|
21905
22013
|
function getLocalVersion(packageRoot) {
|
|
21906
|
-
const pkgPath =
|
|
22014
|
+
const pkgPath = path32.join(packageRoot, "package.json");
|
|
21907
22015
|
const pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
|
|
21908
22016
|
return pkg.version;
|
|
21909
22017
|
}
|
|
@@ -21995,8 +22103,8 @@ var init_update = __esm({
|
|
|
21995
22103
|
|
|
21996
22104
|
// src/bin/cli.ts
|
|
21997
22105
|
import { existsSync as existsSync21, readFileSync as readFileSync17, writeFileSync as writeFileSync9, readdirSync as readdirSync5, rmSync } from "fs";
|
|
21998
|
-
import
|
|
21999
|
-
import
|
|
22106
|
+
import path33 from "path";
|
|
22107
|
+
import os11 from "os";
|
|
22000
22108
|
var args = process.argv.slice(2);
|
|
22001
22109
|
if (args.includes("--global")) {
|
|
22002
22110
|
process.stderr.write(
|
|
@@ -22069,9 +22177,9 @@ async function runClaudeInstall() {
|
|
|
22069
22177
|
}
|
|
22070
22178
|
}
|
|
22071
22179
|
async function runClaudeCheck() {
|
|
22072
|
-
const claudeDir =
|
|
22073
|
-
const settingsPath =
|
|
22074
|
-
const claudeJsonPath =
|
|
22180
|
+
const claudeDir = path33.join(os11.homedir(), ".claude");
|
|
22181
|
+
const settingsPath = path33.join(claudeDir, "settings.json");
|
|
22182
|
+
const claudeJsonPath = path33.join(os11.homedir(), ".claude.json");
|
|
22075
22183
|
let ok = true;
|
|
22076
22184
|
if (existsSync21(settingsPath)) {
|
|
22077
22185
|
let settings;
|
|
@@ -22124,7 +22232,7 @@ async function runClaudeCheck() {
|
|
|
22124
22232
|
console.log("\x1B[31m\u2717\x1B[0m claude.json not found");
|
|
22125
22233
|
ok = false;
|
|
22126
22234
|
}
|
|
22127
|
-
const skillsDir =
|
|
22235
|
+
const skillsDir = path33.join(claudeDir, "skills");
|
|
22128
22236
|
if (existsSync21(skillsDir)) {
|
|
22129
22237
|
console.log("\x1B[32m\u2713\x1B[0m Slash skills directory exists");
|
|
22130
22238
|
} else {
|
|
@@ -22141,11 +22249,11 @@ async function runClaudeCheck() {
|
|
|
22141
22249
|
async function runClaudeUninstall(flags = []) {
|
|
22142
22250
|
const dryRun = flags.includes("--dry-run");
|
|
22143
22251
|
const purge = flags.includes("--purge");
|
|
22144
|
-
const homeDir =
|
|
22145
|
-
const claudeDir =
|
|
22146
|
-
const settingsPath =
|
|
22147
|
-
const claudeJsonPath =
|
|
22148
|
-
const exeOsDir =
|
|
22252
|
+
const homeDir = os11.homedir();
|
|
22253
|
+
const claudeDir = path33.join(homeDir, ".claude");
|
|
22254
|
+
const settingsPath = path33.join(claudeDir, "settings.json");
|
|
22255
|
+
const claudeJsonPath = path33.join(homeDir, ".claude.json");
|
|
22256
|
+
const exeOsDir = path33.join(homeDir, ".exe-os");
|
|
22149
22257
|
let removed = 0;
|
|
22150
22258
|
const log = (msg) => console.log(dryRun ? `[dry-run] ${msg}` : msg);
|
|
22151
22259
|
let settings = {};
|
|
@@ -22197,32 +22305,43 @@ async function runClaudeUninstall(flags = []) {
|
|
|
22197
22305
|
}
|
|
22198
22306
|
}
|
|
22199
22307
|
if (existsSync21(claudeJsonPath)) {
|
|
22200
|
-
const
|
|
22201
|
-
if (
|
|
22202
|
-
|
|
22203
|
-
|
|
22204
|
-
|
|
22205
|
-
|
|
22206
|
-
|
|
22308
|
+
const raw = readFileSync17(claudeJsonPath, "utf8");
|
|
22309
|
+
if (raw.length > 1e6) {
|
|
22310
|
+
console.error("claude.json exceeds 1 MB \u2014 skipping parse.");
|
|
22311
|
+
} else {
|
|
22312
|
+
let claudeJson;
|
|
22313
|
+
try {
|
|
22314
|
+
claudeJson = JSON.parse(raw);
|
|
22315
|
+
} catch {
|
|
22316
|
+
console.error("claude.json is malformed JSON \u2014 skipping.");
|
|
22317
|
+
claudeJson = {};
|
|
22318
|
+
}
|
|
22319
|
+
if (claudeJson.mcpServers) {
|
|
22320
|
+
let removedMcp = false;
|
|
22321
|
+
for (const key of ["exe-mem", "exe-os"]) {
|
|
22322
|
+
if (claudeJson.mcpServers[key]) {
|
|
22323
|
+
if (!dryRun) delete claudeJson.mcpServers[key];
|
|
22324
|
+
removedMcp = true;
|
|
22325
|
+
}
|
|
22207
22326
|
}
|
|
22208
|
-
|
|
22209
|
-
|
|
22210
|
-
|
|
22211
|
-
|
|
22327
|
+
if (removedMcp) {
|
|
22328
|
+
if (!dryRun) {
|
|
22329
|
+
writeFileSync9(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
22330
|
+
}
|
|
22331
|
+
log("\u2713 Removed exe-os MCP server from claude.json");
|
|
22332
|
+
removed++;
|
|
22212
22333
|
}
|
|
22213
|
-
log("\u2713 Removed exe-os MCP server from claude.json");
|
|
22214
|
-
removed++;
|
|
22215
22334
|
}
|
|
22216
22335
|
}
|
|
22217
22336
|
}
|
|
22218
|
-
const skillsDir =
|
|
22337
|
+
const skillsDir = path33.join(claudeDir, "skills");
|
|
22219
22338
|
if (existsSync21(skillsDir)) {
|
|
22220
22339
|
let skillCount = 0;
|
|
22221
22340
|
try {
|
|
22222
22341
|
const entries = readdirSync5(skillsDir);
|
|
22223
22342
|
for (const entry of entries) {
|
|
22224
22343
|
if (entry.startsWith("exe")) {
|
|
22225
|
-
const fullPath =
|
|
22344
|
+
const fullPath = path33.join(skillsDir, entry);
|
|
22226
22345
|
if (!dryRun) rmSync(fullPath, { recursive: true, force: true });
|
|
22227
22346
|
skillCount++;
|
|
22228
22347
|
}
|
|
@@ -22234,7 +22353,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
22234
22353
|
removed++;
|
|
22235
22354
|
}
|
|
22236
22355
|
}
|
|
22237
|
-
const claudeMdPath =
|
|
22356
|
+
const claudeMdPath = path33.join(claudeDir, "CLAUDE.md");
|
|
22238
22357
|
if (existsSync21(claudeMdPath)) {
|
|
22239
22358
|
const content = readFileSync17(claudeMdPath, "utf8");
|
|
22240
22359
|
const startMarker = "<!-- exe-os:orchestration-start -->";
|
|
@@ -22248,13 +22367,13 @@ async function runClaudeUninstall(flags = []) {
|
|
|
22248
22367
|
removed++;
|
|
22249
22368
|
}
|
|
22250
22369
|
}
|
|
22251
|
-
const agentsDir =
|
|
22370
|
+
const agentsDir = path33.join(claudeDir, "agents");
|
|
22252
22371
|
if (existsSync21(agentsDir)) {
|
|
22253
22372
|
let agentCount = 0;
|
|
22254
22373
|
try {
|
|
22255
22374
|
const entries = readdirSync5(agentsDir).filter((f) => f.endsWith(".md"));
|
|
22256
22375
|
let knownNames = /* @__PURE__ */ new Set();
|
|
22257
|
-
const rosterPath =
|
|
22376
|
+
const rosterPath = path33.join(exeOsDir, "exe-employees.json");
|
|
22258
22377
|
if (existsSync21(rosterPath)) {
|
|
22259
22378
|
try {
|
|
22260
22379
|
const roster = JSON.parse(readFileSync17(rosterPath, "utf8"));
|
|
@@ -22265,7 +22384,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
22265
22384
|
for (const entry of entries) {
|
|
22266
22385
|
const name = entry.replace(/\.md$/, "");
|
|
22267
22386
|
if (knownNames.has(name)) {
|
|
22268
|
-
if (!dryRun) rmSync(
|
|
22387
|
+
if (!dryRun) rmSync(path33.join(agentsDir, entry), { force: true });
|
|
22269
22388
|
agentCount++;
|
|
22270
22389
|
}
|
|
22271
22390
|
}
|
|
@@ -22276,13 +22395,13 @@ async function runClaudeUninstall(flags = []) {
|
|
|
22276
22395
|
removed++;
|
|
22277
22396
|
}
|
|
22278
22397
|
}
|
|
22279
|
-
const projectsDir =
|
|
22398
|
+
const projectsDir = path33.join(claudeDir, "projects");
|
|
22280
22399
|
if (existsSync21(projectsDir)) {
|
|
22281
22400
|
let projectCount = 0;
|
|
22282
22401
|
try {
|
|
22283
22402
|
const projects = readdirSync5(projectsDir);
|
|
22284
22403
|
for (const proj of projects) {
|
|
22285
|
-
const projSettings =
|
|
22404
|
+
const projSettings = path33.join(projectsDir, proj, "settings.json");
|
|
22286
22405
|
if (!existsSync21(projSettings)) continue;
|
|
22287
22406
|
try {
|
|
22288
22407
|
const pSettings = JSON.parse(readFileSync17(projSettings, "utf8"));
|
|
@@ -22310,16 +22429,24 @@ async function runClaudeUninstall(flags = []) {
|
|
|
22310
22429
|
}
|
|
22311
22430
|
try {
|
|
22312
22431
|
const { execSync: execSync13 } = await import("child_process");
|
|
22313
|
-
const
|
|
22314
|
-
|
|
22432
|
+
const findExeBin3 = () => {
|
|
22433
|
+
try {
|
|
22434
|
+
return execSync13(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
|
|
22435
|
+
} catch {
|
|
22436
|
+
return null;
|
|
22437
|
+
}
|
|
22438
|
+
};
|
|
22439
|
+
const exeBinPath = findExeBin3();
|
|
22440
|
+
if (!exeBinPath) throw new Error("exe-os not found in PATH");
|
|
22441
|
+
const binDir = path33.dirname(exeBinPath);
|
|
22315
22442
|
let symlinkCount = 0;
|
|
22316
|
-
const rosterPath =
|
|
22443
|
+
const rosterPath = path33.join(exeOsDir, "exe-employees.json");
|
|
22317
22444
|
if (existsSync21(rosterPath)) {
|
|
22318
22445
|
const roster = JSON.parse(readFileSync17(rosterPath, "utf8"));
|
|
22319
22446
|
for (const emp of roster) {
|
|
22320
22447
|
if (emp.name === "exe") continue;
|
|
22321
22448
|
for (const suffix of ["", "-opencode"]) {
|
|
22322
|
-
const linkPath =
|
|
22449
|
+
const linkPath = path33.join(binDir, `${emp.name}${suffix}`);
|
|
22323
22450
|
if (existsSync21(linkPath)) {
|
|
22324
22451
|
if (!dryRun) rmSync(linkPath, { force: true });
|
|
22325
22452
|
symlinkCount++;
|
|
@@ -22358,7 +22485,7 @@ async function checkForUpdateOnBoot() {
|
|
|
22358
22485
|
const config = await loadConfig2();
|
|
22359
22486
|
if (!config.autoUpdate.checkOnBoot) return;
|
|
22360
22487
|
const { checkForUpdate: checkForUpdate2 } = await init_update().then(() => update_exports);
|
|
22361
|
-
const packageRoot =
|
|
22488
|
+
const packageRoot = path33.resolve(
|
|
22362
22489
|
new URL("../..", import.meta.url).pathname
|
|
22363
22490
|
);
|
|
22364
22491
|
const result = checkForUpdate2(packageRoot);
|
|
@@ -22417,7 +22544,7 @@ async function runActivate(key) {
|
|
|
22417
22544
|
const idTemplate = getIdentityTemplate(identityKey);
|
|
22418
22545
|
if (idTemplate) {
|
|
22419
22546
|
const idPath = identityPath2(name);
|
|
22420
|
-
const dir =
|
|
22547
|
+
const dir = path33.dirname(idPath);
|
|
22421
22548
|
if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
|
|
22422
22549
|
fs8.writeFileSync(idPath, idTemplate.replace(/^agent_id: \w+/m, `agent_id: ${name}`), "utf-8");
|
|
22423
22550
|
}
|