@devrouter/cli 0.0.30 → 0.0.31

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
@@ -108,7 +108,9 @@ vars. Use it when you are not (yet) on a devcontainer. Fully supported.
108
108
  - `devrouter workspace up <branch> [--path <dir>] [--no-devpod] [--open] [--repo <path>]`
109
109
  - `devrouter workspace ensure [path] [--open]`
110
110
  - `devrouter workspace ls [--repo <path>] [--json]`
111
- - `devrouter workspace down <workspace|branch> [--keep-worktree] [--keep-devpod] [--repo <path>]`
111
+ - `devrouter workspace stop <workspace|branch> [--repo <path>]`
112
+ - `devrouter workspace down <workspace|branch> [--keep-worktree] [--repo <path>]`
113
+ - `devrouter workspace gc [--repo <path>] [--json] [--yes]`
112
114
 
113
115
  The current `devrouter repo devcontainer write` scaffold is intentionally narrow:
114
116
  Node + pnpm + Postgres. Other package managers stop with a JSON diagnostic
@@ -126,12 +128,13 @@ mutate local route state.
126
128
 
127
129
  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.
128
130
 
129
- Each linked worktree stores one stable identity in its Git metadata. Once stored,
130
- that value is authoritative: an explicit flag or `DEVROUTER_WORKSPACE` may repeat
131
- it but cannot silently rename the environment. On first use, devrouter reuses the
132
- exact DevPod already bound to the worktree path or derives a sanitized identity
133
- from the linked branch/path. Ambiguous identities and DevPods owned by another
134
- worktree fail closed. The primary checkout keeps its plain, non-namespaced routes.
131
+ Each managed linked worktree keeps its local token in Git metadata and a durable
132
+ owner record under the repository's Git common directory. The record survives
133
+ out-of-band linked-worktree removal and ties the exact worktree path to its DevPod
134
+ ID. On first use, devrouter reuses an exact-path DevPod or derives a sanitized
135
+ identity from the linked branch/path. Ambiguous identities and DevPods owned by
136
+ another worktree fail closed. The primary checkout keeps its plain,
137
+ non-namespaced routes.
135
138
 
136
139
  **When a workspace token is active:**
137
140
 
@@ -151,15 +154,41 @@ devrouter workspace up feat/my-feature
151
154
  # Reconcile an existing linked worktree (canonical agent startup command)
152
155
  devrouter workspace ensure .
153
156
 
154
- # List git worktrees with workspace tokens and route counts
157
+ # List ownership, Git, DevPod, and route state
155
158
  devrouter workspace ls
156
159
 
157
- # Tear down a workspace (stop devpod, remove worktree, free routes)
160
+ # Pause runtime while preserving the checkout, owner record, and data
161
+ devrouter workspace stop feat/my-feature
162
+
163
+ # Delete runtime and routes, then remove the clean worktree and owner record
158
164
  devrouter workspace down feat/my-feature
165
+
166
+ # Review missing owners; add --yes only after reviewing the dry run
167
+ devrouter workspace gc
168
+ devrouter workspace gc --yes
159
169
  ```
160
170
 
161
171
  New worktrees default to the repository's ignored `trees/<workspace>` directory; use `--path` only when a repository intentionally follows another layout.
162
172
 
173
+ | Command | DevPod | Routes | Worktree and owner record |
174
+ | --- | --- | --- | --- |
175
+ | `workspace stop` | stop | remove | keep |
176
+ | `workspace down` | delete | remove | remove only when clean and unlocked |
177
+ | `workspace down --keep-worktree` | delete | remove | keep |
178
+ | `workspace gc` | report only | report only | never removes Git worktrees |
179
+ | `workspace gc --yes` | delete eligible missing owners | remove exact owned routes | remove only the owner record |
180
+
181
+ `workspace ls` reports owner status as `present`, `missing`, `locked`, or
182
+ `conflict`. Full `workspace down` checks ownership, the Git registration, lock,
183
+ and cleanliness before changing runtime or routes; dirty and locked worktrees fail
184
+ with zero teardown side effects.
185
+
186
+ Workspace lifecycle commands require a Git repository. Normal config, app,
187
+ status, and diagnostic commands remain usable from a `.devrouter.yml` directory
188
+ without Git. Git has no worktree-removal hook, so devrouter does not install one:
189
+ after manual removal, use `workspace ls`, `doctor`, or the dry-run
190
+ `workspace gc` report before applying cleanup with `--yes`.
191
+
163
192
  **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>`. `.devcontainer/docker-compose.devrouter.yml` passes `WORKSPACE` and `DEVROUTER_WORKSPACE` into the app and bind-mounts `${DEVROUTER_GIT_COMMON_DIR}` to the same absolute container path, so linked-worktree `.git` pointers remain valid. Workspace `feat-a` → alias `feat-a-app`, host `app.feat-a.localhost`.
164
193
 
165
194
  `workspace ensure` is intentionally proof-driven: it verifies exact worktree
@@ -176,7 +205,10 @@ agent-native devcontainer path end to end — `./run.sh` brings up a DevPod
176
205
  workspace, registers app/Postgres proxy routes, runs static/live verification,
177
206
  and prints the proof. `./run.sh down` tears it down.
178
207
 
179
- **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.
208
+ **Missing-owner detection:** `devrouter doctor` reports ledger-owned workspaces
209
+ whose checkout disappeared or conflicts with live Git/DevPod evidence. It does
210
+ not mutate workspace state and prints the exact dry-run remediation command:
211
+ `devrouter workspace gc --repo <repo>`.
180
212
 
181
213
  ## Upgrade metadata and prompts
182
214
 
@@ -243,7 +275,7 @@ devrouter doctor --repo /absolute/path/to/repo --json
243
275
  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.
244
276
  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.
245
277
  When `.devcontainer/` exists, `devrouter doctor` checks devnet aliases, published host ports, and proxy upstream alias matches.
246
- `devrouter doctor` reports stale host routes and orphaned workspace proxy routes without mutating route state.
278
+ `devrouter doctor` reports stale host routes and ownership cleanup candidates without mutating route state; workspace findings point to dry-run `devrouter workspace gc --repo <repo>`.
247
279
 
248
280
  ## `.devrouter.yml` example
249
281