@butlerw/vellum 0.1.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 (446) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +411 -0
  3. package/__fixtures__/responses/code-generation.json +42 -0
  4. package/__fixtures__/responses/error-response.json +20 -0
  5. package/__fixtures__/responses/hello-world.json +32 -0
  6. package/dist/auth-6MCXESOH.js +26 -0
  7. package/dist/chunk-SECXJGWA.js +597 -0
  8. package/dist/index.js +34023 -0
  9. package/package.json +67 -0
  10. package/src/__tests__/commands.e2e.test.ts +728 -0
  11. package/src/__tests__/credentials.test.ts +713 -0
  12. package/src/__tests__/mode-e2e.test.ts +391 -0
  13. package/src/__tests__/tui-integration.test.tsx +1271 -0
  14. package/src/agents/__tests__/task-persistence.test.ts +235 -0
  15. package/src/agents/commands/delegate.ts +240 -0
  16. package/src/agents/commands/index.ts +10 -0
  17. package/src/agents/commands/resume.ts +335 -0
  18. package/src/agents/index.ts +29 -0
  19. package/src/agents/task-persistence.ts +272 -0
  20. package/src/agents/task-resumption.ts +242 -0
  21. package/src/app.tsx +4737 -0
  22. package/src/commands/__tests__/.gitkeep +1 -0
  23. package/src/commands/__tests__/agents.test.ts +606 -0
  24. package/src/commands/__tests__/auth.test.ts +626 -0
  25. package/src/commands/__tests__/autocomplete.test.ts +683 -0
  26. package/src/commands/__tests__/batch.test.ts +287 -0
  27. package/src/commands/__tests__/chain-pipe-parser.test.ts +654 -0
  28. package/src/commands/__tests__/completion.test.ts +238 -0
  29. package/src/commands/__tests__/core.test.ts +363 -0
  30. package/src/commands/__tests__/executor.test.ts +496 -0
  31. package/src/commands/__tests__/exit-codes.test.ts +220 -0
  32. package/src/commands/__tests__/init.test.ts +243 -0
  33. package/src/commands/__tests__/language.test.ts +353 -0
  34. package/src/commands/__tests__/mode-cli.test.ts +667 -0
  35. package/src/commands/__tests__/model.test.ts +277 -0
  36. package/src/commands/__tests__/parser.test.ts +493 -0
  37. package/src/commands/__tests__/performance.bench.ts +380 -0
  38. package/src/commands/__tests__/registry.test.ts +534 -0
  39. package/src/commands/__tests__/resume.test.ts +449 -0
  40. package/src/commands/__tests__/security.test.ts +845 -0
  41. package/src/commands/__tests__/stream-json.test.ts +372 -0
  42. package/src/commands/__tests__/user-commands.test.ts +597 -0
  43. package/src/commands/adapters.ts +267 -0
  44. package/src/commands/agent.ts +395 -0
  45. package/src/commands/agents/generate.ts +506 -0
  46. package/src/commands/agents/index.ts +272 -0
  47. package/src/commands/agents/show.ts +271 -0
  48. package/src/commands/agents/validate.ts +387 -0
  49. package/src/commands/auth.ts +883 -0
  50. package/src/commands/autocomplete.ts +480 -0
  51. package/src/commands/batch/command.ts +388 -0
  52. package/src/commands/batch/executor.ts +361 -0
  53. package/src/commands/batch/index.ts +12 -0
  54. package/src/commands/commit.ts +235 -0
  55. package/src/commands/completion/index.ts +371 -0
  56. package/src/commands/condense.ts +191 -0
  57. package/src/commands/config.ts +344 -0
  58. package/src/commands/context-provider.ts +173 -0
  59. package/src/commands/copy.ts +329 -0
  60. package/src/commands/core/clear.ts +38 -0
  61. package/src/commands/core/exit.ts +43 -0
  62. package/src/commands/core/help.ts +354 -0
  63. package/src/commands/core/index.ts +15 -0
  64. package/src/commands/cost.ts +179 -0
  65. package/src/commands/credentials.tsx +618 -0
  66. package/src/commands/custom-agents/__tests__/custom-agents.test.ts +709 -0
  67. package/src/commands/custom-agents/create.ts +377 -0
  68. package/src/commands/custom-agents/export.ts +135 -0
  69. package/src/commands/custom-agents/import.ts +199 -0
  70. package/src/commands/custom-agents/index.ts +372 -0
  71. package/src/commands/custom-agents/info.ts +318 -0
  72. package/src/commands/custom-agents/list.ts +267 -0
  73. package/src/commands/custom-agents/validate.ts +388 -0
  74. package/src/commands/diff-mode.ts +241 -0
  75. package/src/commands/env.ts +53 -0
  76. package/src/commands/executor.ts +579 -0
  77. package/src/commands/exit-codes.ts +202 -0
  78. package/src/commands/index.ts +701 -0
  79. package/src/commands/init/index.ts +15 -0
  80. package/src/commands/init/prompts.ts +366 -0
  81. package/src/commands/init/templates/commands-readme.md +80 -0
  82. package/src/commands/init/templates/example-command.md +79 -0
  83. package/src/commands/init/templates/example-skill.md +168 -0
  84. package/src/commands/init/templates/example-workflow.md +101 -0
  85. package/src/commands/init/templates/prompts-readme.md +52 -0
  86. package/src/commands/init/templates/rules-readme.md +63 -0
  87. package/src/commands/init/templates/skills-readme.md +83 -0
  88. package/src/commands/init/templates/workflows-readme.md +94 -0
  89. package/src/commands/init.ts +391 -0
  90. package/src/commands/install.ts +90 -0
  91. package/src/commands/language.ts +191 -0
  92. package/src/commands/loaders/.gitkeep +1 -0
  93. package/src/commands/lsp.ts +199 -0
  94. package/src/commands/markdown-commands.ts +253 -0
  95. package/src/commands/mcp.ts +588 -0
  96. package/src/commands/memory/export.ts +341 -0
  97. package/src/commands/memory/index.ts +148 -0
  98. package/src/commands/memory/list.ts +261 -0
  99. package/src/commands/memory/search.ts +346 -0
  100. package/src/commands/memory/utils.ts +15 -0
  101. package/src/commands/metrics.ts +75 -0
  102. package/src/commands/migrate/index.ts +16 -0
  103. package/src/commands/migrate/prompts.ts +477 -0
  104. package/src/commands/mode.ts +331 -0
  105. package/src/commands/model.ts +298 -0
  106. package/src/commands/onboard.ts +205 -0
  107. package/src/commands/open.ts +169 -0
  108. package/src/commands/output/stream-json.ts +373 -0
  109. package/src/commands/parser/chain-parser.ts +370 -0
  110. package/src/commands/parser/index.ts +29 -0
  111. package/src/commands/parser/pipe-parser.ts +480 -0
  112. package/src/commands/parser.ts +588 -0
  113. package/src/commands/persistence.ts +355 -0
  114. package/src/commands/progress.ts +18 -0
  115. package/src/commands/prompt/index.ts +17 -0
  116. package/src/commands/prompt/validate.ts +621 -0
  117. package/src/commands/prompt-priority.ts +401 -0
  118. package/src/commands/registry.ts +374 -0
  119. package/src/commands/sandbox/index.ts +131 -0
  120. package/src/commands/security/index.ts +21 -0
  121. package/src/commands/security/input-sanitizer.ts +168 -0
  122. package/src/commands/security/permission-checker.ts +456 -0
  123. package/src/commands/security/sensitive-data.ts +350 -0
  124. package/src/commands/session/delete.ts +38 -0
  125. package/src/commands/session/export.ts +39 -0
  126. package/src/commands/session/index.ts +26 -0
  127. package/src/commands/session/list.ts +26 -0
  128. package/src/commands/session/resume.ts +562 -0
  129. package/src/commands/session/search.ts +434 -0
  130. package/src/commands/session/show.ts +26 -0
  131. package/src/commands/settings.ts +368 -0
  132. package/src/commands/setup.ts +23 -0
  133. package/src/commands/shell/index.ts +16 -0
  134. package/src/commands/shell/setup.ts +422 -0
  135. package/src/commands/shell-init.ts +50 -0
  136. package/src/commands/shell-integration/index.ts +194 -0
  137. package/src/commands/skill.ts +1220 -0
  138. package/src/commands/spec.ts +558 -0
  139. package/src/commands/status.ts +246 -0
  140. package/src/commands/theme.ts +211 -0
  141. package/src/commands/think.ts +551 -0
  142. package/src/commands/trust.ts +211 -0
  143. package/src/commands/tutorial.ts +522 -0
  144. package/src/commands/types.ts +512 -0
  145. package/src/commands/update.ts +274 -0
  146. package/src/commands/usage.ts +213 -0
  147. package/src/commands/user-commands.ts +630 -0
  148. package/src/commands/utils.ts +142 -0
  149. package/src/commands/vim.ts +152 -0
  150. package/src/commands/workflow.ts +257 -0
  151. package/src/components/header.tsx +25 -0
  152. package/src/components/input.tsx +25 -0
  153. package/src/components/message-list.tsx +32 -0
  154. package/src/components/status-bar.tsx +23 -0
  155. package/src/index.tsx +614 -0
  156. package/src/onboarding/__tests__/tutorial.test.ts +740 -0
  157. package/src/onboarding/index.ts +69 -0
  158. package/src/onboarding/tips/index.ts +9 -0
  159. package/src/onboarding/tips/tip-engine.ts +459 -0
  160. package/src/onboarding/tutorial/index.ts +88 -0
  161. package/src/onboarding/tutorial/lessons/basics.ts +151 -0
  162. package/src/onboarding/tutorial/lessons/index.ts +151 -0
  163. package/src/onboarding/tutorial/lessons/modes.ts +230 -0
  164. package/src/onboarding/tutorial/lessons/tools.ts +172 -0
  165. package/src/onboarding/tutorial/progress-tracker.ts +350 -0
  166. package/src/onboarding/tutorial/storage.ts +249 -0
  167. package/src/onboarding/tutorial/tutorial-system.ts +462 -0
  168. package/src/onboarding/tutorial/types.ts +310 -0
  169. package/src/orchestrator-singleton.ts +129 -0
  170. package/src/shutdown.ts +33 -0
  171. package/src/test/e2e/assertions.ts +267 -0
  172. package/src/test/e2e/fixtures.ts +204 -0
  173. package/src/test/e2e/harness.ts +575 -0
  174. package/src/test/e2e/index.ts +57 -0
  175. package/src/test/e2e/types.ts +228 -0
  176. package/src/test/fixtures/__tests__/fake-response-loader.test.ts +314 -0
  177. package/src/test/fixtures/fake-response-loader.ts +314 -0
  178. package/src/test/fixtures/index.ts +20 -0
  179. package/src/tui/__tests__/mcp-panel.test.tsx +82 -0
  180. package/src/tui/__tests__/mcp-wiring.test.tsx +78 -0
  181. package/src/tui/__tests__/mode-components.test.tsx +395 -0
  182. package/src/tui/__tests__/permission-ask-flow.test.tsx +138 -0
  183. package/src/tui/__tests__/sidebar-panel-data.test.tsx +148 -0
  184. package/src/tui/__tests__/tools-panel-hotkeys.test.tsx +41 -0
  185. package/src/tui/adapters/agent-adapter.ts +1008 -0
  186. package/src/tui/adapters/index.ts +48 -0
  187. package/src/tui/adapters/message-adapter.ts +315 -0
  188. package/src/tui/adapters/persistence-bridge.ts +331 -0
  189. package/src/tui/adapters/session-adapter.ts +419 -0
  190. package/src/tui/buffered-stdout.ts +223 -0
  191. package/src/tui/components/AgentProgress.tsx +424 -0
  192. package/src/tui/components/Banner/AsciiArt.ts +160 -0
  193. package/src/tui/components/Banner/Banner.tsx +355 -0
  194. package/src/tui/components/Banner/ShimmerContext.tsx +131 -0
  195. package/src/tui/components/Banner/ShimmerText.tsx +193 -0
  196. package/src/tui/components/Banner/TypeWriterGradient.tsx +321 -0
  197. package/src/tui/components/Banner/index.ts +61 -0
  198. package/src/tui/components/Banner/useShimmer.ts +241 -0
  199. package/src/tui/components/ChatView.tsx +11 -0
  200. package/src/tui/components/Checkpoint/CheckpointDiffView.tsx +371 -0
  201. package/src/tui/components/Checkpoint/SnapshotCheckpointPanel.tsx +440 -0
  202. package/src/tui/components/Checkpoint/index.ts +19 -0
  203. package/src/tui/components/CostDisplay.tsx +226 -0
  204. package/src/tui/components/InitErrorBanner.tsx +122 -0
  205. package/src/tui/components/Input/Autocomplete.tsx +603 -0
  206. package/src/tui/components/Input/EnhancedCommandInput.tsx +471 -0
  207. package/src/tui/components/Input/HighlightedText.tsx +236 -0
  208. package/src/tui/components/Input/MentionAutocomplete.tsx +375 -0
  209. package/src/tui/components/Input/TextInput.tsx +1002 -0
  210. package/src/tui/components/Input/__tests__/Autocomplete.test.tsx +374 -0
  211. package/src/tui/components/Input/__tests__/TextInput.test.tsx +241 -0
  212. package/src/tui/components/Input/__tests__/highlight.test.ts +219 -0
  213. package/src/tui/components/Input/__tests__/slash-command-utils.test.ts +104 -0
  214. package/src/tui/components/Input/highlight.ts +362 -0
  215. package/src/tui/components/Input/index.ts +36 -0
  216. package/src/tui/components/Input/slash-command-utils.ts +135 -0
  217. package/src/tui/components/Layout.tsx +432 -0
  218. package/src/tui/components/McpPanel.tsx +137 -0
  219. package/src/tui/components/MemoryPanel.tsx +448 -0
  220. package/src/tui/components/Messages/CodeBlock.tsx +527 -0
  221. package/src/tui/components/Messages/DiffView.tsx +679 -0
  222. package/src/tui/components/Messages/ImageReference.tsx +89 -0
  223. package/src/tui/components/Messages/MarkdownBlock.tsx +228 -0
  224. package/src/tui/components/Messages/MarkdownRenderer.tsx +498 -0
  225. package/src/tui/components/Messages/MessageBubble.tsx +270 -0
  226. package/src/tui/components/Messages/MessageList.tsx +1719 -0
  227. package/src/tui/components/Messages/StreamingText.tsx +216 -0
  228. package/src/tui/components/Messages/ThinkingBlock.tsx +408 -0
  229. package/src/tui/components/Messages/ToolResultPreview.tsx +243 -0
  230. package/src/tui/components/Messages/__tests__/CodeBlock.test.tsx +296 -0
  231. package/src/tui/components/Messages/__tests__/DiffView.test.tsx +239 -0
  232. package/src/tui/components/Messages/__tests__/MarkdownRenderer.test.tsx +303 -0
  233. package/src/tui/components/Messages/__tests__/MessageBubble.test.tsx +268 -0
  234. package/src/tui/components/Messages/__tests__/MessageList.test.tsx +324 -0
  235. package/src/tui/components/Messages/__tests__/StreamingText.test.tsx +215 -0
  236. package/src/tui/components/Messages/index.ts +25 -0
  237. package/src/tui/components/ModeIndicator.tsx +177 -0
  238. package/src/tui/components/ModeSelector.tsx +216 -0
  239. package/src/tui/components/ModelSelector.tsx +339 -0
  240. package/src/tui/components/OnboardingWizard.tsx +670 -0
  241. package/src/tui/components/PhaseProgressIndicator.tsx +270 -0
  242. package/src/tui/components/RateLimitIndicator.tsx +82 -0
  243. package/src/tui/components/ScreenReaderLayout.tsx +295 -0
  244. package/src/tui/components/SettingsPanel.tsx +643 -0
  245. package/src/tui/components/Sidebar/SystemStatusPanel.tsx +284 -0
  246. package/src/tui/components/Sidebar/index.ts +9 -0
  247. package/src/tui/components/Status/ModelStatusBar.tsx +270 -0
  248. package/src/tui/components/Status/index.ts +12 -0
  249. package/src/tui/components/StatusBar/AgentModeIndicator.tsx +257 -0
  250. package/src/tui/components/StatusBar/ContextProgress.tsx +167 -0
  251. package/src/tui/components/StatusBar/FileChangesIndicator.tsx +62 -0
  252. package/src/tui/components/StatusBar/GitIndicator.tsx +89 -0
  253. package/src/tui/components/StatusBar/HeaderBar.tsx +126 -0
  254. package/src/tui/components/StatusBar/ModelIndicator.tsx +157 -0
  255. package/src/tui/components/StatusBar/PersistenceStatusIndicator.tsx +210 -0
  256. package/src/tui/components/StatusBar/ResilienceIndicator.tsx +106 -0
  257. package/src/tui/components/StatusBar/SandboxIndicator.tsx +167 -0
  258. package/src/tui/components/StatusBar/StatusBar.tsx +368 -0
  259. package/src/tui/components/StatusBar/ThinkingModeIndicator.tsx +170 -0
  260. package/src/tui/components/StatusBar/TokenBreakdown.tsx +246 -0
  261. package/src/tui/components/StatusBar/TokenCounter.tsx +135 -0
  262. package/src/tui/components/StatusBar/TrustModeIndicator.tsx +130 -0
  263. package/src/tui/components/StatusBar/WorkspaceIndicator.tsx +86 -0
  264. package/src/tui/components/StatusBar/__tests__/AgentModeIndicator.test.tsx +193 -0
  265. package/src/tui/components/StatusBar/__tests__/StatusBar.test.tsx +729 -0
  266. package/src/tui/components/StatusBar/index.ts +60 -0
  267. package/src/tui/components/TipBanner.tsx +115 -0
  268. package/src/tui/components/TodoItem.tsx +208 -0
  269. package/src/tui/components/TodoPanel.tsx +455 -0
  270. package/src/tui/components/Tools/ApprovalQueue.tsx +407 -0
  271. package/src/tui/components/Tools/OptionSelector.tsx +160 -0
  272. package/src/tui/components/Tools/PermissionDialog.tsx +286 -0
  273. package/src/tui/components/Tools/ToolParams.tsx +483 -0
  274. package/src/tui/components/Tools/ToolsPanel.tsx +178 -0
  275. package/src/tui/components/Tools/__tests__/PermissionDialog.test.tsx +510 -0
  276. package/src/tui/components/Tools/__tests__/ToolParams.test.tsx +432 -0
  277. package/src/tui/components/Tools/index.ts +21 -0
  278. package/src/tui/components/TrustPrompt.tsx +279 -0
  279. package/src/tui/components/UpdateBanner.tsx +166 -0
  280. package/src/tui/components/VimModeIndicator.tsx +112 -0
  281. package/src/tui/components/backtrack/BacktrackControls.tsx +402 -0
  282. package/src/tui/components/backtrack/index.ts +13 -0
  283. package/src/tui/components/common/AutoApprovalStatus.tsx +251 -0
  284. package/src/tui/components/common/CostWarning.tsx +294 -0
  285. package/src/tui/components/common/DynamicShortcutHints.tsx +209 -0
  286. package/src/tui/components/common/EnhancedLoadingIndicator.tsx +305 -0
  287. package/src/tui/components/common/ErrorBoundary.tsx +140 -0
  288. package/src/tui/components/common/GradientText.tsx +224 -0
  289. package/src/tui/components/common/HotkeyHelpModal.tsx +193 -0
  290. package/src/tui/components/common/HotkeyHints.tsx +70 -0
  291. package/src/tui/components/common/MaxSizedBox.tsx +354 -0
  292. package/src/tui/components/common/NewMessagesBadge.tsx +65 -0
  293. package/src/tui/components/common/ProtectedFileLegend.tsx +89 -0
  294. package/src/tui/components/common/ScrollIndicator.tsx +160 -0
  295. package/src/tui/components/common/Spinner.tsx +342 -0
  296. package/src/tui/components/common/StreamingIndicator.tsx +316 -0
  297. package/src/tui/components/common/VirtualizedList/VirtualizedList.tsx +428 -0
  298. package/src/tui/components/common/VirtualizedList/hooks/index.ts +19 -0
  299. package/src/tui/components/common/VirtualizedList/hooks/useBatchedScroll.ts +64 -0
  300. package/src/tui/components/common/VirtualizedList/hooks/useScrollAnchor.ts +290 -0
  301. package/src/tui/components/common/VirtualizedList/hooks/useVirtualization.ts +340 -0
  302. package/src/tui/components/common/VirtualizedList/index.ts +30 -0
  303. package/src/tui/components/common/VirtualizedList/types.ts +107 -0
  304. package/src/tui/components/common/__tests__/NewMessagesBadge.test.tsx +74 -0
  305. package/src/tui/components/common/__tests__/ScrollIndicator.test.tsx +193 -0
  306. package/src/tui/components/common/index.ts +110 -0
  307. package/src/tui/components/index.ts +79 -0
  308. package/src/tui/components/session/CheckpointPanel.tsx +323 -0
  309. package/src/tui/components/session/RollbackDialog.tsx +169 -0
  310. package/src/tui/components/session/SessionItem.tsx +136 -0
  311. package/src/tui/components/session/SessionListPanel.tsx +252 -0
  312. package/src/tui/components/session/SessionPicker.tsx +449 -0
  313. package/src/tui/components/session/SessionPreview.tsx +240 -0
  314. package/src/tui/components/session/__tests__/session.test.tsx +408 -0
  315. package/src/tui/components/session/index.ts +28 -0
  316. package/src/tui/components/session/types.ts +116 -0
  317. package/src/tui/components/theme/__tests__/tokens.test.ts +471 -0
  318. package/src/tui/components/theme/index.ts +227 -0
  319. package/src/tui/components/theme/tokens.ts +484 -0
  320. package/src/tui/config/defaults.ts +134 -0
  321. package/src/tui/config/index.ts +17 -0
  322. package/src/tui/context/AnimationContext.tsx +284 -0
  323. package/src/tui/context/AppContext.tsx +349 -0
  324. package/src/tui/context/BracketedPasteContext.tsx +372 -0
  325. package/src/tui/context/LspContext.tsx +192 -0
  326. package/src/tui/context/McpContext.tsx +325 -0
  327. package/src/tui/context/MessagesContext.tsx +870 -0
  328. package/src/tui/context/OverflowContext.tsx +213 -0
  329. package/src/tui/context/RateLimitContext.tsx +108 -0
  330. package/src/tui/context/ResilienceContext.tsx +275 -0
  331. package/src/tui/context/RootProvider.tsx +136 -0
  332. package/src/tui/context/ScrollContext.tsx +331 -0
  333. package/src/tui/context/ToolsContext.tsx +702 -0
  334. package/src/tui/context/__tests__/BracketedPasteContext.test.tsx +416 -0
  335. package/src/tui/context/index.ts +140 -0
  336. package/src/tui/enterprise-integration.ts +282 -0
  337. package/src/tui/hooks/__tests__/useBacktrack.test.tsx +138 -0
  338. package/src/tui/hooks/__tests__/useBracketedPaste.test.tsx +222 -0
  339. package/src/tui/hooks/__tests__/useCopyMode.test.tsx +336 -0
  340. package/src/tui/hooks/__tests__/useHotkeys.ctrl-input.test.tsx +96 -0
  341. package/src/tui/hooks/__tests__/useHotkeys.test.tsx +454 -0
  342. package/src/tui/hooks/__tests__/useInputHistory.test.tsx +660 -0
  343. package/src/tui/hooks/__tests__/useLineBuffer.test.ts +295 -0
  344. package/src/tui/hooks/__tests__/useModeController.test.ts +137 -0
  345. package/src/tui/hooks/__tests__/useModeShortcuts.test.tsx +142 -0
  346. package/src/tui/hooks/__tests__/useScrollController.test.ts +464 -0
  347. package/src/tui/hooks/__tests__/useVim.test.tsx +531 -0
  348. package/src/tui/hooks/index.ts +252 -0
  349. package/src/tui/hooks/useAgentLoop.ts +712 -0
  350. package/src/tui/hooks/useAlternateBuffer.ts +398 -0
  351. package/src/tui/hooks/useAnimatedScrollbar.ts +241 -0
  352. package/src/tui/hooks/useBacktrack.ts +443 -0
  353. package/src/tui/hooks/useBracketedPaste.ts +104 -0
  354. package/src/tui/hooks/useCollapsible.ts +240 -0
  355. package/src/tui/hooks/useCopyMode.ts +382 -0
  356. package/src/tui/hooks/useCostSummary.ts +75 -0
  357. package/src/tui/hooks/useDesktopNotification.ts +414 -0
  358. package/src/tui/hooks/useDiffMode.ts +44 -0
  359. package/src/tui/hooks/useFileChangeStats.ts +110 -0
  360. package/src/tui/hooks/useFileSuggestions.ts +284 -0
  361. package/src/tui/hooks/useFlickerDetector.ts +250 -0
  362. package/src/tui/hooks/useGitStatus.ts +200 -0
  363. package/src/tui/hooks/useHotkeys.ts +579 -0
  364. package/src/tui/hooks/useImagePaste.ts +114 -0
  365. package/src/tui/hooks/useInputHighlight.ts +145 -0
  366. package/src/tui/hooks/useInputHistory.ts +246 -0
  367. package/src/tui/hooks/useKeyboardScroll.ts +209 -0
  368. package/src/tui/hooks/useLineBuffer.ts +356 -0
  369. package/src/tui/hooks/useMentionAutocomplete.ts +235 -0
  370. package/src/tui/hooks/useModeController.ts +167 -0
  371. package/src/tui/hooks/useModeShortcuts.ts +196 -0
  372. package/src/tui/hooks/usePermissionHandler.ts +146 -0
  373. package/src/tui/hooks/usePersistence.ts +480 -0
  374. package/src/tui/hooks/usePersistenceShortcuts.ts +225 -0
  375. package/src/tui/hooks/usePlaceholderRotation.ts +143 -0
  376. package/src/tui/hooks/useProviderStatus.ts +270 -0
  377. package/src/tui/hooks/useRateLimitStatus.ts +90 -0
  378. package/src/tui/hooks/useScreenReader.ts +315 -0
  379. package/src/tui/hooks/useScrollController.ts +450 -0
  380. package/src/tui/hooks/useScrollEventBatcher.ts +185 -0
  381. package/src/tui/hooks/useSidebarPanelData.ts +115 -0
  382. package/src/tui/hooks/useSmoothScroll.ts +202 -0
  383. package/src/tui/hooks/useSnapshots.ts +300 -0
  384. package/src/tui/hooks/useStateAndRef.ts +50 -0
  385. package/src/tui/hooks/useTerminalSize.ts +206 -0
  386. package/src/tui/hooks/useToolApprovalController.ts +91 -0
  387. package/src/tui/hooks/useVim.ts +334 -0
  388. package/src/tui/hooks/useWorkspace.ts +56 -0
  389. package/src/tui/i18n/__tests__/init.test.ts +278 -0
  390. package/src/tui/i18n/__tests__/language-config.test.ts +199 -0
  391. package/src/tui/i18n/__tests__/locale-detection.test.ts +250 -0
  392. package/src/tui/i18n/__tests__/settings-integration.test.ts +262 -0
  393. package/src/tui/i18n/index.ts +72 -0
  394. package/src/tui/i18n/init.ts +131 -0
  395. package/src/tui/i18n/language-config.ts +106 -0
  396. package/src/tui/i18n/locale-detection.ts +173 -0
  397. package/src/tui/i18n/settings-integration.ts +557 -0
  398. package/src/tui/i18n/tui-namespace.ts +538 -0
  399. package/src/tui/i18n/types.ts +312 -0
  400. package/src/tui/index.ts +43 -0
  401. package/src/tui/lsp-integration.ts +409 -0
  402. package/src/tui/metrics-integration.ts +366 -0
  403. package/src/tui/plugins.ts +383 -0
  404. package/src/tui/resilience.ts +342 -0
  405. package/src/tui/sandbox-integration.ts +317 -0
  406. package/src/tui/services/clipboard.ts +348 -0
  407. package/src/tui/services/fuzzy-search.ts +441 -0
  408. package/src/tui/services/index.ts +72 -0
  409. package/src/tui/services/markdown-renderer.ts +565 -0
  410. package/src/tui/services/open-external.ts +247 -0
  411. package/src/tui/services/syntax-highlighter.ts +483 -0
  412. package/src/tui/slash-commands.ts +12 -0
  413. package/src/tui/theme/index.ts +15 -0
  414. package/src/tui/theme/provider.tsx +206 -0
  415. package/src/tui/tip-integration.ts +300 -0
  416. package/src/tui/types/__tests__/ink-extended.test.ts +121 -0
  417. package/src/tui/types/ink-extended.ts +87 -0
  418. package/src/tui/utils/__tests__/bracketedPaste.test.ts +231 -0
  419. package/src/tui/utils/__tests__/heightEstimator.test.ts +157 -0
  420. package/src/tui/utils/__tests__/text-width.test.ts +158 -0
  421. package/src/tui/utils/__tests__/textSanitizer.test.ts +266 -0
  422. package/src/tui/utils/__tests__/ui-sizing.test.ts +169 -0
  423. package/src/tui/utils/bracketedPaste.ts +107 -0
  424. package/src/tui/utils/cursor-manager.ts +131 -0
  425. package/src/tui/utils/detectTerminal.ts +596 -0
  426. package/src/tui/utils/findLastSafeSplitPoint.ts +92 -0
  427. package/src/tui/utils/heightEstimator.ts +198 -0
  428. package/src/tui/utils/index.ts +91 -0
  429. package/src/tui/utils/isNarrowWidth.ts +52 -0
  430. package/src/tui/utils/stdoutGuard.ts +90 -0
  431. package/src/tui/utils/synchronized-update.ts +70 -0
  432. package/src/tui/utils/text-width.ts +225 -0
  433. package/src/tui/utils/textSanitizer.ts +225 -0
  434. package/src/tui/utils/textUtils.ts +114 -0
  435. package/src/tui/utils/ui-sizing.ts +192 -0
  436. package/src/tui-blessed/app.ts +160 -0
  437. package/src/tui-blessed/index.ts +2 -0
  438. package/src/tui-blessed/neo-blessed.d.ts +6 -0
  439. package/src/tui-blessed/test.ts +21 -0
  440. package/src/tui-blessed/types.ts +14 -0
  441. package/src/utils/icons.ts +130 -0
  442. package/src/utils/index.ts +33 -0
  443. package/src/utils/resume-hint.ts +86 -0
  444. package/src/version.ts +1 -0
  445. package/tsconfig.json +8 -0
  446. package/vitest.config.ts +35 -0
@@ -0,0 +1,131 @@
1
+ /**
2
+ * i18n Initialization Module
3
+ *
4
+ * Provides locale resolution and initialization functions.
5
+ * Implements the priority chain for determining the active locale.
6
+ *
7
+ * @module tui/i18n/init
8
+ */
9
+
10
+ import { DEFAULT_LOCALE, isLocaleSupported, type LocaleCode } from "./language-config.js";
11
+ import { detectSystemLocale } from "./locale-detection.js";
12
+ import { getSavedLanguage } from "./settings-integration.js";
13
+ import { setGlobalLocale } from "./tui-namespace.js";
14
+
15
+ /**
16
+ * Options for resolving the locale.
17
+ */
18
+ export interface ResolveLocaleOptions {
19
+ /** CLI --language flag value */
20
+ cliLanguage?: string;
21
+ }
22
+
23
+ /**
24
+ * Source of the resolved locale.
25
+ */
26
+ export type ResolvedLocaleSource = "cli-flag" | "env-var" | "settings" | "system" | "default";
27
+
28
+ /**
29
+ * Result of locale resolution.
30
+ */
31
+ export interface ResolvedLocale {
32
+ /** The resolved locale code */
33
+ locale: LocaleCode;
34
+ /** Source that provided the locale */
35
+ source: ResolvedLocaleSource;
36
+ }
37
+
38
+ /**
39
+ * Resolve the locale to use based on priority chain.
40
+ *
41
+ * Priority order (highest to lowest):
42
+ * 1. CLI flag (`options.cliLanguage`) → source: "cli-flag"
43
+ * 2. VELLUM_LANGUAGE environment variable → source: "env-var"
44
+ * 3. Saved settings (user preference) → source: "settings"
45
+ * 4. System locale detection → source: "system"
46
+ * 5. Default locale (en) → source: "default"
47
+ *
48
+ * Each source is validated with `isLocaleSupported()` before use.
49
+ *
50
+ * @param options - Resolution options
51
+ * @returns Resolved locale with source information
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * // With CLI flag
56
+ * resolveLocale({ cliLanguage: "zh" });
57
+ * // { locale: "zh", source: "cli-flag" }
58
+ *
59
+ * // Without options, uses priority chain
60
+ * resolveLocale();
61
+ * // { locale: "en", source: "settings" } // if saved in settings
62
+ * ```
63
+ */
64
+ export function resolveLocale(options?: ResolveLocaleOptions): ResolvedLocale {
65
+ // 1. CLI flag (highest priority)
66
+ if (options?.cliLanguage && isLocaleSupported(options.cliLanguage)) {
67
+ return {
68
+ locale: options.cliLanguage as LocaleCode,
69
+ source: "cli-flag",
70
+ };
71
+ }
72
+
73
+ // 2. VELLUM_LANGUAGE environment variable
74
+ const envLocale = process.env.VELLUM_LANGUAGE;
75
+ if (envLocale && isLocaleSupported(envLocale)) {
76
+ return {
77
+ locale: envLocale as LocaleCode,
78
+ source: "env-var",
79
+ };
80
+ }
81
+
82
+ // 3. Saved settings
83
+ const savedLocale = getSavedLanguage();
84
+ if (savedLocale && isLocaleSupported(savedLocale)) {
85
+ return {
86
+ locale: savedLocale,
87
+ source: "settings",
88
+ };
89
+ }
90
+
91
+ // 4. System locale detection
92
+ const systemDetected = detectSystemLocale();
93
+ if (systemDetected.locale && isLocaleSupported(systemDetected.locale)) {
94
+ return {
95
+ locale: systemDetected.locale,
96
+ source: "system",
97
+ };
98
+ }
99
+
100
+ // 5. Default locale (lowest priority)
101
+ return {
102
+ locale: DEFAULT_LOCALE,
103
+ source: "default",
104
+ };
105
+ }
106
+
107
+ /**
108
+ * Initialize the i18n system with resolved locale.
109
+ *
110
+ * Resolves the locale using the priority chain and sets it as
111
+ * the global locale for the application.
112
+ *
113
+ * @param options - Resolution options
114
+ * @returns Resolved locale with source information
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * // Initialize with CLI flag
119
+ * const result = initI18n({ cliLanguage: "zh" });
120
+ * console.log(`Using ${result.locale} from ${result.source}`);
121
+ *
122
+ * // Initialize without options
123
+ * const result = initI18n();
124
+ * // Uses priority chain: cli-flag → env-var → settings → system → default
125
+ * ```
126
+ */
127
+ export function initI18n(options?: ResolveLocaleOptions): ResolvedLocale {
128
+ const resolved = resolveLocale(options);
129
+ setGlobalLocale(resolved.locale);
130
+ return resolved;
131
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Language Configuration Module
3
+ *
4
+ * Core language configuration for i18n support.
5
+ * Defines supported locales and provides validation utilities.
6
+ *
7
+ * @module tui/i18n/language-config
8
+ */
9
+
10
+ /**
11
+ * Supported locale codes.
12
+ * Add new locales here as they are implemented.
13
+ */
14
+ export type LocaleCode = "en" | "zh";
15
+
16
+ /**
17
+ * Metadata for a supported language.
18
+ */
19
+ export interface LanguageInfo {
20
+ /** ISO locale code */
21
+ readonly locale: LocaleCode;
22
+ /** English name of the language */
23
+ readonly name: string;
24
+ /** Native name of the language */
25
+ readonly nativeName: string;
26
+ /** Flag emoji for the language */
27
+ readonly flag: string;
28
+ }
29
+
30
+ /**
31
+ * Language metadata for all supported locales.
32
+ */
33
+ export const LANGUAGES: Record<LocaleCode, LanguageInfo> = {
34
+ en: {
35
+ locale: "en",
36
+ name: "English",
37
+ nativeName: "English",
38
+ flag: "🇺🇸",
39
+ },
40
+ zh: {
41
+ locale: "zh",
42
+ name: "Chinese",
43
+ nativeName: "中文",
44
+ flag: "🇨🇳",
45
+ },
46
+ } as const;
47
+
48
+ /**
49
+ * Array of all supported locale codes.
50
+ */
51
+ export const SUPPORTED_LOCALES: readonly LocaleCode[] = Object.keys(LANGUAGES) as LocaleCode[];
52
+
53
+ /**
54
+ * Default locale used when no locale is specified.
55
+ */
56
+ export const DEFAULT_LOCALE: LocaleCode = "en";
57
+
58
+ /**
59
+ * Type guard to check if a string is a supported locale code.
60
+ *
61
+ * @param locale - The locale string to validate
62
+ * @returns True if the locale is supported
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const userLocale = getUserLocale();
67
+ * if (isLocaleSupported(userLocale)) {
68
+ * // userLocale is now typed as LocaleCode
69
+ * setLocale(userLocale);
70
+ * }
71
+ * ```
72
+ */
73
+ export function isLocaleSupported(locale: string): locale is LocaleCode {
74
+ return locale in LANGUAGES;
75
+ }
76
+
77
+ /**
78
+ * Get the native display name for a locale.
79
+ *
80
+ * @param locale - The locale code
81
+ * @returns The native name of the language
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * getLanguageDisplayName("zh"); // "中文"
86
+ * getLanguageDisplayName("en"); // "English"
87
+ * ```
88
+ */
89
+ export function getLanguageDisplayName(locale: LocaleCode): string {
90
+ return LANGUAGES[locale].nativeName;
91
+ }
92
+
93
+ /**
94
+ * Get all available locale codes.
95
+ *
96
+ * @returns Readonly array of supported locale codes
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * const locales = getAvailableLocales();
101
+ * // ["en", "zh"]
102
+ * ```
103
+ */
104
+ export function getAvailableLocales(): readonly LocaleCode[] {
105
+ return SUPPORTED_LOCALES;
106
+ }
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Locale Detection Module
3
+ *
4
+ * Detects system locale from environment variables.
5
+ * Follows POSIX locale conventions with Windows fallback support.
6
+ *
7
+ * @module tui/i18n/locale-detection
8
+ */
9
+
10
+ import { DEFAULT_LOCALE, isLocaleSupported, type LocaleCode } from "./language-config.js";
11
+
12
+ /**
13
+ * Result of parsing a POSIX locale string.
14
+ */
15
+ export interface ParsedLocale {
16
+ /** ISO 639-1 language code (e.g., "en", "zh") */
17
+ language: string;
18
+ /** ISO 3166-1 territory code (e.g., "US", "CN") */
19
+ territory?: string;
20
+ }
21
+
22
+ /**
23
+ * Source of locale detection.
24
+ */
25
+ export type LocaleSource = "LC_ALL" | "LC_MESSAGES" | "LANG" | "VELLUM_LANGUAGE" | null;
26
+
27
+ /**
28
+ * Result of system locale detection.
29
+ */
30
+ export interface DetectedLocale {
31
+ /** Detected locale code, or null if not detected */
32
+ locale: LocaleCode | null;
33
+ /** Source environment variable that provided the locale */
34
+ source: LocaleSource;
35
+ }
36
+
37
+ /**
38
+ * Parse a POSIX locale string into language and territory components.
39
+ *
40
+ * Handles formats like:
41
+ * - "en" → { language: "en" }
42
+ * - "en_US" → { language: "en", territory: "US" }
43
+ * - "zh_CN.UTF-8" → { language: "zh", territory: "CN" }
44
+ * - "en_US.UTF-8@modifier" → { language: "en", territory: "US" }
45
+ *
46
+ * @param localeString - The POSIX locale string to parse
47
+ * @returns Parsed locale object, or null if invalid or unset ("C", "POSIX")
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * parseLocaleString("zh_CN.UTF-8"); // { language: "zh", territory: "CN" }
52
+ * parseLocaleString("en"); // { language: "en" }
53
+ * parseLocaleString("C"); // null
54
+ * parseLocaleString(""); // null
55
+ * ```
56
+ */
57
+ export function parseLocaleString(localeString: string): ParsedLocale | null {
58
+ // Handle empty, null-like, or POSIX default values
59
+ const trimmed = localeString.trim();
60
+ if (!trimmed || trimmed === "C" || trimmed === "POSIX") {
61
+ return null;
62
+ }
63
+
64
+ // Remove encoding (e.g., ".UTF-8") and modifier (e.g., "@euro")
65
+ // Format: language[_territory][.encoding][@modifier]
66
+ const withoutModifier = trimmed.split("@")[0] ?? trimmed;
67
+ const withoutEncoding = withoutModifier.split(".")[0] ?? withoutModifier;
68
+
69
+ // Split into language and territory
70
+ const parts = withoutEncoding.split("_");
71
+ const languagePart = parts[0];
72
+ if (!languagePart) {
73
+ return null;
74
+ }
75
+ const language = languagePart.toLowerCase();
76
+
77
+ // Validate language code (should be 2-3 characters)
78
+ if (language.length < 2 || language.length > 3) {
79
+ return null;
80
+ }
81
+
82
+ const result: ParsedLocale = { language };
83
+
84
+ // Add territory if present
85
+ if (parts[1]) {
86
+ result.territory = parts[1].toUpperCase();
87
+ }
88
+
89
+ return result;
90
+ }
91
+
92
+ /**
93
+ * Environment variables to check for locale, in priority order.
94
+ */
95
+ const LOCALE_ENV_VARS = ["LC_ALL", "LC_MESSAGES", "LANG"] as const;
96
+
97
+ /**
98
+ * Map parsed locale to a supported LocaleCode.
99
+ *
100
+ * Handles territory variants by first trying language-territory (e.g., "pt-BR"),
101
+ * then falling back to just the language code.
102
+ *
103
+ * @param parsed - Parsed locale object
104
+ * @returns Supported LocaleCode or null
105
+ */
106
+ function mapToSupportedLocale(parsed: ParsedLocale): LocaleCode | null {
107
+ // Try language-territory format first (e.g., "pt-BR")
108
+ if (parsed.territory) {
109
+ const withTerritory = `${parsed.language}-${parsed.territory}`;
110
+ if (isLocaleSupported(withTerritory)) {
111
+ return withTerritory as LocaleCode;
112
+ }
113
+ }
114
+
115
+ // Fall back to just the language code
116
+ if (isLocaleSupported(parsed.language)) {
117
+ return parsed.language as LocaleCode;
118
+ }
119
+
120
+ return null;
121
+ }
122
+
123
+ /**
124
+ * Detect system locale from environment variables.
125
+ *
126
+ * Checks environment variables in priority order:
127
+ * 1. LC_ALL
128
+ * 2. LC_MESSAGES
129
+ * 3. LANG
130
+ * 4. VELLUM_LANGUAGE (custom override)
131
+ *
132
+ * On Windows, if no locale is found, returns DEFAULT_LOCALE as fallback.
133
+ *
134
+ * @returns Detection result with locale code and source
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * // On a system with LANG=zh_CN.UTF-8
139
+ * detectSystemLocale(); // { locale: "zh", source: "LANG" }
140
+ *
141
+ * // On Windows with no locale set
142
+ * detectSystemLocale(); // { locale: "en", source: null }
143
+ * ```
144
+ */
145
+ export function detectSystemLocale(): DetectedLocale {
146
+ // Check standard POSIX locale environment variables
147
+ for (const envVar of LOCALE_ENV_VARS) {
148
+ const value = process.env[envVar];
149
+ if (value) {
150
+ const parsed = parseLocaleString(value);
151
+ if (parsed) {
152
+ const locale = mapToSupportedLocale(parsed);
153
+ if (locale) {
154
+ return { locale, source: envVar };
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+ // Check custom VELLUM_LANGUAGE environment variable
161
+ const vellumLang = process.env.VELLUM_LANGUAGE;
162
+ if (vellumLang && isLocaleSupported(vellumLang)) {
163
+ return { locale: vellumLang as LocaleCode, source: "VELLUM_LANGUAGE" };
164
+ }
165
+
166
+ // Windows fallback: use default locale since LANG/LC_* are typically not set
167
+ if (process.platform === "win32") {
168
+ return { locale: DEFAULT_LOCALE, source: null };
169
+ }
170
+
171
+ // No locale detected
172
+ return { locale: null, source: null };
173
+ }