@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
|
@@ -1,11 +1,196 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useState, useMemo } from "react";
|
|
2
2
|
import { render } from "ink";
|
|
3
|
+
import path from "path";
|
|
3
4
|
import { REPL } from "./REPL.js";
|
|
4
5
|
import { deserializeMessages } from "../utils/conversationRecovery.js";
|
|
5
|
-
import { LogSelector } from "../components/LogSelector.js";
|
|
6
6
|
import { logError, getNextAvailableLogForkNumber } from "../utils/log.js";
|
|
7
7
|
import { isDefaultSlowAndCapableModel } from "../utils/model.js";
|
|
8
8
|
import { prepareTerminalForREPL } from "../utils/terminal.js";
|
|
9
|
+
import { getCwd } from "../utils/state.js";
|
|
10
|
+
import { t } from "../i18n/index.js";
|
|
11
|
+
import {
|
|
12
|
+
TabbedListView
|
|
13
|
+
} from "../components/TabbedListView/index.js";
|
|
14
|
+
function formatRelativeTime(date) {
|
|
15
|
+
const diffMs = Date.now() - date.getTime();
|
|
16
|
+
const diffMin = Math.floor(diffMs / 6e4);
|
|
17
|
+
const diffHour = Math.floor(diffMin / 60);
|
|
18
|
+
const diffDay = Math.floor(diffHour / 24);
|
|
19
|
+
const diffWeek = Math.floor(diffDay / 7);
|
|
20
|
+
if (diffMin < 1) return "just now";
|
|
21
|
+
if (diffMin < 60) return `${diffMin} min${diffMin > 1 ? "s" : ""} ago`;
|
|
22
|
+
if (diffHour < 24) return `${diffHour} hour${diffHour > 1 ? "s" : ""} ago`;
|
|
23
|
+
if (diffDay < 7) return `${diffDay} day${diffDay > 1 ? "s" : ""} ago`;
|
|
24
|
+
if (diffWeek < 5) return `${diffWeek} week${diffWeek > 1 ? "s" : ""} ago`;
|
|
25
|
+
return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
26
|
+
}
|
|
27
|
+
function formatFileSize(bytes) {
|
|
28
|
+
if (bytes <= 0) return "";
|
|
29
|
+
if (bytes < 1024) return `${bytes} bytes`;
|
|
30
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
31
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
32
|
+
}
|
|
33
|
+
function truncate(str, maxLength) {
|
|
34
|
+
if (str.length <= maxLength) return str;
|
|
35
|
+
return str.slice(0, maxLength - 3) + "...";
|
|
36
|
+
}
|
|
37
|
+
function getMessageText(msg) {
|
|
38
|
+
if (typeof msg.message?.content === "string") return msg.message.content;
|
|
39
|
+
if (Array.isArray(msg.message?.content)) {
|
|
40
|
+
return msg.message.content.filter((c) => c.type === "text").map((c) => c.text).join("");
|
|
41
|
+
}
|
|
42
|
+
return "";
|
|
43
|
+
}
|
|
44
|
+
function wasCleared(log) {
|
|
45
|
+
for (let i = log.messages.length - 1; i >= 0; i--) {
|
|
46
|
+
const msg = log.messages[i];
|
|
47
|
+
if (msg.type === "user") {
|
|
48
|
+
return getMessageText(msg).includes(
|
|
49
|
+
"<command-name>clear</command-name>"
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
function isEmpty(log) {
|
|
56
|
+
if (log.messageCount === 0) return true;
|
|
57
|
+
return !log.messages.some((msg) => msg.type === "user");
|
|
58
|
+
}
|
|
59
|
+
function deduplicateLogForks(logs) {
|
|
60
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
61
|
+
for (const log of logs) {
|
|
62
|
+
const group = grouped.get(log.date) || [];
|
|
63
|
+
group.push(log);
|
|
64
|
+
grouped.set(log.date, group);
|
|
65
|
+
}
|
|
66
|
+
const deduped = [];
|
|
67
|
+
for (const [, group] of grouped) {
|
|
68
|
+
const best = group.sort((a, b) => {
|
|
69
|
+
const forkDiff = (b.forkNumber ?? 0) - (a.forkNumber ?? 0);
|
|
70
|
+
if (forkDiff !== 0) return forkDiff;
|
|
71
|
+
return b.modified.getTime() - a.modified.getTime();
|
|
72
|
+
})[0];
|
|
73
|
+
if (best) deduped.push(best);
|
|
74
|
+
}
|
|
75
|
+
return deduped.sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
76
|
+
}
|
|
77
|
+
function extractPromptText(msg) {
|
|
78
|
+
const content = getMessageText(msg);
|
|
79
|
+
const trimmed = content.trim();
|
|
80
|
+
if (!trimmed) return null;
|
|
81
|
+
if (trimmed.startsWith("<system-reminder>")) return null;
|
|
82
|
+
if (trimmed.match(/<command-name>[^<]+<\/command-name>/)) return null;
|
|
83
|
+
if (trimmed.startsWith("<") && trimmed.includes("</")) return null;
|
|
84
|
+
const firstLine = trimmed.split("\n")[0]?.trim() || "";
|
|
85
|
+
return firstLine || null;
|
|
86
|
+
}
|
|
87
|
+
function extractLastUserPrompt(log) {
|
|
88
|
+
for (let i = log.messages.length - 1; i >= 0; i--) {
|
|
89
|
+
const msg = log.messages[i];
|
|
90
|
+
if (msg.type !== "user") continue;
|
|
91
|
+
const text = extractPromptText(msg);
|
|
92
|
+
if (text) return text;
|
|
93
|
+
}
|
|
94
|
+
return "(session)";
|
|
95
|
+
}
|
|
96
|
+
function getLogProjectPath(log) {
|
|
97
|
+
return log.messages[0]?.cwd || null;
|
|
98
|
+
}
|
|
99
|
+
function prepareSessionLogs(rawLogs) {
|
|
100
|
+
return deduplicateLogForks(
|
|
101
|
+
rawLogs.filter((log) => !isEmpty(log) && !wasCleared(log))
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
function logToListItem(log) {
|
|
105
|
+
const projectPath = getLogProjectPath(log) || "";
|
|
106
|
+
const projectName = projectPath ? path.basename(projectPath) : "";
|
|
107
|
+
const firstPrompt = extractLastUserPrompt(log);
|
|
108
|
+
const relativeTime = formatRelativeTime(log.modified);
|
|
109
|
+
const fileSize = formatFileSize(log.fileSize ?? 0);
|
|
110
|
+
const descParts = [relativeTime];
|
|
111
|
+
if (projectName) descParts.push(truncate(projectName, 20));
|
|
112
|
+
if (fileSize) descParts.push(fileSize);
|
|
113
|
+
return {
|
|
114
|
+
id: log.fullPath,
|
|
115
|
+
label: truncate(firstPrompt, 60),
|
|
116
|
+
description: descParts.join(" \xB7 "),
|
|
117
|
+
category: projectName || "Unknown",
|
|
118
|
+
data: log
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function SessionPicker({
|
|
122
|
+
logs,
|
|
123
|
+
onSelect,
|
|
124
|
+
onClose
|
|
125
|
+
}) {
|
|
126
|
+
const [activeTab, setActiveTab] = useState("recent");
|
|
127
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
128
|
+
const cwd = getCwd();
|
|
129
|
+
const validLogs = useMemo(() => prepareSessionLogs(logs), [logs]);
|
|
130
|
+
const recentLogs = useMemo(() => validLogs.slice(0, 20), [validLogs]);
|
|
131
|
+
const projectLogs = useMemo(
|
|
132
|
+
() => validLogs.filter((log) => getLogProjectPath(log) === cwd),
|
|
133
|
+
[validLogs, cwd]
|
|
134
|
+
);
|
|
135
|
+
const allLogs = useMemo(() => validLogs.slice(0, 100), [validLogs]);
|
|
136
|
+
const tabs = useMemo(
|
|
137
|
+
() => [
|
|
138
|
+
{
|
|
139
|
+
id: "recent",
|
|
140
|
+
label: t("commands.sessions.title"),
|
|
141
|
+
badge: recentLogs.length
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
id: "project",
|
|
145
|
+
label: t("commands.sessions.headerProject"),
|
|
146
|
+
badge: projectLogs.length
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: "all",
|
|
150
|
+
label: t("common.all"),
|
|
151
|
+
badge: allLogs.length
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
[recentLogs.length, projectLogs.length, allLogs.length]
|
|
155
|
+
);
|
|
156
|
+
const items = useMemo(() => {
|
|
157
|
+
let source;
|
|
158
|
+
switch (activeTab) {
|
|
159
|
+
case "project":
|
|
160
|
+
source = projectLogs;
|
|
161
|
+
break;
|
|
162
|
+
case "all":
|
|
163
|
+
source = allLogs;
|
|
164
|
+
break;
|
|
165
|
+
default:
|
|
166
|
+
source = recentLogs;
|
|
167
|
+
}
|
|
168
|
+
return source.map(logToListItem);
|
|
169
|
+
}, [activeTab, recentLogs, projectLogs, allLogs]);
|
|
170
|
+
const handleSelect = (item) => {
|
|
171
|
+
const log = item.data;
|
|
172
|
+
onSelect(log);
|
|
173
|
+
};
|
|
174
|
+
return /* @__PURE__ */ React.createElement(
|
|
175
|
+
TabbedListView,
|
|
176
|
+
{
|
|
177
|
+
title: t("commands.resume.title"),
|
|
178
|
+
tabs,
|
|
179
|
+
activeTab,
|
|
180
|
+
onTabChange: setActiveTab,
|
|
181
|
+
items,
|
|
182
|
+
searchEnabled: true,
|
|
183
|
+
searchPlaceholder: t("ui.tabbedList.search"),
|
|
184
|
+
searchQuery,
|
|
185
|
+
onSearchChange: setSearchQuery,
|
|
186
|
+
onSelect: handleSelect,
|
|
187
|
+
onClose,
|
|
188
|
+
emptyText: t("commands.resume.noSessions"),
|
|
189
|
+
footerHint: t("commands.resume.navigationHint"),
|
|
190
|
+
groupByCategory: activeTab === "all"
|
|
191
|
+
}
|
|
192
|
+
);
|
|
193
|
+
}
|
|
9
194
|
function ResumeConversation({
|
|
10
195
|
context,
|
|
11
196
|
commands,
|
|
@@ -13,14 +198,10 @@ function ResumeConversation({
|
|
|
13
198
|
tools,
|
|
14
199
|
verbose
|
|
15
200
|
}) {
|
|
16
|
-
async
|
|
17
|
-
const log = logs[index];
|
|
18
|
-
if (!log) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
201
|
+
const handleSelect = async (log) => {
|
|
21
202
|
try {
|
|
22
|
-
context.unmount?.();
|
|
23
203
|
const isDefaultModel = await isDefaultSlowAndCapableModel();
|
|
204
|
+
context.unmount?.();
|
|
24
205
|
await prepareTerminalForREPL();
|
|
25
206
|
render(
|
|
26
207
|
/* @__PURE__ */ React.createElement(
|
|
@@ -42,18 +223,22 @@ function ResumeConversation({
|
|
|
42
223
|
isResumedConversation: true
|
|
43
224
|
}
|
|
44
225
|
),
|
|
45
|
-
{
|
|
46
|
-
exitOnCtrlC: false
|
|
47
|
-
}
|
|
226
|
+
{ exitOnCtrlC: false }
|
|
48
227
|
);
|
|
49
228
|
} catch (e) {
|
|
50
229
|
logError(`Failed to load conversation: ${e}`);
|
|
51
230
|
throw e;
|
|
52
231
|
}
|
|
53
|
-
}
|
|
54
|
-
|
|
232
|
+
};
|
|
233
|
+
const handleClose = () => {
|
|
234
|
+
context.unmount?.();
|
|
235
|
+
process.exit(0);
|
|
236
|
+
};
|
|
237
|
+
return /* @__PURE__ */ React.createElement(SessionPicker, { logs, onSelect: handleSelect, onClose: handleClose });
|
|
55
238
|
}
|
|
56
239
|
export {
|
|
57
|
-
ResumeConversation
|
|
240
|
+
ResumeConversation,
|
|
241
|
+
SessionPicker,
|
|
242
|
+
prepareSessionLogs
|
|
58
243
|
};
|
|
59
244
|
//# sourceMappingURL=ResumeConversation.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/screens/ResumeConversation.tsx"],
|
|
4
|
-
"sourcesContent": ["import React from 'react'\nimport { render } from 'ink'\nimport { REPL } from './REPL'\nimport { deserializeMessages } from '@utils/conversationRecovery'\nimport { LogSelector } from '@components/LogSelector'\nimport type { LogOption } from '@minto-types/logs'\nimport { logError, getNextAvailableLogForkNumber } from '@utils/log'\nimport type { Tool } from '@tool'\nimport { Command } from '@commands'\nimport { isDefaultSlowAndCapableModel } from '@utils/model'\nimport { prepareTerminalForREPL } from '@utils/terminal'\n\ntype Props = {\n commands: Command[]\n context: { unmount?: () => void }\n logs: LogOption[]\n tools: Tool[]\n verbose: boolean | undefined\n}\n\nexport function ResumeConversation({\n context,\n commands,\n logs,\n tools,\n verbose,\n}: Props): React.ReactNode {\n async function onSelect(index: number) {\n const log = logs[index]\n if (!log) {\n return\n }\n\n // Load and deserialize the messages\n try {\n context.unmount?.()\n // Start a new REPL with the loaded messages\n // Increment the fork number by 1 to generate a new transcript\n // Check if using default model before rendering\n const isDefaultModel = await isDefaultSlowAndCapableModel()\n\n // Clear screen and prepare terminal for REPL\n await prepareTerminalForREPL()\n\n render(\n <REPL\n messageLogName={log.date}\n initialPrompt=\"\"\n shouldShowPromptInput={true}\n verbose={verbose}\n commands={commands}\n tools={tools}\n initialMessages={deserializeMessages(log.messages, tools)}\n initialForkNumber={getNextAvailableLogForkNumber(\n log.date,\n log.forkNumber ?? 1,\n 0,\n )}\n isDefaultModel={isDefaultModel}\n isResumedConversation={true}\n />,\n {\n exitOnCtrlC: false,\n },\n )\n } catch (e) {\n logError(`Failed to load conversation: ${e}`)\n throw e\n }\n }\n\n return <LogSelector logs={logs} onSelect={onSelect} />\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/**\n * ResumeConversation Screen & SessionPicker\n *\n * Single source of truth for session resume UI.\n * Used by both `minto --resume` (CLI) and `/resume` (REPL command).\n *\n * Display format:\n * Line 1: Last user prompt (skipping commands, falls back to first prompt)\n * Line 2: \"7 hours ago \u00B7 projectName \u00B7 61KB\"\n */\n\nimport React, { useState, useMemo } from 'react'\nimport { render } from 'ink'\nimport path from 'path'\nimport { REPL } from './REPL'\nimport { deserializeMessages } from '@utils/conversationRecovery'\nimport type { LogOption } from '@minto-types/logs'\nimport { logError, getNextAvailableLogForkNumber } from '@utils/log'\nimport type { Tool } from '@tool'\nimport type { Command } from '@commands'\nimport { isDefaultSlowAndCapableModel } from '@utils/model'\nimport { prepareTerminalForREPL } from '@utils/terminal'\nimport { getCwd } from '@utils/state'\nimport { t } from '@i18n'\nimport {\n TabbedListView,\n type ListItem,\n type TabDefinition,\n} from '@components/TabbedListView'\n\n// \u2500\u2500 Formatting helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Format relative time (CC-style: \"7 hours ago\", \"2 days ago\") */\nfunction formatRelativeTime(date: Date): string {\n const diffMs = Date.now() - date.getTime()\n const diffMin = Math.floor(diffMs / 60_000)\n const diffHour = Math.floor(diffMin / 60)\n const diffDay = Math.floor(diffHour / 24)\n const diffWeek = Math.floor(diffDay / 7)\n\n if (diffMin < 1) return 'just now'\n if (diffMin < 60) return `${diffMin} min${diffMin > 1 ? 's' : ''} ago`\n if (diffHour < 24) return `${diffHour} hour${diffHour > 1 ? 's' : ''} ago`\n if (diffDay < 7) return `${diffDay} day${diffDay > 1 ? 's' : ''} ago`\n if (diffWeek < 5) return `${diffWeek} week${diffWeek > 1 ? 's' : ''} ago`\n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })\n}\n\n/** Format file size (CC-style: \"61KB\", \"1.2MB\") */\nfunction formatFileSize(bytes: number): string {\n if (bytes <= 0) return ''\n if (bytes < 1024) return `${bytes} bytes`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`\n}\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str\n return str.slice(0, maxLength - 3) + '...'\n}\n\n// \u2500\u2500 Log message text extraction \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Extract text content from a serialized message */\nfunction getMessageText(msg: { message?: { content: any } }): string {\n if (typeof msg.message?.content === 'string') return msg.message.content\n if (Array.isArray(msg.message?.content)) {\n return msg.message.content\n .filter((c: any) => c.type === 'text')\n .map((c: any) => c.text)\n .join('')\n }\n return ''\n}\n\n// \u2500\u2500 Log filtering helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Check if conversation ended with /clear */\nfunction wasCleared(log: LogOption): boolean {\n for (let i = log.messages.length - 1; i >= 0; i--) {\n const msg = log.messages[i]\n if (msg.type === 'user') {\n return getMessageText(msg).includes(\n '<command-name>clear</command-name>',\n )\n }\n }\n return false\n}\n\n/** Check if conversation is empty (no real user content) */\nfunction isEmpty(log: LogOption): boolean {\n if (log.messageCount === 0) return true\n // A session is empty if it has no user messages at all\n return !log.messages.some(msg => msg.type === 'user')\n}\n\n/** Deduplicate logs: keep only the latest fork per base conversation */\nfunction deduplicateLogForks(logs: LogOption[]): LogOption[] {\n const grouped = new Map<string, LogOption[]>()\n for (const log of logs) {\n const group = grouped.get(log.date) || []\n group.push(log)\n grouped.set(log.date, group)\n }\n\n const deduped: LogOption[] = []\n for (const [, group] of grouped) {\n const best = group.sort((a, b) => {\n const forkDiff = (b.forkNumber ?? 0) - (a.forkNumber ?? 0)\n if (forkDiff !== 0) return forkDiff\n return b.modified.getTime() - a.modified.getTime()\n })[0]\n if (best) deduped.push(best)\n }\n\n return deduped.sort((a, b) => b.modified.getTime() - a.modified.getTime())\n}\n\n/**\n * Check if a user message is a plain text prompt (not a command or system XML).\n * Returns the first line of text if it's a real prompt, null otherwise.\n */\nfunction extractPromptText(msg: { type: string; message?: { content: any } }): string | null {\n const content = getMessageText(msg)\n const trimmed = content.trim()\n if (!trimmed) return null\n\n // Skip pure system-reminder messages\n if (trimmed.startsWith('<system-reminder>')) return null\n\n // Commands are not user prompts\n if (trimmed.match(/<command-name>[^<]+<\\/command-name>/)) return null\n\n // Skip other XML-only messages (e.g. <local-command-stdout>)\n if (trimmed.startsWith('<') && trimmed.includes('</')) return null\n\n const firstLine = trimmed.split('\\n')[0]?.trim() || ''\n return firstLine || null\n}\n\n/**\n * Extract the last user prompt from log (most recent actual prompt text).\n * Skips commands (/clear, /model, etc.) and system XML messages.\n * Falls back to the first user prompt if no later prompt is found.\n */\nfunction extractLastUserPrompt(log: LogOption): string {\n // Walk backwards to find the last real user prompt\n for (let i = log.messages.length - 1; i >= 0; i--) {\n const msg = log.messages[i]\n if (msg.type !== 'user') continue\n\n const text = extractPromptText(msg)\n if (text) return text\n }\n return '(session)'\n}\n\nfunction getLogProjectPath(log: LogOption): string | null {\n return log.messages[0]?.cwd || null\n}\n\n// \u2500\u2500 Shared log preparation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Prepare logs for the session picker: filter empty/cleared, deduplicate forks.\n * Exported for reuse by the /resume command.\n */\nexport function prepareSessionLogs(rawLogs: LogOption[]): LogOption[] {\n return deduplicateLogForks(\n rawLogs.filter(log => !isEmpty(log) && !wasCleared(log)),\n )\n}\n\n// \u2500\u2500 List item conversion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Convert LogOption to CC-style ListItem:\n * label: first user prompt (or /command)\n * description: \"7 hours ago \u00B7 projectName \u00B7 61KB\"\n */\nfunction logToListItem(log: LogOption): ListItem {\n const projectPath = getLogProjectPath(log) || ''\n const projectName = projectPath ? path.basename(projectPath) : ''\n const firstPrompt = extractLastUserPrompt(log)\n const relativeTime = formatRelativeTime(log.modified)\n const fileSize = formatFileSize(log.fileSize ?? 0)\n\n const descParts = [relativeTime]\n if (projectName) descParts.push(truncate(projectName, 20))\n if (fileSize) descParts.push(fileSize)\n\n return {\n id: log.fullPath,\n label: truncate(firstPrompt, 60),\n description: descParts.join(' \u00B7 '),\n category: projectName || 'Unknown',\n data: log,\n }\n}\n\n// \u2500\u2500 SessionPicker component (shared) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface SessionPickerProps {\n /** Raw log list (will be filtered & deduped internally) */\n logs: LogOption[]\n /** Called when user selects a session */\n onSelect: (log: LogOption) => void\n /** Called when user presses Esc */\n onClose: () => void\n}\n\n/**\n * Reusable session picker with TabbedListView.\n * Used by both `minto --resume` (CLI) and `/resume` (REPL command).\n */\nexport function SessionPicker({\n logs,\n onSelect,\n onClose,\n}: SessionPickerProps) {\n const [activeTab, setActiveTab] = useState('recent')\n const [searchQuery, setSearchQuery] = useState('')\n const cwd = getCwd()\n\n const validLogs = useMemo(() => prepareSessionLogs(logs), [logs])\n\n const recentLogs = useMemo(() => validLogs.slice(0, 20), [validLogs])\n\n const projectLogs = useMemo(\n () => validLogs.filter(log => getLogProjectPath(log) === cwd),\n [validLogs, cwd],\n )\n\n const allLogs = useMemo(() => validLogs.slice(0, 100), [validLogs])\n\n const tabs: TabDefinition[] = useMemo(\n () => [\n {\n id: 'recent',\n label: t('commands.sessions.title'),\n badge: recentLogs.length,\n },\n {\n id: 'project',\n label: t('commands.sessions.headerProject'),\n badge: projectLogs.length,\n },\n {\n id: 'all',\n label: t('common.all'),\n badge: allLogs.length,\n },\n ],\n [recentLogs.length, projectLogs.length, allLogs.length],\n )\n\n const items: ListItem[] = useMemo(() => {\n let source: LogOption[]\n switch (activeTab) {\n case 'project':\n source = projectLogs\n break\n case 'all':\n source = allLogs\n break\n default:\n source = recentLogs\n }\n return source.map(logToListItem)\n }, [activeTab, recentLogs, projectLogs, allLogs])\n\n const handleSelect = (item: ListItem) => {\n const log = item.data as LogOption\n onSelect(log)\n }\n\n return (\n <TabbedListView\n title={t('commands.resume.title')}\n tabs={tabs}\n activeTab={activeTab}\n onTabChange={setActiveTab}\n items={items}\n searchEnabled={true}\n searchPlaceholder={t('ui.tabbedList.search')}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n onSelect={handleSelect}\n onClose={onClose}\n emptyText={t('commands.resume.noSessions')}\n footerHint={t('commands.resume.navigationHint')}\n groupByCategory={activeTab === 'all'}\n />\n )\n}\n\n// \u2500\u2500 CLI --resume wrapper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype ResumeConversationProps = {\n commands: Command[]\n context: { unmount?: () => void }\n logs: LogOption[]\n tools: Tool[]\n verbose: boolean | undefined\n}\n\nexport function ResumeConversation({\n context,\n commands,\n logs,\n tools,\n verbose,\n}: ResumeConversationProps): React.ReactNode {\n const handleSelect = async (log: LogOption) => {\n try {\n const isDefaultModel = await isDefaultSlowAndCapableModel()\n context.unmount?.()\n await prepareTerminalForREPL()\n render(\n <REPL\n messageLogName={log.date}\n initialPrompt=\"\"\n shouldShowPromptInput={true}\n verbose={verbose}\n commands={commands}\n tools={tools}\n initialMessages={deserializeMessages(log.messages, tools)}\n initialForkNumber={getNextAvailableLogForkNumber(\n log.date,\n log.forkNumber ?? 1,\n 0,\n )}\n isDefaultModel={isDefaultModel}\n isResumedConversation={true}\n />,\n { exitOnCtrlC: false },\n )\n } catch (e) {\n logError(`Failed to load conversation: ${e}`)\n throw e\n }\n }\n\n const handleClose = () => {\n context.unmount?.()\n process.exit(0)\n }\n\n return <SessionPicker logs={logs} onSelect={handleSelect} onClose={handleClose} />\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/services/adapters/base.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n ModelCapabilities,\n UnifiedRequestParams,\n UnifiedResponse,\n} from '@minto-types/modelCapabilities'\nimport { ModelProfile } from '@utils/config'\nimport { Tool } from '@tool'\n\nexport abstract class ModelAPIAdapter {\n constructor(\n protected capabilities: ModelCapabilities,\n protected modelProfile: ModelProfile,\n ) {}\n\n // Subclasses must implement these methods\n abstract createRequest(params: UnifiedRequestParams):
|
|
4
|
+
"sourcesContent": ["import {\n ModelCapabilities,\n UnifiedRequestParams,\n UnifiedResponse,\n} from '@minto-types/modelCapabilities'\nimport { ModelProfile } from '@utils/config'\nimport { Tool } from '@tool'\n\nexport abstract class ModelAPIAdapter {\n constructor(\n protected capabilities: ModelCapabilities,\n protected modelProfile: ModelProfile,\n ) {}\n\n // Subclasses must implement these methods\n abstract createRequest(params: UnifiedRequestParams): unknown\n abstract parseResponse(response: unknown): UnifiedResponse\n abstract buildTools(tools: Tool[]): unknown[]\n\n // Shared utility methods\n protected getMaxTokensParam(): string {\n return this.capabilities.parameters.maxTokensField\n }\n\n protected getTemperature(): number {\n if (this.capabilities.parameters.temperatureMode === 'fixed_one') {\n return 1\n }\n if (this.capabilities.parameters.temperatureMode === 'restricted') {\n return Math.min(1, 0.7)\n }\n return 0.7\n }\n\n protected shouldIncludeReasoningEffort(): boolean {\n return this.capabilities.parameters.supportsReasoningEffort\n }\n\n protected shouldIncludeVerbosity(): boolean {\n return this.capabilities.parameters.supportsVerbosity\n }\n}\n"],
|
|
5
5
|
"mappings": "AAQO,MAAe,gBAAgB;AAAA,EACpC,YACY,cACA,cACV;AAFU;AACA;AAAA,EACT;AAAA;AAAA,EAQO,oBAA4B;AACpC,WAAO,KAAK,aAAa,WAAW;AAAA,EACtC;AAAA,EAEU,iBAAyB;AACjC,QAAI,KAAK,aAAa,WAAW,oBAAoB,aAAa;AAChE,aAAO;AAAA,IACT;AACA,QAAI,KAAK,aAAa,WAAW,oBAAoB,cAAc;AACjE,aAAO,KAAK,IAAI,GAAG,GAAG;AAAA,IACxB;AACA,WAAO;AAAA,EACT;AAAA,EAEU,+BAAwC;AAChD,WAAO,KAAK,aAAa,WAAW;AAAA,EACtC;AAAA,EAEU,yBAAkC;AAC1C,WAAO,KAAK,aAAa,WAAW;AAAA,EACtC;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { fork } from "child_process";
|
|
2
|
+
import { debug as debugLogger } from "../../../utils/debugLogger.js";
|
|
3
|
+
const FORCE_KILL_TIMEOUT = 5e3;
|
|
4
|
+
class HeadlessBackend {
|
|
5
|
+
mode = "headless";
|
|
6
|
+
processes = /* @__PURE__ */ new Map();
|
|
7
|
+
exitCallbacks = /* @__PURE__ */ new Map();
|
|
8
|
+
exitCodes = /* @__PURE__ */ new Map();
|
|
9
|
+
async spawn(options) {
|
|
10
|
+
const args = [
|
|
11
|
+
"--headless-agent",
|
|
12
|
+
"--team",
|
|
13
|
+
options.teamName,
|
|
14
|
+
"--agent-id",
|
|
15
|
+
options.agentId,
|
|
16
|
+
"--agent-name",
|
|
17
|
+
options.agentName,
|
|
18
|
+
"--agent-type",
|
|
19
|
+
options.agentType
|
|
20
|
+
];
|
|
21
|
+
if (options.maxTurns) args.push("--max-turns", String(options.maxTurns));
|
|
22
|
+
if (options.model) args.push("--model", options.model);
|
|
23
|
+
if (options.mode) args.push("--permission-mode", options.mode);
|
|
24
|
+
if (options.planModeRequired) args.push("--plan-mode-required");
|
|
25
|
+
if (options.color) args.push("--agent-color", options.color);
|
|
26
|
+
if (options.parentSessionId)
|
|
27
|
+
args.push("--parent-session-id", options.parentSessionId);
|
|
28
|
+
args.push("--", options.prompt);
|
|
29
|
+
const child = fork(process.argv[1], args, {
|
|
30
|
+
cwd: options.cwd,
|
|
31
|
+
stdio: ["pipe", "pipe", "pipe", "ipc"],
|
|
32
|
+
env: {
|
|
33
|
+
...process.env,
|
|
34
|
+
// Keep env vars needed for tool/service discovery in subprocesses
|
|
35
|
+
MINTO_TEAM_NAME: options.teamName,
|
|
36
|
+
MINTO_AGENT_ID: options.agentId,
|
|
37
|
+
MINTO_AGENT_TYPE: options.agentType,
|
|
38
|
+
MINTO_HEADLESS: "1"
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const handle = {
|
|
42
|
+
id: options.agentId,
|
|
43
|
+
pid: child.pid,
|
|
44
|
+
mode: "headless"
|
|
45
|
+
};
|
|
46
|
+
this.processes.set(options.agentId, child);
|
|
47
|
+
child.stderr?.on("data", (chunk) => {
|
|
48
|
+
const msg = chunk.toString().trim();
|
|
49
|
+
if (msg) {
|
|
50
|
+
debugLogger.warn("HEADLESS_AGENT_STDERR", {
|
|
51
|
+
agentId: options.agentId,
|
|
52
|
+
output: msg
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
child.on("exit", (code) => {
|
|
57
|
+
this.processes.delete(options.agentId);
|
|
58
|
+
this.exitCodes.set(options.agentId, code);
|
|
59
|
+
const cbs = this.exitCallbacks.get(options.agentId) ?? [];
|
|
60
|
+
for (const cb of cbs) {
|
|
61
|
+
try {
|
|
62
|
+
cb(code);
|
|
63
|
+
} catch {
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
this.exitCallbacks.delete(options.agentId);
|
|
67
|
+
});
|
|
68
|
+
return handle;
|
|
69
|
+
}
|
|
70
|
+
signal(handle, signal) {
|
|
71
|
+
const child = this.processes.get(handle.id);
|
|
72
|
+
if (!child?.connected) return;
|
|
73
|
+
try {
|
|
74
|
+
child.send({ type: signal });
|
|
75
|
+
} catch {
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
isAlive(handle) {
|
|
79
|
+
return this.processes.has(handle.id);
|
|
80
|
+
}
|
|
81
|
+
async kill(handle) {
|
|
82
|
+
const child = this.processes.get(handle.id);
|
|
83
|
+
if (!child) return;
|
|
84
|
+
child.kill("SIGTERM");
|
|
85
|
+
const forceKillTimer = setTimeout(() => {
|
|
86
|
+
if (this.processes.has(handle.id)) {
|
|
87
|
+
try {
|
|
88
|
+
child.kill("SIGKILL");
|
|
89
|
+
} catch {
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}, FORCE_KILL_TIMEOUT);
|
|
93
|
+
const cleanup = () => clearTimeout(forceKillTimer);
|
|
94
|
+
child.once("exit", cleanup);
|
|
95
|
+
}
|
|
96
|
+
onExit(handle, callback) {
|
|
97
|
+
const existing = this.exitCallbacks.get(handle.id) ?? [];
|
|
98
|
+
existing.push(callback);
|
|
99
|
+
this.exitCallbacks.set(handle.id, existing);
|
|
100
|
+
}
|
|
101
|
+
getExitCode(handle) {
|
|
102
|
+
return this.exitCodes.get(handle.id) ?? null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export {
|
|
106
|
+
HeadlessBackend
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=headless.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/services/agentTeams/backends/headless.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * HeadlessBackend\n *\n * Spawns teammate agents as independent child processes via fork().\n * Each agent runs in its own Node.js process, enabling true multi-core parallelism.\n *\n * Communication:\n * - IPC channel: control signals (abort, shutdown)\n * - File-based inboxes: inter-agent messaging (see mailbox.ts)\n * - stdout/stderr: piped back for progress display\n */\n\nimport { fork, type ChildProcess } from 'child_process'\nimport type { DisplayBackend, AgentHandle, SpawnOptions } from './types'\nimport { debug as debugLogger } from '@utils/debugLogger'\n\n/** Grace period before SIGKILL after SIGTERM (ms) */\nconst FORCE_KILL_TIMEOUT = 5000\n\nexport class HeadlessBackend implements DisplayBackend {\n readonly mode = 'headless'\n private processes = new Map<string, ChildProcess>()\n private exitCallbacks = new Map<string, ((code: number | null) => void)[]>()\n private exitCodes = new Map<string, number | null>()\n\n async spawn(options: SpawnOptions): Promise<AgentHandle> {\n const args = [\n '--headless-agent',\n '--team',\n options.teamName,\n '--agent-id',\n options.agentId,\n '--agent-name',\n options.agentName,\n '--agent-type',\n options.agentType,\n ]\n // Pass optional CLI args for all supported options (CC-compatible format)\n if (options.maxTurns) args.push('--max-turns', String(options.maxTurns))\n if (options.model) args.push('--model', options.model)\n if (options.mode) args.push('--permission-mode', options.mode)\n if (options.planModeRequired) args.push('--plan-mode-required')\n if (options.color) args.push('--agent-color', options.color)\n if (options.parentSessionId)\n args.push('--parent-session-id', options.parentSessionId)\n // Pass prompt as positional argument after '--' separator.\n // Commander treats everything after '--' as positional args, not options.\n args.push('--', options.prompt)\n\n // Fork a new Minto CLI process with IPC channel.\n // process.argv[1] is the path to the running CLI entry point.\n const child = fork(process.argv[1]!, args, {\n cwd: options.cwd,\n stdio: ['pipe', 'pipe', 'pipe', 'ipc'],\n env: {\n ...process.env,\n // Keep env vars needed for tool/service discovery in subprocesses\n MINTO_TEAM_NAME: options.teamName,\n MINTO_AGENT_ID: options.agentId,\n MINTO_AGENT_TYPE: options.agentType,\n MINTO_HEADLESS: '1',\n },\n })\n\n const handle: AgentHandle = {\n id: options.agentId,\n pid: child.pid,\n mode: 'headless',\n }\n\n this.processes.set(options.agentId, child)\n\n // Capture stderr for debugging child process failures\n child.stderr?.on('data', (chunk: Buffer) => {\n const msg = chunk.toString().trim()\n if (msg) {\n debugLogger.warn('HEADLESS_AGENT_STDERR', {\n agentId: options.agentId,\n output: msg,\n })\n }\n })\n\n child.on('exit', code => {\n this.processes.delete(options.agentId)\n this.exitCodes.set(options.agentId, code)\n const cbs = this.exitCallbacks.get(options.agentId) ?? []\n for (const cb of cbs) {\n try {\n cb(code)\n } catch {\n // Don't let callback errors break cleanup\n }\n }\n this.exitCallbacks.delete(options.agentId)\n })\n\n return handle\n }\n\n signal(handle: AgentHandle, signal: 'abort' | 'shutdown'): void {\n const child = this.processes.get(handle.id)\n if (!child?.connected) return\n try {\n child.send({ type: signal })\n } catch {\n // IPC channel may be closed if process is exiting\n }\n }\n\n isAlive(handle: AgentHandle): boolean {\n return this.processes.has(handle.id)\n }\n\n async kill(handle: AgentHandle): Promise<void> {\n const child = this.processes.get(handle.id)\n if (!child) return\n\n child.kill('SIGTERM')\n\n // Force kill after grace period if still alive\n const forceKillTimer = setTimeout(() => {\n if (this.processes.has(handle.id)) {\n try {\n child.kill('SIGKILL')\n } catch {\n // Process may have already exited\n }\n }\n }, FORCE_KILL_TIMEOUT)\n\n // Clean up timer if process exits before timeout\n const cleanup = () => clearTimeout(forceKillTimer)\n child.once('exit', cleanup)\n }\n\n onExit(handle: AgentHandle, callback: (code: number | null) => void): void {\n const existing = this.exitCallbacks.get(handle.id) ?? []\n existing.push(callback)\n this.exitCallbacks.set(handle.id, existing)\n }\n\n getExitCode(handle: AgentHandle): number | null {\n return this.exitCodes.get(handle.id) ?? null\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const sharedHandles = /* @__PURE__ */ new Map();
|
|
2
|
+
const sharedExitCallbacks = /* @__PURE__ */ new Map();
|
|
3
|
+
class InProcessBackend {
|
|
4
|
+
mode = "in-process";
|
|
5
|
+
get handles() {
|
|
6
|
+
return sharedHandles;
|
|
7
|
+
}
|
|
8
|
+
get exitCallbacks() {
|
|
9
|
+
return sharedExitCallbacks;
|
|
10
|
+
}
|
|
11
|
+
async spawn(options) {
|
|
12
|
+
const handle = {
|
|
13
|
+
id: options.agentId,
|
|
14
|
+
mode: "in-process",
|
|
15
|
+
// CC-compatible state defaults
|
|
16
|
+
awaitingPlanApproval: false,
|
|
17
|
+
shutdownRequested: false,
|
|
18
|
+
pendingUserMessages: [],
|
|
19
|
+
lastReportedToolCount: 0,
|
|
20
|
+
lastReportedTokenCount: 0,
|
|
21
|
+
permissionMode: options.mode || "default",
|
|
22
|
+
isIdle: false
|
|
23
|
+
};
|
|
24
|
+
this.handles.set(options.agentId, handle);
|
|
25
|
+
return handle;
|
|
26
|
+
}
|
|
27
|
+
signal(_handle, _signal) {
|
|
28
|
+
}
|
|
29
|
+
isAlive(handle) {
|
|
30
|
+
return this.handles.has(handle.id);
|
|
31
|
+
}
|
|
32
|
+
async kill(handle) {
|
|
33
|
+
this.handles.delete(handle.id);
|
|
34
|
+
const cbs = this.exitCallbacks.get(handle.id) ?? [];
|
|
35
|
+
for (const cb of cbs) {
|
|
36
|
+
try {
|
|
37
|
+
cb(0);
|
|
38
|
+
} catch {
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
this.exitCallbacks.delete(handle.id);
|
|
42
|
+
}
|
|
43
|
+
onExit(handle, callback) {
|
|
44
|
+
const existing = this.exitCallbacks.get(handle.id) ?? [];
|
|
45
|
+
existing.push(callback);
|
|
46
|
+
this.exitCallbacks.set(handle.id, existing);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Mark an in-process agent as completed (remove handle).
|
|
50
|
+
* Called by TaskTool when the query loop finishes.
|
|
51
|
+
*/
|
|
52
|
+
complete(agentId) {
|
|
53
|
+
this.handles.delete(agentId);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Update CC-compatible state fields on an agent handle.
|
|
57
|
+
* Merges the provided updates into the existing handle.
|
|
58
|
+
*/
|
|
59
|
+
updateState(agentId, updates) {
|
|
60
|
+
const handle = this.handles.get(agentId);
|
|
61
|
+
if (!handle) return;
|
|
62
|
+
Object.assign(handle, updates);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get the current state of an agent handle.
|
|
66
|
+
*/
|
|
67
|
+
getState(agentId) {
|
|
68
|
+
return this.handles.get(agentId);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function registerInProcessAgent(agentId, permissionMode) {
|
|
72
|
+
sharedHandles.set(agentId, {
|
|
73
|
+
id: agentId,
|
|
74
|
+
mode: "in-process",
|
|
75
|
+
awaitingPlanApproval: false,
|
|
76
|
+
shutdownRequested: false,
|
|
77
|
+
pendingUserMessages: [],
|
|
78
|
+
lastReportedToolCount: 0,
|
|
79
|
+
lastReportedTokenCount: 0,
|
|
80
|
+
permissionMode: permissionMode || "default",
|
|
81
|
+
isIdle: false
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function updateInProcessAgentState(agentId, updates) {
|
|
85
|
+
const handle = sharedHandles.get(agentId);
|
|
86
|
+
if (!handle) return;
|
|
87
|
+
Object.assign(handle, updates);
|
|
88
|
+
}
|
|
89
|
+
function getInProcessAgentState(agentId) {
|
|
90
|
+
return sharedHandles.get(agentId);
|
|
91
|
+
}
|
|
92
|
+
function unregisterInProcessAgent(agentId) {
|
|
93
|
+
sharedHandles.delete(agentId);
|
|
94
|
+
}
|
|
95
|
+
export {
|
|
96
|
+
InProcessBackend,
|
|
97
|
+
getInProcessAgentState,
|
|
98
|
+
registerInProcessAgent,
|
|
99
|
+
unregisterInProcessAgent,
|
|
100
|
+
updateInProcessAgentState
|
|
101
|
+
};
|
|
102
|
+
//# sourceMappingURL=inProcess.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/services/agentTeams/backends/inProcess.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * InProcessBackend\n *\n * Thin wrapper around the existing in-process agent execution.\n * The actual query loop still runs inside TaskTool \u2014 this backend\n * only tracks handles for interface consistency.\n *\n * In-process agents share the same Node.js event loop (cooperative concurrency).\n */\n\nimport type { DisplayBackend, AgentHandle, SpawnOptions } from './types'\n\n/**\n * Shared state store for in-process agent handles.\n * Module-level so all InProcessBackend instances share the same state,\n * enabling state updates from TaskTool's query loop to be inspectable\n * from any code that resolves an InProcessBackend.\n */\nconst sharedHandles = new Map<string, AgentHandle>()\nconst sharedExitCallbacks = new Map<string, ((code: number | null) => void)[]>()\n\nexport class InProcessBackend implements DisplayBackend {\n readonly mode = 'in-process'\n private get handles() {\n return sharedHandles\n }\n private get exitCallbacks() {\n return sharedExitCallbacks\n }\n\n async spawn(options: SpawnOptions): Promise<AgentHandle> {\n const handle: AgentHandle = {\n id: options.agentId,\n mode: 'in-process',\n // CC-compatible state defaults\n awaitingPlanApproval: false,\n shutdownRequested: false,\n pendingUserMessages: [],\n lastReportedToolCount: 0,\n lastReportedTokenCount: 0,\n permissionMode: options.mode || 'default',\n isIdle: false,\n }\n this.handles.set(options.agentId, handle)\n return handle\n }\n\n signal(_handle: AgentHandle, _signal: 'abort' | 'shutdown'): void {\n // In-process agents are controlled via abortController in TaskTool.\n // This is a no-op \u2014 the caller handles abort directly.\n }\n\n isAlive(handle: AgentHandle): boolean {\n return this.handles.has(handle.id)\n }\n\n async kill(handle: AgentHandle): Promise<void> {\n this.handles.delete(handle.id)\n // Fire exit callbacks with code 0 (clean shutdown)\n const cbs = this.exitCallbacks.get(handle.id) ?? []\n for (const cb of cbs) {\n try {\n cb(0)\n } catch {\n // Don't let callback errors break cleanup\n }\n }\n this.exitCallbacks.delete(handle.id)\n }\n\n onExit(handle: AgentHandle, callback: (code: number | null) => void): void {\n const existing = this.exitCallbacks.get(handle.id) ?? []\n existing.push(callback)\n this.exitCallbacks.set(handle.id, existing)\n }\n\n /**\n * Mark an in-process agent as completed (remove handle).\n * Called by TaskTool when the query loop finishes.\n */\n complete(agentId: string): void {\n this.handles.delete(agentId)\n }\n\n /**\n * Update CC-compatible state fields on an agent handle.\n * Merges the provided updates into the existing handle.\n */\n updateState(agentId: string, updates: Partial<AgentHandle>): void {\n const handle = this.handles.get(agentId)\n if (!handle) return\n Object.assign(handle, updates)\n }\n\n /**\n * Get the current state of an agent handle.\n */\n getState(agentId: string): AgentHandle | undefined {\n return this.handles.get(agentId)\n }\n}\n\n// \u2500\u2500 Module-level helpers for direct state access \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// These allow TaskTool and other callers to register and update\n// in-process agent state without needing a backend instance.\n\n/**\n * Register an in-process agent handle with CC-compatible state defaults.\n * Called by TaskTool at the start of the in-process query loop.\n */\nexport function registerInProcessAgent(\n agentId: string,\n permissionMode?: string,\n): void {\n sharedHandles.set(agentId, {\n id: agentId,\n mode: 'in-process',\n awaitingPlanApproval: false,\n shutdownRequested: false,\n pendingUserMessages: [],\n lastReportedToolCount: 0,\n lastReportedTokenCount: 0,\n permissionMode: permissionMode || 'default',\n isIdle: false,\n })\n}\n\n/**\n * Update CC-compatible state fields on a shared in-process agent handle.\n */\nexport function updateInProcessAgentState(\n agentId: string,\n updates: Partial<AgentHandle>,\n): void {\n const handle = sharedHandles.get(agentId)\n if (!handle) return\n Object.assign(handle, updates)\n}\n\n/**\n * Get the current state of a shared in-process agent handle.\n */\nexport function getInProcessAgentState(\n agentId: string,\n): AgentHandle | undefined {\n return sharedHandles.get(agentId)\n}\n\n/**\n * Remove a shared in-process agent handle (cleanup on completion).\n */\nexport function unregisterInProcessAgent(agentId: string): void {\n sharedHandles.delete(agentId)\n}\n"],
|
|
5
|
+
"mappings": "AAkBA,MAAM,gBAAgB,oBAAI,IAAyB;AACnD,MAAM,sBAAsB,oBAAI,IAA+C;AAExE,MAAM,iBAA2C;AAAA,EAC7C,OAAO;AAAA,EAChB,IAAY,UAAU;AACpB,WAAO;AAAA,EACT;AAAA,EACA,IAAY,gBAAgB;AAC1B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,SAA6C;AACvD,UAAM,SAAsB;AAAA,MAC1B,IAAI,QAAQ;AAAA,MACZ,MAAM;AAAA;AAAA,MAEN,sBAAsB;AAAA,MACtB,mBAAmB;AAAA,MACnB,qBAAqB,CAAC;AAAA,MACtB,uBAAuB;AAAA,MACvB,wBAAwB;AAAA,MACxB,gBAAgB,QAAQ,QAAQ;AAAA,MAChC,QAAQ;AAAA,IACV;AACA,SAAK,QAAQ,IAAI,QAAQ,SAAS,MAAM;AACxC,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,SAAsB,SAAqC;AAAA,EAGlE;AAAA,EAEA,QAAQ,QAA8B;AACpC,WAAO,KAAK,QAAQ,IAAI,OAAO,EAAE;AAAA,EACnC;AAAA,EAEA,MAAM,KAAK,QAAoC;AAC7C,SAAK,QAAQ,OAAO,OAAO,EAAE;AAE7B,UAAM,MAAM,KAAK,cAAc,IAAI,OAAO,EAAE,KAAK,CAAC;AAClD,eAAW,MAAM,KAAK;AACpB,UAAI;AACF,WAAG,CAAC;AAAA,MACN,QAAQ;AAAA,MAER;AAAA,IACF;AACA,SAAK,cAAc,OAAO,OAAO,EAAE;AAAA,EACrC;AAAA,EAEA,OAAO,QAAqB,UAA+C;AACzE,UAAM,WAAW,KAAK,cAAc,IAAI,OAAO,EAAE,KAAK,CAAC;AACvD,aAAS,KAAK,QAAQ;AACtB,SAAK,cAAc,IAAI,OAAO,IAAI,QAAQ;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,SAAuB;AAC9B,SAAK,QAAQ,OAAO,OAAO;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,SAAiB,SAAqC;AAChE,UAAM,SAAS,KAAK,QAAQ,IAAI,OAAO;AACvC,QAAI,CAAC,OAAQ;AACb,WAAO,OAAO,QAAQ,OAAO;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,SAA0C;AACjD,WAAO,KAAK,QAAQ,IAAI,OAAO;AAAA,EACjC;AACF;AAUO,SAAS,uBACd,SACA,gBACM;AACN,gBAAc,IAAI,SAAS;AAAA,IACzB,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,sBAAsB;AAAA,IACtB,mBAAmB;AAAA,IACnB,qBAAqB,CAAC;AAAA,IACtB,uBAAuB;AAAA,IACvB,wBAAwB;AAAA,IACxB,gBAAgB,kBAAkB;AAAA,IAClC,QAAQ;AAAA,EACV,CAAC;AACH;AAKO,SAAS,0BACd,SACA,SACM;AACN,QAAM,SAAS,cAAc,IAAI,OAAO;AACxC,MAAI,CAAC,OAAQ;AACb,SAAO,OAAO,QAAQ,OAAO;AAC/B;AAKO,SAAS,uBACd,SACyB;AACzB,SAAO,cAAc,IAAI,OAAO;AAClC;AAKO,SAAS,yBAAyB,SAAuB;AAC9D,gBAAc,OAAO,OAAO;AAC9B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TmuxBackend } from "./tmux.js";
|
|
2
|
+
import { InProcessBackend } from "./inProcess.js";
|
|
3
|
+
function resolveBackend(requestedMode) {
|
|
4
|
+
const mode = requestedMode ?? "auto";
|
|
5
|
+
if (mode === "in-process") return new InProcessBackend();
|
|
6
|
+
if (mode === "tmux") return new TmuxBackend();
|
|
7
|
+
if (mode === "auto") {
|
|
8
|
+
if (process.env.TMUX || process.env.TERM_PROGRAM === "iTerm.app") {
|
|
9
|
+
return new TmuxBackend();
|
|
10
|
+
}
|
|
11
|
+
return new InProcessBackend();
|
|
12
|
+
}
|
|
13
|
+
return new InProcessBackend();
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
resolveBackend
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/services/agentTeams/backends/resolver.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Backend Resolver\n *\n * Selects the appropriate DisplayBackend based on configuration and environment.\n *\n * Auto-detection priority:\n * 1. tmux session detected? \u2192 TmuxBackend\n * 2. in-process (default \u2014 maximum compatibility)\n */\n\nimport type { TeamDisplayMode } from '../../../types/agentTeams'\nimport type { DisplayBackend } from './types'\nimport { TmuxBackend } from './tmux'\nimport { InProcessBackend } from './inProcess'\n\n/**\n * Resolve the display backend based on the requested mode.\n *\n * @param requestedMode - Explicit mode or 'auto' for auto-detection\n * @returns The resolved DisplayBackend instance\n */\nexport function resolveBackend(\n requestedMode?: TeamDisplayMode,\n): DisplayBackend {\n const mode = requestedMode ?? 'auto'\n\n if (mode === 'in-process') return new InProcessBackend()\n if (mode === 'tmux') return new TmuxBackend()\n // Future: if (mode === 'aiter') return new AiTerBackend()\n\n // Auto: detect tmux/iTerm2 session\n if (mode === 'auto') {\n if (process.env.TMUX || process.env.TERM_PROGRAM === 'iTerm.app') {\n return new TmuxBackend()\n }\n return new InProcessBackend()\n }\n\n return new InProcessBackend()\n}\n"],
|
|
5
|
+
"mappings": "AAYA,SAAS,mBAAmB;AAC5B,SAAS,wBAAwB;AAQ1B,SAAS,eACd,eACgB;AAChB,QAAM,OAAO,iBAAiB;AAE9B,MAAI,SAAS,aAAc,QAAO,IAAI,iBAAiB;AACvD,MAAI,SAAS,OAAQ,QAAO,IAAI,YAAY;AAI5C,MAAI,SAAS,QAAQ;AACnB,QAAI,QAAQ,IAAI,QAAQ,QAAQ,IAAI,iBAAiB,aAAa;AAChE,aAAO,IAAI,YAAY;AAAA,IACzB;AACA,WAAO,IAAI,iBAAiB;AAAA,EAC9B;AAEA,SAAO,IAAI,iBAAiB;AAC9B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|