@within-7/minto 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Tool.js +7 -0
- package/dist/Tool.js.map +2 -2
- package/dist/commands/agents/AgentsCommand.js +1 -1
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/constants.js +2 -2
- package/dist/commands/agents/constants.js.map +2 -2
- package/dist/commands/clear.js +4 -3
- package/dist/commands/clear.js.map +2 -2
- package/dist/commands/compact.js +2 -2
- package/dist/commands/compact.js.map +1 -1
- package/dist/commands/context.js +3 -1
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/login.js +128 -0
- package/dist/commands/login.js.map +7 -0
- package/dist/commands/memory.js +33 -82
- package/dist/commands/memory.js.map +2 -2
- package/dist/commands/quit.js +3 -1
- package/dist/commands/quit.js.map +2 -2
- package/dist/commands/resume.js +39 -239
- package/dist/commands/resume.js.map +2 -2
- package/dist/commands/tasks.js +1 -1
- package/dist/commands/tasks.js.map +2 -2
- package/dist/commands/terminalSetup.js +6 -2
- package/dist/commands/terminalSetup.js.map +2 -2
- package/dist/commands.js +2 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/AgentDetailView.js +126 -0
- package/dist/components/AgentDetailView.js.map +7 -0
- package/dist/components/AgentThinkingBlock.js +1 -1
- package/dist/components/AgentThinkingBlock.js.map +2 -2
- package/dist/components/AgentViewBanner.js +22 -0
- package/dist/components/AgentViewBanner.js.map +7 -0
- package/dist/components/HeaderBar.js +1 -1
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/Help.js +8 -1
- package/dist/components/Help.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +26 -8
- package/dist/components/HotkeyHelpPanel.js.map +2 -2
- package/dist/components/IdleNotificationBar.js +10 -0
- package/dist/components/IdleNotificationBar.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +55 -20
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/PromptInput.js +186 -115
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/RewindPanel.js +272 -0
- package/dist/components/RewindPanel.js.map +7 -0
- package/dist/components/Spinner.js +10 -21
- package/dist/components/Spinner.js.map +2 -2
- package/dist/components/StreamingTextPreview.js +29 -0
- package/dist/components/StreamingTextPreview.js.map +7 -0
- package/dist/components/SubagentBlock.js +3 -2
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/SubagentProgress.js +4 -4
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TabbedListView/SearchInput.js +1 -1
- package/dist/components/TabbedListView/SearchInput.js.map +2 -2
- package/dist/components/TabbedListView/TabbedListView.js +87 -41
- package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
- package/dist/components/TaskCard.js +4 -4
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TeamMemberPanel.js +107 -0
- package/dist/components/TeamMemberPanel.js.map +7 -0
- package/dist/components/ThinkingSelector.js +84 -0
- package/dist/components/ThinkingSelector.js.map +7 -0
- package/dist/components/TitledDivider.js +26 -0
- package/dist/components/TitledDivider.js.map +7 -0
- package/dist/components/TodoPanel.js +31 -30
- package/dist/components/TodoPanel.js.map +2 -2
- package/dist/components/TokenWarning.js +28 -7
- package/dist/components/TokenWarning.js.map +2 -2
- package/dist/components/messages/AssistantTextMessage.js +5 -2
- package/dist/components/messages/AssistantTextMessage.js.map +2 -2
- package/dist/components/messages/AssistantToolUseMessage.js +9 -1
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/DefaultToolResultFallback.js +11 -0
- package/dist/components/messages/DefaultToolResultFallback.js.map +7 -0
- package/dist/components/messages/ParallelTasksGroupView.js +14 -6
- package/dist/components/messages/ParallelTasksGroupView.js.map +2 -2
- package/dist/components/messages/TaskInModuleView.js +27 -27
- package/dist/components/messages/TaskInModuleView.js.map +2 -2
- package/dist/components/messages/UserGuidanceMessage.js +26 -0
- package/dist/components/messages/UserGuidanceMessage.js.map +7 -0
- package/dist/components/messages/UserPromptMessage.js +2 -1
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/components/messages/UserTeamNotificationMessage.js +91 -0
- package/dist/components/messages/UserTeamNotificationMessage.js.map +7 -0
- package/dist/components/messages/UserTextMessage.js +8 -0
- package/dist/components/messages/UserTextMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolRejectMessage.js +4 -2
- package/dist/components/messages/UserToolResultMessage/UserToolRejectMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolResultMessage.js +18 -1
- package/dist/components/messages/UserToolResultMessage/UserToolResultMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +12 -1
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
- package/dist/components/permissions/PermissionRequest.js +4 -0
- package/dist/components/permissions/PermissionRequest.js.map +2 -2
- package/dist/components/permissions/PlanApprovalRequest.js +164 -0
- package/dist/components/permissions/PlanApprovalRequest.js.map +7 -0
- package/dist/constants/agentTeams.js +17 -0
- package/dist/constants/agentTeams.js.map +7 -0
- package/dist/constants/macros.js +2 -1
- package/dist/constants/macros.js.map +2 -2
- package/dist/constants/prompts/agentPrompt.js +1 -0
- package/dist/constants/prompts/agentPrompt.js.map +2 -2
- package/dist/constants/prompts/autoMemory.js +39 -0
- package/dist/constants/prompts/autoMemory.js.map +7 -0
- package/dist/constants/prompts/codeConventions.js +1 -13
- package/dist/constants/prompts/codeConventions.js.map +2 -2
- package/dist/constants/prompts/doingTasks.js +21 -2
- package/dist/constants/prompts/doingTasks.js.map +2 -2
- package/dist/constants/prompts/envInfo.js +6 -7
- package/dist/constants/prompts/envInfo.js.map +2 -2
- package/dist/constants/prompts/index.js +27 -5
- package/dist/constants/prompts/index.js.map +2 -2
- package/dist/constants/prompts/taskManagement.js +2 -43
- package/dist/constants/prompts/taskManagement.js.map +2 -2
- package/dist/constants/prompts/teamOverlays.js +50 -0
- package/dist/constants/prompts/teamOverlays.js.map +7 -0
- package/dist/constants/prompts/toneAndStyle.js +4 -29
- package/dist/constants/prompts/toneAndStyle.js.map +2 -2
- package/dist/constants/prompts/toolUsagePolicy.js +7 -22
- package/dist/constants/prompts/toolUsagePolicy.js.map +2 -2
- package/dist/constants/toolInputExamples.js +2 -2
- package/dist/constants/toolInputExamples.js.map +2 -2
- package/dist/context.js +39 -6
- package/dist/context.js.map +2 -2
- package/dist/core/backupManager.js +1 -1
- package/dist/core/backupManager.js.map +2 -2
- package/dist/core/permissions/rules/planModeRule.js +1 -1
- package/dist/core/permissions/rules/planModeRule.js.map +1 -1
- package/dist/core/permissions/rules/safeModeRule.js +1 -1
- package/dist/core/permissions/rules/safeModeRule.js.map +1 -1
- package/dist/engine/AgentEngine.js +902 -0
- package/dist/engine/AgentEngine.js.map +7 -0
- package/dist/engine/EngineRegistry.js +89 -0
- package/dist/engine/EngineRegistry.js.map +7 -0
- package/dist/engine/foregroundAdapter.js +191 -0
- package/dist/engine/foregroundAdapter.js.map +7 -0
- package/dist/engine/index.js +15 -0
- package/dist/engine/index.js.map +7 -0
- package/dist/engine/types.js +1 -0
- package/dist/engine/types.js.map +7 -0
- package/dist/entrypoints/cli.js +410 -79
- package/dist/entrypoints/cli.js.map +3 -3
- package/dist/hooks/useAgentEngine.js +129 -0
- package/dist/hooks/useAgentEngine.js.map +7 -0
- package/dist/hooks/useAgentTokenStats.js +0 -16
- package/dist/hooks/useAgentTokenStats.js.map +2 -2
- package/dist/hooks/useCanUseTool.js +47 -2
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useDeferredLoading.js +4 -1
- package/dist/hooks/useDeferredLoading.js.map +2 -2
- package/dist/hooks/useIdleNotifications.js +66 -0
- package/dist/hooks/useIdleNotifications.js.map +7 -0
- package/dist/hooks/useSessionTracking.js +9 -7
- package/dist/hooks/useSessionTracking.js.map +2 -2
- package/dist/hooks/useTeamMembers.js +51 -0
- package/dist/hooks/useTeamMembers.js.map +7 -0
- package/dist/i18n/locales/en.js +77 -12
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +77 -12
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js +113 -7
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +135 -37
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +504 -361
- package/dist/screens/REPL.js.map +3 -3
- package/dist/screens/ResumeConversation.js +199 -14
- package/dist/screens/ResumeConversation.js.map +2 -2
- package/dist/services/adapters/base.js.map +1 -1
- package/dist/services/agentTeams/backends/headless.js +108 -0
- package/dist/services/agentTeams/backends/headless.js.map +7 -0
- package/dist/services/agentTeams/backends/inProcess.js +102 -0
- package/dist/services/agentTeams/backends/inProcess.js.map +7 -0
- package/dist/services/agentTeams/backends/resolver.js +18 -0
- package/dist/services/agentTeams/backends/resolver.js.map +7 -0
- package/dist/services/agentTeams/backends/tmux.js +168 -0
- package/dist/services/agentTeams/backends/tmux.js.map +7 -0
- package/dist/services/agentTeams/backends/types.js +1 -0
- package/dist/services/agentTeams/backends/types.js.map +7 -0
- package/dist/services/agentTeams/heartbeat.js +88 -0
- package/dist/services/agentTeams/heartbeat.js.map +7 -0
- package/dist/services/agentTeams/index.js +42 -2
- package/dist/services/agentTeams/index.js.map +2 -2
- package/dist/services/agentTeams/injectionChannel.js +105 -0
- package/dist/services/agentTeams/injectionChannel.js.map +7 -0
- package/dist/services/agentTeams/mailbox.js +410 -30
- package/dist/services/agentTeams/mailbox.js.map +2 -2
- package/dist/services/agentTeams/messageFormatter.js +80 -0
- package/dist/services/agentTeams/messageFormatter.js.map +7 -0
- package/dist/services/agentTeams/permissionDelegation.js +71 -0
- package/dist/services/agentTeams/permissionDelegation.js.map +7 -0
- package/dist/services/agentTeams/teamEvents.js +45 -0
- package/dist/services/agentTeams/teamEvents.js.map +7 -0
- package/dist/services/agentTeams/teamManager.js +251 -34
- package/dist/services/agentTeams/teamManager.js.map +2 -2
- package/dist/services/agentTeams/teamTaskStore.js +290 -61
- package/dist/services/agentTeams/teamTaskStore.js.map +2 -2
- package/dist/services/agentTeams/teammateSpawner.js +99 -18
- package/dist/services/agentTeams/teammateSpawner.js.map +2 -2
- package/dist/services/hookExecutor.js +51 -8
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/llm/anthropicProvider.js +56 -59
- package/dist/services/llm/anthropicProvider.js.map +2 -2
- package/dist/services/llm/dispatch.js +24 -5
- package/dist/services/llm/dispatch.js.map +2 -2
- package/dist/services/llm/openaiProvider.js +115 -136
- package/dist/services/llm/openaiProvider.js.map +3 -3
- package/dist/services/llm/types.js +89 -15
- package/dist/services/llm/types.js.map +2 -2
- package/dist/services/mcpClient.js +80 -4
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/mintoAuth.js +299 -0
- package/dist/services/mintoAuth.js.map +7 -0
- package/dist/services/oauth.js +3 -3
- package/dist/services/oauth.js.map +2 -2
- package/dist/services/openai.js +91 -20
- package/dist/services/openai.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +11 -5
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +4 -2
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/sandbox/sandboxController.js +11 -3
- package/dist/services/sandbox/sandboxController.js.map +2 -2
- package/dist/services/sessionMemoryInjector.js +77 -0
- package/dist/services/sessionMemoryInjector.js.map +7 -0
- package/dist/services/systemReminder.js +130 -8
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/services/taskStore.js +199 -8
- package/dist/services/taskStore.js.map +3 -3
- package/dist/services/topicDetector.js +169 -0
- package/dist/services/topicDetector.js.map +7 -0
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +0 -13
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js +51 -28
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/BashTool/prompt.js +95 -118
- package/dist/tools/BashTool/prompt.js.map +2 -2
- package/dist/tools/BashTool/utils.js +39 -1
- package/dist/tools/BashTool/utils.js.map +2 -2
- package/dist/tools/EnterWorktreeTool/EnterWorktreeTool.js +121 -0
- package/dist/tools/EnterWorktreeTool/EnterWorktreeTool.js.map +7 -0
- package/dist/tools/EnterWorktreeTool/prompt.js +22 -0
- package/dist/tools/EnterWorktreeTool/prompt.js.map +7 -0
- package/dist/tools/FileEditTool/FileEditTool.js +9 -4
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileEditTool/prompt.js +3 -7
- package/dist/tools/FileEditTool/prompt.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js +125 -3
- package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
- package/dist/tools/FileReadTool/prompt.js +1 -2
- package/dist/tools/FileReadTool/prompt.js.map +2 -2
- package/dist/tools/FileWriteTool/prompt.js +3 -5
- package/dist/tools/FileWriteTool/prompt.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js +3 -2
- package/dist/tools/GlobTool/GlobTool.js.map +2 -2
- package/dist/tools/GrepTool/GrepTool.js +16 -5
- package/dist/tools/GrepTool/GrepTool.js.map +2 -2
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
- package/dist/tools/MCPSearchTool/MCPSearchTool.js +172 -0
- package/dist/tools/MCPSearchTool/MCPSearchTool.js.map +7 -0
- package/dist/tools/MCPSearchTool/prompt.js +77 -0
- package/dist/tools/MCPSearchTool/prompt.js.map +7 -0
- package/dist/tools/MultiEditTool/prompt.js +4 -7
- package/dist/tools/MultiEditTool/prompt.js.map +2 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +12 -8
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +54 -1
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/prompt.js +23 -74
- package/dist/tools/PlanModeTool/prompt.js.map +2 -2
- package/dist/tools/SendMessageTool/SendMessageTool.js +341 -0
- package/dist/tools/SendMessageTool/SendMessageTool.js.map +7 -0
- package/dist/tools/SendMessageTool/prompt.js +44 -0
- package/dist/tools/SendMessageTool/prompt.js.map +7 -0
- package/dist/tools/TaskCreateTool/prompt.js +15 -4
- package/dist/tools/TaskCreateTool/prompt.js.map +2 -2
- package/dist/tools/TaskListTool/prompt.js +18 -3
- package/dist/tools/TaskListTool/prompt.js.map +2 -2
- package/dist/tools/TaskOutputTool/prompt.js +4 -3
- package/dist/tools/TaskOutputTool/prompt.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +762 -98
- package/dist/tools/TaskTool/TaskTool.js.map +3 -3
- package/dist/tools/TaskTool/constants.js +8 -2
- package/dist/tools/TaskTool/constants.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js +74 -70
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js +15 -1
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +2 -2
- package/dist/tools/TeamCreateTool/TeamCreateTool.js +129 -0
- package/dist/tools/TeamCreateTool/TeamCreateTool.js.map +7 -0
- package/dist/tools/TeamCreateTool/prompt.js +58 -0
- package/dist/tools/TeamCreateTool/prompt.js.map +7 -0
- package/dist/tools/TeamDeleteTool/TeamDeleteTool.js +151 -0
- package/dist/tools/TeamDeleteTool/TeamDeleteTool.js.map +7 -0
- package/dist/tools/TeamDeleteTool/prompt.js +16 -0
- package/dist/tools/TeamDeleteTool/prompt.js.map +7 -0
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +106 -15
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/prompt.js +3 -2
- package/dist/tools/URLFetcherTool/prompt.js.map +2 -2
- package/dist/tools/WebSearchTool/WebSearchTool.js +2 -1
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +2 -2
- package/dist/tools/WebSearchTool/prompt.js +5 -4
- package/dist/tools/WebSearchTool/prompt.js.map +2 -2
- package/dist/tools.js +100 -20
- package/dist/tools.js.map +2 -2
- package/dist/types/PermissionMode.js +35 -6
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/hooks.js +2 -0
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/plugin.js +2 -0
- package/dist/types/plugin.js.map +3 -3
- package/dist/utils/CircuitBreaker.js +15 -9
- package/dist/utils/CircuitBreaker.js.map +2 -2
- package/dist/utils/agentLoader.js +249 -112
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/animationManager.js +40 -3
- package/dist/utils/animationManager.js.map +2 -2
- package/dist/utils/ask.js +7 -6
- package/dist/utils/ask.js.map +2 -2
- package/dist/utils/atomicWrite.js +23 -0
- package/dist/utils/atomicWrite.js.map +7 -0
- package/dist/utils/autoCompactCore.js +73 -56
- package/dist/utils/autoCompactCore.js.map +2 -2
- package/dist/utils/autoMemoryPaths.js +89 -0
- package/dist/utils/autoMemoryPaths.js.map +7 -0
- package/dist/utils/config.js +63 -38
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configSchema.js +13 -8
- package/dist/utils/configSchema.js.map +2 -2
- package/dist/utils/credentials/index.js +14 -0
- package/dist/utils/credentials/index.js.map +2 -2
- package/dist/utils/dualPath.js +24 -0
- package/dist/utils/dualPath.js.map +7 -0
- package/dist/utils/exit.js +66 -7
- package/dist/utils/exit.js.map +2 -2
- package/dist/utils/externalEditor.js +155 -0
- package/dist/utils/externalEditor.js.map +7 -0
- package/dist/utils/fileLock.js +67 -0
- package/dist/utils/fileLock.js.map +7 -0
- package/dist/utils/format.js +24 -14
- package/dist/utils/format.js.map +2 -2
- package/dist/utils/globalErrorHandler.js +5 -96
- package/dist/utils/globalErrorHandler.js.map +3 -3
- package/dist/utils/groupHandlers/parallelTasksHandler.js +5 -3
- package/dist/utils/groupHandlers/parallelTasksHandler.js.map +2 -2
- package/dist/utils/groupHandlers/taskHandler.js +2 -2
- package/dist/utils/groupHandlers/taskHandler.js.map +2 -2
- package/dist/utils/hookManager.js +64 -6
- package/dist/utils/hookManager.js.map +2 -2
- package/dist/utils/log.js +6 -2
- package/dist/utils/log.js.map +2 -2
- package/dist/utils/markdown.js +237 -19
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/messageContextManager.js +18 -5
- package/dist/utils/messageContextManager.js.map +2 -2
- package/dist/utils/messageGroupManager.js +1 -1
- package/dist/utils/messageGroupManager.js.map +2 -2
- package/dist/utils/messages.js +104 -46
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +2 -2
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/pasteCache.js +8 -4
- package/dist/utils/pasteCache.js.map +2 -2
- package/dist/utils/pluginLoader.js +18 -0
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/secureKeyStorage.js +36 -7
- package/dist/utils/secureKeyStorage.js.map +2 -2
- package/dist/utils/simpleMode.js +7 -0
- package/dist/utils/simpleMode.js.map +7 -0
- package/dist/utils/streamingState.js +11 -1
- package/dist/utils/streamingState.js.map +2 -2
- package/dist/utils/taskDisplayUtils.js +2 -1
- package/dist/utils/taskDisplayUtils.js.map +2 -2
- package/dist/utils/teamConfig.js +2 -2
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/thinking.js +6 -2
- package/dist/utils/thinking.js.map +3 -3
- package/dist/utils/tokenProgress.js +55 -0
- package/dist/utils/tokenProgress.js.map +7 -0
- package/dist/utils/toolRiskClassification.js +26 -17
- package/dist/utils/toolRiskClassification.js.map +2 -2
- package/dist/utils/tooling/toolError.js +12 -0
- package/dist/utils/tooling/toolError.js.map +7 -0
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +10 -8
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { useState, useEffect, useRef, useCallback, useMemo } from "react";
|
|
2
|
+
function useAgentEngine(engine) {
|
|
3
|
+
const [messages, setMessagesState] = useState([]);
|
|
4
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
5
|
+
const [engineState, setEngineState] = useState("created");
|
|
6
|
+
const [lastTurnDurationMs, setLastTurnDurationMs] = useState(
|
|
7
|
+
null
|
|
8
|
+
);
|
|
9
|
+
const engineRef = useRef(engine);
|
|
10
|
+
engineRef.current = engine;
|
|
11
|
+
const pendingMessagesRef = useRef([]);
|
|
12
|
+
const timerRef = useRef(null);
|
|
13
|
+
const prevEngineRef = useRef(engine);
|
|
14
|
+
if (prevEngineRef.current !== engine) {
|
|
15
|
+
prevEngineRef.current = engine;
|
|
16
|
+
if (engine) {
|
|
17
|
+
setMessagesState([...engine.messages]);
|
|
18
|
+
setEngineState(engine.state);
|
|
19
|
+
setIsLoading(engine.state === "querying");
|
|
20
|
+
} else {
|
|
21
|
+
setMessagesState([]);
|
|
22
|
+
setEngineState("created");
|
|
23
|
+
setIsLoading(false);
|
|
24
|
+
}
|
|
25
|
+
setLastTurnDurationMs(null);
|
|
26
|
+
pendingMessagesRef.current = [];
|
|
27
|
+
if (timerRef.current) {
|
|
28
|
+
clearImmediate(timerRef.current);
|
|
29
|
+
timerRef.current = null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const flushMessages = useCallback(() => {
|
|
33
|
+
if (pendingMessagesRef.current.length === 0) return;
|
|
34
|
+
const batch = pendingMessagesRef.current.splice(0);
|
|
35
|
+
setMessagesState((prev) => [...prev, ...batch]);
|
|
36
|
+
}, []);
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (!engine) return () => {
|
|
39
|
+
};
|
|
40
|
+
setMessagesState([...engine.messages]);
|
|
41
|
+
setEngineState(engine.state);
|
|
42
|
+
setIsLoading(engine.state === "querying");
|
|
43
|
+
const handleEvent = (event) => {
|
|
44
|
+
switch (event.type) {
|
|
45
|
+
case "state_change":
|
|
46
|
+
setEngineState(event.to);
|
|
47
|
+
setIsLoading(event.to === "querying");
|
|
48
|
+
break;
|
|
49
|
+
case "message":
|
|
50
|
+
pendingMessagesRef.current.push(event.message);
|
|
51
|
+
if (!timerRef.current) {
|
|
52
|
+
timerRef.current = setImmediate(() => {
|
|
53
|
+
timerRef.current = null;
|
|
54
|
+
flushMessages();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
case "messages_set":
|
|
59
|
+
pendingMessagesRef.current = [];
|
|
60
|
+
if (timerRef.current) {
|
|
61
|
+
clearImmediate(timerRef.current);
|
|
62
|
+
timerRef.current = null;
|
|
63
|
+
}
|
|
64
|
+
setMessagesState([...event.messages]);
|
|
65
|
+
if (event.messages.length === 0) {
|
|
66
|
+
setLastTurnDurationMs(null);
|
|
67
|
+
}
|
|
68
|
+
break;
|
|
69
|
+
case "turn_start":
|
|
70
|
+
setLastTurnDurationMs(null);
|
|
71
|
+
break;
|
|
72
|
+
case "turn_end":
|
|
73
|
+
setLastTurnDurationMs(event.durationMs);
|
|
74
|
+
flushMessages();
|
|
75
|
+
break;
|
|
76
|
+
case "error":
|
|
77
|
+
flushMessages();
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const unsub = engine.on(handleEvent);
|
|
82
|
+
return () => {
|
|
83
|
+
unsub();
|
|
84
|
+
if (timerRef.current) {
|
|
85
|
+
clearImmediate(timerRef.current);
|
|
86
|
+
timerRef.current = null;
|
|
87
|
+
}
|
|
88
|
+
flushMessages();
|
|
89
|
+
};
|
|
90
|
+
}, [engine, flushMessages]);
|
|
91
|
+
const submitPrompt = useCallback(async (input) => {
|
|
92
|
+
await engineRef.current?.submitPrompt(input);
|
|
93
|
+
}, []);
|
|
94
|
+
const abort = useCallback(() => {
|
|
95
|
+
engineRef.current?.abort();
|
|
96
|
+
}, []);
|
|
97
|
+
const setMessages = useCallback((msgs) => {
|
|
98
|
+
engineRef.current?.setMessages(msgs);
|
|
99
|
+
}, []);
|
|
100
|
+
const appendMessages = useCallback((msgs) => {
|
|
101
|
+
engineRef.current?.appendMessages(msgs);
|
|
102
|
+
}, []);
|
|
103
|
+
return useMemo(
|
|
104
|
+
() => ({
|
|
105
|
+
messages,
|
|
106
|
+
isLoading,
|
|
107
|
+
engineState,
|
|
108
|
+
lastTurnDurationMs,
|
|
109
|
+
submitPrompt,
|
|
110
|
+
abort,
|
|
111
|
+
setMessages,
|
|
112
|
+
appendMessages
|
|
113
|
+
}),
|
|
114
|
+
[
|
|
115
|
+
messages,
|
|
116
|
+
isLoading,
|
|
117
|
+
engineState,
|
|
118
|
+
lastTurnDurationMs,
|
|
119
|
+
submitPrompt,
|
|
120
|
+
abort,
|
|
121
|
+
setMessages,
|
|
122
|
+
appendMessages
|
|
123
|
+
]
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
export {
|
|
127
|
+
useAgentEngine
|
|
128
|
+
};
|
|
129
|
+
//# sourceMappingURL=useAgentEngine.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/useAgentEngine.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * useAgentEngine \u2014 React bridge for AgentEngine events.\n *\n * Subscribes to an AgentEngine's event stream and provides\n * React-compatible state for rendering. Uses batched updates\n * to minimize render churn during high-frequency message streams.\n */\n\nimport { useState, useEffect, useRef, useCallback, useMemo } from 'react'\nimport type { AgentEngine } from '../engine/AgentEngine'\nimport type { EngineState, EngineEvent } from '../engine/types'\nimport type { Message } from '@query'\n\nexport interface UseAgentEngineResult {\n /** Current messages from the engine. */\n messages: Message[]\n /** Whether the engine is currently querying. */\n isLoading: boolean\n /** Current engine state. */\n engineState: EngineState\n /** Duration of the last completed turn in ms, or null if no turn completed yet. */\n lastTurnDurationMs: number | null\n /** Submit user input to the engine. Delegates to engine.submitPrompt(). */\n submitPrompt: (input: string | Message[]) => Promise<void>\n /** Abort the current query. Delegates to engine.abort(). */\n abort: () => void\n /** Replace the messages array (e.g., for rollback). Delegates to engine.setMessages(). */\n setMessages: (messages: Message[]) => void\n /** Append messages without triggering a query. Delegates to engine.appendMessages(). */\n appendMessages: (messages: Message[]) => void\n}\n\n/**\n * React hook that bridges AgentEngine events to React state.\n *\n * @param engine - The AgentEngine instance to subscribe to, or null.\n * @returns Reactive state derived from engine events, plus stable callbacks.\n */\nexport function useAgentEngine(\n engine: AgentEngine | null,\n): UseAgentEngineResult {\n const [messages, setMessagesState] = useState<Message[]>([])\n const [isLoading, setIsLoading] = useState(false)\n const [engineState, setEngineState] = useState<EngineState>('created')\n const [lastTurnDurationMs, setLastTurnDurationMs] = useState<number | null>(\n null,\n )\n\n // Keep a ref to the engine for stable callbacks\n const engineRef = useRef(engine)\n engineRef.current = engine\n\n // Batch buffer: accumulate messages and flush on next tick.\n // Uses setImmediate (Node.js/Bun) instead of requestAnimationFrame (browser-only)\n // to ensure messages flush reliably in CLI environments.\n const pendingMessagesRef = useRef<Message[]>([])\n const timerRef = useRef<ReturnType<typeof setImmediate> | null>(null)\n\n // \u2500\u2500 Synchronous state sync when engine parameter changes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // React 18+ \"adjusting state based on props\" pattern.\n //\n // Without this, there's a one-render-cycle delay: the first render after\n // an engine switch still uses the OLD engine's messages (because useEffect\n // hasn't fired yet). If a <Static> component is recreated (via forkNumber\n // key change) during that render, it permanently writes the stale messages\n // to the terminal. Then useEffect fires, syncing new messages, which get\n // appended \u2014 resulting in duplicated content.\n //\n // By syncing during render, React discards the stale render and immediately\n // retries with correct state, ensuring <Static> only sees the new engine.\n const prevEngineRef = useRef(engine)\n if (prevEngineRef.current !== engine) {\n prevEngineRef.current = engine\n if (engine) {\n setMessagesState([...engine.messages])\n setEngineState(engine.state)\n setIsLoading(engine.state === 'querying')\n } else {\n setMessagesState([])\n setEngineState('created')\n setIsLoading(false)\n }\n setLastTurnDurationMs(null)\n // Clear any pending batched messages from the old engine.\n // Without this, stale messages from the old engine's event stream\n // could flush into the new engine's message list.\n pendingMessagesRef.current = []\n if (timerRef.current) {\n clearImmediate(timerRef.current)\n timerRef.current = null\n }\n }\n\n const flushMessages = useCallback(() => {\n if (pendingMessagesRef.current.length === 0) return\n const batch = pendingMessagesRef.current.splice(0)\n setMessagesState(prev => [...prev, ...batch])\n }, [])\n\n useEffect(() => {\n if (!engine) return () => {}\n\n // Sync initial state\n setMessagesState([...engine.messages])\n setEngineState(engine.state)\n setIsLoading(engine.state === 'querying')\n\n const handleEvent = (event: EngineEvent) => {\n switch (event.type) {\n case 'state_change':\n setEngineState(event.to)\n setIsLoading(event.to === 'querying')\n break\n\n case 'message':\n // Batch messages for efficient rendering\n pendingMessagesRef.current.push(event.message)\n if (!timerRef.current) {\n timerRef.current = setImmediate(() => {\n timerRef.current = null\n flushMessages()\n })\n }\n break\n\n case 'messages_set':\n // Full replacement \u2014 flush any pending and set directly\n pendingMessagesRef.current = []\n if (timerRef.current) {\n clearImmediate(timerRef.current)\n timerRef.current = null\n }\n setMessagesState([...event.messages])\n // Reset turn duration when conversation is cleared (empty messages)\n if (event.messages.length === 0) {\n setLastTurnDurationMs(null)\n }\n break\n\n case 'turn_start':\n setLastTurnDurationMs(null)\n break\n\n case 'turn_end':\n setLastTurnDurationMs(event.durationMs)\n // Flush any remaining batched messages\n flushMessages()\n break\n\n case 'error':\n // Flush messages so error context is visible\n flushMessages()\n break\n }\n }\n\n const unsub = engine.on(handleEvent)\n\n return () => {\n unsub()\n // Flush remaining messages on cleanup\n if (timerRef.current) {\n clearImmediate(timerRef.current)\n timerRef.current = null\n }\n flushMessages()\n }\n }, [engine, flushMessages])\n\n // \u2500\u2500 Stable callbacks that delegate to the current engine \u2500\u2500\n\n const submitPrompt = useCallback(async (input: string | Message[]) => {\n await engineRef.current?.submitPrompt(input)\n }, [])\n\n const abort = useCallback(() => {\n engineRef.current?.abort()\n }, [])\n\n const setMessages = useCallback((msgs: Message[]) => {\n engineRef.current?.setMessages(msgs)\n }, [])\n\n const appendMessages = useCallback((msgs: Message[]) => {\n engineRef.current?.appendMessages(msgs)\n }, [])\n\n return useMemo(\n () => ({\n messages,\n isLoading,\n engineState,\n lastTurnDurationMs,\n submitPrompt,\n abort,\n setMessages,\n appendMessages,\n }),\n [\n messages,\n isLoading,\n engineState,\n lastTurnDurationMs,\n submitPrompt,\n abort,\n setMessages,\n appendMessages,\n ],\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -48,23 +48,7 @@ function useAllAgentTokenStats() {
|
|
|
48
48
|
}, []);
|
|
49
49
|
return stats;
|
|
50
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
51
|
export {
|
|
66
|
-
formatTokenCount,
|
|
67
|
-
getTokenSummary,
|
|
68
52
|
useAgentTokenStats,
|
|
69
53
|
useAllAgentTokenStats,
|
|
70
54
|
useGlobalTokenStats
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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 undefined\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
|
|
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,aAAO;AAAA,IACT;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;
|
|
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 undefined\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"],
|
|
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,aAAO;AAAA,IACT;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;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -2,10 +2,19 @@ import { useCallback } from "react";
|
|
|
2
2
|
import { hasPermissionsToUseTool } from "../permissions.js";
|
|
3
3
|
import { BashTool, inputSchema } from "../tools/BashTool/BashTool.js";
|
|
4
4
|
import { getCommandSubcommandPrefix } from "../utils/commands.js";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
REJECT_MESSAGE,
|
|
7
|
+
PLAN_REJECT_WITH_FEEDBACK_PREFIX
|
|
8
|
+
} from "../utils/messages.js";
|
|
6
9
|
import { getToolDescriptionAsync } from "../Tool.js";
|
|
7
10
|
import { AbortError } from "../utils/errors.js";
|
|
8
11
|
import { logError } from "../utils/log.js";
|
|
12
|
+
import { ExitPlanModeTool } from "../tools/PlanModeTool/ExitPlanModeTool.js";
|
|
13
|
+
import { readPlanFile, getPlanConversationKey } from "../utils/plan/planMode.js";
|
|
14
|
+
import {
|
|
15
|
+
getCurrentProjectConfig,
|
|
16
|
+
saveCurrentProjectConfig
|
|
17
|
+
} from "../utils/config.js";
|
|
9
18
|
function useCanUseTool(setToolUseConfirm) {
|
|
10
19
|
return useCallback(
|
|
11
20
|
async (tool, input, toolUseContext, assistantMessage) => {
|
|
@@ -48,11 +57,21 @@ function useCanUseTool(setToolUseConfirm) {
|
|
|
48
57
|
resolveWithCancelledAndAbortAllToolCalls();
|
|
49
58
|
return;
|
|
50
59
|
}
|
|
60
|
+
let enrichedInput = input;
|
|
61
|
+
if (tool === ExitPlanModeTool) {
|
|
62
|
+
try {
|
|
63
|
+
const conversationKey = getPlanConversationKey(toolUseContext);
|
|
64
|
+
const { content } = readPlanFile(void 0, conversationKey);
|
|
65
|
+
enrichedInput = { ...input, planContent: content || "" };
|
|
66
|
+
} catch {
|
|
67
|
+
enrichedInput = { ...input, planContent: "" };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
51
70
|
setToolUseConfirm({
|
|
52
71
|
assistantMessage,
|
|
53
72
|
tool,
|
|
54
73
|
description,
|
|
55
|
-
input,
|
|
74
|
+
input: enrichedInput,
|
|
56
75
|
commandPrefix,
|
|
57
76
|
riskScore: null,
|
|
58
77
|
onAbort() {
|
|
@@ -65,8 +84,34 @@ function useCanUseTool(setToolUseConfirm) {
|
|
|
65
84
|
}
|
|
66
85
|
resolve({ result: true });
|
|
67
86
|
},
|
|
87
|
+
onAllowWithPrompts(patterns) {
|
|
88
|
+
try {
|
|
89
|
+
const projectConfig = getCurrentProjectConfig();
|
|
90
|
+
const allowedTools = projectConfig.allowedTools ?? [];
|
|
91
|
+
for (const pattern of patterns) {
|
|
92
|
+
const key = `Bash(${pattern}:*)`;
|
|
93
|
+
if (!allowedTools.includes(key)) {
|
|
94
|
+
allowedTools.push(key);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
allowedTools.sort();
|
|
98
|
+
projectConfig.allowedTools = allowedTools;
|
|
99
|
+
saveCurrentProjectConfig(projectConfig);
|
|
100
|
+
} catch (err) {
|
|
101
|
+
logError(`Failed to save permitted command patterns: ${err}`);
|
|
102
|
+
}
|
|
103
|
+
resolve({ result: true });
|
|
104
|
+
},
|
|
68
105
|
onReject() {
|
|
69
106
|
resolveWithCancelledAndAbortAllToolCalls();
|
|
107
|
+
},
|
|
108
|
+
onRejectWithFeedback(feedback) {
|
|
109
|
+
resolve({
|
|
110
|
+
result: false,
|
|
111
|
+
message: `${PLAN_REJECT_WITH_FEEDBACK_PREFIX}${feedback}
|
|
112
|
+
|
|
113
|
+
Please revise your plan based on this feedback and call ExitPlanMode again when ready.`
|
|
114
|
+
});
|
|
70
115
|
}
|
|
71
116
|
});
|
|
72
117
|
}).catch((error) => {
|
|
@@ -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 {
|
|
5
|
-
"mappings": "AAAA,SAAgB,mBAAmB;AACnC,SAAS,+BAA+B;AACxC,SAAS,UAAU,mBAAmB;AACtC,SAAS,kCAAkC;AAC3C,
|
|
4
|
+
"sourcesContent": ["import React, { useCallback } from 'react'\nimport { hasPermissionsToUseTool } from '@permissions'\nimport { BashTool, inputSchema } from '@tools/BashTool/BashTool'\nimport { getCommandSubcommandPrefix } from '@utils/commands'\nimport {\n REJECT_MESSAGE,\n PLAN_REJECT_WITH_FEEDBACK_PREFIX,\n} 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'\nimport { ExitPlanModeTool } from '@tools/PlanModeTool/ExitPlanModeTool'\nimport { readPlanFile, getPlanConversationKey } from '@utils/plan/planMode'\nimport {\n getCurrentProjectConfig,\n saveCurrentProjectConfig,\n} from '@utils/config'\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 undefined\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 // Pre-read plan content for ExitPlanModeTool approval UI\n let enrichedInput = input\n if (tool === ExitPlanModeTool) {\n try {\n const conversationKey = getPlanConversationKey(toolUseContext)\n const { content } = readPlanFile(undefined, conversationKey)\n enrichedInput = { ...input, planContent: content || '' }\n } catch {\n enrichedInput = { ...input, planContent: '' }\n }\n }\n\n // Does not have permissions to use tool, ask the user\n setToolUseConfirm({\n assistantMessage,\n tool,\n description,\n input: enrichedInput,\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 onAllowWithPrompts(patterns: string[]) {\n // Convert user-provided command patterns to Bash permission keys\n // and save them to the project config's allowedTools\n try {\n const projectConfig = getCurrentProjectConfig()\n const allowedTools = projectConfig.allowedTools ?? []\n for (const pattern of patterns) {\n // Use prefix-match format: Bash(pattern:*) so any command\n // starting with the pattern will be auto-approved\n const key = `Bash(${pattern}:*)`\n if (!allowedTools.includes(key)) {\n allowedTools.push(key)\n }\n }\n allowedTools.sort()\n projectConfig.allowedTools = allowedTools\n saveCurrentProjectConfig(projectConfig)\n } catch (err) {\n logError(`Failed to save permitted command patterns: ${err}`)\n }\n resolve({ result: true })\n },\n onReject() {\n resolveWithCancelledAndAbortAllToolCalls()\n },\n onRejectWithFeedback(feedback: string) {\n // Resolve with feedback message but do NOT abort the controller.\n // This allows the assistant to receive the feedback and continue\n // revising the plan while plan mode stays enabled.\n resolve({\n result: false,\n message: `${PLAN_REJECT_WITH_FEEDBACK_PREFIX}${feedback}\\n\\nPlease revise your plan based on this feedback and call ExitPlanMode again when ready.`,\n })\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": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -2,7 +2,10 @@ import { useEffect, useState } from "react";
|
|
|
2
2
|
import { getClients } from "../services/mcpClient.js";
|
|
3
3
|
import { getTools } from "../tools.js";
|
|
4
4
|
import { getCommands } from "../commands.js";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
getLatestVersion,
|
|
7
|
+
getUpdateCommandSuggestions
|
|
8
|
+
} from "../utils/autoUpdater.js";
|
|
6
9
|
import { gt } from "semver";
|
|
7
10
|
import { MACRO } from "../constants/macros.js";
|
|
8
11
|
import { useStartupStatus } from "../components/StartupStatus.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/hooks/useDeferredLoading.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Deferred loading of MCP clients, tools, commands, and version check.\n * Runs in background after mount so the REPL renders immediately.\n */\nimport { useEffect, useState } from 'react'\nimport type { Command } from '@commands'\nimport type { Tool } from '@tool'\nimport type { WrappedClient } from '@services/mcpClient'\nimport { getClients } from '@services/mcpClient'\nimport { getTools } from '@tools'\nimport { getCommands } from '@commands'\nimport {
|
|
5
|
-
"mappings": "AAIA,SAAS,WAAW,gBAAgB;AAIpC,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;AAC5B,
|
|
4
|
+
"sourcesContent": ["/**\n * Deferred loading of MCP clients, tools, commands, and version check.\n * Runs in background after mount so the REPL renders immediately.\n */\nimport { useEffect, useState } from 'react'\nimport type { Command } from '@commands'\nimport type { Tool } from '@tool'\nimport type { WrappedClient } from '@services/mcpClient'\nimport { getClients } from '@services/mcpClient'\nimport { getTools } from '@tools'\nimport { getCommands } from '@commands'\nimport {\n getLatestVersion,\n getUpdateCommandSuggestions,\n} from '@utils/autoUpdater'\nimport { gt } from 'semver'\nimport { MACRO } from '@constants/macros'\nimport { useStartupStatus } from '@components/StartupStatus'\n\ninterface DeferredLoadingOptions {\n initialCommands: Command[]\n initialTools: Tool[]\n initialMcpClients: WrappedClient[]\n initialUpdateVersion?: string | null\n initialUpdateCommands?: string[] | null\n enableArchitect?: boolean\n}\n\nexport function useDeferredLoading(options: DeferredLoadingOptions) {\n const [commands, setCommands] = useState<Command[]>(options.initialCommands)\n const [tools, setTools] = useState<Tool[]>(options.initialTools)\n const [mcpClients, setMcpClients] = useState<WrappedClient[]>(\n options.initialMcpClients,\n )\n const [updateVersion, setUpdateVersion] = useState<string | null>(\n options.initialUpdateVersion ?? null,\n )\n const [updateCommands, setUpdateCommands] = useState<string[] | null>(\n options.initialUpdateCommands ?? null,\n )\n\n const { items: startupItems, update: updateStartup } = useStartupStatus([\n { id: 'mcp', label: 'MCP servers' },\n { id: 'version', label: 'Version check' },\n ])\n\n useEffect(() => {\n // 1. MCP clients + full tools (including MCP tools)\n Promise.all([getClients(), getTools(options.enableArchitect)])\n .then(([clients, fullTools]) => {\n setMcpClients(clients)\n setTools(fullTools)\n const connected = clients.filter(c => c.type === 'connected').length\n updateStartup('mcp', 'done', `${connected}/${clients.length} connected`)\n })\n .catch(() => {\n updateStartup('mcp', 'error', 'connection failed')\n })\n\n // 2. Version check\n getLatestVersion()\n .then(latest => {\n if (latest && gt(latest, MACRO.VERSION)) {\n getUpdateCommandSuggestions().then(cmds => {\n setUpdateVersion(latest)\n setUpdateCommands(cmds)\n updateStartup('version', 'done', `v${latest} available`)\n })\n } else {\n updateStartup('version', 'done', 'up to date')\n }\n })\n .catch(() => {\n updateStartup('version', 'done') // non-critical, just hide\n })\n\n // 3. Full commands (MCP, custom, plugin)\n getCommands()\n .then(fullCommands => {\n setCommands(fullCommands)\n })\n .catch(() => {\n // Non-critical: built-in commands still work\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n return {\n commands,\n tools,\n mcpClients,\n updateVersion,\n updateCommands,\n startupItems,\n }\n}\n"],
|
|
5
|
+
"mappings": "AAIA,SAAS,WAAW,gBAAgB;AAIpC,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,UAAU;AACnB,SAAS,aAAa;AACtB,SAAS,wBAAwB;AAW1B,SAAS,mBAAmB,SAAiC;AAClE,QAAM,CAAC,UAAU,WAAW,IAAI,SAAoB,QAAQ,eAAe;AAC3E,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAiB,QAAQ,YAAY;AAC/D,QAAM,CAAC,YAAY,aAAa,IAAI;AAAA,IAClC,QAAQ;AAAA,EACV;AACA,QAAM,CAAC,eAAe,gBAAgB,IAAI;AAAA,IACxC,QAAQ,wBAAwB;AAAA,EAClC;AACA,QAAM,CAAC,gBAAgB,iBAAiB,IAAI;AAAA,IAC1C,QAAQ,yBAAyB;AAAA,EACnC;AAEA,QAAM,EAAE,OAAO,cAAc,QAAQ,cAAc,IAAI,iBAAiB;AAAA,IACtE,EAAE,IAAI,OAAO,OAAO,cAAc;AAAA,IAClC,EAAE,IAAI,WAAW,OAAO,gBAAgB;AAAA,EAC1C,CAAC;AAED,YAAU,MAAM;AAEd,YAAQ,IAAI,CAAC,WAAW,GAAG,SAAS,QAAQ,eAAe,CAAC,CAAC,EAC1D,KAAK,CAAC,CAAC,SAAS,SAAS,MAAM;AAC9B,oBAAc,OAAO;AACrB,eAAS,SAAS;AAClB,YAAM,YAAY,QAAQ,OAAO,OAAK,EAAE,SAAS,WAAW,EAAE;AAC9D,oBAAc,OAAO,QAAQ,GAAG,SAAS,IAAI,QAAQ,MAAM,YAAY;AAAA,IACzE,CAAC,EACA,MAAM,MAAM;AACX,oBAAc,OAAO,SAAS,mBAAmB;AAAA,IACnD,CAAC;AAGH,qBAAiB,EACd,KAAK,YAAU;AACd,UAAI,UAAU,GAAG,QAAQ,MAAM,OAAO,GAAG;AACvC,oCAA4B,EAAE,KAAK,UAAQ;AACzC,2BAAiB,MAAM;AACvB,4BAAkB,IAAI;AACtB,wBAAc,WAAW,QAAQ,IAAI,MAAM,YAAY;AAAA,QACzD,CAAC;AAAA,MACH,OAAO;AACL,sBAAc,WAAW,QAAQ,YAAY;AAAA,MAC/C;AAAA,IACF,CAAC,EACA,MAAM,MAAM;AACX,oBAAc,WAAW,MAAM;AAAA,IACjC,CAAC;AAGH,gBAAY,EACT,KAAK,kBAAgB;AACpB,kBAAY,YAAY;AAAA,IAC1B,CAAC,EACA,MAAM,MAAM;AAAA,IAEb,CAAC;AAAA,EAEL,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { useState, useEffect, useRef, useCallback } from "react";
|
|
2
|
+
import {
|
|
3
|
+
teamEvents,
|
|
4
|
+
getTeam
|
|
5
|
+
} from "../services/agentTeams/index.js";
|
|
6
|
+
const MAX_VISIBLE = 3;
|
|
7
|
+
const DISMISS_MS = 3e3;
|
|
8
|
+
function useIdleNotifications() {
|
|
9
|
+
const [notifications, setNotifications] = useState([]);
|
|
10
|
+
const timersRef = useRef(
|
|
11
|
+
/* @__PURE__ */ new Map()
|
|
12
|
+
);
|
|
13
|
+
const dismiss = useCallback((id) => {
|
|
14
|
+
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
15
|
+
const timer = timersRef.current.get(id);
|
|
16
|
+
if (timer) {
|
|
17
|
+
clearTimeout(timer);
|
|
18
|
+
timersRef.current.delete(id);
|
|
19
|
+
}
|
|
20
|
+
}, []);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
const unsub = teamEvents.onMemberStatusChange(
|
|
23
|
+
(data) => {
|
|
24
|
+
if (data.status !== "idle" || data.previousStatus === "idle") return;
|
|
25
|
+
const entry = getTeam(data.teamName);
|
|
26
|
+
const member = entry?.team.members.find((m) => m.id === data.memberId);
|
|
27
|
+
const color = member?.color ?? "gray";
|
|
28
|
+
const id = `${data.memberId}-${Date.now()}`;
|
|
29
|
+
const notification = {
|
|
30
|
+
id,
|
|
31
|
+
memberName: data.memberName,
|
|
32
|
+
color,
|
|
33
|
+
timestamp: Date.now()
|
|
34
|
+
};
|
|
35
|
+
setNotifications((prev) => {
|
|
36
|
+
const next = [...prev, notification];
|
|
37
|
+
while (next.length > MAX_VISIBLE) {
|
|
38
|
+
const oldest = next.shift();
|
|
39
|
+
const timer2 = timersRef.current.get(oldest.id);
|
|
40
|
+
if (timer2) {
|
|
41
|
+
clearTimeout(timer2);
|
|
42
|
+
timersRef.current.delete(oldest.id);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return next;
|
|
46
|
+
});
|
|
47
|
+
const timer = setTimeout(() => {
|
|
48
|
+
dismiss(id);
|
|
49
|
+
}, DISMISS_MS);
|
|
50
|
+
timersRef.current.set(id, timer);
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
return () => {
|
|
54
|
+
unsub();
|
|
55
|
+
for (const timer of timersRef.current.values()) {
|
|
56
|
+
clearTimeout(timer);
|
|
57
|
+
}
|
|
58
|
+
timersRef.current.clear();
|
|
59
|
+
};
|
|
60
|
+
}, [dismiss]);
|
|
61
|
+
return { notifications };
|
|
62
|
+
}
|
|
63
|
+
export {
|
|
64
|
+
useIdleNotifications
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=useIdleNotifications.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/useIdleNotifications.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * useIdleNotifications Hook\n *\n * Subscribes to team member status changes and surfaces brief notifications\n * when a teammate transitions to 'idle'. Notifications auto-dismiss after\n * 3 seconds. At most 3 notifications are visible at once (oldest dismissed\n * first).\n */\n\nimport { useState, useEffect, useRef, useCallback } from 'react'\nimport {\n teamEvents,\n getTeam,\n type MemberStatusChangeData,\n} from '@services/agentTeams'\n\nexport interface IdleNotification {\n id: string\n memberName: string\n color: string\n timestamp: number\n}\n\nconst MAX_VISIBLE = 3\nconst DISMISS_MS = 3000\n\nexport function useIdleNotifications(): {\n notifications: IdleNotification[]\n} {\n const [notifications, setNotifications] = useState<IdleNotification[]>([])\n // Track active timers so they can be cleaned up on unmount\n const timersRef = useRef<Map<string, ReturnType<typeof setTimeout>>>(\n new Map(),\n )\n\n const dismiss = useCallback((id: string) => {\n setNotifications(prev => prev.filter(n => n.id !== id))\n const timer = timersRef.current.get(id)\n if (timer) {\n clearTimeout(timer)\n timersRef.current.delete(id)\n }\n }, [])\n\n useEffect(() => {\n const unsub = teamEvents.onMemberStatusChange(\n (data: MemberStatusChangeData) => {\n // Only care about transitions *to* idle from a non-idle status\n if (data.status !== 'idle' || data.previousStatus === 'idle') return\n\n // Look up the teammate's color from the team registry\n const entry = getTeam(data.teamName)\n const member = entry?.team.members.find(m => m.id === data.memberId)\n const color = member?.color ?? 'gray'\n\n const id = `${data.memberId}-${Date.now()}`\n const notification: IdleNotification = {\n id,\n memberName: data.memberName,\n color,\n timestamp: Date.now(),\n }\n\n setNotifications(prev => {\n const next = [...prev, notification]\n // Enforce max visible: dismiss oldest if over limit\n while (next.length > MAX_VISIBLE) {\n const oldest = next.shift()!\n // Clean up the timer for the dismissed notification\n const timer = timersRef.current.get(oldest.id)\n if (timer) {\n clearTimeout(timer)\n timersRef.current.delete(oldest.id)\n }\n }\n return next\n })\n\n // Schedule auto-dismiss\n const timer = setTimeout(() => {\n dismiss(id)\n }, DISMISS_MS)\n timersRef.current.set(id, timer)\n },\n )\n\n return () => {\n unsub()\n // Clear all pending timers on unmount\n for (const timer of timersRef.current.values()) {\n clearTimeout(timer)\n }\n timersRef.current.clear()\n }\n }, [dismiss])\n\n return { notifications }\n}\n"],
|
|
5
|
+
"mappings": "AASA,SAAS,UAAU,WAAW,QAAQ,mBAAmB;AACzD;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AASP,MAAM,cAAc;AACpB,MAAM,aAAa;AAEZ,SAAS,uBAEd;AACA,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAA6B,CAAC,CAAC;AAEzE,QAAM,YAAY;AAAA,IAChB,oBAAI,IAAI;AAAA,EACV;AAEA,QAAM,UAAU,YAAY,CAAC,OAAe;AAC1C,qBAAiB,UAAQ,KAAK,OAAO,OAAK,EAAE,OAAO,EAAE,CAAC;AACtD,UAAM,QAAQ,UAAU,QAAQ,IAAI,EAAE;AACtC,QAAI,OAAO;AACT,mBAAa,KAAK;AAClB,gBAAU,QAAQ,OAAO,EAAE;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW;AAAA,MACvB,CAAC,SAAiC;AAEhC,YAAI,KAAK,WAAW,UAAU,KAAK,mBAAmB,OAAQ;AAG9D,cAAM,QAAQ,QAAQ,KAAK,QAAQ;AACnC,cAAM,SAAS,OAAO,KAAK,QAAQ,KAAK,OAAK,EAAE,OAAO,KAAK,QAAQ;AACnE,cAAM,QAAQ,QAAQ,SAAS;AAE/B,cAAM,KAAK,GAAG,KAAK,QAAQ,IAAI,KAAK,IAAI,CAAC;AACzC,cAAM,eAAiC;AAAA,UACrC;AAAA,UACA,YAAY,KAAK;AAAA,UACjB;AAAA,UACA,WAAW,KAAK,IAAI;AAAA,QACtB;AAEA,yBAAiB,UAAQ;AACvB,gBAAM,OAAO,CAAC,GAAG,MAAM,YAAY;AAEnC,iBAAO,KAAK,SAAS,aAAa;AAChC,kBAAM,SAAS,KAAK,MAAM;AAE1B,kBAAMA,SAAQ,UAAU,QAAQ,IAAI,OAAO,EAAE;AAC7C,gBAAIA,QAAO;AACT,2BAAaA,MAAK;AAClB,wBAAU,QAAQ,OAAO,OAAO,EAAE;AAAA,YACpC;AAAA,UACF;AACA,iBAAO;AAAA,QACT,CAAC;AAGD,cAAM,QAAQ,WAAW,MAAM;AAC7B,kBAAQ,EAAE;AAAA,QACZ,GAAG,UAAU;AACb,kBAAU,QAAQ,IAAI,IAAI,KAAK;AAAA,MACjC;AAAA,IACF;AAEA,WAAO,MAAM;AACX,YAAM;AAEN,iBAAW,SAAS,UAAU,QAAQ,OAAO,GAAG;AAC9C,qBAAa,KAAK;AAAA,MACpB;AACA,gBAAU,QAAQ,MAAM;AAAA,IAC1B;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,SAAO,EAAE,cAAc;AACzB;",
|
|
6
|
+
"names": ["timer"]
|
|
7
|
+
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { useEffect, useRef } from "react";
|
|
2
2
|
import { randomUUID } from "crypto";
|
|
3
3
|
import { debug as debugLogger } from "../utils/debugLogger.js";
|
|
4
|
-
import {
|
|
5
|
-
initializeHookManager
|
|
6
|
-
} from "../utils/hookManager.js";
|
|
4
|
+
import { initializeHookManager } from "../utils/hookManager.js";
|
|
7
5
|
import { loadAllPlugins } from "../utils/pluginLoader.js";
|
|
8
6
|
import { loadDefaultPlugins } from "../services/plugins/pluginRuntime.js";
|
|
9
7
|
import {
|
|
@@ -13,16 +11,18 @@ import {
|
|
|
13
11
|
} from "../utils/sessionTracker.js";
|
|
14
12
|
import { getOriginalCwd } from "../utils/state.js";
|
|
15
13
|
import { getMessagesPath } from "../utils/log.js";
|
|
14
|
+
import { isSimpleMode } from "../utils/simpleMode.js";
|
|
16
15
|
function useSessionTracking(messageLogName, forkNumber) {
|
|
17
16
|
const hookManagerRef = useRef(null);
|
|
18
17
|
useEffect(() => {
|
|
18
|
+
if (isSimpleMode()) return;
|
|
19
19
|
loadDefaultPlugins().catch((err) => {
|
|
20
20
|
debugLogger.error("Failed to load session plugins", { error: err });
|
|
21
21
|
});
|
|
22
22
|
}, []);
|
|
23
23
|
useEffect(() => {
|
|
24
24
|
try {
|
|
25
|
-
const plugins = loadAllPlugins();
|
|
25
|
+
const plugins = isSimpleMode() ? [] : loadAllPlugins();
|
|
26
26
|
const sessionId = randomUUID();
|
|
27
27
|
const transcriptPath = getMessagesPath(messageLogName, forkNumber, 0);
|
|
28
28
|
const hookManager = initializeHookManager(
|
|
@@ -32,9 +32,11 @@ function useSessionTracking(messageLogName, forkNumber) {
|
|
|
32
32
|
);
|
|
33
33
|
hookManagerRef.current = hookManager;
|
|
34
34
|
initSessionTracker(getOriginalCwd());
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
if (!isSimpleMode()) {
|
|
36
|
+
hookManager.executeSessionStart().catch((err) => {
|
|
37
|
+
debugLogger.error("SessionStart hooks failed", { error: err });
|
|
38
|
+
});
|
|
39
|
+
}
|
|
38
40
|
return () => {
|
|
39
41
|
flushSessionStats();
|
|
40
42
|
endSession("other");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/hooks/useSessionTracking.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Initializes session tracking, hook manager, and session plugins.\n * Handles session lifecycle (start \u2192 flush stats \u2192 end).\n */\nimport { useEffect, useRef } from 'react'\nimport { randomUUID } from 'crypto'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport {
|
|
5
|
-
"mappings": "AAIA,SAAS,WAAW,cAAc;AAClC,SAAS,kBAAkB;AAC3B,SAAS,SAAS,mBAAmB;AACrC
|
|
4
|
+
"sourcesContent": ["/**\n * Initializes session tracking, hook manager, and session plugins.\n * Handles session lifecycle (start \u2192 flush stats \u2192 end).\n */\nimport { useEffect, useRef } from 'react'\nimport { randomUUID } from 'crypto'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport { initializeHookManager, type HookManager } from '@utils/hookManager'\nimport { loadAllPlugins } from '@utils/pluginLoader'\nimport { loadDefaultPlugins } from '@services/plugins/pluginRuntime'\nimport {\n initSessionTracker,\n flushSessionStats,\n endSession,\n} from '@utils/sessionTracker'\nimport { getOriginalCwd } from '@utils/state'\nimport { getMessagesPath } from '@utils/log'\nimport { isSimpleMode } from '@utils/simpleMode'\n\nexport function useSessionTracking(messageLogName: string, forkNumber: number) {\n const hookManagerRef = useRef<HookManager | null>(null)\n\n // Initialize session plugins (skip in simple mode)\n useEffect(() => {\n if (isSimpleMode()) return\n loadDefaultPlugins().catch(err => {\n debugLogger.error('Failed to load session plugins', { error: err })\n })\n }, [])\n\n // Initialize hook manager and session tracker (hooks skipped in simple mode)\n useEffect(() => {\n try {\n const plugins = isSimpleMode() ? [] : loadAllPlugins()\n const sessionId = randomUUID()\n const transcriptPath = getMessagesPath(messageLogName, forkNumber, 0)\n\n const hookManager = initializeHookManager(\n sessionId,\n transcriptPath,\n plugins,\n )\n hookManagerRef.current = hookManager\n\n initSessionTracker(getOriginalCwd())\n\n if (!isSimpleMode()) {\n hookManager.executeSessionStart().catch(err => {\n debugLogger.error('SessionStart hooks failed', { error: err })\n })\n }\n\n return () => {\n flushSessionStats()\n endSession('other')\n\n hookManager.executeSessionEnd('other').catch(err => {\n debugLogger.error('SessionEnd hooks failed', { error: err })\n })\n }\n } catch (err) {\n debugLogger.error('Failed to initialize hook manager', { error: err })\n return undefined\n }\n }, [messageLogName, forkNumber])\n\n return { hookManagerRef }\n}\n"],
|
|
5
|
+
"mappings": "AAIA,SAAS,WAAW,cAAc;AAClC,SAAS,kBAAkB;AAC3B,SAAS,SAAS,mBAAmB;AACrC,SAAS,6BAA+C;AACxD,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAC/B,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAEtB,SAAS,mBAAmB,gBAAwB,YAAoB;AAC7E,QAAM,iBAAiB,OAA2B,IAAI;AAGtD,YAAU,MAAM;AACd,QAAI,aAAa,EAAG;AACpB,uBAAmB,EAAE,MAAM,SAAO;AAChC,kBAAY,MAAM,kCAAkC,EAAE,OAAO,IAAI,CAAC;AAAA,IACpE,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AACd,QAAI;AACF,YAAM,UAAU,aAAa,IAAI,CAAC,IAAI,eAAe;AACrD,YAAM,YAAY,WAAW;AAC7B,YAAM,iBAAiB,gBAAgB,gBAAgB,YAAY,CAAC;AAEpE,YAAM,cAAc;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,qBAAe,UAAU;AAEzB,yBAAmB,eAAe,CAAC;AAEnC,UAAI,CAAC,aAAa,GAAG;AACnB,oBAAY,oBAAoB,EAAE,MAAM,SAAO;AAC7C,sBAAY,MAAM,6BAA6B,EAAE,OAAO,IAAI,CAAC;AAAA,QAC/D,CAAC;AAAA,MACH;AAEA,aAAO,MAAM;AACX,0BAAkB;AAClB,mBAAW,OAAO;AAElB,oBAAY,kBAAkB,OAAO,EAAE,MAAM,SAAO;AAClD,sBAAY,MAAM,2BAA2B,EAAE,OAAO,IAAI,CAAC;AAAA,QAC7D,CAAC;AAAA,MACH;AAAA,IACF,SAAS,KAAK;AACZ,kBAAY,MAAM,qCAAqC,EAAE,OAAO,IAAI,CAAC;AACrE,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,gBAAgB,UAAU,CAAC;AAE/B,SAAO,EAAE,eAAe;AAC1B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
import {
|
|
3
|
+
getActiveTeams,
|
|
4
|
+
teamEvents
|
|
5
|
+
} from "../services/agentTeams/index.js";
|
|
6
|
+
function useTeamMembers() {
|
|
7
|
+
const [members, setMembers] = useState([]);
|
|
8
|
+
const [teamName, setTeamName] = useState(null);
|
|
9
|
+
const refresh = useCallback(() => {
|
|
10
|
+
const teams = getActiveTeams();
|
|
11
|
+
if (teams.length === 0) {
|
|
12
|
+
setMembers([]);
|
|
13
|
+
setTeamName(null);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const team = teams[0];
|
|
17
|
+
setTeamName(team.name);
|
|
18
|
+
setMembers(
|
|
19
|
+
team.members.map((m) => ({
|
|
20
|
+
id: m.id,
|
|
21
|
+
name: m.name,
|
|
22
|
+
agentType: m.agentType,
|
|
23
|
+
status: m.status,
|
|
24
|
+
currentTaskId: m.currentTaskId,
|
|
25
|
+
lastActivity: m.lastActivity
|
|
26
|
+
}))
|
|
27
|
+
);
|
|
28
|
+
}, []);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
refresh();
|
|
31
|
+
const unsubStatus = teamEvents.onMemberStatusChange(
|
|
32
|
+
(_data) => refresh()
|
|
33
|
+
);
|
|
34
|
+
const unsubTeam = teamEvents.onTeamChange(
|
|
35
|
+
(_data) => refresh()
|
|
36
|
+
);
|
|
37
|
+
return () => {
|
|
38
|
+
unsubStatus();
|
|
39
|
+
unsubTeam();
|
|
40
|
+
};
|
|
41
|
+
}, [refresh]);
|
|
42
|
+
return {
|
|
43
|
+
members,
|
|
44
|
+
teamName,
|
|
45
|
+
hasActiveTeam: teamName !== null
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
useTeamMembers
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=useTeamMembers.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/useTeamMembers.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * useTeamMembers Hook\n *\n * Subscribes to team events and provides team member data for the panel.\n * Event-driven updates via teamEvents (no polling).\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport {\n getActiveTeams,\n teamEvents,\n type MemberStatusChangeData,\n type TeamChangeData,\n} from '@services/agentTeams'\nimport type { Teammate } from '@minto-types/agentTeams'\n\nexport interface TeamMemberInfo {\n id: string\n name: string\n agentType: string\n status: Teammate['status']\n currentTaskId?: string\n lastActivity: number\n}\n\nexport function useTeamMembers(): {\n members: TeamMemberInfo[]\n teamName: string | null\n hasActiveTeam: boolean\n} {\n const [members, setMembers] = useState<TeamMemberInfo[]>([])\n const [teamName, setTeamName] = useState<string | null>(null)\n\n const refresh = useCallback(() => {\n const teams = getActiveTeams()\n if (teams.length === 0) {\n setMembers([])\n setTeamName(null)\n return\n }\n const team = teams[0]!\n setTeamName(team.name)\n setMembers(\n team.members.map(m => ({\n id: m.id,\n name: m.name,\n agentType: m.agentType,\n status: m.status,\n currentTaskId: m.currentTaskId,\n lastActivity: m.lastActivity,\n })),\n )\n }, [])\n\n useEffect(() => {\n refresh()\n\n const unsubStatus = teamEvents.onMemberStatusChange(\n (_data: MemberStatusChangeData) => refresh(),\n )\n const unsubTeam = teamEvents.onTeamChange((_data: TeamChangeData) =>\n refresh(),\n )\n\n return () => {\n unsubStatus()\n unsubTeam()\n }\n }, [refresh])\n\n return {\n members,\n teamName,\n hasActiveTeam: teamName !== null,\n }\n}\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,UAAU,WAAW,mBAAmB;AACjD;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAYA,SAAS,iBAId;AACA,QAAM,CAAC,SAAS,UAAU,IAAI,SAA2B,CAAC,CAAC;AAC3D,QAAM,CAAC,UAAU,WAAW,IAAI,SAAwB,IAAI;AAE5D,QAAM,UAAU,YAAY,MAAM;AAChC,UAAM,QAAQ,eAAe;AAC7B,QAAI,MAAM,WAAW,GAAG;AACtB,iBAAW,CAAC,CAAC;AACb,kBAAY,IAAI;AAChB;AAAA,IACF;AACA,UAAM,OAAO,MAAM,CAAC;AACpB,gBAAY,KAAK,IAAI;AACrB;AAAA,MACE,KAAK,QAAQ,IAAI,QAAM;AAAA,QACrB,IAAI,EAAE;AAAA,QACN,MAAM,EAAE;AAAA,QACR,WAAW,EAAE;AAAA,QACb,QAAQ,EAAE;AAAA,QACV,eAAe,EAAE;AAAA,QACjB,cAAc,EAAE;AAAA,MAClB,EAAE;AAAA,IACJ;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,YAAQ;AAER,UAAM,cAAc,WAAW;AAAA,MAC7B,CAAC,UAAkC,QAAQ;AAAA,IAC7C;AACA,UAAM,YAAY,WAAW;AAAA,MAAa,CAAC,UACzC,QAAQ;AAAA,IACV;AAEA,WAAO,MAAM;AACX,kBAAY;AACZ,gBAAU;AAAA,IACZ;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,eAAe,aAAa;AAAA,EAC9B;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|