@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,268 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LeaderElection - Manages leader/follower roles for multi-instance MCP servers.
|
|
4
|
+
*
|
|
5
|
+
* **EXPERIMENTAL** — APIs, configuration, and behavior may change.
|
|
6
|
+
*
|
|
7
|
+
* Uses a lock file + PID-based election strategy:
|
|
8
|
+
* - Leader is the instance that successfully acquires the lock file
|
|
9
|
+
* - On leader death, the surviving instance with the lowest PID promotes
|
|
10
|
+
* - Heartbeat mechanism keeps leader.lock fresh (stale = dead leader)
|
|
11
|
+
*
|
|
12
|
+
* Lock file location: `<stateDir>/leader.lock`
|
|
13
|
+
*/
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.LeaderElection = void 0;
|
|
19
|
+
const fs_1 = __importDefault(require("fs"));
|
|
20
|
+
const path_1 = __importDefault(require("path"));
|
|
21
|
+
const events_1 = require("events");
|
|
22
|
+
const LOCK_FILE = 'leader.lock';
|
|
23
|
+
const DEFAULT_HEARTBEAT_MS = 5000;
|
|
24
|
+
const DEFAULT_STALE_MS = 15000;
|
|
25
|
+
class LeaderElection extends events_1.EventEmitter {
|
|
26
|
+
stateDir;
|
|
27
|
+
port;
|
|
28
|
+
host;
|
|
29
|
+
heartbeatIntervalMs;
|
|
30
|
+
staleThresholdMs;
|
|
31
|
+
_role = 'candidate';
|
|
32
|
+
heartbeatTimer = null;
|
|
33
|
+
watchTimer = null;
|
|
34
|
+
_leaderInfo = null;
|
|
35
|
+
_stopped = false;
|
|
36
|
+
constructor(options) {
|
|
37
|
+
super();
|
|
38
|
+
this.stateDir = options.stateDir;
|
|
39
|
+
this.port = options.port;
|
|
40
|
+
this.host = options.host;
|
|
41
|
+
this.heartbeatIntervalMs = options.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_MS;
|
|
42
|
+
this.staleThresholdMs = options.staleThresholdMs ?? DEFAULT_STALE_MS;
|
|
43
|
+
}
|
|
44
|
+
get role() { return this._role; }
|
|
45
|
+
get leaderInfo() { return this._leaderInfo; }
|
|
46
|
+
get lockFilePath() { return path_1.default.join(this.stateDir, LOCK_FILE); }
|
|
47
|
+
/**
|
|
48
|
+
* Attempt to become leader via atomic lock file creation.
|
|
49
|
+
* Returns true if this instance is now the leader.
|
|
50
|
+
*/
|
|
51
|
+
tryAcquireLock() {
|
|
52
|
+
this.ensureStateDir();
|
|
53
|
+
const lockPath = this.lockFilePath;
|
|
54
|
+
try {
|
|
55
|
+
// O_CREAT | O_EXCL = fail if file exists (atomic create)
|
|
56
|
+
const fd = fs_1.default.openSync(lockPath, fs_1.default.constants.O_CREAT | fs_1.default.constants.O_EXCL | fs_1.default.constants.O_WRONLY);
|
|
57
|
+
const entry = this.buildLockEntry();
|
|
58
|
+
fs_1.default.writeSync(fd, JSON.stringify(entry, null, 2));
|
|
59
|
+
fs_1.default.closeSync(fd);
|
|
60
|
+
this._role = 'leader';
|
|
61
|
+
this._leaderInfo = entry;
|
|
62
|
+
this.emit('promoted', entry);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Lock file exists — check if holder is alive
|
|
67
|
+
return this.handleExistingLock();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Check existing lock file. If holder is dead or stale, try to take over.
|
|
72
|
+
*/
|
|
73
|
+
handleExistingLock() {
|
|
74
|
+
const lockPath = this.lockFilePath;
|
|
75
|
+
let entry;
|
|
76
|
+
try {
|
|
77
|
+
const raw = fs_1.default.readFileSync(lockPath, 'utf8');
|
|
78
|
+
entry = JSON.parse(raw);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Corrupt lock file — remove and retry
|
|
82
|
+
try {
|
|
83
|
+
fs_1.default.unlinkSync(lockPath);
|
|
84
|
+
}
|
|
85
|
+
catch { /* ignore */ }
|
|
86
|
+
return this.tryAcquireLock();
|
|
87
|
+
}
|
|
88
|
+
if (!this.isProcessAlive(entry.pid)) {
|
|
89
|
+
// Leader is dead — remove lock and retry
|
|
90
|
+
try {
|
|
91
|
+
fs_1.default.unlinkSync(lockPath);
|
|
92
|
+
}
|
|
93
|
+
catch { /* ignore */ }
|
|
94
|
+
return this.tryAcquireLock();
|
|
95
|
+
}
|
|
96
|
+
// Check if heartbeat is stale
|
|
97
|
+
const heartbeatAge = Date.now() - new Date(entry.heartbeat).getTime();
|
|
98
|
+
if (heartbeatAge > this.staleThresholdMs) {
|
|
99
|
+
// Leader heartbeat is stale — assume dead
|
|
100
|
+
try {
|
|
101
|
+
fs_1.default.unlinkSync(lockPath);
|
|
102
|
+
}
|
|
103
|
+
catch { /* ignore */ }
|
|
104
|
+
return this.tryAcquireLock();
|
|
105
|
+
}
|
|
106
|
+
// Leader is alive and fresh — become follower
|
|
107
|
+
this._role = 'follower';
|
|
108
|
+
this._leaderInfo = entry;
|
|
109
|
+
this.emit('following', entry);
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Start the election process and heartbeat/watch timers.
|
|
114
|
+
*/
|
|
115
|
+
start() {
|
|
116
|
+
this._stopped = false;
|
|
117
|
+
const isLeader = this.tryAcquireLock();
|
|
118
|
+
if (isLeader) {
|
|
119
|
+
this.startHeartbeat();
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
this.startWatcher();
|
|
123
|
+
}
|
|
124
|
+
return this._role;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Stop all timers and release the lock if leader.
|
|
128
|
+
*/
|
|
129
|
+
stop() {
|
|
130
|
+
this._stopped = true;
|
|
131
|
+
if (this.heartbeatTimer) {
|
|
132
|
+
clearInterval(this.heartbeatTimer);
|
|
133
|
+
this.heartbeatTimer = null;
|
|
134
|
+
}
|
|
135
|
+
if (this.watchTimer) {
|
|
136
|
+
clearInterval(this.watchTimer);
|
|
137
|
+
this.watchTimer = null;
|
|
138
|
+
}
|
|
139
|
+
if (this._role === 'leader') {
|
|
140
|
+
this.releaseLock();
|
|
141
|
+
}
|
|
142
|
+
this._role = 'candidate';
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Update the heartbeat timestamp in the lock file (leader only).
|
|
146
|
+
* Uses atomic write-to-temp-then-rename to prevent corruption if
|
|
147
|
+
* the process dies mid-write.
|
|
148
|
+
*/
|
|
149
|
+
updateHeartbeat() {
|
|
150
|
+
if (this._role !== 'leader')
|
|
151
|
+
return;
|
|
152
|
+
const lockPath = this.lockFilePath;
|
|
153
|
+
const tmpPath = lockPath + '.tmp';
|
|
154
|
+
try {
|
|
155
|
+
const entry = this.buildLockEntry();
|
|
156
|
+
fs_1.default.writeFileSync(tmpPath, JSON.stringify(entry, null, 2), 'utf8');
|
|
157
|
+
fs_1.default.renameSync(tmpPath, lockPath);
|
|
158
|
+
this._leaderInfo = entry;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// Clean up temp file on failure
|
|
162
|
+
try {
|
|
163
|
+
fs_1.default.unlinkSync(tmpPath);
|
|
164
|
+
}
|
|
165
|
+
catch { /* ignore */ }
|
|
166
|
+
// Lost the lock file -- try to re-acquire
|
|
167
|
+
this.tryAcquireLock();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Remove the lock file (leader relinquishing).
|
|
172
|
+
*/
|
|
173
|
+
releaseLock() {
|
|
174
|
+
try {
|
|
175
|
+
const lockPath = this.lockFilePath;
|
|
176
|
+
if (fs_1.default.existsSync(lockPath)) {
|
|
177
|
+
const raw = fs_1.default.readFileSync(lockPath, 'utf8');
|
|
178
|
+
const entry = JSON.parse(raw);
|
|
179
|
+
// Only remove if we own it
|
|
180
|
+
if (entry.pid === process.pid) {
|
|
181
|
+
fs_1.default.unlinkSync(lockPath);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
// Best-effort
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Check if the current leader is still alive.
|
|
191
|
+
*/
|
|
192
|
+
isLeaderAlive() {
|
|
193
|
+
if (this._role === 'leader')
|
|
194
|
+
return true;
|
|
195
|
+
if (!this._leaderInfo)
|
|
196
|
+
return false;
|
|
197
|
+
return this.isProcessAlive(this._leaderInfo.pid);
|
|
198
|
+
}
|
|
199
|
+
startHeartbeat() {
|
|
200
|
+
this.heartbeatTimer = setInterval(() => {
|
|
201
|
+
if (this._stopped)
|
|
202
|
+
return;
|
|
203
|
+
this.updateHeartbeat();
|
|
204
|
+
}, this.heartbeatIntervalMs);
|
|
205
|
+
}
|
|
206
|
+
startWatcher() {
|
|
207
|
+
this.watchTimer = setInterval(() => {
|
|
208
|
+
if (this._stopped)
|
|
209
|
+
return;
|
|
210
|
+
if (!this.isLeaderAlive() || this.isLeaderStale()) {
|
|
211
|
+
// Leader is dead or stale — attempt promotion
|
|
212
|
+
this.emit('leader-lost', this._leaderInfo);
|
|
213
|
+
const promoted = this.tryAcquireLock();
|
|
214
|
+
if (promoted) {
|
|
215
|
+
if (this.watchTimer) {
|
|
216
|
+
clearInterval(this.watchTimer);
|
|
217
|
+
this.watchTimer = null;
|
|
218
|
+
}
|
|
219
|
+
this.startHeartbeat();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}, this.heartbeatIntervalMs);
|
|
223
|
+
}
|
|
224
|
+
isLeaderStale() {
|
|
225
|
+
try {
|
|
226
|
+
const raw = fs_1.default.readFileSync(this.lockFilePath, 'utf8');
|
|
227
|
+
const entry = JSON.parse(raw);
|
|
228
|
+
const heartbeatTime = new Date(entry.heartbeat).getTime();
|
|
229
|
+
// Guard against clock drift or invalid timestamps
|
|
230
|
+
if (isNaN(heartbeatTime))
|
|
231
|
+
return true;
|
|
232
|
+
const age = Date.now() - heartbeatTime;
|
|
233
|
+
// Negative age means clock skew -- treat as fresh to avoid
|
|
234
|
+
// premature stale detection across machines with clock drift
|
|
235
|
+
if (age < 0)
|
|
236
|
+
return false;
|
|
237
|
+
return age > this.staleThresholdMs;
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
return true; // Can't read = stale
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
buildLockEntry() {
|
|
244
|
+
const now = new Date().toISOString();
|
|
245
|
+
return {
|
|
246
|
+
pid: process.pid,
|
|
247
|
+
port: this.port,
|
|
248
|
+
host: this.host,
|
|
249
|
+
startedAt: this._leaderInfo?.startedAt ?? now,
|
|
250
|
+
heartbeat: now,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
ensureStateDir() {
|
|
254
|
+
if (!fs_1.default.existsSync(this.stateDir)) {
|
|
255
|
+
fs_1.default.mkdirSync(this.stateDir, { recursive: true });
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
isProcessAlive(pid) {
|
|
259
|
+
try {
|
|
260
|
+
process.kill(pid, 0);
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
exports.LeaderElection = LeaderElection;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MetricsCollector — coordinator class (Phase 1–4 Dashboard Foundation).
|
|
3
|
+
*
|
|
4
|
+
* Owns all mutable metrics state and delegates:
|
|
5
|
+
* - pure math to metricsAggregation.ts
|
|
6
|
+
* - output serialisation to metricsSerializer.ts
|
|
7
|
+
*/
|
|
8
|
+
import { BufferRingStats } from '../../utils/BufferRing.js';
|
|
9
|
+
export type { ToolMetrics, ServerMetrics, ConnectionMetrics, MetricsSnapshot, MetricsTimeSeriesEntry, ToolCallEvent, MetricsBufferConfig, ChartDataPoint, ToolUsageChartData, PerformanceChartData, RealtimeMetrics, RealtimeStreamingData, SystemHealth, EnhancedPerformanceMetrics, StreamingStats, ActivityEvent, AdvancedAnalytics, HourlyStats, ToolUsageStats, ErrorAnalysis, PerformanceTrend, PredictionData, Anomaly, Alert, MetricsCollectorOptions, ResourceSample, } from './metricsAggregation.js';
|
|
10
|
+
import { type ToolMetrics, type MetricsSnapshot, type MetricsTimeSeriesEntry, type ToolCallEvent, type RealtimeMetrics, type RealtimeStreamingData, type SystemHealth, type EnhancedPerformanceMetrics, type AdvancedAnalytics, type Alert, type MetricsCollectorOptions, type ResourceSample } from './metricsAggregation.js';
|
|
11
|
+
import type { ToolUsageChartData, PerformanceChartData, ToolUsageStats } from './metricsAggregation.js';
|
|
12
|
+
export declare class MetricsCollector {
|
|
13
|
+
private tools;
|
|
14
|
+
private resourceSamples;
|
|
15
|
+
private lastCpuUsageSample;
|
|
16
|
+
private lastCpuSampleTime;
|
|
17
|
+
private snapshots;
|
|
18
|
+
private connections;
|
|
19
|
+
private disconnectedCount;
|
|
20
|
+
private totalSessionTime;
|
|
21
|
+
private sessionStartTimes;
|
|
22
|
+
private startTime;
|
|
23
|
+
private options;
|
|
24
|
+
private collectTimer?;
|
|
25
|
+
private lastCpuUsage?;
|
|
26
|
+
private recentAlerts;
|
|
27
|
+
private activeConnections;
|
|
28
|
+
private recentCallTimestamps;
|
|
29
|
+
private static readonly MAX_RECENT_CALLS;
|
|
30
|
+
private static readonly MAX_MEMORY_SNAPSHOTS;
|
|
31
|
+
private static readonly MAX_TOOL_METRICS;
|
|
32
|
+
private fileStorage;
|
|
33
|
+
private useFileStorage;
|
|
34
|
+
private historicalSnapshots;
|
|
35
|
+
private toolCallEvents;
|
|
36
|
+
private _lastToolPersist;
|
|
37
|
+
private _pendingToolPersist;
|
|
38
|
+
private performanceMetrics;
|
|
39
|
+
private bufferConfig;
|
|
40
|
+
private appendMode;
|
|
41
|
+
private appendLogPath;
|
|
42
|
+
private pendingAppendEvents;
|
|
43
|
+
private lastAppendFlush;
|
|
44
|
+
private lastAppendCompact;
|
|
45
|
+
private appendChunkSize;
|
|
46
|
+
private appendFlushMs;
|
|
47
|
+
private appendCompactMs;
|
|
48
|
+
constructor(options?: MetricsCollectorOptions);
|
|
49
|
+
/**
|
|
50
|
+
* Record a tool call event
|
|
51
|
+
*/
|
|
52
|
+
recordToolCall(toolName: string, success: boolean, responseTimeMs: number, errorType?: string, clientId?: string): void;
|
|
53
|
+
/** Flush tool call events (append or snapshot) */
|
|
54
|
+
private flushToolCallEvents;
|
|
55
|
+
/**
|
|
56
|
+
* Record client connection
|
|
57
|
+
*/
|
|
58
|
+
recordConnection(clientId: string): void;
|
|
59
|
+
/**
|
|
60
|
+
* Record client disconnection
|
|
61
|
+
*/
|
|
62
|
+
recordDisconnection(clientId: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Get current metrics snapshot
|
|
65
|
+
*/
|
|
66
|
+
getCurrentSnapshot(): MetricsSnapshot;
|
|
67
|
+
/**
|
|
68
|
+
* Get historical snapshots (from memory for recent, or from files for historical)
|
|
69
|
+
*/
|
|
70
|
+
getSnapshots(count?: number): MetricsSnapshot[];
|
|
71
|
+
/**
|
|
72
|
+
* Get snapshots from file storage (for historical analysis)
|
|
73
|
+
*/
|
|
74
|
+
getHistoricalSnapshots(count?: number): Promise<MetricsSnapshot[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Get snapshots within a specific time range from files
|
|
77
|
+
*/
|
|
78
|
+
getSnapshotsInRange(startTime: number, endTime: number): Promise<MetricsSnapshot[]>;
|
|
79
|
+
/**
|
|
80
|
+
* Get file storage statistics
|
|
81
|
+
*/
|
|
82
|
+
getStorageStats(): Promise<{
|
|
83
|
+
fileCount: number;
|
|
84
|
+
totalSizeKB: number;
|
|
85
|
+
oldestTimestamp?: number;
|
|
86
|
+
newestTimestamp?: number;
|
|
87
|
+
memorySnapshots: number;
|
|
88
|
+
}>;
|
|
89
|
+
/**
|
|
90
|
+
* Get tool-specific metrics
|
|
91
|
+
*/
|
|
92
|
+
getToolMetrics(toolName?: string): {
|
|
93
|
+
[toolName: string]: ToolMetrics;
|
|
94
|
+
} | ToolMetrics | null;
|
|
95
|
+
/**
|
|
96
|
+
* Clear all metrics data (memory and files)
|
|
97
|
+
*/
|
|
98
|
+
clearMetrics(): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Clear only memory data (keep files)
|
|
101
|
+
*/
|
|
102
|
+
clearMemoryMetrics(): void;
|
|
103
|
+
/**
|
|
104
|
+
* Stop metrics collection
|
|
105
|
+
*/
|
|
106
|
+
stop(): void;
|
|
107
|
+
private startCollection;
|
|
108
|
+
private takeSnapshot;
|
|
109
|
+
private getVersion;
|
|
110
|
+
getRealtimeMetrics(): RealtimeMetrics;
|
|
111
|
+
getToolUsageChartData(minutes?: number): ToolUsageChartData[];
|
|
112
|
+
getPerformanceChartData(minutes?: number): PerformanceChartData;
|
|
113
|
+
getTimeRangeMetrics(range: '1h' | '6h' | '24h' | '7d' | '30d'): MetricsSnapshot[];
|
|
114
|
+
getRealtimeStreamingData(): RealtimeStreamingData;
|
|
115
|
+
getSystemHealth(): SystemHealth;
|
|
116
|
+
getDetailedPerformanceMetrics(): EnhancedPerformanceMetrics;
|
|
117
|
+
getAdvancedAnalytics(timeRange?: string): AdvancedAnalytics;
|
|
118
|
+
/**
|
|
119
|
+
* Generate real-time alert
|
|
120
|
+
*/
|
|
121
|
+
generateRealTimeAlert(type: string, severity: string, message: string, value: number, threshold: number): Alert;
|
|
122
|
+
/**
|
|
123
|
+
* Get active alerts
|
|
124
|
+
*/
|
|
125
|
+
getActiveAlerts(): Alert[];
|
|
126
|
+
/**
|
|
127
|
+
* Resolve alert by ID
|
|
128
|
+
*/
|
|
129
|
+
resolveAlert(alertId: string): boolean;
|
|
130
|
+
private sampleResources;
|
|
131
|
+
getResourceHistory(limit?: number): {
|
|
132
|
+
samples: ResourceSample[];
|
|
133
|
+
trend?: {
|
|
134
|
+
cpuSlope: number;
|
|
135
|
+
memSlope: number;
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
/** Remove stale / low-activity tool entries to prevent unbounded map growth. */
|
|
139
|
+
private cleanupOldToolMetrics;
|
|
140
|
+
/**
|
|
141
|
+
* Get historical metrics data for charting
|
|
142
|
+
*/
|
|
143
|
+
getHistoricalMetrics(minutes?: number): MetricsTimeSeriesEntry[];
|
|
144
|
+
/**
|
|
145
|
+
* Get recent tool call events for analysis
|
|
146
|
+
*/
|
|
147
|
+
getRecentToolCallEvents(minutes?: number): ToolCallEvent[];
|
|
148
|
+
/**
|
|
149
|
+
* Get performance metrics time series for dashboard charts (BufferRing-enhanced)
|
|
150
|
+
*/
|
|
151
|
+
getPerformanceTimeSeriesData(minutes?: number): PerformanceChartData;
|
|
152
|
+
/**
|
|
153
|
+
* Get tool usage analytics from historical data
|
|
154
|
+
*/
|
|
155
|
+
getToolUsageAnalytics(minutes?: number): ToolUsageStats[];
|
|
156
|
+
/**
|
|
157
|
+
* Get BufferRing statistics for monitoring
|
|
158
|
+
*/
|
|
159
|
+
getBufferRingStats(): {
|
|
160
|
+
historicalSnapshots: BufferRingStats;
|
|
161
|
+
toolCallEvents: BufferRingStats;
|
|
162
|
+
performanceMetrics: BufferRingStats;
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Export metrics data for backup/analysis
|
|
166
|
+
*/
|
|
167
|
+
exportMetricsData(options?: {
|
|
168
|
+
includeHistorical?: boolean;
|
|
169
|
+
includeEvents?: boolean;
|
|
170
|
+
includePerformance?: boolean;
|
|
171
|
+
}): {
|
|
172
|
+
timestamp: number;
|
|
173
|
+
currentSnapshot: MetricsSnapshot;
|
|
174
|
+
bufferStats: {
|
|
175
|
+
historicalSnapshots: BufferRingStats;
|
|
176
|
+
toolCallEvents: BufferRingStats;
|
|
177
|
+
performanceMetrics: BufferRingStats;
|
|
178
|
+
};
|
|
179
|
+
historicalSnapshots?: MetricsTimeSeriesEntry[];
|
|
180
|
+
toolCallEvents?: ToolCallEvent[];
|
|
181
|
+
performanceMetrics?: Array<{
|
|
182
|
+
timestamp: number;
|
|
183
|
+
responseTime: number;
|
|
184
|
+
throughput: number;
|
|
185
|
+
errorRate: number;
|
|
186
|
+
}>;
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* Clear all BufferRing data (for maintenance)
|
|
190
|
+
*/
|
|
191
|
+
clearBufferedData(): void;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Get or create the global metrics collector instance
|
|
195
|
+
*/
|
|
196
|
+
export declare function getMetricsCollector(): MetricsCollector;
|
|
197
|
+
/**
|
|
198
|
+
* Set a custom metrics collector instance (useful for testing)
|
|
199
|
+
*/
|
|
200
|
+
export declare function setMetricsCollector(collector: MetricsCollector | null): void;
|