@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,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Chain Parser Module
|
|
3
|
+
*
|
|
4
|
+
* Parses command chains with shell-like operators:
|
|
5
|
+
* - && (AND): Continue only if previous command succeeds
|
|
6
|
+
* - || (OR): Continue only if previous command fails
|
|
7
|
+
* - ; (SEQUENCE): Always continue regardless of result
|
|
8
|
+
*
|
|
9
|
+
* @module cli/commands/parser/chain-parser
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { CommandResult } from "../types.js";
|
|
13
|
+
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// T053: Chain Operator Types
|
|
16
|
+
// =============================================================================
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Chain operator discriminator
|
|
20
|
+
*
|
|
21
|
+
* - && (AND): Execute next command only if previous succeeded (exit code 0)
|
|
22
|
+
* - || (OR): Execute next command only if previous failed (non-zero exit)
|
|
23
|
+
* - ; (SEQUENCE): Execute next command unconditionally
|
|
24
|
+
*/
|
|
25
|
+
export type ChainOperator = "&&" | "||" | ";";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Single segment of a command chain
|
|
29
|
+
*/
|
|
30
|
+
export interface ChainSegment {
|
|
31
|
+
/** Raw command string (may include pipes internally) */
|
|
32
|
+
readonly command: string;
|
|
33
|
+
/** Operator connecting to the NEXT segment (undefined for last) */
|
|
34
|
+
readonly operator?: ChainOperator;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Result of parsing a chained command string
|
|
39
|
+
*/
|
|
40
|
+
export interface ChainParseResult {
|
|
41
|
+
/** Whether the input contains chain operators */
|
|
42
|
+
readonly isChained: boolean;
|
|
43
|
+
/** Array of command segments with their operators */
|
|
44
|
+
readonly segments: readonly ChainSegment[];
|
|
45
|
+
/** Original raw input */
|
|
46
|
+
readonly raw: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Result of chain execution
|
|
51
|
+
*/
|
|
52
|
+
export interface ChainExecutionResult {
|
|
53
|
+
/** Final result from the chain (last executed command) */
|
|
54
|
+
readonly result: CommandResult;
|
|
55
|
+
/** Number of commands executed */
|
|
56
|
+
readonly executedCount: number;
|
|
57
|
+
/** Total commands in chain */
|
|
58
|
+
readonly totalCount: number;
|
|
59
|
+
/** Whether chain completed fully */
|
|
60
|
+
readonly completed: boolean;
|
|
61
|
+
/** Index of last executed command */
|
|
62
|
+
readonly lastExecutedIndex: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// =============================================================================
|
|
66
|
+
// T053: Chain Parser Implementation
|
|
67
|
+
// =============================================================================
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Check if a position is inside quotes
|
|
71
|
+
*/
|
|
72
|
+
function isInsideQuotes(input: string, position: number): boolean {
|
|
73
|
+
let inDouble = false;
|
|
74
|
+
let inSingle = false;
|
|
75
|
+
|
|
76
|
+
for (let i = 0; i < position && i < input.length; i++) {
|
|
77
|
+
const char = input[i];
|
|
78
|
+
const prevChar = i > 0 ? input[i - 1] : "";
|
|
79
|
+
|
|
80
|
+
if (char === '"' && !inSingle && prevChar !== "\\") {
|
|
81
|
+
inDouble = !inDouble;
|
|
82
|
+
} else if (char === "'" && !inDouble) {
|
|
83
|
+
inSingle = !inSingle;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return inDouble || inSingle;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Find all chain operators with their positions
|
|
92
|
+
*/
|
|
93
|
+
function findChainOperators(
|
|
94
|
+
input: string
|
|
95
|
+
): Array<{ operator: ChainOperator; start: number; end: number }> {
|
|
96
|
+
const operators: Array<{ operator: ChainOperator; start: number; end: number }> = [];
|
|
97
|
+
|
|
98
|
+
let i = 0;
|
|
99
|
+
while (i < input.length) {
|
|
100
|
+
// Skip if inside quotes
|
|
101
|
+
if (isInsideQuotes(input, i)) {
|
|
102
|
+
i++;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Check for && (must check before single &)
|
|
107
|
+
if (input[i] === "&" && input[i + 1] === "&") {
|
|
108
|
+
operators.push({ operator: "&&", start: i, end: i + 2 });
|
|
109
|
+
i += 2;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Check for ||
|
|
114
|
+
if (input[i] === "|" && input[i + 1] === "|") {
|
|
115
|
+
operators.push({ operator: "||", start: i, end: i + 2 });
|
|
116
|
+
i += 2;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Check for ; (only if not followed by another operator-like char)
|
|
121
|
+
if (input[i] === ";") {
|
|
122
|
+
operators.push({ operator: ";", start: i, end: i + 1 });
|
|
123
|
+
i++;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
i++;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return operators;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Chain Parser
|
|
135
|
+
*
|
|
136
|
+
* Parses command strings containing chain operators into segments.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* const result = ChainParser.parse('/cmd1 && /cmd2 || /cmd3');
|
|
141
|
+
* // {
|
|
142
|
+
* // isChained: true,
|
|
143
|
+
* // segments: [
|
|
144
|
+
* // { command: '/cmd1', operator: '&&' },
|
|
145
|
+
* // { command: '/cmd2', operator: '||' },
|
|
146
|
+
* // { command: '/cmd3' }
|
|
147
|
+
* // ],
|
|
148
|
+
* // raw: '/cmd1 && /cmd2 || /cmd3'
|
|
149
|
+
* // }
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
// biome-ignore lint/complexity/noStaticOnlyClass: ChainParser provides logical grouping
|
|
153
|
+
export class ChainParser {
|
|
154
|
+
/**
|
|
155
|
+
* Parse a command string for chain operators
|
|
156
|
+
*
|
|
157
|
+
* @param input - Raw command string
|
|
158
|
+
* @returns ChainParseResult with parsed segments
|
|
159
|
+
*/
|
|
160
|
+
static parse(input: string): ChainParseResult {
|
|
161
|
+
const trimmed = input.trim();
|
|
162
|
+
|
|
163
|
+
if (!trimmed) {
|
|
164
|
+
return {
|
|
165
|
+
isChained: false,
|
|
166
|
+
segments: [],
|
|
167
|
+
raw: input,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const operators = findChainOperators(trimmed);
|
|
172
|
+
|
|
173
|
+
// No chain operators found
|
|
174
|
+
if (operators.length === 0) {
|
|
175
|
+
return {
|
|
176
|
+
isChained: false,
|
|
177
|
+
segments: [{ command: trimmed }],
|
|
178
|
+
raw: input,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Split into segments
|
|
183
|
+
const segments: ChainSegment[] = [];
|
|
184
|
+
let lastEnd = 0;
|
|
185
|
+
|
|
186
|
+
for (const op of operators) {
|
|
187
|
+
const command = trimmed.slice(lastEnd, op.start).trim();
|
|
188
|
+
if (command) {
|
|
189
|
+
segments.push({ command, operator: op.operator });
|
|
190
|
+
}
|
|
191
|
+
lastEnd = op.end;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Add final segment (after last operator)
|
|
195
|
+
const finalCommand = trimmed.slice(lastEnd).trim();
|
|
196
|
+
if (finalCommand) {
|
|
197
|
+
segments.push({ command: finalCommand });
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
isChained: segments.length > 1,
|
|
202
|
+
segments,
|
|
203
|
+
raw: input,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Check if input contains chain operators
|
|
209
|
+
*
|
|
210
|
+
* @param input - Raw command string
|
|
211
|
+
* @returns true if chain operators are present
|
|
212
|
+
*/
|
|
213
|
+
static hasChainOperators(input: string): boolean {
|
|
214
|
+
const operators = findChainOperators(input);
|
|
215
|
+
return operators.length > 0;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// =============================================================================
|
|
220
|
+
// T053: Chained Command Executor
|
|
221
|
+
// =============================================================================
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Executor function type for individual commands
|
|
225
|
+
*/
|
|
226
|
+
export type CommandExecutorFn = (command: string, signal?: AbortSignal) => Promise<CommandResult>;
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Chained Command Executor
|
|
230
|
+
*
|
|
231
|
+
* Executes a chain of commands according to shell semantics:
|
|
232
|
+
* - && : Continue only if previous succeeded (no error)
|
|
233
|
+
* - || : Continue only if previous failed (has error)
|
|
234
|
+
* - ; : Always continue regardless of result
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```typescript
|
|
238
|
+
* const executor = new ChainedCommandExecutor(async (cmd) => {
|
|
239
|
+
* return { type: 'success', message: `Executed: ${cmd}` };
|
|
240
|
+
* });
|
|
241
|
+
*
|
|
242
|
+
* const result = await executor.execute('/build && /test || /rollback');
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
export class ChainedCommandExecutor {
|
|
246
|
+
private readonly executeFn: CommandExecutorFn;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Create a ChainedCommandExecutor
|
|
250
|
+
*
|
|
251
|
+
* @param executeFn - Function to execute individual commands
|
|
252
|
+
*/
|
|
253
|
+
constructor(executeFn: CommandExecutorFn) {
|
|
254
|
+
this.executeFn = executeFn;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Execute a chained command string
|
|
259
|
+
*
|
|
260
|
+
* @param input - Command string (may contain chain operators)
|
|
261
|
+
* @param signal - Optional abort signal for cancellation
|
|
262
|
+
* @returns ChainExecutionResult with execution details
|
|
263
|
+
*/
|
|
264
|
+
async execute(input: string, signal?: AbortSignal): Promise<ChainExecutionResult> {
|
|
265
|
+
const parsed = ChainParser.parse(input);
|
|
266
|
+
|
|
267
|
+
if (!parsed.isChained || parsed.segments.length === 0) {
|
|
268
|
+
// Single command or empty - execute directly
|
|
269
|
+
const command = parsed.segments[0]?.command ?? input;
|
|
270
|
+
const result = await this.executeFn(command, signal);
|
|
271
|
+
|
|
272
|
+
return {
|
|
273
|
+
result,
|
|
274
|
+
executedCount: 1,
|
|
275
|
+
totalCount: 1,
|
|
276
|
+
completed: true,
|
|
277
|
+
lastExecutedIndex: 0,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
let lastResult: CommandResult = {
|
|
282
|
+
kind: "success",
|
|
283
|
+
message: "",
|
|
284
|
+
};
|
|
285
|
+
let executedCount = 0;
|
|
286
|
+
let lastExecutedIndex = 0;
|
|
287
|
+
|
|
288
|
+
for (let i = 0; i < parsed.segments.length; i++) {
|
|
289
|
+
// Check for abort
|
|
290
|
+
if (signal?.aborted) {
|
|
291
|
+
return {
|
|
292
|
+
result: {
|
|
293
|
+
kind: "error",
|
|
294
|
+
code: "COMMAND_ABORTED",
|
|
295
|
+
message: "Chain execution was cancelled",
|
|
296
|
+
},
|
|
297
|
+
executedCount,
|
|
298
|
+
totalCount: parsed.segments.length,
|
|
299
|
+
completed: false,
|
|
300
|
+
lastExecutedIndex,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const segment = parsed.segments[i];
|
|
305
|
+
if (!segment) continue;
|
|
306
|
+
|
|
307
|
+
// Check if we should execute based on previous operator
|
|
308
|
+
if (i > 0) {
|
|
309
|
+
const prevSegment = parsed.segments[i - 1];
|
|
310
|
+
const prevOperator = prevSegment?.operator;
|
|
311
|
+
const prevSucceeded = lastResult.kind === "success";
|
|
312
|
+
|
|
313
|
+
// Apply chain logic
|
|
314
|
+
if (prevOperator === "&&" && !prevSucceeded) {
|
|
315
|
+
// AND: Previous failed, stop chain
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (prevOperator === "||" && prevSucceeded) {
|
|
320
|
+
// OR: Previous succeeded, skip this command
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// ; (SEQUENCE): Always continue
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Execute this command
|
|
328
|
+
lastResult = await this.executeFn(segment.command, signal);
|
|
329
|
+
executedCount++;
|
|
330
|
+
lastExecutedIndex = i;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return {
|
|
334
|
+
result: lastResult,
|
|
335
|
+
executedCount,
|
|
336
|
+
totalCount: parsed.segments.length,
|
|
337
|
+
completed: lastExecutedIndex === parsed.segments.length - 1,
|
|
338
|
+
lastExecutedIndex,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Check if a command would succeed without executing
|
|
344
|
+
* Used for validation purposes
|
|
345
|
+
*
|
|
346
|
+
* @param previousSuccess - Whether previous command succeeded
|
|
347
|
+
* @param operator - Operator connecting to this command
|
|
348
|
+
* @returns true if command should execute
|
|
349
|
+
*/
|
|
350
|
+
static shouldExecute(previousSuccess: boolean, operator: ChainOperator | undefined): boolean {
|
|
351
|
+
if (operator === undefined) {
|
|
352
|
+
// First command or single command
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
switch (operator) {
|
|
357
|
+
case "&&":
|
|
358
|
+
// AND: Execute only if previous succeeded
|
|
359
|
+
return previousSuccess;
|
|
360
|
+
case "||":
|
|
361
|
+
// OR: Execute only if previous failed
|
|
362
|
+
return !previousSuccess;
|
|
363
|
+
case ";":
|
|
364
|
+
// SEQUENCE: Always execute
|
|
365
|
+
return true;
|
|
366
|
+
default:
|
|
367
|
+
return true;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Parser Module Index
|
|
3
|
+
*
|
|
4
|
+
* Exports chain and pipe parsing utilities.
|
|
5
|
+
*
|
|
6
|
+
* @module cli/commands/parser
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
type ChainExecutionResult,
|
|
11
|
+
ChainedCommandExecutor,
|
|
12
|
+
type ChainOperator,
|
|
13
|
+
type ChainParseResult,
|
|
14
|
+
ChainParser,
|
|
15
|
+
type ChainSegment,
|
|
16
|
+
type CommandExecutorFn,
|
|
17
|
+
} from "./chain-parser.js";
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
type FileWriterFn,
|
|
21
|
+
type PipeCommandExecutorFn,
|
|
22
|
+
PipedCommandExecutor,
|
|
23
|
+
type PipeExecutionResult,
|
|
24
|
+
type PipeOperator,
|
|
25
|
+
type PipeParseResult,
|
|
26
|
+
PipeParser,
|
|
27
|
+
type PipeSegment,
|
|
28
|
+
type PipeSegmentType,
|
|
29
|
+
} from "./pipe-parser.js";
|