@m-kopa/launchpad-cli 0.44.0 → 0.46.0
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 +48 -0
- package/dist/cli.js +113 -37
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/deploy/deployment-status.d.ts +5 -0
- package/dist/deploy/deployment-status.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +2 -2
- package/skills/launchpad-content-pr/SKILL.md +1 -1
- package/skills/launchpad-deploy/SKILL.md +1 -1
- package/skills/launchpad-deploy-status/SKILL.md +1 -1
- package/skills/launchpad-destroy/SKILL.md +1 -1
- package/skills/launchpad-identity/SKILL.md +1 -1
- package/skills/launchpad-onboard/SKILL.md +1 -1
- package/skills/launchpad-report/SKILL.md +1 -1
- package/skills/launchpad-status/SKILL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,54 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
6
6
|
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html);
|
|
7
7
|
pre-1.0 minor bumps may carry breaking changes per ADR 0005.
|
|
8
8
|
|
|
9
|
+
## 0.46.0 — 2026-07-07
|
|
10
|
+
|
|
11
|
+
**Honest apply status (sp-k9kw8d).** `launchpad deploy --apply` no longer
|
|
12
|
+
declares success off the merged file - the verdict is now your app's own
|
|
13
|
+
`terraform apply` run:
|
|
14
|
+
|
|
15
|
+
- **Four visible states while polling.** `waiting-approval` (the bot PR is
|
|
16
|
+
open - access-bearing changes need the `allowed-groups-change: true` label
|
|
17
|
+
from someone other than the PR author), `pending` (merged, apply running),
|
|
18
|
+
`applied`, and `failed`. A failed apply exits non-zero and prints the
|
|
19
|
+
failing run's URL - previously the CLI could print `✓ Applied` while the
|
|
20
|
+
apply was failing (the 2026-07-07 people-analytics-v2 incident).
|
|
21
|
+
- **Per-app verdict, not workflow-level.** For per-app-workspace apps the CLI
|
|
22
|
+
reads the app's own `terraform apply (<slug>)` check run, so a sibling
|
|
23
|
+
app's failure in the same matrix never taints your result.
|
|
24
|
+
- **Old-bot fallback.** Against a bot that predates the new endpoint the CLI
|
|
25
|
+
falls back to the previous coarse poll, with a notice.
|
|
26
|
+
- **Access drift now has a self-serve fix.** The `ACCESS DRIFT` refusal from
|
|
27
|
+
`launchpad deploy` (and the drift warning in `launchpad status`) now point
|
|
28
|
+
at `launchpad deploy --apply` as the reconcile path, replacing the manual
|
|
29
|
+
runbook detour. The apply route dispatches on the app's provisioning world
|
|
30
|
+
server-side, so per-app-workspace apps get their workspace regenerated -
|
|
31
|
+
never the legacy flat pair that poisoned shared-root applies.
|
|
32
|
+
|
|
33
|
+
## 0.45.0 — 2026-07-05
|
|
34
|
+
|
|
35
|
+
**Self-serve recovery of a build-failed app (PS-1934).** An app stuck in a
|
|
36
|
+
`failed` lifecycle because of a build bug now recovers through the normal
|
|
37
|
+
`launchpad deploy` flow — no break-glass, no separate `launchpad recover`:
|
|
38
|
+
|
|
39
|
+
- **Auto-reconcile `failed → live`.** Once your fixing deploy's Cloudflare
|
|
40
|
+
Pages build is **verified serving**, the platform flips the record back to
|
|
41
|
+
`live` on the next `launchpad status` / `launchpad watch` read (which
|
|
42
|
+
`deploy` runs for you). `status` surfaces a `✓ recovered:` line so the
|
|
43
|
+
repair is visible, not silent. Scoped to **build** failures only — a
|
|
44
|
+
security-verdict `failed` (origin reachable without auth) is never
|
|
45
|
+
auto-cleared by a green build.
|
|
46
|
+
- **Honest failed-app deploy UX.** An empty-delta deploy to a `failed` app now
|
|
47
|
+
says so plainly (`slug_failed`) and points at the fix path, instead of an
|
|
48
|
+
opaque 409.
|
|
49
|
+
- **`recover` stays** as the explicit reconcile-only path; the docs now
|
|
50
|
+
cross-reference the broken-CI case (PS-1932), where `launchpad deploy` (bot
|
|
51
|
+
bypass) is the supported recovery.
|
|
52
|
+
|
|
53
|
+
Platform-side (ships with the bot): the `redeploy` path now re-ensures the
|
|
54
|
+
D1 binding like `deploy` does, so a redeploy-based recovery can't leave the
|
|
55
|
+
database unbound (the stock-dispatch-tracker 500 root cause).
|
|
56
|
+
|
|
9
57
|
## 0.44.0 — 2026-07-05
|
|
10
58
|
|
|
11
59
|
**Identity guide crystal-clarity — fixes the "gateway signs me in but the app
|
package/dist/cli.js
CHANGED
|
@@ -19,7 +19,7 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
19
19
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
20
20
|
|
|
21
21
|
// src/version.ts
|
|
22
|
-
var CLI_VERSION = "0.
|
|
22
|
+
var CLI_VERSION = "0.46.0";
|
|
23
23
|
|
|
24
24
|
// src/config.ts
|
|
25
25
|
import * as os from "node:os";
|
|
@@ -3763,7 +3763,8 @@ async function fetchDeploymentStatus(cfg, slug, fetcher = fetch) {
|
|
|
3763
3763
|
slug: typeof raw.slug === "string" ? raw.slug : slug,
|
|
3764
3764
|
supported: raw.supported,
|
|
3765
3765
|
liveDeployment: raw.liveDeployment ?? null,
|
|
3766
|
-
lastSuccessfulDeployment: raw.lastSuccessfulDeployment ?? null
|
|
3766
|
+
lastSuccessfulDeployment: raw.lastSuccessfulDeployment ?? null,
|
|
3767
|
+
...raw.reconciledToLive === true ? { reconciledToLive: true } : {}
|
|
3767
3768
|
};
|
|
3768
3769
|
}
|
|
3769
3770
|
|
|
@@ -5121,7 +5122,8 @@ function surfaceAccessDrift(out, io) {
|
|
|
5121
5122
|
for (const u of ad.unresolved) {
|
|
5122
5123
|
io.out(` unresolved group (${u.side}): ${u.token}`);
|
|
5123
5124
|
}
|
|
5124
|
-
io.out(" `launchpad deploy` will NOT fix this —
|
|
5125
|
+
io.out(" `launchpad deploy` will NOT fix this — run `launchpad deploy --apply` to");
|
|
5126
|
+
io.out(" reconcile access through the gated TF route (sp-k9kw8d).");
|
|
5125
5127
|
}
|
|
5126
5128
|
function surfaceNoLocalManifestNote(out, io) {
|
|
5127
5129
|
if (out.drift !== null)
|
|
@@ -5139,6 +5141,9 @@ function surfaceDeployment(out, io) {
|
|
|
5139
5141
|
const dep = out.deployment;
|
|
5140
5142
|
if (dep === undefined || dep === null || !dep.supported)
|
|
5141
5143
|
return;
|
|
5144
|
+
if (dep.reconciledToLive === true) {
|
|
5145
|
+
io.out(" ✓ recovered: this app was in a failed state; its verified-live build reconciled the record failed→live (no `launchpad recover` needed).");
|
|
5146
|
+
}
|
|
5142
5147
|
const live = dep.liveDeployment;
|
|
5143
5148
|
if (live === null) {
|
|
5144
5149
|
io.out(" last deployment: none — Cloudflare Pages has no production deployment yet.");
|
|
@@ -6254,7 +6259,7 @@ async function runDeployApply(opts, io, deps = {}) {
|
|
|
6254
6259
|
timeoutMs
|
|
6255
6260
|
});
|
|
6256
6261
|
if (outcome2.kind !== "applied")
|
|
6257
|
-
return outcomeToExit(outcome2);
|
|
6262
|
+
return outcomeToExit(outcome2, undefined, io);
|
|
6258
6263
|
deletePinIfPresent(cfg, slug2, io);
|
|
6259
6264
|
io.out(`✓ Applied ${slug2}.`);
|
|
6260
6265
|
return 0;
|
|
@@ -6335,7 +6340,7 @@ async function runDeployApply(opts, io, deps = {}) {
|
|
|
6335
6340
|
timeoutMs
|
|
6336
6341
|
});
|
|
6337
6342
|
if (outcome.kind !== "applied")
|
|
6338
|
-
return outcomeToExit(outcome, apply.prUrl);
|
|
6343
|
+
return outcomeToExit(outcome, apply.prUrl, io);
|
|
6339
6344
|
deletePinIfPresent(cfg, slug, io);
|
|
6340
6345
|
io.out("");
|
|
6341
6346
|
io.out(`✓ Applied ${slug}. (See ${apply.prUrl} for the merged PR.)`);
|
|
@@ -6343,36 +6348,83 @@ async function runDeployApply(opts, io, deps = {}) {
|
|
|
6343
6348
|
}
|
|
6344
6349
|
async function pollUntilApplied(args) {
|
|
6345
6350
|
const start = Date.now();
|
|
6346
|
-
let lastPrSeen = true;
|
|
6347
6351
|
let dotsThisLine = 0;
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
} catch (e) {
|
|
6356
|
-
args.io.err(`! state fetch failed (will retry): ${describe13(e)}`);
|
|
6357
|
-
await sleep(args.pollIntervalSec * 1000);
|
|
6358
|
-
continue;
|
|
6359
|
-
}
|
|
6360
|
-
const prGone = state.openPr === null || state.openPr.number !== args.prNumber;
|
|
6361
|
-
const shaMatches2 = args.manifestSha === null ? state.hasAppFile && state.lastAppliedManifestSha !== null : state.lastAppliedManifestSha === args.manifestSha;
|
|
6362
|
-
if (prGone && shaMatches2) {
|
|
6363
|
-
if (dotsThisLine > 0)
|
|
6364
|
-
args.io.out("");
|
|
6365
|
-
return { kind: "applied" };
|
|
6352
|
+
let mode = args.manifestSha === null ? "legacy" : "status";
|
|
6353
|
+
let lastRendered = null;
|
|
6354
|
+
let lastPrSeen = true;
|
|
6355
|
+
const breakDots = () => {
|
|
6356
|
+
if (dotsThisLine > 0) {
|
|
6357
|
+
args.io.out("");
|
|
6358
|
+
dotsThisLine = 0;
|
|
6366
6359
|
}
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6360
|
+
};
|
|
6361
|
+
while (Date.now() - start < args.timeoutMs) {
|
|
6362
|
+
if (mode === "status") {
|
|
6363
|
+
let status;
|
|
6364
|
+
try {
|
|
6365
|
+
status = await apiJson(args.cfg, {
|
|
6366
|
+
method: "GET",
|
|
6367
|
+
path: `/apps/${args.slug}/manifest/apply-status?manifestSha=${args.manifestSha}`
|
|
6368
|
+
}, args.fetcher);
|
|
6369
|
+
} catch (e) {
|
|
6370
|
+
if (e instanceof NotFoundError) {
|
|
6371
|
+
breakDots();
|
|
6372
|
+
args.io.err("! bot has no apply-status endpoint yet — falling back to the coarse merge-poll (upgrade pending bot deploy)");
|
|
6373
|
+
mode = "legacy";
|
|
6374
|
+
continue;
|
|
6375
|
+
}
|
|
6376
|
+
args.io.err(`! apply-status fetch failed (will retry): ${describe13(e)}`);
|
|
6377
|
+
await sleep(args.pollIntervalSec * 1000);
|
|
6378
|
+
continue;
|
|
6379
|
+
}
|
|
6380
|
+
if (status.state === "applied") {
|
|
6381
|
+
breakDots();
|
|
6382
|
+
return { kind: "applied" };
|
|
6383
|
+
}
|
|
6384
|
+
if (status.state === "failed") {
|
|
6385
|
+
breakDots();
|
|
6386
|
+
return {
|
|
6387
|
+
kind: "failed",
|
|
6388
|
+
reason: status.detail ?? "the apply run failed",
|
|
6389
|
+
runUrl: status.runUrl ?? null
|
|
6390
|
+
};
|
|
6391
|
+
}
|
|
6392
|
+
if (status.state !== lastRendered) {
|
|
6393
|
+
breakDots();
|
|
6394
|
+
if (status.state === "waiting-approval") {
|
|
6395
|
+
args.io.out(`⏳ waiting for approval/CI — access-bearing changes need the 'allowed-groups-change: true' label from someone other than the PR author (${status.prUrl})`);
|
|
6396
|
+
} else {
|
|
6397
|
+
args.io.out(`⚙ PR merged — waiting for the app's terraform apply${status.checkName !== undefined ? ` ('${status.checkName}')` : ""} …`);
|
|
6398
|
+
}
|
|
6399
|
+
lastRendered = status.state;
|
|
6400
|
+
}
|
|
6401
|
+
} else {
|
|
6402
|
+
let state;
|
|
6403
|
+
try {
|
|
6404
|
+
state = await apiJson(args.cfg, {
|
|
6405
|
+
method: "GET",
|
|
6406
|
+
path: `/apps/${args.slug}/manifest/state`
|
|
6407
|
+
}, args.fetcher);
|
|
6408
|
+
} catch (e) {
|
|
6409
|
+
args.io.err(`! state fetch failed (will retry): ${describe13(e)}`);
|
|
6410
|
+
await sleep(args.pollIntervalSec * 1000);
|
|
6411
|
+
continue;
|
|
6412
|
+
}
|
|
6413
|
+
const prGone = state.openPr === null || state.openPr.number !== args.prNumber;
|
|
6414
|
+
const shaMatches2 = args.manifestSha === null ? state.hasAppFile && state.lastAppliedManifestSha !== null : state.lastAppliedManifestSha === args.manifestSha;
|
|
6415
|
+
if (prGone && shaMatches2) {
|
|
6416
|
+
breakDots();
|
|
6417
|
+
return { kind: "applied" };
|
|
6418
|
+
}
|
|
6419
|
+
if (prGone && !shaMatches2 && lastPrSeen) {
|
|
6420
|
+
breakDots();
|
|
6421
|
+
return {
|
|
6422
|
+
kind: "failed",
|
|
6423
|
+
reason: "the bot PR closed without applying this manifest sha (was it rejected or superseded?)"
|
|
6424
|
+
};
|
|
6425
|
+
}
|
|
6426
|
+
lastPrSeen = state.openPr !== null;
|
|
6374
6427
|
}
|
|
6375
|
-
lastPrSeen = state.openPr !== null;
|
|
6376
6428
|
process.stdout.write(".");
|
|
6377
6429
|
dotsThisLine++;
|
|
6378
6430
|
if (dotsThisLine >= 60) {
|
|
@@ -6385,15 +6437,29 @@ async function pollUntilApplied(args) {
|
|
|
6385
6437
|
args.io.out("");
|
|
6386
6438
|
return { kind: "timed-out" };
|
|
6387
6439
|
}
|
|
6388
|
-
function outcomeToExit(outcome, prUrl) {
|
|
6440
|
+
function outcomeToExit(outcome, prUrl, io) {
|
|
6441
|
+
const err = (line) => {
|
|
6442
|
+
if (io !== undefined) {
|
|
6443
|
+
io.err(line);
|
|
6444
|
+
} else {
|
|
6445
|
+
console.error(line);
|
|
6446
|
+
}
|
|
6447
|
+
};
|
|
6389
6448
|
switch (outcome.kind) {
|
|
6390
6449
|
case "applied":
|
|
6391
6450
|
return 0;
|
|
6392
6451
|
case "failed":
|
|
6452
|
+
err(`✗ Apply FAILED: ${outcome.reason}`);
|
|
6453
|
+
if (outcome.runUrl !== undefined && outcome.runUrl !== null) {
|
|
6454
|
+
err(` Failing run: ${outcome.runUrl}`);
|
|
6455
|
+
}
|
|
6456
|
+
if (prUrl !== undefined) {
|
|
6457
|
+
err(` PR: ${prUrl}`);
|
|
6458
|
+
}
|
|
6393
6459
|
return 1;
|
|
6394
6460
|
case "timed-out":
|
|
6395
6461
|
if (prUrl !== undefined) {
|
|
6396
|
-
|
|
6462
|
+
err(`! timed out waiting for apply — check ${prUrl} for live status.`);
|
|
6397
6463
|
}
|
|
6398
6464
|
return 4;
|
|
6399
6465
|
case "transport":
|
|
@@ -7137,7 +7203,7 @@ function surfaceDeployExtras(body, io, slug, allowStale = false) {
|
|
|
7137
7203
|
if (adw.manifestOnly !== undefined && adw.manifestOnly.length > 0) {
|
|
7138
7204
|
io.err(` declared but NOT enforced: ${adw.manifestOnly.join(", ")}`);
|
|
7139
7205
|
}
|
|
7140
|
-
io.err(` reconcile
|
|
7206
|
+
io.err(` reconcile with \`launchpad deploy --apply\` (the gated TF route) — \`launchpad deploy\` can't (it ships content only).`);
|
|
7141
7207
|
}
|
|
7142
7208
|
}
|
|
7143
7209
|
function isStaleBlock(body) {
|
|
@@ -7319,6 +7385,14 @@ async function runModelADeploy(args) {
|
|
|
7319
7385
|
}
|
|
7320
7386
|
return 1;
|
|
7321
7387
|
}
|
|
7388
|
+
if (result.status === 409 && errorCode === "slug_failed") {
|
|
7389
|
+
io.err(`launchpad deploy: app "${slug}" is in a FAILED state, and this deploy adds no new content (nothing to re-drive the build).`);
|
|
7390
|
+
if (typeof body.message === "string") {
|
|
7391
|
+
io.err(` ${body.message}`);
|
|
7392
|
+
}
|
|
7393
|
+
io.err(` Deploy a content change to re-drive the build (it reconciles failed→live automatically once verified serving — watch \`launchpad status ${slug}\`), or \`launchpad deploy --resume ${slug}\`.`);
|
|
7394
|
+
return 1;
|
|
7395
|
+
}
|
|
7322
7396
|
if (result.status === 409 && isStaleBlock(body)) {
|
|
7323
7397
|
surfaceStaleBlock(body, io);
|
|
7324
7398
|
return 1;
|
|
@@ -7335,8 +7409,10 @@ async function runModelADeploy(args) {
|
|
|
7335
7409
|
}
|
|
7336
7410
|
io.err("");
|
|
7337
7411
|
io.err(" Your manifest's access groups don't match what the gateway enforces.");
|
|
7338
|
-
io.err(" `launchpad deploy` ships content only and cannot change access
|
|
7339
|
-
io.err("
|
|
7412
|
+
io.err(" `launchpad deploy` ships content only and cannot change access.");
|
|
7413
|
+
io.err(" Run `launchpad deploy --apply` to reconcile — it opens the gated TF PR");
|
|
7414
|
+
io.err(" (access-widening changes need the allowed-groups-change label from a");
|
|
7415
|
+
io.err(" second person), waits for the apply verdict, then redeploy your content.");
|
|
7340
7416
|
io.err(" Nothing was committed by this attempt.");
|
|
7341
7417
|
return 1;
|
|
7342
7418
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,6 +26,11 @@ export interface DeploymentStatusView {
|
|
|
26
26
|
readonly createdOn: string;
|
|
27
27
|
readonly url: string | null;
|
|
28
28
|
} | null;
|
|
29
|
+
/** PS-1934 AC1 — true when THIS read auto-reconciled a build-failed app
|
|
30
|
+
* back to `live` (its latest build is verified serving). Lets `status` /
|
|
31
|
+
* `watch` / the post-deploy verify surface "record reconciled failed→live"
|
|
32
|
+
* rather than the repair happening silently. */
|
|
33
|
+
readonly reconciledToLive?: boolean;
|
|
29
34
|
}
|
|
30
35
|
/** One standing-exception inventory entry (sp-devlp1 T3 / D2) — a
|
|
31
36
|
* policy/boundary/build-command violation observed in content already
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployment-status.d.ts","sourceRoot":"","sources":["../../src/deploy/deployment-status.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;AAC/D,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACnD,yEAAyE;IACzE,QAAQ,CAAC,wBAAwB,EAAE;QACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"deployment-status.d.ts","sourceRoot":"","sources":["../../src/deploy/deployment-status.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;AAC/D,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACnD,yEAAyE;IACzE,QAAQ,CAAC,wBAAwB,EAAE;QACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B,GAAG,IAAI,CAAC;IACT;;;qDAGiD;IACjD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED;;;wEAGwE;AACxE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,SAAS,qBAAqB,EAAE,GAAG,IAAI,CAAC,CAsBlD;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAwBtC"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CLI_VERSION = "0.
|
|
1
|
+
export declare const CLI_VERSION = "0.46.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@m-kopa/launchpad-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Launchpad CLI
|
|
3
|
+
"version": "0.46.0",
|
|
4
|
+
"description": "Launchpad CLI \u2014 clone / deploy / review / merge against Launchpad-managed apps. Talks to the portal-bot endpoints (SCOPE-M-760 / T4).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"launchpad": "./dist/cli.js"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: launchpad-content-pr
|
|
3
3
|
description: Push a content change to a Launchpad app via `launchpad deploy` and verify it shipped via `launchpad status`. Covers the post-first-deploy iteration loop (edit → deploy → verify) — subsequent deploys commit directly to the app repo's main and the Pages build runs asynchronously, so verification is its own step. Use when someone says "push a content change", "ship an update", "/launchpad-content-pr", "verify my deploy", or after `/launchpad-deploy` reports `done` and they want to follow up with an edit.
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.46.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<!-- BEGIN shell-contract (managed by scripts/sync-skill-contract.sh — edit skills/_partials/shell-contract.md) -->
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: launchpad-deploy
|
|
3
3
|
description: Walk a Launchpad user through deploying an app from their local working directory (Model A — `launchpad init` + `launchpad deploy`). Wraps the CLI verbs end-to-end: detects the app shape, scaffolds `launchpad.yaml`, resolves the allowed Entra group via `launchpad groups`, bundles the CWD via `launchpad deploy`, and watches the rollout via `launchpad status`. Use when someone says "deploy a new app", "ship my app to Launchpad", "/launchpad-deploy", "I have an app locally — get it on Launchpad", or any variant. Resume/abandon for legacy in-flight provisioning is at the bottom.
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.46.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<!-- BEGIN shell-contract (managed by scripts/sync-skill-contract.sh — edit skills/_partials/shell-contract.md) -->
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: launchpad-deploy-status
|
|
3
3
|
description: Show the current provisioning stage + failure reason for a Launchpad app via `launchpad status` (Model A drift + deployment_verified) and `launchpad apps` (lifecycle bucket), or watch provisioning live with `launchpad watch`. Renders the M-892 stage trace for in-flight provisioning, and is the canonical home for `launchpad recover` (repair a terminal-failed app record that is actually live). Use when someone says "what's the status of demo-X", "/launchpad-deploy-status", "is my deploy stuck", "watch my deploy go live", "watch provisioning", "my app says failed but it's serving", or after `/launchpad-deploy` reports a non-`done` terminal stage.
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.46.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<!-- BEGIN shell-contract (managed by scripts/sync-skill-contract.sh — edit skills/_partials/shell-contract.md) -->
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: launchpad-destroy
|
|
3
3
|
description: Tear down a Launchpad app end-to-end via `launchpad destroy` — Cloudflare Pages project, edge-auth wiring (gateway KV/audience entries, or the Access app for `auth: access` apps), custom hostname, platform-repo TF, and the app repo (archive-renamed). Owner-only verb with a two-step destructive confirmation. Use when someone says "destroy this app", "/launchpad-destroy", "tear down `<slug>`", "delete the app", or asks to clean up a smoke-test / orphan / retired app.
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.46.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<!-- BEGIN shell-contract (managed by scripts/sync-skill-contract.sh — edit skills/_partials/shell-contract.md) -->
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: launchpad-identity
|
|
3
3
|
description: Teach an app author how to use the signed-in user's identity inside a Launchpad app — read the gateway-forwarded X-Launchpad-User-Assertion in a Pages Function, VERIFY it with @m-kopa/platform-auth (fail-closed), and show who's logged in (sub/email/name). Use when someone says "who is logged in", "show the current user", "get the user's email in my app", "auth in my launchpad app", "read the user identity", "/launchpad-identity", or is wiring up an /api/me for a gateway-fronted app.
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.46.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<!-- BEGIN shell-contract (managed by scripts/sync-skill-contract.sh — edit skills/_partials/shell-contract.md) -->
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: launchpad-onboard
|
|
3
3
|
description: One-time setup for the Launchpad CLI + Claude Code skill bundle. Verifies the `launchpad` CLI is installed and current, runs `launchpad whoami` to confirm the session is fresh, and checks the bundled skills are installed and in lock-step with the CLI. Idempotent — safe to re-run any time. Use when someone says "set me up for Launchpad", "I just got a new machine and want to use Launchpad", "/launchpad-onboard", or any of the other launchpad-* skills fails on a prereq check.
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.46.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<!-- BEGIN shell-contract (managed by scripts/sync-skill-contract.sh — edit skills/_partials/shell-contract.md) -->
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: launchpad-report
|
|
3
3
|
description: File a bug report or feature request to the Launchpad team's tracker from the CLI. Use when someone reports something broken, hits an error in a launchpad command, or wishes a feature existed — e.g. "this is broken", "report a bug", "can you file that", "I wish launchpad could…", "/launchpad-bug", "/launchpad-feature". Always confirm and show exactly what you'll send before filing; never file silently.
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.46.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<!-- BEGIN shell-contract (managed by scripts/sync-skill-contract.sh — edit skills/_partials/shell-contract.md) -->
|
|
@@ -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.46.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<!-- BEGIN shell-contract (managed by scripts/sync-skill-contract.sh — edit skills/_partials/shell-contract.md) -->
|