@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 +21 -0
- package/README.md +371 -0
- package/README_KO.md +371 -0
- package/bin/dev-proxy.js +3 -0
- package/dist/bootstrap.js +3 -0
- package/dist/cli/config-io.js +110 -0
- package/dist/cli/output.js +37 -0
- package/dist/cli.js +78 -0
- package/dist/commands/config.js +60 -0
- package/dist/commands/doctor.js +334 -0
- package/dist/commands/help.js +7 -0
- package/dist/commands/init.js +199 -0
- package/dist/commands/project.js +69 -0
- package/dist/commands/status.js +30 -0
- package/dist/commands/version.js +10 -0
- package/dist/commands/worktree.js +292 -0
- package/dist/components/app.js +394 -0
- package/dist/components/detail-panel.js +122 -0
- package/dist/components/footer-bar.js +62 -0
- package/dist/components/request-list.js +104 -0
- package/dist/components/splash.js +32 -0
- package/dist/components/status-bar.js +19 -0
- package/dist/hooks/use-mouse.js +66 -0
- package/dist/index.js +153 -0
- package/dist/proxy/certs.js +68 -0
- package/dist/proxy/config.js +78 -0
- package/dist/proxy/routes.js +70 -0
- package/dist/proxy/server.js +403 -0
- package/dist/proxy/types.js +1 -0
- package/dist/proxy/worktrees.js +116 -0
- package/dist/store.js +567 -0
- package/dist/utils/format.js +121 -0
- package/dist/utils/list-layout.js +48 -0
- package/package.json +83 -0
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
|
+
[](https://www.npmjs.com/package/@reopt-ai/dev-proxy)
|
|
4
|
+
[](https://github.com/reopt-ai/dev-proxy/actions/workflows/ci.yml)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](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
|
+

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