@revturbine/cli 0.15.0 → 0.16.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.
Files changed (2) hide show
  1. package/dist/cli.js +57 -5
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -9705,6 +9705,36 @@ function fail(cls, message) {
9705
9705
  process.exit(cls);
9706
9706
  }
9707
9707
 
9708
+ // src/lib/pin-drift.ts
9709
+ function isRecord5(value) {
9710
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9711
+ }
9712
+ function pinOf(pkg, name) {
9713
+ for (const field of ["devDependencies", "dependencies"]) {
9714
+ const deps = pkg[field];
9715
+ if (isRecord5(deps) && typeof deps[name] === "string") return deps[name];
9716
+ }
9717
+ return void 0;
9718
+ }
9719
+ var EXACT = /^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/;
9720
+ function checkPinDrift(pkg) {
9721
+ if (!isRecord5(pkg)) return [];
9722
+ const warnings = [];
9723
+ const cliPin = pinOf(pkg, "@revturbine/cli");
9724
+ if (cliPin !== void 0 && !EXACT.test(cliPin)) {
9725
+ warnings.push(
9726
+ `@revturbine/cli is pinned "${cliPin}" \u2014 the repo-pinned CLI must be EXACT (e.g. "0.14.0"): delegation runs the repo's version, and a range makes the running CLI drift from the committed one.`
9727
+ );
9728
+ }
9729
+ const sdkPin = pinOf(pkg, "@revturbine/sdk");
9730
+ if (sdkPin !== void 0 && !sdkPin.startsWith("^")) {
9731
+ warnings.push(
9732
+ `@revturbine/sdk is pinned "${sdkPin}" \u2014 use a caret (e.g. "^${sdkPin.replace(/^[~>=\s]*/, "")}") so additive SDK releases flow in. (Note: on 0.x, ^ spans PATCH releases only.)`
9733
+ );
9734
+ }
9735
+ return warnings;
9736
+ }
9737
+
9708
9738
  // src/lib/selectors.ts
9709
9739
  var SelectorError = class extends Error {
9710
9740
  code = "STATE_REQUIRED";
@@ -9720,6 +9750,13 @@ function collectSelectors(opts, positionalFiles = []) {
9720
9750
  if (opts.release) found.push({ kind: "release", id: opts.release });
9721
9751
  return found;
9722
9752
  }
9753
+ function orderDiffSelectors(sels) {
9754
+ if (sels.length !== 2) return sels;
9755
+ const [first, second] = sels;
9756
+ if (second.kind === "live" && first.kind !== "live") return [second, first];
9757
+ if (first.kind === "file" && second.kind !== "file") return [second, first];
9758
+ return sels;
9759
+ }
9723
9760
  function describeSelector(sel) {
9724
9761
  switch (sel.kind) {
9725
9762
  case "file":
@@ -10439,12 +10476,13 @@ program.command("validate").description("Validate a Config File offline (schema)
10439
10476
  }
10440
10477
  diag("\u2713 No blocking findings.");
10441
10478
  });
10442
- program.command("diff").description("Compare two config versions (first \u2192 second). Dry-run, no writes.").argument("[file...]", "Local Config File path(s)").option("--draft", "The tenant's open draft").option("--live", "The current live Release").option("--release <id>", "A specific playbook version / Release").option("-u, --url <url>", "RevTurbine instance URL", DEFAULT_URL).option("-t, --tenant-id <id>", "x-tenant-id (defaults to the stored token tenant)").action(async (files, opts) => {
10479
+ program.command("diff").description("Compare two config versions (first \u2192 second; a file vs --draft/--live/--release previews the launch \u2014 the server side is the base). Dry-run, no writes.").argument("[file...]", "Local Config File path(s)").option("--draft", "The tenant's open draft").option("--live", "The current live Release").option("--release <id>", "A specific playbook version / Release").option("-u, --url <url>", "RevTurbine instance URL", DEFAULT_URL).option("-t, --tenant-id <id>", "x-tenant-id (defaults to the stored token tenant)").action(async (files, opts) => {
10443
10480
  const sels = requireSelectors(opts, files, { count: 2, allowed: ["file", "draft", "live", "release"], command: "diff" });
10444
- const needsServer = sels.some((s) => s.kind !== "file");
10481
+ const ordered = orderDiffSelectors(sels);
10482
+ const needsServer = ordered.some((s) => s.kind !== "file");
10445
10483
  const conn = needsServer ? connect(opts.url, opts.tenantId) : null;
10446
- const [a, b] = await Promise.all(sels.map((s) => loadVersion(conn, s)));
10447
- diag(`Diff (${sels.map((s) => s.kind === "file" ? s.path : s.kind === "release" ? `--release ${s.id}` : `--${s.kind}`).join(" \u2192 ")}):`);
10484
+ const [a, b] = await Promise.all(ordered.map((s) => loadVersion(conn, s)));
10485
+ diag(`Diff (${ordered.map((s) => s.kind === "file" ? s.path : s.kind === "release" ? `--release ${s.id}` : `--${s.kind}`).join(" \u2192 ")}):`);
10448
10486
  process.stdout.write(`${formatDiff(diffExportedConfig(a, b))}
10449
10487
  `);
10450
10488
  });
@@ -10627,7 +10665,7 @@ program.command("evaluate").description("Run placement/entitlement decisions for
10627
10665
  );
10628
10666
  var generateCmd = program.command("generate").description("Code generation from a config version (see: generate types).");
10629
10667
  generateCmd.command("types").description(
10630
- "Generate a TypeScript module of entitlement handles (namespaced by entitlement type) for type-safe can()/gate() calls."
10668
+ "Generate a TypeScript module of Playbook handles \u2014 entitlements (namespaced by type), plans, segments, surface-template ids, and ui-path action types \u2014 for type-safe call sites."
10631
10669
  ).argument("[file...]", "Path to a Config File").option("--draft", "The tenant's open draft").option("--live", "The current live Release").option("--release <id>", "A specific playbook version / Release").option("-o, --out <path>", "Write the generated module to this path (parent dirs created); default stdout").option("--json", "Emit the handle map as JSON instead of TypeScript").option("-u, --url <url>", "RevTurbine instance URL", DEFAULT_URL).option("-t, --tenant-id <id>", "x-tenant-id (defaults to the stored token tenant)").action(
10632
10670
  async (files, opts) => {
10633
10671
  const [sel] = requireSelectors(opts, files, {
@@ -10796,6 +10834,20 @@ function gitRootOf(from) {
10796
10834
  process.exit(child.status ?? EXIT.UNEXPECTED);
10797
10835
  }
10798
10836
  }
10837
+ if (process.argv.includes("-V") || process.argv.includes("--version")) {
10838
+ process.stdout.write(`${pkgVersion} (schema ${SCHEMA_VERSION})
10839
+ `);
10840
+ try {
10841
+ const pkgPath = path2.resolve("package.json");
10842
+ if (existsSync2(pkgPath)) {
10843
+ for (const warning of checkPinDrift(JSON.parse(readFileSync2(pkgPath, "utf8")))) {
10844
+ diag(`\u26A0 pin drift: ${warning}`);
10845
+ }
10846
+ }
10847
+ } catch {
10848
+ }
10849
+ process.exit(EXIT.OK);
10850
+ }
10799
10851
  program.exitOverride();
10800
10852
  try {
10801
10853
  await program.parseAsync(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revturbine/cli",
3
- "version": "0.15.0",
3
+ "version": "0.16.1",
4
4
  "description": "revturbine — verify RevTurbine ExportedConfig files and ship them to a RevTurbine instance through the Change Set lifecycle.",
5
5
  "license": "MIT",
6
6
  "repository": {