@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,246 @@
1
+ /**
2
+ * Status Command
3
+ *
4
+ * CLI command for displaying system status with various formats:
5
+ * - brief: Quick summary (default)
6
+ * - full: Detailed system information
7
+ * - json: Machine-readable JSON output
8
+ *
9
+ * Usage:
10
+ * - `/status` - Show brief status
11
+ * - `/status brief` - Show brief status
12
+ * - `/status full` - Show detailed status
13
+ * - `/status json` - Show JSON output
14
+ *
15
+ * @module cli/commands/status
16
+ */
17
+
18
+ import { existsSync } from "node:fs";
19
+ import { join, resolve } from "node:path";
20
+ import chalk from "chalk";
21
+
22
+ import { ICONS } from "../utils/icons.js";
23
+ import type { CommandContext, CommandResult, SlashCommand } from "./types.js";
24
+ import { error, success } from "./types.js";
25
+
26
+ // =============================================================================
27
+ // Types
28
+ // =============================================================================
29
+
30
+ /**
31
+ * Status format types
32
+ */
33
+ export type StatusFormat = "brief" | "full" | "json";
34
+
35
+ /**
36
+ * System status information
37
+ */
38
+ export interface SystemStatus {
39
+ /** Current working directory */
40
+ cwd: string;
41
+ /** Whether in a git repository */
42
+ isGitRepo: boolean;
43
+ /** Whether spec workflow exists */
44
+ hasSpec: boolean;
45
+ /** Spec workflow status (if exists) */
46
+ specStatus?: {
47
+ name: string;
48
+ currentPhase: string;
49
+ progress: {
50
+ completed: number;
51
+ total: number;
52
+ percentage: number;
53
+ };
54
+ };
55
+ /** Current mode (if available) */
56
+ currentMode?: string;
57
+ /** Session info (if available) */
58
+ session?: {
59
+ id: string;
60
+ startTime: string;
61
+ };
62
+ }
63
+
64
+ // =============================================================================
65
+ // Constants
66
+ // =============================================================================
67
+
68
+ const SPEC_DIR = ".ouroboros/specs";
69
+ const VALID_FORMATS: readonly StatusFormat[] = ["brief", "full", "json"] as const;
70
+
71
+ // =============================================================================
72
+ // Helpers
73
+ // =============================================================================
74
+
75
+ /**
76
+ * Check if a format string is valid
77
+ */
78
+ function isValidFormat(format: string): format is StatusFormat {
79
+ return VALID_FORMATS.includes(format as StatusFormat);
80
+ }
81
+
82
+ /**
83
+ * Get system status information
84
+ */
85
+ function getSystemStatus(): SystemStatus {
86
+ const cwd = process.cwd();
87
+ const isGitRepo = existsSync(join(cwd, ".git"));
88
+ const specDir = resolve(join(cwd, SPEC_DIR));
89
+ const hasSpec = existsSync(specDir);
90
+
91
+ const status: SystemStatus = {
92
+ cwd,
93
+ isGitRepo,
94
+ hasSpec,
95
+ };
96
+
97
+ return status;
98
+ }
99
+
100
+ /**
101
+ * Format brief status output
102
+ */
103
+ function formatBriefStatus(status: SystemStatus): string {
104
+ const lines: string[] = [];
105
+
106
+ lines.push(chalk.bold.blue("Status Summary"));
107
+ lines.push("");
108
+ lines.push(`${ICONS.cwd} ${chalk.dim("CWD:")} ${status.cwd}`);
109
+ lines.push(`${status.isGitRepo ? ICONS.success : ICONS.error} Git Repository`);
110
+ lines.push(`${status.hasSpec ? ICONS.success : ICONS.error} Spec Workflow`);
111
+
112
+ if (status.currentMode) {
113
+ lines.push(`Mode: ${status.currentMode}`);
114
+ }
115
+
116
+ return lines.join("\n");
117
+ }
118
+
119
+ /**
120
+ * Format full status output
121
+ */
122
+ function formatFullStatus(status: SystemStatus): string {
123
+ const lines: string[] = [];
124
+
125
+ lines.push(chalk.bold.blue("System Status (Full)"));
126
+ lines.push("");
127
+
128
+ // Environment
129
+ lines.push(chalk.bold("Environment:"));
130
+ lines.push(` ${ICONS.cwd} Working Directory: ${status.cwd}`);
131
+ lines.push(
132
+ ` ${ICONS.git} Git Repository: ${status.isGitRepo ? chalk.green("Yes") : chalk.yellow("No")}`
133
+ );
134
+ lines.push(
135
+ ` ${ICONS.mode.spec} Spec Workflow: ${status.hasSpec ? chalk.green("Yes") : chalk.yellow("No")}`
136
+ );
137
+ lines.push("");
138
+
139
+ // Spec details if exists
140
+ if (status.hasSpec && status.specStatus) {
141
+ lines.push(chalk.bold("Spec Workflow:"));
142
+ lines.push(` Name: ${status.specStatus.name}`);
143
+ lines.push(` Phase: ${status.specStatus.currentPhase}`);
144
+ lines.push(
145
+ ` Progress: ${status.specStatus.progress.completed}/${status.specStatus.progress.total} (${status.specStatus.progress.percentage}%)`
146
+ );
147
+ lines.push("");
148
+ }
149
+
150
+ // Session info if available
151
+ if (status.session) {
152
+ lines.push(chalk.bold("Session:"));
153
+ lines.push(` ID: ${status.session.id}`);
154
+ lines.push(` Started: ${status.session.startTime}`);
155
+ lines.push("");
156
+ }
157
+
158
+ // Mode info if available
159
+ if (status.currentMode) {
160
+ lines.push(chalk.bold("Mode:"));
161
+ lines.push(` Current: ${status.currentMode}`);
162
+ lines.push("");
163
+ }
164
+
165
+ return lines.join("\n");
166
+ }
167
+
168
+ /**
169
+ * Format JSON status output
170
+ */
171
+ function formatJsonStatus(status: SystemStatus): string {
172
+ return JSON.stringify(status, null, 2);
173
+ }
174
+
175
+ // =============================================================================
176
+ // Command Executor
177
+ // =============================================================================
178
+
179
+ /**
180
+ * Execute status command
181
+ */
182
+ export function executeStatus(format: StatusFormat = "brief"): CommandResult {
183
+ const status = getSystemStatus();
184
+
185
+ switch (format) {
186
+ case "brief":
187
+ return success(formatBriefStatus(status), { status });
188
+ case "full":
189
+ return success(formatFullStatus(status), { status });
190
+ case "json":
191
+ return success(formatJsonStatus(status), { status, format: "json" });
192
+ default:
193
+ return error("INVALID_ARGUMENT", `Invalid format: ${format}`);
194
+ }
195
+ }
196
+
197
+ // =============================================================================
198
+ // Slash Command Definition
199
+ // =============================================================================
200
+
201
+ /**
202
+ * /status slash command for TUI
203
+ *
204
+ * Displays system status in various formats.
205
+ */
206
+ export const statusCommand: SlashCommand = {
207
+ name: "status",
208
+ description: "Show system status",
209
+ kind: "builtin",
210
+ category: "system",
211
+ aliases: ["st"],
212
+ positionalArgs: [
213
+ {
214
+ name: "format",
215
+ type: "string",
216
+ description: "Output format: brief (default), full, json",
217
+ required: false,
218
+ default: "brief",
219
+ },
220
+ ],
221
+ examples: [
222
+ "/status - Show brief status summary",
223
+ "/status brief - Show brief status (default)",
224
+ "/status full - Show detailed system status",
225
+ "/status json - Show machine-readable JSON output",
226
+ ],
227
+ subcommands: [
228
+ { name: "brief", description: "Quick status summary (default)" },
229
+ { name: "full", description: "Detailed system status" },
230
+ { name: "json", description: "Machine-readable JSON output" },
231
+ ],
232
+
233
+ execute: async (ctx: CommandContext): Promise<CommandResult> => {
234
+ const formatArg = ctx.parsedArgs.positional[0] as string | undefined;
235
+ const format: StatusFormat = formatArg && isValidFormat(formatArg) ? formatArg : "brief";
236
+
237
+ // Validate format if provided
238
+ if (formatArg && !isValidFormat(formatArg)) {
239
+ return error("INVALID_ARGUMENT", `Invalid format: ${formatArg}`, [
240
+ `Valid formats: ${VALID_FORMATS.join(", ")}`,
241
+ ]);
242
+ }
243
+
244
+ return executeStatus(format);
245
+ },
246
+ };
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Theme Slash Commands
3
+ *
4
+ * Provides slash commands for theme management:
5
+ * - /theme - Show current theme and list available themes
6
+ * - /theme <name> - Switch to a specific theme
7
+ * - /theme dark - Switch to dark theme
8
+ * - /theme light - Switch to light theme
9
+ * - /theme dracula - Switch to dracula theme
10
+ * etc.
11
+ *
12
+ * @module cli/commands/theme
13
+ */
14
+
15
+ import type { ThemeContextValue } from "@vellum/shared";
16
+ import { getThemeNames, themes } from "@vellum/shared";
17
+ import type { CommandContext, CommandResult, SlashCommand } from "./types.js";
18
+ import { error, success } from "./types.js";
19
+
20
+ // =============================================================================
21
+ // Module State
22
+ // =============================================================================
23
+
24
+ /**
25
+ * Available theme names derived from the themes registry.
26
+ */
27
+ const availableThemes = getThemeNames();
28
+
29
+ /**
30
+ * Reference to ThemeContext setter.
31
+ * Set by the App component when initialized.
32
+ */
33
+ let themeContextValue: ThemeContextValue | null = null;
34
+
35
+ /**
36
+ * Set the ThemeContextValue instance for theme commands.
37
+ * Called by the App component during initialization.
38
+ *
39
+ * @param ctx - The ThemeContextValue instance to use, or null to clear
40
+ */
41
+ export function setThemeContext(ctx: ThemeContextValue | null): void {
42
+ themeContextValue = ctx;
43
+ }
44
+
45
+ /**
46
+ * Get the current ThemeContextValue instance.
47
+ * Returns null if not yet initialized.
48
+ */
49
+ export function getThemeContext(): ThemeContextValue | null {
50
+ return themeContextValue;
51
+ }
52
+
53
+ // =============================================================================
54
+ // Theme Description Helpers
55
+ // =============================================================================
56
+
57
+ /**
58
+ * Get icon indicator for a theme mode.
59
+ */
60
+ function getThemeModeIcon(mode: "dark" | "light"): string {
61
+ return mode === "dark" ? "●" : "○";
62
+ }
63
+
64
+ /**
65
+ * Format theme information for display.
66
+ */
67
+ function formatThemeInfo(name: string, isCurrent: boolean): string {
68
+ const theme = themes[name as keyof typeof themes];
69
+ if (!theme) return ` ? ${name}`;
70
+ const icon = getThemeModeIcon(theme.mode);
71
+ const marker = isCurrent ? " <- current" : "";
72
+ return ` ${icon} ${name} (${theme.mode})${marker}`;
73
+ }
74
+
75
+ // =============================================================================
76
+ // /theme Command - Show Current Theme and Options
77
+ // =============================================================================
78
+
79
+ /**
80
+ * /theme command - Display current theme and switch to a specific theme.
81
+ *
82
+ * Without arguments, shows the current theme and lists all available themes.
83
+ * With a theme name argument, switches to that theme.
84
+ */
85
+ export const themeCommand: SlashCommand = {
86
+ name: "theme",
87
+ description: "Show current theme or switch themes",
88
+ kind: "builtin",
89
+ category: "config",
90
+ aliases: ["themes"],
91
+ positionalArgs: [
92
+ {
93
+ name: "name",
94
+ type: "string",
95
+ description: "Theme name to switch to",
96
+ required: false,
97
+ },
98
+ ],
99
+ examples: [
100
+ "/theme - Show current theme and options",
101
+ "/theme dark - Switch to dark theme",
102
+ "/theme light - Switch to light theme",
103
+ "/theme dracula - Switch to Dracula theme",
104
+ ],
105
+ subcommands: availableThemes.map((t) => ({
106
+ name: t,
107
+ description: `Apply ${t} theme`,
108
+ })),
109
+
110
+ execute: async (ctx: CommandContext): Promise<CommandResult> => {
111
+ const requestedTheme = ctx.parsedArgs.positional[0] as string | undefined;
112
+
113
+ // If a theme is specified, switch to it
114
+ if (requestedTheme) {
115
+ return switchToTheme(requestedTheme);
116
+ }
117
+
118
+ // Show current theme and list options
119
+ if (!themeContextValue) {
120
+ // No context available - show static info
121
+ const themeList = availableThemes
122
+ .map((name) => formatThemeInfo(name, name === "dark"))
123
+ .join("\n");
124
+
125
+ const lines = [
126
+ "=== Themes ===",
127
+ "",
128
+ "Available themes:",
129
+ themeList,
130
+ "",
131
+ "Theme system not yet initialized. Using default: dark",
132
+ "",
133
+ "Usage: /theme <name>",
134
+ ];
135
+ return success(lines.join("\n"));
136
+ }
137
+
138
+ const current = themeContextValue.themeName;
139
+ const themeList = availableThemes
140
+ .map((name: string) => formatThemeInfo(name, name === current))
141
+ .join("\n");
142
+
143
+ const lines = [
144
+ "=== Themes ===",
145
+ "",
146
+ `Current theme: ${getThemeModeIcon(themes[current as keyof typeof themes]?.mode ?? "dark")} ${current}`,
147
+ "",
148
+ "Available themes:",
149
+ themeList,
150
+ "",
151
+ "Usage: /theme <name>",
152
+ ];
153
+
154
+ return success(lines.join("\n"));
155
+ },
156
+ };
157
+
158
+ // =============================================================================
159
+ // Theme Switch Helper
160
+ // =============================================================================
161
+
162
+ /**
163
+ * Switch to a specified theme with validation.
164
+ *
165
+ * @param themeName - Theme name to switch to
166
+ * @returns Command result
167
+ */
168
+ function switchToTheme(themeName: string): CommandResult {
169
+ const normalizedName = themeName.toLowerCase();
170
+
171
+ // Validate theme name
172
+ if (!availableThemes.includes(normalizedName as (typeof availableThemes)[number])) {
173
+ return error("INVALID_ARGUMENT", `Unknown theme: "${themeName}"`, [
174
+ `Available themes: ${availableThemes.join(", ")}`,
175
+ ]);
176
+ }
177
+
178
+ const themeObj = themes[normalizedName as keyof typeof themes];
179
+
180
+ // If no context, return informative message
181
+ if (!themeContextValue) {
182
+ return success(
183
+ `Theme system not initialized. Would switch to ${getThemeModeIcon(themeObj?.mode ?? "dark")} ${normalizedName}.`
184
+ );
185
+ }
186
+
187
+ // Check if already using this theme
188
+ if (themeContextValue.themeName === normalizedName) {
189
+ return success(
190
+ `Already using ${getThemeModeIcon(themeObj?.mode ?? "dark")} ${normalizedName} theme.`
191
+ );
192
+ }
193
+
194
+ // Execute the switch - pass the theme object directly
195
+ themeContextValue.setTheme(themeObj);
196
+ return success(
197
+ `${getThemeModeIcon(themeObj?.mode ?? "dark")} Switched to ${normalizedName} theme.`
198
+ );
199
+ }
200
+
201
+ // =============================================================================
202
+ // Export Theme Command
203
+ // =============================================================================
204
+
205
+ /**
206
+ * All theme-related slash commands for registration.
207
+ *
208
+ * Note: Theme shortcuts (e.g., /dark, /light) have been removed.
209
+ * Use /theme <name> for theme switching with subcommand autocomplete.
210
+ */
211
+ export const themeSlashCommands: SlashCommand[] = [themeCommand];