Files
Termind/Frameworks/TermindRemoteInfrastructure/Agent/PlanningSSHExecRunTool.swift
T
Kaede Akino ebeb0027d4 feat(ssh)!: redesign command execution tools
Split command execution into run, output, stdin, cancel and list tools for the assistant and MCP. Preserve bounded output tails and use conversation-scoped handles and secret storage with AgentKit 1.20.0.

Add the built-in ssh-exec skill with timestamped log redirection and text/secret stdin workflows. Expand long tool output without adjacent copy controls, update localized presentation, and refresh regression coverage and the website tool name.

BREAKING CHANGE: Replace ssh_exec and ssh_wait with ssh_exec_run and ssh_exec_output. Move stdin to ssh_exec_stdin and remove execution timeout and cwd arguments. Use run_in_background to control foreground execution.
2026-10-17 12:26:48 +08:00

38 lines
1.4 KiB
Swift

import AgentKit
import Foundation
import TermindDomain
/// Planning registration for the ordinary `ssh_exec_run` identity. Destructive
/// commands never reach approval or execution in this posture.
public nonisolated struct PlanningSSHExecRunTool: AgentToolDefinition {
public static let presenter = SSHExecRunTool.presenter
private let base: SSHExecRunTool
public init(
authentication: AgentSSHAuthenticationRegistry,
pool: AgentConnectionPool,
background: AgentBackgroundCommands, scope: UUID = UUID()
) {
base = SSHExecRunTool(authentication: authentication, pool: pool, background: background, scope: scope)
}
public var descriptor: AgentToolDescriptor { base.descriptor }
public func preflight(_ invocation: AgentToolInvocation) async throws -> AgentToolPreflight {
let command = try Arguments(invocation).string("command")
guard CommandRiskClassifier.assess(command).risk == .destructive else {
return try await base.preflight(invocation)
}
return AgentToolPreflight(
invocation: invocation, approvalPolicy: .deny,
reasons: ["Planning cannot execute a destructive SSH command."]
)
}
public func execute(
_ invocation: AgentToolInvocation, context: AgentToolExecutionContext
) async throws -> AgentToolResult {
try await base.execute(invocation, context: context)
}
}