@mseep/claudian 2.0.25
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/.env.local.example +2 -0
- package/.github/workflows/ci.yml +59 -0
- package/.github/workflows/claude-code-review.yml +57 -0
- package/.github/workflows/claude.yml +50 -0
- package/.github/workflows/duplicate-issues.yml +22 -0
- package/.github/workflows/release.yml +73 -0
- package/.github/workflows/stale.yml +21 -0
- package/.node-version +1 -0
- package/AGENTS.md +3 -0
- package/CLAUDE.md +80 -0
- package/LICENSE +21 -0
- package/README.md +190 -0
- package/assets/Preview.png +0 -0
- package/assets/sponsors/MOMA.png +0 -0
- package/bun.lock +1618 -0
- package/esbuild.config.mjs +195 -0
- package/eslint.config.mjs +143 -0
- package/jest.config.js +41 -0
- package/main.js +104915 -0
- package/manifest.json +10 -0
- package/package.json +65 -0
- package/scripts/build-css.mjs +119 -0
- package/scripts/build.mjs +19 -0
- package/scripts/postinstall.mjs +25 -0
- package/scripts/rendererSafeUnref.js +205 -0
- package/scripts/run-jest.js +19 -0
- package/scripts/sync-version.js +16 -0
- package/src/app/settings/ClaudianSettingsStorage.ts +435 -0
- package/src/app/settings/defaultSettings.ts +54 -0
- package/src/app/storage/SharedStorageService.ts +106 -0
- package/src/core/CLAUDE.md +84 -0
- package/src/core/auxiliary/AuxQueryRunner.ts +11 -0
- package/src/core/auxiliary/QueryBackedInlineEditService.ts +73 -0
- package/src/core/auxiliary/QueryBackedInstructionRefineService.ts +78 -0
- package/src/core/auxiliary/QueryBackedTitleGenerationService.ts +90 -0
- package/src/core/bootstrap/SessionStorage.ts +179 -0
- package/src/core/bootstrap/StoragePaths.ts +7 -0
- package/src/core/bootstrap/storage.ts +20 -0
- package/src/core/commands/builtInCommands.ts +141 -0
- package/src/core/mcp/McpConfigParser.ts +102 -0
- package/src/core/mcp/McpServerManager.ts +119 -0
- package/src/core/mcp/McpTester.ts +310 -0
- package/src/core/prompt/inlineEdit.ts +252 -0
- package/src/core/prompt/instructionRefine.ts +72 -0
- package/src/core/prompt/mainAgent.ts +213 -0
- package/src/core/prompt/titleGeneration.ts +44 -0
- package/src/core/providers/ProviderRegistry.ts +253 -0
- package/src/core/providers/ProviderSettingsCoordinator.ts +434 -0
- package/src/core/providers/ProviderWorkspaceRegistry.ts +119 -0
- package/src/core/providers/commands/ProviderCommandCatalog.ts +21 -0
- package/src/core/providers/commands/ProviderCommandEntry.ts +33 -0
- package/src/core/providers/commands/hiddenCommands.ts +74 -0
- package/src/core/providers/modelRouting.ts +17 -0
- package/src/core/providers/modelSelection.ts +72 -0
- package/src/core/providers/providerConfig.ts +34 -0
- package/src/core/providers/providerEnvironment.ts +364 -0
- package/src/core/providers/types.ts +544 -0
- package/src/core/runtime/ChatRuntime.ts +66 -0
- package/src/core/runtime/QueuedTurn.ts +97 -0
- package/src/core/runtime/types.ts +118 -0
- package/src/core/security/ApprovalManager.ts +142 -0
- package/src/core/storage/HomeFileAdapter.ts +75 -0
- package/src/core/storage/VaultFileAdapter.ts +132 -0
- package/src/core/tools/todo.ts +65 -0
- package/src/core/tools/toolIcons.ts +80 -0
- package/src/core/tools/toolInput.ts +119 -0
- package/src/core/tools/toolNames.ts +149 -0
- package/src/core/tools/toolResultContent.ts +26 -0
- package/src/core/types/agent.ts +28 -0
- package/src/core/types/chat.ts +177 -0
- package/src/core/types/diff.ts +31 -0
- package/src/core/types/index.ts +78 -0
- package/src/core/types/mcp.ts +97 -0
- package/src/core/types/plugins.ts +9 -0
- package/src/core/types/provider.ts +1 -0
- package/src/core/types/settings.ts +152 -0
- package/src/core/types/tools.ts +80 -0
- package/src/features/chat/CLAUDE.md +136 -0
- package/src/features/chat/ClaudianView.ts +762 -0
- package/src/features/chat/constants.ts +114 -0
- package/src/features/chat/controllers/BrowserSelectionController.ts +295 -0
- package/src/features/chat/controllers/CanvasSelectionController.ts +142 -0
- package/src/features/chat/controllers/ConversationController.ts +1103 -0
- package/src/features/chat/controllers/InputController.ts +1707 -0
- package/src/features/chat/controllers/NavigationController.ts +209 -0
- package/src/features/chat/controllers/SelectionController.ts +430 -0
- package/src/features/chat/controllers/StreamController.ts +1560 -0
- package/src/features/chat/controllers/contextRowVisibility.ts +18 -0
- package/src/features/chat/rendering/DiffRenderer.ts +134 -0
- package/src/features/chat/rendering/InlineAskUserQuestion.ts +702 -0
- package/src/features/chat/rendering/InlineExitPlanMode.ts +263 -0
- package/src/features/chat/rendering/InlinePlanApproval.ts +183 -0
- package/src/features/chat/rendering/MessageRenderer.ts +907 -0
- package/src/features/chat/rendering/SubagentRenderer.ts +678 -0
- package/src/features/chat/rendering/ThinkingBlockRenderer.ts +126 -0
- package/src/features/chat/rendering/TodoListRenderer.ts +5 -0
- package/src/features/chat/rendering/ToolCallRenderer.ts +1161 -0
- package/src/features/chat/rendering/WriteEditRenderer.ts +232 -0
- package/src/features/chat/rendering/collapsible.ts +101 -0
- package/src/features/chat/rendering/subagentLifecycleResolution.ts +25 -0
- package/src/features/chat/rendering/todoUtils.ts +29 -0
- package/src/features/chat/rewind.ts +31 -0
- package/src/features/chat/services/BangBashService.ts +56 -0
- package/src/features/chat/services/SubagentManager.ts +1107 -0
- package/src/features/chat/state/ChatState.ts +436 -0
- package/src/features/chat/state/types.ts +138 -0
- package/src/features/chat/tabs/Tab.ts +1886 -0
- package/src/features/chat/tabs/TabBar.ts +179 -0
- package/src/features/chat/tabs/TabManager.ts +1021 -0
- package/src/features/chat/tabs/providerResolution.ts +34 -0
- package/src/features/chat/tabs/types.ts +287 -0
- package/src/features/chat/ui/BangBashModeManager.ts +121 -0
- package/src/features/chat/ui/FileContext.ts +385 -0
- package/src/features/chat/ui/ImageContext.ts +366 -0
- package/src/features/chat/ui/InputToolbar.ts +1244 -0
- package/src/features/chat/ui/InstructionModeManager.ts +158 -0
- package/src/features/chat/ui/NavigationSidebar.ts +126 -0
- package/src/features/chat/ui/StatusPanel.ts +589 -0
- package/src/features/chat/ui/file-context/state/FileContextState.ts +83 -0
- package/src/features/chat/ui/file-context/view/FileChipsView.ts +70 -0
- package/src/features/chat/ui/textareaResize.ts +47 -0
- package/src/features/chat/utils/usageInfo.ts +26 -0
- package/src/features/inline-edit/ui/InlineEditModal.ts +895 -0
- package/src/features/inline-edit/ui/inlineEditMarkdownPreview.ts +55 -0
- package/src/features/settings/ClaudianSettings.ts +672 -0
- package/src/features/settings/keyboardNavigation.ts +60 -0
- package/src/features/settings/ui/EnvSnippetManager.ts +430 -0
- package/src/features/settings/ui/EnvironmentSettingsSection.ts +85 -0
- package/src/features/settings/ui/McpServerModal.ts +335 -0
- package/src/features/settings/ui/McpSettingsManager.ts +400 -0
- package/src/features/settings/ui/McpTestModal.ts +346 -0
- package/src/i18n/constants.ts +58 -0
- package/src/i18n/i18n.ts +140 -0
- package/src/i18n/locales/de.json +322 -0
- package/src/i18n/locales/en.json +322 -0
- package/src/i18n/locales/es.json +322 -0
- package/src/i18n/locales/fr.json +322 -0
- package/src/i18n/locales/ja.json +322 -0
- package/src/i18n/locales/ko.json +322 -0
- package/src/i18n/locales/pt.json +322 -0
- package/src/i18n/locales/ru.json +322 -0
- package/src/i18n/locales/zh-CN.json +322 -0
- package/src/i18n/locales/zh-TW.json +322 -0
- package/src/i18n/types.ts +248 -0
- package/src/main.ts +772 -0
- package/src/providers/acp/AcpClientConnection.ts +361 -0
- package/src/providers/acp/AcpJsonRpcTransport.ts +427 -0
- package/src/providers/acp/AcpSessionConfig.ts +139 -0
- package/src/providers/acp/AcpSessionUpdateNormalizer.ts +371 -0
- package/src/providers/acp/AcpSubprocess.ts +155 -0
- package/src/providers/acp/AcpToolStreamAdapter.ts +132 -0
- package/src/providers/acp/buildAcpUsageInfo.ts +41 -0
- package/src/providers/acp/index.ts +9 -0
- package/src/providers/acp/methodNames.ts +50 -0
- package/src/providers/acp/types.ts +566 -0
- package/src/providers/claude/CLAUDE.md +78 -0
- package/src/providers/claude/agents/AgentManager.ts +225 -0
- package/src/providers/claude/agents/AgentStorage.ts +101 -0
- package/src/providers/claude/app/ClaudeWorkspaceServices.ts +90 -0
- package/src/providers/claude/auxiliary/ClaudeInlineEditService.ts +122 -0
- package/src/providers/claude/auxiliary/ClaudeInstructionRefineService.ts +90 -0
- package/src/providers/claude/auxiliary/ClaudeTitleGenerationService.ts +129 -0
- package/src/providers/claude/auxiliary/extractAssistantText.ts +28 -0
- package/src/providers/claude/capabilities.ts +17 -0
- package/src/providers/claude/cli/findClaudeCLIPath.ts +261 -0
- package/src/providers/claude/commands/ClaudeCommandCatalog.ts +149 -0
- package/src/providers/claude/commands/probeRuntimeCommands.ts +86 -0
- package/src/providers/claude/env/ClaudeSettingsReconciler.ts +90 -0
- package/src/providers/claude/env/claudeModelEnv.ts +86 -0
- package/src/providers/claude/history/ClaudeConversationHistoryService.ts +446 -0
- package/src/providers/claude/history/ClaudeHistoryStore.ts +170 -0
- package/src/providers/claude/history/sdkAsyncSubagent.ts +92 -0
- package/src/providers/claude/history/sdkBranchFilter.ts +271 -0
- package/src/providers/claude/history/sdkHistoryTypes.ts +61 -0
- package/src/providers/claude/history/sdkMessageParsing.ts +413 -0
- package/src/providers/claude/history/sdkSessionPaths.ts +98 -0
- package/src/providers/claude/history/sdkSubagentSidecar.ts +261 -0
- package/src/providers/claude/hooks/SubagentHooks.ts +31 -0
- package/src/providers/claude/modelLabels.ts +77 -0
- package/src/providers/claude/modelOptions.ts +113 -0
- package/src/providers/claude/modelSelection.ts +17 -0
- package/src/providers/claude/plugins/PluginManager.ts +194 -0
- package/src/providers/claude/prompt/ClaudeTurnEncoder.ts +46 -0
- package/src/providers/claude/registration.ts +39 -0
- package/src/providers/claude/runtime/ClaudeApprovalHandler.ts +153 -0
- package/src/providers/claude/runtime/ClaudeChatRuntime.ts +1812 -0
- package/src/providers/claude/runtime/ClaudeCliResolver.ts +94 -0
- package/src/providers/claude/runtime/ClaudeDynamicUpdates.ts +164 -0
- package/src/providers/claude/runtime/ClaudeMessageChannel.ts +209 -0
- package/src/providers/claude/runtime/ClaudeQueryOptionsBuilder.ts +315 -0
- package/src/providers/claude/runtime/ClaudeRewindService.ts +220 -0
- package/src/providers/claude/runtime/ClaudeSessionManager.ts +92 -0
- package/src/providers/claude/runtime/ClaudeTaskResultInterpreter.ts +172 -0
- package/src/providers/claude/runtime/ClaudeUserMessageFactory.ts +83 -0
- package/src/providers/claude/runtime/claudeColdStartQuery.ts +152 -0
- package/src/providers/claude/runtime/customSpawn.ts +87 -0
- package/src/providers/claude/runtime/types.ts +134 -0
- package/src/providers/claude/sdk/messages.ts +17 -0
- package/src/providers/claude/sdk/toolResultContent.ts +4 -0
- package/src/providers/claude/sdk/typeGuards.ts +14 -0
- package/src/providers/claude/sdk/types.ts +15 -0
- package/src/providers/claude/security/ClaudePermissionUpdates.ts +44 -0
- package/src/providers/claude/settings.ts +138 -0
- package/src/providers/claude/storage/AgentVaultStorage.ts +101 -0
- package/src/providers/claude/storage/CCSettingsStorage.ts +153 -0
- package/src/providers/claude/storage/ClaudianSettingsStorage.ts +6 -0
- package/src/providers/claude/storage/McpStorage.ts +139 -0
- package/src/providers/claude/storage/SessionStorage.ts +5 -0
- package/src/providers/claude/storage/SkillStorage.ts +61 -0
- package/src/providers/claude/storage/SlashCommandStorage.ts +96 -0
- package/src/providers/claude/storage/StorageService.ts +185 -0
- package/src/providers/claude/stream/toolInputStreamState.ts +318 -0
- package/src/providers/claude/stream/transformClaudeMessage.ts +586 -0
- package/src/providers/claude/types/agent.ts +2 -0
- package/src/providers/claude/types/models.ts +168 -0
- package/src/providers/claude/types/plugins.ts +14 -0
- package/src/providers/claude/types/providerState.ts +16 -0
- package/src/providers/claude/types/settings.ts +98 -0
- package/src/providers/claude/ui/AgentSettings.ts +389 -0
- package/src/providers/claude/ui/ClaudeChatUIConfig.ts +113 -0
- package/src/providers/claude/ui/ClaudeSettingsTab.ts +407 -0
- package/src/providers/claude/ui/PluginSettingsManager.ts +149 -0
- package/src/providers/claude/ui/SlashCommandSettings.ts +527 -0
- package/src/providers/codex/CLAUDE.md +64 -0
- package/src/providers/codex/agents/CodexAgentMentionProvider.ts +33 -0
- package/src/providers/codex/app/CodexWorkspaceServices.ts +76 -0
- package/src/providers/codex/auxiliary/CodexInlineEditService.ts +9 -0
- package/src/providers/codex/auxiliary/CodexInstructionRefineService.ts +9 -0
- package/src/providers/codex/auxiliary/CodexTaskResultInterpreter.ts +29 -0
- package/src/providers/codex/auxiliary/CodexTitleGenerationService.ts +22 -0
- package/src/providers/codex/capabilities.ts +16 -0
- package/src/providers/codex/commands/CodexSkillCatalog.ts +180 -0
- package/src/providers/codex/env/CodexSettingsReconciler.ts +68 -0
- package/src/providers/codex/history/CodexConversationHistoryService.ts +212 -0
- package/src/providers/codex/history/CodexHistoryStore.ts +1672 -0
- package/src/providers/codex/modelOptions.ts +99 -0
- package/src/providers/codex/modelSelection.ts +17 -0
- package/src/providers/codex/normalization/codexSubagentNormalization.ts +227 -0
- package/src/providers/codex/normalization/codexToolNormalization.ts +390 -0
- package/src/providers/codex/prompt/encodeCodexTurn.ts +57 -0
- package/src/providers/codex/registration.ts +29 -0
- package/src/providers/codex/runtime/CodexAppServerProcess.ts +105 -0
- package/src/providers/codex/runtime/CodexAuxQueryRunner.ts +180 -0
- package/src/providers/codex/runtime/CodexBinaryLocator.ts +49 -0
- package/src/providers/codex/runtime/CodexChatRuntime.ts +1296 -0
- package/src/providers/codex/runtime/CodexCliResolver.ts +65 -0
- package/src/providers/codex/runtime/CodexExecutionTargetResolver.ts +104 -0
- package/src/providers/codex/runtime/CodexLaunchSpecBuilder.ts +85 -0
- package/src/providers/codex/runtime/CodexNotificationRouter.ts +1033 -0
- package/src/providers/codex/runtime/CodexPathMapper.ts +155 -0
- package/src/providers/codex/runtime/CodexRpcTransport.ts +171 -0
- package/src/providers/codex/runtime/CodexRuntimeContext.ts +109 -0
- package/src/providers/codex/runtime/CodexServerRequestRouter.ts +331 -0
- package/src/providers/codex/runtime/CodexSessionFileTail.ts +792 -0
- package/src/providers/codex/runtime/CodexSessionManager.ts +39 -0
- package/src/providers/codex/runtime/codexAppServerSupport.ts +58 -0
- package/src/providers/codex/runtime/codexAppServerTypes.ts +705 -0
- package/src/providers/codex/runtime/codexLaunchTypes.ts +30 -0
- package/src/providers/codex/settings.ts +236 -0
- package/src/providers/codex/skills/CodexSkillListingService.ts +173 -0
- package/src/providers/codex/storage/CodexSkillStorage.ts +250 -0
- package/src/providers/codex/storage/CodexSubagentStorage.ts +212 -0
- package/src/providers/codex/types/index.ts +16 -0
- package/src/providers/codex/types/models.ts +46 -0
- package/src/providers/codex/types/subagent.ts +23 -0
- package/src/providers/codex/ui/CodexChatUIConfig.ts +128 -0
- package/src/providers/codex/ui/CodexSettingsTab.ts +432 -0
- package/src/providers/codex/ui/CodexSkillSettings.ts +275 -0
- package/src/providers/codex/ui/CodexSubagentSettings.ts +400 -0
- package/src/providers/defaultProviderConfigs.ts +14 -0
- package/src/providers/index.ts +30 -0
- package/src/providers/opencode/agents/OpencodeAgentMentionProvider.ts +42 -0
- package/src/providers/opencode/app/OpencodeRuntimeCommandLoader.ts +67 -0
- package/src/providers/opencode/app/OpencodeWorkspaceServices.ts +55 -0
- package/src/providers/opencode/auxiliary/OpencodeInlineEditService.ts +13 -0
- package/src/providers/opencode/auxiliary/OpencodeInstructionRefineService.ts +12 -0
- package/src/providers/opencode/auxiliary/OpencodeTaskResultInterpreter.ts +29 -0
- package/src/providers/opencode/auxiliary/OpencodeTitleGenerationService.ts +27 -0
- package/src/providers/opencode/capabilities.ts +16 -0
- package/src/providers/opencode/commands/OpencodeCommandCatalog.ts +92 -0
- package/src/providers/opencode/discoveryState.ts +135 -0
- package/src/providers/opencode/env/OpencodeSettingsReconciler.ts +178 -0
- package/src/providers/opencode/history/OpencodeConversationHistoryService.ts +84 -0
- package/src/providers/opencode/history/OpencodeHistoryStore.ts +472 -0
- package/src/providers/opencode/history/OpencodeSqliteReader.ts +284 -0
- package/src/providers/opencode/internal/compareCollections.ts +72 -0
- package/src/providers/opencode/internal/providerProjection.ts +15 -0
- package/src/providers/opencode/models.ts +378 -0
- package/src/providers/opencode/modes.ts +150 -0
- package/src/providers/opencode/normalization/opencodeToolNormalization.ts +406 -0
- package/src/providers/opencode/registration.ts +27 -0
- package/src/providers/opencode/runtime/OpencodeAuxQueryRunner.ts +436 -0
- package/src/providers/opencode/runtime/OpencodeChatRuntime.ts +1603 -0
- package/src/providers/opencode/runtime/OpencodeCliResolver.ts +57 -0
- package/src/providers/opencode/runtime/OpencodeLaunchArtifacts.ts +231 -0
- package/src/providers/opencode/runtime/OpencodePaths.ts +113 -0
- package/src/providers/opencode/runtime/OpencodeRuntimeEnvironment.ts +18 -0
- package/src/providers/opencode/runtime/buildOpencodePrompt.ts +66 -0
- package/src/providers/opencode/settings.ts +427 -0
- package/src/providers/opencode/storage/OpencodeAgentStorage.ts +346 -0
- package/src/providers/opencode/types/agent.ts +37 -0
- package/src/providers/opencode/types/index.ts +9 -0
- package/src/providers/opencode/ui/OpencodeAgentSettings.ts +579 -0
- package/src/providers/opencode/ui/OpencodeChatUIConfig.ts +316 -0
- package/src/providers/opencode/ui/OpencodeSettingsTab.ts +674 -0
- package/src/providers/pi/app/PiRuntimeCommandLoader.ts +57 -0
- package/src/providers/pi/app/PiWorkspaceServices.ts +39 -0
- package/src/providers/pi/auxiliary/PiInlineEditService.ts +9 -0
- package/src/providers/pi/auxiliary/PiInstructionRefineService.ts +9 -0
- package/src/providers/pi/auxiliary/PiTaskResultInterpreter.ts +29 -0
- package/src/providers/pi/auxiliary/PiTitleGenerationService.ts +19 -0
- package/src/providers/pi/capabilities.ts +16 -0
- package/src/providers/pi/commands/PiCommandCatalog.ts +92 -0
- package/src/providers/pi/env/PiSettingsReconciler.ts +180 -0
- package/src/providers/pi/history/PiConversationHistoryService.ts +123 -0
- package/src/providers/pi/history/PiHistoryStore.ts +664 -0
- package/src/providers/pi/internal/compareCollections.ts +4 -0
- package/src/providers/pi/internal/providerProjection.ts +18 -0
- package/src/providers/pi/models.ts +302 -0
- package/src/providers/pi/normalizations/piEventNormalization.ts +211 -0
- package/src/providers/pi/normalizations/piToolNormalization.ts +97 -0
- package/src/providers/pi/registration.ts +30 -0
- package/src/providers/pi/runtime/PiAuxQueryRunner.ts +216 -0
- package/src/providers/pi/runtime/PiChatRuntime.ts +1064 -0
- package/src/providers/pi/runtime/PiCliResolver.ts +53 -0
- package/src/providers/pi/runtime/PiExtensionUiBridge.ts +161 -0
- package/src/providers/pi/runtime/PiJsonl.ts +71 -0
- package/src/providers/pi/runtime/PiLaunchSpec.ts +70 -0
- package/src/providers/pi/runtime/PiModelDiscoveryService.ts +92 -0
- package/src/providers/pi/runtime/PiRpcPayloads.ts +18 -0
- package/src/providers/pi/runtime/PiRpcTransport.ts +243 -0
- package/src/providers/pi/runtime/PiSubprocess.ts +159 -0
- package/src/providers/pi/runtime/buildPiPrompt.ts +62 -0
- package/src/providers/pi/runtime/buildPiUsageInfo.ts +69 -0
- package/src/providers/pi/settings.ts +468 -0
- package/src/providers/pi/types.ts +64 -0
- package/src/providers/pi/ui/ObsidianPiExtensionUiRenderer.ts +251 -0
- package/src/providers/pi/ui/PiChatUIConfig.ts +265 -0
- package/src/providers/pi/ui/PiExtensionUiRenderer.ts +12 -0
- package/src/providers/pi/ui/PiSettingsTab.ts +642 -0
- package/src/shared/components/ResumeSessionDropdown.ts +185 -0
- package/src/shared/components/SelectableDropdown.ts +140 -0
- package/src/shared/components/SelectionHighlight.ts +77 -0
- package/src/shared/components/SlashCommandDropdown.ts +421 -0
- package/src/shared/icons.ts +180 -0
- package/src/shared/mention/MentionDropdownController.ts +627 -0
- package/src/shared/mention/VaultMentionCache.ts +106 -0
- package/src/shared/mention/VaultMentionDataProvider.ts +51 -0
- package/src/shared/mention/types.ts +67 -0
- package/src/shared/modals/ConfirmModal.ts +60 -0
- package/src/shared/modals/ForkTargetModal.ts +47 -0
- package/src/shared/modals/InstructionConfirmModal.ts +281 -0
- package/src/style/CLAUDE.md +49 -0
- package/src/style/accessibility.css +40 -0
- package/src/style/base/animations.css +44 -0
- package/src/style/base/container.css +20 -0
- package/src/style/base/variables.css +46 -0
- package/src/style/base/visibility.css +15 -0
- package/src/style/components/code.css +97 -0
- package/src/style/components/context-footer.css +76 -0
- package/src/style/components/header.css +27 -0
- package/src/style/components/history.css +221 -0
- package/src/style/components/input.css +312 -0
- package/src/style/components/messages.css +262 -0
- package/src/style/components/nav-sidebar.css +58 -0
- package/src/style/components/status-panel.css +202 -0
- package/src/style/components/subagent.css +248 -0
- package/src/style/components/tabs.css +112 -0
- package/src/style/components/thinking.css +88 -0
- package/src/style/components/toolcalls.css +278 -0
- package/src/style/features/ask-user-question.css +315 -0
- package/src/style/features/diff.css +197 -0
- package/src/style/features/file-context.css +188 -0
- package/src/style/features/file-link.css +22 -0
- package/src/style/features/image-context.css +179 -0
- package/src/style/features/image-embed.css +40 -0
- package/src/style/features/image-modal.css +52 -0
- package/src/style/features/inline-edit.css +278 -0
- package/src/style/features/plan-mode.css +103 -0
- package/src/style/features/resume-session.css +119 -0
- package/src/style/features/slash-commands.css +91 -0
- package/src/style/index.css +63 -0
- package/src/style/modals/fork-target.css +21 -0
- package/src/style/modals/instruction.css +161 -0
- package/src/style/modals/mcp-modal.css +241 -0
- package/src/style/settings/agent-settings.css +2 -0
- package/src/style/settings/base.css +300 -0
- package/src/style/settings/env-snippets.css +366 -0
- package/src/style/settings/mcp-settings.css +211 -0
- package/src/style/settings/plugin-settings.css +164 -0
- package/src/style/settings/provider-model-picker.css +367 -0
- package/src/style/settings/slash-settings.css +16 -0
- package/src/style/toolbar/external-context.css +177 -0
- package/src/style/toolbar/mcp-selector.css +176 -0
- package/src/style/toolbar/mode-selector.css +19 -0
- package/src/style/toolbar/model-selector.css +99 -0
- package/src/style/toolbar/permission-toggle.css +56 -0
- package/src/style/toolbar/service-tier-toggle.css +39 -0
- package/src/style/toolbar/thinking-selector.css +83 -0
- package/src/types/smol-toml.d.ts +4 -0
- package/src/utils/agent.ts +50 -0
- package/src/utils/animationFrame.ts +46 -0
- package/src/utils/browser.ts +46 -0
- package/src/utils/canvas.ts +14 -0
- package/src/utils/cliBinaryLocator.ts +97 -0
- package/src/utils/context.ts +117 -0
- package/src/utils/contextMentionResolver.ts +154 -0
- package/src/utils/date.ts +31 -0
- package/src/utils/diff.ts +384 -0
- package/src/utils/editor.ts +104 -0
- package/src/utils/electronCompat.ts +53 -0
- package/src/utils/env.ts +465 -0
- package/src/utils/externalContext.ts +143 -0
- package/src/utils/externalContextScanner.ts +135 -0
- package/src/utils/fileLink.ts +263 -0
- package/src/utils/frontmatter.ts +194 -0
- package/src/utils/imageEmbed.ts +139 -0
- package/src/utils/inlineEdit.ts +22 -0
- package/src/utils/interrupt.ts +23 -0
- package/src/utils/markdown.ts +25 -0
- package/src/utils/markdownMath.ts +130 -0
- package/src/utils/mcp.ts +96 -0
- package/src/utils/obsidianCompat.ts +23 -0
- package/src/utils/path.ts +342 -0
- package/src/utils/session.ts +240 -0
- package/src/utils/slashCommand.ts +152 -0
- package/src/utils/subagentJsonl.ts +52 -0
- package/src/utils/windowsCmdShim.ts +98 -0
- package/tests/__mocks__/claude-agent-sdk.ts +317 -0
- package/tests/__mocks__/codex-sdk.ts +88 -0
- package/tests/__mocks__/obsidian.ts +434 -0
- package/tests/helpers/mockElement.ts +403 -0
- package/tests/helpers/sdkMessages.ts +291 -0
- package/tests/integration/core/agent/ClaudianService.test.ts +1845 -0
- package/tests/integration/core/mcp/mcp.test.ts +905 -0
- package/tests/integration/features/chat/imagePersistence.test.ts +38 -0
- package/tests/integration/main.test.ts +1701 -0
- package/tests/setupWindow.ts +26 -0
- package/tests/tsconfig.json +7 -0
- package/tests/unit/core/commands/builtInCommands.test.ts +239 -0
- package/tests/unit/core/mcp/McpServerManager.test.ts +405 -0
- package/tests/unit/core/mcp/McpTester.test.ts +282 -0
- package/tests/unit/core/mcp/createNodeFetch.test.ts +188 -0
- package/tests/unit/core/providers/ProviderRegistry.test.ts +275 -0
- package/tests/unit/core/providers/ProviderSettingsCoordinator.test.ts +490 -0
- package/tests/unit/core/providers/ProviderWorkspaceRegistry.test.ts +84 -0
- package/tests/unit/core/providers/modelRouting.test.ts +91 -0
- package/tests/unit/core/providers/modelSelection.test.ts +155 -0
- package/tests/unit/core/providers/providerEnvironment.test.ts +162 -0
- package/tests/unit/core/providers/tabLifecycle.test.ts +217 -0
- package/tests/unit/core/security/ApprovalManager.test.ts +152 -0
- package/tests/unit/core/storage/VaultFileAdapter.test.ts +535 -0
- package/tests/unit/core/tools/todo.test.ts +227 -0
- package/tests/unit/core/tools/toolIcons.test.ts +75 -0
- package/tests/unit/core/tools/toolInput.test.ts +350 -0
- package/tests/unit/core/tools/toolNames.test.ts +464 -0
- package/tests/unit/core/types/mcp.test.ts +115 -0
- package/tests/unit/features/chat/ClaudianView.test.ts +404 -0
- package/tests/unit/features/chat/controllers/BrowserSelectionController.test.ts +179 -0
- package/tests/unit/features/chat/controllers/CanvasSelectionController.test.ts +216 -0
- package/tests/unit/features/chat/controllers/ConversationController.test.ts +2764 -0
- package/tests/unit/features/chat/controllers/InputController.test.ts +3188 -0
- package/tests/unit/features/chat/controllers/NavigationController.test.ts +640 -0
- package/tests/unit/features/chat/controllers/SelectionController.test.ts +695 -0
- package/tests/unit/features/chat/controllers/StreamController.test.ts +2534 -0
- package/tests/unit/features/chat/controllers/contextRowVisibility.test.ts +46 -0
- package/tests/unit/features/chat/controllers/index.test.ts +16 -0
- package/tests/unit/features/chat/rendering/DiffRenderer.test.ts +355 -0
- package/tests/unit/features/chat/rendering/InlineAskUserQuestion.test.ts +1035 -0
- package/tests/unit/features/chat/rendering/InlineExitPlanMode.test.ts +191 -0
- package/tests/unit/features/chat/rendering/InlinePlanApproval.test.ts +126 -0
- package/tests/unit/features/chat/rendering/MessageRenderer.test.ts +2004 -0
- package/tests/unit/features/chat/rendering/SubagentRenderer.test.ts +917 -0
- package/tests/unit/features/chat/rendering/ThinkingBlockRenderer.test.ts +124 -0
- package/tests/unit/features/chat/rendering/TodoListRenderer.test.ts +173 -0
- package/tests/unit/features/chat/rendering/ToolCallRenderer.test.ts +909 -0
- package/tests/unit/features/chat/rendering/WriteEditRenderer.test.ts +474 -0
- package/tests/unit/features/chat/rendering/collapsible.test.ts +158 -0
- package/tests/unit/features/chat/rendering/todoUtils.test.ts +105 -0
- package/tests/unit/features/chat/rewind.test.ts +56 -0
- package/tests/unit/features/chat/services/BangBashService.test.ts +142 -0
- package/tests/unit/features/chat/services/InstructionRefineService.test.ts +371 -0
- package/tests/unit/features/chat/services/SubagentManager.test.ts +1759 -0
- package/tests/unit/features/chat/services/TitleGenerationService.test.ts +480 -0
- package/tests/unit/features/chat/state/ChatState.test.ts +581 -0
- package/tests/unit/features/chat/tabs/Tab.test.ts +4287 -0
- package/tests/unit/features/chat/tabs/TabBar.test.ts +357 -0
- package/tests/unit/features/chat/tabs/TabManager.test.ts +2962 -0
- package/tests/unit/features/chat/tabs/index.test.ts +11 -0
- package/tests/unit/features/chat/ui/BangBashModeManager.test.ts +321 -0
- package/tests/unit/features/chat/ui/ExternalContextSelector.test.ts +555 -0
- package/tests/unit/features/chat/ui/FileContextManager.test.ts +876 -0
- package/tests/unit/features/chat/ui/ImageContext.test.ts +777 -0
- package/tests/unit/features/chat/ui/InputToolbar.test.ts +1139 -0
- package/tests/unit/features/chat/ui/InstructionModeManager.test.ts +243 -0
- package/tests/unit/features/chat/ui/NavigationSidebar.test.ts +570 -0
- package/tests/unit/features/chat/ui/StatusPanel.test.ts +953 -0
- package/tests/unit/features/chat/ui/file-context/state/FileContextState.test.ts +155 -0
- package/tests/unit/features/chat/ui/textareaResize.test.ts +102 -0
- package/tests/unit/features/chat/utils/usageInfo.test.ts +56 -0
- package/tests/unit/features/inline-edit/InlineEditService.test.ts +1199 -0
- package/tests/unit/features/inline-edit/ui/InlineEditModal.openAndWait.test.ts +1482 -0
- package/tests/unit/features/inline-edit/ui/InlineEditModal.test.ts +495 -0
- package/tests/unit/features/inline-edit/ui/inlineEditMarkdownPreview.test.ts +92 -0
- package/tests/unit/features/settings/AgentSettings.test.ts +82 -0
- package/tests/unit/features/settings/keyboardNavigation.test.ts +73 -0
- package/tests/unit/features/settings/ui/CodexSkillSettings.test.ts +294 -0
- package/tests/unit/features/settings/ui/CodexSubagentSettings.test.ts +207 -0
- package/tests/unit/i18n/constants.test.ts +43 -0
- package/tests/unit/i18n/i18n.test.ts +244 -0
- package/tests/unit/i18n/locales.test.ts +134 -0
- package/tests/unit/providers/acp/AcpClientConnection.test.ts +248 -0
- package/tests/unit/providers/acp/AcpJsonRpcTransport.test.ts +186 -0
- package/tests/unit/providers/acp/AcpSessionConfig.test.ts +247 -0
- package/tests/unit/providers/acp/AcpSessionUpdateNormalizer.test.ts +145 -0
- package/tests/unit/providers/acp/AcpSubprocess.test.ts +105 -0
- package/tests/unit/providers/acp/buildAcpUsageInfo.test.ts +51 -0
- package/tests/unit/providers/claude/agents/AgentManager.test.ts +590 -0
- package/tests/unit/providers/claude/agents/AgentStorage.test.ts +434 -0
- package/tests/unit/providers/claude/agents/index.test.ts +10 -0
- package/tests/unit/providers/claude/commands/ClaudeCommandCatalog.test.ts +396 -0
- package/tests/unit/providers/claude/commands/probeRuntimeCommands.test.ts +92 -0
- package/tests/unit/providers/claude/env/ClaudeSettingsReconciler.test.ts +57 -0
- package/tests/unit/providers/claude/env/claudeModelEnv.test.ts +228 -0
- package/tests/unit/providers/claude/hooks/SubagentHooks.test.ts +83 -0
- package/tests/unit/providers/claude/plugins/PluginManager.test.ts +832 -0
- package/tests/unit/providers/claude/plugins/index.test.ts +7 -0
- package/tests/unit/providers/claude/prompt/ClaudeTurnEncoder.test.ts +145 -0
- package/tests/unit/providers/claude/prompt/instructionRefine.test.ts +185 -0
- package/tests/unit/providers/claude/prompt/systemPrompt.test.ts +163 -0
- package/tests/unit/providers/claude/prompt/titleGeneration.test.ts +20 -0
- package/tests/unit/providers/claude/runtime/ClaudeTaskResultInterpreter.test.ts +28 -0
- package/tests/unit/providers/claude/runtime/ClaudianService.test.ts +3796 -0
- package/tests/unit/providers/claude/runtime/MessageChannel.test.ts +421 -0
- package/tests/unit/providers/claude/runtime/QueryOptionsBuilder.test.ts +775 -0
- package/tests/unit/providers/claude/runtime/SessionManager.test.ts +182 -0
- package/tests/unit/providers/claude/runtime/claudeColdStartQuery.test.ts +331 -0
- package/tests/unit/providers/claude/runtime/customSpawn.test.ts +374 -0
- package/tests/unit/providers/claude/runtime/index.test.ts +13 -0
- package/tests/unit/providers/claude/runtime/types.test.ts +190 -0
- package/tests/unit/providers/claude/sdk/typeGuards.test.ts +50 -0
- package/tests/unit/providers/claude/security/ClaudePermissionUpdates.test.ts +198 -0
- package/tests/unit/providers/claude/storage/AgentVaultStorage.test.ts +413 -0
- package/tests/unit/providers/claude/storage/CCSettingsStorage.test.ts +408 -0
- package/tests/unit/providers/claude/storage/ClaudianSettingsStorage.test.ts +653 -0
- package/tests/unit/providers/claude/storage/McpStorage.test.ts +619 -0
- package/tests/unit/providers/claude/storage/SessionStorage.test.ts +680 -0
- package/tests/unit/providers/claude/storage/SkillStorage.test.ts +275 -0
- package/tests/unit/providers/claude/storage/SlashCommandStorage.test.ts +612 -0
- package/tests/unit/providers/claude/storage/storage.test.ts +360 -0
- package/tests/unit/providers/claude/storage/storageService.convenience.test.ts +447 -0
- package/tests/unit/providers/claude/stream/transformSDKMessage.test.ts +1729 -0
- package/tests/unit/providers/claude/types/types.test.ts +726 -0
- package/tests/unit/providers/claude/ui/ClaudeChatUIConfig.test.ts +173 -0
- package/tests/unit/providers/claude/ui/ClaudeSettingsTab.test.ts +466 -0
- package/tests/unit/providers/codex/agents/CodexAgentMentionProvider.test.ts +89 -0
- package/tests/unit/providers/codex/auxiliary/CodexInstructionRefineService.test.ts +81 -0
- package/tests/unit/providers/codex/capabilities.test.ts +39 -0
- package/tests/unit/providers/codex/commands/CodexSkillCatalog.test.ts +413 -0
- package/tests/unit/providers/codex/env/CodexSettingsReconciler.test.ts +106 -0
- package/tests/unit/providers/codex/fixtures/codex-session-abort.jsonl +9 -0
- package/tests/unit/providers/codex/fixtures/codex-session-agent-lifecycle.jsonl +12 -0
- package/tests/unit/providers/codex/fixtures/codex-session-persisted-tools.jsonl +15 -0
- package/tests/unit/providers/codex/fixtures/codex-session-simple.jsonl +10 -0
- package/tests/unit/providers/codex/fixtures/codex-session-tools.jsonl +12 -0
- package/tests/unit/providers/codex/fixtures/codex-session-websearch-persisted.jsonl +3 -0
- package/tests/unit/providers/codex/fixtures/codex-session-websearch.jsonl +7 -0
- package/tests/unit/providers/codex/history/CodexConversationHistoryService.test.ts +690 -0
- package/tests/unit/providers/codex/history/CodexHistoryStore.test.ts +2202 -0
- package/tests/unit/providers/codex/normalization/codexSubagentNormalization.test.ts +81 -0
- package/tests/unit/providers/codex/normalization/codexToolNormalization.test.ts +322 -0
- package/tests/unit/providers/codex/prompt/encodeCodexTurn.test.ts +168 -0
- package/tests/unit/providers/codex/runtime/CodexAppServerProcess.test.ts +255 -0
- package/tests/unit/providers/codex/runtime/CodexAuxQueryRunner.test.ts +130 -0
- package/tests/unit/providers/codex/runtime/CodexBinaryLocator.test.ts +90 -0
- package/tests/unit/providers/codex/runtime/CodexChatRuntime.test.ts +2445 -0
- package/tests/unit/providers/codex/runtime/CodexCliResolver.test.ts +103 -0
- package/tests/unit/providers/codex/runtime/CodexExecutionTargetResolver.test.ts +105 -0
- package/tests/unit/providers/codex/runtime/CodexLaunchSpecBuilder.test.ts +150 -0
- package/tests/unit/providers/codex/runtime/CodexNotificationRouter.test.ts +1248 -0
- package/tests/unit/providers/codex/runtime/CodexPathMapper.test.ts +51 -0
- package/tests/unit/providers/codex/runtime/CodexRpcTransport.test.ts +220 -0
- package/tests/unit/providers/codex/runtime/CodexRuntimeContext.test.ts +107 -0
- package/tests/unit/providers/codex/runtime/CodexServerRequestRouter.test.ts +537 -0
- package/tests/unit/providers/codex/runtime/CodexSessionFileTail.test.ts +1305 -0
- package/tests/unit/providers/codex/runtime/CodexSessionManager.test.ts +82 -0
- package/tests/unit/providers/codex/runtime/codexAppServerTypes.test.ts +336 -0
- package/tests/unit/providers/codex/settings.test.ts +189 -0
- package/tests/unit/providers/codex/skills/CodexSkillListingService.test.ts +178 -0
- package/tests/unit/providers/codex/storage/CodexSkillStorage.test.ts +342 -0
- package/tests/unit/providers/codex/storage/CodexSubagentStorage.test.ts +376 -0
- package/tests/unit/providers/codex/ui/CodexChatUIConfig.test.ts +211 -0
- package/tests/unit/providers/codex/ui/CodexSettingsTab.test.ts +578 -0
- package/tests/unit/providers/defaultProviderConfigs.test.ts +18 -0
- package/tests/unit/providers/opencode/OpencodeAuxQueryRunner.test.ts +355 -0
- package/tests/unit/providers/opencode/OpencodeChatRuntime.test.ts +808 -0
- package/tests/unit/providers/opencode/OpencodeCliResolver.test.ts +93 -0
- package/tests/unit/providers/opencode/OpencodeCommandCatalog.test.ts +75 -0
- package/tests/unit/providers/opencode/OpencodeConversationHistoryService.test.ts +103 -0
- package/tests/unit/providers/opencode/OpencodeHistoryStore.test.ts +418 -0
- package/tests/unit/providers/opencode/OpencodeLaunchArtifacts.test.ts +268 -0
- package/tests/unit/providers/opencode/OpencodePaths.test.ts +35 -0
- package/tests/unit/providers/opencode/OpencodeRuntimeCommandLoader.test.ts +129 -0
- package/tests/unit/providers/opencode/OpencodeSettingsReconciler.test.ts +96 -0
- package/tests/unit/providers/opencode/OpencodeSettingsTab.test.ts +649 -0
- package/tests/unit/providers/opencode/OpencodeSqliteReader.test.ts +185 -0
- package/tests/unit/providers/opencode/agents/OpencodeAgentMentionProvider.test.ts +56 -0
- package/tests/unit/providers/opencode/buildOpencodePrompt.test.ts +87 -0
- package/tests/unit/providers/opencode/capabilities.test.ts +39 -0
- package/tests/unit/providers/opencode/models.test.ts +273 -0
- package/tests/unit/providers/opencode/modes.test.ts +151 -0
- package/tests/unit/providers/opencode/opencodeToolNormalization.test.ts +197 -0
- package/tests/unit/providers/opencode/settings.test.ts +469 -0
- package/tests/unit/providers/opencode/storage/OpencodeAgentStorage.test.ts +377 -0
- package/tests/unit/providers/opencode/ui/OpencodeAgentSettings.test.ts +91 -0
- package/tests/unit/providers/pi/PiRuntimeCommandLoader.test.ts +149 -0
- package/tests/unit/providers/pi/capabilities.test.ts +20 -0
- package/tests/unit/providers/pi/commands/PiCommandCatalog.test.ts +69 -0
- package/tests/unit/providers/pi/env/PiSettingsReconciler.test.ts +61 -0
- package/tests/unit/providers/pi/history/PiConversationHistoryService.test.ts +147 -0
- package/tests/unit/providers/pi/history/PiHistoryStore.test.ts +523 -0
- package/tests/unit/providers/pi/models.test.ts +96 -0
- package/tests/unit/providers/pi/registration.test.ts +54 -0
- package/tests/unit/providers/pi/runtime/PiAuxQueryRunner.test.ts +172 -0
- package/tests/unit/providers/pi/runtime/PiChatRuntime.test.ts +830 -0
- package/tests/unit/providers/pi/runtime/PiCliResolver.test.ts +105 -0
- package/tests/unit/providers/pi/runtime/PiEventNormalization.test.ts +147 -0
- package/tests/unit/providers/pi/runtime/PiExtensionUiBridge.test.ts +98 -0
- package/tests/unit/providers/pi/runtime/PiJsonl.test.ts +42 -0
- package/tests/unit/providers/pi/runtime/PiLaunchSpec.test.ts +92 -0
- package/tests/unit/providers/pi/runtime/PiModelDiscoveryService.test.ts +135 -0
- package/tests/unit/providers/pi/runtime/PiRpcPayloads.test.ts +15 -0
- package/tests/unit/providers/pi/runtime/PiRpcTransport.test.ts +116 -0
- package/tests/unit/providers/pi/runtime/PiSubprocess.test.ts +151 -0
- package/tests/unit/providers/pi/runtime/buildPiPrompt.test.ts +84 -0
- package/tests/unit/providers/pi/runtime/buildPiUsageInfo.test.ts +69 -0
- package/tests/unit/providers/pi/settings.test.ts +253 -0
- package/tests/unit/providers/pi/ui/PiChatUIConfig.test.ts +161 -0
- package/tests/unit/providers/pi/ui/PiSettingsTab.test.ts +492 -0
- package/tests/unit/scripts/rendererSafeUnref.test.ts +101 -0
- package/tests/unit/shared/components/ResumeSessionDropdown.test.ts +356 -0
- package/tests/unit/shared/components/SelectableDropdown.test.ts +406 -0
- package/tests/unit/shared/components/SlashCommandDropdown.provider.test.ts +354 -0
- package/tests/unit/shared/components/SlashCommandDropdown.test.ts +508 -0
- package/tests/unit/shared/icons.test.ts +56 -0
- package/tests/unit/shared/index.test.ts +46 -0
- package/tests/unit/shared/mention/MentionDropdownController.test.ts +823 -0
- package/tests/unit/shared/mention/VaultFileCache.test.ts +195 -0
- package/tests/unit/shared/mention/VaultFolderCache.test.ts +143 -0
- package/tests/unit/shared/mention/VaultMentionDataProvider.test.ts +87 -0
- package/tests/unit/shared/modals/ConfirmModal.test.ts +111 -0
- package/tests/unit/shared/modals/ForkTargetModal.test.ts +101 -0
- package/tests/unit/shared/modals/InstructionConfirmModal.test.ts +305 -0
- package/tests/unit/utils/agent.test.ts +395 -0
- package/tests/unit/utils/animationFrame.test.ts +59 -0
- package/tests/unit/utils/browser.test.ts +73 -0
- package/tests/unit/utils/canvas.test.ts +54 -0
- package/tests/unit/utils/claudeCli.test.ts +294 -0
- package/tests/unit/utils/cliBinaryLocator.test.ts +33 -0
- package/tests/unit/utils/context.test.ts +288 -0
- package/tests/unit/utils/contextMentionResolver.test.ts +270 -0
- package/tests/unit/utils/date.test.ts +80 -0
- package/tests/unit/utils/diff.test.ts +291 -0
- package/tests/unit/utils/editor.test.ts +249 -0
- package/tests/unit/utils/electronCompat.test.ts +87 -0
- package/tests/unit/utils/env.test.ts +1240 -0
- package/tests/unit/utils/externalContext.test.ts +336 -0
- package/tests/unit/utils/externalContextScanner.test.ts +186 -0
- package/tests/unit/utils/fileLink.dom.test.ts +273 -0
- package/tests/unit/utils/fileLink.handler.test.ts +64 -0
- package/tests/unit/utils/fileLink.test.ts +233 -0
- package/tests/unit/utils/frontmatter.test.ts +434 -0
- package/tests/unit/utils/imageEmbed.test.ts +407 -0
- package/tests/unit/utils/inlineEdit.test.ts +63 -0
- package/tests/unit/utils/interrupt.test.ts +73 -0
- package/tests/unit/utils/markdown.test.ts +35 -0
- package/tests/unit/utils/markdownMath.test.ts +54 -0
- package/tests/unit/utils/mcp.test.ts +256 -0
- package/tests/unit/utils/obsidianCompat.test.ts +18 -0
- package/tests/unit/utils/path.test.ts +677 -0
- package/tests/unit/utils/sdkSession.test.ts +2359 -0
- package/tests/unit/utils/session.test.ts +971 -0
- package/tests/unit/utils/slashCommand.test.ts +778 -0
- package/tests/unit/utils/utils.test.ts +809 -0
- package/tsconfig.jest.json +8 -0
- package/tsconfig.json +26 -0
- package/versions.json +4 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export function buildRefineSystemPrompt(existingInstructions: string): string {
|
|
2
|
+
const existingSection = existingInstructions.trim()
|
|
3
|
+
? `\n\nEXISTING INSTRUCTIONS (already in the user's system prompt):
|
|
4
|
+
\`\`\`
|
|
5
|
+
${existingInstructions.trim()}
|
|
6
|
+
\`\`\`
|
|
7
|
+
|
|
8
|
+
When refining the new instruction:
|
|
9
|
+
- Consider how it fits with existing instructions
|
|
10
|
+
- Avoid duplicating existing instructions
|
|
11
|
+
- If the new instruction conflicts with an existing one, refine it to be complementary or note the conflict
|
|
12
|
+
- Match the format of existing instructions (section, heading, bullet points, style, etc.)`
|
|
13
|
+
: '';
|
|
14
|
+
|
|
15
|
+
return `You are an expert Prompt Engineer. You help users craft precise, effective system instructions for their AI assistant.
|
|
16
|
+
|
|
17
|
+
**Your Goal**: Transform vague or simple user requests into **high-quality, actionable, and non-conflicting** system prompt instructions.
|
|
18
|
+
|
|
19
|
+
**Process**:
|
|
20
|
+
1. **Analyze Intent**: What behavior does the user want to enforce or change?
|
|
21
|
+
2. **Check Context**: Does this conflict with existing instructions?
|
|
22
|
+
- *No Conflict*: Add as new.
|
|
23
|
+
- *Conflict*: Propose a **merged instruction** that resolves the contradiction (or ask if unsure).
|
|
24
|
+
3. **Refine**: Draft a clear, positive instruction (e.g., "Do X" instead of "Don't do Y").
|
|
25
|
+
4. **Format**: Return *only* the Markdown snippet wrapped in \`<instruction>\` tags.
|
|
26
|
+
|
|
27
|
+
**Guidelines**:
|
|
28
|
+
- **Clarity**: Use precise language. Avoid ambiguity.
|
|
29
|
+
- **Scope**: Keep it focused. Don't add unrelated rules.
|
|
30
|
+
- **Format**: Valid Markdown (bullets \`-\` or sections \`##\`).
|
|
31
|
+
- **No Header**: Do NOT include a top-level header like \`# Custom Instructions\`.
|
|
32
|
+
- **Conflict Handling**: If the new rule directly contradicts an existing one, rewrite the *new* one to override specific cases or ask for clarification.
|
|
33
|
+
|
|
34
|
+
**Output Format**:
|
|
35
|
+
- **Success**: \`<instruction>...markdown content...</instruction>\`
|
|
36
|
+
- **Ambiguity**: Plain text question.
|
|
37
|
+
|
|
38
|
+
${existingSection}
|
|
39
|
+
|
|
40
|
+
**Examples**:
|
|
41
|
+
|
|
42
|
+
Input: "typescript for code"
|
|
43
|
+
Output: <instruction>- **Code Language**: Always use TypeScript for code examples. Include proper type annotations and interfaces.</instruction>
|
|
44
|
+
|
|
45
|
+
Input: "be concise"
|
|
46
|
+
Output: <instruction>- **Conciseness**: Provide brief, direct responses. Omit conversational filler and unnecessary explanations.</instruction>
|
|
47
|
+
|
|
48
|
+
Input: "organize coding style rules"
|
|
49
|
+
Output: <instruction>## Coding Standards\n\n- **Language**: Use TypeScript.\n- **Style**: Prefer functional patterns.\n- **Review**: Keep diffs small.</instruction>
|
|
50
|
+
|
|
51
|
+
Input: "use that thing from before"
|
|
52
|
+
Output: I'm not sure what you're referring to. Could you please clarify?`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function parseInstructionRefineResponse(responseText: string): {
|
|
56
|
+
success: boolean;
|
|
57
|
+
clarification?: string;
|
|
58
|
+
refinedInstruction?: string;
|
|
59
|
+
error?: string;
|
|
60
|
+
} {
|
|
61
|
+
const instructionMatch = responseText.match(/<instruction>([\s\S]*?)<\/instruction>/);
|
|
62
|
+
if (instructionMatch) {
|
|
63
|
+
return { success: true, refinedInstruction: instructionMatch[1].trim() };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const trimmed = responseText.trim();
|
|
67
|
+
if (trimmed) {
|
|
68
|
+
return { success: true, clarification: trimmed };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { success: false, error: 'Empty response' };
|
|
72
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
export interface SystemPromptSettings {
|
|
2
|
+
mediaFolder?: string;
|
|
3
|
+
customPrompt?: string;
|
|
4
|
+
vaultPath?: string;
|
|
5
|
+
userName?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface SystemPromptBuildOptions {
|
|
9
|
+
appendices?: string[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function getPathRules(vaultPath?: string): string {
|
|
13
|
+
return `## Path Conventions
|
|
14
|
+
|
|
15
|
+
| Location | Access | Path Format | Example |
|
|
16
|
+
|----------|--------|-------------|---------|
|
|
17
|
+
| **Vault** | Read/Write | Relative from vault root | \`notes/my-note.md\`, \`.\` |
|
|
18
|
+
| **External contexts** | Full access | Absolute path | \`/Users/me/Workspace/file.ts\` |
|
|
19
|
+
|
|
20
|
+
**Vault files** (default working directory):
|
|
21
|
+
- ✓ Correct: \`notes/my-note.md\`, \`my-note.md\`, \`folder/subfolder/file.md\`, \`.\`
|
|
22
|
+
- ✗ WRONG: \`/notes/my-note.md\`, \`${vaultPath || '/absolute/path'}/file.md\`
|
|
23
|
+
- A leading slash or absolute path will FAIL for vault operations.
|
|
24
|
+
|
|
25
|
+
**External context paths**: When external directories are selected, use absolute paths to access files there. These directories are explicitly granted for the current session.`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getBaseSystemPrompt(
|
|
29
|
+
vaultPath?: string,
|
|
30
|
+
userName?: string,
|
|
31
|
+
): string {
|
|
32
|
+
const vaultInfo = vaultPath ? `\n\nVault absolute path: ${vaultPath}` : '';
|
|
33
|
+
const trimmedUserName = userName?.trim();
|
|
34
|
+
const userContext = trimmedUserName
|
|
35
|
+
? `## User Context\n\nYou are collaborating with **${trimmedUserName}**.\n\n`
|
|
36
|
+
: '';
|
|
37
|
+
const pathRules = getPathRules(vaultPath);
|
|
38
|
+
|
|
39
|
+
return `${userContext}## Time Context
|
|
40
|
+
|
|
41
|
+
- **Current Date**: Use \`bash: date\` to get the current date and time. Never guess or assume.
|
|
42
|
+
- **Knowledge Status**: You possess extensive internal knowledge up to your training cutoff. You do not know the exact date of your cutoff, but you must assume that your internal weights are static and "past," while the Current Date is "present."
|
|
43
|
+
|
|
44
|
+
## Identity & Role
|
|
45
|
+
|
|
46
|
+
You are **Claudian**, an expert AI assistant specialized in Obsidian vault management, knowledge organization, and code analysis. You operate directly inside the user's Obsidian vault.
|
|
47
|
+
|
|
48
|
+
**Core Principles:**
|
|
49
|
+
1. **Obsidian Native**: You understand Markdown, YAML frontmatter, Wiki-links, and the "second brain" philosophy.
|
|
50
|
+
2. **Safety First**: You never overwrite data without understanding context. You always use relative paths.
|
|
51
|
+
3. **Proactive Thinking**: You do not just execute; you *plan* and *verify*. You anticipate potential issues (like broken links or missing files).
|
|
52
|
+
4. **Clarity**: Your changes are precise, minimizing "noise" in the user's notes or code.
|
|
53
|
+
|
|
54
|
+
The current working directory is the user's vault root.${vaultInfo}
|
|
55
|
+
|
|
56
|
+
${pathRules}
|
|
57
|
+
|
|
58
|
+
## User Message Format
|
|
59
|
+
|
|
60
|
+
User messages have the query first, followed by optional XML context tags:
|
|
61
|
+
|
|
62
|
+
\`\`\`
|
|
63
|
+
User's question or request here
|
|
64
|
+
|
|
65
|
+
<current_note>
|
|
66
|
+
path/to/note.md
|
|
67
|
+
</current_note>
|
|
68
|
+
|
|
69
|
+
<editor_selection path="path/to/note.md" lines="10-15">
|
|
70
|
+
selected text content
|
|
71
|
+
</editor_selection>
|
|
72
|
+
|
|
73
|
+
<browser_selection source="browser:https://leetcode.com/problems/two-sum" title="LeetCode" url="https://leetcode.com/problems/two-sum">
|
|
74
|
+
selected content from an Obsidian browser view
|
|
75
|
+
</browser_selection>
|
|
76
|
+
\`\`\`
|
|
77
|
+
|
|
78
|
+
- The user's query/instruction always comes first in the message.
|
|
79
|
+
- \`<current_note>\`: The note the user is currently viewing/focused on. Read this to understand context.
|
|
80
|
+
- \`<editor_selection>\`: Text currently selected in the editor, with file path and line numbers.
|
|
81
|
+
- \`<browser_selection>\`: Text selected in an Obsidian browser/web view (for example Surfing), including optional source/title/url metadata.
|
|
82
|
+
- \`@filename.md\`: Files mentioned with @ in the query. Read these files when referenced.
|
|
83
|
+
|
|
84
|
+
## Obsidian Context
|
|
85
|
+
|
|
86
|
+
- **Structure**: Files are Markdown (.md). Folders organize content.
|
|
87
|
+
- **Frontmatter**: YAML at the top of files (metadata). Respect existing fields.
|
|
88
|
+
- **Links**: Internal Wiki-links \`[[note-name]]\` or \`[[folder/note-name]]\`. External links \`[text](url)\`.
|
|
89
|
+
- When reading a note with wikilinks, consider reading linked notes; they often contain related context that helps understand the current note.
|
|
90
|
+
- **Tags**: #tag-name for categorization.
|
|
91
|
+
- **Dataview**: You may encounter Dataview queries (in \`\`\`dataview\`\`\` blocks). Do not break them unless asked.
|
|
92
|
+
- **Vault Config**: \`.obsidian/\` contains internal config. Touch only if you know what you are doing.
|
|
93
|
+
|
|
94
|
+
**File References in Responses:**
|
|
95
|
+
When mentioning vault files in your responses, use wikilink format so users can click to open them:
|
|
96
|
+
- ✓ Use: \`[[folder/note.md]]\` or \`[[note]]\`
|
|
97
|
+
- ✗ Avoid: plain paths like \`folder/note.md\` (not clickable)
|
|
98
|
+
|
|
99
|
+
**Image embeds:** Use \`![[image.png]]\` to display images directly in chat. Images render visually, making it easy to show diagrams, screenshots, or visual content you're discussing.
|
|
100
|
+
|
|
101
|
+
Examples:
|
|
102
|
+
- "I found your notes in [[30.areas/finance/Investment lessons/2024.Current trading lessons.md]]"
|
|
103
|
+
- "See [[daily notes/2024-01-15]] for more details"
|
|
104
|
+
- "Here's the diagram: ![[attachments/architecture.png]]"
|
|
105
|
+
|
|
106
|
+
## Selection Context
|
|
107
|
+
|
|
108
|
+
User messages may include an \`<editor_selection>\` tag showing text the user selected:
|
|
109
|
+
|
|
110
|
+
\`\`\`xml
|
|
111
|
+
<editor_selection path="path/to/file.md" lines="line numbers">
|
|
112
|
+
selected text here
|
|
113
|
+
possibly multiple lines
|
|
114
|
+
</editor_selection>
|
|
115
|
+
\`\`\`
|
|
116
|
+
|
|
117
|
+
User messages may also include a \`<browser_selection>\` tag when selection comes from an Obsidian browser view:
|
|
118
|
+
|
|
119
|
+
\`\`\`xml
|
|
120
|
+
<browser_selection source="browser:https://leetcode.com/problems/two-sum" title="LeetCode" url="https://leetcode.com/problems/two-sum">
|
|
121
|
+
selected webpage content
|
|
122
|
+
</browser_selection>
|
|
123
|
+
\`\`\`
|
|
124
|
+
|
|
125
|
+
**When present:** The user selected this text before sending their message. Use this context to understand what they're referring to.`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function getImageInstructions(mediaFolder: string): string {
|
|
129
|
+
const folder = mediaFolder.trim();
|
|
130
|
+
const mediaPath = folder ? `./${folder}` : '.';
|
|
131
|
+
const examplePath = folder ? `${folder}/` : '';
|
|
132
|
+
|
|
133
|
+
return `
|
|
134
|
+
|
|
135
|
+
## Embedded Images in Notes
|
|
136
|
+
|
|
137
|
+
**Proactive image reading**: When reading a note with embedded images, read them alongside text for full context. Images often contain critical information (diagrams, screenshots, charts).
|
|
138
|
+
|
|
139
|
+
**Local images** (\`![[image.jpg]]\`):
|
|
140
|
+
- Located in media folder: \`${mediaPath}\`
|
|
141
|
+
- Read with: \`Read file_path="${examplePath}image.jpg"\`
|
|
142
|
+
- Formats: PNG, JPG/JPEG, GIF, WebP
|
|
143
|
+
|
|
144
|
+
**External images** (\`\`):
|
|
145
|
+
- WebFetch does NOT support images
|
|
146
|
+
- Download to media folder -> Read -> Replace URL with wiki-link:
|
|
147
|
+
|
|
148
|
+
\`\`\`bash
|
|
149
|
+
# Download to media folder with descriptive name
|
|
150
|
+
mkdir -p ${mediaPath}
|
|
151
|
+
img_name="downloaded_\\$(date +%s).png"
|
|
152
|
+
curl -sfo "${examplePath}$img_name" 'URL'
|
|
153
|
+
\`\`\`
|
|
154
|
+
|
|
155
|
+
Then read with \`Read file_path="${examplePath}$img_name"\`, and replace the markdown link \`\` with \`![[${examplePath}$img_name]]\` in the note.
|
|
156
|
+
|
|
157
|
+
**Benefits**: Image becomes a permanent vault asset, works offline, and uses Obsidian's native embed syntax.`;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function getAppendixSections(appendices?: string[]): string {
|
|
161
|
+
if (!appendices || appendices.length === 0) {
|
|
162
|
+
return '';
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const sections = appendices
|
|
166
|
+
.map((appendix) => appendix.trim())
|
|
167
|
+
.filter(Boolean);
|
|
168
|
+
|
|
169
|
+
if (sections.length === 0) {
|
|
170
|
+
return '';
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return `\n\n${sections.join('\n\n')}`;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function buildSystemPrompt(
|
|
177
|
+
settings: SystemPromptSettings = {},
|
|
178
|
+
options: SystemPromptBuildOptions = {},
|
|
179
|
+
): string {
|
|
180
|
+
let prompt = getBaseSystemPrompt(settings.vaultPath, settings.userName);
|
|
181
|
+
|
|
182
|
+
prompt += getImageInstructions(settings.mediaFolder || '');
|
|
183
|
+
prompt += getAppendixSections(options.appendices);
|
|
184
|
+
|
|
185
|
+
if (settings.customPrompt?.trim()) {
|
|
186
|
+
prompt += `\n\n## Custom Instructions\n\n${settings.customPrompt.trim()}`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return prompt;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export function computeSystemPromptKey(
|
|
193
|
+
settings: SystemPromptSettings,
|
|
194
|
+
options: SystemPromptBuildOptions = {},
|
|
195
|
+
): string {
|
|
196
|
+
const appendixKey = (options.appendices || [])
|
|
197
|
+
.map((appendix) => appendix.trim())
|
|
198
|
+
.filter(Boolean)
|
|
199
|
+
.join('||');
|
|
200
|
+
|
|
201
|
+
const parts = [
|
|
202
|
+
settings.mediaFolder || '',
|
|
203
|
+
settings.customPrompt || '',
|
|
204
|
+
settings.vaultPath || '',
|
|
205
|
+
(settings.userName || '').trim(),
|
|
206
|
+
];
|
|
207
|
+
|
|
208
|
+
if (appendixKey) {
|
|
209
|
+
parts.push(appendixKey);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return parts.join('::');
|
|
213
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const MAX_TITLE_INPUT_LENGTH = 500;
|
|
2
|
+
const MAX_TITLE_LENGTH = 50;
|
|
3
|
+
|
|
4
|
+
export const TITLE_GENERATION_SYSTEM_PROMPT = `You are a specialist in summarizing user intent.
|
|
5
|
+
|
|
6
|
+
**Task**: Generate a **concise, descriptive title** (max 50 chars) summarizing the user's task/request.
|
|
7
|
+
|
|
8
|
+
**Rules**:
|
|
9
|
+
1. **Format**: Sentence case. No periods/quotes.
|
|
10
|
+
2. **Structure**: Start with a **strong verb** (e.g., Create, Fix, Debug, Explain, Analyze).
|
|
11
|
+
3. **Forbidden**: "Conversation with...", "Help me...", "Question about...", "I need...".
|
|
12
|
+
4. **Tech Context**: Detect and include the primary language/framework if code is present (e.g., "Debug Python script", "Refactor React hook").
|
|
13
|
+
|
|
14
|
+
**Output**: Return ONLY the raw title text.`;
|
|
15
|
+
|
|
16
|
+
export function buildTitleGenerationPrompt(userMessage: string): string {
|
|
17
|
+
const truncated = userMessage.length > MAX_TITLE_INPUT_LENGTH
|
|
18
|
+
? `${userMessage.slice(0, MAX_TITLE_INPUT_LENGTH)}...`
|
|
19
|
+
: userMessage;
|
|
20
|
+
return `User's request:\n"""\n${truncated}\n"""\n\nGenerate a title for this conversation:`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function parseTitleGenerationResponse(responseText: string): string | null {
|
|
24
|
+
const trimmed = responseText.trim();
|
|
25
|
+
if (!trimmed) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let title = trimmed;
|
|
30
|
+
if (
|
|
31
|
+
(title.startsWith('"') && title.endsWith('"'))
|
|
32
|
+
|| (title.startsWith("'") && title.endsWith("'"))
|
|
33
|
+
) {
|
|
34
|
+
title = title.slice(1, -1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
title = title.replace(/[.!?:;,]+$/, '');
|
|
38
|
+
|
|
39
|
+
if (title.length > MAX_TITLE_LENGTH) {
|
|
40
|
+
title = `${title.slice(0, MAX_TITLE_LENGTH - 3)}...`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return title || null;
|
|
44
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import type ClaudianPlugin from '../../main';
|
|
2
|
+
import type { ChatRuntime } from '../runtime/ChatRuntime';
|
|
3
|
+
import { decodeProviderModelSelectionId } from './modelSelection';
|
|
4
|
+
import {
|
|
5
|
+
type CreateChatRuntimeOptions,
|
|
6
|
+
DEFAULT_CHAT_PROVIDER_ID,
|
|
7
|
+
type InlineEditService,
|
|
8
|
+
type InstructionRefineService,
|
|
9
|
+
type ProviderCapabilities,
|
|
10
|
+
type ProviderChatUIConfig,
|
|
11
|
+
type ProviderConversationHistoryService,
|
|
12
|
+
type ProviderId,
|
|
13
|
+
type ProviderRegistration,
|
|
14
|
+
type ProviderSettingsReconciler,
|
|
15
|
+
type ProviderSubagentLifecycleAdapter,
|
|
16
|
+
type ProviderTaskResultInterpreter,
|
|
17
|
+
type TitleGenerationCallback,
|
|
18
|
+
type TitleGenerationService,
|
|
19
|
+
} from './types';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Registry for chat-facing provider services.
|
|
23
|
+
*
|
|
24
|
+
* Bootstrap concerns (default settings, shared storage, CLI resolution,
|
|
25
|
+
* workspace command/agent services) are composed explicitly in `main.ts`
|
|
26
|
+
* through `src/core/bootstrap/` and `src/providers/<id>/app/`.
|
|
27
|
+
*/
|
|
28
|
+
export class ProviderRegistry {
|
|
29
|
+
private static registrations: Partial<Record<ProviderId, ProviderRegistration>> = {};
|
|
30
|
+
|
|
31
|
+
static register(
|
|
32
|
+
providerId: ProviderId,
|
|
33
|
+
registration: ProviderRegistration,
|
|
34
|
+
): void {
|
|
35
|
+
this.registrations[providerId] = registration;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private static getProviderRegistration(providerId: ProviderId): ProviderRegistration {
|
|
39
|
+
const registration = this.registrations[providerId];
|
|
40
|
+
if (!registration) {
|
|
41
|
+
throw new Error(`Provider "${providerId}" is not registered.`);
|
|
42
|
+
}
|
|
43
|
+
return registration;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static createChatRuntime(options: CreateChatRuntimeOptions): ChatRuntime {
|
|
47
|
+
const providerId = options.providerId ?? DEFAULT_CHAT_PROVIDER_ID;
|
|
48
|
+
return this.getProviderRegistration(providerId).createRuntime(options);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static createTitleGenerationService(plugin: ClaudianPlugin, providerId?: ProviderId): TitleGenerationService {
|
|
52
|
+
if (!providerId) {
|
|
53
|
+
return new RoutedTitleGenerationService(plugin);
|
|
54
|
+
}
|
|
55
|
+
return this.getProviderRegistration(providerId).createTitleGenerationService(plugin);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static resolveTitleGenerationProviderId(settings: Record<string, unknown>): ProviderId {
|
|
59
|
+
const titleModel = typeof settings.titleGenerationModel === 'string'
|
|
60
|
+
? settings.titleGenerationModel.trim()
|
|
61
|
+
: '';
|
|
62
|
+
|
|
63
|
+
if (!titleModel) {
|
|
64
|
+
return DEFAULT_CHAT_PROVIDER_ID;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return this.resolveProviderForModel(titleModel, settings, {
|
|
68
|
+
fallbackProviderId: DEFAULT_CHAT_PROVIDER_ID,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static createInstructionRefineService(plugin: ClaudianPlugin, providerId: ProviderId = DEFAULT_CHAT_PROVIDER_ID): InstructionRefineService {
|
|
73
|
+
return this.getProviderRegistration(providerId).createInstructionRefineService(plugin);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static createInlineEditService(plugin: ClaudianPlugin, providerId: ProviderId = DEFAULT_CHAT_PROVIDER_ID): InlineEditService {
|
|
77
|
+
return this.getProviderRegistration(providerId).createInlineEditService(plugin);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static getConversationHistoryService(
|
|
81
|
+
providerId: ProviderId = DEFAULT_CHAT_PROVIDER_ID,
|
|
82
|
+
): ProviderConversationHistoryService {
|
|
83
|
+
return this.getProviderRegistration(providerId).historyService;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static getTaskResultInterpreter(
|
|
87
|
+
providerId: ProviderId = DEFAULT_CHAT_PROVIDER_ID,
|
|
88
|
+
): ProviderTaskResultInterpreter {
|
|
89
|
+
return this.getProviderRegistration(providerId).taskResultInterpreter;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
static getSubagentLifecycleAdapter(
|
|
93
|
+
providerId: ProviderId = DEFAULT_CHAT_PROVIDER_ID,
|
|
94
|
+
): ProviderSubagentLifecycleAdapter | null {
|
|
95
|
+
return this.getProviderRegistration(providerId).subagentLifecycleAdapter ?? null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static getCapabilities(providerId: ProviderId = DEFAULT_CHAT_PROVIDER_ID): ProviderCapabilities {
|
|
99
|
+
return this.getProviderRegistration(providerId).capabilities;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static getEnvironmentKeyPatterns(providerId: ProviderId): RegExp[] {
|
|
103
|
+
return this.getProviderRegistration(providerId).environmentKeyPatterns ?? [];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
static getChatUIConfig(providerId: ProviderId = DEFAULT_CHAT_PROVIDER_ID): ProviderChatUIConfig {
|
|
107
|
+
return this.getProviderRegistration(providerId).chatUIConfig;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
static getSettingsReconciler(providerId: ProviderId = DEFAULT_CHAT_PROVIDER_ID): ProviderSettingsReconciler {
|
|
111
|
+
return this.getProviderRegistration(providerId).settingsReconciler;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
static getRegisteredProviderIds(): ProviderId[] {
|
|
115
|
+
return Object.keys(this.registrations);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static getEnabledProviderIds(settings: Record<string, unknown>): ProviderId[] {
|
|
119
|
+
return this.getRegisteredProviderIds()
|
|
120
|
+
.filter(providerId => this.getProviderRegistration(providerId).isEnabled(settings))
|
|
121
|
+
.sort((a, b) => (
|
|
122
|
+
this.getProviderRegistration(a).blankTabOrder - this.getProviderRegistration(b).blankTabOrder
|
|
123
|
+
));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
static getProviderDisplayName(providerId: ProviderId): string {
|
|
127
|
+
return this.getProviderRegistration(providerId).displayName;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
static isEnabled(providerId: ProviderId, settings: Record<string, unknown>): boolean {
|
|
131
|
+
return this.getProviderRegistration(providerId).isEnabled(settings);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
static resolveSettingsProviderId(settings: Record<string, unknown>): ProviderId {
|
|
135
|
+
const current = settings.settingsProvider;
|
|
136
|
+
if (typeof current === 'string') {
|
|
137
|
+
const currentProvider = current;
|
|
138
|
+
if (
|
|
139
|
+
this.getRegisteredProviderIds().includes(currentProvider)
|
|
140
|
+
&& this.isEnabled(currentProvider, settings)
|
|
141
|
+
) {
|
|
142
|
+
return currentProvider;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (this.isEnabled(DEFAULT_CHAT_PROVIDER_ID, settings)) {
|
|
147
|
+
return DEFAULT_CHAT_PROVIDER_ID;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return this.getEnabledProviderIds(settings)[0] ?? DEFAULT_CHAT_PROVIDER_ID;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
static resolveProviderForModel(
|
|
154
|
+
model: string,
|
|
155
|
+
settings: Record<string, unknown> = {},
|
|
156
|
+
options: {
|
|
157
|
+
onlyEnabledProviders?: boolean;
|
|
158
|
+
fallbackProviderId?: ProviderId;
|
|
159
|
+
} = {},
|
|
160
|
+
): ProviderId {
|
|
161
|
+
const providerIds = options.onlyEnabledProviders
|
|
162
|
+
? this.getEnabledProviderIds(settings)
|
|
163
|
+
: this.getRegisteredProviderIds();
|
|
164
|
+
const fallbackProviderId = (
|
|
165
|
+
options.fallbackProviderId
|
|
166
|
+
&& (!options.onlyEnabledProviders || this.isEnabled(options.fallbackProviderId, settings))
|
|
167
|
+
)
|
|
168
|
+
? options.fallbackProviderId
|
|
169
|
+
: (options.onlyEnabledProviders
|
|
170
|
+
? this.resolveSettingsProviderId(settings)
|
|
171
|
+
: DEFAULT_CHAT_PROVIDER_ID);
|
|
172
|
+
const decodedSelection = decodeProviderModelSelectionId(model);
|
|
173
|
+
|
|
174
|
+
if (
|
|
175
|
+
decodedSelection
|
|
176
|
+
&& providerIds.includes(decodedSelection.providerId)
|
|
177
|
+
&& (!options.onlyEnabledProviders || this.isEnabled(decodedSelection.providerId, settings))
|
|
178
|
+
) {
|
|
179
|
+
return decodedSelection.providerId;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
for (const providerId of providerIds) {
|
|
183
|
+
if (providerId === fallbackProviderId) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (this.getChatUIConfig(providerId).ownsModel(model, settings)) {
|
|
188
|
+
return providerId;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return fallbackProviderId;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
static getCustomModelIds(envVars: Record<string, string>): Set<string> {
|
|
196
|
+
const ids = new Set<string>();
|
|
197
|
+
for (const providerId of this.getRegisteredProviderIds()) {
|
|
198
|
+
for (const modelId of this.getChatUIConfig(providerId).getCustomModelIds(envVars)) {
|
|
199
|
+
ids.add(modelId);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return ids;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
interface ActiveTitleGeneration {
|
|
207
|
+
service: TitleGenerationService;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
class RoutedTitleGenerationService implements TitleGenerationService {
|
|
211
|
+
private readonly activeGenerations = new Map<string, ActiveTitleGeneration>();
|
|
212
|
+
|
|
213
|
+
constructor(private readonly plugin: ClaudianPlugin) {}
|
|
214
|
+
|
|
215
|
+
async generateTitle(
|
|
216
|
+
conversationId: string,
|
|
217
|
+
userMessage: string,
|
|
218
|
+
callback: TitleGenerationCallback,
|
|
219
|
+
): Promise<void> {
|
|
220
|
+
const providerId = ProviderRegistry.resolveTitleGenerationProviderId(
|
|
221
|
+
this.plugin.settings as unknown as Record<string, unknown>,
|
|
222
|
+
);
|
|
223
|
+
const service = ProviderRegistry.createTitleGenerationService(this.plugin, providerId);
|
|
224
|
+
const generation = { service };
|
|
225
|
+
const previous = this.activeGenerations.get(conversationId);
|
|
226
|
+
|
|
227
|
+
this.activeGenerations.set(conversationId, generation);
|
|
228
|
+
previous?.service.cancel();
|
|
229
|
+
|
|
230
|
+
try {
|
|
231
|
+
await service.generateTitle(conversationId, userMessage, async (convId, result) => {
|
|
232
|
+
if (this.activeGenerations.get(conversationId) !== generation) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
await callback(convId, result);
|
|
236
|
+
});
|
|
237
|
+
} finally {
|
|
238
|
+
if (this.activeGenerations.get(conversationId) === generation) {
|
|
239
|
+
this.activeGenerations.delete(conversationId);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
cancel(): void {
|
|
245
|
+
const services = new Set<TitleGenerationService>(
|
|
246
|
+
[...this.activeGenerations.values()].map(generation => generation.service),
|
|
247
|
+
);
|
|
248
|
+
this.activeGenerations.clear();
|
|
249
|
+
for (const service of services) {
|
|
250
|
+
service.cancel();
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|