@jagilber-org/index-server 1.19.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 +1218 -0
- package/CODE_OF_CONDUCT.md +49 -0
- package/CONTRIBUTING.md +75 -0
- package/LICENSE +21 -0
- package/README.md +523 -0
- package/SECURITY.md +50 -0
- package/dist/config/configUtils.d.ts +11 -0
- package/dist/config/configUtils.js +87 -0
- package/dist/config/dashboardConfig.d.ts +45 -0
- package/dist/config/dashboardConfig.js +63 -0
- package/dist/config/defaultValues.d.ts +61 -0
- package/dist/config/defaultValues.js +70 -0
- package/dist/config/dirConstants.d.ts +17 -0
- package/dist/config/dirConstants.js +28 -0
- package/dist/config/featureConfig.d.ts +61 -0
- package/dist/config/featureConfig.js +121 -0
- package/dist/config/runtimeConfig.d.ts +145 -0
- package/dist/config/runtimeConfig.js +334 -0
- package/dist/config/serverConfig.d.ts +90 -0
- package/dist/config/serverConfig.js +164 -0
- package/dist/dashboard/analytics/AnalyticsEngine.d.ts +142 -0
- package/dist/dashboard/analytics/AnalyticsEngine.js +373 -0
- package/dist/dashboard/analytics/BusinessIntelligence.d.ts +187 -0
- package/dist/dashboard/analytics/BusinessIntelligence.js +594 -0
- package/dist/dashboard/client/admin.html +2150 -0
- package/dist/dashboard/client/chunks/mermaid-layout-elk.esm.min/chunk-SP2CHFBE.mjs +1 -0
- package/dist/dashboard/client/chunks/mermaid-layout-elk.esm.min/render-T6MDALS3.mjs +27 -0
- package/dist/dashboard/client/css/admin.css +1466 -0
- package/dist/dashboard/client/js/admin.boot.js +359 -0
- package/dist/dashboard/client/js/admin.config.js +196 -0
- package/dist/dashboard/client/js/admin.embeddings.js +425 -0
- package/dist/dashboard/client/js/admin.graph.js +583 -0
- package/dist/dashboard/client/js/admin.instances.js +120 -0
- package/dist/dashboard/client/js/admin.instructions.js +552 -0
- package/dist/dashboard/client/js/admin.logs.js +113 -0
- package/dist/dashboard/client/js/admin.maintenance.js +354 -0
- package/dist/dashboard/client/js/admin.messaging.js +635 -0
- package/dist/dashboard/client/js/admin.monitor.js +181 -0
- package/dist/dashboard/client/js/admin.overview.js +221 -0
- package/dist/dashboard/client/js/admin.performance.js +61 -0
- package/dist/dashboard/client/js/admin.sessions.js +293 -0
- package/dist/dashboard/client/js/admin.sqlite.js +366 -0
- package/dist/dashboard/client/js/admin.utils.js +49 -0
- package/dist/dashboard/client/js/chart.umd.js +14 -0
- package/dist/dashboard/client/js/elk.bundled.js +6696 -0
- package/dist/dashboard/client/js/marked.umd.js +74 -0
- package/dist/dashboard/client/js/mermaid.min.js +3022 -0
- package/dist/dashboard/client/mermaid-layout-elk.esm.min.mjs +1 -0
- package/dist/dashboard/export/DataExporter.d.ts +169 -0
- package/dist/dashboard/export/DataExporter.js +737 -0
- package/dist/dashboard/export/exporters/csvExporter.d.ts +11 -0
- package/dist/dashboard/export/exporters/csvExporter.js +46 -0
- package/dist/dashboard/export/exporters/exportTypes.d.ts +89 -0
- package/dist/dashboard/export/exporters/exportTypes.js +5 -0
- package/dist/dashboard/export/exporters/jsonExporter.d.ts +7 -0
- package/dist/dashboard/export/exporters/jsonExporter.js +22 -0
- package/dist/dashboard/export/exporters/xmlExporter.d.ts +17 -0
- package/dist/dashboard/export/exporters/xmlExporter.js +175 -0
- package/dist/dashboard/integration/APIIntegration.d.ts +41 -0
- package/dist/dashboard/integration/APIIntegration.js +95 -0
- package/dist/dashboard/security/SecurityMonitor.d.ts +167 -0
- package/dist/dashboard/security/SecurityMonitor.js +559 -0
- package/dist/dashboard/server/AdminPanel.d.ts +183 -0
- package/dist/dashboard/server/AdminPanel.js +792 -0
- package/dist/dashboard/server/AdminPanelConfig.d.ts +42 -0
- package/dist/dashboard/server/AdminPanelConfig.js +80 -0
- package/dist/dashboard/server/AdminPanelState.d.ts +47 -0
- package/dist/dashboard/server/AdminPanelState.js +214 -0
- package/dist/dashboard/server/ApiRoutes.d.ts +17 -0
- package/dist/dashboard/server/ApiRoutes.js +149 -0
- package/dist/dashboard/server/DashboardServer.d.ts +49 -0
- package/dist/dashboard/server/DashboardServer.js +159 -0
- package/dist/dashboard/server/FileMetricsStorage.d.ts +49 -0
- package/dist/dashboard/server/FileMetricsStorage.js +195 -0
- package/dist/dashboard/server/HttpTransport.d.ts +23 -0
- package/dist/dashboard/server/HttpTransport.js +116 -0
- package/dist/dashboard/server/InstanceManager.d.ts +53 -0
- package/dist/dashboard/server/InstanceManager.js +284 -0
- package/dist/dashboard/server/KnowledgeStore.d.ts +35 -0
- package/dist/dashboard/server/KnowledgeStore.js +105 -0
- package/dist/dashboard/server/LeaderElection.d.ts +81 -0
- package/dist/dashboard/server/LeaderElection.js +268 -0
- package/dist/dashboard/server/MetricsCollector.d.ts +200 -0
- package/dist/dashboard/server/MetricsCollector.js +803 -0
- package/dist/dashboard/server/SessionPersistenceManager.d.ts +88 -0
- package/dist/dashboard/server/SessionPersistenceManager.js +457 -0
- package/dist/dashboard/server/ThinClient.d.ts +64 -0
- package/dist/dashboard/server/ThinClient.js +237 -0
- package/dist/dashboard/server/WebSocketManager.d.ts +161 -0
- package/dist/dashboard/server/WebSocketManager.js +463 -0
- package/dist/dashboard/server/httpLifecycle.d.ts +17 -0
- package/dist/dashboard/server/httpLifecycle.js +35 -0
- package/dist/dashboard/server/legacyDashboardHtml.d.ts +9 -0
- package/dist/dashboard/server/legacyDashboardHtml.js +618 -0
- package/dist/dashboard/server/legacyDashboardStyles.d.ts +5 -0
- package/dist/dashboard/server/legacyDashboardStyles.js +490 -0
- package/dist/dashboard/server/metricsAggregation.d.ts +252 -0
- package/dist/dashboard/server/metricsAggregation.js +206 -0
- package/dist/dashboard/server/metricsSerializer.d.ts +25 -0
- package/dist/dashboard/server/metricsSerializer.js +195 -0
- package/dist/dashboard/server/routes/admin.routes.d.ts +16 -0
- package/dist/dashboard/server/routes/admin.routes.js +596 -0
- package/dist/dashboard/server/routes/alerts.routes.d.ts +7 -0
- package/dist/dashboard/server/routes/alerts.routes.js +93 -0
- package/dist/dashboard/server/routes/api.feedback.routes.d.ts +73 -0
- package/dist/dashboard/server/routes/api.feedback.routes.js +171 -0
- package/dist/dashboard/server/routes/api.instructions.routes.d.ts +101 -0
- package/dist/dashboard/server/routes/api.instructions.routes.js +213 -0
- package/dist/dashboard/server/routes/api.usage.routes.d.ts +57 -0
- package/dist/dashboard/server/routes/api.usage.routes.js +374 -0
- package/dist/dashboard/server/routes/embeddings.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/embeddings.routes.js +246 -0
- package/dist/dashboard/server/routes/graph.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/graph.routes.js +280 -0
- package/dist/dashboard/server/routes/index.d.ts +38 -0
- package/dist/dashboard/server/routes/index.js +194 -0
- package/dist/dashboard/server/routes/instances.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/instances.routes.js +35 -0
- package/dist/dashboard/server/routes/instructions.routes.d.ts +8 -0
- package/dist/dashboard/server/routes/instructions.routes.js +336 -0
- package/dist/dashboard/server/routes/knowledge.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/knowledge.routes.js +82 -0
- package/dist/dashboard/server/routes/logs.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/logs.routes.js +164 -0
- package/dist/dashboard/server/routes/messaging.routes.d.ts +16 -0
- package/dist/dashboard/server/routes/messaging.routes.js +293 -0
- package/dist/dashboard/server/routes/metrics.routes.d.ts +10 -0
- package/dist/dashboard/server/routes/metrics.routes.js +346 -0
- package/dist/dashboard/server/routes/scripts.routes.d.ts +9 -0
- package/dist/dashboard/server/routes/scripts.routes.js +84 -0
- package/dist/dashboard/server/routes/sqlite.routes.d.ts +9 -0
- package/dist/dashboard/server/routes/sqlite.routes.js +569 -0
- package/dist/dashboard/server/routes/status.routes.d.ts +7 -0
- package/dist/dashboard/server/routes/status.routes.js +183 -0
- package/dist/dashboard/server/routes/synthetic.routes.d.ts +7 -0
- package/dist/dashboard/server/routes/synthetic.routes.js +195 -0
- package/dist/dashboard/server/routes/tools.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/tools.routes.js +46 -0
- package/dist/dashboard/server/routes/usage.routes.d.ts +6 -0
- package/dist/dashboard/server/routes/usage.routes.js +25 -0
- package/dist/dashboard/server/wsInit.d.ts +16 -0
- package/dist/dashboard/server/wsInit.js +35 -0
- package/dist/externalClientLib.d.ts +1 -0
- package/dist/externalClientLib.js +2 -0
- package/dist/minimal/index.d.ts +1 -0
- package/dist/minimal/index.js +140 -0
- package/dist/models/SessionPersistence.d.ts +115 -0
- package/dist/models/SessionPersistence.js +66 -0
- package/dist/models/instruction.d.ts +45 -0
- package/dist/models/instruction.js +2 -0
- package/dist/perf/benchmark.d.ts +1 -0
- package/dist/perf/benchmark.js +50 -0
- package/dist/portableClientWrapper.d.ts +1 -0
- package/dist/portableClientWrapper.js +2 -0
- package/dist/schemas/index.d.ts +128 -0
- package/dist/schemas/index.js +371 -0
- package/dist/scripts/runPerformanceBaseline.d.ts +1 -0
- package/dist/scripts/runPerformanceBaseline.js +17 -0
- package/dist/server/handshakeManager.d.ts +25 -0
- package/dist/server/handshakeManager.js +472 -0
- package/dist/server/index-server.d.ts +56 -0
- package/dist/server/index-server.js +822 -0
- package/dist/server/registry.d.ts +44 -0
- package/dist/server/registry.js +236 -0
- package/dist/server/sdkServer.d.ts +8 -0
- package/dist/server/sdkServer.js +299 -0
- package/dist/server/shutdownGuard.d.ts +41 -0
- package/dist/server/shutdownGuard.js +52 -0
- package/dist/server/thin-client.d.ts +22 -0
- package/dist/server/thin-client.js +111 -0
- package/dist/server/transport.d.ts +41 -0
- package/dist/server/transport.js +312 -0
- package/dist/server/transportFactory.d.ts +21 -0
- package/dist/server/transportFactory.js +429 -0
- package/dist/services/atomicFs.d.ts +22 -0
- package/dist/services/atomicFs.js +103 -0
- package/dist/services/auditLog.d.ts +38 -0
- package/dist/services/auditLog.js +142 -0
- package/dist/services/autoBackup.d.ts +14 -0
- package/dist/services/autoBackup.js +171 -0
- package/dist/services/autoSplit.d.ts +32 -0
- package/dist/services/autoSplit.js +113 -0
- package/dist/services/backupZip.d.ts +25 -0
- package/dist/services/backupZip.js +110 -0
- package/dist/services/bootstrapGating.d.ts +123 -0
- package/dist/services/bootstrapGating.js +221 -0
- package/dist/services/canonical.d.ts +23 -0
- package/dist/services/canonical.js +65 -0
- package/dist/services/categoryRules.d.ts +7 -0
- package/dist/services/categoryRules.js +37 -0
- package/dist/services/classificationService.d.ts +42 -0
- package/dist/services/classificationService.js +168 -0
- package/dist/services/embeddingService.d.ts +62 -0
- package/dist/services/embeddingService.js +259 -0
- package/dist/services/errors.d.ts +22 -0
- package/dist/services/errors.js +31 -0
- package/dist/services/featureFlags.d.ts +25 -0
- package/dist/services/featureFlags.js +89 -0
- package/dist/services/features.d.ts +13 -0
- package/dist/services/features.js +35 -0
- package/dist/services/handlers/instructions.add.d.ts +1 -0
- package/dist/services/handlers/instructions.add.js +496 -0
- package/dist/services/handlers/instructions.groom.d.ts +1 -0
- package/dist/services/handlers/instructions.groom.js +523 -0
- package/dist/services/handlers/instructions.import.d.ts +1 -0
- package/dist/services/handlers/instructions.import.js +173 -0
- package/dist/services/handlers/instructions.patch.d.ts +1 -0
- package/dist/services/handlers/instructions.patch.js +167 -0
- package/dist/services/handlers/instructions.query.d.ts +163 -0
- package/dist/services/handlers/instructions.query.js +522 -0
- package/dist/services/handlers/instructions.reload.d.ts +1 -0
- package/dist/services/handlers/instructions.reload.js +13 -0
- package/dist/services/handlers/instructions.remove.d.ts +1 -0
- package/dist/services/handlers/instructions.remove.js +118 -0
- package/dist/services/handlers/instructions.shared.d.ts +31 -0
- package/dist/services/handlers/instructions.shared.js +124 -0
- package/dist/services/handlers.activation.d.ts +1 -0
- package/dist/services/handlers.activation.js +203 -0
- package/dist/services/handlers.bootstrap.d.ts +1 -0
- package/dist/services/handlers.bootstrap.js +38 -0
- package/dist/services/handlers.dashboardConfig.d.ts +34 -0
- package/dist/services/handlers.dashboardConfig.js +108 -0
- package/dist/services/handlers.diagnostics.d.ts +1 -0
- package/dist/services/handlers.diagnostics.js +64 -0
- package/dist/services/handlers.feedback.d.ts +15 -0
- package/dist/services/handlers.feedback.js +378 -0
- package/dist/services/handlers.gates.d.ts +1 -0
- package/dist/services/handlers.gates.js +46 -0
- package/dist/services/handlers.graph.d.ts +53 -0
- package/dist/services/handlers.graph.js +231 -0
- package/dist/services/handlers.help.d.ts +1 -0
- package/dist/services/handlers.help.js +119 -0
- package/dist/services/handlers.instructionSchema.d.ts +1 -0
- package/dist/services/handlers.instructionSchema.js +227 -0
- package/dist/services/handlers.instructions.d.ts +8 -0
- package/dist/services/handlers.instructions.js +14 -0
- package/dist/services/handlers.instructionsDiagnostics.d.ts +1 -0
- package/dist/services/handlers.instructionsDiagnostics.js +14 -0
- package/dist/services/handlers.integrity.d.ts +1 -0
- package/dist/services/handlers.integrity.js +35 -0
- package/dist/services/handlers.manifest.d.ts +1 -0
- package/dist/services/handlers.manifest.js +24 -0
- package/dist/services/handlers.messaging.d.ts +12 -0
- package/dist/services/handlers.messaging.js +203 -0
- package/dist/services/handlers.metrics.d.ts +1 -0
- package/dist/services/handlers.metrics.js +43 -0
- package/dist/services/handlers.promote.d.ts +1 -0
- package/dist/services/handlers.promote.js +306 -0
- package/dist/services/handlers.prompt.d.ts +1 -0
- package/dist/services/handlers.prompt.js +7 -0
- package/dist/services/handlers.search.d.ts +69 -0
- package/dist/services/handlers.search.js +645 -0
- package/dist/services/handlers.testPrimitive.d.ts +1 -0
- package/dist/services/handlers.testPrimitive.js +5 -0
- package/dist/services/handlers.trace.d.ts +1 -0
- package/dist/services/handlers.trace.js +31 -0
- package/dist/services/handlers.usage.d.ts +1 -0
- package/dist/services/handlers.usage.js +11 -0
- package/dist/services/hotScore.d.ts +137 -0
- package/dist/services/hotScore.js +244 -0
- package/dist/services/indexContext.d.ts +117 -0
- package/dist/services/indexContext.js +968 -0
- package/dist/services/indexLoader.d.ts +44 -0
- package/dist/services/indexLoader.js +921 -0
- package/dist/services/indexRepository.d.ts +32 -0
- package/dist/services/indexRepository.js +71 -0
- package/dist/services/indexingService.d.ts +1 -0
- package/dist/services/indexingService.js +2 -0
- package/dist/services/instructions.dispatcher.d.ts +1 -0
- package/dist/services/instructions.dispatcher.js +231 -0
- package/dist/services/logPrefix.d.ts +1 -0
- package/dist/services/logPrefix.js +30 -0
- package/dist/services/logger.d.ts +52 -0
- package/dist/services/logger.js +268 -0
- package/dist/services/manifestManager.d.ts +82 -0
- package/dist/services/manifestManager.js +200 -0
- package/dist/services/messaging/agentMailbox.d.ts +60 -0
- package/dist/services/messaging/agentMailbox.js +353 -0
- package/dist/services/messaging/messagingPersistence.d.ts +20 -0
- package/dist/services/messaging/messagingPersistence.js +111 -0
- package/dist/services/messaging/messagingTypes.d.ts +150 -0
- package/dist/services/messaging/messagingTypes.js +66 -0
- package/dist/services/ownershipService.d.ts +1 -0
- package/dist/services/ownershipService.js +38 -0
- package/dist/services/performanceBaseline.d.ts +19 -0
- package/dist/services/performanceBaseline.js +210 -0
- package/dist/services/preflight.d.ts +12 -0
- package/dist/services/preflight.js +79 -0
- package/dist/services/promptReviewService.d.ts +44 -0
- package/dist/services/promptReviewService.js +101 -0
- package/dist/services/responseEnvelope.d.ts +6 -0
- package/dist/services/responseEnvelope.js +25 -0
- package/dist/services/seedBootstrap.d.ts +34 -0
- package/dist/services/seedBootstrap.js +427 -0
- package/dist/services/storage/factory.d.ts +17 -0
- package/dist/services/storage/factory.js +35 -0
- package/dist/services/storage/hashUtils.d.ts +11 -0
- package/dist/services/storage/hashUtils.js +35 -0
- package/dist/services/storage/index.d.ts +12 -0
- package/dist/services/storage/index.js +18 -0
- package/dist/services/storage/jsonFileStore.d.ts +32 -0
- package/dist/services/storage/jsonFileStore.js +241 -0
- package/dist/services/storage/migrationEngine.d.ts +35 -0
- package/dist/services/storage/migrationEngine.js +93 -0
- package/dist/services/storage/sqliteMessageStore.d.ts +53 -0
- package/dist/services/storage/sqliteMessageStore.js +146 -0
- package/dist/services/storage/sqliteSchema.d.ts +12 -0
- package/dist/services/storage/sqliteSchema.js +122 -0
- package/dist/services/storage/sqliteStore.d.ts +41 -0
- package/dist/services/storage/sqliteStore.js +339 -0
- package/dist/services/storage/sqliteUsageStore.d.ts +35 -0
- package/dist/services/storage/sqliteUsageStore.js +94 -0
- package/dist/services/storage/types.d.ts +171 -0
- package/dist/services/storage/types.js +12 -0
- package/dist/services/toolHandlers.d.ts +23 -0
- package/dist/services/toolHandlers.js +50 -0
- package/dist/services/toolRegistry.d.ts +20 -0
- package/dist/services/toolRegistry.js +490 -0
- package/dist/services/toolRegistry.zod.d.ts +10 -0
- package/dist/services/toolRegistry.zod.js +323 -0
- package/dist/services/tracing.d.ts +26 -0
- package/dist/services/tracing.js +260 -0
- package/dist/services/usageBuckets.d.ts +161 -0
- package/dist/services/usageBuckets.js +364 -0
- package/dist/services/validationService.d.ts +38 -0
- package/dist/services/validationService.js +125 -0
- package/dist/utils/BufferRing.d.ts +203 -0
- package/dist/utils/BufferRing.js +551 -0
- package/dist/utils/BufferRingExamples.d.ts +55 -0
- package/dist/utils/BufferRingExamples.js +188 -0
- package/dist/utils/envUtils.d.ts +42 -0
- package/dist/utils/envUtils.js +80 -0
- package/dist/utils/memoryMonitor.d.ts +83 -0
- package/dist/utils/memoryMonitor.js +275 -0
- package/dist/versioning/schemaVersion.d.ts +6 -0
- package/dist/versioning/schemaVersion.js +93 -0
- package/package.json +134 -0
- package/schemas/README.md +13 -0
- package/schemas/feedback-entry.schema.json +27 -0
- package/schemas/graph-export-v2.schema.json +60 -0
- package/schemas/index-server.code-schema.json +38477 -0
- package/schemas/instruction.schema.json +262 -0
- package/schemas/json-schema/SessionPersistence-persisted-admin-session.schema.json +54 -0
- package/schemas/json-schema/SessionPersistence-persisted-session-history-entry.schema.json +51 -0
- package/schemas/json-schema/SessionPersistence-persisted-web-socket-connection.schema.json +54 -0
- package/schemas/json-schema/SessionPersistence-session-persistence-config.schema.json +110 -0
- package/schemas/json-schema/SessionPersistence-session-persistence-data.schema.json +229 -0
- package/schemas/json-schema/SessionPersistence-session-persistence-manifest.schema.json +109 -0
- package/schemas/json-schema/SessionPersistence-session-persistence-metadata.schema.json +55 -0
- package/schemas/json-schema/instruction-audience-scope.schema.json +14 -0
- package/schemas/json-schema/instruction-content-type.schema.json +17 -0
- package/schemas/json-schema/instruction-instruction-entry.schema.json +206 -0
- package/schemas/json-schema/instruction-requirement-level.schema.json +16 -0
- package/schemas/manifest.json +78 -0
- package/schemas/manifest.schema.json +33 -0
- package/schemas/usage-batch.schema.json +16 -0
- package/schemas/usage-buckets.schema.json +30 -0
- package/schemas/usage-event.schema.json +17 -0
- package/scripts/copy-dashboard-assets.mjs +170 -0
- package/scripts/setup-hooks.cjs +28 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
/**
|
|
5
|
+
* DashboardServer - Enhanced Phase 2 Dashboard with Real-time Features
|
|
6
|
+
*
|
|
7
|
+
* Coordinator class that wires together:
|
|
8
|
+
* - Express middleware and routes (via mountDashboardRoutes)
|
|
9
|
+
* - HTTP/HTTPS server lifecycle (via httpLifecycle)
|
|
10
|
+
* - WebSocket initialization and metrics broadcast (via wsInit)
|
|
11
|
+
*/
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.DashboardServer = void 0;
|
|
17
|
+
exports.createDashboardServer = createDashboardServer;
|
|
18
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
19
|
+
const express_1 = __importDefault(require("express"));
|
|
20
|
+
const path_1 = __importDefault(require("path"));
|
|
21
|
+
const MetricsCollector_js_1 = require("./MetricsCollector.js");
|
|
22
|
+
const WebSocketManager_js_1 = require("./WebSocketManager.js");
|
|
23
|
+
const httpLifecycle_js_1 = require("./httpLifecycle.js");
|
|
24
|
+
const wsInit_js_1 = require("./wsInit.js");
|
|
25
|
+
const index_js_1 = require("./routes/index.js");
|
|
26
|
+
class DashboardServer {
|
|
27
|
+
app;
|
|
28
|
+
server = null;
|
|
29
|
+
metricsCollector = (0, MetricsCollector_js_1.getMetricsCollector)();
|
|
30
|
+
webSocketManager = (0, WebSocketManager_js_1.getWebSocketManager)();
|
|
31
|
+
metricsBroadcastTimer = null;
|
|
32
|
+
options;
|
|
33
|
+
get tlsEnabled() { return !!this.options.tls; }
|
|
34
|
+
get httpProtocol() { return this.tlsEnabled ? 'https' : 'http'; }
|
|
35
|
+
get wsProtocol() { return this.tlsEnabled ? 'wss' : 'ws'; }
|
|
36
|
+
constructor(options = {}) {
|
|
37
|
+
this.options = {
|
|
38
|
+
host: options.host || '127.0.0.1',
|
|
39
|
+
port: options.port || 8989,
|
|
40
|
+
maxPortTries: options.maxPortTries || 10,
|
|
41
|
+
enableWebSockets: options.enableWebSockets ?? true,
|
|
42
|
+
enableCors: options.enableCors ?? true,
|
|
43
|
+
metricsBroadcastIntervalMs: options.metricsBroadcastIntervalMs || 5000,
|
|
44
|
+
tls: options.tls,
|
|
45
|
+
graphEnabled: options.graphEnabled ?? false,
|
|
46
|
+
};
|
|
47
|
+
this.app = (0, express_1.default)();
|
|
48
|
+
this.setupMiddleware();
|
|
49
|
+
(0, index_js_1.mountDashboardRoutes)(this.app, {
|
|
50
|
+
metricsCollector: this.metricsCollector,
|
|
51
|
+
enableWebSockets: this.options.enableWebSockets,
|
|
52
|
+
enableCors: this.options.enableCors,
|
|
53
|
+
graphEnabled: this.options.graphEnabled,
|
|
54
|
+
wsProtocol: this.wsProtocol,
|
|
55
|
+
getServerInfo: () => this.getServerInfo(),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
async start() {
|
|
59
|
+
for (let attempt = 0; attempt < this.options.maxPortTries; attempt++) {
|
|
60
|
+
const currentPort = this.options.port + attempt;
|
|
61
|
+
try {
|
|
62
|
+
this.server = (0, httpLifecycle_js_1.buildHttpServer)(this.app, this.options.tls);
|
|
63
|
+
await (0, httpLifecycle_js_1.bindToPort)(this.server, currentPort, this.options.host);
|
|
64
|
+
// eslint-disable-next-line no-console
|
|
65
|
+
console.log(`[Dashboard] Server started on ${this.httpProtocol}://${this.options.host}:${currentPort}`);
|
|
66
|
+
if (this.options.enableWebSockets) {
|
|
67
|
+
(0, wsInit_js_1.initWebSocket)(this.server, this.webSocketManager);
|
|
68
|
+
// eslint-disable-next-line no-console
|
|
69
|
+
console.log(`[Dashboard] WebSocket support enabled on ${this.wsProtocol}://${this.options.host}:${currentPort}/ws`);
|
|
70
|
+
this.metricsBroadcastTimer = (0, wsInit_js_1.startMetricsBroadcast)(this.webSocketManager, this.metricsCollector, this.options.metricsBroadcastIntervalMs);
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
url: `${this.httpProtocol}://${this.options.host}:${currentPort}/`,
|
|
74
|
+
port: currentPort,
|
|
75
|
+
close: () => this.stop(),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (error?.code === 'EADDRINUSE') {
|
|
80
|
+
// eslint-disable-next-line no-console
|
|
81
|
+
console.log(`[Dashboard] Port ${currentPort} in use, trying ${currentPort + 1}`);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
throw new Error(`Failed to start dashboard server after ${this.options.maxPortTries} attempts`);
|
|
88
|
+
}
|
|
89
|
+
async stop() {
|
|
90
|
+
if (this.server) {
|
|
91
|
+
if (this.options.enableWebSockets) {
|
|
92
|
+
this.webSocketManager.close();
|
|
93
|
+
if (this.metricsBroadcastTimer) {
|
|
94
|
+
clearInterval(this.metricsBroadcastTimer);
|
|
95
|
+
this.metricsBroadcastTimer = null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
await (0, httpLifecycle_js_1.closeHttpServer)(this.server);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
getServerInfo() {
|
|
102
|
+
if (!this.server?.listening) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const address = this.server.address();
|
|
106
|
+
if (!address || typeof address === 'string') {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
port: address.port,
|
|
111
|
+
host: this.options.host,
|
|
112
|
+
url: `${this.httpProtocol}://${this.options.host}:${address.port}`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
setupMiddleware() {
|
|
116
|
+
if (this.options.enableCors) {
|
|
117
|
+
this.app.use((req, res, next) => {
|
|
118
|
+
const origin = req.headers.origin;
|
|
119
|
+
if (origin && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(origin)) {
|
|
120
|
+
res.header('Access-Control-Allow-Origin', origin);
|
|
121
|
+
}
|
|
122
|
+
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
123
|
+
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
|
|
124
|
+
if (req.method === 'OPTIONS') {
|
|
125
|
+
res.sendStatus(200);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
next();
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// Remove X-Powered-By (technology fingerprinting) and enforce strong ETags
|
|
132
|
+
this.app.disable('x-powered-by');
|
|
133
|
+
this.app.set('etag', 'strong');
|
|
134
|
+
// Per-request CSP nonce + security headers
|
|
135
|
+
this.app.use((_req, res, next) => {
|
|
136
|
+
const nonce = crypto_1.default.randomBytes(16).toString('base64');
|
|
137
|
+
res.locals.cspNonce = nonce;
|
|
138
|
+
res.header('X-Content-Type-Options', 'nosniff');
|
|
139
|
+
res.header('X-Frame-Options', 'DENY');
|
|
140
|
+
res.header('X-XSS-Protection', '1; mode=block');
|
|
141
|
+
res.header('Referrer-Policy', 'strict-origin-when-cross-origin');
|
|
142
|
+
res.header('Content-Security-Policy', `default-src 'self'; script-src 'self' 'nonce-${nonce}' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; font-src 'self'; img-src 'self' data:; connect-src 'self' ${this.tlsEnabled ? 'wss:' : 'ws:'}; frame-ancestors 'none'; form-action 'self'`);
|
|
143
|
+
if (this.tlsEnabled) {
|
|
144
|
+
res.header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
|
145
|
+
}
|
|
146
|
+
next();
|
|
147
|
+
});
|
|
148
|
+
this.app.use(express_1.default.json());
|
|
149
|
+
this.app.use(express_1.default.static(path_1.default.join(__dirname, '..', 'client'), {
|
|
150
|
+
etag: true,
|
|
151
|
+
lastModified: true,
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
exports.DashboardServer = DashboardServer;
|
|
156
|
+
function createDashboardServer(options = {}) {
|
|
157
|
+
return new DashboardServer(options);
|
|
158
|
+
}
|
|
159
|
+
exports.default = createDashboardServer;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { MetricsSnapshot } from './MetricsCollector';
|
|
2
|
+
/**
|
|
3
|
+
* File-based storage for metrics snapshots to prevent memory accumulation
|
|
4
|
+
* Stores snapshots as individual JSON files with timestamp-based naming
|
|
5
|
+
*/
|
|
6
|
+
export declare class FileMetricsStorage {
|
|
7
|
+
private storageDir;
|
|
8
|
+
private maxFiles;
|
|
9
|
+
private retentionMinutes;
|
|
10
|
+
constructor(options?: {
|
|
11
|
+
storageDir?: string;
|
|
12
|
+
maxFiles?: number;
|
|
13
|
+
retentionMinutes?: number;
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* Store a metrics snapshot to disk
|
|
17
|
+
*/
|
|
18
|
+
storeSnapshot(snapshot: MetricsSnapshot): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Get recent snapshots from disk (for dashboard/analysis)
|
|
21
|
+
*/
|
|
22
|
+
getRecentSnapshots(count?: number): Promise<MetricsSnapshot[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Get snapshots within a time range
|
|
25
|
+
*/
|
|
26
|
+
getSnapshotsInRange(startTime: number, endTime: number): Promise<MetricsSnapshot[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Get storage statistics
|
|
29
|
+
*/
|
|
30
|
+
getStorageStats(): Promise<{
|
|
31
|
+
fileCount: number;
|
|
32
|
+
totalSizeKB: number;
|
|
33
|
+
oldestTimestamp?: number;
|
|
34
|
+
newestTimestamp?: number;
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Clear all stored metrics
|
|
38
|
+
*/
|
|
39
|
+
clearAll(): Promise<void>;
|
|
40
|
+
private ensureStorageDir;
|
|
41
|
+
private getSnapshotFiles;
|
|
42
|
+
private extractTimestampFromFilename;
|
|
43
|
+
private cleanupOldFiles;
|
|
44
|
+
}
|
|
45
|
+
export declare function getFileMetricsStorage(options?: {
|
|
46
|
+
storageDir?: string;
|
|
47
|
+
maxFiles?: number;
|
|
48
|
+
retentionMinutes?: number;
|
|
49
|
+
}): FileMetricsStorage;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FileMetricsStorage = void 0;
|
|
7
|
+
exports.getFileMetricsStorage = getFileMetricsStorage;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
/**
|
|
11
|
+
* File-based storage for metrics snapshots to prevent memory accumulation
|
|
12
|
+
* Stores snapshots as individual JSON files with timestamp-based naming
|
|
13
|
+
*/
|
|
14
|
+
class FileMetricsStorage {
|
|
15
|
+
storageDir;
|
|
16
|
+
maxFiles;
|
|
17
|
+
retentionMinutes;
|
|
18
|
+
constructor(options = {}) {
|
|
19
|
+
this.storageDir = options.storageDir || path_1.default.join(process.cwd(), 'metrics');
|
|
20
|
+
this.maxFiles = options.maxFiles || 720; // 12 hours at 1-minute intervals
|
|
21
|
+
this.retentionMinutes = options.retentionMinutes || 60;
|
|
22
|
+
this.ensureStorageDir();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Store a metrics snapshot to disk
|
|
26
|
+
*/
|
|
27
|
+
async storeSnapshot(snapshot) {
|
|
28
|
+
try {
|
|
29
|
+
const filename = `metrics-${snapshot.timestamp}.json`;
|
|
30
|
+
const filepath = path_1.default.join(this.storageDir, filename);
|
|
31
|
+
await fs_1.default.promises.writeFile(filepath, JSON.stringify(snapshot, null, 2), 'utf8');
|
|
32
|
+
// Clean up old files periodically (every 10th write)
|
|
33
|
+
if (snapshot.timestamp % 10 === 0) {
|
|
34
|
+
await this.cleanupOldFiles();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.error('Failed to store metrics snapshot:', error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get recent snapshots from disk (for dashboard/analysis)
|
|
43
|
+
*/
|
|
44
|
+
async getRecentSnapshots(count = 60) {
|
|
45
|
+
try {
|
|
46
|
+
const files = await this.getSnapshotFiles();
|
|
47
|
+
const recentFiles = files.slice(-count);
|
|
48
|
+
const snapshots = [];
|
|
49
|
+
for (const file of recentFiles) {
|
|
50
|
+
try {
|
|
51
|
+
const content = await fs_1.default.promises.readFile(path_1.default.join(this.storageDir, file), 'utf8');
|
|
52
|
+
snapshots.push(JSON.parse(content));
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
console.warn(`Failed to read metrics file ${file}:`, error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return snapshots.sort((a, b) => a.timestamp - b.timestamp);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
console.error('Failed to load recent snapshots:', error);
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get snapshots within a time range
|
|
67
|
+
*/
|
|
68
|
+
async getSnapshotsInRange(startTime, endTime) {
|
|
69
|
+
try {
|
|
70
|
+
const files = await this.getSnapshotFiles();
|
|
71
|
+
const snapshots = [];
|
|
72
|
+
for (const file of files) {
|
|
73
|
+
const timestamp = this.extractTimestampFromFilename(file);
|
|
74
|
+
if (timestamp >= startTime && timestamp <= endTime) {
|
|
75
|
+
try {
|
|
76
|
+
const content = await fs_1.default.promises.readFile(path_1.default.join(this.storageDir, file), 'utf8');
|
|
77
|
+
snapshots.push(JSON.parse(content));
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.warn(`Failed to read metrics file ${file}:`, error);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return snapshots.sort((a, b) => a.timestamp - b.timestamp);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
console.error('Failed to load snapshots in range:', error);
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get storage statistics
|
|
93
|
+
*/
|
|
94
|
+
async getStorageStats() {
|
|
95
|
+
try {
|
|
96
|
+
const files = await this.getSnapshotFiles();
|
|
97
|
+
if (files.length === 0) {
|
|
98
|
+
return { fileCount: 0, totalSizeKB: 0 };
|
|
99
|
+
}
|
|
100
|
+
let totalSize = 0;
|
|
101
|
+
for (const file of files) {
|
|
102
|
+
try {
|
|
103
|
+
const stat = await fs_1.default.promises.stat(path_1.default.join(this.storageDir, file));
|
|
104
|
+
totalSize += stat.size;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Ignore individual file errors
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const timestamps = files.map(f => this.extractTimestampFromFilename(f)).filter(t => t > 0);
|
|
111
|
+
return {
|
|
112
|
+
fileCount: files.length,
|
|
113
|
+
totalSizeKB: Math.round(totalSize / 1024),
|
|
114
|
+
oldestTimestamp: timestamps.length > 0 ? Math.min(...timestamps) : undefined,
|
|
115
|
+
newestTimestamp: timestamps.length > 0 ? Math.max(...timestamps) : undefined,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
console.error('Failed to get storage stats:', error);
|
|
120
|
+
return { fileCount: 0, totalSizeKB: 0 };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Clear all stored metrics
|
|
125
|
+
*/
|
|
126
|
+
async clearAll() {
|
|
127
|
+
try {
|
|
128
|
+
const files = await this.getSnapshotFiles();
|
|
129
|
+
await Promise.all(files.map(file => fs_1.default.promises.unlink(path_1.default.join(this.storageDir, file)).catch(() => { })));
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
console.error('Failed to clear metrics storage:', error);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async ensureStorageDir() {
|
|
136
|
+
try {
|
|
137
|
+
await fs_1.default.promises.mkdir(this.storageDir, { recursive: true });
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
console.error('Failed to create metrics storage directory:', error);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async getSnapshotFiles() {
|
|
144
|
+
try {
|
|
145
|
+
const files = await fs_1.default.promises.readdir(this.storageDir);
|
|
146
|
+
return files
|
|
147
|
+
.filter(f => f.startsWith('metrics-') && f.endsWith('.json'))
|
|
148
|
+
.sort(); // Chronological order due to timestamp-based naming
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
extractTimestampFromFilename(filename) {
|
|
155
|
+
const match = filename.match(/^metrics-(\d+)\.json$/);
|
|
156
|
+
return match ? parseInt(match[1], 10) : 0;
|
|
157
|
+
}
|
|
158
|
+
async cleanupOldFiles() {
|
|
159
|
+
try {
|
|
160
|
+
const files = await this.getSnapshotFiles();
|
|
161
|
+
const now = Date.now();
|
|
162
|
+
const cutoffTime = now - (this.retentionMinutes * 60 * 1000);
|
|
163
|
+
// Remove files older than retention period
|
|
164
|
+
const expiredFiles = files.filter(file => {
|
|
165
|
+
const timestamp = this.extractTimestampFromFilename(file);
|
|
166
|
+
return timestamp < cutoffTime;
|
|
167
|
+
});
|
|
168
|
+
// Remove excess files (keep only maxFiles most recent)
|
|
169
|
+
let filesToDelete = expiredFiles;
|
|
170
|
+
if (files.length > this.maxFiles) {
|
|
171
|
+
const excessCount = files.length - this.maxFiles;
|
|
172
|
+
const oldestFiles = files.slice(0, excessCount);
|
|
173
|
+
filesToDelete = [...new Set([...expiredFiles, ...oldestFiles])];
|
|
174
|
+
}
|
|
175
|
+
if (filesToDelete.length > 0) {
|
|
176
|
+
await Promise.all(filesToDelete.map(file => fs_1.default.promises.unlink(path_1.default.join(this.storageDir, file)).catch(() => { })));
|
|
177
|
+
console.log(`Cleaned up ${filesToDelete.length} old metrics files`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
console.error('Failed to cleanup old metrics files:', error);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
exports.FileMetricsStorage = FileMetricsStorage;
|
|
186
|
+
/**
|
|
187
|
+
* Global file storage instance
|
|
188
|
+
*/
|
|
189
|
+
let globalFileStorage = null;
|
|
190
|
+
function getFileMetricsStorage(options) {
|
|
191
|
+
if (!globalFileStorage) {
|
|
192
|
+
globalFileStorage = new FileMetricsStorage(options);
|
|
193
|
+
}
|
|
194
|
+
return globalFileStorage;
|
|
195
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HttpTransport - HTTP/JSON-RPC transport for the Index Server leader.
|
|
3
|
+
*
|
|
4
|
+
* **EXPERIMENTAL** — APIs, configuration, and behavior may change.
|
|
5
|
+
*
|
|
6
|
+
* When running as leader, the server exposes an HTTP endpoint that thin clients
|
|
7
|
+
* can forward JSON-RPC requests to. This reuses the existing handler registry
|
|
8
|
+
* so all MCP tools work over HTTP without any handler changes.
|
|
9
|
+
*
|
|
10
|
+
* Endpoints:
|
|
11
|
+
* POST /mcp/rpc - JSON-RPC 2.0 request/response
|
|
12
|
+
* GET /mcp/health - Health check for thin clients
|
|
13
|
+
* GET /mcp/leader - Leader info (PID, port, role)
|
|
14
|
+
*/
|
|
15
|
+
import { Router } from 'express';
|
|
16
|
+
export interface HttpTransportOptions {
|
|
17
|
+
/** Handler lookup function (defaults to registry getHandler) */
|
|
18
|
+
handlerLookup?: (method: string) => ((params: unknown) => Promise<unknown>) | undefined;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Create an Express router for the MCP HTTP transport.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createMcpTransportRoutes(options?: HttpTransportOptions): Router;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* HttpTransport - HTTP/JSON-RPC transport for the Index Server leader.
|
|
4
|
+
*
|
|
5
|
+
* **EXPERIMENTAL** — APIs, configuration, and behavior may change.
|
|
6
|
+
*
|
|
7
|
+
* When running as leader, the server exposes an HTTP endpoint that thin clients
|
|
8
|
+
* can forward JSON-RPC requests to. This reuses the existing handler registry
|
|
9
|
+
* so all MCP tools work over HTTP without any handler changes.
|
|
10
|
+
*
|
|
11
|
+
* Endpoints:
|
|
12
|
+
* POST /mcp/rpc - JSON-RPC 2.0 request/response
|
|
13
|
+
* GET /mcp/health - Health check for thin clients
|
|
14
|
+
* GET /mcp/leader - Leader info (PID, port, role)
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
+
var ownKeys = function(o) {
|
|
34
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
+
var ar = [];
|
|
36
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
+
return ar;
|
|
38
|
+
};
|
|
39
|
+
return ownKeys(o);
|
|
40
|
+
};
|
|
41
|
+
return function (mod) {
|
|
42
|
+
if (mod && mod.__esModule) return mod;
|
|
43
|
+
var result = {};
|
|
44
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
+
__setModuleDefault(result, mod);
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
})();
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.createMcpTransportRoutes = createMcpTransportRoutes;
|
|
51
|
+
const express_1 = __importStar(require("express"));
|
|
52
|
+
const registry_1 = require("../../server/registry");
|
|
53
|
+
/**
|
|
54
|
+
* Create an Express router for the MCP HTTP transport.
|
|
55
|
+
*/
|
|
56
|
+
function createMcpTransportRoutes(options = {}) {
|
|
57
|
+
const router = (0, express_1.Router)();
|
|
58
|
+
const lookup = options.handlerLookup ?? registry_1.getLocalHandler;
|
|
59
|
+
// Health check for thin client connectivity probing
|
|
60
|
+
router.get('/health', (_req, res) => {
|
|
61
|
+
res.json({
|
|
62
|
+
status: 'ok',
|
|
63
|
+
pid: process.pid,
|
|
64
|
+
uptime: process.uptime(),
|
|
65
|
+
timestamp: new Date().toISOString(),
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
// Leader info endpoint
|
|
69
|
+
router.get('/leader', (_req, res) => {
|
|
70
|
+
res.json({
|
|
71
|
+
pid: process.pid,
|
|
72
|
+
port: (res.req.socket.localPort || 0),
|
|
73
|
+
role: 'leader',
|
|
74
|
+
timestamp: new Date().toISOString(),
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
// JSON-RPC 2.0 endpoint
|
|
78
|
+
router.post('/rpc', express_1.default.json({ limit: '1mb' }), async (req, res) => {
|
|
79
|
+
const body = req.body;
|
|
80
|
+
// Validate JSON-RPC structure
|
|
81
|
+
if (!body || body.jsonrpc !== '2.0' || !body.method) {
|
|
82
|
+
return res.status(400).json({
|
|
83
|
+
jsonrpc: '2.0',
|
|
84
|
+
error: { code: -32600, message: 'Invalid Request: missing jsonrpc or method' },
|
|
85
|
+
id: body?.id ?? null,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const { method, params, id } = body;
|
|
89
|
+
// Look up handler
|
|
90
|
+
const handler = lookup(method);
|
|
91
|
+
if (!handler) {
|
|
92
|
+
return res.status(404).json({
|
|
93
|
+
jsonrpc: '2.0',
|
|
94
|
+
error: { code: -32601, message: `Method not found: ${method}` },
|
|
95
|
+
id: id ?? null,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
const result = await handler(params ?? {});
|
|
100
|
+
res.json({
|
|
101
|
+
jsonrpc: '2.0',
|
|
102
|
+
result,
|
|
103
|
+
id: id ?? null,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
const message = error instanceof Error ? error.message : 'Internal error';
|
|
108
|
+
res.status(500).json({
|
|
109
|
+
jsonrpc: '2.0',
|
|
110
|
+
error: { code: -32603, message },
|
|
111
|
+
id: id ?? null,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return router;
|
|
116
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InstanceManager - Discovers running Index Server dashboard instances.
|
|
3
|
+
*
|
|
4
|
+
* Each dashboard writes a small JSON port file on startup and removes it on
|
|
5
|
+
* shutdown. Other instances (and the `/api/instances` endpoint) read these
|
|
6
|
+
* files to present a list of all active servers the user can switch between.
|
|
7
|
+
*
|
|
8
|
+
* Port file location: `<stateDir>/dashboard-<pid>.json`
|
|
9
|
+
* Default stateDir: `<cwd>/data/state` (override via INDEX_SERVER_STATE_DIR)
|
|
10
|
+
*/
|
|
11
|
+
export interface PortFileEntry {
|
|
12
|
+
pid: number;
|
|
13
|
+
port: number;
|
|
14
|
+
host: string;
|
|
15
|
+
startedAt: string;
|
|
16
|
+
protocol?: 'http' | 'https';
|
|
17
|
+
}
|
|
18
|
+
export interface InstanceInfo extends PortFileEntry {
|
|
19
|
+
current: boolean;
|
|
20
|
+
alive: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Write a port file for the current process.
|
|
24
|
+
* Called once when the dashboard HTTP server starts listening.
|
|
25
|
+
*/
|
|
26
|
+
export declare function writePortFile(port: number, host: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* Remove the port file for the current process.
|
|
29
|
+
* Called during graceful shutdown.
|
|
30
|
+
*/
|
|
31
|
+
export declare function removePortFile(): void;
|
|
32
|
+
/**
|
|
33
|
+
* Remove stale port files for processes that no longer exist.
|
|
34
|
+
* Called on startup to clean up after crashes.
|
|
35
|
+
*/
|
|
36
|
+
export declare function cleanStalePortFiles(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Get a list of all active dashboard instances by reading port files.
|
|
39
|
+
* Stale files (dead PIDs) are cleaned up automatically.
|
|
40
|
+
*/
|
|
41
|
+
export declare function getActiveInstances(): InstanceInfo[];
|
|
42
|
+
/**
|
|
43
|
+
* Validate all registered instances by HTTP health check.
|
|
44
|
+
* Removes port files for instances that are alive (PID exists) but no longer
|
|
45
|
+
* respond on their registered port -- i.e., orphaned processes whose dashboard
|
|
46
|
+
* HTTP server has shut down or whose PID was recycled.
|
|
47
|
+
*
|
|
48
|
+
* Called periodically from a background timer (every ~30s). Skips the current
|
|
49
|
+
* process (always considered valid).
|
|
50
|
+
*/
|
|
51
|
+
export declare function validateInstances(): Promise<void>;
|
|
52
|
+
/** Reset the cached state dir (useful for testing). */
|
|
53
|
+
export declare function _resetStateDir(): void;
|