@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,714 @@
1
+ /**
2
+ * Chat UI for Dev Mode using Ink (React for terminal UIs).
3
+ * Provides a ChatGPT-like terminal interface with message history and input panel.
4
+ *
5
+ * Note: React and Ink are dynamically imported to avoid ESM/CommonJS issues.
6
+ * The component is created inline using React.createElement to avoid separate module imports.
7
+ *
8
+ * ESLint warnings for dynamic imports and React.createElement are disabled as they are
9
+ * necessary for this approach to work with ESM modules in a CommonJS context.
10
+ */
11
+ import * as fs from 'fs';
12
+ import * as path from 'path';
13
+ import { wrapText } from './text-wrapper.js';
14
+ import { createHeader, createWelcomeBanner, createInputPanel, createMessageComponent, createMessagesList, } from './components/index.js';
15
+ import { generateGoodbyeMessage } from './goodbye-messages.js';
16
+ export class ChatUI {
17
+ options;
18
+ instance = null;
19
+ addMessageRef;
20
+ updateLastAssistantMessageRef;
21
+ updateLastSystemMessageRef;
22
+ getMessagesRef;
23
+ clearMessagesRef;
24
+ getLastLargeDataMessageRef;
25
+ constructor(options) {
26
+ this.options = options;
27
+ // Initialize refs as mutable ref objects (will be populated when component mounts)
28
+ this.addMessageRef = { current: () => { } };
29
+ this.updateLastAssistantMessageRef = {
30
+ current: () => { },
31
+ };
32
+ this.updateLastSystemMessageRef = {
33
+ current: () => { },
34
+ };
35
+ this.getMessagesRef = {
36
+ current: () => [],
37
+ };
38
+ this.clearMessagesRef = {
39
+ current: () => { },
40
+ };
41
+ this.getLastLargeDataMessageRef = {
42
+ current: () => null,
43
+ };
44
+ }
45
+ async start() {
46
+ // Dynamically import React and Ink (ESM modules)
47
+ // Use Function constructor to preserve import() syntax and avoid TypeScript transpilation to require()
48
+ const importDynamic = new Function('specifier', 'return import(specifier)');
49
+ const [ReactModule, inkModule, textInputModule] = await Promise.all([
50
+ importDynamic('react'),
51
+ importDynamic('ink'),
52
+ importDynamic('ink-text-input'),
53
+ ]);
54
+ const React = ReactModule.default || ReactModule;
55
+ const { useState, useEffect, useCallback, useRef, memo } = React;
56
+ const { Box, Text, useApp, useInput, render } = inkModule;
57
+ const TextInput = textInputModule.default;
58
+ // Capture options and refs for use inside the component
59
+ const options = this.options;
60
+ const addMessageRef = this.addMessageRef;
61
+ const updateLastAssistantMessageRef = this.updateLastAssistantMessageRef;
62
+ const updateLastSystemMessageRef = this.updateLastSystemMessageRef;
63
+ const getMessagesRef = this.getMessagesRef;
64
+ const clearMessagesRef = this.clearMessagesRef;
65
+ const getLastLargeDataMessageRef = this.getLastLargeDataMessageRef;
66
+ // Create the component inline to avoid importing a separate module file
67
+ // This avoids top-level require() calls for ESM modules
68
+ const ChatUIComponent = () => {
69
+ const { exit } = useApp();
70
+ const [messages, setMessages] = useState([]);
71
+ const [input, setInput] = useState('');
72
+ const [isProcessing, setIsProcessing] = useState(false);
73
+ const maxHistorySize = options.maxHistorySize || 1000;
74
+ // Viewport limiting: only show last N messages for performance
75
+ const maxVisibleMessages = 50; // Show last 50 messages by default
76
+ const inputHistoryRef = useRef([]);
77
+ const historyIndexRef = useRef(-1);
78
+ const currentInputRef = useRef('');
79
+ // Cache for parsed markdown to avoid re-parsing on every render
80
+ const markdownCacheRef = useRef(new Map());
81
+ // Load history from file on mount
82
+ useEffect(() => {
83
+ if (options.historyFile) {
84
+ try {
85
+ if (fs.existsSync(options.historyFile)) {
86
+ const content = fs.readFileSync(options.historyFile, 'utf-8');
87
+ const loadedHistory = content
88
+ .split('\n')
89
+ .filter((line) => line.trim())
90
+ .slice(-maxHistorySize); // Only keep last N entries
91
+ inputHistoryRef.current = loadedHistory;
92
+ }
93
+ }
94
+ catch {
95
+ // Ignore errors loading history
96
+ }
97
+ }
98
+ }, []); // Only run on mount
99
+ // Save history to file helper
100
+ const saveHistoryToFile = useCallback(() => {
101
+ if (options.historyFile && inputHistoryRef.current.length > 0) {
102
+ try {
103
+ const dir = path.dirname(options.historyFile);
104
+ if (!fs.existsSync(dir)) {
105
+ fs.mkdirSync(dir, { recursive: true });
106
+ }
107
+ fs.writeFileSync(options.historyFile, inputHistoryRef.current.join('\n') + '\n', 'utf-8');
108
+ }
109
+ catch {
110
+ // Ignore errors saving history
111
+ }
112
+ }
113
+ }, [options.historyFile]); // Only depend on historyFile, not the ref
114
+ // Initialize messages
115
+ useEffect(() => {
116
+ if (options.initialMessages && options.initialMessages.length > 0) {
117
+ const initMsgs = options.initialMessages.map(msg => ({
118
+ ...msg,
119
+ timestamp: new Date(),
120
+ }));
121
+ setMessages(initMsgs);
122
+ }
123
+ }, []); // Only run on mount
124
+ // Expose methods via refs - use useCallback for stable references
125
+ const addMessage = useCallback((role, content, largeData) => {
126
+ setMessages((prev) => [
127
+ ...prev,
128
+ { role, content, timestamp: new Date(), largeData },
129
+ ]);
130
+ }, []);
131
+ const updateLastAssistantMessage = useCallback((content) => {
132
+ setMessages((prev) => {
133
+ const newMessages = [...prev];
134
+ const lastIndex = newMessages.length - 1;
135
+ if (lastIndex >= 0 &&
136
+ newMessages[lastIndex]?.role === 'assistant') {
137
+ newMessages[lastIndex] = {
138
+ ...newMessages[lastIndex],
139
+ content,
140
+ timestamp: newMessages[lastIndex]?.timestamp || new Date(),
141
+ };
142
+ }
143
+ else {
144
+ newMessages.push({
145
+ role: 'assistant',
146
+ content,
147
+ timestamp: new Date(),
148
+ });
149
+ }
150
+ return newMessages;
151
+ });
152
+ }, []);
153
+ const updateLastSystemMessage = useCallback((content) => {
154
+ setMessages((prev) => {
155
+ const newMessages = [...prev];
156
+ const lastIndex = newMessages.length - 1;
157
+ if (lastIndex >= 0 && newMessages[lastIndex]?.role === 'system') {
158
+ newMessages[lastIndex] = {
159
+ ...newMessages[lastIndex],
160
+ content,
161
+ timestamp: newMessages[lastIndex]?.timestamp || new Date(),
162
+ };
163
+ }
164
+ else {
165
+ newMessages.push({
166
+ role: 'system',
167
+ content,
168
+ timestamp: new Date(),
169
+ });
170
+ }
171
+ return newMessages;
172
+ });
173
+ }, []);
174
+ const getMessages = useCallback(() => {
175
+ return messages;
176
+ }, [messages]);
177
+ const getLastLargeDataMessage = useCallback(() => {
178
+ for (let i = messages.length - 1; i >= 0; i--) {
179
+ const msg = messages[i];
180
+ if (msg && msg.largeData) {
181
+ return msg;
182
+ }
183
+ }
184
+ return null;
185
+ }, [messages]);
186
+ const clearMessages = useCallback(() => {
187
+ setMessages([]);
188
+ }, []);
189
+ // Update refs only when callbacks change (which is stable due to useCallback)
190
+ useEffect(() => {
191
+ addMessageRef.current = addMessage;
192
+ updateLastAssistantMessageRef.current = updateLastAssistantMessage;
193
+ updateLastSystemMessageRef.current = updateLastSystemMessage;
194
+ getMessagesRef.current = getMessages;
195
+ clearMessagesRef.current = clearMessages;
196
+ getLastLargeDataMessageRef.current = getLastLargeDataMessage;
197
+ }, [
198
+ addMessage,
199
+ updateLastAssistantMessage,
200
+ updateLastSystemMessage,
201
+ getMessages,
202
+ clearMessages,
203
+ getLastLargeDataMessage,
204
+ ]);
205
+ // Helper to show goodbye message and exit
206
+ const showGoodbyeAndExit = useCallback(async () => {
207
+ try {
208
+ // Get session state if available
209
+ const sessionState = options.getSessionState?.();
210
+ if (sessionState) {
211
+ // Generate goodbye message
212
+ // Map toolCalls to match DevSessionState format
213
+ const fullSessionState = {
214
+ totalToolCalls: sessionState.totalToolCalls,
215
+ toolCalls: sessionState.toolCalls.map(tc => ({
216
+ id: '',
217
+ name: tc.name,
218
+ arguments: {},
219
+ timestamp: tc.timestamp,
220
+ })),
221
+ startTime: sessionState.startTime,
222
+ conversationHistory: [],
223
+ totalLLMCalls: 0,
224
+ };
225
+ const goodbyeMessage = await generateGoodbyeMessage(options.llmProvider || null, fullSessionState);
226
+ // Add goodbye message to chat
227
+ setMessages((prev) => [
228
+ ...prev,
229
+ {
230
+ role: 'assistant',
231
+ content: goodbyeMessage,
232
+ timestamp: new Date(),
233
+ },
234
+ ]);
235
+ // Wait a bit for message to be displayed
236
+ await new Promise(resolve => setTimeout(resolve, 500));
237
+ }
238
+ }
239
+ catch (error) {
240
+ // Ignore errors during goodbye message generation
241
+ console.error('Error generating goodbye message:', error);
242
+ }
243
+ try {
244
+ await options.onExit?.();
245
+ }
246
+ catch {
247
+ // Ignore errors during exit
248
+ }
249
+ exit();
250
+ }, [options, exit, setMessages]);
251
+ // Handle special commands
252
+ // Returns true if the command was handled, false if it should be passed to onMessage
253
+ const handleSpecialCommand = useCallback(async (command) => {
254
+ const parts = command.split(/\s+/);
255
+ const cmd = parts[0]?.toLowerCase();
256
+ switch (cmd) {
257
+ case '/exit':
258
+ case '/quit':
259
+ // Show goodbye and exit (user message already added by handleSubmit)
260
+ await showGoodbyeAndExit();
261
+ return true;
262
+ case '/clear':
263
+ setMessages([]);
264
+ return true;
265
+ case '/help':
266
+ setMessages((prev) => [
267
+ ...prev,
268
+ {
269
+ role: 'system',
270
+ content: 'Available commands:\n' +
271
+ ' /help - Show this help message\n' +
272
+ ' /clear - Clear the chat history\n' +
273
+ ' /tools - List available MCP tools\n' +
274
+ ' /history - Show command history\n' +
275
+ ' /save-json [tool-name-or-index] - Save tool result JSON to file\n' +
276
+ ' (no arg = last result, number = by index, name = by name)\n' +
277
+ ' /exit, /quit - Exit the chat',
278
+ timestamp: new Date(),
279
+ },
280
+ ]);
281
+ return true;
282
+ default:
283
+ // Not a UI-level special command, pass to onMessage callback
284
+ return false;
285
+ }
286
+ }, [options, showGoodbyeAndExit]);
287
+ // Handle input submission
288
+ const handleSubmit = useCallback((value) => {
289
+ void (async () => {
290
+ const trimmedValue = value.trim();
291
+ if (!trimmedValue)
292
+ return;
293
+ // Clear input immediately
294
+ setInput('');
295
+ // Save current input before checking for special commands
296
+ currentInputRef.current = '';
297
+ // Add user message to chat
298
+ setMessages((prev) => [
299
+ ...prev,
300
+ { role: 'user', content: trimmedValue, timestamp: new Date() },
301
+ ]);
302
+ // Save to history FIRST (before handling commands) - ensures all commands are saved
303
+ // Move existing prompt to recent position if duplicate (don't repeat)
304
+ if (trimmedValue) {
305
+ const history = inputHistoryRef.current;
306
+ // Remove duplicate if exists (this moves it to end)
307
+ const filtered = history.filter((h) => h !== trimmedValue);
308
+ // Add to end (most recent)
309
+ filtered.push(trimmedValue);
310
+ // Keep only last N entries
311
+ inputHistoryRef.current = filtered.slice(-maxHistorySize);
312
+ // Save to file
313
+ saveHistoryToFile();
314
+ }
315
+ // Reset history navigation
316
+ historyIndexRef.current = -1;
317
+ // Handle UI-level special commands (only if handled by UI)
318
+ if (trimmedValue.startsWith('/')) {
319
+ const wasHandled = await handleSpecialCommand(trimmedValue);
320
+ if (wasHandled) {
321
+ return; // Command was handled by UI, don't pass to onMessage
322
+ }
323
+ // Command was not handled by UI, continue to pass to onMessage callback
324
+ }
325
+ // Process the message
326
+ setIsProcessing(true);
327
+ try {
328
+ await options.onMessage?.(trimmedValue);
329
+ }
330
+ catch (error) {
331
+ setMessages((prev) => [
332
+ ...prev,
333
+ {
334
+ role: 'system',
335
+ content: `Error: ${error instanceof Error ? error.message : String(error)}`,
336
+ timestamp: new Date(),
337
+ },
338
+ ]);
339
+ }
340
+ finally {
341
+ setIsProcessing(false);
342
+ }
343
+ })();
344
+ }, [options, handleSpecialCommand, maxHistorySize, saveHistoryToFile]);
345
+ // Handle Ctrl+C (always active)
346
+ useInput((_char, key) => {
347
+ if ((key.ctrl && _char === 'c') || _char === '\x03' || key.escape) {
348
+ void (async () => {
349
+ // Add user message showing they pressed Ctrl+C
350
+ setMessages((prev) => [
351
+ ...prev,
352
+ { role: 'user', content: '/exit', timestamp: new Date() },
353
+ ]);
354
+ // Show goodbye and exit
355
+ await showGoodbyeAndExit();
356
+ })();
357
+ }
358
+ }, { isActive: true });
359
+ // Handle arrow keys for history navigation (only when not processing)
360
+ useInput((_char, key) => {
361
+ if (key.upArrow || key.downArrow) {
362
+ if (inputHistoryRef.current.length === 0 || isProcessing) {
363
+ return;
364
+ }
365
+ if (key.upArrow) {
366
+ // Save current input if we're starting navigation
367
+ if (historyIndexRef.current === -1) {
368
+ currentInputRef.current = input;
369
+ }
370
+ // Move up in history
371
+ historyIndexRef.current = Math.min(historyIndexRef.current + 1, inputHistoryRef.current.length - 1);
372
+ }
373
+ else {
374
+ // Move down in history
375
+ historyIndexRef.current = Math.max(historyIndexRef.current - 1, -1);
376
+ }
377
+ // Set input from history or restore current
378
+ if (historyIndexRef.current >= 0) {
379
+ const historyItem = inputHistoryRef.current[inputHistoryRef.current.length - 1 - historyIndexRef.current];
380
+ if (historyItem !== undefined) {
381
+ setInput(historyItem);
382
+ }
383
+ }
384
+ else {
385
+ setInput(currentInputRef.current);
386
+ }
387
+ }
388
+ }, { isActive: !isProcessing });
389
+ // Note: Ctrl+C is now handled in useInput hook above
390
+ // The useInput hook intercepts all input including Ctrl+C, so SIGINT won't fire
391
+ // We handle Ctrl+C directly in the useInput callback
392
+ // Parse inline markdown (bold, italic, code) - kept in main file due to React hooks
393
+ const parseInlineMarkdown = useCallback((text, baseKey, defaultColor) => {
394
+ const elements = [];
395
+ const parts = text.split(/(\*\*[^*]+\*\*|\*[^*]+\*|``[^`]+``|`[^`]+`)/g);
396
+ let keyIndex = 0;
397
+ for (const part of parts) {
398
+ if (!part)
399
+ continue;
400
+ // Bold **text**
401
+ if (part.startsWith('**') && part.endsWith('**')) {
402
+ const content = part.slice(2, -2);
403
+ elements.push(React.createElement(Text, {
404
+ key: baseKey * 100 + keyIndex++,
405
+ bold: true,
406
+ ...(defaultColor ? { color: defaultColor } : {}),
407
+ }, content));
408
+ }
409
+ // Italic *text*
410
+ else if (part.startsWith('*') &&
411
+ part.endsWith('*') &&
412
+ !part.startsWith('**')) {
413
+ const content = part.slice(1, -1);
414
+ elements.push(React.createElement(Text, {
415
+ key: baseKey * 100 + keyIndex++,
416
+ dimColor: true,
417
+ ...(defaultColor ? { color: defaultColor } : {}),
418
+ }, content));
419
+ }
420
+ // Command ``text`` (double backticks - styled differently)
421
+ else if (part.startsWith('``') && part.endsWith('``')) {
422
+ const content = part.slice(2, -2);
423
+ elements.push(React.createElement(Text, {
424
+ key: baseKey * 100 + keyIndex++,
425
+ color: 'green',
426
+ bold: true,
427
+ }, content));
428
+ }
429
+ // Code `text` (single backtick - tool names, etc.)
430
+ else if (part.startsWith('`') && part.endsWith('`')) {
431
+ const content = part.slice(1, -1);
432
+ elements.push(React.createElement(Text, {
433
+ key: baseKey * 100 + keyIndex++,
434
+ color: 'cyan',
435
+ }, content));
436
+ }
437
+ // Regular text
438
+ else {
439
+ elements.push(React.createElement(Text, {
440
+ key: baseKey * 100 + keyIndex++,
441
+ ...(defaultColor
442
+ ? {
443
+ color: defaultColor,
444
+ ...(defaultColor === 'yellow'
445
+ ? {}
446
+ : { dimColor: true }),
447
+ }
448
+ : {}),
449
+ }, part));
450
+ }
451
+ }
452
+ return elements;
453
+ }, []);
454
+ // Parse table markdown
455
+ const parseTable = useCallback((rows, baseKey, defaultColor) => {
456
+ if (rows.length === 0)
457
+ return null;
458
+ const parsedRows = rows
459
+ .map(row => {
460
+ const cells = row
461
+ .split('|')
462
+ .map(cell => cell.trim())
463
+ .filter(cell => cell.length > 0);
464
+ return cells;
465
+ })
466
+ .filter(row => row.length > 0);
467
+ if (parsedRows.length === 0)
468
+ return null;
469
+ const dataRows = parsedRows.filter((row, idx) => idx !== 1 || !row.every(cell => /^-+$/.test(cell)));
470
+ if (dataRows.length === 0)
471
+ return null;
472
+ const headerRow = dataRows[0] || [];
473
+ const bodyRows = dataRows.slice(1);
474
+ return React.createElement(Box, { key: baseKey, flexDirection: 'column', marginY: 1 }, React.createElement(Box, { key: 'header', flexDirection: 'row', marginBottom: 0.5 }, ...headerRow.map((cell, idx) => React.createElement(Box, {
475
+ key: idx,
476
+ paddingX: 1,
477
+ minWidth: Math.floor(80 / headerRow.length),
478
+ }, ...parseInlineMarkdown(cell, baseKey * 1000 + idx, defaultColor)))), React.createElement(Box, { key: 'separator', marginY: 0.5 }, React.createElement(Text, { dimColor: true }, '─'.repeat(60))), ...bodyRows.map((row, rowIdx) => React.createElement(Box, { key: rowIdx, flexDirection: 'row', marginBottom: 0.25 }, ...row.map((cell, cellIdx) => React.createElement(Box, {
479
+ key: cellIdx,
480
+ paddingX: 1,
481
+ minWidth: Math.floor(80 / headerRow.length),
482
+ }, ...parseInlineMarkdown(cell, baseKey * 10000 + rowIdx * 100 + cellIdx, defaultColor))))));
483
+ }, [parseInlineMarkdown]);
484
+ // Markdown parser for formatting assistant/system messages
485
+ const parseMarkdown = useCallback((text, defaultColor) => {
486
+ const cacheKey = `${text}-${defaultColor || ''}`;
487
+ const cached = markdownCacheRef.current.get(cacheKey);
488
+ if (cached) {
489
+ return cached;
490
+ }
491
+ const elements = [];
492
+ let elementKey = 0;
493
+ const lines = text.split('\n');
494
+ let i = 0;
495
+ while (i < lines.length) {
496
+ const line = lines[i] || '';
497
+ if (line.trim().startsWith('```')) {
498
+ const languageMatch = line.trim().match(/^```(\w+)?$/);
499
+ const language = languageMatch?.[1] || '';
500
+ const codeLines = [];
501
+ i++;
502
+ while (i < lines.length) {
503
+ const codeLine = lines[i] || '';
504
+ if (codeLine.trim() === '```') {
505
+ i++;
506
+ break;
507
+ }
508
+ codeLines.push(codeLine);
509
+ i++;
510
+ }
511
+ const codeColor = language === 'json' ? 'green' : 'white';
512
+ elements.push(React.createElement(Box, {
513
+ key: elementKey++,
514
+ flexDirection: 'column',
515
+ marginY: 0.5,
516
+ marginLeft: 2,
517
+ }, ...codeLines.map((codeLine, lineIdx) => React.createElement(Text, { key: lineIdx, color: codeColor }, codeLine))));
518
+ continue;
519
+ }
520
+ if (line.trim().startsWith('|') && line.includes('|')) {
521
+ const tableRows = [line];
522
+ i++;
523
+ while (i < lines.length) {
524
+ const nextLine = lines[i] || '';
525
+ if (nextLine.trim().startsWith('|') && nextLine.includes('|')) {
526
+ tableRows.push(nextLine);
527
+ i++;
528
+ }
529
+ else {
530
+ break;
531
+ }
532
+ }
533
+ const tableElement = parseTable(tableRows, elementKey++, defaultColor);
534
+ if (tableElement) {
535
+ elements.push(tableElement);
536
+ }
537
+ continue;
538
+ }
539
+ if (/^\s*\d+[.)]\s+/.test(line)) {
540
+ const listItems = [];
541
+ while (i < lines.length) {
542
+ const listLine = lines[i] || '';
543
+ if (/^\s*\d+[.)]\s+/.test(listLine)) {
544
+ listItems.push(listLine.replace(/^\s*\d+[.)]\s+/, ''));
545
+ i++;
546
+ }
547
+ else if (listLine.trim() === '') {
548
+ i++;
549
+ if (i < lines.length &&
550
+ /^\s*\d+[.)]\s+/.test(lines[i] || '')) {
551
+ continue;
552
+ }
553
+ break;
554
+ }
555
+ else {
556
+ break;
557
+ }
558
+ }
559
+ elements.push(React.createElement(Box, { key: elementKey++, flexDirection: 'column', marginY: 0.5 }, ...listItems.map((item, idx) => React.createElement(Box, { key: idx, marginLeft: 2, marginBottom: 0.25 }, React.createElement(Text, {
560
+ ...(defaultColor
561
+ ? {
562
+ color: defaultColor,
563
+ ...(defaultColor === 'yellow'
564
+ ? {}
565
+ : { dimColor: true }),
566
+ }
567
+ : {}),
568
+ }, `${idx + 1}. `), ...parseInlineMarkdown(item, elementKey * 1000 + idx, defaultColor)))));
569
+ continue;
570
+ }
571
+ if (/^\s*[-*]\s+/.test(line)) {
572
+ const listItems = [];
573
+ while (i < lines.length) {
574
+ const listLine = lines[i] || '';
575
+ if (/^\s*[-*]\s+/.test(listLine)) {
576
+ listItems.push(listLine.replace(/^\s*[-*]\s+/, ''));
577
+ i++;
578
+ }
579
+ else if (listLine.trim() === '') {
580
+ i++;
581
+ if (i < lines.length && /^\s*[-*]\s+/.test(lines[i] || '')) {
582
+ continue;
583
+ }
584
+ break;
585
+ }
586
+ else {
587
+ break;
588
+ }
589
+ }
590
+ elements.push(React.createElement(Box, { key: elementKey++, flexDirection: 'column', marginY: 0.5 }, ...listItems.map((item, idx) => React.createElement(Box, { key: idx, marginLeft: 2, marginBottom: 0.25 }, React.createElement(Text, {
591
+ ...(defaultColor
592
+ ? {
593
+ color: defaultColor,
594
+ ...(defaultColor === 'yellow'
595
+ ? {}
596
+ : { dimColor: true }),
597
+ }
598
+ : {}),
599
+ }, '• '), ...parseInlineMarkdown(item, elementKey * 1000 + idx, defaultColor)))));
600
+ continue;
601
+ }
602
+ if (line.trim()) {
603
+ const inlineElements = parseInlineMarkdown(line, elementKey++, defaultColor);
604
+ elements.push(React.createElement(Box, {
605
+ key: elementKey - 1,
606
+ flexDirection: 'row',
607
+ flexWrap: 'wrap',
608
+ }, ...inlineElements));
609
+ }
610
+ else {
611
+ elements.push(React.createElement(Box, {
612
+ key: elementKey++,
613
+ height: 1,
614
+ }));
615
+ }
616
+ i++;
617
+ }
618
+ markdownCacheRef.current.set(cacheKey, elements);
619
+ if (markdownCacheRef.current.size > 100) {
620
+ const firstKey = markdownCacheRef.current.keys().next().value;
621
+ if (firstKey) {
622
+ markdownCacheRef.current.delete(firstKey);
623
+ }
624
+ }
625
+ return elements;
626
+ }, [parseInlineMarkdown, parseTable]);
627
+ // Create message component using extracted factory
628
+ const createMessageComponentFn = createMessageComponent(React, Box, Text, memo);
629
+ const MessageComponent = createMessageComponentFn(parseMarkdown, wrapText);
630
+ // Render using React.createElement (can't use JSX here without importing React at top level)
631
+ return React.createElement(Box, {
632
+ flexDirection: 'column',
633
+ width: '100%',
634
+ height: '100%',
635
+ },
636
+ // Header - distinct style with blue background and border
637
+ createHeader(React, Box, Text),
638
+ // Welcome banner - persistent, not cleared by /clear
639
+ options.welcomeBanner
640
+ ? createWelcomeBanner(React, Box, Text, options.welcomeBanner)
641
+ : null,
642
+ // Messages area - scrollable, takes remaining space (allows terminal scrolling)
643
+ createMessagesList(React, Box, Text, messages, maxVisibleMessages, MessageComponent, options),
644
+ // Input area - fixed at bottom, modern minimal design with border and black background
645
+ // flexShrink: 0 ensures it never shrinks, keeping it always visible at bottom
646
+ createInputPanel(React, Box, Text, TextInput, options, input, isProcessing, setInput, handleSubmit));
647
+ };
648
+ // Render the component with full screen options
649
+ this.instance = render(React.createElement(ChatUIComponent), {
650
+ stdout: process.stdout,
651
+ stderr: process.stderr,
652
+ stdin: process.stdin,
653
+ exitOnCtrlC: false, // We handle this manually
654
+ });
655
+ }
656
+ /**
657
+ * Add a message to the chat.
658
+ */
659
+ addMessage(role, content) {
660
+ this.addMessageRef.current(role, content);
661
+ }
662
+ /**
663
+ * Add a message with large data reference.
664
+ */
665
+ addMessageWithData(role, content, largeData) {
666
+ this.addMessageRef.current(role, content, largeData);
667
+ }
668
+ /**
669
+ * Get the last message with large data.
670
+ */
671
+ getLastLargeDataMessage() {
672
+ return this.getLastLargeDataMessageRef.current();
673
+ }
674
+ /**
675
+ * Update the last assistant message (for streaming).
676
+ */
677
+ updateLastAssistantMessage(content) {
678
+ this.updateLastAssistantMessageRef.current(content);
679
+ }
680
+ /**
681
+ * Update the last system message (for live updates like waiting indicators).
682
+ */
683
+ updateLastSystemMessage(content) {
684
+ this.updateLastSystemMessageRef.current(content);
685
+ }
686
+ /**
687
+ * Get all messages.
688
+ */
689
+ getMessages() {
690
+ return this.getMessagesRef.current();
691
+ }
692
+ /**
693
+ * Clear all messages.
694
+ */
695
+ clearMessages() {
696
+ this.clearMessagesRef.current();
697
+ }
698
+ /**
699
+ * Stop the chat UI (same as exit).
700
+ */
701
+ stop() {
702
+ if (this.instance) {
703
+ this.instance.unmount();
704
+ this.instance = null;
705
+ }
706
+ }
707
+ /**
708
+ * Exit the chat UI.
709
+ */
710
+ exit() {
711
+ this.stop();
712
+ }
713
+ }
714
+ //# sourceMappingURL=chat-ui.js.map