背景
当前 ClawPal 里 SSH 相关逻辑分散在多个层(UI/Tauri/core/install/doctor)。用户遇到连接失败时,报错常常是“点状”的:某一步失败但缺少统一诊断链路,导致修复建议不一致、重复重试成本高。
目标:抽象一个统一的 SSH Diagnostic & Repair Layer,让所有 SSH 入口共享同一套“分层诊断 + 可执行修复建议 + 错误码语义”。
一、调研结果:哪些环节依赖 SSH
1) 连接与会话生命周期(基础层)
src-tauri/src/commands/mod.rs
ssh_connect
ssh_connect_with_passphrase
ssh_disconnect
ssh_status
ssh_exec
src-tauri/src/ssh.rs
- 连接池/重连/并发控制/semaphore
exec / sftp_read / sftp_write / sftp_remove
2) 实例接入与管理
connect_ssh_instance(实例级接入)
- SSH Host registry CRUD:
list_ssh_hosts / upsert_ssh_host / delete_ssh_host
clawpal-core/src/ssh/registry.rs, clawpal-core/src/instance.rs
3) 安装与初始化流程(高频失败点)
src-tauri/src/install/commands.rs
run_remote_ssh_step(...)
- precheck/install/init/verify 阶段均通过 SSH 执行远端命令
4) Doctor 远端诊断与修复
src-tauri/src/doctor_commands.rs
collect_doctor_context_remote
doctor file/config/... 远端读写与执行
- openclaw path 修复、远端日志抓取、gateway 状态探测等
5) 健康检查/轮询
clawpal-core/src/health.rs
- remote ssh health check 依赖 ssh command
- 前端自动轮询(Start/Home)会触发远端状态请求,间接打到 SSH
6) 前端交互与错误提示
src/App.tsx 内有 SSH_ERROR_MAP(字符串正则映射)
- 多处页面(Start/Doctor/Home)有“重连/检查/提示”逻辑
- 目前前后端错误语义尚未统一(regex 文案驱动为主)
二、核心问题
- 诊断逻辑分散:连接失败、认证失败、主机指纹、远端命令失败等分散处理。
- 错误语义不统一:前端 regex + 后端原始错误混杂,缺少稳定错误码。
- 修复建议不可复用:同类错误在 install/doctor/connect 场景下提示不一致。
- 重试策略不一致:有的环节自动重连,有的直接失败;缺少统一 backoff 策略。
- 可观测性弱:缺少跨模块、分阶段的 SSH 诊断事件和统计。
三、设计:SSH Diagnostic & Repair Layer
3.1 新增统一领域模型(建议放 clawpal-core/src/ssh/diagnostic.rs)
SshDiagnosticReport {
stage: SshStage,
status: ok | degraded | failed,
errorCode: Option<SshErrorCode>,
summary: String,
evidence: Vec<SshEvidence>,
repairPlan: Vec<SshRepairAction>,
confidence: f32,
}
SshStage(建议)
ResolveHostConfig
TcpReachability
HostKeyVerification
AuthNegotiation
SessionOpen
RemoteExec
SftpRead
SftpWrite
SftpRemove
SshErrorCode(稳定枚举)
SSH_HOST_UNREACHABLE
SSH_CONNECTION_REFUSED
SSH_TIMEOUT
SSH_HOST_KEY_FAILED
SSH_KEYFILE_MISSING
SSH_PASSPHRASE_REQUIRED
SSH_AUTH_FAILED
SSH_REMOTE_COMMAND_FAILED
SSH_SFTP_PERMISSION_DENIED
SSH_SESSION_STALE
SSH_UNKNOWN
3.2 统一诊断入口
新增接口(core 或 tauri facade):
diagnose_ssh(host_id, intent)
- intent:
connect | exec | sftp_read | sftp_write | install_step | doctor_remote
输出统一 SshDiagnosticReport,上层不再直接拼接散乱字符串。
3.3 修复动作抽象(可执行计划)
SshRepairAction 示例:
PromptPassphrase
RetryWithBackoff
SwitchAuthMethodToSshConfig
SuggestKnownHostsBootstrap(先手动 ssh 一次确认 host key)
SuggestAuthorizedKeysCheck
SuggestPortHostValidation
ReconnectSession
注意:默认只给建议,不做高风险自动修改(authorized_keys/sshd_config)。
3.4 与现有模块集成方式
ssh_connect* / ssh_exec / sftp_*:失败时统一转换为 SshDiagnosticReport
install/commands.rs:每个 remote step 附带 ssh 诊断上下文
doctor_commands.rs:远端诊断输出叠加 sshDiagnostic
App.tsx:由 errorCode -> i18n,逐步替换 regex 文案映射
3.5 事件与可观测性
新增事件(建议):
ssh:diagnostic
ssh:repair-suggested
ssh:repair-applied(若后续支持自动修复)
指标:
- ssh 失败按 stage/errorCode 分布
- 首次修复成功率
- 连接建立耗时 / 重试次数
四、实施拆解
Phase 0:模型与兼容层
Phase 1:连接链路接入
Phase 2:SFTP/命令执行接入
Phase 3:Install + Doctor 接入
Phase 4:前端语义统一
Phase 5:测试与CI
五、验收标准
预期收益
- 降低 SSH 相关排障时间
- 提升 install + doctor 场景的修复成功率
- 为后续“自动修复(受控)”打基础
背景
当前 ClawPal 里 SSH 相关逻辑分散在多个层(UI/Tauri/core/install/doctor)。用户遇到连接失败时,报错常常是“点状”的:某一步失败但缺少统一诊断链路,导致修复建议不一致、重复重试成本高。
目标:抽象一个统一的 SSH Diagnostic & Repair Layer,让所有 SSH 入口共享同一套“分层诊断 + 可执行修复建议 + 错误码语义”。
一、调研结果:哪些环节依赖 SSH
1) 连接与会话生命周期(基础层)
src-tauri/src/commands/mod.rsssh_connectssh_connect_with_passphrasessh_disconnectssh_statusssh_execsrc-tauri/src/ssh.rsexec/sftp_read/sftp_write/sftp_remove2) 实例接入与管理
connect_ssh_instance(实例级接入)list_ssh_hosts/upsert_ssh_host/delete_ssh_hostclawpal-core/src/ssh/registry.rs,clawpal-core/src/instance.rs3) 安装与初始化流程(高频失败点)
src-tauri/src/install/commands.rsrun_remote_ssh_step(...)4) Doctor 远端诊断与修复
src-tauri/src/doctor_commands.rscollect_doctor_context_remotedoctor file/config/...远端读写与执行5) 健康检查/轮询
clawpal-core/src/health.rs6) 前端交互与错误提示
src/App.tsx内有SSH_ERROR_MAP(字符串正则映射)二、核心问题
三、设计:SSH Diagnostic & Repair Layer
3.1 新增统一领域模型(建议放
clawpal-core/src/ssh/diagnostic.rs)SshStage(建议)ResolveHostConfigTcpReachabilityHostKeyVerificationAuthNegotiationSessionOpenRemoteExecSftpReadSftpWriteSftpRemoveSshErrorCode(稳定枚举)SSH_HOST_UNREACHABLESSH_CONNECTION_REFUSEDSSH_TIMEOUTSSH_HOST_KEY_FAILEDSSH_KEYFILE_MISSINGSSH_PASSPHRASE_REQUIREDSSH_AUTH_FAILEDSSH_REMOTE_COMMAND_FAILEDSSH_SFTP_PERMISSION_DENIEDSSH_SESSION_STALESSH_UNKNOWN3.2 统一诊断入口
新增接口(core 或 tauri facade):
diagnose_ssh(host_id, intent)connect | exec | sftp_read | sftp_write | install_step | doctor_remote输出统一
SshDiagnosticReport,上层不再直接拼接散乱字符串。3.3 修复动作抽象(可执行计划)
SshRepairAction示例:PromptPassphraseRetryWithBackoffSwitchAuthMethodToSshConfigSuggestKnownHostsBootstrap(先手动 ssh 一次确认 host key)SuggestAuthorizedKeysCheckSuggestPortHostValidationReconnectSession注意:默认只给建议,不做高风险自动修改(authorized_keys/sshd_config)。
3.4 与现有模块集成方式
ssh_connect*/ssh_exec/sftp_*:失败时统一转换为SshDiagnosticReportinstall/commands.rs:每个 remote step 附带 ssh 诊断上下文doctor_commands.rs:远端诊断输出叠加sshDiagnosticApp.tsx:由errorCode -> i18n,逐步替换 regex 文案映射3.5 事件与可观测性
新增事件(建议):
ssh:diagnosticssh:repair-suggestedssh:repair-applied(若后续支持自动修复)指标:
四、实施拆解
Phase 0:模型与兼容层
SshStage/SshErrorCode/SshDiagnosticReportfrom_any_error(...)适配器(兼容旧错误文本)Phase 1:连接链路接入
ssh_connect/ssh_connect_with_passphrase/ssh_status接入诊断层src-tauri/src/ssh.rs的 reconnect/exec 失败统一产出 errorCodePhase 2:SFTP/命令执行接入
sftp_read/write/remove+ssh_exec接入Phase 3:Install + Doctor 接入
run_remote_ssh_step输出结构化 ssh 诊断collect_doctor_context_remote增加sshDiagnosticPhase 4:前端语义统一
errorCode渲染Phase 5:测试与CI
五、验收标准
预期收益