@quantum-ai/gemini-cli 0.45.4 → 0.45.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +394 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/package.json +12 -11
- package/dist/src/config/settingsSchema.d.ts +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/ui/App.d.ts +1 -1
- package/dist/src/ui/AppContainer.d.ts +1 -1
- package/dist/src/ui/IdeIntegrationNudge.d.ts +1 -1
- package/dist/src/ui/auth/LoginRestartDialog.d.ts +1 -1
- package/dist/src/ui/components/AdminSettingsChangedDialog.d.ts +1 -1
- package/dist/src/ui/components/AlternateBufferQuittingDisplay.d.ts +1 -1
- package/dist/src/ui/components/AppHeader.d.ts +1 -1
- package/dist/src/ui/components/BackgroundTaskDisplay.d.ts +1 -1
- package/dist/src/ui/components/Banner.d.ts +1 -1
- package/dist/src/ui/components/CliSpinner.d.ts +1 -1
- package/dist/src/ui/components/Composer.d.ts +1 -1
- package/dist/src/ui/components/ConfigInitDisplay.d.ts +1 -1
- package/dist/src/ui/components/ConsentPrompt.d.ts +1 -1
- package/dist/src/ui/components/ContextUsageDisplay.d.ts +1 -1
- package/dist/src/ui/components/DebugProfiler.d.ts +1 -1
- package/dist/src/ui/components/DialogManager.d.ts +1 -1
- package/dist/src/ui/components/IdeTrustChangeDialog.d.ts +1 -1
- package/dist/src/ui/components/LoopDetectionConfirmation.d.ts +1 -1
- package/dist/src/ui/components/MainContent.d.ts +1 -1
- package/dist/src/ui/components/ModelQuotaDisplay.d.ts +1 -1
- package/dist/src/ui/components/NewAgentsNotification.d.ts +1 -1
- package/dist/src/ui/components/Notifications.d.ts +1 -1
- package/dist/src/ui/components/QueuedMessageDisplay.d.ts +1 -1
- package/dist/src/ui/components/QuittingDisplay.d.ts +1 -1
- package/dist/src/ui/components/ShowMoreLines.d.ts +1 -1
- package/dist/src/ui/components/SuggestionsDisplay.d.ts +1 -1
- package/dist/src/ui/components/Table.d.ts +1 -1
- package/dist/src/ui/components/UpdateNotification.d.ts +1 -1
- package/dist/src/ui/components/shared/SlicingMaxSizedBox.d.ts +1 -1
- package/dist/src/ui/components/triage/TriageDuplicates.d.ts +1 -1
- package/dist/src/ui/components/triage/TriageIssues.d.ts +1 -1
- package/dist/src/ui/contexts/KeypressContext.d.ts +1 -1
- package/dist/src/ui/contexts/MouseContext.d.ts +1 -1
- package/dist/src/ui/contexts/TerminalContext.d.ts +1 -1
- package/dist/src/ui/contexts/VimModeContext.d.ts +1 -1
- package/dist/src/ui/hooks/useExtensionUpdates.d.ts +2 -2
- package/dist/src/ui/hooks/useInlineEditBuffer.d.ts +1 -1
- package/dist/src/ui/hooks/useStateAndRef.d.ts +1 -1
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.d.ts +1 -1
- package/dist/src/ui/privacy/CloudPaidPrivacyNotice.d.ts +1 -1
- package/dist/src/ui/privacy/GeminiPrivacyNotice.d.ts +1 -1
- package/dist/src/ui/privacy/PrivacyNotice.d.ts +1 -1
- package/dist/src/utils/devtoolsService.js +1 -1
- package/dist/src/utils/devtoolsService.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -11
- package/dist/src/acp/acpCommandHandler.test.d.ts +0 -6
- package/dist/src/acp/acpCommandHandler.test.js +0 -28
- package/dist/src/acp/acpCommandHandler.test.js.map +0 -1
- package/dist/src/acp/acpErrors.test.d.ts +0 -6
- package/dist/src/acp/acpErrors.test.js +0 -38
- package/dist/src/acp/acpErrors.test.js.map +0 -1
- package/dist/src/acp/acpFileSystemService.test.d.ts +0 -6
- package/dist/src/acp/acpFileSystemService.test.js +0 -162
- package/dist/src/acp/acpFileSystemService.test.js.map +0 -1
- package/dist/src/acp/acpResume.test.d.ts +0 -6
- package/dist/src/acp/acpResume.test.js +0 -260
- package/dist/src/acp/acpResume.test.js.map +0 -1
- package/dist/src/acp/acpRpcDispatcher.test.d.ts +0 -6
- package/dist/src/acp/acpRpcDispatcher.test.js +0 -238
- package/dist/src/acp/acpRpcDispatcher.test.js.map +0 -1
- package/dist/src/acp/acpSession.test.d.ts +0 -6
- package/dist/src/acp/acpSession.test.js +0 -742
- package/dist/src/acp/acpSession.test.js.map +0 -1
- package/dist/src/acp/acpSessionManager.test.d.ts +0 -6
- package/dist/src/acp/acpSessionManager.test.js +0 -283
- package/dist/src/acp/acpSessionManager.test.js.map +0 -1
- package/dist/src/acp/commands/extensions.test.d.ts +0 -6
- package/dist/src/acp/commands/extensions.test.js +0 -70
- package/dist/src/acp/commands/extensions.test.js.map +0 -1
- package/dist/src/acp/commands/help.test.d.ts +0 -6
- package/dist/src/acp/commands/help.test.js +0 -40
- package/dist/src/acp/commands/help.test.js.map +0 -1
- package/dist/src/acp/commands/restore.test.d.ts +0 -6
- package/dist/src/acp/commands/restore.test.js +0 -173
- package/dist/src/acp/commands/restore.test.js.map +0 -1
- package/dist/src/commands/extensions/configure.test.d.ts +0 -1
- package/dist/src/commands/extensions/configure.test.js +0 -195
- package/dist/src/commands/extensions/configure.test.js.map +0 -1
- package/dist/src/commands/extensions/disable.test.d.ts +0 -6
- package/dist/src/commands/extensions/disable.test.js +0 -169
- package/dist/src/commands/extensions/disable.test.js.map +0 -1
- package/dist/src/commands/extensions/enable.test.d.ts +0 -6
- package/dist/src/commands/extensions/enable.test.js +0 -199
- package/dist/src/commands/extensions/enable.test.js.map +0 -1
- package/dist/src/commands/extensions/install.test.d.ts +0 -6
- package/dist/src/commands/extensions/install.test.js +0 -311
- package/dist/src/commands/extensions/install.test.js.map +0 -1
- package/dist/src/commands/extensions/link.test.d.ts +0 -6
- package/dist/src/commands/extensions/link.test.js +0 -121
- package/dist/src/commands/extensions/link.test.js.map +0 -1
- package/dist/src/commands/extensions/list.test.d.ts +0 -6
- package/dist/src/commands/extensions/list.test.js +0 -132
- package/dist/src/commands/extensions/list.test.js.map +0 -1
- package/dist/src/commands/extensions/new.test.d.ts +0 -6
- package/dist/src/commands/extensions/new.test.js +0 -62
- package/dist/src/commands/extensions/new.test.js.map +0 -1
- package/dist/src/commands/extensions/uninstall.test.d.ts +0 -6
- package/dist/src/commands/extensions/uninstall.test.js +0 -240
- package/dist/src/commands/extensions/uninstall.test.js.map +0 -1
- package/dist/src/commands/extensions/update.test.d.ts +0 -6
- package/dist/src/commands/extensions/update.test.js +0 -196
- package/dist/src/commands/extensions/update.test.js.map +0 -1
- package/dist/src/commands/extensions/validate.test.d.ts +0 -6
- package/dist/src/commands/extensions/validate.test.js +0 -96
- package/dist/src/commands/extensions/validate.test.js.map +0 -1
- package/dist/src/commands/extensions.test.d.ts +0 -6
- package/dist/src/commands/extensions.test.js +0 -67
- package/dist/src/commands/extensions.test.js.map +0 -1
- package/dist/src/commands/gemma/logs.test.d.ts +0 -6
- package/dist/src/commands/gemma/logs.test.js +0 -122
- package/dist/src/commands/gemma/logs.test.js.map +0 -1
- package/dist/src/commands/gemma/platform.test.d.ts +0 -6
- package/dist/src/commands/gemma/platform.test.js +0 -108
- package/dist/src/commands/gemma/platform.test.js.map +0 -1
- package/dist/src/commands/gemma/setup.test.d.ts +0 -6
- package/dist/src/commands/gemma/setup.test.js +0 -36
- package/dist/src/commands/gemma/setup.test.js.map +0 -1
- package/dist/src/commands/gemma/stop.test.d.ts +0 -6
- package/dist/src/commands/gemma/stop.test.js +0 -89
- package/dist/src/commands/gemma/stop.test.js.map +0 -1
- package/dist/src/commands/hooks/migrate.test.d.ts +0 -6
- package/dist/src/commands/hooks/migrate.test.js +0 -388
- package/dist/src/commands/hooks/migrate.test.js.map +0 -1
- package/dist/src/commands/mcp/add.test.d.ts +0 -6
- package/dist/src/commands/mcp/add.test.js +0 -274
- package/dist/src/commands/mcp/add.test.js.map +0 -1
- package/dist/src/commands/mcp/list.test.d.ts +0 -6
- package/dist/src/commands/mcp/list.test.js +0 -477
- package/dist/src/commands/mcp/list.test.js.map +0 -1
- package/dist/src/commands/mcp/remove.test.d.ts +0 -6
- package/dist/src/commands/mcp/remove.test.js +0 -206
- package/dist/src/commands/mcp/remove.test.js.map +0 -1
- package/dist/src/commands/mcp.test.d.ts +0 -6
- package/dist/src/commands/mcp.test.js +0 -64
- package/dist/src/commands/mcp.test.js.map +0 -1
- package/dist/src/commands/skills/disable.test.d.ts +0 -6
- package/dist/src/commands/skills/disable.test.js +0 -93
- package/dist/src/commands/skills/disable.test.js.map +0 -1
- package/dist/src/commands/skills/enable.test.d.ts +0 -6
- package/dist/src/commands/skills/enable.test.js +0 -104
- package/dist/src/commands/skills/enable.test.js.map +0 -1
- package/dist/src/commands/skills/install.test.d.ts +0 -6
- package/dist/src/commands/skills/install.test.js +0 -99
- package/dist/src/commands/skills/install.test.js.map +0 -1
- package/dist/src/commands/skills/link.test.d.ts +0 -6
- package/dist/src/commands/skills/link.test.js +0 -53
- package/dist/src/commands/skills/link.test.js.map +0 -1
- package/dist/src/commands/skills/list.test.d.ts +0 -6
- package/dist/src/commands/skills/list.test.js +0 -127
- package/dist/src/commands/skills/list.test.js.map +0 -1
- package/dist/src/commands/skills/uninstall.test.d.ts +0 -6
- package/dist/src/commands/skills/uninstall.test.js +0 -65
- package/dist/src/commands/skills/uninstall.test.js.map +0 -1
- package/dist/src/commands/skills.test.d.ts +0 -6
- package/dist/src/commands/skills.test.js +0 -49
- package/dist/src/commands/skills.test.js.map +0 -1
- package/dist/src/commands/utils.test.d.ts +0 -6
- package/dist/src/commands/utils.test.js +0 -35
- package/dist/src/commands/utils.test.js.map +0 -1
- package/dist/src/config/auth.test.d.ts +0 -6
- package/dist/src/config/auth.test.js +0 -96
- package/dist/src/config/auth.test.js.map +0 -1
- package/dist/src/config/config.integration.test.d.ts +0 -6
- package/dist/src/config/config.integration.test.js +0 -205
- package/dist/src/config/config.integration.test.js.map +0 -1
- package/dist/src/config/config.test.d.ts +0 -6
- package/dist/src/config/config.test.js +0 -3124
- package/dist/src/config/config.test.js.map +0 -1
- package/dist/src/config/extension-manager-agents.test.d.ts +0 -6
- package/dist/src/config/extension-manager-agents.test.js +0 -116
- package/dist/src/config/extension-manager-agents.test.js.map +0 -1
- package/dist/src/config/extension-manager-hydration.test.d.ts +0 -6
- package/dist/src/config/extension-manager-hydration.test.js +0 -262
- package/dist/src/config/extension-manager-hydration.test.js.map +0 -1
- package/dist/src/config/extension-manager-permissions.test.d.ts +0 -6
- package/dist/src/config/extension-manager-permissions.test.js +0 -107
- package/dist/src/config/extension-manager-permissions.test.js.map +0 -1
- package/dist/src/config/extension-manager-scope.test.d.ts +0 -6
- package/dist/src/config/extension-manager-scope.test.js +0 -158
- package/dist/src/config/extension-manager-scope.test.js.map +0 -1
- package/dist/src/config/extension-manager-skills.test.d.ts +0 -6
- package/dist/src/config/extension-manager-skills.test.js +0 -157
- package/dist/src/config/extension-manager-skills.test.js.map +0 -1
- package/dist/src/config/extension-manager.test.d.ts +0 -6
- package/dist/src/config/extension-manager.test.js +0 -430
- package/dist/src/config/extension-manager.test.js.map +0 -1
- package/dist/src/config/extension.test.d.ts +0 -6
- package/dist/src/config/extension.test.js +0 -1800
- package/dist/src/config/extension.test.js.map +0 -1
- package/dist/src/config/extensionRegistryClient.test.d.ts +0 -6
- package/dist/src/config/extensionRegistryClient.test.js +0 -261
- package/dist/src/config/extensionRegistryClient.test.js.map +0 -1
- package/dist/src/config/extensions/consent.test.d.ts +0 -6
- package/dist/src/config/extensions/consent.test.js +0 -302
- package/dist/src/config/extensions/consent.test.js.map +0 -1
- package/dist/src/config/extensions/extensionEnablement.test.d.ts +0 -6
- package/dist/src/config/extensions/extensionEnablement.test.js +0 -404
- package/dist/src/config/extensions/extensionEnablement.test.js.map +0 -1
- package/dist/src/config/extensions/extensionSettings.test.d.ts +0 -6
- package/dist/src/config/extensions/extensionSettings.test.js +0 -575
- package/dist/src/config/extensions/extensionSettings.test.js.map +0 -1
- package/dist/src/config/extensions/extensionUpdates.test.d.ts +0 -6
- package/dist/src/config/extensions/extensionUpdates.test.js +0 -265
- package/dist/src/config/extensions/extensionUpdates.test.js.map +0 -1
- package/dist/src/config/extensions/github.test.d.ts +0 -6
- package/dist/src/config/extensions/github.test.js +0 -454
- package/dist/src/config/extensions/github.test.js.map +0 -1
- package/dist/src/config/extensions/github_fetch.test.d.ts +0 -6
- package/dist/src/config/extensions/github_fetch.test.js +0 -171
- package/dist/src/config/extensions/github_fetch.test.js.map +0 -1
- package/dist/src/config/extensions/storage.test.d.ts +0 -6
- package/dist/src/config/extensions/storage.test.js +0 -64
- package/dist/src/config/extensions/storage.test.js.map +0 -1
- package/dist/src/config/extensions/update.test.d.ts +0 -6
- package/dist/src/config/extensions/update.test.js +0 -296
- package/dist/src/config/extensions/update.test.js.map +0 -1
- package/dist/src/config/extensions/variables.test.d.ts +0 -6
- package/dist/src/config/extensions/variables.test.js +0 -119
- package/dist/src/config/extensions/variables.test.js.map +0 -1
- package/dist/src/config/footerItems.test.d.ts +0 -6
- package/dist/src/config/footerItems.test.js +0 -180
- package/dist/src/config/footerItems.test.js.map +0 -1
- package/dist/src/config/mcp/mcpServerEnablement.test.d.ts +0 -6
- package/dist/src/config/mcp/mcpServerEnablement.test.js +0 -148
- package/dist/src/config/mcp/mcpServerEnablement.test.js.map +0 -1
- package/dist/src/config/mutual-exclusivity.test.d.ts +0 -6
- package/dist/src/config/mutual-exclusivity.test.js +0 -33
- package/dist/src/config/mutual-exclusivity.test.js.map +0 -1
- package/dist/src/config/policy-engine.integration.test.d.ts +0 -6
- package/dist/src/config/policy-engine.integration.test.js +0 -394
- package/dist/src/config/policy-engine.integration.test.js.map +0 -1
- package/dist/src/config/policy.test.d.ts +0 -6
- package/dist/src/config/policy.test.js +0 -199
- package/dist/src/config/policy.test.js.map +0 -1
- package/dist/src/config/sandboxConfig.test.d.ts +0 -6
- package/dist/src/config/sandboxConfig.test.js +0 -401
- package/dist/src/config/sandboxConfig.test.js.map +0 -1
- package/dist/src/config/settingPaths.test.d.ts +0 -6
- package/dist/src/config/settingPaths.test.js +0 -22
- package/dist/src/config/settingPaths.test.js.map +0 -1
- package/dist/src/config/settings-env-isolation.test.d.ts +0 -6
- package/dist/src/config/settings-env-isolation.test.js +0 -188
- package/dist/src/config/settings-env-isolation.test.js.map +0 -1
- package/dist/src/config/settings-validation.test.d.ts +0 -6
- package/dist/src/config/settings-validation.test.js +0 -464
- package/dist/src/config/settings-validation.test.js.map +0 -1
- package/dist/src/config/settings.test.d.ts +0 -6
- package/dist/src/config/settings.test.js +0 -2660
- package/dist/src/config/settings.test.js.map +0 -1
- package/dist/src/config/settingsSchema.test.d.ts +0 -6
- package/dist/src/config/settingsSchema.test.js +0 -450
- package/dist/src/config/settingsSchema.test.js.map +0 -1
- package/dist/src/config/settings_repro.test.d.ts +0 -6
- package/dist/src/config/settings_repro.test.js +0 -163
- package/dist/src/config/settings_repro.test.js.map +0 -1
- package/dist/src/config/settings_validation_warning.test.d.ts +0 -6
- package/dist/src/config/settings_validation_warning.test.js +0 -124
- package/dist/src/config/settings_validation_warning.test.js.map +0 -1
- package/dist/src/config/skipExtensions.test.d.ts +0 -6
- package/dist/src/config/skipExtensions.test.js +0 -49
- package/dist/src/config/skipExtensions.test.js.map +0 -1
- package/dist/src/config/trustedFolders.test.d.ts +0 -6
- package/dist/src/config/trustedFolders.test.js +0 -411
- package/dist/src/config/trustedFolders.test.js.map +0 -1
- package/dist/src/config/workspace-policy-cli.test.d.ts +0 -6
- package/dist/src/config/workspace-policy-cli.test.js +0 -204
- package/dist/src/config/workspace-policy-cli.test.js.map +0 -1
- package/dist/src/core/auth.test.d.ts +0 -6
- package/dist/src/core/auth.test.js +0 -93
- package/dist/src/core/auth.test.js.map +0 -1
- package/dist/src/core/initializer.test.d.ts +0 -6
- package/dist/src/core/initializer.test.js +0 -111
- package/dist/src/core/initializer.test.js.map +0 -1
- package/dist/src/core/theme.test.d.ts +0 -6
- package/dist/src/core/theme.test.js +0 -46
- package/dist/src/core/theme.test.js.map +0 -1
- package/dist/src/deferred.test.d.ts +0 -6
- package/dist/src/deferred.test.js +0 -180
- package/dist/src/deferred.test.js.map +0 -1
- package/dist/src/gemini.test.d.ts +0 -6
- package/dist/src/gemini.test.js +0 -1432
- package/dist/src/gemini.test.js.map +0 -1
- package/dist/src/gemini_cleanup.test.d.ts +0 -6
- package/dist/src/gemini_cleanup.test.js +0 -391
- package/dist/src/gemini_cleanup.test.js.map +0 -1
- package/dist/src/integration-tests/modelSteering.test.d.ts +0 -6
- package/dist/src/integration-tests/modelSteering.test.js +0 -62
- package/dist/src/integration-tests/modelSteering.test.js.map +0 -1
- package/dist/src/nonInteractiveCli.test.d.ts +0 -6
- package/dist/src/nonInteractiveCli.test.js +0 -1921
- package/dist/src/nonInteractiveCli.test.js.map +0 -1
- package/dist/src/nonInteractiveCliAgentSession.test.d.ts +0 -6
- package/dist/src/nonInteractiveCliAgentSession.test.js +0 -2015
- package/dist/src/nonInteractiveCliAgentSession.test.js.map +0 -1
- package/dist/src/output-redirection.test.d.ts +0 -6
- package/dist/src/output-redirection.test.js +0 -77
- package/dist/src/output-redirection.test.js.map +0 -1
- package/dist/src/services/BuiltinCommandLoader.test.d.ts +0 -6
- package/dist/src/services/BuiltinCommandLoader.test.js +0 -369
- package/dist/src/services/BuiltinCommandLoader.test.js.map +0 -1
- package/dist/src/services/CommandService.test.d.ts +0 -6
- package/dist/src/services/CommandService.test.js +0 -74
- package/dist/src/services/CommandService.test.js.map +0 -1
- package/dist/src/services/FileCommandLoader.test.d.ts +0 -6
- package/dist/src/services/FileCommandLoader.test.js +0 -1128
- package/dist/src/services/FileCommandLoader.test.js.map +0 -1
- package/dist/src/services/McpPromptLoader.test.d.ts +0 -6
- package/dist/src/services/McpPromptLoader.test.js +0 -411
- package/dist/src/services/McpPromptLoader.test.js.map +0 -1
- package/dist/src/services/SkillCommandLoader.test.d.ts +0 -6
- package/dist/src/services/SkillCommandLoader.test.js +0 -113
- package/dist/src/services/SkillCommandLoader.test.js.map +0 -1
- package/dist/src/services/SlashCommandConflictHandler.test.d.ts +0 -6
- package/dist/src/services/SlashCommandConflictHandler.test.js +0 -144
- package/dist/src/services/SlashCommandConflictHandler.test.js.map +0 -1
- package/dist/src/services/SlashCommandResolver.test.d.ts +0 -6
- package/dist/src/services/SlashCommandResolver.test.js +0 -186
- package/dist/src/services/SlashCommandResolver.test.js.map +0 -1
- package/dist/src/services/liteRtServerManager.test.d.ts +0 -6
- package/dist/src/services/liteRtServerManager.test.js +0 -54
- package/dist/src/services/liteRtServerManager.test.js.map +0 -1
- package/dist/src/services/prompt-processors/argumentProcessor.test.d.ts +0 -6
- package/dist/src/services/prompt-processors/argumentProcessor.test.js +0 -40
- package/dist/src/services/prompt-processors/argumentProcessor.test.js.map +0 -1
- package/dist/src/services/prompt-processors/atFileProcessor.test.d.ts +0 -6
- package/dist/src/services/prompt-processors/atFileProcessor.test.js +0 -177
- package/dist/src/services/prompt-processors/atFileProcessor.test.js.map +0 -1
- package/dist/src/services/prompt-processors/injectionParser.test.d.ts +0 -6
- package/dist/src/services/prompt-processors/injectionParser.test.js +0 -189
- package/dist/src/services/prompt-processors/injectionParser.test.js.map +0 -1
- package/dist/src/services/prompt-processors/shellProcessor.test.d.ts +0 -6
- package/dist/src/services/prompt-processors/shellProcessor.test.js +0 -525
- package/dist/src/services/prompt-processors/shellProcessor.test.js.map +0 -1
- package/dist/src/test-utils/AppRig.test.d.ts +0 -6
- package/dist/src/test-utils/AppRig.test.js +0 -60
- package/dist/src/test-utils/AppRig.test.js.map +0 -1
- package/dist/src/test-utils/mockCommandContext.test.d.ts +0 -6
- package/dist/src/test-utils/mockCommandContext.test.js +0 -51
- package/dist/src/test-utils/mockCommandContext.test.js.map +0 -1
- package/dist/src/test-utils/render.test.d.ts +0 -6
- package/dist/src/test-utils/render.test.js +0 -84
- package/dist/src/test-utils/render.test.js.map +0 -1
- package/dist/src/ui/App.test.d.ts +0 -6
- package/dist/src/ui/App.test.js +0 -244
- package/dist/src/ui/App.test.js.map +0 -1
- package/dist/src/ui/AppContainer.test.d.ts +0 -6
- package/dist/src/ui/AppContainer.test.js +0 -2824
- package/dist/src/ui/AppContainer.test.js.map +0 -1
- package/dist/src/ui/IdeIntegrationNudge.test.d.ts +0 -6
- package/dist/src/ui/IdeIntegrationNudge.test.js +0 -149
- package/dist/src/ui/IdeIntegrationNudge.test.js.map +0 -1
- package/dist/src/ui/ToolConfirmationFullFrame.test.d.ts +0 -1
- package/dist/src/ui/ToolConfirmationFullFrame.test.js +0 -153
- package/dist/src/ui/ToolConfirmationFullFrame.test.js.map +0 -1
- package/dist/src/ui/auth/ApiAuthDialog.test.d.ts +0 -6
- package/dist/src/ui/auth/ApiAuthDialog.test.js +0 -127
- package/dist/src/ui/auth/ApiAuthDialog.test.js.map +0 -1
- package/dist/src/ui/auth/AuthDialog.test.d.ts +0 -6
- package/dist/src/ui/auth/AuthDialog.test.js +0 -350
- package/dist/src/ui/auth/AuthDialog.test.js.map +0 -1
- package/dist/src/ui/auth/AuthInProgress.test.d.ts +0 -6
- package/dist/src/ui/auth/AuthInProgress.test.js +0 -99
- package/dist/src/ui/auth/AuthInProgress.test.js.map +0 -1
- package/dist/src/ui/auth/BannedAccountDialog.test.d.ts +0 -6
- package/dist/src/ui/auth/BannedAccountDialog.test.js +0 -141
- package/dist/src/ui/auth/BannedAccountDialog.test.js.map +0 -1
- package/dist/src/ui/auth/LoginRestartDialog.test.d.ts +0 -6
- package/dist/src/ui/auth/LoginRestartDialog.test.js +0 -79
- package/dist/src/ui/auth/LoginRestartDialog.test.js.map +0 -1
- package/dist/src/ui/auth/useAuth.test.d.ts +0 -6
- package/dist/src/ui/auth/useAuth.test.js +0 -214
- package/dist/src/ui/auth/useAuth.test.js.map +0 -1
- package/dist/src/ui/commands/aboutCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/aboutCommand.test.js +0 -145
- package/dist/src/ui/commands/aboutCommand.test.js.map +0 -1
- package/dist/src/ui/commands/agentsCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/agentsCommand.test.js +0 -382
- package/dist/src/ui/commands/agentsCommand.test.js.map +0 -1
- package/dist/src/ui/commands/authCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/authCommand.test.js +0 -103
- package/dist/src/ui/commands/authCommand.test.js.map +0 -1
- package/dist/src/ui/commands/bugCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/bugCommand.test.js +0 -305
- package/dist/src/ui/commands/bugCommand.test.js.map +0 -1
- package/dist/src/ui/commands/bugMemoryCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/bugMemoryCommand.test.js +0 -100
- package/dist/src/ui/commands/bugMemoryCommand.test.js.map +0 -1
- package/dist/src/ui/commands/chatCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/chatCommand.test.js +0 -627
- package/dist/src/ui/commands/chatCommand.test.js.map +0 -1
- package/dist/src/ui/commands/clearCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/clearCommand.test.js +0 -98
- package/dist/src/ui/commands/clearCommand.test.js.map +0 -1
- package/dist/src/ui/commands/commandsCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/commandsCommand.test.js +0 -115
- package/dist/src/ui/commands/commandsCommand.test.js.map +0 -1
- package/dist/src/ui/commands/compressCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/compressCommand.test.js +0 -110
- package/dist/src/ui/commands/compressCommand.test.js.map +0 -1
- package/dist/src/ui/commands/copyCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/copyCommand.test.js +0 -244
- package/dist/src/ui/commands/copyCommand.test.js.map +0 -1
- package/dist/src/ui/commands/corgiCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/corgiCommand.test.js +0 -28
- package/dist/src/ui/commands/corgiCommand.test.js.map +0 -1
- package/dist/src/ui/commands/directoryCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/directoryCommand.test.js +0 -365
- package/dist/src/ui/commands/directoryCommand.test.js.map +0 -1
- package/dist/src/ui/commands/docsCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/docsCommand.test.js +0 -72
- package/dist/src/ui/commands/docsCommand.test.js.map +0 -1
- package/dist/src/ui/commands/editorCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/editorCommand.test.js +0 -27
- package/dist/src/ui/commands/editorCommand.test.js.map +0 -1
- package/dist/src/ui/commands/exportSessionCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/exportSessionCommand.test.js +0 -100
- package/dist/src/ui/commands/exportSessionCommand.test.js.map +0 -1
- package/dist/src/ui/commands/extensionsCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/extensionsCommand.test.js +0 -947
- package/dist/src/ui/commands/extensionsCommand.test.js.map +0 -1
- package/dist/src/ui/commands/helpCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/helpCommand.test.js +0 -94
- package/dist/src/ui/commands/helpCommand.test.js.map +0 -1
- package/dist/src/ui/commands/hooksCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/hooksCommand.test.js +0 -562
- package/dist/src/ui/commands/hooksCommand.test.js.map +0 -1
- package/dist/src/ui/commands/ideCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/ideCommand.test.js +0 -205
- package/dist/src/ui/commands/ideCommand.test.js.map +0 -1
- package/dist/src/ui/commands/initCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/initCommand.test.js +0 -86
- package/dist/src/ui/commands/initCommand.test.js.map +0 -1
- package/dist/src/ui/commands/mcpCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/mcpCommand.test.js +0 -231
- package/dist/src/ui/commands/mcpCommand.test.js.map +0 -1
- package/dist/src/ui/commands/memoryCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/memoryCommand.test.js +0 -361
- package/dist/src/ui/commands/memoryCommand.test.js.map +0 -1
- package/dist/src/ui/commands/modelCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/modelCommand.test.js +0 -135
- package/dist/src/ui/commands/modelCommand.test.js.map +0 -1
- package/dist/src/ui/commands/permissionsCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/permissionsCommand.test.js +0 -86
- package/dist/src/ui/commands/permissionsCommand.test.js.map +0 -1
- package/dist/src/ui/commands/planCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/planCommand.test.js +0 -146
- package/dist/src/ui/commands/planCommand.test.js.map +0 -1
- package/dist/src/ui/commands/policiesCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/policiesCommand.test.js +0 -133
- package/dist/src/ui/commands/policiesCommand.test.js.map +0 -1
- package/dist/src/ui/commands/privacyCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/privacyCommand.test.js +0 -32
- package/dist/src/ui/commands/privacyCommand.test.js.map +0 -1
- package/dist/src/ui/commands/quitCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/quitCommand.test.js +0 -95
- package/dist/src/ui/commands/quitCommand.test.js.map +0 -1
- package/dist/src/ui/commands/restoreCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/restoreCommand.test.js +0 -193
- package/dist/src/ui/commands/restoreCommand.test.js.map +0 -1
- package/dist/src/ui/commands/resumeCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/resumeCommand.test.js +0 -28
- package/dist/src/ui/commands/resumeCommand.test.js.map +0 -1
- package/dist/src/ui/commands/rewindCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/rewindCommand.test.js +0 -256
- package/dist/src/ui/commands/rewindCommand.test.js.map +0 -1
- package/dist/src/ui/commands/settingsCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/settingsCommand.test.js +0 -30
- package/dist/src/ui/commands/settingsCommand.test.js.map +0 -1
- package/dist/src/ui/commands/setupGithubCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/setupGithubCommand.test.js +0 -238
- package/dist/src/ui/commands/setupGithubCommand.test.js.map +0 -1
- package/dist/src/ui/commands/skillsCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/skillsCommand.test.js +0 -500
- package/dist/src/ui/commands/skillsCommand.test.js.map +0 -1
- package/dist/src/ui/commands/statsCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/statsCommand.test.js +0 -122
- package/dist/src/ui/commands/statsCommand.test.js.map +0 -1
- package/dist/src/ui/commands/tasksCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/tasksCommand.test.js +0 -30
- package/dist/src/ui/commands/tasksCommand.test.js.map +0 -1
- package/dist/src/ui/commands/terminalSetupCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/terminalSetupCommand.test.js +0 -66
- package/dist/src/ui/commands/terminalSetupCommand.test.js.map +0 -1
- package/dist/src/ui/commands/themeCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/themeCommand.test.js +0 -32
- package/dist/src/ui/commands/themeCommand.test.js.map +0 -1
- package/dist/src/ui/commands/toolsCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/toolsCommand.test.js +0 -187
- package/dist/src/ui/commands/toolsCommand.test.js.map +0 -1
- package/dist/src/ui/commands/upgradeCommand.test.d.ts +0 -6
- package/dist/src/ui/commands/upgradeCommand.test.js +0 -102
- package/dist/src/ui/commands/upgradeCommand.test.js.map +0 -1
- package/dist/src/ui/components/AboutBox.test.d.ts +0 -6
- package/dist/src/ui/components/AboutBox.test.js +0 -63
- package/dist/src/ui/components/AboutBox.test.js.map +0 -1
- package/dist/src/ui/components/AdminSettingsChangedDialog.test.d.ts +0 -6
- package/dist/src/ui/components/AdminSettingsChangedDialog.test.js +0 -43
- package/dist/src/ui/components/AdminSettingsChangedDialog.test.js.map +0 -1
- package/dist/src/ui/components/AgentConfigDialog.test.d.ts +0 -6
- package/dist/src/ui/components/AgentConfigDialog.test.js +0 -267
- package/dist/src/ui/components/AgentConfigDialog.test.js.map +0 -1
- package/dist/src/ui/components/AlternateBufferQuittingDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/AlternateBufferQuittingDisplay.test.js +0 -196
- package/dist/src/ui/components/AlternateBufferQuittingDisplay.test.js.map +0 -1
- package/dist/src/ui/components/AnsiOutput.test.d.ts +0 -6
- package/dist/src/ui/components/AnsiOutput.test.js +0 -142
- package/dist/src/ui/components/AnsiOutput.test.js.map +0 -1
- package/dist/src/ui/components/AppHeader.test.d.ts +0 -6
- package/dist/src/ui/components/AppHeader.test.js +0 -212
- package/dist/src/ui/components/AppHeader.test.js.map +0 -1
- package/dist/src/ui/components/AppHeaderIcon.test.d.ts +0 -6
- package/dist/src/ui/components/AppHeaderIcon.test.js +0 -39
- package/dist/src/ui/components/AppHeaderIcon.test.js.map +0 -1
- package/dist/src/ui/components/ApprovalModeIndicator.test.d.ts +0 -6
- package/dist/src/ui/components/ApprovalModeIndicator.test.js +0 -37
- package/dist/src/ui/components/ApprovalModeIndicator.test.js.map +0 -1
- package/dist/src/ui/components/AskUserDialog.test.d.ts +0 -6
- package/dist/src/ui/components/AskUserDialog.test.js +0 -1121
- package/dist/src/ui/components/AskUserDialog.test.js.map +0 -1
- package/dist/src/ui/components/BackgroundTaskDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/BackgroundTaskDisplay.test.js +0 -209
- package/dist/src/ui/components/BackgroundTaskDisplay.test.js.map +0 -1
- package/dist/src/ui/components/Banner.test.d.ts +0 -6
- package/dist/src/ui/components/Banner.test.js +0 -29
- package/dist/src/ui/components/Banner.test.js.map +0 -1
- package/dist/src/ui/components/BubblingRegression.test.d.ts +0 -6
- package/dist/src/ui/components/BubblingRegression.test.js +0 -60
- package/dist/src/ui/components/BubblingRegression.test.js.map +0 -1
- package/dist/src/ui/components/Checklist.test.d.ts +0 -6
- package/dist/src/ui/components/Checklist.test.js +0 -46
- package/dist/src/ui/components/Checklist.test.js.map +0 -1
- package/dist/src/ui/components/ChecklistItem.test.d.ts +0 -6
- package/dist/src/ui/components/ChecklistItem.test.js +0 -40
- package/dist/src/ui/components/ChecklistItem.test.js.map +0 -1
- package/dist/src/ui/components/CliSpinner.test.d.ts +0 -6
- package/dist/src/ui/components/CliSpinner.test.js +0 -32
- package/dist/src/ui/components/CliSpinner.test.js.map +0 -1
- package/dist/src/ui/components/ColorsDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/ColorsDisplay.test.js +0 -107
- package/dist/src/ui/components/ColorsDisplay.test.js.map +0 -1
- package/dist/src/ui/components/Composer.test.d.ts +0 -6
- package/dist/src/ui/components/Composer.test.js +0 -853
- package/dist/src/ui/components/Composer.test.js.map +0 -1
- package/dist/src/ui/components/ConfigInitDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/ConfigInitDisplay.test.js +0 -118
- package/dist/src/ui/components/ConfigInitDisplay.test.js.map +0 -1
- package/dist/src/ui/components/ConsentPrompt.test.d.ts +0 -6
- package/dist/src/ui/components/ConsentPrompt.test.js +0 -80
- package/dist/src/ui/components/ConsentPrompt.test.js.map +0 -1
- package/dist/src/ui/components/ConsoleSummaryDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/ConsoleSummaryDisplay.test.js +0 -28
- package/dist/src/ui/components/ConsoleSummaryDisplay.test.js.map +0 -1
- package/dist/src/ui/components/ContextSummaryDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/ContextSummaryDisplay.test.js +0 -81
- package/dist/src/ui/components/ContextSummaryDisplay.test.js.map +0 -1
- package/dist/src/ui/components/ContextUsageDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/ContextUsageDisplay.test.js +0 -50
- package/dist/src/ui/components/ContextUsageDisplay.test.js.map +0 -1
- package/dist/src/ui/components/CopyModeWarning.test.d.ts +0 -6
- package/dist/src/ui/components/CopyModeWarning.test.js +0 -35
- package/dist/src/ui/components/CopyModeWarning.test.js.map +0 -1
- package/dist/src/ui/components/DebugProfiler.test.d.ts +0 -6
- package/dist/src/ui/components/DebugProfiler.test.js +0 -228
- package/dist/src/ui/components/DebugProfiler.test.js.map +0 -1
- package/dist/src/ui/components/DetailedMessagesDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/DetailedMessagesDisplay.test.js +0 -81
- package/dist/src/ui/components/DetailedMessagesDisplay.test.js.map +0 -1
- package/dist/src/ui/components/DialogManager.test.d.ts +0 -6
- package/dist/src/ui/components/DialogManager.test.js +0 -187
- package/dist/src/ui/components/DialogManager.test.js.map +0 -1
- package/dist/src/ui/components/EditorSettingsDialog.test.d.ts +0 -6
- package/dist/src/ui/components/EditorSettingsDialog.test.js +0 -145
- package/dist/src/ui/components/EditorSettingsDialog.test.js.map +0 -1
- package/dist/src/ui/components/EmptyWalletDialog.test.d.ts +0 -6
- package/dist/src/ui/components/EmptyWalletDialog.test.js +0 -116
- package/dist/src/ui/components/EmptyWalletDialog.test.js.map +0 -1
- package/dist/src/ui/components/ExitPlanModeDialog.test.d.ts +0 -6
- package/dist/src/ui/components/ExitPlanModeDialog.test.js +0 -443
- package/dist/src/ui/components/ExitPlanModeDialog.test.js.map +0 -1
- package/dist/src/ui/components/ExitWarning.test.d.ts +0 -6
- package/dist/src/ui/components/ExitWarning.test.js +0 -58
- package/dist/src/ui/components/ExitWarning.test.js.map +0 -1
- package/dist/src/ui/components/FolderTrustDialog.test.d.ts +0 -6
- package/dist/src/ui/components/FolderTrustDialog.test.js +0 -342
- package/dist/src/ui/components/FolderTrustDialog.test.js.map +0 -1
- package/dist/src/ui/components/Footer.test.d.ts +0 -6
- package/dist/src/ui/components/Footer.test.js +0 -806
- package/dist/src/ui/components/Footer.test.js.map +0 -1
- package/dist/src/ui/components/FooterConfigDialog.test.d.ts +0 -6
- package/dist/src/ui/components/FooterConfigDialog.test.js +0 -191
- package/dist/src/ui/components/FooterConfigDialog.test.js.map +0 -1
- package/dist/src/ui/components/GeminiRespondingSpinner.test.d.ts +0 -6
- package/dist/src/ui/components/GeminiRespondingSpinner.test.js +0 -63
- package/dist/src/ui/components/GeminiRespondingSpinner.test.js.map +0 -1
- package/dist/src/ui/components/GradientRegression.test.d.ts +0 -6
- package/dist/src/ui/components/GradientRegression.test.js +0 -116
- package/dist/src/ui/components/GradientRegression.test.js.map +0 -1
- package/dist/src/ui/components/Header.test.d.ts +0 -6
- package/dist/src/ui/components/Header.test.js +0 -131
- package/dist/src/ui/components/Header.test.js.map +0 -1
- package/dist/src/ui/components/Help.test.d.ts +0 -6
- package/dist/src/ui/components/Help.test.js +0 -67
- package/dist/src/ui/components/Help.test.js.map +0 -1
- package/dist/src/ui/components/HistoryItemDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/HistoryItemDisplay.test.js +0 -302
- package/dist/src/ui/components/HistoryItemDisplay.test.js.map +0 -1
- package/dist/src/ui/components/HookStatusDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/HookStatusDisplay.test.js +0 -77
- package/dist/src/ui/components/HookStatusDisplay.test.js.map +0 -1
- package/dist/src/ui/components/HooksDialog.test.d.ts +0 -6
- package/dist/src/ui/components/HooksDialog.test.js +0 -175
- package/dist/src/ui/components/HooksDialog.test.js.map +0 -1
- package/dist/src/ui/components/IdeTrustChangeDialog.test.d.ts +0 -6
- package/dist/src/ui/components/IdeTrustChangeDialog.test.js +0 -78
- package/dist/src/ui/components/IdeTrustChangeDialog.test.js.map +0 -1
- package/dist/src/ui/components/InboxDialog.test.d.ts +0 -6
- package/dist/src/ui/components/InboxDialog.test.js +0 -804
- package/dist/src/ui/components/InboxDialog.test.js.map +0 -1
- package/dist/src/ui/components/InputPrompt.test.d.ts +0 -17
- package/dist/src/ui/components/InputPrompt.test.js +0 -4078
- package/dist/src/ui/components/InputPrompt.test.js.map +0 -1
- package/dist/src/ui/components/LoadingIndicator.test.d.ts +0 -6
- package/dist/src/ui/components/LoadingIndicator.test.js +0 -325
- package/dist/src/ui/components/LoadingIndicator.test.js.map +0 -1
- package/dist/src/ui/components/LogoutConfirmationDialog.test.d.ts +0 -6
- package/dist/src/ui/components/LogoutConfirmationDialog.test.js +0 -74
- package/dist/src/ui/components/LogoutConfirmationDialog.test.js.map +0 -1
- package/dist/src/ui/components/LoopDetectionConfirmation.test.d.ts +0 -6
- package/dist/src/ui/components/LoopDetectionConfirmation.test.js +0 -27
- package/dist/src/ui/components/LoopDetectionConfirmation.test.js.map +0 -1
- package/dist/src/ui/components/MainContent.test.d.ts +0 -6
- package/dist/src/ui/components/MainContent.test.js +0 -750
- package/dist/src/ui/components/MainContent.test.js.map +0 -1
- package/dist/src/ui/components/MemoryUsageDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/MemoryUsageDisplay.test.js +0 -52
- package/dist/src/ui/components/MemoryUsageDisplay.test.js.map +0 -1
- package/dist/src/ui/components/ModelDialog.test.d.ts +0 -6
- package/dist/src/ui/components/ModelDialog.test.js +0 -356
- package/dist/src/ui/components/ModelDialog.test.js.map +0 -1
- package/dist/src/ui/components/ModelQuotaDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/ModelQuotaDisplay.test.js +0 -62
- package/dist/src/ui/components/ModelQuotaDisplay.test.js.map +0 -1
- package/dist/src/ui/components/ModelStatsDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/ModelStatsDisplay.test.js +0 -651
- package/dist/src/ui/components/ModelStatsDisplay.test.js.map +0 -1
- package/dist/src/ui/components/MultiFolderTrustDialog.test.d.ts +0 -6
- package/dist/src/ui/components/MultiFolderTrustDialog.test.js +0 -177
- package/dist/src/ui/components/MultiFolderTrustDialog.test.js.map +0 -1
- package/dist/src/ui/components/NewAgentsNotification.test.d.ts +0 -6
- package/dist/src/ui/components/NewAgentsNotification.test.js +0 -83
- package/dist/src/ui/components/NewAgentsNotification.test.js.map +0 -1
- package/dist/src/ui/components/Notifications.test.d.ts +0 -6
- package/dist/src/ui/components/Notifications.test.js +0 -285
- package/dist/src/ui/components/Notifications.test.js.map +0 -1
- package/dist/src/ui/components/OverageMenuDialog.test.d.ts +0 -6
- package/dist/src/ui/components/OverageMenuDialog.test.js +0 -118
- package/dist/src/ui/components/OverageMenuDialog.test.js.map +0 -1
- package/dist/src/ui/components/PermissionsModifyTrustDialog.test.d.ts +0 -6
- package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js +0 -181
- package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js.map +0 -1
- package/dist/src/ui/components/PolicyUpdateDialog.test.d.ts +0 -6
- package/dist/src/ui/components/PolicyUpdateDialog.test.js +0 -92
- package/dist/src/ui/components/PolicyUpdateDialog.test.js.map +0 -1
- package/dist/src/ui/components/ProQuotaDialog.test.d.ts +0 -6
- package/dist/src/ui/components/ProQuotaDialog.test.js +0 -222
- package/dist/src/ui/components/ProQuotaDialog.test.js.map +0 -1
- package/dist/src/ui/components/ProgressBar.test.d.ts +0 -6
- package/dist/src/ui/components/ProgressBar.test.js +0 -28
- package/dist/src/ui/components/ProgressBar.test.js.map +0 -1
- package/dist/src/ui/components/QueuedMessageDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/QueuedMessageDisplay.test.js +0 -65
- package/dist/src/ui/components/QueuedMessageDisplay.test.js.map +0 -1
- package/dist/src/ui/components/QuittingDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/QuittingDisplay.test.js +0 -60
- package/dist/src/ui/components/QuittingDisplay.test.js.map +0 -1
- package/dist/src/ui/components/QuotaDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/QuotaDisplay.test.js +0 -68
- package/dist/src/ui/components/QuotaDisplay.test.js.map +0 -1
- package/dist/src/ui/components/RawMarkdownIndicator.test.d.ts +0 -6
- package/dist/src/ui/components/RawMarkdownIndicator.test.js +0 -38
- package/dist/src/ui/components/RawMarkdownIndicator.test.js.map +0 -1
- package/dist/src/ui/components/RewindConfirmation.test.d.ts +0 -6
- package/dist/src/ui/components/RewindConfirmation.test.js +0 -57
- package/dist/src/ui/components/RewindConfirmation.test.js.map +0 -1
- package/dist/src/ui/components/RewindViewer.test.d.ts +0 -6
- package/dist/src/ui/components/RewindViewer.test.js +0 -334
- package/dist/src/ui/components/RewindViewer.test.js.map +0 -1
- package/dist/src/ui/components/SessionBrowser/SessionBrowserSearchNav.test.d.ts +0 -6
- package/dist/src/ui/components/SessionBrowser/SessionBrowserSearchNav.test.js +0 -47
- package/dist/src/ui/components/SessionBrowser/SessionBrowserSearchNav.test.js.map +0 -1
- package/dist/src/ui/components/SessionBrowser/SessionBrowserStates.test.d.ts +0 -6
- package/dist/src/ui/components/SessionBrowser/SessionBrowserStates.test.js +0 -27
- package/dist/src/ui/components/SessionBrowser/SessionBrowserStates.test.js.map +0 -1
- package/dist/src/ui/components/SessionBrowser/utils.test.d.ts +0 -6
- package/dist/src/ui/components/SessionBrowser/utils.test.js +0 -108
- package/dist/src/ui/components/SessionBrowser/utils.test.js.map +0 -1
- package/dist/src/ui/components/SessionBrowser.test.d.ts +0 -6
- package/dist/src/ui/components/SessionBrowser.test.js +0 -266
- package/dist/src/ui/components/SessionBrowser.test.js.map +0 -1
- package/dist/src/ui/components/SessionSummaryDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/SessionSummaryDisplay.test.js +0 -164
- package/dist/src/ui/components/SessionSummaryDisplay.test.js.map +0 -1
- package/dist/src/ui/components/SettingsDialog.test.d.ts +0 -6
- package/dist/src/ui/components/SettingsDialog.test.js +0 -1499
- package/dist/src/ui/components/SettingsDialog.test.js.map +0 -1
- package/dist/src/ui/components/ShellInputPrompt.test.d.ts +0 -6
- package/dist/src/ui/components/ShellInputPrompt.test.js +0 -201
- package/dist/src/ui/components/ShellInputPrompt.test.js.map +0 -1
- package/dist/src/ui/components/ShellModeIndicator.test.d.ts +0 -6
- package/dist/src/ui/components/ShellModeIndicator.test.js +0 -18
- package/dist/src/ui/components/ShellModeIndicator.test.js.map +0 -1
- package/dist/src/ui/components/ShortcutsHelp.test.d.ts +0 -6
- package/dist/src/ui/components/ShortcutsHelp.test.js +0 -45
- package/dist/src/ui/components/ShortcutsHelp.test.js.map +0 -1
- package/dist/src/ui/components/ShowMoreLines.test.d.ts +0 -6
- package/dist/src/ui/components/ShowMoreLines.test.js +0 -79
- package/dist/src/ui/components/ShowMoreLines.test.js.map +0 -1
- package/dist/src/ui/components/ShowMoreLinesLayout.test.d.ts +0 -1
- package/dist/src/ui/components/ShowMoreLinesLayout.test.js +0 -68
- package/dist/src/ui/components/ShowMoreLinesLayout.test.js.map +0 -1
- package/dist/src/ui/components/StatsDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/StatsDisplay.test.js +0 -489
- package/dist/src/ui/components/StatsDisplay.test.js.map +0 -1
- package/dist/src/ui/components/StatusDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/StatusDisplay.test.js +0 -117
- package/dist/src/ui/components/StatusDisplay.test.js.map +0 -1
- package/dist/src/ui/components/StatusRow.test.d.ts +0 -6
- package/dist/src/ui/components/StatusRow.test.js +0 -99
- package/dist/src/ui/components/StatusRow.test.js.map +0 -1
- package/dist/src/ui/components/StickyHeader.test.d.ts +0 -6
- package/dist/src/ui/components/StickyHeader.test.js +0 -19
- package/dist/src/ui/components/StickyHeader.test.js.map +0 -1
- package/dist/src/ui/components/SuggestionsDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/SuggestionsDisplay.test.js +0 -82
- package/dist/src/ui/components/SuggestionsDisplay.test.js.map +0 -1
- package/dist/src/ui/components/Table.test.d.ts +0 -6
- package/dist/src/ui/components/Table.test.js +0 -72
- package/dist/src/ui/components/Table.test.js.map +0 -1
- package/dist/src/ui/components/ThemeDialog.test.d.ts +0 -6
- package/dist/src/ui/components/ThemeDialog.test.js +0 -162
- package/dist/src/ui/components/ThemeDialog.test.js.map +0 -1
- package/dist/src/ui/components/ThemedGradient.test.d.ts +0 -6
- package/dist/src/ui/components/ThemedGradient.test.js +0 -35
- package/dist/src/ui/components/ThemedGradient.test.js.map +0 -1
- package/dist/src/ui/components/Tips.test.d.ts +0 -6
- package/dist/src/ui/components/Tips.test.js +0 -23
- package/dist/src/ui/components/Tips.test.js.map +0 -1
- package/dist/src/ui/components/ToastDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/ToastDisplay.test.js +0 -167
- package/dist/src/ui/components/ToastDisplay.test.js.map +0 -1
- package/dist/src/ui/components/ToolConfirmationQueue.test.d.ts +0 -6
- package/dist/src/ui/components/ToolConfirmationQueue.test.js +0 -444
- package/dist/src/ui/components/ToolConfirmationQueue.test.js.map +0 -1
- package/dist/src/ui/components/ToolStatsDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/ToolStatsDisplay.test.js +0 -234
- package/dist/src/ui/components/ToolStatsDisplay.test.js.map +0 -1
- package/dist/src/ui/components/UpdateNotification.test.d.ts +0 -6
- package/dist/src/ui/components/UpdateNotification.test.js +0 -17
- package/dist/src/ui/components/UpdateNotification.test.js.map +0 -1
- package/dist/src/ui/components/UserIdentity.test.d.ts +0 -6
- package/dist/src/ui/components/UserIdentity.test.js +0 -138
- package/dist/src/ui/components/UserIdentity.test.js.map +0 -1
- package/dist/src/ui/components/ValidationDialog.test.d.ts +0 -6
- package/dist/src/ui/components/ValidationDialog.test.js +0 -162
- package/dist/src/ui/components/ValidationDialog.test.js.map +0 -1
- package/dist/src/ui/components/VoiceModelDialog.test.d.ts +0 -6
- package/dist/src/ui/components/VoiceModelDialog.test.js +0 -68
- package/dist/src/ui/components/VoiceModelDialog.test.js.map +0 -1
- package/dist/src/ui/components/messages/CompressionMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/CompressionMessage.test.js +0 -180
- package/dist/src/ui/components/messages/CompressionMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/DenseToolMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/DenseToolMessage.test.js +0 -406
- package/dist/src/ui/components/messages/DenseToolMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/DiffRenderer.test.d.ts +0 -6
- package/dist/src/ui/components/messages/DiffRenderer.test.js +0 -269
- package/dist/src/ui/components/messages/DiffRenderer.test.js.map +0 -1
- package/dist/src/ui/components/messages/ErrorMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ErrorMessage.test.js +0 -25
- package/dist/src/ui/components/messages/ErrorMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/ExportSessionMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ExportSessionMessage.test.js +0 -32
- package/dist/src/ui/components/messages/ExportSessionMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/GeminiMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/GeminiMessage.test.js +0 -46
- package/dist/src/ui/components/messages/GeminiMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/HintMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/HintMessage.test.js +0 -42
- package/dist/src/ui/components/messages/HintMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/InfoMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/InfoMessage.test.js +0 -31
- package/dist/src/ui/components/messages/InfoMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/RedirectionConfirmation.test.d.ts +0 -6
- package/dist/src/ui/components/messages/RedirectionConfirmation.test.js +0 -35
- package/dist/src/ui/components/messages/RedirectionConfirmation.test.js.map +0 -1
- package/dist/src/ui/components/messages/ShellToolMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ShellToolMessage.test.js +0 -290
- package/dist/src/ui/components/messages/ShellToolMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/SubagentGroupDisplay.test.d.ts +0 -1
- package/dist/src/ui/components/messages/SubagentGroupDisplay.test.js +0 -92
- package/dist/src/ui/components/messages/SubagentGroupDisplay.test.js.map +0 -1
- package/dist/src/ui/components/messages/SubagentHistoryMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/SubagentHistoryMessage.test.js +0 -69
- package/dist/src/ui/components/messages/SubagentHistoryMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/SubagentProgressDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/messages/SubagentProgressDisplay.test.js +0 -164
- package/dist/src/ui/components/messages/SubagentProgressDisplay.test.js.map +0 -1
- package/dist/src/ui/components/messages/ThinkingMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ThinkingMessage.test.js +0 -104
- package/dist/src/ui/components/messages/ThinkingMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/Todo.test.d.ts +0 -6
- package/dist/src/ui/components/messages/Todo.test.js +0 -129
- package/dist/src/ui/components/messages/Todo.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js +0 -558
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolGroupDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolGroupDisplay.test.js +0 -210
- package/dist/src/ui/components/messages/ToolGroupDisplay.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.compact.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolGroupMessage.compact.test.js +0 -147
- package/dist/src/ui/components/messages/ToolGroupMessage.compact.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js +0 -828
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolGroupMessageRegression.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolGroupMessageRegression.test.js +0 -101
- package/dist/src/ui/components/messages/ToolGroupMessageRegression.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolMessage.test.js +0 -292
- package/dist/src/ui/components/messages/ToolMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolMessageFocusHint.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolMessageFocusHint.test.js +0 -96
- package/dist/src/ui/components/messages/ToolMessageFocusHint.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolMessageRawMarkdown.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolMessageRawMarkdown.test.js +0 -72
- package/dist/src/ui/components/messages/ToolMessageRawMarkdown.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolOverflowConsistencyChecks.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolOverflowConsistencyChecks.test.js +0 -88
- package/dist/src/ui/components/messages/ToolOverflowConsistencyChecks.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolResultDisplay.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolResultDisplay.test.js +0 -333
- package/dist/src/ui/components/messages/ToolResultDisplay.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolResultDisplayOverflow.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolResultDisplayOverflow.test.js +0 -77
- package/dist/src/ui/components/messages/ToolResultDisplayOverflow.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolShared.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolShared.test.js +0 -65
- package/dist/src/ui/components/messages/ToolShared.test.js.map +0 -1
- package/dist/src/ui/components/messages/ToolStickyHeaderRegression.test.d.ts +0 -6
- package/dist/src/ui/components/messages/ToolStickyHeaderRegression.test.js +0 -142
- package/dist/src/ui/components/messages/ToolStickyHeaderRegression.test.js.map +0 -1
- package/dist/src/ui/components/messages/TopicMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/TopicMessage.test.js +0 -77
- package/dist/src/ui/components/messages/TopicMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/UserMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/UserMessage.test.js +0 -67
- package/dist/src/ui/components/messages/UserMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/UserShellMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/UserShellMessage.test.js +0 -40
- package/dist/src/ui/components/messages/UserShellMessage.test.js.map +0 -1
- package/dist/src/ui/components/messages/WarningMessage.test.d.ts +0 -6
- package/dist/src/ui/components/messages/WarningMessage.test.js +0 -25
- package/dist/src/ui/components/messages/WarningMessage.test.js.map +0 -1
- package/dist/src/ui/components/shared/BaseSelectionList.test.d.ts +0 -6
- package/dist/src/ui/components/shared/BaseSelectionList.test.js +0 -441
- package/dist/src/ui/components/shared/BaseSelectionList.test.js.map +0 -1
- package/dist/src/ui/components/shared/BaseSettingsDialog.test.d.ts +0 -6
- package/dist/src/ui/components/shared/BaseSettingsDialog.test.js +0 -710
- package/dist/src/ui/components/shared/BaseSettingsDialog.test.js.map +0 -1
- package/dist/src/ui/components/shared/DescriptiveRadioButtonSelect.test.d.ts +0 -6
- package/dist/src/ui/components/shared/DescriptiveRadioButtonSelect.test.js +0 -89
- package/dist/src/ui/components/shared/DescriptiveRadioButtonSelect.test.js.map +0 -1
- package/dist/src/ui/components/shared/EnumSelector.test.d.ts +0 -6
- package/dist/src/ui/components/shared/EnumSelector.test.js +0 -83
- package/dist/src/ui/components/shared/EnumSelector.test.js.map +0 -1
- package/dist/src/ui/components/shared/ExpandableText.test.d.ts +0 -6
- package/dist/src/ui/components/shared/ExpandableText.test.js +0 -95
- package/dist/src/ui/components/shared/ExpandableText.test.js.map +0 -1
- package/dist/src/ui/components/shared/HalfLinePaddedBox.test.d.ts +0 -1
- package/dist/src/ui/components/shared/HalfLinePaddedBox.test.js +0 -47
- package/dist/src/ui/components/shared/HalfLinePaddedBox.test.js.map +0 -1
- package/dist/src/ui/components/shared/MaxSizedBox.test.d.ts +0 -6
- package/dist/src/ui/components/shared/MaxSizedBox.test.js +0 -161
- package/dist/src/ui/components/shared/MaxSizedBox.test.js.map +0 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.test.d.ts +0 -6
- package/dist/src/ui/components/shared/RadioButtonSelect.test.js +0 -146
- package/dist/src/ui/components/shared/RadioButtonSelect.test.js.map +0 -1
- package/dist/src/ui/components/shared/Scrollable.test.d.ts +0 -6
- package/dist/src/ui/components/shared/Scrollable.test.js +0 -143
- package/dist/src/ui/components/shared/Scrollable.test.js.map +0 -1
- package/dist/src/ui/components/shared/ScrollableList.test.d.ts +0 -6
- package/dist/src/ui/components/shared/ScrollableList.test.js +0 -438
- package/dist/src/ui/components/shared/ScrollableList.test.js.map +0 -1
- package/dist/src/ui/components/shared/SearchableList.test.d.ts +0 -6
- package/dist/src/ui/components/shared/SearchableList.test.js +0 -169
- package/dist/src/ui/components/shared/SearchableList.test.js.map +0 -1
- package/dist/src/ui/components/shared/SectionHeader.test.d.ts +0 -6
- package/dist/src/ui/components/shared/SectionHeader.test.js +0 -42
- package/dist/src/ui/components/shared/SectionHeader.test.js.map +0 -1
- package/dist/src/ui/components/shared/SlicingMaxSizedBox.test.d.ts +0 -6
- package/dist/src/ui/components/shared/SlicingMaxSizedBox.test.js +0 -54
- package/dist/src/ui/components/shared/SlicingMaxSizedBox.test.js.map +0 -1
- package/dist/src/ui/components/shared/TabHeader.test.d.ts +0 -6
- package/dist/src/ui/components/shared/TabHeader.test.js +0 -144
- package/dist/src/ui/components/shared/TabHeader.test.js.map +0 -1
- package/dist/src/ui/components/shared/TextInput.test.d.ts +0 -6
- package/dist/src/ui/components/shared/TextInput.test.js +0 -353
- package/dist/src/ui/components/shared/TextInput.test.js.map +0 -1
- package/dist/src/ui/components/shared/VirtualizedList.test.d.ts +0 -6
- package/dist/src/ui/components/shared/VirtualizedList.test.js +0 -174
- package/dist/src/ui/components/shared/VirtualizedList.test.js.map +0 -1
- package/dist/src/ui/components/shared/performance.test.d.ts +0 -1
- package/dist/src/ui/components/shared/performance.test.js +0 -74
- package/dist/src/ui/components/shared/performance.test.js.map +0 -1
- package/dist/src/ui/components/shared/text-buffer.test.d.ts +0 -6
- package/dist/src/ui/components/shared/text-buffer.test.js +0 -2965
- package/dist/src/ui/components/shared/text-buffer.test.js.map +0 -1
- package/dist/src/ui/components/shared/vim-buffer-actions.test.d.ts +0 -6
- package/dist/src/ui/components/shared/vim-buffer-actions.test.js +0 -2272
- package/dist/src/ui/components/shared/vim-buffer-actions.test.js.map +0 -1
- package/dist/src/ui/components/views/ChatList.test.d.ts +0 -6
- package/dist/src/ui/components/views/ChatList.test.js +0 -45
- package/dist/src/ui/components/views/ChatList.test.js.map +0 -1
- package/dist/src/ui/components/views/ExtensionDetails.test.d.ts +0 -6
- package/dist/src/ui/components/views/ExtensionDetails.test.js +0 -154
- package/dist/src/ui/components/views/ExtensionDetails.test.js.map +0 -1
- package/dist/src/ui/components/views/ExtensionRegistryView.test.d.ts +0 -6
- package/dist/src/ui/components/views/ExtensionRegistryView.test.js +0 -222
- package/dist/src/ui/components/views/ExtensionRegistryView.test.js.map +0 -1
- package/dist/src/ui/components/views/ExtensionsList.test.d.ts +0 -6
- package/dist/src/ui/components/views/ExtensionsList.test.js +0 -145
- package/dist/src/ui/components/views/ExtensionsList.test.js.map +0 -1
- package/dist/src/ui/components/views/McpStatus.test.d.ts +0 -6
- package/dist/src/ui/components/views/McpStatus.test.js +0 -174
- package/dist/src/ui/components/views/McpStatus.test.js.map +0 -1
- package/dist/src/ui/components/views/SkillsList.test.d.ts +0 -6
- package/dist/src/ui/components/views/SkillsList.test.js +0 -99
- package/dist/src/ui/components/views/SkillsList.test.js.map +0 -1
- package/dist/src/ui/components/views/ToolsList.test.d.ts +0 -6
- package/dist/src/ui/components/views/ToolsList.test.js +0 -45
- package/dist/src/ui/components/views/ToolsList.test.js.map +0 -1
- package/dist/src/ui/contexts/KeypressContext.test.d.ts +0 -6
- package/dist/src/ui/contexts/KeypressContext.test.js +0 -1133
- package/dist/src/ui/contexts/KeypressContext.test.js.map +0 -1
- package/dist/src/ui/contexts/MouseContext.test.d.ts +0 -6
- package/dist/src/ui/contexts/MouseContext.test.js +0 -269
- package/dist/src/ui/contexts/MouseContext.test.js.map +0 -1
- package/dist/src/ui/contexts/ScrollProvider.drag.test.d.ts +0 -6
- package/dist/src/ui/contexts/ScrollProvider.drag.test.js +0 -320
- package/dist/src/ui/contexts/ScrollProvider.drag.test.js.map +0 -1
- package/dist/src/ui/contexts/ScrollProvider.test.d.ts +0 -6
- package/dist/src/ui/contexts/ScrollProvider.test.js +0 -478
- package/dist/src/ui/contexts/ScrollProvider.test.js.map +0 -1
- package/dist/src/ui/contexts/SessionContext.test.d.ts +0 -6
- package/dist/src/ui/contexts/SessionContext.test.js +0 -213
- package/dist/src/ui/contexts/SessionContext.test.js.map +0 -1
- package/dist/src/ui/contexts/SettingsContext.test.d.ts +0 -6
- package/dist/src/ui/contexts/SettingsContext.test.js +0 -106
- package/dist/src/ui/contexts/SettingsContext.test.js.map +0 -1
- package/dist/src/ui/contexts/TerminalContext.test.d.ts +0 -6
- package/dist/src/ui/contexts/TerminalContext.test.js +0 -75
- package/dist/src/ui/contexts/TerminalContext.test.js.map +0 -1
- package/dist/src/ui/contexts/ToolActionsContext.test.d.ts +0 -6
- package/dist/src/ui/contexts/ToolActionsContext.test.js +0 -247
- package/dist/src/ui/contexts/ToolActionsContext.test.js.map +0 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.d.ts +0 -6
- package/dist/src/ui/hooks/atCommandProcessor.test.js +0 -1265
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +0 -1
- package/dist/src/ui/hooks/atCommandProcessor_agents.test.d.ts +0 -6
- package/dist/src/ui/hooks/atCommandProcessor_agents.test.js +0 -210
- package/dist/src/ui/hooks/atCommandProcessor_agents.test.js.map +0 -1
- package/dist/src/ui/hooks/creditsFlowHandler.test.d.ts +0 -6
- package/dist/src/ui/hooks/creditsFlowHandler.test.js +0 -211
- package/dist/src/ui/hooks/creditsFlowHandler.test.js.map +0 -1
- package/dist/src/ui/hooks/shell-completions/gitProvider.test.d.ts +0 -6
- package/dist/src/ui/hooks/shell-completions/gitProvider.test.js +0 -73
- package/dist/src/ui/hooks/shell-completions/gitProvider.test.js.map +0 -1
- package/dist/src/ui/hooks/shell-completions/npmProvider.test.d.ts +0 -6
- package/dist/src/ui/hooks/shell-completions/npmProvider.test.js +0 -69
- package/dist/src/ui/hooks/shell-completions/npmProvider.test.js.map +0 -1
- package/dist/src/ui/hooks/shellReducer.test.d.ts +0 -6
- package/dist/src/ui/hooks/shellReducer.test.js +0 -341
- package/dist/src/ui/hooks/shellReducer.test.js.map +0 -1
- package/dist/src/ui/hooks/slashCommandProcessor.test.d.ts +0 -6
- package/dist/src/ui/hooks/slashCommandProcessor.test.js +0 -881
- package/dist/src/ui/hooks/slashCommandProcessor.test.js.map +0 -1
- package/dist/src/ui/hooks/toolMapping.test.d.ts +0 -6
- package/dist/src/ui/hooks/toolMapping.test.js +0 -292
- package/dist/src/ui/hooks/toolMapping.test.js.map +0 -1
- package/dist/src/ui/hooks/useAgentStream.test.d.ts +0 -6
- package/dist/src/ui/hooks/useAgentStream.test.js +0 -161
- package/dist/src/ui/hooks/useAgentStream.test.js.map +0 -1
- package/dist/src/ui/hooks/useAlternateBuffer.test.d.ts +0 -6
- package/dist/src/ui/hooks/useAlternateBuffer.test.js +0 -62
- package/dist/src/ui/hooks/useAlternateBuffer.test.js.map +0 -1
- package/dist/src/ui/hooks/useAnimatedScrollbar.test.d.ts +0 -6
- package/dist/src/ui/hooks/useAnimatedScrollbar.test.js +0 -85
- package/dist/src/ui/hooks/useAnimatedScrollbar.test.js.map +0 -1
- package/dist/src/ui/hooks/useApprovalModeIndicator.test.d.ts +0 -6
- package/dist/src/ui/hooks/useApprovalModeIndicator.test.js +0 -477
- package/dist/src/ui/hooks/useApprovalModeIndicator.test.js.map +0 -1
- package/dist/src/ui/hooks/useAtCompletion.test.d.ts +0 -6
- package/dist/src/ui/hooks/useAtCompletion.test.js +0 -567
- package/dist/src/ui/hooks/useAtCompletion.test.js.map +0 -1
- package/dist/src/ui/hooks/useAtCompletion_agents.test.d.ts +0 -6
- package/dist/src/ui/hooks/useAtCompletion_agents.test.js +0 -87
- package/dist/src/ui/hooks/useAtCompletion_agents.test.js.map +0 -1
- package/dist/src/ui/hooks/useBackgroundTaskManager.test.d.ts +0 -6
- package/dist/src/ui/hooks/useBackgroundTaskManager.test.js +0 -168
- package/dist/src/ui/hooks/useBackgroundTaskManager.test.js.map +0 -1
- package/dist/src/ui/hooks/useBanner.test.d.ts +0 -6
- package/dist/src/ui/hooks/useBanner.test.js +0 -144
- package/dist/src/ui/hooks/useBanner.test.js.map +0 -1
- package/dist/src/ui/hooks/useBatchedScroll.test.d.ts +0 -6
- package/dist/src/ui/hooks/useBatchedScroll.test.js +0 -62
- package/dist/src/ui/hooks/useBatchedScroll.test.js.map +0 -1
- package/dist/src/ui/hooks/useCommandCompletion.test.d.ts +0 -6
- package/dist/src/ui/hooks/useCommandCompletion.test.js +0 -722
- package/dist/src/ui/hooks/useCommandCompletion.test.js.map +0 -1
- package/dist/src/ui/hooks/useConsoleMessages.test.d.ts +0 -6
- package/dist/src/ui/hooks/useConsoleMessages.test.js +0 -201
- package/dist/src/ui/hooks/useConsoleMessages.test.js.map +0 -1
- package/dist/src/ui/hooks/useEditorSettings.test.d.ts +0 -6
- package/dist/src/ui/hooks/useEditorSettings.test.js +0 -179
- package/dist/src/ui/hooks/useEditorSettings.test.js.map +0 -1
- package/dist/src/ui/hooks/useExecutionLifecycle.test.d.ts +0 -6
- package/dist/src/ui/hooks/useExecutionLifecycle.test.js +0 -903
- package/dist/src/ui/hooks/useExecutionLifecycle.test.js.map +0 -1
- package/dist/src/ui/hooks/useExtensionUpdates.test.d.ts +0 -6
- package/dist/src/ui/hooks/useExtensionUpdates.test.js +0 -280
- package/dist/src/ui/hooks/useExtensionUpdates.test.js.map +0 -1
- package/dist/src/ui/hooks/useFlickerDetector.test.d.ts +0 -6
- package/dist/src/ui/hooks/useFlickerDetector.test.js +0 -106
- package/dist/src/ui/hooks/useFlickerDetector.test.js.map +0 -1
- package/dist/src/ui/hooks/useFocus.test.d.ts +0 -6
- package/dist/src/ui/hooks/useFocus.test.js +0 -140
- package/dist/src/ui/hooks/useFocus.test.js.map +0 -1
- package/dist/src/ui/hooks/useFolderTrust.test.d.ts +0 -6
- package/dist/src/ui/hooks/useFolderTrust.test.js +0 -268
- package/dist/src/ui/hooks/useFolderTrust.test.js.map +0 -1
- package/dist/src/ui/hooks/useGeminiStream.test.d.ts +0 -6
- package/dist/src/ui/hooks/useGeminiStream.test.js +0 -2855
- package/dist/src/ui/hooks/useGeminiStream.test.js.map +0 -1
- package/dist/src/ui/hooks/useGitBranchName.test.d.ts +0 -6
- package/dist/src/ui/hooks/useGitBranchName.test.js +0 -237
- package/dist/src/ui/hooks/useGitBranchName.test.js.map +0 -1
- package/dist/src/ui/hooks/useHistoryManager.test.d.ts +0 -6
- package/dist/src/ui/hooks/useHistoryManager.test.js +0 -259
- package/dist/src/ui/hooks/useHistoryManager.test.js.map +0 -1
- package/dist/src/ui/hooks/useHookDisplayState.test.d.ts +0 -6
- package/dist/src/ui/hooks/useHookDisplayState.test.js +0 -200
- package/dist/src/ui/hooks/useHookDisplayState.test.js.map +0 -1
- package/dist/src/ui/hooks/useIdeTrustListener.test.d.ts +0 -6
- package/dist/src/ui/hooks/useIdeTrustListener.test.js +0 -225
- package/dist/src/ui/hooks/useIdeTrustListener.test.js.map +0 -1
- package/dist/src/ui/hooks/useIncludeDirsTrust.test.d.ts +0 -6
- package/dist/src/ui/hooks/useIncludeDirsTrust.test.js +0 -174
- package/dist/src/ui/hooks/useIncludeDirsTrust.test.js.map +0 -1
- package/dist/src/ui/hooks/useInlineEditBuffer.test.d.ts +0 -6
- package/dist/src/ui/hooks/useInlineEditBuffer.test.js +0 -112
- package/dist/src/ui/hooks/useInlineEditBuffer.test.js.map +0 -1
- package/dist/src/ui/hooks/useInputHistory.test.d.ts +0 -6
- package/dist/src/ui/hooks/useInputHistory.test.js +0 -389
- package/dist/src/ui/hooks/useInputHistory.test.js.map +0 -1
- package/dist/src/ui/hooks/useInputHistoryStore.test.d.ts +0 -6
- package/dist/src/ui/hooks/useInputHistoryStore.test.js +0 -238
- package/dist/src/ui/hooks/useInputHistoryStore.test.js.map +0 -1
- package/dist/src/ui/hooks/useKeypress.test.d.ts +0 -6
- package/dist/src/ui/hooks/useKeypress.test.js +0 -198
- package/dist/src/ui/hooks/useKeypress.test.js.map +0 -1
- package/dist/src/ui/hooks/useLoadingIndicator.test.d.ts +0 -6
- package/dist/src/ui/hooks/useLoadingIndicator.test.js +0 -177
- package/dist/src/ui/hooks/useLoadingIndicator.test.js.map +0 -1
- package/dist/src/ui/hooks/useLogger.test.d.ts +0 -6
- package/dist/src/ui/hooks/useLogger.test.js +0 -44
- package/dist/src/ui/hooks/useLogger.test.js.map +0 -1
- package/dist/src/ui/hooks/useMcpStatus.test.d.ts +0 -6
- package/dist/src/ui/hooks/useMcpStatus.test.js +0 -69
- package/dist/src/ui/hooks/useMcpStatus.test.js.map +0 -1
- package/dist/src/ui/hooks/useMemoryMonitor.test.d.ts +0 -6
- package/dist/src/ui/hooks/useMemoryMonitor.test.js +0 -62
- package/dist/src/ui/hooks/useMemoryMonitor.test.js.map +0 -1
- package/dist/src/ui/hooks/useMessageQueue.test.d.ts +0 -6
- package/dist/src/ui/hooks/useMessageQueue.test.js +0 -365
- package/dist/src/ui/hooks/useMessageQueue.test.js.map +0 -1
- package/dist/src/ui/hooks/useModelCommand.test.d.ts +0 -6
- package/dist/src/ui/hooks/useModelCommand.test.js +0 -45
- package/dist/src/ui/hooks/useModelCommand.test.js.map +0 -1
- package/dist/src/ui/hooks/useMouse.test.d.ts +0 -6
- package/dist/src/ui/hooks/useMouse.test.js +0 -52
- package/dist/src/ui/hooks/useMouse.test.js.map +0 -1
- package/dist/src/ui/hooks/useMouseClick.test.d.ts +0 -6
- package/dist/src/ui/hooks/useMouseClick.test.js +0 -68
- package/dist/src/ui/hooks/useMouseClick.test.js.map +0 -1
- package/dist/src/ui/hooks/usePermissionsModifyTrust.test.d.ts +0 -6
- package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js +0 -291
- package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js.map +0 -1
- package/dist/src/ui/hooks/usePhraseCycler.test.d.ts +0 -6
- package/dist/src/ui/hooks/usePhraseCycler.test.js +0 -187
- package/dist/src/ui/hooks/usePhraseCycler.test.js.map +0 -1
- package/dist/src/ui/hooks/usePrivacySettings.test.d.ts +0 -6
- package/dist/src/ui/hooks/usePrivacySettings.test.js +0 -113
- package/dist/src/ui/hooks/usePrivacySettings.test.js.map +0 -1
- package/dist/src/ui/hooks/useQuotaAndFallback.test.d.ts +0 -6
- package/dist/src/ui/hooks/useQuotaAndFallback.test.js +0 -817
- package/dist/src/ui/hooks/useQuotaAndFallback.test.js.map +0 -1
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.d.ts +0 -6
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.js +0 -168
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.js.map +0 -1
- package/dist/src/ui/hooks/useRewind.test.d.ts +0 -6
- package/dist/src/ui/hooks/useRewind.test.js +0 -100
- package/dist/src/ui/hooks/useRewind.test.js.map +0 -1
- package/dist/src/ui/hooks/useSelectionList.test.d.ts +0 -6
- package/dist/src/ui/hooks/useSelectionList.test.js +0 -960
- package/dist/src/ui/hooks/useSelectionList.test.js.map +0 -1
- package/dist/src/ui/hooks/useSessionBrowser.test.d.ts +0 -6
- package/dist/src/ui/hooks/useSessionBrowser.test.js +0 -277
- package/dist/src/ui/hooks/useSessionBrowser.test.js.map +0 -1
- package/dist/src/ui/hooks/useSessionResume.test.d.ts +0 -6
- package/dist/src/ui/hooks/useSessionResume.test.js +0 -402
- package/dist/src/ui/hooks/useSessionResume.test.js.map +0 -1
- package/dist/src/ui/hooks/useSettingsNavigation.test.d.ts +0 -6
- package/dist/src/ui/hooks/useSettingsNavigation.test.js +0 -87
- package/dist/src/ui/hooks/useSettingsNavigation.test.js.map +0 -1
- package/dist/src/ui/hooks/useShellCompletion.test.d.ts +0 -6
- package/dist/src/ui/hooks/useShellCompletion.test.js +0 -354
- package/dist/src/ui/hooks/useShellCompletion.test.js.map +0 -1
- package/dist/src/ui/hooks/useShellHistory.test.d.ts +0 -6
- package/dist/src/ui/hooks/useShellHistory.test.js +0 -226
- package/dist/src/ui/hooks/useShellHistory.test.js.map +0 -1
- package/dist/src/ui/hooks/useShellInactivityStatus.test.d.ts +0 -6
- package/dist/src/ui/hooks/useShellInactivityStatus.test.js +0 -84
- package/dist/src/ui/hooks/useShellInactivityStatus.test.js.map +0 -1
- package/dist/src/ui/hooks/useSlashCompletion.test.d.ts +0 -10
- package/dist/src/ui/hooks/useSlashCompletion.test.js +0 -977
- package/dist/src/ui/hooks/useSlashCompletion.test.js.map +0 -1
- package/dist/src/ui/hooks/useSnowfall.test.d.ts +0 -6
- package/dist/src/ui/hooks/useSnowfall.test.js +0 -92
- package/dist/src/ui/hooks/useSnowfall.test.js.map +0 -1
- package/dist/src/ui/hooks/useSuspend.test.d.ts +0 -6
- package/dist/src/ui/hooks/useSuspend.test.js +0 -136
- package/dist/src/ui/hooks/useSuspend.test.js.map +0 -1
- package/dist/src/ui/hooks/useTabbedNavigation.test.d.ts +0 -6
- package/dist/src/ui/hooks/useTabbedNavigation.test.js +0 -243
- package/dist/src/ui/hooks/useTabbedNavigation.test.js.map +0 -1
- package/dist/src/ui/hooks/useTerminalTheme.test.d.ts +0 -6
- package/dist/src/ui/hooks/useTerminalTheme.test.js +0 -169
- package/dist/src/ui/hooks/useTerminalTheme.test.js.map +0 -1
- package/dist/src/ui/hooks/useTimer.test.d.ts +0 -6
- package/dist/src/ui/hooks/useTimer.test.js +0 -119
- package/dist/src/ui/hooks/useTimer.test.js.map +0 -1
- package/dist/src/ui/hooks/useTips.test.d.ts +0 -6
- package/dist/src/ui/hooks/useTips.test.js +0 -33
- package/dist/src/ui/hooks/useTips.test.js.map +0 -1
- package/dist/src/ui/hooks/useToolScheduler.test.d.ts +0 -6
- package/dist/src/ui/hooks/useToolScheduler.test.js +0 -534
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +0 -1
- package/dist/src/ui/hooks/useTurnActivityMonitor.test.d.ts +0 -6
- package/dist/src/ui/hooks/useTurnActivityMonitor.test.js +0 -99
- package/dist/src/ui/hooks/useTurnActivityMonitor.test.js.map +0 -1
- package/dist/src/ui/hooks/vim-passthrough.test.d.ts +0 -6
- package/dist/src/ui/hooks/vim-passthrough.test.js +0 -84
- package/dist/src/ui/hooks/vim-passthrough.test.js.map +0 -1
- package/dist/src/ui/hooks/vim.test.d.ts +0 -6
- package/dist/src/ui/hooks/vim.test.js +0 -2156
- package/dist/src/ui/hooks/vim.test.js.map +0 -1
- package/dist/src/ui/key/keyBindings.test.d.ts +0 -6
- package/dist/src/ui/key/keyBindings.test.js +0 -225
- package/dist/src/ui/key/keyBindings.test.js.map +0 -1
- package/dist/src/ui/key/keyMatchers.test.d.ts +0 -6
- package/dist/src/ui/key/keyMatchers.test.js +0 -524
- package/dist/src/ui/key/keyMatchers.test.js.map +0 -1
- package/dist/src/ui/key/keybindingUtils.test.d.ts +0 -6
- package/dist/src/ui/key/keybindingUtils.test.js +0 -121
- package/dist/src/ui/key/keybindingUtils.test.js.map +0 -1
- package/dist/src/ui/layouts/DefaultAppLayout.test.d.ts +0 -6
- package/dist/src/ui/layouts/DefaultAppLayout.test.js +0 -126
- package/dist/src/ui/layouts/DefaultAppLayout.test.js.map +0 -1
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.test.d.ts +0 -6
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.test.js +0 -134
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.test.js.map +0 -1
- package/dist/src/ui/privacy/CloudPaidPrivacyNotice.test.d.ts +0 -6
- package/dist/src/ui/privacy/CloudPaidPrivacyNotice.test.js +0 -43
- package/dist/src/ui/privacy/CloudPaidPrivacyNotice.test.js.map +0 -1
- package/dist/src/ui/privacy/GeminiPrivacyNotice.test.d.ts +0 -6
- package/dist/src/ui/privacy/GeminiPrivacyNotice.test.js +0 -43
- package/dist/src/ui/privacy/GeminiPrivacyNotice.test.js.map +0 -1
- package/dist/src/ui/privacy/PrivacyNotice.test.d.ts +0 -6
- package/dist/src/ui/privacy/PrivacyNotice.test.js +0 -63
- package/dist/src/ui/privacy/PrivacyNotice.test.js.map +0 -1
- package/dist/src/ui/state/extensions.test.d.ts +0 -6
- package/dist/src/ui/state/extensions.test.js +0 -219
- package/dist/src/ui/state/extensions.test.js.map +0 -1
- package/dist/src/ui/themes/color-utils.test.d.ts +0 -6
- package/dist/src/ui/themes/color-utils.test.js +0 -326
- package/dist/src/ui/themes/color-utils.test.js.map +0 -1
- package/dist/src/ui/themes/theme-manager.test.d.ts +0 -6
- package/dist/src/ui/themes/theme-manager.test.js +0 -274
- package/dist/src/ui/themes/theme-manager.test.js.map +0 -1
- package/dist/src/ui/themes/theme.test.d.ts +0 -6
- package/dist/src/ui/themes/theme.test.js +0 -171
- package/dist/src/ui/themes/theme.test.js.map +0 -1
- package/dist/src/ui/utils/CodeColorizer.test.d.ts +0 -6
- package/dist/src/ui/utils/CodeColorizer.test.js +0 -74
- package/dist/src/ui/utils/CodeColorizer.test.js.map +0 -1
- package/dist/src/ui/utils/ConsolePatcher.test.d.ts +0 -6
- package/dist/src/ui/utils/ConsolePatcher.test.js +0 -199
- package/dist/src/ui/utils/ConsolePatcher.test.js.map +0 -1
- package/dist/src/ui/utils/MarkdownDisplay.test.d.ts +0 -6
- package/dist/src/ui/utils/MarkdownDisplay.test.js +0 -175
- package/dist/src/ui/utils/MarkdownDisplay.test.js.map +0 -1
- package/dist/src/ui/utils/TableRenderer.test.d.ts +0 -1
- package/dist/src/ui/utils/TableRenderer.test.js +0 -396
- package/dist/src/ui/utils/TableRenderer.test.js.map +0 -1
- package/dist/src/ui/utils/antigravityUtils.test.d.ts +0 -6
- package/dist/src/ui/utils/antigravityUtils.test.js +0 -54
- package/dist/src/ui/utils/antigravityUtils.test.js.map +0 -1
- package/dist/src/ui/utils/borderStyles.test.d.ts +0 -6
- package/dist/src/ui/utils/borderStyles.test.js +0 -172
- package/dist/src/ui/utils/borderStyles.test.js.map +0 -1
- package/dist/src/ui/utils/clipboardUtils.test.d.ts +0 -6
- package/dist/src/ui/utils/clipboardUtils.test.js +0 -442
- package/dist/src/ui/utils/clipboardUtils.test.js.map +0 -1
- package/dist/src/ui/utils/clipboardUtils.windows.test.d.ts +0 -6
- package/dist/src/ui/utils/clipboardUtils.windows.test.js +0 -56
- package/dist/src/ui/utils/clipboardUtils.windows.test.js.map +0 -1
- package/dist/src/ui/utils/commandUtils.test.d.ts +0 -6
- package/dist/src/ui/utils/commandUtils.test.js +0 -511
- package/dist/src/ui/utils/commandUtils.test.js.map +0 -1
- package/dist/src/ui/utils/computeStats.test.d.ts +0 -6
- package/dist/src/ui/utils/computeStats.test.js +0 -279
- package/dist/src/ui/utils/computeStats.test.js.map +0 -1
- package/dist/src/ui/utils/directoryUtils.test.d.ts +0 -6
- package/dist/src/ui/utils/directoryUtils.test.js +0 -239
- package/dist/src/ui/utils/directoryUtils.test.js.map +0 -1
- package/dist/src/ui/utils/displayUtils.test.d.ts +0 -6
- package/dist/src/ui/utils/displayUtils.test.js +0 -61
- package/dist/src/ui/utils/displayUtils.test.js.map +0 -1
- package/dist/src/ui/utils/formatters.test.d.ts +0 -6
- package/dist/src/ui/utils/formatters.test.js +0 -152
- package/dist/src/ui/utils/formatters.test.js.map +0 -1
- package/dist/src/ui/utils/highlight.test.d.ts +0 -6
- package/dist/src/ui/utils/highlight.test.js +0 -205
- package/dist/src/ui/utils/highlight.test.js.map +0 -1
- package/dist/src/ui/utils/input.test.d.ts +0 -6
- package/dist/src/ui/utils/input.test.js +0 -44
- package/dist/src/ui/utils/input.test.js.map +0 -1
- package/dist/src/ui/utils/latexToUnicode.test.d.ts +0 -6
- package/dist/src/ui/utils/latexToUnicode.test.js +0 -222
- package/dist/src/ui/utils/latexToUnicode.test.js.map +0 -1
- package/dist/src/ui/utils/markdownParsingUtils.test.d.ts +0 -6
- package/dist/src/ui/utils/markdownParsingUtils.test.js +0 -201
- package/dist/src/ui/utils/markdownParsingUtils.test.js.map +0 -1
- package/dist/src/ui/utils/markdownUtilities.test.d.ts +0 -6
- package/dist/src/ui/utils/markdownUtilities.test.js +0 -42
- package/dist/src/ui/utils/markdownUtilities.test.js.map +0 -1
- package/dist/src/ui/utils/memorySnapshot.test.d.ts +0 -6
- package/dist/src/ui/utils/memorySnapshot.test.js +0 -62
- package/dist/src/ui/utils/memorySnapshot.test.js.map +0 -1
- package/dist/src/ui/utils/mouse.test.d.ts +0 -6
- package/dist/src/ui/utils/mouse.test.js +0 -136
- package/dist/src/ui/utils/mouse.test.js.map +0 -1
- package/dist/src/ui/utils/pendingAttentionNotification.test.d.ts +0 -6
- package/dist/src/ui/utils/pendingAttentionNotification.test.js +0 -79
- package/dist/src/ui/utils/pendingAttentionNotification.test.js.map +0 -1
- package/dist/src/ui/utils/rewindFileOps.test.d.ts +0 -6
- package/dist/src/ui/utils/rewindFileOps.test.js +0 -375
- package/dist/src/ui/utils/rewindFileOps.test.js.map +0 -1
- package/dist/src/ui/utils/terminalCapabilityManager.test.d.ts +0 -6
- package/dist/src/ui/utils/terminalCapabilityManager.test.js +0 -400
- package/dist/src/ui/utils/terminalCapabilityManager.test.js.map +0 -1
- package/dist/src/ui/utils/terminalSetup.test.d.ts +0 -6
- package/dist/src/ui/utils/terminalSetup.test.js +0 -201
- package/dist/src/ui/utils/terminalSetup.test.js.map +0 -1
- package/dist/src/ui/utils/textOutput.test.d.ts +0 -6
- package/dist/src/ui/utils/textOutput.test.js +0 -80
- package/dist/src/ui/utils/textOutput.test.js.map +0 -1
- package/dist/src/ui/utils/textUtils.test.d.ts +0 -6
- package/dist/src/ui/utils/textUtils.test.js +0 -430
- package/dist/src/ui/utils/textUtils.test.js.map +0 -1
- package/dist/src/ui/utils/toolLayoutUtils.test.d.ts +0 -6
- package/dist/src/ui/utils/toolLayoutUtils.test.js +0 -187
- package/dist/src/ui/utils/toolLayoutUtils.test.js.map +0 -1
- package/dist/src/ui/utils/ui-sizing.test.d.ts +0 -6
- package/dist/src/ui/utils/ui-sizing.test.js +0 -25
- package/dist/src/ui/utils/ui-sizing.test.js.map +0 -1
- package/dist/src/ui/utils/updateCheck.test.d.ts +0 -6
- package/dist/src/ui/utils/updateCheck.test.js +0 -207
- package/dist/src/ui/utils/updateCheck.test.js.map +0 -1
- package/dist/src/ui/utils/urlSecurityUtils.test.d.ts +0 -6
- package/dist/src/ui/utils/urlSecurityUtils.test.js +0 -49
- package/dist/src/ui/utils/urlSecurityUtils.test.js.map +0 -1
- package/dist/src/utils/activityLogger.test.d.ts +0 -6
- package/dist/src/utils/activityLogger.test.js +0 -196
- package/dist/src/utils/activityLogger.test.js.map +0 -1
- package/dist/src/utils/agentSettings.test.d.ts +0 -6
- package/dist/src/utils/agentSettings.test.js +0 -111
- package/dist/src/utils/agentSettings.test.js.map +0 -1
- package/dist/src/utils/agentUtils.test.d.ts +0 -6
- package/dist/src/utils/agentUtils.test.js +0 -121
- package/dist/src/utils/agentUtils.test.js.map +0 -1
- package/dist/src/utils/cleanup.test.d.ts +0 -6
- package/dist/src/utils/cleanup.test.js +0 -256
- package/dist/src/utils/cleanup.test.js.map +0 -1
- package/dist/src/utils/commands.test.d.ts +0 -6
- package/dist/src/utils/commands.test.js +0 -194
- package/dist/src/utils/commands.test.js.map +0 -1
- package/dist/src/utils/commentJson.test.d.ts +0 -6
- package/dist/src/utils/commentJson.test.js +0 -308
- package/dist/src/utils/commentJson.test.js.map +0 -1
- package/dist/src/utils/deepMerge.test.d.ts +0 -6
- package/dist/src/utils/deepMerge.test.js +0 -211
- package/dist/src/utils/deepMerge.test.js.map +0 -1
- package/dist/src/utils/devtoolsService.test.d.ts +0 -6
- package/dist/src/utils/devtoolsService.test.js +0 -346
- package/dist/src/utils/devtoolsService.test.js.map +0 -1
- package/dist/src/utils/dialogScopeUtils.test.d.ts +0 -6
- package/dist/src/utils/dialogScopeUtils.test.js +0 -81
- package/dist/src/utils/dialogScopeUtils.test.js.map +0 -1
- package/dist/src/utils/envVarResolver.test.d.ts +0 -6
- package/dist/src/utils/envVarResolver.test.js +0 -238
- package/dist/src/utils/envVarResolver.test.js.map +0 -1
- package/dist/src/utils/errors.test.d.ts +0 -6
- package/dist/src/utils/errors.test.js +0 -420
- package/dist/src/utils/errors.test.js.map +0 -1
- package/dist/src/utils/events.test.d.ts +0 -6
- package/dist/src/utils/events.test.js +0 -24
- package/dist/src/utils/events.test.js.map +0 -1
- package/dist/src/utils/featureToggleUtils.test.d.ts +0 -6
- package/dist/src/utils/featureToggleUtils.test.js +0 -126
- package/dist/src/utils/featureToggleUtils.test.js.map +0 -1
- package/dist/src/utils/gitUtils.test.d.ts +0 -6
- package/dist/src/utils/gitUtils.test.js +0 -172
- package/dist/src/utils/gitUtils.test.js.map +0 -1
- package/dist/src/utils/handleAutoUpdate.test.d.ts +0 -6
- package/dist/src/utils/handleAutoUpdate.test.js +0 -399
- package/dist/src/utils/handleAutoUpdate.test.js.map +0 -1
- package/dist/src/utils/hookSettings.test.d.ts +0 -6
- package/dist/src/utils/hookSettings.test.js +0 -117
- package/dist/src/utils/hookSettings.test.js.map +0 -1
- package/dist/src/utils/hookUtils.test.d.ts +0 -6
- package/dist/src/utils/hookUtils.test.js +0 -113
- package/dist/src/utils/hookUtils.test.js.map +0 -1
- package/dist/src/utils/installationInfo.test.d.ts +0 -6
- package/dist/src/utils/installationInfo.test.js +0 -322
- package/dist/src/utils/installationInfo.test.js.map +0 -1
- package/dist/src/utils/jsonoutput.test.d.ts +0 -6
- package/dist/src/utils/jsonoutput.test.js +0 -74
- package/dist/src/utils/jsonoutput.test.js.map +0 -1
- package/dist/src/utils/logCleanup.test.d.ts +0 -6
- package/dist/src/utils/logCleanup.test.js +0 -87
- package/dist/src/utils/logCleanup.test.js.map +0 -1
- package/dist/src/utils/math.test.d.ts +0 -6
- package/dist/src/utils/math.test.js +0 -23
- package/dist/src/utils/math.test.js.map +0 -1
- package/dist/src/utils/persistentState.test.d.ts +0 -6
- package/dist/src/utils/persistentState.test.js +0 -68
- package/dist/src/utils/persistentState.test.js.map +0 -1
- package/dist/src/utils/processUtils.test.d.ts +0 -6
- package/dist/src/utils/processUtils.test.js +0 -150
- package/dist/src/utils/processUtils.test.js.map +0 -1
- package/dist/src/utils/readStdin.test.d.ts +0 -6
- package/dist/src/utils/readStdin.test.js +0 -149
- package/dist/src/utils/readStdin.test.js.map +0 -1
- package/dist/src/utils/readStdin_safety.test.d.ts +0 -6
- package/dist/src/utils/readStdin_safety.test.js +0 -68
- package/dist/src/utils/readStdin_safety.test.js.map +0 -1
- package/dist/src/utils/relaunch.test.d.ts +0 -6
- package/dist/src/utils/relaunch.test.js +0 -275
- package/dist/src/utils/relaunch.test.js.map +0 -1
- package/dist/src/utils/resolvePath.test.d.ts +0 -6
- package/dist/src/utils/resolvePath.test.js +0 -34
- package/dist/src/utils/resolvePath.test.js.map +0 -1
- package/dist/src/utils/sandbox.test.d.ts +0 -6
- package/dist/src/utils/sandbox.test.js +0 -725
- package/dist/src/utils/sandbox.test.js.map +0 -1
- package/dist/src/utils/sandboxUtils.test.d.ts +0 -6
- package/dist/src/utils/sandboxUtils.test.js +0 -190
- package/dist/src/utils/sandboxUtils.test.js.map +0 -1
- package/dist/src/utils/sessionCleanup.integration.test.d.ts +0 -6
- package/dist/src/utils/sessionCleanup.integration.test.js +0 -276
- package/dist/src/utils/sessionCleanup.integration.test.js.map +0 -1
- package/dist/src/utils/sessionCleanup.test.d.ts +0 -6
- package/dist/src/utils/sessionCleanup.test.js +0 -829
- package/dist/src/utils/sessionCleanup.test.js.map +0 -1
- package/dist/src/utils/sessionUtils.test.d.ts +0 -6
- package/dist/src/utils/sessionUtils.test.js +0 -815
- package/dist/src/utils/sessionUtils.test.js.map +0 -1
- package/dist/src/utils/sessions.test.d.ts +0 -6
- package/dist/src/utils/sessions.test.js +0 -580
- package/dist/src/utils/sessions.test.js.map +0 -1
- package/dist/src/utils/settingsUtils.test.d.ts +0 -6
- package/dist/src/utils/settingsUtils.test.js +0 -673
- package/dist/src/utils/settingsUtils.test.js.map +0 -1
- package/dist/src/utils/skillSettings.test.d.ts +0 -6
- package/dist/src/utils/skillSettings.test.js +0 -142
- package/dist/src/utils/skillSettings.test.js.map +0 -1
- package/dist/src/utils/skillUtils.test.d.ts +0 -6
- package/dist/src/utils/skillUtils.test.js +0 -248
- package/dist/src/utils/skillUtils.test.js.map +0 -1
- package/dist/src/utils/startupWarnings.test.d.ts +0 -6
- package/dist/src/utils/startupWarnings.test.js +0 -61
- package/dist/src/utils/startupWarnings.test.js.map +0 -1
- package/dist/src/utils/terminalNotifications.test.d.ts +0 -6
- package/dist/src/utils/terminalNotifications.test.js +0 -219
- package/dist/src/utils/terminalNotifications.test.js.map +0 -1
- package/dist/src/utils/terminalTheme.test.d.ts +0 -6
- package/dist/src/utils/terminalTheme.test.js +0 -91
- package/dist/src/utils/terminalTheme.test.js.map +0 -1
- package/dist/src/utils/tierUtils.test.d.ts +0 -6
- package/dist/src/utils/tierUtils.test.js +0 -25
- package/dist/src/utils/tierUtils.test.js.map +0 -1
- package/dist/src/utils/toolOutputCleanup.test.d.ts +0 -6
- package/dist/src/utils/toolOutputCleanup.test.js +0 -280
- package/dist/src/utils/toolOutputCleanup.test.js.map +0 -1
- package/dist/src/utils/updateEventEmitter.test.d.ts +0 -6
- package/dist/src/utils/updateEventEmitter.test.js +0 -18
- package/dist/src/utils/updateEventEmitter.test.js.map +0 -1
- package/dist/src/utils/userStartupWarnings.test.d.ts +0 -6
- package/dist/src/utils/userStartupWarnings.test.js +0 -225
- package/dist/src/utils/userStartupWarnings.test.js.map +0 -1
- package/dist/src/utils/windowTitle.test.d.ts +0 -6
- package/dist/src/utils/windowTitle.test.js +0 -216
- package/dist/src/utils/windowTitle.test.js.map +0 -1
- package/dist/src/utils/worktreeSetup.test.d.ts +0 -6
- package/dist/src/utils/worktreeSetup.test.js +0 -89
- package/dist/src/utils/worktreeSetup.test.js.map +0 -1
- package/dist/src/validateNonInterActiveAuth.test.d.ts +0 -6
- package/dist/src/validateNonInterActiveAuth.test.js +0 -319
- package/dist/src/validateNonInterActiveAuth.test.js.map +0 -1
|
@@ -1,2824 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* @license
|
|
4
|
-
* Copyright 2026 Google LLC
|
|
5
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
6
|
-
*/
|
|
7
|
-
import { describe, it, expect, vi, beforeEach, afterEach, } from 'vitest';
|
|
8
|
-
import { render, cleanup, persistentStateMock } from '../test-utils/render.js';
|
|
9
|
-
import { waitFor } from '../test-utils/async.js';
|
|
10
|
-
import { act, useContext } from 'react';
|
|
11
|
-
import { AppContainer } from './AppContainer.js';
|
|
12
|
-
import { SettingsContext } from './contexts/SettingsContext.js';
|
|
13
|
-
import {} from './hooks/useToolScheduler.js';
|
|
14
|
-
import { makeFakeConfig, CoreEvent, WarningPriority, AuthType, CoreToolCallStatus, } from '@google/gemini-cli-core';
|
|
15
|
-
// Mock coreEvents
|
|
16
|
-
const mockCoreEvents = vi.hoisted(() => ({
|
|
17
|
-
on: vi.fn(),
|
|
18
|
-
off: vi.fn(),
|
|
19
|
-
drainBacklogs: vi.fn(),
|
|
20
|
-
emit: vi.fn(),
|
|
21
|
-
}));
|
|
22
|
-
// Mock IdeClient
|
|
23
|
-
const mockIdeClient = vi.hoisted(() => ({
|
|
24
|
-
getInstance: vi.fn().mockReturnValue(new Promise(() => { })),
|
|
25
|
-
}));
|
|
26
|
-
// Mock stdout
|
|
27
|
-
const mocks = vi.hoisted(() => ({
|
|
28
|
-
mockStdout: { write: vi.fn() },
|
|
29
|
-
}));
|
|
30
|
-
const terminalNotificationsMocks = vi.hoisted(() => ({
|
|
31
|
-
notifyViaTerminal: vi.fn().mockResolvedValue(true),
|
|
32
|
-
isNotificationsEnabled: vi.fn(() => true),
|
|
33
|
-
getNotificationMethod: vi.fn(() => 'auto'),
|
|
34
|
-
buildRunEventNotificationContent: vi.fn((event) => ({
|
|
35
|
-
title: 'Mock Notification',
|
|
36
|
-
subtitle: 'Mock Subtitle',
|
|
37
|
-
body: JSON.stringify(event),
|
|
38
|
-
})),
|
|
39
|
-
}));
|
|
40
|
-
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
|
41
|
-
const actual = await importOriginal();
|
|
42
|
-
return {
|
|
43
|
-
...actual,
|
|
44
|
-
coreEvents: mockCoreEvents,
|
|
45
|
-
IdeClient: mockIdeClient,
|
|
46
|
-
writeToStdout: vi.fn((...args) => process.stdout.write(...args)),
|
|
47
|
-
writeToStderr: vi.fn((...args) => process.stderr.write(...args)),
|
|
48
|
-
patchStdio: vi.fn(() => () => { }),
|
|
49
|
-
createWorkingStdio: vi.fn(() => ({
|
|
50
|
-
stdout: process.stdout,
|
|
51
|
-
stderr: process.stderr,
|
|
52
|
-
})),
|
|
53
|
-
enableMouseEvents: vi.fn(),
|
|
54
|
-
disableMouseEvents: vi.fn(),
|
|
55
|
-
FileDiscoveryService: vi.fn().mockImplementation(() => ({
|
|
56
|
-
initialize: vi.fn(),
|
|
57
|
-
})),
|
|
58
|
-
startupProfiler: {
|
|
59
|
-
flush: vi.fn(),
|
|
60
|
-
start: vi.fn(),
|
|
61
|
-
end: vi.fn(),
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
});
|
|
65
|
-
import ansiEscapes from 'ansi-escapes';
|
|
66
|
-
import {} from '../config/settings.js';
|
|
67
|
-
import { createMockSettings } from '../test-utils/settings.js';
|
|
68
|
-
import { useQuotaAndFallback } from './hooks/useQuotaAndFallback.js';
|
|
69
|
-
import { StreamingState, MessageType } from './types.js';
|
|
70
|
-
import { UIStateContext } from './contexts/UIStateContext.js';
|
|
71
|
-
import { UIActionsContext, } from './contexts/UIActionsContext.js';
|
|
72
|
-
import { KeypressProvider } from './contexts/KeypressContext.js';
|
|
73
|
-
import { OverflowProvider } from './contexts/OverflowContext.js';
|
|
74
|
-
import { useOverflowActions, } from './contexts/OverflowContext.js';
|
|
75
|
-
// Mock useStdout to capture terminal title writes
|
|
76
|
-
vi.mock('ink', async (importOriginal) => {
|
|
77
|
-
const actual = await importOriginal();
|
|
78
|
-
return {
|
|
79
|
-
...actual,
|
|
80
|
-
useStdout: () => ({ stdout: mocks.mockStdout }),
|
|
81
|
-
measureElement: vi.fn(),
|
|
82
|
-
};
|
|
83
|
-
});
|
|
84
|
-
import { InputContext } from './contexts/InputContext.js';
|
|
85
|
-
import { QuotaContext } from './contexts/QuotaContext.js';
|
|
86
|
-
// Helper component will read the context values provided by AppContainer
|
|
87
|
-
// so we can assert against them in our tests.
|
|
88
|
-
let capturedUIState;
|
|
89
|
-
let capturedInputState;
|
|
90
|
-
let capturedQuotaState;
|
|
91
|
-
let capturedUIActions;
|
|
92
|
-
let capturedOverflowActions;
|
|
93
|
-
function TestContextConsumer() {
|
|
94
|
-
capturedUIState = useContext(UIStateContext);
|
|
95
|
-
capturedInputState = useContext(InputContext);
|
|
96
|
-
capturedQuotaState = useContext(QuotaContext);
|
|
97
|
-
capturedUIActions = useContext(UIActionsContext);
|
|
98
|
-
capturedOverflowActions = useOverflowActions();
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
vi.mock('./App.js', () => ({
|
|
102
|
-
App: TestContextConsumer,
|
|
103
|
-
}));
|
|
104
|
-
vi.mock('./hooks/useQuotaAndFallback.js');
|
|
105
|
-
vi.mock('./hooks/useHistoryManager.js');
|
|
106
|
-
vi.mock('./hooks/useThemeCommand.js');
|
|
107
|
-
vi.mock('./auth/useAuth.js');
|
|
108
|
-
vi.mock('../config/auth.js', () => ({
|
|
109
|
-
validateAuthMethod: vi.fn().mockResolvedValue(null),
|
|
110
|
-
}));
|
|
111
|
-
vi.mock('./hooks/useEditorSettings.js');
|
|
112
|
-
vi.mock('./hooks/useSettingsCommand.js');
|
|
113
|
-
vi.mock('./hooks/useModelCommand.js');
|
|
114
|
-
vi.mock('./hooks/slashCommandProcessor.js');
|
|
115
|
-
vi.mock('./hooks/useConsoleMessages.js');
|
|
116
|
-
vi.mock('./hooks/useTerminalSize.js', () => ({
|
|
117
|
-
useTerminalSize: vi.fn(() => ({ columns: 80, rows: 24 })),
|
|
118
|
-
}));
|
|
119
|
-
vi.mock('./hooks/useGeminiStream.js');
|
|
120
|
-
vi.mock('./hooks/vim.js');
|
|
121
|
-
vi.mock('./hooks/useFocus.js');
|
|
122
|
-
vi.mock('./hooks/useBracketedPaste.js');
|
|
123
|
-
vi.mock('./hooks/useLoadingIndicator.js');
|
|
124
|
-
vi.mock('./hooks/useSuspend.js');
|
|
125
|
-
vi.mock('./hooks/useFolderTrust.js');
|
|
126
|
-
vi.mock('./hooks/useIdeTrustListener.js');
|
|
127
|
-
vi.mock('./hooks/useMessageQueue.js');
|
|
128
|
-
vi.mock('./hooks/useApprovalModeIndicator.js');
|
|
129
|
-
vi.mock('./hooks/useGitBranchName.js');
|
|
130
|
-
vi.mock('./hooks/useExtensionUpdates.js');
|
|
131
|
-
vi.mock('./contexts/VimModeContext.js');
|
|
132
|
-
vi.mock('./contexts/SessionContext.js');
|
|
133
|
-
vi.mock('./components/shared/text-buffer.js');
|
|
134
|
-
vi.mock('./hooks/useLogger.js');
|
|
135
|
-
vi.mock('./hooks/useInputHistoryStore.js');
|
|
136
|
-
vi.mock('./hooks/atCommandProcessor.js');
|
|
137
|
-
vi.mock('./hooks/useHookDisplayState.js');
|
|
138
|
-
vi.mock('./hooks/useBanner.js', () => ({
|
|
139
|
-
useBanner: vi.fn((bannerData) => ({
|
|
140
|
-
bannerText: (bannerData.warningText ||
|
|
141
|
-
bannerData.defaultText ||
|
|
142
|
-
'').replace(/\\n/g, '\n'),
|
|
143
|
-
})),
|
|
144
|
-
}));
|
|
145
|
-
vi.mock('./hooks/useShellInactivityStatus.js', () => ({
|
|
146
|
-
useShellInactivityStatus: vi.fn(() => ({
|
|
147
|
-
shouldShowFocusHint: false,
|
|
148
|
-
inactivityStatus: 'none',
|
|
149
|
-
})),
|
|
150
|
-
}));
|
|
151
|
-
vi.mock('../utils/terminalNotifications.js', () => ({
|
|
152
|
-
notifyViaTerminal: terminalNotificationsMocks.notifyViaTerminal,
|
|
153
|
-
isNotificationsEnabled: terminalNotificationsMocks.isNotificationsEnabled,
|
|
154
|
-
getNotificationMethod: terminalNotificationsMocks.getNotificationMethod,
|
|
155
|
-
buildRunEventNotificationContent: terminalNotificationsMocks.buildRunEventNotificationContent,
|
|
156
|
-
}));
|
|
157
|
-
vi.mock('./hooks/useTerminalTheme.js', () => ({
|
|
158
|
-
useTerminalTheme: vi.fn(),
|
|
159
|
-
}));
|
|
160
|
-
import { useHookDisplayState } from './hooks/useHookDisplayState.js';
|
|
161
|
-
import { useTerminalTheme } from './hooks/useTerminalTheme.js';
|
|
162
|
-
import { useShellInactivityStatus } from './hooks/useShellInactivityStatus.js';
|
|
163
|
-
import { useFocus } from './hooks/useFocus.js';
|
|
164
|
-
// Mock external utilities
|
|
165
|
-
vi.mock('../utils/events.js');
|
|
166
|
-
vi.mock('../utils/handleAutoUpdate.js');
|
|
167
|
-
vi.mock('./utils/ConsolePatcher.js');
|
|
168
|
-
vi.mock('../utils/cleanup.js');
|
|
169
|
-
import { useHistory } from './hooks/useHistoryManager.js';
|
|
170
|
-
import { useThemeCommand } from './hooks/useThemeCommand.js';
|
|
171
|
-
import { useAuthCommand } from './auth/useAuth.js';
|
|
172
|
-
import { validateAuthMethod } from '../config/auth.js';
|
|
173
|
-
import { useEditorSettings } from './hooks/useEditorSettings.js';
|
|
174
|
-
import { useSettingsCommand } from './hooks/useSettingsCommand.js';
|
|
175
|
-
import { useModelCommand } from './hooks/useModelCommand.js';
|
|
176
|
-
import { useSlashCommandProcessor } from './hooks/slashCommandProcessor.js';
|
|
177
|
-
import { useErrorCount } from './hooks/useConsoleMessages.js';
|
|
178
|
-
import { useGeminiStream } from './hooks/useGeminiStream.js';
|
|
179
|
-
import { useVim } from './hooks/vim.js';
|
|
180
|
-
import { useFolderTrust } from './hooks/useFolderTrust.js';
|
|
181
|
-
import { useIdeTrustListener } from './hooks/useIdeTrustListener.js';
|
|
182
|
-
import { useMessageQueue } from './hooks/useMessageQueue.js';
|
|
183
|
-
import { useApprovalModeIndicator } from './hooks/useApprovalModeIndicator.js';
|
|
184
|
-
import { useGitBranchName } from './hooks/useGitBranchName.js';
|
|
185
|
-
import { useConfirmUpdateRequests, useExtensionUpdates, } from './hooks/useExtensionUpdates.js';
|
|
186
|
-
import { useVimMode } from './contexts/VimModeContext.js';
|
|
187
|
-
import { useSessionStats } from './contexts/SessionContext.js';
|
|
188
|
-
import { useTextBuffer } from './components/shared/text-buffer.js';
|
|
189
|
-
import { useLogger } from './hooks/useLogger.js';
|
|
190
|
-
import { useLoadingIndicator } from './hooks/useLoadingIndicator.js';
|
|
191
|
-
import { useInputHistoryStore } from './hooks/useInputHistoryStore.js';
|
|
192
|
-
import { useKeypress } from './hooks/useKeypress.js';
|
|
193
|
-
import * as useKeypressModule from './hooks/useKeypress.js';
|
|
194
|
-
import { useSuspend } from './hooks/useSuspend.js';
|
|
195
|
-
import { writeToStdout, enableMouseEvents, disableMouseEvents, } from '@google/gemini-cli-core';
|
|
196
|
-
import {} from '../config/extension-manager.js';
|
|
197
|
-
import { WARNING_PROMPT_DURATION_MS, EXPAND_HINT_DURATION_MS, } from './constants.js';
|
|
198
|
-
describe('AppContainer State Management', () => {
|
|
199
|
-
let mockConfig;
|
|
200
|
-
let mockSettings;
|
|
201
|
-
let mockInitResult;
|
|
202
|
-
let mockExtensionManager;
|
|
203
|
-
// Helper to generate the AppContainer JSX for render and rerender
|
|
204
|
-
const getAppContainer = ({ settings = mockSettings, config = mockConfig, version = '1.0.0', initResult = mockInitResult, startupWarnings, resumedSessionData, } = {}) => (_jsx(SettingsContext.Provider, { value: settings, children: _jsx(KeypressProvider, { config: config, children: _jsx(OverflowProvider, { children: _jsx(AppContainer, { config: config, version: version, initializationResult: initResult, startupWarnings: startupWarnings, resumedSessionData: resumedSessionData }) }) }) }));
|
|
205
|
-
// Helper to render the AppContainer
|
|
206
|
-
const renderAppContainer = async (props) => render(getAppContainer(props));
|
|
207
|
-
// Create typed mocks for all hooks
|
|
208
|
-
const mockedUseQuotaAndFallback = useQuotaAndFallback;
|
|
209
|
-
const mockedUseHistory = useHistory;
|
|
210
|
-
const mockedUseThemeCommand = useThemeCommand;
|
|
211
|
-
const mockedUseAuthCommand = useAuthCommand;
|
|
212
|
-
const mockedUseEditorSettings = useEditorSettings;
|
|
213
|
-
const mockedUseSettingsCommand = useSettingsCommand;
|
|
214
|
-
const mockedUseModelCommand = useModelCommand;
|
|
215
|
-
const mockedUseSlashCommandProcessor = useSlashCommandProcessor;
|
|
216
|
-
const mockedUseConsoleMessages = useErrorCount;
|
|
217
|
-
const mockedUseGeminiStream = useGeminiStream;
|
|
218
|
-
const mockedUseVim = useVim;
|
|
219
|
-
const mockedUseFolderTrust = useFolderTrust;
|
|
220
|
-
const mockedUseIdeTrustListener = useIdeTrustListener;
|
|
221
|
-
const mockedUseMessageQueue = useMessageQueue;
|
|
222
|
-
const mockedUseApprovalModeIndicator = useApprovalModeIndicator;
|
|
223
|
-
const mockedUseGitBranchName = useGitBranchName;
|
|
224
|
-
const mockedUseConfirmUpdateRequests = useConfirmUpdateRequests;
|
|
225
|
-
const mockedUseExtensionUpdates = useExtensionUpdates;
|
|
226
|
-
const mockedUseVimMode = useVimMode;
|
|
227
|
-
const mockedUseSessionStats = useSessionStats;
|
|
228
|
-
const mockedUseTextBuffer = useTextBuffer;
|
|
229
|
-
const mockedUseLogger = useLogger;
|
|
230
|
-
const mockedUseLoadingIndicator = useLoadingIndicator;
|
|
231
|
-
const mockedUseSuspend = useSuspend;
|
|
232
|
-
const mockedUseInputHistoryStore = useInputHistoryStore;
|
|
233
|
-
const mockedUseHookDisplayState = useHookDisplayState;
|
|
234
|
-
const mockedUseTerminalTheme = useTerminalTheme;
|
|
235
|
-
const mockedUseShellInactivityStatus = useShellInactivityStatus;
|
|
236
|
-
const mockedUseFocusState = useFocus;
|
|
237
|
-
const DEFAULT_GEMINI_STREAM_MOCK = {
|
|
238
|
-
streamingState: 'idle',
|
|
239
|
-
submitQuery: vi.fn(),
|
|
240
|
-
initError: null,
|
|
241
|
-
pendingHistoryItems: [],
|
|
242
|
-
thought: null,
|
|
243
|
-
cancelOngoingRequest: vi.fn(),
|
|
244
|
-
handleApprovalModeChange: vi.fn(),
|
|
245
|
-
activePtyId: null,
|
|
246
|
-
loopDetectionConfirmationRequest: null,
|
|
247
|
-
backgroundTaskCount: 0,
|
|
248
|
-
isBackgroundTaskVisible: false,
|
|
249
|
-
toggleBackgroundTasks: vi.fn(),
|
|
250
|
-
backgroundCurrentExecution: vi.fn(),
|
|
251
|
-
backgroundTasks: new Map(),
|
|
252
|
-
registerBackgroundTask: vi.fn(),
|
|
253
|
-
dismissBackgroundTask: vi.fn(),
|
|
254
|
-
};
|
|
255
|
-
beforeEach(() => {
|
|
256
|
-
persistentStateMock.reset();
|
|
257
|
-
vi.clearAllMocks();
|
|
258
|
-
mockIdeClient.getInstance.mockReturnValue(new Promise(() => { }));
|
|
259
|
-
// Initialize mock stdout for terminal title tests
|
|
260
|
-
mocks.mockStdout.write.mockClear();
|
|
261
|
-
disableMouseEvents.mockClear();
|
|
262
|
-
capturedUIState = null;
|
|
263
|
-
// **Provide a default return value for EVERY mocked hook.**
|
|
264
|
-
mockedUseQuotaAndFallback.mockReturnValue({
|
|
265
|
-
proQuotaRequest: null,
|
|
266
|
-
handleProQuotaChoice: vi.fn(),
|
|
267
|
-
});
|
|
268
|
-
mockedUseHistory.mockReturnValue({
|
|
269
|
-
history: [],
|
|
270
|
-
addItem: vi.fn(),
|
|
271
|
-
updateItem: vi.fn(),
|
|
272
|
-
clearItems: vi.fn(),
|
|
273
|
-
loadHistory: vi.fn(),
|
|
274
|
-
});
|
|
275
|
-
mockedUseThemeCommand.mockReturnValue({
|
|
276
|
-
isThemeDialogOpen: false,
|
|
277
|
-
openThemeDialog: vi.fn(),
|
|
278
|
-
handleThemeSelect: vi.fn(),
|
|
279
|
-
handleThemeHighlight: vi.fn(),
|
|
280
|
-
});
|
|
281
|
-
mockedUseAuthCommand.mockReturnValue({
|
|
282
|
-
authState: 'authenticated',
|
|
283
|
-
setAuthState: vi.fn(),
|
|
284
|
-
authError: null,
|
|
285
|
-
onAuthError: vi.fn(),
|
|
286
|
-
});
|
|
287
|
-
mockedUseEditorSettings.mockReturnValue({
|
|
288
|
-
isEditorDialogOpen: false,
|
|
289
|
-
openEditorDialog: vi.fn(),
|
|
290
|
-
handleEditorSelect: vi.fn(),
|
|
291
|
-
exitEditorDialog: vi.fn(),
|
|
292
|
-
});
|
|
293
|
-
mockedUseSettingsCommand.mockReturnValue({
|
|
294
|
-
isSettingsDialogOpen: false,
|
|
295
|
-
openSettingsDialog: vi.fn(),
|
|
296
|
-
closeSettingsDialog: vi.fn(),
|
|
297
|
-
});
|
|
298
|
-
mockedUseModelCommand.mockReturnValue({
|
|
299
|
-
isModelDialogOpen: false,
|
|
300
|
-
openModelDialog: vi.fn(),
|
|
301
|
-
closeModelDialog: vi.fn(),
|
|
302
|
-
});
|
|
303
|
-
mockedUseSlashCommandProcessor.mockReturnValue({
|
|
304
|
-
handleSlashCommand: vi.fn(),
|
|
305
|
-
slashCommands: [],
|
|
306
|
-
pendingHistoryItems: [],
|
|
307
|
-
commandContext: {},
|
|
308
|
-
shellConfirmationRequest: null,
|
|
309
|
-
confirmationRequest: null,
|
|
310
|
-
});
|
|
311
|
-
mockedUseConsoleMessages.mockReturnValue({
|
|
312
|
-
errorCount: 0,
|
|
313
|
-
handleNewMessage: vi.fn(),
|
|
314
|
-
clearErrorCount: vi.fn(),
|
|
315
|
-
});
|
|
316
|
-
mockedUseGeminiStream.mockReturnValue(DEFAULT_GEMINI_STREAM_MOCK);
|
|
317
|
-
mockedUseVim.mockReturnValue({ handleInput: vi.fn() });
|
|
318
|
-
mockedUseFolderTrust.mockReturnValue({
|
|
319
|
-
isFolderTrustDialogOpen: false,
|
|
320
|
-
handleFolderTrustSelect: vi.fn(),
|
|
321
|
-
isRestarting: false,
|
|
322
|
-
});
|
|
323
|
-
mockedUseIdeTrustListener.mockReturnValue({
|
|
324
|
-
needsRestart: false,
|
|
325
|
-
restartReason: 'NONE',
|
|
326
|
-
});
|
|
327
|
-
mockedUseMessageQueue.mockReturnValue({
|
|
328
|
-
messageQueue: [],
|
|
329
|
-
addMessage: vi.fn(),
|
|
330
|
-
clearQueue: vi.fn(),
|
|
331
|
-
getQueuedMessagesText: vi.fn().mockReturnValue(''),
|
|
332
|
-
});
|
|
333
|
-
mockedUseApprovalModeIndicator.mockReturnValue(false);
|
|
334
|
-
mockedUseGitBranchName.mockReturnValue('main');
|
|
335
|
-
mockedUseVimMode.mockReturnValue({
|
|
336
|
-
isVimEnabled: false,
|
|
337
|
-
toggleVimEnabled: vi.fn(),
|
|
338
|
-
});
|
|
339
|
-
mockedUseSessionStats.mockReturnValue({ stats: {} });
|
|
340
|
-
mockedUseTextBuffer.mockReturnValue({
|
|
341
|
-
text: '',
|
|
342
|
-
setText: vi.fn(),
|
|
343
|
-
lines: [''],
|
|
344
|
-
cursor: [0, 0],
|
|
345
|
-
handleInput: vi.fn().mockReturnValue(false),
|
|
346
|
-
});
|
|
347
|
-
mockedUseLogger.mockReturnValue({
|
|
348
|
-
getPreviousUserMessages: vi.fn().mockResolvedValue([]),
|
|
349
|
-
});
|
|
350
|
-
mockedUseInputHistoryStore.mockReturnValue({
|
|
351
|
-
inputHistory: [],
|
|
352
|
-
addInput: vi.fn(),
|
|
353
|
-
initializeFromLogger: vi.fn(),
|
|
354
|
-
});
|
|
355
|
-
mockedUseLoadingIndicator.mockReturnValue({
|
|
356
|
-
elapsedTime: '0.0s',
|
|
357
|
-
currentLoadingPhrase: '',
|
|
358
|
-
});
|
|
359
|
-
mockedUseSuspend.mockReturnValue({
|
|
360
|
-
handleSuspend: vi.fn(),
|
|
361
|
-
});
|
|
362
|
-
mockedUseHookDisplayState.mockReturnValue([]);
|
|
363
|
-
mockedUseTerminalTheme.mockReturnValue(undefined);
|
|
364
|
-
mockedUseShellInactivityStatus.mockReturnValue({
|
|
365
|
-
shouldShowFocusHint: false,
|
|
366
|
-
inactivityStatus: 'none',
|
|
367
|
-
});
|
|
368
|
-
mockedUseFocusState.mockReturnValue({
|
|
369
|
-
isFocused: true,
|
|
370
|
-
hasReceivedFocusEvent: true,
|
|
371
|
-
});
|
|
372
|
-
mockedUseConfirmUpdateRequests.mockReturnValue({
|
|
373
|
-
addConfirmUpdateExtensionRequest: vi.fn(),
|
|
374
|
-
confirmUpdateExtensionRequests: [],
|
|
375
|
-
});
|
|
376
|
-
mockedUseExtensionUpdates.mockReturnValue({
|
|
377
|
-
extensionsUpdateState: new Map(),
|
|
378
|
-
extensionsUpdateStateInternal: new Map(),
|
|
379
|
-
dispatchExtensionStateUpdate: vi.fn(),
|
|
380
|
-
});
|
|
381
|
-
// Mock Config
|
|
382
|
-
mockConfig = makeFakeConfig();
|
|
383
|
-
vi.spyOn(mockConfig, 'getUseRenderProcess').mockReturnValue(false);
|
|
384
|
-
// Mock config's getTargetDir to return consistent workspace directory
|
|
385
|
-
vi.spyOn(mockConfig, 'getTargetDir').mockReturnValue('/test/workspace');
|
|
386
|
-
vi.spyOn(mockConfig, 'initialize').mockResolvedValue(undefined);
|
|
387
|
-
vi.spyOn(mockConfig, 'getDebugMode').mockReturnValue(false);
|
|
388
|
-
mockExtensionManager = {
|
|
389
|
-
getExtensions: vi.fn().mockReturnValue([]),
|
|
390
|
-
setRequestConsent: vi.fn(),
|
|
391
|
-
setRequestSetting: vi.fn(),
|
|
392
|
-
start: vi.fn(),
|
|
393
|
-
};
|
|
394
|
-
vi.spyOn(mockConfig, 'getExtensionLoader').mockReturnValue(mockExtensionManager);
|
|
395
|
-
// Mock LoadedSettings
|
|
396
|
-
mockSettings = createMockSettings({
|
|
397
|
-
hideBanner: false,
|
|
398
|
-
hideTips: false,
|
|
399
|
-
hideFooter: false,
|
|
400
|
-
showMemoryUsage: false,
|
|
401
|
-
theme: 'default',
|
|
402
|
-
ui: {
|
|
403
|
-
showStatusInTitle: false,
|
|
404
|
-
hideWindowTitle: false,
|
|
405
|
-
useAlternateBuffer: false,
|
|
406
|
-
},
|
|
407
|
-
});
|
|
408
|
-
// Mock InitializationResult
|
|
409
|
-
mockInitResult = {
|
|
410
|
-
themeError: null,
|
|
411
|
-
authError: null,
|
|
412
|
-
shouldOpenAuthDialog: false,
|
|
413
|
-
geminiMdFileCount: 0,
|
|
414
|
-
};
|
|
415
|
-
});
|
|
416
|
-
afterEach(() => {
|
|
417
|
-
cleanup();
|
|
418
|
-
vi.restoreAllMocks();
|
|
419
|
-
});
|
|
420
|
-
describe('Basic Rendering', () => {
|
|
421
|
-
it('renders without crashing with minimal props', async () => {
|
|
422
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
423
|
-
expect(capturedUIState).toBeTruthy();
|
|
424
|
-
unmount();
|
|
425
|
-
});
|
|
426
|
-
it('renders with startup warnings', async () => {
|
|
427
|
-
const startupWarnings = [
|
|
428
|
-
{
|
|
429
|
-
id: 'w1',
|
|
430
|
-
message: 'Warning 1',
|
|
431
|
-
priority: WarningPriority.High,
|
|
432
|
-
},
|
|
433
|
-
{
|
|
434
|
-
id: 'w2',
|
|
435
|
-
message: 'Warning 2',
|
|
436
|
-
priority: WarningPriority.High,
|
|
437
|
-
},
|
|
438
|
-
];
|
|
439
|
-
const { unmount } = await act(async () => renderAppContainer({ startupWarnings }));
|
|
440
|
-
expect(capturedUIState).toBeTruthy();
|
|
441
|
-
unmount();
|
|
442
|
-
});
|
|
443
|
-
it('shows full UI details by default', async () => {
|
|
444
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
445
|
-
expect(capturedUIState.cleanUiDetailsVisible).toBe(true);
|
|
446
|
-
unmount();
|
|
447
|
-
});
|
|
448
|
-
it('starts in minimal UI mode when Focus UI preference is persisted', async () => {
|
|
449
|
-
persistentStateMock.get.mockReturnValueOnce(true);
|
|
450
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
451
|
-
settings: mockSettings,
|
|
452
|
-
}));
|
|
453
|
-
expect(capturedUIState.cleanUiDetailsVisible).toBe(false);
|
|
454
|
-
expect(persistentStateMock.get).toHaveBeenCalledWith('focusUiEnabled');
|
|
455
|
-
unmount();
|
|
456
|
-
});
|
|
457
|
-
});
|
|
458
|
-
describe('State Initialization', () => {
|
|
459
|
-
it('calls validateAuthMethod and onAuthError if validation fails', async () => {
|
|
460
|
-
const mockOnAuthError = vi.fn();
|
|
461
|
-
mockedUseAuthCommand.mockReturnValue({
|
|
462
|
-
authState: 'authenticated',
|
|
463
|
-
setAuthState: vi.fn(),
|
|
464
|
-
authError: null,
|
|
465
|
-
onAuthError: mockOnAuthError,
|
|
466
|
-
});
|
|
467
|
-
vi.mocked(validateAuthMethod).mockResolvedValueOnce('Validation Failed');
|
|
468
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
469
|
-
settings: createMockSettings({
|
|
470
|
-
merged: {
|
|
471
|
-
security: {
|
|
472
|
-
auth: { selectedType: 'oauth-personal', useExternal: false },
|
|
473
|
-
},
|
|
474
|
-
},
|
|
475
|
-
}),
|
|
476
|
-
}));
|
|
477
|
-
await waitFor(() => {
|
|
478
|
-
expect(validateAuthMethod).toHaveBeenCalledWith('oauth-personal');
|
|
479
|
-
expect(mockOnAuthError).toHaveBeenCalledWith('Validation Failed');
|
|
480
|
-
});
|
|
481
|
-
unmount();
|
|
482
|
-
});
|
|
483
|
-
it('sends a macOS notification when confirmation is pending and terminal is unfocused', async () => {
|
|
484
|
-
mockedUseFocusState.mockReturnValue({
|
|
485
|
-
isFocused: false,
|
|
486
|
-
hasReceivedFocusEvent: true,
|
|
487
|
-
});
|
|
488
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
489
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
490
|
-
pendingHistoryItems: [
|
|
491
|
-
{
|
|
492
|
-
type: 'tool_group',
|
|
493
|
-
tools: [
|
|
494
|
-
{
|
|
495
|
-
callId: 'call-1',
|
|
496
|
-
name: 'run_shell_command',
|
|
497
|
-
description: 'Run command',
|
|
498
|
-
resultDisplay: undefined,
|
|
499
|
-
status: CoreToolCallStatus.AwaitingApproval,
|
|
500
|
-
confirmationDetails: {
|
|
501
|
-
type: 'exec',
|
|
502
|
-
title: 'Run shell command',
|
|
503
|
-
command: 'ls',
|
|
504
|
-
rootCommand: 'ls',
|
|
505
|
-
rootCommands: ['ls'],
|
|
506
|
-
},
|
|
507
|
-
},
|
|
508
|
-
],
|
|
509
|
-
},
|
|
510
|
-
],
|
|
511
|
-
});
|
|
512
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
513
|
-
expect(terminalNotificationsMocks.notifyViaTerminal).toHaveBeenCalled();
|
|
514
|
-
expect(terminalNotificationsMocks.buildRunEventNotificationContent).toHaveBeenCalledWith(expect.objectContaining({
|
|
515
|
-
type: 'attention',
|
|
516
|
-
}));
|
|
517
|
-
unmount();
|
|
518
|
-
});
|
|
519
|
-
it('does not send attention notification when terminal is focused', async () => {
|
|
520
|
-
mockedUseFocusState.mockReturnValue({
|
|
521
|
-
isFocused: true,
|
|
522
|
-
hasReceivedFocusEvent: true,
|
|
523
|
-
});
|
|
524
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
525
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
526
|
-
pendingHistoryItems: [
|
|
527
|
-
{
|
|
528
|
-
type: 'tool_group',
|
|
529
|
-
tools: [
|
|
530
|
-
{
|
|
531
|
-
callId: 'call-2',
|
|
532
|
-
name: 'run_shell_command',
|
|
533
|
-
description: 'Run command',
|
|
534
|
-
resultDisplay: undefined,
|
|
535
|
-
status: CoreToolCallStatus.AwaitingApproval,
|
|
536
|
-
confirmationDetails: {
|
|
537
|
-
type: 'exec',
|
|
538
|
-
title: 'Run shell command',
|
|
539
|
-
command: 'ls',
|
|
540
|
-
rootCommand: 'ls',
|
|
541
|
-
rootCommands: ['ls'],
|
|
542
|
-
},
|
|
543
|
-
},
|
|
544
|
-
],
|
|
545
|
-
},
|
|
546
|
-
],
|
|
547
|
-
});
|
|
548
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
549
|
-
expect(terminalNotificationsMocks.notifyViaTerminal).not.toHaveBeenCalled();
|
|
550
|
-
unmount();
|
|
551
|
-
});
|
|
552
|
-
it('sends attention notification when focus reporting is unavailable', async () => {
|
|
553
|
-
mockedUseFocusState.mockReturnValue({
|
|
554
|
-
isFocused: true,
|
|
555
|
-
hasReceivedFocusEvent: false,
|
|
556
|
-
});
|
|
557
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
558
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
559
|
-
pendingHistoryItems: [
|
|
560
|
-
{
|
|
561
|
-
type: 'tool_group',
|
|
562
|
-
tools: [
|
|
563
|
-
{
|
|
564
|
-
callId: 'call-focus-unknown',
|
|
565
|
-
name: 'run_shell_command',
|
|
566
|
-
description: 'Run command',
|
|
567
|
-
resultDisplay: undefined,
|
|
568
|
-
status: CoreToolCallStatus.AwaitingApproval,
|
|
569
|
-
confirmationDetails: {
|
|
570
|
-
type: 'exec',
|
|
571
|
-
title: 'Run shell command',
|
|
572
|
-
command: 'ls',
|
|
573
|
-
rootCommand: 'ls',
|
|
574
|
-
rootCommands: ['ls'],
|
|
575
|
-
},
|
|
576
|
-
},
|
|
577
|
-
],
|
|
578
|
-
},
|
|
579
|
-
],
|
|
580
|
-
});
|
|
581
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
582
|
-
expect(terminalNotificationsMocks.notifyViaTerminal).toHaveBeenCalled();
|
|
583
|
-
unmount();
|
|
584
|
-
});
|
|
585
|
-
it('sends a macOS notification when a response completes while unfocused', async () => {
|
|
586
|
-
mockedUseFocusState.mockReturnValue({
|
|
587
|
-
isFocused: false,
|
|
588
|
-
hasReceivedFocusEvent: true,
|
|
589
|
-
});
|
|
590
|
-
let currentStreamingState = 'responding';
|
|
591
|
-
mockedUseGeminiStream.mockImplementation(() => ({
|
|
592
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
593
|
-
streamingState: currentStreamingState,
|
|
594
|
-
}));
|
|
595
|
-
const { unmount, rerender } = await act(async () => renderAppContainer());
|
|
596
|
-
currentStreamingState = 'idle';
|
|
597
|
-
await act(async () => {
|
|
598
|
-
rerender(getAppContainer());
|
|
599
|
-
});
|
|
600
|
-
expect(terminalNotificationsMocks.buildRunEventNotificationContent).toHaveBeenCalledWith(expect.objectContaining({
|
|
601
|
-
type: 'session_complete',
|
|
602
|
-
detail: 'Gemini CLI finished responding.',
|
|
603
|
-
}));
|
|
604
|
-
expect(terminalNotificationsMocks.notifyViaTerminal).toHaveBeenCalled();
|
|
605
|
-
unmount();
|
|
606
|
-
});
|
|
607
|
-
it('sends completion notification when focus reporting is unavailable', async () => {
|
|
608
|
-
mockedUseFocusState.mockReturnValue({
|
|
609
|
-
isFocused: true,
|
|
610
|
-
hasReceivedFocusEvent: false,
|
|
611
|
-
});
|
|
612
|
-
let currentStreamingState = 'responding';
|
|
613
|
-
mockedUseGeminiStream.mockImplementation(() => ({
|
|
614
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
615
|
-
streamingState: currentStreamingState,
|
|
616
|
-
}));
|
|
617
|
-
const { unmount, rerender } = await act(async () => renderAppContainer());
|
|
618
|
-
currentStreamingState = 'idle';
|
|
619
|
-
await act(async () => {
|
|
620
|
-
rerender(getAppContainer());
|
|
621
|
-
});
|
|
622
|
-
expect(terminalNotificationsMocks.buildRunEventNotificationContent).toHaveBeenCalledWith(expect.objectContaining({
|
|
623
|
-
type: 'session_complete',
|
|
624
|
-
detail: 'Gemini CLI finished responding.',
|
|
625
|
-
}));
|
|
626
|
-
unmount();
|
|
627
|
-
});
|
|
628
|
-
it('does not send completion notification when another action-required dialog is pending', async () => {
|
|
629
|
-
mockedUseFocusState.mockReturnValue({
|
|
630
|
-
isFocused: false,
|
|
631
|
-
hasReceivedFocusEvent: true,
|
|
632
|
-
});
|
|
633
|
-
mockedUseQuotaAndFallback.mockReturnValue({
|
|
634
|
-
proQuotaRequest: { kind: 'upgrade' },
|
|
635
|
-
handleProQuotaChoice: vi.fn(),
|
|
636
|
-
});
|
|
637
|
-
let currentStreamingState = 'responding';
|
|
638
|
-
mockedUseGeminiStream.mockImplementation(() => ({
|
|
639
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
640
|
-
streamingState: currentStreamingState,
|
|
641
|
-
}));
|
|
642
|
-
const { unmount, rerender } = await act(async () => renderAppContainer());
|
|
643
|
-
currentStreamingState = 'idle';
|
|
644
|
-
await act(async () => {
|
|
645
|
-
rerender(getAppContainer());
|
|
646
|
-
});
|
|
647
|
-
expect(terminalNotificationsMocks.notifyViaTerminal).not.toHaveBeenCalled();
|
|
648
|
-
unmount();
|
|
649
|
-
});
|
|
650
|
-
it('can send repeated attention notifications for the same key after pending state clears', async () => {
|
|
651
|
-
mockedUseFocusState.mockReturnValue({
|
|
652
|
-
isFocused: false,
|
|
653
|
-
hasReceivedFocusEvent: true,
|
|
654
|
-
});
|
|
655
|
-
let pendingHistoryItems = [
|
|
656
|
-
{
|
|
657
|
-
type: 'tool_group',
|
|
658
|
-
tools: [
|
|
659
|
-
{
|
|
660
|
-
callId: 'repeat-key-call',
|
|
661
|
-
name: 'run_shell_command',
|
|
662
|
-
description: 'Run command',
|
|
663
|
-
resultDisplay: undefined,
|
|
664
|
-
status: CoreToolCallStatus.AwaitingApproval,
|
|
665
|
-
confirmationDetails: {
|
|
666
|
-
type: 'exec',
|
|
667
|
-
title: 'Run shell command',
|
|
668
|
-
command: 'ls',
|
|
669
|
-
rootCommand: 'ls',
|
|
670
|
-
rootCommands: ['ls'],
|
|
671
|
-
},
|
|
672
|
-
},
|
|
673
|
-
],
|
|
674
|
-
},
|
|
675
|
-
];
|
|
676
|
-
mockedUseGeminiStream.mockImplementation(() => ({
|
|
677
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
678
|
-
pendingHistoryItems,
|
|
679
|
-
}));
|
|
680
|
-
const { unmount, rerender } = await act(async () => renderAppContainer());
|
|
681
|
-
expect(terminalNotificationsMocks.notifyViaTerminal).toHaveBeenCalledTimes(1);
|
|
682
|
-
pendingHistoryItems = [];
|
|
683
|
-
await act(async () => {
|
|
684
|
-
rerender(getAppContainer());
|
|
685
|
-
});
|
|
686
|
-
pendingHistoryItems = [
|
|
687
|
-
{
|
|
688
|
-
type: 'tool_group',
|
|
689
|
-
tools: [
|
|
690
|
-
{
|
|
691
|
-
callId: 'repeat-key-call',
|
|
692
|
-
name: 'run_shell_command',
|
|
693
|
-
description: 'Run command',
|
|
694
|
-
resultDisplay: undefined,
|
|
695
|
-
status: CoreToolCallStatus.AwaitingApproval,
|
|
696
|
-
confirmationDetails: {
|
|
697
|
-
type: 'exec',
|
|
698
|
-
title: 'Run shell command',
|
|
699
|
-
command: 'ls',
|
|
700
|
-
rootCommand: 'ls',
|
|
701
|
-
rootCommands: ['ls'],
|
|
702
|
-
},
|
|
703
|
-
},
|
|
704
|
-
],
|
|
705
|
-
},
|
|
706
|
-
];
|
|
707
|
-
await act(async () => {
|
|
708
|
-
rerender(getAppContainer());
|
|
709
|
-
});
|
|
710
|
-
expect(terminalNotificationsMocks.notifyViaTerminal).toHaveBeenCalledTimes(2);
|
|
711
|
-
unmount();
|
|
712
|
-
});
|
|
713
|
-
it('initializes with theme error from initialization result', async () => {
|
|
714
|
-
const initResultWithError = {
|
|
715
|
-
...mockInitResult,
|
|
716
|
-
themeError: 'Failed to load theme',
|
|
717
|
-
};
|
|
718
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
719
|
-
initResult: initResultWithError,
|
|
720
|
-
}));
|
|
721
|
-
expect(capturedUIState).toBeTruthy();
|
|
722
|
-
unmount();
|
|
723
|
-
});
|
|
724
|
-
it('handles debug mode state', async () => {
|
|
725
|
-
const debugConfig = makeFakeConfig();
|
|
726
|
-
vi.spyOn(debugConfig, 'getDebugMode').mockReturnValue(true);
|
|
727
|
-
const { unmount } = await act(async () => renderAppContainer({ config: debugConfig }));
|
|
728
|
-
unmount();
|
|
729
|
-
});
|
|
730
|
-
});
|
|
731
|
-
describe('Context Providers', () => {
|
|
732
|
-
it('provides AppContext with correct values', async () => {
|
|
733
|
-
const { unmount } = await act(async () => renderAppContainer({ version: '2.0.0' }));
|
|
734
|
-
expect(capturedUIState).toBeTruthy();
|
|
735
|
-
// Should render and unmount cleanly
|
|
736
|
-
unmount();
|
|
737
|
-
});
|
|
738
|
-
it('provides UIStateContext with state management', async () => {
|
|
739
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
740
|
-
expect(capturedUIState).toBeTruthy();
|
|
741
|
-
unmount();
|
|
742
|
-
});
|
|
743
|
-
it('provides UIActionsContext with action handlers', async () => {
|
|
744
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
745
|
-
expect(capturedUIState).toBeTruthy();
|
|
746
|
-
unmount();
|
|
747
|
-
});
|
|
748
|
-
it('provides ConfigContext with config object', async () => {
|
|
749
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
750
|
-
expect(capturedUIState).toBeTruthy();
|
|
751
|
-
unmount();
|
|
752
|
-
});
|
|
753
|
-
});
|
|
754
|
-
describe('Settings Integration', () => {
|
|
755
|
-
it('handles settings with all display options disabled', async () => {
|
|
756
|
-
const settingsAllHidden = createMockSettings({
|
|
757
|
-
hideBanner: true,
|
|
758
|
-
hideTips: true,
|
|
759
|
-
hideFooter: true,
|
|
760
|
-
showMemoryUsage: false,
|
|
761
|
-
});
|
|
762
|
-
const { unmount } = await act(async () => renderAppContainer({ settings: settingsAllHidden }));
|
|
763
|
-
expect(capturedUIState).toBeTruthy();
|
|
764
|
-
unmount();
|
|
765
|
-
});
|
|
766
|
-
it('handles settings with memory usage enabled', async () => {
|
|
767
|
-
const settingsWithMemory = createMockSettings({
|
|
768
|
-
showMemoryUsage: true,
|
|
769
|
-
});
|
|
770
|
-
const { unmount } = await act(async () => renderAppContainer({ settings: settingsWithMemory }));
|
|
771
|
-
expect(capturedUIState).toBeTruthy();
|
|
772
|
-
unmount();
|
|
773
|
-
});
|
|
774
|
-
});
|
|
775
|
-
describe('Version Handling', () => {
|
|
776
|
-
it.each(['1.0.0', '2.1.3-beta', '3.0.0-nightly'])('handles version format: %s', async (version) => {
|
|
777
|
-
const { unmount } = await act(async () => renderAppContainer({ version }));
|
|
778
|
-
expect(capturedUIState).toBeTruthy();
|
|
779
|
-
unmount();
|
|
780
|
-
});
|
|
781
|
-
});
|
|
782
|
-
describe('Error Handling', () => {
|
|
783
|
-
it('handles config methods that might throw', async () => {
|
|
784
|
-
const errorConfig = makeFakeConfig();
|
|
785
|
-
vi.spyOn(errorConfig, 'getModel').mockImplementation(() => {
|
|
786
|
-
throw new Error('Config error');
|
|
787
|
-
});
|
|
788
|
-
// Should still render without crashing - errors should be handled internally
|
|
789
|
-
const { unmount } = await act(async () => renderAppContainer({ config: errorConfig }));
|
|
790
|
-
unmount();
|
|
791
|
-
});
|
|
792
|
-
it('handles undefined settings gracefully', async () => {
|
|
793
|
-
const undefinedSettings = createMockSettings();
|
|
794
|
-
const { unmount } = await act(async () => renderAppContainer({ settings: undefinedSettings }));
|
|
795
|
-
expect(capturedUIState).toBeTruthy();
|
|
796
|
-
unmount();
|
|
797
|
-
});
|
|
798
|
-
});
|
|
799
|
-
describe('Provider Hierarchy', () => {
|
|
800
|
-
it('establishes correct provider nesting order', async () => {
|
|
801
|
-
// This tests that all the context providers are properly nested
|
|
802
|
-
// and that the component tree can be built without circular dependencies
|
|
803
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
804
|
-
unmount();
|
|
805
|
-
});
|
|
806
|
-
});
|
|
807
|
-
describe('Session Resumption', () => {
|
|
808
|
-
it('handles resumed session data correctly', async () => {
|
|
809
|
-
const mockResumedSessionData = {
|
|
810
|
-
conversation: {
|
|
811
|
-
sessionId: 'test-session-123',
|
|
812
|
-
projectHash: 'test-project-hash',
|
|
813
|
-
startTime: '2024-01-01T00:00:00Z',
|
|
814
|
-
lastUpdated: '2024-01-01T00:00:01Z',
|
|
815
|
-
messages: [
|
|
816
|
-
{
|
|
817
|
-
id: 'msg-1',
|
|
818
|
-
type: 'user',
|
|
819
|
-
content: 'Hello',
|
|
820
|
-
timestamp: '2024-01-01T00:00:00Z',
|
|
821
|
-
},
|
|
822
|
-
{
|
|
823
|
-
id: 'msg-2',
|
|
824
|
-
type: 'gemini',
|
|
825
|
-
content: 'Hi there!',
|
|
826
|
-
role: 'model',
|
|
827
|
-
parts: [{ text: 'Hi there!' }],
|
|
828
|
-
timestamp: '2024-01-01T00:00:01Z',
|
|
829
|
-
},
|
|
830
|
-
],
|
|
831
|
-
},
|
|
832
|
-
filePath: '/tmp/test-session.json',
|
|
833
|
-
};
|
|
834
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
835
|
-
config: mockConfig,
|
|
836
|
-
settings: mockSettings,
|
|
837
|
-
version: '1.0.0',
|
|
838
|
-
initResult: mockInitResult,
|
|
839
|
-
resumedSessionData: mockResumedSessionData,
|
|
840
|
-
}));
|
|
841
|
-
unmount();
|
|
842
|
-
});
|
|
843
|
-
it('renders without resumed session data', async () => {
|
|
844
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
845
|
-
config: mockConfig,
|
|
846
|
-
settings: mockSettings,
|
|
847
|
-
version: '1.0.0',
|
|
848
|
-
initResult: mockInitResult,
|
|
849
|
-
resumedSessionData: undefined,
|
|
850
|
-
}));
|
|
851
|
-
unmount();
|
|
852
|
-
});
|
|
853
|
-
it('initializes chat recording service when config has it', async () => {
|
|
854
|
-
const mockChatRecordingService = {
|
|
855
|
-
initialize: vi.fn(),
|
|
856
|
-
recordMessage: vi.fn(),
|
|
857
|
-
recordMessageTokens: vi.fn(),
|
|
858
|
-
recordToolCalls: vi.fn(),
|
|
859
|
-
};
|
|
860
|
-
const mockGeminiClient = {
|
|
861
|
-
isInitialized: vi.fn(() => true),
|
|
862
|
-
resumeChat: vi.fn(),
|
|
863
|
-
getUserTier: vi.fn(),
|
|
864
|
-
getChatRecordingService: vi.fn(() => mockChatRecordingService),
|
|
865
|
-
};
|
|
866
|
-
const configWithRecording = makeFakeConfig();
|
|
867
|
-
vi.spyOn(configWithRecording, 'getGeminiClient').mockReturnValue(mockGeminiClient);
|
|
868
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
869
|
-
config: configWithRecording,
|
|
870
|
-
settings: mockSettings,
|
|
871
|
-
version: '1.0.0',
|
|
872
|
-
initResult: mockInitResult,
|
|
873
|
-
}));
|
|
874
|
-
unmount();
|
|
875
|
-
});
|
|
876
|
-
});
|
|
877
|
-
describe('Session Recording Integration', () => {
|
|
878
|
-
it('provides chat recording service configuration', async () => {
|
|
879
|
-
const mockChatRecordingService = {
|
|
880
|
-
initialize: vi.fn(),
|
|
881
|
-
recordMessage: vi.fn(),
|
|
882
|
-
recordMessageTokens: vi.fn(),
|
|
883
|
-
recordToolCalls: vi.fn(),
|
|
884
|
-
getSessionId: vi.fn(() => 'test-session-123'),
|
|
885
|
-
getCurrentConversation: vi.fn(),
|
|
886
|
-
};
|
|
887
|
-
const mockGeminiClient = {
|
|
888
|
-
isInitialized: vi.fn(() => true),
|
|
889
|
-
resumeChat: vi.fn(),
|
|
890
|
-
getUserTier: vi.fn(),
|
|
891
|
-
getChatRecordingService: vi.fn(() => mockChatRecordingService),
|
|
892
|
-
setHistory: vi.fn(),
|
|
893
|
-
};
|
|
894
|
-
const configWithRecording = makeFakeConfig();
|
|
895
|
-
vi.spyOn(configWithRecording, 'getGeminiClient').mockReturnValue(mockGeminiClient);
|
|
896
|
-
vi.spyOn(configWithRecording, 'getSessionId').mockReturnValue('test-session-123');
|
|
897
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
898
|
-
config: configWithRecording,
|
|
899
|
-
settings: mockSettings,
|
|
900
|
-
version: '1.0.0',
|
|
901
|
-
initResult: mockInitResult,
|
|
902
|
-
}));
|
|
903
|
-
// Verify the recording service structure is correct
|
|
904
|
-
expect(configWithRecording.getGeminiClient).toBeDefined();
|
|
905
|
-
expect(mockGeminiClient.getChatRecordingService).toBeDefined();
|
|
906
|
-
expect(mockChatRecordingService.initialize).toBeDefined();
|
|
907
|
-
expect(mockChatRecordingService.recordMessage).toBeDefined();
|
|
908
|
-
unmount();
|
|
909
|
-
});
|
|
910
|
-
it('handles session recording when messages are added', async () => {
|
|
911
|
-
const mockRecordMessage = vi.fn();
|
|
912
|
-
const mockRecordMessageTokens = vi.fn();
|
|
913
|
-
const mockChatRecordingService = {
|
|
914
|
-
initialize: vi.fn(),
|
|
915
|
-
recordMessage: mockRecordMessage,
|
|
916
|
-
recordMessageTokens: mockRecordMessageTokens,
|
|
917
|
-
recordToolCalls: vi.fn(),
|
|
918
|
-
getSessionId: vi.fn(() => 'test-session-123'),
|
|
919
|
-
};
|
|
920
|
-
const mockGeminiClient = {
|
|
921
|
-
isInitialized: vi.fn(() => true),
|
|
922
|
-
getChatRecordingService: vi.fn(() => mockChatRecordingService),
|
|
923
|
-
getUserTier: vi.fn(),
|
|
924
|
-
};
|
|
925
|
-
const configWithRecording = makeFakeConfig();
|
|
926
|
-
vi.spyOn(configWithRecording, 'getGeminiClient').mockReturnValue(mockGeminiClient);
|
|
927
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
928
|
-
config: configWithRecording,
|
|
929
|
-
settings: mockSettings,
|
|
930
|
-
version: '1.0.0',
|
|
931
|
-
initResult: mockInitResult,
|
|
932
|
-
}));
|
|
933
|
-
// The actual recording happens through the useHistory hook
|
|
934
|
-
// which would be triggered by user interactions
|
|
935
|
-
expect(mockChatRecordingService.initialize).toBeDefined();
|
|
936
|
-
expect(mockChatRecordingService.recordMessage).toBeDefined();
|
|
937
|
-
unmount();
|
|
938
|
-
});
|
|
939
|
-
});
|
|
940
|
-
describe('Session Resume Flow', () => {
|
|
941
|
-
it('accepts resumed session data', async () => {
|
|
942
|
-
const mockResumeChat = vi.fn();
|
|
943
|
-
const mockGeminiClient = {
|
|
944
|
-
isInitialized: vi.fn(() => true),
|
|
945
|
-
resumeChat: mockResumeChat,
|
|
946
|
-
getUserTier: vi.fn(),
|
|
947
|
-
getChatRecordingService: vi.fn(() => ({
|
|
948
|
-
initialize: vi.fn(),
|
|
949
|
-
recordMessage: vi.fn(),
|
|
950
|
-
recordMessageTokens: vi.fn(),
|
|
951
|
-
recordToolCalls: vi.fn(),
|
|
952
|
-
})),
|
|
953
|
-
};
|
|
954
|
-
const configWithClient = makeFakeConfig();
|
|
955
|
-
vi.spyOn(configWithClient, 'getGeminiClient').mockReturnValue(mockGeminiClient);
|
|
956
|
-
const resumedData = {
|
|
957
|
-
conversation: {
|
|
958
|
-
sessionId: 'resumed-session-456',
|
|
959
|
-
projectHash: 'project-hash',
|
|
960
|
-
startTime: '2024-01-01T00:00:00Z',
|
|
961
|
-
lastUpdated: '2024-01-01T00:01:00Z',
|
|
962
|
-
messages: [
|
|
963
|
-
{
|
|
964
|
-
id: 'msg-1',
|
|
965
|
-
type: 'user',
|
|
966
|
-
content: 'Previous question',
|
|
967
|
-
timestamp: '2024-01-01T00:00:00Z',
|
|
968
|
-
},
|
|
969
|
-
{
|
|
970
|
-
id: 'msg-2',
|
|
971
|
-
type: 'gemini',
|
|
972
|
-
content: 'Previous answer',
|
|
973
|
-
role: 'model',
|
|
974
|
-
parts: [{ text: 'Previous answer' }],
|
|
975
|
-
timestamp: '2024-01-01T00:00:30Z',
|
|
976
|
-
tokenCount: { input: 10, output: 20 },
|
|
977
|
-
},
|
|
978
|
-
],
|
|
979
|
-
},
|
|
980
|
-
filePath: '/tmp/resumed-session.json',
|
|
981
|
-
};
|
|
982
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
983
|
-
config: configWithClient,
|
|
984
|
-
settings: mockSettings,
|
|
985
|
-
version: '1.0.0',
|
|
986
|
-
initResult: mockInitResult,
|
|
987
|
-
resumedSessionData: resumedData,
|
|
988
|
-
}));
|
|
989
|
-
// Verify the resume functionality structure is in place
|
|
990
|
-
expect(mockGeminiClient.resumeChat).toBeDefined();
|
|
991
|
-
expect(resumedData.conversation.messages).toHaveLength(2);
|
|
992
|
-
unmount();
|
|
993
|
-
});
|
|
994
|
-
it('does not attempt resume when client is not initialized', async () => {
|
|
995
|
-
const mockResumeChat = vi.fn();
|
|
996
|
-
const mockGeminiClient = {
|
|
997
|
-
isInitialized: vi.fn(() => false), // Not initialized
|
|
998
|
-
resumeChat: mockResumeChat,
|
|
999
|
-
getUserTier: vi.fn(),
|
|
1000
|
-
getChatRecordingService: vi.fn(),
|
|
1001
|
-
};
|
|
1002
|
-
const configWithClient = makeFakeConfig();
|
|
1003
|
-
vi.spyOn(configWithClient, 'getGeminiClient').mockReturnValue(mockGeminiClient);
|
|
1004
|
-
const resumedData = {
|
|
1005
|
-
conversation: {
|
|
1006
|
-
sessionId: 'test-session',
|
|
1007
|
-
projectHash: 'project-hash',
|
|
1008
|
-
startTime: '2024-01-01T00:00:00Z',
|
|
1009
|
-
lastUpdated: '2024-01-01T00:01:00Z',
|
|
1010
|
-
messages: [],
|
|
1011
|
-
},
|
|
1012
|
-
filePath: '/tmp/session.json',
|
|
1013
|
-
};
|
|
1014
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1015
|
-
config: configWithClient,
|
|
1016
|
-
settings: mockSettings,
|
|
1017
|
-
version: '1.0.0',
|
|
1018
|
-
initResult: mockInitResult,
|
|
1019
|
-
resumedSessionData: resumedData,
|
|
1020
|
-
}));
|
|
1021
|
-
// Should not call resumeChat when client is not initialized
|
|
1022
|
-
expect(mockResumeChat).not.toHaveBeenCalled();
|
|
1023
|
-
unmount();
|
|
1024
|
-
});
|
|
1025
|
-
});
|
|
1026
|
-
describe('SessionStart Hook Rendering', () => {
|
|
1027
|
-
it('does not render systemMessage directly (avoids duplicate with HookSystemMessage event)', async () => {
|
|
1028
|
-
const mockAddItem = vi.fn();
|
|
1029
|
-
mockedUseHistory.mockReturnValue({
|
|
1030
|
-
history: [],
|
|
1031
|
-
addItem: mockAddItem,
|
|
1032
|
-
updateItem: vi.fn(),
|
|
1033
|
-
clearItems: vi.fn(),
|
|
1034
|
-
loadHistory: vi.fn(),
|
|
1035
|
-
});
|
|
1036
|
-
const fireSessionStartEvent = vi.fn().mockResolvedValue({
|
|
1037
|
-
systemMessage: 'Hello from SessionStart hook',
|
|
1038
|
-
getAdditionalContext: vi.fn(() => undefined),
|
|
1039
|
-
});
|
|
1040
|
-
vi.spyOn(mockConfig, 'getHookSystem').mockReturnValue({
|
|
1041
|
-
fireSessionEndEvent: vi.fn().mockResolvedValue(undefined),
|
|
1042
|
-
fireSessionStartEvent,
|
|
1043
|
-
});
|
|
1044
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
1045
|
-
await waitFor(() => expect(fireSessionStartEvent).toHaveBeenCalled());
|
|
1046
|
-
// The direct-render path (the bug) would call addItem with the
|
|
1047
|
-
// systemMessage text and no `source` field. The HookSystemMessage
|
|
1048
|
-
// event-listener path (the correct one) always sets `source`.
|
|
1049
|
-
const directRenderCall = mockAddItem.mock.calls.find(([item]) => item?.text === 'Hello from SessionStart hook' && !item?.source);
|
|
1050
|
-
expect(directRenderCall).toBeUndefined();
|
|
1051
|
-
unmount();
|
|
1052
|
-
});
|
|
1053
|
-
});
|
|
1054
|
-
describe('Token Counting from Session Stats', () => {
|
|
1055
|
-
it('tracks token counts from session messages', async () => {
|
|
1056
|
-
// Session stats are provided through the SessionStatsProvider context
|
|
1057
|
-
// in the real app, not through the config directly
|
|
1058
|
-
const mockChatRecordingService = {
|
|
1059
|
-
initialize: vi.fn(),
|
|
1060
|
-
recordMessage: vi.fn(),
|
|
1061
|
-
recordMessageTokens: vi.fn(),
|
|
1062
|
-
recordToolCalls: vi.fn(),
|
|
1063
|
-
getSessionId: vi.fn(() => 'test-session-123'),
|
|
1064
|
-
getCurrentConversation: vi.fn(() => ({
|
|
1065
|
-
sessionId: 'test-session-123',
|
|
1066
|
-
messages: [],
|
|
1067
|
-
totalInputTokens: 150,
|
|
1068
|
-
totalOutputTokens: 350,
|
|
1069
|
-
})),
|
|
1070
|
-
};
|
|
1071
|
-
const mockGeminiClient = {
|
|
1072
|
-
isInitialized: vi.fn(() => true),
|
|
1073
|
-
getChatRecordingService: vi.fn(() => mockChatRecordingService),
|
|
1074
|
-
getUserTier: vi.fn(),
|
|
1075
|
-
};
|
|
1076
|
-
const configWithRecording = makeFakeConfig();
|
|
1077
|
-
vi.spyOn(configWithRecording, 'getGeminiClient').mockReturnValue(mockGeminiClient);
|
|
1078
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1079
|
-
config: configWithRecording,
|
|
1080
|
-
settings: mockSettings,
|
|
1081
|
-
version: '1.0.0',
|
|
1082
|
-
initResult: mockInitResult,
|
|
1083
|
-
}));
|
|
1084
|
-
// In the actual app, these stats would be displayed in components
|
|
1085
|
-
// and updated as messages are processed through the recording service
|
|
1086
|
-
expect(mockChatRecordingService.recordMessageTokens).toBeDefined();
|
|
1087
|
-
expect(mockChatRecordingService.getCurrentConversation).toBeDefined();
|
|
1088
|
-
unmount();
|
|
1089
|
-
});
|
|
1090
|
-
});
|
|
1091
|
-
describe('Quota and Fallback Integration', () => {
|
|
1092
|
-
it('passes a null proQuotaRequest to QuotaContext by default', async () => {
|
|
1093
|
-
// The default mock from beforeEach already sets proQuotaRequest to null
|
|
1094
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
1095
|
-
// Assert that the context value is as expected
|
|
1096
|
-
expect(capturedQuotaState.proQuotaRequest).toBeNull();
|
|
1097
|
-
unmount();
|
|
1098
|
-
});
|
|
1099
|
-
it('passes a valid proQuotaRequest to QuotaContext when provided by the hook', async () => {
|
|
1100
|
-
// Arrange: Create a mock request object that a UI dialog would receive
|
|
1101
|
-
const mockRequest = {
|
|
1102
|
-
failedModel: 'gemini-pro',
|
|
1103
|
-
fallbackModel: 'gemini-flash',
|
|
1104
|
-
resolve: vi.fn(),
|
|
1105
|
-
};
|
|
1106
|
-
mockedUseQuotaAndFallback.mockReturnValue({
|
|
1107
|
-
proQuotaRequest: mockRequest,
|
|
1108
|
-
handleProQuotaChoice: vi.fn(),
|
|
1109
|
-
});
|
|
1110
|
-
// Act: Render the container
|
|
1111
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
1112
|
-
// Assert: The mock request is correctly passed through the context
|
|
1113
|
-
expect(capturedQuotaState.proQuotaRequest).toEqual(mockRequest);
|
|
1114
|
-
unmount();
|
|
1115
|
-
});
|
|
1116
|
-
it('passes the handleProQuotaChoice function to UIActionsContext', async () => {
|
|
1117
|
-
// Arrange: Create a mock handler function
|
|
1118
|
-
const mockHandler = vi.fn();
|
|
1119
|
-
mockedUseQuotaAndFallback.mockReturnValue({
|
|
1120
|
-
proQuotaRequest: null,
|
|
1121
|
-
handleProQuotaChoice: mockHandler,
|
|
1122
|
-
});
|
|
1123
|
-
// Act: Render the container
|
|
1124
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
1125
|
-
// Assert: The action in the context is the mock handler we provided
|
|
1126
|
-
expect(capturedUIActions.handleProQuotaChoice).toBe(mockHandler);
|
|
1127
|
-
// You can even verify that the plumbed function is callable
|
|
1128
|
-
act(() => {
|
|
1129
|
-
capturedUIActions.handleProQuotaChoice('retry_later');
|
|
1130
|
-
});
|
|
1131
|
-
expect(mockHandler).toHaveBeenCalledWith('retry_later');
|
|
1132
|
-
unmount();
|
|
1133
|
-
});
|
|
1134
|
-
});
|
|
1135
|
-
describe('Terminal Title Update Feature', () => {
|
|
1136
|
-
beforeEach(() => {
|
|
1137
|
-
// Reset mock stdout for each test
|
|
1138
|
-
mocks.mockStdout.write.mockClear();
|
|
1139
|
-
disableMouseEvents.mockClear();
|
|
1140
|
-
});
|
|
1141
|
-
it('verifies useStdout is mocked', async () => {
|
|
1142
|
-
const { useStdout } = await import('ink');
|
|
1143
|
-
const { stdout } = useStdout();
|
|
1144
|
-
expect(stdout).toBe(mocks.mockStdout);
|
|
1145
|
-
});
|
|
1146
|
-
it('should update terminal title with Working… when showStatusInTitle is false', async () => {
|
|
1147
|
-
// Arrange: Set up mock settings with showStatusInTitle disabled
|
|
1148
|
-
const mockSettingsWithShowStatusFalse = createMockSettings({
|
|
1149
|
-
ui: {
|
|
1150
|
-
showStatusInTitle: false,
|
|
1151
|
-
hideWindowTitle: false,
|
|
1152
|
-
},
|
|
1153
|
-
});
|
|
1154
|
-
// Mock the streaming state as Active
|
|
1155
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1156
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1157
|
-
streamingState: 'responding',
|
|
1158
|
-
thought: { subject: 'Some thought' },
|
|
1159
|
-
});
|
|
1160
|
-
// Act: Render the container
|
|
1161
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1162
|
-
settings: mockSettingsWithShowStatusFalse,
|
|
1163
|
-
}));
|
|
1164
|
-
// Assert: Check that title was updated with "Working…"
|
|
1165
|
-
const titleWrites = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1166
|
-
expect(titleWrites).toHaveLength(1);
|
|
1167
|
-
expect(titleWrites[0][0]).toBe(`\x1b]0;${'✦ Working… (workspace)'.padEnd(80, ' ')}\x07`);
|
|
1168
|
-
unmount();
|
|
1169
|
-
});
|
|
1170
|
-
it('should use legacy terminal title when dynamicWindowTitle is false', async () => {
|
|
1171
|
-
// Arrange: Set up mock settings with dynamicWindowTitle disabled
|
|
1172
|
-
const mockSettingsWithDynamicTitleFalse = createMockSettings({
|
|
1173
|
-
ui: {
|
|
1174
|
-
dynamicWindowTitle: false,
|
|
1175
|
-
hideWindowTitle: false,
|
|
1176
|
-
},
|
|
1177
|
-
});
|
|
1178
|
-
// Mock the streaming state
|
|
1179
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1180
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1181
|
-
streamingState: 'responding',
|
|
1182
|
-
thought: { subject: 'Some thought' },
|
|
1183
|
-
});
|
|
1184
|
-
// Act: Render the container
|
|
1185
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1186
|
-
settings: mockSettingsWithDynamicTitleFalse,
|
|
1187
|
-
}));
|
|
1188
|
-
// Assert: Check that legacy title was used
|
|
1189
|
-
const titleWrites = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1190
|
-
expect(titleWrites).toHaveLength(1);
|
|
1191
|
-
expect(titleWrites[0][0]).toBe(`\x1b]0;${'Gemini CLI (workspace)'.padEnd(80, ' ')}\x07`);
|
|
1192
|
-
unmount();
|
|
1193
|
-
});
|
|
1194
|
-
it('should not update terminal title when hideWindowTitle is true', async () => {
|
|
1195
|
-
// Arrange: Set up mock settings with hideWindowTitle enabled
|
|
1196
|
-
const mockSettingsWithHideTitleTrue = createMockSettings({
|
|
1197
|
-
ui: {
|
|
1198
|
-
showStatusInTitle: true,
|
|
1199
|
-
hideWindowTitle: true,
|
|
1200
|
-
},
|
|
1201
|
-
});
|
|
1202
|
-
// Act: Render the container
|
|
1203
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1204
|
-
settings: mockSettingsWithHideTitleTrue,
|
|
1205
|
-
}));
|
|
1206
|
-
// Assert: Check that no title-related writes occurred
|
|
1207
|
-
const titleWrites = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1208
|
-
expect(titleWrites).toHaveLength(0);
|
|
1209
|
-
unmount();
|
|
1210
|
-
});
|
|
1211
|
-
it('should update terminal title with thought subject when in active state', async () => {
|
|
1212
|
-
// Arrange: Set up mock settings with showStatusInTitle enabled
|
|
1213
|
-
const mockSettingsWithTitleEnabled = createMockSettings({
|
|
1214
|
-
ui: {
|
|
1215
|
-
showStatusInTitle: true,
|
|
1216
|
-
hideWindowTitle: false,
|
|
1217
|
-
},
|
|
1218
|
-
});
|
|
1219
|
-
// Mock the streaming state and thought
|
|
1220
|
-
const thoughtSubject = 'Processing request';
|
|
1221
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1222
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1223
|
-
streamingState: 'responding',
|
|
1224
|
-
thought: { subject: thoughtSubject },
|
|
1225
|
-
});
|
|
1226
|
-
// Act: Render the container
|
|
1227
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1228
|
-
settings: mockSettingsWithTitleEnabled,
|
|
1229
|
-
}));
|
|
1230
|
-
// Assert: Check that title was updated with thought subject and suffix
|
|
1231
|
-
const titleWrites = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1232
|
-
expect(titleWrites).toHaveLength(1);
|
|
1233
|
-
expect(titleWrites[0][0]).toBe(`\x1b]0;${`✦ ${thoughtSubject} (workspace)`.padEnd(80, ' ')}\x07`);
|
|
1234
|
-
unmount();
|
|
1235
|
-
});
|
|
1236
|
-
it('should update terminal title with default text when in Idle state and no thought subject', async () => {
|
|
1237
|
-
// Arrange: Set up mock settings with showStatusInTitle enabled
|
|
1238
|
-
const mockSettingsWithTitleEnabled = createMockSettings({
|
|
1239
|
-
ui: {
|
|
1240
|
-
showStatusInTitle: true,
|
|
1241
|
-
hideWindowTitle: false,
|
|
1242
|
-
},
|
|
1243
|
-
});
|
|
1244
|
-
// Mock the streaming state as Idle with no thought
|
|
1245
|
-
mockedUseGeminiStream.mockReturnValue(DEFAULT_GEMINI_STREAM_MOCK);
|
|
1246
|
-
// Act: Render the container
|
|
1247
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1248
|
-
settings: mockSettingsWithTitleEnabled,
|
|
1249
|
-
}));
|
|
1250
|
-
// Assert: Check that title was updated with default Idle text
|
|
1251
|
-
const titleWrites = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1252
|
-
expect(titleWrites).toHaveLength(1);
|
|
1253
|
-
expect(titleWrites[0][0]).toBe(`\x1b]0;${'◇ Ready (workspace)'.padEnd(80, ' ')}\x07`);
|
|
1254
|
-
unmount();
|
|
1255
|
-
});
|
|
1256
|
-
it('should update terminal title when in WaitingForConfirmation state with thought subject', async () => {
|
|
1257
|
-
// Arrange: Set up mock settings with showStatusInTitle enabled
|
|
1258
|
-
const mockSettingsWithTitleEnabled = createMockSettings({
|
|
1259
|
-
ui: {
|
|
1260
|
-
showStatusInTitle: true,
|
|
1261
|
-
hideWindowTitle: false,
|
|
1262
|
-
},
|
|
1263
|
-
});
|
|
1264
|
-
// Mock the streaming state and thought
|
|
1265
|
-
const thoughtSubject = 'Confirm tool execution';
|
|
1266
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1267
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1268
|
-
streamingState: 'waiting_for_confirmation',
|
|
1269
|
-
thought: { subject: thoughtSubject },
|
|
1270
|
-
});
|
|
1271
|
-
// Act: Render the container
|
|
1272
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1273
|
-
settings: mockSettingsWithTitleEnabled,
|
|
1274
|
-
}));
|
|
1275
|
-
// Assert: Check that title was updated with confirmation text
|
|
1276
|
-
const titleWrites = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1277
|
-
expect(titleWrites).toHaveLength(1);
|
|
1278
|
-
expect(titleWrites[0][0]).toBe(`\x1b]0;${'✋ Action Required (workspace)'.padEnd(80, ' ')}\x07`);
|
|
1279
|
-
unmount();
|
|
1280
|
-
});
|
|
1281
|
-
describe('Shell Focus Action Required', () => {
|
|
1282
|
-
beforeEach(async () => {
|
|
1283
|
-
vi.useFakeTimers();
|
|
1284
|
-
// Use real implementation for these tests to verify title updates
|
|
1285
|
-
const actual = await vi.importActual('./hooks/useShellInactivityStatus.js');
|
|
1286
|
-
mockedUseShellInactivityStatus.mockImplementation(actual.useShellInactivityStatus);
|
|
1287
|
-
});
|
|
1288
|
-
afterEach(() => {
|
|
1289
|
-
vi.useRealTimers();
|
|
1290
|
-
});
|
|
1291
|
-
it('should show Action Required in title after a delay when shell is awaiting focus', async () => {
|
|
1292
|
-
const startTime = 1000000;
|
|
1293
|
-
vi.setSystemTime(startTime);
|
|
1294
|
-
// Arrange: Set up mock settings with showStatusInTitle enabled
|
|
1295
|
-
const mockSettingsWithTitleEnabled = createMockSettings({
|
|
1296
|
-
ui: {
|
|
1297
|
-
showStatusInTitle: true,
|
|
1298
|
-
hideWindowTitle: false,
|
|
1299
|
-
},
|
|
1300
|
-
});
|
|
1301
|
-
// Mock an active shell pty but not focused
|
|
1302
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1303
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1304
|
-
streamingState: 'responding',
|
|
1305
|
-
thought: { subject: 'Executing shell command' },
|
|
1306
|
-
pendingToolCalls: [],
|
|
1307
|
-
activePtyId: 'pty-1',
|
|
1308
|
-
lastOutputTime: startTime + 100, // Trigger aggressive delay
|
|
1309
|
-
retryStatus: null,
|
|
1310
|
-
});
|
|
1311
|
-
vi.spyOn(mockConfig, 'isInteractive').mockReturnValue(true);
|
|
1312
|
-
vi.spyOn(mockConfig, 'isInteractiveShellEnabled').mockReturnValue(true);
|
|
1313
|
-
// Act: Render the container (embeddedShellFocused is false by default in state)
|
|
1314
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1315
|
-
settings: mockSettingsWithTitleEnabled,
|
|
1316
|
-
}));
|
|
1317
|
-
// Initially it should show the working status
|
|
1318
|
-
const titleWrites = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1319
|
-
expect(titleWrites[titleWrites.length - 1][0]).toContain('✦ Executing shell command');
|
|
1320
|
-
// Fast-forward time by 40 seconds
|
|
1321
|
-
await act(async () => {
|
|
1322
|
-
await vi.advanceTimersByTimeAsync(40000);
|
|
1323
|
-
});
|
|
1324
|
-
// Now it should show Action Required
|
|
1325
|
-
const titleWritesDelayed = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1326
|
-
const lastTitle = titleWritesDelayed[titleWritesDelayed.length - 1][0];
|
|
1327
|
-
expect(lastTitle).toContain('✋ Action Required');
|
|
1328
|
-
unmount();
|
|
1329
|
-
});
|
|
1330
|
-
it('should show Working… in title for redirected commands after 2 mins', async () => {
|
|
1331
|
-
const startTime = 1000000;
|
|
1332
|
-
vi.setSystemTime(startTime);
|
|
1333
|
-
// Arrange: Set up mock settings with showStatusInTitle enabled
|
|
1334
|
-
const mockSettingsWithTitleEnabled = createMockSettings({
|
|
1335
|
-
ui: {
|
|
1336
|
-
showStatusInTitle: true,
|
|
1337
|
-
hideWindowTitle: false,
|
|
1338
|
-
},
|
|
1339
|
-
});
|
|
1340
|
-
// Mock an active shell pty with redirection active
|
|
1341
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1342
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1343
|
-
streamingState: 'responding',
|
|
1344
|
-
thought: { subject: 'Executing shell command' },
|
|
1345
|
-
pendingToolCalls: [
|
|
1346
|
-
{
|
|
1347
|
-
request: {
|
|
1348
|
-
name: 'run_shell_command',
|
|
1349
|
-
args: { command: 'ls > out' },
|
|
1350
|
-
},
|
|
1351
|
-
status: CoreToolCallStatus.Executing,
|
|
1352
|
-
},
|
|
1353
|
-
],
|
|
1354
|
-
activePtyId: 'pty-1',
|
|
1355
|
-
lastOutputTime: startTime,
|
|
1356
|
-
retryStatus: null,
|
|
1357
|
-
});
|
|
1358
|
-
vi.spyOn(mockConfig, 'isInteractive').mockReturnValue(true);
|
|
1359
|
-
vi.spyOn(mockConfig, 'isInteractiveShellEnabled').mockReturnValue(true);
|
|
1360
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1361
|
-
settings: mockSettingsWithTitleEnabled,
|
|
1362
|
-
}));
|
|
1363
|
-
// Fast-forward time by 65 seconds - should still NOT be Action Required
|
|
1364
|
-
await act(async () => {
|
|
1365
|
-
await vi.advanceTimersByTimeAsync(65000);
|
|
1366
|
-
});
|
|
1367
|
-
const titleWritesMid = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1368
|
-
expect(titleWritesMid[titleWritesMid.length - 1][0]).not.toContain('✋ Action Required');
|
|
1369
|
-
// Fast-forward to 2 minutes (120000ms)
|
|
1370
|
-
await act(async () => {
|
|
1371
|
-
await vi.advanceTimersByTimeAsync(60000);
|
|
1372
|
-
});
|
|
1373
|
-
const titleWritesEnd = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1374
|
-
expect(titleWritesEnd[titleWritesEnd.length - 1][0]).toContain('⏲ Working…');
|
|
1375
|
-
unmount();
|
|
1376
|
-
});
|
|
1377
|
-
it('should show Working… in title for silent non-redirected commands after 1 min', async () => {
|
|
1378
|
-
const startTime = 1000000;
|
|
1379
|
-
vi.setSystemTime(startTime);
|
|
1380
|
-
// Arrange: Set up mock settings with showStatusInTitle enabled
|
|
1381
|
-
const mockSettingsWithTitleEnabled = createMockSettings({
|
|
1382
|
-
ui: {
|
|
1383
|
-
showStatusInTitle: true,
|
|
1384
|
-
hideWindowTitle: false,
|
|
1385
|
-
},
|
|
1386
|
-
});
|
|
1387
|
-
// Mock an active shell pty with NO output since operation started (silent)
|
|
1388
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1389
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1390
|
-
streamingState: 'responding',
|
|
1391
|
-
thought: { subject: 'Executing shell command' },
|
|
1392
|
-
pendingToolCalls: [],
|
|
1393
|
-
activePtyId: 'pty-1',
|
|
1394
|
-
lastOutputTime: startTime, // lastOutputTime <= operationStartTime
|
|
1395
|
-
retryStatus: null,
|
|
1396
|
-
});
|
|
1397
|
-
vi.spyOn(mockConfig, 'isInteractive').mockReturnValue(true);
|
|
1398
|
-
vi.spyOn(mockConfig, 'isInteractiveShellEnabled').mockReturnValue(true);
|
|
1399
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1400
|
-
settings: mockSettingsWithTitleEnabled,
|
|
1401
|
-
}));
|
|
1402
|
-
// Fast-forward time by 65 seconds
|
|
1403
|
-
await act(async () => {
|
|
1404
|
-
await vi.advanceTimersByTimeAsync(65000);
|
|
1405
|
-
});
|
|
1406
|
-
const titleWrites = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1407
|
-
const lastTitle = titleWrites[titleWrites.length - 1][0];
|
|
1408
|
-
// Should show Working… (⏲) instead of Action Required (✋)
|
|
1409
|
-
expect(lastTitle).toContain('⏲ Working…');
|
|
1410
|
-
unmount();
|
|
1411
|
-
});
|
|
1412
|
-
it('should NOT show Action Required in title if shell is streaming output', async () => {
|
|
1413
|
-
const startTime = 1000000;
|
|
1414
|
-
vi.setSystemTime(startTime);
|
|
1415
|
-
// Arrange: Set up mock settings with showStatusInTitle enabled
|
|
1416
|
-
const mockSettingsWithTitleEnabled = createMockSettings({
|
|
1417
|
-
ui: {
|
|
1418
|
-
showStatusInTitle: true,
|
|
1419
|
-
hideWindowTitle: false,
|
|
1420
|
-
},
|
|
1421
|
-
});
|
|
1422
|
-
// Mock an active shell pty but not focused
|
|
1423
|
-
let lastOutputTime = startTime + 1000;
|
|
1424
|
-
mockedUseGeminiStream.mockImplementation(() => ({
|
|
1425
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1426
|
-
streamingState: 'responding',
|
|
1427
|
-
thought: { subject: 'Executing shell command' },
|
|
1428
|
-
activePtyId: 'pty-1',
|
|
1429
|
-
lastOutputTime,
|
|
1430
|
-
}));
|
|
1431
|
-
vi.spyOn(mockConfig, 'isInteractive').mockReturnValue(true);
|
|
1432
|
-
vi.spyOn(mockConfig, 'isInteractiveShellEnabled').mockReturnValue(true);
|
|
1433
|
-
// Act: Render the container
|
|
1434
|
-
const { unmount, rerender } = await act(async () => renderAppContainer({
|
|
1435
|
-
settings: mockSettingsWithTitleEnabled,
|
|
1436
|
-
}));
|
|
1437
|
-
// Fast-forward time by 20 seconds
|
|
1438
|
-
await act(async () => {
|
|
1439
|
-
await vi.advanceTimersByTimeAsync(20000);
|
|
1440
|
-
});
|
|
1441
|
-
// Update lastOutputTime to simulate new output
|
|
1442
|
-
lastOutputTime = startTime + 21000;
|
|
1443
|
-
mockedUseGeminiStream.mockImplementation(() => ({
|
|
1444
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1445
|
-
streamingState: 'responding',
|
|
1446
|
-
thought: { subject: 'Executing shell command' },
|
|
1447
|
-
activePtyId: 'pty-1',
|
|
1448
|
-
lastOutputTime,
|
|
1449
|
-
}));
|
|
1450
|
-
// Rerender to propagate the new lastOutputTime
|
|
1451
|
-
await act(async () => {
|
|
1452
|
-
rerender(getAppContainer({ settings: mockSettingsWithTitleEnabled }));
|
|
1453
|
-
});
|
|
1454
|
-
// Fast-forward time by another 20 seconds
|
|
1455
|
-
// Total time elapsed: 40s.
|
|
1456
|
-
// Time since last output: 20s.
|
|
1457
|
-
// It should NOT show Action Required yet.
|
|
1458
|
-
await act(async () => {
|
|
1459
|
-
await vi.advanceTimersByTimeAsync(20000);
|
|
1460
|
-
});
|
|
1461
|
-
const titleWritesAfterOutput = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1462
|
-
const lastTitle = titleWritesAfterOutput[titleWritesAfterOutput.length - 1][0];
|
|
1463
|
-
expect(lastTitle).not.toContain('✋ Action Required');
|
|
1464
|
-
expect(lastTitle).toContain('✦ Executing shell command');
|
|
1465
|
-
// Fast-forward another 40 seconds (Total 60s since last output)
|
|
1466
|
-
await act(async () => {
|
|
1467
|
-
await vi.advanceTimersByTimeAsync(40000);
|
|
1468
|
-
});
|
|
1469
|
-
// Now it SHOULD show Action Required
|
|
1470
|
-
const titleWrites = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1471
|
-
const lastTitleFinal = titleWrites[titleWrites.length - 1][0];
|
|
1472
|
-
expect(lastTitleFinal).toContain('✋ Action Required');
|
|
1473
|
-
unmount();
|
|
1474
|
-
});
|
|
1475
|
-
});
|
|
1476
|
-
it('should pad title to exactly 80 characters', async () => {
|
|
1477
|
-
// Arrange: Set up mock settings with showStatusInTitle enabled
|
|
1478
|
-
const mockSettingsWithTitleEnabled = createMockSettings({
|
|
1479
|
-
ui: {
|
|
1480
|
-
showStatusInTitle: true,
|
|
1481
|
-
hideWindowTitle: false,
|
|
1482
|
-
},
|
|
1483
|
-
});
|
|
1484
|
-
// Mock the streaming state and thought with a short subject
|
|
1485
|
-
const shortTitle = 'Short';
|
|
1486
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1487
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1488
|
-
streamingState: 'responding',
|
|
1489
|
-
thought: { subject: shortTitle },
|
|
1490
|
-
});
|
|
1491
|
-
// Act: Render the container
|
|
1492
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1493
|
-
settings: mockSettingsWithTitleEnabled,
|
|
1494
|
-
}));
|
|
1495
|
-
// Assert: Check that title is padded to exactly 80 characters
|
|
1496
|
-
const titleWrites = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1497
|
-
expect(titleWrites).toHaveLength(1);
|
|
1498
|
-
const calledWith = titleWrites[0][0];
|
|
1499
|
-
const expectedTitle = `✦ ${shortTitle} (workspace)`.padEnd(80, ' ');
|
|
1500
|
-
const expectedEscapeSequence = `\x1b]0;${expectedTitle}\x07`;
|
|
1501
|
-
expect(calledWith).toBe(expectedEscapeSequence);
|
|
1502
|
-
unmount();
|
|
1503
|
-
});
|
|
1504
|
-
it('should use correct ANSI escape code format', async () => {
|
|
1505
|
-
// Arrange: Set up mock settings with showStatusInTitle enabled
|
|
1506
|
-
const mockSettingsWithTitleEnabled = createMockSettings({
|
|
1507
|
-
ui: {
|
|
1508
|
-
showStatusInTitle: true,
|
|
1509
|
-
hideWindowTitle: false,
|
|
1510
|
-
},
|
|
1511
|
-
});
|
|
1512
|
-
// Mock the streaming state and thought
|
|
1513
|
-
const title = 'Test Title';
|
|
1514
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1515
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1516
|
-
streamingState: 'responding',
|
|
1517
|
-
thought: { subject: title },
|
|
1518
|
-
});
|
|
1519
|
-
// Act: Render the container
|
|
1520
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1521
|
-
settings: mockSettingsWithTitleEnabled,
|
|
1522
|
-
}));
|
|
1523
|
-
// Assert: Check that the correct ANSI escape sequence is used
|
|
1524
|
-
const titleWrites = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1525
|
-
expect(titleWrites).toHaveLength(1);
|
|
1526
|
-
const expectedEscapeSequence = `\x1b]0;${`✦ ${title} (workspace)`.padEnd(80, ' ')}\x07`;
|
|
1527
|
-
expect(titleWrites[0][0]).toBe(expectedEscapeSequence);
|
|
1528
|
-
unmount();
|
|
1529
|
-
});
|
|
1530
|
-
it('should use CLI_TITLE environment variable when set', async () => {
|
|
1531
|
-
// Arrange: Set up mock settings with showStatusInTitle disabled (so it shows suffix)
|
|
1532
|
-
const mockSettingsWithTitleDisabled = createMockSettings({
|
|
1533
|
-
ui: {
|
|
1534
|
-
showStatusInTitle: false,
|
|
1535
|
-
hideWindowTitle: false,
|
|
1536
|
-
},
|
|
1537
|
-
});
|
|
1538
|
-
// Mock CLI_TITLE environment variable
|
|
1539
|
-
vi.stubEnv('CLI_TITLE', 'Custom Gemini Title');
|
|
1540
|
-
// Mock the streaming state
|
|
1541
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1542
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1543
|
-
streamingState: 'responding',
|
|
1544
|
-
});
|
|
1545
|
-
// Act: Render the container
|
|
1546
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
1547
|
-
settings: mockSettingsWithTitleDisabled,
|
|
1548
|
-
}));
|
|
1549
|
-
// Assert: Check that title was updated with CLI_TITLE value
|
|
1550
|
-
const titleWrites = mocks.mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]0;'));
|
|
1551
|
-
expect(titleWrites).toHaveLength(1);
|
|
1552
|
-
expect(titleWrites[0][0]).toBe(`\x1b]0;${'✦ Working… (Custom Gemini Title)'.padEnd(80, ' ')}\x07`);
|
|
1553
|
-
unmount();
|
|
1554
|
-
});
|
|
1555
|
-
});
|
|
1556
|
-
describe('Queue Error Message', () => {
|
|
1557
|
-
beforeEach(() => {
|
|
1558
|
-
vi.useFakeTimers();
|
|
1559
|
-
});
|
|
1560
|
-
afterEach(() => {
|
|
1561
|
-
vi.useRealTimers();
|
|
1562
|
-
vi.restoreAllMocks();
|
|
1563
|
-
});
|
|
1564
|
-
it('should set and clear the queue error message after a timeout', async () => {
|
|
1565
|
-
const { rerender, unmount } = await act(async () => renderAppContainer());
|
|
1566
|
-
await act(async () => {
|
|
1567
|
-
vi.advanceTimersByTime(0);
|
|
1568
|
-
});
|
|
1569
|
-
expect(capturedUIState.queueErrorMessage).toBeNull();
|
|
1570
|
-
act(() => {
|
|
1571
|
-
capturedUIActions.setQueueErrorMessage('Test error');
|
|
1572
|
-
});
|
|
1573
|
-
rerender(getAppContainer());
|
|
1574
|
-
expect(capturedUIState.queueErrorMessage).toBe('Test error');
|
|
1575
|
-
act(() => {
|
|
1576
|
-
vi.advanceTimersByTime(3000);
|
|
1577
|
-
});
|
|
1578
|
-
rerender(getAppContainer());
|
|
1579
|
-
expect(capturedUIState.queueErrorMessage).toBeNull();
|
|
1580
|
-
unmount();
|
|
1581
|
-
});
|
|
1582
|
-
it('should reset the timer if a new error message is set', async () => {
|
|
1583
|
-
const { rerender, unmount } = await act(async () => renderAppContainer());
|
|
1584
|
-
await act(async () => {
|
|
1585
|
-
vi.advanceTimersByTime(0);
|
|
1586
|
-
});
|
|
1587
|
-
act(() => {
|
|
1588
|
-
capturedUIActions.setQueueErrorMessage('First error');
|
|
1589
|
-
});
|
|
1590
|
-
rerender(getAppContainer());
|
|
1591
|
-
expect(capturedUIState.queueErrorMessage).toBe('First error');
|
|
1592
|
-
act(() => {
|
|
1593
|
-
vi.advanceTimersByTime(1500);
|
|
1594
|
-
});
|
|
1595
|
-
act(() => {
|
|
1596
|
-
capturedUIActions.setQueueErrorMessage('Second error');
|
|
1597
|
-
});
|
|
1598
|
-
rerender(getAppContainer());
|
|
1599
|
-
expect(capturedUIState.queueErrorMessage).toBe('Second error');
|
|
1600
|
-
act(() => {
|
|
1601
|
-
vi.advanceTimersByTime(2000);
|
|
1602
|
-
});
|
|
1603
|
-
rerender(getAppContainer());
|
|
1604
|
-
expect(capturedUIState.queueErrorMessage).toBe('Second error');
|
|
1605
|
-
// 5. Advance time past the 3 second timeout from the second message
|
|
1606
|
-
act(() => {
|
|
1607
|
-
vi.advanceTimersByTime(1000);
|
|
1608
|
-
});
|
|
1609
|
-
rerender(getAppContainer());
|
|
1610
|
-
expect(capturedUIState.queueErrorMessage).toBeNull();
|
|
1611
|
-
unmount();
|
|
1612
|
-
});
|
|
1613
|
-
});
|
|
1614
|
-
describe('Keyboard Input Handling (CTRL+C / CTRL+D)', () => {
|
|
1615
|
-
let mockHandleSlashCommand;
|
|
1616
|
-
let mockCancelOngoingRequest;
|
|
1617
|
-
let rerender;
|
|
1618
|
-
let unmount;
|
|
1619
|
-
let stdin;
|
|
1620
|
-
// Helper function to reduce boilerplate in tests
|
|
1621
|
-
const setupKeypressTest = async () => {
|
|
1622
|
-
const renderResult = await act(async () => renderAppContainer());
|
|
1623
|
-
stdin = renderResult.stdin;
|
|
1624
|
-
await act(async () => {
|
|
1625
|
-
vi.advanceTimersByTime(0);
|
|
1626
|
-
});
|
|
1627
|
-
rerender = () => {
|
|
1628
|
-
renderResult.rerender(getAppContainer());
|
|
1629
|
-
};
|
|
1630
|
-
unmount = renderResult.unmount;
|
|
1631
|
-
};
|
|
1632
|
-
const pressKey = (sequence, times = 1) => {
|
|
1633
|
-
for (let i = 0; i < times; i++) {
|
|
1634
|
-
act(() => {
|
|
1635
|
-
stdin.write(sequence);
|
|
1636
|
-
});
|
|
1637
|
-
rerender();
|
|
1638
|
-
}
|
|
1639
|
-
};
|
|
1640
|
-
beforeEach(() => {
|
|
1641
|
-
// Mock slash command handler
|
|
1642
|
-
mockHandleSlashCommand = vi.fn();
|
|
1643
|
-
mockedUseSlashCommandProcessor.mockReturnValue({
|
|
1644
|
-
handleSlashCommand: mockHandleSlashCommand,
|
|
1645
|
-
slashCommands: [],
|
|
1646
|
-
pendingHistoryItems: [],
|
|
1647
|
-
commandContext: {},
|
|
1648
|
-
shellConfirmationRequest: null,
|
|
1649
|
-
confirmationRequest: null,
|
|
1650
|
-
});
|
|
1651
|
-
// Mock request cancellation
|
|
1652
|
-
mockCancelOngoingRequest = vi.fn();
|
|
1653
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1654
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1655
|
-
cancelOngoingRequest: mockCancelOngoingRequest,
|
|
1656
|
-
});
|
|
1657
|
-
// Default empty text buffer
|
|
1658
|
-
mockedUseTextBuffer.mockReturnValue({
|
|
1659
|
-
text: '',
|
|
1660
|
-
setText: vi.fn(),
|
|
1661
|
-
lines: [''],
|
|
1662
|
-
cursor: [0, 0],
|
|
1663
|
-
handleInput: vi.fn().mockReturnValue(false),
|
|
1664
|
-
});
|
|
1665
|
-
vi.useFakeTimers();
|
|
1666
|
-
});
|
|
1667
|
-
afterEach(() => {
|
|
1668
|
-
vi.useRealTimers();
|
|
1669
|
-
vi.restoreAllMocks();
|
|
1670
|
-
});
|
|
1671
|
-
describe('CTRL+C', () => {
|
|
1672
|
-
it('should cancel ongoing request on first press', async () => {
|
|
1673
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1674
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1675
|
-
streamingState: 'responding',
|
|
1676
|
-
cancelOngoingRequest: mockCancelOngoingRequest,
|
|
1677
|
-
});
|
|
1678
|
-
await setupKeypressTest();
|
|
1679
|
-
pressKey('\x03'); // Ctrl+C
|
|
1680
|
-
expect(mockCancelOngoingRequest).toHaveBeenCalledTimes(1);
|
|
1681
|
-
expect(mockHandleSlashCommand).not.toHaveBeenCalled();
|
|
1682
|
-
unmount();
|
|
1683
|
-
});
|
|
1684
|
-
it('should quit on second press', async () => {
|
|
1685
|
-
await setupKeypressTest();
|
|
1686
|
-
pressKey('\x03', 2); // Ctrl+C
|
|
1687
|
-
expect(mockCancelOngoingRequest).toHaveBeenCalledTimes(2);
|
|
1688
|
-
expect(mockHandleSlashCommand).toHaveBeenCalledWith('/quit', undefined, undefined, false);
|
|
1689
|
-
unmount();
|
|
1690
|
-
});
|
|
1691
|
-
it('should reset press count after a timeout', async () => {
|
|
1692
|
-
await setupKeypressTest();
|
|
1693
|
-
pressKey('\x03'); // Ctrl+C
|
|
1694
|
-
expect(mockHandleSlashCommand).not.toHaveBeenCalled();
|
|
1695
|
-
// Advance timer past the reset threshold
|
|
1696
|
-
act(() => {
|
|
1697
|
-
vi.advanceTimersByTime(WARNING_PROMPT_DURATION_MS + 1);
|
|
1698
|
-
});
|
|
1699
|
-
pressKey('\x03'); // Ctrl+C
|
|
1700
|
-
expect(mockHandleSlashCommand).not.toHaveBeenCalled();
|
|
1701
|
-
unmount();
|
|
1702
|
-
});
|
|
1703
|
-
});
|
|
1704
|
-
describe('CTRL+D', () => {
|
|
1705
|
-
it('should quit on second press if buffer is empty', async () => {
|
|
1706
|
-
await setupKeypressTest();
|
|
1707
|
-
pressKey('\x04', 2); // Ctrl+D
|
|
1708
|
-
expect(mockHandleSlashCommand).toHaveBeenCalledWith('/quit', undefined, undefined, false);
|
|
1709
|
-
unmount();
|
|
1710
|
-
});
|
|
1711
|
-
it('should NOT quit if buffer is not empty', async () => {
|
|
1712
|
-
mockedUseTextBuffer.mockReturnValue({
|
|
1713
|
-
text: 'some text',
|
|
1714
|
-
setText: vi.fn(),
|
|
1715
|
-
lines: ['some text'],
|
|
1716
|
-
cursor: [0, 9], // At the end
|
|
1717
|
-
handleInput: vi.fn().mockReturnValue(false),
|
|
1718
|
-
});
|
|
1719
|
-
await setupKeypressTest();
|
|
1720
|
-
pressKey('\x04'); // Ctrl+D
|
|
1721
|
-
// Should only be called once, so count is 1, not quitting yet.
|
|
1722
|
-
expect(mockHandleSlashCommand).not.toHaveBeenCalled();
|
|
1723
|
-
pressKey('\x04'); // Ctrl+D
|
|
1724
|
-
// It should still not quit because buffer is non-empty.
|
|
1725
|
-
expect(mockHandleSlashCommand).not.toHaveBeenCalled();
|
|
1726
|
-
unmount();
|
|
1727
|
-
});
|
|
1728
|
-
it('should reset press count after a timeout', async () => {
|
|
1729
|
-
await setupKeypressTest();
|
|
1730
|
-
pressKey('\x04'); // Ctrl+D
|
|
1731
|
-
expect(mockHandleSlashCommand).not.toHaveBeenCalled();
|
|
1732
|
-
// Advance timer past the reset threshold
|
|
1733
|
-
act(() => {
|
|
1734
|
-
vi.advanceTimersByTime(WARNING_PROMPT_DURATION_MS + 1);
|
|
1735
|
-
});
|
|
1736
|
-
pressKey('\x04'); // Ctrl+D
|
|
1737
|
-
expect(mockHandleSlashCommand).not.toHaveBeenCalled();
|
|
1738
|
-
unmount();
|
|
1739
|
-
});
|
|
1740
|
-
});
|
|
1741
|
-
describe('CTRL+Z', () => {
|
|
1742
|
-
it('should call handleSuspend', async () => {
|
|
1743
|
-
const handleSuspend = vi.fn();
|
|
1744
|
-
mockedUseSuspend.mockReturnValue({ handleSuspend });
|
|
1745
|
-
await setupKeypressTest();
|
|
1746
|
-
pressKey('\x1A'); // Ctrl+Z
|
|
1747
|
-
expect(handleSuspend).toHaveBeenCalledTimes(1);
|
|
1748
|
-
unmount();
|
|
1749
|
-
});
|
|
1750
|
-
});
|
|
1751
|
-
describe('Focus Handling (Tab / Shift+Tab)', () => {
|
|
1752
|
-
beforeEach(() => {
|
|
1753
|
-
// Mock activePtyId to enable focus
|
|
1754
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1755
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1756
|
-
activePtyId: 1,
|
|
1757
|
-
});
|
|
1758
|
-
});
|
|
1759
|
-
it('should focus shell input on Tab', async () => {
|
|
1760
|
-
await setupKeypressTest();
|
|
1761
|
-
pressKey('\t');
|
|
1762
|
-
expect(capturedUIState.embeddedShellFocused).toBe(true);
|
|
1763
|
-
unmount();
|
|
1764
|
-
});
|
|
1765
|
-
it('should unfocus shell input on Shift+Tab', async () => {
|
|
1766
|
-
await setupKeypressTest();
|
|
1767
|
-
// Focus first
|
|
1768
|
-
pressKey('\t');
|
|
1769
|
-
expect(capturedUIState.embeddedShellFocused).toBe(true);
|
|
1770
|
-
// Unfocus via Shift+Tab
|
|
1771
|
-
pressKey('\x1b[Z');
|
|
1772
|
-
expect(capturedUIState.embeddedShellFocused).toBe(false);
|
|
1773
|
-
unmount();
|
|
1774
|
-
});
|
|
1775
|
-
it('should auto-unfocus when activePtyId becomes null', async () => {
|
|
1776
|
-
// Start with active pty and focused
|
|
1777
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1778
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1779
|
-
activePtyId: 1,
|
|
1780
|
-
});
|
|
1781
|
-
const renderResult = await act(async () => render(getAppContainer()));
|
|
1782
|
-
await act(async () => {
|
|
1783
|
-
vi.advanceTimersByTime(0);
|
|
1784
|
-
});
|
|
1785
|
-
// Focus it
|
|
1786
|
-
act(() => {
|
|
1787
|
-
renderResult.stdin.write('\t');
|
|
1788
|
-
});
|
|
1789
|
-
expect(capturedUIState.embeddedShellFocused).toBe(true);
|
|
1790
|
-
// Now mock activePtyId becoming null
|
|
1791
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1792
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1793
|
-
activePtyId: null,
|
|
1794
|
-
});
|
|
1795
|
-
// Rerender to trigger useEffect
|
|
1796
|
-
await act(async () => {
|
|
1797
|
-
renderResult.rerender(getAppContainer());
|
|
1798
|
-
});
|
|
1799
|
-
expect(capturedUIState.embeddedShellFocused).toBe(false);
|
|
1800
|
-
renderResult.unmount();
|
|
1801
|
-
});
|
|
1802
|
-
it('should focus background shell on Tab when already visible (not toggle it off)', async () => {
|
|
1803
|
-
const mockToggleBackgroundTask = vi.fn();
|
|
1804
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1805
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1806
|
-
activePtyId: null,
|
|
1807
|
-
isBackgroundTaskVisible: true,
|
|
1808
|
-
backgroundTasks: new Map([[123, { pid: 123, status: 'running' }]]),
|
|
1809
|
-
toggleBackgroundTasks: mockToggleBackgroundTask,
|
|
1810
|
-
});
|
|
1811
|
-
await setupKeypressTest();
|
|
1812
|
-
// Initially not focused
|
|
1813
|
-
expect(capturedUIState.embeddedShellFocused).toBe(false);
|
|
1814
|
-
// Press Tab
|
|
1815
|
-
pressKey('\t');
|
|
1816
|
-
// Should be focused
|
|
1817
|
-
expect(capturedUIState.embeddedShellFocused).toBe(true);
|
|
1818
|
-
// Should NOT have toggled (closed) the shell
|
|
1819
|
-
expect(mockToggleBackgroundTask).not.toHaveBeenCalled();
|
|
1820
|
-
unmount();
|
|
1821
|
-
});
|
|
1822
|
-
});
|
|
1823
|
-
describe('Background Shell Toggling (CTRL+B)', () => {
|
|
1824
|
-
it('should toggle background shell on Ctrl+B even if visible but not focused', async () => {
|
|
1825
|
-
const mockToggleBackgroundTask = vi.fn();
|
|
1826
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1827
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1828
|
-
activePtyId: null,
|
|
1829
|
-
isBackgroundTaskVisible: true,
|
|
1830
|
-
backgroundTasks: new Map([[123, { pid: 123, status: 'running' }]]),
|
|
1831
|
-
toggleBackgroundTasks: mockToggleBackgroundTask,
|
|
1832
|
-
});
|
|
1833
|
-
await setupKeypressTest();
|
|
1834
|
-
// Initially not focused, but visible
|
|
1835
|
-
expect(capturedUIState.embeddedShellFocused).toBe(false);
|
|
1836
|
-
// Press Ctrl+B
|
|
1837
|
-
pressKey('\x02');
|
|
1838
|
-
// Should have toggled (closed) the shell
|
|
1839
|
-
expect(mockToggleBackgroundTask).toHaveBeenCalled();
|
|
1840
|
-
// Should be unfocused
|
|
1841
|
-
expect(capturedUIState.embeddedShellFocused).toBe(false);
|
|
1842
|
-
unmount();
|
|
1843
|
-
});
|
|
1844
|
-
it('should show and focus background shell on Ctrl+B if hidden', async () => {
|
|
1845
|
-
const mockToggleBackgroundTask = vi.fn();
|
|
1846
|
-
const geminiStreamMock = {
|
|
1847
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1848
|
-
activePtyId: null,
|
|
1849
|
-
isBackgroundTaskVisible: false,
|
|
1850
|
-
backgroundTasks: new Map([[123, { pid: 123, status: 'running' }]]),
|
|
1851
|
-
toggleBackgroundTasks: mockToggleBackgroundTask,
|
|
1852
|
-
};
|
|
1853
|
-
mockedUseGeminiStream.mockReturnValue(geminiStreamMock);
|
|
1854
|
-
await setupKeypressTest();
|
|
1855
|
-
// Update the mock state when toggled to simulate real behavior
|
|
1856
|
-
mockToggleBackgroundTask.mockImplementation(() => {
|
|
1857
|
-
geminiStreamMock.isBackgroundTaskVisible = true;
|
|
1858
|
-
});
|
|
1859
|
-
// Press Ctrl+B
|
|
1860
|
-
pressKey('\x02');
|
|
1861
|
-
// Should have toggled (shown) the shell
|
|
1862
|
-
expect(mockToggleBackgroundTask).toHaveBeenCalled();
|
|
1863
|
-
// Should be focused
|
|
1864
|
-
expect(capturedUIState.embeddedShellFocused).toBe(true);
|
|
1865
|
-
unmount();
|
|
1866
|
-
});
|
|
1867
|
-
});
|
|
1868
|
-
});
|
|
1869
|
-
describe('Shortcuts Help Visibility', () => {
|
|
1870
|
-
let handleGlobalKeypress;
|
|
1871
|
-
let mockedUseKeypress;
|
|
1872
|
-
let rerender;
|
|
1873
|
-
let unmount;
|
|
1874
|
-
const setupShortcutsVisibilityTest = async () => {
|
|
1875
|
-
const renderResult = await act(async () => renderAppContainer());
|
|
1876
|
-
await act(async () => {
|
|
1877
|
-
vi.advanceTimersByTime(0);
|
|
1878
|
-
});
|
|
1879
|
-
rerender = () => renderResult.rerender(getAppContainer());
|
|
1880
|
-
unmount = renderResult.unmount;
|
|
1881
|
-
};
|
|
1882
|
-
const pressKey = (key) => {
|
|
1883
|
-
act(() => {
|
|
1884
|
-
handleGlobalKeypress({
|
|
1885
|
-
name: 'r',
|
|
1886
|
-
shift: false,
|
|
1887
|
-
alt: false,
|
|
1888
|
-
ctrl: false,
|
|
1889
|
-
cmd: false,
|
|
1890
|
-
insertable: false,
|
|
1891
|
-
sequence: '',
|
|
1892
|
-
...key,
|
|
1893
|
-
});
|
|
1894
|
-
});
|
|
1895
|
-
rerender();
|
|
1896
|
-
};
|
|
1897
|
-
beforeEach(() => {
|
|
1898
|
-
mockedUseKeypress = vi.spyOn(useKeypressModule, 'useKeypress');
|
|
1899
|
-
mockedUseKeypress.mockImplementation((callback, options) => {
|
|
1900
|
-
// AppContainer registers multiple keypress handlers; capture only
|
|
1901
|
-
// active handlers so inactive copy-mode handler doesn't override.
|
|
1902
|
-
if (options?.isActive) {
|
|
1903
|
-
handleGlobalKeypress = callback;
|
|
1904
|
-
}
|
|
1905
|
-
});
|
|
1906
|
-
vi.useFakeTimers();
|
|
1907
|
-
});
|
|
1908
|
-
afterEach(() => {
|
|
1909
|
-
mockedUseKeypress.mockRestore();
|
|
1910
|
-
vi.useRealTimers();
|
|
1911
|
-
vi.restoreAllMocks();
|
|
1912
|
-
});
|
|
1913
|
-
it('dismisses shortcuts help when a registered hotkey is pressed', async () => {
|
|
1914
|
-
await setupShortcutsVisibilityTest();
|
|
1915
|
-
act(() => {
|
|
1916
|
-
capturedUIActions.setShortcutsHelpVisible(true);
|
|
1917
|
-
});
|
|
1918
|
-
rerender();
|
|
1919
|
-
expect(capturedUIState.shortcutsHelpVisible).toBe(true);
|
|
1920
|
-
pressKey({ name: 'r', ctrl: true, sequence: '\x12' }); // Ctrl+R
|
|
1921
|
-
expect(capturedUIState.shortcutsHelpVisible).toBe(false);
|
|
1922
|
-
unmount();
|
|
1923
|
-
});
|
|
1924
|
-
it('dismisses shortcuts help when streaming starts', async () => {
|
|
1925
|
-
await setupShortcutsVisibilityTest();
|
|
1926
|
-
act(() => {
|
|
1927
|
-
capturedUIActions.setShortcutsHelpVisible(true);
|
|
1928
|
-
});
|
|
1929
|
-
rerender();
|
|
1930
|
-
expect(capturedUIState.shortcutsHelpVisible).toBe(true);
|
|
1931
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
1932
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
1933
|
-
streamingState: 'responding',
|
|
1934
|
-
});
|
|
1935
|
-
await act(async () => {
|
|
1936
|
-
rerender();
|
|
1937
|
-
});
|
|
1938
|
-
expect(capturedUIState.shortcutsHelpVisible).toBe(false);
|
|
1939
|
-
unmount();
|
|
1940
|
-
});
|
|
1941
|
-
it('dismisses shortcuts help when action-required confirmation appears', async () => {
|
|
1942
|
-
await setupShortcutsVisibilityTest();
|
|
1943
|
-
act(() => {
|
|
1944
|
-
capturedUIActions.setShortcutsHelpVisible(true);
|
|
1945
|
-
});
|
|
1946
|
-
rerender();
|
|
1947
|
-
expect(capturedUIState.shortcutsHelpVisible).toBe(true);
|
|
1948
|
-
mockedUseSlashCommandProcessor.mockReturnValue({
|
|
1949
|
-
handleSlashCommand: vi.fn(),
|
|
1950
|
-
slashCommands: [],
|
|
1951
|
-
pendingHistoryItems: [],
|
|
1952
|
-
commandContext: {},
|
|
1953
|
-
shellConfirmationRequest: null,
|
|
1954
|
-
confirmationRequest: {
|
|
1955
|
-
prompt: 'Confirm this action?',
|
|
1956
|
-
onConfirm: vi.fn(),
|
|
1957
|
-
},
|
|
1958
|
-
});
|
|
1959
|
-
await act(async () => {
|
|
1960
|
-
rerender();
|
|
1961
|
-
});
|
|
1962
|
-
expect(capturedUIState.shortcutsHelpVisible).toBe(false);
|
|
1963
|
-
unmount();
|
|
1964
|
-
});
|
|
1965
|
-
});
|
|
1966
|
-
describe('Copy Mode (F9)', () => {
|
|
1967
|
-
let rerender;
|
|
1968
|
-
let unmount;
|
|
1969
|
-
let stdin;
|
|
1970
|
-
const setupCopyModeTest = async (isAlternateMode = false, childHandler) => {
|
|
1971
|
-
vi.spyOn(mockConfig, 'getUseTerminalBuffer').mockReturnValue(false);
|
|
1972
|
-
vi.spyOn(mockConfig, 'getUseAlternateBuffer').mockReturnValue(isAlternateMode);
|
|
1973
|
-
// Update settings for this test run
|
|
1974
|
-
const testSettings = createMockSettings({
|
|
1975
|
-
ui: { useAlternateBuffer: isAlternateMode },
|
|
1976
|
-
});
|
|
1977
|
-
function TestChild() {
|
|
1978
|
-
useKeypress(childHandler || (() => { }), {
|
|
1979
|
-
isActive: !!childHandler,
|
|
1980
|
-
priority: true,
|
|
1981
|
-
});
|
|
1982
|
-
return null;
|
|
1983
|
-
}
|
|
1984
|
-
const getTree = (settings) => (_jsx(SettingsContext.Provider, { value: settings, children: _jsx(KeypressProvider, { config: mockConfig, children: _jsxs(OverflowProvider, { children: [_jsx(AppContainer, { config: mockConfig, version: "1.0.0", initializationResult: mockInitResult }), _jsx(TestChild, {})] }) }) }));
|
|
1985
|
-
const renderResult = await act(async () => render(getTree(testSettings)));
|
|
1986
|
-
stdin = renderResult.stdin;
|
|
1987
|
-
await act(async () => {
|
|
1988
|
-
vi.advanceTimersByTime(0);
|
|
1989
|
-
});
|
|
1990
|
-
rerender = () => renderResult.rerender(getTree(testSettings));
|
|
1991
|
-
unmount = renderResult.unmount;
|
|
1992
|
-
};
|
|
1993
|
-
beforeEach(() => {
|
|
1994
|
-
mocks.mockStdout.write.mockClear();
|
|
1995
|
-
disableMouseEvents.mockClear();
|
|
1996
|
-
vi.useFakeTimers();
|
|
1997
|
-
});
|
|
1998
|
-
afterEach(() => {
|
|
1999
|
-
vi.useRealTimers();
|
|
2000
|
-
vi.restoreAllMocks();
|
|
2001
|
-
});
|
|
2002
|
-
describe.each([
|
|
2003
|
-
{
|
|
2004
|
-
isAlternateMode: false,
|
|
2005
|
-
shouldEnable: false,
|
|
2006
|
-
modeName: 'Normal Mode',
|
|
2007
|
-
},
|
|
2008
|
-
{
|
|
2009
|
-
isAlternateMode: true,
|
|
2010
|
-
shouldEnable: true,
|
|
2011
|
-
modeName: 'Alternate Buffer Mode',
|
|
2012
|
-
},
|
|
2013
|
-
])('$modeName', ({ isAlternateMode, shouldEnable }) => {
|
|
2014
|
-
it(`should ${shouldEnable ? 'toggle' : 'NOT toggle'} mouse off when F9 is pressed`, async () => {
|
|
2015
|
-
await setupCopyModeTest(isAlternateMode);
|
|
2016
|
-
mocks.mockStdout.write.mockClear(); // Clear initial enable call
|
|
2017
|
-
disableMouseEvents.mockClear();
|
|
2018
|
-
act(() => {
|
|
2019
|
-
stdin.write('\x1b[20~'); // F9
|
|
2020
|
-
});
|
|
2021
|
-
rerender();
|
|
2022
|
-
if (shouldEnable) {
|
|
2023
|
-
expect(disableMouseEvents).toHaveBeenCalled();
|
|
2024
|
-
}
|
|
2025
|
-
else {
|
|
2026
|
-
expect(disableMouseEvents).not.toHaveBeenCalled();
|
|
2027
|
-
}
|
|
2028
|
-
unmount();
|
|
2029
|
-
});
|
|
2030
|
-
if (shouldEnable) {
|
|
2031
|
-
it('should toggle mouse back on when F9 is pressed again', async () => {
|
|
2032
|
-
await setupCopyModeTest(isAlternateMode);
|
|
2033
|
-
writeToStdout.mockClear();
|
|
2034
|
-
// Turn it on (disable mouse)
|
|
2035
|
-
act(() => {
|
|
2036
|
-
stdin.write('\x1b[20~'); // F9
|
|
2037
|
-
});
|
|
2038
|
-
rerender();
|
|
2039
|
-
expect(disableMouseEvents).toHaveBeenCalled();
|
|
2040
|
-
// Turn it off (enable mouse)
|
|
2041
|
-
act(() => {
|
|
2042
|
-
stdin.write('a'); // Any key should exit copy mode
|
|
2043
|
-
});
|
|
2044
|
-
rerender();
|
|
2045
|
-
expect(enableMouseEvents).toHaveBeenCalled();
|
|
2046
|
-
unmount();
|
|
2047
|
-
});
|
|
2048
|
-
it('should exit copy mode on non-scroll key press', async () => {
|
|
2049
|
-
await setupCopyModeTest(isAlternateMode);
|
|
2050
|
-
// Enter copy mode
|
|
2051
|
-
act(() => {
|
|
2052
|
-
stdin.write('\x1b[20~'); // F9
|
|
2053
|
-
});
|
|
2054
|
-
rerender();
|
|
2055
|
-
writeToStdout.mockClear();
|
|
2056
|
-
// Press any other key
|
|
2057
|
-
act(() => {
|
|
2058
|
-
stdin.write('a');
|
|
2059
|
-
});
|
|
2060
|
-
rerender();
|
|
2061
|
-
// Should have re-enabled mouse
|
|
2062
|
-
expect(enableMouseEvents).toHaveBeenCalled();
|
|
2063
|
-
unmount();
|
|
2064
|
-
});
|
|
2065
|
-
it('should not exit copy mode on PageDown and should pass it through', async () => {
|
|
2066
|
-
const childHandler = vi.fn().mockReturnValue(false);
|
|
2067
|
-
await setupCopyModeTest(true, childHandler);
|
|
2068
|
-
// Enter copy mode
|
|
2069
|
-
act(() => {
|
|
2070
|
-
stdin.write('\x13'); // Ctrl+S
|
|
2071
|
-
});
|
|
2072
|
-
rerender();
|
|
2073
|
-
expect(disableMouseEvents).toHaveBeenCalled();
|
|
2074
|
-
childHandler.mockClear();
|
|
2075
|
-
enableMouseEvents.mockClear();
|
|
2076
|
-
// PageDown should be passed through to lower-priority handlers.
|
|
2077
|
-
act(() => {
|
|
2078
|
-
stdin.write('\x1b[6~');
|
|
2079
|
-
});
|
|
2080
|
-
rerender();
|
|
2081
|
-
expect(enableMouseEvents).not.toHaveBeenCalled();
|
|
2082
|
-
expect(childHandler).toHaveBeenCalled();
|
|
2083
|
-
expect(childHandler).toHaveBeenCalledWith(expect.objectContaining({ name: 'pagedown' }));
|
|
2084
|
-
unmount();
|
|
2085
|
-
});
|
|
2086
|
-
it('should not exit copy mode on Shift+Down and should pass it through', async () => {
|
|
2087
|
-
const childHandler = vi.fn().mockReturnValue(false);
|
|
2088
|
-
await setupCopyModeTest(true, childHandler);
|
|
2089
|
-
// Enter copy mode
|
|
2090
|
-
act(() => {
|
|
2091
|
-
stdin.write('\x13'); // Ctrl+S
|
|
2092
|
-
});
|
|
2093
|
-
rerender();
|
|
2094
|
-
expect(disableMouseEvents).toHaveBeenCalled();
|
|
2095
|
-
childHandler.mockClear();
|
|
2096
|
-
enableMouseEvents.mockClear();
|
|
2097
|
-
act(() => {
|
|
2098
|
-
stdin.write('\x1b[1;2B'); // Shift+Down
|
|
2099
|
-
});
|
|
2100
|
-
rerender();
|
|
2101
|
-
expect(enableMouseEvents).not.toHaveBeenCalled();
|
|
2102
|
-
expect(childHandler).toHaveBeenCalled();
|
|
2103
|
-
expect(childHandler).toHaveBeenCalledWith(expect.objectContaining({ name: 'down', shift: true }));
|
|
2104
|
-
unmount();
|
|
2105
|
-
});
|
|
2106
|
-
it('should have higher priority than other priority listeners when enabled', async () => {
|
|
2107
|
-
// 1. Initial state with a child component's priority listener (already subscribed)
|
|
2108
|
-
// It should NOT handle Ctrl+S so we can enter copy mode.
|
|
2109
|
-
const childHandler = vi.fn().mockReturnValue(false);
|
|
2110
|
-
await setupCopyModeTest(true, childHandler);
|
|
2111
|
-
// 2. Enter copy mode
|
|
2112
|
-
act(() => {
|
|
2113
|
-
stdin.write('\x1b[20~'); // F9
|
|
2114
|
-
});
|
|
2115
|
-
rerender();
|
|
2116
|
-
// 3. Verify we are in copy mode
|
|
2117
|
-
expect(disableMouseEvents).toHaveBeenCalled();
|
|
2118
|
-
// 4. Press any key
|
|
2119
|
-
childHandler.mockClear();
|
|
2120
|
-
// Now childHandler should return true for other keys, simulating a greedy listener
|
|
2121
|
-
childHandler.mockReturnValue(true);
|
|
2122
|
-
act(() => {
|
|
2123
|
-
stdin.write('a');
|
|
2124
|
-
});
|
|
2125
|
-
rerender();
|
|
2126
|
-
// 5. Verify that the exit handler took priority and childHandler was NOT called
|
|
2127
|
-
expect(childHandler).not.toHaveBeenCalled();
|
|
2128
|
-
expect(enableMouseEvents).toHaveBeenCalled();
|
|
2129
|
-
unmount();
|
|
2130
|
-
});
|
|
2131
|
-
}
|
|
2132
|
-
});
|
|
2133
|
-
});
|
|
2134
|
-
describe('Model Dialog Integration', () => {
|
|
2135
|
-
it('should provide isModelDialogOpen in the UIStateContext', async () => {
|
|
2136
|
-
mockedUseModelCommand.mockReturnValue({
|
|
2137
|
-
isModelDialogOpen: true,
|
|
2138
|
-
openModelDialog: vi.fn(),
|
|
2139
|
-
closeModelDialog: vi.fn(),
|
|
2140
|
-
});
|
|
2141
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2142
|
-
expect(capturedUIState.isModelDialogOpen).toBe(true);
|
|
2143
|
-
unmount();
|
|
2144
|
-
});
|
|
2145
|
-
it('should provide model dialog actions in the UIActionsContext', async () => {
|
|
2146
|
-
const mockCloseModelDialog = vi.fn();
|
|
2147
|
-
mockedUseModelCommand.mockReturnValue({
|
|
2148
|
-
isModelDialogOpen: false,
|
|
2149
|
-
openModelDialog: vi.fn(),
|
|
2150
|
-
closeModelDialog: mockCloseModelDialog,
|
|
2151
|
-
});
|
|
2152
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2153
|
-
// Verify that the actions are correctly passed through context
|
|
2154
|
-
act(() => {
|
|
2155
|
-
capturedUIActions.closeModelDialog();
|
|
2156
|
-
});
|
|
2157
|
-
expect(mockCloseModelDialog).toHaveBeenCalled();
|
|
2158
|
-
unmount();
|
|
2159
|
-
});
|
|
2160
|
-
});
|
|
2161
|
-
describe('Agent Configuration Dialog Integration', () => {
|
|
2162
|
-
it('should initialize with dialog closed and no agent selected', async () => {
|
|
2163
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2164
|
-
expect(capturedUIState.isAgentConfigDialogOpen).toBe(false);
|
|
2165
|
-
expect(capturedUIState.selectedAgentName).toBeUndefined();
|
|
2166
|
-
expect(capturedUIState.selectedAgentDisplayName).toBeUndefined();
|
|
2167
|
-
expect(capturedUIState.selectedAgentDefinition).toBeUndefined();
|
|
2168
|
-
unmount();
|
|
2169
|
-
});
|
|
2170
|
-
it('should update state when openAgentConfigDialog is called', async () => {
|
|
2171
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2172
|
-
const agentDefinition = { name: 'test-agent' };
|
|
2173
|
-
act(() => {
|
|
2174
|
-
capturedUIActions.openAgentConfigDialog('test-agent', 'Test Agent', agentDefinition);
|
|
2175
|
-
});
|
|
2176
|
-
expect(capturedUIState.isAgentConfigDialogOpen).toBe(true);
|
|
2177
|
-
expect(capturedUIState.selectedAgentName).toBe('test-agent');
|
|
2178
|
-
expect(capturedUIState.selectedAgentDisplayName).toBe('Test Agent');
|
|
2179
|
-
expect(capturedUIState.selectedAgentDefinition).toEqual(agentDefinition);
|
|
2180
|
-
unmount();
|
|
2181
|
-
});
|
|
2182
|
-
it('should clear state when closeAgentConfigDialog is called', async () => {
|
|
2183
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2184
|
-
const agentDefinition = { name: 'test-agent' };
|
|
2185
|
-
act(() => {
|
|
2186
|
-
capturedUIActions.openAgentConfigDialog('test-agent', 'Test Agent', agentDefinition);
|
|
2187
|
-
});
|
|
2188
|
-
expect(capturedUIState.isAgentConfigDialogOpen).toBe(true);
|
|
2189
|
-
act(() => {
|
|
2190
|
-
capturedUIActions.closeAgentConfigDialog();
|
|
2191
|
-
});
|
|
2192
|
-
expect(capturedUIState.isAgentConfigDialogOpen).toBe(false);
|
|
2193
|
-
expect(capturedUIState.selectedAgentName).toBeUndefined();
|
|
2194
|
-
expect(capturedUIState.selectedAgentDisplayName).toBeUndefined();
|
|
2195
|
-
expect(capturedUIState.selectedAgentDefinition).toBeUndefined();
|
|
2196
|
-
unmount();
|
|
2197
|
-
});
|
|
2198
|
-
});
|
|
2199
|
-
describe('CoreEvents Integration', () => {
|
|
2200
|
-
it('subscribes to UserFeedback and drains backlog on mount', async () => {
|
|
2201
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2202
|
-
expect(mockCoreEvents.on).toHaveBeenCalledWith(CoreEvent.UserFeedback, expect.any(Function));
|
|
2203
|
-
expect(mockCoreEvents.drainBacklogs).toHaveBeenCalledTimes(1);
|
|
2204
|
-
unmount();
|
|
2205
|
-
});
|
|
2206
|
-
it('unsubscribes from UserFeedback on unmount', async () => {
|
|
2207
|
-
let unmount;
|
|
2208
|
-
await act(async () => {
|
|
2209
|
-
const result = await renderAppContainer();
|
|
2210
|
-
unmount = result.unmount;
|
|
2211
|
-
});
|
|
2212
|
-
await waitFor(() => expect(capturedUIState).toBeTruthy());
|
|
2213
|
-
unmount();
|
|
2214
|
-
expect(mockCoreEvents.off).toHaveBeenCalledWith(CoreEvent.UserFeedback, expect.any(Function));
|
|
2215
|
-
});
|
|
2216
|
-
it('adds history item when UserFeedback event is received', async () => {
|
|
2217
|
-
let unmount;
|
|
2218
|
-
await act(async () => {
|
|
2219
|
-
const result = await renderAppContainer();
|
|
2220
|
-
unmount = result.unmount;
|
|
2221
|
-
});
|
|
2222
|
-
await waitFor(() => expect(capturedUIState).toBeTruthy());
|
|
2223
|
-
// Get the registered handler
|
|
2224
|
-
const handler = mockCoreEvents.on.mock.calls.find((call) => call[0] === CoreEvent.UserFeedback)?.[1];
|
|
2225
|
-
expect(handler).toBeDefined();
|
|
2226
|
-
// Simulate an event
|
|
2227
|
-
const payload = {
|
|
2228
|
-
severity: 'error',
|
|
2229
|
-
message: 'Test error message',
|
|
2230
|
-
};
|
|
2231
|
-
act(() => {
|
|
2232
|
-
handler(payload);
|
|
2233
|
-
});
|
|
2234
|
-
expect(mockedUseHistory().addItem).toHaveBeenCalledWith(expect.objectContaining({
|
|
2235
|
-
type: 'error',
|
|
2236
|
-
text: 'Test error message',
|
|
2237
|
-
}), expect.any(Number));
|
|
2238
|
-
unmount();
|
|
2239
|
-
});
|
|
2240
|
-
it('updates currentModel when ModelChanged event is received', async () => {
|
|
2241
|
-
// Arrange: Mock initial model
|
|
2242
|
-
vi.spyOn(mockConfig, 'getModel').mockReturnValue('initial-model');
|
|
2243
|
-
let unmount;
|
|
2244
|
-
await act(async () => {
|
|
2245
|
-
const result = await renderAppContainer();
|
|
2246
|
-
unmount = result.unmount;
|
|
2247
|
-
});
|
|
2248
|
-
await waitFor(() => {
|
|
2249
|
-
expect(capturedUIState?.currentModel).toBe('initial-model');
|
|
2250
|
-
});
|
|
2251
|
-
// Get the registered handler for ModelChanged
|
|
2252
|
-
const handler = mockCoreEvents.on.mock.calls.find((call) => call[0] === CoreEvent.ModelChanged)?.[1];
|
|
2253
|
-
expect(handler).toBeDefined();
|
|
2254
|
-
// Act: Simulate ModelChanged event
|
|
2255
|
-
// Update config mock to return new model since the handler reads from config
|
|
2256
|
-
vi.spyOn(mockConfig, 'getModel').mockReturnValue('new-model');
|
|
2257
|
-
act(() => {
|
|
2258
|
-
handler({ model: 'new-model' });
|
|
2259
|
-
});
|
|
2260
|
-
// Assert: Verify model is updated
|
|
2261
|
-
await waitFor(() => {
|
|
2262
|
-
expect(capturedUIState.currentModel).toBe('new-model');
|
|
2263
|
-
});
|
|
2264
|
-
unmount();
|
|
2265
|
-
});
|
|
2266
|
-
it('provides activeHooks from useHookDisplayState', async () => {
|
|
2267
|
-
const mockHooks = [{ name: 'hook1', eventName: 'event1' }];
|
|
2268
|
-
mockedUseHookDisplayState.mockReturnValue(mockHooks);
|
|
2269
|
-
let unmount;
|
|
2270
|
-
await act(async () => {
|
|
2271
|
-
const result = await renderAppContainer();
|
|
2272
|
-
unmount = result.unmount;
|
|
2273
|
-
});
|
|
2274
|
-
await waitFor(() => expect(capturedUIState).toBeTruthy());
|
|
2275
|
-
expect(capturedUIState.activeHooks).toEqual(mockHooks);
|
|
2276
|
-
unmount();
|
|
2277
|
-
});
|
|
2278
|
-
it('handles consent request events', async () => {
|
|
2279
|
-
let unmount;
|
|
2280
|
-
await act(async () => {
|
|
2281
|
-
const result = await renderAppContainer();
|
|
2282
|
-
unmount = result.unmount;
|
|
2283
|
-
});
|
|
2284
|
-
await waitFor(() => expect(capturedUIState).toBeTruthy());
|
|
2285
|
-
const handler = mockCoreEvents.on.mock.calls.find((call) => call[0] === CoreEvent.ConsentRequest)?.[1];
|
|
2286
|
-
expect(handler).toBeDefined();
|
|
2287
|
-
const onConfirm = vi.fn();
|
|
2288
|
-
const payload = {
|
|
2289
|
-
prompt: 'Do you consent?',
|
|
2290
|
-
onConfirm,
|
|
2291
|
-
};
|
|
2292
|
-
act(() => {
|
|
2293
|
-
handler(payload);
|
|
2294
|
-
});
|
|
2295
|
-
expect(capturedUIState.authConsentRequest).toBeDefined();
|
|
2296
|
-
expect(capturedUIState.authConsentRequest?.prompt).toBe('Do you consent?');
|
|
2297
|
-
act(() => {
|
|
2298
|
-
capturedUIState.authConsentRequest?.onConfirm(true);
|
|
2299
|
-
});
|
|
2300
|
-
expect(onConfirm).toHaveBeenCalledWith(true);
|
|
2301
|
-
expect(capturedUIState.authConsentRequest).toBeNull();
|
|
2302
|
-
unmount();
|
|
2303
|
-
});
|
|
2304
|
-
it('unsubscribes from ConsentRequest on unmount', async () => {
|
|
2305
|
-
let unmount;
|
|
2306
|
-
await act(async () => {
|
|
2307
|
-
const result = await renderAppContainer();
|
|
2308
|
-
unmount = result.unmount;
|
|
2309
|
-
});
|
|
2310
|
-
await waitFor(() => expect(capturedUIState).toBeTruthy());
|
|
2311
|
-
unmount();
|
|
2312
|
-
expect(mockCoreEvents.off).toHaveBeenCalledWith(CoreEvent.ConsentRequest, expect.any(Function));
|
|
2313
|
-
});
|
|
2314
|
-
});
|
|
2315
|
-
describe('Banner Text', () => {
|
|
2316
|
-
it('should render placeholder banner text for USE_GEMINI auth type', async () => {
|
|
2317
|
-
const config = makeFakeConfig();
|
|
2318
|
-
vi.spyOn(config, 'getContentGeneratorConfig').mockReturnValue({
|
|
2319
|
-
authType: AuthType.USE_GEMINI,
|
|
2320
|
-
apiKey: 'fake-key',
|
|
2321
|
-
});
|
|
2322
|
-
let unmount;
|
|
2323
|
-
await act(async () => {
|
|
2324
|
-
const result = await renderAppContainer();
|
|
2325
|
-
unmount = result.unmount;
|
|
2326
|
-
});
|
|
2327
|
-
await waitFor(() => {
|
|
2328
|
-
expect(capturedUIState.bannerData.defaultText).toBeDefined();
|
|
2329
|
-
unmount();
|
|
2330
|
-
});
|
|
2331
|
-
});
|
|
2332
|
-
});
|
|
2333
|
-
describe('onCancelSubmit Behavior', () => {
|
|
2334
|
-
let mockSetText;
|
|
2335
|
-
// Helper to extract arguments from the useGeminiStream hook call
|
|
2336
|
-
// This isolates the positional argument dependency to a single location
|
|
2337
|
-
const extractUseGeminiStreamArgs = (args) => ({
|
|
2338
|
-
onCancelSubmit: args[13],
|
|
2339
|
-
});
|
|
2340
|
-
beforeEach(() => {
|
|
2341
|
-
mockSetText = vi.fn();
|
|
2342
|
-
mockedUseTextBuffer.mockReturnValue({
|
|
2343
|
-
text: '',
|
|
2344
|
-
setText: mockSetText,
|
|
2345
|
-
});
|
|
2346
|
-
});
|
|
2347
|
-
it('preserves buffer when cancelling, even if empty (user is in control)', async () => {
|
|
2348
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2349
|
-
const { onCancelSubmit } = extractUseGeminiStreamArgs(mockedUseGeminiStream.mock.lastCall);
|
|
2350
|
-
act(() => {
|
|
2351
|
-
onCancelSubmit(false);
|
|
2352
|
-
});
|
|
2353
|
-
// Should NOT modify buffer when cancelling - user is in control
|
|
2354
|
-
expect(mockSetText).not.toHaveBeenCalled();
|
|
2355
|
-
unmount();
|
|
2356
|
-
});
|
|
2357
|
-
it('preserves prompt text when cancelling streaming, even if same as last message (regression test for issue #13387)', async () => {
|
|
2358
|
-
// Mock buffer with text that user typed while streaming (same as last message)
|
|
2359
|
-
const promptText = 'What is Python?';
|
|
2360
|
-
mockedUseTextBuffer.mockReturnValue({
|
|
2361
|
-
text: promptText,
|
|
2362
|
-
setText: mockSetText,
|
|
2363
|
-
});
|
|
2364
|
-
// Mock input history with same message
|
|
2365
|
-
mockedUseInputHistoryStore.mockReturnValue({
|
|
2366
|
-
inputHistory: [promptText],
|
|
2367
|
-
addInput: vi.fn(),
|
|
2368
|
-
initializeFromLogger: vi.fn(),
|
|
2369
|
-
});
|
|
2370
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2371
|
-
const { onCancelSubmit } = extractUseGeminiStreamArgs(mockedUseGeminiStream.mock.lastCall);
|
|
2372
|
-
act(() => {
|
|
2373
|
-
// Simulate Escape key cancelling streaming (shouldRestorePrompt=false)
|
|
2374
|
-
onCancelSubmit(false);
|
|
2375
|
-
});
|
|
2376
|
-
// Should NOT call setText - prompt should be preserved regardless of content
|
|
2377
|
-
expect(mockSetText).not.toHaveBeenCalled();
|
|
2378
|
-
unmount();
|
|
2379
|
-
});
|
|
2380
|
-
it('restores the prompt when onCancelSubmit is called with shouldRestorePrompt=true (or undefined)', async () => {
|
|
2381
|
-
// Mock useInputHistoryStore to provide input history
|
|
2382
|
-
mockedUseInputHistoryStore.mockReturnValue({
|
|
2383
|
-
inputHistory: ['previous message'],
|
|
2384
|
-
addInput: vi.fn(),
|
|
2385
|
-
initializeFromLogger: vi.fn(),
|
|
2386
|
-
});
|
|
2387
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2388
|
-
expect(capturedInputState.userMessages).toContain('previous message');
|
|
2389
|
-
const { onCancelSubmit } = extractUseGeminiStreamArgs(mockedUseGeminiStream.mock.lastCall);
|
|
2390
|
-
await act(async () => {
|
|
2391
|
-
onCancelSubmit(true);
|
|
2392
|
-
});
|
|
2393
|
-
expect(mockSetText).toHaveBeenCalledWith('previous message');
|
|
2394
|
-
unmount();
|
|
2395
|
-
});
|
|
2396
|
-
it('input history is independent from conversation history (survives /clear)', async () => {
|
|
2397
|
-
// This test verifies that input history (used for up-arrow navigation) is maintained
|
|
2398
|
-
// separately from conversation history and survives /clear operations.
|
|
2399
|
-
const mockAddInput = vi.fn();
|
|
2400
|
-
mockedUseInputHistoryStore.mockReturnValue({
|
|
2401
|
-
inputHistory: ['first prompt', 'second prompt'],
|
|
2402
|
-
addInput: mockAddInput,
|
|
2403
|
-
initializeFromLogger: vi.fn(),
|
|
2404
|
-
});
|
|
2405
|
-
const { rerender, unmount } = await act(async () => renderAppContainer());
|
|
2406
|
-
// Verify userMessages is populated from inputHistory
|
|
2407
|
-
expect(capturedInputState.userMessages).toContain('first prompt');
|
|
2408
|
-
expect(capturedInputState.userMessages).toContain('second prompt');
|
|
2409
|
-
// Clear the conversation history (simulating /clear command)
|
|
2410
|
-
const mockClearItems = vi.fn();
|
|
2411
|
-
mockedUseHistory.mockReturnValue({
|
|
2412
|
-
history: [],
|
|
2413
|
-
addItem: vi.fn(),
|
|
2414
|
-
updateItem: vi.fn(),
|
|
2415
|
-
clearItems: mockClearItems,
|
|
2416
|
-
loadHistory: vi.fn(),
|
|
2417
|
-
});
|
|
2418
|
-
await act(async () => {
|
|
2419
|
-
// Rerender to apply the new mock.
|
|
2420
|
-
rerender(getAppContainer());
|
|
2421
|
-
});
|
|
2422
|
-
// Verify that userMessages still contains the input history
|
|
2423
|
-
// (it should not be affected by clearing conversation history)
|
|
2424
|
-
expect(capturedInputState.userMessages).toContain('first prompt');
|
|
2425
|
-
expect(capturedInputState.userMessages).toContain('second prompt');
|
|
2426
|
-
unmount();
|
|
2427
|
-
});
|
|
2428
|
-
});
|
|
2429
|
-
describe('Regression Tests', () => {
|
|
2430
|
-
it('does not refresh static on startup if banner text is empty', async () => {
|
|
2431
|
-
// Mock banner text to be empty strings
|
|
2432
|
-
vi.spyOn(mockConfig, 'getBannerTextNoCapacityIssues').mockResolvedValue('');
|
|
2433
|
-
vi.spyOn(mockConfig, 'getBannerTextCapacityIssues').mockResolvedValue('');
|
|
2434
|
-
// Clear previous calls
|
|
2435
|
-
mocks.mockStdout.write.mockClear();
|
|
2436
|
-
disableMouseEvents.mockClear();
|
|
2437
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2438
|
-
// Allow async effects to run
|
|
2439
|
-
expect(capturedUIState).toBeTruthy();
|
|
2440
|
-
// Wait for fetchBannerTexts to complete
|
|
2441
|
-
await act(async () => {
|
|
2442
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
2443
|
-
});
|
|
2444
|
-
// Check that clearTerminal was NOT written to stdout
|
|
2445
|
-
const clearTerminalCalls = mocks.mockStdout.write.mock.calls.filter((call) => call[0] === ansiEscapes.clearTerminal);
|
|
2446
|
-
expect(clearTerminalCalls).toHaveLength(0);
|
|
2447
|
-
unmount();
|
|
2448
|
-
});
|
|
2449
|
-
});
|
|
2450
|
-
describe('Submission Handling', () => {
|
|
2451
|
-
it('resets expansion state on submission when not in alternate buffer', async () => {
|
|
2452
|
-
const { checkPermissions } = await import('./hooks/atCommandProcessor.js');
|
|
2453
|
-
vi.mocked(checkPermissions).mockResolvedValue([]);
|
|
2454
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
2455
|
-
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
|
|
2456
|
-
}));
|
|
2457
|
-
expect(capturedUIActions).toBeTruthy();
|
|
2458
|
-
// Expand first
|
|
2459
|
-
act(() => capturedUIActions.setConstrainHeight(false));
|
|
2460
|
-
expect(capturedUIState.constrainHeight).toBe(false);
|
|
2461
|
-
// Reset mock stdout to clear any initial writes
|
|
2462
|
-
mocks.mockStdout.write.mockClear();
|
|
2463
|
-
disableMouseEvents.mockClear();
|
|
2464
|
-
// Submit
|
|
2465
|
-
await act(async () => capturedUIActions.handleFinalSubmit('test prompt'));
|
|
2466
|
-
// Should be reset
|
|
2467
|
-
expect(capturedUIState.constrainHeight).toBe(true);
|
|
2468
|
-
unmount();
|
|
2469
|
-
});
|
|
2470
|
-
it('resets expansion state on submission when in alternate buffer without clearing terminal', async () => {
|
|
2471
|
-
const { checkPermissions } = await import('./hooks/atCommandProcessor.js');
|
|
2472
|
-
vi.mocked(checkPermissions).mockResolvedValue([]);
|
|
2473
|
-
vi.spyOn(mockConfig, 'getUseTerminalBuffer').mockReturnValue(false);
|
|
2474
|
-
vi.spyOn(mockConfig, 'getUseAlternateBuffer').mockReturnValue(true);
|
|
2475
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
2476
|
-
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
|
|
2477
|
-
}));
|
|
2478
|
-
expect(capturedUIActions).toBeTruthy();
|
|
2479
|
-
// Expand first
|
|
2480
|
-
act(() => capturedUIActions.setConstrainHeight(false));
|
|
2481
|
-
expect(capturedUIState.constrainHeight).toBe(false);
|
|
2482
|
-
// Reset mock stdout
|
|
2483
|
-
mocks.mockStdout.write.mockClear();
|
|
2484
|
-
disableMouseEvents.mockClear();
|
|
2485
|
-
// Submit
|
|
2486
|
-
await act(async () => capturedUIActions.handleFinalSubmit('test prompt'));
|
|
2487
|
-
// Should be reset
|
|
2488
|
-
expect(capturedUIState.constrainHeight).toBe(true);
|
|
2489
|
-
// Should NOT refresh static's clearTerminal in alternate buffer
|
|
2490
|
-
expect(mocks.mockStdout.write).not.toHaveBeenCalledWith(ansiEscapes.clearTerminal);
|
|
2491
|
-
unmount();
|
|
2492
|
-
});
|
|
2493
|
-
});
|
|
2494
|
-
describe('Overflow Hint Handling', () => {
|
|
2495
|
-
beforeEach(() => {
|
|
2496
|
-
vi.useFakeTimers();
|
|
2497
|
-
});
|
|
2498
|
-
afterEach(() => {
|
|
2499
|
-
vi.useRealTimers();
|
|
2500
|
-
});
|
|
2501
|
-
it('should set showIsExpandableHint when overflow occurs in Standard Mode and hides after 10s', async () => {
|
|
2502
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2503
|
-
await waitFor(() => expect(capturedOverflowActions).toBeTruthy());
|
|
2504
|
-
// Trigger overflow
|
|
2505
|
-
act(() => {
|
|
2506
|
-
capturedOverflowActions.addOverflowingId('test-id');
|
|
2507
|
-
});
|
|
2508
|
-
await waitFor(() => {
|
|
2509
|
-
// Should show hint because we are in Standard Mode (default settings) and have overflow
|
|
2510
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2511
|
-
});
|
|
2512
|
-
// Advance just before the timeout
|
|
2513
|
-
act(() => {
|
|
2514
|
-
vi.advanceTimersByTime(EXPAND_HINT_DURATION_MS - 100);
|
|
2515
|
-
});
|
|
2516
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2517
|
-
// Advance to hit the timeout mark
|
|
2518
|
-
act(() => {
|
|
2519
|
-
vi.advanceTimersByTime(100);
|
|
2520
|
-
});
|
|
2521
|
-
await waitFor(() => {
|
|
2522
|
-
expect(capturedUIState.showIsExpandableHint).toBe(false);
|
|
2523
|
-
});
|
|
2524
|
-
unmount();
|
|
2525
|
-
});
|
|
2526
|
-
it('resets the hint timer when a new component overflows (overflowingIdsSize increases)', async () => {
|
|
2527
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2528
|
-
await waitFor(() => expect(capturedOverflowActions).toBeTruthy());
|
|
2529
|
-
// 1. Trigger first overflow
|
|
2530
|
-
act(() => {
|
|
2531
|
-
capturedOverflowActions.addOverflowingId('test-id-1');
|
|
2532
|
-
});
|
|
2533
|
-
await waitFor(() => {
|
|
2534
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2535
|
-
});
|
|
2536
|
-
// 2. Advance half the duration
|
|
2537
|
-
act(() => {
|
|
2538
|
-
vi.advanceTimersByTime(EXPAND_HINT_DURATION_MS / 2);
|
|
2539
|
-
});
|
|
2540
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2541
|
-
// 3. Trigger second overflow (this should reset the timer)
|
|
2542
|
-
act(() => {
|
|
2543
|
-
capturedOverflowActions.addOverflowingId('test-id-2');
|
|
2544
|
-
});
|
|
2545
|
-
// Advance by 1ms to allow the OverflowProvider's 0ms batching timeout to fire
|
|
2546
|
-
// and flush the state update to AppContainer, triggering the reset.
|
|
2547
|
-
act(() => {
|
|
2548
|
-
vi.advanceTimersByTime(1);
|
|
2549
|
-
});
|
|
2550
|
-
await waitFor(() => {
|
|
2551
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2552
|
-
});
|
|
2553
|
-
// 4. Advance enough that the ORIGINAL timer would have expired
|
|
2554
|
-
// Subtracting 1ms since we advanced it above to flush the state.
|
|
2555
|
-
act(() => {
|
|
2556
|
-
vi.advanceTimersByTime(EXPAND_HINT_DURATION_MS / 2 + 100 - 1);
|
|
2557
|
-
});
|
|
2558
|
-
// The hint should STILL be visible because the timer reset at step 3
|
|
2559
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2560
|
-
// 5. Advance to the end of the NEW timer
|
|
2561
|
-
act(() => {
|
|
2562
|
-
vi.advanceTimersByTime(EXPAND_HINT_DURATION_MS / 2 - 100);
|
|
2563
|
-
});
|
|
2564
|
-
await waitFor(() => {
|
|
2565
|
-
expect(capturedUIState.showIsExpandableHint).toBe(false);
|
|
2566
|
-
});
|
|
2567
|
-
unmount();
|
|
2568
|
-
});
|
|
2569
|
-
it('toggles expansion state and resets the hint timer when Ctrl+O is pressed in Standard Mode', async () => {
|
|
2570
|
-
const { stdin, unmount } = await act(async () => renderAppContainer());
|
|
2571
|
-
await waitFor(() => expect(capturedOverflowActions).toBeTruthy());
|
|
2572
|
-
// Initial state is constrainHeight = true
|
|
2573
|
-
expect(capturedUIState.constrainHeight).toBe(true);
|
|
2574
|
-
// Trigger overflow so the hint starts showing
|
|
2575
|
-
act(() => {
|
|
2576
|
-
capturedOverflowActions.addOverflowingId('test-id');
|
|
2577
|
-
});
|
|
2578
|
-
await waitFor(() => {
|
|
2579
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2580
|
-
});
|
|
2581
|
-
// Advance half the duration
|
|
2582
|
-
act(() => {
|
|
2583
|
-
vi.advanceTimersByTime(EXPAND_HINT_DURATION_MS / 2);
|
|
2584
|
-
});
|
|
2585
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2586
|
-
// Simulate Ctrl+O
|
|
2587
|
-
act(() => {
|
|
2588
|
-
stdin.write('\x0f'); // \x0f is Ctrl+O
|
|
2589
|
-
});
|
|
2590
|
-
// constrainHeight should toggle
|
|
2591
|
-
expect(capturedUIState.constrainHeight).toBe(false);
|
|
2592
|
-
// Advance enough that the original timer would have expired if it hadn't reset
|
|
2593
|
-
act(() => {
|
|
2594
|
-
vi.advanceTimersByTime(EXPAND_HINT_DURATION_MS / 2 + 1000);
|
|
2595
|
-
});
|
|
2596
|
-
// We expect it to still be true because Ctrl+O should have reset the timer
|
|
2597
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2598
|
-
// Advance remaining time to reach the new timeout
|
|
2599
|
-
act(() => {
|
|
2600
|
-
vi.advanceTimersByTime(EXPAND_HINT_DURATION_MS / 2 - 1000);
|
|
2601
|
-
});
|
|
2602
|
-
await waitFor(() => {
|
|
2603
|
-
expect(capturedUIState.showIsExpandableHint).toBe(false);
|
|
2604
|
-
});
|
|
2605
|
-
unmount();
|
|
2606
|
-
});
|
|
2607
|
-
it('toggles Ctrl+O multiple times and verifies the hint disappears exactly after the last toggle', async () => {
|
|
2608
|
-
const { stdin, unmount } = await act(async () => renderAppContainer());
|
|
2609
|
-
await waitFor(() => expect(capturedOverflowActions).toBeTruthy());
|
|
2610
|
-
// Initial state is constrainHeight = true
|
|
2611
|
-
expect(capturedUIState.constrainHeight).toBe(true);
|
|
2612
|
-
// Trigger overflow so the hint starts showing
|
|
2613
|
-
act(() => {
|
|
2614
|
-
capturedOverflowActions.addOverflowingId('test-id');
|
|
2615
|
-
});
|
|
2616
|
-
await waitFor(() => {
|
|
2617
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2618
|
-
});
|
|
2619
|
-
// Advance half the duration
|
|
2620
|
-
act(() => {
|
|
2621
|
-
vi.advanceTimersByTime(EXPAND_HINT_DURATION_MS / 2);
|
|
2622
|
-
});
|
|
2623
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2624
|
-
// First toggle 'on' (expanded)
|
|
2625
|
-
act(() => {
|
|
2626
|
-
stdin.write('\x0f'); // Ctrl+O
|
|
2627
|
-
});
|
|
2628
|
-
expect(capturedUIState.constrainHeight).toBe(false);
|
|
2629
|
-
// Wait 1 second
|
|
2630
|
-
act(() => {
|
|
2631
|
-
vi.advanceTimersByTime(1000);
|
|
2632
|
-
});
|
|
2633
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2634
|
-
// Second toggle 'off' (collapsed)
|
|
2635
|
-
act(() => {
|
|
2636
|
-
stdin.write('\x0f'); // Ctrl+O
|
|
2637
|
-
});
|
|
2638
|
-
expect(capturedUIState.constrainHeight).toBe(true);
|
|
2639
|
-
// Wait 1 second
|
|
2640
|
-
act(() => {
|
|
2641
|
-
vi.advanceTimersByTime(1000);
|
|
2642
|
-
});
|
|
2643
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2644
|
-
// Third toggle 'on' (expanded)
|
|
2645
|
-
act(() => {
|
|
2646
|
-
stdin.write('\x0f'); // Ctrl+O
|
|
2647
|
-
});
|
|
2648
|
-
expect(capturedUIState.constrainHeight).toBe(false);
|
|
2649
|
-
// Now we wait just before the timeout from the LAST toggle.
|
|
2650
|
-
// It should still be true.
|
|
2651
|
-
act(() => {
|
|
2652
|
-
vi.advanceTimersByTime(EXPAND_HINT_DURATION_MS - 100);
|
|
2653
|
-
});
|
|
2654
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2655
|
-
// Wait 0.1s more to hit exactly the timeout since the last toggle.
|
|
2656
|
-
// It should hide now.
|
|
2657
|
-
act(() => {
|
|
2658
|
-
vi.advanceTimersByTime(100);
|
|
2659
|
-
});
|
|
2660
|
-
await waitFor(() => {
|
|
2661
|
-
expect(capturedUIState.showIsExpandableHint).toBe(false);
|
|
2662
|
-
});
|
|
2663
|
-
unmount();
|
|
2664
|
-
});
|
|
2665
|
-
it('DOES set showIsExpandableHint when overflow occurs in Alternate Buffer Mode', async () => {
|
|
2666
|
-
const settingsWithAlternateBuffer = createMockSettings({
|
|
2667
|
-
ui: { useAlternateBuffer: true },
|
|
2668
|
-
});
|
|
2669
|
-
vi.spyOn(mockConfig, 'getUseTerminalBuffer').mockReturnValue(false);
|
|
2670
|
-
vi.spyOn(mockConfig, 'getUseAlternateBuffer').mockReturnValue(true);
|
|
2671
|
-
const { unmount } = await act(async () => renderAppContainer({
|
|
2672
|
-
settings: settingsWithAlternateBuffer,
|
|
2673
|
-
}));
|
|
2674
|
-
await waitFor(() => expect(capturedOverflowActions).toBeTruthy());
|
|
2675
|
-
// Trigger overflow
|
|
2676
|
-
act(() => {
|
|
2677
|
-
capturedOverflowActions.addOverflowingId('test-id');
|
|
2678
|
-
});
|
|
2679
|
-
// Should NOW show hint because we are in Alternate Buffer Mode
|
|
2680
|
-
await waitFor(() => {
|
|
2681
|
-
expect(capturedUIState.showIsExpandableHint).toBe(true);
|
|
2682
|
-
});
|
|
2683
|
-
unmount();
|
|
2684
|
-
});
|
|
2685
|
-
});
|
|
2686
|
-
describe('Permission Handling', () => {
|
|
2687
|
-
it('shows permission dialog when checkPermissions returns paths', async () => {
|
|
2688
|
-
const { checkPermissions } = await import('./hooks/atCommandProcessor.js');
|
|
2689
|
-
vi.mocked(checkPermissions).mockResolvedValue(['/test/file.txt']);
|
|
2690
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2691
|
-
expect(capturedUIActions).toBeTruthy();
|
|
2692
|
-
await act(async () => capturedUIActions.handleFinalSubmit('read @file.txt'));
|
|
2693
|
-
expect(capturedUIState.permissionConfirmationRequest).not.toBeNull();
|
|
2694
|
-
expect(capturedUIState.permissionConfirmationRequest?.files).toEqual([
|
|
2695
|
-
'/test/file.txt',
|
|
2696
|
-
]);
|
|
2697
|
-
unmount();
|
|
2698
|
-
});
|
|
2699
|
-
it.each([true, false])('handles permissions when allowed is %s', async (allowed) => {
|
|
2700
|
-
const { checkPermissions } = await import('./hooks/atCommandProcessor.js');
|
|
2701
|
-
vi.mocked(checkPermissions).mockResolvedValue(['/test/file.txt']);
|
|
2702
|
-
const addReadOnlyPathSpy = vi.spyOn(mockConfig.getWorkspaceContext(), 'addReadOnlyPath');
|
|
2703
|
-
const { submitQuery } = mockedUseGeminiStream();
|
|
2704
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2705
|
-
expect(capturedUIActions).toBeTruthy();
|
|
2706
|
-
await act(async () => capturedUIActions.handleFinalSubmit('read @file.txt'));
|
|
2707
|
-
await act(async () => capturedUIState.permissionConfirmationRequest?.onComplete({
|
|
2708
|
-
allowed,
|
|
2709
|
-
}));
|
|
2710
|
-
if (allowed) {
|
|
2711
|
-
expect(addReadOnlyPathSpy).toHaveBeenCalledWith('/test/file.txt');
|
|
2712
|
-
}
|
|
2713
|
-
else {
|
|
2714
|
-
expect(addReadOnlyPathSpy).not.toHaveBeenCalled();
|
|
2715
|
-
}
|
|
2716
|
-
expect(submitQuery).toHaveBeenCalledWith('read @file.txt');
|
|
2717
|
-
expect(capturedUIState.permissionConfirmationRequest).toBeNull();
|
|
2718
|
-
unmount();
|
|
2719
|
-
});
|
|
2720
|
-
});
|
|
2721
|
-
describe('Plan Mode Availability', () => {
|
|
2722
|
-
it('should allow plan mode when enabled and idle', async () => {
|
|
2723
|
-
vi.spyOn(mockConfig, 'isPlanEnabled').mockReturnValue(true);
|
|
2724
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
2725
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
2726
|
-
pendingHistoryItems: [],
|
|
2727
|
-
});
|
|
2728
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2729
|
-
expect(capturedUIState).toBeTruthy();
|
|
2730
|
-
expect(capturedUIState.allowPlanMode).toBe(true);
|
|
2731
|
-
unmount();
|
|
2732
|
-
});
|
|
2733
|
-
it('should NOT allow plan mode when disabled in config', async () => {
|
|
2734
|
-
vi.spyOn(mockConfig, 'isPlanEnabled').mockReturnValue(false);
|
|
2735
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
2736
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
2737
|
-
pendingHistoryItems: [],
|
|
2738
|
-
});
|
|
2739
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2740
|
-
expect(capturedUIState).toBeTruthy();
|
|
2741
|
-
expect(capturedUIState.allowPlanMode).toBe(false);
|
|
2742
|
-
unmount();
|
|
2743
|
-
});
|
|
2744
|
-
it('should NOT allow plan mode when streaming', async () => {
|
|
2745
|
-
vi.spyOn(mockConfig, 'isPlanEnabled').mockReturnValue(true);
|
|
2746
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
2747
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
2748
|
-
streamingState: StreamingState.Responding,
|
|
2749
|
-
pendingHistoryItems: [],
|
|
2750
|
-
});
|
|
2751
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2752
|
-
expect(capturedUIState).toBeTruthy();
|
|
2753
|
-
expect(capturedUIState.allowPlanMode).toBe(false);
|
|
2754
|
-
unmount();
|
|
2755
|
-
});
|
|
2756
|
-
it('should NOT allow plan mode when a tool is awaiting confirmation', async () => {
|
|
2757
|
-
vi.spyOn(mockConfig, 'isPlanEnabled').mockReturnValue(true);
|
|
2758
|
-
mockedUseGeminiStream.mockReturnValue({
|
|
2759
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
2760
|
-
streamingState: StreamingState.Idle,
|
|
2761
|
-
pendingHistoryItems: [
|
|
2762
|
-
{
|
|
2763
|
-
type: 'tool_group',
|
|
2764
|
-
tools: [
|
|
2765
|
-
{
|
|
2766
|
-
name: 'test_tool',
|
|
2767
|
-
status: CoreToolCallStatus.AwaitingApproval,
|
|
2768
|
-
},
|
|
2769
|
-
],
|
|
2770
|
-
},
|
|
2771
|
-
],
|
|
2772
|
-
});
|
|
2773
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2774
|
-
expect(capturedUIState).toBeTruthy();
|
|
2775
|
-
expect(capturedUIState.allowPlanMode).toBe(false);
|
|
2776
|
-
unmount();
|
|
2777
|
-
});
|
|
2778
|
-
});
|
|
2779
|
-
describe('Compression Queuing', () => {
|
|
2780
|
-
beforeEach(async () => {
|
|
2781
|
-
const { checkPermissions } = await import('./hooks/atCommandProcessor.js');
|
|
2782
|
-
vi.mocked(checkPermissions).mockResolvedValue([]);
|
|
2783
|
-
vi.spyOn(mockConfig, 'isModelSteeringEnabled').mockReturnValue(true);
|
|
2784
|
-
const actual = await vi.importActual('./hooks/useMessageQueue.js');
|
|
2785
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2786
|
-
const { useMessageQueue: realUseMessageQueue } = actual;
|
|
2787
|
-
mockedUseMessageQueue.mockImplementation(realUseMessageQueue);
|
|
2788
|
-
// Start compression by mocking pendingHistoryItems to include a pending compression
|
|
2789
|
-
mockedUseGeminiStream.mockImplementation(() => ({
|
|
2790
|
-
...DEFAULT_GEMINI_STREAM_MOCK,
|
|
2791
|
-
pendingHistoryItems: [
|
|
2792
|
-
{
|
|
2793
|
-
type: MessageType.COMPRESSION,
|
|
2794
|
-
compression: {
|
|
2795
|
-
isPending: true,
|
|
2796
|
-
originalTokenCount: null,
|
|
2797
|
-
newTokenCount: null,
|
|
2798
|
-
compressionStatus: null,
|
|
2799
|
-
},
|
|
2800
|
-
},
|
|
2801
|
-
],
|
|
2802
|
-
}));
|
|
2803
|
-
});
|
|
2804
|
-
it('queues messages during compression instead of handling as steering hints', async () => {
|
|
2805
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2806
|
-
// Verify state isolation
|
|
2807
|
-
expect(capturedUIState.streamingState).toBe(StreamingState.Idle);
|
|
2808
|
-
// Submit a message
|
|
2809
|
-
await act(async () => capturedUIActions.handleFinalSubmit('follow up message'));
|
|
2810
|
-
// Verify it was queued, not submitted as steering hint
|
|
2811
|
-
expect(capturedUIState.messageQueue).toContain('follow up message');
|
|
2812
|
-
unmount();
|
|
2813
|
-
});
|
|
2814
|
-
it('executes slash commands immediately during compression', async () => {
|
|
2815
|
-
const { unmount } = await act(async () => renderAppContainer());
|
|
2816
|
-
// Submit a slash command
|
|
2817
|
-
await act(async () => capturedUIActions.handleFinalSubmit('/help'));
|
|
2818
|
-
// Verify it was NOT queued
|
|
2819
|
-
expect(capturedUIState.messageQueue).not.toContain('/help');
|
|
2820
|
-
unmount();
|
|
2821
|
-
});
|
|
2822
|
-
});
|
|
2823
|
-
});
|
|
2824
|
-
//# sourceMappingURL=AppContainer.test.js.map
|