@askexenow/exe-os 0.8.38 → 0.8.40
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 +291 -162
- 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 +187 -103
- 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(),
|
|
@@ -12174,6 +12246,7 @@ var init_terminal = __esm({
|
|
|
12174
12246
|
});
|
|
12175
12247
|
|
|
12176
12248
|
// src/tui/Sidebar.tsx
|
|
12249
|
+
import React14 from "react";
|
|
12177
12250
|
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
12178
12251
|
function Sidebar({
|
|
12179
12252
|
active,
|
|
@@ -12504,7 +12577,7 @@ var init_tmux_status = __esm({
|
|
|
12504
12577
|
});
|
|
12505
12578
|
|
|
12506
12579
|
// src/tui/Footer.tsx
|
|
12507
|
-
import { useState as useState4, useEffect as useEffect6 } from "react";
|
|
12580
|
+
import React15, { useState as useState4, useEffect as useEffect6 } from "react";
|
|
12508
12581
|
import { Fragment, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
12509
12582
|
function Footer() {
|
|
12510
12583
|
const demo = useDemo();
|
|
@@ -12637,6 +12710,7 @@ var init_Footer = __esm({
|
|
|
12637
12710
|
});
|
|
12638
12711
|
|
|
12639
12712
|
// src/tui/components/StatusDot.tsx
|
|
12713
|
+
import React16 from "react";
|
|
12640
12714
|
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
12641
12715
|
function StatusDot({ status, showLabel = true }) {
|
|
12642
12716
|
const { char, dotColor, label, labelColor } = STATUS_CONFIG[status];
|
|
@@ -12668,7 +12742,7 @@ var init_demo_data = __esm({
|
|
|
12668
12742
|
"src/tui/demo-data.ts"() {
|
|
12669
12743
|
"use strict";
|
|
12670
12744
|
DEMO_EMPLOYEES = [
|
|
12671
|
-
{ name: "exe", role: "COO", status: "active", activity: "Reviewing yoshi's task-aware behavior injection PR", memoryCount:
|
|
12745
|
+
{ name: "exe", role: "COO", status: "active", activity: "Reviewing yoshi's task-aware behavior injection PR", memoryCount: 15e3, projects: [
|
|
12672
12746
|
{ name: "exe-os", status: "active" },
|
|
12673
12747
|
{ name: "exe-create", status: "has_tasks" },
|
|
12674
12748
|
{ name: "openclaw", status: "idle" }
|
|
@@ -12677,7 +12751,7 @@ var init_demo_data = __esm({
|
|
|
12677
12751
|
"Dispatched behavior injection task",
|
|
12678
12752
|
"Approved gateway Phase 4"
|
|
12679
12753
|
] },
|
|
12680
|
-
{ name: "yoshi", role: "CTO", status: "active", activity: "Implementing skill learning trajectory capture", memoryCount:
|
|
12754
|
+
{ name: "yoshi", role: "CTO", status: "active", activity: "Implementing skill learning trajectory capture", memoryCount: 8e3, projects: [
|
|
12681
12755
|
{ name: "exe-os", status: "active" },
|
|
12682
12756
|
{ name: "exe-create", status: "idle" }
|
|
12683
12757
|
], recentTasks: [
|
|
@@ -12685,7 +12759,7 @@ var init_demo_data = __esm({
|
|
|
12685
12759
|
"Fixed TUI mouse listener leak",
|
|
12686
12760
|
"Built task-aware behavior injection"
|
|
12687
12761
|
] },
|
|
12688
|
-
{ name: "mari", role: "CMO", status: "idle", activity: "", memoryCount:
|
|
12762
|
+
{ name: "mari", role: "CMO", status: "idle", activity: "", memoryCount: 2e3, projects: [
|
|
12689
12763
|
{ name: "exe-build-skills", status: "has_tasks" },
|
|
12690
12764
|
{ name: "exe-os", status: "idle" }
|
|
12691
12765
|
], recentTasks: [
|
|
@@ -12693,13 +12767,13 @@ var init_demo_data = __esm({
|
|
|
12693
12767
|
"Designed exe-os UI system",
|
|
12694
12768
|
"Fixed logo layouts"
|
|
12695
12769
|
] },
|
|
12696
|
-
{ name: "tom", role: "Principal Engineer", status: "idle", activity: "", memoryCount:
|
|
12770
|
+
{ name: "tom", role: "Principal Engineer", status: "idle", activity: "", memoryCount: 700, projects: [
|
|
12697
12771
|
{ name: "exe-os", status: "idle" }
|
|
12698
12772
|
], recentTasks: [
|
|
12699
12773
|
"Implemented BashTool sandboxed execution",
|
|
12700
12774
|
"Ported session scoping to exe-agent-memory"
|
|
12701
12775
|
] },
|
|
12702
|
-
{ name: "sasha", role: "Content Production", status: "offline", activity: "", memoryCount:
|
|
12776
|
+
{ name: "sasha", role: "Content Production", status: "offline", activity: "", memoryCount: 50, projects: [
|
|
12703
12777
|
{ name: "exe-build-skills", status: "idle" }
|
|
12704
12778
|
], recentTasks: [
|
|
12705
12779
|
"Rendered carousel export prototype"
|
|
@@ -12712,7 +12786,7 @@ var init_demo_data = __esm({
|
|
|
12712
12786
|
{ time: "11:15", agent: "mari", action: "Completed exe-os UI design system" },
|
|
12713
12787
|
{ time: "10:50", agent: "exe", action: "Approved gateway Phase 4" }
|
|
12714
12788
|
];
|
|
12715
|
-
DEMO_HEALTH = { memories:
|
|
12789
|
+
DEMO_HEALTH = { memories: 25750, daemon: "running", cloud: "disabled" };
|
|
12716
12790
|
DEMO_PROJECTS = [
|
|
12717
12791
|
{
|
|
12718
12792
|
projectName: "exe-os",
|
|
@@ -14580,7 +14654,7 @@ var init_hooks = __esm({
|
|
|
14580
14654
|
|
|
14581
14655
|
// src/runtime/safety-checks.ts
|
|
14582
14656
|
import path14 from "path";
|
|
14583
|
-
import
|
|
14657
|
+
import os6 from "os";
|
|
14584
14658
|
function checkPathSafety(filePath) {
|
|
14585
14659
|
const resolved = path14.resolve(filePath);
|
|
14586
14660
|
for (const { pattern, reason } of BYPASS_IMMUNE_PATTERNS) {
|
|
@@ -14607,7 +14681,7 @@ var HOME, BYPASS_IMMUNE_PATTERNS;
|
|
|
14607
14681
|
var init_safety_checks = __esm({
|
|
14608
14682
|
"src/runtime/safety-checks.ts"() {
|
|
14609
14683
|
"use strict";
|
|
14610
|
-
HOME =
|
|
14684
|
+
HOME = os6.homedir();
|
|
14611
14685
|
BYPASS_IMMUNE_PATTERNS = [
|
|
14612
14686
|
{
|
|
14613
14687
|
pattern: /\/\.git\/hooks\//,
|
|
@@ -14839,8 +14913,13 @@ function runRipgrep(input, searchPath, context) {
|
|
|
14839
14913
|
timeout: 3e4,
|
|
14840
14914
|
stdio: ["ignore", "pipe", "pipe"]
|
|
14841
14915
|
});
|
|
14916
|
+
const MAX_OUTPUT = 1e7;
|
|
14842
14917
|
const chunks = [];
|
|
14843
|
-
|
|
14918
|
+
let totalSize = 0;
|
|
14919
|
+
child.stdout.on("data", (chunk) => {
|
|
14920
|
+
totalSize += chunk.length;
|
|
14921
|
+
if (totalSize <= MAX_OUTPUT) chunks.push(chunk);
|
|
14922
|
+
});
|
|
14844
14923
|
const onAbort = () => child.kill("SIGTERM");
|
|
14845
14924
|
context.abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
14846
14925
|
child.on("close", (code) => {
|
|
@@ -15224,10 +15303,19 @@ var init_bash = __esm({
|
|
|
15224
15303
|
stdio: ["ignore", "pipe", "pipe"],
|
|
15225
15304
|
env: { ...process.env }
|
|
15226
15305
|
});
|
|
15306
|
+
const MAX_OUTPUT_SIZE = 5242880;
|
|
15227
15307
|
const stdoutChunks = [];
|
|
15228
15308
|
const stderrChunks = [];
|
|
15229
|
-
|
|
15230
|
-
|
|
15309
|
+
let stdoutSize = 0;
|
|
15310
|
+
let stderrSize = 0;
|
|
15311
|
+
child.stdout.on("data", (chunk) => {
|
|
15312
|
+
if (stdoutSize < MAX_OUTPUT_SIZE) stdoutChunks.push(chunk);
|
|
15313
|
+
stdoutSize += chunk.length;
|
|
15314
|
+
});
|
|
15315
|
+
child.stderr.on("data", (chunk) => {
|
|
15316
|
+
if (stderrSize < MAX_OUTPUT_SIZE) stderrChunks.push(chunk);
|
|
15317
|
+
stderrSize += chunk.length;
|
|
15318
|
+
});
|
|
15231
15319
|
const onAbort = () => {
|
|
15232
15320
|
child.kill("SIGTERM");
|
|
15233
15321
|
setTimeout(() => {
|
|
@@ -15270,7 +15358,7 @@ __export(session_registry_exports, {
|
|
|
15270
15358
|
import { readFileSync as readFileSync10, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, existsSync as existsSync14 } from "fs";
|
|
15271
15359
|
import { execSync as execSync4 } from "child_process";
|
|
15272
15360
|
import path20 from "path";
|
|
15273
|
-
import
|
|
15361
|
+
import os7 from "os";
|
|
15274
15362
|
function registerSession(entry) {
|
|
15275
15363
|
const dir = path20.dirname(REGISTRY_PATH);
|
|
15276
15364
|
if (!existsSync14(dir)) {
|
|
@@ -15316,13 +15404,15 @@ var REGISTRY_PATH;
|
|
|
15316
15404
|
var init_session_registry = __esm({
|
|
15317
15405
|
"src/lib/session-registry.ts"() {
|
|
15318
15406
|
"use strict";
|
|
15319
|
-
REGISTRY_PATH = path20.join(
|
|
15407
|
+
REGISTRY_PATH = path20.join(os7.homedir(), ".exe-os", "session-registry.json");
|
|
15320
15408
|
}
|
|
15321
15409
|
});
|
|
15322
15410
|
|
|
15323
15411
|
// src/tui/views/CommandCenter.tsx
|
|
15324
15412
|
import { useState as useState6, useEffect as useEffect8, useMemo as useMemo4, useCallback as useCallback4, useRef as useRef4 } from "react";
|
|
15325
15413
|
import TextInput from "ink-text-input";
|
|
15414
|
+
import path21 from "path";
|
|
15415
|
+
import { homedir as homedir3 } from "os";
|
|
15326
15416
|
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
15327
15417
|
function CommandCenterView({
|
|
15328
15418
|
onSelectProject,
|
|
@@ -15358,8 +15448,8 @@ function CommandCenterView({
|
|
|
15358
15448
|
const { createDefaultHooks: createDefaultHooks2 } = await Promise.resolve().then(() => (init_hooks(), hooks_exports));
|
|
15359
15449
|
const { readFileSync: readFileSync18, existsSync: existsSync22 } = await import("fs");
|
|
15360
15450
|
const { join } = await import("path");
|
|
15361
|
-
const { homedir:
|
|
15362
|
-
const configPath = join(
|
|
15451
|
+
const { homedir: homedir5 } = await import("os");
|
|
15452
|
+
const configPath = join(homedir5(), ".exe-os", "config.json");
|
|
15363
15453
|
let failoverChain = ["anthropic", "opencode", "gemini", "openai"];
|
|
15364
15454
|
let providerConfigs = {};
|
|
15365
15455
|
if (existsSync22(configPath)) {
|
|
@@ -15422,7 +15512,7 @@ function CommandCenterView({
|
|
|
15422
15512
|
registry.register(BashTool2);
|
|
15423
15513
|
let agentRole = "CTO";
|
|
15424
15514
|
try {
|
|
15425
|
-
const markerDir = join(
|
|
15515
|
+
const markerDir = join(homedir5(), ".exe-os", "session-cache");
|
|
15426
15516
|
const agentFiles = (await import("fs")).readdirSync(markerDir).filter((f) => f.startsWith("active-agent-"));
|
|
15427
15517
|
for (const f of agentFiles) {
|
|
15428
15518
|
const data = JSON.parse(readFileSync18(join(markerDir, f), "utf8"));
|
|
@@ -15562,10 +15652,10 @@ function CommandCenterView({
|
|
|
15562
15652
|
const demoEntries = DEMO_PROJECTS.map((p) => ({
|
|
15563
15653
|
projectName: p.projectName,
|
|
15564
15654
|
exeSession: p.exeSession,
|
|
15565
|
-
projectDir:
|
|
15655
|
+
projectDir: path21.join(homedir3(), p.projectName),
|
|
15566
15656
|
employeeCount: p.employees.length,
|
|
15567
15657
|
activeCount: p.employees.filter((e) => e.status === "active").length,
|
|
15568
|
-
memoryCount: p.
|
|
15658
|
+
memoryCount: p.employees.length * 4e3,
|
|
15569
15659
|
status: p.employees.some((e) => e.status === "active") ? "active" : "idle",
|
|
15570
15660
|
type: p.projectName.startsWith("exe-") ? "code" : "automation",
|
|
15571
15661
|
recentTasks: DEMO_RECENT_TASKS[p.projectName] ?? []
|
|
@@ -15972,7 +16062,7 @@ var init_CommandCenter = __esm({
|
|
|
15972
16062
|
});
|
|
15973
16063
|
|
|
15974
16064
|
// src/tui/components/TmuxPane.tsx
|
|
15975
|
-
import { useState as useState7, useEffect as useEffect9 } from "react";
|
|
16065
|
+
import React18, { useState as useState7, useEffect as useEffect9 } from "react";
|
|
15976
16066
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
15977
16067
|
function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDetach }) {
|
|
15978
16068
|
const demo = useDemo();
|
|
@@ -16390,10 +16480,10 @@ var init_provider_table = __esm({
|
|
|
16390
16480
|
|
|
16391
16481
|
// src/lib/intercom-queue.ts
|
|
16392
16482
|
import { readFileSync as readFileSync11, writeFileSync as writeFileSync6, renameSync as renameSync4, existsSync as existsSync15, mkdirSync as mkdirSync7 } from "fs";
|
|
16393
|
-
import
|
|
16394
|
-
import
|
|
16483
|
+
import path22 from "path";
|
|
16484
|
+
import os8 from "os";
|
|
16395
16485
|
function ensureDir2() {
|
|
16396
|
-
const dir =
|
|
16486
|
+
const dir = path22.dirname(QUEUE_PATH);
|
|
16397
16487
|
if (!existsSync15(dir)) mkdirSync7(dir, { recursive: true });
|
|
16398
16488
|
}
|
|
16399
16489
|
function readQueue() {
|
|
@@ -16431,15 +16521,15 @@ var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
|
16431
16521
|
var init_intercom_queue = __esm({
|
|
16432
16522
|
"src/lib/intercom-queue.ts"() {
|
|
16433
16523
|
"use strict";
|
|
16434
|
-
QUEUE_PATH =
|
|
16524
|
+
QUEUE_PATH = path22.join(os8.homedir(), ".exe-os", "intercom-queue.json");
|
|
16435
16525
|
TTL_MS = 60 * 60 * 1e3;
|
|
16436
|
-
INTERCOM_LOG =
|
|
16526
|
+
INTERCOM_LOG = path22.join(os8.homedir(), ".exe-os", "intercom.log");
|
|
16437
16527
|
}
|
|
16438
16528
|
});
|
|
16439
16529
|
|
|
16440
16530
|
// src/lib/plan-limits.ts
|
|
16441
16531
|
import { readFileSync as readFileSync12, existsSync as existsSync16 } from "fs";
|
|
16442
|
-
import
|
|
16532
|
+
import path23 from "path";
|
|
16443
16533
|
function getLicenseSync() {
|
|
16444
16534
|
try {
|
|
16445
16535
|
if (!existsSync16(CACHE_PATH2)) return freeLicense();
|
|
@@ -16511,14 +16601,14 @@ var init_plan_limits = __esm({
|
|
|
16511
16601
|
this.name = "PlanLimitError";
|
|
16512
16602
|
}
|
|
16513
16603
|
};
|
|
16514
|
-
CACHE_PATH2 =
|
|
16604
|
+
CACHE_PATH2 = path23.join(EXE_AI_DIR, "license-cache.json");
|
|
16515
16605
|
}
|
|
16516
16606
|
});
|
|
16517
16607
|
|
|
16518
16608
|
// src/lib/notifications.ts
|
|
16519
16609
|
import crypto4 from "crypto";
|
|
16520
|
-
import
|
|
16521
|
-
import
|
|
16610
|
+
import path24 from "path";
|
|
16611
|
+
import os9 from "os";
|
|
16522
16612
|
import {
|
|
16523
16613
|
readFileSync as readFileSync13,
|
|
16524
16614
|
readdirSync as readdirSync3,
|
|
@@ -16603,7 +16693,7 @@ var init_session_kill_telemetry = __esm({
|
|
|
16603
16693
|
|
|
16604
16694
|
// src/lib/tasks-crud.ts
|
|
16605
16695
|
import crypto6 from "crypto";
|
|
16606
|
-
import
|
|
16696
|
+
import path25 from "path";
|
|
16607
16697
|
import { execSync as execSync7 } from "child_process";
|
|
16608
16698
|
import { mkdir as mkdir6, writeFile as writeFile5, appendFile } from "fs/promises";
|
|
16609
16699
|
import { existsSync as existsSync18, readFileSync as readFileSync14 } from "fs";
|
|
@@ -16736,8 +16826,8 @@ async function createTaskCore(input) {
|
|
|
16736
16826
|
}
|
|
16737
16827
|
if (input.baseDir) {
|
|
16738
16828
|
try {
|
|
16739
|
-
await mkdir6(
|
|
16740
|
-
await mkdir6(
|
|
16829
|
+
await mkdir6(path25.join(input.baseDir, "exe", "output"), { recursive: true });
|
|
16830
|
+
await mkdir6(path25.join(input.baseDir, "exe", "research"), { recursive: true });
|
|
16741
16831
|
await ensureArchitectureDoc(input.baseDir, input.projectName);
|
|
16742
16832
|
await ensureGitignoreExe(input.baseDir);
|
|
16743
16833
|
} catch {
|
|
@@ -16945,7 +17035,7 @@ async function deleteTaskCore(taskId, _baseDir) {
|
|
|
16945
17035
|
return { taskFile, assignedTo, assignedBy, taskSlug };
|
|
16946
17036
|
}
|
|
16947
17037
|
async function ensureArchitectureDoc(baseDir, projectName) {
|
|
16948
|
-
const archPath =
|
|
17038
|
+
const archPath = path25.join(baseDir, "exe", "ARCHITECTURE.md");
|
|
16949
17039
|
try {
|
|
16950
17040
|
if (existsSync18(archPath)) return;
|
|
16951
17041
|
const template = [
|
|
@@ -16980,7 +17070,7 @@ async function ensureArchitectureDoc(baseDir, projectName) {
|
|
|
16980
17070
|
}
|
|
16981
17071
|
}
|
|
16982
17072
|
async function ensureGitignoreExe(baseDir) {
|
|
16983
|
-
const gitignorePath =
|
|
17073
|
+
const gitignorePath = path25.join(baseDir, ".gitignore");
|
|
16984
17074
|
try {
|
|
16985
17075
|
if (existsSync18(gitignorePath)) {
|
|
16986
17076
|
const content = readFileSync14(gitignorePath, "utf-8");
|
|
@@ -17003,7 +17093,7 @@ var init_tasks_crud = __esm({
|
|
|
17003
17093
|
});
|
|
17004
17094
|
|
|
17005
17095
|
// src/lib/tasks-review.ts
|
|
17006
|
-
import
|
|
17096
|
+
import path26 from "path";
|
|
17007
17097
|
import { existsSync as existsSync19, readdirSync as readdirSync4, unlinkSync as unlinkSync6 } from "fs";
|
|
17008
17098
|
async function countPendingReviews() {
|
|
17009
17099
|
const client = getClient();
|
|
@@ -17124,11 +17214,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
17124
17214
|
);
|
|
17125
17215
|
}
|
|
17126
17216
|
try {
|
|
17127
|
-
const cacheDir =
|
|
17217
|
+
const cacheDir = path26.join(EXE_AI_DIR, "session-cache");
|
|
17128
17218
|
if (existsSync19(cacheDir)) {
|
|
17129
17219
|
for (const f of readdirSync4(cacheDir)) {
|
|
17130
17220
|
if (f.startsWith("review-notified-")) {
|
|
17131
|
-
unlinkSync6(
|
|
17221
|
+
unlinkSync6(path26.join(cacheDir, f));
|
|
17132
17222
|
}
|
|
17133
17223
|
}
|
|
17134
17224
|
}
|
|
@@ -17149,7 +17239,7 @@ var init_tasks_review = __esm({
|
|
|
17149
17239
|
});
|
|
17150
17240
|
|
|
17151
17241
|
// src/lib/tasks-chain.ts
|
|
17152
|
-
import
|
|
17242
|
+
import path27 from "path";
|
|
17153
17243
|
import { readFile as readFile5, writeFile as writeFile6 } from "fs/promises";
|
|
17154
17244
|
async function cascadeUnblock(taskId, baseDir, now) {
|
|
17155
17245
|
const client = getClient();
|
|
@@ -17165,7 +17255,7 @@ async function cascadeUnblock(taskId, baseDir, now) {
|
|
|
17165
17255
|
});
|
|
17166
17256
|
for (const ur of unblockedRows.rows) {
|
|
17167
17257
|
try {
|
|
17168
|
-
const ubFile =
|
|
17258
|
+
const ubFile = path27.join(baseDir, String(ur.task_file));
|
|
17169
17259
|
let ubContent = await readFile5(ubFile, "utf-8");
|
|
17170
17260
|
ubContent = ubContent.replace(/\*\*Status:\*\* blocked/, "**Status:** open");
|
|
17171
17261
|
ubContent = ubContent.replace(/\n\*\*Blocked by:\*\*.*\n/, "\n");
|
|
@@ -17231,7 +17321,7 @@ var init_tasks_chain = __esm({
|
|
|
17231
17321
|
|
|
17232
17322
|
// src/lib/project-name.ts
|
|
17233
17323
|
import { execSync as execSync8 } from "child_process";
|
|
17234
|
-
import
|
|
17324
|
+
import path28 from "path";
|
|
17235
17325
|
function getProjectName(cwd2) {
|
|
17236
17326
|
const dir = cwd2 ?? process.cwd();
|
|
17237
17327
|
if (_cached2 && _cachedCwd === dir) return _cached2;
|
|
@@ -17244,7 +17334,7 @@ function getProjectName(cwd2) {
|
|
|
17244
17334
|
timeout: 2e3,
|
|
17245
17335
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17246
17336
|
}).trim();
|
|
17247
|
-
repoRoot =
|
|
17337
|
+
repoRoot = path28.dirname(gitCommonDir);
|
|
17248
17338
|
} catch {
|
|
17249
17339
|
repoRoot = execSync8("git rev-parse --show-toplevel", {
|
|
17250
17340
|
cwd: dir,
|
|
@@ -17253,11 +17343,11 @@ function getProjectName(cwd2) {
|
|
|
17253
17343
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17254
17344
|
}).trim();
|
|
17255
17345
|
}
|
|
17256
|
-
_cached2 =
|
|
17346
|
+
_cached2 = path28.basename(repoRoot);
|
|
17257
17347
|
_cachedCwd = dir;
|
|
17258
17348
|
return _cached2;
|
|
17259
17349
|
} catch {
|
|
17260
|
-
_cached2 =
|
|
17350
|
+
_cached2 = path28.basename(dir);
|
|
17261
17351
|
_cachedCwd = dir;
|
|
17262
17352
|
return _cached2;
|
|
17263
17353
|
}
|
|
@@ -17728,7 +17818,7 @@ __export(tasks_exports, {
|
|
|
17728
17818
|
updateTaskStatus: () => updateTaskStatus,
|
|
17729
17819
|
writeCheckpoint: () => writeCheckpoint
|
|
17730
17820
|
});
|
|
17731
|
-
import
|
|
17821
|
+
import path29 from "path";
|
|
17732
17822
|
import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync8, unlinkSync as unlinkSync7 } from "fs";
|
|
17733
17823
|
async function createTask(input) {
|
|
17734
17824
|
const result = await createTaskCore(input);
|
|
@@ -17748,8 +17838,8 @@ async function updateTask(input) {
|
|
|
17748
17838
|
const { row, taskFile, now, taskId } = await updateTaskStatus(input);
|
|
17749
17839
|
try {
|
|
17750
17840
|
const agent = String(row.assigned_to);
|
|
17751
|
-
const cacheDir =
|
|
17752
|
-
const cachePath =
|
|
17841
|
+
const cacheDir = path29.join(EXE_AI_DIR, "session-cache");
|
|
17842
|
+
const cachePath = path29.join(cacheDir, `current-task-${agent}.json`);
|
|
17753
17843
|
if (input.status === "in_progress") {
|
|
17754
17844
|
mkdirSync8(cacheDir, { recursive: true });
|
|
17755
17845
|
writeFileSync7(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
@@ -18171,12 +18261,12 @@ __export(tmux_routing_exports, {
|
|
|
18171
18261
|
});
|
|
18172
18262
|
import { execFileSync as execFileSync3, execSync as execSync9 } from "child_process";
|
|
18173
18263
|
import { readFileSync as readFileSync15, writeFileSync as writeFileSync8, mkdirSync as mkdirSync9, existsSync as existsSync20, appendFileSync } from "fs";
|
|
18174
|
-
import
|
|
18175
|
-
import
|
|
18264
|
+
import path30 from "path";
|
|
18265
|
+
import os10 from "os";
|
|
18176
18266
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
18177
18267
|
import { unlinkSync as unlinkSync8 } from "fs";
|
|
18178
18268
|
function spawnLockPath(sessionName) {
|
|
18179
|
-
return
|
|
18269
|
+
return path30.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
18180
18270
|
}
|
|
18181
18271
|
function isProcessAlive(pid) {
|
|
18182
18272
|
try {
|
|
@@ -18213,8 +18303,8 @@ function releaseSpawnLock2(sessionName) {
|
|
|
18213
18303
|
function resolveBehaviorsExporterScript() {
|
|
18214
18304
|
try {
|
|
18215
18305
|
const thisFile = fileURLToPath4(import.meta.url);
|
|
18216
|
-
const scriptPath =
|
|
18217
|
-
|
|
18306
|
+
const scriptPath = path30.join(
|
|
18307
|
+
path30.dirname(thisFile),
|
|
18218
18308
|
"..",
|
|
18219
18309
|
"bin",
|
|
18220
18310
|
"exe-export-behaviors.js"
|
|
@@ -18264,7 +18354,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
|
18264
18354
|
mkdirSync9(SESSION_CACHE, { recursive: true });
|
|
18265
18355
|
}
|
|
18266
18356
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
18267
|
-
const filePath =
|
|
18357
|
+
const filePath = path30.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
18268
18358
|
writeFileSync8(filePath, JSON.stringify({
|
|
18269
18359
|
parentExe: rootExe,
|
|
18270
18360
|
dispatchedBy: dispatchedBy || rootExe,
|
|
@@ -18273,7 +18363,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
|
18273
18363
|
}
|
|
18274
18364
|
function getParentExe(sessionKey) {
|
|
18275
18365
|
try {
|
|
18276
|
-
const data = JSON.parse(readFileSync15(
|
|
18366
|
+
const data = JSON.parse(readFileSync15(path30.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
18277
18367
|
return data.parentExe || null;
|
|
18278
18368
|
} catch {
|
|
18279
18369
|
return null;
|
|
@@ -18282,7 +18372,7 @@ function getParentExe(sessionKey) {
|
|
|
18282
18372
|
function getDispatchedBy(sessionKey) {
|
|
18283
18373
|
try {
|
|
18284
18374
|
const data = JSON.parse(readFileSync15(
|
|
18285
|
-
|
|
18375
|
+
path30.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
|
|
18286
18376
|
"utf8"
|
|
18287
18377
|
));
|
|
18288
18378
|
return data.dispatchedBy ?? data.parentExe ?? null;
|
|
@@ -18525,8 +18615,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18525
18615
|
const transport = getTransport();
|
|
18526
18616
|
const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
|
|
18527
18617
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
18528
|
-
const logDir =
|
|
18529
|
-
const logFile =
|
|
18618
|
+
const logDir = path30.join(os10.homedir(), ".exe-os", "session-logs");
|
|
18619
|
+
const logFile = path30.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
18530
18620
|
if (!existsSync20(logDir)) {
|
|
18531
18621
|
mkdirSync9(logDir, { recursive: true });
|
|
18532
18622
|
}
|
|
@@ -18534,14 +18624,14 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18534
18624
|
let cleanupSuffix = "";
|
|
18535
18625
|
try {
|
|
18536
18626
|
const thisFile = fileURLToPath4(import.meta.url);
|
|
18537
|
-
const cleanupScript =
|
|
18627
|
+
const cleanupScript = path30.join(path30.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
|
|
18538
18628
|
if (existsSync20(cleanupScript)) {
|
|
18539
18629
|
cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
|
|
18540
18630
|
}
|
|
18541
18631
|
} catch {
|
|
18542
18632
|
}
|
|
18543
18633
|
try {
|
|
18544
|
-
const claudeJsonPath =
|
|
18634
|
+
const claudeJsonPath = path30.join(os10.homedir(), ".claude.json");
|
|
18545
18635
|
let claudeJson = {};
|
|
18546
18636
|
try {
|
|
18547
18637
|
claudeJson = JSON.parse(readFileSync15(claudeJsonPath, "utf8"));
|
|
@@ -18556,10 +18646,10 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18556
18646
|
} catch {
|
|
18557
18647
|
}
|
|
18558
18648
|
try {
|
|
18559
|
-
const settingsDir =
|
|
18649
|
+
const settingsDir = path30.join(os10.homedir(), ".claude", "projects");
|
|
18560
18650
|
const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
|
|
18561
|
-
const projSettingsDir =
|
|
18562
|
-
const settingsPath =
|
|
18651
|
+
const projSettingsDir = path30.join(settingsDir, normalizedKey);
|
|
18652
|
+
const settingsPath = path30.join(projSettingsDir, "settings.json");
|
|
18563
18653
|
let settings = {};
|
|
18564
18654
|
try {
|
|
18565
18655
|
settings = JSON.parse(readFileSync15(settingsPath, "utf8"));
|
|
@@ -18603,8 +18693,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18603
18693
|
let behaviorsFlag = "";
|
|
18604
18694
|
let legacyFallbackWarned = false;
|
|
18605
18695
|
if (!useExeAgent && !useBinSymlink) {
|
|
18606
|
-
const identityPath2 =
|
|
18607
|
-
|
|
18696
|
+
const identityPath2 = path30.join(
|
|
18697
|
+
os10.homedir(),
|
|
18608
18698
|
".exe-os",
|
|
18609
18699
|
"identity",
|
|
18610
18700
|
`${employeeName}.md`
|
|
@@ -18619,7 +18709,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18619
18709
|
}
|
|
18620
18710
|
const behaviorsFile = exportBehaviorsSync(
|
|
18621
18711
|
employeeName,
|
|
18622
|
-
|
|
18712
|
+
path30.basename(spawnCwd),
|
|
18623
18713
|
sessionName
|
|
18624
18714
|
);
|
|
18625
18715
|
if (behaviorsFile) {
|
|
@@ -18634,9 +18724,9 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18634
18724
|
}
|
|
18635
18725
|
let sessionContextFlag = "";
|
|
18636
18726
|
try {
|
|
18637
|
-
const ctxDir =
|
|
18727
|
+
const ctxDir = path30.join(os10.homedir(), ".exe-os", "session-cache");
|
|
18638
18728
|
mkdirSync9(ctxDir, { recursive: true });
|
|
18639
|
-
const ctxFile =
|
|
18729
|
+
const ctxFile = path30.join(ctxDir, `session-context-${sessionName}.md`);
|
|
18640
18730
|
const ctxContent = [
|
|
18641
18731
|
`## Session Context`,
|
|
18642
18732
|
`You are running in tmux session: ${sessionName}.`,
|
|
@@ -18681,7 +18771,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18681
18771
|
transport.pipeLog(sessionName, logFile);
|
|
18682
18772
|
try {
|
|
18683
18773
|
const mySession = getMySession();
|
|
18684
|
-
const dispatchInfo =
|
|
18774
|
+
const dispatchInfo = path30.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
|
|
18685
18775
|
writeFileSync8(dispatchInfo, JSON.stringify({
|
|
18686
18776
|
dispatchedBy: mySession,
|
|
18687
18777
|
rootExe: exeSession,
|
|
@@ -18745,13 +18835,13 @@ var init_tmux_routing = __esm({
|
|
|
18745
18835
|
init_provider_table();
|
|
18746
18836
|
init_intercom_queue();
|
|
18747
18837
|
init_plan_limits();
|
|
18748
|
-
SPAWN_LOCK_DIR =
|
|
18749
|
-
SESSION_CACHE =
|
|
18838
|
+
SPAWN_LOCK_DIR = path30.join(os10.homedir(), ".exe-os", "spawn-locks");
|
|
18839
|
+
SESSION_CACHE = path30.join(os10.homedir(), ".exe-os", "session-cache");
|
|
18750
18840
|
BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
|
|
18751
18841
|
VERIFY_PANE_LINES = 200;
|
|
18752
18842
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
18753
|
-
INTERCOM_LOG2 =
|
|
18754
|
-
DEBOUNCE_FILE =
|
|
18843
|
+
INTERCOM_LOG2 = path30.join(os10.homedir(), ".exe-os", "intercom.log");
|
|
18844
|
+
DEBOUNCE_FILE = path30.join(SESSION_CACHE, "intercom-debounce.json");
|
|
18755
18845
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
18756
18846
|
BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
|
|
18757
18847
|
}
|
|
@@ -19138,7 +19228,9 @@ var init_useOrchestrator = __esm({
|
|
|
19138
19228
|
});
|
|
19139
19229
|
|
|
19140
19230
|
// src/tui/views/Sessions.tsx
|
|
19141
|
-
import { useState as useState9, useEffect as useEffect11, useCallback as useCallback6 } from "react";
|
|
19231
|
+
import React19, { useState as useState9, useEffect as useEffect11, useCallback as useCallback6 } from "react";
|
|
19232
|
+
import path31 from "path";
|
|
19233
|
+
import { homedir as homedir4 } from "os";
|
|
19142
19234
|
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
19143
19235
|
function SessionsView({
|
|
19144
19236
|
initialProject,
|
|
@@ -19171,7 +19263,7 @@ function SessionsView({
|
|
|
19171
19263
|
if (demo) {
|
|
19172
19264
|
setProjects(DEMO_PROJECTS.map((p) => ({
|
|
19173
19265
|
...p,
|
|
19174
|
-
projectDir:
|
|
19266
|
+
projectDir: path31.join(homedir4(), p.projectName),
|
|
19175
19267
|
employees: p.employees.map((e) => ({ ...e, attached: e.status === "active" }))
|
|
19176
19268
|
})));
|
|
19177
19269
|
return;
|
|
@@ -19571,7 +19663,7 @@ var init_Sessions = __esm({
|
|
|
19571
19663
|
});
|
|
19572
19664
|
|
|
19573
19665
|
// src/tui/views/Tasks.tsx
|
|
19574
|
-
import { useState as useState10, useEffect as useEffect12, useMemo as useMemo5 } from "react";
|
|
19666
|
+
import React20, { useState as useState10, useEffect as useEffect12, useMemo as useMemo5 } from "react";
|
|
19575
19667
|
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
19576
19668
|
function relativeTime(iso) {
|
|
19577
19669
|
const now = Date.now();
|
|
@@ -20155,7 +20247,7 @@ var init_gateway_client = __esm({
|
|
|
20155
20247
|
});
|
|
20156
20248
|
|
|
20157
20249
|
// src/tui/views/Gateway.tsx
|
|
20158
|
-
import { useState as useState11, useEffect as useEffect13, useRef as useRef6, useMemo as useMemo6 } from "react";
|
|
20250
|
+
import React21, { useState as useState11, useEffect as useEffect13, useRef as useRef6, useMemo as useMemo6 } from "react";
|
|
20159
20251
|
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
20160
20252
|
function connectionStatusColor(status) {
|
|
20161
20253
|
switch (status) {
|
|
@@ -20757,7 +20849,7 @@ var init_agent_status = __esm({
|
|
|
20757
20849
|
});
|
|
20758
20850
|
|
|
20759
20851
|
// src/tui/views/Team.tsx
|
|
20760
|
-
import { useState as useState12, useEffect as useEffect14 } from "react";
|
|
20852
|
+
import React22, { useState as useState12, useEffect as useEffect14 } from "react";
|
|
20761
20853
|
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
20762
20854
|
function TeamView({ onBack }) {
|
|
20763
20855
|
const demo = useDemo();
|
|
@@ -21034,8 +21126,8 @@ __export(wiki_client_exports, {
|
|
|
21034
21126
|
listDocuments: () => listDocuments,
|
|
21035
21127
|
listWorkspaces: () => listWorkspaces
|
|
21036
21128
|
});
|
|
21037
|
-
async function wikiFetch(config,
|
|
21038
|
-
const url = `${config.baseUrl}/api/v1${
|
|
21129
|
+
async function wikiFetch(config, path34, method = "GET", body) {
|
|
21130
|
+
const url = `${config.baseUrl}/api/v1${path34}`;
|
|
21039
21131
|
const headers = {
|
|
21040
21132
|
Authorization: `Bearer ${config.apiKey}`,
|
|
21041
21133
|
"Content-Type": "application/json"
|
|
@@ -21043,14 +21135,32 @@ async function wikiFetch(config, path32, method = "GET", body) {
|
|
|
21043
21135
|
const controller = new AbortController();
|
|
21044
21136
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS2);
|
|
21045
21137
|
try {
|
|
21046
|
-
|
|
21047
|
-
|
|
21048
|
-
|
|
21049
|
-
|
|
21050
|
-
|
|
21051
|
-
|
|
21138
|
+
let response;
|
|
21139
|
+
try {
|
|
21140
|
+
response = await fetch(url, {
|
|
21141
|
+
method,
|
|
21142
|
+
headers,
|
|
21143
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
21144
|
+
signal: controller.signal
|
|
21145
|
+
});
|
|
21146
|
+
} catch {
|
|
21147
|
+
clearTimeout(timeout);
|
|
21148
|
+
const retryController = new AbortController();
|
|
21149
|
+
const retryTimeout = setTimeout(() => retryController.abort(), REQUEST_TIMEOUT_MS2);
|
|
21150
|
+
try {
|
|
21151
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
21152
|
+
response = await fetch(url, {
|
|
21153
|
+
method,
|
|
21154
|
+
headers,
|
|
21155
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
21156
|
+
signal: retryController.signal
|
|
21157
|
+
});
|
|
21158
|
+
} finally {
|
|
21159
|
+
clearTimeout(retryTimeout);
|
|
21160
|
+
}
|
|
21161
|
+
}
|
|
21052
21162
|
if (!response.ok) {
|
|
21053
|
-
throw new Error(`Wiki API ${method} ${
|
|
21163
|
+
throw new Error(`Wiki API ${method} ${path34}: ${response.status} ${response.statusText}`);
|
|
21054
21164
|
}
|
|
21055
21165
|
return response.json();
|
|
21056
21166
|
} finally {
|
|
@@ -21150,7 +21260,7 @@ var init_wiki_client = __esm({
|
|
|
21150
21260
|
});
|
|
21151
21261
|
|
|
21152
21262
|
// src/tui/views/Wiki.tsx
|
|
21153
|
-
import { useState as useState13, useEffect as useEffect15 } from "react";
|
|
21263
|
+
import React23, { useState as useState13, useEffect as useEffect15 } from "react";
|
|
21154
21264
|
import TextInput2 from "ink-text-input";
|
|
21155
21265
|
import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
21156
21266
|
function WikiView({ onBack }) {
|
|
@@ -21461,7 +21571,7 @@ var init_Wiki = __esm({
|
|
|
21461
21571
|
});
|
|
21462
21572
|
|
|
21463
21573
|
// src/tui/views/Settings.tsx
|
|
21464
|
-
import { useState as useState14, useEffect as useEffect16 } from "react";
|
|
21574
|
+
import React24, { useState as useState14, useEffect as useEffect16 } from "react";
|
|
21465
21575
|
import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
21466
21576
|
function SettingsView({ onBack }) {
|
|
21467
21577
|
const [providers, setProviders] = useState14([]);
|
|
@@ -21901,9 +22011,9 @@ var init_App2 = __esm({
|
|
|
21901
22011
|
// src/lib/update-check.ts
|
|
21902
22012
|
import { execSync as execSync11 } from "child_process";
|
|
21903
22013
|
import { readFileSync as readFileSync16 } from "fs";
|
|
21904
|
-
import
|
|
22014
|
+
import path32 from "path";
|
|
21905
22015
|
function getLocalVersion(packageRoot) {
|
|
21906
|
-
const pkgPath =
|
|
22016
|
+
const pkgPath = path32.join(packageRoot, "package.json");
|
|
21907
22017
|
const pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
|
|
21908
22018
|
return pkg.version;
|
|
21909
22019
|
}
|
|
@@ -21995,8 +22105,8 @@ var init_update = __esm({
|
|
|
21995
22105
|
|
|
21996
22106
|
// src/bin/cli.ts
|
|
21997
22107
|
import { existsSync as existsSync21, readFileSync as readFileSync17, writeFileSync as writeFileSync9, readdirSync as readdirSync5, rmSync } from "fs";
|
|
21998
|
-
import
|
|
21999
|
-
import
|
|
22108
|
+
import path33 from "path";
|
|
22109
|
+
import os11 from "os";
|
|
22000
22110
|
var args = process.argv.slice(2);
|
|
22001
22111
|
if (args.includes("--global")) {
|
|
22002
22112
|
process.stderr.write(
|
|
@@ -22069,9 +22179,9 @@ async function runClaudeInstall() {
|
|
|
22069
22179
|
}
|
|
22070
22180
|
}
|
|
22071
22181
|
async function runClaudeCheck() {
|
|
22072
|
-
const claudeDir =
|
|
22073
|
-
const settingsPath =
|
|
22074
|
-
const claudeJsonPath =
|
|
22182
|
+
const claudeDir = path33.join(os11.homedir(), ".claude");
|
|
22183
|
+
const settingsPath = path33.join(claudeDir, "settings.json");
|
|
22184
|
+
const claudeJsonPath = path33.join(os11.homedir(), ".claude.json");
|
|
22075
22185
|
let ok = true;
|
|
22076
22186
|
if (existsSync21(settingsPath)) {
|
|
22077
22187
|
let settings;
|
|
@@ -22124,7 +22234,7 @@ async function runClaudeCheck() {
|
|
|
22124
22234
|
console.log("\x1B[31m\u2717\x1B[0m claude.json not found");
|
|
22125
22235
|
ok = false;
|
|
22126
22236
|
}
|
|
22127
|
-
const skillsDir =
|
|
22237
|
+
const skillsDir = path33.join(claudeDir, "skills");
|
|
22128
22238
|
if (existsSync21(skillsDir)) {
|
|
22129
22239
|
console.log("\x1B[32m\u2713\x1B[0m Slash skills directory exists");
|
|
22130
22240
|
} else {
|
|
@@ -22141,11 +22251,11 @@ async function runClaudeCheck() {
|
|
|
22141
22251
|
async function runClaudeUninstall(flags = []) {
|
|
22142
22252
|
const dryRun = flags.includes("--dry-run");
|
|
22143
22253
|
const purge = flags.includes("--purge");
|
|
22144
|
-
const homeDir =
|
|
22145
|
-
const claudeDir =
|
|
22146
|
-
const settingsPath =
|
|
22147
|
-
const claudeJsonPath =
|
|
22148
|
-
const exeOsDir =
|
|
22254
|
+
const homeDir = os11.homedir();
|
|
22255
|
+
const claudeDir = path33.join(homeDir, ".claude");
|
|
22256
|
+
const settingsPath = path33.join(claudeDir, "settings.json");
|
|
22257
|
+
const claudeJsonPath = path33.join(homeDir, ".claude.json");
|
|
22258
|
+
const exeOsDir = path33.join(homeDir, ".exe-os");
|
|
22149
22259
|
let removed = 0;
|
|
22150
22260
|
const log = (msg) => console.log(dryRun ? `[dry-run] ${msg}` : msg);
|
|
22151
22261
|
let settings = {};
|
|
@@ -22197,32 +22307,43 @@ async function runClaudeUninstall(flags = []) {
|
|
|
22197
22307
|
}
|
|
22198
22308
|
}
|
|
22199
22309
|
if (existsSync21(claudeJsonPath)) {
|
|
22200
|
-
const
|
|
22201
|
-
if (
|
|
22202
|
-
|
|
22203
|
-
|
|
22204
|
-
|
|
22205
|
-
|
|
22206
|
-
|
|
22310
|
+
const raw = readFileSync17(claudeJsonPath, "utf8");
|
|
22311
|
+
if (raw.length > 1e6) {
|
|
22312
|
+
console.error("claude.json exceeds 1 MB \u2014 skipping parse.");
|
|
22313
|
+
} else {
|
|
22314
|
+
let claudeJson;
|
|
22315
|
+
try {
|
|
22316
|
+
claudeJson = JSON.parse(raw);
|
|
22317
|
+
} catch {
|
|
22318
|
+
console.error("claude.json is malformed JSON \u2014 skipping.");
|
|
22319
|
+
claudeJson = {};
|
|
22320
|
+
}
|
|
22321
|
+
if (claudeJson.mcpServers) {
|
|
22322
|
+
let removedMcp = false;
|
|
22323
|
+
for (const key of ["exe-mem", "exe-os"]) {
|
|
22324
|
+
if (claudeJson.mcpServers[key]) {
|
|
22325
|
+
if (!dryRun) delete claudeJson.mcpServers[key];
|
|
22326
|
+
removedMcp = true;
|
|
22327
|
+
}
|
|
22207
22328
|
}
|
|
22208
|
-
|
|
22209
|
-
|
|
22210
|
-
|
|
22211
|
-
|
|
22329
|
+
if (removedMcp) {
|
|
22330
|
+
if (!dryRun) {
|
|
22331
|
+
writeFileSync9(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
22332
|
+
}
|
|
22333
|
+
log("\u2713 Removed exe-os MCP server from claude.json");
|
|
22334
|
+
removed++;
|
|
22212
22335
|
}
|
|
22213
|
-
log("\u2713 Removed exe-os MCP server from claude.json");
|
|
22214
|
-
removed++;
|
|
22215
22336
|
}
|
|
22216
22337
|
}
|
|
22217
22338
|
}
|
|
22218
|
-
const skillsDir =
|
|
22339
|
+
const skillsDir = path33.join(claudeDir, "skills");
|
|
22219
22340
|
if (existsSync21(skillsDir)) {
|
|
22220
22341
|
let skillCount = 0;
|
|
22221
22342
|
try {
|
|
22222
22343
|
const entries = readdirSync5(skillsDir);
|
|
22223
22344
|
for (const entry of entries) {
|
|
22224
22345
|
if (entry.startsWith("exe")) {
|
|
22225
|
-
const fullPath =
|
|
22346
|
+
const fullPath = path33.join(skillsDir, entry);
|
|
22226
22347
|
if (!dryRun) rmSync(fullPath, { recursive: true, force: true });
|
|
22227
22348
|
skillCount++;
|
|
22228
22349
|
}
|
|
@@ -22234,7 +22355,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
22234
22355
|
removed++;
|
|
22235
22356
|
}
|
|
22236
22357
|
}
|
|
22237
|
-
const claudeMdPath =
|
|
22358
|
+
const claudeMdPath = path33.join(claudeDir, "CLAUDE.md");
|
|
22238
22359
|
if (existsSync21(claudeMdPath)) {
|
|
22239
22360
|
const content = readFileSync17(claudeMdPath, "utf8");
|
|
22240
22361
|
const startMarker = "<!-- exe-os:orchestration-start -->";
|
|
@@ -22248,13 +22369,13 @@ async function runClaudeUninstall(flags = []) {
|
|
|
22248
22369
|
removed++;
|
|
22249
22370
|
}
|
|
22250
22371
|
}
|
|
22251
|
-
const agentsDir =
|
|
22372
|
+
const agentsDir = path33.join(claudeDir, "agents");
|
|
22252
22373
|
if (existsSync21(agentsDir)) {
|
|
22253
22374
|
let agentCount = 0;
|
|
22254
22375
|
try {
|
|
22255
22376
|
const entries = readdirSync5(agentsDir).filter((f) => f.endsWith(".md"));
|
|
22256
22377
|
let knownNames = /* @__PURE__ */ new Set();
|
|
22257
|
-
const rosterPath =
|
|
22378
|
+
const rosterPath = path33.join(exeOsDir, "exe-employees.json");
|
|
22258
22379
|
if (existsSync21(rosterPath)) {
|
|
22259
22380
|
try {
|
|
22260
22381
|
const roster = JSON.parse(readFileSync17(rosterPath, "utf8"));
|
|
@@ -22265,7 +22386,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
22265
22386
|
for (const entry of entries) {
|
|
22266
22387
|
const name = entry.replace(/\.md$/, "");
|
|
22267
22388
|
if (knownNames.has(name)) {
|
|
22268
|
-
if (!dryRun) rmSync(
|
|
22389
|
+
if (!dryRun) rmSync(path33.join(agentsDir, entry), { force: true });
|
|
22269
22390
|
agentCount++;
|
|
22270
22391
|
}
|
|
22271
22392
|
}
|
|
@@ -22276,13 +22397,13 @@ async function runClaudeUninstall(flags = []) {
|
|
|
22276
22397
|
removed++;
|
|
22277
22398
|
}
|
|
22278
22399
|
}
|
|
22279
|
-
const projectsDir =
|
|
22400
|
+
const projectsDir = path33.join(claudeDir, "projects");
|
|
22280
22401
|
if (existsSync21(projectsDir)) {
|
|
22281
22402
|
let projectCount = 0;
|
|
22282
22403
|
try {
|
|
22283
22404
|
const projects = readdirSync5(projectsDir);
|
|
22284
22405
|
for (const proj of projects) {
|
|
22285
|
-
const projSettings =
|
|
22406
|
+
const projSettings = path33.join(projectsDir, proj, "settings.json");
|
|
22286
22407
|
if (!existsSync21(projSettings)) continue;
|
|
22287
22408
|
try {
|
|
22288
22409
|
const pSettings = JSON.parse(readFileSync17(projSettings, "utf8"));
|
|
@@ -22310,16 +22431,24 @@ async function runClaudeUninstall(flags = []) {
|
|
|
22310
22431
|
}
|
|
22311
22432
|
try {
|
|
22312
22433
|
const { execSync: execSync13 } = await import("child_process");
|
|
22313
|
-
const
|
|
22314
|
-
|
|
22434
|
+
const findExeBin3 = () => {
|
|
22435
|
+
try {
|
|
22436
|
+
return execSync13(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
|
|
22437
|
+
} catch {
|
|
22438
|
+
return null;
|
|
22439
|
+
}
|
|
22440
|
+
};
|
|
22441
|
+
const exeBinPath = findExeBin3();
|
|
22442
|
+
if (!exeBinPath) throw new Error("exe-os not found in PATH");
|
|
22443
|
+
const binDir = path33.dirname(exeBinPath);
|
|
22315
22444
|
let symlinkCount = 0;
|
|
22316
|
-
const rosterPath =
|
|
22445
|
+
const rosterPath = path33.join(exeOsDir, "exe-employees.json");
|
|
22317
22446
|
if (existsSync21(rosterPath)) {
|
|
22318
22447
|
const roster = JSON.parse(readFileSync17(rosterPath, "utf8"));
|
|
22319
22448
|
for (const emp of roster) {
|
|
22320
22449
|
if (emp.name === "exe") continue;
|
|
22321
22450
|
for (const suffix of ["", "-opencode"]) {
|
|
22322
|
-
const linkPath =
|
|
22451
|
+
const linkPath = path33.join(binDir, `${emp.name}${suffix}`);
|
|
22323
22452
|
if (existsSync21(linkPath)) {
|
|
22324
22453
|
if (!dryRun) rmSync(linkPath, { force: true });
|
|
22325
22454
|
symlinkCount++;
|
|
@@ -22358,7 +22487,7 @@ async function checkForUpdateOnBoot() {
|
|
|
22358
22487
|
const config = await loadConfig2();
|
|
22359
22488
|
if (!config.autoUpdate.checkOnBoot) return;
|
|
22360
22489
|
const { checkForUpdate: checkForUpdate2 } = await init_update().then(() => update_exports);
|
|
22361
|
-
const packageRoot =
|
|
22490
|
+
const packageRoot = path33.resolve(
|
|
22362
22491
|
new URL("../..", import.meta.url).pathname
|
|
22363
22492
|
);
|
|
22364
22493
|
const result = checkForUpdate2(packageRoot);
|
|
@@ -22417,7 +22546,7 @@ async function runActivate(key) {
|
|
|
22417
22546
|
const idTemplate = getIdentityTemplate(identityKey);
|
|
22418
22547
|
if (idTemplate) {
|
|
22419
22548
|
const idPath = identityPath2(name);
|
|
22420
|
-
const dir =
|
|
22549
|
+
const dir = path33.dirname(idPath);
|
|
22421
22550
|
if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
|
|
22422
22551
|
fs8.writeFileSync(idPath, idTemplate.replace(/^agent_id: \w+/m, `agent_id: ${name}`), "utf-8");
|
|
22423
22552
|
}
|