@pretense/cli 0.6.25 → 0.6.26

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.
@@ -17,7 +17,7 @@ function versionFromPackageJson() {
17
17
  return void 0;
18
18
  }
19
19
  }
20
- var PRETENSE_VERSION = (true ? "0.6.25" : void 0) ?? versionFromPackageJson() ?? "0.0.0-unknown";
20
+ var PRETENSE_VERSION = (true ? "0.6.26" : void 0) ?? versionFromPackageJson() ?? "0.0.0-unknown";
21
21
 
22
22
  export {
23
23
  PRETENSE_VERSION
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  PRETENSE_VERSION
4
- } from "./chunk-XYBJ63JG.js";
4
+ } from "./chunk-ZSQPYJVT.js";
5
5
  import {
6
6
  __commonJS,
7
7
  __toESM,
@@ -16657,11 +16657,11 @@ function versionFromCliPackageJson() {
16657
16657
  return void 0;
16658
16658
  }
16659
16659
  function productVersion() {
16660
- return override ?? (true ? "0.6.25" : void 0) ?? versionFromCliPackageJson() ?? "0.0.0-unknown";
16660
+ return override ?? (true ? "0.6.26" : void 0) ?? versionFromCliPackageJson() ?? "0.0.0-unknown";
16661
16661
  }
16662
16662
  var UNKNOWN_COMMIT = "unknown";
16663
16663
  function bakedCommitSha() {
16664
- return "24595f8f691656d511f75ed2d8b59f98069779ac".length > 0 ? "24595f8f691656d511f75ed2d8b59f98069779ac" : UNKNOWN_COMMIT;
16664
+ return "91077fab39006ac43c0256257c895b5534640e17".length > 0 ? "91077fab39006ac43c0256257c895b5534640e17" : UNKNOWN_COMMIT;
16665
16665
  }
16666
16666
  var FEATURE_TIERS = {
16667
16667
  compliance_export: "pro",
@@ -18657,6 +18657,39 @@ function parseEntitlement(body) {
18657
18657
  ...subscriptionStatus !== void 0 ? { subscriptionStatus } : {}
18658
18658
  };
18659
18659
  }
18660
+ function parseCounter(raw2) {
18661
+ if (typeof raw2 !== "number" || !Number.isFinite(raw2)) return null;
18662
+ if (!Number.isInteger(raw2) || raw2 < 0) return null;
18663
+ return raw2;
18664
+ }
18665
+ function parseAllowance(raw2) {
18666
+ if (typeof raw2 !== "number" || !Number.isFinite(raw2) || !Number.isInteger(raw2)) return null;
18667
+ if (raw2 === -1) return { limit: null, unlimited: true };
18668
+ if (raw2 < 0) return null;
18669
+ return { limit: raw2, unlimited: false };
18670
+ }
18671
+ function parseResetInstant(raw2) {
18672
+ if (typeof raw2 !== "string" || raw2.trim().length === 0) return null;
18673
+ const ms = Date.parse(raw2.trim());
18674
+ if (!Number.isFinite(ms)) return null;
18675
+ try {
18676
+ return new Date(ms).toISOString();
18677
+ } catch {
18678
+ return null;
18679
+ }
18680
+ }
18681
+ function parseRemoteQuota(body) {
18682
+ const used = parseCounter(body["codeProtectionsUsed"]);
18683
+ const allowance = parseAllowance(body["monthlyCodeProtectionLimit"]);
18684
+ if (used === null || allowance === null) return void 0;
18685
+ const resetsAt = parseResetInstant(body["periodResetsAt"]);
18686
+ if (allowance.unlimited) {
18687
+ return { used, limit: null, remaining: null, unlimited: true, resetsAt };
18688
+ }
18689
+ const reported = parseCounter(body["codeProtectionsRemaining"]);
18690
+ const remaining2 = reported ?? Math.max(0, allowance.limit - used);
18691
+ return { used, limit: allowance.limit, remaining: remaining2, unlimited: false, resetsAt };
18692
+ }
18660
18693
  async function tierFromBackend(apiKey) {
18661
18694
  const url = `${getConfiguredApiRoot()}/api/cli/auth/validate`;
18662
18695
  const controller = new AbortController();
@@ -18691,7 +18724,13 @@ async function tierFromBackend(apiKey) {
18691
18724
  detail: "the plan service did not report a recognizable plan"
18692
18725
  };
18693
18726
  }
18694
- return { tier, source: "backend", entitlement: parseEntitlement(body) };
18727
+ const quota2 = parseRemoteQuota(body);
18728
+ return {
18729
+ tier,
18730
+ source: "backend",
18731
+ entitlement: parseEntitlement(body),
18732
+ ...quota2 ? { quota: quota2 } : {}
18733
+ };
18695
18734
  } catch (err) {
18696
18735
  const aborted = err?.name === "AbortError";
18697
18736
  return {
@@ -18753,6 +18792,87 @@ function collectUsage(dbPath) {
18753
18792
  function resetCadenceLabel() {
18754
18793
  return `every ${QUOTA_PERIOD_DAYS2} days`;
18755
18794
  }
18795
+ function formatResetInstant(iso) {
18796
+ const ms = Date.parse(iso);
18797
+ if (!Number.isFinite(ms)) return iso;
18798
+ return new Date(ms).toISOString().replace("T", " ").replace(/\.\d{3}Z$/, " UTC");
18799
+ }
18800
+ function resetLabel(quota2) {
18801
+ return quota2?.resetsAt ? formatResetInstant(quota2.resetsAt) : resetCadenceLabel();
18802
+ }
18803
+ function percentOf(used, limit) {
18804
+ if (limit <= 0) return used > 0 ? 100 : 0;
18805
+ return Math.round(used / limit * 100);
18806
+ }
18807
+ function resolveMutationBudget(resolution, localMutationsApplied) {
18808
+ const quota2 = resolution.quota;
18809
+ if (quota2) {
18810
+ return {
18811
+ source: "server",
18812
+ used: quota2.used,
18813
+ limit: quota2.limit,
18814
+ remaining: quota2.remaining,
18815
+ percent: quota2.unlimited ? null : percentOf(quota2.used, quota2.limit ?? 0),
18816
+ unlimited: quota2.unlimited,
18817
+ limitUnknown: false,
18818
+ resetsAt: quota2.resetsAt
18819
+ };
18820
+ }
18821
+ const tier = resolution.tier;
18822
+ if (!tier) {
18823
+ return {
18824
+ source: "local-audit",
18825
+ used: localMutationsApplied,
18826
+ limit: null,
18827
+ remaining: null,
18828
+ percent: null,
18829
+ unlimited: false,
18830
+ limitUnknown: true,
18831
+ resetsAt: null
18832
+ };
18833
+ }
18834
+ const planLimit = PLAN_CONFIGS[tier].mutationsPerPeriod;
18835
+ if (planLimit === null) {
18836
+ return {
18837
+ source: "local-audit",
18838
+ used: localMutationsApplied,
18839
+ limit: null,
18840
+ remaining: null,
18841
+ percent: null,
18842
+ unlimited: true,
18843
+ limitUnknown: false,
18844
+ resetsAt: null
18845
+ };
18846
+ }
18847
+ return {
18848
+ source: "local-audit",
18849
+ used: localMutationsApplied,
18850
+ limit: planLimit,
18851
+ remaining: Math.max(0, planLimit - localMutationsApplied),
18852
+ percent: percentOf(localMutationsApplied, planLimit),
18853
+ unlimited: false,
18854
+ limitUnknown: false,
18855
+ resetsAt: null
18856
+ };
18857
+ }
18858
+ function budgetSourceLines(budget, resolution, localMutationsApplied) {
18859
+ if (budget.source === "server") {
18860
+ const lines = [
18861
+ "Mutations: counted by the Pretense API \u2014 this is the figure your quota is enforced against."
18862
+ ];
18863
+ if (localMutationsApplied !== budget.used) {
18864
+ lines.push(
18865
+ `This machine's local audit log records ${localMutationsApplied.toLocaleString("en-US")} \u2014 a different machine set and window, not your quota.`
18866
+ );
18867
+ }
18868
+ return lines;
18869
+ }
18870
+ const why = resolution.source === "no-credentials" ? "you are not signed in, so no server was asked" : resolution.source === "key-prefix" ? "a legacy pt- key names its plan offline, so no server was asked for your usage" : resolution.source === "unverified" ? resolution.detail ?? "the plan service could not be reached" : "the plan service did not report usage figures";
18871
+ return [
18872
+ "Mutations: counted LOCALLY on this machine (~/.pretense/audit.db) \u2014 this is NOT",
18873
+ `the usage your quota is enforced against, because ${why}.`
18874
+ ];
18875
+ }
18756
18876
  function priceLabel(tier) {
18757
18877
  const cents = PLAN_CONFIGS[tier].pricePerSeatCents;
18758
18878
  if (cents === null) return "custom \u2014 contact sales";
@@ -20242,22 +20362,38 @@ function percentLabel(percent) {
20242
20362
  if (percent >= 80) return chalk9.yellow(`${percent}%`);
20243
20363
  return chalk9.green(`${percent}%`);
20244
20364
  }
20365
+ function mutationsPayload(budget) {
20366
+ return {
20367
+ source: budget.source,
20368
+ current: budget.used,
20369
+ limit: budget.limit,
20370
+ percent: budget.percent,
20371
+ remaining: budget.remaining,
20372
+ // `allowed` is only knowable with an allowance. `limitUnknown` must not
20373
+ // read as `true` — "we could not check" is not "you are fine".
20374
+ allowed: budget.limitUnknown ? null : budget.unlimited || (budget.remaining ?? 0) > 0,
20375
+ unlimited: budget.unlimited
20376
+ };
20377
+ }
20245
20378
  function emptyUsagePayload(resolution) {
20246
20379
  const tier = resolution.tier;
20247
20380
  const planConfig = tier ? PLAN_CONFIGS[tier] : null;
20381
+ const budget = resolveMutationBudget(resolution, 0);
20248
20382
  return {
20249
20383
  tier,
20250
20384
  tierSource: resolution.source,
20251
20385
  ...resolution.detail ? { tierDetail: resolution.detail } : {},
20252
20386
  periodStart: null,
20253
20387
  periodEnd: null,
20254
- resetDate: null,
20388
+ resetDate: budget.resetsAt,
20255
20389
  resetCadenceDays: QUOTA_PERIOD_DAYS2,
20390
+ quotaSource: budget.source,
20256
20391
  usage: {
20257
- mutations: { current: 0, limit: planConfig ? planConfig.mutationsPerPeriod : null, percent: 0, allowed: true },
20258
- scans: { current: 0, limit: planConfig ? planConfig.scansPerPeriod : null, percent: 0, allowed: true }
20392
+ mutations: mutationsPayload(budget),
20393
+ scans: { source: "local-audit", current: 0, limit: planConfig ? planConfig.scansPerPeriod : null, percent: 0, allowed: true }
20259
20394
  },
20260
- overallPercent: 0,
20395
+ localAudit: { mutations: 0, scans: 0, secretsBlocked: 0 },
20396
+ overallPercent: budget.percent ?? 0,
20261
20397
  recommendedUpgrade: null
20262
20398
  };
20263
20399
  }
@@ -20278,6 +20414,7 @@ function usageCommand() {
20278
20414
  return;
20279
20415
  }
20280
20416
  const usageMetrics = collected.metrics;
20417
+ const budget = resolveMutationBudget(resolution, usageMetrics.mutationsApplied);
20281
20418
  if (opts.json) {
20282
20419
  const limits = tier ? checkAllLimits(usageMetrics, tier) : null;
20283
20420
  const planConfig2 = tier ? PLAN_CONFIGS[tier] : null;
@@ -20289,23 +20426,33 @@ function usageCommand() {
20289
20426
  ...resolution.detail ? { tierDetail: resolution.detail } : {},
20290
20427
  periodStart: usageMetrics.periodStart,
20291
20428
  periodEnd: usageMetrics.periodEnd,
20292
- resetDate: null,
20429
+ // The server's own instant when it reported one. `null` means the
20430
+ // CLI was not told — it does NOT mean "no reset exists", and it is
20431
+ // not an invitation to compute one.
20432
+ resetDate: budget.resetsAt,
20293
20433
  resetCadenceDays: QUOTA_PERIOD_DAYS2,
20434
+ quotaSource: budget.source,
20294
20435
  usage: {
20295
- mutations: {
20296
- current: usageMetrics.mutationsApplied,
20297
- limit: planConfig2 ? planConfig2.mutationsPerPeriod : null,
20298
- percent: limits ? limits.mutations.usagePercent ?? 0 : null,
20299
- allowed: limits ? limits.mutations.allowed : null
20300
- },
20436
+ mutations: mutationsPayload(budget),
20437
+ // Scans have no server-side counterpart on the validate
20438
+ // response, so this half is local and says so.
20301
20439
  scans: {
20440
+ source: "local-audit",
20302
20441
  current: usageMetrics.totalScans,
20303
20442
  limit: planConfig2 ? planConfig2.scansPerPeriod : null,
20304
20443
  percent: limits ? limits.scans.usagePercent ?? 0 : null,
20305
20444
  allowed: limits ? limits.scans.allowed : null
20306
20445
  }
20307
20446
  },
20308
- overallPercent: tier ? maxUsagePercent(usageMetrics, tier) : null,
20447
+ // The raw local counters, always under a key that names them as
20448
+ // local, so a consumer that wants this machine's view can have it
20449
+ // without it ever being mistaken for the quota.
20450
+ localAudit: {
20451
+ mutations: usageMetrics.mutationsApplied,
20452
+ scans: usageMetrics.totalScans,
20453
+ secretsBlocked: usageMetrics.secretsBlocked
20454
+ },
20455
+ overallPercent: budget.percent ?? (tier ? maxUsagePercent(usageMetrics, tier) : null),
20309
20456
  recommendedUpgrade: tier ? recommendedTier(usageMetrics, tier) : null
20310
20457
  },
20311
20458
  null,
@@ -20314,11 +20461,11 @@ function usageCommand() {
20314
20461
  );
20315
20462
  return;
20316
20463
  }
20317
- const resetDate = resetCadenceLabel();
20464
+ const resetDate = resetLabel(resolution.quota);
20318
20465
  console.log(
20319
20466
  chalk9.cyan(
20320
- "\n Pretense Usage \u2014 " + // Header shows today's date, NOT a billing month: quotas roll on a
20321
- // 7-day window anchored to signup, so a month name would imply a
20467
+ "\n Pretense Usage \u2014 " + // Header shows today's date, NOT a billing month: the quota window
20468
+ // trails the account's own activity, so a month name would imply a
20322
20469
  // reset boundary that does not exist.
20323
20470
  (/* @__PURE__ */ new Date()).toLocaleDateString("en-US", {
20324
20471
  month: "long",
@@ -20337,35 +20484,60 @@ function usageCommand() {
20337
20484
  console.log(chalk9.yellow(` ${line}`));
20338
20485
  }
20339
20486
  console.log();
20340
- console.log(" " + "Mutations".padEnd(20) + usageMetrics.mutationsApplied.toLocaleString("en-US"));
20487
+ console.log(" " + "Mutations".padEnd(20) + budget.used.toLocaleString("en-US"));
20341
20488
  console.log(" " + "API Requests".padEnd(20) + usageMetrics.totalScans.toLocaleString("en-US"));
20342
20489
  console.log(" " + "Secrets Blocked".padEnd(20) + usageMetrics.secretsBlocked.toLocaleString("en-US"));
20343
20490
  console.log();
20491
+ for (const line of budgetSourceLines(budget, resolution, usageMetrics.mutationsApplied)) {
20492
+ console.log(chalk9.dim(` ${line}`));
20493
+ }
20494
+ console.log();
20344
20495
  return;
20345
20496
  }
20346
20497
  const planConfig = PLAN_CONFIGS[tier];
20347
- const overall = maxUsagePercent(usageMetrics, tier);
20498
+ const overall = budget.source === "server" ? budget.percent ?? 0 : maxUsagePercent(usageMetrics, tier);
20348
20499
  const nextTier = recommendedTier(usageMetrics, tier);
20349
20500
  console.log(
20350
20501
  " " + chalk9.bold("Metric".padEnd(20)) + chalk9.bold("Used / Limit".padEnd(30)) + chalk9.bold("Progress")
20351
20502
  );
20352
20503
  console.log(" " + chalk9.dim("\u2500".repeat(72)));
20353
20504
  const rows = [
20354
- { label: "Mutations", value: usageMetrics.mutationsApplied, limit: planConfig.mutationsPerPeriod },
20355
- { label: "API Requests", value: usageMetrics.totalScans, limit: planConfig.scansPerPeriod }
20505
+ {
20506
+ label: "Mutations",
20507
+ value: budget.used,
20508
+ // `limitUnknown` must render as unknown, NOT as unlimited. That
20509
+ // conflation is the original defect: an org at 100% of its quota read
20510
+ // every missing field as "no limit" and was told it had none.
20511
+ limit: budget.limitUnknown ? null : budget.limit,
20512
+ percent: budget.percent
20513
+ },
20514
+ {
20515
+ label: "API Requests",
20516
+ value: usageMetrics.totalScans,
20517
+ limit: planConfig.scansPerPeriod,
20518
+ percent: null
20519
+ }
20356
20520
  ];
20357
20521
  for (const row of rows) {
20358
- const percent = row.limit === null ? 0 : Math.round(row.value / row.limit * 100);
20359
- const bar2 = row.limit === null ? chalk9.dim(" unlimited ".padEnd(32)) : renderBar(percent);
20522
+ const percent = row.percent ?? (row.limit === null ? 0 : Math.round(row.value / row.limit * 100));
20523
+ const unknown = row.label === "Mutations" && budget.limitUnknown;
20524
+ const bar2 = unknown ? chalk9.dim(" not reported ".padEnd(32)) : row.limit === null ? chalk9.dim(" unlimited ".padEnd(32)) : renderBar(percent);
20525
+ const used = unknown ? `${row.value.toLocaleString("en-US")} / not reported` : formatMetric(row.value, row.limit);
20360
20526
  console.log(
20361
- " " + row.label.padEnd(20) + formatMetric(row.value, row.limit).padEnd(30) + bar2 + " " + (row.limit === null ? "" : percentLabel(percent))
20527
+ " " + row.label.padEnd(20) + used.padEnd(30) + bar2 + " " + (row.limit === null || unknown ? "" : percentLabel(percent))
20362
20528
  );
20363
20529
  }
20364
20530
  console.log(
20365
20531
  " " + "Secrets Blocked".padEnd(20) + String(usageMetrics.secretsBlocked.toLocaleString("en-US")).padEnd(30) + chalk9.dim("(no limit)")
20366
20532
  );
20367
20533
  console.log(" " + chalk9.dim("\u2500".repeat(72)));
20368
- if (tier === "enterprise") {
20534
+ for (const line of budgetSourceLines(budget, resolution, usageMetrics.mutationsApplied)) {
20535
+ console.log(" " + chalk9.dim(line));
20536
+ }
20537
+ console.log(
20538
+ " " + chalk9.dim("API Requests / Secrets Blocked: counted locally on this machine.")
20539
+ );
20540
+ if (tier === "enterprise" && budget.unlimited) {
20369
20541
  console.log(chalk9.green("\n Enterprise plan \u2014 all limits are unlimited.\n"));
20370
20542
  } else if (overall >= 100) {
20371
20543
  console.log(chalk9.red(`
@@ -22743,9 +22915,10 @@ function creditsCommand() {
22743
22915
  if (!collected && !opts.json) {
22744
22916
  console.log(chalk21.dim("\n No usage recorded yet \u2014 showing your full allowance.\n"));
22745
22917
  }
22746
- const mutationLimit = tier ? PLAN_CONFIGS[tier].mutationsPerPeriod : null;
22918
+ const budget = resolveMutationBudget(resolution, m.mutationsApplied);
22919
+ const mutationLimit = budget.limitUnknown ? null : budget.limit;
22920
+ const mutationsLeft = budget.limitUnknown ? null : budget.remaining;
22747
22921
  const scanLimit = tier ? PLAN_CONFIGS[tier].scansPerPeriod : null;
22748
- const mutationsLeft = tier ? remaining(m.mutationsApplied, mutationLimit) : null;
22749
22922
  const scansLeft = tier ? remaining(m.totalScans, scanLimit) : null;
22750
22923
  if (opts.json) {
22751
22924
  console.log(
@@ -22754,18 +22927,26 @@ function creditsCommand() {
22754
22927
  tier,
22755
22928
  tierSource: resolution.source,
22756
22929
  ...resolution.detail ? { tierDetail: resolution.detail } : {},
22757
- resetDate: null,
22930
+ // The server's instant when it sent one. It sends `periodResetsAt`
22931
+ // on every validation; this used to be hardcoded `null` while a
22932
+ // hardcoded cadence string was printed beside it.
22933
+ resetDate: budget.resetsAt,
22758
22934
  resetCadenceDays: QUOTA_PERIOD_DAYS2,
22935
+ quotaSource: budget.source,
22759
22936
  mutations: {
22760
- used: m.mutationsApplied,
22761
- limit: tier ? mutationLimit : null,
22762
- remaining: tier ? mutationsLeft : null
22937
+ source: budget.source,
22938
+ used: budget.used,
22939
+ limit: mutationLimit,
22940
+ remaining: mutationsLeft,
22941
+ unlimited: budget.unlimited
22763
22942
  },
22764
22943
  scans: {
22944
+ source: "local-audit",
22765
22945
  used: m.totalScans,
22766
22946
  limit: tier ? scanLimit : null,
22767
22947
  remaining: tier ? scansLeft : null
22768
- }
22948
+ },
22949
+ localAudit: { mutations: m.mutationsApplied, scans: m.totalScans }
22769
22950
  },
22770
22951
  null,
22771
22952
  2
@@ -22774,29 +22955,39 @@ function creditsCommand() {
22774
22955
  return;
22775
22956
  }
22776
22957
  console.log(chalk21.cyan("\n Pretense Credits"));
22777
- console.log(chalk21.dim(` Plan: ${tierLabel(tier)} | Resets: ${resetCadenceLabel()}
22778
- `));
22958
+ console.log(
22959
+ chalk21.dim(` Plan: ${tierLabel(tier)} | Resets: ${resetLabel(resolution.quota)}
22960
+ `)
22961
+ );
22779
22962
  if (!tier) {
22780
22963
  for (const line of unverifiedNote(resolution.detail)) {
22781
22964
  console.log(chalk21.yellow(` ${line}`));
22782
22965
  }
22783
22966
  console.log();
22784
- console.log(" " + "Mutations used".padEnd(20) + m.mutationsApplied.toLocaleString("en-US"));
22967
+ console.log(" " + "Mutations used".padEnd(20) + budget.used.toLocaleString("en-US"));
22785
22968
  console.log(" " + "Requests used".padEnd(20) + m.totalScans.toLocaleString("en-US"));
22786
22969
  console.log();
22970
+ for (const line of budgetSourceLines(budget, resolution, m.mutationsApplied)) {
22971
+ console.log(chalk21.dim(` ${line}`));
22972
+ }
22973
+ console.log();
22787
22974
  return;
22788
22975
  }
22789
22976
  console.log(
22790
- " " + "Mutations".padEnd(14) + bar(m.mutationsApplied, mutationLimit) + " " + chalk21.bold(fmt(mutationsLeft)) + chalk21.dim(` left of ${fmt(mutationLimit)}`)
22977
+ " " + "Mutations".padEnd(14) + bar(budget.used, mutationLimit) + " " + chalk21.bold(fmt(mutationsLeft)) + chalk21.dim(` left of ${fmt(mutationLimit)}`)
22791
22978
  );
22792
22979
  console.log(
22793
22980
  " " + "Requests".padEnd(14) + bar(m.totalScans, scanLimit) + " " + chalk21.bold(fmt(scansLeft)) + chalk21.dim(` left of ${fmt(scanLimit)}`)
22794
22981
  );
22982
+ console.log();
22983
+ for (const line of budgetSourceLines(budget, resolution, m.mutationsApplied)) {
22984
+ console.log(chalk21.dim(` ${line}`));
22985
+ }
22795
22986
  if (tier !== "enterprise" && mutationLimit !== null && mutationsLeft === 0) {
22796
22987
  console.log(
22797
22988
  chalk21.red("\n Mutation budget exhausted for this period.") + chalk21.dim(" Run ") + chalk21.cyan("pretense upgrade") + chalk21.dim(" to compare plans.")
22798
22989
  );
22799
- } else if (tier !== "enterprise" && mutationLimit !== null && m.mutationsApplied >= mutationLimit * 0.8) {
22990
+ } else if (tier !== "enterprise" && mutationLimit !== null && budget.used >= mutationLimit * 0.8) {
22800
22991
  console.log(
22801
22992
  chalk21.yellow("\n Running low.") + chalk21.dim(" Run ") + chalk21.cyan("pretense upgrade") + chalk21.dim(" to compare plans.")
22802
22993
  );
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  PRETENSE_VERSION
4
- } from "./chunk-XYBJ63JG.js";
4
+ } from "./chunk-ZSQPYJVT.js";
5
5
  import {
6
6
  init_esm_shims
7
7
  } from "./chunk-TWMRHZGM.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pretense/cli",
3
- "version": "0.6.25",
3
+ "version": "0.6.26",
4
4
  "description": "Local-first AI firewall that mutates proprietary code before sending to LLM APIs",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,15 +23,15 @@
23
23
  "tsx": "^4.0.0",
24
24
  "typescript": "^5.4.0",
25
25
  "vitest": "^1.0.0",
26
- "@pretense/billing": "0.1.0",
27
- "@pretense/learner": "0.2.0",
28
26
  "@pretense/compliance-engine": "0.1.0",
27
+ "@pretense/protocol": "0.1.0",
28
+ "@pretense/learner": "0.2.0",
29
+ "@pretense/billing": "0.1.0",
29
30
  "@pretense/mutator": "0.2.0",
30
31
  "@pretense/proxy": "0.1.0",
31
32
  "@pretense/scanner": "0.2.0",
32
33
  "@pretense/scanner-rs": "0.2.0",
33
- "@pretense/store": "0.2.0",
34
- "@pretense/protocol": "0.1.0"
34
+ "@pretense/store": "0.2.0"
35
35
  },
36
36
  "publishConfig": {
37
37
  "access": "public",