@askexenow/exe-os 0.9.16 → 0.9.18
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 +1242 -909
- package/dist/bin/backfill-responses.js +1245 -912
- package/dist/bin/backfill-vectors.js +1244 -906
- package/dist/bin/cleanup-stale-review-tasks.js +1870 -417
- package/dist/bin/cli.js +217 -107
- package/dist/bin/exe-agent-config.js +2 -2
- package/dist/bin/exe-agent.js +62 -0
- package/dist/bin/exe-assign.js +346 -10
- package/dist/bin/exe-boot.js +387 -32
- package/dist/bin/exe-call.js +72 -2
- package/dist/bin/exe-cloud.js +8 -0
- package/dist/bin/exe-dispatch.js +1821 -225
- package/dist/bin/exe-doctor.js +720 -52
- package/dist/bin/exe-export-behaviors.js +1429 -148
- package/dist/bin/exe-forget.js +1408 -34
- package/dist/bin/exe-gateway.js +1629 -1295
- package/dist/bin/exe-heartbeat.js +1899 -448
- package/dist/bin/exe-kill.js +1624 -346
- package/dist/bin/exe-launch-agent.js +726 -90
- package/dist/bin/exe-link.js +27 -8
- package/dist/bin/exe-new-employee.js +75 -9
- package/dist/bin/exe-pending-messages.js +2769 -1316
- package/dist/bin/exe-pending-notifications.js +2829 -1376
- package/dist/bin/exe-pending-reviews.js +2847 -1392
- package/dist/bin/exe-rename.js +89 -8
- package/dist/bin/exe-review.js +1494 -312
- package/dist/bin/exe-search.js +1608 -1300
- package/dist/bin/exe-session-cleanup.js +194 -91
- package/dist/bin/exe-settings.js +10 -2
- package/dist/bin/exe-start-codex.js +769 -120
- package/dist/bin/exe-start-opencode.js +763 -108
- package/dist/bin/exe-status.js +1887 -434
- package/dist/bin/exe-team.js +1782 -324
- package/dist/bin/git-sweep.js +408 -33
- package/dist/bin/graph-backfill.js +681 -27
- package/dist/bin/graph-export.js +1419 -141
- package/dist/bin/install.js +4 -8
- package/dist/bin/intercom-check.js +8641 -0
- package/dist/bin/scan-tasks.js +553 -38
- package/dist/bin/setup.js +82 -10
- package/dist/bin/shard-migrate.js +682 -28
- package/dist/gateway/index.js +1629 -1295
- package/dist/hooks/bug-report-worker.js +1136 -183
- package/dist/hooks/codex-stop-task-finalizer.js +1060 -107
- package/dist/hooks/commit-complete.js +408 -33
- package/dist/hooks/error-recall.js +1608 -1300
- package/dist/hooks/ingest-worker.js +250 -7966
- package/dist/hooks/ingest.js +707 -119
- package/dist/hooks/instructions-loaded.js +383 -20
- package/dist/hooks/notification.js +383 -20
- package/dist/hooks/post-compact.js +384 -21
- package/dist/hooks/{response-ingest-worker.js → post-tool-combined.js} +4157 -1716
- package/dist/hooks/pre-compact.js +486 -45
- package/dist/hooks/pre-tool-use.js +385 -22
- package/dist/hooks/prompt-submit.js +291 -96
- package/dist/hooks/session-end.js +490 -48
- package/dist/hooks/session-start.js +236 -22
- package/dist/hooks/stop.js +192 -50
- package/dist/hooks/subagent-stop.js +95 -18
- package/dist/hooks/summary-worker.js +205 -361
- package/dist/index.js +221 -105
- package/dist/lib/agent-config.js +2 -2
- package/dist/lib/cloud-sync.js +27 -8
- package/dist/lib/consolidation.js +437 -41
- package/dist/lib/database.js +20 -8
- package/dist/lib/db-daemon-client.js +2 -2
- package/dist/lib/db.js +20 -8
- package/dist/lib/device-registry.js +27 -8
- package/dist/lib/employee-templates.js +62 -0
- package/dist/lib/employees.js +2 -2
- package/dist/lib/exe-daemon.js +6703 -6259
- package/dist/lib/hybrid-search.js +1608 -1300
- package/dist/lib/identity.js +1 -1
- package/dist/lib/messaging.js +11 -3
- package/dist/lib/reminders.js +1 -1
- package/dist/lib/schedules.js +718 -26
- package/dist/lib/session-registry.js +11 -0
- package/dist/lib/skill-learning.js +639 -9
- package/dist/lib/store.js +676 -27
- package/dist/lib/tasks.js +665 -27
- package/dist/lib/tmux-routing.js +732 -94
- package/dist/lib/token-spend.js +1 -1
- package/dist/mcp/server.js +856 -383
- package/dist/mcp/tools/complete-reminder.js +1 -1
- package/dist/mcp/tools/create-reminder.js +1 -1
- package/dist/mcp/tools/create-task.js +616 -46
- package/dist/mcp/tools/deactivate-behavior.js +9 -1
- package/dist/mcp/tools/list-reminders.js +1 -1
- package/dist/mcp/tools/list-tasks.js +10 -2
- package/dist/mcp/tools/send-message.js +11 -3
- package/dist/mcp/tools/update-task.js +677 -39
- package/dist/runtime/index.js +425 -37
- package/dist/tui/App.js +365 -34
- package/package.json +5 -2
- package/src/commands/exe/intercom.md +6 -17
- package/dist/bin/wiki-sync.js +0 -2991
- package/dist/hooks/prompt-ingest-worker.js +0 -3979
package/dist/mcp/server.js
CHANGED
|
@@ -313,7 +313,7 @@ var init_config = __esm({
|
|
|
313
313
|
});
|
|
314
314
|
|
|
315
315
|
// src/lib/daemon-auth.ts
|
|
316
|
-
import
|
|
316
|
+
import crypto from "crypto";
|
|
317
317
|
import path2 from "path";
|
|
318
318
|
import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
319
319
|
function normalizeToken(token) {
|
|
@@ -332,7 +332,7 @@ function readDaemonToken() {
|
|
|
332
332
|
function ensureDaemonToken(seed) {
|
|
333
333
|
const existing = readDaemonToken();
|
|
334
334
|
if (existing) return existing;
|
|
335
|
-
const token = normalizeToken(seed) ??
|
|
335
|
+
const token = normalizeToken(seed) ?? crypto.randomBytes(32).toString("hex");
|
|
336
336
|
ensurePrivateDirSync(EXE_AI_DIR);
|
|
337
337
|
writeFileSync(DAEMON_TOKEN_PATH, `${token}
|
|
338
338
|
`, "utf8");
|
|
@@ -850,8 +850,8 @@ 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
852
|
const { existsSync: existsSync34 } = await import("fs");
|
|
853
|
-
const
|
|
854
|
-
const modelPath =
|
|
853
|
+
const path44 = await import("path");
|
|
854
|
+
const modelPath = path44.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
855
855
|
if (!existsSync34(modelPath)) {
|
|
856
856
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
857
857
|
}
|
|
@@ -929,9 +929,9 @@ var MAX_RETRIES, BASE_DELAY_MS, MAX_JITTER_MS;
|
|
|
929
929
|
var init_db_retry = __esm({
|
|
930
930
|
"src/lib/db-retry.ts"() {
|
|
931
931
|
"use strict";
|
|
932
|
-
MAX_RETRIES =
|
|
933
|
-
BASE_DELAY_MS =
|
|
934
|
-
MAX_JITTER_MS =
|
|
932
|
+
MAX_RETRIES = 5;
|
|
933
|
+
BASE_DELAY_MS = 250;
|
|
934
|
+
MAX_JITTER_MS = 400;
|
|
935
935
|
}
|
|
936
936
|
});
|
|
937
937
|
|
|
@@ -1034,7 +1034,7 @@ var init_agent_config = __esm({
|
|
|
1034
1034
|
init_secure_files();
|
|
1035
1035
|
AGENT_CONFIG_PATH = path4.join(EXE_AI_DIR, "agent-config.json");
|
|
1036
1036
|
KNOWN_RUNTIMES = {
|
|
1037
|
-
claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
|
|
1037
|
+
claude: ["claude-opus-4.6", "claude-opus-4", "claude-sonnet-4.6", "claude-sonnet-4", "claude-haiku-4.5"],
|
|
1038
1038
|
codex: ["gpt-5.4", "gpt-5.5", "gpt-5.3-codex-spark", "o3", "o4-mini"],
|
|
1039
1039
|
opencode: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4", "google/gemini-2.5-pro", "deepseek/deepseek-r3", "minimax/minimax-m2.5"]
|
|
1040
1040
|
};
|
|
@@ -1044,7 +1044,7 @@ var init_agent_config = __esm({
|
|
|
1044
1044
|
opencode: "OpenCode (open source)"
|
|
1045
1045
|
};
|
|
1046
1046
|
DEFAULT_MODELS = {
|
|
1047
|
-
claude: "claude-opus-4",
|
|
1047
|
+
claude: "claude-opus-4.6",
|
|
1048
1048
|
codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
|
|
1049
1049
|
opencode: RUNTIME_TABLE.opencode?.defaultModel ?? "anthropic/claude-sonnet-4-6"
|
|
1050
1050
|
};
|
|
@@ -1993,7 +1993,7 @@ function createDaemonDbClient(fallbackClient) {
|
|
|
1993
1993
|
});
|
|
1994
1994
|
if (response.error) {
|
|
1995
1995
|
const errMsg = String(response.error);
|
|
1996
|
-
if (errMsg === "Not connected" || errMsg === "Request timeout" || errMsg === "Write failed") {
|
|
1996
|
+
if (errMsg === "Not connected" || errMsg === "Request timeout" || errMsg === "Write failed" || errMsg === "DB not initialized") {
|
|
1997
1997
|
process.stderr.write(`[db-daemon] Transport error (${errMsg}), falling back to direct
|
|
1998
1998
|
`);
|
|
1999
1999
|
return fallbackClient.execute(stmt);
|
|
@@ -2018,7 +2018,7 @@ function createDaemonDbClient(fallbackClient) {
|
|
|
2018
2018
|
});
|
|
2019
2019
|
if (response.error) {
|
|
2020
2020
|
const errMsg = String(response.error);
|
|
2021
|
-
if (errMsg === "Not connected" || errMsg === "Request timeout" || errMsg === "Write failed") {
|
|
2021
|
+
if (errMsg === "Not connected" || errMsg === "Request timeout" || errMsg === "Write failed" || errMsg === "DB not initialized") {
|
|
2022
2022
|
process.stderr.write(`[db-daemon] Batch transport error (${errMsg}), falling back to direct
|
|
2023
2023
|
`);
|
|
2024
2024
|
return fallbackClient.batch(stmts, mode);
|
|
@@ -2141,7 +2141,7 @@ async function initDatabase(config2) {
|
|
|
2141
2141
|
});
|
|
2142
2142
|
}, 3e4);
|
|
2143
2143
|
_walCheckpointTimer.unref();
|
|
2144
|
-
if (process.env.DATABASE_URL) {
|
|
2144
|
+
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2145
2145
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2146
2146
|
}
|
|
2147
2147
|
}
|
|
@@ -2152,7 +2152,7 @@ function getClient() {
|
|
|
2152
2152
|
if (!_adapterClient) {
|
|
2153
2153
|
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
2154
2154
|
}
|
|
2155
|
-
if (process.env.DATABASE_URL) {
|
|
2155
|
+
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2156
2156
|
return _adapterClient;
|
|
2157
2157
|
}
|
|
2158
2158
|
if (process.env.EXE_IS_DAEMON === "1") {
|
|
@@ -2164,9 +2164,11 @@ function getClient() {
|
|
|
2164
2164
|
return _resilientClient;
|
|
2165
2165
|
}
|
|
2166
2166
|
async function initDaemonClient() {
|
|
2167
|
-
if (process.env.DATABASE_URL) return;
|
|
2167
|
+
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
|
|
2168
2168
|
if (process.env.EXE_IS_DAEMON === "1") return;
|
|
2169
|
+
if (process.env.VITEST) return;
|
|
2169
2170
|
if (!_resilientClient) return;
|
|
2171
|
+
if (_daemonClient) return;
|
|
2170
2172
|
try {
|
|
2171
2173
|
const { initDaemonDbClient: initDaemonDbClient2 } = await Promise.resolve().then(() => (init_db_daemon_client(), db_daemon_client_exports));
|
|
2172
2174
|
_daemonClient = await initDaemonDbClient2(_resilientClient);
|
|
@@ -2315,6 +2317,13 @@ async function ensureSchema() {
|
|
|
2315
2317
|
});
|
|
2316
2318
|
} catch {
|
|
2317
2319
|
}
|
|
2320
|
+
try {
|
|
2321
|
+
await client.execute({
|
|
2322
|
+
sql: `ALTER TABLE behaviors ADD COLUMN vector F32_BLOB(${EMBEDDING_DIM})`,
|
|
2323
|
+
args: []
|
|
2324
|
+
});
|
|
2325
|
+
} catch {
|
|
2326
|
+
}
|
|
2318
2327
|
try {
|
|
2319
2328
|
await client.execute({
|
|
2320
2329
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
@@ -3185,6 +3194,7 @@ var init_database = __esm({
|
|
|
3185
3194
|
init_db_retry();
|
|
3186
3195
|
init_employees();
|
|
3187
3196
|
init_database_adapter();
|
|
3197
|
+
init_memory();
|
|
3188
3198
|
_client = null;
|
|
3189
3199
|
_resilientClient = null;
|
|
3190
3200
|
_walCheckpointTimer = null;
|
|
@@ -3803,6 +3813,68 @@ var init_platform_procedures = __esm({
|
|
|
3803
3813
|
domain: "architecture",
|
|
3804
3814
|
priority: "p0",
|
|
3805
3815
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
3816
|
+
},
|
|
3817
|
+
// --- MCP is the ONLY data interface ---
|
|
3818
|
+
{
|
|
3819
|
+
title: "MCP disconnect \u2014 ask the user, never work around it",
|
|
3820
|
+
domain: "workflow",
|
|
3821
|
+
priority: "p0",
|
|
3822
|
+
content: "If MCP tools are unavailable, disconnected, or returning connection errors: STOP. Tell the user clearly: 'MCP server is disconnected. Please run /mcp to reconnect.' Do NOT attempt workarounds \u2014 no raw Node imports, no direct DB access, no CLI hacks, no daemon socket calls. MCP is the ONLY data interface. Working around it wastes time, hits bundling issues, and bypasses the contract boundary. Ask once, wait, proceed when reconnected."
|
|
3823
|
+
},
|
|
3824
|
+
// --- MCP Tool Catalog (Layer 0 — every agent knows what tools exist) ---
|
|
3825
|
+
{
|
|
3826
|
+
title: "MCP tools \u2014 memory and search",
|
|
3827
|
+
domain: "tool-use",
|
|
3828
|
+
priority: "p1",
|
|
3829
|
+
content: "recall_my_memory: search your own memories (semantic + FTS). ask_team_memory: search a colleague's memories by agent name. store_memory: persist a memory (decisions, summaries, context). commit_memory: high-importance memory that survives consolidation. search_everything: unified search across memories, tasks, entities, conversations. get_session_context: temporal window of memories around a timestamp. consolidate_memories: merge duplicate/related memories into insights. get_memory_cardinality: count memories per agent (health check)."
|
|
3830
|
+
},
|
|
3831
|
+
{
|
|
3832
|
+
title: "MCP tools \u2014 task orchestration",
|
|
3833
|
+
domain: "tool-use",
|
|
3834
|
+
priority: "p1",
|
|
3835
|
+
content: "create_task: dispatch work to an employee (auto-spawns session). The ONLY dispatch path. list_tasks: query tasks by status, assignee, project. get_task: fetch full task details by ID. update_task: change status (in_progress, done, blocked, cancelled) + add result summary. close_task: finalize a reviewed task (COO only). checkpoint_task: save progress state for crash recovery. resume_employee: re-spawn an employee session for an existing task."
|
|
3836
|
+
},
|
|
3837
|
+
{
|
|
3838
|
+
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
3839
|
+
domain: "tool-use",
|
|
3840
|
+
priority: "p1",
|
|
3841
|
+
content: "query_relationships: find connections between entities in the knowledge graph. get_entity_neighbors: explore an entity's direct connections. get_hot_entities: find most-referenced entities (trending topics). get_graph_stats: graph health \u2014 entity/relationship counts, density. export_graph: export graph data for visualization. merge_entities: deduplicate entities (alias resolution). find_similar_trajectories: match tool-call patterns to past task solutions."
|
|
3842
|
+
},
|
|
3843
|
+
{
|
|
3844
|
+
title: "MCP tools \u2014 identity, behavior, and decisions",
|
|
3845
|
+
domain: "tool-use",
|
|
3846
|
+
priority: "p1",
|
|
3847
|
+
content: "get_identity: read an agent's exe.md (Layer 1 identity). update_identity: write an agent's exe.md. Identity > behavior \u2014 use for permanent rules. store_behavior: record a correction or pattern for an agent (Layer 2 expertise). list_behaviors: view an agent's active behaviors. deactivate_behavior: soft-delete a stale or conflicting behavior. store_decision: record an ADR (architectural decision record). get_decision: retrieve a past decision by query."
|
|
3848
|
+
},
|
|
3849
|
+
{
|
|
3850
|
+
title: "MCP tools \u2014 communication and messaging",
|
|
3851
|
+
domain: "tool-use",
|
|
3852
|
+
priority: "p1",
|
|
3853
|
+
content: "send_message: send supplementary context to another agent (NOT for actionable work \u2014 use create_task). acknowledge_messages: mark messages as read. send_whatsapp: send WhatsApp message via gateway (customer-facing alerts). query_conversations: search ingested conversations across all channels (WhatsApp, email, etc.)."
|
|
3854
|
+
},
|
|
3855
|
+
{
|
|
3856
|
+
title: "MCP tools \u2014 wiki, documents, and content",
|
|
3857
|
+
domain: "tool-use",
|
|
3858
|
+
priority: "p1",
|
|
3859
|
+
content: "create_wiki_page: create a wiki page in exe-wiki. list_wiki_pages: browse wiki pages. get_wiki_page: read a wiki page. update_wiki_page: edit a wiki page. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
|
|
3860
|
+
},
|
|
3861
|
+
{
|
|
3862
|
+
title: "MCP tools \u2014 system, operations, and admin",
|
|
3863
|
+
domain: "tool-use",
|
|
3864
|
+
priority: "p1",
|
|
3865
|
+
content: "get_agent_spend: token usage per agent/session (cost tracking). list_agent_sessions: view agent session history. get_session_kills: audit log of killed sessions. get_daemon_health: check exed daemon status. get_auto_wake_status: daemon auto-wake configuration. get_worker_gate: check worker deployment gates. run_memory_audit: health check \u2014 duplicates, null vectors, orphaned rows. run_consolidation: trigger sleep-time memory consolidation. cloud_sync: force a cloud sync cycle. backup_vps: trigger VPS backup."
|
|
3866
|
+
},
|
|
3867
|
+
{
|
|
3868
|
+
title: "MCP tools \u2014 config, licensing, and team",
|
|
3869
|
+
domain: "tool-use",
|
|
3870
|
+
priority: "p1",
|
|
3871
|
+
content: "set_agent_config: view/change per-agent runtime and model settings. list_employees: view the employee roster. add_person: add a person to the CRM contacts roster. list_people: browse CRM contacts. get_person: fetch contact details. get_license_status: check license validity. create_license: generate a new license key (admin). list_licenses: view all issued licenses. activate_license: activate a license on a device."
|
|
3872
|
+
},
|
|
3873
|
+
{
|
|
3874
|
+
title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
|
|
3875
|
+
domain: "tool-use",
|
|
3876
|
+
priority: "p1",
|
|
3877
|
+
content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. global_procedure: manage Layer 0 procedures (actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
|
|
3806
3878
|
}
|
|
3807
3879
|
];
|
|
3808
3880
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -3952,6 +4024,11 @@ async function initStore(options) {
|
|
|
3952
4024
|
encryptionKey: hexKey
|
|
3953
4025
|
});
|
|
3954
4026
|
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
4027
|
+
try {
|
|
4028
|
+
const { initDaemonClient: initDaemonClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
4029
|
+
await initDaemonClient2();
|
|
4030
|
+
} catch {
|
|
4031
|
+
}
|
|
3955
4032
|
if (!options?.lightweight) {
|
|
3956
4033
|
try {
|
|
3957
4034
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
@@ -4742,7 +4819,7 @@ __export(file_grep_exports, {
|
|
|
4742
4819
|
import { execSync as execSync3 } from "child_process";
|
|
4743
4820
|
import { readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync2, existsSync as existsSync10 } from "fs";
|
|
4744
4821
|
import path11 from "path";
|
|
4745
|
-
import
|
|
4822
|
+
import crypto2 from "crypto";
|
|
4746
4823
|
function hasRipgrep() {
|
|
4747
4824
|
if (_hasRg === null) {
|
|
4748
4825
|
try {
|
|
@@ -4775,7 +4852,7 @@ async function grepProjectFiles(query, projectRoot, options) {
|
|
|
4775
4852
|
const chunkCtx = getChunkContext(hit.filePath, hit.lineNumber);
|
|
4776
4853
|
const prefix = chunkCtx ? `[file: ${hit.filePath}:${hit.lineNumber} in ${chunkCtx}]` : `[file: ${hit.filePath}:${hit.lineNumber}]`;
|
|
4777
4854
|
return {
|
|
4778
|
-
id:
|
|
4855
|
+
id: crypto2.createHash("sha256").update(`${hit.filePath}:${hit.lineNumber}`).digest("hex").slice(0, 36),
|
|
4779
4856
|
agent_id: "project",
|
|
4780
4857
|
agent_role: "file",
|
|
4781
4858
|
session_id: "file-grep",
|
|
@@ -5714,10 +5791,10 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
5714
5791
|
};
|
|
5715
5792
|
try {
|
|
5716
5793
|
const fs = await import("fs");
|
|
5717
|
-
const
|
|
5718
|
-
const
|
|
5719
|
-
const logPath =
|
|
5720
|
-
fs.mkdirSync(
|
|
5794
|
+
const path44 = await import("path");
|
|
5795
|
+
const os18 = await import("os");
|
|
5796
|
+
const logPath = path44.join(os18.homedir(), ".exe-os", "search-quality.jsonl");
|
|
5797
|
+
fs.mkdirSync(path44.dirname(logPath), { recursive: true });
|
|
5721
5798
|
fs.appendFileSync(logPath, JSON.stringify(logEntry) + "\n");
|
|
5722
5799
|
} catch {
|
|
5723
5800
|
}
|
|
@@ -5812,7 +5889,7 @@ function rrfMergeMulti(lists, limit, k = RRF_K, weights) {
|
|
|
5812
5889
|
const importance = normalizedImportance(e.record.importance);
|
|
5813
5890
|
const confidence = sourceConfidence(e.record);
|
|
5814
5891
|
const frecency = frecencyBoost(e.record.last_accessed, e.record.timestamp);
|
|
5815
|
-
const baseScore = e.rrfScore * 0.
|
|
5892
|
+
const baseScore = e.rrfScore * 0.45 + recency * 0.24 + importance * 0.21 + confidence * 0.1;
|
|
5816
5893
|
const finalScore = baseScore * (1 + 0.3 * frecency);
|
|
5817
5894
|
return { score: finalScore, record: e.record };
|
|
5818
5895
|
});
|
|
@@ -7324,7 +7401,7 @@ var init_intercom_queue = __esm({
|
|
|
7324
7401
|
});
|
|
7325
7402
|
|
|
7326
7403
|
// src/lib/session-kill-telemetry.ts
|
|
7327
|
-
import
|
|
7404
|
+
import crypto5 from "crypto";
|
|
7328
7405
|
async function recordSessionKill(input) {
|
|
7329
7406
|
try {
|
|
7330
7407
|
const client = getClient();
|
|
@@ -7334,7 +7411,7 @@ async function recordSessionKill(input) {
|
|
|
7334
7411
|
ticks_idle, estimated_tokens_saved)
|
|
7335
7412
|
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
7336
7413
|
args: [
|
|
7337
|
-
|
|
7414
|
+
crypto5.randomUUID(),
|
|
7338
7415
|
input.sessionName,
|
|
7339
7416
|
input.agentId,
|
|
7340
7417
|
(/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -8295,7 +8372,7 @@ function isSessionBusy(sessionName) {
|
|
|
8295
8372
|
function isExeSession(sessionName) {
|
|
8296
8373
|
const matchesBaseWithInstance = (baseName) => sessionName === baseName || sessionName.startsWith(baseName) && /^\d+$/.test(sessionName.slice(baseName.length));
|
|
8297
8374
|
const coordinatorName = getCoordinatorName();
|
|
8298
|
-
return matchesBaseWithInstance(coordinatorName)
|
|
8375
|
+
return matchesBaseWithInstance(coordinatorName);
|
|
8299
8376
|
}
|
|
8300
8377
|
function sendIntercom(targetSession) {
|
|
8301
8378
|
const transport = getTransport();
|
|
@@ -8833,7 +8910,7 @@ var init_task_scope = __esm({
|
|
|
8833
8910
|
});
|
|
8834
8911
|
|
|
8835
8912
|
// src/lib/notifications.ts
|
|
8836
|
-
import
|
|
8913
|
+
import crypto6 from "crypto";
|
|
8837
8914
|
import path21 from "path";
|
|
8838
8915
|
import os10 from "os";
|
|
8839
8916
|
import {
|
|
@@ -8846,7 +8923,7 @@ import {
|
|
|
8846
8923
|
async function writeNotification(notification) {
|
|
8847
8924
|
try {
|
|
8848
8925
|
const client = getClient();
|
|
8849
|
-
const id =
|
|
8926
|
+
const id = crypto6.randomUUID();
|
|
8850
8927
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
8851
8928
|
const sessionScope = notification.sessionScope === void 0 ? getCurrentSessionScope() : notification.sessionScope;
|
|
8852
8929
|
await client.execute({
|
|
@@ -8968,7 +9045,7 @@ __export(tasks_crud_exports, {
|
|
|
8968
9045
|
updateTaskStatus: () => updateTaskStatus,
|
|
8969
9046
|
writeCheckpoint: () => writeCheckpoint
|
|
8970
9047
|
});
|
|
8971
|
-
import
|
|
9048
|
+
import crypto7 from "crypto";
|
|
8972
9049
|
import path22 from "path";
|
|
8973
9050
|
import os11 from "os";
|
|
8974
9051
|
import { execSync as execSync8 } from "child_process";
|
|
@@ -9089,7 +9166,7 @@ async function resolveTask(client, identifier, scopeSession) {
|
|
|
9089
9166
|
}
|
|
9090
9167
|
async function createTaskCore(input) {
|
|
9091
9168
|
const client = getClient();
|
|
9092
|
-
const id =
|
|
9169
|
+
const id = crypto7.randomUUID();
|
|
9093
9170
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9094
9171
|
const slug = slugify(input.title);
|
|
9095
9172
|
let earlySessionScope = null;
|
|
@@ -9098,15 +9175,20 @@ async function createTaskCore(input) {
|
|
|
9098
9175
|
const { resolveExeSession: resolveExeSession2 } = await Promise.resolve().then(() => (init_tmux_routing(), tmux_routing_exports));
|
|
9099
9176
|
const resolved = resolveExeSession2();
|
|
9100
9177
|
if (resolved && input.projectName) {
|
|
9101
|
-
const
|
|
9102
|
-
|
|
9103
|
-
if (sessionProject && sessionProject !== input.projectName) {
|
|
9104
|
-
scopeMismatchWarning = `session/project mismatch: session "${resolved}" owns "${sessionProject}" but task targets "${input.projectName}". Routed to default scope.`;
|
|
9105
|
-
process.stderr.write(`[create_task] ${scopeMismatchWarning}
|
|
9106
|
-
`);
|
|
9107
|
-
earlySessionScope = null;
|
|
9108
|
-
} else {
|
|
9178
|
+
const isCoordinatorSession = !resolved.includes("-");
|
|
9179
|
+
if (isCoordinatorSession) {
|
|
9109
9180
|
earlySessionScope = resolved;
|
|
9181
|
+
} else {
|
|
9182
|
+
const { getSessionProject: getSessionProject2 } = await Promise.resolve().then(() => (init_session_scope(), session_scope_exports));
|
|
9183
|
+
const sessionProject = getSessionProject2(resolved);
|
|
9184
|
+
if (sessionProject && sessionProject !== input.projectName) {
|
|
9185
|
+
scopeMismatchWarning = `session/project mismatch: session "${resolved}" owns "${sessionProject}" but task targets "${input.projectName}". Routed to default scope.`;
|
|
9186
|
+
process.stderr.write(`[create_task] ${scopeMismatchWarning}
|
|
9187
|
+
`);
|
|
9188
|
+
earlySessionScope = null;
|
|
9189
|
+
} else {
|
|
9190
|
+
earlySessionScope = resolved;
|
|
9191
|
+
}
|
|
9110
9192
|
}
|
|
9111
9193
|
} else {
|
|
9112
9194
|
earlySessionScope = resolved;
|
|
@@ -9683,6 +9765,10 @@ async function dispatchTaskToEmployee(input) {
|
|
|
9683
9765
|
if (transport.isAlive(sessionName)) {
|
|
9684
9766
|
const result = sendIntercom(sessionName);
|
|
9685
9767
|
const dispatched = result === "acknowledged" || result === "debounced" || result === "queued" ? "verified" : result === "delivered" ? "sent_unverified" : "session_dead";
|
|
9768
|
+
process.stderr.write(
|
|
9769
|
+
`[dispatch-audit] intercom \u2192 ${sessionName} | task="${input.title}" [${input.priority}] | result=${dispatched} (sendIntercom=${result})
|
|
9770
|
+
`
|
|
9771
|
+
);
|
|
9686
9772
|
return { dispatched, session: sessionName, crossProject };
|
|
9687
9773
|
} else {
|
|
9688
9774
|
const projectDir = input.projectDir ?? process.cwd();
|
|
@@ -9691,11 +9777,15 @@ async function dispatchTaskToEmployee(input) {
|
|
|
9691
9777
|
});
|
|
9692
9778
|
if (result.status === "failed") {
|
|
9693
9779
|
process.stderr.write(
|
|
9694
|
-
`[dispatch]
|
|
9780
|
+
`[dispatch-audit] SPAWN FAILED \u2192 ${input.assignedTo} | task="${input.title}" [${input.priority}] | error=${result.error}
|
|
9695
9781
|
`
|
|
9696
9782
|
);
|
|
9697
9783
|
return { dispatched: "session_missing" };
|
|
9698
9784
|
}
|
|
9785
|
+
process.stderr.write(
|
|
9786
|
+
`[dispatch-audit] SPAWNED \u2192 ${result.sessionName} | task="${input.title}" [${input.priority}]
|
|
9787
|
+
`
|
|
9788
|
+
);
|
|
9699
9789
|
return { dispatched: "spawned", session: result.sessionName, crossProject };
|
|
9700
9790
|
}
|
|
9701
9791
|
} catch {
|
|
@@ -9705,7 +9795,13 @@ async function dispatchTaskToEmployee(input) {
|
|
|
9705
9795
|
function notifyTaskDone() {
|
|
9706
9796
|
try {
|
|
9707
9797
|
const key = getSessionKey();
|
|
9708
|
-
if (key && !process.env.VITEST)
|
|
9798
|
+
if (key && !process.env.VITEST) {
|
|
9799
|
+
notifyParentExe(key);
|
|
9800
|
+
process.stderr.write(
|
|
9801
|
+
`[dispatch-audit] notifyTaskDone \u2192 parent coordinator (session=${key})
|
|
9802
|
+
`
|
|
9803
|
+
);
|
|
9804
|
+
}
|
|
9709
9805
|
} catch {
|
|
9710
9806
|
}
|
|
9711
9807
|
}
|
|
@@ -9727,22 +9823,29 @@ var init_tasks_notify = __esm({
|
|
|
9727
9823
|
});
|
|
9728
9824
|
|
|
9729
9825
|
// src/lib/behaviors.ts
|
|
9730
|
-
import
|
|
9826
|
+
import crypto8 from "crypto";
|
|
9731
9827
|
async function storeBehavior(opts) {
|
|
9732
9828
|
const client = getClient();
|
|
9733
|
-
const id =
|
|
9829
|
+
const id = crypto8.randomUUID();
|
|
9734
9830
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9831
|
+
let vector = null;
|
|
9832
|
+
try {
|
|
9833
|
+
const { embed: embed2 } = await Promise.resolve().then(() => (init_embedder(), embedder_exports));
|
|
9834
|
+
const vec = await embed2(opts.content);
|
|
9835
|
+
vector = new Float32Array(vec);
|
|
9836
|
+
} catch {
|
|
9837
|
+
}
|
|
9735
9838
|
await client.execute({
|
|
9736
|
-
sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, priority, content, active, created_at, updated_at)
|
|
9737
|
-
VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?)`,
|
|
9738
|
-
args: [id, opts.agentId, opts.projectName ?? null, opts.domain ?? null, opts.priority ?? "p1", opts.content, now, now]
|
|
9839
|
+
sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector)
|
|
9840
|
+
VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?, ?)`,
|
|
9841
|
+
args: [id, opts.agentId, opts.projectName ?? null, opts.domain ?? null, opts.priority ?? "p1", opts.content, now, now, vector ? vector.buffer : null]
|
|
9739
9842
|
});
|
|
9740
9843
|
return id;
|
|
9741
9844
|
}
|
|
9742
9845
|
async function listBehaviorsByDomain(agentId, domain) {
|
|
9743
9846
|
const client = getClient();
|
|
9744
9847
|
const result = await client.execute({
|
|
9745
|
-
sql: `SELECT id, agent_id, project_name, domain, priority, content, active, created_at, updated_at
|
|
9848
|
+
sql: `SELECT id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector
|
|
9746
9849
|
FROM behaviors
|
|
9747
9850
|
WHERE agent_id = ? AND domain = ? AND active = 1`,
|
|
9748
9851
|
args: [agentId, domain]
|
|
@@ -9756,7 +9859,8 @@ async function listBehaviorsByDomain(agentId, domain) {
|
|
|
9756
9859
|
content: String(r.content),
|
|
9757
9860
|
active: Number(r.active),
|
|
9758
9861
|
created_at: String(r.created_at),
|
|
9759
|
-
updated_at: String(r.updated_at)
|
|
9862
|
+
updated_at: String(r.updated_at),
|
|
9863
|
+
vector: r.vector ? Array.from(new Float32Array(r.vector)) : null
|
|
9760
9864
|
}));
|
|
9761
9865
|
}
|
|
9762
9866
|
async function deactivateBehavior(id) {
|
|
@@ -9787,7 +9891,7 @@ __export(skill_learning_exports, {
|
|
|
9787
9891
|
storeTrajectory: () => storeTrajectory,
|
|
9788
9892
|
sweepTrajectories: () => sweepTrajectories
|
|
9789
9893
|
});
|
|
9790
|
-
import
|
|
9894
|
+
import crypto9 from "crypto";
|
|
9791
9895
|
async function extractTrajectory(taskId, agentId) {
|
|
9792
9896
|
const client = getClient();
|
|
9793
9897
|
const result = await client.execute({
|
|
@@ -9816,11 +9920,11 @@ async function extractTrajectory(taskId, agentId) {
|
|
|
9816
9920
|
return signature;
|
|
9817
9921
|
}
|
|
9818
9922
|
function hashSignature(signature) {
|
|
9819
|
-
return
|
|
9923
|
+
return crypto9.createHash("sha256").update(signature.join("|")).digest("hex").slice(0, 16);
|
|
9820
9924
|
}
|
|
9821
9925
|
async function storeTrajectory(opts) {
|
|
9822
9926
|
const client = getClient();
|
|
9823
|
-
const id =
|
|
9927
|
+
const id = crypto9.randomUUID();
|
|
9824
9928
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9825
9929
|
const signatureHash = hashSignature(opts.signature);
|
|
9826
9930
|
await client.execute({
|
|
@@ -10943,10 +11047,10 @@ ${PLAN_MODE_COMPAT}
|
|
|
10943
11047
|
});
|
|
10944
11048
|
|
|
10945
11049
|
// src/lib/messaging.ts
|
|
10946
|
-
import
|
|
11050
|
+
import crypto10 from "crypto";
|
|
10947
11051
|
function generateUlid() {
|
|
10948
11052
|
const timestamp = Date.now().toString(36).padStart(10, "0");
|
|
10949
|
-
const random =
|
|
11053
|
+
const random = crypto10.randomBytes(10).toString("hex").slice(0, 16);
|
|
10950
11054
|
return (timestamp + random).toUpperCase();
|
|
10951
11055
|
}
|
|
10952
11056
|
function rowToMessage(row) {
|
|
@@ -11157,7 +11261,6 @@ async function selectUnconsolidated(client, limit = 200) {
|
|
|
11157
11261
|
sql: `SELECT id, agent_id, project_name, tool_name, raw_text, timestamp
|
|
11158
11262
|
FROM memories
|
|
11159
11263
|
WHERE consolidated = 0
|
|
11160
|
-
AND timestamp >= datetime('now', '-7 days')
|
|
11161
11264
|
ORDER BY timestamp DESC
|
|
11162
11265
|
LIMIT ?`,
|
|
11163
11266
|
args: [limit]
|
|
@@ -11212,11 +11315,12 @@ function groupMemories(memories) {
|
|
|
11212
11315
|
}
|
|
11213
11316
|
return clusters;
|
|
11214
11317
|
}
|
|
11215
|
-
function buildConsolidationPrompt(cluster) {
|
|
11318
|
+
function buildConsolidationPrompt(cluster, agentRole) {
|
|
11216
11319
|
const snippets = cluster.memories.map((m, i) => {
|
|
11217
11320
|
const text = m.raw_text.length > 200 ? m.raw_text.slice(0, 200) + "..." : m.raw_text;
|
|
11218
11321
|
return `${i + 1}. [${m.tool_name}] ${text}`;
|
|
11219
11322
|
}).join("\n");
|
|
11323
|
+
const rolePrompt = agentRole && ROLE_PROMPTS[agentRole] || DEFAULT_ROLE_PROMPT;
|
|
11220
11324
|
return `You are reviewing a set of work memories from an AI coding agent.
|
|
11221
11325
|
These are raw tool call records from ${cluster.dateRange}.
|
|
11222
11326
|
|
|
@@ -11225,19 +11329,15 @@ Agent: ${cluster.agentId} | Project: ${cluster.projectName} | Date: ${cluster.da
|
|
|
11225
11329
|
MEMORIES:
|
|
11226
11330
|
${snippets}
|
|
11227
11331
|
|
|
11228
|
-
|
|
11229
|
-
|
|
11230
|
-
1. KEY DECISIONS \u2014 choices that were made and why (at most 3)
|
|
11231
|
-
2. RECURRING PATTERNS \u2014 actions or approaches that repeated (at most 3)
|
|
11232
|
-
3. OPEN QUESTIONS \u2014 things that seem unresolved or risky (at most 2)
|
|
11332
|
+
${rolePrompt}
|
|
11233
11333
|
|
|
11234
11334
|
Format each as a single sentence. Be specific \u2014 include file names,
|
|
11235
11335
|
function names, and concrete details. Skip if no insight for a category.`;
|
|
11236
11336
|
}
|
|
11237
|
-
async function consolidateCluster(cluster, model) {
|
|
11337
|
+
async function consolidateCluster(cluster, model, agentRole) {
|
|
11238
11338
|
const Anthropic = (await import("@anthropic-ai/sdk")).default;
|
|
11239
11339
|
const client = new Anthropic();
|
|
11240
|
-
const prompt = buildConsolidationPrompt(cluster);
|
|
11340
|
+
const prompt = buildConsolidationPrompt(cluster, agentRole);
|
|
11241
11341
|
const response = await client.messages.create({
|
|
11242
11342
|
model,
|
|
11243
11343
|
max_tokens: 300,
|
|
@@ -11380,6 +11480,15 @@ async function runConsolidation(client, options) {
|
|
|
11380
11480
|
if (memories.length < 20) {
|
|
11381
11481
|
return { clustersProcessed: 0, memoriesConsolidated: 0 };
|
|
11382
11482
|
}
|
|
11483
|
+
let roleMap = {};
|
|
11484
|
+
try {
|
|
11485
|
+
const { loadEmployeesSync: loadEmployeesSync2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
11486
|
+
const employees = loadEmployeesSync2();
|
|
11487
|
+
for (const e of employees) {
|
|
11488
|
+
roleMap[e.name] = e.role;
|
|
11489
|
+
}
|
|
11490
|
+
} catch {
|
|
11491
|
+
}
|
|
11383
11492
|
const clusters = groupMemories(memories);
|
|
11384
11493
|
let clustersProcessed = 0;
|
|
11385
11494
|
let memoriesConsolidated = 0;
|
|
@@ -11388,21 +11497,27 @@ async function runConsolidation(client, options) {
|
|
|
11388
11497
|
if (cluster.memories.length < 3) continue;
|
|
11389
11498
|
try {
|
|
11390
11499
|
const isCoordinator = isCoordinatorName(cluster.agentId);
|
|
11391
|
-
|
|
11392
|
-
|
|
11393
|
-
|
|
11394
|
-
|
|
11395
|
-
|
|
11396
|
-
|
|
11397
|
-
|
|
11398
|
-
|
|
11399
|
-
|
|
11400
|
-
|
|
11401
|
-
|
|
11500
|
+
const agentRole = roleMap[cluster.agentId];
|
|
11501
|
+
const dedupCount = await dedupCluster(client, cluster, options.embedFn);
|
|
11502
|
+
memoriesConsolidated += dedupCount;
|
|
11503
|
+
const synthesis = await consolidateCluster(cluster, options.model, agentRole);
|
|
11504
|
+
if (!synthesis.trim()) {
|
|
11505
|
+
if (dedupCount > 0) clustersProcessed++;
|
|
11506
|
+
continue;
|
|
11507
|
+
}
|
|
11508
|
+
const result = await storeConsolidation(client, cluster, synthesis, options.embedFn);
|
|
11509
|
+
if (isCoordinator && options.wikiConfig) {
|
|
11510
|
+
await pushToWiki(
|
|
11511
|
+
{ ...result, projectName: cluster.projectName },
|
|
11512
|
+
options.wikiConfig
|
|
11513
|
+
).catch((err) => {
|
|
11514
|
+
process.stderr.write(
|
|
11515
|
+
`[consolidation] Wiki push error (non-fatal): ${err instanceof Error ? err.message : String(err)}
|
|
11402
11516
|
`
|
|
11403
|
-
|
|
11404
|
-
|
|
11405
|
-
|
|
11517
|
+
);
|
|
11518
|
+
});
|
|
11519
|
+
}
|
|
11520
|
+
if (isCoordinator) {
|
|
11406
11521
|
const sourceIds = result.sourceIds;
|
|
11407
11522
|
if (sourceIds.length > 0) {
|
|
11408
11523
|
const placeholders = sourceIds.map(() => "?").join(",");
|
|
@@ -11411,13 +11526,9 @@ async function runConsolidation(client, options) {
|
|
|
11411
11526
|
args: sourceIds
|
|
11412
11527
|
});
|
|
11413
11528
|
}
|
|
11414
|
-
} else {
|
|
11415
|
-
const dedupCount = await dedupCluster(client, cluster, options.embedFn);
|
|
11416
|
-
memoriesConsolidated += dedupCount;
|
|
11417
|
-
if (dedupCount === 0) continue;
|
|
11418
11529
|
}
|
|
11419
11530
|
clustersProcessed++;
|
|
11420
|
-
memoriesConsolidated +=
|
|
11531
|
+
memoriesConsolidated += cluster.memories.length;
|
|
11421
11532
|
} catch (err) {
|
|
11422
11533
|
process.stderr.write(
|
|
11423
11534
|
`[consolidation] Cluster failed (${cluster.projectName}/${cluster.dateRange}): ${err instanceof Error ? err.message : String(err)}
|
|
@@ -11493,18 +11604,47 @@ async function isUserIdle(client, idleMinutes = 30) {
|
|
|
11493
11604
|
async function countUnconsolidated(client) {
|
|
11494
11605
|
const result = await client.execute({
|
|
11495
11606
|
sql: `SELECT COUNT(*) as cnt FROM memories
|
|
11496
|
-
WHERE consolidated = 0
|
|
11497
|
-
AND timestamp >= datetime('now', '-7 days')`,
|
|
11607
|
+
WHERE consolidated = 0`,
|
|
11498
11608
|
args: []
|
|
11499
11609
|
});
|
|
11500
11610
|
return Number(result.rows[0]?.cnt ?? 0);
|
|
11501
11611
|
}
|
|
11502
|
-
var WIKI_FETCH_TIMEOUT_MS;
|
|
11612
|
+
var ROLE_PROMPTS, DEFAULT_ROLE_PROMPT, WIKI_FETCH_TIMEOUT_MS;
|
|
11503
11613
|
var init_consolidation = __esm({
|
|
11504
11614
|
"src/lib/consolidation.ts"() {
|
|
11505
11615
|
"use strict";
|
|
11506
11616
|
init_store();
|
|
11507
11617
|
init_employees();
|
|
11618
|
+
ROLE_PROMPTS = {
|
|
11619
|
+
"COO": `Extract EXACTLY THREE types of insights:
|
|
11620
|
+
1. KEY DECISIONS \u2014 choices that were made and why (at most 3)
|
|
11621
|
+
2. RECURRING PATTERNS \u2014 actions or approaches that repeated (at most 3)
|
|
11622
|
+
3. OPEN QUESTIONS \u2014 things that seem unresolved or risky (at most 2)`,
|
|
11623
|
+
"CTO": `Extract EXACTLY THREE types of insights:
|
|
11624
|
+
1. ARCHITECTURE DECISIONS \u2014 design choices, tradeoffs, delegation patterns (at most 3)
|
|
11625
|
+
2. REVIEW OUTCOMES \u2014 what was approved, rejected, or flagged during code review (at most 3)
|
|
11626
|
+
3. TECHNICAL DEBT \u2014 unresolved issues, deferred work, risks identified (at most 2)`,
|
|
11627
|
+
"Principal Engineer": `Extract EXACTLY THREE types of insights:
|
|
11628
|
+
1. CODE DECISIONS \u2014 implementation choices, patterns used, bugs fixed (at most 3)
|
|
11629
|
+
2. FILE CHANGES \u2014 key files modified and why (at most 3)
|
|
11630
|
+
3. BLOCKERS \u2014 things that slowed down or prevented progress (at most 2)`,
|
|
11631
|
+
"Staff Code Reviewer": `Extract EXACTLY THREE types of insights:
|
|
11632
|
+
1. AUDIT FINDINGS \u2014 issues found, severity, fix status (at most 3)
|
|
11633
|
+
2. RECURRING ISSUES \u2014 patterns that keep appearing across reviews (at most 3)
|
|
11634
|
+
3. QUALITY SIGNALS \u2014 areas of the codebase that are strong or weak (at most 2)`,
|
|
11635
|
+
"CMO": `Extract EXACTLY THREE types of insights:
|
|
11636
|
+
1. DESIGN DECISIONS \u2014 brand, layout, typography, or content choices made (at most 3)
|
|
11637
|
+
2. CONTENT STRATEGY \u2014 messaging, SEO, platform-specific decisions (at most 3)
|
|
11638
|
+
3. BRAND ALIGNMENT \u2014 consistency issues or guidelines established (at most 2)`,
|
|
11639
|
+
"AI Product Lead": `Extract EXACTLY THREE types of insights:
|
|
11640
|
+
1. RESEARCH FINDINGS \u2014 tools, repos, or models evaluated with conclusions (at most 3)
|
|
11641
|
+
2. COMPETITIVE GAPS \u2014 features or patterns worth adopting from competitors (at most 3)
|
|
11642
|
+
3. BUILD RECOMMENDATIONS \u2014 what to build, skip, or watch (at most 2)`
|
|
11643
|
+
};
|
|
11644
|
+
DEFAULT_ROLE_PROMPT = `Extract EXACTLY THREE types of insights:
|
|
11645
|
+
1. KEY DECISIONS \u2014 choices that were made and why (at most 3)
|
|
11646
|
+
2. RECURRING PATTERNS \u2014 actions or approaches that repeated (at most 3)
|
|
11647
|
+
3. OPEN QUESTIONS \u2014 things that seem unresolved or risky (at most 2)`;
|
|
11508
11648
|
WIKI_FETCH_TIMEOUT_MS = 1e4;
|
|
11509
11649
|
}
|
|
11510
11650
|
});
|
|
@@ -11518,8 +11658,8 @@ __export(wiki_client_exports, {
|
|
|
11518
11658
|
listDocuments: () => listDocuments,
|
|
11519
11659
|
listWorkspaces: () => listWorkspaces
|
|
11520
11660
|
});
|
|
11521
|
-
async function wikiFetch(config2,
|
|
11522
|
-
const url = `${config2.baseUrl}/api/v1${
|
|
11661
|
+
async function wikiFetch(config2, path44, method = "GET", body) {
|
|
11662
|
+
const url = `${config2.baseUrl}/api/v1${path44}`;
|
|
11523
11663
|
const headers = {
|
|
11524
11664
|
Authorization: `Bearer ${config2.apiKey}`,
|
|
11525
11665
|
"Content-Type": "application/json"
|
|
@@ -11552,7 +11692,7 @@ async function wikiFetch(config2, path45, method = "GET", body) {
|
|
|
11552
11692
|
}
|
|
11553
11693
|
}
|
|
11554
11694
|
if (!response.ok) {
|
|
11555
|
-
throw new Error(`Wiki API ${method} ${
|
|
11695
|
+
throw new Error(`Wiki API ${method} ${path44}: ${response.status} ${response.statusText}`);
|
|
11556
11696
|
}
|
|
11557
11697
|
return response.json();
|
|
11558
11698
|
} finally {
|
|
@@ -11995,7 +12135,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
11995
12135
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
11996
12136
|
import { spawn as spawn4 } from "child_process";
|
|
11997
12137
|
import { existsSync as existsSync33, openSync as openSync3, mkdirSync as mkdirSync17, closeSync as closeSync3 } from "fs";
|
|
11998
|
-
import
|
|
12138
|
+
import path43 from "path";
|
|
11999
12139
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
12000
12140
|
|
|
12001
12141
|
// src/mcp/tools/recall-my-memory.ts
|
|
@@ -12304,7 +12444,7 @@ init_store();
|
|
|
12304
12444
|
init_active_agent();
|
|
12305
12445
|
init_plan_limits();
|
|
12306
12446
|
import { z as z4 } from "zod";
|
|
12307
|
-
import
|
|
12447
|
+
import crypto3 from "crypto";
|
|
12308
12448
|
import { writeFileSync as writeFileSync6 } from "fs";
|
|
12309
12449
|
import path15 from "path";
|
|
12310
12450
|
function registerStoreMemory(server2) {
|
|
@@ -12355,7 +12495,7 @@ function registerStoreMemory(server2) {
|
|
|
12355
12495
|
vector = null;
|
|
12356
12496
|
needsBackfill = true;
|
|
12357
12497
|
}
|
|
12358
|
-
const memoryId =
|
|
12498
|
+
const memoryId = crypto3.randomUUID();
|
|
12359
12499
|
await writeMemory({
|
|
12360
12500
|
id: memoryId,
|
|
12361
12501
|
agent_id: agentId,
|
|
@@ -12398,7 +12538,7 @@ init_plan_limits();
|
|
|
12398
12538
|
init_active_agent();
|
|
12399
12539
|
init_employees();
|
|
12400
12540
|
import { z as z5 } from "zod";
|
|
12401
|
-
import
|
|
12541
|
+
import crypto4 from "crypto";
|
|
12402
12542
|
import { writeFileSync as writeFileSync7 } from "fs";
|
|
12403
12543
|
import path16 from "path";
|
|
12404
12544
|
function registerCommitMemory(server2) {
|
|
@@ -12447,7 +12587,7 @@ function registerCommitMemory(server2) {
|
|
|
12447
12587
|
vector = null;
|
|
12448
12588
|
needsBackfill = true;
|
|
12449
12589
|
}
|
|
12450
|
-
const memoryId =
|
|
12590
|
+
const memoryId = crypto4.randomUUID();
|
|
12451
12591
|
await assertMemoryLimit();
|
|
12452
12592
|
const memoryType = canCoordinate(agentId, agentRole) ? "adr" : "raw";
|
|
12453
12593
|
await writeMemory({
|
|
@@ -13383,10 +13523,10 @@ import { z as z16 } from "zod";
|
|
|
13383
13523
|
|
|
13384
13524
|
// src/lib/reminders.ts
|
|
13385
13525
|
init_database();
|
|
13386
|
-
import
|
|
13526
|
+
import crypto11 from "crypto";
|
|
13387
13527
|
async function createReminder(text, dueDate) {
|
|
13388
13528
|
const client = getClient();
|
|
13389
|
-
const id =
|
|
13529
|
+
const id = crypto11.randomUUID();
|
|
13390
13530
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
13391
13531
|
await client.execute({
|
|
13392
13532
|
sql: `INSERT INTO reminders (id, text, created_at, due_date) VALUES (?, ?, ?, ?)`,
|
|
@@ -13523,7 +13663,9 @@ function rowToBehavior(r) {
|
|
|
13523
13663
|
priority: r.priority ? String(r.priority) : "p1",
|
|
13524
13664
|
active: Number(r.active),
|
|
13525
13665
|
created_at: String(r.created_at),
|
|
13526
|
-
updated_at: String(r.updated_at)
|
|
13666
|
+
updated_at: String(r.updated_at),
|
|
13667
|
+
vector: null
|
|
13668
|
+
// Not needed for listing
|
|
13527
13669
|
};
|
|
13528
13670
|
}
|
|
13529
13671
|
function registerListBehaviors(server2) {
|
|
@@ -13770,7 +13912,7 @@ import { z as z23 } from "zod";
|
|
|
13770
13912
|
init_database();
|
|
13771
13913
|
init_embedder();
|
|
13772
13914
|
init_store();
|
|
13773
|
-
import
|
|
13915
|
+
import crypto12 from "crypto";
|
|
13774
13916
|
var WIKI_AGENT_ID = "wiki";
|
|
13775
13917
|
var WIKI_AGENT_ROLE = "Knowledge";
|
|
13776
13918
|
var WIKI_TOOL_NAME = "ingest_document";
|
|
@@ -13824,7 +13966,7 @@ async function resolveWorkspace(slug_or_id, name) {
|
|
|
13824
13966
|
if (existing.rows.length > 0) {
|
|
13825
13967
|
return rowToWorkspace(existing.rows[0]);
|
|
13826
13968
|
}
|
|
13827
|
-
const id =
|
|
13969
|
+
const id = crypto12.randomUUID();
|
|
13828
13970
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
13829
13971
|
const resolvedName = name ?? slug_or_id;
|
|
13830
13972
|
await client.execute({
|
|
@@ -13915,13 +14057,13 @@ async function ingestDocument(input) {
|
|
|
13915
14057
|
}));
|
|
13916
14058
|
const vectors = await embedTexts(enrichedChunks.map((c) => c.text));
|
|
13917
14059
|
const client = getClient();
|
|
13918
|
-
const documentId =
|
|
14060
|
+
const documentId = crypto12.randomUUID();
|
|
13919
14061
|
const uploadedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
13920
14062
|
const mime = input.mime ?? null;
|
|
13921
14063
|
const sourceType = input.source_type ?? DEFAULT_SOURCE_TYPE;
|
|
13922
14064
|
const userId = input.user_id ?? null;
|
|
13923
14065
|
const documentMetadata = input.document_metadata != null ? JSON.stringify(input.document_metadata) : null;
|
|
13924
|
-
const chunkIds = input.chunks.map(() =>
|
|
14066
|
+
const chunkIds = input.chunks.map(() => crypto12.randomUUID());
|
|
13925
14067
|
const versions = reserveVersions(input.chunks.length);
|
|
13926
14068
|
const documentStmt = {
|
|
13927
14069
|
sql: `INSERT INTO documents
|
|
@@ -14593,8 +14735,18 @@ function isScheduledTrigger(trigger) {
|
|
|
14593
14735
|
// src/lib/schedules.ts
|
|
14594
14736
|
init_database();
|
|
14595
14737
|
init_store();
|
|
14596
|
-
import
|
|
14738
|
+
import crypto13 from "crypto";
|
|
14597
14739
|
import { execSync as execSync9 } from "child_process";
|
|
14740
|
+
var CRON_FIELD = /^[\d*/,\-]+$/;
|
|
14741
|
+
function isValidCron(cron) {
|
|
14742
|
+
const fields = cron.trim().split(/\s+/);
|
|
14743
|
+
if (fields.length !== 5) return false;
|
|
14744
|
+
return fields.every((f) => CRON_FIELD.test(f));
|
|
14745
|
+
}
|
|
14746
|
+
var SAFE_ID = /^[a-zA-Z0-9_\-]+$/;
|
|
14747
|
+
function isValidScheduleId(id) {
|
|
14748
|
+
return SAFE_ID.test(id) && id.length <= 128;
|
|
14749
|
+
}
|
|
14598
14750
|
async function ensureDb() {
|
|
14599
14751
|
if (!isInitialized()) {
|
|
14600
14752
|
await initStore();
|
|
@@ -14660,9 +14812,12 @@ function parseHumanCron(input) {
|
|
|
14660
14812
|
return `${minute} ${hour} * * ${dow}`;
|
|
14661
14813
|
}
|
|
14662
14814
|
async function createSchedule(input) {
|
|
14815
|
+
if (!isValidCron(input.cron)) {
|
|
14816
|
+
throw new Error(`Invalid cron expression: ${input.cron}. Must be 5 fields with only digits, *, /, -, comma.`);
|
|
14817
|
+
}
|
|
14663
14818
|
await ensureDb();
|
|
14664
14819
|
const client = getClient();
|
|
14665
|
-
const id =
|
|
14820
|
+
const id = crypto13.randomUUID().slice(0, 8);
|
|
14666
14821
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
14667
14822
|
const prompt = input.prompt ?? input.description;
|
|
14668
14823
|
await client.execute({
|
|
@@ -14697,6 +14852,12 @@ async function createSchedule(input) {
|
|
|
14697
14852
|
};
|
|
14698
14853
|
}
|
|
14699
14854
|
function addToCrontab(id, cron, prompt, projectDir) {
|
|
14855
|
+
if (!isValidCron(cron)) {
|
|
14856
|
+
throw new Error(`Invalid cron expression: ${cron}`);
|
|
14857
|
+
}
|
|
14858
|
+
if (!isValidScheduleId(id)) {
|
|
14859
|
+
throw new Error(`Invalid schedule ID: ${id}`);
|
|
14860
|
+
}
|
|
14700
14861
|
try {
|
|
14701
14862
|
const cwd = projectDir ? `cd ${JSON.stringify(projectDir)} && ` : "";
|
|
14702
14863
|
const escapedPrompt = prompt.replace(/"/g, '\\"');
|
|
@@ -14705,7 +14866,8 @@ function addToCrontab(id, cron, prompt, projectDir) {
|
|
|
14705
14866
|
`(crontab -l 2>/dev/null; echo ${JSON.stringify(entry)}) | crontab -`,
|
|
14706
14867
|
{ timeout: 5e3, stdio: "ignore" }
|
|
14707
14868
|
);
|
|
14708
|
-
} catch {
|
|
14869
|
+
} catch (err) {
|
|
14870
|
+
if (err instanceof Error && err.message.startsWith("Invalid")) throw err;
|
|
14709
14871
|
}
|
|
14710
14872
|
}
|
|
14711
14873
|
|
|
@@ -15320,7 +15482,7 @@ init_database();
|
|
|
15320
15482
|
import { z as z32 } from "zod";
|
|
15321
15483
|
|
|
15322
15484
|
// src/lib/graph-rag.ts
|
|
15323
|
-
import
|
|
15485
|
+
import crypto14 from "crypto";
|
|
15324
15486
|
|
|
15325
15487
|
// src/lib/code-chunker.ts
|
|
15326
15488
|
import ts from "typescript";
|
|
@@ -15331,7 +15493,7 @@ function normalizeEntityName(name) {
|
|
|
15331
15493
|
}
|
|
15332
15494
|
function entityId(name, type) {
|
|
15333
15495
|
const normalized = normalizeEntityName(name);
|
|
15334
|
-
return
|
|
15496
|
+
return crypto14.createHash("sha256").update(`${normalized}::${type.toLowerCase()}`).digest("hex").slice(0, 16);
|
|
15335
15497
|
}
|
|
15336
15498
|
async function registerAlias(client, alias, canonicalEntityId) {
|
|
15337
15499
|
const normalized = normalizeEntityName(alias);
|
|
@@ -16065,9 +16227,9 @@ var HostingerApiClient = class {
|
|
|
16065
16227
|
}
|
|
16066
16228
|
this.lastRequestTime = Date.now();
|
|
16067
16229
|
}
|
|
16068
|
-
async request(method,
|
|
16230
|
+
async request(method, path44, body) {
|
|
16069
16231
|
await this.rateLimit();
|
|
16070
|
-
const url = `${this.baseUrl}${
|
|
16232
|
+
const url = `${this.baseUrl}${path44}`;
|
|
16071
16233
|
const headers = {
|
|
16072
16234
|
Authorization: `Bearer ${this.apiKey}`,
|
|
16073
16235
|
"Content-Type": "application/json",
|
|
@@ -16140,8 +16302,8 @@ async function requestCloudflare(cfApiToken, zoneId, options) {
|
|
|
16140
16302
|
}
|
|
16141
16303
|
return envelope.result;
|
|
16142
16304
|
}
|
|
16143
|
-
function buildUrl(zoneId,
|
|
16144
|
-
const normalizedPath =
|
|
16305
|
+
function buildUrl(zoneId, path44 = "/dns_records", query) {
|
|
16306
|
+
const normalizedPath = path44.startsWith("/") ? path44 : `/${path44}`;
|
|
16145
16307
|
const url = new URL(
|
|
16146
16308
|
`${CLOUDFLARE_API_BASE_URL}/zones/${zoneId}${normalizedPath}`
|
|
16147
16309
|
);
|
|
@@ -17164,65 +17326,467 @@ Consolidated summaries stored as tier-1 (importance=9) memories.`
|
|
|
17164
17326
|
);
|
|
17165
17327
|
}
|
|
17166
17328
|
|
|
17167
|
-
// src/mcp/tools/
|
|
17168
|
-
|
|
17329
|
+
// src/mcp/tools/behavior.ts
|
|
17330
|
+
init_behaviors();
|
|
17169
17331
|
init_active_agent();
|
|
17332
|
+
init_project_name();
|
|
17333
|
+
init_database();
|
|
17170
17334
|
init_employees();
|
|
17171
17335
|
import { z as z43 } from "zod";
|
|
17172
|
-
function
|
|
17336
|
+
function rowToBehavior2(r) {
|
|
17337
|
+
return {
|
|
17338
|
+
id: String(r.id),
|
|
17339
|
+
agent_id: String(r.agent_id),
|
|
17340
|
+
project_name: r.project_name ? String(r.project_name) : null,
|
|
17341
|
+
domain: r.domain ? String(r.domain) : null,
|
|
17342
|
+
content: String(r.content),
|
|
17343
|
+
priority: r.priority ? String(r.priority) : "p1",
|
|
17344
|
+
active: Number(r.active),
|
|
17345
|
+
created_at: String(r.created_at),
|
|
17346
|
+
updated_at: String(r.updated_at),
|
|
17347
|
+
vector: null
|
|
17348
|
+
};
|
|
17349
|
+
}
|
|
17350
|
+
function registerBehavior(server2) {
|
|
17173
17351
|
server2.registerTool(
|
|
17174
|
-
"
|
|
17352
|
+
"behavior",
|
|
17175
17353
|
{
|
|
17176
|
-
title: "
|
|
17177
|
-
description: "
|
|
17354
|
+
title: "Behavior",
|
|
17355
|
+
description: "Manage behavioral patterns, corrections, and reusable procedures for employees. Actions: store (create new), list (query existing), deactivate (soft-delete, restricted).",
|
|
17178
17356
|
inputSchema: {
|
|
17179
|
-
|
|
17180
|
-
content: z43.string().max(500).describe("The
|
|
17181
|
-
|
|
17182
|
-
|
|
17357
|
+
action: z43.enum(["store", "list", "deactivate"]).describe("Action to perform"),
|
|
17358
|
+
content: z43.string().max(500).optional().describe("The behavioral instruction \u2014 one clear sentence (store)"),
|
|
17359
|
+
domain: z43.string().optional().describe("Category: workflow, code-style, tool-use, communication, architecture, testing"),
|
|
17360
|
+
priority: z43.enum(["p0", "p1", "p2"]).optional().describe("Priority tier. p0 = always included. p1 = standard (default). p2 = nice-to-have."),
|
|
17361
|
+
agent_id: z43.string().optional().describe("Employee name. Defaults to current agent. Pass 'all' to list everyone's (list only)."),
|
|
17362
|
+
project_name: z43.string().optional().describe("Defaults to current project. Pass 'global' for a behavior that applies everywhere (store)."),
|
|
17363
|
+
behavior_id: z43.string().optional().describe("UUID of the behavior (deactivate)")
|
|
17183
17364
|
}
|
|
17184
17365
|
},
|
|
17185
|
-
async ({
|
|
17366
|
+
async ({ action, content, domain, priority, agent_id, project_name, behavior_id }) => {
|
|
17367
|
+
if (action === "list") {
|
|
17368
|
+
const client2 = getClient();
|
|
17369
|
+
const conditions = ["active = 1"];
|
|
17370
|
+
const args = [];
|
|
17371
|
+
if (agent_id !== "all") {
|
|
17372
|
+
const resolvedAgent = agent_id ?? getActiveAgent().agentId;
|
|
17373
|
+
conditions.push("agent_id = ?");
|
|
17374
|
+
args.push(resolvedAgent);
|
|
17375
|
+
}
|
|
17376
|
+
if (domain) {
|
|
17377
|
+
conditions.push("domain = ?");
|
|
17378
|
+
args.push(domain);
|
|
17379
|
+
}
|
|
17380
|
+
if (project_name) {
|
|
17381
|
+
conditions.push("(project_name IS NULL OR project_name = ?)");
|
|
17382
|
+
args.push(project_name);
|
|
17383
|
+
} else if (!agent_id || agent_id !== "all") {
|
|
17384
|
+
const proj = getProjectName();
|
|
17385
|
+
conditions.push("(project_name IS NULL OR project_name = ?)");
|
|
17386
|
+
args.push(proj);
|
|
17387
|
+
}
|
|
17388
|
+
const where = conditions.join(" AND ");
|
|
17389
|
+
const result2 = await client2.execute({
|
|
17390
|
+
sql: `SELECT id, agent_id, project_name, domain, content, active, created_at, updated_at
|
|
17391
|
+
FROM behaviors
|
|
17392
|
+
WHERE ${where}
|
|
17393
|
+
ORDER BY agent_id, domain, updated_at DESC
|
|
17394
|
+
LIMIT 50`,
|
|
17395
|
+
args
|
|
17396
|
+
});
|
|
17397
|
+
const behaviors = result2.rows.map((r) => rowToBehavior2(r));
|
|
17398
|
+
if (behaviors.length === 0) {
|
|
17399
|
+
return {
|
|
17400
|
+
content: [{ type: "text", text: "No behaviors found." }]
|
|
17401
|
+
};
|
|
17402
|
+
}
|
|
17403
|
+
const lines = behaviors.map((b) => {
|
|
17404
|
+
const scope = b.project_name ?? "global";
|
|
17405
|
+
const dom = b.domain ?? "general";
|
|
17406
|
+
return `- [${b.agent_id}] [${dom}] (${scope}) ${b.content}
|
|
17407
|
+
ID: ${b.id}`;
|
|
17408
|
+
});
|
|
17409
|
+
return {
|
|
17410
|
+
content: [{
|
|
17411
|
+
type: "text",
|
|
17412
|
+
text: `${behaviors.length} behavior(s):
|
|
17413
|
+
${lines.join("\n")}`
|
|
17414
|
+
}]
|
|
17415
|
+
};
|
|
17416
|
+
}
|
|
17417
|
+
if (action === "store") {
|
|
17418
|
+
if (!content) {
|
|
17419
|
+
return {
|
|
17420
|
+
content: [{
|
|
17421
|
+
type: "text",
|
|
17422
|
+
text: "Missing required field: content is required for store action."
|
|
17423
|
+
}],
|
|
17424
|
+
isError: true
|
|
17425
|
+
};
|
|
17426
|
+
}
|
|
17427
|
+
const resolvedAgent = agent_id ?? getActiveAgent().agentId;
|
|
17428
|
+
if (agent_id) {
|
|
17429
|
+
const caller2 = getActiveAgent();
|
|
17430
|
+
if (agent_id !== caller2.agentId) {
|
|
17431
|
+
const allowed2 = canCoordinate(caller2.agentId, caller2.agentRole);
|
|
17432
|
+
if (!allowed2) {
|
|
17433
|
+
return {
|
|
17434
|
+
content: [{
|
|
17435
|
+
type: "text",
|
|
17436
|
+
text: `Permission denied. Only the coordinator or founder sessions can store behaviors for other agents. You are "${caller2.agentId}".`
|
|
17437
|
+
}],
|
|
17438
|
+
isError: true
|
|
17439
|
+
};
|
|
17440
|
+
}
|
|
17441
|
+
}
|
|
17442
|
+
}
|
|
17443
|
+
let resolvedProject;
|
|
17444
|
+
if (project_name === "global" || project_name === null) {
|
|
17445
|
+
resolvedProject = void 0;
|
|
17446
|
+
} else if (project_name) {
|
|
17447
|
+
resolvedProject = project_name;
|
|
17448
|
+
} else {
|
|
17449
|
+
resolvedProject = getProjectName();
|
|
17450
|
+
}
|
|
17451
|
+
const id = await storeBehavior({
|
|
17452
|
+
agentId: resolvedAgent,
|
|
17453
|
+
content,
|
|
17454
|
+
domain: domain ?? void 0,
|
|
17455
|
+
projectName: resolvedProject,
|
|
17456
|
+
priority: priority ?? void 0
|
|
17457
|
+
});
|
|
17458
|
+
let responseText = `Behavior stored for ${resolvedAgent}. ID: ${id}`;
|
|
17459
|
+
if (domain) {
|
|
17460
|
+
const existing = await listBehaviorsByDomain(resolvedAgent, domain);
|
|
17461
|
+
const others = existing.filter((b) => b.id !== id);
|
|
17462
|
+
if (others.length > 0) {
|
|
17463
|
+
const list = others.map((b) => ` - [${b.id}] ${b.content}`).join("\n");
|
|
17464
|
+
responseText += `
|
|
17465
|
+
|
|
17466
|
+
Existing behaviors in [${domain}] domain:
|
|
17467
|
+
${list}
|
|
17468
|
+
Use /exe-forget to remove any that this supersedes.`;
|
|
17469
|
+
}
|
|
17470
|
+
}
|
|
17471
|
+
return {
|
|
17472
|
+
content: [{ type: "text", text: responseText }]
|
|
17473
|
+
};
|
|
17474
|
+
}
|
|
17186
17475
|
const caller = getActiveAgent();
|
|
17187
17476
|
const allowed = canCoordinate(caller.agentId, caller.agentRole);
|
|
17188
17477
|
if (!allowed) {
|
|
17189
17478
|
return {
|
|
17190
17479
|
content: [{
|
|
17191
17480
|
type: "text",
|
|
17192
|
-
text: `Permission denied. Only the coordinator or founder sessions can
|
|
17481
|
+
text: `Permission denied. Only the coordinator or founder sessions can deactivate behaviors. You are "${caller.agentId}".`
|
|
17193
17482
|
}],
|
|
17194
17483
|
isError: true
|
|
17195
17484
|
};
|
|
17196
17485
|
}
|
|
17197
|
-
|
|
17198
|
-
|
|
17199
|
-
|
|
17200
|
-
|
|
17201
|
-
|
|
17486
|
+
if (!behavior_id) {
|
|
17487
|
+
return {
|
|
17488
|
+
content: [{
|
|
17489
|
+
type: "text",
|
|
17490
|
+
text: "Missing required field: behavior_id is required for deactivate action."
|
|
17491
|
+
}],
|
|
17492
|
+
isError: true
|
|
17493
|
+
};
|
|
17494
|
+
}
|
|
17495
|
+
const client = getClient();
|
|
17496
|
+
const result = await client.execute({
|
|
17497
|
+
sql: "SELECT id, agent_id, content, domain, priority FROM behaviors WHERE id = ?",
|
|
17498
|
+
args: [behavior_id]
|
|
17202
17499
|
});
|
|
17500
|
+
if (result.rows.length === 0) {
|
|
17501
|
+
return {
|
|
17502
|
+
content: [{
|
|
17503
|
+
type: "text",
|
|
17504
|
+
text: `Behavior not found: ${behavior_id}`
|
|
17505
|
+
}],
|
|
17506
|
+
isError: true
|
|
17507
|
+
};
|
|
17508
|
+
}
|
|
17509
|
+
const row = result.rows[0];
|
|
17510
|
+
const wasActive = await deactivateBehavior(behavior_id);
|
|
17511
|
+
if (!wasActive) {
|
|
17512
|
+
return {
|
|
17513
|
+
content: [{
|
|
17514
|
+
type: "text",
|
|
17515
|
+
text: `Behavior ${behavior_id} was already inactive.`
|
|
17516
|
+
}]
|
|
17517
|
+
};
|
|
17518
|
+
}
|
|
17203
17519
|
return {
|
|
17204
17520
|
content: [{
|
|
17205
17521
|
type: "text",
|
|
17206
|
-
text: `
|
|
17207
|
-
ID: ${id}
|
|
17208
|
-
|
|
17209
|
-
Priority: ${priority
|
|
17210
|
-
|
|
17522
|
+
text: `Deactivated behavior for ${row.agent_id}.
|
|
17523
|
+
ID: ${row.id}
|
|
17524
|
+
Domain: ${row.domain ?? "none"}
|
|
17525
|
+
Priority: ${row.priority}
|
|
17526
|
+
Content: ${row.content}`
|
|
17211
17527
|
}]
|
|
17212
17528
|
};
|
|
17213
17529
|
}
|
|
17214
17530
|
);
|
|
17215
17531
|
}
|
|
17216
17532
|
|
|
17217
|
-
// src/mcp/tools/
|
|
17218
|
-
|
|
17219
|
-
|
|
17220
|
-
function registerListGlobalProcedures(server2) {
|
|
17533
|
+
// src/mcp/tools/reminder.ts
|
|
17534
|
+
import { z as z44 } from "zod";
|
|
17535
|
+
function registerReminder(server2) {
|
|
17221
17536
|
server2.registerTool(
|
|
17222
|
-
"
|
|
17537
|
+
"reminder",
|
|
17223
17538
|
{
|
|
17224
|
-
title: "
|
|
17225
|
-
description: "
|
|
17539
|
+
title: "Reminder",
|
|
17540
|
+
description: "Manage reminders for the founder. Shown in the boot brief every session. Actions: create (set new), list (view active), complete (mark done).",
|
|
17541
|
+
inputSchema: {
|
|
17542
|
+
action: z44.enum(["create", "list", "complete"]).describe("Action to perform"),
|
|
17543
|
+
text: z44.string().optional().describe("What to remind about (create)"),
|
|
17544
|
+
due_date: z44.string().optional().describe("Optional due date \u2014 ISO date (2026-04-01) or null for persistent (create)"),
|
|
17545
|
+
reminder_id: z44.string().optional().describe("Reminder UUID or text substring to match (complete)"),
|
|
17546
|
+
include_completed: z44.boolean().optional().default(false).describe("Include completed reminders (list)")
|
|
17547
|
+
}
|
|
17548
|
+
},
|
|
17549
|
+
async ({ action, text, due_date, reminder_id, include_completed }) => {
|
|
17550
|
+
if (action === "create") {
|
|
17551
|
+
if (!text) {
|
|
17552
|
+
return {
|
|
17553
|
+
content: [{ type: "text", text: "Missing required field: text is required for create action." }],
|
|
17554
|
+
isError: true
|
|
17555
|
+
};
|
|
17556
|
+
}
|
|
17557
|
+
const reminder2 = await createReminder(text, due_date);
|
|
17558
|
+
const dueStr = reminder2.dueDate ? ` (due: ${reminder2.dueDate})` : "";
|
|
17559
|
+
return {
|
|
17560
|
+
content: [{ type: "text", text: `Reminder set: "${reminder2.text}"${dueStr}` }]
|
|
17561
|
+
};
|
|
17562
|
+
}
|
|
17563
|
+
if (action === "list") {
|
|
17564
|
+
const reminders = await listReminders(include_completed);
|
|
17565
|
+
if (reminders.length === 0) {
|
|
17566
|
+
return {
|
|
17567
|
+
content: [{ type: "text", text: "No active reminders." }]
|
|
17568
|
+
};
|
|
17569
|
+
}
|
|
17570
|
+
const lines = reminders.map((r) => {
|
|
17571
|
+
const due = r.dueDate ? ` (due: ${r.dueDate})` : "";
|
|
17572
|
+
const done = r.completedAt ? " [DONE]" : "";
|
|
17573
|
+
return `\u2022 ${r.text}${due}${done} [id: ${r.id.slice(0, 8)}]`;
|
|
17574
|
+
});
|
|
17575
|
+
return {
|
|
17576
|
+
content: [{ type: "text", text: lines.join("\n") }]
|
|
17577
|
+
};
|
|
17578
|
+
}
|
|
17579
|
+
if (!reminder_id) {
|
|
17580
|
+
return {
|
|
17581
|
+
content: [{ type: "text", text: "Missing required field: reminder_id is required for complete action." }],
|
|
17582
|
+
isError: true
|
|
17583
|
+
};
|
|
17584
|
+
}
|
|
17585
|
+
const reminder = await completeReminder(reminder_id);
|
|
17586
|
+
if (!reminder) {
|
|
17587
|
+
return {
|
|
17588
|
+
content: [{ type: "text", text: `No active reminder matching "${reminder_id}".` }]
|
|
17589
|
+
};
|
|
17590
|
+
}
|
|
17591
|
+
return {
|
|
17592
|
+
content: [{ type: "text", text: `Reminder completed: "${reminder.text}"` }]
|
|
17593
|
+
};
|
|
17594
|
+
}
|
|
17595
|
+
);
|
|
17596
|
+
}
|
|
17597
|
+
|
|
17598
|
+
// src/mcp/tools/global-procedure.ts
|
|
17599
|
+
init_global_procedures();
|
|
17600
|
+
init_platform_procedures();
|
|
17601
|
+
init_active_agent();
|
|
17602
|
+
init_database();
|
|
17603
|
+
init_employees();
|
|
17604
|
+
import { z as z45 } from "zod";
|
|
17605
|
+
function registerGlobalProcedure(server2) {
|
|
17606
|
+
server2.registerTool(
|
|
17607
|
+
"global_procedure",
|
|
17608
|
+
{
|
|
17609
|
+
title: "Global Procedure",
|
|
17610
|
+
description: "Manage organization-wide procedures (Layer 0) that supersede identity, expertise, and experience. Actions: store (create new, restricted), list (view all, open), deactivate (soft-delete, restricted).",
|
|
17611
|
+
inputSchema: {
|
|
17612
|
+
action: z45.enum(["store", "list", "deactivate"]).describe("Action to perform"),
|
|
17613
|
+
title: z45.string().optional().describe("Short title for the procedure (store)"),
|
|
17614
|
+
content: z45.string().max(500).optional().describe("The procedure content \u2014 clear, actionable instruction (store)"),
|
|
17615
|
+
priority: z45.enum(["p0", "p1", "p2"]).optional().describe("Priority tier. p0 = always (default). p1 = standard. p2 = nice-to-have."),
|
|
17616
|
+
domain: z45.string().optional().describe("Category: workflow, code-style, communication, architecture, testing, security"),
|
|
17617
|
+
procedure_id: z45.string().optional().describe("UUID of the global procedure (deactivate)")
|
|
17618
|
+
}
|
|
17619
|
+
},
|
|
17620
|
+
async ({ action, title, content, priority, domain, procedure_id }) => {
|
|
17621
|
+
if (action === "list") {
|
|
17622
|
+
const customerProcs = await loadGlobalProcedures();
|
|
17623
|
+
if (customerProcs.length === 0) {
|
|
17624
|
+
return {
|
|
17625
|
+
content: [{
|
|
17626
|
+
type: "text",
|
|
17627
|
+
text: `No custom procedures. ${PLATFORM_PROCEDURES.length} platform procedures are active (shipped with exe-os, not editable).
|
|
17628
|
+
Use global_procedure with action "store" to add org-specific rules.`
|
|
17629
|
+
}]
|
|
17630
|
+
};
|
|
17631
|
+
}
|
|
17632
|
+
const lines = customerProcs.map(
|
|
17633
|
+
(p) => `[${p.id}] (${p.priority}) ${p.title}${p.domain ? ` [${p.domain}]` : ""}
|
|
17634
|
+
${p.content}`
|
|
17635
|
+
);
|
|
17636
|
+
return {
|
|
17637
|
+
content: [{
|
|
17638
|
+
type: "text",
|
|
17639
|
+
text: `Custom procedures (${customerProcs.length}) + ${PLATFORM_PROCEDURES.length} platform procedures (built-in):
|
|
17640
|
+
|
|
17641
|
+
${lines.join("\n\n")}`
|
|
17642
|
+
}]
|
|
17643
|
+
};
|
|
17644
|
+
}
|
|
17645
|
+
const caller = getActiveAgent();
|
|
17646
|
+
const allowed = canCoordinate(caller.agentId, caller.agentRole);
|
|
17647
|
+
if (!allowed) {
|
|
17648
|
+
return {
|
|
17649
|
+
content: [{
|
|
17650
|
+
type: "text",
|
|
17651
|
+
text: `Permission denied. Only the coordinator or founder sessions can ${action} global procedures. You are "${caller.agentId}".`
|
|
17652
|
+
}],
|
|
17653
|
+
isError: true
|
|
17654
|
+
};
|
|
17655
|
+
}
|
|
17656
|
+
if (action === "store") {
|
|
17657
|
+
if (!title || !content) {
|
|
17658
|
+
return {
|
|
17659
|
+
content: [{
|
|
17660
|
+
type: "text",
|
|
17661
|
+
text: "Missing required fields: title and content are required for store action."
|
|
17662
|
+
}],
|
|
17663
|
+
isError: true
|
|
17664
|
+
};
|
|
17665
|
+
}
|
|
17666
|
+
const id = await storeGlobalProcedure({
|
|
17667
|
+
title,
|
|
17668
|
+
content,
|
|
17669
|
+
priority: priority ?? "p0",
|
|
17670
|
+
domain: domain ?? void 0
|
|
17671
|
+
});
|
|
17672
|
+
return {
|
|
17673
|
+
content: [{
|
|
17674
|
+
type: "text",
|
|
17675
|
+
text: `Global procedure stored.
|
|
17676
|
+
ID: ${id}
|
|
17677
|
+
Title: ${title}
|
|
17678
|
+
Priority: ${priority ?? "p0"}
|
|
17679
|
+
Domain: ${domain ?? "none"}`
|
|
17680
|
+
}]
|
|
17681
|
+
};
|
|
17682
|
+
}
|
|
17683
|
+
if (!procedure_id) {
|
|
17684
|
+
return {
|
|
17685
|
+
content: [{
|
|
17686
|
+
type: "text",
|
|
17687
|
+
text: "Missing required field: procedure_id is required for deactivate action."
|
|
17688
|
+
}],
|
|
17689
|
+
isError: true
|
|
17690
|
+
};
|
|
17691
|
+
}
|
|
17692
|
+
const client = getClient();
|
|
17693
|
+
const result = await client.execute({
|
|
17694
|
+
sql: "SELECT id, title, content, priority, domain FROM global_procedures WHERE id = ?",
|
|
17695
|
+
args: [procedure_id]
|
|
17696
|
+
});
|
|
17697
|
+
if (result.rows.length === 0) {
|
|
17698
|
+
return {
|
|
17699
|
+
content: [{
|
|
17700
|
+
type: "text",
|
|
17701
|
+
text: `Global procedure not found: ${procedure_id}`
|
|
17702
|
+
}],
|
|
17703
|
+
isError: true
|
|
17704
|
+
};
|
|
17705
|
+
}
|
|
17706
|
+
const row = result.rows[0];
|
|
17707
|
+
const wasActive = await deactivateGlobalProcedure(procedure_id);
|
|
17708
|
+
if (!wasActive) {
|
|
17709
|
+
return {
|
|
17710
|
+
content: [{
|
|
17711
|
+
type: "text",
|
|
17712
|
+
text: `Global procedure ${procedure_id} was already inactive.`
|
|
17713
|
+
}]
|
|
17714
|
+
};
|
|
17715
|
+
}
|
|
17716
|
+
return {
|
|
17717
|
+
content: [{
|
|
17718
|
+
type: "text",
|
|
17719
|
+
text: `Deactivated global procedure.
|
|
17720
|
+
ID: ${row.id}
|
|
17721
|
+
Title: ${row.title}
|
|
17722
|
+
Priority: ${row.priority}
|
|
17723
|
+
Domain: ${row.domain ?? "none"}
|
|
17724
|
+
Content: ${row.content}`
|
|
17725
|
+
}]
|
|
17726
|
+
};
|
|
17727
|
+
}
|
|
17728
|
+
);
|
|
17729
|
+
}
|
|
17730
|
+
|
|
17731
|
+
// src/mcp/tools/store-global-procedure.ts
|
|
17732
|
+
init_global_procedures();
|
|
17733
|
+
init_active_agent();
|
|
17734
|
+
init_employees();
|
|
17735
|
+
import { z as z46 } from "zod";
|
|
17736
|
+
function registerStoreGlobalProcedure(server2) {
|
|
17737
|
+
server2.registerTool(
|
|
17738
|
+
"store_global_procedure",
|
|
17739
|
+
{
|
|
17740
|
+
title: "Store Global Procedure (use global_procedure instead)",
|
|
17741
|
+
description: "DEPRECATED \u2014 use global_procedure with action='store'. Create an organization-wide procedure (Layer 0). RESTRICTED: only coordinator or founder sessions.",
|
|
17742
|
+
inputSchema: {
|
|
17743
|
+
title: z46.string().describe("Short title for the procedure"),
|
|
17744
|
+
content: z46.string().max(500).describe("The procedure content \u2014 clear, actionable instruction"),
|
|
17745
|
+
priority: z46.enum(["p0", "p1", "p2"]).optional().describe("Priority tier. p0 = always (default)."),
|
|
17746
|
+
domain: z46.string().optional().describe("Category: workflow, code-style, communication, architecture, testing, security")
|
|
17747
|
+
}
|
|
17748
|
+
},
|
|
17749
|
+
async ({ title, content, priority, domain }) => {
|
|
17750
|
+
const caller = getActiveAgent();
|
|
17751
|
+
const allowed = canCoordinate(caller.agentId, caller.agentRole);
|
|
17752
|
+
if (!allowed) {
|
|
17753
|
+
return {
|
|
17754
|
+
content: [{
|
|
17755
|
+
type: "text",
|
|
17756
|
+
text: `Permission denied. Only the coordinator or founder sessions can create global procedures. You are "${caller.agentId}".`
|
|
17757
|
+
}],
|
|
17758
|
+
isError: true
|
|
17759
|
+
};
|
|
17760
|
+
}
|
|
17761
|
+
const id = await storeGlobalProcedure({
|
|
17762
|
+
title,
|
|
17763
|
+
content,
|
|
17764
|
+
priority: priority ?? "p0",
|
|
17765
|
+
domain: domain ?? void 0
|
|
17766
|
+
});
|
|
17767
|
+
return {
|
|
17768
|
+
content: [{
|
|
17769
|
+
type: "text",
|
|
17770
|
+
text: `Global procedure stored.
|
|
17771
|
+
ID: ${id}
|
|
17772
|
+
Title: ${title}
|
|
17773
|
+
Priority: ${priority ?? "p0"}
|
|
17774
|
+
Domain: ${domain ?? "none"}`
|
|
17775
|
+
}]
|
|
17776
|
+
};
|
|
17777
|
+
}
|
|
17778
|
+
);
|
|
17779
|
+
}
|
|
17780
|
+
|
|
17781
|
+
// src/mcp/tools/list-global-procedures.ts
|
|
17782
|
+
init_global_procedures();
|
|
17783
|
+
init_platform_procedures();
|
|
17784
|
+
function registerListGlobalProcedures(server2) {
|
|
17785
|
+
server2.registerTool(
|
|
17786
|
+
"list_global_procedures",
|
|
17787
|
+
{
|
|
17788
|
+
title: "List Global Procedures (use global_procedure instead)",
|
|
17789
|
+
description: "DEPRECATED \u2014 use global_procedure with action='list'. List all active organization-wide procedures (Layer 0).",
|
|
17226
17790
|
inputSchema: {}
|
|
17227
17791
|
},
|
|
17228
17792
|
async () => {
|
|
@@ -17232,7 +17796,7 @@ function registerListGlobalProcedures(server2) {
|
|
|
17232
17796
|
content: [{
|
|
17233
17797
|
type: "text",
|
|
17234
17798
|
text: `No custom procedures. ${PLATFORM_PROCEDURES.length} platform procedures are active (shipped with exe-os, not editable).
|
|
17235
|
-
Use
|
|
17799
|
+
Use global_procedure with action "store" to add org-specific rules.`
|
|
17236
17800
|
}]
|
|
17237
17801
|
};
|
|
17238
17802
|
}
|
|
@@ -17257,15 +17821,15 @@ init_global_procedures();
|
|
|
17257
17821
|
init_active_agent();
|
|
17258
17822
|
init_database();
|
|
17259
17823
|
init_employees();
|
|
17260
|
-
import { z as
|
|
17824
|
+
import { z as z47 } from "zod";
|
|
17261
17825
|
function registerDeactivateGlobalProcedure(server2) {
|
|
17262
17826
|
server2.registerTool(
|
|
17263
17827
|
"deactivate_global_procedure",
|
|
17264
17828
|
{
|
|
17265
|
-
title: "Deactivate Global Procedure",
|
|
17266
|
-
description: "Soft-delete a global procedure
|
|
17829
|
+
title: "Deactivate Global Procedure (use global_procedure instead)",
|
|
17830
|
+
description: "DEPRECATED \u2014 use global_procedure with action='deactivate'. Soft-delete a global procedure. RESTRICTED: only coordinator or founder sessions.",
|
|
17267
17831
|
inputSchema: {
|
|
17268
|
-
procedure_id:
|
|
17832
|
+
procedure_id: z47.string().describe("UUID of the global procedure to deactivate")
|
|
17269
17833
|
}
|
|
17270
17834
|
},
|
|
17271
17835
|
async ({ procedure_id }) => {
|
|
@@ -17320,7 +17884,7 @@ Content: ${row.content}`
|
|
|
17320
17884
|
}
|
|
17321
17885
|
|
|
17322
17886
|
// src/mcp/tools/search-everything.ts
|
|
17323
|
-
import { z as
|
|
17887
|
+
import { z as z48 } from "zod";
|
|
17324
17888
|
|
|
17325
17889
|
// src/lib/unified-search.ts
|
|
17326
17890
|
var DEFAULT_LIMIT = 10;
|
|
@@ -17487,11 +18051,11 @@ function registerSearchEverything(server2) {
|
|
|
17487
18051
|
title: "Search Everything",
|
|
17488
18052
|
description: "Search across all data stores \u2014 memories, conversations, and wiki \u2014 in one query. Returns merged results sorted by relevance with entity links.",
|
|
17489
18053
|
inputSchema: {
|
|
17490
|
-
query:
|
|
17491
|
-
sources:
|
|
18054
|
+
query: z48.string().describe("What to search for across all data stores"),
|
|
18055
|
+
sources: z48.array(z48.enum(["memory", "conversations", "wiki"])).optional().describe(
|
|
17492
18056
|
"Which sources to search (default: all). Options: memory, conversations, wiki"
|
|
17493
18057
|
),
|
|
17494
|
-
limit:
|
|
18058
|
+
limit: z48.coerce.number().int().min(1).max(50).optional().default(10).describe("Max results to return (default 10, max 50)")
|
|
17495
18059
|
}
|
|
17496
18060
|
},
|
|
17497
18061
|
async (params) => {
|
|
@@ -17552,8 +18116,8 @@ init_store();
|
|
|
17552
18116
|
init_active_agent();
|
|
17553
18117
|
init_database();
|
|
17554
18118
|
init_plan_limits();
|
|
17555
|
-
import { z as
|
|
17556
|
-
import
|
|
18119
|
+
import { z as z49 } from "zod";
|
|
18120
|
+
import crypto15 from "crypto";
|
|
17557
18121
|
function registerStoreDecision(server2) {
|
|
17558
18122
|
server2.registerTool(
|
|
17559
18123
|
"store_decision",
|
|
@@ -17561,13 +18125,13 @@ function registerStoreDecision(server2) {
|
|
|
17561
18125
|
title: "Store Decision",
|
|
17562
18126
|
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.",
|
|
17563
18127
|
inputSchema: {
|
|
17564
|
-
domain:
|
|
18128
|
+
domain: z49.string().describe(
|
|
17565
18129
|
"Domain key, e.g. 'auth-strategy', 'db-migration-approach', 'api-versioning'"
|
|
17566
18130
|
),
|
|
17567
|
-
decision:
|
|
17568
|
-
rationale:
|
|
17569
|
-
supersedes:
|
|
17570
|
-
project_name:
|
|
18131
|
+
decision: z49.string().describe("The decision text \u2014 what was decided"),
|
|
18132
|
+
rationale: z49.string().optional().describe("Why this decision was made \u2014 constraints, trade-offs, context"),
|
|
18133
|
+
supersedes: z49.string().optional().describe("UUID of the decision this supersedes (previous decision for this domain)"),
|
|
18134
|
+
project_name: z49.string().optional().describe("Project name")
|
|
17571
18135
|
}
|
|
17572
18136
|
},
|
|
17573
18137
|
async ({ domain, decision, rationale, supersedes, project_name }) => {
|
|
@@ -17591,7 +18155,7 @@ function registerStoreDecision(server2) {
|
|
|
17591
18155
|
} catch {
|
|
17592
18156
|
vector = null;
|
|
17593
18157
|
}
|
|
17594
|
-
const memoryId =
|
|
18158
|
+
const memoryId = crypto15.randomUUID();
|
|
17595
18159
|
if (supersedes) {
|
|
17596
18160
|
try {
|
|
17597
18161
|
const client = getClient();
|
|
@@ -17635,7 +18199,7 @@ Supersedes: ${supersedes}` : ""}`
|
|
|
17635
18199
|
|
|
17636
18200
|
// src/mcp/tools/get-decision.ts
|
|
17637
18201
|
init_database();
|
|
17638
|
-
import { z as
|
|
18202
|
+
import { z as z50 } from "zod";
|
|
17639
18203
|
function registerGetDecision(server2) {
|
|
17640
18204
|
server2.registerTool(
|
|
17641
18205
|
"get_decision",
|
|
@@ -17643,7 +18207,7 @@ function registerGetDecision(server2) {
|
|
|
17643
18207
|
title: "Get Decision",
|
|
17644
18208
|
description: "Retrieve the latest authoritative decision for a domain. Returns the current active decision and the supersession history.",
|
|
17645
18209
|
inputSchema: {
|
|
17646
|
-
domain:
|
|
18210
|
+
domain: z50.string().describe(
|
|
17647
18211
|
"Domain key to look up, e.g. 'auth-strategy', 'db-migration-approach'"
|
|
17648
18212
|
)
|
|
17649
18213
|
}
|
|
@@ -17706,7 +18270,7 @@ function registerGetDecision(server2) {
|
|
|
17706
18270
|
}
|
|
17707
18271
|
|
|
17708
18272
|
// src/mcp/tools/get-agent-spend.ts
|
|
17709
|
-
import { z as
|
|
18273
|
+
import { z as z51 } from "zod";
|
|
17710
18274
|
|
|
17711
18275
|
// src/lib/token-spend.ts
|
|
17712
18276
|
init_database();
|
|
@@ -17876,8 +18440,8 @@ function registerGetAgentSpend(server2) {
|
|
|
17876
18440
|
title: "Get Agent Spend",
|
|
17877
18441
|
description: "Get per-agent token spend attribution. Shows input, output, and cache tokens consumed by each agent over a time period, with estimated cost.",
|
|
17878
18442
|
inputSchema: {
|
|
17879
|
-
period:
|
|
17880
|
-
agent_id:
|
|
18443
|
+
period: z51.enum(["24h", "7d", "30d"]).default("7d").describe("Time period to query"),
|
|
18444
|
+
agent_id: z51.string().optional().describe("Filter to a specific agent (e.g. 'tom', 'yoshi')")
|
|
17881
18445
|
}
|
|
17882
18446
|
},
|
|
17883
18447
|
async ({ period, agent_id }) => {
|
|
@@ -17943,7 +18507,7 @@ function registerGetAgentSpend(server2) {
|
|
|
17943
18507
|
// src/mcp/tools/get-graph-stats.ts
|
|
17944
18508
|
init_database();
|
|
17945
18509
|
init_graph_query();
|
|
17946
|
-
import { z as
|
|
18510
|
+
import { z as z52 } from "zod";
|
|
17947
18511
|
function registerGetGraphStats(server2) {
|
|
17948
18512
|
server2.registerTool(
|
|
17949
18513
|
"get_graph_stats",
|
|
@@ -17951,7 +18515,7 @@ function registerGetGraphStats(server2) {
|
|
|
17951
18515
|
title: "Get Graph Stats",
|
|
17952
18516
|
description: "Get knowledge graph summary statistics: entity count, relationship count, and entity type breakdown.",
|
|
17953
18517
|
inputSchema: {
|
|
17954
|
-
_dummy:
|
|
18518
|
+
_dummy: z52.string().optional().describe("Unused \u2014 no input required")
|
|
17955
18519
|
}
|
|
17956
18520
|
},
|
|
17957
18521
|
async () => {
|
|
@@ -17993,7 +18557,7 @@ function registerGetGraphStats(server2) {
|
|
|
17993
18557
|
// src/mcp/tools/get-entity-neighbors.ts
|
|
17994
18558
|
init_database();
|
|
17995
18559
|
init_graph_query();
|
|
17996
|
-
import { z as
|
|
18560
|
+
import { z as z53 } from "zod";
|
|
17997
18561
|
function registerGetEntityNeighbors(server2) {
|
|
17998
18562
|
server2.registerTool(
|
|
17999
18563
|
"get_entity_neighbors",
|
|
@@ -18001,7 +18565,7 @@ function registerGetEntityNeighbors(server2) {
|
|
|
18001
18565
|
title: "Get Entity Neighbors",
|
|
18002
18566
|
description: "Get connected entities for a given entity name. Returns neighbors with relationship types, directions, and weights.",
|
|
18003
18567
|
inputSchema: {
|
|
18004
|
-
entity_name:
|
|
18568
|
+
entity_name: z53.string().describe("Name of the entity to find neighbors for")
|
|
18005
18569
|
}
|
|
18006
18570
|
},
|
|
18007
18571
|
async ({ entity_name }) => {
|
|
@@ -18070,7 +18634,7 @@ function registerGetEntityNeighbors(server2) {
|
|
|
18070
18634
|
// src/mcp/tools/get-hot-entities.ts
|
|
18071
18635
|
init_database();
|
|
18072
18636
|
init_graph_query();
|
|
18073
|
-
import { z as
|
|
18637
|
+
import { z as z54 } from "zod";
|
|
18074
18638
|
var PERIOD_MS = {
|
|
18075
18639
|
"24h": 24 * 60 * 60 * 1e3,
|
|
18076
18640
|
"7d": 7 * 24 * 60 * 60 * 1e3,
|
|
@@ -18083,8 +18647,8 @@ function registerGetHotEntities(server2) {
|
|
|
18083
18647
|
title: "Get Hot Entities",
|
|
18084
18648
|
description: "Get trending entities \u2014 those with the most new relationships in a time period. Surfaces what's most active in the knowledge graph.",
|
|
18085
18649
|
inputSchema: {
|
|
18086
|
-
period:
|
|
18087
|
-
limit:
|
|
18650
|
+
period: z54.enum(["24h", "7d", "30d"]).default("7d").describe("Time period to look back"),
|
|
18651
|
+
limit: z54.number().int().min(1).max(50).default(10).describe("Max entities to return")
|
|
18088
18652
|
}
|
|
18089
18653
|
},
|
|
18090
18654
|
async ({ period, limit }) => {
|
|
@@ -18132,7 +18696,7 @@ function registerGetHotEntities(server2) {
|
|
|
18132
18696
|
|
|
18133
18697
|
// src/mcp/tools/export-graph.ts
|
|
18134
18698
|
init_database();
|
|
18135
|
-
import { z as
|
|
18699
|
+
import { z as z55 } from "zod";
|
|
18136
18700
|
|
|
18137
18701
|
// src/lib/graph-export.ts
|
|
18138
18702
|
async function loadGraphData(client) {
|
|
@@ -18345,7 +18909,7 @@ function registerExportGraph(server2) {
|
|
|
18345
18909
|
title: "Export Graph",
|
|
18346
18910
|
description: "Export the knowledge graph as a markdown report (inline) or an interactive HTML visualization (writes file, returns path).",
|
|
18347
18911
|
inputSchema: {
|
|
18348
|
-
format:
|
|
18912
|
+
format: z55.enum(["html", "markdown"]).default("markdown").describe("Export format: markdown (inline) or html (file)")
|
|
18349
18913
|
}
|
|
18350
18914
|
},
|
|
18351
18915
|
async ({ format }) => {
|
|
@@ -18359,12 +18923,12 @@ function registerExportGraph(server2) {
|
|
|
18359
18923
|
}
|
|
18360
18924
|
const html = await exportGraphHTML(client);
|
|
18361
18925
|
const fs = await import("fs");
|
|
18362
|
-
const
|
|
18363
|
-
const
|
|
18364
|
-
const outDir =
|
|
18926
|
+
const path44 = await import("path");
|
|
18927
|
+
const os18 = await import("os");
|
|
18928
|
+
const outDir = path44.join(os18.homedir(), ".exe-os", "exports");
|
|
18365
18929
|
fs.mkdirSync(outDir, { recursive: true });
|
|
18366
18930
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
18367
|
-
const filePath =
|
|
18931
|
+
const filePath = path44.join(outDir, `graph-${timestamp}.html`);
|
|
18368
18932
|
fs.writeFileSync(filePath, html, "utf-8");
|
|
18369
18933
|
return {
|
|
18370
18934
|
content: [
|
|
@@ -18395,7 +18959,7 @@ Open in a browser to explore interactively.`
|
|
|
18395
18959
|
|
|
18396
18960
|
// src/mcp/tools/find-similar-trajectories.ts
|
|
18397
18961
|
init_skill_learning();
|
|
18398
|
-
import { z as
|
|
18962
|
+
import { z as z56 } from "zod";
|
|
18399
18963
|
function registerFindSimilarTrajectories(server2) {
|
|
18400
18964
|
server2.registerTool(
|
|
18401
18965
|
"find_similar_trajectories",
|
|
@@ -18403,7 +18967,7 @@ function registerFindSimilarTrajectories(server2) {
|
|
|
18403
18967
|
title: "Find Similar Trajectories",
|
|
18404
18968
|
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.',
|
|
18405
18969
|
inputSchema: {
|
|
18406
|
-
description:
|
|
18970
|
+
description: z56.string().describe(
|
|
18407
18971
|
'Tool sequence to match \u2014 comma-separated tool names (e.g. "Read, Grep, Edit, Bash:npm, Bash:git")'
|
|
18408
18972
|
)
|
|
18409
18973
|
}
|
|
@@ -18474,7 +19038,7 @@ ${withSkill.length} trajectory(s) already extracted into skill(s).`
|
|
|
18474
19038
|
|
|
18475
19039
|
// src/mcp/tools/get-session-kills.ts
|
|
18476
19040
|
init_session_kill_telemetry();
|
|
18477
|
-
import { z as
|
|
19041
|
+
import { z as z57 } from "zod";
|
|
18478
19042
|
var PERIOD_MS2 = {
|
|
18479
19043
|
"24h": 24 * 60 * 60 * 1e3,
|
|
18480
19044
|
"7d": 7 * 24 * 60 * 60 * 1e3,
|
|
@@ -18490,7 +19054,7 @@ function registerGetSessionKills(server2) {
|
|
|
18490
19054
|
title: "Get Session Kills",
|
|
18491
19055
|
description: "Get session kill telemetry: how many idle/TTL sessions were killed, tokens saved, and estimated cost savings over a time period.",
|
|
18492
19056
|
inputSchema: {
|
|
18493
|
-
period:
|
|
19057
|
+
period: z57.enum(["24h", "7d", "30d"]).default("7d").describe("Time period to query")
|
|
18494
19058
|
}
|
|
18495
19059
|
},
|
|
18496
19060
|
async ({ period }) => {
|
|
@@ -18530,7 +19094,7 @@ function registerGetSessionKills(server2) {
|
|
|
18530
19094
|
|
|
18531
19095
|
// src/mcp/tools/list-agent-sessions.ts
|
|
18532
19096
|
init_session_registry();
|
|
18533
|
-
import { z as
|
|
19097
|
+
import { z as z58 } from "zod";
|
|
18534
19098
|
function registerListAgentSessions(server2) {
|
|
18535
19099
|
server2.registerTool(
|
|
18536
19100
|
"list_agent_sessions",
|
|
@@ -18538,7 +19102,7 @@ function registerListAgentSessions(server2) {
|
|
|
18538
19102
|
title: "List Agent Sessions",
|
|
18539
19103
|
description: "List all registered agent sessions with their agent ID, project, PID, and registration time.",
|
|
18540
19104
|
inputSchema: {
|
|
18541
|
-
_placeholder:
|
|
19105
|
+
_placeholder: z58.string().optional().describe("No input required")
|
|
18542
19106
|
}
|
|
18543
19107
|
},
|
|
18544
19108
|
async () => {
|
|
@@ -18584,7 +19148,7 @@ function registerListAgentSessions(server2) {
|
|
|
18584
19148
|
}
|
|
18585
19149
|
|
|
18586
19150
|
// src/mcp/tools/get-daemon-health.ts
|
|
18587
|
-
import { z as
|
|
19151
|
+
import { z as z59 } from "zod";
|
|
18588
19152
|
import { existsSync as existsSync25, readFileSync as readFileSync22 } from "fs";
|
|
18589
19153
|
import path34 from "path";
|
|
18590
19154
|
import { homedir as homedir3 } from "os";
|
|
@@ -18615,7 +19179,7 @@ function registerGetDaemonHealth(server2) {
|
|
|
18615
19179
|
title: "Get Daemon Health",
|
|
18616
19180
|
description: "Check the embedding daemon (exed) health: whether it's running, its PID, uptime, and requests served.",
|
|
18617
19181
|
inputSchema: {
|
|
18618
|
-
_placeholder:
|
|
19182
|
+
_placeholder: z59.string().optional().describe("No input required")
|
|
18619
19183
|
}
|
|
18620
19184
|
},
|
|
18621
19185
|
async () => {
|
|
@@ -18667,7 +19231,7 @@ function registerGetDaemonHealth(server2) {
|
|
|
18667
19231
|
// src/mcp/tools/get-auto-wake-status.ts
|
|
18668
19232
|
init_database();
|
|
18669
19233
|
init_session_registry();
|
|
18670
|
-
import { z as
|
|
19234
|
+
import { z as z60 } from "zod";
|
|
18671
19235
|
|
|
18672
19236
|
// src/lib/daemon-orchestration.ts
|
|
18673
19237
|
init_tmux_routing();
|
|
@@ -18695,7 +19259,7 @@ function registerGetAutoWakeStatus(server2) {
|
|
|
18695
19259
|
title: "Get Auto-Wake Status",
|
|
18696
19260
|
description: "Check auto-wake status: orphaned tasks (assigned agent has no running session), tasks blocked by auto-wake retry limit, and session activity.",
|
|
18697
19261
|
inputSchema: {
|
|
18698
|
-
_placeholder:
|
|
19262
|
+
_placeholder: z60.string().optional().describe("No input required")
|
|
18699
19263
|
}
|
|
18700
19264
|
},
|
|
18701
19265
|
async () => {
|
|
@@ -18776,7 +19340,7 @@ function registerGetAutoWakeStatus(server2) {
|
|
|
18776
19340
|
// src/mcp/tools/get-worker-gate.ts
|
|
18777
19341
|
init_worker_gate();
|
|
18778
19342
|
init_config();
|
|
18779
|
-
import { z as
|
|
19343
|
+
import { z as z61 } from "zod";
|
|
18780
19344
|
import { readdirSync as readdirSync11, existsSync as existsSync28 } from "fs";
|
|
18781
19345
|
import path36 from "path";
|
|
18782
19346
|
var WORKER_PID_DIR2 = path36.join(EXE_AI_DIR, "worker-pids");
|
|
@@ -18814,7 +19378,7 @@ function registerGetWorkerGate(server2) {
|
|
|
18814
19378
|
title: "Get Worker Gate",
|
|
18815
19379
|
description: "Check worker concurrency gate status: how many worker slots are in use, the maximum allowed, and whether new workers can spawn.",
|
|
18816
19380
|
inputSchema: {
|
|
18817
|
-
_placeholder:
|
|
19381
|
+
_placeholder: z61.string().optional().describe("No input required")
|
|
18818
19382
|
}
|
|
18819
19383
|
},
|
|
18820
19384
|
async () => {
|
|
@@ -18850,7 +19414,7 @@ function registerGetWorkerGate(server2) {
|
|
|
18850
19414
|
|
|
18851
19415
|
// src/mcp/tools/run-memory-audit.ts
|
|
18852
19416
|
init_database();
|
|
18853
|
-
import { z as
|
|
19417
|
+
import { z as z62 } from "zod";
|
|
18854
19418
|
|
|
18855
19419
|
// src/bin/exe-doctor.ts
|
|
18856
19420
|
init_store();
|
|
@@ -19654,8 +20218,8 @@ function registerRunMemoryAudit(server2) {
|
|
|
19654
20218
|
title: "Run Memory Audit",
|
|
19655
20219
|
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).",
|
|
19656
20220
|
inputSchema: {
|
|
19657
|
-
agent_id:
|
|
19658
|
-
project_name:
|
|
20221
|
+
agent_id: z62.string().optional().describe("Filter audit to a specific agent"),
|
|
20222
|
+
project_name: z62.string().optional().describe("Filter audit to a specific project")
|
|
19659
20223
|
}
|
|
19660
20224
|
},
|
|
19661
20225
|
async ({ agent_id, project_name }) => {
|
|
@@ -19688,17 +20252,17 @@ function registerRunMemoryAudit(server2) {
|
|
|
19688
20252
|
}
|
|
19689
20253
|
|
|
19690
20254
|
// src/mcp/tools/cloud-sync.ts
|
|
19691
|
-
import { z as
|
|
20255
|
+
import { z as z63 } from "zod";
|
|
19692
20256
|
|
|
19693
20257
|
// src/lib/cloud-sync.ts
|
|
19694
20258
|
init_database();
|
|
19695
20259
|
import { readFileSync as readFileSync26, writeFileSync as writeFileSync20, existsSync as existsSync31, readdirSync as readdirSync12, mkdirSync as mkdirSync16, appendFileSync as appendFileSync2, unlinkSync as unlinkSync10, openSync as openSync2, closeSync as closeSync2 } from "fs";
|
|
19696
|
-
import
|
|
20260
|
+
import crypto17 from "crypto";
|
|
19697
20261
|
import path39 from "path";
|
|
19698
20262
|
import { homedir as homedir6 } from "os";
|
|
19699
20263
|
|
|
19700
20264
|
// src/lib/crypto.ts
|
|
19701
|
-
import
|
|
20265
|
+
import crypto16 from "crypto";
|
|
19702
20266
|
var ALGORITHM = "aes-256-gcm";
|
|
19703
20267
|
var IV_LENGTH = 12;
|
|
19704
20268
|
var TAG_LENGTH = 16;
|
|
@@ -19709,7 +20273,7 @@ function initSyncCrypto(masterKey) {
|
|
|
19709
20273
|
throw new Error(`Master key must be 32 bytes, got ${masterKey.length}`);
|
|
19710
20274
|
}
|
|
19711
20275
|
_syncKey = Buffer.from(
|
|
19712
|
-
|
|
20276
|
+
crypto16.hkdfSync("sha256", masterKey, "", SYNC_HKDF_INFO, 32)
|
|
19713
20277
|
);
|
|
19714
20278
|
}
|
|
19715
20279
|
function isSyncCryptoInitialized() {
|
|
@@ -19723,8 +20287,8 @@ function requireSyncKey() {
|
|
|
19723
20287
|
}
|
|
19724
20288
|
function encryptSyncBlob(data) {
|
|
19725
20289
|
const key = requireSyncKey();
|
|
19726
|
-
const iv =
|
|
19727
|
-
const cipher =
|
|
20290
|
+
const iv = crypto16.randomBytes(IV_LENGTH);
|
|
20291
|
+
const cipher = crypto16.createCipheriv(ALGORITHM, key, iv);
|
|
19728
20292
|
const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
|
|
19729
20293
|
const tag = cipher.getAuthTag();
|
|
19730
20294
|
return Buffer.concat([iv, encrypted, tag]).toString("base64");
|
|
@@ -19738,7 +20302,7 @@ function decryptSyncBlob(ciphertext) {
|
|
|
19738
20302
|
const iv = combined.subarray(0, IV_LENGTH);
|
|
19739
20303
|
const tag = combined.subarray(combined.length - TAG_LENGTH);
|
|
19740
20304
|
const encrypted = combined.subarray(IV_LENGTH, combined.length - TAG_LENGTH);
|
|
19741
|
-
const decipher =
|
|
20305
|
+
const decipher = crypto16.createDecipheriv(ALGORITHM, key, iv);
|
|
19742
20306
|
decipher.setAuthTag(tag);
|
|
19743
20307
|
return Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
19744
20308
|
}
|
|
@@ -19805,12 +20369,12 @@ function loadPgClient() {
|
|
|
19805
20369
|
}
|
|
19806
20370
|
if (!_pgPromise) {
|
|
19807
20371
|
_pgPromise = (async () => {
|
|
19808
|
-
const { createRequire:
|
|
19809
|
-
const { pathToFileURL:
|
|
20372
|
+
const { createRequire: createRequire5 } = await import("module");
|
|
20373
|
+
const { pathToFileURL: pathToFileURL5 } = await import("url");
|
|
19810
20374
|
const exeDbRoot = process.env.EXE_DB_ROOT ?? path39.join(homedir6(), "exe-db");
|
|
19811
|
-
const req =
|
|
20375
|
+
const req = createRequire5(path39.join(exeDbRoot, "package.json"));
|
|
19812
20376
|
const entry = req.resolve("@prisma/client");
|
|
19813
|
-
const mod = await import(
|
|
20377
|
+
const mod = await import(pathToFileURL5(entry).href);
|
|
19814
20378
|
const Ctor = mod.PrismaClient ?? mod.default?.PrismaClient;
|
|
19815
20379
|
if (!Ctor) throw new Error("No PrismaClient");
|
|
19816
20380
|
return new Ctor();
|
|
@@ -20315,7 +20879,7 @@ function buildRosterBlob(paths) {
|
|
|
20315
20879
|
}
|
|
20316
20880
|
const deletedNames = consumeRosterDeletions();
|
|
20317
20881
|
const content = JSON.stringify({ roster, identities, config: config2, agentConfig, deletedNames });
|
|
20318
|
-
const hash =
|
|
20882
|
+
const hash = crypto17.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
20319
20883
|
return { roster, identities, config: config2, agentConfig, deletedNames, version: hash };
|
|
20320
20884
|
}
|
|
20321
20885
|
async function cloudPushRoster(config2) {
|
|
@@ -20902,7 +21466,7 @@ function registerCloudSync(server2) {
|
|
|
20902
21466
|
title: "Cloud Sync",
|
|
20903
21467
|
description: "Trigger a cloud sync cycle \u2014 pulls remote changes then pushes local. Reports pushed/pulled counts for memories, behaviors, graph, tasks, and more.",
|
|
20904
21468
|
inputSchema: {
|
|
20905
|
-
force:
|
|
21469
|
+
force: z63.boolean().default(false).describe("Force sync even if recently synced")
|
|
20906
21470
|
}
|
|
20907
21471
|
},
|
|
20908
21472
|
async () => {
|
|
@@ -20955,7 +21519,7 @@ function registerCloudSync(server2) {
|
|
|
20955
21519
|
|
|
20956
21520
|
// src/mcp/tools/get-memory-cardinality.ts
|
|
20957
21521
|
init_database();
|
|
20958
|
-
import { z as
|
|
21522
|
+
import { z as z64 } from "zod";
|
|
20959
21523
|
function registerGetMemoryCardinality(server2) {
|
|
20960
21524
|
server2.registerTool(
|
|
20961
21525
|
"get_memory_cardinality",
|
|
@@ -20963,7 +21527,7 @@ function registerGetMemoryCardinality(server2) {
|
|
|
20963
21527
|
title: "Get Memory Cardinality",
|
|
20964
21528
|
description: "Get memory counts: total active memories and per-project breakdown. Optionally filter by agent.",
|
|
20965
21529
|
inputSchema: {
|
|
20966
|
-
agent_id:
|
|
21530
|
+
agent_id: z64.string().optional().describe("Filter to a specific agent (e.g. 'tom', 'exe')")
|
|
20967
21531
|
}
|
|
20968
21532
|
},
|
|
20969
21533
|
async ({ agent_id }) => {
|
|
@@ -21046,7 +21610,7 @@ function registerGetMemoryCardinality(server2) {
|
|
|
21046
21610
|
init_database();
|
|
21047
21611
|
init_consolidation();
|
|
21048
21612
|
init_config();
|
|
21049
|
-
import { z as
|
|
21613
|
+
import { z as z65 } from "zod";
|
|
21050
21614
|
function registerRunConsolidation(server2) {
|
|
21051
21615
|
server2.registerTool(
|
|
21052
21616
|
"run_consolidation",
|
|
@@ -21054,7 +21618,7 @@ function registerRunConsolidation(server2) {
|
|
|
21054
21618
|
title: "Run Consolidation",
|
|
21055
21619
|
description: "Run memory consolidation \u2014 synthesizes unconsolidated memories into meta-insights. Use dry_run=true (default) to preview without executing.",
|
|
21056
21620
|
inputSchema: {
|
|
21057
|
-
dry_run:
|
|
21621
|
+
dry_run: z65.boolean().default(true).describe("Preview mode \u2014 show what would be consolidated without doing it")
|
|
21058
21622
|
}
|
|
21059
21623
|
},
|
|
21060
21624
|
async ({ dry_run }) => {
|
|
@@ -21123,7 +21687,7 @@ function registerRunConsolidation(server2) {
|
|
|
21123
21687
|
|
|
21124
21688
|
// src/mcp/tools/get-license-status.ts
|
|
21125
21689
|
init_license();
|
|
21126
|
-
import { z as
|
|
21690
|
+
import { z as z66 } from "zod";
|
|
21127
21691
|
var FEATURES = [
|
|
21128
21692
|
"cloud_sync",
|
|
21129
21693
|
"external_agents",
|
|
@@ -21137,7 +21701,7 @@ function registerGetLicenseStatus(server2) {
|
|
|
21137
21701
|
title: "Get License Status",
|
|
21138
21702
|
description: "Get current license status: plan, validity, feature gates, limits, and expiry.",
|
|
21139
21703
|
inputSchema: {
|
|
21140
|
-
_dummy:
|
|
21704
|
+
_dummy: z66.string().optional().describe("Unused \u2014 no input required")
|
|
21141
21705
|
}
|
|
21142
21706
|
},
|
|
21143
21707
|
async () => {
|
|
@@ -21190,7 +21754,7 @@ function registerGetLicenseStatus(server2) {
|
|
|
21190
21754
|
|
|
21191
21755
|
// src/mcp/tools/backup-vps.ts
|
|
21192
21756
|
init_keychain();
|
|
21193
|
-
import { z as
|
|
21757
|
+
import { z as z67 } from "zod";
|
|
21194
21758
|
|
|
21195
21759
|
// src/lib/vps-backup.ts
|
|
21196
21760
|
import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
|
|
@@ -21515,43 +22079,43 @@ function registerBackupVps(server2) {
|
|
|
21515
22079
|
{
|
|
21516
22080
|
title: "VPS Backup",
|
|
21517
22081
|
description: "Run VPS Postgres backup/restore workflows and check status.",
|
|
21518
|
-
inputSchema:
|
|
21519
|
-
|
|
21520
|
-
action:
|
|
21521
|
-
databaseUrl:
|
|
21522
|
-
encryptionKeyB64:
|
|
22082
|
+
inputSchema: z67.discriminatedUnion("action", [
|
|
22083
|
+
z67.object({
|
|
22084
|
+
action: z67.literal("backup"),
|
|
22085
|
+
databaseUrl: z67.string().min(1).describe("Postgres DATABASE_URL to dump from"),
|
|
22086
|
+
encryptionKeyB64: z67.string().min(1).max(4096).optional().describe(
|
|
21523
22087
|
"Base64 AES-256 key (defaults to local master key if omitted)"
|
|
21524
22088
|
),
|
|
21525
|
-
r2Bucket:
|
|
21526
|
-
r2Endpoint:
|
|
21527
|
-
r2AccessKeyId:
|
|
21528
|
-
r2SecretAccessKey:
|
|
22089
|
+
r2Bucket: z67.string().min(1).describe("R2 bucket name"),
|
|
22090
|
+
r2Endpoint: z67.string().min(1).describe("R2 endpoint URL"),
|
|
22091
|
+
r2AccessKeyId: z67.string().min(1).describe("R2 access key ID"),
|
|
22092
|
+
r2SecretAccessKey: z67.string().min(1).describe("R2 secret access key")
|
|
21529
22093
|
}),
|
|
21530
|
-
|
|
21531
|
-
action:
|
|
21532
|
-
databaseUrl:
|
|
21533
|
-
backupKey:
|
|
21534
|
-
encryptionKeyB64:
|
|
22094
|
+
z67.object({
|
|
22095
|
+
action: z67.literal("restore"),
|
|
22096
|
+
databaseUrl: z67.string().min(1).describe("Target Postgres DATABASE_URL for restore"),
|
|
22097
|
+
backupKey: z67.string().min(1).describe("R2 object key to restore from"),
|
|
22098
|
+
encryptionKeyB64: z67.string().min(1).max(4096).optional().describe(
|
|
21535
22099
|
"Base64 AES-256 key (defaults to local master key if omitted)"
|
|
21536
22100
|
),
|
|
21537
|
-
r2Bucket:
|
|
21538
|
-
r2Endpoint:
|
|
21539
|
-
r2AccessKeyId:
|
|
21540
|
-
r2SecretAccessKey:
|
|
22101
|
+
r2Bucket: z67.string().min(1).describe("R2 bucket name"),
|
|
22102
|
+
r2Endpoint: z67.string().min(1).describe("R2 endpoint URL"),
|
|
22103
|
+
r2AccessKeyId: z67.string().min(1).describe("R2 access key ID"),
|
|
22104
|
+
r2SecretAccessKey: z67.string().min(1).describe("R2 secret access key")
|
|
21541
22105
|
}),
|
|
21542
|
-
|
|
21543
|
-
action:
|
|
21544
|
-
r2Bucket:
|
|
21545
|
-
r2Endpoint:
|
|
21546
|
-
r2AccessKeyId:
|
|
21547
|
-
r2SecretAccessKey:
|
|
22106
|
+
z67.object({
|
|
22107
|
+
action: z67.literal("list"),
|
|
22108
|
+
r2Bucket: z67.string().min(1).describe("R2 bucket name"),
|
|
22109
|
+
r2Endpoint: z67.string().min(1).describe("R2 endpoint URL"),
|
|
22110
|
+
r2AccessKeyId: z67.string().min(1).describe("R2 access key ID"),
|
|
22111
|
+
r2SecretAccessKey: z67.string().min(1).describe("R2 secret access key")
|
|
21548
22112
|
}),
|
|
21549
|
-
|
|
21550
|
-
action:
|
|
21551
|
-
r2Bucket:
|
|
21552
|
-
r2Endpoint:
|
|
21553
|
-
r2AccessKeyId:
|
|
21554
|
-
r2SecretAccessKey:
|
|
22113
|
+
z67.object({
|
|
22114
|
+
action: z67.literal("health"),
|
|
22115
|
+
r2Bucket: z67.string().min(1).describe("R2 bucket name"),
|
|
22116
|
+
r2Endpoint: z67.string().min(1).describe("R2 endpoint URL"),
|
|
22117
|
+
r2AccessKeyId: z67.string().min(1).describe("R2 access key ID"),
|
|
22118
|
+
r2SecretAccessKey: z67.string().min(1).describe("R2 secret access key")
|
|
21555
22119
|
})
|
|
21556
22120
|
])
|
|
21557
22121
|
},
|
|
@@ -21689,7 +22253,7 @@ async function resolveEncryptionKey(providedB64) {
|
|
|
21689
22253
|
}
|
|
21690
22254
|
|
|
21691
22255
|
// src/mcp/tools/people-roster.ts
|
|
21692
|
-
import { z as
|
|
22256
|
+
import { z as z68 } from "zod";
|
|
21693
22257
|
|
|
21694
22258
|
// src/lib/people.ts
|
|
21695
22259
|
init_config();
|
|
@@ -21737,10 +22301,10 @@ function registerAddPerson(server2) {
|
|
|
21737
22301
|
title: "Add Person",
|
|
21738
22302
|
description: "Add or update a key human in the people roster. Used for co-founders, partners, customers \u2014 anyone agents need to know about.",
|
|
21739
22303
|
inputSchema: {
|
|
21740
|
-
name:
|
|
21741
|
-
role:
|
|
21742
|
-
relationship:
|
|
21743
|
-
notes:
|
|
22304
|
+
name: z68.string().describe("Person's name"),
|
|
22305
|
+
role: z68.string().describe("Their role (e.g. co-founder, customer, partner)"),
|
|
22306
|
+
relationship: z68.string().describe("Relationship to the organization (e.g. co-founder, early adopter, investor)"),
|
|
22307
|
+
notes: z68.string().optional().describe("Additional context about this person")
|
|
21744
22308
|
}
|
|
21745
22309
|
},
|
|
21746
22310
|
async ({ name, role, relationship, notes }) => {
|
|
@@ -21786,7 +22350,7 @@ function registerGetPerson(server2) {
|
|
|
21786
22350
|
title: "Get Person",
|
|
21787
22351
|
description: "Look up a specific person by name from the people roster.",
|
|
21788
22352
|
inputSchema: {
|
|
21789
|
-
name:
|
|
22353
|
+
name: z68.string().describe("Person's name to look up")
|
|
21790
22354
|
}
|
|
21791
22355
|
},
|
|
21792
22356
|
async ({ name }) => {
|
|
@@ -21814,7 +22378,7 @@ init_active_agent();
|
|
|
21814
22378
|
init_agent_config();
|
|
21815
22379
|
init_runtime_table();
|
|
21816
22380
|
init_employees();
|
|
21817
|
-
import { z as
|
|
22381
|
+
import { z as z69 } from "zod";
|
|
21818
22382
|
function registerSetAgentConfig(server2) {
|
|
21819
22383
|
server2.registerTool(
|
|
21820
22384
|
"set_agent_config",
|
|
@@ -21822,10 +22386,10 @@ function registerSetAgentConfig(server2) {
|
|
|
21822
22386
|
title: "Set Agent Config",
|
|
21823
22387
|
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.",
|
|
21824
22388
|
inputSchema: {
|
|
21825
|
-
agent_id:
|
|
21826
|
-
runtime:
|
|
21827
|
-
model:
|
|
21828
|
-
reasoning_effort:
|
|
22389
|
+
agent_id: z69.string().optional().describe("Agent name, or 'default' for org-wide default. Omit to view all agents."),
|
|
22390
|
+
runtime: z69.string().optional().describe(`Runtime: ${Object.keys(KNOWN_RUNTIMES).join(", ")}`),
|
|
22391
|
+
model: z69.string().optional().describe("Model name (e.g. claude-opus-4, gpt-5.4, anthropic/claude-sonnet-4-6)"),
|
|
22392
|
+
reasoning_effort: z69.string().optional().describe("Codex reasoning effort: low, medium, high, xhigh. Per-agent override for thinking/reasoning depth.")
|
|
21829
22393
|
}
|
|
21830
22394
|
},
|
|
21831
22395
|
async ({ agent_id, runtime, model, reasoning_effort }) => {
|
|
@@ -21923,7 +22487,7 @@ function registerSetAgentConfig(server2) {
|
|
|
21923
22487
|
// src/mcp/tools/list-employees.ts
|
|
21924
22488
|
init_employees();
|
|
21925
22489
|
init_agent_config();
|
|
21926
|
-
import { z as
|
|
22490
|
+
import { z as z70 } from "zod";
|
|
21927
22491
|
function registerListEmployees(server2) {
|
|
21928
22492
|
server2.registerTool(
|
|
21929
22493
|
"list_employees",
|
|
@@ -21931,7 +22495,7 @@ function registerListEmployees(server2) {
|
|
|
21931
22495
|
title: "List Employees",
|
|
21932
22496
|
description: "List all AI employees in the organization with their role, runtime, and model configuration. Use to see who's on the team and how they're configured.",
|
|
21933
22497
|
inputSchema: {
|
|
21934
|
-
role:
|
|
22498
|
+
role: z70.string().optional().describe("Filter by role (case-insensitive)")
|
|
21935
22499
|
}
|
|
21936
22500
|
},
|
|
21937
22501
|
async ({ role }) => {
|
|
@@ -21986,12 +22550,14 @@ function registerListEmployees(server2) {
|
|
|
21986
22550
|
);
|
|
21987
22551
|
}
|
|
21988
22552
|
|
|
21989
|
-
// src/mcp/tools/
|
|
22553
|
+
// src/mcp/tools/create-license.ts
|
|
22554
|
+
init_license();
|
|
21990
22555
|
import os16 from "os";
|
|
21991
22556
|
import path41 from "path";
|
|
22557
|
+
import { randomBytes as randomBytes2, randomUUID as randomUUID8 } from "crypto";
|
|
21992
22558
|
import { createRequire as createRequire3 } from "module";
|
|
21993
22559
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
21994
|
-
import { z as
|
|
22560
|
+
import { z as z71 } from "zod";
|
|
21995
22561
|
var prismaPromise = null;
|
|
21996
22562
|
function loadPrisma() {
|
|
21997
22563
|
if (!prismaPromise) {
|
|
@@ -22014,101 +22580,6 @@ function loadPrisma() {
|
|
|
22014
22580
|
}
|
|
22015
22581
|
return prismaPromise;
|
|
22016
22582
|
}
|
|
22017
|
-
function registerIngestRaw(server2) {
|
|
22018
|
-
server2.registerTool(
|
|
22019
|
-
"ingest_raw",
|
|
22020
|
-
{
|
|
22021
|
-
title: "Ingest Raw Event",
|
|
22022
|
-
description: "Insert a raw event into the landing pad (raw.raw_events). Used by the gateway, external agents, and webhooks to push data into the Company Brain. Background projection workers process unprocessed events and route to curated schemas.",
|
|
22023
|
-
inputSchema: {
|
|
22024
|
-
source: z68.string().describe(
|
|
22025
|
-
'Event source identifier: "whatsapp", "shopify", "asana", "email", "external_agent", etc.'
|
|
22026
|
-
),
|
|
22027
|
-
event_type: z68.string().describe(
|
|
22028
|
-
'Event type: "message", "order", "task_update", "webhook", etc.'
|
|
22029
|
-
),
|
|
22030
|
-
payload: z68.record(z68.string(), z68.unknown()).describe(
|
|
22031
|
-
"Exact raw JSON payload \u2014 stored verbatim, never modified."
|
|
22032
|
-
),
|
|
22033
|
-
source_id: z68.string().optional().describe(
|
|
22034
|
-
"External reference ID for deduplication (e.g., WhatsApp message ID, Shopify order ID)."
|
|
22035
|
-
),
|
|
22036
|
-
metadata: z68.record(z68.string(), z68.unknown()).optional().describe(
|
|
22037
|
-
"Source-specific metadata (account info, adapter version, etc.)."
|
|
22038
|
-
)
|
|
22039
|
-
}
|
|
22040
|
-
},
|
|
22041
|
-
async ({ source, event_type, payload, source_id, metadata }) => {
|
|
22042
|
-
try {
|
|
22043
|
-
const prisma = await loadPrisma();
|
|
22044
|
-
const id = crypto.randomUUID();
|
|
22045
|
-
await prisma.$executeRawUnsafe(
|
|
22046
|
-
`INSERT INTO "raw"."raw_events" ("id", "source", "source_id", "event_type", "payload", "metadata", "timestamp")
|
|
22047
|
-
VALUES ($1, $2, $3, $4, $5::jsonb, $6::jsonb, NOW())
|
|
22048
|
-
ON CONFLICT ("source", "source_id", "event_type") DO NOTHING`,
|
|
22049
|
-
id,
|
|
22050
|
-
source,
|
|
22051
|
-
source_id ?? null,
|
|
22052
|
-
event_type,
|
|
22053
|
-
JSON.stringify(payload),
|
|
22054
|
-
metadata ? JSON.stringify(metadata) : null
|
|
22055
|
-
);
|
|
22056
|
-
return {
|
|
22057
|
-
content: [{
|
|
22058
|
-
type: "text",
|
|
22059
|
-
text: JSON.stringify({
|
|
22060
|
-
event_id: id,
|
|
22061
|
-
source,
|
|
22062
|
-
event_type,
|
|
22063
|
-
source_id: source_id ?? null,
|
|
22064
|
-
status: "ingested"
|
|
22065
|
-
})
|
|
22066
|
-
}]
|
|
22067
|
-
};
|
|
22068
|
-
} catch (err) {
|
|
22069
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
22070
|
-
return {
|
|
22071
|
-
content: [{
|
|
22072
|
-
type: "text",
|
|
22073
|
-
text: `Error ingesting raw event: ${message}`
|
|
22074
|
-
}],
|
|
22075
|
-
isError: true
|
|
22076
|
-
};
|
|
22077
|
-
}
|
|
22078
|
-
}
|
|
22079
|
-
);
|
|
22080
|
-
}
|
|
22081
|
-
|
|
22082
|
-
// src/mcp/tools/create-license.ts
|
|
22083
|
-
init_license();
|
|
22084
|
-
import os17 from "os";
|
|
22085
|
-
import path42 from "path";
|
|
22086
|
-
import { randomBytes as randomBytes2, randomUUID as randomUUID8 } from "crypto";
|
|
22087
|
-
import { createRequire as createRequire4 } from "module";
|
|
22088
|
-
import { pathToFileURL as pathToFileURL4 } from "url";
|
|
22089
|
-
import { z as z69 } from "zod";
|
|
22090
|
-
var prismaPromise2 = null;
|
|
22091
|
-
function loadPrisma2() {
|
|
22092
|
-
if (!prismaPromise2) {
|
|
22093
|
-
prismaPromise2 = (async () => {
|
|
22094
|
-
const explicitPath = process.env.EXE_OS_PRISMA_CLIENT_PATH;
|
|
22095
|
-
if (explicitPath) {
|
|
22096
|
-
const mod2 = await import(pathToFileURL4(explicitPath).href);
|
|
22097
|
-
const Ctor2 = mod2.PrismaClient ?? mod2.default?.PrismaClient;
|
|
22098
|
-
if (!Ctor2) throw new Error(`No PrismaClient at ${explicitPath}`);
|
|
22099
|
-
return new Ctor2();
|
|
22100
|
-
}
|
|
22101
|
-
const exeDbRoot = process.env.EXE_DB_ROOT ?? path42.join(os17.homedir(), "exe-db");
|
|
22102
|
-
const req = createRequire4(path42.join(exeDbRoot, "package.json"));
|
|
22103
|
-
const entry = req.resolve("@prisma/client");
|
|
22104
|
-
const mod = await import(pathToFileURL4(entry).href);
|
|
22105
|
-
const Ctor = mod.PrismaClient ?? mod.default?.PrismaClient;
|
|
22106
|
-
if (!Ctor) throw new Error(`No PrismaClient in ${entry}`);
|
|
22107
|
-
return new Ctor();
|
|
22108
|
-
})();
|
|
22109
|
-
}
|
|
22110
|
-
return prismaPromise2;
|
|
22111
|
-
}
|
|
22112
22583
|
function generateKey() {
|
|
22113
22584
|
return `exe_sk_${randomBytes2(16).toString("hex")}`;
|
|
22114
22585
|
}
|
|
@@ -22119,15 +22590,15 @@ function registerCreateLicense(server2) {
|
|
|
22119
22590
|
title: "Create License",
|
|
22120
22591
|
description: "Generate an exe_sk_* license key for a user. Stores in billing.licenses. Returns the key to give to the customer.",
|
|
22121
22592
|
inputSchema: {
|
|
22122
|
-
email:
|
|
22123
|
-
name:
|
|
22124
|
-
plan:
|
|
22125
|
-
expires_in_days:
|
|
22593
|
+
email: z71.string().email().describe("Customer email address"),
|
|
22594
|
+
name: z71.string().optional().describe("Customer name"),
|
|
22595
|
+
plan: z71.enum(["free", "pro", "team", "agency", "enterprise"]).default("pro").describe("License plan tier"),
|
|
22596
|
+
expires_in_days: z71.number().int().positive().default(365).describe("Days until expiration (default 365)")
|
|
22126
22597
|
}
|
|
22127
22598
|
},
|
|
22128
22599
|
async ({ email, name, plan, expires_in_days }) => {
|
|
22129
22600
|
try {
|
|
22130
|
-
const prisma = await
|
|
22601
|
+
const prisma = await loadPrisma();
|
|
22131
22602
|
const id = randomUUID8();
|
|
22132
22603
|
const key = generateKey();
|
|
22133
22604
|
const limits = PLAN_LIMITS[plan];
|
|
@@ -22173,32 +22644,32 @@ Give this key to the customer. They paste it during \`exe-os setup\`.`);
|
|
|
22173
22644
|
}
|
|
22174
22645
|
|
|
22175
22646
|
// src/mcp/tools/list-licenses.ts
|
|
22176
|
-
import
|
|
22177
|
-
import
|
|
22178
|
-
import { createRequire as
|
|
22179
|
-
import { pathToFileURL as
|
|
22180
|
-
import { z as
|
|
22181
|
-
var
|
|
22182
|
-
function
|
|
22183
|
-
if (!
|
|
22184
|
-
|
|
22647
|
+
import os17 from "os";
|
|
22648
|
+
import path42 from "path";
|
|
22649
|
+
import { createRequire as createRequire4 } from "module";
|
|
22650
|
+
import { pathToFileURL as pathToFileURL4 } from "url";
|
|
22651
|
+
import { z as z72 } from "zod";
|
|
22652
|
+
var prismaPromise2 = null;
|
|
22653
|
+
function loadPrisma2() {
|
|
22654
|
+
if (!prismaPromise2) {
|
|
22655
|
+
prismaPromise2 = (async () => {
|
|
22185
22656
|
const explicitPath = process.env.EXE_OS_PRISMA_CLIENT_PATH;
|
|
22186
22657
|
if (explicitPath) {
|
|
22187
|
-
const mod2 = await import(
|
|
22658
|
+
const mod2 = await import(pathToFileURL4(explicitPath).href);
|
|
22188
22659
|
const Ctor2 = mod2.PrismaClient ?? mod2.default?.PrismaClient;
|
|
22189
22660
|
if (!Ctor2) throw new Error(`No PrismaClient at ${explicitPath}`);
|
|
22190
22661
|
return new Ctor2();
|
|
22191
22662
|
}
|
|
22192
|
-
const exeDbRoot = process.env.EXE_DB_ROOT ??
|
|
22193
|
-
const req =
|
|
22663
|
+
const exeDbRoot = process.env.EXE_DB_ROOT ?? path42.join(os17.homedir(), "exe-db");
|
|
22664
|
+
const req = createRequire4(path42.join(exeDbRoot, "package.json"));
|
|
22194
22665
|
const entry = req.resolve("@prisma/client");
|
|
22195
|
-
const mod = await import(
|
|
22666
|
+
const mod = await import(pathToFileURL4(entry).href);
|
|
22196
22667
|
const Ctor = mod.PrismaClient ?? mod.default?.PrismaClient;
|
|
22197
22668
|
if (!Ctor) throw new Error(`No PrismaClient in ${entry}`);
|
|
22198
22669
|
return new Ctor();
|
|
22199
22670
|
})();
|
|
22200
22671
|
}
|
|
22201
|
-
return
|
|
22672
|
+
return prismaPromise2;
|
|
22202
22673
|
}
|
|
22203
22674
|
function registerListLicenses(server2) {
|
|
22204
22675
|
server2.registerTool(
|
|
@@ -22207,12 +22678,12 @@ function registerListLicenses(server2) {
|
|
|
22207
22678
|
title: "List Licenses",
|
|
22208
22679
|
description: "List all issued licenses with status (active/expired/revoked). Optionally filter by plan.",
|
|
22209
22680
|
inputSchema: {
|
|
22210
|
-
plan:
|
|
22681
|
+
plan: z72.enum(["free", "pro", "team", "agency", "enterprise"]).optional().describe("Filter by plan tier (omit for all)")
|
|
22211
22682
|
}
|
|
22212
22683
|
},
|
|
22213
22684
|
async ({ plan }) => {
|
|
22214
22685
|
try {
|
|
22215
|
-
const prisma = await
|
|
22686
|
+
const prisma = await loadPrisma2();
|
|
22216
22687
|
let rows;
|
|
22217
22688
|
if (plan) {
|
|
22218
22689
|
rows = await prisma.$queryRawUnsafe(
|
|
@@ -22258,7 +22729,7 @@ function registerListLicenses(server2) {
|
|
|
22258
22729
|
|
|
22259
22730
|
// src/mcp/tools/activate-license.ts
|
|
22260
22731
|
init_license();
|
|
22261
|
-
import { z as
|
|
22732
|
+
import { z as z73 } from "zod";
|
|
22262
22733
|
function registerActivateLicense(server2) {
|
|
22263
22734
|
server2.registerTool(
|
|
22264
22735
|
"activate_license",
|
|
@@ -22266,7 +22737,7 @@ function registerActivateLicense(server2) {
|
|
|
22266
22737
|
title: "Activate License",
|
|
22267
22738
|
description: "Activate an exe_sk_* license key on this device. Writes to ~/.exe-os/license.key, validates against Postgres, and caches the result.",
|
|
22268
22739
|
inputSchema: {
|
|
22269
|
-
key:
|
|
22740
|
+
key: z73.string().startsWith("exe_sk_").describe("License key (exe_sk_*)")
|
|
22270
22741
|
}
|
|
22271
22742
|
},
|
|
22272
22743
|
async ({ key }) => {
|
|
@@ -22313,9 +22784,9 @@ Key saved to ~/.exe-os/license.key. Device ID: ${deviceId}`);
|
|
|
22313
22784
|
|
|
22314
22785
|
// src/mcp/tools/query-company-brain.ts
|
|
22315
22786
|
init_config();
|
|
22316
|
-
import { z as
|
|
22787
|
+
import { z as z74 } from "zod";
|
|
22317
22788
|
var FETCH_TIMEOUT_MS5 = 1e4;
|
|
22318
|
-
var QUERY_SCOPE =
|
|
22789
|
+
var QUERY_SCOPE = z74.enum(["raw", "wiki", "memory", "gateway", "all"]);
|
|
22319
22790
|
function formatSuccess(query, scope, payload) {
|
|
22320
22791
|
const pretty = typeof payload === "string" ? payload : JSON.stringify(payload, null, 2);
|
|
22321
22792
|
return [
|
|
@@ -22334,10 +22805,10 @@ function registerQueryCompanyBrain(server2) {
|
|
|
22334
22805
|
title: "Query Company Brain",
|
|
22335
22806
|
description: "Search the Company Brain \u2014 queries across all data (raw events, wiki docs, agent memories, gateway messages).",
|
|
22336
22807
|
inputSchema: {
|
|
22337
|
-
query:
|
|
22808
|
+
query: z74.string().min(1).describe("Search text"),
|
|
22338
22809
|
scope: QUERY_SCOPE.default("all").describe("Which data scope to search"),
|
|
22339
|
-
source:
|
|
22340
|
-
limit:
|
|
22810
|
+
source: z74.string().optional().describe("Filter raw events by source (shopify, asana, etc.)"),
|
|
22811
|
+
limit: z74.coerce.number().int().min(1).max(100).default(20).describe("Max results per scope")
|
|
22341
22812
|
}
|
|
22342
22813
|
},
|
|
22343
22814
|
async ({ query, scope, source, limit }) => {
|
|
@@ -22492,15 +22963,11 @@ registerCloseTask(server);
|
|
|
22492
22963
|
registerGetTask(server);
|
|
22493
22964
|
registerCheckpointTask(server);
|
|
22494
22965
|
registerResumeEmployee(server);
|
|
22495
|
-
|
|
22966
|
+
registerBehavior(server);
|
|
22496
22967
|
registerSendMessage(server);
|
|
22497
|
-
|
|
22498
|
-
registerListReminders(server);
|
|
22499
|
-
registerCompleteReminder(server);
|
|
22500
|
-
registerListBehaviors(server);
|
|
22968
|
+
registerReminder(server);
|
|
22501
22969
|
registerGetIdentity(server);
|
|
22502
22970
|
registerUpdateIdentity(server);
|
|
22503
|
-
registerDeactivateBehavior(server);
|
|
22504
22971
|
registerIngestDocument(server);
|
|
22505
22972
|
registerListDocuments(server);
|
|
22506
22973
|
registerPurgeDocument(server);
|
|
@@ -22522,9 +22989,16 @@ registerImportOrchestration(server);
|
|
|
22522
22989
|
registerQueryConversations(server);
|
|
22523
22990
|
registerLoadSkill(server);
|
|
22524
22991
|
registerConsolidateMemories(server);
|
|
22992
|
+
registerGlobalProcedure(server);
|
|
22525
22993
|
registerStoreGlobalProcedure(server);
|
|
22526
22994
|
registerListGlobalProcedures(server);
|
|
22527
22995
|
registerDeactivateGlobalProcedure(server);
|
|
22996
|
+
registerStoreBehavior(server);
|
|
22997
|
+
registerListBehaviors(server);
|
|
22998
|
+
registerDeactivateBehavior(server);
|
|
22999
|
+
registerCreateReminder(server);
|
|
23000
|
+
registerListReminders(server);
|
|
23001
|
+
registerCompleteReminder(server);
|
|
22528
23002
|
registerSearchEverything(server);
|
|
22529
23003
|
registerStoreDecision(server);
|
|
22530
23004
|
registerGetDecision(server);
|
|
@@ -22550,7 +23024,6 @@ registerListPeople(server);
|
|
|
22550
23024
|
registerGetPerson(server);
|
|
22551
23025
|
registerSetAgentConfig(server);
|
|
22552
23026
|
registerListEmployees(server);
|
|
22553
|
-
registerIngestRaw(server);
|
|
22554
23027
|
registerCreateLicense(server);
|
|
22555
23028
|
registerListLicenses(server);
|
|
22556
23029
|
registerActivateLicense(server);
|
|
@@ -22623,14 +23096,14 @@ try {
|
|
|
22623
23096
|
`
|
|
22624
23097
|
);
|
|
22625
23098
|
const thisFile = fileURLToPath5(import.meta.url);
|
|
22626
|
-
const backfillPath =
|
|
22627
|
-
|
|
23099
|
+
const backfillPath = path43.resolve(
|
|
23100
|
+
path43.dirname(thisFile),
|
|
22628
23101
|
"../bin/backfill-vectors.js"
|
|
22629
23102
|
);
|
|
22630
23103
|
if (existsSync33(backfillPath)) {
|
|
22631
23104
|
const { EXE_AI_DIR: exeDir } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
22632
|
-
const logPath =
|
|
22633
|
-
mkdirSync17(
|
|
23105
|
+
const logPath = path43.join(exeDir, "workers.log");
|
|
23106
|
+
mkdirSync17(path43.dirname(logPath), { recursive: true });
|
|
22634
23107
|
let logFd = "ignore";
|
|
22635
23108
|
try {
|
|
22636
23109
|
logFd = openSync3(logPath, "a");
|