@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.
- package/LICENSE +21 -0
- package/README.md +411 -0
- package/__fixtures__/responses/code-generation.json +42 -0
- package/__fixtures__/responses/error-response.json +20 -0
- package/__fixtures__/responses/hello-world.json +32 -0
- package/dist/auth-6MCXESOH.js +26 -0
- package/dist/chunk-SECXJGWA.js +597 -0
- package/dist/index.js +34023 -0
- package/package.json +67 -0
- package/src/__tests__/commands.e2e.test.ts +728 -0
- package/src/__tests__/credentials.test.ts +713 -0
- package/src/__tests__/mode-e2e.test.ts +391 -0
- package/src/__tests__/tui-integration.test.tsx +1271 -0
- package/src/agents/__tests__/task-persistence.test.ts +235 -0
- package/src/agents/commands/delegate.ts +240 -0
- package/src/agents/commands/index.ts +10 -0
- package/src/agents/commands/resume.ts +335 -0
- package/src/agents/index.ts +29 -0
- package/src/agents/task-persistence.ts +272 -0
- package/src/agents/task-resumption.ts +242 -0
- package/src/app.tsx +4737 -0
- package/src/commands/__tests__/.gitkeep +1 -0
- package/src/commands/__tests__/agents.test.ts +606 -0
- package/src/commands/__tests__/auth.test.ts +626 -0
- package/src/commands/__tests__/autocomplete.test.ts +683 -0
- package/src/commands/__tests__/batch.test.ts +287 -0
- package/src/commands/__tests__/chain-pipe-parser.test.ts +654 -0
- package/src/commands/__tests__/completion.test.ts +238 -0
- package/src/commands/__tests__/core.test.ts +363 -0
- package/src/commands/__tests__/executor.test.ts +496 -0
- package/src/commands/__tests__/exit-codes.test.ts +220 -0
- package/src/commands/__tests__/init.test.ts +243 -0
- package/src/commands/__tests__/language.test.ts +353 -0
- package/src/commands/__tests__/mode-cli.test.ts +667 -0
- package/src/commands/__tests__/model.test.ts +277 -0
- package/src/commands/__tests__/parser.test.ts +493 -0
- package/src/commands/__tests__/performance.bench.ts +380 -0
- package/src/commands/__tests__/registry.test.ts +534 -0
- package/src/commands/__tests__/resume.test.ts +449 -0
- package/src/commands/__tests__/security.test.ts +845 -0
- package/src/commands/__tests__/stream-json.test.ts +372 -0
- package/src/commands/__tests__/user-commands.test.ts +597 -0
- package/src/commands/adapters.ts +267 -0
- package/src/commands/agent.ts +395 -0
- package/src/commands/agents/generate.ts +506 -0
- package/src/commands/agents/index.ts +272 -0
- package/src/commands/agents/show.ts +271 -0
- package/src/commands/agents/validate.ts +387 -0
- package/src/commands/auth.ts +883 -0
- package/src/commands/autocomplete.ts +480 -0
- package/src/commands/batch/command.ts +388 -0
- package/src/commands/batch/executor.ts +361 -0
- package/src/commands/batch/index.ts +12 -0
- package/src/commands/commit.ts +235 -0
- package/src/commands/completion/index.ts +371 -0
- package/src/commands/condense.ts +191 -0
- package/src/commands/config.ts +344 -0
- package/src/commands/context-provider.ts +173 -0
- package/src/commands/copy.ts +329 -0
- package/src/commands/core/clear.ts +38 -0
- package/src/commands/core/exit.ts +43 -0
- package/src/commands/core/help.ts +354 -0
- package/src/commands/core/index.ts +15 -0
- package/src/commands/cost.ts +179 -0
- package/src/commands/credentials.tsx +618 -0
- package/src/commands/custom-agents/__tests__/custom-agents.test.ts +709 -0
- package/src/commands/custom-agents/create.ts +377 -0
- package/src/commands/custom-agents/export.ts +135 -0
- package/src/commands/custom-agents/import.ts +199 -0
- package/src/commands/custom-agents/index.ts +372 -0
- package/src/commands/custom-agents/info.ts +318 -0
- package/src/commands/custom-agents/list.ts +267 -0
- package/src/commands/custom-agents/validate.ts +388 -0
- package/src/commands/diff-mode.ts +241 -0
- package/src/commands/env.ts +53 -0
- package/src/commands/executor.ts +579 -0
- package/src/commands/exit-codes.ts +202 -0
- package/src/commands/index.ts +701 -0
- package/src/commands/init/index.ts +15 -0
- package/src/commands/init/prompts.ts +366 -0
- package/src/commands/init/templates/commands-readme.md +80 -0
- package/src/commands/init/templates/example-command.md +79 -0
- package/src/commands/init/templates/example-skill.md +168 -0
- package/src/commands/init/templates/example-workflow.md +101 -0
- package/src/commands/init/templates/prompts-readme.md +52 -0
- package/src/commands/init/templates/rules-readme.md +63 -0
- package/src/commands/init/templates/skills-readme.md +83 -0
- package/src/commands/init/templates/workflows-readme.md +94 -0
- package/src/commands/init.ts +391 -0
- package/src/commands/install.ts +90 -0
- package/src/commands/language.ts +191 -0
- package/src/commands/loaders/.gitkeep +1 -0
- package/src/commands/lsp.ts +199 -0
- package/src/commands/markdown-commands.ts +253 -0
- package/src/commands/mcp.ts +588 -0
- package/src/commands/memory/export.ts +341 -0
- package/src/commands/memory/index.ts +148 -0
- package/src/commands/memory/list.ts +261 -0
- package/src/commands/memory/search.ts +346 -0
- package/src/commands/memory/utils.ts +15 -0
- package/src/commands/metrics.ts +75 -0
- package/src/commands/migrate/index.ts +16 -0
- package/src/commands/migrate/prompts.ts +477 -0
- package/src/commands/mode.ts +331 -0
- package/src/commands/model.ts +298 -0
- package/src/commands/onboard.ts +205 -0
- package/src/commands/open.ts +169 -0
- package/src/commands/output/stream-json.ts +373 -0
- package/src/commands/parser/chain-parser.ts +370 -0
- package/src/commands/parser/index.ts +29 -0
- package/src/commands/parser/pipe-parser.ts +480 -0
- package/src/commands/parser.ts +588 -0
- package/src/commands/persistence.ts +355 -0
- package/src/commands/progress.ts +18 -0
- package/src/commands/prompt/index.ts +17 -0
- package/src/commands/prompt/validate.ts +621 -0
- package/src/commands/prompt-priority.ts +401 -0
- package/src/commands/registry.ts +374 -0
- package/src/commands/sandbox/index.ts +131 -0
- package/src/commands/security/index.ts +21 -0
- package/src/commands/security/input-sanitizer.ts +168 -0
- package/src/commands/security/permission-checker.ts +456 -0
- package/src/commands/security/sensitive-data.ts +350 -0
- package/src/commands/session/delete.ts +38 -0
- package/src/commands/session/export.ts +39 -0
- package/src/commands/session/index.ts +26 -0
- package/src/commands/session/list.ts +26 -0
- package/src/commands/session/resume.ts +562 -0
- package/src/commands/session/search.ts +434 -0
- package/src/commands/session/show.ts +26 -0
- package/src/commands/settings.ts +368 -0
- package/src/commands/setup.ts +23 -0
- package/src/commands/shell/index.ts +16 -0
- package/src/commands/shell/setup.ts +422 -0
- package/src/commands/shell-init.ts +50 -0
- package/src/commands/shell-integration/index.ts +194 -0
- package/src/commands/skill.ts +1220 -0
- package/src/commands/spec.ts +558 -0
- package/src/commands/status.ts +246 -0
- package/src/commands/theme.ts +211 -0
- package/src/commands/think.ts +551 -0
- package/src/commands/trust.ts +211 -0
- package/src/commands/tutorial.ts +522 -0
- package/src/commands/types.ts +512 -0
- package/src/commands/update.ts +274 -0
- package/src/commands/usage.ts +213 -0
- package/src/commands/user-commands.ts +630 -0
- package/src/commands/utils.ts +142 -0
- package/src/commands/vim.ts +152 -0
- package/src/commands/workflow.ts +257 -0
- package/src/components/header.tsx +25 -0
- package/src/components/input.tsx +25 -0
- package/src/components/message-list.tsx +32 -0
- package/src/components/status-bar.tsx +23 -0
- package/src/index.tsx +614 -0
- package/src/onboarding/__tests__/tutorial.test.ts +740 -0
- package/src/onboarding/index.ts +69 -0
- package/src/onboarding/tips/index.ts +9 -0
- package/src/onboarding/tips/tip-engine.ts +459 -0
- package/src/onboarding/tutorial/index.ts +88 -0
- package/src/onboarding/tutorial/lessons/basics.ts +151 -0
- package/src/onboarding/tutorial/lessons/index.ts +151 -0
- package/src/onboarding/tutorial/lessons/modes.ts +230 -0
- package/src/onboarding/tutorial/lessons/tools.ts +172 -0
- package/src/onboarding/tutorial/progress-tracker.ts +350 -0
- package/src/onboarding/tutorial/storage.ts +249 -0
- package/src/onboarding/tutorial/tutorial-system.ts +462 -0
- package/src/onboarding/tutorial/types.ts +310 -0
- package/src/orchestrator-singleton.ts +129 -0
- package/src/shutdown.ts +33 -0
- package/src/test/e2e/assertions.ts +267 -0
- package/src/test/e2e/fixtures.ts +204 -0
- package/src/test/e2e/harness.ts +575 -0
- package/src/test/e2e/index.ts +57 -0
- package/src/test/e2e/types.ts +228 -0
- package/src/test/fixtures/__tests__/fake-response-loader.test.ts +314 -0
- package/src/test/fixtures/fake-response-loader.ts +314 -0
- package/src/test/fixtures/index.ts +20 -0
- package/src/tui/__tests__/mcp-panel.test.tsx +82 -0
- package/src/tui/__tests__/mcp-wiring.test.tsx +78 -0
- package/src/tui/__tests__/mode-components.test.tsx +395 -0
- package/src/tui/__tests__/permission-ask-flow.test.tsx +138 -0
- package/src/tui/__tests__/sidebar-panel-data.test.tsx +148 -0
- package/src/tui/__tests__/tools-panel-hotkeys.test.tsx +41 -0
- package/src/tui/adapters/agent-adapter.ts +1008 -0
- package/src/tui/adapters/index.ts +48 -0
- package/src/tui/adapters/message-adapter.ts +315 -0
- package/src/tui/adapters/persistence-bridge.ts +331 -0
- package/src/tui/adapters/session-adapter.ts +419 -0
- package/src/tui/buffered-stdout.ts +223 -0
- package/src/tui/components/AgentProgress.tsx +424 -0
- package/src/tui/components/Banner/AsciiArt.ts +160 -0
- package/src/tui/components/Banner/Banner.tsx +355 -0
- package/src/tui/components/Banner/ShimmerContext.tsx +131 -0
- package/src/tui/components/Banner/ShimmerText.tsx +193 -0
- package/src/tui/components/Banner/TypeWriterGradient.tsx +321 -0
- package/src/tui/components/Banner/index.ts +61 -0
- package/src/tui/components/Banner/useShimmer.ts +241 -0
- package/src/tui/components/ChatView.tsx +11 -0
- package/src/tui/components/Checkpoint/CheckpointDiffView.tsx +371 -0
- package/src/tui/components/Checkpoint/SnapshotCheckpointPanel.tsx +440 -0
- package/src/tui/components/Checkpoint/index.ts +19 -0
- package/src/tui/components/CostDisplay.tsx +226 -0
- package/src/tui/components/InitErrorBanner.tsx +122 -0
- package/src/tui/components/Input/Autocomplete.tsx +603 -0
- package/src/tui/components/Input/EnhancedCommandInput.tsx +471 -0
- package/src/tui/components/Input/HighlightedText.tsx +236 -0
- package/src/tui/components/Input/MentionAutocomplete.tsx +375 -0
- package/src/tui/components/Input/TextInput.tsx +1002 -0
- package/src/tui/components/Input/__tests__/Autocomplete.test.tsx +374 -0
- package/src/tui/components/Input/__tests__/TextInput.test.tsx +241 -0
- package/src/tui/components/Input/__tests__/highlight.test.ts +219 -0
- package/src/tui/components/Input/__tests__/slash-command-utils.test.ts +104 -0
- package/src/tui/components/Input/highlight.ts +362 -0
- package/src/tui/components/Input/index.ts +36 -0
- package/src/tui/components/Input/slash-command-utils.ts +135 -0
- package/src/tui/components/Layout.tsx +432 -0
- package/src/tui/components/McpPanel.tsx +137 -0
- package/src/tui/components/MemoryPanel.tsx +448 -0
- package/src/tui/components/Messages/CodeBlock.tsx +527 -0
- package/src/tui/components/Messages/DiffView.tsx +679 -0
- package/src/tui/components/Messages/ImageReference.tsx +89 -0
- package/src/tui/components/Messages/MarkdownBlock.tsx +228 -0
- package/src/tui/components/Messages/MarkdownRenderer.tsx +498 -0
- package/src/tui/components/Messages/MessageBubble.tsx +270 -0
- package/src/tui/components/Messages/MessageList.tsx +1719 -0
- package/src/tui/components/Messages/StreamingText.tsx +216 -0
- package/src/tui/components/Messages/ThinkingBlock.tsx +408 -0
- package/src/tui/components/Messages/ToolResultPreview.tsx +243 -0
- package/src/tui/components/Messages/__tests__/CodeBlock.test.tsx +296 -0
- package/src/tui/components/Messages/__tests__/DiffView.test.tsx +239 -0
- package/src/tui/components/Messages/__tests__/MarkdownRenderer.test.tsx +303 -0
- package/src/tui/components/Messages/__tests__/MessageBubble.test.tsx +268 -0
- package/src/tui/components/Messages/__tests__/MessageList.test.tsx +324 -0
- package/src/tui/components/Messages/__tests__/StreamingText.test.tsx +215 -0
- package/src/tui/components/Messages/index.ts +25 -0
- package/src/tui/components/ModeIndicator.tsx +177 -0
- package/src/tui/components/ModeSelector.tsx +216 -0
- package/src/tui/components/ModelSelector.tsx +339 -0
- package/src/tui/components/OnboardingWizard.tsx +670 -0
- package/src/tui/components/PhaseProgressIndicator.tsx +270 -0
- package/src/tui/components/RateLimitIndicator.tsx +82 -0
- package/src/tui/components/ScreenReaderLayout.tsx +295 -0
- package/src/tui/components/SettingsPanel.tsx +643 -0
- package/src/tui/components/Sidebar/SystemStatusPanel.tsx +284 -0
- package/src/tui/components/Sidebar/index.ts +9 -0
- package/src/tui/components/Status/ModelStatusBar.tsx +270 -0
- package/src/tui/components/Status/index.ts +12 -0
- package/src/tui/components/StatusBar/AgentModeIndicator.tsx +257 -0
- package/src/tui/components/StatusBar/ContextProgress.tsx +167 -0
- package/src/tui/components/StatusBar/FileChangesIndicator.tsx +62 -0
- package/src/tui/components/StatusBar/GitIndicator.tsx +89 -0
- package/src/tui/components/StatusBar/HeaderBar.tsx +126 -0
- package/src/tui/components/StatusBar/ModelIndicator.tsx +157 -0
- package/src/tui/components/StatusBar/PersistenceStatusIndicator.tsx +210 -0
- package/src/tui/components/StatusBar/ResilienceIndicator.tsx +106 -0
- package/src/tui/components/StatusBar/SandboxIndicator.tsx +167 -0
- package/src/tui/components/StatusBar/StatusBar.tsx +368 -0
- package/src/tui/components/StatusBar/ThinkingModeIndicator.tsx +170 -0
- package/src/tui/components/StatusBar/TokenBreakdown.tsx +246 -0
- package/src/tui/components/StatusBar/TokenCounter.tsx +135 -0
- package/src/tui/components/StatusBar/TrustModeIndicator.tsx +130 -0
- package/src/tui/components/StatusBar/WorkspaceIndicator.tsx +86 -0
- package/src/tui/components/StatusBar/__tests__/AgentModeIndicator.test.tsx +193 -0
- package/src/tui/components/StatusBar/__tests__/StatusBar.test.tsx +729 -0
- package/src/tui/components/StatusBar/index.ts +60 -0
- package/src/tui/components/TipBanner.tsx +115 -0
- package/src/tui/components/TodoItem.tsx +208 -0
- package/src/tui/components/TodoPanel.tsx +455 -0
- package/src/tui/components/Tools/ApprovalQueue.tsx +407 -0
- package/src/tui/components/Tools/OptionSelector.tsx +160 -0
- package/src/tui/components/Tools/PermissionDialog.tsx +286 -0
- package/src/tui/components/Tools/ToolParams.tsx +483 -0
- package/src/tui/components/Tools/ToolsPanel.tsx +178 -0
- package/src/tui/components/Tools/__tests__/PermissionDialog.test.tsx +510 -0
- package/src/tui/components/Tools/__tests__/ToolParams.test.tsx +432 -0
- package/src/tui/components/Tools/index.ts +21 -0
- package/src/tui/components/TrustPrompt.tsx +279 -0
- package/src/tui/components/UpdateBanner.tsx +166 -0
- package/src/tui/components/VimModeIndicator.tsx +112 -0
- package/src/tui/components/backtrack/BacktrackControls.tsx +402 -0
- package/src/tui/components/backtrack/index.ts +13 -0
- package/src/tui/components/common/AutoApprovalStatus.tsx +251 -0
- package/src/tui/components/common/CostWarning.tsx +294 -0
- package/src/tui/components/common/DynamicShortcutHints.tsx +209 -0
- package/src/tui/components/common/EnhancedLoadingIndicator.tsx +305 -0
- package/src/tui/components/common/ErrorBoundary.tsx +140 -0
- package/src/tui/components/common/GradientText.tsx +224 -0
- package/src/tui/components/common/HotkeyHelpModal.tsx +193 -0
- package/src/tui/components/common/HotkeyHints.tsx +70 -0
- package/src/tui/components/common/MaxSizedBox.tsx +354 -0
- package/src/tui/components/common/NewMessagesBadge.tsx +65 -0
- package/src/tui/components/common/ProtectedFileLegend.tsx +89 -0
- package/src/tui/components/common/ScrollIndicator.tsx +160 -0
- package/src/tui/components/common/Spinner.tsx +342 -0
- package/src/tui/components/common/StreamingIndicator.tsx +316 -0
- package/src/tui/components/common/VirtualizedList/VirtualizedList.tsx +428 -0
- package/src/tui/components/common/VirtualizedList/hooks/index.ts +19 -0
- package/src/tui/components/common/VirtualizedList/hooks/useBatchedScroll.ts +64 -0
- package/src/tui/components/common/VirtualizedList/hooks/useScrollAnchor.ts +290 -0
- package/src/tui/components/common/VirtualizedList/hooks/useVirtualization.ts +340 -0
- package/src/tui/components/common/VirtualizedList/index.ts +30 -0
- package/src/tui/components/common/VirtualizedList/types.ts +107 -0
- package/src/tui/components/common/__tests__/NewMessagesBadge.test.tsx +74 -0
- package/src/tui/components/common/__tests__/ScrollIndicator.test.tsx +193 -0
- package/src/tui/components/common/index.ts +110 -0
- package/src/tui/components/index.ts +79 -0
- package/src/tui/components/session/CheckpointPanel.tsx +323 -0
- package/src/tui/components/session/RollbackDialog.tsx +169 -0
- package/src/tui/components/session/SessionItem.tsx +136 -0
- package/src/tui/components/session/SessionListPanel.tsx +252 -0
- package/src/tui/components/session/SessionPicker.tsx +449 -0
- package/src/tui/components/session/SessionPreview.tsx +240 -0
- package/src/tui/components/session/__tests__/session.test.tsx +408 -0
- package/src/tui/components/session/index.ts +28 -0
- package/src/tui/components/session/types.ts +116 -0
- package/src/tui/components/theme/__tests__/tokens.test.ts +471 -0
- package/src/tui/components/theme/index.ts +227 -0
- package/src/tui/components/theme/tokens.ts +484 -0
- package/src/tui/config/defaults.ts +134 -0
- package/src/tui/config/index.ts +17 -0
- package/src/tui/context/AnimationContext.tsx +284 -0
- package/src/tui/context/AppContext.tsx +349 -0
- package/src/tui/context/BracketedPasteContext.tsx +372 -0
- package/src/tui/context/LspContext.tsx +192 -0
- package/src/tui/context/McpContext.tsx +325 -0
- package/src/tui/context/MessagesContext.tsx +870 -0
- package/src/tui/context/OverflowContext.tsx +213 -0
- package/src/tui/context/RateLimitContext.tsx +108 -0
- package/src/tui/context/ResilienceContext.tsx +275 -0
- package/src/tui/context/RootProvider.tsx +136 -0
- package/src/tui/context/ScrollContext.tsx +331 -0
- package/src/tui/context/ToolsContext.tsx +702 -0
- package/src/tui/context/__tests__/BracketedPasteContext.test.tsx +416 -0
- package/src/tui/context/index.ts +140 -0
- package/src/tui/enterprise-integration.ts +282 -0
- package/src/tui/hooks/__tests__/useBacktrack.test.tsx +138 -0
- package/src/tui/hooks/__tests__/useBracketedPaste.test.tsx +222 -0
- package/src/tui/hooks/__tests__/useCopyMode.test.tsx +336 -0
- package/src/tui/hooks/__tests__/useHotkeys.ctrl-input.test.tsx +96 -0
- package/src/tui/hooks/__tests__/useHotkeys.test.tsx +454 -0
- package/src/tui/hooks/__tests__/useInputHistory.test.tsx +660 -0
- package/src/tui/hooks/__tests__/useLineBuffer.test.ts +295 -0
- package/src/tui/hooks/__tests__/useModeController.test.ts +137 -0
- package/src/tui/hooks/__tests__/useModeShortcuts.test.tsx +142 -0
- package/src/tui/hooks/__tests__/useScrollController.test.ts +464 -0
- package/src/tui/hooks/__tests__/useVim.test.tsx +531 -0
- package/src/tui/hooks/index.ts +252 -0
- package/src/tui/hooks/useAgentLoop.ts +712 -0
- package/src/tui/hooks/useAlternateBuffer.ts +398 -0
- package/src/tui/hooks/useAnimatedScrollbar.ts +241 -0
- package/src/tui/hooks/useBacktrack.ts +443 -0
- package/src/tui/hooks/useBracketedPaste.ts +104 -0
- package/src/tui/hooks/useCollapsible.ts +240 -0
- package/src/tui/hooks/useCopyMode.ts +382 -0
- package/src/tui/hooks/useCostSummary.ts +75 -0
- package/src/tui/hooks/useDesktopNotification.ts +414 -0
- package/src/tui/hooks/useDiffMode.ts +44 -0
- package/src/tui/hooks/useFileChangeStats.ts +110 -0
- package/src/tui/hooks/useFileSuggestions.ts +284 -0
- package/src/tui/hooks/useFlickerDetector.ts +250 -0
- package/src/tui/hooks/useGitStatus.ts +200 -0
- package/src/tui/hooks/useHotkeys.ts +579 -0
- package/src/tui/hooks/useImagePaste.ts +114 -0
- package/src/tui/hooks/useInputHighlight.ts +145 -0
- package/src/tui/hooks/useInputHistory.ts +246 -0
- package/src/tui/hooks/useKeyboardScroll.ts +209 -0
- package/src/tui/hooks/useLineBuffer.ts +356 -0
- package/src/tui/hooks/useMentionAutocomplete.ts +235 -0
- package/src/tui/hooks/useModeController.ts +167 -0
- package/src/tui/hooks/useModeShortcuts.ts +196 -0
- package/src/tui/hooks/usePermissionHandler.ts +146 -0
- package/src/tui/hooks/usePersistence.ts +480 -0
- package/src/tui/hooks/usePersistenceShortcuts.ts +225 -0
- package/src/tui/hooks/usePlaceholderRotation.ts +143 -0
- package/src/tui/hooks/useProviderStatus.ts +270 -0
- package/src/tui/hooks/useRateLimitStatus.ts +90 -0
- package/src/tui/hooks/useScreenReader.ts +315 -0
- package/src/tui/hooks/useScrollController.ts +450 -0
- package/src/tui/hooks/useScrollEventBatcher.ts +185 -0
- package/src/tui/hooks/useSidebarPanelData.ts +115 -0
- package/src/tui/hooks/useSmoothScroll.ts +202 -0
- package/src/tui/hooks/useSnapshots.ts +300 -0
- package/src/tui/hooks/useStateAndRef.ts +50 -0
- package/src/tui/hooks/useTerminalSize.ts +206 -0
- package/src/tui/hooks/useToolApprovalController.ts +91 -0
- package/src/tui/hooks/useVim.ts +334 -0
- package/src/tui/hooks/useWorkspace.ts +56 -0
- package/src/tui/i18n/__tests__/init.test.ts +278 -0
- package/src/tui/i18n/__tests__/language-config.test.ts +199 -0
- package/src/tui/i18n/__tests__/locale-detection.test.ts +250 -0
- package/src/tui/i18n/__tests__/settings-integration.test.ts +262 -0
- package/src/tui/i18n/index.ts +72 -0
- package/src/tui/i18n/init.ts +131 -0
- package/src/tui/i18n/language-config.ts +106 -0
- package/src/tui/i18n/locale-detection.ts +173 -0
- package/src/tui/i18n/settings-integration.ts +557 -0
- package/src/tui/i18n/tui-namespace.ts +538 -0
- package/src/tui/i18n/types.ts +312 -0
- package/src/tui/index.ts +43 -0
- package/src/tui/lsp-integration.ts +409 -0
- package/src/tui/metrics-integration.ts +366 -0
- package/src/tui/plugins.ts +383 -0
- package/src/tui/resilience.ts +342 -0
- package/src/tui/sandbox-integration.ts +317 -0
- package/src/tui/services/clipboard.ts +348 -0
- package/src/tui/services/fuzzy-search.ts +441 -0
- package/src/tui/services/index.ts +72 -0
- package/src/tui/services/markdown-renderer.ts +565 -0
- package/src/tui/services/open-external.ts +247 -0
- package/src/tui/services/syntax-highlighter.ts +483 -0
- package/src/tui/slash-commands.ts +12 -0
- package/src/tui/theme/index.ts +15 -0
- package/src/tui/theme/provider.tsx +206 -0
- package/src/tui/tip-integration.ts +300 -0
- package/src/tui/types/__tests__/ink-extended.test.ts +121 -0
- package/src/tui/types/ink-extended.ts +87 -0
- package/src/tui/utils/__tests__/bracketedPaste.test.ts +231 -0
- package/src/tui/utils/__tests__/heightEstimator.test.ts +157 -0
- package/src/tui/utils/__tests__/text-width.test.ts +158 -0
- package/src/tui/utils/__tests__/textSanitizer.test.ts +266 -0
- package/src/tui/utils/__tests__/ui-sizing.test.ts +169 -0
- package/src/tui/utils/bracketedPaste.ts +107 -0
- package/src/tui/utils/cursor-manager.ts +131 -0
- package/src/tui/utils/detectTerminal.ts +596 -0
- package/src/tui/utils/findLastSafeSplitPoint.ts +92 -0
- package/src/tui/utils/heightEstimator.ts +198 -0
- package/src/tui/utils/index.ts +91 -0
- package/src/tui/utils/isNarrowWidth.ts +52 -0
- package/src/tui/utils/stdoutGuard.ts +90 -0
- package/src/tui/utils/synchronized-update.ts +70 -0
- package/src/tui/utils/text-width.ts +225 -0
- package/src/tui/utils/textSanitizer.ts +225 -0
- package/src/tui/utils/textUtils.ts +114 -0
- package/src/tui/utils/ui-sizing.ts +192 -0
- package/src/tui-blessed/app.ts +160 -0
- package/src/tui-blessed/index.ts +2 -0
- package/src/tui-blessed/neo-blessed.d.ts +6 -0
- package/src/tui-blessed/test.ts +21 -0
- package/src/tui-blessed/types.ts +14 -0
- package/src/utils/icons.ts +130 -0
- package/src/utils/index.ts +33 -0
- package/src/utils/resume-hint.ts +86 -0
- package/src/version.ts +1 -0
- package/tsconfig.json +8 -0
- package/vitest.config.ts +35 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FakeResponseLoader - Load and manage fake API responses for testing
|
|
3
|
+
*
|
|
4
|
+
* This module provides infrastructure for loading and managing mock API responses
|
|
5
|
+
* during E2E and integration testing. It enables deterministic testing without
|
|
6
|
+
* making actual API calls.
|
|
7
|
+
*
|
|
8
|
+
* @module cli/test/fixtures/fake-response-loader
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
12
|
+
import { join, resolve } from "node:path";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Supported stream event types for mock responses
|
|
16
|
+
*/
|
|
17
|
+
export type MockEventType =
|
|
18
|
+
| "text"
|
|
19
|
+
| "reasoning"
|
|
20
|
+
| "tool_call_start"
|
|
21
|
+
| "tool_call_delta"
|
|
22
|
+
| "tool_call_end"
|
|
23
|
+
| "usage"
|
|
24
|
+
| "end"
|
|
25
|
+
| "error";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Mock stream event structure
|
|
29
|
+
*/
|
|
30
|
+
export interface MockStreamEvent {
|
|
31
|
+
type: MockEventType;
|
|
32
|
+
content?: string;
|
|
33
|
+
toolCallId?: string;
|
|
34
|
+
toolName?: string;
|
|
35
|
+
arguments?: string;
|
|
36
|
+
stopReason?: string;
|
|
37
|
+
usage?: {
|
|
38
|
+
inputTokens: number;
|
|
39
|
+
outputTokens: number;
|
|
40
|
+
};
|
|
41
|
+
error?: {
|
|
42
|
+
code: string;
|
|
43
|
+
message: string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Mock response fixture structure
|
|
49
|
+
*/
|
|
50
|
+
export interface MockResponse {
|
|
51
|
+
/** Unique identifier for this response fixture */
|
|
52
|
+
id: string;
|
|
53
|
+
/** Pattern to match against prompts */
|
|
54
|
+
promptPattern: string;
|
|
55
|
+
/** Whether the pattern is a regex (default: false) */
|
|
56
|
+
isRegex?: boolean;
|
|
57
|
+
/** Description of what this fixture tests */
|
|
58
|
+
description?: string;
|
|
59
|
+
/** Delay in milliseconds between events (simulates streaming) */
|
|
60
|
+
streamDelay?: number;
|
|
61
|
+
/** The mock events to return */
|
|
62
|
+
events: MockStreamEvent[];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Environment variable to enable fake responses mode
|
|
67
|
+
*/
|
|
68
|
+
export const FAKE_RESPONSES_ENV = "VELLUM_FAKE_RESPONSES";
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Environment variable for custom fixtures directory
|
|
72
|
+
*/
|
|
73
|
+
export const FIXTURES_DIR_ENV = "VELLUM_FIXTURES_DIR";
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Default fixtures directory relative to package root
|
|
77
|
+
*/
|
|
78
|
+
export const DEFAULT_FIXTURES_DIR = "__fixtures__/responses";
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* FakeResponseLoader - Load and manage fake API responses for testing
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const loader = new FakeResponseLoader();
|
|
86
|
+
* const response = loader.getResponse("Hello, world");
|
|
87
|
+
* if (response) {
|
|
88
|
+
* for (const event of response.events) {
|
|
89
|
+
* // Process mock events
|
|
90
|
+
* }
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export class FakeResponseLoader {
|
|
95
|
+
private fixtures: Map<string, MockResponse>;
|
|
96
|
+
private readonly fixturesDir: string;
|
|
97
|
+
private loaded = false;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Create a new FakeResponseLoader
|
|
101
|
+
*
|
|
102
|
+
* @param fixturesDir - Custom directory for fixtures (optional)
|
|
103
|
+
*/
|
|
104
|
+
constructor(fixturesDir?: string) {
|
|
105
|
+
this.fixtures = new Map();
|
|
106
|
+
this.fixturesDir = fixturesDir ?? this.resolveDefaultFixturesDir();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Resolve the default fixtures directory
|
|
111
|
+
*/
|
|
112
|
+
private resolveDefaultFixturesDir(): string {
|
|
113
|
+
// Check environment variable first
|
|
114
|
+
const envDir = process.env[FIXTURES_DIR_ENV];
|
|
115
|
+
if (envDir) {
|
|
116
|
+
return resolve(envDir);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Default to package __fixtures__ directory
|
|
120
|
+
// Navigate from src/test/fixtures to package root
|
|
121
|
+
return resolve(__dirname, "../../..", DEFAULT_FIXTURES_DIR);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Load a single fixture from file
|
|
126
|
+
*
|
|
127
|
+
* @param name - Fixture filename (without .json extension)
|
|
128
|
+
* @returns The loaded fixture or null if not found
|
|
129
|
+
*/
|
|
130
|
+
load(name: string): MockResponse | null {
|
|
131
|
+
const filename = name.endsWith(".json") ? name : `${name}.json`;
|
|
132
|
+
const filepath = join(this.fixturesDir, filename);
|
|
133
|
+
|
|
134
|
+
if (!existsSync(filepath)) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
const content = readFileSync(filepath, "utf-8");
|
|
140
|
+
const fixture = JSON.parse(content) as MockResponse;
|
|
141
|
+
|
|
142
|
+
// Ensure fixture has an ID
|
|
143
|
+
if (!fixture.id) {
|
|
144
|
+
fixture.id = name.replace(/\.json$/, "");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Cache the fixture
|
|
148
|
+
this.fixtures.set(fixture.id, fixture);
|
|
149
|
+
|
|
150
|
+
return fixture;
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.error(`Failed to load fixture ${name}:`, error);
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Load all fixtures from the fixtures directory
|
|
159
|
+
*/
|
|
160
|
+
loadAll(): void {
|
|
161
|
+
if (this.loaded) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (!existsSync(this.fixturesDir)) {
|
|
166
|
+
console.warn(`Fixtures directory not found: ${this.fixturesDir}`);
|
|
167
|
+
this.loaded = true;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
const files = readdirSync(this.fixturesDir).filter((f) => f.endsWith(".json"));
|
|
173
|
+
|
|
174
|
+
for (const file of files) {
|
|
175
|
+
this.load(file);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
this.loaded = true;
|
|
179
|
+
} catch (error) {
|
|
180
|
+
console.error("Failed to load fixtures:", error);
|
|
181
|
+
this.loaded = true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Get a response matching a prompt pattern
|
|
187
|
+
*
|
|
188
|
+
* @param prompt - The prompt to match against
|
|
189
|
+
* @returns Matching response or null if no match found
|
|
190
|
+
*/
|
|
191
|
+
getResponse(prompt: string): MockResponse | null {
|
|
192
|
+
// Ensure all fixtures are loaded
|
|
193
|
+
this.loadAll();
|
|
194
|
+
|
|
195
|
+
// Search through fixtures for a match
|
|
196
|
+
for (const fixture of this.fixtures.values()) {
|
|
197
|
+
if (this.matchesPattern(prompt, fixture)) {
|
|
198
|
+
return fixture;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Check if a prompt matches a fixture's pattern
|
|
207
|
+
*/
|
|
208
|
+
private matchesPattern(prompt: string, fixture: MockResponse): boolean {
|
|
209
|
+
const pattern = fixture.promptPattern;
|
|
210
|
+
|
|
211
|
+
if (fixture.isRegex) {
|
|
212
|
+
try {
|
|
213
|
+
const regex = new RegExp(pattern, "i");
|
|
214
|
+
return regex.test(prompt);
|
|
215
|
+
} catch {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Simple substring match (case-insensitive)
|
|
221
|
+
return prompt.toLowerCase().includes(pattern.toLowerCase());
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Get a fixture by ID
|
|
226
|
+
*
|
|
227
|
+
* @param id - The fixture ID
|
|
228
|
+
* @returns The fixture or null if not found
|
|
229
|
+
*/
|
|
230
|
+
getById(id: string): MockResponse | null {
|
|
231
|
+
// Try cache first
|
|
232
|
+
if (this.fixtures.has(id)) {
|
|
233
|
+
return this.fixtures.get(id) ?? null;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Try loading by name
|
|
237
|
+
return this.load(id);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Get all loaded fixtures
|
|
242
|
+
*/
|
|
243
|
+
getAll(): MockResponse[] {
|
|
244
|
+
this.loadAll();
|
|
245
|
+
return Array.from(this.fixtures.values());
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Clear all cached fixtures
|
|
250
|
+
*/
|
|
251
|
+
clear(): void {
|
|
252
|
+
this.fixtures.clear();
|
|
253
|
+
this.loaded = false;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Get the fixtures directory path
|
|
258
|
+
*/
|
|
259
|
+
getFixturesDir(): string {
|
|
260
|
+
return this.fixturesDir;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Check if fake responses mode is enabled
|
|
265
|
+
*
|
|
266
|
+
* @returns true if VELLUM_FAKE_RESPONSES env var is set to 'true' or '1'
|
|
267
|
+
*/
|
|
268
|
+
static isEnabled(): boolean {
|
|
269
|
+
const value = process.env[FAKE_RESPONSES_ENV];
|
|
270
|
+
return value === "true" || value === "1";
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Create a stream from a mock response
|
|
275
|
+
*
|
|
276
|
+
* @param response - The mock response to stream
|
|
277
|
+
* @returns AsyncIterable of mock stream events
|
|
278
|
+
*/
|
|
279
|
+
static async *createStream(response: MockResponse): AsyncIterable<MockStreamEvent> {
|
|
280
|
+
const delay = response.streamDelay ?? 0;
|
|
281
|
+
|
|
282
|
+
for (const event of response.events) {
|
|
283
|
+
if (delay > 0) {
|
|
284
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
285
|
+
}
|
|
286
|
+
yield event;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Global singleton instance for convenience
|
|
293
|
+
*/
|
|
294
|
+
let globalLoader: FakeResponseLoader | null = null;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Get the global FakeResponseLoader instance
|
|
298
|
+
*
|
|
299
|
+
* @returns The global loader instance
|
|
300
|
+
*/
|
|
301
|
+
export function getFakeResponseLoader(): FakeResponseLoader {
|
|
302
|
+
if (!globalLoader) {
|
|
303
|
+
globalLoader = new FakeResponseLoader();
|
|
304
|
+
}
|
|
305
|
+
return globalLoader;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Reset the global loader instance (useful for tests)
|
|
310
|
+
*/
|
|
311
|
+
export function resetFakeResponseLoader(): void {
|
|
312
|
+
globalLoader?.clear();
|
|
313
|
+
globalLoader = null;
|
|
314
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Fixtures Module
|
|
3
|
+
*
|
|
4
|
+
* Exports for test fixture utilities including the FakeResponseLoader
|
|
5
|
+
* for mocking API responses in E2E and integration tests.
|
|
6
|
+
*
|
|
7
|
+
* @module cli/test/fixtures
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
DEFAULT_FIXTURES_DIR,
|
|
12
|
+
FAKE_RESPONSES_ENV,
|
|
13
|
+
FakeResponseLoader,
|
|
14
|
+
FIXTURES_DIR_ENV,
|
|
15
|
+
getFakeResponseLoader,
|
|
16
|
+
type MockEventType,
|
|
17
|
+
type MockResponse,
|
|
18
|
+
type MockStreamEvent,
|
|
19
|
+
resetFakeResponseLoader,
|
|
20
|
+
} from "./fake-response-loader.js";
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP panel render tests
|
|
3
|
+
*
|
|
4
|
+
* Verifies basic read-only status output for the MCP sidebar panel.
|
|
5
|
+
*
|
|
6
|
+
* @vitest-environment node
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { createToolRegistry, type ToolExecutor } from "@vellum/core";
|
|
10
|
+
import { render } from "ink-testing-library";
|
|
11
|
+
import { act } from "react";
|
|
12
|
+
import { describe, expect, it, vi } from "vitest";
|
|
13
|
+
|
|
14
|
+
let mockConnections: Array<{ server: { name: string; statusInfo: unknown } }> = [];
|
|
15
|
+
|
|
16
|
+
vi.mock("@vellum/mcp", () => {
|
|
17
|
+
class MockMcpHub {
|
|
18
|
+
public connections = mockConnections as unknown[];
|
|
19
|
+
|
|
20
|
+
async initialize(): Promise<void> {}
|
|
21
|
+
|
|
22
|
+
async dispose(): Promise<void> {}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
McpHub: MockMcpHub,
|
|
27
|
+
createOAuthCredentialAdapter: vi.fn(),
|
|
28
|
+
getProcessManager: () => ({
|
|
29
|
+
onCleanup: vi.fn(),
|
|
30
|
+
}),
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("McpPanel", () => {
|
|
35
|
+
it("renders server count and MCP tool count", async () => {
|
|
36
|
+
const { RootProvider, McpPanel } = await import("../index.js");
|
|
37
|
+
|
|
38
|
+
const registry = createToolRegistry();
|
|
39
|
+
|
|
40
|
+
registry.registerMcpTool(
|
|
41
|
+
"c1a2b3",
|
|
42
|
+
{
|
|
43
|
+
name: "ping",
|
|
44
|
+
description: "Ping",
|
|
45
|
+
inputSchema: { type: "object", properties: {} },
|
|
46
|
+
},
|
|
47
|
+
async () => "ok"
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const executor: ToolExecutor = {
|
|
51
|
+
registerTool: vi.fn(),
|
|
52
|
+
} as unknown as ToolExecutor;
|
|
53
|
+
|
|
54
|
+
mockConnections = [
|
|
55
|
+
{ server: { name: "Server A", statusInfo: { status: "connected" } } },
|
|
56
|
+
{ server: { name: "Server B", statusInfo: { status: "failed", error: "boom" } } },
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
const { lastFrame } = render(
|
|
60
|
+
<RootProvider theme="dark" toolRegistry={registry} toolExecutor={executor}>
|
|
61
|
+
<McpPanel isFocused={true} toolRegistry={registry} />
|
|
62
|
+
</RootProvider>
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
await act(async () => {
|
|
66
|
+
await Promise.resolve();
|
|
67
|
+
await Promise.resolve();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const frame = lastFrame() ?? "";
|
|
71
|
+
|
|
72
|
+
expect(frame).toContain("MCP");
|
|
73
|
+
expect(frame).toContain("Servers: 2");
|
|
74
|
+
expect(frame).toContain("MCP tools registered: 1");
|
|
75
|
+
expect(frame).toContain("Last error:");
|
|
76
|
+
|
|
77
|
+
// Footer hotkey hints (Alt primary)
|
|
78
|
+
expect(frame).toContain("Alt+K");
|
|
79
|
+
expect(frame).toContain("Alt+O");
|
|
80
|
+
expect(frame).toContain("MCP");
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP wiring tests
|
|
3
|
+
*
|
|
4
|
+
* Ensures that the TUI-level McpProvider (via RootProvider) receives the shared
|
|
5
|
+
* ToolRegistry and ToolExecutor so MCP tools are registered into the same
|
|
6
|
+
* running tool system as the agent.
|
|
7
|
+
*
|
|
8
|
+
* @vitest-environment node
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { createToolRegistry, type ToolExecutor, type ToolRegistry } from "@vellum/core";
|
|
12
|
+
import { Text } from "ink";
|
|
13
|
+
import { render } from "ink-testing-library";
|
|
14
|
+
import { act } from "react";
|
|
15
|
+
import { describe, expect, it, vi } from "vitest";
|
|
16
|
+
|
|
17
|
+
let lastMcpHubOptions: Record<string, unknown> | null = null;
|
|
18
|
+
|
|
19
|
+
vi.mock("@vellum/mcp", () => {
|
|
20
|
+
class MockMcpHub {
|
|
21
|
+
public connections: unknown[] = [];
|
|
22
|
+
|
|
23
|
+
constructor(options: Record<string, unknown>) {
|
|
24
|
+
lastMcpHubOptions = options;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async initialize(): Promise<void> {}
|
|
28
|
+
|
|
29
|
+
async dispose(): Promise<void> {}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
McpHub: MockMcpHub,
|
|
34
|
+
createOAuthCredentialAdapter: vi.fn(),
|
|
35
|
+
getProcessManager: () => ({
|
|
36
|
+
onCleanup: vi.fn(),
|
|
37
|
+
}),
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe("MCP wiring", () => {
|
|
42
|
+
it("passes shared ToolRegistry and ToolExecutor into McpHub", async () => {
|
|
43
|
+
const { RootProvider } = await import("../index.js");
|
|
44
|
+
|
|
45
|
+
const registry: ToolRegistry = createToolRegistry();
|
|
46
|
+
const executor: ToolExecutor = {
|
|
47
|
+
// The provider only forwards this reference to McpHub.
|
|
48
|
+
registerTool: vi.fn(),
|
|
49
|
+
} as unknown as ToolExecutor;
|
|
50
|
+
|
|
51
|
+
lastMcpHubOptions = null;
|
|
52
|
+
|
|
53
|
+
render(
|
|
54
|
+
<RootProvider theme="dark" toolRegistry={registry} toolExecutor={executor}>
|
|
55
|
+
<Text>ok</Text>
|
|
56
|
+
</RootProvider>
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// Allow effects to run.
|
|
60
|
+
await act(async () => {
|
|
61
|
+
await Promise.resolve();
|
|
62
|
+
await Promise.resolve();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
expect(lastMcpHubOptions).not.toBeNull();
|
|
66
|
+
if (!lastMcpHubOptions) {
|
|
67
|
+
throw new Error("Expected McpHub to be constructed");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const options = lastMcpHubOptions as unknown as {
|
|
71
|
+
toolRegistry?: unknown;
|
|
72
|
+
toolExecutor?: unknown;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
expect(options.toolRegistry).toBe(registry);
|
|
76
|
+
expect(options.toolExecutor).toBe(executor);
|
|
77
|
+
});
|
|
78
|
+
});
|