@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,336 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Instructions Management Routes
|
|
4
|
+
* Routes: GET /instructions, GET /instructions_search, GET /instructions_categories,
|
|
5
|
+
* GET /instructions/:name, POST /instructions, PUT /instructions/:name,
|
|
6
|
+
* DELETE /instructions/:name
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.createInstructionsRoutes = createInstructionsRoutes;
|
|
13
|
+
const express_1 = require("express");
|
|
14
|
+
const fs_1 = __importDefault(require("fs"));
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const runtimeConfig_js_1 = require("../../../config/runtimeConfig.js");
|
|
17
|
+
const registry_js_1 = require("../../../server/registry.js");
|
|
18
|
+
const indexContext_js_1 = require("../../../services/indexContext.js");
|
|
19
|
+
const handlers_search_js_1 = require("../../../services/handlers.search.js");
|
|
20
|
+
function resolveInstructionsDir() {
|
|
21
|
+
const config = (0, runtimeConfig_js_1.getRuntimeConfig)();
|
|
22
|
+
const configured = config.dashboard.admin.instructionsDir || config.index.baseDir;
|
|
23
|
+
return configured && configured.trim().length ? configured : path_1.default.join(process.cwd(), 'instructions');
|
|
24
|
+
}
|
|
25
|
+
function ensureInstructionsDir() {
|
|
26
|
+
const instructionsDir = resolveInstructionsDir();
|
|
27
|
+
try {
|
|
28
|
+
if (!fs_1.default.existsSync(instructionsDir))
|
|
29
|
+
fs_1.default.mkdirSync(instructionsDir, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// ignore
|
|
33
|
+
}
|
|
34
|
+
return instructionsDir;
|
|
35
|
+
}
|
|
36
|
+
function createInstructionsRoutes() {
|
|
37
|
+
const router = (0, express_1.Router)();
|
|
38
|
+
const buildSnippet = (parts, query) => {
|
|
39
|
+
const source = parts.filter((part) => typeof part === 'string' && part.trim().length > 0).join('\n');
|
|
40
|
+
if (!source)
|
|
41
|
+
return '';
|
|
42
|
+
const snippetWindow = 120;
|
|
43
|
+
const lowerSource = source.toLowerCase();
|
|
44
|
+
const lowerQuery = query.toLowerCase();
|
|
45
|
+
const matchIndex = lowerSource.indexOf(lowerQuery);
|
|
46
|
+
const start = matchIndex === -1 ? 0 : Math.max(0, matchIndex - snippetWindow);
|
|
47
|
+
const end = matchIndex === -1 ? Math.min(source.length, 240) : Math.min(source.length, matchIndex + lowerQuery.length + snippetWindow);
|
|
48
|
+
let snippet = source.slice(start, end).replace(/\s+/g, ' ').trim();
|
|
49
|
+
if (!snippet)
|
|
50
|
+
return '';
|
|
51
|
+
if (matchIndex !== -1) {
|
|
52
|
+
snippet = snippet.replace(new RegExp(query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i'), match => `**${match}**`);
|
|
53
|
+
}
|
|
54
|
+
return snippet;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* GET /api/instructions - list instruction JSON files
|
|
58
|
+
*/
|
|
59
|
+
router.get('/instructions', (_req, res) => {
|
|
60
|
+
try {
|
|
61
|
+
const instructionsDir = ensureInstructionsDir();
|
|
62
|
+
const classify = (basename) => {
|
|
63
|
+
const lower = basename.toLowerCase();
|
|
64
|
+
let category = 'general';
|
|
65
|
+
if (lower.startsWith('alpha'))
|
|
66
|
+
category = 'alpha';
|
|
67
|
+
else if (lower.startsWith('beta'))
|
|
68
|
+
category = 'beta';
|
|
69
|
+
else if (lower.includes('seed'))
|
|
70
|
+
category = 'seed';
|
|
71
|
+
else if (lower.includes('enterprise'))
|
|
72
|
+
category = 'enterprise';
|
|
73
|
+
else if (lower.includes('dispatcher'))
|
|
74
|
+
category = 'dispatcher';
|
|
75
|
+
return { category, sizeCategory: 'small' };
|
|
76
|
+
};
|
|
77
|
+
const files = fs_1.default.readdirSync(instructionsDir)
|
|
78
|
+
.filter(f => f.toLowerCase().endsWith('.json'))
|
|
79
|
+
.map(f => {
|
|
80
|
+
const abs = path_1.default.join(instructionsDir, f);
|
|
81
|
+
const stat = fs_1.default.statSync(abs);
|
|
82
|
+
const base = f.replace(/\.json$/i, '');
|
|
83
|
+
const meta = classify(base);
|
|
84
|
+
const sizeCategory = stat.size < 1024 ? 'small' : (stat.size < 5 * 1024 ? 'medium' : 'large');
|
|
85
|
+
let primaryCategory = meta.category;
|
|
86
|
+
let categories = [];
|
|
87
|
+
let semanticSummary;
|
|
88
|
+
try {
|
|
89
|
+
const raw = fs_1.default.readFileSync(abs, 'utf8');
|
|
90
|
+
if (raw.length < 1_000_000) {
|
|
91
|
+
const json = JSON.parse(raw);
|
|
92
|
+
const getProp = (obj, key) => {
|
|
93
|
+
if (obj && typeof obj === 'object' && key in obj) {
|
|
94
|
+
return obj[key];
|
|
95
|
+
}
|
|
96
|
+
return undefined;
|
|
97
|
+
};
|
|
98
|
+
const rawCats = getProp(json, 'categories');
|
|
99
|
+
if (Array.isArray(rawCats)) {
|
|
100
|
+
categories = rawCats
|
|
101
|
+
.filter((c) => typeof c === 'string')
|
|
102
|
+
.map(c => c.trim())
|
|
103
|
+
.filter(c => !!c);
|
|
104
|
+
}
|
|
105
|
+
const rawPrimary = getProp(json, 'category');
|
|
106
|
+
if (typeof rawPrimary === 'string') {
|
|
107
|
+
const c = rawPrimary.trim();
|
|
108
|
+
if (c)
|
|
109
|
+
primaryCategory = c;
|
|
110
|
+
if (c && !categories.includes(c))
|
|
111
|
+
categories.push(c);
|
|
112
|
+
}
|
|
113
|
+
const fileMeta = getProp(json, 'meta');
|
|
114
|
+
if (fileMeta && typeof fileMeta === 'object') {
|
|
115
|
+
const metaPrimary = getProp(fileMeta, 'category');
|
|
116
|
+
if (typeof metaPrimary === 'string') {
|
|
117
|
+
const c = metaPrimary.trim();
|
|
118
|
+
if (c)
|
|
119
|
+
primaryCategory = c;
|
|
120
|
+
if (c && !categories.includes(c))
|
|
121
|
+
categories.push(c);
|
|
122
|
+
}
|
|
123
|
+
const metaCats = getProp(fileMeta, 'categories');
|
|
124
|
+
if (Array.isArray(metaCats)) {
|
|
125
|
+
for (const c of metaCats) {
|
|
126
|
+
if (typeof c === 'string') {
|
|
127
|
+
const norm = c.trim();
|
|
128
|
+
if (norm && !categories.includes(norm))
|
|
129
|
+
categories.push(norm);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const metaSummary = getProp(fileMeta, 'semanticSummary');
|
|
134
|
+
if (typeof metaSummary === 'string' && metaSummary.trim())
|
|
135
|
+
semanticSummary = metaSummary.trim();
|
|
136
|
+
}
|
|
137
|
+
if (!semanticSummary) {
|
|
138
|
+
const topSummary = getProp(json, 'semanticSummary');
|
|
139
|
+
if (typeof topSummary === 'string' && topSummary.trim())
|
|
140
|
+
semanticSummary = topSummary.trim();
|
|
141
|
+
}
|
|
142
|
+
if (!semanticSummary) {
|
|
143
|
+
const desc = getProp(json, 'description');
|
|
144
|
+
if (typeof desc === 'string' && desc.trim())
|
|
145
|
+
semanticSummary = desc.trim();
|
|
146
|
+
}
|
|
147
|
+
if (!semanticSummary) {
|
|
148
|
+
const body = getProp(json, 'body');
|
|
149
|
+
if (typeof body === 'string' && body.trim()) {
|
|
150
|
+
const firstLine = body.split(/\r?\n/).map(l => l.trim()).filter(Boolean)[0];
|
|
151
|
+
if (firstLine)
|
|
152
|
+
semanticSummary = firstLine;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (semanticSummary) {
|
|
156
|
+
if (semanticSummary.length > 400)
|
|
157
|
+
semanticSummary = semanticSummary.slice(0, 400) + '…';
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// ignore parse errors; fall back to heuristic classification only
|
|
163
|
+
}
|
|
164
|
+
if (!categories.length && primaryCategory)
|
|
165
|
+
categories = [primaryCategory];
|
|
166
|
+
categories = Array.from(new Set(categories));
|
|
167
|
+
return {
|
|
168
|
+
name: base,
|
|
169
|
+
size: stat.size,
|
|
170
|
+
mtime: stat.mtimeMs,
|
|
171
|
+
category: primaryCategory,
|
|
172
|
+
categories,
|
|
173
|
+
sizeCategory,
|
|
174
|
+
semanticSummary,
|
|
175
|
+
};
|
|
176
|
+
});
|
|
177
|
+
res.json({ success: true, instructions: files, count: files.length, timestamp: Date.now() });
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
res.status(500).json({ success: false, error: 'Failed to list instructions', message: error instanceof Error ? error.message : 'Unknown error' });
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
/**
|
|
184
|
+
* GET /api/instructions_search?q=term&limit=20
|
|
185
|
+
*/
|
|
186
|
+
router.get('/instructions_search', async (req, res) => {
|
|
187
|
+
try {
|
|
188
|
+
const instructionsDir = ensureInstructionsDir();
|
|
189
|
+
const qRaw = String(req.query.q || '').trim();
|
|
190
|
+
const query = qRaw.slice(0, 256);
|
|
191
|
+
const limitRaw = parseInt(String(req.query.limit || '20'), 10);
|
|
192
|
+
const limit = Math.min(100, Math.max(1, isNaN(limitRaw) ? 20 : limitRaw));
|
|
193
|
+
if (!query || query.length < 2) {
|
|
194
|
+
return res.json({ success: true, query, count: 0, results: [], note: 'query_too_short' });
|
|
195
|
+
}
|
|
196
|
+
const searchResult = await (0, handlers_search_js_1.handleInstructionsSearch)({
|
|
197
|
+
keywords: [query],
|
|
198
|
+
mode: 'keyword',
|
|
199
|
+
limit,
|
|
200
|
+
includeCategories: true,
|
|
201
|
+
});
|
|
202
|
+
const state = (0, indexContext_js_1.ensureLoaded)();
|
|
203
|
+
const results = [];
|
|
204
|
+
for (const match of searchResult.results) {
|
|
205
|
+
try {
|
|
206
|
+
const entry = state.byId.get(match.instructionId);
|
|
207
|
+
if (!entry)
|
|
208
|
+
continue;
|
|
209
|
+
const abs = path_1.default.join(instructionsDir, `${entry.id}.json`);
|
|
210
|
+
const stat = fs_1.default.existsSync(abs) ? fs_1.default.statSync(abs) : undefined;
|
|
211
|
+
const snippet = buildSnippet([
|
|
212
|
+
entry.id,
|
|
213
|
+
entry.title,
|
|
214
|
+
entry.semanticSummary,
|
|
215
|
+
entry.categories.join(' '),
|
|
216
|
+
entry.body,
|
|
217
|
+
], query);
|
|
218
|
+
results.push({
|
|
219
|
+
name: entry.id,
|
|
220
|
+
categories: entry.categories.slice(0, 10),
|
|
221
|
+
size: stat?.size ?? Buffer.byteLength(JSON.stringify(entry), 'utf8'),
|
|
222
|
+
mtime: stat?.mtimeMs ?? Date.now(),
|
|
223
|
+
snippet,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
catch { /* skip file on error */ }
|
|
227
|
+
}
|
|
228
|
+
res.json({ success: true, query, count: results.length, results, timestamp: Date.now() });
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
console.error('[API] instructions search error:', error);
|
|
232
|
+
res.status(500).json({ success: false, error: 'search_failed', message: error instanceof Error ? error.message : 'Unknown error' });
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
/**
|
|
236
|
+
* GET /api/instructions_categories - get dynamic categories from actual instructions
|
|
237
|
+
*/
|
|
238
|
+
router.get('/instructions_categories', async (_req, res) => {
|
|
239
|
+
try {
|
|
240
|
+
const instructionHandler = (0, registry_js_1.getLocalHandler)('index_dispatch');
|
|
241
|
+
if (!instructionHandler) {
|
|
242
|
+
return res.status(500).json({ success: false, error: 'Instruction handler not available' });
|
|
243
|
+
}
|
|
244
|
+
const result = await instructionHandler({
|
|
245
|
+
action: 'categories'
|
|
246
|
+
});
|
|
247
|
+
res.json({
|
|
248
|
+
success: true,
|
|
249
|
+
categories: result?.categories || [],
|
|
250
|
+
count: result?.count || 0,
|
|
251
|
+
timestamp: Date.now()
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
res.status(500).json({
|
|
256
|
+
success: false,
|
|
257
|
+
error: 'Failed to get categories',
|
|
258
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
/**
|
|
263
|
+
* GET /api/instructions/:name - get single instruction content
|
|
264
|
+
*/
|
|
265
|
+
router.get('/instructions/:name', (req, res) => {
|
|
266
|
+
try {
|
|
267
|
+
const instructionsDir = ensureInstructionsDir();
|
|
268
|
+
const file = path_1.default.join(instructionsDir, req.params.name + '.json');
|
|
269
|
+
if (!fs_1.default.existsSync(file))
|
|
270
|
+
return res.status(404).json({ success: false, error: 'Not found' });
|
|
271
|
+
const content = JSON.parse(fs_1.default.readFileSync(file, 'utf8'));
|
|
272
|
+
res.json({ success: true, content, timestamp: Date.now() });
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
res.status(500).json({ success: false, error: 'Failed to load instruction', message: error instanceof Error ? error.message : 'Unknown error' });
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
/**
|
|
279
|
+
* POST /api/instructions - create new instruction
|
|
280
|
+
* body: { name, content }
|
|
281
|
+
*/
|
|
282
|
+
router.post('/instructions', (req, res) => {
|
|
283
|
+
try {
|
|
284
|
+
const instructionsDir = ensureInstructionsDir();
|
|
285
|
+
const { name, content } = req.body || {};
|
|
286
|
+
if (!name || !content)
|
|
287
|
+
return res.status(400).json({ success: false, error: 'Missing name or content' });
|
|
288
|
+
const safeName = String(name).replace(/[^a-zA-Z0-9-_]/g, '-');
|
|
289
|
+
const file = path_1.default.join(instructionsDir, safeName + '.json');
|
|
290
|
+
if (fs_1.default.existsSync(file))
|
|
291
|
+
return res.status(409).json({ success: false, error: 'Instruction already exists' });
|
|
292
|
+
fs_1.default.writeFileSync(file, JSON.stringify(content, null, 2));
|
|
293
|
+
res.json({ success: true, message: 'Instruction created', name: safeName, timestamp: Date.now() });
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
res.status(500).json({ success: false, error: 'Failed to create instruction', message: error instanceof Error ? error.message : 'Unknown error' });
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
/**
|
|
300
|
+
* PUT /api/instructions/:name - update existing instruction
|
|
301
|
+
*/
|
|
302
|
+
router.put('/instructions/:name', (req, res) => {
|
|
303
|
+
try {
|
|
304
|
+
const instructionsDir = ensureInstructionsDir();
|
|
305
|
+
const { content } = req.body || {};
|
|
306
|
+
const name = req.params.name;
|
|
307
|
+
if (!content)
|
|
308
|
+
return res.status(400).json({ success: false, error: 'Missing content' });
|
|
309
|
+
const file = path_1.default.join(instructionsDir, name + '.json');
|
|
310
|
+
if (!fs_1.default.existsSync(file))
|
|
311
|
+
return res.status(404).json({ success: false, error: 'Not found' });
|
|
312
|
+
fs_1.default.writeFileSync(file, JSON.stringify(content, null, 2));
|
|
313
|
+
res.json({ success: true, message: 'Instruction updated', timestamp: Date.now() });
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
res.status(500).json({ success: false, error: 'Failed to update instruction', message: error instanceof Error ? error.message : 'Unknown error' });
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
/**
|
|
320
|
+
* DELETE /api/instructions/:name - delete instruction
|
|
321
|
+
*/
|
|
322
|
+
router.delete('/instructions/:name', (req, res) => {
|
|
323
|
+
try {
|
|
324
|
+
const instructionsDir = ensureInstructionsDir();
|
|
325
|
+
const file = path_1.default.join(instructionsDir, req.params.name + '.json');
|
|
326
|
+
if (!fs_1.default.existsSync(file))
|
|
327
|
+
return res.status(404).json({ success: false, error: 'Not found' });
|
|
328
|
+
fs_1.default.unlinkSync(file);
|
|
329
|
+
res.json({ success: true, message: 'Instruction deleted', timestamp: Date.now() });
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
res.status(500).json({ success: false, error: 'Failed to delete instruction', message: error instanceof Error ? error.message : 'Unknown error' });
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
return router;
|
|
336
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Knowledge Store Routes
|
|
4
|
+
* Routes: POST /knowledge, GET /knowledge/search, GET /knowledge/:key
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.createKnowledgeRoutes = createKnowledgeRoutes;
|
|
8
|
+
const express_1 = require("express");
|
|
9
|
+
const KnowledgeStore_js_1 = require("../KnowledgeStore.js");
|
|
10
|
+
function createKnowledgeRoutes() {
|
|
11
|
+
const router = (0, express_1.Router)();
|
|
12
|
+
/**
|
|
13
|
+
* POST /api/knowledge - Store or update a knowledge entry
|
|
14
|
+
* Body: { key: string, content: string, metadata?: Record<string, unknown> }
|
|
15
|
+
*/
|
|
16
|
+
router.post('/knowledge', (req, res) => {
|
|
17
|
+
try {
|
|
18
|
+
const { key, content, metadata } = req.body;
|
|
19
|
+
if (!key || typeof key !== 'string') {
|
|
20
|
+
return res.status(400).json({ success: false, error: 'Missing required field: key (string)' });
|
|
21
|
+
}
|
|
22
|
+
if (!content || typeof content !== 'string') {
|
|
23
|
+
return res.status(400).json({ success: false, error: 'Missing required field: content (string)' });
|
|
24
|
+
}
|
|
25
|
+
const store = (0, KnowledgeStore_js_1.getKnowledgeStore)();
|
|
26
|
+
const entry = store.upsert(key, content, metadata || {});
|
|
27
|
+
res.json({ success: true, entry, timestamp: Date.now() });
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error('[API] Knowledge store error:', error);
|
|
31
|
+
res.status(500).json({
|
|
32
|
+
success: false,
|
|
33
|
+
error: 'Failed to store knowledge entry',
|
|
34
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* GET /api/knowledge/search?q=query&category=cat&limit=20
|
|
40
|
+
*/
|
|
41
|
+
router.get('/knowledge/search', (req, res) => {
|
|
42
|
+
try {
|
|
43
|
+
const query = String(req.query.q || '').trim();
|
|
44
|
+
if (!query) {
|
|
45
|
+
return res.json({ success: true, query: '', results: [], count: 0, timestamp: Date.now() });
|
|
46
|
+
}
|
|
47
|
+
const category = req.query.category ? String(req.query.category) : undefined;
|
|
48
|
+
const limit = Math.min(100, Math.max(1, parseInt(String(req.query.limit || '20'), 10) || 20));
|
|
49
|
+
const store = (0, KnowledgeStore_js_1.getKnowledgeStore)();
|
|
50
|
+
const results = store.search(query, { category, limit });
|
|
51
|
+
res.json({
|
|
52
|
+
success: true, query, category: category || null,
|
|
53
|
+
results, count: results.length, totalEntries: store.count(), timestamp: Date.now(),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error('[API] Knowledge search error:', error);
|
|
58
|
+
res.status(500).json({ success: false, error: 'Failed to search knowledge',
|
|
59
|
+
message: error instanceof Error ? error.message : 'Unknown error' });
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
/**
|
|
63
|
+
* GET /api/knowledge/:key - Get a specific knowledge entry
|
|
64
|
+
*/
|
|
65
|
+
router.get('/knowledge/:key', (req, res) => {
|
|
66
|
+
try {
|
|
67
|
+
const key = decodeURIComponent(req.params.key);
|
|
68
|
+
const store = (0, KnowledgeStore_js_1.getKnowledgeStore)();
|
|
69
|
+
const entry = store.get(key);
|
|
70
|
+
if (!entry) {
|
|
71
|
+
return res.status(404).json({ success: false, error: `Knowledge entry not found: ${key}` });
|
|
72
|
+
}
|
|
73
|
+
res.json({ success: true, ...entry, timestamp: Date.now() });
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.error('[API] Knowledge get error:', error);
|
|
77
|
+
res.status(500).json({ success: false, error: 'Failed to get knowledge entry',
|
|
78
|
+
message: error instanceof Error ? error.message : 'Unknown error' });
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return router;
|
|
82
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Logs Routes
|
|
4
|
+
* Routes: GET /logs, GET /logs/stream
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.createLogsRoutes = createLogsRoutes;
|
|
11
|
+
const express_1 = require("express");
|
|
12
|
+
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
const runtimeConfig_js_1 = require("../../../config/runtimeConfig.js");
|
|
14
|
+
function createLogsRoutes() {
|
|
15
|
+
const router = (0, express_1.Router)();
|
|
16
|
+
/**
|
|
17
|
+
* GET /api/logs - Get server logs with optional tail functionality
|
|
18
|
+
*/
|
|
19
|
+
router.get('/logs', (req, res) => {
|
|
20
|
+
try {
|
|
21
|
+
const loggingConfig = (0, runtimeConfig_js_1.getRuntimeConfig)().logging;
|
|
22
|
+
const logFile = loggingConfig.file;
|
|
23
|
+
const lines = req.query.lines ? parseInt(req.query.lines, 10) : 100;
|
|
24
|
+
const follow = req.query.follow === 'true';
|
|
25
|
+
const raw = req.query.raw === '1' || req.query.raw === 'true';
|
|
26
|
+
if (!logFile || !fs_1.default.existsSync(logFile)) {
|
|
27
|
+
return res.json({
|
|
28
|
+
logs: [],
|
|
29
|
+
message: 'No log file configured or file not found. Set INDEX_SERVER_LOG_FILE environment variable or update runtime logging configuration.',
|
|
30
|
+
timestamp: Date.now(),
|
|
31
|
+
totalLines: 0
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
// Read log file
|
|
35
|
+
const logContent = fs_1.default.readFileSync(logFile, 'utf8');
|
|
36
|
+
const allLines = logContent.split('\n').filter(line => line.trim());
|
|
37
|
+
// Get last N lines (tail functionality)
|
|
38
|
+
const tailLines = lines > 0 ? allLines.slice(-lines) : allLines;
|
|
39
|
+
if (raw) {
|
|
40
|
+
// Plain text response for simpler clients (backwards-compatible option)
|
|
41
|
+
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
|
42
|
+
res.send(tailLines.join('\n'));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
res.json({
|
|
46
|
+
logs: tailLines,
|
|
47
|
+
timestamp: Date.now(),
|
|
48
|
+
totalLines: allLines.length,
|
|
49
|
+
showing: tailLines.length,
|
|
50
|
+
file: loggingConfig.rawFileValue ?? logFile,
|
|
51
|
+
follow: follow,
|
|
52
|
+
mode: raw ? 'text' : 'json'
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error('[API] Logs error:', error);
|
|
57
|
+
res.status(500).json({
|
|
58
|
+
error: 'Failed to read logs',
|
|
59
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
60
|
+
timestamp: Date.now()
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
/**
|
|
65
|
+
* GET /api/logs/stream - Server-Sent Events stream for real-time log tailing
|
|
66
|
+
*/
|
|
67
|
+
router.get('/logs/stream', (req, res) => {
|
|
68
|
+
const loggingConfig = (0, runtimeConfig_js_1.getRuntimeConfig)().logging;
|
|
69
|
+
const logFile = loggingConfig.file;
|
|
70
|
+
if (!logFile || !fs_1.default.existsSync(logFile)) {
|
|
71
|
+
return res.status(404).json({
|
|
72
|
+
error: 'Log file not available',
|
|
73
|
+
message: 'No log file configured or file not found. Set INDEX_SERVER_LOG_FILE environment variable or update runtime logging configuration.'
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// Set up Server-Sent Events
|
|
77
|
+
const origin = req.headers.origin;
|
|
78
|
+
const corsOrigin = (origin && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(origin)) ? origin : '';
|
|
79
|
+
res.writeHead(200, {
|
|
80
|
+
'Content-Type': 'text/event-stream',
|
|
81
|
+
'Cache-Control': 'no-cache',
|
|
82
|
+
'Connection': 'keep-alive',
|
|
83
|
+
...(corsOrigin ? { 'Access-Control-Allow-Origin': corsOrigin } : {}),
|
|
84
|
+
});
|
|
85
|
+
let lastSize = 0;
|
|
86
|
+
let watchInterval = null;
|
|
87
|
+
try {
|
|
88
|
+
// Get initial file size
|
|
89
|
+
const initialStats = fs_1.default.statSync(logFile);
|
|
90
|
+
lastSize = initialStats.size;
|
|
91
|
+
// Send initial connection message
|
|
92
|
+
res.write(`data: ${JSON.stringify({ type: 'connected', timestamp: Date.now() })}\n\n`);
|
|
93
|
+
// Poll for file changes (more reliable than fs.watchFile)
|
|
94
|
+
watchInterval = setInterval(() => {
|
|
95
|
+
try {
|
|
96
|
+
const currentStats = fs_1.default.statSync(logFile);
|
|
97
|
+
if (currentStats.size > lastSize) {
|
|
98
|
+
// File has grown, read new content
|
|
99
|
+
const stream = fs_1.default.createReadStream(logFile, {
|
|
100
|
+
start: lastSize,
|
|
101
|
+
end: currentStats.size - 1,
|
|
102
|
+
encoding: 'utf8'
|
|
103
|
+
});
|
|
104
|
+
let buffer = '';
|
|
105
|
+
stream.on('data', (chunk) => {
|
|
106
|
+
const chunkStr = chunk.toString();
|
|
107
|
+
buffer += chunkStr;
|
|
108
|
+
const lineArr = buffer.split('\n');
|
|
109
|
+
buffer = lineArr.pop() || ''; // Keep incomplete line in buffer
|
|
110
|
+
lineArr.forEach(line => {
|
|
111
|
+
if (line.trim()) {
|
|
112
|
+
res.write(`data: ${JSON.stringify({
|
|
113
|
+
type: 'log',
|
|
114
|
+
line: line.trim(),
|
|
115
|
+
timestamp: Date.now()
|
|
116
|
+
})}\n\n`);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
stream.on('end', () => {
|
|
121
|
+
lastSize = currentStats.size;
|
|
122
|
+
});
|
|
123
|
+
stream.on('error', (error) => {
|
|
124
|
+
res.write(`data: ${JSON.stringify({
|
|
125
|
+
type: 'error',
|
|
126
|
+
message: error.message,
|
|
127
|
+
timestamp: Date.now()
|
|
128
|
+
})}\n\n`);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
res.write(`data: ${JSON.stringify({
|
|
134
|
+
type: 'error',
|
|
135
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
136
|
+
timestamp: Date.now()
|
|
137
|
+
})}\n\n`);
|
|
138
|
+
}
|
|
139
|
+
}, 1000);
|
|
140
|
+
// Cleanup on client disconnect
|
|
141
|
+
req.on('close', () => {
|
|
142
|
+
if (watchInterval) {
|
|
143
|
+
clearInterval(watchInterval);
|
|
144
|
+
watchInterval = null;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
// Keep connection alive
|
|
148
|
+
const heartbeat = setInterval(() => {
|
|
149
|
+
res.write(`data: ${JSON.stringify({ type: 'heartbeat', timestamp: Date.now() })}\n\n`);
|
|
150
|
+
}, 30000);
|
|
151
|
+
req.on('close', () => {
|
|
152
|
+
clearInterval(heartbeat);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
res.write(`data: ${JSON.stringify({
|
|
157
|
+
type: 'error',
|
|
158
|
+
message: error instanceof Error ? error.message : 'Failed to start log streaming',
|
|
159
|
+
timestamp: Date.now()
|
|
160
|
+
})}\n\n`);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
return router;
|
|
164
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Messaging Routes — Dashboard REST API for inter-agent messaging.
|
|
3
|
+
*
|
|
4
|
+
* Routes:
|
|
5
|
+
* POST /api/messages — send a message
|
|
6
|
+
* GET /api/messages/channels — list channels
|
|
7
|
+
* GET /api/messages/stats — reader stats
|
|
8
|
+
* GET /api/messages/:channel — read messages from channel
|
|
9
|
+
* POST /api/messages/ack — acknowledge messages
|
|
10
|
+
* GET /api/messages/by-id/:id — get message by ID
|
|
11
|
+
* PUT /api/messages/by-id/:id — update message
|
|
12
|
+
* DELETE /api/messages — purge messages
|
|
13
|
+
* POST /api/messages/inbound — peer inbound (cross-instance)
|
|
14
|
+
*/
|
|
15
|
+
import { Router } from 'express';
|
|
16
|
+
export declare function createMessagingRoutes(): Router;
|