@syrin/cli 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (438) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +302 -0
  3. package/dist/cli/commands/analyse.d.ts +16 -0
  4. package/dist/cli/commands/analyse.js +61 -0
  5. package/dist/cli/commands/dev.d.ts +23 -0
  6. package/dist/cli/commands/dev.js +419 -0
  7. package/dist/cli/commands/doctor.d.ts +10 -0
  8. package/dist/cli/commands/doctor.js +195 -0
  9. package/dist/cli/commands/index.d.ts +12 -0
  10. package/dist/cli/commands/index.js +12 -0
  11. package/dist/cli/commands/init.d.ts +16 -0
  12. package/dist/cli/commands/init.js +90 -0
  13. package/dist/cli/commands/list.d.ts +15 -0
  14. package/dist/cli/commands/list.js +50 -0
  15. package/dist/cli/commands/rollback.d.ts +12 -0
  16. package/dist/cli/commands/rollback.js +101 -0
  17. package/dist/cli/commands/test.d.ts +31 -0
  18. package/dist/cli/commands/test.js +88 -0
  19. package/dist/cli/commands/update.d.ts +9 -0
  20. package/dist/cli/commands/update.js +76 -0
  21. package/dist/cli/index.d.ts +13 -0
  22. package/dist/cli/index.js +342 -0
  23. package/dist/cli/prompts/index.d.ts +5 -0
  24. package/dist/cli/prompts/index.js +5 -0
  25. package/dist/cli/prompts/init-prompt.d.ts +17 -0
  26. package/dist/cli/prompts/init-prompt.js +263 -0
  27. package/dist/cli/utils/command-error-handler.d.ts +14 -0
  28. package/dist/cli/utils/command-error-handler.js +35 -0
  29. package/dist/cli/utils/common-types.d.ts +24 -0
  30. package/dist/cli/utils/common-types.js +6 -0
  31. package/dist/cli/utils/connection-handler.d.ts +37 -0
  32. package/dist/cli/utils/connection-handler.js +90 -0
  33. package/dist/cli/utils/index.d.ts +11 -0
  34. package/dist/cli/utils/index.js +11 -0
  35. package/dist/cli/utils/option-parsers.d.ts +41 -0
  36. package/dist/cli/utils/option-parsers.js +92 -0
  37. package/dist/cli/utils/output-utils.d.ts +12 -0
  38. package/dist/cli/utils/output-utils.js +21 -0
  39. package/dist/cli/utils/transport-resolver.d.ts +33 -0
  40. package/dist/cli/utils/transport-resolver.js +82 -0
  41. package/dist/cli/utils/version-banner.d.ts +10 -0
  42. package/dist/cli/utils/version-banner.js +26 -0
  43. package/dist/config/env-checker.d.ts +37 -0
  44. package/dist/config/env-checker.js +136 -0
  45. package/dist/config/generator.d.ts +19 -0
  46. package/dist/config/generator.js +196 -0
  47. package/dist/config/index.d.ts +9 -0
  48. package/dist/config/index.js +9 -0
  49. package/dist/config/loader.d.ts +19 -0
  50. package/dist/config/loader.js +57 -0
  51. package/dist/config/schema.d.ts +42 -0
  52. package/dist/config/schema.js +181 -0
  53. package/dist/config/syrin.template.yaml +127 -0
  54. package/dist/config/types.d.ts +87 -0
  55. package/dist/config/types.js +6 -0
  56. package/dist/constants/app.d.ts +9 -0
  57. package/dist/constants/app.js +9 -0
  58. package/dist/constants/commands.d.ts +43 -0
  59. package/dist/constants/commands.js +43 -0
  60. package/dist/constants/defaults.d.ts +18 -0
  61. package/dist/constants/defaults.js +18 -0
  62. package/dist/constants/env-vars.d.ts +11 -0
  63. package/dist/constants/env-vars.js +11 -0
  64. package/dist/constants/icons.d.ts +23 -0
  65. package/dist/constants/icons.js +23 -0
  66. package/dist/constants/index.d.ts +17 -0
  67. package/dist/constants/index.js +17 -0
  68. package/dist/constants/labels.d.ts +38 -0
  69. package/dist/constants/labels.js +42 -0
  70. package/dist/constants/links.d.ts +10 -0
  71. package/dist/constants/links.js +11 -0
  72. package/dist/constants/list.d.ts +10 -0
  73. package/dist/constants/list.js +9 -0
  74. package/dist/constants/llm.d.ts +26 -0
  75. package/dist/constants/llm.js +25 -0
  76. package/dist/constants/messages.d.ts +107 -0
  77. package/dist/constants/messages.js +138 -0
  78. package/dist/constants/paths.d.ts +29 -0
  79. package/dist/constants/paths.js +29 -0
  80. package/dist/constants/transport.d.ts +9 -0
  81. package/dist/constants/transport.js +8 -0
  82. package/dist/events/emitter.d.ts +64 -0
  83. package/dist/events/emitter.js +142 -0
  84. package/dist/events/event-type.d.ts +66 -0
  85. package/dist/events/event-type.js +81 -0
  86. package/dist/events/payloads/diagnostics.d.ts +24 -0
  87. package/dist/events/payloads/diagnostics.js +5 -0
  88. package/dist/events/payloads/index.d.ts +15 -0
  89. package/dist/events/payloads/index.js +6 -0
  90. package/dist/events/payloads/llm.d.ts +58 -0
  91. package/dist/events/payloads/llm.js +6 -0
  92. package/dist/events/payloads/registry.d.ts +28 -0
  93. package/dist/events/payloads/registry.js +5 -0
  94. package/dist/events/payloads/session.d.ts +32 -0
  95. package/dist/events/payloads/session.js +5 -0
  96. package/dist/events/payloads/testing.d.ts +17 -0
  97. package/dist/events/payloads/testing.js +5 -0
  98. package/dist/events/payloads/tool.d.ts +29 -0
  99. package/dist/events/payloads/tool.js +5 -0
  100. package/dist/events/payloads/transport.d.ts +30 -0
  101. package/dist/events/payloads/transport.js +5 -0
  102. package/dist/events/payloads/validation.d.ts +37 -0
  103. package/dist/events/payloads/validation.js +5 -0
  104. package/dist/events/payloads/workflow.d.ts +45 -0
  105. package/dist/events/payloads/workflow.js +5 -0
  106. package/dist/events/store/file-store.d.ts +37 -0
  107. package/dist/events/store/file-store.js +113 -0
  108. package/dist/events/store/index.d.ts +7 -0
  109. package/dist/events/store/index.js +6 -0
  110. package/dist/events/store/memory-store.d.ts +26 -0
  111. package/dist/events/store/memory-store.js +39 -0
  112. package/dist/events/store.d.ts +11 -0
  113. package/dist/events/store.js +2 -0
  114. package/dist/events/types.d.ts +14 -0
  115. package/dist/events/types.js +2 -0
  116. package/dist/index.d.ts +8 -0
  117. package/dist/index.js +30 -0
  118. package/dist/presentation/analysis-ui.d.ts +24 -0
  119. package/dist/presentation/analysis-ui.js +158 -0
  120. package/dist/presentation/dev/chat-ui-types.d.ts +68 -0
  121. package/dist/presentation/dev/chat-ui-types.js +5 -0
  122. package/dist/presentation/dev/chat-ui.d.ts +61 -0
  123. package/dist/presentation/dev/chat-ui.js +714 -0
  124. package/dist/presentation/dev/components/assistant-message.d.ts +19 -0
  125. package/dist/presentation/dev/components/assistant-message.js +36 -0
  126. package/dist/presentation/dev/components/header.d.ts +16 -0
  127. package/dist/presentation/dev/components/header.js +22 -0
  128. package/dist/presentation/dev/components/index.d.ts +13 -0
  129. package/dist/presentation/dev/components/index.js +13 -0
  130. package/dist/presentation/dev/components/input-panel.d.ts +22 -0
  131. package/dist/presentation/dev/components/input-panel.js +43 -0
  132. package/dist/presentation/dev/components/message-component.d.ts +16 -0
  133. package/dist/presentation/dev/components/message-component.js +51 -0
  134. package/dist/presentation/dev/components/messages-list.d.ts +24 -0
  135. package/dist/presentation/dev/components/messages-list.js +48 -0
  136. package/dist/presentation/dev/components/system-message.d.ts +16 -0
  137. package/dist/presentation/dev/components/system-message.js +26 -0
  138. package/dist/presentation/dev/components/user-message.d.ts +21 -0
  139. package/dist/presentation/dev/components/user-message.js +35 -0
  140. package/dist/presentation/dev/components/welcome-banner.d.ts +24 -0
  141. package/dist/presentation/dev/components/welcome-banner.js +146 -0
  142. package/dist/presentation/dev/goodbye-messages.d.ts +31 -0
  143. package/dist/presentation/dev/goodbye-messages.js +100 -0
  144. package/dist/presentation/dev/index.d.ts +5 -0
  145. package/dist/presentation/dev/index.js +5 -0
  146. package/dist/presentation/dev/text-wrapper.d.ts +30 -0
  147. package/dist/presentation/dev/text-wrapper.js +74 -0
  148. package/dist/presentation/dev-ui.d.ts +33 -0
  149. package/dist/presentation/dev-ui.js +246 -0
  150. package/dist/presentation/doctor-ui.d.ts +40 -0
  151. package/dist/presentation/doctor-ui.js +157 -0
  152. package/dist/presentation/init-ui.d.ts +14 -0
  153. package/dist/presentation/init-ui.js +41 -0
  154. package/dist/presentation/list-ui.d.ts +44 -0
  155. package/dist/presentation/list-ui.js +139 -0
  156. package/dist/presentation/test-ui.d.ts +49 -0
  157. package/dist/presentation/test-ui.js +358 -0
  158. package/dist/runtime/analysis/analyser.d.ts +14 -0
  159. package/dist/runtime/analysis/analyser.js +88 -0
  160. package/dist/runtime/analysis/dependencies.d.ts +10 -0
  161. package/dist/runtime/analysis/dependencies.js +140 -0
  162. package/dist/runtime/analysis/index.d.ts +10 -0
  163. package/dist/runtime/analysis/index.js +10 -0
  164. package/dist/runtime/analysis/indexer.d.ts +10 -0
  165. package/dist/runtime/analysis/indexer.js +62 -0
  166. package/dist/runtime/analysis/loader.d.ts +15 -0
  167. package/dist/runtime/analysis/loader.js +47 -0
  168. package/dist/runtime/analysis/normalizer.d.ts +14 -0
  169. package/dist/runtime/analysis/normalizer.js +184 -0
  170. package/dist/runtime/analysis/rules/__test-helpers__.d.ts +18 -0
  171. package/dist/runtime/analysis/rules/__test-helpers__.js +40 -0
  172. package/dist/runtime/analysis/rules/base.d.ts +38 -0
  173. package/dist/runtime/analysis/rules/base.js +23 -0
  174. package/dist/runtime/analysis/rules/error-codes.d.ts +64 -0
  175. package/dist/runtime/analysis/rules/error-codes.js +73 -0
  176. package/dist/runtime/analysis/rules/errors/e000-tool-not-found.d.ts +35 -0
  177. package/dist/runtime/analysis/rules/errors/e000-tool-not-found.js +32 -0
  178. package/dist/runtime/analysis/rules/errors/e001-missing-output-schema.d.ts +22 -0
  179. package/dist/runtime/analysis/rules/errors/e001-missing-output-schema.js +30 -0
  180. package/dist/runtime/analysis/rules/errors/e002-underspecified-input.d.ts +24 -0
  181. package/dist/runtime/analysis/rules/errors/e002-underspecified-input.js +52 -0
  182. package/dist/runtime/analysis/rules/errors/e003-type-mismatch.d.ts +23 -0
  183. package/dist/runtime/analysis/rules/errors/e003-type-mismatch.js +73 -0
  184. package/dist/runtime/analysis/rules/errors/e004-free-text-propagation.d.ts +23 -0
  185. package/dist/runtime/analysis/rules/errors/e004-free-text-propagation.js +47 -0
  186. package/dist/runtime/analysis/rules/errors/e005-tool-ambiguity.d.ts +25 -0
  187. package/dist/runtime/analysis/rules/errors/e005-tool-ambiguity.js +73 -0
  188. package/dist/runtime/analysis/rules/errors/e006-param-not-in-description.d.ts +22 -0
  189. package/dist/runtime/analysis/rules/errors/e006-param-not-in-description.js +57 -0
  190. package/dist/runtime/analysis/rules/errors/e007-output-not-guaranteed.d.ts +23 -0
  191. package/dist/runtime/analysis/rules/errors/e007-output-not-guaranteed.js +56 -0
  192. package/dist/runtime/analysis/rules/errors/e008-circular-dependency.d.ts +22 -0
  193. package/dist/runtime/analysis/rules/errors/e008-circular-dependency.js +84 -0
  194. package/dist/runtime/analysis/rules/errors/e009-implicit-user-input.d.ts +23 -0
  195. package/dist/runtime/analysis/rules/errors/e009-implicit-user-input.js +89 -0
  196. package/dist/runtime/analysis/rules/errors/e010-non-serializable.d.ts +25 -0
  197. package/dist/runtime/analysis/rules/errors/e010-non-serializable.js +46 -0
  198. package/dist/runtime/analysis/rules/errors/e011-missing-tool-description.d.ts +24 -0
  199. package/dist/runtime/analysis/rules/errors/e011-missing-tool-description.js +33 -0
  200. package/dist/runtime/analysis/rules/errors/e012-side-effect-detected.d.ts +39 -0
  201. package/dist/runtime/analysis/rules/errors/e012-side-effect-detected.js +40 -0
  202. package/dist/runtime/analysis/rules/errors/e013-non-deterministic-output.d.ts +37 -0
  203. package/dist/runtime/analysis/rules/errors/e013-non-deterministic-output.js +34 -0
  204. package/dist/runtime/analysis/rules/errors/e013-output-explosion.d.ts +39 -0
  205. package/dist/runtime/analysis/rules/errors/e013-output-explosion.js +36 -0
  206. package/dist/runtime/analysis/rules/errors/e014-hidden-dependency.d.ts +42 -0
  207. package/dist/runtime/analysis/rules/errors/e014-hidden-dependency.js +46 -0
  208. package/dist/runtime/analysis/rules/errors/e014-output-explosion.d.ts +39 -0
  209. package/dist/runtime/analysis/rules/errors/e014-output-explosion.js +36 -0
  210. package/dist/runtime/analysis/rules/errors/e015-hidden-dependency.d.ts +42 -0
  211. package/dist/runtime/analysis/rules/errors/e015-hidden-dependency.js +46 -0
  212. package/dist/runtime/analysis/rules/errors/e015-unbounded-execution.d.ts +44 -0
  213. package/dist/runtime/analysis/rules/errors/e015-unbounded-execution.js +66 -0
  214. package/dist/runtime/analysis/rules/errors/e016-output-validation-failed.d.ts +43 -0
  215. package/dist/runtime/analysis/rules/errors/e016-output-validation-failed.js +42 -0
  216. package/dist/runtime/analysis/rules/errors/e016-unbounded-execution.d.ts +44 -0
  217. package/dist/runtime/analysis/rules/errors/e016-unbounded-execution.js +66 -0
  218. package/dist/runtime/analysis/rules/errors/e017-input-validation-failed.d.ts +57 -0
  219. package/dist/runtime/analysis/rules/errors/e017-input-validation-failed.js +80 -0
  220. package/dist/runtime/analysis/rules/errors/e017-output-validation-failed.d.ts +43 -0
  221. package/dist/runtime/analysis/rules/errors/e017-output-validation-failed.js +42 -0
  222. package/dist/runtime/analysis/rules/errors/e018-input-validation-failed.d.ts +57 -0
  223. package/dist/runtime/analysis/rules/errors/e018-input-validation-failed.js +80 -0
  224. package/dist/runtime/analysis/rules/errors/e018-tool-execution-failed.d.ts +38 -0
  225. package/dist/runtime/analysis/rules/errors/e018-tool-execution-failed.js +37 -0
  226. package/dist/runtime/analysis/rules/errors/e019-tool-execution-failed.d.ts +38 -0
  227. package/dist/runtime/analysis/rules/errors/e019-tool-execution-failed.js +37 -0
  228. package/dist/runtime/analysis/rules/errors/e019-unexpected-test-result.d.ts +65 -0
  229. package/dist/runtime/analysis/rules/errors/e019-unexpected-test-result.js +109 -0
  230. package/dist/runtime/analysis/rules/errors/e020-unexpected-test-result.d.ts +65 -0
  231. package/dist/runtime/analysis/rules/errors/e020-unexpected-test-result.js +109 -0
  232. package/dist/runtime/analysis/rules/errors/e100-missing-output-schema.d.ts +22 -0
  233. package/dist/runtime/analysis/rules/errors/e100-missing-output-schema.js +30 -0
  234. package/dist/runtime/analysis/rules/errors/e101-missing-tool-description.d.ts +24 -0
  235. package/dist/runtime/analysis/rules/errors/e101-missing-tool-description.js +33 -0
  236. package/dist/runtime/analysis/rules/errors/e102-underspecified-input.d.ts +24 -0
  237. package/dist/runtime/analysis/rules/errors/e102-underspecified-input.js +52 -0
  238. package/dist/runtime/analysis/rules/errors/e103-type-mismatch.d.ts +23 -0
  239. package/dist/runtime/analysis/rules/errors/e103-type-mismatch.js +72 -0
  240. package/dist/runtime/analysis/rules/errors/e104-param-not-in-description.d.ts +22 -0
  241. package/dist/runtime/analysis/rules/errors/e104-param-not-in-description.js +57 -0
  242. package/dist/runtime/analysis/rules/errors/e105-free-text-propagation.d.ts +23 -0
  243. package/dist/runtime/analysis/rules/errors/e105-free-text-propagation.js +47 -0
  244. package/dist/runtime/analysis/rules/errors/e106-output-not-guaranteed.d.ts +23 -0
  245. package/dist/runtime/analysis/rules/errors/e106-output-not-guaranteed.js +58 -0
  246. package/dist/runtime/analysis/rules/errors/e107-circular-dependency.d.ts +22 -0
  247. package/dist/runtime/analysis/rules/errors/e107-circular-dependency.js +84 -0
  248. package/dist/runtime/analysis/rules/errors/e108-implicit-user-input.d.ts +23 -0
  249. package/dist/runtime/analysis/rules/errors/e108-implicit-user-input.js +94 -0
  250. package/dist/runtime/analysis/rules/errors/e109-non-serializable.d.ts +25 -0
  251. package/dist/runtime/analysis/rules/errors/e109-non-serializable.js +44 -0
  252. package/dist/runtime/analysis/rules/errors/e110-tool-ambiguity.d.ts +25 -0
  253. package/dist/runtime/analysis/rules/errors/e110-tool-ambiguity.js +73 -0
  254. package/dist/runtime/analysis/rules/errors/e200-input-validation-failed.d.ts +57 -0
  255. package/dist/runtime/analysis/rules/errors/e200-input-validation-failed.js +71 -0
  256. package/dist/runtime/analysis/rules/errors/e300-output-validation-failed.d.ts +43 -0
  257. package/dist/runtime/analysis/rules/errors/e300-output-validation-failed.js +44 -0
  258. package/dist/runtime/analysis/rules/errors/e301-output-explosion.d.ts +39 -0
  259. package/dist/runtime/analysis/rules/errors/e301-output-explosion.js +36 -0
  260. package/dist/runtime/analysis/rules/errors/e400-tool-execution-failed.d.ts +38 -0
  261. package/dist/runtime/analysis/rules/errors/e400-tool-execution-failed.js +37 -0
  262. package/dist/runtime/analysis/rules/errors/e403-unbounded-execution.d.ts +44 -0
  263. package/dist/runtime/analysis/rules/errors/e403-unbounded-execution.js +66 -0
  264. package/dist/runtime/analysis/rules/errors/e500-side-effect-detected.d.ts +39 -0
  265. package/dist/runtime/analysis/rules/errors/e500-side-effect-detected.js +40 -0
  266. package/dist/runtime/analysis/rules/errors/e501-hidden-dependency.d.ts +47 -0
  267. package/dist/runtime/analysis/rules/errors/e501-hidden-dependency.js +46 -0
  268. package/dist/runtime/analysis/rules/errors/e600-unexpected-test-result.d.ts +65 -0
  269. package/dist/runtime/analysis/rules/errors/e600-unexpected-test-result.js +109 -0
  270. package/dist/runtime/analysis/rules/index.d.ts +18 -0
  271. package/dist/runtime/analysis/rules/index.js +94 -0
  272. package/dist/runtime/analysis/rules/warnings/w001-implicit-dependency.d.ts +22 -0
  273. package/dist/runtime/analysis/rules/warnings/w001-implicit-dependency.js +39 -0
  274. package/dist/runtime/analysis/rules/warnings/w002-free-text-without-normalization.d.ts +24 -0
  275. package/dist/runtime/analysis/rules/warnings/w002-free-text-without-normalization.js +40 -0
  276. package/dist/runtime/analysis/rules/warnings/w003-missing-examples.d.ts +22 -0
  277. package/dist/runtime/analysis/rules/warnings/w003-missing-examples.js +84 -0
  278. package/dist/runtime/analysis/rules/warnings/w004-overloaded-responsibility.d.ts +23 -0
  279. package/dist/runtime/analysis/rules/warnings/w004-overloaded-responsibility.js +96 -0
  280. package/dist/runtime/analysis/rules/warnings/w005-generic-description.d.ts +53 -0
  281. package/dist/runtime/analysis/rules/warnings/w005-generic-description.js +108 -0
  282. package/dist/runtime/analysis/rules/warnings/w006-optional-as-required.d.ts +22 -0
  283. package/dist/runtime/analysis/rules/warnings/w006-optional-as-required.js +44 -0
  284. package/dist/runtime/analysis/rules/warnings/w007-broad-output-schema.d.ts +23 -0
  285. package/dist/runtime/analysis/rules/warnings/w007-broad-output-schema.js +37 -0
  286. package/dist/runtime/analysis/rules/warnings/w008-multiple-entry-points.d.ts +22 -0
  287. package/dist/runtime/analysis/rules/warnings/w008-multiple-entry-points.js +97 -0
  288. package/dist/runtime/analysis/rules/warnings/w009-hidden-side-effects.d.ts +23 -0
  289. package/dist/runtime/analysis/rules/warnings/w009-hidden-side-effects.js +88 -0
  290. package/dist/runtime/analysis/rules/warnings/w010-output-not-reusable.d.ts +22 -0
  291. package/dist/runtime/analysis/rules/warnings/w010-output-not-reusable.js +81 -0
  292. package/dist/runtime/analysis/rules/warnings/w021-weak-schema.d.ts +40 -0
  293. package/dist/runtime/analysis/rules/warnings/w021-weak-schema.js +32 -0
  294. package/dist/runtime/analysis/rules/warnings/w022-high-entropy-output.d.ts +39 -0
  295. package/dist/runtime/analysis/rules/warnings/w022-high-entropy-output.js +36 -0
  296. package/dist/runtime/analysis/rules/warnings/w023-unstable-defaults.d.ts +38 -0
  297. package/dist/runtime/analysis/rules/warnings/w023-unstable-defaults.js +36 -0
  298. package/dist/runtime/analysis/rules/warnings/w100-implicit-dependency.d.ts +22 -0
  299. package/dist/runtime/analysis/rules/warnings/w100-implicit-dependency.js +89 -0
  300. package/dist/runtime/analysis/rules/warnings/w101-free-text-without-normalization.d.ts +24 -0
  301. package/dist/runtime/analysis/rules/warnings/w101-free-text-without-normalization.js +40 -0
  302. package/dist/runtime/analysis/rules/warnings/w102-missing-examples.d.ts +22 -0
  303. package/dist/runtime/analysis/rules/warnings/w102-missing-examples.js +76 -0
  304. package/dist/runtime/analysis/rules/warnings/w103-overloaded-responsibility.d.ts +23 -0
  305. package/dist/runtime/analysis/rules/warnings/w103-overloaded-responsibility.js +91 -0
  306. package/dist/runtime/analysis/rules/warnings/w104-generic-description.d.ts +53 -0
  307. package/dist/runtime/analysis/rules/warnings/w104-generic-description.js +108 -0
  308. package/dist/runtime/analysis/rules/warnings/w105-optional-as-required.d.ts +22 -0
  309. package/dist/runtime/analysis/rules/warnings/w105-optional-as-required.js +45 -0
  310. package/dist/runtime/analysis/rules/warnings/w106-broad-output-schema.d.ts +23 -0
  311. package/dist/runtime/analysis/rules/warnings/w106-broad-output-schema.js +37 -0
  312. package/dist/runtime/analysis/rules/warnings/w107-multiple-entry-points.d.ts +22 -0
  313. package/dist/runtime/analysis/rules/warnings/w107-multiple-entry-points.js +97 -0
  314. package/dist/runtime/analysis/rules/warnings/w108-hidden-side-effects.d.ts +23 -0
  315. package/dist/runtime/analysis/rules/warnings/w108-hidden-side-effects.js +94 -0
  316. package/dist/runtime/analysis/rules/warnings/w109-output-not-reusable.d.ts +22 -0
  317. package/dist/runtime/analysis/rules/warnings/w109-output-not-reusable.js +63 -0
  318. package/dist/runtime/analysis/rules/warnings/w110-weak-schema.d.ts +40 -0
  319. package/dist/runtime/analysis/rules/warnings/w110-weak-schema.js +32 -0
  320. package/dist/runtime/analysis/rules/warnings/w300-high-entropy-output.d.ts +39 -0
  321. package/dist/runtime/analysis/rules/warnings/w300-high-entropy-output.js +47 -0
  322. package/dist/runtime/analysis/rules/warnings/w301-unstable-defaults.d.ts +38 -0
  323. package/dist/runtime/analysis/rules/warnings/w301-unstable-defaults.js +36 -0
  324. package/dist/runtime/analysis/strict-mode.d.ts +21 -0
  325. package/dist/runtime/analysis/strict-mode.js +44 -0
  326. package/dist/runtime/analysis/types.d.ts +133 -0
  327. package/dist/runtime/analysis/types.js +6 -0
  328. package/dist/runtime/analysis/utils.d.ts +19 -0
  329. package/dist/runtime/analysis/utils.js +21 -0
  330. package/dist/runtime/dev/data-manager.d.ts +55 -0
  331. package/dist/runtime/dev/data-manager.js +87 -0
  332. package/dist/runtime/dev/event-mapper.d.ts +100 -0
  333. package/dist/runtime/dev/event-mapper.js +400 -0
  334. package/dist/runtime/dev/formatter.d.ts +94 -0
  335. package/dist/runtime/dev/formatter.js +236 -0
  336. package/dist/runtime/dev/index.d.ts +9 -0
  337. package/dist/runtime/dev/index.js +9 -0
  338. package/dist/runtime/dev/repl.d.ts +114 -0
  339. package/dist/runtime/dev/repl.js +310 -0
  340. package/dist/runtime/dev/session.d.ts +86 -0
  341. package/dist/runtime/dev/session.js +447 -0
  342. package/dist/runtime/dev/stack-trace.d.ts +77 -0
  343. package/dist/runtime/dev/stack-trace.js +286 -0
  344. package/dist/runtime/dev/types.d.ts +54 -0
  345. package/dist/runtime/dev/types.js +5 -0
  346. package/dist/runtime/llm/claude.d.ts +27 -0
  347. package/dist/runtime/llm/claude.js +150 -0
  348. package/dist/runtime/llm/factory.d.ts +30 -0
  349. package/dist/runtime/llm/factory.js +78 -0
  350. package/dist/runtime/llm/index.d.ts +10 -0
  351. package/dist/runtime/llm/index.js +10 -0
  352. package/dist/runtime/llm/ollama.d.ts +45 -0
  353. package/dist/runtime/llm/ollama.js +449 -0
  354. package/dist/runtime/llm/openai.d.ts +27 -0
  355. package/dist/runtime/llm/openai.js +170 -0
  356. package/dist/runtime/llm/provider.d.ts +32 -0
  357. package/dist/runtime/llm/provider.js +6 -0
  358. package/dist/runtime/llm/types.d.ts +55 -0
  359. package/dist/runtime/llm/types.js +6 -0
  360. package/dist/runtime/mcp/client/base.d.ts +40 -0
  361. package/dist/runtime/mcp/client/base.js +157 -0
  362. package/dist/runtime/mcp/client/manager.d.ts +91 -0
  363. package/dist/runtime/mcp/client/manager.js +248 -0
  364. package/dist/runtime/mcp/client/process.d.ts +31 -0
  365. package/dist/runtime/mcp/client/process.js +82 -0
  366. package/dist/runtime/mcp/connection.d.ts +63 -0
  367. package/dist/runtime/mcp/connection.js +449 -0
  368. package/dist/runtime/mcp/index.d.ts +9 -0
  369. package/dist/runtime/mcp/index.js +9 -0
  370. package/dist/runtime/mcp/list.d.ts +50 -0
  371. package/dist/runtime/mcp/list.js +65 -0
  372. package/dist/runtime/mcp/stdio-transport.d.ts +23 -0
  373. package/dist/runtime/mcp/stdio-transport.js +71 -0
  374. package/dist/runtime/mcp/types.d.ts +85 -0
  375. package/dist/runtime/mcp/types.js +6 -0
  376. package/dist/runtime/sandbox/executor.d.ts +102 -0
  377. package/dist/runtime/sandbox/executor.js +537 -0
  378. package/dist/runtime/sandbox/index.d.ts +9 -0
  379. package/dist/runtime/sandbox/index.js +9 -0
  380. package/dist/runtime/sandbox/io-monitor.d.ts +78 -0
  381. package/dist/runtime/sandbox/io-monitor.js +98 -0
  382. package/dist/runtime/sandbox/time-parser.d.ts +19 -0
  383. package/dist/runtime/sandbox/time-parser.js +67 -0
  384. package/dist/runtime/sandbox/types.d.ts +58 -0
  385. package/dist/runtime/sandbox/types.js +23 -0
  386. package/dist/runtime/test/behavior-observer.d.ts +61 -0
  387. package/dist/runtime/test/behavior-observer.js +140 -0
  388. package/dist/runtime/test/contract-loader.d.ts +41 -0
  389. package/dist/runtime/test/contract-loader.js +158 -0
  390. package/dist/runtime/test/contract-schema.d.ts +46 -0
  391. package/dist/runtime/test/contract-schema.js +107 -0
  392. package/dist/runtime/test/contract-types.d.ts +106 -0
  393. package/dist/runtime/test/contract-types.js +6 -0
  394. package/dist/runtime/test/dependency-tracker.d.ts +66 -0
  395. package/dist/runtime/test/dependency-tracker.js +80 -0
  396. package/dist/runtime/test/formatters.d.ts +18 -0
  397. package/dist/runtime/test/formatters.js +172 -0
  398. package/dist/runtime/test/index.d.ts +12 -0
  399. package/dist/runtime/test/index.js +13 -0
  400. package/dist/runtime/test/input-generator.d.ts +33 -0
  401. package/dist/runtime/test/input-generator.js +498 -0
  402. package/dist/runtime/test/mcp-root-detector.d.ts +31 -0
  403. package/dist/runtime/test/mcp-root-detector.js +105 -0
  404. package/dist/runtime/test/orchestrator.d.ts +131 -0
  405. package/dist/runtime/test/orchestrator.js +738 -0
  406. package/dist/runtime/test/output-validator.d.ts +44 -0
  407. package/dist/runtime/test/output-validator.js +262 -0
  408. package/dist/runtime/test/retry-tester.d.ts +44 -0
  409. package/dist/runtime/test/retry-tester.js +103 -0
  410. package/dist/runtime/test/runner.d.ts +28 -0
  411. package/dist/runtime/test/runner.js +55 -0
  412. package/dist/runtime/test/synthetic-input-generator.d.ts +11 -0
  413. package/dist/runtime/test/synthetic-input-generator.js +154 -0
  414. package/dist/runtime/test/test-runner.d.ts +28 -0
  415. package/dist/runtime/test/test-runner.js +55 -0
  416. package/dist/types/factories.d.ts +16 -0
  417. package/dist/types/factories.js +43 -0
  418. package/dist/types/ids.d.ts +16 -0
  419. package/dist/types/ids.js +2 -0
  420. package/dist/types/opaque.d.ts +4 -0
  421. package/dist/types/opaque.js +2 -0
  422. package/dist/utils/errors.d.ts +92 -0
  423. package/dist/utils/errors.js +97 -0
  424. package/dist/utils/gitignore.d.ts +11 -0
  425. package/dist/utils/gitignore.js +59 -0
  426. package/dist/utils/json-file-saver.d.ts +17 -0
  427. package/dist/utils/json-file-saver.js +81 -0
  428. package/dist/utils/json-formatter.d.ts +63 -0
  429. package/dist/utils/json-formatter.js +344 -0
  430. package/dist/utils/logger.d.ts +184 -0
  431. package/dist/utils/logger.js +330 -0
  432. package/dist/utils/package-manager.d.ts +30 -0
  433. package/dist/utils/package-manager.js +157 -0
  434. package/dist/utils/version-checker.d.ts +47 -0
  435. package/dist/utils/version-checker.js +167 -0
  436. package/dist/utils/version-display.d.ts +10 -0
  437. package/dist/utils/version-display.js +20 -0
  438. package/package.json +106 -0
@@ -0,0 +1,537 @@
1
+ /**
2
+ * Sandbox executor for isolated tool execution.
3
+ * Provides isolated execution environment with process reuse for performance.
4
+ * This module is reusable for any sandboxed execution needs, not just testing.
5
+ */
6
+ import * as fs from 'fs';
7
+ import * as os from 'os';
8
+ import * as path from 'path';
9
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
10
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
11
+ import { parseCommand } from '../../runtime/mcp/client/process.js';
12
+ import { ConfigurationError } from '../../utils/errors.js';
13
+ import { formatTimeString } from './time-parser.js';
14
+ import { ToolExecutionErrorType } from './types.js';
15
+ import { logger } from '../../utils/logger.js';
16
+ // Re-export types for convenience
17
+ export * from './types.js';
18
+ /**
19
+ * Sandbox executor with process reuse.
20
+ * Starts MCP server once, executes multiple tools, then closes.
21
+ */
22
+ export class SandboxExecutor {
23
+ // Note: serverProcess is managed by StdioClientTransport internally
24
+ client = null;
25
+ transport = null;
26
+ tempDir = null;
27
+ initialized = false;
28
+ options;
29
+ constructor(options) {
30
+ this.options = options;
31
+ }
32
+ /**
33
+ * Initialize the sandbox (start MCP server process).
34
+ * This should be called once before testing multiple tools.
35
+ */
36
+ async initialize() {
37
+ if (this.initialized) {
38
+ return;
39
+ }
40
+ try {
41
+ // Create isolated temp directory
42
+ this.tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'syrin-sandbox-'));
43
+ // Parse command
44
+ let { executable, args } = parseCommand(this.options.mcpCommand);
45
+ let isWrapped = false;
46
+ // Apply memory limit enforcement if specified
47
+ if (this.options.memoryLimitMB) {
48
+ const memoryMB = this.options.memoryLimitMB;
49
+ // Check if this is a Node.js command
50
+ const isNodeCommand = executable === 'node' || executable.endsWith('/node');
51
+ if (isNodeCommand) {
52
+ // For Node.js: inject --max-old-space-size flag
53
+ args = ['--max-old-space-size', String(memoryMB), ...args];
54
+ logger.debug(`Memory limit: ${memoryMB}MB enforced via --max-old-space-size for Node.js`);
55
+ }
56
+ else if (process.platform !== 'win32') {
57
+ // For POSIX systems: wrap with ulimit -v (virtual memory limit)
58
+ // Convert MB to KB (ulimit -v uses KB)
59
+ const memoryKB = memoryMB * 1024;
60
+ // Wrap the original command with ulimit
61
+ const originalCommand = [executable, ...args]
62
+ .map(arg => (arg.includes(' ') ? `"${arg}"` : arg))
63
+ .join(' ');
64
+ executable = '/bin/sh';
65
+ args = ['-c', `ulimit -v ${memoryKB} && exec ${originalCommand}`];
66
+ isWrapped = true;
67
+ logger.debug(`Memory limit: ${memoryMB}MB (${memoryKB}KB) enforced via ulimit -v`);
68
+ }
69
+ else {
70
+ // Windows: Memory limits require different approach (SetProcessWorkingSetSize, Job Objects)
71
+ // For now, log warning that limit is not enforced on Windows
72
+ logger.warn(`Memory limit ${memoryMB}MB specified but not enforced on Windows platform`);
73
+ }
74
+ }
75
+ // Suppress stderr output if requested (for CI mode)
76
+ if (this.options.suppressStderr) {
77
+ if (process.platform !== 'win32') {
78
+ // POSIX: Add stderr redirection to /dev/null
79
+ if (isWrapped) {
80
+ // Already wrapped - add stderr redirection to the existing wrapper
81
+ args[1] = `${args[1]} 2>/dev/null`;
82
+ }
83
+ else {
84
+ // Not wrapped yet - wrap to redirect stderr
85
+ const originalCommand = [executable, ...args]
86
+ .map(arg => (arg.includes(' ') ? `"${arg}"` : arg))
87
+ .join(' ');
88
+ executable = '/bin/sh';
89
+ args = ['-c', `${originalCommand} 2>/dev/null`];
90
+ }
91
+ }
92
+ else {
93
+ // Windows: Add stderr redirection to NUL
94
+ if (isWrapped) {
95
+ // Already wrapped - add stderr redirection to the existing wrapper
96
+ args[1] = `${args[1]} 2>NUL`;
97
+ }
98
+ else {
99
+ // Not wrapped yet - wrap to redirect stderr
100
+ const originalCommand = [executable, ...args]
101
+ .map(arg => (arg.includes(' ') ? `"${arg}"` : arg))
102
+ .join(' ');
103
+ executable = 'cmd.exe';
104
+ args = ['/c', `${originalCommand} 2>NUL`];
105
+ }
106
+ }
107
+ }
108
+ // Prepare environment
109
+ const env = {
110
+ ...process.env,
111
+ ...this.options.env,
112
+ SYRIN_SANDBOX: 'true',
113
+ SYRIN_TEMP_DIR: this.tempDir,
114
+ };
115
+ // Create MCP client
116
+ this.client = new Client({
117
+ name: 'syrin-test',
118
+ version: '1.3.0',
119
+ }, {
120
+ capabilities: {},
121
+ });
122
+ // Create stdio transport (this will spawn the process automatically)
123
+ // Note: StdioClientTransport handles process spawning internally
124
+ // Use project root as cwd (not temp dir) so the server can find its files
125
+ // Memory limits are enforced via command wrapping (see above)
126
+ this.transport = new StdioClientTransport({
127
+ command: executable,
128
+ args,
129
+ env: env,
130
+ cwd: this.options.projectRoot,
131
+ });
132
+ // Set up error handlers
133
+ this.client.onerror = (event) => {
134
+ // Log connection-level errors for debugging
135
+ const errorMessage = event instanceof Error
136
+ ? event.message
137
+ : typeof event === 'object' && event !== null && 'message' in event
138
+ ? String(event.message)
139
+ : 'Unknown MCP client error';
140
+ logger.error(`MCP client connection error: ${errorMessage}`, event instanceof Error ? event : new Error(errorMessage));
141
+ // Errors will also be caught in try-catch blocks during tool execution
142
+ };
143
+ // Connect client to server (StdioClientTransport spawns the process here)
144
+ await this.client.connect(this.transport);
145
+ // Poll for server readiness with exponential backoff
146
+ const maxWaitTime = 5000; // Maximum total wait time: 5 seconds
147
+ const initialBackoff = 100; // Start with 100ms
148
+ const maxBackoff = 500; // Cap at 500ms
149
+ const startTime = Date.now();
150
+ let backoff = initialBackoff;
151
+ let lastError;
152
+ while (Date.now() - startTime < maxWaitTime) {
153
+ try {
154
+ // Try to list tools to verify server is ready
155
+ const listToolsPromise = this.client.listTools();
156
+ const timeoutPromise = new Promise((_, reject) => {
157
+ setTimeout(() => {
158
+ reject(new Error('listTools timeout'));
159
+ }, Math.min(backoff, 1000)); // Use backoff as timeout, max 1s
160
+ });
161
+ await Promise.race([listToolsPromise, timeoutPromise]);
162
+ // Success - server is ready
163
+ break;
164
+ }
165
+ catch (pollError) {
166
+ lastError =
167
+ pollError instanceof Error
168
+ ? pollError
169
+ : new Error(String(pollError));
170
+ // Check if we've exceeded max wait time
171
+ if (Date.now() - startTime >= maxWaitTime) {
172
+ throw new ConfigurationError(`MCP server did not become ready within ${maxWaitTime}ms. Command may not exist or server failed to start.`, { cause: lastError });
173
+ }
174
+ // Wait with exponential backoff before retrying
175
+ await new Promise(resolve => setTimeout(resolve, backoff));
176
+ backoff = Math.min(backoff * 1.5, maxBackoff); // Exponential backoff with cap
177
+ }
178
+ }
179
+ // Final verification (in case we exited loop due to timeout)
180
+ if (Date.now() - startTime >= maxWaitTime && lastError) {
181
+ throw new ConfigurationError(`MCP server did not become ready within ${maxWaitTime}ms. Command may not exist or server failed to start.`, { cause: lastError });
182
+ }
183
+ this.initialized = true;
184
+ }
185
+ catch (error) {
186
+ await this.cleanup();
187
+ throw error;
188
+ }
189
+ }
190
+ /**
191
+ * Parse MCP protocol response and extract output or error.
192
+ * Handles various response formats from MCP SDK.
193
+ * @param rawResult - Raw result from MCP SDK
194
+ * @param timedOut - Whether execution timed out
195
+ * @returns Object with output and error (mutually exclusive)
196
+ */
197
+ parseMcpResponse(rawResult, timedOut) {
198
+ // Handle non-object responses
199
+ if (!rawResult || typeof rawResult !== 'object') {
200
+ return { output: rawResult, error: undefined };
201
+ }
202
+ // Check for error field (MCP protocol error response)
203
+ if ('error' in rawResult && rawResult.error) {
204
+ const errorObj = rawResult.error;
205
+ const mcpError = new Error(errorObj.message ||
206
+ `Tool execution failed with code ${errorObj.code || 'unknown'}`);
207
+ return {
208
+ output: undefined,
209
+ error: this.classifyError(mcpError, rawResult, timedOut),
210
+ };
211
+ }
212
+ // Check for content array (MCP SDK standard response format)
213
+ if ('content' in rawResult) {
214
+ const content = rawResult.content;
215
+ if (!Array.isArray(content) || content.length === 0) {
216
+ return { output: rawResult, error: undefined };
217
+ }
218
+ // Check for error content in MCP protocol
219
+ const errorContent = content.find(item => item.type === 'error' || item.error);
220
+ if (errorContent) {
221
+ const errorMessage = errorContent
222
+ .text ||
223
+ errorContent.error?.message ||
224
+ 'Tool execution failed';
225
+ const mcpError = new Error(errorMessage);
226
+ return {
227
+ output: undefined,
228
+ error: this.classifyError(mcpError, rawResult, timedOut),
229
+ };
230
+ }
231
+ // Extract text content
232
+ const textContent = content
233
+ .filter(item => item.type === 'text' && item.text)
234
+ .map(item => item.text)
235
+ .join('\n');
236
+ if (textContent) {
237
+ // Check if this looks like an error message
238
+ if (this.isErrorText(textContent)) {
239
+ const errorMessage = new Error(textContent);
240
+ return {
241
+ output: undefined,
242
+ error: this.classifyError(errorMessage, rawResult, timedOut),
243
+ };
244
+ }
245
+ // Try to parse as JSON (for structured outputs like Pydantic models)
246
+ try {
247
+ const parsedOutput = JSON.parse(textContent);
248
+ // Check if parsed output contains error-like structure
249
+ if (parsedOutput && typeof parsedOutput === 'object') {
250
+ if ('error' in parsedOutput ||
251
+ 'exception' in parsedOutput ||
252
+ 'traceback' in parsedOutput) {
253
+ const errorMsg = parsedOutput.error ||
254
+ parsedOutput.exception ||
255
+ String(parsedOutput);
256
+ return {
257
+ output: undefined,
258
+ error: this.classifyError(new Error(errorMsg), rawResult, timedOut),
259
+ };
260
+ }
261
+ }
262
+ return { output: parsedOutput, error: undefined };
263
+ }
264
+ catch {
265
+ // If not JSON, use text as-is
266
+ return { output: textContent, error: undefined };
267
+ }
268
+ }
269
+ }
270
+ // Fallback: return raw result as output
271
+ return { output: rawResult, error: undefined };
272
+ }
273
+ /**
274
+ * Check if text content looks like an error message.
275
+ * This handles cases where MCP servers return errors as text instead of proper error responses.
276
+ */
277
+ isErrorText(text) {
278
+ // Check for validation error patterns (more specific and robust)
279
+ const validationPatterns = [
280
+ /validation\s+error/i,
281
+ /validationerror/i,
282
+ /input\s+should\s+be\s+a\s+valid/i,
283
+ /invalid\s+parameter/i,
284
+ /invalid\s+params/i,
285
+ /type.*mismatch/i,
286
+ /required\s+field/i,
287
+ ];
288
+ // Check for general error patterns
289
+ const errorPatterns = [
290
+ /^error:/i,
291
+ /^exception:/i,
292
+ /traceback/i,
293
+ /failed\s+to/i,
294
+ /cannot\s+.*because/i,
295
+ // FastMCP exception patterns - exceptions are logged but might appear in output
296
+ /^valueerror:/i,
297
+ /^runtimeerror:/i,
298
+ /^typeerror:/i,
299
+ /^keyerror:/i,
300
+ /^attributeerror:/i,
301
+ /execution\s+failed/i,
302
+ /error\s+calling\s+tool/i,
303
+ ];
304
+ // Must match at least one pattern and be reasonably short (error messages, not large outputs)
305
+ const isShortEnough = text.length < 2000; // Error messages are typically short
306
+ // Also check if text contains exception-like patterns (common in Python tracebacks)
307
+ const hasExceptionPattern = /^\s*\w+Error\s*:/i.test(text) ||
308
+ /^\s*Traceback\s+\(most\s+recent\s+call\s+last\)/i.test(text);
309
+ return (isShortEnough &&
310
+ (validationPatterns.some(pattern => pattern.test(text)) ||
311
+ errorPatterns.some(pattern => pattern.test(text)) ||
312
+ hasExceptionPattern));
313
+ }
314
+ /**
315
+ * Classify error type from error message and MCP protocol response.
316
+ */
317
+ classifyError(error, rawResult, timedOut = false) {
318
+ if (timedOut) {
319
+ return Object.assign(error, {
320
+ errorType: ToolExecutionErrorType.TIMEOUT,
321
+ name: 'ToolExecutionTimeout',
322
+ });
323
+ }
324
+ // Check MCP protocol error codes
325
+ if (rawResult && typeof rawResult === 'object') {
326
+ // MCP protocol uses error codes: -32700 to -32099
327
+ // -32602: Invalid params (input validation)
328
+ // -32603: Internal error (execution error)
329
+ if ('error' in rawResult && rawResult.error) {
330
+ const errorObj = rawResult.error;
331
+ const errorCode = errorObj.code;
332
+ if (errorCode === -32602) {
333
+ return Object.assign(new Error(errorObj.message || error.message), {
334
+ errorType: ToolExecutionErrorType.INPUT_VALIDATION,
335
+ errorCode,
336
+ name: 'MCPInvalidParams',
337
+ context: { mcpErrorCode: errorCode },
338
+ });
339
+ }
340
+ if (errorCode) {
341
+ return Object.assign(new Error(errorObj.message || error.message), {
342
+ errorType: ToolExecutionErrorType.EXECUTION_ERROR,
343
+ errorCode,
344
+ name: 'MCPExecutionError',
345
+ context: { mcpErrorCode: errorCode },
346
+ });
347
+ }
348
+ }
349
+ }
350
+ // Classify based on error message patterns (fallback, but more robust)
351
+ const message = error.message.toLowerCase();
352
+ // Input validation patterns (more specific)
353
+ if (message.includes('invalid params') ||
354
+ message.includes('invalid parameter') ||
355
+ message.includes('validation error') ||
356
+ (message.includes('input should be') && message.includes('type'))) {
357
+ return Object.assign(error, {
358
+ errorType: ToolExecutionErrorType.INPUT_VALIDATION,
359
+ name: 'InputValidationError',
360
+ });
361
+ }
362
+ // Connection errors (use specific patterns to avoid false positives)
363
+ if (message.includes('connection refused') ||
364
+ message.includes('connection reset') ||
365
+ message.includes('connect failed') ||
366
+ message.includes('unable to connect') ||
367
+ message.includes('econnrefused') ||
368
+ message.includes('network')) {
369
+ return Object.assign(error, {
370
+ errorType: ToolExecutionErrorType.CONNECTION_ERROR,
371
+ name: 'ConnectionError',
372
+ });
373
+ }
374
+ // Default to execution error
375
+ return Object.assign(error, {
376
+ errorType: ToolExecutionErrorType.EXECUTION_ERROR,
377
+ name: 'ToolExecutionError',
378
+ });
379
+ }
380
+ /**
381
+ * Execute a tool with the given inputs.
382
+ * @param toolName - Name of the tool to execute
383
+ * @param inputs - Array of input objects to test
384
+ * @param timeoutMs - Optional per-tool timeout in milliseconds (overrides default)
385
+ * @returns Array of execution results (one per input)
386
+ */
387
+ async executeTool(toolName, inputs, timeoutMs) {
388
+ if (!this.initialized || !this.client) {
389
+ throw new ConfigurationError('Sandbox not initialized. Call initialize() first.');
390
+ }
391
+ const results = [];
392
+ for (const input of inputs) {
393
+ const startTime = Date.now();
394
+ let timedOut = false;
395
+ let output;
396
+ let error;
397
+ let rawResult;
398
+ try {
399
+ // Use per-tool timeout if provided, otherwise use default
400
+ const effectiveTimeout = timeoutMs ?? this.options.timeout;
401
+ // Execute with timeout
402
+ const executionPromise = this.client.callTool({
403
+ name: toolName,
404
+ arguments: input,
405
+ });
406
+ let timeoutId;
407
+ const timeoutPromise = new Promise((_, reject) => {
408
+ timeoutId = setTimeout(() => {
409
+ timedOut = true;
410
+ reject(new Error(`Tool execution timeout after ${this.formatTimeout(effectiveTimeout)}`));
411
+ }, effectiveTimeout);
412
+ });
413
+ try {
414
+ rawResult = await Promise.race([executionPromise, timeoutPromise]);
415
+ }
416
+ finally {
417
+ // Clear the timeout timer if execution completed before timeout
418
+ if (timeoutId !== undefined) {
419
+ clearTimeout(timeoutId);
420
+ }
421
+ }
422
+ // Parse MCP response to extract output or error
423
+ const parsed = this.parseMcpResponse(rawResult, timedOut);
424
+ output = parsed.output;
425
+ error = parsed.error;
426
+ }
427
+ catch (err) {
428
+ const baseError = err instanceof Error ? err : new Error(String(err));
429
+ error = this.classifyError(baseError, rawResult, timedOut);
430
+ output = undefined;
431
+ }
432
+ const executionTime = Date.now() - startTime;
433
+ // Get memory usage if available (platform-specific)
434
+ const memoryUsed = this.getProcessMemoryUsage();
435
+ if (error) {
436
+ results.push({
437
+ success: false,
438
+ error,
439
+ executionTime,
440
+ memoryUsed,
441
+ timedOut: timedOut || undefined,
442
+ });
443
+ }
444
+ else {
445
+ results.push({
446
+ success: true,
447
+ output: output ?? null,
448
+ executionTime,
449
+ memoryUsed,
450
+ });
451
+ }
452
+ }
453
+ return results;
454
+ }
455
+ /**
456
+ * Format timeout in milliseconds to human-readable string.
457
+ */
458
+ formatTimeout(ms) {
459
+ return formatTimeString(ms);
460
+ }
461
+ /**
462
+ * Get the MCP client instance (for reuse by orchestrator).
463
+ * @returns The MCP client, or null if not initialized
464
+ */
465
+ getClient() {
466
+ return this.client;
467
+ }
468
+ /**
469
+ * Get current process memory usage (if available).
470
+ * @returns Memory usage in MB, or undefined if not available
471
+ */
472
+ getProcessMemoryUsage() {
473
+ // Memory usage tracking is platform-specific
474
+ // For now, we'll return undefined and can enhance later
475
+ // On Linux, we could read from /proc/{pid}/status
476
+ // On macOS, we could use ps command
477
+ // On Windows, we could use tasklist or WMI
478
+ // Note: The process is managed by StdioClientTransport internally
479
+ // We would need to access it from the transport to get the PID
480
+ return undefined;
481
+ }
482
+ /**
483
+ * Cleanup sandbox resources.
484
+ * Should be called after all tools are tested.
485
+ */
486
+ async cleanup() {
487
+ // Close MCP client (this will also close the transport and process)
488
+ if (this.client) {
489
+ try {
490
+ await this.client.close();
491
+ }
492
+ catch (_error) {
493
+ // Ignore cleanup errors
494
+ }
495
+ this.client = null;
496
+ }
497
+ // Close transport explicitly (StdioClientTransport manages the process internally)
498
+ if (this.transport) {
499
+ try {
500
+ // The transport's process is managed internally and will be closed
501
+ // when the client is closed, but we can close it explicitly if needed
502
+ if ('close' in this.transport &&
503
+ typeof this.transport.close === 'function') {
504
+ await this.transport.close();
505
+ }
506
+ }
507
+ catch (_error) {
508
+ // Ignore cleanup errors
509
+ }
510
+ this.transport = null;
511
+ }
512
+ // Clean up temp directory
513
+ if (this.tempDir) {
514
+ try {
515
+ await fs.promises.rm(this.tempDir, { recursive: true, force: true });
516
+ }
517
+ catch (_error) {
518
+ // Ignore cleanup errors
519
+ }
520
+ this.tempDir = null;
521
+ }
522
+ this.initialized = false;
523
+ }
524
+ /**
525
+ * Check if sandbox is initialized.
526
+ */
527
+ isInitialized() {
528
+ return this.initialized;
529
+ }
530
+ /**
531
+ * Get the temp directory path.
532
+ */
533
+ getTempDir() {
534
+ return this.tempDir;
535
+ }
536
+ }
537
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Sandbox module exports.
3
+ * Reusable sandbox functionality for isolated tool execution.
4
+ */
5
+ export * from './executor.js';
6
+ export * from './types.js';
7
+ export * from './io-monitor.js';
8
+ export * from './time-parser.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Sandbox module exports.
3
+ * Reusable sandbox functionality for isolated tool execution.
4
+ */
5
+ export * from './executor.js';
6
+ export * from './types.js';
7
+ export * from './io-monitor.js';
8
+ export * from './time-parser.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,78 @@
1
+ /**
2
+ * I/O monitor for sandboxed tool execution.
3
+ * Monitors filesystem and network operations (does not block).
4
+ */
5
+ /**
6
+ * Filesystem operation type.
7
+ */
8
+ export type FSOperation = 'read' | 'write' | 'delete' | 'mkdir' | 'rmdir';
9
+ /**
10
+ * Filesystem operation record.
11
+ */
12
+ export interface FSOperationRecord {
13
+ /** Operation type */
14
+ operation: FSOperation;
15
+ /** File or directory path */
16
+ path: string;
17
+ /** Timestamp */
18
+ timestamp: number;
19
+ }
20
+ /**
21
+ * Network operation record.
22
+ */
23
+ export interface NetworkOperationRecord {
24
+ /** Request URL or endpoint */
25
+ url: string;
26
+ /** HTTP method (if applicable) */
27
+ method?: string;
28
+ /** Timestamp */
29
+ timestamp: number;
30
+ }
31
+ /**
32
+ * I/O monitor for tracking operations during tool execution.
33
+ */
34
+ export declare class IOMonitor {
35
+ private fsOperations;
36
+ private networkOperations;
37
+ private readonly tempDir;
38
+ private readonly projectRoot;
39
+ constructor(tempDir: string, projectRoot: string);
40
+ /**
41
+ * Record a filesystem operation.
42
+ */
43
+ recordFSOperation(operation: FSOperation, filePath: string): void;
44
+ /**
45
+ * Record a network operation.
46
+ */
47
+ recordNetworkOperation(url: string, method?: string): void;
48
+ /**
49
+ * Get all filesystem operations.
50
+ */
51
+ getFSOperations(): readonly FSOperationRecord[];
52
+ /**
53
+ * Get all network operations.
54
+ */
55
+ getNetworkOperations(): readonly NetworkOperationRecord[];
56
+ /**
57
+ * Get filesystem operations that are side effects (writes to project files).
58
+ * Writes to temp directory are NOT considered side effects.
59
+ */
60
+ getSideEffects(): FSOperationRecord[];
61
+ /**
62
+ * Get filesystem operations filtered by operation type.
63
+ */
64
+ getFSOperationsByType(operation: FSOperation): readonly FSOperationRecord[];
65
+ /**
66
+ * Clear all recorded operations.
67
+ */
68
+ clear(): void;
69
+ /**
70
+ * Get summary of I/O operations.
71
+ */
72
+ getSummary(): {
73
+ totalFSOperations: number;
74
+ sideEffects: number;
75
+ networkOperations: number;
76
+ };
77
+ }
78
+ //# sourceMappingURL=io-monitor.d.ts.map