@askexenow/exe-os 0.9.1 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +26 -6
- package/dist/bin/exe-agent-config.js +1 -1
- package/dist/bin/exe-call.js +1 -1
- package/dist/bin/exe-new-employee.js +23 -4
- package/dist/bin/exe-settings.js +1 -1
- package/dist/bin/install.js +23 -4
- package/dist/bin/update.js +3 -2
- package/dist/hooks/prompt-submit.js +1 -1
- package/dist/lib/agent-config.js +1 -1
- package/dist/lib/exe-daemon.js +1 -1
- package/dist/mcp/server.js +657 -209
- package/package.json +1 -1
package/dist/mcp/server.js
CHANGED
|
@@ -698,10 +698,10 @@ async function disposeEmbedder() {
|
|
|
698
698
|
async function embedDirect(text) {
|
|
699
699
|
const llamaCpp = await import("node-llama-cpp");
|
|
700
700
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
701
|
-
const { existsSync:
|
|
702
|
-
const
|
|
703
|
-
const modelPath =
|
|
704
|
-
if (!
|
|
701
|
+
const { existsSync: existsSync32 } = await import("fs");
|
|
702
|
+
const path40 = await import("path");
|
|
703
|
+
const modelPath = path40.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
704
|
+
if (!existsSync32(modelPath)) {
|
|
705
705
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
706
706
|
}
|
|
707
707
|
const llama = await llamaCpp.getLlama();
|
|
@@ -6108,7 +6108,7 @@ var init_agent_config = __esm({
|
|
|
6108
6108
|
AGENT_CONFIG_PATH = path16.join(EXE_AI_DIR, "agent-config.json");
|
|
6109
6109
|
KNOWN_RUNTIMES = {
|
|
6110
6110
|
claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
|
|
6111
|
-
codex: ["gpt-5.4", "gpt-5.5", "o3", "o4-mini"],
|
|
6111
|
+
codex: ["gpt-5.4", "gpt-5.5", "gpt-5.3-codex-spark", "o3", "o4-mini"],
|
|
6112
6112
|
opencode: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4", "google/gemini-2.5-pro", "deepseek/deepseek-r3", "minimax/minimax-m2.5"]
|
|
6113
6113
|
};
|
|
6114
6114
|
RUNTIME_LABELS = {
|
|
@@ -9817,7 +9817,7 @@ __export(consolidation_exports, {
|
|
|
9817
9817
|
selectUnconsolidated: () => selectUnconsolidated,
|
|
9818
9818
|
storeConsolidation: () => storeConsolidation
|
|
9819
9819
|
});
|
|
9820
|
-
import { randomUUID as
|
|
9820
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
9821
9821
|
async function selectUnconsolidated(client, limit = 200) {
|
|
9822
9822
|
const result = await client.execute({
|
|
9823
9823
|
sql: `SELECT id, agent_id, project_name, tool_name, raw_text, timestamp
|
|
@@ -9913,7 +9913,7 @@ async function consolidateCluster(cluster, model) {
|
|
|
9913
9913
|
return textBlock?.text ?? "";
|
|
9914
9914
|
}
|
|
9915
9915
|
async function storeConsolidation(client, cluster, synthesisText, embedFn) {
|
|
9916
|
-
const consolidatedId =
|
|
9916
|
+
const consolidatedId = randomUUID6();
|
|
9917
9917
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9918
9918
|
const rawText = `CONSOLIDATION [${cluster.dateRange}, ${cluster.projectName}]:
|
|
9919
9919
|
|
|
@@ -9938,7 +9938,7 @@ ${synthesisText}`;
|
|
|
9938
9938
|
const linkStmts = sourceIds.map((sourceId) => ({
|
|
9939
9939
|
sql: `INSERT INTO consolidations (id, consolidated_memory_id, source_memory_id, created_at)
|
|
9940
9940
|
VALUES (?, ?, ?, ?)`,
|
|
9941
|
-
args: [
|
|
9941
|
+
args: [randomUUID6(), consolidatedId, sourceId, now]
|
|
9942
9942
|
}));
|
|
9943
9943
|
const placeholders = sourceIds.map(() => "?").join(",");
|
|
9944
9944
|
const markStmt = {
|
|
@@ -10184,8 +10184,8 @@ __export(wiki_client_exports, {
|
|
|
10184
10184
|
listDocuments: () => listDocuments,
|
|
10185
10185
|
listWorkspaces: () => listWorkspaces
|
|
10186
10186
|
});
|
|
10187
|
-
async function wikiFetch(config2,
|
|
10188
|
-
const url = `${config2.baseUrl}/api/v1${
|
|
10187
|
+
async function wikiFetch(config2, path40, method = "GET", body) {
|
|
10188
|
+
const url = `${config2.baseUrl}/api/v1${path40}`;
|
|
10189
10189
|
const headers = {
|
|
10190
10190
|
Authorization: `Bearer ${config2.apiKey}`,
|
|
10191
10191
|
"Content-Type": "application/json"
|
|
@@ -10218,7 +10218,7 @@ async function wikiFetch(config2, path38, method = "GET", body) {
|
|
|
10218
10218
|
}
|
|
10219
10219
|
}
|
|
10220
10220
|
if (!response.ok) {
|
|
10221
|
-
throw new Error(`Wiki API ${method} ${
|
|
10221
|
+
throw new Error(`Wiki API ${method} ${path40}: ${response.status} ${response.statusText}`);
|
|
10222
10222
|
}
|
|
10223
10223
|
return response.json();
|
|
10224
10224
|
} finally {
|
|
@@ -10327,14 +10327,14 @@ __export(worker_gate_exports, {
|
|
|
10327
10327
|
tryAcquireBackfillLock: () => tryAcquireBackfillLock,
|
|
10328
10328
|
tryAcquireWorkerSlot: () => tryAcquireWorkerSlot
|
|
10329
10329
|
});
|
|
10330
|
-
import { readdirSync as readdirSync9, writeFileSync as
|
|
10331
|
-
import
|
|
10330
|
+
import { readdirSync as readdirSync9, writeFileSync as writeFileSync17, unlinkSync as unlinkSync8, mkdirSync as mkdirSync14, existsSync as existsSync25 } from "fs";
|
|
10331
|
+
import path33 from "path";
|
|
10332
10332
|
function tryAcquireWorkerSlot() {
|
|
10333
10333
|
try {
|
|
10334
|
-
|
|
10334
|
+
mkdirSync14(WORKER_PID_DIR, { recursive: true });
|
|
10335
10335
|
const reservationId = `res-${process.pid}-${Date.now()}`;
|
|
10336
|
-
const reservationPath =
|
|
10337
|
-
|
|
10336
|
+
const reservationPath = path33.join(WORKER_PID_DIR, `${reservationId}.pid`);
|
|
10337
|
+
writeFileSync17(reservationPath, String(process.pid));
|
|
10338
10338
|
const files = readdirSync9(WORKER_PID_DIR);
|
|
10339
10339
|
let alive = 0;
|
|
10340
10340
|
for (const f of files) {
|
|
@@ -10351,7 +10351,7 @@ function tryAcquireWorkerSlot() {
|
|
|
10351
10351
|
alive++;
|
|
10352
10352
|
} catch {
|
|
10353
10353
|
try {
|
|
10354
|
-
unlinkSync8(
|
|
10354
|
+
unlinkSync8(path33.join(WORKER_PID_DIR, f));
|
|
10355
10355
|
} catch {
|
|
10356
10356
|
}
|
|
10357
10357
|
}
|
|
@@ -10374,21 +10374,21 @@ function tryAcquireWorkerSlot() {
|
|
|
10374
10374
|
}
|
|
10375
10375
|
function registerWorkerPid(pid) {
|
|
10376
10376
|
try {
|
|
10377
|
-
|
|
10378
|
-
|
|
10377
|
+
mkdirSync14(WORKER_PID_DIR, { recursive: true });
|
|
10378
|
+
writeFileSync17(path33.join(WORKER_PID_DIR, `worker-${pid}.pid`), String(pid));
|
|
10379
10379
|
} catch {
|
|
10380
10380
|
}
|
|
10381
10381
|
}
|
|
10382
10382
|
function cleanupWorkerPid() {
|
|
10383
10383
|
try {
|
|
10384
|
-
unlinkSync8(
|
|
10384
|
+
unlinkSync8(path33.join(WORKER_PID_DIR, `worker-${process.pid}.pid`));
|
|
10385
10385
|
} catch {
|
|
10386
10386
|
}
|
|
10387
10387
|
}
|
|
10388
10388
|
function tryAcquireBackfillLock() {
|
|
10389
10389
|
try {
|
|
10390
|
-
|
|
10391
|
-
if (
|
|
10390
|
+
mkdirSync14(WORKER_PID_DIR, { recursive: true });
|
|
10391
|
+
if (existsSync25(BACKFILL_LOCK)) {
|
|
10392
10392
|
try {
|
|
10393
10393
|
const pid = parseInt(
|
|
10394
10394
|
__require("fs").readFileSync(BACKFILL_LOCK, "utf8").trim(),
|
|
@@ -10404,7 +10404,7 @@ function tryAcquireBackfillLock() {
|
|
|
10404
10404
|
} catch {
|
|
10405
10405
|
}
|
|
10406
10406
|
}
|
|
10407
|
-
|
|
10407
|
+
writeFileSync17(BACKFILL_LOCK, String(process.pid));
|
|
10408
10408
|
return true;
|
|
10409
10409
|
} catch {
|
|
10410
10410
|
return true;
|
|
@@ -10421,9 +10421,9 @@ var init_worker_gate = __esm({
|
|
|
10421
10421
|
"src/lib/worker-gate.ts"() {
|
|
10422
10422
|
"use strict";
|
|
10423
10423
|
init_config();
|
|
10424
|
-
WORKER_PID_DIR =
|
|
10424
|
+
WORKER_PID_DIR = path33.join(EXE_AI_DIR, "worker-pids");
|
|
10425
10425
|
MAX_CONCURRENT_WORKERS = 3;
|
|
10426
|
-
BACKFILL_LOCK =
|
|
10426
|
+
BACKFILL_LOCK = path33.join(WORKER_PID_DIR, "backfill.lock");
|
|
10427
10427
|
}
|
|
10428
10428
|
});
|
|
10429
10429
|
|
|
@@ -10446,8 +10446,8 @@ __export(crdt_sync_exports, {
|
|
|
10446
10446
|
rebuildFromDb: () => rebuildFromDb
|
|
10447
10447
|
});
|
|
10448
10448
|
import * as Y from "yjs";
|
|
10449
|
-
import { readFileSync as
|
|
10450
|
-
import
|
|
10449
|
+
import { readFileSync as readFileSync24, writeFileSync as writeFileSync18, existsSync as existsSync28, mkdirSync as mkdirSync15, unlinkSync as unlinkSync9 } from "fs";
|
|
10450
|
+
import path36 from "path";
|
|
10451
10451
|
import { homedir as homedir5 } from "os";
|
|
10452
10452
|
function getStatePath() {
|
|
10453
10453
|
return _statePathOverride ?? DEFAULT_STATE_PATH;
|
|
@@ -10459,9 +10459,9 @@ function initCrdtDoc() {
|
|
|
10459
10459
|
if (doc) return doc;
|
|
10460
10460
|
doc = new Y.Doc();
|
|
10461
10461
|
const sp = getStatePath();
|
|
10462
|
-
if (
|
|
10462
|
+
if (existsSync28(sp)) {
|
|
10463
10463
|
try {
|
|
10464
|
-
const state =
|
|
10464
|
+
const state = readFileSync24(sp);
|
|
10465
10465
|
Y.applyUpdate(doc, new Uint8Array(state));
|
|
10466
10466
|
} catch {
|
|
10467
10467
|
console.warn("[crdt-sync] WARN: corrupted state file, rebuilding from DB");
|
|
@@ -10603,10 +10603,10 @@ function persistState() {
|
|
|
10603
10603
|
if (!doc) return;
|
|
10604
10604
|
try {
|
|
10605
10605
|
const sp = getStatePath();
|
|
10606
|
-
const dir =
|
|
10607
|
-
if (!
|
|
10606
|
+
const dir = path36.dirname(sp);
|
|
10607
|
+
if (!existsSync28(dir)) mkdirSync15(dir, { recursive: true });
|
|
10608
10608
|
const state = Y.encodeStateAsUpdate(doc);
|
|
10609
|
-
|
|
10609
|
+
writeFileSync18(sp, Buffer.from(state));
|
|
10610
10610
|
} catch {
|
|
10611
10611
|
}
|
|
10612
10612
|
}
|
|
@@ -10647,7 +10647,7 @@ var DEFAULT_STATE_PATH, _statePathOverride, doc;
|
|
|
10647
10647
|
var init_crdt_sync = __esm({
|
|
10648
10648
|
"src/lib/crdt-sync.ts"() {
|
|
10649
10649
|
"use strict";
|
|
10650
|
-
DEFAULT_STATE_PATH =
|
|
10650
|
+
DEFAULT_STATE_PATH = path36.join(homedir5(), ".exe-os", "crdt-state.bin");
|
|
10651
10651
|
_statePathOverride = null;
|
|
10652
10652
|
doc = null;
|
|
10653
10653
|
}
|
|
@@ -10660,8 +10660,8 @@ init_database();
|
|
|
10660
10660
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10661
10661
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
10662
10662
|
import { spawn as spawn3 } from "child_process";
|
|
10663
|
-
import { existsSync as
|
|
10664
|
-
import
|
|
10663
|
+
import { existsSync as existsSync31, openSync as openSync3, mkdirSync as mkdirSync17, closeSync as closeSync3 } from "fs";
|
|
10664
|
+
import path39 from "path";
|
|
10665
10665
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
10666
10666
|
|
|
10667
10667
|
// src/mcp/tools/recall-my-memory.ts
|
|
@@ -11331,10 +11331,10 @@ function registerCreateTask(server2) {
|
|
|
11331
11331
|
skipDispatch: true
|
|
11332
11332
|
});
|
|
11333
11333
|
try {
|
|
11334
|
-
const { existsSync:
|
|
11334
|
+
const { existsSync: existsSync32, mkdirSync: mkdirSync18, writeFileSync: writeFileSync20 } = await import("fs");
|
|
11335
11335
|
const { identityPath: identityPath2 } = await Promise.resolve().then(() => (init_identity(), identity_exports));
|
|
11336
11336
|
const idPath = identityPath2(assigned_to);
|
|
11337
|
-
if (!
|
|
11337
|
+
if (!existsSync32(idPath)) {
|
|
11338
11338
|
const { loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
11339
11339
|
const employees = await loadEmployees2();
|
|
11340
11340
|
const emp = employees.find((e) => e.name === assigned_to);
|
|
@@ -11343,8 +11343,8 @@ function registerCreateTask(server2) {
|
|
|
11343
11343
|
const template = getTemplateForTitle2(emp.role);
|
|
11344
11344
|
if (template) {
|
|
11345
11345
|
const dir = (await import("path")).dirname(idPath);
|
|
11346
|
-
if (!
|
|
11347
|
-
|
|
11346
|
+
if (!existsSync32(dir)) mkdirSync18(dir, { recursive: true });
|
|
11347
|
+
writeFileSync20(idPath, template.replace(/^agent_id: \w+/m, `agent_id: ${assigned_to}`), "utf-8");
|
|
11348
11348
|
}
|
|
11349
11349
|
}
|
|
11350
11350
|
}
|
|
@@ -14689,9 +14689,9 @@ var HostingerApiClient = class {
|
|
|
14689
14689
|
}
|
|
14690
14690
|
this.lastRequestTime = Date.now();
|
|
14691
14691
|
}
|
|
14692
|
-
async request(method,
|
|
14692
|
+
async request(method, path40, body) {
|
|
14693
14693
|
await this.rateLimit();
|
|
14694
|
-
const url = `${this.baseUrl}${
|
|
14694
|
+
const url = `${this.baseUrl}${path40}`;
|
|
14695
14695
|
const headers = {
|
|
14696
14696
|
Authorization: `Bearer ${this.apiKey}`,
|
|
14697
14697
|
"Content-Type": "application/json",
|
|
@@ -14764,8 +14764,8 @@ async function requestCloudflare(cfApiToken, zoneId, options) {
|
|
|
14764
14764
|
}
|
|
14765
14765
|
return envelope.result;
|
|
14766
14766
|
}
|
|
14767
|
-
function buildUrl(zoneId,
|
|
14768
|
-
const normalizedPath =
|
|
14767
|
+
function buildUrl(zoneId, path40 = "/dns_records", query) {
|
|
14768
|
+
const normalizedPath = path40.startsWith("/") ? path40 : `/${path40}`;
|
|
14769
14769
|
const url = new URL(
|
|
14770
14770
|
`${CLOUDFLARE_API_BASE_URL}/zones/${zoneId}${normalizedPath}`
|
|
14771
14771
|
);
|
|
@@ -15070,9 +15070,455 @@ function buildInventoryRecord(params) {
|
|
|
15070
15070
|
};
|
|
15071
15071
|
}
|
|
15072
15072
|
|
|
15073
|
+
// src/mcp/tools/export-orchestration.ts
|
|
15074
|
+
init_active_agent();
|
|
15075
|
+
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync15 } from "fs";
|
|
15076
|
+
import path29 from "path";
|
|
15077
|
+
import { z as z38 } from "zod";
|
|
15078
|
+
|
|
15079
|
+
// src/lib/orchestration-package.ts
|
|
15080
|
+
init_database();
|
|
15081
|
+
init_identity();
|
|
15082
|
+
init_platform_procedures();
|
|
15083
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
15084
|
+
import { copyFileSync, existsSync as existsSync22, mkdirSync as mkdirSync12, readFileSync as readFileSync18, writeFileSync as writeFileSync14 } from "fs";
|
|
15085
|
+
import os11 from "os";
|
|
15086
|
+
import path28 from "path";
|
|
15087
|
+
var PACKAGE_VERSION = "1.0";
|
|
15088
|
+
var ROSTER_FILENAME = "exe-employees.json";
|
|
15089
|
+
var ROSTER_BACKUP_FILENAME = "exe-employees.json.bak";
|
|
15090
|
+
var EXE_OS_DIRNAME = ".exe-os";
|
|
15091
|
+
var DEFAULT_BEHAVIOR_PRIORITY = "p1";
|
|
15092
|
+
var DEFAULT_PROCEDURE_PRIORITY = "p0";
|
|
15093
|
+
var DEFAULT_IDENTITY_UPDATED_BY = "orchestration-import";
|
|
15094
|
+
function ensureObject(value, label) {
|
|
15095
|
+
if (value == null || Array.isArray(value) || typeof value !== "object") {
|
|
15096
|
+
throw new Error(`${label} must be an object`);
|
|
15097
|
+
}
|
|
15098
|
+
return value;
|
|
15099
|
+
}
|
|
15100
|
+
function ensureString(value, label) {
|
|
15101
|
+
if (typeof value !== "string") {
|
|
15102
|
+
throw new Error(`${label} must be a string`);
|
|
15103
|
+
}
|
|
15104
|
+
return value;
|
|
15105
|
+
}
|
|
15106
|
+
function ensureOptionalString(value, label) {
|
|
15107
|
+
if (value == null) return void 0;
|
|
15108
|
+
return ensureString(value, label);
|
|
15109
|
+
}
|
|
15110
|
+
function ensureNullableString(value, label) {
|
|
15111
|
+
if (value == null) return null;
|
|
15112
|
+
return ensureString(value, label);
|
|
15113
|
+
}
|
|
15114
|
+
function ensurePriority(value, label, fallback) {
|
|
15115
|
+
if (value == null) return fallback;
|
|
15116
|
+
if (value === "p0" || value === "p1" || value === "p2") {
|
|
15117
|
+
return value;
|
|
15118
|
+
}
|
|
15119
|
+
throw new Error(`${label} must be one of: p0, p1, p2`);
|
|
15120
|
+
}
|
|
15121
|
+
function validateRosterEntry(value, index) {
|
|
15122
|
+
const record = ensureObject(value, `roster[${index}]`);
|
|
15123
|
+
return {
|
|
15124
|
+
name: ensureString(record.name, `roster[${index}].name`),
|
|
15125
|
+
role: ensureString(record.role, `roster[${index}].role`),
|
|
15126
|
+
systemPrompt: ensureString(record.systemPrompt, `roster[${index}].systemPrompt`),
|
|
15127
|
+
createdAt: typeof record.createdAt === "string" ? record.createdAt : "",
|
|
15128
|
+
templateName: ensureOptionalString(record.templateName, `roster[${index}].templateName`),
|
|
15129
|
+
templateVersion: typeof record.templateVersion === "number" ? record.templateVersion : void 0
|
|
15130
|
+
};
|
|
15131
|
+
}
|
|
15132
|
+
function validateBehaviorEntry(value, index) {
|
|
15133
|
+
const record = ensureObject(value, `behaviors[${index}]`);
|
|
15134
|
+
return {
|
|
15135
|
+
agent_id: ensureString(record.agent_id, `behaviors[${index}].agent_id`),
|
|
15136
|
+
project_name: ensureNullableString(record.project_name, `behaviors[${index}].project_name`),
|
|
15137
|
+
domain: ensureNullableString(record.domain, `behaviors[${index}].domain`),
|
|
15138
|
+
content: ensureString(record.content, `behaviors[${index}].content`),
|
|
15139
|
+
priority: ensurePriority(record.priority, `behaviors[${index}].priority`, DEFAULT_BEHAVIOR_PRIORITY)
|
|
15140
|
+
};
|
|
15141
|
+
}
|
|
15142
|
+
function validateProcedureEntry(value, index) {
|
|
15143
|
+
const record = ensureObject(value, `procedures[${index}]`);
|
|
15144
|
+
return {
|
|
15145
|
+
title: ensureString(record.title, `procedures[${index}].title`),
|
|
15146
|
+
content: ensureString(record.content, `procedures[${index}].content`),
|
|
15147
|
+
priority: ensurePriority(record.priority, `procedures[${index}].priority`, DEFAULT_PROCEDURE_PRIORITY),
|
|
15148
|
+
domain: ensureNullableString(record.domain, `procedures[${index}].domain`)
|
|
15149
|
+
};
|
|
15150
|
+
}
|
|
15151
|
+
function getRosterPath() {
|
|
15152
|
+
return path28.join(os11.homedir(), EXE_OS_DIRNAME, ROSTER_FILENAME);
|
|
15153
|
+
}
|
|
15154
|
+
function getBackupPath() {
|
|
15155
|
+
return path28.join(os11.homedir(), EXE_OS_DIRNAME, ROSTER_BACKUP_FILENAME);
|
|
15156
|
+
}
|
|
15157
|
+
function readRosterFile() {
|
|
15158
|
+
const rosterPath = getRosterPath();
|
|
15159
|
+
if (!existsSync22(rosterPath)) return [];
|
|
15160
|
+
const raw = readFileSync18(rosterPath, "utf-8");
|
|
15161
|
+
const parsed = JSON.parse(raw);
|
|
15162
|
+
if (!Array.isArray(parsed)) {
|
|
15163
|
+
throw new Error("Roster file must contain a JSON array");
|
|
15164
|
+
}
|
|
15165
|
+
return parsed.map((entry, index) => validateRosterEntry(entry, index));
|
|
15166
|
+
}
|
|
15167
|
+
function writeRosterFile(roster) {
|
|
15168
|
+
if (roster.length === 0) {
|
|
15169
|
+
throw new Error("Refusing to write empty roster \u2014 this would delete all employees");
|
|
15170
|
+
}
|
|
15171
|
+
const rosterPath = getRosterPath();
|
|
15172
|
+
mkdirSync12(path28.dirname(rosterPath), { recursive: true });
|
|
15173
|
+
if (existsSync22(rosterPath)) {
|
|
15174
|
+
const currentRoster = readRosterFile();
|
|
15175
|
+
if (roster.length < currentRoster.length) {
|
|
15176
|
+
throw new Error(
|
|
15177
|
+
`Refusing to write roster with ${roster.length} entries \u2014 current roster has ${currentRoster.length}. Import would delete ${currentRoster.length - roster.length} employee(s). Use merge strategy instead, or add the missing entries to the package.`
|
|
15178
|
+
);
|
|
15179
|
+
}
|
|
15180
|
+
copyFileSync(rosterPath, getBackupPath());
|
|
15181
|
+
}
|
|
15182
|
+
writeFileSync14(rosterPath, `${JSON.stringify(roster, null, 2)}
|
|
15183
|
+
`, "utf-8");
|
|
15184
|
+
}
|
|
15185
|
+
function buildImportedRosterEntries(roster, timestamp) {
|
|
15186
|
+
return roster.map((entry) => ({
|
|
15187
|
+
name: entry.name,
|
|
15188
|
+
role: entry.role,
|
|
15189
|
+
systemPrompt: entry.systemPrompt,
|
|
15190
|
+
createdAt: timestamp,
|
|
15191
|
+
...entry.templateName != null ? { templateName: entry.templateName } : {},
|
|
15192
|
+
...entry.templateVersion != null ? { templateVersion: entry.templateVersion } : {}
|
|
15193
|
+
}));
|
|
15194
|
+
}
|
|
15195
|
+
async function insertBehaviors(behaviors, timestamp) {
|
|
15196
|
+
const client = getClient();
|
|
15197
|
+
for (const behavior of behaviors) {
|
|
15198
|
+
await client.execute({
|
|
15199
|
+
sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, priority, content, active, created_at, updated_at)
|
|
15200
|
+
VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?)`,
|
|
15201
|
+
args: [
|
|
15202
|
+
randomUUID5(),
|
|
15203
|
+
behavior.agent_id,
|
|
15204
|
+
behavior.project_name,
|
|
15205
|
+
behavior.domain,
|
|
15206
|
+
behavior.priority,
|
|
15207
|
+
behavior.content,
|
|
15208
|
+
timestamp,
|
|
15209
|
+
timestamp
|
|
15210
|
+
]
|
|
15211
|
+
});
|
|
15212
|
+
}
|
|
15213
|
+
return behaviors.length;
|
|
15214
|
+
}
|
|
15215
|
+
async function insertProcedures(procedures, timestamp, options) {
|
|
15216
|
+
const client = getClient();
|
|
15217
|
+
const skipTitles = options?.skipTitles ?? /* @__PURE__ */ new Set();
|
|
15218
|
+
let inserted = 0;
|
|
15219
|
+
for (const procedure of procedures) {
|
|
15220
|
+
if (skipTitles.has(procedure.title) || PLATFORM_PROCEDURE_TITLES.has(procedure.title)) {
|
|
15221
|
+
continue;
|
|
15222
|
+
}
|
|
15223
|
+
await client.execute({
|
|
15224
|
+
sql: `INSERT INTO global_procedures (id, title, content, priority, domain, active, created_at, updated_at)
|
|
15225
|
+
VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
|
|
15226
|
+
args: [
|
|
15227
|
+
randomUUID5(),
|
|
15228
|
+
procedure.title,
|
|
15229
|
+
procedure.content,
|
|
15230
|
+
procedure.priority,
|
|
15231
|
+
procedure.domain,
|
|
15232
|
+
timestamp,
|
|
15233
|
+
timestamp
|
|
15234
|
+
]
|
|
15235
|
+
});
|
|
15236
|
+
skipTitles.add(procedure.title);
|
|
15237
|
+
inserted += 1;
|
|
15238
|
+
}
|
|
15239
|
+
return inserted;
|
|
15240
|
+
}
|
|
15241
|
+
async function replaceBehaviorsAndProcedures(behaviors, procedures, timestamp) {
|
|
15242
|
+
const client = getClient();
|
|
15243
|
+
const existingBehaviors = await client.execute({
|
|
15244
|
+
sql: "SELECT agent_id, content FROM behaviors WHERE active = 1",
|
|
15245
|
+
args: []
|
|
15246
|
+
});
|
|
15247
|
+
const existingBehaviorKeys = new Set(
|
|
15248
|
+
existingBehaviors.rows.map((row) => `${String(row.agent_id)}::${String(row.content)}`)
|
|
15249
|
+
);
|
|
15250
|
+
const newBehaviors = behaviors.filter(
|
|
15251
|
+
(b) => !existingBehaviorKeys.has(`${b.agent_id}::${b.content}`)
|
|
15252
|
+
);
|
|
15253
|
+
const existingProcedureTitles = await getActiveProcedureTitles();
|
|
15254
|
+
return {
|
|
15255
|
+
behaviors: await insertBehaviors(newBehaviors, timestamp),
|
|
15256
|
+
procedures: await insertProcedures(procedures, timestamp, { skipTitles: existingProcedureTitles })
|
|
15257
|
+
};
|
|
15258
|
+
}
|
|
15259
|
+
async function mergeRosterEntries(importedRoster, timestamp) {
|
|
15260
|
+
const currentRoster = readRosterFile();
|
|
15261
|
+
const existingNames = new Set(currentRoster.map((entry) => entry.name.toLowerCase()));
|
|
15262
|
+
const additions = buildImportedRosterEntries(
|
|
15263
|
+
importedRoster.filter((entry) => !existingNames.has(entry.name.toLowerCase())),
|
|
15264
|
+
timestamp
|
|
15265
|
+
);
|
|
15266
|
+
if (additions.length > 0) {
|
|
15267
|
+
writeRosterFile([...currentRoster, ...additions]);
|
|
15268
|
+
}
|
|
15269
|
+
return additions.length;
|
|
15270
|
+
}
|
|
15271
|
+
async function replaceRosterEntries(importedRoster, timestamp) {
|
|
15272
|
+
const currentRoster = readRosterFile();
|
|
15273
|
+
const importedByName = new Map(
|
|
15274
|
+
buildImportedRosterEntries(importedRoster, timestamp).map((entry) => [entry.name.toLowerCase(), entry])
|
|
15275
|
+
);
|
|
15276
|
+
const merged = currentRoster.map((existing) => {
|
|
15277
|
+
const imported = importedByName.get(existing.name.toLowerCase());
|
|
15278
|
+
if (imported) {
|
|
15279
|
+
importedByName.delete(existing.name.toLowerCase());
|
|
15280
|
+
return imported;
|
|
15281
|
+
}
|
|
15282
|
+
return existing;
|
|
15283
|
+
});
|
|
15284
|
+
for (const newEntry of importedByName.values()) {
|
|
15285
|
+
merged.push(newEntry);
|
|
15286
|
+
}
|
|
15287
|
+
writeRosterFile(merged);
|
|
15288
|
+
return importedRoster.length;
|
|
15289
|
+
}
|
|
15290
|
+
async function importIdentities(identities, updatedBy) {
|
|
15291
|
+
const entries = Object.entries(identities);
|
|
15292
|
+
let imported = 0;
|
|
15293
|
+
for (const [agentId, content] of entries) {
|
|
15294
|
+
const existing = getIdentity(agentId);
|
|
15295
|
+
if (existing?.raw) {
|
|
15296
|
+
continue;
|
|
15297
|
+
}
|
|
15298
|
+
await updateIdentity(agentId, content, updatedBy);
|
|
15299
|
+
imported += 1;
|
|
15300
|
+
}
|
|
15301
|
+
return imported;
|
|
15302
|
+
}
|
|
15303
|
+
async function getActiveProcedureTitles() {
|
|
15304
|
+
const client = getClient();
|
|
15305
|
+
const result = await client.execute({
|
|
15306
|
+
sql: "SELECT title FROM global_procedures WHERE active = 1",
|
|
15307
|
+
args: []
|
|
15308
|
+
});
|
|
15309
|
+
return new Set(result.rows.map((row) => String(row.title)));
|
|
15310
|
+
}
|
|
15311
|
+
async function exportOrchestration(createdBy) {
|
|
15312
|
+
const client = getClient();
|
|
15313
|
+
const roster = readRosterFile().map((entry) => ({
|
|
15314
|
+
...entry,
|
|
15315
|
+
createdAt: ""
|
|
15316
|
+
}));
|
|
15317
|
+
const identities = {};
|
|
15318
|
+
for (const identitySummary of listIdentities()) {
|
|
15319
|
+
const identity = getIdentity(identitySummary.agentId);
|
|
15320
|
+
if (identity?.raw) {
|
|
15321
|
+
identities[identitySummary.agentId] = identity.raw;
|
|
15322
|
+
}
|
|
15323
|
+
}
|
|
15324
|
+
const behaviorResult = await client.execute({
|
|
15325
|
+
sql: "SELECT agent_id, project_name, domain, content, priority FROM behaviors WHERE active = 1",
|
|
15326
|
+
args: []
|
|
15327
|
+
});
|
|
15328
|
+
const procedureResult = await client.execute({
|
|
15329
|
+
sql: "SELECT title, content, priority, domain FROM global_procedures WHERE active = 1",
|
|
15330
|
+
args: []
|
|
15331
|
+
});
|
|
15332
|
+
const behaviors = behaviorResult.rows.map((row) => ({
|
|
15333
|
+
agent_id: String(row.agent_id),
|
|
15334
|
+
project_name: row.project_name == null ? null : String(row.project_name),
|
|
15335
|
+
domain: row.domain == null ? null : String(row.domain),
|
|
15336
|
+
content: String(row.content),
|
|
15337
|
+
priority: ensurePriority(row.priority, "behaviors.priority", DEFAULT_BEHAVIOR_PRIORITY)
|
|
15338
|
+
}));
|
|
15339
|
+
const procedures = procedureResult.rows.map((row) => ({
|
|
15340
|
+
title: String(row.title),
|
|
15341
|
+
content: String(row.content),
|
|
15342
|
+
priority: ensurePriority(row.priority, "procedures.priority", DEFAULT_PROCEDURE_PRIORITY),
|
|
15343
|
+
domain: row.domain == null ? null : String(row.domain)
|
|
15344
|
+
})).filter((procedure) => !PLATFORM_PROCEDURE_TITLES.has(procedure.title));
|
|
15345
|
+
return {
|
|
15346
|
+
version: PACKAGE_VERSION,
|
|
15347
|
+
created_by: createdBy,
|
|
15348
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
15349
|
+
roster,
|
|
15350
|
+
identities,
|
|
15351
|
+
behaviors,
|
|
15352
|
+
procedures
|
|
15353
|
+
};
|
|
15354
|
+
}
|
|
15355
|
+
async function importOrchestration(pkg, strategy) {
|
|
15356
|
+
const validated = validatePackage(pkg);
|
|
15357
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
15358
|
+
const updatedBy = validated.created_by || DEFAULT_IDENTITY_UPDATED_BY;
|
|
15359
|
+
const rosterCount = strategy === "replace" ? await replaceRosterEntries(validated.roster, timestamp) : await mergeRosterEntries(validated.roster, timestamp);
|
|
15360
|
+
const identityCount = await importIdentities(validated.identities, updatedBy);
|
|
15361
|
+
if (strategy === "replace") {
|
|
15362
|
+
const replaced = await replaceBehaviorsAndProcedures(
|
|
15363
|
+
validated.behaviors,
|
|
15364
|
+
validated.procedures,
|
|
15365
|
+
timestamp
|
|
15366
|
+
);
|
|
15367
|
+
return {
|
|
15368
|
+
imported: {
|
|
15369
|
+
roster: rosterCount,
|
|
15370
|
+
identities: identityCount,
|
|
15371
|
+
behaviors: replaced.behaviors,
|
|
15372
|
+
procedures: replaced.procedures
|
|
15373
|
+
}
|
|
15374
|
+
};
|
|
15375
|
+
}
|
|
15376
|
+
const existingProcedureTitles = await getActiveProcedureTitles();
|
|
15377
|
+
const behaviorCount = await insertBehaviors(validated.behaviors, timestamp);
|
|
15378
|
+
const procedureCount = await insertProcedures(
|
|
15379
|
+
validated.procedures,
|
|
15380
|
+
timestamp,
|
|
15381
|
+
{ skipTitles: existingProcedureTitles }
|
|
15382
|
+
);
|
|
15383
|
+
return {
|
|
15384
|
+
imported: {
|
|
15385
|
+
roster: rosterCount,
|
|
15386
|
+
identities: identityCount,
|
|
15387
|
+
behaviors: behaviorCount,
|
|
15388
|
+
procedures: procedureCount
|
|
15389
|
+
}
|
|
15390
|
+
};
|
|
15391
|
+
}
|
|
15392
|
+
function validatePackage(data) {
|
|
15393
|
+
const record = ensureObject(data, "package");
|
|
15394
|
+
const version = ensureString(record.version, "version");
|
|
15395
|
+
if (version !== PACKAGE_VERSION) {
|
|
15396
|
+
throw new Error(`Unsupported orchestration package version: ${version}`);
|
|
15397
|
+
}
|
|
15398
|
+
if (!Array.isArray(record.roster)) {
|
|
15399
|
+
throw new Error("roster is required and must be an array");
|
|
15400
|
+
}
|
|
15401
|
+
if (record.identities == null || Array.isArray(record.identities) || typeof record.identities !== "object") {
|
|
15402
|
+
throw new Error("identities is required and must be an object");
|
|
15403
|
+
}
|
|
15404
|
+
if (!Array.isArray(record.behaviors)) {
|
|
15405
|
+
throw new Error("behaviors is required and must be an array");
|
|
15406
|
+
}
|
|
15407
|
+
if (!Array.isArray(record.procedures)) {
|
|
15408
|
+
throw new Error("procedures is required and must be an array");
|
|
15409
|
+
}
|
|
15410
|
+
const identities = Object.entries(record.identities).reduce(
|
|
15411
|
+
(acc, [agentId, content]) => {
|
|
15412
|
+
acc[agentId] = ensureString(content, `identities.${agentId}`);
|
|
15413
|
+
return acc;
|
|
15414
|
+
},
|
|
15415
|
+
{}
|
|
15416
|
+
);
|
|
15417
|
+
return {
|
|
15418
|
+
version: PACKAGE_VERSION,
|
|
15419
|
+
created_by: ensureString(record.created_by, "created_by"),
|
|
15420
|
+
created_at: ensureString(record.created_at, "created_at"),
|
|
15421
|
+
roster: record.roster.map((entry, index) => validateRosterEntry(entry, index)),
|
|
15422
|
+
identities,
|
|
15423
|
+
behaviors: record.behaviors.map((entry, index) => validateBehaviorEntry(entry, index)),
|
|
15424
|
+
procedures: record.procedures.map((entry, index) => validateProcedureEntry(entry, index))
|
|
15425
|
+
};
|
|
15426
|
+
}
|
|
15427
|
+
|
|
15428
|
+
// src/mcp/tools/export-orchestration.ts
|
|
15429
|
+
init_store();
|
|
15430
|
+
function registerExportOrchestration(server2) {
|
|
15431
|
+
server2.registerTool(
|
|
15432
|
+
"export_orchestration",
|
|
15433
|
+
{
|
|
15434
|
+
title: "Export Orchestration",
|
|
15435
|
+
description: "Export roster, identities, behaviors, and customer procedures to a JSON package.",
|
|
15436
|
+
inputSchema: {
|
|
15437
|
+
output_path: z38.string().describe("File path to write the JSON package")
|
|
15438
|
+
}
|
|
15439
|
+
},
|
|
15440
|
+
async ({ output_path }) => {
|
|
15441
|
+
try {
|
|
15442
|
+
await initStore();
|
|
15443
|
+
const pkg = await exportOrchestration(getActiveAgent().agentId);
|
|
15444
|
+
mkdirSync13(path29.dirname(output_path), { recursive: true });
|
|
15445
|
+
writeFileSync15(output_path, `${JSON.stringify(pkg, null, 2)}
|
|
15446
|
+
`, "utf-8");
|
|
15447
|
+
return {
|
|
15448
|
+
content: [{
|
|
15449
|
+
type: "text",
|
|
15450
|
+
text: `Exported ${pkg.roster.length} roster entries, ${Object.keys(pkg.identities).length} identities, ${pkg.behaviors.length} behaviors, ${pkg.procedures.length} procedures to ${output_path}`
|
|
15451
|
+
}]
|
|
15452
|
+
};
|
|
15453
|
+
} catch (err) {
|
|
15454
|
+
return {
|
|
15455
|
+
content: [{
|
|
15456
|
+
type: "text",
|
|
15457
|
+
text: `Failed to export orchestration: ${err instanceof Error ? err.message : String(err)}`
|
|
15458
|
+
}],
|
|
15459
|
+
isError: true
|
|
15460
|
+
};
|
|
15461
|
+
}
|
|
15462
|
+
}
|
|
15463
|
+
);
|
|
15464
|
+
}
|
|
15465
|
+
|
|
15466
|
+
// src/mcp/tools/import-orchestration.ts
|
|
15467
|
+
import { readFileSync as readFileSync19 } from "fs";
|
|
15468
|
+
import { z as z39 } from "zod";
|
|
15469
|
+
init_store();
|
|
15470
|
+
init_active_agent();
|
|
15471
|
+
init_employees();
|
|
15472
|
+
function registerImportOrchestration(server2) {
|
|
15473
|
+
server2.registerTool(
|
|
15474
|
+
"import_orchestration",
|
|
15475
|
+
{
|
|
15476
|
+
title: "Import Orchestration",
|
|
15477
|
+
description: "Import roster, identities, behaviors, and procedures from an orchestration package. Restricted to coordinator/founder.",
|
|
15478
|
+
inputSchema: {
|
|
15479
|
+
package_path: z39.string().describe("Path to the orchestration package JSON file"),
|
|
15480
|
+
merge_strategy: z39.enum(["replace", "merge"]).default("merge").describe("How to apply the package: both strategies are additive-only \u2014 existing data is never deleted or overwritten")
|
|
15481
|
+
}
|
|
15482
|
+
},
|
|
15483
|
+
async ({ package_path, merge_strategy }) => {
|
|
15484
|
+
try {
|
|
15485
|
+
const caller = getActiveAgent();
|
|
15486
|
+
const allowed = canCoordinate(caller.agentId, caller.agentRole);
|
|
15487
|
+
if (!allowed) {
|
|
15488
|
+
return {
|
|
15489
|
+
content: [{
|
|
15490
|
+
type: "text",
|
|
15491
|
+
text: `Permission denied. Only the coordinator or founder sessions can import orchestration packages. You are "${caller.agentId}".`
|
|
15492
|
+
}],
|
|
15493
|
+
isError: true
|
|
15494
|
+
};
|
|
15495
|
+
}
|
|
15496
|
+
await initStore();
|
|
15497
|
+
const raw = readFileSync19(package_path, "utf-8");
|
|
15498
|
+
const pkg = validatePackage(JSON.parse(raw));
|
|
15499
|
+
const result = await importOrchestration(pkg, merge_strategy);
|
|
15500
|
+
return {
|
|
15501
|
+
content: [{
|
|
15502
|
+
type: "text",
|
|
15503
|
+
text: `Imported ${result.imported.roster} roster entries, ${result.imported.identities} identities, ${result.imported.behaviors} behaviors, ${result.imported.procedures} procedures using ${merge_strategy} strategy`
|
|
15504
|
+
}]
|
|
15505
|
+
};
|
|
15506
|
+
} catch (err) {
|
|
15507
|
+
return {
|
|
15508
|
+
content: [{
|
|
15509
|
+
type: "text",
|
|
15510
|
+
text: `Failed to import orchestration: ${err instanceof Error ? err.message : String(err)}`
|
|
15511
|
+
}],
|
|
15512
|
+
isError: true
|
|
15513
|
+
};
|
|
15514
|
+
}
|
|
15515
|
+
}
|
|
15516
|
+
);
|
|
15517
|
+
}
|
|
15518
|
+
|
|
15073
15519
|
// src/mcp/tools/query-conversations.ts
|
|
15074
15520
|
init_database();
|
|
15075
|
-
import { z as
|
|
15521
|
+
import { z as z40 } from "zod";
|
|
15076
15522
|
function registerQueryConversations(server2) {
|
|
15077
15523
|
server2.registerTool(
|
|
15078
15524
|
"query_conversations",
|
|
@@ -15080,14 +15526,14 @@ function registerQueryConversations(server2) {
|
|
|
15080
15526
|
title: "Query Conversations",
|
|
15081
15527
|
description: "Search across all adapter messages by content, sender, date range, or platform. Returns messages with source attribution (platform, sender, timestamp).",
|
|
15082
15528
|
inputSchema: {
|
|
15083
|
-
query:
|
|
15084
|
-
sender:
|
|
15085
|
-
platform:
|
|
15086
|
-
after:
|
|
15087
|
-
before:
|
|
15088
|
-
channel_id:
|
|
15089
|
-
thread_id:
|
|
15090
|
-
limit:
|
|
15529
|
+
query: z40.string().optional().describe("Full-text search query across message content and responses"),
|
|
15530
|
+
sender: z40.string().optional().describe("Filter by sender ID or name (partial match)"),
|
|
15531
|
+
platform: z40.string().optional().describe("Filter by platform: whatsapp, signal, telegram, discord, imessage, slack, email, webchat"),
|
|
15532
|
+
after: z40.string().optional().describe("Filter messages after this ISO 8601 date (e.g. 2026-04-01)"),
|
|
15533
|
+
before: z40.string().optional().describe("Filter messages before this ISO 8601 date (e.g. 2026-04-15)"),
|
|
15534
|
+
channel_id: z40.string().optional().describe("Filter by channel/chat ID"),
|
|
15535
|
+
thread_id: z40.string().optional().describe("Filter by conversation thread ID"),
|
|
15536
|
+
limit: z40.number().int().min(1).max(100).optional().default(25).describe("Max results to return (default 25, max 100)")
|
|
15091
15537
|
}
|
|
15092
15538
|
},
|
|
15093
15539
|
async (params) => {
|
|
@@ -15194,19 +15640,19 @@ function registerQueryConversations(server2) {
|
|
|
15194
15640
|
}
|
|
15195
15641
|
|
|
15196
15642
|
// src/mcp/tools/load-skill.ts
|
|
15197
|
-
import { z as
|
|
15198
|
-
import { readFileSync as
|
|
15199
|
-
import
|
|
15643
|
+
import { z as z41 } from "zod";
|
|
15644
|
+
import { readFileSync as readFileSync20, readdirSync as readdirSync8, statSync as statSync3 } from "fs";
|
|
15645
|
+
import path30 from "path";
|
|
15200
15646
|
import { homedir as homedir2 } from "os";
|
|
15201
|
-
var SKILLS_DIR =
|
|
15647
|
+
var SKILLS_DIR = path30.join(homedir2(), ".claude", "skills");
|
|
15202
15648
|
function listAvailableSkills() {
|
|
15203
15649
|
try {
|
|
15204
15650
|
const entries = readdirSync8(SKILLS_DIR);
|
|
15205
15651
|
return entries.filter((entry) => {
|
|
15206
15652
|
try {
|
|
15207
|
-
const entryPath =
|
|
15653
|
+
const entryPath = path30.join(SKILLS_DIR, entry);
|
|
15208
15654
|
if (!statSync3(entryPath).isDirectory()) return false;
|
|
15209
|
-
const skillFile =
|
|
15655
|
+
const skillFile = path30.join(entryPath, "SKILL.md");
|
|
15210
15656
|
statSync3(skillFile);
|
|
15211
15657
|
return true;
|
|
15212
15658
|
} catch {
|
|
@@ -15224,7 +15670,7 @@ function registerLoadSkill(server2) {
|
|
|
15224
15670
|
title: "Load Skill",
|
|
15225
15671
|
description: "Load domain-specific guidance into your context. Use when you need specialized knowledge for a task (e.g., load_skill('seo') before doing SEO work, load_skill('code-reviewer') before reviewing code). Pass skill_name='list' to see all available skills.",
|
|
15226
15672
|
inputSchema: {
|
|
15227
|
-
skill_name:
|
|
15673
|
+
skill_name: z41.string().describe(
|
|
15228
15674
|
"Skill to load (e.g. 'seo', 'code-reviewer', 'frontend-design'). Pass 'list' to see all available skills."
|
|
15229
15675
|
)
|
|
15230
15676
|
}
|
|
@@ -15249,10 +15695,10 @@ ${skills.map((s) => `- ${s}`).join("\n")}`
|
|
|
15249
15695
|
}]
|
|
15250
15696
|
};
|
|
15251
15697
|
}
|
|
15252
|
-
const sanitized =
|
|
15253
|
-
const skillFile =
|
|
15698
|
+
const sanitized = path30.basename(skill_name);
|
|
15699
|
+
const skillFile = path30.join(SKILLS_DIR, sanitized, "SKILL.md");
|
|
15254
15700
|
try {
|
|
15255
|
-
const content =
|
|
15701
|
+
const content = readFileSync20(skillFile, "utf-8");
|
|
15256
15702
|
return {
|
|
15257
15703
|
content: [{
|
|
15258
15704
|
type: "text",
|
|
@@ -15281,7 +15727,7 @@ ${available.map((s) => `- ${s}`).join("\n")}` : "\n\nNo skills found in ~/.claud
|
|
|
15281
15727
|
// src/mcp/tools/consolidate-memories.ts
|
|
15282
15728
|
init_database();
|
|
15283
15729
|
init_active_agent();
|
|
15284
|
-
import { z as
|
|
15730
|
+
import { z as z42 } from "zod";
|
|
15285
15731
|
function registerConsolidateMemories(server2) {
|
|
15286
15732
|
server2.registerTool(
|
|
15287
15733
|
"consolidate_memories",
|
|
@@ -15289,8 +15735,8 @@ function registerConsolidateMemories(server2) {
|
|
|
15289
15735
|
title: "Consolidate Memories",
|
|
15290
15736
|
description: "Trigger content-aware memory consolidation. Groups recent memories by project, uses LLM to extract key facts, decisions, and patterns, then stores a high-importance summary and archives the originals. Runs automatically during idle time, but can be triggered manually when you want to compress your working memory.",
|
|
15291
15737
|
inputSchema: {
|
|
15292
|
-
max_clusters:
|
|
15293
|
-
model:
|
|
15738
|
+
max_clusters: z42.coerce.number().optional().default(5).describe("Maximum number of clusters to consolidate (default 5)"),
|
|
15739
|
+
model: z42.string().optional().describe("LLM model for summarization (defaults to config value)")
|
|
15294
15740
|
}
|
|
15295
15741
|
},
|
|
15296
15742
|
async ({ max_clusters, model }) => {
|
|
@@ -15346,7 +15792,7 @@ Consolidated summaries stored as tier-1 (importance=9) memories.`
|
|
|
15346
15792
|
init_global_procedures();
|
|
15347
15793
|
init_active_agent();
|
|
15348
15794
|
init_employees();
|
|
15349
|
-
import { z as
|
|
15795
|
+
import { z as z43 } from "zod";
|
|
15350
15796
|
function registerStoreGlobalProcedure(server2) {
|
|
15351
15797
|
server2.registerTool(
|
|
15352
15798
|
"store_global_procedure",
|
|
@@ -15354,10 +15800,10 @@ function registerStoreGlobalProcedure(server2) {
|
|
|
15354
15800
|
title: "Store Global Procedure",
|
|
15355
15801
|
description: "Create an organization-wide procedure (Layer 0) that supersedes identity, expertise, and experience. Use for hard rules that every employee must follow. RESTRICTED: only coordinator or founder sessions.",
|
|
15356
15802
|
inputSchema: {
|
|
15357
|
-
title:
|
|
15358
|
-
content:
|
|
15359
|
-
priority:
|
|
15360
|
-
domain:
|
|
15803
|
+
title: z43.string().describe("Short title for the procedure"),
|
|
15804
|
+
content: z43.string().max(500).describe("The procedure content \u2014 clear, actionable instruction"),
|
|
15805
|
+
priority: z43.enum(["p0", "p1", "p2"]).optional().describe("Priority tier. p0 = always (default). p1 = standard. p2 = nice-to-have."),
|
|
15806
|
+
domain: z43.string().optional().describe("Category: workflow, code-style, communication, architecture, testing, security")
|
|
15361
15807
|
}
|
|
15362
15808
|
},
|
|
15363
15809
|
async ({ title, content, priority, domain }) => {
|
|
@@ -15435,7 +15881,7 @@ init_global_procedures();
|
|
|
15435
15881
|
init_active_agent();
|
|
15436
15882
|
init_database();
|
|
15437
15883
|
init_employees();
|
|
15438
|
-
import { z as
|
|
15884
|
+
import { z as z44 } from "zod";
|
|
15439
15885
|
function registerDeactivateGlobalProcedure(server2) {
|
|
15440
15886
|
server2.registerTool(
|
|
15441
15887
|
"deactivate_global_procedure",
|
|
@@ -15443,7 +15889,7 @@ function registerDeactivateGlobalProcedure(server2) {
|
|
|
15443
15889
|
title: "Deactivate Global Procedure",
|
|
15444
15890
|
description: "Soft-delete a global procedure by setting active = 0. RESTRICTED: only coordinator or founder sessions. Use list_global_procedures to find the procedure ID first.",
|
|
15445
15891
|
inputSchema: {
|
|
15446
|
-
procedure_id:
|
|
15892
|
+
procedure_id: z44.string().describe("UUID of the global procedure to deactivate")
|
|
15447
15893
|
}
|
|
15448
15894
|
},
|
|
15449
15895
|
async ({ procedure_id }) => {
|
|
@@ -15498,7 +15944,7 @@ Content: ${row.content}`
|
|
|
15498
15944
|
}
|
|
15499
15945
|
|
|
15500
15946
|
// src/mcp/tools/search-everything.ts
|
|
15501
|
-
import { z as
|
|
15947
|
+
import { z as z45 } from "zod";
|
|
15502
15948
|
|
|
15503
15949
|
// src/lib/unified-search.ts
|
|
15504
15950
|
var DEFAULT_LIMIT = 10;
|
|
@@ -15665,11 +16111,11 @@ function registerSearchEverything(server2) {
|
|
|
15665
16111
|
title: "Search Everything",
|
|
15666
16112
|
description: "Search across all data stores \u2014 memories, conversations, and wiki \u2014 in one query. Returns merged results sorted by relevance with entity links.",
|
|
15667
16113
|
inputSchema: {
|
|
15668
|
-
query:
|
|
15669
|
-
sources:
|
|
16114
|
+
query: z45.string().describe("What to search for across all data stores"),
|
|
16115
|
+
sources: z45.array(z45.enum(["memory", "conversations", "wiki"])).optional().describe(
|
|
15670
16116
|
"Which sources to search (default: all). Options: memory, conversations, wiki"
|
|
15671
16117
|
),
|
|
15672
|
-
limit:
|
|
16118
|
+
limit: z45.coerce.number().int().min(1).max(50).optional().default(10).describe("Max results to return (default 10, max 50)")
|
|
15673
16119
|
}
|
|
15674
16120
|
},
|
|
15675
16121
|
async (params) => {
|
|
@@ -15730,7 +16176,7 @@ init_store();
|
|
|
15730
16176
|
init_active_agent();
|
|
15731
16177
|
init_database();
|
|
15732
16178
|
init_plan_limits();
|
|
15733
|
-
import { z as
|
|
16179
|
+
import { z as z46 } from "zod";
|
|
15734
16180
|
import crypto14 from "crypto";
|
|
15735
16181
|
function registerStoreDecision(server2) {
|
|
15736
16182
|
server2.registerTool(
|
|
@@ -15739,13 +16185,13 @@ function registerStoreDecision(server2) {
|
|
|
15739
16185
|
title: "Store Decision",
|
|
15740
16186
|
description: "Store an authoritative decision keyed by domain. Use this when a decision is made that should be canonical \u2014 future lookups via get_decision return the latest decision for that domain. Supports supersession chains.",
|
|
15741
16187
|
inputSchema: {
|
|
15742
|
-
domain:
|
|
16188
|
+
domain: z46.string().describe(
|
|
15743
16189
|
"Domain key, e.g. 'auth-strategy', 'db-migration-approach', 'api-versioning'"
|
|
15744
16190
|
),
|
|
15745
|
-
decision:
|
|
15746
|
-
rationale:
|
|
15747
|
-
supersedes:
|
|
15748
|
-
project_name:
|
|
16191
|
+
decision: z46.string().describe("The decision text \u2014 what was decided"),
|
|
16192
|
+
rationale: z46.string().optional().describe("Why this decision was made \u2014 constraints, trade-offs, context"),
|
|
16193
|
+
supersedes: z46.string().optional().describe("UUID of the decision this supersedes (previous decision for this domain)"),
|
|
16194
|
+
project_name: z46.string().optional().describe("Project name")
|
|
15749
16195
|
}
|
|
15750
16196
|
},
|
|
15751
16197
|
async ({ domain, decision, rationale, supersedes, project_name }) => {
|
|
@@ -15813,7 +16259,7 @@ Supersedes: ${supersedes}` : ""}`
|
|
|
15813
16259
|
|
|
15814
16260
|
// src/mcp/tools/get-decision.ts
|
|
15815
16261
|
init_database();
|
|
15816
|
-
import { z as
|
|
16262
|
+
import { z as z47 } from "zod";
|
|
15817
16263
|
function registerGetDecision(server2) {
|
|
15818
16264
|
server2.registerTool(
|
|
15819
16265
|
"get_decision",
|
|
@@ -15821,7 +16267,7 @@ function registerGetDecision(server2) {
|
|
|
15821
16267
|
title: "Get Decision",
|
|
15822
16268
|
description: "Retrieve the latest authoritative decision for a domain. Returns the current active decision and the supersession history.",
|
|
15823
16269
|
inputSchema: {
|
|
15824
|
-
domain:
|
|
16270
|
+
domain: z47.string().describe(
|
|
15825
16271
|
"Domain key to look up, e.g. 'auth-strategy', 'db-migration-approach'"
|
|
15826
16272
|
)
|
|
15827
16273
|
}
|
|
@@ -15884,15 +16330,15 @@ function registerGetDecision(server2) {
|
|
|
15884
16330
|
}
|
|
15885
16331
|
|
|
15886
16332
|
// src/mcp/tools/get-agent-spend.ts
|
|
15887
|
-
import { z as
|
|
16333
|
+
import { z as z48 } from "zod";
|
|
15888
16334
|
|
|
15889
16335
|
// src/lib/token-spend.ts
|
|
15890
16336
|
init_database();
|
|
15891
16337
|
import { readdir } from "fs/promises";
|
|
15892
16338
|
import { createReadStream } from "fs";
|
|
15893
16339
|
import { createInterface } from "readline";
|
|
15894
|
-
import
|
|
15895
|
-
import
|
|
16340
|
+
import path31 from "path";
|
|
16341
|
+
import os12 from "os";
|
|
15896
16342
|
var MODEL_PRICING = {
|
|
15897
16343
|
// Opus 4.5+ ($5/$25 — Anthropic price drop from original Opus 4)
|
|
15898
16344
|
"claude-opus-4-7": { input: 5 / 1e6, output: 25 / 1e6, cacheRead: 0.5 / 1e6, cacheWrite: 6.25 / 1e6 },
|
|
@@ -15940,18 +16386,18 @@ async function getAgentSpend(period = "7d") {
|
|
|
15940
16386
|
for (const row of result.rows) {
|
|
15941
16387
|
sessionAgent.set(row.session_uuid, row.agent_id);
|
|
15942
16388
|
}
|
|
15943
|
-
const claudeDir =
|
|
16389
|
+
const claudeDir = path31.join(os12.homedir(), ".claude", "projects");
|
|
15944
16390
|
let projectDirs = [];
|
|
15945
16391
|
try {
|
|
15946
16392
|
const entries = await readdir(claudeDir);
|
|
15947
|
-
projectDirs = entries.map((e) =>
|
|
16393
|
+
projectDirs = entries.map((e) => path31.join(claudeDir, e));
|
|
15948
16394
|
} catch {
|
|
15949
16395
|
return [];
|
|
15950
16396
|
}
|
|
15951
16397
|
const agentTotals = /* @__PURE__ */ new Map();
|
|
15952
16398
|
for (const [sessionUuid, agentId] of sessionAgent) {
|
|
15953
16399
|
for (const dir of projectDirs) {
|
|
15954
|
-
const jsonlPath =
|
|
16400
|
+
const jsonlPath = path31.join(dir, `${sessionUuid}.jsonl`);
|
|
15955
16401
|
try {
|
|
15956
16402
|
const usage = await extractSessionUsage(jsonlPath);
|
|
15957
16403
|
if (usage.input === 0 && usage.output === 0) continue;
|
|
@@ -16046,8 +16492,8 @@ function registerGetAgentSpend(server2) {
|
|
|
16046
16492
|
title: "Get Agent Spend",
|
|
16047
16493
|
description: "Get per-agent token spend attribution. Shows input, output, and cache tokens consumed by each agent over a time period, with estimated cost.",
|
|
16048
16494
|
inputSchema: {
|
|
16049
|
-
period:
|
|
16050
|
-
agent_id:
|
|
16495
|
+
period: z48.enum(["24h", "7d", "30d"]).default("7d").describe("Time period to query"),
|
|
16496
|
+
agent_id: z48.string().optional().describe("Filter to a specific agent (e.g. 'tom', 'yoshi')")
|
|
16051
16497
|
}
|
|
16052
16498
|
},
|
|
16053
16499
|
async ({ period, agent_id }) => {
|
|
@@ -16113,7 +16559,7 @@ function registerGetAgentSpend(server2) {
|
|
|
16113
16559
|
// src/mcp/tools/get-graph-stats.ts
|
|
16114
16560
|
init_database();
|
|
16115
16561
|
init_graph_query();
|
|
16116
|
-
import { z as
|
|
16562
|
+
import { z as z49 } from "zod";
|
|
16117
16563
|
function registerGetGraphStats(server2) {
|
|
16118
16564
|
server2.registerTool(
|
|
16119
16565
|
"get_graph_stats",
|
|
@@ -16121,7 +16567,7 @@ function registerGetGraphStats(server2) {
|
|
|
16121
16567
|
title: "Get Graph Stats",
|
|
16122
16568
|
description: "Get knowledge graph summary statistics: entity count, relationship count, and entity type breakdown.",
|
|
16123
16569
|
inputSchema: {
|
|
16124
|
-
_dummy:
|
|
16570
|
+
_dummy: z49.string().optional().describe("Unused \u2014 no input required")
|
|
16125
16571
|
}
|
|
16126
16572
|
},
|
|
16127
16573
|
async () => {
|
|
@@ -16163,7 +16609,7 @@ function registerGetGraphStats(server2) {
|
|
|
16163
16609
|
// src/mcp/tools/get-entity-neighbors.ts
|
|
16164
16610
|
init_database();
|
|
16165
16611
|
init_graph_query();
|
|
16166
|
-
import { z as
|
|
16612
|
+
import { z as z50 } from "zod";
|
|
16167
16613
|
function registerGetEntityNeighbors(server2) {
|
|
16168
16614
|
server2.registerTool(
|
|
16169
16615
|
"get_entity_neighbors",
|
|
@@ -16171,7 +16617,7 @@ function registerGetEntityNeighbors(server2) {
|
|
|
16171
16617
|
title: "Get Entity Neighbors",
|
|
16172
16618
|
description: "Get connected entities for a given entity name. Returns neighbors with relationship types, directions, and weights.",
|
|
16173
16619
|
inputSchema: {
|
|
16174
|
-
entity_name:
|
|
16620
|
+
entity_name: z50.string().describe("Name of the entity to find neighbors for")
|
|
16175
16621
|
}
|
|
16176
16622
|
},
|
|
16177
16623
|
async ({ entity_name }) => {
|
|
@@ -16240,7 +16686,7 @@ function registerGetEntityNeighbors(server2) {
|
|
|
16240
16686
|
// src/mcp/tools/get-hot-entities.ts
|
|
16241
16687
|
init_database();
|
|
16242
16688
|
init_graph_query();
|
|
16243
|
-
import { z as
|
|
16689
|
+
import { z as z51 } from "zod";
|
|
16244
16690
|
var PERIOD_MS = {
|
|
16245
16691
|
"24h": 24 * 60 * 60 * 1e3,
|
|
16246
16692
|
"7d": 7 * 24 * 60 * 60 * 1e3,
|
|
@@ -16253,8 +16699,8 @@ function registerGetHotEntities(server2) {
|
|
|
16253
16699
|
title: "Get Hot Entities",
|
|
16254
16700
|
description: "Get trending entities \u2014 those with the most new relationships in a time period. Surfaces what's most active in the knowledge graph.",
|
|
16255
16701
|
inputSchema: {
|
|
16256
|
-
period:
|
|
16257
|
-
limit:
|
|
16702
|
+
period: z51.enum(["24h", "7d", "30d"]).default("7d").describe("Time period to look back"),
|
|
16703
|
+
limit: z51.number().int().min(1).max(50).default(10).describe("Max entities to return")
|
|
16258
16704
|
}
|
|
16259
16705
|
},
|
|
16260
16706
|
async ({ period, limit }) => {
|
|
@@ -16302,7 +16748,7 @@ function registerGetHotEntities(server2) {
|
|
|
16302
16748
|
|
|
16303
16749
|
// src/mcp/tools/export-graph.ts
|
|
16304
16750
|
init_database();
|
|
16305
|
-
import { z as
|
|
16751
|
+
import { z as z52 } from "zod";
|
|
16306
16752
|
|
|
16307
16753
|
// src/lib/graph-export.ts
|
|
16308
16754
|
async function loadGraphData(client) {
|
|
@@ -16515,7 +16961,7 @@ function registerExportGraph(server2) {
|
|
|
16515
16961
|
title: "Export Graph",
|
|
16516
16962
|
description: "Export the knowledge graph as a markdown report (inline) or an interactive HTML visualization (writes file, returns path).",
|
|
16517
16963
|
inputSchema: {
|
|
16518
|
-
format:
|
|
16964
|
+
format: z52.enum(["html", "markdown"]).default("markdown").describe("Export format: markdown (inline) or html (file)")
|
|
16519
16965
|
}
|
|
16520
16966
|
},
|
|
16521
16967
|
async ({ format }) => {
|
|
@@ -16529,12 +16975,12 @@ function registerExportGraph(server2) {
|
|
|
16529
16975
|
}
|
|
16530
16976
|
const html = await exportGraphHTML(client);
|
|
16531
16977
|
const fs = await import("fs");
|
|
16532
|
-
const
|
|
16533
|
-
const
|
|
16534
|
-
const outDir =
|
|
16978
|
+
const path40 = await import("path");
|
|
16979
|
+
const os14 = await import("os");
|
|
16980
|
+
const outDir = path40.join(os14.homedir(), ".exe-os", "exports");
|
|
16535
16981
|
fs.mkdirSync(outDir, { recursive: true });
|
|
16536
16982
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
16537
|
-
const filePath =
|
|
16983
|
+
const filePath = path40.join(outDir, `graph-${timestamp}.html`);
|
|
16538
16984
|
fs.writeFileSync(filePath, html, "utf-8");
|
|
16539
16985
|
return {
|
|
16540
16986
|
content: [
|
|
@@ -16565,7 +17011,7 @@ Open in a browser to explore interactively.`
|
|
|
16565
17011
|
|
|
16566
17012
|
// src/mcp/tools/find-similar-trajectories.ts
|
|
16567
17013
|
init_skill_learning();
|
|
16568
|
-
import { z as
|
|
17014
|
+
import { z as z53 } from "zod";
|
|
16569
17015
|
function registerFindSimilarTrajectories(server2) {
|
|
16570
17016
|
server2.registerTool(
|
|
16571
17017
|
"find_similar_trajectories",
|
|
@@ -16573,7 +17019,7 @@ function registerFindSimilarTrajectories(server2) {
|
|
|
16573
17019
|
title: "Find Similar Trajectories",
|
|
16574
17020
|
description: 'Find past task trajectories that match a described tool sequence. Input a comma-separated tool sequence (e.g. "Read, Edit, Bash, Read") to find similar past workflows.',
|
|
16575
17021
|
inputSchema: {
|
|
16576
|
-
description:
|
|
17022
|
+
description: z53.string().describe(
|
|
16577
17023
|
'Tool sequence to match \u2014 comma-separated tool names (e.g. "Read, Grep, Edit, Bash:npm, Bash:git")'
|
|
16578
17024
|
)
|
|
16579
17025
|
}
|
|
@@ -16644,7 +17090,7 @@ ${withSkill.length} trajectory(s) already extracted into skill(s).`
|
|
|
16644
17090
|
|
|
16645
17091
|
// src/mcp/tools/get-session-kills.ts
|
|
16646
17092
|
init_session_kill_telemetry();
|
|
16647
|
-
import { z as
|
|
17093
|
+
import { z as z54 } from "zod";
|
|
16648
17094
|
var PERIOD_MS2 = {
|
|
16649
17095
|
"24h": 24 * 60 * 60 * 1e3,
|
|
16650
17096
|
"7d": 7 * 24 * 60 * 60 * 1e3,
|
|
@@ -16660,7 +17106,7 @@ function registerGetSessionKills(server2) {
|
|
|
16660
17106
|
title: "Get Session Kills",
|
|
16661
17107
|
description: "Get session kill telemetry: how many idle/TTL sessions were killed, tokens saved, and estimated cost savings over a time period.",
|
|
16662
17108
|
inputSchema: {
|
|
16663
|
-
period:
|
|
17109
|
+
period: z54.enum(["24h", "7d", "30d"]).default("7d").describe("Time period to query")
|
|
16664
17110
|
}
|
|
16665
17111
|
},
|
|
16666
17112
|
async ({ period }) => {
|
|
@@ -16700,7 +17146,7 @@ function registerGetSessionKills(server2) {
|
|
|
16700
17146
|
|
|
16701
17147
|
// src/mcp/tools/list-agent-sessions.ts
|
|
16702
17148
|
init_session_registry();
|
|
16703
|
-
import { z as
|
|
17149
|
+
import { z as z55 } from "zod";
|
|
16704
17150
|
function registerListAgentSessions(server2) {
|
|
16705
17151
|
server2.registerTool(
|
|
16706
17152
|
"list_agent_sessions",
|
|
@@ -16708,7 +17154,7 @@ function registerListAgentSessions(server2) {
|
|
|
16708
17154
|
title: "List Agent Sessions",
|
|
16709
17155
|
description: "List all registered agent sessions with their agent ID, project, PID, and registration time.",
|
|
16710
17156
|
inputSchema: {
|
|
16711
|
-
_placeholder:
|
|
17157
|
+
_placeholder: z55.string().optional().describe("No input required")
|
|
16712
17158
|
}
|
|
16713
17159
|
},
|
|
16714
17160
|
async () => {
|
|
@@ -16754,11 +17200,11 @@ function registerListAgentSessions(server2) {
|
|
|
16754
17200
|
}
|
|
16755
17201
|
|
|
16756
17202
|
// src/mcp/tools/get-daemon-health.ts
|
|
16757
|
-
import { z as
|
|
16758
|
-
import { existsSync as
|
|
16759
|
-
import
|
|
17203
|
+
import { z as z56 } from "zod";
|
|
17204
|
+
import { existsSync as existsSync23, readFileSync as readFileSync21 } from "fs";
|
|
17205
|
+
import path32 from "path";
|
|
16760
17206
|
import { homedir as homedir3 } from "os";
|
|
16761
|
-
var PID_PATH2 =
|
|
17207
|
+
var PID_PATH2 = path32.join(homedir3(), ".exe-os", "exed.pid");
|
|
16762
17208
|
function formatUptime(seconds) {
|
|
16763
17209
|
const h = Math.floor(seconds / 3600);
|
|
16764
17210
|
const m = Math.floor(seconds % 3600 / 60);
|
|
@@ -16769,8 +17215,8 @@ function formatUptime(seconds) {
|
|
|
16769
17215
|
}
|
|
16770
17216
|
function isDaemonAlive() {
|
|
16771
17217
|
try {
|
|
16772
|
-
if (!
|
|
16773
|
-
const pid = parseInt(
|
|
17218
|
+
if (!existsSync23(PID_PATH2)) return { alive: false, pid: null };
|
|
17219
|
+
const pid = parseInt(readFileSync21(PID_PATH2, "utf8").trim(), 10);
|
|
16774
17220
|
if (isNaN(pid) || pid <= 0) return { alive: false, pid: null };
|
|
16775
17221
|
process.kill(pid, 0);
|
|
16776
17222
|
return { alive: true, pid };
|
|
@@ -16785,7 +17231,7 @@ function registerGetDaemonHealth(server2) {
|
|
|
16785
17231
|
title: "Get Daemon Health",
|
|
16786
17232
|
description: "Check the embedding daemon (exed) health: whether it's running, its PID, uptime, and requests served.",
|
|
16787
17233
|
inputSchema: {
|
|
16788
|
-
_placeholder:
|
|
17234
|
+
_placeholder: z56.string().optional().describe("No input required")
|
|
16789
17235
|
}
|
|
16790
17236
|
},
|
|
16791
17237
|
async () => {
|
|
@@ -16837,14 +17283,14 @@ function registerGetDaemonHealth(server2) {
|
|
|
16837
17283
|
// src/mcp/tools/get-auto-wake-status.ts
|
|
16838
17284
|
init_database();
|
|
16839
17285
|
init_session_registry();
|
|
16840
|
-
import { z as
|
|
17286
|
+
import { z as z57 } from "zod";
|
|
16841
17287
|
|
|
16842
17288
|
// src/lib/daemon-orchestration.ts
|
|
16843
17289
|
init_tmux_routing();
|
|
16844
17290
|
init_task_scope();
|
|
16845
17291
|
init_employees();
|
|
16846
17292
|
import { execSync as execSync10 } from "child_process";
|
|
16847
|
-
import { existsSync as
|
|
17293
|
+
import { existsSync as existsSync24, readFileSync as readFileSync22, writeFileSync as writeFileSync16 } from "fs";
|
|
16848
17294
|
import { homedir as homedir4 } from "os";
|
|
16849
17295
|
import { join as join2 } from "path";
|
|
16850
17296
|
var IDLE_NUDGE_DEDUP_MS = Number(process.env.EXE_NUDGE_INTERVAL_MS) || 6e4;
|
|
@@ -16865,7 +17311,7 @@ function registerGetAutoWakeStatus(server2) {
|
|
|
16865
17311
|
title: "Get Auto-Wake Status",
|
|
16866
17312
|
description: "Check auto-wake status: orphaned tasks (assigned agent has no running session), tasks blocked by auto-wake retry limit, and session activity.",
|
|
16867
17313
|
inputSchema: {
|
|
16868
|
-
_placeholder:
|
|
17314
|
+
_placeholder: z57.string().optional().describe("No input required")
|
|
16869
17315
|
}
|
|
16870
17316
|
},
|
|
16871
17317
|
async () => {
|
|
@@ -16946,16 +17392,16 @@ function registerGetAutoWakeStatus(server2) {
|
|
|
16946
17392
|
// src/mcp/tools/get-worker-gate.ts
|
|
16947
17393
|
init_worker_gate();
|
|
16948
17394
|
init_config();
|
|
16949
|
-
import { z as
|
|
16950
|
-
import { readdirSync as readdirSync10, existsSync as
|
|
16951
|
-
import
|
|
16952
|
-
var WORKER_PID_DIR2 =
|
|
17395
|
+
import { z as z58 } from "zod";
|
|
17396
|
+
import { readdirSync as readdirSync10, existsSync as existsSync26 } from "fs";
|
|
17397
|
+
import path34 from "path";
|
|
17398
|
+
var WORKER_PID_DIR2 = path34.join(EXE_AI_DIR, "worker-pids");
|
|
16953
17399
|
function countAliveWorkers() {
|
|
16954
17400
|
let alive = 0;
|
|
16955
17401
|
let stale = 0;
|
|
16956
17402
|
let reservations = 0;
|
|
16957
17403
|
try {
|
|
16958
|
-
if (!
|
|
17404
|
+
if (!existsSync26(WORKER_PID_DIR2)) return { alive: 0, stale: 0, reservations: 0 };
|
|
16959
17405
|
const files = readdirSync10(WORKER_PID_DIR2);
|
|
16960
17406
|
for (const f of files) {
|
|
16961
17407
|
if (!f.endsWith(".pid")) continue;
|
|
@@ -16984,7 +17430,7 @@ function registerGetWorkerGate(server2) {
|
|
|
16984
17430
|
title: "Get Worker Gate",
|
|
16985
17431
|
description: "Check worker concurrency gate status: how many worker slots are in use, the maximum allowed, and whether new workers can spawn.",
|
|
16986
17432
|
inputSchema: {
|
|
16987
|
-
_placeholder:
|
|
17433
|
+
_placeholder: z58.string().optional().describe("No input required")
|
|
16988
17434
|
}
|
|
16989
17435
|
},
|
|
16990
17436
|
async () => {
|
|
@@ -17020,12 +17466,12 @@ function registerGetWorkerGate(server2) {
|
|
|
17020
17466
|
|
|
17021
17467
|
// src/mcp/tools/run-memory-audit.ts
|
|
17022
17468
|
init_database();
|
|
17023
|
-
import { z as
|
|
17469
|
+
import { z as z59 } from "zod";
|
|
17024
17470
|
|
|
17025
17471
|
// src/bin/exe-doctor.ts
|
|
17026
17472
|
init_store();
|
|
17027
17473
|
init_database();
|
|
17028
|
-
import
|
|
17474
|
+
import os13 from "os";
|
|
17029
17475
|
|
|
17030
17476
|
// src/lib/is-main.ts
|
|
17031
17477
|
import { realpathSync } from "fs";
|
|
@@ -17043,10 +17489,10 @@ function isMainModule(importMetaUrl) {
|
|
|
17043
17489
|
}
|
|
17044
17490
|
|
|
17045
17491
|
// src/bin/exe-doctor.ts
|
|
17046
|
-
import { existsSync as
|
|
17492
|
+
import { existsSync as existsSync27, readFileSync as readFileSync23 } from "fs";
|
|
17047
17493
|
import { spawn as spawn2 } from "child_process";
|
|
17048
|
-
import
|
|
17049
|
-
import { randomUUID as
|
|
17494
|
+
import path35 from "path";
|
|
17495
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
17050
17496
|
|
|
17051
17497
|
// src/lib/conflict-detector.ts
|
|
17052
17498
|
var DEFAULT_MAX_PAIRS = 100;
|
|
@@ -17448,7 +17894,7 @@ async function auditOrphanedProjects(client) {
|
|
|
17448
17894
|
for (const row of result.rows) {
|
|
17449
17895
|
const name = row.project_name;
|
|
17450
17896
|
const count = Number(row.cnt);
|
|
17451
|
-
const exists =
|
|
17897
|
+
const exists = existsSync27(path35.join(home, name)) || existsSync27(path35.join(home, "..", name)) || existsSync27(path35.join(process.cwd(), "..", name));
|
|
17452
17898
|
if (!exists) {
|
|
17453
17899
|
orphans.push({ project_name: name, count });
|
|
17454
17900
|
}
|
|
@@ -17456,18 +17902,18 @@ async function auditOrphanedProjects(client) {
|
|
|
17456
17902
|
return orphans;
|
|
17457
17903
|
}
|
|
17458
17904
|
function auditHookHealth() {
|
|
17459
|
-
const logPath =
|
|
17905
|
+
const logPath = path35.join(
|
|
17460
17906
|
process.env.HOME ?? process.env.USERPROFILE ?? "",
|
|
17461
17907
|
".exe-os",
|
|
17462
17908
|
"logs",
|
|
17463
17909
|
"hooks.log"
|
|
17464
17910
|
);
|
|
17465
|
-
if (!
|
|
17911
|
+
if (!existsSync27(logPath)) {
|
|
17466
17912
|
return { logExists: false, totalLines: 0, errorsLastHour: 0, topPatterns: [] };
|
|
17467
17913
|
}
|
|
17468
17914
|
let content;
|
|
17469
17915
|
try {
|
|
17470
|
-
content =
|
|
17916
|
+
content = readFileSync23(logPath, "utf-8");
|
|
17471
17917
|
} catch {
|
|
17472
17918
|
return { logExists: false, totalLines: 0, errorsLastHour: 0, topPatterns: [] };
|
|
17473
17919
|
}
|
|
@@ -17542,7 +17988,7 @@ function formatReport(report, flags) {
|
|
|
17542
17988
|
}
|
|
17543
17989
|
lines.push("");
|
|
17544
17990
|
}
|
|
17545
|
-
const totalMemGB =
|
|
17991
|
+
const totalMemGB = os13.totalmem() / (1024 * 1024 * 1024);
|
|
17546
17992
|
const isLowMemSystem = totalMemGB <= 8;
|
|
17547
17993
|
if (isLowMemSystem && report.nullVectors > 0) {
|
|
17548
17994
|
lines.push(`\u{1F7E2} Null vectors: ${fmtNum(report.nullVectors)} / ${fmtNum(s.total)} (expected \u2014 8GB system, keyword search mode)`);
|
|
@@ -17664,7 +18110,7 @@ async function fixNullVectors() {
|
|
|
17664
18110
|
}
|
|
17665
18111
|
}
|
|
17666
18112
|
const npmRoot = (await import("child_process")).execSync("npm root -g", { encoding: "utf8" }).trim();
|
|
17667
|
-
const backfillPath =
|
|
18113
|
+
const backfillPath = path35.join(npmRoot, "exe-os", "dist", "bin", "backfill-vectors.js");
|
|
17668
18114
|
return new Promise((resolve, reject) => {
|
|
17669
18115
|
const child = spawn2("node", [backfillPath], { stdio: "inherit" });
|
|
17670
18116
|
if (child.pid) registerWorkerPid2(child.pid);
|
|
@@ -17720,7 +18166,7 @@ async function fixBloated(client, bloated, dryRun) {
|
|
|
17720
18166
|
tool_name, project_name, has_error, raw_text, vector, version, consolidated)
|
|
17721
18167
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, 0, 0)`,
|
|
17722
18168
|
args: [
|
|
17723
|
-
|
|
18169
|
+
randomUUID7(),
|
|
17724
18170
|
row.agent_id,
|
|
17725
18171
|
row.agent_role,
|
|
17726
18172
|
row.session_id,
|
|
@@ -17824,8 +18270,8 @@ function registerRunMemoryAudit(server2) {
|
|
|
17824
18270
|
title: "Run Memory Audit",
|
|
17825
18271
|
description: "Run a memory health audit: total counts, per-agent breakdown, null vectors, duplicates, FTS sync status, bloated records, and conflict detection (contradictory/superseded memories).",
|
|
17826
18272
|
inputSchema: {
|
|
17827
|
-
agent_id:
|
|
17828
|
-
project_name:
|
|
18273
|
+
agent_id: z59.string().optional().describe("Filter audit to a specific agent"),
|
|
18274
|
+
project_name: z59.string().optional().describe("Filter audit to a specific project")
|
|
17829
18275
|
}
|
|
17830
18276
|
},
|
|
17831
18277
|
async ({ agent_id, project_name }) => {
|
|
@@ -17858,13 +18304,13 @@ function registerRunMemoryAudit(server2) {
|
|
|
17858
18304
|
}
|
|
17859
18305
|
|
|
17860
18306
|
// src/mcp/tools/cloud-sync.ts
|
|
17861
|
-
import { z as
|
|
18307
|
+
import { z as z60 } from "zod";
|
|
17862
18308
|
|
|
17863
18309
|
// src/lib/cloud-sync.ts
|
|
17864
18310
|
init_database();
|
|
17865
|
-
import { readFileSync as
|
|
18311
|
+
import { readFileSync as readFileSync25, writeFileSync as writeFileSync19, existsSync as existsSync29, readdirSync as readdirSync11, mkdirSync as mkdirSync16, appendFileSync as appendFileSync2, unlinkSync as unlinkSync10, openSync as openSync2, closeSync as closeSync2 } from "fs";
|
|
17866
18312
|
import crypto16 from "crypto";
|
|
17867
|
-
import
|
|
18313
|
+
import path37 from "path";
|
|
17868
18314
|
import { homedir as homedir6 } from "os";
|
|
17869
18315
|
|
|
17870
18316
|
// src/lib/crypto.ts
|
|
@@ -17938,7 +18384,7 @@ function sqlSafe(v) {
|
|
|
17938
18384
|
}
|
|
17939
18385
|
function logError(msg) {
|
|
17940
18386
|
try {
|
|
17941
|
-
const logPath =
|
|
18387
|
+
const logPath = path37.join(homedir6(), ".exe-os", "workers.log");
|
|
17942
18388
|
appendFileSync2(logPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
|
|
17943
18389
|
`);
|
|
17944
18390
|
} catch {
|
|
@@ -17947,24 +18393,24 @@ function logError(msg) {
|
|
|
17947
18393
|
var LOCALHOST_PATTERNS = /^(localhost|127\.0\.0\.1|\[::1\])$/i;
|
|
17948
18394
|
var FETCH_TIMEOUT_MS4 = 3e4;
|
|
17949
18395
|
var PUSH_BATCH_SIZE = 5e3;
|
|
17950
|
-
var ROSTER_LOCK_PATH =
|
|
18396
|
+
var ROSTER_LOCK_PATH = path37.join(EXE_AI_DIR, "roster-merge.lock");
|
|
17951
18397
|
var LOCK_STALE_MS = 3e4;
|
|
17952
18398
|
async function withRosterLock(fn) {
|
|
17953
18399
|
try {
|
|
17954
18400
|
const fd = openSync2(ROSTER_LOCK_PATH, "wx");
|
|
17955
18401
|
closeSync2(fd);
|
|
17956
|
-
|
|
18402
|
+
writeFileSync19(ROSTER_LOCK_PATH, String(Date.now()));
|
|
17957
18403
|
} catch (err) {
|
|
17958
18404
|
if (err.code === "EEXIST") {
|
|
17959
18405
|
try {
|
|
17960
|
-
const ts2 = parseInt(
|
|
18406
|
+
const ts2 = parseInt(readFileSync25(ROSTER_LOCK_PATH, "utf-8"), 10);
|
|
17961
18407
|
if (Date.now() - ts2 < LOCK_STALE_MS) {
|
|
17962
18408
|
throw new Error("Roster merge already in progress \u2014 another sync is running");
|
|
17963
18409
|
}
|
|
17964
18410
|
unlinkSync10(ROSTER_LOCK_PATH);
|
|
17965
18411
|
const fd = openSync2(ROSTER_LOCK_PATH, "wx");
|
|
17966
18412
|
closeSync2(fd);
|
|
17967
|
-
|
|
18413
|
+
writeFileSync19(ROSTER_LOCK_PATH, String(Date.now()));
|
|
17968
18414
|
} catch (retryErr) {
|
|
17969
18415
|
if (retryErr instanceof Error && retryErr.message.includes("already in progress")) throw retryErr;
|
|
17970
18416
|
throw new Error("Roster merge already in progress \u2014 another sync is running");
|
|
@@ -18338,8 +18784,8 @@ async function cloudSync(config2) {
|
|
|
18338
18784
|
try {
|
|
18339
18785
|
const employees = await loadEmployees();
|
|
18340
18786
|
rosterResult.employees = employees.length;
|
|
18341
|
-
const idDir =
|
|
18342
|
-
if (
|
|
18787
|
+
const idDir = path37.join(EXE_AI_DIR, "identity");
|
|
18788
|
+
if (existsSync29(idDir)) {
|
|
18343
18789
|
rosterResult.identities = readdirSync11(idDir).filter((f) => f.endsWith(".md")).length;
|
|
18344
18790
|
}
|
|
18345
18791
|
} catch {
|
|
@@ -18357,49 +18803,49 @@ async function cloudSync(config2) {
|
|
|
18357
18803
|
roster: rosterResult
|
|
18358
18804
|
};
|
|
18359
18805
|
}
|
|
18360
|
-
var ROSTER_DELETIONS_PATH =
|
|
18806
|
+
var ROSTER_DELETIONS_PATH = path37.join(EXE_AI_DIR, "roster-deletions.json");
|
|
18361
18807
|
function consumeRosterDeletions() {
|
|
18362
18808
|
try {
|
|
18363
|
-
if (!
|
|
18364
|
-
const deletions = JSON.parse(
|
|
18365
|
-
|
|
18809
|
+
if (!existsSync29(ROSTER_DELETIONS_PATH)) return [];
|
|
18810
|
+
const deletions = JSON.parse(readFileSync25(ROSTER_DELETIONS_PATH, "utf-8"));
|
|
18811
|
+
writeFileSync19(ROSTER_DELETIONS_PATH, "[]");
|
|
18366
18812
|
return deletions;
|
|
18367
18813
|
} catch {
|
|
18368
18814
|
return [];
|
|
18369
18815
|
}
|
|
18370
18816
|
}
|
|
18371
18817
|
function buildRosterBlob(paths) {
|
|
18372
|
-
const rosterPath = paths?.rosterPath ??
|
|
18373
|
-
const identityDir = paths?.identityDir ??
|
|
18374
|
-
const configPath = paths?.configPath ??
|
|
18818
|
+
const rosterPath = paths?.rosterPath ?? path37.join(EXE_AI_DIR, "exe-employees.json");
|
|
18819
|
+
const identityDir = paths?.identityDir ?? path37.join(EXE_AI_DIR, "identity");
|
|
18820
|
+
const configPath = paths?.configPath ?? path37.join(EXE_AI_DIR, "config.json");
|
|
18375
18821
|
let roster = [];
|
|
18376
|
-
if (
|
|
18822
|
+
if (existsSync29(rosterPath)) {
|
|
18377
18823
|
try {
|
|
18378
|
-
roster = JSON.parse(
|
|
18824
|
+
roster = JSON.parse(readFileSync25(rosterPath, "utf-8"));
|
|
18379
18825
|
} catch {
|
|
18380
18826
|
}
|
|
18381
18827
|
}
|
|
18382
18828
|
const identities = {};
|
|
18383
|
-
if (
|
|
18829
|
+
if (existsSync29(identityDir)) {
|
|
18384
18830
|
for (const file of readdirSync11(identityDir).filter((f) => f.endsWith(".md"))) {
|
|
18385
18831
|
try {
|
|
18386
|
-
identities[file] =
|
|
18832
|
+
identities[file] = readFileSync25(path37.join(identityDir, file), "utf-8");
|
|
18387
18833
|
} catch {
|
|
18388
18834
|
}
|
|
18389
18835
|
}
|
|
18390
18836
|
}
|
|
18391
18837
|
let config2;
|
|
18392
|
-
if (
|
|
18838
|
+
if (existsSync29(configPath)) {
|
|
18393
18839
|
try {
|
|
18394
|
-
config2 = JSON.parse(
|
|
18840
|
+
config2 = JSON.parse(readFileSync25(configPath, "utf-8"));
|
|
18395
18841
|
} catch {
|
|
18396
18842
|
}
|
|
18397
18843
|
}
|
|
18398
18844
|
let agentConfig;
|
|
18399
|
-
const agentConfigPath =
|
|
18400
|
-
if (
|
|
18845
|
+
const agentConfigPath = path37.join(EXE_AI_DIR, "agent-config.json");
|
|
18846
|
+
if (existsSync29(agentConfigPath)) {
|
|
18401
18847
|
try {
|
|
18402
|
-
agentConfig = JSON.parse(
|
|
18848
|
+
agentConfig = JSON.parse(readFileSync25(agentConfigPath, "utf-8"));
|
|
18403
18849
|
} catch {
|
|
18404
18850
|
}
|
|
18405
18851
|
}
|
|
@@ -18475,23 +18921,23 @@ async function cloudPullRoster(config2) {
|
|
|
18475
18921
|
}
|
|
18476
18922
|
}
|
|
18477
18923
|
function mergeConfig(remoteConfig, configPath) {
|
|
18478
|
-
const cfgPath = configPath ??
|
|
18924
|
+
const cfgPath = configPath ?? path37.join(EXE_AI_DIR, "config.json");
|
|
18479
18925
|
let local = {};
|
|
18480
|
-
if (
|
|
18926
|
+
if (existsSync29(cfgPath)) {
|
|
18481
18927
|
try {
|
|
18482
|
-
local = JSON.parse(
|
|
18928
|
+
local = JSON.parse(readFileSync25(cfgPath, "utf-8"));
|
|
18483
18929
|
} catch {
|
|
18484
18930
|
}
|
|
18485
18931
|
}
|
|
18486
18932
|
const merged = { ...remoteConfig, ...local };
|
|
18487
|
-
const dir =
|
|
18488
|
-
if (!
|
|
18489
|
-
|
|
18933
|
+
const dir = path37.dirname(cfgPath);
|
|
18934
|
+
if (!existsSync29(dir)) mkdirSync16(dir, { recursive: true });
|
|
18935
|
+
writeFileSync19(cfgPath, JSON.stringify(merged, null, 2), "utf-8");
|
|
18490
18936
|
}
|
|
18491
18937
|
async function mergeRosterFromRemote(remote, paths) {
|
|
18492
18938
|
return withRosterLock(async () => {
|
|
18493
18939
|
const rosterPath = paths?.rosterPath ?? void 0;
|
|
18494
|
-
const identityDir = paths?.identityDir ??
|
|
18940
|
+
const identityDir = paths?.identityDir ?? path37.join(EXE_AI_DIR, "identity");
|
|
18495
18941
|
const localEmployees = await loadEmployees(rosterPath);
|
|
18496
18942
|
const localNames = new Set(localEmployees.map((e) => e.name));
|
|
18497
18943
|
let added = 0;
|
|
@@ -18512,15 +18958,15 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
18512
18958
|
) ?? lookupKey;
|
|
18513
18959
|
const remoteIdentity = remote.identities[matchedKey];
|
|
18514
18960
|
if (remoteIdentity) {
|
|
18515
|
-
if (!
|
|
18516
|
-
const idPath =
|
|
18961
|
+
if (!existsSync29(identityDir)) mkdirSync16(identityDir, { recursive: true });
|
|
18962
|
+
const idPath = path37.join(identityDir, `${remoteEmp.name}.md`);
|
|
18517
18963
|
let localIdentity = null;
|
|
18518
18964
|
try {
|
|
18519
|
-
localIdentity =
|
|
18965
|
+
localIdentity = existsSync29(idPath) ? readFileSync25(idPath, "utf-8") : null;
|
|
18520
18966
|
} catch {
|
|
18521
18967
|
}
|
|
18522
18968
|
if (localIdentity !== remoteIdentity) {
|
|
18523
|
-
|
|
18969
|
+
writeFileSync19(idPath, remoteIdentity, "utf-8");
|
|
18524
18970
|
identitiesUpdated++;
|
|
18525
18971
|
}
|
|
18526
18972
|
}
|
|
@@ -18546,16 +18992,16 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
18546
18992
|
}
|
|
18547
18993
|
if (remote.agentConfig && Object.keys(remote.agentConfig).length > 0) {
|
|
18548
18994
|
try {
|
|
18549
|
-
const agentConfigPath =
|
|
18995
|
+
const agentConfigPath = path37.join(EXE_AI_DIR, "agent-config.json");
|
|
18550
18996
|
let local = {};
|
|
18551
|
-
if (
|
|
18997
|
+
if (existsSync29(agentConfigPath)) {
|
|
18552
18998
|
try {
|
|
18553
|
-
local = JSON.parse(
|
|
18999
|
+
local = JSON.parse(readFileSync25(agentConfigPath, "utf-8"));
|
|
18554
19000
|
} catch {
|
|
18555
19001
|
}
|
|
18556
19002
|
}
|
|
18557
19003
|
const merged = { ...remote.agentConfig, ...local };
|
|
18558
|
-
|
|
19004
|
+
writeFileSync19(agentConfigPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
18559
19005
|
} catch {
|
|
18560
19006
|
}
|
|
18561
19007
|
}
|
|
@@ -18989,7 +19435,7 @@ function registerCloudSync(server2) {
|
|
|
18989
19435
|
title: "Cloud Sync",
|
|
18990
19436
|
description: "Trigger a cloud sync cycle \u2014 pulls remote changes then pushes local. Reports pushed/pulled counts for memories, behaviors, graph, tasks, and more.",
|
|
18991
19437
|
inputSchema: {
|
|
18992
|
-
force:
|
|
19438
|
+
force: z60.boolean().default(false).describe("Force sync even if recently synced")
|
|
18993
19439
|
}
|
|
18994
19440
|
},
|
|
18995
19441
|
async () => {
|
|
@@ -19042,7 +19488,7 @@ function registerCloudSync(server2) {
|
|
|
19042
19488
|
|
|
19043
19489
|
// src/mcp/tools/get-memory-cardinality.ts
|
|
19044
19490
|
init_database();
|
|
19045
|
-
import { z as
|
|
19491
|
+
import { z as z61 } from "zod";
|
|
19046
19492
|
function registerGetMemoryCardinality(server2) {
|
|
19047
19493
|
server2.registerTool(
|
|
19048
19494
|
"get_memory_cardinality",
|
|
@@ -19050,7 +19496,7 @@ function registerGetMemoryCardinality(server2) {
|
|
|
19050
19496
|
title: "Get Memory Cardinality",
|
|
19051
19497
|
description: "Get memory counts: total active memories and per-project breakdown. Optionally filter by agent.",
|
|
19052
19498
|
inputSchema: {
|
|
19053
|
-
agent_id:
|
|
19499
|
+
agent_id: z61.string().optional().describe("Filter to a specific agent (e.g. 'tom', 'exe')")
|
|
19054
19500
|
}
|
|
19055
19501
|
},
|
|
19056
19502
|
async ({ agent_id }) => {
|
|
@@ -19133,7 +19579,7 @@ function registerGetMemoryCardinality(server2) {
|
|
|
19133
19579
|
init_database();
|
|
19134
19580
|
init_consolidation();
|
|
19135
19581
|
init_config();
|
|
19136
|
-
import { z as
|
|
19582
|
+
import { z as z62 } from "zod";
|
|
19137
19583
|
function registerRunConsolidation(server2) {
|
|
19138
19584
|
server2.registerTool(
|
|
19139
19585
|
"run_consolidation",
|
|
@@ -19141,7 +19587,7 @@ function registerRunConsolidation(server2) {
|
|
|
19141
19587
|
title: "Run Consolidation",
|
|
19142
19588
|
description: "Run memory consolidation \u2014 synthesizes unconsolidated memories into meta-insights. Use dry_run=true (default) to preview without executing.",
|
|
19143
19589
|
inputSchema: {
|
|
19144
|
-
dry_run:
|
|
19590
|
+
dry_run: z62.boolean().default(true).describe("Preview mode \u2014 show what would be consolidated without doing it")
|
|
19145
19591
|
}
|
|
19146
19592
|
},
|
|
19147
19593
|
async ({ dry_run }) => {
|
|
@@ -19210,7 +19656,7 @@ function registerRunConsolidation(server2) {
|
|
|
19210
19656
|
|
|
19211
19657
|
// src/mcp/tools/get-license-status.ts
|
|
19212
19658
|
init_license();
|
|
19213
|
-
import { z as
|
|
19659
|
+
import { z as z63 } from "zod";
|
|
19214
19660
|
var FEATURES = [
|
|
19215
19661
|
"cloud_sync",
|
|
19216
19662
|
"external_agents",
|
|
@@ -19224,7 +19670,7 @@ function registerGetLicenseStatus(server2) {
|
|
|
19224
19670
|
title: "Get License Status",
|
|
19225
19671
|
description: "Get current license status: plan, validity, feature gates, limits, and expiry.",
|
|
19226
19672
|
inputSchema: {
|
|
19227
|
-
_dummy:
|
|
19673
|
+
_dummy: z63.string().optional().describe("Unused \u2014 no input required")
|
|
19228
19674
|
}
|
|
19229
19675
|
},
|
|
19230
19676
|
async () => {
|
|
@@ -19276,16 +19722,16 @@ function registerGetLicenseStatus(server2) {
|
|
|
19276
19722
|
}
|
|
19277
19723
|
|
|
19278
19724
|
// src/mcp/tools/people-roster.ts
|
|
19279
|
-
import { z as
|
|
19725
|
+
import { z as z64 } from "zod";
|
|
19280
19726
|
|
|
19281
19727
|
// src/lib/people.ts
|
|
19282
19728
|
init_config();
|
|
19283
19729
|
import { readFile as readFile5, writeFile as writeFile6, mkdir as mkdir5 } from "fs/promises";
|
|
19284
|
-
import { existsSync as
|
|
19285
|
-
import
|
|
19286
|
-
var PEOPLE_PATH =
|
|
19730
|
+
import { existsSync as existsSync30, readFileSync as readFileSync26 } from "fs";
|
|
19731
|
+
import path38 from "path";
|
|
19732
|
+
var PEOPLE_PATH = path38.join(EXE_AI_DIR, "people.json");
|
|
19287
19733
|
async function loadPeople() {
|
|
19288
|
-
if (!
|
|
19734
|
+
if (!existsSync30(PEOPLE_PATH)) return [];
|
|
19289
19735
|
try {
|
|
19290
19736
|
const raw = await readFile5(PEOPLE_PATH, "utf-8");
|
|
19291
19737
|
return JSON.parse(raw);
|
|
@@ -19294,7 +19740,7 @@ async function loadPeople() {
|
|
|
19294
19740
|
}
|
|
19295
19741
|
}
|
|
19296
19742
|
async function savePeople(people) {
|
|
19297
|
-
await mkdir5(
|
|
19743
|
+
await mkdir5(path38.dirname(PEOPLE_PATH), { recursive: true });
|
|
19298
19744
|
await writeFile6(PEOPLE_PATH, JSON.stringify(people, null, 2) + "\n", "utf-8");
|
|
19299
19745
|
}
|
|
19300
19746
|
async function addPerson(person) {
|
|
@@ -19324,10 +19770,10 @@ function registerAddPerson(server2) {
|
|
|
19324
19770
|
title: "Add Person",
|
|
19325
19771
|
description: "Add or update a key human in the people roster. Used for co-founders, partners, customers \u2014 anyone agents need to know about.",
|
|
19326
19772
|
inputSchema: {
|
|
19327
|
-
name:
|
|
19328
|
-
role:
|
|
19329
|
-
relationship:
|
|
19330
|
-
notes:
|
|
19773
|
+
name: z64.string().describe("Person's name"),
|
|
19774
|
+
role: z64.string().describe("Their role (e.g. co-founder, customer, partner)"),
|
|
19775
|
+
relationship: z64.string().describe("Relationship to the organization (e.g. co-founder, early adopter, investor)"),
|
|
19776
|
+
notes: z64.string().optional().describe("Additional context about this person")
|
|
19331
19777
|
}
|
|
19332
19778
|
},
|
|
19333
19779
|
async ({ name, role, relationship, notes }) => {
|
|
@@ -19373,7 +19819,7 @@ function registerGetPerson(server2) {
|
|
|
19373
19819
|
title: "Get Person",
|
|
19374
19820
|
description: "Look up a specific person by name from the people roster.",
|
|
19375
19821
|
inputSchema: {
|
|
19376
|
-
name:
|
|
19822
|
+
name: z64.string().describe("Person's name to look up")
|
|
19377
19823
|
}
|
|
19378
19824
|
},
|
|
19379
19825
|
async ({ name }) => {
|
|
@@ -19401,7 +19847,7 @@ init_active_agent();
|
|
|
19401
19847
|
init_agent_config();
|
|
19402
19848
|
init_runtime_table();
|
|
19403
19849
|
init_employees();
|
|
19404
|
-
import { z as
|
|
19850
|
+
import { z as z65 } from "zod";
|
|
19405
19851
|
function registerSetAgentConfig(server2) {
|
|
19406
19852
|
server2.registerTool(
|
|
19407
19853
|
"set_agent_config",
|
|
@@ -19409,9 +19855,9 @@ function registerSetAgentConfig(server2) {
|
|
|
19409
19855
|
title: "Set Agent Config",
|
|
19410
19856
|
description: "Set or view per-agent runtime + model configuration. Controls which runtime (claude, codex, opencode) and model each agent uses when dispatched. COO-only. Omit runtime/model to view current config for an agent or all agents.",
|
|
19411
19857
|
inputSchema: {
|
|
19412
|
-
agent_id:
|
|
19413
|
-
runtime:
|
|
19414
|
-
model:
|
|
19858
|
+
agent_id: z65.string().optional().describe("Agent name, or 'default' for org-wide default. Omit to view all agents."),
|
|
19859
|
+
runtime: z65.string().optional().describe(`Runtime: ${Object.keys(KNOWN_RUNTIMES).join(", ")}`),
|
|
19860
|
+
model: z65.string().optional().describe("Model name (e.g. claude-opus-4, gpt-5.4, anthropic/claude-sonnet-4-6)")
|
|
19415
19861
|
}
|
|
19416
19862
|
},
|
|
19417
19863
|
async ({ agent_id, runtime, model }) => {
|
|
@@ -19604,6 +20050,8 @@ registerListWikiPages(server);
|
|
|
19604
20050
|
registerGetWikiPage(server);
|
|
19605
20051
|
registerUpdateWikiPage(server);
|
|
19606
20052
|
registerDeployClient(server);
|
|
20053
|
+
registerExportOrchestration(server);
|
|
20054
|
+
registerImportOrchestration(server);
|
|
19607
20055
|
registerQueryConversations(server);
|
|
19608
20056
|
registerLoadSkill(server);
|
|
19609
20057
|
registerConsolidateMemories(server);
|
|
@@ -19695,14 +20143,14 @@ try {
|
|
|
19695
20143
|
`
|
|
19696
20144
|
);
|
|
19697
20145
|
const thisFile = fileURLToPath5(import.meta.url);
|
|
19698
|
-
const backfillPath =
|
|
19699
|
-
|
|
20146
|
+
const backfillPath = path39.resolve(
|
|
20147
|
+
path39.dirname(thisFile),
|
|
19700
20148
|
"../bin/backfill-vectors.js"
|
|
19701
20149
|
);
|
|
19702
|
-
if (
|
|
20150
|
+
if (existsSync31(backfillPath)) {
|
|
19703
20151
|
const { EXE_AI_DIR: exeDir } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
19704
|
-
const logPath =
|
|
19705
|
-
|
|
20152
|
+
const logPath = path39.join(exeDir, "workers.log");
|
|
20153
|
+
mkdirSync17(path39.dirname(logPath), { recursive: true });
|
|
19706
20154
|
let logFd = "ignore";
|
|
19707
20155
|
try {
|
|
19708
20156
|
logFd = openSync3(logPath, "a");
|