@reopt-ai/dev-proxy 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 reopt.ai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,371 @@
1
+ # dev-proxy
2
+
3
+ [![npm](https://img.shields.io/npm/v/@reopt-ai/dev-proxy)](https://www.npmjs.com/package/@reopt-ai/dev-proxy)
4
+ [![CI](https://github.com/reopt-ai/dev-proxy/actions/workflows/ci.yml/badge.svg)](https://github.com/reopt-ai/dev-proxy/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
6
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D20.11-brightgreen.svg)](https://nodejs.org)
7
+
8
+ **Subdomain-based reverse proxy with a real-time HTTP/WS traffic inspector TUI.**
9
+
10
+ Built for agentic development workflows where dozens of services, worktrees, and AI-driven coding sessions run simultaneously — one proxy to route them all, one terminal to see everything.
11
+
12
+ Routes `*.{domain}:3000` requests to local services by subdomain and displays all traffic in a terminal dashboard. Think of it as a lightweight, terminal-native alternative to tools like Charles or Proxyman — purpose-built for local multi-service development.
13
+
14
+ [한국어 문서 (Korean)](README_KO.md)
15
+
16
+ ![dev-proxy screenshot](docs/screenshot.png)
17
+
18
+ ## Why dev-proxy?
19
+
20
+ When developing with multiple local services (frontend, API, auth, docs, admin...), you need a way to route requests by subdomain and see what's happening. Existing options are either too heavy (nginx, Caddy) or GUI-only (Charles, Proxyman).
21
+
22
+ dev-proxy is:
23
+
24
+ - **Zero-config start** — Works out of the box with `localhost` and auto-generated TLS certs
25
+ - **Terminal-native** — No browser windows to manage; lives where you already work
26
+ - **Vim-style navigation** — `j`/`k` to browse, `/` to search, `r` to replay
27
+ - **Worktree-aware** — Routes `branch--app.domain` to per-worktree ports automatically
28
+ - **Lightweight** — Two runtime dependencies (`ink` + `react`), ~10fps throttled rendering
29
+
30
+ ## Features
31
+
32
+ - Real-time HTTP request/response monitoring (method, status, size, latency)
33
+ - WebSocket connection tracking (OPEN / CLOSED / ERROR)
34
+ - Request/response header, cookie, and query parameter inspection
35
+ - Noise filter (`_next/`, `favicon`), error-only mode, URL/method search
36
+ - Request replay with original headers and curl copy to clipboard
37
+ - Upstream `http`/`https` and `ws`/`wss` target support
38
+ - Git worktree-based dynamic routing via project config
39
+ - Auto-generated TLS certificates via [mkcert](https://github.com/FiloSottile/mkcert)
40
+ - Project-based config: global (`~/.dev-proxy/config.json`) + per-project (`.dev-proxy.json`)
41
+
42
+ ## Prerequisites
43
+
44
+ - **Node.js** >= 20.11
45
+ - **mkcert** _(optional, for HTTPS)_ — `brew install mkcert && mkcert -install`
46
+
47
+ ## Quick Start
48
+
49
+ ### For Humans
50
+
51
+ ```bash
52
+ npm install -g @reopt-ai/dev-proxy
53
+ dev-proxy init
54
+ dev-proxy
55
+ ```
56
+
57
+ Press **Enter** to arm the inspector, then open `http://www.example.dev:3000` in your browser.
58
+
59
+ ### For LLM Agents
60
+
61
+ Paste this to your AI coding agent (Claude Code, Cursor, Copilot, etc.):
62
+
63
+ > Install and configure dev-proxy by following the instructions here:
64
+ > https://raw.githubusercontent.com/reopt-ai/dev-proxy/main/docs/guide/installation.md
65
+
66
+ ## Install
67
+
68
+ ```bash
69
+ # npx (no install)
70
+ npx @reopt-ai/dev-proxy
71
+
72
+ # Global install
73
+ npm install -g @reopt-ai/dev-proxy
74
+
75
+ # From source
76
+ git clone https://github.com/reopt-ai/dev-proxy.git
77
+ cd dev-proxy && pnpm install && pnpm proxy
78
+ ```
79
+
80
+ ## Configuration
81
+
82
+ Config is split into two layers:
83
+
84
+ 1. **`~/.dev-proxy/config.json`** — Global settings (domain, ports, TLS, project list)
85
+ 2. **`.dev-proxy.json`** — Per-project config (routes, worktrees)
86
+
87
+ ### Global Config (`~/.dev-proxy/config.json`)
88
+
89
+ ```json
90
+ {
91
+ "domain": "example.dev",
92
+ "port": 3000,
93
+ "httpsPort": 3443,
94
+ "projects": ["/path/to/your/project"]
95
+ }
96
+ ```
97
+
98
+ ### Project Config (`.dev-proxy.json`)
99
+
100
+ Place a `.dev-proxy.json` in each project root registered in `projects`. Routes and worktrees are defined here.
101
+
102
+ ```json
103
+ {
104
+ "routes": {
105
+ "www": "http://localhost:3001",
106
+ "studio": "http://localhost:3001",
107
+ "api": "http://localhost:4000",
108
+ "*": "http://localhost:3001"
109
+ },
110
+ "worktrees": {
111
+ "feature-auth": { "port": 4001 }
112
+ }
113
+ }
114
+ ```
115
+
116
+ - `"*"` is a wildcard — unmatched subdomains route here
117
+ - When multiple projects register the same subdomain, the first one wins
118
+ - `certPath`/`keyPath` are set in the global config, resolved relative to `~/.dev-proxy/`
119
+
120
+ ### HTTPS
121
+
122
+ Certificates are stored in `~/.dev-proxy/certs/`. If missing, they are auto-generated using [mkcert](https://github.com/FiloSottile/mkcert).
123
+
124
+ ```bash
125
+ brew install mkcert
126
+ mkcert -install
127
+ ```
128
+
129
+ When mkcert is installed, dev-proxy automatically generates wildcard certificates on first run. No manual steps needed.
130
+
131
+ ### Worktree Routing
132
+
133
+ dev-proxy supports git worktree-based dynamic routing. When you use `branch--app.domain` as the hostname, it routes to a per-worktree port.
134
+
135
+ **Automatic lifecycle management:**
136
+
137
+ Add `worktreeConfig` to your project's `.dev-proxy.json`. Use `services` to define per-subdomain port mappings — dev-proxy allocates ports automatically and generates a `.env.local` file so your dev servers know which port to listen on:
138
+
139
+ ```json
140
+ {
141
+ "routes": {
142
+ "www": "http://localhost:3001",
143
+ "data": "http://localhost:4001",
144
+ "*": "http://localhost:3001"
145
+ },
146
+ "worktrees": {
147
+ "main": { "ports": { "www": 3001, "data": 4001 } }
148
+ },
149
+ "worktreeConfig": {
150
+ "portRange": [4101, 5000],
151
+ "directory": "../myproject-{branch}",
152
+ "services": {
153
+ "www": { "env": "PORT" },
154
+ "data": { "env": "DATA_PORT" }
155
+ },
156
+ "envFile": ".env.local",
157
+ "hooks": {
158
+ "post-create": "pnpm install",
159
+ "post-remove": "echo cleanup done"
160
+ }
161
+ }
162
+ }
163
+ ```
164
+
165
+ Then create and destroy worktrees with a single command:
166
+
167
+ ```bash
168
+ dev-proxy worktree create feature-auth
169
+ # → git worktree add
170
+ # → allocates ports: www=4101, data=4102
171
+ # → writes .env.local: PORT=4101, DATA_PORT=4102
172
+ # → runs post-create hook (pnpm install)
173
+
174
+ dev-proxy worktree destroy feature-auth
175
+ # → runs post-remove hook, git worktree remove, releases ports
176
+ ```
177
+
178
+ **How routing works:**
179
+
180
+ - `feature-auth--www.example.dev:3000` → routes to port 4101 (www service)
181
+ - `feature-auth--data.example.dev:3000` → routes to port 4102 (data service)
182
+ - Config file is watched live — routing updates instantly on changes
183
+ - Unregistered worktrees show an offline error page instead of silently falling back
184
+
185
+ **Manual mode** (without `worktreeConfig`):
186
+
187
+ ```bash
188
+ dev-proxy worktree add feature-auth 4001 # Register single port (no git operations)
189
+ dev-proxy worktree remove feature-auth # Unregister only
190
+ ```
191
+
192
+ ## Usage
193
+
194
+ ```bash
195
+ # If installed globally or via npx
196
+ dev-proxy
197
+
198
+ # From source
199
+ pnpm proxy
200
+
201
+ # Debug mode (tsx, no build step)
202
+ pnpm proxy:src
203
+ ```
204
+
205
+ `pnpm proxy` builds `dist/` first, then runs with `NODE_ENV=production` to avoid Ink/React dev-mode memory leaks.
206
+
207
+ ### UI States
208
+
209
+ The TUI has three states:
210
+
211
+ 1. **Splash** — Shows configured routes and listening ports. Press **Enter** to arm.
212
+ 2. **Inspect** — Live traffic dashboard with list + detail panels.
213
+ 3. **Standby** — Auto-sleeps after 60s of no interaction to reduce memory pressure. Press **I** or **Enter** to resume.
214
+
215
+ ## Keybindings
216
+
217
+ ### Navigation
218
+
219
+ | Key | Action |
220
+ | --------- | --------------------------- |
221
+ | `←` / `→` | Switch list / detail focus |
222
+ | `j` / `↓` | Next request |
223
+ | `k` / `↑` | Previous request |
224
+ | `g` | Jump to first |
225
+ | `G` | Jump to last |
226
+ | `Enter` | Open detail panel |
227
+ | `Esc` | Back to list / clear search |
228
+
229
+ ### Detail Panel
230
+
231
+ | Key | Action |
232
+ | --------- | ------ |
233
+ | `↑` / `↓` | Scroll |
234
+
235
+ > Focusing the detail panel automatically disables Follow mode so your selection stays put.
236
+
237
+ ### Filters & Actions
238
+
239
+ | Key | Action |
240
+ | --- | ------------------------------------------ |
241
+ | `/` | Search mode (filter by URL or method) |
242
+ | `f` | Toggle Follow mode |
243
+ | `n` | Toggle noise filter (`_next`, `favicon`) |
244
+ | `e` | Toggle error-only mode |
245
+ | `x` | Clear all traffic and filters |
246
+ | `r` | Replay selected request (with headers) |
247
+ | `y` | Copy selected request as curl to clipboard |
248
+
249
+ ### Mouse
250
+
251
+ - **Scroll** in list or detail panel
252
+ - **Click** a row to select it
253
+ - **Click** header filter badges to toggle them
254
+
255
+ ## Security
256
+
257
+ This is a **development tool** and makes deliberate trade-offs for local development convenience:
258
+
259
+ - **`rejectUnauthorized: false`** — The proxy accepts self-signed certificates from upstream targets. This is intentional so that dev services using mkcert or self-signed certs work without extra configuration. **Do not use this proxy in production.**
260
+ - **No authentication** — The proxy binds to localhost by default with no auth layer.
261
+
262
+ ## Troubleshooting
263
+
264
+ ### Port already in use
265
+
266
+ ```
267
+ Error: port 3000 is already in use (another dev-proxy instance may already be running)
268
+ ```
269
+
270
+ Kill the existing process or use a different port in your config:
271
+
272
+ ```bash
273
+ # Find and kill
274
+ lsof -ti :3000 | xargs kill
275
+
276
+ # Or change port
277
+ # Or change port in ~/.dev-proxy/config.json: "port": 3080
278
+ ```
279
+
280
+ ### mkcert not found
281
+
282
+ ```
283
+ HTTPS disabled — mkcert not found.
284
+ ```
285
+
286
+ HTTPS is optional. Install mkcert for TLS support:
287
+
288
+ ```bash
289
+ brew install mkcert # macOS
290
+ mkcert -install
291
+ ```
292
+
293
+ ### Blank screen / Raw mode error
294
+
295
+ If you see `Raw mode is not supported`, you're running in a non-TTY context (e.g., piped output, CI). dev-proxy requires an interactive terminal.
296
+
297
+ ### Request not routing to expected target
298
+
299
+ 1. Check the splash screen — it lists all configured routes
300
+ 2. Verify your `Host` header matches `subdomain.domain:port`
301
+ 3. Ensure the target service is actually running on the configured port
302
+
303
+ ## CLI Reference
304
+
305
+ | Command | Description |
306
+ | -------------------------------------- | ------------------------------------------------ |
307
+ | `dev-proxy` | Start proxy and open traffic inspector |
308
+ | `dev-proxy init` | Interactive setup wizard |
309
+ | `dev-proxy status` | Show configuration and routing table |
310
+ | `dev-proxy doctor` | Run environment diagnostics |
311
+ | `dev-proxy config` | View global settings |
312
+ | `dev-proxy config set <key> <value>` | Modify global settings (domain, port, httpsPort) |
313
+ | `dev-proxy project add [path]` | Register a project (default: cwd) |
314
+ | `dev-proxy project remove <path>` | Unregister a project |
315
+ | `dev-proxy project list` | List registered projects |
316
+ | `dev-proxy worktree create <branch>` | Create worktree with auto port + hooks |
317
+ | `dev-proxy worktree destroy <branch>` | Destroy worktree with hooks + cleanup |
318
+ | `dev-proxy worktree add <name> <port>` | Register worktree manually (no git operations) |
319
+ | `dev-proxy worktree remove <name>` | Unregister worktree manually |
320
+ | `dev-proxy worktree list` | List all worktrees |
321
+ | `dev-proxy --help` | Show help |
322
+ | `dev-proxy --version` | Show version |
323
+
324
+ ## Architecture
325
+
326
+ ```
327
+ src/
328
+ ├── cli.ts # Subcommand router
329
+ ├── index.tsx # TUI dashboard (Ink render + proxy lifecycle)
330
+ ├── store.ts # External store (useSyncExternalStore)
331
+ ├── commands/ # CLI subcommands (Ink components)
332
+ │ ├── init.tsx # Interactive setup wizard
333
+ │ ├── status.tsx # Configuration overview
334
+ │ ├── doctor.tsx # Environment diagnostics
335
+ │ ├── config.tsx # Config view/set
336
+ │ ├── project.tsx # Project management
337
+ │ ├── worktree.tsx # Worktree management
338
+ │ ├── help.tsx # Help output
339
+ │ └── version.tsx # Version output
340
+ ├── bootstrap.ts # Startup bootstrapper (config load, proxy init)
341
+ ├── cli/ # Shared CLI components
342
+ │ ├── config-io.ts # Config I/O helpers and port allocation
343
+ │ └── output.tsx # Display components (Header, Section, Check, etc.)
344
+ ├── proxy/
345
+ │ ├── config.ts # Config loader (~/.dev-proxy + .dev-proxy.json)
346
+ │ ├── server.ts # HTTP/WS reverse proxy
347
+ │ ├── routes.ts # Subdomain → target routing
348
+ │ ├── certs.ts # TLS certificate resolution (mkcert)
349
+ │ ├── worktrees.ts # Dynamic worktree port registry
350
+ │ └── types.ts # Event types
351
+ ├── components/
352
+ │ ├── app.tsx # Root (resize, keyboard, state machine)
353
+ │ ├── splash.tsx # Splash screen
354
+ │ ├── status-bar.tsx # Top status bar
355
+ │ ├── request-list.tsx # Request list (viewport slicing)
356
+ │ ├── detail-panel.tsx # Detail panel (scrollable)
357
+ │ └── footer-bar.tsx # Bottom keybinding hints
358
+ ├── hooks/
359
+ │ └── use-mouse.ts # SGR mouse event parser
360
+ └── utils/
361
+ ├── format.ts # Color palette, formatters
362
+ └── list-layout.ts # Responsive column layout
363
+ ```
364
+
365
+ ## Contributing
366
+
367
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
368
+
369
+ ## License
370
+
371
+ [MIT](LICENSE)