@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.
Files changed (687) hide show
  1. package/.env.local.example +2 -0
  2. package/.github/workflows/ci.yml +59 -0
  3. package/.github/workflows/claude-code-review.yml +57 -0
  4. package/.github/workflows/claude.yml +50 -0
  5. package/.github/workflows/duplicate-issues.yml +22 -0
  6. package/.github/workflows/release.yml +73 -0
  7. package/.github/workflows/stale.yml +21 -0
  8. package/.node-version +1 -0
  9. package/AGENTS.md +3 -0
  10. package/CLAUDE.md +80 -0
  11. package/LICENSE +21 -0
  12. package/README.md +190 -0
  13. package/assets/Preview.png +0 -0
  14. package/assets/sponsors/MOMA.png +0 -0
  15. package/bun.lock +1618 -0
  16. package/esbuild.config.mjs +195 -0
  17. package/eslint.config.mjs +143 -0
  18. package/jest.config.js +41 -0
  19. package/main.js +104915 -0
  20. package/manifest.json +10 -0
  21. package/package.json +65 -0
  22. package/scripts/build-css.mjs +119 -0
  23. package/scripts/build.mjs +19 -0
  24. package/scripts/postinstall.mjs +25 -0
  25. package/scripts/rendererSafeUnref.js +205 -0
  26. package/scripts/run-jest.js +19 -0
  27. package/scripts/sync-version.js +16 -0
  28. package/src/app/settings/ClaudianSettingsStorage.ts +435 -0
  29. package/src/app/settings/defaultSettings.ts +54 -0
  30. package/src/app/storage/SharedStorageService.ts +106 -0
  31. package/src/core/CLAUDE.md +84 -0
  32. package/src/core/auxiliary/AuxQueryRunner.ts +11 -0
  33. package/src/core/auxiliary/QueryBackedInlineEditService.ts +73 -0
  34. package/src/core/auxiliary/QueryBackedInstructionRefineService.ts +78 -0
  35. package/src/core/auxiliary/QueryBackedTitleGenerationService.ts +90 -0
  36. package/src/core/bootstrap/SessionStorage.ts +179 -0
  37. package/src/core/bootstrap/StoragePaths.ts +7 -0
  38. package/src/core/bootstrap/storage.ts +20 -0
  39. package/src/core/commands/builtInCommands.ts +141 -0
  40. package/src/core/mcp/McpConfigParser.ts +102 -0
  41. package/src/core/mcp/McpServerManager.ts +119 -0
  42. package/src/core/mcp/McpTester.ts +310 -0
  43. package/src/core/prompt/inlineEdit.ts +252 -0
  44. package/src/core/prompt/instructionRefine.ts +72 -0
  45. package/src/core/prompt/mainAgent.ts +213 -0
  46. package/src/core/prompt/titleGeneration.ts +44 -0
  47. package/src/core/providers/ProviderRegistry.ts +253 -0
  48. package/src/core/providers/ProviderSettingsCoordinator.ts +434 -0
  49. package/src/core/providers/ProviderWorkspaceRegistry.ts +119 -0
  50. package/src/core/providers/commands/ProviderCommandCatalog.ts +21 -0
  51. package/src/core/providers/commands/ProviderCommandEntry.ts +33 -0
  52. package/src/core/providers/commands/hiddenCommands.ts +74 -0
  53. package/src/core/providers/modelRouting.ts +17 -0
  54. package/src/core/providers/modelSelection.ts +72 -0
  55. package/src/core/providers/providerConfig.ts +34 -0
  56. package/src/core/providers/providerEnvironment.ts +364 -0
  57. package/src/core/providers/types.ts +544 -0
  58. package/src/core/runtime/ChatRuntime.ts +66 -0
  59. package/src/core/runtime/QueuedTurn.ts +97 -0
  60. package/src/core/runtime/types.ts +118 -0
  61. package/src/core/security/ApprovalManager.ts +142 -0
  62. package/src/core/storage/HomeFileAdapter.ts +75 -0
  63. package/src/core/storage/VaultFileAdapter.ts +132 -0
  64. package/src/core/tools/todo.ts +65 -0
  65. package/src/core/tools/toolIcons.ts +80 -0
  66. package/src/core/tools/toolInput.ts +119 -0
  67. package/src/core/tools/toolNames.ts +149 -0
  68. package/src/core/tools/toolResultContent.ts +26 -0
  69. package/src/core/types/agent.ts +28 -0
  70. package/src/core/types/chat.ts +177 -0
  71. package/src/core/types/diff.ts +31 -0
  72. package/src/core/types/index.ts +78 -0
  73. package/src/core/types/mcp.ts +97 -0
  74. package/src/core/types/plugins.ts +9 -0
  75. package/src/core/types/provider.ts +1 -0
  76. package/src/core/types/settings.ts +152 -0
  77. package/src/core/types/tools.ts +80 -0
  78. package/src/features/chat/CLAUDE.md +136 -0
  79. package/src/features/chat/ClaudianView.ts +762 -0
  80. package/src/features/chat/constants.ts +114 -0
  81. package/src/features/chat/controllers/BrowserSelectionController.ts +295 -0
  82. package/src/features/chat/controllers/CanvasSelectionController.ts +142 -0
  83. package/src/features/chat/controllers/ConversationController.ts +1103 -0
  84. package/src/features/chat/controllers/InputController.ts +1707 -0
  85. package/src/features/chat/controllers/NavigationController.ts +209 -0
  86. package/src/features/chat/controllers/SelectionController.ts +430 -0
  87. package/src/features/chat/controllers/StreamController.ts +1560 -0
  88. package/src/features/chat/controllers/contextRowVisibility.ts +18 -0
  89. package/src/features/chat/rendering/DiffRenderer.ts +134 -0
  90. package/src/features/chat/rendering/InlineAskUserQuestion.ts +702 -0
  91. package/src/features/chat/rendering/InlineExitPlanMode.ts +263 -0
  92. package/src/features/chat/rendering/InlinePlanApproval.ts +183 -0
  93. package/src/features/chat/rendering/MessageRenderer.ts +907 -0
  94. package/src/features/chat/rendering/SubagentRenderer.ts +678 -0
  95. package/src/features/chat/rendering/ThinkingBlockRenderer.ts +126 -0
  96. package/src/features/chat/rendering/TodoListRenderer.ts +5 -0
  97. package/src/features/chat/rendering/ToolCallRenderer.ts +1161 -0
  98. package/src/features/chat/rendering/WriteEditRenderer.ts +232 -0
  99. package/src/features/chat/rendering/collapsible.ts +101 -0
  100. package/src/features/chat/rendering/subagentLifecycleResolution.ts +25 -0
  101. package/src/features/chat/rendering/todoUtils.ts +29 -0
  102. package/src/features/chat/rewind.ts +31 -0
  103. package/src/features/chat/services/BangBashService.ts +56 -0
  104. package/src/features/chat/services/SubagentManager.ts +1107 -0
  105. package/src/features/chat/state/ChatState.ts +436 -0
  106. package/src/features/chat/state/types.ts +138 -0
  107. package/src/features/chat/tabs/Tab.ts +1886 -0
  108. package/src/features/chat/tabs/TabBar.ts +179 -0
  109. package/src/features/chat/tabs/TabManager.ts +1021 -0
  110. package/src/features/chat/tabs/providerResolution.ts +34 -0
  111. package/src/features/chat/tabs/types.ts +287 -0
  112. package/src/features/chat/ui/BangBashModeManager.ts +121 -0
  113. package/src/features/chat/ui/FileContext.ts +385 -0
  114. package/src/features/chat/ui/ImageContext.ts +366 -0
  115. package/src/features/chat/ui/InputToolbar.ts +1244 -0
  116. package/src/features/chat/ui/InstructionModeManager.ts +158 -0
  117. package/src/features/chat/ui/NavigationSidebar.ts +126 -0
  118. package/src/features/chat/ui/StatusPanel.ts +589 -0
  119. package/src/features/chat/ui/file-context/state/FileContextState.ts +83 -0
  120. package/src/features/chat/ui/file-context/view/FileChipsView.ts +70 -0
  121. package/src/features/chat/ui/textareaResize.ts +47 -0
  122. package/src/features/chat/utils/usageInfo.ts +26 -0
  123. package/src/features/inline-edit/ui/InlineEditModal.ts +895 -0
  124. package/src/features/inline-edit/ui/inlineEditMarkdownPreview.ts +55 -0
  125. package/src/features/settings/ClaudianSettings.ts +672 -0
  126. package/src/features/settings/keyboardNavigation.ts +60 -0
  127. package/src/features/settings/ui/EnvSnippetManager.ts +430 -0
  128. package/src/features/settings/ui/EnvironmentSettingsSection.ts +85 -0
  129. package/src/features/settings/ui/McpServerModal.ts +335 -0
  130. package/src/features/settings/ui/McpSettingsManager.ts +400 -0
  131. package/src/features/settings/ui/McpTestModal.ts +346 -0
  132. package/src/i18n/constants.ts +58 -0
  133. package/src/i18n/i18n.ts +140 -0
  134. package/src/i18n/locales/de.json +322 -0
  135. package/src/i18n/locales/en.json +322 -0
  136. package/src/i18n/locales/es.json +322 -0
  137. package/src/i18n/locales/fr.json +322 -0
  138. package/src/i18n/locales/ja.json +322 -0
  139. package/src/i18n/locales/ko.json +322 -0
  140. package/src/i18n/locales/pt.json +322 -0
  141. package/src/i18n/locales/ru.json +322 -0
  142. package/src/i18n/locales/zh-CN.json +322 -0
  143. package/src/i18n/locales/zh-TW.json +322 -0
  144. package/src/i18n/types.ts +248 -0
  145. package/src/main.ts +772 -0
  146. package/src/providers/acp/AcpClientConnection.ts +361 -0
  147. package/src/providers/acp/AcpJsonRpcTransport.ts +427 -0
  148. package/src/providers/acp/AcpSessionConfig.ts +139 -0
  149. package/src/providers/acp/AcpSessionUpdateNormalizer.ts +371 -0
  150. package/src/providers/acp/AcpSubprocess.ts +155 -0
  151. package/src/providers/acp/AcpToolStreamAdapter.ts +132 -0
  152. package/src/providers/acp/buildAcpUsageInfo.ts +41 -0
  153. package/src/providers/acp/index.ts +9 -0
  154. package/src/providers/acp/methodNames.ts +50 -0
  155. package/src/providers/acp/types.ts +566 -0
  156. package/src/providers/claude/CLAUDE.md +78 -0
  157. package/src/providers/claude/agents/AgentManager.ts +225 -0
  158. package/src/providers/claude/agents/AgentStorage.ts +101 -0
  159. package/src/providers/claude/app/ClaudeWorkspaceServices.ts +90 -0
  160. package/src/providers/claude/auxiliary/ClaudeInlineEditService.ts +122 -0
  161. package/src/providers/claude/auxiliary/ClaudeInstructionRefineService.ts +90 -0
  162. package/src/providers/claude/auxiliary/ClaudeTitleGenerationService.ts +129 -0
  163. package/src/providers/claude/auxiliary/extractAssistantText.ts +28 -0
  164. package/src/providers/claude/capabilities.ts +17 -0
  165. package/src/providers/claude/cli/findClaudeCLIPath.ts +261 -0
  166. package/src/providers/claude/commands/ClaudeCommandCatalog.ts +149 -0
  167. package/src/providers/claude/commands/probeRuntimeCommands.ts +86 -0
  168. package/src/providers/claude/env/ClaudeSettingsReconciler.ts +90 -0
  169. package/src/providers/claude/env/claudeModelEnv.ts +86 -0
  170. package/src/providers/claude/history/ClaudeConversationHistoryService.ts +446 -0
  171. package/src/providers/claude/history/ClaudeHistoryStore.ts +170 -0
  172. package/src/providers/claude/history/sdkAsyncSubagent.ts +92 -0
  173. package/src/providers/claude/history/sdkBranchFilter.ts +271 -0
  174. package/src/providers/claude/history/sdkHistoryTypes.ts +61 -0
  175. package/src/providers/claude/history/sdkMessageParsing.ts +413 -0
  176. package/src/providers/claude/history/sdkSessionPaths.ts +98 -0
  177. package/src/providers/claude/history/sdkSubagentSidecar.ts +261 -0
  178. package/src/providers/claude/hooks/SubagentHooks.ts +31 -0
  179. package/src/providers/claude/modelLabels.ts +77 -0
  180. package/src/providers/claude/modelOptions.ts +113 -0
  181. package/src/providers/claude/modelSelection.ts +17 -0
  182. package/src/providers/claude/plugins/PluginManager.ts +194 -0
  183. package/src/providers/claude/prompt/ClaudeTurnEncoder.ts +46 -0
  184. package/src/providers/claude/registration.ts +39 -0
  185. package/src/providers/claude/runtime/ClaudeApprovalHandler.ts +153 -0
  186. package/src/providers/claude/runtime/ClaudeChatRuntime.ts +1812 -0
  187. package/src/providers/claude/runtime/ClaudeCliResolver.ts +94 -0
  188. package/src/providers/claude/runtime/ClaudeDynamicUpdates.ts +164 -0
  189. package/src/providers/claude/runtime/ClaudeMessageChannel.ts +209 -0
  190. package/src/providers/claude/runtime/ClaudeQueryOptionsBuilder.ts +315 -0
  191. package/src/providers/claude/runtime/ClaudeRewindService.ts +220 -0
  192. package/src/providers/claude/runtime/ClaudeSessionManager.ts +92 -0
  193. package/src/providers/claude/runtime/ClaudeTaskResultInterpreter.ts +172 -0
  194. package/src/providers/claude/runtime/ClaudeUserMessageFactory.ts +83 -0
  195. package/src/providers/claude/runtime/claudeColdStartQuery.ts +152 -0
  196. package/src/providers/claude/runtime/customSpawn.ts +87 -0
  197. package/src/providers/claude/runtime/types.ts +134 -0
  198. package/src/providers/claude/sdk/messages.ts +17 -0
  199. package/src/providers/claude/sdk/toolResultContent.ts +4 -0
  200. package/src/providers/claude/sdk/typeGuards.ts +14 -0
  201. package/src/providers/claude/sdk/types.ts +15 -0
  202. package/src/providers/claude/security/ClaudePermissionUpdates.ts +44 -0
  203. package/src/providers/claude/settings.ts +138 -0
  204. package/src/providers/claude/storage/AgentVaultStorage.ts +101 -0
  205. package/src/providers/claude/storage/CCSettingsStorage.ts +153 -0
  206. package/src/providers/claude/storage/ClaudianSettingsStorage.ts +6 -0
  207. package/src/providers/claude/storage/McpStorage.ts +139 -0
  208. package/src/providers/claude/storage/SessionStorage.ts +5 -0
  209. package/src/providers/claude/storage/SkillStorage.ts +61 -0
  210. package/src/providers/claude/storage/SlashCommandStorage.ts +96 -0
  211. package/src/providers/claude/storage/StorageService.ts +185 -0
  212. package/src/providers/claude/stream/toolInputStreamState.ts +318 -0
  213. package/src/providers/claude/stream/transformClaudeMessage.ts +586 -0
  214. package/src/providers/claude/types/agent.ts +2 -0
  215. package/src/providers/claude/types/models.ts +168 -0
  216. package/src/providers/claude/types/plugins.ts +14 -0
  217. package/src/providers/claude/types/providerState.ts +16 -0
  218. package/src/providers/claude/types/settings.ts +98 -0
  219. package/src/providers/claude/ui/AgentSettings.ts +389 -0
  220. package/src/providers/claude/ui/ClaudeChatUIConfig.ts +113 -0
  221. package/src/providers/claude/ui/ClaudeSettingsTab.ts +407 -0
  222. package/src/providers/claude/ui/PluginSettingsManager.ts +149 -0
  223. package/src/providers/claude/ui/SlashCommandSettings.ts +527 -0
  224. package/src/providers/codex/CLAUDE.md +64 -0
  225. package/src/providers/codex/agents/CodexAgentMentionProvider.ts +33 -0
  226. package/src/providers/codex/app/CodexWorkspaceServices.ts +76 -0
  227. package/src/providers/codex/auxiliary/CodexInlineEditService.ts +9 -0
  228. package/src/providers/codex/auxiliary/CodexInstructionRefineService.ts +9 -0
  229. package/src/providers/codex/auxiliary/CodexTaskResultInterpreter.ts +29 -0
  230. package/src/providers/codex/auxiliary/CodexTitleGenerationService.ts +22 -0
  231. package/src/providers/codex/capabilities.ts +16 -0
  232. package/src/providers/codex/commands/CodexSkillCatalog.ts +180 -0
  233. package/src/providers/codex/env/CodexSettingsReconciler.ts +68 -0
  234. package/src/providers/codex/history/CodexConversationHistoryService.ts +212 -0
  235. package/src/providers/codex/history/CodexHistoryStore.ts +1672 -0
  236. package/src/providers/codex/modelOptions.ts +99 -0
  237. package/src/providers/codex/modelSelection.ts +17 -0
  238. package/src/providers/codex/normalization/codexSubagentNormalization.ts +227 -0
  239. package/src/providers/codex/normalization/codexToolNormalization.ts +390 -0
  240. package/src/providers/codex/prompt/encodeCodexTurn.ts +57 -0
  241. package/src/providers/codex/registration.ts +29 -0
  242. package/src/providers/codex/runtime/CodexAppServerProcess.ts +105 -0
  243. package/src/providers/codex/runtime/CodexAuxQueryRunner.ts +180 -0
  244. package/src/providers/codex/runtime/CodexBinaryLocator.ts +49 -0
  245. package/src/providers/codex/runtime/CodexChatRuntime.ts +1296 -0
  246. package/src/providers/codex/runtime/CodexCliResolver.ts +65 -0
  247. package/src/providers/codex/runtime/CodexExecutionTargetResolver.ts +104 -0
  248. package/src/providers/codex/runtime/CodexLaunchSpecBuilder.ts +85 -0
  249. package/src/providers/codex/runtime/CodexNotificationRouter.ts +1033 -0
  250. package/src/providers/codex/runtime/CodexPathMapper.ts +155 -0
  251. package/src/providers/codex/runtime/CodexRpcTransport.ts +171 -0
  252. package/src/providers/codex/runtime/CodexRuntimeContext.ts +109 -0
  253. package/src/providers/codex/runtime/CodexServerRequestRouter.ts +331 -0
  254. package/src/providers/codex/runtime/CodexSessionFileTail.ts +792 -0
  255. package/src/providers/codex/runtime/CodexSessionManager.ts +39 -0
  256. package/src/providers/codex/runtime/codexAppServerSupport.ts +58 -0
  257. package/src/providers/codex/runtime/codexAppServerTypes.ts +705 -0
  258. package/src/providers/codex/runtime/codexLaunchTypes.ts +30 -0
  259. package/src/providers/codex/settings.ts +236 -0
  260. package/src/providers/codex/skills/CodexSkillListingService.ts +173 -0
  261. package/src/providers/codex/storage/CodexSkillStorage.ts +250 -0
  262. package/src/providers/codex/storage/CodexSubagentStorage.ts +212 -0
  263. package/src/providers/codex/types/index.ts +16 -0
  264. package/src/providers/codex/types/models.ts +46 -0
  265. package/src/providers/codex/types/subagent.ts +23 -0
  266. package/src/providers/codex/ui/CodexChatUIConfig.ts +128 -0
  267. package/src/providers/codex/ui/CodexSettingsTab.ts +432 -0
  268. package/src/providers/codex/ui/CodexSkillSettings.ts +275 -0
  269. package/src/providers/codex/ui/CodexSubagentSettings.ts +400 -0
  270. package/src/providers/defaultProviderConfigs.ts +14 -0
  271. package/src/providers/index.ts +30 -0
  272. package/src/providers/opencode/agents/OpencodeAgentMentionProvider.ts +42 -0
  273. package/src/providers/opencode/app/OpencodeRuntimeCommandLoader.ts +67 -0
  274. package/src/providers/opencode/app/OpencodeWorkspaceServices.ts +55 -0
  275. package/src/providers/opencode/auxiliary/OpencodeInlineEditService.ts +13 -0
  276. package/src/providers/opencode/auxiliary/OpencodeInstructionRefineService.ts +12 -0
  277. package/src/providers/opencode/auxiliary/OpencodeTaskResultInterpreter.ts +29 -0
  278. package/src/providers/opencode/auxiliary/OpencodeTitleGenerationService.ts +27 -0
  279. package/src/providers/opencode/capabilities.ts +16 -0
  280. package/src/providers/opencode/commands/OpencodeCommandCatalog.ts +92 -0
  281. package/src/providers/opencode/discoveryState.ts +135 -0
  282. package/src/providers/opencode/env/OpencodeSettingsReconciler.ts +178 -0
  283. package/src/providers/opencode/history/OpencodeConversationHistoryService.ts +84 -0
  284. package/src/providers/opencode/history/OpencodeHistoryStore.ts +472 -0
  285. package/src/providers/opencode/history/OpencodeSqliteReader.ts +284 -0
  286. package/src/providers/opencode/internal/compareCollections.ts +72 -0
  287. package/src/providers/opencode/internal/providerProjection.ts +15 -0
  288. package/src/providers/opencode/models.ts +378 -0
  289. package/src/providers/opencode/modes.ts +150 -0
  290. package/src/providers/opencode/normalization/opencodeToolNormalization.ts +406 -0
  291. package/src/providers/opencode/registration.ts +27 -0
  292. package/src/providers/opencode/runtime/OpencodeAuxQueryRunner.ts +436 -0
  293. package/src/providers/opencode/runtime/OpencodeChatRuntime.ts +1603 -0
  294. package/src/providers/opencode/runtime/OpencodeCliResolver.ts +57 -0
  295. package/src/providers/opencode/runtime/OpencodeLaunchArtifacts.ts +231 -0
  296. package/src/providers/opencode/runtime/OpencodePaths.ts +113 -0
  297. package/src/providers/opencode/runtime/OpencodeRuntimeEnvironment.ts +18 -0
  298. package/src/providers/opencode/runtime/buildOpencodePrompt.ts +66 -0
  299. package/src/providers/opencode/settings.ts +427 -0
  300. package/src/providers/opencode/storage/OpencodeAgentStorage.ts +346 -0
  301. package/src/providers/opencode/types/agent.ts +37 -0
  302. package/src/providers/opencode/types/index.ts +9 -0
  303. package/src/providers/opencode/ui/OpencodeAgentSettings.ts +579 -0
  304. package/src/providers/opencode/ui/OpencodeChatUIConfig.ts +316 -0
  305. package/src/providers/opencode/ui/OpencodeSettingsTab.ts +674 -0
  306. package/src/providers/pi/app/PiRuntimeCommandLoader.ts +57 -0
  307. package/src/providers/pi/app/PiWorkspaceServices.ts +39 -0
  308. package/src/providers/pi/auxiliary/PiInlineEditService.ts +9 -0
  309. package/src/providers/pi/auxiliary/PiInstructionRefineService.ts +9 -0
  310. package/src/providers/pi/auxiliary/PiTaskResultInterpreter.ts +29 -0
  311. package/src/providers/pi/auxiliary/PiTitleGenerationService.ts +19 -0
  312. package/src/providers/pi/capabilities.ts +16 -0
  313. package/src/providers/pi/commands/PiCommandCatalog.ts +92 -0
  314. package/src/providers/pi/env/PiSettingsReconciler.ts +180 -0
  315. package/src/providers/pi/history/PiConversationHistoryService.ts +123 -0
  316. package/src/providers/pi/history/PiHistoryStore.ts +664 -0
  317. package/src/providers/pi/internal/compareCollections.ts +4 -0
  318. package/src/providers/pi/internal/providerProjection.ts +18 -0
  319. package/src/providers/pi/models.ts +302 -0
  320. package/src/providers/pi/normalizations/piEventNormalization.ts +211 -0
  321. package/src/providers/pi/normalizations/piToolNormalization.ts +97 -0
  322. package/src/providers/pi/registration.ts +30 -0
  323. package/src/providers/pi/runtime/PiAuxQueryRunner.ts +216 -0
  324. package/src/providers/pi/runtime/PiChatRuntime.ts +1064 -0
  325. package/src/providers/pi/runtime/PiCliResolver.ts +53 -0
  326. package/src/providers/pi/runtime/PiExtensionUiBridge.ts +161 -0
  327. package/src/providers/pi/runtime/PiJsonl.ts +71 -0
  328. package/src/providers/pi/runtime/PiLaunchSpec.ts +70 -0
  329. package/src/providers/pi/runtime/PiModelDiscoveryService.ts +92 -0
  330. package/src/providers/pi/runtime/PiRpcPayloads.ts +18 -0
  331. package/src/providers/pi/runtime/PiRpcTransport.ts +243 -0
  332. package/src/providers/pi/runtime/PiSubprocess.ts +159 -0
  333. package/src/providers/pi/runtime/buildPiPrompt.ts +62 -0
  334. package/src/providers/pi/runtime/buildPiUsageInfo.ts +69 -0
  335. package/src/providers/pi/settings.ts +468 -0
  336. package/src/providers/pi/types.ts +64 -0
  337. package/src/providers/pi/ui/ObsidianPiExtensionUiRenderer.ts +251 -0
  338. package/src/providers/pi/ui/PiChatUIConfig.ts +265 -0
  339. package/src/providers/pi/ui/PiExtensionUiRenderer.ts +12 -0
  340. package/src/providers/pi/ui/PiSettingsTab.ts +642 -0
  341. package/src/shared/components/ResumeSessionDropdown.ts +185 -0
  342. package/src/shared/components/SelectableDropdown.ts +140 -0
  343. package/src/shared/components/SelectionHighlight.ts +77 -0
  344. package/src/shared/components/SlashCommandDropdown.ts +421 -0
  345. package/src/shared/icons.ts +180 -0
  346. package/src/shared/mention/MentionDropdownController.ts +627 -0
  347. package/src/shared/mention/VaultMentionCache.ts +106 -0
  348. package/src/shared/mention/VaultMentionDataProvider.ts +51 -0
  349. package/src/shared/mention/types.ts +67 -0
  350. package/src/shared/modals/ConfirmModal.ts +60 -0
  351. package/src/shared/modals/ForkTargetModal.ts +47 -0
  352. package/src/shared/modals/InstructionConfirmModal.ts +281 -0
  353. package/src/style/CLAUDE.md +49 -0
  354. package/src/style/accessibility.css +40 -0
  355. package/src/style/base/animations.css +44 -0
  356. package/src/style/base/container.css +20 -0
  357. package/src/style/base/variables.css +46 -0
  358. package/src/style/base/visibility.css +15 -0
  359. package/src/style/components/code.css +97 -0
  360. package/src/style/components/context-footer.css +76 -0
  361. package/src/style/components/header.css +27 -0
  362. package/src/style/components/history.css +221 -0
  363. package/src/style/components/input.css +312 -0
  364. package/src/style/components/messages.css +262 -0
  365. package/src/style/components/nav-sidebar.css +58 -0
  366. package/src/style/components/status-panel.css +202 -0
  367. package/src/style/components/subagent.css +248 -0
  368. package/src/style/components/tabs.css +112 -0
  369. package/src/style/components/thinking.css +88 -0
  370. package/src/style/components/toolcalls.css +278 -0
  371. package/src/style/features/ask-user-question.css +315 -0
  372. package/src/style/features/diff.css +197 -0
  373. package/src/style/features/file-context.css +188 -0
  374. package/src/style/features/file-link.css +22 -0
  375. package/src/style/features/image-context.css +179 -0
  376. package/src/style/features/image-embed.css +40 -0
  377. package/src/style/features/image-modal.css +52 -0
  378. package/src/style/features/inline-edit.css +278 -0
  379. package/src/style/features/plan-mode.css +103 -0
  380. package/src/style/features/resume-session.css +119 -0
  381. package/src/style/features/slash-commands.css +91 -0
  382. package/src/style/index.css +63 -0
  383. package/src/style/modals/fork-target.css +21 -0
  384. package/src/style/modals/instruction.css +161 -0
  385. package/src/style/modals/mcp-modal.css +241 -0
  386. package/src/style/settings/agent-settings.css +2 -0
  387. package/src/style/settings/base.css +300 -0
  388. package/src/style/settings/env-snippets.css +366 -0
  389. package/src/style/settings/mcp-settings.css +211 -0
  390. package/src/style/settings/plugin-settings.css +164 -0
  391. package/src/style/settings/provider-model-picker.css +367 -0
  392. package/src/style/settings/slash-settings.css +16 -0
  393. package/src/style/toolbar/external-context.css +177 -0
  394. package/src/style/toolbar/mcp-selector.css +176 -0
  395. package/src/style/toolbar/mode-selector.css +19 -0
  396. package/src/style/toolbar/model-selector.css +99 -0
  397. package/src/style/toolbar/permission-toggle.css +56 -0
  398. package/src/style/toolbar/service-tier-toggle.css +39 -0
  399. package/src/style/toolbar/thinking-selector.css +83 -0
  400. package/src/types/smol-toml.d.ts +4 -0
  401. package/src/utils/agent.ts +50 -0
  402. package/src/utils/animationFrame.ts +46 -0
  403. package/src/utils/browser.ts +46 -0
  404. package/src/utils/canvas.ts +14 -0
  405. package/src/utils/cliBinaryLocator.ts +97 -0
  406. package/src/utils/context.ts +117 -0
  407. package/src/utils/contextMentionResolver.ts +154 -0
  408. package/src/utils/date.ts +31 -0
  409. package/src/utils/diff.ts +384 -0
  410. package/src/utils/editor.ts +104 -0
  411. package/src/utils/electronCompat.ts +53 -0
  412. package/src/utils/env.ts +465 -0
  413. package/src/utils/externalContext.ts +143 -0
  414. package/src/utils/externalContextScanner.ts +135 -0
  415. package/src/utils/fileLink.ts +263 -0
  416. package/src/utils/frontmatter.ts +194 -0
  417. package/src/utils/imageEmbed.ts +139 -0
  418. package/src/utils/inlineEdit.ts +22 -0
  419. package/src/utils/interrupt.ts +23 -0
  420. package/src/utils/markdown.ts +25 -0
  421. package/src/utils/markdownMath.ts +130 -0
  422. package/src/utils/mcp.ts +96 -0
  423. package/src/utils/obsidianCompat.ts +23 -0
  424. package/src/utils/path.ts +342 -0
  425. package/src/utils/session.ts +240 -0
  426. package/src/utils/slashCommand.ts +152 -0
  427. package/src/utils/subagentJsonl.ts +52 -0
  428. package/src/utils/windowsCmdShim.ts +98 -0
  429. package/tests/__mocks__/claude-agent-sdk.ts +317 -0
  430. package/tests/__mocks__/codex-sdk.ts +88 -0
  431. package/tests/__mocks__/obsidian.ts +434 -0
  432. package/tests/helpers/mockElement.ts +403 -0
  433. package/tests/helpers/sdkMessages.ts +291 -0
  434. package/tests/integration/core/agent/ClaudianService.test.ts +1845 -0
  435. package/tests/integration/core/mcp/mcp.test.ts +905 -0
  436. package/tests/integration/features/chat/imagePersistence.test.ts +38 -0
  437. package/tests/integration/main.test.ts +1701 -0
  438. package/tests/setupWindow.ts +26 -0
  439. package/tests/tsconfig.json +7 -0
  440. package/tests/unit/core/commands/builtInCommands.test.ts +239 -0
  441. package/tests/unit/core/mcp/McpServerManager.test.ts +405 -0
  442. package/tests/unit/core/mcp/McpTester.test.ts +282 -0
  443. package/tests/unit/core/mcp/createNodeFetch.test.ts +188 -0
  444. package/tests/unit/core/providers/ProviderRegistry.test.ts +275 -0
  445. package/tests/unit/core/providers/ProviderSettingsCoordinator.test.ts +490 -0
  446. package/tests/unit/core/providers/ProviderWorkspaceRegistry.test.ts +84 -0
  447. package/tests/unit/core/providers/modelRouting.test.ts +91 -0
  448. package/tests/unit/core/providers/modelSelection.test.ts +155 -0
  449. package/tests/unit/core/providers/providerEnvironment.test.ts +162 -0
  450. package/tests/unit/core/providers/tabLifecycle.test.ts +217 -0
  451. package/tests/unit/core/security/ApprovalManager.test.ts +152 -0
  452. package/tests/unit/core/storage/VaultFileAdapter.test.ts +535 -0
  453. package/tests/unit/core/tools/todo.test.ts +227 -0
  454. package/tests/unit/core/tools/toolIcons.test.ts +75 -0
  455. package/tests/unit/core/tools/toolInput.test.ts +350 -0
  456. package/tests/unit/core/tools/toolNames.test.ts +464 -0
  457. package/tests/unit/core/types/mcp.test.ts +115 -0
  458. package/tests/unit/features/chat/ClaudianView.test.ts +404 -0
  459. package/tests/unit/features/chat/controllers/BrowserSelectionController.test.ts +179 -0
  460. package/tests/unit/features/chat/controllers/CanvasSelectionController.test.ts +216 -0
  461. package/tests/unit/features/chat/controllers/ConversationController.test.ts +2764 -0
  462. package/tests/unit/features/chat/controllers/InputController.test.ts +3188 -0
  463. package/tests/unit/features/chat/controllers/NavigationController.test.ts +640 -0
  464. package/tests/unit/features/chat/controllers/SelectionController.test.ts +695 -0
  465. package/tests/unit/features/chat/controllers/StreamController.test.ts +2534 -0
  466. package/tests/unit/features/chat/controllers/contextRowVisibility.test.ts +46 -0
  467. package/tests/unit/features/chat/controllers/index.test.ts +16 -0
  468. package/tests/unit/features/chat/rendering/DiffRenderer.test.ts +355 -0
  469. package/tests/unit/features/chat/rendering/InlineAskUserQuestion.test.ts +1035 -0
  470. package/tests/unit/features/chat/rendering/InlineExitPlanMode.test.ts +191 -0
  471. package/tests/unit/features/chat/rendering/InlinePlanApproval.test.ts +126 -0
  472. package/tests/unit/features/chat/rendering/MessageRenderer.test.ts +2004 -0
  473. package/tests/unit/features/chat/rendering/SubagentRenderer.test.ts +917 -0
  474. package/tests/unit/features/chat/rendering/ThinkingBlockRenderer.test.ts +124 -0
  475. package/tests/unit/features/chat/rendering/TodoListRenderer.test.ts +173 -0
  476. package/tests/unit/features/chat/rendering/ToolCallRenderer.test.ts +909 -0
  477. package/tests/unit/features/chat/rendering/WriteEditRenderer.test.ts +474 -0
  478. package/tests/unit/features/chat/rendering/collapsible.test.ts +158 -0
  479. package/tests/unit/features/chat/rendering/todoUtils.test.ts +105 -0
  480. package/tests/unit/features/chat/rewind.test.ts +56 -0
  481. package/tests/unit/features/chat/services/BangBashService.test.ts +142 -0
  482. package/tests/unit/features/chat/services/InstructionRefineService.test.ts +371 -0
  483. package/tests/unit/features/chat/services/SubagentManager.test.ts +1759 -0
  484. package/tests/unit/features/chat/services/TitleGenerationService.test.ts +480 -0
  485. package/tests/unit/features/chat/state/ChatState.test.ts +581 -0
  486. package/tests/unit/features/chat/tabs/Tab.test.ts +4287 -0
  487. package/tests/unit/features/chat/tabs/TabBar.test.ts +357 -0
  488. package/tests/unit/features/chat/tabs/TabManager.test.ts +2962 -0
  489. package/tests/unit/features/chat/tabs/index.test.ts +11 -0
  490. package/tests/unit/features/chat/ui/BangBashModeManager.test.ts +321 -0
  491. package/tests/unit/features/chat/ui/ExternalContextSelector.test.ts +555 -0
  492. package/tests/unit/features/chat/ui/FileContextManager.test.ts +876 -0
  493. package/tests/unit/features/chat/ui/ImageContext.test.ts +777 -0
  494. package/tests/unit/features/chat/ui/InputToolbar.test.ts +1139 -0
  495. package/tests/unit/features/chat/ui/InstructionModeManager.test.ts +243 -0
  496. package/tests/unit/features/chat/ui/NavigationSidebar.test.ts +570 -0
  497. package/tests/unit/features/chat/ui/StatusPanel.test.ts +953 -0
  498. package/tests/unit/features/chat/ui/file-context/state/FileContextState.test.ts +155 -0
  499. package/tests/unit/features/chat/ui/textareaResize.test.ts +102 -0
  500. package/tests/unit/features/chat/utils/usageInfo.test.ts +56 -0
  501. package/tests/unit/features/inline-edit/InlineEditService.test.ts +1199 -0
  502. package/tests/unit/features/inline-edit/ui/InlineEditModal.openAndWait.test.ts +1482 -0
  503. package/tests/unit/features/inline-edit/ui/InlineEditModal.test.ts +495 -0
  504. package/tests/unit/features/inline-edit/ui/inlineEditMarkdownPreview.test.ts +92 -0
  505. package/tests/unit/features/settings/AgentSettings.test.ts +82 -0
  506. package/tests/unit/features/settings/keyboardNavigation.test.ts +73 -0
  507. package/tests/unit/features/settings/ui/CodexSkillSettings.test.ts +294 -0
  508. package/tests/unit/features/settings/ui/CodexSubagentSettings.test.ts +207 -0
  509. package/tests/unit/i18n/constants.test.ts +43 -0
  510. package/tests/unit/i18n/i18n.test.ts +244 -0
  511. package/tests/unit/i18n/locales.test.ts +134 -0
  512. package/tests/unit/providers/acp/AcpClientConnection.test.ts +248 -0
  513. package/tests/unit/providers/acp/AcpJsonRpcTransport.test.ts +186 -0
  514. package/tests/unit/providers/acp/AcpSessionConfig.test.ts +247 -0
  515. package/tests/unit/providers/acp/AcpSessionUpdateNormalizer.test.ts +145 -0
  516. package/tests/unit/providers/acp/AcpSubprocess.test.ts +105 -0
  517. package/tests/unit/providers/acp/buildAcpUsageInfo.test.ts +51 -0
  518. package/tests/unit/providers/claude/agents/AgentManager.test.ts +590 -0
  519. package/tests/unit/providers/claude/agents/AgentStorage.test.ts +434 -0
  520. package/tests/unit/providers/claude/agents/index.test.ts +10 -0
  521. package/tests/unit/providers/claude/commands/ClaudeCommandCatalog.test.ts +396 -0
  522. package/tests/unit/providers/claude/commands/probeRuntimeCommands.test.ts +92 -0
  523. package/tests/unit/providers/claude/env/ClaudeSettingsReconciler.test.ts +57 -0
  524. package/tests/unit/providers/claude/env/claudeModelEnv.test.ts +228 -0
  525. package/tests/unit/providers/claude/hooks/SubagentHooks.test.ts +83 -0
  526. package/tests/unit/providers/claude/plugins/PluginManager.test.ts +832 -0
  527. package/tests/unit/providers/claude/plugins/index.test.ts +7 -0
  528. package/tests/unit/providers/claude/prompt/ClaudeTurnEncoder.test.ts +145 -0
  529. package/tests/unit/providers/claude/prompt/instructionRefine.test.ts +185 -0
  530. package/tests/unit/providers/claude/prompt/systemPrompt.test.ts +163 -0
  531. package/tests/unit/providers/claude/prompt/titleGeneration.test.ts +20 -0
  532. package/tests/unit/providers/claude/runtime/ClaudeTaskResultInterpreter.test.ts +28 -0
  533. package/tests/unit/providers/claude/runtime/ClaudianService.test.ts +3796 -0
  534. package/tests/unit/providers/claude/runtime/MessageChannel.test.ts +421 -0
  535. package/tests/unit/providers/claude/runtime/QueryOptionsBuilder.test.ts +775 -0
  536. package/tests/unit/providers/claude/runtime/SessionManager.test.ts +182 -0
  537. package/tests/unit/providers/claude/runtime/claudeColdStartQuery.test.ts +331 -0
  538. package/tests/unit/providers/claude/runtime/customSpawn.test.ts +374 -0
  539. package/tests/unit/providers/claude/runtime/index.test.ts +13 -0
  540. package/tests/unit/providers/claude/runtime/types.test.ts +190 -0
  541. package/tests/unit/providers/claude/sdk/typeGuards.test.ts +50 -0
  542. package/tests/unit/providers/claude/security/ClaudePermissionUpdates.test.ts +198 -0
  543. package/tests/unit/providers/claude/storage/AgentVaultStorage.test.ts +413 -0
  544. package/tests/unit/providers/claude/storage/CCSettingsStorage.test.ts +408 -0
  545. package/tests/unit/providers/claude/storage/ClaudianSettingsStorage.test.ts +653 -0
  546. package/tests/unit/providers/claude/storage/McpStorage.test.ts +619 -0
  547. package/tests/unit/providers/claude/storage/SessionStorage.test.ts +680 -0
  548. package/tests/unit/providers/claude/storage/SkillStorage.test.ts +275 -0
  549. package/tests/unit/providers/claude/storage/SlashCommandStorage.test.ts +612 -0
  550. package/tests/unit/providers/claude/storage/storage.test.ts +360 -0
  551. package/tests/unit/providers/claude/storage/storageService.convenience.test.ts +447 -0
  552. package/tests/unit/providers/claude/stream/transformSDKMessage.test.ts +1729 -0
  553. package/tests/unit/providers/claude/types/types.test.ts +726 -0
  554. package/tests/unit/providers/claude/ui/ClaudeChatUIConfig.test.ts +173 -0
  555. package/tests/unit/providers/claude/ui/ClaudeSettingsTab.test.ts +466 -0
  556. package/tests/unit/providers/codex/agents/CodexAgentMentionProvider.test.ts +89 -0
  557. package/tests/unit/providers/codex/auxiliary/CodexInstructionRefineService.test.ts +81 -0
  558. package/tests/unit/providers/codex/capabilities.test.ts +39 -0
  559. package/tests/unit/providers/codex/commands/CodexSkillCatalog.test.ts +413 -0
  560. package/tests/unit/providers/codex/env/CodexSettingsReconciler.test.ts +106 -0
  561. package/tests/unit/providers/codex/fixtures/codex-session-abort.jsonl +9 -0
  562. package/tests/unit/providers/codex/fixtures/codex-session-agent-lifecycle.jsonl +12 -0
  563. package/tests/unit/providers/codex/fixtures/codex-session-persisted-tools.jsonl +15 -0
  564. package/tests/unit/providers/codex/fixtures/codex-session-simple.jsonl +10 -0
  565. package/tests/unit/providers/codex/fixtures/codex-session-tools.jsonl +12 -0
  566. package/tests/unit/providers/codex/fixtures/codex-session-websearch-persisted.jsonl +3 -0
  567. package/tests/unit/providers/codex/fixtures/codex-session-websearch.jsonl +7 -0
  568. package/tests/unit/providers/codex/history/CodexConversationHistoryService.test.ts +690 -0
  569. package/tests/unit/providers/codex/history/CodexHistoryStore.test.ts +2202 -0
  570. package/tests/unit/providers/codex/normalization/codexSubagentNormalization.test.ts +81 -0
  571. package/tests/unit/providers/codex/normalization/codexToolNormalization.test.ts +322 -0
  572. package/tests/unit/providers/codex/prompt/encodeCodexTurn.test.ts +168 -0
  573. package/tests/unit/providers/codex/runtime/CodexAppServerProcess.test.ts +255 -0
  574. package/tests/unit/providers/codex/runtime/CodexAuxQueryRunner.test.ts +130 -0
  575. package/tests/unit/providers/codex/runtime/CodexBinaryLocator.test.ts +90 -0
  576. package/tests/unit/providers/codex/runtime/CodexChatRuntime.test.ts +2445 -0
  577. package/tests/unit/providers/codex/runtime/CodexCliResolver.test.ts +103 -0
  578. package/tests/unit/providers/codex/runtime/CodexExecutionTargetResolver.test.ts +105 -0
  579. package/tests/unit/providers/codex/runtime/CodexLaunchSpecBuilder.test.ts +150 -0
  580. package/tests/unit/providers/codex/runtime/CodexNotificationRouter.test.ts +1248 -0
  581. package/tests/unit/providers/codex/runtime/CodexPathMapper.test.ts +51 -0
  582. package/tests/unit/providers/codex/runtime/CodexRpcTransport.test.ts +220 -0
  583. package/tests/unit/providers/codex/runtime/CodexRuntimeContext.test.ts +107 -0
  584. package/tests/unit/providers/codex/runtime/CodexServerRequestRouter.test.ts +537 -0
  585. package/tests/unit/providers/codex/runtime/CodexSessionFileTail.test.ts +1305 -0
  586. package/tests/unit/providers/codex/runtime/CodexSessionManager.test.ts +82 -0
  587. package/tests/unit/providers/codex/runtime/codexAppServerTypes.test.ts +336 -0
  588. package/tests/unit/providers/codex/settings.test.ts +189 -0
  589. package/tests/unit/providers/codex/skills/CodexSkillListingService.test.ts +178 -0
  590. package/tests/unit/providers/codex/storage/CodexSkillStorage.test.ts +342 -0
  591. package/tests/unit/providers/codex/storage/CodexSubagentStorage.test.ts +376 -0
  592. package/tests/unit/providers/codex/ui/CodexChatUIConfig.test.ts +211 -0
  593. package/tests/unit/providers/codex/ui/CodexSettingsTab.test.ts +578 -0
  594. package/tests/unit/providers/defaultProviderConfigs.test.ts +18 -0
  595. package/tests/unit/providers/opencode/OpencodeAuxQueryRunner.test.ts +355 -0
  596. package/tests/unit/providers/opencode/OpencodeChatRuntime.test.ts +808 -0
  597. package/tests/unit/providers/opencode/OpencodeCliResolver.test.ts +93 -0
  598. package/tests/unit/providers/opencode/OpencodeCommandCatalog.test.ts +75 -0
  599. package/tests/unit/providers/opencode/OpencodeConversationHistoryService.test.ts +103 -0
  600. package/tests/unit/providers/opencode/OpencodeHistoryStore.test.ts +418 -0
  601. package/tests/unit/providers/opencode/OpencodeLaunchArtifacts.test.ts +268 -0
  602. package/tests/unit/providers/opencode/OpencodePaths.test.ts +35 -0
  603. package/tests/unit/providers/opencode/OpencodeRuntimeCommandLoader.test.ts +129 -0
  604. package/tests/unit/providers/opencode/OpencodeSettingsReconciler.test.ts +96 -0
  605. package/tests/unit/providers/opencode/OpencodeSettingsTab.test.ts +649 -0
  606. package/tests/unit/providers/opencode/OpencodeSqliteReader.test.ts +185 -0
  607. package/tests/unit/providers/opencode/agents/OpencodeAgentMentionProvider.test.ts +56 -0
  608. package/tests/unit/providers/opencode/buildOpencodePrompt.test.ts +87 -0
  609. package/tests/unit/providers/opencode/capabilities.test.ts +39 -0
  610. package/tests/unit/providers/opencode/models.test.ts +273 -0
  611. package/tests/unit/providers/opencode/modes.test.ts +151 -0
  612. package/tests/unit/providers/opencode/opencodeToolNormalization.test.ts +197 -0
  613. package/tests/unit/providers/opencode/settings.test.ts +469 -0
  614. package/tests/unit/providers/opencode/storage/OpencodeAgentStorage.test.ts +377 -0
  615. package/tests/unit/providers/opencode/ui/OpencodeAgentSettings.test.ts +91 -0
  616. package/tests/unit/providers/pi/PiRuntimeCommandLoader.test.ts +149 -0
  617. package/tests/unit/providers/pi/capabilities.test.ts +20 -0
  618. package/tests/unit/providers/pi/commands/PiCommandCatalog.test.ts +69 -0
  619. package/tests/unit/providers/pi/env/PiSettingsReconciler.test.ts +61 -0
  620. package/tests/unit/providers/pi/history/PiConversationHistoryService.test.ts +147 -0
  621. package/tests/unit/providers/pi/history/PiHistoryStore.test.ts +523 -0
  622. package/tests/unit/providers/pi/models.test.ts +96 -0
  623. package/tests/unit/providers/pi/registration.test.ts +54 -0
  624. package/tests/unit/providers/pi/runtime/PiAuxQueryRunner.test.ts +172 -0
  625. package/tests/unit/providers/pi/runtime/PiChatRuntime.test.ts +830 -0
  626. package/tests/unit/providers/pi/runtime/PiCliResolver.test.ts +105 -0
  627. package/tests/unit/providers/pi/runtime/PiEventNormalization.test.ts +147 -0
  628. package/tests/unit/providers/pi/runtime/PiExtensionUiBridge.test.ts +98 -0
  629. package/tests/unit/providers/pi/runtime/PiJsonl.test.ts +42 -0
  630. package/tests/unit/providers/pi/runtime/PiLaunchSpec.test.ts +92 -0
  631. package/tests/unit/providers/pi/runtime/PiModelDiscoveryService.test.ts +135 -0
  632. package/tests/unit/providers/pi/runtime/PiRpcPayloads.test.ts +15 -0
  633. package/tests/unit/providers/pi/runtime/PiRpcTransport.test.ts +116 -0
  634. package/tests/unit/providers/pi/runtime/PiSubprocess.test.ts +151 -0
  635. package/tests/unit/providers/pi/runtime/buildPiPrompt.test.ts +84 -0
  636. package/tests/unit/providers/pi/runtime/buildPiUsageInfo.test.ts +69 -0
  637. package/tests/unit/providers/pi/settings.test.ts +253 -0
  638. package/tests/unit/providers/pi/ui/PiChatUIConfig.test.ts +161 -0
  639. package/tests/unit/providers/pi/ui/PiSettingsTab.test.ts +492 -0
  640. package/tests/unit/scripts/rendererSafeUnref.test.ts +101 -0
  641. package/tests/unit/shared/components/ResumeSessionDropdown.test.ts +356 -0
  642. package/tests/unit/shared/components/SelectableDropdown.test.ts +406 -0
  643. package/tests/unit/shared/components/SlashCommandDropdown.provider.test.ts +354 -0
  644. package/tests/unit/shared/components/SlashCommandDropdown.test.ts +508 -0
  645. package/tests/unit/shared/icons.test.ts +56 -0
  646. package/tests/unit/shared/index.test.ts +46 -0
  647. package/tests/unit/shared/mention/MentionDropdownController.test.ts +823 -0
  648. package/tests/unit/shared/mention/VaultFileCache.test.ts +195 -0
  649. package/tests/unit/shared/mention/VaultFolderCache.test.ts +143 -0
  650. package/tests/unit/shared/mention/VaultMentionDataProvider.test.ts +87 -0
  651. package/tests/unit/shared/modals/ConfirmModal.test.ts +111 -0
  652. package/tests/unit/shared/modals/ForkTargetModal.test.ts +101 -0
  653. package/tests/unit/shared/modals/InstructionConfirmModal.test.ts +305 -0
  654. package/tests/unit/utils/agent.test.ts +395 -0
  655. package/tests/unit/utils/animationFrame.test.ts +59 -0
  656. package/tests/unit/utils/browser.test.ts +73 -0
  657. package/tests/unit/utils/canvas.test.ts +54 -0
  658. package/tests/unit/utils/claudeCli.test.ts +294 -0
  659. package/tests/unit/utils/cliBinaryLocator.test.ts +33 -0
  660. package/tests/unit/utils/context.test.ts +288 -0
  661. package/tests/unit/utils/contextMentionResolver.test.ts +270 -0
  662. package/tests/unit/utils/date.test.ts +80 -0
  663. package/tests/unit/utils/diff.test.ts +291 -0
  664. package/tests/unit/utils/editor.test.ts +249 -0
  665. package/tests/unit/utils/electronCompat.test.ts +87 -0
  666. package/tests/unit/utils/env.test.ts +1240 -0
  667. package/tests/unit/utils/externalContext.test.ts +336 -0
  668. package/tests/unit/utils/externalContextScanner.test.ts +186 -0
  669. package/tests/unit/utils/fileLink.dom.test.ts +273 -0
  670. package/tests/unit/utils/fileLink.handler.test.ts +64 -0
  671. package/tests/unit/utils/fileLink.test.ts +233 -0
  672. package/tests/unit/utils/frontmatter.test.ts +434 -0
  673. package/tests/unit/utils/imageEmbed.test.ts +407 -0
  674. package/tests/unit/utils/inlineEdit.test.ts +63 -0
  675. package/tests/unit/utils/interrupt.test.ts +73 -0
  676. package/tests/unit/utils/markdown.test.ts +35 -0
  677. package/tests/unit/utils/markdownMath.test.ts +54 -0
  678. package/tests/unit/utils/mcp.test.ts +256 -0
  679. package/tests/unit/utils/obsidianCompat.test.ts +18 -0
  680. package/tests/unit/utils/path.test.ts +677 -0
  681. package/tests/unit/utils/sdkSession.test.ts +2359 -0
  682. package/tests/unit/utils/session.test.ts +971 -0
  683. package/tests/unit/utils/slashCommand.test.ts +778 -0
  684. package/tests/unit/utils/utils.test.ts +809 -0
  685. package/tsconfig.jest.json +8 -0
  686. package/tsconfig.json +26 -0
  687. package/versions.json +4 -0
@@ -0,0 +1,119 @@
1
+ import { extractMcpMentions, transformMcpMentions } from '../../utils/mcp';
2
+ import type { ManagedMcpServer, McpServerConfig } from '../types';
3
+
4
+ /** Storage interface for loading MCP servers. */
5
+ export interface McpStorageAdapter {
6
+ load(): Promise<ManagedMcpServer[]>;
7
+ }
8
+
9
+ export class McpServerManager {
10
+ private servers: ManagedMcpServer[] = [];
11
+ private storage: McpStorageAdapter;
12
+
13
+ constructor(storage: McpStorageAdapter) {
14
+ this.storage = storage;
15
+ }
16
+
17
+ async loadServers(): Promise<void> {
18
+ this.servers = await this.storage.load();
19
+ }
20
+
21
+ getServers(): ManagedMcpServer[] {
22
+ return this.servers;
23
+ }
24
+
25
+ getEnabledCount(): number {
26
+ return this.servers.filter((s) => s.enabled).length;
27
+ }
28
+
29
+ /**
30
+ * Get servers to include in SDK options.
31
+ *
32
+ * A server is included if:
33
+ * - It is enabled AND
34
+ * - Either context-saving is disabled OR the server is @-mentioned
35
+ *
36
+ * @param mentionedNames Set of server names that were @-mentioned in the prompt
37
+ */
38
+ getActiveServers(mentionedNames: Set<string>): Record<string, McpServerConfig> {
39
+ const result: Record<string, McpServerConfig> = {};
40
+
41
+ for (const server of this.servers) {
42
+ if (!server.enabled) continue;
43
+
44
+ // If context-saving is enabled, only include if @-mentioned
45
+ if (server.contextSaving && !mentionedNames.has(server.name)) {
46
+ continue;
47
+ }
48
+
49
+ result[server.name] = server.config;
50
+ }
51
+
52
+ return result;
53
+ }
54
+
55
+ /**
56
+ * Get disabled MCP tools formatted for SDK disallowedTools option.
57
+ *
58
+ * Only returns disabled tools from servers that would be active (same filter as getActiveServers).
59
+ *
60
+ * @param mentionedNames Set of server names that were @-mentioned in the prompt
61
+ */
62
+ getDisallowedMcpTools(mentionedNames: Set<string>): string[] {
63
+ return this.collectDisallowedTools(
64
+ (s) => !s.contextSaving || mentionedNames.has(s.name)
65
+ );
66
+ }
67
+
68
+ /**
69
+ * Get all disabled MCP tools from ALL enabled servers (ignoring @-mentions).
70
+ *
71
+ * Used for persistent queries to pre-register all disabled tools upfront,
72
+ * so @-mentioning servers doesn't require cold start.
73
+ */
74
+ getAllDisallowedMcpTools(): string[] {
75
+ return this.collectDisallowedTools().sort();
76
+ }
77
+
78
+ private collectDisallowedTools(filter?: (server: ManagedMcpServer) => boolean): string[] {
79
+ const disallowed = new Set<string>();
80
+
81
+ for (const server of this.servers) {
82
+ if (!server.enabled) continue;
83
+ if (filter && !filter(server)) continue;
84
+ if (!server.disabledTools || server.disabledTools.length === 0) continue;
85
+
86
+ for (const tool of server.disabledTools) {
87
+ const normalized = tool.trim();
88
+ if (!normalized) continue;
89
+ disallowed.add(`mcp__${server.name}__${normalized}`);
90
+ }
91
+ }
92
+
93
+ return Array.from(disallowed);
94
+ }
95
+
96
+ hasServers(): boolean {
97
+ return this.servers.length > 0;
98
+ }
99
+
100
+ getContextSavingServers(): ManagedMcpServer[] {
101
+ return this.servers.filter((s) => s.enabled && s.contextSaving);
102
+ }
103
+
104
+ private getContextSavingNames(): Set<string> {
105
+ return new Set(this.getContextSavingServers().map((s) => s.name));
106
+ }
107
+
108
+ /** Only matches against enabled servers with context-saving mode. */
109
+ extractMentions(text: string): Set<string> {
110
+ return extractMcpMentions(text, this.getContextSavingNames());
111
+ }
112
+
113
+ /**
114
+ * Appends " MCP" after each valid @mention. Applied to API requests only, not shown in UI.
115
+ */
116
+ transformMentions(text: string): string {
117
+ return transformMcpMentions(text, this.getContextSavingNames());
118
+ }
119
+ }
@@ -0,0 +1,310 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client';
2
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio';
3
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp';
4
+ import type { Transport } from '@modelcontextprotocol/sdk/shared/transport';
5
+ import * as http from 'http';
6
+ import * as https from 'https';
7
+
8
+ import { getEnhancedPath } from '../../utils/env';
9
+ import { parseCommand } from '../../utils/mcp';
10
+ import type { ManagedMcpServer } from '../types';
11
+ import { getMcpServerType } from '../types';
12
+
13
+ export interface McpTool {
14
+ name: string;
15
+ description?: string;
16
+ inputSchema?: Record<string, unknown>;
17
+ }
18
+
19
+ export interface McpTestResult {
20
+ success: boolean;
21
+ serverName?: string;
22
+ serverVersion?: string;
23
+ tools: McpTool[];
24
+ error?: string;
25
+ }
26
+
27
+ interface UrlServerConfig {
28
+ url: string;
29
+ headers?: Record<string, string>;
30
+ }
31
+
32
+ type StreamableHttpTransportOptions = ConstructorParameters<typeof StreamableHTTPClientTransport>[1];
33
+ type LegacySseTransportConstructor = new (
34
+ url: URL,
35
+ options?: StreamableHttpTransportOptions,
36
+ ) => Transport;
37
+
38
+ function createLegacySseTransport(url: URL, options: StreamableHttpTransportOptions): Transport {
39
+ // eslint-disable-next-line @typescript-eslint/no-require-imports -- Legacy SSE MCP servers still need the SDK's deprecated compatibility transport.
40
+ const module = require('@modelcontextprotocol/sdk/client/sse') as {
41
+ SSEClientTransport: LegacySseTransportConstructor;
42
+ };
43
+ return new module.SSEClientTransport(url, options);
44
+ }
45
+
46
+ /**
47
+ * Use Node's HTTP stack for MCP server verification to avoid renderer CORS restrictions.
48
+ * We still rely on official SDK transports for MCP protocol semantics.
49
+ */
50
+ export function createNodeFetch(): (input: string | URL | Request, init?: RequestInit) => Promise<Response> {
51
+ return async (input: string | URL | Request, init?: RequestInit): Promise<Response> => {
52
+ const requestUrl = getRequestUrl(input);
53
+ const method = init?.method ?? (input instanceof Request ? input.method : 'GET');
54
+ const headers = mergeHeaders(input, init);
55
+ const signal = init?.signal ?? (input instanceof Request ? input.signal : undefined);
56
+ const body = await getRequestBody(init?.body ?? (input instanceof Request ? input.body : undefined));
57
+ const transport = requestUrl.protocol === 'https:' ? https : http;
58
+
59
+ return new Promise<Response>((resolve, reject) => {
60
+ let settled = false;
61
+
62
+ const fail = (error: unknown) => {
63
+ if (settled) return;
64
+ settled = true;
65
+ signal?.removeEventListener('abort', onAbort);
66
+ reject(error instanceof Error ? error : new Error(String(error)));
67
+ };
68
+
69
+ const onAbort = () => {
70
+ req.destroy(new Error('Request aborted'));
71
+ fail(signal?.reason ?? new Error('Request aborted'));
72
+ };
73
+
74
+ const requestHeaders: Record<string, string> = {};
75
+ headers.forEach((value, key) => {
76
+ requestHeaders[key] = value;
77
+ });
78
+ if (body) {
79
+ requestHeaders['content-length'] = String(body.byteLength);
80
+ }
81
+
82
+ const req = transport.request(
83
+ requestUrl,
84
+ {
85
+ method,
86
+ headers: requestHeaders,
87
+ },
88
+ (res: http.IncomingMessage) => {
89
+ if (settled) return;
90
+ settled = true;
91
+ signal?.removeEventListener('abort', onAbort);
92
+ resolve(createFetchResponse(res) as Response);
93
+ },
94
+ );
95
+
96
+ req.on('error', (error: Error) => fail(error));
97
+
98
+ if (signal) {
99
+ if (signal.aborted) {
100
+ onAbort();
101
+ return;
102
+ }
103
+ signal.addEventListener('abort', onAbort, { once: true });
104
+ }
105
+
106
+ if (body) {
107
+ req.end(body);
108
+ } else {
109
+ req.end();
110
+ }
111
+ });
112
+ };
113
+ }
114
+
115
+ interface MinimalFetchResponse {
116
+ ok: boolean;
117
+ status: number;
118
+ statusText: string;
119
+ headers: Headers;
120
+ body: ReadableStream<Uint8Array> | null;
121
+ text: () => Promise<string>;
122
+ json: () => Promise<unknown>;
123
+ }
124
+
125
+ function createFetchResponse(res: http.IncomingMessage): MinimalFetchResponse {
126
+ const responseHeaders = new Headers();
127
+ for (const [key, value] of Object.entries(res.headers)) {
128
+ if (value === undefined) continue;
129
+ if (Array.isArray(value)) {
130
+ for (const headerValue of value) {
131
+ responseHeaders.append(key, headerValue);
132
+ }
133
+ } else {
134
+ responseHeaders.append(key, value);
135
+ }
136
+ }
137
+
138
+ const body = new ReadableStream<Uint8Array>({
139
+ start(controller) {
140
+ res.on('data', (chunk: Buffer | string) => {
141
+ const buffer = typeof chunk === 'string' ? Buffer.from(chunk) : chunk;
142
+ controller.enqueue(new Uint8Array(buffer));
143
+ });
144
+ res.on('end', () => controller.close());
145
+ res.on('error', (error: Error) => controller.error(error));
146
+ },
147
+ cancel(reason?: unknown) {
148
+ res.destroy(reason instanceof Error ? reason : new Error('Response body cancelled'));
149
+ },
150
+ });
151
+
152
+ let bodyUsed = false;
153
+ const readAsText = async (): Promise<string> => {
154
+ if (bodyUsed) {
155
+ throw new TypeError('Body has already been consumed');
156
+ }
157
+ bodyUsed = true;
158
+ const reader = body.getReader();
159
+ const chunks: Uint8Array[] = [];
160
+ let total = 0;
161
+ let done = false;
162
+ try {
163
+ while (!done) {
164
+ const { value, done: streamDone } = await reader.read();
165
+ done = streamDone;
166
+ if (done) break;
167
+ if (value) {
168
+ chunks.push(value);
169
+ total += value.byteLength;
170
+ }
171
+ }
172
+ } finally {
173
+ reader.releaseLock();
174
+ }
175
+
176
+ const merged = new Uint8Array(total);
177
+ let offset = 0;
178
+ for (const chunk of chunks) {
179
+ merged.set(chunk, offset);
180
+ offset += chunk.byteLength;
181
+ }
182
+ return new TextDecoder().decode(merged);
183
+ };
184
+
185
+ return {
186
+ ok: (res.statusCode ?? 500) >= 200 && (res.statusCode ?? 500) < 300,
187
+ status: res.statusCode ?? 500,
188
+ statusText: res.statusMessage ?? '',
189
+ headers: responseHeaders,
190
+ body,
191
+ text: readAsText,
192
+ json: async () => {
193
+ const parsed: unknown = JSON.parse(await readAsText());
194
+ return parsed;
195
+ },
196
+ };
197
+ }
198
+
199
+ function getRequestUrl(input: string | URL | Request): URL {
200
+ if (input instanceof URL) {
201
+ return input;
202
+ }
203
+ if (typeof input === 'string') {
204
+ return new URL(input);
205
+ }
206
+ return new URL(input.url);
207
+ }
208
+
209
+ function mergeHeaders(input: string | URL | Request, init?: RequestInit): Headers {
210
+ const headers = new Headers(input instanceof Request ? input.headers : undefined);
211
+ if (init?.headers) {
212
+ const initHeaders = new Headers(init.headers);
213
+ initHeaders.forEach((value, key) => {
214
+ headers.set(key, value);
215
+ });
216
+ }
217
+ return headers;
218
+ }
219
+
220
+ async function getRequestBody(body: BodyInit | null | undefined): Promise<Buffer | undefined> {
221
+ if (body === undefined || body === null) {
222
+ return undefined;
223
+ }
224
+
225
+ const serialized = await new Response(body).arrayBuffer();
226
+ return Buffer.from(serialized);
227
+ }
228
+
229
+ const nodeFetch = createNodeFetch();
230
+
231
+ export async function testMcpServer(server: ManagedMcpServer): Promise<McpTestResult> {
232
+ const type = getMcpServerType(server.config);
233
+
234
+ let transport: Transport;
235
+ try {
236
+ if (type === 'stdio') {
237
+ const config = server.config as { command: string; args?: string[]; env?: Record<string, string> };
238
+ const { cmd, args } = parseCommand(config.command, config.args);
239
+ if (!cmd) {
240
+ return { success: false, tools: [], error: 'Missing command' };
241
+ }
242
+ transport = new StdioClientTransport({
243
+ command: cmd,
244
+ args,
245
+ env: { ...process.env, ...config.env, PATH: getEnhancedPath(config.env?.PATH) },
246
+ stderr: 'ignore',
247
+ });
248
+ } else {
249
+ const config = server.config as UrlServerConfig;
250
+ const url = new URL(config.url);
251
+ const options = {
252
+ fetch: nodeFetch,
253
+ requestInit: config.headers ? { headers: config.headers } : undefined,
254
+ };
255
+ transport = type === 'sse'
256
+ ? createLegacySseTransport(url, options)
257
+ : new StreamableHTTPClientTransport(url, options);
258
+ }
259
+ } catch (error) {
260
+ return {
261
+ success: false,
262
+ tools: [],
263
+ error: error instanceof Error ? error.message : 'Invalid server configuration',
264
+ };
265
+ }
266
+
267
+ const client = new Client({ name: 'claudian-tester', version: '1.0.0' });
268
+ const controller = new AbortController();
269
+ const timeout = window.setTimeout(() => controller.abort(), 10000);
270
+
271
+ try {
272
+ await client.connect(transport, { signal: controller.signal });
273
+
274
+ const serverVersion = client.getServerVersion();
275
+ let tools: McpTool[] = [];
276
+ try {
277
+ const result = await client.listTools(undefined, { signal: controller.signal });
278
+ tools = result.tools.map((t: { name: string; description?: string; inputSchema?: Record<string, unknown> }) => ({
279
+ name: t.name,
280
+ description: t.description,
281
+ inputSchema: t.inputSchema as Record<string, unknown>,
282
+ }));
283
+ } catch {
284
+ // listTools failure after successful connect = partial success
285
+ }
286
+
287
+ return {
288
+ success: true,
289
+ serverName: serverVersion?.name,
290
+ serverVersion: serverVersion?.version,
291
+ tools,
292
+ };
293
+ } catch (error) {
294
+ if (controller.signal.aborted) {
295
+ return { success: false, tools: [], error: 'Connection timeout (10s)' };
296
+ }
297
+ return {
298
+ success: false,
299
+ tools: [],
300
+ error: error instanceof Error ? error.message : 'Unknown error',
301
+ };
302
+ } finally {
303
+ window.clearTimeout(timeout);
304
+ try {
305
+ await client.close();
306
+ } catch {
307
+ // Ignore close errors
308
+ }
309
+ }
310
+ }
@@ -0,0 +1,252 @@
1
+ import { appendContextFiles } from '../../utils/context';
2
+ import { getTodayDate } from '../../utils/date';
3
+ import type {
4
+ InlineEditCursorRequest,
5
+ InlineEditRequest,
6
+ InlineEditResult,
7
+ } from '../providers/types';
8
+
9
+ export function parseInlineEditResponse(responseText: string): InlineEditResult {
10
+ const replacementMatch = responseText.match(/<replacement>([\s\S]*?)<\/replacement>/);
11
+ if (replacementMatch) {
12
+ return { success: true, editedText: replacementMatch[1] };
13
+ }
14
+
15
+ const insertionMatch = responseText.match(/<insertion>([\s\S]*?)<\/insertion>/);
16
+ if (insertionMatch) {
17
+ return { success: true, insertedText: insertionMatch[1] };
18
+ }
19
+
20
+ const trimmed = responseText.trim();
21
+ if (trimmed) {
22
+ return { success: true, clarification: trimmed };
23
+ }
24
+
25
+ return { success: false, error: 'Empty response' };
26
+ }
27
+
28
+ function buildCursorPrompt(request: InlineEditCursorRequest): string {
29
+ const ctx = request.cursorContext;
30
+ const lineAttr = ` line="${ctx.line + 1}"`;
31
+
32
+ let cursorContent: string;
33
+ if (ctx.isInbetween) {
34
+ const parts = [];
35
+ if (ctx.beforeCursor) parts.push(ctx.beforeCursor);
36
+ parts.push('| #inbetween');
37
+ if (ctx.afterCursor) parts.push(ctx.afterCursor);
38
+ cursorContent = parts.join('\n');
39
+ } else {
40
+ cursorContent = `${ctx.beforeCursor}|${ctx.afterCursor} #inline`;
41
+ }
42
+
43
+ return [
44
+ request.instruction,
45
+ '',
46
+ `<editor_cursor path="${request.notePath}"${lineAttr}>`,
47
+ cursorContent,
48
+ '</editor_cursor>',
49
+ ].join('\n');
50
+ }
51
+
52
+ export function buildInlineEditPrompt(request: InlineEditRequest): string {
53
+ let prompt: string;
54
+
55
+ if (request.mode === 'cursor') {
56
+ prompt = buildCursorPrompt(request);
57
+ } else {
58
+ const lineAttr = request.startLine && request.lineCount
59
+ ? ` lines="${request.startLine}-${request.startLine + request.lineCount - 1}"`
60
+ : '';
61
+ prompt = [
62
+ request.instruction,
63
+ '',
64
+ `<editor_selection path="${request.notePath}"${lineAttr}>`,
65
+ request.selectedText,
66
+ '</editor_selection>',
67
+ ].join('\n');
68
+ }
69
+
70
+ if (request.contextFiles && request.contextFiles.length > 0) {
71
+ prompt = appendContextFiles(prompt, request.contextFiles);
72
+ }
73
+
74
+ return prompt;
75
+ }
76
+
77
+ export function getInlineEditSystemPrompt(): string {
78
+ const pathRules = '- **Paths**: Must be RELATIVE to vault root (e.g., "notes/file.md").';
79
+
80
+ return `Today is ${getTodayDate()}.
81
+
82
+ You are **Claudian**, an expert editor and writing assistant embedded in Obsidian. You help users refine their text, answer questions, and generate content with high precision.
83
+
84
+ ## Core Directives
85
+
86
+ 1. **Style Matching**: Mimic the user's tone, voice, and formatting style (indentation, bullet points, capitalization).
87
+ 2. **Context Awareness**: Always Read the full file (or significant context) to understand the broader topic before editing. Do not rely solely on the selection.
88
+ 3. **Silent Execution**: Use tools (Read, WebSearch) silently. Your final output must be ONLY the result.
89
+ 4. **No Fluff**: No pleasantries, no "Here is the text", no "I have updated...". Just the content.
90
+
91
+ ## Input Format
92
+
93
+ User messages have the instruction first, followed by XML context tags:
94
+
95
+ ### Selection Mode
96
+ \`\`\`
97
+ user's instruction
98
+
99
+ <editor_selection path="path/to/file.md">
100
+ selected text here
101
+ </editor_selection>
102
+ \`\`\`
103
+ Use \`<replacement>\` tags for edits.
104
+
105
+ ### Cursor Mode
106
+ \`\`\`
107
+ user's instruction
108
+
109
+ <editor_cursor path="path/to/file.md">
110
+ text before|text after #inline
111
+ </editor_cursor>
112
+ \`\`\`
113
+ Or between paragraphs:
114
+ \`\`\`
115
+ user's instruction
116
+
117
+ <editor_cursor path="path/to/file.md">
118
+ Previous paragraph
119
+ | #inbetween
120
+ Next paragraph
121
+ </editor_cursor>
122
+ \`\`\`
123
+ Use \`<insertion>\` tags to insert new content at the cursor position (\`|\`).
124
+
125
+ ## Tools & Path Rules
126
+
127
+ - **Tools**: Read, Grep, Glob, LS, WebSearch, WebFetch. (All read-only).
128
+ ${pathRules}
129
+
130
+ ## Thinking Process
131
+
132
+ Before generating the final output, mentally check:
133
+ 1. **Context**: Have I read enough of the file to understand the *topic* and *structure*?
134
+ 2. **Style**: What is the user's indentation (2 vs 4 spaces, tabs)? What is their tone?
135
+ 3. **Type**: Is this **Prose** (flow, grammar, clarity) or **Code** (syntax, logic, variable names)?
136
+ - *Prose*: Ensure smooth transitions.
137
+ - *Code*: Preserve syntax validity; do not break surrounding brackets/indentation.
138
+
139
+ ## Output Rules - CRITICAL
140
+
141
+ **ABSOLUTE RULE**: Your text output must contain ONLY the final answer, replacement, or insertion. NEVER output:
142
+ - "I'll read the file..." / "Let me check..." / "I will..."
143
+ - "I'm asked about..." / "The user wants..."
144
+ - "Based on my analysis..." / "After reading..."
145
+ - "Here's..." / "The answer is..."
146
+ - ANY announcement of what you're about to do or did
147
+
148
+ Use tools silently. Your text output = final result only.
149
+
150
+ ### When Replacing Selected Text (Selection Mode)
151
+
152
+ If the user wants to MODIFY or REPLACE the selected text, wrap the replacement in <replacement> tags:
153
+
154
+ <replacement>your replacement text here</replacement>
155
+
156
+ The content inside the tags should be ONLY the replacement text - no explanation.
157
+
158
+ ### When Inserting at Cursor (Cursor Mode)
159
+
160
+ If the user wants to INSERT new content at the cursor position, wrap the insertion in <insertion> tags:
161
+
162
+ <insertion>your inserted text here</insertion>
163
+
164
+ The content inside the tags should be ONLY the text to insert - no explanation.
165
+
166
+ ### When Answering Questions or Providing Information
167
+
168
+ If the user is asking a QUESTION, respond WITHOUT tags. Output the answer directly.
169
+
170
+ WRONG: "I'll read the full context of this file to give you a better explanation. This is a guide about..."
171
+ CORRECT: "This is a guide about..."
172
+
173
+ ### When Clarification is Needed
174
+
175
+ If the request is ambiguous, ask a clarifying question. Keep questions concise and specific.
176
+
177
+ ## Examples
178
+
179
+ ### Selection Mode
180
+ Input:
181
+ \`\`\`
182
+ translate to French
183
+
184
+ <editor_selection path="notes/readme.md">
185
+ Hello world
186
+ </editor_selection>
187
+ \`\`\`
188
+
189
+ CORRECT (replacement):
190
+ <replacement>Bonjour le monde</replacement>
191
+
192
+ Input:
193
+ \`\`\`
194
+ what does this do?
195
+
196
+ <editor_selection path="notes/code.md">
197
+ const x = arr.reduce((a, b) => a + b, 0);
198
+ </editor_selection>
199
+ \`\`\`
200
+
201
+ CORRECT (question - no tags):
202
+ This code sums all numbers in the array \`arr\`. It uses \`reduce\` to iterate through the array, accumulating the total starting from 0.
203
+
204
+ ### Cursor Mode
205
+
206
+ Input:
207
+ \`\`\`
208
+ what animal?
209
+
210
+ <editor_cursor path="notes/draft.md">
211
+ The quick brown | jumps over the lazy dog. #inline
212
+ </editor_cursor>
213
+ \`\`\`
214
+
215
+ CORRECT (insertion):
216
+ <insertion>fox</insertion>
217
+
218
+ ### Q&A
219
+ Input:
220
+ \`\`\`
221
+ add a brief description section
222
+
223
+ <editor_cursor path="notes/readme.md">
224
+ # Introduction
225
+ This is my project.
226
+ | #inbetween
227
+ ## Features
228
+ </editor_cursor>
229
+ \`\`\`
230
+
231
+ CORRECT (insertion):
232
+ <insertion>
233
+ ## Description
234
+
235
+ This project provides tools for managing your notes efficiently.
236
+ </insertion>
237
+
238
+ Input:
239
+ \`\`\`
240
+ translate to Spanish
241
+
242
+ <editor_selection path="notes/draft.md">
243
+ The bank was steep.
244
+ </editor_selection>
245
+ \`\`\`
246
+
247
+ CORRECT (asking for clarification):
248
+ "Bank" can mean a financial institution (banco) or a river bank (orilla). Which meaning should I use?
249
+
250
+ Then after user clarifies "river bank":
251
+ <replacement>La orilla era empinada.</replacement>`;
252
+ }