@within-7/minto 0.1.7 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.js +155 -37
- package/dist/Tool.js +38 -0
- package/dist/Tool.js.map +3 -3
- package/dist/commands/agents/AgentsCommand.js +73 -49
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/constants.js +1 -1
- package/dist/commands/agents/constants.js.map +1 -1
- package/dist/commands/agents/index.js +1 -1
- package/dist/commands/bug.js +74 -7
- package/dist/commands/bug.js.map +3 -3
- package/dist/commands/clear.js +3 -0
- package/dist/commands/clear.js.map +2 -2
- package/dist/commands/compact.js +37 -0
- package/dist/commands/compact.js.map +2 -2
- package/dist/commands/context.js +85 -0
- package/dist/commands/context.js.map +7 -0
- package/dist/commands/ctx_viz.js +18 -10
- package/dist/commands/ctx_viz.js.map +2 -2
- package/dist/commands/doctor.js +158 -12
- package/dist/commands/doctor.js.map +2 -2
- package/dist/commands/export.js +157 -0
- package/dist/commands/export.js.map +7 -0
- package/dist/commands/mcp-interactive.js +28 -18
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +9 -7
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/permissions.js +87 -0
- package/dist/commands/permissions.js.map +7 -0
- package/dist/commands/plugin/AddMarketplaceForm.js +3 -2
- package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
- package/dist/commands/plugin/ConfirmDialog.js +2 -1
- package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
- package/dist/commands/plugin/ErrorView.js +2 -1
- package/dist/commands/plugin/ErrorView.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js +5 -4
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsManager.js +5 -4
- package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
- package/dist/commands/plugin/MainMenu.js +2 -1
- package/dist/commands/plugin/MainMenu.js.map +2 -2
- package/dist/commands/plugin/MarketplaceManager.js +5 -4
- package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
- package/dist/commands/plugin/MarketplaceSelector.js +4 -3
- package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
- package/dist/commands/plugin/PlaceholderScreen.js +3 -2
- package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
- package/dist/commands/plugin/PluginBrowser.js +6 -5
- package/dist/commands/plugin/PluginBrowser.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsInstall.js +5 -4
- package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsManage.js +4 -3
- package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
- package/dist/commands/plugin.js +16 -15
- package/dist/commands/plugin.js.map +2 -2
- package/dist/commands/quit.js +3 -1
- package/dist/commands/quit.js.map +2 -2
- package/dist/commands/sandbox.js +105 -0
- package/dist/commands/sandbox.js.map +7 -0
- package/dist/commands/setup.js +2 -1
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/status.js +59 -0
- package/dist/commands/status.js.map +7 -0
- package/dist/commands/tasks.js +108 -0
- package/dist/commands/tasks.js.map +7 -0
- package/dist/commands/todos.js +123 -0
- package/dist/commands/todos.js.map +7 -0
- package/dist/commands/undo.js +245 -0
- package/dist/commands/undo.js.map +7 -0
- package/dist/commands.js +22 -2
- package/dist/commands.js.map +2 -2
- package/dist/components/AgentThinkingBlock.js +10 -18
- package/dist/components/AgentThinkingBlock.js.map +2 -2
- package/dist/components/AsciiLogo.js +7 -8
- package/dist/components/AsciiLogo.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/QuestionView.js +2 -1
- package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
- package/dist/components/BackgroundTasksPanel.js +78 -29
- package/dist/components/BackgroundTasksPanel.js.map +2 -2
- package/dist/components/BashStreamingProgress.js +24 -0
- package/dist/components/BashStreamingProgress.js.map +7 -0
- package/dist/components/CollapsibleHint.js +15 -0
- package/dist/components/CollapsibleHint.js.map +7 -0
- package/dist/components/Config.js +3 -2
- package/dist/components/Config.js.map +2 -2
- package/dist/components/ConsoleOAuthFlow.js +2 -1
- package/dist/components/ConsoleOAuthFlow.js.map +2 -2
- package/dist/components/Cost.js +2 -1
- package/dist/components/Cost.js.map +2 -2
- package/dist/components/FileEditToolUpdatedMessage.js +1 -1
- package/dist/components/FileEditToolUpdatedMessage.js.map +2 -2
- package/dist/components/HeaderBar.js +13 -8
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/HistorySearchOverlay.js +4 -3
- package/dist/components/HistorySearchOverlay.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +134 -0
- package/dist/components/HotkeyHelpPanel.js.map +7 -0
- package/dist/components/InvalidConfigDialog.js +2 -1
- package/dist/components/InvalidConfigDialog.js.map +2 -2
- package/dist/components/Logo.js +24 -68
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/MCPServerApprovalDialog.js +2 -1
- package/dist/components/MCPServerApprovalDialog.js.map +2 -2
- package/dist/components/MCPServerDialogCopy.js +2 -1
- package/dist/components/MCPServerDialogCopy.js.map +2 -2
- package/dist/components/MCPServerMultiselectDialog.js +2 -1
- package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
- package/dist/components/Message.js +23 -7
- package/dist/components/Message.js.map +3 -3
- package/dist/components/MessageSelector.js +4 -3
- package/dist/components/MessageSelector.js.map +2 -2
- package/dist/components/ModeIndicator.js +2 -1
- package/dist/components/ModeIndicator.js.map +2 -2
- package/dist/components/ModelConfig.js +20 -6
- package/dist/components/ModelConfig.js.map +2 -2
- package/dist/components/ModelListManager.js +7 -6
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/ModelSelector/ModelSelector.js +27 -14
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/Onboarding.js +22 -16
- package/dist/components/Onboarding.js.map +2 -2
- package/dist/components/OperationSummary.js +130 -0
- package/dist/components/OperationSummary.js.map +7 -0
- package/dist/components/ProgressBar.js +74 -0
- package/dist/components/ProgressBar.js.map +7 -0
- package/dist/components/PromptInput.js +210 -87
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/RequestStatusIndicator.js +194 -0
- package/dist/components/RequestStatusIndicator.js.map +7 -0
- package/dist/components/SensitiveFileWarning.js +31 -0
- package/dist/components/SensitiveFileWarning.js.map +7 -0
- package/dist/components/Spinner.js +141 -27
- package/dist/components/Spinner.js.map +2 -2
- package/dist/components/SpinnerSymbol.js +21 -27
- package/dist/components/SpinnerSymbol.js.map +2 -2
- package/dist/components/StreamingBashOutput.js +9 -8
- package/dist/components/StreamingBashOutput.js.map +2 -2
- package/dist/components/StructuredDiff.js +6 -8
- package/dist/components/StructuredDiff.js.map +2 -2
- package/dist/components/SubagentBlock.js +5 -3
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/SubagentProgress.js +17 -15
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TaskCard.js +30 -24
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TextInput.js +9 -1
- package/dist/components/TextInput.js.map +2 -2
- package/dist/components/TodoChangeBlock.js +1 -1
- package/dist/components/TodoChangeBlock.js.map +2 -2
- package/dist/components/TodoPanel.js +140 -31
- package/dist/components/TodoPanel.js.map +3 -3
- package/dist/components/TokenCounter.js +74 -0
- package/dist/components/TokenCounter.js.map +7 -0
- package/dist/components/TokenWarning.js +2 -1
- package/dist/components/TokenWarning.js.map +2 -2
- package/dist/components/ToolUseLoader.js +2 -2
- package/dist/components/ToolUseLoader.js.map +2 -2
- package/dist/components/TreeConnector.js +26 -0
- package/dist/components/TreeConnector.js.map +7 -0
- package/dist/components/TrustDialog.js +2 -1
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/TurnCompletionIndicator.js +18 -0
- package/dist/components/TurnCompletionIndicator.js.map +7 -0
- package/dist/components/binary-feedback/BinaryFeedbackView.js +2 -1
- package/dist/components/binary-feedback/BinaryFeedbackView.js.map +2 -2
- package/dist/components/messages/AssistantTextMessage.js +20 -9
- package/dist/components/messages/AssistantTextMessage.js.map +2 -2
- package/dist/components/messages/AssistantThinkingMessage.js +18 -3
- package/dist/components/messages/AssistantThinkingMessage.js.map +2 -2
- package/dist/components/messages/AssistantToolUseMessage.js +17 -10
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/GroupRenderer.js +54 -0
- package/dist/components/messages/GroupRenderer.js.map +7 -0
- package/dist/components/messages/NestedTasksPreview.js +24 -0
- package/dist/components/messages/NestedTasksPreview.js.map +7 -0
- package/dist/components/messages/ParallelTasksGroupView.js +93 -0
- package/dist/components/messages/ParallelTasksGroupView.js.map +7 -0
- package/dist/components/messages/TaskInModuleView.js +218 -0
- package/dist/components/messages/TaskInModuleView.js.map +7 -0
- package/dist/components/messages/TaskOutputContent.js +56 -0
- package/dist/components/messages/TaskOutputContent.js.map +7 -0
- package/dist/components/messages/UserPromptMessage.js +2 -2
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +2 -3
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
- package/dist/components/permissions/FallbackPermissionRequest.js +4 -4
- package/dist/components/permissions/FallbackPermissionRequest.js.map +2 -2
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +4 -4
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +2 -2
- package/dist/constants/colors.js +120 -54
- package/dist/constants/colors.js.map +2 -2
- package/dist/constants/formatRules.js +102 -0
- package/dist/constants/formatRules.js.map +7 -0
- package/dist/constants/prompts.js +12 -34
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/symbols.js +64 -6
- package/dist/constants/symbols.js.map +2 -2
- package/dist/constants/timing.js +5 -0
- package/dist/constants/timing.js.map +2 -2
- package/dist/constants/toolInputExamples.js +84 -0
- package/dist/constants/toolInputExamples.js.map +7 -0
- package/dist/core/backupManager.js +321 -0
- package/dist/core/backupManager.js.map +7 -0
- package/dist/core/config/defaults.js +84 -0
- package/dist/core/config/defaults.js.map +7 -0
- package/dist/core/config/index.js +111 -0
- package/dist/core/config/index.js.map +7 -0
- package/dist/core/config/loader.js +221 -0
- package/dist/core/config/loader.js.map +7 -0
- package/dist/core/config/migrations.js +128 -0
- package/dist/core/config/migrations.js.map +7 -0
- package/dist/core/config/schema.js +178 -0
- package/dist/core/config/schema.js.map +7 -0
- package/dist/core/costTracker.js +129 -0
- package/dist/core/costTracker.js.map +7 -0
- package/dist/core/gitAutoCommit.js +287 -0
- package/dist/core/gitAutoCommit.js.map +7 -0
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +7 -0
- package/dist/core/operationTracker.js +212 -0
- package/dist/core/operationTracker.js.map +7 -0
- package/dist/core/permissions/auditLog.js +204 -0
- package/dist/core/permissions/auditLog.js.map +7 -0
- package/dist/core/permissions/engine/index.js +3 -0
- package/dist/core/permissions/engine/index.js.map +7 -0
- package/dist/core/permissions/engine/permissionEngine.js +106 -0
- package/dist/core/permissions/engine/permissionEngine.js.map +7 -0
- package/dist/core/permissions/engine/types.js +1 -0
- package/dist/core/permissions/engine/types.js.map +7 -0
- package/dist/core/permissions/index.js +84 -0
- package/dist/core/permissions/index.js.map +7 -0
- package/dist/core/permissions/ruleEngine.js +259 -0
- package/dist/core/permissions/ruleEngine.js.map +7 -0
- package/dist/core/permissions/rules/allowedToolsRule.js +62 -0
- package/dist/core/permissions/rules/allowedToolsRule.js.map +7 -0
- package/dist/core/permissions/rules/autoEscalationRule.js +296 -0
- package/dist/core/permissions/rules/autoEscalationRule.js.map +7 -0
- package/dist/core/permissions/rules/index.js +46 -0
- package/dist/core/permissions/rules/index.js.map +7 -0
- package/dist/core/permissions/rules/planModeRule.js +55 -0
- package/dist/core/permissions/rules/planModeRule.js.map +7 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js +173 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js.map +7 -0
- package/dist/core/permissions/rules/safeModeRule.js +65 -0
- package/dist/core/permissions/rules/safeModeRule.js.map +7 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js +345 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js.map +7 -0
- package/dist/core/permissions/types.js +127 -0
- package/dist/core/permissions/types.js.map +7 -0
- package/dist/core/tokenStats.js +9 -0
- package/dist/core/tokenStats.js.map +7 -0
- package/dist/core/tokenStatsManager.js +331 -0
- package/dist/core/tokenStatsManager.js.map +7 -0
- package/dist/core/tools/executor.js +143 -0
- package/dist/core/tools/executor.js.map +7 -0
- package/dist/core/tools/index.js +15 -0
- package/dist/core/tools/index.js.map +7 -0
- package/dist/core/tools/registry.js +183 -0
- package/dist/core/tools/registry.js.map +7 -0
- package/dist/core/tools/types.js +1 -0
- package/dist/core/tools/types.js.map +7 -0
- package/dist/cost-tracker.js +23 -15
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/cli.js +158 -130
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/entrypoints/mcp.js +12 -4
- package/dist/entrypoints/mcp.js.map +2 -2
- package/dist/history.js +14 -3
- package/dist/history.js.map +2 -2
- package/dist/hooks/useAgentTokenStats.js +72 -0
- package/dist/hooks/useAgentTokenStats.js.map +7 -0
- package/dist/hooks/useAgentTranscripts.js +140 -0
- package/dist/hooks/useAgentTranscripts.js.map +7 -0
- package/dist/hooks/useAnimationSync.js +53 -0
- package/dist/hooks/useAnimationSync.js.map +7 -0
- package/dist/hooks/useArrowKeyHistory.js +4 -2
- package/dist/hooks/useArrowKeyHistory.js.map +2 -2
- package/dist/hooks/useCanUseTool.js +3 -1
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useExitOnCtrlCD.js +9 -5
- package/dist/hooks/useExitOnCtrlCD.js.map +2 -2
- package/dist/hooks/useHookStatus.js +40 -0
- package/dist/hooks/useHookStatus.js.map +7 -0
- package/dist/hooks/useLogMessages.js +29 -2
- package/dist/hooks/useLogMessages.js.map +2 -2
- package/dist/hooks/useMessageGroups.js +43 -0
- package/dist/hooks/useMessageGroups.js.map +7 -0
- package/dist/hooks/useTerminalSize.js +62 -6
- package/dist/hooks/useTerminalSize.js.map +2 -2
- package/dist/hooks/useUnifiedCompletion.js +69 -0
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/i18n/index.js +109 -0
- package/dist/i18n/index.js.map +7 -0
- package/dist/i18n/locales/en.js +348 -0
- package/dist/i18n/locales/en.js.map +7 -0
- package/dist/i18n/locales/index.js +7 -0
- package/dist/i18n/locales/index.js.map +7 -0
- package/dist/i18n/locales/zh-CN.js +348 -0
- package/dist/i18n/locales/zh-CN.js.map +7 -0
- package/dist/i18n/types.js +8 -0
- package/dist/i18n/types.js.map +7 -0
- package/dist/permissions.js +28 -1
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +253 -21
- package/dist/query.js.map +3 -3
- package/dist/screens/REPL.js +523 -194
- package/dist/screens/REPL.js.map +3 -3
- package/dist/services/adapters/chatCompletions.js +3 -1
- package/dist/services/adapters/chatCompletions.js.map +2 -2
- package/dist/services/adapters/messageNormalizer.js +354 -0
- package/dist/services/adapters/messageNormalizer.js.map +7 -0
- package/dist/services/adapters/responsesAPI.js +6 -3
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/checkpointManager.js +386 -0
- package/dist/services/checkpointManager.js.map +7 -0
- package/dist/services/claude.js +192 -14
- package/dist/services/claude.js.map +3 -3
- package/dist/services/compressionService.js +50 -1
- package/dist/services/compressionService.js.map +2 -2
- package/dist/services/contextMonitor.js +162 -0
- package/dist/services/contextMonitor.js.map +7 -0
- package/dist/services/customCommands.js +60 -41
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/hookExecutor.js +173 -1
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/intelligentCompactor.js +281 -0
- package/dist/services/intelligentCompactor.js.map +7 -0
- package/dist/services/lspConfig.js +109 -0
- package/dist/services/lspConfig.js.map +7 -0
- package/dist/services/mcpClient.js +338 -43
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/modelOrchestrator.js +310 -0
- package/dist/services/modelOrchestrator.js.map +7 -0
- package/dist/services/openai.js +8 -1
- package/dist/services/openai.js.map +2 -2
- package/dist/services/outputStyles.js +138 -0
- package/dist/services/outputStyles.js.map +7 -0
- package/dist/services/plugins/index.js +5 -0
- package/dist/services/plugins/index.js.map +7 -0
- package/dist/services/plugins/lspServers.js +188 -0
- package/dist/services/plugins/lspServers.js.map +7 -0
- package/dist/services/plugins/pluginRuntime.js +229 -0
- package/dist/services/plugins/pluginRuntime.js.map +7 -0
- package/dist/services/plugins/pluginValidation.js +219 -0
- package/dist/services/plugins/pluginValidation.js.map +7 -0
- package/dist/services/plugins/skillMarketplace.js +556 -0
- package/dist/services/plugins/skillMarketplace.js.map +7 -0
- package/dist/services/responseStateManager.js +37 -3
- package/dist/services/responseStateManager.js.map +2 -2
- package/dist/services/sandbox/filesystemBoundary.js +341 -0
- package/dist/services/sandbox/filesystemBoundary.js.map +7 -0
- package/dist/services/sandbox/index.js +14 -0
- package/dist/services/sandbox/index.js.map +7 -0
- package/dist/services/sandbox/networkProxy.js +293 -0
- package/dist/services/sandbox/networkProxy.js.map +7 -0
- package/dist/services/sandbox/sandboxController.js +574 -0
- package/dist/services/sandbox/sandboxController.js.map +7 -0
- package/dist/services/sandbox/types.js +50 -0
- package/dist/services/sandbox/types.js.map +7 -0
- package/dist/services/sessionMemory.js +266 -0
- package/dist/services/sessionMemory.js.map +7 -0
- package/dist/services/taskRouter.js +324 -0
- package/dist/services/taskRouter.js.map +7 -0
- package/dist/tools/ArchitectTool/ArchitectTool.js +7 -1
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +2 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +6 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +2 -1
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
- package/dist/tools/BaseTool.js +72 -0
- package/dist/tools/BaseTool.js.map +7 -0
- package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js +3 -0
- package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js +79 -3
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/BashTool/BashToolResultMessage.js +3 -0
- package/dist/tools/BashTool/BashToolResultMessage.js.map +2 -2
- package/dist/tools/BashTool/OutputLine.js +54 -0
- package/dist/tools/BashTool/OutputLine.js.map +2 -2
- package/dist/tools/BashTool/prompt.js +336 -3
- package/dist/tools/BashTool/prompt.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +29 -4
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileEditTool/prompt.js +6 -3
- package/dist/tools/FileEditTool/prompt.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +5 -5
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/FileWriteTool/prompt.js +4 -2
- package/dist/tools/FileWriteTool/prompt.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js +4 -2
- package/dist/tools/GlobTool/GlobTool.js.map +2 -2
- package/dist/tools/GrepTool/GrepTool.js +36 -7
- package/dist/tools/GrepTool/GrepTool.js.map +2 -2
- package/dist/tools/KillShellTool/KillShellToolResultMessage.js +3 -0
- package/dist/tools/KillShellTool/KillShellToolResultMessage.js.map +2 -2
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +109 -0
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +7 -0
- package/dist/tools/ListMcpResourcesTool/prompt.js +19 -0
- package/dist/tools/ListMcpResourcesTool/prompt.js.map +7 -0
- package/dist/tools/LspTool/LspTool.js +664 -0
- package/dist/tools/LspTool/LspTool.js.map +7 -0
- package/dist/tools/LspTool/prompt.js +27 -0
- package/dist/tools/LspTool/prompt.js.map +7 -0
- package/dist/tools/MCPTool/MCPTool.js +9 -1
- package/dist/tools/MCPTool/MCPTool.js.map +2 -2
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +19 -6
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +6 -6
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +19 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/MultiEditTool/prompt.js +5 -3
- package/dist/tools/MultiEditTool/prompt.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +7 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +75 -0
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +7 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +109 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +7 -0
- package/dist/tools/PlanModeTool/prompt.js +94 -0
- package/dist/tools/PlanModeTool/prompt.js.map +7 -0
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +130 -0
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +7 -0
- package/dist/tools/ReadMcpResourceTool/prompt.js +17 -0
- package/dist/tools/ReadMcpResourceTool/prompt.js.map +7 -0
- package/dist/tools/SkillTool/SkillTool.js +10 -4
- package/dist/tools/SkillTool/SkillTool.js.map +2 -2
- package/dist/tools/SkillTool/prompt.js +1 -1
- package/dist/tools/SkillTool/prompt.js.map +1 -1
- package/dist/tools/SlashCommandTool/SlashCommandTool.js +260 -0
- package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +7 -0
- package/dist/tools/SlashCommandTool/prompt.js +35 -0
- package/dist/tools/SlashCommandTool/prompt.js.map +7 -0
- package/dist/tools/TaskOutputTool/TaskOutputTool.js +190 -0
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +7 -0
- package/dist/tools/TaskOutputTool/prompt.js +15 -0
- package/dist/tools/TaskOutputTool/prompt.js.map +7 -0
- package/dist/tools/TaskTool/TaskTool.js +310 -104
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TodoWriteTool/TodoWriteTool.js +42 -77
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +4 -1
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/cache.js +55 -8
- package/dist/tools/URLFetcherTool/cache.js.map +2 -2
- package/dist/tools.js +31 -2
- package/dist/tools.js.map +2 -2
- package/dist/types/hooks.js +4 -0
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/marketplace.js.map +2 -2
- package/dist/types/messageGroup.js +36 -0
- package/dist/types/messageGroup.js.map +7 -0
- package/dist/types/plugin.js.map +2 -2
- package/dist/types/thinking.js +1 -0
- package/dist/types/thinking.js.map +7 -0
- package/dist/utils/BackgroundShellManager.js +136 -39
- package/dist/utils/BackgroundShellManager.js.map +2 -2
- package/dist/utils/CircuitBreaker.js +242 -0
- package/dist/utils/CircuitBreaker.js.map +7 -0
- package/dist/utils/MessageBatchBuffer.js +102 -0
- package/dist/utils/MessageBatchBuffer.js.map +7 -0
- package/dist/utils/PersistentShell.js +151 -1
- package/dist/utils/PersistentShell.js.map +2 -2
- package/dist/utils/agentLoader.js +1 -23
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentTranscripts.js +641 -0
- package/dist/utils/agentTranscripts.js.map +7 -0
- package/dist/utils/animationManager.js +213 -0
- package/dist/utils/animationManager.js.map +7 -0
- package/dist/utils/animationSync.js +110 -0
- package/dist/utils/animationSync.js.map +7 -0
- package/dist/utils/ask.js +2 -0
- package/dist/utils/ask.js.map +2 -2
- package/dist/utils/asyncFile.js +215 -0
- package/dist/utils/asyncFile.js.map +7 -0
- package/dist/utils/backgroundAgentManager.js +231 -0
- package/dist/utils/backgroundAgentManager.js.map +7 -0
- package/dist/utils/config.js +108 -10
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/conversationRecovery.js +19 -0
- package/dist/utils/conversationRecovery.js.map +2 -2
- package/dist/utils/credentials/CredentialStore.js +1 -0
- package/dist/utils/credentials/CredentialStore.js.map +7 -0
- package/dist/utils/credentials/EncryptedFileStore.js +157 -0
- package/dist/utils/credentials/EncryptedFileStore.js.map +7 -0
- package/dist/utils/credentials/index.js +37 -0
- package/dist/utils/credentials/index.js.map +7 -0
- package/dist/utils/credentials/migration.js +82 -0
- package/dist/utils/credentials/migration.js.map +7 -0
- package/dist/utils/exit.js +73 -0
- package/dist/utils/exit.js.map +7 -0
- package/dist/utils/format.js +73 -5
- package/dist/utils/format.js.map +2 -2
- package/dist/utils/generators.js +76 -6
- package/dist/utils/generators.js.map +2 -2
- package/dist/utils/globalErrorHandler.js +149 -0
- package/dist/utils/globalErrorHandler.js.map +7 -0
- package/dist/utils/groupHandlers/index.js +8 -0
- package/dist/utils/groupHandlers/index.js.map +7 -0
- package/dist/utils/groupHandlers/parallelTasksHandler.js +140 -0
- package/dist/utils/groupHandlers/parallelTasksHandler.js.map +7 -0
- package/dist/utils/groupHandlers/taskHandler.js +104 -0
- package/dist/utils/groupHandlers/taskHandler.js.map +7 -0
- package/dist/utils/groupHandlers/types.js +1 -0
- package/dist/utils/groupHandlers/types.js.map +7 -0
- package/dist/utils/logRotation.js +224 -0
- package/dist/utils/logRotation.js.map +7 -0
- package/dist/utils/markdown.js +13 -1
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/marketplaceManager.js +3 -5
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/memSafety.js +264 -0
- package/dist/utils/memSafety.js.map +7 -0
- package/dist/utils/messageGroupManager.js +274 -0
- package/dist/utils/messageGroupManager.js.map +7 -0
- package/dist/utils/messages.js +13 -4
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +119 -15
- package/dist/utils/model.js.map +3 -3
- package/dist/utils/permissions/filesystem.js +162 -6
- package/dist/utils/permissions/filesystem.js.map +2 -2
- package/dist/utils/plan/planMode.js +143 -0
- package/dist/utils/plan/planMode.js.map +7 -0
- package/dist/utils/pluginLoader.js +17 -21
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/ripgrep.js +55 -2
- package/dist/utils/ripgrep.js.map +2 -2
- package/dist/utils/safePath.js +132 -0
- package/dist/utils/safePath.js.map +7 -0
- package/dist/utils/sanitizeInput.js +32 -0
- package/dist/utils/sanitizeInput.js.map +7 -0
- package/dist/utils/secureKeyStorage.js +312 -0
- package/dist/utils/secureKeyStorage.js.map +7 -0
- package/dist/utils/sensitiveFiles.js +125 -0
- package/dist/utils/sensitiveFiles.js.map +7 -0
- package/dist/utils/session/sessionPlugins.js +67 -0
- package/dist/utils/session/sessionPlugins.js.map +7 -0
- package/dist/utils/taskDisplayUtils.js +257 -0
- package/dist/utils/taskDisplayUtils.js.map +7 -0
- package/dist/utils/teamConfig.js +2 -1
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/theme.js +6 -6
- package/dist/utils/theme.js.map +1 -1
- package/dist/utils/todoStorage.js +92 -2
- package/dist/utils/todoStorage.js.map +2 -2
- package/dist/utils/toolRiskClassification.js +207 -0
- package/dist/utils/toolRiskClassification.js.map +7 -0
- package/dist/utils/toolTimeout.js +136 -0
- package/dist/utils/toolTimeout.js.map +7 -0
- package/dist/utils/tooling/safeRender.js +116 -0
- package/dist/utils/tooling/safeRender.js.map +7 -0
- package/dist/utils/userFriendlyError.js +346 -0
- package/dist/utils/userFriendlyError.js.map +7 -0
- package/dist/utils/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +17 -5
- package/scripts/postinstall.js +128 -38
- package/dist/commands/agents.js +0 -2086
- package/dist/commands/agents.js.map +0 -7
- package/dist/commands/build.js +0 -74
- package/dist/commands/build.js.map +0 -7
- package/dist/commands/compression.js +0 -57
- package/dist/commands/compression.js.map +0 -7
- package/dist/commands/listen.js +0 -37
- package/dist/commands/listen.js.map +0 -7
- package/dist/commands/login.js +0 -37
- package/dist/commands/login.js.map +0 -7
- package/dist/commands/logout.js +0 -33
- package/dist/commands/logout.js.map +0 -7
- package/dist/commands/mcp.js +0 -40
- package/dist/commands/mcp.js.map +0 -7
- package/dist/commands/mcp_refresh.js +0 -40
- package/dist/commands/mcp_refresh.js.map +0 -7
- package/dist/commands/modelstatus.js +0 -21
- package/dist/commands/modelstatus.js.map +0 -7
- package/dist/commands/onboarding.js +0 -36
- package/dist/commands/onboarding.js.map +0 -7
- package/dist/commands/plugin-interactive.js +0 -446
- package/dist/commands/plugin-interactive.js.map +0 -7
- package/dist/commands/pr_comments.js +0 -61
- package/dist/commands/pr_comments.js.map +0 -7
- package/dist/commands/release-notes.js +0 -30
- package/dist/commands/release-notes.js.map +0 -7
- package/dist/commands/review.js +0 -51
- package/dist/commands/review.js.map +0 -7
- package/dist/components/Bug.js +0 -147
- package/dist/components/Bug.js.map +0 -7
- package/dist/components/ModelSelector.js +0 -2062
- package/dist/components/ModelSelector.js.map +0 -7
- package/dist/components/ModelStatusDisplay.js +0 -87
- package/dist/components/ModelStatusDisplay.js.map +0 -7
- package/dist/entrypoints/cli-wrapper.js +0 -61
- package/dist/entrypoints/cli-wrapper.js.map +0 -7
- package/dist/hooks/useCancelRequest.js +0 -28
- package/dist/hooks/useCancelRequest.js.map +0 -7
- package/dist/screens/Doctor.js +0 -22
- package/dist/screens/Doctor.js.map +0 -7
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/tools/LspTool/LspTool.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * LSP Tool\n *\n * Provides Language Server Protocol operations for code intelligence.\n * Currently supports TypeScript/JavaScript files using the project's TypeScript.\n */\n\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport type { Tool, ToolUseContext } from '@tool'\nimport { getCwd } from '@utils/state'\nimport { existsSync, readFileSync, statSync } from 'fs'\nimport { Box, Text } from 'ink'\nimport { createRequire } from 'node:module'\nimport { extname, join, relative } from 'path'\nimport React from 'react'\nimport { pathToFileURL } from 'url'\nimport { z } from 'zod'\nimport { DESCRIPTION, PROMPT, TOOL_NAME_FOR_PROMPT } from './prompt'\n\ntype TypeScriptModule = typeof import('typescript')\n\ntype Operation =\n | 'goToDefinition'\n | 'findReferences'\n | 'hover'\n | 'documentSymbol'\n | 'workspaceSymbol'\n | 'goToImplementation'\n | 'prepareCallHierarchy'\n | 'incomingCalls'\n | 'outgoingCalls'\n\nconst inputSchema = z.strictObject({\n operation: z\n .enum([\n 'goToDefinition',\n 'findReferences',\n 'hover',\n 'documentSymbol',\n 'workspaceSymbol',\n 'goToImplementation',\n 'prepareCallHierarchy',\n 'incomingCalls',\n 'outgoingCalls',\n ])\n .describe('The LSP operation to perform'),\n filePath: z.string().describe('The absolute or relative path to the file'),\n line: z\n .number()\n .int()\n .positive()\n .describe('The line number (1-based, as shown in editors)'),\n character: z\n .number()\n .int()\n .positive()\n .describe('The character offset (1-based, as shown in editors)'),\n})\n\nconst outputSchema = z.object({\n operation: z\n .enum([\n 'goToDefinition',\n 'findReferences',\n 'hover',\n 'documentSymbol',\n 'workspaceSymbol',\n 'goToImplementation',\n 'prepareCallHierarchy',\n 'incomingCalls',\n 'outgoingCalls',\n ])\n .describe('The LSP operation that was performed'),\n result: z.string().describe('The formatted result of the LSP operation'),\n filePath: z.string().describe('The file path the operation was performed on'),\n resultCount: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Number of results (definitions, references, symbols)'),\n fileCount: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Number of files containing results'),\n})\n\ntype Input = z.infer<typeof inputSchema>\ntype Output = z.infer<typeof outputSchema>\n\nconst OPERATION_LABELS: Record<\n Operation,\n { singular: string; plural: string; special?: string }\n> = {\n goToDefinition: { singular: 'definition', plural: 'definitions' },\n findReferences: { singular: 'reference', plural: 'references' },\n documentSymbol: { singular: 'symbol', plural: 'symbols' },\n workspaceSymbol: { singular: 'symbol', plural: 'symbols' },\n hover: { singular: 'hover info', plural: 'hover info', special: 'available' },\n goToImplementation: { singular: 'implementation', plural: 'implementations' },\n prepareCallHierarchy: { singular: 'call item', plural: 'call items' },\n incomingCalls: { singular: 'caller', plural: 'callers' },\n outgoingCalls: { singular: 'callee', plural: 'callees' },\n}\n\nfunction getAbsolutePath(filePath: string): string {\n if (filePath.startsWith('/')) return filePath\n return join(getCwd(), filePath)\n}\n\nfunction toProjectRelativeIfPossible(filePath: string): string {\n const cwd = getCwd()\n try {\n const rel = relative(cwd, filePath)\n if (!rel || rel === '') return filePath\n if (rel.startsWith('..')) return filePath\n return rel\n } catch {\n return filePath\n }\n}\n\nfunction formatLocation(\n fileName: string,\n line0: number,\n character0: number,\n): string {\n return `${toProjectRelativeIfPossible(fileName)}:${line0 + 1}:${character0 + 1}`\n}\n\nfunction formatGoToDefinitionResult(\n locations: Array<{\n fileName: string\n line0: number\n character0: number\n }> | null,\n): { formatted: string; resultCount: number; fileCount: number } {\n if (!locations || locations.length === 0) {\n return {\n formatted:\n 'No definition found. This may occur if the cursor is not on a symbol, or if the definition is in an external library not indexed by the LSP server.',\n resultCount: 0,\n fileCount: 0,\n }\n }\n const fileCount = new Set(locations.map(l => l.fileName)).size\n if (locations.length === 1) {\n const loc = locations[0]\n return {\n formatted: `Defined in ${formatLocation(loc.fileName, loc.line0, loc.character0)}`,\n resultCount: 1,\n fileCount,\n }\n }\n return {\n formatted: `Found ${locations.length} definitions:\\n${locations\n .map(\n loc => ` ${formatLocation(loc.fileName, loc.line0, loc.character0)}`,\n )\n .join('\\n')}`,\n resultCount: locations.length,\n fileCount,\n }\n}\n\nfunction groupLocationsByFile<T extends { fileName: string }>(\n items: T[],\n): Map<string, T[]> {\n const grouped = new Map<string, T[]>()\n for (const item of items) {\n const key = toProjectRelativeIfPossible(item.fileName)\n const existing = grouped.get(key)\n if (existing) existing.push(item)\n else grouped.set(key, [item])\n }\n return grouped\n}\n\nfunction formatFindReferencesResult(\n references: Array<{\n fileName: string\n line0: number\n character0: number\n }> | null,\n): { formatted: string; resultCount: number; fileCount: number } {\n if (!references || references.length === 0) {\n return {\n formatted:\n 'No references found. This may occur if the symbol has no usages, or if the LSP server has not fully indexed the workspace.',\n resultCount: 0,\n fileCount: 0,\n }\n }\n if (references.length === 1) {\n const ref = references[0]\n return {\n formatted: `Found 1 reference:\\n ${formatLocation(ref.fileName, ref.line0, ref.character0)}`,\n resultCount: 1,\n fileCount: 1,\n }\n }\n\n const grouped = groupLocationsByFile(references)\n const lines: string[] = [\n `Found ${references.length} references across ${grouped.size} files:`,\n ]\n for (const [file, refs] of grouped) {\n lines.push(`\\n${file}:`)\n for (const ref of refs) {\n lines.push(` Line ${ref.line0 + 1}:${ref.character0 + 1}`)\n }\n }\n return {\n formatted: lines.join('\\n'),\n resultCount: references.length,\n fileCount: grouped.size,\n }\n}\n\nfunction formatHoverResult(\n hoverText: string | null,\n line0: number,\n character0: number,\n) {\n if (!hoverText || hoverText.trim() === '') {\n return {\n formatted:\n 'No hover information available. This may occur if the cursor is not on a symbol, or if the LSP server has not fully indexed the file.',\n resultCount: 0,\n fileCount: 0,\n }\n }\n return {\n formatted: `Hover info at ${line0 + 1}:${character0 + 1}:\\n\\n${hoverText}`,\n resultCount: 1,\n fileCount: 1,\n }\n}\n\nfunction formatDocumentSymbolsResult(lines: string[], symbolCount: number) {\n if (symbolCount === 0) {\n return {\n formatted:\n 'No symbols found in document. This may occur if the file is empty, not supported by the LSP server, or if the server has not fully indexed the file.',\n resultCount: 0,\n fileCount: 0,\n }\n }\n return {\n formatted: ['Document symbols:', ...lines].join('\\n'),\n resultCount: symbolCount,\n fileCount: 1,\n }\n}\n\n// TypeScript module cache\nlet cachedTypeScript: { cwd: string; module: TypeScriptModule | null } | null =\n null\n\nfunction tryLoadTypeScriptModule(projectCwd: string): TypeScriptModule | null {\n if (cachedTypeScript?.cwd === projectCwd) return cachedTypeScript.module\n\n try {\n const requireFromCwd = createRequire(\n pathToFileURL(join(projectCwd, '__minto_lsp__.js')),\n )\n const mod = requireFromCwd('typescript') as TypeScriptModule\n cachedTypeScript = { cwd: projectCwd, module: mod }\n return mod\n } catch {\n cachedTypeScript = { cwd: projectCwd, module: null }\n return null\n }\n}\n\ntype TsProjectState = {\n ts: TypeScriptModule\n cwd: string\n rootFiles: Set<string>\n compilerOptions: any\n languageService: any\n versions: Map<string, string>\n}\n\nconst projectCache = new Map<string, TsProjectState>()\n\nfunction getOrCreateTsProject(projectCwd: string): TsProjectState | null {\n const ts = tryLoadTypeScriptModule(projectCwd)\n if (!ts) return null\n\n const existing = projectCache.get(projectCwd)\n if (existing) return existing\n\n let compilerOptions: any = {\n allowJs: true,\n checkJs: false,\n jsx: ts.JsxEmit.ReactJSX,\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n }\n\n let rootFileNames: string[] = []\n try {\n const configPath = ts.findConfigFile(\n projectCwd,\n ts.sys.fileExists,\n 'tsconfig.json',\n )\n if (configPath) {\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile)\n if (!configFile.error) {\n const parsed = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n projectCwd,\n )\n compilerOptions = { ...compilerOptions, ...parsed.options }\n rootFileNames = parsed.fileNames\n }\n }\n } catch {\n // Use defaults\n }\n\n const rootFiles = new Set(rootFileNames)\n const versions = new Map<string, string>()\n\n const host: any = {\n getCompilationSettings: () => compilerOptions,\n getScriptFileNames: () => Array.from(rootFiles),\n getScriptVersion: (fileName: string) => {\n try {\n const stat = statSync(fileName)\n const version = String(stat.mtimeMs ?? Date.now())\n versions.set(fileName, version)\n return version\n } catch {\n return versions.get(fileName) ?? '0'\n }\n },\n getScriptSnapshot: (fileName: string) => {\n try {\n if (!ts.sys.fileExists(fileName)) return undefined\n const content = ts.sys.readFile(fileName)\n if (content === undefined) return undefined\n const stat = statSync(fileName)\n versions.set(fileName, String(stat.mtimeMs ?? Date.now()))\n return ts.ScriptSnapshot.fromString(content)\n } catch {\n return undefined\n }\n },\n getCurrentDirectory: () => projectCwd,\n getDefaultLibFileName: (options: any) => ts.getDefaultLibFilePath(options),\n fileExists: ts.sys.fileExists,\n readFile: ts.sys.readFile,\n readDirectory: ts.sys.readDirectory,\n directoryExists: ts.sys.directoryExists,\n getDirectories: ts.sys.getDirectories,\n useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,\n getCanonicalFileName: (fileName: string) =>\n ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(),\n getNewLine: () => ts.sys.newLine,\n }\n\n const languageService = ts.createLanguageService(\n host,\n ts.createDocumentRegistry(),\n )\n\n const state: TsProjectState = {\n ts,\n cwd: projectCwd,\n rootFiles,\n compilerOptions,\n languageService,\n versions,\n }\n projectCache.set(projectCwd, state)\n return state\n}\n\nfunction isFileTypeSupportedByTypescriptBackend(filePath: string): boolean {\n const ext = extname(filePath).toLowerCase()\n return (\n ext === '.ts' ||\n ext === '.tsx' ||\n ext === '.js' ||\n ext === '.jsx' ||\n ext === '.mts' ||\n ext === '.cts' ||\n ext === '.mjs' ||\n ext === '.cjs'\n )\n}\n\nfunction summarizeToolResult(\n operation: Operation,\n resultCount: number,\n fileCount: number,\n) {\n const label = OPERATION_LABELS[operation] ?? {\n singular: 'result',\n plural: 'results',\n }\n const noun = resultCount === 1 ? label.singular : label.plural\n if (operation === 'hover' && resultCount > 0 && label.special) {\n return <Text>Hover info {label.special}</Text>\n }\n return (\n <Text>\n Found <Text bold>{resultCount}</Text> {noun}\n {fileCount > 1 ? (\n <>\n {' '}\n across <Text bold>{fileCount}</Text> files\n </>\n ) : null}\n </Text>\n )\n}\n\nexport const LspTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'LSP'\n },\n async isEnabled() {\n return tryLoadTypeScriptModule(getCwd()) !== null\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n needsPermissions({ filePath }: Input) {\n // LSP operations are read-only, but we check if file exists\n const abs = getAbsolutePath(filePath)\n return !existsSync(abs)\n },\n async validateInput(input: Input) {\n const parsed = inputSchema.safeParse(input)\n if (!parsed.success) {\n return {\n result: false,\n message: `Invalid input: ${parsed.error.message}`,\n errorCode: 3,\n }\n }\n\n const absPath = getAbsolutePath(input.filePath)\n if (!existsSync(absPath)) {\n return {\n result: false,\n message: `File does not exist: ${input.filePath}`,\n errorCode: 1,\n }\n }\n try {\n if (!statSync(absPath).isFile()) {\n return {\n result: false,\n message: `Path is not a file: ${input.filePath}`,\n errorCode: 2,\n }\n }\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err))\n return {\n result: false,\n message: `Cannot access file: ${input.filePath}. ${e.message}`,\n errorCode: 4,\n }\n }\n\n return { result: true }\n },\n renderToolUseMessage(input: Input, { verbose }: { verbose: boolean }) {\n const abs = getAbsolutePath(input.filePath)\n const filePathForDisplay = verbose ? abs : toProjectRelativeIfPossible(abs)\n const parts: string[] = []\n\n parts.push(`operation: \"${input.operation}\"`)\n if (input.filePath) parts.push(`file: \"${filePathForDisplay}\"`)\n if (input.line && input.character) {\n parts.push(`position: ${input.line}:${input.character}`)\n }\n return parts.join(', ')\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: Output, { verbose }: { verbose: boolean }) {\n if (!output) {\n return (\n <Box paddingLeft={2}>\n <Text>LSP operation completed</Text>\n </Box>\n )\n }\n\n if (output.resultCount !== undefined && output.fileCount !== undefined) {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n {summarizeToolResult(\n output.operation,\n output.resultCount,\n output.fileCount,\n )}\n </Box>\n {verbose ? (\n <Box marginLeft={5}>\n <Text>{output.result}</Text>\n </Box>\n ) : null}\n </Box>\n )\n }\n\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>{output.result}</Text>\n </Box>\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n return output?.result ?? 'LSP operation completed'\n },\n async *call(input: Input, _context: ToolUseContext) {\n const absPath = getAbsolutePath(input.filePath)\n\n if (!isFileTypeSupportedByTypescriptBackend(absPath)) {\n const ext = extname(absPath)\n const out: Output = {\n operation: input.operation,\n result: `No LSP server available for file type: ${ext}`,\n filePath: input.filePath,\n resultCount: 0,\n fileCount: 0,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n return\n }\n\n const project = getOrCreateTsProject(getCwd())\n if (!project) {\n const out: Output = {\n operation: input.operation,\n result:\n 'TypeScript not found in project. Install typescript to use LSP features: npm install typescript',\n filePath: input.filePath,\n resultCount: 0,\n fileCount: 0,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n return\n }\n\n project.rootFiles.add(absPath)\n\n const ts = project.ts\n const service = project.languageService\n const program = service.getProgram?.()\n if (!program) {\n const out: Output = {\n operation: input.operation,\n result: `Error performing ${input.operation}: TypeScript program not available`,\n filePath: input.filePath,\n resultCount: 0,\n fileCount: 0,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n return\n }\n\n const sourceFile = program.getSourceFile(absPath)\n if (!sourceFile) {\n const out: Output = {\n operation: input.operation,\n result: `Error performing ${input.operation}: File is not part of the TypeScript program`,\n filePath: input.filePath,\n resultCount: 0,\n fileCount: 0,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n return\n }\n\n const pos = ts.getPositionOfLineAndCharacter(\n sourceFile,\n input.line - 1,\n input.character - 1,\n )\n\n try {\n let formatted: string\n let resultCount = 0\n let fileCount = 0\n\n switch (input.operation) {\n case 'goToDefinition': {\n const defs = service.getDefinitionAtPosition?.(absPath, pos) ?? []\n const locations = defs\n .map((d: any) => {\n const defSourceFile = program.getSourceFile(d.fileName)\n if (!defSourceFile) return null\n const lc = ts.getLineAndCharacterOfPosition(\n defSourceFile,\n d.textSpan.start,\n )\n return {\n fileName: d.fileName,\n line0: lc.line,\n character0: lc.character,\n }\n })\n .filter(Boolean) as Array<{\n fileName: string\n line0: number\n character0: number\n }>\n const res = formatGoToDefinitionResult(locations)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'goToImplementation': {\n const impls =\n service.getImplementationAtPosition?.(absPath, pos) ?? []\n const locations = impls\n .map((d: any) => {\n const defSourceFile = program.getSourceFile(d.fileName)\n if (!defSourceFile) return null\n const lc = ts.getLineAndCharacterOfPosition(\n defSourceFile,\n d.textSpan.start,\n )\n return {\n fileName: d.fileName,\n line0: lc.line,\n character0: lc.character,\n }\n })\n .filter(Boolean) as Array<{\n fileName: string\n line0: number\n character0: number\n }>\n const res = formatGoToDefinitionResult(locations)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'findReferences': {\n const referencedSymbols = service.findReferences?.(absPath, pos) ?? []\n const refs: Array<{\n fileName: string\n line0: number\n character0: number\n }> = []\n for (const sym of referencedSymbols) {\n for (const ref of sym.references ?? []) {\n const refSource = program.getSourceFile(ref.fileName)\n if (!refSource) continue\n const lc = ts.getLineAndCharacterOfPosition(\n refSource,\n ref.textSpan.start,\n )\n refs.push({\n fileName: ref.fileName,\n line0: lc.line,\n character0: lc.character,\n })\n }\n }\n const res = formatFindReferencesResult(refs)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'hover': {\n const info = service.getQuickInfoAtPosition?.(absPath, pos)\n let text: string | null = null\n let hoverLine0 = input.line - 1\n let hoverCharacter0 = input.character - 1\n if (info) {\n const parts: string[] = []\n const signature = ts.displayPartsToString(info.displayParts ?? [])\n if (signature) parts.push(signature)\n const doc = ts.displayPartsToString(info.documentation ?? [])\n if (doc) parts.push(doc)\n if (info.tags && info.tags.length > 0) {\n for (const tag of info.tags) {\n const tagText = ts.displayPartsToString(tag.text ?? [])\n parts.push(`@${tag.name}${tagText ? ` ${tagText}` : ''}`)\n }\n }\n text = parts.filter(Boolean).join('\\n\\n')\n const lc = ts.getLineAndCharacterOfPosition(\n sourceFile,\n info.textSpan.start,\n )\n hoverLine0 = lc.line\n hoverCharacter0 = lc.character\n }\n const res = formatHoverResult(text, hoverLine0, hoverCharacter0)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'documentSymbol': {\n const tree = service.getNavigationTree?.(absPath)\n const lines: string[] = []\n let count = 0\n\n const kindLabel = (kind: string) => {\n const m = {\n class: 'Class',\n interface: 'Interface',\n enum: 'Enum',\n function: 'Function',\n method: 'Method',\n property: 'Property',\n var: 'Variable',\n let: 'Variable',\n const: 'Constant',\n module: 'Module',\n alias: 'Alias',\n type: 'Type',\n } as Record<string, string>\n return (\n m[kind] ??\n (kind ? kind[0].toUpperCase() + kind.slice(1) : 'Unknown')\n )\n }\n\n const walk = (node: any, depth: number) => {\n const children: any[] = node?.childItems ?? []\n for (const child of children) {\n const span = child.spans?.[0]\n if (!span) continue\n const lc = ts.getLineAndCharacterOfPosition(\n sourceFile,\n span.start,\n )\n const indent = ' '.repeat(depth)\n const label = kindLabel(child.kind)\n const detail = child.kindModifiers\n ? ` ${child.kindModifiers}`\n : ''\n lines.push(\n `${indent}${child.text} (${label})${detail} - Line ${lc.line + 1}`,\n )\n count += 1\n if (child.childItems && child.childItems.length > 0) {\n walk(child, depth + 1)\n }\n }\n }\n walk(tree, 0)\n\n const res = formatDocumentSymbolsResult(lines, count)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'workspaceSymbol': {\n const items =\n service.getNavigateToItems?.('', 100, undefined, true, true) ?? []\n if (!items || items.length === 0) {\n formatted =\n 'No symbols found in workspace. This may occur if the workspace is empty, or if the LSP server has not finished indexing the project.'\n resultCount = 0\n fileCount = 0\n break\n }\n\n const lines: string[] = [\n `Found ${items.length} symbol${items.length === 1 ? '' : 's'} in workspace:`,\n ]\n const grouped = groupLocationsByFile(\n items.map((it: any) => ({\n fileName: it.fileName,\n item: it,\n })),\n )\n for (const [file, itemsInFile] of grouped) {\n lines.push(`\\n${file}:`)\n for (const wrapper of itemsInFile) {\n const it: any = (wrapper as any).item\n const sf = program.getSourceFile(it.fileName)\n if (!sf) continue\n const span = it.textSpan\n const lc = span\n ? ts.getLineAndCharacterOfPosition(sf, span.start)\n : { line: 0, character: 0 }\n const label = it.kind\n ? String(it.kind)[0].toUpperCase() + String(it.kind).slice(1)\n : 'Symbol'\n let line = ` ${it.name} (${label}) - Line ${lc.line + 1}`\n if (it.containerName) line += ` in ${it.containerName}`\n lines.push(line)\n }\n }\n formatted = lines.join('\\n')\n resultCount = items.length\n fileCount = grouped.size\n break\n }\n case 'prepareCallHierarchy':\n case 'incomingCalls':\n case 'outgoingCalls': {\n const opLabel = input.operation\n formatted = `Error performing ${opLabel}: Call hierarchy is not supported by the TypeScript backend`\n resultCount = 0\n fileCount = 0\n break\n }\n default: {\n formatted = `Error performing ${input.operation}: Unsupported operation`\n resultCount = 0\n fileCount = 0\n }\n }\n\n const out: Output = {\n operation: input.operation,\n result: formatted,\n filePath: input.filePath,\n resultCount,\n fileCount,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n const out: Output = {\n operation: input.operation,\n result: `Error performing ${input.operation}: ${message}`,\n filePath: input.filePath,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n }\n },\n} satisfies Tool<typeof inputSchema, Output>\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const TOOL_NAME_FOR_PROMPT = "LSP";
|
|
2
|
+
const PROMPT = `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
|
|
3
|
+
|
|
4
|
+
Supported operations:
|
|
5
|
+
- goToDefinition: Find where a symbol is defined
|
|
6
|
+
- findReferences: Find all references to a symbol
|
|
7
|
+
- hover: Get hover information (documentation, type info) for a symbol
|
|
8
|
+
- documentSymbol: Get all symbols (functions, classes, variables) in a document
|
|
9
|
+
- workspaceSymbol: Search for symbols across the entire workspace
|
|
10
|
+
- goToImplementation: Find implementations of an interface or abstract method
|
|
11
|
+
- prepareCallHierarchy: Get call hierarchy item at a position (functions/methods)
|
|
12
|
+
- incomingCalls: Find all functions/methods that call the function at a position
|
|
13
|
+
- outgoingCalls: Find all functions/methods called by the function at a position
|
|
14
|
+
|
|
15
|
+
All operations require:
|
|
16
|
+
- filePath: The file to operate on
|
|
17
|
+
- line: The line number (1-based, as shown in editors)
|
|
18
|
+
- character: The character offset (1-based, as shown in editors)
|
|
19
|
+
|
|
20
|
+
Note: LSP servers must be configured for the file type. If no server is available, an error will be returned.`;
|
|
21
|
+
const DESCRIPTION = PROMPT;
|
|
22
|
+
export {
|
|
23
|
+
DESCRIPTION,
|
|
24
|
+
PROMPT,
|
|
25
|
+
TOOL_NAME_FOR_PROMPT
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/tools/LspTool/prompt.ts"],
|
|
4
|
+
"sourcesContent": ["export const TOOL_NAME_FOR_PROMPT = 'LSP'\n\nexport const PROMPT = `Interact with Language Server Protocol (LSP) servers to get code intelligence features.\n\nSupported operations:\n- goToDefinition: Find where a symbol is defined\n- findReferences: Find all references to a symbol\n- hover: Get hover information (documentation, type info) for a symbol\n- documentSymbol: Get all symbols (functions, classes, variables) in a document\n- workspaceSymbol: Search for symbols across the entire workspace\n- goToImplementation: Find implementations of an interface or abstract method\n- prepareCallHierarchy: Get call hierarchy item at a position (functions/methods)\n- incomingCalls: Find all functions/methods that call the function at a position\n- outgoingCalls: Find all functions/methods called by the function at a position\n\nAll operations require:\n- filePath: The file to operate on\n- line: The line number (1-based, as shown in editors)\n- character: The character offset (1-based, as shown in editors)\n\nNote: LSP servers must be configured for the file type. If no server is available, an error will be returned.`\n\nexport const DESCRIPTION = PROMPT\n"],
|
|
5
|
+
"mappings": "AAAO,MAAM,uBAAuB;AAE7B,MAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBf,MAAM,cAAc;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -70,7 +70,15 @@ const MCPTool = {
|
|
|
70
70
|
}
|
|
71
71
|
const text = item.text || "";
|
|
72
72
|
const lines2 = text.split("\n").length;
|
|
73
|
-
return /* @__PURE__ */ React.createElement(
|
|
73
|
+
return /* @__PURE__ */ React.createElement(
|
|
74
|
+
OutputLine,
|
|
75
|
+
{
|
|
76
|
+
key: i,
|
|
77
|
+
content: text,
|
|
78
|
+
lines: lines2,
|
|
79
|
+
verbose
|
|
80
|
+
}
|
|
81
|
+
);
|
|
74
82
|
}));
|
|
75
83
|
}
|
|
76
84
|
if (typeof output !== "string") {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/MCPTool/MCPTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { type Tool } from '@tool'\nimport { getTheme } from '@utils/theme'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { OutputLine } from '@tools/BashTool/OutputLine'\n\n// Allow any input object since MCP tools define their own schemas\nconst inputSchema = z.object({}).passthrough()\n\nexport const MCPTool = {\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false // MCPTool can modify state through MCP calls, not safe for concurrent execution\n },\n // Overridden in mcpClient.ts\n name: 'mcp',\n // Overridden in mcpClient.ts\n async description() {\n return DESCRIPTION\n },\n // Overridden in mcpClient.ts\n async prompt() {\n return PROMPT\n },\n inputSchema,\n // Overridden in mcpClient.ts\n async *call() {\n yield {\n type: 'result',\n data: '',\n resultForAssistant: '',\n }\n },\n needsPermissions() {\n return true\n },\n renderToolUseMessage(input) {\n return Object.entries(input)\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join(', ')\n },\n // Overridden in mcpClient.ts\n userFacingName: () => 'mcp',\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output) {\n const verbose = false // Set default value for verbose\n\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" overflowX=\"hidden\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={getTheme().secondaryText}>(No content)</Text>\n </Box>\n </Box>\n )\n }\n\n if (Array.isArray(output)) {\n return (\n <Box flexDirection=\"column\">\n {output.map((item, i) => {\n // Guard against null/undefined items in array\n if (!item) {\n return null\n }\n if (item.type === 'image') {\n return (\n <Box\n key={i}\n justifyContent=\"space-between\"\n overflowX=\"hidden\"\n width=\"100%\"\n >\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>[Image]</Text>\n </Box>\n </Box>\n )\n }\n // Guard against missing text property\n const text = item.text || ''\n const lines = text.split('\\n').length\n return (\n <OutputLine
|
|
5
|
-
"mappings": "AAAA,SAAS,KAAK,YAAY;AAC1B,YAAY,WAAW;AACvB,SAAS,SAAS;AAClB,SAAS,sCAAsC;AAE/C,SAAS,gBAAgB;AACzB,SAAS,aAAa,cAAc;AACpC,SAAS,kBAAkB;AAG3B,MAAM,cAAc,EAAE,OAAO,CAAC,CAAC,EAAE,YAAY;AAEtC,MAAM,UAAU;AAAA,EACrB,MAAM,YAAY;AAChB,WAAO;AAAA,EACT;AAAA,EACA,aAAa;AACX,WAAO;AAAA,EACT;AAAA,EACA,oBAAoB;AAClB,WAAO;AAAA,EACT;AAAA;AAAA,EAEA,MAAM;AAAA;AAAA,EAEN,MAAM,cAAc;AAClB,WAAO;AAAA,EACT;AAAA;AAAA,EAEA,MAAM,SAAS;AACb,WAAO;AAAA,EACT;AAAA,EACA;AAAA;AAAA,EAEA,OAAO,OAAO;AACZ,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,oBAAoB;AAAA,IACtB;AAAA,EACF;AAAA,EACA,mBAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EACA,qBAAqB,OAAO;AAC1B,WAAO,OAAO,QAAQ,KAAK,EACxB,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,KAAK,KAAK,UAAU,KAAK,CAAC,EAAE,EACxD,KAAK,IAAI;AAAA,EACd;AAAA;AAAA,EAEA,gBAAgB,MAAM;AAAA,EACtB,+BAA+B;AAC7B,WAAO,oCAAC,oCAA+B;AAAA,EACzC;AAAA,EACA,wBAAwB,QAAQ;AAC9B,UAAM,UAAU;AAGhB,QAAI,CAAC,QAAQ;AACX,aACE,oCAAC,OAAI,gBAAe,iBAAgB,WAAU,UAAS,OAAM,UAC3D,oCAAC,OAAI,eAAc,SACjB,oCAAC,YAAK,qBAAoB,GAC1B,oCAAC,QAAK,OAAO,SAAS,EAAE,iBAAe,cAAY,CACrD,CACF;AAAA,IAEJ;AAEA,QAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,aACE,oCAAC,OAAI,eAAc,YAChB,OAAO,IAAI,CAAC,MAAM,MAAM;AAEvB,YAAI,CAAC,MAAM;AACT,iBAAO;AAAA,QACT;AACA,YAAI,KAAK,SAAS,SAAS;AACzB,iBACE;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,gBAAe;AAAA,cACf,WAAU;AAAA,cACV,OAAM;AAAA;AAAA,YAEN,oCAAC,OAAI,eAAc,SACjB,oCAAC,YAAK,qBAAoB,GAC1B,oCAAC,YAAK,SAAO,CACf;AAAA,UACF;AAAA,QAEJ;AAEA,cAAM,OAAO,KAAK,QAAQ;AAC1B,cAAMA,SAAQ,KAAK,MAAM,IAAI,EAAE;AAC/B,eACE,
|
|
4
|
+
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { type Tool } from '@tool'\nimport { getTheme } from '@utils/theme'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { OutputLine } from '@tools/BashTool/OutputLine'\n\n// Allow any input object since MCP tools define their own schemas\nconst inputSchema = z.object({}).passthrough()\n\nexport const MCPTool = {\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false // MCPTool can modify state through MCP calls, not safe for concurrent execution\n },\n // Overridden in mcpClient.ts\n name: 'mcp',\n // Overridden in mcpClient.ts\n async description() {\n return DESCRIPTION\n },\n // Overridden in mcpClient.ts\n async prompt() {\n return PROMPT\n },\n inputSchema,\n // Overridden in mcpClient.ts\n async *call() {\n yield {\n type: 'result',\n data: '',\n resultForAssistant: '',\n }\n },\n needsPermissions() {\n return true\n },\n renderToolUseMessage(input) {\n return Object.entries(input)\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join(', ')\n },\n // Overridden in mcpClient.ts\n userFacingName: () => 'mcp',\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output) {\n const verbose = false // Set default value for verbose\n\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" overflowX=\"hidden\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={getTheme().secondaryText}>(No content)</Text>\n </Box>\n </Box>\n )\n }\n\n if (Array.isArray(output)) {\n return (\n <Box flexDirection=\"column\">\n {output.map((item, i) => {\n // Guard against null/undefined items in array\n if (!item) {\n return null\n }\n if (item.type === 'image') {\n return (\n <Box\n key={i}\n justifyContent=\"space-between\"\n overflowX=\"hidden\"\n width=\"100%\"\n >\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>[Image]</Text>\n </Box>\n </Box>\n )\n }\n // Guard against missing text property\n const text = item.text || ''\n const lines = text.split('\\n').length\n return (\n <OutputLine\n key={i}\n content={text}\n lines={lines}\n verbose={verbose}\n />\n )\n })}\n </Box>\n )\n }\n\n // Guard against non-string output\n if (typeof output !== 'string') {\n return (\n <Box justifyContent=\"space-between\" overflowX=\"hidden\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={getTheme().secondaryText}>\n MCP operation completed\n </Text>\n </Box>\n </Box>\n )\n }\n\n const lines = output.split('\\n').length\n return <OutputLine content={output} lines={lines} verbose={verbose} />\n },\n renderResultForAssistant(content) {\n return content\n },\n} satisfies Tool<typeof inputSchema, string>\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,KAAK,YAAY;AAC1B,YAAY,WAAW;AACvB,SAAS,SAAS;AAClB,SAAS,sCAAsC;AAE/C,SAAS,gBAAgB;AACzB,SAAS,aAAa,cAAc;AACpC,SAAS,kBAAkB;AAG3B,MAAM,cAAc,EAAE,OAAO,CAAC,CAAC,EAAE,YAAY;AAEtC,MAAM,UAAU;AAAA,EACrB,MAAM,YAAY;AAChB,WAAO;AAAA,EACT;AAAA,EACA,aAAa;AACX,WAAO;AAAA,EACT;AAAA,EACA,oBAAoB;AAClB,WAAO;AAAA,EACT;AAAA;AAAA,EAEA,MAAM;AAAA;AAAA,EAEN,MAAM,cAAc;AAClB,WAAO;AAAA,EACT;AAAA;AAAA,EAEA,MAAM,SAAS;AACb,WAAO;AAAA,EACT;AAAA,EACA;AAAA;AAAA,EAEA,OAAO,OAAO;AACZ,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,oBAAoB;AAAA,IACtB;AAAA,EACF;AAAA,EACA,mBAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EACA,qBAAqB,OAAO;AAC1B,WAAO,OAAO,QAAQ,KAAK,EACxB,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,KAAK,KAAK,UAAU,KAAK,CAAC,EAAE,EACxD,KAAK,IAAI;AAAA,EACd;AAAA;AAAA,EAEA,gBAAgB,MAAM;AAAA,EACtB,+BAA+B;AAC7B,WAAO,oCAAC,oCAA+B;AAAA,EACzC;AAAA,EACA,wBAAwB,QAAQ;AAC9B,UAAM,UAAU;AAGhB,QAAI,CAAC,QAAQ;AACX,aACE,oCAAC,OAAI,gBAAe,iBAAgB,WAAU,UAAS,OAAM,UAC3D,oCAAC,OAAI,eAAc,SACjB,oCAAC,YAAK,qBAAoB,GAC1B,oCAAC,QAAK,OAAO,SAAS,EAAE,iBAAe,cAAY,CACrD,CACF;AAAA,IAEJ;AAEA,QAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,aACE,oCAAC,OAAI,eAAc,YAChB,OAAO,IAAI,CAAC,MAAM,MAAM;AAEvB,YAAI,CAAC,MAAM;AACT,iBAAO;AAAA,QACT;AACA,YAAI,KAAK,SAAS,SAAS;AACzB,iBACE;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,gBAAe;AAAA,cACf,WAAU;AAAA,cACV,OAAM;AAAA;AAAA,YAEN,oCAAC,OAAI,eAAc,SACjB,oCAAC,YAAK,qBAAoB,GAC1B,oCAAC,YAAK,SAAO,CACf;AAAA,UACF;AAAA,QAEJ;AAEA,cAAM,OAAO,KAAK,QAAQ;AAC1B,cAAMA,SAAQ,KAAK,MAAM,IAAI,EAAE;AAC/B,eACE;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,SAAS;AAAA,YACT,OAAOA;AAAA,YACP;AAAA;AAAA,QACF;AAAA,MAEJ,CAAC,CACH;AAAA,IAEJ;AAGA,QAAI,OAAO,WAAW,UAAU;AAC9B,aACE,oCAAC,OAAI,gBAAe,iBAAgB,WAAU,UAAS,OAAM,UAC3D,oCAAC,OAAI,eAAc,SACjB,oCAAC,YAAK,qBAAoB,GAC1B,oCAAC,QAAK,OAAO,SAAS,EAAE,iBAAe,yBAEvC,CACF,CACF;AAAA,IAEJ;AAEA,UAAM,QAAQ,OAAO,MAAM,IAAI,EAAE;AACjC,WAAO,oCAAC,cAAW,SAAS,QAAQ,OAAc,SAAkB;AAAA,EACtE;AAAA,EACA,yBAAyB,SAAS;AAChC,WAAO;AAAA,EACT;AACF;",
|
|
6
6
|
"names": ["lines"]
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync } from "fs";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
|
-
import { join } from "path";
|
|
3
|
+
import { join, resolve } from "path";
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { FallbackToolUseRejectedMessage } from "../../components/FallbackToolUseRejectedMessage.js";
|
|
@@ -44,28 +44,41 @@ const MemoryReadTool = {
|
|
|
44
44
|
return /* @__PURE__ */ React.createElement(FallbackToolUseRejectedMessage, null);
|
|
45
45
|
},
|
|
46
46
|
renderToolResultMessage(output) {
|
|
47
|
+
if (!output) {
|
|
48
|
+
return /* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between", overflowX: "hidden", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Text, null, "(No memory content)")));
|
|
49
|
+
}
|
|
47
50
|
return /* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between", overflowX: "hidden", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Text, null, output.content)));
|
|
48
51
|
},
|
|
49
52
|
async validateInput({ file_path }, context) {
|
|
50
53
|
const agentId = resolveAgentId(context?.agentId);
|
|
51
|
-
const agentMemoryDir =
|
|
54
|
+
const agentMemoryDir = resolve(MEMORY_DIR, "agents", agentId);
|
|
52
55
|
if (file_path) {
|
|
53
|
-
const fullPath =
|
|
54
|
-
if (!fullPath.startsWith(agentMemoryDir)) {
|
|
56
|
+
const fullPath = resolve(agentMemoryDir, file_path);
|
|
57
|
+
if (!fullPath.startsWith(agentMemoryDir + "/") && fullPath !== agentMemoryDir) {
|
|
55
58
|
return { result: false, message: "Invalid memory file path" };
|
|
56
59
|
}
|
|
57
60
|
if (!existsSync(fullPath)) {
|
|
58
61
|
return { result: false, message: "Memory file does not exist" };
|
|
59
62
|
}
|
|
63
|
+
try {
|
|
64
|
+
const stat = lstatSync(fullPath);
|
|
65
|
+
if (stat.isSymbolicLink()) {
|
|
66
|
+
return {
|
|
67
|
+
result: false,
|
|
68
|
+
message: "Symbolic links are not allowed in memory paths"
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
} catch {
|
|
72
|
+
}
|
|
60
73
|
}
|
|
61
74
|
return { result: true };
|
|
62
75
|
},
|
|
63
76
|
async *call({ file_path }, context) {
|
|
64
77
|
const agentId = resolveAgentId(context?.agentId);
|
|
65
|
-
const agentMemoryDir =
|
|
78
|
+
const agentMemoryDir = resolve(MEMORY_DIR, "agents", agentId);
|
|
66
79
|
mkdirSync(agentMemoryDir, { recursive: true });
|
|
67
80
|
if (file_path) {
|
|
68
|
-
const fullPath =
|
|
81
|
+
const fullPath = resolve(agentMemoryDir, file_path);
|
|
69
82
|
if (!existsSync(fullPath)) {
|
|
70
83
|
throw new Error("Memory file does not exist");
|
|
71
84
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/MemoryReadTool/MemoryReadTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync } from 'fs'\nimport { Box, Text } from 'ink'\nimport { join } from 'path'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { MEMORY_DIR } from '@utils/env'\nimport { resolveAgentId } from '@utils/agentStorage'\nimport { DESCRIPTION, PROMPT } from './prompt'\n\nconst inputSchema = z.strictObject({\n file_path: z\n .string()\n .optional()\n .describe('Optional path to a specific memory file to read'),\n})\n\nexport const MemoryReadTool = {\n name: 'MemoryRead',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Read Memory'\n },\n async isEnabled() {\n //
|
|
5
|
-
"mappings": "AAAA,SAAS,YAAY,WAAW,WAAW,aAAa,oBAAoB;AAC5E,SAAS,KAAK,YAAY;AAC1B,SAAS,
|
|
4
|
+
"sourcesContent": ["import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync } from 'fs'\nimport { Box, Text } from 'ink'\nimport { join, resolve } from 'path'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { MEMORY_DIR } from '@utils/env'\nimport { resolveAgentId } from '@utils/agentStorage'\nimport { DESCRIPTION, PROMPT } from './prompt'\n\nconst inputSchema = z.strictObject({\n file_path: z\n .string()\n .optional()\n .describe('Optional path to a specific memory file to read'),\n})\n\nexport const MemoryReadTool = {\n name: 'MemoryRead',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Read Memory'\n },\n async isEnabled() {\n // Memory tools are currently disabled pending:\n // 1. User-facing configuration UI for enabling/disabling\n // 2. Security review of path traversal handling\n // 3. Documentation of memory storage format and lifecycle\n // These tools are for agent-level persistent memory across sessions\n return false\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true // MemoryRead is read-only, safe for concurrent execution\n },\n needsPermissions() {\n return false\n },\n renderResultForAssistant({ content }) {\n return content\n },\n renderToolUseMessage(input) {\n return Object.entries(input)\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join(', ')\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output) {\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" overflowX=\"hidden\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>(No memory content)</Text>\n </Box>\n </Box>\n )\n }\n\n return (\n <Box justifyContent=\"space-between\" overflowX=\"hidden\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>{output.content}</Text>\n </Box>\n </Box>\n )\n },\n async validateInput({ file_path }, context) {\n const agentId = resolveAgentId(context?.agentId)\n const agentMemoryDir = resolve(MEMORY_DIR, 'agents', agentId)\n\n if (file_path) {\n // Use resolve() to normalize paths and prevent path traversal attacks\n // join() alone doesn't protect against \"../\" sequences\n const fullPath = resolve(agentMemoryDir, file_path)\n if (\n !fullPath.startsWith(agentMemoryDir + '/') &&\n fullPath !== agentMemoryDir\n ) {\n return { result: false, message: 'Invalid memory file path' }\n }\n if (!existsSync(fullPath)) {\n return { result: false, message: 'Memory file does not exist' }\n }\n // Check for symlinks that could escape the directory\n try {\n const stat = lstatSync(fullPath)\n if (stat.isSymbolicLink()) {\n return {\n result: false,\n message: 'Symbolic links are not allowed in memory paths',\n }\n }\n } catch {\n // File doesn't exist or can't be accessed, will be caught above\n }\n }\n return { result: true }\n },\n async *call({ file_path }, context) {\n const agentId = resolveAgentId(context?.agentId)\n const agentMemoryDir = resolve(MEMORY_DIR, 'agents', agentId)\n mkdirSync(agentMemoryDir, { recursive: true })\n\n // If a specific file is requested, return its contents\n if (file_path) {\n const fullPath = resolve(agentMemoryDir, file_path)\n if (!existsSync(fullPath)) {\n throw new Error('Memory file does not exist')\n }\n const content = readFileSync(fullPath, 'utf-8')\n yield {\n type: 'result',\n data: {\n content,\n },\n resultForAssistant: this.renderResultForAssistant({ content }),\n }\n return\n }\n\n // Otherwise return the index and file list for this agent\n const files = readdirSync(agentMemoryDir, { recursive: true })\n .map(f => join(agentMemoryDir, f.toString()))\n .filter(f => !lstatSync(f).isDirectory())\n .map(f => `- ${f}`)\n .join('\\n')\n\n const indexPath = join(agentMemoryDir, 'index.md')\n const index = existsSync(indexPath) ? readFileSync(indexPath, 'utf-8') : ''\n\n const quotes = \"'''\"\n const content = `Here are the contents of the agent memory file, \\`${indexPath}\\`:\n${quotes}\n${index}\n${quotes}\n\nFiles in the agent memory directory:\n${files}`\n yield {\n type: 'result',\n data: { content },\n resultForAssistant: this.renderResultForAssistant({ content }),\n }\n },\n} satisfies Tool<typeof inputSchema, { content: string }>\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["content"]
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mkdirSync, writeFileSync } from "fs";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
|
-
import { dirname,
|
|
3
|
+
import { dirname, resolve } from "path";
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { FallbackToolUseRejectedMessage } from "../../components/FallbackToolUseRejectedMessage.js";
|
|
@@ -50,17 +50,17 @@ const MemoryWriteTool = {
|
|
|
50
50
|
},
|
|
51
51
|
async validateInput({ file_path }, context) {
|
|
52
52
|
const agentId = resolveAgentId(context?.agentId);
|
|
53
|
-
const agentMemoryDir =
|
|
54
|
-
const fullPath =
|
|
55
|
-
if (!fullPath.startsWith(agentMemoryDir)) {
|
|
53
|
+
const agentMemoryDir = resolve(MEMORY_DIR, "agents", agentId);
|
|
54
|
+
const fullPath = resolve(agentMemoryDir, file_path);
|
|
55
|
+
if (!fullPath.startsWith(agentMemoryDir + "/") && fullPath !== agentMemoryDir) {
|
|
56
56
|
return { result: false, message: "Invalid memory file path" };
|
|
57
57
|
}
|
|
58
58
|
return { result: true };
|
|
59
59
|
},
|
|
60
60
|
async *call({ file_path, content }, context) {
|
|
61
61
|
const agentId = resolveAgentId(context?.agentId);
|
|
62
|
-
const agentMemoryDir =
|
|
63
|
-
const fullPath =
|
|
62
|
+
const agentMemoryDir = resolve(MEMORY_DIR, "agents", agentId);
|
|
63
|
+
const fullPath = resolve(agentMemoryDir, file_path);
|
|
64
64
|
mkdirSync(dirname(fullPath), { recursive: true });
|
|
65
65
|
writeFileSync(fullPath, content, "utf-8");
|
|
66
66
|
recordFileEdit(fullPath, content);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/MemoryWriteTool/MemoryWriteTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { mkdirSync, writeFileSync } from 'fs'\nimport { Box, Text } from 'ink'\nimport { dirname, join } from 'path'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { MEMORY_DIR } from '@utils/env'\nimport { resolveAgentId } from '@utils/agentStorage'\nimport { recordFileEdit } from '@services/fileFreshness'\nimport { DESCRIPTION, PROMPT } from './prompt'\n\nconst inputSchema = z.strictObject({\n file_path: z.string().describe('Path to the memory file to write'),\n content: z.string().describe('Content to write to the file'),\n})\n\nexport const MemoryWriteTool = {\n name: 'MemoryWrite',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Write Memory'\n },\n async isEnabled() {\n //
|
|
5
|
-
"mappings": "AAAA,SAAS,WAAW,qBAAqB;AACzC,SAAS,KAAK,YAAY;AAC1B,SAAS,
|
|
4
|
+
"sourcesContent": ["import { mkdirSync, writeFileSync } from 'fs'\nimport { Box, Text } from 'ink'\nimport { dirname, join, resolve } from 'path'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { MEMORY_DIR } from '@utils/env'\nimport { resolveAgentId } from '@utils/agentStorage'\nimport { recordFileEdit } from '@services/fileFreshness'\nimport { DESCRIPTION, PROMPT } from './prompt'\n\nconst inputSchema = z.strictObject({\n file_path: z.string().describe('Path to the memory file to write'),\n content: z.string().describe('Content to write to the file'),\n})\n\nexport const MemoryWriteTool = {\n name: 'MemoryWrite',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Write Memory'\n },\n async isEnabled() {\n // Memory tools are currently disabled pending:\n // 1. User-facing configuration UI for enabling/disabling\n // 2. Security review of path traversal handling\n // 3. Documentation of memory storage format and lifecycle\n // These tools are for agent-level persistent memory across sessions\n return false\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false // MemoryWrite modifies state, not safe for concurrent execution\n },\n needsPermissions() {\n return false\n },\n renderResultForAssistant(content) {\n return content\n },\n renderToolUseMessage(input) {\n return Object.entries(input)\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join(', ')\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage() {\n return (\n <Box justifyContent=\"space-between\" overflowX=\"hidden\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>{' '}\u23BF Updated memory</Text>\n </Box>\n </Box>\n )\n },\n async validateInput({ file_path }, context) {\n const agentId = resolveAgentId(context?.agentId)\n const agentMemoryDir = resolve(MEMORY_DIR, 'agents', agentId)\n // Use resolve() to normalize paths and prevent path traversal attacks\n // join() alone doesn't protect against \"../\" sequences\n const fullPath = resolve(agentMemoryDir, file_path)\n if (\n !fullPath.startsWith(agentMemoryDir + '/') &&\n fullPath !== agentMemoryDir\n ) {\n return { result: false, message: 'Invalid memory file path' }\n }\n return { result: true }\n },\n async *call({ file_path, content }, context) {\n const agentId = resolveAgentId(context?.agentId)\n const agentMemoryDir = resolve(MEMORY_DIR, 'agents', agentId)\n const fullPath = resolve(agentMemoryDir, file_path)\n mkdirSync(dirname(fullPath), { recursive: true })\n writeFileSync(fullPath, content, 'utf-8')\n\n // Record Agent edit operation for file freshness tracking\n recordFileEdit(fullPath, content)\n\n yield {\n type: 'result',\n data: 'Saved',\n resultForAssistant: 'Saved',\n }\n },\n} satisfies Tool<typeof inputSchema, string>\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,WAAW,qBAAqB;AACzC,SAAS,KAAK,YAAY;AAC1B,SAAS,SAAe,eAAe;AACvC,YAAY,WAAW;AACvB,SAAS,SAAS;AAClB,SAAS,sCAAsC;AAE/C,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,aAAa,cAAc;AAEpC,MAAM,cAAc,EAAE,aAAa;AAAA,EACjC,WAAW,EAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,EACjE,SAAS,EAAE,OAAO,EAAE,SAAS,8BAA8B;AAC7D,CAAC;AAEM,MAAM,kBAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,MAAM,cAAc;AAClB,WAAO;AAAA,EACT;AAAA,EACA,MAAM,SAAS;AACb,WAAO;AAAA,EACT;AAAA,EACA;AAAA,EACA,iBAAiB;AACf,WAAO;AAAA,EACT;AAAA,EACA,MAAM,YAAY;AAMhB,WAAO;AAAA,EACT;AAAA,EACA,aAAa;AACX,WAAO;AAAA,EACT;AAAA,EACA,oBAAoB;AAClB,WAAO;AAAA,EACT;AAAA,EACA,mBAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EACA,yBAAyB,SAAS;AAChC,WAAO;AAAA,EACT;AAAA,EACA,qBAAqB,OAAO;AAC1B,WAAO,OAAO,QAAQ,KAAK,EACxB,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,KAAK,KAAK,UAAU,KAAK,CAAC,EAAE,EACxD,KAAK,IAAI;AAAA,EACd;AAAA,EACA,+BAA+B;AAC7B,WAAO,oCAAC,oCAA+B;AAAA,EACzC;AAAA,EACA,0BAA0B;AACxB,WACE,oCAAC,OAAI,gBAAe,iBAAgB,WAAU,UAAS,OAAM,UAC3D,oCAAC,OAAI,eAAc,SACjB,oCAAC,YAAM,MAAK,uBAAgB,CAC9B,CACF;AAAA,EAEJ;AAAA,EACA,MAAM,cAAc,EAAE,UAAU,GAAG,SAAS;AAC1C,UAAM,UAAU,eAAe,SAAS,OAAO;AAC/C,UAAM,iBAAiB,QAAQ,YAAY,UAAU,OAAO;AAG5D,UAAM,WAAW,QAAQ,gBAAgB,SAAS;AAClD,QACE,CAAC,SAAS,WAAW,iBAAiB,GAAG,KACzC,aAAa,gBACb;AACA,aAAO,EAAE,QAAQ,OAAO,SAAS,2BAA2B;AAAA,IAC9D;AACA,WAAO,EAAE,QAAQ,KAAK;AAAA,EACxB;AAAA,EACA,OAAO,KAAK,EAAE,WAAW,QAAQ,GAAG,SAAS;AAC3C,UAAM,UAAU,eAAe,SAAS,OAAO;AAC/C,UAAM,iBAAiB,QAAQ,YAAY,UAAU,OAAO;AAC5D,UAAM,WAAW,QAAQ,gBAAgB,SAAS;AAClD,cAAU,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAChD,kBAAc,UAAU,SAAS,OAAO;AAGxC,mBAAe,UAAU,OAAO;AAEhC,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,oBAAoB;AAAA,IACtB;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -91,7 +91,11 @@ ${editSummary}`;
|
|
|
91
91
|
renderToolUseRejectedMessage() {
|
|
92
92
|
return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: getTheme().error }, "\u26A0 Edit request rejected"));
|
|
93
93
|
},
|
|
94
|
-
renderToolResultMessage(output) {
|
|
94
|
+
renderToolResultMessage(output, options) {
|
|
95
|
+
const verbose = options?.verbose ?? false;
|
|
96
|
+
if (!output) {
|
|
97
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "Multi-edit completed"));
|
|
98
|
+
}
|
|
95
99
|
if (typeof output === "string") {
|
|
96
100
|
const isError = output.includes("Error:");
|
|
97
101
|
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: isError ? getTheme().error : getTheme().success }, output));
|
|
@@ -101,7 +105,7 @@ ${editSummary}`;
|
|
|
101
105
|
{
|
|
102
106
|
filePath: output.filePath,
|
|
103
107
|
structuredPatch: output.structuredPatch,
|
|
104
|
-
verbose
|
|
108
|
+
verbose
|
|
105
109
|
}
|
|
106
110
|
);
|
|
107
111
|
},
|
|
@@ -221,9 +225,22 @@ ${editSummary}`;
|
|
|
221
225
|
}
|
|
222
226
|
let modifiedContent = currentContent;
|
|
223
227
|
const appliedEdits = [];
|
|
228
|
+
const totalEdits = edits.length;
|
|
224
229
|
for (let i = 0; i < edits.length; i++) {
|
|
225
230
|
const edit = edits[i];
|
|
226
231
|
const { old_string, new_string, replace_all } = edit;
|
|
232
|
+
if (totalEdits > 1) {
|
|
233
|
+
yield {
|
|
234
|
+
type: "progress",
|
|
235
|
+
content: {
|
|
236
|
+
type: "streaming",
|
|
237
|
+
toolName: "Multi-Edit",
|
|
238
|
+
stdout: `Applying edit ${i + 1}/${totalEdits}...`,
|
|
239
|
+
stderr: "",
|
|
240
|
+
isStreaming: true
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
}
|
|
227
244
|
try {
|
|
228
245
|
const result = applyContentEdit(
|
|
229
246
|
modifiedContent,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/MultiEditTool/MultiEditTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { existsSync, mkdirSync, readFileSync, statSync } from 'fs'\nimport { Box, Text } from 'ink'\nimport { dirname, isAbsolute, relative, resolve, sep } from 'path'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FileEditToolUpdatedMessage } from '@components/FileEditToolUpdatedMessage'\nimport { StructuredDiff } from '@components/StructuredDiff'\nimport { Tool, ValidationResult } from '@tool'\nimport { intersperse } from '@utils/array'\nimport {\n addLineNumbers,\n detectFileEncoding,\n detectLineEndings,\n findSimilarFile,\n writeTextContent,\n} from '@utils/file'\nimport { logError } from '@utils/log'\nimport { getCwd } from '@utils/state'\nimport { getTheme } from '@utils/theme'\nimport { NotebookEditTool } from '@tools/NotebookEditTool/NotebookEditTool'\n// Local content-based edit function for MultiEditTool\nfunction applyContentEdit(\n content: string,\n oldString: string,\n newString: string,\n replaceAll: boolean = false,\n): { newContent: string; occurrences: number } {\n if (replaceAll) {\n const regex = new RegExp(\n oldString.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'),\n 'g',\n )\n const matches = content.match(regex)\n const occurrences = matches ? matches.length : 0\n const newContent = content.replace(regex, newString)\n return { newContent, occurrences }\n } else {\n if (content.includes(oldString)) {\n const newContent = content.replace(oldString, newString)\n return { newContent, occurrences: 1 }\n } else {\n throw new Error(`String not found: ${oldString.substring(0, 50)}...`)\n }\n }\n}\nimport { hasWritePermission } from '@utils/permissions/filesystem'\nimport { PROJECT_FILE } from '@constants/product'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { recordFileEdit } from '@services/fileFreshness'\nimport { getPatch } from '@utils/diff'\n\nconst EditSchema = z.object({\n old_string: z.string().describe('The text to replace'),\n new_string: z.string().describe('The text to replace it with'),\n replace_all: z\n .boolean()\n .optional()\n .default(false)\n .describe('Replace all occurences of old_string (default false)'),\n})\n\nconst inputSchema = z.strictObject({\n file_path: z.string().describe('The absolute path to the file to modify'),\n edits: z\n .array(EditSchema)\n .min(1)\n .describe('Array of edit operations to perform sequentially on the file'),\n})\n\nexport type In = typeof inputSchema\n\n// Number of lines of context to include before/after the change in our result message\nconst N_LINES_SNIPPET = 4\n\nexport const MultiEditTool = {\n name: 'MultiEdit',\n async description() {\n return 'A tool for making multiple edits to a single file atomically'\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Multi-Edit'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false // MultiEdit modifies files, not safe for concurrent execution\n },\n needsPermissions(input?: z.infer<typeof inputSchema>) {\n if (!input) return true\n return !hasWritePermission(input.file_path)\n },\n renderResultForAssistant(content) {\n return content\n },\n renderToolUseMessage(input, { verbose }) {\n const { file_path, edits } = input\n const workingDir = getCwd()\n const relativePath = isAbsolute(file_path)\n ? relative(workingDir, file_path)\n : file_path\n\n if (verbose) {\n const editSummary = edits\n .map(\n (edit, index) =>\n `${index + 1}. Replace \"${edit.old_string.substring(0, 50)}${edit.old_string.length > 50 ? '...' : ''}\" with \"${edit.new_string.substring(0, 50)}${edit.new_string.length > 50 ? '...' : ''}\"`,\n )\n .join('\\n')\n return `Multiple edits to ${relativePath}:\\n${editSummary}`\n }\n\n return `Making ${edits.length} edits to ${relativePath}`\n },\n renderToolUseRejectedMessage() {\n return (\n <Box>\n <Text color={getTheme().error}>\u26A0 Edit request rejected</Text>\n </Box>\n )\n },\n renderToolResultMessage(output) {\n if (typeof output === 'string') {\n const isError = output.includes('Error:')\n return (\n <Box flexDirection=\"column\">\n <Text color={isError ? getTheme().error : getTheme().success}>\n {output}\n </Text>\n </Box>\n )\n }\n\n return (\n <FileEditToolUpdatedMessage\n filePath={output.filePath}\n structuredPatch={output.structuredPatch}\n verbose={false}\n />\n )\n },\n async validateInput(\n { file_path, edits }: z.infer<typeof inputSchema>,\n context?: { readFileTimestamps?: Record<string, number> },\n ): Promise<ValidationResult> {\n const workingDir = getCwd()\n const normalizedPath = isAbsolute(file_path)\n ? resolve(file_path)\n : resolve(workingDir, file_path)\n\n // Check if it's a notebook file\n if (normalizedPath.endsWith('.ipynb')) {\n return {\n result: false,\n errorCode: 1,\n message: `For Jupyter notebooks (.ipynb files), use the ${NotebookEditTool.name} tool instead.`,\n }\n }\n\n // For new files, check parent directory exists\n if (!existsSync(normalizedPath)) {\n const parentDir = dirname(normalizedPath)\n if (!existsSync(parentDir)) {\n return {\n result: false,\n errorCode: 2,\n message: `Parent directory does not exist: ${parentDir}`,\n }\n }\n\n // For new files, ensure first edit creates the file (empty old_string)\n if (edits.length === 0 || edits[0].old_string !== '') {\n return {\n result: false,\n errorCode: 6,\n message:\n 'For new files, the first edit must have an empty old_string to create the file content.',\n }\n }\n } else {\n // For existing files, apply file protection mechanisms\n const readFileTimestamps = context?.readFileTimestamps || {}\n const readTimestamp = readFileTimestamps[normalizedPath]\n\n if (!readTimestamp) {\n return {\n result: false,\n errorCode: 7,\n message:\n 'File has not been read yet. Read it first before editing it.',\n meta: {\n filePath: normalizedPath,\n isFilePathAbsolute: String(isAbsolute(file_path)),\n },\n }\n }\n\n // Check if file has been modified since last read\n const stats = statSync(normalizedPath)\n const lastWriteTime = stats.mtimeMs\n if (lastWriteTime > readTimestamp) {\n return {\n result: false,\n errorCode: 8,\n message:\n 'File has been modified since read, either by the user or by a linter. Read it again before attempting to edit it.',\n meta: {\n filePath: normalizedPath,\n lastWriteTime,\n readTimestamp,\n },\n }\n }\n\n // Pre-validate that all old_strings exist in the file\n const encoding = detectFileEncoding(normalizedPath)\n if (encoding === 'binary') {\n return {\n result: false,\n errorCode: 9,\n message: 'Cannot edit binary files.',\n }\n }\n\n const currentContent = readFileSync(normalizedPath, 'utf-8')\n for (let i = 0; i < edits.length; i++) {\n const edit = edits[i]\n if (\n edit.old_string !== '' &&\n !currentContent.includes(edit.old_string)\n ) {\n return {\n result: false,\n errorCode: 10,\n message: `Edit ${i + 1}: String to replace not found in file: \"${edit.old_string.substring(0, 100)}${edit.old_string.length > 100 ? '...' : ''}\"`,\n meta: {\n editIndex: i + 1,\n oldString: edit.old_string.substring(0, 200),\n },\n }\n }\n }\n }\n\n // Validate each edit\n for (let i = 0; i < edits.length; i++) {\n const edit = edits[i]\n if (edit.old_string === edit.new_string) {\n return {\n result: false,\n errorCode: 3,\n message: `Edit ${i + 1}: old_string and new_string cannot be the same`,\n }\n }\n }\n\n return { result: true }\n },\n async *call({ file_path, edits }, { readFileTimestamps }) {\n const startTime = Date.now()\n const workingDir = getCwd()\n const filePath = isAbsolute(file_path)\n ? resolve(file_path)\n : resolve(workingDir, file_path)\n\n try {\n // Read current file content (or empty for new files)\n let currentContent = ''\n let fileExists = existsSync(filePath)\n\n if (fileExists) {\n const encoding = detectFileEncoding(filePath)\n if (encoding === 'binary') {\n yield {\n type: 'result',\n data: 'Error: Cannot edit binary files',\n resultForAssistant: 'Error: Cannot edit binary files',\n }\n return\n }\n currentContent = readFileSync(filePath, 'utf-8')\n } else {\n // For new files, ensure parent directory exists\n const parentDir = dirname(filePath)\n if (!existsSync(parentDir)) {\n mkdirSync(parentDir, { recursive: true })\n }\n }\n\n // Apply all edits sequentially\n let modifiedContent = currentContent\n const appliedEdits = []\n\n for (let i = 0; i < edits.length; i++) {\n const edit = edits[i]\n const { old_string, new_string, replace_all } = edit\n\n try {\n const result = applyContentEdit(\n modifiedContent,\n old_string,\n new_string,\n replace_all,\n )\n modifiedContent = result.newContent\n appliedEdits.push({\n editIndex: i + 1,\n success: true,\n old_string: old_string.substring(0, 100),\n new_string: new_string.substring(0, 100),\n occurrences: result.occurrences,\n })\n } catch (error) {\n // If any edit fails, abort the entire operation\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error'\n yield {\n type: 'result',\n data: `Error in edit ${i + 1}: ${errorMessage}`,\n resultForAssistant: `Error in edit ${i + 1}: ${errorMessage}`,\n }\n return\n }\n }\n\n // Write the modified content\n const lineEndings = fileExists ? detectLineEndings(currentContent) : 'LF'\n const encoding = fileExists ? detectFileEncoding(filePath) : 'utf8'\n writeTextContent(filePath, modifiedContent, encoding, lineEndings)\n\n // Record Agent edit operation for file freshness tracking\n recordFileEdit(filePath, modifiedContent)\n\n // Update readFileTimestamps to prevent stale file warnings\n readFileTimestamps[filePath] = Date.now()\n\n // Emit file edited event for system reminders\n emitReminderEvent('file:edited', {\n filePath,\n edits: edits.map(e => ({\n oldString: e.old_string,\n newString: e.new_string,\n })),\n originalContent: currentContent,\n newContent: modifiedContent,\n timestamp: Date.now(),\n operation: fileExists ? 'update' : 'create',\n })\n\n // Generate result data\n const relativePath = relative(workingDir, filePath)\n const summary = `Successfully applied ${edits.length} edits to ${relativePath}`\n\n const structuredPatch = getPatch({\n filePath: file_path,\n fileContents: currentContent,\n oldStr: currentContent,\n newStr: modifiedContent,\n })\n\n const resultData = {\n filePath: file_path,\n wasNewFile: !fileExists,\n editsApplied: appliedEdits,\n totalEdits: edits.length,\n summary,\n structuredPatch,\n }\n\n // Log the operation\n\n yield {\n type: 'result',\n data: resultData,\n resultForAssistant: summary,\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n const errorResult = `Error applying multi-edit: ${errorMessage}`\n\n logError(error)\n\n yield {\n type: 'result',\n data: errorResult,\n resultForAssistant: errorResult,\n }\n }\n },\n} satisfies Tool<typeof inputSchema, any>\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { existsSync, mkdirSync, readFileSync, statSync } from 'fs'\nimport { Box, Text } from 'ink'\nimport { dirname, isAbsolute, relative, resolve, sep } from 'path'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FileEditToolUpdatedMessage } from '@components/FileEditToolUpdatedMessage'\nimport { StructuredDiff } from '@components/StructuredDiff'\nimport { Tool, ValidationResult } from '@tool'\nimport { intersperse } from '@utils/array'\nimport {\n addLineNumbers,\n detectFileEncoding,\n detectLineEndings,\n findSimilarFile,\n writeTextContent,\n} from '@utils/file'\nimport { logError } from '@utils/log'\nimport { getCwd } from '@utils/state'\nimport { getTheme } from '@utils/theme'\nimport { NotebookEditTool } from '@tools/NotebookEditTool/NotebookEditTool'\n// Local content-based edit function for MultiEditTool\nfunction applyContentEdit(\n content: string,\n oldString: string,\n newString: string,\n replaceAll: boolean = false,\n): { newContent: string; occurrences: number } {\n if (replaceAll) {\n const regex = new RegExp(\n oldString.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'),\n 'g',\n )\n const matches = content.match(regex)\n const occurrences = matches ? matches.length : 0\n const newContent = content.replace(regex, newString)\n return { newContent, occurrences }\n } else {\n if (content.includes(oldString)) {\n const newContent = content.replace(oldString, newString)\n return { newContent, occurrences: 1 }\n } else {\n throw new Error(`String not found: ${oldString.substring(0, 50)}...`)\n }\n }\n}\nimport { hasWritePermission } from '@utils/permissions/filesystem'\nimport { PROJECT_FILE } from '@constants/product'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { recordFileEdit } from '@services/fileFreshness'\nimport { getPatch } from '@utils/diff'\n\nconst EditSchema = z.object({\n old_string: z.string().describe('The text to replace'),\n new_string: z.string().describe('The text to replace it with'),\n replace_all: z\n .boolean()\n .optional()\n .default(false)\n .describe('Replace all occurences of old_string (default false)'),\n})\n\nconst inputSchema = z.strictObject({\n file_path: z.string().describe('The absolute path to the file to modify'),\n edits: z\n .array(EditSchema)\n .min(1)\n .describe('Array of edit operations to perform sequentially on the file'),\n})\n\nexport type In = typeof inputSchema\n\n// Number of lines of context to include before/after the change in our result message\nconst N_LINES_SNIPPET = 4\n\nexport const MultiEditTool = {\n name: 'MultiEdit',\n async description() {\n return 'A tool for making multiple edits to a single file atomically'\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Multi-Edit'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false // MultiEdit modifies files, not safe for concurrent execution\n },\n needsPermissions(input?: z.infer<typeof inputSchema>) {\n if (!input) return true\n return !hasWritePermission(input.file_path)\n },\n renderResultForAssistant(content) {\n return content\n },\n renderToolUseMessage(input, { verbose }) {\n const { file_path, edits } = input\n const workingDir = getCwd()\n const relativePath = isAbsolute(file_path)\n ? relative(workingDir, file_path)\n : file_path\n\n if (verbose) {\n const editSummary = edits\n .map(\n (edit, index) =>\n `${index + 1}. Replace \"${edit.old_string.substring(0, 50)}${edit.old_string.length > 50 ? '...' : ''}\" with \"${edit.new_string.substring(0, 50)}${edit.new_string.length > 50 ? '...' : ''}\"`,\n )\n .join('\\n')\n return `Multiple edits to ${relativePath}:\\n${editSummary}`\n }\n\n return `Making ${edits.length} edits to ${relativePath}`\n },\n renderToolUseRejectedMessage() {\n return (\n <Box>\n <Text color={getTheme().error}>\u26A0 Edit request rejected</Text>\n </Box>\n )\n },\n renderToolResultMessage(output, options?: { verbose?: boolean }) {\n const verbose = options?.verbose ?? false\n\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box flexDirection=\"column\">\n <Text color={getTheme().secondaryText}>Multi-edit completed</Text>\n </Box>\n )\n }\n\n if (typeof output === 'string') {\n const isError = output.includes('Error:')\n return (\n <Box flexDirection=\"column\">\n <Text color={isError ? getTheme().error : getTheme().success}>\n {output}\n </Text>\n </Box>\n )\n }\n\n return (\n <FileEditToolUpdatedMessage\n filePath={output.filePath}\n structuredPatch={output.structuredPatch}\n verbose={verbose}\n />\n )\n },\n async validateInput(\n { file_path, edits }: z.infer<typeof inputSchema>,\n context?: { readFileTimestamps?: Record<string, number> },\n ): Promise<ValidationResult> {\n const workingDir = getCwd()\n const normalizedPath = isAbsolute(file_path)\n ? resolve(file_path)\n : resolve(workingDir, file_path)\n\n // Check if it's a notebook file\n if (normalizedPath.endsWith('.ipynb')) {\n return {\n result: false,\n errorCode: 1,\n message: `For Jupyter notebooks (.ipynb files), use the ${NotebookEditTool.name} tool instead.`,\n }\n }\n\n // For new files, check parent directory exists\n if (!existsSync(normalizedPath)) {\n const parentDir = dirname(normalizedPath)\n if (!existsSync(parentDir)) {\n return {\n result: false,\n errorCode: 2,\n message: `Parent directory does not exist: ${parentDir}`,\n }\n }\n\n // For new files, ensure first edit creates the file (empty old_string)\n if (edits.length === 0 || edits[0].old_string !== '') {\n return {\n result: false,\n errorCode: 6,\n message:\n 'For new files, the first edit must have an empty old_string to create the file content.',\n }\n }\n } else {\n // For existing files, apply file protection mechanisms\n const readFileTimestamps = context?.readFileTimestamps || {}\n const readTimestamp = readFileTimestamps[normalizedPath]\n\n if (!readTimestamp) {\n return {\n result: false,\n errorCode: 7,\n message:\n 'File has not been read yet. Read it first before editing it.',\n meta: {\n filePath: normalizedPath,\n isFilePathAbsolute: String(isAbsolute(file_path)),\n },\n }\n }\n\n // Check if file has been modified since last read\n const stats = statSync(normalizedPath)\n const lastWriteTime = stats.mtimeMs\n if (lastWriteTime > readTimestamp) {\n return {\n result: false,\n errorCode: 8,\n message:\n 'File has been modified since read, either by the user or by a linter. Read it again before attempting to edit it.',\n meta: {\n filePath: normalizedPath,\n lastWriteTime,\n readTimestamp,\n },\n }\n }\n\n // Pre-validate that all old_strings exist in the file\n const encoding = detectFileEncoding(normalizedPath)\n if (encoding === 'binary') {\n return {\n result: false,\n errorCode: 9,\n message: 'Cannot edit binary files.',\n }\n }\n\n const currentContent = readFileSync(normalizedPath, 'utf-8')\n for (let i = 0; i < edits.length; i++) {\n const edit = edits[i]\n if (\n edit.old_string !== '' &&\n !currentContent.includes(edit.old_string)\n ) {\n return {\n result: false,\n errorCode: 10,\n message: `Edit ${i + 1}: String to replace not found in file: \"${edit.old_string.substring(0, 100)}${edit.old_string.length > 100 ? '...' : ''}\"`,\n meta: {\n editIndex: i + 1,\n oldString: edit.old_string.substring(0, 200),\n },\n }\n }\n }\n }\n\n // Validate each edit\n for (let i = 0; i < edits.length; i++) {\n const edit = edits[i]\n if (edit.old_string === edit.new_string) {\n return {\n result: false,\n errorCode: 3,\n message: `Edit ${i + 1}: old_string and new_string cannot be the same`,\n }\n }\n }\n\n return { result: true }\n },\n async *call({ file_path, edits }, { readFileTimestamps }) {\n const startTime = Date.now()\n const workingDir = getCwd()\n const filePath = isAbsolute(file_path)\n ? resolve(file_path)\n : resolve(workingDir, file_path)\n\n try {\n // Read current file content (or empty for new files)\n let currentContent = ''\n let fileExists = existsSync(filePath)\n\n if (fileExists) {\n const encoding = detectFileEncoding(filePath)\n if (encoding === 'binary') {\n yield {\n type: 'result',\n data: 'Error: Cannot edit binary files',\n resultForAssistant: 'Error: Cannot edit binary files',\n }\n return\n }\n currentContent = readFileSync(filePath, 'utf-8')\n } else {\n // For new files, ensure parent directory exists\n const parentDir = dirname(filePath)\n if (!existsSync(parentDir)) {\n mkdirSync(parentDir, { recursive: true })\n }\n }\n\n // Apply all edits sequentially with progress updates\n let modifiedContent = currentContent\n const appliedEdits = []\n const totalEdits = edits.length\n\n for (let i = 0; i < edits.length; i++) {\n const edit = edits[i]\n const { old_string, new_string, replace_all } = edit\n\n // Yield progress update for multi-edit operations\n if (totalEdits > 1) {\n yield {\n type: 'progress',\n content: {\n type: 'streaming',\n toolName: 'Multi-Edit',\n stdout: `Applying edit ${i + 1}/${totalEdits}...`,\n stderr: '',\n isStreaming: true,\n },\n }\n }\n\n try {\n const result = applyContentEdit(\n modifiedContent,\n old_string,\n new_string,\n replace_all,\n )\n modifiedContent = result.newContent\n appliedEdits.push({\n editIndex: i + 1,\n success: true,\n old_string: old_string.substring(0, 100),\n new_string: new_string.substring(0, 100),\n occurrences: result.occurrences,\n })\n } catch (error) {\n // If any edit fails, abort the entire operation\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error'\n yield {\n type: 'result',\n data: `Error in edit ${i + 1}: ${errorMessage}`,\n resultForAssistant: `Error in edit ${i + 1}: ${errorMessage}`,\n }\n return\n }\n }\n\n // Write the modified content\n const lineEndings = fileExists ? detectLineEndings(currentContent) : 'LF'\n const encoding = fileExists ? detectFileEncoding(filePath) : 'utf8'\n writeTextContent(filePath, modifiedContent, encoding, lineEndings)\n\n // Record Agent edit operation for file freshness tracking\n recordFileEdit(filePath, modifiedContent)\n\n // Update readFileTimestamps to prevent stale file warnings\n readFileTimestamps[filePath] = Date.now()\n\n // Emit file edited event for system reminders\n emitReminderEvent('file:edited', {\n filePath,\n edits: edits.map(e => ({\n oldString: e.old_string,\n newString: e.new_string,\n })),\n originalContent: currentContent,\n newContent: modifiedContent,\n timestamp: Date.now(),\n operation: fileExists ? 'update' : 'create',\n })\n\n // Generate result data\n const relativePath = relative(workingDir, filePath)\n const summary = `Successfully applied ${edits.length} edits to ${relativePath}`\n\n const structuredPatch = getPatch({\n filePath: file_path,\n fileContents: currentContent,\n oldStr: currentContent,\n newStr: modifiedContent,\n })\n\n const resultData = {\n filePath: file_path,\n wasNewFile: !fileExists,\n editsApplied: appliedEdits,\n totalEdits: edits.length,\n summary,\n structuredPatch,\n }\n\n // Log the operation\n\n yield {\n type: 'result',\n data: resultData,\n resultForAssistant: summary,\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n const errorResult = `Error applying multi-edit: ${errorMessage}`\n\n logError(error)\n\n yield {\n type: 'result',\n data: errorResult,\n resultForAssistant: errorResult,\n }\n }\n },\n} satisfies Tool<typeof inputSchema, any>\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["encoding"]
|
|
7
7
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { NotebookEditTool } from "../NotebookEditTool/NotebookEditTool.js";
|
|
2
|
-
|
|
2
|
+
import { FileReadTool } from "../FileReadTool/FileReadTool.js";
|
|
3
|
+
import { FileEditTool } from "../FileEditTool/FileEditTool.js";
|
|
4
|
+
const DESCRIPTION = `This is a tool for making multiple edits to a single file in one operation. It is built on top of the ${FileEditTool.name} tool and allows you to perform multiple find-and-replace operations efficiently. Prefer this tool over the ${FileEditTool.name} tool when you need to make multiple edits to the same file.
|
|
3
5
|
|
|
4
6
|
Before using this tool:
|
|
5
7
|
|
|
6
|
-
1. Use the
|
|
8
|
+
1. Use the ${FileReadTool.name} tool to understand the file's contents and context
|
|
7
9
|
2. Verify the directory path is correct
|
|
8
10
|
|
|
9
11
|
To make multiple file edits, provide the following:
|
|
@@ -21,7 +23,7 @@ IMPORTANT:
|
|
|
21
23
|
- For Jupyter notebooks (.ipynb files), use the ${NotebookEditTool.name} instead
|
|
22
24
|
|
|
23
25
|
CRITICAL REQUIREMENTS:
|
|
24
|
-
1. All edits follow the same requirements as the single
|
|
26
|
+
1. All edits follow the same requirements as the single ${FileEditTool.name} tool
|
|
25
27
|
2. The edits are atomic - either all succeed or none are applied
|
|
26
28
|
3. Plan your edits carefully to avoid conflicts between sequential operations
|
|
27
29
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/MultiEditTool/prompt.ts"],
|
|
4
|
-
"sourcesContent": ["import { NotebookEditTool } from '@tools/NotebookEditTool/NotebookEditTool'\n\nexport const DESCRIPTION = `This is a tool for making multiple edits to a single file in one operation. It is built on top of the
|
|
5
|
-
"mappings": "AAAA,SAAS,wBAAwB;
|
|
4
|
+
"sourcesContent": ["import { NotebookEditTool } from '@tools/NotebookEditTool/NotebookEditTool'\nimport { FileReadTool } from '@tools/FileReadTool/FileReadTool'\nimport { FileEditTool } from '@tools/FileEditTool/FileEditTool'\n\nexport const DESCRIPTION = `This is a tool for making multiple edits to a single file in one operation. It is built on top of the ${FileEditTool.name} tool and allows you to perform multiple find-and-replace operations efficiently. Prefer this tool over the ${FileEditTool.name} tool when you need to make multiple edits to the same file.\n\nBefore using this tool:\n\n1. Use the ${FileReadTool.name} tool to understand the file's contents and context\n2. Verify the directory path is correct\n\nTo make multiple file edits, provide the following:\n1. file_path: The absolute path to the file to modify (must be absolute, not relative)\n2. edits: An array of edit operations to perform, where each edit contains:\n - old_string: The text to replace (must match the file contents exactly, including all whitespace and indentation)\n - new_string: The edited text to replace the old_string\n - replace_all: Replace all occurences of old_string. This parameter is optional and defaults to false.\n\nIMPORTANT:\n- All edits are applied in sequence, in the order they are provided\n- Each edit operates on the result of the previous edit\n- All edits must be valid for the operation to succeed - if any edit fails, none will be applied\n- This tool is ideal when you need to make several changes to different parts of the same file\n- For Jupyter notebooks (.ipynb files), use the ${NotebookEditTool.name} instead\n\nCRITICAL REQUIREMENTS:\n1. All edits follow the same requirements as the single ${FileEditTool.name} tool\n2. The edits are atomic - either all succeed or none are applied\n3. Plan your edits carefully to avoid conflicts between sequential operations\n\nWARNING:\n- The tool will fail if edits.old_string doesn't match the file contents exactly (including whitespace)\n- The tool will fail if edits.old_string and edits.new_string are the same\n- Since edits are applied in sequence, ensure that earlier edits don't affect the text that later edits are trying to find\n\nWhen making edits:\n- Ensure all edits result in idiomatic, correct code\n- Do not leave the code in a broken state\n- Always use absolute file paths (starting with /)\n- Use replace_all for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance.\n\nIf you want to create a new file, use:\n- A new file path, including dir name if needed\n- First edit: empty old_string and the new file's contents as new_string\n- Subsequent edits: normal edit operations on the created content`\n\nexport const PROMPT = DESCRIPTION\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,wBAAwB;AACjC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAEtB,MAAM,cAAc,yGAAyG,aAAa,IAAI,+GAA+G,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA,aAIxQ,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kDAeoB,iBAAiB,IAAI;AAAA;AAAA;AAAA,0DAGb,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBpE,MAAM,SAAS;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -16,6 +16,7 @@ import { DESCRIPTION, PROMPT } from "./prompt.js";
|
|
|
16
16
|
import { hasWritePermission } from "../../utils/permissions/filesystem.js";
|
|
17
17
|
import { emitReminderEvent } from "../../services/systemReminder.js";
|
|
18
18
|
import { recordFileEdit } from "../../services/fileFreshness.js";
|
|
19
|
+
import { FileEditTool } from "../FileEditTool/FileEditTool.js";
|
|
19
20
|
const inputSchema = z.strictObject({
|
|
20
21
|
notebook_path: z.string().describe(
|
|
21
22
|
"The absolute path to the Jupyter notebook file to edit (must be absolute, not relative)"
|
|
@@ -72,7 +73,11 @@ const NotebookEditTool = {
|
|
|
72
73
|
renderToolUseRejectedMessage() {
|
|
73
74
|
return /* @__PURE__ */ React.createElement(FallbackToolUseRejectedMessage, null);
|
|
74
75
|
},
|
|
75
|
-
renderToolResultMessage(
|
|
76
|
+
renderToolResultMessage(output) {
|
|
77
|
+
if (!output) {
|
|
78
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, "Notebook cell updated"));
|
|
79
|
+
}
|
|
80
|
+
const { cell_number, new_source, language, error } = output;
|
|
76
81
|
if (error) {
|
|
77
82
|
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: "red" }, error));
|
|
78
83
|
}
|
|
@@ -94,7 +99,7 @@ const NotebookEditTool = {
|
|
|
94
99
|
if (extname(fullPath) !== ".ipynb") {
|
|
95
100
|
return {
|
|
96
101
|
result: false,
|
|
97
|
-
message:
|
|
102
|
+
message: `File must be a Jupyter notebook (.ipynb file). For editing other file types, use the ${FileEditTool.name} tool.`
|
|
98
103
|
};
|
|
99
104
|
}
|
|
100
105
|
if (cell_number < 0) {
|