nova-terminal-ai 0.3.4
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/README.md +84 -0
- package/bin/nova +38 -0
- package/bin/nova.js +11 -0
- package/dist/commands/SmartCompletion.d.ts +71 -0
- package/dist/commands/SmartCompletion.d.ts.map +1 -0
- package/dist/commands/SmartCompletion.js +377 -0
- package/dist/commands/SmartCompletion.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/packages/cli/src/commands/SmartCompletion.d.ts +71 -0
- package/dist/packages/cli/src/commands/SmartCompletion.d.ts.map +1 -0
- package/dist/packages/cli/src/commands/SmartCompletion.js +377 -0
- package/dist/packages/cli/src/commands/SmartCompletion.js.map +1 -0
- package/dist/packages/cli/src/index.d.ts +2 -0
- package/dist/packages/cli/src/index.d.ts.map +1 -0
- package/dist/packages/cli/src/index.js +5 -0
- package/dist/packages/cli/src/index.js.map +1 -0
- package/dist/packages/cli/src/startup/IFlowRepl.d.ts +50 -0
- package/dist/packages/cli/src/startup/IFlowRepl.d.ts.map +1 -0
- package/dist/packages/cli/src/startup/IFlowRepl.js +178 -0
- package/dist/packages/cli/src/startup/IFlowRepl.js.map +1 -0
- package/dist/packages/cli/src/startup/InkBasedRepl.d.ts +151 -0
- package/dist/packages/cli/src/startup/InkBasedRepl.d.ts.map +1 -0
- package/dist/packages/cli/src/startup/InkBasedRepl.js +1415 -0
- package/dist/packages/cli/src/startup/InkBasedRepl.js.map +1 -0
- package/dist/packages/cli/src/startup/InteractiveRepl.d.ts +141 -0
- package/dist/packages/cli/src/startup/InteractiveRepl.d.ts.map +1 -0
- package/dist/packages/cli/src/startup/InteractiveRepl.js +2561 -0
- package/dist/packages/cli/src/startup/InteractiveRepl.js.map +1 -0
- package/dist/packages/cli/src/startup/NovaApp.d.ts +57 -0
- package/dist/packages/cli/src/startup/NovaApp.d.ts.map +1 -0
- package/dist/packages/cli/src/startup/NovaApp.js +1978 -0
- package/dist/packages/cli/src/startup/NovaApp.js.map +1 -0
- package/dist/packages/cli/src/startup/index.d.ts +5 -0
- package/dist/packages/cli/src/startup/index.d.ts.map +1 -0
- package/dist/packages/cli/src/startup/index.js +4 -0
- package/dist/packages/cli/src/startup/index.js.map +1 -0
- package/dist/packages/cli/src/startup/parseArgs.d.ts +47 -0
- package/dist/packages/cli/src/startup/parseArgs.d.ts.map +1 -0
- package/dist/packages/cli/src/startup/parseArgs.js +262 -0
- package/dist/packages/cli/src/startup/parseArgs.js.map +1 -0
- package/dist/packages/cli/src/ui/IFlowDropdown.d.ts +63 -0
- package/dist/packages/cli/src/ui/IFlowDropdown.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/IFlowDropdown.js +362 -0
- package/dist/packages/cli/src/ui/IFlowDropdown.js.map +1 -0
- package/dist/packages/cli/src/ui/ModernReplUI.d.ts +55 -0
- package/dist/packages/cli/src/ui/ModernReplUI.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/ModernReplUI.js +207 -0
- package/dist/packages/cli/src/ui/ModernReplUI.js.map +1 -0
- package/dist/packages/cli/src/ui/SimpleSelector2.d.ts +28 -0
- package/dist/packages/cli/src/ui/SimpleSelector2.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/SimpleSelector2.js +181 -0
- package/dist/packages/cli/src/ui/SimpleSelector2.js.map +1 -0
- package/dist/packages/cli/src/ui/components/ActiveCursor.d.ts +128 -0
- package/dist/packages/cli/src/ui/components/ActiveCursor.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/ActiveCursor.js +273 -0
- package/dist/packages/cli/src/ui/components/ActiveCursor.js.map +1 -0
- package/dist/packages/cli/src/ui/components/ConfirmDialog.d.ts +51 -0
- package/dist/packages/cli/src/ui/components/ConfirmDialog.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/ConfirmDialog.js +147 -0
- package/dist/packages/cli/src/ui/components/ConfirmDialog.js.map +1 -0
- package/dist/packages/cli/src/ui/components/ErrorPanel.d.ts +33 -0
- package/dist/packages/cli/src/ui/components/ErrorPanel.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/ErrorPanel.js +309 -0
- package/dist/packages/cli/src/ui/components/ErrorPanel.js.map +1 -0
- package/dist/packages/cli/src/ui/components/InkAppRunner.d.ts +18 -0
- package/dist/packages/cli/src/ui/components/InkAppRunner.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/InkAppRunner.js +33 -0
- package/dist/packages/cli/src/ui/components/InkAppRunner.js.map +1 -0
- package/dist/packages/cli/src/ui/components/InkComponents.d.ts +126 -0
- package/dist/packages/cli/src/ui/components/InkComponents.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/InkComponents.js +216 -0
- package/dist/packages/cli/src/ui/components/InkComponents.js.map +1 -0
- package/dist/packages/cli/src/ui/components/NovaInkApp.d.ts +11 -0
- package/dist/packages/cli/src/ui/components/NovaInkApp.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/NovaInkApp.js +148 -0
- package/dist/packages/cli/src/ui/components/NovaInkApp.js.map +1 -0
- package/dist/packages/cli/src/ui/components/ProgressBar.d.ts +65 -0
- package/dist/packages/cli/src/ui/components/ProgressBar.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/ProgressBar.js +135 -0
- package/dist/packages/cli/src/ui/components/ProgressBar.js.map +1 -0
- package/dist/packages/cli/src/ui/components/ProgressIndicator.d.ts +41 -0
- package/dist/packages/cli/src/ui/components/ProgressIndicator.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/ProgressIndicator.js +235 -0
- package/dist/packages/cli/src/ui/components/ProgressIndicator.js.map +1 -0
- package/dist/packages/cli/src/ui/components/QuickActions.d.ts +36 -0
- package/dist/packages/cli/src/ui/components/QuickActions.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/QuickActions.js +328 -0
- package/dist/packages/cli/src/ui/components/QuickActions.js.map +1 -0
- package/dist/packages/cli/src/ui/components/SimpleErrorPanel.d.ts +16 -0
- package/dist/packages/cli/src/ui/components/SimpleErrorPanel.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/SimpleErrorPanel.js +193 -0
- package/dist/packages/cli/src/ui/components/SimpleErrorPanel.js.map +1 -0
- package/dist/packages/cli/src/ui/components/StatusBar.d.ts +30 -0
- package/dist/packages/cli/src/ui/components/StatusBar.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/StatusBar.js +154 -0
- package/dist/packages/cli/src/ui/components/StatusBar.js.map +1 -0
- package/dist/packages/cli/src/ui/components/ThinkingBlockRenderer.d.ts +109 -0
- package/dist/packages/cli/src/ui/components/ThinkingBlockRenderer.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/ThinkingBlockRenderer.js +335 -0
- package/dist/packages/cli/src/ui/components/ThinkingBlockRenderer.js.map +1 -0
- package/dist/packages/cli/src/ui/components/ThinkingContentDisplay.d.ts +59 -0
- package/dist/packages/cli/src/ui/components/ThinkingContentDisplay.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/ThinkingContentDisplay.js +172 -0
- package/dist/packages/cli/src/ui/components/ThinkingContentDisplay.js.map +1 -0
- package/dist/packages/cli/src/ui/components/TodoProgressPanel.d.ts +91 -0
- package/dist/packages/cli/src/ui/components/TodoProgressPanel.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/TodoProgressPanel.js +284 -0
- package/dist/packages/cli/src/ui/components/TodoProgressPanel.js.map +1 -0
- package/dist/packages/cli/src/ui/components/ToolCallStatusDisplay.d.ts +89 -0
- package/dist/packages/cli/src/ui/components/ToolCallStatusDisplay.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/ToolCallStatusDisplay.js +246 -0
- package/dist/packages/cli/src/ui/components/ToolCallStatusDisplay.js.map +1 -0
- package/dist/packages/cli/src/ui/components/UserMessageHighlight.d.ts +48 -0
- package/dist/packages/cli/src/ui/components/UserMessageHighlight.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/UserMessageHighlight.js +196 -0
- package/dist/packages/cli/src/ui/components/UserMessageHighlight.js.map +1 -0
- package/dist/packages/cli/src/ui/components/index.d.ts +17 -0
- package/dist/packages/cli/src/ui/components/index.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/components/index.js +18 -0
- package/dist/packages/cli/src/ui/components/index.js.map +1 -0
- package/dist/packages/cli/src/ui/ink-prototype.d.ts +3 -0
- package/dist/packages/cli/src/ui/ink-prototype.d.ts.map +1 -0
- package/dist/packages/cli/src/ui/ink-prototype.js +160 -0
- package/dist/packages/cli/src/ui/ink-prototype.js.map +1 -0
- package/dist/packages/cli/src/utils/CliUI.d.ts +163 -0
- package/dist/packages/cli/src/utils/CliUI.d.ts.map +1 -0
- package/dist/packages/cli/src/utils/CliUI.js +292 -0
- package/dist/packages/cli/src/utils/CliUI.js.map +1 -0
- package/dist/packages/cli/src/utils/CompletionHelper.d.ts +112 -0
- package/dist/packages/cli/src/utils/CompletionHelper.d.ts.map +1 -0
- package/dist/packages/cli/src/utils/CompletionHelper.js +304 -0
- package/dist/packages/cli/src/utils/CompletionHelper.js.map +1 -0
- package/dist/packages/cli/src/utils/EnhancedCompleter.d.ts +107 -0
- package/dist/packages/cli/src/utils/EnhancedCompleter.d.ts.map +1 -0
- package/dist/packages/cli/src/utils/EnhancedCompleter.js +428 -0
- package/dist/packages/cli/src/utils/EnhancedCompleter.js.map +1 -0
- package/dist/packages/cli/src/utils/ErrorEnhancer.d.ts +103 -0
- package/dist/packages/cli/src/utils/ErrorEnhancer.d.ts.map +1 -0
- package/dist/packages/cli/src/utils/ErrorEnhancer.js +350 -0
- package/dist/packages/cli/src/utils/ErrorEnhancer.js.map +1 -0
- package/dist/packages/cli/src/utils/OutputFormatter.d.ts +65 -0
- package/dist/packages/cli/src/utils/OutputFormatter.d.ts.map +1 -0
- package/dist/packages/cli/src/utils/OutputFormatter.js +145 -0
- package/dist/packages/cli/src/utils/OutputFormatter.js.map +1 -0
- package/dist/packages/cli/src/utils/index.d.ts +5 -0
- package/dist/packages/cli/src/utils/index.d.ts.map +1 -0
- package/dist/packages/cli/src/utils/index.js +8 -0
- package/dist/packages/cli/src/utils/index.js.map +1 -0
- package/dist/packages/cli/tsconfig.tsbuildinfo +1 -0
- package/dist/packages/core/src/agents/AgentOrchestrator.d.ts +147 -0
- package/dist/packages/core/src/agents/AgentOrchestrator.d.ts.map +1 -0
- package/dist/packages/core/src/agents/AgentOrchestrator.js +358 -0
- package/dist/packages/core/src/agents/AgentOrchestrator.js.map +1 -0
- package/dist/packages/core/src/agents/index.d.ts +3 -0
- package/dist/packages/core/src/agents/index.d.ts.map +1 -0
- package/dist/packages/core/src/agents/index.js +5 -0
- package/dist/packages/core/src/agents/index.js.map +1 -0
- package/dist/packages/core/src/analysis/ProjectAnalyzer.d.ts +95 -0
- package/dist/packages/core/src/analysis/ProjectAnalyzer.d.ts.map +1 -0
- package/dist/packages/core/src/analysis/ProjectAnalyzer.js +656 -0
- package/dist/packages/core/src/analysis/ProjectAnalyzer.js.map +1 -0
- package/dist/packages/core/src/audit/AuditLogger.d.ts +140 -0
- package/dist/packages/core/src/audit/AuditLogger.d.ts.map +1 -0
- package/dist/packages/core/src/audit/AuditLogger.js +357 -0
- package/dist/packages/core/src/audit/AuditLogger.js.map +1 -0
- package/dist/packages/core/src/audit/index.d.ts +3 -0
- package/dist/packages/core/src/audit/index.d.ts.map +1 -0
- package/dist/packages/core/src/audit/index.js +5 -0
- package/dist/packages/core/src/audit/index.js.map +1 -0
- package/dist/packages/core/src/auth/AuthManager.d.ts +38 -0
- package/dist/packages/core/src/auth/AuthManager.d.ts.map +1 -0
- package/dist/packages/core/src/auth/AuthManager.js +120 -0
- package/dist/packages/core/src/auth/AuthManager.js.map +1 -0
- package/dist/packages/core/src/auth/index.d.ts +3 -0
- package/dist/packages/core/src/auth/index.d.ts.map +1 -0
- package/dist/packages/core/src/auth/index.js +2 -0
- package/dist/packages/core/src/auth/index.js.map +1 -0
- package/dist/packages/core/src/config/ConfigManager.d.ts +47 -0
- package/dist/packages/core/src/config/ConfigManager.d.ts.map +1 -0
- package/dist/packages/core/src/config/ConfigManager.js +1197 -0
- package/dist/packages/core/src/config/ConfigManager.js.map +1 -0
- package/dist/packages/core/src/config/index.d.ts +2 -0
- package/dist/packages/core/src/config/index.d.ts.map +1 -0
- package/dist/packages/core/src/config/index.js +2 -0
- package/dist/packages/core/src/config/index.js.map +1 -0
- package/dist/packages/core/src/context/ContextBuilder.d.ts +39 -0
- package/dist/packages/core/src/context/ContextBuilder.d.ts.map +1 -0
- package/dist/packages/core/src/context/ContextBuilder.js +132 -0
- package/dist/packages/core/src/context/ContextBuilder.js.map +1 -0
- package/dist/packages/core/src/context/ContextCompressor.d.ts +147 -0
- package/dist/packages/core/src/context/ContextCompressor.d.ts.map +1 -0
- package/dist/packages/core/src/context/ContextCompressor.js +451 -0
- package/dist/packages/core/src/context/ContextCompressor.js.map +1 -0
- package/dist/packages/core/src/context/LayeredMemoryManager.d.ts +160 -0
- package/dist/packages/core/src/context/LayeredMemoryManager.d.ts.map +1 -0
- package/dist/packages/core/src/context/LayeredMemoryManager.js +505 -0
- package/dist/packages/core/src/context/LayeredMemoryManager.js.map +1 -0
- package/dist/packages/core/src/context/MemoryDiscovery.d.ts +33 -0
- package/dist/packages/core/src/context/MemoryDiscovery.d.ts.map +1 -0
- package/dist/packages/core/src/context/MemoryDiscovery.js +146 -0
- package/dist/packages/core/src/context/MemoryDiscovery.js.map +1 -0
- package/dist/packages/core/src/context/defaultSystemPrompt.d.ts +12 -0
- package/dist/packages/core/src/context/defaultSystemPrompt.d.ts.map +1 -0
- package/dist/packages/core/src/context/defaultSystemPrompt.js +32 -0
- package/dist/packages/core/src/context/defaultSystemPrompt.js.map +1 -0
- package/dist/packages/core/src/context/index.d.ts +9 -0
- package/dist/packages/core/src/context/index.d.ts.map +1 -0
- package/dist/packages/core/src/context/index.js +5 -0
- package/dist/packages/core/src/context/index.js.map +1 -0
- package/dist/packages/core/src/extensions/SkillGenerator.d.ts +77 -0
- package/dist/packages/core/src/extensions/SkillGenerator.d.ts.map +1 -0
- package/dist/packages/core/src/extensions/SkillGenerator.js +323 -0
- package/dist/packages/core/src/extensions/SkillGenerator.js.map +1 -0
- package/dist/packages/core/src/extensions/SkillInstaller.d.ts +74 -0
- package/dist/packages/core/src/extensions/SkillInstaller.d.ts.map +1 -0
- package/dist/packages/core/src/extensions/SkillInstaller.js +216 -0
- package/dist/packages/core/src/extensions/SkillInstaller.js.map +1 -0
- package/dist/packages/core/src/extensions/SkillRegistry.d.ts +99 -0
- package/dist/packages/core/src/extensions/SkillRegistry.d.ts.map +1 -0
- package/dist/packages/core/src/extensions/SkillRegistry.js +263 -0
- package/dist/packages/core/src/extensions/SkillRegistry.js.map +1 -0
- package/dist/packages/core/src/extensions/SkillValidator.d.ts +51 -0
- package/dist/packages/core/src/extensions/SkillValidator.d.ts.map +1 -0
- package/dist/packages/core/src/extensions/SkillValidator.js +465 -0
- package/dist/packages/core/src/extensions/SkillValidator.js.map +1 -0
- package/dist/packages/core/src/extensions/index.d.ts +11 -0
- package/dist/packages/core/src/extensions/index.d.ts.map +1 -0
- package/dist/packages/core/src/extensions/index.js +8 -0
- package/dist/packages/core/src/extensions/index.js.map +1 -0
- package/dist/packages/core/src/index.d.ts +14 -0
- package/dist/packages/core/src/index.d.ts.map +1 -0
- package/dist/packages/core/src/index.js +30 -0
- package/dist/packages/core/src/index.js.map +1 -0
- package/dist/packages/core/src/mcp/McpManager.d.ts +94 -0
- package/dist/packages/core/src/mcp/McpManager.d.ts.map +1 -0
- package/dist/packages/core/src/mcp/McpManager.js +494 -0
- package/dist/packages/core/src/mcp/McpManager.js.map +1 -0
- package/dist/packages/core/src/mcp/index.d.ts +2 -0
- package/dist/packages/core/src/mcp/index.d.ts.map +1 -0
- package/dist/packages/core/src/mcp/index.js +3 -0
- package/dist/packages/core/src/mcp/index.js.map +1 -0
- package/dist/packages/core/src/model/ModelClient.d.ts +40 -0
- package/dist/packages/core/src/model/ModelClient.d.ts.map +1 -0
- package/dist/packages/core/src/model/ModelClient.js +163 -0
- package/dist/packages/core/src/model/ModelClient.js.map +1 -0
- package/dist/packages/core/src/model/ModelConnectionTester.d.ts +58 -0
- package/dist/packages/core/src/model/ModelConnectionTester.d.ts.map +1 -0
- package/dist/packages/core/src/model/ModelConnectionTester.js +311 -0
- package/dist/packages/core/src/model/ModelConnectionTester.js.map +1 -0
- package/dist/packages/core/src/model/ModelValidator.d.ts +39 -0
- package/dist/packages/core/src/model/ModelValidator.d.ts.map +1 -0
- package/dist/packages/core/src/model/ModelValidator.js +296 -0
- package/dist/packages/core/src/model/ModelValidator.js.map +1 -0
- package/dist/packages/core/src/model/index.d.ts +7 -0
- package/dist/packages/core/src/model/index.d.ts.map +1 -0
- package/dist/packages/core/src/model/index.js +5 -0
- package/dist/packages/core/src/model/index.js.map +1 -0
- package/dist/packages/core/src/model/providers/AnthropicProvider.d.ts +25 -0
- package/dist/packages/core/src/model/providers/AnthropicProvider.d.ts.map +1 -0
- package/dist/packages/core/src/model/providers/AnthropicProvider.js +258 -0
- package/dist/packages/core/src/model/providers/AnthropicProvider.js.map +1 -0
- package/dist/packages/core/src/model/providers/CodingPlanProvider.d.ts +66 -0
- package/dist/packages/core/src/model/providers/CodingPlanProvider.d.ts.map +1 -0
- package/dist/packages/core/src/model/providers/CodingPlanProvider.js +161 -0
- package/dist/packages/core/src/model/providers/CodingPlanProvider.js.map +1 -0
- package/dist/packages/core/src/model/providers/OllamaCloudProvider.d.ts +38 -0
- package/dist/packages/core/src/model/providers/OllamaCloudProvider.d.ts.map +1 -0
- package/dist/packages/core/src/model/providers/OllamaCloudProvider.js +365 -0
- package/dist/packages/core/src/model/providers/OllamaCloudProvider.js.map +1 -0
- package/dist/packages/core/src/model/providers/OllamaManager.d.ts +72 -0
- package/dist/packages/core/src/model/providers/OllamaManager.d.ts.map +1 -0
- package/dist/packages/core/src/model/providers/OllamaManager.js +144 -0
- package/dist/packages/core/src/model/providers/OllamaManager.js.map +1 -0
- package/dist/packages/core/src/model/providers/OllamaProvider.d.ts +23 -0
- package/dist/packages/core/src/model/providers/OllamaProvider.d.ts.map +1 -0
- package/dist/packages/core/src/model/providers/OllamaProvider.js +56 -0
- package/dist/packages/core/src/model/providers/OllamaProvider.js.map +1 -0
- package/dist/packages/core/src/model/providers/OpenAICompatibleProvider.d.ts +53 -0
- package/dist/packages/core/src/model/providers/OpenAICompatibleProvider.d.ts.map +1 -0
- package/dist/packages/core/src/model/providers/OpenAICompatibleProvider.js +383 -0
- package/dist/packages/core/src/model/providers/OpenAICompatibleProvider.js.map +1 -0
- package/dist/packages/core/src/model/providers/OpenAIProvider.d.ts +12 -0
- package/dist/packages/core/src/model/providers/OpenAIProvider.d.ts.map +1 -0
- package/dist/packages/core/src/model/providers/OpenAIProvider.js +19 -0
- package/dist/packages/core/src/model/providers/OpenAIProvider.js.map +1 -0
- package/dist/packages/core/src/model/providers/index.d.ts +13 -0
- package/dist/packages/core/src/model/providers/index.d.ts.map +1 -0
- package/dist/packages/core/src/model/providers/index.js +7 -0
- package/dist/packages/core/src/model/providers/index.js.map +1 -0
- package/dist/packages/core/src/model/types.d.ts +81 -0
- package/dist/packages/core/src/model/types.d.ts.map +1 -0
- package/dist/packages/core/src/model/types.js +12 -0
- package/dist/packages/core/src/model/types.js.map +1 -0
- package/dist/packages/core/src/security/ApprovalManager.d.ts +56 -0
- package/dist/packages/core/src/security/ApprovalManager.d.ts.map +1 -0
- package/dist/packages/core/src/security/ApprovalManager.js +122 -0
- package/dist/packages/core/src/security/ApprovalManager.js.map +1 -0
- package/dist/packages/core/src/security/FileFilter.d.ts +47 -0
- package/dist/packages/core/src/security/FileFilter.d.ts.map +1 -0
- package/dist/packages/core/src/security/FileFilter.js +111 -0
- package/dist/packages/core/src/security/FileFilter.js.map +1 -0
- package/dist/packages/core/src/security/HookExecutor.d.ts +37 -0
- package/dist/packages/core/src/security/HookExecutor.d.ts.map +1 -0
- package/dist/packages/core/src/security/HookExecutor.js +142 -0
- package/dist/packages/core/src/security/HookExecutor.js.map +1 -0
- package/dist/packages/core/src/security/SandboxExecutor.d.ts +90 -0
- package/dist/packages/core/src/security/SandboxExecutor.d.ts.map +1 -0
- package/dist/packages/core/src/security/SandboxExecutor.js +345 -0
- package/dist/packages/core/src/security/SandboxExecutor.js.map +1 -0
- package/dist/packages/core/src/security/index.d.ts +8 -0
- package/dist/packages/core/src/security/index.d.ts.map +1 -0
- package/dist/packages/core/src/security/index.js +6 -0
- package/dist/packages/core/src/security/index.js.map +1 -0
- package/dist/packages/core/src/session/AgentLoop.d.ts +75 -0
- package/dist/packages/core/src/session/AgentLoop.d.ts.map +1 -0
- package/dist/packages/core/src/session/AgentLoop.js +381 -0
- package/dist/packages/core/src/session/AgentLoop.js.map +1 -0
- package/dist/packages/core/src/session/SessionManager.d.ts +96 -0
- package/dist/packages/core/src/session/SessionManager.d.ts.map +1 -0
- package/dist/packages/core/src/session/SessionManager.js +390 -0
- package/dist/packages/core/src/session/SessionManager.js.map +1 -0
- package/dist/packages/core/src/session/index.d.ts +4 -0
- package/dist/packages/core/src/session/index.d.ts.map +1 -0
- package/dist/packages/core/src/session/index.js +3 -0
- package/dist/packages/core/src/session/index.js.map +1 -0
- package/dist/packages/core/src/telemetry/Telemetry.d.ts +25 -0
- package/dist/packages/core/src/telemetry/Telemetry.d.ts.map +1 -0
- package/dist/packages/core/src/telemetry/Telemetry.js +73 -0
- package/dist/packages/core/src/telemetry/Telemetry.js.map +1 -0
- package/dist/packages/core/src/telemetry/TelemetryService.d.ts +152 -0
- package/dist/packages/core/src/telemetry/TelemetryService.d.ts.map +1 -0
- package/dist/packages/core/src/telemetry/TelemetryService.js +410 -0
- package/dist/packages/core/src/telemetry/TelemetryService.js.map +1 -0
- package/dist/packages/core/src/telemetry/index.d.ts +5 -0
- package/dist/packages/core/src/telemetry/index.d.ts.map +1 -0
- package/dist/packages/core/src/telemetry/index.js +3 -0
- package/dist/packages/core/src/telemetry/index.js.map +1 -0
- package/dist/packages/core/src/testing/AutoFixer.d.ts +98 -0
- package/dist/packages/core/src/testing/AutoFixer.d.ts.map +1 -0
- package/dist/packages/core/src/testing/AutoFixer.js +262 -0
- package/dist/packages/core/src/testing/AutoFixer.js.map +1 -0
- package/dist/packages/core/src/testing/ErrorAnalyzer.d.ts +74 -0
- package/dist/packages/core/src/testing/ErrorAnalyzer.d.ts.map +1 -0
- package/dist/packages/core/src/testing/ErrorAnalyzer.js +407 -0
- package/dist/packages/core/src/testing/ErrorAnalyzer.js.map +1 -0
- package/dist/packages/core/src/testing/TestRunner.d.ts +57 -0
- package/dist/packages/core/src/testing/TestRunner.d.ts.map +1 -0
- package/dist/packages/core/src/testing/TestRunner.js +205 -0
- package/dist/packages/core/src/testing/TestRunner.js.map +1 -0
- package/dist/packages/core/src/testing/agent-cli-tests.d.ts +2 -0
- package/dist/packages/core/src/testing/agent-cli-tests.d.ts.map +1 -0
- package/dist/packages/core/src/testing/agent-cli-tests.js +493 -0
- package/dist/packages/core/src/testing/agent-cli-tests.js.map +1 -0
- package/dist/packages/core/src/testing/index.d.ts +7 -0
- package/dist/packages/core/src/testing/index.d.ts.map +1 -0
- package/dist/packages/core/src/testing/index.js +8 -0
- package/dist/packages/core/src/testing/index.js.map +1 -0
- package/dist/packages/core/src/tools/ToolRegistry.d.ts +72 -0
- package/dist/packages/core/src/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/packages/core/src/tools/ToolRegistry.js +208 -0
- package/dist/packages/core/src/tools/ToolRegistry.js.map +1 -0
- package/dist/packages/core/src/tools/impl/EditFileTool.d.ts +3 -0
- package/dist/packages/core/src/tools/impl/EditFileTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/EditFileTool.js +76 -0
- package/dist/packages/core/src/tools/impl/EditFileTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/FileProcessor.d.ts +85 -0
- package/dist/packages/core/src/tools/impl/FileProcessor.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/FileProcessor.js +512 -0
- package/dist/packages/core/src/tools/impl/FileProcessor.js.map +1 -0
- package/dist/packages/core/src/tools/impl/FileProcessorTool.d.ts +151 -0
- package/dist/packages/core/src/tools/impl/FileProcessorTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/FileProcessorTool.js +100 -0
- package/dist/packages/core/src/tools/impl/FileProcessorTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/ImageProcessorTool.d.ts +43 -0
- package/dist/packages/core/src/tools/impl/ImageProcessorTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/ImageProcessorTool.js +104 -0
- package/dist/packages/core/src/tools/impl/ImageProcessorTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/ListDirectoryTool.d.ts +3 -0
- package/dist/packages/core/src/tools/impl/ListDirectoryTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/ListDirectoryTool.js +120 -0
- package/dist/packages/core/src/tools/impl/ListDirectoryTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/MemoryTool.d.ts +4 -0
- package/dist/packages/core/src/tools/impl/MemoryTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/MemoryTool.js +80 -0
- package/dist/packages/core/src/tools/impl/MemoryTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/ReadFileTool.d.ts +3 -0
- package/dist/packages/core/src/tools/impl/ReadFileTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/ReadFileTool.js +223 -0
- package/dist/packages/core/src/tools/impl/ReadFileTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/SearchContentTool.d.ts +3 -0
- package/dist/packages/core/src/tools/impl/SearchContentTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/SearchContentTool.js +65 -0
- package/dist/packages/core/src/tools/impl/SearchContentTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/SearchFileTool.d.ts +3 -0
- package/dist/packages/core/src/tools/impl/SearchFileTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/SearchFileTool.js +48 -0
- package/dist/packages/core/src/tools/impl/SearchFileTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/ShellTool.d.ts +3 -0
- package/dist/packages/core/src/tools/impl/ShellTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/ShellTool.js +92 -0
- package/dist/packages/core/src/tools/impl/ShellTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/TaskTool.d.ts +51 -0
- package/dist/packages/core/src/tools/impl/TaskTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/TaskTool.js +172 -0
- package/dist/packages/core/src/tools/impl/TaskTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/TodoTool.d.ts +31 -0
- package/dist/packages/core/src/tools/impl/TodoTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/TodoTool.js +102 -0
- package/dist/packages/core/src/tools/impl/TodoTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/WebFetchTool.d.ts +3 -0
- package/dist/packages/core/src/tools/impl/WebFetchTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/WebFetchTool.js +77 -0
- package/dist/packages/core/src/tools/impl/WebFetchTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/WebSearchTool.d.ts +3 -0
- package/dist/packages/core/src/tools/impl/WebSearchTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/WebSearchTool.js +67 -0
- package/dist/packages/core/src/tools/impl/WebSearchTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/WriteFileTool.d.ts +3 -0
- package/dist/packages/core/src/tools/impl/WriteFileTool.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/WriteFileTool.js +41 -0
- package/dist/packages/core/src/tools/impl/WriteFileTool.js.map +1 -0
- package/dist/packages/core/src/tools/impl/index.d.ts +14 -0
- package/dist/packages/core/src/tools/impl/index.d.ts.map +1 -0
- package/dist/packages/core/src/tools/impl/index.js +21 -0
- package/dist/packages/core/src/tools/impl/index.js.map +1 -0
- package/dist/packages/core/src/tools/index.d.ts +16 -0
- package/dist/packages/core/src/tools/index.d.ts.map +1 -0
- package/dist/packages/core/src/tools/index.js +21 -0
- package/dist/packages/core/src/tools/index.js.map +1 -0
- package/dist/packages/core/src/tools/schemas/execution.d.ts +41 -0
- package/dist/packages/core/src/tools/schemas/execution.d.ts.map +1 -0
- package/dist/packages/core/src/tools/schemas/execution.js +42 -0
- package/dist/packages/core/src/tools/schemas/execution.js.map +1 -0
- package/dist/packages/core/src/tools/schemas/file.d.ts +113 -0
- package/dist/packages/core/src/tools/schemas/file.d.ts.map +1 -0
- package/dist/packages/core/src/tools/schemas/file.js +116 -0
- package/dist/packages/core/src/tools/schemas/file.js.map +1 -0
- package/dist/packages/core/src/tools/schemas/fileProcessorSchema.d.ts +278 -0
- package/dist/packages/core/src/tools/schemas/fileProcessorSchema.d.ts.map +1 -0
- package/dist/packages/core/src/tools/schemas/fileProcessorSchema.js +61 -0
- package/dist/packages/core/src/tools/schemas/fileProcessorSchema.js.map +1 -0
- package/dist/packages/core/src/tools/schemas/index.d.ts +8 -0
- package/dist/packages/core/src/tools/schemas/index.d.ts.map +1 -0
- package/dist/packages/core/src/tools/schemas/index.js +11 -0
- package/dist/packages/core/src/tools/schemas/index.js.map +1 -0
- package/dist/packages/core/src/tools/schemas/memory.d.ts +50 -0
- package/dist/packages/core/src/tools/schemas/memory.d.ts.map +1 -0
- package/dist/packages/core/src/tools/schemas/memory.js +51 -0
- package/dist/packages/core/src/tools/schemas/memory.js.map +1 -0
- package/dist/packages/core/src/tools/schemas/orchestration.d.ts +41 -0
- package/dist/packages/core/src/tools/schemas/orchestration.d.ts.map +1 -0
- package/dist/packages/core/src/tools/schemas/orchestration.js +44 -0
- package/dist/packages/core/src/tools/schemas/orchestration.js.map +1 -0
- package/dist/packages/core/src/tools/schemas/search.d.ts +111 -0
- package/dist/packages/core/src/tools/schemas/search.d.ts.map +1 -0
- package/dist/packages/core/src/tools/schemas/search.js +110 -0
- package/dist/packages/core/src/tools/schemas/search.js.map +1 -0
- package/dist/packages/core/src/tools/schemas/todo.d.ts +29 -0
- package/dist/packages/core/src/tools/schemas/todo.d.ts.map +1 -0
- package/dist/packages/core/src/tools/schemas/todo.js +32 -0
- package/dist/packages/core/src/tools/schemas/todo.js.map +1 -0
- package/dist/packages/core/src/tools/schemas/web.d.ts +84 -0
- package/dist/packages/core/src/tools/schemas/web.d.ts.map +1 -0
- package/dist/packages/core/src/tools/schemas/web.js +85 -0
- package/dist/packages/core/src/tools/schemas/web.js.map +1 -0
- package/dist/packages/core/src/types/config.d.ts +212 -0
- package/dist/packages/core/src/types/config.d.ts.map +1 -0
- package/dist/packages/core/src/types/config.js +5 -0
- package/dist/packages/core/src/types/config.js.map +1 -0
- package/dist/packages/core/src/types/errors.d.ts +92 -0
- package/dist/packages/core/src/types/errors.d.ts.map +1 -0
- package/dist/packages/core/src/types/errors.js +172 -0
- package/dist/packages/core/src/types/errors.js.map +1 -0
- package/dist/packages/core/src/types/index.d.ts +5 -0
- package/dist/packages/core/src/types/index.d.ts.map +1 -0
- package/dist/packages/core/src/types/index.js +8 -0
- package/dist/packages/core/src/types/index.js.map +1 -0
- package/dist/packages/core/src/types/session.d.ts +141 -0
- package/dist/packages/core/src/types/session.d.ts.map +1 -0
- package/dist/packages/core/src/types/session.js +16 -0
- package/dist/packages/core/src/types/session.js.map +1 -0
- package/dist/packages/core/src/types/tools.d.ts +126 -0
- package/dist/packages/core/src/types/tools.d.ts.map +1 -0
- package/dist/packages/core/src/types/tools.js +26 -0
- package/dist/packages/core/src/types/tools.js.map +1 -0
- package/dist/packages/core/src/utils/CheckpointManager.d.ts +100 -0
- package/dist/packages/core/src/utils/CheckpointManager.d.ts.map +1 -0
- package/dist/packages/core/src/utils/CheckpointManager.js +255 -0
- package/dist/packages/core/src/utils/CheckpointManager.js.map +1 -0
- package/dist/packages/core/src/utils/Logger.d.ts +29 -0
- package/dist/packages/core/src/utils/Logger.d.ts.map +1 -0
- package/dist/packages/core/src/utils/Logger.js +77 -0
- package/dist/packages/core/src/utils/Logger.js.map +1 -0
- package/dist/packages/core/src/utils/RetryManager.d.ts +125 -0
- package/dist/packages/core/src/utils/RetryManager.d.ts.map +1 -0
- package/dist/packages/core/src/utils/RetryManager.js +348 -0
- package/dist/packages/core/src/utils/RetryManager.js.map +1 -0
- package/dist/packages/core/src/utils/TokenCounter.d.ts +73 -0
- package/dist/packages/core/src/utils/TokenCounter.d.ts.map +1 -0
- package/dist/packages/core/src/utils/TokenCounter.js +338 -0
- package/dist/packages/core/src/utils/TokenCounter.js.map +1 -0
- package/dist/packages/core/src/utils/VectorMemoryStore.d.ts +110 -0
- package/dist/packages/core/src/utils/VectorMemoryStore.d.ts.map +1 -0
- package/dist/packages/core/src/utils/VectorMemoryStore.js +320 -0
- package/dist/packages/core/src/utils/VectorMemoryStore.js.map +1 -0
- package/dist/packages/core/src/utils/helpers.d.ts +24 -0
- package/dist/packages/core/src/utils/helpers.d.ts.map +1 -0
- package/dist/packages/core/src/utils/helpers.js +77 -0
- package/dist/packages/core/src/utils/helpers.js.map +1 -0
- package/dist/packages/core/src/utils/index.d.ts +11 -0
- package/dist/packages/core/src/utils/index.d.ts.map +1 -0
- package/dist/packages/core/src/utils/index.js +7 -0
- package/dist/packages/core/src/utils/index.js.map +1 -0
- package/dist/startup/IFlowRepl.d.ts +50 -0
- package/dist/startup/IFlowRepl.d.ts.map +1 -0
- package/dist/startup/IFlowRepl.js +178 -0
- package/dist/startup/IFlowRepl.js.map +1 -0
- package/dist/startup/InkBasedRepl.d.ts +151 -0
- package/dist/startup/InkBasedRepl.d.ts.map +1 -0
- package/dist/startup/InkBasedRepl.js +1415 -0
- package/dist/startup/InkBasedRepl.js.map +1 -0
- package/dist/startup/InteractiveRepl.d.ts +141 -0
- package/dist/startup/InteractiveRepl.d.ts.map +1 -0
- package/dist/startup/InteractiveRepl.js +2561 -0
- package/dist/startup/InteractiveRepl.js.map +1 -0
- package/dist/startup/NovaApp.d.ts +57 -0
- package/dist/startup/NovaApp.d.ts.map +1 -0
- package/dist/startup/NovaApp.js +1978 -0
- package/dist/startup/NovaApp.js.map +1 -0
- package/dist/startup/index.d.ts +5 -0
- package/dist/startup/index.d.ts.map +1 -0
- package/dist/startup/index.js +4 -0
- package/dist/startup/index.js.map +1 -0
- package/dist/startup/parseArgs.d.ts +47 -0
- package/dist/startup/parseArgs.d.ts.map +1 -0
- package/dist/startup/parseArgs.js +262 -0
- package/dist/startup/parseArgs.js.map +1 -0
- package/dist/ui/IFlowDropdown.d.ts +63 -0
- package/dist/ui/IFlowDropdown.d.ts.map +1 -0
- package/dist/ui/IFlowDropdown.js +362 -0
- package/dist/ui/IFlowDropdown.js.map +1 -0
- package/dist/ui/ModernReplUI.d.ts +55 -0
- package/dist/ui/ModernReplUI.d.ts.map +1 -0
- package/dist/ui/ModernReplUI.js +207 -0
- package/dist/ui/ModernReplUI.js.map +1 -0
- package/dist/ui/SimpleSelector2.d.ts +28 -0
- package/dist/ui/SimpleSelector2.d.ts.map +1 -0
- package/dist/ui/SimpleSelector2.js +181 -0
- package/dist/ui/SimpleSelector2.js.map +1 -0
- package/dist/ui/components/ActiveCursor.d.ts +128 -0
- package/dist/ui/components/ActiveCursor.d.ts.map +1 -0
- package/dist/ui/components/ActiveCursor.js +273 -0
- package/dist/ui/components/ActiveCursor.js.map +1 -0
- package/dist/ui/components/ConfirmDialog.d.ts +51 -0
- package/dist/ui/components/ConfirmDialog.d.ts.map +1 -0
- package/dist/ui/components/ConfirmDialog.js +147 -0
- package/dist/ui/components/ConfirmDialog.js.map +1 -0
- package/dist/ui/components/ErrorPanel.d.ts +33 -0
- package/dist/ui/components/ErrorPanel.d.ts.map +1 -0
- package/dist/ui/components/ErrorPanel.js +309 -0
- package/dist/ui/components/ErrorPanel.js.map +1 -0
- package/dist/ui/components/InkAppRunner.d.ts +18 -0
- package/dist/ui/components/InkAppRunner.d.ts.map +1 -0
- package/dist/ui/components/InkAppRunner.js +33 -0
- package/dist/ui/components/InkAppRunner.js.map +1 -0
- package/dist/ui/components/InkComponents.d.ts +126 -0
- package/dist/ui/components/InkComponents.d.ts.map +1 -0
- package/dist/ui/components/InkComponents.js +216 -0
- package/dist/ui/components/InkComponents.js.map +1 -0
- package/dist/ui/components/NovaInkApp.d.ts +11 -0
- package/dist/ui/components/NovaInkApp.d.ts.map +1 -0
- package/dist/ui/components/NovaInkApp.js +148 -0
- package/dist/ui/components/NovaInkApp.js.map +1 -0
- package/dist/ui/components/ProgressBar.d.ts +65 -0
- package/dist/ui/components/ProgressBar.d.ts.map +1 -0
- package/dist/ui/components/ProgressBar.js +135 -0
- package/dist/ui/components/ProgressBar.js.map +1 -0
- package/dist/ui/components/ProgressIndicator.d.ts +41 -0
- package/dist/ui/components/ProgressIndicator.d.ts.map +1 -0
- package/dist/ui/components/ProgressIndicator.js +235 -0
- package/dist/ui/components/ProgressIndicator.js.map +1 -0
- package/dist/ui/components/QuickActions.d.ts +36 -0
- package/dist/ui/components/QuickActions.d.ts.map +1 -0
- package/dist/ui/components/QuickActions.js +328 -0
- package/dist/ui/components/QuickActions.js.map +1 -0
- package/dist/ui/components/SimpleErrorPanel.d.ts +16 -0
- package/dist/ui/components/SimpleErrorPanel.d.ts.map +1 -0
- package/dist/ui/components/SimpleErrorPanel.js +193 -0
- package/dist/ui/components/SimpleErrorPanel.js.map +1 -0
- package/dist/ui/components/StatusBar.d.ts +30 -0
- package/dist/ui/components/StatusBar.d.ts.map +1 -0
- package/dist/ui/components/StatusBar.js +154 -0
- package/dist/ui/components/StatusBar.js.map +1 -0
- package/dist/ui/components/ThinkingBlockRenderer.d.ts +109 -0
- package/dist/ui/components/ThinkingBlockRenderer.d.ts.map +1 -0
- package/dist/ui/components/ThinkingBlockRenderer.js +335 -0
- package/dist/ui/components/ThinkingBlockRenderer.js.map +1 -0
- package/dist/ui/components/ThinkingContentDisplay.d.ts +59 -0
- package/dist/ui/components/ThinkingContentDisplay.d.ts.map +1 -0
- package/dist/ui/components/ThinkingContentDisplay.js +172 -0
- package/dist/ui/components/ThinkingContentDisplay.js.map +1 -0
- package/dist/ui/components/TodoProgressPanel.d.ts +91 -0
- package/dist/ui/components/TodoProgressPanel.d.ts.map +1 -0
- package/dist/ui/components/TodoProgressPanel.js +284 -0
- package/dist/ui/components/TodoProgressPanel.js.map +1 -0
- package/dist/ui/components/ToolCallStatusDisplay.d.ts +89 -0
- package/dist/ui/components/ToolCallStatusDisplay.d.ts.map +1 -0
- package/dist/ui/components/ToolCallStatusDisplay.js +246 -0
- package/dist/ui/components/ToolCallStatusDisplay.js.map +1 -0
- package/dist/ui/components/UserMessageHighlight.d.ts +48 -0
- package/dist/ui/components/UserMessageHighlight.d.ts.map +1 -0
- package/dist/ui/components/UserMessageHighlight.js +196 -0
- package/dist/ui/components/UserMessageHighlight.js.map +1 -0
- package/dist/ui/components/index.d.ts +17 -0
- package/dist/ui/components/index.d.ts.map +1 -0
- package/dist/ui/components/index.js +18 -0
- package/dist/ui/components/index.js.map +1 -0
- package/dist/ui/ink-prototype.d.ts +3 -0
- package/dist/ui/ink-prototype.d.ts.map +1 -0
- package/dist/ui/ink-prototype.js +160 -0
- package/dist/ui/ink-prototype.js.map +1 -0
- package/dist/utils/CliUI.d.ts +163 -0
- package/dist/utils/CliUI.d.ts.map +1 -0
- package/dist/utils/CliUI.js +292 -0
- package/dist/utils/CliUI.js.map +1 -0
- package/dist/utils/CompletionHelper.d.ts +112 -0
- package/dist/utils/CompletionHelper.d.ts.map +1 -0
- package/dist/utils/CompletionHelper.js +304 -0
- package/dist/utils/CompletionHelper.js.map +1 -0
- package/dist/utils/EnhancedCompleter.d.ts +107 -0
- package/dist/utils/EnhancedCompleter.d.ts.map +1 -0
- package/dist/utils/EnhancedCompleter.js +428 -0
- package/dist/utils/EnhancedCompleter.js.map +1 -0
- package/dist/utils/ErrorEnhancer.d.ts +103 -0
- package/dist/utils/ErrorEnhancer.d.ts.map +1 -0
- package/dist/utils/ErrorEnhancer.js +350 -0
- package/dist/utils/ErrorEnhancer.js.map +1 -0
- package/dist/utils/OutputFormatter.d.ts +65 -0
- package/dist/utils/OutputFormatter.d.ts.map +1 -0
- package/dist/utils/OutputFormatter.js +145 -0
- package/dist/utils/OutputFormatter.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +99 -0
|
@@ -0,0 +1,1415 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// InkBasedRepl - Interactive REPL using Ink UI framework
|
|
3
|
+
// A modern, component-based terminal UI similar to Claude Code
|
|
4
|
+
// ============================================================================
|
|
5
|
+
import * as fs from 'node:fs';
|
|
6
|
+
import * as path from 'node:path';
|
|
7
|
+
import { spawn } from 'node:child_process';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import { AgentLoop } from '../../../core/src/session/AgentLoop.js';
|
|
10
|
+
import { ModelClient } from '../../../core/src/model/ModelClient.js';
|
|
11
|
+
import { buildSystemPrompt } from '../../../core/src/context/defaultSystemPrompt.js';
|
|
12
|
+
import { ThinkingBlockRenderer } from '../ui/components/ThinkingBlockRenderer.js';
|
|
13
|
+
import { TodoProgressPanel } from '../ui/components/TodoProgressPanel.js';
|
|
14
|
+
import { UserMessageHighlight } from '../ui/components/UserMessageHighlight.js';
|
|
15
|
+
import { ThinkingContentDisplay } from '../ui/components/ThinkingContentDisplay.js';
|
|
16
|
+
import { ToolCallStatusDisplay } from '../ui/components/ToolCallStatusDisplay.js';
|
|
17
|
+
import { selectModelInteractive, selectSkillInteractive } from '../ui/SimpleSelector2.js';
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Box drawing characters
|
|
20
|
+
// ============================================================================
|
|
21
|
+
const BOX = {
|
|
22
|
+
tl: '╭', tr: '╮', bl: '╰', br: '╯',
|
|
23
|
+
h: '─', v: '│', ht: '├', htr: '┤',
|
|
24
|
+
hThick: '━', vThick: '┃',
|
|
25
|
+
arrow: '›', bullet: '•', check: '✓', crossX: '✗', dot: '·',
|
|
26
|
+
diamond: '◆', star: '★',
|
|
27
|
+
spinner: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
|
|
28
|
+
};
|
|
29
|
+
const MODE_LABELS = {
|
|
30
|
+
auto: { label: 'AUTO', color: chalk.green.bold, description: 'Full autonomous' },
|
|
31
|
+
plan: { label: 'PLAN', color: chalk.yellow.bold, description: 'Plan first' },
|
|
32
|
+
ask: { label: 'ASK', color: chalk.cyan.bold, description: 'Answer only' },
|
|
33
|
+
};
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// InkBasedRepl Class
|
|
36
|
+
// ============================================================================
|
|
37
|
+
export class InkBasedRepl {
|
|
38
|
+
modelClient;
|
|
39
|
+
sessionManager;
|
|
40
|
+
toolRegistry;
|
|
41
|
+
approvalManager;
|
|
42
|
+
authManager;
|
|
43
|
+
config;
|
|
44
|
+
configManager;
|
|
45
|
+
cwd;
|
|
46
|
+
contextCompressor;
|
|
47
|
+
mcpManager;
|
|
48
|
+
skillRegistry;
|
|
49
|
+
sessionId = null;
|
|
50
|
+
restoreSessionId;
|
|
51
|
+
currentLoop = null;
|
|
52
|
+
state;
|
|
53
|
+
_pendingSkillInject = null;
|
|
54
|
+
// Thinking renderer for non-Ink fallback
|
|
55
|
+
thinkingRenderer;
|
|
56
|
+
// New UI components
|
|
57
|
+
todoProgressPanel;
|
|
58
|
+
userMessageHighlight;
|
|
59
|
+
thinkingContentDisplay;
|
|
60
|
+
toolCallStatusDisplay;
|
|
61
|
+
activeCursor; // ActiveCursor instance
|
|
62
|
+
// Execution tracking for compact display
|
|
63
|
+
turnCount = 0;
|
|
64
|
+
toolCallCount = 0;
|
|
65
|
+
lastStatusLine = '';
|
|
66
|
+
// UI state
|
|
67
|
+
showHelp = false;
|
|
68
|
+
showModelSelector = false;
|
|
69
|
+
processing = false;
|
|
70
|
+
currentText = '';
|
|
71
|
+
pendingToolCalls = new Map();
|
|
72
|
+
// Store initial config for recreating ModelClient
|
|
73
|
+
initialConfig;
|
|
74
|
+
// Agent-first options
|
|
75
|
+
json;
|
|
76
|
+
noInput;
|
|
77
|
+
limit;
|
|
78
|
+
constructor(options) {
|
|
79
|
+
this.modelClient = options.modelClient;
|
|
80
|
+
this.sessionManager = options.sessionManager;
|
|
81
|
+
this.toolRegistry = options.toolRegistry;
|
|
82
|
+
this.approvalManager = options.approvalManager;
|
|
83
|
+
this.authManager = options.authManager;
|
|
84
|
+
this.config = options.config;
|
|
85
|
+
this.initialConfig = JSON.parse(JSON.stringify(options.config)); // Deep copy
|
|
86
|
+
this.configManager = options.configManager;
|
|
87
|
+
this.cwd = options.cwd;
|
|
88
|
+
this.contextCompressor = options.contextCompressor;
|
|
89
|
+
this.mcpManager = options.mcpManager;
|
|
90
|
+
this.skillRegistry = options.skillRegistry;
|
|
91
|
+
this.restoreSessionId = options.restoreSessionId;
|
|
92
|
+
// Agent-first options
|
|
93
|
+
this.json = options.json ?? false;
|
|
94
|
+
this.noInput = options.noInput ?? false;
|
|
95
|
+
this.limit = options.limit ?? 20; // Default limit for bounded output
|
|
96
|
+
this.thinkingRenderer = new ThinkingBlockRenderer({
|
|
97
|
+
expanded: false,
|
|
98
|
+
maxPreviewLines: 4,
|
|
99
|
+
maxLineLength: 80,
|
|
100
|
+
showStreamingPreview: false,
|
|
101
|
+
});
|
|
102
|
+
// Initialize TODO progress panel for fixed-position task display
|
|
103
|
+
this.todoProgressPanel = new TodoProgressPanel({
|
|
104
|
+
showPriority: true,
|
|
105
|
+
compact: true,
|
|
106
|
+
});
|
|
107
|
+
// Initialize user message highlighter
|
|
108
|
+
this.userMessageHighlight = new UserMessageHighlight({
|
|
109
|
+
highlightColor: 'purple',
|
|
110
|
+
showTimestamp: true,
|
|
111
|
+
});
|
|
112
|
+
// Initialize thinking content display (green dashed box)
|
|
113
|
+
this.thinkingContentDisplay = new ThinkingContentDisplay({
|
|
114
|
+
maxPreviewLines: 6,
|
|
115
|
+
expanded: false,
|
|
116
|
+
});
|
|
117
|
+
// Initialize tool call status display
|
|
118
|
+
this.toolCallStatusDisplay = new ToolCallStatusDisplay({
|
|
119
|
+
showInput: true,
|
|
120
|
+
showResult: false,
|
|
121
|
+
});
|
|
122
|
+
// Initialize active cursor (purple circle animation)
|
|
123
|
+
// Note: ActiveCursor will be initialized when first needed
|
|
124
|
+
this.activeCursor = null;
|
|
125
|
+
// Initialize state
|
|
126
|
+
this.state = {
|
|
127
|
+
model: this.modelClient.getModel(),
|
|
128
|
+
mode: (this.config.core.defaultApprovalMode === 'yolo' ? 'auto' :
|
|
129
|
+
this.config.core.defaultApprovalMode === 'plan' ? 'plan' : 'ask'),
|
|
130
|
+
contextUsage: 0,
|
|
131
|
+
sessionId: 'new',
|
|
132
|
+
messages: [],
|
|
133
|
+
activeTools: [],
|
|
134
|
+
processing: false,
|
|
135
|
+
thinkingContent: '',
|
|
136
|
+
showThinking: true,
|
|
137
|
+
mcpConnected: 0,
|
|
138
|
+
mcpTotal: 0,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// ========================================================================
|
|
142
|
+
// Lifecycle
|
|
143
|
+
// ========================================================================
|
|
144
|
+
async start() {
|
|
145
|
+
// Restore or create session
|
|
146
|
+
if (this.restoreSessionId) {
|
|
147
|
+
const existing = this.sessionManager.get(this.restoreSessionId);
|
|
148
|
+
this.sessionId = existing ? this.restoreSessionId : this.createInitialSession();
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
this.sessionId = this.createInitialSession();
|
|
152
|
+
}
|
|
153
|
+
// Set approval handler
|
|
154
|
+
this.approvalManager.setHandler(this.handleApproval.bind(this));
|
|
155
|
+
// Print initial banner (simplified)
|
|
156
|
+
this.printBanner();
|
|
157
|
+
// Start interactive loop
|
|
158
|
+
await this.runInputLoop();
|
|
159
|
+
}
|
|
160
|
+
createInitialSession() {
|
|
161
|
+
const session = this.sessionManager.create({
|
|
162
|
+
workingDirectory: this.cwd,
|
|
163
|
+
model: this.modelClient.getModel(),
|
|
164
|
+
maxTokens: this.config.core.maxTokens,
|
|
165
|
+
temperature: this.config.core.temperature,
|
|
166
|
+
approvalMode: this.getEffectiveApprovalMode(),
|
|
167
|
+
streaming: true,
|
|
168
|
+
maxTurns: this.config.core.maxTurns,
|
|
169
|
+
});
|
|
170
|
+
return session.id;
|
|
171
|
+
}
|
|
172
|
+
// ========================================================================
|
|
173
|
+
// Agent-First: JSON Output Helpers
|
|
174
|
+
// ========================================================================
|
|
175
|
+
/**
|
|
176
|
+
* Output structured JSON data when --json flag is set
|
|
177
|
+
* This enables machine-parseable output for Agent consumers
|
|
178
|
+
*/
|
|
179
|
+
outputJSON(data) {
|
|
180
|
+
if (this.json) {
|
|
181
|
+
console.log(JSON.stringify(data, null, 2));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Output structured error in JSON format
|
|
186
|
+
*/
|
|
187
|
+
outputErrorJSON(code, message, suggestion, example) {
|
|
188
|
+
if (this.json) {
|
|
189
|
+
console.log(JSON.stringify({
|
|
190
|
+
error: {
|
|
191
|
+
code,
|
|
192
|
+
message,
|
|
193
|
+
suggestion,
|
|
194
|
+
example
|
|
195
|
+
}
|
|
196
|
+
}, null, 2));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Check if we should suppress interactive elements
|
|
201
|
+
*/
|
|
202
|
+
shouldSuppressInteractive() {
|
|
203
|
+
return this.noInput || this.json;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Apply limit to array results for bounded output
|
|
207
|
+
*/
|
|
208
|
+
applyLimit(items) {
|
|
209
|
+
const total = items.length;
|
|
210
|
+
const limited = items.slice(0, this.limit);
|
|
211
|
+
const showing = `Showing ${limited.length} of ${total}`;
|
|
212
|
+
const hint = total > this.limit ? `Use --limit ${total} to see all items` : undefined;
|
|
213
|
+
return { items: limited, total, showing, hint };
|
|
214
|
+
}
|
|
215
|
+
// ========================================================================
|
|
216
|
+
// Banner & UI
|
|
217
|
+
// ========================================================================
|
|
218
|
+
printBanner() {
|
|
219
|
+
const w = 70;
|
|
220
|
+
const hr = chalk.hex('#7C3AED').dim(BOX.h.repeat(w));
|
|
221
|
+
const hrThick = chalk.hex('#7C3AED')(BOX.hThick.repeat(w));
|
|
222
|
+
const vl = chalk.hex('#7C3AED').dim(BOX.v);
|
|
223
|
+
const modelShort = this.modelClient.getModel().split('/').pop() || this.modelClient.getModel();
|
|
224
|
+
const modeInfo = MODE_LABELS[this.state.mode];
|
|
225
|
+
console.log('');
|
|
226
|
+
console.log(chalk.hex('#7C3AED')(BOX.tl) + hrThick + chalk.hex('#7C3AED')(BOX.tr));
|
|
227
|
+
// Logo
|
|
228
|
+
console.log(vl + chalk.hex('#7C3AED').bold(' NOVA ') +
|
|
229
|
+
chalk.hex('#A78BFA')('CLI') +
|
|
230
|
+
chalk.dim(' · AI-powered terminal assistant') + ' '.repeat(24) + vl);
|
|
231
|
+
console.log(chalk.hex('#7C3AED')(BOX.ht) + hr + chalk.hex('#7C3AED')(BOX.htr));
|
|
232
|
+
// Status line
|
|
233
|
+
console.log(vl + ' Model: ' + chalk.white(modelShort) + ' '.repeat(Math.max(0, 52 - modelShort.length)) + vl);
|
|
234
|
+
console.log(vl + ' Mode: ' + modeInfo.color(modeInfo.label) + ' '.repeat(52) + vl);
|
|
235
|
+
console.log(vl + ' Dir: ' + chalk.gray(this.cwd.slice(-50)) + ' '.repeat(Math.max(0, 52 - Math.min(50, this.cwd.length))) + vl);
|
|
236
|
+
console.log(chalk.hex('#7C3AED')(BOX.bl) + hrThick + chalk.hex('#7C3AED')(BOX.br));
|
|
237
|
+
console.log('');
|
|
238
|
+
}
|
|
239
|
+
printPrompt() {
|
|
240
|
+
const modeInfo = MODE_LABELS[this.state.mode];
|
|
241
|
+
const modelShort = this.modelClient.getModel().split('/').pop() || this.modelClient.getModel();
|
|
242
|
+
const modeBadge = modeInfo.color(`[${modeInfo.label}]`);
|
|
243
|
+
const ctxStr = this.state.contextUsage > 0 ?
|
|
244
|
+
chalk.dim(` (${this.state.contextUsage}% ctx)`) : '';
|
|
245
|
+
process.stdout.write(`\n${modeBadge} ${chalk.gray(modelShort)}${ctxStr} ${chalk.hex('#7C3AED')('›')} `);
|
|
246
|
+
}
|
|
247
|
+
// ========================================================================
|
|
248
|
+
// Input Loop
|
|
249
|
+
// ========================================================================
|
|
250
|
+
async runInputLoop() {
|
|
251
|
+
const readline = await import('node:readline');
|
|
252
|
+
const rl = readline.createInterface({
|
|
253
|
+
input: process.stdin,
|
|
254
|
+
output: process.stdout,
|
|
255
|
+
historySize: 200,
|
|
256
|
+
removeHistoryDuplicates: true,
|
|
257
|
+
});
|
|
258
|
+
// Guard flag: when true, rl 'close' is a false alarm from raw-mode pause/resume
|
|
259
|
+
let closeGuard = false;
|
|
260
|
+
// Handle Ctrl+C
|
|
261
|
+
process.on('SIGINT', () => {
|
|
262
|
+
if (this.currentLoop?.isActive()) {
|
|
263
|
+
this.currentLoop.cancel();
|
|
264
|
+
this.processing = false;
|
|
265
|
+
process.stdout.write('\n');
|
|
266
|
+
this.printPrompt();
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
console.log(chalk.dim('\n Use /quit or Ctrl+D to exit'));
|
|
270
|
+
this.printPrompt();
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
rl.on('close', () => {
|
|
274
|
+
// Ignore close events triggered by raw-mode pause/resume during
|
|
275
|
+
// interactive selectors (SimpleSelector2, etc.)
|
|
276
|
+
if (closeGuard) {
|
|
277
|
+
closeGuard = false;
|
|
278
|
+
process.stdin.resume();
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (this.sessionId)
|
|
282
|
+
this.sessionManager.persist(this.sessionId);
|
|
283
|
+
console.log(chalk.dim('\nGoodbye!'));
|
|
284
|
+
process.exit(0);
|
|
285
|
+
});
|
|
286
|
+
// Main loop
|
|
287
|
+
while (true) {
|
|
288
|
+
this.printPrompt();
|
|
289
|
+
const input = await new Promise((resolve) => {
|
|
290
|
+
rl.question('', resolve);
|
|
291
|
+
});
|
|
292
|
+
if (!input.trim())
|
|
293
|
+
continue;
|
|
294
|
+
// Set guard before dispatching — commands may enter/leave raw mode
|
|
295
|
+
closeGuard = true;
|
|
296
|
+
this.processing = true;
|
|
297
|
+
await this.dispatchInput(input.trim());
|
|
298
|
+
this.processing = false;
|
|
299
|
+
closeGuard = false;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
async dispatchInput(input) {
|
|
303
|
+
// Handle commands
|
|
304
|
+
if (input.startsWith('/')) {
|
|
305
|
+
await this.handleCommand(input);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
// Handle shell commands
|
|
309
|
+
if (input.startsWith('!')) {
|
|
310
|
+
await this.handleShellCommand(input.slice(1).trim());
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
// Process normal input
|
|
314
|
+
await this.processInput(input);
|
|
315
|
+
}
|
|
316
|
+
// ========================================================================
|
|
317
|
+
// Command Handlers
|
|
318
|
+
// ========================================================================
|
|
319
|
+
async handleCommand(cmd) {
|
|
320
|
+
const parts = cmd.slice(1).split(/\s+/);
|
|
321
|
+
const command = (parts[0] || '').toLowerCase();
|
|
322
|
+
const arg = parts.slice(1).join(' ');
|
|
323
|
+
switch (command) {
|
|
324
|
+
case 'init':
|
|
325
|
+
await this.handleProjectAnalyze();
|
|
326
|
+
break;
|
|
327
|
+
case 'quit':
|
|
328
|
+
case 'exit':
|
|
329
|
+
case 'q':
|
|
330
|
+
if (this.sessionId)
|
|
331
|
+
this.sessionManager.persist(this.sessionId);
|
|
332
|
+
if (this.activeCursor)
|
|
333
|
+
this.activeCursor.stop();
|
|
334
|
+
console.log(chalk.dim('Goodbye!'));
|
|
335
|
+
process.exit(0);
|
|
336
|
+
case 'help':
|
|
337
|
+
case 'h':
|
|
338
|
+
case '?':
|
|
339
|
+
this.printHelp();
|
|
340
|
+
break;
|
|
341
|
+
case 'clear':
|
|
342
|
+
if (this.sessionId)
|
|
343
|
+
this.sessionManager.persist(this.sessionId);
|
|
344
|
+
this.sessionId = this.createInitialSession();
|
|
345
|
+
this.state.messages = [];
|
|
346
|
+
this.state.contextUsage = 0;
|
|
347
|
+
console.log(chalk.dim(' Conversation cleared.'));
|
|
348
|
+
break;
|
|
349
|
+
case 'mode':
|
|
350
|
+
if (arg && ['auto', 'plan', 'ask'].includes(arg)) {
|
|
351
|
+
this.state.mode = arg;
|
|
352
|
+
console.log(chalk.dim(` Mode: ${arg}`));
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
// Cycle mode
|
|
356
|
+
const modes = ['auto', 'plan', 'ask'];
|
|
357
|
+
const idx = modes.indexOf(this.state.mode);
|
|
358
|
+
this.state.mode = modes[(idx + 1) % 3];
|
|
359
|
+
console.log(chalk.dim(` Mode: ${this.state.mode}`));
|
|
360
|
+
}
|
|
361
|
+
break;
|
|
362
|
+
case 'model':
|
|
363
|
+
await this.handleModelCommand(arg);
|
|
364
|
+
break;
|
|
365
|
+
case 'ollama':
|
|
366
|
+
await this.handleOllamaCommand(arg);
|
|
367
|
+
break;
|
|
368
|
+
case 'status':
|
|
369
|
+
this.printStatus();
|
|
370
|
+
break;
|
|
371
|
+
case 'mcp':
|
|
372
|
+
await this.handleMcpCommand(arg);
|
|
373
|
+
break;
|
|
374
|
+
case 'skills':
|
|
375
|
+
await this.handleSkillsCommand(arg);
|
|
376
|
+
break;
|
|
377
|
+
case 'thinking':
|
|
378
|
+
this.state.showThinking = !this.state.showThinking;
|
|
379
|
+
console.log(chalk.dim(` Thinking: ${this.state.showThinking ? 'ON' : 'OFF'}`));
|
|
380
|
+
break;
|
|
381
|
+
case 'project':
|
|
382
|
+
await this.handleProjectCommand(arg);
|
|
383
|
+
break;
|
|
384
|
+
default:
|
|
385
|
+
console.log(chalk.yellow(` Unknown command: /${command}`));
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
printHelp() {
|
|
389
|
+
console.log('');
|
|
390
|
+
console.log(chalk.hex('#7C3AED').bold(' Commands:'));
|
|
391
|
+
console.log(chalk.gray(' /help, /h Show this help'));
|
|
392
|
+
console.log(chalk.gray(' /init Analyze project and initialize context'));
|
|
393
|
+
console.log(chalk.gray(' /quit, /q Exit Nova CLI'));
|
|
394
|
+
console.log(chalk.gray(' /clear Clear conversation'));
|
|
395
|
+
console.log(chalk.gray(' /mode Cycle mode (AUTO → PLAN → ASK)'));
|
|
396
|
+
console.log(chalk.gray(' /model Switch model'));
|
|
397
|
+
console.log(chalk.gray(' /ollama Ollama status'));
|
|
398
|
+
console.log(chalk.gray(' /status Session status'));
|
|
399
|
+
console.log(chalk.gray(' /mcp MCP servers'));
|
|
400
|
+
console.log(chalk.gray(' /skills Available skills'));
|
|
401
|
+
console.log(chalk.gray(' /thinking Toggle thinking display'));
|
|
402
|
+
console.log('');
|
|
403
|
+
console.log(chalk.gray(' @file Inject file content'));
|
|
404
|
+
console.log(chalk.gray(' !command Run shell command'));
|
|
405
|
+
console.log('');
|
|
406
|
+
}
|
|
407
|
+
async handleModelCommand(arg) {
|
|
408
|
+
if (!arg) {
|
|
409
|
+
// Interactive model selection — only show configured providers
|
|
410
|
+
const config = this.configManager.getConfig();
|
|
411
|
+
const models = [];
|
|
412
|
+
// Collect models only from configured/available providers
|
|
413
|
+
for (const [provider, providerConfig] of Object.entries(config.models.providers)) {
|
|
414
|
+
const hasCreds = this.authManager.hasCredentials(provider);
|
|
415
|
+
const isOllama = providerConfig.type === 'ollama';
|
|
416
|
+
const isOllamaCloud = providerConfig.type === 'ollama-cloud';
|
|
417
|
+
// Skip providers that are not configured
|
|
418
|
+
if (!hasCreds && !isOllama && !isOllamaCloud)
|
|
419
|
+
continue;
|
|
420
|
+
// For Ollama, verify it's actually running
|
|
421
|
+
if (isOllama && !hasCreds) {
|
|
422
|
+
try {
|
|
423
|
+
const baseUrl = process.env.OLLAMA_HOST || 'http://localhost:11434';
|
|
424
|
+
const resp = await fetch(`${baseUrl}/api/tags`, { signal: AbortSignal.timeout(2000) });
|
|
425
|
+
if (!resp.ok)
|
|
426
|
+
continue; // Ollama not running
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
continue; // Ollama not running
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
for (const [modelId, modelConfig] of Object.entries(providerConfig.models)) {
|
|
433
|
+
const features = [];
|
|
434
|
+
if (modelConfig.supportsVision)
|
|
435
|
+
features.push('vision');
|
|
436
|
+
if (modelConfig.supportsTools)
|
|
437
|
+
features.push('tools');
|
|
438
|
+
if (modelConfig.supportsThinking)
|
|
439
|
+
features.push('thinking');
|
|
440
|
+
const description = features.length > 0 ? `[${features.join(', ')}]` : '';
|
|
441
|
+
models.push({
|
|
442
|
+
provider,
|
|
443
|
+
model: modelId,
|
|
444
|
+
description,
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (models.length === 0) {
|
|
449
|
+
console.log(chalk.yellow(' No models available. Configure a provider first.'));
|
|
450
|
+
console.log(chalk.gray(' Use: nova auth set <provider>'));
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
// Show interactive selector (returns "provider/model" format)
|
|
454
|
+
const selectedModel = await selectModelInteractive(models);
|
|
455
|
+
if (selectedModel && selectedModel !== 'separator' && !selectedModel.startsWith('provider:')) {
|
|
456
|
+
const success = await this.switchModel(selectedModel);
|
|
457
|
+
if (success) {
|
|
458
|
+
console.log(chalk.green(` ✓ Switched to: ${selectedModel}`));
|
|
459
|
+
}
|
|
460
|
+
// If failed, switchModel already printed an error message
|
|
461
|
+
}
|
|
462
|
+
else if (selectedModel && selectedModel.startsWith('provider:')) {
|
|
463
|
+
console.log(chalk.dim(' Please select a specific model, not a provider header'));
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
console.log(chalk.dim(' Model selection cancelled'));
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
// Direct model switch
|
|
471
|
+
const success = await this.switchModel(arg);
|
|
472
|
+
if (success) {
|
|
473
|
+
console.log(chalk.green(` ✓ Switched to: ${arg}`));
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
async handleOllamaCommand(arg) {
|
|
478
|
+
const creds = this.authManager.getCredentials('ollama');
|
|
479
|
+
const baseUrl = creds?.baseUrl || process.env.OLLAMA_HOST || 'http://localhost:11434';
|
|
480
|
+
console.log(chalk.hex('#7C3AED')('\n Ollama Status:'));
|
|
481
|
+
console.log(chalk.gray(` Host: ${baseUrl}`));
|
|
482
|
+
try {
|
|
483
|
+
const response = await fetch(`${baseUrl}/api/tags`);
|
|
484
|
+
if (response.ok) {
|
|
485
|
+
const data = await response.json();
|
|
486
|
+
console.log(chalk.green(' Status: Running'));
|
|
487
|
+
console.log(chalk.gray(` Models: ${data.models?.length || 0} installed`));
|
|
488
|
+
if (data.models?.length > 0) {
|
|
489
|
+
data.models.slice(0, 5).forEach((m) => {
|
|
490
|
+
console.log(chalk.gray(` - ${m.name}`));
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
console.log(chalk.yellow(' Status: Not responding'));
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
catch {
|
|
499
|
+
console.log(chalk.red(' Status: Not running'));
|
|
500
|
+
console.log(chalk.gray(' Start with: ollama serve'));
|
|
501
|
+
}
|
|
502
|
+
console.log('');
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Switch to a different model, potentially across providers.
|
|
506
|
+
* Accepts "provider/model" or bare "model" format.
|
|
507
|
+
* Persists selection to global config.
|
|
508
|
+
*/
|
|
509
|
+
async switchModel(modelId) {
|
|
510
|
+
try {
|
|
511
|
+
// Parse provider/model format (e.g., "ollama/gemma3:4b")
|
|
512
|
+
let providerName;
|
|
513
|
+
let actualModelId;
|
|
514
|
+
if (modelId.includes('/')) {
|
|
515
|
+
const idx = modelId.indexOf('/');
|
|
516
|
+
providerName = modelId.substring(0, idx);
|
|
517
|
+
actualModelId = modelId.substring(idx + 1);
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
// Bare model name — look up in config to find provider
|
|
521
|
+
const modelConfig = this.configManager.getModelConfig(modelId);
|
|
522
|
+
if (!modelConfig) {
|
|
523
|
+
// Might be an Ollama model
|
|
524
|
+
if (this.authManager.hasCredentials('ollama') || process.env.OLLAMA_HOST) {
|
|
525
|
+
providerName = 'ollama';
|
|
526
|
+
actualModelId = modelId;
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
console.log(chalk.red(` ✗ Model "${modelId}" not found in config`));
|
|
530
|
+
return false;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
const config = this.configManager.getConfig();
|
|
535
|
+
for (const [name, p] of Object.entries(config.models.providers)) {
|
|
536
|
+
if (p === modelConfig.provider || p.models === modelConfig.provider.models) {
|
|
537
|
+
providerName = name;
|
|
538
|
+
break;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
actualModelId = modelId;
|
|
542
|
+
if (!providerName) {
|
|
543
|
+
console.log(chalk.red(` ✗ Cannot determine provider for "${modelId}"`));
|
|
544
|
+
return false;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
// Get provider config
|
|
549
|
+
const config = this.configManager.getConfig();
|
|
550
|
+
const providerConfig = config.models.providers[providerName];
|
|
551
|
+
if (!providerConfig) {
|
|
552
|
+
console.log(chalk.red(` ✗ Unknown provider: "${providerName}"`));
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
const providerType = providerConfig.type;
|
|
556
|
+
const creds = this.authManager.getCredentials(providerName);
|
|
557
|
+
// For non-Ollama providers, require API key
|
|
558
|
+
const isOllamaType = providerType === 'ollama' || providerName === 'ollama' || providerName === 'ollama-cloud';
|
|
559
|
+
if (!isOllamaType && !creds?.apiKey) {
|
|
560
|
+
console.log(chalk.yellow(` ⚠ No API key found for "${providerName}"`));
|
|
561
|
+
console.log(chalk.gray(` Set it with: nova auth set ${providerName}`));
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
// Create new ModelClient with correct provider
|
|
565
|
+
this.modelClient = new ModelClient({
|
|
566
|
+
provider: providerType,
|
|
567
|
+
apiKey: creds?.apiKey,
|
|
568
|
+
baseUrl: creds?.baseUrl || providerConfig.baseUrl,
|
|
569
|
+
model: actualModelId,
|
|
570
|
+
maxTokens: this.config.core.maxTokens,
|
|
571
|
+
temperature: this.config.core.temperature,
|
|
572
|
+
organizationId: creds?.organizationId,
|
|
573
|
+
codingPlanPlatform: providerConfig.codingPlanPlatform,
|
|
574
|
+
});
|
|
575
|
+
// Update state
|
|
576
|
+
this.state.model = `${providerName}/${actualModelId}`;
|
|
577
|
+
// Persist to global config
|
|
578
|
+
config.core.defaultModel = `${providerName}/${actualModelId}`;
|
|
579
|
+
await this.configManager.save(config);
|
|
580
|
+
return true;
|
|
581
|
+
}
|
|
582
|
+
catch (err) {
|
|
583
|
+
console.log(chalk.red(` ✗ Error switching model: ${err.message}`));
|
|
584
|
+
return false;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
printStatus() {
|
|
588
|
+
console.log(chalk.hex('#7C3AED')('\n Session Status:'));
|
|
589
|
+
console.log(chalk.gray(` Session: ${this.sessionId?.slice(0, 8) || 'none'}`));
|
|
590
|
+
console.log(chalk.gray(` Model: ${this.state.model}`));
|
|
591
|
+
console.log(chalk.gray(` Mode: ${this.state.mode}`));
|
|
592
|
+
console.log(chalk.gray(` Context: ${this.state.contextUsage}%`));
|
|
593
|
+
console.log(chalk.gray(` Messages: ${this.state.messages.length}`));
|
|
594
|
+
console.log('');
|
|
595
|
+
}
|
|
596
|
+
printMcpStatus() {
|
|
597
|
+
if (!this.mcpManager) {
|
|
598
|
+
console.log(chalk.gray(' MCP not initialized'));
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
const statuses = this.mcpManager.listServers();
|
|
602
|
+
if (statuses.length === 0) {
|
|
603
|
+
console.log(chalk.gray(' No MCP servers configured'));
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
console.log(chalk.hex('#7C3AED')('\n MCP Servers:'));
|
|
607
|
+
for (const s of statuses) {
|
|
608
|
+
const icon = s.connected ? chalk.green('✓') : chalk.red('✗');
|
|
609
|
+
console.log(chalk.gray(` ${icon} ${s.name}: ${s.connected ? 'connected' : 'disconnected'}`));
|
|
610
|
+
}
|
|
611
|
+
console.log('');
|
|
612
|
+
}
|
|
613
|
+
async handleMcpCommand(arg) {
|
|
614
|
+
if (!this.mcpManager) {
|
|
615
|
+
console.log(chalk.gray(' MCP not initialized'));
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
const statuses = this.mcpManager.listServers();
|
|
619
|
+
if (statuses.length === 0) {
|
|
620
|
+
console.log(chalk.gray(' No MCP servers configured'));
|
|
621
|
+
console.log(chalk.dim(' Add servers to ~/.nova/config.yaml under "mcp:"'));
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
if (!arg) {
|
|
625
|
+
// Show status (non-interactive for now)
|
|
626
|
+
this.printMcpStatus();
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
629
|
+
// Specific server action requested
|
|
630
|
+
console.log(chalk.green(` MCP server: ${arg}`));
|
|
631
|
+
console.log(chalk.dim(' Note: MCP server management not yet implemented in interactive mode'));
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
printSkillsStatus() {
|
|
635
|
+
if (!this.skillRegistry) {
|
|
636
|
+
console.log(chalk.gray(' Skills not initialized'));
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
// We'd need async for this, but for now just show a message
|
|
640
|
+
console.log(chalk.hex('#7C3AED')('\n Skills:'));
|
|
641
|
+
console.log(chalk.gray(' Use /skills <name> to inject a skill'));
|
|
642
|
+
console.log('');
|
|
643
|
+
}
|
|
644
|
+
async handleSkillsCommand(arg) {
|
|
645
|
+
if (!this.skillRegistry) {
|
|
646
|
+
console.log(chalk.gray(' Skills not initialized'));
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
// Parse command arguments
|
|
650
|
+
const args = arg.trim().split(/\s+/);
|
|
651
|
+
const subcommand = args[0]?.toLowerCase();
|
|
652
|
+
if (subcommand === 'add') {
|
|
653
|
+
// Handle /skills add <global|local> [file-path]
|
|
654
|
+
const scope = args[1]?.toLowerCase();
|
|
655
|
+
const filePath = args.slice(2).join(' ').trim();
|
|
656
|
+
if (!scope || (scope !== 'global' && scope !== 'local')) {
|
|
657
|
+
await this.handleAddSkillCommand('local');
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
if (!filePath) {
|
|
661
|
+
await this.handleAddSkillCommand(scope);
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
await this.handleAddSkillFromFile(scope, filePath);
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
if (subcommand === 'list') {
|
|
668
|
+
// Handle /skills list
|
|
669
|
+
try {
|
|
670
|
+
const skills = await this.skillRegistry.list();
|
|
671
|
+
const localSkills = this.state.activeSkills || [];
|
|
672
|
+
if (skills.length === 0 && localSkills.length === 0) {
|
|
673
|
+
console.log(chalk.dim(' No skills installed. Use "/skills add" to add skills from local files.'));
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
console.log('');
|
|
677
|
+
console.log(chalk.hex('#7C3AED').bold(' Available Skills:'));
|
|
678
|
+
console.log('');
|
|
679
|
+
// Show global skills
|
|
680
|
+
if (skills.length > 0) {
|
|
681
|
+
console.log(chalk.hex('#7C3AED').bold(' Global Skills:'));
|
|
682
|
+
console.log('');
|
|
683
|
+
skills.forEach(skill => {
|
|
684
|
+
console.log(chalk.white(` • ${skill.metadata.name}`));
|
|
685
|
+
console.log(chalk.dim(` ${skill.metadata.description}`));
|
|
686
|
+
console.log('');
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
// Show local skills (current session)
|
|
690
|
+
if (localSkills.length > 0) {
|
|
691
|
+
console.log(chalk.hex('#7C3AED').bold(' Local Skills (Current Session):'));
|
|
692
|
+
console.log('');
|
|
693
|
+
localSkills.forEach(skill => {
|
|
694
|
+
console.log(chalk.white(` • ${skill.name}`));
|
|
695
|
+
console.log(chalk.dim(` ${skill.description}`));
|
|
696
|
+
console.log('');
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
catch (error) {
|
|
701
|
+
console.log(chalk.red(` Error loading skills: ${error.message}`));
|
|
702
|
+
}
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
if (subcommand === 'rm') {
|
|
706
|
+
// Handle /skills rm <skill-name>
|
|
707
|
+
const skillName = args[1]?.toLowerCase();
|
|
708
|
+
if (!skillName) {
|
|
709
|
+
console.log(chalk.yellow(' Usage: /skills rm <skill-name>'));
|
|
710
|
+
console.log(chalk.dim(' Example: /skills rm code-simplifier'));
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
await this.handleRemoveSkillCommand(skillName);
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
// Default behavior: interactive skill selection or specific skill
|
|
717
|
+
if (!arg) {
|
|
718
|
+
// Interactive skill selection
|
|
719
|
+
try {
|
|
720
|
+
const skills = await this.skillRegistry.list();
|
|
721
|
+
if (skills.length === 0) {
|
|
722
|
+
console.log(chalk.dim(' No skills installed. Use "/skills add" to add skills from local files.'));
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
const skillItems = skills.map(skill => ({
|
|
726
|
+
name: skill.metadata.name,
|
|
727
|
+
description: skill.metadata.description,
|
|
728
|
+
}));
|
|
729
|
+
const selectedSkill = await selectSkillInteractive(skillItems);
|
|
730
|
+
if (selectedSkill) {
|
|
731
|
+
console.log(chalk.green(` ✓ Selected skill: ${selectedSkill}`));
|
|
732
|
+
console.log(chalk.dim(' Note: Skill injection not yet implemented in interactive mode'));
|
|
733
|
+
}
|
|
734
|
+
else {
|
|
735
|
+
console.log(chalk.dim(' Skill selection cancelled'));
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
catch (error) {
|
|
739
|
+
console.log(chalk.red(` Error loading skills: ${error.message}`));
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
else {
|
|
743
|
+
// Specific skill requested
|
|
744
|
+
console.log(chalk.green(` ✓ Selected skill: ${arg}`));
|
|
745
|
+
console.log(chalk.dim(' Note: Skill injection not yet implemented in interactive mode'));
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
// ========================================================================
|
|
749
|
+
// Add Skill Handler
|
|
750
|
+
// ========================================================================
|
|
751
|
+
async handleAddSkillCommand(scope) {
|
|
752
|
+
const { resolve } = await import('path');
|
|
753
|
+
const { readFile } = await import('fs/promises');
|
|
754
|
+
console.log('');
|
|
755
|
+
console.log(chalk.hex('#7C3AED').bold(` ${scope === 'global' ? 'Add Skill (Global)' : 'Add Skill (Local)'}`));
|
|
756
|
+
console.log(chalk.dim(` Scope: ${scope === 'global' ? 'All sessions' : 'Current session only'}`));
|
|
757
|
+
console.log('');
|
|
758
|
+
console.log(chalk.yellow(' Usage: /skills add <global|local> <file-path>'));
|
|
759
|
+
console.log(chalk.dim(' Example: /skills add local code-simplifier.md'));
|
|
760
|
+
console.log('');
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Add skill from file path (called with file path argument)
|
|
764
|
+
*/
|
|
765
|
+
async handleAddSkillFromFile(scope, filePath) {
|
|
766
|
+
const { resolve } = await import('path');
|
|
767
|
+
const { readFile } = await import('fs/promises');
|
|
768
|
+
console.log('');
|
|
769
|
+
console.log(chalk.hex('#7C3AED').bold(` ${scope === 'global' ? 'Add Skill (Global)' : 'Add Skill (Local)'}`));
|
|
770
|
+
console.log(chalk.dim(` Scope: ${scope === 'global' ? 'All sessions' : 'Current session only'}`));
|
|
771
|
+
console.log('');
|
|
772
|
+
if (!filePath) {
|
|
773
|
+
console.log(chalk.yellow(' No file path provided.'));
|
|
774
|
+
console.log(chalk.dim(' Usage: /skills add <global|local> <file-path>'));
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
// Resolve absolute path
|
|
778
|
+
const absolutePath = resolve(filePath);
|
|
779
|
+
// Read file
|
|
780
|
+
let fileContent;
|
|
781
|
+
try {
|
|
782
|
+
fileContent = await readFile(absolutePath, 'utf-8');
|
|
783
|
+
}
|
|
784
|
+
catch (error) {
|
|
785
|
+
console.log(chalk.red(` Error reading file: ${error.message}`));
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
// Parse skill file
|
|
789
|
+
const skill = this.parseSkillFile(absolutePath, fileContent);
|
|
790
|
+
if (!skill) {
|
|
791
|
+
console.log(chalk.red(' Invalid skill file format.'));
|
|
792
|
+
console.log(chalk.dim(' Expected format: YAML frontmatter with name, description, and content'));
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
console.log('');
|
|
796
|
+
console.log(chalk.hex('#7C3AED').bold(' Skill Information:'));
|
|
797
|
+
console.log(chalk.white(` Name: ${skill.name}`));
|
|
798
|
+
console.log(chalk.white(` Description: ${skill.description}`));
|
|
799
|
+
console.log(chalk.dim(` Model: ${skill.model || 'default'}`));
|
|
800
|
+
console.log('');
|
|
801
|
+
// Store skill based on scope
|
|
802
|
+
if (scope === 'global') {
|
|
803
|
+
// Register to SkillRegistry
|
|
804
|
+
try {
|
|
805
|
+
await this.skillRegistry.register({
|
|
806
|
+
metadata: {
|
|
807
|
+
name: skill.name,
|
|
808
|
+
description: skill.description,
|
|
809
|
+
version: '1.0.0',
|
|
810
|
+
tags: ['user-added'],
|
|
811
|
+
createdAt: new Date().toISOString(),
|
|
812
|
+
updatedAt: new Date().toISOString(),
|
|
813
|
+
},
|
|
814
|
+
content: skill.content,
|
|
815
|
+
});
|
|
816
|
+
console.log(chalk.green(` ✓ Skill "${skill.name}" added to global configuration`));
|
|
817
|
+
}
|
|
818
|
+
catch (error) {
|
|
819
|
+
console.log(chalk.red(` Error registering skill: ${error.message}`));
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
else {
|
|
824
|
+
// Add to current session
|
|
825
|
+
if (!this.state.activeSkills) {
|
|
826
|
+
this.state.activeSkills = [];
|
|
827
|
+
}
|
|
828
|
+
this.state.activeSkills.push(skill);
|
|
829
|
+
console.log(chalk.green(` ✓ Skill "${skill.name}" added to current session`));
|
|
830
|
+
}
|
|
831
|
+
console.log('');
|
|
832
|
+
console.log(chalk.dim(' The skill will be applied to all subsequent conversations.'));
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* Remove skill from current session or global configuration
|
|
836
|
+
*/
|
|
837
|
+
async handleRemoveSkillCommand(skillName) {
|
|
838
|
+
console.log('');
|
|
839
|
+
// First, try to remove from current session (local skills)
|
|
840
|
+
if (this.state.activeSkills) {
|
|
841
|
+
const localIndex = this.state.activeSkills.findIndex(s => s.name.toLowerCase() === skillName);
|
|
842
|
+
if (localIndex !== -1) {
|
|
843
|
+
const removed = this.state.activeSkills.splice(localIndex, 1)[0];
|
|
844
|
+
console.log(chalk.hex('#7C3AED').bold(' Remove Skill (Local)'));
|
|
845
|
+
console.log('');
|
|
846
|
+
console.log(chalk.white(` Name: ${removed.name}`));
|
|
847
|
+
console.log(chalk.white(` Description: ${removed.description}`));
|
|
848
|
+
console.log('');
|
|
849
|
+
console.log(chalk.green(` ✓ Skill "${removed.name}" removed from current session`));
|
|
850
|
+
console.log('');
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
// If not found in local skills, try global skills
|
|
855
|
+
try {
|
|
856
|
+
const globalSkills = await this.skillRegistry.list();
|
|
857
|
+
const globalSkill = globalSkills.find(s => s.metadata.name.toLowerCase() === skillName);
|
|
858
|
+
if (globalSkill) {
|
|
859
|
+
console.log(chalk.hex('#7C3AED').bold(' Remove Skill (Global)'));
|
|
860
|
+
console.log('');
|
|
861
|
+
console.log(chalk.white(` Name: ${globalSkill.metadata.name}`));
|
|
862
|
+
console.log(chalk.white(` Description: ${globalSkill.metadata.description}`));
|
|
863
|
+
console.log('');
|
|
864
|
+
const success = await this.skillRegistry.remove(globalSkill.metadata.name);
|
|
865
|
+
if (success) {
|
|
866
|
+
console.log(chalk.green(` ✓ Skill "${globalSkill.metadata.name}" removed from global configuration`));
|
|
867
|
+
}
|
|
868
|
+
else {
|
|
869
|
+
console.log(chalk.red(` ✗ Failed to remove skill "${globalSkill.metadata.name}"`));
|
|
870
|
+
}
|
|
871
|
+
console.log('');
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
catch (error) {
|
|
876
|
+
console.log(chalk.red(` Error removing skill: ${error.message}`));
|
|
877
|
+
console.log('');
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
// Skill not found
|
|
881
|
+
console.log(chalk.yellow(` Skill "${skillName}" not found`));
|
|
882
|
+
console.log(chalk.dim(' Use "/skills list" to see available skills'));
|
|
883
|
+
console.log('');
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Parse skill file with YAML frontmatter
|
|
887
|
+
*/
|
|
888
|
+
parseSkillFile(filePath, content) {
|
|
889
|
+
// Match YAML frontmatter
|
|
890
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
891
|
+
if (!frontmatterMatch) {
|
|
892
|
+
return null;
|
|
893
|
+
}
|
|
894
|
+
const frontmatter = frontmatterMatch[1];
|
|
895
|
+
const body = frontmatterMatch[2];
|
|
896
|
+
// Parse fields
|
|
897
|
+
const parseField = (field) => {
|
|
898
|
+
const match = frontmatter.match(new RegExp(`^${field}:\\s*(.+)$`, 'm'));
|
|
899
|
+
return match ? match[1].trim() : '';
|
|
900
|
+
};
|
|
901
|
+
const name = parseField('name');
|
|
902
|
+
const description = parseField('description');
|
|
903
|
+
const model = parseField('model') || undefined;
|
|
904
|
+
if (!name || !description) {
|
|
905
|
+
return null;
|
|
906
|
+
}
|
|
907
|
+
return {
|
|
908
|
+
name,
|
|
909
|
+
description,
|
|
910
|
+
model,
|
|
911
|
+
content: body,
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
// ========================================================================
|
|
915
|
+
// Project Analysis Handler
|
|
916
|
+
// ========================================================================
|
|
917
|
+
async handleProjectCommand(arg) {
|
|
918
|
+
const { ProjectAnalyzer } = await import('../../../core/src/analysis/ProjectAnalyzer.js');
|
|
919
|
+
// Parse command arguments
|
|
920
|
+
const args = arg.trim().split(/\s+/);
|
|
921
|
+
const subcommand = args[0]?.toLowerCase();
|
|
922
|
+
if (subcommand === 'analyze') {
|
|
923
|
+
await this.handleProjectAnalyze();
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
// Default: show usage
|
|
927
|
+
console.log('');
|
|
928
|
+
console.log(chalk.hex('#7C3AED').bold(' Project Analysis'));
|
|
929
|
+
console.log('');
|
|
930
|
+
console.log(chalk.yellow(' Usage: /project analyze'));
|
|
931
|
+
console.log(chalk.dim(' Analyze current project and generate documentation'));
|
|
932
|
+
console.log('');
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* Analyze current project and generate documentation
|
|
936
|
+
*/
|
|
937
|
+
async handleProjectAnalyze() {
|
|
938
|
+
const { ProjectAnalyzer } = await import('../../../core/src/analysis/ProjectAnalyzer.js');
|
|
939
|
+
console.log('');
|
|
940
|
+
console.log(chalk.hex('#7C3AED').bold(' Analyzing Project...'));
|
|
941
|
+
console.log('');
|
|
942
|
+
try {
|
|
943
|
+
const analyzer = new ProjectAnalyzer(this.cwd, {
|
|
944
|
+
maxDepth: 5,
|
|
945
|
+
includeTests: true,
|
|
946
|
+
includeNodeModules: false,
|
|
947
|
+
analyzeImports: true,
|
|
948
|
+
});
|
|
949
|
+
const structure = await analyzer.analyze();
|
|
950
|
+
console.log(chalk.green(' ✓ Analysis complete'));
|
|
951
|
+
console.log('');
|
|
952
|
+
// Generate markdown documentation
|
|
953
|
+
const markdown = analyzer.generateMarkdown(structure);
|
|
954
|
+
// Save to file
|
|
955
|
+
const { writeFile } = await import('fs/promises');
|
|
956
|
+
const { join } = await import('path');
|
|
957
|
+
const docPath = join(this.cwd, 'PROJECT_ANALYSIS.md');
|
|
958
|
+
await writeFile(docPath, markdown, 'utf-8');
|
|
959
|
+
console.log(chalk.hex('#7C3AED').bold(' Project Summary:'));
|
|
960
|
+
console.log('');
|
|
961
|
+
console.log(chalk.white(` Name: ${structure.name}`));
|
|
962
|
+
console.log(chalk.white(` Type: ${this.formatProjectType(structure.type)}`));
|
|
963
|
+
console.log(chalk.white(` Files: ${structure.codeMetrics.totalFiles}`));
|
|
964
|
+
console.log(chalk.white(` Lines: ${structure.codeMetrics.totalLines.toLocaleString()}`));
|
|
965
|
+
console.log('');
|
|
966
|
+
console.log(chalk.hex('#7C3AED').bold(' Tech Stack:'));
|
|
967
|
+
console.log('');
|
|
968
|
+
if (structure.techStack.languages.length > 0) {
|
|
969
|
+
console.log(chalk.white(' Languages:'));
|
|
970
|
+
structure.techStack.languages.forEach(lang => console.log(chalk.dim(` - ${lang}`)));
|
|
971
|
+
}
|
|
972
|
+
if (structure.techStack.frameworks.length > 0) {
|
|
973
|
+
console.log(chalk.white(' Frameworks:'));
|
|
974
|
+
structure.techStack.frameworks.forEach(fw => console.log(chalk.dim(` - ${fw}`)));
|
|
975
|
+
}
|
|
976
|
+
console.log('');
|
|
977
|
+
console.log(chalk.hex('#7C3AED').bold(' Key Directories:'));
|
|
978
|
+
console.log('');
|
|
979
|
+
structure.directories.slice(0, 5).forEach(dir => {
|
|
980
|
+
console.log(chalk.white(` ${dir.name}/`));
|
|
981
|
+
console.log(chalk.dim(` ${dir.purpose} (${dir.fileCount} files)`));
|
|
982
|
+
});
|
|
983
|
+
console.log('');
|
|
984
|
+
console.log(chalk.green(` ✓ Full documentation saved to: ${docPath}`));
|
|
985
|
+
console.log('');
|
|
986
|
+
console.log(chalk.dim(' The analysis will be used to help the AI understand your project structure.'));
|
|
987
|
+
console.log('');
|
|
988
|
+
// Store analysis in state for injection into system prompt
|
|
989
|
+
this.state.projectAnalysis = markdown;
|
|
990
|
+
}
|
|
991
|
+
catch (error) {
|
|
992
|
+
console.log(chalk.red(` ✗ Error analyzing project: ${error.message}`));
|
|
993
|
+
console.log('');
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* Format project type for display
|
|
998
|
+
*/
|
|
999
|
+
formatProjectType(type) {
|
|
1000
|
+
const typeNames = {
|
|
1001
|
+
unknown: 'Unknown',
|
|
1002
|
+
frontend: 'Frontend Application',
|
|
1003
|
+
backend: 'Backend Application',
|
|
1004
|
+
fullstack: 'Full Stack Application',
|
|
1005
|
+
mobile: 'Mobile Application',
|
|
1006
|
+
desktop: 'Desktop Application',
|
|
1007
|
+
library: 'Library/Package',
|
|
1008
|
+
cli: 'CLI Tool',
|
|
1009
|
+
monorepo: 'Monorepo',
|
|
1010
|
+
};
|
|
1011
|
+
return typeNames[type] || type;
|
|
1012
|
+
}
|
|
1013
|
+
// ========================================================================
|
|
1014
|
+
// Shell Command Handler
|
|
1015
|
+
// ========================================================================
|
|
1016
|
+
async handleShellCommand(cmd) {
|
|
1017
|
+
if (!cmd) {
|
|
1018
|
+
console.log(chalk.gray(' Usage: !<command>'));
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
1021
|
+
console.log(chalk.gray(` $ ${cmd}`));
|
|
1022
|
+
const startTime = Date.now();
|
|
1023
|
+
try {
|
|
1024
|
+
const isWin = process.platform === 'win32';
|
|
1025
|
+
const shell = isWin ? 'powershell.exe' : '/bin/sh';
|
|
1026
|
+
const shellArgs = isWin ? ['-Command', cmd] : ['-c', cmd];
|
|
1027
|
+
await new Promise((resolve, reject) => {
|
|
1028
|
+
const child = spawn(shell, shellArgs, {
|
|
1029
|
+
cwd: this.cwd,
|
|
1030
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
1031
|
+
});
|
|
1032
|
+
child.stdout?.on('data', (chunk) => process.stdout.write(chunk.toString()));
|
|
1033
|
+
child.stderr?.on('data', (chunk) => process.stderr.write(chunk.toString()));
|
|
1034
|
+
child.on('close', (code) => {
|
|
1035
|
+
const duration = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
1036
|
+
if (code === 0) {
|
|
1037
|
+
console.log(chalk.green(` ✓ exit 0`) + chalk.dim(` (${duration}s)`));
|
|
1038
|
+
}
|
|
1039
|
+
else {
|
|
1040
|
+
console.log(chalk.red(` ✗ exit ${code}`) + chalk.dim(` (${duration}s)`));
|
|
1041
|
+
}
|
|
1042
|
+
resolve();
|
|
1043
|
+
});
|
|
1044
|
+
child.on('error', reject);
|
|
1045
|
+
});
|
|
1046
|
+
}
|
|
1047
|
+
catch (err) {
|
|
1048
|
+
console.log(chalk.red(` Error: ${err.message}`));
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
// ========================================================================
|
|
1052
|
+
// Input Processing
|
|
1053
|
+
// ========================================================================
|
|
1054
|
+
async processInput(input) {
|
|
1055
|
+
if (!this.sessionId)
|
|
1056
|
+
return;
|
|
1057
|
+
// Initialize active cursor on first use
|
|
1058
|
+
if (!this.activeCursor) {
|
|
1059
|
+
const { createPurpleCursor } = await import('../ui/components/ActiveCursor.js');
|
|
1060
|
+
this.activeCursor = createPurpleCursor();
|
|
1061
|
+
}
|
|
1062
|
+
// Expand @file references
|
|
1063
|
+
const expandedInput = await this.expandAtReferences(input);
|
|
1064
|
+
// Show user message with highlighted box (distinctive from AI responses)
|
|
1065
|
+
this.userMessageHighlight.render(input);
|
|
1066
|
+
// Clear any previous TODO panel
|
|
1067
|
+
this.todoProgressPanel.hide();
|
|
1068
|
+
// Add to messages
|
|
1069
|
+
this.state.messages.push({
|
|
1070
|
+
id: Date.now().toString(),
|
|
1071
|
+
role: 'user',
|
|
1072
|
+
content: input,
|
|
1073
|
+
timestamp: new Date(),
|
|
1074
|
+
});
|
|
1075
|
+
// Get mode prefix
|
|
1076
|
+
const modePrefix = this.getModePrefix();
|
|
1077
|
+
const fullInput = modePrefix ? `${modePrefix}\n\n${expandedInput}` : expandedInput;
|
|
1078
|
+
// Get model config to check for built-in search capability
|
|
1079
|
+
const modelConfigResult = this.configManager.getModelConfig(this.modelClient.getModel());
|
|
1080
|
+
// Build system prompt
|
|
1081
|
+
// Build system prompt with active skills
|
|
1082
|
+
let systemPrompt = buildSystemPrompt({
|
|
1083
|
+
workingDirectory: this.cwd,
|
|
1084
|
+
model: this.modelClient.getModel(),
|
|
1085
|
+
approvalMode: this.getEffectiveApprovalMode(),
|
|
1086
|
+
supportsBuiltinSearch: modelConfigResult?.model?.supportsBuiltinSearch,
|
|
1087
|
+
});
|
|
1088
|
+
// Inject active skills into system prompt
|
|
1089
|
+
if (this.state.activeSkills && this.state.activeSkills.length > 0) {
|
|
1090
|
+
systemPrompt += '\n\n';
|
|
1091
|
+
systemPrompt += '# Active Skills\n\n';
|
|
1092
|
+
for (const skill of this.state.activeSkills) {
|
|
1093
|
+
systemPrompt += `## ${skill.name}\n`;
|
|
1094
|
+
systemPrompt += `${skill.description}\n\n`;
|
|
1095
|
+
systemPrompt += `${skill.content}\n\n`;
|
|
1096
|
+
systemPrompt += '---\n\n';
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
// Inject project analysis into system prompt
|
|
1100
|
+
if (this.state.projectAnalysis) {
|
|
1101
|
+
systemPrompt += '\n\n';
|
|
1102
|
+
systemPrompt += '# Project Context\n\n';
|
|
1103
|
+
systemPrompt += 'The following is an analysis of the current project structure and tech stack:\n\n';
|
|
1104
|
+
systemPrompt += this.state.projectAnalysis;
|
|
1105
|
+
systemPrompt += '\n';
|
|
1106
|
+
}
|
|
1107
|
+
// Reset tracking counters
|
|
1108
|
+
this.turnCount = 0;
|
|
1109
|
+
this.toolCallCount = 0;
|
|
1110
|
+
this.toolCallStatusDisplay.clear();
|
|
1111
|
+
// Start active cursor (purple circle animation)
|
|
1112
|
+
this.activeCursor.start();
|
|
1113
|
+
// Show compact execution status header
|
|
1114
|
+
this.showExecutionHeader();
|
|
1115
|
+
// Create agent loop
|
|
1116
|
+
this.currentLoop = new AgentLoop({
|
|
1117
|
+
modelClient: this.modelClient,
|
|
1118
|
+
sessionManager: this.sessionManager,
|
|
1119
|
+
toolRegistry: this.toolRegistry,
|
|
1120
|
+
systemPrompt,
|
|
1121
|
+
contextCompressor: this.contextCompressor,
|
|
1122
|
+
maxContextTokens: (this.config.core.maxTokens || 16384) * 8,
|
|
1123
|
+
onTextDelta: (text) => {
|
|
1124
|
+
// Stop cursor when text output starts (prevents cursor symbols in output)
|
|
1125
|
+
if (this.activeCursor && this.activeCursor.isVisible()) {
|
|
1126
|
+
this.activeCursor.stop();
|
|
1127
|
+
}
|
|
1128
|
+
this.currentText += text;
|
|
1129
|
+
process.stdout.write(text);
|
|
1130
|
+
},
|
|
1131
|
+
onToolStart: (name, toolCallId, input) => {
|
|
1132
|
+
this.toolCallCount++;
|
|
1133
|
+
this.toolCallStatusDisplay.startCall(toolCallId, name, input);
|
|
1134
|
+
this.updateStatusLine();
|
|
1135
|
+
},
|
|
1136
|
+
onToolComplete: (name, toolCallId, result) => {
|
|
1137
|
+
if (result.isError) {
|
|
1138
|
+
this.toolCallStatusDisplay.completeError(toolCallId, result.content || 'Unknown error');
|
|
1139
|
+
}
|
|
1140
|
+
else {
|
|
1141
|
+
this.toolCallStatusDisplay.completeSuccess(toolCallId, result.content);
|
|
1142
|
+
}
|
|
1143
|
+
// Handle TODO panel display for todo tool
|
|
1144
|
+
if (name === 'todo' && !result.isError && result.content) {
|
|
1145
|
+
this.handleTodoResult(result.content);
|
|
1146
|
+
}
|
|
1147
|
+
// Handle code file changes display
|
|
1148
|
+
if ((name === 'write_file' || name === 'replace' || name === 'edit_file') && !result.isError) {
|
|
1149
|
+
this.showCodeChangeIndicator(name, result.content);
|
|
1150
|
+
}
|
|
1151
|
+
this.updateStatusLine();
|
|
1152
|
+
},
|
|
1153
|
+
onThinkingStart: () => {
|
|
1154
|
+
if (this.state.showThinking) {
|
|
1155
|
+
this.thinkingContentDisplay.start();
|
|
1156
|
+
}
|
|
1157
|
+
},
|
|
1158
|
+
onThinkingDelta: (delta) => {
|
|
1159
|
+
if (this.state.showThinking) {
|
|
1160
|
+
this.thinkingContentDisplay.append(delta);
|
|
1161
|
+
}
|
|
1162
|
+
},
|
|
1163
|
+
onThinkingEnd: () => {
|
|
1164
|
+
if (this.state.showThinking) {
|
|
1165
|
+
this.thinkingContentDisplay.complete();
|
|
1166
|
+
}
|
|
1167
|
+
},
|
|
1168
|
+
onApprovalRequired: this.handleApproval.bind(this),
|
|
1169
|
+
onTurnStart: (turn) => {
|
|
1170
|
+
this.turnCount = turn;
|
|
1171
|
+
this.updateStatusLine();
|
|
1172
|
+
},
|
|
1173
|
+
onTurnEnd: () => {
|
|
1174
|
+
// Nothing
|
|
1175
|
+
},
|
|
1176
|
+
onContextCompress: (orig, result, action) => {
|
|
1177
|
+
console.log(chalk.dim(` 🔄 context: ${orig} → ${result} tokens (${action})`));
|
|
1178
|
+
},
|
|
1179
|
+
});
|
|
1180
|
+
try {
|
|
1181
|
+
const result = await this.currentLoop.runStream(this.sessionId, fullInput);
|
|
1182
|
+
// Add assistant message
|
|
1183
|
+
this.state.messages.push({
|
|
1184
|
+
id: (Date.now() + 1).toString(),
|
|
1185
|
+
role: 'assistant',
|
|
1186
|
+
content: this.currentText,
|
|
1187
|
+
timestamp: new Date(),
|
|
1188
|
+
});
|
|
1189
|
+
// Update context usage
|
|
1190
|
+
const totalTokens = result.totalInputTokens + result.totalOutputTokens;
|
|
1191
|
+
this.state.contextUsage = Math.min(100, Math.round((totalTokens / 128000) * 100));
|
|
1192
|
+
// Show summary
|
|
1193
|
+
console.log('');
|
|
1194
|
+
console.log(chalk.dim(` ✓ ${result.turnsCompleted} turns · ${totalTokens.toLocaleString()} tokens`));
|
|
1195
|
+
// Persist session
|
|
1196
|
+
this.sessionManager.persist(this.sessionId);
|
|
1197
|
+
}
|
|
1198
|
+
catch (err) {
|
|
1199
|
+
if (err.name !== 'CancelledError') {
|
|
1200
|
+
console.log(chalk.red(`\n Error: ${err.message}`));
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
finally {
|
|
1204
|
+
this.currentLoop = null;
|
|
1205
|
+
this.currentText = '';
|
|
1206
|
+
// Stop active cursor
|
|
1207
|
+
if (this.activeCursor)
|
|
1208
|
+
this.activeCursor.stop();
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
// ========================================================================
|
|
1212
|
+
// @ File Reference Expansion
|
|
1213
|
+
// ========================================================================
|
|
1214
|
+
async expandAtReferences(input) {
|
|
1215
|
+
const atPattern = /@([\w./\-\\]+)/g;
|
|
1216
|
+
const matches = [...input.matchAll(atPattern)];
|
|
1217
|
+
if (matches.length === 0)
|
|
1218
|
+
return input;
|
|
1219
|
+
const injections = [];
|
|
1220
|
+
for (const match of matches) {
|
|
1221
|
+
const refPath = match[1];
|
|
1222
|
+
if (!refPath)
|
|
1223
|
+
continue;
|
|
1224
|
+
const absPath = path.isAbsolute(refPath)
|
|
1225
|
+
? refPath
|
|
1226
|
+
: path.resolve(this.cwd, refPath);
|
|
1227
|
+
try {
|
|
1228
|
+
if (!fs.existsSync(absPath)) {
|
|
1229
|
+
injections.push(`[@${refPath}: not found]`);
|
|
1230
|
+
continue;
|
|
1231
|
+
}
|
|
1232
|
+
const stat = fs.statSync(absPath);
|
|
1233
|
+
if (stat.isDirectory()) {
|
|
1234
|
+
const files = fs.readdirSync(absPath).slice(0, 20);
|
|
1235
|
+
injections.push(`\n\`\`\`\n# Directory: ${refPath}\n${files.join('\n')}\n\`\`\`\n`);
|
|
1236
|
+
}
|
|
1237
|
+
else {
|
|
1238
|
+
const content = fs.readFileSync(absPath, 'utf-8');
|
|
1239
|
+
const ext = path.extname(refPath).slice(1) || 'txt';
|
|
1240
|
+
injections.push(`\n\`\`\`${ext}\n# ${refPath}\n${content}\n\`\`\`\n`);
|
|
1241
|
+
}
|
|
1242
|
+
console.log(chalk.dim(` @ ${refPath}`));
|
|
1243
|
+
}
|
|
1244
|
+
catch (err) {
|
|
1245
|
+
injections.push(`[@${refPath}: error]`);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
return input + '\n' + injections.join('\n');
|
|
1249
|
+
}
|
|
1250
|
+
// ========================================================================
|
|
1251
|
+
// Approval Handler
|
|
1252
|
+
// ========================================================================
|
|
1253
|
+
async handleApproval(request) {
|
|
1254
|
+
const mode = this.getEffectiveApprovalMode();
|
|
1255
|
+
if (mode === 'yolo' || mode === 'accepting_edits') {
|
|
1256
|
+
return { requestId: request.id, approved: true };
|
|
1257
|
+
}
|
|
1258
|
+
console.log('');
|
|
1259
|
+
console.log(chalk.yellow.bold(' ⚠ Approval Required'));
|
|
1260
|
+
console.log(chalk.gray(` Tool: ${request.toolName}`));
|
|
1261
|
+
console.log(chalk.gray(` Risk: ${request.risk}`));
|
|
1262
|
+
console.log('');
|
|
1263
|
+
// For now, auto-approve in non-interactive mode
|
|
1264
|
+
// In a full implementation, this would use a ConfirmDialog
|
|
1265
|
+
return { requestId: request.id, approved: true };
|
|
1266
|
+
}
|
|
1267
|
+
// ========================================================================
|
|
1268
|
+
// Helpers
|
|
1269
|
+
// ========================================================================
|
|
1270
|
+
getModePrefix() {
|
|
1271
|
+
switch (this.state.mode) {
|
|
1272
|
+
case 'plan':
|
|
1273
|
+
return '[PLAN MODE] First analyze and create a step-by-step plan. Wait for confirmation before executing.';
|
|
1274
|
+
case 'ask':
|
|
1275
|
+
return '[ASK MODE] Only answer questions. Do NOT modify files or execute commands.';
|
|
1276
|
+
default:
|
|
1277
|
+
return '';
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
getEffectiveApprovalMode() {
|
|
1281
|
+
switch (this.state.mode) {
|
|
1282
|
+
case 'auto': return 'yolo';
|
|
1283
|
+
case 'plan': return 'plan';
|
|
1284
|
+
case 'ask': return 'plan';
|
|
1285
|
+
default: return 'default';
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
summarizeToolInput(name, input) {
|
|
1289
|
+
switch (name) {
|
|
1290
|
+
case 'read_file':
|
|
1291
|
+
case 'list_directory':
|
|
1292
|
+
return String(input.file_path || input.path || input.target_directory || '').replace(/\\/g, '/').split('/').slice(-2).join('/');
|
|
1293
|
+
case 'write_file':
|
|
1294
|
+
return String(input.file_path || input.path || '').replace(/\\/g, '/').split('/').slice(-2).join('/') + ' (write)';
|
|
1295
|
+
case 'edit_file':
|
|
1296
|
+
case 'replace_in_file':
|
|
1297
|
+
return String(input.file_path || '').replace(/\\/g, '/').split('/').slice(-2).join('/') + ' (edit)';
|
|
1298
|
+
case 'execute_command':
|
|
1299
|
+
return String(input.command || '').slice(0, 60);
|
|
1300
|
+
case 'search_file':
|
|
1301
|
+
return String(input.pattern || '') + ' in ' + String(input.path || '.').split('/').pop();
|
|
1302
|
+
case 'search_content':
|
|
1303
|
+
return '"' + String(input.pattern || '').slice(0, 40) + '"';
|
|
1304
|
+
case 'web_search':
|
|
1305
|
+
return '"' + String(input.query || '').slice(0, 40) + '"';
|
|
1306
|
+
default:
|
|
1307
|
+
const vals = Object.values(input).filter((v) => typeof v === 'string' && v.length > 0);
|
|
1308
|
+
return vals.length > 0 ? vals[0].slice(0, 50) : '';
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
/**
|
|
1312
|
+
* Handle TODO tool result and display in fixed-position panel
|
|
1313
|
+
*/
|
|
1314
|
+
handleTodoResult(result) {
|
|
1315
|
+
if (!result || result === 'No tasks tracked.' || result === 'All tasks cleared.') {
|
|
1316
|
+
this.todoProgressPanel.hide();
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1319
|
+
const lines = result.split('\n').filter((l) => l.trim());
|
|
1320
|
+
if (lines.length === 0) {
|
|
1321
|
+
this.todoProgressPanel.hide();
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1324
|
+
// Parse TODO items from the result string
|
|
1325
|
+
const todos = [];
|
|
1326
|
+
let idx = 0;
|
|
1327
|
+
for (const line of lines) {
|
|
1328
|
+
const pendingMatch = line.match(/^○\s+\[pending\s*\]\s+(.+)/);
|
|
1329
|
+
const inProgressMatch = line.match(/^◉\s+\[in_progress\s*\]\s+(.+)/);
|
|
1330
|
+
const completedMatch = line.match(/^●\s+\[completed\s*\]\s+(.+)/);
|
|
1331
|
+
const failedMatch = line.match(/^✗\s+\[failed\s*\]\s+(.+)/);
|
|
1332
|
+
// Detect priority from task text
|
|
1333
|
+
const detectPriority = (text) => {
|
|
1334
|
+
if (/high|critical|urgent|重要/i.test(text))
|
|
1335
|
+
return 'high';
|
|
1336
|
+
if (/low|minor|低/i.test(text))
|
|
1337
|
+
return 'low';
|
|
1338
|
+
if (/medium|normal|中/i.test(text))
|
|
1339
|
+
return 'medium';
|
|
1340
|
+
return undefined;
|
|
1341
|
+
};
|
|
1342
|
+
if (completedMatch) {
|
|
1343
|
+
todos.push({
|
|
1344
|
+
id: String(idx++),
|
|
1345
|
+
task: completedMatch[1].trim(),
|
|
1346
|
+
status: 'completed',
|
|
1347
|
+
priority: detectPriority(completedMatch[1]),
|
|
1348
|
+
});
|
|
1349
|
+
}
|
|
1350
|
+
else if (inProgressMatch) {
|
|
1351
|
+
todos.push({
|
|
1352
|
+
id: String(idx++),
|
|
1353
|
+
task: inProgressMatch[1].trim(),
|
|
1354
|
+
status: 'in_progress',
|
|
1355
|
+
priority: detectPriority(inProgressMatch[1]),
|
|
1356
|
+
});
|
|
1357
|
+
}
|
|
1358
|
+
else if (pendingMatch) {
|
|
1359
|
+
todos.push({
|
|
1360
|
+
id: String(idx++),
|
|
1361
|
+
task: pendingMatch[1].trim(),
|
|
1362
|
+
status: 'pending',
|
|
1363
|
+
priority: detectPriority(pendingMatch[1]),
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
else if (failedMatch) {
|
|
1367
|
+
todos.push({
|
|
1368
|
+
id: String(idx++),
|
|
1369
|
+
task: failedMatch[1].trim(),
|
|
1370
|
+
status: 'failed',
|
|
1371
|
+
priority: detectPriority(failedMatch[1]),
|
|
1372
|
+
});
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
// Update and show the fixed-position TODO panel
|
|
1376
|
+
if (todos.length > 0) {
|
|
1377
|
+
this.todoProgressPanel.setTodos(todos);
|
|
1378
|
+
this.todoProgressPanel.show();
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
/**
|
|
1382
|
+
* Show compact execution status header
|
|
1383
|
+
*/
|
|
1384
|
+
showExecutionHeader() {
|
|
1385
|
+
console.log(chalk.dim(' ┌─ 执行开始 ' + '─'.repeat(40)));
|
|
1386
|
+
}
|
|
1387
|
+
/**
|
|
1388
|
+
* Update the compact status line showing current progress
|
|
1389
|
+
*/
|
|
1390
|
+
updateStatusLine() {
|
|
1391
|
+
const stats = this.toolCallStatusDisplay.getStats();
|
|
1392
|
+
const statusIcon = stats.error > 0 ? chalk.red('⚠') : stats.running > 0 ? chalk.yellow('◉') : chalk.green('✓');
|
|
1393
|
+
const turnStr = this.turnCount > 0 ? `turn ${this.turnCount}` : 'init';
|
|
1394
|
+
const toolStr = `${stats.success}✓ ${stats.error}✗`;
|
|
1395
|
+
const status = `${statusIcon} ${chalk.dim(turnStr)} ${chalk.dim('·')} ${chalk.dim(toolStr)}`;
|
|
1396
|
+
// Only update if changed
|
|
1397
|
+
if (status !== this.lastStatusLine) {
|
|
1398
|
+
this.lastStatusLine = status;
|
|
1399
|
+
// Write status to a fixed position (compact inline update)
|
|
1400
|
+
process.stdout.write(`\r${status} `);
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* Show indicator when code files are modified
|
|
1405
|
+
*/
|
|
1406
|
+
showCodeChangeIndicator(name, result) {
|
|
1407
|
+
// Extract file path from result if available
|
|
1408
|
+
const pathMatch = result?.match(/(.+\.\w+)/);
|
|
1409
|
+
const filePath = pathMatch ? pathMatch[1].split('/').slice(-2).join('/') : 'file';
|
|
1410
|
+
// Show compact code change indicator
|
|
1411
|
+
const icon = name === 'write_file' ? chalk.cyan('📝') : chalk.yellow('✏️');
|
|
1412
|
+
console.log(`\n ${icon} ${chalk.dim(filePath)}`);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
//# sourceMappingURL=InkBasedRepl.js.map
|