Skip to content

feat: improve SSH host UX and model profile validation#13

Merged
Keith-CY merged 6 commits intolay2dev:mainfrom
Keith-CY:develop
Feb 25, 2026
Merged

feat: improve SSH host UX and model profile validation#13
Keith-CY merged 6 commits intolay2dev:mainfrom
Keith-CY:develop

Conversation

@Keith-CY
Copy link
Copy Markdown
Collaborator

@Keith-CY Keith-CY commented Feb 24, 2026

Summary

  • improve SSH connection UX for remote hosts, including passphrase-first flow and clearer connection behavior
  • auto-detect hosts from ssh config and support faster host selection in the instance tab
  • harden SSH host management with duplicate-name validation and clearer duplicate display names
  • replace fake model profile checks with real provider probes for both local and remote profiles
  • add profile-level actions in Settings, including Test and Enable or Disable, with toast feedback
  • improve remote profile key resolution using auth_ref, remote auth-profiles, and env fallbacks
  • strengthen error handling and safety in remote probing paths, including stricter env var validation

Scope

  • backend: src-tauri/src/commands.rs, src-tauri/src/lib.rs, src-tauri/src/ssh.rs
  • frontend: src/components/InstanceTabBar.tsx, src/pages/Settings.tsx, src/lib/api.ts, src/lib/use-api.ts, src/App.tsx
  • i18n and deps: src/locales/en.json, src/locales/zh.json, package.json, bun.lockb

Source and Target

  • source: Keith-CY:develop
  • target: zhixianio/clawpal:main

@Keith-CY Keith-CY changed the title chore: sync develop branch updates feat: improve SSH host UX and model profile validation Feb 24, 2026
@Keith-CY Keith-CY marked this pull request as ready for review February 24, 2026 19:25
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ada9cb6549

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +6102 to +6105
let entries = pool
.sftp_list(host_id, "~/.openclaw/agents")
.await
.map_err(|e| format!("Failed to list remote agents directory: {e}"))?;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Treat missing remote agents dir as no auth profiles

resolve_remote_key_from_agent_auth_profiles turns any failure from listing ~/.openclaw/agents into a hard error, so remote_test_model_profile aborts before provider-env fallback can run. On remotes that don't have an agents directory (a common setup when credentials come from environment variables), profile tests will fail even when a valid fallback key like ${PROVIDER}_API_KEY is present. Missing-path errors here should be treated as Ok(None) instead of failing the whole resolution path.

Useful? React with 👍 / 👎.

std::env::temp_dir()
.join(format!("clawpal-askpass-{}.bat", uuid::Uuid::new_v4())),
);
let script = "@echo off\r\necho %CLAWPAL_SSH_PASSPHRASE%\r\n";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Escape passphrase in Windows askpass helper

The generated .bat askpass script uses echo %CLAWPAL_SSH_PASSPHRASE%, but cmd.exe treats characters such as &, |, >, <, and parentheses as metacharacters. If a key passphrase contains any of these, the echoed value is altered and ssh-add receives the wrong passphrase, so passphrase-based connection fails for valid credentials on Windows. The helper should output the env value using a quoting/escaping-safe approach.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator

@dev01lay2 dev01lay2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid feature PR — SSH config auto-detect, passphrase-first UX, model profile testing, and remote key resolution are all welcome additions. A few observations:

Backend (commands.rs)

SSH config parser — thorough handling of quotes, comments, and multi-alias Host lines. The dedup via BTreeMap at the end is a nice touch.

run_provider_probe — clean implementation. A few notes:

  • The 20s timeout is reasonable for a user-initiated test action.
  • truncate_error_text correctly handles multi-byte chars via char_indices. 👍
  • Consider whether the Anthropic branch should also treat 4xx with specific error types (e.g. overloaded_error) differently from auth failures, so the toast message is more actionable. Not blocking.

resolve_remote_profile_api_key — the fallback chain (direct key → auth_ref as env var → auth_ref from agent auth-profiles → provider convention env vars) is well-structured. The is_valid_env_var_name guard before printenv is good defense.

is_remote_missing_path_error — the string matching is pragmatic but fragile across locales/SSH implementations. Since this is best-effort fallback, it's acceptable, but a comment noting this would help future maintainers.

SSH (ssh.rs)

Passphrase flow — the RAII AskpassScript with Drop cleanup is good practice. Two notes:

  • The Unix askpass script has a stray \\n at the end: "#!/bin/sh\nprintf '%s\\n' \"\\"\\n" — that literal \n after the printf will be written into the script file. Should just be \n (newline), not \\n. Worth double-checking the generated script content.
  • The Windows .bat version uses echo %CLAWPAL_SSH_PASSPHRASE% which will break if the passphrase contains &, |, >, etc. Consider echo(%CLAWPAL_SSH_PASSPHRASE% or a PowerShell wrapper. Not critical for v1 but worth a TODO.

Duplication: add_key_to_agent_with_passphrase is implemented twice (Unix + Windows inner modules) with slightly different script content. Could extract the shared logic into a helper that takes a script template string, but it's manageable at this size.

Frontend

Passphrase dialog — clean promise-based flow with passphraseResolveRef. The Enter-to-submit on the password input is a nice UX touch.

Duplicate name validationhasDuplicateInputName using useMemo is correct. The inline error clears on input change. Good.

SSH config preset dropdown — auto-fills host/user/port from ~/.ssh/config, which is exactly the UX improvement described. The useEffect fetch on mount is fine since this is a dialog-level component.

Settings profile actions — Test and Enable/Disable buttons with toast feedback via sonner integrate well. The testingProfileId loading state prevents double-clicks.

i18n

Both en.json and zh.json are in sync — all new keys present in both. ✅

Minor

  • .gitignore now excludes bun.lockb / bun.lock / bun.dlock — makes sense with the bun migration. But if bun.lock is the new lockfile, should it actually be committed for reproducible installs? Worth confirming intent.

Overall: well-scoped, good error handling, no security concerns. The askpass script content on Unix is the one thing I'd double-check before merge.

@Keith-CY Keith-CY merged commit 739ab31 into lay2dev:main Feb 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants