Skip to main content

shanframe

Use the shanframe CLI to reach the user's other machines — run commands on them, forward ports / borrow their network, and see and operate their screens (macOS, Android phones). Use whenever a task involves another device on the user's shanframe list; for a phone, read android.md next to this file.

Datos de origen

Repositorio
ShawnPana/shanframe
Última actividad en el origen
2 de octubre de 2026 a las 04:04
Idioma detectado de SKILL.md
inglés
Estrellas
14
Forks
0

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
2 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
shanframe
description
Use the shanframe CLI to reach the user's other machines — run commands on them, forward ports / borrow their network, and see and operate their screens (macOS, Android phones). Use whenever a task involves another device on the user's shanframe list; for a phone, read android.md next to this file.
# shanframe — your other machines, from here Every machine the user installed shanframe on is reachable from this one with the `shanframe` CLI. Same account, no keys to manage, peer-to-peer and end-to-end encrypted. Everything below works from any device on the list. ## Find machines ```sh shanframe ls # human list: name, os, online/asleep/offline, screen shanframe ls --json # [{id,name,os,online,asleep,screen,native,services:[…]}] ``` `services` says what each machine offers right now: `shell`, `exec`, `tunnel`, `screen`, `input`, `screenshot`. Names match by prefix: `shanframe rasp …` reaches "Raspberry Pi 5". Offline/asleep machines can't be reached; say so instead of retrying in a loop. ## Run commands (any machine) ```sh shanframe <dev> run -- <command line> ``` ssh semantics: runs in the user's login shell on that machine, from their home directory; stdout and stderr come back separately; the exit code is yours. stdin is piped when it's not a terminal (`cat file | shanframe pi run -- tee x`). Quote shell syntax so it reaches the remote shell: `run -- 'cd app && make'`. Prefer `run` to an interactive terminal; `shanframe <dev>` (no verb) opens a live shell for humans. Everything a `run` starts dies when the command ends (its whole process group is cleaned up) — to leave something running on the far machine use the machine's own service manager (`systemctl --user`, `launchctl`, `tmux new -d`, `setsid`), and for tunnels use `--install`. ## Ports and networks (any machine) ```sh shanframe <dev> tunnel 5432 # localhost:5432 here → that machine's localhost:5432 shanframe <dev> tunnel 8080:db.internal:80 # a host only that machine can see; resolved there shanframe <dev> tunnel --socks 1080 # SOCKS5 proxy here; connections leave from that machine ``` The command stays in the foreground while the tunnel is up (run it in the background, then use it). Add `--install` to keep a tunnel permanently: the background service listens from then on and connects on first use; `--uninstall` removes it; `shanframe tunnels` lists them. On a one-way machine the CLI can do nothing — unless the owner granted it a port in the app: then `shanframe ls` shows the granted device by id with the ports it may reach, and `shanframe <id> tunnel <port> --install` is the only thing that works there (no shell, no run, no other port). This is also how you "host" an app for the whole list: run it on one machine, and on each machine that should see it, `shanframe <host> tunnel <port> --install` — `localhost:<port>` there is now that app (verified: a web app on a Mac, opened in a Raspberry Pi's browser). Use the SOCKS form with `HTTP_PROXY=socks5h://localhost:1080` (the `h` matters: names resolve on the far side). Use a plain port forward for things that can't use a proxy — e.g. Chrome DevTools: `shanframe mac tunnel 9222` then talk to localhost:9222. TCP only. ## Look and act on a screen (macOS and Android targets) Coordinates are points in the screenshot — what you see is what you click. ```sh shanframe <dev> screenshot shot.png [--json] # {"file","w","h"}; also `-` for stdout shanframe <dev> size # e.g. 1512x982 shanframe <dev> displays # a Mac with more than one: "1 Built-in Retina Display 1512x982 (main)" … shanframe <dev> screenshot --display 2 d2.png # any screen verb takes --display N; coordinates are then points on that display shanframe <dev> click X Y [--right|--double] # tap = click shanframe <dev> drag X1 Y1 X2 Y2 shanframe <dev> scroll X Y DY # negative DY scrolls up; or X Y DX DY shanframe <dev> type some text here shanframe <dev> key cmd+space # enter, esc, tab, cmd+shift+t, ctrl+c, up/down/left/right shanframe <dev> batch <<'STEPS' # many steps, one connection (fast) click 640 400 type hello key enter sleep 0.5 screenshot after.png STEPS ``` Loop: screenshot → decide → act → screenshot to verify. One verb is one session (~0.3–3 s); `batch` is the fast path. Each line of `batch` is a verb above plus `move X Y` and `sleep SECONDS`. Android phones take the same verbs (tap/swipe/type; `--right` = Back) — see **android.md** for the phone specifics and setup. Linux desktops have no screen verbs yet (terminal only from the CLI); `ls --json` tells you. ## Drive another machine's Chrome (CDP through a tunnel) Works for any Chromium-based browser with remote debugging on. Two ways the far machine can have it on: - **Chrome, recent versions:** `chrome://inspect/#remote-debugging` → "Allow remote debugging for this browser instance". This is *gated* mode: the `/json/*` discovery endpoints answer 404; you connect straight to the browser WebSocket whose path is in the `DevToolsActivePort` file. - **Any Chromium (Brave, Edge, Chromium, Arc…):** launched with `--remote-debugging-port=9222 --user-data-dir=<a dir>` — then `/json/version` works too. One verb does the plumbing — finds the browser's debug port on the device (DevToolsActivePort, or a listening Chromium process), tunnels it to a free local port, detects gated vs classic, prints what to connect to, and keeps the tunnel up until Ctrl-C: ```sh shanframe pi cdp & # stdout: CDP_WS=ws://localhost:PORT/devtools/browser/… (+ CDP_URL=http://… when classic) shanframe pi cdp --json # {"device","mode","url","ws","local_port"} shanframe pi cdp --port 9222 # if it can't find the port itself ``` Then hand `CDP_WS` to any CDP client, e.g. browser-harness: ```sh eval "$(shanframe pi cdp 2>/dev/null | head -2)" & # or parse --json BU_NAME=pi BU_CDP_WS="$CDP_WS" browser-harness <<'PY' print(page_info()); new_tab("https://example.com") PY ``` Verified both ways: Mac Chrome in gated mode, and a Raspberry Pi's Chromium launched with `--remote-debugging-port`. Playwright/Puppeteer take `CDP_URL` (classic) or `CDP_WS`. Keep `localhost` as the host — Chrome only trusts that. You're operating the user's real browser with their logins: act on the task, don't browse around; prefer a new tab, leave theirs alone. ## Rules of the road - You act as the user, on their machines, with their permissions. Do what was asked; don't wander. - Check `online` first; an asleep Mac comes back when it wakes, not because you retry. - Destructive commands on another machine deserve the same care as here.
Ver en GitHub