@jagilber-org/index-server 1.22.0 → 1.26.1
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/CHANGELOG.md +87 -2
- package/CODE_OF_CONDUCT.md +2 -0
- package/CONTRIBUTING.md +32 -2
- package/README.md +83 -20
- package/SECURITY.md +17 -5
- package/dist/config/dashboardConfig.d.ts +3 -0
- package/dist/config/dashboardConfig.js +3 -0
- package/dist/config/defaultValues.d.ts +1 -1
- package/dist/config/defaultValues.js +1 -1
- package/dist/config/featureConfig.d.ts +2 -0
- package/dist/config/featureConfig.js +6 -1
- package/dist/config/runtimeConfig.d.ts +1 -1
- package/dist/config/runtimeConfig.js +8 -9
- package/dist/dashboard/client/admin.html +173 -54
- package/dist/dashboard/client/css/admin.css +151 -0
- package/dist/dashboard/client/js/admin.auth.js +25 -11
- package/dist/dashboard/client/js/admin.config.js +1 -1
- package/dist/dashboard/client/js/admin.feedback.js +328 -0
- package/dist/dashboard/client/js/admin.graph.js +120 -18
- package/dist/dashboard/client/js/admin.instructions.js +27 -13
- package/dist/dashboard/client/js/admin.logs.js +1 -5
- package/dist/dashboard/client/js/admin.maintenance.js +53 -8
- package/dist/dashboard/client/js/admin.messaging.js +1 -4
- package/dist/dashboard/client/js/admin.overview.js +5 -1
- package/dist/dashboard/client/js/admin.sessions.js +1 -1
- package/dist/dashboard/client/js/admin.utils.js +43 -1
- package/dist/dashboard/client/js/mermaid.min.js +813 -537
- package/dist/dashboard/export/DataExporter.js +2 -1
- package/dist/dashboard/server/AdminPanel.d.ts +3 -0
- package/dist/dashboard/server/AdminPanel.js +132 -35
- package/dist/dashboard/server/ApiRoutes.js +40 -9
- package/dist/dashboard/server/DashboardServer.js +1 -1
- package/dist/dashboard/server/FileMetricsStorage.d.ts +19 -0
- package/dist/dashboard/server/FileMetricsStorage.js +52 -5
- package/dist/dashboard/server/HttpTransport.js +6 -0
- package/dist/dashboard/server/InstanceManager.js +7 -2
- package/dist/dashboard/server/KnowledgeStore.js +7 -2
- package/dist/dashboard/server/MetricsCollector.d.ts +16 -0
- package/dist/dashboard/server/MetricsCollector.js +113 -17
- package/dist/dashboard/server/legacyDashboardHtml.js +7 -2
- package/dist/dashboard/server/middleware/ensureLoadedMiddleware.d.ts +1 -1
- package/dist/dashboard/server/middleware/ensureLoadedMiddleware.js +8 -3
- package/dist/dashboard/server/routes/admin.feedback.routes.d.ts +15 -0
- package/dist/dashboard/server/routes/admin.feedback.routes.js +188 -0
- package/dist/dashboard/server/routes/admin.routes.js +35 -27
- package/dist/dashboard/server/routes/alerts.routes.js +4 -3
- package/dist/dashboard/server/routes/api.feedback.routes.js +2 -1
- package/dist/dashboard/server/routes/api.usage.routes.js +8 -7
- package/dist/dashboard/server/routes/embeddings.routes.d.ts +2 -1
- package/dist/dashboard/server/routes/embeddings.routes.js +18 -9
- package/dist/dashboard/server/routes/graph.routes.js +10 -13
- package/dist/dashboard/server/routes/index.d.ts +1 -0
- package/dist/dashboard/server/routes/index.js +74 -39
- package/dist/dashboard/server/routes/instances.routes.js +2 -1
- package/dist/dashboard/server/routes/instructions.routes.js +46 -27
- package/dist/dashboard/server/routes/knowledge.routes.js +4 -3
- package/dist/dashboard/server/routes/logs.routes.js +5 -4
- package/dist/dashboard/server/routes/messaging.routes.js +15 -14
- package/dist/dashboard/server/routes/metrics.routes.js +14 -13
- package/dist/dashboard/server/routes/scripts.routes.js +6 -3
- package/dist/dashboard/server/routes/status.routes.js +25 -6
- package/dist/dashboard/server/routes/synthetic.routes.js +3 -2
- package/dist/dashboard/server/routes/usage.routes.js +2 -1
- package/dist/dashboard/server/utils/escapeHtml.d.ts +1 -0
- package/dist/dashboard/server/utils/escapeHtml.js +11 -0
- package/dist/dashboard/server/utils/pathContainment.d.ts +1 -0
- package/dist/dashboard/server/utils/pathContainment.js +15 -0
- package/dist/dashboard/server/wsInit.js +2 -2
- package/dist/lib/mcpStdioLogging.d.ts +165 -0
- package/dist/lib/mcpStdioLogging.js +287 -0
- package/dist/schemas/index.d.ts +37 -2
- package/dist/schemas/index.js +27 -3
- package/dist/server/backgroundServicesStartup.d.ts +7 -1
- package/dist/server/backgroundServicesStartup.js +25 -8
- package/dist/server/certInit.d.ts +97 -0
- package/dist/server/certInit.js +359 -0
- package/dist/server/certInit.types.d.ts +92 -0
- package/dist/server/certInit.types.js +34 -0
- package/dist/server/handshake/fallbackFrames.d.ts +31 -0
- package/dist/server/handshake/fallbackFrames.js +38 -0
- package/dist/server/handshake/initializeDetector.d.ts +31 -0
- package/dist/server/handshake/initializeDetector.js +88 -0
- package/dist/server/handshake/protocol.d.ts +15 -0
- package/dist/server/handshake/protocol.js +37 -0
- package/dist/server/handshake/readyEmitter.d.ts +6 -0
- package/dist/server/handshake/readyEmitter.js +88 -0
- package/dist/server/handshake/safetyFallbacks.d.ts +1 -0
- package/dist/server/handshake/safetyFallbacks.js +134 -0
- package/dist/server/handshake/stdinSniffer.d.ts +1 -0
- package/dist/server/handshake/stdinSniffer.js +260 -0
- package/dist/server/handshake/tracing.d.ts +16 -0
- package/dist/server/handshake/tracing.js +95 -0
- package/dist/server/handshakeManager.d.ts +23 -23
- package/dist/server/handshakeManager.js +36 -466
- package/dist/server/index-server.d.ts +23 -0
- package/dist/server/index-server.js +194 -9
- package/dist/server/mcpReadOnlySurfaces.d.ts +44 -0
- package/dist/server/mcpReadOnlySurfaces.js +297 -0
- package/dist/server/sdkServer.js +69 -7
- package/dist/server/transport.d.ts +5 -6
- package/dist/server/transport.js +46 -64
- package/dist/server/transportFactory.d.ts +3 -9
- package/dist/server/transportFactory.js +18 -380
- package/dist/services/atomicFs.d.ts +3 -0
- package/dist/services/atomicFs.js +171 -13
- package/dist/services/auditLog.d.ts +17 -2
- package/dist/services/auditLog.js +75 -14
- package/dist/services/bootstrapGating.js +1 -1
- package/dist/services/categoryRules.d.ts +10 -0
- package/dist/services/categoryRules.js +17 -0
- package/dist/services/classificationService.js +7 -5
- package/dist/services/embeddingService.d.ts +27 -11
- package/dist/services/embeddingService.js +51 -14
- package/dist/services/feedbackStorage.d.ts +39 -0
- package/dist/services/feedbackStorage.js +88 -0
- package/dist/services/handlers/instructions.add.js +429 -317
- package/dist/services/handlers/instructions.groom.js +128 -31
- package/dist/services/handlers/instructions.import.js +56 -23
- package/dist/services/handlers/instructions.patch.js +43 -32
- package/dist/services/handlers/instructions.query.js +20 -29
- package/dist/services/handlers/instructions.shared.d.ts +54 -0
- package/dist/services/handlers/instructions.shared.js +126 -1
- package/dist/services/handlers.activation.js +83 -81
- package/dist/services/handlers.dashboardConfig.d.ts +2 -2
- package/dist/services/handlers.dashboardConfig.js +1 -2
- package/dist/services/handlers.diagnostics.js +75 -54
- package/dist/services/handlers.feedback.d.ts +4 -11
- package/dist/services/handlers.feedback.js +11 -333
- package/dist/services/handlers.gates.js +69 -37
- package/dist/services/handlers.graph.js +2 -2
- package/dist/services/handlers.help.js +2 -2
- package/dist/services/handlers.instructionSchema.js +4 -2
- package/dist/services/handlers.integrity.js +42 -22
- package/dist/services/handlers.messaging.js +1 -1
- package/dist/services/handlers.metrics.js +51 -6
- package/dist/services/handlers.prompt.js +10 -2
- package/dist/services/handlers.search.js +94 -44
- package/dist/services/handlers.trace.js +1 -1
- package/dist/services/handlers.usage.js +38 -7
- package/dist/services/indexContext.d.ts +21 -1
- package/dist/services/indexContext.js +267 -82
- package/dist/services/indexLoader.d.ts +1 -0
- package/dist/services/indexLoader.js +28 -8
- package/dist/services/instructionRecordValidation.d.ts +39 -0
- package/dist/services/instructionRecordValidation.js +388 -0
- package/dist/services/instructions.dispatcher.js +4 -4
- package/dist/services/loaderSchemaValidator.d.ts +15 -0
- package/dist/services/loaderSchemaValidator.js +69 -0
- package/dist/services/logger.js +11 -2
- package/dist/services/mcpLogBridge.d.ts +49 -0
- package/dist/services/mcpLogBridge.js +83 -0
- package/dist/services/ownershipService.js +18 -8
- package/dist/services/performanceBaseline.js +23 -22
- package/dist/services/promptReviewService.d.ts +3 -1
- package/dist/services/promptReviewService.js +41 -13
- package/dist/services/regexSafety.d.ts +6 -0
- package/dist/services/regexSafety.js +46 -0
- package/dist/services/seedBootstrap.js +4 -4
- package/dist/services/storage/factory.d.ts +14 -1
- package/dist/services/storage/factory.js +61 -1
- package/dist/services/storage/jsonEmbeddingStore.d.ts +15 -0
- package/dist/services/storage/jsonEmbeddingStore.js +83 -0
- package/dist/services/storage/jsonFileStore.d.ts +3 -1
- package/dist/services/storage/jsonFileStore.js +8 -6
- package/dist/services/storage/migrationEngine.d.ts +13 -0
- package/dist/services/storage/migrationEngine.js +31 -0
- package/dist/services/storage/sqliteEmbeddingStore.d.ts +30 -0
- package/dist/services/storage/sqliteEmbeddingStore.js +222 -0
- package/dist/services/storage/sqliteStore.d.ts +3 -1
- package/dist/services/storage/sqliteStore.js +2 -2
- package/dist/services/storage/types.d.ts +48 -1
- package/dist/services/toolRegistry.js +77 -67
- package/dist/services/toolRegistry.zod.js +89 -86
- package/dist/services/tracing.js +5 -4
- package/dist/utils/envUtils.d.ts +4 -0
- package/dist/utils/envUtils.js +7 -0
- package/dist/utils/memoryMonitor.js +11 -10
- package/package.json +11 -4
- package/schemas/instruction.schema.json +38 -1
- package/scripts/copy-dashboard-assets.mjs +1 -1
- package/scripts/dist/README.md +1 -1
- package/scripts/setup-wizard.mjs +781 -0
- package/server.json +1 -0
- package/dist/externalClientLib.d.ts +0 -1
- package/dist/externalClientLib.js +0 -2
- package/dist/portableClientWrapper.d.ts +0 -1
- package/dist/portableClientWrapper.js +0 -2
- package/dist/services/indexingService.d.ts +0 -1
- package/dist/services/indexingService.js +0 -2
package/dist/server/sdkServer.js
CHANGED
|
@@ -20,8 +20,10 @@ require("../services/toolHandlers");
|
|
|
20
20
|
const registry_1 = require("./registry");
|
|
21
21
|
const zod_1 = require("zod");
|
|
22
22
|
const runtimeConfig_1 = require("../config/runtimeConfig");
|
|
23
|
+
const mcpLogBridge_1 = require("../services/mcpLogBridge");
|
|
23
24
|
const handshakeManager_1 = require("./handshakeManager");
|
|
24
25
|
const transportFactory_1 = require("./transportFactory");
|
|
26
|
+
const mcpReadOnlySurfaces_1 = require("./mcpReadOnlySurfaces");
|
|
25
27
|
// ESM dynamic import used below for SDK modules.
|
|
26
28
|
// We'll lazy-load ESM exports via dynamic import when starting.
|
|
27
29
|
let StdioServerTransport;
|
|
@@ -50,8 +52,15 @@ function createSdkServer(ServerClass) {
|
|
|
50
52
|
}
|
|
51
53
|
catch { /* ignore */ }
|
|
52
54
|
}
|
|
53
|
-
const
|
|
55
|
+
const serverCapabilities = {
|
|
56
|
+
tools: { listChanged: true },
|
|
57
|
+
logging: {},
|
|
58
|
+
...(0, mcpReadOnlySurfaces_1.getReadOnlySurfaceCapabilities)(),
|
|
59
|
+
};
|
|
60
|
+
const server = new ServerClass({ name: 'index', version }, { capabilities: serverCapabilities });
|
|
54
61
|
server.__declaredVersion = version;
|
|
62
|
+
// Register server with the MCP log bridge (activated later after ready)
|
|
63
|
+
(0, mcpLogBridge_1.registerMcpServer)(server);
|
|
55
64
|
// Never emit tools/list_changed before ready. Wrap sendToolListChanged to enforce ordering.
|
|
56
65
|
try {
|
|
57
66
|
const origSendToolListChanged = server.sendToolListChanged?.bind(server);
|
|
@@ -102,14 +111,31 @@ function createSdkServer(ServerClass) {
|
|
|
102
111
|
const result = {
|
|
103
112
|
protocolVersion: negotiated,
|
|
104
113
|
serverInfo: { name: 'index', version: versionDeclared },
|
|
105
|
-
capabilities:
|
|
106
|
-
instructions: 'Use initialize -> tools/list -> tools/call { name, arguments }. Health: tools/call health_check. Metrics: tools/call metrics_snapshot. Ping: ping.'
|
|
114
|
+
capabilities: serverCapabilities,
|
|
115
|
+
instructions: 'Use initialize -> tools/list -> tools/call { name, arguments }. Prompts: prompts/list and prompts/get. Resources: resources/list and resources/read. Health: tools/call health_check. Metrics: tools/call metrics_snapshot. Ping: ping.'
|
|
107
116
|
};
|
|
108
117
|
(0, handshakeManager_1.initFrameLog)('handler_return', { negotiated });
|
|
118
|
+
setImmediate(() => {
|
|
119
|
+
try {
|
|
120
|
+
server.__initResponseSent = true;
|
|
121
|
+
(0, handshakeManager_1.initFrameLog)('ready_emit_scheduled', { reason: 'initialize-handler' });
|
|
122
|
+
(0, handshakeManager_1.emitReadyGlobal)(server, 'initialize-handler');
|
|
123
|
+
}
|
|
124
|
+
catch { /* ignore */ }
|
|
125
|
+
});
|
|
109
126
|
return result;
|
|
110
127
|
}
|
|
111
|
-
catch {
|
|
112
|
-
|
|
128
|
+
catch (error) {
|
|
129
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
130
|
+
try {
|
|
131
|
+
process.stderr.write(`[startup] initialize_handler_failed ${message}\n`);
|
|
132
|
+
}
|
|
133
|
+
catch { /* ignore */ }
|
|
134
|
+
throw {
|
|
135
|
+
code: -32603,
|
|
136
|
+
message: 'Initialize handler failure',
|
|
137
|
+
data: { message },
|
|
138
|
+
};
|
|
113
139
|
}
|
|
114
140
|
});
|
|
115
141
|
// Legacy internal _oninitialize patch (will not trigger because we intercept initialize directly)
|
|
@@ -122,7 +148,7 @@ function createSdkServer(ServerClass) {
|
|
|
122
148
|
const negotiated = (0, handshakeManager_1.negotiateProtocolVersion)(request?.params?.protocolVersion);
|
|
123
149
|
result.protocolVersion = negotiated;
|
|
124
150
|
if (result && typeof result === 'object' && !('instructions' in result)) {
|
|
125
|
-
result.instructions = 'Use initialize -> tools/list -> tools/call { name, arguments }. Health: tools/call health_check. Metrics: tools/call metrics_snapshot. Ping: ping.';
|
|
151
|
+
result.instructions = 'Use initialize -> tools/list -> tools/call { name, arguments }. Prompts: prompts/list and prompts/get. Resources: resources/list and resources/read. Health: tools/call health_check. Metrics: tools/call metrics_snapshot. Ping: ping.';
|
|
126
152
|
}
|
|
127
153
|
this.__sawInitializeRequest = true;
|
|
128
154
|
}
|
|
@@ -135,6 +161,43 @@ function createSdkServer(ServerClass) {
|
|
|
135
161
|
const registry = (0, toolRegistry_1.getToolRegistry)();
|
|
136
162
|
return { tools: registry.map(r => ({ name: r.name, description: r.description, inputSchema: r.inputSchema })) };
|
|
137
163
|
});
|
|
164
|
+
server.setRequestHandler(requestSchema('prompts/list'), async () => {
|
|
165
|
+
return { prompts: (0, mcpReadOnlySurfaces_1.listReadOnlyPrompts)() };
|
|
166
|
+
});
|
|
167
|
+
server.setRequestHandler(zod_1.z.object({
|
|
168
|
+
jsonrpc: zod_1.z.literal('2.0'),
|
|
169
|
+
id: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]).optional(),
|
|
170
|
+
method: zod_1.z.literal('prompts/get'),
|
|
171
|
+
params: zod_1.z.object({
|
|
172
|
+
_meta: zod_1.z.any().optional(),
|
|
173
|
+
name: zod_1.z.string(),
|
|
174
|
+
arguments: zod_1.z.record(zod_1.z.string()).optional(),
|
|
175
|
+
}),
|
|
176
|
+
}), async (req) => {
|
|
177
|
+
const prompt = (0, mcpReadOnlySurfaces_1.getReadOnlyPrompt)(req.params.name, req.params.arguments);
|
|
178
|
+
if (!prompt) {
|
|
179
|
+
throw { code: -32602, message: `Unknown prompt: ${req.params.name}`, data: { message: `Unknown prompt: ${req.params.name}`, method: 'prompts/get', name: req.params.name } };
|
|
180
|
+
}
|
|
181
|
+
return prompt;
|
|
182
|
+
});
|
|
183
|
+
server.setRequestHandler(requestSchema('resources/list'), async () => {
|
|
184
|
+
return { resources: (0, mcpReadOnlySurfaces_1.listReadOnlyResources)() };
|
|
185
|
+
});
|
|
186
|
+
server.setRequestHandler(zod_1.z.object({
|
|
187
|
+
jsonrpc: zod_1.z.literal('2.0'),
|
|
188
|
+
id: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]).optional(),
|
|
189
|
+
method: zod_1.z.literal('resources/read'),
|
|
190
|
+
params: zod_1.z.object({
|
|
191
|
+
_meta: zod_1.z.any().optional(),
|
|
192
|
+
uri: zod_1.z.string(),
|
|
193
|
+
}),
|
|
194
|
+
}), async (req) => {
|
|
195
|
+
const resource = (0, mcpReadOnlySurfaces_1.readReadOnlyResource)(req.params.uri);
|
|
196
|
+
if (!resource) {
|
|
197
|
+
throw { code: -32602, message: `Unknown resource: ${req.params.uri}`, data: { message: `Unknown resource: ${req.params.uri}`, method: 'resources/read', uri: req.params.uri } };
|
|
198
|
+
}
|
|
199
|
+
return resource;
|
|
200
|
+
});
|
|
138
201
|
// Raw handler for tools/call (MCP style) - returns content array
|
|
139
202
|
server.setRequestHandler(requestSchema('tools/call'), async (req) => {
|
|
140
203
|
const p = req?.params ?? {};
|
|
@@ -254,7 +317,6 @@ async function startSdkServer() {
|
|
|
254
317
|
}
|
|
255
318
|
(0, transportFactory_1.setupKeepalive)();
|
|
256
319
|
(0, handshakeManager_1.setupSafetyFallbacks)(server);
|
|
257
|
-
(0, transportFactory_1.wrapTransportSend)(server, transport);
|
|
258
320
|
return;
|
|
259
321
|
}
|
|
260
322
|
// Secondary path: StdioServerTransport already loaded
|
|
@@ -9,22 +9,21 @@ interface MetricRecord {
|
|
|
9
9
|
*/
|
|
10
10
|
export declare function getMetrics(): Record<string, MetricRecord>;
|
|
11
11
|
/**
|
|
12
|
-
* Register a method handler
|
|
13
|
-
* Unlike the SDK registry, this does not add wrapping (metrics, audit, etc.).
|
|
12
|
+
* Register a transport-exposed method handler via the canonical registry.
|
|
14
13
|
* @param method - JSON-RPC method name
|
|
15
14
|
* @param handler - Handler function invoked with the parsed params
|
|
16
15
|
*/
|
|
17
16
|
export declare function registerHandler<TParams = unknown>(method: string, handler: Handler<TParams>): void;
|
|
18
17
|
/**
|
|
19
|
-
* Return a sorted list of
|
|
18
|
+
* Return a sorted list of transport-exposed method names.
|
|
20
19
|
* @returns Array of method name strings in alphabetical order
|
|
21
20
|
*/
|
|
22
21
|
export declare function listRegisteredMethods(): string[];
|
|
23
22
|
/**
|
|
24
|
-
* Look up a registered handler by method name.
|
|
23
|
+
* Look up a canonical registered handler by method name.
|
|
25
24
|
* @param method - JSON-RPC method name to look up
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
* @returns The handler function, or `undefined` if not registered
|
|
26
|
+
*/
|
|
28
27
|
export declare function getHandler(method: string): Handler | undefined;
|
|
29
28
|
export interface TransportOptions {
|
|
30
29
|
input?: NodeJS.ReadableStream;
|
package/dist/server/transport.js
CHANGED
|
@@ -22,6 +22,7 @@ exports.startTransport = startTransport;
|
|
|
22
22
|
const readline_1 = require("readline");
|
|
23
23
|
const validationService_1 = require("../services/validationService");
|
|
24
24
|
const runtimeConfig_1 = require("../config/runtimeConfig");
|
|
25
|
+
const registry_1 = require("./registry");
|
|
25
26
|
const fs_1 = __importDefault(require("fs"));
|
|
26
27
|
const path_1 = __importDefault(require("path"));
|
|
27
28
|
// Robust version resolution: attempt cwd + relative to compiled dist location
|
|
@@ -42,50 +43,48 @@ for (const p of versionCandidates) {
|
|
|
42
43
|
}
|
|
43
44
|
catch { /* ignore */ }
|
|
44
45
|
}
|
|
45
|
-
const handlers = {
|
|
46
|
-
'health_check': () => {
|
|
47
|
-
// Minimal fallback health; enriched version registered by handlers.metrics.ts overwrites this
|
|
48
|
-
let instances = [];
|
|
49
|
-
try {
|
|
50
|
-
// Dynamic require avoids circular dependency at module load time
|
|
51
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
52
|
-
const { getActiveInstances } = require('../dashboard/server/InstanceManager');
|
|
53
|
-
instances = getActiveInstances().map(i => ({ pid: i.pid, port: i.port, host: i.host, startedAt: i.startedAt, current: i.current }));
|
|
54
|
-
}
|
|
55
|
-
catch { /* fail-open */ }
|
|
56
|
-
return { status: 'ok', timestamp: new Date().toISOString(), version: VERSION, pid: process.pid, uptime: Math.round(process.uptime()), instances };
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
const metrics = {};
|
|
60
46
|
/** Return the in-memory per-method metrics map (count, totalMs, maxMs).
|
|
61
47
|
* @returns Reference to the live metrics map keyed by method name
|
|
62
48
|
*/
|
|
63
|
-
function getMetrics() {
|
|
64
|
-
|
|
49
|
+
function getMetrics() {
|
|
50
|
+
return (0, registry_1.getMetricsRaw)();
|
|
51
|
+
}
|
|
65
52
|
/**
|
|
66
|
-
* Register a method handler
|
|
67
|
-
* Unlike the SDK registry, this does not add wrapping (metrics, audit, etc.).
|
|
53
|
+
* Register a transport-exposed method handler via the canonical registry.
|
|
68
54
|
* @param method - JSON-RPC method name
|
|
69
55
|
* @param handler - Handler function invoked with the parsed params
|
|
70
56
|
*/
|
|
71
57
|
function registerHandler(method, handler) {
|
|
72
|
-
|
|
73
|
-
handlerMeta[method] = { method };
|
|
58
|
+
(0, registry_1.registerHandler)(method, handler);
|
|
74
59
|
}
|
|
75
60
|
/**
|
|
76
|
-
* Return a sorted list of
|
|
61
|
+
* Return a sorted list of transport-exposed method names.
|
|
77
62
|
* @returns Array of method name strings in alphabetical order
|
|
78
63
|
*/
|
|
79
64
|
function listRegisteredMethods() {
|
|
80
|
-
return
|
|
65
|
+
return (0, registry_1.listRegisteredMethods)();
|
|
81
66
|
}
|
|
82
67
|
/**
|
|
83
|
-
* Look up a registered handler by method name.
|
|
68
|
+
* Look up a canonical registered handler by method name.
|
|
84
69
|
* @param method - JSON-RPC method name to look up
|
|
85
|
-
|
|
86
|
-
|
|
70
|
+
* @returns The handler function, or `undefined` if not registered
|
|
71
|
+
*/
|
|
87
72
|
function getHandler(method) {
|
|
88
|
-
return
|
|
73
|
+
return (0, registry_1.getHandler)(method);
|
|
74
|
+
}
|
|
75
|
+
function getFallbackHealth() {
|
|
76
|
+
let instances = [];
|
|
77
|
+
try {
|
|
78
|
+
// Dynamic require avoids circular dependency at module load time
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
80
|
+
const { getActiveInstances } = require('../dashboard/server/InstanceManager');
|
|
81
|
+
instances = getActiveInstances().map(i => ({ pid: i.pid, port: i.port, host: i.host, startedAt: i.startedAt, current: i.current }));
|
|
82
|
+
}
|
|
83
|
+
catch { /* fail-open */ }
|
|
84
|
+
return { status: 'ok', timestamp: new Date().toISOString(), version: VERSION, pid: process.pid, uptime: Math.round(process.uptime()), instances };
|
|
85
|
+
}
|
|
86
|
+
if (!(0, registry_1.getHandler)('health_check')) {
|
|
87
|
+
(0, registry_1.registerHandler)('health_check', () => getFallbackHealth());
|
|
89
88
|
}
|
|
90
89
|
function makeError(id, code, message, data) {
|
|
91
90
|
return { jsonrpc: '2.0', id: id ?? null, error: { code, message, data } };
|
|
@@ -132,6 +131,23 @@ function startTransport(opts = {}) {
|
|
|
132
131
|
const msg = typeof reason === 'object' && reason && 'message' in reason ? reason.message : String(reason);
|
|
133
132
|
log('error', 'unhandledRejection', { reason: msg });
|
|
134
133
|
});
|
|
134
|
+
const transportHandlers = {
|
|
135
|
+
'initialize': (params) => {
|
|
136
|
+
const p = params;
|
|
137
|
+
return {
|
|
138
|
+
protocolVersion: p?.protocolVersion || '2025-06-18',
|
|
139
|
+
serverInfo: { name: 'index', version: VERSION },
|
|
140
|
+
capabilities: { roots: { listChanged: true }, tools: { listChanged: true } }
|
|
141
|
+
};
|
|
142
|
+
},
|
|
143
|
+
'notifications/initialized': () => ({ acknowledged: true }),
|
|
144
|
+
'shutdown': () => ({ shuttingDown: true }),
|
|
145
|
+
'exit': () => { setTimeout(() => process.exit(0), 0); return { exiting: true }; }
|
|
146
|
+
};
|
|
147
|
+
const getAvailableMethods = () => Array.from(new Set([
|
|
148
|
+
...Object.keys(transportHandlers),
|
|
149
|
+
...(0, registry_1.listRegisteredMethods)(),
|
|
150
|
+
])).sort();
|
|
135
151
|
// Handshake state & helpers (deterministic: initialize result flushes, then server/ready)
|
|
136
152
|
let initialized = false;
|
|
137
153
|
let readyEmitted = false;
|
|
@@ -145,20 +161,6 @@ function startTransport(opts = {}) {
|
|
|
145
161
|
}
|
|
146
162
|
catch { /* ignore */ }
|
|
147
163
|
}
|
|
148
|
-
// Replace initialize handler with direct interception below to control write callback ordering.
|
|
149
|
-
registerHandler('initialize', (params) => {
|
|
150
|
-
// This body will be bypassed by explicit fast-path in line reader (kept for compatibility if called indirectly)
|
|
151
|
-
const p = params;
|
|
152
|
-
return {
|
|
153
|
-
protocolVersion: p?.protocolVersion || '2025-06-18',
|
|
154
|
-
serverInfo: { name: 'index', version: VERSION },
|
|
155
|
-
capabilities: { roots: { listChanged: true }, tools: { listChanged: true } }
|
|
156
|
-
};
|
|
157
|
-
});
|
|
158
|
-
// Accept notification some clients send post-initialize; respond benignly (single registration)
|
|
159
|
-
registerHandler('notifications/initialized', () => ({ acknowledged: true }));
|
|
160
|
-
registerHandler('shutdown', () => ({ shuttingDown: true }));
|
|
161
|
-
registerHandler('exit', () => { setTimeout(() => process.exit(0), 0); return { exiting: true }; });
|
|
162
164
|
// Use readline only for input parsing; do NOT set output to avoid echoing client-sent
|
|
163
165
|
// JSON-RPC request lines back to stdout (which confused tests expecting only server
|
|
164
166
|
// responses and caused false negatives when matching initialize/result frames).
|
|
@@ -208,8 +210,7 @@ function startTransport(opts = {}) {
|
|
|
208
210
|
}
|
|
209
211
|
initialized = true;
|
|
210
212
|
// Reuse registered initialize handler so future shared logic (capability changes, root listing, etc.) stays centralized.
|
|
211
|
-
const initHandler =
|
|
212
|
-
const start = Date.now();
|
|
213
|
+
const initHandler = transportHandlers['initialize'];
|
|
213
214
|
let resultPayload;
|
|
214
215
|
try {
|
|
215
216
|
resultPayload = initHandler ? initHandler(req.params) : {
|
|
@@ -224,12 +225,6 @@ function startTransport(opts = {}) {
|
|
|
224
225
|
}
|
|
225
226
|
// Support promise return from handler
|
|
226
227
|
Promise.resolve(resultPayload).then(resolved => {
|
|
227
|
-
const dur = Date.now() - start;
|
|
228
|
-
const rec = metrics['initialize'] || (metrics['initialize'] = { count: 0, totalMs: 0, maxMs: 0 });
|
|
229
|
-
rec.count++;
|
|
230
|
-
rec.totalMs += dur;
|
|
231
|
-
if (dur > rec.maxMs)
|
|
232
|
-
rec.maxMs = dur;
|
|
233
228
|
const initResult = { jsonrpc: '2.0', id: req.id ?? 1, result: resolved };
|
|
234
229
|
try {
|
|
235
230
|
if (protocolLog) {
|
|
@@ -249,10 +244,10 @@ function startTransport(opts = {}) {
|
|
|
249
244
|
});
|
|
250
245
|
return;
|
|
251
246
|
}
|
|
252
|
-
const handler =
|
|
247
|
+
const handler = transportHandlers[req.method] ?? (0, registry_1.getHandler)(req.method);
|
|
253
248
|
if (!handler) {
|
|
254
249
|
// Provide richer context for missing method to help client authors.
|
|
255
|
-
const available =
|
|
250
|
+
const available = getAvailableMethods();
|
|
256
251
|
log('debug', 'method_not_found', { requested: req.method, availableCount: available.length });
|
|
257
252
|
respondFn(makeError(req.id ?? null, -32601, 'Method not found', { method: req.method, available }));
|
|
258
253
|
return;
|
|
@@ -266,19 +261,12 @@ function startTransport(opts = {}) {
|
|
|
266
261
|
}
|
|
267
262
|
}
|
|
268
263
|
catch { /* fail-open on validator issues */ }
|
|
269
|
-
const start = Date.now();
|
|
270
264
|
Promise.resolve()
|
|
271
265
|
.then(() => handler(req.params))
|
|
272
266
|
.then(result => {
|
|
273
267
|
if (!initialized) {
|
|
274
268
|
log('debug', 'call_before_initialize', { method: req.method });
|
|
275
269
|
}
|
|
276
|
-
const dur = Date.now() - start;
|
|
277
|
-
const rec = metrics[req.method] || (metrics[req.method] = { count: 0, totalMs: 0, maxMs: 0 });
|
|
278
|
-
rec.count++;
|
|
279
|
-
rec.totalMs += dur;
|
|
280
|
-
if (dur > rec.maxMs)
|
|
281
|
-
rec.maxMs = dur;
|
|
282
270
|
if (req.id !== undefined && req.id !== null) {
|
|
283
271
|
try {
|
|
284
272
|
if (protocolLog || verbose)
|
|
@@ -289,12 +277,6 @@ function startTransport(opts = {}) {
|
|
|
289
277
|
}
|
|
290
278
|
})
|
|
291
279
|
.catch(e => {
|
|
292
|
-
const dur = Date.now() - start;
|
|
293
|
-
const rec = metrics[req.method] || (metrics[req.method] = { count: 0, totalMs: 0, maxMs: 0 });
|
|
294
|
-
rec.count++;
|
|
295
|
-
rec.totalMs += dur;
|
|
296
|
-
if (dur > rec.maxMs)
|
|
297
|
-
rec.maxMs = dur;
|
|
298
280
|
const maybeErr = e;
|
|
299
281
|
if (maybeErr && typeof maybeErr === 'object' && Number.isSafeInteger(maybeErr.code)) {
|
|
300
282
|
log('error', 'handler_error', { method: req.method, message: maybeErr.message, code: maybeErr.code });
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
export declare const dynamicImport: (specifier: string) => any;
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Emit a lightweight diagnostic marker without intercepting stdout writes.
|
|
4
4
|
* Enabled via INDEX_SERVER_TRACE=healthMixed.
|
|
5
5
|
*/
|
|
6
6
|
export declare function setupStdoutDiagnostics(): Promise<void>;
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
* The upstream SDK has used both `_onRequest` (camel) and `_onrequest` (lower) across versions;
|
|
10
|
-
* we defensively hook whichever exists and assign our wrapper to BOTH names.
|
|
8
|
+
* Keep diagnostics on public surfaces only; private SDK dispatcher hooks are no longer patched.
|
|
11
9
|
*/
|
|
12
|
-
export declare function setupDispatcherOverride(
|
|
13
|
-
/**
|
|
14
|
-
* Wrap transport.send to detect initialize response flush and emit ready.
|
|
15
|
-
*/
|
|
16
|
-
export declare function wrapTransportSend(server: any, transport: any): void;
|
|
10
|
+
export declare function setupDispatcherOverride(_server: any): void;
|
|
17
11
|
/**
|
|
18
12
|
* Explicit keepalive to avoid premature process exit before first client request.
|
|
19
13
|
* @param label - Optional label for diagnostic log messages (e.g. 'secondary')
|