@devrouter/cli 0.0.22 → 0.0.23

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/README.md CHANGED
@@ -27,13 +27,12 @@ This is the only supported per-repo config for app routing/runtime definitions.
27
27
 
28
28
  Both are configured the same way (`.devrouter.yml`) and can be mixed in one repo.
29
29
 
30
- ### 1. Front a devcontainer / existing process `runtime: proxy` (preferred)
30
+ ### 1. Front a devcontainer / existing process: `runtime: proxy` (preferred)
31
31
 
32
- The recommended setup going forward. A **devcontainer** (DevPod, VS Code Dev
33
- Containers, `@devcontainers/cli`, Codespaces) owns the *environment* — toolchain,
34
- databases, auth mocks, the app process, seeding and publishes the app on a local
35
- port. devrouter is a thin **routing layer**: it puts a stable `*.localhost` HTTPS
36
- host (shared `:443`, mkcert TLS) in front of that port and does nothing else.
32
+ The recommended setup is devcontainer first. The devcontainer owns the toolchain,
33
+ databases, auth mocks, app process, and seed data. devrouter owns only the local
34
+ routes. In the best case the container joins `devnet` and exposes stable network
35
+ aliases, so the app and database need no published host ports.
37
36
 
38
37
  ```yaml
39
38
  apps:
@@ -41,18 +40,20 @@ apps:
41
40
  host: myapp.localhost
42
41
  protocol: http
43
42
  runtime: proxy
44
- upstream: 127.0.0.1:3000 # the port your devcontainer publishes
43
+ upstream: myapp-app:3000 # devnet alias inside the devcontainer compose
45
44
  ```
46
45
 
47
46
  ```bash
48
- dev up && dev tls install # one-time
49
- dev app run app # registers the route; the container owns start/stop
47
+ dev setup --yes
48
+ devpod up .
49
+ dev repo devcontainer verify --live --yes --json
50
50
  ```
51
51
 
52
52
  Why prefer it: the environment is reproducible and runs anywhere the devcontainer
53
- spec runs (including remote/cloud via DevPod), devrouter never duplicates the
54
- DB/lifecycle/env work, and the two layers can't fight. See
55
- [`docs/DEVCONTAINER.md`](./docs/DEVCONTAINER.md) for the end-to-end walkthrough.
53
+ spec runs, while devrouter gives it stable local HTTPS and database hostnames.
54
+ Agents can add the scaffold with `dev repo inspect`, `dev repo devcontainer write`,
55
+ and `dev repo devcontainer verify`, then include the JSON evidence in a PR. See
56
+ [`docs/DEVCONTAINER.md`](./docs/DEVCONTAINER.md) for the full reference.
56
57
 
57
58
  ### 2. devrouter runs everything — `runtime: host` / `runtime: docker`
58
59
 
@@ -65,6 +66,7 @@ vars. Use it when you are not (yet) on a devcontainer. Fully supported.
65
66
  - `dev init [--repo <path>] [--entries-json <json>] [--json] [--write-agents] [--write-skill] [--with-linear]`
66
67
  - `dev -V [--repo <path>]` (installed CLI version, local repo version, next upgrade target)
67
68
  - `dev upgrade [version] [--repo <path>]`
69
+ - `dev setup --yes [--repo <path>] [--json]`
68
70
  - `dev up`
69
71
  - `dev down`
70
72
  - `dev status [--repo <path>] [--json]`
@@ -73,17 +75,27 @@ vars. Use it when you are not (yet) on a devcontainer. Fully supported.
73
75
  - `dev open <name>` (matches app name, then service/container/host)
74
76
  - `dev tls install`
75
77
  - `dev repo init [--repo <path>]`
78
+ - `dev repo inspect [--repo <path>] [--json]`
79
+ - `dev repo devcontainer write [--repo <path>] [--dry-run] [--yes] [--json]`
80
+ - `dev repo devcontainer verify [--repo <path>] [--live] [--yes] [--json]`
76
81
  - `dev repo agents [--repo <path>] [--with-linear]`
77
82
  - `dev app add ...` (`--kind app|dependency`, default `app`)
78
83
  - `dev app ls [--repo <path>] [--json]`
79
84
  - `dev app run <name> [--repo <path>] [--yes] [--workspace <slug>]`
80
- - `dev app exec <name> [--repo <path>] [--yes] [--shell] [--env-map TARGET=SOURCE] [--workspace <slug>] -- <command>`
85
+ - `dev app exec <name> [--repo <path>] [--yes] [--shell] [--env <env>] [--workspace <slug>] -- <command>`
81
86
  - `dev app rm <name> [--repo <path>]`
82
87
  - `dev logs [-f]`
83
88
  - `dev workspace up <branch> [--path <dir>] [--no-devpod] [--open] [--repo <path>]`
84
89
  - `dev workspace ls [--repo <path>] [--json]`
85
90
  - `dev workspace down <workspace|branch> [--keep-worktree] [--keep-devpod] [--repo <path>]`
86
91
 
92
+ The current `dev repo devcontainer write` scaffold is intentionally narrow:
93
+ Node + pnpm + Postgres. Other package managers stop with a JSON diagnostic
94
+ instead of writing files that would need manual repair.
95
+ Use `dev repo devcontainer verify --json` for read-only PR evidence; add
96
+ `--live --yes` only after the devcontainer is running and route probes should
97
+ mutate local route state.
98
+
87
99
  ## Workspace isolation (parallel worktrees)
88
100
 
89
101
  A **workspace token** lets several git worktrees of the same repo run side-by-side without host or route collisions. The token is a single identity spanning three layers: the devpod workspace id, the routes devrouter registers, and the `${WORKSPACE}` placeholder in `.devrouter.yml` proxy upstreams and devcontainer compose network aliases.
@@ -121,7 +133,12 @@ dev workspace down feat/my-feature
121
133
 
122
134
  **Try it:** [`examples/workspace/`](examples/workspace/) is a runnable showcase — `./run.sh` brings up one app in two parallel worktrees (`wsdemo.localhost` and `wsdemo.feat-a.localhost`) served at once, then `./run.sh down` tears it down.
123
135
 
124
- **GC:** `dev doctor` check `routes.orphaned-workspace-routes` reclaims proxy routes whose worktree directory was removed without `dev workspace down`. Only orphaned workspace routes are reclaimed; primary-checkout routes are never touched.
136
+ **DevPod example:** [`examples/devcontainer/`](examples/devcontainer/) is the
137
+ agent-native devcontainer path end to end — `./run.sh` brings up a DevPod
138
+ workspace, registers app/Postgres proxy routes, runs static/live verification,
139
+ and prints the proof. `./run.sh down` tears it down.
140
+
141
+ **Orphan detection:** `dev doctor` check `routes.orphaned-workspace-routes` reports proxy routes whose worktree directory was removed without `dev workspace down`. It does not mutate route state.
125
142
 
126
143
  ## Upgrade metadata and prompts
127
144
 
@@ -180,7 +197,7 @@ When `--with-linear` is combined with AGENTS writes, devrouter captures minimal
180
197
 
181
198
  ## Health diagnostics
182
199
 
183
- Run deep checks for global router state and repo configuration:
200
+ Run check-only diagnostics for global router state, machine prerequisites, route state, and repo configuration:
184
201
 
185
202
  ```bash
186
203
  dev doctor --repo /absolute/path/to/repo
@@ -195,7 +212,8 @@ dev doctor --repo /absolute/path/to/repo --json
195
212
  `dev status` now includes readiness hints and next-step commands.
196
213
  For host apps that depend on postgres, `dev doctor` also checks host command wrapper precedence and warns with `repo.host-command-env-precedence` when `DATABASE_URI`/`DATABASE_URL` is assigned before a `run --` wrapper boundary.
197
214
  When TLS is enabled, `dev doctor` also checks TLS host coverage and warns with `repo.tls-host-coverage` if configured `.localhost` hosts are not covered by the current cert SANs.
198
- `dev doctor` also reclaims orphaned workspace proxy routes (`routes.orphaned-workspace-routes`) whose worktree directory was removed without `dev workspace down`.
215
+ When `.devcontainer/` exists, `dev doctor` checks devnet aliases, published host ports, and proxy upstream alias matches.
216
+ `dev doctor` reports stale host routes and orphaned workspace proxy routes without mutating route state.
199
217
 
200
218
  ## `.devrouter.yml` example
201
219
 
@@ -255,9 +273,8 @@ Notes:
255
273
 
256
274
  - `kind` defaults to routed app behavior. Use `kind: dependency` for non-routed Docker dependencies.
257
275
  - `runtime: proxy` registers an HTTP route to an externally-managed `upstream` (`host:port`) and does nothing else — use it to put a stable `*.localhost` HTTPS host in front of a devcontainer or any process you start yourself. Loopback upstreams (`localhost`/`127.0.0.1`/`0.0.0.0`) are rewritten to `host.docker.internal` so Traefik (in Docker) can reach the host. The route persists until `dev app rm`.
258
- - TCP mode currently supports PostgreSQL first (`tcpProtocol: postgres`).
259
- - Multi-DB hostname routing on shared `:5432` requires TLS/SNI.
260
- - Plaintext Postgres is not supported for multiplexed hostname routing.
276
+ - TCP routing supports `tcpProtocol: postgres`, `redis`, `mariadb`, and `mysql` on shared protocol ports with TLS/SNI.
277
+ - Plaintext TCP is not supported for multiplexed hostname routing.
261
278
  - Multi-segment `.localhost` hosts are supported (for example `elearning.klicker.localhost`).
262
279
 
263
280
  ## Runtime behavior
@@ -274,24 +291,33 @@ Notes:
274
291
  - prints recent dependency logs (last 20 lines) after deps start
275
292
  - `kind=dependency` apps are dependency-only: they do not create routes and cannot be direct targets for `dev app run`, `dev app exec`, or `dev open`
276
293
  - `kind=dependency` services start as declared in compose (no Traefik labels, no random published ports, no injected env vars)
277
- - for TCP deps of host apps: publishes a random host port and injects `<NAME>_HOST`/`<NAME>_PORT` env vars into the host process; for postgres deps also injects `DATABASE_URL` and `SHADOW_DATABASE_URL` (fixed credentials `prisma:prisma`, databases `prisma`/`shadow`)
294
+ - for TCP deps of host apps: publishes a random host port and injects per-dependency `<NAME>_HOST`/`<NAME>_PORT`/`<NAME>_URL` env vars into the host process; for postgres deps also injects `<NAME>_SHADOW_URL` (fixed credentials `prisma:prisma`, databases `prisma`/`shadow`)
278
295
  - for one-shot commands, `dev app exec` starts declared docker deps as needed and only stops deps it started in that invocation (already-running deps stay running)
279
296
  - if `dev app exec` cannot determine pre-existing running services, it leaves selected deps running to avoid stopping non-owned services
280
297
  - when TLS is enabled, `dev app run` / `dev app exec` auto-refresh cert SAN coverage for configured repo hosts before startup (fails fast with `Run: dev tls install` guidance if refresh fails)
281
298
  - for one-shot commands, `dev app exec` preserves argv semantics by default (`shell: false`) to avoid nested quoting issues
282
299
  - `dev app exec --shell` is explicit and requires one command string after `--`
283
- - `dev app exec --env-map TARGET=SOURCE` (repeatable) maps aliases after dependency env resolution (for example `DATABASE_URI=DATABASE_URL`)
300
+ - config-level `envMap` on dependency references maps aliases after dependency env resolution (for example `DATABASE_URL: DB_URL`)
284
301
  - starts host app command for host runtime apps
285
302
  - generates docker overlay in `~/.config/devrouter/cache/...` for docker runtime apps
286
303
 
287
304
  Secret manager interop (Infisical/Doppler):
288
305
 
289
- - dependency env injection from devrouter includes `<NAME>_HOST`, `<NAME>_PORT`, `DATABASE_URL`, and `SHADOW_DATABASE_URL`
306
+ - dependency env injection from devrouter includes `<NAME>_HOST`, `<NAME>_PORT`, `<NAME>_URL`, and postgres-only `<NAME>_SHADOW_URL`
290
307
  - do not assume secret-manager precedence when DB vars overlap; validate effective env before migrate/seed
291
308
  - avoid pre-wrapper DB assignments such as `DATABASE_URI=... <wrapper> run -- ...`; wrapper-managed env may override those values
292
- - safe host-run override pattern when wrapper also defines `DATABASE_URI`: `infisical run --projectId <id> --env=<env> -- env DATABASE_URI=${DATABASE_URL:?missing DATABASE_URL} pnpm dev`
293
- - non-Prisma mapping example: `dev app exec web --yes --env-map DATABASE_URI=DATABASE_URL -- infisical run --projectId <id> --env=<env> -- pnpm payload migrate`
294
- - env probe example: `dev app exec web --yes --env-map DATABASE_URI=DATABASE_URL -- printenv DATABASE_URL DATABASE_URI DB_HOST DB_PORT SHADOW_DATABASE_URL`
309
+ - map app-specific names in `.devrouter.yml`:
310
+ ```yaml
311
+ dependencies:
312
+ - app: db
313
+ envMap:
314
+ DATABASE_URL: DB_URL
315
+ DIRECT_URL: DB_URL
316
+ SHADOW_DATABASE_URL: DB_SHADOW_URL
317
+ ```
318
+ - safe host-run override pattern when wrapper also defines `DATABASE_URI`: `infisical run --projectId <id> --env=<env> -- env DATABASE_URI=${DB_URL:?missing DB_URL} pnpm dev`
319
+ - non-Prisma mapping example: `dev app exec web --yes -- infisical run --projectId <id> --env=<env> -- pnpm payload migrate`
320
+ - env probe example: `dev app exec web --yes -- printenv DB_URL DATABASE_URL DB_HOST DB_PORT DB_SHADOW_URL SHADOW_DATABASE_URL`
295
321
  - run `dev doctor --repo <path>` to surface risky wrapper precedence (`repo.host-command-env-precedence`) before migrations or app startup
296
322
 
297
323
  `dev ls` output includes both configured app identity (`APP`) and runtime service identity (`SERVICE`).
@@ -316,11 +342,11 @@ Expected endpoints:
316
342
  - `https://web.localhost`
317
343
  - `postgres://db.localhost:5432 (tls required)`
318
344
 
319
- ## Demo workspace (in this repo)
345
+ ## Routing example (without devcontainers)
320
346
 
321
- A complete sample repository is included at:
347
+ A complete no-devcontainer sample repository is included at:
322
348
 
323
- - [`./demo`](./demo)
349
+ - [`./examples/routing`](./examples/routing)
324
350
 
325
351
  It contains:
326
352
 
@@ -329,15 +355,24 @@ It contains:
329
355
  - Postgres in Docker (`db`)
330
356
  - ready-to-use `.devrouter.yml`
331
357
 
332
- Run the end-to-end smoke demo:
358
+ Run the bundled routing smoke:
359
+
360
+ ```bash
361
+ pnpm routing:smoke
362
+ ```
363
+
364
+ Run the live DevPod/devcontainer smoke when Docker, DevPod, and mkcert are
365
+ available:
333
366
 
334
367
  ```bash
335
- pnpm demo:smoke
368
+ pnpm devcontainer:smoke
369
+ pnpm devcontainer:smoke down
336
370
  ```
337
371
 
338
372
  See details:
339
373
 
340
- - [`./demo/README.md`](./demo/README.md)
374
+ - [`./examples/routing/README.md`](./examples/routing/README.md)
375
+ - [`./examples/devcontainer/README.md`](./examples/devcontainer/README.md)
341
376
 
342
377
  ## AI agent discoverability
343
378
 
@@ -380,8 +415,8 @@ Required Linear execution hygiene:
380
415
 
381
416
  - Host-runtime dependencies are not auto-started; only Docker dependencies are auto-started.
382
417
  - `kind=dependency` apps are not direct run/exec/open targets (must be started via a routed app dependency graph).
383
- - TCP routing currently supports PostgreSQL only (`tcpProtocol: postgres`).
384
- - Shared `:5432` hostname multiplexing requires TLS/SNI (`sslmode=require` or stronger).
418
+ - TCP routing supports `tcpProtocol: postgres`, `redis`, `mariadb`, and `mysql`.
419
+ - Shared TCP hostname multiplexing requires TLS/SNI (`sslmode=require` or protocol-equivalent client SNI).
385
420
 
386
421
  ## Router state
387
422
 
@@ -400,6 +435,6 @@ Global managed artifacts remain under:
400
435
  - Setup and bootstrapping: [`docs/GETTING_STARTED.md`](./docs/GETTING_STARTED.md)
401
436
  - Onboarding repositories and AI prompt: [`docs/REPO_ONBOARDING.md`](./docs/REPO_ONBOARDING.md)
402
437
  - Agent contributor guide: [`AGENTS.md`](./AGENTS.md)
403
- - Demo workspace: [`./demo/README.md`](./demo/README.md)
438
+ - Routing example: [`./examples/routing/README.md`](./examples/routing/README.md)
404
439
  - Roadmap: [`docs/PLAN.md`](./docs/PLAN.md)
405
440
  - Release and adaptation history: [`CHANGELOG.md`](./CHANGELOG.md) and [`upgrade-prompts/`](./upgrade-prompts/)