@m-kopa/launchpad-cli 0.26.1 → 0.27.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/CHANGELOG.md +77 -0
- package/dist/auth/flow.d.ts +7 -3
- package/dist/auth/flow.d.ts.map +1 -1
- package/dist/auth/gateway-flow.d.ts +76 -0
- package/dist/auth/gateway-flow.d.ts.map +1 -0
- package/dist/auth/session.d.ts +35 -2
- package/dist/auth/session.d.ts.map +1 -1
- package/dist/cli.js +401 -103
- package/dist/commands/login.d.ts +10 -0
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/logout.d.ts +7 -0
- package/dist/commands/logout.d.ts.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +2 -2
- package/skills/launchpad-content-pr/SKILL.md +146 -124
- package/skills/launchpad-deploy/SKILL.md +153 -67
- package/skills/launchpad-deploy-status/SKILL.md +136 -36
- package/skills/launchpad-destroy/SKILL.md +163 -65
- package/skills/launchpad-onboard/SKILL.md +43 -14
- package/skills/launchpad-status/SKILL.md +119 -25
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: launchpad-status
|
|
3
3
|
description: Show whether a Launchpad app's local launchpad.yaml matches what's deployed, and read the deployed manifest. Wraps `launchpad pull` (fetch deployed YAML) and `launchpad status` (drift report). Use when someone says "is my app in sync", "what's deployed", "show drift", "/launchpad-status", "/launchpad-pull", or after `launchpad deploy` to verify the change landed.
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.27.1
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<!-- BEGIN shell-contract (managed by scripts/sync-skill-contract.sh — edit skills/_partials/shell-contract.md) -->
|
|
@@ -34,7 +34,11 @@ Read-only verbs. Zero local platform-repo / terraform / GitHub
|
|
|
34
34
|
credentials needed. Both go through the bot's `/manifest/state`
|
|
35
35
|
endpoint; the bot reads launchpad-platform's TF state to find the
|
|
36
36
|
last-applied manifest sha, then fetches launchpad.yaml from the app
|
|
37
|
-
repo at that sha.
|
|
37
|
+
repo at that sha. `launchpad status` additionally reads the bot's
|
|
38
|
+
`/apps/<slug>/lifecycle`, `/apps/<slug>/deployment-status` and
|
|
39
|
+
`/apps/<slug>/exceptions` surfaces, so it reports the **live**
|
|
40
|
+
Cloudflare Pages build truth — not just the manifest view. The CLI
|
|
41
|
+
is a thin client.
|
|
38
42
|
|
|
39
43
|
## When to use which verb
|
|
40
44
|
|
|
@@ -54,7 +58,7 @@ the answer.
|
|
|
54
58
|
|
|
55
59
|
## Pre-flight
|
|
56
60
|
|
|
57
|
-
Both verbs need a current
|
|
61
|
+
Both verbs need a current session (`launchpad login`). If the session
|
|
58
62
|
is missing or expired, surface the run-login hint:
|
|
59
63
|
|
|
60
64
|
```bash
|
|
@@ -99,6 +103,9 @@ launchpad pull horizon --out /tmp/deployed.yaml
|
|
|
99
103
|
launchpad clone horizon
|
|
100
104
|
cd launchpad-app-horizon
|
|
101
105
|
launchpad pull
|
|
106
|
+
|
|
107
|
+
# Read the role-redacted status block instead of the spec manifest
|
|
108
|
+
launchpad pull horizon --status
|
|
102
109
|
```
|
|
103
110
|
|
|
104
111
|
Exit codes:
|
|
@@ -111,22 +118,75 @@ Exit codes:
|
|
|
111
118
|
Reads `./launchpad.yaml` by default, compares to the deployed
|
|
112
119
|
manifest, reports state.
|
|
113
120
|
|
|
114
|
-
###
|
|
121
|
+
### The state union
|
|
122
|
+
|
|
123
|
+
`launchpad status` is lifecycle-aware: it reports one of a closed
|
|
124
|
+
union of states, not just a drift verdict. The drift pair:
|
|
115
125
|
|
|
116
|
-
- **`in sync`** — local and deployed are
|
|
117
|
-
equivalence relation is normalised-AST:
|
|
118
|
-
key ordering do NOT count as drift.
|
|
119
|
-
(absent key with a default ==
|
|
126
|
+
- **`in sync`** (`in_sync` in `--json`) — local and deployed are
|
|
127
|
+
equivalent. The equivalence relation is normalised-AST:
|
|
128
|
+
whitespace, comments, and key ordering do NOT count as drift.
|
|
129
|
+
Schema defaults are honoured (absent key with a default ==
|
|
130
|
+
explicit default).
|
|
120
131
|
- **`drift: <field list>`** — local and deployed differ on at least
|
|
121
132
|
one field in the v1 closed set:
|
|
122
133
|
`metadata.name`, `metadata.team`, `metadata.owner`,
|
|
123
134
|
`metadata.description`, `deployment.type`,
|
|
124
135
|
`access.allowed_entra_group`, `hostnames[0]`, `build.command`,
|
|
125
136
|
`build.destination_dir`, `build.root_dir`, `production_env.*`.
|
|
126
|
-
- **`no deployed manifest yet`** — bot reports no
|
|
127
|
-
`output "<slug>_manifest_sha"`. Run `launchpad deploy` first.
|
|
128
137
|
|
|
129
|
-
|
|
138
|
+
The lifecycle states (rendered without needing a local manifest):
|
|
139
|
+
|
|
140
|
+
- **`provisioning`** — the provisioning workflow is running; status
|
|
141
|
+
shows the current stage inline. Re-run to watch progress.
|
|
142
|
+
- **`provisioning_failed`** — the workflow failed; status names the
|
|
143
|
+
failing stage + reason. Fix the cause and re-run
|
|
144
|
+
`launchpad deploy` — or, if the app is actually serving despite
|
|
145
|
+
the failed record, `launchpad recover <slug>` reconciles the
|
|
146
|
+
record against live Cloudflare state.
|
|
147
|
+
- **`destroying` / `destroyed` / `destroy_failed`** — teardown
|
|
148
|
+
phases; route to `/launchpad-destroy`.
|
|
149
|
+
|
|
150
|
+
And the live-truth states:
|
|
151
|
+
|
|
152
|
+
- **`live_no_content`** — provisioned but nothing deployed yet. Run
|
|
153
|
+
`launchpad deploy`.
|
|
154
|
+
- **`live_content_untracked`** — the app IS live, but content
|
|
155
|
+
reached Cloudflare Pages outside `launchpad deploy` (git
|
|
156
|
+
integration / push-to-main); there's no platform-tracked manifest
|
|
157
|
+
to diff against.
|
|
158
|
+
- **`live_drift_unknown`** — the app is live and tracked, but no
|
|
159
|
+
local `launchpad.yaml` exists to compare: status degrades to the
|
|
160
|
+
live-truth-only view (see below).
|
|
161
|
+
- **`no deployed manifest yet`** — registered, but no deployed
|
|
162
|
+
manifest. Run `launchpad deploy` first.
|
|
163
|
+
|
|
164
|
+
### Live build truth
|
|
165
|
+
|
|
166
|
+
For every live state, status also renders the app's **last
|
|
167
|
+
Cloudflare Pages deployment**: when it ran, what triggered it
|
|
168
|
+
(`git push` vs `launchpad deploy (bot)`), the commit, and the build
|
|
169
|
+
outcome — `build success`, `build IN PROGRESS`, or
|
|
170
|
+
`build FAILED at stage "<stage>"` with a failure-log excerpt and
|
|
171
|
+
what's still serving (the last successful deployment). This is the
|
|
172
|
+
load-bearing answer to "my deploy exited 0 but the site didn't
|
|
173
|
+
change": the commit can land while the asynchronous Pages build
|
|
174
|
+
fails afterwards. Status also lists the app's **standing
|
|
175
|
+
exceptions** (pre-existing, non-blocking policy violations already
|
|
176
|
+
live on main — ADR 0025).
|
|
177
|
+
|
|
178
|
+
### No local manifest? Status still works
|
|
179
|
+
|
|
180
|
+
If `launchpad status` has a slug (explicit, or inferred from the
|
|
181
|
+
directory name) but no local `launchpad.yaml`, it does **not**
|
|
182
|
+
error (v0.26.1 behaviour): it degrades to the live-truth-only view —
|
|
183
|
+
lifecycle + deployment block + standing exceptions, plus a one-line
|
|
184
|
+
"drift not checked" note — and exits 0. In `--json` that view
|
|
185
|
+
carries `"drift": null` and the `live_drift_unknown` state as the
|
|
186
|
+
not-evaluated discriminant. A present-but-unreadable or invalid
|
|
187
|
+
manifest is still a hard exit-2 error.
|
|
188
|
+
|
|
189
|
+
### HEAD-vs-deployed surfacing
|
|
130
190
|
|
|
131
191
|
Beyond drift, status also surfaces the relationship between the app
|
|
132
192
|
repo's main HEAD sha and the last-applied manifest sha. If HEAD is
|
|
@@ -140,9 +200,14 @@ without polling tf-apply.
|
|
|
140
200
|
|
|
141
201
|
### Exit codes
|
|
142
202
|
|
|
143
|
-
- **0** — in sync, OR drift in default (report-only) mode
|
|
144
|
-
-
|
|
145
|
-
- **
|
|
203
|
+
- **0** — in sync, OR drift in default (report-only) mode, OR the
|
|
204
|
+
live-truth-only view (slug known, no local manifest).
|
|
205
|
+
- **1** — drift, when `--strict` is set. With `--strict` and no
|
|
206
|
+
local manifest (drift can't be evaluated), exit 1 fires only when
|
|
207
|
+
the live build itself failed.
|
|
208
|
+
- **2** — error (network, auth, unreadable/invalid local manifest).
|
|
209
|
+
A *missing* local manifest is no longer an error when the slug is
|
|
210
|
+
known — status degrades to the live-truth-only view instead.
|
|
146
211
|
|
|
147
212
|
The default is report-only so casual interactive use never surprises
|
|
148
213
|
the operator. For CI guards, use `--strict`:
|
|
@@ -176,10 +241,33 @@ launchpad status horizon --json
|
|
|
176
241
|
"driftDetails": [
|
|
177
242
|
{ "path": "metadata.owner", "local": "alice@m-kopa.com", "deployed": "bob@m-kopa.com" },
|
|
178
243
|
{ "path": "production_env.API_BASE", "local": "https://new", "deployed": "https://old" }
|
|
179
|
-
]
|
|
244
|
+
],
|
|
245
|
+
"deployment": {
|
|
246
|
+
"slug": "horizon",
|
|
247
|
+
"supported": true,
|
|
248
|
+
"liveDeployment": {
|
|
249
|
+
"id": "<uuid>",
|
|
250
|
+
"createdOn": "<iso8601>",
|
|
251
|
+
"modifiedOn": "<iso8601>",
|
|
252
|
+
"url": "https://<id>.<project>.pages.dev",
|
|
253
|
+
"trigger": "bot",
|
|
254
|
+
"commit": { "hash": "<40-hex>", "message": "deploy via launchpad" },
|
|
255
|
+
"buildStatus": "success"
|
|
256
|
+
},
|
|
257
|
+
"lastSuccessfulDeployment": { "id": "<uuid>", "createdOn": "<iso8601>", "url": "..." }
|
|
258
|
+
}
|
|
180
259
|
}
|
|
181
260
|
```
|
|
182
261
|
|
|
262
|
+
Notes: JSON `state` values use underscores (`in_sync`, not
|
|
263
|
+
`in sync`). Provisioning/failed states carry `stage` /
|
|
264
|
+
`failedReason` / `submissionId` instead of the sha fields. The
|
|
265
|
+
live-truth-only degrade adds `"drift": null`; on a failed build,
|
|
266
|
+
`deployment.liveDeployment` carries `buildStatus: "failure"`,
|
|
267
|
+
`failedStage`, and a `logExcerpt`. A `standingExceptions` array
|
|
268
|
+
appears when the app has any. `deployment` is absent when the bot
|
|
269
|
+
pre-dates the endpoint and `null` for apps with no Pages surface.
|
|
270
|
+
|
|
183
271
|
### production_env secret-shape warning
|
|
184
272
|
|
|
185
273
|
If any `production_env.<KEY>` value matches a basic secret-shape
|
|
@@ -195,16 +283,16 @@ secrets bindings path. (This is informational; status will continue.)
|
|
|
195
283
|
|
|
196
284
|
Warning, not block. If you see this: open `launchpad.yaml`, move the
|
|
197
285
|
secret out of `production_env:` and into the `secrets:` bindings
|
|
198
|
-
section
|
|
199
|
-
git).
|
|
286
|
+
section, then push the value with `launchpad secrets push` (the
|
|
287
|
+
operator never runs `wrangler`; values never go via git).
|
|
200
288
|
|
|
201
289
|
## Common error patterns + fixes
|
|
202
290
|
|
|
203
291
|
### "session expired, run `launchpad login`"
|
|
204
292
|
|
|
205
|
-
The
|
|
206
|
-
|
|
207
|
-
|
|
293
|
+
The session is gone or stale. Run `launchpad login` once; the session
|
|
294
|
+
then stays fresh by silent refresh as you use the CLI — you'll only
|
|
295
|
+
be asked to log in again after roughly a week of not using it.
|
|
208
296
|
|
|
209
297
|
### "not authorised for app X (you must be an owner or editor)"
|
|
210
298
|
|
|
@@ -227,6 +315,10 @@ launchpad apps # confirm lifecycle is `live`
|
|
|
227
315
|
/launchpad-deploy-status # diagnose the M-892 stage trace
|
|
228
316
|
```
|
|
229
317
|
|
|
318
|
+
If the record says `failed` but the app is actually serving,
|
|
319
|
+
`launchpad recover <slug>` reconciles the record against live
|
|
320
|
+
Cloudflare state (it verifies; it never fabricates a live state).
|
|
321
|
+
|
|
230
322
|
### "drift: hostnames[0]"
|
|
231
323
|
|
|
232
324
|
The hostname changed in your local manifest but the deployed app
|
|
@@ -246,14 +338,16 @@ Group binding changed in your local manifest. This is the
|
|
|
246
338
|
|
|
247
339
|
## Related skills
|
|
248
340
|
|
|
249
|
-
- **`/launchpad-deploy`** — provision a new app (
|
|
250
|
-
|
|
341
|
+
- **`/launchpad-deploy`** — provision a new app (`launchpad init`
|
|
342
|
+
to write the manifest, then `launchpad deploy`; the legacy
|
|
343
|
+
`launchpad create` wizard verb is deprecated).
|
|
251
344
|
- **`/launchpad-deploy-status`** — interrogate provisioning state
|
|
252
345
|
(M-892 stages). Use during initial provisioning; once the app is
|
|
253
346
|
`live`, `launchpad status` is the daily-use tool.
|
|
254
|
-
- **`/launchpad-content-pr`** —
|
|
255
|
-
|
|
256
|
-
status` is how
|
|
347
|
+
- **`/launchpad-content-pr`** — the iteration loop for a live app
|
|
348
|
+
(edit → deploy → verify). First content ships with the
|
|
349
|
+
provisioning run itself; after that, `launchpad status` is how
|
|
350
|
+
you check ongoing deploys.
|
|
257
351
|
|
|
258
352
|
## Anti-patterns
|
|
259
353
|
|