Skip to content

Commit f06fa88

Browse files
authored
docs: rewrite README for humans (#10)
The README read like an engineering changelog: each skill opened with its implementation stack, sentences carried verification history, and a visitor couldn't figure out in 30 seconds which piece they needed. New structure: - pitch first: 'Use your CLI agent from your phone' - a scenario table — 'I want to… → use this → what you get' - 3-line quick start with a plain-language usage example - safety in everyday words (3 bullets) - per-skill reference and all install variants moved into collapsible <details> — depth preserved, front page stays flat - maintainer notes condensed to 3 lines Also folds in a style.css cleanup from the last merge: sidebar rules back in the sidebar section, picker rules in the picker section (no functional change; all selectors verified present).
1 parent 11d1020 commit f06fa88

2 files changed

Lines changed: 50 additions & 78 deletions

File tree

README.md

Lines changed: 48 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,88 @@
11
# Oh My Portal
22

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.**
44

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.
66

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?
98

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 |
1116

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).
1318

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
1520

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.
1722

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
2227

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+
```
2432

25-
### agent-web (universal)
33+
Then just ask: *"set up a web chat for my agent so I can use it from my phone"*.
2634

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.
2836

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.
3038

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>
3241

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.
3443

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.
3645

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.
3847

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.
4049

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.
4251

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.
4453

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.
5355

54-
## Install
56+
</details>
5557

56-
### From this repository (OMP marketplace)
58+
<details>
59+
<summary><strong>All install options</strong></summary>
5760

5861
```sh
62+
# OMP marketplace
5963
omp plugin marketplace add gosuda/oh-my-portal
6064
omp plugin install oh-my-portal@oh-my-portal # universal skills
6165
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
7467

75-
### From npm
76-
77-
```sh
68+
# npm
7869
omp plugin install oh-my-portal
79-
```
8070

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
8872
claude plugin marketplace add gosuda/oh-my-portal
8973
claude plugin install oh-my-portal@oh-my-portal
90-
```
9174

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
10877
```
10978

110-
## Publishing
79+
</details>
80+
81+
## For maintainers
11182

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.
11486

11587
## License
11688

frontend/style.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ body { width:100%; background:var(--bg); color:var(--text); font-family:var(--fo
4141
.sb-item .sb-del { background:none; border:none; color:var(--dim); font-size:14px; cursor:pointer; padding:2px 4px; border-radius:4px; }
4242
.sb-item .sb-del:hover { color:var(--error); background:var(--surface); }
4343
.sb-item .sb-ren { background:none; border:none; color:var(--dim); font-size:12px; cursor:pointer; padding:2px 4px; border-radius:4px; }
44-
.model-item.active { border-color:var(--accent); background:rgba(88,166,255,.08); }
45-
.model-item .mi-id { flex:1; font-weight:500; }
44+
.sb-item .sb-ren:hover { color:var(--accent); background:var(--surface); }
4645
.sb-item .sb-title-input { flex:1; min-width:0; font-size:13px; background:var(--bg); border:1px solid var(--accent); border-radius:4px; color:var(--text); padding:2px 6px; outline:none; font-family:inherit; }
4746

4847
/* Main app */
@@ -113,6 +112,7 @@ main::-webkit-scrollbar-thumb { background:var(--border); border-radius:3px; }
113112
.model-list { display:flex; flex-direction:column; gap:4px; }
114113
.model-item { display:flex; align-items:center; gap:10px; text-align:left; padding:8px 12px; border:1px solid var(--border); border-radius:6px; background:var(--bg); color:var(--text); cursor:pointer; font-size:13px; font-family:inherit; }
115114
.model-item:hover { border-color:var(--accent); }
115+
.model-item.active { border-color:var(--accent); background:rgba(88,166,255,.08); }
116116
.model-item.current { border-color:var(--success); background:rgba(76,175,80,.08); }
117117
.mi-provider { color:var(--dim); font-size:11px; min-width:70px; }
118118
.mi-id { flex:1; font-weight:500; }

0 commit comments

Comments
 (0)