@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
|
+
* Init Command
|
|
3
|
+
*
|
|
4
|
+
* Interactive wizard to create AGENTS.md for project configuration.
|
|
5
|
+
* Supports both interactive and non-interactive modes.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* - `vellum init` - Interactive wizard
|
|
9
|
+
* - `vellum init --minimal` - Skip wizard, use defaults
|
|
10
|
+
* - `vellum init --force` - Overwrite existing AGENTS.md
|
|
11
|
+
*
|
|
12
|
+
* @module cli/commands/init
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { existsSync } from "node:fs";
|
|
16
|
+
import { writeFile } from "node:fs/promises";
|
|
17
|
+
import { basename, join } from "node:path";
|
|
18
|
+
|
|
19
|
+
import { confirm, input, select } from "@inquirer/prompts";
|
|
20
|
+
import chalk from "chalk";
|
|
21
|
+
|
|
22
|
+
import { EXIT_CODES } from "./exit-codes.js";
|
|
23
|
+
|
|
24
|
+
// =============================================================================
|
|
25
|
+
// Types
|
|
26
|
+
// =============================================================================
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Init command options
|
|
30
|
+
*/
|
|
31
|
+
export interface InitOptions {
|
|
32
|
+
/** Overwrite existing AGENTS.md without prompting */
|
|
33
|
+
force?: boolean;
|
|
34
|
+
/** Skip wizard prompts, use defaults */
|
|
35
|
+
minimal?: boolean;
|
|
36
|
+
/** Non-interactive mode (for CI) */
|
|
37
|
+
nonInteractive?: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Project information gathered from wizard
|
|
42
|
+
*/
|
|
43
|
+
export interface ProjectInfo {
|
|
44
|
+
/** Project name */
|
|
45
|
+
name: string;
|
|
46
|
+
/** Brief description */
|
|
47
|
+
description: string;
|
|
48
|
+
/** Programming language/stack */
|
|
49
|
+
language: string;
|
|
50
|
+
/** Framework (if any) */
|
|
51
|
+
framework: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Init command result
|
|
56
|
+
*/
|
|
57
|
+
export interface InitResult {
|
|
58
|
+
/** Whether initialization succeeded */
|
|
59
|
+
success: boolean;
|
|
60
|
+
/** Output file path */
|
|
61
|
+
filePath?: string;
|
|
62
|
+
/** Error message if failed */
|
|
63
|
+
error?: string;
|
|
64
|
+
/** Exit code */
|
|
65
|
+
exitCode: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// =============================================================================
|
|
69
|
+
// Constants
|
|
70
|
+
// =============================================================================
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Default project name from current directory
|
|
74
|
+
*/
|
|
75
|
+
function getDefaultProjectName(): string {
|
|
76
|
+
return basename(process.cwd());
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Available language choices
|
|
81
|
+
*/
|
|
82
|
+
const LANGUAGE_CHOICES = [
|
|
83
|
+
{ name: "TypeScript", value: "TypeScript" },
|
|
84
|
+
{ name: "JavaScript", value: "JavaScript" },
|
|
85
|
+
{ name: "Python", value: "Python" },
|
|
86
|
+
{ name: "Rust", value: "Rust" },
|
|
87
|
+
{ name: "Go", value: "Go" },
|
|
88
|
+
{ name: "Java", value: "Java" },
|
|
89
|
+
{ name: "C#", value: "C#" },
|
|
90
|
+
{ name: "Other", value: "Other" },
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Available framework choices by language
|
|
95
|
+
*/
|
|
96
|
+
const FRAMEWORK_CHOICES: Record<string, Array<{ name: string; value: string }>> = {
|
|
97
|
+
TypeScript: [
|
|
98
|
+
{ name: "React", value: "React" },
|
|
99
|
+
{ name: "Vue", value: "Vue" },
|
|
100
|
+
{ name: "Node.js", value: "Node.js" },
|
|
101
|
+
{ name: "Next.js", value: "Next.js" },
|
|
102
|
+
{ name: "None", value: "None" },
|
|
103
|
+
],
|
|
104
|
+
JavaScript: [
|
|
105
|
+
{ name: "React", value: "React" },
|
|
106
|
+
{ name: "Vue", value: "Vue" },
|
|
107
|
+
{ name: "Node.js", value: "Node.js" },
|
|
108
|
+
{ name: "Express", value: "Express" },
|
|
109
|
+
{ name: "None", value: "None" },
|
|
110
|
+
],
|
|
111
|
+
Python: [
|
|
112
|
+
{ name: "FastAPI", value: "FastAPI" },
|
|
113
|
+
{ name: "Django", value: "Django" },
|
|
114
|
+
{ name: "Flask", value: "Flask" },
|
|
115
|
+
{ name: "None", value: "None" },
|
|
116
|
+
],
|
|
117
|
+
Rust: [
|
|
118
|
+
{ name: "Actix", value: "Actix" },
|
|
119
|
+
{ name: "Axum", value: "Axum" },
|
|
120
|
+
{ name: "Tokio", value: "Tokio" },
|
|
121
|
+
{ name: "None", value: "None" },
|
|
122
|
+
],
|
|
123
|
+
Go: [
|
|
124
|
+
{ name: "Gin", value: "Gin" },
|
|
125
|
+
{ name: "Echo", value: "Echo" },
|
|
126
|
+
{ name: "Fiber", value: "Fiber" },
|
|
127
|
+
{ name: "None", value: "None" },
|
|
128
|
+
],
|
|
129
|
+
Java: [
|
|
130
|
+
{ name: "Spring Boot", value: "Spring Boot" },
|
|
131
|
+
{ name: "Quarkus", value: "Quarkus" },
|
|
132
|
+
{ name: "None", value: "None" },
|
|
133
|
+
],
|
|
134
|
+
"C#": [
|
|
135
|
+
{ name: ".NET Core", value: ".NET Core" },
|
|
136
|
+
{ name: "ASP.NET", value: "ASP.NET" },
|
|
137
|
+
{ name: "None", value: "None" },
|
|
138
|
+
],
|
|
139
|
+
Other: [{ name: "None", value: "None" }],
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// =============================================================================
|
|
143
|
+
// Template Generation
|
|
144
|
+
// =============================================================================
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Generate AGENTS.md content from project info
|
|
148
|
+
*
|
|
149
|
+
* @param info - Project information
|
|
150
|
+
* @returns Generated AGENTS.md content
|
|
151
|
+
*/
|
|
152
|
+
export function generateAgentsMd(info: ProjectInfo): string {
|
|
153
|
+
const frameworkLine = info.framework && info.framework !== "None" ? `\n- ${info.framework}` : "";
|
|
154
|
+
|
|
155
|
+
return `---
|
|
156
|
+
name: "${info.name}"
|
|
157
|
+
version: "1.0.0"
|
|
158
|
+
description: "${info.description || `AI coding assistant configuration for ${info.name}`}"
|
|
159
|
+
priority: 100
|
|
160
|
+
merge:
|
|
161
|
+
strategy: extend
|
|
162
|
+
arrays: append
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
# Instructions
|
|
166
|
+
|
|
167
|
+
You are an AI coding assistant for ${info.name}.
|
|
168
|
+
|
|
169
|
+
## Tech Stack
|
|
170
|
+
- ${info.language}${frameworkLine}
|
|
171
|
+
|
|
172
|
+
## Coding Standards
|
|
173
|
+
- Follow project conventions
|
|
174
|
+
- Write clean, readable code
|
|
175
|
+
- Use meaningful variable and function names
|
|
176
|
+
- Add appropriate comments for complex logic
|
|
177
|
+
|
|
178
|
+
## Allowed Tools
|
|
179
|
+
- @readonly
|
|
180
|
+
- @edit
|
|
181
|
+
- !bash
|
|
182
|
+
`;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Generate minimal AGENTS.md content
|
|
187
|
+
*
|
|
188
|
+
* @param projectName - Project name
|
|
189
|
+
* @returns Minimal AGENTS.md content
|
|
190
|
+
*/
|
|
191
|
+
export function generateMinimalAgentsMd(projectName: string): string {
|
|
192
|
+
return `---
|
|
193
|
+
name: "${projectName}"
|
|
194
|
+
version: "1.0.0"
|
|
195
|
+
priority: 100
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
# Instructions
|
|
199
|
+
|
|
200
|
+
You are an AI coding assistant for ${projectName}.
|
|
201
|
+
|
|
202
|
+
## Allowed Tools
|
|
203
|
+
- @readonly
|
|
204
|
+
- @edit
|
|
205
|
+
`;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// =============================================================================
|
|
209
|
+
// Wizard Prompts
|
|
210
|
+
// =============================================================================
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Run interactive wizard to gather project information
|
|
214
|
+
*
|
|
215
|
+
* @returns Project information
|
|
216
|
+
*/
|
|
217
|
+
async function runWizard(): Promise<ProjectInfo> {
|
|
218
|
+
console.log(chalk.bold.blue("\n🚀 Initialize AGENTS.md\n"));
|
|
219
|
+
|
|
220
|
+
const name = await input({
|
|
221
|
+
message: "Project name:",
|
|
222
|
+
default: getDefaultProjectName(),
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
const description = await input({
|
|
226
|
+
message: "Brief description (optional):",
|
|
227
|
+
default: "",
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
const language = await select({
|
|
231
|
+
message: "Primary language/stack:",
|
|
232
|
+
choices: LANGUAGE_CHOICES,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const frameworkChoices = FRAMEWORK_CHOICES[language] || [{ name: "None", value: "None" }];
|
|
236
|
+
const framework = await select({
|
|
237
|
+
message: "Framework:",
|
|
238
|
+
choices: frameworkChoices,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
return { name, description, language, framework };
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// =============================================================================
|
|
245
|
+
// Init Command Handler
|
|
246
|
+
// =============================================================================
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Execute init command
|
|
250
|
+
*
|
|
251
|
+
* @param options - Command options
|
|
252
|
+
* @returns Init result
|
|
253
|
+
*/
|
|
254
|
+
export async function executeInit(options: InitOptions = {}): Promise<InitResult> {
|
|
255
|
+
const targetPath = join(process.cwd(), "AGENTS.md");
|
|
256
|
+
|
|
257
|
+
try {
|
|
258
|
+
// Check for existing file
|
|
259
|
+
const fileExists = existsSync(targetPath);
|
|
260
|
+
|
|
261
|
+
if (fileExists && !options.force) {
|
|
262
|
+
// In non-interactive mode, fail if file exists
|
|
263
|
+
if (options.nonInteractive || options.minimal) {
|
|
264
|
+
console.log(chalk.yellow("AGENTS.md already exists. Use --force to overwrite."));
|
|
265
|
+
return {
|
|
266
|
+
success: false,
|
|
267
|
+
error: "File already exists",
|
|
268
|
+
exitCode: EXIT_CODES.ERROR,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Interactive confirmation
|
|
273
|
+
const shouldOverwrite = await confirm({
|
|
274
|
+
message: "AGENTS.md already exists. Overwrite?",
|
|
275
|
+
default: false,
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
if (!shouldOverwrite) {
|
|
279
|
+
console.log(chalk.gray("Aborted."));
|
|
280
|
+
return {
|
|
281
|
+
success: false,
|
|
282
|
+
error: "Aborted by user",
|
|
283
|
+
exitCode: EXIT_CODES.SUCCESS, // User choice, not an error
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Generate content
|
|
289
|
+
let content: string;
|
|
290
|
+
|
|
291
|
+
if (options.minimal || options.nonInteractive) {
|
|
292
|
+
// Use minimal template with defaults
|
|
293
|
+
content = generateMinimalAgentsMd(getDefaultProjectName());
|
|
294
|
+
} else {
|
|
295
|
+
// Run interactive wizard
|
|
296
|
+
const info = await runWizard();
|
|
297
|
+
content = generateAgentsMd(info);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Write file
|
|
301
|
+
await writeFile(targetPath, content, "utf-8");
|
|
302
|
+
|
|
303
|
+
console.log(chalk.green(`\n✅ Created ${targetPath}`));
|
|
304
|
+
console.log(chalk.gray("\nNext steps:"));
|
|
305
|
+
console.log(chalk.gray(" • Review and customize AGENTS.md"));
|
|
306
|
+
console.log(chalk.gray(" • Run `vellum agents validate` to check syntax"));
|
|
307
|
+
console.log(chalk.gray(" • Run `vellum agents show` to view merged config\n"));
|
|
308
|
+
|
|
309
|
+
return {
|
|
310
|
+
success: true,
|
|
311
|
+
filePath: targetPath,
|
|
312
|
+
exitCode: EXIT_CODES.SUCCESS,
|
|
313
|
+
};
|
|
314
|
+
} catch (err) {
|
|
315
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
316
|
+
console.error(chalk.red(`\n❌ Failed to create AGENTS.md: ${message}`));
|
|
317
|
+
return {
|
|
318
|
+
success: false,
|
|
319
|
+
error: message,
|
|
320
|
+
exitCode: EXIT_CODES.ERROR,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// =============================================================================
|
|
326
|
+
// Command Definition (SlashCommand format for TUI)
|
|
327
|
+
// =============================================================================
|
|
328
|
+
|
|
329
|
+
import type { CommandContext, CommandResult, SlashCommand } from "./types.js";
|
|
330
|
+
import { error, pending, success } from "./types.js";
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Init slash command for TUI
|
|
334
|
+
*
|
|
335
|
+
* Creates AGENTS.md in the current working directory.
|
|
336
|
+
*/
|
|
337
|
+
export const initSlashCommand: SlashCommand = {
|
|
338
|
+
name: "init",
|
|
339
|
+
description: "Initialize AGENTS.md for your project",
|
|
340
|
+
kind: "builtin",
|
|
341
|
+
category: "config",
|
|
342
|
+
aliases: [],
|
|
343
|
+
namedArgs: [
|
|
344
|
+
{
|
|
345
|
+
name: "force",
|
|
346
|
+
shorthand: "f",
|
|
347
|
+
type: "boolean",
|
|
348
|
+
description: "Overwrite existing AGENTS.md without prompting",
|
|
349
|
+
required: false,
|
|
350
|
+
default: false,
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
name: "minimal",
|
|
354
|
+
shorthand: "m",
|
|
355
|
+
type: "boolean",
|
|
356
|
+
description: "Skip wizard prompts, use defaults",
|
|
357
|
+
required: false,
|
|
358
|
+
default: false,
|
|
359
|
+
},
|
|
360
|
+
],
|
|
361
|
+
examples: [
|
|
362
|
+
"/init - Interactive wizard",
|
|
363
|
+
"/init --minimal - Skip wizard, use defaults",
|
|
364
|
+
"/init --force - Overwrite existing file",
|
|
365
|
+
],
|
|
366
|
+
|
|
367
|
+
execute: async (ctx: CommandContext): Promise<CommandResult> => {
|
|
368
|
+
const force = ctx.parsedArgs.named.force as boolean | undefined;
|
|
369
|
+
const minimal = ctx.parsedArgs.named.minimal as boolean | undefined;
|
|
370
|
+
|
|
371
|
+
// Return pending result with async operation
|
|
372
|
+
return pending({
|
|
373
|
+
message: "Initializing AGENTS.md...",
|
|
374
|
+
showProgress: true,
|
|
375
|
+
promise: (async (): Promise<CommandResult> => {
|
|
376
|
+
const result = await executeInit({
|
|
377
|
+
force: force ?? false,
|
|
378
|
+
minimal: minimal ?? false,
|
|
379
|
+
// In TUI context, assume interactive is available
|
|
380
|
+
nonInteractive: false,
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
if (result.success) {
|
|
384
|
+
return success(`Created ${result.filePath}`, { filePath: result.filePath });
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return error("INTERNAL_ERROR", result.error ?? "Failed to initialize AGENTS.md");
|
|
388
|
+
})(),
|
|
389
|
+
});
|
|
390
|
+
},
|
|
391
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install/Uninstall Commands (Phase 37)
|
|
3
|
+
* @module cli/commands/install
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { CommandResult, SlashCommand } from "./types.js";
|
|
7
|
+
import { success } from "./types.js";
|
|
8
|
+
|
|
9
|
+
export interface InstallCommandOptions {
|
|
10
|
+
shell?: string;
|
|
11
|
+
force?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface InstallCommandResult {
|
|
15
|
+
success: boolean;
|
|
16
|
+
message?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface UninstallCommandOptions {
|
|
20
|
+
shell?: string;
|
|
21
|
+
force?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Install command
|
|
26
|
+
*/
|
|
27
|
+
export const installCommand: SlashCommand = {
|
|
28
|
+
name: "install",
|
|
29
|
+
description: "Install shell integration",
|
|
30
|
+
kind: "builtin",
|
|
31
|
+
category: "system",
|
|
32
|
+
execute: async (): Promise<CommandResult> => success("Install command not yet implemented"),
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Uninstall command
|
|
37
|
+
*/
|
|
38
|
+
export const uninstallCommand: SlashCommand = {
|
|
39
|
+
name: "uninstall",
|
|
40
|
+
description: "Uninstall shell integration",
|
|
41
|
+
kind: "builtin",
|
|
42
|
+
category: "system",
|
|
43
|
+
execute: async (): Promise<CommandResult> => success("Uninstall command not yet implemented"),
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Execute install
|
|
48
|
+
*/
|
|
49
|
+
export async function executeInstall(
|
|
50
|
+
_options?: InstallCommandOptions
|
|
51
|
+
): Promise<InstallCommandResult> {
|
|
52
|
+
return { success: true, message: "Installed" };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Execute uninstall
|
|
57
|
+
*/
|
|
58
|
+
export async function executeUninstall(
|
|
59
|
+
_options?: UninstallCommandOptions
|
|
60
|
+
): Promise<InstallCommandResult> {
|
|
61
|
+
return { success: true, message: "Uninstalled" };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Handle install
|
|
66
|
+
*/
|
|
67
|
+
export async function handleInstall(_options?: InstallCommandOptions): Promise<void> {
|
|
68
|
+
// Placeholder
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Handle uninstall
|
|
73
|
+
*/
|
|
74
|
+
export async function handleUninstall(_options?: UninstallCommandOptions): Promise<void> {
|
|
75
|
+
// Placeholder
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Print install result
|
|
80
|
+
*/
|
|
81
|
+
export function printInstallResult(_result: InstallCommandResult): void {
|
|
82
|
+
// Placeholder
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Print uninstall result
|
|
87
|
+
*/
|
|
88
|
+
export function printUninstallResult(_result: InstallCommandResult): void {
|
|
89
|
+
// Placeholder
|
|
90
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language Command
|
|
3
|
+
*
|
|
4
|
+
* Slash command for viewing and changing the TUI language setting.
|
|
5
|
+
*
|
|
6
|
+
* @module cli/commands/language
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
clearSavedLanguage,
|
|
11
|
+
getAvailableLocales,
|
|
12
|
+
getGlobalLocale,
|
|
13
|
+
getLanguageDisplayName,
|
|
14
|
+
isLocaleSupported,
|
|
15
|
+
type LocaleCode,
|
|
16
|
+
saveLanguage,
|
|
17
|
+
setGlobalLocale,
|
|
18
|
+
} from "../tui/i18n/index.js";
|
|
19
|
+
import type { CommandContext, CommandResult, SlashCommand } from "./types.js";
|
|
20
|
+
|
|
21
|
+
// =============================================================================
|
|
22
|
+
// T011/T012: Language Command Implementation
|
|
23
|
+
// =============================================================================
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Format a locale for display with its native name.
|
|
27
|
+
*
|
|
28
|
+
* @param locale - The locale code
|
|
29
|
+
* @returns Formatted string like "zh (中文)"
|
|
30
|
+
*/
|
|
31
|
+
function formatLocale(locale: LocaleCode): string {
|
|
32
|
+
return `${locale} (${getLanguageDisplayName(locale)})`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Build the list of available languages for display.
|
|
37
|
+
*
|
|
38
|
+
* @returns Formatted list of available locales
|
|
39
|
+
*/
|
|
40
|
+
function buildLanguageList(): string {
|
|
41
|
+
const locales = getAvailableLocales();
|
|
42
|
+
return locales.map((locale) => ` • ${formatLocale(locale)}`).join("\n");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Handle no-argument case: show current locale and list available languages.
|
|
47
|
+
*
|
|
48
|
+
* @returns Success result with current language info
|
|
49
|
+
*/
|
|
50
|
+
function handleShowCurrent(): CommandResult {
|
|
51
|
+
const currentLocale = getGlobalLocale();
|
|
52
|
+
const availableList = buildLanguageList();
|
|
53
|
+
|
|
54
|
+
const message = [
|
|
55
|
+
`Current language: ${currentLocale}`,
|
|
56
|
+
"",
|
|
57
|
+
"Available languages:",
|
|
58
|
+
availableList,
|
|
59
|
+
"",
|
|
60
|
+
'Use "/language <code>" to switch, or "/language auto" for auto-detection.',
|
|
61
|
+
].join("\n");
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
kind: "success",
|
|
65
|
+
message,
|
|
66
|
+
data: {
|
|
67
|
+
currentLocale,
|
|
68
|
+
availableLocales: getAvailableLocales(),
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Handle "auto" argument: clear saved preference and use auto-detection.
|
|
75
|
+
*
|
|
76
|
+
* @returns Success result confirming auto mode
|
|
77
|
+
*/
|
|
78
|
+
function handleAutoDetect(): CommandResult {
|
|
79
|
+
clearSavedLanguage();
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
kind: "success",
|
|
83
|
+
message:
|
|
84
|
+
"Language preference cleared. Auto-detection will be used.\nRestart the application for the change to take effect.",
|
|
85
|
+
data: {
|
|
86
|
+
mode: "auto",
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Handle valid locale code: switch to that language and save preference.
|
|
93
|
+
*
|
|
94
|
+
* @param locale - The valid locale code to switch to
|
|
95
|
+
* @returns Success result confirming language change
|
|
96
|
+
*/
|
|
97
|
+
function handleValidLocale(locale: LocaleCode): CommandResult {
|
|
98
|
+
// Save the preference for future sessions
|
|
99
|
+
saveLanguage(locale);
|
|
100
|
+
|
|
101
|
+
// Switch immediately for the current session
|
|
102
|
+
setGlobalLocale(locale);
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
kind: "success",
|
|
106
|
+
message: `Language changed to ${formatLocale(locale)}.`,
|
|
107
|
+
data: {
|
|
108
|
+
locale,
|
|
109
|
+
displayName: getLanguageDisplayName(locale),
|
|
110
|
+
},
|
|
111
|
+
refresh: true,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Handle invalid locale code: show error with suggestions.
|
|
117
|
+
*
|
|
118
|
+
* @param input - The invalid locale string provided
|
|
119
|
+
* @returns Error result with available options
|
|
120
|
+
*/
|
|
121
|
+
function handleInvalidLocale(input: string): CommandResult {
|
|
122
|
+
const availableList = buildLanguageList();
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
kind: "error",
|
|
126
|
+
code: "INVALID_ARGUMENT",
|
|
127
|
+
message: `Unknown language: "${input}"`,
|
|
128
|
+
suggestions: [
|
|
129
|
+
`Available languages:\n${availableList}`,
|
|
130
|
+
'Use "/language auto" for auto-detection',
|
|
131
|
+
],
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Language command - view or change the current language setting
|
|
137
|
+
*
|
|
138
|
+
* Usage:
|
|
139
|
+
* /language - Show current language and available options
|
|
140
|
+
* /language <code> - Switch to a specific language (e.g., /language zh)
|
|
141
|
+
* /language auto - Clear preference and use auto-detection
|
|
142
|
+
*/
|
|
143
|
+
export const languageCommand: SlashCommand = {
|
|
144
|
+
name: "language",
|
|
145
|
+
description: "Change or view current language setting",
|
|
146
|
+
kind: "builtin",
|
|
147
|
+
category: "config",
|
|
148
|
+
aliases: ["lang"],
|
|
149
|
+
positionalArgs: [
|
|
150
|
+
{
|
|
151
|
+
name: "locale",
|
|
152
|
+
type: "string",
|
|
153
|
+
description: 'Language code (e.g., "en", "zh") or "auto"',
|
|
154
|
+
required: false,
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
examples: [
|
|
158
|
+
"/language - Show current language",
|
|
159
|
+
"/language zh - Switch to Chinese",
|
|
160
|
+
"/language auto - Use auto-detection",
|
|
161
|
+
],
|
|
162
|
+
subcommands: [
|
|
163
|
+
{ name: "en", description: "English" },
|
|
164
|
+
{ name: "zh", description: "中文" },
|
|
165
|
+
{ name: "auto", description: "Auto-detect" },
|
|
166
|
+
],
|
|
167
|
+
|
|
168
|
+
execute: async (ctx: CommandContext): Promise<CommandResult> => {
|
|
169
|
+
const { parsedArgs } = ctx;
|
|
170
|
+
|
|
171
|
+
// Case 1: No arguments - show current locale and available options
|
|
172
|
+
if (parsedArgs.positional.length === 0) {
|
|
173
|
+
return handleShowCurrent();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const localeArg = String(parsedArgs.positional[0]).toLowerCase().trim();
|
|
177
|
+
|
|
178
|
+
// Case 2: "auto" - clear saved preference
|
|
179
|
+
if (localeArg === "auto") {
|
|
180
|
+
return handleAutoDetect();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Case 3: Valid locale code - switch to that language
|
|
184
|
+
if (isLocaleSupported(localeArg)) {
|
|
185
|
+
return handleValidLocale(localeArg);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Case 4: Invalid locale code - show error with suggestions
|
|
189
|
+
return handleInvalidLocale(localeArg);
|
|
190
|
+
},
|
|
191
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Placeholder to track empty directory in Git
|