@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,213 @@
1
+ /**
2
+ * Overflow Context
3
+ *
4
+ * Tracks which components are currently overflowing their containers.
5
+ * This enables smart truncation and "Show More" functionality.
6
+ *
7
+ * Ported from Gemini CLI for Vellum TUI.
8
+ *
9
+ * @module tui/context/OverflowContext
10
+ */
11
+
12
+ import React, {
13
+ createContext,
14
+ type ReactNode,
15
+ useCallback,
16
+ useContext,
17
+ useMemo,
18
+ useState,
19
+ } from "react";
20
+
21
+ // =============================================================================
22
+ // Types
23
+ // =============================================================================
24
+
25
+ /**
26
+ * State tracking which component IDs are currently overflowing
27
+ */
28
+ export interface OverflowState {
29
+ /** Set of component IDs that are currently overflowing */
30
+ readonly overflowingIds: ReadonlySet<string>;
31
+ }
32
+
33
+ /**
34
+ * Context value providing overflow state and management functions
35
+ */
36
+ export interface OverflowContextValue {
37
+ /** Current overflow state */
38
+ readonly state: OverflowState;
39
+ /**
40
+ * Register a component as overflowing
41
+ * @param id - Unique identifier for the component
42
+ */
43
+ readonly registerOverflow: (id: string) => void;
44
+ /**
45
+ * Unregister a component from the overflow set
46
+ * @param id - Unique identifier for the component
47
+ */
48
+ readonly unregisterOverflow: (id: string) => void;
49
+ /**
50
+ * Check if a specific component is overflowing
51
+ * @param id - Unique identifier for the component
52
+ * @returns true if the component is currently overflowing
53
+ */
54
+ readonly isOverflowing: (id: string) => boolean;
55
+ }
56
+
57
+ /**
58
+ * Props for the OverflowProvider component
59
+ */
60
+ export interface OverflowProviderProps {
61
+ /** Children to render within the overflow context */
62
+ readonly children: ReactNode;
63
+ }
64
+
65
+ // =============================================================================
66
+ // Context
67
+ // =============================================================================
68
+
69
+ /**
70
+ * Initial overflow state
71
+ */
72
+ const initialState: OverflowState = {
73
+ overflowingIds: new Set<string>(),
74
+ };
75
+
76
+ /**
77
+ * React context for overflow state management
78
+ */
79
+ export const OverflowContext = createContext<OverflowContextValue | null>(null);
80
+
81
+ // Set display name for debugging
82
+ OverflowContext.displayName = "OverflowContext";
83
+
84
+ // =============================================================================
85
+ // Provider Component
86
+ // =============================================================================
87
+
88
+ /**
89
+ * OverflowProvider manages tracking of overflowing components.
90
+ *
91
+ * Components can register themselves as overflowing when their content
92
+ * exceeds their container bounds, enabling parent components to respond
93
+ * appropriately (e.g., showing truncation indicators or "Show More" buttons).
94
+ *
95
+ * @example
96
+ * ```tsx
97
+ * <OverflowProvider>
98
+ * <App />
99
+ * </OverflowProvider>
100
+ *
101
+ * // In a child component:
102
+ * const { registerOverflow, unregisterOverflow, isOverflowing } = useOverflow();
103
+ *
104
+ * useEffect(() => {
105
+ * if (contentHeight > containerHeight) {
106
+ * registerOverflow('my-component-id');
107
+ * } else {
108
+ * unregisterOverflow('my-component-id');
109
+ * }
110
+ * }, [contentHeight, containerHeight]);
111
+ * ```
112
+ */
113
+ export function OverflowProvider({ children }: OverflowProviderProps): React.JSX.Element {
114
+ const [overflowingIds, setOverflowingIds] = useState<ReadonlySet<string>>(
115
+ initialState.overflowingIds
116
+ );
117
+
118
+ /**
119
+ * Register a component as overflowing
120
+ */
121
+ const registerOverflow = useCallback((id: string) => {
122
+ setOverflowingIds((prev) => {
123
+ if (prev.has(id)) {
124
+ return prev;
125
+ }
126
+ const next = new Set(prev);
127
+ next.add(id);
128
+ return next;
129
+ });
130
+ }, []);
131
+
132
+ /**
133
+ * Unregister a component from the overflow set
134
+ */
135
+ const unregisterOverflow = useCallback((id: string) => {
136
+ setOverflowingIds((prev) => {
137
+ if (!prev.has(id)) {
138
+ return prev;
139
+ }
140
+ const next = new Set(prev);
141
+ next.delete(id);
142
+ return next;
143
+ });
144
+ }, []);
145
+
146
+ /**
147
+ * Check if a specific component is overflowing
148
+ */
149
+ const isOverflowing = useCallback(
150
+ (id: string): boolean => {
151
+ return overflowingIds.has(id);
152
+ },
153
+ [overflowingIds]
154
+ );
155
+
156
+ /**
157
+ * Memoized context value to prevent unnecessary re-renders
158
+ */
159
+ const contextValue = useMemo<OverflowContextValue>(
160
+ () => ({
161
+ state: { overflowingIds },
162
+ registerOverflow,
163
+ unregisterOverflow,
164
+ isOverflowing,
165
+ }),
166
+ [overflowingIds, registerOverflow, unregisterOverflow, isOverflowing]
167
+ );
168
+
169
+ return <OverflowContext.Provider value={contextValue}>{children}</OverflowContext.Provider>;
170
+ }
171
+
172
+ // =============================================================================
173
+ // Hook
174
+ // =============================================================================
175
+
176
+ /**
177
+ * Hook to access the overflow context.
178
+ *
179
+ * @returns The overflow context value
180
+ * @throws Error if used outside of an OverflowProvider
181
+ *
182
+ * @example
183
+ * ```tsx
184
+ * function MyComponent() {
185
+ * const { registerOverflow, isOverflowing } = useOverflow();
186
+ *
187
+ * if (isOverflowing('my-id')) {
188
+ * return <Text>Content is overflowing!</Text>;
189
+ * }
190
+ *
191
+ * return <Text>Content fits</Text>;
192
+ * }
193
+ * ```
194
+ */
195
+ export function useOverflow(): OverflowContextValue {
196
+ const context = useContext(OverflowContext);
197
+
198
+ if (context === null) {
199
+ throw new Error("useOverflow must be used within an OverflowProvider");
200
+ }
201
+
202
+ return context;
203
+ }
204
+
205
+ /**
206
+ * Optional hook that returns null instead of throwing when used outside provider.
207
+ * Useful for components that may be used with or without overflow tracking.
208
+ *
209
+ * @returns The overflow context value or null if not within a provider
210
+ */
211
+ export function useOverflowOptional(): OverflowContextValue | null {
212
+ return useContext(OverflowContext);
213
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Rate Limit Context
3
+ *
4
+ * Provides rate limiting state and notifications for the TUI.
5
+ *
6
+ * @module tui/context/RateLimitContext
7
+ */
8
+
9
+ import type { EventBus, RateLimiterConfig } from "@vellum/core";
10
+ import type { JSX } from "react";
11
+ import { createContext, type ReactNode, useCallback, useContext, useMemo, useState } from "react";
12
+ // =============================================================================
13
+ // Types
14
+ // =============================================================================
15
+
16
+ export interface RateLimitState {
17
+ /** Whether rate limiting is currently active */
18
+ isRateLimited: boolean;
19
+ /** Current retry delay in milliseconds */
20
+ retryAfterMs?: number;
21
+ /** Number of retries performed */
22
+ retryCount: number;
23
+ /** Last rate limit error message */
24
+ lastError?: string;
25
+ }
26
+
27
+ export interface RateLimitContextValue {
28
+ /** Current rate limit state */
29
+ state: RateLimitState;
30
+ /** Set rate limited state */
31
+ setRateLimited: (limited: boolean, retryAfterMs?: number) => void;
32
+ /** Increment retry count */
33
+ incrementRetry: () => void;
34
+ /** Reset rate limit state */
35
+ reset: () => void;
36
+ }
37
+
38
+ // =============================================================================
39
+ // Context
40
+ // =============================================================================
41
+
42
+ const defaultState: RateLimitState = {
43
+ isRateLimited: false,
44
+ retryCount: 0,
45
+ };
46
+
47
+ const RateLimitContext = createContext<RateLimitContextValue | null>(null);
48
+
49
+ // =============================================================================
50
+ // Provider
51
+ // =============================================================================
52
+
53
+ export interface RateLimitProviderProps {
54
+ children: ReactNode;
55
+ config?: RateLimiterConfig;
56
+ eventBus?: EventBus;
57
+ }
58
+
59
+ export function RateLimitProvider({
60
+ children,
61
+ config: _config,
62
+ eventBus: _eventBus,
63
+ }: RateLimitProviderProps): JSX.Element {
64
+ const [state, setState] = useState<RateLimitState>(defaultState);
65
+
66
+ const setRateLimited = useCallback((limited: boolean, retryAfterMs?: number) => {
67
+ setState((prev) => ({
68
+ ...prev,
69
+ isRateLimited: limited,
70
+ retryAfterMs: limited ? retryAfterMs : undefined,
71
+ }));
72
+ }, []);
73
+
74
+ const incrementRetry = useCallback(() => {
75
+ setState((prev) => ({
76
+ ...prev,
77
+ retryCount: prev.retryCount + 1,
78
+ }));
79
+ }, []);
80
+
81
+ const reset = useCallback(() => {
82
+ setState(defaultState);
83
+ }, []);
84
+
85
+ const value = useMemo<RateLimitContextValue>(
86
+ () => ({
87
+ state,
88
+ setRateLimited,
89
+ incrementRetry,
90
+ reset,
91
+ }),
92
+ [state, setRateLimited, incrementRetry, reset]
93
+ );
94
+
95
+ return <RateLimitContext.Provider value={value}>{children}</RateLimitContext.Provider>;
96
+ }
97
+
98
+ // =============================================================================
99
+ // Hook
100
+ // =============================================================================
101
+
102
+ export function useRateLimit(): RateLimitContextValue {
103
+ const context = useContext(RateLimitContext);
104
+ if (!context) {
105
+ throw new Error("useRateLimit must be used within a RateLimitProvider");
106
+ }
107
+ return context;
108
+ }
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Resilience Context
3
+ *
4
+ * React context for subscribing to resilience events (rate limiting, retry)
5
+ * and displaying feedback in the TUI.
6
+ *
7
+ * @module tui/context/ResilienceContext
8
+ */
9
+
10
+ import {
11
+ getResilienceEventBus,
12
+ type RateLimitThrottleEvent,
13
+ type ResilienceEventBus,
14
+ type RetryAttemptEvent,
15
+ } from "@vellum/core";
16
+ import React, {
17
+ createContext,
18
+ type ReactNode,
19
+ useCallback,
20
+ useContext,
21
+ useEffect,
22
+ useMemo,
23
+ useState,
24
+ } from "react";
25
+
26
+ // =============================================================================
27
+ // Types
28
+ // =============================================================================
29
+
30
+ /**
31
+ * Active resilience status to display in UI
32
+ */
33
+ export interface ResilienceStatus {
34
+ /** Type of resilience event */
35
+ readonly type: "rate-limit" | "retry" | "idle";
36
+ /** Status message to display */
37
+ readonly message: string;
38
+ /** Wait time in seconds (if applicable) */
39
+ readonly waitSeconds?: number;
40
+ /** Current attempt (for retry) */
41
+ readonly attempt?: number;
42
+ /** Max attempts (for retry) */
43
+ readonly maxAttempts?: number;
44
+ /** Timestamp when status was set */
45
+ readonly timestamp: number;
46
+ }
47
+
48
+ /**
49
+ * Resilience context state
50
+ */
51
+ export interface ResilienceContextState {
52
+ /** Current resilience status */
53
+ readonly status: ResilienceStatus;
54
+ /** Whether feedback is enabled */
55
+ readonly feedbackEnabled: boolean;
56
+ /** Enable/disable feedback */
57
+ readonly setFeedbackEnabled: (enabled: boolean) => void;
58
+ /** Clear current status */
59
+ readonly clearStatus: () => void;
60
+ /** Event bus instance (for advanced usage) */
61
+ readonly eventBus: ResilienceEventBus;
62
+ }
63
+
64
+ /**
65
+ * Props for ResilienceProvider
66
+ */
67
+ export interface ResilienceProviderProps {
68
+ /** Child components */
69
+ readonly children: ReactNode;
70
+ /** Whether feedback is initially enabled (default: true) */
71
+ readonly initialEnabled?: boolean;
72
+ /** Custom event bus instance (optional, uses global by default) */
73
+ readonly eventBus?: ResilienceEventBus;
74
+ /** Auto-clear timeout in milliseconds (default: 5000) */
75
+ readonly autoClearMs?: number;
76
+ }
77
+
78
+ // =============================================================================
79
+ // Context
80
+ // =============================================================================
81
+
82
+ const ResilienceContext = createContext<ResilienceContextState | null>(null);
83
+
84
+ // =============================================================================
85
+ // Constants
86
+ // =============================================================================
87
+
88
+ /** Default idle status */
89
+ const IDLE_STATUS: ResilienceStatus = {
90
+ type: "idle",
91
+ message: "",
92
+ timestamp: 0,
93
+ };
94
+
95
+ /** Default auto-clear timeout */
96
+ const DEFAULT_AUTO_CLEAR_MS = 5000;
97
+
98
+ // =============================================================================
99
+ // Provider Component
100
+ // =============================================================================
101
+
102
+ /**
103
+ * Resilience provider component.
104
+ *
105
+ * Subscribes to resilience events and provides status to child components.
106
+ *
107
+ * @example
108
+ * ```tsx
109
+ * <ResilienceProvider>
110
+ * <App />
111
+ * </ResilienceProvider>
112
+ * ```
113
+ */
114
+ export function ResilienceProvider({
115
+ children,
116
+ initialEnabled = true,
117
+ eventBus: customEventBus,
118
+ autoClearMs = DEFAULT_AUTO_CLEAR_MS,
119
+ }: ResilienceProviderProps): React.JSX.Element {
120
+ const [status, setStatus] = useState<ResilienceStatus>(IDLE_STATUS);
121
+ const [feedbackEnabled, setFeedbackEnabled] = useState(initialEnabled);
122
+
123
+ // Get event bus (custom or global)
124
+ const eventBus = useMemo(() => customEventBus ?? getResilienceEventBus(), [customEventBus]);
125
+
126
+ // Clear status function
127
+ const clearStatus = useCallback(() => {
128
+ setStatus(IDLE_STATUS);
129
+ }, []);
130
+
131
+ // Auto-clear timer
132
+ useEffect(() => {
133
+ if (status.type === "idle" || !feedbackEnabled) {
134
+ return;
135
+ }
136
+
137
+ const timer = setTimeout(() => {
138
+ setStatus(IDLE_STATUS);
139
+ }, autoClearMs);
140
+
141
+ return () => clearTimeout(timer);
142
+ }, [status, feedbackEnabled, autoClearMs]);
143
+
144
+ // Subscribe to rate limit events
145
+ useEffect(() => {
146
+ if (!feedbackEnabled) {
147
+ return;
148
+ }
149
+
150
+ const unsubThrottle = eventBus.on("rateLimitThrottle", (event: RateLimitThrottleEvent) => {
151
+ const waitSeconds = Math.ceil(event.waitTimeMs / 1000);
152
+ setStatus({
153
+ type: "rate-limit",
154
+ message: `Rate limited, waiting ${waitSeconds}s...`,
155
+ waitSeconds,
156
+ timestamp: event.timestamp,
157
+ });
158
+ });
159
+
160
+ const unsubExceeded = eventBus.on("rateLimitExceeded", (event) => {
161
+ const waitSeconds = Math.ceil(event.waitTimeMs / 1000);
162
+ const reason = event.reason === "max_wait" ? "max wait exceeded" : "limit exceeded";
163
+ setStatus({
164
+ type: "rate-limit",
165
+ message: `Rate limit ${reason} (${waitSeconds}s)`,
166
+ waitSeconds,
167
+ timestamp: event.timestamp,
168
+ });
169
+ });
170
+
171
+ return () => {
172
+ unsubThrottle();
173
+ unsubExceeded();
174
+ };
175
+ }, [eventBus, feedbackEnabled]);
176
+
177
+ // Subscribe to retry events
178
+ useEffect(() => {
179
+ if (!feedbackEnabled) {
180
+ return;
181
+ }
182
+
183
+ const unsubAttempt = eventBus.on("retryAttempt", (event: RetryAttemptEvent) => {
184
+ const waitSeconds = Math.ceil(event.delayMs / 1000);
185
+ setStatus({
186
+ type: "retry",
187
+ message: `Retry ${event.attempt}/${event.maxAttempts}, waiting ${waitSeconds}s...`,
188
+ waitSeconds,
189
+ attempt: event.attempt,
190
+ maxAttempts: event.maxAttempts,
191
+ timestamp: event.timestamp,
192
+ });
193
+ });
194
+
195
+ const unsubCompleted = eventBus.on("retryCompleted", (event) => {
196
+ if (event.success) {
197
+ // Clear on success
198
+ setStatus(IDLE_STATUS);
199
+ } else {
200
+ // Show failure briefly
201
+ setStatus({
202
+ type: "retry",
203
+ message: `Retry failed after ${event.totalAttempts} attempts`,
204
+ timestamp: event.timestamp,
205
+ });
206
+ }
207
+ });
208
+
209
+ return () => {
210
+ unsubAttempt();
211
+ unsubCompleted();
212
+ };
213
+ }, [eventBus, feedbackEnabled]);
214
+
215
+ // Build context value
216
+ const value = useMemo<ResilienceContextState>(
217
+ () => ({
218
+ status,
219
+ feedbackEnabled,
220
+ setFeedbackEnabled,
221
+ clearStatus,
222
+ eventBus,
223
+ }),
224
+ [status, feedbackEnabled, clearStatus, eventBus]
225
+ );
226
+
227
+ return <ResilienceContext.Provider value={value}>{children}</ResilienceContext.Provider>;
228
+ }
229
+
230
+ // =============================================================================
231
+ // Hooks
232
+ // =============================================================================
233
+
234
+ /**
235
+ * Hook to access resilience context.
236
+ *
237
+ * @throws Error if used outside ResilienceProvider
238
+ * @returns ResilienceContextState
239
+ */
240
+ export function useResilience(): ResilienceContextState {
241
+ const context = useContext(ResilienceContext);
242
+ if (!context) {
243
+ throw new Error("useResilience must be used within a ResilienceProvider");
244
+ }
245
+ return context;
246
+ }
247
+
248
+ /**
249
+ * Hook to access resilience context optionally.
250
+ *
251
+ * @returns ResilienceContextState or null if outside provider
252
+ */
253
+ export function useResilienceOptional(): ResilienceContextState | null {
254
+ return useContext(ResilienceContext);
255
+ }
256
+
257
+ /**
258
+ * Hook to get current resilience status.
259
+ *
260
+ * @returns Current ResilienceStatus
261
+ */
262
+ export function useResilienceStatus(): ResilienceStatus {
263
+ const context = useResilience();
264
+ return context.status;
265
+ }
266
+
267
+ /**
268
+ * Hook to check if any resilience event is active.
269
+ *
270
+ * @returns true if rate limiting or retry is in progress
271
+ */
272
+ export function useIsResilienceActive(): boolean {
273
+ const context = useResilienceOptional();
274
+ return context?.status.type !== "idle" && context?.status.type !== undefined;
275
+ }