MCP polish + SSH host manager Connect button

Three small things bundled from PR-3 verification:

1. Split SSH out of mcp.spawn_pane schema. New McpSpawnSpec enum
   (Wsl | Powershell only) used for SpawnPaneArgs, so Claude's
   spawn_pane tool description and JSON schema show only the local
   shells. SSH must go through connect_host. The internal
   pty::SpawnSpec is unchanged — the frontend's manual spawn path
   via XtermPane still supports all three variants. Previously
   spawn_pane(kind=ssh) was a half-broken path that required `host`
   as a separate mandatory field even when hostId was given;
   serde-rejected the natural "spawn to a saved host" call shape.

2. Refresh the MCP server's `with_instructions` text and the
   module-level header comment. Both still claimed "read-only v1"
   long after the v2 write surface landed, which was making Claude
   refuse to attempt tools on first contact ("the server has
   flagged itself as read-only..."). The instructions now describe
   the actual tool set, the SSH-via-connect_host convention, and
   the policy/safeguards gates so Claude doesn't have to infer.

3. Add a "Connect" button to the SSH hosts manager. Previously
   the dialog only had Edit — users (rightly) expected clicking a
   saved host to spawn an SSH pane to it. New onConnect callback
   does the splitLeaf + smart-orient dance and closes the manager.
   Buttons wrapped in a flex container so the row's
   space-between layout doesn't strand the new button mid-row.
This commit is contained in:
megaproxy 2026-05-26 15:20:22 +01:00
parent bf2810a433
commit 6da7523993
4 changed files with 144 additions and 52 deletions

View file

@ -92,7 +92,13 @@
font-size: 11px;
margin-top: 1px;
}
.host-edit-btn {
.host-actions {
display: flex;
gap: 6px;
flex-shrink: 0;
}
.host-edit-btn,
.host-connect-btn {
background: #222;
color: #aac;
border: 1px solid #2a2a3a;
@ -106,6 +112,15 @@
background: #2a2a3a;
color: #cce;
}
.host-connect-btn {
background: #1a2a1a;
color: #80c080;
border-color: #2a4a2a;
}
.host-connect-btn:hover {
background: #2a4a2a;
color: #a0e0a0;
}
.host-form {
display: flex;

View file

@ -40,6 +40,8 @@ interface HostManagerProps {
/** Delete the keyring entry for this host id. Called when the user
* clicked "Remove password" before Save. */
onClearPassword: (hostId: string) => void;
/** Open a new pane connected to this host (and close the manager). */
onConnect: (hostId: string) => void;
onClose: () => void;
}
@ -48,6 +50,7 @@ export default function HostManager({
onSave,
onSavePassword,
onClearPassword,
onConnect,
onClose,
}: HostManagerProps) {
// Local editable copy. Any save / delete acts on this and pushes the
@ -377,12 +380,21 @@ export default function HostManager({
{h.jumpHost ? ` via ${h.jumpHost}` : ""}
</div>
</div>
<button
className="host-edit-btn"
onClick={() => startEdit(h.id)}
>
Edit
</button>
<div className="host-actions">
<button
className="host-connect-btn"
onClick={() => onConnect(h.id)}
title={`Open a new pane connected to ${h.label}`}
>
Connect
</button>
<button
className="host-edit-btn"
onClick={() => startEdit(h.id)}
>
Edit
</button>
</div>
</div>
)}
</li>