@askexenow/exe-os 0.9.30 → 0.9.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/backfill-conversations.js +135 -7
- package/dist/bin/backfill-responses.js +135 -7
- package/dist/bin/backfill-vectors.js +135 -7
- package/dist/bin/cleanup-stale-review-tasks.js +139 -11
- package/dist/bin/cli.js +812 -486
- package/dist/bin/exe-assign.js +135 -7
- package/dist/bin/exe-boot.js +422 -113
- package/dist/bin/exe-cloud.js +160 -9
- package/dist/bin/exe-dispatch.js +136 -8
- package/dist/bin/exe-doctor.js +255 -13
- package/dist/bin/exe-export-behaviors.js +136 -8
- package/dist/bin/exe-forget.js +136 -8
- package/dist/bin/exe-gateway.js +171 -24
- package/dist/bin/exe-heartbeat.js +141 -13
- package/dist/bin/exe-kill.js +140 -12
- package/dist/bin/exe-launch-agent.js +143 -15
- package/dist/bin/exe-link.js +357 -48
- package/dist/bin/exe-pending-messages.js +136 -8
- package/dist/bin/exe-pending-notifications.js +136 -8
- package/dist/bin/exe-pending-reviews.js +138 -10
- package/dist/bin/exe-review.js +136 -8
- package/dist/bin/exe-search.js +155 -20
- package/dist/bin/exe-session-cleanup.js +166 -38
- package/dist/bin/exe-start-codex.js +142 -14
- package/dist/bin/exe-start-opencode.js +140 -12
- package/dist/bin/exe-status.js +148 -20
- package/dist/bin/exe-team.js +136 -8
- package/dist/bin/git-sweep.js +138 -10
- package/dist/bin/graph-backfill.js +135 -7
- package/dist/bin/graph-export.js +136 -8
- package/dist/bin/intercom-check.js +153 -25
- package/dist/bin/scan-tasks.js +138 -10
- package/dist/bin/setup.js +447 -121
- package/dist/bin/shard-migrate.js +135 -7
- package/dist/gateway/index.js +151 -23
- package/dist/hooks/bug-report-worker.js +151 -23
- package/dist/hooks/codex-stop-task-finalizer.js +145 -17
- package/dist/hooks/commit-complete.js +138 -10
- package/dist/hooks/error-recall.js +159 -24
- package/dist/hooks/ingest.js +142 -14
- package/dist/hooks/instructions-loaded.js +136 -8
- package/dist/hooks/notification.js +136 -8
- package/dist/hooks/post-compact.js +136 -8
- package/dist/hooks/post-tool-combined.js +159 -24
- package/dist/hooks/pre-compact.js +136 -8
- package/dist/hooks/pre-tool-use.js +144 -16
- package/dist/hooks/prompt-submit.js +195 -55
- package/dist/hooks/session-end.js +141 -13
- package/dist/hooks/session-start.js +165 -30
- package/dist/hooks/stop.js +136 -8
- package/dist/hooks/subagent-stop.js +136 -8
- package/dist/hooks/summary-worker.js +374 -65
- package/dist/index.js +136 -8
- package/dist/lib/cloud-sync.js +355 -46
- package/dist/lib/consolidation.js +1 -0
- package/dist/lib/exe-daemon.js +469 -127
- package/dist/lib/hybrid-search.js +155 -20
- package/dist/lib/keychain.js +191 -7
- package/dist/lib/schedules.js +138 -10
- package/dist/lib/store.js +135 -7
- package/dist/mcp/server.js +706 -213
- package/dist/runtime/index.js +136 -8
- package/dist/tui/App.js +208 -31
- package/package.json +1 -1
package/dist/mcp/server.js
CHANGED
|
@@ -428,8 +428,8 @@ function findPackageRoot() {
|
|
|
428
428
|
function getAvailableMemoryGB() {
|
|
429
429
|
if (process.platform === "darwin") {
|
|
430
430
|
try {
|
|
431
|
-
const { execSync:
|
|
432
|
-
const vmstat =
|
|
431
|
+
const { execSync: execSync12 } = __require("child_process");
|
|
432
|
+
const vmstat = execSync12("vm_stat", { encoding: "utf8" });
|
|
433
433
|
const pageSize = 16384;
|
|
434
434
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
435
435
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -849,10 +849,10 @@ async function disposeEmbedder() {
|
|
|
849
849
|
async function embedDirect(text) {
|
|
850
850
|
const llamaCpp = await import("node-llama-cpp");
|
|
851
851
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
852
|
-
const { existsSync:
|
|
853
|
-
const
|
|
854
|
-
const modelPath =
|
|
855
|
-
if (!
|
|
852
|
+
const { existsSync: existsSync35 } = await import("fs");
|
|
853
|
+
const path45 = await import("path");
|
|
854
|
+
const modelPath = path45.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
855
|
+
if (!existsSync35(modelPath)) {
|
|
856
856
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
857
857
|
}
|
|
858
858
|
const llama = await llamaCpp.getLlama();
|
|
@@ -3220,6 +3220,7 @@ __export(keychain_exports, {
|
|
|
3220
3220
|
});
|
|
3221
3221
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3222
3222
|
import { existsSync as existsSync7 } from "fs";
|
|
3223
|
+
import { execSync as execSync2 } from "child_process";
|
|
3223
3224
|
import path7 from "path";
|
|
3224
3225
|
import os5 from "os";
|
|
3225
3226
|
function getKeyDir() {
|
|
@@ -3228,6 +3229,83 @@ function getKeyDir() {
|
|
|
3228
3229
|
function getKeyPath() {
|
|
3229
3230
|
return path7.join(getKeyDir(), "master.key");
|
|
3230
3231
|
}
|
|
3232
|
+
function macKeychainGet() {
|
|
3233
|
+
if (process.platform !== "darwin") return null;
|
|
3234
|
+
try {
|
|
3235
|
+
return execSync2(
|
|
3236
|
+
`security find-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
3237
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
3238
|
+
).trim();
|
|
3239
|
+
} catch {
|
|
3240
|
+
return null;
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
function macKeychainSet(value) {
|
|
3244
|
+
if (process.platform !== "darwin") return false;
|
|
3245
|
+
try {
|
|
3246
|
+
try {
|
|
3247
|
+
execSync2(
|
|
3248
|
+
`security delete-generic-password -s "${SERVICE}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3249
|
+
{ timeout: 5e3 }
|
|
3250
|
+
);
|
|
3251
|
+
} catch {
|
|
3252
|
+
}
|
|
3253
|
+
execSync2(
|
|
3254
|
+
`security add-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w "${value}"`,
|
|
3255
|
+
{ timeout: 5e3 }
|
|
3256
|
+
);
|
|
3257
|
+
return true;
|
|
3258
|
+
} catch {
|
|
3259
|
+
return false;
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
function macKeychainDelete() {
|
|
3263
|
+
if (process.platform !== "darwin") return false;
|
|
3264
|
+
try {
|
|
3265
|
+
execSync2(
|
|
3266
|
+
`security delete-generic-password -s "${SERVICE}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3267
|
+
{ timeout: 5e3 }
|
|
3268
|
+
);
|
|
3269
|
+
return true;
|
|
3270
|
+
} catch {
|
|
3271
|
+
return false;
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3274
|
+
function linuxSecretGet() {
|
|
3275
|
+
if (process.platform !== "linux") return null;
|
|
3276
|
+
try {
|
|
3277
|
+
return execSync2(
|
|
3278
|
+
`secret-tool lookup service "${SERVICE}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3279
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
3280
|
+
).trim();
|
|
3281
|
+
} catch {
|
|
3282
|
+
return null;
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
function linuxSecretSet(value) {
|
|
3286
|
+
if (process.platform !== "linux") return false;
|
|
3287
|
+
try {
|
|
3288
|
+
execSync2(
|
|
3289
|
+
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${SERVICE}" account "${ACCOUNT}"`,
|
|
3290
|
+
{ timeout: 5e3 }
|
|
3291
|
+
);
|
|
3292
|
+
return true;
|
|
3293
|
+
} catch {
|
|
3294
|
+
return false;
|
|
3295
|
+
}
|
|
3296
|
+
}
|
|
3297
|
+
function linuxSecretDelete() {
|
|
3298
|
+
if (process.platform !== "linux") return false;
|
|
3299
|
+
try {
|
|
3300
|
+
execSync2(
|
|
3301
|
+
`secret-tool clear service "${SERVICE}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3302
|
+
{ timeout: 5e3 }
|
|
3303
|
+
);
|
|
3304
|
+
return true;
|
|
3305
|
+
} catch {
|
|
3306
|
+
return false;
|
|
3307
|
+
}
|
|
3308
|
+
}
|
|
3231
3309
|
async function tryKeytar() {
|
|
3232
3310
|
try {
|
|
3233
3311
|
return await import("keytar");
|
|
@@ -3235,13 +3313,72 @@ async function tryKeytar() {
|
|
|
3235
3313
|
return null;
|
|
3236
3314
|
}
|
|
3237
3315
|
}
|
|
3316
|
+
function deriveMachineKey() {
|
|
3317
|
+
try {
|
|
3318
|
+
const crypto18 = __require("crypto");
|
|
3319
|
+
const material = [
|
|
3320
|
+
os5.hostname(),
|
|
3321
|
+
os5.userInfo().username,
|
|
3322
|
+
os5.arch(),
|
|
3323
|
+
os5.platform(),
|
|
3324
|
+
// Machine ID on Linux (stable across reboots)
|
|
3325
|
+
process.platform === "linux" ? readMachineId() : ""
|
|
3326
|
+
].join("|");
|
|
3327
|
+
return crypto18.createHash("sha256").update(material).digest();
|
|
3328
|
+
} catch {
|
|
3329
|
+
return null;
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
function readMachineId() {
|
|
3333
|
+
try {
|
|
3334
|
+
const { readFileSync: readFileSync29 } = __require("fs");
|
|
3335
|
+
return readFileSync29("/etc/machine-id", "utf-8").trim();
|
|
3336
|
+
} catch {
|
|
3337
|
+
return "";
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
function encryptWithMachineKey(plaintext, machineKey) {
|
|
3341
|
+
const crypto18 = __require("crypto");
|
|
3342
|
+
const iv = crypto18.randomBytes(12);
|
|
3343
|
+
const cipher = crypto18.createCipheriv("aes-256-gcm", machineKey, iv);
|
|
3344
|
+
let encrypted = cipher.update(plaintext, "utf-8", "base64");
|
|
3345
|
+
encrypted += cipher.final("base64");
|
|
3346
|
+
const authTag = cipher.getAuthTag().toString("base64");
|
|
3347
|
+
return `${ENCRYPTED_PREFIX}${iv.toString("base64")}:${authTag}:${encrypted}`;
|
|
3348
|
+
}
|
|
3349
|
+
function decryptWithMachineKey(encrypted, machineKey) {
|
|
3350
|
+
if (!encrypted.startsWith(ENCRYPTED_PREFIX)) return null;
|
|
3351
|
+
try {
|
|
3352
|
+
const crypto18 = __require("crypto");
|
|
3353
|
+
const parts = encrypted.slice(ENCRYPTED_PREFIX.length).split(":");
|
|
3354
|
+
if (parts.length !== 3) return null;
|
|
3355
|
+
const [ivB64, tagB64, cipherB64] = parts;
|
|
3356
|
+
const iv = Buffer.from(ivB64, "base64");
|
|
3357
|
+
const authTag = Buffer.from(tagB64, "base64");
|
|
3358
|
+
const decipher = crypto18.createDecipheriv("aes-256-gcm", machineKey, iv);
|
|
3359
|
+
decipher.setAuthTag(authTag);
|
|
3360
|
+
let decrypted = decipher.update(cipherB64, "base64", "utf-8");
|
|
3361
|
+
decrypted += decipher.final("utf-8");
|
|
3362
|
+
return decrypted;
|
|
3363
|
+
} catch {
|
|
3364
|
+
return null;
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3238
3367
|
async function getMasterKey() {
|
|
3368
|
+
const nativeValue = macKeychainGet() ?? linuxSecretGet();
|
|
3369
|
+
if (nativeValue) {
|
|
3370
|
+
return Buffer.from(nativeValue, "base64");
|
|
3371
|
+
}
|
|
3239
3372
|
const keytar = await tryKeytar();
|
|
3240
3373
|
if (keytar) {
|
|
3241
3374
|
try {
|
|
3242
|
-
const
|
|
3243
|
-
if (
|
|
3244
|
-
|
|
3375
|
+
const keytarValue = await keytar.getPassword(SERVICE, ACCOUNT);
|
|
3376
|
+
if (keytarValue) {
|
|
3377
|
+
const migrated = macKeychainSet(keytarValue) || linuxSecretSet(keytarValue);
|
|
3378
|
+
if (migrated) {
|
|
3379
|
+
process.stderr.write("[keychain] Migrated key from keytar to native keychain.\n");
|
|
3380
|
+
}
|
|
3381
|
+
return Buffer.from(keytarValue, "base64");
|
|
3245
3382
|
}
|
|
3246
3383
|
} catch {
|
|
3247
3384
|
}
|
|
@@ -3255,8 +3392,31 @@ async function getMasterKey() {
|
|
|
3255
3392
|
return null;
|
|
3256
3393
|
}
|
|
3257
3394
|
try {
|
|
3258
|
-
const content = await readFile3(keyPath, "utf-8");
|
|
3259
|
-
|
|
3395
|
+
const content = (await readFile3(keyPath, "utf-8")).trim();
|
|
3396
|
+
let b64Value;
|
|
3397
|
+
if (content.startsWith(ENCRYPTED_PREFIX)) {
|
|
3398
|
+
const machineKey = deriveMachineKey();
|
|
3399
|
+
if (!machineKey) {
|
|
3400
|
+
process.stderr.write("[keychain] Cannot derive machine key to decrypt stored key.\n");
|
|
3401
|
+
return null;
|
|
3402
|
+
}
|
|
3403
|
+
const decrypted = decryptWithMachineKey(content, machineKey);
|
|
3404
|
+
if (!decrypted) {
|
|
3405
|
+
process.stderr.write(
|
|
3406
|
+
"[keychain] Key decryption failed \u2014 machine may have changed.\n Use your 24-word recovery phrase: exe-os link import\n"
|
|
3407
|
+
);
|
|
3408
|
+
return null;
|
|
3409
|
+
}
|
|
3410
|
+
b64Value = decrypted;
|
|
3411
|
+
} else {
|
|
3412
|
+
b64Value = content;
|
|
3413
|
+
}
|
|
3414
|
+
const key = Buffer.from(b64Value, "base64");
|
|
3415
|
+
const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
|
|
3416
|
+
if (migrated) {
|
|
3417
|
+
process.stderr.write("[keychain] Migrated key from file to native keychain.\n");
|
|
3418
|
+
}
|
|
3419
|
+
return key;
|
|
3260
3420
|
} catch (err) {
|
|
3261
3421
|
process.stderr.write(
|
|
3262
3422
|
`[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -3267,6 +3427,9 @@ async function getMasterKey() {
|
|
|
3267
3427
|
}
|
|
3268
3428
|
async function setMasterKey(key) {
|
|
3269
3429
|
const b64 = key.toString("base64");
|
|
3430
|
+
if (macKeychainSet(b64) || linuxSecretSet(b64)) {
|
|
3431
|
+
return;
|
|
3432
|
+
}
|
|
3270
3433
|
const keytar = await tryKeytar();
|
|
3271
3434
|
if (keytar) {
|
|
3272
3435
|
try {
|
|
@@ -3278,10 +3441,23 @@ async function setMasterKey(key) {
|
|
|
3278
3441
|
const dir = getKeyDir();
|
|
3279
3442
|
await mkdir3(dir, { recursive: true });
|
|
3280
3443
|
const keyPath = getKeyPath();
|
|
3281
|
-
|
|
3282
|
-
|
|
3444
|
+
const machineKey = deriveMachineKey();
|
|
3445
|
+
if (machineKey) {
|
|
3446
|
+
const encrypted = encryptWithMachineKey(b64, machineKey);
|
|
3447
|
+
await writeFile3(keyPath, encrypted + "\n", "utf-8");
|
|
3448
|
+
await chmod2(keyPath, 384);
|
|
3449
|
+
process.stderr.write("[keychain] Key stored encrypted (machine-bound).\n");
|
|
3450
|
+
} else {
|
|
3451
|
+
await writeFile3(keyPath, b64 + "\n", "utf-8");
|
|
3452
|
+
await chmod2(keyPath, 384);
|
|
3453
|
+
process.stderr.write(
|
|
3454
|
+
"[keychain] WARNING: Key stored in plaintext file \u2014 no OS keychain available.\n"
|
|
3455
|
+
);
|
|
3456
|
+
}
|
|
3283
3457
|
}
|
|
3284
3458
|
async function deleteMasterKey() {
|
|
3459
|
+
macKeychainDelete();
|
|
3460
|
+
linuxSecretDelete();
|
|
3285
3461
|
const keytar = await tryKeytar();
|
|
3286
3462
|
if (keytar) {
|
|
3287
3463
|
try {
|
|
@@ -3323,12 +3499,13 @@ async function importMnemonic(mnemonic) {
|
|
|
3323
3499
|
const entropy = mnemonicToEntropy(trimmed);
|
|
3324
3500
|
return Buffer.from(entropy, "hex");
|
|
3325
3501
|
}
|
|
3326
|
-
var SERVICE, ACCOUNT;
|
|
3502
|
+
var SERVICE, ACCOUNT, ENCRYPTED_PREFIX;
|
|
3327
3503
|
var init_keychain = __esm({
|
|
3328
3504
|
"src/lib/keychain.ts"() {
|
|
3329
3505
|
"use strict";
|
|
3330
3506
|
SERVICE = "exe-mem";
|
|
3331
3507
|
ACCOUNT = "master-key";
|
|
3508
|
+
ENCRYPTED_PREFIX = "enc:";
|
|
3332
3509
|
}
|
|
3333
3510
|
});
|
|
3334
3511
|
|
|
@@ -4783,7 +4960,7 @@ __export(project_name_exports, {
|
|
|
4783
4960
|
_resetCache: () => _resetCache,
|
|
4784
4961
|
getProjectName: () => getProjectName
|
|
4785
4962
|
});
|
|
4786
|
-
import { execSync as
|
|
4963
|
+
import { execSync as execSync3 } from "child_process";
|
|
4787
4964
|
import path10 from "path";
|
|
4788
4965
|
function getProjectName(cwd) {
|
|
4789
4966
|
const dir = cwd ?? process.cwd();
|
|
@@ -4791,7 +4968,7 @@ function getProjectName(cwd) {
|
|
|
4791
4968
|
try {
|
|
4792
4969
|
let repoRoot;
|
|
4793
4970
|
try {
|
|
4794
|
-
const gitCommonDir =
|
|
4971
|
+
const gitCommonDir = execSync3("git rev-parse --path-format=absolute --git-common-dir", {
|
|
4795
4972
|
cwd: dir,
|
|
4796
4973
|
encoding: "utf8",
|
|
4797
4974
|
timeout: 2e3,
|
|
@@ -4799,7 +4976,7 @@ function getProjectName(cwd) {
|
|
|
4799
4976
|
}).trim();
|
|
4800
4977
|
repoRoot = path10.dirname(gitCommonDir);
|
|
4801
4978
|
} catch {
|
|
4802
|
-
repoRoot =
|
|
4979
|
+
repoRoot = execSync3("git rev-parse --show-toplevel", {
|
|
4803
4980
|
cwd: dir,
|
|
4804
4981
|
encoding: "utf8",
|
|
4805
4982
|
timeout: 2e3,
|
|
@@ -4833,14 +5010,14 @@ var file_grep_exports = {};
|
|
|
4833
5010
|
__export(file_grep_exports, {
|
|
4834
5011
|
grepProjectFiles: () => grepProjectFiles
|
|
4835
5012
|
});
|
|
4836
|
-
import { execSync as
|
|
5013
|
+
import { execSync as execSync4 } from "child_process";
|
|
4837
5014
|
import { readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync2, existsSync as existsSync10 } from "fs";
|
|
4838
5015
|
import path11 from "path";
|
|
4839
5016
|
import crypto2 from "crypto";
|
|
4840
5017
|
function hasRipgrep() {
|
|
4841
5018
|
if (_hasRg === null) {
|
|
4842
5019
|
try {
|
|
4843
|
-
|
|
5020
|
+
execSync4("rg --version", { stdio: "ignore", timeout: 2e3 });
|
|
4844
5021
|
_hasRg = true;
|
|
4845
5022
|
} catch {
|
|
4846
5023
|
_hasRg = false;
|
|
@@ -4906,7 +5083,7 @@ function grepWithRipgrep(pattern, projectRoot, patterns) {
|
|
|
4906
5083
|
const globs = (patterns ?? DEFAULT_PATTERNS).map((p) => `--glob '${p}'`).join(" ");
|
|
4907
5084
|
const excludes = EXCLUDE_DIRS.map((d) => `--glob '!${d}'`).join(" ");
|
|
4908
5085
|
const cmd = `rg -i -c --hidden --no-config --no-ignore '${pattern.replace(/'/g, "\\'")}' . ${globs} ${excludes} --max-filesize ${MAX_FILE_SIZE} 2>/dev/null || true`;
|
|
4909
|
-
const output =
|
|
5086
|
+
const output = execSync4(cmd, {
|
|
4910
5087
|
cwd: projectRoot,
|
|
4911
5088
|
encoding: "utf8",
|
|
4912
5089
|
timeout: 3e3,
|
|
@@ -4921,12 +5098,12 @@ function grepWithRipgrep(pattern, projectRoot, patterns) {
|
|
|
4921
5098
|
const matchCount = parseInt(line.slice(colonIdx + 1));
|
|
4922
5099
|
if (isNaN(matchCount) || matchCount === 0) continue;
|
|
4923
5100
|
try {
|
|
4924
|
-
const firstMatch =
|
|
5101
|
+
const firstMatch = execSync4(
|
|
4925
5102
|
`rg -i -n --hidden '${pattern.replace(/'/g, "\\'")}' '${filePath}' --max-count 1 2>/dev/null | head -1`,
|
|
4926
5103
|
{ cwd: projectRoot, encoding: "utf8", timeout: 1e3 }
|
|
4927
5104
|
).trim();
|
|
4928
5105
|
const lineNum = parseInt(firstMatch.split(":")[0] ?? "1");
|
|
4929
|
-
const totalLines =
|
|
5106
|
+
const totalLines = execSync4(`wc -l < '${filePath}'`, {
|
|
4930
5107
|
cwd: projectRoot,
|
|
4931
5108
|
encoding: "utf8",
|
|
4932
5109
|
timeout: 1e3
|
|
@@ -5555,10 +5732,17 @@ async function applyEntityBoost(results, query, client) {
|
|
|
5555
5732
|
if (ENTITY_BOOST_WEIGHT === 0 || results.length === 0) {
|
|
5556
5733
|
return emptyResult;
|
|
5557
5734
|
}
|
|
5558
|
-
|
|
5735
|
+
const debugStart = process.env.EXE_DEBUG_HOOKS ? performance.now() : 0;
|
|
5736
|
+
const debugEnd = () => {
|
|
5737
|
+
if (!process.env.EXE_DEBUG_HOOKS) return;
|
|
5738
|
+
process.stderr.write(
|
|
5739
|
+
`[entity-boost] ${(performance.now() - debugStart).toFixed(3)}ms
|
|
5740
|
+
`
|
|
5741
|
+
);
|
|
5742
|
+
};
|
|
5559
5743
|
const entities = await matchEntities(query, client);
|
|
5560
5744
|
if (entities.length === 0) {
|
|
5561
|
-
|
|
5745
|
+
debugEnd();
|
|
5562
5746
|
return emptyResult;
|
|
5563
5747
|
}
|
|
5564
5748
|
const boostMap = /* @__PURE__ */ new Map();
|
|
@@ -5580,7 +5764,7 @@ async function applyEntityBoost(results, query, client) {
|
|
|
5580
5764
|
await traverseAndScore(entities, client, boostMap, resultIds, graphContextMap);
|
|
5581
5765
|
await applyHyperedgeBoost(entities, client, boostMap, resultIds);
|
|
5582
5766
|
if (boostMap.size === 0) {
|
|
5583
|
-
|
|
5767
|
+
debugEnd();
|
|
5584
5768
|
return emptyResult;
|
|
5585
5769
|
}
|
|
5586
5770
|
const scored = results.map((r, i) => ({
|
|
@@ -5591,7 +5775,7 @@ async function applyEntityBoost(results, query, client) {
|
|
|
5591
5775
|
scored.sort(
|
|
5592
5776
|
(a, b) => b.baseScore + b.entityBoost - (a.baseScore + a.entityBoost)
|
|
5593
5777
|
);
|
|
5594
|
-
|
|
5778
|
+
debugEnd();
|
|
5595
5779
|
return {
|
|
5596
5780
|
results: scored.map((s) => s.record),
|
|
5597
5781
|
graphContext: graphContextMap
|
|
@@ -5810,10 +5994,10 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
5810
5994
|
};
|
|
5811
5995
|
try {
|
|
5812
5996
|
const fs = await import("fs");
|
|
5813
|
-
const
|
|
5997
|
+
const path45 = await import("path");
|
|
5814
5998
|
const os19 = await import("os");
|
|
5815
|
-
const logPath =
|
|
5816
|
-
fs.mkdirSync(
|
|
5999
|
+
const logPath = path45.join(os19.homedir(), ".exe-os", "search-quality.jsonl");
|
|
6000
|
+
fs.mkdirSync(path45.dirname(logPath), { recursive: true });
|
|
5817
6001
|
fs.appendFileSync(logPath, JSON.stringify(logEntry) + "\n");
|
|
5818
6002
|
} catch {
|
|
5819
6003
|
}
|
|
@@ -6236,7 +6420,7 @@ var init_hybrid_search = __esm({
|
|
|
6236
6420
|
});
|
|
6237
6421
|
|
|
6238
6422
|
// src/lib/session-key.ts
|
|
6239
|
-
import { execSync as
|
|
6423
|
+
import { execSync as execSync5 } from "child_process";
|
|
6240
6424
|
function normalizeCommand(command) {
|
|
6241
6425
|
const trimmed = command.trim().toLowerCase();
|
|
6242
6426
|
const parts = trimmed.split(/[\\/]/);
|
|
@@ -6255,7 +6439,7 @@ function resolveRuntimeProcess() {
|
|
|
6255
6439
|
let pid = process.ppid;
|
|
6256
6440
|
for (let i = 0; i < 10; i++) {
|
|
6257
6441
|
try {
|
|
6258
|
-
const info =
|
|
6442
|
+
const info = execSync5(`ps -p ${pid} -o ppid=,comm=`, {
|
|
6259
6443
|
encoding: "utf8",
|
|
6260
6444
|
timeout: 2e3
|
|
6261
6445
|
}).trim();
|
|
@@ -6314,7 +6498,7 @@ __export(active_agent_exports, {
|
|
|
6314
6498
|
writeActiveAgent: () => writeActiveAgent
|
|
6315
6499
|
});
|
|
6316
6500
|
import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3, unlinkSync as unlinkSync3, readdirSync as readdirSync3 } from "fs";
|
|
6317
|
-
import { execSync as
|
|
6501
|
+
import { execSync as execSync6 } from "child_process";
|
|
6318
6502
|
import path12 from "path";
|
|
6319
6503
|
function isNameWithOptionalInstance(candidate, baseName) {
|
|
6320
6504
|
if (candidate === baseName) return true;
|
|
@@ -6406,7 +6590,7 @@ function getActiveAgent() {
|
|
|
6406
6590
|
} catch {
|
|
6407
6591
|
}
|
|
6408
6592
|
try {
|
|
6409
|
-
const sessionName =
|
|
6593
|
+
const sessionName = execSync6(
|
|
6410
6594
|
"tmux display-message -p '#{session_name}' 2>/dev/null",
|
|
6411
6595
|
{ encoding: "utf8", timeout: 2e3 }
|
|
6412
6596
|
).trim();
|
|
@@ -6739,8 +6923,8 @@ async function validateLicense(apiKey, deviceId) {
|
|
|
6739
6923
|
}
|
|
6740
6924
|
function getCacheAgeMs() {
|
|
6741
6925
|
try {
|
|
6742
|
-
const { statSync:
|
|
6743
|
-
const s =
|
|
6926
|
+
const { statSync: statSync5 } = __require("fs");
|
|
6927
|
+
const s = statSync5(CACHE_PATH);
|
|
6744
6928
|
return Date.now() - s.mtimeMs;
|
|
6745
6929
|
} catch {
|
|
6746
6930
|
return Infinity;
|
|
@@ -7221,14 +7405,14 @@ var init_transport = __esm({
|
|
|
7221
7405
|
});
|
|
7222
7406
|
|
|
7223
7407
|
// src/lib/cc-agent-support.ts
|
|
7224
|
-
import { execSync as
|
|
7408
|
+
import { execSync as execSync7 } from "child_process";
|
|
7225
7409
|
function _resetCcAgentSupportCache() {
|
|
7226
7410
|
_cachedSupport = null;
|
|
7227
7411
|
}
|
|
7228
7412
|
function claudeSupportsAgentFlag() {
|
|
7229
7413
|
if (_cachedSupport !== null) return _cachedSupport;
|
|
7230
7414
|
try {
|
|
7231
|
-
const helpOutput =
|
|
7415
|
+
const helpOutput = execSync7("claude --help 2>&1", {
|
|
7232
7416
|
encoding: "utf-8",
|
|
7233
7417
|
timeout: 5e3
|
|
7234
7418
|
});
|
|
@@ -8101,7 +8285,7 @@ __export(tmux_routing_exports, {
|
|
|
8101
8285
|
spawnEmployee: () => spawnEmployee,
|
|
8102
8286
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
8103
8287
|
});
|
|
8104
|
-
import { execFileSync as execFileSync2, execSync as
|
|
8288
|
+
import { execFileSync as execFileSync2, execSync as execSync8 } from "child_process";
|
|
8105
8289
|
import { readFileSync as readFileSync12, writeFileSync as writeFileSync10, mkdirSync as mkdirSync7, existsSync as existsSync16, appendFileSync, readdirSync as readdirSync5 } from "fs";
|
|
8106
8290
|
import path20 from "path";
|
|
8107
8291
|
import os9 from "os";
|
|
@@ -8811,7 +8995,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
8811
8995
|
let booted = false;
|
|
8812
8996
|
for (let i = 0; i < 30; i++) {
|
|
8813
8997
|
try {
|
|
8814
|
-
|
|
8998
|
+
execSync8("sleep 0.5");
|
|
8815
8999
|
} catch {
|
|
8816
9000
|
}
|
|
8817
9001
|
try {
|
|
@@ -9058,7 +9242,7 @@ __export(tasks_crud_exports, {
|
|
|
9058
9242
|
import crypto7 from "crypto";
|
|
9059
9243
|
import path22 from "path";
|
|
9060
9244
|
import os11 from "os";
|
|
9061
|
-
import { execSync as
|
|
9245
|
+
import { execSync as execSync9 } from "child_process";
|
|
9062
9246
|
import { mkdir as mkdir4, writeFile as writeFile4, appendFile } from "fs/promises";
|
|
9063
9247
|
import { existsSync as existsSync18, readFileSync as readFileSync14 } from "fs";
|
|
9064
9248
|
async function writeCheckpoint(input) {
|
|
@@ -9403,14 +9587,14 @@ function isTmuxSessionAlive(identifier) {
|
|
|
9403
9587
|
if (!identifier || identifier === "unknown") return true;
|
|
9404
9588
|
try {
|
|
9405
9589
|
if (identifier.startsWith("%")) {
|
|
9406
|
-
const output =
|
|
9590
|
+
const output = execSync9("tmux list-panes -a -F '#{pane_id}'", {
|
|
9407
9591
|
timeout: 2e3,
|
|
9408
9592
|
encoding: "utf8",
|
|
9409
9593
|
stdio: ["pipe", "pipe", "pipe"]
|
|
9410
9594
|
});
|
|
9411
9595
|
return output.split("\n").some((l) => l.trim() === identifier);
|
|
9412
9596
|
} else {
|
|
9413
|
-
|
|
9597
|
+
execSync9(`tmux has-session -t ${JSON.stringify(identifier)}`, {
|
|
9414
9598
|
timeout: 2e3,
|
|
9415
9599
|
stdio: ["pipe", "pipe", "pipe"]
|
|
9416
9600
|
});
|
|
@@ -9419,7 +9603,7 @@ function isTmuxSessionAlive(identifier) {
|
|
|
9419
9603
|
} catch {
|
|
9420
9604
|
if (identifier.startsWith("%")) return true;
|
|
9421
9605
|
try {
|
|
9422
|
-
|
|
9606
|
+
execSync9("tmux list-sessions", {
|
|
9423
9607
|
timeout: 2e3,
|
|
9424
9608
|
stdio: ["pipe", "pipe", "pipe"]
|
|
9425
9609
|
});
|
|
@@ -9434,12 +9618,12 @@ function checkStaleCompletion(taskContext, taskCreatedAt) {
|
|
|
9434
9618
|
if (!DELEGATION_KEYWORDS.test(taskContext)) return null;
|
|
9435
9619
|
try {
|
|
9436
9620
|
const since = new Date(taskCreatedAt).toISOString();
|
|
9437
|
-
const branch =
|
|
9621
|
+
const branch = execSync9(
|
|
9438
9622
|
"git rev-parse --abbrev-ref HEAD 2>/dev/null",
|
|
9439
9623
|
{ encoding: "utf8", timeout: 3e3 }
|
|
9440
9624
|
).trim();
|
|
9441
9625
|
const branchArg = branch && branch !== "HEAD" ? branch : "";
|
|
9442
|
-
const commitCount =
|
|
9626
|
+
const commitCount = execSync9(
|
|
9443
9627
|
`git log --oneline --since="${since}" ${branchArg} 2>/dev/null | wc -l`,
|
|
9444
9628
|
{ encoding: "utf8", timeout: 5e3 }
|
|
9445
9629
|
).trim();
|
|
@@ -11668,8 +11852,8 @@ __export(wiki_client_exports, {
|
|
|
11668
11852
|
listDocuments: () => listDocuments,
|
|
11669
11853
|
listWorkspaces: () => listWorkspaces
|
|
11670
11854
|
});
|
|
11671
|
-
async function wikiFetch(config2,
|
|
11672
|
-
const url = `${config2.baseUrl}/api/v1${
|
|
11855
|
+
async function wikiFetch(config2, path45, method = "GET", body) {
|
|
11856
|
+
const url = `${config2.baseUrl}/api/v1${path45}`;
|
|
11673
11857
|
const headers = {
|
|
11674
11858
|
Authorization: `Bearer ${config2.apiKey}`,
|
|
11675
11859
|
"Content-Type": "application/json"
|
|
@@ -11702,7 +11886,7 @@ async function wikiFetch(config2, path44, method = "GET", body) {
|
|
|
11702
11886
|
}
|
|
11703
11887
|
}
|
|
11704
11888
|
if (!response.ok) {
|
|
11705
|
-
throw new Error(`Wiki API ${method} ${
|
|
11889
|
+
throw new Error(`Wiki API ${method} ${path45}: ${response.status} ${response.statusText}`);
|
|
11706
11890
|
}
|
|
11707
11891
|
return response.json();
|
|
11708
11892
|
} finally {
|
|
@@ -11911,6 +12095,109 @@ var init_worker_gate = __esm({
|
|
|
11911
12095
|
}
|
|
11912
12096
|
});
|
|
11913
12097
|
|
|
12098
|
+
// src/lib/db-backup.ts
|
|
12099
|
+
var db_backup_exports = {};
|
|
12100
|
+
__export(db_backup_exports, {
|
|
12101
|
+
createBackup: () => createBackup,
|
|
12102
|
+
findActiveDb: () => findActiveDb,
|
|
12103
|
+
getBackupDir: () => getBackupDir,
|
|
12104
|
+
getLatestBackup: () => getLatestBackup,
|
|
12105
|
+
hasBackupToday: () => hasBackupToday,
|
|
12106
|
+
listBackups: () => listBackups,
|
|
12107
|
+
rotateBackups: () => rotateBackups
|
|
12108
|
+
});
|
|
12109
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync29, mkdirSync as mkdirSync15, readdirSync as readdirSync12, unlinkSync as unlinkSync9, statSync as statSync4 } from "fs";
|
|
12110
|
+
import path37 from "path";
|
|
12111
|
+
function findActiveDb() {
|
|
12112
|
+
for (const name of DB_NAMES) {
|
|
12113
|
+
const p = path37.join(EXE_AI_DIR, name);
|
|
12114
|
+
if (existsSync29(p)) return p;
|
|
12115
|
+
}
|
|
12116
|
+
return null;
|
|
12117
|
+
}
|
|
12118
|
+
function createBackup(reason = "manual") {
|
|
12119
|
+
const dbPath = findActiveDb();
|
|
12120
|
+
if (!dbPath) return null;
|
|
12121
|
+
mkdirSync15(BACKUP_DIR, { recursive: true });
|
|
12122
|
+
const dbName = path37.basename(dbPath, ".db");
|
|
12123
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
12124
|
+
const backupName = `${dbName}-${reason}-${timestamp}.db`;
|
|
12125
|
+
const backupPath = path37.join(BACKUP_DIR, backupName);
|
|
12126
|
+
copyFileSync2(dbPath, backupPath);
|
|
12127
|
+
const walPath = dbPath + "-wal";
|
|
12128
|
+
if (existsSync29(walPath)) {
|
|
12129
|
+
try {
|
|
12130
|
+
copyFileSync2(walPath, backupPath + "-wal");
|
|
12131
|
+
} catch {
|
|
12132
|
+
}
|
|
12133
|
+
}
|
|
12134
|
+
const shmPath = dbPath + "-shm";
|
|
12135
|
+
if (existsSync29(shmPath)) {
|
|
12136
|
+
try {
|
|
12137
|
+
copyFileSync2(shmPath, backupPath + "-shm");
|
|
12138
|
+
} catch {
|
|
12139
|
+
}
|
|
12140
|
+
}
|
|
12141
|
+
return backupPath;
|
|
12142
|
+
}
|
|
12143
|
+
function rotateBackups(keepDays = DEFAULT_KEEP_DAYS) {
|
|
12144
|
+
if (!existsSync29(BACKUP_DIR)) return 0;
|
|
12145
|
+
const cutoff = Date.now() - keepDays * 24 * 60 * 60 * 1e3;
|
|
12146
|
+
let deleted = 0;
|
|
12147
|
+
try {
|
|
12148
|
+
const files = readdirSync12(BACKUP_DIR);
|
|
12149
|
+
for (const file of files) {
|
|
12150
|
+
if (!file.endsWith(".db") && !file.endsWith(".db-wal") && !file.endsWith(".db-shm")) continue;
|
|
12151
|
+
const filePath = path37.join(BACKUP_DIR, file);
|
|
12152
|
+
try {
|
|
12153
|
+
const stat = statSync4(filePath);
|
|
12154
|
+
if (stat.mtimeMs < cutoff) {
|
|
12155
|
+
unlinkSync9(filePath);
|
|
12156
|
+
deleted++;
|
|
12157
|
+
}
|
|
12158
|
+
} catch {
|
|
12159
|
+
}
|
|
12160
|
+
}
|
|
12161
|
+
} catch {
|
|
12162
|
+
}
|
|
12163
|
+
return deleted;
|
|
12164
|
+
}
|
|
12165
|
+
function listBackups() {
|
|
12166
|
+
if (!existsSync29(BACKUP_DIR)) return [];
|
|
12167
|
+
try {
|
|
12168
|
+
const files = readdirSync12(BACKUP_DIR).filter((f) => f.endsWith(".db") && !f.endsWith("-wal") && !f.endsWith("-shm"));
|
|
12169
|
+
return files.map((name) => {
|
|
12170
|
+
const p = path37.join(BACKUP_DIR, name);
|
|
12171
|
+
const stat = statSync4(p);
|
|
12172
|
+
return { path: p, name, size: stat.size, date: stat.mtime };
|
|
12173
|
+
}).sort((a, b) => b.date.getTime() - a.date.getTime());
|
|
12174
|
+
} catch {
|
|
12175
|
+
return [];
|
|
12176
|
+
}
|
|
12177
|
+
}
|
|
12178
|
+
function hasBackupToday(reason) {
|
|
12179
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
12180
|
+
const backups = listBackups();
|
|
12181
|
+
return backups.some((b) => b.name.includes(reason) && b.name.includes(today.replace(/-/g, "-")));
|
|
12182
|
+
}
|
|
12183
|
+
function getLatestBackup() {
|
|
12184
|
+
const backups = listBackups();
|
|
12185
|
+
return backups.length > 0 ? backups[0].path : null;
|
|
12186
|
+
}
|
|
12187
|
+
function getBackupDir() {
|
|
12188
|
+
return BACKUP_DIR;
|
|
12189
|
+
}
|
|
12190
|
+
var BACKUP_DIR, DEFAULT_KEEP_DAYS, DB_NAMES;
|
|
12191
|
+
var init_db_backup = __esm({
|
|
12192
|
+
"src/lib/db-backup.ts"() {
|
|
12193
|
+
"use strict";
|
|
12194
|
+
init_config();
|
|
12195
|
+
BACKUP_DIR = path37.join(EXE_AI_DIR, "backups");
|
|
12196
|
+
DEFAULT_KEEP_DAYS = 3;
|
|
12197
|
+
DB_NAMES = ["memories.db", "exe-mem.db", "exe-os.db", "exe.db"];
|
|
12198
|
+
}
|
|
12199
|
+
});
|
|
12200
|
+
|
|
11914
12201
|
// src/lib/crdt-sync.ts
|
|
11915
12202
|
var crdt_sync_exports = {};
|
|
11916
12203
|
__export(crdt_sync_exports, {
|
|
@@ -11930,8 +12217,8 @@ __export(crdt_sync_exports, {
|
|
|
11930
12217
|
rebuildFromDb: () => rebuildFromDb
|
|
11931
12218
|
});
|
|
11932
12219
|
import * as Y from "yjs";
|
|
11933
|
-
import { readFileSync as readFileSync25, writeFileSync as writeFileSync19, existsSync as
|
|
11934
|
-
import
|
|
12220
|
+
import { readFileSync as readFileSync25, writeFileSync as writeFileSync19, existsSync as existsSync31, mkdirSync as mkdirSync16, unlinkSync as unlinkSync10 } from "fs";
|
|
12221
|
+
import path39 from "path";
|
|
11935
12222
|
import { homedir as homedir5 } from "os";
|
|
11936
12223
|
function getStatePath() {
|
|
11937
12224
|
return _statePathOverride ?? DEFAULT_STATE_PATH;
|
|
@@ -11943,14 +12230,14 @@ function initCrdtDoc() {
|
|
|
11943
12230
|
if (doc) return doc;
|
|
11944
12231
|
doc = new Y.Doc();
|
|
11945
12232
|
const sp = getStatePath();
|
|
11946
|
-
if (
|
|
12233
|
+
if (existsSync31(sp)) {
|
|
11947
12234
|
try {
|
|
11948
12235
|
const state = readFileSync25(sp);
|
|
11949
12236
|
Y.applyUpdate(doc, new Uint8Array(state));
|
|
11950
12237
|
} catch {
|
|
11951
12238
|
console.warn("[crdt-sync] WARN: corrupted state file, rebuilding from DB");
|
|
11952
12239
|
try {
|
|
11953
|
-
|
|
12240
|
+
unlinkSync10(sp);
|
|
11954
12241
|
} catch {
|
|
11955
12242
|
}
|
|
11956
12243
|
rebuildFromDb().catch((err) => {
|
|
@@ -12087,8 +12374,8 @@ function persistState() {
|
|
|
12087
12374
|
if (!doc) return;
|
|
12088
12375
|
try {
|
|
12089
12376
|
const sp = getStatePath();
|
|
12090
|
-
const dir =
|
|
12091
|
-
if (!
|
|
12377
|
+
const dir = path39.dirname(sp);
|
|
12378
|
+
if (!existsSync31(dir)) mkdirSync16(dir, { recursive: true });
|
|
12092
12379
|
const state = Y.encodeStateAsUpdate(doc);
|
|
12093
12380
|
writeFileSync19(sp, Buffer.from(state));
|
|
12094
12381
|
} catch {
|
|
@@ -12131,7 +12418,7 @@ var DEFAULT_STATE_PATH, _statePathOverride, doc;
|
|
|
12131
12418
|
var init_crdt_sync = __esm({
|
|
12132
12419
|
"src/lib/crdt-sync.ts"() {
|
|
12133
12420
|
"use strict";
|
|
12134
|
-
DEFAULT_STATE_PATH =
|
|
12421
|
+
DEFAULT_STATE_PATH = path39.join(homedir5(), ".exe-os", "crdt-state.bin");
|
|
12135
12422
|
_statePathOverride = null;
|
|
12136
12423
|
doc = null;
|
|
12137
12424
|
}
|
|
@@ -12144,8 +12431,8 @@ init_database();
|
|
|
12144
12431
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
12145
12432
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12146
12433
|
import { spawn as spawn4 } from "child_process";
|
|
12147
|
-
import { existsSync as
|
|
12148
|
-
import
|
|
12434
|
+
import { existsSync as existsSync34, openSync as openSync3, mkdirSync as mkdirSync18, closeSync as closeSync3, readFileSync as readFileSync28 } from "fs";
|
|
12435
|
+
import path44 from "path";
|
|
12149
12436
|
import os18 from "os";
|
|
12150
12437
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
12151
12438
|
|
|
@@ -12832,10 +13119,10 @@ function registerCreateTask(server2) {
|
|
|
12832
13119
|
skipDispatch: true
|
|
12833
13120
|
});
|
|
12834
13121
|
try {
|
|
12835
|
-
const { existsSync:
|
|
13122
|
+
const { existsSync: existsSync35, mkdirSync: mkdirSync19, writeFileSync: writeFileSync21 } = await import("fs");
|
|
12836
13123
|
const { identityPath: identityPath2 } = await Promise.resolve().then(() => (init_identity(), identity_exports));
|
|
12837
13124
|
const idPath = identityPath2(assigned_to);
|
|
12838
|
-
if (!
|
|
13125
|
+
if (!existsSync35(idPath)) {
|
|
12839
13126
|
const { loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
12840
13127
|
const employees = await loadEmployees2();
|
|
12841
13128
|
const emp = employees.find((e) => e.name === assigned_to);
|
|
@@ -12844,7 +13131,7 @@ function registerCreateTask(server2) {
|
|
|
12844
13131
|
const template = getTemplateForTitle2(emp.role);
|
|
12845
13132
|
if (template) {
|
|
12846
13133
|
const dir = (await import("path")).dirname(idPath);
|
|
12847
|
-
if (!
|
|
13134
|
+
if (!existsSync35(dir)) mkdirSync19(dir, { recursive: true });
|
|
12848
13135
|
writeFileSync21(idPath, template.replace(/^agent_id: \w+/m, `agent_id: ${assigned_to}`), "utf-8");
|
|
12849
13136
|
}
|
|
12850
13137
|
}
|
|
@@ -14747,7 +15034,7 @@ function isScheduledTrigger(trigger) {
|
|
|
14747
15034
|
init_database();
|
|
14748
15035
|
init_store();
|
|
14749
15036
|
import crypto13 from "crypto";
|
|
14750
|
-
import { execSync as
|
|
15037
|
+
import { execSync as execSync10 } from "child_process";
|
|
14751
15038
|
var CRON_FIELD = /^[\d*/,\-]+$/;
|
|
14752
15039
|
function isValidCron(cron) {
|
|
14753
15040
|
const fields = cron.trim().split(/\s+/);
|
|
@@ -14873,7 +15160,7 @@ function addToCrontab(id, cron, prompt, projectDir) {
|
|
|
14873
15160
|
const cwd = projectDir ? `cd ${JSON.stringify(projectDir)} && ` : "";
|
|
14874
15161
|
const escapedPrompt = prompt.replace(/"/g, '\\"');
|
|
14875
15162
|
const entry = `${cron} ${cwd}claude -p --dangerously-skip-permissions "${escapedPrompt}" # exe-schedule:${id}`;
|
|
14876
|
-
|
|
15163
|
+
execSync10(
|
|
14877
15164
|
`(crontab -l 2>/dev/null; echo ${JSON.stringify(entry)}) | crontab -`,
|
|
14878
15165
|
{ timeout: 5e3, stdio: "ignore" }
|
|
14879
15166
|
);
|
|
@@ -16238,9 +16525,9 @@ var HostingerApiClient = class {
|
|
|
16238
16525
|
}
|
|
16239
16526
|
this.lastRequestTime = Date.now();
|
|
16240
16527
|
}
|
|
16241
|
-
async request(method,
|
|
16528
|
+
async request(method, path45, body) {
|
|
16242
16529
|
await this.rateLimit();
|
|
16243
|
-
const url = `${this.baseUrl}${
|
|
16530
|
+
const url = `${this.baseUrl}${path45}`;
|
|
16244
16531
|
const headers = {
|
|
16245
16532
|
Authorization: `Bearer ${this.apiKey}`,
|
|
16246
16533
|
"Content-Type": "application/json",
|
|
@@ -16313,8 +16600,8 @@ async function requestCloudflare(cfApiToken, zoneId, options) {
|
|
|
16313
16600
|
}
|
|
16314
16601
|
return envelope.result;
|
|
16315
16602
|
}
|
|
16316
|
-
function buildUrl(zoneId,
|
|
16317
|
-
const normalizedPath =
|
|
16603
|
+
function buildUrl(zoneId, path45 = "/dns_records", query) {
|
|
16604
|
+
const normalizedPath = path45.startsWith("/") ? path45 : `/${path45}`;
|
|
16318
16605
|
const url = new URL(
|
|
16319
16606
|
`${CLOUDFLARE_API_BASE_URL}/zones/${zoneId}${normalizedPath}`
|
|
16320
16607
|
);
|
|
@@ -18934,12 +19221,12 @@ function registerExportGraph(server2) {
|
|
|
18934
19221
|
}
|
|
18935
19222
|
const html = await exportGraphHTML(client);
|
|
18936
19223
|
const fs = await import("fs");
|
|
18937
|
-
const
|
|
19224
|
+
const path45 = await import("path");
|
|
18938
19225
|
const os19 = await import("os");
|
|
18939
|
-
const outDir =
|
|
19226
|
+
const outDir = path45.join(os19.homedir(), ".exe-os", "exports");
|
|
18940
19227
|
fs.mkdirSync(outDir, { recursive: true });
|
|
18941
19228
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
18942
|
-
const filePath =
|
|
19229
|
+
const filePath = path45.join(outDir, `graph-${timestamp}.html`);
|
|
18943
19230
|
fs.writeFileSync(filePath, html, "utf-8");
|
|
18944
19231
|
return {
|
|
18945
19232
|
content: [
|
|
@@ -19248,7 +19535,7 @@ import { z as z60 } from "zod";
|
|
|
19248
19535
|
init_tmux_routing();
|
|
19249
19536
|
init_task_scope();
|
|
19250
19537
|
init_employees();
|
|
19251
|
-
import { execSync as
|
|
19538
|
+
import { execSync as execSync11 } from "child_process";
|
|
19252
19539
|
import { existsSync as existsSync26, readFileSync as readFileSync23, writeFileSync as writeFileSync17 } from "fs";
|
|
19253
19540
|
import { homedir as homedir4 } from "os";
|
|
19254
19541
|
import { join as join2 } from "path";
|
|
@@ -19448,9 +19735,9 @@ function isMainModule(importMetaUrl) {
|
|
|
19448
19735
|
}
|
|
19449
19736
|
|
|
19450
19737
|
// src/bin/exe-doctor.ts
|
|
19451
|
-
import { existsSync as
|
|
19738
|
+
import { existsSync as existsSync30, readFileSync as readFileSync24 } from "fs";
|
|
19452
19739
|
import { spawn as spawn2 } from "child_process";
|
|
19453
|
-
import
|
|
19740
|
+
import path38 from "path";
|
|
19454
19741
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
19455
19742
|
|
|
19456
19743
|
// src/lib/conflict-detector.ts
|
|
@@ -19854,7 +20141,7 @@ async function auditOrphanedProjects(client) {
|
|
|
19854
20141
|
for (const row of result.rows) {
|
|
19855
20142
|
const name = row.project_name;
|
|
19856
20143
|
const count = Number(row.cnt);
|
|
19857
|
-
const exists =
|
|
20144
|
+
const exists = existsSync30(path38.join(home, name)) || existsSync30(path38.join(home, "..", name)) || existsSync30(path38.join(process.cwd(), "..", name));
|
|
19858
20145
|
if (!exists) {
|
|
19859
20146
|
orphans.push({ project_name: name, count });
|
|
19860
20147
|
}
|
|
@@ -19862,13 +20149,13 @@ async function auditOrphanedProjects(client) {
|
|
|
19862
20149
|
return orphans;
|
|
19863
20150
|
}
|
|
19864
20151
|
function auditHookHealth() {
|
|
19865
|
-
const logPath =
|
|
20152
|
+
const logPath = path38.join(
|
|
19866
20153
|
process.env.HOME ?? process.env.USERPROFILE ?? "",
|
|
19867
20154
|
".exe-os",
|
|
19868
20155
|
"logs",
|
|
19869
20156
|
"hooks.log"
|
|
19870
20157
|
);
|
|
19871
|
-
if (!
|
|
20158
|
+
if (!existsSync30(logPath)) {
|
|
19872
20159
|
return { logExists: false, totalLines: 0, errorsLastHour: 0, topPatterns: [] };
|
|
19873
20160
|
}
|
|
19874
20161
|
let content;
|
|
@@ -20086,7 +20373,7 @@ async function fixNullVectors() {
|
|
|
20086
20373
|
}
|
|
20087
20374
|
}
|
|
20088
20375
|
const npmRoot = (await import("child_process")).execSync("npm root -g", { encoding: "utf8" }).trim();
|
|
20089
|
-
const backfillPath =
|
|
20376
|
+
const backfillPath = path38.join(npmRoot, "exe-os", "dist", "bin", "backfill-vectors.js");
|
|
20090
20377
|
return new Promise((resolve, reject) => {
|
|
20091
20378
|
const child = spawn2("node", [backfillPath], { stdio: "inherit" });
|
|
20092
20379
|
if (child.pid) registerWorkerPid2(child.pid);
|
|
@@ -20198,6 +20485,17 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
20198
20485
|
console.log(`
|
|
20199
20486
|
${mode} Applying repairs...
|
|
20200
20487
|
`);
|
|
20488
|
+
if (!flags.dryRun) {
|
|
20489
|
+
try {
|
|
20490
|
+
const { createBackup: createBackup3 } = await Promise.resolve().then(() => (init_db_backup(), db_backup_exports));
|
|
20491
|
+
const backupPath = createBackup3("pre-fix");
|
|
20492
|
+
if (backupPath) {
|
|
20493
|
+
console.log(` Backup created: ${backupPath.split("/").pop()}`);
|
|
20494
|
+
}
|
|
20495
|
+
} catch {
|
|
20496
|
+
console.log(" Warning: backup failed \u2014 proceeding with fix anyway");
|
|
20497
|
+
}
|
|
20498
|
+
}
|
|
20201
20499
|
if (report.nullVectors > 0) {
|
|
20202
20500
|
console.log(`${mode} Backfilling ${fmtNum(report.nullVectors)} null vectors...`);
|
|
20203
20501
|
if (!flags.dryRun) {
|
|
@@ -20286,9 +20584,9 @@ import { z as z63 } from "zod";
|
|
|
20286
20584
|
|
|
20287
20585
|
// src/lib/cloud-sync.ts
|
|
20288
20586
|
init_database();
|
|
20289
|
-
import { readFileSync as readFileSync26, writeFileSync as writeFileSync20, existsSync as
|
|
20587
|
+
import { readFileSync as readFileSync26, writeFileSync as writeFileSync20, existsSync as existsSync32, readdirSync as readdirSync13, mkdirSync as mkdirSync17, appendFileSync as appendFileSync2, unlinkSync as unlinkSync11, openSync as openSync2, closeSync as closeSync2 } from "fs";
|
|
20290
20588
|
import crypto17 from "crypto";
|
|
20291
|
-
import
|
|
20589
|
+
import path40 from "path";
|
|
20292
20590
|
import { homedir as homedir6 } from "os";
|
|
20293
20591
|
|
|
20294
20592
|
// src/lib/crypto.ts
|
|
@@ -20363,7 +20661,7 @@ function sqlSafe(v) {
|
|
|
20363
20661
|
}
|
|
20364
20662
|
function logError(msg) {
|
|
20365
20663
|
try {
|
|
20366
|
-
const logPath =
|
|
20664
|
+
const logPath = path40.join(homedir6(), ".exe-os", "workers.log");
|
|
20367
20665
|
appendFileSync2(logPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
|
|
20368
20666
|
`);
|
|
20369
20667
|
} catch {
|
|
@@ -20372,17 +20670,17 @@ function logError(msg) {
|
|
|
20372
20670
|
var LOCALHOST_PATTERNS = /^(localhost|127\.0\.0\.1|\[::1\])$/i;
|
|
20373
20671
|
var FETCH_TIMEOUT_MS4 = 3e4;
|
|
20374
20672
|
var PUSH_BATCH_SIZE = 5e3;
|
|
20375
|
-
var ROSTER_LOCK_PATH =
|
|
20673
|
+
var ROSTER_LOCK_PATH = path40.join(EXE_AI_DIR, "roster-merge.lock");
|
|
20376
20674
|
var LOCK_STALE_MS = 3e4;
|
|
20377
20675
|
var _pgPromise = null;
|
|
20378
20676
|
var _pgFailed = false;
|
|
20379
20677
|
function loadPgClient() {
|
|
20380
20678
|
if (_pgFailed) return null;
|
|
20381
20679
|
const postgresUrl = process.env.DATABASE_URL;
|
|
20382
|
-
const configPath =
|
|
20680
|
+
const configPath = path40.join(EXE_AI_DIR, "config.json");
|
|
20383
20681
|
let cloudPostgresUrl;
|
|
20384
20682
|
try {
|
|
20385
|
-
if (
|
|
20683
|
+
if (existsSync32(configPath)) {
|
|
20386
20684
|
const cfg = JSON.parse(readFileSync26(configPath, "utf8"));
|
|
20387
20685
|
cloudPostgresUrl = cfg.cloud?.postgresUrl;
|
|
20388
20686
|
if (cfg.cloud?.syncToPostgres === false) {
|
|
@@ -20401,8 +20699,8 @@ function loadPgClient() {
|
|
|
20401
20699
|
_pgPromise = (async () => {
|
|
20402
20700
|
const { createRequire: createRequire5 } = await import("module");
|
|
20403
20701
|
const { pathToFileURL: pathToFileURL5 } = await import("url");
|
|
20404
|
-
const exeDbRoot = process.env.EXE_DB_ROOT ??
|
|
20405
|
-
const req = createRequire5(
|
|
20702
|
+
const exeDbRoot = process.env.EXE_DB_ROOT ?? path40.join(homedir6(), "exe-db");
|
|
20703
|
+
const req = createRequire5(path40.join(exeDbRoot, "package.json"));
|
|
20406
20704
|
const entry = req.resolve("@prisma/client");
|
|
20407
20705
|
const mod = await import(pathToFileURL5(entry).href);
|
|
20408
20706
|
const Ctor = mod.PrismaClient ?? mod.default?.PrismaClient;
|
|
@@ -20455,7 +20753,7 @@ async function withRosterLock(fn) {
|
|
|
20455
20753
|
if (Date.now() - ts2 < LOCK_STALE_MS) {
|
|
20456
20754
|
throw new Error("Roster merge already in progress \u2014 another sync is running");
|
|
20457
20755
|
}
|
|
20458
|
-
|
|
20756
|
+
unlinkSync11(ROSTER_LOCK_PATH);
|
|
20459
20757
|
const fd = openSync2(ROSTER_LOCK_PATH, "wx");
|
|
20460
20758
|
closeSync2(fd);
|
|
20461
20759
|
writeFileSync20(ROSTER_LOCK_PATH, String(Date.now()));
|
|
@@ -20471,7 +20769,7 @@ async function withRosterLock(fn) {
|
|
|
20471
20769
|
return await fn();
|
|
20472
20770
|
} finally {
|
|
20473
20771
|
try {
|
|
20474
|
-
|
|
20772
|
+
unlinkSync11(ROSTER_LOCK_PATH);
|
|
20475
20773
|
} catch {
|
|
20476
20774
|
}
|
|
20477
20775
|
}
|
|
@@ -20842,13 +21140,42 @@ async function cloudSync(config2) {
|
|
|
20842
21140
|
try {
|
|
20843
21141
|
const employees = await loadEmployees();
|
|
20844
21142
|
rosterResult.employees = employees.length;
|
|
20845
|
-
const idDir =
|
|
20846
|
-
if (
|
|
20847
|
-
rosterResult.identities =
|
|
21143
|
+
const idDir = path40.join(EXE_AI_DIR, "identity");
|
|
21144
|
+
if (existsSync32(idDir)) {
|
|
21145
|
+
rosterResult.identities = readdirSync13(idDir).filter((f) => f.endsWith(".md")).length;
|
|
20848
21146
|
}
|
|
20849
21147
|
} catch {
|
|
20850
21148
|
}
|
|
20851
21149
|
const totalMemories = await countRows("SELECT COUNT(*) as cnt FROM memories WHERE status = 'active' OR status IS NULL");
|
|
21150
|
+
try {
|
|
21151
|
+
const { getLatestBackup: getLatestBackup2 } = await Promise.resolve().then(() => (init_db_backup(), db_backup_exports));
|
|
21152
|
+
const { statSync: statFile } = await import("fs");
|
|
21153
|
+
const latestBackup = getLatestBackup2();
|
|
21154
|
+
if (latestBackup) {
|
|
21155
|
+
const backupSize = statFile(latestBackup).size;
|
|
21156
|
+
const MAX_CLOUD_BACKUP_BYTES = 50 * 1024 * 1024;
|
|
21157
|
+
if (backupSize <= MAX_CLOUD_BACKUP_BYTES) {
|
|
21158
|
+
const backupData = readFileSync26(latestBackup);
|
|
21159
|
+
const deviceId = loadDeviceId() ?? "unknown";
|
|
21160
|
+
const encrypted = encryptSyncBlob(backupData);
|
|
21161
|
+
const backupRes = await fetchWithRetry(`${config2.endpoint}/sync/push-db-backup`, {
|
|
21162
|
+
method: "POST",
|
|
21163
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${config2.apiKey}` },
|
|
21164
|
+
body: JSON.stringify({
|
|
21165
|
+
device_id: deviceId,
|
|
21166
|
+
filename: path40.basename(latestBackup),
|
|
21167
|
+
blob: encrypted,
|
|
21168
|
+
size: backupData.length
|
|
21169
|
+
})
|
|
21170
|
+
});
|
|
21171
|
+
if (backupRes && !backupRes.ok) {
|
|
21172
|
+
logError(`[cloud-sync] DB backup upload failed: ${backupRes.status}`);
|
|
21173
|
+
}
|
|
21174
|
+
}
|
|
21175
|
+
}
|
|
21176
|
+
} catch (err) {
|
|
21177
|
+
logError(`[cloud-sync] DB backup upload error: ${err instanceof Error ? err.message : String(err)}`);
|
|
21178
|
+
}
|
|
20852
21179
|
return {
|
|
20853
21180
|
pushed,
|
|
20854
21181
|
pulled,
|
|
@@ -20861,10 +21188,10 @@ async function cloudSync(config2) {
|
|
|
20861
21188
|
roster: rosterResult
|
|
20862
21189
|
};
|
|
20863
21190
|
}
|
|
20864
|
-
var ROSTER_DELETIONS_PATH =
|
|
21191
|
+
var ROSTER_DELETIONS_PATH = path40.join(EXE_AI_DIR, "roster-deletions.json");
|
|
20865
21192
|
function consumeRosterDeletions() {
|
|
20866
21193
|
try {
|
|
20867
|
-
if (!
|
|
21194
|
+
if (!existsSync32(ROSTER_DELETIONS_PATH)) return [];
|
|
20868
21195
|
const deletions = JSON.parse(readFileSync26(ROSTER_DELETIONS_PATH, "utf-8"));
|
|
20869
21196
|
writeFileSync20(ROSTER_DELETIONS_PATH, "[]");
|
|
20870
21197
|
return deletions;
|
|
@@ -20873,35 +21200,35 @@ function consumeRosterDeletions() {
|
|
|
20873
21200
|
}
|
|
20874
21201
|
}
|
|
20875
21202
|
function buildRosterBlob(paths) {
|
|
20876
|
-
const rosterPath = paths?.rosterPath ??
|
|
20877
|
-
const identityDir = paths?.identityDir ??
|
|
20878
|
-
const configPath = paths?.configPath ??
|
|
21203
|
+
const rosterPath = paths?.rosterPath ?? path40.join(EXE_AI_DIR, "exe-employees.json");
|
|
21204
|
+
const identityDir = paths?.identityDir ?? path40.join(EXE_AI_DIR, "identity");
|
|
21205
|
+
const configPath = paths?.configPath ?? path40.join(EXE_AI_DIR, "config.json");
|
|
20879
21206
|
let roster = [];
|
|
20880
|
-
if (
|
|
21207
|
+
if (existsSync32(rosterPath)) {
|
|
20881
21208
|
try {
|
|
20882
21209
|
roster = JSON.parse(readFileSync26(rosterPath, "utf-8"));
|
|
20883
21210
|
} catch {
|
|
20884
21211
|
}
|
|
20885
21212
|
}
|
|
20886
21213
|
const identities = {};
|
|
20887
|
-
if (
|
|
20888
|
-
for (const file of
|
|
21214
|
+
if (existsSync32(identityDir)) {
|
|
21215
|
+
for (const file of readdirSync13(identityDir).filter((f) => f.endsWith(".md"))) {
|
|
20889
21216
|
try {
|
|
20890
|
-
identities[file] = readFileSync26(
|
|
21217
|
+
identities[file] = readFileSync26(path40.join(identityDir, file), "utf-8");
|
|
20891
21218
|
} catch {
|
|
20892
21219
|
}
|
|
20893
21220
|
}
|
|
20894
21221
|
}
|
|
20895
21222
|
let config2;
|
|
20896
|
-
if (
|
|
21223
|
+
if (existsSync32(configPath)) {
|
|
20897
21224
|
try {
|
|
20898
21225
|
config2 = JSON.parse(readFileSync26(configPath, "utf-8"));
|
|
20899
21226
|
} catch {
|
|
20900
21227
|
}
|
|
20901
21228
|
}
|
|
20902
21229
|
let agentConfig;
|
|
20903
|
-
const agentConfigPath =
|
|
20904
|
-
if (
|
|
21230
|
+
const agentConfigPath = path40.join(EXE_AI_DIR, "agent-config.json");
|
|
21231
|
+
if (existsSync32(agentConfigPath)) {
|
|
20905
21232
|
try {
|
|
20906
21233
|
agentConfig = JSON.parse(readFileSync26(agentConfigPath, "utf-8"));
|
|
20907
21234
|
} catch {
|
|
@@ -20979,16 +21306,16 @@ async function cloudPullRoster(config2) {
|
|
|
20979
21306
|
}
|
|
20980
21307
|
}
|
|
20981
21308
|
function mergeConfig(remoteConfig, configPath) {
|
|
20982
|
-
const cfgPath = configPath ??
|
|
21309
|
+
const cfgPath = configPath ?? path40.join(EXE_AI_DIR, "config.json");
|
|
20983
21310
|
let local = {};
|
|
20984
|
-
if (
|
|
21311
|
+
if (existsSync32(cfgPath)) {
|
|
20985
21312
|
try {
|
|
20986
21313
|
local = JSON.parse(readFileSync26(cfgPath, "utf-8"));
|
|
20987
21314
|
} catch {
|
|
20988
21315
|
}
|
|
20989
21316
|
}
|
|
20990
21317
|
const merged = { ...remoteConfig, ...local };
|
|
20991
|
-
const dir =
|
|
21318
|
+
const dir = path40.dirname(cfgPath);
|
|
20992
21319
|
ensurePrivateDirSync(dir);
|
|
20993
21320
|
writeFileSync20(cfgPath, JSON.stringify(merged, null, 2), "utf-8");
|
|
20994
21321
|
enforcePrivateFileSync(cfgPath);
|
|
@@ -20996,7 +21323,7 @@ function mergeConfig(remoteConfig, configPath) {
|
|
|
20996
21323
|
async function mergeRosterFromRemote(remote, paths) {
|
|
20997
21324
|
return withRosterLock(async () => {
|
|
20998
21325
|
const rosterPath = paths?.rosterPath ?? void 0;
|
|
20999
|
-
const identityDir = paths?.identityDir ??
|
|
21326
|
+
const identityDir = paths?.identityDir ?? path40.join(EXE_AI_DIR, "identity");
|
|
21000
21327
|
const localEmployees = await loadEmployees(rosterPath);
|
|
21001
21328
|
const localNames = new Set(localEmployees.map((e) => e.name));
|
|
21002
21329
|
let added = 0;
|
|
@@ -21017,11 +21344,11 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
21017
21344
|
) ?? lookupKey;
|
|
21018
21345
|
const remoteIdentity = remote.identities[matchedKey];
|
|
21019
21346
|
if (remoteIdentity) {
|
|
21020
|
-
if (!
|
|
21021
|
-
const idPath =
|
|
21347
|
+
if (!existsSync32(identityDir)) mkdirSync17(identityDir, { recursive: true });
|
|
21348
|
+
const idPath = path40.join(identityDir, `${remoteEmp.name}.md`);
|
|
21022
21349
|
let localIdentity = null;
|
|
21023
21350
|
try {
|
|
21024
|
-
localIdentity =
|
|
21351
|
+
localIdentity = existsSync32(idPath) ? readFileSync26(idPath, "utf-8") : null;
|
|
21025
21352
|
} catch {
|
|
21026
21353
|
}
|
|
21027
21354
|
if (localIdentity !== remoteIdentity) {
|
|
@@ -21051,16 +21378,16 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
21051
21378
|
}
|
|
21052
21379
|
if (remote.agentConfig && Object.keys(remote.agentConfig).length > 0) {
|
|
21053
21380
|
try {
|
|
21054
|
-
const agentConfigPath =
|
|
21381
|
+
const agentConfigPath = path40.join(EXE_AI_DIR, "agent-config.json");
|
|
21055
21382
|
let local = {};
|
|
21056
|
-
if (
|
|
21383
|
+
if (existsSync32(agentConfigPath)) {
|
|
21057
21384
|
try {
|
|
21058
21385
|
local = JSON.parse(readFileSync26(agentConfigPath, "utf-8"));
|
|
21059
21386
|
} catch {
|
|
21060
21387
|
}
|
|
21061
21388
|
}
|
|
21062
21389
|
const merged = { ...remote.agentConfig, ...local };
|
|
21063
|
-
ensurePrivateDirSync(
|
|
21390
|
+
ensurePrivateDirSync(path40.dirname(agentConfigPath));
|
|
21064
21391
|
writeFileSync20(agentConfigPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
21065
21392
|
enforcePrivateFileSync(agentConfigPath);
|
|
21066
21393
|
} catch {
|
|
@@ -22024,7 +22351,7 @@ function normalizeS3Body(body) {
|
|
|
22024
22351
|
}
|
|
22025
22352
|
throw new Error("Unsupported S3 object body type");
|
|
22026
22353
|
}
|
|
22027
|
-
async function
|
|
22354
|
+
async function createBackup2(opts) {
|
|
22028
22355
|
validateEncryptionKey(opts.encryptionKey);
|
|
22029
22356
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
22030
22357
|
const key = makeBackupKey(opts.databaseUrl, new Date(timestamp));
|
|
@@ -22075,7 +22402,7 @@ async function restoreBackup(opts) {
|
|
|
22075
22402
|
const decompressed = decompress2(decryptBlob(encrypted, opts.encryptionKey));
|
|
22076
22403
|
await runProcess("pg_restore", ["--clean", "--if-exists", "-d", opts.databaseUrl], decompressed);
|
|
22077
22404
|
}
|
|
22078
|
-
async function
|
|
22405
|
+
async function listBackups2(opts) {
|
|
22079
22406
|
const s3 = makeS3Client(opts);
|
|
22080
22407
|
const objects = await listBackupObjects(s3, opts.r2Bucket, BACKUP_PREFIX);
|
|
22081
22408
|
return objects.filter((obj) => obj.key.endsWith(BACKUP_EXT)).map((obj) => ({
|
|
@@ -22085,7 +22412,7 @@ async function listBackups(opts) {
|
|
|
22085
22412
|
})).sort((a, b) => b.lastModified.localeCompare(a.lastModified));
|
|
22086
22413
|
}
|
|
22087
22414
|
async function backupHealth(opts) {
|
|
22088
|
-
const backups = await
|
|
22415
|
+
const backups = await listBackups2(opts);
|
|
22089
22416
|
if (backups.length === 0) {
|
|
22090
22417
|
return {
|
|
22091
22418
|
lastBackup: null,
|
|
@@ -22162,7 +22489,7 @@ function registerBackupVps(server2) {
|
|
|
22162
22489
|
r2AccessKeyId: input.r2AccessKeyId,
|
|
22163
22490
|
r2SecretAccessKey: input.r2SecretAccessKey
|
|
22164
22491
|
};
|
|
22165
|
-
const result = await
|
|
22492
|
+
const result = await createBackup2(options);
|
|
22166
22493
|
return {
|
|
22167
22494
|
content: [
|
|
22168
22495
|
{
|
|
@@ -22202,7 +22529,7 @@ ${result.timestamp}`
|
|
|
22202
22529
|
r2AccessKeyId: input.r2AccessKeyId,
|
|
22203
22530
|
r2SecretAccessKey: input.r2SecretAccessKey
|
|
22204
22531
|
};
|
|
22205
|
-
const result = await
|
|
22532
|
+
const result = await listBackups2(options);
|
|
22206
22533
|
return {
|
|
22207
22534
|
content: [
|
|
22208
22535
|
{
|
|
@@ -22288,11 +22615,11 @@ import { z as z68 } from "zod";
|
|
|
22288
22615
|
// src/lib/people.ts
|
|
22289
22616
|
init_config();
|
|
22290
22617
|
import { readFile as readFile5, writeFile as writeFile6, mkdir as mkdir5 } from "fs/promises";
|
|
22291
|
-
import { existsSync as
|
|
22292
|
-
import
|
|
22293
|
-
var PEOPLE_PATH =
|
|
22618
|
+
import { existsSync as existsSync33, readFileSync as readFileSync27 } from "fs";
|
|
22619
|
+
import path41 from "path";
|
|
22620
|
+
var PEOPLE_PATH = path41.join(EXE_AI_DIR, "people.json");
|
|
22294
22621
|
async function loadPeople() {
|
|
22295
|
-
if (!
|
|
22622
|
+
if (!existsSync33(PEOPLE_PATH)) return [];
|
|
22296
22623
|
try {
|
|
22297
22624
|
const raw = await readFile5(PEOPLE_PATH, "utf-8");
|
|
22298
22625
|
return JSON.parse(raw);
|
|
@@ -22301,7 +22628,7 @@ async function loadPeople() {
|
|
|
22301
22628
|
}
|
|
22302
22629
|
}
|
|
22303
22630
|
async function savePeople(people) {
|
|
22304
|
-
await mkdir5(
|
|
22631
|
+
await mkdir5(path41.dirname(PEOPLE_PATH), { recursive: true });
|
|
22305
22632
|
await writeFile6(PEOPLE_PATH, JSON.stringify(people, null, 2) + "\n", "utf-8");
|
|
22306
22633
|
}
|
|
22307
22634
|
async function addPerson(person) {
|
|
@@ -22594,7 +22921,7 @@ function registerListEmployees(server2) {
|
|
|
22594
22921
|
// src/mcp/tools/create-license.ts
|
|
22595
22922
|
init_license();
|
|
22596
22923
|
import os16 from "os";
|
|
22597
|
-
import
|
|
22924
|
+
import path42 from "path";
|
|
22598
22925
|
import { randomBytes as randomBytes2, randomUUID as randomUUID8 } from "crypto";
|
|
22599
22926
|
import { createRequire as createRequire3 } from "module";
|
|
22600
22927
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
@@ -22610,8 +22937,8 @@ function loadPrisma() {
|
|
|
22610
22937
|
if (!Ctor2) throw new Error(`No PrismaClient at ${explicitPath}`);
|
|
22611
22938
|
return new Ctor2();
|
|
22612
22939
|
}
|
|
22613
|
-
const exeDbRoot = process.env.EXE_DB_ROOT ??
|
|
22614
|
-
const req = createRequire3(
|
|
22940
|
+
const exeDbRoot = process.env.EXE_DB_ROOT ?? path42.join(os16.homedir(), "exe-db");
|
|
22941
|
+
const req = createRequire3(path42.join(exeDbRoot, "package.json"));
|
|
22615
22942
|
const entry = req.resolve("@prisma/client");
|
|
22616
22943
|
const mod = await import(pathToFileURL3(entry).href);
|
|
22617
22944
|
const Ctor = mod.PrismaClient ?? mod.default?.PrismaClient;
|
|
@@ -22686,7 +23013,7 @@ Give this key to the customer. They paste it during \`exe-os setup\`.`);
|
|
|
22686
23013
|
|
|
22687
23014
|
// src/mcp/tools/list-licenses.ts
|
|
22688
23015
|
import os17 from "os";
|
|
22689
|
-
import
|
|
23016
|
+
import path43 from "path";
|
|
22690
23017
|
import { createRequire as createRequire4 } from "module";
|
|
22691
23018
|
import { pathToFileURL as pathToFileURL4 } from "url";
|
|
22692
23019
|
import { z as z72 } from "zod";
|
|
@@ -22701,8 +23028,8 @@ function loadPrisma2() {
|
|
|
22701
23028
|
if (!Ctor2) throw new Error(`No PrismaClient at ${explicitPath}`);
|
|
22702
23029
|
return new Ctor2();
|
|
22703
23030
|
}
|
|
22704
|
-
const exeDbRoot = process.env.EXE_DB_ROOT ??
|
|
22705
|
-
const req = createRequire4(
|
|
23031
|
+
const exeDbRoot = process.env.EXE_DB_ROOT ?? path43.join(os17.homedir(), "exe-db");
|
|
23032
|
+
const req = createRequire4(path43.join(exeDbRoot, "package.json"));
|
|
22706
23033
|
const entry = req.resolve("@prisma/client");
|
|
22707
23034
|
const mod = await import(pathToFileURL4(entry).href);
|
|
22708
23035
|
const Ctor = mod.PrismaClient ?? mod.default?.PrismaClient;
|
|
@@ -22828,6 +23155,21 @@ init_config();
|
|
|
22828
23155
|
import { z as z74 } from "zod";
|
|
22829
23156
|
var FETCH_TIMEOUT_MS5 = 1e4;
|
|
22830
23157
|
var QUERY_SCOPE = z74.enum(["raw", "wiki", "memory", "gateway", "all"]);
|
|
23158
|
+
var LOCAL_GATEWAY_HTTP_HOSTS = /^(localhost|127\.0\.0\.1|::1|exe-gateway|gateway)$/i;
|
|
23159
|
+
function assertSecureGatewayUrlForToken(gatewayUrl, authToken) {
|
|
23160
|
+
if (!authToken) return;
|
|
23161
|
+
let parsed;
|
|
23162
|
+
try {
|
|
23163
|
+
parsed = new URL(gatewayUrl);
|
|
23164
|
+
} catch {
|
|
23165
|
+
return;
|
|
23166
|
+
}
|
|
23167
|
+
if (parsed.protocol === "https:") return;
|
|
23168
|
+
if (parsed.protocol === "http:" && LOCAL_GATEWAY_HTTP_HOSTS.test(parsed.hostname)) return;
|
|
23169
|
+
throw new Error(
|
|
23170
|
+
`Insecure Company Brain gateway URL rejected: "${gatewayUrl}". Bearer tokens require https:// for remote hosts; plain http:// is only allowed for localhost or Docker-internal gateway services.`
|
|
23171
|
+
);
|
|
23172
|
+
}
|
|
22831
23173
|
function formatSuccess(query, scope, payload) {
|
|
22832
23174
|
const pretty = typeof payload === "string" ? payload : JSON.stringify(payload, null, 2);
|
|
22833
23175
|
return [
|
|
@@ -22866,6 +23208,19 @@ function registerQueryCompanyBrain(server2) {
|
|
|
22866
23208
|
]
|
|
22867
23209
|
};
|
|
22868
23210
|
}
|
|
23211
|
+
try {
|
|
23212
|
+
assertSecureGatewayUrlForToken(gatewayUrl, authToken);
|
|
23213
|
+
} catch (err) {
|
|
23214
|
+
return {
|
|
23215
|
+
content: [
|
|
23216
|
+
{
|
|
23217
|
+
type: "text",
|
|
23218
|
+
text: err instanceof Error ? err.message : String(err)
|
|
23219
|
+
}
|
|
23220
|
+
],
|
|
23221
|
+
isError: true
|
|
23222
|
+
};
|
|
23223
|
+
}
|
|
22869
23224
|
let url;
|
|
22870
23225
|
try {
|
|
22871
23226
|
url = new URL("/query", gatewayUrl);
|
|
@@ -22982,6 +23337,138 @@ function instrumentServer(server2) {
|
|
|
22982
23337
|
};
|
|
22983
23338
|
}
|
|
22984
23339
|
|
|
23340
|
+
// src/mcp/tool-gates.ts
|
|
23341
|
+
var TOOL_GATES = {
|
|
23342
|
+
core: [],
|
|
23343
|
+
// all agents — recall, store, ask_team, commit, search, session, consolidate, cardinality, behavior, identity, decisions
|
|
23344
|
+
tasks: [],
|
|
23345
|
+
// all agents — create, list, get, update, close, checkpoint, resume
|
|
23346
|
+
comms: [],
|
|
23347
|
+
// all agents — send_message, acknowledge
|
|
23348
|
+
reminders: [],
|
|
23349
|
+
// all agents — create, list, complete, reminder
|
|
23350
|
+
"graph-read": [],
|
|
23351
|
+
// all agents — query_relationships, get_entity_neighbors, get_hot_entities, get_graph_stats, find_similar_trajectories
|
|
23352
|
+
"graph-write": ["COO", "CTO"],
|
|
23353
|
+
// merge_entities, export_graph
|
|
23354
|
+
wiki: ["COO", "Wiki Agent"],
|
|
23355
|
+
// create/list/get/update wiki pages
|
|
23356
|
+
crm: ["COO", "CRM Agent"],
|
|
23357
|
+
// add/list/get person
|
|
23358
|
+
documents: ["COO", "CTO", "Wiki Agent"],
|
|
23359
|
+
// ingest, list, purge, set_importance, rerank
|
|
23360
|
+
gateway: ["COO", "Gateway Agent"],
|
|
23361
|
+
// send_whatsapp, query_conversations, query_company_brain
|
|
23362
|
+
admin: ["COO"],
|
|
23363
|
+
// deploy, backup, daemon health, auto-wake, worker gate, memory audit, consolidation, cloud sync, agent config, list employees, agent spend, sessions, session kills
|
|
23364
|
+
licensing: ["COO"],
|
|
23365
|
+
// get/create/list/activate license
|
|
23366
|
+
orchestration: ["COO"]
|
|
23367
|
+
// triggers, load_skill, starter_pack, export/import orchestration, global procedures
|
|
23368
|
+
};
|
|
23369
|
+
var TOOL_CATEGORIES = {
|
|
23370
|
+
// core
|
|
23371
|
+
registerRecallMyMemory: "core",
|
|
23372
|
+
registerAskTeamMemory: "core",
|
|
23373
|
+
registerGetSessionContext: "core",
|
|
23374
|
+
registerStoreMemory: "core",
|
|
23375
|
+
registerCommitMemory: "core",
|
|
23376
|
+
registerSearchEverything: "core",
|
|
23377
|
+
registerConsolidateMemories: "core",
|
|
23378
|
+
registerGetMemoryCardinality: "core",
|
|
23379
|
+
registerStoreBehavior: "core",
|
|
23380
|
+
registerListBehaviors: "core",
|
|
23381
|
+
registerDeactivateBehavior: "core",
|
|
23382
|
+
registerBehavior: "core",
|
|
23383
|
+
registerStoreDecision: "core",
|
|
23384
|
+
registerGetDecision: "core",
|
|
23385
|
+
registerGetIdentity: "core",
|
|
23386
|
+
registerUpdateIdentity: "core",
|
|
23387
|
+
// tasks
|
|
23388
|
+
registerCreateTask: "tasks",
|
|
23389
|
+
registerListTasks: "tasks",
|
|
23390
|
+
registerUpdateTask: "tasks",
|
|
23391
|
+
registerCloseTask: "tasks",
|
|
23392
|
+
registerGetTask: "tasks",
|
|
23393
|
+
registerCheckpointTask: "tasks",
|
|
23394
|
+
registerResumeEmployee: "tasks",
|
|
23395
|
+
// comms
|
|
23396
|
+
registerSendMessage: "comms",
|
|
23397
|
+
registerAcknowledgeMessages: "comms",
|
|
23398
|
+
// reminders
|
|
23399
|
+
registerCreateReminder: "reminders",
|
|
23400
|
+
registerListReminders: "reminders",
|
|
23401
|
+
registerCompleteReminder: "reminders",
|
|
23402
|
+
registerReminder: "reminders",
|
|
23403
|
+
// graph-read
|
|
23404
|
+
registerQueryRelationships: "graph-read",
|
|
23405
|
+
registerGetEntityNeighbors: "graph-read",
|
|
23406
|
+
registerGetHotEntities: "graph-read",
|
|
23407
|
+
registerGetGraphStats: "graph-read",
|
|
23408
|
+
registerFindSimilarTrajectories: "graph-read",
|
|
23409
|
+
// graph-write
|
|
23410
|
+
registerMergeEntities: "graph-write",
|
|
23411
|
+
registerExportGraph: "graph-write",
|
|
23412
|
+
// wiki
|
|
23413
|
+
registerCreateWikiPage: "wiki",
|
|
23414
|
+
registerListWikiPages: "wiki",
|
|
23415
|
+
registerGetWikiPage: "wiki",
|
|
23416
|
+
registerUpdateWikiPage: "wiki",
|
|
23417
|
+
// crm
|
|
23418
|
+
registerAddPerson: "crm",
|
|
23419
|
+
registerListPeople: "crm",
|
|
23420
|
+
registerGetPerson: "crm",
|
|
23421
|
+
// documents
|
|
23422
|
+
registerIngestDocument: "documents",
|
|
23423
|
+
registerListDocuments: "documents",
|
|
23424
|
+
registerPurgeDocument: "documents",
|
|
23425
|
+
registerSetDocumentImportance: "documents",
|
|
23426
|
+
registerRerankDocuments: "documents",
|
|
23427
|
+
// gateway
|
|
23428
|
+
registerSendWhatsapp: "gateway",
|
|
23429
|
+
registerQueryConversations: "gateway",
|
|
23430
|
+
registerQueryCompanyBrain: "gateway",
|
|
23431
|
+
// admin
|
|
23432
|
+
registerDeployClient: "admin",
|
|
23433
|
+
registerBackupVps: "admin",
|
|
23434
|
+
registerGetDaemonHealth: "admin",
|
|
23435
|
+
registerGetAutoWakeStatus: "admin",
|
|
23436
|
+
registerGetWorkerGate: "admin",
|
|
23437
|
+
registerRunMemoryAudit: "admin",
|
|
23438
|
+
registerRunConsolidation: "admin",
|
|
23439
|
+
registerCloudSync: "admin",
|
|
23440
|
+
registerSetAgentConfig: "admin",
|
|
23441
|
+
registerListEmployees: "admin",
|
|
23442
|
+
registerGetAgentSpend: "admin",
|
|
23443
|
+
registerListAgentSessions: "admin",
|
|
23444
|
+
registerGetSessionKills: "admin",
|
|
23445
|
+
// licensing
|
|
23446
|
+
registerGetLicenseStatus: "licensing",
|
|
23447
|
+
registerCreateLicense: "licensing",
|
|
23448
|
+
registerListLicenses: "licensing",
|
|
23449
|
+
registerActivateLicense: "licensing",
|
|
23450
|
+
// orchestration
|
|
23451
|
+
registerCreateTrigger: "orchestration",
|
|
23452
|
+
registerListTriggers: "orchestration",
|
|
23453
|
+
registerApplyStarterPack: "orchestration",
|
|
23454
|
+
registerLoadSkill: "orchestration",
|
|
23455
|
+
registerExportOrchestration: "orchestration",
|
|
23456
|
+
registerImportOrchestration: "orchestration",
|
|
23457
|
+
registerGlobalProcedure: "orchestration",
|
|
23458
|
+
registerStoreGlobalProcedure: "orchestration",
|
|
23459
|
+
registerListGlobalProcedures: "orchestration",
|
|
23460
|
+
registerDeactivateGlobalProcedure: "orchestration"
|
|
23461
|
+
};
|
|
23462
|
+
function isToolAllowed(registerFnName) {
|
|
23463
|
+
const role = process.env.AGENT_ROLE;
|
|
23464
|
+
if (!role) return true;
|
|
23465
|
+
const category = TOOL_CATEGORIES[registerFnName];
|
|
23466
|
+
if (!category) return true;
|
|
23467
|
+
const allowedRoles = TOOL_GATES[category];
|
|
23468
|
+
if (!allowedRoles || allowedRoles.length === 0) return true;
|
|
23469
|
+
return allowedRoles.includes(role);
|
|
23470
|
+
}
|
|
23471
|
+
|
|
22985
23472
|
// src/mcp/server.ts
|
|
22986
23473
|
var server = new McpServer({
|
|
22987
23474
|
name: "exe-os",
|
|
@@ -22991,84 +23478,90 @@ var _backfillTimer = null;
|
|
|
22991
23478
|
var _ppidWatchdog = null;
|
|
22992
23479
|
var _shuttingDown = false;
|
|
22993
23480
|
instrumentServer(server);
|
|
22994
|
-
|
|
22995
|
-
|
|
22996
|
-
|
|
22997
|
-
|
|
22998
|
-
|
|
22999
|
-
|
|
23000
|
-
|
|
23001
|
-
|
|
23002
|
-
|
|
23003
|
-
|
|
23004
|
-
|
|
23005
|
-
|
|
23006
|
-
|
|
23007
|
-
|
|
23008
|
-
|
|
23009
|
-
|
|
23010
|
-
|
|
23011
|
-
|
|
23012
|
-
|
|
23013
|
-
|
|
23014
|
-
|
|
23015
|
-
|
|
23016
|
-
|
|
23017
|
-
|
|
23018
|
-
|
|
23019
|
-
|
|
23020
|
-
|
|
23021
|
-
|
|
23022
|
-
|
|
23023
|
-
|
|
23024
|
-
|
|
23025
|
-
|
|
23026
|
-
|
|
23027
|
-
|
|
23028
|
-
|
|
23029
|
-
|
|
23030
|
-
|
|
23031
|
-
|
|
23032
|
-
|
|
23033
|
-
|
|
23034
|
-
|
|
23035
|
-
|
|
23036
|
-
|
|
23037
|
-
|
|
23038
|
-
|
|
23039
|
-
|
|
23040
|
-
|
|
23041
|
-
|
|
23042
|
-
|
|
23043
|
-
|
|
23044
|
-
|
|
23045
|
-
|
|
23046
|
-
|
|
23047
|
-
|
|
23048
|
-
|
|
23049
|
-
|
|
23050
|
-
|
|
23051
|
-
|
|
23052
|
-
|
|
23053
|
-
|
|
23054
|
-
|
|
23055
|
-
|
|
23056
|
-
|
|
23057
|
-
|
|
23058
|
-
|
|
23059
|
-
|
|
23060
|
-
|
|
23061
|
-
|
|
23062
|
-
|
|
23063
|
-
|
|
23064
|
-
|
|
23065
|
-
|
|
23066
|
-
|
|
23067
|
-
|
|
23068
|
-
|
|
23069
|
-
|
|
23070
|
-
|
|
23071
|
-
|
|
23481
|
+
var gate = (name, fn) => {
|
|
23482
|
+
if (isToolAllowed(name)) fn(server);
|
|
23483
|
+
};
|
|
23484
|
+
gate("registerRecallMyMemory", registerRecallMyMemory);
|
|
23485
|
+
gate("registerAskTeamMemory", registerAskTeamMemory);
|
|
23486
|
+
gate("registerGetSessionContext", registerGetSessionContext);
|
|
23487
|
+
gate("registerStoreMemory", registerStoreMemory);
|
|
23488
|
+
gate("registerCommitMemory", registerCommitMemory);
|
|
23489
|
+
gate("registerQueryRelationships", registerQueryRelationships);
|
|
23490
|
+
gate("registerCreateTask", registerCreateTask);
|
|
23491
|
+
gate("registerListTasks", registerListTasks);
|
|
23492
|
+
gate("registerUpdateTask", registerUpdateTask);
|
|
23493
|
+
gate("registerCloseTask", registerCloseTask);
|
|
23494
|
+
gate("registerGetTask", registerGetTask);
|
|
23495
|
+
gate("registerCheckpointTask", registerCheckpointTask);
|
|
23496
|
+
gate("registerResumeEmployee", registerResumeEmployee);
|
|
23497
|
+
gate("registerBehavior", registerBehavior);
|
|
23498
|
+
gate("registerSendMessage", registerSendMessage);
|
|
23499
|
+
gate("registerReminder", registerReminder);
|
|
23500
|
+
gate("registerGetIdentity", registerGetIdentity);
|
|
23501
|
+
gate("registerUpdateIdentity", registerUpdateIdentity);
|
|
23502
|
+
gate("registerIngestDocument", registerIngestDocument);
|
|
23503
|
+
gate("registerListDocuments", registerListDocuments);
|
|
23504
|
+
gate("registerPurgeDocument", registerPurgeDocument);
|
|
23505
|
+
gate("registerSetDocumentImportance", registerSetDocumentImportance);
|
|
23506
|
+
gate("registerRerankDocuments", registerRerankDocuments);
|
|
23507
|
+
gate("registerAcknowledgeMessages", registerAcknowledgeMessages);
|
|
23508
|
+
gate("registerSendWhatsapp", registerSendWhatsapp);
|
|
23509
|
+
gate("registerCreateTrigger", registerCreateTrigger);
|
|
23510
|
+
gate("registerListTriggers", registerListTriggers);
|
|
23511
|
+
gate("registerApplyStarterPack", registerApplyStarterPack);
|
|
23512
|
+
gate("registerMergeEntities", registerMergeEntities);
|
|
23513
|
+
gate("registerCreateWikiPage", registerCreateWikiPage);
|
|
23514
|
+
gate("registerListWikiPages", registerListWikiPages);
|
|
23515
|
+
gate("registerGetWikiPage", registerGetWikiPage);
|
|
23516
|
+
gate("registerUpdateWikiPage", registerUpdateWikiPage);
|
|
23517
|
+
gate("registerDeployClient", registerDeployClient);
|
|
23518
|
+
gate("registerExportOrchestration", registerExportOrchestration);
|
|
23519
|
+
gate("registerImportOrchestration", registerImportOrchestration);
|
|
23520
|
+
gate("registerQueryConversations", registerQueryConversations);
|
|
23521
|
+
gate("registerLoadSkill", registerLoadSkill);
|
|
23522
|
+
gate("registerConsolidateMemories", registerConsolidateMemories);
|
|
23523
|
+
gate("registerGlobalProcedure", registerGlobalProcedure);
|
|
23524
|
+
gate("registerStoreGlobalProcedure", registerStoreGlobalProcedure);
|
|
23525
|
+
gate("registerListGlobalProcedures", registerListGlobalProcedures);
|
|
23526
|
+
gate("registerDeactivateGlobalProcedure", registerDeactivateGlobalProcedure);
|
|
23527
|
+
gate("registerStoreBehavior", registerStoreBehavior);
|
|
23528
|
+
gate("registerListBehaviors", registerListBehaviors);
|
|
23529
|
+
gate("registerDeactivateBehavior", registerDeactivateBehavior);
|
|
23530
|
+
gate("registerCreateReminder", registerCreateReminder);
|
|
23531
|
+
gate("registerListReminders", registerListReminders);
|
|
23532
|
+
gate("registerCompleteReminder", registerCompleteReminder);
|
|
23533
|
+
gate("registerSearchEverything", registerSearchEverything);
|
|
23534
|
+
gate("registerStoreDecision", registerStoreDecision);
|
|
23535
|
+
gate("registerGetDecision", registerGetDecision);
|
|
23536
|
+
gate("registerGetAgentSpend", registerGetAgentSpend);
|
|
23537
|
+
gate("registerGetGraphStats", registerGetGraphStats);
|
|
23538
|
+
gate("registerGetEntityNeighbors", registerGetEntityNeighbors);
|
|
23539
|
+
gate("registerGetHotEntities", registerGetHotEntities);
|
|
23540
|
+
gate("registerExportGraph", registerExportGraph);
|
|
23541
|
+
gate("registerFindSimilarTrajectories", registerFindSimilarTrajectories);
|
|
23542
|
+
gate("registerGetSessionKills", registerGetSessionKills);
|
|
23543
|
+
gate("registerListAgentSessions", registerListAgentSessions);
|
|
23544
|
+
gate("registerGetDaemonHealth", registerGetDaemonHealth);
|
|
23545
|
+
gate("registerGetAutoWakeStatus", registerGetAutoWakeStatus);
|
|
23546
|
+
gate("registerGetWorkerGate", registerGetWorkerGate);
|
|
23547
|
+
gate("registerRunMemoryAudit", registerRunMemoryAudit);
|
|
23548
|
+
gate("registerCloudSync", registerCloudSync);
|
|
23549
|
+
gate("registerBackupVps", registerBackupVps);
|
|
23550
|
+
gate("registerGetMemoryCardinality", registerGetMemoryCardinality);
|
|
23551
|
+
gate("registerRunConsolidation", registerRunConsolidation);
|
|
23552
|
+
gate("registerGetLicenseStatus", registerGetLicenseStatus);
|
|
23553
|
+
gate("registerAddPerson", registerAddPerson);
|
|
23554
|
+
gate("registerListPeople", registerListPeople);
|
|
23555
|
+
gate("registerGetPerson", registerGetPerson);
|
|
23556
|
+
gate("registerSetAgentConfig", registerSetAgentConfig);
|
|
23557
|
+
gate("registerListEmployees", registerListEmployees);
|
|
23558
|
+
gate("registerCreateLicense", registerCreateLicense);
|
|
23559
|
+
gate("registerListLicenses", registerListLicenses);
|
|
23560
|
+
gate("registerActivateLicense", registerActivateLicense);
|
|
23561
|
+
gate("registerQueryCompanyBrain", registerQueryCompanyBrain);
|
|
23562
|
+
var _gatedRole = process.env.AGENT_ROLE ?? "standalone";
|
|
23563
|
+
process.stderr.write(`[exe-os] Tool gating: role=${_gatedRole}
|
|
23564
|
+
`);
|
|
23072
23565
|
try {
|
|
23073
23566
|
await initStore();
|
|
23074
23567
|
process.stderr.write("[exe-os] MCP server starting...\n");
|
|
@@ -23117,15 +23610,15 @@ try {
|
|
|
23117
23610
|
}
|
|
23118
23611
|
}, 3e4);
|
|
23119
23612
|
_ppidWatchdog.unref();
|
|
23120
|
-
const MCP_VERSION_PATH =
|
|
23613
|
+
const MCP_VERSION_PATH = path44.join(os18.homedir(), ".exe-os", "mcp-version");
|
|
23121
23614
|
let _currentMcpVersion = null;
|
|
23122
23615
|
try {
|
|
23123
|
-
_currentMcpVersion =
|
|
23616
|
+
_currentMcpVersion = existsSync34(MCP_VERSION_PATH) ? readFileSync28(MCP_VERSION_PATH, "utf8").trim() : null;
|
|
23124
23617
|
} catch {
|
|
23125
23618
|
}
|
|
23126
23619
|
const _versionWatchdog = setInterval(() => {
|
|
23127
23620
|
try {
|
|
23128
|
-
if (!
|
|
23621
|
+
if (!existsSync34(MCP_VERSION_PATH)) return;
|
|
23129
23622
|
const diskVersion = readFileSync28(MCP_VERSION_PATH, "utf8").trim();
|
|
23130
23623
|
if (_currentMcpVersion && diskVersion !== _currentMcpVersion) {
|
|
23131
23624
|
process.stderr.write(
|
|
@@ -23159,14 +23652,14 @@ try {
|
|
|
23159
23652
|
`
|
|
23160
23653
|
);
|
|
23161
23654
|
const thisFile = fileURLToPath5(import.meta.url);
|
|
23162
|
-
const backfillPath =
|
|
23163
|
-
|
|
23655
|
+
const backfillPath = path44.resolve(
|
|
23656
|
+
path44.dirname(thisFile),
|
|
23164
23657
|
"../bin/backfill-vectors.js"
|
|
23165
23658
|
);
|
|
23166
|
-
if (
|
|
23659
|
+
if (existsSync34(backfillPath)) {
|
|
23167
23660
|
const { EXE_AI_DIR: exeDir } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
23168
|
-
const logPath =
|
|
23169
|
-
|
|
23661
|
+
const logPath = path44.join(exeDir, "workers.log");
|
|
23662
|
+
mkdirSync18(path44.dirname(logPath), { recursive: true });
|
|
23170
23663
|
let logFd = "ignore";
|
|
23171
23664
|
try {
|
|
23172
23665
|
logFd = openSync3(logPath, "a");
|