{"_id":"@balaenis/pi-remote","_rev":"8-2a07354b841779b3e7de3375eb2e1562","name":"@balaenis/pi-remote","dist-tags":{"latest":"0.3.0","next":"0.2.0-next.3"},"versions":{"0.1.0":{"name":"@balaenis/pi-remote","version":"0.1.0","keywords":["pi-package","pi-extension","ssh","remote","connect"],"author":{"name":"balaenis","email":"pzyyll@gmail.com"},"license":"Apache-2.0","_id":"@balaenis/pi-remote@0.1.0","maintainers":[{"name":"pzyyll","email":"pzyyll@gmail.com"}],"homepage":"https://github.com/balaenis/pi-toolset#readme","bugs":{"url":"https://github.com/balaenis/pi-toolset/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"bd91f98a8fa05c12498c24ddf86c8e0f81cbee38","tarball":"https://registry.npmjs.org/@balaenis/pi-remote/-/pi-remote-0.1.0.tgz","fileCount":3,"integrity":"sha512-omZ9xrcXF4j+8qr93qgi4a9eWHpqogfKhLUz7XXgTRkt6SDVEz0LTrjOGJZNXjPprpq69u8YcyEGH2SJ4GRRJg==","signatures":[{"sig":"MEYCIQD8tx1lwZMxYnHq9v/tiPqaENxKbmrFZ4boIieNu91iQQIhAKa+X7NyN1IKBc+J8f4NEJt5m1Hm/IfZ02wztizoUxhc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":36440},"type":"module","exports":{".":"./dist/index.js"},"gitHead":"f94085ff86aeba264ab43adc830c990999be0644","_npmUser":{"name":"pzyyll","email":"pzyyll@gmail.com"},"repository":{"url":"git+https://github.com/balaenis/pi-toolset.git","type":"git"},"_npmVersion":"12.0.2","description":"Pi extension that runs read/write/edit/bash/grep/find/ls tools on a remote machine via SSH (--ssh flag).","directories":{},"_nodeVersion":"26.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-remote_0.1.0_1786210506662_0.4643728351315439","host":"s3://npm-registry-packages-npm-production"}},"0.1.0-next.8":{"name":"@balaenis/pi-remote","version":"0.1.0-next.8","keywords":["pi-package","pi-extension","ssh","remote","connect"],"author":{"name":"balaenis","email":"pzyyll@gmail.com"},"license":"Apache-2.0","_id":"@balaenis/pi-remote@0.1.0-next.8","maintainers":[{"name":"pzyyll","email":"pzyyll@gmail.com"}],"homepage":"https://github.com/balaenis/pi-toolset#readme","bugs":{"url":"https://github.com/balaenis/pi-toolset/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"1ac45b60044a8678442d849e7f38f9854c740525","tarball":"https://registry.npmjs.org/@balaenis/pi-remote/-/pi-remote-0.1.0-next.8.tgz","fileCount":3,"integrity":"sha512-51lRxXwa53LXOhnvCxk1hwIMLmpO/S4HooWUxj0ftmUdNI7VZB10sI+vu1PKC0bTaZSZ+qUTl8t1QmOWAZj+6w==","signatures":[{"sig":"MEUCIFV/GWNuu+H5MIjPnIfEXqYg4XD2ONJOFXwefxA1Y7eCAiEApbS0aRNdeN9IbPCzAuPDL71Vh8hHmeHEI3vmHaUGbDk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@balaenis%2fpi-remote@0.1.0-next.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":36446},"type":"module","exports":{".":"./dist/index.js"},"gitHead":"328c028a326f31260f66a83382c72d9c3b629f60","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c80c7ee1-9d81-4edb-ba17-52eb51ad66b9"}},"repository":{"url":"git+https://github.com/balaenis/pi-toolset.git","type":"git"},"_npmVersion":"11.16.0","description":"Pi extension that runs read/write/edit/bash/grep/find/ls tools on a remote machine via SSH (--ssh flag).","directories":{},"_nodeVersion":"26.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-remote_0.1.0-next.8_1786211141414_0.9021916362582947","host":"s3://npm-registry-packages-npm-production"}},"0.1.0-next.9":{"name":"@balaenis/pi-remote","version":"0.1.0-next.9","keywords":["pi-package","pi-extension","ssh","remote","connect"],"author":{"name":"balaenis","email":"pzyyll@gmail.com"},"license":"Apache-2.0","_id":"@balaenis/pi-remote@0.1.0-next.9","maintainers":[{"name":"pzyyll","email":"pzyyll@gmail.com"}],"homepage":"https://github.com/balaenis/pi-toolset#readme","bugs":{"url":"https://github.com/balaenis/pi-toolset/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"679aeb9bd4a733dd90ac2c436d1009ad814c045e","tarball":"https://registry.npmjs.org/@balaenis/pi-remote/-/pi-remote-0.1.0-next.9.tgz","fileCount":3,"integrity":"sha512-OAR+wRRk7TXnwdRTHL7sjnJRDMW3ohKUi682XRd5sSND1xTXK+BbapQM5Tm+Mo9nKCRJfgo5PmAshAzpywjvyA==","signatures":[{"sig":"MEYCIQDrN/blyURSfe5UHvce/nLolk5Fgds/lsQFMNQq33/JEwIhAM4RBoUM2TzKla6Q1PJoEbdXjtG9f5e1jVDYUKLJkyvA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@balaenis%2fpi-remote@0.1.0-next.9","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":36454},"type":"module","exports":{".":"./dist/index.js"},"gitHead":"ad6deb4f192204b41230e33d906bf33a710526d1","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c80c7ee1-9d81-4edb-ba17-52eb51ad66b9"}},"repository":{"url":"git+https://github.com/balaenis/pi-toolset.git","type":"git"},"_npmVersion":"11.16.0","description":"Pi extension that runs read/write/edit/bash/grep/find/ls tools on a remote machine via SSH (--ssh flag).","directories":{},"_nodeVersion":"26.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-remote_0.1.0-next.9_1786214620938_0.6365975327768634","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@balaenis/pi-remote","version":"0.2.0","keywords":["pi-package","pi-extension","ssh","remote","connect"],"author":{"name":"balaenis","email":"pzyyll@gmail.com"},"license":"Apache-2.0","_id":"@balaenis/pi-remote@0.2.0","maintainers":[{"name":"pzyyll","email":"pzyyll@gmail.com"}],"homepage":"https://github.com/balaenis/pi-toolset#readme","bugs":{"url":"https://github.com/balaenis/pi-toolset/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"d5fe225a78e3f17ea3a246dfc1349aacc486e0bd","tarball":"https://registry.npmjs.org/@balaenis/pi-remote/-/pi-remote-0.2.0.tgz","fileCount":3,"integrity":"sha512-mQu0vggU227m7DeDBC8eNN9nUx9P9N/JyB0Qyr8zfJTuaLNO5///KHPstgEUSUNcIjoxZHD2aWBw481tLVlfTA==","signatures":[{"sig":"MEUCIFMUw0EoX98QCR3HAW4geeFvIJheWWaUQiDymIPLXjovAiEA4ICFGhBp3+BXm3SX1Z4s4SJ71lQ51NHvJ6acdy0QS2Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@balaenis%2fpi-remote@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":36447},"type":"module","exports":{".":"./dist/index.js"},"gitHead":"3d33f3848f9f318fe30bb95794f0e5229b875ad0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c80c7ee1-9d81-4edb-ba17-52eb51ad66b9"}},"repository":{"url":"git+https://github.com/balaenis/pi-toolset.git","type":"git"},"_npmVersion":"11.16.0","description":"Pi extension that runs read/write/edit/bash/grep/find/ls tools on a remote machine via SSH (--ssh flag).","directories":{},"_nodeVersion":"26.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-remote_0.2.0_1786214878238_0.7480408001182344","host":"s3://npm-registry-packages-npm-production"}},"0.2.0-next.1":{"name":"@balaenis/pi-remote","version":"0.2.0-next.1","keywords":["pi-package","pi-extension","ssh","remote","connect"],"author":{"name":"balaenis","email":"pzyyll@gmail.com"},"license":"Apache-2.0","_id":"@balaenis/pi-remote@0.2.0-next.1","maintainers":[{"name":"pzyyll","email":"pzyyll@gmail.com"}],"homepage":"https://github.com/balaenis/pi-toolset#readme","bugs":{"url":"https://github.com/balaenis/pi-toolset/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"9c1fd69bcef78bf5d7ff77cb9ada2be4232e2e69","tarball":"https://registry.npmjs.org/@balaenis/pi-remote/-/pi-remote-0.2.0-next.1.tgz","fileCount":3,"integrity":"sha512-/Q/kzQNreqT1hglnZFTdrza1PTnbUAPO2mROPwBYMDoRk+OeCoZvSWWc66W1XQWYv2v3Fa0jsuruuNdQkXdwlA==","signatures":[{"sig":"MEUCIQDXrGaBfzm4pNitNoILcwtYbyuZ4ZMSthpLjUrIpBCyBAIgN5oUtMuFfZ/LJ9+J8NNl/kBFVMKkJB4lSiX9Nm2wUEU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@balaenis%2fpi-remote@0.2.0-next.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":37884},"type":"module","exports":{".":"./dist/index.js"},"gitHead":"0b70fa76dd6ad037310417091448b6f231db9c07","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c80c7ee1-9d81-4edb-ba17-52eb51ad66b9"}},"repository":{"url":"git+https://github.com/balaenis/pi-toolset.git","type":"git"},"_npmVersion":"11.16.0","description":"Pi extension that runs read/write/edit/bash/grep/find/ls tools on a remote machine via SSH (--ssh flag).","directories":{},"_nodeVersion":"26.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-remote_0.2.0-next.1_1786220269339_0.4123251719020584","host":"s3://npm-registry-packages-npm-production"}},"0.2.0-next.2":{"name":"@balaenis/pi-remote","version":"0.2.0-next.2","keywords":["pi-package","pi-extension","ssh","remote","connect"],"author":{"name":"balaenis","email":"pzyyll@gmail.com"},"license":"Apache-2.0","_id":"@balaenis/pi-remote@0.2.0-next.2","maintainers":[{"name":"pzyyll","email":"pzyyll@gmail.com"}],"homepage":"https://github.com/balaenis/pi-toolset#readme","bugs":{"url":"https://github.com/balaenis/pi-toolset/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"c050c1075b756af7887e461ece53b9bf5b3db134","tarball":"https://registry.npmjs.org/@balaenis/pi-remote/-/pi-remote-0.2.0-next.2.tgz","fileCount":3,"integrity":"sha512-50gXa37CNuRcMvzKKjzFvtPYcjmJ5VT+TRmR6oGFOAc9UBhy/O0NTVQh/orj8LOas5oesNS47qvX5K9r8UPbOw==","signatures":[{"sig":"MEYCIQCkO65PVSHVA0SYuHd8wHycW8/+WeTdD2TuAp8po5vMbAIhAJRr80SftpZENlE1uTW1B8F1SJrSMnlOPAgjNBfk/0oV","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@balaenis%2fpi-remote@0.2.0-next.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":45986},"type":"module","exports":{".":"./dist/index.js"},"gitHead":"d11c4f7431315d8281f43e06f4a5d7cfb9ed9a66","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c80c7ee1-9d81-4edb-ba17-52eb51ad66b9"}},"repository":{"url":"git+https://github.com/balaenis/pi-toolset.git","type":"git"},"_npmVersion":"11.16.0","description":"Pi extension that runs read/write/edit/bash/grep/find/ls tools on a remote machine via SSH (--ssh flag).","directories":{},"_nodeVersion":"26.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-remote_0.2.0-next.2_1786372350691_0.7180597107162017","host":"s3://npm-registry-packages-npm-production"}},"0.2.0-next.3":{"name":"@balaenis/pi-remote","version":"0.2.0-next.3","keywords":["pi-package","pi-extension","ssh","remote","connect"],"author":{"name":"balaenis","email":"pzyyll@gmail.com"},"license":"Apache-2.0","_id":"@balaenis/pi-remote@0.2.0-next.3","maintainers":[{"name":"pzyyll","email":"pzyyll@gmail.com"}],"homepage":"https://github.com/balaenis/pi-toolset#readme","bugs":{"url":"https://github.com/balaenis/pi-toolset/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"8df93d22eeb8ca0c75229a8eeae72640c7c49109","tarball":"https://registry.npmjs.org/@balaenis/pi-remote/-/pi-remote-0.2.0-next.3.tgz","fileCount":3,"integrity":"sha512-m+vCYWVcdeIZV46MI3HRjpgitejDkDKrPh8ukNWfdL8prHlMhfHiSXHAXBk05sgdYAJnd50K4WrcN5NgoERdxA==","signatures":[{"sig":"MEQCICNPJcISxs1xsT63fk2328+QTAOp1qZoKEABNbRj3vYsAiBlD1Pjeb0n6nlYeZufgDzkXbmAVFQnSAqe5OpXqoTwYQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@balaenis%2fpi-remote@0.2.0-next.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":45986},"type":"module","exports":{".":"./dist/index.js"},"gitHead":"a6196e31ef71d83490dfd9d38dd4dda8c5ed70c0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c80c7ee1-9d81-4edb-ba17-52eb51ad66b9"}},"repository":{"url":"git+https://github.com/balaenis/pi-toolset.git","type":"git"},"_npmVersion":"11.16.0","description":"Pi extension that runs read/write/edit/bash/grep/find/ls tools on a remote machine via SSH (--ssh flag).","directories":{},"_nodeVersion":"26.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-remote_0.2.0-next.3_1786430633735_0.05006908287982492","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@balaenis/pi-remote","version":"0.3.0","description":"Pi extension that runs read/write/edit/bash/grep/find/ls tools on a remote machine via SSH (--ssh flag).","license":"Apache-2.0","author":{"name":"balaenis","email":"pzyyll@gmail.com"},"type":"module","keywords":["pi-package","pi-extension","ssh","remote","connect"],"exports":{".":"./dist/index.js"},"pi":{"extensions":["./dist/index.js"]},"repository":{"type":"git","url":"git+https://github.com/balaenis/pi-toolset.git"},"publishConfig":{"access":"public"},"peerDependencies":{"@earendil-works/pi-coding-agent":"*","@earendil-works/pi-tui":"*"},"gitHead":"fa848e4c2a0d4b3df8f3151a8695130897451a48","_id":"@balaenis/pi-remote@0.3.0","bugs":{"url":"https://github.com/balaenis/pi-toolset/issues"},"homepage":"https://github.com/balaenis/pi-toolset#readme","_nodeVersion":"26.3.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-X1D6dmgxWIrLGLMXNq04nWN7X0pxPq0fHXJGUE+ypYMFNA8e18yZepvgMKXpy/I5w7GwJvrcpRqw5rUdPxGJPQ==","shasum":"1a49512504cb805797fbb3f57188d7f09564c9b3","tarball":"https://registry.npmjs.org/@balaenis/pi-remote/-/pi-remote-0.3.0.tgz","fileCount":3,"unpackedSize":45979,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@balaenis%2fpi-remote@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDPTBQLnGRRt8zRugtbGzv7O8AK3wzDXygyC01SHGwjkAIhAPtRtXnfgcZHf5YhbpPPkAVgpIQmfJYFNi2jFlgDqASI"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c80c7ee1-9d81-4edb-ba17-52eb51ad66b9"}},"directories":{},"maintainers":[{"name":"pzyyll","email":"pzyyll@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-remote_0.3.0_1787921571419_0.47381123719451534"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-08T17:35:06.513Z","modified":"2026-08-28T12:52:51.923Z","0.1.0":"2026-08-08T17:35:06.792Z","0.1.0-next.8":"2026-08-08T17:45:41.568Z","0.1.0-next.9":"2026-08-08T18:43:41.113Z","0.2.0":"2026-08-08T18:47:58.367Z","0.2.0-next.1":"2026-08-08T20:17:49.471Z","0.2.0-next.2":"2026-08-10T14:32:30.828Z","0.2.0-next.3":"2026-08-11T06:43:53.914Z","0.3.0":"2026-08-28T12:52:51.547Z"},"bugs":{"url":"https://github.com/balaenis/pi-toolset/issues"},"author":{"name":"balaenis","email":"pzyyll@gmail.com"},"license":"Apache-2.0","homepage":"https://github.com/balaenis/pi-toolset#readme","keywords":["pi-package","pi-extension","ssh","remote","connect"],"repository":{"type":"git","url":"git+https://github.com/balaenis/pi-toolset.git"},"description":"Pi extension that runs read/write/edit/bash/grep/find/ls tools on a remote machine via SSH (--ssh flag).","maintainers":[{"name":"pzyyll","email":"pzyyll@gmail.com"}],"readme":"# @balaenis/pi-remote\n\nPi extension that delegates tool operations to a remote machine via SSH.\n\nWhen `--ssh` is provided, the `read`, `write`, `edit`, `bash`, `grep`, `find`, and `ls` tools run on the remote host instead of locally. Without the flag, all tools behave as usual, so the extension is safe to always load.\n\n## Requirements\n\n- SSH key-based auth to the remote host (password and interactive prompts are rejected immediately via `BatchMode=yes` — they would freeze the TUI)\n- Unknown host keys are accepted on first connect (`StrictHostKeyChecking=accept-new`); changed keys still fail\n- `bash` on the remote\n- `rg` (ripgrep) on the remote (for the `grep` and `find` tools)\n- `fd` on the remote (for interactive `@` file completion; same tool local Pi uses). `/ssh:cwd` prefers `fd` but falls back to standard `find`.\n- `file` on the remote (only for image mime-type detection; degrades gracefully)\n\n## Usage\n\n```bash\n# Run in the current project with SSH enabled\npi -e ./src/index.ts --ssh user@host\n\n# Target a specific remote directory (paths are remapped from local cwd)\npi -e ./src/index.ts --ssh user@host:/remote/path\n```\n\nWithout a path, the remote working directory is resolved via `pwd` over SSH.\n\n## Interactive connection (`/ssh`)\n\nWhile running in the TUI, connect at any time with the `/ssh` command:\n\n```\n/ssh                          # pick a host from ~/.ssh/config\n/ssh user@host                # manual target\n/ssh user@host:/remote/path   # manual target with a remote path\n/ssh user@host -p 2222        # manual target with a custom port\n```\n\n- With no arguments, the hosts listed in `~/.ssh/config` are offered for selection. A single host connects directly; multiple hosts open a picker; no hosts shows a warning.\n- Manual targets accept an optional `:/path` suffix and `-p PORT` (also `-pPORT`, `-p=PORT`, or `--port PORT`).\n- Reconnecting switches the active connection; a failed reconnect keeps the previous working connection and shows the failure reason as an error notification.\n- The same SSH-backed tools, `@` autocomplete, `!commands`, and status indicator are wired as for `--ssh`.\n\n## How it works\n\n- Path remapping: local absolute paths are rewritten from the local cwd to the remote cwd.\n- `bash` runs as `cd <remote-cwd> && <command>` on the remote; timeout and abort signals are forwarded to the SSH child process.\n- `grep` runs `rg` over SSH with `--json`, streaming matches and context lines; limits, line truncation, and notices mirror the built-in grep tool.\n- `find` delegates to remote `rg --files` via the tool's `FindOperations` (globs match like fd `--full-path`); relative paths are produced by running inside the remote cwd.\n- `ls` delegates to the tool's `LsOperations`: remote `test` stats and `ls -1A` directory listings.\n- `ls` and `find` treat only a remote `test -e` exit status of `1` as a missing path and report `Path not found`. Every other SSH failure (any other nonzero status) and every local process error propagates unchanged from the registered tool; no exit status is classified as a transport failure.\n- `!commands` (user bash) also execute remotely when SSH mode is active.\n- When `--ssh` or `/ssh` cannot reach the remote (auth, host key, network, etc.), SSH mode fails loudly: an error notification shows the cleaned SSH reason (stderr), the status bar marks the failure, and every remote tool call errors with `SSH mode unavailable` instead of hanging on interactive prompts or silently running locally.\n- The system prompt's `Current working directory:` line is rewritten to the remote cwd (format-tolerant: any cwd line is replaced, or one is appended).\n- The TUI status bar shows the active SSH target via `ctx.ui.setStatus`.\n\n## Connection multiplexing\n\nSSH connections are reused automatically; no new flag is required. Each session owns one OpenSSH multiplexed connection created with `ControlMaster=auto` and a fixed `ControlPersist=10m`. The control socket is stored in a process- and session-unique private directory under the XDG runtime directory (when safe) or a private temporary subdirectory, so parallel Pi sessions never collide.\n\n- Every normal SSH child runs in a separate process session with fixed internal bounds: `ServerAliveInterval=15`, `ServerAliveCountMax=3`, `ConnectTimeout=15`, `ConnectionAttempts=2`, `BatchMode=yes`, and `StrictHostKeyChecking=accept-new`. The separate session prevents `ProxyJump` and `ProxyCommand` children from opening Pi's controlling terminal. Failures return through stderr instead of showing interactive prompts.\n- A failed in-flight operation is never automatically replayed. A later invocation starts another SSH attempt on the same session-owned connection and control path: `ControlMaster=auto` reuses a live master or opens a new transport. This is a new attempt, not a retry of the failed command.\n- `bash`, `write`, and `edit` can have partial or uncertain remote side effects after a failure. Inspect the remote state before manually repeating them.\n- `session_shutdown` sends a best-effort `ssh -O exit` to the master. The finite 10-minute persist bounds a master left by a hard Pi crash; such a crash can also leave an inert private directory for normal runtime/temp cleanup.\n- Explicit-path startup stays lazy. The first tool call pays the connection handshake; pathless startup pays it during remote `pwd` resolution.\n- Abort and timeout still kill the current SSH client/channel. The multiplexing master remains available for later commands.\n\n## Remote `@` autocomplete\n\nWhen SSH mode is active, the interactive editor's `@` completion lists remote files under the remote working directory instead of local project files. Selected items insert `@path` text only (no file-body injection), matching local Pi behavior — the model can use the `read` tool for contents.\n\n- Typing `@` or `@query` fuzzy-searches under the remote cwd; `@dir/` searches inside that directory; `@dir/query` combines both. Absolute prefixes map from the local cwd to the remote cwd (`@/home/u/proj/src/` → `@/root/proj/src/`); pure remote-absolute prefixes (`@/etc/`) pass through.\n- Directory candidates end with `/` so you can drill down (`@src/` → children). Results are capped at 20, and the listing honors the editor's abort signal (each keystroke cancels the in-flight SSH `fd`).\n- Remote listing uses `fd` over SSH (aligned with local pi-tui `@` completion): `--type d` + `--type f`, `--hidden`, `--follow`, `.git` excludes, optional `--full-path` + path query, `--max-results 100`. Fuzzy/path matching is done by `fd` on the remote; the client re-scores and keeps the top 20.\n- Errors, timeouts, and empty directories return an empty popup — never an error into the editor.\n- Scope v1: only unquoted `@` tokens are remote. Slash commands (`/…`), bare path Tab completion, and quoted `@\"…` tokens keep the local provider.\n- The provider is registered only when SSH resolves successfully in `session_start`; without `--ssh` (or on failure) local `@` completion is untouched.\n- Latency note: each keystroke on `@` still starts one remote listing command (two `fd` passes: dirs then files), but after the first command it reuses the authenticated multiplexed transport instead of performing a new SSH handshake.\n\n## Remote working directory (`/ssh:cwd`)\n\nChange the active remote working directory at any time:\n\n```\n/ssh:cwd                  # pick a directory under the current remote cwd\n/ssh:cwd packages/app     # relative path under the current remote cwd\n/ssh:cwd /srv/app         # absolute path\n/ssh:cwd ~                # remote home directory\n/ssh:cwd ~/src/app        # directory under the remote home directory\n```\n\n- With no arguments, a picker lists directory candidates under the current remote cwd. Candidates include hidden directories, follow symlinks, and exclude `.git`. The list always includes `..`, even at the filesystem root.\n- Inline argument completion fuzzy-ranks candidates case-insensitively: exact basename, basename prefix, basename substring, path substring, then ordered subsequence. Selecting a candidate inserts an executable `/ssh:cwd <path>` argument.\n- The picker and inline completion each show at most 100 items total: `..` plus at most 99 descendants.\n- Remote `fd` is preferred for directory listing; standard `find` is the automatic fallback. `fd` is not required for `/ssh:cwd`.\n- The switch affects all later SSH-backed tools, `!commands`, remote `@` completion, the status bar, and the prompt context. Operations already in flight keep the cwd captured when they started.\n- The switch lasts only for the active SSH connection. A failed or cancelled switch leaves the previous cwd active; failures report the cleaned remote reason.\n\n## Install\n\n```bash\npi install ./packages/pi-remote\n```\n\nThe extension is based on the official Pi example [`examples/extensions/ssh.ts`](https://github.com/earendil-works/pi-coding-agent/blob/main/examples/extensions/ssh.ts).\n","readmeFilename":"README.md"}