@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,391 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mode E2E Integration Tests
|
|
3
|
+
*
|
|
4
|
+
* End-to-end tests verifying complete flow from CLI flag to mode behavior:
|
|
5
|
+
* 1. CLI flag parsing → ModeManager initialization
|
|
6
|
+
* 2. Slash command → mode switching
|
|
7
|
+
* 3. Mode indicator → TUI header display
|
|
8
|
+
* 4. Mode handlers → message processing
|
|
9
|
+
* 5. Legacy modes → deprecation warnings
|
|
10
|
+
*
|
|
11
|
+
* @module __tests__/mode-e2e.test
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
BUILTIN_CODING_MODES,
|
|
16
|
+
type CodingMode,
|
|
17
|
+
createModeManager,
|
|
18
|
+
emitDeprecationWarning,
|
|
19
|
+
isLegacyMode,
|
|
20
|
+
legacyToNewMode,
|
|
21
|
+
type ModeManager,
|
|
22
|
+
normalizeMode,
|
|
23
|
+
} from "@vellum/core";
|
|
24
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
25
|
+
|
|
26
|
+
// =============================================================================
|
|
27
|
+
// Test Utilities
|
|
28
|
+
// =============================================================================
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a test ModeManager with optional initial mode
|
|
32
|
+
*/
|
|
33
|
+
function createTestModeManager(initialMode?: CodingMode): ModeManager {
|
|
34
|
+
return createModeManager({
|
|
35
|
+
initialMode,
|
|
36
|
+
modes: BUILTIN_CODING_MODES,
|
|
37
|
+
// Disable spec confirmation for easier testing
|
|
38
|
+
requireSpecConfirmation: false,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// =============================================================================
|
|
43
|
+
// E2E Flow 1: CLI Flag → ModeManager Initialization
|
|
44
|
+
// =============================================================================
|
|
45
|
+
|
|
46
|
+
describe("E2E: CLI Flag → ModeManager Initialization", () => {
|
|
47
|
+
it("initializes with default vibe mode when no flag provided", () => {
|
|
48
|
+
const manager = createTestModeManager();
|
|
49
|
+
|
|
50
|
+
expect(manager.getCurrentMode()).toBe("vibe");
|
|
51
|
+
expect(manager.getCurrentHandler()).toBeDefined();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("initializes with plan mode when --mode=plan flag provided", () => {
|
|
55
|
+
const manager = createTestModeManager("plan");
|
|
56
|
+
|
|
57
|
+
expect(manager.getCurrentMode()).toBe("plan");
|
|
58
|
+
expect(manager.getCurrentHandler()).toBeDefined();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("initializes with spec mode when --mode=spec flag provided", () => {
|
|
62
|
+
const manager = createTestModeManager("spec");
|
|
63
|
+
|
|
64
|
+
expect(manager.getCurrentMode()).toBe("spec");
|
|
65
|
+
expect(manager.getCurrentHandler()).toBeDefined();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("normalizes legacy mode flags to new modes", () => {
|
|
69
|
+
// Simulate CLI flag normalization
|
|
70
|
+
const legacyFlag = "code";
|
|
71
|
+
const result = normalizeMode(legacyFlag);
|
|
72
|
+
|
|
73
|
+
expect(result.mode).toBe("vibe"); // code → vibe
|
|
74
|
+
expect(result.wasLegacy).toBe(true);
|
|
75
|
+
|
|
76
|
+
// Create manager with normalized mode
|
|
77
|
+
const manager = createTestModeManager(result.mode);
|
|
78
|
+
expect(manager.getCurrentMode()).toBe("vibe");
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// =============================================================================
|
|
83
|
+
// E2E Flow 2: Slash Command → Mode Switching
|
|
84
|
+
// =============================================================================
|
|
85
|
+
|
|
86
|
+
describe("E2E: Slash Command → Mode Switching", () => {
|
|
87
|
+
let manager: ModeManager;
|
|
88
|
+
|
|
89
|
+
beforeEach(() => {
|
|
90
|
+
manager = createTestModeManager("vibe");
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("/plan switches to plan mode", async () => {
|
|
94
|
+
// Simulate /plan command handler
|
|
95
|
+
const result = await manager.switchMode("plan");
|
|
96
|
+
|
|
97
|
+
expect(result.success).toBe(true);
|
|
98
|
+
expect(manager.getCurrentMode()).toBe("plan");
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("/spec switches to spec mode", async () => {
|
|
102
|
+
// Simulate /spec command handler
|
|
103
|
+
const result = await manager.switchMode("spec");
|
|
104
|
+
|
|
105
|
+
expect(result.success).toBe(true);
|
|
106
|
+
expect(manager.getCurrentMode()).toBe("spec");
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("/vibe switches back to vibe mode", async () => {
|
|
110
|
+
// Start in plan mode
|
|
111
|
+
await manager.switchMode("plan");
|
|
112
|
+
expect(manager.getCurrentMode()).toBe("plan");
|
|
113
|
+
|
|
114
|
+
// Switch to vibe
|
|
115
|
+
const result = await manager.switchMode("vibe");
|
|
116
|
+
|
|
117
|
+
expect(result.success).toBe(true);
|
|
118
|
+
expect(manager.getCurrentMode()).toBe("vibe");
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("emits mode-changed event on successful switch", async () => {
|
|
122
|
+
const events: { previous: CodingMode; current: CodingMode }[] = [];
|
|
123
|
+
|
|
124
|
+
manager.on("mode-changed", (event) => {
|
|
125
|
+
events.push({
|
|
126
|
+
previous: event.previousMode,
|
|
127
|
+
current: event.currentMode,
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
await manager.switchMode("plan");
|
|
132
|
+
|
|
133
|
+
expect(events).toHaveLength(1);
|
|
134
|
+
expect(events[0]).toEqual({
|
|
135
|
+
previous: "vibe",
|
|
136
|
+
current: "plan",
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("handles rapid mode switches correctly", async () => {
|
|
141
|
+
await manager.switchMode("plan");
|
|
142
|
+
await manager.switchMode("spec");
|
|
143
|
+
await manager.switchMode("vibe");
|
|
144
|
+
await manager.switchMode("plan");
|
|
145
|
+
|
|
146
|
+
expect(manager.getCurrentMode()).toBe("plan");
|
|
147
|
+
expect(manager.getPreviousMode()).toBe("vibe");
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// =============================================================================
|
|
152
|
+
// E2E Flow 3: Mode Handlers → Message Processing
|
|
153
|
+
// =============================================================================
|
|
154
|
+
|
|
155
|
+
describe("E2E: Mode Handlers → Message Processing", () => {
|
|
156
|
+
let manager: ModeManager;
|
|
157
|
+
|
|
158
|
+
beforeEach(() => {
|
|
159
|
+
manager = createTestModeManager("vibe");
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("vibe mode handler processes messages", async () => {
|
|
163
|
+
const result = await manager.processMessage({
|
|
164
|
+
content: "Hello, fix this bug",
|
|
165
|
+
timestamp: Date.now(),
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
expect(result.shouldContinue).toBe(true);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("plan mode handler processes messages with plan structure", async () => {
|
|
172
|
+
await manager.switchMode("plan");
|
|
173
|
+
|
|
174
|
+
const result = await manager.processMessage({
|
|
175
|
+
content: "Create a new authentication system",
|
|
176
|
+
timestamp: Date.now(),
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
expect(result.shouldContinue).toBe(true);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("spec mode handler tracks phases", async () => {
|
|
183
|
+
await manager.switchMode("spec");
|
|
184
|
+
|
|
185
|
+
const result = await manager.processMessage({
|
|
186
|
+
content: "Build a user management module",
|
|
187
|
+
timestamp: Date.now(),
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
expect(result.shouldContinue).toBe(true);
|
|
191
|
+
// Spec mode may include checkpoint requirements
|
|
192
|
+
// Handler result includes requiresCheckpoint flag
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it("switching modes resets handler state", async () => {
|
|
196
|
+
// Process in vibe mode
|
|
197
|
+
await manager.processMessage({
|
|
198
|
+
content: "First task",
|
|
199
|
+
timestamp: Date.now(),
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Switch to plan mode
|
|
203
|
+
await manager.switchMode("plan");
|
|
204
|
+
|
|
205
|
+
// Process in plan mode (fresh state)
|
|
206
|
+
const result = await manager.processMessage({
|
|
207
|
+
content: "Second task",
|
|
208
|
+
timestamp: Date.now(),
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
expect(result.shouldContinue).toBe(true);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// =============================================================================
|
|
216
|
+
// E2E Flow 4: Legacy Mode → Deprecation Warnings
|
|
217
|
+
// =============================================================================
|
|
218
|
+
|
|
219
|
+
describe("E2E: Legacy Mode → Deprecation Warnings", () => {
|
|
220
|
+
let consoleSpy: ReturnType<typeof vi.spyOn>;
|
|
221
|
+
|
|
222
|
+
beforeEach(() => {
|
|
223
|
+
consoleSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
afterEach(() => {
|
|
227
|
+
consoleSpy.mockRestore();
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it("detects legacy mode from CLI input", () => {
|
|
231
|
+
expect(isLegacyMode("code")).toBe(true);
|
|
232
|
+
expect(isLegacyMode("draft")).toBe(true);
|
|
233
|
+
expect(isLegacyMode("debug")).toBe(true);
|
|
234
|
+
// Note: 'ask' and 'plan' are in LEGACY_MODE_MAP but 'plan' is also a valid new mode
|
|
235
|
+
expect(isLegacyMode("ask")).toBe(true);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it("maps legacy modes to new equivalents", () => {
|
|
239
|
+
expect(legacyToNewMode("code")).toBe("vibe");
|
|
240
|
+
expect(legacyToNewMode("draft")).toBe("vibe");
|
|
241
|
+
expect(legacyToNewMode("debug")).toBe("vibe");
|
|
242
|
+
expect(legacyToNewMode("ask")).toBe("plan");
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it("emits deprecation warning when legacy mode used", () => {
|
|
246
|
+
emitDeprecationWarning("code", "vibe");
|
|
247
|
+
|
|
248
|
+
expect(consoleSpy).toHaveBeenCalled();
|
|
249
|
+
const warnCall = consoleSpy.mock.calls[0]?.[0] ?? "";
|
|
250
|
+
expect(warnCall).toContain("code");
|
|
251
|
+
expect(warnCall).toContain("vibe");
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it("normalizes legacy mode and provides migration info", () => {
|
|
255
|
+
const result = normalizeMode("draft");
|
|
256
|
+
|
|
257
|
+
expect(result.mode).toBe("vibe");
|
|
258
|
+
expect(result.wasLegacy).toBe(true);
|
|
259
|
+
expect(result.originalName).toBe("draft");
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it("does not set wasLegacy for new mode names", () => {
|
|
263
|
+
// Clear any existing deprecation warnings
|
|
264
|
+
consoleSpy.mockClear();
|
|
265
|
+
|
|
266
|
+
const result = normalizeMode("vibe");
|
|
267
|
+
|
|
268
|
+
expect(result.wasLegacy).toBe(false);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// =============================================================================
|
|
273
|
+
// E2E Flow 5: Mode Configuration Integration
|
|
274
|
+
// =============================================================================
|
|
275
|
+
|
|
276
|
+
describe("E2E: Mode Configuration Integration", () => {
|
|
277
|
+
it("mode configs have correct approval policies", () => {
|
|
278
|
+
// Vibe: full-auto (autonomous)
|
|
279
|
+
expect(BUILTIN_CODING_MODES.vibe.approvalPolicy).toBe("full-auto");
|
|
280
|
+
// Plan: auto-edit (moderate oversight)
|
|
281
|
+
expect(BUILTIN_CODING_MODES.plan.approvalPolicy).toBe("auto-edit");
|
|
282
|
+
// Spec: suggest (all actions require confirmation)
|
|
283
|
+
expect(BUILTIN_CODING_MODES.spec.approvalPolicy).toBe("suggest");
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it("mode configs have correct sandbox policies", () => {
|
|
287
|
+
// Vibe: full-access (autonomous, full write access)
|
|
288
|
+
expect(BUILTIN_CODING_MODES.vibe.sandboxPolicy).toBe("full-access");
|
|
289
|
+
// Plan: workspace-write
|
|
290
|
+
expect(BUILTIN_CODING_MODES.plan.sandboxPolicy).toBe("workspace-write");
|
|
291
|
+
// Spec: workspace-read (read-only until implementation phase)
|
|
292
|
+
expect(BUILTIN_CODING_MODES.spec.sandboxPolicy).toBe("workspace-read");
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it("ModeManager uses correct mode config", () => {
|
|
296
|
+
const manager = createTestModeManager("plan");
|
|
297
|
+
|
|
298
|
+
const config = manager.getModeConfig("plan");
|
|
299
|
+
|
|
300
|
+
expect(config).toEqual(BUILTIN_CODING_MODES.plan);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it("spec mode references orchestrator agent that can spawn", () => {
|
|
304
|
+
// Spec mode references spec-orchestrator agent which has canSpawnAgents: true
|
|
305
|
+
// Agent spawning is now controlled via AgentConfig, not CodingModeConfig
|
|
306
|
+
expect(BUILTIN_CODING_MODES.spec.agentName).toBe("spec-orchestrator");
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it("modes have correct checkpoint counts", () => {
|
|
310
|
+
expect(BUILTIN_CODING_MODES.vibe.checkpointCount).toBe(0);
|
|
311
|
+
expect(BUILTIN_CODING_MODES.plan.checkpointCount).toBe(1);
|
|
312
|
+
expect(BUILTIN_CODING_MODES.spec.checkpointCount).toBe(6);
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// =============================================================================
|
|
317
|
+
// E2E Flow 6: Mode Detection Integration
|
|
318
|
+
// =============================================================================
|
|
319
|
+
|
|
320
|
+
describe("E2E: Mode Detection Integration", () => {
|
|
321
|
+
let manager: ModeManager;
|
|
322
|
+
|
|
323
|
+
beforeEach(() => {
|
|
324
|
+
manager = createTestModeManager("vibe");
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it("detects vibe mode for quick tasks", () => {
|
|
328
|
+
const result = manager.detectMode("fix typo in readme");
|
|
329
|
+
|
|
330
|
+
expect(result.suggestedMode).toBe("vibe");
|
|
331
|
+
expect(result.confidence).toBeGreaterThan(0);
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it("detects plan mode for complex tasks", () => {
|
|
335
|
+
const result = manager.detectMode(
|
|
336
|
+
"refactor the entire authentication system with proper testing"
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
// Plan mode is suggested for complex tasks
|
|
340
|
+
expect(["plan", "spec"]).toContain(result.suggestedMode);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it("detection does not auto-switch modes", async () => {
|
|
344
|
+
// Detection only suggests, doesn't switch
|
|
345
|
+
manager.detectMode("build a complete API");
|
|
346
|
+
|
|
347
|
+
// Mode should still be vibe
|
|
348
|
+
expect(manager.getCurrentMode()).toBe("vibe");
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// =============================================================================
|
|
353
|
+
// E2E Flow 7: Full Integration Scenario
|
|
354
|
+
// =============================================================================
|
|
355
|
+
|
|
356
|
+
describe("E2E: Full Integration Scenario", () => {
|
|
357
|
+
it("complete workflow: start → detect → switch → process → switch back", async () => {
|
|
358
|
+
// 1. Initialize with CLI flag (simulated)
|
|
359
|
+
const cliMode = "vibe";
|
|
360
|
+
const manager = createTestModeManager(cliMode);
|
|
361
|
+
expect(manager.getCurrentMode()).toBe("vibe");
|
|
362
|
+
|
|
363
|
+
// 2. User types complex task, detection suggests plan
|
|
364
|
+
const detection = manager.detectMode("design a new feature with tests");
|
|
365
|
+
expect(detection).toBeDefined();
|
|
366
|
+
|
|
367
|
+
// 3. User executes /plan command to switch
|
|
368
|
+
const switchResult = await manager.switchMode("plan");
|
|
369
|
+
expect(switchResult.success).toBe(true);
|
|
370
|
+
expect(manager.getCurrentMode()).toBe("plan");
|
|
371
|
+
|
|
372
|
+
// 4. Process messages in plan mode
|
|
373
|
+
const msgResult = await manager.processMessage({
|
|
374
|
+
content: "Create the feature spec",
|
|
375
|
+
timestamp: Date.now(),
|
|
376
|
+
});
|
|
377
|
+
expect(msgResult.shouldContinue).toBe(true);
|
|
378
|
+
|
|
379
|
+
// 5. User executes /vibe to switch back for implementation
|
|
380
|
+
const vibeResult = await manager.switchMode("vibe");
|
|
381
|
+
expect(vibeResult.success).toBe(true);
|
|
382
|
+
expect(manager.getCurrentMode()).toBe("vibe");
|
|
383
|
+
|
|
384
|
+
// 6. Process implementation in vibe mode
|
|
385
|
+
const implResult = await manager.processMessage({
|
|
386
|
+
content: "Implement the feature",
|
|
387
|
+
timestamp: Date.now(),
|
|
388
|
+
});
|
|
389
|
+
expect(implResult.shouldContinue).toBe(true);
|
|
390
|
+
});
|
|
391
|
+
});
|