@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
package/src/index.tsx
ADDED
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
AgentLoop,
|
|
4
|
+
APPROVAL_POLICIES,
|
|
5
|
+
type ApprovalPolicy,
|
|
6
|
+
BUILTIN_CODING_MODES,
|
|
7
|
+
CODING_MODES,
|
|
8
|
+
type CodingMode,
|
|
9
|
+
OnboardingWizard as CoreOnboardingWizard,
|
|
10
|
+
createAgentFactory,
|
|
11
|
+
LLM,
|
|
12
|
+
normalizeMode,
|
|
13
|
+
SANDBOX_POLICIES,
|
|
14
|
+
type SandboxPolicy,
|
|
15
|
+
UnifiedToolContainer,
|
|
16
|
+
} from "@vellum/core";
|
|
17
|
+
import { ProviderRegistry } from "@vellum/provider";
|
|
18
|
+
import { createId } from "@vellum/shared";
|
|
19
|
+
import { Command } from "commander";
|
|
20
|
+
import { render } from "ink";
|
|
21
|
+
import { registerDelegateCommand } from "./agents/commands/index.js";
|
|
22
|
+
import { App } from "./app.js";
|
|
23
|
+
import { handleAgentsGenerate } from "./commands/agents/generate.js";
|
|
24
|
+
import { handleAgentsShow } from "./commands/agents/show.js";
|
|
25
|
+
import { handleAgentsValidate } from "./commands/agents/validate.js";
|
|
26
|
+
import {
|
|
27
|
+
renderCredentialsAdd,
|
|
28
|
+
renderCredentialsList,
|
|
29
|
+
renderCredentialsRemove,
|
|
30
|
+
} from "./commands/credentials.js";
|
|
31
|
+
import { executeInit } from "./commands/init.js";
|
|
32
|
+
import { createLspCommand } from "./commands/lsp.js";
|
|
33
|
+
import {
|
|
34
|
+
handleSkillCreate,
|
|
35
|
+
handleSkillList,
|
|
36
|
+
handleSkillShow,
|
|
37
|
+
handleSkillValidate,
|
|
38
|
+
} from "./commands/skill.js";
|
|
39
|
+
import { getEffectiveThinkingConfig } from "./commands/think.js";
|
|
40
|
+
import type { CommandResult } from "./commands/types.js";
|
|
41
|
+
import { getOrCreateOrchestrator } from "./orchestrator-singleton.js";
|
|
42
|
+
import { executeShutdownCleanup, getShutdownCleanup, setShutdownCleanup } from "./shutdown.js";
|
|
43
|
+
import { BufferedStdout, createCompatStdout, setActiveStdout } from "./tui/buffered-stdout.js";
|
|
44
|
+
import { initI18n } from "./tui/i18n/index.js";
|
|
45
|
+
|
|
46
|
+
import {
|
|
47
|
+
getAlternateBufferSetting,
|
|
48
|
+
getDefaultAlternateBufferEnabled,
|
|
49
|
+
} from "./tui/i18n/settings-integration.js";
|
|
50
|
+
import { isConptyTerminal } from "./tui/utils/detectTerminal.js";
|
|
51
|
+
import { version } from "./version.js";
|
|
52
|
+
|
|
53
|
+
// ============================================
|
|
54
|
+
// Helper: Get message from CommandResult
|
|
55
|
+
// ============================================
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Extract display message from CommandResult
|
|
59
|
+
*/
|
|
60
|
+
function getResultMessage(result: CommandResult): string {
|
|
61
|
+
switch (result.kind) {
|
|
62
|
+
case "success":
|
|
63
|
+
return result.message ?? "";
|
|
64
|
+
case "error":
|
|
65
|
+
return result.message;
|
|
66
|
+
case "interactive":
|
|
67
|
+
return result.prompt.message;
|
|
68
|
+
case "pending":
|
|
69
|
+
return result.operation.message;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// ============================================
|
|
73
|
+
// T-VIRTUAL-SCROLL: Working Stdio Proxy for Ink
|
|
74
|
+
// ============================================
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Creates working stdio proxies for Ink rendering.
|
|
78
|
+
*
|
|
79
|
+
* This fixes an issue where Ink's stdout/stderr writes can get intercepted
|
|
80
|
+
* or cause issues in VS Code terminal. By proxying through the original
|
|
81
|
+
* write functions bound to process.stdout/stderr, we ensure atomic writes.
|
|
82
|
+
*
|
|
83
|
+
* Pattern adapted from Gemini CLI's terminal handling.
|
|
84
|
+
*/
|
|
85
|
+
function createWorkingStdio(): {
|
|
86
|
+
stdout: typeof process.stdout;
|
|
87
|
+
stderr: typeof process.stderr;
|
|
88
|
+
} {
|
|
89
|
+
const originalWrite = process.stdout.write.bind(process.stdout);
|
|
90
|
+
const originalErrWrite = process.stderr.write.bind(process.stderr);
|
|
91
|
+
|
|
92
|
+
const inkStdout = new Proxy(process.stdout, {
|
|
93
|
+
get(target, prop, receiver) {
|
|
94
|
+
if (prop === "write") return originalWrite;
|
|
95
|
+
const value = Reflect.get(target, prop, receiver);
|
|
96
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const inkStderr = new Proxy(process.stderr, {
|
|
101
|
+
get(target, prop, receiver) {
|
|
102
|
+
if (prop === "write") return originalErrWrite;
|
|
103
|
+
const value = Reflect.get(target, prop, receiver);
|
|
104
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
stdout: inkStdout as typeof process.stdout,
|
|
110
|
+
stderr: inkStderr as typeof process.stderr,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ============================================
|
|
115
|
+
// Graceful Shutdown Setup (T030)
|
|
116
|
+
// ============================================
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Handle process signals for graceful shutdown.
|
|
120
|
+
*/
|
|
121
|
+
function setupGlobalShutdownHandlers(): void {
|
|
122
|
+
const signals: NodeJS.Signals[] = ["SIGINT", "SIGTERM", "SIGQUIT"];
|
|
123
|
+
|
|
124
|
+
for (const signal of signals) {
|
|
125
|
+
process.on(signal, () => {
|
|
126
|
+
console.log(`\n[CLI] Received ${signal}, shutting down gracefully...`);
|
|
127
|
+
executeShutdownCleanup();
|
|
128
|
+
// Give time for cleanup, then exit
|
|
129
|
+
setTimeout(() => process.exit(0), 100);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Setup handlers early
|
|
135
|
+
setupGlobalShutdownHandlers();
|
|
136
|
+
|
|
137
|
+
// =============================================================================
|
|
138
|
+
// T037-T040: Mode CLI Flag Interfaces
|
|
139
|
+
// =============================================================================
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Chat command options including mode flags.
|
|
143
|
+
*/
|
|
144
|
+
export interface ChatOptions {
|
|
145
|
+
/** Model to use for AI responses */
|
|
146
|
+
model: string;
|
|
147
|
+
/** Provider to use (anthropic, openai, etc.) */
|
|
148
|
+
provider: string;
|
|
149
|
+
/** Language/locale for UI */
|
|
150
|
+
language?: string;
|
|
151
|
+
/** Coding mode (vibe, plan, spec) */
|
|
152
|
+
mode: CodingMode;
|
|
153
|
+
/** Approval policy override */
|
|
154
|
+
approval?: ApprovalPolicy;
|
|
155
|
+
/** Sandbox policy override */
|
|
156
|
+
sandbox?: SandboxPolicy;
|
|
157
|
+
/** Full-auto shortcut flag */
|
|
158
|
+
fullAuto?: boolean;
|
|
159
|
+
/** UI theme (dark, parchment, dracula, etc.) */
|
|
160
|
+
theme?: string;
|
|
161
|
+
/** Force banner display on startup */
|
|
162
|
+
banner?: boolean;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Parse mode flag with validation.
|
|
167
|
+
* Supports both new modes (vibe, plan, spec) and legacy modes (code, draft, debug, ask).
|
|
168
|
+
* @param value - User input value
|
|
169
|
+
* @returns Validated CodingMode
|
|
170
|
+
*/
|
|
171
|
+
function parseMode(value: string): CodingMode {
|
|
172
|
+
const result = normalizeMode(value);
|
|
173
|
+
return result.mode;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Parse approval policy flag with validation.
|
|
178
|
+
* @param value - User input value
|
|
179
|
+
* @returns Validated ApprovalPolicy
|
|
180
|
+
*/
|
|
181
|
+
function parseApproval(value: string): ApprovalPolicy {
|
|
182
|
+
const valid = APPROVAL_POLICIES as readonly string[];
|
|
183
|
+
if (!valid.includes(value)) {
|
|
184
|
+
throw new Error(`Invalid approval: ${value}. Valid options: ${valid.join(", ")}`);
|
|
185
|
+
}
|
|
186
|
+
return value as ApprovalPolicy;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Parse sandbox policy flag with validation.
|
|
191
|
+
* @param value - User input value
|
|
192
|
+
* @returns Validated SandboxPolicy
|
|
193
|
+
*/
|
|
194
|
+
function parseSandbox(value: string): SandboxPolicy {
|
|
195
|
+
const valid = SANDBOX_POLICIES as readonly string[];
|
|
196
|
+
if (!valid.includes(value)) {
|
|
197
|
+
throw new Error(`Invalid sandbox: ${value}. Valid options: ${valid.join(", ")}`);
|
|
198
|
+
}
|
|
199
|
+
return value as SandboxPolicy;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const program = new Command();
|
|
203
|
+
|
|
204
|
+
program.name("vellum").description("Next-generation AI coding agent").version(version);
|
|
205
|
+
|
|
206
|
+
// =============================================================================
|
|
207
|
+
// T037-T040: Chat Command with Mode Flags
|
|
208
|
+
// =============================================================================
|
|
209
|
+
|
|
210
|
+
program
|
|
211
|
+
.command("chat", { isDefault: true })
|
|
212
|
+
.description("Start interactive chat session")
|
|
213
|
+
.option("-m, --model <model>", "Model to use", "claude-sonnet-4-20250514")
|
|
214
|
+
.option("-p, --provider <provider>", "Provider to use", "anthropic")
|
|
215
|
+
.option("-l, --language <locale>", "Language/locale to use (e.g., en, zh)")
|
|
216
|
+
// T037: --mode flag
|
|
217
|
+
.option("--mode <mode>", `Set coding mode (${CODING_MODES.join("|")})`, parseMode, "vibe")
|
|
218
|
+
// T038: --approval flag
|
|
219
|
+
.option(
|
|
220
|
+
"--approval <policy>",
|
|
221
|
+
`Set approval policy (${APPROVAL_POLICIES.join("|")})`,
|
|
222
|
+
parseApproval
|
|
223
|
+
)
|
|
224
|
+
// T039: --sandbox flag
|
|
225
|
+
.option("--sandbox <policy>", `Set sandbox policy (${SANDBOX_POLICIES.join("|")})`, parseSandbox)
|
|
226
|
+
// T040: --full-auto shortcut
|
|
227
|
+
.option("--full-auto", "Shortcut for --mode=vibe --approval=full-auto", false)
|
|
228
|
+
// Theme selection
|
|
229
|
+
.option("--theme <theme>", "UI theme (dark|parchment|dracula|etc.)", "parchment")
|
|
230
|
+
.option("--banner", "Show banner on startup", false)
|
|
231
|
+
.action(async (options: ChatOptions) => {
|
|
232
|
+
// T040: Apply --full-auto shortcut
|
|
233
|
+
let effectiveMode = options.mode;
|
|
234
|
+
let effectiveApproval = options.approval;
|
|
235
|
+
|
|
236
|
+
if (options.fullAuto) {
|
|
237
|
+
effectiveMode = "vibe";
|
|
238
|
+
effectiveApproval = "full-auto";
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Initialize i18n before rendering (T019)
|
|
242
|
+
initI18n({ cliLanguage: options.language });
|
|
243
|
+
|
|
244
|
+
// Load user's saved configuration from onboarding
|
|
245
|
+
// CLI flags override user config if explicitly provided
|
|
246
|
+
let effectiveProvider = options.provider;
|
|
247
|
+
let effectiveModel = options.model;
|
|
248
|
+
|
|
249
|
+
try {
|
|
250
|
+
const wizard = new CoreOnboardingWizard();
|
|
251
|
+
const loadResult = await wizard.loadState();
|
|
252
|
+
if (loadResult.ok) {
|
|
253
|
+
const userConfig = wizard.generateConfig();
|
|
254
|
+
if (userConfig.provider) {
|
|
255
|
+
effectiveProvider = userConfig.provider;
|
|
256
|
+
}
|
|
257
|
+
if (userConfig.model) {
|
|
258
|
+
effectiveModel = userConfig.model;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
} catch {
|
|
262
|
+
// Use CLI defaults if config loading fails
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Create AgentLoop with real LLM provider
|
|
266
|
+
let agentLoop: AgentLoop | undefined;
|
|
267
|
+
let initError: Error | undefined;
|
|
268
|
+
try {
|
|
269
|
+
// Initialize credential manager for secure credential resolution
|
|
270
|
+
const { createCredentialManager } = await import("./commands/auth.js");
|
|
271
|
+
const credentialManager = await createCredentialManager();
|
|
272
|
+
|
|
273
|
+
// Initialize provider registry with credential manager
|
|
274
|
+
const providerRegistry = new ProviderRegistry({
|
|
275
|
+
credentialManager: credentialManager,
|
|
276
|
+
});
|
|
277
|
+
LLM.initialize(providerRegistry);
|
|
278
|
+
|
|
279
|
+
// Get mode config for the selected coding mode
|
|
280
|
+
const modeConfig = BUILTIN_CODING_MODES[effectiveMode];
|
|
281
|
+
|
|
282
|
+
// Initialize orchestrator singleton for task delegation
|
|
283
|
+
const orchestrator = getOrCreateOrchestrator();
|
|
284
|
+
|
|
285
|
+
// Create PromptBuilder with MD prompts (REQ-001: Use MD prompts)
|
|
286
|
+
const { promptBuilder, cleanup } = await createAgentFactory({
|
|
287
|
+
cwd: process.cwd(),
|
|
288
|
+
projectRoot: process.cwd(),
|
|
289
|
+
role: "base", // Load base.md for identity
|
|
290
|
+
mode: effectiveMode, // Load vibe.md/plan.md/spec.md
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// Register cleanup for graceful shutdown
|
|
294
|
+
setShutdownCleanup(cleanup);
|
|
295
|
+
|
|
296
|
+
// Create unified tool container (T045: Single source of truth for tools)
|
|
297
|
+
const toolContainer = new UnifiedToolContainer({
|
|
298
|
+
cwd: process.cwd(),
|
|
299
|
+
});
|
|
300
|
+
toolContainer.registerBuiltins();
|
|
301
|
+
|
|
302
|
+
// Create AgentLoop with PromptBuilder and unified tool container
|
|
303
|
+
agentLoop = new AgentLoop({
|
|
304
|
+
sessionId: createId(),
|
|
305
|
+
mode: modeConfig,
|
|
306
|
+
providerType: effectiveProvider,
|
|
307
|
+
model: effectiveModel,
|
|
308
|
+
cwd: process.cwd(),
|
|
309
|
+
projectRoot: process.cwd(),
|
|
310
|
+
interactive: true,
|
|
311
|
+
orchestrator,
|
|
312
|
+
promptBuilder, // Use MD-loaded prompts
|
|
313
|
+
// Dynamic thinking config getter for runtime /think toggling
|
|
314
|
+
getThinkingConfig: getEffectiveThinkingConfig,
|
|
315
|
+
// T045: Wire unified tool container
|
|
316
|
+
tools: toolContainer.getProviderToolDefinitions(),
|
|
317
|
+
toolExecutor: toolContainer.getExecutor(),
|
|
318
|
+
// Enable AGENTS.md and Skills integration for project context
|
|
319
|
+
enableAgentsIntegration: true,
|
|
320
|
+
enableSkillsIntegration: true,
|
|
321
|
+
});
|
|
322
|
+
} catch (error) {
|
|
323
|
+
initError = error instanceof Error ? error : new Error(String(error));
|
|
324
|
+
console.error("[CLI] Failed to initialize agent:", initError.message);
|
|
325
|
+
// Continue without agentLoop - App will show error banner and fall back to echo mode
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const isVSCodeTerminal =
|
|
329
|
+
process.env.TERM_PROGRAM === "vscode" ||
|
|
330
|
+
process.env.VSCODE_INJECTION === "1" ||
|
|
331
|
+
Boolean(process.env.VSCODE_GIT_IPC_HANDLE);
|
|
332
|
+
const isScreenReaderActive = Boolean(
|
|
333
|
+
process.env.ACCESSIBILITY === "true" || process.env.SCREEN_READER === "true"
|
|
334
|
+
);
|
|
335
|
+
// T-VIRTUAL-SCROLL: Enable debug mode for static output testing
|
|
336
|
+
// Set VELLUM_STATIC_OUTPUT=1 to enable non-replacing output (each update renders separately)
|
|
337
|
+
const isStaticOutputMode = Boolean(process.env.VELLUM_STATIC_OUTPUT === "1");
|
|
338
|
+
|
|
339
|
+
// T-VIRTUAL-SCROLL: Get working stdio proxies for Ink
|
|
340
|
+
// Always use proxied stdio to ensure proper write handling in VS Code terminal
|
|
341
|
+
const { stdout: inkStdoutProxy, stderr: inkStderr } = createWorkingStdio();
|
|
342
|
+
|
|
343
|
+
// Synchronized Output (DEC 2026): Only enable on Windows + VS Code terminal
|
|
344
|
+
// by reusing the existing detection in createCompatStdout().
|
|
345
|
+
const compatStdout = createCompatStdout();
|
|
346
|
+
const useBufferedStdout = compatStdout instanceof BufferedStdout;
|
|
347
|
+
|
|
348
|
+
// Set active stdout for modules that need to write outside Ink
|
|
349
|
+
if (useBufferedStdout) {
|
|
350
|
+
setActiveStdout(compatStdout);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Preserve existing behavior everywhere else (proxy stdout).
|
|
354
|
+
const inkStdout: NodeJS.WriteStream = useBufferedStdout ? compatStdout : inkStdoutProxy;
|
|
355
|
+
|
|
356
|
+
if (useBufferedStdout) {
|
|
357
|
+
// Compose with existing shutdown cleanup so we don't lose agent cleanup.
|
|
358
|
+
const previousCleanup = getShutdownCleanup();
|
|
359
|
+
setShutdownCleanup(() => {
|
|
360
|
+
previousCleanup?.();
|
|
361
|
+
(compatStdout as BufferedStdout).dispose();
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Build Ink render options
|
|
366
|
+
// Key changes from Gemini CLI analysis:
|
|
367
|
+
// - Always use stdio proxy (prevents write interception issues)
|
|
368
|
+
// - patchConsole: false (prevent Ink from hijacking console)
|
|
369
|
+
// - exitOnCtrlC: false (let app handle Ctrl+C for proper cleanup)
|
|
370
|
+
// - incrementalRendering linked to alternateBuffer state
|
|
371
|
+
// - Removed maxFps: 20 (let Ink manage frame rate naturally)
|
|
372
|
+
const userAltBufferSetting = getAlternateBufferSetting();
|
|
373
|
+
const defaultAltBuffer = getDefaultAlternateBufferEnabled();
|
|
374
|
+
const resolvedAltBuffer = userAltBufferSetting ?? defaultAltBuffer;
|
|
375
|
+
const isConpty = isConptyTerminal();
|
|
376
|
+
const allowAlternateBuffer = !isConpty || userAltBufferSetting === true;
|
|
377
|
+
const useAlternateBuffer =
|
|
378
|
+
!isScreenReaderActive && !isStaticOutputMode && resolvedAltBuffer && allowAlternateBuffer;
|
|
379
|
+
const incrementalRendering = !isStaticOutputMode;
|
|
380
|
+
const inkRenderOptions = isVSCodeTerminal
|
|
381
|
+
? {
|
|
382
|
+
stdout: inkStdout,
|
|
383
|
+
stderr: inkStderr,
|
|
384
|
+
stdin: process.stdin,
|
|
385
|
+
patchConsole: useAlternateBuffer,
|
|
386
|
+
exitOnCtrlC: false,
|
|
387
|
+
alternateBuffer: useAlternateBuffer,
|
|
388
|
+
incrementalRendering,
|
|
389
|
+
debug: isStaticOutputMode,
|
|
390
|
+
}
|
|
391
|
+
: {
|
|
392
|
+
stdout: inkStdout,
|
|
393
|
+
stderr: inkStderr,
|
|
394
|
+
stdin: process.stdin,
|
|
395
|
+
patchConsole: useAlternateBuffer,
|
|
396
|
+
exitOnCtrlC: false,
|
|
397
|
+
alternateBuffer: useAlternateBuffer,
|
|
398
|
+
incrementalRendering,
|
|
399
|
+
debug: isStaticOutputMode,
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
render(
|
|
403
|
+
<App
|
|
404
|
+
model={effectiveModel}
|
|
405
|
+
provider={effectiveProvider}
|
|
406
|
+
mode={effectiveMode}
|
|
407
|
+
approval={effectiveApproval}
|
|
408
|
+
sandbox={options.sandbox}
|
|
409
|
+
theme={options.theme as import("./tui/theme/index.js").ThemeName}
|
|
410
|
+
banner={options.banner}
|
|
411
|
+
agentLoop={agentLoop}
|
|
412
|
+
initError={initError}
|
|
413
|
+
/>,
|
|
414
|
+
inkRenderOptions
|
|
415
|
+
);
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
program
|
|
419
|
+
.command("run <prompt>")
|
|
420
|
+
.description("Run a single prompt")
|
|
421
|
+
.option("-m, --model <model>", "Model to use", "claude-sonnet-4-20250514")
|
|
422
|
+
.action(async (prompt, options) => {
|
|
423
|
+
console.log(`Running: ${prompt} with model ${options.model}`);
|
|
424
|
+
// TODO: Implement single run
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
program
|
|
428
|
+
.command("config")
|
|
429
|
+
.description("Manage configuration")
|
|
430
|
+
.action(() => {
|
|
431
|
+
console.log("Config management coming soon");
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
// =============================================================================
|
|
435
|
+
// Credentials Command (T022)
|
|
436
|
+
// =============================================================================
|
|
437
|
+
|
|
438
|
+
const credentialsCmd = program
|
|
439
|
+
.command("credentials")
|
|
440
|
+
.description("Manage API credentials for LLM providers");
|
|
441
|
+
|
|
442
|
+
credentialsCmd
|
|
443
|
+
.command("list", { isDefault: true })
|
|
444
|
+
.description("List all stored credentials (masked values)")
|
|
445
|
+
.action(() => {
|
|
446
|
+
renderCredentialsList();
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
credentialsCmd
|
|
450
|
+
.command("add <provider>")
|
|
451
|
+
.description("Add or update credential for a provider")
|
|
452
|
+
.action((provider: string) => {
|
|
453
|
+
renderCredentialsAdd(provider);
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
credentialsCmd
|
|
457
|
+
.command("remove <provider>")
|
|
458
|
+
.alias("rm")
|
|
459
|
+
.description("Remove credential for a provider")
|
|
460
|
+
.action((provider: string) => {
|
|
461
|
+
renderCredentialsRemove(provider);
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
// =============================================================================
|
|
465
|
+
// Init Command (T039-T041)
|
|
466
|
+
// =============================================================================
|
|
467
|
+
|
|
468
|
+
program
|
|
469
|
+
.command("init")
|
|
470
|
+
.description("Initialize AGENTS.md for your project")
|
|
471
|
+
.option("-f, --force", "Overwrite existing AGENTS.md without prompting")
|
|
472
|
+
.option("-m, --minimal", "Skip wizard prompts, use defaults")
|
|
473
|
+
.action(async (options) => {
|
|
474
|
+
const result = await executeInit({
|
|
475
|
+
force: options.force,
|
|
476
|
+
minimal: options.minimal,
|
|
477
|
+
nonInteractive: false,
|
|
478
|
+
});
|
|
479
|
+
process.exit(result.exitCode);
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
// =============================================================================
|
|
483
|
+
// Agents Command Group (T042-T046)
|
|
484
|
+
// =============================================================================
|
|
485
|
+
|
|
486
|
+
const agentsCmd = program.command("agents").description("Manage AGENTS.md configuration");
|
|
487
|
+
|
|
488
|
+
agentsCmd
|
|
489
|
+
.command("show", { isDefault: true })
|
|
490
|
+
.description("Display merged AGENTS.md configuration")
|
|
491
|
+
.option("-j, --json", "Output as JSON")
|
|
492
|
+
.option("-v, --verbose", "Show all details including sources")
|
|
493
|
+
.option("-s, --scope <path>", "Show config for specific file/directory")
|
|
494
|
+
.action(async (options) => {
|
|
495
|
+
const result = await handleAgentsShow({
|
|
496
|
+
json: options.json,
|
|
497
|
+
verbose: options.verbose,
|
|
498
|
+
scope: options.scope,
|
|
499
|
+
});
|
|
500
|
+
console.log(getResultMessage(result));
|
|
501
|
+
process.exit(result.kind === "success" ? 0 : 1);
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
agentsCmd
|
|
505
|
+
.command("validate [file]")
|
|
506
|
+
.description("Validate AGENTS.md syntax and structure")
|
|
507
|
+
.option("-v, --verbose", "Show verbose output")
|
|
508
|
+
.option("-j, --json", "Output as JSON")
|
|
509
|
+
.action(async (file, options) => {
|
|
510
|
+
const result = await handleAgentsValidate({
|
|
511
|
+
file,
|
|
512
|
+
verbose: options.verbose,
|
|
513
|
+
json: options.json,
|
|
514
|
+
});
|
|
515
|
+
console.log(getResultMessage(result));
|
|
516
|
+
process.exit(result.kind === "success" ? 0 : 1);
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
agentsCmd
|
|
520
|
+
.command("generate")
|
|
521
|
+
.description("Generate AGENTS.md based on detected project stack")
|
|
522
|
+
.option("-o, --output <path>", "Output file path (default: ./AGENTS.md)")
|
|
523
|
+
.option("-m, --merge", "Merge with existing file")
|
|
524
|
+
.option("--dry-run", "Preview generated content without writing")
|
|
525
|
+
.action(async (options) => {
|
|
526
|
+
const result = await handleAgentsGenerate({
|
|
527
|
+
output: options.output,
|
|
528
|
+
merge: options.merge,
|
|
529
|
+
dryRun: options.dryRun,
|
|
530
|
+
});
|
|
531
|
+
console.log(getResultMessage(result));
|
|
532
|
+
process.exit(result.kind === "success" ? 0 : 1);
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
// =============================================================================
|
|
536
|
+
// Skill Command Group (T033-T037)
|
|
537
|
+
// =============================================================================
|
|
538
|
+
|
|
539
|
+
const skillCmd = program.command("skill").description("Manage skills for AI context");
|
|
540
|
+
|
|
541
|
+
skillCmd
|
|
542
|
+
.command("list", { isDefault: true })
|
|
543
|
+
.description("List all available skills")
|
|
544
|
+
.option("-s, --source <source>", "Filter by source (workspace, user, global, builtin)")
|
|
545
|
+
.option("-j, --json", "Output as JSON")
|
|
546
|
+
.option("-v, --verbose", "Show full descriptions and triggers")
|
|
547
|
+
.action(async (options) => {
|
|
548
|
+
const result = await handleSkillList({
|
|
549
|
+
source: options.source,
|
|
550
|
+
json: options.json,
|
|
551
|
+
verbose: options.verbose,
|
|
552
|
+
});
|
|
553
|
+
console.log(getResultMessage(result));
|
|
554
|
+
process.exit(result.kind === "success" ? 0 : 1);
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
skillCmd
|
|
558
|
+
.command("show <name>")
|
|
559
|
+
.description("Show details of a specific skill")
|
|
560
|
+
.option("-c, --content", "Show full SKILL.md content")
|
|
561
|
+
.option("-j, --json", "Output as JSON")
|
|
562
|
+
.action(async (name, options) => {
|
|
563
|
+
const result = await handleSkillShow(name, {
|
|
564
|
+
content: options.content,
|
|
565
|
+
json: options.json,
|
|
566
|
+
});
|
|
567
|
+
console.log(getResultMessage(result));
|
|
568
|
+
process.exit(result.kind === "success" ? 0 : 1);
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
skillCmd
|
|
572
|
+
.command("create <name>")
|
|
573
|
+
.description("Create a new skill from template")
|
|
574
|
+
.option("-l, --location <location>", "Location: workspace, user, or global")
|
|
575
|
+
.option("-f, --force", "Overwrite if skill already exists")
|
|
576
|
+
.option("-n, --non-interactive", "Non-interactive mode (use defaults)")
|
|
577
|
+
.action(async (name, options) => {
|
|
578
|
+
const result = await handleSkillCreate(name, {
|
|
579
|
+
location: options.location,
|
|
580
|
+
force: options.force,
|
|
581
|
+
nonInteractive: options.nonInteractive,
|
|
582
|
+
});
|
|
583
|
+
process.exit(result.exitCode);
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
skillCmd
|
|
587
|
+
.command("validate")
|
|
588
|
+
.description("Validate skill(s)")
|
|
589
|
+
.option("-s, --skill <name>", "Validate single skill by name")
|
|
590
|
+
.option("--strict", "Treat warnings as errors")
|
|
591
|
+
.option("-j, --json", "Output as JSON")
|
|
592
|
+
.action(async (options) => {
|
|
593
|
+
const result = await handleSkillValidate({
|
|
594
|
+
skill: options.skill,
|
|
595
|
+
strict: options.strict,
|
|
596
|
+
json: options.json,
|
|
597
|
+
});
|
|
598
|
+
console.log(getResultMessage(result));
|
|
599
|
+
process.exit(result.kind === "success" ? 0 : 1);
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
// =============================================================================
|
|
603
|
+
// Agent Commands (T044 - Multi-Agent Orchestration)
|
|
604
|
+
// =============================================================================
|
|
605
|
+
|
|
606
|
+
registerDelegateCommand(program);
|
|
607
|
+
|
|
608
|
+
// =============================================================================
|
|
609
|
+
// LSP Command (Phase 30)
|
|
610
|
+
// =============================================================================
|
|
611
|
+
|
|
612
|
+
program.addCommand(createLspCommand());
|
|
613
|
+
|
|
614
|
+
program.parse();
|