@devrouter/cli 0.0.23 → 0.0.25
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 +75 -116
- package/dist/{dev.js → devrouter.js} +345 -644
- package/package.json +6 -4
- package/upgrade-prompts/0.0.24.md +10 -0
- package/upgrade-prompts/0.0.25.md +20 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Roland Schlaefli
|
|
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
CHANGED
|
@@ -44,15 +44,15 @@ apps:
|
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
|
-
|
|
47
|
+
devrouter setup --yes
|
|
48
48
|
devpod up .
|
|
49
|
-
|
|
49
|
+
devrouter 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
53
|
spec runs, while devrouter gives it stable local HTTPS and database hostnames.
|
|
54
|
-
Agents can add the scaffold with `
|
|
55
|
-
and `
|
|
54
|
+
Agents can add the scaffold with `devrouter repo inspect`, `devrouter repo devcontainer write`,
|
|
55
|
+
and `devrouter repo devcontainer verify`, then include the JSON evidence in a PR. See
|
|
56
56
|
[`docs/DEVCONTAINER.md`](./docs/DEVCONTAINER.md) for the full reference.
|
|
57
57
|
|
|
58
58
|
### 2. devrouter runs everything — `runtime: host` / `runtime: docker`
|
|
@@ -63,36 +63,36 @@ vars. Use it when you are not (yet) on a devcontainer. Fully supported.
|
|
|
63
63
|
|
|
64
64
|
## Core commands
|
|
65
65
|
|
|
66
|
-
- `
|
|
67
|
-
- `
|
|
68
|
-
- `
|
|
69
|
-
- `
|
|
70
|
-
- `
|
|
71
|
-
- `
|
|
72
|
-
- `
|
|
73
|
-
- `
|
|
74
|
-
- `
|
|
75
|
-
- `
|
|
76
|
-
- `
|
|
77
|
-
- `
|
|
78
|
-
- `
|
|
79
|
-
- `
|
|
80
|
-
- `
|
|
81
|
-
- `
|
|
82
|
-
- `
|
|
83
|
-
- `
|
|
84
|
-
- `
|
|
85
|
-
- `
|
|
86
|
-
- `
|
|
87
|
-
- `
|
|
88
|
-
- `
|
|
89
|
-
- `
|
|
90
|
-
- `
|
|
91
|
-
|
|
92
|
-
The current `
|
|
66
|
+
- `devrouter init [--repo <path>] [--entries-json <json>] [--json] [--write-agents] [--write-skill]`
|
|
67
|
+
- `devrouter -V [--repo <path>]` (installed CLI version, local repo version, next upgrade target)
|
|
68
|
+
- `devrouter upgrade [version] [--repo <path>]`
|
|
69
|
+
- `devrouter setup --yes [--repo <path>] [--json]`
|
|
70
|
+
- `devrouter up`
|
|
71
|
+
- `devrouter down`
|
|
72
|
+
- `devrouter status [--repo <path>] [--json]`
|
|
73
|
+
- `devrouter doctor|verify [--repo <path>] [--json]`
|
|
74
|
+
- `devrouter ls [--json]`
|
|
75
|
+
- `devrouter open <name>` (matches app name, then service/container/host)
|
|
76
|
+
- `devrouter tls install`
|
|
77
|
+
- `devrouter repo init [--repo <path>]`
|
|
78
|
+
- `devrouter repo inspect [--repo <path>] [--json]`
|
|
79
|
+
- `devrouter repo devcontainer write [--repo <path>] [--dry-run] [--yes] [--json]`
|
|
80
|
+
- `devrouter repo devcontainer verify [--repo <path>] [--live] [--yes] [--json]`
|
|
81
|
+
- `devrouter repo agents [--repo <path>]`
|
|
82
|
+
- `devrouter app add ...` (`--kind app|dependency`, default `app`)
|
|
83
|
+
- `devrouter app ls [--repo <path>] [--json]`
|
|
84
|
+
- `devrouter app run <name> [--repo <path>] [--yes] [--workspace <slug>]`
|
|
85
|
+
- `devrouter app exec <name> [--repo <path>] [--yes] [--shell] [--env <env>] [--workspace <slug>] -- <command>`
|
|
86
|
+
- `devrouter app rm <name> [--repo <path>]`
|
|
87
|
+
- `devrouter logs [-f]`
|
|
88
|
+
- `devrouter workspace up <branch> [--path <dir>] [--no-devpod] [--open] [--repo <path>]`
|
|
89
|
+
- `devrouter workspace ls [--repo <path>] [--json]`
|
|
90
|
+
- `devrouter workspace down <workspace|branch> [--keep-worktree] [--keep-devpod] [--repo <path>]`
|
|
91
|
+
|
|
92
|
+
The current `devrouter repo devcontainer write` scaffold is intentionally narrow:
|
|
93
93
|
Node + pnpm + Postgres. Other package managers stop with a JSON diagnostic
|
|
94
94
|
instead of writing files that would need manual repair.
|
|
95
|
-
Use `
|
|
95
|
+
Use `devrouter repo devcontainer verify --json` for read-only PR evidence; add
|
|
96
96
|
`--live --yes` only after the devcontainer is running and route probes should
|
|
97
97
|
mutate local route state.
|
|
98
98
|
|
|
@@ -120,13 +120,13 @@ A **workspace token** lets several git worktrees of the same repo run side-by-si
|
|
|
120
120
|
|
|
121
121
|
```bash
|
|
122
122
|
# Bring up a feature branch as an isolated workspace
|
|
123
|
-
|
|
123
|
+
devrouter workspace up feat/my-feature
|
|
124
124
|
|
|
125
125
|
# List git worktrees with workspace tokens and route counts
|
|
126
|
-
|
|
126
|
+
devrouter workspace ls
|
|
127
127
|
|
|
128
128
|
# Tear down a workspace (stop devpod, remove worktree, free routes)
|
|
129
|
-
|
|
129
|
+
devrouter workspace down feat/my-feature
|
|
130
130
|
```
|
|
131
131
|
|
|
132
132
|
**devcontainer integration:** the devcontainer compose service exposes a devnet network alias `${WORKSPACE}-app` (defaulting to the project name in `devcontainer.env`); the proxy app uses `upstream: ${WORKSPACE}-app:<port>`. Workspace `feat-a` → alias `feat-a-app`, host `app.feat-a.localhost`.
|
|
@@ -138,11 +138,11 @@ agent-native devcontainer path end to end — `./run.sh` brings up a DevPod
|
|
|
138
138
|
workspace, registers app/Postgres proxy routes, runs static/live verification,
|
|
139
139
|
and prints the proof. `./run.sh down` tears it down.
|
|
140
140
|
|
|
141
|
-
**Orphan detection:** `
|
|
141
|
+
**Orphan detection:** `devrouter doctor` check `routes.orphaned-workspace-routes` reports proxy routes whose worktree directory was removed without `devrouter workspace down`. It does not mutate route state.
|
|
142
142
|
|
|
143
143
|
## Upgrade metadata and prompts
|
|
144
144
|
|
|
145
|
-
`
|
|
145
|
+
`devrouter upgrade` and `devrouter -V` read local upgrade metadata from `.devrouter.yml` in the target repo (`devrouter.version`):
|
|
146
146
|
|
|
147
147
|
```yaml
|
|
148
148
|
version: 1
|
|
@@ -153,18 +153,18 @@ apps: []
|
|
|
153
153
|
|
|
154
154
|
Quick checks:
|
|
155
155
|
|
|
156
|
-
- `
|
|
157
|
-
- `
|
|
158
|
-
- `
|
|
156
|
+
- `devrouter -V` shows installed CLI version, local repo version, and next available upgrade target.
|
|
157
|
+
- `devrouter upgrade` lists all upgrade targets newer than the local repo version and marks the next one.
|
|
158
|
+
- `devrouter upgrade <version>` prints that target release's Agent Adaptation Prompt and then shows if a further version is available.
|
|
159
159
|
- Upgrade prompts are sourced from `upgrade-prompts/<version>.md`.
|
|
160
|
-
- `
|
|
160
|
+
- `devrouter repo init` initializes `devrouter.version` to the installed CLI version.
|
|
161
161
|
|
|
162
162
|
## AI-native onboarding prompt
|
|
163
163
|
|
|
164
164
|
Generate a ready-to-copy onboarding prompt for an AI agent:
|
|
165
165
|
|
|
166
166
|
```bash
|
|
167
|
-
|
|
167
|
+
devrouter init --repo /absolute/path/to/repo
|
|
168
168
|
```
|
|
169
169
|
|
|
170
170
|
By default, this command is non-mutating (it prints prompt text only).
|
|
@@ -172,48 +172,40 @@ By default, this command is non-mutating (it prints prompt text only).
|
|
|
172
172
|
Optional: embed target app entries as JSON:
|
|
173
173
|
|
|
174
174
|
```bash
|
|
175
|
-
|
|
175
|
+
devrouter init --repo /absolute/path/to/repo --entries-json '[{"name":"web","host":"web.localhost","protocol":"http","runtime":"host"}]'
|
|
176
176
|
```
|
|
177
177
|
|
|
178
178
|
JSON mode for machine consumption:
|
|
179
179
|
|
|
180
180
|
```bash
|
|
181
|
-
|
|
181
|
+
devrouter init --repo /absolute/path/to/repo --json
|
|
182
182
|
```
|
|
183
183
|
|
|
184
184
|
Optional repo artifact writes are explicit:
|
|
185
185
|
|
|
186
186
|
```bash
|
|
187
|
-
|
|
187
|
+
devrouter init --repo /absolute/path/to/repo --write-agents --write-skill
|
|
188
188
|
```
|
|
189
189
|
|
|
190
|
-
Optional: also bootstrap Linear workflow skill/templates and AGENTS section:
|
|
191
|
-
|
|
192
|
-
```bash
|
|
193
|
-
dev init --repo /absolute/path/to/repo --with-linear --write-agents --write-skill
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
When `--with-linear` is combined with AGENTS writes, devrouter captures minimal Linear mapping (workspace, team, project). In non-interactive mode it writes placeholders and prints a warning so values can be filled in later.
|
|
197
|
-
|
|
198
190
|
## Health diagnostics
|
|
199
191
|
|
|
200
192
|
Run check-only diagnostics for global router state, machine prerequisites, route state, and repo configuration:
|
|
201
193
|
|
|
202
194
|
```bash
|
|
203
|
-
|
|
195
|
+
devrouter doctor --repo /absolute/path/to/repo
|
|
204
196
|
```
|
|
205
197
|
|
|
206
198
|
Machine-friendly output:
|
|
207
199
|
|
|
208
200
|
```bash
|
|
209
|
-
|
|
201
|
+
devrouter doctor --repo /absolute/path/to/repo --json
|
|
210
202
|
```
|
|
211
203
|
|
|
212
|
-
`
|
|
213
|
-
For host apps that depend on postgres, `
|
|
214
|
-
When TLS is enabled, `
|
|
215
|
-
When `.devcontainer/` exists, `
|
|
216
|
-
`
|
|
204
|
+
`devrouter status` now includes readiness hints and next-step commands.
|
|
205
|
+
For host apps that depend on postgres, `devrouter 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.
|
|
206
|
+
When TLS is enabled, `devrouter 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.
|
|
207
|
+
When `.devcontainer/` exists, `devrouter doctor` checks devnet aliases, published host ports, and proxy upstream alias matches.
|
|
208
|
+
`devrouter doctor` reports stale host routes and orphaned workspace proxy routes without mutating route state.
|
|
217
209
|
|
|
218
210
|
## `.devrouter.yml` example
|
|
219
211
|
|
|
@@ -272,31 +264,31 @@ apps:
|
|
|
272
264
|
Notes:
|
|
273
265
|
|
|
274
266
|
- `kind` defaults to routed app behavior. Use `kind: dependency` for non-routed Docker dependencies.
|
|
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 `
|
|
267
|
+
- `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 `devrouter app rm`.
|
|
276
268
|
- TCP routing supports `tcpProtocol: postgres`, `redis`, `mariadb`, and `mysql` on shared protocol ports with TLS/SNI.
|
|
277
269
|
- Plaintext TCP is not supported for multiplexed hostname routing.
|
|
278
270
|
- Multi-segment `.localhost` hosts are supported (for example `elearning.klicker.localhost`).
|
|
279
271
|
|
|
280
272
|
## Runtime behavior
|
|
281
273
|
|
|
282
|
-
`
|
|
274
|
+
`devrouter app run <name>`:
|
|
283
275
|
|
|
284
276
|
- reads `.devrouter.yml`
|
|
285
277
|
- prompts to start declared dependencies (or use `--yes`)
|
|
286
278
|
- starts docker target services for `runtime: docker` apps, plus declared docker dependencies
|
|
287
|
-
- for `runtime: proxy` apps: registers the route to `upstream` and returns immediately (no process started, no dependencies); re-running is an idempotent upsert and the route persists until `
|
|
279
|
+
- for `runtime: proxy` apps: registers the route to `upstream` and returns immediately (no process started, no dependencies); re-running is an idempotent upsert and the route persists until `devrouter app rm`
|
|
288
280
|
- fails fast if host-runtime dependencies are configured (start those manually)
|
|
289
281
|
- waits for Docker dependencies to become healthy (`--wait`) before proceeding
|
|
290
|
-
- automatically stops Docker dependencies when a host app exits; docker app services remain running until explicit cleanup (`docker compose down`, `
|
|
282
|
+
- automatically stops Docker dependencies when a host app exits; docker app services remain running until explicit cleanup (`docker compose down`, `devrouter down`, or equivalent)
|
|
291
283
|
- prints recent dependency logs (last 20 lines) after deps start
|
|
292
|
-
- `kind=dependency` apps are dependency-only: they do not create routes and cannot be direct targets for `
|
|
284
|
+
- `kind=dependency` apps are dependency-only: they do not create routes and cannot be direct targets for `devrouter app run`, `devrouter app exec`, or `devrouter open`
|
|
293
285
|
- `kind=dependency` services start as declared in compose (no Traefik labels, no random published ports, no injected env vars)
|
|
294
286
|
- 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`)
|
|
295
|
-
- for one-shot commands, `
|
|
296
|
-
- if `
|
|
297
|
-
- when TLS is enabled, `
|
|
298
|
-
- for one-shot commands, `
|
|
299
|
-
- `
|
|
287
|
+
- for one-shot commands, `devrouter app exec` starts declared docker deps as needed and only stops deps it started in that invocation (already-running deps stay running)
|
|
288
|
+
- if `devrouter app exec` cannot determine pre-existing running services, it leaves selected deps running to avoid stopping non-owned services
|
|
289
|
+
- when TLS is enabled, `devrouter app run` / `devrouter app exec` auto-refresh cert SAN coverage for configured repo hosts before startup (fails fast with `Run: devrouter tls install` guidance if refresh fails)
|
|
290
|
+
- for one-shot commands, `devrouter app exec` preserves argv semantics by default (`shell: false`) to avoid nested quoting issues
|
|
291
|
+
- `devrouter app exec --shell` is explicit and requires one command string after `--`
|
|
300
292
|
- config-level `envMap` on dependency references maps aliases after dependency env resolution (for example `DATABASE_URL: DB_URL`)
|
|
301
293
|
- starts host app command for host runtime apps
|
|
302
294
|
- generates docker overlay in `~/.config/devrouter/cache/...` for docker runtime apps
|
|
@@ -316,25 +308,25 @@ Secret manager interop (Infisical/Doppler):
|
|
|
316
308
|
SHADOW_DATABASE_URL: DB_SHADOW_URL
|
|
317
309
|
```
|
|
318
310
|
- 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: `
|
|
320
|
-
- env probe example: `
|
|
321
|
-
- run `
|
|
311
|
+
- non-Prisma mapping example: `devrouter app exec web --yes -- infisical run --projectId <id> --env=<env> -- pnpm payload migrate`
|
|
312
|
+
- env probe example: `devrouter app exec web --yes -- printenv DB_URL DATABASE_URL DB_HOST DB_PORT DB_SHADOW_URL SHADOW_DATABASE_URL`
|
|
313
|
+
- run `devrouter doctor --repo <path>` to surface risky wrapper precedence (`repo.host-command-env-precedence`) before migrations or app startup
|
|
322
314
|
|
|
323
|
-
`
|
|
315
|
+
`devrouter ls` output includes both configured app identity (`APP`) and runtime service identity (`SERVICE`).
|
|
324
316
|
|
|
325
317
|
## First onboarding quick path
|
|
326
318
|
|
|
327
319
|
In a repo that has a host app and a Docker Postgres service:
|
|
328
320
|
|
|
329
321
|
```bash
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
322
|
+
devrouter repo init
|
|
323
|
+
devrouter app add --name web --host web.localhost --protocol http --runtime host --command "pnpm dev" --cwd .
|
|
324
|
+
devrouter app add --name db --host db.localhost --protocol tcp --runtime docker --tcp-protocol postgres --service db --port 5432 --compose-file docker-compose.yml
|
|
325
|
+
devrouter app add --name redis --kind dependency --service redis --compose-file docker-compose.yml
|
|
326
|
+
devrouter app add --name web --host web.localhost --protocol http --runtime host --command "pnpm dev" --cwd . --depends-on db --depends-on redis
|
|
327
|
+
devrouter tls install
|
|
328
|
+
devrouter app run web --yes
|
|
329
|
+
devrouter ls
|
|
338
330
|
```
|
|
339
331
|
|
|
340
332
|
Expected endpoints:
|
|
@@ -376,40 +368,7 @@ See details:
|
|
|
376
368
|
|
|
377
369
|
## AI agent discoverability
|
|
378
370
|
|
|
379
|
-
`
|
|
380
|
-
|
|
381
|
-
If you also want Linear workflow assets and repository mapping metadata, run:
|
|
382
|
-
|
|
383
|
-
```bash
|
|
384
|
-
dev repo agents --with-linear
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
This additionally installs:
|
|
388
|
-
|
|
389
|
-
- `.agents/skills/linear-workflow/SKILL.md`
|
|
390
|
-
- `.agents/skills/linear-workflow/references/LINEAR_ISSUE_TEMPLATE.md`
|
|
391
|
-
- `.agents/skills/linear-workflow/references/MILESTONE_PLAN_TEMPLATE.md`
|
|
392
|
-
- `.agents/skills/linear-workflow/references/PROGRESS_UPDATE_TEMPLATE.md`
|
|
393
|
-
|
|
394
|
-
and appends an idempotent `linear-workflow` section to `AGENTS.md`.
|
|
395
|
-
|
|
396
|
-
With `--with-linear`, AGENTS also stores a managed config block:
|
|
397
|
-
|
|
398
|
-
- `<!-- devrouter-linear-workflow-config:start -->`
|
|
399
|
-
- `<!-- devrouter-linear-workflow-config:end -->`
|
|
400
|
-
|
|
401
|
-
The block captures:
|
|
402
|
-
|
|
403
|
-
- `workspace.name`
|
|
404
|
-
- `team.name` (optional `team.key`)
|
|
405
|
-
- `project.name` (optional `project.id`)
|
|
406
|
-
|
|
407
|
-
Required Linear execution hygiene:
|
|
408
|
-
|
|
409
|
-
1. Set issue status at session start and update it at each phase transition.
|
|
410
|
-
2. Post progress comments at meaningful checkpoints during implementation.
|
|
411
|
-
3. Before ending a session, post a final comment with completed work, remaining work, risks, and next step.
|
|
412
|
-
4. Re-check status and comment freshness toward/at session end before stopping.
|
|
371
|
+
`devrouter repo agents` writes a devrouter section into the repo's `AGENTS.md` and installs a skill file at `.agents/skills/devrouter/SKILL.md`. The skill content is embedded in the CLI bundle so it stays in sync across repos.
|
|
413
372
|
|
|
414
373
|
## Known limitations (v1)
|
|
415
374
|
|