@pellux/goodvibes-sdk 0.21.30 → 0.21.33

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 (307) hide show
  1. package/dist/_internal/contracts/zod-schemas/accounts.d.ts +9 -9
  2. package/dist/_internal/contracts/zod-schemas/auth.d.ts +1 -1
  3. package/dist/_internal/daemon/context.d.ts +1 -0
  4. package/dist/_internal/daemon/context.d.ts.map +1 -1
  5. package/dist/_internal/daemon/error-response.js +22 -22
  6. package/dist/_internal/daemon/integration-route-types.d.ts +2 -1
  7. package/dist/_internal/daemon/integration-route-types.d.ts.map +1 -1
  8. package/dist/_internal/daemon/knowledge-routes.js +5 -5
  9. package/dist/_internal/daemon/media-routes.d.ts.map +1 -1
  10. package/dist/_internal/daemon/media-routes.js +4 -3
  11. package/dist/_internal/daemon/operator.d.ts +1 -1
  12. package/dist/_internal/daemon/operator.d.ts.map +1 -1
  13. package/dist/_internal/daemon/operator.js +2 -0
  14. package/dist/_internal/daemon/runtime-route-types.d.ts +2 -1
  15. package/dist/_internal/daemon/runtime-route-types.d.ts.map +1 -1
  16. package/dist/_internal/daemon/runtime-routes.d.ts +1 -1
  17. package/dist/_internal/daemon/runtime-routes.d.ts.map +1 -1
  18. package/dist/_internal/daemon/runtime-routes.js +1 -0
  19. package/dist/_internal/daemon/telemetry-routes.d.ts.map +1 -1
  20. package/dist/_internal/daemon/telemetry-routes.js +13 -12
  21. package/dist/_internal/errors/daemon-error-contract.d.ts +17 -0
  22. package/dist/_internal/errors/daemon-error-contract.d.ts.map +1 -1
  23. package/dist/_internal/errors/daemon-error-contract.js +17 -1
  24. package/dist/_internal/errors/index.d.ts +2 -1
  25. package/dist/_internal/errors/index.d.ts.map +1 -1
  26. package/dist/_internal/errors/index.js +1 -0
  27. package/dist/_internal/platform/artifacts/store.d.ts.map +1 -1
  28. package/dist/_internal/platform/artifacts/store.js +2 -1
  29. package/dist/_internal/platform/automation/scheduler-capacity.d.ts +29 -0
  30. package/dist/_internal/platform/automation/scheduler-capacity.d.ts.map +1 -0
  31. package/dist/_internal/platform/automation/scheduler-capacity.js +31 -0
  32. package/dist/_internal/platform/channels/delivery/shared.d.ts.map +1 -1
  33. package/dist/_internal/platform/channels/delivery/shared.js +3 -2
  34. package/dist/_internal/platform/channels/delivery/strategies-bridge.d.ts.map +1 -1
  35. package/dist/_internal/platform/channels/delivery/strategies-bridge.js +3 -2
  36. package/dist/_internal/platform/channels/delivery/strategies-core.d.ts.map +1 -1
  37. package/dist/_internal/platform/channels/delivery/strategies-core.js +5 -4
  38. package/dist/_internal/platform/channels/delivery/strategies-enterprise.d.ts.map +1 -1
  39. package/dist/_internal/platform/channels/delivery/strategies-enterprise.js +4 -3
  40. package/dist/_internal/platform/config/manager.d.ts.map +1 -1
  41. package/dist/_internal/platform/config/manager.js +2 -1
  42. package/dist/_internal/platform/config/schema-domain-runtime.d.ts +6 -0
  43. package/dist/_internal/platform/config/schema-domain-runtime.d.ts.map +1 -1
  44. package/dist/_internal/platform/config/schema-domain-runtime.js +22 -0
  45. package/dist/_internal/platform/config/schema-types.d.ts +16 -2
  46. package/dist/_internal/platform/config/schema-types.d.ts.map +1 -1
  47. package/dist/_internal/platform/config/schema.d.ts.map +1 -1
  48. package/dist/_internal/platform/config/schema.js +1 -0
  49. package/dist/_internal/platform/config/service-registry.d.ts.map +1 -1
  50. package/dist/_internal/platform/config/service-registry.js +2 -1
  51. package/dist/_internal/platform/control-plane/gateway-web-ui.d.ts +0 -1
  52. package/dist/_internal/platform/control-plane/gateway-web-ui.d.ts.map +1 -1
  53. package/dist/_internal/platform/control-plane/gateway-web-ui.js +7 -6
  54. package/dist/_internal/platform/control-plane/session-broker.d.ts.map +1 -1
  55. package/dist/_internal/platform/control-plane/session-broker.js +12 -4
  56. package/dist/_internal/platform/core/orchestrator-tool-runtime.d.ts.map +1 -1
  57. package/dist/_internal/platform/core/orchestrator-tool-runtime.js +6 -6
  58. package/dist/_internal/platform/core/orchestrator-turn-loop.d.ts.map +1 -1
  59. package/dist/_internal/platform/core/orchestrator-turn-loop.js +10 -2
  60. package/dist/_internal/platform/daemon/facade-composition.d.ts +4 -131
  61. package/dist/_internal/platform/daemon/facade-composition.d.ts.map +1 -1
  62. package/dist/_internal/platform/daemon/facade-composition.js +9 -10
  63. package/dist/_internal/platform/daemon/facade-types.d.ts +141 -0
  64. package/dist/_internal/platform/daemon/facade-types.d.ts.map +1 -0
  65. package/dist/_internal/platform/daemon/facade-types.js +1 -0
  66. package/dist/_internal/platform/daemon/http/rate-limiter.d.ts +23 -0
  67. package/dist/_internal/platform/daemon/http/rate-limiter.d.ts.map +1 -0
  68. package/dist/_internal/platform/daemon/http/rate-limiter.js +71 -0
  69. package/dist/_internal/platform/daemon/http/router-route-contexts.d.ts.map +1 -1
  70. package/dist/_internal/platform/daemon/http/router-route-contexts.js +2 -1
  71. package/dist/_internal/platform/daemon/http/router.d.ts.map +1 -1
  72. package/dist/_internal/platform/daemon/http/router.js +70 -65
  73. package/dist/_internal/platform/daemon/http/runtime-route-types.d.ts.map +1 -1
  74. package/dist/_internal/platform/daemon/http-listener.d.ts +1 -0
  75. package/dist/_internal/platform/daemon/http-listener.d.ts.map +1 -1
  76. package/dist/_internal/platform/daemon/http-listener.js +53 -73
  77. package/dist/_internal/platform/daemon/surface-delivery.d.ts.map +1 -1
  78. package/dist/_internal/platform/daemon/surface-delivery.js +6 -5
  79. package/dist/_internal/platform/discovery/mcp-scanner.d.ts.map +1 -1
  80. package/dist/_internal/platform/discovery/mcp-scanner.js +28 -22
  81. package/dist/_internal/platform/discovery/scanner.d.ts.map +1 -1
  82. package/dist/_internal/platform/discovery/scanner.js +38 -22
  83. package/dist/_internal/platform/export/session-export.d.ts +0 -1
  84. package/dist/_internal/platform/export/session-export.d.ts.map +1 -1
  85. package/dist/_internal/platform/export/session-export.js +1 -33
  86. package/dist/_internal/platform/hooks/runners/http.d.ts.map +1 -1
  87. package/dist/_internal/platform/hooks/runners/http.js +2 -1
  88. package/dist/_internal/platform/integrations/delivery.d.ts +3 -1
  89. package/dist/_internal/platform/integrations/delivery.d.ts.map +1 -1
  90. package/dist/_internal/platform/integrations/delivery.js +3 -2
  91. package/dist/_internal/platform/integrations/discord.d.ts.map +1 -1
  92. package/dist/_internal/platform/integrations/discord.js +6 -5
  93. package/dist/_internal/platform/integrations/ntfy.d.ts.map +1 -1
  94. package/dist/_internal/platform/integrations/ntfy.js +3 -2
  95. package/dist/_internal/platform/integrations/webhooks.d.ts.map +1 -1
  96. package/dist/_internal/platform/integrations/webhooks.js +2 -1
  97. package/dist/_internal/platform/intelligence/lsp/binary-downloader.d.ts.map +1 -1
  98. package/dist/_internal/platform/intelligence/lsp/binary-downloader.js +4 -3
  99. package/dist/_internal/platform/knowledge/store.d.ts.map +1 -1
  100. package/dist/_internal/platform/knowledge/store.js +50 -25
  101. package/dist/_internal/platform/mcp/client.d.ts.map +1 -1
  102. package/dist/_internal/platform/mcp/client.js +3 -2
  103. package/dist/_internal/platform/media/builtin-generation-providers.d.ts.map +1 -1
  104. package/dist/_internal/platform/media/builtin-generation-providers.js +4 -3
  105. package/dist/_internal/platform/media/builtin-image-understanding.d.ts.map +1 -1
  106. package/dist/_internal/platform/media/builtin-image-understanding.js +5 -4
  107. package/dist/_internal/platform/providers/anthropic-compat.d.ts.map +1 -1
  108. package/dist/_internal/platform/providers/anthropic-compat.js +5 -3
  109. package/dist/_internal/platform/providers/anthropic.d.ts.map +1 -1
  110. package/dist/_internal/platform/providers/anthropic.js +10 -7
  111. package/dist/_internal/platform/providers/builtin-catalog.d.ts.map +1 -1
  112. package/dist/_internal/platform/providers/builtin-catalog.js +3 -2
  113. package/dist/_internal/platform/providers/catalogue.d.ts +56 -0
  114. package/dist/_internal/platform/providers/catalogue.d.ts.map +1 -0
  115. package/dist/_internal/platform/providers/catalogue.js +111 -0
  116. package/dist/_internal/platform/providers/context-discovery.d.ts.map +1 -1
  117. package/dist/_internal/platform/providers/context-discovery.js +2 -1
  118. package/dist/_internal/platform/providers/credentials.d.ts +12 -0
  119. package/dist/_internal/platform/providers/credentials.d.ts.map +1 -0
  120. package/dist/_internal/platform/providers/credentials.js +54 -0
  121. package/dist/_internal/platform/providers/gemini.d.ts.map +1 -1
  122. package/dist/_internal/platform/providers/gemini.js +6 -5
  123. package/dist/_internal/platform/providers/github-copilot.d.ts.map +1 -1
  124. package/dist/_internal/platform/providers/github-copilot.js +2 -1
  125. package/dist/_internal/platform/providers/health.d.ts +15 -0
  126. package/dist/_internal/platform/providers/health.d.ts.map +1 -0
  127. package/dist/_internal/platform/providers/health.js +32 -0
  128. package/dist/_internal/platform/providers/llama-cpp.d.ts.map +1 -1
  129. package/dist/_internal/platform/providers/llama-cpp.js +5 -3
  130. package/dist/_internal/platform/providers/lm-studio.d.ts.map +1 -1
  131. package/dist/_internal/platform/providers/lm-studio.js +5 -3
  132. package/dist/_internal/platform/providers/model-benchmarks.d.ts.map +1 -1
  133. package/dist/_internal/platform/providers/model-benchmarks.js +2 -1
  134. package/dist/_internal/platform/providers/model-catalog-cache.d.ts.map +1 -1
  135. package/dist/_internal/platform/providers/model-catalog-cache.js +2 -1
  136. package/dist/_internal/platform/providers/model-limits.d.ts.map +1 -1
  137. package/dist/_internal/platform/providers/model-limits.js +2 -1
  138. package/dist/_internal/platform/providers/ollama.d.ts.map +1 -1
  139. package/dist/_internal/platform/providers/ollama.js +5 -3
  140. package/dist/_internal/platform/providers/openai-codex.d.ts.map +1 -1
  141. package/dist/_internal/platform/providers/openai-codex.js +4 -2
  142. package/dist/_internal/platform/providers/openai-compat.d.ts.map +1 -1
  143. package/dist/_internal/platform/providers/openai-compat.js +3 -2
  144. package/dist/_internal/platform/providers/provider-not-found-error.d.ts +3 -1
  145. package/dist/_internal/platform/providers/provider-not-found-error.d.ts.map +1 -1
  146. package/dist/_internal/platform/providers/provider-not-found-error.js +3 -4
  147. package/dist/_internal/platform/providers/well-known-endpoints.d.ts +53 -0
  148. package/dist/_internal/platform/providers/well-known-endpoints.d.ts.map +1 -0
  149. package/dist/_internal/platform/providers/well-known-endpoints.js +52 -0
  150. package/dist/_internal/platform/runtime/auth/oauth-core.d.ts.map +1 -1
  151. package/dist/_internal/platform/runtime/auth/oauth-core.js +2 -1
  152. package/dist/_internal/platform/runtime/contracts/index.d.ts.map +1 -1
  153. package/dist/_internal/platform/runtime/contracts/index.js +1 -5
  154. package/dist/_internal/platform/runtime/contracts/migrations/schemas.d.ts +57 -0
  155. package/dist/_internal/platform/runtime/contracts/migrations/schemas.d.ts.map +1 -0
  156. package/dist/_internal/platform/runtime/contracts/migrations/schemas.js +157 -0
  157. package/dist/_internal/platform/runtime/correlation.d.ts +44 -0
  158. package/dist/_internal/platform/runtime/correlation.d.ts.map +1 -0
  159. package/dist/_internal/platform/runtime/correlation.js +40 -0
  160. package/dist/_internal/platform/runtime/emitters/security.d.ts +32 -0
  161. package/dist/_internal/platform/runtime/emitters/security.d.ts.map +1 -1
  162. package/dist/_internal/platform/runtime/emitters/security.js +26 -0
  163. package/dist/_internal/platform/runtime/emitters/tools.d.ts +11 -2
  164. package/dist/_internal/platform/runtime/emitters/tools.d.ts.map +1 -1
  165. package/dist/_internal/platform/runtime/emitters/tools.js +27 -0
  166. package/dist/_internal/platform/runtime/emitters/transport.d.ts +27 -0
  167. package/dist/_internal/platform/runtime/emitters/transport.d.ts.map +1 -1
  168. package/dist/_internal/platform/runtime/emitters/transport.js +19 -0
  169. package/dist/_internal/platform/runtime/emitters/turn.d.ts +22 -1
  170. package/dist/_internal/platform/runtime/emitters/turn.d.ts.map +1 -1
  171. package/dist/_internal/platform/runtime/emitters/turn.js +9 -0
  172. package/dist/_internal/platform/runtime/events/index.d.ts +45 -0
  173. package/dist/_internal/platform/runtime/events/index.d.ts.map +1 -1
  174. package/dist/_internal/platform/runtime/events/index.js +108 -14
  175. package/dist/_internal/platform/runtime/events/ops.d.ts +8 -0
  176. package/dist/_internal/platform/runtime/events/ops.d.ts.map +1 -1
  177. package/dist/_internal/platform/runtime/events/security.d.ts +47 -0
  178. package/dist/_internal/platform/runtime/events/security.d.ts.map +1 -1
  179. package/dist/_internal/platform/runtime/events/tools.d.ts +14 -2
  180. package/dist/_internal/platform/runtime/events/tools.d.ts.map +1 -1
  181. package/dist/_internal/platform/runtime/events/transport.d.ts +31 -0
  182. package/dist/_internal/platform/runtime/events/transport.d.ts.map +1 -1
  183. package/dist/_internal/platform/runtime/events/turn.d.ts +25 -1
  184. package/dist/_internal/platform/runtime/events/turn.d.ts.map +1 -1
  185. package/dist/_internal/platform/runtime/events/workspace.d.ts +16 -0
  186. package/dist/_internal/platform/runtime/events/workspace.d.ts.map +1 -1
  187. package/dist/_internal/platform/runtime/llm-observability.d.ts +43 -0
  188. package/dist/_internal/platform/runtime/llm-observability.d.ts.map +1 -0
  189. package/dist/_internal/platform/runtime/llm-observability.js +107 -0
  190. package/dist/_internal/platform/runtime/metrics.d.ts +49 -0
  191. package/dist/_internal/platform/runtime/metrics.d.ts.map +1 -0
  192. package/dist/_internal/platform/runtime/metrics.js +114 -0
  193. package/dist/_internal/platform/runtime/ops/control-plane.d.ts +5 -2
  194. package/dist/_internal/platform/runtime/ops/control-plane.d.ts.map +1 -1
  195. package/dist/_internal/platform/runtime/ops/control-plane.js +5 -4
  196. package/dist/_internal/platform/runtime/permissions/divergence-dashboard.d.ts +3 -1
  197. package/dist/_internal/platform/runtime/permissions/divergence-dashboard.d.ts.map +1 -1
  198. package/dist/_internal/platform/runtime/permissions/divergence-dashboard.js +3 -2
  199. package/dist/_internal/platform/runtime/permissions/policy-loader.d.ts +3 -1
  200. package/dist/_internal/platform/runtime/permissions/policy-loader.d.ts.map +1 -1
  201. package/dist/_internal/platform/runtime/permissions/policy-loader.js +3 -2
  202. package/dist/_internal/platform/runtime/permissions/policy-signer.d.ts.map +1 -1
  203. package/dist/_internal/platform/runtime/permissions/policy-signer.js +7 -2
  204. package/dist/_internal/platform/runtime/permissions/simulation.d.ts +3 -1
  205. package/dist/_internal/platform/runtime/permissions/simulation.d.ts.map +1 -1
  206. package/dist/_internal/platform/runtime/permissions/simulation.js +3 -2
  207. package/dist/_internal/platform/runtime/remote/transport-contract.d.ts +14 -2
  208. package/dist/_internal/platform/runtime/remote/transport-contract.d.ts.map +1 -1
  209. package/dist/_internal/platform/runtime/remote/transport-contract.js +7 -5
  210. package/dist/_internal/platform/runtime/store/helpers/reducers/sync.d.ts.map +1 -1
  211. package/dist/_internal/platform/runtime/store/helpers/reducers/sync.js +12 -1
  212. package/dist/_internal/platform/runtime/tasks/manager.d.ts +7 -3
  213. package/dist/_internal/platform/runtime/tasks/manager.d.ts.map +1 -1
  214. package/dist/_internal/platform/runtime/tasks/manager.js +7 -6
  215. package/dist/_internal/platform/runtime/telemetry/api-helpers.d.ts +14 -0
  216. package/dist/_internal/platform/runtime/telemetry/api-helpers.d.ts.map +1 -1
  217. package/dist/_internal/platform/runtime/telemetry/api-helpers.js +59 -0
  218. package/dist/_internal/platform/runtime/telemetry/api.d.ts.map +1 -1
  219. package/dist/_internal/platform/runtime/telemetry/api.js +9 -2
  220. package/dist/_internal/platform/runtime/telemetry/exporters/otlp.d.ts.map +1 -1
  221. package/dist/_internal/platform/runtime/telemetry/exporters/otlp.js +19 -6
  222. package/dist/_internal/platform/runtime/telemetry/exporters/queue.d.ts.map +1 -1
  223. package/dist/_internal/platform/runtime/telemetry/exporters/queue.js +11 -4
  224. package/dist/_internal/platform/runtime/telemetry/meter.d.ts.map +1 -1
  225. package/dist/_internal/platform/runtime/telemetry/meter.js +7 -3
  226. package/dist/_internal/platform/runtime/telemetry/redaction-config.d.ts +9 -0
  227. package/dist/_internal/platform/runtime/telemetry/redaction-config.d.ts.map +1 -0
  228. package/dist/_internal/platform/runtime/telemetry/redaction-config.js +52 -0
  229. package/dist/_internal/platform/runtime/tools/phases/budget.d.ts.map +1 -1
  230. package/dist/_internal/platform/runtime/tools/phases/budget.js +3 -2
  231. package/dist/_internal/platform/runtime/transports/daemon-http-client.d.ts.map +1 -1
  232. package/dist/_internal/platform/runtime/transports/daemon-http-client.js +138 -17
  233. package/dist/_internal/platform/scheduler/scheduler.d.ts.map +1 -1
  234. package/dist/_internal/platform/scheduler/scheduler.js +6 -2
  235. package/dist/_internal/platform/sessions/manager.d.ts.map +1 -1
  236. package/dist/_internal/platform/sessions/manager.js +6 -2
  237. package/dist/_internal/platform/state/memory-embedding-http.d.ts.map +1 -1
  238. package/dist/_internal/platform/state/memory-embedding-http.js +3 -2
  239. package/dist/_internal/platform/state/project-index.d.ts.map +1 -1
  240. package/dist/_internal/platform/state/project-index.js +6 -4
  241. package/dist/_internal/platform/tools/agent/index.d.ts.map +1 -1
  242. package/dist/_internal/platform/tools/agent/index.js +2 -1
  243. package/dist/_internal/platform/tools/analyze/git-modes.d.ts.map +1 -1
  244. package/dist/_internal/platform/tools/analyze/git-modes.js +2 -1
  245. package/dist/_internal/platform/tools/edit/core.d.ts.map +1 -1
  246. package/dist/_internal/platform/tools/edit/core.js +2 -1
  247. package/dist/_internal/platform/tools/exec/runtime.d.ts.map +1 -1
  248. package/dist/_internal/platform/tools/exec/runtime.js +3 -2
  249. package/dist/_internal/platform/tools/fetch/runtime.d.ts.map +1 -1
  250. package/dist/_internal/platform/tools/fetch/runtime.js +4 -2
  251. package/dist/_internal/platform/tools/read/index.d.ts.map +1 -1
  252. package/dist/_internal/platform/tools/read/index.js +2 -1
  253. package/dist/_internal/platform/tools/registry-tool/index.d.ts.map +1 -1
  254. package/dist/_internal/platform/tools/registry-tool/index.js +2 -1
  255. package/dist/_internal/platform/tools/state/index.d.ts.map +1 -1
  256. package/dist/_internal/platform/tools/state/index.js +2 -1
  257. package/dist/_internal/platform/tools/task/index.d.ts.map +1 -1
  258. package/dist/_internal/platform/tools/task/index.js +2 -1
  259. package/dist/_internal/platform/tools/team/index.d.ts.map +1 -1
  260. package/dist/_internal/platform/tools/team/index.js +2 -1
  261. package/dist/_internal/platform/tools/web-search/index.d.ts.map +1 -1
  262. package/dist/_internal/platform/tools/web-search/index.js +2 -1
  263. package/dist/_internal/platform/tools/worklist/index.d.ts.map +1 -1
  264. package/dist/_internal/platform/tools/worklist/index.js +2 -1
  265. package/dist/_internal/platform/types/errors.d.ts +12 -10
  266. package/dist/_internal/platform/types/errors.d.ts.map +1 -1
  267. package/dist/_internal/platform/types/errors.js +21 -20
  268. package/dist/_internal/platform/utils/error-display.d.ts.map +1 -1
  269. package/dist/_internal/platform/utils/error-display.js +6 -4
  270. package/dist/_internal/platform/utils/fetch-with-timeout.d.ts +17 -0
  271. package/dist/_internal/platform/utils/fetch-with-timeout.d.ts.map +1 -1
  272. package/dist/_internal/platform/utils/fetch-with-timeout.js +59 -0
  273. package/dist/_internal/platform/utils/record-coerce.d.ts +11 -0
  274. package/dist/_internal/platform/utils/record-coerce.d.ts.map +1 -0
  275. package/dist/_internal/platform/utils/record-coerce.js +12 -0
  276. package/dist/_internal/platform/utils/redaction.js +1 -1
  277. package/dist/_internal/platform/utils/ring-buffer.d.ts +54 -0
  278. package/dist/_internal/platform/utils/ring-buffer.d.ts.map +1 -0
  279. package/dist/_internal/platform/utils/ring-buffer.js +96 -0
  280. package/dist/_internal/platform/utils/shell-split.d.ts +11 -0
  281. package/dist/_internal/platform/utils/shell-split.d.ts.map +1 -0
  282. package/dist/_internal/platform/utils/shell-split.js +83 -0
  283. package/dist/_internal/platform/version.js +1 -1
  284. package/dist/_internal/platform/voice/providers/deepgram.d.ts.map +1 -1
  285. package/dist/_internal/platform/voice/providers/deepgram.js +2 -1
  286. package/dist/_internal/platform/voice/providers/elevenlabs.d.ts.map +1 -1
  287. package/dist/_internal/platform/voice/providers/elevenlabs.js +5 -4
  288. package/dist/_internal/platform/voice/providers/google.d.ts.map +1 -1
  289. package/dist/_internal/platform/voice/providers/google.js +5 -4
  290. package/dist/_internal/platform/voice/providers/microsoft.d.ts.map +1 -1
  291. package/dist/_internal/platform/voice/providers/microsoft.js +2 -1
  292. package/dist/_internal/platform/voice/providers/openai.d.ts.map +1 -1
  293. package/dist/_internal/platform/voice/providers/openai.js +4 -3
  294. package/dist/_internal/platform/voice/providers/shared.d.ts.map +1 -1
  295. package/dist/_internal/platform/voice/providers/shared.js +2 -1
  296. package/dist/_internal/platform/voice/providers/vydra.d.ts.map +1 -1
  297. package/dist/_internal/platform/voice/providers/vydra.js +3 -2
  298. package/dist/_internal/platform/watchers/registry.d.ts.map +1 -1
  299. package/dist/_internal/platform/watchers/registry.js +3 -2
  300. package/dist/_internal/platform/workflow/trigger-executor.d.ts.map +1 -1
  301. package/dist/_internal/platform/workflow/trigger-executor.js +5 -3
  302. package/dist/_internal/platform/workspace/daemon-home.d.ts.map +1 -1
  303. package/dist/_internal/platform/workspace/daemon-home.js +6 -2
  304. package/dist/_internal/platform/workspace/workspace-swap-manager.d.ts +1 -0
  305. package/dist/_internal/platform/workspace/workspace-swap-manager.d.ts.map +1 -1
  306. package/dist/_internal/platform/workspace/workspace-swap-manager.js +14 -2
  307. package/package.json +1 -1
@@ -1,4 +1,6 @@
1
+ import { randomUUID } from 'node:crypto';
1
2
  import { logger } from '../utils/logger.js';
3
+ import { authFailureTotal, authSuccessTotal, httpRequestDurationMs, httpRequestsTotal, } from '../runtime/metrics.js';
2
4
  import { HookDispatcher } from '../hooks/dispatcher.js';
3
5
  import { authenticateOperatorRequest, buildOperatorSessionCookie, } from '../security/http-auth.js';
4
6
  import { UserAuthManager } from '../security/user-auth.js';
@@ -8,77 +10,7 @@ import { summarizeError } from '../utils/error-display.js';
8
10
  import { requirePortAvailable } from './port-check.js';
9
11
  import { resolveHostBinding } from './host-resolver.js';
10
12
  import { createHostModeRestartWatcher } from './host-mode-watcher.js';
11
- // ---------------------------------------------------------------------------
12
- // Rate limiter (sliding window per IP, in-memory)
13
- // ---------------------------------------------------------------------------
14
- const RATE_WINDOW_MS = 60_000;
15
- /** Entries older than this are eligible for TTL eviction. Default: 10 minutes. */
16
- const RATE_TTL_MS = 10 * 60_000;
17
- /** Maximum number of IP entries kept in the limiter at any time (LRU eviction). */
18
- const RATE_MAX_ENTRIES = 10_000;
19
- /** How often the background sweep runs to evict expired entries (ms). */
20
- const RATE_SWEEP_INTERVAL_MS = 60_000;
21
- class RateLimiter {
22
- limit;
23
- /** hits[ip] = sorted ascending array of request timestamps within the window */
24
- counts = new Map();
25
- /**
26
- * O(1) LRU tracking via Map insertion-order semantics.
27
- * Key = ip, value = last-seen timestamp.
28
- * To promote an entry to MRU: delete it and re-set it (both O(1)).
29
- * The Map iterator yields entries in insertion order, so the first entry is
30
- * the least-recently-used — perfect for LRU eviction without any indexOf scan.
31
- * (PERF-02)
32
- */
33
- lruMap = new Map();
34
- sweepInterval = null;
35
- constructor(limit) {
36
- this.limit = limit;
37
- // Periodic sweep to evict entries whose TTL has expired.
38
- this.sweepInterval = setInterval(() => this._sweep(), RATE_SWEEP_INTERVAL_MS);
39
- // Don't block clean process exit (PERF-07).
40
- this.sweepInterval.unref?.();
41
- }
42
- /** Returns true if the request is allowed, false if rate-limited. */
43
- check(ip) {
44
- const now = Date.now();
45
- const windowStart = now - RATE_WINDOW_MS;
46
- const hits = (this.counts.get(ip) ?? []).filter((t) => t > windowStart);
47
- hits.push(now);
48
- this.counts.set(ip, hits);
49
- // Promote to MRU: delete then re-set (both O(1) Map operations).
50
- this.lruMap.delete(ip);
51
- this.lruMap.set(ip, now);
52
- // Evict least-recently-used entry when cap is exceeded.
53
- if (this.lruMap.size > RATE_MAX_ENTRIES) {
54
- const evict = this.lruMap.keys().next().value;
55
- if (evict !== undefined) {
56
- this.lruMap.delete(evict);
57
- this.counts.delete(evict);
58
- }
59
- }
60
- return hits.length <= this.limit;
61
- }
62
- /** Stop the background sweep interval. Call this when the listener stops. */
63
- stop() {
64
- if (this.sweepInterval !== null) {
65
- clearInterval(this.sweepInterval);
66
- this.sweepInterval = null;
67
- }
68
- }
69
- /** Evict entries whose last-seen timestamp is older than RATE_TTL_MS. */
70
- _sweep() {
71
- const cutoff = Date.now() - RATE_TTL_MS;
72
- for (const [ip, lastSeen] of this.lruMap) {
73
- // Map iteration is insertion-order; first entries are oldest.
74
- // Break early once we hit a non-expired entry (all subsequent are newer).
75
- if (lastSeen >= cutoff)
76
- break;
77
- this.lruMap.delete(ip);
78
- this.counts.delete(ip);
79
- }
80
- }
81
- }
13
+ import { RateLimiter } from './http/rate-limiter.js';
82
14
  // ---------------------------------------------------------------------------
83
15
  // HttpListener
84
16
  // ---------------------------------------------------------------------------
@@ -323,8 +255,36 @@ export class HttpListener {
323
255
  // Request handling
324
256
  // -------------------------------------------------------------------------
325
257
  async handleRequest(req) {
258
+ const requestId = randomUUID();
259
+ const startMs = Date.now();
326
260
  const url = new URL(req.url);
327
261
  const clientIp = extractForwardedClientIp(req, this.trustProxy || (this.tlsState?.trustProxy ?? false)) ?? 'unknown';
262
+ let response = null;
263
+ try {
264
+ response = await this._handleRequestInner(req, url, clientIp, requestId);
265
+ return response;
266
+ }
267
+ finally {
268
+ const status = response?.status ?? 500;
269
+ const latencyMs = Date.now() - startMs;
270
+ // OBS-01: structured HTTP access log — SIEM-ingestable
271
+ logger.info('HTTP_ACCESS_LOG', {
272
+ type: 'HTTP_ACCESS_LOG',
273
+ requestId,
274
+ method: req.method,
275
+ path: url.pathname,
276
+ status,
277
+ latencyMs,
278
+ clientIp,
279
+ });
280
+ // C-1: record HTTP metric instruments
281
+ const statusClass = status >= 500 ? '5xx' : status >= 400 ? '4xx' : '2xx';
282
+ const pathPattern = url.pathname.replace(/\/[0-9a-f-]{8,}(?=\/|$)/gi, '/:id');
283
+ httpRequestsTotal.add(1, { method: req.method, status_class: statusClass });
284
+ httpRequestDurationMs.record(latencyMs, { method: req.method, path_pattern: pathPattern, status_class: statusClass });
285
+ }
286
+ }
287
+ async _handleRequestInner(req, url, clientIp, requestId) {
328
288
  // SEC-07: CORS origin check is OPT-IN via enforceCors. Default is permissive
329
289
  // (home/single-user deployments) — pre-0.21.29 behavior preserved. When
330
290
  // enforceCors is true:
@@ -351,7 +311,7 @@ export class HttpListener {
351
311
  if (!this.loginRateLimiter.check(clientIp)) {
352
312
  return Response.json({ error: 'Too many requests' }, { status: 429 });
353
313
  }
354
- return this.handleLogin(req);
314
+ return this.handleLogin(req, clientIp, requestId);
355
315
  }
356
316
  // General rate limiting for all other routes.
357
317
  if (!this.rateLimiter.check(clientIp)) {
@@ -370,7 +330,7 @@ export class HttpListener {
370
330
  }
371
331
  return Response.json({ error: 'Not found' }, { status: 404 });
372
332
  }
373
- async handleLogin(req) {
333
+ async handleLogin(req, clientIp, requestId) {
374
334
  const body = await this.parseJsonBody(req);
375
335
  if (body instanceof Response)
376
336
  return body;
@@ -378,9 +338,29 @@ export class HttpListener {
378
338
  const password = typeof body.password === 'string' ? body.password : '';
379
339
  const user = this.userAuth.authenticate(username, password);
380
340
  if (!user) {
341
+ // OBS-02: AUTH_FAILED — never log credential values
342
+ logger.warn('AUTH_FAILED', {
343
+ type: 'AUTH_FAILED',
344
+ requestId,
345
+ usernameAttempted: username,
346
+ clientIp,
347
+ reason: 'invalid_credentials',
348
+ });
349
+ // C-1: record auth failure metric
350
+ authFailureTotal.add(1);
381
351
  return Response.json({ error: 'Invalid credentials' }, { status: 401 });
382
352
  }
383
353
  const session = this.userAuth.createSession(user.username);
354
+ // OBS-02: AUTH_SUCCEEDED — never log credential values
355
+ // C-1: record auth success metric
356
+ authSuccessTotal.add(1);
357
+ logger.info('AUTH_SUCCEEDED', {
358
+ type: 'AUTH_SUCCEEDED',
359
+ requestId,
360
+ username: user.username,
361
+ clientIp,
362
+ method: 'password',
363
+ });
384
364
  return Response.json({
385
365
  authenticated: true,
386
366
  token: session.token,
@@ -1 +1 @@
1
- {"version":3,"file":"surface-delivery.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/daemon/surface-delivery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"surface-delivery.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/daemon/surface-delivery.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import { SlackIntegration, DiscordIntegration, NtfyIntegration } from '../integr
3
3
  import { logger } from '../utils/logger.js';
4
4
  import { validatePublicWebhookUrl } from '../utils/url-safety.js';
5
5
  import { summarizeError } from '../utils/error-display.js';
6
+ import { instrumentedFetch } from '../utils/fetch-with-timeout.js';
6
7
  function isSupportedDeliverySurface(surface) {
7
8
  return surface === 'slack'
8
9
  || surface === 'discord'
@@ -116,7 +117,7 @@ export class DaemonSurfaceDeliveryHelper {
116
117
  ?? process.env.SLACK_BOT_TOKEN;
117
118
  const slack = new SlackIntegration(webhookUrl ?? undefined, botToken ?? undefined);
118
119
  if (pending.responseUrl) {
119
- await fetch(pending.responseUrl, {
120
+ await instrumentedFetch(pending.responseUrl, {
120
121
  method: 'POST',
121
122
  headers: { 'Content-Type': 'application/json' },
122
123
  body: JSON.stringify({
@@ -153,7 +154,7 @@ export class DaemonSurfaceDeliveryHelper {
153
154
  ?? process.env.SLACK_BOT_TOKEN;
154
155
  const slack = new SlackIntegration(webhookUrl ?? undefined, botToken ?? undefined);
155
156
  if (pending.responseUrl) {
156
- await fetch(pending.responseUrl, {
157
+ await instrumentedFetch(pending.responseUrl, {
157
158
  method: 'POST',
158
159
  headers: { 'Content-Type': 'application/json' },
159
160
  body: JSON.stringify({
@@ -237,7 +238,7 @@ export class DaemonSurfaceDeliveryHelper {
237
238
  else if (secret && pending.callbackSignature === 'shared-secret') {
238
239
  headers.set('X-Goodvibes-Webhook-Secret', secret);
239
240
  }
240
- await fetch(validation.url, {
241
+ await instrumentedFetch(validation.url, {
241
242
  method: 'POST',
242
243
  headers,
243
244
  signal: AbortSignal.timeout(timeoutMs),
@@ -379,7 +380,7 @@ export class DaemonSurfaceDeliveryHelper {
379
380
  ]
380
381
  : undefined;
381
382
  if (typeof binding.metadata.responseUrl === 'string' && binding.metadata.responseUrl.startsWith('https://')) {
382
- await fetch(binding.metadata.responseUrl, {
383
+ await instrumentedFetch(binding.metadata.responseUrl, {
383
384
  method: 'POST',
384
385
  headers: { 'Content-Type': 'application/json' },
385
386
  body: JSON.stringify({
@@ -450,7 +451,7 @@ export class DaemonSurfaceDeliveryHelper {
450
451
  if (secret) {
451
452
  headers.set('X-Goodvibes-Signature', this.signWebhookPayload(payload, secret));
452
453
  }
453
- await fetch(validation.url, {
454
+ await instrumentedFetch(validation.url, {
454
455
  method: 'POST',
455
456
  headers,
456
457
  body: payload,
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-scanner.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/discovery/mcp-scanner.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIlE,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,kCAAkC;IAClC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,eAAe,CAAC,GAAG;IAC7F,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AA4KF;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,iBAAiB,EACxB,eAAe,GAAE,GAAG,CAAC,MAAM,CAAa,GACvC,OAAO,CAAC,kBAAkB,CAAC,CAiC7B"}
1
+ {"version":3,"file":"mcp-scanner.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/discovery/mcp-scanner.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIlE,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,kCAAkC;IAClC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,eAAe,CAAC,GAAG;IAC7F,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AA4KF;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,iBAAiB,EACxB,eAAe,GAAE,GAAG,CAAC,MAAM,CAAa,GACvC,OAAO,CAAC,kBAAkB,CAAC,CAwC7B"}
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * Returns suggested McpServerConfig[] for servers not already in the registry.
13
13
  */
14
- import { existsSync, readdirSync, statSync } from 'fs';
14
+ import { readdir, stat } from 'node:fs/promises';
15
15
  import { join } from 'path';
16
16
  import { logger } from '../utils/logger.js';
17
17
  import { requireSurfaceRoot } from '../runtime/surface-root.js';
@@ -50,15 +50,15 @@ function deriveServerName(nameOrPath) {
50
50
  * Check if a given package is installed locally (in node_modules).
51
51
  * Returns the bin path if found, null otherwise.
52
52
  */
53
- function findLocalNpxBin(cwd, packageName) {
53
+ async function findLocalNpxBin(cwd, packageName) {
54
54
  // Check project-local node_modules/.bin
55
55
  const binName = packageName.replace(/^@[^/]+\//, '');
56
56
  const localBin = join(cwd, 'node_modules', '.bin', binName);
57
- if (existsSync(localBin))
57
+ if (await stat(localBin).then(() => true).catch(() => false))
58
58
  return localBin;
59
59
  // Also check if the package itself exists in node_modules
60
60
  const localPkg = join(cwd, 'node_modules', packageName, 'package.json');
61
- if (existsSync(localPkg))
61
+ if (await stat(localPkg).then(() => true).catch(() => false))
62
62
  return packageName;
63
63
  return null;
64
64
  }
@@ -68,27 +68,27 @@ function findLocalNpxBin(cwd, packageName) {
68
68
  * - .mcp/mcp.json (already handled by loadMcpConfig, skip)
69
69
  * - .mcp/<name>/index.js or .mcp/<name>/index.ts or .mcp/<name>/server.js
70
70
  */
71
- function scanProjectMcpDir(roots, knownNames) {
71
+ async function scanProjectMcpDir(roots, knownNames) {
72
72
  const mcpDir = join(roots.workingDirectory, '.mcp');
73
- if (!existsSync(mcpDir))
73
+ if (!await stat(mcpDir).then(() => true).catch(() => false))
74
74
  return [];
75
75
  const suggestions = [];
76
76
  try {
77
- const entries = readdirSync(mcpDir);
77
+ const entries = await readdir(mcpDir);
78
78
  for (const entry of entries) {
79
79
  // Skip mcp.json — already read by loadMcpConfig
80
80
  if (entry === 'mcp.json')
81
81
  continue;
82
82
  const entryPath = join(mcpDir, entry);
83
83
  try {
84
- const stat = statSync(entryPath);
85
- if (!stat.isDirectory())
84
+ const entryStat = await stat(entryPath);
85
+ if (!entryStat.isDirectory())
86
86
  continue;
87
87
  // Look for a server entry point inside the subdirectory
88
88
  const candidates = ['index.js', 'index.ts', 'server.js', 'server.ts', 'main.js', 'main.ts'];
89
89
  for (const candidate of candidates) {
90
90
  const candidatePath = join(entryPath, candidate);
91
- if (existsSync(candidatePath)) {
91
+ if (await stat(candidatePath).then(() => true).catch(() => false)) {
92
92
  if (knownNames.has(entry))
93
93
  break; // already registered
94
94
  const runtime = candidate.endsWith('.ts') ? 'bun' : 'node';
@@ -117,22 +117,22 @@ function scanProjectMcpDir(roots, knownNames) {
117
117
  * - <name>/index.js, <name>/server.js, etc.
118
118
  * - <name>.js, <name>.ts standalone scripts
119
119
  */
120
- function scanGoodvibesMcpDir(roots, knownNames) {
120
+ async function scanGoodvibesMcpDir(roots, knownNames) {
121
121
  const mcpDir = join(roots.homeDirectory, '.goodvibes', requireSurfaceRoot(roots.surfaceRoot, 'MCP discovery surfaceRoot'), 'mcp');
122
- if (!existsSync(mcpDir))
122
+ if (!await stat(mcpDir).then(() => true).catch(() => false))
123
123
  return [];
124
124
  const suggestions = [];
125
125
  try {
126
- const entries = readdirSync(mcpDir);
126
+ const entries = await readdir(mcpDir);
127
127
  for (const entry of entries) {
128
128
  const entryPath = join(mcpDir, entry);
129
129
  try {
130
- const stat = statSync(entryPath);
131
- if (stat.isDirectory()) {
130
+ const entryStat = await stat(entryPath);
131
+ if (entryStat.isDirectory()) {
132
132
  const candidates = ['index.js', 'index.ts', 'server.js', 'server.ts'];
133
133
  for (const candidate of candidates) {
134
134
  const candidatePath = join(entryPath, candidate);
135
- if (existsSync(candidatePath)) {
135
+ if (await stat(candidatePath).then(() => true).catch(() => false)) {
136
136
  if (knownNames.has(entry))
137
137
  break;
138
138
  const runtime = candidate.endsWith('.ts') ? 'bun' : 'node';
@@ -141,7 +141,7 @@ function scanGoodvibesMcpDir(roots, knownNames) {
141
141
  }
142
142
  }
143
143
  }
144
- else if (stat.isFile()) {
144
+ else if (entryStat.isFile()) {
145
145
  // Standalone script: name.js or name.ts
146
146
  if (!entry.endsWith('.js') && !entry.endsWith('.ts'))
147
147
  continue;
@@ -165,10 +165,10 @@ function scanGoodvibesMcpDir(roots, knownNames) {
165
165
  /**
166
166
  * Check for locally-installed npx MCP packages not already registered.
167
167
  */
168
- function scanNpxMcpPackages(roots, knownNames) {
168
+ async function scanNpxMcpPackages(roots, knownNames) {
169
169
  const suggestions = [];
170
170
  for (const pkg of KNOWN_NPX_MCP_PACKAGES) {
171
- const binPath = findLocalNpxBin(roots.workingDirectory, pkg);
171
+ const binPath = await findLocalNpxBin(roots.workingDirectory, pkg);
172
172
  if (!binPath)
173
173
  continue;
174
174
  const serverName = deriveServerName(pkg);
@@ -202,15 +202,21 @@ export async function scanMcpServers(roots, registeredNames = new Set()) {
202
202
  }
203
203
  }
204
204
  };
205
+ // Run all three scanners in parallel — they are independent
206
+ const [projectResults, goodvibesResults, npxResults] = await Promise.all([
207
+ scanProjectMcpDir(roots, registeredNames),
208
+ scanGoodvibesMcpDir(roots, registeredNames),
209
+ scanNpxMcpPackages(roots, registeredNames),
210
+ ]);
205
211
  // 1. Project .mcp/ directory
206
212
  locationsScanned++;
207
- addSuggestions(scanProjectMcpDir(roots, registeredNames));
213
+ addSuggestions(projectResults);
208
214
  // 2. ~/.goodvibes/<surface>/mcp/ user-global directory
209
215
  locationsScanned++;
210
- addSuggestions(scanGoodvibesMcpDir(roots, registeredNames));
216
+ addSuggestions(goodvibesResults);
211
217
  // 3. Locally installed npx MCP packages
212
218
  locationsScanned++;
213
- addSuggestions(scanNpxMcpPackages(roots, registeredNames));
219
+ addSuggestions(npxResults);
214
220
  logger.debug('[mcp-scanner] Scan complete', {
215
221
  locationsScanned,
216
222
  suggestions: suggestions.length,
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/discovery/scanner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAOlE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;AAEtJ,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,KAAK,cAAc,GAAG,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,GAAG;IAC9D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AAUF,iGAAiG;AACjG,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,gBAAgB,EAAE,CAiBhF;AAED,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,IAAI,CA+BzF;AAED,sEAAsE;AACtE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAcrH;AAoMD;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA0KjC;AA4MD;;GAEG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACtD,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAkC7B;AAMD;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CASzD;AAED;;;GAGG;AACH,wBAAsB,IAAI,CACxB,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACtD,OAAO,CAAC,UAAU,CAAC,CA8BrB"}
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/discovery/scanner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAQlE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;AAEtJ,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,KAAK,cAAc,GAAG,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,GAAG;IAC9D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AAUF,iGAAiG;AACjG,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,gBAAgB,EAAE,CAiBhF;AAED,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAgCzF;AAED,sEAAsE;AACtE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAerH;AAgND;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA0KjC;AA4MD;;GAEG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACtD,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAkC7B;AAMD;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CASzD;AAED;;;GAGG;AACH,wBAAsB,IAAI,CACxB,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACtD,OAAO,CAAC,UAAU,CAAC,CA8BrB"}
@@ -3,7 +3,9 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
3
3
  import { dirname } from 'node:path';
4
4
  import { logger } from '../utils/logger.js';
5
5
  import { discoverContextWindows } from '../providers/context-discovery.js';
6
+ import { WELL_KNOWN_LOCAL_PORTS } from '../providers/well-known-endpoints.js';
6
7
  import { resolveSurfaceDirectory } from '../runtime/surface-root.js';
8
+ import { instrumentedFetch } from '../utils/fetch-with-timeout.js';
7
9
  function getPersistedPath(roots) {
8
10
  return resolveSurfaceDirectory(roots.homeDirectory, roots.surfaceRoot, 'discovered-providers.json');
9
11
  }
@@ -57,8 +59,9 @@ export function persistProviders(roots, servers) {
57
59
  mkdirSync(dirname(persistedPath), { recursive: true });
58
60
  writeFileSync(persistedPath, JSON.stringify([...byKey.values()], null, 2) + '\n', 'utf-8');
59
61
  }
60
- catch {
61
- // Non-fatal — persistence is best-effort
62
+ catch (err) {
63
+ // OBS-11: Non-fatal — persistence is best-effort
64
+ logger.debug('[Scanner] persistProviders failed (non-fatal)', { error: String(err) });
62
65
  }
63
66
  }
64
67
  /** Remove specific servers from the persisted file (by host:port). */
@@ -77,14 +80,27 @@ export function removePersistedProviders(roots, toRemove) {
77
80
  const filtered = current.filter(s => !removeKeys.has(`${s.host}:${s.port}`));
78
81
  writeFileSync(persistedPath, JSON.stringify(filtered, null, 2) + '\n', 'utf-8');
79
82
  }
80
- catch {
81
- // Non-fatal
83
+ catch (err) {
84
+ // OBS-11: Non-fatal — removal from persisted file failed
85
+ logger.debug('[Scanner] removePersistedProviders failed (non-fatal)', { error: String(err) });
82
86
  }
83
87
  }
84
88
  // ---------------------------------------------------------------------------
85
89
  // Constants
86
90
  // ---------------------------------------------------------------------------
87
- const KNOWN_PORTS = [1234, 1337, 2242, 4891, 5000, 5001, 7860, 8000, 8001, 8080, 11434];
91
+ const KNOWN_PORTS = [
92
+ WELL_KNOWN_LOCAL_PORTS.lmStudio,
93
+ WELL_KNOWN_LOCAL_PORTS.jan,
94
+ WELL_KNOWN_LOCAL_PORTS.aphrodite,
95
+ WELL_KNOWN_LOCAL_PORTS.gpt4all,
96
+ 5000,
97
+ WELL_KNOWN_LOCAL_PORTS.koboldCpp,
98
+ 7860,
99
+ 8000,
100
+ 8001,
101
+ WELL_KNOWN_LOCAL_PORTS.llamaCpp,
102
+ WELL_KNOWN_LOCAL_PORTS.ollama,
103
+ ];
88
104
  const PROBE_TIMEOUT_MS = 200;
89
105
  const MAX_CONCURRENT_PROBES = 50;
90
106
  const METADATA_TIMEOUT_MS = 2000;
@@ -152,7 +168,7 @@ async function probeHost(host, port) {
152
168
  }
153
169
  async function tryFetch(url) {
154
170
  try {
155
- const res = await fetch(url, {
171
+ const res = await instrumentedFetch(url, {
156
172
  signal: AbortSignal.timeout(PROBE_TIMEOUT_MS),
157
173
  });
158
174
  if (!res.ok)
@@ -200,17 +216,17 @@ function identifyServer(port, headers, responseBody) {
200
216
  .map((item) => String(item.id))
201
217
  .join(' ');
202
218
  }
203
- if (port === 11434)
219
+ if (port === WELL_KNOWN_LOCAL_PORTS.ollama)
204
220
  return 'ollama';
205
- if (port === 1337)
221
+ if (port === WELL_KNOWN_LOCAL_PORTS.jan)
206
222
  return 'jan';
207
- if (port === 4891)
223
+ if (port === WELL_KNOWN_LOCAL_PORTS.gpt4all)
208
224
  return 'gpt4all';
209
- if (port === 5001)
225
+ if (port === WELL_KNOWN_LOCAL_PORTS.koboldCpp)
210
226
  return 'koboldcpp';
211
- if (port === 2242)
227
+ if (port === WELL_KNOWN_LOCAL_PORTS.aphrodite)
212
228
  return 'aphrodite';
213
- if (port === 1234 || headerValues.includes('lmstudio') || modelIds.includes('lmstudio')) {
229
+ if (port === WELL_KNOWN_LOCAL_PORTS.lmStudio || headerValues.includes('lmstudio') || modelIds.includes('lmstudio')) {
214
230
  return 'lm-studio';
215
231
  }
216
232
  if (Object.keys(headers).some((k) => k.startsWith('x-vllm')))
@@ -240,7 +256,7 @@ export async function fetchModelContextWindows(host, port, serverType, models) {
240
256
  // Ollama: POST /api/show for each model — parallel to avoid blocking pool slot
241
257
  await Promise.allSettled(models.map(async (model) => {
242
258
  try {
243
- const res = await fetch(`http://${host}:${port}/api/show`, {
259
+ const res = await instrumentedFetch(`http://${host}:${port}/api/show`, {
244
260
  method: 'POST',
245
261
  headers: { 'Content-Type': 'application/json' },
246
262
  body: JSON.stringify({ name: model }),
@@ -281,7 +297,7 @@ export async function fetchModelContextWindows(host, port, serverType, models) {
281
297
  // vLLM: GET /v1/models/{id} returns max_model_len — parallel to avoid blocking pool slot
282
298
  await Promise.allSettled(models.map(async (model) => {
283
299
  try {
284
- const res = await fetch(`http://${host}:${port}/v1/models/${encodeURIComponent(model)}`, {
300
+ const res = await instrumentedFetch(`http://${host}:${port}/v1/models/${encodeURIComponent(model)}`, {
285
301
  signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
286
302
  });
287
303
  if (!res.ok)
@@ -301,7 +317,7 @@ export async function fetchModelContextWindows(host, port, serverType, models) {
301
317
  case 'llamacpp': {
302
318
  // llama.cpp: GET /props returns default_generation_settings.n_ctx (server-wide)
303
319
  try {
304
- const res = await fetch(`http://${host}:${port}/props`, {
320
+ const res = await instrumentedFetch(`http://${host}:${port}/props`, {
305
321
  signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
306
322
  });
307
323
  if (res.ok) {
@@ -349,7 +365,7 @@ export async function fetchModelContextWindows(host, port, serverType, models) {
349
365
  // Generic: try /v1/models/{id} for each model, look for common context length fields — parallel
350
366
  await Promise.allSettled(models.map(async (model) => {
351
367
  try {
352
- const res = await fetch(`http://${host}:${port}/v1/models/${encodeURIComponent(model)}`, {
368
+ const res = await instrumentedFetch(`http://${host}:${port}/v1/models/${encodeURIComponent(model)}`, {
353
369
  signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
354
370
  });
355
371
  if (!res.ok)
@@ -371,7 +387,7 @@ export async function fetchModelContextWindows(host, port, serverType, models) {
371
387
  // Fallback: try /props (llama.cpp-style) if no context windows found
372
388
  if (Object.keys(result).length === 0 && models.length > 0) {
373
389
  try {
374
- const res = await fetch(`http://${host}:${port}/props`, {
390
+ const res = await instrumentedFetch(`http://${host}:${port}/props`, {
375
391
  signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
376
392
  });
377
393
  if (res.ok) {
@@ -410,7 +426,7 @@ async function fetchModelOutputLimits(host, port, serverType, models) {
410
426
  // Ollama: POST /api/show for each model — look for num_predict in model_info or parameters
411
427
  await Promise.allSettled(models.map(async (model) => {
412
428
  try {
413
- const res = await fetch(`http://${host}:${port}/api/show`, {
429
+ const res = await instrumentedFetch(`http://${host}:${port}/api/show`, {
414
430
  method: 'POST',
415
431
  headers: { 'Content-Type': 'application/json' },
416
432
  body: JSON.stringify({ name: model }),
@@ -450,7 +466,7 @@ async function fetchModelOutputLimits(host, port, serverType, models) {
450
466
  // vLLM: GET /v1/models/{id} — look for max_completion_tokens
451
467
  await Promise.allSettled(models.map(async (model) => {
452
468
  try {
453
- const res = await fetch(`http://${host}:${port}/v1/models/${encodeURIComponent(model)}`, {
469
+ const res = await instrumentedFetch(`http://${host}:${port}/v1/models/${encodeURIComponent(model)}`, {
454
470
  signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
455
471
  });
456
472
  if (!res.ok)
@@ -470,7 +486,7 @@ async function fetchModelOutputLimits(host, port, serverType, models) {
470
486
  case 'llamacpp': {
471
487
  // llama.cpp: GET /props — look for default_generation_settings.n_predict
472
488
  try {
473
- const res = await fetch(`http://${host}:${port}/props`, {
489
+ const res = await instrumentedFetch(`http://${host}:${port}/props`, {
474
490
  signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
475
491
  });
476
492
  if (res.ok) {
@@ -502,7 +518,7 @@ async function fetchModelOutputLimits(host, port, serverType, models) {
502
518
  // Generic: try /v1/models/{id} for each model, look for common output limit fields
503
519
  await Promise.allSettled(models.map(async (model) => {
504
520
  try {
505
- const res = await fetch(`http://${host}:${port}/v1/models/${encodeURIComponent(model)}`, {
521
+ const res = await instrumentedFetch(`http://${host}:${port}/v1/models/${encodeURIComponent(model)}`, {
506
522
  signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
507
523
  });
508
524
  if (!res.ok)
@@ -522,7 +538,7 @@ async function fetchModelOutputLimits(host, port, serverType, models) {
522
538
  // Fallback: try /props (llama.cpp-style) for n_predict if no output limits found
523
539
  if (Object.keys(result).length === 0 && models.length > 0) {
524
540
  try {
525
- const res = await fetch(`http://${host}:${port}/props`, {
541
+ const res = await instrumentedFetch(`http://${host}:${port}/props`, {
526
542
  signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
527
543
  });
528
544
  if (res.ok) {
@@ -12,7 +12,6 @@ export interface SessionExportData {
12
12
  /** ISO timestamp of export. */
13
13
  exportedAt?: string;
14
14
  }
15
- export declare function redactSensitiveData(text: string): string;
16
15
  /**
17
16
  * redactMessage - Deep-clone a message and redact all string fields that may
18
17
  * contain sensitive data (content, reasoning, tool arguments).
@@ -1 +1 @@
1
- {"version":3,"file":"session-export.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/export/session-export.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAIvG,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA8BD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMxD;AAID;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,aAAa,CAqB/D;AAID;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,aAAa,EAAE,EACzB,QAAQ,CAAC,EAAE,cAAc,EACzB,OAAO,GAAE,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,MAAM,CAwCR;AAqBD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,aAAa,EAAE,EACzB,QAAQ,CAAC,EAAE,cAAc,EACzB,OAAO,GAAE,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,MAAM,CAsBR;AAOD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,aAAa,EAAE,EACzB,QAAQ,CAAC,EAAE,cAAc,EACzB,OAAO,GAAE,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,MAAM,CA0JR;AAmQD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAG/F"}
1
+ {"version":3,"file":"session-export.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/export/session-export.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAKvG,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,aAAa,CAqB/D;AAID;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,aAAa,EAAE,EACzB,QAAQ,CAAC,EAAE,cAAc,EACzB,OAAO,GAAE,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,MAAM,CAwCR;AAqBD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,aAAa,EAAE,EACzB,QAAQ,CAAC,EAAE,cAAc,EACzB,OAAO,GAAE,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,MAAM,CAsBR;AAOD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,aAAa,EAAE,EACzB,QAAQ,CAAC,EAAE,cAAc,EACzB,OAAO,GAAE,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,MAAM,CA0JR;AAmQD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAG/F"}
@@ -1,38 +1,6 @@
1
1
  import { join } from 'node:path';
2
2
  import { exportToMarkdown, extractText } from './markdown.js';
3
- // ── Sensitive-data redaction ──────────────────────────────────────────────────
4
- /** Patterns that identify sensitive content — API keys and absolute paths. */
5
- const REDACT_PATTERNS = [
6
- // Generic API key patterns (sk-*, key-*, bearer tokens)
7
- { pattern: /\b(sk-[A-Za-z0-9_-]{20,})/g, replacement: '[REDACTED_API_KEY]' },
8
- { pattern: /\b(key-[A-Za-z0-9_-]{16,})/g, replacement: '[REDACTED_API_KEY]' },
9
- // Bearer / Authorization header values
10
- { pattern: /(Bearer\s+)[A-Za-z0-9._~+\/-]+=*/gi, replacement: '$1[REDACTED_TOKEN]' },
11
- // GitHub tokens
12
- { pattern: /\b(ghp_[A-Za-z0-9]{36,})/g, replacement: '[REDACTED_GITHUB_TOKEN]' },
13
- { pattern: /\b(gho_[A-Za-z0-9]{36,})/g, replacement: '[REDACTED_GITHUB_TOKEN]' },
14
- { pattern: /\b(github_pat_[A-Za-z0-9_]{36,})/g, replacement: '[REDACTED_GITHUB_TOKEN]' },
15
- // GitLab tokens
16
- { pattern: /\b(glpat-[A-Za-z0-9_-]{20,})/g, replacement: '[REDACTED_GITLAB_TOKEN]' },
17
- // Slack tokens
18
- { pattern: /\b(xoxb-[A-Za-z0-9-]{24,})/g, replacement: '[REDACTED_SLACK_TOKEN]' },
19
- { pattern: /\b(xoxp-[A-Za-z0-9-]{24,})/g, replacement: '[REDACTED_SLACK_TOKEN]' },
20
- // AWS access keys
21
- { pattern: /\b(AKIA[A-Z0-9]{16})\b/g, replacement: '[REDACTED_AWS_KEY]' },
22
- // Absolute Unix paths starting from home (e.g. /home/alice/projects/...)
23
- { pattern: /\/home\/[A-Za-z0-9_.-]+/g, replacement: '/home/[REDACTED]' },
24
- // Absolute Unix paths in /Users (macOS)
25
- { pattern: /\/Users\/[A-Za-z0-9_.-]+/g, replacement: '/Users/[REDACTED]' },
26
- // Windows user paths (C:\Users\username\...)
27
- { pattern: /[A-Za-z]:\\Users\\[A-Za-z0-9_.-]+/g, replacement: 'C:\\Users\\[REDACTED]' },
28
- ];
29
- export function redactSensitiveData(text) {
30
- let result = text;
31
- for (const { pattern, replacement } of REDACT_PATTERNS) {
32
- result = result.replace(pattern, replacement);
33
- }
34
- return result;
35
- }
3
+ import { redactSensitiveData } from '../utils/redaction.js';
36
4
  // ── Message redaction helper ─────────────────────────────────────────────────
37
5
  /**
38
6
  * redactMessage - Deep-clone a message and redact all string fields that may
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/hooks/runners/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAKzE;;;GAGG;AACH,wBAAsB,GAAG,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CA+DrF"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/hooks/runners/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAMzE;;;GAGG;AACH,wBAAsB,GAAG,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CA+DrF"}
@@ -1,6 +1,7 @@
1
1
  import { logger } from '../../utils/logger.js';
2
2
  import { summarizeError } from '../../utils/error-display.js';
3
3
  import { classifyHostTrustTier, extractHostname, emitSsrfDeny } from '../../tools/fetch/trust-tiers.js';
4
+ import { instrumentedFetch } from '../../utils/fetch-with-timeout.js';
4
5
  /**
5
6
  * HTTP hook runner.
6
7
  * POSTs the event JSON to the configured URL and parses the response as HookResult.
@@ -28,7 +29,7 @@ export async function run(hook, event) {
28
29
  const timer = setTimeout(() => controller.abort(), timeoutMs);
29
30
  let response;
30
31
  try {
31
- response = await fetch(url, {
32
+ response = await instrumentedFetch(url, {
32
33
  method: 'POST',
33
34
  headers: {
34
35
  'Content-Type': 'application/json',