@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,597 @@
1
+ // src/commands/auth.ts
2
+ import {
3
+ CredentialManager,
4
+ EncryptedFileStore,
5
+ EnvCredentialStore,
6
+ KeychainStore
7
+ } from "@vellum/core";
8
+
9
+ // src/commands/types.ts
10
+ function success(message, data) {
11
+ return { kind: "success", message, data };
12
+ }
13
+ function error(code, message, suggestions) {
14
+ return { kind: "error", code, message, suggestions };
15
+ }
16
+ function interactive(prompt) {
17
+ return { kind: "interactive", prompt };
18
+ }
19
+ function pending(operation) {
20
+ return { kind: "pending", operation };
21
+ }
22
+
23
+ // src/commands/auth.ts
24
+ async function createCredentialManager() {
25
+ const stores = [
26
+ new EnvCredentialStore(),
27
+ new KeychainStore(),
28
+ new EncryptedFileStore({
29
+ filePath: `${process.env.HOME ?? process.env.USERPROFILE}/.vellum/credentials.enc`,
30
+ password: process.env.VELLUM_CREDENTIAL_PASSWORD ?? "vellum-default-key"
31
+ })
32
+ ];
33
+ return new CredentialManager(stores, {
34
+ preferredWriteStore: "keychain"
35
+ });
36
+ }
37
+ async function handleCredentials(args, context) {
38
+ const filterProvider = args[0]?.toLowerCase();
39
+ try {
40
+ const availability = await context.credentialManager.getStoreAvailability();
41
+ const listResult = await context.credentialManager.list(filterProvider);
42
+ if (!listResult.ok) {
43
+ return {
44
+ success: false,
45
+ message: `\u274C Failed to list credentials: ${listResult.error.message}`
46
+ };
47
+ }
48
+ const credentials = listResult.value;
49
+ const lines = [];
50
+ lines.push("\u{1F510} Credential Status");
51
+ lines.push("\u2501".repeat(40));
52
+ lines.push("\n\u{1F4E6} Storage Backends:");
53
+ for (const [store, available] of Object.entries(availability)) {
54
+ lines.push(` ${available ? "\u2713" : "\u2717"} ${store}`);
55
+ }
56
+ lines.push("\n\u{1F511} Credentials:");
57
+ if (credentials.length === 0) {
58
+ if (filterProvider) {
59
+ lines.push(` No credential found for ${filterProvider}`);
60
+ } else {
61
+ lines.push(" No credentials stored");
62
+ lines.push(" Use /auth set <provider> to add one");
63
+ }
64
+ } else {
65
+ for (const cred of credentials) {
66
+ const maskedValue = cred.maskedHint ?? "***";
67
+ lines.push(` \u2022 ${cred.provider} (${cred.source}): ${maskedValue} [${cred.type}]`);
68
+ }
69
+ }
70
+ lines.push("\u2501".repeat(40));
71
+ return {
72
+ success: true,
73
+ message: lines.join("\n"),
74
+ data: {
75
+ availability,
76
+ credentials: credentials.map((c) => ({
77
+ provider: c.provider,
78
+ source: c.source,
79
+ type: c.type,
80
+ maskedHint: c.maskedHint
81
+ }))
82
+ }
83
+ };
84
+ } catch (err) {
85
+ return {
86
+ success: false,
87
+ message: `\u274C Error: ${err instanceof Error ? err.message : String(err)}`
88
+ };
89
+ }
90
+ }
91
+ var authSlashCommands = [
92
+ {
93
+ name: "credentials",
94
+ aliases: ["creds", "keys"],
95
+ description: "Show credential status",
96
+ usage: "/credentials [provider]",
97
+ handler: handleCredentials
98
+ }
99
+ ];
100
+ var credentialsCommand = {
101
+ name: "credentials",
102
+ description: "Show credential status and available stores",
103
+ kind: "builtin",
104
+ category: "auth",
105
+ aliases: ["creds", "keys"],
106
+ positionalArgs: [
107
+ {
108
+ name: "provider",
109
+ type: "string",
110
+ description: "Filter by provider name",
111
+ required: false
112
+ }
113
+ ],
114
+ namedArgs: [],
115
+ examples: ["/credentials", "/credentials anthropic", "/creds"],
116
+ execute: async (ctx) => {
117
+ const filterProvider = ctx.parsedArgs.positional[0];
118
+ const normalizedFilter = filterProvider?.toLowerCase();
119
+ try {
120
+ const availability = await ctx.credentials.getStoreAvailability();
121
+ const listResult = await ctx.credentials.list(normalizedFilter);
122
+ if (!listResult.ok) {
123
+ return error(
124
+ "INTERNAL_ERROR",
125
+ `\u274C Failed to list credentials: ${listResult.error.message}`
126
+ );
127
+ }
128
+ const credentials = listResult.value;
129
+ const lines = [];
130
+ lines.push("\u{1F510} Credential Status");
131
+ lines.push("\u2501".repeat(40));
132
+ lines.push("\n\u{1F4E6} Storage Backends:");
133
+ for (const [store, available] of Object.entries(availability)) {
134
+ lines.push(` ${available ? "\u2713" : "\u2717"} ${store}`);
135
+ }
136
+ lines.push("\n\u{1F511} Credentials:");
137
+ if (credentials.length === 0) {
138
+ if (normalizedFilter) {
139
+ lines.push(` No credential found for ${normalizedFilter}`);
140
+ } else {
141
+ lines.push(" No credentials stored");
142
+ lines.push(" Use /auth set <provider> to add one");
143
+ }
144
+ } else {
145
+ for (const cred of credentials) {
146
+ const maskedValue = cred.maskedHint ?? "***";
147
+ lines.push(` \u2022 ${cred.provider} (${cred.source}): ${maskedValue} [${cred.type}]`);
148
+ }
149
+ }
150
+ lines.push("\u2501".repeat(40));
151
+ return success(lines.join("\n"), {
152
+ availability,
153
+ credentials: credentials.map((c) => ({
154
+ provider: c.provider,
155
+ source: c.source,
156
+ type: c.type,
157
+ maskedHint: c.maskedHint
158
+ }))
159
+ });
160
+ } catch (err) {
161
+ return error(
162
+ "INTERNAL_ERROR",
163
+ `\u274C Error: ${err instanceof Error ? err.message : String(err)}`
164
+ );
165
+ }
166
+ }
167
+ };
168
+ var authCommand = {
169
+ name: "auth",
170
+ description: "Manage API credentials (status, set, clear)",
171
+ kind: "builtin",
172
+ category: "auth",
173
+ aliases: [],
174
+ subcommands: [
175
+ {
176
+ name: "status",
177
+ description: "Show current authentication status (default)",
178
+ aliases: ["st", "list"]
179
+ },
180
+ {
181
+ name: "set",
182
+ description: "Add or update API credential for a provider",
183
+ aliases: ["add", "login"]
184
+ },
185
+ {
186
+ name: "clear",
187
+ description: "Remove credential for a provider",
188
+ aliases: ["remove", "delete", "logout"]
189
+ }
190
+ ],
191
+ positionalArgs: [
192
+ {
193
+ name: "subcommand",
194
+ type: "string",
195
+ description: "Subcommand: status, set, clear (default: status)",
196
+ required: false
197
+ },
198
+ {
199
+ name: "provider",
200
+ type: "string",
201
+ description: "Provider name (e.g., anthropic, openai)",
202
+ required: false
203
+ }
204
+ ],
205
+ namedArgs: [
206
+ {
207
+ name: "store",
208
+ shorthand: "s",
209
+ type: "string",
210
+ description: "Credential store to use (keychain, encrypted-file, env)",
211
+ required: false,
212
+ default: "keychain"
213
+ },
214
+ {
215
+ name: "force",
216
+ shorthand: "f",
217
+ type: "boolean",
218
+ description: "Skip confirmation prompt for clear",
219
+ required: false,
220
+ default: false
221
+ }
222
+ ],
223
+ examples: [
224
+ "/auth",
225
+ "/auth status",
226
+ "/auth set anthropic",
227
+ "/auth set openai --store keychain",
228
+ "/auth clear anthropic",
229
+ "/auth clear openai --force"
230
+ ],
231
+ execute: async (ctx) => {
232
+ const args = ctx.parsedArgs.positional;
233
+ const subcommand = args[0]?.toLowerCase() ?? "status";
234
+ const provider = args[1] ?? // If subcommand is a provider name (not a known subcommand), treat it as provider
235
+ (![
236
+ "status",
237
+ "st",
238
+ "list",
239
+ "set",
240
+ "add",
241
+ "login",
242
+ "clear",
243
+ "remove",
244
+ "delete",
245
+ "logout"
246
+ ].includes(subcommand) ? subcommand : void 0);
247
+ const store = ctx.parsedArgs.named.store;
248
+ const force = ctx.parsedArgs.named.force === true;
249
+ const actualSubcommand = [
250
+ "status",
251
+ "st",
252
+ "list",
253
+ "set",
254
+ "add",
255
+ "login",
256
+ "clear",
257
+ "remove",
258
+ "delete",
259
+ "logout"
260
+ ].includes(subcommand) ? subcommand : "status";
261
+ switch (actualSubcommand) {
262
+ case "set":
263
+ case "add":
264
+ case "login":
265
+ return authSet(ctx.credentials, provider ?? ctx.session.provider, store);
266
+ case "clear":
267
+ case "remove":
268
+ case "delete":
269
+ case "logout":
270
+ return authClear(ctx.credentials, provider ?? ctx.session.provider, force);
271
+ default:
272
+ return authStatus(ctx.credentials, provider);
273
+ }
274
+ }
275
+ };
276
+ async function authStatus(credentials, filterProvider) {
277
+ const normalizedFilter = filterProvider?.toLowerCase();
278
+ try {
279
+ const availability = await credentials.getStoreAvailability();
280
+ const listResult = await credentials.list(normalizedFilter);
281
+ if (!listResult.ok) {
282
+ return error("INTERNAL_ERROR", `\u274C Failed to list credentials: ${listResult.error.message}`);
283
+ }
284
+ const credentialsList = listResult.value;
285
+ const lines = [];
286
+ lines.push("\u{1F510} Authentication Status");
287
+ lines.push("\u2501".repeat(40));
288
+ lines.push("\n\u{1F4E6} Storage Backends:");
289
+ for (const [store, available] of Object.entries(availability)) {
290
+ lines.push(` ${available ? "\u2713" : "\u2717"} ${store}`);
291
+ }
292
+ lines.push("\n\u{1F511} Configured Providers:");
293
+ if (credentialsList.length === 0) {
294
+ if (normalizedFilter) {
295
+ lines.push(` No credential found for ${normalizedFilter}`);
296
+ } else {
297
+ lines.push(" No credentials stored");
298
+ lines.push(" Use /auth set <provider> to add one");
299
+ }
300
+ } else {
301
+ for (const cred of credentialsList) {
302
+ const maskedValue = cred.maskedHint ?? "***";
303
+ lines.push(` \u2022 ${cred.provider} (${cred.source}): ${maskedValue} [${cred.type}]`);
304
+ }
305
+ }
306
+ lines.push(`
307
+ ${"\u2501".repeat(40)}`);
308
+ lines.push("\u{1F4A1} Commands: /auth set <provider> | /auth clear <provider>");
309
+ return success(lines.join("\n"), {
310
+ availability,
311
+ credentials: credentialsList.map((c) => ({
312
+ provider: c.provider,
313
+ source: c.source,
314
+ type: c.type,
315
+ maskedHint: c.maskedHint
316
+ }))
317
+ });
318
+ } catch (err) {
319
+ return error("INTERNAL_ERROR", `\u274C Error: ${err instanceof Error ? err.message : String(err)}`);
320
+ }
321
+ }
322
+ var PROVIDER_KEY_HINTS = {
323
+ anthropic: {
324
+ formatHint: "sk-ant-api03-...",
325
+ helpText: "Your Anthropic key starts with sk-ant-",
326
+ documentationUrl: "https://console.anthropic.com/settings/keys"
327
+ },
328
+ openai: {
329
+ formatHint: "sk-proj-...",
330
+ helpText: "Your OpenAI key starts with sk-proj- or sk-",
331
+ documentationUrl: "https://platform.openai.com/api-keys"
332
+ },
333
+ google: {
334
+ formatHint: "AIza...",
335
+ helpText: "Your Google AI key starts with AIza",
336
+ documentationUrl: "https://aistudio.google.com/apikey"
337
+ },
338
+ gemini: {
339
+ formatHint: "AIza...",
340
+ helpText: "Your Gemini key starts with AIza",
341
+ documentationUrl: "https://aistudio.google.com/apikey"
342
+ },
343
+ bedrock: {
344
+ formatHint: "AKIA...",
345
+ helpText: "Enter your AWS access key ID",
346
+ documentationUrl: "https://docs.aws.amazon.com/bedrock/latest/userguide/setting-up.html"
347
+ },
348
+ cohere: {
349
+ formatHint: "...",
350
+ helpText: "Your Cohere API key",
351
+ documentationUrl: "https://dashboard.cohere.com/api-keys"
352
+ },
353
+ mistral: {
354
+ formatHint: "...",
355
+ helpText: "Your Mistral API key",
356
+ documentationUrl: "https://console.mistral.ai/api-keys"
357
+ },
358
+ groq: {
359
+ formatHint: "gsk_...",
360
+ helpText: "Your Groq key starts with gsk_",
361
+ documentationUrl: "https://console.groq.com/keys"
362
+ },
363
+ fireworks: {
364
+ formatHint: "fw_...",
365
+ helpText: "Your Fireworks key starts with fw_",
366
+ documentationUrl: "https://fireworks.ai/account/api-keys"
367
+ },
368
+ together: {
369
+ formatHint: "...",
370
+ helpText: "Your Together AI API key",
371
+ documentationUrl: "https://api.together.xyz/settings/api-keys"
372
+ },
373
+ perplexity: {
374
+ formatHint: "pplx-...",
375
+ helpText: "Your Perplexity key starts with pplx-",
376
+ documentationUrl: "https://www.perplexity.ai/settings/api"
377
+ },
378
+ deepseek: {
379
+ formatHint: "sk-...",
380
+ helpText: "Your DeepSeek API key",
381
+ documentationUrl: "https://platform.deepseek.com/api_keys"
382
+ },
383
+ openrouter: {
384
+ formatHint: "sk-or-...",
385
+ helpText: "Your OpenRouter key starts with sk-or-",
386
+ documentationUrl: "https://openrouter.ai/keys"
387
+ },
388
+ ollama: {
389
+ formatHint: "(optional)",
390
+ helpText: "Ollama typically runs locally without an API key"
391
+ }
392
+ };
393
+ function getProviderHints(provider) {
394
+ return PROVIDER_KEY_HINTS[provider] ?? {
395
+ formatHint: "...",
396
+ helpText: `Enter your ${provider} API key`
397
+ };
398
+ }
399
+ async function authSet(credentials, provider, store) {
400
+ if (!provider) {
401
+ return error(
402
+ "MISSING_ARGUMENT",
403
+ "\u274C Provider required. Usage: /auth set <provider>\n Example: /auth set anthropic"
404
+ );
405
+ }
406
+ const normalizedProvider = provider.toLowerCase();
407
+ const existsResult = await credentials.exists(normalizedProvider);
408
+ const alreadyExists = existsResult.ok && existsResult.value;
409
+ const hints = getProviderHints(normalizedProvider);
410
+ const displayName = normalizedProvider.charAt(0).toUpperCase() + normalizedProvider.slice(1);
411
+ const title = alreadyExists ? `\u{1F510} Update API Key for ${displayName}` : `\u{1F510} Set API Key for ${displayName}`;
412
+ const promptMessage = `${displayName} API Key:`;
413
+ return interactive({
414
+ inputType: "password",
415
+ message: promptMessage,
416
+ placeholder: hints.formatHint,
417
+ provider: normalizedProvider,
418
+ title,
419
+ helpText: hints.helpText,
420
+ formatHint: hints.formatHint,
421
+ documentationUrl: hints.documentationUrl,
422
+ handler: async (value) => {
423
+ if (!value.trim()) {
424
+ return error("INVALID_ARGUMENT", "\u274C API key cannot be empty");
425
+ }
426
+ try {
427
+ const result = await credentials.store(
428
+ {
429
+ provider: normalizedProvider,
430
+ type: "api_key",
431
+ value: value.trim(),
432
+ metadata: {
433
+ label: `${normalizedProvider} API Key`
434
+ }
435
+ },
436
+ store
437
+ );
438
+ if (!result.ok) {
439
+ return error("INTERNAL_ERROR", `\u274C Failed to save credential: ${result.error.message}`);
440
+ }
441
+ return success(`\u2705 Credential for ${normalizedProvider} saved to ${result.value.source}`, {
442
+ provider: normalizedProvider,
443
+ source: result.value.source
444
+ });
445
+ } catch (err) {
446
+ return error(
447
+ "INTERNAL_ERROR",
448
+ `\u274C Error: ${err instanceof Error ? err.message : String(err)}`
449
+ );
450
+ }
451
+ },
452
+ onCancel: () => ({
453
+ kind: "error",
454
+ code: "COMMAND_ABORTED",
455
+ message: "Credential setup cancelled"
456
+ })
457
+ });
458
+ }
459
+ async function authClear(credentials, provider, force) {
460
+ if (!provider) {
461
+ return error(
462
+ "MISSING_ARGUMENT",
463
+ "\u274C Provider required. Usage: /auth clear <provider>\n Example: /auth clear anthropic"
464
+ );
465
+ }
466
+ const normalizedProvider = provider.toLowerCase();
467
+ const existsResult = await credentials.exists(normalizedProvider);
468
+ if (!existsResult.ok || !existsResult.value) {
469
+ return error("CREDENTIAL_NOT_FOUND", `\u26A0\uFE0F No credential found for ${normalizedProvider}`);
470
+ }
471
+ if (!force) {
472
+ return interactive({
473
+ inputType: "confirm",
474
+ message: `Are you sure you want to remove credential for ${normalizedProvider}?`,
475
+ handler: async (value) => {
476
+ if (value.toLowerCase() !== "yes" && value.toLowerCase() !== "y") {
477
+ return error("COMMAND_ABORTED", "Credential removal cancelled");
478
+ }
479
+ return performAuthClear(credentials, normalizedProvider);
480
+ },
481
+ onCancel: () => ({
482
+ kind: "error",
483
+ code: "COMMAND_ABORTED",
484
+ message: "Credential removal cancelled"
485
+ })
486
+ });
487
+ }
488
+ return performAuthClear(credentials, normalizedProvider);
489
+ }
490
+ async function performAuthClear(credentials, provider) {
491
+ try {
492
+ const result = await credentials.delete(provider);
493
+ if (!result.ok) {
494
+ return error("INTERNAL_ERROR", `\u274C Failed to remove credential: ${result.error.message}`);
495
+ }
496
+ if (result.value === 0) {
497
+ return error("CREDENTIAL_NOT_FOUND", `\u26A0\uFE0F No credential found for ${provider}`);
498
+ }
499
+ return success(`\u2705 Credential for ${provider} removed from ${result.value} store(s)`, {
500
+ provider,
501
+ deletedCount: result.value
502
+ });
503
+ } catch (err) {
504
+ return error("INTERNAL_ERROR", `\u274C Error: ${err instanceof Error ? err.message : String(err)}`);
505
+ }
506
+ }
507
+ var enhancedAuthCommands = [authCommand, credentialsCommand];
508
+ function isSlashCommand(input) {
509
+ return input.trim().startsWith("/");
510
+ }
511
+ function parseSlashCommand(input) {
512
+ const trimmed = input.trim();
513
+ if (!trimmed.startsWith("/")) {
514
+ return null;
515
+ }
516
+ const parts = trimmed.slice(1).split(/\s+/);
517
+ const command = parts[0]?.toLowerCase() ?? "";
518
+ const args = parts.slice(1);
519
+ return { command, args };
520
+ }
521
+ function findSlashCommand(name) {
522
+ const lowerName = name.toLowerCase();
523
+ return authSlashCommands.find(
524
+ (cmd) => cmd.name === lowerName || cmd.aliases?.includes(lowerName)
525
+ );
526
+ }
527
+ async function executeSlashCommand(input, context = {}) {
528
+ const parsed = parseSlashCommand(input);
529
+ if (!parsed) {
530
+ return {
531
+ success: false,
532
+ message: "Invalid slash command format"
533
+ };
534
+ }
535
+ const command = findSlashCommand(parsed.command);
536
+ if (!command) {
537
+ if (parsed.command === "help" && parsed.args[0]) {
538
+ const helpCmd = findSlashCommand(parsed.args[0]);
539
+ if (helpCmd) {
540
+ return {
541
+ success: true,
542
+ message: `\u{1F4D6} ${helpCmd.name}
543
+ ${helpCmd.description}
544
+ Usage: ${helpCmd.usage}`
545
+ };
546
+ }
547
+ }
548
+ const available = authSlashCommands.map((c) => `/${c.name}`).join(", ");
549
+ return {
550
+ success: false,
551
+ message: `\u2753 Unknown command: /${parsed.command}
552
+ Available: ${available}`
553
+ };
554
+ }
555
+ const credentialManager = context.credentialManager ?? await createCredentialManager();
556
+ const fullContext = {
557
+ currentProvider: context.currentProvider,
558
+ credentialManager
559
+ };
560
+ return command.handler(parsed.args, fullContext);
561
+ }
562
+ function getSlashCommandHelp() {
563
+ const lines = [];
564
+ lines.push("\u{1F4D6} Available Commands:");
565
+ lines.push("\u2501".repeat(40));
566
+ for (const cmd of authSlashCommands) {
567
+ lines.push(`
568
+ /${cmd.name}`);
569
+ if (cmd.aliases?.length) {
570
+ lines.push(` Aliases: ${cmd.aliases.map((a) => `/${a}`).join(", ")}`);
571
+ }
572
+ lines.push(` ${cmd.description}`);
573
+ lines.push(` Usage: ${cmd.usage}`);
574
+ }
575
+ lines.push(`
576
+ ${"\u2501".repeat(40)}`);
577
+ lines.push("Tip: Use /help <command> for detailed help");
578
+ return lines.join("\n");
579
+ }
580
+
581
+ export {
582
+ success,
583
+ error,
584
+ interactive,
585
+ pending,
586
+ createCredentialManager,
587
+ handleCredentials,
588
+ authSlashCommands,
589
+ credentialsCommand,
590
+ authCommand,
591
+ enhancedAuthCommands,
592
+ isSlashCommand,
593
+ parseSlashCommand,
594
+ findSlashCommand,
595
+ executeSlashCommand,
596
+ getSlashCommandHelp
597
+ };