|
1 | 1 | # Oh My Portal |
2 | 2 |
|
3 | | -Portal access skills for every CLI agent — Claude Code, Codex CLI, Gemini CLI, opencode, OMP, or anything else that lives in a terminal. Reach your agent from a phone or remote browser through [Portal](https://github.com/gosuda/portal-tunnel), the trustless relay network: tenant TLS terminates on your machine, the relay only ever sees ciphertext. |
| 3 | +**Use your CLI agent from your phone.** |
4 | 4 |
|
5 | | -Two plugins ship from this repository: |
| 5 | +You run Claude Code, Codex, Gemini CLI, opencode, or OMP in a terminal. Oh My Portal gives you safe ways to reach it from anywhere — through [Portal](https://github.com/gosuda/portal-tunnel), a relay network that never sees your data: traffic is encrypted end-to-end and terminates on your machine, not on anyone else's server. |
6 | 6 |
|
7 | | -- **`oh-my-portal`** (main, universal) — pattern-based skills that work with every CLI agent. |
8 | | -- **`oh-my-omp`** (OMP-specific, under `omp/`) — native OMP collab integration. |
| 7 | +## What can I do with it? |
9 | 8 |
|
10 | | -## Skills |
| 9 | +| I want to… | Use | What you get | |
| 10 | +|---|---|---| |
| 11 | +| Chat with my agent from my phone | **agent-frontend** | A proper web chat — streaming answers with code formatting, model switching, session list, cost tracking | |
| 12 | +| Full terminal access on the go | **agent-terminal** | The real terminal in your phone browser; the agent survives disconnects and reboots | |
| 13 | +| Let a teammate watch or join | **agent-share** | One stable link per person; add and revoke access in seconds | |
| 14 | +| Know when a long task finishes | **agent-notify** | Push notifications to your phone when the agent needs you | |
| 15 | +| Share my MCP tools with another machine | **mcp-share** | Your local tools, reachable by other agents — behind your login | |
11 | 16 |
|
12 | | -### agent-terminal (universal) |
| 17 | +On OMP there's also **omp-collab** (OMP's own session-sharing) and **agent-web** (an agent's built-in web UI, safely exposed). |
13 | 18 |
|
14 | | -Reach any terminal-based CLI agent from a phone: **tmux** keeps the agent alive and resumable, **ttyd** serves the terminal over WebSocket, and **Portal** publishes it as public HTTPS. The only per-agent difference is the launch command, carried in a small matrix (`omp`, `claude`, `codex`, ...). Security rules are front-loaded: loopback bind only, credentials always, never an open terminal — a terminal is shell-equivalent. |
| 19 | +## Quick start |
15 | 20 |
|
16 | | -### omp-collab (OMP-specific, `oh-my-omp` plugin) |
| 21 | +The skills install into your agent and guide you from there — you describe what you want in plain language, the agent sets everything up. |
17 | 22 |
|
18 | | -Share a live OMP session through OMP collab: |
19 | | - |
20 | | -- **Hosted path** — the user runs `/collab` in the OMP TUI and opens the printed `my.omp.sh` link or QR on the phone. No infrastructure; payloads are end-to-end encrypted (AES-256-GCM) and the relay only sees ciphertext. |
21 | | -- **Self-hosted path** — the collab relay stand-in runs on the user's machine and is published through a Portal tunnel (`portal expose 127.0.0.1:7466`), with `collab.relayUrl` pointing at the tunnel and `collab.webUrl` at an HTTPS web-client origin. Session traffic terminates on the user's own machine. |
| 23 | +```sh |
| 24 | +# OMP |
| 25 | +omp plugin marketplace add gosuda/oh-my-portal |
| 26 | +omp plugin install oh-my-portal@oh-my-portal |
22 | 27 |
|
23 | | -Only the host human mints collab links; the agent prepares infrastructure and never fabricates or logs them. |
| 28 | +# Claude Code |
| 29 | +claude plugin marketplace add gosuda/oh-my-portal |
| 30 | +claude plugin install oh-my-portal@oh-my-portal |
| 31 | +``` |
24 | 32 |
|
25 | | -### agent-web (universal) |
| 33 | +Then just ask: *"set up a web chat for my agent so I can use it from my phone"*. |
26 | 34 |
|
27 | | -Publish an agent's native web UI — `opencode serve` (verified end to end: loopback default, full web UI at `/`, **no built-in auth**) or self-hosted community UIs for Claude Code / Codex / Gemini — behind a mandatory authentication gate (caddy basic_auth recipe included) and through a Portal tunnel. The skill encodes the verified failure mode: local-first UIs usually answer unauthenticated, so the gate is a hard rule, and verification requires `401` without credentials before hand-off. |
| 35 | +Every setup ends the same way: your agent runs on your machine, a relay forwards encrypted traffic, and nothing works without a password you control. |
28 | 36 |
|
29 | | -### agent-share (universal) |
| 37 | +The chat adapts to whichever agent it's talking to: OMP gets model pickers, live subagent tracking, and session cost; other agents get streaming chat with full conversation memory. New agents plug in without changing the chat. |
30 | 38 |
|
31 | | -One persistent Portal tunnel = one stable HTTPS domain, guarded by per-person tokens (caddy `basic_auth`, one bcrypt hash per person). Inviting is minting a token; removal is deleting a line plus a graceful reload — verified to revoke instantly while other members stay connected without a drop. |
| 39 | +<details> |
| 40 | +<summary><strong>Skill reference</strong> (what each one actually does)</summary> |
32 | 41 |
|
33 | | -### agent-notify (universal) |
| 42 | +**agent-terminal** — tmux keeps the agent alive across disconnects, ttyd serves the terminal over WebSocket, Portal publishes it as HTTPS. Loopback bind + credentials are hard rules; an open terminal is a shell. |
34 | 43 |
|
35 | | -Agent hooks (Claude Code notification hooks, OMP hooks) push to a self-hosted ntfy server exposed through a hidden Portal tunnel. Verified end to end on ntfy 2.27: `403` anonymous, token publish and SSE subscribe locally and through the public URL. Notification content is labels-only. |
| 44 | +**agent-frontend** — a Bun bridge adapts each agent's protocol into one event stream the chat renders. OMP via RPC (full features), Claude Code and Codex via SDK with conversation history, opencode via its API, anything else via a subprocess fallback. Ships with a contract test suite; the bridge won't start on a broken frontend. |
36 | 45 |
|
37 | | -### mcp-share (universal) |
| 46 | +**agent-share** — one persistent tunnel, one stable HTTPS domain, per-person tokens (caddy `basic_auth`). Revoking a token takes effect immediately without dropping other members. |
38 | 47 |
|
39 | | -Expose a local stdio MCP server to other machines' agents: a supergateway bridge (streamable HTTP, stateless `/mcp`) behind the auth gate, published through a hidden tunnel. Verified with `initialize` → `tools/list` → `tools/call` all round-tripping through the public URL. The bridge has no built-in auth, so the gate is mandatory; the skill makes the tool-execution grant explicit. |
| 48 | +**agent-notify** — agent hooks push to a self-hosted ntfy server behind a hidden tunnel. Verified on ntfy 2.27; notification content is labels-only. |
40 | 49 |
|
41 | | -### agent-frontend (universal) |
| 50 | +**mcp-share** — a supergateway bridge exposes a local stdio MCP server as HTTP behind the auth gate; `initialize`/`tools/list`/`tools/call` round-trip through the public URL. |
42 | 51 |
|
43 | | -A rich mobile-first web chat for any CLI agent — streaming markdown with syntax highlighting, rich tool cards, model/thinking pickers, session cost tracking, and an Agent Hub with subagent transcripts. Adapters declare capabilities; the frontend shows exactly what the active agent supports. OMP gets the full set; Claude Code, Codex, and opencode connect with multi-turn history; everything else works through a streaming subprocess fallback. Adding an adapter requires zero frontend changes. |
| 52 | +**agent-web** — publishes an agent's own web UI (opencode serve, or community UIs) behind a mandatory gate. Most local-first UIs answer unauthenticated — the skill refuses to deploy without `401` proof. |
44 | 53 |
|
45 | | -``` |
46 | | -Phone → Portal → caddy gate → agent-bridge.ts |
47 | | - ├── omp-rpc adapter (full: pickers, hub, cost, commands) |
48 | | - ├── claude-code adapter (SDK + history) |
49 | | - ├── codex adapter (SDK + history) |
50 | | - ├── opencode adapter (API session) |
51 | | - └── simple adapter (any CLI, line-streamed) |
52 | | -``` |
| 54 | +**omp-collab** (OMP only) — share a live OMP session. Either use the hosted `my.omp.sh` link (end-to-end encrypted) or self-host the relay stand-in through your own tunnel. |
53 | 55 |
|
54 | | -## Install |
| 56 | +</details> |
55 | 57 |
|
56 | | -### From this repository (OMP marketplace) |
| 58 | +<details> |
| 59 | +<summary><strong>All install options</strong></summary> |
57 | 60 |
|
58 | 61 | ```sh |
| 62 | +# OMP marketplace |
59 | 63 | omp plugin marketplace add gosuda/oh-my-portal |
60 | 64 | omp plugin install oh-my-portal@oh-my-portal # universal skills |
61 | 65 | omp plugin install oh-my-omp@oh-my-portal # OMP collab (optional) |
62 | | -``` |
63 | | - |
64 | | -Or inside the OMP TUI: `/marketplace add gosuda/oh-my-portal`, then `/marketplace install ...`. |
65 | | - |
66 | | -Local development: |
67 | | - |
68 | | -```sh |
69 | | -omp plugin marketplace add ./oh-my-portal |
70 | | -omp plugin install oh-my-portal@oh-my-portal |
71 | | -``` |
72 | | - |
73 | | -Run `/reload-plugins` after installing to refresh skills. |
| 66 | +# then /reload-plugins in the TUI |
74 | 67 |
|
75 | | -### From npm |
76 | | - |
77 | | -```sh |
| 68 | +# npm |
78 | 69 | omp plugin install oh-my-portal |
79 | | -``` |
80 | 70 |
|
81 | | -(The npm package carries the universal plugin; the OMP-specific plugin installs from the marketplace above.) |
82 | | - |
83 | | -### Claude Code |
84 | | - |
85 | | -The catalog is also published in the Claude Code plugin registry format (`.claude-plugin/marketplace.json`): |
86 | | - |
87 | | -```sh |
| 71 | +# Claude Code registry |
88 | 72 | claude plugin marketplace add gosuda/oh-my-portal |
89 | 73 | claude plugin install oh-my-portal@oh-my-portal |
90 | | -``` |
91 | 74 |
|
92 | | -## Layout |
93 | | - |
94 | | -```text |
95 | | -oh-my-portal/ |
96 | | -├── .omp-plugin/marketplace.json # OMP marketplace catalog: both plugins |
97 | | -├── .claude-plugin/marketplace.json # Claude Code-compatible catalog |
98 | | -├── .claude-plugin/plugin.json # oh-my-portal (main) manifest |
99 | | -├── skills/ |
100 | | -│ └── agent-terminal/ # universal: any CLI agent via tmux+ttyd+Portal |
101 | | -├── omp/ # oh-my-omp (OMP-specific plugin) |
102 | | -│ ├── .claude-plugin/plugin.json |
103 | | -│ └── skills/omp-collab/ |
104 | | -│ ├── SKILL.md |
105 | | -│ └── references/omp-collab-details.md |
106 | | -├── package.json # npm distribution (universal plugin) |
107 | | -└── README.md |
| 75 | +# local development |
| 76 | +omp plugin marketplace add ./oh-my-portal |
108 | 77 | ``` |
109 | 78 |
|
110 | | -## Publishing |
| 79 | +</details> |
| 80 | + |
| 81 | +## For maintainers |
111 | 82 |
|
112 | | -- npm: `npm publish` (package `oh-my-portal`; the tarball carries the catalogs, both plugin manifests, and all skills). |
113 | | -- Marketplace consumers track this repository's `main` branch; bump `version` in `package.json`, both plugin manifests, and the catalog entries together. |
| 83 | +- Skills live in `skills/`, the OMP-specific plugin in `omp/`, the web chat in `frontend/`. |
| 84 | +- The web chat deploys through a contract suite (`bun run test/contract.ts`) and the bridge refuses to boot if the suite's static checks fail. |
| 85 | +- npm package `oh-my-portal` carries the universal plugin; bump versions in `package.json` and the plugin manifests together. |
114 | 86 |
|
115 | 87 | ## License |
116 | 88 |
|
|
0 commit comments