@gguf/coder 0.2.9 → 0.3.1

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 (439) hide show
  1. package/.editorconfig +16 -0
  2. package/.env.example +63 -0
  3. package/.gitattributes +1 -0
  4. package/.semgrepignore +19 -0
  5. package/coder-dummy-file.ts +52 -0
  6. package/coder.config.example.json +59 -0
  7. package/coder.config.json +13 -0
  8. package/color_picker.html +36 -0
  9. package/dist/tools/execute-bash.js +3 -3
  10. package/dist/tools/execute-bash.js.map +1 -1
  11. package/dist/tools/fetch-url.js +3 -3
  12. package/dist/tools/fetch-url.js.map +1 -1
  13. package/dist/tools/find-files.d.ts.map +1 -1
  14. package/dist/tools/find-files.js +1 -1
  15. package/dist/tools/find-files.js.map +1 -1
  16. package/dist/tools/lsp-get-diagnostics.js +1 -1
  17. package/dist/tools/lsp-get-diagnostics.js.map +1 -1
  18. package/dist/tools/read-file.d.ts.map +1 -1
  19. package/dist/tools/read-file.js +6 -6
  20. package/dist/tools/read-file.js.map +1 -1
  21. package/dist/tools/search-file-contents.d.ts.map +1 -1
  22. package/dist/tools/search-file-contents.js +1 -1
  23. package/dist/tools/search-file-contents.js.map +1 -1
  24. package/dist/tools/string-replace.js +11 -11
  25. package/dist/tools/string-replace.js.map +1 -1
  26. package/dist/tools/web-search.d.ts.map +1 -1
  27. package/dist/tools/web-search.js +3 -3
  28. package/dist/tools/web-search.js.map +1 -1
  29. package/dist/tools/write-file.js +4 -4
  30. package/dist/tools/write-file.js.map +1 -1
  31. package/dist/utils/tool-result-display.d.ts.map +1 -1
  32. package/dist/utils/tool-result-display.js +3 -3
  33. package/dist/utils/tool-result-display.js.map +1 -1
  34. package/package.json +2 -14
  35. package/scripts/extract-changelog.js +73 -0
  36. package/scripts/fetch-models.js +143 -0
  37. package/scripts/test.sh +40 -0
  38. package/scripts/update-homebrew-formula.sh +125 -0
  39. package/scripts/update-nix-version.sh +157 -0
  40. package/source/ai-sdk-client/AISDKClient.spec.ts +117 -0
  41. package/source/ai-sdk-client/AISDKClient.ts +155 -0
  42. package/source/ai-sdk-client/chat/chat-handler.spec.ts +121 -0
  43. package/source/ai-sdk-client/chat/chat-handler.ts +276 -0
  44. package/source/ai-sdk-client/chat/streaming-handler.spec.ts +173 -0
  45. package/source/ai-sdk-client/chat/streaming-handler.ts +110 -0
  46. package/source/ai-sdk-client/chat/tool-processor.spec.ts +92 -0
  47. package/source/ai-sdk-client/chat/tool-processor.ts +70 -0
  48. package/source/ai-sdk-client/converters/message-converter.spec.ts +220 -0
  49. package/source/ai-sdk-client/converters/message-converter.ts +113 -0
  50. package/source/ai-sdk-client/converters/tool-converter.spec.ts +90 -0
  51. package/source/ai-sdk-client/converters/tool-converter.ts +46 -0
  52. package/source/ai-sdk-client/error-handling/error-extractor.spec.ts +55 -0
  53. package/source/ai-sdk-client/error-handling/error-extractor.ts +15 -0
  54. package/source/ai-sdk-client/error-handling/error-parser.spec.ts +169 -0
  55. package/source/ai-sdk-client/error-handling/error-parser.ts +161 -0
  56. package/source/ai-sdk-client/index.ts +7 -0
  57. package/source/ai-sdk-client/providers/provider-factory.spec.ts +71 -0
  58. package/source/ai-sdk-client/providers/provider-factory.ts +41 -0
  59. package/source/ai-sdk-client/types.ts +9 -0
  60. package/source/ai-sdk-client-empty-message.spec.ts +141 -0
  61. package/source/ai-sdk-client-error-handling.spec.ts +186 -0
  62. package/source/ai-sdk-client-maxretries.spec.ts +114 -0
  63. package/source/ai-sdk-client-preparestep.spec.ts +279 -0
  64. package/source/app/App.spec.tsx +32 -0
  65. package/source/app/App.tsx +480 -0
  66. package/source/app/components/AppContainer.spec.tsx +96 -0
  67. package/source/app/components/AppContainer.tsx +56 -0
  68. package/source/app/components/ChatInterface.spec.tsx +163 -0
  69. package/source/app/components/ChatInterface.tsx +144 -0
  70. package/source/app/components/ModalSelectors.spec.tsx +141 -0
  71. package/source/app/components/ModalSelectors.tsx +135 -0
  72. package/source/app/helpers.spec.ts +97 -0
  73. package/source/app/helpers.ts +63 -0
  74. package/source/app/index.ts +4 -0
  75. package/source/app/types.ts +39 -0
  76. package/source/app/utils/appUtils.ts +294 -0
  77. package/source/app/utils/conversationState.ts +310 -0
  78. package/source/app.spec.tsx +244 -0
  79. package/source/cli.spec.ts +73 -0
  80. package/source/cli.tsx +51 -0
  81. package/source/client-factory.spec.ts +48 -0
  82. package/source/client-factory.ts +178 -0
  83. package/source/command-parser.spec.ts +127 -0
  84. package/source/command-parser.ts +36 -0
  85. package/source/commands/checkpoint.spec.tsx +277 -0
  86. package/source/commands/checkpoint.tsx +366 -0
  87. package/source/commands/clear.tsx +22 -0
  88. package/source/commands/custom-commands.tsx +121 -0
  89. package/source/commands/exit.ts +21 -0
  90. package/source/commands/export.spec.tsx +131 -0
  91. package/source/commands/export.tsx +79 -0
  92. package/source/commands/help.tsx +120 -0
  93. package/source/commands/index.ts +17 -0
  94. package/source/commands/init.tsx +339 -0
  95. package/source/commands/lsp-command.spec.tsx +281 -0
  96. package/source/commands/lsp.tsx +120 -0
  97. package/source/commands/mcp-command.spec.tsx +313 -0
  98. package/source/commands/mcp.tsx +162 -0
  99. package/source/commands/model-database.spec.tsx +758 -0
  100. package/source/commands/model-database.tsx +418 -0
  101. package/source/commands/model.ts +12 -0
  102. package/source/commands/provider.ts +12 -0
  103. package/source/commands/setup-config.tsx +16 -0
  104. package/source/commands/simple-commands.spec.tsx +175 -0
  105. package/source/commands/status.ts +12 -0
  106. package/source/commands/theme.ts +12 -0
  107. package/source/commands/update.spec.tsx +261 -0
  108. package/source/commands/update.tsx +201 -0
  109. package/source/commands/usage.spec.tsx +495 -0
  110. package/source/commands/usage.tsx +100 -0
  111. package/source/commands.spec.ts +436 -0
  112. package/source/commands.ts +83 -0
  113. package/source/components/assistant-message.spec.tsx +796 -0
  114. package/source/components/assistant-message.tsx +34 -0
  115. package/source/components/bash-execution-indicator.tsx +21 -0
  116. package/source/components/cancelling-indicator.tsx +16 -0
  117. package/source/components/chat-queue.spec.tsx +83 -0
  118. package/source/components/chat-queue.tsx +36 -0
  119. package/source/components/checkpoint-display.spec.tsx +219 -0
  120. package/source/components/checkpoint-display.tsx +126 -0
  121. package/source/components/checkpoint-selector.spec.tsx +173 -0
  122. package/source/components/checkpoint-selector.tsx +173 -0
  123. package/source/components/development-mode-indicator.spec.tsx +268 -0
  124. package/source/components/development-mode-indicator.tsx +38 -0
  125. package/source/components/message-box.spec.tsx +427 -0
  126. package/source/components/message-box.tsx +87 -0
  127. package/source/components/model-selector.tsx +132 -0
  128. package/source/components/provider-selector.tsx +75 -0
  129. package/source/components/random-spinner.tsx +19 -0
  130. package/source/components/security-disclaimer.tsx +73 -0
  131. package/source/components/status-connection-display.spec.tsx +133 -0
  132. package/source/components/status.tsx +267 -0
  133. package/source/components/theme-selector.tsx +126 -0
  134. package/source/components/tool-confirmation.tsx +190 -0
  135. package/source/components/tool-execution-indicator.tsx +33 -0
  136. package/source/components/tool-message.tsx +85 -0
  137. package/source/components/ui/titled-box.spec.tsx +207 -0
  138. package/source/components/ui/titled-box.tsx +57 -0
  139. package/source/components/usage/progress-bar.spec.tsx +398 -0
  140. package/source/components/usage/progress-bar.tsx +30 -0
  141. package/source/components/usage/usage-display.spec.tsx +780 -0
  142. package/source/components/usage/usage-display.tsx +291 -0
  143. package/source/components/user-input.spec.tsx +327 -0
  144. package/source/components/user-input.tsx +533 -0
  145. package/source/components/user-message.spec.tsx +230 -0
  146. package/source/components/user-message.tsx +84 -0
  147. package/source/components/welcome-message.tsx +76 -0
  148. package/source/config/env-substitution.ts +65 -0
  149. package/source/config/index.spec.ts +171 -0
  150. package/source/config/index.ts +154 -0
  151. package/source/config/paths.spec.ts +241 -0
  152. package/source/config/paths.ts +55 -0
  153. package/source/config/preferences.ts +51 -0
  154. package/source/config/themes.ts +315 -0
  155. package/source/constants.ts +130 -0
  156. package/source/context/mode-context.spec.ts +79 -0
  157. package/source/context/mode-context.ts +24 -0
  158. package/source/custom-commands/executor.spec.ts +142 -0
  159. package/source/custom-commands/executor.ts +64 -0
  160. package/source/custom-commands/loader.spec.ts +314 -0
  161. package/source/custom-commands/loader.ts +153 -0
  162. package/source/custom-commands/parser.ts +196 -0
  163. package/source/hooks/chat-handler/conversation/conversation-loop.spec.ts +39 -0
  164. package/source/hooks/chat-handler/conversation/conversation-loop.tsx +511 -0
  165. package/source/hooks/chat-handler/conversation/tool-executor.spec.ts +50 -0
  166. package/source/hooks/chat-handler/conversation/tool-executor.tsx +109 -0
  167. package/source/hooks/chat-handler/index.ts +12 -0
  168. package/source/hooks/chat-handler/state/streaming-state.spec.ts +26 -0
  169. package/source/hooks/chat-handler/state/streaming-state.ts +19 -0
  170. package/source/hooks/chat-handler/types.ts +38 -0
  171. package/source/hooks/chat-handler/useChatHandler.spec.tsx +321 -0
  172. package/source/hooks/chat-handler/useChatHandler.tsx +194 -0
  173. package/source/hooks/chat-handler/utils/context-checker.spec.ts +60 -0
  174. package/source/hooks/chat-handler/utils/context-checker.tsx +73 -0
  175. package/source/hooks/chat-handler/utils/message-helpers.spec.ts +42 -0
  176. package/source/hooks/chat-handler/utils/message-helpers.tsx +36 -0
  177. package/source/hooks/chat-handler/utils/tool-filters.spec.ts +109 -0
  178. package/source/hooks/chat-handler/utils/tool-filters.ts +64 -0
  179. package/source/hooks/useAppHandlers.tsx +291 -0
  180. package/source/hooks/useAppInitialization.tsx +422 -0
  181. package/source/hooks/useAppState.tsx +311 -0
  182. package/source/hooks/useDirectoryTrust.tsx +98 -0
  183. package/source/hooks/useInputState.ts +414 -0
  184. package/source/hooks/useModeHandlers.tsx +302 -0
  185. package/source/hooks/useNonInteractiveMode.ts +140 -0
  186. package/source/hooks/useTerminalWidth.tsx +81 -0
  187. package/source/hooks/useTheme.ts +18 -0
  188. package/source/hooks/useToolHandler.tsx +349 -0
  189. package/source/hooks/useUIState.ts +61 -0
  190. package/source/init/agents-template-generator.ts +421 -0
  191. package/source/init/existing-rules-extractor.ts +319 -0
  192. package/source/init/file-scanner.spec.ts +227 -0
  193. package/source/init/file-scanner.ts +238 -0
  194. package/source/init/framework-detector.ts +382 -0
  195. package/source/init/language-detector.ts +269 -0
  196. package/source/init/project-analyzer.spec.ts +231 -0
  197. package/source/init/project-analyzer.ts +458 -0
  198. package/source/lsp/index.ts +31 -0
  199. package/source/lsp/lsp-client.spec.ts +508 -0
  200. package/source/lsp/lsp-client.ts +487 -0
  201. package/source/lsp/lsp-manager.spec.ts +477 -0
  202. package/source/lsp/lsp-manager.ts +419 -0
  203. package/source/lsp/protocol.spec.ts +502 -0
  204. package/source/lsp/protocol.ts +360 -0
  205. package/source/lsp/server-discovery.spec.ts +654 -0
  206. package/source/lsp/server-discovery.ts +515 -0
  207. package/source/markdown-parser/html-entities.spec.ts +88 -0
  208. package/source/markdown-parser/html-entities.ts +45 -0
  209. package/source/markdown-parser/index.spec.ts +281 -0
  210. package/source/markdown-parser/index.ts +126 -0
  211. package/source/markdown-parser/table-parser.spec.ts +133 -0
  212. package/source/markdown-parser/table-parser.ts +114 -0
  213. package/source/markdown-parser/utils.spec.ts +70 -0
  214. package/source/markdown-parser/utils.ts +13 -0
  215. package/source/mcp/mcp-client.spec.ts +81 -0
  216. package/source/mcp/mcp-client.ts +625 -0
  217. package/source/mcp/transport-factory.spec.ts +406 -0
  218. package/source/mcp/transport-factory.ts +312 -0
  219. package/source/message-handler.ts +67 -0
  220. package/source/model-database/database-engine.spec.ts +494 -0
  221. package/source/model-database/database-engine.ts +50 -0
  222. package/source/model-database/model-database.spec.ts +363 -0
  223. package/source/model-database/model-database.ts +91 -0
  224. package/source/model-database/model-engine.spec.ts +447 -0
  225. package/source/model-database/model-engine.ts +65 -0
  226. package/source/model-database/model-fetcher.spec.ts +583 -0
  227. package/source/model-database/model-fetcher.ts +330 -0
  228. package/source/models/index.ts +1 -0
  229. package/source/models/models-cache.spec.ts +214 -0
  230. package/source/models/models-cache.ts +78 -0
  231. package/source/models/models-dev-client.spec.ts +379 -0
  232. package/source/models/models-dev-client.ts +329 -0
  233. package/source/models/models-types.ts +68 -0
  234. package/source/prompt-history.ts +155 -0
  235. package/source/security/command-injection.spec.ts +240 -0
  236. package/source/services/checkpoint-manager.spec.ts +523 -0
  237. package/source/services/checkpoint-manager.ts +466 -0
  238. package/source/services/file-snapshot.spec.ts +569 -0
  239. package/source/services/file-snapshot.ts +220 -0
  240. package/source/test-utils/render-with-theme.tsx +48 -0
  241. package/source/tokenization/index.ts +1 -0
  242. package/source/tokenization/tokenizer-factory.spec.ts +170 -0
  243. package/source/tokenization/tokenizer-factory.ts +125 -0
  244. package/source/tokenization/tokenizers/anthropic-tokenizer.spec.ts +200 -0
  245. package/source/tokenization/tokenizers/anthropic-tokenizer.ts +43 -0
  246. package/source/tokenization/tokenizers/fallback-tokenizer.spec.ts +236 -0
  247. package/source/tokenization/tokenizers/fallback-tokenizer.ts +26 -0
  248. package/source/tokenization/tokenizers/llama-tokenizer.spec.ts +224 -0
  249. package/source/tokenization/tokenizers/llama-tokenizer.ts +41 -0
  250. package/source/tokenization/tokenizers/openai-tokenizer.spec.ts +184 -0
  251. package/source/tokenization/tokenizers/openai-tokenizer.ts +57 -0
  252. package/source/tool-calling/index.ts +5 -0
  253. package/source/tool-calling/json-parser.spec.ts +639 -0
  254. package/source/tool-calling/json-parser.ts +247 -0
  255. package/source/tool-calling/tool-parser.spec.ts +395 -0
  256. package/source/tool-calling/tool-parser.ts +120 -0
  257. package/source/tool-calling/xml-parser.spec.ts +662 -0
  258. package/source/tool-calling/xml-parser.ts +289 -0
  259. package/source/tools/execute-bash.spec.tsx +353 -0
  260. package/source/tools/execute-bash.tsx +219 -0
  261. package/source/tools/execute-function.spec.ts +130 -0
  262. package/source/tools/fetch-url.spec.tsx +342 -0
  263. package/source/tools/fetch-url.tsx +172 -0
  264. package/source/tools/find-files.spec.tsx +924 -0
  265. package/source/tools/find-files.tsx +293 -0
  266. package/source/tools/index.ts +102 -0
  267. package/source/tools/lsp-get-diagnostics.tsx +192 -0
  268. package/source/tools/needs-approval.spec.ts +282 -0
  269. package/source/tools/read-file.spec.tsx +801 -0
  270. package/source/tools/read-file.tsx +387 -0
  271. package/source/tools/search-file-contents.spec.tsx +1273 -0
  272. package/source/tools/search-file-contents.tsx +293 -0
  273. package/source/tools/string-replace.spec.tsx +730 -0
  274. package/source/tools/string-replace.tsx +548 -0
  275. package/source/tools/tool-manager.ts +210 -0
  276. package/source/tools/tool-registry.spec.ts +415 -0
  277. package/source/tools/tool-registry.ts +228 -0
  278. package/source/tools/web-search.tsx +223 -0
  279. package/source/tools/write-file.spec.tsx +559 -0
  280. package/source/tools/write-file.tsx +228 -0
  281. package/source/types/app.ts +37 -0
  282. package/source/types/checkpoint.ts +48 -0
  283. package/source/types/commands.ts +46 -0
  284. package/source/types/components.ts +27 -0
  285. package/source/types/config.ts +103 -0
  286. package/source/types/core-connection-status.spec.ts +67 -0
  287. package/source/types/core.ts +181 -0
  288. package/source/types/hooks.ts +50 -0
  289. package/source/types/index.ts +12 -0
  290. package/source/types/markdown-parser.ts +11 -0
  291. package/source/types/mcp.ts +52 -0
  292. package/source/types/system.ts +16 -0
  293. package/source/types/tokenization.ts +41 -0
  294. package/source/types/ui.ts +40 -0
  295. package/source/types/usage.ts +58 -0
  296. package/source/types/utils.ts +16 -0
  297. package/source/usage/calculator.spec.ts +385 -0
  298. package/source/usage/calculator.ts +104 -0
  299. package/source/usage/storage.spec.ts +703 -0
  300. package/source/usage/storage.ts +238 -0
  301. package/source/usage/tracker.spec.ts +456 -0
  302. package/source/usage/tracker.ts +102 -0
  303. package/source/utils/atomic-deletion.spec.ts +194 -0
  304. package/source/utils/atomic-deletion.ts +127 -0
  305. package/source/utils/bounded-map.spec.ts +300 -0
  306. package/source/utils/bounded-map.ts +193 -0
  307. package/source/utils/checkpoint-utils.spec.ts +222 -0
  308. package/source/utils/checkpoint-utils.ts +92 -0
  309. package/source/utils/error-formatter.spec.ts +169 -0
  310. package/source/utils/error-formatter.ts +194 -0
  311. package/source/utils/file-autocomplete.spec.ts +173 -0
  312. package/source/utils/file-autocomplete.ts +196 -0
  313. package/source/utils/file-cache.spec.ts +309 -0
  314. package/source/utils/file-cache.ts +195 -0
  315. package/source/utils/file-content-loader.spec.ts +180 -0
  316. package/source/utils/file-content-loader.ts +179 -0
  317. package/source/utils/file-mention-handler.spec.ts +261 -0
  318. package/source/utils/file-mention-handler.ts +84 -0
  319. package/source/utils/file-mention-parser.spec.ts +182 -0
  320. package/source/utils/file-mention-parser.ts +170 -0
  321. package/source/utils/fuzzy-matching.spec.ts +149 -0
  322. package/source/utils/fuzzy-matching.ts +146 -0
  323. package/source/utils/indentation-normalizer.spec.ts +216 -0
  324. package/source/utils/indentation-normalizer.ts +76 -0
  325. package/source/utils/installation-detector.spec.ts +178 -0
  326. package/source/utils/installation-detector.ts +153 -0
  327. package/source/utils/logging/config.spec.ts +311 -0
  328. package/source/utils/logging/config.ts +210 -0
  329. package/source/utils/logging/console-facade.spec.ts +184 -0
  330. package/source/utils/logging/console-facade.ts +384 -0
  331. package/source/utils/logging/correlation.spec.ts +679 -0
  332. package/source/utils/logging/correlation.ts +474 -0
  333. package/source/utils/logging/formatters.spec.ts +464 -0
  334. package/source/utils/logging/formatters.ts +207 -0
  335. package/source/utils/logging/health-monitor/alerts/alert-manager.spec.ts +93 -0
  336. package/source/utils/logging/health-monitor/alerts/alert-manager.ts +79 -0
  337. package/source/utils/logging/health-monitor/checks/configuration-check.spec.ts +56 -0
  338. package/source/utils/logging/health-monitor/checks/configuration-check.ts +43 -0
  339. package/source/utils/logging/health-monitor/checks/logging-check.spec.ts +56 -0
  340. package/source/utils/logging/health-monitor/checks/logging-check.ts +58 -0
  341. package/source/utils/logging/health-monitor/checks/memory-check.spec.ts +100 -0
  342. package/source/utils/logging/health-monitor/checks/memory-check.ts +78 -0
  343. package/source/utils/logging/health-monitor/checks/performance-check.spec.ts +56 -0
  344. package/source/utils/logging/health-monitor/checks/performance-check.ts +56 -0
  345. package/source/utils/logging/health-monitor/checks/request-check.spec.ts +56 -0
  346. package/source/utils/logging/health-monitor/checks/request-check.ts +76 -0
  347. package/source/utils/logging/health-monitor/core/health-check-runner.spec.ts +70 -0
  348. package/source/utils/logging/health-monitor/core/health-check-runner.ts +138 -0
  349. package/source/utils/logging/health-monitor/core/health-monitor.spec.ts +58 -0
  350. package/source/utils/logging/health-monitor/core/health-monitor.ts +344 -0
  351. package/source/utils/logging/health-monitor/core/scoring.spec.ts +65 -0
  352. package/source/utils/logging/health-monitor/core/scoring.ts +91 -0
  353. package/source/utils/logging/health-monitor/index.ts +15 -0
  354. package/source/utils/logging/health-monitor/instances.ts +48 -0
  355. package/source/utils/logging/health-monitor/middleware/http-middleware.spec.ts +141 -0
  356. package/source/utils/logging/health-monitor/middleware/http-middleware.ts +75 -0
  357. package/source/utils/logging/health-monitor/types.ts +126 -0
  358. package/source/utils/logging/index.spec.ts +284 -0
  359. package/source/utils/logging/index.ts +236 -0
  360. package/source/utils/logging/integration.spec.ts +441 -0
  361. package/source/utils/logging/log-method-factory.spec.ts +573 -0
  362. package/source/utils/logging/log-method-factory.ts +233 -0
  363. package/source/utils/logging/log-query/aggregation/aggregator.spec.ts +277 -0
  364. package/source/utils/logging/log-query/aggregation/aggregator.ts +159 -0
  365. package/source/utils/logging/log-query/aggregation/facet-generator.spec.ts +159 -0
  366. package/source/utils/logging/log-query/aggregation/facet-generator.ts +47 -0
  367. package/source/utils/logging/log-query/index.ts +23 -0
  368. package/source/utils/logging/log-query/query/filter-predicates.spec.ts +247 -0
  369. package/source/utils/logging/log-query/query/filter-predicates.ts +154 -0
  370. package/source/utils/logging/log-query/query/query-builder.spec.ts +182 -0
  371. package/source/utils/logging/log-query/query/query-builder.ts +151 -0
  372. package/source/utils/logging/log-query/query/query-engine.spec.ts +214 -0
  373. package/source/utils/logging/log-query/query/query-engine.ts +45 -0
  374. package/source/utils/logging/log-query/storage/circular-buffer.spec.ts +143 -0
  375. package/source/utils/logging/log-query/storage/circular-buffer.ts +75 -0
  376. package/source/utils/logging/log-query/storage/index-manager.spec.ts +150 -0
  377. package/source/utils/logging/log-query/storage/index-manager.ts +71 -0
  378. package/source/utils/logging/log-query/storage/log-storage.spec.ts +257 -0
  379. package/source/utils/logging/log-query/storage/log-storage.ts +80 -0
  380. package/source/utils/logging/log-query/types.ts +163 -0
  381. package/source/utils/logging/log-query/utils/helpers.spec.ts +263 -0
  382. package/source/utils/logging/log-query/utils/helpers.ts +72 -0
  383. package/source/utils/logging/log-query/utils/sorting.spec.ts +182 -0
  384. package/source/utils/logging/log-query/utils/sorting.ts +61 -0
  385. package/source/utils/logging/logger-provider.spec.ts +262 -0
  386. package/source/utils/logging/logger-provider.ts +362 -0
  387. package/source/utils/logging/performance.spec.ts +209 -0
  388. package/source/utils/logging/performance.ts +757 -0
  389. package/source/utils/logging/pino-logger.spec.ts +425 -0
  390. package/source/utils/logging/pino-logger.ts +514 -0
  391. package/source/utils/logging/redaction.spec.ts +490 -0
  392. package/source/utils/logging/redaction.ts +267 -0
  393. package/source/utils/logging/request-tracker.spec.ts +1198 -0
  394. package/source/utils/logging/request-tracker.ts +803 -0
  395. package/source/utils/logging/transports.spec.ts +505 -0
  396. package/source/utils/logging/transports.ts +305 -0
  397. package/source/utils/logging/types.ts +216 -0
  398. package/source/utils/message-builder.spec.ts +179 -0
  399. package/source/utils/message-builder.ts +101 -0
  400. package/source/utils/message-queue.tsx +486 -0
  401. package/source/utils/paste-detection.spec.ts +69 -0
  402. package/source/utils/paste-detection.ts +124 -0
  403. package/source/utils/paste-roundtrip.spec.ts +442 -0
  404. package/source/utils/paste-utils.spec.ts +128 -0
  405. package/source/utils/paste-utils.ts +52 -0
  406. package/source/utils/programming-language-helper.spec.ts +74 -0
  407. package/source/utils/programming-language-helper.ts +32 -0
  408. package/source/utils/prompt-assembly.spec.ts +221 -0
  409. package/source/utils/prompt-processor.ts +173 -0
  410. package/source/utils/tool-args-parser.spec.ts +136 -0
  411. package/source/utils/tool-args-parser.ts +54 -0
  412. package/source/utils/tool-cancellation.spec.ts +230 -0
  413. package/source/utils/tool-cancellation.ts +28 -0
  414. package/source/utils/tool-result-display.spec.tsx +469 -0
  415. package/source/utils/tool-result-display.tsx +90 -0
  416. package/source/utils/update-checker.spec.ts +383 -0
  417. package/source/utils/update-checker.ts +183 -0
  418. package/source/wizard/config-wizard.spec.tsx +103 -0
  419. package/source/wizard/config-wizard.tsx +382 -0
  420. package/source/wizard/steps/location-step.spec.tsx +186 -0
  421. package/source/wizard/steps/location-step.tsx +147 -0
  422. package/source/wizard/steps/mcp-step.spec.tsx +607 -0
  423. package/source/wizard/steps/mcp-step.tsx +632 -0
  424. package/source/wizard/steps/provider-step.spec.tsx +342 -0
  425. package/source/wizard/steps/provider-step.tsx +957 -0
  426. package/source/wizard/steps/summary-step.spec.tsx +749 -0
  427. package/source/wizard/steps/summary-step.tsx +228 -0
  428. package/source/wizard/templates/mcp-templates.spec.ts +613 -0
  429. package/source/wizard/templates/mcp-templates.ts +570 -0
  430. package/source/wizard/templates/provider-templates.spec.ts +152 -0
  431. package/source/wizard/templates/provider-templates.ts +485 -0
  432. package/source/wizard/utils/fetch-cloud-models.spec.ts +428 -0
  433. package/source/wizard/utils/fetch-cloud-models.ts +223 -0
  434. package/source/wizard/utils/fetch-local-models.spec.ts +297 -0
  435. package/source/wizard/utils/fetch-local-models.ts +192 -0
  436. package/source/wizard/validation-array.spec.ts +264 -0
  437. package/source/wizard/validation.spec.ts +373 -0
  438. package/source/wizard/validation.ts +232 -0
  439. package/source/app/prompts/main-prompt.md +0 -122
@@ -0,0 +1,632 @@
1
+ import {colors} from '@/config/index';
2
+ import {useResponsiveTerminal} from '@/hooks/useTerminalWidth';
3
+ import {Box, Text, useInput} from 'ink';
4
+ import SelectInput from 'ink-select-input';
5
+ import {Tab, Tabs} from 'ink-tab';
6
+ import TextInput from 'ink-text-input';
7
+ import {useEffect, useState} from 'react';
8
+ import {
9
+ MCP_TEMPLATES,
10
+ type McpServerConfig,
11
+ type McpTemplate,
12
+ } from '../templates/mcp-templates';
13
+
14
+ interface McpStepProps {
15
+ onComplete: (mcpServers: Record<string, McpServerConfig>) => void;
16
+ onBack?: () => void;
17
+ existingServers?: Record<string, McpServerConfig>;
18
+ }
19
+
20
+ type Mode =
21
+ | 'initial-menu'
22
+ | 'tabs'
23
+ | 'edit-selection'
24
+ | 'edit-or-delete'
25
+ | 'field-input';
26
+
27
+ interface TemplateOption {
28
+ label: string;
29
+ value: string;
30
+ category?: string;
31
+ }
32
+
33
+ export function McpStep({
34
+ onComplete,
35
+ onBack,
36
+ existingServers = {},
37
+ }: McpStepProps) {
38
+ const {isNarrow} = useResponsiveTerminal();
39
+ const [servers, setServers] =
40
+ useState<Record<string, McpServerConfig>>(existingServers);
41
+
42
+ // Update servers when existingServers prop changes
43
+ useEffect(() => {
44
+ setServers(existingServers);
45
+ }, [existingServers]);
46
+
47
+ const [mode, setMode] = useState<Mode>('initial-menu');
48
+ const [selectedTemplate, setSelectedTemplate] = useState<McpTemplate | null>(
49
+ null,
50
+ );
51
+ const [currentFieldIndex, setCurrentFieldIndex] = useState(0);
52
+ const [fieldAnswers, setFieldAnswers] = useState<Record<string, string>>({});
53
+ const [currentValue, setCurrentValue] = useState('');
54
+ const [multilineBuffer, setMultilineBuffer] = useState('');
55
+ const [error, setError] = useState<string | null>(null);
56
+ const [inputKey, setInputKey] = useState(0);
57
+ const [editingServerName, setEditingServerName] = useState<string | null>(
58
+ null,
59
+ );
60
+ const [activeTab, setActiveTab] = useState<'local' | 'remote'>('local');
61
+
62
+ const serverCount = Object.keys(servers).length;
63
+
64
+ // Filter templates by category
65
+ const localTemplates = MCP_TEMPLATES.filter(
66
+ template => template.category === 'local',
67
+ );
68
+ const remoteTemplates = MCP_TEMPLATES.filter(
69
+ template => template.category === 'remote',
70
+ );
71
+
72
+ // Initial menu options
73
+ const initialOptions = [
74
+ {label: 'Add MCP servers', value: 'add'},
75
+ ...(serverCount > 0
76
+ ? [{label: 'Edit existing servers', value: 'edit'}]
77
+ : []),
78
+ {label: 'Skip MCP servers', value: 'skip'},
79
+ ];
80
+
81
+ // Create template options for current tab
82
+ const getTemplateOptions = (): TemplateOption[] => {
83
+ if (mode === 'tabs') {
84
+ const options: TemplateOption[] = [];
85
+ const templates =
86
+ activeTab === 'local' ? localTemplates : remoteTemplates;
87
+
88
+ // Add templates for current tab
89
+ templates.forEach(template => {
90
+ options.push({
91
+ label: isNarrow
92
+ ? `${template.name}`
93
+ : `${template.name} - ${template.description}`,
94
+ value: template.id,
95
+ category: activeTab,
96
+ });
97
+ });
98
+
99
+ // Add done option at the end
100
+ options.push({
101
+ label: 'Done adding MCP servers',
102
+ value: 'done',
103
+ });
104
+
105
+ return options;
106
+ }
107
+
108
+ return [];
109
+ };
110
+
111
+ const handleInitialSelect = (item: {value: string}) => {
112
+ if (item.value === 'add') {
113
+ setMode('tabs');
114
+ } else if (item.value === 'edit') {
115
+ setMode('edit-selection');
116
+ } else {
117
+ // Skip
118
+ onComplete(servers);
119
+ }
120
+ };
121
+
122
+ const handleTemplateSelect = (item: TemplateOption) => {
123
+ if (item.value === 'done') {
124
+ // Done adding servers
125
+ onComplete(servers);
126
+ return;
127
+ }
128
+
129
+ // Adding new server
130
+ const template = MCP_TEMPLATES.find(t => t.id === item.value);
131
+ if (template) {
132
+ // Check if template has no fields
133
+ if (template.fields.length === 0) {
134
+ // Automatically build config and add server when no fields are required
135
+ try {
136
+ const serverConfig = template.buildConfig({});
137
+ setServers({...servers, [serverConfig.name]: serverConfig});
138
+ // Stay in tabs mode to allow adding more servers
139
+ setMode('tabs');
140
+ } catch (err) {
141
+ setError(
142
+ err instanceof Error
143
+ ? err.message
144
+ : 'Failed to build configuration',
145
+ );
146
+ }
147
+ } else {
148
+ // Template has fields, proceed with normal flow
149
+ setEditingServerName(null); // Not editing
150
+ setSelectedTemplate(template);
151
+ setCurrentFieldIndex(0);
152
+ setFieldAnswers({});
153
+ setCurrentValue(template.fields[0]?.default || '');
154
+ setMultilineBuffer('');
155
+ setError(null);
156
+ setMode('field-input');
157
+ }
158
+ }
159
+ };
160
+
161
+ const handleEditSelect = (item: TemplateOption) => {
162
+ // Store the server name and show edit/delete options
163
+ if (item.value.startsWith('edit-')) {
164
+ const serverKey = item.value.replace('edit-', '');
165
+ setEditingServerName(serverKey);
166
+ setMode('edit-or-delete');
167
+ }
168
+ };
169
+
170
+ const handleEditOrDeleteChoice = (item: {value: string}) => {
171
+ if (item.value === 'delete' && editingServerName !== null) {
172
+ // Delete the server
173
+ const newServers = {...servers};
174
+ delete newServers[editingServerName];
175
+ setServers(newServers);
176
+ setEditingServerName(null);
177
+ // Go back to initial menu after deleting
178
+ setMode('initial-menu');
179
+ return;
180
+ }
181
+
182
+ if (item.value === 'edit' && editingServerName !== null) {
183
+ const server = servers[editingServerName];
184
+ if (server) {
185
+ // Find matching template by server name or use custom
186
+ const template =
187
+ MCP_TEMPLATES.find(t => t.id === server.name) ||
188
+ MCP_TEMPLATES.find(t => t.id === editingServerName) ||
189
+ MCP_TEMPLATES.find(t => t.id === 'custom');
190
+
191
+ if (template) {
192
+ setSelectedTemplate(template);
193
+ setCurrentFieldIndex(0);
194
+
195
+ // Pre-populate field answers from existing server
196
+ const answers: Record<string, string> = {};
197
+
198
+ // Map server properties to field names based on template fields
199
+ for (const field of template.fields) {
200
+ if (field.name === 'serverName' && server.name) {
201
+ answers.serverName = server.name;
202
+ } else if (field.name === 'url' && server.url) {
203
+ answers.url = server.url;
204
+ } else if (field.name === 'command' && server.command) {
205
+ answers.command = server.command;
206
+ } else if (field.name === 'allowedDirs' && server.args) {
207
+ // Special handling for filesystem server - extract allowed directories
208
+ const packageIndex = server.args.findIndex(arg =>
209
+ arg.includes('@modelcontextprotocol/server-filesystem'),
210
+ );
211
+ if (packageIndex !== -1) {
212
+ const dirs = server.args.slice(packageIndex + 1);
213
+ answers.allowedDirs = dirs.join(', ');
214
+ }
215
+ } else if (field.name === 'args' && server.args) {
216
+ answers.args = server.args.join(' ');
217
+ } else if (field.name === 'envVars' && server.env) {
218
+ answers.envVars = Object.entries(server.env)
219
+ .map(([key, value]) => `${key}=${value}`)
220
+ .join('\n');
221
+ } else if (field.name === 'apiKey' && server.env) {
222
+ // Try to find API key from env vars
223
+ const apiKeyEntry = Object.entries(server.env).find(
224
+ ([key]) => key.includes('API_KEY') || key.includes('TOKEN'),
225
+ );
226
+ if (apiKeyEntry) {
227
+ answers.apiKey = apiKeyEntry[1];
228
+ }
229
+ }
230
+ }
231
+
232
+ setFieldAnswers(answers);
233
+ setCurrentValue(
234
+ answers[template.fields[0]?.name] ||
235
+ template.fields[0]?.default ||
236
+ '',
237
+ );
238
+ setMultilineBuffer('');
239
+ setError(null);
240
+ setMode('field-input');
241
+ }
242
+ }
243
+ }
244
+ };
245
+
246
+ const handleFieldSubmit = () => {
247
+ if (!selectedTemplate) return;
248
+
249
+ const currentField = selectedTemplate.fields[currentFieldIndex];
250
+ if (!currentField) return;
251
+
252
+ // For multiline fields, handle differently
253
+ const isMultiline = currentField.name === 'envVars';
254
+ const finalValue = isMultiline ? multilineBuffer : currentValue.trim();
255
+
256
+ // Validate required fields
257
+ if (currentField.required && !finalValue) {
258
+ setError('This field is required');
259
+ return;
260
+ }
261
+
262
+ // Validate with custom validator
263
+ if (currentField.validator && finalValue) {
264
+ const validationError = currentField.validator(finalValue);
265
+ if (validationError) {
266
+ setError(validationError);
267
+ return;
268
+ }
269
+ }
270
+
271
+ // Save answer
272
+ const newAnswers = {
273
+ ...fieldAnswers,
274
+ [currentField.name]: finalValue,
275
+ };
276
+ setFieldAnswers(newAnswers);
277
+ setError(null);
278
+
279
+ // Move to next field or complete
280
+ if (currentFieldIndex < selectedTemplate.fields.length - 1) {
281
+ setCurrentFieldIndex(currentFieldIndex + 1);
282
+ const nextField = selectedTemplate.fields[currentFieldIndex + 1];
283
+ setCurrentValue(newAnswers[nextField?.name] || nextField?.default || '');
284
+ setMultilineBuffer('');
285
+ } else {
286
+ // Build config and add/update server
287
+ try {
288
+ const serverConfig = selectedTemplate.buildConfig(newAnswers);
289
+
290
+ if (editingServerName !== null) {
291
+ // Replace existing server (delete old, add new)
292
+ const newServers = {...servers};
293
+ delete newServers[editingServerName];
294
+ newServers[serverConfig.name] = serverConfig;
295
+ setServers(newServers);
296
+ } else {
297
+ // Add new server
298
+ setServers({...servers, [serverConfig.name]: serverConfig});
299
+ }
300
+
301
+ // Reset for next server
302
+ setSelectedTemplate(null);
303
+ setCurrentFieldIndex(0);
304
+ setFieldAnswers({});
305
+ setCurrentValue('');
306
+ setMultilineBuffer('');
307
+ setEditingServerName(null);
308
+ setMode('tabs');
309
+ } catch (err) {
310
+ setError(
311
+ err instanceof Error ? err.message : 'Failed to build configuration',
312
+ );
313
+ }
314
+ }
315
+ };
316
+
317
+ const editOptions: TemplateOption[] = [
318
+ ...Object.entries(servers).map(([key, server], index) => ({
319
+ label: `${index + 1}. ${server.name}`,
320
+ value: `edit-${key}`,
321
+ })),
322
+ ];
323
+
324
+ // Handle keyboard navigation
325
+ useInput((input, key) => {
326
+ // Handle Shift+Tab for going back (but not regular Tab, let Tabs component handle it)
327
+ if (key.shift && key.tab) {
328
+ if (mode === 'field-input') {
329
+ // In field input mode, check if we can go back to previous field
330
+ if (currentFieldIndex > 0) {
331
+ // Go back to previous field
332
+ setCurrentFieldIndex(currentFieldIndex - 1);
333
+ const prevField = selectedTemplate?.fields[currentFieldIndex - 1];
334
+ setCurrentValue(
335
+ fieldAnswers[prevField?.name || ''] || prevField?.default || '',
336
+ );
337
+ setMultilineBuffer('');
338
+ setInputKey(prev => prev + 1); // Force remount to reset cursor position
339
+ setError(null);
340
+ } else {
341
+ // At first field, go back based on context
342
+ if (editingServerName !== null) {
343
+ // Was editing, go back to edit-or-delete choice
344
+ setMode('edit-or-delete');
345
+ } else {
346
+ // Was adding, go back to tabs
347
+ setMode('tabs');
348
+ }
349
+ setSelectedTemplate(null);
350
+ setCurrentFieldIndex(0);
351
+ setFieldAnswers({});
352
+ setCurrentValue('');
353
+ setMultilineBuffer('');
354
+ setError(null);
355
+ }
356
+ } else if (mode === 'edit-or-delete') {
357
+ // In edit-or-delete, go back to edit selection
358
+ setEditingServerName(null);
359
+ setMode('edit-selection');
360
+ } else if (mode === 'edit-selection') {
361
+ // In edit selection, go back to initial menu
362
+ setMode('initial-menu');
363
+ } else if (mode === 'tabs') {
364
+ // At tabs screen, go back to initial menu
365
+ setMode('initial-menu');
366
+ } else if (mode === 'initial-menu' && onBack) {
367
+ // At initial menu, call parent's onBack
368
+ onBack();
369
+ }
370
+ return;
371
+ }
372
+
373
+ if (mode === 'field-input' && selectedTemplate) {
374
+ const currentField = selectedTemplate.fields[currentFieldIndex];
375
+ const isMultiline = currentField?.name === 'envVars';
376
+
377
+ if (isMultiline) {
378
+ // Handle multiline input
379
+ if (key.return) {
380
+ // Add newline to buffer
381
+ setMultilineBuffer(multilineBuffer + '\n');
382
+ } else if (key.escape) {
383
+ // Submit multiline input on Escape
384
+ handleFieldSubmit();
385
+ } else if (!key.ctrl && !key.meta && input) {
386
+ setMultilineBuffer(multilineBuffer + input);
387
+ }
388
+ } else {
389
+ if (key.return) {
390
+ handleFieldSubmit();
391
+ } else if (key.escape) {
392
+ // Go back to tabs or initial menu
393
+ if (editingServerName !== null) {
394
+ setMode('edit-or-delete');
395
+ } else {
396
+ setMode('tabs');
397
+ }
398
+ setSelectedTemplate(null);
399
+ setCurrentFieldIndex(0);
400
+ setFieldAnswers({});
401
+ setCurrentValue('');
402
+ setMultilineBuffer('');
403
+ setError(null);
404
+ }
405
+ }
406
+ }
407
+ });
408
+
409
+ if (mode === 'initial-menu') {
410
+ return (
411
+ <Box flexDirection="column">
412
+ <Box marginBottom={1}>
413
+ <Text bold color={colors.primary}>
414
+ Configure MCP Servers
415
+ </Text>
416
+ </Box>
417
+ {serverCount > 0 && (
418
+ <Box flexDirection="column" marginBottom={1}>
419
+ <Text color={colors.success}>
420
+ {serverCount} MCP server(s) configured:
421
+ </Text>
422
+ {Object.values(servers).map((server, index) => (
423
+ <Text key={index} color={colors.secondary}>
424
+ • {server.name} ({server.transport})
425
+ </Text>
426
+ ))}
427
+ </Box>
428
+ )}
429
+ <SelectInput
430
+ items={initialOptions}
431
+ onSelect={(item: {value: string}) => handleInitialSelect(item)}
432
+ />
433
+ </Box>
434
+ );
435
+ }
436
+
437
+ if (mode === 'tabs') {
438
+ const templateOptions = getTemplateOptions();
439
+
440
+ return (
441
+ <Box flexDirection="column">
442
+ <Box marginBottom={1}>
443
+ <Text bold color={colors.primary}>
444
+ Add MCP Servers:
445
+ </Text>
446
+ </Box>
447
+ {serverCount > 0 && (
448
+ <Box marginBottom={1}>
449
+ <Text color={colors.success}>
450
+ Added:{' '}
451
+ {Object.values(servers)
452
+ .map(s => s.name)
453
+ .join(', ')}
454
+ </Text>
455
+ </Box>
456
+ )}
457
+ <Tabs
458
+ onChange={name => setActiveTab(name as 'local' | 'remote')}
459
+ defaultValue={activeTab}
460
+ flexDirection="row"
461
+ colors={{
462
+ activeTab: {
463
+ color: colors.success,
464
+ },
465
+ }}
466
+ >
467
+ <Tab name="local">Local Servers (STDIO)</Tab>
468
+ <Tab name="remote">Remote Servers (HTTP/WebSocket)</Tab>
469
+ </Tabs>
470
+ <Box marginTop={1} marginBottom={1}>
471
+ <Text>
472
+ {activeTab === 'local'
473
+ ? 'Select a local MCP server to add:'
474
+ : 'Select a remote MCP server to add:'}
475
+ </Text>
476
+ </Box>
477
+ <SelectInput items={templateOptions} onSelect={handleTemplateSelect} />
478
+ <Box marginTop={1}>
479
+ <Text color={colors.secondary}>
480
+ Arrow keys: Navigate | Tab: Switch tabs | Shift+Tab: Go back
481
+ </Text>
482
+ </Box>
483
+ </Box>
484
+ );
485
+ }
486
+
487
+ if (mode === 'edit-selection') {
488
+ return (
489
+ <Box flexDirection="column">
490
+ <Box marginBottom={1}>
491
+ <Text bold color={colors.primary}>
492
+ Select an MCP server to edit:
493
+ </Text>
494
+ </Box>
495
+ <SelectInput
496
+ items={editOptions}
497
+ onSelect={(item: TemplateOption) => handleEditSelect(item)}
498
+ />
499
+ <Box marginTop={1}>
500
+ <Text color={colors.secondary}>Shift+Tab: Go back</Text>
501
+ </Box>
502
+ </Box>
503
+ );
504
+ }
505
+
506
+ if (mode === 'edit-or-delete') {
507
+ const server =
508
+ editingServerName !== null ? servers[editingServerName] : null;
509
+ const editOrDeleteOptions = [
510
+ {label: 'Edit this server', value: 'edit'},
511
+ {label: 'Delete this server', value: 'delete'},
512
+ ];
513
+
514
+ return (
515
+ <Box flexDirection="column">
516
+ <Box marginBottom={1}>
517
+ <Text bold color={colors.primary}>
518
+ {server?.name} - What would you like to do?
519
+ </Text>
520
+ </Box>
521
+ <SelectInput
522
+ items={editOrDeleteOptions}
523
+ onSelect={(item: {value: string}) => handleEditOrDeleteChoice(item)}
524
+ />
525
+ <Box marginTop={1}>
526
+ <Text color={colors.secondary}>Shift+Tab: Go back</Text>
527
+ </Box>
528
+ </Box>
529
+ );
530
+ }
531
+
532
+ if (mode === 'field-input' && selectedTemplate) {
533
+ const currentField = selectedTemplate.fields[currentFieldIndex];
534
+ if (!currentField) return null;
535
+
536
+ const isMultiline = currentField.name === 'envVars';
537
+
538
+ return (
539
+ <Box flexDirection="column">
540
+ <Box marginBottom={1}>
541
+ <Text bold color={colors.primary}>
542
+ {selectedTemplate.name} Configuration
543
+ </Text>
544
+ <Text dimColor>
545
+ {' '}
546
+ (Field {currentFieldIndex + 1}/{selectedTemplate.fields.length})
547
+ </Text>
548
+ </Box>
549
+
550
+ <Box>
551
+ <Text>
552
+ {currentField.prompt}
553
+ {currentField.required && <Text color={colors.error}> *</Text>}
554
+ {currentField.default && (
555
+ <Text dimColor> [{currentField.default}]</Text>
556
+ )}
557
+ : {currentField.sensitive && '****'}
558
+ </Text>
559
+ </Box>
560
+
561
+ {isMultiline ? (
562
+ <Box flexDirection="column" marginBottom={1}>
563
+ <Box
564
+ borderStyle="round"
565
+ borderColor={colors.secondary}
566
+ paddingX={1}
567
+ >
568
+ <Text>{multilineBuffer || <Text dimColor>(empty)</Text>}</Text>
569
+ </Box>
570
+ <Box marginTop={1}>
571
+ <Text color={colors.secondary}>
572
+ Type to add lines. Press Esc when done to submit.
573
+ </Text>
574
+ </Box>
575
+ </Box>
576
+ ) : currentField.sensitive ? (
577
+ <Box
578
+ marginBottom={1}
579
+ borderStyle="round"
580
+ borderColor={colors.secondary}
581
+ >
582
+ <TextInput
583
+ key={inputKey}
584
+ value={currentValue}
585
+ onChange={setCurrentValue}
586
+ onSubmit={handleFieldSubmit}
587
+ mask="*"
588
+ />
589
+ </Box>
590
+ ) : (
591
+ <Box
592
+ marginBottom={1}
593
+ borderStyle="round"
594
+ borderColor={colors.secondary}
595
+ >
596
+ <TextInput
597
+ key={inputKey}
598
+ value={currentValue}
599
+ onChange={setCurrentValue}
600
+ onSubmit={handleFieldSubmit}
601
+ />
602
+ </Box>
603
+ )}
604
+
605
+ {error && (
606
+ <Box marginBottom={1}>
607
+ <Text color={colors.error}>{error}</Text>
608
+ </Box>
609
+ )}
610
+
611
+ {isNarrow ? (
612
+ <Box flexDirection="column">
613
+ <Text color={colors.secondary}>
614
+ {isMultiline ? 'Esc: submit' : 'Enter: continue'}
615
+ </Text>
616
+ <Text color={colors.secondary}>Shift+Tab: go back</Text>
617
+ </Box>
618
+ ) : (
619
+ <Box>
620
+ <Text color={colors.secondary}>
621
+ {isMultiline
622
+ ? 'Press Esc to submit | Shift+Tab to go back'
623
+ : 'Press Enter to continue | Shift+Tab to go back'}
624
+ </Text>
625
+ </Box>
626
+ )}
627
+ </Box>
628
+ );
629
+ }
630
+
631
+ return null;
632
+ }