Porterminal
Quick n' dirty web terminal tunneling your phone & pc
Install / Use
/learn @lyehe/PorterminalREADME
Why
I wanted to vibe code from bed.
ngrok requires registration and the free tier sucks. Cloudflare Quick Tunnel works great but is hard to use directly on the phone. Termius requires complicated setup: port forwarding, firewall rules, key management... Tried Claude Code web, but it can't access my local hardware and environment. Also tried Happy, but it's too bulky and updates lag behind.
So I built something simpler: run a command, scan a QR, start typing.
Features
- One command, instant access - No SSH, no port forwarding, no config files. Cloudflare tunnel + QR code.
- Actually usable on mobile - Touch-optimized with momentum scrolling, pinch-to-zoom, swipe gestures, and modifier keys (Ctrl, Alt).
- Full terminal apps - vim, htop, less, tmux all work correctly with proper alt-screen buffer handling.
- Persistent multi-tab sessions - Sessions survive disconnects. Close the browser, switch networks, reconnect from another device—your shell and running processes are still there. Multiple devices can view the same session simultaneously.
- Cross-platform - Windows (PowerShell, CMD, WSL), Linux/macOS (Bash, Zsh, Fish, Nushell, and any shell via
$SHELL). Auto-detects your shells.
Install
| Method | Install | Update |
|--------|---------|--------|
| uvx (no install) | uvx ptn | uvx --refresh ptn |
| uv tool | uv tool install ptn | uv tool upgrade ptn |
| pipx | pipx install ptn | pipx upgrade ptn |
| pip | pip install ptn | pip install -U ptn |
One-line install (uv + ptn):
| OS | Command |
|----|---------|
| Windows | powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/lyehe/porterminal/master/install.ps1 \| iex" |
| macOS/Linux | curl -LsSf https://raw.githubusercontent.com/lyehe/porterminal/master/install.sh \| sh |
Requires Python 3.12+ and cloudflared (auto-installed if missing).
Usage
ptn # Start in current directory
ptn ~/projects/myapp # Start in specific folder
| Flag | Description |
|------|-------------|
| -n, --no-tunnel | Local network only (no Cloudflare tunnel) |
| -b, --background | Run in background and return immediately |
| -p, --password | Prompt for password to protect this session |
| -sp, --save-password | Save or clear password in config |
| -tp, --toggle-password | Set password requirement (on/off/toggle) |
| -v, --verbose | Show detailed startup logs |
| -i, --init | Create .ptn/ptn.yaml config (-i "" for auto-discovery, or -i URL/PATH) |
| -c, --compose | Enable compose mode by default |
| -u, --check-update | Check if a newer version is available |
| -V, --version | Show version |
Mobile Gestures
| Gesture | Action | |---------|--------| | Tap | Focus terminal, clear selection | | Long-press | Start text selection | | Double-tap | Select word | | Swipe left/right | Arrow keys (← →) | | Scroll | Momentum scrolling with physics | | Pinch | Zoom text (10-24px) |
Modifier keys (Ctrl, Alt, Shift): Tap once for sticky (one keystroke), double-tap for lock.
Compose mode (▤ button): Toggle a text input field where you can type or dictate, edit your text with full mobile editing features (autocorrect, suggestions, cursor positioning), then send to terminal. Useful for longer commands or voice input.
Configuration
Run ptn --init to create a starter config. It auto-discovers project scripts from package.json, pyproject.toml, or Makefile and adds them as buttons:
ptn -i ""
# Created: .ptn/ptn.yaml
# Discovered 3 project script(s): build, dev, test
Or create ptn.yaml manually:
# Terminal settings
terminal:
default_shell: nu # Default shell ID
shells: # Custom shell definitions
- id: nu
name: Nushell
command: nu
args: []
# Custom buttons (appear in toolbar)
# row: 1 = default row, 2+ = additional rows
buttons:
- label: "claude"
send:
- "claude"
- 100 # delay in ms
- "\r"
- label: "build"
send: "npm run build\r"
row: 2 # second button row
# Update checker settings
update:
notify_on_startup: true # Show update notification
check_interval: 86400 # Seconds between checks (default: 24h)
# Security settings
security:
require_password: true # Always require password at startup
password_hash: "" # Saved password hash (use ptn -sp to set)
max_auth_attempts: 5 # Max failed attempts before disconnect
Config is searched in order: $PORTERMINAL_CONFIG_PATH, ./ptn.yaml, ./.ptn/ptn.yaml, ~/.ptn/ptn.yaml.
Security
Protect your terminal with a password:
From the UI: Open Settings (gear icon) and use the Security section to set/change password and toggle password requirement. Changes require server restart.
From CLI:
# One-time password (prompt each session)
ptn -p
# Save password to config (no prompt needed)
ptn -sp
# Password: ****
# Confirm password: ****
# Clear saved password (enter empty password)
ptn -sp
# Password: [press Enter]
# Set or toggle password requirement
ptn -tp on # Enable
ptn -tp off # Disable
ptn -tp toggle # Toggle current state
See docs/security.md for details.
Troubleshooting
Connection fails? Cloudflare tunnel sometimes blocks connections. Restart the server (Ctrl+C, then ptn) to get a fresh tunnel URL.
Shell not detected? Set your $SHELL environment variable or configure shells in ptn.yaml.
Contributing
Issues and PRs welcome.
git clone https://github.com/lyehe/porterminal
cd porterminal
uv sync
uv run ptn
License
Related Skills
node-connect
349.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.9kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
