@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,341 @@
1
+ /**
2
+ * Memory Export Command
3
+ *
4
+ * Export project memories to a file in JSON or Markdown format.
5
+ *
6
+ * @module cli/commands/memory/export
7
+ */
8
+
9
+ import { writeFile } from "node:fs/promises";
10
+ import { resolve } from "node:path";
11
+
12
+ import type { MemoryEntry, MemoryEntryType } from "@vellum/core";
13
+ import chalk from "chalk";
14
+
15
+ import type { CommandContext, CommandResult, SlashCommand } from "../types.js";
16
+ import { error, success } from "../types.js";
17
+ import { withMemoryService } from "./utils.js";
18
+
19
+ // =============================================================================
20
+ // Types
21
+ // =============================================================================
22
+
23
+ /**
24
+ * Export format options.
25
+ */
26
+ export type MemoryExportFormat = "json" | "markdown";
27
+
28
+ /**
29
+ * Options for the memory export command.
30
+ */
31
+ export interface MemoryExportOptions {
32
+ /** Output file path */
33
+ output?: string;
34
+ /** Export format */
35
+ format?: MemoryExportFormat;
36
+ /** Filter by type */
37
+ type?: MemoryEntryType;
38
+ /** Include metadata in export */
39
+ includeMetadata?: boolean;
40
+ }
41
+
42
+ /**
43
+ * JSON export structure.
44
+ */
45
+ interface MemoryExportJson {
46
+ version: 1;
47
+ exportedAt: string;
48
+ projectPath: string;
49
+ entries: Array<{
50
+ key: string;
51
+ type: MemoryEntryType;
52
+ content: string;
53
+ createdAt: string;
54
+ updatedAt: string;
55
+ metadata?: {
56
+ tags: string[];
57
+ importance: number;
58
+ sessionId?: string;
59
+ };
60
+ }>;
61
+ stats: {
62
+ total: number;
63
+ byType: Record<MemoryEntryType, number>;
64
+ };
65
+ }
66
+
67
+ // =============================================================================
68
+ // Export Functions
69
+ // =============================================================================
70
+
71
+ /**
72
+ * Generate default filename based on format.
73
+ */
74
+ function getDefaultFilename(format: MemoryExportFormat): string {
75
+ const timestamp = new Date().toISOString().slice(0, 10);
76
+ const ext = format === "json" ? "json" : "md";
77
+ return `vellum-memory-${timestamp}.${ext}`;
78
+ }
79
+
80
+ /**
81
+ * Calculate type statistics.
82
+ */
83
+ function calculateStats(entries: MemoryEntry[]): Record<MemoryEntryType, number> {
84
+ const stats: Record<MemoryEntryType, number> = {
85
+ context: 0,
86
+ preference: 0,
87
+ decision: 0,
88
+ summary: 0,
89
+ };
90
+
91
+ for (const entry of entries) {
92
+ stats[entry.type] += 1;
93
+ }
94
+
95
+ return stats;
96
+ }
97
+
98
+ /**
99
+ * Export entries to JSON format.
100
+ */
101
+ function exportToJson(
102
+ entries: MemoryEntry[],
103
+ projectPath: string,
104
+ includeMetadata: boolean
105
+ ): string {
106
+ const exportData: MemoryExportJson = {
107
+ version: 1,
108
+ exportedAt: new Date().toISOString(),
109
+ projectPath,
110
+ entries: entries.map((e) => ({
111
+ key: e.key,
112
+ type: e.type,
113
+ content: e.content,
114
+ createdAt: e.createdAt.toISOString(),
115
+ updatedAt: e.updatedAt.toISOString(),
116
+ ...(includeMetadata
117
+ ? {
118
+ metadata: {
119
+ tags: e.metadata.tags,
120
+ importance: e.metadata.importance,
121
+ sessionId: e.metadata.sessionId,
122
+ },
123
+ }
124
+ : {}),
125
+ })),
126
+ stats: {
127
+ total: entries.length,
128
+ byType: calculateStats(entries),
129
+ },
130
+ };
131
+
132
+ return JSON.stringify(exportData, null, 2);
133
+ }
134
+
135
+ /**
136
+ * Format date for markdown.
137
+ */
138
+ function formatDateLong(date: Date): string {
139
+ return date.toISOString().slice(0, 19).replace("T", " ");
140
+ }
141
+
142
+ /**
143
+ * Get emoji for entry type.
144
+ */
145
+ function getTypeEmoji(type: MemoryEntryType): string {
146
+ const emojis: Record<MemoryEntryType, string> = {
147
+ context: "📋",
148
+ preference: "⚙️",
149
+ decision: "🎯",
150
+ summary: "📝",
151
+ };
152
+ return emojis[type];
153
+ }
154
+
155
+ /**
156
+ * Export entries to Markdown format.
157
+ */
158
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Markdown export requires handling multiple content sections and formatting options
159
+ function exportToMarkdown(
160
+ entries: MemoryEntry[],
161
+ projectPath: string,
162
+ includeMetadata: boolean
163
+ ): string {
164
+ const lines: string[] = [
165
+ "# Vellum Project Memory Export",
166
+ "",
167
+ `> Exported: ${formatDateLong(new Date())}`,
168
+ `> Project: \`${projectPath}\``,
169
+ `> Total entries: ${entries.length}`,
170
+ "",
171
+ ];
172
+
173
+ // Add statistics
174
+ const stats = calculateStats(entries);
175
+ lines.push("## Statistics", "");
176
+ lines.push("| Type | Count |");
177
+ lines.push("|------|-------|");
178
+ for (const [type, count] of Object.entries(stats)) {
179
+ if (count > 0) {
180
+ lines.push(`| ${type} | ${count} |`);
181
+ }
182
+ }
183
+ lines.push("");
184
+
185
+ // Group entries by type
186
+ const grouped = new Map<MemoryEntryType, MemoryEntry[]>();
187
+ for (const entry of entries) {
188
+ const list = grouped.get(entry.type) ?? [];
189
+ list.push(entry);
190
+ grouped.set(entry.type, list);
191
+ }
192
+
193
+ // Export each type section
194
+ const typeOrder: MemoryEntryType[] = ["context", "preference", "decision", "summary"];
195
+ for (const type of typeOrder) {
196
+ const typeEntries = grouped.get(type);
197
+ if (!typeEntries || typeEntries.length === 0) continue;
198
+
199
+ const emoji = getTypeEmoji(type);
200
+ lines.push(`## ${emoji} ${type.charAt(0).toUpperCase() + type.slice(1)}`, "");
201
+
202
+ for (const entry of typeEntries) {
203
+ lines.push(`### ${entry.key}`, "");
204
+ lines.push(entry.content, "");
205
+
206
+ if (includeMetadata) {
207
+ lines.push("<details>");
208
+ lines.push("<summary>Metadata</summary>", "");
209
+ lines.push(`- **Created**: ${formatDateLong(entry.createdAt)}`);
210
+ lines.push(`- **Updated**: ${formatDateLong(entry.updatedAt)}`);
211
+ lines.push(`- **Importance**: ${entry.metadata.importance}`);
212
+ if (entry.metadata.tags.length > 0) {
213
+ lines.push(`- **Tags**: ${entry.metadata.tags.join(", ")}`);
214
+ }
215
+ if (entry.metadata.sessionId) {
216
+ lines.push(`- **Session**: ${entry.metadata.sessionId}`);
217
+ }
218
+ lines.push("</details>", "");
219
+ }
220
+ }
221
+ }
222
+
223
+ lines.push("---", "");
224
+ lines.push("*Exported by Vellum CLI*");
225
+
226
+ return lines.join("\n");
227
+ }
228
+
229
+ // =============================================================================
230
+ // Command Execution
231
+ // =============================================================================
232
+
233
+ /**
234
+ * Execute the memory export command.
235
+ */
236
+ export async function executeMemoryExport(
237
+ projectPath: string,
238
+ options: MemoryExportOptions = {}
239
+ ): Promise<CommandResult> {
240
+ const format = options.format ?? "json";
241
+ const includeMetadata = options.includeMetadata ?? true;
242
+ const outputPath = options.output
243
+ ? resolve(projectPath, options.output)
244
+ : resolve(projectPath, getDefaultFilename(format));
245
+
246
+ try {
247
+ return await withMemoryService(projectPath, async (service) => {
248
+ let entries = await service.listEntries(options.type);
249
+
250
+ // Sort by type then by key for consistent output
251
+ entries = entries.sort((a, b) => {
252
+ if (a.type !== b.type) {
253
+ return a.type.localeCompare(b.type);
254
+ }
255
+ return a.key.localeCompare(b.key);
256
+ });
257
+
258
+ if (entries.length === 0) {
259
+ return success(chalk.dim("No memories to export."));
260
+ }
261
+
262
+ const content =
263
+ format === "json"
264
+ ? exportToJson(entries, projectPath, includeMetadata)
265
+ : exportToMarkdown(entries, projectPath, includeMetadata);
266
+
267
+ await writeFile(outputPath, content, "utf-8");
268
+
269
+ const lines: string[] = [
270
+ chalk.bold.green("✅ Memory export complete"),
271
+ "",
272
+ chalk.dim(`Format: ${format}`),
273
+ chalk.dim(`Entries: ${entries.length}`),
274
+ chalk.dim(`Output: ${outputPath}`),
275
+ ];
276
+
277
+ return success(lines.join("\n"));
278
+ });
279
+ } catch (err) {
280
+ const message = err instanceof Error ? err.message : String(err);
281
+ return error("INTERNAL_ERROR", `Failed to export memories: ${message}`);
282
+ }
283
+ }
284
+
285
+ // =============================================================================
286
+ // Slash Command Definition
287
+ // =============================================================================
288
+
289
+ /**
290
+ * Parse export command arguments.
291
+ */
292
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Argument parsing requires handling many flag combinations
293
+ function parseExportArgs(args: string[]): MemoryExportOptions {
294
+ const options: MemoryExportOptions = {};
295
+
296
+ for (let i = 0; i < args.length; i++) {
297
+ const arg = args[i];
298
+ const nextArg = args[i + 1];
299
+
300
+ if ((arg === "--output" || arg === "-o") && nextArg) {
301
+ options.output = nextArg;
302
+ i++;
303
+ } else if ((arg === "--format" || arg === "-f") && nextArg) {
304
+ if (nextArg === "json" || nextArg === "markdown" || nextArg === "md") {
305
+ options.format = nextArg === "md" ? "markdown" : nextArg;
306
+ }
307
+ i++;
308
+ } else if (arg === "--type" && nextArg) {
309
+ if (["context", "preference", "decision", "summary"].includes(nextArg)) {
310
+ options.type = nextArg as MemoryEntryType;
311
+ }
312
+ i++;
313
+ } else if (arg === "--no-metadata") {
314
+ options.includeMetadata = false;
315
+ }
316
+ }
317
+
318
+ return options;
319
+ }
320
+
321
+ /**
322
+ * Memory export slash command handler.
323
+ */
324
+ async function handleMemoryExport(context: CommandContext): Promise<CommandResult> {
325
+ const args = context.parsedArgs.positional as string[];
326
+ const options = parseExportArgs(args);
327
+ const projectPath = context.session.cwd;
328
+
329
+ return executeMemoryExport(projectPath, options);
330
+ }
331
+
332
+ /**
333
+ * Memory export slash command definition.
334
+ */
335
+ export const memoryExportCommand: SlashCommand = {
336
+ name: "memory export",
337
+ description: "Export project memories to a file",
338
+ kind: "builtin",
339
+ category: "session",
340
+ execute: handleMemoryExport,
341
+ };
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Memory Commands Index
3
+ *
4
+ * Re-exports all memory-related CLI commands and provides
5
+ * the main memory command dispatcher.
6
+ *
7
+ * @module cli/commands/memory
8
+ */
9
+
10
+ import chalk from "chalk";
11
+
12
+ import type { CommandContext, CommandResult, SlashCommand } from "../types.js";
13
+ import { error, success } from "../types.js";
14
+
15
+ // =============================================================================
16
+ // Command Exports
17
+ // =============================================================================
18
+
19
+ export {
20
+ executeMemoryExport,
21
+ type MemoryExportFormat,
22
+ type MemoryExportOptions,
23
+ memoryExportCommand,
24
+ } from "./export.js";
25
+
26
+ export {
27
+ executeMemoryList,
28
+ type MemoryListOptions,
29
+ memoryListCommand,
30
+ } from "./list.js";
31
+
32
+ export {
33
+ executeMemorySearch,
34
+ type MemorySearchOptions,
35
+ memorySearchCommand,
36
+ } from "./search.js";
37
+
38
+ export { withMemoryService } from "./utils.js";
39
+
40
+ // =============================================================================
41
+ // Subcommands Registry
42
+ // =============================================================================
43
+
44
+ import { memoryExportCommand } from "./export.js";
45
+ import { memoryListCommand } from "./list.js";
46
+ import { memorySearchCommand } from "./search.js";
47
+
48
+ /**
49
+ * All memory subcommands.
50
+ */
51
+ export const memorySubcommands: SlashCommand[] = [
52
+ memoryListCommand,
53
+ memorySearchCommand,
54
+ memoryExportCommand,
55
+ ];
56
+
57
+ // =============================================================================
58
+ // Memory Command Dispatcher
59
+ // =============================================================================
60
+
61
+ /**
62
+ * Get help text for memory commands.
63
+ */
64
+ function getMemoryHelp(): string {
65
+ const lines: string[] = [
66
+ chalk.bold.blue("📚 Memory Commands"),
67
+ "",
68
+ chalk.dim("Manage project memory - persistent context across sessions."),
69
+ "",
70
+ chalk.bold("Available subcommands:"),
71
+ "",
72
+ ` ${chalk.cyan("/memory list")} List all saved memories`,
73
+ ` ${chalk.cyan("/memory search")} Search memories by query`,
74
+ ` ${chalk.cyan("/memory export")} Export memories to file`,
75
+ "",
76
+ chalk.bold("Examples:"),
77
+ "",
78
+ chalk.dim(" /memory list --limit 10"),
79
+ chalk.dim(" /memory list --type preference --json"),
80
+ chalk.dim(" /memory search authentication"),
81
+ chalk.dim(" /memory export --format markdown"),
82
+ "",
83
+ chalk.dim("Use /memory <subcommand> --help for detailed usage."),
84
+ ];
85
+
86
+ return lines.join("\n");
87
+ }
88
+
89
+ /**
90
+ * Memory command dispatcher.
91
+ * Routes to the appropriate subcommand based on the first argument.
92
+ */
93
+ async function handleMemory(context: CommandContext): Promise<CommandResult> {
94
+ const args = context.parsedArgs.positional as string[];
95
+ const subcommand = args[0]?.toLowerCase();
96
+
97
+ // Show help if no subcommand
98
+ if (!subcommand || subcommand === "help" || subcommand === "--help") {
99
+ return success(getMemoryHelp());
100
+ }
101
+
102
+ // Route to subcommand - subcommands are invoked via main command handler
103
+ // Since they use the same context, just call execute directly
104
+ switch (subcommand) {
105
+ case "list":
106
+ case "ls":
107
+ return memoryListCommand.execute(context);
108
+
109
+ case "search":
110
+ case "find":
111
+ return memorySearchCommand.execute(context);
112
+
113
+ case "export":
114
+ return memoryExportCommand.execute(context);
115
+
116
+ default:
117
+ return error(
118
+ "COMMAND_NOT_FOUND",
119
+ `Unknown memory subcommand: ${subcommand}\n\n${getMemoryHelp()}`
120
+ );
121
+ }
122
+ }
123
+
124
+ // =============================================================================
125
+ // Main Memory Command Definition
126
+ // =============================================================================
127
+
128
+ /**
129
+ * Main memory slash command.
130
+ */
131
+ export const memoryCommand: SlashCommand = {
132
+ name: "memory",
133
+ description: "Manage project memory",
134
+ kind: "builtin",
135
+ category: "session",
136
+ aliases: ["mem"],
137
+ subcommands: [
138
+ { name: "list", description: "List memories", aliases: ["ls"] },
139
+ { name: "search", description: "Search memories" },
140
+ { name: "export", description: "Export memories" },
141
+ ],
142
+ execute: handleMemory,
143
+ };
144
+
145
+ /**
146
+ * All memory commands for registration.
147
+ */
148
+ export const memoryCommands: SlashCommand[] = [memoryCommand, ...memorySubcommands];