@jagilber-org/index-server 1.22.1 → 1.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/CHANGELOG.md +87 -2
  2. package/CODE_OF_CONDUCT.md +2 -0
  3. package/CONTRIBUTING.md +32 -2
  4. package/README.md +82 -19
  5. package/SECURITY.md +17 -5
  6. package/dist/config/dashboardConfig.d.ts +3 -0
  7. package/dist/config/dashboardConfig.js +3 -0
  8. package/dist/config/defaultValues.d.ts +1 -1
  9. package/dist/config/defaultValues.js +1 -1
  10. package/dist/config/featureConfig.d.ts +2 -0
  11. package/dist/config/featureConfig.js +6 -1
  12. package/dist/config/runtimeConfig.d.ts +1 -1
  13. package/dist/config/runtimeConfig.js +8 -9
  14. package/dist/dashboard/client/admin.html +170 -53
  15. package/dist/dashboard/client/css/admin.css +132 -0
  16. package/dist/dashboard/client/js/admin.auth.js +25 -11
  17. package/dist/dashboard/client/js/admin.config.js +1 -1
  18. package/dist/dashboard/client/js/admin.feedback.js +328 -0
  19. package/dist/dashboard/client/js/admin.graph.js +120 -18
  20. package/dist/dashboard/client/js/admin.instructions.js +27 -13
  21. package/dist/dashboard/client/js/admin.logs.js +1 -5
  22. package/dist/dashboard/client/js/admin.maintenance.js +53 -8
  23. package/dist/dashboard/client/js/admin.messaging.js +1 -4
  24. package/dist/dashboard/client/js/admin.overview.js +5 -1
  25. package/dist/dashboard/client/js/admin.sessions.js +1 -1
  26. package/dist/dashboard/client/js/admin.utils.js +43 -1
  27. package/dist/dashboard/client/js/mermaid.min.js +813 -537
  28. package/dist/dashboard/export/DataExporter.js +2 -1
  29. package/dist/dashboard/server/AdminPanel.d.ts +3 -0
  30. package/dist/dashboard/server/AdminPanel.js +132 -35
  31. package/dist/dashboard/server/ApiRoutes.js +40 -9
  32. package/dist/dashboard/server/DashboardServer.js +1 -1
  33. package/dist/dashboard/server/FileMetricsStorage.d.ts +19 -0
  34. package/dist/dashboard/server/FileMetricsStorage.js +52 -5
  35. package/dist/dashboard/server/HttpTransport.js +6 -0
  36. package/dist/dashboard/server/InstanceManager.js +7 -2
  37. package/dist/dashboard/server/KnowledgeStore.js +7 -2
  38. package/dist/dashboard/server/MetricsCollector.d.ts +16 -0
  39. package/dist/dashboard/server/MetricsCollector.js +113 -17
  40. package/dist/dashboard/server/legacyDashboardHtml.js +7 -2
  41. package/dist/dashboard/server/middleware/ensureLoadedMiddleware.d.ts +1 -1
  42. package/dist/dashboard/server/middleware/ensureLoadedMiddleware.js +8 -3
  43. package/dist/dashboard/server/routes/admin.feedback.routes.d.ts +15 -0
  44. package/dist/dashboard/server/routes/admin.feedback.routes.js +188 -0
  45. package/dist/dashboard/server/routes/admin.routes.js +35 -27
  46. package/dist/dashboard/server/routes/alerts.routes.js +4 -3
  47. package/dist/dashboard/server/routes/api.feedback.routes.js +2 -1
  48. package/dist/dashboard/server/routes/api.usage.routes.js +8 -7
  49. package/dist/dashboard/server/routes/embeddings.routes.d.ts +2 -1
  50. package/dist/dashboard/server/routes/embeddings.routes.js +18 -9
  51. package/dist/dashboard/server/routes/graph.routes.js +10 -13
  52. package/dist/dashboard/server/routes/index.d.ts +1 -0
  53. package/dist/dashboard/server/routes/index.js +74 -39
  54. package/dist/dashboard/server/routes/instances.routes.js +2 -1
  55. package/dist/dashboard/server/routes/instructions.routes.js +46 -27
  56. package/dist/dashboard/server/routes/knowledge.routes.js +4 -3
  57. package/dist/dashboard/server/routes/logs.routes.js +5 -4
  58. package/dist/dashboard/server/routes/messaging.routes.js +15 -14
  59. package/dist/dashboard/server/routes/metrics.routes.js +14 -13
  60. package/dist/dashboard/server/routes/scripts.routes.js +6 -3
  61. package/dist/dashboard/server/routes/status.routes.js +5 -4
  62. package/dist/dashboard/server/routes/synthetic.routes.js +3 -2
  63. package/dist/dashboard/server/routes/usage.routes.js +2 -1
  64. package/dist/dashboard/server/utils/escapeHtml.d.ts +1 -0
  65. package/dist/dashboard/server/utils/escapeHtml.js +11 -0
  66. package/dist/dashboard/server/utils/pathContainment.d.ts +1 -0
  67. package/dist/dashboard/server/utils/pathContainment.js +15 -0
  68. package/dist/dashboard/server/wsInit.js +2 -2
  69. package/dist/lib/mcpStdioLogging.d.ts +165 -0
  70. package/dist/lib/mcpStdioLogging.js +287 -0
  71. package/dist/schemas/index.d.ts +37 -2
  72. package/dist/schemas/index.js +27 -3
  73. package/dist/server/backgroundServicesStartup.d.ts +7 -1
  74. package/dist/server/backgroundServicesStartup.js +25 -8
  75. package/dist/server/certInit.d.ts +97 -0
  76. package/dist/server/certInit.js +359 -0
  77. package/dist/server/certInit.types.d.ts +92 -0
  78. package/dist/server/certInit.types.js +34 -0
  79. package/dist/server/handshake/fallbackFrames.d.ts +31 -0
  80. package/dist/server/handshake/fallbackFrames.js +38 -0
  81. package/dist/server/handshake/initializeDetector.d.ts +31 -0
  82. package/dist/server/handshake/initializeDetector.js +88 -0
  83. package/dist/server/handshake/protocol.d.ts +15 -0
  84. package/dist/server/handshake/protocol.js +37 -0
  85. package/dist/server/handshake/readyEmitter.d.ts +6 -0
  86. package/dist/server/handshake/readyEmitter.js +88 -0
  87. package/dist/server/handshake/safetyFallbacks.d.ts +1 -0
  88. package/dist/server/handshake/safetyFallbacks.js +134 -0
  89. package/dist/server/handshake/stdinSniffer.d.ts +1 -0
  90. package/dist/server/handshake/stdinSniffer.js +260 -0
  91. package/dist/server/handshake/tracing.d.ts +16 -0
  92. package/dist/server/handshake/tracing.js +95 -0
  93. package/dist/server/handshakeManager.d.ts +23 -23
  94. package/dist/server/handshakeManager.js +36 -466
  95. package/dist/server/index-server.d.ts +23 -0
  96. package/dist/server/index-server.js +194 -9
  97. package/dist/server/mcpReadOnlySurfaces.d.ts +44 -0
  98. package/dist/server/mcpReadOnlySurfaces.js +297 -0
  99. package/dist/server/sdkServer.js +69 -7
  100. package/dist/server/transport.d.ts +5 -6
  101. package/dist/server/transport.js +46 -64
  102. package/dist/server/transportFactory.d.ts +3 -9
  103. package/dist/server/transportFactory.js +18 -380
  104. package/dist/services/atomicFs.d.ts +3 -0
  105. package/dist/services/atomicFs.js +171 -13
  106. package/dist/services/auditLog.d.ts +17 -2
  107. package/dist/services/auditLog.js +75 -14
  108. package/dist/services/bootstrapGating.js +1 -1
  109. package/dist/services/categoryRules.d.ts +10 -0
  110. package/dist/services/categoryRules.js +17 -0
  111. package/dist/services/classificationService.js +7 -5
  112. package/dist/services/embeddingService.d.ts +27 -11
  113. package/dist/services/embeddingService.js +51 -14
  114. package/dist/services/feedbackStorage.d.ts +39 -0
  115. package/dist/services/feedbackStorage.js +88 -0
  116. package/dist/services/handlers/instructions.add.js +429 -317
  117. package/dist/services/handlers/instructions.groom.js +128 -31
  118. package/dist/services/handlers/instructions.import.js +56 -23
  119. package/dist/services/handlers/instructions.patch.js +43 -32
  120. package/dist/services/handlers/instructions.query.js +20 -29
  121. package/dist/services/handlers/instructions.shared.d.ts +54 -0
  122. package/dist/services/handlers/instructions.shared.js +126 -1
  123. package/dist/services/handlers.activation.js +83 -81
  124. package/dist/services/handlers.dashboardConfig.d.ts +2 -2
  125. package/dist/services/handlers.dashboardConfig.js +1 -2
  126. package/dist/services/handlers.diagnostics.js +75 -54
  127. package/dist/services/handlers.feedback.d.ts +4 -11
  128. package/dist/services/handlers.feedback.js +11 -333
  129. package/dist/services/handlers.gates.js +69 -37
  130. package/dist/services/handlers.graph.js +2 -2
  131. package/dist/services/handlers.help.js +2 -2
  132. package/dist/services/handlers.instructionSchema.js +4 -2
  133. package/dist/services/handlers.integrity.js +42 -22
  134. package/dist/services/handlers.messaging.js +1 -1
  135. package/dist/services/handlers.metrics.js +51 -6
  136. package/dist/services/handlers.prompt.js +10 -2
  137. package/dist/services/handlers.search.js +94 -44
  138. package/dist/services/handlers.trace.js +1 -1
  139. package/dist/services/handlers.usage.js +38 -7
  140. package/dist/services/indexContext.d.ts +21 -1
  141. package/dist/services/indexContext.js +263 -78
  142. package/dist/services/indexLoader.d.ts +1 -0
  143. package/dist/services/indexLoader.js +28 -8
  144. package/dist/services/instructionRecordValidation.d.ts +39 -0
  145. package/dist/services/instructionRecordValidation.js +388 -0
  146. package/dist/services/instructions.dispatcher.js +4 -4
  147. package/dist/services/loaderSchemaValidator.d.ts +15 -0
  148. package/dist/services/loaderSchemaValidator.js +69 -0
  149. package/dist/services/logger.js +11 -2
  150. package/dist/services/mcpLogBridge.d.ts +49 -0
  151. package/dist/services/mcpLogBridge.js +83 -0
  152. package/dist/services/ownershipService.js +18 -8
  153. package/dist/services/performanceBaseline.js +23 -22
  154. package/dist/services/promptReviewService.d.ts +3 -1
  155. package/dist/services/promptReviewService.js +41 -13
  156. package/dist/services/regexSafety.d.ts +6 -0
  157. package/dist/services/regexSafety.js +46 -0
  158. package/dist/services/seedBootstrap.js +1 -1
  159. package/dist/services/storage/factory.d.ts +14 -1
  160. package/dist/services/storage/factory.js +61 -1
  161. package/dist/services/storage/jsonEmbeddingStore.d.ts +15 -0
  162. package/dist/services/storage/jsonEmbeddingStore.js +83 -0
  163. package/dist/services/storage/jsonFileStore.d.ts +3 -1
  164. package/dist/services/storage/jsonFileStore.js +8 -6
  165. package/dist/services/storage/migrationEngine.d.ts +13 -0
  166. package/dist/services/storage/migrationEngine.js +31 -0
  167. package/dist/services/storage/sqliteEmbeddingStore.d.ts +30 -0
  168. package/dist/services/storage/sqliteEmbeddingStore.js +222 -0
  169. package/dist/services/storage/sqliteStore.d.ts +3 -1
  170. package/dist/services/storage/sqliteStore.js +2 -2
  171. package/dist/services/storage/types.d.ts +48 -1
  172. package/dist/services/toolRegistry.js +77 -67
  173. package/dist/services/toolRegistry.zod.js +89 -86
  174. package/dist/services/tracing.js +5 -4
  175. package/dist/utils/envUtils.d.ts +4 -0
  176. package/dist/utils/envUtils.js +7 -0
  177. package/dist/utils/memoryMonitor.js +11 -10
  178. package/package.json +11 -4
  179. package/schemas/instruction.schema.json +38 -1
  180. package/scripts/copy-dashboard-assets.mjs +1 -1
  181. package/scripts/dist/README.md +1 -1
  182. package/scripts/setup-wizard.mjs +781 -0
  183. package/server.json +1 -0
  184. package/dist/externalClientLib.d.ts +0 -1
  185. package/dist/externalClientLib.js +0 -2
  186. package/dist/portableClientWrapper.d.ts +0 -1
  187. package/dist/portableClientWrapper.js +0 -2
  188. package/dist/services/indexingService.d.ts +0 -1
  189. package/dist/services/indexingService.js +0 -2
@@ -32,6 +32,11 @@ exports.startDashboard = startDashboard;
32
32
  // and then re-emit the buffered chunks once the SDK has attached its handlers.
33
33
  // This ensures spec compliance: an initialize request always yields either a
34
34
  // success or a version negotiation error – never silent drop.
35
+ // Install MCP log bridge stderr intercept FIRST — before any module writes to stderr.
36
+ // This buffers all stderr output and replays it through MCP notifications/message
37
+ // after the handshake, so VS Code shows proper [info]/[warning]/[error] levels
38
+ // instead of tagging everything as [warning] [server stderr].
39
+ require("../services/mcpLogBridge");
35
40
  // Install global stderr log prefix (timestamps, pid, ppid, seq, tid) before any diagnostic output.
36
41
  require("../services/logPrefix");
37
42
  // Ensure logger initializes early (file logging environment may auto-resolve)
@@ -88,7 +93,10 @@ const path_1 = __importDefault(require("path"));
88
93
  const logger_1 = require("../services/logger");
89
94
  const bootstrapGating_1 = require("../services/bootstrapGating");
90
95
  const preflight_1 = require("../services/preflight");
96
+ const child_process_1 = require("child_process");
91
97
  const shutdownGuard_1 = require("./shutdownGuard");
98
+ const certInit_1 = require("./certInit");
99
+ const certInit_types_1 = require("./certInit.types");
92
100
  // Singleton shutdown guard — all exit paths funnel through this (Issue #36 fix)
93
101
  exports.shutdownGuard = (0, shutdownGuard_1.createShutdownGuard)();
94
102
  // Store in global symbol so services (indexContext) can register cleanup without circular imports
@@ -223,12 +231,18 @@ function parseArgs(argv) {
223
231
  config.dashboard = true;
224
232
  else if (raw === '--no-dashboard')
225
233
  config.dashboard = false;
226
- else if (raw.startsWith('--dashboard-port='))
227
- config.dashboardPort = parseInt(raw.split('=')[1], 10) || config.dashboardPort;
234
+ else if (raw.startsWith('--dashboard-port=')) {
235
+ const parsed = parseInt(raw.split('=')[1], 10);
236
+ if (!Number.isNaN(parsed))
237
+ config.dashboardPort = parsed;
238
+ }
228
239
  else if (raw === '--dashboard-port') {
229
240
  const v = args[++i];
230
- if (v)
231
- config.dashboardPort = parseInt(v, 10) || config.dashboardPort;
241
+ if (v) {
242
+ const parsed = parseInt(v, 10);
243
+ if (!Number.isNaN(parsed))
244
+ config.dashboardPort = parsed;
245
+ }
232
246
  }
233
247
  else if (raw.startsWith('--dashboard-host='))
234
248
  config.dashboardHost = raw.split('=')[1] || config.dashboardHost;
@@ -267,14 +281,103 @@ function parseArgs(argv) {
267
281
  if (v)
268
282
  config.dashboardTlsCa = v;
269
283
  }
284
+ // ── --init-cert family ───────────────────────────────────────────────
285
+ else if (raw === '--init-cert')
286
+ config.initCert = true;
287
+ else if (raw.startsWith('--cert-dir='))
288
+ config.certDir = raw.split('=').slice(1).join('=');
289
+ else if (raw === '--cert-dir') {
290
+ const v = args[++i];
291
+ if (v)
292
+ config.certDir = v;
293
+ }
294
+ else if (raw.startsWith('--cert-file='))
295
+ config.certFile = raw.split('=').slice(1).join('=');
296
+ else if (raw === '--cert-file') {
297
+ const v = args[++i];
298
+ if (v)
299
+ config.certFile = v;
300
+ }
301
+ else if (raw.startsWith('--key-file='))
302
+ config.keyFile = raw.split('=').slice(1).join('=');
303
+ else if (raw === '--key-file') {
304
+ const v = args[++i];
305
+ if (v)
306
+ config.keyFile = v;
307
+ }
308
+ else if (raw.startsWith('--cn='))
309
+ config.certCn = raw.split('=').slice(1).join('=');
310
+ else if (raw === '--cn') {
311
+ const v = args[++i];
312
+ if (v)
313
+ config.certCn = v;
314
+ }
315
+ else if (raw.startsWith('--san='))
316
+ config.certSan = raw.split('=').slice(1).join('=');
317
+ else if (raw === '--san') {
318
+ const v = args[++i];
319
+ if (v)
320
+ config.certSan = v;
321
+ }
322
+ else if (raw.startsWith('--days=')) {
323
+ const p = parseInt(raw.split('=')[1], 10);
324
+ if (!Number.isNaN(p))
325
+ config.certDays = p;
326
+ }
327
+ else if (raw === '--days') {
328
+ const v = args[++i];
329
+ if (v) {
330
+ const p = parseInt(v, 10);
331
+ if (!Number.isNaN(p))
332
+ config.certDays = p;
333
+ }
334
+ }
335
+ else if (raw.startsWith('--key-bits=')) {
336
+ const p = parseInt(raw.split('=')[1], 10);
337
+ if (!Number.isNaN(p))
338
+ config.certKeyBits = p;
339
+ }
340
+ else if (raw === '--key-bits') {
341
+ const v = args[++i];
342
+ if (v) {
343
+ const p = parseInt(v, 10);
344
+ if (!Number.isNaN(p))
345
+ config.certKeyBits = p;
346
+ }
347
+ }
348
+ else if (raw === '--force')
349
+ config.certForce = true;
350
+ else if (raw === '--print-env')
351
+ config.certPrintEnv = true;
352
+ else if (raw.startsWith('--print-env='))
353
+ config.certPrintEnv = raw.split('=').slice(1).join('=');
354
+ else if (raw === '--start')
355
+ config.start = true;
270
356
  else if (raw === '--legacy' || raw === '--legacy-transport')
271
357
  config.legacy = true; // no-op
358
+ else if (raw === '--setup' || raw === '--configure') {
359
+ launchSetupWizard(argv);
360
+ }
272
361
  else if (raw === '--help' || raw === '-h') {
273
362
  printHelpAndExit();
274
363
  }
275
364
  }
276
365
  return config;
277
366
  }
367
+ function launchSetupWizard(argv) {
368
+ const wizardPath = path_1.default.join(__dirname, '..', '..', 'scripts', 'setup-wizard.mjs');
369
+ // Forward all args after --setup/--configure to the wizard
370
+ const setupIdx = argv.findIndex(a => a === '--setup' || a === '--configure');
371
+ const forwardArgs = setupIdx >= 0 ? argv.slice(setupIdx + 1) : [];
372
+ try {
373
+ (0, child_process_1.execFileSync)(process.execPath, [wizardPath, ...forwardArgs], { stdio: 'inherit' });
374
+ }
375
+ catch (e) {
376
+ const code = e.status ?? 1;
377
+ process.exit(code);
378
+ }
379
+ process.exit(0);
380
+ }
278
381
  function printHelpAndExit() {
279
382
  const help = `index-server - Model Context Protocol Server
280
383
 
@@ -283,6 +386,10 @@ MCP TRANSPORT (Client Communication):
283
386
  Purpose: VS Code, Claude, and other MCP clients
284
387
  Security: Process-isolated, no network exposure
285
388
 
389
+ SETUP:
390
+ --setup Launch interactive configuration wizard
391
+ --configure Alias for --setup
392
+
286
393
  ADMIN DASHBOARD (Optional):
287
394
  --dashboard Enable read-only admin dashboard (default off)
288
395
  --dashboard-port=PORT Dashboard port (default 8787)
@@ -295,6 +402,23 @@ ADMIN DASHBOARD (Optional):
295
402
  --dashboard-tls-ca=PATH Optional CA certificate file (PEM)
296
403
  Purpose: Local administrator monitoring only
297
404
 
405
+ CERTIFICATE BOOTSTRAP (Optional, Self-Signed TLS):
406
+ --init-cert Generate a self-signed TLS cert+key (requires openssl on PATH).
407
+ Exits after generation unless --start is also given.
408
+ --cert-dir PATH Output directory (default: ~/.index-server/certs)
409
+ --cert-file PATH Override cert output path (must be under --cert-dir)
410
+ --key-file PATH Override key output path (must be under --cert-dir)
411
+ --cn NAME CommonName subject (default: localhost)
412
+ --san LIST Comma-separated SAN entries (default: DNS:localhost,IP:127.0.0.1)
413
+ --days N Validity in days, 1..3650 (default: 365)
414
+ --key-bits N RSA key size, 2048 or 4096 (default: 2048)
415
+ --force Overwrite existing cert/key files
416
+ --print-env[=FMT] Print INDEX_SERVER_DASHBOARD_TLS_* env lines after generation.
417
+ FMT = posix | powershell | both | auto (default: auto)
418
+ --start After --init-cert, start the server with the generated material
419
+ (sets --dashboard-tls and feeds the new cert/key automatically)
420
+ See docs/cert_init.md for full reference, examples, and security notes.
421
+
298
422
  ENVIRONMENT VARIABLES:
299
423
  INDEX_SERVER_DASHBOARD=1 Enable dashboard (0=disable, 1=enable)
300
424
  INDEX_SERVER_DASHBOARD_PORT=PORT Dashboard port (default 8787)
@@ -308,7 +432,7 @@ ENVIRONMENT VARIABLES:
308
432
  Other environment variables:
309
433
  INDEX_SERVER_VERBOSE_LOGGING=1 Verbose RPC/transport logging
310
434
  INDEX_SERVER_LOG_DIAG=1 Diagnostic logging
311
- INDEX_SERVER_MUTATION=1 Enable write operations
435
+ INDEX_SERVER_MUTATION=0 Force read-only mode (writes enabled by default)
312
436
  INDEX_SERVER_IDLE_KEEPALIVE_MS Keepalive interval (default 30000ms)
313
437
  NODE_ENV=development Use dev ports (dashboard=${defaultValues_1.DEFAULT_PORTS.DASHBOARD_DEV}, leader=${defaultValues_1.DEFAULT_PORTS.LEADER_DEV})
314
438
 
@@ -484,10 +608,72 @@ async function main() {
484
608
  // observes the synthetic readiness sentinel. The interval self-clears on first
485
609
  // stdin activity or after the bounded max window.
486
610
  startIdleKeepalive();
487
- // Short-circuit handshake mode removed (INDEX_SERVER_SHORTCIRCUIT) now that full
488
- // protocol framing is stable and locked by tests. (2025-08-31)
489
611
  const cfg = parseArgs(process.argv);
490
612
  const runtime = (0, runtimeConfig_1.getRuntimeConfig)();
613
+ // ── --init-cert dispatch ──────────────────────────────────────────────
614
+ // Self-contained: if --init-cert is given, run cert generation. When --start
615
+ // is NOT also given, exit after generation (or on error). When --start IS
616
+ // given, inject the generated paths into the dashboard TLS config so the
617
+ // server boots with the new material — no extra env wiring required.
618
+ // Constitution refs: AR-1 (additive, no implicit side effects without flag),
619
+ // SH-4 (path traversal guard re-asserted by validateOptions inside runCertInit),
620
+ // OB-3/OB-5 (CertInitError surfaced with stable code; structured logs from module).
621
+ if (cfg.initCert) {
622
+ try {
623
+ const result = await (0, certInit_1.runCertInit)({
624
+ certDir: cfg.certDir,
625
+ certFile: cfg.certFile,
626
+ keyFile: cfg.keyFile,
627
+ cn: cfg.certCn,
628
+ san: cfg.certSan,
629
+ days: cfg.certDays,
630
+ keyBits: cfg.certKeyBits,
631
+ force: cfg.certForce ?? false,
632
+ printEnv: (cfg.certPrintEnv ?? false),
633
+ });
634
+ process.stderr.write(`[init-cert] ${result.kind === 'generated' ? 'generated' : 'skipped'}: cert=${result.certFile} key=${result.keyFile}\n`);
635
+ if (cfg.certPrintEnv) {
636
+ const fmt = (typeof cfg.certPrintEnv === 'string')
637
+ ? cfg.certPrintEnv
638
+ : 'auto';
639
+ // Re-validate to obtain the resolved option shape (paths) for the helper.
640
+ const opts = (0, certInit_1.validateOptions)({
641
+ certDir: cfg.certDir,
642
+ certFile: result.certFile,
643
+ keyFile: result.keyFile,
644
+ cn: cfg.certCn,
645
+ san: cfg.certSan,
646
+ days: cfg.certDays,
647
+ keyBits: cfg.certKeyBits,
648
+ force: cfg.certForce ?? false,
649
+ printEnv: (cfg.certPrintEnv ?? false),
650
+ });
651
+ process.stderr.write((0, certInit_1.formatPrintEnv)(opts, fmt));
652
+ }
653
+ // When --start was passed, inject paths into the dashboard TLS config
654
+ // so startDashboard() picks them up without requiring --dashboard-tls-cert/key.
655
+ if (cfg.start) {
656
+ cfg.dashboardTls = true;
657
+ cfg.dashboardTlsCert = result.certFile;
658
+ cfg.dashboardTlsKey = result.keyFile;
659
+ // Continue normal startup below.
660
+ }
661
+ else {
662
+ // Generation-only mode: exit cleanly.
663
+ process.exit(0);
664
+ }
665
+ }
666
+ catch (e) {
667
+ const code = (e instanceof certInit_types_1.CertInitError) ? e.code : 'UNKNOWN';
668
+ const msg = (e instanceof Error) ? e.message : String(e);
669
+ process.stderr.write(`[init-cert] FAILED (code=${code}): ${msg}\n`);
670
+ try {
671
+ (0, logger_1.logError)('[init-cert] failed', { code, message: msg });
672
+ }
673
+ catch { /* ignore */ }
674
+ process.exit(2);
675
+ }
676
+ }
491
677
  // ── Dev/prod port-collision guard ─────────────────────────────────
492
678
  // When NODE_ENV=development (or --watch), refuse to start on production
493
679
  // default ports to prevent dev servers from receiving production traffic.
@@ -597,9 +783,8 @@ async function main() {
597
783
  catch { /* ignore */ }
598
784
  }
599
785
  }
600
- // eslint-disable-next-line no-console
601
786
  if (runtime.logging.diagnostics)
602
- console.error(`[handshake-buffer] replayed ${__earlyInitChunks.length} early chunk(s)`);
787
+ (0, logger_1.logError)(`[handshake-buffer] replayed ${__earlyInitChunks.length} early chunk(s)`);
603
788
  __earlyInitChunks.length = 0;
604
789
  }
605
790
  else if (runtime.logging.diagnostics) {
@@ -0,0 +1,44 @@
1
+ type PromptArgument = {
2
+ name: string;
3
+ description?: string;
4
+ required?: boolean;
5
+ };
6
+ export declare function getReadOnlySurfaceCapabilities(): {
7
+ prompts: {
8
+ listChanged: boolean;
9
+ };
10
+ resources: {
11
+ listChanged: boolean;
12
+ };
13
+ };
14
+ export declare function listReadOnlyResources(): {
15
+ uri: string;
16
+ name: string;
17
+ title?: string;
18
+ description: string;
19
+ mimeType: "text/markdown";
20
+ }[];
21
+ export declare function readReadOnlyResource(uri: string): {
22
+ contents: {
23
+ uri: string;
24
+ mimeType: "text/markdown";
25
+ text: string;
26
+ }[];
27
+ } | null;
28
+ export declare function listReadOnlyPrompts(): {
29
+ name: string;
30
+ title?: string;
31
+ description: string;
32
+ arguments?: PromptArgument[];
33
+ }[];
34
+ export declare function getReadOnlyPrompt(name: string, args?: Record<string, string>): {
35
+ description?: string;
36
+ messages: Array<{
37
+ role: "user" | "assistant";
38
+ content: {
39
+ type: "text";
40
+ text: string;
41
+ };
42
+ }>;
43
+ } | null;
44
+ export {};
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getReadOnlySurfaceCapabilities = getReadOnlySurfaceCapabilities;
4
+ exports.listReadOnlyResources = listReadOnlyResources;
5
+ exports.readReadOnlyResource = readReadOnlyResource;
6
+ exports.listReadOnlyPrompts = listReadOnlyPrompts;
7
+ exports.getReadOnlyPrompt = getReadOnlyPrompt;
8
+ function normalizeClientTarget(value) {
9
+ const normalized = String(value ?? '').trim().toLowerCase();
10
+ if (!normalized)
11
+ return 'generic';
12
+ if (normalized.includes('code') || normalized.includes('vscode') || normalized.includes('vs code'))
13
+ return 'vscode';
14
+ if (normalized.includes('copilot'))
15
+ return 'copilot-cli';
16
+ if (normalized.includes('claude'))
17
+ return 'claude';
18
+ return 'generic';
19
+ }
20
+ function clientLabel(target) {
21
+ switch (normalizeClientTarget(target)) {
22
+ case 'vscode':
23
+ return 'VS Code';
24
+ case 'copilot-cli':
25
+ return 'Copilot CLI';
26
+ case 'claude':
27
+ return 'Claude Desktop';
28
+ default:
29
+ return 'your MCP client';
30
+ }
31
+ }
32
+ function clientConfigPath(target) {
33
+ switch (normalizeClientTarget(target)) {
34
+ case 'vscode':
35
+ return '.vscode/mcp.json (workspace) or User/mcp.json (global)';
36
+ case 'copilot-cli':
37
+ return '~/.copilot/mcp-config.json';
38
+ case 'claude':
39
+ return 'claude_desktop_config.json';
40
+ default:
41
+ return 'the MCP client config file for your environment';
42
+ }
43
+ }
44
+ function clientConfigRoot(target) {
45
+ switch (normalizeClientTarget(target)) {
46
+ case 'vscode':
47
+ return '`servers`';
48
+ case 'copilot-cli':
49
+ case 'claude':
50
+ return '`mcpServers`';
51
+ default:
52
+ return '`servers` or `mcpServers` depending on the client';
53
+ }
54
+ }
55
+ const STATIC_RESOURCES = [
56
+ {
57
+ uri: 'index://guides/quickstart',
58
+ name: 'quickstart',
59
+ title: 'Quick Start',
60
+ description: 'Install, configure, and verify Index Server with the MCP-native flow.',
61
+ mimeType: 'text/markdown',
62
+ text: [
63
+ '# Index Server Quick Start',
64
+ '',
65
+ '## Recommended install',
66
+ '',
67
+ '```bash',
68
+ 'npx -y @jagilber-org/index-server@latest --setup',
69
+ '```',
70
+ '',
71
+ 'Use the setup wizard to generate MCP client config for VS Code, Copilot CLI, or Claude Desktop.',
72
+ '',
73
+ '## Manual configuration',
74
+ '',
75
+ '- Use `npx` with `@jagilber-org/index-server@latest` as the command target.',
76
+ '- Keep `INDEX_SERVER_DIR` in a stable data folder outside client install/config directories.',
77
+ '- Add `--dashboard` or `--dashboard-port=8787` if you want the admin UI enabled.',
78
+ '',
79
+ '## Verification',
80
+ '',
81
+ '1. Restart the MCP client.',
82
+ '2. Confirm the server appears in the MCP server list.',
83
+ '3. Ask the client to run `health_check`.',
84
+ '4. Ask the client to run `bootstrap` / `index-server-bootstrap status` to confirm initialization state.',
85
+ ].join('\n'),
86
+ },
87
+ {
88
+ uri: 'index://guides/client-config',
89
+ name: 'client-config',
90
+ title: 'Client Configuration',
91
+ description: 'Config file formats and best practices for VS Code, Copilot CLI, and Claude Desktop.',
92
+ mimeType: 'text/markdown',
93
+ text: [
94
+ '# MCP Client Configuration',
95
+ '',
96
+ '## File formats',
97
+ '',
98
+ '- **VS Code** uses `.vscode/mcp.json` (workspace) or User `mcp.json` with a `servers` root key.',
99
+ '- **Copilot CLI** uses `~/.copilot/mcp-config.json` with an `mcpServers` root key.',
100
+ '- **Claude Desktop** uses `claude_desktop_config.json` with an `mcpServers` root key.',
101
+ '',
102
+ '## Best practices',
103
+ '',
104
+ '- Prefer `npx -y @jagilber-org/index-server@latest` for published installs.',
105
+ '- Set `INDEX_SERVER_DIR` to a persistent data directory such as `C:/mcp/index-data/instructions`.',
106
+ '- For Copilot CLI and Claude Desktop, include `cwd` when you are running a local checkout instead of the published package.',
107
+ '- For Copilot CLI, `tools: ["*"]` keeps all tools available.',
108
+ '',
109
+ '## Setup wizard targets',
110
+ '',
111
+ '- `--target vscode`',
112
+ '- `--target copilot-cli`',
113
+ '- `--target claude`',
114
+ '- multiple targets are supported with comma-separated values',
115
+ ].join('\n'),
116
+ },
117
+ {
118
+ uri: 'index://guides/verification',
119
+ name: 'verification',
120
+ title: 'Verification and Troubleshooting',
121
+ description: 'Checklist for verifying the MCP connection and diagnosing common setup issues.',
122
+ mimeType: 'text/markdown',
123
+ text: [
124
+ '# Verification and Troubleshooting',
125
+ '',
126
+ '## Basic checks',
127
+ '',
128
+ '1. Restart the MCP client after config changes.',
129
+ '2. Confirm the server is listed in the client UI.',
130
+ '3. Run `tools/list` to confirm tool discovery.',
131
+ '4. Run `health_check` to confirm the server is reachable.',
132
+ '5. Run bootstrap status if initialization looks gated on a fresh install.',
133
+ '',
134
+ '## Common causes',
135
+ '',
136
+ '- The config file uses the wrong root key (`servers` vs `mcpServers`).',
137
+ '- `cwd` is missing for a local checkout configuration.',
138
+ '- `INDEX_SERVER_DIR` points at a transient or client-owned directory.',
139
+ '- The client was not restarted after editing the config.',
140
+ '- The command path references a local build that has not been built yet.',
141
+ ].join('\n'),
142
+ },
143
+ ];
144
+ const RESOURCE_BY_URI = new Map(STATIC_RESOURCES.map((resource) => [resource.uri, resource]));
145
+ function renderSetupPrompt(args) {
146
+ const client = clientLabel(args?.client);
147
+ const configPath = clientConfigPath(args?.client);
148
+ const configRoot = clientConfigRoot(args?.client);
149
+ return {
150
+ description: `Guide ${client} setup with the MCP-native install flow.`,
151
+ messages: [
152
+ {
153
+ role: 'user',
154
+ content: {
155
+ type: 'text',
156
+ text: `Help me install and configure Index Server for ${client}. Prefer the published MCP-native flow.`,
157
+ },
158
+ },
159
+ {
160
+ role: 'assistant',
161
+ content: {
162
+ type: 'text',
163
+ text: [
164
+ `Use \`npx -y @jagilber-org/index-server@latest --setup\` first so ${client} configuration is generated automatically when possible.`,
165
+ `If the user needs manual setup, edit ${configPath} and use the ${configRoot} root key.`,
166
+ 'Keep `INDEX_SERVER_DIR` in a stable data folder outside the MCP client install/config path.',
167
+ 'After configuration, restart the client and verify with `health_check` and bootstrap status.',
168
+ 'Reference resources: `index://guides/quickstart`, `index://guides/client-config`, `index://guides/verification`.',
169
+ ].join('\n'),
170
+ },
171
+ },
172
+ ],
173
+ };
174
+ }
175
+ function renderConfigPrompt(args) {
176
+ const client = clientLabel(args?.client);
177
+ const configPath = clientConfigPath(args?.client);
178
+ const configRoot = clientConfigRoot(args?.client);
179
+ return {
180
+ description: `Explain the right MCP config shape for ${client}.`,
181
+ messages: [
182
+ {
183
+ role: 'user',
184
+ content: {
185
+ type: 'text',
186
+ text: `Review or generate the MCP configuration for ${client}.`,
187
+ },
188
+ },
189
+ {
190
+ role: 'assistant',
191
+ content: {
192
+ type: 'text',
193
+ text: [
194
+ `Target config file: ${configPath}.`,
195
+ `Use ${configRoot} as the root key for this client.`,
196
+ 'Prefer `npx -y @jagilber-org/index-server@latest` for published installs.',
197
+ 'Use `cwd` only for local checkout configurations that run `dist/server/index-server.js`.',
198
+ 'Set `INDEX_SERVER_DIR` to a persistent directory and keep env values as strings.',
199
+ 'Reference resource: `index://guides/client-config`.',
200
+ ].join('\n'),
201
+ },
202
+ },
203
+ ],
204
+ };
205
+ }
206
+ function renderVerificationPrompt(args) {
207
+ const symptom = String(args?.symptom ?? 'the MCP client is not behaving as expected')
208
+ .trim()
209
+ .slice(0, 500);
210
+ return {
211
+ description: 'Walk through a quick verification and troubleshooting checklist.',
212
+ messages: [
213
+ {
214
+ role: 'user',
215
+ content: {
216
+ type: 'text',
217
+ text: `Help me troubleshoot Index Server because ${symptom}.`,
218
+ },
219
+ },
220
+ {
221
+ role: 'assistant',
222
+ content: {
223
+ type: 'text',
224
+ text: [
225
+ 'Start with protocol-level checks: confirm the server appears in the MCP client and that `tools/list` succeeds.',
226
+ 'Then run `health_check` and bootstrap status to separate connectivity problems from initialization state.',
227
+ 'Verify the config file uses the correct root key and includes `cwd` for local checkout setups.',
228
+ 'If configuration changed recently, restart the MCP client before concluding the server is broken.',
229
+ 'Reference resource: `index://guides/verification`.',
230
+ ].join('\n'),
231
+ },
232
+ },
233
+ ],
234
+ };
235
+ }
236
+ const PROMPTS = [
237
+ {
238
+ name: 'setup_index_server',
239
+ title: 'Setup Index Server',
240
+ description: 'Guide an MCP-native Index Server install and initial configuration.',
241
+ arguments: [
242
+ { name: 'client', description: 'Optional target client such as vscode, copilot-cli, or claude.' },
243
+ ],
244
+ render: renderSetupPrompt,
245
+ },
246
+ {
247
+ name: 'configure_index_server',
248
+ title: 'Configure Index Server',
249
+ description: 'Explain the right config file shape and key settings for a target client.',
250
+ arguments: [
251
+ { name: 'client', description: 'Optional target client such as vscode, copilot-cli, or claude.' },
252
+ ],
253
+ render: renderConfigPrompt,
254
+ },
255
+ {
256
+ name: 'verify_index_server',
257
+ title: 'Verify Index Server',
258
+ description: 'Walk through verification and troubleshooting for setup or connection issues.',
259
+ arguments: [
260
+ { name: 'symptom', description: 'Optional short problem statement to tailor the checklist.' },
261
+ ],
262
+ render: renderVerificationPrompt,
263
+ },
264
+ ];
265
+ const PROMPT_BY_NAME = new Map(PROMPTS.map((prompt) => [prompt.name, prompt]));
266
+ function getReadOnlySurfaceCapabilities() {
267
+ return {
268
+ prompts: { listChanged: false },
269
+ resources: { listChanged: false },
270
+ };
271
+ }
272
+ function listReadOnlyResources() {
273
+ return STATIC_RESOURCES.map(({ text: _text, ...resource }) => resource);
274
+ }
275
+ function readReadOnlyResource(uri) {
276
+ const resource = RESOURCE_BY_URI.get(uri);
277
+ if (!resource)
278
+ return null;
279
+ return {
280
+ contents: [
281
+ {
282
+ uri: resource.uri,
283
+ mimeType: resource.mimeType,
284
+ text: resource.text,
285
+ },
286
+ ],
287
+ };
288
+ }
289
+ function listReadOnlyPrompts() {
290
+ return PROMPTS.map(({ render: _render, ...prompt }) => prompt);
291
+ }
292
+ function getReadOnlyPrompt(name, args) {
293
+ const prompt = PROMPT_BY_NAME.get(name);
294
+ if (!prompt)
295
+ return null;
296
+ return prompt.render(args);
297
+ }