@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/lib/exe-daemon.js
CHANGED
|
@@ -2112,6 +2112,7 @@ __export(database_exports, {
|
|
|
2112
2112
|
isInitialized: () => isInitialized,
|
|
2113
2113
|
setExternalClient: () => setExternalClient
|
|
2114
2114
|
});
|
|
2115
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2115
2116
|
import { createClient } from "@libsql/client";
|
|
2116
2117
|
async function initDatabase(config2) {
|
|
2117
2118
|
if (_walCheckpointTimer) {
|
|
@@ -2153,6 +2154,16 @@ async function initDatabase(config2) {
|
|
|
2153
2154
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2154
2155
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2155
2156
|
}
|
|
2157
|
+
try {
|
|
2158
|
+
chmodSync2(config2.dbPath, 384);
|
|
2159
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2160
|
+
try {
|
|
2161
|
+
chmodSync2(config2.dbPath + suffix, 384);
|
|
2162
|
+
} catch {
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
} catch {
|
|
2166
|
+
}
|
|
2156
2167
|
}
|
|
2157
2168
|
function isInitialized() {
|
|
2158
2169
|
return _adapterClient !== null || _client !== null;
|
|
@@ -4135,6 +4146,21 @@ var init_agentic_ontology = __esm({
|
|
|
4135
4146
|
}
|
|
4136
4147
|
});
|
|
4137
4148
|
|
|
4149
|
+
// src/lib/pg-ssl.ts
|
|
4150
|
+
var pg_ssl_exports = {};
|
|
4151
|
+
__export(pg_ssl_exports, {
|
|
4152
|
+
pgSslConfig: () => pgSslConfig
|
|
4153
|
+
});
|
|
4154
|
+
function pgSslConfig() {
|
|
4155
|
+
if (process.env.EXE_DB_SSL_DISABLED === "true") return {};
|
|
4156
|
+
return { ssl: { rejectUnauthorized: process.env.EXE_DB_SSL_ALLOW_SELFSIGNED !== "true" } };
|
|
4157
|
+
}
|
|
4158
|
+
var init_pg_ssl = __esm({
|
|
4159
|
+
"src/lib/pg-ssl.ts"() {
|
|
4160
|
+
"use strict";
|
|
4161
|
+
}
|
|
4162
|
+
});
|
|
4163
|
+
|
|
4138
4164
|
// src/lib/projection-worker.ts
|
|
4139
4165
|
var projection_worker_exports = {};
|
|
4140
4166
|
__export(projection_worker_exports, {
|
|
@@ -4173,7 +4199,8 @@ function loadPrisma() {
|
|
|
4173
4199
|
return new Ctor();
|
|
4174
4200
|
}
|
|
4175
4201
|
const { Pool } = await import("pg");
|
|
4176
|
-
const
|
|
4202
|
+
const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
|
|
4203
|
+
const pool = new Pool({ connectionString: process.env.DATABASE_URL, ...pgSslConfig2() });
|
|
4177
4204
|
return {
|
|
4178
4205
|
async $queryRawUnsafe(query, ...values) {
|
|
4179
4206
|
const result3 = await pool.query(query, values);
|
|
@@ -11631,7 +11658,7 @@ function readQueue() {
|
|
|
11631
11658
|
function writeQueue(queue) {
|
|
11632
11659
|
ensureDir();
|
|
11633
11660
|
const tmp = `${QUEUE_PATH2}.tmp`;
|
|
11634
|
-
writeFileSync11(tmp, JSON.stringify(queue, null, 2));
|
|
11661
|
+
writeFileSync11(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
|
|
11635
11662
|
renameSync5(tmp, QUEUE_PATH2);
|
|
11636
11663
|
}
|
|
11637
11664
|
function queueIntercom(targetSession, reason) {
|
|
@@ -20832,6 +20859,166 @@ var init_get_daemon_health = __esm({
|
|
|
20832
20859
|
}
|
|
20833
20860
|
});
|
|
20834
20861
|
|
|
20862
|
+
// src/mcp/license-gate.ts
|
|
20863
|
+
var license_gate_exports = {};
|
|
20864
|
+
__export(license_gate_exports, {
|
|
20865
|
+
NO_LICENSE_MESSAGE: () => NO_LICENSE_MESSAGE,
|
|
20866
|
+
getCachedLicenseGate: () => getCachedLicenseGate,
|
|
20867
|
+
initLicenseGate: () => initLicenseGate
|
|
20868
|
+
});
|
|
20869
|
+
async function initLicenseGate() {
|
|
20870
|
+
const key = loadLicense();
|
|
20871
|
+
_hasLicenseKey = key !== null && key.length > 0;
|
|
20872
|
+
if (_hasLicenseKey) {
|
|
20873
|
+
try {
|
|
20874
|
+
_cachedLicense = await checkLicense();
|
|
20875
|
+
} catch {
|
|
20876
|
+
_cachedLicense = null;
|
|
20877
|
+
}
|
|
20878
|
+
return { license: _cachedLicense, hasKey: true };
|
|
20879
|
+
}
|
|
20880
|
+
return { license: null, hasKey: false };
|
|
20881
|
+
}
|
|
20882
|
+
function getCachedLicenseGate() {
|
|
20883
|
+
return {
|
|
20884
|
+
license: _cachedLicense,
|
|
20885
|
+
hasKey: _hasLicenseKey
|
|
20886
|
+
};
|
|
20887
|
+
}
|
|
20888
|
+
var _cachedLicense, _hasLicenseKey, NO_LICENSE_MESSAGE;
|
|
20889
|
+
var init_license_gate = __esm({
|
|
20890
|
+
"src/mcp/license-gate.ts"() {
|
|
20891
|
+
"use strict";
|
|
20892
|
+
init_license();
|
|
20893
|
+
_cachedLicense = null;
|
|
20894
|
+
_hasLicenseKey = false;
|
|
20895
|
+
NO_LICENSE_MESSAGE = "License key required. Get your key from the Exe OS team, then:\n\n echo 'exe_sk_YOUR_KEY' > ~/.exe-os/license.key\n\nThen run /mcp to reconnect, or restart your session.";
|
|
20896
|
+
}
|
|
20897
|
+
});
|
|
20898
|
+
|
|
20899
|
+
// src/mcp/tool-telemetry.ts
|
|
20900
|
+
var tool_telemetry_exports = {};
|
|
20901
|
+
__export(tool_telemetry_exports, {
|
|
20902
|
+
getToolUsageStats: () => getToolUsageStats,
|
|
20903
|
+
resetToolUsageStats: () => resetToolUsageStats,
|
|
20904
|
+
startToolTelemetryFlush: () => startToolTelemetryFlush,
|
|
20905
|
+
stopToolTelemetryFlush: () => stopToolTelemetryFlush,
|
|
20906
|
+
wrapServerWithTelemetry: () => wrapServerWithTelemetry
|
|
20907
|
+
});
|
|
20908
|
+
function recordCall(toolName, action, isError) {
|
|
20909
|
+
let record = _toolCalls.get(toolName);
|
|
20910
|
+
if (!record) {
|
|
20911
|
+
record = { count: 0, actions: /* @__PURE__ */ new Map(), lastCalledAt: 0, errors: 0 };
|
|
20912
|
+
_toolCalls.set(toolName, record);
|
|
20913
|
+
}
|
|
20914
|
+
record.count++;
|
|
20915
|
+
record.lastCalledAt = Date.now();
|
|
20916
|
+
if (isError) record.errors++;
|
|
20917
|
+
if (action) {
|
|
20918
|
+
record.actions.set(action, (record.actions.get(action) ?? 0) + 1);
|
|
20919
|
+
}
|
|
20920
|
+
}
|
|
20921
|
+
function wrapServerWithTelemetry(server) {
|
|
20922
|
+
const originalRegisterTool = server.registerTool.bind(server);
|
|
20923
|
+
server.registerTool = (name, config2, handler) => {
|
|
20924
|
+
const wrappedHandler = async (input, extra) => {
|
|
20925
|
+
const action = input.action;
|
|
20926
|
+
try {
|
|
20927
|
+
const result3 = await handler(input, extra);
|
|
20928
|
+
const isError = result3?.isError === true;
|
|
20929
|
+
recordCall(name, action, isError);
|
|
20930
|
+
return result3;
|
|
20931
|
+
} catch (err) {
|
|
20932
|
+
recordCall(name, action, true);
|
|
20933
|
+
throw err;
|
|
20934
|
+
}
|
|
20935
|
+
};
|
|
20936
|
+
return originalRegisterTool(name, config2, wrappedHandler);
|
|
20937
|
+
};
|
|
20938
|
+
return server;
|
|
20939
|
+
}
|
|
20940
|
+
function getToolUsageStats() {
|
|
20941
|
+
let totalCalls = 0;
|
|
20942
|
+
let totalErrors = 0;
|
|
20943
|
+
const tools = {};
|
|
20944
|
+
for (const [name, record] of _toolCalls) {
|
|
20945
|
+
totalCalls += record.count;
|
|
20946
|
+
totalErrors += record.errors;
|
|
20947
|
+
const entry = {
|
|
20948
|
+
calls: record.count,
|
|
20949
|
+
errors: record.errors,
|
|
20950
|
+
lastCalledAt: new Date(record.lastCalledAt).toISOString()
|
|
20951
|
+
};
|
|
20952
|
+
if (record.actions.size > 0) {
|
|
20953
|
+
entry.actions = Object.fromEntries(record.actions);
|
|
20954
|
+
}
|
|
20955
|
+
tools[name] = entry;
|
|
20956
|
+
}
|
|
20957
|
+
return {
|
|
20958
|
+
sessionStartedAt: new Date(_sessionStartedAt).toISOString(),
|
|
20959
|
+
uptimeMs: Date.now() - _sessionStartedAt,
|
|
20960
|
+
totalCalls,
|
|
20961
|
+
totalErrors,
|
|
20962
|
+
tools
|
|
20963
|
+
};
|
|
20964
|
+
}
|
|
20965
|
+
function resetToolUsageStats() {
|
|
20966
|
+
_toolCalls.clear();
|
|
20967
|
+
_sessionStartedAt = Date.now();
|
|
20968
|
+
}
|
|
20969
|
+
async function flushToMemory() {
|
|
20970
|
+
const stats = getToolUsageStats();
|
|
20971
|
+
if (stats.totalCalls === 0) return;
|
|
20972
|
+
if (stats.totalCalls === _lastFlushedAt) return;
|
|
20973
|
+
try {
|
|
20974
|
+
const { getClient: getClient2, isInitialized: isInitialized2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
20975
|
+
if (!isInitialized2()) return;
|
|
20976
|
+
const client = getClient2();
|
|
20977
|
+
const toolSummary = Object.entries(stats.tools).sort((a, b) => b[1].calls - a[1].calls).map(([name, t]) => {
|
|
20978
|
+
const actionStr = t.actions ? ` (${Object.entries(t.actions).sort((a, b) => b[1] - a[1]).map(([a, c]) => `${a}:${c}`).join(", ")})` : "";
|
|
20979
|
+
return `${name}: ${t.calls} calls${t.errors > 0 ? ` (${t.errors} errors)` : ""}${actionStr}`;
|
|
20980
|
+
}).join("\n");
|
|
20981
|
+
const raw_text = `Tool usage since ${stats.sessionStartedAt} (${Math.round(stats.uptimeMs / 6e4)}min):
|
|
20982
|
+
Total: ${stats.totalCalls} calls, ${stats.totalErrors} errors
|
|
20983
|
+
|
|
20984
|
+
${toolSummary}`;
|
|
20985
|
+
await client.execute({
|
|
20986
|
+
sql: `INSERT INTO memories (id, agent_id, raw_text, memory_type, project_name, importance, created_at, updated_at)
|
|
20987
|
+
VALUES (?, 'system', ?, 'telemetry', 'exe-os', 2, datetime('now'), datetime('now'))`,
|
|
20988
|
+
args: [
|
|
20989
|
+
`telemetry-tools-${Date.now()}`,
|
|
20990
|
+
raw_text
|
|
20991
|
+
]
|
|
20992
|
+
});
|
|
20993
|
+
_lastFlushedAt = stats.totalCalls;
|
|
20994
|
+
} catch {
|
|
20995
|
+
}
|
|
20996
|
+
}
|
|
20997
|
+
function startToolTelemetryFlush() {
|
|
20998
|
+
if (_flushTimer3) return;
|
|
20999
|
+
_sessionStartedAt = Date.now();
|
|
21000
|
+
_flushTimer3 = setInterval(() => void flushToMemory(), FLUSH_INTERVAL_MS2);
|
|
21001
|
+
_flushTimer3.unref();
|
|
21002
|
+
}
|
|
21003
|
+
async function stopToolTelemetryFlush() {
|
|
21004
|
+
if (_flushTimer3) {
|
|
21005
|
+
clearInterval(_flushTimer3);
|
|
21006
|
+
_flushTimer3 = null;
|
|
21007
|
+
}
|
|
21008
|
+
await flushToMemory();
|
|
21009
|
+
}
|
|
21010
|
+
var _toolCalls, _sessionStartedAt, _flushTimer3, FLUSH_INTERVAL_MS2, _lastFlushedAt;
|
|
21011
|
+
var init_tool_telemetry = __esm({
|
|
21012
|
+
"src/mcp/tool-telemetry.ts"() {
|
|
21013
|
+
"use strict";
|
|
21014
|
+
_toolCalls = /* @__PURE__ */ new Map();
|
|
21015
|
+
_sessionStartedAt = Date.now();
|
|
21016
|
+
_flushTimer3 = null;
|
|
21017
|
+
FLUSH_INTERVAL_MS2 = 5 * 60 * 1e3;
|
|
21018
|
+
_lastFlushedAt = 0;
|
|
21019
|
+
}
|
|
21020
|
+
});
|
|
21021
|
+
|
|
20835
21022
|
// src/mcp/tools/mcp-ping.ts
|
|
20836
21023
|
import { existsSync as existsSync27, readFileSync as readFileSync22 } from "fs";
|
|
20837
21024
|
import path33 from "path";
|
|
@@ -20862,6 +21049,7 @@ function registerMcpPing(server) {
|
|
|
20862
21049
|
const daemon = isDaemonAlive2();
|
|
20863
21050
|
const summary = summarizeMcpTransport();
|
|
20864
21051
|
writeMcpTransportSummary();
|
|
21052
|
+
const gate = getCachedLicenseGate();
|
|
20865
21053
|
const status2 = daemon.alive ? "ok" : "degraded";
|
|
20866
21054
|
return {
|
|
20867
21055
|
content: [
|
|
@@ -20870,8 +21058,14 @@ function registerMcpPing(server) {
|
|
|
20870
21058
|
text: JSON.stringify({
|
|
20871
21059
|
status: status2,
|
|
20872
21060
|
daemon,
|
|
21061
|
+
licenseGate: {
|
|
21062
|
+
hasKey: gate.hasKey,
|
|
21063
|
+
plan: gate.license?.plan ?? "none",
|
|
21064
|
+
valid: gate.license?.valid ?? false
|
|
21065
|
+
},
|
|
21066
|
+
toolUsage: getToolUsageStats(),
|
|
20873
21067
|
mcpTransport: summary,
|
|
20874
|
-
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."
|
|
21068
|
+
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."
|
|
20875
21069
|
}, null, 2)
|
|
20876
21070
|
}
|
|
20877
21071
|
]
|
|
@@ -20884,6 +21078,8 @@ var init_mcp_ping = __esm({
|
|
|
20884
21078
|
"src/mcp/tools/mcp-ping.ts"() {
|
|
20885
21079
|
"use strict";
|
|
20886
21080
|
init_mcp_transport_health();
|
|
21081
|
+
init_license_gate();
|
|
21082
|
+
init_tool_telemetry();
|
|
20887
21083
|
PID_PATH3 = path33.join(homedir4(), ".exe-os", "exed.pid");
|
|
20888
21084
|
}
|
|
20889
21085
|
});
|
|
@@ -22171,6 +22367,7 @@ import { fileURLToPath as fileURLToPath4 } from "url";
|
|
|
22171
22367
|
function isMainModule(importMetaUrl) {
|
|
22172
22368
|
if (process.argv[1] == null) return false;
|
|
22173
22369
|
if (process.argv[1].includes("mcp/server")) return false;
|
|
22370
|
+
if (process.argv[1].includes("exe-daemon")) return false;
|
|
22174
22371
|
try {
|
|
22175
22372
|
const scriptPath = realpathSync(process.argv[1]);
|
|
22176
22373
|
const modulePath = realpathSync(fileURLToPath4(importMetaUrl));
|
|
@@ -24005,6 +24202,7 @@ __export(cloud_sync_exports, {
|
|
|
24005
24202
|
cloudPull: () => cloudPull,
|
|
24006
24203
|
cloudPullBehaviors: () => cloudPullBehaviors,
|
|
24007
24204
|
cloudPullBlob: () => cloudPullBlob,
|
|
24205
|
+
cloudPullCodeContext: () => cloudPullCodeContext,
|
|
24008
24206
|
cloudPullConversations: () => cloudPullConversations,
|
|
24009
24207
|
cloudPullDocuments: () => cloudPullDocuments,
|
|
24010
24208
|
cloudPullGlobalProcedures: () => cloudPullGlobalProcedures,
|
|
@@ -24014,6 +24212,7 @@ __export(cloud_sync_exports, {
|
|
|
24014
24212
|
cloudPush: () => cloudPush,
|
|
24015
24213
|
cloudPushBehaviors: () => cloudPushBehaviors,
|
|
24016
24214
|
cloudPushBlob: () => cloudPushBlob,
|
|
24215
|
+
cloudPushCodeContext: () => cloudPushCodeContext,
|
|
24017
24216
|
cloudPushConversations: () => cloudPushConversations,
|
|
24018
24217
|
cloudPushDocuments: () => cloudPushDocuments,
|
|
24019
24218
|
cloudPushGlobalProcedures: () => cloudPushGlobalProcedures,
|
|
@@ -24092,7 +24291,8 @@ function loadPgClient() {
|
|
|
24092
24291
|
return new Ctor();
|
|
24093
24292
|
}
|
|
24094
24293
|
const { Pool } = await import("pg");
|
|
24095
|
-
const
|
|
24294
|
+
const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
|
|
24295
|
+
const pool = new Pool({ connectionString: process.env.DATABASE_URL, ...pgSslConfig2() });
|
|
24096
24296
|
return {
|
|
24097
24297
|
async $queryRawUnsafe(query, ...values) {
|
|
24098
24298
|
const result3 = await pool.query(query, values);
|
|
@@ -24637,6 +24837,17 @@ async function cloudSync(config2) {
|
|
|
24637
24837
|
} catch (err) {
|
|
24638
24838
|
logError(`[cloud-sync] DB backup upload error: ${err instanceof Error ? err.message : String(err)}`);
|
|
24639
24839
|
}
|
|
24840
|
+
let codeContextResult = { pushed: 0, pulled: 0 };
|
|
24841
|
+
try {
|
|
24842
|
+
codeContextResult.pushed = await cloudPushCodeContext(config2);
|
|
24843
|
+
} catch (err) {
|
|
24844
|
+
logError(`[cloud-sync] Code context push: ${err instanceof Error ? err.message : String(err)}`);
|
|
24845
|
+
}
|
|
24846
|
+
try {
|
|
24847
|
+
codeContextResult.pulled = await cloudPullCodeContext(config2);
|
|
24848
|
+
} catch (err) {
|
|
24849
|
+
logError(`[cloud-sync] Code context pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
24850
|
+
}
|
|
24640
24851
|
return {
|
|
24641
24852
|
pushed,
|
|
24642
24853
|
pulled,
|
|
@@ -24646,7 +24857,8 @@ async function cloudSync(config2) {
|
|
|
24646
24857
|
tasks: tasksResult,
|
|
24647
24858
|
conversations: conversationsResult,
|
|
24648
24859
|
documents: documentsResult,
|
|
24649
|
-
roster: rosterResult
|
|
24860
|
+
roster: rosterResult,
|
|
24861
|
+
codeContext: codeContextResult
|
|
24650
24862
|
};
|
|
24651
24863
|
}
|
|
24652
24864
|
function recordRosterDeletion(name) {
|
|
@@ -25284,7 +25496,99 @@ async function cloudPullDocuments(config2) {
|
|
|
25284
25496
|
}
|
|
25285
25497
|
return { pulled };
|
|
25286
25498
|
}
|
|
25287
|
-
|
|
25499
|
+
async function cloudPushCodeContext(config2) {
|
|
25500
|
+
assertSecureEndpoint(config2.endpoint);
|
|
25501
|
+
if (!existsSync36(CODE_CONTEXT_DIR)) return 0;
|
|
25502
|
+
const files = readdirSync11(CODE_CONTEXT_DIR).filter(
|
|
25503
|
+
(f) => f.endsWith(".json") && !f.endsWith(".vectors.json") && !f.startsWith(".")
|
|
25504
|
+
);
|
|
25505
|
+
if (files.length === 0) return 0;
|
|
25506
|
+
const metaPath = path41.join(CODE_CONTEXT_DIR, ".sync-meta.json");
|
|
25507
|
+
let syncMeta = {};
|
|
25508
|
+
if (existsSync36(metaPath)) {
|
|
25509
|
+
try {
|
|
25510
|
+
syncMeta = JSON.parse(readFileSync28(metaPath, "utf-8"));
|
|
25511
|
+
} catch {
|
|
25512
|
+
}
|
|
25513
|
+
}
|
|
25514
|
+
let pushed = 0;
|
|
25515
|
+
for (const file of files) {
|
|
25516
|
+
const filePath = path41.join(CODE_CONTEXT_DIR, file);
|
|
25517
|
+
try {
|
|
25518
|
+
const stat = statSync8(filePath);
|
|
25519
|
+
const lastPushed = syncMeta[file] ?? 0;
|
|
25520
|
+
if (stat.mtimeMs <= lastPushed) continue;
|
|
25521
|
+
const content = readFileSync28(filePath, "utf-8");
|
|
25522
|
+
const header = content.substring(0, 300);
|
|
25523
|
+
if (header.includes("/tmp") || header.includes("/var/folders") || header.includes(".worktrees/")) continue;
|
|
25524
|
+
const compressed = compress(Buffer.from(content, "utf8"));
|
|
25525
|
+
const encrypted = encryptSyncBlob(compressed);
|
|
25526
|
+
const resp = await fetchWithRetry(`${config2.endpoint}/sync/push-code-context`, {
|
|
25527
|
+
method: "POST",
|
|
25528
|
+
headers: {
|
|
25529
|
+
Authorization: `Bearer ${config2.apiKey}`,
|
|
25530
|
+
"Content-Type": "application/json",
|
|
25531
|
+
"X-Device-Id": loadDeviceId()
|
|
25532
|
+
},
|
|
25533
|
+
body: JSON.stringify({ key: file, blob: encrypted })
|
|
25534
|
+
});
|
|
25535
|
+
if (resp.ok) {
|
|
25536
|
+
syncMeta[file] = stat.mtimeMs;
|
|
25537
|
+
pushed++;
|
|
25538
|
+
}
|
|
25539
|
+
} catch {
|
|
25540
|
+
}
|
|
25541
|
+
}
|
|
25542
|
+
if (pushed > 0) {
|
|
25543
|
+
try {
|
|
25544
|
+
writeFileSync19(metaPath, JSON.stringify(syncMeta));
|
|
25545
|
+
} catch {
|
|
25546
|
+
}
|
|
25547
|
+
}
|
|
25548
|
+
return pushed;
|
|
25549
|
+
}
|
|
25550
|
+
async function cloudPullCodeContext(config2) {
|
|
25551
|
+
assertSecureEndpoint(config2.endpoint);
|
|
25552
|
+
try {
|
|
25553
|
+
const resp = await fetchWithRetry(`${config2.endpoint}/sync/pull-code-context`, {
|
|
25554
|
+
method: "GET",
|
|
25555
|
+
headers: {
|
|
25556
|
+
Authorization: `Bearer ${config2.apiKey}`,
|
|
25557
|
+
"X-Device-Id": loadDeviceId()
|
|
25558
|
+
}
|
|
25559
|
+
});
|
|
25560
|
+
if (!resp.ok) return 0;
|
|
25561
|
+
const data = await resp.json();
|
|
25562
|
+
if (!data.indexes || data.indexes.length === 0) return 0;
|
|
25563
|
+
mkdirSync16(CODE_CONTEXT_DIR, { recursive: true });
|
|
25564
|
+
let pulled = 0;
|
|
25565
|
+
for (const { key, blob } of data.indexes) {
|
|
25566
|
+
try {
|
|
25567
|
+
if (key.endsWith(".vectors.json")) continue;
|
|
25568
|
+
const localPath = path41.join(CODE_CONTEXT_DIR, key);
|
|
25569
|
+
const compressed = decryptSyncBlob(blob);
|
|
25570
|
+
const content = decompress(compressed).toString("utf8");
|
|
25571
|
+
if (!existsSync36(localPath)) {
|
|
25572
|
+
writeFileSync19(localPath, content, "utf-8");
|
|
25573
|
+
pulled++;
|
|
25574
|
+
} else {
|
|
25575
|
+
const localContent = readFileSync28(localPath, "utf-8");
|
|
25576
|
+
if (localContent.length !== content.length) {
|
|
25577
|
+
writeFileSync19(localPath, content, "utf-8");
|
|
25578
|
+
pulled++;
|
|
25579
|
+
}
|
|
25580
|
+
}
|
|
25581
|
+
} catch {
|
|
25582
|
+
}
|
|
25583
|
+
}
|
|
25584
|
+
return pulled;
|
|
25585
|
+
} catch (err) {
|
|
25586
|
+
process.stderr.write(`[cloud-sync] Code context pull failed: ${err instanceof Error ? err.message : String(err)}
|
|
25587
|
+
`);
|
|
25588
|
+
return 0;
|
|
25589
|
+
}
|
|
25590
|
+
}
|
|
25591
|
+
var LOCALHOST_PATTERNS, FETCH_TIMEOUT_MS2, PUSH_BATCH_SIZE, ROSTER_LOCK_PATH, LOCK_STALE_MS, _pgPromise, _pgFailed, CLOUD_REUPLOAD_REQUIRED_MESSAGE, ROSTER_DELETIONS_PATH, CODE_CONTEXT_DIR;
|
|
25288
25592
|
var init_cloud_sync = __esm({
|
|
25289
25593
|
"src/lib/cloud-sync.ts"() {
|
|
25290
25594
|
"use strict";
|
|
@@ -25305,6 +25609,7 @@ var init_cloud_sync = __esm({
|
|
|
25305
25609
|
_pgFailed = false;
|
|
25306
25610
|
CLOUD_REUPLOAD_REQUIRED_MESSAGE = "Cloud sync is blocked because this device rotated its memory encryption key. Run `exe-os cloud reupload` first to re-upload the cloud backup with the new key.";
|
|
25307
25611
|
ROSTER_DELETIONS_PATH = path41.join(EXE_AI_DIR, "roster-deletions.json");
|
|
25612
|
+
CODE_CONTEXT_DIR = path41.join(EXE_AI_DIR, "code-context");
|
|
25308
25613
|
}
|
|
25309
25614
|
});
|
|
25310
25615
|
|
|
@@ -29700,6 +30005,22 @@ async function getExeDbReadClient() {
|
|
|
29700
30005
|
}
|
|
29701
30006
|
if (!prismaPromise4) {
|
|
29702
30007
|
prismaPromise4 = (async () => {
|
|
30008
|
+
const readonlyUrl = process.env.MCP_READONLY_DATABASE_URL;
|
|
30009
|
+
if (readonlyUrl) {
|
|
30010
|
+
const { Pool } = await import("pg");
|
|
30011
|
+
const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
|
|
30012
|
+
const pool = new Pool({ connectionString: readonlyUrl, ...pgSslConfig2() });
|
|
30013
|
+
return {
|
|
30014
|
+
async $queryRawUnsafe(query, ...values) {
|
|
30015
|
+
const result3 = await pool.query(query, values);
|
|
30016
|
+
return result3.rows;
|
|
30017
|
+
},
|
|
30018
|
+
async $disconnect() {
|
|
30019
|
+
await pool.end();
|
|
30020
|
+
}
|
|
30021
|
+
};
|
|
30022
|
+
}
|
|
30023
|
+
console.warn("[exe-db-read] WARNING: MCP_READONLY_DATABASE_URL not set \u2014 falling back to admin role");
|
|
29703
30024
|
const explicitPath = process.env.EXE_OS_PRISMA_CLIENT_PATH;
|
|
29704
30025
|
if (explicitPath) {
|
|
29705
30026
|
const mod2 = await import(pathToFileURL6(explicitPath).href);
|
|
@@ -30702,7 +31023,10 @@ function registerSupportTools(server) {
|
|
|
30702
31023
|
endpoint2.searchParams.set("status", status2);
|
|
30703
31024
|
endpoint2.searchParams.set("limit", String(limit));
|
|
30704
31025
|
const headers = { "content-type": "application/json" };
|
|
30705
|
-
if (licenseKey)
|
|
31026
|
+
if (licenseKey) {
|
|
31027
|
+
headers["authorization"] = `Bearer ${licenseKey}`;
|
|
31028
|
+
headers["x-exe-license-key"] = licenseKey;
|
|
31029
|
+
}
|
|
30706
31030
|
if (licenseToken) headers["x-exe-license-token"] = licenseToken;
|
|
30707
31031
|
try {
|
|
30708
31032
|
const res = await fetch(endpoint2.toString(), { method: "GET", headers, signal: AbortSignal.timeout(15e3) });
|
|
@@ -30765,7 +31089,10 @@ function registerSupportTools(server) {
|
|
|
30765
31089
|
endpoint2.searchParams.set("status", status2);
|
|
30766
31090
|
endpoint2.searchParams.set("limit", String(limit));
|
|
30767
31091
|
const headers = { "content-type": "application/json" };
|
|
30768
|
-
if (licenseKey)
|
|
31092
|
+
if (licenseKey) {
|
|
31093
|
+
headers["authorization"] = `Bearer ${licenseKey}`;
|
|
31094
|
+
headers["x-exe-license-key"] = licenseKey;
|
|
31095
|
+
}
|
|
30769
31096
|
if (licenseToken) headers["x-exe-license-token"] = licenseToken;
|
|
30770
31097
|
try {
|
|
30771
31098
|
const res = await fetch(endpoint2.toString(), { method: "GET", headers, signal: AbortSignal.timeout(15e3) });
|
|
@@ -31243,7 +31570,7 @@ var init_exe_healthcheck = __esm({
|
|
|
31243
31570
|
init_is_main();
|
|
31244
31571
|
init_config();
|
|
31245
31572
|
init_mcp_transport_health();
|
|
31246
|
-
if (isMainModule(import.meta.url)) {
|
|
31573
|
+
if (isMainModule(import.meta.url) && (process.argv[1] ?? "").includes("exe-healthcheck")) {
|
|
31247
31574
|
const { results, passed, failed } = runHealthCheck();
|
|
31248
31575
|
console.log("\n exe-os Health Check\n");
|
|
31249
31576
|
for (const r of results) {
|
|
@@ -32496,7 +32823,269 @@ var init_support_inbox = __esm({
|
|
|
32496
32823
|
}
|
|
32497
32824
|
});
|
|
32498
32825
|
|
|
32826
|
+
// src/mcp/tools/decision.ts
|
|
32827
|
+
import { z as z95 } from "zod";
|
|
32828
|
+
function buildHandlers6() {
|
|
32829
|
+
const tools = /* @__PURE__ */ new Map();
|
|
32830
|
+
const fake = {
|
|
32831
|
+
registerTool(name, _config, handler) {
|
|
32832
|
+
tools.set(name, handler);
|
|
32833
|
+
}
|
|
32834
|
+
};
|
|
32835
|
+
registerStoreDecision(fake);
|
|
32836
|
+
registerGetDecision(fake);
|
|
32837
|
+
return tools;
|
|
32838
|
+
}
|
|
32839
|
+
function registerDecision(server) {
|
|
32840
|
+
const handlers = buildHandlers6();
|
|
32841
|
+
server.registerTool(
|
|
32842
|
+
"decision",
|
|
32843
|
+
{
|
|
32844
|
+
title: "Decision",
|
|
32845
|
+
description: "Store or retrieve authoritative decisions. Actions: store (persist a decision by domain), get (look up a decision by domain/query).",
|
|
32846
|
+
inputSchema: {
|
|
32847
|
+
action: z95.enum(["store", "get"]).describe("Decision operation"),
|
|
32848
|
+
domain: z95.string().optional().describe("Decision domain (e.g. 'architecture', 'hiring')"),
|
|
32849
|
+
decision: z95.string().optional().describe("Decision text for action=store"),
|
|
32850
|
+
rationale: z95.string().optional().describe("Why this decision was made (action=store)"),
|
|
32851
|
+
query: z95.string().optional().describe("Search query for action=get"),
|
|
32852
|
+
limit: z95.coerce.number().optional().describe("Max results for action=get")
|
|
32853
|
+
}
|
|
32854
|
+
},
|
|
32855
|
+
async (input, extra) => {
|
|
32856
|
+
const action = input.action;
|
|
32857
|
+
const toolName = ACTION_TO_TOOL3[action];
|
|
32858
|
+
if (!toolName) return { content: [{ type: "text", text: `Unknown decision action: ${action}` }], isError: true };
|
|
32859
|
+
const handler = handlers.get(toolName);
|
|
32860
|
+
if (!handler) return { content: [{ type: "text", text: `Handler not found: ${toolName}` }], isError: true };
|
|
32861
|
+
const { action: _, ...args } = input;
|
|
32862
|
+
return handler(args, extra);
|
|
32863
|
+
}
|
|
32864
|
+
);
|
|
32865
|
+
}
|
|
32866
|
+
var ACTION_TO_TOOL3;
|
|
32867
|
+
var init_decision = __esm({
|
|
32868
|
+
"src/mcp/tools/decision.ts"() {
|
|
32869
|
+
"use strict";
|
|
32870
|
+
init_store_decision();
|
|
32871
|
+
init_get_decision();
|
|
32872
|
+
ACTION_TO_TOOL3 = {
|
|
32873
|
+
store: "store_decision",
|
|
32874
|
+
get: "get_decision"
|
|
32875
|
+
};
|
|
32876
|
+
}
|
|
32877
|
+
});
|
|
32878
|
+
|
|
32879
|
+
// src/mcp/tools/session.ts
|
|
32880
|
+
import { z as z96 } from "zod";
|
|
32881
|
+
function buildHandlers7() {
|
|
32882
|
+
const tools = /* @__PURE__ */ new Map();
|
|
32883
|
+
const fake = {
|
|
32884
|
+
registerTool(name, _config, handler) {
|
|
32885
|
+
tools.set(name, handler);
|
|
32886
|
+
}
|
|
32887
|
+
};
|
|
32888
|
+
registerGetSessionEvents(fake);
|
|
32889
|
+
registerGetLastAssistantResponse(fake);
|
|
32890
|
+
return tools;
|
|
32891
|
+
}
|
|
32892
|
+
function registerSession2(server) {
|
|
32893
|
+
const handlers = buildHandlers7();
|
|
32894
|
+
server.registerTool(
|
|
32895
|
+
"session",
|
|
32896
|
+
{
|
|
32897
|
+
title: "Session",
|
|
32898
|
+
description: "Session inspection tools. Actions: events (get session event log), last_response (get the most recent assistant response text).",
|
|
32899
|
+
inputSchema: {
|
|
32900
|
+
action: z96.enum(["events", "last_response"]).describe("Session operation"),
|
|
32901
|
+
session_id: z96.string().optional().describe("Session ID for action=events"),
|
|
32902
|
+
limit: z96.coerce.number().optional().describe("Max events for action=events")
|
|
32903
|
+
}
|
|
32904
|
+
},
|
|
32905
|
+
async (input, extra) => {
|
|
32906
|
+
const action = input.action;
|
|
32907
|
+
const toolName = ACTION_TO_TOOL4[action];
|
|
32908
|
+
if (!toolName) return { content: [{ type: "text", text: `Unknown session action: ${action}` }], isError: true };
|
|
32909
|
+
const handler = handlers.get(toolName);
|
|
32910
|
+
if (!handler) return { content: [{ type: "text", text: `Handler not found: ${toolName}` }], isError: true };
|
|
32911
|
+
const { action: _, ...args } = input;
|
|
32912
|
+
return handler(args, extra);
|
|
32913
|
+
}
|
|
32914
|
+
);
|
|
32915
|
+
}
|
|
32916
|
+
var ACTION_TO_TOOL4;
|
|
32917
|
+
var init_session = __esm({
|
|
32918
|
+
"src/mcp/tools/session.ts"() {
|
|
32919
|
+
"use strict";
|
|
32920
|
+
init_get_session_events();
|
|
32921
|
+
ACTION_TO_TOOL4 = {
|
|
32922
|
+
events: "get_session_events",
|
|
32923
|
+
last_response: "get_last_assistant_response"
|
|
32924
|
+
};
|
|
32925
|
+
}
|
|
32926
|
+
});
|
|
32927
|
+
|
|
32928
|
+
// src/mcp/tools/support-consolidated.ts
|
|
32929
|
+
import { z as z97 } from "zod";
|
|
32930
|
+
function buildHandlers8() {
|
|
32931
|
+
const tools = /* @__PURE__ */ new Map();
|
|
32932
|
+
const fake = {
|
|
32933
|
+
registerTool(name, _config, handler) {
|
|
32934
|
+
tools.set(name, handler);
|
|
32935
|
+
}
|
|
32936
|
+
};
|
|
32937
|
+
registerCreateBugReport(fake);
|
|
32938
|
+
registerCreateFeatureRequest(fake);
|
|
32939
|
+
registerSupportTools(fake);
|
|
32940
|
+
registerListBugReports(fake);
|
|
32941
|
+
registerGetBugReport(fake);
|
|
32942
|
+
registerTriageBugReport(fake);
|
|
32943
|
+
registerListFeatureRequests(fake);
|
|
32944
|
+
registerGetFeatureRequest(fake);
|
|
32945
|
+
registerTriageFeatureRequest(fake);
|
|
32946
|
+
return tools;
|
|
32947
|
+
}
|
|
32948
|
+
function registerSupportConsolidated(server) {
|
|
32949
|
+
const handlers = buildHandlers8();
|
|
32950
|
+
server.registerTool(
|
|
32951
|
+
"support",
|
|
32952
|
+
{
|
|
32953
|
+
title: "Support",
|
|
32954
|
+
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.",
|
|
32955
|
+
inputSchema: {
|
|
32956
|
+
action: z97.enum([
|
|
32957
|
+
"create_bug",
|
|
32958
|
+
"create_feature",
|
|
32959
|
+
"list_my_bugs",
|
|
32960
|
+
"list_my_features",
|
|
32961
|
+
"list_bugs",
|
|
32962
|
+
"get_bug",
|
|
32963
|
+
"triage_bug",
|
|
32964
|
+
"list_features",
|
|
32965
|
+
"get_feature",
|
|
32966
|
+
"triage_feature",
|
|
32967
|
+
"health",
|
|
32968
|
+
"test"
|
|
32969
|
+
]).describe("Support operation"),
|
|
32970
|
+
title: z97.string().optional().describe("Bug/feature title"),
|
|
32971
|
+
description: z97.string().optional().describe("Bug/feature description"),
|
|
32972
|
+
steps_to_reproduce: z97.string().optional().describe("Steps to reproduce (bugs)"),
|
|
32973
|
+
expected_behavior: z97.string().optional().describe("Expected behavior (bugs)"),
|
|
32974
|
+
actual_behavior: z97.string().optional().describe("Actual behavior (bugs)"),
|
|
32975
|
+
severity: z97.string().optional().describe("Severity: p0/p1/p2/p3"),
|
|
32976
|
+
use_case: z97.string().optional().describe("Use case (features)"),
|
|
32977
|
+
proposed_solution: z97.string().optional().describe("Proposed solution (features)"),
|
|
32978
|
+
priority: z97.string().optional().describe("Priority (features)"),
|
|
32979
|
+
id: z97.string().optional().describe("Bug/feature ID for get/triage"),
|
|
32980
|
+
status: z97.string().optional().describe("Filter by status"),
|
|
32981
|
+
classification: z97.string().optional().describe("Triage classification"),
|
|
32982
|
+
resolution: z97.string().optional().describe("Triage resolution"),
|
|
32983
|
+
notes: z97.string().optional().describe("Triage notes (mapped to triage_notes for bug/feature triage)"),
|
|
32984
|
+
triage_notes: z97.string().optional().describe("Triage notes (legacy field name)"),
|
|
32985
|
+
linked_task_id: z97.string().optional().describe("Linked task ID for triage"),
|
|
32986
|
+
linked_commit: z97.string().optional().describe("Linked commit hash for triage"),
|
|
32987
|
+
fixed_version: z97.string().optional().describe("Version that fixes this bug"),
|
|
32988
|
+
limit: z97.coerce.number().optional().describe("Max results")
|
|
32989
|
+
}
|
|
32990
|
+
},
|
|
32991
|
+
async (input, extra) => {
|
|
32992
|
+
const action = input.action;
|
|
32993
|
+
const toolName = ACTION_TO_TOOL5[action];
|
|
32994
|
+
if (!toolName) return { content: [{ type: "text", text: `Unknown support action: ${action}` }], isError: true };
|
|
32995
|
+
const handler = handlers.get(toolName);
|
|
32996
|
+
if (!handler) return { content: [{ type: "text", text: `Handler not found: ${toolName}` }], isError: true };
|
|
32997
|
+
const { action: _, ...args } = input;
|
|
32998
|
+
if ((action === "triage_bug" || action === "triage_feature") && args.notes && !args.triage_notes) {
|
|
32999
|
+
args.triage_notes = args.notes;
|
|
33000
|
+
delete args.notes;
|
|
33001
|
+
}
|
|
33002
|
+
return handler(args, extra);
|
|
33003
|
+
}
|
|
33004
|
+
);
|
|
33005
|
+
}
|
|
33006
|
+
var ACTION_TO_TOOL5;
|
|
33007
|
+
var init_support_consolidated = __esm({
|
|
33008
|
+
"src/mcp/tools/support-consolidated.ts"() {
|
|
33009
|
+
"use strict";
|
|
33010
|
+
init_create_bug_report();
|
|
33011
|
+
init_create_feature_request();
|
|
33012
|
+
init_support();
|
|
33013
|
+
init_support_inbox();
|
|
33014
|
+
ACTION_TO_TOOL5 = {
|
|
33015
|
+
create_bug: "create_bug_report",
|
|
33016
|
+
create_feature: "create_feature_request",
|
|
33017
|
+
list_my_bugs: "list_my_bug_reports",
|
|
33018
|
+
list_my_features: "list_my_feature_requests",
|
|
33019
|
+
list_bugs: "list_bug_reports",
|
|
33020
|
+
get_bug: "get_bug_report",
|
|
33021
|
+
triage_bug: "triage_bug_report",
|
|
33022
|
+
list_features: "list_feature_requests",
|
|
33023
|
+
get_feature: "get_feature_request",
|
|
33024
|
+
triage_feature: "triage_feature_request",
|
|
33025
|
+
health: "support_health",
|
|
33026
|
+
test: "support_test"
|
|
33027
|
+
};
|
|
33028
|
+
}
|
|
33029
|
+
});
|
|
33030
|
+
|
|
33031
|
+
// src/mcp/tools/diagnostics.ts
|
|
33032
|
+
import { z as z98 } from "zod";
|
|
33033
|
+
function buildHandlers9() {
|
|
33034
|
+
const tools = /* @__PURE__ */ new Map();
|
|
33035
|
+
const fake = {
|
|
33036
|
+
registerTool(name, _config, handler) {
|
|
33037
|
+
tools.set(name, handler);
|
|
33038
|
+
}
|
|
33039
|
+
};
|
|
33040
|
+
registerCliParityTools(fake);
|
|
33041
|
+
return tools;
|
|
33042
|
+
}
|
|
33043
|
+
function registerDiagnostics(server) {
|
|
33044
|
+
const handlers = buildHandlers9();
|
|
33045
|
+
const toolNames = Array.from(handlers.keys());
|
|
33046
|
+
void (toolNames.length > 0 ? toolNames : ["healthcheck"]);
|
|
33047
|
+
server.registerTool(
|
|
33048
|
+
"diagnostics",
|
|
33049
|
+
{
|
|
33050
|
+
title: "Diagnostics",
|
|
33051
|
+
description: `System diagnostics and admin operations. Actions: ${toolNames.join(", ")}. Covers health checks, update status, cloud status, key management, and employee rename.`,
|
|
33052
|
+
inputSchema: {
|
|
33053
|
+
action: z98.string().describe(`Diagnostic operation: ${toolNames.join(", ")}`),
|
|
33054
|
+
// Pass-through params used by various sub-tools
|
|
33055
|
+
name: z98.string().optional().describe("Employee name (rename_employee)"),
|
|
33056
|
+
new_name: z98.string().optional().describe("New employee name (rename_employee)"),
|
|
33057
|
+
query: z98.string().optional().describe("Search/filter query"),
|
|
33058
|
+
format: z98.string().optional().describe("Output format")
|
|
33059
|
+
}
|
|
33060
|
+
},
|
|
33061
|
+
async (input, extra) => {
|
|
33062
|
+
const action = input.action;
|
|
33063
|
+
const handler = handlers.get(action);
|
|
33064
|
+
if (!handler) {
|
|
33065
|
+
return {
|
|
33066
|
+
content: [{ type: "text", text: `Unknown diagnostics action: ${action}. Available: ${toolNames.join(", ")}` }],
|
|
33067
|
+
isError: true
|
|
33068
|
+
};
|
|
33069
|
+
}
|
|
33070
|
+
const { action: _, ...args } = input;
|
|
33071
|
+
return handler(args, extra);
|
|
33072
|
+
}
|
|
33073
|
+
);
|
|
33074
|
+
}
|
|
33075
|
+
var init_diagnostics = __esm({
|
|
33076
|
+
"src/mcp/tools/diagnostics.ts"() {
|
|
33077
|
+
"use strict";
|
|
33078
|
+
init_cli_parity();
|
|
33079
|
+
}
|
|
33080
|
+
});
|
|
33081
|
+
|
|
32499
33082
|
// src/mcp/tool-gates.ts
|
|
33083
|
+
function isToolAllowedForPlan(registerFnName, plan) {
|
|
33084
|
+
const category = TOOL_CATEGORIES[registerFnName];
|
|
33085
|
+
if (!category) return true;
|
|
33086
|
+
const requiredPlan = PLAN_GATES[category] ?? "free";
|
|
33087
|
+
return PLAN_TIERS[plan] >= PLAN_TIERS[requiredPlan];
|
|
33088
|
+
}
|
|
32500
33089
|
function isChiefOfStaffRole(role) {
|
|
32501
33090
|
const normalized = (role ?? "").trim().toLowerCase();
|
|
32502
33091
|
return normalized === "chief of staff" || normalized === "executive assistant";
|
|
@@ -32513,7 +33102,7 @@ function isToolAllowed(registerFnName) {
|
|
|
32513
33102
|
if (!allowedRoles || allowedRoles.length === 0) return true;
|
|
32514
33103
|
return allowedRoles.includes(role);
|
|
32515
33104
|
}
|
|
32516
|
-
var TOOL_GATES, TOOL_CATEGORIES, CHIEF_OF_STAFF_READ_TOOLS;
|
|
33105
|
+
var TOOL_GATES, TOOL_CATEGORIES, PLAN_TIERS, PLAN_GATES, CHIEF_OF_STAFF_READ_TOOLS;
|
|
32517
33106
|
var init_tool_gates = __esm({
|
|
32518
33107
|
"src/mcp/tool-gates.ts"() {
|
|
32519
33108
|
"use strict";
|
|
@@ -32571,6 +33160,11 @@ var init_tool_gates = __esm({
|
|
|
32571
33160
|
registerGetSessionEvents: "core",
|
|
32572
33161
|
registerGetLastAssistantResponse: "core",
|
|
32573
33162
|
registerCodeContext: "graph-read",
|
|
33163
|
+
// consolidated tools
|
|
33164
|
+
registerDecision: "core",
|
|
33165
|
+
registerSession: "core",
|
|
33166
|
+
registerSupportConsolidated: "core",
|
|
33167
|
+
registerDiagnostics: "admin",
|
|
32574
33168
|
registerListBugReports: "admin",
|
|
32575
33169
|
registerGetBugReport: "admin",
|
|
32576
33170
|
registerTriageBugReport: "admin",
|
|
@@ -32664,6 +33258,30 @@ var init_tool_gates = __esm({
|
|
|
32664
33258
|
registerListGlobalProcedures: "orchestration",
|
|
32665
33259
|
registerDeactivateGlobalProcedure: "orchestration"
|
|
32666
33260
|
};
|
|
33261
|
+
PLAN_TIERS = {
|
|
33262
|
+
free: 0,
|
|
33263
|
+
pro: 1,
|
|
33264
|
+
team: 2,
|
|
33265
|
+
agency: 3,
|
|
33266
|
+
enterprise: 4
|
|
33267
|
+
};
|
|
33268
|
+
PLAN_GATES = {
|
|
33269
|
+
core: "free",
|
|
33270
|
+
tasks: "free",
|
|
33271
|
+
comms: "free",
|
|
33272
|
+
reminders: "free",
|
|
33273
|
+
"graph-read": "free",
|
|
33274
|
+
licensing: "free",
|
|
33275
|
+
// always allow checking/managing own license
|
|
33276
|
+
"graph-write": "pro",
|
|
33277
|
+
wiki: "pro",
|
|
33278
|
+
crm: "pro",
|
|
33279
|
+
"raw-data": "pro",
|
|
33280
|
+
documents: "pro",
|
|
33281
|
+
gateway: "pro",
|
|
33282
|
+
admin: "pro",
|
|
33283
|
+
orchestration: "pro"
|
|
33284
|
+
};
|
|
32667
33285
|
CHIEF_OF_STAFF_READ_TOOLS = /* @__PURE__ */ new Set([
|
|
32668
33286
|
"registerRecallMyMemory",
|
|
32669
33287
|
"registerAskTeamMemory",
|
|
@@ -32689,9 +33307,12 @@ var register_tools_exports = {};
|
|
|
32689
33307
|
__export(register_tools_exports, {
|
|
32690
33308
|
registerAllTools: () => registerAllTools
|
|
32691
33309
|
});
|
|
32692
|
-
function registerAllTools(server) {
|
|
33310
|
+
function registerAllTools(server, license, hasKey) {
|
|
32693
33311
|
const gate = (name, fn) => {
|
|
32694
|
-
if (isToolAllowed(name))
|
|
33312
|
+
if (!isToolAllowed(name)) return;
|
|
33313
|
+
if (hasKey === false && !ALWAYS_ALLOWED.has(name)) return;
|
|
33314
|
+
if (license && !isToolAllowedForPlan(name, license.plan)) return;
|
|
33315
|
+
fn(server);
|
|
32695
33316
|
};
|
|
32696
33317
|
const mcpToolSurface = process.env.EXE_MCP_TOOL_SURFACE ?? "legacy";
|
|
32697
33318
|
const exposeConsolidatedTasks = mcpToolSurface === "both" || mcpToolSurface === "consolidated";
|
|
@@ -32712,6 +33333,14 @@ function registerAllTools(server) {
|
|
|
32712
33333
|
const exposeLegacyGraph = mcpToolSurface !== "consolidated";
|
|
32713
33334
|
const exposeConsolidatedConfig = mcpToolSurface === "both" || mcpToolSurface === "consolidated";
|
|
32714
33335
|
const exposeLegacyConfig = mcpToolSurface !== "consolidated";
|
|
33336
|
+
const exposeConsolidatedDecisions = mcpToolSurface === "both" || mcpToolSurface === "consolidated";
|
|
33337
|
+
const exposeLegacyDecisions = mcpToolSurface !== "consolidated";
|
|
33338
|
+
const exposeConsolidatedSession = mcpToolSurface === "both" || mcpToolSurface === "consolidated";
|
|
33339
|
+
const exposeLegacySession = mcpToolSurface !== "consolidated";
|
|
33340
|
+
const exposeConsolidatedSupport = mcpToolSurface === "both" || mcpToolSurface === "consolidated";
|
|
33341
|
+
const exposeLegacySupport = mcpToolSurface !== "consolidated";
|
|
33342
|
+
const exposeConsolidatedDiagnostics = mcpToolSurface === "both" || mcpToolSurface === "consolidated";
|
|
33343
|
+
const exposeLegacyDiagnostics = mcpToolSurface !== "consolidated";
|
|
32715
33344
|
if (exposeConsolidatedMemory) {
|
|
32716
33345
|
gate("registerMemory", registerMemory);
|
|
32717
33346
|
}
|
|
@@ -32825,23 +33454,43 @@ function registerAllTools(server) {
|
|
|
32825
33454
|
if (exposeLegacyMemory) {
|
|
32826
33455
|
gate("registerSearchEverything", registerSearchEverything);
|
|
32827
33456
|
}
|
|
32828
|
-
|
|
32829
|
-
|
|
32830
|
-
|
|
32831
|
-
|
|
32832
|
-
|
|
32833
|
-
|
|
32834
|
-
|
|
32835
|
-
|
|
32836
|
-
|
|
32837
|
-
|
|
32838
|
-
|
|
32839
|
-
gate("
|
|
32840
|
-
gate("
|
|
32841
|
-
gate("
|
|
32842
|
-
|
|
32843
|
-
|
|
33457
|
+
if (exposeConsolidatedDecisions) {
|
|
33458
|
+
gate("registerDecision", registerDecision);
|
|
33459
|
+
}
|
|
33460
|
+
if (exposeLegacyDecisions) {
|
|
33461
|
+
gate("registerStoreDecision", registerStoreDecision);
|
|
33462
|
+
gate("registerGetDecision", registerGetDecision);
|
|
33463
|
+
}
|
|
33464
|
+
if (exposeConsolidatedSupport) {
|
|
33465
|
+
gate("registerSupportConsolidated", registerSupportConsolidated);
|
|
33466
|
+
}
|
|
33467
|
+
if (exposeLegacySupport) {
|
|
33468
|
+
gate("registerCreateBugReport", registerCreateBugReport);
|
|
33469
|
+
gate("registerCreateFeatureRequest", registerCreateFeatureRequest);
|
|
33470
|
+
gate("registerSupportTools", registerSupportTools);
|
|
33471
|
+
if (process.env.ASKEXE_SUPPORT_ADMIN_TOKEN || process.env.EXE_SUPPORT_ADMIN_TOKEN) {
|
|
33472
|
+
gate("registerListBugReports", registerListBugReports);
|
|
33473
|
+
gate("registerGetBugReport", registerGetBugReport);
|
|
33474
|
+
gate("registerTriageBugReport", registerTriageBugReport);
|
|
33475
|
+
gate("registerListFeatureRequests", registerListFeatureRequests);
|
|
33476
|
+
gate("registerGetFeatureRequest", registerGetFeatureRequest);
|
|
33477
|
+
gate("registerTriageFeatureRequest", registerTriageFeatureRequest);
|
|
33478
|
+
}
|
|
33479
|
+
}
|
|
33480
|
+
if (exposeConsolidatedDiagnostics) {
|
|
33481
|
+
gate("registerDiagnostics", registerDiagnostics);
|
|
33482
|
+
}
|
|
33483
|
+
if (exposeLegacyDiagnostics) {
|
|
33484
|
+
gate("registerCliParityTools", registerCliParityTools);
|
|
33485
|
+
}
|
|
33486
|
+
if (exposeConsolidatedSession) {
|
|
33487
|
+
gate("registerSession", registerSession2);
|
|
32844
33488
|
}
|
|
33489
|
+
if (exposeLegacySession) {
|
|
33490
|
+
gate("registerGetSessionEvents", registerGetSessionEvents);
|
|
33491
|
+
gate("registerGetLastAssistantResponse", registerGetLastAssistantResponse);
|
|
33492
|
+
}
|
|
33493
|
+
gate("registerCodeContext", registerCodeContext);
|
|
32845
33494
|
if (exposeLegacyConfig) {
|
|
32846
33495
|
gate("registerGetAgentSpend", registerGetAgentSpend);
|
|
32847
33496
|
}
|
|
@@ -32890,6 +33539,7 @@ function registerAllTools(server) {
|
|
|
32890
33539
|
gate("registerCompanyActions", registerCompanyActions);
|
|
32891
33540
|
}
|
|
32892
33541
|
}
|
|
33542
|
+
var ALWAYS_ALLOWED;
|
|
32893
33543
|
var init_register_tools = __esm({
|
|
32894
33544
|
"src/mcp/register-tools.ts"() {
|
|
32895
33545
|
"use strict";
|
|
@@ -32989,7 +33639,16 @@ var init_register_tools = __esm({
|
|
|
32989
33639
|
init_get_session_events();
|
|
32990
33640
|
init_code_context();
|
|
32991
33641
|
init_support_inbox();
|
|
33642
|
+
init_decision();
|
|
33643
|
+
init_session();
|
|
33644
|
+
init_support_consolidated();
|
|
33645
|
+
init_diagnostics();
|
|
32992
33646
|
init_tool_gates();
|
|
33647
|
+
ALWAYS_ALLOWED = /* @__PURE__ */ new Set([
|
|
33648
|
+
"registerMcpPing",
|
|
33649
|
+
"registerGetLicenseStatus",
|
|
33650
|
+
"registerActivateLicense"
|
|
33651
|
+
]);
|
|
32993
33652
|
}
|
|
32994
33653
|
});
|
|
32995
33654
|
|
|
@@ -33849,6 +34508,14 @@ function createWsClient(config2, handlers) {
|
|
|
33849
34508
|
let currentProjects = [];
|
|
33850
34509
|
function connect() {
|
|
33851
34510
|
if (closed) return;
|
|
34511
|
+
if (ws) {
|
|
34512
|
+
try {
|
|
34513
|
+
ws.onopen = ws.onmessage = ws.onclose = ws.onerror = null;
|
|
34514
|
+
ws.close();
|
|
34515
|
+
} catch {
|
|
34516
|
+
}
|
|
34517
|
+
ws = null;
|
|
34518
|
+
}
|
|
33852
34519
|
try {
|
|
33853
34520
|
const url = `${config2.endpoint}?org=${config2.orgId}`;
|
|
33854
34521
|
ws = new WebSocket(url, {
|
|
@@ -34007,7 +34674,7 @@ import os24 from "os";
|
|
|
34007
34674
|
import net2 from "net";
|
|
34008
34675
|
import { createServer as createHttpServer } from "http";
|
|
34009
34676
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
34010
|
-
import { writeFileSync as writeFileSync29, unlinkSync as unlinkSync15, mkdirSync as mkdirSync25, existsSync as existsSync47, readFileSync as readFileSync41, chmodSync as
|
|
34677
|
+
import { writeFileSync as writeFileSync29, unlinkSync as unlinkSync15, mkdirSync as mkdirSync25, existsSync as existsSync47, readFileSync as readFileSync41, chmodSync as chmodSync3 } from "fs";
|
|
34011
34678
|
import path62 from "path";
|
|
34012
34679
|
|
|
34013
34680
|
// src/lib/orchestration-metrics.ts
|
|
@@ -34091,6 +34758,7 @@ var _context = null;
|
|
|
34091
34758
|
var _model = null;
|
|
34092
34759
|
var _llama = null;
|
|
34093
34760
|
var _shuttingDown = false;
|
|
34761
|
+
var _mcpHttpReady = Promise.resolve();
|
|
34094
34762
|
var _daemonToken = "";
|
|
34095
34763
|
var MAX_QUEUE_SIZE = 1e3;
|
|
34096
34764
|
var highQueue = [];
|
|
@@ -34140,6 +34808,13 @@ async function processQueue() {
|
|
|
34140
34808
|
if (entry.socket.destroyed) continue;
|
|
34141
34809
|
try {
|
|
34142
34810
|
const vectors = [];
|
|
34811
|
+
if (!_context) {
|
|
34812
|
+
sendResponse(entry.socket, {
|
|
34813
|
+
id: entry.request.id,
|
|
34814
|
+
error: "Model not loaded yet \u2014 embeddings unavailable"
|
|
34815
|
+
});
|
|
34816
|
+
continue;
|
|
34817
|
+
}
|
|
34143
34818
|
for (const text3 of entry.request.texts) {
|
|
34144
34819
|
const embedding = await _context.getEmbeddingFor(text3);
|
|
34145
34820
|
const vector = Array.from(embedding.vector);
|
|
@@ -34555,7 +35230,7 @@ function startMemoryQueueDrain() {
|
|
|
34555
35230
|
function startServer() {
|
|
34556
35231
|
mkdirSync25(path62.dirname(SOCKET_PATH2), { recursive: true });
|
|
34557
35232
|
try {
|
|
34558
|
-
|
|
35233
|
+
chmodSync3(path62.dirname(SOCKET_PATH2), 448);
|
|
34559
35234
|
} catch {
|
|
34560
35235
|
}
|
|
34561
35236
|
_daemonToken = ensureDaemonToken(process.env[DAEMON_TOKEN_ENV2] ?? null);
|
|
@@ -34677,12 +35352,12 @@ function startServer() {
|
|
|
34677
35352
|
process.stderr.write(`[exed] Listening on ${SOCKET_PATH2}
|
|
34678
35353
|
`);
|
|
34679
35354
|
try {
|
|
34680
|
-
|
|
35355
|
+
chmodSync3(SOCKET_PATH2, 384);
|
|
34681
35356
|
} catch {
|
|
34682
35357
|
}
|
|
34683
35358
|
checkIdle();
|
|
34684
35359
|
});
|
|
34685
|
-
|
|
35360
|
+
_mcpHttpReady = startMcpHttpServer();
|
|
34686
35361
|
}
|
|
34687
35362
|
async function startMcpHttpServer() {
|
|
34688
35363
|
process.stderr.write("[exed] MCP HTTP: starting setup...\n");
|
|
@@ -34719,6 +35394,15 @@ async function startMcpHttpServer() {
|
|
|
34719
35394
|
for (const [sid, lastSeen] of sessionLastSeen.entries()) {
|
|
34720
35395
|
if (now2 - lastSeen > MCP_SESSION_TTL_MS) closeMcpSession2(sid, "session_expired");
|
|
34721
35396
|
}
|
|
35397
|
+
const rss = process.memoryUsage.rss();
|
|
35398
|
+
if (rss > RSS_RESTART_BYTES * 0.8 && transports.size > 1) {
|
|
35399
|
+
const sorted = [...sessionLastSeen.entries()].sort((a, b) => a[1] - b[1]);
|
|
35400
|
+
for (let i = 0; i < sorted.length - 1; i++) {
|
|
35401
|
+
closeMcpSession2(sorted[i][0], "rss_pressure_evict");
|
|
35402
|
+
process.stderr.write(`[exed] RSS pressure eviction: closed session ${sorted[i][0].slice(0, 8)} (${transports.size} remaining)
|
|
35403
|
+
`);
|
|
35404
|
+
}
|
|
35405
|
+
}
|
|
34722
35406
|
}, getJsonRpcId2 = function(body) {
|
|
34723
35407
|
if (body && typeof body === "object" && !Array.isArray(body) && "id" in body) {
|
|
34724
35408
|
const id = body.id;
|
|
@@ -34735,11 +35419,13 @@ async function startMcpHttpServer() {
|
|
|
34735
35419
|
recordMcpHttpEvent({ level: "warn", message, status: status2, ...extra });
|
|
34736
35420
|
};
|
|
34737
35421
|
var parseDurationMs = parseDurationMs2, closeMcpSession = closeMcpSession2, sweepStaleMcpSessions = sweepStaleMcpSessions2, getJsonRpcId = getJsonRpcId2, sendJsonRpcError = sendJsonRpcError2;
|
|
35422
|
+
process.stderr.write("[exed] MCP HTTP: importing SDK modules...\n");
|
|
34738
35423
|
const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
|
|
34739
35424
|
const { StreamableHTTPServerTransport } = await import("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
34740
35425
|
const { isInitializeRequest } = await import("@modelcontextprotocol/sdk/types.js");
|
|
34741
35426
|
const { registerAllTools: registerAllTools2 } = await Promise.resolve().then(() => (init_register_tools(), register_tools_exports));
|
|
34742
35427
|
const { runWithAgent: runWithAgent2 } = await Promise.resolve().then(() => (init_agent_context(), agent_context_exports));
|
|
35428
|
+
process.stderr.write("[exed] MCP HTTP: SDK imports done, initializing DB...\n");
|
|
34743
35429
|
const dbReady = await ensureStoreForPolling();
|
|
34744
35430
|
if (!dbReady) {
|
|
34745
35431
|
process.stderr.write(
|
|
@@ -34748,9 +35434,21 @@ async function startMcpHttpServer() {
|
|
|
34748
35434
|
return;
|
|
34749
35435
|
}
|
|
34750
35436
|
process.stderr.write("[exed] MCP HTTP: DB ready\n");
|
|
35437
|
+
const { initLicenseGate: initLicenseGate2, getCachedLicenseGate: getCachedLicenseGate2 } = await Promise.resolve().then(() => (init_license_gate(), license_gate_exports));
|
|
35438
|
+
const gateResult = await initLicenseGate2();
|
|
35439
|
+
if (!gateResult.hasKey) {
|
|
35440
|
+
process.stderr.write(
|
|
35441
|
+
"[exed] MCP HTTP: No license key found \u2014 tools restricted to diagnostics only.\n"
|
|
35442
|
+
);
|
|
35443
|
+
} else if (gateResult.license) {
|
|
35444
|
+
process.stderr.write(
|
|
35445
|
+
`[exed] MCP HTTP: License validated \u2014 plan=${gateResult.license.plan}
|
|
35446
|
+
`
|
|
35447
|
+
);
|
|
35448
|
+
}
|
|
34751
35449
|
const transports = /* @__PURE__ */ new Map();
|
|
34752
35450
|
const MCP_HTTP_PORT = parseInt(process.env.EXE_MCP_PORT || "48739", 10);
|
|
34753
|
-
const MCP_SESSION_TTL_MS = parseDurationMs2(process.env.EXE_MCP_SESSION_TTL_MS,
|
|
35451
|
+
const MCP_SESSION_TTL_MS = parseDurationMs2(process.env.EXE_MCP_SESSION_TTL_MS, 30 * 60 * 1e3, { allowZero: true });
|
|
34754
35452
|
const MCP_SESSION_SWEEP_MS = parseDurationMs2(process.env.EXE_MCP_SESSION_SWEEP_MS, 60 * 1e3);
|
|
34755
35453
|
const sessionLastSeen = /* @__PURE__ */ new Map();
|
|
34756
35454
|
const sessionDetails = /* @__PURE__ */ new Map();
|
|
@@ -34767,16 +35465,14 @@ async function startMcpHttpServer() {
|
|
|
34767
35465
|
return;
|
|
34768
35466
|
}
|
|
34769
35467
|
const url = new URL(req.url || "/", `http://127.0.0.1:${MCP_HTTP_PORT}`);
|
|
34770
|
-
|
|
34771
|
-
|
|
34772
|
-
|
|
34773
|
-
method: req.method,
|
|
34774
|
-
path: url.pathname
|
|
34775
|
-
});
|
|
35468
|
+
if (url.pathname !== "/mcp") {
|
|
35469
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
35470
|
+
res.end("Not Found");
|
|
34776
35471
|
return;
|
|
34777
35472
|
}
|
|
34778
|
-
|
|
34779
|
-
|
|
35473
|
+
const authHeader = req.headers.authorization;
|
|
35474
|
+
if (authHeader && authHeader !== `Bearer ${_daemonToken}`) {
|
|
35475
|
+
sendJsonRpcError2(res, 401, "Unauthorized: invalid daemon token", "unknown", {
|
|
34780
35476
|
method: req.method,
|
|
34781
35477
|
path: url.pathname
|
|
34782
35478
|
});
|
|
@@ -34837,7 +35533,10 @@ async function startMcpHttpServer() {
|
|
|
34837
35533
|
if (sid) closeMcpSession2(sid, "session_closed");
|
|
34838
35534
|
};
|
|
34839
35535
|
const sessionMcp = new McpServer({ name: "exe-os", version: "1.3.0" });
|
|
34840
|
-
|
|
35536
|
+
const gateState = getCachedLicenseGate2();
|
|
35537
|
+
const { wrapServerWithTelemetry: wrapServerWithTelemetry2 } = await Promise.resolve().then(() => (init_tool_telemetry(), tool_telemetry_exports));
|
|
35538
|
+
const wrappedMcp = wrapServerWithTelemetry2(sessionMcp);
|
|
35539
|
+
registerAllTools2(wrappedMcp, gateState.license, gateState.hasKey);
|
|
34841
35540
|
await sessionMcp.connect(transport);
|
|
34842
35541
|
} else {
|
|
34843
35542
|
const message = sessionId ? "Bad Request: MCP session is stale or unknown; reconnect MCP client" : "Bad Request: missing MCP session; initialize before tool calls";
|
|
@@ -34910,8 +35609,9 @@ async function startMcpHttpServer() {
|
|
|
34910
35609
|
}
|
|
34911
35610
|
}
|
|
34912
35611
|
});
|
|
34913
|
-
|
|
34914
|
-
|
|
35612
|
+
const MCP_HTTP_HOST = process.env.EXE_MCP_HOST || process.env.EXED_HOST || "127.0.0.1";
|
|
35613
|
+
httpServer.listen(MCP_HTTP_PORT, MCP_HTTP_HOST, () => {
|
|
35614
|
+
process.stderr.write(`[exed] MCP HTTP listening on ${MCP_HTTP_HOST}:${MCP_HTTP_PORT}
|
|
34915
35615
|
`);
|
|
34916
35616
|
recordMcpHttpEvent({
|
|
34917
35617
|
level: "info",
|
|
@@ -35481,8 +36181,8 @@ function startAutoWake() {
|
|
|
35481
36181
|
`);
|
|
35482
36182
|
}
|
|
35483
36183
|
var TOTAL_MEM_GB = os24.totalmem() / 1024 ** 3;
|
|
35484
|
-
var RSS_WARN_BYTES = Number(process.env.EXE_RSS_WARN_MB) * 1024 * 1024 || (TOTAL_MEM_GB >= 64 ? 6 * 1024 ** 3 : TOTAL_MEM_GB >= 32 ? 4 * 1024 ** 3 : 1024 ** 3);
|
|
35485
|
-
var RSS_RESTART_BYTES = Number(process.env.EXE_RSS_RESTART_MB) * 1024 * 1024 || (TOTAL_MEM_GB >= 64 ? 8 * 1024 ** 3 : TOTAL_MEM_GB >= 32 ? 6 * 1024 ** 3 :
|
|
36184
|
+
var RSS_WARN_BYTES = Number(process.env.EXE_RSS_WARN_MB) * 1024 * 1024 || (TOTAL_MEM_GB >= 64 ? 6 * 1024 ** 3 : TOTAL_MEM_GB >= 32 ? 4 * 1024 ** 3 : TOTAL_MEM_GB >= 16 ? 2.5 * 1024 ** 3 : 1.5 * 1024 ** 3);
|
|
36185
|
+
var RSS_RESTART_BYTES = Number(process.env.EXE_RSS_RESTART_MB) * 1024 * 1024 || (TOTAL_MEM_GB >= 64 ? 8 * 1024 ** 3 : TOTAL_MEM_GB >= 32 ? 6 * 1024 ** 3 : TOTAL_MEM_GB >= 16 ? 4 * 1024 ** 3 : 3 * 1024 ** 3);
|
|
35486
36186
|
var RSS_CHECK_INTERVAL_MS = 30 * 1e3;
|
|
35487
36187
|
var _rssWarned = false;
|
|
35488
36188
|
var TASK_ENFORCEMENT_INTERVAL_MS2 = 6e4;
|
|
@@ -35511,7 +36211,8 @@ function startTaskEnforcementScanner() {
|
|
|
35511
36211
|
);
|
|
35512
36212
|
}
|
|
35513
36213
|
};
|
|
35514
|
-
setInterval(tick, TASK_ENFORCEMENT_INTERVAL_MS2);
|
|
36214
|
+
const timer = setInterval(tick, TASK_ENFORCEMENT_INTERVAL_MS2);
|
|
36215
|
+
timer.unref();
|
|
35515
36216
|
process.stderr.write(`[exed] Task enforcement scanner started (${TASK_ENFORCEMENT_INTERVAL_MS2 / 1e3}s interval)
|
|
35516
36217
|
`);
|
|
35517
36218
|
}
|
|
@@ -35595,6 +36296,18 @@ function handleSignalShutdown() {
|
|
|
35595
36296
|
}
|
|
35596
36297
|
process.on("SIGINT", handleSignalShutdown);
|
|
35597
36298
|
process.on("SIGTERM", handleSignalShutdown);
|
|
36299
|
+
process.on("unhandledRejection", (reason) => {
|
|
36300
|
+
process.stderr.write(
|
|
36301
|
+
`[exed] Unhandled rejection (caught): ${reason instanceof Error ? reason.stack ?? reason.message : String(reason)}
|
|
36302
|
+
`
|
|
36303
|
+
);
|
|
36304
|
+
});
|
|
36305
|
+
process.on("uncaughtException", (err) => {
|
|
36306
|
+
process.stderr.write(
|
|
36307
|
+
`[exed] Uncaught exception (caught): ${err.stack ?? err.message}
|
|
36308
|
+
`
|
|
36309
|
+
);
|
|
36310
|
+
});
|
|
35598
36311
|
function checkExistingDaemon() {
|
|
35599
36312
|
try {
|
|
35600
36313
|
if (!existsSync47(PID_PATH4)) return false;
|
|
@@ -35694,14 +36407,20 @@ if (checkExistingDaemon()) {
|
|
|
35694
36407
|
}
|
|
35695
36408
|
writeFileSync29(PID_PATH4, String(process.pid));
|
|
35696
36409
|
try {
|
|
35697
|
-
|
|
36410
|
+
chmodSync3(PID_PATH4, 384);
|
|
35698
36411
|
} catch {
|
|
35699
36412
|
}
|
|
35700
36413
|
process.env.EXE_IS_DAEMON = "1";
|
|
35701
36414
|
try {
|
|
35702
36415
|
initMetrics();
|
|
35703
|
-
await loadModel();
|
|
35704
36416
|
startServer();
|
|
36417
|
+
await _mcpHttpReady;
|
|
36418
|
+
loadModel().catch((err) => {
|
|
36419
|
+
process.stderr.write(
|
|
36420
|
+
`[exed] Background model load failed: ${err instanceof Error ? err.message : String(err)}
|
|
36421
|
+
`
|
|
36422
|
+
);
|
|
36423
|
+
});
|
|
35705
36424
|
startReviewPolling();
|
|
35706
36425
|
startSessionTTL();
|
|
35707
36426
|
startIdleKill();
|
|
@@ -35721,6 +36440,9 @@ try {
|
|
|
35721
36440
|
startRssWatchdog();
|
|
35722
36441
|
startBackgroundJobGuardrails();
|
|
35723
36442
|
startTaskEnforcementScanner();
|
|
36443
|
+
const { startToolTelemetryFlush: startToolTelemetryFlush2 } = await Promise.resolve().then(() => (init_tool_telemetry(), tool_telemetry_exports));
|
|
36444
|
+
startToolTelemetryFlush2();
|
|
36445
|
+
process.stderr.write("[exed] Tool telemetry started (flush every 5m)\n");
|
|
35724
36446
|
const { startProjectionWorker: startProjectionWorker2 } = await Promise.resolve().then(() => (init_projection_worker(), projection_worker_exports));
|
|
35725
36447
|
startProjectionWorker2();
|
|
35726
36448
|
try {
|