@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,366 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Init Prompts Command
|
|
3
|
+
*
|
|
4
|
+
* Scaffolds the .vellum/ directory structure for customizing prompts,
|
|
5
|
+
* rules, skills, commands, and workflows.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* - `vellum init prompts` - Interactive scaffolding
|
|
9
|
+
* - `vellum init prompts --force` - Overwrite existing .vellum/
|
|
10
|
+
*
|
|
11
|
+
* @module cli/commands/init/prompts
|
|
12
|
+
* @see REQ-015
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { dirname, join } from "node:path";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
|
|
19
|
+
import { confirm } from "@inquirer/prompts";
|
|
20
|
+
import chalk from "chalk";
|
|
21
|
+
|
|
22
|
+
import { EXIT_CODES } from "../exit-codes.js";
|
|
23
|
+
import type { CommandContext, CommandResult, SlashCommand } from "../types.js";
|
|
24
|
+
import { error, pending, success } from "../types.js";
|
|
25
|
+
|
|
26
|
+
// =============================================================================
|
|
27
|
+
// Constants
|
|
28
|
+
// =============================================================================
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Directory structure to scaffold
|
|
32
|
+
*/
|
|
33
|
+
const SCAFFOLD_DIRECTORIES = [
|
|
34
|
+
"prompts",
|
|
35
|
+
"prompts/roles",
|
|
36
|
+
"prompts/providers",
|
|
37
|
+
"prompts/spec",
|
|
38
|
+
"prompts/workers",
|
|
39
|
+
"prompts/custom",
|
|
40
|
+
"rules",
|
|
41
|
+
"skills",
|
|
42
|
+
"commands",
|
|
43
|
+
"workflows",
|
|
44
|
+
] as const;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* README files to copy from templates
|
|
48
|
+
*/
|
|
49
|
+
const README_MAPPINGS: Record<string, string> = {
|
|
50
|
+
prompts: "prompts-readme.md",
|
|
51
|
+
rules: "rules-readme.md",
|
|
52
|
+
skills: "skills-readme.md",
|
|
53
|
+
commands: "commands-readme.md",
|
|
54
|
+
workflows: "workflows-readme.md",
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Example files to copy from templates
|
|
59
|
+
*/
|
|
60
|
+
const EXAMPLE_MAPPINGS: Record<string, string> = {
|
|
61
|
+
"commands/summarize.example.md": "example-command.md",
|
|
62
|
+
"workflows/bugfix.example.md": "example-workflow.md",
|
|
63
|
+
"skills/react-patterns/SKILL.md": "example-skill.md",
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// =============================================================================
|
|
67
|
+
// Types
|
|
68
|
+
// =============================================================================
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Options for init prompts command
|
|
72
|
+
*/
|
|
73
|
+
export interface InitPromptsOptions {
|
|
74
|
+
/** Overwrite existing .vellum/ without prompting */
|
|
75
|
+
force?: boolean;
|
|
76
|
+
/** Non-interactive mode (for CI) */
|
|
77
|
+
nonInteractive?: boolean;
|
|
78
|
+
/** Working directory (defaults to process.cwd()) */
|
|
79
|
+
cwd?: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Result of init prompts command
|
|
84
|
+
*/
|
|
85
|
+
export interface InitPromptsResult {
|
|
86
|
+
/** Whether initialization succeeded */
|
|
87
|
+
success: boolean;
|
|
88
|
+
/** Path to created .vellum/ directory */
|
|
89
|
+
vellumPath?: string;
|
|
90
|
+
/** Directories created */
|
|
91
|
+
directoriesCreated?: string[];
|
|
92
|
+
/** Files created */
|
|
93
|
+
filesCreated?: string[];
|
|
94
|
+
/** Error message if failed */
|
|
95
|
+
error?: string;
|
|
96
|
+
/** Exit code */
|
|
97
|
+
exitCode: number;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// =============================================================================
|
|
101
|
+
// Template Loading
|
|
102
|
+
// =============================================================================
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Get the templates directory path
|
|
106
|
+
*/
|
|
107
|
+
function getTemplatesDir(): string {
|
|
108
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
109
|
+
return join(dirname(currentFile), "templates");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Read a template file
|
|
114
|
+
*/
|
|
115
|
+
function readTemplate(templateName: string): string | null {
|
|
116
|
+
try {
|
|
117
|
+
const templatePath = join(getTemplatesDir(), templateName);
|
|
118
|
+
return readFileSync(templatePath, "utf-8");
|
|
119
|
+
} catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// =============================================================================
|
|
125
|
+
// Scaffolding Logic
|
|
126
|
+
// =============================================================================
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Create the .vellum/ directory structure
|
|
130
|
+
*
|
|
131
|
+
* @param rootDir - Project root directory
|
|
132
|
+
* @returns Created directories and files
|
|
133
|
+
*/
|
|
134
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Multiple directory/file creation paths required
|
|
135
|
+
function scaffoldVellumDirectory(rootDir: string): {
|
|
136
|
+
directories: string[];
|
|
137
|
+
files: string[];
|
|
138
|
+
} {
|
|
139
|
+
const vellumPath = join(rootDir, ".vellum");
|
|
140
|
+
const directories: string[] = [];
|
|
141
|
+
const files: string[] = [];
|
|
142
|
+
|
|
143
|
+
// Create main .vellum directory
|
|
144
|
+
if (!existsSync(vellumPath)) {
|
|
145
|
+
mkdirSync(vellumPath, { recursive: true });
|
|
146
|
+
directories.push(".vellum");
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Create subdirectories
|
|
150
|
+
for (const subdir of SCAFFOLD_DIRECTORIES) {
|
|
151
|
+
const fullPath = join(vellumPath, subdir);
|
|
152
|
+
if (!existsSync(fullPath)) {
|
|
153
|
+
mkdirSync(fullPath, { recursive: true });
|
|
154
|
+
directories.push(`.vellum/${subdir}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Copy README files
|
|
159
|
+
for (const [targetDir, templateFile] of Object.entries(README_MAPPINGS)) {
|
|
160
|
+
const targetPath = join(vellumPath, targetDir, "README.md");
|
|
161
|
+
if (!existsSync(targetPath)) {
|
|
162
|
+
const content = readTemplate(templateFile);
|
|
163
|
+
if (content) {
|
|
164
|
+
writeFileSync(targetPath, content, "utf-8");
|
|
165
|
+
files.push(`.vellum/${targetDir}/README.md`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Copy example files
|
|
171
|
+
for (const [targetFile, templateFile] of Object.entries(EXAMPLE_MAPPINGS)) {
|
|
172
|
+
const targetPath = join(vellumPath, targetFile);
|
|
173
|
+
const targetDirPath = dirname(targetPath);
|
|
174
|
+
|
|
175
|
+
// Ensure parent directory exists (for nested paths like skills/react-patterns/)
|
|
176
|
+
if (!existsSync(targetDirPath)) {
|
|
177
|
+
mkdirSync(targetDirPath, { recursive: true });
|
|
178
|
+
const relativePath = targetDirPath
|
|
179
|
+
.replace(`${vellumPath}/`, "")
|
|
180
|
+
.replace(`${vellumPath}\\`, "");
|
|
181
|
+
if (!directories.includes(`.vellum/${relativePath}`)) {
|
|
182
|
+
directories.push(`.vellum/${relativePath}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (!existsSync(targetPath)) {
|
|
187
|
+
const content = readTemplate(templateFile);
|
|
188
|
+
if (content) {
|
|
189
|
+
writeFileSync(targetPath, content, "utf-8");
|
|
190
|
+
files.push(`.vellum/${targetFile}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return { directories, files };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// =============================================================================
|
|
199
|
+
// Command Execution
|
|
200
|
+
// =============================================================================
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Execute init prompts command
|
|
204
|
+
*
|
|
205
|
+
* @param options - Command options
|
|
206
|
+
* @returns Init result
|
|
207
|
+
*/
|
|
208
|
+
export async function executeInitPrompts(
|
|
209
|
+
options: InitPromptsOptions = {}
|
|
210
|
+
): Promise<InitPromptsResult> {
|
|
211
|
+
const rootDir = options.cwd ?? process.cwd();
|
|
212
|
+
const vellumPath = join(rootDir, ".vellum");
|
|
213
|
+
|
|
214
|
+
try {
|
|
215
|
+
// Check for existing .vellum directory
|
|
216
|
+
const exists = existsSync(vellumPath);
|
|
217
|
+
|
|
218
|
+
if (exists && !options.force) {
|
|
219
|
+
// In non-interactive mode, fail if directory exists
|
|
220
|
+
if (options.nonInteractive) {
|
|
221
|
+
console.log(chalk.yellow(".vellum/ already exists. Use --force to overwrite."));
|
|
222
|
+
return {
|
|
223
|
+
success: false,
|
|
224
|
+
error: "Directory already exists",
|
|
225
|
+
exitCode: EXIT_CODES.ERROR,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Interactive confirmation
|
|
230
|
+
const shouldOverwrite = await confirm({
|
|
231
|
+
message: ".vellum/ already exists. Overwrite?",
|
|
232
|
+
default: false,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
if (!shouldOverwrite) {
|
|
236
|
+
console.log(chalk.gray("Aborted."));
|
|
237
|
+
return {
|
|
238
|
+
success: false,
|
|
239
|
+
error: "Aborted by user",
|
|
240
|
+
exitCode: EXIT_CODES.SUCCESS, // User choice, not an error
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Scaffold the directory structure
|
|
246
|
+
console.log(chalk.blue("\n🔧 Scaffolding .vellum/ directory...\n"));
|
|
247
|
+
|
|
248
|
+
const { directories, files } = scaffoldVellumDirectory(rootDir);
|
|
249
|
+
|
|
250
|
+
// Display created items
|
|
251
|
+
if (directories.length > 0) {
|
|
252
|
+
console.log(chalk.gray("Created directories:"));
|
|
253
|
+
for (const dir of directories) {
|
|
254
|
+
console.log(chalk.gray(` 📁 ${dir}`));
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (files.length > 0) {
|
|
259
|
+
console.log(chalk.gray("\nCreated files:"));
|
|
260
|
+
for (const file of files) {
|
|
261
|
+
console.log(chalk.gray(` 📄 ${file}`));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
console.log(chalk.green("\n✅ .vellum/ directory scaffolded successfully!"));
|
|
266
|
+
console.log(chalk.gray("\nNext steps:"));
|
|
267
|
+
console.log(chalk.gray(" • Add custom prompts to .vellum/prompts/"));
|
|
268
|
+
console.log(chalk.gray(" • Add global rules to .vellum/rules/"));
|
|
269
|
+
console.log(chalk.gray(" • Create skills in .vellum/skills/"));
|
|
270
|
+
console.log(chalk.gray(" • Add custom commands in .vellum/commands/"));
|
|
271
|
+
console.log(chalk.gray(" • Define workflows in .vellum/workflows/"));
|
|
272
|
+
console.log(chalk.gray(" • Run `vellum prompt validate` to check syntax\n"));
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
success: true,
|
|
276
|
+
vellumPath,
|
|
277
|
+
directoriesCreated: directories,
|
|
278
|
+
filesCreated: files,
|
|
279
|
+
exitCode: EXIT_CODES.SUCCESS,
|
|
280
|
+
};
|
|
281
|
+
} catch (err) {
|
|
282
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
283
|
+
console.error(chalk.red(`\n❌ Failed to scaffold .vellum/: ${message}`));
|
|
284
|
+
return {
|
|
285
|
+
success: false,
|
|
286
|
+
error: message,
|
|
287
|
+
exitCode: EXIT_CODES.ERROR,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// =============================================================================
|
|
293
|
+
// Slash Command Definition
|
|
294
|
+
// =============================================================================
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Init prompts slash command for TUI
|
|
298
|
+
*
|
|
299
|
+
* Scaffolds the .vellum/ directory structure.
|
|
300
|
+
*/
|
|
301
|
+
export const initPromptsCommand: SlashCommand = {
|
|
302
|
+
name: "init-prompts",
|
|
303
|
+
description: "Scaffold .vellum/ directory for custom prompts and configuration",
|
|
304
|
+
kind: "builtin",
|
|
305
|
+
category: "config",
|
|
306
|
+
aliases: ["scaffold"],
|
|
307
|
+
namedArgs: [
|
|
308
|
+
{
|
|
309
|
+
name: "force",
|
|
310
|
+
shorthand: "f",
|
|
311
|
+
type: "boolean",
|
|
312
|
+
description: "Overwrite existing .vellum/ without prompting",
|
|
313
|
+
required: false,
|
|
314
|
+
default: false,
|
|
315
|
+
},
|
|
316
|
+
],
|
|
317
|
+
examples: [
|
|
318
|
+
"/init-prompts - Interactive scaffolding",
|
|
319
|
+
"/init-prompts --force - Overwrite existing .vellum/",
|
|
320
|
+
],
|
|
321
|
+
|
|
322
|
+
execute: async (ctx: CommandContext): Promise<CommandResult> => {
|
|
323
|
+
const force = ctx.parsedArgs.named.force as boolean | undefined;
|
|
324
|
+
|
|
325
|
+
return pending({
|
|
326
|
+
message: "Scaffolding .vellum/ directory...",
|
|
327
|
+
showProgress: true,
|
|
328
|
+
promise: (async (): Promise<CommandResult> => {
|
|
329
|
+
const result = await executeInitPrompts({
|
|
330
|
+
force: force ?? false,
|
|
331
|
+
nonInteractive: false,
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
if (result.success) {
|
|
335
|
+
const createdCount =
|
|
336
|
+
(result.directoriesCreated?.length ?? 0) + (result.filesCreated?.length ?? 0);
|
|
337
|
+
return success(`Scaffolded ${createdCount} items in .vellum/`, {
|
|
338
|
+
vellumPath: result.vellumPath,
|
|
339
|
+
directoriesCreated: result.directoriesCreated,
|
|
340
|
+
filesCreated: result.filesCreated,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return error("INTERNAL_ERROR", result.error ?? "Failed to scaffold .vellum/");
|
|
345
|
+
})(),
|
|
346
|
+
});
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
// =============================================================================
|
|
351
|
+
// CLI Entry Point
|
|
352
|
+
// =============================================================================
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Run init prompts command from CLI
|
|
356
|
+
*
|
|
357
|
+
* @param options - CLI options
|
|
358
|
+
*/
|
|
359
|
+
export async function runInitPromptsCli(options: { force?: boolean }): Promise<void> {
|
|
360
|
+
const result = await executeInitPrompts({
|
|
361
|
+
force: options.force ?? false,
|
|
362
|
+
nonInteractive: false,
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
process.exit(result.exitCode);
|
|
366
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Commands Directory
|
|
2
|
+
|
|
3
|
+
Custom slash commands that extend Vellum's functionality.
|
|
4
|
+
|
|
5
|
+
## Structure
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
commands/
|
|
9
|
+
├── {command-name}.md # Command definition
|
|
10
|
+
└── README.md
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## File Format
|
|
14
|
+
|
|
15
|
+
```markdown
|
|
16
|
+
---
|
|
17
|
+
name: review
|
|
18
|
+
description: Request code review for current changes
|
|
19
|
+
category: tools
|
|
20
|
+
aliases:
|
|
21
|
+
- cr
|
|
22
|
+
- codereview
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# /review Command
|
|
26
|
+
|
|
27
|
+
Review the current changes and provide feedback.
|
|
28
|
+
|
|
29
|
+
## Instructions
|
|
30
|
+
|
|
31
|
+
When this command is invoked:
|
|
32
|
+
|
|
33
|
+
1. Examine the current git diff
|
|
34
|
+
2. Look for potential issues:
|
|
35
|
+
- Code style violations
|
|
36
|
+
- Performance concerns
|
|
37
|
+
- Security vulnerabilities
|
|
38
|
+
- Missing error handling
|
|
39
|
+
3. Provide structured feedback
|
|
40
|
+
|
|
41
|
+
## Output Format
|
|
42
|
+
|
|
43
|
+
Format your review as:
|
|
44
|
+
|
|
45
|
+
### Summary
|
|
46
|
+
Brief overview of changes
|
|
47
|
+
|
|
48
|
+
### Issues Found
|
|
49
|
+
- [ ] Issue 1
|
|
50
|
+
- [ ] Issue 2
|
|
51
|
+
|
|
52
|
+
### Suggestions
|
|
53
|
+
Improvement recommendations
|
|
54
|
+
```markdown
|
|
55
|
+
|
|
56
|
+
## Frontmatter Options
|
|
57
|
+
|
|
58
|
+
| Field | Type | Description |
|
|
59
|
+
|-------|------|-------------|
|
|
60
|
+
| `name` | string | Command name without slash (required) |
|
|
61
|
+
| `description` | string | Help text (required) |
|
|
62
|
+
| `category` | string | Grouping: system, auth, session, navigation, tools, config, debug |
|
|
63
|
+
| `aliases` | string[] | Alternative command names |
|
|
64
|
+
| `enabled` | boolean | Whether command is active |
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
After creating a command file:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Use the command
|
|
72
|
+
/review
|
|
73
|
+
|
|
74
|
+
# Or use an alias
|
|
75
|
+
/cr
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Documentation
|
|
79
|
+
|
|
80
|
+
See [Vellum Commands Documentation](https://vellum.dev/docs/commands) for more details.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: summarize
|
|
3
|
+
description: Summarize the current file or selection
|
|
4
|
+
category: tools
|
|
5
|
+
aliases:
|
|
6
|
+
- sum
|
|
7
|
+
- tldr
|
|
8
|
+
enabled: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# /summarize Command
|
|
12
|
+
|
|
13
|
+
Provide a concise summary of the current context.
|
|
14
|
+
|
|
15
|
+
## Instructions
|
|
16
|
+
|
|
17
|
+
When this command is invoked:
|
|
18
|
+
|
|
19
|
+
1. Identify the current context:
|
|
20
|
+
- If text is selected, summarize the selection
|
|
21
|
+
- If a file is open, summarize the file
|
|
22
|
+
- If in a conversation, summarize recent messages
|
|
23
|
+
|
|
24
|
+
2. Generate a summary that includes:
|
|
25
|
+
- **Purpose**: What does this code/text do?
|
|
26
|
+
- **Key Points**: Main concepts or functionality
|
|
27
|
+
- **Structure**: How is it organized?
|
|
28
|
+
|
|
29
|
+
3. Keep the summary:
|
|
30
|
+
- Concise (3-5 sentences for small content)
|
|
31
|
+
- Structured (use bullet points for complex content)
|
|
32
|
+
- Actionable (highlight important details)
|
|
33
|
+
|
|
34
|
+
## Output Format
|
|
35
|
+
|
|
36
|
+
```markdown
|
|
37
|
+
## Summary
|
|
38
|
+
|
|
39
|
+
**Purpose**: [One-sentence description]
|
|
40
|
+
|
|
41
|
+
**Key Points**:
|
|
42
|
+
- Point 1
|
|
43
|
+
- Point 2
|
|
44
|
+
- Point 3
|
|
45
|
+
|
|
46
|
+
**Notable**: [Any important observations]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Examples
|
|
50
|
+
|
|
51
|
+
### For Code Files
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
## Summary
|
|
55
|
+
|
|
56
|
+
**Purpose**: HTTP request handler for user authentication
|
|
57
|
+
|
|
58
|
+
**Key Points**:
|
|
59
|
+
- Validates JWT tokens from Authorization header
|
|
60
|
+
- Supports both cookie and header-based auth
|
|
61
|
+
- Returns 401 for invalid/expired tokens
|
|
62
|
+
|
|
63
|
+
**Notable**: Rate limiting applied via middleware
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### For Documentation
|
|
67
|
+
|
|
68
|
+
```markdown
|
|
69
|
+
## Summary
|
|
70
|
+
|
|
71
|
+
**Purpose**: API reference for the authentication module
|
|
72
|
+
|
|
73
|
+
**Key Points**:
|
|
74
|
+
- 5 endpoints documented (login, logout, refresh, verify, revoke)
|
|
75
|
+
- OAuth2 flow supported
|
|
76
|
+
- Includes code examples in TypeScript
|
|
77
|
+
|
|
78
|
+
**Notable**: Breaking changes from v1 noted in migration section
|
|
79
|
+
```
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: react-patterns
|
|
3
|
+
description: Best practices and patterns for React development
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
triggers:
|
|
6
|
+
- react
|
|
7
|
+
- component
|
|
8
|
+
- hook
|
|
9
|
+
- jsx
|
|
10
|
+
- tsx
|
|
11
|
+
tags:
|
|
12
|
+
- react
|
|
13
|
+
- frontend
|
|
14
|
+
- typescript
|
|
15
|
+
priority: 100
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# React Patterns Skill
|
|
19
|
+
|
|
20
|
+
Expert knowledge for building React applications with TypeScript.
|
|
21
|
+
|
|
22
|
+
## Core Principles
|
|
23
|
+
|
|
24
|
+
1. **Composition over inheritance**: Build small, reusable components
|
|
25
|
+
2. **Unidirectional data flow**: Props down, events up
|
|
26
|
+
3. **Explicit over implicit**: Prefer explicit prop passing
|
|
27
|
+
4. **Type safety**: Leverage TypeScript for all components
|
|
28
|
+
|
|
29
|
+
## Component Patterns
|
|
30
|
+
|
|
31
|
+
### Functional Components (Preferred)
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
interface ButtonProps {
|
|
35
|
+
label: string;
|
|
36
|
+
onClick: () => void;
|
|
37
|
+
variant?: 'primary' | 'secondary';
|
|
38
|
+
disabled?: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function Button({
|
|
42
|
+
label,
|
|
43
|
+
onClick,
|
|
44
|
+
variant = 'primary',
|
|
45
|
+
disabled = false
|
|
46
|
+
}: ButtonProps) {
|
|
47
|
+
return (
|
|
48
|
+
<button
|
|
49
|
+
className={`btn btn-${variant}`}
|
|
50
|
+
onClick={onClick}
|
|
51
|
+
disabled={disabled}
|
|
52
|
+
>
|
|
53
|
+
{label}
|
|
54
|
+
</button>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```markdown
|
|
58
|
+
|
|
59
|
+
### Compound Components
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
interface TabsContextValue {
|
|
63
|
+
activeTab: string;
|
|
64
|
+
setActiveTab: (tab: string) => void;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const TabsContext = createContext<TabsContextValue | null>(null);
|
|
68
|
+
|
|
69
|
+
function Tabs({ children, defaultTab }: TabsProps) {
|
|
70
|
+
const [activeTab, setActiveTab] = useState(defaultTab);
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<TabsContext.Provider value={{ activeTab, setActiveTab }}>
|
|
74
|
+
<div className="tabs">{children}</div>
|
|
75
|
+
</TabsContext.Provider>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
Tabs.Tab = function Tab({ id, children }: TabProps) {
|
|
80
|
+
const ctx = useContext(TabsContext);
|
|
81
|
+
if (!ctx) throw new Error('Tab must be used within Tabs');
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<button
|
|
85
|
+
className={ctx.activeTab === id ? 'active' : ''}
|
|
86
|
+
onClick={() => ctx.setActiveTab(id)}
|
|
87
|
+
>
|
|
88
|
+
{children}
|
|
89
|
+
</button>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
```markdown
|
|
93
|
+
|
|
94
|
+
## Hook Patterns
|
|
95
|
+
|
|
96
|
+
### Custom Hooks
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
function useLocalStorage<T>(key: string, initialValue: T) {
|
|
100
|
+
const [value, setValue] = useState<T>(() => {
|
|
101
|
+
const stored = localStorage.getItem(key);
|
|
102
|
+
return stored ? JSON.parse(stored) : initialValue;
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
localStorage.setItem(key, JSON.stringify(value));
|
|
107
|
+
}, [key, value]);
|
|
108
|
+
|
|
109
|
+
return [value, setValue] as const;
|
|
110
|
+
}
|
|
111
|
+
```markdown
|
|
112
|
+
|
|
113
|
+
### Cleanup Pattern
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
const controller = new AbortController();
|
|
118
|
+
|
|
119
|
+
fetchData(controller.signal)
|
|
120
|
+
.then(setData)
|
|
121
|
+
.catch(err => {
|
|
122
|
+
if (!controller.signal.aborted) {
|
|
123
|
+
setError(err);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
return () => controller.abort();
|
|
128
|
+
}, []);
|
|
129
|
+
```markdown
|
|
130
|
+
|
|
131
|
+
## Anti-Patterns to Avoid
|
|
132
|
+
|
|
133
|
+
1. **Don't mutate state directly**
|
|
134
|
+
```tsx
|
|
135
|
+
// ❌ Bad
|
|
136
|
+
state.items.push(newItem);
|
|
137
|
+
|
|
138
|
+
// ✅ Good
|
|
139
|
+
setItems([...items, newItem]);
|
|
140
|
+
```text
|
|
141
|
+
|
|
142
|
+
2. **Don't use index as key for dynamic lists**
|
|
143
|
+
```tsx
|
|
144
|
+
// ❌ Bad
|
|
145
|
+
items.map((item, i) => <Item key={i} {...item} />);
|
|
146
|
+
|
|
147
|
+
// ✅ Good
|
|
148
|
+
items.map(item => <Item key={item.id} {...item} />);
|
|
149
|
+
```text
|
|
150
|
+
|
|
151
|
+
3. **Don't overuse useEffect**
|
|
152
|
+
```tsx
|
|
153
|
+
// ❌ Bad - derived state
|
|
154
|
+
const [fullName, setFullName] = useState('');
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
setFullName(`${firstName} ${lastName}`);
|
|
157
|
+
}, [firstName, lastName]);
|
|
158
|
+
|
|
159
|
+
// ✅ Good - compute directly
|
|
160
|
+
const fullName = `${firstName} ${lastName}`;
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Testing Recommendations
|
|
164
|
+
|
|
165
|
+
- Use `@testing-library/react` for component tests
|
|
166
|
+
- Test behavior, not implementation
|
|
167
|
+
- Use `userEvent` over `fireEvent`
|
|
168
|
+
- Mock API calls at the network level with MSW
|