@m-kopa/launchpad-cli 0.47.0 → 0.47.2

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 CHANGED
@@ -6,6 +6,38 @@ 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.47.2 — 2026-07-08
10
+
11
+ **Fix: `launchpad deploy` no longer leaves you falsely "stale" after your own
12
+ deploys (PS-2119).** The clone staleness guard compares `.launchpad/base-sha`
13
+ against managed `main` head, but the marker only ever advanced on
14
+ `--rebase-onto-head` — a normal deploy left it frozen at clone time. So each
15
+ deploy you made moved `main` forward while your marker stayed put, and the next
16
+ deploy re-warned "a teammate may have shipped changes you don't have" (and could
17
+ BLOCK), when the only "teammate" was your own prior commits. `launchpad deploy`
18
+ now re-pins the marker after a successful deploy — to the new commit (committed)
19
+ or to managed main head (nothing-to-deploy). It only re-stamps a marker that
20
+ already exists (a git-less `launchpad init` tree gains nothing), and a stamp
21
+ failure never fails the deploy. If you were stuck on this, a single
22
+ `launchpad update` + `launchpad deploy` clears it — no re-clone.
23
+
24
+ (Companion bot-side fix PS-2120, shipped separately: co-owners were wrongly 403'd
25
+ by `launchpad status` / hidden from `launchpad apps` on their own apps — several
26
+ read endpoints resolved the role without `coOwners`. Now co-owner-aware.)
27
+
28
+ ## 0.47.1 — 2026-07-08
29
+
30
+ **Fix: no false-success exit code when the inline access-drift apply is aborted
31
+ (PS-2071).** 0.47.0 gated the "✓ Access reconciled" *message* on a real apply,
32
+ but `handleAccessDrift` still returned the apply's raw exit code — and
33
+ `deploy --apply` exits `0` both on a genuine apply and when the operator reviews
34
+ the plan and aborts at its own prompt. So accepting the inline offer and then
35
+ aborting made `launchpad deploy` exit `0` for a no-op — inconsistent with
36
+ declining the offer (which exits `1`) and a false-success signal to any script.
37
+ Now the exit code is gated on the same real-apply signal: an abort maps to `1`
38
+ (nothing changed), while a genuine apply failure's code (`1`/`2`/`4`) passes
39
+ through unchanged. Caught by CodeRabbit review of the 0.47.0 change.
40
+
9
41
  ## 0.47.0 — 2026-07-07
10
42
 
11
43
  **`launchpad deploy` offers to reconcile access drift inline (PS-2071).** When a
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.47.0";
22
+ var CLI_VERSION = "0.47.2";
23
23
 
24
24
  // src/config.ts
25
25
  import * as os from "node:os";
@@ -6614,8 +6614,9 @@ async function handleAccessDrift(params) {
6614
6614
  if (applied) {
6615
6615
  io.out("");
6616
6616
  io.out("✓ Access reconciled. Re-run `launchpad deploy` to ship your content change.");
6617
+ return exit;
6617
6618
  }
6618
- return exit;
6619
+ return exit === 0 ? 1 : exit;
6619
6620
  }
6620
6621
 
6621
6622
  // src/io/prompt.ts
@@ -7357,6 +7358,17 @@ async function surfaceManifestDiff(cfg, slug, manifestPath, io) {
7357
7358
  for (const line of renderManifestDiffLines(diff))
7358
7359
  io.out(line);
7359
7360
  }
7361
+ async function advanceBaseShaMarker(cwd, sha, io) {
7362
+ try {
7363
+ if (typeof sha !== "string" || !isValidBaseSha(sha))
7364
+ return;
7365
+ if (await readBaseShaMarker(cwd) === null)
7366
+ return;
7367
+ await writeBaseShaMarker(cwd, sha);
7368
+ } catch (e) {
7369
+ io.err(`warning: couldn't update the local base-sha marker (${describe15(e)}); ` + `a future deploy may re-warn about staleness. Harmless — your deploy landed.`);
7370
+ }
7371
+ }
7360
7372
  async function runModelADeploy(args) {
7361
7373
  const { cwd, manifestPath, io } = args;
7362
7374
  let slug;
@@ -7524,6 +7536,7 @@ async function runModelADeploy(args) {
7524
7536
  io.out(` (managed main @ ${success.head_sha.slice(0, 8)} matches the bundle)`);
7525
7537
  }
7526
7538
  surfaceDeployExtras(success, io, slug, args.allowStale);
7539
+ await advanceBaseShaMarker(cwd, success.head_sha, io);
7527
7540
  return 0;
7528
7541
  }
7529
7542
  if (success.status === "provisioning_started") {
@@ -7553,6 +7566,7 @@ async function runModelADeploy(args) {
7553
7566
  io.err(` got: ${JSON.stringify(success)}`);
7554
7567
  return 1;
7555
7568
  }
7569
+ await advanceBaseShaMarker(cwd, success.commit_sha, io);
7556
7570
  io.out(`✓ Bundle accepted — committed as ${success.commit_sha.slice(0, 8)} on ${success.repo}`);
7557
7571
  io.out(` ${result.fileCount} files (${formatBytes2(result.compressedBytes)} gzipped)`);
7558
7572
  if (result.workerScript !== null) {
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAqEA,OAAO,EAGL,4BAA4B,EAC7B,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,EAAa,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,KAAK,EAAS,OAAO,EAAY,MAAM,kBAAkB,CAAC;AAKjE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,CAAC;AAEjD,eAAO,MAAM,aAAa,EAAE,OAI3B,CAAC;AAEF,UAAU,UAAU;IAClB,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAmQD;;;;;;GAMG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAoBpC;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,GAAG,IAAI,CAwBpE;AAkMD,2BAA2B;AAC3B,OAAO,EAAE,4BAA4B,EAAE,CAAC"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAsEA,OAAO,EAGL,4BAA4B,EAC7B,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,EAAa,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,KAAK,EAAS,OAAO,EAAY,MAAM,kBAAkB,CAAC;AAKjE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,CAAC;AAEjD,eAAO,MAAM,aAAa,EAAE,OAI3B,CAAC;AAEF,UAAU,UAAU;IAClB,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAmQD;;;;;;GAMG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAoBpC;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,GAAG,IAAI,CAwBpE;AAkMD,2BAA2B;AAC3B,OAAO,EAAE,4BAA4B,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"access-drift-offer.d.ts","sourceRoot":"","sources":["../../src/deploy/access-drift-offer.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,CACjB,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,KAAK,EACT,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,KACvC,OAAO,CAAC,QAAQ,CAAC,CAAC;CACxB;AAKD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,eAAe,GACpB,MAAM,EAAE,CAoBV;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,EAAE,CAOpD;AAQD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;CAChC,GAAG,OAAO,CAAC,QAAQ,CAAC,CA8CpB"}
1
+ {"version":3,"file":"access-drift-offer.d.ts","sourceRoot":"","sources":["../../src/deploy/access-drift-offer.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,CACjB,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,KAAK,EACT,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,KACvC,OAAO,CAAC,QAAQ,CAAC,CAAC;CACxB;AAKD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,eAAe,GACpB,MAAM,EAAE,CAoBV;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,EAAE,CAOpD;AAQD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;CAChC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAoDpB"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const CLI_VERSION = "0.47.0";
1
+ export declare const CLI_VERSION = "0.47.2";
2
2
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m-kopa/launchpad-cli",
3
- "version": "0.47.0",
3
+ "version": "0.47.2",
4
4
  "description": "Launchpad CLI — 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": {
@@ -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.47.0
4
+ version: 0.47.2
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.47.0
4
+ version: 0.47.2
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.47.0
4
+ version: 0.47.2
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.47.0
4
+ version: 0.47.2
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.47.0
4
+ version: 0.47.2
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.47.0
4
+ version: 0.47.2
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.47.0
4
+ version: 0.47.2
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.47.0
4
+ version: 0.47.2
5
5
  ---
6
6
 
7
7
  <!-- BEGIN shell-contract (managed by scripts/sync-skill-contract.sh — edit skills/_partials/shell-contract.md) -->