@tokenoftrust/cli 4.4.2 → 4.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokenoftrust/cli",
3
- "version": "4.4.2",
3
+ "version": "4.5.0",
4
4
  "description": "Token of Trust developer CLI — clone a tenant store, run it locally with save→reload, and submit it for preview. Installs the `tot` command.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Token of Trust",
@@ -39,7 +39,7 @@ import { openBrowser } from "../open.mjs";
39
39
  import { missingGrantsOf, refusalHint } from "../admission-hint.mjs";
40
40
  // Reuse `tot ship`'s operator-secret precedence + live-url derivation verbatim so
41
41
  // ship + hotfix speak ONE operator-auth contract.
42
- import { resolveOperatorSecret, liveUrlFor, normalizeLiveDrift } from "./ship.mjs";
42
+ import { resolveOperatorSecret, normalizeLiveDrift } from "./ship.mjs";
43
43
 
44
44
  const DEFAULT_STOREFRONT_URL = "https://storefront.tokenoftrust.store";
45
45
 
@@ -127,6 +127,7 @@ export function normalizeHotfixPlan(data) {
127
127
  bypassedPrs: Array.isArray(o.bypassedPrs) ? o.bypassedPrs : [],
128
128
  rollbackTarget: o.rollbackTarget && typeof o.rollbackTarget === "object" ? o.rollbackTarget : null,
129
129
  warning: normalizeLiveDrift(o.warning),
130
+ liveUrl: typeof o.liveUrl === "string" && o.liveUrl ? o.liveUrl : null,
130
131
  paywall:
131
132
  o.paywall && typeof o.paywall === "object"
132
133
  ? { allowed: o.paywall.allowed === true, message: typeof o.paywall.message === "string" ? o.paywall.message : null }
@@ -277,7 +278,7 @@ export async function runHotfix(
277
278
 
278
279
  // 2. Print the EXACT plan — including the unshipped preview work it BYPASSES —
279
280
  // then require ONE explicit confirm (default NO).
280
- const liveUrl = liveUrlFor(tenant);
281
+ const liveUrl = plan.liveUrl;
281
282
  const planLines = planForAction({
282
283
  action: "hotfix",
283
284
  tenant,
@@ -223,14 +223,6 @@ export async function pollChangeShipped(scoped, { id }, { attempts = 6, delayMs
223
223
  return last;
224
224
  }
225
225
 
226
- // ─── URL derivation (pure) ─────────────────────────────────────────────────────
227
-
228
- /** The live site URL for a tenant (the tenant IS its apex domain, e.g. tokenoftrust.com). Pure. */
229
- export function liveUrlFor(tenant) {
230
- const t = (tenant || "").trim();
231
- return t ? `https://${t}` : null;
232
- }
233
-
234
226
  // ─── Response normalisation (defensive — one endpoint, but shapes may vary) ─────
235
227
 
236
228
  /**
@@ -242,7 +234,8 @@ export function liveUrlFor(tenant) {
242
234
  * includedPrs:Array<{prNumber?:number|null,changeId?:string|null,headSha?:string|null}>,
243
235
  * integrationRunId:string|null, receiptId:string|null,
244
236
  * rollbackTarget:{receiptId:string,aggregateSha:string,artifactDigest?:string}|null,
245
- * paywall:{allowed:boolean,message:string|null}, alreadyShipped:boolean} |
237
+ * paywall:{allowed:boolean,message:string|null}, alreadyShipped:boolean,
238
+ * provedAt:string|null, liveUrl:string|null} |
246
239
  * {ok:false, reason:string, message:string}}
247
240
  */
248
241
  /** The plan CDN drift warning, or null when the ledger and the CDN name the same release. */
@@ -283,6 +276,8 @@ export function normalizeShipPlan(data) {
283
276
  }
284
277
  : { allowed: true, message: null },
285
278
  alreadyShipped: o.alreadyShipped === true,
279
+ provedAt: typeof o.provedAt === "string" && o.provedAt ? o.provedAt : null,
280
+ liveUrl: typeof o.liveUrl === "string" && o.liveUrl ? o.liveUrl : null,
286
281
  };
287
282
  }
288
283
  return {
@@ -553,9 +548,22 @@ export async function runShip(
553
548
  return 1;
554
549
  }
555
550
 
551
+ // The pinned release is already what live serves and nothing else is pending: there is nothing
552
+ // to confirm or POST. A CDN-drift warning means live is not what the ledger says, so that
553
+ // still goes through the plan.
554
+ if (plan.ok && plan.alreadyShipped && !plan.warning && !spaces.ready.length) {
555
+ const detail = [
556
+ plan.receiptId ? `receipt ${plan.receiptId}` : null,
557
+ plan.provedAt ? `proved ${plan.provedAt}` : null,
558
+ ].filter(Boolean).join(", ");
559
+ console.log(` Already live: ${plan.pinnedSha}${detail ? ` (${detail})` : ""} — nothing to ship`);
560
+ return 0;
561
+ }
562
+
556
563
  // 2. Print the EXACT plan via the shared affordance, then require ONE
557
564
  // explicit confirm (`--yes` non-interactive; a non-TTY without it refuses).
558
- const liveUrl = liveUrlFor(tenant);
565
+ // The live URL is the server's served truth; the client derives none.
566
+ const liveUrl = plan.ok ? plan.liveUrl : null;
559
567
  const planLines = plan.ok
560
568
  ? planForAction({
561
569
  action: "ship",