@askexenow/exe-os 0.9.87 → 0.9.89
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/deploy/compose/docker-compose.yml +3 -3
- package/dist/bin/age-ontology-load.js +8 -2
- package/dist/bin/agentic-ontology-backfill.js +11 -0
- package/dist/bin/agentic-reflection-backfill.js +11 -0
- package/dist/bin/agentic-semantic-label.js +11 -0
- package/dist/bin/backfill-conversations.js +12 -0
- package/dist/bin/backfill-responses.js +12 -0
- package/dist/bin/backfill-vectors.js +12 -0
- package/dist/bin/bulk-sync-postgres.js +29 -1
- package/dist/bin/cc-doctor.js +3 -2
- package/dist/bin/cleanup-stale-review-tasks.js +12 -0
- package/dist/bin/cli.js +170 -15
- package/dist/bin/exe-agent.js +1 -0
- package/dist/bin/exe-assign.js +12 -0
- package/dist/bin/exe-boot.js +139 -4
- package/dist/bin/exe-call.js +2 -0
- package/dist/bin/exe-cloud.js +138 -3
- package/dist/bin/exe-dispatch.js +12 -1
- package/dist/bin/exe-doctor.js +12 -0
- package/dist/bin/exe-export-behaviors.js +11 -0
- package/dist/bin/exe-forget.js +12 -0
- package/dist/bin/exe-gateway.js +132 -35
- package/dist/bin/exe-healthcheck.js +2 -1
- package/dist/bin/exe-heartbeat.js +12 -0
- package/dist/bin/exe-kill.js +11 -0
- package/dist/bin/exe-launch-agent.js +11 -0
- package/dist/bin/exe-new-employee.js +4 -2
- package/dist/bin/exe-pending-messages.js +11 -0
- package/dist/bin/exe-pending-notifications.js +12 -0
- package/dist/bin/exe-pending-reviews.js +12 -0
- package/dist/bin/exe-rename.js +12 -0
- package/dist/bin/exe-review.js +12 -0
- package/dist/bin/exe-search.js +12 -0
- package/dist/bin/exe-session-cleanup.js +12 -1
- package/dist/bin/exe-settings.js +3 -0
- package/dist/bin/exe-start-codex.js +13 -2
- package/dist/bin/exe-start-opencode.js +13 -2
- package/dist/bin/exe-status.js +12 -0
- package/dist/bin/exe-team.js +12 -0
- package/dist/bin/git-sweep.js +12 -1
- package/dist/bin/graph-backfill.js +11 -0
- package/dist/bin/graph-export.js +11 -0
- package/dist/bin/graph-layer-benchmark.js +9 -1
- package/dist/bin/intercom-check.js +13 -1
- package/dist/bin/list-providers.js +1 -0
- package/dist/bin/postgres-agentic-reflection-backfill.js +7 -1
- package/dist/bin/postgres-agentic-semantic-backfill.js +7 -1
- package/dist/bin/registry-proxy.js +1 -0
- package/dist/bin/scan-tasks.js +13 -1
- package/dist/bin/setup.js +141 -7
- package/dist/bin/shard-migrate.js +11 -0
- package/dist/bin/stack-update.js +24 -7
- package/dist/bin/update.js +5 -0
- package/dist/gateway/index.js +12 -1
- package/dist/hooks/bug-report-worker.js +12 -1
- package/dist/hooks/codex-stop-task-finalizer.js +12 -1
- package/dist/hooks/commit-complete.js +12 -1
- package/dist/hooks/error-recall.js +11 -0
- package/dist/hooks/ingest.js +11 -0
- package/dist/hooks/instructions-loaded.js +11 -0
- package/dist/hooks/notification.js +11 -0
- package/dist/hooks/post-compact.js +11 -0
- package/dist/hooks/post-tool-combined.js +11 -0
- package/dist/hooks/pre-compact.js +12 -1
- package/dist/hooks/pre-tool-use.js +11 -0
- package/dist/hooks/prompt-submit.js +12 -1
- package/dist/hooks/session-end.js +12 -1
- package/dist/hooks/session-start.js +11 -0
- package/dist/hooks/stop.js +11 -0
- package/dist/hooks/subagent-stop.js +11 -0
- package/dist/hooks/summary-worker.js +137 -3
- package/dist/index.js +12 -1
- package/dist/lib/cloud-sync.js +136 -2
- package/dist/lib/consolidation.js +1 -0
- package/dist/lib/database.js +11 -0
- package/dist/lib/db.js +11 -0
- package/dist/lib/device-registry.js +11 -0
- package/dist/lib/employee-templates.js +1 -0
- package/dist/lib/exe-daemon.js +771 -49
- package/dist/lib/hybrid-search.js +11 -0
- package/dist/lib/identity.js +1 -0
- package/dist/lib/messaging.js +2 -1
- package/dist/lib/reminders.js +1 -0
- package/dist/lib/schedules.js +11 -0
- package/dist/lib/skill-learning.js +1 -0
- package/dist/lib/store.js +11 -0
- package/dist/lib/tasks.js +2 -1
- package/dist/lib/tmux-routing.js +2 -1
- package/dist/lib/token-spend.js +1 -0
- package/dist/lib/ws-client.js +8 -0
- package/dist/mcp/server.js +613 -27
- package/dist/mcp/tools/complete-reminder.js +1 -0
- package/dist/mcp/tools/create-reminder.js +1 -0
- package/dist/mcp/tools/create-task.js +2 -1
- package/dist/mcp/tools/deactivate-behavior.js +1 -0
- package/dist/mcp/tools/list-reminders.js +1 -0
- package/dist/mcp/tools/list-tasks.js +1 -0
- package/dist/mcp/tools/send-message.js +2 -1
- package/dist/mcp/tools/update-task.js +2 -1
- package/dist/runtime/index.js +12 -1
- package/dist/tui/App.js +12 -1
- package/package.json +2 -2
package/dist/mcp/server.js
CHANGED
|
@@ -2180,6 +2180,7 @@ __export(database_exports, {
|
|
|
2180
2180
|
isInitialized: () => isInitialized,
|
|
2181
2181
|
setExternalClient: () => setExternalClient
|
|
2182
2182
|
});
|
|
2183
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2183
2184
|
import { createClient } from "@libsql/client";
|
|
2184
2185
|
async function initDatabase(config2) {
|
|
2185
2186
|
if (_walCheckpointTimer) {
|
|
@@ -2221,6 +2222,16 @@ async function initDatabase(config2) {
|
|
|
2221
2222
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2222
2223
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2223
2224
|
}
|
|
2225
|
+
try {
|
|
2226
|
+
chmodSync2(config2.dbPath, 384);
|
|
2227
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2228
|
+
try {
|
|
2229
|
+
chmodSync2(config2.dbPath + suffix, 384);
|
|
2230
|
+
} catch {
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
} catch {
|
|
2234
|
+
}
|
|
2224
2235
|
}
|
|
2225
2236
|
function isInitialized() {
|
|
2226
2237
|
return _adapterClient !== null || _client !== null;
|
|
@@ -9426,7 +9437,7 @@ function readQueue() {
|
|
|
9426
9437
|
function writeQueue(queue) {
|
|
9427
9438
|
ensureDir();
|
|
9428
9439
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
9429
|
-
writeFileSync9(tmp, JSON.stringify(queue, null, 2));
|
|
9440
|
+
writeFileSync9(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
|
|
9430
9441
|
renameSync4(tmp, QUEUE_PATH);
|
|
9431
9442
|
}
|
|
9432
9443
|
function queueIntercom(targetSession, reason) {
|
|
@@ -13996,6 +14007,21 @@ var init_crdt_sync = __esm({
|
|
|
13996
14007
|
}
|
|
13997
14008
|
});
|
|
13998
14009
|
|
|
14010
|
+
// src/lib/pg-ssl.ts
|
|
14011
|
+
var pg_ssl_exports = {};
|
|
14012
|
+
__export(pg_ssl_exports, {
|
|
14013
|
+
pgSslConfig: () => pgSslConfig
|
|
14014
|
+
});
|
|
14015
|
+
function pgSslConfig() {
|
|
14016
|
+
if (process.env.EXE_DB_SSL_DISABLED === "true") return {};
|
|
14017
|
+
return { ssl: { rejectUnauthorized: process.env.EXE_DB_SSL_ALLOW_SELFSIGNED !== "true" } };
|
|
14018
|
+
}
|
|
14019
|
+
var init_pg_ssl = __esm({
|
|
14020
|
+
"src/lib/pg-ssl.ts"() {
|
|
14021
|
+
"use strict";
|
|
14022
|
+
}
|
|
14023
|
+
});
|
|
14024
|
+
|
|
13999
14025
|
// src/lib/tmux-status.ts
|
|
14000
14026
|
import { execSync as execSync13 } from "child_process";
|
|
14001
14027
|
function inTmux() {
|
|
@@ -19940,6 +19966,130 @@ import { existsSync as existsSync24, readFileSync as readFileSync20 } from "fs";
|
|
|
19940
19966
|
import path30 from "path";
|
|
19941
19967
|
import { homedir as homedir4 } from "os";
|
|
19942
19968
|
import { z as z54 } from "zod";
|
|
19969
|
+
|
|
19970
|
+
// src/mcp/license-gate.ts
|
|
19971
|
+
init_license();
|
|
19972
|
+
var _cachedLicense = null;
|
|
19973
|
+
var _hasLicenseKey = false;
|
|
19974
|
+
async function initLicenseGate() {
|
|
19975
|
+
const key = loadLicense();
|
|
19976
|
+
_hasLicenseKey = key !== null && key.length > 0;
|
|
19977
|
+
if (_hasLicenseKey) {
|
|
19978
|
+
try {
|
|
19979
|
+
_cachedLicense = await checkLicense();
|
|
19980
|
+
} catch {
|
|
19981
|
+
_cachedLicense = null;
|
|
19982
|
+
}
|
|
19983
|
+
return { license: _cachedLicense, hasKey: true };
|
|
19984
|
+
}
|
|
19985
|
+
return { license: null, hasKey: false };
|
|
19986
|
+
}
|
|
19987
|
+
function getCachedLicenseGate() {
|
|
19988
|
+
return {
|
|
19989
|
+
license: _cachedLicense,
|
|
19990
|
+
hasKey: _hasLicenseKey
|
|
19991
|
+
};
|
|
19992
|
+
}
|
|
19993
|
+
|
|
19994
|
+
// src/mcp/tool-telemetry.ts
|
|
19995
|
+
var _toolCalls = /* @__PURE__ */ new Map();
|
|
19996
|
+
var _sessionStartedAt = Date.now();
|
|
19997
|
+
var _flushTimer2 = null;
|
|
19998
|
+
function recordCall(toolName, action, isError) {
|
|
19999
|
+
let record = _toolCalls.get(toolName);
|
|
20000
|
+
if (!record) {
|
|
20001
|
+
record = { count: 0, actions: /* @__PURE__ */ new Map(), lastCalledAt: 0, errors: 0 };
|
|
20002
|
+
_toolCalls.set(toolName, record);
|
|
20003
|
+
}
|
|
20004
|
+
record.count++;
|
|
20005
|
+
record.lastCalledAt = Date.now();
|
|
20006
|
+
if (isError) record.errors++;
|
|
20007
|
+
if (action) {
|
|
20008
|
+
record.actions.set(action, (record.actions.get(action) ?? 0) + 1);
|
|
20009
|
+
}
|
|
20010
|
+
}
|
|
20011
|
+
function wrapServerWithTelemetry(server2) {
|
|
20012
|
+
const originalRegisterTool = server2.registerTool.bind(server2);
|
|
20013
|
+
server2.registerTool = (name, config2, handler) => {
|
|
20014
|
+
const wrappedHandler = async (input, extra) => {
|
|
20015
|
+
const action = input.action;
|
|
20016
|
+
try {
|
|
20017
|
+
const result3 = await handler(input, extra);
|
|
20018
|
+
const isError = result3?.isError === true;
|
|
20019
|
+
recordCall(name, action, isError);
|
|
20020
|
+
return result3;
|
|
20021
|
+
} catch (err) {
|
|
20022
|
+
recordCall(name, action, true);
|
|
20023
|
+
throw err;
|
|
20024
|
+
}
|
|
20025
|
+
};
|
|
20026
|
+
return originalRegisterTool(name, config2, wrappedHandler);
|
|
20027
|
+
};
|
|
20028
|
+
return server2;
|
|
20029
|
+
}
|
|
20030
|
+
function getToolUsageStats() {
|
|
20031
|
+
let totalCalls = 0;
|
|
20032
|
+
let totalErrors = 0;
|
|
20033
|
+
const tools = {};
|
|
20034
|
+
for (const [name, record] of _toolCalls) {
|
|
20035
|
+
totalCalls += record.count;
|
|
20036
|
+
totalErrors += record.errors;
|
|
20037
|
+
const entry = {
|
|
20038
|
+
calls: record.count,
|
|
20039
|
+
errors: record.errors,
|
|
20040
|
+
lastCalledAt: new Date(record.lastCalledAt).toISOString()
|
|
20041
|
+
};
|
|
20042
|
+
if (record.actions.size > 0) {
|
|
20043
|
+
entry.actions = Object.fromEntries(record.actions);
|
|
20044
|
+
}
|
|
20045
|
+
tools[name] = entry;
|
|
20046
|
+
}
|
|
20047
|
+
return {
|
|
20048
|
+
sessionStartedAt: new Date(_sessionStartedAt).toISOString(),
|
|
20049
|
+
uptimeMs: Date.now() - _sessionStartedAt,
|
|
20050
|
+
totalCalls,
|
|
20051
|
+
totalErrors,
|
|
20052
|
+
tools
|
|
20053
|
+
};
|
|
20054
|
+
}
|
|
20055
|
+
var FLUSH_INTERVAL_MS = 5 * 60 * 1e3;
|
|
20056
|
+
var _lastFlushedAt = 0;
|
|
20057
|
+
async function flushToMemory() {
|
|
20058
|
+
const stats = getToolUsageStats();
|
|
20059
|
+
if (stats.totalCalls === 0) return;
|
|
20060
|
+
if (stats.totalCalls === _lastFlushedAt) return;
|
|
20061
|
+
try {
|
|
20062
|
+
const { getClient: getClient2, isInitialized: isInitialized2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
20063
|
+
if (!isInitialized2()) return;
|
|
20064
|
+
const client = getClient2();
|
|
20065
|
+
const toolSummary = Object.entries(stats.tools).sort((a, b) => b[1].calls - a[1].calls).map(([name, t]) => {
|
|
20066
|
+
const actionStr = t.actions ? ` (${Object.entries(t.actions).sort((a, b) => b[1] - a[1]).map(([a, c]) => `${a}:${c}`).join(", ")})` : "";
|
|
20067
|
+
return `${name}: ${t.calls} calls${t.errors > 0 ? ` (${t.errors} errors)` : ""}${actionStr}`;
|
|
20068
|
+
}).join("\n");
|
|
20069
|
+
const raw_text = `Tool usage since ${stats.sessionStartedAt} (${Math.round(stats.uptimeMs / 6e4)}min):
|
|
20070
|
+
Total: ${stats.totalCalls} calls, ${stats.totalErrors} errors
|
|
20071
|
+
|
|
20072
|
+
${toolSummary}`;
|
|
20073
|
+
await client.execute({
|
|
20074
|
+
sql: `INSERT INTO memories (id, agent_id, raw_text, memory_type, project_name, importance, created_at, updated_at)
|
|
20075
|
+
VALUES (?, 'system', ?, 'telemetry', 'exe-os', 2, datetime('now'), datetime('now'))`,
|
|
20076
|
+
args: [
|
|
20077
|
+
`telemetry-tools-${Date.now()}`,
|
|
20078
|
+
raw_text
|
|
20079
|
+
]
|
|
20080
|
+
});
|
|
20081
|
+
_lastFlushedAt = stats.totalCalls;
|
|
20082
|
+
} catch {
|
|
20083
|
+
}
|
|
20084
|
+
}
|
|
20085
|
+
function startToolTelemetryFlush() {
|
|
20086
|
+
if (_flushTimer2) return;
|
|
20087
|
+
_sessionStartedAt = Date.now();
|
|
20088
|
+
_flushTimer2 = setInterval(() => void flushToMemory(), FLUSH_INTERVAL_MS);
|
|
20089
|
+
_flushTimer2.unref();
|
|
20090
|
+
}
|
|
20091
|
+
|
|
20092
|
+
// src/mcp/tools/mcp-ping.ts
|
|
19943
20093
|
var PID_PATH3 = path30.join(homedir4(), ".exe-os", "exed.pid");
|
|
19944
20094
|
function isDaemonAlive2() {
|
|
19945
20095
|
try {
|
|
@@ -19966,6 +20116,7 @@ function registerMcpPing(server2) {
|
|
|
19966
20116
|
const daemon = isDaemonAlive2();
|
|
19967
20117
|
const summary = summarizeMcpTransport();
|
|
19968
20118
|
writeMcpTransportSummary();
|
|
20119
|
+
const gate = getCachedLicenseGate();
|
|
19969
20120
|
const status2 = daemon.alive ? "ok" : "degraded";
|
|
19970
20121
|
return {
|
|
19971
20122
|
content: [
|
|
@@ -19974,8 +20125,14 @@ function registerMcpPing(server2) {
|
|
|
19974
20125
|
text: JSON.stringify({
|
|
19975
20126
|
status: status2,
|
|
19976
20127
|
daemon,
|
|
20128
|
+
licenseGate: {
|
|
20129
|
+
hasKey: gate.hasKey,
|
|
20130
|
+
plan: gate.license?.plan ?? "none",
|
|
20131
|
+
valid: gate.license?.valid ?? false
|
|
20132
|
+
},
|
|
20133
|
+
toolUsage: getToolUsageStats(),
|
|
19977
20134
|
mcpTransport: summary,
|
|
19978
|
-
remediation: daemon.alive ? "MCP transport probe reached the server. If tools still fail, reconnect the MCP client." : "Daemon is offline. Restart exe-os/exed; do not bypass MCP or access the DB directly."
|
|
20135
|
+
remediation: daemon.alive ? gate.hasKey ? "MCP transport probe reached the server. If tools still fail, reconnect the MCP client." : "No license key found. Run: echo 'exe_sk_YOUR_KEY' > ~/.exe-os/license.key then reconnect MCP." : "Daemon is offline. Restart exe-os/exed; do not bypass MCP or access the DB directly."
|
|
19979
20136
|
}, null, 2)
|
|
19980
20137
|
}
|
|
19981
20138
|
]
|
|
@@ -20181,6 +20338,7 @@ import { fileURLToPath as fileURLToPath4 } from "url";
|
|
|
20181
20338
|
function isMainModule(importMetaUrl) {
|
|
20182
20339
|
if (process.argv[1] == null) return false;
|
|
20183
20340
|
if (process.argv[1].includes("mcp/server")) return false;
|
|
20341
|
+
if (process.argv[1].includes("exe-daemon")) return false;
|
|
20184
20342
|
try {
|
|
20185
20343
|
const scriptPath = realpathSync(process.argv[1]);
|
|
20186
20344
|
const modulePath = realpathSync(fileURLToPath4(importMetaUrl));
|
|
@@ -21597,7 +21755,8 @@ function loadPgClient() {
|
|
|
21597
21755
|
return new Ctor();
|
|
21598
21756
|
}
|
|
21599
21757
|
const { Pool } = await import("pg");
|
|
21600
|
-
const
|
|
21758
|
+
const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
|
|
21759
|
+
const pool = new Pool({ connectionString: process.env.DATABASE_URL, ...pgSslConfig2() });
|
|
21601
21760
|
return {
|
|
21602
21761
|
async $queryRawUnsafe(query, ...values) {
|
|
21603
21762
|
const result3 = await pool.query(query, values);
|
|
@@ -22126,6 +22285,17 @@ async function cloudSync(config2) {
|
|
|
22126
22285
|
} catch (err) {
|
|
22127
22286
|
logError(`[cloud-sync] DB backup upload error: ${err instanceof Error ? err.message : String(err)}`);
|
|
22128
22287
|
}
|
|
22288
|
+
let codeContextResult = { pushed: 0, pulled: 0 };
|
|
22289
|
+
try {
|
|
22290
|
+
codeContextResult.pushed = await cloudPushCodeContext(config2);
|
|
22291
|
+
} catch (err) {
|
|
22292
|
+
logError(`[cloud-sync] Code context push: ${err instanceof Error ? err.message : String(err)}`);
|
|
22293
|
+
}
|
|
22294
|
+
try {
|
|
22295
|
+
codeContextResult.pulled = await cloudPullCodeContext(config2);
|
|
22296
|
+
} catch (err) {
|
|
22297
|
+
logError(`[cloud-sync] Code context pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
22298
|
+
}
|
|
22129
22299
|
return {
|
|
22130
22300
|
pushed,
|
|
22131
22301
|
pulled,
|
|
@@ -22135,7 +22305,8 @@ async function cloudSync(config2) {
|
|
|
22135
22305
|
tasks: tasksResult,
|
|
22136
22306
|
conversations: conversationsResult,
|
|
22137
22307
|
documents: documentsResult,
|
|
22138
|
-
roster: rosterResult
|
|
22308
|
+
roster: rosterResult,
|
|
22309
|
+
codeContext: codeContextResult
|
|
22139
22310
|
};
|
|
22140
22311
|
}
|
|
22141
22312
|
var ROSTER_DELETIONS_PATH = path37.join(EXE_AI_DIR, "roster-deletions.json");
|
|
@@ -22763,6 +22934,99 @@ async function cloudPullDocuments(config2) {
|
|
|
22763
22934
|
}
|
|
22764
22935
|
return { pulled };
|
|
22765
22936
|
}
|
|
22937
|
+
var CODE_CONTEXT_DIR = path37.join(EXE_AI_DIR, "code-context");
|
|
22938
|
+
async function cloudPushCodeContext(config2) {
|
|
22939
|
+
assertSecureEndpoint(config2.endpoint);
|
|
22940
|
+
if (!existsSync32(CODE_CONTEXT_DIR)) return 0;
|
|
22941
|
+
const files = readdirSync11(CODE_CONTEXT_DIR).filter(
|
|
22942
|
+
(f) => f.endsWith(".json") && !f.endsWith(".vectors.json") && !f.startsWith(".")
|
|
22943
|
+
);
|
|
22944
|
+
if (files.length === 0) return 0;
|
|
22945
|
+
const metaPath = path37.join(CODE_CONTEXT_DIR, ".sync-meta.json");
|
|
22946
|
+
let syncMeta = {};
|
|
22947
|
+
if (existsSync32(metaPath)) {
|
|
22948
|
+
try {
|
|
22949
|
+
syncMeta = JSON.parse(readFileSync25(metaPath, "utf-8"));
|
|
22950
|
+
} catch {
|
|
22951
|
+
}
|
|
22952
|
+
}
|
|
22953
|
+
let pushed = 0;
|
|
22954
|
+
for (const file of files) {
|
|
22955
|
+
const filePath = path37.join(CODE_CONTEXT_DIR, file);
|
|
22956
|
+
try {
|
|
22957
|
+
const stat = statSync7(filePath);
|
|
22958
|
+
const lastPushed = syncMeta[file] ?? 0;
|
|
22959
|
+
if (stat.mtimeMs <= lastPushed) continue;
|
|
22960
|
+
const content = readFileSync25(filePath, "utf-8");
|
|
22961
|
+
const header = content.substring(0, 300);
|
|
22962
|
+
if (header.includes("/tmp") || header.includes("/var/folders") || header.includes(".worktrees/")) continue;
|
|
22963
|
+
const compressed = compress(Buffer.from(content, "utf8"));
|
|
22964
|
+
const encrypted = encryptSyncBlob(compressed);
|
|
22965
|
+
const resp = await fetchWithRetry(`${config2.endpoint}/sync/push-code-context`, {
|
|
22966
|
+
method: "POST",
|
|
22967
|
+
headers: {
|
|
22968
|
+
Authorization: `Bearer ${config2.apiKey}`,
|
|
22969
|
+
"Content-Type": "application/json",
|
|
22970
|
+
"X-Device-Id": loadDeviceId()
|
|
22971
|
+
},
|
|
22972
|
+
body: JSON.stringify({ key: file, blob: encrypted })
|
|
22973
|
+
});
|
|
22974
|
+
if (resp.ok) {
|
|
22975
|
+
syncMeta[file] = stat.mtimeMs;
|
|
22976
|
+
pushed++;
|
|
22977
|
+
}
|
|
22978
|
+
} catch {
|
|
22979
|
+
}
|
|
22980
|
+
}
|
|
22981
|
+
if (pushed > 0) {
|
|
22982
|
+
try {
|
|
22983
|
+
writeFileSync18(metaPath, JSON.stringify(syncMeta));
|
|
22984
|
+
} catch {
|
|
22985
|
+
}
|
|
22986
|
+
}
|
|
22987
|
+
return pushed;
|
|
22988
|
+
}
|
|
22989
|
+
async function cloudPullCodeContext(config2) {
|
|
22990
|
+
assertSecureEndpoint(config2.endpoint);
|
|
22991
|
+
try {
|
|
22992
|
+
const resp = await fetchWithRetry(`${config2.endpoint}/sync/pull-code-context`, {
|
|
22993
|
+
method: "GET",
|
|
22994
|
+
headers: {
|
|
22995
|
+
Authorization: `Bearer ${config2.apiKey}`,
|
|
22996
|
+
"X-Device-Id": loadDeviceId()
|
|
22997
|
+
}
|
|
22998
|
+
});
|
|
22999
|
+
if (!resp.ok) return 0;
|
|
23000
|
+
const data = await resp.json();
|
|
23001
|
+
if (!data.indexes || data.indexes.length === 0) return 0;
|
|
23002
|
+
mkdirSync16(CODE_CONTEXT_DIR, { recursive: true });
|
|
23003
|
+
let pulled = 0;
|
|
23004
|
+
for (const { key, blob } of data.indexes) {
|
|
23005
|
+
try {
|
|
23006
|
+
if (key.endsWith(".vectors.json")) continue;
|
|
23007
|
+
const localPath = path37.join(CODE_CONTEXT_DIR, key);
|
|
23008
|
+
const compressed = decryptSyncBlob(blob);
|
|
23009
|
+
const content = decompress(compressed).toString("utf8");
|
|
23010
|
+
if (!existsSync32(localPath)) {
|
|
23011
|
+
writeFileSync18(localPath, content, "utf-8");
|
|
23012
|
+
pulled++;
|
|
23013
|
+
} else {
|
|
23014
|
+
const localContent = readFileSync25(localPath, "utf-8");
|
|
23015
|
+
if (localContent.length !== content.length) {
|
|
23016
|
+
writeFileSync18(localPath, content, "utf-8");
|
|
23017
|
+
pulled++;
|
|
23018
|
+
}
|
|
23019
|
+
}
|
|
23020
|
+
} catch {
|
|
23021
|
+
}
|
|
23022
|
+
}
|
|
23023
|
+
return pulled;
|
|
23024
|
+
} catch (err) {
|
|
23025
|
+
process.stderr.write(`[cloud-sync] Code context pull failed: ${err instanceof Error ? err.message : String(err)}
|
|
23026
|
+
`);
|
|
23027
|
+
return 0;
|
|
23028
|
+
}
|
|
23029
|
+
}
|
|
22766
23030
|
|
|
22767
23031
|
// src/mcp/tools/cloud-sync.ts
|
|
22768
23032
|
init_config();
|
|
@@ -26921,6 +27185,22 @@ async function getExeDbReadClient() {
|
|
|
26921
27185
|
}
|
|
26922
27186
|
if (!prismaPromise3) {
|
|
26923
27187
|
prismaPromise3 = (async () => {
|
|
27188
|
+
const readonlyUrl = process.env.MCP_READONLY_DATABASE_URL;
|
|
27189
|
+
if (readonlyUrl) {
|
|
27190
|
+
const { Pool } = await import("pg");
|
|
27191
|
+
const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
|
|
27192
|
+
const pool = new Pool({ connectionString: readonlyUrl, ...pgSslConfig2() });
|
|
27193
|
+
return {
|
|
27194
|
+
async $queryRawUnsafe(query, ...values) {
|
|
27195
|
+
const result3 = await pool.query(query, values);
|
|
27196
|
+
return result3.rows;
|
|
27197
|
+
},
|
|
27198
|
+
async $disconnect() {
|
|
27199
|
+
await pool.end();
|
|
27200
|
+
}
|
|
27201
|
+
};
|
|
27202
|
+
}
|
|
27203
|
+
console.warn("[exe-db-read] WARNING: MCP_READONLY_DATABASE_URL not set \u2014 falling back to admin role");
|
|
26924
27204
|
const explicitPath = process.env.EXE_OS_PRISMA_CLIENT_PATH;
|
|
26925
27205
|
if (explicitPath) {
|
|
26926
27206
|
const mod2 = await import(pathToFileURL5(explicitPath).href);
|
|
@@ -27881,7 +28161,10 @@ function registerSupportTools(server2) {
|
|
|
27881
28161
|
endpoint2.searchParams.set("status", status2);
|
|
27882
28162
|
endpoint2.searchParams.set("limit", String(limit));
|
|
27883
28163
|
const headers = { "content-type": "application/json" };
|
|
27884
|
-
if (licenseKey)
|
|
28164
|
+
if (licenseKey) {
|
|
28165
|
+
headers["authorization"] = `Bearer ${licenseKey}`;
|
|
28166
|
+
headers["x-exe-license-key"] = licenseKey;
|
|
28167
|
+
}
|
|
27885
28168
|
if (licenseToken) headers["x-exe-license-token"] = licenseToken;
|
|
27886
28169
|
try {
|
|
27887
28170
|
const res = await fetch(endpoint2.toString(), { method: "GET", headers, signal: AbortSignal.timeout(15e3) });
|
|
@@ -27944,7 +28227,10 @@ function registerSupportTools(server2) {
|
|
|
27944
28227
|
endpoint2.searchParams.set("status", status2);
|
|
27945
28228
|
endpoint2.searchParams.set("limit", String(limit));
|
|
27946
28229
|
const headers = { "content-type": "application/json" };
|
|
27947
|
-
if (licenseKey)
|
|
28230
|
+
if (licenseKey) {
|
|
28231
|
+
headers["authorization"] = `Bearer ${licenseKey}`;
|
|
28232
|
+
headers["x-exe-license-key"] = licenseKey;
|
|
28233
|
+
}
|
|
27948
28234
|
if (licenseToken) headers["x-exe-license-token"] = licenseToken;
|
|
27949
28235
|
try {
|
|
27950
28236
|
const res = await fetch(endpoint2.toString(), { method: "GET", headers, signal: AbortSignal.timeout(15e3) });
|
|
@@ -28409,7 +28695,7 @@ function runHealthCheck() {
|
|
|
28409
28695
|
const failed = results.filter((r) => !r.pass).length;
|
|
28410
28696
|
return { results, passed, failed };
|
|
28411
28697
|
}
|
|
28412
|
-
if (isMainModule(import.meta.url)) {
|
|
28698
|
+
if (isMainModule(import.meta.url) && (process.argv[1] ?? "").includes("exe-healthcheck")) {
|
|
28413
28699
|
const { results, passed, failed } = runHealthCheck();
|
|
28414
28700
|
console.log("\n exe-os Health Check\n");
|
|
28415
28701
|
for (const r of results) {
|
|
@@ -29610,6 +29896,231 @@ function registerTriageFeatureRequest(server2) {
|
|
|
29610
29896
|
);
|
|
29611
29897
|
}
|
|
29612
29898
|
|
|
29899
|
+
// src/mcp/tools/decision.ts
|
|
29900
|
+
import { z as z95 } from "zod";
|
|
29901
|
+
function buildHandlers6() {
|
|
29902
|
+
const tools = /* @__PURE__ */ new Map();
|
|
29903
|
+
const fake = {
|
|
29904
|
+
registerTool(name, _config, handler) {
|
|
29905
|
+
tools.set(name, handler);
|
|
29906
|
+
}
|
|
29907
|
+
};
|
|
29908
|
+
registerStoreDecision(fake);
|
|
29909
|
+
registerGetDecision(fake);
|
|
29910
|
+
return tools;
|
|
29911
|
+
}
|
|
29912
|
+
var ACTION_TO_TOOL3 = {
|
|
29913
|
+
store: "store_decision",
|
|
29914
|
+
get: "get_decision"
|
|
29915
|
+
};
|
|
29916
|
+
function registerDecision(server2) {
|
|
29917
|
+
const handlers = buildHandlers6();
|
|
29918
|
+
server2.registerTool(
|
|
29919
|
+
"decision",
|
|
29920
|
+
{
|
|
29921
|
+
title: "Decision",
|
|
29922
|
+
description: "Store or retrieve authoritative decisions. Actions: store (persist a decision by domain), get (look up a decision by domain/query).",
|
|
29923
|
+
inputSchema: {
|
|
29924
|
+
action: z95.enum(["store", "get"]).describe("Decision operation"),
|
|
29925
|
+
domain: z95.string().optional().describe("Decision domain (e.g. 'architecture', 'hiring')"),
|
|
29926
|
+
decision: z95.string().optional().describe("Decision text for action=store"),
|
|
29927
|
+
rationale: z95.string().optional().describe("Why this decision was made (action=store)"),
|
|
29928
|
+
query: z95.string().optional().describe("Search query for action=get"),
|
|
29929
|
+
limit: z95.coerce.number().optional().describe("Max results for action=get")
|
|
29930
|
+
}
|
|
29931
|
+
},
|
|
29932
|
+
async (input, extra) => {
|
|
29933
|
+
const action = input.action;
|
|
29934
|
+
const toolName = ACTION_TO_TOOL3[action];
|
|
29935
|
+
if (!toolName) return { content: [{ type: "text", text: `Unknown decision action: ${action}` }], isError: true };
|
|
29936
|
+
const handler = handlers.get(toolName);
|
|
29937
|
+
if (!handler) return { content: [{ type: "text", text: `Handler not found: ${toolName}` }], isError: true };
|
|
29938
|
+
const { action: _, ...args } = input;
|
|
29939
|
+
return handler(args, extra);
|
|
29940
|
+
}
|
|
29941
|
+
);
|
|
29942
|
+
}
|
|
29943
|
+
|
|
29944
|
+
// src/mcp/tools/session.ts
|
|
29945
|
+
import { z as z96 } from "zod";
|
|
29946
|
+
function buildHandlers7() {
|
|
29947
|
+
const tools = /* @__PURE__ */ new Map();
|
|
29948
|
+
const fake = {
|
|
29949
|
+
registerTool(name, _config, handler) {
|
|
29950
|
+
tools.set(name, handler);
|
|
29951
|
+
}
|
|
29952
|
+
};
|
|
29953
|
+
registerGetSessionEvents(fake);
|
|
29954
|
+
registerGetLastAssistantResponse(fake);
|
|
29955
|
+
return tools;
|
|
29956
|
+
}
|
|
29957
|
+
var ACTION_TO_TOOL4 = {
|
|
29958
|
+
events: "get_session_events",
|
|
29959
|
+
last_response: "get_last_assistant_response"
|
|
29960
|
+
};
|
|
29961
|
+
function registerSession2(server2) {
|
|
29962
|
+
const handlers = buildHandlers7();
|
|
29963
|
+
server2.registerTool(
|
|
29964
|
+
"session",
|
|
29965
|
+
{
|
|
29966
|
+
title: "Session",
|
|
29967
|
+
description: "Session inspection tools. Actions: events (get session event log), last_response (get the most recent assistant response text).",
|
|
29968
|
+
inputSchema: {
|
|
29969
|
+
action: z96.enum(["events", "last_response"]).describe("Session operation"),
|
|
29970
|
+
session_id: z96.string().optional().describe("Session ID for action=events"),
|
|
29971
|
+
limit: z96.coerce.number().optional().describe("Max events for action=events")
|
|
29972
|
+
}
|
|
29973
|
+
},
|
|
29974
|
+
async (input, extra) => {
|
|
29975
|
+
const action = input.action;
|
|
29976
|
+
const toolName = ACTION_TO_TOOL4[action];
|
|
29977
|
+
if (!toolName) return { content: [{ type: "text", text: `Unknown session action: ${action}` }], isError: true };
|
|
29978
|
+
const handler = handlers.get(toolName);
|
|
29979
|
+
if (!handler) return { content: [{ type: "text", text: `Handler not found: ${toolName}` }], isError: true };
|
|
29980
|
+
const { action: _, ...args } = input;
|
|
29981
|
+
return handler(args, extra);
|
|
29982
|
+
}
|
|
29983
|
+
);
|
|
29984
|
+
}
|
|
29985
|
+
|
|
29986
|
+
// src/mcp/tools/support-consolidated.ts
|
|
29987
|
+
import { z as z97 } from "zod";
|
|
29988
|
+
function buildHandlers8() {
|
|
29989
|
+
const tools = /* @__PURE__ */ new Map();
|
|
29990
|
+
const fake = {
|
|
29991
|
+
registerTool(name, _config, handler) {
|
|
29992
|
+
tools.set(name, handler);
|
|
29993
|
+
}
|
|
29994
|
+
};
|
|
29995
|
+
registerCreateBugReport(fake);
|
|
29996
|
+
registerCreateFeatureRequest(fake);
|
|
29997
|
+
registerSupportTools(fake);
|
|
29998
|
+
registerListBugReports(fake);
|
|
29999
|
+
registerGetBugReport(fake);
|
|
30000
|
+
registerTriageBugReport(fake);
|
|
30001
|
+
registerListFeatureRequests(fake);
|
|
30002
|
+
registerGetFeatureRequest(fake);
|
|
30003
|
+
registerTriageFeatureRequest(fake);
|
|
30004
|
+
return tools;
|
|
30005
|
+
}
|
|
30006
|
+
var ACTION_TO_TOOL5 = {
|
|
30007
|
+
create_bug: "create_bug_report",
|
|
30008
|
+
create_feature: "create_feature_request",
|
|
30009
|
+
list_my_bugs: "list_my_bug_reports",
|
|
30010
|
+
list_my_features: "list_my_feature_requests",
|
|
30011
|
+
list_bugs: "list_bug_reports",
|
|
30012
|
+
get_bug: "get_bug_report",
|
|
30013
|
+
triage_bug: "triage_bug_report",
|
|
30014
|
+
list_features: "list_feature_requests",
|
|
30015
|
+
get_feature: "get_feature_request",
|
|
30016
|
+
triage_feature: "triage_feature_request",
|
|
30017
|
+
health: "support_health",
|
|
30018
|
+
test: "support_test"
|
|
30019
|
+
};
|
|
30020
|
+
function registerSupportConsolidated(server2) {
|
|
30021
|
+
const handlers = buildHandlers8();
|
|
30022
|
+
server2.registerTool(
|
|
30023
|
+
"support",
|
|
30024
|
+
{
|
|
30025
|
+
title: "Support",
|
|
30026
|
+
description: "Bug reports, feature requests, and support system. Actions: create_bug, create_feature, list_my_bugs, list_my_features, list_bugs, get_bug, triage_bug, list_features, get_feature, triage_feature, health, test.",
|
|
30027
|
+
inputSchema: {
|
|
30028
|
+
action: z97.enum([
|
|
30029
|
+
"create_bug",
|
|
30030
|
+
"create_feature",
|
|
30031
|
+
"list_my_bugs",
|
|
30032
|
+
"list_my_features",
|
|
30033
|
+
"list_bugs",
|
|
30034
|
+
"get_bug",
|
|
30035
|
+
"triage_bug",
|
|
30036
|
+
"list_features",
|
|
30037
|
+
"get_feature",
|
|
30038
|
+
"triage_feature",
|
|
30039
|
+
"health",
|
|
30040
|
+
"test"
|
|
30041
|
+
]).describe("Support operation"),
|
|
30042
|
+
title: z97.string().optional().describe("Bug/feature title"),
|
|
30043
|
+
description: z97.string().optional().describe("Bug/feature description"),
|
|
30044
|
+
steps_to_reproduce: z97.string().optional().describe("Steps to reproduce (bugs)"),
|
|
30045
|
+
expected_behavior: z97.string().optional().describe("Expected behavior (bugs)"),
|
|
30046
|
+
actual_behavior: z97.string().optional().describe("Actual behavior (bugs)"),
|
|
30047
|
+
severity: z97.string().optional().describe("Severity: p0/p1/p2/p3"),
|
|
30048
|
+
use_case: z97.string().optional().describe("Use case (features)"),
|
|
30049
|
+
proposed_solution: z97.string().optional().describe("Proposed solution (features)"),
|
|
30050
|
+
priority: z97.string().optional().describe("Priority (features)"),
|
|
30051
|
+
id: z97.string().optional().describe("Bug/feature ID for get/triage"),
|
|
30052
|
+
status: z97.string().optional().describe("Filter by status"),
|
|
30053
|
+
classification: z97.string().optional().describe("Triage classification"),
|
|
30054
|
+
resolution: z97.string().optional().describe("Triage resolution"),
|
|
30055
|
+
notes: z97.string().optional().describe("Triage notes (mapped to triage_notes for bug/feature triage)"),
|
|
30056
|
+
triage_notes: z97.string().optional().describe("Triage notes (legacy field name)"),
|
|
30057
|
+
linked_task_id: z97.string().optional().describe("Linked task ID for triage"),
|
|
30058
|
+
linked_commit: z97.string().optional().describe("Linked commit hash for triage"),
|
|
30059
|
+
fixed_version: z97.string().optional().describe("Version that fixes this bug"),
|
|
30060
|
+
limit: z97.coerce.number().optional().describe("Max results")
|
|
30061
|
+
}
|
|
30062
|
+
},
|
|
30063
|
+
async (input, extra) => {
|
|
30064
|
+
const action = input.action;
|
|
30065
|
+
const toolName = ACTION_TO_TOOL5[action];
|
|
30066
|
+
if (!toolName) return { content: [{ type: "text", text: `Unknown support action: ${action}` }], isError: true };
|
|
30067
|
+
const handler = handlers.get(toolName);
|
|
30068
|
+
if (!handler) return { content: [{ type: "text", text: `Handler not found: ${toolName}` }], isError: true };
|
|
30069
|
+
const { action: _, ...args } = input;
|
|
30070
|
+
if ((action === "triage_bug" || action === "triage_feature") && args.notes && !args.triage_notes) {
|
|
30071
|
+
args.triage_notes = args.notes;
|
|
30072
|
+
delete args.notes;
|
|
30073
|
+
}
|
|
30074
|
+
return handler(args, extra);
|
|
30075
|
+
}
|
|
30076
|
+
);
|
|
30077
|
+
}
|
|
30078
|
+
|
|
30079
|
+
// src/mcp/tools/diagnostics.ts
|
|
30080
|
+
import { z as z98 } from "zod";
|
|
30081
|
+
function buildHandlers9() {
|
|
30082
|
+
const tools = /* @__PURE__ */ new Map();
|
|
30083
|
+
const fake = {
|
|
30084
|
+
registerTool(name, _config, handler) {
|
|
30085
|
+
tools.set(name, handler);
|
|
30086
|
+
}
|
|
30087
|
+
};
|
|
30088
|
+
registerCliParityTools(fake);
|
|
30089
|
+
return tools;
|
|
30090
|
+
}
|
|
30091
|
+
function registerDiagnostics(server2) {
|
|
30092
|
+
const handlers = buildHandlers9();
|
|
30093
|
+
const toolNames = Array.from(handlers.keys());
|
|
30094
|
+
void (toolNames.length > 0 ? toolNames : ["healthcheck"]);
|
|
30095
|
+
server2.registerTool(
|
|
30096
|
+
"diagnostics",
|
|
30097
|
+
{
|
|
30098
|
+
title: "Diagnostics",
|
|
30099
|
+
description: `System diagnostics and admin operations. Actions: ${toolNames.join(", ")}. Covers health checks, update status, cloud status, key management, and employee rename.`,
|
|
30100
|
+
inputSchema: {
|
|
30101
|
+
action: z98.string().describe(`Diagnostic operation: ${toolNames.join(", ")}`),
|
|
30102
|
+
// Pass-through params used by various sub-tools
|
|
30103
|
+
name: z98.string().optional().describe("Employee name (rename_employee)"),
|
|
30104
|
+
new_name: z98.string().optional().describe("New employee name (rename_employee)"),
|
|
30105
|
+
query: z98.string().optional().describe("Search/filter query"),
|
|
30106
|
+
format: z98.string().optional().describe("Output format")
|
|
30107
|
+
}
|
|
30108
|
+
},
|
|
30109
|
+
async (input, extra) => {
|
|
30110
|
+
const action = input.action;
|
|
30111
|
+
const handler = handlers.get(action);
|
|
30112
|
+
if (!handler) {
|
|
30113
|
+
return {
|
|
30114
|
+
content: [{ type: "text", text: `Unknown diagnostics action: ${action}. Available: ${toolNames.join(", ")}` }],
|
|
30115
|
+
isError: true
|
|
30116
|
+
};
|
|
30117
|
+
}
|
|
30118
|
+
const { action: _, ...args } = input;
|
|
30119
|
+
return handler(args, extra);
|
|
30120
|
+
}
|
|
30121
|
+
);
|
|
30122
|
+
}
|
|
30123
|
+
|
|
29613
30124
|
// src/mcp/tool-gates.ts
|
|
29614
30125
|
var TOOL_GATES = {
|
|
29615
30126
|
core: [],
|
|
@@ -29665,6 +30176,11 @@ var TOOL_CATEGORIES = {
|
|
|
29665
30176
|
registerGetSessionEvents: "core",
|
|
29666
30177
|
registerGetLastAssistantResponse: "core",
|
|
29667
30178
|
registerCodeContext: "graph-read",
|
|
30179
|
+
// consolidated tools
|
|
30180
|
+
registerDecision: "core",
|
|
30181
|
+
registerSession: "core",
|
|
30182
|
+
registerSupportConsolidated: "core",
|
|
30183
|
+
registerDiagnostics: "admin",
|
|
29668
30184
|
registerListBugReports: "admin",
|
|
29669
30185
|
registerGetBugReport: "admin",
|
|
29670
30186
|
registerTriageBugReport: "admin",
|
|
@@ -29758,6 +30274,36 @@ var TOOL_CATEGORIES = {
|
|
|
29758
30274
|
registerListGlobalProcedures: "orchestration",
|
|
29759
30275
|
registerDeactivateGlobalProcedure: "orchestration"
|
|
29760
30276
|
};
|
|
30277
|
+
var PLAN_TIERS = {
|
|
30278
|
+
free: 0,
|
|
30279
|
+
pro: 1,
|
|
30280
|
+
team: 2,
|
|
30281
|
+
agency: 3,
|
|
30282
|
+
enterprise: 4
|
|
30283
|
+
};
|
|
30284
|
+
var PLAN_GATES = {
|
|
30285
|
+
core: "free",
|
|
30286
|
+
tasks: "free",
|
|
30287
|
+
comms: "free",
|
|
30288
|
+
reminders: "free",
|
|
30289
|
+
"graph-read": "free",
|
|
30290
|
+
licensing: "free",
|
|
30291
|
+
// always allow checking/managing own license
|
|
30292
|
+
"graph-write": "pro",
|
|
30293
|
+
wiki: "pro",
|
|
30294
|
+
crm: "pro",
|
|
30295
|
+
"raw-data": "pro",
|
|
30296
|
+
documents: "pro",
|
|
30297
|
+
gateway: "pro",
|
|
30298
|
+
admin: "pro",
|
|
30299
|
+
orchestration: "pro"
|
|
30300
|
+
};
|
|
30301
|
+
function isToolAllowedForPlan(registerFnName, plan) {
|
|
30302
|
+
const category = TOOL_CATEGORIES[registerFnName];
|
|
30303
|
+
if (!category) return true;
|
|
30304
|
+
const requiredPlan = PLAN_GATES[category] ?? "free";
|
|
30305
|
+
return PLAN_TIERS[plan] >= PLAN_TIERS[requiredPlan];
|
|
30306
|
+
}
|
|
29761
30307
|
var CHIEF_OF_STAFF_READ_TOOLS = /* @__PURE__ */ new Set([
|
|
29762
30308
|
"registerRecallMyMemory",
|
|
29763
30309
|
"registerAskTeamMemory",
|
|
@@ -29793,9 +30339,17 @@ function isToolAllowed(registerFnName) {
|
|
|
29793
30339
|
}
|
|
29794
30340
|
|
|
29795
30341
|
// src/mcp/register-tools.ts
|
|
29796
|
-
|
|
30342
|
+
var ALWAYS_ALLOWED = /* @__PURE__ */ new Set([
|
|
30343
|
+
"registerMcpPing",
|
|
30344
|
+
"registerGetLicenseStatus",
|
|
30345
|
+
"registerActivateLicense"
|
|
30346
|
+
]);
|
|
30347
|
+
function registerAllTools(server2, license, hasKey) {
|
|
29797
30348
|
const gate = (name, fn) => {
|
|
29798
|
-
if (isToolAllowed(name))
|
|
30349
|
+
if (!isToolAllowed(name)) return;
|
|
30350
|
+
if (hasKey === false && !ALWAYS_ALLOWED.has(name)) return;
|
|
30351
|
+
if (license && !isToolAllowedForPlan(name, license.plan)) return;
|
|
30352
|
+
fn(server2);
|
|
29799
30353
|
};
|
|
29800
30354
|
const mcpToolSurface = process.env.EXE_MCP_TOOL_SURFACE ?? "legacy";
|
|
29801
30355
|
const exposeConsolidatedTasks = mcpToolSurface === "both" || mcpToolSurface === "consolidated";
|
|
@@ -29816,6 +30370,14 @@ function registerAllTools(server2) {
|
|
|
29816
30370
|
const exposeLegacyGraph = mcpToolSurface !== "consolidated";
|
|
29817
30371
|
const exposeConsolidatedConfig = mcpToolSurface === "both" || mcpToolSurface === "consolidated";
|
|
29818
30372
|
const exposeLegacyConfig = mcpToolSurface !== "consolidated";
|
|
30373
|
+
const exposeConsolidatedDecisions = mcpToolSurface === "both" || mcpToolSurface === "consolidated";
|
|
30374
|
+
const exposeLegacyDecisions = mcpToolSurface !== "consolidated";
|
|
30375
|
+
const exposeConsolidatedSession = mcpToolSurface === "both" || mcpToolSurface === "consolidated";
|
|
30376
|
+
const exposeLegacySession = mcpToolSurface !== "consolidated";
|
|
30377
|
+
const exposeConsolidatedSupport = mcpToolSurface === "both" || mcpToolSurface === "consolidated";
|
|
30378
|
+
const exposeLegacySupport = mcpToolSurface !== "consolidated";
|
|
30379
|
+
const exposeConsolidatedDiagnostics = mcpToolSurface === "both" || mcpToolSurface === "consolidated";
|
|
30380
|
+
const exposeLegacyDiagnostics = mcpToolSurface !== "consolidated";
|
|
29819
30381
|
if (exposeConsolidatedMemory) {
|
|
29820
30382
|
gate("registerMemory", registerMemory);
|
|
29821
30383
|
}
|
|
@@ -29929,23 +30491,43 @@ function registerAllTools(server2) {
|
|
|
29929
30491
|
if (exposeLegacyMemory) {
|
|
29930
30492
|
gate("registerSearchEverything", registerSearchEverything);
|
|
29931
30493
|
}
|
|
29932
|
-
|
|
29933
|
-
|
|
29934
|
-
|
|
29935
|
-
|
|
29936
|
-
|
|
29937
|
-
|
|
29938
|
-
|
|
29939
|
-
|
|
29940
|
-
|
|
29941
|
-
|
|
29942
|
-
|
|
29943
|
-
gate("
|
|
29944
|
-
gate("
|
|
29945
|
-
gate("
|
|
29946
|
-
|
|
29947
|
-
|
|
30494
|
+
if (exposeConsolidatedDecisions) {
|
|
30495
|
+
gate("registerDecision", registerDecision);
|
|
30496
|
+
}
|
|
30497
|
+
if (exposeLegacyDecisions) {
|
|
30498
|
+
gate("registerStoreDecision", registerStoreDecision);
|
|
30499
|
+
gate("registerGetDecision", registerGetDecision);
|
|
30500
|
+
}
|
|
30501
|
+
if (exposeConsolidatedSupport) {
|
|
30502
|
+
gate("registerSupportConsolidated", registerSupportConsolidated);
|
|
30503
|
+
}
|
|
30504
|
+
if (exposeLegacySupport) {
|
|
30505
|
+
gate("registerCreateBugReport", registerCreateBugReport);
|
|
30506
|
+
gate("registerCreateFeatureRequest", registerCreateFeatureRequest);
|
|
30507
|
+
gate("registerSupportTools", registerSupportTools);
|
|
30508
|
+
if (process.env.ASKEXE_SUPPORT_ADMIN_TOKEN || process.env.EXE_SUPPORT_ADMIN_TOKEN) {
|
|
30509
|
+
gate("registerListBugReports", registerListBugReports);
|
|
30510
|
+
gate("registerGetBugReport", registerGetBugReport);
|
|
30511
|
+
gate("registerTriageBugReport", registerTriageBugReport);
|
|
30512
|
+
gate("registerListFeatureRequests", registerListFeatureRequests);
|
|
30513
|
+
gate("registerGetFeatureRequest", registerGetFeatureRequest);
|
|
30514
|
+
gate("registerTriageFeatureRequest", registerTriageFeatureRequest);
|
|
30515
|
+
}
|
|
30516
|
+
}
|
|
30517
|
+
if (exposeConsolidatedDiagnostics) {
|
|
30518
|
+
gate("registerDiagnostics", registerDiagnostics);
|
|
30519
|
+
}
|
|
30520
|
+
if (exposeLegacyDiagnostics) {
|
|
30521
|
+
gate("registerCliParityTools", registerCliParityTools);
|
|
29948
30522
|
}
|
|
30523
|
+
if (exposeConsolidatedSession) {
|
|
30524
|
+
gate("registerSession", registerSession2);
|
|
30525
|
+
}
|
|
30526
|
+
if (exposeLegacySession) {
|
|
30527
|
+
gate("registerGetSessionEvents", registerGetSessionEvents);
|
|
30528
|
+
gate("registerGetLastAssistantResponse", registerGetLastAssistantResponse);
|
|
30529
|
+
}
|
|
30530
|
+
gate("registerCodeContext", registerCodeContext);
|
|
29949
30531
|
if (exposeLegacyConfig) {
|
|
29950
30532
|
gate("registerGetAgentSpend", registerGetAgentSpend);
|
|
29951
30533
|
}
|
|
@@ -30060,9 +30642,13 @@ var _backfillTimer = null;
|
|
|
30060
30642
|
var _ppidWatchdog = null;
|
|
30061
30643
|
var _shuttingDown = false;
|
|
30062
30644
|
instrumentServer(server);
|
|
30063
|
-
|
|
30645
|
+
var wrappedServer = wrapServerWithTelemetry(server);
|
|
30646
|
+
var _licenseGate = await initLicenseGate();
|
|
30647
|
+
registerAllTools(wrappedServer, _licenseGate.license, _licenseGate.hasKey);
|
|
30648
|
+
startToolTelemetryFlush();
|
|
30064
30649
|
var _gatedRole = process.env.AGENT_ROLE ?? "standalone";
|
|
30065
|
-
|
|
30650
|
+
var _gatedPlan = _licenseGate.license?.plan ?? (_licenseGate.hasKey ? "validating" : "no-key");
|
|
30651
|
+
process.stderr.write(`[exe-os] Tool gating: role=${_gatedRole} plan=${_gatedPlan}
|
|
30066
30652
|
`);
|
|
30067
30653
|
try {
|
|
30068
30654
|
await initStore();
|