@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,116 @@
1
+ /**
2
+ * Session Management Types (T056)
3
+ *
4
+ * Type definitions for session management components.
5
+ *
6
+ * @module tui/components/session/types
7
+ */
8
+
9
+ // =============================================================================
10
+ // Core Types
11
+ // =============================================================================
12
+
13
+ /**
14
+ * Metadata for a session stored in the session list.
15
+ */
16
+ export interface SessionMetadata {
17
+ /** Unique session identifier */
18
+ readonly id: string;
19
+ /** Display title for the session */
20
+ readonly title: string;
21
+ /** Preview of the last message in the session */
22
+ readonly lastMessage?: string;
23
+ /** Timestamp when the session was last active */
24
+ readonly timestamp: Date;
25
+ /** Total number of messages in the session */
26
+ readonly messageCount: number;
27
+ }
28
+
29
+ /**
30
+ * A message within a session for preview display.
31
+ */
32
+ export interface SessionPreviewMessage {
33
+ /** Unique message identifier */
34
+ readonly id: string;
35
+ /** Role of the message sender */
36
+ readonly role: "user" | "assistant" | "system" | "tool";
37
+ /** Content of the message */
38
+ readonly content: string;
39
+ /** Timestamp when the message was created */
40
+ readonly timestamp: Date;
41
+ }
42
+
43
+ // =============================================================================
44
+ // Component Props
45
+ // =============================================================================
46
+
47
+ /**
48
+ * Props for SessionItem component.
49
+ */
50
+ export interface SessionItemProps {
51
+ /** Session metadata to display */
52
+ readonly session: SessionMetadata;
53
+ /** Whether this session is currently selected */
54
+ readonly isSelected?: boolean;
55
+ /** Whether this session is the active session */
56
+ readonly isActive?: boolean;
57
+ /** Callback when the session is clicked/selected */
58
+ readonly onSelect?: (sessionId: string) => void;
59
+ }
60
+
61
+ /**
62
+ * Props for SessionListPanel component.
63
+ */
64
+ export interface SessionListPanelProps {
65
+ /** List of sessions to display */
66
+ readonly sessions: readonly SessionMetadata[];
67
+ /** ID of the currently selected session */
68
+ readonly selectedSessionId?: string;
69
+ /** ID of the currently active session */
70
+ readonly activeSessionId?: string;
71
+ /** Callback when a session is selected */
72
+ readonly onSelectSession?: (sessionId: string) => void;
73
+ /** Maximum height in lines (optional) */
74
+ readonly maxHeight?: number;
75
+ /** Whether the panel is focused for keyboard input */
76
+ readonly isFocused?: boolean;
77
+ }
78
+
79
+ /**
80
+ * Props for SessionPicker modal component.
81
+ */
82
+ export interface SessionPickerProps {
83
+ /** List of sessions to display */
84
+ readonly sessions: readonly SessionMetadata[];
85
+ /** ID of the currently active session */
86
+ readonly activeSessionId?: string;
87
+ /**
88
+ * Optional loader for real preview messages.
89
+ *
90
+ * When provided, SessionPicker will fetch messages for the selected session
91
+ * and cache results per session id.
92
+ *
93
+ * Return null when preview is unavailable.
94
+ */
95
+ readonly loadPreviewMessages?: (
96
+ sessionId: string
97
+ ) => Promise<readonly SessionPreviewMessage[] | null>;
98
+ /** Callback when a session is selected */
99
+ readonly onSelect: (sessionId: string) => void;
100
+ /** Callback to close the picker */
101
+ readonly onClose: () => void;
102
+ /** Whether the picker is visible */
103
+ readonly isOpen: boolean;
104
+ }
105
+
106
+ /**
107
+ * Props for SessionPreview component.
108
+ */
109
+ export interface SessionPreviewProps {
110
+ /** Messages to preview */
111
+ readonly messages: readonly SessionPreviewMessage[];
112
+ /** Maximum height in lines */
113
+ readonly maxHeight?: number;
114
+ /** Title of the session being previewed */
115
+ readonly title?: string;
116
+ }
@@ -0,0 +1,471 @@
1
+ /**
2
+ * Design Tokens Tests
3
+ *
4
+ * Unit tests for the design token system.
5
+ */
6
+
7
+ import { describe, expect, it } from "vitest";
8
+ import {
9
+ createSpacing,
10
+ // Utilities
11
+ getColor,
12
+ getColorTokens,
13
+ getFontSize,
14
+ getSpacing,
15
+ getSpacingTokens,
16
+ isColorToken,
17
+ isSpacingToken,
18
+ } from "../index.js";
19
+ import {
20
+ animationTiming,
21
+ backgroundColors,
22
+ borderCharsBold,
23
+ borderCharsDouble,
24
+ borderCharsRounded,
25
+ borderCharsSingle,
26
+ borderColors,
27
+ // Borders
28
+ borderRadius,
29
+ borderWidth,
30
+ // Core colors
31
+ colors,
32
+ // Typography
33
+ fontSizes,
34
+ fontWeights,
35
+ // Icons
36
+ icons,
37
+ lineHeights,
38
+ // Spacing
39
+ spacing,
40
+ // Animation
41
+ spinnerFrames,
42
+ statusColors,
43
+ textColors,
44
+ // Grouped
45
+ tokens,
46
+ } from "../tokens.js";
47
+
48
+ // =============================================================================
49
+ // Color Token Tests
50
+ // =============================================================================
51
+
52
+ describe("Design Tokens", () => {
53
+ describe("colors", () => {
54
+ it("should have all required color tokens", () => {
55
+ expect(colors.primary).toBeDefined();
56
+ expect(colors.secondary).toBeDefined();
57
+ expect(colors.success).toBeDefined();
58
+ expect(colors.warning).toBeDefined();
59
+ expect(colors.error).toBeDefined();
60
+ expect(colors.muted).toBeDefined();
61
+ expect(colors.info).toBeDefined();
62
+ expect(colors.accent).toBeDefined();
63
+ });
64
+
65
+ it("should have valid hex color values", () => {
66
+ const hexRegex = /^#[0-9A-Fa-f]{6}$/;
67
+
68
+ for (const [name, value] of Object.entries(colors)) {
69
+ expect(value, `${name} should be valid hex`).toMatch(hexRegex);
70
+ }
71
+ });
72
+
73
+ it("should have specific expected colors", () => {
74
+ expect(colors.primary).toBe("#7C3AED");
75
+ expect(colors.success).toBe("#10B981");
76
+ expect(colors.error).toBe("#EF4444");
77
+ });
78
+ });
79
+
80
+ describe("textColors", () => {
81
+ it("should have all text color tokens", () => {
82
+ expect(textColors.primary).toBeDefined();
83
+ expect(textColors.secondary).toBeDefined();
84
+ expect(textColors.muted).toBeDefined();
85
+ expect(textColors.inverted).toBeDefined();
86
+ expect(textColors.user).toBeDefined();
87
+ expect(textColors.assistant).toBeDefined();
88
+ expect(textColors.system).toBeDefined();
89
+ expect(textColors.tool).toBeDefined();
90
+ });
91
+
92
+ it("should have valid hex color values", () => {
93
+ const hexRegex = /^#[0-9A-Fa-f]{6}$/;
94
+
95
+ for (const [name, value] of Object.entries(textColors)) {
96
+ expect(value, `${name} should be valid hex`).toMatch(hexRegex);
97
+ }
98
+ });
99
+ });
100
+
101
+ describe("backgroundColors", () => {
102
+ it("should have all background color tokens", () => {
103
+ expect(backgroundColors.primary).toBeDefined();
104
+ expect(backgroundColors.secondary).toBeDefined();
105
+ expect(backgroundColors.elevated).toBeDefined();
106
+ expect(backgroundColors.code).toBeDefined();
107
+ });
108
+ });
109
+
110
+ describe("borderColors", () => {
111
+ it("should have all border color tokens", () => {
112
+ expect(borderColors.default).toBeDefined();
113
+ expect(borderColors.focus).toBeDefined();
114
+ expect(borderColors.muted).toBeDefined();
115
+ });
116
+ });
117
+
118
+ describe("statusColors", () => {
119
+ it("should have all status color tokens", () => {
120
+ expect(statusColors.pending).toBeDefined();
121
+ expect(statusColors.running).toBeDefined();
122
+ expect(statusColors.complete).toBeDefined();
123
+ expect(statusColors.error).toBeDefined();
124
+ expect(statusColors.approved).toBeDefined();
125
+ expect(statusColors.rejected).toBeDefined();
126
+ });
127
+ });
128
+ });
129
+
130
+ // =============================================================================
131
+ // Spacing Token Tests
132
+ // =============================================================================
133
+
134
+ describe("Spacing Tokens", () => {
135
+ describe("spacing", () => {
136
+ it("should have all spacing tokens", () => {
137
+ expect(spacing.none).toBe(0);
138
+ expect(spacing.xs).toBe(1);
139
+ expect(spacing.sm).toBe(2);
140
+ expect(spacing.md).toBe(4);
141
+ expect(spacing.lg).toBe(8);
142
+ expect(spacing.xl).toBe(16);
143
+ });
144
+
145
+ it("should have ascending values", () => {
146
+ expect(spacing.none).toBeLessThan(spacing.xs);
147
+ expect(spacing.xs).toBeLessThan(spacing.sm);
148
+ expect(spacing.sm).toBeLessThan(spacing.md);
149
+ expect(spacing.md).toBeLessThan(spacing.lg);
150
+ expect(spacing.lg).toBeLessThan(spacing.xl);
151
+ });
152
+
153
+ it("should be numeric values", () => {
154
+ for (const value of Object.values(spacing)) {
155
+ expect(typeof value).toBe("number");
156
+ }
157
+ });
158
+ });
159
+ });
160
+
161
+ // =============================================================================
162
+ // Typography Token Tests
163
+ // =============================================================================
164
+
165
+ describe("Typography Tokens", () => {
166
+ describe("fontSizes", () => {
167
+ it("should have all font size tokens", () => {
168
+ expect(fontSizes.xs).toBeDefined();
169
+ expect(fontSizes.sm).toBeDefined();
170
+ expect(fontSizes.md).toBeDefined();
171
+ expect(fontSizes.lg).toBeDefined();
172
+ expect(fontSizes.xl).toBeDefined();
173
+ expect(fontSizes.xxl).toBeDefined();
174
+ });
175
+
176
+ it("should have ascending values", () => {
177
+ expect(fontSizes.xs).toBeLessThan(fontSizes.sm);
178
+ expect(fontSizes.sm).toBeLessThan(fontSizes.md);
179
+ expect(fontSizes.md).toBeLessThan(fontSizes.lg);
180
+ expect(fontSizes.lg).toBeLessThan(fontSizes.xl);
181
+ expect(fontSizes.xl).toBeLessThan(fontSizes.xxl);
182
+ });
183
+ });
184
+
185
+ describe("fontWeights", () => {
186
+ it("should have all font weight tokens", () => {
187
+ expect(fontWeights.light).toBe(300);
188
+ expect(fontWeights.normal).toBe(400);
189
+ expect(fontWeights.medium).toBe(500);
190
+ expect(fontWeights.semibold).toBe(600);
191
+ expect(fontWeights.bold).toBe(700);
192
+ });
193
+ });
194
+
195
+ describe("lineHeights", () => {
196
+ it("should have all line height tokens", () => {
197
+ expect(lineHeights.tight).toBe(1.25);
198
+ expect(lineHeights.normal).toBe(1.5);
199
+ expect(lineHeights.relaxed).toBe(1.75);
200
+ });
201
+ });
202
+ });
203
+
204
+ // =============================================================================
205
+ // Border Token Tests
206
+ // =============================================================================
207
+
208
+ describe("Border Tokens", () => {
209
+ describe("borderRadius", () => {
210
+ it("should have all radius tokens", () => {
211
+ expect(borderRadius.none).toBe(0);
212
+ expect(borderRadius.sm).toBe(1);
213
+ expect(borderRadius.md).toBe(2);
214
+ expect(borderRadius.lg).toBe(4);
215
+ expect(borderRadius.full).toBe(999);
216
+ });
217
+ });
218
+
219
+ describe("borderWidth", () => {
220
+ it("should have all width tokens", () => {
221
+ expect(borderWidth.none).toBe(0);
222
+ expect(borderWidth.thin).toBe(1);
223
+ expect(borderWidth.medium).toBe(2);
224
+ expect(borderWidth.thick).toBe(3);
225
+ });
226
+ });
227
+
228
+ describe("border characters", () => {
229
+ it("should have single border characters", () => {
230
+ expect(borderCharsSingle.topLeft).toBe("┌");
231
+ expect(borderCharsSingle.topRight).toBe("┐");
232
+ expect(borderCharsSingle.bottomLeft).toBe("└");
233
+ expect(borderCharsSingle.bottomRight).toBe("┘");
234
+ expect(borderCharsSingle.horizontal).toBe("─");
235
+ expect(borderCharsSingle.vertical).toBe("│");
236
+ });
237
+
238
+ it("should have double border characters", () => {
239
+ expect(borderCharsDouble.topLeft).toBe("╔");
240
+ expect(borderCharsDouble.topRight).toBe("╗");
241
+ expect(borderCharsDouble.bottomLeft).toBe("╚");
242
+ expect(borderCharsDouble.bottomRight).toBe("╝");
243
+ expect(borderCharsDouble.horizontal).toBe("═");
244
+ expect(borderCharsDouble.vertical).toBe("║");
245
+ });
246
+
247
+ it("should have rounded border characters", () => {
248
+ expect(borderCharsRounded.topLeft).toBe("╭");
249
+ expect(borderCharsRounded.topRight).toBe("╮");
250
+ expect(borderCharsRounded.bottomLeft).toBe("╰");
251
+ expect(borderCharsRounded.bottomRight).toBe("╯");
252
+ });
253
+
254
+ it("should have bold border characters", () => {
255
+ expect(borderCharsBold.topLeft).toBe("┏");
256
+ expect(borderCharsBold.topRight).toBe("┓");
257
+ expect(borderCharsBold.bottomLeft).toBe("┗");
258
+ expect(borderCharsBold.bottomRight).toBe("┛");
259
+ expect(borderCharsBold.horizontal).toBe("━");
260
+ expect(borderCharsBold.vertical).toBe("┃");
261
+ });
262
+ });
263
+ });
264
+
265
+ // =============================================================================
266
+ // Animation Token Tests
267
+ // =============================================================================
268
+
269
+ describe("Animation Tokens", () => {
270
+ describe("spinnerFrames", () => {
271
+ it("should have all spinner frame sequences", () => {
272
+ expect(spinnerFrames.dots).toHaveLength(10);
273
+ expect(spinnerFrames.line).toHaveLength(4);
274
+ expect(spinnerFrames.arc).toHaveLength(6);
275
+ expect(spinnerFrames.bounce).toHaveLength(4);
276
+ });
277
+
278
+ it("should have non-empty frames", () => {
279
+ for (const frames of Object.values(spinnerFrames)) {
280
+ expect(frames.length).toBeGreaterThan(0);
281
+ for (const frame of frames) {
282
+ expect(frame.length).toBeGreaterThan(0);
283
+ }
284
+ }
285
+ });
286
+ });
287
+
288
+ describe("animationTiming", () => {
289
+ it("should have all timing values", () => {
290
+ expect(animationTiming.frameInterval).toBe(80);
291
+ expect(animationTiming.cursorBlink).toBe(530);
292
+ expect(animationTiming.fast).toBe(150);
293
+ expect(animationTiming.normal).toBe(300);
294
+ expect(animationTiming.slow).toBe(500);
295
+ });
296
+ });
297
+ });
298
+
299
+ // =============================================================================
300
+ // Icon Token Tests
301
+ // =============================================================================
302
+
303
+ describe("Icon Tokens", () => {
304
+ describe("icons", () => {
305
+ it("should have all status icons", () => {
306
+ expect(icons.success).toBe("✓");
307
+ expect(icons.error).toBe("✗");
308
+ expect(icons.warning).toBe("⚠");
309
+ expect(icons.info).toBe("ℹ");
310
+ expect(icons.pending).toBe("○");
311
+ });
312
+
313
+ it("should have all checkbox icons", () => {
314
+ expect(icons.checked).toBe("☑");
315
+ expect(icons.unchecked).toBe("☐");
316
+ });
317
+
318
+ it("should have all navigation icons", () => {
319
+ expect(icons.collapsed).toBe("▸");
320
+ expect(icons.expanded).toBe("▾");
321
+ expect(icons.arrowRight).toBe("→");
322
+ expect(icons.arrowLeft).toBe("←");
323
+ expect(icons.arrowUp).toBe("↑");
324
+ expect(icons.arrowDown).toBe("↓");
325
+ });
326
+
327
+ it("should have all entity icons", () => {
328
+ expect(icons.user).toBe("@");
329
+ expect(icons.assistant).toBe("*");
330
+ expect(icons.tool).toBe(">");
331
+ });
332
+
333
+ it("should have action icons", () => {
334
+ expect(icons.edit).toBe("~");
335
+ expect(icons.copy).toBe("#");
336
+ expect(icons.loading).toBe("◌");
337
+ });
338
+ });
339
+ });
340
+
341
+ // =============================================================================
342
+ // Grouped Tokens Tests
343
+ // =============================================================================
344
+
345
+ describe("Grouped Tokens", () => {
346
+ describe("tokens", () => {
347
+ it("should contain all token categories", () => {
348
+ expect(tokens.colors).toBe(colors);
349
+ expect(tokens.textColors).toBe(textColors);
350
+ expect(tokens.backgroundColors).toBe(backgroundColors);
351
+ expect(tokens.borderColors).toBe(borderColors);
352
+ expect(tokens.statusColors).toBe(statusColors);
353
+ expect(tokens.spacing).toBe(spacing);
354
+ expect(tokens.fontSizes).toBe(fontSizes);
355
+ expect(tokens.fontWeights).toBe(fontWeights);
356
+ expect(tokens.lineHeights).toBe(lineHeights);
357
+ expect(tokens.borderRadius).toBe(borderRadius);
358
+ expect(tokens.borderWidth).toBe(borderWidth);
359
+ expect(tokens.borderCharsSingle).toBe(borderCharsSingle);
360
+ expect(tokens.borderCharsDouble).toBe(borderCharsDouble);
361
+ expect(tokens.borderCharsRounded).toBe(borderCharsRounded);
362
+ expect(tokens.borderCharsBold).toBe(borderCharsBold);
363
+ expect(tokens.spinnerFrames).toBe(spinnerFrames);
364
+ expect(tokens.animationTiming).toBe(animationTiming);
365
+ expect(tokens.icons).toBe(icons);
366
+ });
367
+ });
368
+ });
369
+
370
+ // =============================================================================
371
+ // Utility Function Tests
372
+ // =============================================================================
373
+
374
+ describe("Theme Utilities", () => {
375
+ describe("getColor", () => {
376
+ it("should return color for valid token", () => {
377
+ expect(getColor("primary")).toBe("#7C3AED");
378
+ expect(getColor("error")).toBe("#EF4444");
379
+ expect(getColor("success")).toBe("#10B981");
380
+ });
381
+ });
382
+
383
+ describe("getSpacing", () => {
384
+ it("should return spacing value for valid token", () => {
385
+ expect(getSpacing("none")).toBe(0);
386
+ expect(getSpacing("md")).toBe(4);
387
+ expect(getSpacing("xl")).toBe(16);
388
+ });
389
+ });
390
+
391
+ describe("getFontSize", () => {
392
+ it("should return font size for valid token", () => {
393
+ expect(getFontSize("sm")).toBe(12);
394
+ expect(getFontSize("md")).toBe(14);
395
+ expect(getFontSize("xl")).toBe(20);
396
+ });
397
+ });
398
+
399
+ describe("createSpacing", () => {
400
+ it("should return single value for one token", () => {
401
+ expect(createSpacing("md")).toBe(4);
402
+ expect(createSpacing("lg")).toBe(8);
403
+ });
404
+
405
+ it("should return vertical/horizontal for two tokens", () => {
406
+ const result = createSpacing("sm", "md");
407
+ expect(result).toEqual({ vertical: 2, horizontal: 4 });
408
+ });
409
+
410
+ it("should return all sides for four tokens", () => {
411
+ const result = createSpacing("xs", "sm", "md", "lg");
412
+ expect(result).toEqual({ top: 1, right: 2, bottom: 4, left: 8 });
413
+ });
414
+ });
415
+
416
+ describe("isColorToken", () => {
417
+ it("should return true for valid color tokens", () => {
418
+ expect(isColorToken("primary")).toBe(true);
419
+ expect(isColorToken("error")).toBe(true);
420
+ expect(isColorToken("success")).toBe(true);
421
+ });
422
+
423
+ it("should return false for invalid tokens", () => {
424
+ expect(isColorToken("invalid")).toBe(false);
425
+ expect(isColorToken("")).toBe(false);
426
+ expect(isColorToken("PRIMARY")).toBe(false);
427
+ });
428
+ });
429
+
430
+ describe("isSpacingToken", () => {
431
+ it("should return true for valid spacing tokens", () => {
432
+ expect(isSpacingToken("xs")).toBe(true);
433
+ expect(isSpacingToken("md")).toBe(true);
434
+ expect(isSpacingToken("xl")).toBe(true);
435
+ });
436
+
437
+ it("should return false for invalid tokens", () => {
438
+ expect(isSpacingToken("invalid")).toBe(false);
439
+ expect(isSpacingToken("")).toBe(false);
440
+ expect(isSpacingToken("XXL")).toBe(false);
441
+ });
442
+ });
443
+
444
+ describe("getColorTokens", () => {
445
+ it("should return all color token names", () => {
446
+ const tokenNames = getColorTokens();
447
+
448
+ expect(tokenNames).toContain("primary");
449
+ expect(tokenNames).toContain("secondary");
450
+ expect(tokenNames).toContain("success");
451
+ expect(tokenNames).toContain("error");
452
+ expect(tokenNames).toContain("warning");
453
+ expect(tokenNames).toContain("muted");
454
+ expect(tokenNames).toContain("info");
455
+ expect(tokenNames).toContain("accent");
456
+ });
457
+ });
458
+
459
+ describe("getSpacingTokens", () => {
460
+ it("should return all spacing token names", () => {
461
+ const tokenNames = getSpacingTokens();
462
+
463
+ expect(tokenNames).toContain("none");
464
+ expect(tokenNames).toContain("xs");
465
+ expect(tokenNames).toContain("sm");
466
+ expect(tokenNames).toContain("md");
467
+ expect(tokenNames).toContain("lg");
468
+ expect(tokenNames).toContain("xl");
469
+ });
470
+ });
471
+ });