@m-kopa/launchpad-cli 0.50.0 → 0.52.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 CHANGED
@@ -8,6 +8,26 @@ pre-1.0 minor bumps may carry breaking changes per ADR 0005.
8
8
 
9
9
  ## Unreleased
10
10
 
11
+ ## 0.52.0 - 2026-07-18
12
+
13
+ **Server-authoritative manifest apply completion.**
14
+
15
+ - A deploy now attaches directly to the exact server-opened apply PR and head SHA.
16
+ It never creates a second apply attempt for the same durable reconcile intent, and an identity mismatch remains a hard protocol error that names both sides.
17
+ - `launchpad merge` accepts `--repo app|platform`, fails closed when the same PR number exists in both repositories, and explains that attested platform apply PRs are auto-managed.
18
+ - Manifest status treats the registry's successfully applied manifest SHA as primary deployed provenance, so per-app-workspace apps report a real deployed SHA without relying on legacy flat Terraform metadata.
19
+ - Bot-side apply completion now uses an append-only attempt ledger, exact PR and check evidence, one atomic provenance transition, webhook-first completion, sweep fallback, and fresh per-attempt branches cut from platform `main`.
20
+
21
+ ## 0.51.0 - 2026-07-17
22
+
23
+ **Self-serve recovery rendering + honest guidance.**
24
+
25
+ `launchpad recover` now renders a synchronous pre-Terraform teardown response (HTTP 200, `lifecycle: released`, slug reusable) as a success and prints the server's `launchpad create` next step, instead of failing with "bot returned an unexpected HTTP 200 response". (Found by the live recovery canary.)
26
+ Failed `status` and recoverable `destroy_failed` output now name the exact self-serve command (`launchpad recover` / `launchpad destroy`) instead of directing owners to platform-team or the misleading "re-run `launchpad deploy`".
27
+
28
+ Bot-side (delivered under the recovery bundle, published with this bump):
29
+ recovery observability and convergence - every mutating `cli_recover` audit record now includes the recovery class, wedge stage, and persisted cause; the quarter-hour stuck-apply sweep now lists terminal-failed registry records and files one deduplicated aggregate platform-team issue; interrupted pre-Terraform teardown resumes from an already-archived record, Terraform-PR re-drive reuses its open unarmed replacement, and post-Terraform retry starts a fresh deployment.
30
+
11
31
  Bot-side provisioning recovery safety spine: `launchpad recover` now classifies non-serving failed apps by their recorded provisioning stage.
12
32
  Mutating dispatch is guarded by the original submission's single-flight lease, an original-Workflow terminal-state check, owner/co-owner/break-glass authorization for destructive or access-granting recovery, and the runtime `ROUTING_KV.__recovery_disabled` kill-switch.
13
33
  Reconcile-only recovery remains available to editors.
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.50.0";
22
+ var CLI_VERSION = "0.52.0";
23
23
 
24
24
  // src/config.ts
25
25
  import * as os from "node:os";
@@ -5535,9 +5535,9 @@ function emit3(out, asJson, io) {
5535
5535
  io.out(`${out.slug}: provisioning FAILED at stage ${out.stage ?? "unknown"}` + (out.failedReason ? `: ${out.failedReason}` : ""));
5536
5536
  if (isLikelyLiveFailureStage(out.stage)) {
5537
5537
  io.out(` the app may already be live — run \`launchpad recover ${out.slug}\` to reconcile the record;`);
5538
- io.out(" if it isn't, fix the cause and re-run `launchpad deploy`.");
5538
+ io.out(` if it is not serving, the same command starts the stage-dependent recovery.`);
5539
5539
  } else {
5540
- io.out(" fix the cause and re-run `launchpad deploy`.");
5540
+ io.out(` run \`launchpad recover ${out.slug}\` to start the stage-dependent recovery.`);
5541
5541
  }
5542
5542
  return;
5543
5543
  case "destroying":
@@ -6777,6 +6777,31 @@ async function runDeployApply(opts, io, deps = {}) {
6777
6777
  io.err(`launchpad deploy --apply: --at expects a 40-char lowercase hex git SHA, got '${opts.atSha}'`);
6778
6778
  return 64;
6779
6779
  }
6780
+ if (opts.preopenedPr !== undefined) {
6781
+ if (opts.atSha === undefined) {
6782
+ io.err("launchpad deploy --apply: server-preopened apply attachment requires its exact manifest SHA");
6783
+ return 2;
6784
+ }
6785
+ io.out(`Attaching to server-preopened apply PR #${opts.preopenedPr.number} ` + `at head ${opts.preopenedPr.headSha}.`);
6786
+ const outcome2 = await pollUntilApplied({
6787
+ slug,
6788
+ manifestSha: opts.atSha,
6789
+ prNumber: opts.preopenedPr.number,
6790
+ expectedHeadSha: opts.preopenedPr.headSha,
6791
+ cfg,
6792
+ io,
6793
+ fetcher,
6794
+ pollIntervalSec,
6795
+ timeoutMs
6796
+ });
6797
+ if (outcome2.kind !== "applied") {
6798
+ return outcomeToExit(outcome2, opts.preopenedPr.url, io);
6799
+ }
6800
+ deletePinIfPresent(cfg, slug, io);
6801
+ io.out(`✓ Applied ${slug} from PR #${opts.preopenedPr.number}.`);
6802
+ deps.onApplied?.();
6803
+ return 0;
6804
+ }
6780
6805
  io.out(opts.atSha !== undefined ? `Planning apply for ${slug} @ ${opts.atSha.slice(0, 7)} (managed repo) …` : `Planning apply for ${slug} (bot resolves managed main HEAD) …`);
6781
6806
  let plan;
6782
6807
  try {
@@ -6817,9 +6842,6 @@ async function runDeployApply(opts, io, deps = {}) {
6817
6842
  return 0;
6818
6843
  }
6819
6844
  }
6820
- if (opts.preopenedPr !== undefined) {
6821
- io.out(`Server already opened exact-SHA apply PR #${opts.preopenedPr.number}; ` + "confirming it idempotently before polling.");
6822
- }
6823
6845
  let apply;
6824
6846
  try {
6825
6847
  apply = await apiJson(cfg, {
@@ -6834,10 +6856,6 @@ async function runDeployApply(opts, io, deps = {}) {
6834
6856
  io.err(`launchpad deploy --apply: protocol failure from /apps/${slug}/manifest/apply: ` + `requested ${manifestSha}, received ${String(apply.manifestSha)}`);
6835
6857
  return 2;
6836
6858
  }
6837
- if (opts.preopenedPr !== undefined && apply.prNumber !== opts.preopenedPr.number) {
6838
- io.err(`launchpad deploy --apply: protocol failure from /apps/${slug}/manifest/apply: ` + `server-preopened PR #${opts.preopenedPr.number}, received #${apply.prNumber}`);
6839
- return 2;
6840
- }
6841
6859
  io.out("");
6842
6860
  io.out(`PR opened: ${apply.prUrl}`);
6843
6861
  io.out(`Branch: ${apply.branch}`);
@@ -6896,6 +6914,13 @@ async function pollUntilApplied(args) {
6896
6914
  await sleep(args.pollIntervalSec * 1000);
6897
6915
  continue;
6898
6916
  }
6917
+ if (args.expectedHeadSha !== undefined) {
6918
+ breakDots();
6919
+ return {
6920
+ kind: "transport",
6921
+ reason: "the bot cannot verify the exact server-preopened apply attempt"
6922
+ };
6923
+ }
6899
6924
  breakDots();
6900
6925
  args.io.err("! bot has no apply-status endpoint yet — falling back to the coarse merge-poll (upgrade pending bot deploy)");
6901
6926
  mode = "legacy";
@@ -6916,6 +6941,13 @@ async function pollUntilApplied(args) {
6916
6941
  reason: `protocol failure from /apps/${args.slug}/manifest/apply-status: ` + `requested ${args.manifestSha}, received ${status.manifestSha}`
6917
6942
  };
6918
6943
  }
6944
+ if (args.expectedHeadSha !== undefined && (status.prNumber !== args.prNumber || status.headSha !== args.expectedHeadSha)) {
6945
+ breakDots();
6946
+ return {
6947
+ kind: "transport",
6948
+ reason: `server-preopened PR #${args.prNumber} head ${args.expectedHeadSha}, ` + `received PR #${status.prNumber} head ${String(status.headSha)}`
6949
+ };
6950
+ }
6919
6951
  if (status.state === "applied") {
6920
6952
  breakDots();
6921
6953
  return { kind: "applied" };
@@ -10337,7 +10369,7 @@ var HANDLED_STATUSES = [409, 422, 502, 503];
10337
10369
  async function runMerge(args, io) {
10338
10370
  const parsed = parseArgs8(args);
10339
10371
  if (parsed === null) {
10340
- io.err(`usage: launchpad merge <prNumber> [--slug <slug>]
10372
+ io.err(`usage: launchpad merge <prNumber> [--slug <slug>] [--repo app|platform]
10341
10373
  ` + " (prNumber is required; slug defaults to the cwd's `launchpad-app-<slug>` suffix)");
10342
10374
  return 64;
10343
10375
  }
@@ -10362,7 +10394,7 @@ async function runMerge(args, io) {
10362
10394
  io.out(`Merging PR #${parsed.prNumber} on ${slug} …`);
10363
10395
  const res = await apiRaw(cfg, {
10364
10396
  method: "POST",
10365
- path: `/apps/${slug}/merge/${parsed.prNumber}`,
10397
+ path: `/apps/${slug}/merge/${parsed.prNumber}` + (parsed.repository === null ? "" : `?repository=${parsed.repository}`),
10366
10398
  nonThrowingStatuses: [...HANDLED_STATUSES]
10367
10399
  });
10368
10400
  if (res.ok) {
@@ -10416,6 +10448,7 @@ async function runMerge(args, io) {
10416
10448
  }
10417
10449
  function parseArgs8(args) {
10418
10450
  let slug = null;
10451
+ let repository = null;
10419
10452
  let prNumber = null;
10420
10453
  let i = 0;
10421
10454
  while (i < args.length) {
@@ -10428,6 +10461,14 @@ function parseArgs8(args) {
10428
10461
  i += 2;
10429
10462
  continue;
10430
10463
  }
10464
+ if (a === "--repo") {
10465
+ const value = args[i + 1];
10466
+ if (value !== "app" && value !== "platform")
10467
+ return null;
10468
+ repository = value;
10469
+ i += 2;
10470
+ continue;
10471
+ }
10431
10472
  if (/^\d+$/.test(a)) {
10432
10473
  if (prNumber !== null)
10433
10474
  return null;
@@ -10442,7 +10483,7 @@ function parseArgs8(args) {
10442
10483
  }
10443
10484
  if (prNumber === null)
10444
10485
  return null;
10445
- return { slug, prNumber };
10486
+ return { slug, prNumber, repository };
10446
10487
  }
10447
10488
  function renderBotError(status, env, io, prNumber = null) {
10448
10489
  const code = env?.error ?? "unknown";
@@ -10479,6 +10520,12 @@ function renderBotError(status, env, io, prNumber = null) {
10479
10520
  case "pipeline_unavailable":
10480
10521
  io.err("launchpad merge: no review state recorded for this PR — push a commit to trigger the workflow, or wait for the first event.");
10481
10522
  return;
10523
+ case "platform_apply_auto_managed":
10524
+ io.err("launchpad merge: this platform apply PR is auto-managed; inspect `launchpad status` or apply status.");
10525
+ return;
10526
+ case "merge_pr_ambiguous":
10527
+ io.err("launchpad merge: that PR number exists in both repositories; pass `--repo app` or `--repo platform`.");
10528
+ return;
10482
10529
  case "credential_unavailable":
10483
10530
  io.err("launchpad merge: bot credential is temporarily unavailable — retry in a moment.");
10484
10531
  return;
@@ -10911,8 +10958,7 @@ function renderBotError2(status, env, slug, io) {
10911
10958
  return;
10912
10959
  case "destroy_failed":
10913
10960
  io.err(`launchpad destroy: ${message}`);
10914
- io.err(" Re-run `launchpad destroy` to retry once the platform-team has unstuck the apply,");
10915
- io.err(" or contact platform-team if the destroy PR needs manual intervention.");
10961
+ io.err(` Re-run \`launchpad destroy ${slug}\` to retry the idempotent teardown.`);
10916
10962
  return;
10917
10963
  case "conflict":
10918
10964
  io.err(`launchpad destroy: ${message}`);
@@ -11161,6 +11207,10 @@ async function runRecover(args, io) {
11161
11207
  renderSuccess2(body, io);
11162
11208
  return 0;
11163
11209
  }
11210
+ if (res.status === 200 && isRecord3(body) && typeof body.message === "string") {
11211
+ io.out(body.message);
11212
+ return 0;
11213
+ }
11164
11214
  if (res.status === 202 && isRecoverInitiatedBody(body)) {
11165
11215
  renderInitiated(body, io);
11166
11216
  return 0;
@@ -6,6 +6,7 @@ export declare const mergeCommand: Command;
6
6
  interface MergeArgs {
7
7
  readonly slug: string | null;
8
8
  readonly prNumber: number;
9
+ readonly repository: "app" | "platform" | null;
9
10
  }
10
11
  /**
11
12
  * Parse the merge verb's args. Returns null on malformed argv. The
@@ -1 +1 @@
1
- {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/commands/merge.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAY,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAa,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAI9D,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAC5B,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,iBAAiB,CAAC;AAEzB,eAAO,MAAM,YAAY,EAAE,OAI1B,CAAC;AAEF,UAAU,SAAS;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AA8GD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI,CA8BnE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,gBAAgB,GAAG,IAAI,EAC5B,EAAE,EAAE,KAAK,EACT,QAAQ,GAAE,MAAM,GAAG,IAAW,GAC7B,IAAI,CA4EN"}
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/commands/merge.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAY,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAa,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAI9D,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAC5B,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,iBAAiB,CAAC;AAEzB,eAAO,MAAM,YAAY,EAAE,OAI1B,CAAC;AAEF,UAAU,SAAS;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,KAAK,GAAG,UAAU,GAAG,IAAI,CAAC;CAChD;AAkHD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI,CAsCnE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,gBAAgB,GAAG,IAAI,EAC5B,EAAE,EAAE,KAAK,EACT,QAAQ,GAAE,MAAM,GAAG,IAAW,GAC7B,IAAI,CAsFN"}
@@ -1 +1 @@
1
- {"version":3,"file":"recover.d.ts","sourceRoot":"","sources":["../../src/commands/recover.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAS,OAAO,EAAY,MAAM,kBAAkB,CAAC;AAEjE,eAAO,MAAM,cAAc,EAAE,OAI5B,CAAC;AAIF,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AA2OD;;kEAEkE;AAClE,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,GAAE,MAAsB,EAC3B,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC5B,WAAW,GAAG,MAAM,CAgDtB"}
1
+ {"version":3,"file":"recover.d.ts","sourceRoot":"","sources":["../../src/commands/recover.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAS,OAAO,EAAY,MAAM,kBAAkB,CAAC;AAEjE,eAAO,MAAM,cAAc,EAAE,OAI5B,CAAC;AAIF,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAuPD;;kEAEkE;AAClE,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,GAAE,MAAsB,EAC3B,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC5B,WAAW,GAAG,MAAM,CAgDtB"}
@@ -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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"}
@@ -1 +1 @@
1
- {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/deploy/apply.ts"],"names":[],"mappings":"AAqDA,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAU1D,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;iCAC6B;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;wDACoD;IACpD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB;;;oEAGgE;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,mEAAmE;IACnE,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,0EAA0E;IAC1E,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;CACzC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,gEAAgE;IAChE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACjC;AAwCD,wBAAsB,cAAc,CAClC,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,KAAK,EACT,IAAI,GAAE,SAAc,GACnB,OAAO,CAAC,QAAQ,CAAC,CAmOnB"}
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/deploy/apply.ts"],"names":[],"mappings":"AAqDA,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAU1D,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;iCAC6B;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;wDACoD;IACpD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB;;;oEAGgE;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,mEAAmE;IACnE,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,0EAA0E;IAC1E,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;CACzC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,gEAAgE;IAChE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACjC;AAwCD,wBAAsB,cAAc,CAClC,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,KAAK,EACT,IAAI,GAAE,SAAc,GACnB,OAAO,CAAC,QAAQ,CAAC,CAoPnB"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const CLI_VERSION = "0.50.0";
1
+ export declare const CLI_VERSION = "0.52.0";
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.50.0",
3
+ "version": "0.52.0",
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.50.0
4
+ version: 0.52.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.50.0
4
+ version: 0.52.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.50.0
4
+ version: 0.52.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.50.0
4
+ version: 0.52.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.50.0
4
+ version: 0.52.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.50.0
4
+ version: 0.52.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.50.0
4
+ version: 0.52.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.50.0
4
+ version: 0.52.0
5
5
  ---
6
6
 
7
7
  <!-- BEGIN shell-contract (managed by scripts/sync-skill-contract.sh — edit skills/_partials/shell-contract.md) -->