@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,134 @@
1
+ /**
2
+ * Sandbox Configuration Defaults
3
+ *
4
+ * Centralized configuration constants for sandbox execution.
5
+ * All values can be overridden via function parameters or environment variables.
6
+ *
7
+ * @module cli/tui/config/defaults
8
+ */
9
+
10
+ // =============================================================================
11
+ // Environment Variable Helpers
12
+ // =============================================================================
13
+
14
+ /**
15
+ * Parse numeric environment variable with fallback.
16
+ */
17
+ function parseEnvNumber(key: string, fallback: number): number {
18
+ const value = process.env[key];
19
+ if (value === undefined) return fallback;
20
+ const parsed = Number.parseInt(value, 10);
21
+ return Number.isNaN(parsed) ? fallback : parsed;
22
+ }
23
+
24
+ /**
25
+ * Parse boolean environment variable with fallback.
26
+ */
27
+ function parseEnvBoolean(key: string, fallback: boolean): boolean {
28
+ const value = process.env[key];
29
+ if (value === undefined) return fallback;
30
+ return value === "true" || value === "1";
31
+ }
32
+
33
+ // =============================================================================
34
+ // Size Constants (in bytes)
35
+ // =============================================================================
36
+
37
+ /** 1 Megabyte in bytes */
38
+ const MB = 1024 * 1024;
39
+
40
+ // =============================================================================
41
+ // Sandbox Resource Defaults
42
+ // =============================================================================
43
+
44
+ /**
45
+ * Default sandbox resource limits.
46
+ */
47
+ export const SANDBOX_RESOURCES = {
48
+ /** Default execution timeout in milliseconds (30s) */
49
+ TIMEOUT_MS: parseEnvNumber("VELLUM_SANDBOX_TIMEOUT_MS", 30_000),
50
+
51
+ /** Additional wall time buffer beyond CPU timeout (5s) */
52
+ WALL_TIME_BUFFER_MS: parseEnvNumber("VELLUM_SANDBOX_WALL_TIME_BUFFER_MS", 5_000),
53
+
54
+ /** Maximum memory limit in bytes (512MB) */
55
+ MEMORY_BYTES: parseEnvNumber("VELLUM_SANDBOX_MEMORY_BYTES", 512 * MB),
56
+
57
+ /** Maximum output size in bytes (1MB) */
58
+ MAX_OUTPUT_BYTES: parseEnvNumber("VELLUM_SANDBOX_MAX_OUTPUT_BYTES", 1 * MB),
59
+
60
+ /** Maximum single file size in bytes (50MB) */
61
+ MAX_FILE_SIZE_BYTES: parseEnvNumber("VELLUM_SANDBOX_MAX_FILE_SIZE_BYTES", 50 * MB),
62
+
63
+ /** Maximum disk usage in bytes (100MB) */
64
+ MAX_DISK_USAGE_BYTES: parseEnvNumber("VELLUM_SANDBOX_MAX_DISK_USAGE_BYTES", 100 * MB),
65
+
66
+ /** Maximum number of file descriptors */
67
+ MAX_FILE_DESCRIPTORS: parseEnvNumber("VELLUM_SANDBOX_MAX_FILE_DESCRIPTORS", 100),
68
+
69
+ /** Maximum number of spawned processes */
70
+ MAX_PROCESSES: parseEnvNumber("VELLUM_SANDBOX_MAX_PROCESSES", 10),
71
+ } as const;
72
+
73
+ /**
74
+ * Default sandbox permission settings.
75
+ */
76
+ export const SANDBOX_PERMISSIONS = {
77
+ /** Allow network access by default */
78
+ ALLOW_NETWORK: parseEnvBoolean("VELLUM_SANDBOX_ALLOW_NETWORK", false),
79
+
80
+ /** Allow file system access by default */
81
+ ALLOW_FILE_SYSTEM: parseEnvBoolean("VELLUM_SANDBOX_ALLOW_FILE_SYSTEM", true),
82
+
83
+ /** Use overlay filesystem */
84
+ USE_OVERLAY: parseEnvBoolean("VELLUM_SANDBOX_USE_OVERLAY", false),
85
+
86
+ /** Enable audit logging */
87
+ ENABLE_AUDIT: parseEnvBoolean("VELLUM_SANDBOX_ENABLE_AUDIT", false),
88
+ } as const;
89
+
90
+ /**
91
+ * Default security paths to deny access.
92
+ * These paths are blocked for security reasons.
93
+ */
94
+ export const SANDBOX_DENIED_PATHS = ["/etc/passwd", "/etc/shadow"] as const;
95
+
96
+ // =============================================================================
97
+ // Aggregated Defaults
98
+ // =============================================================================
99
+
100
+ /**
101
+ * Complete sandbox defaults configuration.
102
+ * Import and spread to apply all defaults with optional overrides.
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * import { SANDBOX_DEFAULTS } from './config/defaults';
107
+ *
108
+ * const config = {
109
+ * ...SANDBOX_DEFAULTS.resources,
110
+ * timeoutMs: 60_000, // Override timeout
111
+ * };
112
+ * ```
113
+ */
114
+ export const SANDBOX_DEFAULTS = {
115
+ /** Resource limits */
116
+ resources: SANDBOX_RESOURCES,
117
+ /** Permission settings */
118
+ permissions: SANDBOX_PERMISSIONS,
119
+ /** Denied filesystem paths */
120
+ deniedPaths: SANDBOX_DENIED_PATHS,
121
+ } as const;
122
+
123
+ // =============================================================================
124
+ // Type Exports
125
+ // =============================================================================
126
+
127
+ /** Type for sandbox resource configuration */
128
+ export type SandboxResourceConfig = typeof SANDBOX_RESOURCES;
129
+
130
+ /** Type for sandbox permission configuration */
131
+ export type SandboxPermissionConfig = typeof SANDBOX_PERMISSIONS;
132
+
133
+ /** Type for complete sandbox defaults */
134
+ export type SandboxDefaultsConfig = typeof SANDBOX_DEFAULTS;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * TUI Configuration Module
3
+ *
4
+ * Re-exports all configuration constants and types.
5
+ *
6
+ * @module cli/tui/config
7
+ */
8
+
9
+ export {
10
+ SANDBOX_DEFAULTS,
11
+ SANDBOX_DENIED_PATHS,
12
+ SANDBOX_PERMISSIONS,
13
+ SANDBOX_RESOURCES,
14
+ type SandboxDefaultsConfig,
15
+ type SandboxPermissionConfig,
16
+ type SandboxResourceConfig,
17
+ } from "./defaults.js";
@@ -0,0 +1,284 @@
1
+ /**
2
+ * Animation Context
3
+ *
4
+ * Global animation context that provides:
5
+ * 1. A centralized animation frame counter
6
+ * 2. FPS limiting to prevent excessive re-renders (60 FPS max)
7
+ * 3. VS Code terminal detection for adaptive timing
8
+ *
9
+ * All animated components should subscribe to this instead of individual timers
10
+ * to reduce flickering and improve performance.
11
+ *
12
+ * @module tui/context/AnimationContext
13
+ */
14
+
15
+ import type React from "react";
16
+ import type { ReactNode } from "react";
17
+ import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
18
+
19
+ // =============================================================================
20
+ // Constants
21
+ // =============================================================================
22
+
23
+ /** Minimum frame interval (~60 FPS) to prevent excessive re-renders */
24
+ const MIN_FRAME_INTERVAL_MS = 16;
25
+
26
+ /** Base animation tick interval */
27
+ const BASE_ANIMATION_TICK_MS = 120;
28
+
29
+ /** Extended animation tick for VS Code terminal (more conservative) */
30
+ const VSCODE_ANIMATION_TICK_MS = 200;
31
+
32
+ // =============================================================================
33
+ // Environment Detection
34
+ // =============================================================================
35
+
36
+ /**
37
+ * Detects if running inside VS Code integrated terminal.
38
+ * VS Code terminals benefit from slightly longer intervals to reduce flickering.
39
+ */
40
+ function isVSCodeTerminal(): boolean {
41
+ return (
42
+ process.env.TERM_PROGRAM === "vscode" ||
43
+ process.env.VSCODE_INJECTION === "1" ||
44
+ !!process.env.VSCODE_GIT_IPC_HANDLE
45
+ );
46
+ }
47
+
48
+ /**
49
+ * Gets the optimal animation tick interval based on terminal environment.
50
+ * VS Code terminals use a longer interval to reduce flickering.
51
+ */
52
+ function getAnimationTick(): number {
53
+ // Allow environment override for debugging
54
+ const envTick = Number(process.env.VELLUM_ANIMATION_TICK);
55
+ if (Number.isFinite(envTick) && envTick > 0) {
56
+ return envTick;
57
+ }
58
+
59
+ return isVSCodeTerminal() ? VSCODE_ANIMATION_TICK_MS : BASE_ANIMATION_TICK_MS;
60
+ }
61
+
62
+ // =============================================================================
63
+ // Types
64
+ // =============================================================================
65
+
66
+ /**
67
+ * Animation context state
68
+ */
69
+ export interface AnimationState {
70
+ /** Current animation frame counter (monotonically increasing) */
71
+ readonly frame: number;
72
+ /** Current timestamp in milliseconds */
73
+ readonly timestamp: number;
74
+ }
75
+
76
+ /**
77
+ * Animation context value
78
+ */
79
+ export interface AnimationContextValue extends AnimationState {
80
+ /** Whether running in VS Code terminal */
81
+ readonly isVSCode: boolean;
82
+ /** Current animation tick interval in ms */
83
+ readonly tickInterval: number;
84
+ /** Whether animations are currently paused */
85
+ readonly isPaused: boolean;
86
+ /** Pause all animations (useful during text input to reduce flickering) */
87
+ readonly pauseAnimations: () => void;
88
+ /** Resume animations after pausing */
89
+ readonly resumeAnimations: () => void;
90
+ }
91
+
92
+ /**
93
+ * Props for the AnimationProvider component
94
+ */
95
+ export interface AnimationProviderProps {
96
+ /** Children to render */
97
+ readonly children: ReactNode;
98
+ /** Override the animation tick interval (for testing) */
99
+ readonly tickInterval?: number;
100
+ }
101
+
102
+ // =============================================================================
103
+ // Context
104
+ // =============================================================================
105
+
106
+ const initialState: AnimationContextValue = {
107
+ frame: 0,
108
+ timestamp: Date.now(),
109
+ isVSCode: isVSCodeTerminal(),
110
+ tickInterval: getAnimationTick(),
111
+ isPaused: false,
112
+ pauseAnimations: () => {},
113
+ resumeAnimations: () => {},
114
+ };
115
+
116
+ /**
117
+ * Animation context - provides global animation frame and timing
118
+ */
119
+ export const AnimationContext = createContext<AnimationContextValue>(initialState);
120
+
121
+ // =============================================================================
122
+ // Provider Component
123
+ // =============================================================================
124
+
125
+ /**
126
+ * Animation provider that manages a global animation loop.
127
+ *
128
+ * Features:
129
+ * - Single timer for all animated components
130
+ * - FPS limiting to prevent excessive renders
131
+ * - VS Code terminal detection for adaptive timing
132
+ * - Environment variable override for debugging
133
+ *
134
+ * @example
135
+ * ```tsx
136
+ * // In root provider
137
+ * <AnimationProvider>
138
+ * <App />
139
+ * </AnimationProvider>
140
+ *
141
+ * // Override tick for testing
142
+ * <AnimationProvider tickInterval={200}>
143
+ * <SlowAnimatedComponent />
144
+ * </AnimationProvider>
145
+ * ```
146
+ */
147
+ export function AnimationProvider({
148
+ children,
149
+ tickInterval: tickOverride,
150
+ }: AnimationProviderProps): React.JSX.Element {
151
+ const tickInterval = tickOverride ?? getAnimationTick();
152
+ const isVSCode = isVSCodeTerminal();
153
+
154
+ const [state, setState] = useState<AnimationState>({
155
+ frame: 0,
156
+ timestamp: Date.now(),
157
+ });
158
+
159
+ const [isPaused, setIsPaused] = useState(false);
160
+ const isPausedRef = useRef(false);
161
+ const lastRenderRef = useRef(Date.now());
162
+
163
+ // Stable pause/resume callbacks
164
+ const pauseAnimations = useCallback(() => {
165
+ isPausedRef.current = true;
166
+ setIsPaused(true);
167
+ }, []);
168
+
169
+ const resumeAnimations = useCallback(() => {
170
+ isPausedRef.current = false;
171
+ setIsPaused(false);
172
+ }, []);
173
+
174
+ useEffect(() => {
175
+ // Don't start timer when paused - completely stops animation overhead
176
+ if (isPaused) return;
177
+
178
+ let mounted = true;
179
+
180
+ const tick = () => {
181
+ if (!mounted) return;
182
+
183
+ const now = Date.now();
184
+ const sinceLastRender = now - lastRenderRef.current;
185
+
186
+ // FPS limiter: ensure minimum interval since last render
187
+ if (sinceLastRender >= MIN_FRAME_INTERVAL_MS) {
188
+ lastRenderRef.current = now;
189
+ setState((prev) => ({
190
+ frame: prev.frame + 1,
191
+ timestamp: now,
192
+ }));
193
+ }
194
+ };
195
+
196
+ // Use setInterval for consistent timing in terminal environments
197
+ // requestAnimationFrame is designed for visual rendering, not terminal output
198
+ const timer = setInterval(tick, tickInterval);
199
+
200
+ return () => {
201
+ mounted = false;
202
+ clearInterval(timer);
203
+ };
204
+ }, [tickInterval, isPaused]);
205
+
206
+ const contextValue: AnimationContextValue = {
207
+ ...state,
208
+ isVSCode,
209
+ tickInterval,
210
+ isPaused,
211
+ pauseAnimations,
212
+ resumeAnimations,
213
+ };
214
+
215
+ return <AnimationContext.Provider value={contextValue}>{children}</AnimationContext.Provider>;
216
+ }
217
+
218
+ // =============================================================================
219
+ // Hooks
220
+ // =============================================================================
221
+
222
+ /**
223
+ * Hook to access the full animation context.
224
+ *
225
+ * Returns safe defaults if context is not available (e.g., when rendered
226
+ * outside AnimationProvider). This prevents "Rendered more hooks than
227
+ * during the previous render" errors.
228
+ *
229
+ * @returns Animation context value with frame, timestamp, and metadata
230
+ *
231
+ * @example
232
+ * ```tsx
233
+ * function AnimatedComponent() {
234
+ * const { frame, timestamp, isVSCode } = useAnimation();
235
+ * // Use frame/timestamp for animations
236
+ * }
237
+ * ```
238
+ */
239
+ export function useAnimation(): AnimationContextValue {
240
+ const context = useContext(AnimationContext);
241
+ // Return safe defaults if context is not available
242
+ // This prevents hook count errors when rendered outside AnimationProvider
243
+ if (!context) {
244
+ return initialState;
245
+ }
246
+ return context;
247
+ }
248
+
249
+ /**
250
+ * Hook to get the current animation frame index for a set of frames.
251
+ *
252
+ * This is the recommended way to animate through a sequence of frames
253
+ * (like spinner characters) without managing your own state or timer.
254
+ *
255
+ * @param frames - Array of frames or number of total frames
256
+ * @returns Current frame index (0 to frames.length-1 or 0 to frames-1)
257
+ *
258
+ * @example
259
+ * ```tsx
260
+ * // With array of frames
261
+ * const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
262
+ * function Spinner() {
263
+ * const frameIndex = useAnimationFrame(SPINNER_FRAMES);
264
+ * return <Text>{SPINNER_FRAMES[frameIndex]}</Text>;
265
+ * }
266
+ *
267
+ * // With frame count
268
+ * function FourPhaseAnimation() {
269
+ * const phase = useAnimationFrame(4);
270
+ * return <Text>Phase {phase + 1}</Text>;
271
+ * }
272
+ * ```
273
+ */
274
+ export function useAnimationFrame(frames: readonly unknown[] | number): number {
275
+ const { frame } = useAnimation();
276
+ const frameCount = typeof frames === "number" ? frames : frames.length;
277
+ return frameCount > 0 ? frame % frameCount : 0;
278
+ }
279
+
280
+ // =============================================================================
281
+ // Exports
282
+ // =============================================================================
283
+
284
+ export default AnimationProvider;