@within-7/minto 0.1.7 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.js +155 -37
- package/dist/Tool.js +38 -0
- package/dist/Tool.js.map +3 -3
- package/dist/commands/agents/AgentsCommand.js +73 -49
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/constants.js +1 -1
- package/dist/commands/agents/constants.js.map +1 -1
- package/dist/commands/agents/index.js +1 -1
- package/dist/commands/bug.js +74 -7
- package/dist/commands/bug.js.map +3 -3
- package/dist/commands/clear.js +3 -0
- package/dist/commands/clear.js.map +2 -2
- package/dist/commands/compact.js +37 -0
- package/dist/commands/compact.js.map +2 -2
- package/dist/commands/context.js +85 -0
- package/dist/commands/context.js.map +7 -0
- package/dist/commands/ctx_viz.js +18 -10
- package/dist/commands/ctx_viz.js.map +2 -2
- package/dist/commands/doctor.js +158 -12
- package/dist/commands/doctor.js.map +2 -2
- package/dist/commands/export.js +157 -0
- package/dist/commands/export.js.map +7 -0
- package/dist/commands/mcp-interactive.js +28 -18
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +9 -7
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/permissions.js +87 -0
- package/dist/commands/permissions.js.map +7 -0
- package/dist/commands/plugin/AddMarketplaceForm.js +3 -2
- package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
- package/dist/commands/plugin/ConfirmDialog.js +2 -1
- package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
- package/dist/commands/plugin/ErrorView.js +2 -1
- package/dist/commands/plugin/ErrorView.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js +5 -4
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsManager.js +5 -4
- package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
- package/dist/commands/plugin/MainMenu.js +2 -1
- package/dist/commands/plugin/MainMenu.js.map +2 -2
- package/dist/commands/plugin/MarketplaceManager.js +5 -4
- package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
- package/dist/commands/plugin/MarketplaceSelector.js +4 -3
- package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
- package/dist/commands/plugin/PlaceholderScreen.js +3 -2
- package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
- package/dist/commands/plugin/PluginBrowser.js +6 -5
- package/dist/commands/plugin/PluginBrowser.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsInstall.js +5 -4
- package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsManage.js +4 -3
- package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
- package/dist/commands/plugin.js +16 -15
- package/dist/commands/plugin.js.map +2 -2
- package/dist/commands/quit.js +3 -1
- package/dist/commands/quit.js.map +2 -2
- package/dist/commands/sandbox.js +105 -0
- package/dist/commands/sandbox.js.map +7 -0
- package/dist/commands/setup.js +2 -1
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/status.js +59 -0
- package/dist/commands/status.js.map +7 -0
- package/dist/commands/tasks.js +108 -0
- package/dist/commands/tasks.js.map +7 -0
- package/dist/commands/todos.js +123 -0
- package/dist/commands/todos.js.map +7 -0
- package/dist/commands/undo.js +245 -0
- package/dist/commands/undo.js.map +7 -0
- package/dist/commands.js +22 -2
- package/dist/commands.js.map +2 -2
- package/dist/components/AgentThinkingBlock.js +10 -18
- package/dist/components/AgentThinkingBlock.js.map +2 -2
- package/dist/components/AsciiLogo.js +7 -8
- package/dist/components/AsciiLogo.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/QuestionView.js +2 -1
- package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
- package/dist/components/BackgroundTasksPanel.js +78 -29
- package/dist/components/BackgroundTasksPanel.js.map +2 -2
- package/dist/components/BashStreamingProgress.js +24 -0
- package/dist/components/BashStreamingProgress.js.map +7 -0
- package/dist/components/CollapsibleHint.js +15 -0
- package/dist/components/CollapsibleHint.js.map +7 -0
- package/dist/components/Config.js +3 -2
- package/dist/components/Config.js.map +2 -2
- package/dist/components/ConsoleOAuthFlow.js +2 -1
- package/dist/components/ConsoleOAuthFlow.js.map +2 -2
- package/dist/components/Cost.js +2 -1
- package/dist/components/Cost.js.map +2 -2
- package/dist/components/FileEditToolUpdatedMessage.js +1 -1
- package/dist/components/FileEditToolUpdatedMessage.js.map +2 -2
- package/dist/components/HeaderBar.js +13 -8
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/HistorySearchOverlay.js +4 -3
- package/dist/components/HistorySearchOverlay.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +134 -0
- package/dist/components/HotkeyHelpPanel.js.map +7 -0
- package/dist/components/InvalidConfigDialog.js +2 -1
- package/dist/components/InvalidConfigDialog.js.map +2 -2
- package/dist/components/Logo.js +24 -68
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/MCPServerApprovalDialog.js +2 -1
- package/dist/components/MCPServerApprovalDialog.js.map +2 -2
- package/dist/components/MCPServerDialogCopy.js +2 -1
- package/dist/components/MCPServerDialogCopy.js.map +2 -2
- package/dist/components/MCPServerMultiselectDialog.js +2 -1
- package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
- package/dist/components/Message.js +23 -7
- package/dist/components/Message.js.map +3 -3
- package/dist/components/MessageSelector.js +4 -3
- package/dist/components/MessageSelector.js.map +2 -2
- package/dist/components/ModeIndicator.js +2 -1
- package/dist/components/ModeIndicator.js.map +2 -2
- package/dist/components/ModelConfig.js +20 -6
- package/dist/components/ModelConfig.js.map +2 -2
- package/dist/components/ModelListManager.js +7 -6
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/ModelSelector/ModelSelector.js +27 -14
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/Onboarding.js +22 -16
- package/dist/components/Onboarding.js.map +2 -2
- package/dist/components/OperationSummary.js +130 -0
- package/dist/components/OperationSummary.js.map +7 -0
- package/dist/components/ProgressBar.js +74 -0
- package/dist/components/ProgressBar.js.map +7 -0
- package/dist/components/PromptInput.js +210 -87
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/RequestStatusIndicator.js +194 -0
- package/dist/components/RequestStatusIndicator.js.map +7 -0
- package/dist/components/SensitiveFileWarning.js +31 -0
- package/dist/components/SensitiveFileWarning.js.map +7 -0
- package/dist/components/Spinner.js +141 -27
- package/dist/components/Spinner.js.map +2 -2
- package/dist/components/SpinnerSymbol.js +21 -27
- package/dist/components/SpinnerSymbol.js.map +2 -2
- package/dist/components/StreamingBashOutput.js +9 -8
- package/dist/components/StreamingBashOutput.js.map +2 -2
- package/dist/components/StructuredDiff.js +6 -8
- package/dist/components/StructuredDiff.js.map +2 -2
- package/dist/components/SubagentBlock.js +5 -3
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/SubagentProgress.js +17 -15
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TaskCard.js +30 -24
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TextInput.js +9 -1
- package/dist/components/TextInput.js.map +2 -2
- package/dist/components/TodoChangeBlock.js +1 -1
- package/dist/components/TodoChangeBlock.js.map +2 -2
- package/dist/components/TodoPanel.js +140 -31
- package/dist/components/TodoPanel.js.map +3 -3
- package/dist/components/TokenCounter.js +74 -0
- package/dist/components/TokenCounter.js.map +7 -0
- package/dist/components/TokenWarning.js +2 -1
- package/dist/components/TokenWarning.js.map +2 -2
- package/dist/components/ToolUseLoader.js +2 -2
- package/dist/components/ToolUseLoader.js.map +2 -2
- package/dist/components/TreeConnector.js +26 -0
- package/dist/components/TreeConnector.js.map +7 -0
- package/dist/components/TrustDialog.js +2 -1
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/TurnCompletionIndicator.js +18 -0
- package/dist/components/TurnCompletionIndicator.js.map +7 -0
- package/dist/components/binary-feedback/BinaryFeedbackView.js +2 -1
- package/dist/components/binary-feedback/BinaryFeedbackView.js.map +2 -2
- package/dist/components/messages/AssistantTextMessage.js +20 -9
- package/dist/components/messages/AssistantTextMessage.js.map +2 -2
- package/dist/components/messages/AssistantThinkingMessage.js +18 -3
- package/dist/components/messages/AssistantThinkingMessage.js.map +2 -2
- package/dist/components/messages/AssistantToolUseMessage.js +17 -10
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/GroupRenderer.js +54 -0
- package/dist/components/messages/GroupRenderer.js.map +7 -0
- package/dist/components/messages/NestedTasksPreview.js +24 -0
- package/dist/components/messages/NestedTasksPreview.js.map +7 -0
- package/dist/components/messages/ParallelTasksGroupView.js +93 -0
- package/dist/components/messages/ParallelTasksGroupView.js.map +7 -0
- package/dist/components/messages/TaskInModuleView.js +218 -0
- package/dist/components/messages/TaskInModuleView.js.map +7 -0
- package/dist/components/messages/TaskOutputContent.js +56 -0
- package/dist/components/messages/TaskOutputContent.js.map +7 -0
- package/dist/components/messages/UserPromptMessage.js +2 -2
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +2 -3
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
- package/dist/components/permissions/FallbackPermissionRequest.js +4 -4
- package/dist/components/permissions/FallbackPermissionRequest.js.map +2 -2
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +4 -4
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +2 -2
- package/dist/constants/colors.js +120 -54
- package/dist/constants/colors.js.map +2 -2
- package/dist/constants/formatRules.js +102 -0
- package/dist/constants/formatRules.js.map +7 -0
- package/dist/constants/prompts.js +12 -34
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/symbols.js +64 -6
- package/dist/constants/symbols.js.map +2 -2
- package/dist/constants/timing.js +5 -0
- package/dist/constants/timing.js.map +2 -2
- package/dist/constants/toolInputExamples.js +84 -0
- package/dist/constants/toolInputExamples.js.map +7 -0
- package/dist/core/backupManager.js +321 -0
- package/dist/core/backupManager.js.map +7 -0
- package/dist/core/config/defaults.js +84 -0
- package/dist/core/config/defaults.js.map +7 -0
- package/dist/core/config/index.js +111 -0
- package/dist/core/config/index.js.map +7 -0
- package/dist/core/config/loader.js +221 -0
- package/dist/core/config/loader.js.map +7 -0
- package/dist/core/config/migrations.js +128 -0
- package/dist/core/config/migrations.js.map +7 -0
- package/dist/core/config/schema.js +178 -0
- package/dist/core/config/schema.js.map +7 -0
- package/dist/core/costTracker.js +129 -0
- package/dist/core/costTracker.js.map +7 -0
- package/dist/core/gitAutoCommit.js +287 -0
- package/dist/core/gitAutoCommit.js.map +7 -0
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +7 -0
- package/dist/core/operationTracker.js +212 -0
- package/dist/core/operationTracker.js.map +7 -0
- package/dist/core/permissions/auditLog.js +204 -0
- package/dist/core/permissions/auditLog.js.map +7 -0
- package/dist/core/permissions/engine/index.js +3 -0
- package/dist/core/permissions/engine/index.js.map +7 -0
- package/dist/core/permissions/engine/permissionEngine.js +106 -0
- package/dist/core/permissions/engine/permissionEngine.js.map +7 -0
- package/dist/core/permissions/engine/types.js +1 -0
- package/dist/core/permissions/engine/types.js.map +7 -0
- package/dist/core/permissions/index.js +84 -0
- package/dist/core/permissions/index.js.map +7 -0
- package/dist/core/permissions/ruleEngine.js +259 -0
- package/dist/core/permissions/ruleEngine.js.map +7 -0
- package/dist/core/permissions/rules/allowedToolsRule.js +62 -0
- package/dist/core/permissions/rules/allowedToolsRule.js.map +7 -0
- package/dist/core/permissions/rules/autoEscalationRule.js +296 -0
- package/dist/core/permissions/rules/autoEscalationRule.js.map +7 -0
- package/dist/core/permissions/rules/index.js +46 -0
- package/dist/core/permissions/rules/index.js.map +7 -0
- package/dist/core/permissions/rules/planModeRule.js +55 -0
- package/dist/core/permissions/rules/planModeRule.js.map +7 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js +173 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js.map +7 -0
- package/dist/core/permissions/rules/safeModeRule.js +65 -0
- package/dist/core/permissions/rules/safeModeRule.js.map +7 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js +345 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js.map +7 -0
- package/dist/core/permissions/types.js +127 -0
- package/dist/core/permissions/types.js.map +7 -0
- package/dist/core/tokenStats.js +9 -0
- package/dist/core/tokenStats.js.map +7 -0
- package/dist/core/tokenStatsManager.js +331 -0
- package/dist/core/tokenStatsManager.js.map +7 -0
- package/dist/core/tools/executor.js +143 -0
- package/dist/core/tools/executor.js.map +7 -0
- package/dist/core/tools/index.js +15 -0
- package/dist/core/tools/index.js.map +7 -0
- package/dist/core/tools/registry.js +183 -0
- package/dist/core/tools/registry.js.map +7 -0
- package/dist/core/tools/types.js +1 -0
- package/dist/core/tools/types.js.map +7 -0
- package/dist/cost-tracker.js +23 -15
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/cli.js +158 -130
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/entrypoints/mcp.js +12 -4
- package/dist/entrypoints/mcp.js.map +2 -2
- package/dist/history.js +14 -3
- package/dist/history.js.map +2 -2
- package/dist/hooks/useAgentTokenStats.js +72 -0
- package/dist/hooks/useAgentTokenStats.js.map +7 -0
- package/dist/hooks/useAgentTranscripts.js +140 -0
- package/dist/hooks/useAgentTranscripts.js.map +7 -0
- package/dist/hooks/useAnimationSync.js +53 -0
- package/dist/hooks/useAnimationSync.js.map +7 -0
- package/dist/hooks/useArrowKeyHistory.js +4 -2
- package/dist/hooks/useArrowKeyHistory.js.map +2 -2
- package/dist/hooks/useCanUseTool.js +3 -1
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useExitOnCtrlCD.js +9 -5
- package/dist/hooks/useExitOnCtrlCD.js.map +2 -2
- package/dist/hooks/useHookStatus.js +40 -0
- package/dist/hooks/useHookStatus.js.map +7 -0
- package/dist/hooks/useLogMessages.js +29 -2
- package/dist/hooks/useLogMessages.js.map +2 -2
- package/dist/hooks/useMessageGroups.js +43 -0
- package/dist/hooks/useMessageGroups.js.map +7 -0
- package/dist/hooks/useTerminalSize.js +62 -6
- package/dist/hooks/useTerminalSize.js.map +2 -2
- package/dist/hooks/useUnifiedCompletion.js +69 -0
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/i18n/index.js +109 -0
- package/dist/i18n/index.js.map +7 -0
- package/dist/i18n/locales/en.js +348 -0
- package/dist/i18n/locales/en.js.map +7 -0
- package/dist/i18n/locales/index.js +7 -0
- package/dist/i18n/locales/index.js.map +7 -0
- package/dist/i18n/locales/zh-CN.js +348 -0
- package/dist/i18n/locales/zh-CN.js.map +7 -0
- package/dist/i18n/types.js +8 -0
- package/dist/i18n/types.js.map +7 -0
- package/dist/permissions.js +28 -1
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +253 -21
- package/dist/query.js.map +3 -3
- package/dist/screens/REPL.js +523 -194
- package/dist/screens/REPL.js.map +3 -3
- package/dist/services/adapters/chatCompletions.js +3 -1
- package/dist/services/adapters/chatCompletions.js.map +2 -2
- package/dist/services/adapters/messageNormalizer.js +354 -0
- package/dist/services/adapters/messageNormalizer.js.map +7 -0
- package/dist/services/adapters/responsesAPI.js +6 -3
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/checkpointManager.js +386 -0
- package/dist/services/checkpointManager.js.map +7 -0
- package/dist/services/claude.js +192 -14
- package/dist/services/claude.js.map +3 -3
- package/dist/services/compressionService.js +50 -1
- package/dist/services/compressionService.js.map +2 -2
- package/dist/services/contextMonitor.js +162 -0
- package/dist/services/contextMonitor.js.map +7 -0
- package/dist/services/customCommands.js +60 -41
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/hookExecutor.js +173 -1
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/intelligentCompactor.js +281 -0
- package/dist/services/intelligentCompactor.js.map +7 -0
- package/dist/services/lspConfig.js +109 -0
- package/dist/services/lspConfig.js.map +7 -0
- package/dist/services/mcpClient.js +338 -43
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/modelOrchestrator.js +310 -0
- package/dist/services/modelOrchestrator.js.map +7 -0
- package/dist/services/openai.js +8 -1
- package/dist/services/openai.js.map +2 -2
- package/dist/services/outputStyles.js +138 -0
- package/dist/services/outputStyles.js.map +7 -0
- package/dist/services/plugins/index.js +5 -0
- package/dist/services/plugins/index.js.map +7 -0
- package/dist/services/plugins/lspServers.js +188 -0
- package/dist/services/plugins/lspServers.js.map +7 -0
- package/dist/services/plugins/pluginRuntime.js +229 -0
- package/dist/services/plugins/pluginRuntime.js.map +7 -0
- package/dist/services/plugins/pluginValidation.js +219 -0
- package/dist/services/plugins/pluginValidation.js.map +7 -0
- package/dist/services/plugins/skillMarketplace.js +556 -0
- package/dist/services/plugins/skillMarketplace.js.map +7 -0
- package/dist/services/responseStateManager.js +37 -3
- package/dist/services/responseStateManager.js.map +2 -2
- package/dist/services/sandbox/filesystemBoundary.js +341 -0
- package/dist/services/sandbox/filesystemBoundary.js.map +7 -0
- package/dist/services/sandbox/index.js +14 -0
- package/dist/services/sandbox/index.js.map +7 -0
- package/dist/services/sandbox/networkProxy.js +293 -0
- package/dist/services/sandbox/networkProxy.js.map +7 -0
- package/dist/services/sandbox/sandboxController.js +574 -0
- package/dist/services/sandbox/sandboxController.js.map +7 -0
- package/dist/services/sandbox/types.js +50 -0
- package/dist/services/sandbox/types.js.map +7 -0
- package/dist/services/sessionMemory.js +266 -0
- package/dist/services/sessionMemory.js.map +7 -0
- package/dist/services/taskRouter.js +324 -0
- package/dist/services/taskRouter.js.map +7 -0
- package/dist/tools/ArchitectTool/ArchitectTool.js +7 -1
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +2 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +6 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +2 -1
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
- package/dist/tools/BaseTool.js +72 -0
- package/dist/tools/BaseTool.js.map +7 -0
- package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js +3 -0
- package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js +79 -3
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/BashTool/BashToolResultMessage.js +3 -0
- package/dist/tools/BashTool/BashToolResultMessage.js.map +2 -2
- package/dist/tools/BashTool/OutputLine.js +54 -0
- package/dist/tools/BashTool/OutputLine.js.map +2 -2
- package/dist/tools/BashTool/prompt.js +336 -3
- package/dist/tools/BashTool/prompt.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +29 -4
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileEditTool/prompt.js +6 -3
- package/dist/tools/FileEditTool/prompt.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +5 -5
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/FileWriteTool/prompt.js +4 -2
- package/dist/tools/FileWriteTool/prompt.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js +4 -2
- package/dist/tools/GlobTool/GlobTool.js.map +2 -2
- package/dist/tools/GrepTool/GrepTool.js +36 -7
- package/dist/tools/GrepTool/GrepTool.js.map +2 -2
- package/dist/tools/KillShellTool/KillShellToolResultMessage.js +3 -0
- package/dist/tools/KillShellTool/KillShellToolResultMessage.js.map +2 -2
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +109 -0
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +7 -0
- package/dist/tools/ListMcpResourcesTool/prompt.js +19 -0
- package/dist/tools/ListMcpResourcesTool/prompt.js.map +7 -0
- package/dist/tools/LspTool/LspTool.js +664 -0
- package/dist/tools/LspTool/LspTool.js.map +7 -0
- package/dist/tools/LspTool/prompt.js +27 -0
- package/dist/tools/LspTool/prompt.js.map +7 -0
- package/dist/tools/MCPTool/MCPTool.js +9 -1
- package/dist/tools/MCPTool/MCPTool.js.map +2 -2
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +19 -6
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +6 -6
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +19 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/MultiEditTool/prompt.js +5 -3
- package/dist/tools/MultiEditTool/prompt.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +7 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +75 -0
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +7 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +109 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +7 -0
- package/dist/tools/PlanModeTool/prompt.js +94 -0
- package/dist/tools/PlanModeTool/prompt.js.map +7 -0
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +130 -0
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +7 -0
- package/dist/tools/ReadMcpResourceTool/prompt.js +17 -0
- package/dist/tools/ReadMcpResourceTool/prompt.js.map +7 -0
- package/dist/tools/SkillTool/SkillTool.js +10 -4
- package/dist/tools/SkillTool/SkillTool.js.map +2 -2
- package/dist/tools/SkillTool/prompt.js +1 -1
- package/dist/tools/SkillTool/prompt.js.map +1 -1
- package/dist/tools/SlashCommandTool/SlashCommandTool.js +260 -0
- package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +7 -0
- package/dist/tools/SlashCommandTool/prompt.js +35 -0
- package/dist/tools/SlashCommandTool/prompt.js.map +7 -0
- package/dist/tools/TaskOutputTool/TaskOutputTool.js +190 -0
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +7 -0
- package/dist/tools/TaskOutputTool/prompt.js +15 -0
- package/dist/tools/TaskOutputTool/prompt.js.map +7 -0
- package/dist/tools/TaskTool/TaskTool.js +310 -104
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TodoWriteTool/TodoWriteTool.js +42 -77
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +4 -1
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/cache.js +55 -8
- package/dist/tools/URLFetcherTool/cache.js.map +2 -2
- package/dist/tools.js +31 -2
- package/dist/tools.js.map +2 -2
- package/dist/types/hooks.js +4 -0
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/marketplace.js.map +2 -2
- package/dist/types/messageGroup.js +36 -0
- package/dist/types/messageGroup.js.map +7 -0
- package/dist/types/plugin.js.map +2 -2
- package/dist/types/thinking.js +1 -0
- package/dist/types/thinking.js.map +7 -0
- package/dist/utils/BackgroundShellManager.js +136 -39
- package/dist/utils/BackgroundShellManager.js.map +2 -2
- package/dist/utils/CircuitBreaker.js +242 -0
- package/dist/utils/CircuitBreaker.js.map +7 -0
- package/dist/utils/MessageBatchBuffer.js +102 -0
- package/dist/utils/MessageBatchBuffer.js.map +7 -0
- package/dist/utils/PersistentShell.js +151 -1
- package/dist/utils/PersistentShell.js.map +2 -2
- package/dist/utils/agentLoader.js +1 -23
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentTranscripts.js +641 -0
- package/dist/utils/agentTranscripts.js.map +7 -0
- package/dist/utils/animationManager.js +213 -0
- package/dist/utils/animationManager.js.map +7 -0
- package/dist/utils/animationSync.js +110 -0
- package/dist/utils/animationSync.js.map +7 -0
- package/dist/utils/ask.js +2 -0
- package/dist/utils/ask.js.map +2 -2
- package/dist/utils/asyncFile.js +215 -0
- package/dist/utils/asyncFile.js.map +7 -0
- package/dist/utils/backgroundAgentManager.js +231 -0
- package/dist/utils/backgroundAgentManager.js.map +7 -0
- package/dist/utils/config.js +108 -10
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/conversationRecovery.js +19 -0
- package/dist/utils/conversationRecovery.js.map +2 -2
- package/dist/utils/credentials/CredentialStore.js +1 -0
- package/dist/utils/credentials/CredentialStore.js.map +7 -0
- package/dist/utils/credentials/EncryptedFileStore.js +157 -0
- package/dist/utils/credentials/EncryptedFileStore.js.map +7 -0
- package/dist/utils/credentials/index.js +37 -0
- package/dist/utils/credentials/index.js.map +7 -0
- package/dist/utils/credentials/migration.js +82 -0
- package/dist/utils/credentials/migration.js.map +7 -0
- package/dist/utils/exit.js +73 -0
- package/dist/utils/exit.js.map +7 -0
- package/dist/utils/format.js +73 -5
- package/dist/utils/format.js.map +2 -2
- package/dist/utils/generators.js +76 -6
- package/dist/utils/generators.js.map +2 -2
- package/dist/utils/globalErrorHandler.js +149 -0
- package/dist/utils/globalErrorHandler.js.map +7 -0
- package/dist/utils/groupHandlers/index.js +8 -0
- package/dist/utils/groupHandlers/index.js.map +7 -0
- package/dist/utils/groupHandlers/parallelTasksHandler.js +140 -0
- package/dist/utils/groupHandlers/parallelTasksHandler.js.map +7 -0
- package/dist/utils/groupHandlers/taskHandler.js +104 -0
- package/dist/utils/groupHandlers/taskHandler.js.map +7 -0
- package/dist/utils/groupHandlers/types.js +1 -0
- package/dist/utils/groupHandlers/types.js.map +7 -0
- package/dist/utils/logRotation.js +224 -0
- package/dist/utils/logRotation.js.map +7 -0
- package/dist/utils/markdown.js +13 -1
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/marketplaceManager.js +3 -5
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/memSafety.js +264 -0
- package/dist/utils/memSafety.js.map +7 -0
- package/dist/utils/messageGroupManager.js +274 -0
- package/dist/utils/messageGroupManager.js.map +7 -0
- package/dist/utils/messages.js +13 -4
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +119 -15
- package/dist/utils/model.js.map +3 -3
- package/dist/utils/permissions/filesystem.js +162 -6
- package/dist/utils/permissions/filesystem.js.map +2 -2
- package/dist/utils/plan/planMode.js +143 -0
- package/dist/utils/plan/planMode.js.map +7 -0
- package/dist/utils/pluginLoader.js +17 -21
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/ripgrep.js +55 -2
- package/dist/utils/ripgrep.js.map +2 -2
- package/dist/utils/safePath.js +132 -0
- package/dist/utils/safePath.js.map +7 -0
- package/dist/utils/sanitizeInput.js +32 -0
- package/dist/utils/sanitizeInput.js.map +7 -0
- package/dist/utils/secureKeyStorage.js +312 -0
- package/dist/utils/secureKeyStorage.js.map +7 -0
- package/dist/utils/sensitiveFiles.js +125 -0
- package/dist/utils/sensitiveFiles.js.map +7 -0
- package/dist/utils/session/sessionPlugins.js +67 -0
- package/dist/utils/session/sessionPlugins.js.map +7 -0
- package/dist/utils/taskDisplayUtils.js +257 -0
- package/dist/utils/taskDisplayUtils.js.map +7 -0
- package/dist/utils/teamConfig.js +2 -1
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/theme.js +6 -6
- package/dist/utils/theme.js.map +1 -1
- package/dist/utils/todoStorage.js +92 -2
- package/dist/utils/todoStorage.js.map +2 -2
- package/dist/utils/toolRiskClassification.js +207 -0
- package/dist/utils/toolRiskClassification.js.map +7 -0
- package/dist/utils/toolTimeout.js +136 -0
- package/dist/utils/toolTimeout.js.map +7 -0
- package/dist/utils/tooling/safeRender.js +116 -0
- package/dist/utils/tooling/safeRender.js.map +7 -0
- package/dist/utils/userFriendlyError.js +346 -0
- package/dist/utils/userFriendlyError.js.map +7 -0
- package/dist/utils/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +17 -5
- package/scripts/postinstall.js +128 -38
- package/dist/commands/agents.js +0 -2086
- package/dist/commands/agents.js.map +0 -7
- package/dist/commands/build.js +0 -74
- package/dist/commands/build.js.map +0 -7
- package/dist/commands/compression.js +0 -57
- package/dist/commands/compression.js.map +0 -7
- package/dist/commands/listen.js +0 -37
- package/dist/commands/listen.js.map +0 -7
- package/dist/commands/login.js +0 -37
- package/dist/commands/login.js.map +0 -7
- package/dist/commands/logout.js +0 -33
- package/dist/commands/logout.js.map +0 -7
- package/dist/commands/mcp.js +0 -40
- package/dist/commands/mcp.js.map +0 -7
- package/dist/commands/mcp_refresh.js +0 -40
- package/dist/commands/mcp_refresh.js.map +0 -7
- package/dist/commands/modelstatus.js +0 -21
- package/dist/commands/modelstatus.js.map +0 -7
- package/dist/commands/onboarding.js +0 -36
- package/dist/commands/onboarding.js.map +0 -7
- package/dist/commands/plugin-interactive.js +0 -446
- package/dist/commands/plugin-interactive.js.map +0 -7
- package/dist/commands/pr_comments.js +0 -61
- package/dist/commands/pr_comments.js.map +0 -7
- package/dist/commands/release-notes.js +0 -30
- package/dist/commands/release-notes.js.map +0 -7
- package/dist/commands/review.js +0 -51
- package/dist/commands/review.js.map +0 -7
- package/dist/components/Bug.js +0 -147
- package/dist/components/Bug.js.map +0 -7
- package/dist/components/ModelSelector.js +0 -2062
- package/dist/components/ModelSelector.js.map +0 -7
- package/dist/components/ModelStatusDisplay.js +0 -87
- package/dist/components/ModelStatusDisplay.js.map +0 -7
- package/dist/entrypoints/cli-wrapper.js +0 -61
- package/dist/entrypoints/cli-wrapper.js.map +0 -7
- package/dist/hooks/useCancelRequest.js +0 -28
- package/dist/hooks/useCancelRequest.js.map +0 -7
- package/dist/screens/Doctor.js +0 -22
- package/dist/screens/Doctor.js.map +0 -7
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/components/SensitiveFileWarning.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * SensitiveFileWarning Component\n *\n * Displays an informational warning when operating on files that may contain\n * sensitive information (API keys, credentials, private keys, etc.).\n *\n * This warning is INFORMATIONAL only - it does not block operations.\n * Designed to give non-technical users awareness without interrupting workflow.\n */\n\nimport { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { basename } from 'path'\nimport { SEMANTIC_COLORS } from '../constants/colors'\nimport { getSensitiveFileReason } from '../utils/sensitiveFiles'\n\ninterface Props {\n /** The path to the sensitive file */\n filePath: string\n /** The operation being performed on the file */\n operation: 'read' | 'write' | 'delete'\n}\n\n/**\n * Maps operation types to human-readable Chinese text\n */\nconst operationText: Record<Props['operation'], string> = {\n read: '\u8BFB\u53D6',\n write: '\u4FEE\u6539',\n delete: '\u5220\u9664',\n}\n\n/**\n * SensitiveFileWarning displays an informational warning box when\n * accessing files that may contain sensitive information.\n *\n * @example\n * ```tsx\n * <SensitiveFileWarning filePath=\"/path/to/.env\" operation=\"write\" />\n * ```\n */\nexport function SensitiveFileWarning({ filePath, operation }: Props) {\n const fileName = basename(filePath)\n const reason = getSensitiveFileReason(filePath)\n\n return (\n <Box\n flexDirection=\"column\"\n paddingX={1}\n paddingY={1}\n borderStyle=\"round\"\n borderColor={SEMANTIC_COLORS.accent}\n >\n <Text bold color={SEMANTIC_COLORS.accent}>\n \uD83D\uDD12 \u654F\u611F\u6587\u4EF6\u8B66\u544A\n </Text>\n <Text color={SEMANTIC_COLORS.secondary}>\n \u6B63\u5728{operationText[operation]}\u654F\u611F\u6587\u4EF6: <Text bold>{fileName}</Text>\n </Text>\n <Text color={SEMANTIC_COLORS.muted}>\n {reason || '\u6B64\u6587\u4EF6\u53EF\u80FD\u5305\u542B\u5BC6\u94A5\u3001\u51ED\u8BC1\u6216\u5176\u4ED6\u654F\u611F\u4FE1\u606F\u3002'}\n </Text>\n </Box>\n )\n}\n"],
|
|
5
|
+
"mappings": "AAUA,SAAS,KAAK,YAAY;AAC1B,YAAY,WAAW;AACvB,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAChC,SAAS,8BAA8B;AAYvC,MAAM,gBAAoD;AAAA,EACxD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AACV;AAWO,SAAS,qBAAqB,EAAE,UAAU,UAAU,GAAU;AACnE,QAAM,WAAW,SAAS,QAAQ;AAClC,QAAM,SAAS,uBAAuB,QAAQ;AAE9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAc;AAAA,MACd,UAAU;AAAA,MACV,UAAU;AAAA,MACV,aAAY;AAAA,MACZ,aAAa,gBAAgB;AAAA;AAAA,IAE7B,oCAAC,QAAK,MAAI,MAAC,OAAO,gBAAgB,UAAQ,gDAE1C;AAAA,IACA,oCAAC,QAAK,OAAO,gBAAgB,aAAW,gBACnC,cAAc,SAAS,GAAE,8BAAM,oCAAC,QAAK,MAAI,QAAE,QAAS,CACzD;AAAA,IACA,oCAAC,QAAK,OAAO,gBAAgB,SAC1B,UAAU,0HACb;AAAA,EACF;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,10 +1,54 @@
|
|
|
1
1
|
import { Box, Text } from "ink";
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { useRef, useMemo } from "react";
|
|
4
4
|
import { getTheme } from "../utils/theme.js";
|
|
5
5
|
import { sample } from "lodash-es";
|
|
6
6
|
import { getSessionState } from "../utils/sessionState.js";
|
|
7
|
+
import { useUnifiedAnimation } from "../utils/animationManager.js";
|
|
8
|
+
import { formatNumber, formatTokenUsage } from "../utils/format.js";
|
|
9
|
+
import { BRAND_GRADIENT, SEMANTIC_COLORS } from "../constants/colors.js";
|
|
7
10
|
const CHARACTERS = process.platform === "darwin" ? ["\xB7", "\u2722", "\u2733", "\u2217", "\u273B", "\u273D"] : ["\xB7", "\u2722", "*", "\u2217", "\u273B", "\u273D"];
|
|
11
|
+
function createDefaultState() {
|
|
12
|
+
return { phase: "thinking" };
|
|
13
|
+
}
|
|
14
|
+
const streamingStates = /* @__PURE__ */ new Map([
|
|
15
|
+
["__main__", createDefaultState()]
|
|
16
|
+
]);
|
|
17
|
+
const agentContextStack = ["__main__"];
|
|
18
|
+
function getCurrentAgentContext() {
|
|
19
|
+
return agentContextStack[agentContextStack.length - 1] ?? "__main__";
|
|
20
|
+
}
|
|
21
|
+
function pushAgentContext(agentId) {
|
|
22
|
+
agentContextStack.push(agentId);
|
|
23
|
+
if (!streamingStates.has(agentId)) {
|
|
24
|
+
streamingStates.set(agentId, createDefaultState());
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function popAgentContext() {
|
|
28
|
+
if (agentContextStack.length > 1) {
|
|
29
|
+
return agentContextStack.pop();
|
|
30
|
+
}
|
|
31
|
+
return void 0;
|
|
32
|
+
}
|
|
33
|
+
function setStreamingState(state, agentId) {
|
|
34
|
+
const targetId = agentId ?? getCurrentAgentContext();
|
|
35
|
+
const current = streamingStates.get(targetId) ?? createDefaultState();
|
|
36
|
+
streamingStates.set(targetId, { ...current, ...state });
|
|
37
|
+
}
|
|
38
|
+
function resetStreamingState(agentId) {
|
|
39
|
+
const targetId = agentId ?? getCurrentAgentContext();
|
|
40
|
+
streamingStates.set(targetId, createDefaultState());
|
|
41
|
+
}
|
|
42
|
+
function getStreamingState(agentId) {
|
|
43
|
+
const targetId = agentId ?? getCurrentAgentContext();
|
|
44
|
+
return streamingStates.get(targetId) ?? createDefaultState();
|
|
45
|
+
}
|
|
46
|
+
function getMainStreamingState() {
|
|
47
|
+
return streamingStates.get("__main__") ?? createDefaultState();
|
|
48
|
+
}
|
|
49
|
+
function cleanupAgentStreamingState(agentId) {
|
|
50
|
+
streamingStates.delete(agentId);
|
|
51
|
+
}
|
|
8
52
|
const MESSAGES = [
|
|
9
53
|
"Accomplishing",
|
|
10
54
|
"Actioning",
|
|
@@ -63,39 +107,109 @@ const MESSAGES = [
|
|
|
63
107
|
"Vibing",
|
|
64
108
|
"Working"
|
|
65
109
|
];
|
|
66
|
-
function Spinner() {
|
|
110
|
+
function Spinner({ isActive = true }) {
|
|
67
111
|
const frames = [...CHARACTERS, ...[...CHARACTERS].reverse()];
|
|
68
|
-
const [frame, setFrame] = useState(0);
|
|
69
|
-
const [elapsedTime, setElapsedTime] = useState(0);
|
|
70
112
|
const message = useRef(sample(MESSAGES));
|
|
71
113
|
const startTime = useRef(Date.now());
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
114
|
+
const theme = getTheme();
|
|
115
|
+
const { spinnerFrame, elapsedTime } = useUnifiedAnimation({
|
|
116
|
+
enabled: isActive,
|
|
117
|
+
startTime: startTime.current,
|
|
118
|
+
spinnerFrameCount: frames.length,
|
|
119
|
+
componentId: "main-spinner"
|
|
120
|
+
});
|
|
121
|
+
const streamState = useMemo(() => getMainStreamingState(), [spinnerFrame]);
|
|
122
|
+
const getPhaseDisplay = () => {
|
|
123
|
+
switch (streamState.phase) {
|
|
124
|
+
case "deep_thinking": {
|
|
125
|
+
const elapsed = streamState.thinkingStartTime ? Math.floor((Date.now() - streamState.thinkingStartTime) / 1e3) : 0;
|
|
126
|
+
const charInfo = streamState.tokenCount ? `${formatNumber(streamState.tokenCount)} chars` : "";
|
|
127
|
+
if (streamState.thinkingMaxTokens && streamState.tokenCount) {
|
|
128
|
+
return `Deep thinking (${elapsed}s \xB7 ${charInfo} / ${formatNumber(streamState.thinkingMaxTokens)})`;
|
|
129
|
+
}
|
|
130
|
+
return `Deep thinking (${elapsed}s${charInfo ? " \xB7 " + charInfo : ""})`;
|
|
131
|
+
}
|
|
132
|
+
case "retrying":
|
|
133
|
+
return streamState.retryCount && streamState.maxRetries ? `Retrying (${streamState.retryCount}/${streamState.maxRetries})${streamState.errorName ? ` \xB7 ${streamState.errorName}` : ""}` : streamState.errorName ? `Retrying \xB7 ${streamState.errorName}` : "Retrying...";
|
|
134
|
+
case "permission":
|
|
135
|
+
return "Waiting for permission...";
|
|
136
|
+
case "compacting":
|
|
137
|
+
return "Compacting context...";
|
|
138
|
+
case "concurrent":
|
|
139
|
+
return streamState.concurrentCount ? `Running ${streamState.concurrentCount} concurrent tasks...` : "Running concurrent tasks...";
|
|
140
|
+
case "tool_use":
|
|
141
|
+
return streamState.toolName ? `Using ${streamState.toolName}` : "Executing tool";
|
|
142
|
+
case "generating":
|
|
143
|
+
return "Receiving";
|
|
144
|
+
case "waiting":
|
|
145
|
+
return "Waiting for response";
|
|
146
|
+
case "thinking":
|
|
147
|
+
default:
|
|
148
|
+
return message.current;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
const phaseColors = {
|
|
152
|
+
thinking: BRAND_GRADIENT.MIDDLE,
|
|
153
|
+
// 粉紫 - 思考中
|
|
154
|
+
deep_thinking: BRAND_GRADIENT.START,
|
|
155
|
+
// 紫蓝 - 深度思考
|
|
156
|
+
generating: SEMANTIC_COLORS.success,
|
|
157
|
+
// 绿色 - 生成中
|
|
158
|
+
tool_use: SEMANTIC_COLORS.running,
|
|
159
|
+
// 粉紫 - 工具执行
|
|
160
|
+
waiting: SEMANTIC_COLORS.dim,
|
|
161
|
+
// 灰色 - 等待
|
|
162
|
+
retrying: SEMANTIC_COLORS.error,
|
|
163
|
+
// 红色 - 重试
|
|
164
|
+
permission: SEMANTIC_COLORS.info,
|
|
165
|
+
// 蓝色 - 权限
|
|
166
|
+
compacting: SEMANTIC_COLORS.info,
|
|
167
|
+
// 蓝色 - 压缩
|
|
168
|
+
concurrent: SEMANTIC_COLORS.success
|
|
169
|
+
// 绿色 - 并发
|
|
170
|
+
};
|
|
171
|
+
const getTokenDisplay = () => {
|
|
172
|
+
if (streamState.inputTokens || streamState.outputTokens) {
|
|
173
|
+
return formatTokenUsage(streamState.inputTokens, streamState.outputTokens);
|
|
174
|
+
}
|
|
175
|
+
if (streamState.receivedChars && streamState.receivedChars > 0) {
|
|
176
|
+
const approxOutputTokens = Math.round(streamState.receivedChars / 3);
|
|
177
|
+
if (streamState.sentChars && streamState.sentChars > 0) {
|
|
178
|
+
const approxInputTokens = Math.round(streamState.sentChars / 3);
|
|
179
|
+
return `\u2191 ~${formatNumber(approxInputTokens)} \xB7 \u2193 ~${formatNumber(approxOutputTokens)}`;
|
|
180
|
+
}
|
|
181
|
+
return `\u2193 ~${formatNumber(approxOutputTokens)}`;
|
|
182
|
+
}
|
|
183
|
+
return "";
|
|
184
|
+
};
|
|
185
|
+
const tokenUsage = getTokenDisplay();
|
|
186
|
+
const thinkingDuration = streamState.thinkingDurationMs ? Math.floor(streamState.thinkingDurationMs / 1e3) : null;
|
|
187
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", marginTop: 1 }, /* @__PURE__ */ React.createElement(Box, { flexWrap: "nowrap", height: 1, width: 2 }, /* @__PURE__ */ React.createElement(Text, { color: phaseColors[streamState.phase] }, frames[spinnerFrame])), /* @__PURE__ */ React.createElement(Text, { color: phaseColors[streamState.phase] }, getPhaseDisplay(), "\u2026 "), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "(", /* @__PURE__ */ React.createElement(Text, { bold: true }, "esc esc"), " to cancel \xB7 ", elapsedTime, "s", tokenUsage && /* @__PURE__ */ React.createElement(Text, null, " \xB7 ", tokenUsage), thinkingDuration !== null && thinkingDuration > 0 && /* @__PURE__ */ React.createElement(Text, null, " \xB7 thinking ", thinkingDuration, "s"), ")"), getSessionState("currentError") && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "\xB7 ", getSessionState("currentError")));
|
|
85
188
|
}
|
|
86
|
-
function SimpleSpinner(
|
|
189
|
+
function SimpleSpinner({
|
|
190
|
+
isActive = true,
|
|
191
|
+
label
|
|
192
|
+
}) {
|
|
87
193
|
const frames = [...CHARACTERS, ...[...CHARACTERS].reverse()];
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
return /* @__PURE__ */ React.createElement(Box, { flexWrap: "nowrap", height: 1, width: 2 }, /* @__PURE__ */ React.createElement(Text, { color:
|
|
194
|
+
const startTime = useRef(Date.now());
|
|
195
|
+
const { spinnerFrame } = useUnifiedAnimation({
|
|
196
|
+
enabled: isActive,
|
|
197
|
+
startTime: startTime.current,
|
|
198
|
+
spinnerFrameCount: frames.length,
|
|
199
|
+
componentId: "simple-spinner"
|
|
200
|
+
});
|
|
201
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Box, { flexWrap: "nowrap", height: 1, width: 2 }, /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.MIDDLE }, frames[spinnerFrame])), label && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", label));
|
|
96
202
|
}
|
|
97
203
|
export {
|
|
98
204
|
SimpleSpinner,
|
|
99
|
-
Spinner
|
|
205
|
+
Spinner,
|
|
206
|
+
cleanupAgentStreamingState,
|
|
207
|
+
getCurrentAgentContext,
|
|
208
|
+
getMainStreamingState,
|
|
209
|
+
getStreamingState,
|
|
210
|
+
popAgentContext,
|
|
211
|
+
pushAgentContext,
|
|
212
|
+
resetStreamingState,
|
|
213
|
+
setStreamingState
|
|
100
214
|
};
|
|
101
215
|
//# sourceMappingURL=Spinner.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/components/Spinner.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { useEffect, useRef, useState } from 'react'\nimport { getTheme } from '@utils/theme'\nimport { sample } from 'lodash-es'\nimport { getSessionState } from '@utils/sessionState'\n// NB: The third character in this string is an emoji that\n// renders on Windows consoles with a green background\nconst CHARACTERS =\n process.platform === 'darwin'\n ? ['\u00B7', '\u2722', '\u2733', '\u2217', '\u273B', '\u273D']\n : ['\u00B7', '\u2722', '*', '\u2217', '\u273B', '\u273D']\n\nconst MESSAGES = [\n 'Accomplishing',\n 'Actioning',\n 'Actualizing',\n 'Baking',\n 'Brewing',\n 'Calculating',\n 'Cerebrating',\n 'Churning',\n 'Coding',\n 'Coalescing',\n 'Cogitating',\n 'Computing',\n 'Conjuring',\n 'Considering',\n 'Cooking',\n 'Crafting',\n 'Creating',\n 'Crunching',\n 'Deliberating',\n 'Determining',\n 'Doing',\n 'Effecting',\n 'Finagling',\n 'Forging',\n 'Forming',\n 'Generating',\n 'Hatching',\n 'Herding',\n 'Honking',\n 'Hustling',\n 'Ideating',\n 'Inferring',\n 'Manifesting',\n 'Marinating',\n 'Moseying',\n 'Mulling',\n 'Mustering',\n 'Musing',\n 'Noodling',\n 'Percolating',\n 'Pondering',\n 'Processing',\n 'Puttering',\n 'Reticulating',\n 'Ruminating',\n 'Schlepping',\n 'Shucking',\n 'Simmering',\n 'Smooshing',\n 'Spinning',\n 'Stewing',\n 'Synthesizing',\n 'Thinking',\n 'Transmuting',\n 'Vibing',\n 'Working',\n]\n\nexport function Spinner(): React.ReactNode {\n const frames = [...CHARACTERS, ...[...CHARACTERS].reverse()]\n const [frame, setFrame] = useState(0)\n const [elapsedTime, setElapsedTime] = useState(0)\n const message = useRef(sample(MESSAGES))\n const startTime = useRef(Date.now())\n\n useEffect(() => {\n const timer = setInterval(() => {\n setFrame(f => (f + 1) % frames.length)\n }, 120)\n\n return () => clearInterval(timer)\n }, [frames.length])\n\n useEffect(() => {\n const timer = setInterval(() => {\n setElapsedTime(Math.floor((Date.now() - startTime.current) / 1000))\n }, 1000)\n\n return () => clearInterval(timer)\n }, [])\n\n return (\n <Box flexDirection=\"row\" marginTop={1}>\n <Box flexWrap=\"nowrap\" height={1} width={2}>\n <Text color={getTheme().minto}>{frames[frame]}</Text>\n </Box>\n <Text color={getTheme().minto}>{message.current}\u2026 </Text>\n <Text color={getTheme().secondaryText}>\n ({elapsedTime}s \u00B7 <Text bold>esc</Text> to interrupt)\n </Text>\n <Text color={getTheme().secondaryText}>\n \u00B7 {getSessionState('currentError')}\n </Text>\n </Box>\n )\n}\n\nexport function SimpleSpinner(): React.ReactNode {\n const frames = [...CHARACTERS, ...[...CHARACTERS].reverse()]\n const [frame, setFrame] = useState(0)\n\n useEffect(() => {\n const timer = setInterval(() => {\n setFrame(f => (f + 1) % frames.length)\n }, 120)\n\n return () => clearInterval(timer)\n }, [frames.length])\n\n return (\n <Box flexWrap=\"nowrap\" height={1} width={2}>\n <Text color={getTheme().minto}>{frames[frame]}</Text>\n </Box>\n )\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,KAAK,YAAY;AAC1B,YAAY,WAAW;AACvB,
|
|
4
|
+
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { useEffect, useRef, useState, useMemo } from 'react'\nimport { getTheme } from '@utils/theme'\nimport { sample } from 'lodash-es'\nimport { getSessionState, setSessionState } from '@utils/sessionState'\nimport { useUnifiedAnimation } from '@utils/animationManager'\nimport { formatNumber, formatTokenUsage } from '@utils/format'\nimport { BRAND_GRADIENT, SEMANTIC_COLORS } from '@constants/colors'\n\n// NB: The third character in this string is an emoji that\n// renders on Windows consoles with a green background\nconst CHARACTERS =\n process.platform === 'darwin'\n ? ['\u00B7', '\u2722', '\u2733', '\u2217', '\u273B', '\u273D']\n : ['\u00B7', '\u2722', '*', '\u2217', '\u273B', '\u273D']\n\n// Streaming phases for better UX feedback\nexport type StreamingPhase =\n | 'thinking' // Initial thinking phase\n | 'generating' // Generating response content\n | 'tool_use' // Executing a tool\n | 'waiting' // Waiting for API response\n | 'deep_thinking' // Extended thinking mode (Claude thinking blocks)\n | 'retrying' // API retry in progress\n | 'permission' // Waiting for user permission\n | 'compacting' // Compacting conversation context\n | 'concurrent' // Running concurrent tasks\n\n// Streaming state type definition\nexport interface StreamingStateData {\n phase: StreamingPhase\n toolName?: string\n tokenCount?: number\n chunkCount?: number\n // New fields for enhanced feedback\n retryCount?: number\n maxRetries?: number\n errorName?: string\n concurrentCount?: number\n thinkingMaxTokens?: number\n // Token usage from API (real-time streaming)\n inputTokens?: number\n outputTokens?: number\n // Character counts for approximate token estimation\n sentChars?: number // Characters sent to API (input)\n receivedChars?: number // Characters received from API (output)\n // Thinking timing\n thinkingStartTime?: number\n thinkingDurationMs?: number\n}\n\n// Default state factory\nfunction createDefaultState(): StreamingStateData {\n return { phase: 'thinking' }\n}\n\n// Store streaming state per agent (agentId -> state)\n// '__main__' is used for the main/root agent\nconst streamingStates: Map<string, StreamingStateData> = new Map([\n ['__main__', createDefaultState()],\n])\n\n// Current active agent context (stack to support nesting)\nconst agentContextStack: string[] = ['__main__']\n\n/**\n * Get the current active agent ID\n */\nexport function getCurrentAgentContext(): string {\n return agentContextStack[agentContextStack.length - 1] ?? '__main__'\n}\n\n/**\n * Push a new agent context (when entering a subagent)\n */\nexport function pushAgentContext(agentId: string): void {\n agentContextStack.push(agentId)\n if (!streamingStates.has(agentId)) {\n streamingStates.set(agentId, createDefaultState())\n }\n}\n\n/**\n * Pop the current agent context (when exiting a subagent)\n */\nexport function popAgentContext(): string | undefined {\n if (agentContextStack.length > 1) {\n return agentContextStack.pop()\n }\n return undefined\n}\n\n/**\n * Set streaming state for a specific agent (or current context if not specified)\n */\nexport function setStreamingState(\n state: Partial<StreamingStateData>,\n agentId?: string,\n): void {\n const targetId = agentId ?? getCurrentAgentContext()\n const current = streamingStates.get(targetId) ?? createDefaultState()\n streamingStates.set(targetId, { ...current, ...state })\n}\n\n/**\n * Reset streaming state for a specific agent (or current context if not specified)\n */\nexport function resetStreamingState(agentId?: string): void {\n const targetId = agentId ?? getCurrentAgentContext()\n streamingStates.set(targetId, createDefaultState())\n}\n\n/**\n * Get streaming state for a specific agent (or current context if not specified)\n */\nexport function getStreamingState(agentId?: string): StreamingStateData {\n const targetId = agentId ?? getCurrentAgentContext()\n return streamingStates.get(targetId) ?? createDefaultState()\n}\n\n/**\n * Get streaming state for the main/root agent (used by main Spinner)\n */\nexport function getMainStreamingState(): StreamingStateData {\n return streamingStates.get('__main__') ?? createDefaultState()\n}\n\n/**\n * Clean up streaming state for a completed agent\n */\nexport function cleanupAgentStreamingState(agentId: string): void {\n streamingStates.delete(agentId)\n}\n\nconst MESSAGES = [\n 'Accomplishing',\n 'Actioning',\n 'Actualizing',\n 'Baking',\n 'Brewing',\n 'Calculating',\n 'Cerebrating',\n 'Churning',\n 'Coding',\n 'Coalescing',\n 'Cogitating',\n 'Computing',\n 'Conjuring',\n 'Considering',\n 'Cooking',\n 'Crafting',\n 'Creating',\n 'Crunching',\n 'Deliberating',\n 'Determining',\n 'Doing',\n 'Effecting',\n 'Finagling',\n 'Forging',\n 'Forming',\n 'Generating',\n 'Hatching',\n 'Herding',\n 'Honking',\n 'Hustling',\n 'Ideating',\n 'Inferring',\n 'Manifesting',\n 'Marinating',\n 'Moseying',\n 'Mulling',\n 'Mustering',\n 'Musing',\n 'Noodling',\n 'Percolating',\n 'Pondering',\n 'Processing',\n 'Puttering',\n 'Reticulating',\n 'Ruminating',\n 'Schlepping',\n 'Shucking',\n 'Simmering',\n 'Smooshing',\n 'Spinning',\n 'Stewing',\n 'Synthesizing',\n 'Thinking',\n 'Transmuting',\n 'Vibing',\n 'Working',\n]\n\ninterface SpinnerProps {\n /** Whether the spinner should be active (animating) */\n isActive?: boolean\n}\n\nexport function Spinner({ isActive = true }: SpinnerProps): React.ReactNode {\n const frames = [...CHARACTERS, ...[...CHARACTERS].reverse()]\n const message = useRef(sample(MESSAGES))\n const startTime = useRef(Date.now())\n const theme = getTheme()\n\n // Use unified animation manager instead of separate setInterval timers\n const { spinnerFrame, elapsedTime } = useUnifiedAnimation({\n enabled: isActive,\n startTime: startTime.current,\n spinnerFrameCount: frames.length,\n componentId: 'main-spinner',\n })\n\n // Get main streaming state on each render (updates when spinnerFrame changes)\n // Use getMainStreamingState to avoid subagent interference\n const streamState = useMemo(() => getMainStreamingState(), [spinnerFrame])\n\n // Get phase-specific display\n const getPhaseDisplay = () => {\n switch (streamState.phase) {\n case 'deep_thinking': {\n // Show elapsed time and char count for thinking phase\n const elapsed = streamState.thinkingStartTime\n ? Math.floor((Date.now() - streamState.thinkingStartTime) / 1000)\n : 0\n const charInfo = streamState.tokenCount\n ? `${formatNumber(streamState.tokenCount)} chars`\n : ''\n\n if (streamState.thinkingMaxTokens && streamState.tokenCount) {\n return `Deep thinking (${elapsed}s \u00B7 ${charInfo} / ${formatNumber(streamState.thinkingMaxTokens)})`\n }\n return `Deep thinking (${elapsed}s${charInfo ? ' \u00B7 ' + charInfo : ''})`\n }\n\n case 'retrying':\n return streamState.retryCount && streamState.maxRetries\n ? `Retrying (${streamState.retryCount}/${streamState.maxRetries})${streamState.errorName ? ` \u00B7 ${streamState.errorName}` : ''}`\n : streamState.errorName\n ? `Retrying \u00B7 ${streamState.errorName}`\n : 'Retrying...'\n\n case 'permission':\n return 'Waiting for permission...'\n\n case 'compacting':\n return 'Compacting context...'\n\n case 'concurrent':\n return streamState.concurrentCount\n ? `Running ${streamState.concurrentCount} concurrent tasks...`\n : 'Running concurrent tasks...'\n\n case 'tool_use':\n return streamState.toolName\n ? `Using ${streamState.toolName}`\n : 'Executing tool'\n\n case 'generating':\n return 'Receiving'\n\n case 'waiting':\n return 'Waiting for response'\n\n case 'thinking':\n default:\n return message.current\n }\n }\n\n // \u4F7F\u7528\u8BED\u4E49\u989C\u8272\u7CFB\u7EDF\uFF0C\u54C1\u724C\u8272\u7528\u4E8E\u601D\u8003\uFF0C\u72B6\u6001\u8272\u7528\u4E8E\u5404\u9636\u6BB5\n const phaseColors: Record<StreamingPhase, string> = {\n thinking: BRAND_GRADIENT.MIDDLE, // \u7C89\u7D2B - \u601D\u8003\u4E2D\n deep_thinking: BRAND_GRADIENT.START, // \u7D2B\u84DD - \u6DF1\u5EA6\u601D\u8003\n generating: SEMANTIC_COLORS.success, // \u7EFF\u8272 - \u751F\u6210\u4E2D\n tool_use: SEMANTIC_COLORS.running, // \u7C89\u7D2B - \u5DE5\u5177\u6267\u884C\n waiting: SEMANTIC_COLORS.dim, // \u7070\u8272 - \u7B49\u5F85\n retrying: SEMANTIC_COLORS.error, // \u7EA2\u8272 - \u91CD\u8BD5\n permission: SEMANTIC_COLORS.info, // \u84DD\u8272 - \u6743\u9650\n compacting: SEMANTIC_COLORS.info, // \u84DD\u8272 - \u538B\u7F29\n concurrent: SEMANTIC_COLORS.success, // \u7EFF\u8272 - \u5E76\u53D1\n }\n\n // Get token usage from streaming state (API values or approximate from chars)\n const getTokenDisplay = () => {\n // Prefer API-provided token counts - always show bidirectional if available\n if (streamState.inputTokens || streamState.outputTokens) {\n return formatTokenUsage(streamState.inputTokens, streamState.outputTokens)\n }\n // Fallback: approximate from received characters (~3 chars per token for mixed content)\n if (streamState.receivedChars && streamState.receivedChars > 0) {\n const approxOutputTokens = Math.round(streamState.receivedChars / 3)\n // If we have sentChars, show both directions\n if (streamState.sentChars && streamState.sentChars > 0) {\n const approxInputTokens = Math.round(streamState.sentChars / 3)\n return `\u2191 ~${formatNumber(approxInputTokens)} \u00B7 \u2193 ~${formatNumber(approxOutputTokens)}`\n }\n return `\u2193 ~${formatNumber(approxOutputTokens)}`\n }\n return ''\n }\n\n const tokenUsage = getTokenDisplay()\n\n // Get thinking duration if available\n const thinkingDuration = streamState.thinkingDurationMs\n ? Math.floor(streamState.thinkingDurationMs / 1000)\n : null\n\n return (\n <Box flexDirection=\"row\" marginTop={1}>\n <Box flexWrap=\"nowrap\" height={1} width={2}>\n <Text color={phaseColors[streamState.phase]}>\n {frames[spinnerFrame]}\n </Text>\n </Box>\n <Text color={phaseColors[streamState.phase]}>{getPhaseDisplay()}\u2026 </Text>\n <Text color={SEMANTIC_COLORS.dim}>\n (<Text bold>esc esc</Text> to cancel \u00B7 {elapsedTime}s\n {tokenUsage && <Text> \u00B7 {tokenUsage}</Text>}\n {thinkingDuration !== null && thinkingDuration > 0 && (\n <Text> \u00B7 thinking {thinkingDuration}s</Text>\n )}\n )\n </Text>\n {getSessionState('currentError') && (\n <Text color={SEMANTIC_COLORS.dim}>\n \u00B7 {getSessionState('currentError')}\n </Text>\n )}\n </Box>\n )\n}\n\ninterface SimpleSpinnerProps {\n /** Whether the spinner should be active (animating) */\n isActive?: boolean\n /** Optional label to display next to spinner */\n label?: string\n}\n\nexport function SimpleSpinner({\n isActive = true,\n label,\n}: SimpleSpinnerProps): React.ReactNode {\n const frames = [...CHARACTERS, ...[...CHARACTERS].reverse()]\n const startTime = useRef(Date.now())\n\n // Use unified animation manager\n const { spinnerFrame } = useUnifiedAnimation({\n enabled: isActive,\n startTime: startTime.current,\n spinnerFrameCount: frames.length,\n componentId: 'simple-spinner',\n })\n\n return (\n <Box flexDirection=\"row\">\n <Box flexWrap=\"nowrap\" height={1} width={2}>\n <Text color={BRAND_GRADIENT.MIDDLE}>{frames[spinnerFrame]}</Text>\n </Box>\n {label && <Text color={SEMANTIC_COLORS.dim}> {label}</Text>}\n </Box>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,27 +1,25 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useRef } from "react";
|
|
2
2
|
import { Text } from "ink";
|
|
3
3
|
import { SYMBOLS } from "../constants/symbols.js";
|
|
4
4
|
import { getAgentColor } from "../constants/colors.js";
|
|
5
5
|
import { getTheme } from "../utils/theme.js";
|
|
6
|
+
import { useUnifiedAnimation } from "../utils/animationManager.js";
|
|
6
7
|
function SpinnerSymbol({
|
|
7
8
|
isRunning,
|
|
8
9
|
color,
|
|
9
|
-
symbol = SYMBOLS.TASK_INDICATOR
|
|
10
|
-
interval = 500
|
|
10
|
+
symbol = SYMBOLS.TASK_INDICATOR
|
|
11
11
|
}) {
|
|
12
12
|
const theme = getTheme();
|
|
13
13
|
const baseColor = getAgentColor(color, theme);
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return () => clearInterval(timer);
|
|
24
|
-
}, [isRunning, interval]);
|
|
14
|
+
const startTimeRef = useRef(Date.now());
|
|
15
|
+
const { dotVisible } = useUnifiedAnimation({
|
|
16
|
+
enabled: isRunning,
|
|
17
|
+
startTime: startTimeRef.current,
|
|
18
|
+
spinnerFrameCount: 2,
|
|
19
|
+
// Just for alternation
|
|
20
|
+
componentId: "spinner-symbol"
|
|
21
|
+
});
|
|
22
|
+
const isBright = isRunning ? dotVisible : true;
|
|
25
23
|
const displayColor = isRunning && !isBright ? dimColor(baseColor) : baseColor;
|
|
26
24
|
return /* @__PURE__ */ React.createElement(Text, { color: displayColor }, symbol);
|
|
27
25
|
}
|
|
@@ -51,23 +49,19 @@ function getBlinkingSymbols() {
|
|
|
51
49
|
}
|
|
52
50
|
function SpinnerSymbolAlternative({
|
|
53
51
|
isRunning,
|
|
54
|
-
color
|
|
55
|
-
interval = 500
|
|
52
|
+
color
|
|
56
53
|
}) {
|
|
57
54
|
const theme = getTheme();
|
|
58
55
|
const displayColor = getAgentColor(color, theme);
|
|
56
|
+
const startTimeRef = useRef(Date.now());
|
|
59
57
|
const symbols = getBlinkingSymbols();
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
setFrameIndex((prev) => (prev + 1) % symbols.length);
|
|
68
|
-
}, interval);
|
|
69
|
-
return () => clearInterval(timer);
|
|
70
|
-
}, [isRunning, interval, symbols.length]);
|
|
58
|
+
const { spinnerFrame } = useUnifiedAnimation({
|
|
59
|
+
enabled: isRunning,
|
|
60
|
+
startTime: startTimeRef.current,
|
|
61
|
+
spinnerFrameCount: symbols.length,
|
|
62
|
+
componentId: "spinner-symbol-alt"
|
|
63
|
+
});
|
|
64
|
+
const frameIndex = isRunning ? spinnerFrame : 0;
|
|
71
65
|
return /* @__PURE__ */ React.createElement(Text, { color: displayColor }, symbols[frameIndex]);
|
|
72
66
|
}
|
|
73
67
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/components/SpinnerSymbol.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, {
|
|
5
|
-
"mappings": "AAAA,OAAO,SAAS,
|
|
4
|
+
"sourcesContent": ["import React, { useRef, useMemo } from 'react'\nimport { Text } from 'ink'\nimport { SYMBOLS } from '@constants/symbols'\nimport { getAgentColor } from '@constants/colors'\nimport { getTheme } from '@utils/theme'\nimport { useUnifiedAnimation } from '@utils/animationManager'\nimport type { AgentColor } from '@constants/colors'\n\ninterface SpinnerSymbolProps {\n /** \u662F\u5426\u6B63\u5728\u8FD0\u884C\uFF08\u63A7\u5236\u95EA\u70C1\uFF09 */\n isRunning: boolean\n /** Agent \u989C\u8272 */\n color?: AgentColor\n /** \u81EA\u5B9A\u4E49\u7B26\u53F7\uFF08\u9ED8\u8BA4\u4F7F\u7528 TASK_INDICATOR \u23FA\uFF09 */\n symbol?: string\n /** \u95EA\u70C1\u95F4\u9694\uFF08\u6BEB\u79D2\uFF0C\u9ED8\u8BA4 500ms\uFF09- \u4E0D\u518D\u4F7F\u7528\uFF0C\u4FDD\u7559\u7528\u4E8E\u5411\u540E\u517C\u5BB9 */\n interval?: number\n}\n\n/**\n * \u95EA\u70C1\u7684\u4EFB\u52A1\u6307\u793A\u5668\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u4EFB\u52A1\u6267\u884C\u4E2D\uFF1A\u23FA \u7B26\u53F7\u4EE5\u6307\u5B9A\u989C\u8272\u95EA\u70C1\uFF08\u4EAE \u2192 \u6697\u4EA4\u66FF\uFF09\n * - \u4EFB\u52A1\u5B8C\u6210\u540E\uFF1A\u23FA \u7B26\u53F7\u505C\u6B62\u95EA\u70C1\uFF0C\u4FDD\u6301\u56FA\u5B9A\u989C\u8272\n * - \u652F\u6301\u81EA\u5B9A\u4E49\u989C\u8272\u548C\u95EA\u70C1\u9891\u7387\n *\n * \u5B9E\u73B0\u539F\u7406\uFF1A\n * \u4F7F\u7528\u7EDF\u4E00\u52A8\u753B\u7BA1\u7406\u5668\u4EE3\u66FF setInterval\uFF0C\u51CF\u5C11\u5C4F\u5E55\u95EA\u70C1\n */\nexport function SpinnerSymbol({\n isRunning,\n color,\n symbol = SYMBOLS.TASK_INDICATOR,\n}: SpinnerSymbolProps) {\n const theme = getTheme()\n const baseColor = getAgentColor(color, theme)\n const startTimeRef = useRef(Date.now())\n\n // Use unified animation manager with 2 frames (bright/dim)\n const { dotVisible } = useUnifiedAnimation({\n enabled: isRunning,\n startTime: startTimeRef.current,\n spinnerFrameCount: 2, // Just for alternation\n componentId: 'spinner-symbol',\n })\n\n // dotVisible alternates at 600ms, perfect for blink effect\n const isBright = isRunning ? dotVisible : true\n\n // \u6839\u636E\u95EA\u70C1\u72B6\u6001\u8C03\u6574\u989C\u8272\u4EAE\u5EA6\n const displayColor = isRunning && !isBright ? dimColor(baseColor) : baseColor\n\n return <Text color={displayColor}>{symbol}</Text>\n}\n\n/**\n * \u964D\u4F4E\u989C\u8272\u4EAE\u5EA6\uFF08\u6A21\u62DF\u6697\u72B6\u6001\uFF09\n *\n * @param color - Hex \u989C\u8272\u503C\uFF08\u5982 #FF5555\uFF09\n * @returns \u964D\u4F4E\u4EAE\u5EA6\u540E\u7684 Hex \u989C\u8272\u503C\n */\nfunction dimColor(color: string): string {\n // \u79FB\u9664 # \u524D\u7F00\n const hex = color.replace('#', '')\n\n // \u8F6C\u6362\u4E3A RGB\n const r = parseInt(hex.substring(0, 2), 16)\n const g = parseInt(hex.substring(2, 4), 16)\n const b = parseInt(hex.substring(4, 6), 16)\n\n // \u964D\u4F4E\u4EAE\u5EA6\u5230 40%\n const dimFactor = 0.4\n const dimR = Math.floor(r * dimFactor)\n const dimG = Math.floor(g * dimFactor)\n const dimB = Math.floor(b * dimFactor)\n\n // \u8F6C\u6362\u56DE Hex\n const toHex = (n: number) => n.toString(16).padStart(2, '0')\n return `#${toHex(dimR)}${toHex(dimG)}${toHex(dimB)}`\n}\n\n/**\n * \u83B7\u53D6\u95EA\u70C1\u5E27\u7B26\u53F7\uFF08\u5907\u9009\u65B9\u6848\uFF1A\u4F7F\u7528\u4E0D\u540C\u7B26\u53F7\u6A21\u62DF\u95EA\u70C1\uFF09\n *\n * \u5982\u679C\u7EC8\u7AEF\u4E0D\u652F\u6301\u989C\u8272\u8C03\u6574\uFF0C\u53EF\u4EE5\u4F7F\u7528\u4E0D\u540C\u7B26\u53F7\u4EA4\u66FF\u663E\u793A\n */\nexport function getBlinkingSymbols(): string[] {\n return [\n '\u23FA', // \u5B9E\u5FC3\u5706\n '\u25C9', // \u5927\u5706\u70B9\n '\u25CF', // \u4E2D\u5706\u70B9\n '\u25CB', // \u7A7A\u5FC3\u5706\n ]\n}\n\n/**\n * \u95EA\u70C1\u7684\u4EFB\u52A1\u6307\u793A\u5668\uFF08\u5907\u9009\u65B9\u6848\uFF1A\u7B26\u53F7\u4EA4\u66FF\uFF09\n *\n * \u4F7F\u7528\u4E0D\u540C\u7B26\u53F7\u6A21\u62DF\u95EA\u70C1\u6548\u679C\uFF0C\u9002\u7528\u4E8E\u4E0D\u652F\u6301\u989C\u8272\u8C03\u6574\u7684\u7EC8\u7AEF\n * \u4F7F\u7528\u7EDF\u4E00\u52A8\u753B\u7BA1\u7406\u5668\u4EE3\u66FF setInterval\n */\nexport function SpinnerSymbolAlternative({\n isRunning,\n color,\n}: Omit<SpinnerSymbolProps, 'symbol'>) {\n const theme = getTheme()\n const displayColor = getAgentColor(color, theme)\n const startTimeRef = useRef(Date.now())\n\n const symbols = getBlinkingSymbols()\n\n // Use unified animation manager\n const { spinnerFrame } = useUnifiedAnimation({\n enabled: isRunning,\n startTime: startTimeRef.current,\n spinnerFrameCount: symbols.length,\n componentId: 'spinner-symbol-alt',\n })\n\n const frameIndex = isRunning ? spinnerFrame : 0\n\n return <Text color={displayColor}>{symbols[frameIndex]}</Text>\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,SAAS,cAAuB;AACvC,SAAS,YAAY;AACrB,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,SAAS,2BAA2B;AAyB7B,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,SAAS,QAAQ;AACnB,GAAuB;AACrB,QAAM,QAAQ,SAAS;AACvB,QAAM,YAAY,cAAc,OAAO,KAAK;AAC5C,QAAM,eAAe,OAAO,KAAK,IAAI,CAAC;AAGtC,QAAM,EAAE,WAAW,IAAI,oBAAoB;AAAA,IACzC,SAAS;AAAA,IACT,WAAW,aAAa;AAAA,IACxB,mBAAmB;AAAA;AAAA,IACnB,aAAa;AAAA,EACf,CAAC;AAGD,QAAM,WAAW,YAAY,aAAa;AAG1C,QAAM,eAAe,aAAa,CAAC,WAAW,SAAS,SAAS,IAAI;AAEpE,SAAO,oCAAC,QAAK,OAAO,gBAAe,MAAO;AAC5C;AAQA,SAAS,SAAS,OAAuB;AAEvC,QAAM,MAAM,MAAM,QAAQ,KAAK,EAAE;AAGjC,QAAM,IAAI,SAAS,IAAI,UAAU,GAAG,CAAC,GAAG,EAAE;AAC1C,QAAM,IAAI,SAAS,IAAI,UAAU,GAAG,CAAC,GAAG,EAAE;AAC1C,QAAM,IAAI,SAAS,IAAI,UAAU,GAAG,CAAC,GAAG,EAAE;AAG1C,QAAM,YAAY;AAClB,QAAM,OAAO,KAAK,MAAM,IAAI,SAAS;AACrC,QAAM,OAAO,KAAK,MAAM,IAAI,SAAS;AACrC,QAAM,OAAO,KAAK,MAAM,IAAI,SAAS;AAGrC,QAAM,QAAQ,CAAC,MAAc,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAC3D,SAAO,IAAI,MAAM,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC;AACpD;AAOO,SAAS,qBAA+B;AAC7C,SAAO;AAAA,IACL;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,EACF;AACF;AAQO,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AACF,GAAuC;AACrC,QAAM,QAAQ,SAAS;AACvB,QAAM,eAAe,cAAc,OAAO,KAAK;AAC/C,QAAM,eAAe,OAAO,KAAK,IAAI,CAAC;AAEtC,QAAM,UAAU,mBAAmB;AAGnC,QAAM,EAAE,aAAa,IAAI,oBAAoB;AAAA,IAC3C,SAAS;AAAA,IACT,WAAW,aAAa;AAAA,IACxB,mBAAmB,QAAQ;AAAA,IAC3B,aAAa;AAAA,EACf,CAAC;AAED,QAAM,aAAa,YAAY,eAAe;AAE9C,SAAO,oCAAC,QAAK,OAAO,gBAAe,QAAQ,UAAU,CAAE;AACzD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -3,6 +3,7 @@ import * as React from "react";
|
|
|
3
3
|
import { useState, useEffect, useRef } from "react";
|
|
4
4
|
import { getTheme } from "../utils/theme.js";
|
|
5
5
|
import { BackgroundShellManager } from "../utils/BackgroundShellManager.js";
|
|
6
|
+
import { useUnifiedAnimation } from "../utils/animationManager.js";
|
|
6
7
|
const MAX_SUMMARY_LINES = 5;
|
|
7
8
|
const MAX_DETAIL_LINES = 50;
|
|
8
9
|
function StreamingBashOutput({
|
|
@@ -13,11 +14,17 @@ function StreamingBashOutput({
|
|
|
13
14
|
}) {
|
|
14
15
|
const [outputLines, setOutputLines] = useState([]);
|
|
15
16
|
const [hiddenLineCount, setHiddenLineCount] = useState(0);
|
|
16
|
-
const [elapsedTime, setElapsedTime] = useState(0);
|
|
17
17
|
const [isComplete, setIsComplete] = useState(false);
|
|
18
18
|
const [showDetail, setShowDetail] = useState(false);
|
|
19
|
-
const
|
|
19
|
+
const startTimeRef = useRef(Date.now());
|
|
20
20
|
const theme = getTheme();
|
|
21
|
+
const { elapsedTime } = useUnifiedAnimation({
|
|
22
|
+
enabled: !isComplete,
|
|
23
|
+
startTime: startTimeRef.current,
|
|
24
|
+
spinnerFrameCount: 1,
|
|
25
|
+
// Not used but required
|
|
26
|
+
componentId: `streaming-bash-${shellId}`
|
|
27
|
+
});
|
|
21
28
|
useInput((input, key) => {
|
|
22
29
|
if (key.ctrl && input === "b") {
|
|
23
30
|
onMoveToBackground();
|
|
@@ -25,12 +32,6 @@ function StreamingBashOutput({
|
|
|
25
32
|
setShowDetail((prev) => !prev);
|
|
26
33
|
}
|
|
27
34
|
});
|
|
28
|
-
useEffect(() => {
|
|
29
|
-
const interval = setInterval(() => {
|
|
30
|
-
setElapsedTime(Math.floor((Date.now() - startTime.current) / 1e3));
|
|
31
|
-
}, 1e3);
|
|
32
|
-
return () => clearInterval(interval);
|
|
33
|
-
}, []);
|
|
34
35
|
useEffect(() => {
|
|
35
36
|
const manager = BackgroundShellManager.getInstance();
|
|
36
37
|
const interval = setInterval(() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/components/StreamingBashOutput.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Box, Text, useInput } from 'ink'\nimport * as React from 'react'\nimport { useState, useEffect, useRef } from 'react'\nimport { getTheme } from '@utils/theme'\nimport { BackgroundShellManager } from '@utils/BackgroundShellManager'\n\ntype Props = {\n shellId: string\n command: string\n onMoveToBackground: () => void\n onComplete: (stdout: string, stderr: string, exitCode: number) => void\n}\n\nconst MAX_SUMMARY_LINES = 5 // Show only first few lines in summary mode\nconst MAX_DETAIL_LINES = 50 // Show more lines in detail mode\n\nexport function StreamingBashOutput({\n shellId,\n command,\n onMoveToBackground,\n onComplete,\n}: Props) {\n const [outputLines, setOutputLines] = useState<string[]>([])\n const [hiddenLineCount, setHiddenLineCount] = useState(0)\n const [
|
|
5
|
-
"mappings": "AAAA,SAAS,KAAK,MAAM,gBAAgB;AACpC,YAAY,WAAW;AACvB,SAAS,UAAU,WAAW,cAAc;AAC5C,SAAS,gBAAgB;AACzB,SAAS,8BAA8B;
|
|
4
|
+
"sourcesContent": ["import { Box, Text, useInput } from 'ink'\nimport * as React from 'react'\nimport { useState, useEffect, useRef } from 'react'\nimport { getTheme } from '@utils/theme'\nimport { BackgroundShellManager } from '@utils/BackgroundShellManager'\nimport { useUnifiedAnimation } from '@utils/animationManager'\n\ntype Props = {\n shellId: string\n command: string\n onMoveToBackground: () => void\n onComplete: (stdout: string, stderr: string, exitCode: number) => void\n}\n\nconst MAX_SUMMARY_LINES = 5 // Show only first few lines in summary mode\nconst MAX_DETAIL_LINES = 50 // Show more lines in detail mode\n\nexport function StreamingBashOutput({\n shellId,\n command,\n onMoveToBackground,\n onComplete,\n}: Props) {\n const [outputLines, setOutputLines] = useState<string[]>([])\n const [hiddenLineCount, setHiddenLineCount] = useState(0)\n const [isComplete, setIsComplete] = useState(false)\n const [showDetail, setShowDetail] = useState(false) // Ctrl+O toggle\n const startTimeRef = useRef(Date.now())\n const theme = getTheme()\n\n // Use unified animation manager for elapsed time instead of setInterval\n const { elapsedTime } = useUnifiedAnimation({\n enabled: !isComplete,\n startTime: startTimeRef.current,\n spinnerFrameCount: 1, // Not used but required\n componentId: `streaming-bash-${shellId}`,\n })\n\n // Listen for keyboard shortcuts\n useInput((input, key) => {\n if (key.ctrl && input === 'b') {\n onMoveToBackground()\n } else if (key.ctrl && input === 'o') {\n setShowDetail(prev => !prev)\n }\n })\n\n // Poll for output from background shell\n useEffect(() => {\n const manager = BackgroundShellManager.getInstance()\n\n const interval = setInterval(() => {\n const shell = manager.get(shellId)\n if (!shell) return\n\n // Get all output\n const allLines = [...shell.stdout, ...shell.stderr].filter(\n line => line.trim().length > 0,\n )\n setOutputLines(allLines)\n\n // Calculate hidden lines based on current mode\n const maxLines = showDetail ? MAX_DETAIL_LINES : MAX_SUMMARY_LINES\n if (allLines.length > maxLines) {\n setHiddenLineCount(allLines.length - maxLines)\n } else {\n setHiddenLineCount(0)\n }\n\n // Check if complete\n if (shell.status !== 'running' && !isComplete) {\n setIsComplete(true)\n clearInterval(interval)\n\n // Clean up the shell after getting final output\n const stdout = shell.stdout.join('\\n')\n const stderr = shell.stderr.join('\\n')\n const exitCode = shell.exitCode ?? 0\n\n // Remove from manager after a short delay\n setTimeout(() => {\n manager.remove(shellId)\n }, 1000)\n\n onComplete(stdout, stderr, exitCode)\n }\n }, 100)\n\n return () => clearInterval(interval)\n }, [shellId, isComplete, onComplete, showDetail])\n\n const maxLines = showDetail ? MAX_DETAIL_LINES : MAX_SUMMARY_LINES\n const visibleLines = outputLines.slice(0, maxLines) // Show first N lines, not last N\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box>\n <Text color={theme.bashBorder}>! </Text>\n <Text>{command}</Text>\n </Box>\n\n {visibleLines.length > 0 && (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Text color={theme.secondaryText}>\u23BF </Text>\n {visibleLines.map((line, index) => (\n <Box key={index}>\n <Text>{line}</Text>\n </Box>\n ))}\n </Box>\n )}\n\n {hiddenLineCount > 0 && (\n <Box paddingLeft={2}>\n <Text color={theme.secondaryText}>\n +{hiddenLineCount} more lines ({elapsedTime}s)\n </Text>\n </Box>\n )}\n\n {!isComplete && (\n <Box paddingLeft={2} marginTop={1} flexDirection=\"row\" gap={1}>\n <Text color={theme.secondaryText}>\n ctrl+o {showDetail ? 'hide details' : 'show details'}\n </Text>\n <Text color={theme.secondaryText}>\u00B7</Text>\n <Text color={theme.warning}>ctrl+b run in background</Text>\n </Box>\n )}\n </Box>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["maxLines"]
|
|
7
7
|
}
|
|
@@ -3,6 +3,7 @@ import * as React from "react";
|
|
|
3
3
|
import { getTheme } from "../utils/theme.js";
|
|
4
4
|
import { useMemo } from "react";
|
|
5
5
|
import { wrapText } from "../utils/format.js";
|
|
6
|
+
import { SEMANTIC_COLORS } from "../constants/colors.js";
|
|
6
7
|
function StructuredDiff({
|
|
7
8
|
patch,
|
|
8
9
|
dim,
|
|
@@ -54,9 +55,8 @@ function formatDiff(lines, startingLineNumber, width, dim, overrideTheme) {
|
|
|
54
55
|
), /* @__PURE__ */ React.createElement(
|
|
55
56
|
Text,
|
|
56
57
|
{
|
|
57
|
-
color: overrideTheme ? theme.text : void 0,
|
|
58
|
-
backgroundColor: dim ? theme.diff.addedDimmed : theme.diff.added
|
|
59
|
-
dimColor: dim
|
|
58
|
+
color: dim ? SEMANTIC_COLORS.dim : overrideTheme ? theme.text : void 0,
|
|
59
|
+
backgroundColor: dim ? theme.diff.addedDimmed : theme.diff.added
|
|
60
60
|
},
|
|
61
61
|
line
|
|
62
62
|
)));
|
|
@@ -70,9 +70,8 @@ function formatDiff(lines, startingLineNumber, width, dim, overrideTheme) {
|
|
|
70
70
|
), /* @__PURE__ */ React.createElement(
|
|
71
71
|
Text,
|
|
72
72
|
{
|
|
73
|
-
color: overrideTheme ? theme.text : void 0,
|
|
74
|
-
backgroundColor: dim ? theme.diff.removedDimmed : theme.diff.removed
|
|
75
|
-
dimColor: dim
|
|
73
|
+
color: dim ? SEMANTIC_COLORS.dim : overrideTheme ? theme.text : void 0,
|
|
74
|
+
backgroundColor: dim ? theme.diff.removedDimmed : theme.diff.removed
|
|
76
75
|
},
|
|
77
76
|
line
|
|
78
77
|
)));
|
|
@@ -86,8 +85,7 @@ function formatDiff(lines, startingLineNumber, width, dim, overrideTheme) {
|
|
|
86
85
|
), /* @__PURE__ */ React.createElement(
|
|
87
86
|
Text,
|
|
88
87
|
{
|
|
89
|
-
color: overrideTheme ? theme.text : void 0
|
|
90
|
-
dimColor: dim
|
|
88
|
+
color: dim ? SEMANTIC_COLORS.dim : overrideTheme ? theme.text : void 0
|
|
91
89
|
},
|
|
92
90
|
line
|
|
93
91
|
)));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/components/StructuredDiff.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { Hunk } from 'diff'\nimport { getTheme, ThemeNames } from '@utils/theme'\nimport { useMemo } from 'react'\nimport { wrapText } from '@utils/format'\n\ntype Props = {\n patch: Hunk\n dim: boolean\n width: number\n overrideTheme?: ThemeNames // custom theme for previews\n key?: React.Key\n}\n\nexport function StructuredDiff({\n patch,\n dim,\n width,\n overrideTheme,\n}: Props): React.ReactNode {\n const diff = useMemo(\n () => formatDiff(patch.lines, patch.oldStart, width, dim, overrideTheme),\n [patch.lines, patch.oldStart, width, dim, overrideTheme],\n )\n\n return diff.map((_, i) => <Box key={i}>{_}</Box>)\n}\n\nfunction formatDiff(\n lines: string[],\n startingLineNumber: number,\n width: number,\n dim: boolean,\n overrideTheme?: ThemeNames,\n): React.ReactNode[] {\n const theme = getTheme(overrideTheme)\n\n const ls = numberDiffLines(\n lines.map(code => {\n if (code.startsWith('+')) {\n return {\n code: ' ' + code.slice(1),\n i: 0,\n type: 'add',\n }\n }\n if (code.startsWith('-')) {\n return {\n code: ' ' + code.slice(1),\n i: 0,\n type: 'remove',\n }\n }\n return { code, i: 0, type: 'nochange' }\n }),\n startingLineNumber,\n )\n\n const maxLineNumber = Math.max(...ls.map(({ i }) => i))\n const maxWidth = maxLineNumber.toString().length\n\n return ls.flatMap(({ type, code, i }) => {\n const wrappedLines = wrapText(code, width - maxWidth)\n return wrappedLines.map((line, lineIndex) => {\n const key = `${type}-${i}-${lineIndex}`\n switch (type) {\n case 'add':\n return (\n <React.Fragment key={key}>\n <Text>\n <LineNumber\n i={lineIndex === 0 ? i : undefined}\n width={maxWidth}\n />\n <Text\n color={overrideTheme
|
|
5
|
-
"mappings": "AAAA,SAAS,KAAK,YAAY;AAC1B,YAAY,WAAW;AAEvB,SAAS,gBAA4B;AACrC,SAAS,eAAe;AACxB,SAAS,gBAAgB;
|
|
4
|
+
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { Hunk } from 'diff'\nimport { getTheme, ThemeNames } from '@utils/theme'\nimport { useMemo } from 'react'\nimport { wrapText } from '@utils/format'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\ntype Props = {\n patch: Hunk\n dim: boolean\n width: number\n overrideTheme?: ThemeNames // custom theme for previews\n key?: React.Key\n}\n\nexport function StructuredDiff({\n patch,\n dim,\n width,\n overrideTheme,\n}: Props): React.ReactNode {\n const diff = useMemo(\n () => formatDiff(patch.lines, patch.oldStart, width, dim, overrideTheme),\n [patch.lines, patch.oldStart, width, dim, overrideTheme],\n )\n\n return diff.map((_, i) => <Box key={i}>{_}</Box>)\n}\n\nfunction formatDiff(\n lines: string[],\n startingLineNumber: number,\n width: number,\n dim: boolean,\n overrideTheme?: ThemeNames,\n): React.ReactNode[] {\n const theme = getTheme(overrideTheme)\n\n const ls = numberDiffLines(\n lines.map(code => {\n if (code.startsWith('+')) {\n return {\n code: ' ' + code.slice(1),\n i: 0,\n type: 'add',\n }\n }\n if (code.startsWith('-')) {\n return {\n code: ' ' + code.slice(1),\n i: 0,\n type: 'remove',\n }\n }\n return { code, i: 0, type: 'nochange' }\n }),\n startingLineNumber,\n )\n\n const maxLineNumber = Math.max(...ls.map(({ i }) => i))\n const maxWidth = maxLineNumber.toString().length\n\n return ls.flatMap(({ type, code, i }) => {\n const wrappedLines = wrapText(code, width - maxWidth)\n return wrappedLines.map((line, lineIndex) => {\n const key = `${type}-${i}-${lineIndex}`\n switch (type) {\n case 'add':\n return (\n <React.Fragment key={key}>\n <Text>\n <LineNumber\n i={lineIndex === 0 ? i : undefined}\n width={maxWidth}\n />\n <Text\n color={\n dim\n ? SEMANTIC_COLORS.dim\n : overrideTheme\n ? theme.text\n : undefined\n }\n backgroundColor={\n dim ? theme.diff.addedDimmed : theme.diff.added\n }\n >\n {line}\n </Text>\n </Text>\n </React.Fragment>\n )\n case 'remove':\n return (\n <React.Fragment key={key}>\n <Text>\n <LineNumber\n i={lineIndex === 0 ? i : undefined}\n width={maxWidth}\n />\n <Text\n color={\n dim\n ? SEMANTIC_COLORS.dim\n : overrideTheme\n ? theme.text\n : undefined\n }\n backgroundColor={\n dim ? theme.diff.removedDimmed : theme.diff.removed\n }\n >\n {line}\n </Text>\n </Text>\n </React.Fragment>\n )\n case 'nochange':\n return (\n <React.Fragment key={key}>\n <Text>\n <LineNumber\n i={lineIndex === 0 ? i : undefined}\n width={maxWidth}\n />\n <Text\n color={\n dim\n ? SEMANTIC_COLORS.dim\n : overrideTheme\n ? theme.text\n : undefined\n }\n >\n {line}\n </Text>\n </Text>\n </React.Fragment>\n )\n }\n })\n })\n}\n\nfunction LineNumber({\n i,\n width,\n}: {\n i: number | undefined\n width: number\n}): React.ReactNode {\n return (\n <Text color={getTheme().secondaryText}>\n {i !== undefined ? i.toString().padStart(width) : ' '.repeat(width)}{' '}\n </Text>\n )\n}\n\nfunction numberDiffLines(\n diff: { code: string; type: string }[],\n startLine: number,\n): { code: string; type: string; i: number }[] {\n let i = startLine\n const result: { code: string; type: string; i: number }[] = []\n const queue = [...diff]\n\n while (queue.length > 0) {\n const { code, type } = queue.shift()!\n const line = {\n code: code,\n type,\n i,\n }\n\n // Update counters based on change type\n switch (type) {\n case 'nochange':\n i++\n result.push(line)\n break\n case 'add':\n i++\n result.push(line)\n break\n case 'remove': {\n result.push(line)\n let numRemoved = 0\n while (queue[0]?.type === 'remove') {\n i++\n const { code, type } = queue.shift()!\n const line = {\n code: code,\n type,\n i,\n }\n result.push(line)\n numRemoved++\n }\n i -= numRemoved\n break\n }\n }\n }\n\n return result\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["code", "type", "line"]
|
|
7
7
|
}
|
|
@@ -5,6 +5,7 @@ import { getTodoStatusSymbol } from "../constants/symbols.js";
|
|
|
5
5
|
import { AgentThinkingBlock } from "./AgentThinkingBlock.js";
|
|
6
6
|
import { ToolExecutionBlock } from "./ToolExecutionBlock.js";
|
|
7
7
|
import { AgentResponseBlock } from "./AgentResponseBlock.js";
|
|
8
|
+
import { useAgentTokenStats, formatTokenCount } from "../hooks/useAgentTokenStats.js";
|
|
8
9
|
function SubagentBlock({
|
|
9
10
|
subagent,
|
|
10
11
|
indent = 0,
|
|
@@ -13,6 +14,7 @@ function SubagentBlock({
|
|
|
13
14
|
const theme = getTheme();
|
|
14
15
|
const [expanded, setExpanded] = useState(isExpanded);
|
|
15
16
|
const marginLeft = indent * 2;
|
|
17
|
+
const tokenStats = useAgentTokenStats(subagent.id);
|
|
16
18
|
const todos = extractSubagentTodos(subagent);
|
|
17
19
|
const thinking = extractThinkingMessage(subagent);
|
|
18
20
|
const toolExecutions = extractToolExecutions(subagent);
|
|
@@ -20,7 +22,7 @@ function SubagentBlock({
|
|
|
20
22
|
const duration = subagent.metrics.endTime ? ((subagent.metrics.endTime - subagent.metrics.startTime) / 1e3).toFixed(
|
|
21
23
|
1
|
|
22
24
|
) : "...";
|
|
23
|
-
const tokenCount =
|
|
25
|
+
const tokenCount = tokenStats?.grandTotalTokens ?? 0;
|
|
24
26
|
const statusIndicator = getStatusIndicator(subagent.status);
|
|
25
27
|
const statusColor = getStatusColor(subagent.status, theme);
|
|
26
28
|
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginLeft, marginTop: 1 }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: theme.brand }, "\u{1F916} "), /* @__PURE__ */ React.createElement(Text, null, "Launching subagent: ", /* @__PURE__ */ React.createElement(Text, { bold: true }, subagent.agentType))), /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: theme.dimmedText }, "\u251C\u2500 "), /* @__PURE__ */ React.createElement(Text, null, "Task: ", subagent.taskName)), expanded && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: theme.dimmedText }, "\u2502"), todos && todos.length > 0 && /* @__PURE__ */ React.createElement(SubagentTodosSection, { todos, theme }), thinking && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.dimmedText }, "\u2502 "), /* @__PURE__ */ React.createElement(
|
|
@@ -38,7 +40,7 @@ function SubagentBlock({
|
|
|
38
40
|
indent: 0,
|
|
39
41
|
isSubagent: true
|
|
40
42
|
}
|
|
41
|
-
)), /* @__PURE__ */ React.createElement(Text, { color: theme.dimmedText }, "\u2502")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: theme.dimmedText }, "\u2514\u2500 "), /* @__PURE__ */ React.createElement(Text, { color: statusColor }, statusIndicator, " ", getStatusLabel(subagent.status)), subagent.status === "completed" && /* @__PURE__ */ React.createElement(Text, { color: theme.mutedText }, " ", "(", duration, "s, ", tokenCount, " tokens)")), !expanded && /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", marginLeft: 4 }, /* @__PURE__ */ React.createElement(Text, { color: theme.mutedText }, "Press ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Ctrl+O"), " to expand details")));
|
|
43
|
+
)), /* @__PURE__ */ React.createElement(Text, { color: theme.dimmedText }, "\u2502")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: theme.dimmedText }, "\u2514\u2500 "), /* @__PURE__ */ React.createElement(Text, { color: statusColor }, statusIndicator, " ", getStatusLabel(subagent.status)), subagent.status === "completed" && /* @__PURE__ */ React.createElement(Text, { color: theme.mutedText }, " ", "(", duration, "s, ", formatTokenCount(tokenCount), " tokens)")), !expanded && /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", marginLeft: 4 }, /* @__PURE__ */ React.createElement(Text, { color: theme.mutedText }, "Press ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Ctrl+O"), " to expand details")));
|
|
42
44
|
}
|
|
43
45
|
function SubagentTodosSection({
|
|
44
46
|
todos,
|
|
@@ -146,7 +148,7 @@ function getStatusLabel(status) {
|
|
|
146
148
|
case "running":
|
|
147
149
|
return "Running...";
|
|
148
150
|
case "completed":
|
|
149
|
-
return "
|
|
151
|
+
return "Done";
|
|
150
152
|
case "error":
|
|
151
153
|
return "Error";
|
|
152
154
|
}
|