@m-kopa/launchpad-cli 0.45.0 → 0.46.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 CHANGED
@@ -6,6 +6,36 @@ 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.1 — 2026-07-07
10
+
11
+ Copy fixes in the access-drift guidance: consistent voice in the deploy
12
+ refusal remediation, and an internal scope reference removed from the
13
+ `launchpad status` drift note.
14
+
15
+ ## 0.46.0 — 2026-07-07
16
+
17
+ **Honest apply status (sp-k9kw8d).** `launchpad deploy --apply` no longer
18
+ declares success off the merged file - the verdict is now your app's own
19
+ `terraform apply` run:
20
+
21
+ - **Four visible states while polling.** `waiting-approval` (the bot PR is
22
+ open - access-bearing changes need the `allowed-groups-change: true` label
23
+ from someone other than the PR author), `pending` (merged, apply running),
24
+ `applied`, and `failed`. A failed apply exits non-zero and prints the
25
+ failing run's URL - previously the CLI could print `✓ Applied` while the
26
+ apply was failing (the 2026-07-07 people-analytics-v2 incident).
27
+ - **Per-app verdict, not workflow-level.** For per-app-workspace apps the CLI
28
+ reads the app's own `terraform apply (<slug>)` check run, so a sibling
29
+ app's failure in the same matrix never taints your result.
30
+ - **Old-bot fallback.** Against a bot that predates the new endpoint the CLI
31
+ falls back to the previous coarse poll, with a notice.
32
+ - **Access drift now has a self-serve fix.** The `ACCESS DRIFT` refusal from
33
+ `launchpad deploy` (and the drift warning in `launchpad status`) now point
34
+ at `launchpad deploy --apply` as the reconcile path, replacing the manual
35
+ runbook detour. The apply route dispatches on the app's provisioning world
36
+ server-side, so per-app-workspace apps get their workspace regenerated -
37
+ never the legacy flat pair that poisoned shared-root applies.
38
+
9
39
  ## 0.45.0 — 2026-07-05
10
40
 
11
41
  **Self-serve recovery of a build-failed app (PS-1934).** An app stuck in 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.45.0";
22
+ var CLI_VERSION = "0.46.1";
23
23
 
24
24
  // src/config.ts
25
25
  import * as os from "node:os";
@@ -5122,7 +5122,8 @@ function surfaceAccessDrift(out, io) {
5122
5122
  for (const u of ad.unresolved) {
5123
5123
  io.out(` unresolved group (${u.side}): ${u.token}`);
5124
5124
  }
5125
- io.out(" `launchpad deploy` will NOT fix this — access changes go via the gated TF route.");
5125
+ io.out(" `launchpad deploy` will NOT fix this — run `launchpad deploy --apply` to");
5126
+ io.out(" reconcile access through the gated TF route.");
5126
5127
  }
5127
5128
  function surfaceNoLocalManifestNote(out, io) {
5128
5129
  if (out.drift !== null)
@@ -6258,7 +6259,7 @@ async function runDeployApply(opts, io, deps = {}) {
6258
6259
  timeoutMs
6259
6260
  });
6260
6261
  if (outcome2.kind !== "applied")
6261
- return outcomeToExit(outcome2);
6262
+ return outcomeToExit(outcome2, undefined, io);
6262
6263
  deletePinIfPresent(cfg, slug2, io);
6263
6264
  io.out(`✓ Applied ${slug2}.`);
6264
6265
  return 0;
@@ -6339,7 +6340,7 @@ async function runDeployApply(opts, io, deps = {}) {
6339
6340
  timeoutMs
6340
6341
  });
6341
6342
  if (outcome.kind !== "applied")
6342
- return outcomeToExit(outcome, apply.prUrl);
6343
+ return outcomeToExit(outcome, apply.prUrl, io);
6343
6344
  deletePinIfPresent(cfg, slug, io);
6344
6345
  io.out("");
6345
6346
  io.out(`✓ Applied ${slug}. (See ${apply.prUrl} for the merged PR.)`);
@@ -6347,36 +6348,83 @@ async function runDeployApply(opts, io, deps = {}) {
6347
6348
  }
6348
6349
  async function pollUntilApplied(args) {
6349
6350
  const start = Date.now();
6350
- let lastPrSeen = true;
6351
6351
  let dotsThisLine = 0;
6352
- while (Date.now() - start < args.timeoutMs) {
6353
- let state;
6354
- try {
6355
- state = await apiJson(args.cfg, {
6356
- method: "GET",
6357
- path: `/apps/${args.slug}/manifest/state`
6358
- }, args.fetcher);
6359
- } catch (e) {
6360
- args.io.err(`! state fetch failed (will retry): ${describe13(e)}`);
6361
- await sleep(args.pollIntervalSec * 1000);
6362
- continue;
6363
- }
6364
- const prGone = state.openPr === null || state.openPr.number !== args.prNumber;
6365
- const shaMatches2 = args.manifestSha === null ? state.hasAppFile && state.lastAppliedManifestSha !== null : state.lastAppliedManifestSha === args.manifestSha;
6366
- if (prGone && shaMatches2) {
6367
- if (dotsThisLine > 0)
6368
- args.io.out("");
6369
- 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;
6370
6359
  }
6371
- if (prGone && !shaMatches2 && lastPrSeen) {
6372
- if (dotsThisLine > 0)
6373
- args.io.out("");
6374
- return {
6375
- kind: "failed",
6376
- reason: "the bot PR closed without applying this manifest sha (was it rejected or superseded?)"
6377
- };
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;
6378
6427
  }
6379
- lastPrSeen = state.openPr !== null;
6380
6428
  process.stdout.write(".");
6381
6429
  dotsThisLine++;
6382
6430
  if (dotsThisLine >= 60) {
@@ -6389,15 +6437,29 @@ async function pollUntilApplied(args) {
6389
6437
  args.io.out("");
6390
6438
  return { kind: "timed-out" };
6391
6439
  }
6392
- 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
+ };
6393
6448
  switch (outcome.kind) {
6394
6449
  case "applied":
6395
6450
  return 0;
6396
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
+ }
6397
6459
  return 1;
6398
6460
  case "timed-out":
6399
6461
  if (prUrl !== undefined) {
6400
- console.error(`! timed out waiting for apply — check ${prUrl} for live status.`);
6462
+ err(`! timed out waiting for apply — check ${prUrl} for live status.`);
6401
6463
  }
6402
6464
  return 4;
6403
6465
  case "transport":
@@ -7141,7 +7203,7 @@ function surfaceDeployExtras(body, io, slug, allowStale = false) {
7141
7203
  if (adw.manifestOnly !== undefined && adw.manifestOnly.length > 0) {
7142
7204
  io.err(` declared but NOT enforced: ${adw.manifestOnly.join(", ")}`);
7143
7205
  }
7144
- io.err(` reconcile access via the gated TF route — \`launchpad deploy\` can't (it ships content only).`);
7206
+ io.err(` reconcile with \`launchpad deploy --apply\` (the gated TF route) — \`launchpad deploy\` can't (it ships content only).`);
7145
7207
  }
7146
7208
  }
7147
7209
  function isStaleBlock(body) {
@@ -7347,8 +7409,10 @@ async function runModelADeploy(args) {
7347
7409
  }
7348
7410
  io.err("");
7349
7411
  io.err(" Your manifest's access groups don't match what the gateway enforces.");
7350
- io.err(" `launchpad deploy` ships content only and cannot change access — reconcile");
7351
- io.err(" via the gated TF route (see the access-change runbook), then redeploy.");
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) and waits for the apply verdict. Then redeploy your content.");
7352
7416
  io.err(" Nothing was committed by this attempt.");
7353
7417
  return 1;
7354
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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"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const CLI_VERSION = "0.45.0";
1
+ export declare const CLI_VERSION = "0.46.1";
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.45.0",
3
+ "version": "0.46.1",
4
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": {
@@ -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.45.0
4
+ version: 0.46.1
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.45.0
4
+ version: 0.46.1
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.45.0
4
+ version: 0.46.1
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.45.0
4
+ version: 0.46.1
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.45.0
4
+ version: 0.46.1
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.45.0
4
+ version: 0.46.1
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.45.0
4
+ version: 0.46.1
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.45.0
4
+ version: 0.46.1
5
5
  ---
6
6
 
7
7
  <!-- BEGIN shell-contract (managed by scripts/sync-skill-contract.sh — edit skills/_partials/shell-contract.md) -->