@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,557 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings Integration Module
|
|
3
|
+
*
|
|
4
|
+
* Manages language preference storage in user settings file.
|
|
5
|
+
* Provides graceful error handling for all file operations.
|
|
6
|
+
*
|
|
7
|
+
* @module tui/i18n/settings-integration
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import * as fs from "node:fs";
|
|
11
|
+
import * as os from "node:os";
|
|
12
|
+
import * as path from "node:path";
|
|
13
|
+
import { isConptyTerminal } from "../utils/detectTerminal.js";
|
|
14
|
+
import { isLocaleSupported, type LocaleCode } from "./language-config.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* UI configuration options.
|
|
18
|
+
*/
|
|
19
|
+
export interface UISettings {
|
|
20
|
+
/** Enable alternate screen buffer (default: true) */
|
|
21
|
+
alternateBuffer?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Thinking display mode.
|
|
26
|
+
* - "full": Show thinking content (default, current behavior)
|
|
27
|
+
* - "compact": Only show thinking header, no content preview
|
|
28
|
+
*/
|
|
29
|
+
export type ThinkingDisplayMode = "full" | "compact";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Thinking mode configuration.
|
|
33
|
+
*/
|
|
34
|
+
export interface ThinkingSettings {
|
|
35
|
+
enabled?: boolean;
|
|
36
|
+
budgetTokens?: number;
|
|
37
|
+
priority?: "global" | "mode" | "merge";
|
|
38
|
+
displayMode?: ThinkingDisplayMode;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Model configuration.
|
|
43
|
+
*/
|
|
44
|
+
export interface ModelSettings {
|
|
45
|
+
provider?: string;
|
|
46
|
+
modelId?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Diff view display mode configuration.
|
|
51
|
+
*/
|
|
52
|
+
export type DiffViewMode = "unified" | "side-by-side";
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Settings file structure.
|
|
56
|
+
*/
|
|
57
|
+
export interface VellumSettings {
|
|
58
|
+
language?: LocaleCode;
|
|
59
|
+
bannerSeen?: boolean;
|
|
60
|
+
ui?: UISettings;
|
|
61
|
+
thinking?: ThinkingSettings;
|
|
62
|
+
theme?: string;
|
|
63
|
+
model?: ModelSettings;
|
|
64
|
+
mode?: string; // "vibe" | "plan" | "spec"
|
|
65
|
+
diffViewMode?: DiffViewMode;
|
|
66
|
+
[key: string]: unknown;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get the path to the Vellum settings directory.
|
|
71
|
+
*
|
|
72
|
+
* @returns Absolute path to ~/.vellum/
|
|
73
|
+
*/
|
|
74
|
+
function getSettingsDir(): string {
|
|
75
|
+
return path.join(os.homedir(), ".vellum");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get the path to the Vellum settings file.
|
|
80
|
+
*
|
|
81
|
+
* @returns Absolute path to ~/.vellum/settings.json
|
|
82
|
+
*/
|
|
83
|
+
function getSettingsPath(): string {
|
|
84
|
+
return path.join(getSettingsDir(), "settings.json");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Read and parse the settings file.
|
|
89
|
+
*
|
|
90
|
+
* @returns Parsed settings object, or null on any error
|
|
91
|
+
*/
|
|
92
|
+
function readSettings(): VellumSettings | null {
|
|
93
|
+
try {
|
|
94
|
+
const settingsPath = getSettingsPath();
|
|
95
|
+
if (!fs.existsSync(settingsPath)) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
const content = fs.readFileSync(settingsPath, "utf-8");
|
|
99
|
+
const parsed = JSON.parse(content) as unknown;
|
|
100
|
+
|
|
101
|
+
// Validate that parsed content is an object
|
|
102
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return parsed as VellumSettings;
|
|
107
|
+
} catch {
|
|
108
|
+
// Silently handle any error (file not found, permission, parse error, etc.)
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Write settings to the settings file.
|
|
115
|
+
*
|
|
116
|
+
* Creates the settings directory if it doesn't exist.
|
|
117
|
+
*
|
|
118
|
+
* @param settings - Settings object to write
|
|
119
|
+
* @returns True if successful, false on any error
|
|
120
|
+
*/
|
|
121
|
+
function writeSettings(settings: VellumSettings): boolean {
|
|
122
|
+
try {
|
|
123
|
+
const settingsDir = getSettingsDir();
|
|
124
|
+
const settingsPath = getSettingsPath();
|
|
125
|
+
|
|
126
|
+
// Ensure settings directory exists
|
|
127
|
+
if (!fs.existsSync(settingsDir)) {
|
|
128
|
+
fs.mkdirSync(settingsDir, { recursive: true });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const content = JSON.stringify(settings, null, 2);
|
|
132
|
+
fs.writeFileSync(settingsPath, content, "utf-8");
|
|
133
|
+
return true;
|
|
134
|
+
} catch {
|
|
135
|
+
// Silently handle any error (permission, disk space, etc.)
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Load the current settings from the settings file.
|
|
142
|
+
*
|
|
143
|
+
* @returns Current settings object, or empty object if file doesn't exist
|
|
144
|
+
*/
|
|
145
|
+
export function loadSettings(): VellumSettings {
|
|
146
|
+
return readSettings() ?? {};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Save settings to the settings file.
|
|
151
|
+
*
|
|
152
|
+
* @param settings - Complete settings object to save
|
|
153
|
+
* @returns True if successful, false on error
|
|
154
|
+
*/
|
|
155
|
+
export function saveSettings(settings: VellumSettings): boolean {
|
|
156
|
+
return writeSettings(settings);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Save a single user setting by key.
|
|
161
|
+
*
|
|
162
|
+
* This is a convenience helper that loads current settings,
|
|
163
|
+
* updates the specified key, and saves back to disk.
|
|
164
|
+
*
|
|
165
|
+
* @param key - The setting key to update
|
|
166
|
+
* @param value - The new value for the setting
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* await saveUserSetting("thinking", { enabled: true, budgetTokens: 20000 });
|
|
171
|
+
* await saveUserSetting("theme", "dracula");
|
|
172
|
+
* await saveUserSetting("mode", "plan");
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
export async function saveUserSetting<K extends keyof VellumSettings>(
|
|
176
|
+
key: K,
|
|
177
|
+
value: VellumSettings[K]
|
|
178
|
+
): Promise<void> {
|
|
179
|
+
const current = loadSettings();
|
|
180
|
+
const updated = { ...current, [key]: value };
|
|
181
|
+
saveSettings(updated);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Get the saved language preference from settings.
|
|
186
|
+
*
|
|
187
|
+
* @returns Saved locale code, or undefined if not set or invalid
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```typescript
|
|
191
|
+
* const savedLang = getSavedLanguage();
|
|
192
|
+
* if (savedLang) {
|
|
193
|
+
* setLocale(savedLang);
|
|
194
|
+
* }
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
export function getSavedLanguage(): LocaleCode | undefined {
|
|
198
|
+
const settings = readSettings();
|
|
199
|
+
if (!settings?.language) {
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Validate that the saved language is still supported
|
|
204
|
+
if (!isLocaleSupported(settings.language)) {
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return settings.language;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Save language preference to settings.
|
|
213
|
+
*
|
|
214
|
+
* Creates the settings file and directory if they don't exist.
|
|
215
|
+
* Preserves other settings in the file.
|
|
216
|
+
*
|
|
217
|
+
* @param locale - The locale code to save
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* saveLanguage("zh");
|
|
222
|
+
* // Now getSavedLanguage() returns "zh"
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
export function saveLanguage(locale: LocaleCode): void {
|
|
226
|
+
const existingSettings = readSettings() ?? {};
|
|
227
|
+
const newSettings: VellumSettings = {
|
|
228
|
+
...existingSettings,
|
|
229
|
+
language: locale,
|
|
230
|
+
};
|
|
231
|
+
writeSettings(newSettings);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Remove language preference from settings.
|
|
236
|
+
*
|
|
237
|
+
* Preserves other settings in the file.
|
|
238
|
+
* Does nothing if settings file doesn't exist.
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* clearSavedLanguage();
|
|
243
|
+
* // Now getSavedLanguage() returns undefined
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
export function clearSavedLanguage(): void {
|
|
247
|
+
const settings = readSettings();
|
|
248
|
+
if (!settings) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Remove the language property while preserving others
|
|
253
|
+
const { language: _, ...rest } = settings;
|
|
254
|
+
writeSettings(rest as VellumSettings);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Check whether the startup banner has been shown before.
|
|
259
|
+
*
|
|
260
|
+
* @returns True if the banner has been shown, false otherwise
|
|
261
|
+
*/
|
|
262
|
+
export function getBannerSeen(): boolean {
|
|
263
|
+
const settings = readSettings();
|
|
264
|
+
return settings?.bannerSeen === true;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Persist the banner seen flag.
|
|
269
|
+
*
|
|
270
|
+
* @param seen - Whether the banner has been shown
|
|
271
|
+
*/
|
|
272
|
+
export function setBannerSeen(seen: boolean): void {
|
|
273
|
+
const existingSettings = readSettings() ?? {};
|
|
274
|
+
const newSettings: VellumSettings = {
|
|
275
|
+
...existingSettings,
|
|
276
|
+
bannerSeen: seen,
|
|
277
|
+
};
|
|
278
|
+
writeSettings(newSettings);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// =============================================================================
|
|
282
|
+
// UI Settings
|
|
283
|
+
// =============================================================================
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Get the alternate buffer preference from settings.
|
|
287
|
+
*
|
|
288
|
+
* @returns True if alternate buffer is enabled (default: true), false if disabled
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```typescript
|
|
292
|
+
* const altBufferEnabled = getAlternateBufferEnabled();
|
|
293
|
+
* ```
|
|
294
|
+
*/
|
|
295
|
+
export function getAlternateBufferSetting(): boolean | undefined {
|
|
296
|
+
const settings = readSettings();
|
|
297
|
+
return settings?.ui?.alternateBuffer;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export function getDefaultAlternateBufferEnabled(): boolean {
|
|
301
|
+
return !isConptyTerminal();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export function getAlternateBufferEnabled(): boolean {
|
|
305
|
+
const explicit = getAlternateBufferSetting();
|
|
306
|
+
if (typeof explicit === "boolean") {
|
|
307
|
+
return explicit;
|
|
308
|
+
}
|
|
309
|
+
return getDefaultAlternateBufferEnabled();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Save alternate buffer preference to settings.
|
|
314
|
+
*
|
|
315
|
+
* Creates the settings file and directory if they don't exist.
|
|
316
|
+
* Preserves other settings in the file.
|
|
317
|
+
*
|
|
318
|
+
* @param enabled - Whether to enable alternate buffer
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* ```typescript
|
|
322
|
+
* setAlternateBufferEnabled(false);
|
|
323
|
+
* // Now getAlternateBufferEnabled() returns false
|
|
324
|
+
* ```
|
|
325
|
+
*/
|
|
326
|
+
export function setAlternateBufferEnabled(enabled: boolean): void {
|
|
327
|
+
const existingSettings = readSettings() ?? {};
|
|
328
|
+
const newSettings: VellumSettings = {
|
|
329
|
+
...existingSettings,
|
|
330
|
+
ui: {
|
|
331
|
+
...existingSettings.ui,
|
|
332
|
+
alternateBuffer: enabled,
|
|
333
|
+
},
|
|
334
|
+
};
|
|
335
|
+
writeSettings(newSettings);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Get all UI settings.
|
|
340
|
+
*
|
|
341
|
+
* @returns UI settings object with defaults applied
|
|
342
|
+
*/
|
|
343
|
+
export function getUISettings(): UISettings {
|
|
344
|
+
const settings = readSettings();
|
|
345
|
+
return {
|
|
346
|
+
alternateBuffer: settings?.ui?.alternateBuffer ?? getDefaultAlternateBufferEnabled(),
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// =============================================================================
|
|
351
|
+
// Thinking Settings
|
|
352
|
+
// =============================================================================
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Get the saved thinking settings.
|
|
356
|
+
*
|
|
357
|
+
* @returns Thinking settings object, or undefined if not saved
|
|
358
|
+
*
|
|
359
|
+
* @example
|
|
360
|
+
* ```typescript
|
|
361
|
+
* const thinking = getThinkingSettings();
|
|
362
|
+
* if (thinking?.enabled) {
|
|
363
|
+
* enableThinking(thinking.budgetTokens);
|
|
364
|
+
* }
|
|
365
|
+
* ```
|
|
366
|
+
*/
|
|
367
|
+
export function getThinkingSettings(): ThinkingSettings | undefined {
|
|
368
|
+
const settings = readSettings();
|
|
369
|
+
return settings?.thinking;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Save thinking settings.
|
|
374
|
+
*
|
|
375
|
+
* @param thinking - Thinking settings to save
|
|
376
|
+
*/
|
|
377
|
+
export function setThinkingSettings(thinking: ThinkingSettings): void {
|
|
378
|
+
const existingSettings = readSettings() ?? {};
|
|
379
|
+
const newSettings: VellumSettings = {
|
|
380
|
+
...existingSettings,
|
|
381
|
+
thinking,
|
|
382
|
+
};
|
|
383
|
+
writeSettings(newSettings);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Get the thinking display mode preference.
|
|
388
|
+
*
|
|
389
|
+
* @returns Display mode ("full" or "compact"), defaults to "full"
|
|
390
|
+
*
|
|
391
|
+
* @example
|
|
392
|
+
* ```typescript
|
|
393
|
+
* const mode = getThinkingDisplayMode();
|
|
394
|
+
* // mode is "full" | "compact"
|
|
395
|
+
* ```
|
|
396
|
+
*/
|
|
397
|
+
export function getThinkingDisplayMode(): ThinkingDisplayMode {
|
|
398
|
+
const settings = readSettings();
|
|
399
|
+
const mode = settings?.thinking?.displayMode;
|
|
400
|
+
if (mode === "full" || mode === "compact") {
|
|
401
|
+
return mode;
|
|
402
|
+
}
|
|
403
|
+
return "full"; // Default
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Set the thinking display mode preference.
|
|
408
|
+
*
|
|
409
|
+
* @param mode - Display mode to save ("full" or "compact")
|
|
410
|
+
*
|
|
411
|
+
* @example
|
|
412
|
+
* ```typescript
|
|
413
|
+
* setThinkingDisplayMode("compact");
|
|
414
|
+
* // Now thinking blocks will be compact by default
|
|
415
|
+
* ```
|
|
416
|
+
*/
|
|
417
|
+
export function setThinkingDisplayMode(mode: ThinkingDisplayMode): void {
|
|
418
|
+
const existingSettings = readSettings() ?? {};
|
|
419
|
+
const existingThinking = existingSettings.thinking ?? {};
|
|
420
|
+
const newSettings: VellumSettings = {
|
|
421
|
+
...existingSettings,
|
|
422
|
+
thinking: {
|
|
423
|
+
...existingThinking,
|
|
424
|
+
displayMode: mode,
|
|
425
|
+
},
|
|
426
|
+
};
|
|
427
|
+
writeSettings(newSettings);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// =============================================================================
|
|
431
|
+
// Theme Settings
|
|
432
|
+
// =============================================================================
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Get the saved theme preference.
|
|
436
|
+
*
|
|
437
|
+
* @returns Theme name, or undefined if not saved
|
|
438
|
+
*/
|
|
439
|
+
export function getThemeFromSettings(): string | undefined {
|
|
440
|
+
const settings = readSettings();
|
|
441
|
+
return settings?.theme;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Save theme preference.
|
|
446
|
+
*
|
|
447
|
+
* @param theme - Theme name to save
|
|
448
|
+
*/
|
|
449
|
+
export function setThemeInSettings(theme: string): void {
|
|
450
|
+
const existingSettings = readSettings() ?? {};
|
|
451
|
+
const newSettings: VellumSettings = {
|
|
452
|
+
...existingSettings,
|
|
453
|
+
theme,
|
|
454
|
+
};
|
|
455
|
+
writeSettings(newSettings);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// =============================================================================
|
|
459
|
+
// Mode Settings
|
|
460
|
+
// =============================================================================
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Get the saved mode preference.
|
|
464
|
+
*
|
|
465
|
+
* @returns Mode name, or undefined if not saved
|
|
466
|
+
*/
|
|
467
|
+
export function getModeFromSettings(): string | undefined {
|
|
468
|
+
const settings = readSettings();
|
|
469
|
+
return settings?.mode;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Save mode preference.
|
|
474
|
+
*
|
|
475
|
+
* @param mode - Mode name to save
|
|
476
|
+
*/
|
|
477
|
+
export function setModeInSettings(mode: string): void {
|
|
478
|
+
const existingSettings = readSettings() ?? {};
|
|
479
|
+
const newSettings: VellumSettings = {
|
|
480
|
+
...existingSettings,
|
|
481
|
+
mode,
|
|
482
|
+
};
|
|
483
|
+
writeSettings(newSettings);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// =============================================================================
|
|
487
|
+
// Model Settings
|
|
488
|
+
// =============================================================================
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Get the saved model configuration.
|
|
492
|
+
*
|
|
493
|
+
* @returns Model settings, or undefined if not saved
|
|
494
|
+
*/
|
|
495
|
+
export function getModelSettings(): ModelSettings | undefined {
|
|
496
|
+
const settings = readSettings();
|
|
497
|
+
return settings?.model;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Save model configuration.
|
|
502
|
+
*
|
|
503
|
+
* @param model - Model settings to save
|
|
504
|
+
*/
|
|
505
|
+
export function setModelSettings(model: ModelSettings): void {
|
|
506
|
+
const existingSettings = readSettings() ?? {};
|
|
507
|
+
const newSettings: VellumSettings = {
|
|
508
|
+
...existingSettings,
|
|
509
|
+
model,
|
|
510
|
+
};
|
|
511
|
+
writeSettings(newSettings);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// =============================================================================
|
|
515
|
+
// Diff View Mode Settings
|
|
516
|
+
// =============================================================================
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Get the saved diff view mode preference.
|
|
520
|
+
*
|
|
521
|
+
* @returns Diff view mode ("unified" or "side-by-side"), or undefined if not saved
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* ```typescript
|
|
525
|
+
* const mode = getDiffViewMode();
|
|
526
|
+
* // mode is "unified" | "side-by-side" | undefined
|
|
527
|
+
* ```
|
|
528
|
+
*/
|
|
529
|
+
export function getDiffViewMode(): DiffViewMode | undefined {
|
|
530
|
+
const settings = readSettings();
|
|
531
|
+
const mode = settings?.diffViewMode;
|
|
532
|
+
// Validate the value
|
|
533
|
+
if (mode === "unified" || mode === "side-by-side") {
|
|
534
|
+
return mode;
|
|
535
|
+
}
|
|
536
|
+
return undefined;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Save diff view mode preference.
|
|
541
|
+
*
|
|
542
|
+
* @param mode - Diff view mode to save ("unified" or "side-by-side")
|
|
543
|
+
*
|
|
544
|
+
* @example
|
|
545
|
+
* ```typescript
|
|
546
|
+
* setDiffViewMode("side-by-side");
|
|
547
|
+
* // Now getDiffViewMode() returns "side-by-side"
|
|
548
|
+
* ```
|
|
549
|
+
*/
|
|
550
|
+
export function setDiffViewMode(mode: DiffViewMode): void {
|
|
551
|
+
const existingSettings = readSettings() ?? {};
|
|
552
|
+
const newSettings: VellumSettings = {
|
|
553
|
+
...existingSettings,
|
|
554
|
+
diffViewMode: mode,
|
|
555
|
+
};
|
|
556
|
+
writeSettings(newSettings);
|
|
557
|
+
}
|