@google/gemini-cli 0.3.0-nightly.20250822.15c62bad → 0.3.0-preview.1
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/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/package.json +7 -7
- package/dist/src/commands/extensions/disable.d.ts +14 -0
- package/dist/src/commands/extensions/disable.js +42 -0
- package/dist/src/commands/extensions/disable.js.map +1 -0
- package/dist/src/commands/extensions/enable.d.ts +14 -0
- package/dist/src/commands/extensions/enable.js +48 -0
- package/dist/src/commands/extensions/enable.js.map +1 -0
- package/dist/src/commands/extensions/install.d.ts +13 -0
- package/dist/src/commands/extensions/install.js +48 -0
- package/dist/src/commands/extensions/install.js.map +1 -0
- package/dist/src/commands/extensions/install.test.d.ts +6 -0
- package/dist/src/commands/extensions/install.test.js +19 -0
- package/dist/src/commands/extensions/install.test.js.map +1 -0
- package/dist/src/commands/extensions/list.d.ts +8 -0
- package/dist/src/commands/extensions/list.js +32 -0
- package/dist/src/commands/extensions/list.js.map +1 -0
- package/dist/src/commands/extensions/uninstall.d.ts +12 -0
- package/dist/src/commands/extensions/uninstall.js +38 -0
- package/dist/src/commands/extensions/uninstall.js.map +1 -0
- package/dist/src/commands/extensions/uninstall.test.d.ts +6 -0
- package/dist/src/commands/extensions/uninstall.test.js +15 -0
- package/dist/src/commands/extensions/uninstall.test.js.map +1 -0
- package/dist/src/commands/extensions/update.d.ts +12 -0
- package/dist/src/commands/extensions/update.js +38 -0
- package/dist/src/commands/extensions/update.js.map +1 -0
- package/dist/src/commands/extensions.d.ts +7 -0
- package/dist/src/commands/extensions.js +29 -0
- package/dist/src/commands/extensions.js.map +1 -0
- package/dist/src/commands/mcp/list.js +1 -1
- package/dist/src/commands/mcp/list.js.map +1 -1
- package/dist/src/config/config.d.ts +6 -6
- package/dist/src/config/config.js +65 -58
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/extension.d.ts +40 -2
- package/dist/src/config/extension.js +267 -14
- package/dist/src/config/extension.js.map +1 -1
- package/dist/src/config/extensions/variableSchema.d.ts +28 -0
- package/dist/src/config/extensions/variableSchema.js +18 -0
- package/dist/src/config/extensions/variableSchema.js.map +1 -0
- package/dist/src/config/extensions/variables.d.ts +17 -0
- package/dist/src/config/extensions/variables.js +40 -0
- package/dist/src/config/extensions/variables.js.map +1 -0
- package/dist/src/config/extensions/variables.test.d.ts +6 -0
- package/dist/src/config/extensions/variables.test.js +17 -0
- package/dist/src/config/extensions/variables.test.js.map +1 -0
- package/dist/src/config/keyBindings.test.js +1 -1
- package/dist/src/config/keyBindings.test.js.map +1 -1
- package/dist/src/config/sandboxConfig.d.ts +2 -2
- package/dist/src/config/sandboxConfig.js +5 -7
- package/dist/src/config/sandboxConfig.js.map +1 -1
- package/dist/src/config/settings.d.ts +9 -4
- package/dist/src/config/settings.js +342 -80
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +633 -416
- package/dist/src/config/settingsSchema.js +628 -411
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/config/settingsSchema.test.js +87 -89
- package/dist/src/config/settingsSchema.test.js.map +1 -1
- package/dist/src/config/trustedFolders.d.ts +1 -1
- package/dist/src/config/trustedFolders.js +5 -5
- package/dist/src/config/trustedFolders.js.map +1 -1
- package/dist/src/config/trustedFolders.test.js +9 -5
- package/dist/src/config/trustedFolders.test.js.map +1 -1
- package/dist/src/gemini.d.ts +3 -1
- package/dist/src/gemini.js +51 -44
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +78 -24
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/nonInteractiveCli.d.ts +1 -1
- package/dist/src/nonInteractiveCli.js +5 -17
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.d.ts +3 -3
- package/dist/src/services/CommandService.d.ts +2 -2
- package/dist/src/services/CommandService.test.js +1 -0
- package/dist/src/services/CommandService.test.js.map +1 -1
- package/dist/src/services/FileCommandLoader.d.ts +3 -3
- package/dist/src/services/FileCommandLoader.js +22 -13
- package/dist/src/services/FileCommandLoader.js.map +1 -1
- package/dist/src/services/McpPromptLoader.d.ts +14 -4
- package/dist/src/services/McpPromptLoader.js +44 -18
- package/dist/src/services/McpPromptLoader.js.map +1 -1
- package/dist/src/services/McpPromptLoader.test.d.ts +6 -0
- package/dist/src/services/McpPromptLoader.test.js +114 -0
- package/dist/src/services/McpPromptLoader.test.js.map +1 -0
- package/dist/src/services/prompt-processors/argumentProcessor.d.ts +3 -3
- package/dist/src/services/prompt-processors/argumentProcessor.js +3 -2
- package/dist/src/services/prompt-processors/argumentProcessor.js.map +1 -1
- package/dist/src/services/prompt-processors/atFileProcessor.d.ts +12 -0
- package/dist/src/services/prompt-processors/atFileProcessor.js +62 -0
- package/dist/src/services/prompt-processors/atFileProcessor.js.map +1 -0
- package/dist/src/services/prompt-processors/atFileProcessor.test.d.ts +6 -0
- package/dist/src/services/prompt-processors/atFileProcessor.test.js +174 -0
- package/dist/src/services/prompt-processors/atFileProcessor.test.js.map +1 -0
- package/dist/src/services/prompt-processors/injectionParser.d.ts +29 -0
- package/dist/src/services/prompt-processors/injectionParser.js +60 -0
- package/dist/src/services/prompt-processors/injectionParser.js.map +1 -0
- package/dist/src/services/prompt-processors/injectionParser.test.d.ts +6 -0
- package/dist/src/services/prompt-processors/injectionParser.test.js +189 -0
- package/dist/src/services/prompt-processors/injectionParser.test.js.map +1 -0
- package/dist/src/services/prompt-processors/shellProcessor.d.ts +4 -12
- package/dist/src/services/prompt-processors/shellProcessor.js +17 -58
- package/dist/src/services/prompt-processors/shellProcessor.js.map +1 -1
- package/dist/src/services/prompt-processors/types.d.ts +13 -8
- package/dist/src/services/prompt-processors/types.js +4 -0
- package/dist/src/services/prompt-processors/types.js.map +1 -1
- package/dist/src/services/types.d.ts +1 -1
- package/dist/src/test-utils/customMatchers.js +0 -6
- package/dist/src/test-utils/customMatchers.js.map +1 -1
- package/dist/src/test-utils/mockCommandContext.d.ts +1 -1
- package/dist/src/test-utils/render.d.ts +1 -1
- package/dist/src/ui/App.d.ts +2 -2
- package/dist/src/ui/App.js +50 -26
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/IdeIntegrationNudge.d.ts +1 -1
- package/dist/src/ui/IdeIntegrationNudge.js +2 -7
- package/dist/src/ui/IdeIntegrationNudge.js.map +1 -1
- package/dist/src/ui/colors.d.ts +1 -1
- package/dist/src/ui/commands/aboutCommand.d.ts +1 -1
- package/dist/src/ui/commands/aboutCommand.js +1 -1
- package/dist/src/ui/commands/aboutCommand.js.map +1 -1
- package/dist/src/ui/commands/authCommand.d.ts +1 -1
- package/dist/src/ui/commands/authCommand.js.map +1 -1
- package/dist/src/ui/commands/chatCommand.d.ts +1 -1
- package/dist/src/ui/commands/chatCommand.js +3 -3
- package/dist/src/ui/commands/chatCommand.js.map +1 -1
- package/dist/src/ui/commands/clearCommand.d.ts +1 -1
- package/dist/src/ui/commands/clearCommand.js.map +1 -1
- package/dist/src/ui/commands/compressCommand.d.ts +1 -1
- package/dist/src/ui/commands/compressCommand.js +2 -0
- package/dist/src/ui/commands/compressCommand.js.map +1 -1
- package/dist/src/ui/commands/copyCommand.d.ts +1 -1
- package/dist/src/ui/commands/copyCommand.js +2 -2
- package/dist/src/ui/commands/copyCommand.js.map +1 -1
- package/dist/src/ui/commands/directoryCommand.d.ts +1 -1
- package/dist/src/ui/commands/directoryCommand.js +5 -4
- package/dist/src/ui/commands/directoryCommand.js.map +1 -1
- package/dist/src/ui/commands/helpCommand.d.ts +1 -1
- package/dist/src/ui/commands/helpCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.d.ts +2 -2
- package/dist/src/ui/commands/ideCommand.js +6 -8
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/initCommand.d.ts +1 -1
- package/dist/src/ui/commands/initCommand.js +3 -3
- package/dist/src/ui/commands/initCommand.js.map +1 -1
- package/dist/src/ui/commands/mcpCommand.d.ts +1 -1
- package/dist/src/ui/commands/mcpCommand.js +1 -1
- package/dist/src/ui/commands/mcpCommand.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.d.ts +1 -1
- package/dist/src/ui/commands/memoryCommand.js +4 -3
- package/dist/src/ui/commands/memoryCommand.js.map +1 -1
- package/dist/src/ui/commands/privacyCommand.d.ts +1 -1
- package/dist/src/ui/commands/privacyCommand.js.map +1 -1
- package/dist/src/ui/commands/restoreCommand.d.ts +1 -1
- package/dist/src/ui/commands/restoreCommand.js +2 -2
- package/dist/src/ui/commands/restoreCommand.js.map +1 -1
- package/dist/src/ui/commands/settingsCommand.d.ts +1 -1
- package/dist/src/ui/commands/settingsCommand.js.map +1 -1
- package/dist/src/ui/commands/setupGithubCommand.d.ts +2 -1
- package/dist/src/ui/commands/setupGithubCommand.js +10 -9
- package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
- package/dist/src/ui/commands/setupGithubCommand.test.js +2 -7
- package/dist/src/ui/commands/setupGithubCommand.test.js.map +1 -1
- package/dist/src/ui/commands/statsCommand.js.map +1 -1
- package/dist/src/ui/commands/terminalSetupCommand.d.ts +1 -1
- package/dist/src/ui/commands/terminalSetupCommand.js.map +1 -1
- package/dist/src/ui/commands/themeCommand.d.ts +1 -1
- package/dist/src/ui/commands/themeCommand.js.map +1 -1
- package/dist/src/ui/commands/toolsCommand.js +1 -1
- package/dist/src/ui/commands/toolsCommand.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +7 -8
- package/dist/src/ui/commands/types.js +1 -0
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/commands/vimCommand.d.ts +1 -1
- package/dist/src/ui/commands/vimCommand.js.map +1 -1
- package/dist/src/ui/components/AboutBox.d.ts +1 -1
- package/dist/src/ui/components/AuthDialog.d.ts +3 -2
- package/dist/src/ui/components/AuthDialog.js +3 -8
- package/dist/src/ui/components/AuthDialog.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.test.js +83 -49
- package/dist/src/ui/components/AuthDialog.test.js.map +1 -1
- package/dist/src/ui/components/AuthInProgress.d.ts +1 -1
- package/dist/src/ui/components/AuthInProgress.js +0 -5
- package/dist/src/ui/components/AuthInProgress.js.map +1 -1
- package/dist/src/ui/components/AutoAcceptIndicator.d.ts +1 -1
- package/dist/src/ui/components/ConsoleSummaryDisplay.d.ts +1 -1
- package/dist/src/ui/components/ContextSummaryDisplay.d.ts +1 -1
- package/dist/src/ui/components/ContextSummaryDisplay.js +1 -0
- package/dist/src/ui/components/ContextSummaryDisplay.js.map +1 -1
- package/dist/src/ui/components/DetailedMessagesDisplay.d.ts +2 -2
- package/dist/src/ui/components/DetailedMessagesDisplay.js +1 -1
- package/dist/src/ui/components/DetailedMessagesDisplay.js.map +1 -1
- package/dist/src/ui/components/EditorSettingsDialog.d.ts +4 -3
- package/dist/src/ui/components/EditorSettingsDialog.js +8 -11
- package/dist/src/ui/components/EditorSettingsDialog.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.d.ts +1 -1
- package/dist/src/ui/components/FolderTrustDialog.js +2 -2
- package/dist/src/ui/components/FolderTrustDialog.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.test.js +1 -1
- package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -1
- package/dist/src/ui/components/Footer.d.ts +1 -1
- package/dist/src/ui/components/GeminiRespondingSpinner.d.ts +1 -1
- package/dist/src/ui/components/Header.d.ts +1 -1
- package/dist/src/ui/components/Help.d.ts +2 -2
- package/dist/src/ui/components/HistoryItemDisplay.d.ts +4 -4
- package/dist/src/ui/components/HistoryItemDisplay.test.js +2 -0
- package/dist/src/ui/components/HistoryItemDisplay.test.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.d.ts +5 -5
- package/dist/src/ui/components/InputPrompt.js +1 -7
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/LoadingIndicator.d.ts +2 -2
- package/dist/src/ui/components/MemoryUsageDisplay.d.ts +1 -1
- package/dist/src/ui/components/MemoryUsageDisplay.js +0 -5
- package/dist/src/ui/components/MemoryUsageDisplay.js.map +1 -1
- package/dist/src/ui/components/ModelStatsDisplay.d.ts +1 -1
- package/dist/src/ui/components/ModelStatsDisplay.js.map +1 -1
- package/dist/src/ui/components/PrepareLabel.d.ts +1 -1
- package/dist/src/ui/components/SessionSummaryDisplay.d.ts +1 -1
- package/dist/src/ui/components/SettingsDialog.d.ts +2 -1
- package/dist/src/ui/components/SettingsDialog.js +2 -2
- package/dist/src/ui/components/SettingsDialog.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.test.js +32 -14
- package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.d.ts +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.js +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.js.map +1 -1
- package/dist/src/ui/components/ShellModeIndicator.d.ts +1 -1
- package/dist/src/ui/components/StatsDisplay.d.ts +1 -1
- package/dist/src/ui/components/StatsDisplay.js.map +1 -1
- package/dist/src/ui/components/SuggestionsDisplay.js +12 -4
- package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
- package/dist/src/ui/components/ThemeDialog.d.ts +3 -2
- package/dist/src/ui/components/ThemeDialog.js +5 -10
- package/dist/src/ui/components/ThemeDialog.js.map +1 -1
- package/dist/src/ui/components/Tips.d.ts +1 -1
- package/dist/src/ui/components/Tips.js +1 -0
- package/dist/src/ui/components/Tips.js.map +1 -1
- package/dist/src/ui/components/ToolStatsDisplay.d.ts +1 -1
- package/dist/src/ui/components/WorkspaceMigrationDialog.d.ts +11 -0
- package/dist/src/ui/components/WorkspaceMigrationDialog.js +42 -0
- package/dist/src/ui/components/WorkspaceMigrationDialog.js.map +1 -0
- package/dist/src/ui/components/messages/CompressionMessage.d.ts +2 -2
- package/dist/src/ui/components/messages/DiffRenderer.d.ts +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.js +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.js.map +1 -1
- package/dist/src/ui/components/messages/ErrorMessage.d.ts +1 -1
- package/dist/src/ui/components/messages/GeminiMessage.d.ts +1 -1
- package/dist/src/ui/components/messages/GeminiMessageContent.d.ts +1 -1
- package/dist/src/ui/components/messages/InfoMessage.d.ts +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.d.ts +3 -3
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +41 -24
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js +87 -2
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.d.ts +4 -4
- package/dist/src/ui/components/messages/ToolGroupMessage.js +1 -6
- package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.test.d.ts +6 -0
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js +259 -0
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -0
- package/dist/src/ui/components/messages/ToolMessage.d.ts +1 -1
- package/dist/src/ui/components/messages/ToolMessage.js +2 -1
- package/dist/src/ui/components/messages/ToolMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolMessage.test.js +6 -6
- package/dist/src/ui/components/messages/ToolMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/UserMessage.d.ts +1 -1
- package/dist/src/ui/components/messages/UserMessage.js +2 -1
- package/dist/src/ui/components/messages/UserMessage.js.map +1 -1
- package/dist/src/ui/components/messages/UserShellMessage.d.ts +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.d.ts +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.js +0 -5
- package/dist/src/ui/components/shared/RadioButtonSelect.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.js +4 -4
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/components/shared/vim-buffer-actions.d.ts +1 -1
- package/dist/src/ui/components/shared/vim-buffer-actions.js.map +1 -1
- package/dist/src/ui/constants.d.ts +8 -0
- package/dist/src/ui/constants.js +9 -0
- package/dist/src/ui/constants.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.d.ts +4 -3
- package/dist/src/ui/contexts/KeypressContext.js +34 -25
- package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.test.js +176 -10
- package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
- package/dist/src/ui/contexts/OverflowContext.d.ts +1 -1
- package/dist/src/ui/contexts/OverflowContext.js +0 -5
- package/dist/src/ui/contexts/OverflowContext.js.map +1 -1
- package/dist/src/ui/contexts/SessionContext.d.ts +2 -2
- package/dist/src/ui/contexts/SessionContext.js +1 -6
- package/dist/src/ui/contexts/SessionContext.js.map +1 -1
- package/dist/src/ui/contexts/SettingsContext.d.ts +1 -1
- package/dist/src/ui/contexts/StreamingContext.d.ts +1 -1
- package/dist/src/ui/contexts/VimModeContext.d.ts +1 -1
- package/dist/src/ui/contexts/VimModeContext.js +4 -4
- package/dist/src/ui/contexts/VimModeContext.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.d.ts +3 -3
- package/dist/src/ui/hooks/atCommandProcessor.js +3 -4
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.js +12 -4
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.d.ts +3 -3
- package/dist/src/ui/hooks/shellCommandProcessor.js +7 -6
- package/dist/src/ui/hooks/shellCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.test.js +5 -4
- package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +5 -4
- package/dist/src/ui/hooks/slashCommandProcessor.js +3 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAtCompletion.d.ts +2 -2
- package/dist/src/ui/hooks/useAtCompletion.js +3 -2
- package/dist/src/ui/hooks/useAtCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useAuthCommand.d.ts +2 -2
- package/dist/src/ui/hooks/useAuthCommand.js +5 -4
- package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
- package/dist/src/ui/hooks/useAutoAcceptIndicator.d.ts +3 -1
- package/dist/src/ui/hooks/useAutoAcceptIndicator.js +13 -4
- package/dist/src/ui/hooks/useAutoAcceptIndicator.js.map +1 -1
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js +122 -2
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js.map +1 -1
- package/dist/src/ui/hooks/useCommandCompletion.d.ts +5 -5
- package/dist/src/ui/hooks/useCommandCompletion.js +2 -2
- package/dist/src/ui/hooks/useCommandCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useCompletion.d.ts +1 -1
- package/dist/src/ui/hooks/useCompletion.js +1 -1
- package/dist/src/ui/hooks/useCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useConsoleMessages.d.ts +1 -1
- package/dist/src/ui/hooks/useEditorSettings.d.ts +2 -2
- package/dist/src/ui/hooks/useEditorSettings.js.map +1 -1
- package/dist/src/ui/hooks/useEditorSettings.test.js.map +1 -1
- package/dist/src/ui/hooks/useFolderTrust.d.ts +1 -1
- package/dist/src/ui/hooks/useFolderTrust.js +3 -2
- package/dist/src/ui/hooks/useFolderTrust.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.d.ts +4 -4
- package/dist/src/ui/hooks/useGeminiStream.js +35 -37
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useGitBranchName.js +1 -1
- package/dist/src/ui/hooks/useGitBranchName.js.map +1 -1
- package/dist/src/ui/hooks/useGitBranchName.test.js +1 -1
- package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -1
- package/dist/src/ui/hooks/useHistoryManager.d.ts +1 -1
- package/dist/src/ui/hooks/useKeypress.d.ts +2 -2
- package/dist/src/ui/hooks/useKeypress.js +1 -1
- package/dist/src/ui/hooks/useKeypress.js.map +1 -1
- package/dist/src/ui/hooks/useLogger.d.ts +2 -1
- package/dist/src/ui/hooks/useLogger.js.map +1 -1
- package/dist/src/ui/hooks/usePrivacySettings.d.ts +1 -1
- package/dist/src/ui/hooks/usePrivacySettings.js.map +1 -1
- package/dist/src/ui/hooks/usePrivacySettings.test.js.map +1 -1
- package/dist/src/ui/hooks/usePromptCompletion.d.ts +2 -2
- package/dist/src/ui/hooks/usePromptCompletion.js +3 -2
- package/dist/src/ui/hooks/usePromptCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.d.ts +2 -2
- package/dist/src/ui/hooks/useReactToolScheduler.js +2 -2
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- package/dist/src/ui/hooks/useReverseSearchCompletion.d.ts +2 -2
- package/dist/src/ui/hooks/useShellHistory.js +2 -2
- package/dist/src/ui/hooks/useShellHistory.js.map +1 -1
- package/dist/src/ui/hooks/useShellHistory.test.js +4 -4
- package/dist/src/ui/hooks/useShellHistory.test.js.map +1 -1
- package/dist/src/ui/hooks/useShowMemoryCommand.d.ts +3 -3
- package/dist/src/ui/hooks/useShowMemoryCommand.js +1 -1
- package/dist/src/ui/hooks/useShowMemoryCommand.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.d.ts +2 -2
- package/dist/src/ui/hooks/useThemeCommand.d.ts +1 -1
- package/dist/src/ui/hooks/useThemeCommand.js +8 -8
- package/dist/src/ui/hooks/useThemeCommand.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +41 -30
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/hooks/useWorkspaceMigration.d.ts +13 -0
- package/dist/src/ui/hooks/useWorkspaceMigration.js +53 -0
- package/dist/src/ui/hooks/useWorkspaceMigration.js.map +1 -0
- package/dist/src/ui/keyMatchers.d.ts +2 -1
- package/dist/src/ui/keyMatchers.js +1 -1
- package/dist/src/ui/keyMatchers.js.map +1 -1
- package/dist/src/ui/keyMatchers.test.js.map +1 -1
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.d.ts +1 -1
- package/dist/src/ui/semantic-colors.d.ts +1 -1
- package/dist/src/ui/themes/atom-one-dark.js +1 -2
- package/dist/src/ui/themes/atom-one-dark.js.map +1 -1
- package/dist/src/ui/themes/ayu-light.js +1 -2
- package/dist/src/ui/themes/ayu-light.js.map +1 -1
- package/dist/src/ui/themes/ayu.js +1 -2
- package/dist/src/ui/themes/ayu.js.map +1 -1
- package/dist/src/ui/themes/default-light.js +1 -2
- package/dist/src/ui/themes/default-light.js.map +1 -1
- package/dist/src/ui/themes/default.js +1 -2
- package/dist/src/ui/themes/default.js.map +1 -1
- package/dist/src/ui/themes/dracula.js +1 -2
- package/dist/src/ui/themes/dracula.js.map +1 -1
- package/dist/src/ui/themes/github-dark.js +1 -2
- package/dist/src/ui/themes/github-dark.js.map +1 -1
- package/dist/src/ui/themes/github-light.js +1 -2
- package/dist/src/ui/themes/github-light.js.map +1 -1
- package/dist/src/ui/themes/googlecode.js +2 -3
- package/dist/src/ui/themes/googlecode.js.map +1 -1
- package/dist/src/ui/themes/no-color.js.map +1 -1
- package/dist/src/ui/themes/shades-of-purple.js +1 -2
- package/dist/src/ui/themes/shades-of-purple.js.map +1 -1
- package/dist/src/ui/themes/theme-manager.d.ts +4 -2
- package/dist/src/ui/themes/theme-manager.js +73 -6
- package/dist/src/ui/themes/theme-manager.js.map +1 -1
- package/dist/src/ui/themes/theme-manager.test.js +60 -1
- package/dist/src/ui/themes/theme-manager.test.js.map +1 -1
- package/dist/src/ui/themes/theme.d.ts +3 -3
- package/dist/src/ui/themes/theme.js +30 -2
- package/dist/src/ui/themes/theme.js.map +1 -1
- package/dist/src/ui/themes/xcode.js +1 -2
- package/dist/src/ui/themes/xcode.js.map +1 -1
- package/dist/src/ui/types.d.ts +4 -2
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/ui/utils/CodeColorizer.d.ts +2 -2
- package/dist/src/ui/utils/CodeColorizer.js +1 -1
- package/dist/src/ui/utils/CodeColorizer.js.map +1 -1
- package/dist/src/ui/utils/ConsolePatcher.d.ts +1 -1
- package/dist/src/ui/utils/ConsolePatcher.js +1 -1
- package/dist/src/ui/utils/ConsolePatcher.js.map +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.js +2 -1
- package/dist/src/ui/utils/MarkdownDisplay.js.map +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.test.js +17 -16
- package/dist/src/ui/utils/MarkdownDisplay.test.js.map +1 -1
- package/dist/src/ui/utils/clipboardUtils.js +4 -4
- package/dist/src/ui/utils/clipboardUtils.js.map +1 -1
- package/dist/src/ui/utils/commandUtils.d.ts +1 -1
- package/dist/src/ui/utils/commandUtils.js +32 -6
- package/dist/src/ui/utils/commandUtils.js.map +1 -1
- package/dist/src/ui/utils/commandUtils.test.js +67 -9
- package/dist/src/ui/utils/commandUtils.test.js.map +1 -1
- package/dist/src/ui/utils/computeStats.d.ts +1 -1
- package/dist/src/ui/utils/platformConstants.d.ts +9 -0
- package/dist/src/ui/utils/platformConstants.js +9 -0
- package/dist/src/ui/utils/platformConstants.js.map +1 -1
- package/dist/src/ui/utils/terminalSetup.js +5 -5
- package/dist/src/ui/utils/terminalSetup.js.map +1 -1
- package/dist/src/ui/utils/textUtils.js +1 -1
- package/dist/src/ui/utils/textUtils.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.d.ts +1 -1
- package/dist/src/ui/utils/updateCheck.js.map +1 -1
- package/dist/src/utils/cleanup.js +2 -2
- package/dist/src/utils/cleanup.js.map +1 -1
- package/dist/src/utils/dialogScopeUtils.d.ts +2 -1
- package/dist/src/utils/dialogScopeUtils.js.map +1 -1
- package/dist/src/utils/errors.d.ts +6 -0
- package/dist/src/utils/errors.js +12 -0
- package/dist/src/utils/errors.js.map +1 -0
- package/dist/src/utils/events.d.ts +1 -1
- package/dist/src/utils/events.js +1 -1
- package/dist/src/utils/events.js.map +1 -1
- package/dist/src/utils/gitUtils.js +1 -1
- package/dist/src/utils/gitUtils.js.map +1 -1
- package/dist/src/utils/gitUtils.test.js +4 -4
- package/dist/src/utils/gitUtils.test.js.map +1 -1
- package/dist/src/utils/handleAutoUpdate.d.ts +4 -4
- package/dist/src/utils/handleAutoUpdate.js +4 -3
- package/dist/src/utils/handleAutoUpdate.js.map +1 -1
- package/dist/src/utils/installationInfo.js +3 -3
- package/dist/src/utils/installationInfo.js.map +1 -1
- package/dist/src/utils/installationInfo.test.js +3 -3
- package/dist/src/utils/installationInfo.test.js.map +1 -1
- package/dist/src/utils/package.js +2 -2
- package/dist/src/utils/package.js.map +1 -1
- package/dist/src/utils/readStdin.js +15 -0
- package/dist/src/utils/readStdin.js.map +1 -1
- package/dist/src/utils/readStdin.test.d.ts +6 -0
- package/dist/src/utils/readStdin.test.js +88 -0
- package/dist/src/utils/readStdin.test.js.map +1 -0
- package/dist/src/utils/resolvePath.js +2 -2
- package/dist/src/utils/resolvePath.js.map +1 -1
- package/dist/src/utils/sandbox.d.ts +1 -1
- package/dist/src/utils/sandbox.js +13 -21
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/utils/settingsUtils.d.ts +2 -2
- package/dist/src/utils/settingsUtils.js +2 -8
- package/dist/src/utils/settingsUtils.js.map +1 -1
- package/dist/src/utils/settingsUtils.test.js +145 -148
- package/dist/src/utils/settingsUtils.test.js.map +1 -1
- package/dist/src/utils/spawnWrapper.d.ts +1 -1
- package/dist/src/utils/spawnWrapper.js +1 -1
- package/dist/src/utils/spawnWrapper.js.map +1 -1
- package/dist/src/utils/startupWarnings.js +2 -2
- package/dist/src/utils/startupWarnings.js.map +1 -1
- package/dist/src/utils/updateEventEmitter.d.ts +1 -1
- package/dist/src/utils/updateEventEmitter.js +1 -1
- package/dist/src/utils/updateEventEmitter.js.map +1 -1
- package/dist/src/utils/userStartupWarnings.js +3 -3
- package/dist/src/utils/userStartupWarnings.js.map +1 -1
- package/dist/src/utils/userStartupWarnings.test.js +3 -3
- package/dist/src/utils/userStartupWarnings.test.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.d.ts +2 -1
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/src/zed-integration/acp.d.ts +1 -1
- package/dist/src/zed-integration/acp.js +2 -1
- package/dist/src/zed-integration/acp.js.map +1 -1
- package/dist/src/zed-integration/fileSystemService.d.ts +2 -2
- package/dist/src/zed-integration/schema.d.ts +422 -319
- package/dist/src/zed-integration/schema.js +7 -1
- package/dist/src/zed-integration/schema.js.map +1 -1
- package/dist/src/zed-integration/zedIntegration.d.ts +4 -4
- package/dist/src/zed-integration/zedIntegration.js +188 -152
- package/dist/src/zed-integration/zedIntegration.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
7
|
+
import { createMockCommandContext } from '../../test-utils/mockCommandContext.js';
|
|
8
|
+
import {} from '../../ui/commands/types.js';
|
|
9
|
+
import { AtFileProcessor } from './atFileProcessor.js';
|
|
10
|
+
import { MessageType } from '../../ui/types.js';
|
|
11
|
+
// Mock the core dependency
|
|
12
|
+
const mockReadPathFromWorkspace = vi.hoisted(() => vi.fn());
|
|
13
|
+
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
|
14
|
+
const original = await importOriginal();
|
|
15
|
+
return {
|
|
16
|
+
...original,
|
|
17
|
+
readPathFromWorkspace: mockReadPathFromWorkspace,
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
describe('AtFileProcessor', () => {
|
|
21
|
+
let context;
|
|
22
|
+
let mockConfig;
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
vi.clearAllMocks();
|
|
25
|
+
mockConfig = {
|
|
26
|
+
// The processor only passes the config through, so we don't need a full mock.
|
|
27
|
+
};
|
|
28
|
+
context = createMockCommandContext({
|
|
29
|
+
services: {
|
|
30
|
+
config: mockConfig,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
// Default mock success behavior: return content wrapped in a text part.
|
|
34
|
+
mockReadPathFromWorkspace.mockImplementation(async (path) => [
|
|
35
|
+
{ text: `content of ${path}` },
|
|
36
|
+
]);
|
|
37
|
+
});
|
|
38
|
+
it('should not change the prompt if no @{ trigger is present', async () => {
|
|
39
|
+
const processor = new AtFileProcessor();
|
|
40
|
+
const prompt = [{ text: 'This is a simple prompt.' }];
|
|
41
|
+
const result = await processor.process(prompt, context);
|
|
42
|
+
expect(result).toEqual(prompt);
|
|
43
|
+
expect(mockReadPathFromWorkspace).not.toHaveBeenCalled();
|
|
44
|
+
});
|
|
45
|
+
it('should not change the prompt if config service is missing', async () => {
|
|
46
|
+
const processor = new AtFileProcessor();
|
|
47
|
+
const prompt = [{ text: 'Analyze @{file.txt}' }];
|
|
48
|
+
const contextWithoutConfig = createMockCommandContext({
|
|
49
|
+
services: {
|
|
50
|
+
config: null,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
const result = await processor.process(prompt, contextWithoutConfig);
|
|
54
|
+
expect(result).toEqual(prompt);
|
|
55
|
+
expect(mockReadPathFromWorkspace).not.toHaveBeenCalled();
|
|
56
|
+
});
|
|
57
|
+
describe('Parsing Logic', () => {
|
|
58
|
+
it('should replace a single valid @{path/to/file.txt} placeholder', async () => {
|
|
59
|
+
const processor = new AtFileProcessor();
|
|
60
|
+
const prompt = [
|
|
61
|
+
{ text: 'Analyze this file: @{path/to/file.txt}' },
|
|
62
|
+
];
|
|
63
|
+
const result = await processor.process(prompt, context);
|
|
64
|
+
expect(mockReadPathFromWorkspace).toHaveBeenCalledWith('path/to/file.txt', mockConfig);
|
|
65
|
+
expect(result).toEqual([
|
|
66
|
+
{ text: 'Analyze this file: ' },
|
|
67
|
+
{ text: 'content of path/to/file.txt' },
|
|
68
|
+
]);
|
|
69
|
+
});
|
|
70
|
+
it('should replace multiple different @{...} placeholders', async () => {
|
|
71
|
+
const processor = new AtFileProcessor();
|
|
72
|
+
const prompt = [
|
|
73
|
+
{ text: 'Compare @{file1.js} with @{file2.js}' },
|
|
74
|
+
];
|
|
75
|
+
const result = await processor.process(prompt, context);
|
|
76
|
+
expect(mockReadPathFromWorkspace).toHaveBeenCalledTimes(2);
|
|
77
|
+
expect(mockReadPathFromWorkspace).toHaveBeenCalledWith('file1.js', mockConfig);
|
|
78
|
+
expect(mockReadPathFromWorkspace).toHaveBeenCalledWith('file2.js', mockConfig);
|
|
79
|
+
expect(result).toEqual([
|
|
80
|
+
{ text: 'Compare ' },
|
|
81
|
+
{ text: 'content of file1.js' },
|
|
82
|
+
{ text: ' with ' },
|
|
83
|
+
{ text: 'content of file2.js' },
|
|
84
|
+
]);
|
|
85
|
+
});
|
|
86
|
+
it('should handle placeholders at the beginning, middle, and end', async () => {
|
|
87
|
+
const processor = new AtFileProcessor();
|
|
88
|
+
const prompt = [
|
|
89
|
+
{ text: '@{start.txt} in the @{middle.txt} and @{end.txt}' },
|
|
90
|
+
];
|
|
91
|
+
const result = await processor.process(prompt, context);
|
|
92
|
+
expect(result).toEqual([
|
|
93
|
+
{ text: 'content of start.txt' },
|
|
94
|
+
{ text: ' in the ' },
|
|
95
|
+
{ text: 'content of middle.txt' },
|
|
96
|
+
{ text: ' and ' },
|
|
97
|
+
{ text: 'content of end.txt' },
|
|
98
|
+
]);
|
|
99
|
+
});
|
|
100
|
+
it('should correctly parse paths that contain balanced braces', async () => {
|
|
101
|
+
const processor = new AtFileProcessor();
|
|
102
|
+
const prompt = [
|
|
103
|
+
{ text: 'Analyze @{path/with/{braces}/file.txt}' },
|
|
104
|
+
];
|
|
105
|
+
const result = await processor.process(prompt, context);
|
|
106
|
+
expect(mockReadPathFromWorkspace).toHaveBeenCalledWith('path/with/{braces}/file.txt', mockConfig);
|
|
107
|
+
expect(result).toEqual([
|
|
108
|
+
{ text: 'Analyze ' },
|
|
109
|
+
{ text: 'content of path/with/{braces}/file.txt' },
|
|
110
|
+
]);
|
|
111
|
+
});
|
|
112
|
+
it('should throw an error if the prompt contains an unclosed trigger', async () => {
|
|
113
|
+
const processor = new AtFileProcessor();
|
|
114
|
+
const prompt = [{ text: 'Hello @{world' }];
|
|
115
|
+
// The new parser throws an error for unclosed injections.
|
|
116
|
+
await expect(processor.process(prompt, context)).rejects.toThrow(/Unclosed injection/);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe('Integration and Error Handling', () => {
|
|
120
|
+
it('should leave the placeholder unmodified if readPathFromWorkspace throws', async () => {
|
|
121
|
+
const processor = new AtFileProcessor();
|
|
122
|
+
const prompt = [
|
|
123
|
+
{ text: 'Analyze @{not-found.txt} and @{good-file.txt}' },
|
|
124
|
+
];
|
|
125
|
+
mockReadPathFromWorkspace.mockImplementation(async (path) => {
|
|
126
|
+
if (path === 'not-found.txt') {
|
|
127
|
+
throw new Error('File not found');
|
|
128
|
+
}
|
|
129
|
+
return [{ text: `content of ${path}` }];
|
|
130
|
+
});
|
|
131
|
+
const result = await processor.process(prompt, context);
|
|
132
|
+
expect(result).toEqual([
|
|
133
|
+
{ text: 'Analyze ' },
|
|
134
|
+
{ text: '@{not-found.txt}' }, // Placeholder is preserved as a text part
|
|
135
|
+
{ text: ' and ' },
|
|
136
|
+
{ text: 'content of good-file.txt' },
|
|
137
|
+
]);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
describe('UI Feedback', () => {
|
|
141
|
+
it('should call ui.addItem with an ERROR on failure', async () => {
|
|
142
|
+
const processor = new AtFileProcessor();
|
|
143
|
+
const prompt = [{ text: 'Analyze @{bad-file.txt}' }];
|
|
144
|
+
mockReadPathFromWorkspace.mockRejectedValue(new Error('Access denied'));
|
|
145
|
+
await processor.process(prompt, context);
|
|
146
|
+
expect(context.ui.addItem).toHaveBeenCalledTimes(1);
|
|
147
|
+
expect(context.ui.addItem).toHaveBeenCalledWith({
|
|
148
|
+
type: MessageType.ERROR,
|
|
149
|
+
text: "Failed to inject content for '@{bad-file.txt}': Access denied",
|
|
150
|
+
}, expect.any(Number));
|
|
151
|
+
});
|
|
152
|
+
it('should call ui.addItem with a WARNING if the file was ignored', async () => {
|
|
153
|
+
const processor = new AtFileProcessor();
|
|
154
|
+
const prompt = [{ text: 'Analyze @{ignored.txt}' }];
|
|
155
|
+
// Simulate an ignored file by returning an empty array.
|
|
156
|
+
mockReadPathFromWorkspace.mockResolvedValue([]);
|
|
157
|
+
const result = await processor.process(prompt, context);
|
|
158
|
+
// The placeholder should be removed, resulting in only the prefix.
|
|
159
|
+
expect(result).toEqual([{ text: 'Analyze ' }]);
|
|
160
|
+
expect(context.ui.addItem).toHaveBeenCalledTimes(1);
|
|
161
|
+
expect(context.ui.addItem).toHaveBeenCalledWith({
|
|
162
|
+
type: MessageType.INFO,
|
|
163
|
+
text: "File '@{ignored.txt}' was ignored by .gitignore or .geminiignore and was not included in the prompt.",
|
|
164
|
+
}, expect.any(Number));
|
|
165
|
+
});
|
|
166
|
+
it('should NOT call ui.addItem on success', async () => {
|
|
167
|
+
const processor = new AtFileProcessor();
|
|
168
|
+
const prompt = [{ text: 'Analyze @{good-file.txt}' }];
|
|
169
|
+
await processor.process(prompt, context);
|
|
170
|
+
expect(context.ui.addItem).not.toHaveBeenCalled();
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
//# sourceMappingURL=atFileProcessor.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atFileProcessor.test.js","sourceRoot":"","sources":["../../../../src/services/prompt-processors/atFileProcessor.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Represents a single detected injection site in a prompt string.
|
|
8
|
+
*/
|
|
9
|
+
export interface Injection {
|
|
10
|
+
/** The content extracted from within the braces (e.g., the command or path), trimmed. */
|
|
11
|
+
content: string;
|
|
12
|
+
/** The starting index of the injection (inclusive, points to the start of the trigger). */
|
|
13
|
+
startIndex: number;
|
|
14
|
+
/** The ending index of the injection (exclusive, points after the closing '}'). */
|
|
15
|
+
endIndex: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Iteratively parses a prompt string to extract injections (e.g., !{...} or @{...}),
|
|
19
|
+
* correctly handling nested braces within the content.
|
|
20
|
+
*
|
|
21
|
+
* This parser relies on simple brace counting and does not support escaping.
|
|
22
|
+
*
|
|
23
|
+
* @param prompt The prompt string to parse.
|
|
24
|
+
* @param trigger The opening trigger sequence (e.g., '!{', '@{').
|
|
25
|
+
* @param contextName Optional context name (e.g., command name) for error messages.
|
|
26
|
+
* @returns An array of extracted Injection objects.
|
|
27
|
+
* @throws Error if an unclosed injection is found.
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractInjections(prompt: string, trigger: string, contextName?: string): Injection[];
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Iteratively parses a prompt string to extract injections (e.g., !{...} or @{...}),
|
|
8
|
+
* correctly handling nested braces within the content.
|
|
9
|
+
*
|
|
10
|
+
* This parser relies on simple brace counting and does not support escaping.
|
|
11
|
+
*
|
|
12
|
+
* @param prompt The prompt string to parse.
|
|
13
|
+
* @param trigger The opening trigger sequence (e.g., '!{', '@{').
|
|
14
|
+
* @param contextName Optional context name (e.g., command name) for error messages.
|
|
15
|
+
* @returns An array of extracted Injection objects.
|
|
16
|
+
* @throws Error if an unclosed injection is found.
|
|
17
|
+
*/
|
|
18
|
+
export function extractInjections(prompt, trigger, contextName) {
|
|
19
|
+
const injections = [];
|
|
20
|
+
let index = 0;
|
|
21
|
+
while (index < prompt.length) {
|
|
22
|
+
const startIndex = prompt.indexOf(trigger, index);
|
|
23
|
+
if (startIndex === -1) {
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
let currentIndex = startIndex + trigger.length;
|
|
27
|
+
let braceCount = 1;
|
|
28
|
+
let foundEnd = false;
|
|
29
|
+
while (currentIndex < prompt.length) {
|
|
30
|
+
const char = prompt[currentIndex];
|
|
31
|
+
if (char === '{') {
|
|
32
|
+
braceCount++;
|
|
33
|
+
}
|
|
34
|
+
else if (char === '}') {
|
|
35
|
+
braceCount--;
|
|
36
|
+
if (braceCount === 0) {
|
|
37
|
+
const injectionContent = prompt.substring(startIndex + trigger.length, currentIndex);
|
|
38
|
+
const endIndex = currentIndex + 1;
|
|
39
|
+
injections.push({
|
|
40
|
+
content: injectionContent.trim(),
|
|
41
|
+
startIndex,
|
|
42
|
+
endIndex,
|
|
43
|
+
});
|
|
44
|
+
index = endIndex;
|
|
45
|
+
foundEnd = true;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
currentIndex++;
|
|
50
|
+
}
|
|
51
|
+
// Check if the inner loop finished without finding the closing brace.
|
|
52
|
+
if (!foundEnd) {
|
|
53
|
+
const contextInfo = contextName ? ` in command '${contextName}'` : '';
|
|
54
|
+
// Enforce strict parsing (Comment 1) and clarify limitations (Comment 2).
|
|
55
|
+
throw new Error(`Invalid syntax${contextInfo}: Unclosed injection starting at index ${startIndex} ('${trigger}'). Ensure braces are balanced. Paths or commands with unbalanced braces are not supported directly.`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return injections;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=injectionParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injectionParser.js","sourceRoot":"","sources":["../../../../src/services/prompt-processors/injectionParser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAc,EACd,OAAe,EACf,WAAoB;IAEpB,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,OAAO,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAElD,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YACtB,MAAM;QACR,CAAC;QAED,IAAI,YAAY,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;QAC/C,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,OAAO,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;YAElC,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACjB,UAAU,EAAE,CAAC;YACf,CAAC;iBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACxB,UAAU,EAAE,CAAC;gBACb,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;oBACrB,MAAM,gBAAgB,GAAG,MAAM,CAAC,SAAS,CACvC,UAAU,GAAG,OAAO,CAAC,MAAM,EAC3B,YAAY,CACb,CAAC;oBACF,MAAM,QAAQ,GAAG,YAAY,GAAG,CAAC,CAAC;oBAElC,UAAU,CAAC,IAAI,CAAC;wBACd,OAAO,EAAE,gBAAgB,CAAC,IAAI,EAAE;wBAChC,UAAU;wBACV,QAAQ;qBACT,CAAC,CAAC;oBAEH,KAAK,GAAG,QAAQ,CAAC;oBACjB,QAAQ,GAAG,IAAI,CAAC;oBAChB,MAAM;gBACR,CAAC;YACH,CAAC;YACD,YAAY,EAAE,CAAC;QACjB,CAAC;QAED,sEAAsE;QACtE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,gBAAgB,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,0EAA0E;YAC1E,MAAM,IAAI,KAAK,CACb,iBAAiB,WAAW,0CAA0C,UAAU,MAAM,OAAO,sGAAsG,CACpM,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect } from 'vitest';
|
|
7
|
+
import { extractInjections } from './injectionParser.js';
|
|
8
|
+
describe('extractInjections', () => {
|
|
9
|
+
const SHELL_TRIGGER = '!{';
|
|
10
|
+
const AT_FILE_TRIGGER = '@{';
|
|
11
|
+
describe('Basic Functionality', () => {
|
|
12
|
+
it('should return an empty array if no trigger is present', () => {
|
|
13
|
+
const prompt = 'This is a simple prompt without injections.';
|
|
14
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
15
|
+
expect(result).toEqual([]);
|
|
16
|
+
});
|
|
17
|
+
it('should extract a single, simple injection', () => {
|
|
18
|
+
const prompt = 'Run this command: !{ls -la}';
|
|
19
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
20
|
+
expect(result).toEqual([
|
|
21
|
+
{
|
|
22
|
+
content: 'ls -la',
|
|
23
|
+
startIndex: 18,
|
|
24
|
+
endIndex: 27,
|
|
25
|
+
},
|
|
26
|
+
]);
|
|
27
|
+
});
|
|
28
|
+
it('should extract multiple injections', () => {
|
|
29
|
+
const prompt = 'First: !{cmd1}, Second: !{cmd2}';
|
|
30
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
31
|
+
expect(result).toHaveLength(2);
|
|
32
|
+
expect(result[0]).toEqual({
|
|
33
|
+
content: 'cmd1',
|
|
34
|
+
startIndex: 7,
|
|
35
|
+
endIndex: 14,
|
|
36
|
+
});
|
|
37
|
+
expect(result[1]).toEqual({
|
|
38
|
+
content: 'cmd2',
|
|
39
|
+
startIndex: 24,
|
|
40
|
+
endIndex: 31,
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
it('should handle different triggers (e.g., @{)', () => {
|
|
44
|
+
const prompt = 'Read this file: @{path/to/file.txt}';
|
|
45
|
+
const result = extractInjections(prompt, AT_FILE_TRIGGER);
|
|
46
|
+
expect(result).toEqual([
|
|
47
|
+
{
|
|
48
|
+
content: 'path/to/file.txt',
|
|
49
|
+
startIndex: 16,
|
|
50
|
+
endIndex: 35,
|
|
51
|
+
},
|
|
52
|
+
]);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe('Positioning and Edge Cases', () => {
|
|
56
|
+
it('should handle injections at the start and end of the prompt', () => {
|
|
57
|
+
const prompt = '!{start} middle text !{end}';
|
|
58
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
59
|
+
expect(result).toHaveLength(2);
|
|
60
|
+
expect(result[0]).toEqual({
|
|
61
|
+
content: 'start',
|
|
62
|
+
startIndex: 0,
|
|
63
|
+
endIndex: 8,
|
|
64
|
+
});
|
|
65
|
+
expect(result[1]).toEqual({
|
|
66
|
+
content: 'end',
|
|
67
|
+
startIndex: 21,
|
|
68
|
+
endIndex: 27,
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
it('should handle adjacent injections', () => {
|
|
72
|
+
const prompt = '!{A}!{B}';
|
|
73
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
74
|
+
expect(result).toHaveLength(2);
|
|
75
|
+
expect(result[0]).toEqual({ content: 'A', startIndex: 0, endIndex: 4 });
|
|
76
|
+
expect(result[1]).toEqual({ content: 'B', startIndex: 4, endIndex: 8 });
|
|
77
|
+
});
|
|
78
|
+
it('should handle empty injections', () => {
|
|
79
|
+
const prompt = 'Empty: !{}';
|
|
80
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
81
|
+
expect(result).toEqual([
|
|
82
|
+
{
|
|
83
|
+
content: '',
|
|
84
|
+
startIndex: 7,
|
|
85
|
+
endIndex: 10,
|
|
86
|
+
},
|
|
87
|
+
]);
|
|
88
|
+
});
|
|
89
|
+
it('should trim whitespace within the content', () => {
|
|
90
|
+
const prompt = '!{ \n command with space \t }';
|
|
91
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
92
|
+
expect(result).toEqual([
|
|
93
|
+
{
|
|
94
|
+
content: 'command with space',
|
|
95
|
+
startIndex: 0,
|
|
96
|
+
endIndex: 29,
|
|
97
|
+
},
|
|
98
|
+
]);
|
|
99
|
+
});
|
|
100
|
+
it('should ignore similar patterns that are not the exact trigger', () => {
|
|
101
|
+
const prompt = 'Not a trigger: !(cmd) or {cmd} or ! {cmd}';
|
|
102
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
103
|
+
expect(result).toEqual([]);
|
|
104
|
+
});
|
|
105
|
+
it('should ignore extra closing braces before the trigger', () => {
|
|
106
|
+
const prompt = 'Ignore this } then !{run}';
|
|
107
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
108
|
+
expect(result).toEqual([
|
|
109
|
+
{
|
|
110
|
+
content: 'run',
|
|
111
|
+
startIndex: 19,
|
|
112
|
+
endIndex: 25,
|
|
113
|
+
},
|
|
114
|
+
]);
|
|
115
|
+
});
|
|
116
|
+
it('should stop parsing at the first balanced closing brace (non-greedy)', () => {
|
|
117
|
+
// This tests that the parser doesn't greedily consume extra closing braces
|
|
118
|
+
const prompt = 'Run !{ls -l}} extra braces';
|
|
119
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
120
|
+
expect(result).toEqual([
|
|
121
|
+
{
|
|
122
|
+
content: 'ls -l',
|
|
123
|
+
startIndex: 4,
|
|
124
|
+
endIndex: 12,
|
|
125
|
+
},
|
|
126
|
+
]);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
describe('Nested Braces (Balanced)', () => {
|
|
130
|
+
it('should correctly parse content with simple nested braces (e.g., JSON)', () => {
|
|
131
|
+
const prompt = `Send JSON: !{curl -d '{"key": "value"}'}`;
|
|
132
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
133
|
+
expect(result).toHaveLength(1);
|
|
134
|
+
expect(result[0].content).toBe(`curl -d '{"key": "value"}'`);
|
|
135
|
+
});
|
|
136
|
+
it('should correctly parse content with shell constructs (e.g., awk)', () => {
|
|
137
|
+
const prompt = `Process text: !{awk '{print $1}' file.txt}`;
|
|
138
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
139
|
+
expect(result).toHaveLength(1);
|
|
140
|
+
expect(result[0].content).toBe(`awk '{print $1}' file.txt`);
|
|
141
|
+
});
|
|
142
|
+
it('should correctly parse multiple levels of nesting', () => {
|
|
143
|
+
const prompt = `!{level1 {level2 {level3}} suffix}`;
|
|
144
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
145
|
+
expect(result).toHaveLength(1);
|
|
146
|
+
expect(result[0].content).toBe(`level1 {level2 {level3}} suffix`);
|
|
147
|
+
expect(result[0].endIndex).toBe(prompt.length);
|
|
148
|
+
});
|
|
149
|
+
it('should correctly parse paths containing balanced braces', () => {
|
|
150
|
+
const prompt = 'Analyze @{path/with/{braces}/file.txt}';
|
|
151
|
+
const result = extractInjections(prompt, AT_FILE_TRIGGER);
|
|
152
|
+
expect(result).toHaveLength(1);
|
|
153
|
+
expect(result[0].content).toBe('path/with/{braces}/file.txt');
|
|
154
|
+
});
|
|
155
|
+
it('should correctly handle an injection containing the trigger itself', () => {
|
|
156
|
+
// This works because the parser counts braces, it doesn't look for the trigger again until the current one is closed.
|
|
157
|
+
const prompt = '!{echo "The trigger is !{ confusing }"}';
|
|
158
|
+
const expectedContent = 'echo "The trigger is !{ confusing }"';
|
|
159
|
+
const result = extractInjections(prompt, SHELL_TRIGGER);
|
|
160
|
+
expect(result).toHaveLength(1);
|
|
161
|
+
expect(result[0].content).toBe(expectedContent);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
describe('Error Handling (Unbalanced/Unclosed)', () => {
|
|
165
|
+
it('should throw an error for a simple unclosed injection', () => {
|
|
166
|
+
const prompt = 'This prompt has !{an unclosed trigger';
|
|
167
|
+
expect(() => extractInjections(prompt, SHELL_TRIGGER)).toThrow(/Invalid syntax: Unclosed injection starting at index 16 \('!{'\)/);
|
|
168
|
+
});
|
|
169
|
+
it('should throw an error if the prompt ends inside a nested block', () => {
|
|
170
|
+
const prompt = 'This fails: !{outer {inner';
|
|
171
|
+
expect(() => extractInjections(prompt, SHELL_TRIGGER)).toThrow(/Invalid syntax: Unclosed injection starting at index 12 \('!{'\)/);
|
|
172
|
+
});
|
|
173
|
+
it('should include the context name in the error message if provided', () => {
|
|
174
|
+
const prompt = 'Failing !{command';
|
|
175
|
+
const contextName = 'test-command';
|
|
176
|
+
expect(() => extractInjections(prompt, SHELL_TRIGGER, contextName)).toThrow(/Invalid syntax in command 'test-command': Unclosed injection starting at index 8/);
|
|
177
|
+
});
|
|
178
|
+
it('should throw if content contains unbalanced braces (e.g., missing closing)', () => {
|
|
179
|
+
// This is functionally the same as an unclosed injection from the parser's perspective.
|
|
180
|
+
const prompt = 'Analyze @{path/with/braces{example.txt}';
|
|
181
|
+
expect(() => extractInjections(prompt, AT_FILE_TRIGGER)).toThrow(/Invalid syntax: Unclosed injection starting at index 8 \('@{'\)/);
|
|
182
|
+
});
|
|
183
|
+
it('should clearly state that unbalanced braces in content are not supported in the error', () => {
|
|
184
|
+
const prompt = 'Analyze @{path/with/braces{example.txt}';
|
|
185
|
+
expect(() => extractInjections(prompt, AT_FILE_TRIGGER)).toThrow(/Paths or commands with unbalanced braces are not supported directly/);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
//# sourceMappingURL=injectionParser.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injectionParser.test.js","sourceRoot":"","sources":["../../../../src/services/prompt-processors/injectionParser.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { CommandContext } from '../../ui/commands/types.js';
|
|
7
|
-
import { IPromptProcessor } from './types.js';
|
|
6
|
+
import type { CommandContext } from '../../ui/commands/types.js';
|
|
7
|
+
import type { IPromptProcessor, PromptPipelineContent } from './types.js';
|
|
8
8
|
export declare class ConfirmationRequiredError extends Error {
|
|
9
9
|
commandsToConfirm: string[];
|
|
10
10
|
constructor(message: string, commandsToConfirm: string[]);
|
|
@@ -22,14 +22,6 @@ export declare class ConfirmationRequiredError extends Error {
|
|
|
22
22
|
export declare class ShellProcessor implements IPromptProcessor {
|
|
23
23
|
private readonly commandName;
|
|
24
24
|
constructor(commandName: string);
|
|
25
|
-
process(prompt:
|
|
26
|
-
|
|
27
|
-
* Iteratively parses the prompt string to extract shell injections (!{...}),
|
|
28
|
-
* correctly handling nested braces within the command.
|
|
29
|
-
*
|
|
30
|
-
* @param prompt The prompt string to parse.
|
|
31
|
-
* @returns An array of extracted ShellInjection objects.
|
|
32
|
-
* @throws Error if an unclosed injection (`!{`) is found.
|
|
33
|
-
*/
|
|
34
|
-
private extractInjections;
|
|
25
|
+
process(prompt: PromptPipelineContent, context: CommandContext): Promise<PromptPipelineContent>;
|
|
26
|
+
private processString;
|
|
35
27
|
}
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { ApprovalMode, checkCommandPermissions, escapeShellArg, getShellConfiguration, ShellExecutionService, } from '@google/gemini-cli-core';
|
|
6
|
+
import { ApprovalMode, checkCommandPermissions, escapeShellArg, getShellConfiguration, ShellExecutionService, flatMapTextParts, } from '@google/gemini-cli-core';
|
|
7
7
|
import { SHELL_INJECTION_TRIGGER, SHORTHAND_ARGS_PLACEHOLDER, } from './types.js';
|
|
8
|
+
import { extractInjections } from './injectionParser.js';
|
|
8
9
|
export class ConfirmationRequiredError extends Error {
|
|
9
10
|
commandsToConfirm;
|
|
10
11
|
constructor(message, commandsToConfirm) {
|
|
@@ -29,28 +30,35 @@ export class ShellProcessor {
|
|
|
29
30
|
this.commandName = commandName;
|
|
30
31
|
}
|
|
31
32
|
async process(prompt, context) {
|
|
33
|
+
return flatMapTextParts(prompt, (text) => this.processString(text, context));
|
|
34
|
+
}
|
|
35
|
+
async processString(prompt, context) {
|
|
32
36
|
const userArgsRaw = context.invocation?.args || '';
|
|
33
37
|
if (!prompt.includes(SHELL_INJECTION_TRIGGER)) {
|
|
34
|
-
return
|
|
38
|
+
return [
|
|
39
|
+
{ text: prompt.replaceAll(SHORTHAND_ARGS_PLACEHOLDER, userArgsRaw) },
|
|
40
|
+
];
|
|
35
41
|
}
|
|
36
42
|
const config = context.services.config;
|
|
37
43
|
if (!config) {
|
|
38
44
|
throw new Error(`Security configuration not loaded. Cannot verify shell command permissions for '${this.commandName}'. Aborting.`);
|
|
39
45
|
}
|
|
40
46
|
const { sessionShellAllowlist } = context.session;
|
|
41
|
-
const injections =
|
|
47
|
+
const injections = extractInjections(prompt, SHELL_INJECTION_TRIGGER, this.commandName);
|
|
42
48
|
// If extractInjections found no closed blocks (and didn't throw), treat as raw.
|
|
43
49
|
if (injections.length === 0) {
|
|
44
|
-
return
|
|
50
|
+
return [
|
|
51
|
+
{ text: prompt.replaceAll(SHORTHAND_ARGS_PLACEHOLDER, userArgsRaw) },
|
|
52
|
+
];
|
|
45
53
|
}
|
|
46
54
|
const { shell } = getShellConfiguration();
|
|
47
55
|
const userArgsEscaped = escapeShellArg(userArgsRaw, shell);
|
|
48
56
|
const resolvedInjections = injections.map((injection) => {
|
|
49
|
-
|
|
50
|
-
|
|
57
|
+
const command = injection.content;
|
|
58
|
+
if (command === '') {
|
|
59
|
+
return { ...injection, resolvedCommand: undefined };
|
|
51
60
|
}
|
|
52
|
-
|
|
53
|
-
const resolvedCommand = injection.command.replaceAll(SHORTHAND_ARGS_PLACEHOLDER, userArgsEscaped);
|
|
61
|
+
const resolvedCommand = command.replaceAll(SHORTHAND_ARGS_PLACEHOLDER, userArgsEscaped);
|
|
54
62
|
return { ...injection, resolvedCommand };
|
|
55
63
|
});
|
|
56
64
|
const commandsToConfirm = new Set();
|
|
@@ -107,56 +115,7 @@ export class ShellProcessor {
|
|
|
107
115
|
// Append the remaining text AFTER the last injection, substituting {{args}} with RAW input.
|
|
108
116
|
const finalSegment = prompt.substring(lastIndex);
|
|
109
117
|
processedPrompt += finalSegment.replaceAll(SHORTHAND_ARGS_PLACEHOLDER, userArgsRaw);
|
|
110
|
-
return processedPrompt;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Iteratively parses the prompt string to extract shell injections (!{...}),
|
|
114
|
-
* correctly handling nested braces within the command.
|
|
115
|
-
*
|
|
116
|
-
* @param prompt The prompt string to parse.
|
|
117
|
-
* @returns An array of extracted ShellInjection objects.
|
|
118
|
-
* @throws Error if an unclosed injection (`!{`) is found.
|
|
119
|
-
*/
|
|
120
|
-
extractInjections(prompt) {
|
|
121
|
-
const injections = [];
|
|
122
|
-
let index = 0;
|
|
123
|
-
while (index < prompt.length) {
|
|
124
|
-
const startIndex = prompt.indexOf(SHELL_INJECTION_TRIGGER, index);
|
|
125
|
-
if (startIndex === -1) {
|
|
126
|
-
break;
|
|
127
|
-
}
|
|
128
|
-
let currentIndex = startIndex + SHELL_INJECTION_TRIGGER.length;
|
|
129
|
-
let braceCount = 1;
|
|
130
|
-
let foundEnd = false;
|
|
131
|
-
while (currentIndex < prompt.length) {
|
|
132
|
-
const char = prompt[currentIndex];
|
|
133
|
-
// We count literal braces. This parser does not interpret shell quoting/escaping.
|
|
134
|
-
if (char === '{') {
|
|
135
|
-
braceCount++;
|
|
136
|
-
}
|
|
137
|
-
else if (char === '}') {
|
|
138
|
-
braceCount--;
|
|
139
|
-
if (braceCount === 0) {
|
|
140
|
-
const commandContent = prompt.substring(startIndex + SHELL_INJECTION_TRIGGER.length, currentIndex);
|
|
141
|
-
const endIndex = currentIndex + 1;
|
|
142
|
-
injections.push({
|
|
143
|
-
command: commandContent.trim(),
|
|
144
|
-
startIndex,
|
|
145
|
-
endIndex,
|
|
146
|
-
});
|
|
147
|
-
index = endIndex;
|
|
148
|
-
foundEnd = true;
|
|
149
|
-
break;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
currentIndex++;
|
|
153
|
-
}
|
|
154
|
-
// Check if the inner loop finished without finding the closing brace.
|
|
155
|
-
if (!foundEnd) {
|
|
156
|
-
throw new Error(`Invalid syntax in command '${this.commandName}': Unclosed shell injection starting at index ${startIndex} ('!{'). Ensure braces are balanced.`);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return injections;
|
|
118
|
+
return [{ text: processedPrompt }];
|
|
160
119
|
}
|
|
161
120
|
}
|
|
162
121
|
//# sourceMappingURL=shellProcessor.js.map
|