@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,72 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
import { tokenStatsManager } from "@core/tokenStatsManager";
|
|
3
|
+
function useAgentTokenStats(agentId) {
|
|
4
|
+
const [stats, setStats] = useState(() => {
|
|
5
|
+
if (!agentId) return null;
|
|
6
|
+
return tokenStatsManager.getAgentStats(agentId);
|
|
7
|
+
});
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (!agentId) {
|
|
10
|
+
setStats(null);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const initialStats = tokenStatsManager.getAgentStats(agentId);
|
|
14
|
+
if (initialStats) {
|
|
15
|
+
setStats(initialStats);
|
|
16
|
+
}
|
|
17
|
+
const unsubscribe = tokenStatsManager.onAgentStatsUpdate(
|
|
18
|
+
agentId,
|
|
19
|
+
(newStats) => {
|
|
20
|
+
setStats(newStats);
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
return unsubscribe;
|
|
24
|
+
}, [agentId]);
|
|
25
|
+
return stats;
|
|
26
|
+
}
|
|
27
|
+
function useGlobalTokenStats() {
|
|
28
|
+
const [stats, setStats] = useState(
|
|
29
|
+
() => tokenStatsManager.getGlobalStats()
|
|
30
|
+
);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const unsubscribe = tokenStatsManager.onGlobalStatsUpdate((newStats) => {
|
|
33
|
+
setStats(newStats);
|
|
34
|
+
});
|
|
35
|
+
return unsubscribe;
|
|
36
|
+
}, []);
|
|
37
|
+
return stats;
|
|
38
|
+
}
|
|
39
|
+
function useAllAgentTokenStats() {
|
|
40
|
+
const [stats, setStats] = useState(
|
|
41
|
+
() => tokenStatsManager.getAllAgentStats()
|
|
42
|
+
);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
const unsubscribe = tokenStatsManager.onStatsUpdate((event) => {
|
|
45
|
+
setStats(tokenStatsManager.getAllAgentStats());
|
|
46
|
+
});
|
|
47
|
+
return unsubscribe;
|
|
48
|
+
}, []);
|
|
49
|
+
return stats;
|
|
50
|
+
}
|
|
51
|
+
function formatTokenCount(count) {
|
|
52
|
+
if (count >= 1e6) {
|
|
53
|
+
return `${(count / 1e6).toFixed(1)}M`;
|
|
54
|
+
}
|
|
55
|
+
if (count >= 1e3) {
|
|
56
|
+
return `${(count / 1e3).toFixed(1)}k`;
|
|
57
|
+
}
|
|
58
|
+
return count.toString();
|
|
59
|
+
}
|
|
60
|
+
function getTokenSummary(stats) {
|
|
61
|
+
const input = formatTokenCount(stats.totalInputTokens);
|
|
62
|
+
const output = formatTokenCount(stats.totalOutputTokens);
|
|
63
|
+
return `${input} in / ${output} out`;
|
|
64
|
+
}
|
|
65
|
+
export {
|
|
66
|
+
formatTokenCount,
|
|
67
|
+
getTokenSummary,
|
|
68
|
+
useAgentTokenStats,
|
|
69
|
+
useAllAgentTokenStats,
|
|
70
|
+
useGlobalTokenStats
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=useAgentTokenStats.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/useAgentTokenStats.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * useAgentTokenStats Hook\n *\n * Provides real-time access to token statistics for a specific agent.\n * Subscribes to TokenStatsManager events for automatic updates.\n *\n * Usage:\n * ```tsx\n * function SubagentDisplay({ agentId }) {\n * const stats = useAgentTokenStats(agentId)\n *\n * if (!stats) return <Text>Loading...</Text>\n *\n * return (\n * <Text>\n * {stats.grandTotalTokens.toLocaleString()} tokens\n * </Text>\n * )\n * }\n * ```\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { tokenStatsManager } from '@core/tokenStatsManager'\nimport type { AggregatedTokenStats } from '@core/tokenStats'\n\n/**\n * Hook for accessing token statistics for a specific agent\n *\n * @param agentId - The agent ID to track\n * @returns Current token statistics or null if not found\n */\nexport function useAgentTokenStats(\n agentId: string | undefined,\n): AggregatedTokenStats | null {\n const [stats, setStats] = useState<AggregatedTokenStats | null>(() => {\n if (!agentId) return null\n return tokenStatsManager.getAgentStats(agentId)\n })\n\n useEffect(() => {\n if (!agentId) {\n setStats(null)\n return\n }\n\n // Get initial stats\n const initialStats = tokenStatsManager.getAgentStats(agentId)\n if (initialStats) {\n setStats(initialStats)\n }\n\n // Subscribe to updates\n const unsubscribe = tokenStatsManager.onAgentStatsUpdate(\n agentId,\n newStats => {\n setStats(newStats)\n },\n )\n\n return unsubscribe\n }, [agentId])\n\n return stats\n}\n\n/**\n * Hook for accessing global token statistics\n *\n * @returns Current global token statistics\n */\nexport function useGlobalTokenStats(): AggregatedTokenStats {\n const [stats, setStats] = useState<AggregatedTokenStats>(() =>\n tokenStatsManager.getGlobalStats(),\n )\n\n useEffect(() => {\n // Subscribe to global updates\n const unsubscribe = tokenStatsManager.onGlobalStatsUpdate(newStats => {\n setStats(newStats)\n })\n\n return unsubscribe\n }, [])\n\n return stats\n}\n\n/**\n * Hook for accessing all agent statistics\n *\n * @returns Map of agentId to token statistics\n */\nexport function useAllAgentTokenStats(): Map<string, AggregatedTokenStats> {\n const [stats, setStats] = useState<Map<string, AggregatedTokenStats>>(() =>\n tokenStatsManager.getAllAgentStats(),\n )\n\n useEffect(() => {\n // Subscribe to all updates\n const unsubscribe = tokenStatsManager.onStatsUpdate(event => {\n // Refresh the entire map on any update\n setStats(tokenStatsManager.getAllAgentStats())\n })\n\n return unsubscribe\n }, [])\n\n return stats\n}\n\n/**\n * Format token count for display\n *\n * @param count - Token count to format\n * @returns Formatted string (e.g., \"1.2k\", \"45.3k\", \"1.2M\")\n */\nexport function formatTokenCount(count: number): string {\n if (count >= 1_000_000) {\n return `${(count / 1_000_000).toFixed(1)}M`\n }\n if (count >= 1_000) {\n return `${(count / 1_000).toFixed(1)}k`\n }\n return count.toString()\n}\n\n/**\n * Get a summary string of token usage\n *\n * @param stats - Token statistics to summarize\n * @returns Formatted summary (e.g., \"1.2k in / 0.5k out\")\n */\nexport function getTokenSummary(stats: AggregatedTokenStats): string {\n const input = formatTokenCount(stats.totalInputTokens)\n const output = formatTokenCount(stats.totalOutputTokens)\n return `${input} in / ${output} out`\n}\n"],
|
|
5
|
+
"mappings": "AAsBA,SAAS,UAAU,iBAA8B;AACjD,SAAS,yBAAyB;AAS3B,SAAS,mBACd,SAC6B;AAC7B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAsC,MAAM;AACpE,QAAI,CAAC,QAAS,QAAO;AACrB,WAAO,kBAAkB,cAAc,OAAO;AAAA,EAChD,CAAC;AAED,YAAU,MAAM;AACd,QAAI,CAAC,SAAS;AACZ,eAAS,IAAI;AACb;AAAA,IACF;AAGA,UAAM,eAAe,kBAAkB,cAAc,OAAO;AAC5D,QAAI,cAAc;AAChB,eAAS,YAAY;AAAA,IACvB;AAGA,UAAM,cAAc,kBAAkB;AAAA,MACpC;AAAA,MACA,cAAY;AACV,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,CAAC;AAEZ,SAAO;AACT;AAOO,SAAS,sBAA4C;AAC1D,QAAM,CAAC,OAAO,QAAQ,IAAI;AAAA,IAA+B,MACvD,kBAAkB,eAAe;AAAA,EACnC;AAEA,YAAU,MAAM;AAEd,UAAM,cAAc,kBAAkB,oBAAoB,cAAY;AACpE,eAAS,QAAQ;AAAA,IACnB,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,SAAO;AACT;AAOO,SAAS,wBAA2D;AACzE,QAAM,CAAC,OAAO,QAAQ,IAAI;AAAA,IAA4C,MACpE,kBAAkB,iBAAiB;AAAA,EACrC;AAEA,YAAU,MAAM;AAEd,UAAM,cAAc,kBAAkB,cAAc,WAAS;AAE3D,eAAS,kBAAkB,iBAAiB,CAAC;AAAA,IAC/C,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,SAAO;AACT;AAQO,SAAS,iBAAiB,OAAuB;AACtD,MAAI,SAAS,KAAW;AACtB,WAAO,IAAI,QAAQ,KAAW,QAAQ,CAAC,CAAC;AAAA,EAC1C;AACA,MAAI,SAAS,KAAO;AAClB,WAAO,IAAI,QAAQ,KAAO,QAAQ,CAAC,CAAC;AAAA,EACtC;AACA,SAAO,MAAM,SAAS;AACxB;AAQO,SAAS,gBAAgB,OAAqC;AACnE,QAAM,QAAQ,iBAAiB,MAAM,gBAAgB;AACrD,QAAM,SAAS,iBAAiB,MAAM,iBAAiB;AACvD,SAAO,GAAG,KAAK,SAAS,MAAM;AAChC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { useState, useEffect, useMemo, useCallback, useRef } from "react";
|
|
2
|
+
import {
|
|
3
|
+
transcriptEmitter,
|
|
4
|
+
getAgentTranscript
|
|
5
|
+
} from "../utils/agentTranscripts.js";
|
|
6
|
+
function useAgentTranscripts(agentIds) {
|
|
7
|
+
const [transcripts, setTranscripts] = useState(
|
|
8
|
+
() => /* @__PURE__ */ new Map()
|
|
9
|
+
);
|
|
10
|
+
const lazyLoadCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
11
|
+
const syncScheduledRef = useRef(false);
|
|
12
|
+
const trackedAgentIds = useMemo(
|
|
13
|
+
() => agentIds ? new Set(agentIds) : null,
|
|
14
|
+
[agentIds?.join(",")]
|
|
15
|
+
);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
const handleUpdate = (event) => {
|
|
18
|
+
if (trackedAgentIds && !trackedAgentIds.has(event.agentId)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
setTranscripts((prev) => {
|
|
22
|
+
const next = new Map(prev);
|
|
23
|
+
next.set(event.agentId, event.transcript);
|
|
24
|
+
return next;
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
transcriptEmitter.on("update", handleUpdate);
|
|
28
|
+
if (trackedAgentIds) {
|
|
29
|
+
for (const agentId of trackedAgentIds) {
|
|
30
|
+
const transcript = getAgentTranscript(agentId);
|
|
31
|
+
if (transcript) {
|
|
32
|
+
setTranscripts((prev) => {
|
|
33
|
+
const next = new Map(prev);
|
|
34
|
+
next.set(agentId, transcript);
|
|
35
|
+
return next;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return () => {
|
|
41
|
+
transcriptEmitter.off("update", handleUpdate);
|
|
42
|
+
};
|
|
43
|
+
}, [trackedAgentIds]);
|
|
44
|
+
const getTranscriptCallback = useCallback(
|
|
45
|
+
(agentId) => {
|
|
46
|
+
const cached = transcripts.get(agentId);
|
|
47
|
+
if (cached) {
|
|
48
|
+
return cached;
|
|
49
|
+
}
|
|
50
|
+
const lazyCached = lazyLoadCacheRef.current.get(agentId);
|
|
51
|
+
if (lazyCached) {
|
|
52
|
+
return lazyCached;
|
|
53
|
+
}
|
|
54
|
+
const loaded = getAgentTranscript(agentId);
|
|
55
|
+
if (loaded) {
|
|
56
|
+
lazyLoadCacheRef.current.set(agentId, loaded);
|
|
57
|
+
}
|
|
58
|
+
return loaded;
|
|
59
|
+
},
|
|
60
|
+
[transcripts]
|
|
61
|
+
);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (lazyLoadCacheRef.current.size > 0 && !syncScheduledRef.current) {
|
|
64
|
+
syncScheduledRef.current = true;
|
|
65
|
+
const timeoutId = setTimeout(() => {
|
|
66
|
+
setTranscripts((prev) => {
|
|
67
|
+
const next = new Map(prev);
|
|
68
|
+
for (const [agentId, transcript] of lazyLoadCacheRef.current) {
|
|
69
|
+
if (!next.has(agentId)) {
|
|
70
|
+
next.set(agentId, transcript);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return next;
|
|
74
|
+
});
|
|
75
|
+
lazyLoadCacheRef.current = /* @__PURE__ */ new Map();
|
|
76
|
+
syncScheduledRef.current = false;
|
|
77
|
+
}, 0);
|
|
78
|
+
return () => {
|
|
79
|
+
clearTimeout(timeoutId);
|
|
80
|
+
syncScheduledRef.current = false;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}, [transcripts]);
|
|
84
|
+
const refreshTranscript = useCallback((agentId) => {
|
|
85
|
+
const fresh = getAgentTranscript(agentId);
|
|
86
|
+
if (fresh) {
|
|
87
|
+
setTranscripts((prev) => {
|
|
88
|
+
const next = new Map(prev);
|
|
89
|
+
next.set(agentId, fresh);
|
|
90
|
+
return next;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}, []);
|
|
94
|
+
const activeCount = useMemo(() => {
|
|
95
|
+
let count = 0;
|
|
96
|
+
for (const transcript of transcripts.values()) {
|
|
97
|
+
if (transcript.status === "running" || transcript.status === "pending") {
|
|
98
|
+
count++;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return count;
|
|
102
|
+
}, [transcripts]);
|
|
103
|
+
return {
|
|
104
|
+
transcripts,
|
|
105
|
+
getTranscript: getTranscriptCallback,
|
|
106
|
+
refreshTranscript,
|
|
107
|
+
activeCount
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function useAgentTranscript(agentId) {
|
|
111
|
+
const [transcript, setTranscript] = useState(() => {
|
|
112
|
+
if (!agentId) return null;
|
|
113
|
+
return getAgentTranscript(agentId);
|
|
114
|
+
});
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
if (!agentId) {
|
|
117
|
+
setTranscript(null);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const initial = getAgentTranscript(agentId);
|
|
121
|
+
if (initial) {
|
|
122
|
+
setTranscript(initial);
|
|
123
|
+
}
|
|
124
|
+
const handleUpdate = (event) => {
|
|
125
|
+
if (event.agentId === agentId) {
|
|
126
|
+
setTranscript(event.transcript);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
transcriptEmitter.on("update", handleUpdate);
|
|
130
|
+
return () => {
|
|
131
|
+
transcriptEmitter.off("update", handleUpdate);
|
|
132
|
+
};
|
|
133
|
+
}, [agentId]);
|
|
134
|
+
return transcript;
|
|
135
|
+
}
|
|
136
|
+
export {
|
|
137
|
+
useAgentTranscript,
|
|
138
|
+
useAgentTranscripts
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=useAgentTranscripts.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/useAgentTranscripts.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * useAgentTranscripts Hook\n *\n * Provides real-time access to agent transcripts with automatic updates.\n * Subscribes to transcript events and maintains a reactive map of transcripts.\n */\n\nimport { useState, useEffect, useMemo, useCallback, useRef } from 'react'\nimport {\n transcriptEmitter,\n getAgentTranscript,\n type AgentTranscript,\n type TranscriptEvent,\n} from '@utils/agentTranscripts'\n\ninterface UseAgentTranscriptsResult {\n /** Map of agentId to transcript */\n transcripts: Map<string, AgentTranscript>\n /** Get transcript by agentId */\n getTranscript: (agentId: string) => AgentTranscript | null\n /** Force refresh of a specific transcript */\n refreshTranscript: (agentId: string) => void\n /** Number of active transcripts */\n activeCount: number\n}\n\n/**\n * Hook for accessing agent transcripts with real-time updates\n *\n * @param agentIds - Optional list of specific agent IDs to track\n * @returns Transcript state and utilities\n */\nexport function useAgentTranscripts(\n agentIds?: string[],\n): UseAgentTranscriptsResult {\n // State to hold current transcripts\n const [transcripts, setTranscripts] = useState<Map<string, AgentTranscript>>(\n () => new Map(),\n )\n\n // Ref-based cache for lazy loading during render (avoids setState during render)\n // This allows getTranscript to return cached values synchronously without triggering re-renders\n const lazyLoadCacheRef = useRef<Map<string, AgentTranscript>>(new Map())\n\n // Prevent duplicate sync scheduling - avoids infinite render loops\n const syncScheduledRef = useRef<boolean>(false)\n\n // Track which agents we're interested in\n const trackedAgentIds = useMemo(\n () => (agentIds ? new Set(agentIds) : null),\n [agentIds?.join(',')],\n )\n\n // Handle transcript updates\n useEffect(() => {\n const handleUpdate = (event: TranscriptEvent) => {\n // If we have a tracked list and this agent isn't in it, skip\n if (trackedAgentIds && !trackedAgentIds.has(event.agentId)) {\n return\n }\n\n setTranscripts(prev => {\n const next = new Map(prev)\n next.set(event.agentId, event.transcript)\n return next\n })\n }\n\n // Subscribe to all transcript updates\n transcriptEmitter.on('update', handleUpdate)\n\n // Initial load for tracked agents\n if (trackedAgentIds) {\n for (const agentId of trackedAgentIds) {\n const transcript = getAgentTranscript(agentId)\n if (transcript) {\n setTranscripts(prev => {\n const next = new Map(prev)\n next.set(agentId, transcript)\n return next\n })\n }\n }\n }\n\n return () => {\n transcriptEmitter.off('update', handleUpdate)\n }\n }, [trackedAgentIds])\n\n // Get transcript by ID (with fallback to disk)\n // IMPORTANT: This function may be called during render (e.g., by ParallelTasksGroupView),\n // so we must NOT call setTranscripts here. Instead, we use a ref-based cache for lazy loading\n // and schedule state updates via useEffect.\n const getTranscriptCallback = useCallback(\n (agentId: string): AgentTranscript | null => {\n // Check state first (reactive updates)\n const cached = transcripts.get(agentId)\n if (cached) {\n return cached\n }\n\n // Check ref cache (lazy loaded during render)\n const lazyCached = lazyLoadCacheRef.current.get(agentId)\n if (lazyCached) {\n return lazyCached\n }\n\n // Try to load from disk - store in ref only (no setState during render!)\n const loaded = getAgentTranscript(agentId)\n if (loaded) {\n lazyLoadCacheRef.current.set(agentId, loaded)\n }\n return loaded\n },\n [transcripts],\n )\n\n // Sync lazy-loaded transcripts from ref cache to state after render\n // This ensures state stays up-to-date for future renders without causing\n // \"Cannot update component while rendering\" warnings\n useEffect(() => {\n if (lazyLoadCacheRef.current.size > 0 && !syncScheduledRef.current) {\n syncScheduledRef.current = true\n const timeoutId = setTimeout(() => {\n setTranscripts(prev => {\n const next = new Map(prev)\n for (const [agentId, transcript] of lazyLoadCacheRef.current) {\n if (!next.has(agentId)) {\n next.set(agentId, transcript)\n }\n }\n return next\n })\n lazyLoadCacheRef.current = new Map()\n syncScheduledRef.current = false\n }, 0)\n return () => {\n clearTimeout(timeoutId)\n syncScheduledRef.current = false\n }\n }\n }, [transcripts])\n\n // Force refresh a specific transcript\n const refreshTranscript = useCallback((agentId: string) => {\n const fresh = getAgentTranscript(agentId)\n if (fresh) {\n setTranscripts(prev => {\n const next = new Map(prev)\n next.set(agentId, fresh)\n return next\n })\n }\n }, [])\n\n // Count active (non-completed) transcripts\n const activeCount = useMemo(() => {\n let count = 0\n for (const transcript of transcripts.values()) {\n if (transcript.status === 'running' || transcript.status === 'pending') {\n count++\n }\n }\n return count\n }, [transcripts])\n\n return {\n transcripts,\n getTranscript: getTranscriptCallback,\n refreshTranscript,\n activeCount,\n }\n}\n\n/**\n * Simplified hook for single transcript tracking\n */\nexport function useAgentTranscript(\n agentId: string | undefined,\n): AgentTranscript | null {\n const [transcript, setTranscript] = useState<AgentTranscript | null>(() => {\n if (!agentId) return null\n return getAgentTranscript(agentId)\n })\n\n useEffect(() => {\n if (!agentId) {\n setTranscript(null)\n return\n }\n\n // Load initial\n const initial = getAgentTranscript(agentId)\n if (initial) {\n setTranscript(initial)\n }\n\n // Subscribe to updates for this specific agent\n const handleUpdate = (event: TranscriptEvent) => {\n if (event.agentId === agentId) {\n setTranscript(event.transcript)\n }\n }\n\n transcriptEmitter.on('update', handleUpdate)\n return () => {\n transcriptEmitter.off('update', handleUpdate)\n }\n }, [agentId])\n\n return transcript\n}\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,UAAU,WAAW,SAAS,aAAa,cAAc;AAClE;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAmBA,SAAS,oBACd,UAC2B;AAE3B,QAAM,CAAC,aAAa,cAAc,IAAI;AAAA,IACpC,MAAM,oBAAI,IAAI;AAAA,EAChB;AAIA,QAAM,mBAAmB,OAAqC,oBAAI,IAAI,CAAC;AAGvE,QAAM,mBAAmB,OAAgB,KAAK;AAG9C,QAAM,kBAAkB;AAAA,IACtB,MAAO,WAAW,IAAI,IAAI,QAAQ,IAAI;AAAA,IACtC,CAAC,UAAU,KAAK,GAAG,CAAC;AAAA,EACtB;AAGA,YAAU,MAAM;AACd,UAAM,eAAe,CAAC,UAA2B;AAE/C,UAAI,mBAAmB,CAAC,gBAAgB,IAAI,MAAM,OAAO,GAAG;AAC1D;AAAA,MACF;AAEA,qBAAe,UAAQ;AACrB,cAAM,OAAO,IAAI,IAAI,IAAI;AACzB,aAAK,IAAI,MAAM,SAAS,MAAM,UAAU;AACxC,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAGA,sBAAkB,GAAG,UAAU,YAAY;AAG3C,QAAI,iBAAiB;AACnB,iBAAW,WAAW,iBAAiB;AACrC,cAAM,aAAa,mBAAmB,OAAO;AAC7C,YAAI,YAAY;AACd,yBAAe,UAAQ;AACrB,kBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,iBAAK,IAAI,SAAS,UAAU;AAC5B,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM;AACX,wBAAkB,IAAI,UAAU,YAAY;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,eAAe,CAAC;AAMpB,QAAM,wBAAwB;AAAA,IAC5B,CAAC,YAA4C;AAE3C,YAAM,SAAS,YAAY,IAAI,OAAO;AACtC,UAAI,QAAQ;AACV,eAAO;AAAA,MACT;AAGA,YAAM,aAAa,iBAAiB,QAAQ,IAAI,OAAO;AACvD,UAAI,YAAY;AACd,eAAO;AAAA,MACT;AAGA,YAAM,SAAS,mBAAmB,OAAO;AACzC,UAAI,QAAQ;AACV,yBAAiB,QAAQ,IAAI,SAAS,MAAM;AAAA,MAC9C;AACA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAKA,YAAU,MAAM;AACd,QAAI,iBAAiB,QAAQ,OAAO,KAAK,CAAC,iBAAiB,SAAS;AAClE,uBAAiB,UAAU;AAC3B,YAAM,YAAY,WAAW,MAAM;AACjC,uBAAe,UAAQ;AACrB,gBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,qBAAW,CAAC,SAAS,UAAU,KAAK,iBAAiB,SAAS;AAC5D,gBAAI,CAAC,KAAK,IAAI,OAAO,GAAG;AACtB,mBAAK,IAAI,SAAS,UAAU;AAAA,YAC9B;AAAA,UACF;AACA,iBAAO;AAAA,QACT,CAAC;AACD,yBAAiB,UAAU,oBAAI,IAAI;AACnC,yBAAiB,UAAU;AAAA,MAC7B,GAAG,CAAC;AACJ,aAAO,MAAM;AACX,qBAAa,SAAS;AACtB,yBAAiB,UAAU;AAAA,MAC7B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAGhB,QAAM,oBAAoB,YAAY,CAAC,YAAoB;AACzD,UAAM,QAAQ,mBAAmB,OAAO;AACxC,QAAI,OAAO;AACT,qBAAe,UAAQ;AACrB,cAAM,OAAO,IAAI,IAAI,IAAI;AACzB,aAAK,IAAI,SAAS,KAAK;AACvB,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,QAAM,cAAc,QAAQ,MAAM;AAChC,QAAI,QAAQ;AACZ,eAAW,cAAc,YAAY,OAAO,GAAG;AAC7C,UAAI,WAAW,WAAW,aAAa,WAAW,WAAW,WAAW;AACtE;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,CAAC,WAAW,CAAC;AAEhB,SAAO;AAAA,IACL;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,mBACd,SACwB;AACxB,QAAM,CAAC,YAAY,aAAa,IAAI,SAAiC,MAAM;AACzE,QAAI,CAAC,QAAS,QAAO;AACrB,WAAO,mBAAmB,OAAO;AAAA,EACnC,CAAC;AAED,YAAU,MAAM;AACd,QAAI,CAAC,SAAS;AACZ,oBAAc,IAAI;AAClB;AAAA,IACF;AAGA,UAAM,UAAU,mBAAmB,OAAO;AAC1C,QAAI,SAAS;AACX,oBAAc,OAAO;AAAA,IACvB;AAGA,UAAM,eAAe,CAAC,UAA2B;AAC/C,UAAI,MAAM,YAAY,SAAS;AAC7B,sBAAc,MAAM,UAAU;AAAA,MAChC;AAAA,IACF;AAEA,sBAAkB,GAAG,UAAU,YAAY;AAC3C,WAAO,MAAM;AACX,wBAAkB,IAAI,UAAU,YAAY;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
import { animationSync, ANIMATION_INTERVALS } from "../utils/animationSync.js";
|
|
3
|
+
function useAnimationSync() {
|
|
4
|
+
const [state, setState] = useState(
|
|
5
|
+
() => animationSync.getFrame()
|
|
6
|
+
);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
const unsubscribe = animationSync.subscribe((frame) => {
|
|
9
|
+
setState(frame);
|
|
10
|
+
});
|
|
11
|
+
return unsubscribe;
|
|
12
|
+
}, []);
|
|
13
|
+
return state;
|
|
14
|
+
}
|
|
15
|
+
function useSpinnerAnimation(frames) {
|
|
16
|
+
const [frameIndex, setFrameIndex] = useState(0);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
const timer = setInterval(() => {
|
|
19
|
+
setFrameIndex((f) => (f + 1) % frames.length);
|
|
20
|
+
}, ANIMATION_INTERVALS.SPINNER);
|
|
21
|
+
return () => clearInterval(timer);
|
|
22
|
+
}, [frames.length]);
|
|
23
|
+
return frames[frameIndex] || frames[0] || "";
|
|
24
|
+
}
|
|
25
|
+
function useBlinkAnimation() {
|
|
26
|
+
const [visible, setVisible] = useState(true);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const timer = setInterval(() => {
|
|
29
|
+
setVisible((v) => !v);
|
|
30
|
+
}, ANIMATION_INTERVALS.BLINK);
|
|
31
|
+
return () => clearInterval(timer);
|
|
32
|
+
}, []);
|
|
33
|
+
return visible;
|
|
34
|
+
}
|
|
35
|
+
function useElapsedTime(startTime) {
|
|
36
|
+
const [elapsed, setElapsed] = useState(0);
|
|
37
|
+
const start = startTime ?? Date.now();
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const timer = setInterval(() => {
|
|
40
|
+
setElapsed(Math.floor((Date.now() - start) / 1e3));
|
|
41
|
+
}, ANIMATION_INTERVALS.ELAPSED_TIME);
|
|
42
|
+
return () => clearInterval(timer);
|
|
43
|
+
}, [start]);
|
|
44
|
+
return elapsed;
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
ANIMATION_INTERVALS,
|
|
48
|
+
useAnimationSync,
|
|
49
|
+
useBlinkAnimation,
|
|
50
|
+
useElapsedTime,
|
|
51
|
+
useSpinnerAnimation
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=useAnimationSync.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/useAnimationSync.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * React hook for synchronized animations across components\n *\n * Provides synchronized animation state that updates at consistent intervals:\n * - Spinner: 120ms\n * - Blinking: 600ms\n * - Elapsed Time: 1000ms\n *\n * Usage:\n * ```tsx\n * function MySpinner() {\n * const { spinnerFrame, blinkVisible, elapsedSeconds } = useAnimationSync()\n * const spinnerChars = ['\u00B7', '\u2722', '\u2733', '\u2217', '\u273B', '\u273D']\n * return <Text>{spinnerChars[spinnerFrame % spinnerChars.length]}</Text>\n * }\n * ```\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { animationSync, ANIMATION_INTERVALS } from '@utils/animationSync'\n\nexport interface AnimationState {\n spinnerFrame: number\n blinkVisible: boolean\n elapsedSeconds: number\n}\n\n/**\n * Hook for synchronized animation state\n * Components using this hook will animate in sync with each other\n */\nexport function useAnimationSync(): AnimationState {\n const [state, setState] = useState<AnimationState>(() =>\n animationSync.getFrame(),\n )\n\n useEffect(() => {\n const unsubscribe = animationSync.subscribe(frame => {\n setState(frame)\n })\n\n return unsubscribe\n }, [])\n\n return state\n}\n\n/**\n * Hook for just the spinner animation (120ms interval)\n * Lighter weight than full animation sync if you only need spinner\n */\nexport function useSpinnerAnimation(frames: string[]): string {\n const [frameIndex, setFrameIndex] = useState(0)\n\n useEffect(() => {\n const timer = setInterval(() => {\n setFrameIndex(f => (f + 1) % frames.length)\n }, ANIMATION_INTERVALS.SPINNER)\n\n return () => clearInterval(timer)\n }, [frames.length])\n\n return frames[frameIndex] || frames[0] || ''\n}\n\n/**\n * Hook for blinking animation (600ms interval)\n */\nexport function useBlinkAnimation(): boolean {\n const [visible, setVisible] = useState(true)\n\n useEffect(() => {\n const timer = setInterval(() => {\n setVisible(v => !v)\n }, ANIMATION_INTERVALS.BLINK)\n\n return () => clearInterval(timer)\n }, [])\n\n return visible\n}\n\n/**\n * Hook for elapsed time counter (1000ms interval)\n */\nexport function useElapsedTime(startTime?: number): number {\n const [elapsed, setElapsed] = useState(0)\n const start = startTime ?? Date.now()\n\n useEffect(() => {\n const timer = setInterval(() => {\n setElapsed(Math.floor((Date.now() - start) / 1000))\n }, ANIMATION_INTERVALS.ELAPSED_TIME)\n\n return () => clearInterval(timer)\n }, [start])\n\n return elapsed\n}\n\n// Re-export intervals for convenience\nexport { ANIMATION_INTERVALS }\n"],
|
|
5
|
+
"mappings": "AAkBA,SAAS,UAAU,iBAA8B;AACjD,SAAS,eAAe,2BAA2B;AAY5C,SAAS,mBAAmC;AACjD,QAAM,CAAC,OAAO,QAAQ,IAAI;AAAA,IAAyB,MACjD,cAAc,SAAS;AAAA,EACzB;AAEA,YAAU,MAAM;AACd,UAAM,cAAc,cAAc,UAAU,WAAS;AACnD,eAAS,KAAK;AAAA,IAChB,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,SAAO;AACT;AAMO,SAAS,oBAAoB,QAA0B;AAC5D,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,CAAC;AAE9C,YAAU,MAAM;AACd,UAAM,QAAQ,YAAY,MAAM;AAC9B,oBAAc,QAAM,IAAI,KAAK,OAAO,MAAM;AAAA,IAC5C,GAAG,oBAAoB,OAAO;AAE9B,WAAO,MAAM,cAAc,KAAK;AAAA,EAClC,GAAG,CAAC,OAAO,MAAM,CAAC;AAElB,SAAO,OAAO,UAAU,KAAK,OAAO,CAAC,KAAK;AAC5C;AAKO,SAAS,oBAA6B;AAC3C,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAE3C,YAAU,MAAM;AACd,UAAM,QAAQ,YAAY,MAAM;AAC9B,iBAAW,OAAK,CAAC,CAAC;AAAA,IACpB,GAAG,oBAAoB,KAAK;AAE5B,WAAO,MAAM,cAAc,KAAK;AAAA,EAClC,GAAG,CAAC,CAAC;AAEL,SAAO;AACT;AAKO,SAAS,eAAe,WAA4B;AACzD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,CAAC;AACxC,QAAM,QAAQ,aAAa,KAAK,IAAI;AAEpC,YAAU,MAAM;AACd,UAAM,QAAQ,YAAY,MAAM;AAC9B,iBAAW,KAAK,OAAO,KAAK,IAAI,IAAI,SAAS,GAAI,CAAC;AAAA,IACpD,GAAG,oBAAoB,YAAY;AAEnC,WAAO,MAAM,cAAc,KAAK;AAAA,EAClC,GAAG,CAAC,KAAK,CAAC;AAEV,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
2
|
import { getHistory } from "../history.js";
|
|
3
|
+
import { sanitizeInput } from "../utils/sanitizeInput.js";
|
|
3
4
|
function useArrowKeyHistory(onSetInput, currentInput) {
|
|
4
5
|
const [historyIndex, setHistoryIndex] = useState(0);
|
|
5
6
|
const [lastTypedInput, setLastTypedInput] = useState("");
|
|
6
7
|
const updateInput = (input) => {
|
|
7
8
|
if (input !== void 0) {
|
|
8
|
-
const
|
|
9
|
-
const
|
|
9
|
+
const sanitized = sanitizeInput(input);
|
|
10
|
+
const mode = sanitized.startsWith("!") ? "bash" : "prompt";
|
|
11
|
+
const value = mode === "bash" ? sanitized.slice(1) : sanitized;
|
|
10
12
|
onSetInput(value, mode);
|
|
11
13
|
}
|
|
12
14
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/hooks/useArrowKeyHistory.ts"],
|
|
4
|
-
"sourcesContent": ["import { useState } from 'react'\nimport { getHistory } from '@history'\n\nexport function useArrowKeyHistory(\n onSetInput: (value: string, mode: 'bash' | 'prompt') => void,\n currentInput: string,\n) {\n const [historyIndex, setHistoryIndex] = useState(0)\n const [lastTypedInput, setLastTypedInput] = useState('')\n\n const updateInput = (input: string | undefined) => {\n if (input !== undefined) {\n const mode =
|
|
5
|
-
"mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;
|
|
4
|
+
"sourcesContent": ["import { useState } from 'react'\nimport { getHistory } from '@history'\nimport { sanitizeInput } from '@utils/sanitizeInput'\n\nexport function useArrowKeyHistory(\n onSetInput: (value: string, mode: 'bash' | 'prompt') => void,\n currentInput: string,\n) {\n const [historyIndex, setHistoryIndex] = useState(0)\n const [lastTypedInput, setLastTypedInput] = useState('')\n\n const updateInput = (input: string | undefined) => {\n if (input !== undefined) {\n // Sanitize input to remove dangerous escape sequences\n // This prevents corrupt history entries (like \"\\x1b\\x1bclear\") from\n // triggering terminal resets when loaded\n const sanitized = sanitizeInput(input)\n const mode = sanitized.startsWith('!') ? 'bash' : 'prompt'\n const value = mode === 'bash' ? sanitized.slice(1) : sanitized\n onSetInput(value, mode)\n }\n }\n\n function onHistoryUp() {\n const latestHistory = getHistory()\n if (historyIndex < latestHistory.length) {\n if (historyIndex === 0 && currentInput.trim() !== '') {\n setLastTypedInput(currentInput)\n }\n const newIndex = historyIndex + 1\n setHistoryIndex(newIndex)\n updateInput(latestHistory[historyIndex])\n }\n }\n\n function onHistoryDown() {\n const latestHistory = getHistory()\n if (historyIndex > 1) {\n const newIndex = historyIndex - 1\n setHistoryIndex(newIndex)\n updateInput(latestHistory[newIndex - 1])\n } else if (historyIndex === 1) {\n setHistoryIndex(0)\n updateInput(lastTypedInput)\n }\n }\n\n function resetHistory() {\n setLastTypedInput('')\n setHistoryIndex(0)\n }\n\n return {\n historyIndex,\n setHistoryIndex,\n onHistoryUp,\n onHistoryDown,\n resetHistory,\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAEvB,SAAS,mBACd,YACA,cACA;AACA,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,CAAC;AAClD,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,EAAE;AAEvD,QAAM,cAAc,CAAC,UAA8B;AACjD,QAAI,UAAU,QAAW;AAIvB,YAAM,YAAY,cAAc,KAAK;AACrC,YAAM,OAAO,UAAU,WAAW,GAAG,IAAI,SAAS;AAClD,YAAM,QAAQ,SAAS,SAAS,UAAU,MAAM,CAAC,IAAI;AACrD,iBAAW,OAAO,IAAI;AAAA,IACxB;AAAA,EACF;AAEA,WAAS,cAAc;AACrB,UAAM,gBAAgB,WAAW;AACjC,QAAI,eAAe,cAAc,QAAQ;AACvC,UAAI,iBAAiB,KAAK,aAAa,KAAK,MAAM,IAAI;AACpD,0BAAkB,YAAY;AAAA,MAChC;AACA,YAAM,WAAW,eAAe;AAChC,sBAAgB,QAAQ;AACxB,kBAAY,cAAc,YAAY,CAAC;AAAA,IACzC;AAAA,EACF;AAEA,WAAS,gBAAgB;AACvB,UAAM,gBAAgB,WAAW;AACjC,QAAI,eAAe,GAAG;AACpB,YAAM,WAAW,eAAe;AAChC,sBAAgB,QAAQ;AACxB,kBAAY,cAAc,WAAW,CAAC,CAAC;AAAA,IACzC,WAAW,iBAAiB,GAAG;AAC7B,sBAAgB,CAAC;AACjB,kBAAY,cAAc;AAAA,IAC5B;AAAA,EACF;AAEA,WAAS,eAAe;AACtB,sBAAkB,EAAE;AACpB,oBAAgB,CAAC;AAAA,EACnB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -3,6 +3,7 @@ import { hasPermissionsToUseTool } from "../permissions.js";
|
|
|
3
3
|
import { BashTool, inputSchema } from "../tools/BashTool/BashTool.js";
|
|
4
4
|
import { getCommandSubcommandPrefix } from "../utils/commands.js";
|
|
5
5
|
import { REJECT_MESSAGE } from "../utils/messages.js";
|
|
6
|
+
import { getToolDescriptionAsync } from "../Tool.js";
|
|
6
7
|
import { AbortError } from "../utils/errors.js";
|
|
7
8
|
import { logError } from "../utils/log.js";
|
|
8
9
|
function useCanUseTool(setToolUseConfirm) {
|
|
@@ -34,7 +35,8 @@ function useCanUseTool(setToolUseConfirm) {
|
|
|
34
35
|
return;
|
|
35
36
|
}
|
|
36
37
|
const [description, commandPrefix] = await Promise.all([
|
|
37
|
-
|
|
38
|
+
// Use getToolDescriptionAsync for safe async access
|
|
39
|
+
getToolDescriptionAsync(tool, input),
|
|
38
40
|
tool === BashTool ? getCommandSubcommandPrefix(
|
|
39
41
|
inputSchema.parse(input).command,
|
|
40
42
|
// already validated upstream, so ok to parse (as opposed to safeParse)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/hooks/useCanUseTool.ts"],
|
|
4
|
-
"sourcesContent": ["import React, { useCallback } from 'react'\nimport { hasPermissionsToUseTool } from '@permissions'\nimport { BashTool, inputSchema } from '@tools/BashTool/BashTool'\nimport { getCommandSubcommandPrefix } from '@utils/commands'\nimport { REJECT_MESSAGE } from '@utils/messages'\nimport type { Tool as ToolType, ToolUseContext } from '@tool'\nimport { AssistantMessage } from '@query'\nimport { ToolUseConfirm } from '@components/permissions/PermissionRequest'\nimport { AbortError } from '@utils/errors'\nimport { logError } from '@utils/log'\n\ntype SetState<T> = React.Dispatch<React.SetStateAction<T>>\n\nexport type CanUseToolFn = (\n tool: ToolType,\n input: { [key: string]: unknown },\n toolUseContext: ToolUseContext,\n assistantMessage: AssistantMessage,\n) => Promise<{ result: true } | { result: false; message: string }>\n\nfunction useCanUseTool(\n setToolUseConfirm: SetState<ToolUseConfirm | null>,\n): CanUseToolFn {\n return useCallback<CanUseToolFn>(\n async (tool, input, toolUseContext, assistantMessage) => {\n return new Promise(resolve => {\n function logCancelledEvent() {}\n\n function resolveWithCancelledAndAbortAllToolCalls() {\n resolve({\n result: false,\n message: REJECT_MESSAGE,\n })\n // Trigger a synthetic assistant message in query(), to cancel\n // any other pending tool uses and stop further requests to the\n // API and wait for user input.\n toolUseContext.abortController.abort()\n }\n\n if (toolUseContext.abortController.signal.aborted) {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n return\n }\n\n return hasPermissionsToUseTool(\n tool,\n input,\n toolUseContext,\n assistantMessage,\n )\n .then(async result => {\n // Has permissions to use tool, granted in config\n if (result.result) {\n resolve({ result: true })\n return\n }\n\n const [description, commandPrefix] = await Promise.all([\n tool
|
|
5
|
-
"mappings": "AAAA,SAAgB,mBAAmB;AACnC,SAAS,+BAA+B;AACxC,SAAS,UAAU,mBAAmB;AACtC,SAAS,kCAAkC;AAC3C,SAAS,sBAAsB;
|
|
4
|
+
"sourcesContent": ["import React, { useCallback } from 'react'\nimport { hasPermissionsToUseTool } from '@permissions'\nimport { BashTool, inputSchema } from '@tools/BashTool/BashTool'\nimport { getCommandSubcommandPrefix } from '@utils/commands'\nimport { REJECT_MESSAGE } from '@utils/messages'\nimport type { Tool as ToolType, ToolUseContext } from '@tool'\nimport { getToolDescriptionAsync } from '@tool'\nimport { AssistantMessage } from '@query'\nimport { ToolUseConfirm } from '@components/permissions/PermissionRequest'\nimport { AbortError } from '@utils/errors'\nimport { logError } from '@utils/log'\n\ntype SetState<T> = React.Dispatch<React.SetStateAction<T>>\n\nexport type CanUseToolFn = (\n tool: ToolType,\n input: { [key: string]: unknown },\n toolUseContext: ToolUseContext,\n assistantMessage: AssistantMessage,\n) => Promise<{ result: true } | { result: false; message: string }>\n\nfunction useCanUseTool(\n setToolUseConfirm: SetState<ToolUseConfirm | null>,\n): CanUseToolFn {\n return useCallback<CanUseToolFn>(\n async (tool, input, toolUseContext, assistantMessage) => {\n return new Promise(resolve => {\n function logCancelledEvent() {}\n\n function resolveWithCancelledAndAbortAllToolCalls() {\n resolve({\n result: false,\n message: REJECT_MESSAGE,\n })\n // Trigger a synthetic assistant message in query(), to cancel\n // any other pending tool uses and stop further requests to the\n // API and wait for user input.\n toolUseContext.abortController.abort()\n }\n\n if (toolUseContext.abortController.signal.aborted) {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n return\n }\n\n return hasPermissionsToUseTool(\n tool,\n input,\n toolUseContext,\n assistantMessage,\n )\n .then(async result => {\n // Has permissions to use tool, granted in config\n if (result.result) {\n resolve({ result: true })\n return\n }\n\n const [description, commandPrefix] = await Promise.all([\n // Use getToolDescriptionAsync for safe async access\n getToolDescriptionAsync(tool, input),\n tool === BashTool\n ? getCommandSubcommandPrefix(\n inputSchema.parse(input).command, // already validated upstream, so ok to parse (as opposed to safeParse)\n toolUseContext.abortController.signal,\n )\n : Promise.resolve(null),\n ])\n\n if (toolUseContext.abortController.signal.aborted) {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n return\n }\n\n // Does not have permissions to use tool, ask the user\n setToolUseConfirm({\n assistantMessage,\n tool,\n description,\n input,\n commandPrefix,\n riskScore: null,\n onAbort() {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n },\n onAllow(type) {\n if (type === 'permanent') {\n } else {\n }\n resolve({ result: true })\n },\n onReject() {\n resolveWithCancelledAndAbortAllToolCalls()\n },\n })\n })\n .catch(error => {\n if (error instanceof AbortError) {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n } else {\n logError(error)\n }\n })\n })\n },\n [setToolUseConfirm],\n )\n}\n\nexport default useCanUseTool\n"],
|
|
5
|
+
"mappings": "AAAA,SAAgB,mBAAmB;AACnC,SAAS,+BAA+B;AACxC,SAAS,UAAU,mBAAmB;AACtC,SAAS,kCAAkC;AAC3C,SAAS,sBAAsB;AAE/B,SAAS,+BAA+B;AAGxC,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AAWzB,SAAS,cACP,mBACc;AACd,SAAO;AAAA,IACL,OAAO,MAAM,OAAO,gBAAgB,qBAAqB;AACvD,aAAO,IAAI,QAAQ,aAAW;AAC5B,iBAAS,oBAAoB;AAAA,QAAC;AAE9B,iBAAS,2CAA2C;AAClD,kBAAQ;AAAA,YACN,QAAQ;AAAA,YACR,SAAS;AAAA,UACX,CAAC;AAID,yBAAe,gBAAgB,MAAM;AAAA,QACvC;AAEA,YAAI,eAAe,gBAAgB,OAAO,SAAS;AACjD,4BAAkB;AAClB,mDAAyC;AACzC;AAAA,QACF;AAEA,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EACG,KAAK,OAAM,WAAU;AAEpB,cAAI,OAAO,QAAQ;AACjB,oBAAQ,EAAE,QAAQ,KAAK,CAAC;AACxB;AAAA,UACF;AAEA,gBAAM,CAAC,aAAa,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA;AAAA,YAErD,wBAAwB,MAAM,KAAK;AAAA,YACnC,SAAS,WACL;AAAA,cACE,YAAY,MAAM,KAAK,EAAE;AAAA;AAAA,cACzB,eAAe,gBAAgB;AAAA,YACjC,IACA,QAAQ,QAAQ,IAAI;AAAA,UAC1B,CAAC;AAED,cAAI,eAAe,gBAAgB,OAAO,SAAS;AACjD,8BAAkB;AAClB,qDAAyC;AACzC;AAAA,UACF;AAGA,4BAAkB;AAAA,YAChB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAW;AAAA,YACX,UAAU;AACR,gCAAkB;AAClB,uDAAyC;AAAA,YAC3C;AAAA,YACA,QAAQ,MAAM;AACZ,kBAAI,SAAS,aAAa;AAAA,cAC1B,OAAO;AAAA,cACP;AACA,sBAAQ,EAAE,QAAQ,KAAK,CAAC;AAAA,YAC1B;AAAA,YACA,WAAW;AACT,uDAAyC;AAAA,YAC3C;AAAA,UACF,CAAC;AAAA,QACH,CAAC,EACA,MAAM,WAAS;AACd,cAAI,iBAAiB,YAAY;AAC/B,8BAAkB;AAClB,qDAAyC;AAAA,UAC3C,OAAO;AACL,qBAAS,KAAK;AAAA,UAChB;AAAA,QACF,CAAC;AAAA,MACL,CAAC;AAAA,IACH;AAAA,IACA,CAAC,iBAAiB;AAAA,EACpB;AACF;AAEA,IAAO,wBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { useInput } from "ink";
|
|
2
2
|
import { useDoublePress } from "./useDoublePress.js";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
function useExitOnCtrlCD(onExit) {
|
|
4
|
+
function useExitOnCtrlCD(onExit, options = {}) {
|
|
5
|
+
const { isActive = true } = options;
|
|
5
6
|
const [exitState, setExitState] = useState({
|
|
6
7
|
pending: false,
|
|
7
8
|
keyName: null
|
|
@@ -14,10 +15,13 @@ function useExitOnCtrlCD(onExit) {
|
|
|
14
15
|
(pending) => setExitState({ pending, keyName: "Ctrl-D" }),
|
|
15
16
|
onExit
|
|
16
17
|
);
|
|
17
|
-
useInput(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
useInput(
|
|
19
|
+
(input, key) => {
|
|
20
|
+
if (key.ctrl && input === "c") handleCtrlC();
|
|
21
|
+
if (key.ctrl && input === "d") handleCtrlD();
|
|
22
|
+
},
|
|
23
|
+
{ isActive }
|
|
24
|
+
);
|
|
21
25
|
return exitState;
|
|
22
26
|
}
|
|
23
27
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/hooks/useExitOnCtrlCD.ts"],
|
|
4
|
-
"sourcesContent": ["import { useInput } from 'ink'\nimport { useDoublePress } from './useDoublePress'\nimport { useState } from 'react'\n\ntype ExitState = {\n pending: boolean\n keyName: 'Ctrl-C' | 'Ctrl-D' | null\n}\n\nexport function useExitOnCtrlCD(onExit: () => void): ExitState {\n const [exitState, setExitState] = useState<ExitState>({\n pending: false,\n keyName: null,\n })\n\n const handleCtrlC = useDoublePress(\n pending => setExitState({ pending, keyName: 'Ctrl-C' }),\n onExit,\n )\n const handleCtrlD = useDoublePress(\n pending => setExitState({ pending, keyName: 'Ctrl-D' }),\n onExit,\n )\n\n useInput((input, key) => {\n
|
|
5
|
-
"mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,sBAAsB;AAC/B,SAAS,gBAAgB;
|
|
4
|
+
"sourcesContent": ["import { useInput } from 'ink'\nimport { useDoublePress } from './useDoublePress'\nimport { useState } from 'react'\n\ntype ExitState = {\n pending: boolean\n keyName: 'Ctrl-C' | 'Ctrl-D' | null\n}\n\ntype Options = {\n isActive?: boolean\n}\n\nexport function useExitOnCtrlCD(\n onExit: () => void,\n options: Options = {},\n): ExitState {\n const { isActive = true } = options\n const [exitState, setExitState] = useState<ExitState>({\n pending: false,\n keyName: null,\n })\n\n const handleCtrlC = useDoublePress(\n pending => setExitState({ pending, keyName: 'Ctrl-C' }),\n onExit,\n )\n const handleCtrlD = useDoublePress(\n pending => setExitState({ pending, keyName: 'Ctrl-D' }),\n onExit,\n )\n\n // Support isActive option to conditionally enable/disable input handling\n // This helps prevent EventEmitter listener accumulation in nested components\n useInput(\n (input, key) => {\n if (key.ctrl && input === 'c') handleCtrlC()\n if (key.ctrl && input === 'd') handleCtrlD()\n },\n { isActive },\n )\n\n return exitState\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,sBAAsB;AAC/B,SAAS,gBAAgB;AAWlB,SAAS,gBACd,QACA,UAAmB,CAAC,GACT;AACX,QAAM,EAAE,WAAW,KAAK,IAAI;AAC5B,QAAM,CAAC,WAAW,YAAY,IAAI,SAAoB;AAAA,IACpD,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAED,QAAM,cAAc;AAAA,IAClB,aAAW,aAAa,EAAE,SAAS,SAAS,SAAS,CAAC;AAAA,IACtD;AAAA,EACF;AACA,QAAM,cAAc;AAAA,IAClB,aAAW,aAAa,EAAE,SAAS,SAAS,SAAS,CAAC;AAAA,IACtD;AAAA,EACF;AAIA;AAAA,IACE,CAAC,OAAO,QAAQ;AACd,UAAI,IAAI,QAAQ,UAAU,IAAK,aAAY;AAC3C,UAAI,IAAI,QAAQ,UAAU,IAAK,aAAY;AAAA,IAC7C;AAAA,IACA,EAAE,SAAS;AAAA,EACb;AAEA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
import { hookStatusEmitter } from "../services/hookExecutor.js";
|
|
3
|
+
function useHookStatus(enabled) {
|
|
4
|
+
const [state, setState] = useState({
|
|
5
|
+
recentEvents: [],
|
|
6
|
+
successCount: 0,
|
|
7
|
+
failureCount: 0
|
|
8
|
+
});
|
|
9
|
+
const handleStatus = useCallback((event) => {
|
|
10
|
+
setState((prev) => ({
|
|
11
|
+
recentEvents: [...prev.recentEvents.slice(-9), event],
|
|
12
|
+
// Keep last 10
|
|
13
|
+
successCount: prev.successCount + (event.success ? 1 : 0),
|
|
14
|
+
failureCount: prev.failureCount + (event.success ? 0 : 1)
|
|
15
|
+
}));
|
|
16
|
+
}, []);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!enabled) return;
|
|
19
|
+
hookStatusEmitter.on("status", handleStatus);
|
|
20
|
+
return () => {
|
|
21
|
+
hookStatusEmitter.off("status", handleStatus);
|
|
22
|
+
};
|
|
23
|
+
}, [enabled, handleStatus]);
|
|
24
|
+
return state;
|
|
25
|
+
}
|
|
26
|
+
function formatHookStatus(event) {
|
|
27
|
+
const timestamp = new Date(event.timestamp).toLocaleTimeString("en-US", {
|
|
28
|
+
hour: "numeric",
|
|
29
|
+
minute: "2-digit",
|
|
30
|
+
second: "2-digit",
|
|
31
|
+
hour12: true
|
|
32
|
+
});
|
|
33
|
+
const status = event.success ? "\u2713" : "\u2717";
|
|
34
|
+
return `${timestamp} ${status} ${event.message}`;
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
formatHookStatus,
|
|
38
|
+
useHookStatus
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=useHookStatus.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/useHookStatus.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Hook Status Tracking for Verbose Mode\n *\n * Listens to hookStatusEmitter and provides status information\n * for display in verbose mode.\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { hookStatusEmitter, HookStatusEvent } from '@services/hookExecutor'\n\ninterface HookStatusState {\n /** Recent hook events (last 10) */\n recentEvents: HookStatusEvent[]\n /** Count of successful hooks */\n successCount: number\n /** Count of failed hooks */\n failureCount: number\n}\n\n/**\n * Hook to track hook status events for verbose mode display\n *\n * @param enabled - Whether to listen for events (should be verbose mode)\n * @returns Hook status state\n */\nexport function useHookStatus(enabled: boolean): HookStatusState {\n const [state, setState] = useState<HookStatusState>({\n recentEvents: [],\n successCount: 0,\n failureCount: 0,\n })\n\n const handleStatus = useCallback((event: HookStatusEvent) => {\n setState(prev => ({\n recentEvents: [...prev.recentEvents.slice(-9), event], // Keep last 10\n successCount: prev.successCount + (event.success ? 1 : 0),\n failureCount: prev.failureCount + (event.success ? 0 : 1),\n }))\n }, [])\n\n useEffect(() => {\n if (!enabled) return\n\n hookStatusEmitter.on('status', handleStatus)\n return () => {\n hookStatusEmitter.off('status', handleStatus)\n }\n }, [enabled, handleStatus])\n\n return state\n}\n\n/**\n * Format hook status for display\n */\nexport function formatHookStatus(event: HookStatusEvent): string {\n const timestamp = new Date(event.timestamp).toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n hour12: true,\n })\n const status = event.success ? '\u2713' : '\u2717'\n return `${timestamp} ${status} ${event.message}`\n}\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,yBAA0C;AAiB5C,SAAS,cAAc,SAAmC;AAC/D,QAAM,CAAC,OAAO,QAAQ,IAAI,SAA0B;AAAA,IAClD,cAAc,CAAC;AAAA,IACf,cAAc;AAAA,IACd,cAAc;AAAA,EAChB,CAAC;AAED,QAAM,eAAe,YAAY,CAAC,UAA2B;AAC3D,aAAS,WAAS;AAAA,MAChB,cAAc,CAAC,GAAG,KAAK,aAAa,MAAM,EAAE,GAAG,KAAK;AAAA;AAAA,MACpD,cAAc,KAAK,gBAAgB,MAAM,UAAU,IAAI;AAAA,MACvD,cAAc,KAAK,gBAAgB,MAAM,UAAU,IAAI;AAAA,IACzD,EAAE;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,sBAAkB,GAAG,UAAU,YAAY;AAC3C,WAAO,MAAM;AACX,wBAAkB,IAAI,UAAU,YAAY;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,SAAS,YAAY,CAAC;AAE1B,SAAO;AACT;AAKO,SAAS,iBAAiB,OAAgC;AAC/D,QAAM,YAAY,IAAI,KAAK,MAAM,SAAS,EAAE,mBAAmB,SAAS;AAAA,IACtE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,SAAS,MAAM,UAAU,WAAM;AACrC,SAAO,GAAG,SAAS,IAAI,MAAM,IAAI,MAAM,OAAO;AAChD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,14 +1,41 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
2
|
import { overwriteLog, getMessagesPath } from "../utils/log.js";
|
|
3
|
+
function serializeMessageForLog(message) {
|
|
4
|
+
if (message.type === "progress") {
|
|
5
|
+
const progressMsg = message;
|
|
6
|
+
return {
|
|
7
|
+
type: "progress",
|
|
8
|
+
uuid: progressMsg.uuid,
|
|
9
|
+
toolUseID: progressMsg.toolUseID,
|
|
10
|
+
// Convert Set to Array for JSON serialization
|
|
11
|
+
siblingToolUseIDs: Array.from(progressMsg.siblingToolUseIDs),
|
|
12
|
+
// Keep the content (AssistantMessage) for display
|
|
13
|
+
content: progressMsg.content
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return message;
|
|
17
|
+
}
|
|
3
18
|
function useLogMessages(messages, messageLogName, forkNumber) {
|
|
19
|
+
const messagesRef = useRef(messages);
|
|
20
|
+
messagesRef.current = messages;
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
return () => {
|
|
23
|
+
if (messagesRef.current.length > 0) {
|
|
24
|
+
const serialized = messagesRef.current.map(serializeMessageForLog);
|
|
25
|
+
overwriteLog(getMessagesPath(messageLogName, forkNumber, 0), serialized);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}, [messageLogName, forkNumber]);
|
|
4
29
|
useEffect(() => {
|
|
30
|
+
const serializedMessages = messages.map(serializeMessageForLog);
|
|
5
31
|
overwriteLog(
|
|
6
32
|
getMessagesPath(messageLogName, forkNumber, 0),
|
|
7
|
-
|
|
33
|
+
serializedMessages
|
|
8
34
|
);
|
|
9
35
|
}, [messages, messageLogName, forkNumber]);
|
|
10
36
|
}
|
|
11
37
|
export {
|
|
38
|
+
serializeMessageForLog,
|
|
12
39
|
useLogMessages
|
|
13
40
|
};
|
|
14
41
|
//# sourceMappingURL=useLogMessages.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/hooks/useLogMessages.ts"],
|
|
4
|
-
"sourcesContent": ["import { useEffect } from 'react'\nimport { type Message } from '@query'\nimport { overwriteLog, getMessagesPath } from '@utils/log'\n\nexport function useLogMessages(\n messages: Message[],\n messageLogName: string,\n forkNumber: number,\n): void {\n useEffect(() => {\n
|
|
5
|
-
"mappings": "AAAA,SAAS,
|
|
4
|
+
"sourcesContent": ["import { useEffect, useRef } from 'react'\nimport { type Message, type ProgressMessage } from '@query'\nimport { overwriteLog, getMessagesPath } from '@utils/log'\n\n/**\n * Serialize a message for persistence.\n * Progress messages need special handling because they contain Sets that\n * cannot be directly JSON serialized, and they include references to tools\n * that would create circular references.\n *\n * Exported for use in REPL's onInterrupt to force-save messages before abort.\n */\nexport function serializeMessageForLog(message: Message): object {\n if (message.type === 'progress') {\n // Convert Set to Array for JSON serialization\n // Only keep essential fields - omit tools and normalizedMessages to avoid circular refs\n const progressMsg = message as ProgressMessage\n return {\n type: 'progress',\n uuid: progressMsg.uuid,\n toolUseID: progressMsg.toolUseID,\n // Convert Set to Array for JSON serialization\n siblingToolUseIDs: Array.from(progressMsg.siblingToolUseIDs),\n // Keep the content (AssistantMessage) for display\n content: progressMsg.content,\n }\n }\n return message\n}\n\nexport function useLogMessages(\n messages: Message[],\n messageLogName: string,\n forkNumber: number,\n): void {\n // Keep a ref to messages for cleanup function access\n // This ensures we can save the latest messages even during unmount\n const messagesRef = useRef(messages)\n messagesRef.current = messages\n\n // Defensive cleanup: ensure messages are saved when component unmounts\n // This catches cases where ESC interrupt or other state changes might\n // cause the component to unmount before the regular save effect runs\n useEffect(() => {\n return () => {\n if (messagesRef.current.length > 0) {\n const serialized = messagesRef.current.map(serializeMessageForLog)\n overwriteLog(getMessagesPath(messageLogName, forkNumber, 0), serialized)\n }\n }\n }, [messageLogName, forkNumber])\n\n // Regular save effect: runs on every messages change\n useEffect(() => {\n // Serialize all messages including progress messages\n // Progress messages are essential for proper tool use grouping on resume\n const serializedMessages = messages.map(serializeMessageForLog)\n overwriteLog(\n getMessagesPath(messageLogName, forkNumber, 0),\n serializedMessages,\n )\n }, [messages, messageLogName, forkNumber])\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,WAAW,cAAc;AAElC,SAAS,cAAc,uBAAuB;AAUvC,SAAS,uBAAuB,SAA0B;AAC/D,MAAI,QAAQ,SAAS,YAAY;AAG/B,UAAM,cAAc;AACpB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,YAAY;AAAA,MAClB,WAAW,YAAY;AAAA;AAAA,MAEvB,mBAAmB,MAAM,KAAK,YAAY,iBAAiB;AAAA;AAAA,MAE3D,SAAS,YAAY;AAAA,IACvB;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,eACd,UACA,gBACA,YACM;AAGN,QAAM,cAAc,OAAO,QAAQ;AACnC,cAAY,UAAU;AAKtB,YAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,YAAY,QAAQ,SAAS,GAAG;AAClC,cAAM,aAAa,YAAY,QAAQ,IAAI,sBAAsB;AACjE,qBAAa,gBAAgB,gBAAgB,YAAY,CAAC,GAAG,UAAU;AAAA,MACzE;AAAA,IACF;AAAA,EACF,GAAG,CAAC,gBAAgB,UAAU,CAAC;AAG/B,YAAU,MAAM;AAGd,UAAM,qBAAqB,SAAS,IAAI,sBAAsB;AAC9D;AAAA,MACE,gBAAgB,gBAAgB,YAAY,CAAC;AAAA,MAC7C;AAAA,IACF;AAAA,EACF,GAAG,CAAC,UAAU,gBAAgB,UAAU,CAAC;AAC3C;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { MessageGroupManager } from "../utils/messageGroupManager.js";
|
|
3
|
+
import { DISPLAY_CONFIGS } from "../types/messageGroup.js";
|
|
4
|
+
function useMessageGroups(normalizedMessages, unresolvedToolUseIDs, inProgressToolUseIDs, verbose = false) {
|
|
5
|
+
const displayConfig = useMemo(
|
|
6
|
+
() => verbose ? DISPLAY_CONFIGS.verbose : DISPLAY_CONFIGS.normal,
|
|
7
|
+
[verbose]
|
|
8
|
+
);
|
|
9
|
+
const managerState = useMemo(() => {
|
|
10
|
+
const manager2 = new MessageGroupManager();
|
|
11
|
+
manager2.identifyGroups(normalizedMessages);
|
|
12
|
+
manager2.updateResolutionStates(unresolvedToolUseIDs, inProgressToolUseIDs);
|
|
13
|
+
const groups2 = manager2.getAllGroups();
|
|
14
|
+
const groupById2 = new Map(groups2.map((g) => [g.id, g]));
|
|
15
|
+
return { manager: manager2, groups: groups2, groupById: groupById2 };
|
|
16
|
+
}, [normalizedMessages, unresolvedToolUseIDs, inProgressToolUseIDs]);
|
|
17
|
+
const { manager, groups, groupById } = managerState;
|
|
18
|
+
const getGroupForMessage = useMemo(
|
|
19
|
+
() => (messageUuid) => manager.getGroupByMessageUuid(messageUuid),
|
|
20
|
+
[manager]
|
|
21
|
+
);
|
|
22
|
+
const getGroupForToolUse = useMemo(
|
|
23
|
+
() => (toolUseId) => manager.getGroupByToolUseId(toolUseId),
|
|
24
|
+
[manager]
|
|
25
|
+
);
|
|
26
|
+
const shouldGroupBeStatic = useMemo(
|
|
27
|
+
() => (group) => manager.shouldGroupBeStatic(group),
|
|
28
|
+
[manager]
|
|
29
|
+
);
|
|
30
|
+
return {
|
|
31
|
+
groups,
|
|
32
|
+
manager,
|
|
33
|
+
groupById,
|
|
34
|
+
getGroupForMessage,
|
|
35
|
+
getGroupForToolUse,
|
|
36
|
+
shouldGroupBeStatic,
|
|
37
|
+
displayConfig
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
useMessageGroups
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=useMessageGroups.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/useMessageGroups.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * useMessageGroups Hook\n *\n * Provides integration between MessageGroupManager and React components.\n * Handles group identification, resolution state updates, and memoization.\n */\n\nimport { useMemo } from 'react'\nimport type { NormalizedMessage } from '@utils/messages'\nimport type { AgentTranscript } from '@utils/agentTranscripts'\nimport { MessageGroupManager } from '@utils/messageGroupManager'\nimport type { MessageGroup, DisplayConfig } from '@minto-types/messageGroup'\nimport { DISPLAY_CONFIGS } from '@minto-types/messageGroup'\n\ninterface UseMessageGroupsResult {\n /** All identified message groups */\n groups: MessageGroup[]\n /** Group manager instance for direct access */\n manager: MessageGroupManager\n /** Map of group ID to group */\n groupById: Map<string, MessageGroup>\n /** Get group for a specific message UUID */\n getGroupForMessage: (messageUuid: string) => MessageGroup | undefined\n /** Get group for a specific toolUseId */\n getGroupForToolUse: (toolUseId: string) => MessageGroup | undefined\n /** Check if a group should be rendered as static */\n shouldGroupBeStatic: (group: MessageGroup) => boolean\n /** Current display configuration */\n displayConfig: DisplayConfig\n}\n\n/**\n * Hook for managing message groups in React components\n *\n * @param normalizedMessages - Normalized message array\n * @param unresolvedToolUseIDs - Set of unresolved tool use IDs\n * @param inProgressToolUseIDs - Set of in-progress tool use IDs\n * @param verbose - Whether verbose mode is enabled\n * @returns Message group utilities and state\n */\nexport function useMessageGroups(\n normalizedMessages: NormalizedMessage[],\n unresolvedToolUseIDs: Set<string>,\n inProgressToolUseIDs: Set<string>,\n verbose: boolean = false,\n): UseMessageGroupsResult {\n // Select display config based on verbose mode\n const displayConfig = useMemo(\n () => (verbose ? DISPLAY_CONFIGS.verbose : DISPLAY_CONFIGS.normal),\n [verbose],\n )\n\n // Create and update message group manager\n // Memoized to only recompute when dependencies change\n const managerState = useMemo(() => {\n const manager = new MessageGroupManager()\n\n // Identify groups from messages\n manager.identifyGroups(normalizedMessages)\n\n // Update resolution states\n manager.updateResolutionStates(unresolvedToolUseIDs, inProgressToolUseIDs)\n\n // Get all groups\n const groups = manager.getAllGroups()\n const groupById = new Map(groups.map(g => [g.id, g]))\n\n return { manager, groups, groupById }\n }, [normalizedMessages, unresolvedToolUseIDs, inProgressToolUseIDs])\n\n const { manager, groups, groupById } = managerState\n\n // Helper to get group for a message\n const getGroupForMessage = useMemo(\n () => (messageUuid: string) => manager.getGroupByMessageUuid(messageUuid),\n [manager],\n )\n\n // Helper to get group for a toolUseId\n const getGroupForToolUse = useMemo(\n () => (toolUseId: string) => manager.getGroupByToolUseId(toolUseId),\n [manager],\n )\n\n // Helper to check if group should be static\n const shouldGroupBeStatic = useMemo(\n () => (group: MessageGroup) => manager.shouldGroupBeStatic(group),\n [manager],\n )\n\n return {\n groups,\n manager,\n groupById,\n getGroupForMessage,\n getGroupForToolUse,\n shouldGroupBeStatic,\n displayConfig,\n }\n}\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,eAAe;AAGxB,SAAS,2BAA2B;AAEpC,SAAS,uBAAuB;AA4BzB,SAAS,iBACd,oBACA,sBACA,sBACA,UAAmB,OACK;AAExB,QAAM,gBAAgB;AAAA,IACpB,MAAO,UAAU,gBAAgB,UAAU,gBAAgB;AAAA,IAC3D,CAAC,OAAO;AAAA,EACV;AAIA,QAAM,eAAe,QAAQ,MAAM;AACjC,UAAMA,WAAU,IAAI,oBAAoB;AAGxC,IAAAA,SAAQ,eAAe,kBAAkB;AAGzC,IAAAA,SAAQ,uBAAuB,sBAAsB,oBAAoB;AAGzE,UAAMC,UAASD,SAAQ,aAAa;AACpC,UAAME,aAAY,IAAI,IAAID,QAAO,IAAI,OAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAEpD,WAAO,EAAE,SAAAD,UAAS,QAAAC,SAAQ,WAAAC,WAAU;AAAA,EACtC,GAAG,CAAC,oBAAoB,sBAAsB,oBAAoB,CAAC;AAEnE,QAAM,EAAE,SAAS,QAAQ,UAAU,IAAI;AAGvC,QAAM,qBAAqB;AAAA,IACzB,MAAM,CAAC,gBAAwB,QAAQ,sBAAsB,WAAW;AAAA,IACxE,CAAC,OAAO;AAAA,EACV;AAGA,QAAM,qBAAqB;AAAA,IACzB,MAAM,CAAC,cAAsB,QAAQ,oBAAoB,SAAS;AAAA,IAClE,CAAC,OAAO;AAAA,EACV;AAGA,QAAM,sBAAsB;AAAA,IAC1B,MAAM,CAAC,UAAwB,QAAQ,oBAAoB,KAAK;AAAA,IAChE,CAAC,OAAO;AAAA,EACV;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
|
+
"names": ["manager", "groups", "groupById"]
|
|
7
|
+
}
|