Skip to content

Commit 048010e

Browse files
authored
Merge pull request #20 from connorads/dev
feat: promote built-in runtime from dev to main
2 parents bd14e6b + 7e2fa1b commit 048010e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+3345
-686
lines changed

.agents/skills/remobi-setup/SKILL.md

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,12 @@ Run silently, then report what's present vs missing:
4444

4545
```bash
4646
node --version # need >= 22
47-
which ttyd # must be on PATH
4847
tmux -V # target multiplexer
4948
which remobi # npm install -g remobi
5049
```
5150

5251
If anything is missing, help install it:
5352
- **Node**: suggest mise, nvm, or direct install
54-
- **ttyd**: `brew install ttyd` (macOS), distro package or source build (Linux) — see [ttyd installation](https://github.com/tsl0922/ttyd#installation)
5553
- **tmux**: `brew install tmux` or distro package
5654
- **remobi**: `npm install -g remobi`
5755

@@ -168,13 +166,13 @@ export default {
168166

169167
Place at `~/.config/remobi/remobi.config.ts` (XDG location) unless the user prefers elsewhere.
170168

171-
After writing, validate:
169+
After writing, validate by starting remobi:
172170

173171
```bash
174-
remobi build --dry-run
172+
remobi serve --config ~/.config/remobi/remobi.config.ts --port 18765 -- /bin/true
175173
```
176174

177-
A zero exit with "Dry run: build" output means valid. Fix any errors and re-validate until clean.
175+
A zero exit means the config loaded and the command started cleanly. Fix any errors and re-validate until clean.
178176

179177
See [Config reference](#config-reference) below for the full schema, allowed keys, action types, and escape codes.
180178

@@ -234,13 +232,13 @@ remobi hardens the connection even on private networks. Mention these if the use
234232
- **Content-Security-Policy** — strict default-src, script-src, connect-src scoped to same host
235233
- **WebSocket origin validation** — rejects cross-origin upgrade requests
236234
- **Relay buffer limit** — 1 MB per connection; drops oversized payloads
237-
- **Crypto-secure internal port**ttyd listens on a random ephemeral port (crypto PRNG), never exposed
235+
- **Local-only default**remobi binds to `127.0.0.1` unless the user explicitly changes `--host`
238236
- **X-Frame-Options DENY** — prevents clickjacking via iframes
239237
- **Referrer-Policy: no-referrer** — no URL leaking to external sites
240238

241239
For macOS users, mention `--no-sleep` and point to `references/keep-awake.md` for persistent options.
242240

243-
For users who want manual ttyd control, point to `references/ttyd-flags.md`.
241+
For users migrating from old ttyd-based setups, point to `references/ttyd-flags.md` as legacy guidance only.
244242

245243
#### Summary
246244

@@ -589,11 +587,11 @@ Requires matching tmux bindings (see `references/tmux-basics.md` popup section).
589587
## Validation
590588

591589
```bash
592-
remobi build --dry-run # validates config, prints plan, exits without building
593-
remobi build --dry-run -c ./remobi.config.ts # explicit path
590+
remobi serve --config ~/.config/remobi/remobi.config.ts --port 18765 -- /bin/true
591+
remobi serve --config ./remobi.config.ts --port 18765 -- /bin/true
594592
```
595593

596-
A zero exit with "Dry run: build" output means the config is valid. Any error output means fix the reported paths before proceeding.
594+
A zero exit means the config is valid. Any error output means fix the reported paths before proceeding.
597595

598596
### Common validation errors
599597

.agents/skills/remobi-setup/references/tailscale-serve.md

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ Expose a tmux session as a mobile-friendly web terminal over your Tailscale netw
44

55
## Prerequisites
66

7-
- [ttyd](https://github.com/tsl0922/ttyd) installed (`brew install ttyd` on macOS; Linux via distro package manager or source build from the [installation guide](https://github.com/tsl0922/ttyd#installation))
87
- [tmux](https://github.com/tmux/tmux) installed
98
- [Tailscale](https://tailscale.com/) configured with HTTPS enabled (`tailscale cert`)
109
- remobi installed (`npm install -g remobi`)
@@ -17,7 +16,7 @@ Expose a tmux session as a mobile-friendly web terminal over your Tailscale netw
1716
remobi serve
1817
```
1918

20-
This builds the overlay in memory, starts ttyd on an internal port, and serves on `:7681` with full PWA support (manifest, icons, meta tags).
19+
This bundles the browser client in memory, starts remobi's built-in HTTP and WebSocket server, and spawns a local PTY-backed terminal session on `:7681` with full PWA support.
2120

2221
By default `remobi serve` binds to `127.0.0.1`, so it is not exposed on your LAN. Tailscale Serve is the thing that publishes it.
2322

@@ -57,7 +56,6 @@ function webtermup() {
5756
local port=${2:-7681}
5857
5958
pkill -f "remobi serve.*--port $port" 2>/dev/null
60-
pkill -f "ttyd.*--port $port" 2>/dev/null
6159
6260
remobi serve --no-sleep --port $port -- tmux new-session -A -s "$session" &!
6361
@@ -69,42 +67,15 @@ function webtermup() {
6967
function webtermdown() {
7068
local port=${1:-7681}
7169
pkill -f "remobi serve.*--port $port" 2>/dev/null
72-
pkill -f "ttyd.*--port $port" 2>/dev/null
7370
tailscale serve --https=443 off 2>/dev/null
7471
echo "Web terminal stopped"
7572
}
7673
```
7774
78-
## Advanced: manual build + ttyd
75+
## Legacy ttyd notes
7976

80-
If you are tempted to run `remobi serve --host 0.0.0.0`, be explicit about the trade-off: that bypasses the localhost-only default and exposes terminal control directly on the bound network interface. Prefer keeping remobi on loopback and letting Tailscale handle reachability.
81-
82-
For cases where you need direct control over ttyd (e.g. custom flags, separate processes):
83-
84-
### 1. Build the overlay
85-
86-
```bash
87-
remobi build --output ~/.cache/remobi/index.html
88-
```
89-
90-
Always rebuild before starting to avoid stale overlay issues.
91-
92-
### 2. Start ttyd with the overlay
77+
Current remobi releases do not depend on `ttyd`. If you are migrating an older setup, move it to `remobi serve` rather than trying to preserve the old `ttyd` path.
9378

94-
```bash
95-
ttyd -i 127.0.0.1 --port 7681 --writable \
96-
--index ~/.cache/remobi/index.html \
97-
-t 'theme={"background":"#1e1e2e","foreground":"#cdd6f4"}' \
98-
-t 'fontFamily="JetBrainsMono NFM, monospace"' \
99-
-t 'scrollSensitivity=3' \
100-
-t 'disableLeaveAlert=true' \
101-
tmux new-session -A -s main
102-
```
103-
104-
### 3. Expose via Tailscale Serve
105-
106-
```bash
107-
tailscale serve --bg 7681
108-
```
79+
The old `ttyd` docs in this repo are historical only and are not a supported setup path on current releases.
10980

110-
Note: with the manual approach, PWA file refs (`/manifest.json`, `/apple-touch-icon.png`) will 404 — ttyd only serves a single HTML file. The inline SVG favicon still works. Use `remobi serve` for full PWA support.
81+
If you are tempted to run `remobi serve --host 0.0.0.0`, be explicit about the trade-off: that bypasses the localhost-only default and exposes terminal control directly on the bound network interface. Prefer keeping remobi on loopback and letting Tailscale handle reachability.

.agents/skills/remobi-setup/references/ttyd-flags.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Recommended ttyd flags
22

3-
Reference for ttyd flags that work well with remobi.
3+
Historical reference for old ttyd-based remobi setups.
44

5-
> **Note:** `remobi serve` generates these flags automatically from your config. This guide is for manual `ttyd` usage with `remobi build`.
5+
> **Legacy only:** current remobi releases no longer use `ttyd`, `remobi serve` does not generate ttyd flags, and `remobi build` is deprecated. Use `remobi serve` for supported setups. Keep this page only for understanding or migrating old pre-runtime installs.
66
77
## Essential flags
88

.github/workflows/ci.yml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,26 @@ name: CI
22

33
on:
44
push:
5-
branches: [main]
5+
branches: [main, dev]
66
pull_request:
7-
branches: [main]
7+
branches: [main, dev]
88

99
jobs:
1010
check:
1111
runs-on: ubuntu-latest
1212
steps:
1313
- uses: actions/checkout@v4
1414
- uses: jdx/mise-action@v3
15+
# node-pty stable does not ship Linux prebuilds, so CI must support source builds.
16+
- name: Verify native build prerequisites
17+
run: |
18+
python3 --version
19+
node-gyp --version
1520
- run: pnpm install
1621
- run: pnpm exec playwright install --with-deps chromium webkit
1722
- run: pnpm test
1823
- run: pnpm run build:dist
1924
- run: pnpm run test:pw
20-
- name: Validate build pipeline (inject mode, no ttyd needed)
21-
run: echo '<html><head></head><body></body></html>' | npx tsx cli.ts inject > /dev/null
2225
- run: pnpm run check
2326
- run: pnpm run lint:ox
2427
- run: pnpm run lint:typos
@@ -27,7 +30,7 @@ jobs:
2730
- run: pnpm exec tsc --noEmit
2831

2932
release:
30-
if: github.ref == 'refs/heads/main'
33+
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev'
3134
needs: check
3235
runs-on: ubuntu-latest
3336
permissions:
@@ -40,6 +43,10 @@ jobs:
4043
with:
4144
fetch-depth: 0
4245
- uses: jdx/mise-action@v3
46+
- name: Verify native build prerequisites
47+
run: |
48+
python3 --version
49+
node-gyp --version
4350
- run: pnpm install
4451
- run: npx semantic-release
4552
env:

.hk-hooks/commit-msg

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
#!/bin/sh
2-
exec hk run commit-msg "$@"
2+
set -eu
3+
4+
hk run commit-msg "$@"
5+
pnpm exec tsx scripts/check-breaking-footer.ts "$1"

.releaserc.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
{
2-
"branches": ["main"],
2+
"branches": [
3+
"main",
4+
{
5+
"name": "dev",
6+
"channel": "dev",
7+
"prerelease": "dev"
8+
}
9+
],
310
"plugins": [
411
"@semantic-release/commit-analyzer",
512
"@semantic-release/release-notes-generator",

AGENTS.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@ Monitor and control your coding agents from your phone. Touch controls for tmux
44

55
## Architecture
66

7-
Pure TypeScript + DOM API — no framework. Transpiles to JS via tsdown for npm distribution. Produces a single `index.html` for ttyd's `--index` flag via esbuild.
7+
Pure TypeScript + DOM API — no framework. Transpiles to JS via tsdown for npm distribution. Bundles a browser client via esbuild and serves it from Node.
88

99
## Stack
1010

1111
- **Node 22+** — runtime
1212
- **pnpm** — package manager
13-
- **esbuild** — browser bundle (overlay JS)
13+
- **esbuild** — browser client bundle
1414
- **tsdown** — transpile TS → JS for npm publish
1515
- **vitest** — test runner
1616
- **TypeScript (strict)** — no `any`, discriminated unions for actions
1717
- **Biome** — lint + format
1818
- **happy-dom** — DOM testing
1919
- **Hono** — HTTP + WebSocket server (`remobi serve`)
20+
- **node-pty** — PTY bridge for `remobi serve`
21+
- **xterm.js** — browser terminal rendering
2022

2123
## Key Commands
2224

@@ -26,7 +28,7 @@ pnpm test # Run all tests
2628
pnpm run test:pw # Playwright e2e tests (chromium + webkit)
2729
pnpm run check # Biome lint + format check
2830
pnpm run check:fix # Auto-fix lint + format
29-
pnpm run build # Build dist/index.html (dev-time, uses tsx)
31+
pnpm run build # Deprecated legacy command
3032
pnpm run build:dist # Transpile for publishing (tsdown)
3133
```
3234

@@ -51,15 +53,15 @@ Commits must follow [Conventional Commits](https://www.conventionalcommits.org/)
5153

5254
- Format: `type(scope): description`
5355
- Types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `ci`, `perf`, `style`, `build`, `revert`
54-
- Breaking changes: `!` after type/scope or `BREAKING CHANGE:` in footer
56+
- Breaking changes: include a `BREAKING CHANGE:` footer. `!` after type/scope is optional shorthand only and must be paired with the footer because semantic-release major detection relies on the footer.
5557

5658
**Choosing the right type matters** — it controls whether semantic-release publishes to npm:
5759

5860
| Type | Release | When to use |
5961
|------|---------|-------------|
6062
| `fix` | patch | Bug fix **visible to package consumers** (runtime behaviour, CLI output, published types) |
6163
| `feat` | minor | New feature visible to consumers |
62-
| `fix!`/`feat!` | major | Breaking change to public API |
64+
| `BREAKING CHANGE:` footer | major | Breaking change to public API; `!` is optional shorthand but not sufficient on its own in this repo |
6365
| `ci` | none | CI/CD workflow changes (GitHub Actions, release config) |
6466
| `chore` | none | Tooling, deps, repo hygiene — anything not shipped to consumers |
6567
| `docs` | none | Documentation only |
@@ -96,17 +98,20 @@ Commits must follow [Conventional Commits](https://www.conventionalcommits.org/)
9698
- `src/reconnect.ts` — connection loss overlay
9799
- `src/overlay-entry.ts` — IIFE entry point for browser bundle
98100
- `styles/base.css` — all CSS
99-
- `cli.ts` — CLI: build, inject, init, serve, --version
100-
- `build.ts`build pipeline: bundle → inject → output
101+
- `cli.ts` — CLI: serve, init, deprecated build/inject, --version
102+
- `build.ts`browser client bundling + HTML rendering
101103

102104
## Publishing
103105

104106
- Transpiles to JS via tsdown: `bin``dist/cli.mjs`, `exports``dist/*.mjs` + `dist/*.d.mts`
105107
- `files` array controls what's published: `dist/`, `styles/`, `src/pwa/icons/`, `README.md`, `CHANGELOG.md`, `LICENSE`
106108
- CI: `.github/workflows/ci.yml` — pnpm test + biome check
107-
- Release: `release` job in `.github/workflows/ci.yml` — semantic-release on push to main, gated on `check` job
109+
- Release: `release` job in `.github/workflows/ci.yml` — semantic-release on push to `main` and `dev`, gated on `check` job
108110
- Versioning, changelog, npm publish, and GitHub Release are all automated
109111
- `npx semantic-release --dry-run` for local verification
112+
- Stable channel: `main` → npm `latest`
113+
- Prerelease channel: `dev` → npm `dev` + GitHub prereleases
114+
- Promote experimental releases by merging `dev` into `main`
110115
- Release triggers: `feat:` → minor, `fix:` → patch, `BREAKING CHANGE` → major
111116
- No release: `chore:`, `docs:`, `refactor:`, `test:`, `ci:`
112117
- See **Local Development** above for running from source

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,32 @@
1+
# [1.0.0-dev.1](https://github.com/connorads/remobi/compare/v0.5.1-dev.2...v1.0.0-dev.1) (2026-03-27)
2+
3+
4+
### chore
5+
6+
* mark built-in runtime migration as breaking ([20d466b](https://github.com/connorads/remobi/commit/20d466b68d861c697b90b51524f7a2956ca33e50))
7+
8+
9+
### BREAKING CHANGES
10+
11+
* remobi replaces the ttyd-based runtime with the built-in terminal runtime.
12+
13+
## [0.5.1-dev.2](https://github.com/connorads/remobi/compare/v0.5.1-dev.1...v0.5.1-dev.2) (2026-03-24)
14+
15+
16+
### Bug Fixes
17+
18+
* load Unicode11Addon on headless mirror to align character widths ([54a3ec5](https://github.com/connorads/remobi/commit/54a3ec5b875098758d1a1b3d466f7517e025cc57))
19+
* remove terminal padding that exposed white document background ([cd92504](https://github.com/connorads/remobi/commit/cd92504c93bbc223979a3c77b60a90b0f10a13da)), closes [#terminal](https://github.com/connorads/remobi/issues/terminal)
20+
* set document background from theme to eliminate white border ([5c821ca](https://github.com/connorads/remobi/commit/5c821ca9d7e4aaea6ac6531bc93116b24166807e)), closes [#1e1e2e](https://github.com/connorads/remobi/issues/1e1e2e) [#terminal-container](https://github.com/connorads/remobi/issues/terminal-container) [#terminal](https://github.com/connorads/remobi/issues/terminal)
21+
* strip TMUX env vars via destructuring instead of undefined assignment ([33fa6ec](https://github.com/connorads/remobi/commit/33fa6ec2ee550db3d88e789afd989735918685db))
22+
23+
## [0.5.1-dev.1](https://github.com/connorads/remobi/compare/v0.5.0...v0.5.1-dev.1) (2026-03-22)
24+
25+
26+
### Bug Fixes
27+
28+
* guard handleClientMessage against resize on exited PTY ([41043ee](https://github.com/connorads/remobi/commit/41043eee23b86005d180ecae770c1055aaa538de))
29+
130
# [0.5.0](https://github.com/connorads/remobi/compare/v0.4.0...v0.5.0) (2026-03-20)
231

332

0 commit comments

Comments
 (0)