pub(crate) const PTY_SHELL_TOOL: &str = r#"{
"name": "PtyShell",
"description": "Attach to this pane's one interactive shell — the SAME real terminal the user sees if they open the shell drawer in the UI, creating it if it doesn't exist yet. Unlike Shell(), which runs on a plain pipe, this is a REAL PTY, so programs that check for one (password/wizard prompts, sudo, ssh, REPLs) work instead of refusing or misbehaving. Returns a shell_id immediately; use PtyShellInput to type into it, PtyShellRead to see its output, PtyShellStatus to poll, PtyShellStop to release your lock early. Because this is the user's own visible shell, PtyShellInput/PtyShellResize briefly lock out the user's own keyboard input to it (a few seconds, refreshed while you keep typing, auto-released the moment you stop) so your keystrokes and theirs don't collide — don't hold it longer than you need to. Works with no UI involved at all on your end — the window need not be open, focused, or rendering anything for you to call this; it's a plain backend call, not simulated keystrokes.",
"inputSchema": {
"type": "object",
"properties": {
"cwd": { "type": "string", "description": "Working directory (defaults to agent workdir)" },
"rows": { "type": "integer", "description": "Initial terminal rows (default 25)" },
"cols": { "type": "integer", "description": "Initial terminal columns (default 200)" },
"connection": { "type": "string", "description": "Where it runs: \"local\" (default, this machine), \"wsl://<distro>\" for a WSL distribution on this Windows machine, or an SSH host (an ssh config alias, host, user@host or user@host:port). ConnList shows what is available. An SSH host runs as the user with their SSH keys, so the first use asks the user to allow it (an error says if they did not), and any ssh password or host-key prompt goes to the user, never to you. A WSL or SSH shell is the login shell there, and cwd is a path on that side. The pane has one shell: to switch connection while it runs, end it first with PtyShellInput(text: \"exit\\r\") (PtyShellStop only releases your keyboard lock and leaves it running)." }
}
}
}"#;