@slopus/rig 0.0.3 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +144 -1
- package/dist/agent/Agent.d.ts +16 -0
- package/dist/agent/Agent.d.ts.map +1 -1
- package/dist/agent/Agent.js +106 -0
- package/dist/agent/compaction/compactConversation.d.ts +22 -0
- package/dist/agent/compaction/compactConversation.d.ts.map +1 -0
- package/dist/agent/compaction/compactConversation.js +77 -0
- package/dist/agent/compaction/estimateMessagesTokens.d.ts +3 -0
- package/dist/agent/compaction/estimateMessagesTokens.d.ts.map +1 -0
- package/dist/agent/compaction/estimateMessagesTokens.js +39 -0
- package/dist/agent/compaction/formatMessagesForCompaction.d.ts +3 -0
- package/dist/agent/compaction/formatMessagesForCompaction.d.ts.map +1 -0
- package/dist/agent/compaction/formatMessagesForCompaction.js +30 -0
- package/dist/agent/compaction/requestCompactionSummary.d.ts +11 -0
- package/dist/agent/compaction/requestCompactionSummary.d.ts.map +1 -0
- package/dist/agent/compaction/requestCompactionSummary.js +43 -0
- package/dist/agent/context/AgentContext.d.ts +8 -0
- package/dist/agent/context/AgentContext.d.ts.map +1 -1
- package/dist/agent/context/BashContext.d.ts +23 -0
- package/dist/agent/context/BashContext.d.ts.map +1 -1
- package/dist/agent/context/GoalContext.d.ts +7 -0
- package/dist/agent/context/GoalContext.d.ts.map +1 -0
- package/dist/agent/context/GoalContext.js +1 -0
- package/dist/agent/context/SubagentContext.d.ts +20 -1
- package/dist/agent/context/SubagentContext.d.ts.map +1 -1
- package/dist/agent/context/TaskContext.d.ts +8 -0
- package/dist/agent/context/TaskContext.d.ts.map +1 -0
- package/dist/agent/context/TaskContext.js +1 -0
- package/dist/agent/context/UserInputContext.d.ts +7 -0
- package/dist/agent/context/UserInputContext.d.ts.map +1 -0
- package/dist/agent/context/UserInputContext.js +1 -0
- package/dist/agent/context/assertCanWritePath.d.ts +3 -0
- package/dist/agent/context/assertCanWritePath.d.ts.map +1 -0
- package/dist/agent/context/assertCanWritePath.js +11 -0
- package/dist/agent/context/createJustBashBashContext.d.ts.map +1 -1
- package/dist/agent/context/createJustBashBashContext.js +127 -0
- package/dist/agent/context/createNodeAgentContext.d.ts +8 -0
- package/dist/agent/context/createNodeAgentContext.d.ts.map +1 -1
- package/dist/agent/context/createNodeAgentContext.js +15 -2
- package/dist/agent/context/createNodeBashContext.d.ts +2 -0
- package/dist/agent/context/createNodeBashContext.d.ts.map +1 -1
- package/dist/agent/context/createNodeBashContext.js +123 -4
- package/dist/agent/context/createNodeFileSystemContext.d.ts +2 -0
- package/dist/agent/context/createNodeFileSystemContext.d.ts.map +1 -1
- package/dist/agent/context/createNodeFileSystemContext.js +18 -8
- package/dist/agent/context/createSandboxedCommand.d.ts +7 -0
- package/dist/agent/context/createSandboxedCommand.d.ts.map +1 -0
- package/dist/agent/context/createSandboxedCommand.js +47 -0
- package/dist/agent/context/findGitWritablePaths.d.ts +2 -0
- package/dist/agent/context/findGitWritablePaths.d.ts.map +1 -0
- package/dist/agent/context/findGitWritablePaths.js +54 -0
- package/dist/agent/context/isPathInsideWorkspace.d.ts +2 -0
- package/dist/agent/context/isPathInsideWorkspace.d.ts.map +1 -0
- package/dist/agent/context/isPathInsideWorkspace.js +14 -0
- package/dist/agent/context/resolvePotentialPath.d.ts +2 -0
- package/dist/agent/context/resolvePotentialPath.d.ts.map +1 -0
- package/dist/agent/context/resolvePotentialPath.js +32 -0
- package/dist/agent/createPermissionInstructions.d.ts +3 -0
- package/dist/agent/createPermissionInstructions.d.ts.map +1 -0
- package/dist/agent/createPermissionInstructions.js +12 -0
- package/dist/agent/createSubagentInstructions.js +1 -1
- package/dist/agent/createSystemPrompt.d.ts.map +1 -1
- package/dist/agent/createSystemPrompt.js +4 -0
- package/dist/agent/index.d.ts +7 -3
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/loop.d.ts +16 -2
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +115 -15
- package/dist/agent/printAgentMessageToConsole.d.ts +1 -0
- package/dist/agent/printAgentMessageToConsole.d.ts.map +1 -1
- package/dist/agent/selectSystemPromptForModel.js +1 -1
- package/dist/agent/types.d.ts +1 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/app/CodingAssistantAgentBackend.d.ts +11 -1
- package/dist/app/CodingAssistantAgentBackend.d.ts.map +1 -1
- package/dist/app/CodingAssistantApp.d.ts +7 -1
- package/dist/app/CodingAssistantApp.d.ts.map +1 -1
- package/dist/app/CodingAssistantApp.js +678 -45
- package/dist/app/ScrollbackPreservingTerminal.d.ts +5 -0
- package/dist/app/ScrollbackPreservingTerminal.d.ts.map +1 -0
- package/dist/app/ScrollbackPreservingTerminal.js +7 -0
- package/dist/app/StartupStatusApp.js +1 -1
- package/dist/app/createCodingAssistantAgent.d.ts +6 -1
- package/dist/app/createCodingAssistantAgent.d.ts.map +1 -1
- package/dist/app/createCodingAssistantAgent.js +24 -7
- package/dist/app/createSlashCommands.d.ts.map +1 -1
- package/dist/app/createSlashCommands.js +42 -0
- package/dist/app/describeReasoningLevel.d.ts.map +1 -1
- package/dist/app/describeReasoningLevel.js +1 -0
- package/dist/app/highlightAgentCode.d.ts.map +1 -1
- package/dist/app/highlightAgentCode.js +10 -7
- package/dist/app/humanizeGoalStatus.d.ts +3 -0
- package/dist/app/humanizeGoalStatus.d.ts.map +1 -0
- package/dist/app/humanizeGoalStatus.js +9 -0
- package/dist/app/humanizePermissionMode.d.ts +3 -0
- package/dist/app/humanizePermissionMode.d.ts.map +1 -0
- package/dist/app/humanizePermissionMode.js +9 -0
- package/dist/app/humanizeReasoningLevel.d.ts.map +1 -1
- package/dist/app/humanizeReasoningLevel.js +3 -0
- package/dist/app/humanizeToolName.d.ts +2 -0
- package/dist/app/humanizeToolName.d.ts.map +1 -0
- package/dist/app/humanizeToolName.js +40 -0
- package/dist/app/main.d.ts.map +1 -1
- package/dist/app/main.js +4 -0
- package/dist/app/renderAgentMarkdown.d.ts.map +1 -1
- package/dist/app/renderAgentMarkdown.js +2 -1
- package/dist/app/runApp.d.ts +2 -0
- package/dist/app/runApp.d.ts.map +1 -1
- package/dist/app/runApp.js +48 -3
- package/dist/app/sanitizeTerminalText.d.ts +2 -0
- package/dist/app/sanitizeTerminalText.d.ts.map +1 -0
- package/dist/app/sanitizeTerminalText.js +55 -0
- package/dist/app/upsertSubagentSummary.d.ts +3 -0
- package/dist/app/upsertSubagentSummary.d.ts.map +1 -0
- package/dist/app/upsertSubagentSummary.js +6 -0
- package/dist/client/ProtocolHttpClient.d.ts +12 -1
- package/dist/client/ProtocolHttpClient.d.ts.map +1 -1
- package/dist/client/ProtocolHttpClient.js +21 -0
- package/dist/client/RemoteAgent.d.ts +11 -1
- package/dist/client/RemoteAgent.d.ts.map +1 -1
- package/dist/client/RemoteAgent.js +91 -1
- package/dist/config/createConfigFile.d.ts.map +1 -1
- package/dist/config/createConfigFile.js +5 -0
- package/dist/config/defaultConfig.d.ts.map +1 -1
- package/dist/config/defaultConfig.js +2 -0
- package/dist/config/mergeConfigValues.d.ts.map +1 -1
- package/dist/config/mergeConfigValues.js +8 -1
- package/dist/config/parseConfigToml.d.ts.map +1 -1
- package/dist/config/parseConfigToml.js +88 -0
- package/dist/config/serializeMcpServers.d.ts +3 -0
- package/dist/config/serializeMcpServers.d.ts.map +1 -0
- package/dist/config/serializeMcpServers.js +34 -0
- package/dist/config/types.d.ts +6 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/writeRuntimeConfig.d.ts.map +1 -1
- package/dist/config/writeRuntimeConfig.js +3 -0
- package/dist/goals/SessionGoal.d.ts +14 -0
- package/dist/goals/SessionGoal.d.ts.map +1 -0
- package/dist/goals/SessionGoal.js +1 -0
- package/dist/goals/createGoalContinuationPrompt.d.ts +3 -0
- package/dist/goals/createGoalContinuationPrompt.d.ts.map +1 -0
- package/dist/goals/createGoalContinuationPrompt.js +17 -0
- package/dist/goals/index.d.ts +5 -0
- package/dist/goals/index.d.ts.map +1 -0
- package/dist/goals/index.js +3 -0
- package/dist/goals/isGoalStatus.d.ts +3 -0
- package/dist/goals/isGoalStatus.d.ts.map +1 -0
- package/dist/goals/isGoalStatus.js +3 -0
- package/dist/goals/normalizeGoalObjective.d.ts +3 -0
- package/dist/goals/normalizeGoalObjective.d.ts.map +1 -0
- package/dist/goals/normalizeGoalObjective.js +11 -0
- package/dist/mcp/McpClientManager.d.ts +12 -0
- package/dist/mcp/McpClientManager.d.ts.map +1 -0
- package/dist/mcp/McpClientManager.js +123 -0
- package/dist/mcp/connectMcpServer.d.ts +8 -0
- package/dist/mcp/connectMcpServer.d.ts.map +1 -0
- package/dist/mcp/connectMcpServer.js +47 -0
- package/dist/mcp/createMcpTool.d.ts +11 -0
- package/dist/mcp/createMcpTool.d.ts.map +1 -0
- package/dist/mcp/createMcpTool.js +43 -0
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +3 -0
- package/dist/mcp/loadMcpServerConfigs.d.ts +4 -0
- package/dist/mcp/loadMcpServerConfigs.d.ts.map +1 -0
- package/dist/mcp/loadMcpServerConfigs.js +122 -0
- package/dist/mcp/mcpResultToContentBlocks.d.ts +3 -0
- package/dist/mcp/mcpResultToContentBlocks.d.ts.map +1 -0
- package/dist/mcp/mcpResultToContentBlocks.js +51 -0
- package/dist/mcp/mergeMcpTools.d.ts +7 -0
- package/dist/mcp/mergeMcpTools.d.ts.map +1 -0
- package/dist/mcp/mergeMcpTools.js +34 -0
- package/dist/mcp/normalizeMcpName.d.ts +2 -0
- package/dist/mcp/normalizeMcpName.d.ts.map +1 -0
- package/dist/mcp/normalizeMcpName.js +3 -0
- package/dist/mcp/types.d.ts +37 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +1 -0
- package/dist/permissions/PermissionContext.d.ts +7 -0
- package/dist/permissions/PermissionContext.d.ts.map +1 -0
- package/dist/permissions/PermissionContext.js +1 -0
- package/dist/permissions/PermissionMode.d.ts +3 -0
- package/dist/permissions/PermissionMode.d.ts.map +1 -0
- package/dist/permissions/PermissionMode.js +1 -0
- package/dist/permissions/createPermissionContext.d.ts +4 -0
- package/dist/permissions/createPermissionContext.d.ts.map +1 -0
- package/dist/permissions/createPermissionContext.js +16 -0
- package/dist/permissions/index.d.ts +13 -0
- package/dist/permissions/index.d.ts.map +1 -0
- package/dist/permissions/index.js +9 -0
- package/dist/permissions/isPermissionMode.d.ts +3 -0
- package/dist/permissions/isPermissionMode.d.ts.map +1 -0
- package/dist/permissions/isPermissionMode.js +6 -0
- package/dist/permissions/parseAutoPermissionReview.d.ts +7 -0
- package/dist/permissions/parseAutoPermissionReview.d.ts.map +1 -0
- package/dist/permissions/parseAutoPermissionReview.js +33 -0
- package/dist/permissions/parsePermissionMode.d.ts +3 -0
- package/dist/permissions/parsePermissionMode.d.ts.map +1 -0
- package/dist/permissions/parsePermissionMode.js +6 -0
- package/dist/permissions/requestAutoPermissionApproval.d.ts +9 -0
- package/dist/permissions/requestAutoPermissionApproval.d.ts.map +1 -0
- package/dist/permissions/requestAutoPermissionApproval.js +26 -0
- package/dist/permissions/reviewAutoPermission.d.ts +13 -0
- package/dist/permissions/reviewAutoPermission.d.ts.map +1 -0
- package/dist/permissions/reviewAutoPermission.js +70 -0
- package/dist/permissions/shouldElevateToolInAutoMode.d.ts +2 -0
- package/dist/permissions/shouldElevateToolInAutoMode.d.ts.map +1 -0
- package/dist/permissions/shouldElevateToolInAutoMode.js +37 -0
- package/dist/permissions/shouldReviewToolInAutoMode.d.ts +2 -0
- package/dist/permissions/shouldReviewToolInAutoMode.d.ts.map +1 -0
- package/dist/permissions/shouldReviewToolInAutoMode.js +85 -0
- package/dist/permissions/summarizePermissionAction.d.ts +2 -0
- package/dist/permissions/summarizePermissionAction.d.ts.map +1 -0
- package/dist/permissions/summarizePermissionAction.js +29 -0
- package/dist/protocol/SessionProtocol.d.ts +49 -2
- package/dist/protocol/SessionProtocol.d.ts.map +1 -1
- package/dist/protocol/index.d.ts +4 -1
- package/dist/protocol/index.d.ts.map +1 -1
- package/dist/providers/claude-sdk.d.ts.map +1 -1
- package/dist/providers/claude-sdk.js +7 -6
- package/dist/providers/codex.d.ts.map +1 -1
- package/dist/providers/codex.js +52 -6
- package/dist/providers/models.d.ts +12 -9
- package/dist/providers/models.d.ts.map +1 -1
- package/dist/providers/models.js +36 -0
- package/dist/providers/types.d.ts +3 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/review/createCodeReviewPrompt.d.ts +2 -0
- package/dist/review/createCodeReviewPrompt.d.ts.map +1 -0
- package/dist/review/createCodeReviewPrompt.js +11 -0
- package/dist/review/index.d.ts +2 -0
- package/dist/review/index.d.ts.map +1 -0
- package/dist/review/index.js +1 -0
- package/dist/server/AgentSessionManager.d.ts +10 -1
- package/dist/server/AgentSessionManager.d.ts.map +1 -1
- package/dist/server/AgentSessionManager.js +203 -12
- package/dist/server/InMemorySession.d.ts +34 -1
- package/dist/server/InMemorySession.d.ts.map +1 -1
- package/dist/server/InMemorySession.js +558 -10
- package/dist/server/InMemorySessionStore.d.ts +2 -0
- package/dist/server/InMemorySessionStore.d.ts.map +1 -1
- package/dist/server/InMemorySessionStore.js +7 -0
- package/dist/server/PersistentSessionStore.d.ts +2 -0
- package/dist/server/PersistentSessionStore.d.ts.map +1 -1
- package/dist/server/PersistentSessionStore.js +80 -5
- package/dist/server/createGoalTitle.d.ts +2 -0
- package/dist/server/createGoalTitle.d.ts.map +1 -0
- package/dist/server/createGoalTitle.js +4 -0
- package/dist/server/createModelCatalog.js +2 -2
- package/dist/server/createProtocolHttpServer.d.ts.map +1 -1
- package/dist/server/createProtocolHttpServer.js +119 -2
- package/dist/server/runLocalProtocolServer.d.ts.map +1 -1
- package/dist/server/runLocalProtocolServer.js +18 -2
- package/dist/tasks/index.d.ts +2 -0
- package/dist/tasks/index.d.ts.map +1 -0
- package/dist/tasks/index.js +1 -0
- package/dist/tasks/types.d.ts +39 -0
- package/dist/tasks/types.d.ts.map +1 -0
- package/dist/tasks/types.js +1 -0
- package/dist/tools/Agent.d.ts +13 -3
- package/dist/tools/Agent.d.ts.map +1 -1
- package/dist/tools/Agent.js +40 -12
- package/dist/tools/claude/AskUserQuestion.d.ts +23 -0
- package/dist/tools/claude/AskUserQuestion.d.ts.map +1 -0
- package/dist/tools/claude/AskUserQuestion.js +52 -0
- package/dist/tools/claude/Bash.d.ts +2 -0
- package/dist/tools/claude/Bash.d.ts.map +1 -1
- package/dist/tools/claude/Bash.js +20 -2
- package/dist/tools/claude/SendMessage.d.ts +10 -0
- package/dist/tools/claude/SendMessage.d.ts.map +1 -0
- package/dist/tools/claude/SendMessage.js +33 -0
- package/dist/tools/claude/TaskCreate.d.ts +12 -0
- package/dist/tools/claude/TaskCreate.d.ts.map +1 -0
- package/dist/tools/claude/TaskCreate.js +34 -0
- package/dist/tools/claude/TaskGet.d.ts +16 -0
- package/dist/tools/claude/TaskGet.d.ts.map +1 -0
- package/dist/tools/claude/TaskGet.js +44 -0
- package/dist/tools/claude/TaskList.d.ts +10 -0
- package/dist/tools/claude/TaskList.d.ts.map +1 -0
- package/dist/tools/claude/TaskList.js +51 -0
- package/dist/tools/claude/TaskOutput.d.ts +17 -0
- package/dist/tools/claude/TaskOutput.d.ts.map +1 -0
- package/dist/tools/claude/TaskOutput.js +74 -0
- package/dist/tools/claude/TaskStop.d.ts +10 -0
- package/dist/tools/claude/TaskStop.d.ts.map +1 -0
- package/dist/tools/claude/TaskStop.js +42 -0
- package/dist/tools/claude/TaskUpdate.d.ts +21 -0
- package/dist/tools/claude/TaskUpdate.d.ts.map +1 -0
- package/dist/tools/claude/TaskUpdate.js +55 -0
- package/dist/tools/claude/index.d.ts +111 -5
- package/dist/tools/claude/index.d.ts.map +1 -1
- package/dist/tools/claude/index.js +24 -2
- package/dist/tools/claude/parseBackgroundTaskId.d.ts +2 -0
- package/dist/tools/claude/parseBackgroundTaskId.d.ts.map +1 -0
- package/dist/tools/claude/parseBackgroundTaskId.js +7 -0
- package/dist/tools/claude/taskSchemas.d.ts +14 -0
- package/dist/tools/claude/taskSchemas.d.ts.map +1 -0
- package/dist/tools/claude/taskSchemas.js +18 -0
- package/dist/tools/codex/exec_command.d.ts +8 -6
- package/dist/tools/codex/exec_command.d.ts.map +1 -1
- package/dist/tools/codex/exec_command.js +37 -18
- package/dist/tools/codex/followup_task.d.ts +11 -0
- package/dist/tools/codex/followup_task.d.ts.map +1 -0
- package/dist/tools/codex/followup_task.js +18 -0
- package/dist/tools/codex/humanizeTaskName.d.ts +2 -0
- package/dist/tools/codex/humanizeTaskName.d.ts.map +1 -0
- package/dist/tools/codex/humanizeTaskName.js +4 -0
- package/dist/tools/codex/index.d.ts +90 -7
- package/dist/tools/codex/index.d.ts.map +1 -1
- package/dist/tools/codex/index.js +24 -0
- package/dist/tools/codex/interrupt_agent.d.ts +10 -0
- package/dist/tools/codex/interrupt_agent.d.ts.map +1 -0
- package/dist/tools/codex/interrupt_agent.js +17 -0
- package/dist/tools/codex/list_agents.d.ts +12 -0
- package/dist/tools/codex/list_agents.d.ts.map +1 -0
- package/dist/tools/codex/list_agents.js +23 -0
- package/dist/tools/codex/request_user_input.d.ts +16 -0
- package/dist/tools/codex/request_user_input.d.ts.map +1 -0
- package/dist/tools/codex/request_user_input.js +58 -0
- package/dist/tools/codex/requireSubagentContext.d.ts +3 -0
- package/dist/tools/codex/requireSubagentContext.d.ts.map +1 -0
- package/dist/tools/codex/requireSubagentContext.js +6 -0
- package/dist/tools/codex/spawn_agent.d.ts +9 -0
- package/dist/tools/codex/spawn_agent.d.ts.map +1 -0
- package/dist/tools/codex/spawn_agent.js +35 -0
- package/dist/tools/codex/subagentSchemas.d.ts +8 -0
- package/dist/tools/codex/subagentSchemas.d.ts.map +1 -0
- package/dist/tools/codex/subagentSchemas.js +13 -0
- package/dist/tools/codex/unifiedExecOutput.d.ts +14 -0
- package/dist/tools/codex/unifiedExecOutput.d.ts.map +1 -0
- package/dist/tools/codex/unifiedExecOutput.js +44 -0
- package/dist/tools/codex/update_plan.d.ts +10 -0
- package/dist/tools/codex/update_plan.d.ts.map +1 -0
- package/dist/tools/codex/update_plan.js +34 -0
- package/dist/tools/codex/wait_agent.d.ts +13 -0
- package/dist/tools/codex/wait_agent.d.ts.map +1 -0
- package/dist/tools/codex/wait_agent.js +32 -0
- package/dist/tools/codex/write_stdin.d.ts +6 -1
- package/dist/tools/codex/write_stdin.d.ts.map +1 -1
- package/dist/tools/codex/write_stdin.js +44 -12
- package/dist/tools/goals/create_goal.d.ts +11 -0
- package/dist/tools/goals/create_goal.d.ts.map +1 -0
- package/dist/tools/goals/create_goal.js +29 -0
- package/dist/tools/goals/get_goal.d.ts +9 -0
- package/dist/tools/goals/get_goal.d.ts.map +1 -0
- package/dist/tools/goals/get_goal.js +26 -0
- package/dist/tools/goals/goalSchemas.d.ts +8 -0
- package/dist/tools/goals/goalSchemas.d.ts.map +1 -0
- package/dist/tools/goals/goalSchemas.js +13 -0
- package/dist/tools/goals/index.d.ts +30 -0
- package/dist/tools/goals/index.d.ts.map +1 -0
- package/dist/tools/goals/index.js +7 -0
- package/dist/tools/goals/update_goal.d.ts +11 -0
- package/dist/tools/goals/update_goal.d.ts.map +1 -0
- package/dist/tools/goals/update_goal.js +33 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1 -0
- package/dist/tools/pi/bash.d.ts.map +1 -1
- package/dist/tools/pi/bash.js +2 -0
- package/dist/tools/utils/readSessionWithProgress.d.ts +9 -0
- package/dist/tools/utils/readSessionWithProgress.d.ts.map +1 -0
- package/dist/tools/utils/readSessionWithProgress.js +27 -0
- package/dist/tools/utils/shell.d.ts +2 -0
- package/dist/tools/utils/shell.d.ts.map +1 -1
- package/dist/tools/utils/shell.js +37 -0
- package/dist/tools/utils/summarizeShellOutput.d.ts.map +1 -1
- package/dist/tools/utils/summarizeShellOutput.js +2 -0
- package/dist/user-input/index.d.ts +2 -0
- package/dist/user-input/index.d.ts.map +1 -0
- package/dist/user-input/index.js +1 -0
- package/dist/user-input/types.d.ts +19 -0
- package/dist/user-input/types.d.ts.map +1 -0
- package/dist/user-input/types.js +1 -0
- package/dist/web/assets/highlighted-body-OFNGDK62-BuJOCQJD.js +1 -0
- package/dist/web/assets/highlighted-body-OFNGDK62-TwhCqUaJ.js +1 -0
- package/dist/web/assets/index-B6Bc6sUJ.css +1 -0
- package/dist/web/assets/index-BC99-iZC.js +341 -0
- package/dist/web/assets/index-BZN9jSiw.js +341 -0
- package/dist/web/assets/index-CcF0unjO.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +2 -1
|
@@ -4,6 +4,7 @@ import { basename, join } from "node:path";
|
|
|
4
4
|
import { CURSOR_MARKER, Editor, matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi, } from "@earendil-works/pi-tui";
|
|
5
5
|
import { formatSkillInvocation, loadSkills, } from "../agent/index.js";
|
|
6
6
|
import { parseSkillFrontmatter } from "../agent/skills/parseSkillFrontmatter.js";
|
|
7
|
+
import { createCodeReviewPrompt } from "../review/index.js";
|
|
7
8
|
import { createSelectionPanel } from "./createSelectionPanel.js";
|
|
8
9
|
import { createSlashCommands } from "./createSlashCommands.js";
|
|
9
10
|
import { describeModelChoice } from "./describeModelChoice.js";
|
|
@@ -13,9 +14,14 @@ import { formatActivityElapsedTime } from "./formatActivityElapsedTime.js";
|
|
|
13
14
|
import { FileMentionAutocomplete } from "./FileMentionAutocomplete.js";
|
|
14
15
|
import { formatFileMention } from "./formatFileMention.js";
|
|
15
16
|
import { humanizeReasoningLevel } from "./humanizeReasoningLevel.js";
|
|
17
|
+
import { humanizePermissionMode } from "./humanizePermissionMode.js";
|
|
18
|
+
import { humanizeGoalStatus } from "./humanizeGoalStatus.js";
|
|
19
|
+
import { humanizeToolName } from "./humanizeToolName.js";
|
|
16
20
|
import { readClipboardImage, } from "./readClipboardImage.js";
|
|
17
21
|
import { ACTIVITY_WAVE_FRAME_COUNT, renderActivityWave } from "./renderActivityWave.js";
|
|
18
22
|
import { renderAgentMarkdown } from "./renderAgentMarkdown.js";
|
|
23
|
+
import { sanitizeTerminalText } from "./sanitizeTerminalText.js";
|
|
24
|
+
import { upsertSubagentSummary } from "./upsertSubagentSummary.js";
|
|
19
25
|
const RESET = "\x1b[0m";
|
|
20
26
|
const BOLD = "\x1b[1m";
|
|
21
27
|
const DIM = "\x1b[2m";
|
|
@@ -48,6 +54,8 @@ const IMAGE_PASTE_RAW_KEYS = new Set(["\x16", "\x1bv"]);
|
|
|
48
54
|
const AUTOCOMPLETE_MAX_VISIBLE = 6;
|
|
49
55
|
const BRACKETED_PASTE_START = "\x1b[200~";
|
|
50
56
|
const BRACKETED_PASTE_END = "\x1b[201~";
|
|
57
|
+
const TERMINAL_FOCUS_IN = "\x1b[I";
|
|
58
|
+
const TERMINAL_FOCUS_OUT = "\x1b[O";
|
|
51
59
|
const IMAGE_PLACEHOLDER_REGEX = /\[Image #(\d+) [A-Z0-9]+\]/gu;
|
|
52
60
|
const IMAGE_CHIP_BG = "\x1b[48;5;240m";
|
|
53
61
|
const IMAGE_CHIP_FG = "\x1b[38;5;255m";
|
|
@@ -73,6 +81,7 @@ export class CodingAssistantApp {
|
|
|
73
81
|
#onDefaultModelChange;
|
|
74
82
|
#onSettingsChange;
|
|
75
83
|
#onExit;
|
|
84
|
+
#respondUserInput;
|
|
76
85
|
#processManager;
|
|
77
86
|
#readClipboardImage;
|
|
78
87
|
#tui;
|
|
@@ -81,6 +90,8 @@ export class CodingAssistantApp {
|
|
|
81
90
|
#abortController;
|
|
82
91
|
#abortNotified = false;
|
|
83
92
|
#activeRun;
|
|
93
|
+
#activeUserInput;
|
|
94
|
+
#answeringUserInputRequestId;
|
|
84
95
|
#activityAnimationFrame = 0;
|
|
85
96
|
#activityStartedAtMs;
|
|
86
97
|
#activityAnimationTimer;
|
|
@@ -92,7 +103,10 @@ export class CodingAssistantApp {
|
|
|
92
103
|
#exiting = false;
|
|
93
104
|
#exitResolve;
|
|
94
105
|
#focused = false;
|
|
106
|
+
#terminalFocused = true;
|
|
107
|
+
#freeformUserInput;
|
|
95
108
|
#pendingPrompts = [];
|
|
109
|
+
#compacting = false;
|
|
96
110
|
#pastedImagesById = new Map();
|
|
97
111
|
#selectionPanel;
|
|
98
112
|
#dismissedSlashCommandText;
|
|
@@ -101,6 +115,7 @@ export class CodingAssistantApp {
|
|
|
101
115
|
#showReasoning;
|
|
102
116
|
#sessionBacked;
|
|
103
117
|
#modelLocked;
|
|
118
|
+
#mcpServers;
|
|
104
119
|
#slashCommandSelectionIndex = 0;
|
|
105
120
|
#slashCommands = createSlashCommands();
|
|
106
121
|
#skillCommands = [];
|
|
@@ -115,8 +130,12 @@ export class CodingAssistantApp {
|
|
|
115
130
|
#statusText = "Idle";
|
|
116
131
|
#stopped = false;
|
|
117
132
|
#streamEntryId;
|
|
133
|
+
#subagents;
|
|
134
|
+
#tasks;
|
|
118
135
|
#thinkingEntryIdsByContentIndex = new Map();
|
|
119
136
|
#toolCallEntryIdsByContentIndex = new Map();
|
|
137
|
+
#runningToolCallIds = new Set();
|
|
138
|
+
#userInputRequests = [];
|
|
120
139
|
constructor(options) {
|
|
121
140
|
this.#agent = options.agent;
|
|
122
141
|
this.#cwd = options.cwd;
|
|
@@ -125,11 +144,15 @@ export class CodingAssistantApp {
|
|
|
125
144
|
this.#onDefaultModelChange = options.onDefaultModelChange;
|
|
126
145
|
this.#onSettingsChange = options.onSettingsChange;
|
|
127
146
|
this.#onExit = options.onExit;
|
|
147
|
+
this.#respondUserInput = options.respondUserInput;
|
|
128
148
|
this.#processManager = options.processManager;
|
|
129
149
|
this.#readClipboardImage = options.readClipboardImage ?? readClipboardImage;
|
|
130
150
|
this.#sessionBacked = options.sessionBacked ?? false;
|
|
131
151
|
this.#showReasoning = options.showReasoning ?? false;
|
|
132
152
|
this.#modelLocked = options.modelLocked ?? !options.agent.canChangeModel;
|
|
153
|
+
this.#mcpServers = options.initialMcpServers ?? [];
|
|
154
|
+
this.#subagents = options.initialSubagents ?? [];
|
|
155
|
+
this.#tasks = options.initialTasks ?? [];
|
|
133
156
|
this.#tui = options.tui;
|
|
134
157
|
this.#version = options.version ?? "0.0.0";
|
|
135
158
|
this.#editor = new Editor(this.#tui, EDITOR_THEME, { paddingX: 0 });
|
|
@@ -143,6 +166,9 @@ export class CodingAssistantApp {
|
|
|
143
166
|
this.#editor.onSubmit = (value) => {
|
|
144
167
|
this.#submit(value);
|
|
145
168
|
};
|
|
169
|
+
for (const request of options.initialUserInputs ?? []) {
|
|
170
|
+
this.#enqueueUserInputRequest(request);
|
|
171
|
+
}
|
|
146
172
|
for (const event of options.initialSessionEvents ?? []) {
|
|
147
173
|
this.applySessionEvent(event);
|
|
148
174
|
}
|
|
@@ -153,14 +179,16 @@ export class CodingAssistantApp {
|
|
|
153
179
|
}
|
|
154
180
|
set focused(value) {
|
|
155
181
|
this.#focused = value;
|
|
156
|
-
this.#editor.focused = value;
|
|
182
|
+
this.#editor.focused = value && this.#terminalFocused;
|
|
157
183
|
this.#cursorVisible = true;
|
|
158
|
-
if (value) {
|
|
184
|
+
if (value && this.#terminalFocused) {
|
|
159
185
|
this.#cursorTyping = false;
|
|
160
186
|
this.#startCursorBlink();
|
|
161
187
|
}
|
|
162
188
|
else {
|
|
163
189
|
this.#stopCursorBlink();
|
|
190
|
+
if (!this.#terminalFocused)
|
|
191
|
+
this.#cursorVisible = false;
|
|
164
192
|
}
|
|
165
193
|
}
|
|
166
194
|
start(options = {}) {
|
|
@@ -222,6 +250,29 @@ export class CodingAssistantApp {
|
|
|
222
250
|
this.#applyAgentMessage(event.data.message);
|
|
223
251
|
return;
|
|
224
252
|
}
|
|
253
|
+
if (event.type === "user_input_requested") {
|
|
254
|
+
this.#enqueueUserInputRequest(event.data);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (event.type === "user_input_resolved") {
|
|
258
|
+
this.#removeUserInputRequest(event.data.requestId);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (event.type === "mcp_servers_changed") {
|
|
262
|
+
this.#mcpServers = event.data.servers;
|
|
263
|
+
this.#requestRender();
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
if (event.type === "tasks_changed") {
|
|
267
|
+
this.#tasks = event.data.tasks;
|
|
268
|
+
this.#requestRender();
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (event.type === "subagent_changed") {
|
|
272
|
+
this.#subagents = upsertSubagentSummary(this.#subagents, event.data.subagent);
|
|
273
|
+
this.#requestRender();
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
225
276
|
if (event.type === "run_finished") {
|
|
226
277
|
this.#running = false;
|
|
227
278
|
this.#statusText =
|
|
@@ -230,6 +281,8 @@ export class CodingAssistantApp {
|
|
|
230
281
|
this.#streamEntryId = undefined;
|
|
231
282
|
this.#thinkingEntryIdsByContentIndex.clear();
|
|
232
283
|
this.#toolCallEntryIdsByContentIndex.clear();
|
|
284
|
+
this.#runningToolCallIds.clear();
|
|
285
|
+
this.#clearUserInputRequests();
|
|
233
286
|
this.#requestRender();
|
|
234
287
|
return;
|
|
235
288
|
}
|
|
@@ -237,6 +290,8 @@ export class CodingAssistantApp {
|
|
|
237
290
|
this.#running = false;
|
|
238
291
|
this.#statusText = "Error";
|
|
239
292
|
this.#stopActivityAnimation();
|
|
293
|
+
this.#runningToolCallIds.clear();
|
|
294
|
+
this.#clearUserInputRequests();
|
|
240
295
|
this.#appendEntry({ role: "error", text: event.data.errorMessage });
|
|
241
296
|
return;
|
|
242
297
|
}
|
|
@@ -247,6 +302,8 @@ export class CodingAssistantApp {
|
|
|
247
302
|
this.#streamEntryId = undefined;
|
|
248
303
|
this.#thinkingEntryIdsByContentIndex.clear();
|
|
249
304
|
this.#toolCallEntryIdsByContentIndex.clear();
|
|
305
|
+
this.#runningToolCallIds.clear();
|
|
306
|
+
this.#clearUserInputRequests();
|
|
250
307
|
this.#appendEntry({
|
|
251
308
|
role: "system",
|
|
252
309
|
text: "Session reset. Started a new session.",
|
|
@@ -272,6 +329,15 @@ export class CodingAssistantApp {
|
|
|
272
329
|
});
|
|
273
330
|
return;
|
|
274
331
|
}
|
|
332
|
+
if (event.type === "permission_mode_changed") {
|
|
333
|
+
this.#appendEntry({
|
|
334
|
+
role: "event",
|
|
335
|
+
title: "permissions",
|
|
336
|
+
text: `Permissions changed to ${humanizePermissionMode(event.data.permissionMode)}.`,
|
|
337
|
+
});
|
|
338
|
+
this.#requestRender();
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
275
341
|
}
|
|
276
342
|
async waitForIdle() {
|
|
277
343
|
for (;;) {
|
|
@@ -291,15 +357,41 @@ export class CodingAssistantApp {
|
|
|
291
357
|
if (this.#stopped || this.#exiting) {
|
|
292
358
|
return;
|
|
293
359
|
}
|
|
360
|
+
if (data === TERMINAL_FOCUS_IN || data === TERMINAL_FOCUS_OUT) {
|
|
361
|
+
this.#setTerminalFocused(data === TERMINAL_FOCUS_IN);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
294
364
|
if (this.#selectionPanel !== undefined) {
|
|
295
365
|
if (matchesKey(data, "ctrl+c") || data === "\x03") {
|
|
296
|
-
|
|
366
|
+
this.#selectionPanel.handleInput?.("\x1b");
|
|
367
|
+
this.#requestRender();
|
|
297
368
|
return;
|
|
298
369
|
}
|
|
299
370
|
this.#selectionPanel.handleInput?.(data);
|
|
300
371
|
this.#requestRender();
|
|
301
372
|
return;
|
|
302
373
|
}
|
|
374
|
+
if (this.#freeformUserInput !== undefined) {
|
|
375
|
+
if (this.#handlePastedInput(data))
|
|
376
|
+
return;
|
|
377
|
+
if (matchesKey(data, "ctrl+c") || data === "\x03") {
|
|
378
|
+
this.#handleCtrlC();
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
if (matchesKey(data, "ctrl+d") && this.#editor.getText().length === 0) {
|
|
382
|
+
void this.stop();
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
if (matchesKey(data, "escape")) {
|
|
386
|
+
this.#handleEscape();
|
|
387
|
+
this.#requestRender();
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
this.#markTypingActivity();
|
|
391
|
+
this.#editor.handleInput(data);
|
|
392
|
+
this.#requestRender();
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
303
395
|
if (this.#handlePastedInput(data)) {
|
|
304
396
|
return;
|
|
305
397
|
}
|
|
@@ -307,13 +399,18 @@ export class CodingAssistantApp {
|
|
|
307
399
|
return;
|
|
308
400
|
}
|
|
309
401
|
if (matchesKey(data, "ctrl+c") || data === "\x03") {
|
|
310
|
-
|
|
402
|
+
this.#handleCtrlC();
|
|
311
403
|
return;
|
|
312
404
|
}
|
|
313
405
|
if (matchesKey(data, "ctrl+d") && this.#editor.getText().length === 0) {
|
|
314
406
|
void this.stop();
|
|
315
407
|
return;
|
|
316
408
|
}
|
|
409
|
+
if (this.#running && matchesKey(data, "escape")) {
|
|
410
|
+
this.#handleEscape();
|
|
411
|
+
this.#requestRender();
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
317
414
|
const previousSlashCommandSuggestionCount = this.#slashCommandSuggestions().length;
|
|
318
415
|
const previousFileMentionSuggestionCount = this.#fileMentionSnapshot()?.items.length ?? 0;
|
|
319
416
|
if (this.#handleSlashCommandAutocompleteInput(data)) {
|
|
@@ -321,6 +418,12 @@ export class CodingAssistantApp {
|
|
|
321
418
|
this.#requestRender(nextSlashCommandSuggestionCount < previousSlashCommandSuggestionCount);
|
|
322
419
|
return;
|
|
323
420
|
}
|
|
421
|
+
if (this.#running &&
|
|
422
|
+
matchesKey(data, "tab") &&
|
|
423
|
+
previousFileMentionSuggestionCount === 0 &&
|
|
424
|
+
this.#queueCurrentInput()) {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
324
427
|
if (this.#fileMentionAutocomplete?.handleInput(data, this.#editor.getLines(), this.#editor.getCursor(), (path, context) => this.#completeFileMention(path, context)) === true) {
|
|
325
428
|
const nextFileMentionSuggestionCount = this.#fileMentionSnapshot()?.items.length ?? 0;
|
|
326
429
|
this.#requestRender(nextFileMentionSuggestionCount < previousFileMentionSuggestionCount);
|
|
@@ -478,6 +581,7 @@ export class CodingAssistantApp {
|
|
|
478
581
|
...header,
|
|
479
582
|
...this.#renderTranscript(safeWidth),
|
|
480
583
|
"",
|
|
584
|
+
...this.#renderQueuedPrompts(safeWidth),
|
|
481
585
|
...(this.#selectionPanel === undefined
|
|
482
586
|
? input
|
|
483
587
|
: this.#selectionPanel.render(safeWidth)),
|
|
@@ -488,6 +592,10 @@ export class CodingAssistantApp {
|
|
|
488
592
|
];
|
|
489
593
|
}
|
|
490
594
|
#submit(value) {
|
|
595
|
+
if (this.#freeformUserInput !== undefined) {
|
|
596
|
+
this.#submitFreeformUserInput(value);
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
491
599
|
const submission = this.#submitAsync(value).catch((error) => {
|
|
492
600
|
this.#appendEntry({ role: "error", text: this.#formatError(error) });
|
|
493
601
|
});
|
|
@@ -500,6 +608,14 @@ export class CodingAssistantApp {
|
|
|
500
608
|
this.#activeSubmission = trackedSubmission;
|
|
501
609
|
}
|
|
502
610
|
async #submitAsync(value) {
|
|
611
|
+
if (this.#compacting) {
|
|
612
|
+
this.#appendEntry({
|
|
613
|
+
role: "event",
|
|
614
|
+
title: "compact",
|
|
615
|
+
text: "Wait for conversation compaction to finish before submitting.",
|
|
616
|
+
});
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
503
619
|
const submission = this.#createPromptSubmission(value);
|
|
504
620
|
if (submission === undefined) {
|
|
505
621
|
return;
|
|
@@ -512,20 +628,27 @@ export class CodingAssistantApp {
|
|
|
512
628
|
this.#requestRender();
|
|
513
629
|
return;
|
|
514
630
|
}
|
|
631
|
+
if (prompt === "/compact") {
|
|
632
|
+
await this.#compactSession();
|
|
633
|
+
this.#requestRender();
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
515
636
|
if (this.#handleCommand(prompt)) {
|
|
516
637
|
this.#requestRender();
|
|
517
638
|
return;
|
|
518
639
|
}
|
|
519
640
|
this.#modelLocked = true;
|
|
641
|
+
if (this.#running) {
|
|
642
|
+
await this.#agent.steer(submission.content, { displayText: submission.displayText });
|
|
643
|
+
this.#clearSubmittedImages(prompt);
|
|
644
|
+
if (!this.#sessionBacked)
|
|
645
|
+
this.#appendEntry({ role: "user", text: prompt });
|
|
646
|
+
this.#requestRender();
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
520
649
|
if (!this.#sessionBacked) {
|
|
521
650
|
this.#appendEntry({ role: "user", text: prompt });
|
|
522
|
-
|
|
523
|
-
if (this.#running && !this.#sessionBacked) {
|
|
524
|
-
this.#appendEntry({
|
|
525
|
-
role: "event",
|
|
526
|
-
title: "queue",
|
|
527
|
-
text: `Queued behind the active run.`,
|
|
528
|
-
});
|
|
651
|
+
submission.transcriptAppended = true;
|
|
529
652
|
}
|
|
530
653
|
this.#pendingPrompts.push(submission);
|
|
531
654
|
this.#startDrainQueue();
|
|
@@ -536,8 +659,7 @@ export class CodingAssistantApp {
|
|
|
536
659
|
if (prompt.length === 0) {
|
|
537
660
|
return undefined;
|
|
538
661
|
}
|
|
539
|
-
const content = this.#contentFromPrompt(prompt);
|
|
540
|
-
this.#clearSubmittedImages(prompt);
|
|
662
|
+
const content = createCodeReviewPrompt(prompt) ?? this.#contentFromPrompt(prompt);
|
|
541
663
|
return {
|
|
542
664
|
content,
|
|
543
665
|
displayText: prompt,
|
|
@@ -620,6 +742,12 @@ export class CodingAssistantApp {
|
|
|
620
742
|
}
|
|
621
743
|
const expandedPrompt = formatSkillInvocation(skill, parseSkillFrontmatter(content).body, parsed[2] ?? "");
|
|
622
744
|
this.#modelLocked = true;
|
|
745
|
+
if (this.#running) {
|
|
746
|
+
await this.#agent.steer(expandedPrompt, { displayText: prompt });
|
|
747
|
+
if (!this.#sessionBacked)
|
|
748
|
+
this.#appendEntry({ role: "user", text: prompt });
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
623
751
|
if (!this.#sessionBacked) {
|
|
624
752
|
this.#appendEntry({ role: "user", text: prompt });
|
|
625
753
|
}
|
|
@@ -634,6 +762,13 @@ export class CodingAssistantApp {
|
|
|
634
762
|
this.#startDrainQueue();
|
|
635
763
|
}
|
|
636
764
|
#handleCommand(prompt) {
|
|
765
|
+
if (prompt === "/goal" || prompt.startsWith("/goal ")) {
|
|
766
|
+
void this.#handleGoalCommand(prompt).catch((error) => {
|
|
767
|
+
this.#appendEntry({ role: "error", text: this.#formatError(error) });
|
|
768
|
+
this.#requestRender();
|
|
769
|
+
});
|
|
770
|
+
return true;
|
|
771
|
+
}
|
|
637
772
|
if (prompt === "/model") {
|
|
638
773
|
this.#openModelMenu();
|
|
639
774
|
return true;
|
|
@@ -649,6 +784,22 @@ export class CodingAssistantApp {
|
|
|
649
784
|
this.#openConfigureMenu();
|
|
650
785
|
return true;
|
|
651
786
|
}
|
|
787
|
+
if (prompt === "/permissions" || prompt === "/permission") {
|
|
788
|
+
this.#openPermissionsMenu();
|
|
789
|
+
return true;
|
|
790
|
+
}
|
|
791
|
+
if (prompt === "/mcp") {
|
|
792
|
+
this.#showMcpStatus();
|
|
793
|
+
return true;
|
|
794
|
+
}
|
|
795
|
+
if (prompt === "/tasks" || prompt === "/todos") {
|
|
796
|
+
this.#showTasks();
|
|
797
|
+
return true;
|
|
798
|
+
}
|
|
799
|
+
if (prompt === "/agents") {
|
|
800
|
+
this.#showSubagents();
|
|
801
|
+
return true;
|
|
802
|
+
}
|
|
652
803
|
if (prompt === "/new") {
|
|
653
804
|
this.#resetSession();
|
|
654
805
|
return true;
|
|
@@ -677,6 +828,145 @@ export class CodingAssistantApp {
|
|
|
677
828
|
}
|
|
678
829
|
return false;
|
|
679
830
|
}
|
|
831
|
+
async #handleGoalCommand(prompt) {
|
|
832
|
+
const argument = prompt.slice("/goal".length).trim();
|
|
833
|
+
const goal = this.#agent.goal;
|
|
834
|
+
if (argument.length === 0) {
|
|
835
|
+
this.#appendEntry({
|
|
836
|
+
role: "event",
|
|
837
|
+
title: "goal",
|
|
838
|
+
text: goal === undefined
|
|
839
|
+
? "No goal is set. Use /goal followed by an objective to start one."
|
|
840
|
+
: `Status: ${humanizeGoalStatus(goal.status)}\nObjective: ${goal.objective}\n\nCommands: /goal pause, /goal resume, /goal clear`,
|
|
841
|
+
});
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
if (argument === "pause" || argument === "resume") {
|
|
845
|
+
if (this.#agent.changeGoalStatus === undefined) {
|
|
846
|
+
throw new Error("Goal controls are unavailable in this session.");
|
|
847
|
+
}
|
|
848
|
+
const status = argument === "pause" ? "paused" : "active";
|
|
849
|
+
await this.#agent.changeGoalStatus(status);
|
|
850
|
+
this.#appendEntry({
|
|
851
|
+
role: "event",
|
|
852
|
+
title: "goal",
|
|
853
|
+
text: argument === "pause" ? "Goal paused." : "Goal resumed.",
|
|
854
|
+
});
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
if (argument === "clear") {
|
|
858
|
+
if (this.#agent.clearGoal === undefined) {
|
|
859
|
+
throw new Error("Goal controls are unavailable in this session.");
|
|
860
|
+
}
|
|
861
|
+
await this.#agent.clearGoal();
|
|
862
|
+
this.#appendEntry({ role: "event", title: "goal", text: "Goal cleared." });
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
if (this.#agent.setGoal === undefined) {
|
|
866
|
+
throw new Error("Goal controls are unavailable in this session.");
|
|
867
|
+
}
|
|
868
|
+
await this.#agent.setGoal(argument);
|
|
869
|
+
this.#appendEntry({
|
|
870
|
+
role: "event",
|
|
871
|
+
title: "goal",
|
|
872
|
+
text: `Goal started: ${argument}`,
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
#showMcpStatus() {
|
|
876
|
+
if (this.#mcpServers.length === 0) {
|
|
877
|
+
this.#appendEntry({
|
|
878
|
+
role: "event",
|
|
879
|
+
title: "MCP servers",
|
|
880
|
+
text: "No MCP servers have connected in this session.",
|
|
881
|
+
});
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
const text = this.#mcpServers
|
|
885
|
+
.map((server) => {
|
|
886
|
+
if (server.status === "connected") {
|
|
887
|
+
return `${server.name}: connected with ${server.toolCount} tool${server.toolCount === 1 ? "" : "s"}`;
|
|
888
|
+
}
|
|
889
|
+
if (server.status === "disabled")
|
|
890
|
+
return `${server.name}: disabled`;
|
|
891
|
+
return `${server.name}: could not connect${server.errorMessage === undefined ? "" : ` — ${server.errorMessage}`}`;
|
|
892
|
+
})
|
|
893
|
+
.join("\n");
|
|
894
|
+
this.#appendEntry({ role: "event", title: "MCP servers", text });
|
|
895
|
+
}
|
|
896
|
+
#showTasks() {
|
|
897
|
+
if (this.#tasks.length === 0) {
|
|
898
|
+
this.#appendEntry({
|
|
899
|
+
role: "event",
|
|
900
|
+
title: "Tasks",
|
|
901
|
+
text: "No tasks are being tracked in this session.",
|
|
902
|
+
});
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
const status = {
|
|
906
|
+
completed: "Completed",
|
|
907
|
+
in_progress: "In progress",
|
|
908
|
+
pending: "Pending",
|
|
909
|
+
};
|
|
910
|
+
this.#appendEntry({
|
|
911
|
+
role: "event",
|
|
912
|
+
title: "Tasks",
|
|
913
|
+
text: this.#tasks
|
|
914
|
+
.map((task) => `#${task.id} · ${status[task.status]} · ${task.subject}`)
|
|
915
|
+
.join("\n"),
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
#showSubagents() {
|
|
919
|
+
if (this.#subagents.length === 0) {
|
|
920
|
+
this.#appendEntry({
|
|
921
|
+
role: "event",
|
|
922
|
+
title: "Subagents",
|
|
923
|
+
text: "No delegated work has been started in this session.",
|
|
924
|
+
});
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
const labels = {
|
|
928
|
+
aborted: "Stopped",
|
|
929
|
+
completed: "Completed",
|
|
930
|
+
error: "Failed",
|
|
931
|
+
idle: "Idle",
|
|
932
|
+
queued: "Queued",
|
|
933
|
+
running: "Running",
|
|
934
|
+
};
|
|
935
|
+
this.#appendEntry({
|
|
936
|
+
role: "event",
|
|
937
|
+
title: "Subagents",
|
|
938
|
+
text: this.#subagents
|
|
939
|
+
.map((subagent) => `${labels[subagent.status]} · ${subagent.description}`)
|
|
940
|
+
.join("\n"),
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
async #compactSession() {
|
|
944
|
+
if (this.#compacting || this.#running || this.#pendingPrompts.length > 0) {
|
|
945
|
+
this.#appendEntry({
|
|
946
|
+
role: "event",
|
|
947
|
+
title: "compact",
|
|
948
|
+
text: "Wait for the active response to finish before compacting.",
|
|
949
|
+
});
|
|
950
|
+
return;
|
|
951
|
+
}
|
|
952
|
+
this.#compacting = true;
|
|
953
|
+
this.#statusText = "Compacting conversation";
|
|
954
|
+
this.#requestRender();
|
|
955
|
+
try {
|
|
956
|
+
const result = await this.#agent.compact();
|
|
957
|
+
this.#appendEntry({
|
|
958
|
+
role: "event",
|
|
959
|
+
title: "compact",
|
|
960
|
+
text: result.compacted
|
|
961
|
+
? `Compacted ${result.compactedMessageCount} older messages. The full transcript remains visible.`
|
|
962
|
+
: "There is not enough conversation history to compact yet.",
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
finally {
|
|
966
|
+
this.#compacting = false;
|
|
967
|
+
this.#statusText = "Idle";
|
|
968
|
+
}
|
|
969
|
+
}
|
|
680
970
|
#resetSession() {
|
|
681
971
|
this.#abortActiveRun({ silent: true });
|
|
682
972
|
this.#runToken += 1;
|
|
@@ -688,6 +978,7 @@ export class CodingAssistantApp {
|
|
|
688
978
|
this.#streamEntryId = undefined;
|
|
689
979
|
this.#thinkingEntryIdsByContentIndex.clear();
|
|
690
980
|
this.#toolCallEntryIdsByContentIndex.clear();
|
|
981
|
+
this.#runningToolCallIds.clear();
|
|
691
982
|
this.#abortNotified = false;
|
|
692
983
|
this.#statusText = "Idle";
|
|
693
984
|
this.#agent.reset();
|
|
@@ -697,11 +988,14 @@ export class CodingAssistantApp {
|
|
|
697
988
|
});
|
|
698
989
|
}
|
|
699
990
|
#startDrainQueue() {
|
|
700
|
-
if (this.#activeRun !== undefined
|
|
991
|
+
if (this.#activeRun !== undefined ||
|
|
992
|
+
this.#compacting ||
|
|
993
|
+
this.#pendingPrompts.length === 0) {
|
|
701
994
|
return;
|
|
702
995
|
}
|
|
703
996
|
this.#activeRun = this.#drainQueue().finally(() => {
|
|
704
997
|
this.#activeRun = undefined;
|
|
998
|
+
this.#startDrainQueue();
|
|
705
999
|
this.#requestRender();
|
|
706
1000
|
});
|
|
707
1001
|
}
|
|
@@ -727,6 +1021,10 @@ export class CodingAssistantApp {
|
|
|
727
1021
|
this.#activityStartedAtMs = this.#now();
|
|
728
1022
|
this.#startActivityAnimation();
|
|
729
1023
|
this.#requestRender();
|
|
1024
|
+
this.#clearSubmittedImages(prompt.displayText);
|
|
1025
|
+
if (!this.#sessionBacked && prompt.transcriptAppended !== true) {
|
|
1026
|
+
this.#appendEntry({ role: "user", text: prompt.displayText });
|
|
1027
|
+
}
|
|
730
1028
|
try {
|
|
731
1029
|
await this.#refreshSkillCommands({ force: true });
|
|
732
1030
|
if (!this.#isCurrentRun(runToken)) {
|
|
@@ -783,10 +1081,19 @@ export class CodingAssistantApp {
|
|
|
783
1081
|
}
|
|
784
1082
|
}
|
|
785
1083
|
#handleEscape() {
|
|
786
|
-
|
|
1084
|
+
this.#restoreQueuedPromptsToComposer();
|
|
1085
|
+
this.#abortActiveRun();
|
|
1086
|
+
}
|
|
1087
|
+
#restoreQueuedPromptsToComposer() {
|
|
1088
|
+
if (this.#pendingPrompts.length === 0)
|
|
787
1089
|
return;
|
|
788
|
-
|
|
789
|
-
|
|
1090
|
+
const draft = this.#editor.getText().trim();
|
|
1091
|
+
const restored = this.#pendingPrompts.map((prompt) => prompt.displayText);
|
|
1092
|
+
if (draft.length > 0)
|
|
1093
|
+
restored.push(draft);
|
|
1094
|
+
this.#pendingPrompts = [];
|
|
1095
|
+
this.#editor.setText(restored.join("\n"));
|
|
1096
|
+
this.#syncAutocompleteState();
|
|
790
1097
|
}
|
|
791
1098
|
#abortActiveRun(options = {}) {
|
|
792
1099
|
if (!this.#running || this.#abortController === undefined) {
|
|
@@ -796,12 +1103,12 @@ export class CodingAssistantApp {
|
|
|
796
1103
|
this.#runToken += 1;
|
|
797
1104
|
controller.abort();
|
|
798
1105
|
this.#abortController = undefined;
|
|
799
|
-
this.#pendingPrompts = [];
|
|
800
1106
|
this.#running = false;
|
|
801
1107
|
this.#statusText = "Idle";
|
|
802
1108
|
this.#streamEntryId = undefined;
|
|
803
1109
|
this.#thinkingEntryIdsByContentIndex.clear();
|
|
804
1110
|
this.#toolCallEntryIdsByContentIndex.clear();
|
|
1111
|
+
this.#runningToolCallIds.clear();
|
|
805
1112
|
this.#stopActivityAnimation();
|
|
806
1113
|
void this.#processManager.killAll({ forceAfterMs: 500 }).catch((error) => {
|
|
807
1114
|
this.#appendEntry({ role: "error", text: this.#formatError(error) });
|
|
@@ -862,6 +1169,23 @@ export class CodingAssistantApp {
|
|
|
862
1169
|
else if (event.type === "toolcall_end") {
|
|
863
1170
|
this.#finishToolCall(event.contentIndex, event.toolCall);
|
|
864
1171
|
}
|
|
1172
|
+
else if (event.type === "tool_execution_start") {
|
|
1173
|
+
this.#runningToolCallIds.add(event.toolCall.id);
|
|
1174
|
+
this.#statusText = `Running ${this.#runningToolCallIds.size} tool${this.#runningToolCallIds.size === 1 ? "" : "s"}`;
|
|
1175
|
+
}
|
|
1176
|
+
else if (event.type === "tool_execution_end") {
|
|
1177
|
+
this.#runningToolCallIds.delete(event.result.toolCallId);
|
|
1178
|
+
this.#finishToolResult(event.result);
|
|
1179
|
+
this.#statusText =
|
|
1180
|
+
this.#runningToolCallIds.size === 0
|
|
1181
|
+
? "Working"
|
|
1182
|
+
: `Running ${this.#runningToolCallIds.size} tool${this.#runningToolCallIds.size === 1 ? "" : "s"}`;
|
|
1183
|
+
}
|
|
1184
|
+
else if (event.type === "tool_execution_progress") {
|
|
1185
|
+
const entry = this.#entries.find((candidate) => candidate.id === event.toolCallId);
|
|
1186
|
+
if (entry !== undefined)
|
|
1187
|
+
entry.detail = this.#singleLine(event.display);
|
|
1188
|
+
}
|
|
865
1189
|
else if (event.type === "done") {
|
|
866
1190
|
this.#statusText = event.reason === "toolUse" ? "Running tools" : "Idle";
|
|
867
1191
|
}
|
|
@@ -925,7 +1249,7 @@ export class CodingAssistantApp {
|
|
|
925
1249
|
this.#appendEntry({
|
|
926
1250
|
id: block.id,
|
|
927
1251
|
role: "tool",
|
|
928
|
-
title: block.name,
|
|
1252
|
+
title: this.#toolDisplayName(block.name),
|
|
929
1253
|
text: this.#formatToolCall(block.name, block.arguments),
|
|
930
1254
|
});
|
|
931
1255
|
}
|
|
@@ -999,14 +1323,14 @@ export class CodingAssistantApp {
|
|
|
999
1323
|
}
|
|
1000
1324
|
#finishToolCall(contentIndex, toolCall) {
|
|
1001
1325
|
this.#seenToolCallIds.add(toolCall.id);
|
|
1002
|
-
this.#statusText = `Calling ${toolCall.name}`;
|
|
1326
|
+
this.#statusText = `Calling ${this.#toolDisplayName(toolCall.name)}`;
|
|
1003
1327
|
const existingId = this.#toolCallEntryIdsByContentIndex.get(contentIndex);
|
|
1004
1328
|
const existing = existingId === undefined
|
|
1005
1329
|
? undefined
|
|
1006
1330
|
: this.#entries.find((entry) => entry.id === existingId);
|
|
1007
1331
|
if (existing !== undefined) {
|
|
1008
1332
|
existing.id = toolCall.id;
|
|
1009
|
-
existing.title = toolCall.name;
|
|
1333
|
+
existing.title = this.#toolDisplayName(toolCall.name);
|
|
1010
1334
|
existing.text = this.#formatToolCall(toolCall.name, toolCall.arguments);
|
|
1011
1335
|
this.#toolCallEntryIdsByContentIndex.delete(contentIndex);
|
|
1012
1336
|
return;
|
|
@@ -1015,7 +1339,7 @@ export class CodingAssistantApp {
|
|
|
1015
1339
|
this.#appendEntry({
|
|
1016
1340
|
id: toolCall.id,
|
|
1017
1341
|
role: "tool",
|
|
1018
|
-
title: toolCall.name,
|
|
1342
|
+
title: this.#toolDisplayName(toolCall.name),
|
|
1019
1343
|
text: this.#formatToolCall(toolCall.name, toolCall.arguments),
|
|
1020
1344
|
});
|
|
1021
1345
|
}
|
|
@@ -1124,6 +1448,9 @@ export class CodingAssistantApp {
|
|
|
1124
1448
|
return this.#renderAutocomplete(width, suggestions, selectedIndex);
|
|
1125
1449
|
}
|
|
1126
1450
|
const parts = [`${FOOTER_MODEL_FG}${this.#modelWithReasoningDisplayName()}${RESET}`];
|
|
1451
|
+
if (this.#running) {
|
|
1452
|
+
parts.push(`${FOOTER_QUEUED_FG}Enter steers · Tab queues${RESET}`);
|
|
1453
|
+
}
|
|
1127
1454
|
parts.push(`${FOOTER_CWD_FG}${this.#cwdDisplayName()}${RESET}`);
|
|
1128
1455
|
if (this.#pendingPrompts.length > 0) {
|
|
1129
1456
|
parts.push(`${FOOTER_QUEUED_FG}queued ${this.#pendingPrompts.length}${RESET}`);
|
|
@@ -1131,6 +1458,15 @@ export class CodingAssistantApp {
|
|
|
1131
1458
|
const line = `${" ".repeat(visibleWidth(INPUT_PROMPT))}${parts.join(`${DIM} • ${RESET}`)}`;
|
|
1132
1459
|
return [this.#fitLine(line, width)];
|
|
1133
1460
|
}
|
|
1461
|
+
#renderQueuedPrompts(width) {
|
|
1462
|
+
return this.#pendingPrompts.flatMap((prompt) => {
|
|
1463
|
+
const prefix = `${DIM}↳ queued${RESET} `;
|
|
1464
|
+
const prefixWidth = visibleWidth(prefix);
|
|
1465
|
+
const wrapped = wrapTextWithAnsi(prompt.displayText, Math.max(1, width - prefixWidth)).slice(0, 3);
|
|
1466
|
+
const indent = " ".repeat(prefixWidth);
|
|
1467
|
+
return wrapped.map((line, index) => this.#fitLine(`${index === 0 ? prefix : indent}${DIM}${line}${RESET}`, width));
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1134
1470
|
#renderAutocomplete(width, suggestions, selectedIndex, maxVisible = AUTOCOMPLETE_MAX_VISIBLE) {
|
|
1135
1471
|
const rowWidth = Math.max(1, width - 1);
|
|
1136
1472
|
const visibleCount = Math.max(1, Math.min(maxVisible, AUTOCOMPLETE_MAX_VISIBLE));
|
|
@@ -1295,6 +1631,221 @@ export class CodingAssistantApp {
|
|
|
1295
1631
|
});
|
|
1296
1632
|
this.#showSelectionPanel(panel);
|
|
1297
1633
|
}
|
|
1634
|
+
#openPermissionsMenu() {
|
|
1635
|
+
const panel = createSelectionPanel({
|
|
1636
|
+
title: "Choose Permissions",
|
|
1637
|
+
subtitle: "Applies to this session and its subagents",
|
|
1638
|
+
selectedValue: this.#agent.permissionMode,
|
|
1639
|
+
items: [
|
|
1640
|
+
{
|
|
1641
|
+
value: "auto",
|
|
1642
|
+
label: "Auto",
|
|
1643
|
+
description: "Automatically review risky actions; ask only when needed.",
|
|
1644
|
+
},
|
|
1645
|
+
{
|
|
1646
|
+
value: "workspace_write",
|
|
1647
|
+
label: "Workspace write",
|
|
1648
|
+
description: "Write in the workspace; block shell network access.",
|
|
1649
|
+
},
|
|
1650
|
+
{
|
|
1651
|
+
value: "read_only",
|
|
1652
|
+
label: "Read only",
|
|
1653
|
+
description: "Keep project files read only; allow temporary files.",
|
|
1654
|
+
},
|
|
1655
|
+
{
|
|
1656
|
+
value: "full_access",
|
|
1657
|
+
label: "Full access",
|
|
1658
|
+
description: "Allow unrestricted filesystem, shell, and network access.",
|
|
1659
|
+
},
|
|
1660
|
+
],
|
|
1661
|
+
onSelect: (item) => {
|
|
1662
|
+
const mode = item.value;
|
|
1663
|
+
this.#agent.setPermissionMode(mode);
|
|
1664
|
+
if (!this.#sessionBacked) {
|
|
1665
|
+
this.#appendEntry({
|
|
1666
|
+
role: "event",
|
|
1667
|
+
title: "permissions",
|
|
1668
|
+
text: `Permissions changed to ${humanizePermissionMode(mode)}.`,
|
|
1669
|
+
});
|
|
1670
|
+
}
|
|
1671
|
+
this.#closeSelectionPanel();
|
|
1672
|
+
this.#requestRender();
|
|
1673
|
+
},
|
|
1674
|
+
onCancel: () => this.#closeSelectionPanel(),
|
|
1675
|
+
});
|
|
1676
|
+
this.#showSelectionPanel(panel);
|
|
1677
|
+
}
|
|
1678
|
+
#enqueueUserInputRequest(request) {
|
|
1679
|
+
if (this.#userInputRequests.some((candidate) => candidate.requestId === request.requestId)) {
|
|
1680
|
+
return;
|
|
1681
|
+
}
|
|
1682
|
+
this.#userInputRequests.push(request);
|
|
1683
|
+
this.#openNextUserInputRequest();
|
|
1684
|
+
}
|
|
1685
|
+
#openNextUserInputRequest() {
|
|
1686
|
+
if (this.#activeUserInput !== undefined ||
|
|
1687
|
+
this.#answeringUserInputRequestId !== undefined ||
|
|
1688
|
+
this.#freeformUserInput !== undefined) {
|
|
1689
|
+
return;
|
|
1690
|
+
}
|
|
1691
|
+
const request = this.#userInputRequests[0];
|
|
1692
|
+
if (request === undefined)
|
|
1693
|
+
return;
|
|
1694
|
+
this.#activeUserInput = {
|
|
1695
|
+
answers: {},
|
|
1696
|
+
questionIndex: 0,
|
|
1697
|
+
request,
|
|
1698
|
+
selected: new Set(),
|
|
1699
|
+
};
|
|
1700
|
+
this.#openUserInputQuestion();
|
|
1701
|
+
}
|
|
1702
|
+
#openUserInputQuestion() {
|
|
1703
|
+
const active = this.#activeUserInput;
|
|
1704
|
+
const question = active?.request.questions[active.questionIndex];
|
|
1705
|
+
if (active === undefined || question === undefined)
|
|
1706
|
+
return;
|
|
1707
|
+
const items = question.options.map((option, index) => ({
|
|
1708
|
+
value: `option:${index}`,
|
|
1709
|
+
label: active.selected.has(option.label) ? `✓ ${option.label}` : option.label,
|
|
1710
|
+
description: option.description,
|
|
1711
|
+
}));
|
|
1712
|
+
if (question.multiSelect && active.selected.size > 0) {
|
|
1713
|
+
items.push({
|
|
1714
|
+
value: "done",
|
|
1715
|
+
label: "Done",
|
|
1716
|
+
description: `Submit ${active.selected.size} selected answer${active.selected.size === 1 ? "" : "s"}.`,
|
|
1717
|
+
});
|
|
1718
|
+
}
|
|
1719
|
+
items.push({
|
|
1720
|
+
value: "other",
|
|
1721
|
+
label: "Type another answer",
|
|
1722
|
+
description: "Enter a response that is not listed.",
|
|
1723
|
+
});
|
|
1724
|
+
this.#showSelectionPanel(createSelectionPanel({
|
|
1725
|
+
title: question.header,
|
|
1726
|
+
subtitle: `${question.question} · ${active.questionIndex + 1} of ${active.request.questions.length}`,
|
|
1727
|
+
items,
|
|
1728
|
+
onSelect: (item) => {
|
|
1729
|
+
if (item.value === "other") {
|
|
1730
|
+
this.#freeformUserInput = {
|
|
1731
|
+
existingAnswers: [...active.selected],
|
|
1732
|
+
questionId: question.id,
|
|
1733
|
+
requestId: active.request.requestId,
|
|
1734
|
+
};
|
|
1735
|
+
this.#closeSelectionPanel();
|
|
1736
|
+
this.#editor.setText("");
|
|
1737
|
+
this.#requestRender();
|
|
1738
|
+
return;
|
|
1739
|
+
}
|
|
1740
|
+
if (item.value === "done") {
|
|
1741
|
+
this.#commitUserInputAnswer([...active.selected]);
|
|
1742
|
+
return;
|
|
1743
|
+
}
|
|
1744
|
+
const optionIndex = Number.parseInt(item.value.slice("option:".length), 10);
|
|
1745
|
+
const option = question.options[optionIndex];
|
|
1746
|
+
if (option === undefined)
|
|
1747
|
+
return;
|
|
1748
|
+
if (!question.multiSelect) {
|
|
1749
|
+
this.#commitUserInputAnswer([option.label]);
|
|
1750
|
+
return;
|
|
1751
|
+
}
|
|
1752
|
+
if (active.selected.has(option.label))
|
|
1753
|
+
active.selected.delete(option.label);
|
|
1754
|
+
else
|
|
1755
|
+
active.selected.add(option.label);
|
|
1756
|
+
this.#openUserInputQuestion();
|
|
1757
|
+
this.#requestRender();
|
|
1758
|
+
},
|
|
1759
|
+
onCancel: () => {
|
|
1760
|
+
this.#closeSelectionPanel();
|
|
1761
|
+
this.#handleEscape();
|
|
1762
|
+
},
|
|
1763
|
+
}));
|
|
1764
|
+
this.#requestRender();
|
|
1765
|
+
}
|
|
1766
|
+
#commitUserInputAnswer(answers) {
|
|
1767
|
+
const active = this.#activeUserInput;
|
|
1768
|
+
const question = active?.request.questions[active.questionIndex];
|
|
1769
|
+
if (active === undefined || question === undefined || answers.length === 0)
|
|
1770
|
+
return;
|
|
1771
|
+
active.answers[question.id] = [...answers];
|
|
1772
|
+
active.questionIndex += 1;
|
|
1773
|
+
active.selected = new Set();
|
|
1774
|
+
if (active.questionIndex < active.request.questions.length) {
|
|
1775
|
+
this.#openUserInputQuestion();
|
|
1776
|
+
return;
|
|
1777
|
+
}
|
|
1778
|
+
this.#sendUserInputResponse(active.request, { answers: active.answers });
|
|
1779
|
+
}
|
|
1780
|
+
#submitFreeformUserInput(value) {
|
|
1781
|
+
const answer = value.trim();
|
|
1782
|
+
const freeform = this.#freeformUserInput;
|
|
1783
|
+
const active = this.#activeUserInput;
|
|
1784
|
+
if (answer.length === 0 || freeform === undefined || active === undefined)
|
|
1785
|
+
return;
|
|
1786
|
+
if (active.request.requestId !== freeform.requestId)
|
|
1787
|
+
return;
|
|
1788
|
+
if (active.request.questions[active.questionIndex]?.id !== freeform.questionId)
|
|
1789
|
+
return;
|
|
1790
|
+
this.#freeformUserInput = undefined;
|
|
1791
|
+
this.#editor.setText("");
|
|
1792
|
+
this.#commitUserInputAnswer([...freeform.existingAnswers, answer]);
|
|
1793
|
+
this.#requestRender();
|
|
1794
|
+
}
|
|
1795
|
+
#sendUserInputResponse(request, response) {
|
|
1796
|
+
this.#activeUserInput = undefined;
|
|
1797
|
+
this.#closeSelectionPanel();
|
|
1798
|
+
if (this.#respondUserInput === undefined) {
|
|
1799
|
+
this.#appendEntry({
|
|
1800
|
+
role: "error",
|
|
1801
|
+
text: "This client cannot send interactive answers.",
|
|
1802
|
+
});
|
|
1803
|
+
this.#removeUserInputRequest(request.requestId);
|
|
1804
|
+
this.#handleEscape();
|
|
1805
|
+
return;
|
|
1806
|
+
}
|
|
1807
|
+
this.#answeringUserInputRequestId = request.requestId;
|
|
1808
|
+
void Promise.resolve(this.#respondUserInput(request.requestId, response))
|
|
1809
|
+
.then(() => this.#removeUserInputRequest(request.requestId))
|
|
1810
|
+
.catch((error) => {
|
|
1811
|
+
this.#answeringUserInputRequestId = undefined;
|
|
1812
|
+
this.#appendEntry({
|
|
1813
|
+
role: "error",
|
|
1814
|
+
text: `The answer could not be sent: ${this.#formatError(error)}`,
|
|
1815
|
+
});
|
|
1816
|
+
this.#openNextUserInputRequest();
|
|
1817
|
+
this.#requestRender();
|
|
1818
|
+
});
|
|
1819
|
+
}
|
|
1820
|
+
#removeUserInputRequest(requestId) {
|
|
1821
|
+
const wasActive = this.#activeUserInput?.request.requestId === requestId;
|
|
1822
|
+
const wasFreeform = this.#freeformUserInput?.requestId === requestId;
|
|
1823
|
+
this.#userInputRequests = this.#userInputRequests.filter((request) => request.requestId !== requestId);
|
|
1824
|
+
if (wasActive)
|
|
1825
|
+
this.#activeUserInput = undefined;
|
|
1826
|
+
if (wasFreeform) {
|
|
1827
|
+
this.#freeformUserInput = undefined;
|
|
1828
|
+
this.#editor.setText("");
|
|
1829
|
+
}
|
|
1830
|
+
if (this.#answeringUserInputRequestId === requestId) {
|
|
1831
|
+
this.#answeringUserInputRequestId = undefined;
|
|
1832
|
+
}
|
|
1833
|
+
if (wasActive || wasFreeform)
|
|
1834
|
+
this.#closeSelectionPanel();
|
|
1835
|
+
this.#openNextUserInputRequest();
|
|
1836
|
+
this.#requestRender();
|
|
1837
|
+
}
|
|
1838
|
+
#clearUserInputRequests() {
|
|
1839
|
+
const hadVisibleRequest = this.#activeUserInput !== undefined || this.#freeformUserInput !== undefined;
|
|
1840
|
+
this.#userInputRequests = [];
|
|
1841
|
+
this.#activeUserInput = undefined;
|
|
1842
|
+
this.#answeringUserInputRequestId = undefined;
|
|
1843
|
+
if (this.#freeformUserInput !== undefined)
|
|
1844
|
+
this.#editor.setText("");
|
|
1845
|
+
this.#freeformUserInput = undefined;
|
|
1846
|
+
if (hadVisibleRequest)
|
|
1847
|
+
this.#closeSelectionPanel();
|
|
1848
|
+
}
|
|
1298
1849
|
#showSelectionPanel(component) {
|
|
1299
1850
|
this.#selectionPanel = component;
|
|
1300
1851
|
}
|
|
@@ -1316,6 +1867,9 @@ export class CodingAssistantApp {
|
|
|
1316
1867
|
const editorWidth = Math.max(1, width - promptWidth);
|
|
1317
1868
|
const contentLines = this.#stripSpuriousLeadingEmptyLine(this.#stripEditorChrome(this.#editor.render(editorWidth)));
|
|
1318
1869
|
return contentLines.map((line, index) => {
|
|
1870
|
+
if (this.#isEditorScrollIndicator(line)) {
|
|
1871
|
+
return this.#inputSurfaceLine(`${INPUT_LINE_INDENT}${DIM}${line}${RESET}`, width);
|
|
1872
|
+
}
|
|
1319
1873
|
const prefix = index === 0 ? this.#inputPrompt() : INPUT_LINE_INDENT;
|
|
1320
1874
|
const rendered = `${prefix}${this.#styleImagePlaceholders(line)}`;
|
|
1321
1875
|
return this.#inputSurfaceLine(this.#cursorVisible ? rendered : this.#hideCursor(rendered), width);
|
|
@@ -1326,15 +1880,15 @@ export class CodingAssistantApp {
|
|
|
1326
1880
|
const detail = this.#formatToolResult(block);
|
|
1327
1881
|
if (existing !== undefined) {
|
|
1328
1882
|
existing.role = block.isError ? "error" : "tool";
|
|
1329
|
-
existing.title = block.toolName;
|
|
1883
|
+
existing.title = this.#toolDisplayName(block.toolName);
|
|
1330
1884
|
existing.detail = detail;
|
|
1331
1885
|
return;
|
|
1332
1886
|
}
|
|
1333
1887
|
this.#appendEntry({
|
|
1334
1888
|
id: block.toolCallId,
|
|
1335
1889
|
role: block.isError ? "error" : "tool",
|
|
1336
|
-
title: block.toolName,
|
|
1337
|
-
text: block.toolName,
|
|
1890
|
+
title: this.#toolDisplayName(block.toolName),
|
|
1891
|
+
text: this.#toolDisplayName(block.toolName),
|
|
1338
1892
|
detail,
|
|
1339
1893
|
});
|
|
1340
1894
|
}
|
|
@@ -1345,6 +1899,14 @@ export class CodingAssistantApp {
|
|
|
1345
1899
|
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
1346
1900
|
};
|
|
1347
1901
|
const normalized = toolName.toLowerCase();
|
|
1902
|
+
if (normalized === "request_user_input" || normalized === "askuserquestion") {
|
|
1903
|
+
const questions = record.questions;
|
|
1904
|
+
const firstQuestion = Array.isArray(questions) ? questions[0] : undefined;
|
|
1905
|
+
if (this.#isRecord(firstQuestion) && typeof firstQuestion.question === "string") {
|
|
1906
|
+
return this.#singleLine(firstQuestion.question);
|
|
1907
|
+
}
|
|
1908
|
+
return "Waiting for your answer";
|
|
1909
|
+
}
|
|
1348
1910
|
const command = stringField("cmd") ?? stringField("command");
|
|
1349
1911
|
if (command !== undefined) {
|
|
1350
1912
|
return this.#singleLine(command);
|
|
@@ -1367,7 +1929,43 @@ export class CodingAssistantApp {
|
|
|
1367
1929
|
? `${todos.length} todo${todos.length === 1 ? "" : "s"}`
|
|
1368
1930
|
: "todos";
|
|
1369
1931
|
}
|
|
1370
|
-
|
|
1932
|
+
if (normalized === "taskcreate") {
|
|
1933
|
+
return stringField("subject") ?? "Create task";
|
|
1934
|
+
}
|
|
1935
|
+
if (normalized === "taskget") {
|
|
1936
|
+
const taskId = stringField("taskId");
|
|
1937
|
+
return taskId === undefined ? "Read task" : `Read task ${taskId}`;
|
|
1938
|
+
}
|
|
1939
|
+
if (normalized === "taskupdate") {
|
|
1940
|
+
const taskId = stringField("taskId");
|
|
1941
|
+
return taskId === undefined ? "Update task" : `Update task ${taskId}`;
|
|
1942
|
+
}
|
|
1943
|
+
if (normalized === "tasklist")
|
|
1944
|
+
return "Current tasks";
|
|
1945
|
+
if (normalized === "agent") {
|
|
1946
|
+
return stringField("description") ?? "Delegated work";
|
|
1947
|
+
}
|
|
1948
|
+
if (normalized === "spawn_agent") {
|
|
1949
|
+
const taskName = stringField("task_name");
|
|
1950
|
+
return taskName === undefined
|
|
1951
|
+
? "Start delegated work"
|
|
1952
|
+
: taskName
|
|
1953
|
+
.replaceAll("_", " ")
|
|
1954
|
+
.replace(/^./u, (character) => character.toUpperCase());
|
|
1955
|
+
}
|
|
1956
|
+
if (normalized === "followup_task" || normalized === "sendmessage") {
|
|
1957
|
+
return stringField("summary") ?? "Send follow-up work";
|
|
1958
|
+
}
|
|
1959
|
+
if (normalized === "wait_agent")
|
|
1960
|
+
return "Wait for delegated work";
|
|
1961
|
+
if (normalized === "list_agents")
|
|
1962
|
+
return "Show delegated work";
|
|
1963
|
+
if (normalized === "interrupt_agent")
|
|
1964
|
+
return "Stop delegated work";
|
|
1965
|
+
return this.#toolDisplayName(toolName);
|
|
1966
|
+
}
|
|
1967
|
+
#toolDisplayName(toolName) {
|
|
1968
|
+
return humanizeToolName(toolName);
|
|
1371
1969
|
}
|
|
1372
1970
|
#formatToolResult(block) {
|
|
1373
1971
|
return this.#singleLine(block.display.length > 0 ? block.display : "(empty result)");
|
|
@@ -1454,9 +2052,7 @@ export class CodingAssistantApp {
|
|
|
1454
2052
|
if (!isError &&
|
|
1455
2053
|
entry.title === PENDING_TOOL_CALL_TITLE &&
|
|
1456
2054
|
entry.text === PENDING_TOOL_CALL_TITLE) {
|
|
1457
|
-
return [
|
|
1458
|
-
this.#fitLine(`${DIM}•${RESET} ${renderActivityWave(PENDING_TOOL_CALL_TITLE, this.#activityAnimationFrame)}`, width),
|
|
1459
|
-
];
|
|
2055
|
+
return [this.#fitLine(`${DIM}• ${PENDING_TOOL_CALL_TITLE}${RESET}`, width)];
|
|
1460
2056
|
}
|
|
1461
2057
|
const toolName = entry.title ?? "tool";
|
|
1462
2058
|
const verb = isError ? "Failed" : this.#toolVerb(toolName);
|
|
@@ -1481,12 +2077,13 @@ export class CodingAssistantApp {
|
|
|
1481
2077
|
return wrapped.map((line, index) => this.#fitLine(`${index === 0 ? prefix : indent}${line}`, width));
|
|
1482
2078
|
}
|
|
1483
2079
|
#emptyInputLine() {
|
|
2080
|
+
const placeholder = this.#freeformUserInput === undefined ? INPUT_PLACEHOLDER : "Type another answer";
|
|
1484
2081
|
const marker = this.#focused ? CURSOR_MARKER : "";
|
|
1485
2082
|
if (!this.#focused || !this.#cursorVisible) {
|
|
1486
|
-
return `${this.#inputPrompt()}${marker}${SURFACE_MUTED_FG}${
|
|
2083
|
+
return `${this.#inputPrompt()}${marker}${SURFACE_MUTED_FG}${placeholder}${INPUT_FG}`;
|
|
1487
2084
|
}
|
|
1488
|
-
const firstCharacter =
|
|
1489
|
-
const rest =
|
|
2085
|
+
const firstCharacter = placeholder[0] ?? " ";
|
|
2086
|
+
const rest = placeholder.slice(firstCharacter.length);
|
|
1490
2087
|
return `${this.#inputPrompt()}${marker}${CURSOR_BG}${CURSOR_FG}${firstCharacter}${RESET}${SURFACE_MUTED_FG}${rest}${INPUT_FG}`;
|
|
1491
2088
|
}
|
|
1492
2089
|
#surfaceLine(line, width) {
|
|
@@ -1532,21 +2129,14 @@ export class CodingAssistantApp {
|
|
|
1532
2129
|
return this.#statusText;
|
|
1533
2130
|
}
|
|
1534
2131
|
#shouldRenderActivityAsLastMessage() {
|
|
1535
|
-
|
|
1536
|
-
return false;
|
|
1537
|
-
}
|
|
1538
|
-
const lastEntry = this.#entries.at(-1);
|
|
1539
|
-
return (lastEntry === undefined ||
|
|
1540
|
-
lastEntry.role === "separator" ||
|
|
1541
|
-
lastEntry.role === "user" ||
|
|
1542
|
-
lastEntry.role === "system" ||
|
|
1543
|
-
(lastEntry.role === "thinking" && !this.#showReasoning));
|
|
2132
|
+
return this.#running || this.#compacting;
|
|
1544
2133
|
}
|
|
1545
2134
|
#renderActivityLine(label, width) {
|
|
1546
2135
|
const prefix = `${RIG_ORANGE}•${RESET} `;
|
|
1547
2136
|
const frame = this.#activityAnimationFrame;
|
|
1548
2137
|
const elapsed = this.#activityElapsedText();
|
|
1549
|
-
const
|
|
2138
|
+
const elapsedText = elapsed ?? "0s";
|
|
2139
|
+
const elapsedSuffix = ` ${DIM}${SURFACE_MUTED_FG}(${elapsedText} • Esc to interrupt)${RESET}`;
|
|
1550
2140
|
return [
|
|
1551
2141
|
this.#fitLine(`${prefix}${renderActivityWave(label, frame)}${elapsedSuffix}`, width),
|
|
1552
2142
|
];
|
|
@@ -1819,7 +2409,7 @@ export class CodingAssistantApp {
|
|
|
1819
2409
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1820
2410
|
}
|
|
1821
2411
|
#singleLine(text) {
|
|
1822
|
-
return text.replace(/\s+/gu, " ").trim();
|
|
2412
|
+
return sanitizeTerminalText(text).replace(/\s+/gu, " ").trim();
|
|
1823
2413
|
}
|
|
1824
2414
|
#markTypingActivity() {
|
|
1825
2415
|
this.#cursorTyping = true;
|
|
@@ -1841,7 +2431,11 @@ export class CodingAssistantApp {
|
|
|
1841
2431
|
while (content.length > 0 && this.#isEditorBorderLine(content[content.length - 1] ?? "")) {
|
|
1842
2432
|
content = content.slice(0, -1);
|
|
1843
2433
|
}
|
|
1844
|
-
return content.filter((line) => !
|
|
2434
|
+
return content.filter((line) => !this.#isEditorBorderLine(line));
|
|
2435
|
+
}
|
|
2436
|
+
#isEditorScrollIndicator(line) {
|
|
2437
|
+
const stripped = line.replace(/\x1b\[[0-9;]*m/g, "");
|
|
2438
|
+
return stripped.includes(" more ") && (stripped.includes("↑") || stripped.includes("↓"));
|
|
1845
2439
|
}
|
|
1846
2440
|
#isEditorBorderLine(line) {
|
|
1847
2441
|
const stripped = line.replace(/\x1b\[[0-9;]*m/g, "");
|
|
@@ -1901,7 +2495,7 @@ export class CodingAssistantApp {
|
|
|
1901
2495
|
}
|
|
1902
2496
|
this.#activityAnimationFrame =
|
|
1903
2497
|
(this.#activityAnimationFrame + 1) % ACTIVITY_WAVE_FRAME_COUNT;
|
|
1904
|
-
if (this.#activityText() !== undefined
|
|
2498
|
+
if (this.#activityText() !== undefined) {
|
|
1905
2499
|
this.#requestRender();
|
|
1906
2500
|
}
|
|
1907
2501
|
}, ACTIVITY_ANIMATION_MS);
|
|
@@ -1928,4 +2522,43 @@ export class CodingAssistantApp {
|
|
|
1928
2522
|
setTimeout(resolve, 25);
|
|
1929
2523
|
});
|
|
1930
2524
|
}
|
|
2525
|
+
#handleCtrlC() {
|
|
2526
|
+
if (this.#editor.getText().length > 0) {
|
|
2527
|
+
this.#editor.setText("");
|
|
2528
|
+
this.#fileMentionAutocomplete?.clear();
|
|
2529
|
+
this.#dismissedSlashCommandText = undefined;
|
|
2530
|
+
this.#pastedImagesById.clear();
|
|
2531
|
+
this.#requestRender();
|
|
2532
|
+
return;
|
|
2533
|
+
}
|
|
2534
|
+
if (this.#abortActiveRun())
|
|
2535
|
+
return;
|
|
2536
|
+
void this.stop();
|
|
2537
|
+
}
|
|
2538
|
+
#queueCurrentInput() {
|
|
2539
|
+
const submission = this.#createPromptSubmission(this.#editor.getText());
|
|
2540
|
+
if (submission === undefined)
|
|
2541
|
+
return false;
|
|
2542
|
+
this.#editor.setText("");
|
|
2543
|
+
this.#fileMentionAutocomplete?.clear();
|
|
2544
|
+
this.#modelLocked = true;
|
|
2545
|
+
this.#pendingPrompts.push(submission);
|
|
2546
|
+
this.#requestRender();
|
|
2547
|
+
return true;
|
|
2548
|
+
}
|
|
2549
|
+
#setTerminalFocused(focused) {
|
|
2550
|
+
if (this.#terminalFocused === focused)
|
|
2551
|
+
return;
|
|
2552
|
+
this.#terminalFocused = focused;
|
|
2553
|
+
this.#editor.focused = this.#focused && focused;
|
|
2554
|
+
if (focused && this.#focused) {
|
|
2555
|
+
this.#cursorVisible = true;
|
|
2556
|
+
this.#startCursorBlink();
|
|
2557
|
+
}
|
|
2558
|
+
else {
|
|
2559
|
+
this.#stopCursorBlink();
|
|
2560
|
+
this.#cursorVisible = false;
|
|
2561
|
+
}
|
|
2562
|
+
this.#requestRender();
|
|
2563
|
+
}
|
|
1931
2564
|
}
|