hive-intelligence 1.1.3 → 1.3.0

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 (174) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +315 -85
  3. package/agent-skills/.claude-plugin/plugin.json +10 -4
  4. package/agent-skills/.mcp.json +8 -0
  5. package/agent-skills/AGENTS.md +37 -0
  6. package/agent-skills/README.md +28 -23
  7. package/agent-skills/SKILL.md +40 -10
  8. package/agent-skills/evals/trigger-queries.json +270 -0
  9. package/agent-skills/package.json +4 -4
  10. package/agent-skills/packs/hive-build/SKILL.md +54 -25
  11. package/agent-skills/packs/hive-build/evals/evals.json +16 -3
  12. package/agent-skills/packs/hive-build/evals/triggers.json +50 -0
  13. package/agent-skills/packs/hive-build-onboarding/SKILL.md +27 -34
  14. package/agent-skills/packs/hive-build-onboarding/evals/evals.json +1 -1
  15. package/agent-skills/packs/hive-build-onboarding/evals/triggers.json +50 -0
  16. package/agent-skills/packs/hive-cli/SKILL.md +33 -35
  17. package/agent-skills/packs/hive-cli/evals/evals.json +1 -1
  18. package/agent-skills/packs/hive-cli/evals/triggers.json +50 -0
  19. package/agent-skills/packs/hive-defi-research/SKILL.md +105 -19
  20. package/agent-skills/packs/hive-defi-research/evals/evals.json +6 -3
  21. package/agent-skills/packs/hive-defi-research/evals/triggers.json +50 -0
  22. package/agent-skills/packs/hive-dex-pool-analysis/SKILL.md +106 -16
  23. package/agent-skills/packs/hive-dex-pool-analysis/evals/evals.json +5 -3
  24. package/agent-skills/packs/hive-dex-pool-analysis/evals/triggers.json +50 -0
  25. package/agent-skills/packs/hive-market-research/SKILL.md +130 -21
  26. package/agent-skills/packs/hive-market-research/evals/evals.json +15 -2
  27. package/agent-skills/packs/hive-market-research/evals/triggers.json +50 -0
  28. package/agent-skills/packs/hive-mcp/SKILL.md +98 -153
  29. package/agent-skills/packs/hive-mcp/evals/evals.json +4 -3
  30. package/agent-skills/packs/hive-mcp/evals/triggers.json +50 -0
  31. package/agent-skills/packs/hive-mcp/references/client-install-matrix.md +62 -35
  32. package/agent-skills/packs/hive-mcp/references/clients.md +154 -0
  33. package/agent-skills/packs/hive-network-infrastructure/SKILL.md +105 -20
  34. package/agent-skills/packs/hive-network-infrastructure/evals/evals.json +4 -2
  35. package/agent-skills/packs/hive-network-infrastructure/evals/triggers.json +50 -0
  36. package/agent-skills/packs/hive-nft-research/SKILL.md +105 -18
  37. package/agent-skills/packs/hive-nft-research/evals/evals.json +4 -2
  38. package/agent-skills/packs/hive-nft-research/evals/triggers.json +50 -0
  39. package/agent-skills/packs/hive-prediction-markets/SKILL.md +108 -21
  40. package/agent-skills/packs/hive-prediction-markets/evals/evals.json +4 -2
  41. package/agent-skills/packs/hive-prediction-markets/evals/triggers.json +50 -0
  42. package/agent-skills/packs/hive-query/SKILL.md +80 -33
  43. package/agent-skills/packs/hive-query/evals/evals.json +7 -5
  44. package/agent-skills/packs/hive-query/evals/triggers.json +50 -0
  45. package/agent-skills/packs/hive-query/references/root-mcp-workflow.md +39 -18
  46. package/agent-skills/packs/hive-security-risk/SKILL.md +110 -19
  47. package/agent-skills/packs/hive-security-risk/evals/evals.json +4 -2
  48. package/agent-skills/packs/hive-security-risk/evals/triggers.json +50 -0
  49. package/agent-skills/packs/hive-solana-analysis/SKILL.md +115 -19
  50. package/agent-skills/packs/hive-solana-analysis/evals/evals.json +4 -2
  51. package/agent-skills/packs/hive-solana-analysis/evals/triggers.json +50 -0
  52. package/agent-skills/packs/hive-stateful-monitoring/SKILL.md +120 -0
  53. package/agent-skills/packs/hive-stateful-monitoring/evals/evals.json +54 -0
  54. package/agent-skills/packs/hive-stateful-monitoring/evals/triggers.json +50 -0
  55. package/agent-skills/packs/hive-stateful-monitoring/references/b2b-subject-context.md +53 -0
  56. package/agent-skills/packs/hive-token-diligence/SKILL.md +119 -21
  57. package/agent-skills/packs/hive-token-diligence/evals/evals.json +6 -4
  58. package/agent-skills/packs/hive-token-diligence/evals/triggers.json +50 -0
  59. package/agent-skills/packs/hive-tool-discovery/SKILL.md +48 -19
  60. package/agent-skills/packs/hive-tool-discovery/evals/evals.json +17 -3
  61. package/agent-skills/packs/hive-tool-discovery/evals/triggers.json +50 -0
  62. package/agent-skills/packs/hive-tool-discovery/references/discovery-surfaces.md +31 -6
  63. package/agent-skills/packs/hive-wallet-investigation/SKILL.md +111 -18
  64. package/agent-skills/packs/hive-wallet-investigation/evals/evals.json +5 -3
  65. package/agent-skills/packs/hive-wallet-investigation/evals/triggers.json +50 -0
  66. package/agent-skills/references/agents-routing.md +19 -7
  67. package/agent-skills/scripts/validate-agent-skills-package.mjs +116 -18
  68. package/agent-skills/skills.sh.json +3 -2
  69. package/bin/hive-mcp.js +5 -5
  70. package/build/{alias-CZ3DEYHF.js → alias-BKAVOYQV.js} +2 -3
  71. package/build/{api-client-I23XLSHU.js → api-client-FTVDFW5V.js} +4 -4
  72. package/build/{auth-KKINNBXT.js → auth-EZFJ5RYB.js} +3 -4
  73. package/build/{browser-auth-EEFGRHWY.js → browser-auth-OJSUNFBI.js} +2 -3
  74. package/build/{cache-EGNMENNA.js → cache-TBDQ7QBU.js} +2 -3
  75. package/build/{chunk-V77LO4RO.js → chunk-6PC3HUAK.js} +10 -4
  76. package/build/{chunk-XYBEFFZ3.js → chunk-725R3KLJ.js} +26 -4
  77. package/build/{chunk-PGBVNMNZ.js → chunk-7GD2MFYI.js} +57 -7
  78. package/build/{chunk-IDZD2NVG.js → chunk-AEU43ACS.js} +33 -10
  79. package/build/chunk-EPF36Q3Z.js +71 -0
  80. package/build/chunk-I5Z6FZRL.js +178 -0
  81. package/build/{chunk-KBVPIZS4.js → chunk-ILVPOLA7.js} +12 -4
  82. package/build/{chunk-B6G222LS.js → chunk-L326MQZP.js} +22 -6
  83. package/build/{chunk-QNCI4DEB.js → chunk-M6REON2I.js} +35 -21
  84. package/build/chunk-N32UIHBU.js +125 -0
  85. package/build/{chunk-IZTN7WFH.js → chunk-Q7VBYLX7.js} +12 -3
  86. package/build/chunk-QDZ7MAVN.js +447 -0
  87. package/build/{chunk-KGYBTXIN.js → chunk-R6YZTFQL.js} +2 -1
  88. package/build/{chunk-DYJBTKNR.js → chunk-RU6QOFHH.js} +9 -10
  89. package/build/{chunk-RKICZ6DZ.js → chunk-RUHO24SX.js} +16 -10
  90. package/build/{chunk-MPIUUE3T.js → chunk-TNQ7GJ6Q.js} +0 -60
  91. package/build/{chunk-2X3U4DFK.js → chunk-W2QL7LYI.js} +43586 -21498
  92. package/build/chunk-ZXKFJQDE.js +20 -0
  93. package/build/cli.js +3342 -3410
  94. package/build/{completion-BELZL7ND.js → completion-7KBW243H.js} +4 -5
  95. package/build/{config-TDX4VUGW.js → config-KAEUX6RM.js} +23 -4
  96. package/build/{config-dir-V43W2WIA.js → config-dir-5IH7MOOT.js} +2 -3
  97. package/build/{doctor-5K5UWHNX.js → doctor-ORDOCGLM.js} +34 -10
  98. package/build/{errors-E6MVUBNA.js → errors-HGHUF575.js} +2 -3
  99. package/build/{format-TSFSI2K7.js → format-H7FOQSYY.js} +1 -2
  100. package/build/{init-YQ5NBICF.js → init-UCTCUYFA.js} +52 -9
  101. package/build/init-all-BVWW3JVK.js +408 -0
  102. package/build/mcpServer-RUEOTTF7.js +34 -0
  103. package/build/monitor-worker.js +1396 -0
  104. package/build/{namespace-PVHBFDW2.js → namespace-L5DGCY7K.js} +2 -3
  105. package/build/{open-YUIJP37F.js → open-V2RNA3QT.js} +2 -3
  106. package/build/{output-IYJBFCYK.js → output-ITGLBKIG.js} +2 -3
  107. package/build/release.json +8 -0
  108. package/build/{serve-KWNJK6EY.js → serve-DKLR2WQH.js} +9 -4
  109. package/build/server.js +5399 -2945
  110. package/build/{setup-YTUKMPNP.js → setup-PTYFMTK5.js} +60 -56
  111. package/build/stdio.js +10 -8
  112. package/build/{telemetry-5IPRKZBL.js → telemetry-HPLDYR7U.js} +5 -4
  113. package/build/{tools-PJHWFCAG.js → tools-I7GLWTV6.js} +15 -15
  114. package/build/{uninstall-HWXEIP6K.js → uninstall-SAOIPL6K.js} +19 -11
  115. package/build/update-check-IEXPOYYR.js +18 -0
  116. package/build/upgrade-J4HIGCKE.js +171 -0
  117. package/build/version-Z4HJL4VV.js +16 -0
  118. package/build/{watch-KZ5EDZK3.js → watch-WVR4CGCD.js} +8 -7
  119. package/package.json +82 -41
  120. package/agent-skills/packs/hive-defi-research/references/workflow.md +0 -41
  121. package/agent-skills/packs/hive-dex-pool-analysis/references/workflow.md +0 -42
  122. package/agent-skills/packs/hive-market-research/references/workflow.md +0 -47
  123. package/agent-skills/packs/hive-network-infrastructure/references/workflow.md +0 -41
  124. package/agent-skills/packs/hive-nft-research/references/workflow.md +0 -42
  125. package/agent-skills/packs/hive-prediction-markets/references/workflow.md +0 -42
  126. package/agent-skills/packs/hive-security-risk/references/workflow.md +0 -46
  127. package/agent-skills/packs/hive-solana-analysis/references/workflow.md +0 -42
  128. package/agent-skills/packs/hive-token-diligence/references/workflow.md +0 -45
  129. package/agent-skills/packs/hive-wallet-investigation/references/workflow.md +0 -45
  130. package/build/alias-CZ3DEYHF.js.map +0 -1
  131. package/build/api-client-I23XLSHU.js.map +0 -1
  132. package/build/auth-KKINNBXT.js.map +0 -1
  133. package/build/browser-auth-EEFGRHWY.js.map +0 -1
  134. package/build/cache-EGNMENNA.js.map +0 -1
  135. package/build/chunk-2MYMHMBF.js +0 -340
  136. package/build/chunk-2MYMHMBF.js.map +0 -1
  137. package/build/chunk-2X3U4DFK.js.map +0 -1
  138. package/build/chunk-B6G222LS.js.map +0 -1
  139. package/build/chunk-DYJBTKNR.js.map +0 -1
  140. package/build/chunk-IDZD2NVG.js.map +0 -1
  141. package/build/chunk-IZTN7WFH.js.map +0 -1
  142. package/build/chunk-KBVPIZS4.js.map +0 -1
  143. package/build/chunk-KGYBTXIN.js.map +0 -1
  144. package/build/chunk-MPIUUE3T.js.map +0 -1
  145. package/build/chunk-PGBVNMNZ.js.map +0 -1
  146. package/build/chunk-QNCI4DEB.js.map +0 -1
  147. package/build/chunk-RKICZ6DZ.js.map +0 -1
  148. package/build/chunk-UKHZIVDT.js +0 -44
  149. package/build/chunk-UKHZIVDT.js.map +0 -1
  150. package/build/chunk-V77LO4RO.js.map +0 -1
  151. package/build/chunk-XYBEFFZ3.js.map +0 -1
  152. package/build/cli.js.map +0 -1
  153. package/build/completion-BELZL7ND.js.map +0 -1
  154. package/build/config-TDX4VUGW.js.map +0 -1
  155. package/build/config-dir-V43W2WIA.js.map +0 -1
  156. package/build/doctor-5K5UWHNX.js.map +0 -1
  157. package/build/errors-E6MVUBNA.js.map +0 -1
  158. package/build/format-TSFSI2K7.js.map +0 -1
  159. package/build/init-YQ5NBICF.js.map +0 -1
  160. package/build/init-all-6OWEQALB.js +0 -274
  161. package/build/init-all-6OWEQALB.js.map +0 -1
  162. package/build/mcpServer-AEX3RQ4U.js +0 -20
  163. package/build/mcpServer-AEX3RQ4U.js.map +0 -1
  164. package/build/namespace-PVHBFDW2.js.map +0 -1
  165. package/build/open-YUIJP37F.js.map +0 -1
  166. package/build/output-IYJBFCYK.js.map +0 -1
  167. package/build/serve-KWNJK6EY.js.map +0 -1
  168. package/build/server.js.map +0 -1
  169. package/build/setup-YTUKMPNP.js.map +0 -1
  170. package/build/stdio.js.map +0 -1
  171. package/build/telemetry-5IPRKZBL.js.map +0 -1
  172. package/build/tools-PJHWFCAG.js.map +0 -1
  173. package/build/uninstall-HWXEIP6K.js.map +0 -1
  174. package/build/watch-KZ5EDZK3.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/server.ts","../src/middleware/rate-limit.ts","../src/utils/api-errors.ts","../src/health/index.ts","../src/health/testRunner.ts","../src/health/statusPage.ts","../src/health/mcpProtocol.ts","../src/services/unkey-service.ts","../src/db/supabase.ts","../src/health/workflowCanaries.ts","../src/config/cors.ts","../src/middleware/api-key.ts","../src/services/wallet-service.ts","../src/routes/auth.ts","../src/middleware/supabase-auth.ts","../src/utils/asyncHandler.ts","../src/routes/keys.ts","../src/middleware/idempotency.ts","../src/routes/usage.ts","../src/middleware/request-id.ts","../src/middleware/rate-limit-headers.ts","../src/middleware/cache-headers.ts","../src/utils/openapi.ts","../src/services/tool-execution.ts","../src/utils/mcpHttp.ts","../src/serverCard.ts"],"sourcesContent":["#!/usr/bin/env node\nimport dotenv from \"dotenv\";\ndotenv.config({ quiet: true });\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport {\n getCorsAllowedOrigins,\n getEnvVar,\n getNodeEnv,\n getPort,\n getRateLimitMax,\n} from \"./config/env.js\";\nimport { randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport express from \"express\";\nimport compression from \"compression\";\nimport cors from \"cors\";\nimport helmet from \"helmet\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { createIpRateLimiter } from \"./middleware/rate-limit.js\";\nimport { CategoryEndpoints } from \"./toolRegistry.js\";\nimport healthRouter, { markStartupComplete } from \"./health/index.js\";\nimport { secureLogger } from \"./utils/secureLogger.js\";\nimport { getCorsConfig } from \"./config/cors.js\";\nimport {\n createHiveMcpServer,\n SERVER_NAME,\n SERVER_VERSION,\n ServerScope,\n} from \"./mcpServer.js\";\nimport { trackServerEvent } from \"./utils/analytics.js\";\nimport { requireApiKey } from \"./middleware/api-key.js\";\nimport {\n isUnkeyConfigured,\n isUnkeyRequired,\n verifyApiKey,\n} from \"./services/unkey-service.js\";\nimport { consumeCredits } from \"./services/wallet-service.js\";\nimport authRouter from \"./routes/auth.js\";\nimport keysRouter from \"./routes/keys.js\";\nimport usageRouter from \"./routes/usage.js\";\nimport { getAllWrappedEndpoints } from \"./wrapper/index.js\";\nimport { requestIdMiddleware } from \"./middleware/request-id.js\";\nimport { rateLimitInfoHeaders } from \"./middleware/rate-limit-headers.js\";\nimport { cacheHeaders, etagSupport } from \"./middleware/cache-headers.js\";\nimport { apiError } from \"./utils/api-errors.js\";\nimport { generateOpenApiSpec } from \"./utils/openapi.js\";\nimport { idempotencyMiddleware } from \"./middleware/idempotency.js\";\nimport { executeToolByName } from \"./services/tool-execution.js\";\nimport {\n hasRequiredStreamableHttpAcceptHeader,\n isMcpPath,\n} from \"./utils/mcpHttp.js\";\nimport { asyncHandler } from \"./utils/asyncHandler.js\";\nimport { buildServerCard } from \"./serverCard.js\";\nimport {\n buildToolCatalogEntry,\n getRootVisibleToolCount,\n} from \"./utils/toolCatalog.js\";\n\nlet isShuttingDown = false;\nlet activeRequests = 0;\n\nconst app = express();\nconst port = getPort();\ntype CspNonceResponse = ServerResponse & {\n locals?: { cspNonce?: string };\n};\n\nexport function createHttpApp(): express.Express {\n return app;\n}\n\napp.set(\"trust proxy\", 1);\napp.use(requestIdMiddleware);\napp.use((_req, res, next) => {\n if (isShuttingDown) {\n res.setHeader(\"Connection\", \"close\");\n return res\n .status(503)\n .json(\n apiError(\"internal_error\", \"SHUTTING_DOWN\", \"Server is shutting down\"),\n );\n }\n activeRequests++;\n res.on(\"finish\", () => {\n activeRequests--;\n });\n return next();\n});\nconst RATE_LIMIT_MAX = getRateLimitMax();\nconst RATE_LIMIT_WINDOW_MS = 60_000;\n\napp.use(\n rateLimitInfoHeaders({\n limit: RATE_LIMIT_MAX,\n windowMs: RATE_LIMIT_WINDOW_MS,\n }),\n);\napp.use(compression()); // compression() already sets Vary: Accept-Encoding\napp.use(cacheHeaders());\napp.use(etagSupport());\napp.use((_req, res, next) => {\n res.locals.cspNonce = randomUUID().replace(/-/g, \"\");\n next();\n});\napp.use(\n helmet({\n contentSecurityPolicy: {\n directives: {\n defaultSrc: [\"'self'\"],\n scriptSrc: [\n \"'self'\",\n (_req: IncomingMessage, res: ServerResponse) =>\n `'nonce-${(res as CspNonceResponse).locals?.cspNonce ?? \"\"}'`,\n \"https://www.googletagmanager.com\",\n \"https://cdn.tailwindcss.com\",\n \"https://unpkg.com\",\n ],\n styleSrc: [\"'self'\", \"'unsafe-inline'\", \"https://unpkg.com\"],\n imgSrc: [\"'self'\", \"data:\"],\n connectSrc: [\n \"'self'\",\n \"https://www.google-analytics.com\",\n \"https://www.google.com\",\n ],\n fontSrc: [\"'self'\"],\n objectSrc: [\"'none'\"],\n frameSrc: [\"'none'\"],\n },\n },\n referrerPolicy: { policy: \"no-referrer\" },\n }),\n);\napp.use(cors(getCorsConfig()));\n\n// MCP spec §12.2: Servers MUST validate the Origin header to prevent DNS rebinding\nconst ALLOWED_MCP_ORIGINS = getCorsAllowedOrigins();\nconst LOCALHOST_RE = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?$/;\napp.use(\n (req: express.Request, res: express.Response, next: express.NextFunction) => {\n if (\n req.method === \"POST\" &&\n (req.path === \"/mcp\" || req.path.endsWith(\"/mcp\"))\n ) {\n const origin = req.headers.origin;\n if (\n origin &&\n !LOCALHOST_RE.test(origin) &&\n ALLOWED_MCP_ORIGINS.length > 0 &&\n !ALLOWED_MCP_ORIGINS.includes(origin)\n ) {\n res.status(403).json({\n jsonrpc: \"2.0\",\n error: { code: -32600, message: \"Origin not allowed\" },\n id: null,\n });\n return;\n }\n }\n next();\n },\n);\n\napp.use(\n (\n req: express.Request,\n res: express.Response,\n next: express.NextFunction,\n ): void => {\n if (\n req.method === \"POST\" &&\n isMcpPath(req.path) &&\n !hasRequiredStreamableHttpAcceptHeader(req.headers.accept)\n ) {\n res.status(406).json({\n jsonrpc: \"2.0\",\n error: {\n code: -32600,\n message:\n \"Invalid Accept header. MCP Streamable HTTP POST requests must accept both application/json and text/event-stream.\",\n },\n id: null,\n });\n return;\n }\n next();\n },\n);\n\napp.use(\n express.json({\n limit: \"1mb\",\n type: \"application/json\",\n }),\n);\n\napp.use(\n (\n err: Error,\n req: express.Request,\n res: express.Response,\n next: express.NextFunction,\n ) => {\n if (err instanceof SyntaxError && \"body\" in err) {\n secureLogger.warn(\"JSON parse error\", {\n path: req.path,\n method: req.method,\n errorMessage: err.message,\n });\n return res.status(400).json({\n jsonrpc: \"2.0\",\n error: {\n code: -32700,\n message: \"Parse error: Invalid JSON\",\n },\n id: null,\n });\n }\n return next(err);\n },\n);\n\n// OAuth is not supported — return clean 404s for all OAuth/OIDC endpoints\n// the MCP SDK probes during its auth flow. Without these, our JSON catch-all\n// 404 has `error` as an object which breaks the SDK's Zod parser (expects a string).\nconst oauthNotSupported: express.RequestHandler = (_req, res) => {\n res.status(404).end();\n};\napp.get(\"/.well-known/oauth-authorization-server\", oauthNotSupported);\napp.get(\"/.well-known/oauth-authorization-server/*\", oauthNotSupported);\napp.get(\"/.well-known/oauth-protected-resource\", oauthNotSupported);\napp.get(\"/.well-known/oauth-protected-resource/*\", oauthNotSupported);\napp.get(\"/.well-known/openid-configuration\", oauthNotSupported);\napp.get(\"/.well-known/openid-configuration/*\", oauthNotSupported);\napp.all(\"/register\", oauthNotSupported);\napp.all(\"/authorize\", oauthNotSupported);\napp.all(\"/token\", oauthNotSupported);\napp.all(\"/revoke\", oauthNotSupported);\n\nfunction buildMcpDiscoveryDescriptor() {\n return {\n name: \"Hive Intelligence\",\n id: SERVER_NAME,\n version: SERVER_VERSION,\n description:\n \"Institutional-grade crypto market infrastructure for AI — unified API for crypto market data, DeFi, wallets, security, DEX flows, NFTs, and prediction markets\",\n endpoints: {\n mcp: \"/mcp\",\n rest: \"/api/v1\",\n openapi: \"/api/openapi.json\",\n docs: \"https://www.hiveintelligence.xyz/quick-start\",\n },\n package: {\n name: \"hive-intelligence\",\n command: \"hive\",\n install: \"npx -y -p hive-intelligence@latest hive\",\n stdio_args: [\"-y\", \"-p\", \"hive-intelligence@latest\", \"hive\"],\n },\n capabilities: [\"tools\", \"resources\", \"prompts\"],\n tool_count: getRootVisibleToolCount(),\n visible_tool_count: getRootVisibleToolCount(),\n underlying_tool_count: getAllWrappedEndpoints().length,\n categories: Object.keys(CategoryEndpoints).length,\n };\n}\n\nfunction setDiscoveryHeaders(res: express.Response) {\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\"Cache-Control\", \"public, max-age=300\");\n}\n\napp.get([\"/.well-known/mcp.json\", \"/mcp.json\"], (_req, res) => {\n setDiscoveryHeaders(res);\n res.json(buildMcpDiscoveryDescriptor());\n});\n\n// SEP-1649 server-card.json — richer discovery surface for MCP clients and\n// directory crawlers. Served from the MCP host directly so clients that look\n// up `/.well-known/mcp/server-card.json` against the server URL find it.\napp.get(\n [\"/.well-known/mcp/server-card.json\", \"/server-card.json\", \"/mcp/server-card.json\"],\n (_req, res) => {\n setDiscoveryHeaders(res);\n res.json(buildServerCard());\n },\n);\n\nfunction pingHandler(_req: express.Request, res: express.Response) {\n res.json({\n status: \"ok\",\n message: \"Hive MCP Server is running\",\n version: SERVER_VERSION,\n endpoints: {\n health: \"/health\",\n mcp: \"/mcp\",\n status: \"/status\",\n apiHealth: \"/api/health\",\n },\n });\n}\n\napp.get(\"/ping\", pingHandler);\napp.get(\"/health\", pingHandler);\n\napp.use(healthRouter);\n\n// ─── Auth, Key Management & Usage Routes ─────────────────────────────\napp.use(\"/auth\", authRouter);\napp.use(\"/api/v1/keys\", keysRouter);\napp.use(\"/api/v1/usage\", usageRouter);\n\n// IP-based rate limiters — created at startup (not lazily) to avoid\n// express-rate-limit ERR_ERL_CREATED_IN_REQUEST_HANDLER warning.\nconst mcpIpRateLimiter = createIpRateLimiter();\nconst restIpRateLimiter = createIpRateLimiter();\n\n// MCP routes do NOT use the Express requireApiKey middleware because HTTP 401/403\n// triggers the SDK's automatic OAuth flow. Instead we validate the key inside the\n// handler and return a JSON-RPC error (HTTP 200) so the SDK treats it as a\n// protocol-level error rather than starting OAuth discovery.\nconst mcpMiddlewares = [mcpIpRateLimiter];\n\n// Bounded-latency wrapper. Used to gate auth round-trips so a slow/down\n// Unkey doesn't stall every MCP request behind it.\nfunction withTimeout<T>(p: Promise<T>, ms: number): Promise<T> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new Error(`timeout after ${ms}ms`));\n }, ms);\n p.then(\n (v) => {\n clearTimeout(timer);\n resolve(v);\n },\n (err) => {\n clearTimeout(timer);\n reject(err);\n },\n );\n });\n}\n\n// Fire-and-forget Supabase debit. Caller doesn't await; insufficient-\n// credit gating happens on the next request (eventual consistency).\nfunction debitCreditsAsync(args: {\n userId: string;\n keyId?: string;\n requestId?: string;\n}): void {\n consumeCredits({\n userId: args.userId,\n cost: 1,\n idempotencyKey: args.requestId ?? randomUUID(),\n requestId: args.requestId,\n keyId: args.keyId,\n }).catch((err) => {\n secureLogger.error(\"MCP consume_credits async debit failed\", err, {});\n });\n}\n\nfunction extractApiKey(req: express.Request): string | undefined {\n return (\n (req.headers[\"x-api-key\"] as string) ??\n (req.headers.authorization?.startsWith(\"Bearer \")\n ? req.headers.authorization.slice(7)\n : undefined)\n );\n}\n\nasync function validateMcpApiKey(req: express.Request): Promise<string | null> {\n const key = extractApiKey(req);\n\n if (isUnkeyRequired() && !isUnkeyConfigured()) {\n return \"Unkey authentication is selected but not configured. Set UNKEY_ROOT_KEY and UNKEY_API_ID, or set HIVE_AUTH_BACKEND=static with HIVE_API_KEYS.\";\n }\n\n if (isUnkeyConfigured()) {\n if (!key)\n return \"API key required. Get a free key at https://hiveintelligence.xyz/dashboard/keys then pass it as 'Authorization: Bearer <key>' or 'x-api-key: <key>'. Claude Code: claude mcp add --transport http hive https://mcp.hiveintelligence.xyz/mcp --header \\\"Authorization: Bearer <key>\\\".\";\n\n // Unkey verification is security-critical; on timeout we deny rather\n // than fail-open. 500ms is generous for an Unkey RPC; if it's slower\n // than that, treat it as unavailable.\n let result: Awaited<ReturnType<typeof verifyApiKey>>;\n try {\n result = await withTimeout(verifyApiKey(key, getMcpAnalyticsTags(req)), 500);\n } catch (err) {\n secureLogger.warn(\"MCP Unkey verifyApiKey timeout/failure\", {\n error: err instanceof Error ? err.message : String(err),\n });\n return \"Authentication service temporarily unavailable. Please retry in a moment.\";\n }\n if (!result.valid) {\n if (result.code === \"RATE_LIMITED\") return \"Rate limit exceeded.\";\n return \"Invalid API key.\";\n }\n if (!result.userId) {\n return \"Invalid API key.\";\n }\n\n // Wallet-level credit accounting. The MCP path bypasses requireApiKey\n // so we must debit here too — otherwise MCP traffic would be free.\n //\n // Latency strategy: fire-and-forget the debit so the hot path doesn't\n // serialize through Supabase RPC. Insufficient-credit gating happens\n // on the NEXT request — eventual consistency for billing. The trade\n // is one free MCP call per credit-exhaustion edge; acceptable for\n // trader-tier billing and a 5x latency win on the 99% case.\n void debitCreditsAsync({\n userId: result.userId,\n keyId: result.keyId,\n requestId: req.requestId,\n });\n return null;\n }\n\n const validKeys = (process.env.HIVE_API_KEYS || \"\")\n .split(\",\")\n .filter(Boolean);\n\n if (validKeys.length === 0) {\n return \"API key authentication is not configured on this server.\";\n }\n\n if (!key)\n return \"API key required. Set x-api-key header or Authorization: Bearer <key>.\";\n if (!validKeys.includes(key)) return \"Invalid API key.\";\n return null;\n}\n\nfunction getMcpAnalyticsTags(req: express.Request): string[] {\n const body = req.body as\n | {\n method?: unknown;\n params?: {\n name?: unknown;\n arguments?: {\n endpoint_name?: unknown;\n args?: { endpoint_name?: unknown };\n };\n };\n }\n | undefined;\n\n const tags = [\"service=hive\", \"transport=mcp\"];\n if (typeof body?.method === \"string\") {\n tags.push(`mcp_method=${body.method}`);\n }\n\n if (body?.method === \"tools/call\" && typeof body.params?.name === \"string\") {\n tags.push(`mcp_tool=${body.params.name}`);\n\n const args = body.params.arguments;\n const endpointName =\n typeof args?.endpoint_name === \"string\"\n ? args.endpoint_name\n : typeof args?.args?.endpoint_name === \"string\"\n ? args.args.endpoint_name\n : body.params.name !== \"invoke_api_endpoint\"\n ? body.params.name\n : undefined;\n\n if (endpointName) {\n tags.push(`endpoint=${endpointName}`);\n }\n }\n\n return tags;\n}\n\nfunction createStatelessMcpHandler(scope: ServerScope) {\n return async (req: express.Request, res: express.Response) => {\n const sessionCorrelationId = req.requestId!;\n\n // Validate API key — return JSON-RPC error (not HTTP 401) on failure\n const authError = await validateMcpApiKey(req);\n if (authError) {\n res.status(200).json({\n jsonrpc: \"2.0\",\n error: { code: -32001, message: authError },\n id: req.body?.id ?? null,\n });\n return;\n }\n\n try {\n // Normalize flat args for invoke_api_endpoint: move top-level keys\n // (ids, vs_currencies, etc.) into nested `args` object so the MCP SDK's\n // schema validation doesn't strip them.\n const body = req.body;\n if (\n body?.method === \"tools/call\" &&\n body?.params?.name === \"invoke_api_endpoint\" &&\n body?.params?.arguments\n ) {\n const a = body.params.arguments;\n if (!a.args && a.endpoint_name) {\n const { endpoint_name, response_format, ...rest } = a;\n if (Object.keys(rest).length > 0) {\n body.params.arguments = {\n endpoint_name,\n response_format,\n args: rest,\n };\n }\n }\n }\n\n const server = createHiveMcpServer(scope).getServer();\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n enableJsonResponse: true,\n });\n\n res.on(\"close\", () => {\n transport.close();\n server.close();\n });\n\n await server.connect(transport);\n await transport.handleRequest(req, res, body);\n\n secureLogger.debug(\"MCP request completed\", {\n sessionId: sessionCorrelationId,\n scope: scope.kind === \"root\" ? \"root\" : `category:${scope.category}`,\n });\n } catch (error) {\n secureLogger.error(\"Error handling MCP request\", error, {\n sessionId: sessionCorrelationId,\n scope: scope.kind === \"root\" ? \"root\" : `category:${scope.category}`,\n });\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: \"2.0\",\n error: {\n code: -32603,\n message: \"Internal server error\",\n },\n id: null,\n });\n }\n }\n };\n}\n\nconst rootMcpHandler = createStatelessMcpHandler({ kind: \"root\" });\n\napp.post([\"/mcp\", \"/mcp/\"], ...mcpMiddlewares, rootMcpHandler);\n\nObject.entries(CategoryEndpoints).forEach(([categoryIndex, endpointPath]) => {\n const handler = createStatelessMcpHandler({\n kind: \"category\",\n category: Number(categoryIndex),\n });\n\n app.post([endpointPath, `${endpointPath}/`], ...mcpMiddlewares, handler);\n});\n\n// GET: Anthropic's native MCP client probes with GET for SSE.\n// Stateless server has no SSE streams — return empty 200 so the client\n// proceeds to POST without erroring on 405.\nconst mcpPaths = [\n \"/mcp\",\n \"/mcp/\",\n ...Object.values(CategoryEndpoints).flatMap((p) => [p, `${p}/`]),\n];\napp.get(mcpPaths, (_req: express.Request, res: express.Response) => {\n res\n .writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"close\",\n })\n .end();\n});\napp.delete(mcpPaths, (_req: express.Request, res: express.Response) => {\n res.writeHead(405, { Allow: \"POST\" }).end();\n});\n\napp.post(\n \"/api/run-tests\",\n restIpRateLimiter,\n asyncHandler(async (req: express.Request, res: express.Response) => {\n const authToken = req.headers[\"x-monitor-secret\"];\n const monitorSecret = getEnvVar(\"MONITOR_SECRET\");\n let isAuthorized = false;\n if (monitorSecret && typeof authToken === \"string\") {\n const a = Buffer.from(authToken);\n const b = Buffer.from(monitorSecret);\n isAuthorized = a.length === b.length && timingSafeEqual(a, b);\n }\n\n secureLogger.authEvent(\"monitor-tests-access\", isAuthorized, {\n hasToken: !!authToken,\n ip: req.ip || req.socket?.remoteAddress,\n });\n\n if (!isAuthorized) {\n return res\n .status(401)\n .json(apiError(\"authentication_error\", \"UNAUTHORIZED\", \"Unauthorized\"));\n }\n\n secureLogger.info(\"MCP test suite triggered by monitoring system\");\n\n try {\n return res.status(200).json({\n status: \"healthy\",\n timestamp: new Date().toISOString(),\n summary: {\n total: 1,\n passed: 1,\n failed: 0,\n passRate: \"100.0%\",\n },\n message: \"Server is healthy. For comprehensive tests, run: npm test\",\n note: \"Legacy MCPTestRunner removed. Use vitest for testing: npm run test\",\n server: SERVER_NAME,\n version: SERVER_VERSION,\n endpoints: Object.keys(CategoryEndpoints).length + 1,\n });\n } catch (error) {\n secureLogger.error(\"Health check failed\", error);\n return res.status(500).json({\n status: \"error\",\n error: \"An internal error occurred\",\n timestamp: new Date().toISOString(),\n });\n }\n }),\n);\n\n// ─── v1 REST API (for CLI tool + agents) ─────────────────────────────\n// These run alongside the MCP protocol on the same port.\n// CLI calls these directly; MCP clients use /mcp.\n\n// API version headers on all /api/* responses\napp.use(\"/api\", (_req, res, next) => {\n res.setHeader(\"API-Version\", \"v1\");\n res.setHeader(\"Deprecation\", \"false\");\n next();\n});\n\napp.use(\"/api/v1\", restIpRateLimiter);\n\napp.get(\"/api/v1/tools\", requireApiKey, (req, res) => {\n const allEndpoints = getAllWrappedEndpoints();\n const limit = Math.min(parseInt(req.query.limit as string, 10) || 50, 250);\n const cursor = req.query.cursor as string | undefined;\n const search = req.query.search as string | undefined;\n\n let filtered = allEndpoints;\n if (search) {\n const q = search.toLowerCase();\n filtered = filtered.filter(\n (ep) =>\n ep.tool.name.includes(q) ||\n (ep.tool.description ?? \"\").toLowerCase().includes(q),\n );\n }\n\n const sortBy = req.query.sort as string | undefined;\n const order = (req.query.order as string | undefined) ?? \"asc\";\n if (sortBy === \"name\") {\n filtered = [...filtered].sort((a, b) => {\n const cmp = a.tool.name.localeCompare(b.tool.name);\n return order === \"desc\" ? -cmp : cmp;\n });\n }\n\n let startIndex = 0;\n if (cursor) {\n const cursorIdx = filtered.findIndex((ep) => ep.tool.name === cursor);\n if (cursorIdx >= 0) startIndex = cursorIdx + 1;\n }\n\n const page = filtered.slice(startIndex, startIndex + limit);\n const hasMore = startIndex + limit < filtered.length;\n\n const tools = page.map((ep) => buildToolCatalogEntry(ep));\n\n const fields = req.query.fields as string | undefined;\n let result: Record<string, unknown>[] = tools;\n if (fields) {\n const fieldList = fields.split(\",\").map((f) => f.trim());\n result = tools.map((t) => {\n const picked: Record<string, unknown> = {};\n for (const f of fieldList) {\n if (f in t) picked[f] = (t as Record<string, unknown>)[f];\n }\n return picked;\n });\n }\n\n return res.json({\n ok: true,\n data: result,\n has_more: hasMore,\n ...(hasMore &&\n page.length > 0 && { next_cursor: page[page.length - 1].tool.name }),\n meta: {\n total: filtered.length,\n returned: result.length,\n ...(sortBy && { sort: sortBy, order }),\n },\n });\n});\n\napp.post(\n \"/api/v1/execute\",\n requireApiKey,\n idempotencyMiddleware(),\n asyncHandler(async (req, res) => {\n const { tool: toolName, args } = req.body as {\n tool?: string;\n args?: Record<string, unknown>;\n };\n\n if (!toolName || typeof toolName !== \"string\") {\n return res.status(400).json({\n ...apiError(\n \"invalid_request_error\",\n \"MISSING_PARAM\",\n '\"tool\" field is required.',\n {\n param: \"tool\",\n requestId: req.requestId,\n },\n ),\n meta: { tool: toolName ?? null, duration_ms: 0 },\n });\n }\n\n const result = await executeToolByName(toolName, args ?? {});\n const meta = {\n tool: toolName,\n duration_ms: result.durationMs,\n provider: result.meta.provider,\n category: result.meta.category,\n runtime_status: result.meta.runtime_status,\n fetched_at: result.meta.fetched_at,\n cache_status: result.meta.cache_status,\n source: result.meta.source,\n truncated: result.meta.truncated,\n warnings: result.meta.warnings,\n };\n\n if (result.ok) {\n return res.json({ ok: true, data: result.data, meta });\n }\n\n const error = result.error!;\n const statusMap: Record<string, number> = {\n TOOL_NOT_FOUND: 404,\n VALIDATION_ERROR: 422,\n PROVIDER_UNAVAILABLE: 503,\n TOOL_ERROR: 400,\n INTERNAL_ERROR: 500,\n };\n const status = statusMap[error.code] ?? 500;\n\n return res.status(status).json({\n ...apiError(error.type, error.code, error.message, {\n requestId: req.requestId,\n }),\n meta,\n ...(result.validationErrors && {\n validation_errors: result.validationErrors,\n }),\n });\n }),\n);\n\n// OpenAPI spec is public — it's API documentation, not sensitive data.\n// Swagger UI at /docs fetches this client-side without auth.\napp.get(\"/api/openapi.json\", (_req, res) => {\n res.json(generateOpenApiSpec());\n});\n\n// Interactive API docs powered by Swagger UI (loaded from CDN — zero deps)\napp.get(\"/docs\", (_req, res) => {\n res.setHeader(\"Content-Type\", \"text/html\");\n res.send(`<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Hive API Docs</title>\n <link rel=\"stylesheet\" href=\"https://unpkg.com/swagger-ui-dist@5/swagger-ui.css\">\n</head>\n<body>\n <div id=\"swagger-ui\"></div>\n <script src=\"https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js\"></script>\n <script>\n SwaggerUIBundle({\n url: '/api/openapi.json',\n dom_id: '#swagger-ui',\n deepLinking: true,\n presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],\n layout: 'BaseLayout',\n });\n </script>\n</body>\n</html>`);\n});\n\napp.get(\"/\", (_req, res) => {\n res.json({\n status: \"ok\",\n message: \"Hive MCP Service is running\",\n version: SERVER_VERSION,\n note: \"Use /mcp for MCP protocol, /api/v1/execute for REST API.\",\n });\n});\n\n// 404 catch-all — do not enumerate endpoints\napp.use((_req, res) => {\n res\n .status(404)\n .json(\n apiError(\"not_found_error\", \"ENDPOINT_NOT_FOUND\", \"Endpoint not found.\"),\n );\n});\n\n// Global error handler — catches errors from next(err) in routes/middleware\napp.use(\n (\n err: Error,\n _req: express.Request,\n res: express.Response,\n _next: express.NextFunction,\n ) => {\n secureLogger.error(\"Unhandled express error\", err, {});\n if (!res.headersSent) {\n res\n .status(500)\n .json(\n apiError(\n \"internal_error\",\n \"INTERNAL_ERROR\",\n \"An unexpected error occurred.\",\n ),\n );\n }\n },\n);\n\nasync function setupServer() {\n secureLogger.info(\"Setting up Hive MCP server...\", {\n server: SERVER_NAME,\n version: SERVER_VERSION,\n port,\n });\n\n // --- Optional API key warnings ---\n const optionalApiKeys = [\n \"COINGECKO_PRO_API_KEY\",\n \"CODEX_API_KEY\",\n \"GOPLUS_APP_KEY\",\n \"GOPLUS_APP_SECRET\",\n \"ALCHEMY_API_KEY\",\n \"MORALIS_API_KEY\",\n \"TENDERLY_API_KEY\",\n \"TENDERLY_NODE_ACCESS_KEY\",\n \"TENDERLY_GATEWAY_ACCESS_KEY\",\n \"HELIUS_API_KEY\",\n ] as const;\n\n const configured: string[] = [];\n const degraded: string[] = [];\n\n for (const key of optionalApiKeys) {\n if (getEnvVar(key)) {\n configured.push(key);\n } else {\n degraded.push(key);\n secureLogger.warn(\n `${key} is not set — provider will run in degraded mode`,\n {},\n );\n }\n }\n\n // --- Infrastructure warnings ---\n if (!getEnvVar(\"MONITOR_SECRET\")) {\n secureLogger.warn(\n \"MONITOR_SECRET is not set — test endpoints will be inaccessible\",\n {},\n );\n }\n\n if (!getEnvVar(\"REDIS_URL\")) {\n secureLogger.warn(\n \"REDIS_URL is not set — rate limiting will fall back to in-memory\",\n {},\n );\n }\n\n if (getNodeEnv() === \"production\" && ALLOWED_MCP_ORIGINS.length === 0) {\n secureLogger.warn(\n \"CORS_ALLOWED_ORIGINS is not set in production — CORS may be too permissive\",\n {},\n );\n }\n\n if (!getEnvVar(\"GA_MEASUREMENT_ID\") || !getEnvVar(\"GA_API_SECRET\")) {\n secureLogger.warn(\n \"GA_MEASUREMENT_ID or GA_API_SECRET is not set — analytics disabled\",\n {},\n );\n }\n\n // --- Provider summary ---\n secureLogger.info(\"Provider configuration summary\", {\n configured: configured.length,\n degraded: degraded.length,\n configuredProviders: configured.join(\", \") || \"(none)\",\n degradedProviders: degraded.join(\", \") || \"(none)\",\n });\n}\n\nfunction installProcessSafetyNets(): void {\n process.on(\"unhandledRejection\", (reason) => {\n secureLogger.error(\"Unhandled promise rejection\", reason as Error, {});\n });\n\n process.on(\"uncaughtException\", (error) => {\n secureLogger.error(\"Uncaught exception — shutting down\", error, {});\n process.exit(1);\n });\n}\n\nexport async function startHttpServer() {\n const PORT = port;\n await setupServer();\n\n const httpServer = app.listen(PORT, () => {\n secureLogger.info(\n `MCP Stateless Streamable HTTP Server listening on port ${PORT}`,\n );\n trackServerEvent({\n event: \"server_start\",\n details: { port: Number(PORT) },\n });\n markStartupComplete();\n });\n\n // Handle bind errors (e.g. EADDRINUSE)\n httpServer.on(\"error\", (err) => {\n secureLogger.error(\"Failed to start server\", err);\n process.exit(1);\n });\n\n // Connection limits\n httpServer.keepAliveTimeout = 65_000;\n httpServer.headersTimeout = 70_000;\n\n // Graceful shutdown — wait for active requests to drain\n const shutdown = (signal: string) => {\n if (isShuttingDown) return;\n isShuttingDown = true;\n secureLogger.info(\n `${signal} received — draining ${activeRequests} active requests`,\n );\n\n httpServer.close(() => {\n secureLogger.info(\"HTTP server closed\", { activeRequests });\n process.exit(0);\n });\n\n // Poll active requests — exit early once drained\n const drainInterval = setInterval(() => {\n if (activeRequests <= 0) {\n clearInterval(drainInterval);\n secureLogger.info(\"All requests drained, closing\");\n httpServer.close(() => process.exit(0));\n }\n }, 500);\n drainInterval.unref();\n\n const forceTimer = setTimeout(() => {\n clearInterval(drainInterval);\n secureLogger.warn(\"Force shutdown after 10s timeout\", {\n activeRequests,\n });\n process.exit(1);\n }, 10_000);\n forceTimer.unref();\n };\n\n process.on(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\n process.on(\"SIGINT\", () => shutdown(\"SIGINT\"));\n\n return httpServer;\n}\n\nfunction isMainModule(): boolean {\n const entrypoint = process.argv[1];\n return Boolean(\n entrypoint && resolve(entrypoint) === fileURLToPath(import.meta.url),\n );\n}\n\nif (isMainModule()) {\n installProcessSafetyNets();\n startHttpServer().catch((error) => {\n secureLogger.error(\"Failed to set up the server\", error);\n process.exit(1);\n });\n}\n\nexport default app;\n","import { Request } from \"express\";\nimport rateLimit from \"express-rate-limit\";\nimport RedisStore, { type SendCommandFn } from \"rate-limit-redis\";\nimport { getRedisClient, isRedisAvailable } from \"../utils/redis.js\";\nimport { apiError } from \"../utils/api-errors.js\";\nimport { getEnvVar, getNodeEnv, getRateLimitMax } from \"../config/env.js\";\nimport { secureLogger } from \"../utils/secureLogger.js\";\n\n// IP-based rate limiter. In production we REQUIRE REDIS_URL to be configured.\n// Redis connects asynchronously during module load, so do not require\n// isRedisAvailable() to be true while constructing middleware; ioredis queues\n// commands until the connection is ready.\nexport const createIpRateLimiter = () => {\n const maxRequests = getRateLimitMax();\n const redisClient = getRedisClient();\n const isProduction = getNodeEnv() === \"production\";\n\n if (isProduction && !redisClient) {\n // In prod we throw at construction time so the server crashloops on\n // missing Redis config rather than silently running per-instance limits.\n throw new Error(\n \"REDIS_URL is required in production for the rate limiter. \" +\n \"In-memory fallback is per-instance and bypasses limits at scale.\",\n );\n }\n\n if (!redisClient) {\n secureLogger.warn(\n \"[rate-limit] No Redis — using per-instance in-memory store. OK for local dev only.\",\n {},\n );\n } else if (!isRedisAvailable()) {\n secureLogger.info(\"[rate-limit] Redis configured; connection pending\", {});\n }\n\n const storeConfig =\n redisClient\n ? {\n store: new RedisStore({\n sendCommand: ((...args: string[]) =>\n redisClient.call(\n args[0],\n ...args.slice(1),\n ) as ReturnType<SendCommandFn>) satisfies SendCommandFn,\n prefix: \"rl:ip:\",\n }),\n }\n : {};\n\n return rateLimit({\n ...storeConfig,\n windowMs: 60 * 1000,\n max: maxRequests,\n standardHeaders: true,\n legacyHeaders: false,\n keyGenerator: (req: Request) =>\n req.ip || req.socket?.remoteAddress || \"anon\",\n skip: (req: Request) => {\n const secret = getEnvVar(\"MONITOR_SECRET\");\n return !!(secret && req.headers[\"x-monitor-secret\"] === secret);\n },\n handler: (_req, res) => {\n res.setHeader(\"Retry-After\", \"60\");\n res\n .status(429)\n .json(\n apiError(\n \"rate_limit_error\",\n \"RATE_LIMITED\",\n `Rate limit exceeded. Maximum ${maxRequests} requests per minute.`,\n ),\n );\n },\n });\n};\n","export type ApiErrorType =\n | \"invalid_request_error\"\n | \"authentication_error\"\n | \"rate_limit_error\"\n | \"not_found_error\"\n | \"provider_error\"\n | \"internal_error\";\n\nconst ERROR_DOC_BASE = \"https://www.hiveintelligence.xyz/errors\";\n\nconst ERROR_DOC_URLS: Record<string, string> = {\n MISSING_PARAM: `${ERROR_DOC_BASE}#missing-param`,\n TOOL_NOT_FOUND: `${ERROR_DOC_BASE}#tool-not-found`,\n TOOL_ERROR: `${ERROR_DOC_BASE}#tool-error`,\n PROVIDER_UNAVAILABLE: `${ERROR_DOC_BASE}#provider-unavailable`,\n RATE_LIMITED: `${ERROR_DOC_BASE}#rate-limited`,\n INTERNAL_ERROR: `${ERROR_DOC_BASE}#internal-error`,\n ENDPOINT_NOT_FOUND: `${ERROR_DOC_BASE}#endpoint-not-found`,\n SHUTTING_DOWN: `${ERROR_DOC_BASE}#shutting-down`,\n UNAUTHORIZED: `${ERROR_DOC_BASE}#unauthorized`,\n VALIDATION_ERROR: `${ERROR_DOC_BASE}#validation-error`,\n};\n\nexport interface ApiErrorEnvelope {\n ok: false;\n error: {\n type: ApiErrorType;\n code: string;\n message: string;\n param?: string;\n request_id?: string;\n doc_url: string;\n };\n}\n\nexport function apiError(\n type: ApiErrorType,\n code: string,\n message: string,\n opts?: { param?: string; requestId?: string },\n): ApiErrorEnvelope {\n return {\n ok: false,\n error: {\n type,\n code,\n message,\n ...(opts?.param && { param: opts.param }),\n ...(opts?.requestId && { request_id: opts.requestId }),\n doc_url:\n ERROR_DOC_URLS[code] ??\n `${ERROR_DOC_BASE}#${code.toLowerCase().replace(/_/g, \"-\")}`,\n },\n };\n}\n","/**\n * Health Check Routes for API Status Page\n *\n * Provides endpoints for viewing and running API tests:\n * - GET /status - HTML status page\n * - GET /api/health - JSON health data\n * - GET /api/health/quick - Quick health check\n * - GET /api/health/:apiName - Single API health check\n */\n\nimport { timingSafeEqual } from \"node:crypto\";\nimport { Router, Request, Response } from \"express\";\nimport {\n runAllTests,\n runApiTests,\n runQuickHealthCheck,\n getAvailableApis,\n AllTestResults,\n} from \"./testRunner.js\";\nimport {\n generateStatusPageHtml,\n generateLoadingPageHtml,\n} from \"./statusPage.js\";\nimport {\n getTaskCanaryCatalog,\n getTaskCanaryHistory,\n runTaskCanariesQuick,\n runTaskCanary,\n} from \"./taskCanaries.js\";\nimport {\n runMcpProtocolHealth,\n type McpProtocolHealth,\n} from \"./mcpProtocol.js\";\nimport {\n getWorkflowRegressionCatalog,\n getWorkflowRegressionHistory,\n runWorkflowRegressionCanaries,\n} from \"./workflowCanaries.js\";\nimport { secureLogger } from \"../utils/secureLogger.js\";\n\nconst router = Router();\n\n// Cache for test results (expires after 5 minutes)\nlet cachedResults: AllTestResults | null = null;\nlet cacheTimestamp: number = 0;\nconst CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n\n// Track running tests\nlet isRunningTests = false;\nlet runningTestsPromise: Promise<AllTestResults | null> | null = null;\nlet runningFullTestsPromise: Promise<AllTestResults | null> | null = null;\nlet cachedMcpProtocolHealth: McpProtocolHealth | null = null;\nlet cachedMcpProtocolTimestamp = 0;\nlet runningMcpProtocolPromise: Promise<McpProtocolHealth> | null = null;\nconst MCP_PROTOCOL_CACHE_TTL_MS = 60 * 1000;\n\nfunction startFullHealthRun(): Promise<AllTestResults | null> {\n if (!runningFullTestsPromise) {\n isRunningTests = true;\n runningFullTestsPromise = runAllTests()\n .then((results) => {\n cachedResults = results;\n cacheTimestamp = Date.now();\n return results;\n })\n .catch((error) => {\n secureLogger.error(\"Error running full health tests\", error, {});\n return null;\n })\n .finally(() => {\n isRunningTests = false;\n runningFullTestsPromise = null;\n });\n }\n\n return runningFullTestsPromise;\n}\n\n/**\n * Verify monitor secret for test-triggering endpoints.\n * Returns true if authorized (secret matches or no ?run=true requested).\n */\nfunction isMonitorAuthorized(req: Request): boolean {\n const MONITOR_SECRET = process.env.MONITOR_SECRET;\n if (!MONITOR_SECRET) return false; // No secret configured = no test execution\n const authToken = req.headers[\"x-monitor-secret\"];\n if (typeof authToken !== \"string\") return false;\n const a = Buffer.from(authToken);\n const b = Buffer.from(MONITOR_SECRET);\n return a.length === b.length && timingSafeEqual(a, b);\n}\n\n/**\n * Get cached results or return empty results\n */\nfunction getCachedOrEmptyResults(): AllTestResults {\n if (cachedResults && Date.now() - cacheTimestamp < CACHE_TTL_MS) {\n return cachedResults;\n }\n\n // Empty health evidence must not be reported as healthy.\n return {\n status: \"unhealthy\",\n totalApis: 0,\n healthyApis: 0,\n degradedApis: 0,\n unhealthyApis: 0,\n inactiveApis: 0,\n totalTests: 0,\n passedTests: 0,\n failedTests: 0,\n duration: 0,\n apis: [],\n timestamp: new Date().toISOString(),\n };\n}\n\nfunction getScriptNonce(res: Response): string | undefined {\n return typeof res.locals.cspNonce === \"string\"\n ? res.locals.cspNonce\n : undefined;\n}\n\nasync function getCachedMcpProtocolHealth(): Promise<McpProtocolHealth> {\n if (\n cachedMcpProtocolHealth &&\n Date.now() - cachedMcpProtocolTimestamp < MCP_PROTOCOL_CACHE_TTL_MS\n ) {\n return cachedMcpProtocolHealth;\n }\n\n if (!runningMcpProtocolPromise) {\n runningMcpProtocolPromise = runMcpProtocolHealth({\n includeLiveInvoke: false,\n })\n .then((result) => {\n cachedMcpProtocolHealth = result;\n cachedMcpProtocolTimestamp = Date.now();\n return result;\n })\n .finally(() => {\n runningMcpProtocolPromise = null;\n });\n }\n\n return runningMcpProtocolPromise;\n}\n\n/**\n * HTML Status Page\n * GET /status\n */\nrouter.get(\"/status\", async (req: Request, res: Response) => {\n try {\n // If tests are currently running, show loading page\n if (isRunningTests) {\n res.send(generateLoadingPageHtml(getScriptNonce(res)));\n return;\n }\n\n // Check if we should run tests (requires monitor secret)\n const shouldRun = req.query.run === \"true\" && isMonitorAuthorized(req);\n\n if (shouldRun) {\n startFullHealthRun();\n res.send(generateLoadingPageHtml(getScriptNonce(res)));\n return;\n }\n\n // If cache is empty and not running tests, auto-run quick check to populate\n if (!cachedResults || Date.now() - cacheTimestamp >= CACHE_TTL_MS) {\n if (!runningTestsPromise) {\n runningTestsPromise = (async () => {\n isRunningTests = true;\n try {\n const results = await runQuickHealthCheck();\n cachedResults = results;\n cacheTimestamp = Date.now();\n return results;\n } catch (error) {\n secureLogger.error(\"Error running auto quick check\", error, {});\n return null;\n } finally {\n isRunningTests = false;\n runningTestsPromise = null;\n }\n })();\n }\n await runningTestsPromise;\n }\n\n // Return cached results\n const results = getCachedOrEmptyResults();\n res.send(generateStatusPageHtml(results, false, getScriptNonce(res)));\n } catch (error) {\n secureLogger.error(\"Error rendering status page\", error, {});\n res.status(500).send(\"Error generating status page\");\n }\n});\n\n/**\n * JSON Health Endpoint - All APIs\n * GET /api/health\n */\nrouter.get(\"/api/health\", async (req: Request, res: Response) => {\n try {\n const shouldRun = req.query.run === \"true\" && isMonitorAuthorized(req);\n const shouldWait = req.query.wait === \"true\";\n\n if (shouldRun) {\n const runPromise = startFullHealthRun();\n if (shouldWait) {\n const results = await runPromise;\n res.json(results ?? getCachedOrEmptyResults());\n return;\n }\n\n res.status(202).json({\n status: \"running\",\n message:\n \"Full provider health check started. Poll /api/health for cached results.\",\n running: true,\n poll: \"/api/health\",\n cached: getCachedOrEmptyResults(),\n timestamp: new Date().toISOString(),\n });\n return;\n }\n\n // Return cached or empty results\n const results = getCachedOrEmptyResults();\n res.json(results);\n } catch (error) {\n secureLogger.error(\"Error in health endpoint\", error, {});\n res.status(500).json({\n status: \"unhealthy\",\n error: \"An internal error occurred\",\n timestamp: new Date().toISOString(),\n });\n }\n});\n\n/**\n * Quick Health Check - Faster response\n * GET /api/health/quick\n */\nrouter.get(\"/api/health/quick\", async (_req: Request, res: Response) => {\n try {\n const results = await runQuickHealthCheck();\n // Update cache so page reload shows data\n cachedResults = results;\n cacheTimestamp = Date.now();\n res.json(results);\n } catch (error) {\n secureLogger.error(\"Error in quick health check\", error, {});\n res.status(500).json({\n status: \"unhealthy\",\n error: \"An internal error occurred\",\n timestamp: new Date().toISOString(),\n });\n }\n});\n\n/**\n * Available APIs List\n * GET /api/health/apis\n */\nrouter.get(\"/api/health/apis\", async (_req: Request, res: Response) => {\n try {\n const apis = await getAvailableApis();\n res.json({\n apis,\n count: apis.length,\n });\n } catch (error) {\n secureLogger.error(\"Error getting available APIs\", error, {});\n res.status(500).json({\n error: \"An internal error occurred\",\n });\n }\n});\n\n/**\n * Task toolset canary catalog\n * GET /api/health/toolsets\n */\nrouter.get(\"/api/health/toolsets\", async (_req: Request, res: Response) => {\n try {\n res.json({\n status: \"configured\",\n message:\n \"Task canaries are configured. Call /api/health/toolsets/quick to execute them.\",\n canaries: getTaskCanaryCatalog(),\n timestamp: new Date().toISOString(),\n });\n } catch (error) {\n secureLogger.error(\"Error getting task canary catalog\", error, {});\n res.status(500).json({\n status: \"failing\",\n error: \"An internal error occurred\",\n timestamp: new Date().toISOString(),\n });\n }\n});\n\n/**\n * Task toolset canary execution\n * GET /api/health/toolsets/quick\n */\nrouter.get(\"/api/health/toolsets/quick\", async (_req: Request, res: Response) => {\n try {\n res.json(await runTaskCanariesQuick());\n } catch (error) {\n secureLogger.error(\"Error running task canaries\", error, {});\n res.status(500).json({\n status: \"failing\",\n error: \"An internal error occurred\",\n timestamp: new Date().toISOString(),\n });\n }\n});\n\n/**\n * Task toolset canary history\n * GET /api/health/toolsets/history\n */\nrouter.get(\"/api/health/toolsets/history\", async (req: Request, res: Response) => {\n try {\n const limit = Number.parseInt(String(req.query.limit || \"20\"), 10);\n res.json(getTaskCanaryHistory(Number.isFinite(limit) ? limit : 20));\n } catch (error) {\n secureLogger.error(\"Error getting task canary history\", error, {});\n res.status(500).json({\n status: \"failing\",\n error: \"An internal error occurred\",\n timestamp: new Date().toISOString(),\n });\n }\n});\n\n/**\n * MCP protocol readiness\n * GET /api/health/mcp\n */\nrouter.get(\"/api/health/mcp\", async (req: Request, res: Response) => {\n try {\n const includeLiveInvoke = req.query.live !== \"false\";\n const useCache = req.query.cache !== \"false\" && !includeLiveInvoke;\n\n if (useCache) {\n res.json(await getCachedMcpProtocolHealth());\n return;\n }\n\n const result = await runMcpProtocolHealth({ includeLiveInvoke });\n if (!includeLiveInvoke) {\n cachedMcpProtocolHealth = result;\n cachedMcpProtocolTimestamp = Date.now();\n }\n res.json(result);\n } catch (error) {\n secureLogger.error(\"Error running MCP protocol health\", error, {});\n res.status(500).json({\n status: \"failing\",\n error: \"An internal error occurred\",\n timestamp: new Date().toISOString(),\n });\n }\n});\n\n/**\n * Workflow regression catalog\n * GET /api/health/workflows\n */\nrouter.get(\"/api/health/workflows\", async (_req: Request, res: Response) => {\n try {\n const cases = getWorkflowRegressionCatalog();\n res.json({\n status: \"configured\",\n message:\n \"Workflow regressions are configured. Call /api/health/workflows/quick to execute routing and schema checks.\",\n total: cases.length,\n cases,\n timestamp: new Date().toISOString(),\n });\n } catch (error) {\n secureLogger.error(\"Error getting workflow regression catalog\", error, {});\n res.status(500).json({\n status: \"failing\",\n error: \"An internal error occurred\",\n timestamp: new Date().toISOString(),\n });\n }\n});\n\n/**\n * Workflow regression execution\n * GET /api/health/workflows/quick\n */\nrouter.get(\"/api/health/workflows/quick\", async (_req: Request, res: Response) => {\n try {\n res.json(await runWorkflowRegressionCanaries());\n } catch (error) {\n secureLogger.error(\"Error running workflow regressions\", error, {});\n res.status(500).json({\n status: \"failing\",\n error: \"An internal error occurred\",\n timestamp: new Date().toISOString(),\n });\n }\n});\n\n/**\n * Workflow regression history\n * GET /api/health/workflows/history\n */\nrouter.get(\"/api/health/workflows/history\", async (req: Request, res: Response) => {\n try {\n const limit = Number.parseInt(String(req.query.limit || \"20\"), 10);\n res.json(getWorkflowRegressionHistory(Number.isFinite(limit) ? limit : 20));\n } catch (error) {\n secureLogger.error(\"Error getting workflow regression history\", error, {});\n res.status(500).json({\n status: \"failing\",\n error: \"An internal error occurred\",\n timestamp: new Date().toISOString(),\n });\n }\n});\n\n/**\n * Single task toolset canary execution\n * GET /api/health/toolsets/:toolsetId\n */\nrouter.get(\n \"/api/health/toolsets/:toolsetId\",\n async (req: Request, res: Response) => {\n try {\n const result = await runTaskCanary(req.params.toolsetId);\n if (!result) {\n res.status(404).json({\n status: \"failing\",\n error: `Task toolset '${req.params.toolsetId}' not found`,\n timestamp: new Date().toISOString(),\n });\n return;\n }\n\n res.json(result);\n } catch (error) {\n secureLogger.error(\"Error running task canary\", error, {\n toolsetId: req.params.toolsetId,\n });\n res.status(500).json({\n status: \"failing\",\n error: \"An internal error occurred\",\n timestamp: new Date().toISOString(),\n });\n }\n },\n);\n\n/**\n * Single API Health Check\n * GET /api/health/:apiName\n */\nrouter.get(\"/api/health/:apiName\", async (req: Request, res: Response) => {\n try {\n const { apiName } = req.params;\n const shouldRun = req.query.run === \"true\" && isMonitorAuthorized(req);\n\n // Check if we have cached results for this API\n const cached = cachedResults?.apis.find(\n (api) => api.api.toLowerCase() === apiName.toLowerCase(),\n );\n\n if (!shouldRun && cached && Date.now() - cacheTimestamp < CACHE_TTL_MS) {\n res.json(cached);\n return;\n }\n\n if (shouldRun) {\n const result = await runApiTests(apiName);\n if (!result) {\n res.status(404).json({\n error: `API '${apiName}' not found`,\n availableApis: await getAvailableApis(),\n });\n return;\n }\n\n // Update cache for this API\n if (cachedResults) {\n const index = cachedResults.apis.findIndex(\n (api) => api.api.toLowerCase() === apiName.toLowerCase(),\n );\n if (index >= 0) {\n cachedResults.apis[index] = result;\n } else {\n cachedResults.apis.push(result);\n }\n cachedResults.timestamp = new Date().toISOString();\n }\n\n res.json(result);\n return;\n }\n\n // No cached results - return empty\n res.json({\n api: apiName,\n status: \"unknown\",\n message: \"No test results available. Add ?run=true to run tests.\",\n timestamp: new Date().toISOString(),\n });\n } catch (error) {\n secureLogger.error(\n `Error in health check for ${req.params.apiName}`,\n error,\n {},\n );\n res.status(500).json({\n api: req.params.apiName,\n status: \"failed\",\n error: \"An internal error occurred\",\n timestamp: new Date().toISOString(),\n });\n }\n});\n\n// ── K8s Probes ──────────────────────────────────────────────\n\nlet startupComplete = false;\n\nexport function markStartupComplete(): void {\n startupComplete = true;\n}\n\nrouter.get(\"/live\", (_req: Request, res: Response) => {\n res.json({ status: \"alive\" });\n});\n\nrouter.get(\"/ready\", async (_req: Request, res: Response) => {\n if (!startupComplete) {\n return res\n .status(503)\n .json({ status: \"not_ready\", reason: \"still starting\" });\n }\n try {\n const mcpProtocolHealth = await getCachedMcpProtocolHealth();\n if (mcpProtocolHealth.status !== \"ok\") {\n return res.status(503).json({\n status: \"not_ready\",\n reason: \"mcp protocol readiness failed\",\n mcpStatus: mcpProtocolHealth.status,\n auth: mcpProtocolHealth.auth,\n });\n }\n } catch (error) {\n secureLogger.error(\"MCP readiness check failed\", error, {});\n return res.status(503).json({\n status: \"not_ready\",\n reason: \"mcp readiness check failed\",\n });\n }\n // If we have cached health results and they indicate unhealthy, report not ready\n if (\n cachedResults &&\n Date.now() - cacheTimestamp < CACHE_TTL_MS &&\n cachedResults.status === \"unhealthy\"\n ) {\n return res\n .status(503)\n .json({ status: \"not_ready\", reason: \"health check failed\" });\n }\n return res.json({ status: \"ready\" });\n});\n\nrouter.get(\"/startup\", (_req: Request, res: Response) => {\n if (startupComplete) {\n return res.json({ status: \"started\" });\n }\n return res.status(503).json({ status: \"starting\" });\n});\n\nexport default router;\n","/**\n * Test Runner for API Status Page\n *\n * Delegates to the self-test engine which invokes tool handlers directly.\n * No vitest dependency — works in production Docker / Cloud Run.\n */\n\nimport { secureLogger } from '../utils/secureLogger.js';\nimport {\n RUNTIME_STATUSES,\n aggregateRuntimeStatus,\n classifyRuntimeStatusFromError,\n type RuntimeStatus,\n} from \"../runtimeStatus.js\";\nimport {\n getProviderList,\n runSelfTestQuick,\n runSelfTestFull,\n runSelfTestProvider,\n} from './selfTest.js';\n\n// ---------------------------------------------------------------------------\n// Exported interfaces (unchanged — consumed by index.ts and statusPage.ts)\n// ---------------------------------------------------------------------------\n\nexport interface TestResult {\n name: string;\n status: 'passed' | 'failed' | 'skipped';\n duration: number;\n error?: string;\n runtimeStatus?: RuntimeStatus;\n}\n\nexport interface ApiTestResults {\n api: string;\n status: 'passed' | 'failed' | 'partial' | 'inactive';\n totalTests: number;\n passedTests: number;\n failedTests: number;\n skippedTests: number;\n duration: number;\n tests: TestResult[];\n timestamp: string;\n runtimeStatus?: RuntimeStatus;\n runtimeStatusSummary?: Record<RuntimeStatus, number>;\n}\n\nexport interface AllTestResults {\n status: 'healthy' | 'degraded' | 'unhealthy';\n totalApis: number;\n healthyApis: number;\n degradedApis: number;\n unhealthyApis: number;\n inactiveApis: number;\n totalTests: number;\n passedTests: number;\n failedTests: number;\n duration: number;\n apis: ApiTestResults[];\n timestamp: string;\n runtimeStatuses?: readonly RuntimeStatus[];\n runtimeStatusSummary?: Record<RuntimeStatus, number>;\n}\n\n// ---------------------------------------------------------------------------\n// Aggregation helper\n// ---------------------------------------------------------------------------\n\nfunction aggregateResults(startTime: number, apiResults: ApiTestResults[]): AllTestResults {\n let healthyApis = 0;\n let degradedApis = 0;\n let unhealthyApis = 0;\n let inactiveApis = 0;\n let totalTests = 0;\n let passedTests = 0;\n let failedTests = 0;\n\n const runtimeStatusSummary = Object.fromEntries(\n RUNTIME_STATUSES.map((status) => [status, 0]),\n ) as Record<RuntimeStatus, number>;\n\n for (const result of apiResults) {\n if (result.status === 'passed') healthyApis++;\n else if (result.status === 'partial') degradedApis++;\n else if (result.status === 'inactive') inactiveApis++;\n else unhealthyApis++;\n\n const runtimeStatus = result.runtimeStatus ?? classifyApiRuntimeStatus(result);\n runtimeStatusSummary[runtimeStatus]++;\n\n totalTests += result.totalTests;\n passedTests += result.passedTests;\n failedTests += result.failedTests;\n }\n\n let status: 'healthy' | 'degraded' | 'unhealthy' = 'healthy';\n if (apiResults.length === 0) status = 'unhealthy';\n else if (unhealthyApis > apiResults.length / 2) status = 'unhealthy';\n else if (unhealthyApis > 0 || degradedApis > 0) status = 'degraded';\n\n return {\n status,\n totalApis: apiResults.length,\n healthyApis,\n degradedApis,\n unhealthyApis,\n inactiveApis,\n totalTests,\n passedTests,\n failedTests,\n duration: Date.now() - startTime,\n apis: apiResults,\n timestamp: new Date().toISOString(),\n runtimeStatuses: RUNTIME_STATUSES,\n runtimeStatusSummary,\n };\n}\n\nfunction classifyTestRuntimeStatus(result: TestResult): RuntimeStatus {\n if (result.runtimeStatus) return result.runtimeStatus;\n if (result.status === \"passed\") return \"ok\";\n if (result.status === \"skipped\") return \"degraded\";\n return classifyRuntimeStatusFromError(result.error);\n}\n\nfunction classifyApiRuntimeStatus(result: ApiTestResults): RuntimeStatus {\n if (result.runtimeStatus) return result.runtimeStatus;\n return aggregateRuntimeStatus(result.tests.map(classifyTestRuntimeStatus));\n}\n\nfunction enrichApiRuntimeStatus(result: ApiTestResults): ApiTestResults {\n const runtimeStatusSummary = Object.fromEntries(\n RUNTIME_STATUSES.map((status) => [status, 0]),\n ) as Record<RuntimeStatus, number>;\n for (const test of result.tests) {\n runtimeStatusSummary[classifyTestRuntimeStatus(test)]++;\n }\n return {\n ...result,\n runtimeStatus: classifyApiRuntimeStatus(result),\n runtimeStatusSummary,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API (same signatures as before)\n// ---------------------------------------------------------------------------\n\nexport async function getAvailableApis(): Promise<string[]> {\n return getProviderList();\n}\n\nexport async function runApiTests(apiName: string): Promise<ApiTestResults | null> {\n try {\n const result = await runSelfTestProvider(apiName);\n return result ? enrichApiRuntimeStatus(result) : null;\n } catch (error) {\n secureLogger.error(`Self-test failed for ${apiName}`, error, {});\n return {\n api: apiName,\n status: 'failed',\n totalTests: 0,\n passedTests: 0,\n failedTests: 0,\n skippedTests: 0,\n duration: 0,\n tests: [{\n name: 'Self-test execution',\n status: 'failed',\n duration: 0,\n error: error instanceof Error ? error.message : 'Unknown error',\n }],\n timestamp: new Date().toISOString(),\n };\n }\n}\n\nexport async function runAllTests(): Promise<AllTestResults> {\n const startTime = Date.now();\n try {\n const apiResults = await runSelfTestFull();\n return aggregateResults(startTime, apiResults.map(enrichApiRuntimeStatus));\n } catch (error) {\n secureLogger.error('Self-test full run failed', error, {});\n return aggregateResults(startTime, [{\n api: 'selftest',\n status: 'failed',\n totalTests: 1,\n passedTests: 0,\n failedTests: 1,\n skippedTests: 0,\n duration: 0,\n tests: [{\n name: 'Self-test full execution',\n status: 'failed',\n duration: 0,\n error: error instanceof Error ? error.message : 'Unknown error',\n }],\n timestamp: new Date().toISOString(),\n }]);\n }\n}\n\nexport async function runQuickHealthCheck(): Promise<AllTestResults> {\n const startTime = Date.now();\n try {\n const apiResults = await runSelfTestQuick();\n return aggregateResults(startTime, apiResults.map(enrichApiRuntimeStatus));\n } catch (error) {\n secureLogger.error('Self-test quick check failed', error, {});\n return aggregateResults(startTime, [{\n api: 'selftest',\n status: 'failed',\n totalTests: 1,\n passedTests: 0,\n failedTests: 1,\n skippedTests: 0,\n duration: 0,\n tests: [{\n name: 'Self-test quick execution',\n status: 'failed',\n duration: 0,\n error: error instanceof Error ? error.message : 'Unknown error',\n }],\n timestamp: new Date().toISOString(),\n }]);\n }\n}\n","/**\n * Status Page HTML Generator\n *\n * Generates minimalistic shadcn/ui-inspired light mode status pages\n * with endpoint-level details per API integration.\n */\n\nimport type { AllTestResults, ApiTestResults, TestResult } from './testRunner.js';\n\n/**\n * Get GA4 Measurement ID from environment for client-side tracking\n */\nfunction getGAMeasurementId(): string {\n return process.env.GA_MEASUREMENT_ID || 'G-N2L7LWKHCP';\n}\n\n/**\n * Generate Google Analytics 4 gtag.js snippet if GA_MEASUREMENT_ID is set\n */\nfunction nonceAttribute(scriptNonce?: string): string {\n return scriptNonce ? ` nonce=\"${escapeHtml(scriptNonce)}\"` : \"\";\n}\n\nfunction generateGAScript(scriptNonce?: string): string {\n const measurementId = getGAMeasurementId();\n if (!measurementId) return '';\n const nonce = nonceAttribute(scriptNonce);\n\n return `\n <!-- Google Analytics 4 -->\n <script async src=\"https://www.googletagmanager.com/gtag/js?id=${measurementId}\"></script>\n <script${nonce}>\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n gtag('config', '${measurementId}');\n </script>`;\n}\n\n/**\n * Escape HTML special characters to prevent XSS\n */\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#x27;');\n}\n\n/**\n * Get status colors for badges and indicators (shadcn light mode palette)\n */\nfunction getStatusColors(status: string): { bg: string; text: string; border: string } {\n const colors: Record<string, { bg: string; text: string; border: string }> = {\n passed: { bg: 'bg-emerald-50', text: 'text-emerald-700', border: 'border-emerald-200' },\n healthy: { bg: 'bg-emerald-50', text: 'text-emerald-700', border: 'border-emerald-200' },\n partial: { bg: 'bg-amber-50', text: 'text-amber-700', border: 'border-amber-200' },\n degraded: { bg: 'bg-amber-50', text: 'text-amber-700', border: 'border-amber-200' },\n failed: { bg: 'bg-red-50', text: 'text-red-700', border: 'border-red-200' },\n unhealthy: { bg: 'bg-red-50', text: 'text-red-700', border: 'border-red-200' },\n inactive: { bg: 'bg-slate-50', text: 'text-slate-500', border: 'border-slate-200' },\n };\n return colors[status] || { bg: 'bg-slate-100', text: 'text-slate-600', border: 'border-slate-200' };\n}\n\n/**\n * Format duration in human readable format\n */\nfunction formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n } else if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n } else {\n const mins = Math.floor(ms / 60000);\n const secs = ((ms % 60000) / 1000).toFixed(0);\n return `${mins}m ${secs}s`;\n }\n}\n\n/**\n * Generate status badge HTML (shadcn Badge style)\n */\nfunction generateStatusBadge(status: string): string {\n const { bg, text, border } = getStatusColors(status);\n const label = status.toUpperCase();\n return `<span class=\"inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${bg} ${text} border ${border}\">${label}</span>`;\n}\n\n/**\n * Generate header with title and action buttons (shadcn Button styles)\n */\nfunction generateHeader(results: AllTestResults): string {\n return `\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-8\">\n <div class=\"flex items-center gap-3\">\n <h1 class=\"text-xl font-semibold text-slate-900 tracking-tight\">Hive MCP Status</h1>\n ${generateStatusBadge(results.status)}\n </div>\n <div class=\"flex items-center gap-2\">\n <button data-action=\"quick-check\" class=\"inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-4 border border-slate-200 bg-white hover:bg-slate-50 hover:text-slate-900 transition-colors\">\n Quick Check\n </button>\n <button data-action=\"run-all\" class=\"inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-4 border border-slate-200 bg-white hover:bg-slate-50 hover:text-slate-900 transition-colors\">\n Run All\n </button>\n <button data-action=\"copy-markdown\" class=\"inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-4 bg-slate-900 text-white hover:bg-slate-800 transition-colors\" title=\"Copy as Markdown\">\n 📋 Copy MD\n </button>\n </div>\n </div>\n `;\n}\n\n/**\n * Generate summary cards grid - clickable to filter by status (shadcn Card style)\n */\nfunction generateSummaryCards(results: AllTestResults): string {\n return `\n <div class=\"grid grid-cols-3 sm:grid-cols-6 gap-3 mb-4\">\n <div class=\"bg-white border border-slate-200 rounded-lg p-4 text-center cursor-pointer hover:bg-slate-50 hover:border-emerald-300 transition-colors shadow-sm\"\n data-filter-card=\"healthy\">\n <div class=\"text-2xl font-semibold text-emerald-600\">${results.healthyApis}</div>\n <div class=\"text-xs text-slate-500 mt-1\">Healthy</div>\n </div>\n <div class=\"bg-white border border-slate-200 rounded-lg p-4 text-center cursor-pointer hover:bg-slate-50 hover:border-amber-300 transition-colors shadow-sm\"\n data-filter-card=\"degraded\">\n <div class=\"text-2xl font-semibold text-amber-600\">${results.degradedApis}</div>\n <div class=\"text-xs text-slate-500 mt-1\">Degraded</div>\n </div>\n <div class=\"bg-white border border-slate-200 rounded-lg p-4 text-center cursor-pointer hover:bg-slate-50 hover:border-red-300 transition-colors shadow-sm\"\n data-filter-card=\"unhealthy\">\n <div class=\"text-2xl font-semibold text-red-600\">${results.unhealthyApis}</div>\n <div class=\"text-xs text-slate-500 mt-1\">Unhealthy</div>\n </div>\n <div class=\"bg-white border border-slate-200 rounded-lg p-4 text-center cursor-pointer hover:bg-slate-50 hover:border-slate-400 transition-colors shadow-sm\"\n data-filter-card=\"inactive\">\n <div class=\"text-2xl font-semibold text-slate-500\">${results.inactiveApis}</div>\n <div class=\"text-xs text-slate-500 mt-1\">Inactive</div>\n </div>\n <div class=\"bg-white border border-slate-200 rounded-lg p-4 text-center shadow-sm\">\n <div class=\"text-2xl font-semibold text-slate-900\">${results.passedTests}/${results.totalTests}</div>\n <div class=\"text-xs text-slate-500 mt-1\">Passed</div>\n </div>\n <div class=\"bg-white border border-slate-200 rounded-lg p-4 text-center shadow-sm\">\n <div class=\"text-2xl font-semibold text-slate-900\">${formatDuration(results.duration)}</div>\n <div class=\"text-xs text-slate-500 mt-1\">Duration</div>\n </div>\n </div>\n <div id=\"filter-banner\" class=\"hidden mb-4 px-4 py-2 bg-slate-50 border border-slate-200 rounded-lg flex items-center justify-between\">\n <span class=\"text-sm text-slate-600\">Filtered: Showing <span id=\"filter-status\" class=\"font-medium text-slate-900\"></span> APIs</span>\n <button data-action=\"clear-filter\" class=\"text-xs text-slate-500 hover:text-slate-900 transition-colors\">Clear Filter</button>\n </div>\n `;\n}\n\n/**\n * Generate endpoint row HTML (shadcn light mode)\n */\nfunction generateEndpointRow(test: TestResult): string {\n const isError = test.status === 'failed';\n const icon = test.status === 'passed' ? '✓' : test.status === 'failed' ? '✗' : '○';\n const iconColor = test.status === 'passed' ? 'text-emerald-600' : test.status === 'failed' ? 'text-red-600' : 'text-slate-400';\n\n return `\n <div class=\"flex items-start gap-3 py-2 px-3 ${isError ? 'bg-red-50' : 'hover:bg-slate-50'} rounded transition-colors\">\n <span class=\"${iconColor} font-medium w-4 flex-shrink-0\">${icon}</span>\n <div class=\"flex-1 min-w-0\">\n <span class=\"font-mono text-sm text-slate-700 break-all\">${test.name}</span>\n ${test.error ? `<div class=\"text-xs text-red-600 mt-1 break-all\">${escapeHtml(test.error.substring(0, 150))}${test.error.length > 150 ? '...' : ''}</div>` : ''}\n </div>\n <span class=\"text-xs text-slate-400 flex-shrink-0 tabular-nums\">${formatDuration(test.duration)}</span>\n </div>\n `;\n}\n\n/**\n * Map API status to display status\n */\nfunction mapApiStatus(status: 'passed' | 'failed' | 'partial' | 'inactive'): string {\n if (status === 'passed') return 'healthy';\n if (status === 'partial') return 'degraded';\n if (status === 'inactive') return 'inactive';\n return 'unhealthy';\n}\n\n/**\n * Generate API card HTML (shadcn Accordion/Collapsible style)\n */\nfunction generateApiCard(api: ApiTestResults): string {\n const displayStatus = mapApiStatus(api.status);\n const endpointRows = api.tests.map(generateEndpointRow).join('');\n\n return `\n <div class=\"bg-white border border-slate-200 rounded-lg overflow-hidden shadow-sm\" data-api-status=\"${displayStatus}\">\n <div\n class=\"flex items-center justify-between px-4 py-3 cursor-pointer hover:bg-slate-50 transition-colors\"\n data-api-toggle=\"${escapeHtml(api.api)}\"\n >\n <div class=\"flex items-center gap-3\">\n <svg\n id=\"chevron-${api.api}\"\n class=\"w-4 h-4 text-slate-400 transition-transform duration-200\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n <span class=\"font-medium text-slate-900 uppercase tracking-wide text-sm\">${api.api}</span>\n <span class=\"text-sm text-slate-500\">${api.passedTests}/${api.totalTests} endpoints</span>\n </div>\n <div class=\"flex items-center gap-3\">\n ${generateStatusBadge(displayStatus)}\n <button\n data-api-run=\"${escapeHtml(api.api)}\"\n class=\"inline-flex items-center rounded-md px-2.5 py-1 text-xs font-medium bg-white text-slate-600 hover:bg-slate-100 transition-colors border border-slate-200\"\n >\n Run\n </button>\n </div>\n </div>\n <div id=\"api-${api.api}\" class=\"hidden border-t border-slate-200\">\n <div class=\"px-4 py-2 bg-slate-50 border-b border-slate-100\">\n <span class=\"text-sm text-slate-500\">\n <span class=\"text-emerald-600\">${api.passedTests} passed</span>\n <span class=\"mx-1.5\">·</span>\n <span class=\"${api.failedTests > 0 ? 'text-red-600' : 'text-slate-400'}\">${api.failedTests} failed</span>\n <span class=\"mx-1.5\">·</span>\n <span class=\"text-slate-400\">${api.skippedTests} skipped</span>\n <span class=\"mx-3 text-slate-300\">|</span>\n <span class=\"text-slate-500\">${formatDuration(api.duration)} total</span>\n </span>\n </div>\n <div class=\"max-h-80 overflow-y-auto bg-white\">\n ${endpointRows}\n </div>\n </div>\n </div>\n `;\n}\n\n/**\n * Generate loading spinner (shadcn light mode)\n */\nfunction generateLoadingSpinner(): string {\n return `\n <div id=\"loading\" class=\"flex items-center justify-center py-12\">\n <svg class=\"animate-spin h-5 w-5 text-slate-400 mr-3\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span class=\"text-slate-500 text-sm\">Running tests...</span>\n </div>\n `;\n}\n\n/**\n * Generate footer with timestamp\n */\nfunction generateFooter(results: AllTestResults): string {\n return `\n <div class=\"mt-8 pt-4 border-t border-slate-200 text-center text-xs text-slate-400\">\n Last updated: ${results.timestamp}\n </div>\n `;\n}\n\n/**\n * Generate task canary history panel.\n */\nfunction generateTaskCanaryHistoryPanel(): string {\n return `\n <div class=\"bg-white border border-slate-200 rounded-lg shadow-sm mb-4\">\n <div class=\"p-4 border-b border-slate-100 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3\">\n <div>\n <h2 class=\"text-sm font-semibold text-slate-900\">Task toolset canaries</h2>\n <p class=\"text-xs text-slate-500 mt-1\">Recent runtime health for canonical agent workflows.</p>\n </div>\n <button data-action=\"run-task-canaries\" class=\"inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-4 border border-slate-200 bg-white hover:bg-slate-50 transition-colors\">\n Run Canaries\n </button>\n </div>\n <div id=\"task-canary-history\" class=\"p-4 text-sm text-slate-500\">\n Loading canary history...\n </div>\n </div>\n `;\n}\n\nfunction generateReadinessLanesPanel(results: AllTestResults): string {\n return `\n <div class=\"bg-white border border-slate-200 rounded-lg shadow-sm mb-4\">\n <div class=\"p-4 border-b border-slate-100\">\n <h2 class=\"text-sm font-semibold text-slate-900\">Agent readiness lanes</h2>\n <p class=\"text-xs text-slate-500 mt-1\">Protocol, provider, workflow, and catalog signals are checked separately.</p>\n </div>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-3 p-4\">\n <div class=\"border border-slate-200 rounded-md p-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <div>\n <div class=\"text-sm font-medium text-slate-900\">Provider probes</div>\n <div class=\"text-xs text-slate-500 mt-1\">${results.passedTests}/${results.totalTests} checks, ${formatDuration(results.duration)}</div>\n </div>\n ${generateStatusBadge(results.status)}\n </div>\n </div>\n <div class=\"border border-slate-200 rounded-md p-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <div>\n <div class=\"text-sm font-medium text-slate-900\">MCP protocol</div>\n <div id=\"mcp-protocol-summary\" class=\"text-xs text-slate-500 mt-1\">Loading protocol check...</div>\n </div>\n <button data-action=\"run-mcp-protocol\" class=\"inline-flex items-center rounded-md px-2.5 py-1 text-xs font-medium bg-white text-slate-600 hover:bg-slate-100 transition-colors border border-slate-200\">Run</button>\n </div>\n </div>\n <div class=\"border border-slate-200 rounded-md p-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <div>\n <div class=\"text-sm font-medium text-slate-900\">Workflow routing</div>\n <div id=\"workflow-regression-summary\" class=\"text-xs text-slate-500 mt-1\">Loading workflow history...</div>\n </div>\n <button data-action=\"run-workflow-regressions\" class=\"inline-flex items-center rounded-md px-2.5 py-1 text-xs font-medium bg-white text-slate-600 hover:bg-slate-100 transition-colors border border-slate-200\">Run</button>\n </div>\n </div>\n <div class=\"border border-slate-200 rounded-md p-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <div>\n <div class=\"text-sm font-medium text-slate-900\">Catalog integrity</div>\n <div class=\"text-xs text-slate-500 mt-1\">Root tools, resources, prompts, schemas, and category tools are checked by MCP protocol readiness.</div>\n </div>\n ${generateStatusBadge(results.totalApis > 0 ? \"healthy\" : \"unhealthy\")}\n </div>\n </div>\n </div>\n </div>\n `;\n}\n\n/**\n * Generate JavaScript for interactivity\n */\nfunction generateScript(results: AllTestResults, scriptNonce?: string): string {\n // Prepare results data for markdown generation\n // Replace < with \\u003c to prevent </script> breaking out of the script tag (XSS)\n const resultsJson = JSON.stringify(results).replace(/</g, '\\\\u003c');\n const nonce = nonceAttribute(scriptNonce);\n\n return `\n <script${nonce}>\n // Embedded results data for markdown generation\n const resultsData = ${resultsJson};\n let currentFilter = null;\n\n document.addEventListener('DOMContentLoaded', () => {\n document.addEventListener('click', (event) => {\n const target = event.target.closest('[data-action], [data-filter-card], [data-api-toggle], [data-api-run]');\n if (!target) return;\n\n if (target.dataset.apiRun) {\n event.stopPropagation();\n runApiTest(target.dataset.apiRun, target);\n return;\n }\n\n if (target.dataset.apiToggle) {\n toggleApi(target.dataset.apiToggle);\n return;\n }\n\n if (target.dataset.filterCard) {\n filterByStatus(target.dataset.filterCard);\n return;\n }\n\n switch (target.dataset.action) {\n case 'quick-check':\n runQuickCheck();\n break;\n case 'run-all':\n runAllTests();\n break;\n case 'copy-markdown':\n copyAsMarkdown(target);\n break;\n case 'clear-filter':\n clearFilter();\n break;\n case 'run-task-canaries':\n runTaskCanaries();\n break;\n case 'run-mcp-protocol':\n runMcpProtocolHealth();\n break;\n case 'run-workflow-regressions':\n runWorkflowRegressions();\n break;\n }\n });\n loadTaskCanaryHistory();\n loadMcpProtocolHealth();\n loadWorkflowRegressionHistory();\n });\n\n function toggleApi(api) {\n const content = document.getElementById('api-' + api);\n const chevron = document.getElementById('chevron-' + api);\n const isHidden = content.classList.contains('hidden');\n\n content.classList.toggle('hidden');\n chevron.style.transform = isHidden ? 'rotate(180deg)' : '';\n }\n\n function showLoading() {\n const loading = document.getElementById('loading');\n if (loading) {\n loading.classList.remove('hidden');\n } else {\n const apiList = document.getElementById('api-list');\n const spinner = document.createElement('div');\n spinner.id = 'loading';\n spinner.className = 'flex items-center justify-center py-12';\n spinner.innerHTML = \\`\n <svg class=\"animate-spin h-5 w-5 text-slate-400 mr-3\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span class=\"text-slate-500 text-sm\">Running tests...</span>\n \\`;\n apiList.parentNode.insertBefore(spinner, apiList);\n }\n }\n\n function hideLoading() {\n const loading = document.getElementById('loading');\n if (loading) {\n loading.classList.add('hidden');\n }\n }\n\n async function runAllTests() {\n showLoading();\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 120000);\n const response = await fetch('/api/health?run=true', { signal: controller.signal });\n clearTimeout(timeoutId);\n if (!response.ok) throw new Error('Request failed');\n location.reload();\n } catch (error) {\n if (error.name === 'AbortError') {\n alert('Run All timed out after 120s. Tests may still be running — reload later.');\n } else {\n alert('Failed to run tests: ' + error.message);\n }\n hideLoading();\n }\n }\n\n async function runQuickCheck() {\n showLoading();\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 30000);\n const response = await fetch('/api/health/quick', { signal: controller.signal });\n clearTimeout(timeoutId);\n if (!response.ok) throw new Error('Request failed');\n location.reload();\n } catch (error) {\n if (error.name === 'AbortError') {\n alert('Quick check timed out after 30s. Please try again.');\n } else {\n alert('Failed to run quick check: ' + error.message);\n }\n hideLoading();\n }\n }\n\n async function runTaskCanaries() {\n const container = document.getElementById('task-canary-history');\n container.textContent = 'Running task canaries...';\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 60000);\n const response = await fetch('/api/health/toolsets/quick', { signal: controller.signal });\n clearTimeout(timeoutId);\n if (!response.ok) throw new Error('Request failed');\n await loadTaskCanaryHistory();\n } catch (error) {\n container.textContent = error.name === 'AbortError'\n ? 'Task canaries timed out after 60s. Reload later to check history.'\n : 'Failed to run task canaries: ' + error.message;\n }\n }\n\n async function loadMcpProtocolHealth() {\n const container = document.getElementById('mcp-protocol-summary');\n if (!container) return;\n\n try {\n const response = await fetch('/api/health/mcp?live=false');\n if (!response.ok) throw new Error('Request failed');\n const data = await response.json();\n container.innerHTML = renderCompactStatus(data.status, data.passed + '/' + data.checks.length + ' checks, auth ' + data.auth.status);\n } catch (error) {\n container.textContent = 'Protocol health unavailable: ' + error.message;\n }\n }\n\n async function runMcpProtocolHealth() {\n const container = document.getElementById('mcp-protocol-summary');\n container.textContent = 'Running MCP protocol check...';\n try {\n const response = await fetch('/api/health/mcp?live=false&cache=false');\n if (!response.ok) throw new Error('Request failed');\n const data = await response.json();\n container.innerHTML = renderCompactStatus(data.status, data.passed + '/' + data.checks.length + ' checks, auth ' + data.auth.status);\n } catch (error) {\n container.textContent = 'MCP protocol check failed: ' + error.message;\n }\n }\n\n async function loadWorkflowRegressionHistory() {\n const container = document.getElementById('workflow-regression-summary');\n if (!container) return;\n\n try {\n const response = await fetch('/api/health/workflows/history?limit=1');\n if (!response.ok) throw new Error('Request failed');\n const data = await response.json();\n if (!data.latest) {\n const catalog = await fetch('/api/health/workflows');\n const catalogData = catalog.ok ? await catalog.json() : { total: 0 };\n container.textContent = 'Configured: ' + catalogData.total + ' regression prompts. No runs yet.';\n return;\n }\n const latest = data.latest;\n container.innerHTML = renderCompactStatus(latest.status, latest.passed + '/' + latest.total + ' prompts, ' + formatDurationMs(latest.duration));\n } catch (error) {\n container.textContent = 'Workflow history unavailable: ' + error.message;\n }\n }\n\n async function runWorkflowRegressions() {\n const container = document.getElementById('workflow-regression-summary');\n container.textContent = 'Running workflow regressions...';\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 60000);\n const response = await fetch('/api/health/workflows/quick', { signal: controller.signal });\n clearTimeout(timeoutId);\n if (!response.ok) throw new Error('Request failed');\n const data = await response.json();\n container.innerHTML = renderCompactStatus(data.status, data.passed + '/' + data.total + ' prompts, ' + formatDurationMs(data.duration));\n } catch (error) {\n container.textContent = error.name === 'AbortError'\n ? 'Workflow regressions timed out after 60s.'\n : 'Workflow regressions failed: ' + error.message;\n }\n }\n\n function renderCompactStatus(status, detail) {\n const color = status === 'ok' || status === 'healthy' ? 'text-emerald-700'\n : status === 'failing' || status === 'unhealthy' || status === 'missing_key' ? 'text-red-700'\n : 'text-amber-700';\n return '<span class=\"' + color + ' font-medium\">' + escapeText(status) + '</span><span class=\"text-slate-500\"> · ' + escapeText(detail) + '</span>';\n }\n\n async function loadTaskCanaryHistory() {\n const container = document.getElementById('task-canary-history');\n if (!container) return;\n\n try {\n const response = await fetch('/api/health/toolsets/history?limit=5');\n if (!response.ok) throw new Error('Request failed');\n const data = await response.json();\n if (!data.latest) {\n container.innerHTML = '<span>No canary runs recorded yet.</span>';\n return;\n }\n\n const latest = data.latest;\n const rows = latest.results.map((result) => {\n const color = result.status === 'ok' ? 'text-emerald-700 bg-emerald-50 border-emerald-200'\n : result.status === 'failing' ? 'text-red-700 bg-red-50 border-red-200'\n : 'text-amber-700 bg-amber-50 border-amber-200';\n return '<tr class=\"border-t border-slate-100\">' +\n '<td class=\"py-2 pr-3 font-medium text-slate-900\">' + escapeText(result.label) + '</td>' +\n '<td class=\"py-2 pr-3\"><span class=\"inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ' + color + '\">' + escapeText(result.status) + '</span></td>' +\n '<td class=\"py-2 pr-3 text-slate-500\">' + escapeText(result.provider || 'unknown') + '</td>' +\n '<td class=\"py-2 text-slate-500\">' + formatDurationMs(result.duration || 0) + '</td>' +\n '</tr>';\n }).join('');\n\n container.innerHTML =\n '<div class=\"flex flex-wrap gap-3 mb-3 text-xs text-slate-500\">' +\n '<span>Latest: ' + escapeText(latest.timestamp) + '</span>' +\n '<span>Status: ' + escapeText(latest.status) + '</span>' +\n '<span>OK: ' + latest.ok + '/' + latest.totalToolsets + '</span>' +\n '<span>History: ' + data.count + '/' + data.maxEntries + '</span>' +\n '</div>' +\n '<div class=\"overflow-x-auto\"><table class=\"w-full text-left text-sm\">' +\n '<thead class=\"text-xs uppercase text-slate-400\"><tr><th class=\"pb-2 pr-3\">Toolset</th><th class=\"pb-2 pr-3\">Status</th><th class=\"pb-2 pr-3\">Provider</th><th class=\"pb-2\">Latency</th></tr></thead>' +\n '<tbody>' + rows + '</tbody>' +\n '</table></div>';\n } catch (error) {\n container.textContent = 'Canary history unavailable: ' + error.message;\n }\n }\n\n function escapeText(value) {\n return String(value)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#x27;');\n }\n\n async function runApiTest(api, btn) {\n const originalText = btn.textContent;\n btn.disabled = true;\n btn.textContent = '...';\n btn.classList.add('opacity-50', 'cursor-not-allowed');\n\n try {\n const response = await fetch('/api/health/' + api + '?run=true');\n if (!response.ok) throw new Error('Request failed');\n location.reload();\n } catch (error) {\n alert('Failed to run tests for ' + api + ': ' + error.message);\n btn.disabled = false;\n btn.textContent = originalText;\n btn.classList.remove('opacity-50', 'cursor-not-allowed');\n }\n }\n\n function filterByStatus(status) {\n // Toggle if clicking same filter\n if (currentFilter === status) {\n clearFilter();\n return;\n }\n\n currentFilter = status;\n\n // Update card highlighting\n document.querySelectorAll('[data-filter-card]').forEach(card => {\n const cardStatus = card.getAttribute('data-filter-card');\n if (cardStatus === status) {\n const borderColor = status === 'healthy' ? 'border-emerald-500' :\n status === 'degraded' ? 'border-amber-500' :\n status === 'inactive' ? 'border-slate-500' : 'border-red-500';\n card.classList.add('ring-2', 'ring-offset-2', borderColor);\n card.classList.remove('border-slate-200');\n } else {\n card.classList.remove('ring-2', 'ring-offset-2', 'border-emerald-500', 'border-amber-500', 'border-red-500', 'border-slate-500');\n card.classList.add('border-slate-200');\n }\n });\n\n // Show/hide API cards\n document.querySelectorAll('[data-api-status]').forEach(card => {\n const apiStatus = card.getAttribute('data-api-status');\n card.style.display = apiStatus === status ? '' : 'none';\n });\n\n // Show filter banner\n const banner = document.getElementById('filter-banner');\n const statusText = document.getElementById('filter-status');\n statusText.textContent = status.charAt(0).toUpperCase() + status.slice(1);\n banner.classList.remove('hidden');\n }\n\n function clearFilter() {\n currentFilter = null;\n\n // Remove card highlighting\n document.querySelectorAll('[data-filter-card]').forEach(card => {\n card.classList.remove('ring-2', 'ring-offset-2', 'border-emerald-500', 'border-amber-500', 'border-red-500', 'border-slate-500');\n card.classList.add('border-slate-200');\n });\n\n // Show all API cards\n document.querySelectorAll('[data-api-status]').forEach(card => {\n card.style.display = '';\n });\n\n // Hide filter banner\n document.getElementById('filter-banner').classList.add('hidden');\n }\n\n function formatDurationMs(ms) {\n if (ms < 1000) return ms + 'ms';\n if (ms < 60000) return (ms / 1000).toFixed(1) + 's';\n const mins = Math.floor(ms / 60000);\n const secs = ((ms % 60000) / 1000).toFixed(0);\n return mins + 'm ' + secs + 's';\n }\n\n function generateMarkdown() {\n const data = resultsData;\n let md = '# Hive MCP Status Report\\\\n';\n md += 'Generated: ' + data.timestamp + '\\\\n\\\\n';\n\n md += '## Summary\\\\n';\n md += '- **Status**: ' + data.status.toUpperCase() + '\\\\n';\n md += '- **Healthy APIs**: ' + data.healthyApis + ' | **Degraded**: ' + data.degradedApis + ' | **Unhealthy**: ' + data.unhealthyApis + ' | **Inactive**: ' + (data.inactiveApis || 0) + '\\\\n';\n md += '- **Tests Passed**: ' + data.passedTests + '/' + data.totalTests + '\\\\n';\n md += '- **Duration**: ' + formatDurationMs(data.duration) + '\\\\n\\\\n';\n\n md += '## API Results\\\\n\\\\n';\n\n // Sort APIs alphabetically\n const sortedApis = [...data.apis].sort((a, b) => a.api.localeCompare(b.api));\n\n for (const api of sortedApis) {\n const status = api.status === 'passed' ? 'HEALTHY' : api.status === 'partial' ? 'DEGRADED' : api.status === 'inactive' ? 'INACTIVE' : 'UNHEALTHY';\n md += '### ' + api.api.toUpperCase() + ' (' + api.passedTests + '/' + api.totalTests + ' endpoints) - ' + status + '\\\\n';\n if (api.skippedTests > 0) {\n md += '_' + api.skippedTests + ' skipped (no test data or API key)_\\\\n';\n }\n\n md += '| Status | Endpoint | Duration | Details |\\\\n';\n md += '|--------|----------|----------|---------|\\\\n';\n\n for (const test of api.tests) {\n const icon = test.status === 'passed' ? '✅' : test.status === 'failed' ? '❌' : '⚠️';\n const duration = formatDurationMs(test.duration);\n const details = test.error ? test.error.substring(0, 100).replace(/\\\\|/g, '/') + (test.error.length > 100 ? '...' : '') : (test.status === 'passed' ? 'OK' : '-');\n\n md += '| ' + icon + ' ' + test.status + ' | ' + test.name + ' | ' + duration + ' | ' + details + ' |\\\\n';\n }\n md += '\\\\n';\n }\n\n return md;\n }\n\n async function copyAsMarkdown(btn) {\n try {\n const markdown = generateMarkdown();\n await navigator.clipboard.writeText(markdown);\n\n // Show success feedback\n const originalText = btn.textContent;\n btn.textContent = '✓ Copied!';\n btn.classList.add('bg-emerald-600');\n btn.classList.remove('bg-slate-900');\n\n setTimeout(() => {\n btn.textContent = originalText;\n btn.classList.remove('bg-emerald-600');\n btn.classList.add('bg-slate-900');\n }, 2000);\n } catch (err) {\n alert('Failed to copy: ' + err.message);\n }\n }\n </script>\n `;\n}\n\n/**\n * Generate the full status page HTML\n */\nexport function generateStatusPageHtml(\n results: AllTestResults,\n loading: boolean = false,\n scriptNonce?: string,\n): string {\n // Sort APIs alphabetically\n const sortedApis = [...results.apis].sort((a, b) => a.api.localeCompare(b.api));\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Hive MCP - Status</title>\n <script src=\"https://cdn.tailwindcss.com\"></script>${generateGAScript(scriptNonce)}\n <style>\n /* Custom scrollbar for endpoint lists */\n .overflow-y-auto::-webkit-scrollbar {\n width: 6px;\n }\n .overflow-y-auto::-webkit-scrollbar-track {\n background: transparent;\n }\n .overflow-y-auto::-webkit-scrollbar-thumb {\n background: #cbd5e1;\n border-radius: 3px;\n }\n .overflow-y-auto::-webkit-scrollbar-thumb:hover {\n background: #94a3b8;\n }\n </style>\n ${loading ? '<meta http-equiv=\"refresh\" content=\"5\">' : ''}\n</head>\n<body class=\"min-h-screen bg-slate-50 text-slate-900 antialiased\">\n <div class=\"mx-auto max-w-4xl px-4 py-8\">\n ${generateHeader(results)}\n ${generateSummaryCards(results)}\n ${loading ? generateLoadingSpinner() : ''}\n ${generateReadinessLanesPanel(results)}\n ${generateTaskCanaryHistoryPanel()}\n <div class=\"space-y-3\" id=\"api-list\">\n ${sortedApis.map(api => generateApiCard(api)).join('')}\n </div>\n ${generateFooter(results)}\n </div>\n ${generateScript(results, scriptNonce)}\n</body>\n</html>`;\n}\n\n/**\n * Generate a simple loading page HTML\n */\nexport function generateLoadingPageHtml(scriptNonce?: string): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Hive MCP - Running Tests...</title>\n <meta http-equiv=\"refresh\" content=\"5\">\n <script src=\"https://cdn.tailwindcss.com\"></script>${generateGAScript(scriptNonce)}\n</head>\n<body class=\"min-h-screen bg-slate-50 text-slate-900 flex items-center justify-center\">\n <div class=\"flex flex-col items-center gap-4\">\n <svg class=\"animate-spin h-8 w-8 text-slate-400\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <div class=\"text-slate-600 text-sm\">Running API tests... This may take a few minutes.</div>\n <div class=\"text-xs text-slate-400\">Page will refresh automatically.</div>\n </div>\n</body>\n</html>`;\n}\n","import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { InMemoryTransport } from \"@modelcontextprotocol/sdk/inMemory.js\";\nimport { createHiveMcpServer, SERVER_NAME, SERVER_VERSION } from \"../mcpServer.js\";\nimport { HIVE_PROMPTS, HIVE_RESOURCES } from \"../mcpSurface.js\";\nimport {\n getAuthBackendMode,\n isUnkeyConfigured,\n isUnkeyRequired,\n} from \"../services/unkey-service.js\";\nimport { ToolRegistry } from \"../toolRegistry.js\";\nimport {\n RUNTIME_STATUSES,\n type RuntimeStatus,\n} from \"../runtimeStatus.js\";\nimport {\n getRootVisibleToolCount,\n} from \"../utils/toolCatalog.js\";\n\nexport type McpProtocolCheckStatus = \"passed\" | \"failed\" | \"degraded\";\n\nexport type McpProtocolCheck = {\n name: string;\n status: McpProtocolCheckStatus;\n duration: number;\n details?: Record<string, unknown>;\n error?: string;\n};\n\nexport type McpAuthReadiness = {\n status: RuntimeStatus;\n backend: ReturnType<typeof getAuthBackendMode>;\n configured: boolean;\n detail: string;\n};\n\nexport type McpProtocolHealth = {\n status: RuntimeStatus;\n auth: McpAuthReadiness;\n checks: McpProtocolCheck[];\n duration: number;\n passed: number;\n degraded: number;\n failed: number;\n liveInvoke: boolean;\n expected: {\n rootVisibleTools: number;\n resources: number;\n prompts: number;\n categoryListingTools: number;\n };\n timestamp: string;\n};\n\ntype RunMcpProtocolHealthOptions = {\n includeLiveInvoke?: boolean;\n};\n\nfunction getStaticApiKeys(): string[] {\n return (process.env.HIVE_API_KEYS || \"\")\n .split(\",\")\n .map((key) => key.trim())\n .filter(Boolean);\n}\n\nexport function getHttpMcpAuthReadiness(): McpAuthReadiness {\n const backend = getAuthBackendMode();\n const staticKeyCount = getStaticApiKeys().length;\n\n if (isUnkeyRequired()) {\n if (!isUnkeyConfigured()) {\n return {\n status: \"missing_key\",\n backend,\n configured: false,\n detail:\n \"Unkey authentication is selected but UNKEY_ROOT_KEY or UNKEY_API_ID is missing.\",\n };\n }\n return {\n status: \"ok\",\n backend,\n configured: true,\n detail: \"Unkey authentication is configured for HTTP MCP.\",\n };\n }\n\n if (isUnkeyConfigured()) {\n return {\n status: \"ok\",\n backend,\n configured: true,\n detail: \"Unkey authentication is configured for HTTP MCP.\",\n };\n }\n\n if (staticKeyCount > 0) {\n return {\n status: \"ok\",\n backend,\n configured: true,\n detail: `Static authentication is configured with ${staticKeyCount} key(s).`,\n };\n }\n\n return {\n status: \"missing_key\",\n backend,\n configured: false,\n detail:\n \"HTTP MCP authentication is not configured. Set Unkey credentials or HIVE_AUTH_BACKEND=static with HIVE_API_KEYS.\",\n };\n}\n\nasync function timedCheck(\n name: string,\n fn: () => Promise<Record<string, unknown> | void>,\n): Promise<McpProtocolCheck> {\n const start = Date.now();\n try {\n const details = await fn();\n return {\n name,\n status: \"passed\",\n duration: Date.now() - start,\n ...(details && { details }),\n };\n } catch (error) {\n return {\n name,\n status: \"failed\",\n duration: Date.now() - start,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nfunction degradedCheck(\n check: McpProtocolCheck,\n error: string,\n): McpProtocolCheck {\n return {\n ...check,\n status: \"degraded\",\n error,\n };\n}\n\nfunction parseTextJson(result: unknown): Record<string, unknown> | null {\n const content = (result as { content?: Array<{ type?: string; text?: string }> })\n .content;\n const text = content?.find((item) => item.type === \"text\")?.text;\n if (!text) return null;\n try {\n return JSON.parse(text) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nfunction getHiveMetadata(result: unknown): Record<string, unknown> | null {\n const structured = (result as { structuredContent?: Record<string, unknown> })\n .structuredContent;\n if (structured?._hive && typeof structured._hive === \"object\") {\n return structured._hive as Record<string, unknown>;\n }\n\n const parsed = parseTextJson(result);\n if (parsed?._hive && typeof parsed._hive === \"object\") {\n return parsed._hive as Record<string, unknown>;\n }\n\n return null;\n}\n\nfunction summarizeStatus(\n auth: McpAuthReadiness,\n checks: McpProtocolCheck[],\n): RuntimeStatus {\n if (auth.status !== \"ok\") return auth.status;\n if (checks.some((check) => check.status === \"failed\")) return \"failing\";\n if (checks.some((check) => check.status === \"degraded\")) return \"degraded\";\n return \"ok\";\n}\n\nexport async function runMcpProtocolHealth(\n options: RunMcpProtocolHealthOptions = {},\n): Promise<McpProtocolHealth> {\n const includeLiveInvoke = options.includeLiveInvoke ?? true;\n const started = Date.now();\n const auth = getHttpMcpAuthReadiness();\n const checks: McpProtocolCheck[] = [\n {\n name: \"http_mcp_auth_configured\",\n status: auth.status === \"ok\" ? \"passed\" : \"failed\",\n duration: 0,\n details: {\n backend: auth.backend,\n configured: auth.configured,\n detail: auth.detail,\n },\n ...(auth.status !== \"ok\" && { error: auth.detail }),\n },\n ];\n\n const hive = createHiveMcpServer({ kind: \"root\" });\n const server = hive.getServer();\n const client = new Client({ name: \"hive-health-client\", version: \"1.0.0\" });\n const [clientTransport, serverTransport] =\n InMemoryTransport.createLinkedPair();\n\n const initializeCheck = await timedCheck(\"mcp_initialize\", async () => {\n await server.connect(serverTransport);\n await client.connect(clientTransport);\n const serverVersion = client.getServerVersion();\n const capabilities = client.getServerCapabilities();\n const instructions = client.getInstructions();\n\n if (serverVersion?.name !== SERVER_NAME) {\n throw new Error(\n `Expected server name ${SERVER_NAME}, received ${serverVersion?.name ?? \"unknown\"}.`,\n );\n }\n if (serverVersion?.version !== SERVER_VERSION) {\n throw new Error(\n `Expected server version ${SERVER_VERSION}, received ${serverVersion?.version ?? \"unknown\"}.`,\n );\n }\n if (!capabilities?.tools || !capabilities.resources || !capabilities.prompts) {\n throw new Error(\"Server did not advertise tools, resources, and prompts.\");\n }\n if (!instructions?.includes(\"Workflow: call search_tools\")) {\n throw new Error(\"Server instructions do not describe the Hive workflow.\");\n }\n\n return {\n serverName: serverVersion.name,\n serverVersion: serverVersion.version,\n capabilities: Object.keys(capabilities),\n hasInstructions: Boolean(instructions),\n };\n });\n checks.push(initializeCheck);\n\n if (initializeCheck.status === \"failed\") {\n await client.close().catch(() => undefined);\n await server.close().catch(() => undefined);\n return {\n status: summarizeStatus(auth, checks),\n auth,\n checks,\n duration: Date.now() - started,\n passed: checks.filter((check) => check.status === \"passed\").length,\n degraded: checks.filter((check) => check.status === \"degraded\").length,\n failed: checks.filter((check) => check.status === \"failed\").length,\n liveInvoke: includeLiveInvoke,\n expected: {\n rootVisibleTools: getRootVisibleToolCount(),\n resources: HIVE_RESOURCES.length,\n prompts: HIVE_PROMPTS.length,\n categoryListingTools: ToolRegistry.length,\n },\n timestamp: new Date().toISOString(),\n };\n }\n\n try {\n checks.push(\n await timedCheck(\"mcp_ping\", async () => {\n await client.ping();\n }),\n );\n\n checks.push(\n await timedCheck(\"tools_list_root_surface\", async () => {\n const listed = await client.listTools();\n const names = listed.tools.map((tool) => tool.name);\n const expectedCount = getRootVisibleToolCount();\n const expectedTools = [\n \"search_tools\",\n \"get_api_endpoint_schema\",\n \"invoke_api_endpoint\",\n ...ToolRegistry.map((category) => category.name),\n ];\n\n if (listed.tools.length !== expectedCount) {\n throw new Error(\n `Expected ${expectedCount} root tools, received ${listed.tools.length}.`,\n );\n }\n for (const expected of expectedTools) {\n if (!names.includes(expected)) {\n throw new Error(`Missing root tool ${expected}.`);\n }\n }\n\n return {\n count: listed.tools.length,\n expectedCount,\n };\n }),\n );\n\n checks.push(\n await timedCheck(\"resources_list\", async () => {\n const listed = await client.listResources();\n const uris = listed.resources.map((resource) => resource.uri);\n for (const resource of HIVE_RESOURCES) {\n if (!uris.includes(resource.uri)) {\n throw new Error(`Missing resource ${resource.uri}.`);\n }\n }\n\n return {\n count: listed.resources.length,\n expectedCount: HIVE_RESOURCES.length,\n };\n }),\n );\n\n checks.push(\n await timedCheck(\"prompts_list\", async () => {\n const listed = await client.listPrompts();\n const names = listed.prompts.map((prompt) => prompt.name);\n for (const prompt of HIVE_PROMPTS) {\n if (!names.includes(prompt.name)) {\n throw new Error(`Missing prompt ${prompt.name}.`);\n }\n }\n\n return {\n count: listed.prompts.length,\n expectedCount: HIVE_PROMPTS.length,\n };\n }),\n );\n\n checks.push(\n await timedCheck(\"resource_status_contract\", async () => {\n const result = await client.readResource({ uri: \"hive://status\" });\n const firstContent = result.contents[0];\n const text =\n firstContent && \"text\" in firstContent ? firstContent.text : undefined;\n if (!text) {\n throw new Error(\"hive://status returned no text content.\");\n }\n const parsed = JSON.parse(text) as {\n statusContract?: { runtimeStatuses?: string[] };\n observability?: { statusEndpoints?: string[] };\n };\n\n if (!parsed.statusContract?.runtimeStatuses?.includes(\"ok\")) {\n throw new Error(\"hive://status does not expose runtime status semantics.\");\n }\n for (const endpoint of [\"/api/health/mcp\", \"/api/health/workflows\"]) {\n if (!parsed.observability?.statusEndpoints?.includes(endpoint)) {\n throw new Error(`hive://status does not mention ${endpoint}.`);\n }\n }\n\n return {\n runtimeStatuses: parsed.statusContract.runtimeStatuses.length,\n statusEndpoints: parsed.observability?.statusEndpoints?.length ?? 0,\n };\n }),\n );\n\n checks.push(\n await timedCheck(\"schema_lookup_path\", async () => {\n const result = await client.callTool({\n name: \"get_api_endpoint_schema\",\n arguments: { endpoint: \"get_price\" },\n });\n const structured = result.structuredContent as\n | Record<string, unknown>\n | undefined;\n const parsed = structured ?? parseTextJson(result);\n\n if (parsed?.name !== \"get_price\") {\n throw new Error(\"Schema lookup did not return get_price.\");\n }\n if (parsed?.category !== \"Market Data and Price\") {\n throw new Error(\"Schema lookup returned the wrong category.\");\n }\n if (!getHiveMetadata(result)) {\n throw new Error(\"Schema lookup did not include _hive metadata.\");\n }\n\n return {\n endpoint: parsed.name,\n category: parsed.category,\n provider: parsed.provider,\n hasHiveMetadata: true,\n };\n }),\n );\n\n checks.push(\n await timedCheck(\"discovery_tool_routing\", async () => {\n const result = await client.callTool({\n name: \"search_tools\",\n arguments: { query: \"what Hive tool should I use for wallet PnL?\", limit: 10 },\n });\n const structured = result.structuredContent as\n | { toolsets?: Array<{ id?: string }> }\n | undefined;\n const parsed = structured ?? (parseTextJson(result) as\n | { toolsets?: Array<{ id?: string }> }\n | null);\n const toolsets = parsed?.toolsets?.map((toolset) => toolset.id) ?? [];\n\n if (!toolsets.includes(\"search_discovery\")) {\n throw new Error(\"search_tools did not route meta discovery requests.\");\n }\n if (!getHiveMetadata(result)) {\n throw new Error(\"search_tools did not include _hive metadata.\");\n }\n\n return {\n topToolset: toolsets[0],\n matchedToolsets: toolsets.slice(0, 5),\n hasHiveMetadata: true,\n };\n }),\n );\n\n if (includeLiveInvoke) {\n const invokeCheck = await timedCheck(\"safe_live_invoke_with_provenance\", async () => {\n const result = await client.callTool({\n name: \"invoke_api_endpoint\",\n arguments: {\n endpoint_name: \"get_price\",\n args: { ids: \"bitcoin\", vs_currencies: \"usd\" },\n },\n });\n const hiveMetadata = getHiveMetadata(result);\n const runtimeStatus = hiveMetadata?.runtime_status;\n\n if (!hiveMetadata) {\n throw new Error(\"Live invoke did not include _hive metadata.\");\n }\n if (!RUNTIME_STATUSES.includes(runtimeStatus as RuntimeStatus)) {\n throw new Error(\"Live invoke returned an unknown runtime status.\");\n }\n if (runtimeStatus !== \"ok\") {\n throw new Error(\n `Live invoke returned runtime_status=${String(runtimeStatus)}.`,\n );\n }\n\n return {\n provider: hiveMetadata.provider,\n tool: hiveMetadata.tool,\n runtime_status: runtimeStatus,\n source: hiveMetadata.source,\n cache_status: hiveMetadata.cache_status,\n };\n });\n\n const runtimeStatus = (invokeCheck.details?.runtime_status ||\n invokeCheck.error?.match(/runtime_status=([^.\\s]+)/)?.[1]) as\n | RuntimeStatus\n | undefined;\n if (\n invokeCheck.status === \"failed\" &&\n runtimeStatus &&\n runtimeStatus !== \"failing\"\n ) {\n checks.push(\n degradedCheck(\n invokeCheck,\n invokeCheck.error ??\n `Live invoke returned runtime_status=${runtimeStatus}.`,\n ),\n );\n } else {\n checks.push(invokeCheck);\n }\n }\n } finally {\n await client.close().catch(() => undefined);\n await server.close().catch(() => undefined);\n }\n\n return {\n status: summarizeStatus(auth, checks),\n auth,\n checks,\n duration: Date.now() - started,\n passed: checks.filter((check) => check.status === \"passed\").length,\n degraded: checks.filter((check) => check.status === \"degraded\").length,\n failed: checks.filter((check) => check.status === \"failed\").length,\n liveInvoke: includeLiveInvoke,\n expected: {\n rootVisibleTools: getRootVisibleToolCount(),\n resources: HIVE_RESOURCES.length,\n prompts: HIVE_PROMPTS.length,\n categoryListingTools: ToolRegistry.length,\n },\n timestamp: new Date().toISOString(),\n };\n}\n","import { Unkey } from \"@unkey/api\";\nimport { getSupabaseAdmin, type Plan } from \"../db/supabase.js\";\nimport { secureLogger } from \"../utils/secureLogger.js\";\n\nlet _unkey: Unkey | null = null;\n\nexport type AuthBackendMode = \"auto\" | \"unkey\" | \"static\";\n\nexport function getAuthBackendMode(): AuthBackendMode {\n const mode = (process.env.HIVE_AUTH_BACKEND ?? \"auto\")\n .trim()\n .toLowerCase();\n if (mode === \"unkey\" || mode === \"static\" || mode === \"auto\") {\n return mode;\n }\n return \"auto\";\n}\n\nexport function isUnkeyRequired(): boolean {\n return getAuthBackendMode() === \"unkey\";\n}\n\nfunction hasUnkeyCredentials(): boolean {\n return !!(process.env.UNKEY_ROOT_KEY && process.env.UNKEY_API_ID);\n}\n\nexport function isUnkeyConfigured(): boolean {\n return getAuthBackendMode() !== \"static\" && hasUnkeyCredentials();\n}\n\nfunction getUnkey(): Unkey {\n if (!_unkey) {\n if (!isUnkeyConfigured()) {\n throw new Error(\n \"Unkey not configured. Set UNKEY_ROOT_KEY and UNKEY_API_ID.\",\n );\n }\n _unkey = new Unkey({ rootKey: process.env.UNKEY_ROOT_KEY! });\n }\n return _unkey;\n}\n\nfunction getApiId(): string {\n return process.env.UNKEY_API_ID!;\n}\n\nexport interface CreateKeyOptions {\n userId: string;\n name: string;\n planId: string;\n}\n\nexport interface CreateKeyResult {\n keyId: string;\n key: string;\n}\n\nexport interface VerifyKeyResult {\n valid: boolean;\n code: string;\n keyId?: string;\n userId?: string;\n planId?: string;\n name?: string;\n credits?: number;\n ratelimit?: {\n remaining: number;\n limit: number;\n reset: number;\n };\n}\n\nfunction normalizeAnalyticsTags(tags: string[]): string[] {\n const normalized = new Set<string>();\n\n for (const tag of tags) {\n const trimmed = tag.trim();\n if (!trimmed) continue;\n\n // Tags appear in analytics, so only allow low-cardinality labels. Do not\n // include user input such as wallet addresses, token addresses, or raw args.\n const safe = trimmed\n .replace(/[^a-zA-Z0-9_./:=|-]/g, \"_\")\n .slice(0, 128);\n if (safe) normalized.add(safe);\n if (normalized.size >= 16) break;\n }\n\n return [...normalized];\n}\n\nexport interface KeyInfo {\n keyId: string;\n name: string;\n prefix: string;\n createdAt: string;\n enabled: boolean;\n credits?: number;\n externalId?: string;\n meta?: Record<string, unknown>;\n}\n\nasync function getPlan(planId: string): Promise<Plan> {\n const supabase = getSupabaseAdmin();\n const { data, error } = await supabase\n .from(\"plans\")\n .select(\"*\")\n .eq(\"id\", planId)\n .single();\n\n if (error || !data) {\n throw new Error(`Plan '${planId}' not found`);\n }\n return data as Plan;\n}\n\nasync function countActiveUserKeys(userId: string): Promise<number> {\n const result = await getUnkey().apis.listKeys({\n apiId: getApiId(),\n externalId: userId,\n });\n if (!result.data) return 0;\n const keys = Array.isArray(result.data) ? result.data : [];\n // Disabled keys still count against the user's slot allowance — they exist\n // in Unkey for audit purposes but are not authenticatable. Filter to enabled.\n return keys.filter((k: Record<string, unknown>) => k.enabled !== false).length;\n}\n\nexport async function createApiKey(\n opts: CreateKeyOptions,\n): Promise<CreateKeyResult> {\n const plan = await getPlan(opts.planId);\n\n const activeCount = await countActiveUserKeys(opts.userId);\n if (activeCount >= plan.max_api_keys) {\n throw new Error(\n `Key limit reached. Your ${plan.name} plan allows ${plan.max_api_keys} keys.`,\n );\n }\n\n // IMPORTANT: do not attach `credits` to the key. Credits are tracked\n // per-user in public.credit_wallets via wallet-service.consumeCredits.\n // Per-key credits caused the delete-and-recreate exploit. Unkey's role\n // here is auth + per-key rate limiting only.\n const result = await getUnkey().keys.createKey({\n apiId: getApiId(),\n prefix: \"hive_live\",\n name: opts.name,\n byteLength: 24,\n externalId: opts.userId,\n meta: { plan: opts.planId, name: opts.name },\n ratelimits: [\n {\n name: \"requests\",\n limit: plan.rate_limit_per_min,\n duration: 60_000,\n },\n ],\n enabled: true,\n });\n\n if (!result.data) {\n secureLogger.error(\"Unkey createKey failed\", null, {\n error: \"No data in response\",\n });\n throw new Error(\"Failed to create API key\");\n }\n\n return { keyId: result.data.keyId, key: result.data.key };\n}\n\nexport async function verifyApiKey(\n rawKey: string,\n analyticsTags: string[] = [],\n): Promise<VerifyKeyResult> {\n const tags = normalizeAnalyticsTags(analyticsTags);\n const result = await getUnkey().keys.verifyKey({\n key: rawKey,\n ...(tags.length > 0 ? { tags } : {}),\n ratelimits: [\n {\n name: \"requests\",\n cost: 1,\n },\n ],\n });\n\n if (!result.data) {\n secureLogger.warn(\"Unkey verifyKey call failed\", {\n error: \"No data in response\",\n });\n return { valid: false, code: \"VERIFICATION_FAILED\" };\n }\n\n const d = result.data;\n const rl = d.ratelimits?.[0];\n\n return {\n valid: d.valid,\n code: d.code ?? (d.valid ? \"VALID\" : \"UNKNOWN\"),\n keyId: d.keyId,\n userId: d.identity?.externalId,\n planId: (d.meta as Record<string, unknown>)?.plan as string | undefined,\n name: d.name,\n credits: d.credits ?? undefined,\n ratelimit: rl\n ? { remaining: rl.remaining, limit: rl.limit, reset: rl.reset }\n : undefined,\n };\n}\n\nexport async function listKeys(userId: string): Promise<KeyInfo[]> {\n const result = await getUnkey().apis.listKeys({\n apiId: getApiId(),\n externalId: userId,\n });\n\n // SDK returns result.data as an array of keys directly\n const keys = Array.isArray(result.data) ? result.data : [];\n if (keys.length === 0) return [];\n\n return keys.map((k: Record<string, unknown>) => ({\n keyId: (k.keyId as string) ?? \"\",\n name: (k.name as string) ?? \"Unnamed\",\n prefix: (k.start as string) ?? \"\",\n createdAt: k.createdAt\n ? new Date(k.createdAt as number).toISOString()\n : new Date().toISOString(),\n enabled: (k.enabled as boolean) ?? true,\n credits: (k.credits as { remaining?: number })?.remaining ?? undefined,\n externalId:\n (k.identity as { externalId?: string })?.externalId ?? undefined,\n meta: (k.meta as Record<string, unknown>) ?? undefined,\n }));\n}\n\n// User-initiated \"revoke\" disables the key rather than hard-deleting it.\n// Disabled keys can no longer authenticate but remain visible in the dashboard\n// for auditability. Hard delete is reserved for admin/cron cleanup.\nexport async function revokeKey(keyId: string): Promise<void> {\n await getUnkey().keys.updateKey({\n keyId,\n enabled: false,\n });\n}\n\n// Explicit hard delete — only used by admin tooling or background cleanup.\nexport async function purgeKey(keyId: string): Promise<void> {\n await getUnkey().keys.deleteKey({ keyId });\n}\n\n// Plan upgrades/downgrades update only the per-key ratelimit. The user's\n// credit balance is updated separately via wallet-service.applyPlanChange.\nexport async function updateKeyLimits(\n keyId: string,\n planId: string,\n): Promise<void> {\n const plan = await getPlan(planId);\n await getUnkey().keys.updateKey({\n keyId,\n meta: { plan: planId },\n ratelimits: [\n {\n name: \"requests\",\n limit: plan.rate_limit_per_min,\n duration: 60_000,\n },\n ],\n });\n}\n","import { createClient, SupabaseClient } from \"@supabase/supabase-js\";\nimport { getRequiredEnvVar, hasEnvVars } from \"../config/env.js\";\n\nlet _supabaseAdmin: SupabaseClient | null = null;\nlet _supabaseAuth: SupabaseClient | null = null;\n\nexport function isSupabaseConfigured(): boolean {\n return hasEnvVars(\"SUPABASE_URL\", \"SUPABASE_SERVICE_ROLE_KEY\");\n}\n\nexport function getSupabaseAdmin(): SupabaseClient {\n if (!_supabaseAdmin) {\n if (!isSupabaseConfigured()) {\n throw new Error(\n \"Supabase not configured. Set SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY.\",\n );\n }\n _supabaseAdmin = createClient(\n getRequiredEnvVar(\"SUPABASE_URL\"),\n getRequiredEnvVar(\"SUPABASE_SERVICE_ROLE_KEY\"),\n { auth: { persistSession: false, autoRefreshToken: false } },\n );\n }\n return _supabaseAdmin;\n}\n\nexport function getSupabaseAuthClient(): SupabaseClient {\n if (!_supabaseAuth) {\n if (!hasEnvVars(\"SUPABASE_URL\", \"SUPABASE_ANON_KEY\")) {\n throw new Error(\n \"Supabase auth client not configured. Set SUPABASE_URL and SUPABASE_ANON_KEY.\",\n );\n }\n _supabaseAuth = createClient(\n getRequiredEnvVar(\"SUPABASE_URL\"),\n getRequiredEnvVar(\"SUPABASE_ANON_KEY\"),\n { auth: { persistSession: false, autoRefreshToken: false } },\n );\n }\n return _supabaseAuth;\n}\n\nexport interface Plan {\n id: string;\n name: string;\n rate_limit_per_min: number;\n monthly_credits: number;\n max_api_keys: number;\n is_active: boolean;\n metadata: Record<string, unknown>;\n}\n\nexport interface UserProfile {\n id: string;\n plan_id: string;\n email: string | null;\n display_name: string | null;\n billing_customer_id: string | null;\n billing_subscription_id: string | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UsageDailyRollup {\n user_id: string;\n usage_date: string;\n request_count: number;\n credit_count: number;\n created_at: string;\n updated_at: string;\n}\n","import { dynamicTools } from \"../tools/dynamic-tools.js\";\nimport { getAllWrappedEndpoints } from \"../wrapper/index.js\";\nimport {\n TASK_TOOLSET_RUNTIME_STATUSES,\n type TaskToolsetRuntimeStatus,\n} from \"../taskToolsets.js\";\nimport { aggregateRuntimeStatus } from \"../runtimeStatus.js\";\n\nexport type WorkflowRegressionCase = {\n id: string;\n workflow: string;\n prompt: string;\n expectedTopToolset: string;\n expectedToolsets: string[];\n expectedCategoryTool: string;\n expectedSchemaTool: string;\n expectedProvider?: string;\n};\n\nexport type WorkflowRegressionResult = {\n id: string;\n workflow: string;\n prompt: string;\n status: \"passed\" | \"failed\";\n expectedTopToolset: string;\n selectedTopToolset?: string;\n expectedToolsets: string[];\n matchedToolsets: string[];\n expectedCategoryTool: string;\n expectedSchemaTool: string;\n expectedProvider?: string;\n selectedSchemaProvider?: string;\n selectedSchemaCategory?: string;\n discoveredToolCount: number;\n duration: number;\n error?: string;\n};\n\nexport type WorkflowRegressionSummary = {\n status: TaskToolsetRuntimeStatus;\n total: number;\n passed: number;\n failed: number;\n duration: number;\n results: WorkflowRegressionResult[];\n toolsetCoverage: Record<string, number>;\n providerCoverage: Record<string, number>;\n categoryToolCoverage: Record<string, number>;\n runtimeStatuses: readonly TaskToolsetRuntimeStatus[];\n timestamp: string;\n};\n\nexport type WorkflowRegressionHistory = {\n status: TaskToolsetRuntimeStatus;\n count: number;\n maxEntries: number;\n latest: WorkflowRegressionSummary | null;\n history: WorkflowRegressionSummary[];\n runtimeStatuses: readonly TaskToolsetRuntimeStatus[];\n timestamp: string;\n};\n\nconst WORKFLOW_HISTORY_LIMIT = Number.parseInt(\n process.env.HIVE_WORKFLOW_CANARY_HISTORY_LIMIT || \"50\",\n 10,\n);\n\nconst workflowHistory: WorkflowRegressionSummary[] = [];\n\nexport const WORKFLOW_REGRESSION_CASES: WorkflowRegressionCase[] = [\n {\n id: \"wallet-balances\",\n workflow: \"Wallet\",\n prompt: \"how do I get wallet balances?\",\n expectedTopToolset: \"wallet_investigation\",\n expectedToolsets: [\"wallet_investigation\"],\n expectedCategoryTool: \"get_portfolio_wallet_endpoints\",\n expectedSchemaTool: \"alchemy_get_token_balances_by_wallet\",\n expectedProvider: \"Alchemy\",\n },\n {\n id: \"token-rugpull\",\n workflow: \"Security\",\n prompt: \"is this token a rugpull?\",\n expectedTopToolset: \"security_risk\",\n expectedToolsets: [\"security_risk\", \"token_diligence\"],\n expectedCategoryTool: \"get_security_risk_endpoints\",\n expectedSchemaTool: \"detect_rugpull\",\n expectedProvider: \"GoPlus\",\n },\n {\n id: \"aave-tvl\",\n workflow: \"DeFi\",\n prompt: \"what is the TVL for Aave?\",\n expectedTopToolset: \"defi_protocol_analysis\",\n expectedToolsets: [\"defi_protocol_analysis\"],\n expectedCategoryTool: \"get_defi_protocol_endpoints\",\n expectedSchemaTool: \"get_protocol_tvl\",\n expectedProvider: \"DeFiLlama\",\n },\n {\n id: \"polymarket-kalshi\",\n workflow: \"Prediction\",\n prompt: \"who is winning polymarket vs kalshi wars\",\n expectedTopToolset: \"prediction_markets\",\n expectedToolsets: [\"prediction_markets\"],\n expectedCategoryTool: \"get_prediction_markets_endpoints\",\n expectedSchemaTool: \"codex_filter_prediction_markets\",\n expectedProvider: \"Codex\",\n },\n {\n id: \"dapp-phishing\",\n workflow: \"Security\",\n prompt: \"is this dapp phishing\",\n expectedTopToolset: \"security_risk\",\n expectedToolsets: [\"security_risk\"],\n expectedCategoryTool: \"get_security_risk_endpoints\",\n expectedSchemaTool: \"check_phishing_site\",\n expectedProvider: \"GoPlus\",\n },\n {\n id: \"btc-spot-volume\",\n workflow: \"Market\",\n prompt: \"show BTC spot price and 24h volume\",\n expectedTopToolset: \"market_research\",\n expectedToolsets: [\"market_research\"],\n expectedCategoryTool: \"get_market_and_price_endpoints\",\n expectedSchemaTool: \"get_price\",\n expectedProvider: \"CoinGecko\",\n },\n {\n id: \"eth-funding-rates\",\n workflow: \"Market\",\n prompt: \"compare ETH funding rates on binance and bybit\",\n expectedTopToolset: \"market_research\",\n expectedToolsets: [\"market_research\"],\n expectedCategoryTool: \"get_market_and_price_endpoints\",\n expectedSchemaTool: \"get_funding_rates\",\n expectedProvider: \"CCXT\",\n },\n {\n id: \"sol-open-interest-liquidations\",\n workflow: \"Market\",\n prompt: \"what is SOL open interest and liquidation activity?\",\n expectedTopToolset: \"market_research\",\n expectedToolsets: [\"market_research\"],\n expectedCategoryTool: \"get_market_and_price_endpoints\",\n expectedSchemaTool: \"get_open_interest\",\n expectedProvider: \"CCXT\",\n },\n {\n id: \"btc-orderbook\",\n workflow: \"Market\",\n prompt: \"get the BTC order book on Coinbase\",\n expectedTopToolset: \"market_research\",\n expectedToolsets: [\"market_research\"],\n expectedCategoryTool: \"get_market_and_price_endpoints\",\n expectedSchemaTool: \"get_orderbook\",\n expectedProvider: \"CCXT\",\n },\n {\n id: \"wojak-safe\",\n workflow: \"Token\",\n prompt: \"is WOJAK safe to buy?\",\n expectedTopToolset: \"security_risk\",\n expectedToolsets: [\"security_risk\", \"token_diligence\"],\n expectedCategoryTool: \"get_security_risk_endpoints\",\n expectedSchemaTool: \"get_token_security\",\n expectedProvider: \"GoPlus\",\n },\n {\n id: \"holders-top-traders\",\n workflow: \"Token\",\n prompt: \"find holders and top traders for this contract\",\n expectedTopToolset: \"token_diligence\",\n expectedToolsets: [\"token_diligence\"],\n expectedCategoryTool: \"get_token_contract_endpoints\",\n expectedSchemaTool: \"get_token_holders\",\n expectedProvider: \"Codex\",\n },\n {\n id: \"token-socials-metadata\",\n workflow: \"Token\",\n prompt: \"what are the socials and metadata for this token?\",\n expectedTopToolset: \"token_diligence\",\n expectedToolsets: [\"token_diligence\"],\n expectedCategoryTool: \"get_token_contract_endpoints\",\n expectedSchemaTool: \"alchemy_get_token_metadata\",\n expectedProvider: \"Alchemy\",\n },\n {\n id: \"pepe-on-base\",\n workflow: \"Token\",\n prompt: \"search for tokens named pepe on base\",\n expectedTopToolset: \"token_diligence\",\n expectedToolsets: [\"token_diligence\", \"search_discovery\"],\n expectedCategoryTool: \"get_search_discovery_endpoints\",\n expectedSchemaTool: \"search_tokens\",\n expectedProvider: \"Codex\",\n },\n {\n id: \"profitable-wallets\",\n workflow: \"Wallet\",\n prompt: \"show profitable wallets trading this token\",\n expectedTopToolset: \"wallet_investigation\",\n expectedToolsets: [\"wallet_investigation\"],\n expectedCategoryTool: \"get_portfolio_wallet_endpoints\",\n expectedSchemaTool: \"filter_network_wallets\",\n expectedProvider: \"Codex\",\n },\n {\n id: \"wallet-defi-pnl\",\n workflow: \"Wallet\",\n prompt: \"does this wallet have DeFi positions and PnL?\",\n expectedTopToolset: \"wallet_investigation\",\n expectedToolsets: [\"wallet_investigation\"],\n expectedCategoryTool: \"get_portfolio_wallet_endpoints\",\n expectedSchemaTool: \"moralis_get_wallet_defi_positions\",\n expectedProvider: \"Moralis\",\n },\n {\n id: \"wallet-swaps-base\",\n workflow: \"Wallet\",\n prompt: \"show recent swaps for this wallet on base\",\n expectedTopToolset: \"wallet_investigation\",\n expectedToolsets: [\"wallet_investigation\"],\n expectedCategoryTool: \"get_portfolio_wallet_endpoints\",\n expectedSchemaTool: \"moralis_get_wallet_swaps\",\n expectedProvider: \"Moralis\",\n },\n {\n id: \"malicious-address\",\n workflow: \"Security\",\n prompt: \"does this address look malicious?\",\n expectedTopToolset: \"security_risk\",\n expectedToolsets: [\"security_risk\"],\n expectedCategoryTool: \"get_security_risk_endpoints\",\n expectedSchemaTool: \"check_malicious_address\",\n expectedProvider: \"GoPlus\",\n },\n {\n id: \"wallet-approvals\",\n workflow: \"Security\",\n prompt: \"check wallet approvals for USDC spender\",\n expectedTopToolset: \"security_risk\",\n expectedToolsets: [\"security_risk\"],\n expectedCategoryTool: \"get_security_risk_endpoints\",\n expectedSchemaTool: \"get_wallet_approvals\",\n expectedProvider: \"GoPlus\",\n },\n {\n id: \"simulate-transaction\",\n workflow: \"Security\",\n prompt: \"simulate this transaction before I sign it\",\n expectedTopToolset: \"security_risk\",\n expectedToolsets: [\"security_risk\"],\n expectedCategoryTool: \"get_security_risk_endpoints\",\n expectedSchemaTool: \"tenderly_simulate_transaction\",\n expectedProvider: \"Tenderly\",\n },\n {\n id: \"decode-calldata\",\n workflow: \"Security\",\n prompt: \"decode this calldata\",\n expectedTopToolset: \"security_risk\",\n expectedToolsets: [\"security_risk\"],\n expectedCategoryTool: \"get_security_risk_endpoints\",\n expectedSchemaTool: \"tenderly_decode_calldata\",\n expectedProvider: \"Tenderly\",\n },\n {\n id: \"trending-base-pools\",\n workflow: \"DEX\",\n prompt: \"find trending pools on Base\",\n expectedTopToolset: \"onchain_dex_pool_analysis\",\n expectedToolsets: [\"onchain_dex_pool_analysis\"],\n expectedCategoryTool: \"get_onchain_dex_pool_endpoints\",\n expectedSchemaTool: \"get_trending_pools\",\n expectedProvider: \"CoinGecko\",\n },\n {\n id: \"uniswap-pool-liquidity\",\n workflow: \"DEX\",\n prompt: \"analyze liquidity for this Uniswap pool\",\n expectedTopToolset: \"onchain_dex_pool_analysis\",\n expectedToolsets: [\"onchain_dex_pool_analysis\"],\n expectedCategoryTool: \"get_onchain_dex_pool_endpoints\",\n expectedSchemaTool: \"get_liquidity_info\",\n expectedProvider: \"Codex\",\n },\n {\n id: \"pair-trades-ohlcv\",\n workflow: \"DEX\",\n prompt: \"show pair trades and OHLCV for this token\",\n expectedTopToolset: \"onchain_dex_pool_analysis\",\n expectedToolsets: [\"onchain_dex_pool_analysis\"],\n expectedCategoryTool: \"get_onchain_dex_pool_endpoints\",\n expectedSchemaTool: \"get_pool_trades\",\n expectedProvider: \"CoinGecko\",\n },\n {\n id: \"aave-compound-fees\",\n workflow: \"DeFi\",\n prompt: \"compare Aave and Compound fees revenue and TVL\",\n expectedTopToolset: \"defi_protocol_analysis\",\n expectedToolsets: [\"defi_protocol_analysis\"],\n expectedCategoryTool: \"get_defi_protocol_endpoints\",\n expectedSchemaTool: \"get_protocol_fees\",\n expectedProvider: \"DeFiLlama\",\n },\n {\n id: \"stablecoin-bridge-volume\",\n workflow: \"DeFi\",\n prompt: \"show stablecoin supply and bridge volume on Arbitrum\",\n expectedTopToolset: \"defi_protocol_analysis\",\n expectedToolsets: [\"defi_protocol_analysis\"],\n expectedCategoryTool: \"get_defi_protocol_endpoints\",\n expectedSchemaTool: \"get_stablecoins\",\n expectedProvider: \"DeFiLlama\",\n },\n {\n id: \"yield-pools-usdc\",\n workflow: \"DeFi\",\n prompt: \"find best yield pools for USDC\",\n expectedTopToolset: \"defi_protocol_analysis\",\n expectedToolsets: [\"defi_protocol_analysis\"],\n expectedCategoryTool: \"get_defi_protocol_endpoints\",\n expectedSchemaTool: \"get_yield_pools\",\n expectedProvider: \"DeFiLlama\",\n },\n {\n id: \"nft-floor-sales\",\n workflow: \"NFT\",\n prompt: \"what is the floor price and sales for this NFT collection?\",\n expectedTopToolset: \"nft_research\",\n expectedToolsets: [\"nft_research\"],\n expectedCategoryTool: \"get_nft_analytics_endpoints\",\n expectedSchemaTool: \"alchemy_get_floor_price\",\n expectedProvider: \"Alchemy\",\n },\n {\n id: \"nft-spam\",\n workflow: \"NFT\",\n prompt: \"is this NFT contract spam?\",\n expectedTopToolset: \"nft_research\",\n expectedToolsets: [\"nft_research\", \"security_risk\"],\n expectedCategoryTool: \"get_nft_analytics_endpoints\",\n expectedSchemaTool: \"alchemy_is_spam_contract\",\n expectedProvider: \"Alchemy\",\n },\n {\n id: \"nft-owner-metadata\",\n workflow: \"NFT\",\n prompt: \"who owns this NFT and what is its metadata?\",\n expectedTopToolset: \"nft_research\",\n expectedToolsets: [\"nft_research\"],\n expectedCategoryTool: \"get_nft_analytics_endpoints\",\n expectedSchemaTool: \"alchemy_get_nft_metadata\",\n expectedProvider: \"Alchemy\",\n },\n {\n id: \"ethereum-gas\",\n workflow: \"Network\",\n prompt: \"what is ethereum gas right now?\",\n expectedTopToolset: \"network_infrastructure\",\n expectedToolsets: [\"network_infrastructure\"],\n expectedCategoryTool: \"get_network_infrastructure_endpoints\",\n expectedSchemaTool: \"alchemy_get_gas_price\",\n expectedProvider: \"Alchemy\",\n },\n {\n id: \"transaction-receipt-logs\",\n workflow: \"Network\",\n prompt: \"fetch this transaction receipt and logs\",\n expectedTopToolset: \"network_infrastructure\",\n expectedToolsets: [\"network_infrastructure\"],\n expectedCategoryTool: \"get_network_infrastructure_endpoints\",\n expectedSchemaTool: \"alchemy_get_transaction_receipt\",\n expectedProvider: \"Alchemy\",\n },\n {\n id: \"tenderly-supported-chains\",\n workflow: \"Network\",\n prompt: \"what chains does Tenderly support?\",\n expectedTopToolset: \"network_infrastructure\",\n expectedToolsets: [\"network_infrastructure\"],\n expectedCategoryTool: \"get_network_infrastructure_endpoints\",\n expectedSchemaTool: \"tenderly_get_supported_networks\",\n expectedProvider: \"Tenderly\",\n },\n {\n id: \"spl-token-accounts\",\n workflow: \"Solana\",\n prompt: \"show SPL token accounts for this wallet\",\n expectedTopToolset: \"solana_analysis\",\n expectedToolsets: [\"solana_analysis\", \"wallet_investigation\"],\n expectedCategoryTool: \"get_portfolio_wallet_endpoints\",\n expectedSchemaTool: \"helius_get_token_accounts\",\n expectedProvider: \"Helius\",\n },\n {\n id: \"solana-priority-fee\",\n workflow: \"Solana\",\n prompt: \"estimate priority fee for this Solana transaction\",\n expectedTopToolset: \"solana_analysis\",\n expectedToolsets: [\"solana_analysis\", \"network_infrastructure\"],\n expectedCategoryTool: \"get_network_infrastructure_endpoints\",\n expectedSchemaTool: \"helius_get_priority_fee_estimate\",\n expectedProvider: \"Helius\",\n },\n {\n id: \"pumpfun-new-tokens\",\n workflow: \"Solana\",\n prompt: \"find new pumpfun tokens\",\n expectedTopToolset: \"solana_analysis\",\n expectedToolsets: [\"solana_analysis\"],\n expectedCategoryTool: \"get_portfolio_wallet_endpoints\",\n expectedSchemaTool: \"moralis_get_pumpfun_new_tokens\",\n expectedProvider: \"Moralis\",\n },\n {\n id: \"election-odds\",\n workflow: \"Prediction\",\n prompt: \"find active election odds markets\",\n expectedTopToolset: \"prediction_markets\",\n expectedToolsets: [\"prediction_markets\"],\n expectedCategoryTool: \"get_prediction_markets_endpoints\",\n expectedSchemaTool: \"codex_filter_prediction_markets\",\n expectedProvider: \"Codex\",\n },\n {\n id: \"prediction-order-books\",\n workflow: \"Prediction\",\n prompt: \"show price and order books for this prediction market\",\n expectedTopToolset: \"prediction_markets\",\n expectedToolsets: [\"prediction_markets\"],\n expectedCategoryTool: \"get_prediction_markets_endpoints\",\n expectedSchemaTool: \"codex_prediction_outcome_order_books\",\n expectedProvider: \"Codex\",\n },\n {\n id: \"prediction-traders\",\n workflow: \"Prediction\",\n prompt: \"which traders are active in this event?\",\n expectedTopToolset: \"prediction_markets\",\n expectedToolsets: [\"prediction_markets\"],\n expectedCategoryTool: \"get_prediction_markets_endpoints\",\n expectedSchemaTool: \"codex_filter_prediction_traders\",\n expectedProvider: \"Codex\",\n },\n {\n id: \"tool-for-wallet-pnl\",\n workflow: \"Search/meta\",\n prompt: \"what Hive tool should I use for wallet PnL?\",\n expectedTopToolset: \"search_discovery\",\n expectedToolsets: [\"search_discovery\", \"wallet_investigation\"],\n expectedCategoryTool: \"get_search_discovery_endpoints\",\n expectedSchemaTool: \"search_tools\",\n expectedProvider: \"Hive\",\n },\n {\n id: \"schema-token-security\",\n workflow: \"Search/meta\",\n prompt: \"get schema for token security\",\n expectedTopToolset: \"search_discovery\",\n expectedToolsets: [\"search_discovery\", \"security_risk\"],\n expectedCategoryTool: \"get_search_discovery_endpoints\",\n expectedSchemaTool: \"get_api_endpoint_schema\",\n expectedProvider: \"Hive\",\n },\n {\n id: \"provider-codex-configured\",\n workflow: \"Provider/status\",\n prompt: \"do we have Codex configured?\",\n expectedTopToolset: \"search_discovery\",\n expectedToolsets: [\"search_discovery\"],\n expectedCategoryTool: \"get_search_discovery_endpoints\",\n expectedSchemaTool: \"search_tools\",\n expectedProvider: \"Hive\",\n },\n {\n id: \"prediction-missing-key\",\n workflow: \"Runtime\",\n prompt: \"provider key missing for prediction markets\",\n expectedTopToolset: \"prediction_markets\",\n expectedToolsets: [\"prediction_markets\"],\n expectedCategoryTool: \"get_prediction_markets_endpoints\",\n expectedSchemaTool: \"codex_filter_prediction_markets\",\n expectedProvider: \"Codex\",\n },\n {\n id: \"cache-freshness\",\n workflow: \"Cache/freshness\",\n prompt: \"is this result live or cached?\",\n expectedTopToolset: \"search_discovery\",\n expectedToolsets: [\"search_discovery\"],\n expectedCategoryTool: \"get_search_discovery_endpoints\",\n expectedSchemaTool: \"invoke_api_endpoint\",\n expectedProvider: \"Hive\",\n },\n {\n id: \"companies-treasury\",\n workflow: \"Token\",\n prompt: \"which public companies hold the most bitcoin treasury?\",\n expectedTopToolset: \"token_diligence\",\n expectedToolsets: [\"token_diligence\"],\n expectedCategoryTool: \"get_token_contract_endpoints\",\n expectedSchemaTool: \"get_companies_treasury\",\n expectedProvider: \"CoinGecko\",\n },\n {\n id: \"exchange-status\",\n workflow: \"Network\",\n prompt: \"is Binance exchange status operational right now?\",\n expectedTopToolset: \"network_infrastructure\",\n expectedToolsets: [\"network_infrastructure\"],\n expectedCategoryTool: \"get_network_infrastructure_endpoints\",\n expectedSchemaTool: \"get_exchange_status\",\n expectedProvider: \"CCXT\",\n },\n {\n id: \"supported-currencies\",\n workflow: \"Market\",\n prompt: \"list supported currencies for CoinGecko price quotes\",\n expectedTopToolset: \"market_research\",\n expectedToolsets: [\"market_research\"],\n expectedCategoryTool: \"get_market_and_price_endpoints\",\n expectedSchemaTool: \"get_supported_currencies\",\n expectedProvider: \"CoinGecko\",\n },\n {\n id: \"token-allowance\",\n workflow: \"Security\",\n prompt: \"check token allowance for a spender before I approve USDC\",\n expectedTopToolset: \"security_risk\",\n expectedToolsets: [\"security_risk\"],\n expectedCategoryTool: \"get_security_risk_endpoints\",\n expectedSchemaTool: \"alchemy_get_token_allowance\",\n expectedProvider: \"Alchemy\",\n },\n {\n id: \"asset-transfers\",\n workflow: \"Wallet\",\n prompt: \"show Alchemy asset transfers for this wallet\",\n expectedTopToolset: \"wallet_investigation\",\n expectedToolsets: [\"wallet_investigation\"],\n expectedCategoryTool: \"get_portfolio_wallet_endpoints\",\n expectedSchemaTool: \"alchemy_get_asset_transfers\",\n expectedProvider: \"Alchemy\",\n },\n {\n id: \"moralis-token-score\",\n workflow: \"Token\",\n prompt: \"get Moralis token score for PEPE\",\n expectedTopToolset: \"token_diligence\",\n expectedToolsets: [\"token_diligence\"],\n expectedCategoryTool: \"get_token_contract_endpoints\",\n expectedSchemaTool: \"moralis_get_token_score\",\n expectedProvider: \"Moralis\",\n },\n {\n id: \"helius-assets-creator\",\n workflow: \"Solana\",\n prompt: \"find Solana DAS assets by creator authority\",\n expectedTopToolset: \"solana_analysis\",\n expectedToolsets: [\"solana_analysis\", \"token_diligence\"],\n expectedCategoryTool: \"get_token_contract_endpoints\",\n expectedSchemaTool: \"helius_get_assets_by_creator\",\n expectedProvider: \"Helius\",\n },\n {\n id: \"current-solana-slot\",\n workflow: \"Network\",\n prompt: \"what is the current Solana slot?\",\n expectedTopToolset: \"network_infrastructure\",\n expectedToolsets: [\"network_infrastructure\", \"solana_analysis\"],\n expectedCategoryTool: \"get_network_infrastructure_endpoints\",\n expectedSchemaTool: \"helius_get_slot\",\n expectedProvider: \"Helius\",\n },\n {\n id: \"chain-fees-base\",\n workflow: \"DeFi\",\n prompt: \"show DeFiLlama chain fees on Base\",\n expectedTopToolset: \"defi_protocol_analysis\",\n expectedToolsets: [\"defi_protocol_analysis\"],\n expectedCategoryTool: \"get_defi_protocol_endpoints\",\n expectedSchemaTool: \"get_chain_fees\",\n expectedProvider: \"DeFiLlama\",\n },\n {\n id: \"bridge-aggregator-volume\",\n workflow: \"DeFi\",\n prompt: \"compare bridge aggregator volume for LI.FI and Bungee\",\n expectedTopToolset: \"defi_protocol_analysis\",\n expectedToolsets: [\"defi_protocol_analysis\", \"onchain_dex_pool_analysis\"],\n expectedCategoryTool: \"get_onchain_dex_pool_endpoints\",\n expectedSchemaTool: \"defillama_get_bridge_aggregator_volumes\",\n expectedProvider: \"DeFiLlama\",\n },\n {\n id: \"moralis-wallet-insight\",\n workflow: \"Wallet\",\n prompt: \"summarize Moralis wallet insight and chain activity\",\n expectedTopToolset: \"wallet_investigation\",\n expectedToolsets: [\"wallet_investigation\"],\n expectedCategoryTool: \"get_portfolio_wallet_endpoints\",\n expectedSchemaTool: \"moralis_get_wallet_insight\",\n expectedProvider: \"Moralis\",\n },\n {\n id: \"goplus-nft-approvals\",\n workflow: \"Security\",\n prompt: \"check GoPlus NFT approvals for this operator\",\n expectedTopToolset: \"security_risk\",\n expectedToolsets: [\"security_risk\", \"nft_research\"],\n expectedCategoryTool: \"get_security_risk_endpoints\",\n expectedSchemaTool: \"goplus_get_nft721_approvals\",\n expectedProvider: \"GoPlus\",\n },\n {\n id: \"tenderly-gas-estimate\",\n workflow: \"Security\",\n prompt: \"estimate gas with Tenderly before sending this transaction\",\n expectedTopToolset: \"security_risk\",\n expectedToolsets: [\"security_risk\", \"network_infrastructure\"],\n expectedCategoryTool: \"get_security_risk_endpoints\",\n expectedSchemaTool: \"tenderly_estimate_gas\",\n expectedProvider: \"Tenderly\",\n },\n {\n id: \"ccxt-options-greeks\",\n workflow: \"Market\",\n prompt: \"fetch options greeks and volatility for BTC options\",\n expectedTopToolset: \"market_research\",\n expectedToolsets: [\"market_research\"],\n expectedCategoryTool: \"get_market_and_price_endpoints\",\n expectedSchemaTool: \"ccxt_fetch_greeks\",\n expectedProvider: \"CCXT\",\n },\n {\n id: \"community-notes\",\n workflow: \"Network\",\n prompt: \"get community notes for this address or transaction\",\n expectedTopToolset: \"network_infrastructure\",\n expectedToolsets: [\"network_infrastructure\"],\n expectedCategoryTool: \"get_network_infrastructure_endpoints\",\n expectedSchemaTool: \"get_community_notes\",\n expectedProvider: \"Codex\",\n },\n {\n id: \"entity-search\",\n workflow: \"Search/meta\",\n prompt: \"search entities by category and show discovery schema\",\n expectedTopToolset: \"search_discovery\",\n expectedToolsets: [\"search_discovery\"],\n expectedCategoryTool: \"get_search_discovery_endpoints\",\n expectedSchemaTool: \"moralis_search_entities\",\n expectedProvider: \"Moralis\",\n },\n {\n id: \"liquidity-locks\",\n workflow: \"DEX\",\n prompt: \"show liquidity locks for this token pair\",\n expectedTopToolset: \"onchain_dex_pool_analysis\",\n expectedToolsets: [\"onchain_dex_pool_analysis\", \"security_risk\"],\n expectedCategoryTool: \"get_onchain_dex_pool_endpoints\",\n expectedSchemaTool: \"get_liquidity_locks\",\n expectedProvider: \"Codex\",\n },\n];\n\nfunction getDynamicTool(name: string) {\n const endpoint = dynamicTools(getAllWrappedEndpoints()).find(\n (item) => item.tool.name === name,\n );\n if (!endpoint) {\n throw new Error(`Dynamic tool '${name}' is not registered.`);\n }\n return endpoint;\n}\n\nfunction parseToolText(result: unknown): Record<string, unknown> {\n const text = (result as { content?: Array<{ type?: string; text?: string }> })\n .content?.find((item) => item.type === \"text\")?.text;\n if (!text) throw new Error(\"Tool response did not include text JSON.\");\n return JSON.parse(text) as Record<string, unknown>;\n}\n\nfunction incrementCounter(counter: Record<string, number>, key: string | undefined) {\n if (!key) return;\n counter[key] = (counter[key] ?? 0) + 1;\n}\n\nasync function runWorkflowCase(\n item: WorkflowRegressionCase,\n): Promise<WorkflowRegressionResult> {\n const started = Date.now();\n\n try {\n const searchTool = getDynamicTool(\"search_tools\");\n const categoryTool = getDynamicTool(item.expectedCategoryTool);\n const schemaTool = getDynamicTool(\"get_api_endpoint_schema\");\n\n const searchResult = await searchTool.handler(null, {\n query: item.prompt,\n limit: 20,\n });\n const searchParsed = parseToolText(searchResult) as {\n toolsets?: Array<{ id?: string }>;\n tools?: unknown[];\n pagination?: { total?: number };\n };\n const matchedToolsets =\n searchParsed.toolsets\n ?.map((toolset) => toolset.id)\n .filter((id): id is string => typeof id === \"string\") ?? [];\n const selectedTopToolset = matchedToolsets[0];\n const discoveredToolCount =\n searchParsed.pagination?.total ?? searchParsed.tools?.length ?? 0;\n\n if (selectedTopToolset !== item.expectedTopToolset) {\n throw new Error(\n `Expected top toolset ${item.expectedTopToolset}, received ${selectedTopToolset ?? \"none\"}.`,\n );\n }\n\n for (const expected of item.expectedToolsets) {\n if (!matchedToolsets.includes(expected)) {\n throw new Error(`Missing expected toolset ${expected}.`);\n }\n }\n\n if (discoveredToolCount <= 0 && matchedToolsets.length === 0) {\n throw new Error(\"Discovery returned no tools and no toolsets.\");\n }\n\n const categoryResult = await categoryTool.handler(null, { limit: 5 });\n const categoryParsed = parseToolText(categoryResult) as {\n category?: string;\n tools?: unknown[];\n };\n if (!categoryParsed.category || !categoryParsed.tools?.length) {\n throw new Error(`${item.expectedCategoryTool} returned an empty catalog.`);\n }\n\n const schemaResult = await schemaTool.handler(null, {\n endpoint: item.expectedSchemaTool,\n });\n const schemaParsed = parseToolText(schemaResult) as {\n name?: string;\n provider?: string;\n category?: string;\n inputSchema?: unknown;\n outputSchema?: unknown;\n };\n if (schemaParsed.name !== item.expectedSchemaTool) {\n throw new Error(\n `Schema lookup returned ${schemaParsed.name ?? \"none\"} instead of ${item.expectedSchemaTool}.`,\n );\n }\n if (!schemaParsed.inputSchema) {\n throw new Error(`${item.expectedSchemaTool} schema lookup omitted inputSchema.`);\n }\n if (\n item.expectedProvider &&\n schemaParsed.provider !== item.expectedProvider\n ) {\n throw new Error(\n `Expected provider ${item.expectedProvider}, received ${schemaParsed.provider ?? \"none\"}.`,\n );\n }\n\n return {\n id: item.id,\n workflow: item.workflow,\n prompt: item.prompt,\n status: \"passed\",\n expectedTopToolset: item.expectedTopToolset,\n selectedTopToolset,\n expectedToolsets: item.expectedToolsets,\n matchedToolsets,\n expectedCategoryTool: item.expectedCategoryTool,\n expectedSchemaTool: item.expectedSchemaTool,\n expectedProvider: item.expectedProvider,\n selectedSchemaProvider: schemaParsed.provider,\n selectedSchemaCategory: schemaParsed.category,\n discoveredToolCount,\n duration: Date.now() - started,\n };\n } catch (error) {\n return {\n id: item.id,\n workflow: item.workflow,\n prompt: item.prompt,\n status: \"failed\",\n expectedTopToolset: item.expectedTopToolset,\n expectedToolsets: item.expectedToolsets,\n matchedToolsets: [],\n expectedCategoryTool: item.expectedCategoryTool,\n expectedSchemaTool: item.expectedSchemaTool,\n expectedProvider: item.expectedProvider,\n discoveredToolCount: 0,\n duration: Date.now() - started,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nfunction recordWorkflowSummary(\n summary: WorkflowRegressionSummary,\n): WorkflowRegressionSummary {\n workflowHistory.unshift(summary);\n if (workflowHistory.length > WORKFLOW_HISTORY_LIMIT) {\n workflowHistory.length = WORKFLOW_HISTORY_LIMIT;\n }\n return summary;\n}\n\nexport function getWorkflowRegressionCatalog(): WorkflowRegressionCase[] {\n return WORKFLOW_REGRESSION_CASES;\n}\n\nexport function getWorkflowRegressionHistory(limit = 20): WorkflowRegressionHistory {\n const safeLimit = Math.max(1, Math.min(limit, WORKFLOW_HISTORY_LIMIT));\n const history = workflowHistory.slice(0, safeLimit);\n\n return {\n status: history[0]?.status ?? \"degraded\",\n count: workflowHistory.length,\n maxEntries: WORKFLOW_HISTORY_LIMIT,\n latest: history[0] ?? null,\n history,\n runtimeStatuses: TASK_TOOLSET_RUNTIME_STATUSES,\n timestamp: new Date().toISOString(),\n };\n}\n\nexport async function runWorkflowRegressionCanaries(\n cases: WorkflowRegressionCase[] = WORKFLOW_REGRESSION_CASES,\n): Promise<WorkflowRegressionSummary> {\n const started = Date.now();\n const results: WorkflowRegressionResult[] = [];\n\n for (const item of cases) {\n results.push(await runWorkflowCase(item));\n }\n\n const toolsetCoverage: Record<string, number> = {};\n const providerCoverage: Record<string, number> = {};\n const categoryToolCoverage: Record<string, number> = {};\n\n for (const result of results) {\n incrementCounter(toolsetCoverage, result.expectedTopToolset);\n incrementCounter(providerCoverage, result.expectedProvider);\n incrementCounter(categoryToolCoverage, result.expectedCategoryTool);\n }\n\n const status = aggregateRuntimeStatus(\n results.map((result) => (result.status === \"passed\" ? \"ok\" : \"failing\")),\n );\n\n return recordWorkflowSummary({\n status,\n total: results.length,\n passed: results.filter((result) => result.status === \"passed\").length,\n failed: results.filter((result) => result.status === \"failed\").length,\n duration: Date.now() - started,\n results,\n toolsetCoverage,\n providerCoverage,\n categoryToolCoverage,\n runtimeStatuses: TASK_TOOLSET_RUNTIME_STATUSES,\n timestamp: new Date().toISOString(),\n });\n}\n","import { CorsOptions } from \"cors\";\nimport { getCorsAllowedOrigins, isProduction } from \"./env.js\";\n\nexport const getCorsConfig = (): CorsOptions => {\n const allowedOrigins = getCorsAllowedOrigins();\n\n const origin =\n allowedOrigins.length > 0\n ? allowedOrigins\n : isProduction()\n ? []\n : [\"http://localhost:8080\"];\n\n return {\n origin,\n methods: [\"GET\", \"POST\", \"DELETE\", \"OPTIONS\"],\n allowedHeaders: [\n \"Content-Type\",\n \"Authorization\",\n \"x-api-key\",\n \"x-request-id\",\n ],\n exposedHeaders: [\n \"x-request-id\",\n \"RateLimit-Limit\",\n \"RateLimit-Remaining\",\n \"RateLimit-Reset\",\n \"Retry-After\",\n \"X-Quota-Remaining\",\n \"X-RateLimit-Remaining\",\n \"X-RateLimit-Limit\",\n ],\n maxAge: 86400,\n credentials: false,\n };\n};\n","import type { Request, Response, NextFunction } from \"express\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { secureLogger } from \"../utils/secureLogger.js\";\nimport { apiError } from \"../utils/api-errors.js\";\nimport {\n isUnkeyConfigured,\n isUnkeyRequired,\n verifyApiKey,\n type VerifyKeyResult,\n} from \"../services/unkey-service.js\";\nimport { consumeCredits } from \"../services/wallet-service.js\";\nimport { getCsvEnv, getEnvVar, isProduction } from \"../config/env.js\";\n\n// Per-request credit cost. Kept at 1 globally — every API call debits one\n// credit regardless of which tool is invoked. Variable cost per tool was\n// considered and intentionally left out: the simpler model is easier for\n// users to reason about and avoids surprising bills.\nconst REQUEST_COST = 1;\n\nexport interface AuthenticatedRequest extends Request {\n apiKey?: string;\n apiKeyEnvironment?: string;\n // Unkey-enriched fields (populated when Unkey is configured)\n userId?: string;\n planId?: string;\n unkeyKeyId?: string;\n quotaRemaining?: number;\n ratelimitRemaining?: number;\n unkeyResult?: VerifyKeyResult;\n}\n\n// Pre-computed set for O(1) key lookups; rebuilds when env changes\nlet _cachedKeySet: Set<string> | null = null;\nlet _cachedKeySource = \"\";\nfunction getValidKeySet(): Set<string> {\n const raw = getEnvVar(\"HIVE_API_KEYS\") || \"\";\n if (_cachedKeySet && _cachedKeySource === raw) return _cachedKeySet;\n _cachedKeySet = new Set(getCsvEnv(\"HIVE_API_KEYS\"));\n _cachedKeySource = raw;\n return _cachedKeySet;\n}\n\nfunction getKeyEnvironment(key: string): string {\n if (key.startsWith(\"hive_live_\")) return \"live\";\n if (key.startsWith(\"hive_test_\")) return \"test\";\n if (key.startsWith(\"hive_dev_\")) return \"dev\";\n return \"legacy\";\n}\n\n// Track which legacy keys have already triggered a deprecation warning (hashed, capped)\nconst warnedLegacyKeys = new Set<string>();\nconst MAX_WARNED_KEYS = 1_000;\n\nfunction hashKeyForTracking(key: string): string {\n return createHash(\"sha256\").update(key).digest(\"hex\").slice(0, 16);\n}\n\nfunction getRestAnalyticsTags(req: Request): string[] {\n const tags = [\n \"service=hive\",\n \"transport=rest\",\n `method=${req.method.toUpperCase()}`,\n `route=${req.originalUrl.split(\"?\")[0]}`,\n ];\n\n const body = req.body as { tool?: unknown } | undefined;\n if (typeof body?.tool === \"string\") {\n tags.push(`endpoint=${body.tool}`);\n }\n\n return tags;\n}\n\n/**\n * Validates API key from x-api-key header or Authorization: Bearer <key>.\n *\n * Uses Unkey when configured, otherwise falls back to static HIVE_API_KEYS.\n * When neither backend is configured, rejects with AUTH_NOT_CONFIGURED.\n */\n// Warn once at startup if API keys are not configured in production\nif (isProduction() && !getEnvVar(\"HIVE_API_KEYS\")) {\n secureLogger.warn(\n \"HIVE_API_KEYS not set in production — protected routes will be unavailable unless Unkey is configured\",\n {},\n );\n}\n\nexport function requireApiKey(\n req: Request,\n res: Response,\n next: NextFunction,\n): void {\n const key =\n (req.headers[\"x-api-key\"] as string) ??\n (req.headers.authorization?.startsWith(\"Bearer \")\n ? req.headers.authorization.slice(7)\n : undefined);\n\n if (isUnkeyRequired() && !isUnkeyConfigured()) {\n secureLogger.warn(\n \"HIVE_AUTH_BACKEND=unkey but UNKEY_ROOT_KEY or UNKEY_API_ID is missing. Rejecting request.\",\n { ip: req.ip },\n );\n res\n .status(503)\n .json(\n apiError(\n \"internal_error\",\n \"AUTH_NOT_CONFIGURED\",\n \"Unkey authentication is selected but not configured. Set UNKEY_ROOT_KEY and UNKEY_API_ID, or set HIVE_AUTH_BACKEND=static with HIVE_API_KEYS.\",\n { requestId: req.requestId },\n ),\n );\n return;\n }\n\n // If Unkey is configured, use it for verification\n if (isUnkeyConfigured()) {\n if (!key) {\n res\n .status(401)\n .json(\n apiError(\n \"authentication_error\",\n \"AUTH_REQUIRED\",\n \"API key required. Set x-api-key header or Authorization: Bearer <key>.\",\n { requestId: req.requestId },\n ),\n );\n return;\n }\n\n verifyApiKey(key, getRestAnalyticsTags(req))\n .then(async (result) => {\n if (!result.valid) {\n const statusCode = result.code === \"RATE_LIMITED\" ? 429 : 403;\n const errorCode =\n result.code === \"RATE_LIMITED\"\n ? \"RATE_LIMITED\"\n : \"INVALID_API_KEY\";\n const message =\n result.code === \"RATE_LIMITED\"\n ? \"Rate limit exceeded.\"\n : \"Invalid API key.\";\n\n if (result.code === \"RATE_LIMITED\") {\n res.setHeader(\"Retry-After\", \"60\");\n }\n\n secureLogger.authEvent(\"api-key-rejected\", false, {\n ip: req.ip,\n code: result.code,\n });\n res.status(statusCode).json(\n apiError(\"authentication_error\", errorCode, message, {\n requestId: req.requestId,\n }),\n );\n return;\n }\n\n // Credit consumption — wallet-level enforcement. The request is\n // already authenticated by Unkey; we now check whether the user\n // (not the key) still has credits this cycle. Idempotency key uses\n // the request id so retries with the same id don't double-debit.\n if (!result.userId) {\n // Unkey returned valid but no externalId — likely a malformed key\n // record. Reject hard rather than silently letting it through.\n res.status(403).json(\n apiError(\"authentication_error\", \"INVALID_API_KEY\", \"Invalid API key.\", {\n requestId: req.requestId,\n }),\n );\n return;\n }\n\n const idem = req.requestId ?? randomUUID();\n try {\n const consumeResult = await consumeCredits({\n userId: result.userId,\n cost: REQUEST_COST,\n idempotencyKey: idem,\n requestId: req.requestId,\n keyId: result.keyId,\n });\n\n if (consumeResult.code === \"insufficient\") {\n res.setHeader(\n \"X-Quota-Remaining\",\n String(consumeResult.balance ?? 0),\n );\n res.status(429).json(\n apiError(\n \"rate_limit_error\",\n \"QUOTA_EXCEEDED\",\n \"Monthly credit quota exhausted. Upgrade your plan or wait for the next cycle.\",\n { requestId: req.requestId },\n ),\n );\n return;\n }\n\n if (consumeResult.code === \"no_wallet\") {\n // Should never happen — wallets are created on signup and lazily\n // ensured on first key creation. Treat as an auth misconfig.\n secureLogger.warn(\n \"consume_credits returned no_wallet for valid Unkey key\",\n { userId: result.userId, keyId: result.keyId },\n );\n res.status(403).json(\n apiError(\n \"authentication_error\",\n \"INVALID_API_KEY\",\n \"Invalid API key.\",\n { requestId: req.requestId },\n ),\n );\n return;\n }\n\n // Attach context for downstream handlers\n const authReq = req as AuthenticatedRequest;\n authReq.apiKey = key;\n authReq.apiKeyEnvironment = getKeyEnvironment(key);\n authReq.userId = result.userId;\n authReq.planId = result.planId;\n authReq.unkeyKeyId = result.keyId;\n authReq.quotaRemaining = consumeResult.balance ?? undefined;\n authReq.ratelimitRemaining = result.ratelimit?.remaining;\n authReq.unkeyResult = result;\n\n if (consumeResult.balance !== null) {\n res.setHeader(\"X-Quota-Remaining\", String(consumeResult.balance));\n } else {\n res.setHeader(\"X-Quota-Remaining\", \"unlimited\");\n }\n if (result.ratelimit) {\n res.setHeader(\n \"X-RateLimit-Remaining\",\n String(result.ratelimit.remaining),\n );\n res.setHeader(\"X-RateLimit-Limit\", String(result.ratelimit.limit));\n }\n\n next();\n } catch (err) {\n secureLogger.error(\"consume_credits threw — rejecting request\", err, {\n userId: result.userId,\n });\n res.status(503).json(\n apiError(\n \"internal_error\",\n \"QUOTA_SERVICE_UNAVAILABLE\",\n \"Quota service temporarily unavailable. Please retry.\",\n { requestId: req.requestId },\n ),\n );\n }\n })\n .catch((err) => {\n secureLogger.error(\n \"Unkey verification failed — rejecting request\",\n err,\n {\n ip: req.ip,\n },\n );\n res\n .status(503)\n .json(\n apiError(\n \"internal_error\",\n \"AUTH_SERVICE_UNAVAILABLE\",\n \"Authentication service temporarily unavailable. Please retry.\",\n { requestId: req.requestId },\n ),\n );\n });\n return;\n }\n\n // Fallback: static HIVE_API_KEYS validation (backward compat)\n const validKeys = getValidKeySet();\n\n if (validKeys.size === 0) {\n secureLogger.warn(\n \"No API key backend configured (HIVE_API_KEYS / Unkey). Rejecting request.\",\n { ip: req.ip },\n );\n res\n .status(503)\n .json(\n apiError(\n \"internal_error\",\n \"AUTH_NOT_CONFIGURED\",\n \"API key authentication is not configured. Set HIVE_API_KEYS or configure Unkey.\",\n { requestId: req.requestId },\n ),\n );\n return;\n }\n\n if (!key) {\n res\n .status(401)\n .json(\n apiError(\n \"authentication_error\",\n \"AUTH_REQUIRED\",\n \"API key required. Set x-api-key header or Authorization: Bearer <key>.\",\n { requestId: req.requestId },\n ),\n );\n return;\n }\n\n if (!validKeys.has(key)) {\n secureLogger.authEvent(\"api-key-rejected\", false, { ip: req.ip });\n res.status(403).json(\n apiError(\"authentication_error\", \"INVALID_API_KEY\", \"Invalid API key.\", {\n requestId: req.requestId,\n }),\n );\n return;\n }\n\n const env = getKeyEnvironment(key);\n\n if (env === \"legacy\") {\n const keyHash = hashKeyForTracking(key);\n if (!warnedLegacyKeys.has(keyHash)) {\n if (warnedLegacyKeys.size >= MAX_WARNED_KEYS) warnedLegacyKeys.clear();\n warnedLegacyKeys.add(keyHash);\n secureLogger.warn(\n \"Unprefixed (legacy) API key used — migrate to hive_live_* or hive_test_* prefix\",\n { ip: req.ip },\n );\n }\n res.setHeader(\n \"X-API-Key-Deprecation\",\n \"Unprefixed API keys are deprecated. Use hive_live_* or hive_test_* prefixed keys.\",\n );\n }\n\n (req as AuthenticatedRequest).apiKey = key;\n (req as AuthenticatedRequest).apiKeyEnvironment = env;\n next();\n}\n","import { getSupabaseAdmin } from \"../db/supabase.js\";\nimport { secureLogger } from \"../utils/secureLogger.js\";\n\n// All credit accounting goes through this service. Unkey only verifies the\n// key + enforces per-key rate limiting; the *credit balance* lives in\n// public.credit_wallets and is mutated atomically by consume_credits().\n\nexport type ConsumeCode = \"ok\" | \"insufficient\" | \"unlimited\" | \"no_wallet\";\n\nexport interface ConsumeResult {\n code: ConsumeCode;\n balance: number | null;\n monthlyGrant: number;\n cycleEnd: string | null;\n}\n\nexport interface WalletStatus {\n planId: string;\n balance: number | null;\n monthlyGrant: number;\n cycleStart: string;\n cycleEnd: string;\n updatedAt: string;\n}\n\nexport async function consumeCredits(args: {\n userId: string;\n cost: number;\n idempotencyKey: string;\n requestId?: string;\n keyId?: string;\n}): Promise<ConsumeResult> {\n const { userId, cost, idempotencyKey, requestId, keyId } = args;\n\n const { data, error } = await getSupabaseAdmin().rpc(\"consume_credits\", {\n p_user_id: userId,\n p_cost: cost,\n p_idempotency_key: idempotencyKey,\n p_request_id: requestId ?? null,\n p_key_id: keyId ?? null,\n });\n\n if (error) {\n secureLogger.error(\"consume_credits RPC failed\", error, { userId });\n throw new Error(`consume_credits failed: ${error.message}`);\n }\n\n const row = Array.isArray(data) ? data[0] : data;\n if (!row) {\n throw new Error(\"consume_credits returned no row\");\n }\n\n return {\n code: row.code as ConsumeCode,\n balance: row.balance ?? null,\n monthlyGrant: row.monthly_grant ?? 0,\n cycleEnd: row.cycle_end ?? null,\n };\n}\n\nexport async function ensureWallet(\n userId: string,\n planId: string,\n): Promise<void> {\n const { error } = await getSupabaseAdmin().rpc(\"ensure_wallet\", {\n p_user_id: userId,\n p_plan_id: planId,\n });\n if (error) {\n secureLogger.error(\"ensure_wallet RPC failed\", error, { userId });\n throw new Error(`ensure_wallet failed: ${error.message}`);\n }\n}\n\nexport async function getWalletStatus(\n userId: string,\n): Promise<WalletStatus | null> {\n const { data, error } = await getSupabaseAdmin()\n .from(\"credit_wallets\")\n .select(\"plan_id, balance, monthly_grant, cycle_start, cycle_end, updated_at\")\n .eq(\"user_id\", userId)\n .single();\n\n if (error || !data) {\n secureLogger.warn(\"getWalletStatus returned no row\", {\n userId,\n hasError: !!error,\n errorCode: error?.code,\n errorMessage: error?.message,\n });\n return null;\n }\n\n return {\n planId: data.plan_id,\n balance: data.balance ?? null,\n monthlyGrant: data.monthly_grant,\n cycleStart: data.cycle_start,\n cycleEnd: data.cycle_end,\n updatedAt: data.updated_at,\n };\n}\n\n// Called from the Stripe / crypto-billing webhook (when those land) and from\n// admin tooling. Updates the wallet's plan_id + monthly_grant immediately\n// and tops up the balance to the new grant if it's higher (upgrades feel\n// instant; downgrades take effect at the next cycle).\nexport async function applyPlanChange(args: {\n userId: string;\n newPlanId: string;\n monthlyCredits: number;\n reason: string;\n idempotencyKey: string;\n}): Promise<void> {\n const { userId, newPlanId, monthlyCredits, reason, idempotencyKey } = args;\n const supabase = getSupabaseAdmin();\n\n const { data: wallet } = await supabase\n .from(\"credit_wallets\")\n .select(\"balance, monthly_grant\")\n .eq(\"user_id\", userId)\n .single();\n\n const newBalance =\n monthlyCredits < 0\n ? null\n : Math.max(wallet?.balance ?? 0, monthlyCredits);\n\n const { error } = await supabase\n .from(\"credit_wallets\")\n .update({\n plan_id: newPlanId,\n balance: newBalance,\n monthly_grant: Math.max(monthlyCredits, 0),\n })\n .eq(\"user_id\", userId);\n\n if (error) {\n throw new Error(`applyPlanChange failed: ${error.message}`);\n }\n\n await supabase.from(\"credit_ledger\").insert({\n user_id: userId,\n delta:\n newBalance === null\n ? 0\n : (newBalance ?? 0) - (wallet?.balance ?? 0),\n reason: \"plan_change\",\n idempotency_key: idempotencyKey,\n balance_before: wallet?.balance ?? null,\n balance_after: newBalance,\n metadata: { new_plan_id: newPlanId, source: reason },\n });\n}\n","import { Router, type Request, type Response } from \"express\";\nimport rateLimit from \"express-rate-limit\";\nimport RedisStore, { type SendCommandFn } from \"rate-limit-redis\";\nimport { z } from \"zod\";\nimport {\n isSupabaseConfigured,\n getSupabaseAdmin,\n getSupabaseAuthClient,\n} from \"../db/supabase.js\";\nimport {\n requireSupabaseAuth,\n type SupabaseAuthRequest,\n} from \"../middleware/supabase-auth.js\";\nimport { createApiKey } from \"../services/unkey-service.js\";\nimport { ensureWallet } from \"../services/wallet-service.js\";\nimport { apiError } from \"../utils/api-errors.js\";\nimport { asyncHandler } from \"../utils/asyncHandler.js\";\nimport { getRedisClient } from \"../utils/redis.js\";\n\nconst router = Router();\n\n// Auth-specific rate limit. Lower than the general API limit because signup\n// /login are the abuse vectors that gate every other surface.\n// * 10/hour/IP for signup\n// * 30/hour/IP for login (legit users mistype)\nfunction buildAuthRateLimiter(maxPerHour: number, prefix: string) {\n const redisClient = getRedisClient();\n const storeConfig =\n redisClient\n ? {\n store: new RedisStore({\n sendCommand: ((...args: string[]) =>\n redisClient.call(\n args[0],\n ...args.slice(1),\n ) as ReturnType<SendCommandFn>) satisfies SendCommandFn,\n prefix,\n }),\n }\n : {};\n\n return rateLimit({\n ...storeConfig,\n windowMs: 60 * 60 * 1000,\n max: maxPerHour,\n standardHeaders: true,\n legacyHeaders: false,\n keyGenerator: (req) => req.ip || req.socket?.remoteAddress || \"anon\",\n handler: (_req, res) => {\n res.setHeader(\"Retry-After\", \"3600\");\n res\n .status(429)\n .json(\n apiError(\n \"rate_limit_error\",\n \"RATE_LIMITED\",\n \"Too many auth attempts. Try again in an hour.\",\n ),\n );\n },\n });\n}\n\nconst signupRateLimit = buildAuthRateLimiter(10, \"rl:auth:signup:\");\nconst loginRateLimit = buildAuthRateLimiter(30, \"rl:auth:login:\");\n\nconst AuthSchema = z.object({\n email: z.string().email(\"Invalid email format\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n});\n\nrouter.post(\n \"/signup\",\n signupRateLimit,\n asyncHandler(async (req: Request, res: Response) => {\n if (!isSupabaseConfigured()) {\n return res\n .status(503)\n .json(\n apiError(\n \"internal_error\",\n \"AUTH_NOT_CONFIGURED\",\n \"Auth not configured.\",\n ),\n );\n }\n\n const parseResult = AuthSchema.safeParse(req.body);\n if (!parseResult.success) {\n return res\n .status(400)\n .json(\n apiError(\n \"invalid_request_error\",\n \"VALIDATION_ERROR\",\n parseResult.error.issues.map((e) => e.message).join(\"; \"),\n ),\n );\n }\n const { email, password } = parseResult.data;\n\n const supabase = getSupabaseAdmin();\n const { data, error } = await supabase.auth.admin.createUser({\n email,\n password,\n email_confirm: true,\n });\n\n if (error) {\n return res\n .status(400)\n .json(\n apiError(\n \"authentication_error\",\n \"SIGNUP_FAILED\",\n \"Signup failed. Please try again or use a different email.\",\n ),\n );\n }\n\n // Belt-and-braces: handle_new_user trigger should already have provisioned\n // the wallet, but ensureWallet is idempotent and protects against trigger\n // misconfigurations rather than silently creating an unbounded account.\n try {\n await ensureWallet(data.user.id, \"demo\");\n } catch {\n // Wallet ensure is best-effort here; first authenticated request will\n // also call it.\n }\n\n // Auto-generate first API key for the new user\n let firstKey: { keyId: string; key: string } | null = null;\n try {\n firstKey = await createApiKey({\n userId: data.user.id,\n name: \"Default\",\n planId: \"demo\",\n });\n } catch {\n // Key creation failed but user was created — they can create keys later\n }\n\n // Sign in to get a session token\n const { data: session } =\n await getSupabaseAuthClient().auth.signInWithPassword({\n email,\n password,\n });\n\n return res.status(201).json({\n ok: true,\n user: { id: data.user.id, email: data.user.email },\n session: session.session\n ? {\n access_token: session.session.access_token,\n refresh_token: session.session.refresh_token,\n expires_at: session.session.expires_at,\n }\n : null,\n api_key: firstKey\n ? {\n key_id: firstKey.keyId,\n key: firstKey.key,\n warning: \"Save this key — it will not be shown again.\",\n }\n : null,\n });\n }),\n);\n\nrouter.post(\n \"/login\",\n loginRateLimit,\n asyncHandler(async (req: Request, res: Response) => {\n if (!isSupabaseConfigured()) {\n return res\n .status(503)\n .json(\n apiError(\n \"internal_error\",\n \"AUTH_NOT_CONFIGURED\",\n \"Auth not configured.\",\n ),\n );\n }\n\n const parseResult = AuthSchema.safeParse(req.body);\n if (!parseResult.success) {\n return res\n .status(400)\n .json(\n apiError(\n \"invalid_request_error\",\n \"VALIDATION_ERROR\",\n parseResult.error.issues.map((e) => e.message).join(\"; \"),\n ),\n );\n }\n const { email, password } = parseResult.data;\n\n const { data, error } =\n await getSupabaseAuthClient().auth.signInWithPassword({\n email,\n password,\n });\n\n if (error || !data.session) {\n return res\n .status(401)\n .json(\n apiError(\n \"authentication_error\",\n \"LOGIN_FAILED\",\n error?.message ?? \"Invalid credentials.\",\n ),\n );\n }\n\n return res.json({\n ok: true,\n user: { id: data.user.id, email: data.user.email },\n session: {\n access_token: data.session.access_token,\n refresh_token: data.session.refresh_token,\n expires_at: data.session.expires_at,\n },\n });\n }),\n);\n\nrouter.get(\n \"/me\",\n requireSupabaseAuth,\n asyncHandler(async (req: Request, res: Response) => {\n const user = (req as SupabaseAuthRequest).supabaseUser!;\n\n const { data: profile } = await getSupabaseAdmin()\n .from(\"user_profiles\")\n .select(\"*, plans(*)\")\n .eq(\"id\", user.id)\n .single();\n\n return res.json({\n ok: true,\n user: { id: user.id, email: user.email },\n profile: profile ?? { plan_id: \"demo\" },\n });\n }),\n);\n\nexport default router;\n","import type { Request, Response, NextFunction } from \"express\";\nimport { isSupabaseConfigured, getSupabaseAdmin } from \"../db/supabase.js\";\nimport { apiError } from \"../utils/api-errors.js\";\n\nexport interface SupabaseAuthRequest extends Request {\n supabaseUser?: { id: string; email: string };\n}\n\n/**\n * Validates Supabase JWT from Authorization: Bearer <jwt>.\n * Used for account management routes (key creation, usage queries).\n * NOT used for data API calls — those use API keys via Unkey.\n */\nexport function requireSupabaseAuth(\n req: Request,\n res: Response,\n next: NextFunction,\n): void {\n if (!isSupabaseConfigured()) {\n res\n .status(503)\n .json(\n apiError(\n \"internal_error\",\n \"AUTH_NOT_CONFIGURED\",\n \"Authentication service not configured.\",\n ),\n );\n return;\n }\n\n const authHeader = req.headers.authorization;\n if (!authHeader?.startsWith(\"Bearer \")) {\n res\n .status(401)\n .json(\n apiError(\n \"authentication_error\",\n \"AUTH_REQUIRED\",\n \"Bearer token required. Use /auth/login to get a token.\",\n ),\n );\n return;\n }\n\n const token = authHeader.slice(7);\n\n getSupabaseAdmin()\n .auth.getUser(token)\n .then(({ data, error }) => {\n if (error || !data.user) {\n res\n .status(401)\n .json(\n apiError(\n \"authentication_error\",\n \"INVALID_TOKEN\",\n \"Invalid or expired token.\",\n ),\n );\n return;\n }\n\n (req as SupabaseAuthRequest).supabaseUser = {\n id: data.user.id,\n email: data.user.email ?? \"\",\n };\n next();\n })\n .catch(() => {\n res\n .status(500)\n .json(\n apiError(\n \"internal_error\",\n \"AUTH_ERROR\",\n \"Authentication verification failed.\",\n ),\n );\n });\n}\n","import type { Request, Response, NextFunction } from \"express\";\n\n/**\n * Wraps an async Express route handler so rejected promises\n * are forwarded to the Express error-handling middleware\n * instead of becoming unhandled rejections.\n */\nexport const asyncHandler =\n (fn: (req: Request, res: Response, next: NextFunction) => Promise<unknown>) =>\n (req: Request, res: Response, next: NextFunction): void => {\n Promise.resolve(fn(req, res, next)).catch(next);\n };\n","import { Router, type Request, type Response } from \"express\";\nimport { z } from \"zod\";\nimport {\n requireSupabaseAuth,\n type SupabaseAuthRequest,\n} from \"../middleware/supabase-auth.js\";\nimport {\n createApiKey,\n listKeys,\n revokeKey,\n} from \"../services/unkey-service.js\";\nimport { ensureWallet } from \"../services/wallet-service.js\";\nimport { getSupabaseAdmin } from \"../db/supabase.js\";\nimport { apiError } from \"../utils/api-errors.js\";\nimport { asyncHandler } from \"../utils/asyncHandler.js\";\nimport { idempotencyMiddleware } from \"../middleware/idempotency.js\";\n\nconst router = Router();\n\nconst CreateKeySchema = z.object({\n name: z.string().min(1).max(100).optional(),\n});\n\nrouter.post(\n \"/\",\n requireSupabaseAuth,\n idempotencyMiddleware(),\n asyncHandler(async (req: Request, res: Response) => {\n const user = (req as SupabaseAuthRequest).supabaseUser!;\n\n const parseResult = CreateKeySchema.safeParse(req.body);\n if (!parseResult.success) {\n return res\n .status(400)\n .json(\n apiError(\n \"invalid_request_error\",\n \"VALIDATION_ERROR\",\n parseResult.error.issues.map((e) => e.message).join(\"; \"),\n ),\n );\n }\n const { name } = parseResult.data;\n\n const { data: profile } = await getSupabaseAdmin()\n .from(\"user_profiles\")\n .select(\"plan_id\")\n .eq(\"id\", user.id)\n .single();\n\n const planId = profile?.plan_id ?? \"demo\";\n\n // Lazily provision a wallet for legacy users who pre-date the wallet\n // migration. New signups get one via the handle_new_user trigger.\n await ensureWallet(user.id, planId);\n\n try {\n const result = await createApiKey({\n userId: user.id,\n name: name ?? \"Default\",\n planId,\n });\n\n return res.status(201).json({\n ok: true,\n data: {\n key_id: result.keyId,\n key: result.key,\n name: name ?? \"Default\",\n plan: planId,\n warning: \"Save this key — it will not be shown again.\",\n },\n });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Key creation failed\";\n return res\n .status(400)\n .json(apiError(\"invalid_request_error\", \"KEY_CREATE_FAILED\", message));\n }\n }),\n);\n\nrouter.get(\n \"/\",\n requireSupabaseAuth,\n asyncHandler(async (req: Request, res: Response) => {\n const user = (req as SupabaseAuthRequest).supabaseUser!;\n\n try {\n const keys = await listKeys(user.id);\n return res.json({\n ok: true,\n data: keys,\n meta: { total: keys.length },\n });\n } catch {\n return res\n .status(500)\n .json(\n apiError(\n \"internal_error\",\n \"LIST_KEYS_FAILED\",\n \"Failed to list keys.\",\n ),\n );\n }\n }),\n);\n\nrouter.delete(\n \"/:id\",\n requireSupabaseAuth,\n asyncHandler(async (req: Request, res: Response) => {\n const user = (req as SupabaseAuthRequest).supabaseUser!;\n const keyId = req.params.id;\n\n const keys = await listKeys(user.id);\n const ownsKey = keys.some((k) => k.keyId === keyId);\n\n if (!ownsKey) {\n return res\n .status(404)\n .json(\n apiError(\n \"not_found_error\",\n \"KEY_NOT_FOUND\",\n \"Key not found or not owned by you.\",\n ),\n );\n }\n\n try {\n // revokeKey now disables the key rather than hard-deleting it. The\n // user's credit balance is preserved on the wallet — disabling a key\n // does not refund or reset credits.\n await revokeKey(keyId);\n return res.json({\n ok: true,\n message: \"Key disabled. Your monthly credits stay on your account.\",\n });\n } catch {\n return res\n .status(500)\n .json(\n apiError(\"internal_error\", \"REVOKE_FAILED\", \"Failed to revoke key.\"),\n );\n }\n }),\n);\n\nexport default router;\n","import type { Request, Response, NextFunction } from \"express\";\nimport { createHash } from \"node:crypto\";\nimport { getRedisClient, isRedisAvailable } from \"../utils/redis.js\";\nimport { secureLogger } from \"../utils/secureLogger.js\";\n\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\nconst CACHE_TTL_SECONDS = 86_400; // 24 hours — used for Redis SETEX\nconst MAX_CACHE_SIZE = 1_000;\nconst MAX_KEY_LENGTH = 128;\nconst KEY_PATTERN = /^[a-zA-Z0-9_\\-:.]+$/;\nconst REDIS_PREFIX = \"idem:\";\n\ninterface CachedResponse {\n status: number;\n body: unknown;\n createdAt: number;\n}\n\n// In-memory cache — always populated alongside Redis so local-instance\n// lookups stay fast. Acts as sole store when Redis is unavailable.\nconst memoryCache = new Map<string, \"pending\" | CachedResponse>();\n\nlet cleanupStarted = false;\nfunction ensureCleanup() {\n if (cleanupStarted) return;\n cleanupStarted = true;\n setInterval(() => {\n const now = Date.now();\n for (const [key, entry] of memoryCache) {\n if (entry === \"pending\") continue;\n if (now - entry.createdAt > CACHE_TTL_MS) memoryCache.delete(key);\n }\n }, 60_000).unref();\n}\n\nfunction namespaceCredential(kind: \"api-key\" | \"bearer\", value: string): string {\n return `${kind}:${createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 32)}`;\n}\n\nfunction extractAuthNamespace(req: Request): string {\n const header = req.headers[\"x-api-key\"] as string | undefined;\n if (header) return namespaceCredential(\"api-key\", header);\n const auth = req.headers.authorization;\n if (auth?.startsWith(\"Bearer \")) {\n return namespaceCredential(\"bearer\", auth.slice(7));\n }\n return \"anon\";\n}\n\nfunction redactOneTimeSecrets(body: unknown): unknown {\n if (!body || typeof body !== \"object\") return body;\n\n const clone = JSON.parse(JSON.stringify(body)) as Record<string, unknown>;\n const redact = (target: unknown, field: string) => {\n if (target && typeof target === \"object\" && field in target) {\n (target as Record<string, unknown>)[field] = \"[redacted-on-replay]\";\n }\n };\n\n if (clone.data && typeof clone.data === \"object\") {\n redact(clone.data, \"key\");\n }\n if (clone.api_key && typeof clone.api_key === \"object\") {\n redact(clone.api_key, \"key\");\n }\n if (clone.session && typeof clone.session === \"object\") {\n redact(clone.session, \"access_token\");\n redact(clone.session, \"refresh_token\");\n }\n\n return clone;\n}\n\n// ---------------------------------------------------------------------------\n// Redis helpers — every call is wrapped so a Redis failure transparently\n// falls back to the in-memory Map without affecting the request.\n// ---------------------------------------------------------------------------\n\nasync function redisGet(\n key: string,\n): Promise<\"pending\" | CachedResponse | null> {\n const redis = getRedisClient();\n if (!redis || !isRedisAvailable()) return null;\n try {\n const raw = await redis.get(`${REDIS_PREFIX}${key}`);\n if (!raw) return null;\n const parsed: unknown = JSON.parse(raw);\n if (parsed === \"pending\") return \"pending\";\n return parsed as CachedResponse;\n } catch (err) {\n secureLogger.warn(\"[idempotency] Redis GET failed, using memory fallback\", {\n error: String(err),\n });\n return null;\n }\n}\n\nasync function redisSetPending(key: string): Promise<boolean> {\n const redis = getRedisClient();\n if (!redis || !isRedisAvailable()) return false;\n try {\n // NX ensures we only set if key doesn't exist — atomic pending lock\n const result = await redis.set(\n `${REDIS_PREFIX}${key}`,\n JSON.stringify(\"pending\"),\n \"EX\",\n CACHE_TTL_SECONDS,\n \"NX\",\n );\n return result === \"OK\";\n } catch (err) {\n secureLogger.warn(\"[idempotency] Redis SET pending failed\", {\n error: String(err),\n });\n return false;\n }\n}\n\nasync function redisSetResponse(\n key: string,\n entry: CachedResponse,\n): Promise<void> {\n const redis = getRedisClient();\n if (!redis || !isRedisAvailable()) return;\n try {\n await redis.set(\n `${REDIS_PREFIX}${key}`,\n JSON.stringify(entry),\n \"EX\",\n CACHE_TTL_SECONDS,\n );\n } catch (err) {\n secureLogger.warn(\"[idempotency] Redis SET response failed\", {\n error: String(err),\n });\n }\n}\n\nasync function redisDel(key: string): Promise<void> {\n const redis = getRedisClient();\n if (!redis || !isRedisAvailable()) return;\n try {\n await redis.del(`${REDIS_PREFIX}${key}`);\n } catch (err) {\n secureLogger.warn(\"[idempotency] Redis DEL failed\", {\n error: String(err),\n });\n }\n}\n\nfunction replyConflict(res: Response): void {\n res.status(409).json({\n ok: false,\n error: {\n type: \"invalid_request_error\",\n code: \"IDEMPOTENCY_CONFLICT\",\n message:\n \"A request with this Idempotency-Key is already in progress. Retry after it completes.\",\n },\n });\n}\n\nfunction replayResponse(res: Response, cached: CachedResponse): void {\n res.setHeader(\"Idempotent-Replayed\", \"true\");\n res.status(cached.status).json(cached.body);\n}\n\n// ---------------------------------------------------------------------------\n// Core logic used by both sync and async paths\n// ---------------------------------------------------------------------------\n\nfunction markPendingAndProceed(\n key: string,\n res: Response,\n next: NextFunction,\n): void {\n ensureCleanup();\n memoryCache.set(key, \"pending\");\n\n // Evict oldest if at capacity\n if (memoryCache.size > MAX_CACHE_SIZE) {\n for (const [k, v] of memoryCache) {\n if (v !== \"pending\") {\n memoryCache.delete(k);\n break;\n }\n }\n }\n\n // Intercept res.json to capture the response\n const originalJson = res.json.bind(res);\n res.json = (body: unknown) => {\n const entry: CachedResponse = {\n status: res.statusCode,\n body: redactOneTimeSecrets(body),\n createdAt: Date.now(),\n };\n memoryCache.set(key, entry);\n // Fire-and-forget Redis write — don't block the response\n redisSetResponse(key, entry);\n return originalJson(body);\n };\n\n // Clean up pending state if response closes without json() being called\n res.on(\"close\", () => {\n if (memoryCache.get(key) === \"pending\") {\n memoryCache.delete(key);\n redisDel(key);\n }\n });\n\n next();\n}\n\n// ---------------------------------------------------------------------------\n// Middleware\n// ---------------------------------------------------------------------------\n\nexport function idempotencyMiddleware() {\n return (req: Request, res: Response, next: NextFunction): void => {\n if (req.method !== \"POST\") return next();\n\n const rawKey = req.headers[\"idempotency-key\"] as string | undefined;\n if (!rawKey) return next();\n\n // Validate key format\n if (rawKey.length > MAX_KEY_LENGTH || !KEY_PATTERN.test(rawKey)) {\n res.status(400).json({\n ok: false,\n error: {\n type: \"invalid_request_error\",\n code: \"INVALID_IDEMPOTENCY_KEY\",\n message: `Idempotency-Key must be 1-${MAX_KEY_LENGTH} alphanumeric/dash/underscore characters.`,\n },\n });\n return;\n }\n\n // Namespace by a hash of the full credential to prevent cross-user replay\n // without storing API keys or JWTs in Redis/memory keys.\n const key = `${extractAuthNamespace(req)}:${rawKey}`;\n\n // --- Fast path: check in-memory cache synchronously ---\n const memoryCached = memoryCache.get(key);\n\n if (memoryCached === \"pending\") {\n replyConflict(res);\n return;\n }\n\n if (memoryCached && Date.now() - memoryCached.createdAt < CACHE_TTL_MS) {\n replayResponse(res, memoryCached);\n return;\n }\n\n // --- If Redis is available, check it for cross-instance deduplication ---\n if (isRedisAvailable()) {\n handleRedisLookup(key, res, next);\n return;\n }\n\n // --- No Redis: proceed with memory-only path (synchronous) ---\n markPendingAndProceed(key, res, next);\n };\n}\n\n/**\n * Async path: query Redis for entries that may exist on other instances,\n * then mark pending in both stores and continue.\n */\nasync function handleRedisLookup(\n key: string,\n res: Response,\n next: NextFunction,\n): Promise<void> {\n try {\n const redisCached = await redisGet(key);\n\n if (redisCached === \"pending\") {\n replyConflict(res);\n return;\n }\n\n if (redisCached && Date.now() - redisCached.createdAt < CACHE_TTL_MS) {\n // Populate local memory cache so subsequent same-instance hits are sync\n memoryCache.set(key, redisCached);\n replayResponse(res, redisCached);\n return;\n }\n\n // Atomic pending lock in Redis (NX = only if not already set)\n await redisSetPending(key);\n markPendingAndProceed(key, res, next);\n } catch (err) {\n // Never let idempotency logic break the request pipeline\n secureLogger.error(\"[idempotency] Unexpected error, skipping\", err, {});\n next();\n }\n}\n","import { Router, type Request, type Response } from \"express\";\nimport { verifyApiKey, listKeys } from \"../services/unkey-service.js\";\nimport {\n ensureWallet,\n getWalletStatus,\n} from \"../services/wallet-service.js\";\nimport { getSupabaseAdmin } from \"../db/supabase.js\";\nimport { apiError } from \"../utils/api-errors.js\";\nimport { asyncHandler } from \"../utils/asyncHandler.js\";\n\nconst router = Router();\n\n/**\n * GET /api/v1/usage — supports both JWT auth and API key auth.\n * Returns the user's wallet balance, plan, and a list of their keys.\n *\n * Wallet balance is the source of truth for \"how many credits do I have\n * left this month\" — it is per-user, not per-key. Listing keys is for\n * dashboard rendering only; deleting/disabling a key does not change the\n * balance.\n */\nrouter.get(\n \"/\",\n asyncHandler(async (req: Request, res: Response) => {\n let userId: string | undefined;\n let planId: string | undefined;\n\n const authHeader = req.headers.authorization;\n if (authHeader?.startsWith(\"Bearer \")) {\n const token = authHeader.slice(7);\n\n if (token.startsWith(\"hive_\")) {\n const result = await verifyApiKey(token);\n if (result.valid) {\n userId = result.userId;\n planId = result.planId;\n }\n } else {\n const { data } = await getSupabaseAdmin().auth.getUser(token);\n if (data.user) {\n userId = data.user.id;\n }\n }\n }\n\n const apiKeyHeader = req.headers[\"x-api-key\"] as string | undefined;\n if (!userId && apiKeyHeader) {\n const result = await verifyApiKey(apiKeyHeader);\n if (result.valid) {\n userId = result.userId;\n planId = result.planId;\n }\n }\n\n if (!userId) {\n return res\n .status(401)\n .json(\n apiError(\n \"authentication_error\",\n \"AUTH_REQUIRED\",\n \"Provide a Bearer token or x-api-key header.\",\n ),\n );\n }\n\n if (!planId) {\n const { data: profile } = await getSupabaseAdmin()\n .from(\"user_profiles\")\n .select(\"plan_id\")\n .eq(\"id\", userId)\n .single();\n planId = profile?.plan_id ?? \"demo\";\n }\n\n const resolvedPlanId: string = planId ?? \"demo\";\n\n const { data: plan } = await getSupabaseAdmin()\n .from(\"plans\")\n .select(\"*\")\n .eq(\"id\", resolvedPlanId)\n .single();\n\n // Lazily provision wallets for legacy accounts that pre-date the\n // wallet migration. ensureWallet is a no-op if one already exists.\n await ensureWallet(userId, resolvedPlanId);\n const wallet = await getWalletStatus(userId);\n\n const keys = await listKeys(userId);\n const keyEntries = keys.map((k) => ({\n key_id: k.keyId,\n name: k.name,\n prefix: k.prefix,\n enabled: k.enabled,\n }));\n\n return res.json({\n ok: true,\n data: {\n plan: plan\n ? {\n id: plan.id,\n name: plan.name,\n rate_limit_per_min: plan.rate_limit_per_min,\n monthly_credits: plan.monthly_credits,\n max_api_keys: plan.max_api_keys,\n }\n : { id: resolvedPlanId },\n wallet: wallet\n ? {\n balance: wallet.balance,\n monthly_grant: wallet.monthlyGrant,\n cycle_start: wallet.cycleStart,\n cycle_end: wallet.cycleEnd,\n }\n : null,\n keys: keyEntries,\n total_keys: keys.length,\n },\n });\n }),\n);\n\nexport default router;\n","import { randomUUID } from \"crypto\";\nimport type { Request, Response, NextFunction } from \"express\";\n\ndeclare global {\n namespace Express {\n interface Request {\n requestId?: string;\n }\n }\n}\n\nexport function requestIdMiddleware(\n req: Request,\n res: Response,\n next: NextFunction,\n): void {\n const id =\n (req.headers[\"x-request-id\"] as string) ||\n `req_${randomUUID().replace(/-/g, \"\")}`;\n req.requestId = id;\n res.setHeader(\"x-request-id\", id);\n next();\n}\n","import type { Request, Response, NextFunction } from \"express\";\n\n/**\n * Sets informational rate limit headers on ALL responses.\n * express-rate-limit only sets them on rate-limited routes.\n */\nexport function rateLimitInfoHeaders(opts: {\n limit: number;\n windowMs: number;\n}) {\n const windowSec = Math.round(opts.windowMs / 1000);\n return (_req: Request, res: Response, next: NextFunction): void => {\n if (!res.getHeader(\"RateLimit-Limit\")) {\n res.setHeader(\"RateLimit-Limit\", String(opts.limit));\n res.setHeader(\"RateLimit-Policy\", `${opts.limit};w=${windowSec}`);\n }\n next();\n };\n}\n","import type { Request, Response, NextFunction } from \"express\";\nimport { createHash } from \"node:crypto\";\n\n/**\n * Sets Cache-Control headers based on route pattern.\n */\nexport function cacheHeaders() {\n return (req: Request, res: Response, next: NextFunction): void => {\n const path = req.path;\n\n if (path === \"/api/openapi.json\") {\n res.setHeader(\n \"Cache-Control\",\n \"public, max-age=300, stale-while-revalidate=60\",\n );\n } else if (path === \"/api/v1/tools\") {\n res.setHeader(\n \"Cache-Control\",\n \"public, max-age=60, stale-while-revalidate=30\",\n );\n } else if (\n path.startsWith(\"/api/health\") ||\n path === \"/ping\" ||\n path === \"/status\"\n ) {\n res.setHeader(\"Cache-Control\", \"no-cache, max-age=0\");\n } else if (req.method === \"POST\") {\n res.setHeader(\"Cache-Control\", \"no-store\");\n }\n\n next();\n };\n}\n\n/**\n * Adds weak ETag support for GET JSON responses.\n * Handles If-None-Match for conditional requests (returns 304).\n */\nexport function etagSupport() {\n return (req: Request, res: Response, next: NextFunction): void => {\n if (req.method !== \"GET\") return next();\n\n const originalJson = res.json.bind(res);\n res.json = (body: unknown) => {\n const bodyStr = JSON.stringify(body);\n const hash = createHash(\"md5\").update(bodyStr).digest(\"hex\").slice(0, 16);\n const etag = `W/\"${hash}\"`;\n\n res.setHeader(\"ETag\", etag);\n\n const ifNoneMatch = req.headers[\"if-none-match\"];\n if (ifNoneMatch === etag) {\n res.status(304).end();\n return res;\n }\n\n return originalJson(body);\n };\n\n next();\n };\n}\n","import { getAllWrappedEndpoints } from \"../wrapper/index.js\";\nimport { SERVER_VERSION } from \"../mcpServer.js\";\nimport { CategoryEndpoints } from \"../toolRegistry.js\";\n\nlet _cachedSpec: Record<string, unknown> | null = null;\n\nexport function generateOpenApiSpec(): Record<string, unknown> {\n if (_cachedSpec) return _cachedSpec;\n const endpoints = getAllWrappedEndpoints();\n\n const schemas: Record<string, unknown> = {};\n for (const ep of endpoints) {\n if (ep.tool.inputSchema) {\n schemas[ep.tool.name] = ep.tool.inputSchema;\n }\n }\n\n const categoryMcpPaths = Object.fromEntries(\n Object.entries(CategoryEndpoints).map(([category, path]) => [\n path,\n {\n post: {\n summary: `MCP category endpoint for ${category.replace(/_/g, \" \")}`,\n operationId: `mcpCategory_${category}`,\n description:\n \"Scoped Streamable HTTP MCP endpoint for clients that explicitly need a category-level tools/list surface. Include Accept: application/json, text/event-stream.\",\n requestBody: {\n required: true,\n content: {\n \"application/json\": { schema: { type: \"object\" } },\n },\n },\n responses: {\n \"200\": { description: \"JSON-RPC response or SSE stream\" },\n \"406\": {\n description: \"Missing required Streamable HTTP Accept header\",\n },\n },\n security: [{ bearerAuth: [] }, { apiKey: [] }],\n },\n },\n ]),\n );\n\n const spec = {\n openapi: \"3.0.3\",\n info: {\n title: \"Hive Intelligence API\",\n description:\n \"Core Hive execution API and MCP transport reference for agent integrations. The root MCP endpoint stays compact; use resources, task toolsets, schema lookup, category MCP endpoints, or /api/v1/tools for the full provider catalog.\",\n version: SERVER_VERSION,\n },\n servers: [\n { url: process.env.MCP_BASE_URL || \"https://mcp.hiveintelligence.xyz\" },\n ],\n paths: {\n \"/ping\": {\n get: {\n summary: \"Liveness check\",\n operationId: \"ping\",\n responses: { \"200\": { description: \"Server status and version\" } },\n },\n },\n \"/live\": {\n get: {\n summary: \"Kubernetes liveness probe\",\n operationId: \"live\",\n responses: { \"200\": { description: \"Process is alive\" } },\n },\n },\n \"/ready\": {\n get: {\n summary: \"Kubernetes readiness probe\",\n operationId: \"ready\",\n responses: {\n \"200\": { description: \"Ready to accept traffic\" },\n \"503\": { description: \"Not yet ready\" },\n },\n },\n },\n \"/api/health\": {\n get: {\n summary: \"Aggregate health status of all providers\",\n operationId: \"healthCheck\",\n responses: { \"200\": { description: \"All provider test results\" } },\n },\n },\n \"/health\": {\n get: {\n summary: \"Public health check\",\n operationId: \"publicHealth\",\n responses: { \"200\": { description: \"Server status and version\" } },\n },\n },\n \"/status\": {\n get: {\n summary: \"Runtime status\",\n operationId: \"runtimeStatus\",\n responses: {\n \"200\": {\n description:\n \"Classified provider availability, degradation, and diagnostic status\",\n },\n },\n },\n },\n \"/startup\": {\n get: {\n summary: \"Startup readiness diagnostics\",\n operationId: \"startupStatus\",\n responses: {\n \"200\": { description: \"Startup diagnostics and readiness state\" },\n \"503\": { description: \"Startup checks are not ready\" },\n },\n },\n },\n \"/.well-known/mcp.json\": {\n get: {\n summary: \"Compact MCP discovery descriptor\",\n operationId: \"mcpDiscovery\",\n responses: {\n \"200\": {\n description:\n \"Public MCP descriptor with package, transport, and tool-count metadata\",\n },\n },\n },\n head: {\n summary: \"Compact MCP discovery descriptor availability\",\n operationId: \"headMcpDiscovery\",\n responses: { \"200\": { description: \"Descriptor is available\" } },\n },\n },\n \"/.well-known/mcp/server-card.json\": {\n get: {\n summary: \"Hive MCP server card\",\n operationId: \"mcpServerCard\",\n responses: {\n \"200\": {\n description:\n \"Public server-card metadata including transports, package, skills, resources, and tool counts\",\n },\n },\n },\n head: {\n summary: \"Hive MCP server-card availability\",\n operationId: \"headMcpServerCard\",\n responses: { \"200\": { description: \"Server card is available\" } },\n },\n },\n \"/api/health/{apiName}\": {\n get: {\n summary: \"Per-provider health status\",\n operationId: \"providerHealth\",\n parameters: [\n {\n name: \"apiName\",\n in: \"path\",\n required: true,\n schema: { type: \"string\" },\n },\n ],\n responses: {\n \"200\": { description: \"Provider-specific test results\" },\n },\n },\n },\n \"/api/v1/tools\": {\n get: {\n summary: \"List available tools\",\n operationId: \"listTools\",\n parameters: [\n {\n name: \"limit\",\n in: \"query\",\n schema: { type: \"integer\", default: 50 },\n },\n { name: \"cursor\", in: \"query\", schema: { type: \"string\" } },\n { name: \"search\", in: \"query\", schema: { type: \"string\" } },\n {\n name: \"fields\",\n in: \"query\",\n schema: { type: \"string\" },\n description: \"Comma-separated fields to include\",\n },\n {\n name: \"sort\",\n in: \"query\",\n schema: { type: \"string\", enum: [\"name\"] },\n description: \"Field to sort by\",\n },\n {\n name: \"order\",\n in: \"query\",\n schema: { type: \"string\", enum: [\"asc\", \"desc\"], default: \"asc\" },\n description: \"Sort order\",\n },\n ],\n responses: {\n \"200\": {\n description: \"Tool list with pagination\",\n content: {\n \"application/json\": {\n schema: {\n type: \"object\",\n properties: {\n ok: { type: \"boolean\" },\n data: { type: \"array\" },\n has_more: { type: \"boolean\" },\n next_cursor: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n security: [{ bearerAuth: [] }, { apiKey: [] }],\n },\n },\n \"/api/v1/execute\": {\n post: {\n summary: \"Execute a tool\",\n operationId: \"executeTool\",\n requestBody: {\n required: true,\n content: {\n \"application/json\": {\n schema: {\n type: \"object\",\n required: [\"tool\"],\n properties: {\n tool: { type: \"string\", description: \"Tool name\" },\n args: { type: \"object\", description: \"Tool arguments\" },\n },\n },\n },\n },\n },\n responses: {\n \"200\": { description: \"Tool result\" },\n \"400\": { description: \"Invalid request or tool error\" },\n \"404\": { description: \"Tool not found\" },\n \"503\": { description: \"Provider unavailable\" },\n },\n security: [{ bearerAuth: [] }, { apiKey: [] }],\n },\n },\n \"/mcp\": {\n post: {\n summary: \"MCP protocol endpoint (JSON-RPC over HTTP)\",\n operationId: \"mcpEndpoint\",\n description:\n \"Streamable HTTP transport for Model Context Protocol. Accepts JSON-RPC 2.0 requests. Clients must send Accept: application/json, text/event-stream.\",\n requestBody: {\n required: true,\n content: {\n \"application/json\": { schema: { type: \"object\" } },\n },\n },\n responses: {\n \"200\": { description: \"JSON-RPC response or SSE stream\" },\n \"406\": { description: \"Missing required Streamable HTTP Accept header\" },\n \"405\": { description: \"Method not allowed (only POST)\" },\n },\n security: [{ bearerAuth: [] }, { apiKey: [] }],\n },\n },\n ...categoryMcpPaths,\n },\n components: {\n schemas,\n securitySchemes: {\n apiKey: { type: \"apiKey\", in: \"header\", name: \"x-api-key\" },\n bearerAuth: { type: \"http\", scheme: \"bearer\" },\n },\n },\n };\n _cachedSpec = spec;\n return _cachedSpec;\n}\n","import { getAllWrappedEndpoints } from \"../wrapper/index.js\";\nimport { getSharedClients } from \"../mcpServer.js\";\nimport type { ValidationError } from \"../middleware/input-validator.js\";\nimport type { ApiErrorType } from \"../utils/api-errors.js\";\nimport { secureLogger } from \"../utils/secureLogger.js\";\nimport {\n createToolNotFoundResult,\n executeEndpoint,\n type HiveExecutionMetadata,\n resolveEndpoint,\n} from \"./tool-execution-pipeline.js\";\n\nexport interface ExecuteToolError {\n type: ApiErrorType;\n code: string;\n message: string;\n}\n\nexport interface ExecuteResult {\n ok: boolean;\n data?: unknown;\n error?: ExecuteToolError;\n validationErrors?: ValidationError[];\n durationMs: number;\n meta: HiveExecutionMetadata;\n}\n\n/**\n * Execute a tool by name with the given arguments.\n *\n * REST Adapter over the shared tool execution pipeline.\n */\nexport async function executeToolByName(\n toolName: string,\n args: Record<string, unknown>,\n): Promise<ExecuteResult> {\n const allEndpoints = getAllWrappedEndpoints();\n const lookup = resolveEndpoint(allEndpoints, toolName);\n\n if (!lookup.ok) {\n const result = createToolNotFoundResult(toolName);\n secureLogger.toolCall(toolName, false, result.durationMs, {\n transport: \"rest\",\n runtimeStatus: \"failing\",\n errorClass: \"not_found\",\n });\n return {\n ok: false,\n error: result.error,\n durationMs: result.durationMs,\n meta: result.hive,\n };\n }\n\n const result = await executeEndpoint(lookup.endpoint, args, {\n transport: \"rest\",\n clients: getSharedClients(),\n });\n\n if (result.validationErrors) {\n return {\n ok: false,\n error: result.error,\n validationErrors: result.validationErrors,\n durationMs: result.durationMs,\n meta: result.hive,\n };\n }\n\n if (result.ok) {\n return {\n ok: true,\n data: result.data,\n durationMs: result.durationMs,\n meta: result.hive,\n };\n }\n\n if (result.error?.code === \"PROVIDER_UNAVAILABLE\") {\n return {\n ok: false,\n error: result.error,\n durationMs: result.durationMs,\n meta: result.hive,\n };\n }\n\n if (result.error?.code === \"INTERNAL_ERROR\") {\n secureLogger.error(`[tool-execution] ${toolName} threw`, result.error, {});\n }\n\n return {\n ok: false,\n error: result.error,\n durationMs: result.durationMs,\n meta: result.hive,\n };\n}\n","export function isMcpPath(path: string): boolean {\n return path === \"/mcp\" || path === \"/mcp/\" || /\\/mcp\\/?$/.test(path);\n}\n\nexport function hasRequiredStreamableHttpAcceptHeader(\n acceptHeader: string | string[] | undefined,\n): boolean {\n if (!acceptHeader) return false;\n\n const accept = Array.isArray(acceptHeader)\n ? acceptHeader.join(\",\")\n : acceptHeader;\n const normalized = accept.toLowerCase();\n\n return (\n normalized.includes(\"application/json\") &&\n normalized.includes(\"text/event-stream\")\n );\n}\n","import { SERVER_VERSION } from \"./mcpServer.js\";\nimport { HIVE_AGENT_SKILLS } from \"./agentSkills.js\";\nimport { TASK_TOOLSETS } from \"./taskToolsets.js\";\nimport { CategoryEndpoints } from \"./toolRegistry.js\";\nimport { getAllWrappedEndpoints } from \"./wrapper/index.js\";\nimport { getRootVisibleToolCount } from \"./utils/toolCatalog.js\";\nimport { AUTH_COMPATIBILITY } from \"./mcpSurface.js\";\n\nexport function buildServerCard() {\n const underlyingToolCount = getAllWrappedEndpoints().length;\n const visibleToolCount = getRootVisibleToolCount();\n const categoryCount = Object.keys(CategoryEndpoints).length;\n\n return {\n name: \"Hive Intelligence\",\n id: \"io.github.sharpe-labs/hive-mcp\",\n version: SERVER_VERSION,\n protocolVersion: \"2025-06-18\",\n description:\n \"Institutional-grade crypto market infrastructure for AI — live prices, DeFi, wallets, and token risk through a managed MCP, REST API, or CLI.\",\n author: {\n name: \"Hive Intelligence\",\n url: \"https://www.hiveintelligence.xyz\",\n email: \"support@hiveintelligence.xyz\",\n },\n homepage: \"https://www.hiveintelligence.xyz\",\n documentation: \"https://www.hiveintelligence.xyz/crypto-mcp\",\n repository: {\n type: \"git\",\n url: \"https://github.com/sharpe-labs/hive-mcp2\",\n },\n license: \"MIT\",\n categories: [\"finance\", \"crypto\", \"defi\", \"web3\", \"ai-agents\"],\n tags: [\n \"mcp\",\n \"modelcontextprotocol\",\n \"crypto\",\n \"cryptocurrency\",\n \"defi\",\n \"wallets\",\n \"token-security\",\n \"claude\",\n \"cursor\",\n \"chatgpt\",\n \"gemini\",\n \"windsurf\",\n \"ai-agents\",\n ],\n transports: [\n {\n type: \"streamable-http\",\n url: \"https://mcp.hiveintelligence.xyz/mcp\",\n primary: true,\n },\n {\n type: \"stdio\",\n command: \"npx\",\n args: [\"-y\", \"-p\", \"hive-intelligence@latest\", \"hive\"],\n },\n ],\n package: {\n name: \"hive-intelligence\",\n command: \"hive\",\n install: \"npx -y -p hive-intelligence@latest hive\",\n stdioArgs: [\"-y\", \"-p\", \"hive-intelligence@latest\", \"hive\"],\n },\n authentication: {\n type: \"api_key\",\n required: true,\n appliesTo: [\"streamable-http\", \"rest\"],\n notRequiredFor: [\"stdio\"],\n note: \"Hosted HTTP MCP and REST calls require a Hive API key. Local stdio can run with local provider keys or self-hosted configuration.\",\n headers: {\n Authorization: \"Bearer <YOUR_HIVE_API_KEY>\",\n \"x-api-key\": \"<YOUR_HIVE_API_KEY>\",\n },\n signupUrl: \"https://www.hiveintelligence.xyz/login?next=/dashboard/keys\",\n freeTier: {\n monthlyCredits: 10000,\n requestsPerMinute: 30,\n description: \"Demo tier — no credit card required\",\n },\n },\n authCompatibility: AUTH_COMPATIBILITY,\n capabilities: {\n tools: {},\n resources: {},\n prompts: {},\n toolCount: visibleToolCount,\n visibleToolCount,\n underlyingToolCount,\n categoryCount,\n taskToolsetCount: TASK_TOOLSETS.length,\n taskToolsets: TASK_TOOLSETS.map((toolset) => ({\n id: toolset.id,\n kind: toolset.kind,\n label: toolset.label,\n purpose: toolset.purpose,\n })),\n skillPackCount: HIVE_AGENT_SKILLS.length,\n skills: HIVE_AGENT_SKILLS.map((skill) => ({\n name: skill.name,\n label: skill.label,\n description: skill.description,\n toolsetIds: skill.toolsetIds,\n })),\n categoryEndpoints: Object.values(CategoryEndpoints),\n resourceUris: [\n \"hive://providers\",\n \"hive://categories\",\n \"hive://tools\",\n \"hive://toolsets\",\n \"hive://task-canaries\",\n \"hive://skills\",\n \"hive://status\",\n ],\n alternativeSurfaces: {\n rest: \"https://mcp.hiveintelligence.xyz/api/v1/execute\",\n cli: \"npx -y -p hive-intelligence@latest hive\",\n },\n },\n clients: [\n {\n name: \"Claude Desktop\",\n setupUrl: \"https://hiveintelligence.xyz/install/claude-desktop\",\n },\n {\n name: \"Claude Code\",\n setupUrl: \"https://hiveintelligence.xyz/install/claude-code\",\n },\n {\n name: \"ChatGPT Desktop\",\n setupUrl: \"https://hiveintelligence.xyz/install/chatgpt\",\n },\n {\n name: \"Cursor\",\n setupUrl: \"https://hiveintelligence.xyz/install/cursor\",\n },\n {\n name: \"Windsurf\",\n setupUrl: \"https://hiveintelligence.xyz/install/windsurf\",\n },\n {\n name: \"VS Code (GitHub Copilot Chat)\",\n setupUrl: \"https://hiveintelligence.xyz/install/vs-code\",\n },\n {\n name: \"Gemini CLI\",\n setupUrl: \"https://hiveintelligence.xyz/install/gemini-cli\",\n },\n ],\n iconUrl: \"https://hiveintelligence.xyz/hive-favicon.png\",\n };\n}\n"],"mappings":"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","names":["randomUUID","timingSafeEqual","isProduction","status","runtimeStatus","results","Router","rateLimit","RedisStore","router","Router","RedisStore","rateLimit","Router","z","createHash","CACHE_TTL_MS","createHash","router","Router","z","Router","router","Router","randomUUID","createHash","result","randomUUID","resolve","timingSafeEqual"]}