@evalops/maestro 0.10.8 → 0.10.11

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 (1009) hide show
  1. package/README.md +3 -1
  2. package/dist/agent/action-approval.d.ts +6 -0
  3. package/dist/agent/action-approval.d.ts.map +1 -1
  4. package/dist/agent/action-approval.js.map +1 -1
  5. package/dist/agent/agent.d.ts +13 -1
  6. package/dist/agent/agent.d.ts.map +1 -1
  7. package/dist/agent/agent.js +368 -1
  8. package/dist/agent/agent.js.map +1 -1
  9. package/dist/agent/auto-compaction.d.ts +4 -4
  10. package/dist/agent/auto-compaction.d.ts.map +1 -1
  11. package/dist/agent/auto-compaction.js.map +1 -1
  12. package/dist/agent/compaction-cleanup.d.ts +2 -0
  13. package/dist/agent/compaction-cleanup.d.ts.map +1 -1
  14. package/dist/agent/compaction-cleanup.js +17 -2
  15. package/dist/agent/compaction-cleanup.js.map +1 -1
  16. package/dist/agent/compaction.d.ts +3 -1
  17. package/dist/agent/compaction.d.ts.map +1 -1
  18. package/dist/agent/compaction.js +10 -2
  19. package/dist/agent/compaction.js.map +1 -1
  20. package/dist/agent/context-manager.d.ts +4 -0
  21. package/dist/agent/context-manager.d.ts.map +1 -1
  22. package/dist/agent/context-manager.js +8 -0
  23. package/dist/agent/context-manager.js.map +1 -1
  24. package/dist/agent/context-providers.d.ts +2 -0
  25. package/dist/agent/context-providers.d.ts.map +1 -1
  26. package/dist/agent/context-providers.js +3 -2
  27. package/dist/agent/context-providers.js.map +1 -1
  28. package/dist/agent/providers/google-gemini-cli.js +17 -5
  29. package/dist/agent/providers/google.js +174 -144
  30. package/dist/agent/providers/openai-codex-responses.d.ts +4 -0
  31. package/dist/agent/providers/openai-codex-responses.d.ts.map +1 -0
  32. package/dist/agent/providers/openai-codex-responses.js +637 -0
  33. package/dist/agent/providers/openai-codex-responses.js.map +1 -0
  34. package/dist/agent/providers/openai-codex-session.d.ts +18 -0
  35. package/dist/agent/providers/openai-codex-session.d.ts.map +1 -0
  36. package/dist/agent/providers/openai-codex-session.js +53 -0
  37. package/dist/agent/providers/openai-codex-session.js.map +1 -0
  38. package/dist/agent/providers/openai-responses-sdk.d.ts.map +1 -1
  39. package/dist/agent/providers/openai-responses-sdk.js +16 -6
  40. package/dist/agent/providers/openai-responses-sdk.js.map +1 -1
  41. package/dist/agent/providers/openai-shared.d.ts +12 -5
  42. package/dist/agent/providers/openai-shared.d.ts.map +1 -1
  43. package/dist/agent/providers/openai-shared.js +291 -2
  44. package/dist/agent/providers/openai-shared.js.map +1 -1
  45. package/dist/agent/providers/openai.d.ts +1 -1
  46. package/dist/agent/providers/openai.d.ts.map +1 -1
  47. package/dist/agent/providers/openai.js +48 -20
  48. package/dist/agent/providers/openai.js.map +1 -1
  49. package/dist/agent/providers/vertex.js +7 -0
  50. package/dist/agent/tracing.d.ts +16 -5
  51. package/dist/agent/tracing.d.ts.map +1 -1
  52. package/dist/agent/tracing.js +44 -2
  53. package/dist/agent/tracing.js.map +1 -1
  54. package/dist/agent/transport/create-provider-stream.d.ts.map +1 -1
  55. package/dist/agent/transport/create-provider-stream.js +9 -0
  56. package/dist/agent/transport/create-provider-stream.js.map +1 -1
  57. package/dist/agent/transport/tool-execution-bridge.d.ts +86 -0
  58. package/dist/agent/transport/tool-execution-bridge.d.ts.map +1 -0
  59. package/dist/agent/transport/tool-execution-bridge.js +665 -0
  60. package/dist/agent/transport/tool-execution-bridge.js.map +1 -0
  61. package/dist/agent/transport/tool-execution.d.ts +3 -0
  62. package/dist/agent/transport/tool-execution.d.ts.map +1 -1
  63. package/dist/agent/transport/tool-execution.js +16 -1
  64. package/dist/agent/transport/tool-execution.js.map +1 -1
  65. package/dist/agent/transport/tool-safety-pipeline.d.ts +7 -1
  66. package/dist/agent/transport/tool-safety-pipeline.d.ts.map +1 -1
  67. package/dist/agent/transport/tool-safety-pipeline.js +207 -40
  68. package/dist/agent/transport/tool-safety-pipeline.js.map +1 -1
  69. package/dist/agent/transport/tool-update-queue.d.ts +2 -0
  70. package/dist/agent/transport/tool-update-queue.d.ts.map +1 -1
  71. package/dist/agent/transport/tool-update-queue.js.map +1 -1
  72. package/dist/agent/transport.d.ts +3 -0
  73. package/dist/agent/transport.d.ts.map +1 -1
  74. package/dist/agent/transport.js +96 -16
  75. package/dist/agent/transport.js.map +1 -1
  76. package/dist/agent/types.d.ts +50 -2
  77. package/dist/agent/types.d.ts.map +1 -1
  78. package/dist/agent/types.js.map +1 -1
  79. package/dist/approvals/platform-action-approval.d.ts +32 -0
  80. package/dist/approvals/platform-action-approval.d.ts.map +1 -0
  81. package/dist/approvals/platform-action-approval.js +210 -0
  82. package/dist/approvals/platform-action-approval.js.map +1 -0
  83. package/dist/approvals/service-client.d.ts +56 -0
  84. package/dist/approvals/service-client.d.ts.map +1 -0
  85. package/dist/approvals/service-client.js +316 -0
  86. package/dist/approvals/service-client.js.map +1 -0
  87. package/dist/audit/logger.d.ts +4 -4
  88. package/dist/bootstrap/auth-setup.d.ts +2 -2
  89. package/dist/bootstrap/auth-setup.d.ts.map +1 -1
  90. package/dist/bootstrap/auth-setup.js +4 -7
  91. package/dist/bootstrap/auth-setup.js.map +1 -1
  92. package/dist/cli/args.d.ts +2 -0
  93. package/dist/cli/args.d.ts.map +1 -1
  94. package/dist/cli/args.js +29 -0
  95. package/dist/cli/args.js.map +1 -1
  96. package/dist/cli/commands/codex.d.ts +2 -0
  97. package/dist/cli/commands/codex.d.ts.map +1 -0
  98. package/dist/cli/commands/codex.js +65 -0
  99. package/dist/cli/commands/codex.js.map +1 -0
  100. package/dist/cli/commands/config.js +1 -1
  101. package/dist/cli/commands/config.js.map +1 -1
  102. package/dist/cli/commands/evalops.d.ts +2 -0
  103. package/dist/cli/commands/evalops.d.ts.map +1 -0
  104. package/dist/cli/commands/evalops.js +74 -0
  105. package/dist/cli/commands/evalops.js.map +1 -0
  106. package/dist/cli/commands/hosted-runner.d.ts +23 -0
  107. package/dist/cli/commands/hosted-runner.d.ts.map +1 -0
  108. package/dist/cli/commands/hosted-runner.js +241 -0
  109. package/dist/cli/commands/hosted-runner.js.map +1 -0
  110. package/dist/cli/commands/init.d.ts +4 -0
  111. package/dist/cli/commands/init.d.ts.map +1 -0
  112. package/dist/cli/commands/init.js +140 -0
  113. package/dist/cli/commands/init.js.map +1 -0
  114. package/dist/cli/commands/memory.d.ts.map +1 -1
  115. package/dist/cli/commands/memory.js +23 -30
  116. package/dist/cli/commands/memory.js.map +1 -1
  117. package/dist/cli/commands/remote.d.ts +3 -0
  118. package/dist/cli/commands/remote.d.ts.map +1 -0
  119. package/dist/cli/commands/remote.js +631 -0
  120. package/dist/cli/commands/remote.js.map +1 -0
  121. package/dist/cli/commands/stats.d.ts +7 -0
  122. package/dist/cli/commands/stats.d.ts.map +1 -0
  123. package/dist/cli/commands/stats.js +167 -0
  124. package/dist/cli/commands/stats.js.map +1 -0
  125. package/dist/cli/headless-protocol.d.ts +16 -1
  126. package/dist/cli/headless-protocol.d.ts.map +1 -1
  127. package/dist/cli/headless-protocol.js +60 -4
  128. package/dist/cli/headless-protocol.js.map +1 -1
  129. package/dist/cli/headless.d.ts.map +1 -1
  130. package/dist/cli/headless.js +1 -0
  131. package/dist/cli/headless.js.map +1 -1
  132. package/dist/cli/help.d.ts.map +1 -1
  133. package/dist/cli/help.js +44 -1
  134. package/dist/cli/help.js.map +1 -1
  135. package/dist/cli/jsonl-writer.d.ts.map +1 -1
  136. package/dist/cli/jsonl-writer.js +19 -6
  137. package/dist/cli/jsonl-writer.js.map +1 -1
  138. package/dist/cli-tui/client-tools/client-tool-controller.d.ts.map +1 -1
  139. package/dist/cli-tui/client-tools/client-tool-controller.js +17 -1
  140. package/dist/cli-tui/client-tools/client-tool-controller.js.map +1 -1
  141. package/dist/cli-tui/commands/access-command.js +1 -1
  142. package/dist/cli-tui/commands/access-command.js.map +1 -1
  143. package/dist/cli-tui/commands/audit-command.js +1 -1
  144. package/dist/cli-tui/commands/audit-command.js.map +1 -1
  145. package/dist/cli-tui/commands/command-catalog.d.ts +29 -0
  146. package/dist/cli-tui/commands/command-catalog.d.ts.map +1 -0
  147. package/dist/cli-tui/commands/command-catalog.js +645 -0
  148. package/dist/cli-tui/commands/command-catalog.js.map +1 -0
  149. package/dist/cli-tui/commands/command-registry-adapter.d.ts +12 -0
  150. package/dist/cli-tui/commands/command-registry-adapter.d.ts.map +1 -0
  151. package/dist/cli-tui/commands/command-registry-adapter.js +120 -0
  152. package/dist/cli-tui/commands/command-registry-adapter.js.map +1 -0
  153. package/dist/cli-tui/commands/command-suite-catalog.d.ts +14 -0
  154. package/dist/cli-tui/commands/command-suite-catalog.d.ts.map +1 -0
  155. package/dist/cli-tui/commands/command-suite-catalog.js +147 -0
  156. package/dist/cli-tui/commands/command-suite-catalog.js.map +1 -0
  157. package/dist/cli-tui/commands/{grouped-command-handlers.d.ts → command-suite-handlers.d.ts} +27 -26
  158. package/dist/cli-tui/commands/command-suite-handlers.d.ts.map +1 -0
  159. package/dist/cli-tui/commands/command-suite-handlers.js +110 -0
  160. package/dist/cli-tui/commands/command-suite-handlers.js.map +1 -0
  161. package/dist/cli-tui/commands/hotkeys-command.d.ts +1 -1
  162. package/dist/cli-tui/commands/hotkeys-command.d.ts.map +1 -1
  163. package/dist/cli-tui/commands/hotkeys-command.js +2 -2
  164. package/dist/cli-tui/commands/hotkeys-command.js.map +1 -1
  165. package/dist/cli-tui/commands/limits-command.js +1 -1
  166. package/dist/cli-tui/commands/limits-command.js.map +1 -1
  167. package/dist/cli-tui/commands/pii-command.js +1 -1
  168. package/dist/cli-tui/commands/pii-command.js.map +1 -1
  169. package/dist/cli-tui/commands/registry.d.ts +1 -1
  170. package/dist/cli-tui/commands/registry.d.ts.map +1 -1
  171. package/dist/cli-tui/commands/registry.js +29 -921
  172. package/dist/cli-tui/commands/registry.js.map +1 -1
  173. package/dist/cli-tui/commands/{grouped → subcommands}/auth-commands.d.ts +2 -1
  174. package/dist/cli-tui/commands/subcommands/auth-commands.d.ts.map +1 -0
  175. package/dist/cli-tui/commands/{grouped → subcommands}/auth-commands.js +22 -6
  176. package/dist/cli-tui/commands/subcommands/auth-commands.js.map +1 -0
  177. package/dist/cli-tui/commands/{grouped → subcommands}/config-commands.d.ts +0 -1
  178. package/dist/cli-tui/commands/subcommands/config-commands.d.ts.map +1 -0
  179. package/dist/cli-tui/commands/{grouped → subcommands}/config-commands.js +2 -2
  180. package/dist/cli-tui/commands/subcommands/config-commands.js.map +1 -0
  181. package/dist/cli-tui/commands/{grouped → subcommands}/diag-commands.d.ts +1 -2
  182. package/dist/cli-tui/commands/subcommands/diag-commands.d.ts.map +1 -0
  183. package/dist/cli-tui/commands/{grouped → subcommands}/diag-commands.js +5 -7
  184. package/dist/cli-tui/commands/subcommands/diag-commands.js.map +1 -0
  185. package/dist/cli-tui/commands/{grouped → subcommands}/git-commands.d.ts +0 -2
  186. package/dist/cli-tui/commands/subcommands/git-commands.d.ts.map +1 -0
  187. package/dist/cli-tui/commands/{grouped → subcommands}/git-commands.js +2 -2
  188. package/dist/cli-tui/commands/subcommands/git-commands.js.map +1 -0
  189. package/dist/cli-tui/commands/{grouped → subcommands}/index.d.ts +2 -2
  190. package/dist/cli-tui/commands/subcommands/index.d.ts.map +1 -0
  191. package/dist/cli-tui/commands/{grouped → subcommands}/index.js +2 -2
  192. package/dist/cli-tui/commands/subcommands/index.js.map +1 -0
  193. package/dist/cli-tui/commands/{grouped → subcommands}/safety-commands.d.ts +0 -1
  194. package/dist/cli-tui/commands/subcommands/safety-commands.d.ts.map +1 -0
  195. package/dist/cli-tui/commands/{grouped → subcommands}/safety-commands.js +12 -12
  196. package/dist/cli-tui/commands/subcommands/safety-commands.js.map +1 -0
  197. package/dist/cli-tui/commands/{grouped → subcommands}/session-commands.d.ts +1 -2
  198. package/dist/cli-tui/commands/subcommands/session-commands.d.ts.map +1 -0
  199. package/dist/cli-tui/commands/{grouped → subcommands}/session-commands.js +3 -3
  200. package/dist/cli-tui/commands/subcommands/session-commands.js.map +1 -0
  201. package/dist/cli-tui/commands/{grouped → subcommands}/tools-commands.d.ts +0 -1
  202. package/dist/cli-tui/commands/subcommands/tools-commands.d.ts.map +1 -0
  203. package/dist/cli-tui/commands/{grouped → subcommands}/tools-commands.js +2 -2
  204. package/dist/cli-tui/commands/subcommands/tools-commands.js.map +1 -0
  205. package/dist/cli-tui/commands/{grouped → subcommands}/ui-commands.d.ts +0 -1
  206. package/dist/cli-tui/commands/subcommands/ui-commands.d.ts.map +1 -0
  207. package/dist/cli-tui/commands/{grouped → subcommands}/ui-commands.js +5 -5
  208. package/dist/cli-tui/commands/subcommands/ui-commands.js.map +1 -0
  209. package/dist/cli-tui/commands/{grouped → subcommands}/undo-commands.d.ts +1 -2
  210. package/dist/cli-tui/commands/subcommands/undo-commands.d.ts.map +1 -0
  211. package/dist/cli-tui/commands/{grouped → subcommands}/undo-commands.js +6 -6
  212. package/dist/cli-tui/commands/subcommands/undo-commands.js.map +1 -0
  213. package/dist/cli-tui/commands/subcommands/usage-commands.d.ts.map +1 -0
  214. package/dist/cli-tui/commands/{grouped → subcommands}/usage-commands.js +2 -2
  215. package/dist/cli-tui/commands/subcommands/usage-commands.js.map +1 -0
  216. package/dist/cli-tui/commands/{grouped → subcommands}/utils.d.ts +15 -15
  217. package/dist/cli-tui/commands/subcommands/utils.d.ts.map +1 -0
  218. package/dist/cli-tui/commands/{grouped → subcommands}/utils.js +13 -8
  219. package/dist/cli-tui/commands/subcommands/utils.js.map +1 -0
  220. package/dist/cli-tui/commands/types.d.ts +3 -3
  221. package/dist/cli-tui/commands/types.d.ts.map +1 -1
  222. package/dist/cli-tui/commands/types.js.map +1 -1
  223. package/dist/cli-tui/editor-view.d.ts +1 -1
  224. package/dist/cli-tui/editor-view.d.ts.map +1 -1
  225. package/dist/cli-tui/editor-view.js +1 -1
  226. package/dist/cli-tui/editor-view.js.map +1 -1
  227. package/dist/cli-tui/oauth/oauth-flow-controller.d.ts +4 -0
  228. package/dist/cli-tui/oauth/oauth-flow-controller.d.ts.map +1 -1
  229. package/dist/cli-tui/oauth/oauth-flow-controller.js +76 -5
  230. package/dist/cli-tui/oauth/oauth-flow-controller.js.map +1 -1
  231. package/dist/cli-tui/run/run-controller.d.ts +2 -2
  232. package/dist/cli-tui/run/run-controller.d.ts.map +1 -1
  233. package/dist/cli-tui/run/run-controller.js +3 -2
  234. package/dist/cli-tui/run/run-controller.js.map +1 -1
  235. package/dist/cli-tui/run/run-shell-command.d.ts.map +1 -1
  236. package/dist/cli-tui/run/run-shell-command.js +11 -3
  237. package/dist/cli-tui/run/run-shell-command.js.map +1 -1
  238. package/dist/cli-tui/run/streaming-shell-command.d.ts.map +1 -1
  239. package/dist/cli-tui/run/streaming-shell-command.js +11 -3
  240. package/dist/cli-tui/run/streaming-shell-command.js.map +1 -1
  241. package/dist/cli-tui/selectors/model-selector.d.ts.map +1 -1
  242. package/dist/cli-tui/selectors/model-selector.js +1 -0
  243. package/dist/cli-tui/selectors/model-selector.js.map +1 -1
  244. package/dist/cli-tui/tui-renderer/agent-event-bridge.d.ts +8 -0
  245. package/dist/cli-tui/tui-renderer/agent-event-bridge.d.ts.map +1 -1
  246. package/dist/cli-tui/tui-renderer/agent-event-bridge.js +23 -2
  247. package/dist/cli-tui/tui-renderer/agent-event-bridge.js.map +1 -1
  248. package/dist/cli-tui/tui-renderer/command-registry-options.d.ts +3 -3
  249. package/dist/cli-tui/tui-renderer/command-registry-options.d.ts.map +1 -1
  250. package/dist/cli-tui/tui-renderer/command-registry-options.js +12 -2
  251. package/dist/cli-tui/tui-renderer/command-registry-options.js.map +1 -1
  252. package/dist/cli-tui/tui-renderer/command-suite-wiring.d.ts +32 -0
  253. package/dist/cli-tui/tui-renderer/command-suite-wiring.d.ts.map +1 -0
  254. package/dist/cli-tui/tui-renderer/command-suite-wiring.js +108 -0
  255. package/dist/cli-tui/tui-renderer/command-suite-wiring.js.map +1 -0
  256. package/dist/cli-tui/tui-renderer/input-controller.d.ts +2 -2
  257. package/dist/cli-tui/tui-renderer/input-controller.d.ts.map +1 -1
  258. package/dist/cli-tui/tui-renderer/input-controller.js +2 -2
  259. package/dist/cli-tui/tui-renderer/input-controller.js.map +1 -1
  260. package/dist/cli-tui/tui-renderer/ui-state-controller.d.ts +1 -1
  261. package/dist/cli-tui/tui-renderer/ui-state-controller.js +1 -1
  262. package/dist/cli-tui/tui-renderer/ui-state-controller.js.map +1 -1
  263. package/dist/cli-tui/tui-renderer.d.ts +1 -3
  264. package/dist/cli-tui/tui-renderer.d.ts.map +1 -1
  265. package/dist/cli-tui/tui-renderer.js +37 -83
  266. package/dist/cli-tui/tui-renderer.js.map +1 -1
  267. package/dist/cli-tui/utils/runtime-badges.d.ts +8 -0
  268. package/dist/cli-tui/utils/runtime-badges.d.ts.map +1 -1
  269. package/dist/cli-tui/utils/runtime-badges.js +58 -0
  270. package/dist/cli-tui/utils/runtime-badges.js.map +1 -1
  271. package/dist/cli.js +42555 -23133
  272. package/dist/cli.js.map +1 -1
  273. package/dist/config/env-vars.d.ts +4 -0
  274. package/dist/config/env-vars.d.ts.map +1 -1
  275. package/dist/config/env-vars.js +4 -0
  276. package/dist/config/env-vars.js.map +1 -1
  277. package/dist/config/feature-flags.d.ts +44 -0
  278. package/dist/config/feature-flags.d.ts.map +1 -1
  279. package/dist/config/feature-flags.js +214 -0
  280. package/dist/config/feature-flags.js.map +1 -1
  281. package/dist/connectors/service-client.d.ts +98 -0
  282. package/dist/connectors/service-client.d.ts.map +1 -0
  283. package/dist/connectors/service-client.js +459 -0
  284. package/dist/connectors/service-client.js.map +1 -0
  285. package/dist/conversation/render-model.d.ts.map +1 -1
  286. package/dist/conversation/render-model.js +53 -3
  287. package/dist/conversation/render-model.js.map +1 -1
  288. package/dist/db/health.d.ts +8 -0
  289. package/dist/db/health.d.ts.map +1 -0
  290. package/dist/db/health.js +64 -0
  291. package/dist/db/health.js.map +1 -0
  292. package/dist/db/migrate.d.ts +301 -0
  293. package/dist/db/migrate.d.ts.map +1 -1
  294. package/dist/db/migrate.js +186 -0
  295. package/dist/db/migrate.js.map +1 -1
  296. package/dist/db/migrations/0000_initial.sql +308 -0
  297. package/dist/db/migrations/0001_shared_sessions.sql +18 -0
  298. package/dist/db/migrations/0002_usage_metrics.sql +28 -0
  299. package/dist/db/migrations/0003_execution_traces.sql +18 -0
  300. package/dist/db/migrations/0004_workspace_config.sql +11 -0
  301. package/dist/db/migrations/0005_revenue_attribution.sql +31 -0
  302. package/dist/db/migrations/0006_hosted_session_storage.sql +51 -0
  303. package/dist/db/migrations/0007_reconcile_legacy_audit_hash_cache.sql +24 -0
  304. package/dist/db/migrations/0008_reconcile_legacy_webhook_deliveries.sql +290 -0
  305. package/dist/db/migrations/meta/0000_snapshot.json +2438 -0
  306. package/dist/db/migrations/meta/_journal.json +69 -0
  307. package/dist/db/schema.d.ts +2232 -844
  308. package/dist/db/schema.d.ts.map +1 -1
  309. package/dist/db/schema.js +187 -1
  310. package/dist/db/schema.js.map +1 -1
  311. package/dist/evalops/agent-bootstrap.d.ts +73 -0
  312. package/dist/evalops/agent-bootstrap.d.ts.map +1 -0
  313. package/dist/evalops/agent-bootstrap.js +380 -0
  314. package/dist/evalops/agent-bootstrap.js.map +1 -0
  315. package/dist/export-html.d.ts.map +1 -1
  316. package/dist/export-html.js +7 -4
  317. package/dist/export-html.js.map +1 -1
  318. package/dist/headless/utility-command-manager.d.ts +2 -1
  319. package/dist/headless/utility-command-manager.d.ts.map +1 -1
  320. package/dist/headless/utility-command-manager.js +12 -6
  321. package/dist/headless/utility-command-manager.js.map +1 -1
  322. package/dist/headless/utility-file-read.d.ts +1 -0
  323. package/dist/headless/utility-file-read.d.ts.map +1 -1
  324. package/dist/headless/utility-file-read.js +5 -1
  325. package/dist/headless/utility-file-read.js.map +1 -1
  326. package/dist/headless/utility-file-search.d.ts +1 -0
  327. package/dist/headless/utility-file-search.d.ts.map +1 -1
  328. package/dist/headless/utility-file-search.js +4 -1
  329. package/dist/headless/utility-file-search.js.map +1 -1
  330. package/dist/headless/utility-file-watch-manager.d.ts +2 -1
  331. package/dist/headless/utility-file-watch-manager.d.ts.map +1 -1
  332. package/dist/headless/utility-file-watch-manager.js +6 -2
  333. package/dist/headless/utility-file-watch-manager.js.map +1 -1
  334. package/dist/headless/workspace-root.d.ts +8 -0
  335. package/dist/headless/workspace-root.d.ts.map +1 -0
  336. package/dist/headless/workspace-root.js +74 -0
  337. package/dist/headless/workspace-root.js.map +1 -0
  338. package/dist/hooks/notification-hooks.d.ts +5 -0
  339. package/dist/hooks/notification-hooks.d.ts.map +1 -1
  340. package/dist/hooks/notification-hooks.js +4 -0
  341. package/dist/hooks/notification-hooks.js.map +1 -1
  342. package/dist/lsp/diagnostic-deltas.d.ts +20 -0
  343. package/dist/lsp/diagnostic-deltas.d.ts.map +1 -0
  344. package/dist/lsp/diagnostic-deltas.js +92 -0
  345. package/dist/lsp/diagnostic-deltas.js.map +1 -0
  346. package/dist/lsp/diagnostic-repair.d.ts +48 -0
  347. package/dist/lsp/diagnostic-repair.d.ts.map +1 -0
  348. package/dist/lsp/diagnostic-repair.js +143 -0
  349. package/dist/lsp/diagnostic-repair.js.map +1 -0
  350. package/dist/main.d.ts.map +1 -1
  351. package/dist/main.js +127 -37
  352. package/dist/main.js.map +1 -1
  353. package/dist/mcp/config.d.ts +4 -2
  354. package/dist/mcp/config.d.ts.map +1 -1
  355. package/dist/mcp/config.js +58 -14
  356. package/dist/mcp/config.js.map +1 -1
  357. package/dist/mcp/index.d.ts +1 -0
  358. package/dist/mcp/index.d.ts.map +1 -1
  359. package/dist/mcp/index.js +1 -0
  360. package/dist/mcp/index.js.map +1 -1
  361. package/dist/mcp/manager.d.ts +1 -0
  362. package/dist/mcp/manager.d.ts.map +1 -1
  363. package/dist/mcp/manager.js +1 -0
  364. package/dist/mcp/manager.js.map +1 -1
  365. package/dist/mcp/platform-plugin.d.ts +3 -0
  366. package/dist/mcp/platform-plugin.d.ts.map +1 -0
  367. package/dist/mcp/platform-plugin.js +117 -0
  368. package/dist/mcp/platform-plugin.js.map +1 -0
  369. package/dist/mcp/tool-bridge.d.ts +15 -0
  370. package/dist/mcp/tool-bridge.d.ts.map +1 -1
  371. package/dist/mcp/tool-bridge.js +194 -6
  372. package/dist/mcp/tool-bridge.js.map +1 -1
  373. package/dist/memory/platform-memory-client.d.ts +130 -0
  374. package/dist/memory/platform-memory-client.d.ts.map +1 -0
  375. package/dist/memory/platform-memory-client.js +330 -0
  376. package/dist/memory/platform-memory-client.js.map +1 -0
  377. package/dist/memory/service-client.d.ts.map +1 -1
  378. package/dist/memory/service-client.js +1 -2
  379. package/dist/memory/service-client.js.map +1 -1
  380. package/dist/models/builtin.d.ts.map +1 -1
  381. package/dist/models/builtin.js +137 -0
  382. package/dist/models/builtin.js.map +1 -1
  383. package/dist/models/config-loader.d.ts +10 -10
  384. package/dist/models/config-loader.d.ts.map +1 -1
  385. package/dist/models/config-loader.js +1 -0
  386. package/dist/models/config-loader.js.map +1 -1
  387. package/dist/models/registry.d.ts +1 -0
  388. package/dist/models/registry.d.ts.map +1 -1
  389. package/dist/models/registry.js +1 -0
  390. package/dist/models/registry.js.map +1 -1
  391. package/dist/oauth/connectors.d.ts +25 -0
  392. package/dist/oauth/connectors.d.ts.map +1 -0
  393. package/dist/oauth/connectors.js +253 -0
  394. package/dist/oauth/connectors.js.map +1 -0
  395. package/dist/oauth/device-identity.d.ts +18 -0
  396. package/dist/oauth/device-identity.d.ts.map +1 -0
  397. package/dist/oauth/device-identity.js +193 -0
  398. package/dist/oauth/device-identity.js.map +1 -0
  399. package/dist/oauth/evalops.d.ts.map +1 -1
  400. package/dist/oauth/evalops.js +74 -15
  401. package/dist/oauth/evalops.js.map +1 -1
  402. package/dist/oauth/index.d.ts +1 -1
  403. package/dist/oauth/index.d.ts.map +1 -1
  404. package/dist/oauth/index.js +31 -1
  405. package/dist/oauth/index.js.map +1 -1
  406. package/dist/oauth/openai-codex.d.ts +16 -0
  407. package/dist/oauth/openai-codex.d.ts.map +1 -0
  408. package/dist/oauth/openai-codex.js +300 -0
  409. package/dist/oauth/openai-codex.js.map +1 -0
  410. package/dist/opentelemetry.d.ts.map +1 -1
  411. package/dist/opentelemetry.js +9 -2
  412. package/dist/opentelemetry.js.map +1 -1
  413. package/dist/platform/agent-runtime-client.d.ts +279 -0
  414. package/dist/platform/agent-runtime-client.d.ts.map +1 -0
  415. package/dist/platform/agent-runtime-client.js +515 -0
  416. package/dist/platform/agent-runtime-client.js.map +1 -0
  417. package/dist/platform/cerebro-facts-client.d.ts +56 -0
  418. package/dist/platform/cerebro-facts-client.d.ts.map +1 -0
  419. package/dist/platform/cerebro-facts-client.js +297 -0
  420. package/dist/platform/cerebro-facts-client.js.map +1 -0
  421. package/dist/platform/client.d.ts +2 -1
  422. package/dist/platform/client.d.ts.map +1 -1
  423. package/dist/platform/client.js +9 -26
  424. package/dist/platform/client.js.map +1 -1
  425. package/dist/platform/core-services.d.ts +128 -0
  426. package/dist/platform/core-services.d.ts.map +1 -1
  427. package/dist/platform/core-services.js +128 -0
  428. package/dist/platform/core-services.js.map +1 -1
  429. package/dist/platform/maestro-timeline-client.d.ts +22 -0
  430. package/dist/platform/maestro-timeline-client.d.ts.map +1 -0
  431. package/dist/platform/maestro-timeline-client.js +373 -0
  432. package/dist/platform/maestro-timeline-client.js.map +1 -0
  433. package/dist/platform/tool-execution-client.d.ts +104 -0
  434. package/dist/platform/tool-execution-client.d.ts.map +1 -0
  435. package/dist/platform/tool-execution-client.js +284 -0
  436. package/dist/platform/tool-execution-client.js.map +1 -0
  437. package/dist/prompts/service-client.d.ts.map +1 -1
  438. package/dist/prompts/service-client.js +5 -2
  439. package/dist/prompts/service-client.js.map +1 -1
  440. package/dist/providers/anthropic-auth.d.ts.map +1 -1
  441. package/dist/providers/anthropic-auth.js +8 -6
  442. package/dist/providers/anthropic-auth.js.map +1 -1
  443. package/dist/providers/api-keys.d.ts +1 -0
  444. package/dist/providers/api-keys.d.ts.map +1 -1
  445. package/dist/providers/api-keys.js +5 -0
  446. package/dist/providers/api-keys.js.map +1 -1
  447. package/dist/providers/auth.d.ts +2 -1
  448. package/dist/providers/auth.d.ts.map +1 -1
  449. package/dist/providers/auth.js +26 -3
  450. package/dist/providers/auth.js.map +1 -1
  451. package/dist/remote-runner/attach-client.d.ts +41 -0
  452. package/dist/remote-runner/attach-client.d.ts.map +1 -0
  453. package/dist/remote-runner/attach-client.js +692 -0
  454. package/dist/remote-runner/attach-client.js.map +1 -0
  455. package/dist/remote-runner/client.d.ts +205 -0
  456. package/dist/remote-runner/client.d.ts.map +1 -0
  457. package/dist/remote-runner/client.js +633 -0
  458. package/dist/remote-runner/client.js.map +1 -0
  459. package/dist/safety/action-firewall.d.ts +6 -1
  460. package/dist/safety/action-firewall.d.ts.map +1 -1
  461. package/dist/safety/action-firewall.js +62 -26
  462. package/dist/safety/action-firewall.js.map +1 -1
  463. package/dist/safety/governance-service-client.d.ts +36 -0
  464. package/dist/safety/governance-service-client.d.ts.map +1 -0
  465. package/dist/safety/governance-service-client.js +279 -0
  466. package/dist/safety/governance-service-client.js.map +1 -0
  467. package/dist/safety/policy.d.ts +13 -2
  468. package/dist/safety/policy.d.ts.map +1 -1
  469. package/dist/safety/policy.js +474 -52
  470. package/dist/safety/policy.js.map +1 -1
  471. package/dist/sdk-tools.d.ts +21 -0
  472. package/dist/sdk-tools.d.ts.map +1 -1
  473. package/dist/sdk-tools.js +16 -0
  474. package/dist/sdk-tools.js.map +1 -1
  475. package/dist/server/app-context.d.ts +25 -0
  476. package/dist/server/app-context.d.ts.map +1 -1
  477. package/dist/server/app-context.js.map +1 -1
  478. package/dist/server/approval-service.d.ts +7 -8
  479. package/dist/server/approval-service.d.ts.map +1 -1
  480. package/dist/server/approval-service.js +12 -24
  481. package/dist/server/approval-service.js.map +1 -1
  482. package/dist/server/authz.d.ts +23 -2
  483. package/dist/server/authz.d.ts.map +1 -1
  484. package/dist/server/authz.js +153 -17
  485. package/dist/server/authz.js.map +1 -1
  486. package/dist/server/handlers/approvals.d.ts.map +1 -1
  487. package/dist/server/handlers/approvals.js +3 -10
  488. package/dist/server/handlers/approvals.js.map +1 -1
  489. package/dist/server/handlers/branch.d.ts.map +1 -1
  490. package/dist/server/handlers/branch.js +29 -20
  491. package/dist/server/handlers/branch.js.map +1 -1
  492. package/dist/server/handlers/bridge.d.ts.map +1 -1
  493. package/dist/server/handlers/bridge.js +3 -2
  494. package/dist/server/handlers/bridge.js.map +1 -1
  495. package/dist/server/handlers/chat-ws.d.ts.map +1 -1
  496. package/dist/server/handlers/chat-ws.js +23 -31
  497. package/dist/server/handlers/chat-ws.js.map +1 -1
  498. package/dist/server/handlers/chat.d.ts.map +1 -1
  499. package/dist/server/handlers/chat.js +105 -46
  500. package/dist/server/handlers/chat.js.map +1 -1
  501. package/dist/server/handlers/compliance.d.ts +3 -0
  502. package/dist/server/handlers/compliance.d.ts.map +1 -0
  503. package/dist/server/handlers/compliance.js +53 -0
  504. package/dist/server/handlers/compliance.js.map +1 -0
  505. package/dist/server/handlers/context.d.ts.map +1 -1
  506. package/dist/server/handlers/context.js +3 -8
  507. package/dist/server/handlers/context.js.map +1 -1
  508. package/dist/server/handlers/fleet.d.ts +4 -0
  509. package/dist/server/handlers/fleet.d.ts.map +1 -0
  510. package/dist/server/handlers/fleet.js +9 -0
  511. package/dist/server/handlers/fleet.js.map +1 -0
  512. package/dist/server/handlers/headless-sessions.d.ts +4 -0
  513. package/dist/server/handlers/headless-sessions.d.ts.map +1 -1
  514. package/dist/server/handlers/headless-sessions.js +168 -3
  515. package/dist/server/handlers/headless-sessions.js.map +1 -1
  516. package/dist/server/handlers/health.d.ts +31 -2
  517. package/dist/server/handlers/health.d.ts.map +1 -1
  518. package/dist/server/handlers/health.js +82 -8
  519. package/dist/server/handlers/health.js.map +1 -1
  520. package/dist/server/handlers/hosted-runner-drain.d.ts +128 -0
  521. package/dist/server/handlers/hosted-runner-drain.d.ts.map +1 -0
  522. package/dist/server/handlers/hosted-runner-drain.js +373 -0
  523. package/dist/server/handlers/hosted-runner-drain.js.map +1 -0
  524. package/dist/server/handlers/hosted-runner-identity.d.ts +17 -0
  525. package/dist/server/handlers/hosted-runner-identity.d.ts.map +1 -0
  526. package/dist/server/handlers/hosted-runner-identity.js +39 -0
  527. package/dist/server/handlers/hosted-runner-identity.js.map +1 -0
  528. package/dist/server/handlers/intelligent-router.d.ts +3 -0
  529. package/dist/server/handlers/intelligent-router.d.ts.map +1 -0
  530. package/dist/server/handlers/intelligent-router.js +141 -0
  531. package/dist/server/handlers/intelligent-router.js.map +1 -0
  532. package/dist/server/handlers/models.d.ts.map +1 -1
  533. package/dist/server/handlers/models.js +14 -0
  534. package/dist/server/handlers/models.js.map +1 -1
  535. package/dist/server/handlers/pending-requests.d.ts +8 -0
  536. package/dist/server/handlers/pending-requests.d.ts.map +1 -0
  537. package/dist/server/handlers/pending-requests.js +149 -0
  538. package/dist/server/handlers/pending-requests.js.map +1 -0
  539. package/dist/server/handlers/revenue-attribution.d.ts +3 -0
  540. package/dist/server/handlers/revenue-attribution.d.ts.map +1 -0
  541. package/dist/server/handlers/revenue-attribution.js +45 -0
  542. package/dist/server/handlers/revenue-attribution.js.map +1 -0
  543. package/dist/server/handlers/runtime-app-server-ws.d.ts +10 -0
  544. package/dist/server/handlers/runtime-app-server-ws.d.ts.map +1 -0
  545. package/dist/server/handlers/runtime-app-server-ws.js +206 -0
  546. package/dist/server/handlers/runtime-app-server-ws.js.map +1 -0
  547. package/dist/server/handlers/session-artifacts.js +2 -2
  548. package/dist/server/handlers/session-artifacts.js.map +1 -1
  549. package/dist/server/handlers/session-attachments.js +3 -3
  550. package/dist/server/handlers/session-attachments.js.map +1 -1
  551. package/dist/server/handlers/session-timeline.d.ts +11 -0
  552. package/dist/server/handlers/session-timeline.d.ts.map +1 -0
  553. package/dist/server/handlers/session-timeline.js +77 -0
  554. package/dist/server/handlers/session-timeline.js.map +1 -0
  555. package/dist/server/handlers/sessions.d.ts +11 -0
  556. package/dist/server/handlers/sessions.d.ts.map +1 -1
  557. package/dist/server/handlers/sessions.js +68 -100
  558. package/dist/server/handlers/sessions.js.map +1 -1
  559. package/dist/server/handlers/traces.d.ts +3 -0
  560. package/dist/server/handlers/traces.d.ts.map +1 -0
  561. package/dist/server/handlers/traces.js +60 -0
  562. package/dist/server/handlers/traces.js.map +1 -0
  563. package/dist/server/handlers/usage-analytics.d.ts +3 -0
  564. package/dist/server/handlers/usage-analytics.d.ts.map +1 -0
  565. package/dist/server/handlers/usage-analytics.js +40 -0
  566. package/dist/server/handlers/usage-analytics.js.map +1 -0
  567. package/dist/server/handlers/workspace-config.d.ts +3 -0
  568. package/dist/server/handlers/workspace-config.d.ts.map +1 -0
  569. package/dist/server/handlers/workspace-config.js +62 -0
  570. package/dist/server/handlers/workspace-config.js.map +1 -0
  571. package/dist/server/headless-in-process-host.d.ts +8 -1
  572. package/dist/server/headless-in-process-host.d.ts.map +1 -1
  573. package/dist/server/headless-in-process-host.js +6 -0
  574. package/dist/server/headless-in-process-host.js.map +1 -1
  575. package/dist/server/headless-runtime-service.d.ts +99 -1
  576. package/dist/server/headless-runtime-service.d.ts.map +1 -1
  577. package/dist/server/headless-runtime-service.js +286 -23
  578. package/dist/server/headless-runtime-service.js.map +1 -1
  579. package/dist/server/hosted-session-manager.d.ts +103 -0
  580. package/dist/server/hosted-session-manager.d.ts.map +1 -0
  581. package/dist/server/hosted-session-manager.js +629 -0
  582. package/dist/server/hosted-session-manager.js.map +1 -0
  583. package/dist/server/pending-request-payload.d.ts +4 -0
  584. package/dist/server/pending-request-payload.d.ts.map +1 -0
  585. package/dist/server/pending-request-payload.js +107 -0
  586. package/dist/server/pending-request-payload.js.map +1 -0
  587. package/dist/server/request-context.d.ts +4 -0
  588. package/dist/server/request-context.d.ts.map +1 -1
  589. package/dist/server/request-context.js +9 -0
  590. package/dist/server/request-context.js.map +1 -1
  591. package/dist/server/routes.d.ts.map +1 -1
  592. package/dist/server/routes.js +149 -1
  593. package/dist/server/routes.js.map +1 -1
  594. package/dist/server/runtime-ws-access.d.ts +16 -0
  595. package/dist/server/runtime-ws-access.d.ts.map +1 -0
  596. package/dist/server/runtime-ws-access.js +21 -0
  597. package/dist/server/runtime-ws-access.js.map +1 -0
  598. package/dist/server/server-middlewares.d.ts +1 -1
  599. package/dist/server/server-middlewares.d.ts.map +1 -1
  600. package/dist/server/server-middlewares.js +35 -27
  601. package/dist/server/server-middlewares.js.map +1 -1
  602. package/dist/server/server-request-manager.d.ts +8 -27
  603. package/dist/server/server-request-manager.d.ts.map +1 -1
  604. package/dist/server/server-request-manager.js +7 -0
  605. package/dist/server/server-request-manager.js.map +1 -1
  606. package/dist/server/server-utils.d.ts +2 -1
  607. package/dist/server/server-utils.d.ts.map +1 -1
  608. package/dist/server/server-utils.js +11 -1
  609. package/dist/server/server-utils.js.map +1 -1
  610. package/dist/server/session-event-env.d.ts +2 -0
  611. package/dist/server/session-event-env.d.ts.map +1 -0
  612. package/dist/server/session-event-env.js +8 -0
  613. package/dist/server/session-event-env.js.map +1 -0
  614. package/dist/server/session-initialization.d.ts +25 -4
  615. package/dist/server/session-initialization.d.ts.map +1 -1
  616. package/dist/server/session-initialization.js +22 -5
  617. package/dist/server/session-initialization.js.map +1 -1
  618. package/dist/server/session-scope.d.ts +4 -0
  619. package/dist/server/session-scope.d.ts.map +1 -1
  620. package/dist/server/session-scope.js +44 -4
  621. package/dist/server/session-scope.js.map +1 -1
  622. package/dist/server/session-timeline.d.ts +13 -0
  623. package/dist/server/session-timeline.d.ts.map +1 -0
  624. package/dist/server/session-timeline.js +566 -0
  625. package/dist/server/session-timeline.js.map +1 -0
  626. package/dist/services/compliance/controls.d.ts +6 -0
  627. package/dist/services/compliance/controls.d.ts.map +1 -0
  628. package/dist/services/compliance/controls.js +113 -0
  629. package/dist/services/compliance/controls.js.map +1 -0
  630. package/dist/services/compliance/index.d.ts +6 -0
  631. package/dist/services/compliance/index.d.ts.map +1 -0
  632. package/dist/services/compliance/index.js +5 -0
  633. package/dist/services/compliance/index.js.map +1 -0
  634. package/dist/services/compliance/normalize.d.ts +23 -0
  635. package/dist/services/compliance/normalize.d.ts.map +1 -0
  636. package/dist/services/compliance/normalize.js +226 -0
  637. package/dist/services/compliance/normalize.js.map +1 -0
  638. package/dist/services/compliance/recorder.d.ts +22 -0
  639. package/dist/services/compliance/recorder.d.ts.map +1 -0
  640. package/dist/services/compliance/recorder.js +89 -0
  641. package/dist/services/compliance/recorder.js.map +1 -0
  642. package/dist/services/compliance/service.d.ts +24 -0
  643. package/dist/services/compliance/service.d.ts.map +1 -0
  644. package/dist/services/compliance/service.js +426 -0
  645. package/dist/services/compliance/service.js.map +1 -0
  646. package/dist/services/compliance/types.d.ts +185 -0
  647. package/dist/services/compliance/types.d.ts.map +1 -0
  648. package/dist/services/compliance/types.js +2 -0
  649. package/dist/services/compliance/types.js.map +1 -0
  650. package/dist/services/intelligent-router/index.d.ts +5 -0
  651. package/dist/services/intelligent-router/index.d.ts.map +1 -0
  652. package/dist/services/intelligent-router/index.js +5 -0
  653. package/dist/services/intelligent-router/index.js.map +1 -0
  654. package/dist/services/intelligent-router/normalize.d.ts +9 -0
  655. package/dist/services/intelligent-router/normalize.d.ts.map +1 -0
  656. package/dist/services/intelligent-router/normalize.js +169 -0
  657. package/dist/services/intelligent-router/normalize.js.map +1 -0
  658. package/dist/services/intelligent-router/recorder.d.ts +24 -0
  659. package/dist/services/intelligent-router/recorder.d.ts.map +1 -0
  660. package/dist/services/intelligent-router/recorder.js +98 -0
  661. package/dist/services/intelligent-router/recorder.js.map +1 -0
  662. package/dist/services/intelligent-router/service.d.ts +22 -0
  663. package/dist/services/intelligent-router/service.d.ts.map +1 -0
  664. package/dist/services/intelligent-router/service.js +328 -0
  665. package/dist/services/intelligent-router/service.js.map +1 -0
  666. package/dist/services/intelligent-router/types.d.ts +98 -0
  667. package/dist/services/intelligent-router/types.d.ts.map +1 -0
  668. package/dist/services/intelligent-router/types.js +7 -0
  669. package/dist/services/intelligent-router/types.js.map +1 -0
  670. package/dist/services/revenue-attribution/index.d.ts +4 -0
  671. package/dist/services/revenue-attribution/index.d.ts.map +1 -0
  672. package/dist/services/revenue-attribution/index.js +4 -0
  673. package/dist/services/revenue-attribution/index.js.map +1 -0
  674. package/dist/services/revenue-attribution/normalize.d.ts +13 -0
  675. package/dist/services/revenue-attribution/normalize.d.ts.map +1 -0
  676. package/dist/services/revenue-attribution/normalize.js +155 -0
  677. package/dist/services/revenue-attribution/normalize.js.map +1 -0
  678. package/dist/services/revenue-attribution/service.d.ts +21 -0
  679. package/dist/services/revenue-attribution/service.d.ts.map +1 -0
  680. package/dist/services/revenue-attribution/service.js +248 -0
  681. package/dist/services/revenue-attribution/service.js.map +1 -0
  682. package/dist/services/revenue-attribution/types.d.ts +96 -0
  683. package/dist/services/revenue-attribution/types.d.ts.map +1 -0
  684. package/dist/services/revenue-attribution/types.js +7 -0
  685. package/dist/services/revenue-attribution/types.js.map +1 -0
  686. package/dist/services/traces/index.d.ts +5 -0
  687. package/dist/services/traces/index.d.ts.map +1 -0
  688. package/dist/services/traces/index.js +4 -0
  689. package/dist/services/traces/index.js.map +1 -0
  690. package/dist/services/traces/normalize.d.ts +20 -0
  691. package/dist/services/traces/normalize.d.ts.map +1 -0
  692. package/dist/services/traces/normalize.js +261 -0
  693. package/dist/services/traces/normalize.js.map +1 -0
  694. package/dist/services/traces/otel.d.ts +3 -0
  695. package/dist/services/traces/otel.d.ts.map +1 -0
  696. package/dist/services/traces/otel.js +173 -0
  697. package/dist/services/traces/otel.js.map +1 -0
  698. package/dist/services/traces/service.d.ts +17 -0
  699. package/dist/services/traces/service.d.ts.map +1 -0
  700. package/dist/services/traces/service.js +197 -0
  701. package/dist/services/traces/service.js.map +1 -0
  702. package/dist/services/traces/types.d.ts +130 -0
  703. package/dist/services/traces/types.d.ts.map +1 -0
  704. package/dist/services/traces/types.js +8 -0
  705. package/dist/services/traces/types.js.map +1 -0
  706. package/dist/services/usage-analytics/aggregation.d.ts +18 -0
  707. package/dist/services/usage-analytics/aggregation.d.ts.map +1 -0
  708. package/dist/services/usage-analytics/aggregation.js +130 -0
  709. package/dist/services/usage-analytics/aggregation.js.map +1 -0
  710. package/dist/services/usage-analytics/index.d.ts +5 -0
  711. package/dist/services/usage-analytics/index.d.ts.map +1 -0
  712. package/dist/services/usage-analytics/index.js +4 -0
  713. package/dist/services/usage-analytics/index.js.map +1 -0
  714. package/dist/services/usage-analytics/recorder.d.ts +16 -0
  715. package/dist/services/usage-analytics/recorder.d.ts.map +1 -0
  716. package/dist/services/usage-analytics/recorder.js +128 -0
  717. package/dist/services/usage-analytics/recorder.js.map +1 -0
  718. package/dist/services/usage-analytics/service.d.ts +15 -0
  719. package/dist/services/usage-analytics/service.d.ts.map +1 -0
  720. package/dist/services/usage-analytics/service.js +210 -0
  721. package/dist/services/usage-analytics/service.js.map +1 -0
  722. package/dist/services/usage-analytics/types.d.ts +80 -0
  723. package/dist/services/usage-analytics/types.d.ts.map +1 -0
  724. package/dist/services/usage-analytics/types.js +2 -0
  725. package/dist/services/usage-analytics/types.js.map +1 -0
  726. package/dist/services/workspace-config/index.d.ts +6 -0
  727. package/dist/services/workspace-config/index.d.ts.map +1 -0
  728. package/dist/services/workspace-config/index.js +5 -0
  729. package/dist/services/workspace-config/index.js.map +1 -0
  730. package/dist/services/workspace-config/middleware.d.ts +5 -0
  731. package/dist/services/workspace-config/middleware.d.ts.map +1 -0
  732. package/dist/services/workspace-config/middleware.js +98 -0
  733. package/dist/services/workspace-config/middleware.js.map +1 -0
  734. package/dist/services/workspace-config/normalize.d.ts +17 -0
  735. package/dist/services/workspace-config/normalize.d.ts.map +1 -0
  736. package/dist/services/workspace-config/normalize.js +148 -0
  737. package/dist/services/workspace-config/normalize.js.map +1 -0
  738. package/dist/services/workspace-config/policy.d.ts +16 -0
  739. package/dist/services/workspace-config/policy.d.ts.map +1 -0
  740. package/dist/services/workspace-config/policy.js +77 -0
  741. package/dist/services/workspace-config/policy.js.map +1 -0
  742. package/dist/services/workspace-config/service.d.ts +20 -0
  743. package/dist/services/workspace-config/service.d.ts.map +1 -0
  744. package/dist/services/workspace-config/service.js +162 -0
  745. package/dist/services/workspace-config/service.js.map +1 -0
  746. package/dist/services/workspace-config/types.d.ts +71 -0
  747. package/dist/services/workspace-config/types.d.ts.map +1 -0
  748. package/dist/services/workspace-config/types.js +2 -0
  749. package/dist/services/workspace-config/types.js.map +1 -0
  750. package/dist/session/manager.d.ts.map +1 -1
  751. package/dist/session/manager.js +10 -0
  752. package/dist/session/manager.js.map +1 -1
  753. package/dist/session/migration.d.ts.map +1 -1
  754. package/dist/session/migration.js +2 -1
  755. package/dist/session/migration.js.map +1 -1
  756. package/dist/session/session-memory.d.ts.map +1 -1
  757. package/dist/session/session-memory.js +7 -1
  758. package/dist/session/session-memory.js.map +1 -1
  759. package/dist/session/types.d.ts +1 -2
  760. package/dist/session/types.d.ts.map +1 -1
  761. package/dist/session/types.js +1 -22
  762. package/dist/session/types.js.map +1 -1
  763. package/dist/session/wire-format.d.ts +7 -0
  764. package/dist/session/wire-format.d.ts.map +1 -0
  765. package/dist/session/wire-format.generated.d.ts +95 -0
  766. package/dist/session/wire-format.generated.d.ts.map +1 -0
  767. package/dist/session/wire-format.generated.js +111 -0
  768. package/dist/session/wire-format.generated.js.map +1 -0
  769. package/dist/session/wire-format.js +145 -0
  770. package/dist/session/wire-format.js.map +1 -0
  771. package/dist/shared-memory/client.d.ts.map +1 -1
  772. package/dist/shared-memory/client.js +22 -22
  773. package/dist/shared-memory/client.js.map +1 -1
  774. package/dist/skills/artifact-metadata.d.ts +16 -0
  775. package/dist/skills/artifact-metadata.d.ts.map +1 -0
  776. package/dist/skills/artifact-metadata.js +86 -0
  777. package/dist/skills/artifact-metadata.js.map +1 -0
  778. package/dist/skills/loader.d.ts +2 -2
  779. package/dist/skills/loader.d.ts.map +1 -1
  780. package/dist/skills/loader.js +1 -0
  781. package/dist/skills/loader.js.map +1 -1
  782. package/dist/skills/service-client.d.ts +42 -0
  783. package/dist/skills/service-client.d.ts.map +1 -0
  784. package/dist/skills/service-client.js +258 -0
  785. package/dist/skills/service-client.js.map +1 -0
  786. package/dist/skills/tool.d.ts +3 -0
  787. package/dist/skills/tool.d.ts.map +1 -1
  788. package/dist/skills/tool.js +67 -5
  789. package/dist/skills/tool.js.map +1 -1
  790. package/dist/telemetry/index.d.ts +4 -0
  791. package/dist/telemetry/index.d.ts.map +1 -1
  792. package/dist/telemetry/index.js +5 -0
  793. package/dist/telemetry/index.js.map +1 -1
  794. package/dist/telemetry/maestro-event-bus.d.ts +440 -0
  795. package/dist/telemetry/maestro-event-bus.d.ts.map +1 -0
  796. package/dist/telemetry/maestro-event-bus.js +784 -0
  797. package/dist/telemetry/maestro-event-bus.js.map +1 -0
  798. package/dist/telemetry/maestro-event-catalog.d.ts +48 -0
  799. package/dist/telemetry/maestro-event-catalog.d.ts.map +1 -0
  800. package/dist/telemetry/maestro-event-catalog.js +69 -0
  801. package/dist/telemetry/maestro-event-catalog.js.map +1 -0
  802. package/dist/telemetry/maestro-platform-replay-fixture.d.ts +24 -0
  803. package/dist/telemetry/maestro-platform-replay-fixture.d.ts.map +1 -0
  804. package/dist/telemetry/maestro-platform-replay-fixture.js +400 -0
  805. package/dist/telemetry/maestro-platform-replay-fixture.js.map +1 -0
  806. package/dist/telemetry/maestro-publisher-conformance-fixture.d.ts +29 -0
  807. package/dist/telemetry/maestro-publisher-conformance-fixture.d.ts.map +1 -0
  808. package/dist/telemetry/maestro-publisher-conformance-fixture.js +240 -0
  809. package/dist/telemetry/maestro-publisher-conformance-fixture.js.map +1 -0
  810. package/dist/telemetry/meter-service-client.d.ts +0 -33
  811. package/dist/telemetry/meter-service-client.d.ts.map +1 -1
  812. package/dist/telemetry/meter-service-client.js +22 -50
  813. package/dist/telemetry/meter-service-client.js.map +1 -1
  814. package/dist/telemetry/turn-tracker.d.ts.map +1 -1
  815. package/dist/telemetry/turn-tracker.js +5 -5
  816. package/dist/telemetry/turn-tracker.js.map +1 -1
  817. package/dist/telemetry/wide-events.d.ts +8 -0
  818. package/dist/telemetry/wide-events.d.ts.map +1 -1
  819. package/dist/telemetry/wide-events.js +28 -0
  820. package/dist/telemetry/wide-events.js.map +1 -1
  821. package/dist/telemetry.d.ts +1 -1
  822. package/dist/telemetry.d.ts.map +1 -1
  823. package/dist/telemetry.js +14 -4
  824. package/dist/telemetry.js.map +1 -1
  825. package/dist/timeline/redaction.d.ts +5 -0
  826. package/dist/timeline/redaction.d.ts.map +1 -0
  827. package/dist/timeline/redaction.js +119 -0
  828. package/dist/timeline/redaction.js.map +1 -0
  829. package/dist/tools/ask-user.d.ts +26 -0
  830. package/dist/tools/ask-user.d.ts.map +1 -1
  831. package/dist/tools/ask-user.js +33 -1
  832. package/dist/tools/ask-user.js.map +1 -1
  833. package/dist/tools/background/task-types.d.ts +1 -1
  834. package/dist/tools/edit.d.ts +2 -0
  835. package/dist/tools/edit.d.ts.map +1 -1
  836. package/dist/tools/edit.js +27 -7
  837. package/dist/tools/edit.js.map +1 -1
  838. package/dist/tools/index.d.ts +9 -0
  839. package/dist/tools/index.d.ts.map +1 -1
  840. package/dist/tools/pipeline.d.ts.map +1 -1
  841. package/dist/tools/pipeline.js +16 -7
  842. package/dist/tools/pipeline.js.map +1 -1
  843. package/dist/tools/write.d.ts +2 -0
  844. package/dist/tools/write.d.ts.map +1 -1
  845. package/dist/tools/write.js +24 -6
  846. package/dist/tools/write.js.map +1 -1
  847. package/dist/tracking/cost-tracker.d.ts +15 -12
  848. package/dist/tracking/cost-tracker.d.ts.map +1 -1
  849. package/dist/tracking/cost-tracker.js +29 -40
  850. package/dist/tracking/cost-tracker.js.map +1 -1
  851. package/dist/utils/checkpoint-profiler.d.ts +29 -0
  852. package/dist/utils/checkpoint-profiler.d.ts.map +1 -0
  853. package/dist/utils/checkpoint-profiler.js +118 -0
  854. package/dist/utils/checkpoint-profiler.js.map +1 -0
  855. package/dist/utils/downstream-http.d.ts +21 -0
  856. package/dist/utils/downstream-http.d.ts.map +1 -0
  857. package/dist/utils/downstream-http.js +151 -0
  858. package/dist/utils/downstream-http.js.map +1 -0
  859. package/dist/utils/downstream.d.ts +18 -0
  860. package/dist/utils/downstream.d.ts.map +1 -0
  861. package/dist/utils/downstream.js +47 -0
  862. package/dist/utils/downstream.js.map +1 -0
  863. package/dist/utils/logger.d.ts +3 -1
  864. package/dist/utils/logger.d.ts.map +1 -1
  865. package/dist/utils/logger.js +12 -1
  866. package/dist/utils/logger.js.map +1 -1
  867. package/dist/utils/oauth-http.d.ts +8 -0
  868. package/dist/utils/oauth-http.d.ts.map +1 -0
  869. package/dist/utils/oauth-http.js +41 -0
  870. package/dist/utils/oauth-http.js.map +1 -0
  871. package/dist/utils/path-utils.d.ts +2 -0
  872. package/dist/utils/path-utils.d.ts.map +1 -0
  873. package/dist/utils/path-utils.js +12 -0
  874. package/dist/utils/path-utils.js.map +1 -0
  875. package/dist/utils/path-validation.d.ts +1 -1
  876. package/dist/utils/path-validation.d.ts.map +1 -1
  877. package/dist/utils/path-validation.js +3 -3
  878. package/dist/utils/path-validation.js.map +1 -1
  879. package/dist/version.json +2 -2
  880. package/dist/web-server.d.ts +7 -1
  881. package/dist/web-server.d.ts.map +1 -1
  882. package/dist/web-server.js +117 -15
  883. package/dist/web-server.js.map +1 -1
  884. package/dist/webhooks/delivery.d.ts.map +1 -1
  885. package/dist/webhooks/delivery.js +9 -12
  886. package/dist/webhooks/delivery.js.map +1 -1
  887. package/node_modules/@bufbuild/protobuf/dist/cjs/descriptors.d.ts +12 -5
  888. package/node_modules/@bufbuild/protobuf/dist/cjs/from-binary.js +7 -7
  889. package/node_modules/@bufbuild/protobuf/dist/cjs/from-json.d.ts +1 -1
  890. package/node_modules/@bufbuild/protobuf/dist/cjs/from-json.js +1 -1
  891. package/node_modules/@bufbuild/protobuf/dist/cjs/reflect/path.d.ts +1 -1
  892. package/node_modules/@bufbuild/protobuf/dist/cjs/registry.js +24 -1
  893. package/node_modules/@bufbuild/protobuf/dist/cjs/to-json.d.ts +1 -1
  894. package/node_modules/@bufbuild/protobuf/dist/cjs/to-json.js +9 -10
  895. package/node_modules/@bufbuild/protobuf/dist/cjs/types.d.ts +1 -1
  896. package/node_modules/@bufbuild/protobuf/dist/cjs/wire/binary-encoding.d.ts +9 -7
  897. package/node_modules/@bufbuild/protobuf/dist/cjs/wire/binary-encoding.js +18 -8
  898. package/node_modules/@bufbuild/protobuf/dist/cjs/wire/text-encoding.d.ts +4 -2
  899. package/node_modules/@bufbuild/protobuf/dist/cjs/wire/text-encoding.js +8 -1
  900. package/node_modules/@bufbuild/protobuf/dist/cjs/wkt/gen/google/protobuf/api_pb.d.ts +1 -1
  901. package/node_modules/@bufbuild/protobuf/dist/cjs/wkt/gen/google/protobuf/compiler/plugin_pb.d.ts +2 -2
  902. package/node_modules/@bufbuild/protobuf/dist/cjs/wkt/gen/google/protobuf/descriptor_pb.d.ts +37 -23
  903. package/node_modules/@bufbuild/protobuf/dist/cjs/wkt/gen/google/protobuf/descriptor_pb.js +1 -1
  904. package/node_modules/@bufbuild/protobuf/dist/cjs/wkt/gen/google/protobuf/field_mask_pb.d.ts +32 -36
  905. package/node_modules/@bufbuild/protobuf/dist/cjs/wkt/gen/google/protobuf/go_features_pb.d.ts +65 -0
  906. package/node_modules/@bufbuild/protobuf/dist/cjs/wkt/gen/google/protobuf/go_features_pb.js +38 -2
  907. package/node_modules/@bufbuild/protobuf/dist/cjs/wkt/gen/google/protobuf/timestamp_pb.d.ts +5 -5
  908. package/node_modules/@bufbuild/protobuf/dist/cjs/wkt/gen/google/protobuf/type_pb.d.ts +3 -3
  909. package/node_modules/@bufbuild/protobuf/dist/cjs/wkt/wrappers.d.ts +10 -0
  910. package/node_modules/@bufbuild/protobuf/dist/cjs/wkt/wrappers.js +24 -0
  911. package/node_modules/@bufbuild/protobuf/dist/esm/descriptors.d.ts +12 -5
  912. package/node_modules/@bufbuild/protobuf/dist/esm/from-binary.js +7 -7
  913. package/node_modules/@bufbuild/protobuf/dist/esm/from-json.d.ts +1 -1
  914. package/node_modules/@bufbuild/protobuf/dist/esm/from-json.js +2 -2
  915. package/node_modules/@bufbuild/protobuf/dist/esm/reflect/path.d.ts +1 -1
  916. package/node_modules/@bufbuild/protobuf/dist/esm/registry.js +24 -1
  917. package/node_modules/@bufbuild/protobuf/dist/esm/to-json.d.ts +1 -1
  918. package/node_modules/@bufbuild/protobuf/dist/esm/to-json.js +10 -11
  919. package/node_modules/@bufbuild/protobuf/dist/esm/types.d.ts +1 -1
  920. package/node_modules/@bufbuild/protobuf/dist/esm/wire/binary-encoding.d.ts +9 -7
  921. package/node_modules/@bufbuild/protobuf/dist/esm/wire/binary-encoding.js +18 -8
  922. package/node_modules/@bufbuild/protobuf/dist/esm/wire/text-encoding.d.ts +4 -2
  923. package/node_modules/@bufbuild/protobuf/dist/esm/wire/text-encoding.js +8 -1
  924. package/node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/api_pb.d.ts +1 -1
  925. package/node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/compiler/plugin_pb.d.ts +2 -2
  926. package/node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/descriptor_pb.d.ts +37 -23
  927. package/node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/descriptor_pb.js +1 -1
  928. package/node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/field_mask_pb.d.ts +32 -36
  929. package/node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/go_features_pb.d.ts +65 -0
  930. package/node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/go_features_pb.js +37 -1
  931. package/node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/timestamp_pb.d.ts +5 -5
  932. package/node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/type_pb.d.ts +3 -3
  933. package/node_modules/@bufbuild/protobuf/dist/esm/wkt/wrappers.d.ts +10 -0
  934. package/node_modules/@bufbuild/protobuf/dist/esm/wkt/wrappers.js +23 -0
  935. package/node_modules/@bufbuild/protobuf/package.json +1 -1
  936. package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.d.ts +305 -2
  937. package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.d.ts.map +1 -1
  938. package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.js +34 -4
  939. package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.js.map +1 -1
  940. package/node_modules/@evalops/contracts/dist/index.d.ts +88 -0
  941. package/node_modules/@evalops/contracts/dist/index.d.ts.map +1 -1
  942. package/node_modules/@evalops/contracts/dist/index.js +2 -0
  943. package/node_modules/@evalops/contracts/dist/index.js.map +1 -1
  944. package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.d.ts +77 -77
  945. package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.d.ts.map +1 -1
  946. package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.js +1 -1
  947. package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.js.map +1 -1
  948. package/node_modules/@evalops/contracts/dist/runtime-app-server.d.ts +182 -0
  949. package/node_modules/@evalops/contracts/dist/runtime-app-server.d.ts.map +1 -0
  950. package/node_modules/@evalops/contracts/dist/runtime-app-server.js +83 -0
  951. package/node_modules/@evalops/contracts/dist/runtime-app-server.js.map +1 -0
  952. package/node_modules/@evalops/contracts/dist/runtime-server-request.d.ts +133 -0
  953. package/node_modules/@evalops/contracts/dist/runtime-server-request.d.ts.map +1 -0
  954. package/node_modules/@evalops/contracts/dist/runtime-server-request.js +68 -0
  955. package/node_modules/@evalops/contracts/dist/runtime-server-request.js.map +1 -0
  956. package/node_modules/@evalops/contracts/dist/schemas.d.ts +178 -0
  957. package/node_modules/@evalops/contracts/dist/schemas.d.ts.map +1 -1
  958. package/node_modules/@evalops/contracts/dist/schemas.js +165 -0
  959. package/node_modules/@evalops/contracts/dist/schemas.js.map +1 -1
  960. package/node_modules/@evalops/contracts/dist/typebox-utils.d.ts +2 -0
  961. package/node_modules/@evalops/contracts/dist/typebox-utils.d.ts.map +1 -0
  962. package/node_modules/@evalops/contracts/dist/typebox-utils.js +5 -0
  963. package/node_modules/@evalops/contracts/dist/typebox-utils.js.map +1 -0
  964. package/node_modules/@evalops/contracts/dist/validators.d.ts +4 -1
  965. package/node_modules/@evalops/contracts/dist/validators.d.ts.map +1 -1
  966. package/node_modules/@evalops/contracts/dist/validators.js +4 -1
  967. package/node_modules/@evalops/contracts/dist/validators.js.map +1 -1
  968. package/node_modules/@evalops/contracts/package.json +1 -1
  969. package/node_modules/@evalops/tui/package.json +1 -1
  970. package/node_modules/string-width/index.js +93 -9
  971. package/node_modules/string-width/package.json +1 -1
  972. package/package.json +32 -25
  973. package/dist/cli-tui/commands/grouped/auth-commands.d.ts.map +0 -1
  974. package/dist/cli-tui/commands/grouped/auth-commands.js.map +0 -1
  975. package/dist/cli-tui/commands/grouped/config-commands.d.ts.map +0 -1
  976. package/dist/cli-tui/commands/grouped/config-commands.js.map +0 -1
  977. package/dist/cli-tui/commands/grouped/diag-commands.d.ts.map +0 -1
  978. package/dist/cli-tui/commands/grouped/diag-commands.js.map +0 -1
  979. package/dist/cli-tui/commands/grouped/git-commands.d.ts.map +0 -1
  980. package/dist/cli-tui/commands/grouped/git-commands.js.map +0 -1
  981. package/dist/cli-tui/commands/grouped/index.d.ts.map +0 -1
  982. package/dist/cli-tui/commands/grouped/index.js.map +0 -1
  983. package/dist/cli-tui/commands/grouped/safety-commands.d.ts.map +0 -1
  984. package/dist/cli-tui/commands/grouped/safety-commands.js.map +0 -1
  985. package/dist/cli-tui/commands/grouped/session-commands.d.ts.map +0 -1
  986. package/dist/cli-tui/commands/grouped/session-commands.js.map +0 -1
  987. package/dist/cli-tui/commands/grouped/tools-commands.d.ts.map +0 -1
  988. package/dist/cli-tui/commands/grouped/tools-commands.js.map +0 -1
  989. package/dist/cli-tui/commands/grouped/ui-commands.d.ts.map +0 -1
  990. package/dist/cli-tui/commands/grouped/ui-commands.js.map +0 -1
  991. package/dist/cli-tui/commands/grouped/undo-commands.d.ts.map +0 -1
  992. package/dist/cli-tui/commands/grouped/undo-commands.js.map +0 -1
  993. package/dist/cli-tui/commands/grouped/usage-commands.d.ts.map +0 -1
  994. package/dist/cli-tui/commands/grouped/usage-commands.js.map +0 -1
  995. package/dist/cli-tui/commands/grouped/utils.d.ts.map +0 -1
  996. package/dist/cli-tui/commands/grouped/utils.js.map +0 -1
  997. package/dist/cli-tui/commands/grouped-command-handlers.d.ts.map +0 -1
  998. package/dist/cli-tui/commands/grouped-command-handlers.js +0 -135
  999. package/dist/cli-tui/commands/grouped-command-handlers.js.map +0 -1
  1000. package/dist/cli-tui/tui-renderer/grouped-handlers-wiring.d.ts +0 -78
  1001. package/dist/cli-tui/tui-renderer/grouped-handlers-wiring.d.ts.map +0 -1
  1002. package/dist/cli-tui/tui-renderer/grouped-handlers-wiring.js +0 -129
  1003. package/dist/cli-tui/tui-renderer/grouped-handlers-wiring.js.map +0 -1
  1004. package/node_modules/@evalops/memory/dist/client.d.ts +0 -94
  1005. package/node_modules/@evalops/memory/dist/client.js +0 -503
  1006. package/node_modules/@evalops/memory/gen/proto/dist/memory/v1/memory_pb.d.ts +0 -608
  1007. package/node_modules/@evalops/memory/gen/proto/dist/memory/v1/memory_pb.js +0 -187
  1008. package/node_modules/@evalops/memory/package.json +0 -26
  1009. /package/dist/cli-tui/commands/{grouped → subcommands}/usage-commands.d.ts +0 -0
@@ -0,0 +1,151 @@
1
+ import { createLogger } from "./logger.js";
2
+ import { parseRetryAfter } from "./retry.js";
3
+ const logger = createLogger("runtime:downstream-http");
4
+ export class DownstreamHttpError extends Error {
5
+ constructor(message, serviceName, failureMode, retryable, timeoutMs) {
6
+ super(message);
7
+ this.serviceName = serviceName;
8
+ this.failureMode = failureMode;
9
+ this.retryable = retryable;
10
+ this.timeoutMs = timeoutMs;
11
+ this.name = "DownstreamHttpError";
12
+ }
13
+ }
14
+ function sleep(delayMs) {
15
+ return new Promise((resolve) => setTimeout(resolve, delayMs));
16
+ }
17
+ function defaultShouldRetryStatus(status) {
18
+ return status === 408 || status === 429 || status >= 500;
19
+ }
20
+ function isRetryableFetchError(error) {
21
+ if (error.name === "AbortError") {
22
+ return true;
23
+ }
24
+ const message = error.message.toLowerCase();
25
+ return (message.includes("timeout") ||
26
+ message.includes("network") ||
27
+ message.includes("econnreset") ||
28
+ message.includes("etimedout") ||
29
+ message.includes("econnrefused") ||
30
+ message.includes("socket hang up") ||
31
+ message.includes("fetch failed"));
32
+ }
33
+ function normalizePositiveInt(value, fallback) {
34
+ if (typeof value !== "number" || !Number.isFinite(value)) {
35
+ return fallback;
36
+ }
37
+ return Math.max(1, Math.trunc(value));
38
+ }
39
+ function normalizeDelay(value, fallback) {
40
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
41
+ return fallback;
42
+ }
43
+ return Math.trunc(value);
44
+ }
45
+ function combineAbortSignals(signals) {
46
+ const controller = new AbortController();
47
+ const abortFrom = (signal) => {
48
+ if (!controller.signal.aborted) {
49
+ controller.abort(signal.reason);
50
+ }
51
+ };
52
+ for (const signal of signals) {
53
+ if (signal.aborted) {
54
+ abortFrom(signal);
55
+ break;
56
+ }
57
+ signal.addEventListener("abort", () => abortFrom(signal), { once: true });
58
+ }
59
+ return controller.signal;
60
+ }
61
+ function collectRetryHeaders(response) {
62
+ const headers = {};
63
+ const retryAfter = response.headers.get("retry-after");
64
+ const retryAfterMs = response.headers.get("retry-after-ms");
65
+ if (retryAfter) {
66
+ headers["retry-after"] = retryAfter;
67
+ }
68
+ if (retryAfterMs) {
69
+ headers["retry-after-ms"] = retryAfterMs;
70
+ }
71
+ return headers;
72
+ }
73
+ function retryDelayMs(response, attemptIndex, initialDelayMs, maxDelayMs) {
74
+ const retryAfterMs = parseRetryAfter(collectRetryHeaders(response));
75
+ if (retryAfterMs !== null) {
76
+ return Math.min(retryAfterMs, maxDelayMs);
77
+ }
78
+ return Math.min(initialDelayMs * 2 ** attemptIndex, maxDelayMs);
79
+ }
80
+ function toError(error) {
81
+ return error instanceof Error ? error : new Error(String(error));
82
+ }
83
+ function timeoutError(serviceName, failureMode, timeoutMs) {
84
+ return new DownstreamHttpError(`${serviceName} request timed out after ${timeoutMs}ms`, serviceName, failureMode, true, timeoutMs);
85
+ }
86
+ function requestError(serviceName, failureMode, error, retryable) {
87
+ return new DownstreamHttpError(`${serviceName} request failed: ${error.message}`, serviceName, failureMode, retryable);
88
+ }
89
+ export async function fetchDownstream(input, init, options) {
90
+ const maxAttempts = normalizePositiveInt(options.maxAttempts, 2);
91
+ const initialDelayMs = normalizeDelay(options.initialDelayMs, 100);
92
+ const maxDelayMs = normalizeDelay(options.maxDelayMs, 1_000);
93
+ const timeoutMs = normalizePositiveInt(options.timeoutMs, 2_000);
94
+ const fetchImpl = options.fetchImpl ?? fetch;
95
+ const sleepImpl = options.sleepMs ?? sleep;
96
+ const shouldRetryStatus = options.shouldRetryStatus ?? defaultShouldRetryStatus;
97
+ const externalSignal = init.signal;
98
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
99
+ const timeoutController = new AbortController();
100
+ const timeout = setTimeout(() => timeoutController.abort(), timeoutMs);
101
+ const signal = externalSignal
102
+ ? combineAbortSignals([externalSignal, timeoutController.signal])
103
+ : timeoutController.signal;
104
+ try {
105
+ const response = await fetchImpl(input, { ...init, signal });
106
+ clearTimeout(timeout);
107
+ if (response.ok ||
108
+ !shouldRetryStatus(response.status) ||
109
+ attempt >= maxAttempts) {
110
+ return response;
111
+ }
112
+ const delayMs = retryDelayMs(response, attempt - 1, initialDelayMs, maxDelayMs);
113
+ logger.debug("Retrying downstream request after status", {
114
+ serviceName: options.serviceName,
115
+ failureMode: options.failureMode,
116
+ status: response.status,
117
+ attempt,
118
+ maxAttempts,
119
+ delayMs,
120
+ });
121
+ await sleepImpl(delayMs);
122
+ }
123
+ catch (error) {
124
+ clearTimeout(timeout);
125
+ const normalized = toError(error);
126
+ const timedOut = timeoutController.signal.aborted;
127
+ if (externalSignal?.aborted && !timedOut) {
128
+ throw normalized;
129
+ }
130
+ const retryable = timedOut || isRetryableFetchError(normalized);
131
+ const wrapped = timedOut
132
+ ? timeoutError(options.serviceName, options.failureMode, timeoutMs)
133
+ : requestError(options.serviceName, options.failureMode, normalized, retryable);
134
+ if (!retryable || attempt >= maxAttempts) {
135
+ throw wrapped;
136
+ }
137
+ const delayMs = Math.min(initialDelayMs * 2 ** (attempt - 1), maxDelayMs);
138
+ logger.debug("Retrying downstream request after error", {
139
+ serviceName: options.serviceName,
140
+ failureMode: options.failureMode,
141
+ error: wrapped.message,
142
+ attempt,
143
+ maxAttempts,
144
+ delayMs,
145
+ });
146
+ await sleepImpl(delayMs);
147
+ }
148
+ }
149
+ throw new DownstreamHttpError(`${options.serviceName} request failed after ${maxAttempts} attempts`, options.serviceName, options.failureMode, true);
150
+ }
151
+ //# sourceMappingURL=downstream-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"downstream-http.js","sourceRoot":"","sources":["../../src/utils/downstream-http.ts"],"names":[],"mappings":"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","sourcesContent":["import { createLogger } from \"./logger.js\";\nimport { parseRetryAfter } from \"./retry.js\";\n\nconst logger = createLogger(\"runtime:downstream-http\");\n\nexport type DownstreamFailureMode = \"required\" | \"optional\";\n\nexport interface DownstreamFetchOptions {\n\tserviceName: string;\n\tfailureMode: DownstreamFailureMode;\n\ttimeoutMs: number;\n\tmaxAttempts?: number;\n\tinitialDelayMs?: number;\n\tmaxDelayMs?: number;\n\tfetchImpl?: typeof fetch;\n\tsleepMs?: (delayMs: number) => Promise<void>;\n\tshouldRetryStatus?: (status: number) => boolean;\n}\n\nexport class DownstreamHttpError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly serviceName: string,\n\t\tpublic readonly failureMode: DownstreamFailureMode,\n\t\tpublic readonly retryable: boolean,\n\t\tpublic readonly timeoutMs?: number,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"DownstreamHttpError\";\n\t}\n}\n\nfunction sleep(delayMs: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, delayMs));\n}\n\nfunction defaultShouldRetryStatus(status: number): boolean {\n\treturn status === 408 || status === 429 || status >= 500;\n}\n\nfunction isRetryableFetchError(error: Error): boolean {\n\tif (error.name === \"AbortError\") {\n\t\treturn true;\n\t}\n\n\tconst message = error.message.toLowerCase();\n\treturn (\n\t\tmessage.includes(\"timeout\") ||\n\t\tmessage.includes(\"network\") ||\n\t\tmessage.includes(\"econnreset\") ||\n\t\tmessage.includes(\"etimedout\") ||\n\t\tmessage.includes(\"econnrefused\") ||\n\t\tmessage.includes(\"socket hang up\") ||\n\t\tmessage.includes(\"fetch failed\")\n\t);\n}\n\nfunction normalizePositiveInt(\n\tvalue: number | undefined,\n\tfallback: number,\n): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) {\n\t\treturn fallback;\n\t}\n\treturn Math.max(1, Math.trunc(value));\n}\n\nfunction normalizeDelay(value: number | undefined, fallback: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n\t\treturn fallback;\n\t}\n\treturn Math.trunc(value);\n}\n\nfunction combineAbortSignals(signals: AbortSignal[]): AbortSignal {\n\tconst controller = new AbortController();\n\tconst abortFrom = (signal: AbortSignal) => {\n\t\tif (!controller.signal.aborted) {\n\t\t\tcontroller.abort(signal.reason);\n\t\t}\n\t};\n\n\tfor (const signal of signals) {\n\t\tif (signal.aborted) {\n\t\t\tabortFrom(signal);\n\t\t\tbreak;\n\t\t}\n\t\tsignal.addEventListener(\"abort\", () => abortFrom(signal), { once: true });\n\t}\n\n\treturn controller.signal;\n}\n\nfunction collectRetryHeaders(response: Response): Record<string, string> {\n\tconst headers: Record<string, string> = {};\n\tconst retryAfter = response.headers.get(\"retry-after\");\n\tconst retryAfterMs = response.headers.get(\"retry-after-ms\");\n\tif (retryAfter) {\n\t\theaders[\"retry-after\"] = retryAfter;\n\t}\n\tif (retryAfterMs) {\n\t\theaders[\"retry-after-ms\"] = retryAfterMs;\n\t}\n\treturn headers;\n}\n\nfunction retryDelayMs(\n\tresponse: Response,\n\tattemptIndex: number,\n\tinitialDelayMs: number,\n\tmaxDelayMs: number,\n): number {\n\tconst retryAfterMs = parseRetryAfter(collectRetryHeaders(response));\n\tif (retryAfterMs !== null) {\n\t\treturn Math.min(retryAfterMs, maxDelayMs);\n\t}\n\n\treturn Math.min(initialDelayMs * 2 ** attemptIndex, maxDelayMs);\n}\n\nfunction toError(error: unknown): Error {\n\treturn error instanceof Error ? error : new Error(String(error));\n}\n\nfunction timeoutError(\n\tserviceName: string,\n\tfailureMode: DownstreamFailureMode,\n\ttimeoutMs: number,\n): DownstreamHttpError {\n\treturn new DownstreamHttpError(\n\t\t`${serviceName} request timed out after ${timeoutMs}ms`,\n\t\tserviceName,\n\t\tfailureMode,\n\t\ttrue,\n\t\ttimeoutMs,\n\t);\n}\n\nfunction requestError(\n\tserviceName: string,\n\tfailureMode: DownstreamFailureMode,\n\terror: Error,\n\tretryable: boolean,\n): DownstreamHttpError {\n\treturn new DownstreamHttpError(\n\t\t`${serviceName} request failed: ${error.message}`,\n\t\tserviceName,\n\t\tfailureMode,\n\t\tretryable,\n\t);\n}\n\nexport async function fetchDownstream(\n\tinput: Parameters<typeof fetch>[0],\n\tinit: RequestInit,\n\toptions: DownstreamFetchOptions,\n): Promise<Response> {\n\tconst maxAttempts = normalizePositiveInt(options.maxAttempts, 2);\n\tconst initialDelayMs = normalizeDelay(options.initialDelayMs, 100);\n\tconst maxDelayMs = normalizeDelay(options.maxDelayMs, 1_000);\n\tconst timeoutMs = normalizePositiveInt(options.timeoutMs, 2_000);\n\tconst fetchImpl = options.fetchImpl ?? fetch;\n\tconst sleepImpl = options.sleepMs ?? sleep;\n\tconst shouldRetryStatus =\n\t\toptions.shouldRetryStatus ?? defaultShouldRetryStatus;\n\tconst externalSignal = init.signal;\n\n\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\tconst timeoutController = new AbortController();\n\t\tconst timeout = setTimeout(() => timeoutController.abort(), timeoutMs);\n\t\tconst signal = externalSignal\n\t\t\t? combineAbortSignals([externalSignal, timeoutController.signal])\n\t\t\t: timeoutController.signal;\n\n\t\ttry {\n\t\t\tconst response = await fetchImpl(input, { ...init, signal });\n\t\t\tclearTimeout(timeout);\n\n\t\t\tif (\n\t\t\t\tresponse.ok ||\n\t\t\t\t!shouldRetryStatus(response.status) ||\n\t\t\t\tattempt >= maxAttempts\n\t\t\t) {\n\t\t\t\treturn response;\n\t\t\t}\n\n\t\t\tconst delayMs = retryDelayMs(\n\t\t\t\tresponse,\n\t\t\t\tattempt - 1,\n\t\t\t\tinitialDelayMs,\n\t\t\t\tmaxDelayMs,\n\t\t\t);\n\t\t\tlogger.debug(\"Retrying downstream request after status\", {\n\t\t\t\tserviceName: options.serviceName,\n\t\t\t\tfailureMode: options.failureMode,\n\t\t\t\tstatus: response.status,\n\t\t\t\tattempt,\n\t\t\t\tmaxAttempts,\n\t\t\t\tdelayMs,\n\t\t\t});\n\t\t\tawait sleepImpl(delayMs);\n\t\t} catch (error) {\n\t\t\tclearTimeout(timeout);\n\t\t\tconst normalized = toError(error);\n\t\t\tconst timedOut = timeoutController.signal.aborted;\n\t\t\tif (externalSignal?.aborted && !timedOut) {\n\t\t\t\tthrow normalized;\n\t\t\t}\n\n\t\t\tconst retryable = timedOut || isRetryableFetchError(normalized);\n\t\t\tconst wrapped = timedOut\n\t\t\t\t? timeoutError(options.serviceName, options.failureMode, timeoutMs)\n\t\t\t\t: requestError(\n\t\t\t\t\t\toptions.serviceName,\n\t\t\t\t\t\toptions.failureMode,\n\t\t\t\t\t\tnormalized,\n\t\t\t\t\t\tretryable,\n\t\t\t\t\t);\n\n\t\t\tif (!retryable || attempt >= maxAttempts) {\n\t\t\t\tthrow wrapped;\n\t\t\t}\n\n\t\t\tconst delayMs = Math.min(initialDelayMs * 2 ** (attempt - 1), maxDelayMs);\n\t\t\tlogger.debug(\"Retrying downstream request after error\", {\n\t\t\t\tserviceName: options.serviceName,\n\t\t\t\tfailureMode: options.failureMode,\n\t\t\t\terror: wrapped.message,\n\t\t\t\tattempt,\n\t\t\t\tmaxAttempts,\n\t\t\t\tdelayMs,\n\t\t\t});\n\t\t\tawait sleepImpl(delayMs);\n\t\t}\n\t}\n\n\tthrow new DownstreamHttpError(\n\t\t`${options.serviceName} request failed after ${maxAttempts} attempts`,\n\t\toptions.serviceName,\n\t\toptions.failureMode,\n\t\ttrue,\n\t);\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { CircuitBreaker, type CircuitBreakerConfig } from "../safety/circuit-breaker.js";
2
+ export declare const FailClosed = "fail-closed";
3
+ export declare const FailOpen = "fail-open";
4
+ export type DownstreamFailureMode = typeof FailClosed | typeof FailOpen;
5
+ export interface DownstreamConfig {
6
+ failureMode: DownstreamFailureMode;
7
+ breaker?: CircuitBreaker | Partial<CircuitBreakerConfig> | false;
8
+ }
9
+ export declare class DownstreamClient {
10
+ readonly name: string;
11
+ readonly failureMode: DownstreamFailureMode;
12
+ private readonly breaker?;
13
+ constructor(name: string, config: DownstreamConfig);
14
+ callOp<T>(op: string, fn: () => Promise<T>, failOpenValue: () => T): Promise<T>;
15
+ }
16
+ export declare function New(name: string, config: DownstreamConfig): DownstreamClient;
17
+ export declare function CallOp<T>(client: DownstreamClient, op: string, fn: () => Promise<T>, failOpenValue: () => T): Promise<T>;
18
+ //# sourceMappingURL=downstream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"downstream.d.ts","sourceRoot":"","sources":["../../src/utils/downstream.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,cAAc,EACd,KAAK,oBAAoB,EACzB,MAAM,8BAA8B,CAAC;AAKtC,eAAO,MAAM,UAAU,gBAAgB,CAAC;AACxC,eAAO,MAAM,QAAQ,cAAc,CAAC;AAEpC,MAAM,MAAM,qBAAqB,GAAG,OAAO,UAAU,GAAG,OAAO,QAAQ,CAAC;AAExE,MAAM,WAAW,gBAAgB;IAChC,WAAW,EAAE,qBAAqB,CAAC;IACnC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,oBAAoB,CAAC,GAAG,KAAK,CAAC;CACjE;AAED,qBAAa,gBAAgB;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,qBAAqB,CAAC;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAiB;gBAE9B,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB;IAe5C,MAAM,CAAC,CAAC,EACb,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,aAAa,EAAE,MAAM,CAAC,GACpB,OAAO,CAAC,CAAC,CAAC;CAoBb;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAE5E;AAED,wBAAgB,MAAM,CAAC,CAAC,EACvB,MAAM,EAAE,gBAAgB,EACxB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,aAAa,EAAE,MAAM,CAAC,GACpB,OAAO,CAAC,CAAC,CAAC,CAEZ"}
@@ -0,0 +1,47 @@
1
+ import { CircuitBreaker, } from "../safety/circuit-breaker.js";
2
+ import { createLogger } from "./logger.js";
3
+ const logger = createLogger("runtime:downstream");
4
+ export const FailClosed = "fail-closed";
5
+ export const FailOpen = "fail-open";
6
+ export class DownstreamClient {
7
+ constructor(name, config) {
8
+ this.name = name;
9
+ this.failureMode = config.failureMode;
10
+ if (config.breaker === false || config.breaker === undefined) {
11
+ this.breaker = undefined;
12
+ }
13
+ else if (config.breaker instanceof CircuitBreaker) {
14
+ this.breaker = config.breaker;
15
+ }
16
+ else {
17
+ this.breaker = new CircuitBreaker({
18
+ ...config.breaker,
19
+ toolName: config.breaker.toolName ?? name,
20
+ });
21
+ }
22
+ }
23
+ async callOp(op, fn, failOpenValue) {
24
+ try {
25
+ return this.breaker ? await this.breaker.execute(fn) : await fn();
26
+ }
27
+ catch (error) {
28
+ if (this.failureMode === FailOpen) {
29
+ logger.warn("Downstream call failed (fail-open)", {
30
+ downstream: this.name,
31
+ op,
32
+ error: error instanceof Error ? error.message : String(error),
33
+ });
34
+ return failOpenValue();
35
+ }
36
+ logger.error("Downstream call failed (fail-closed)", error instanceof Error ? error : new Error(String(error)), { downstream: this.name, op });
37
+ throw error;
38
+ }
39
+ }
40
+ }
41
+ export function New(name, config) {
42
+ return new DownstreamClient(name, config);
43
+ }
44
+ export function CallOp(client, op, fn, failOpenValue) {
45
+ return client.callOp(op, fn, failOpenValue);
46
+ }
47
+ //# sourceMappingURL=downstream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"downstream.js","sourceRoot":"","sources":["../../src/utils/downstream.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,cAAc,GAEd,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,GAAG,YAAY,CAAC,oBAAoB,CAAC,CAAC;AAElD,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAC;AACxC,MAAM,CAAC,MAAM,QAAQ,GAAG,WAAW,CAAC;AASpC,MAAM,OAAO,gBAAgB;IAK5B,YAAY,IAAY,EAAE,MAAwB;QACjD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACtC,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC9D,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QAC1B,CAAC;aAAM,IAAI,MAAM,CAAC,OAAO,YAAY,cAAc,EAAE,CAAC;YACrD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC/B,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC;gBACjC,GAAG,MAAM,CAAC,OAAO;gBACjB,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI;aACzC,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED,KAAK,CAAC,MAAM,CACX,EAAU,EACV,EAAoB,EACpB,aAAsB;QAEtB,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;QACnE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,IAAI,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;gBACnC,MAAM,CAAC,IAAI,CAAC,oCAAoC,EAAE;oBACjD,UAAU,EAAE,IAAI,CAAC,IAAI;oBACrB,EAAE;oBACF,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC7D,CAAC,CAAC;gBACH,OAAO,aAAa,EAAE,CAAC;YACxB,CAAC;YACD,MAAM,CAAC,KAAK,CACX,sCAAsC,EACtC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EACzD,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAC7B,CAAC;YACF,MAAM,KAAK,CAAC;QACb,CAAC;IACF,CAAC;CACD;AAED,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,MAAwB;IACzD,OAAO,IAAI,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,MAAM,CACrB,MAAwB,EACxB,EAAU,EACV,EAAoB,EACpB,aAAsB;IAEtB,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,aAAa,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import {\n\tCircuitBreaker,\n\ttype CircuitBreakerConfig,\n} from \"../safety/circuit-breaker.js\";\nimport { createLogger } from \"./logger.js\";\n\nconst logger = createLogger(\"runtime:downstream\");\n\nexport const FailClosed = \"fail-closed\";\nexport const FailOpen = \"fail-open\";\n\nexport type DownstreamFailureMode = typeof FailClosed | typeof FailOpen;\n\nexport interface DownstreamConfig {\n\tfailureMode: DownstreamFailureMode;\n\tbreaker?: CircuitBreaker | Partial<CircuitBreakerConfig> | false;\n}\n\nexport class DownstreamClient {\n\treadonly name: string;\n\treadonly failureMode: DownstreamFailureMode;\n\tprivate readonly breaker?: CircuitBreaker;\n\n\tconstructor(name: string, config: DownstreamConfig) {\n\t\tthis.name = name;\n\t\tthis.failureMode = config.failureMode;\n\t\tif (config.breaker === false || config.breaker === undefined) {\n\t\t\tthis.breaker = undefined;\n\t\t} else if (config.breaker instanceof CircuitBreaker) {\n\t\t\tthis.breaker = config.breaker;\n\t\t} else {\n\t\t\tthis.breaker = new CircuitBreaker({\n\t\t\t\t...config.breaker,\n\t\t\t\ttoolName: config.breaker.toolName ?? name,\n\t\t\t});\n\t\t}\n\t}\n\n\tasync callOp<T>(\n\t\top: string,\n\t\tfn: () => Promise<T>,\n\t\tfailOpenValue: () => T,\n\t): Promise<T> {\n\t\ttry {\n\t\t\treturn this.breaker ? await this.breaker.execute(fn) : await fn();\n\t\t} catch (error) {\n\t\t\tif (this.failureMode === FailOpen) {\n\t\t\t\tlogger.warn(\"Downstream call failed (fail-open)\", {\n\t\t\t\t\tdownstream: this.name,\n\t\t\t\t\top,\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t});\n\t\t\t\treturn failOpenValue();\n\t\t\t}\n\t\t\tlogger.error(\n\t\t\t\t\"Downstream call failed (fail-closed)\",\n\t\t\t\terror instanceof Error ? error : new Error(String(error)),\n\t\t\t\t{ downstream: this.name, op },\n\t\t\t);\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n\nexport function New(name: string, config: DownstreamConfig): DownstreamClient {\n\treturn new DownstreamClient(name, config);\n}\n\nexport function CallOp<T>(\n\tclient: DownstreamClient,\n\top: string,\n\tfn: () => Promise<T>,\n\tfailOpenValue: () => T,\n): Promise<T> {\n\treturn client.callOp(op, fn, failOpenValue);\n}\n"]}
@@ -98,7 +98,9 @@ export declare function redirectLoggerToFile(filePath?: string): void;
98
98
  * output) has been configured; otherwise console.* would route back to the
99
99
  * console-backed logger output and recurse.
100
100
  */
101
- export declare function redirectConsoleToLogger(): void;
101
+ export declare function redirectConsoleToLogger(options?: {
102
+ preserveErrorStderr?: boolean;
103
+ }): void;
102
104
  /**
103
105
  * Redirect process.stderr writes to the structured logger.
104
106
  * Useful in TUI mode to prevent third-party libraries from corrupting the terminal.
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,UAAU;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED,UAAU,QAAQ;IACjB,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,KAAK,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACF;AAED;;GAEG;AACH,UAAU,YAAY;IACrB,gEAAgE;IAChE,QAAQ,EAAE,QAAQ,CAAC;IACnB,iEAAiE;IACjE,UAAU,EAAE,OAAO,CAAC;IACpB,oCAAoC;IACpC,UAAU,EAAE,OAAO,CAAC;IACpB,mDAAmD;IACnD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;CACnC;AASD,cAAM,MAAM;IACX,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC;IAS1C;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,GAAG;IAkCX;;OAEG;IACH,OAAO,CAAC,UAAU;IAKlB;;OAEG;IACH,OAAO,CAAC,YAAY;IAsBpB;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIlD;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjD;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjD;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjE;;OAEG;IACH,KAAK,CAAC,iBAAiB,EAAE,UAAU,GAAG,MAAM;IAI5C;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI;CAG9C;AAkCD;;GAEG;AACH,eAAO,MAAM,MAAM,QAAe,CAAC;AAEnC;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAkC5D;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAwB9C;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAW7C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAsBhD"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,UAAU;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED,UAAU,QAAQ;IACjB,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,KAAK,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACF;AAED;;GAEG;AACH,UAAU,YAAY;IACrB,gEAAgE;IAChE,QAAQ,EAAE,QAAQ,CAAC;IACnB,iEAAiE;IACjE,UAAU,EAAE,OAAO,CAAC;IACpB,oCAAoC;IACpC,UAAU,EAAE,OAAO,CAAC;IACpB,mDAAmD;IACnD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;CACnC;AAiBD,cAAM,MAAM;IACX,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC;IAS1C;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,GAAG;IAkCX;;OAEG;IACH,OAAO,CAAC,UAAU;IAKlB;;OAEG;IACH,OAAO,CAAC,YAAY;IAsBpB;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIlD;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjD;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjD;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjE;;OAEG;IACH,KAAK,CAAC,iBAAiB,EAAE,UAAU,GAAG,MAAM;IAI5C;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI;CAG9C;AAkCD;;GAEG;AACH,eAAO,MAAM,MAAM,QAAe,CAAC;AAEnC;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAkC5D;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,CAAC,EAAE;IACjD,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC9B,GAAG,IAAI,CA4BP;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAW7C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAsBhD"}
@@ -5,6 +5,13 @@
5
5
  import { appendFileSync, mkdirSync } from "node:fs";
6
6
  import { dirname, join } from "node:path";
7
7
  import { PATHS } from "../config/constants.js";
8
+ const originalConsole = {
9
+ log: console.log.bind(console),
10
+ info: console.info.bind(console),
11
+ warn: console.warn.bind(console),
12
+ error: console.error.bind(console),
13
+ debug: console.debug.bind(console),
14
+ };
8
15
  const LOG_LEVELS = {
9
16
  debug: 0,
10
17
  info: 1,
@@ -202,7 +209,7 @@ export function redirectLoggerToFile(filePath) {
202
209
  * output) has been configured; otherwise console.* would route back to the
203
210
  * console-backed logger output and recurse.
204
211
  */
205
- export function redirectConsoleToLogger() {
212
+ export function redirectConsoleToLogger(options) {
206
213
  console.log = (...args) => {
207
214
  logger.info(args.map(String).join(" "));
208
215
  };
@@ -213,6 +220,10 @@ export function redirectConsoleToLogger() {
213
220
  logger.warn(args.map(String).join(" "));
214
221
  };
215
222
  console.error = (...args) => {
223
+ if (options?.preserveErrorStderr) {
224
+ originalConsole.error(...args);
225
+ return;
226
+ }
216
227
  // Preserve first Error stack if present
217
228
  const maybeError = args.find((a) => a instanceof Error);
218
229
  if (maybeError) {
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Structured logging service for Composer CLI.\n * Replaces scattered console.log/error calls with centralized, level-based logging.\n */\n\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { PATHS } from \"../config/constants.js\";\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface LogContext {\n\t[key: string]: unknown;\n}\n\ninterface LogEntry {\n\tlevel: LogLevel;\n\tmessage: string;\n\ttimestamp: string;\n\tcontext?: LogContext;\n\terror?: {\n\t\tname: string;\n\t\tmessage: string;\n\t\tstack?: string;\n\t};\n}\n\n/**\n * Logger configuration\n */\ninterface LoggerConfig {\n\t/** Minimum log level to output (debug < info < warn < error) */\n\tminLevel: LogLevel;\n\t/** Whether to output JSON format (useful for log aggregation) */\n\tjsonFormat: boolean;\n\t/** Whether to include timestamps */\n\ttimestamps: boolean;\n\t/** Custom output function (defaults to console) */\n\toutput?: (entry: LogEntry) => void;\n}\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n\tdebug: 0,\n\tinfo: 1,\n\twarn: 2,\n\terror: 3,\n};\n\nclass Logger {\n\tprivate config: LoggerConfig;\n\n\tconstructor(config?: Partial<LoggerConfig>) {\n\t\tthis.config = {\n\t\t\tminLevel: (process.env.MAESTRO_LOG_LEVEL as LogLevel) ?? \"info\",\n\t\t\tjsonFormat: process.env.MAESTRO_LOG_JSON === \"1\",\n\t\t\ttimestamps: true,\n\t\t\t...config,\n\t\t};\n\t}\n\n\t/**\n\t * Check if a log level should be output\n\t */\n\tprivate shouldLog(level: LogLevel): boolean {\n\t\treturn LOG_LEVELS[level] >= LOG_LEVELS[this.config.minLevel];\n\t}\n\n\t/**\n\t * Format and output a log entry\n\t */\n\tprivate log(\n\t\tlevel: LogLevel,\n\t\tmessage: string,\n\t\tcontext?: LogContext,\n\t\terror?: Error,\n\t): void {\n\t\tif (!this.shouldLog(level)) return;\n\n\t\tconst entry: LogEntry = {\n\t\t\tlevel,\n\t\t\tmessage,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tcontext,\n\t\t\terror: error\n\t\t\t\t? {\n\t\t\t\t\t\tname: error.name,\n\t\t\t\t\t\tmessage: error.message,\n\t\t\t\t\t\tstack: error.stack,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t};\n\n\t\tif (this.config.output) {\n\t\t\tthis.config.output(entry);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.config.jsonFormat) {\n\t\t\tthis.outputJson(entry);\n\t\t} else {\n\t\t\tthis.outputPretty(entry);\n\t\t}\n\t}\n\n\t/**\n\t * Output as JSON (for log aggregation systems)\n\t */\n\tprivate outputJson(entry: LogEntry): void {\n\t\tconst output = entry.level === \"error\" ? console.error : console.log;\n\t\toutput(JSON.stringify(entry));\n\t}\n\n\t/**\n\t * Output as human-readable format\n\t */\n\tprivate outputPretty(entry: LogEntry): void {\n\t\tconst output = entry.level === \"error\" ? console.error : console.log;\n\t\tconst parts: string[] = [];\n\n\t\tif (this.config.timestamps) {\n\t\t\tparts.push(`[${entry.timestamp}]`);\n\t\t}\n\n\t\tparts.push(`[${entry.level.toUpperCase()}]`);\n\t\tparts.push(entry.message);\n\n\t\tif (entry.context && Object.keys(entry.context).length > 0) {\n\t\t\tparts.push(JSON.stringify(entry.context));\n\t\t}\n\n\t\toutput(parts.join(\" \"));\n\n\t\tif (entry.error?.stack) {\n\t\t\toutput(entry.error.stack);\n\t\t}\n\t}\n\n\t/**\n\t * Log debug message (verbose, typically for development)\n\t */\n\tdebug(message: string, context?: LogContext): void {\n\t\tthis.log(\"debug\", message, context);\n\t}\n\n\t/**\n\t * Log info message (general information)\n\t */\n\tinfo(message: string, context?: LogContext): void {\n\t\tthis.log(\"info\", message, context);\n\t}\n\n\t/**\n\t * Log warning message (potentially problematic situations)\n\t */\n\twarn(message: string, context?: LogContext): void {\n\t\tthis.log(\"warn\", message, context);\n\t}\n\n\t/**\n\t * Log error message (failures and exceptions)\n\t */\n\terror(message: string, error?: Error, context?: LogContext): void {\n\t\tthis.log(\"error\", message, context, error);\n\t}\n\n\t/**\n\t * Create a child logger with additional context\n\t */\n\tchild(additionalContext: LogContext): Logger {\n\t\treturn new ContextualLogger(this, additionalContext);\n\t}\n\n\t/**\n\t * Update logger configuration\n\t */\n\tconfigure(config: Partial<LoggerConfig>): void {\n\t\tthis.config = { ...this.config, ...config };\n\t}\n}\n\n/**\n * Logger that automatically includes context in all log calls\n */\nclass ContextualLogger extends Logger {\n\tconstructor(\n\t\tprivate parent: Logger,\n\t\tprivate contextData: LogContext,\n\t) {\n\t\tsuper();\n\t}\n\n\tprivate mergeContext(context?: LogContext): LogContext {\n\t\treturn { ...this.contextData, ...context };\n\t}\n\n\toverride debug(message: string, context?: LogContext): void {\n\t\tthis.parent.debug(message, this.mergeContext(context));\n\t}\n\n\toverride info(message: string, context?: LogContext): void {\n\t\tthis.parent.info(message, this.mergeContext(context));\n\t}\n\n\toverride warn(message: string, context?: LogContext): void {\n\t\tthis.parent.warn(message, this.mergeContext(context));\n\t}\n\n\toverride error(message: string, error?: Error, context?: LogContext): void {\n\t\tthis.parent.error(message, error, this.mergeContext(context));\n\t}\n}\n\n/**\n * Global logger instance\n */\nexport const logger = new Logger();\n\n/**\n * Create a logger for a specific module/component\n */\nexport function createLogger(moduleName: string): Logger {\n\treturn logger.child({ module: moduleName });\n}\n\n/**\n * Silence the logger (useful for TUI mode where stdout must not be polluted)\n */\nexport function silenceLogger(): void {\n\tlogger.configure({ output: () => {} });\n}\n\n/**\n * Redirect all logs to a file (useful for TUI mode)\n * @param filePath - Path to the log file (defaults to ~/.maestro/logs/maestro.log)\n */\nexport function redirectLoggerToFile(filePath?: string): void {\n\tconst logFile = filePath ?? join(PATHS.MAESTRO_HOME, \"logs\", \"maestro.log\");\n\n\t// Ensure directory exists\n\ttry {\n\t\tmkdirSync(dirname(logFile), { recursive: true });\n\t} catch {\n\t\t// Directory may already exist\n\t}\n\n\tlogger.configure({\n\t\toutput: (entry) => {\n\t\t\tconst parts: string[] = [];\n\t\t\tparts.push(`[${entry.timestamp}]`);\n\t\t\tparts.push(`[${entry.level.toUpperCase()}]`);\n\t\t\tparts.push(entry.message);\n\n\t\t\tif (entry.context && Object.keys(entry.context).length > 0) {\n\t\t\t\tparts.push(JSON.stringify(entry.context));\n\t\t\t}\n\n\t\t\tlet line = `${parts.join(\" \")}\\n`;\n\n\t\t\tif (entry.error?.stack) {\n\t\t\t\tline += `${entry.error.stack}\\n`;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tappendFileSync(logFile, line);\n\t\t\t} catch {\n\t\t\t\t// Silently fail if we can't write to the log file\n\t\t\t}\n\t\t},\n\t});\n}\n\n/**\n * Redirect global console methods to the structured logger.\n *\n * Important: Call this only after redirectLoggerToFile() (or a custom logger\n * output) has been configured; otherwise console.* would route back to the\n * console-backed logger output and recurse.\n */\nexport function redirectConsoleToLogger(): void {\n\tconsole.log = (...args: unknown[]) => {\n\t\tlogger.info(args.map(String).join(\" \"));\n\t};\n\tconsole.info = (...args: unknown[]) => {\n\t\tlogger.info(args.map(String).join(\" \"));\n\t};\n\tconsole.warn = (...args: unknown[]) => {\n\t\tlogger.warn(args.map(String).join(\" \"));\n\t};\n\tconsole.error = (...args: unknown[]) => {\n\t\t// Preserve first Error stack if present\n\t\tconst maybeError = args.find((a) => a instanceof Error) as\n\t\t\t| Error\n\t\t\t| undefined;\n\t\tif (maybeError) {\n\t\t\tlogger.error(maybeError.message, maybeError);\n\t\t} else {\n\t\t\tlogger.error(args.map(String).join(\" \"));\n\t\t}\n\t};\n\tconsole.debug = (...args: unknown[]) => {\n\t\tlogger.debug(args.map(String).join(\" \"));\n\t};\n}\n\n/**\n * Redirect process.stderr writes to the structured logger.\n * Useful in TUI mode to prevent third-party libraries from corrupting the terminal.\n */\nexport function redirectStderrToLogger(): void {\n\tprocess.stderr.write = (chunk: unknown) => {\n\t\tconst text =\n\t\t\ttypeof chunk === \"string\"\n\t\t\t\t? chunk\n\t\t\t\t: chunk instanceof Buffer\n\t\t\t\t\t? chunk.toString()\n\t\t\t\t\t: String(chunk);\n\t\tlogger.error(text.trimEnd());\n\t\treturn true;\n\t};\n}\n\n/**\n * Wire process warning / rejection hooks into the logger so they don't hit stderr.\n */\nexport function pipeProcessEventsToLogger(): void {\n\tprocess.on(\"warning\", (warning) => {\n\t\tlogger.warn(\n\t\t\t`${warning.name}: ${warning.message}${\n\t\t\t\twarning.stack ? `\\n${warning.stack}` : \"\"\n\t\t\t}`,\n\t\t);\n\t});\n\n\tprocess.on(\"unhandledRejection\", (reason, promise) => {\n\t\tlogger.error(\n\t\t\t`UnhandledRejection: ${String(reason)} (promise: ${String(promise)})`,\n\t\t);\n\t});\n\n\tprocess.on(\"uncaughtException\", (error) => {\n\t\tif (error instanceof Error) {\n\t\t\tlogger.error(error.message, error);\n\t\t} else {\n\t\t\tlogger.error(`UncaughtException: ${String(error)}`);\n\t\t}\n\t});\n}\n"]}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Structured logging service for Composer CLI.\n * Replaces scattered console.log/error calls with centralized, level-based logging.\n */\n\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { PATHS } from \"../config/constants.js\";\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface LogContext {\n\t[key: string]: unknown;\n}\n\ninterface LogEntry {\n\tlevel: LogLevel;\n\tmessage: string;\n\ttimestamp: string;\n\tcontext?: LogContext;\n\terror?: {\n\t\tname: string;\n\t\tmessage: string;\n\t\tstack?: string;\n\t};\n}\n\n/**\n * Logger configuration\n */\ninterface LoggerConfig {\n\t/** Minimum log level to output (debug < info < warn < error) */\n\tminLevel: LogLevel;\n\t/** Whether to output JSON format (useful for log aggregation) */\n\tjsonFormat: boolean;\n\t/** Whether to include timestamps */\n\ttimestamps: boolean;\n\t/** Custom output function (defaults to console) */\n\toutput?: (entry: LogEntry) => void;\n}\n\nconst originalConsole = {\n\tlog: console.log.bind(console),\n\tinfo: console.info.bind(console),\n\twarn: console.warn.bind(console),\n\terror: console.error.bind(console),\n\tdebug: console.debug.bind(console),\n};\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n\tdebug: 0,\n\tinfo: 1,\n\twarn: 2,\n\terror: 3,\n};\n\nclass Logger {\n\tprivate config: LoggerConfig;\n\n\tconstructor(config?: Partial<LoggerConfig>) {\n\t\tthis.config = {\n\t\t\tminLevel: (process.env.MAESTRO_LOG_LEVEL as LogLevel) ?? \"info\",\n\t\t\tjsonFormat: process.env.MAESTRO_LOG_JSON === \"1\",\n\t\t\ttimestamps: true,\n\t\t\t...config,\n\t\t};\n\t}\n\n\t/**\n\t * Check if a log level should be output\n\t */\n\tprivate shouldLog(level: LogLevel): boolean {\n\t\treturn LOG_LEVELS[level] >= LOG_LEVELS[this.config.minLevel];\n\t}\n\n\t/**\n\t * Format and output a log entry\n\t */\n\tprivate log(\n\t\tlevel: LogLevel,\n\t\tmessage: string,\n\t\tcontext?: LogContext,\n\t\terror?: Error,\n\t): void {\n\t\tif (!this.shouldLog(level)) return;\n\n\t\tconst entry: LogEntry = {\n\t\t\tlevel,\n\t\t\tmessage,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tcontext,\n\t\t\terror: error\n\t\t\t\t? {\n\t\t\t\t\t\tname: error.name,\n\t\t\t\t\t\tmessage: error.message,\n\t\t\t\t\t\tstack: error.stack,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t};\n\n\t\tif (this.config.output) {\n\t\t\tthis.config.output(entry);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.config.jsonFormat) {\n\t\t\tthis.outputJson(entry);\n\t\t} else {\n\t\t\tthis.outputPretty(entry);\n\t\t}\n\t}\n\n\t/**\n\t * Output as JSON (for log aggregation systems)\n\t */\n\tprivate outputJson(entry: LogEntry): void {\n\t\tconst output = entry.level === \"error\" ? console.error : console.log;\n\t\toutput(JSON.stringify(entry));\n\t}\n\n\t/**\n\t * Output as human-readable format\n\t */\n\tprivate outputPretty(entry: LogEntry): void {\n\t\tconst output = entry.level === \"error\" ? console.error : console.log;\n\t\tconst parts: string[] = [];\n\n\t\tif (this.config.timestamps) {\n\t\t\tparts.push(`[${entry.timestamp}]`);\n\t\t}\n\n\t\tparts.push(`[${entry.level.toUpperCase()}]`);\n\t\tparts.push(entry.message);\n\n\t\tif (entry.context && Object.keys(entry.context).length > 0) {\n\t\t\tparts.push(JSON.stringify(entry.context));\n\t\t}\n\n\t\toutput(parts.join(\" \"));\n\n\t\tif (entry.error?.stack) {\n\t\t\toutput(entry.error.stack);\n\t\t}\n\t}\n\n\t/**\n\t * Log debug message (verbose, typically for development)\n\t */\n\tdebug(message: string, context?: LogContext): void {\n\t\tthis.log(\"debug\", message, context);\n\t}\n\n\t/**\n\t * Log info message (general information)\n\t */\n\tinfo(message: string, context?: LogContext): void {\n\t\tthis.log(\"info\", message, context);\n\t}\n\n\t/**\n\t * Log warning message (potentially problematic situations)\n\t */\n\twarn(message: string, context?: LogContext): void {\n\t\tthis.log(\"warn\", message, context);\n\t}\n\n\t/**\n\t * Log error message (failures and exceptions)\n\t */\n\terror(message: string, error?: Error, context?: LogContext): void {\n\t\tthis.log(\"error\", message, context, error);\n\t}\n\n\t/**\n\t * Create a child logger with additional context\n\t */\n\tchild(additionalContext: LogContext): Logger {\n\t\treturn new ContextualLogger(this, additionalContext);\n\t}\n\n\t/**\n\t * Update logger configuration\n\t */\n\tconfigure(config: Partial<LoggerConfig>): void {\n\t\tthis.config = { ...this.config, ...config };\n\t}\n}\n\n/**\n * Logger that automatically includes context in all log calls\n */\nclass ContextualLogger extends Logger {\n\tconstructor(\n\t\tprivate parent: Logger,\n\t\tprivate contextData: LogContext,\n\t) {\n\t\tsuper();\n\t}\n\n\tprivate mergeContext(context?: LogContext): LogContext {\n\t\treturn { ...this.contextData, ...context };\n\t}\n\n\toverride debug(message: string, context?: LogContext): void {\n\t\tthis.parent.debug(message, this.mergeContext(context));\n\t}\n\n\toverride info(message: string, context?: LogContext): void {\n\t\tthis.parent.info(message, this.mergeContext(context));\n\t}\n\n\toverride warn(message: string, context?: LogContext): void {\n\t\tthis.parent.warn(message, this.mergeContext(context));\n\t}\n\n\toverride error(message: string, error?: Error, context?: LogContext): void {\n\t\tthis.parent.error(message, error, this.mergeContext(context));\n\t}\n}\n\n/**\n * Global logger instance\n */\nexport const logger = new Logger();\n\n/**\n * Create a logger for a specific module/component\n */\nexport function createLogger(moduleName: string): Logger {\n\treturn logger.child({ module: moduleName });\n}\n\n/**\n * Silence the logger (useful for TUI mode where stdout must not be polluted)\n */\nexport function silenceLogger(): void {\n\tlogger.configure({ output: () => {} });\n}\n\n/**\n * Redirect all logs to a file (useful for TUI mode)\n * @param filePath - Path to the log file (defaults to ~/.maestro/logs/maestro.log)\n */\nexport function redirectLoggerToFile(filePath?: string): void {\n\tconst logFile = filePath ?? join(PATHS.MAESTRO_HOME, \"logs\", \"maestro.log\");\n\n\t// Ensure directory exists\n\ttry {\n\t\tmkdirSync(dirname(logFile), { recursive: true });\n\t} catch {\n\t\t// Directory may already exist\n\t}\n\n\tlogger.configure({\n\t\toutput: (entry) => {\n\t\t\tconst parts: string[] = [];\n\t\t\tparts.push(`[${entry.timestamp}]`);\n\t\t\tparts.push(`[${entry.level.toUpperCase()}]`);\n\t\t\tparts.push(entry.message);\n\n\t\t\tif (entry.context && Object.keys(entry.context).length > 0) {\n\t\t\t\tparts.push(JSON.stringify(entry.context));\n\t\t\t}\n\n\t\t\tlet line = `${parts.join(\" \")}\\n`;\n\n\t\t\tif (entry.error?.stack) {\n\t\t\t\tline += `${entry.error.stack}\\n`;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tappendFileSync(logFile, line);\n\t\t\t} catch {\n\t\t\t\t// Silently fail if we can't write to the log file\n\t\t\t}\n\t\t},\n\t});\n}\n\n/**\n * Redirect global console methods to the structured logger.\n *\n * Important: Call this only after redirectLoggerToFile() (or a custom logger\n * output) has been configured; otherwise console.* would route back to the\n * console-backed logger output and recurse.\n */\nexport function redirectConsoleToLogger(options?: {\n\tpreserveErrorStderr?: boolean;\n}): void {\n\tconsole.log = (...args: unknown[]) => {\n\t\tlogger.info(args.map(String).join(\" \"));\n\t};\n\tconsole.info = (...args: unknown[]) => {\n\t\tlogger.info(args.map(String).join(\" \"));\n\t};\n\tconsole.warn = (...args: unknown[]) => {\n\t\tlogger.warn(args.map(String).join(\" \"));\n\t};\n\tconsole.error = (...args: unknown[]) => {\n\t\tif (options?.preserveErrorStderr) {\n\t\t\toriginalConsole.error(...args);\n\t\t\treturn;\n\t\t}\n\t\t// Preserve first Error stack if present\n\t\tconst maybeError = args.find((a) => a instanceof Error) as\n\t\t\t| Error\n\t\t\t| undefined;\n\t\tif (maybeError) {\n\t\t\tlogger.error(maybeError.message, maybeError);\n\t\t} else {\n\t\t\tlogger.error(args.map(String).join(\" \"));\n\t\t}\n\t};\n\tconsole.debug = (...args: unknown[]) => {\n\t\tlogger.debug(args.map(String).join(\" \"));\n\t};\n}\n\n/**\n * Redirect process.stderr writes to the structured logger.\n * Useful in TUI mode to prevent third-party libraries from corrupting the terminal.\n */\nexport function redirectStderrToLogger(): void {\n\tprocess.stderr.write = (chunk: unknown) => {\n\t\tconst text =\n\t\t\ttypeof chunk === \"string\"\n\t\t\t\t? chunk\n\t\t\t\t: chunk instanceof Buffer\n\t\t\t\t\t? chunk.toString()\n\t\t\t\t\t: String(chunk);\n\t\tlogger.error(text.trimEnd());\n\t\treturn true;\n\t};\n}\n\n/**\n * Wire process warning / rejection hooks into the logger so they don't hit stderr.\n */\nexport function pipeProcessEventsToLogger(): void {\n\tprocess.on(\"warning\", (warning) => {\n\t\tlogger.warn(\n\t\t\t`${warning.name}: ${warning.message}${\n\t\t\t\twarning.stack ? `\\n${warning.stack}` : \"\"\n\t\t\t}`,\n\t\t);\n\t});\n\n\tprocess.on(\"unhandledRejection\", (reason, promise) => {\n\t\tlogger.error(\n\t\t\t`UnhandledRejection: ${String(reason)} (promise: ${String(promise)})`,\n\t\t);\n\t});\n\n\tprocess.on(\"uncaughtException\", (error) => {\n\t\tif (error instanceof Error) {\n\t\t\tlogger.error(error.message, error);\n\t\t} else {\n\t\t\tlogger.error(`UncaughtException: ${String(error)}`);\n\t\t}\n\t});\n}\n"]}
@@ -0,0 +1,8 @@
1
+ interface OAuthHttpOptions {
2
+ maxAttempts?: number;
3
+ serviceName: string;
4
+ timeoutMs?: number;
5
+ }
6
+ export declare function fetchOAuthHttp(input: Parameters<typeof fetch>[0], init: RequestInit, options: OAuthHttpOptions): Promise<Response>;
7
+ export {};
8
+ //# sourceMappingURL=oauth-http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-http.d.ts","sourceRoot":"","sources":["../../src/utils/oauth-http.ts"],"names":[],"mappings":"AAaA,UAAU,gBAAgB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AA2BD,wBAAgB,cAAc,CAC7B,KAAK,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAClC,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,gBAAgB,GACvB,OAAO,CAAC,QAAQ,CAAC,CASnB"}
@@ -0,0 +1,41 @@
1
+ import { fetchDownstream } from "./downstream-http.js";
2
+ const DEFAULT_OAUTH_HTTP_MAX_ATTEMPTS = 1;
3
+ const DEFAULT_OAUTH_HTTP_TIMEOUT_MS = 10_000;
4
+ const MAX_ATTEMPTS_ENV_VARS = [
5
+ "MAESTRO_OAUTH_HTTP_MAX_ATTEMPTS",
6
+ "OAUTH_HTTP_MAX_ATTEMPTS",
7
+ ];
8
+ const TIMEOUT_ENV_VARS = [
9
+ "MAESTRO_OAUTH_HTTP_TIMEOUT_MS",
10
+ "OAUTH_HTTP_TIMEOUT_MS",
11
+ ];
12
+ function getEnvPositiveInt(names, fallback) {
13
+ for (const name of names) {
14
+ const value = process.env[name]?.trim();
15
+ if (!value) {
16
+ continue;
17
+ }
18
+ const parsed = Number.parseInt(value, 10);
19
+ if (Number.isFinite(parsed) && parsed > 0) {
20
+ return parsed;
21
+ }
22
+ }
23
+ return fallback;
24
+ }
25
+ function getOAuthHttpMaxAttempts() {
26
+ return getEnvPositiveInt(MAX_ATTEMPTS_ENV_VARS, DEFAULT_OAUTH_HTTP_MAX_ATTEMPTS);
27
+ }
28
+ function getOAuthHttpTimeoutMs() {
29
+ return getEnvPositiveInt(TIMEOUT_ENV_VARS, DEFAULT_OAUTH_HTTP_TIMEOUT_MS);
30
+ }
31
+ export function fetchOAuthHttp(input, init, options) {
32
+ return fetchDownstream(input, init, {
33
+ serviceName: options.serviceName,
34
+ failureMode: "required",
35
+ timeoutMs: options.timeoutMs ?? getOAuthHttpTimeoutMs(),
36
+ maxAttempts: options.maxAttempts ?? getOAuthHttpMaxAttempts(),
37
+ initialDelayMs: 100,
38
+ maxDelayMs: 1_000,
39
+ });
40
+ }
41
+ //# sourceMappingURL=oauth-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-http.js","sourceRoot":"","sources":["../../src/utils/oauth-http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,+BAA+B,GAAG,CAAC,CAAC;AAC1C,MAAM,6BAA6B,GAAG,MAAM,CAAC;AAC7C,MAAM,qBAAqB,GAAG;IAC7B,iCAAiC;IACjC,yBAAyB;CAChB,CAAC;AACX,MAAM,gBAAgB,GAAG;IACxB,+BAA+B;IAC/B,uBAAuB;CACd,CAAC;AAQX,SAAS,iBAAiB,CAAC,KAAwB,EAAE,QAAgB;IACpE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,SAAS;QACV,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,OAAO,MAAM,CAAC;QACf,CAAC;IACF,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,SAAS,uBAAuB;IAC/B,OAAO,iBAAiB,CACvB,qBAAqB,EACrB,+BAA+B,CAC/B,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB;IAC7B,OAAO,iBAAiB,CAAC,gBAAgB,EAAE,6BAA6B,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,cAAc,CAC7B,KAAkC,EAClC,IAAiB,EACjB,OAAyB;IAEzB,OAAO,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE;QACnC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,WAAW,EAAE,UAAU;QACvB,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,qBAAqB,EAAE;QACvD,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,uBAAuB,EAAE;QAC7D,cAAc,EAAE,GAAG;QACnB,UAAU,EAAE,KAAK;KACjB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { fetchDownstream } from \"./downstream-http.js\";\n\nconst DEFAULT_OAUTH_HTTP_MAX_ATTEMPTS = 1;\nconst DEFAULT_OAUTH_HTTP_TIMEOUT_MS = 10_000;\nconst MAX_ATTEMPTS_ENV_VARS = [\n\t\"MAESTRO_OAUTH_HTTP_MAX_ATTEMPTS\",\n\t\"OAUTH_HTTP_MAX_ATTEMPTS\",\n] as const;\nconst TIMEOUT_ENV_VARS = [\n\t\"MAESTRO_OAUTH_HTTP_TIMEOUT_MS\",\n\t\"OAUTH_HTTP_TIMEOUT_MS\",\n] as const;\n\ninterface OAuthHttpOptions {\n\tmaxAttempts?: number;\n\tserviceName: string;\n\ttimeoutMs?: number;\n}\n\nfunction getEnvPositiveInt(names: readonly string[], fallback: number): number {\n\tfor (const name of names) {\n\t\tconst value = process.env[name]?.trim();\n\t\tif (!value) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst parsed = Number.parseInt(value, 10);\n\t\tif (Number.isFinite(parsed) && parsed > 0) {\n\t\t\treturn parsed;\n\t\t}\n\t}\n\treturn fallback;\n}\n\nfunction getOAuthHttpMaxAttempts(): number {\n\treturn getEnvPositiveInt(\n\t\tMAX_ATTEMPTS_ENV_VARS,\n\t\tDEFAULT_OAUTH_HTTP_MAX_ATTEMPTS,\n\t);\n}\n\nfunction getOAuthHttpTimeoutMs(): number {\n\treturn getEnvPositiveInt(TIMEOUT_ENV_VARS, DEFAULT_OAUTH_HTTP_TIMEOUT_MS);\n}\n\nexport function fetchOAuthHttp(\n\tinput: Parameters<typeof fetch>[0],\n\tinit: RequestInit,\n\toptions: OAuthHttpOptions,\n): Promise<Response> {\n\treturn fetchDownstream(input, init, {\n\t\tserviceName: options.serviceName,\n\t\tfailureMode: \"required\",\n\t\ttimeoutMs: options.timeoutMs ?? getOAuthHttpTimeoutMs(),\n\t\tmaxAttempts: options.maxAttempts ?? getOAuthHttpMaxAttempts(),\n\t\tinitialDelayMs: 100,\n\t\tmaxDelayMs: 1_000,\n\t});\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function uniquePaths(paths: ReadonlyArray<string | null | undefined>): string[];
2
+ //# sourceMappingURL=path-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-utils.d.ts","sourceRoot":"","sources":["../../src/utils/path-utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAC1B,KAAK,EAAE,aAAa,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAC7C,MAAM,EAAE,CASV"}
@@ -0,0 +1,12 @@
1
+ export function uniquePaths(paths) {
2
+ const seen = new Set();
3
+ const result = [];
4
+ for (const path of paths) {
5
+ if (!path || seen.has(path))
6
+ continue;
7
+ seen.add(path);
8
+ result.push(path);
9
+ }
10
+ return result;
11
+ }
12
+ //# sourceMappingURL=path-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-utils.js","sourceRoot":"","sources":["../../src/utils/path-utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAC1B,KAA+C;IAE/C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QACtC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC","sourcesContent":["export function uniquePaths(\n\tpaths: ReadonlyArray<string | null | undefined>,\n): string[] {\n\tconst seen = new Set<string>();\n\tconst result: string[] = [];\n\tfor (const path of paths) {\n\t\tif (!path || seen.has(path)) continue;\n\t\tseen.add(path);\n\t\tresult.push(path);\n\t}\n\treturn result;\n}\n"]}
@@ -52,7 +52,7 @@ export declare function validatePathSync(path: string, baseDir?: string): string
52
52
  /**
53
53
  * Check if a path is within the current working directory
54
54
  */
55
- export declare function isWithinCwd(path: string): boolean;
55
+ export declare function isWithinCwd(path: string, cwd?: string): boolean;
56
56
  /**
57
57
  * Safely join paths with validation
58
58
  */
@@ -1 +1 @@
1
- {"version":3,"file":"path-validation.d.ts","sourceRoot":"","sources":["../../src/utils/path-validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;aAG5B,IAAI,EAAE,MAAM;aACZ,MAAM,EAAE,MAAM;gBAF9B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM;CAK/B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAevE;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC,gCAAgC;IAChC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,sCAAsC;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sCAAsC;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,wBAAwB;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,YAAY,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,qBAA0B,GACjC,OAAO,CAAC,MAAM,CAAC,CA8HjB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAYvE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CASjD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAiBjE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAClC,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,GAAE,qBAA0B,GACjC,OAAO,CAAC,MAAM,EAAE,CAAC,CAEnB"}
1
+ {"version":3,"file":"path-validation.d.ts","sourceRoot":"","sources":["../../src/utils/path-validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;aAG5B,IAAI,EAAE,MAAM;aACZ,MAAM,EAAE,MAAM;gBAF9B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM;CAK/B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAevE;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC,gCAAgC;IAChC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,sCAAsC;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sCAAsC;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,wBAAwB;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,YAAY,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,qBAA0B,GACjC,OAAO,CAAC,MAAM,CAAC,CA8HjB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAYvE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAgB,GAAG,OAAO,CAStE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAiBjE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAClC,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,GAAE,qBAA0B,GACjC,OAAO,CAAC,MAAM,EAAE,CAAC,CAEnB"}
@@ -153,12 +153,12 @@ export function validatePathSync(path, baseDir) {
153
153
  /**
154
154
  * Check if a path is within the current working directory
155
155
  */
156
- export function isWithinCwd(path) {
156
+ export function isWithinCwd(path, cwd = process.cwd()) {
157
157
  const normalizedPath = normalizePath(path);
158
- const cwd = process.cwd();
158
+ const normalizedCwd = normalizePath(cwd);
159
159
  const isWindows = process.platform === "win32";
160
160
  const pathCheck = isWindows ? normalizedPath.toLowerCase() : normalizedPath;
161
- const cwdCheck = isWindows ? cwd.toLowerCase() : cwd;
161
+ const cwdCheck = isWindows ? normalizedCwd.toLowerCase() : normalizedCwd;
162
162
  return pathCheck.startsWith(cwdCheck + sep) || pathCheck === cwdCheck;
163
163
  }
164
164
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"path-validation.js","sourceRoot":"","sources":["../../src/utils/path-validation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Path validation utilities for secure file operations.\n * Prevents path traversal attacks and validates file paths.\n */\n\nimport { constants } from \"node:fs\";\nimport { access, realpath, stat } from \"node:fs/promises\";\nimport { basename, isAbsolute, normalize, resolve, sep } from \"node:path\";\nimport { ERRORS, LIMITS } from \"../config/constants.js\";\nimport { createLogger } from \"./logger.js\";\nimport { expandTildePathWithHomeDir, getHomeDir } from \"./path-expansion.js\";\n\nconst logger = createLogger(\"path-validation\");\n\n/**\n * Error thrown when path validation fails\n */\nexport class PathValidationError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly path: string,\n\t\tpublic readonly reason: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"PathValidationError\";\n\t}\n}\n\n/**\n * Expand ~ to home directory\n */\nexport function expandUserPath(path: string): string {\n\treturn expandTildePathWithHomeDir(path, getHomeDir());\n}\n\n/**\n * Normalize and resolve path to absolute form\n */\nexport function normalizePath(path: string): string {\n\tconst expanded = expandUserPath(path);\n\tconst normalized = normalize(expanded);\n\treturn isAbsolute(normalized)\n\t\t? normalized\n\t\t: resolve(process.cwd(), normalized);\n}\n\n/**\n * Check if path attempts to escape a base directory\n */\nexport function isPathTraversal(path: string, baseDir?: string): boolean {\n\tconst normalizedPath = normalizePath(path);\n\tconst base = baseDir ? normalizePath(baseDir) : process.cwd();\n\n\t// Check if the normalized path starts with the base directory\n\tconst isWindows = process.platform === \"win32\";\n\tconst normalizedPathCheck = isWindows\n\t\t? normalizedPath.toLowerCase()\n\t\t: normalizedPath;\n\tconst baseCheck = isWindows ? base.toLowerCase() : base;\n\n\treturn (\n\t\t!normalizedPathCheck.startsWith(baseCheck + sep) &&\n\t\tnormalizedPathCheck !== baseCheck\n\t);\n}\n\n/**\n * Validate that a path is safe and accessible\n */\nexport interface PathValidationOptions {\n\t/** Require the path to exist */\n\tmustExist?: boolean;\n\t/** Require the path to be readable */\n\tmustBeReadable?: boolean;\n\t/** Require the path to be writable */\n\tmustBeWritable?: boolean;\n\t/** Base directory to restrict access to */\n\tbaseDir?: string;\n\t/** Maximum file size in bytes */\n\tmaxSize?: number;\n\t/** Allowed file extensions */\n\tallowedExtensions?: Set<string>;\n\t/** Disallow symlinks */\n\tnoSymlinks?: boolean;\n}\n\n/**\n * Comprehensive path validation\n */\nexport async function validatePath(\n\tpath: string,\n\toptions: PathValidationOptions = {},\n): Promise<string> {\n\tconst {\n\t\tmustExist = false,\n\t\tmustBeReadable = false,\n\t\tmustBeWritable = false,\n\t\tbaseDir,\n\t\tmaxSize,\n\t\tallowedExtensions,\n\t\tnoSymlinks = false,\n\t} = options;\n\n\t// Normalize the path\n\tlet normalizedPath: string;\n\ttry {\n\t\tnormalizedPath = normalizePath(path);\n\t} catch (error) {\n\t\tlogger.warn(\"Path normalization failed\", { path, error });\n\t\tthrow new PathValidationError(\n\t\t\t`Invalid path: ${path}`,\n\t\t\tpath,\n\t\t\t\"normalization_failed\",\n\t\t);\n\t}\n\n\t// Check for path traversal\n\tif (baseDir && isPathTraversal(normalizedPath, baseDir)) {\n\t\tlogger.warn(\"Path traversal attempt detected\", {\n\t\t\tpath,\n\t\t\tnormalizedPath,\n\t\t\tbaseDir,\n\t\t});\n\t\tthrow new PathValidationError(\n\t\t\t`Path traversal detected: ${path}`,\n\t\t\tpath,\n\t\t\t\"path_traversal\",\n\t\t);\n\t}\n\n\t// Check existence if required\n\tif (mustExist || mustBeReadable || mustBeWritable || maxSize !== undefined) {\n\t\ttry {\n\t\t\tawait access(normalizedPath, constants.F_OK);\n\t\t} catch {\n\t\t\tthrow new PathValidationError(\n\t\t\t\t`File not found: ${path}`,\n\t\t\t\tnormalizedPath,\n\t\t\t\t\"not_found\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// Check readability\n\tif (mustBeReadable) {\n\t\ttry {\n\t\t\tawait access(normalizedPath, constants.R_OK);\n\t\t} catch {\n\t\t\tthrow new PathValidationError(\n\t\t\t\t`File not readable: ${path}`,\n\t\t\t\tnormalizedPath,\n\t\t\t\t\"not_readable\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// Check writability\n\tif (mustBeWritable) {\n\t\ttry {\n\t\t\tawait access(normalizedPath, constants.W_OK);\n\t\t} catch {\n\t\t\tthrow new PathValidationError(\n\t\t\t\t`File not writable: ${path}`,\n\t\t\t\tnormalizedPath,\n\t\t\t\t\"not_writable\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// Check file size\n\tif (maxSize !== undefined) {\n\t\ttry {\n\t\t\tconst stats = await stat(normalizedPath);\n\t\t\tif (stats.size > maxSize) {\n\t\t\t\tthrow new PathValidationError(\n\t\t\t\t\t`${ERRORS.FILE_TOO_LARGE}: ${path} (${stats.size} bytes, max: ${maxSize} bytes)`,\n\t\t\t\t\tnormalizedPath,\n\t\t\t\t\t\"file_too_large\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (error instanceof PathValidationError) throw error;\n\t\t\t// Ignore stat errors if file doesn't exist\n\t\t}\n\t}\n\n\t// Check file extension from the last path segment (so dirs like .git don't affect it)\n\tif (allowedExtensions && allowedExtensions.size > 0) {\n\t\tconst name = basename(normalizedPath);\n\t\tconst lastDot = name.lastIndexOf(\".\");\n\t\tconst ext = lastDot >= 0 ? name.slice(lastDot) : \"\";\n\t\tif (!allowedExtensions.has(ext)) {\n\t\t\tthrow new PathValidationError(\n\t\t\t\t`File extension not allowed: ${ext || \"(none)\"}`,\n\t\t\t\tnormalizedPath,\n\t\t\t\t\"extension_not_allowed\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// Check for symlinks\n\tif (noSymlinks) {\n\t\ttry {\n\t\t\tconst realPath = await realpath(normalizedPath);\n\t\t\tif (realPath !== normalizedPath) {\n\t\t\t\tthrow new PathValidationError(\n\t\t\t\t\t`Symlinks not allowed: ${path}`,\n\t\t\t\t\tnormalizedPath,\n\t\t\t\t\t\"symlink_detected\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (error instanceof PathValidationError) throw error;\n\t\t\t// Ignore errors if file doesn't exist yet\n\t\t}\n\t}\n\n\treturn normalizedPath;\n}\n\n/**\n * Synchronous path validation (basic checks only)\n */\nexport function validatePathSync(path: string, baseDir?: string): string {\n\tconst normalizedPath = normalizePath(path);\n\n\tif (baseDir && isPathTraversal(normalizedPath, baseDir)) {\n\t\tthrow new PathValidationError(\n\t\t\t`Path traversal detected: ${path}`,\n\t\t\tpath,\n\t\t\t\"path_traversal\",\n\t\t);\n\t}\n\n\treturn normalizedPath;\n}\n\n/**\n * Check if a path is within the current working directory\n */\nexport function isWithinCwd(path: string): boolean {\n\tconst normalizedPath = normalizePath(path);\n\tconst cwd = process.cwd();\n\tconst isWindows = process.platform === \"win32\";\n\n\tconst pathCheck = isWindows ? normalizedPath.toLowerCase() : normalizedPath;\n\tconst cwdCheck = isWindows ? cwd.toLowerCase() : cwd;\n\n\treturn pathCheck.startsWith(cwdCheck + sep) || pathCheck === cwdCheck;\n}\n\n/**\n * Safely join paths with validation\n */\nexport function safejoin(base: string, ...parts: string[]): string {\n\tconst joined = resolve(base, ...parts);\n\tconst normalizedBase = normalizePath(base);\n\n\tconst isWindows = process.platform === \"win32\";\n\tconst joinedCheck = isWindows ? joined.toLowerCase() : joined;\n\tconst baseCheck = isWindows ? normalizedBase.toLowerCase() : normalizedBase;\n\n\tif (!joinedCheck.startsWith(baseCheck + sep) && joinedCheck !== baseCheck) {\n\t\tthrow new PathValidationError(\n\t\t\t`Path would escape base directory: ${parts.join(\"/\")}`,\n\t\t\tjoined,\n\t\t\t\"path_traversal\",\n\t\t);\n\t}\n\n\treturn joined;\n}\n\n/**\n * Validate multiple paths in parallel\n */\nexport async function validatePaths(\n\tpaths: string[],\n\toptions: PathValidationOptions = {},\n): Promise<string[]> {\n\treturn Promise.all(paths.map((path) => validatePath(path, options)));\n}\n"]}
1
+ {"version":3,"file":"path-validation.js","sourceRoot":"","sources":["../../src/utils/path-validation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Path validation utilities for secure file operations.\n * Prevents path traversal attacks and validates file paths.\n */\n\nimport { constants } from \"node:fs\";\nimport { access, realpath, stat } from \"node:fs/promises\";\nimport { basename, isAbsolute, normalize, resolve, sep } from \"node:path\";\nimport { ERRORS, LIMITS } from \"../config/constants.js\";\nimport { createLogger } from \"./logger.js\";\nimport { expandTildePathWithHomeDir, getHomeDir } from \"./path-expansion.js\";\n\nconst logger = createLogger(\"path-validation\");\n\n/**\n * Error thrown when path validation fails\n */\nexport class PathValidationError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly path: string,\n\t\tpublic readonly reason: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"PathValidationError\";\n\t}\n}\n\n/**\n * Expand ~ to home directory\n */\nexport function expandUserPath(path: string): string {\n\treturn expandTildePathWithHomeDir(path, getHomeDir());\n}\n\n/**\n * Normalize and resolve path to absolute form\n */\nexport function normalizePath(path: string): string {\n\tconst expanded = expandUserPath(path);\n\tconst normalized = normalize(expanded);\n\treturn isAbsolute(normalized)\n\t\t? normalized\n\t\t: resolve(process.cwd(), normalized);\n}\n\n/**\n * Check if path attempts to escape a base directory\n */\nexport function isPathTraversal(path: string, baseDir?: string): boolean {\n\tconst normalizedPath = normalizePath(path);\n\tconst base = baseDir ? normalizePath(baseDir) : process.cwd();\n\n\t// Check if the normalized path starts with the base directory\n\tconst isWindows = process.platform === \"win32\";\n\tconst normalizedPathCheck = isWindows\n\t\t? normalizedPath.toLowerCase()\n\t\t: normalizedPath;\n\tconst baseCheck = isWindows ? base.toLowerCase() : base;\n\n\treturn (\n\t\t!normalizedPathCheck.startsWith(baseCheck + sep) &&\n\t\tnormalizedPathCheck !== baseCheck\n\t);\n}\n\n/**\n * Validate that a path is safe and accessible\n */\nexport interface PathValidationOptions {\n\t/** Require the path to exist */\n\tmustExist?: boolean;\n\t/** Require the path to be readable */\n\tmustBeReadable?: boolean;\n\t/** Require the path to be writable */\n\tmustBeWritable?: boolean;\n\t/** Base directory to restrict access to */\n\tbaseDir?: string;\n\t/** Maximum file size in bytes */\n\tmaxSize?: number;\n\t/** Allowed file extensions */\n\tallowedExtensions?: Set<string>;\n\t/** Disallow symlinks */\n\tnoSymlinks?: boolean;\n}\n\n/**\n * Comprehensive path validation\n */\nexport async function validatePath(\n\tpath: string,\n\toptions: PathValidationOptions = {},\n): Promise<string> {\n\tconst {\n\t\tmustExist = false,\n\t\tmustBeReadable = false,\n\t\tmustBeWritable = false,\n\t\tbaseDir,\n\t\tmaxSize,\n\t\tallowedExtensions,\n\t\tnoSymlinks = false,\n\t} = options;\n\n\t// Normalize the path\n\tlet normalizedPath: string;\n\ttry {\n\t\tnormalizedPath = normalizePath(path);\n\t} catch (error) {\n\t\tlogger.warn(\"Path normalization failed\", { path, error });\n\t\tthrow new PathValidationError(\n\t\t\t`Invalid path: ${path}`,\n\t\t\tpath,\n\t\t\t\"normalization_failed\",\n\t\t);\n\t}\n\n\t// Check for path traversal\n\tif (baseDir && isPathTraversal(normalizedPath, baseDir)) {\n\t\tlogger.warn(\"Path traversal attempt detected\", {\n\t\t\tpath,\n\t\t\tnormalizedPath,\n\t\t\tbaseDir,\n\t\t});\n\t\tthrow new PathValidationError(\n\t\t\t`Path traversal detected: ${path}`,\n\t\t\tpath,\n\t\t\t\"path_traversal\",\n\t\t);\n\t}\n\n\t// Check existence if required\n\tif (mustExist || mustBeReadable || mustBeWritable || maxSize !== undefined) {\n\t\ttry {\n\t\t\tawait access(normalizedPath, constants.F_OK);\n\t\t} catch {\n\t\t\tthrow new PathValidationError(\n\t\t\t\t`File not found: ${path}`,\n\t\t\t\tnormalizedPath,\n\t\t\t\t\"not_found\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// Check readability\n\tif (mustBeReadable) {\n\t\ttry {\n\t\t\tawait access(normalizedPath, constants.R_OK);\n\t\t} catch {\n\t\t\tthrow new PathValidationError(\n\t\t\t\t`File not readable: ${path}`,\n\t\t\t\tnormalizedPath,\n\t\t\t\t\"not_readable\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// Check writability\n\tif (mustBeWritable) {\n\t\ttry {\n\t\t\tawait access(normalizedPath, constants.W_OK);\n\t\t} catch {\n\t\t\tthrow new PathValidationError(\n\t\t\t\t`File not writable: ${path}`,\n\t\t\t\tnormalizedPath,\n\t\t\t\t\"not_writable\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// Check file size\n\tif (maxSize !== undefined) {\n\t\ttry {\n\t\t\tconst stats = await stat(normalizedPath);\n\t\t\tif (stats.size > maxSize) {\n\t\t\t\tthrow new PathValidationError(\n\t\t\t\t\t`${ERRORS.FILE_TOO_LARGE}: ${path} (${stats.size} bytes, max: ${maxSize} bytes)`,\n\t\t\t\t\tnormalizedPath,\n\t\t\t\t\t\"file_too_large\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (error instanceof PathValidationError) throw error;\n\t\t\t// Ignore stat errors if file doesn't exist\n\t\t}\n\t}\n\n\t// Check file extension from the last path segment (so dirs like .git don't affect it)\n\tif (allowedExtensions && allowedExtensions.size > 0) {\n\t\tconst name = basename(normalizedPath);\n\t\tconst lastDot = name.lastIndexOf(\".\");\n\t\tconst ext = lastDot >= 0 ? name.slice(lastDot) : \"\";\n\t\tif (!allowedExtensions.has(ext)) {\n\t\t\tthrow new PathValidationError(\n\t\t\t\t`File extension not allowed: ${ext || \"(none)\"}`,\n\t\t\t\tnormalizedPath,\n\t\t\t\t\"extension_not_allowed\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// Check for symlinks\n\tif (noSymlinks) {\n\t\ttry {\n\t\t\tconst realPath = await realpath(normalizedPath);\n\t\t\tif (realPath !== normalizedPath) {\n\t\t\t\tthrow new PathValidationError(\n\t\t\t\t\t`Symlinks not allowed: ${path}`,\n\t\t\t\t\tnormalizedPath,\n\t\t\t\t\t\"symlink_detected\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (error instanceof PathValidationError) throw error;\n\t\t\t// Ignore errors if file doesn't exist yet\n\t\t}\n\t}\n\n\treturn normalizedPath;\n}\n\n/**\n * Synchronous path validation (basic checks only)\n */\nexport function validatePathSync(path: string, baseDir?: string): string {\n\tconst normalizedPath = normalizePath(path);\n\n\tif (baseDir && isPathTraversal(normalizedPath, baseDir)) {\n\t\tthrow new PathValidationError(\n\t\t\t`Path traversal detected: ${path}`,\n\t\t\tpath,\n\t\t\t\"path_traversal\",\n\t\t);\n\t}\n\n\treturn normalizedPath;\n}\n\n/**\n * Check if a path is within the current working directory\n */\nexport function isWithinCwd(path: string, cwd = process.cwd()): boolean {\n\tconst normalizedPath = normalizePath(path);\n\tconst normalizedCwd = normalizePath(cwd);\n\tconst isWindows = process.platform === \"win32\";\n\n\tconst pathCheck = isWindows ? normalizedPath.toLowerCase() : normalizedPath;\n\tconst cwdCheck = isWindows ? normalizedCwd.toLowerCase() : normalizedCwd;\n\n\treturn pathCheck.startsWith(cwdCheck + sep) || pathCheck === cwdCheck;\n}\n\n/**\n * Safely join paths with validation\n */\nexport function safejoin(base: string, ...parts: string[]): string {\n\tconst joined = resolve(base, ...parts);\n\tconst normalizedBase = normalizePath(base);\n\n\tconst isWindows = process.platform === \"win32\";\n\tconst joinedCheck = isWindows ? joined.toLowerCase() : joined;\n\tconst baseCheck = isWindows ? normalizedBase.toLowerCase() : normalizedBase;\n\n\tif (!joinedCheck.startsWith(baseCheck + sep) && joinedCheck !== baseCheck) {\n\t\tthrow new PathValidationError(\n\t\t\t`Path would escape base directory: ${parts.join(\"/\")}`,\n\t\t\tjoined,\n\t\t\t\"path_traversal\",\n\t\t);\n\t}\n\n\treturn joined;\n}\n\n/**\n * Validate multiple paths in parallel\n */\nexport async function validatePaths(\n\tpaths: string[],\n\toptions: PathValidationOptions = {},\n): Promise<string[]> {\n\treturn Promise.all(paths.map((path) => validatePath(path, options)));\n}\n"]}
package/dist/version.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "version": "0.10.8",
3
- "notes": "Maestro by EvalOps - Deterministic coding agent with TUI/CLI and Web UI for AI-assisted development v0.10.8 is now available."
2
+ "version": "0.10.11",
3
+ "notes": "Maestro by EvalOps - Deterministic coding agent with TUI/CLI and Web UI for AI-assisted development v0.10.11 is now available."
4
4
  }