@blockyfy/stg-cli 0.4.0 → 0.4.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/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { Command } from "commander";
5
5
  import chalk9 from "chalk";
6
6
  import {
7
7
  readFileSync as readFileSync7,
8
- existsSync as existsSync8,
8
+ existsSync as existsSync7,
9
9
  readdirSync,
10
10
  statSync,
11
11
  openSync,
@@ -13,7 +13,7 @@ import {
13
13
  closeSync
14
14
  } from "fs";
15
15
  import { readFile, stat as fsStat, open as fsOpen } from "fs/promises";
16
- import { resolve as resolve2, extname, join as join6, basename } from "path";
16
+ import { resolve as resolve2, extname, join as join5, basename } from "path";
17
17
  import os from "os";
18
18
 
19
19
  // src/types.ts
@@ -31,7 +31,7 @@ var DEFAULT_CONFIG = {
31
31
  { tokenType: "Property" /* Property */, prefix: "_prop" },
32
32
  { tokenType: "Method" /* Method */, prefix: "_fn" }
33
33
  ],
34
- storePath: `${process.env["HOME"] ?? "/tmp"}/.pretest`
34
+ storePath: `${process.env["HOME"] ?? "/tmp"}/.pretense`
35
35
  };
36
36
 
37
37
  // src/scanner.ts
@@ -866,50 +866,20 @@ function scan(code, language) {
866
866
  }
867
867
 
868
868
  // src/salt.ts
869
- import { readFileSync, writeFileSync, mkdirSync, existsSync as existsSync2, renameSync as renameSync2 } from "fs";
870
- import { join as join2 } from "path";
869
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
870
+ import { join } from "path";
871
871
  import { homedir } from "os";
872
872
  import { randomBytes } from "crypto";
873
-
874
- // src/config-dir.ts
875
- import { existsSync, renameSync } from "fs";
876
- import { join } from "path";
877
- var PROJECT_CONFIG_DIR_NAME = ".pretest";
878
- var LEGACY_PROJECT_CONFIG_DIR_NAME = ".pretense";
879
- function migrateLegacyProjectConfigDir(parentDir) {
880
- const next = join(parentDir, PROJECT_CONFIG_DIR_NAME);
881
- const prev = join(parentDir, LEGACY_PROJECT_CONFIG_DIR_NAME);
882
- if (existsSync(next)) return;
883
- if (!existsSync(prev)) return;
884
- try {
885
- renameSync(prev, next);
886
- } catch {
887
- }
888
- }
889
-
890
- // src/salt.ts
891
873
  var SALT_BYTES = 32;
892
874
  function getSaltPath() {
893
- const home = homedir();
894
- migrateLegacyProjectConfigDir(home);
895
- const dir = join2(home, PROJECT_CONFIG_DIR_NAME);
896
- const legacyDir = join2(home, LEGACY_PROJECT_CONFIG_DIR_NAME);
897
- const path = join2(dir, "mutation.salt");
898
- const legacySalt = join2(legacyDir, "mutation.salt");
899
- if (!existsSync2(path) && existsSync2(legacySalt)) {
900
- try {
901
- if (!existsSync2(dir)) mkdirSync(dir, { recursive: true });
902
- renameSync2(legacySalt, path);
903
- } catch {
904
- }
905
- }
906
- return { dir, path };
875
+ const dir = join(homedir(), ".pretense");
876
+ return { dir, path: join(dir, "mutation.salt") };
907
877
  }
908
878
  var _cachedSalt = null;
909
879
  function getMutationSalt() {
910
880
  if (_cachedSalt) return _cachedSalt;
911
881
  const { dir, path } = getSaltPath();
912
- if (existsSync2(path)) {
882
+ if (existsSync(path)) {
913
883
  try {
914
884
  const raw = readFileSync(path, "utf-8").trim();
915
885
  if (/^[0-9a-f]{64}$/i.test(raw)) {
@@ -931,12 +901,6 @@ function getMutationSalt() {
931
901
  function buildSaltedSeed(baseSeed) {
932
902
  return `${baseSeed}:${getMutationSalt()}`;
933
903
  }
934
- function effectiveSeedForMutation(userSeed) {
935
- if (userSeed === "pretense" || userSeed === "pretest") {
936
- return buildSaltedSeed("pretense");
937
- }
938
- return userSeed;
939
- }
940
904
 
941
905
  // src/deterministic-id.ts
942
906
  function hash32(str) {
@@ -980,7 +944,7 @@ function prefixForType(type) {
980
944
  return "_tok";
981
945
  }
982
946
  }
983
- function mutate(code, language, seed = "pretest") {
947
+ function mutate(code, language, seed = "pretense") {
984
948
  const startMs = performance.now();
985
949
  const lang = language ?? detectLanguage(code);
986
950
  if (!code || !code.trim()) {
@@ -991,7 +955,7 @@ function mutate(code, language, seed = "pretest") {
991
955
  stats: { tokensScanned: 0, tokensMutated: 0, durationMs: 0, language: lang }
992
956
  };
993
957
  }
994
- const effectiveSeed = effectiveSeedForMutation(seed);
958
+ const effectiveSeed = seed === "pretense" ? buildSaltedSeed(seed) : seed;
995
959
  const { tokens } = scan(code, lang);
996
960
  const map = /* @__PURE__ */ new Map();
997
961
  for (const token of tokens) {
@@ -1080,7 +1044,7 @@ function reverse(mutatedCode, map, secretsMap) {
1080
1044
  // src/secrets.ts
1081
1045
  var SECRET_PATTERNS = [
1082
1046
  { name: "anthropic-api-key", category: "secret", severity: "critical", defaultAction: "block", pattern: /sk-ant-api\d{2}-[A-Za-z0-9_-]{40,}/g },
1083
- /** Legacy `sk-…` and modern `sk-proj-…` (hyphenated body); aligned with upstream scanner heuristics */
1047
+ /** Legacy `sk-…` and modern `sk-proj-…` (hyphenated body); aligned with @pretense/scanner */
1084
1048
  { name: "openai-api-key", category: "secret", severity: "critical", defaultAction: "block", pattern: /sk-(?:proj-)?[A-Za-z0-9_-]{20,}/g },
1085
1049
  { name: "aws-access-key", category: "secret", severity: "critical", defaultAction: "block", pattern: /AKIA[0-9A-Z]{16}/g },
1086
1050
  /** `AWS_SECRET = '…40 chars…'` (not `AWS_SECRET_ACCESS_KEY`, which is covered below). */
@@ -1343,7 +1307,7 @@ function applyRedactionsTracked(text, matches, mutationSeed = buildSaltedSeed("p
1343
1307
  }
1344
1308
 
1345
1309
  // src/store.ts
1346
- import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync3 } from "fs";
1310
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "fs";
1347
1311
  import { dirname } from "path";
1348
1312
  var MutationStore = class {
1349
1313
  entries = /* @__PURE__ */ new Map();
@@ -1408,7 +1372,7 @@ var MutationStore = class {
1408
1372
  */
1409
1373
  persist() {
1410
1374
  const dir = dirname(this.filePath);
1411
- if (!existsSync3(dir)) {
1375
+ if (!existsSync2(dir)) {
1412
1376
  mkdirSync2(dir, { recursive: true });
1413
1377
  }
1414
1378
  const data = JSON.stringify([...this.entries.values()], null, 2);
@@ -1419,7 +1383,7 @@ var MutationStore = class {
1419
1383
  * No-ops if the file doesn't exist.
1420
1384
  */
1421
1385
  load() {
1422
- if (!existsSync3(this.filePath)) return;
1386
+ if (!existsSync2(this.filePath)) return;
1423
1387
  try {
1424
1388
  const raw = readFileSync2(this.filePath, "utf-8");
1425
1389
  const parsed = JSON.parse(raw);
@@ -1454,42 +1418,41 @@ var MutationStore = class {
1454
1418
  };
1455
1419
 
1456
1420
  // src/config.ts
1457
- import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
1458
- import { join as join3, resolve } from "path";
1421
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
1422
+ import { join as join2, resolve } from "path";
1459
1423
  import { createHmac } from "crypto";
1460
- var CONFIG_DIR_NAME = PROJECT_CONFIG_DIR_NAME;
1424
+ var CONFIG_DIR_NAME = ".pretense";
1461
1425
  var CONFIG_FILE = "config.json";
1462
1426
  var MUTATION_MAP_FILE = "mutation-map.json";
1463
1427
  var AUDIT_LOG_FILE = "audit.log";
1464
1428
  var USAGE_FILE = "usage.json";
1465
1429
  function getConfigDir(baseDir) {
1466
1430
  const base = baseDir ?? process.cwd();
1467
- migrateLegacyProjectConfigDir(base);
1468
1431
  return resolve(base, CONFIG_DIR_NAME);
1469
1432
  }
1470
1433
  function initConfig(dir) {
1471
1434
  const configDir = getConfigDir(dir);
1472
- if (!existsSync4(configDir)) {
1435
+ if (!existsSync3(configDir)) {
1473
1436
  mkdirSync3(configDir, { recursive: true });
1474
1437
  }
1475
- const configPath = join3(configDir, CONFIG_FILE);
1476
- if (!existsSync4(configPath)) {
1438
+ const configPath = join2(configDir, CONFIG_FILE);
1439
+ if (!existsSync3(configPath)) {
1477
1440
  const config = {
1478
1441
  ...DEFAULT_CONFIG,
1479
1442
  storePath: configDir
1480
1443
  };
1481
1444
  writeFileSync3(configPath, JSON.stringify(config, null, 2), "utf-8");
1482
1445
  }
1483
- const mapPath = join3(configDir, MUTATION_MAP_FILE);
1484
- if (!existsSync4(mapPath)) {
1446
+ const mapPath = join2(configDir, MUTATION_MAP_FILE);
1447
+ if (!existsSync3(mapPath)) {
1485
1448
  writeFileSync3(mapPath, "[]", "utf-8");
1486
1449
  }
1487
- const auditPath = join3(configDir, AUDIT_LOG_FILE);
1488
- if (!existsSync4(auditPath)) {
1450
+ const auditPath = join2(configDir, AUDIT_LOG_FILE);
1451
+ if (!existsSync3(auditPath)) {
1489
1452
  writeFileSync3(auditPath, "", "utf-8");
1490
1453
  }
1491
- const usagePath = join3(configDir, USAGE_FILE);
1492
- if (!existsSync4(usagePath)) {
1454
+ const usagePath = join2(configDir, USAGE_FILE);
1455
+ if (!existsSync3(usagePath)) {
1493
1456
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
1494
1457
  const month = today.slice(0, 7);
1495
1458
  const usageData = { month, mutations: 0, firstUseDate: today };
@@ -1503,8 +1466,8 @@ function initConfig(dir) {
1503
1466
  }
1504
1467
  function loadConfig(dir) {
1505
1468
  const configDir = getConfigDir(dir);
1506
- const configPath = join3(configDir, CONFIG_FILE);
1507
- if (!existsSync4(configPath)) {
1469
+ const configPath = join2(configDir, CONFIG_FILE);
1470
+ if (!existsSync3(configPath)) {
1508
1471
  return { ...DEFAULT_CONFIG };
1509
1472
  }
1510
1473
  try {
@@ -1517,7 +1480,7 @@ function loadConfig(dir) {
1517
1480
  }
1518
1481
  var USAGE_HMAC_SECRET = "pretense_usage_integrity_v1";
1519
1482
  function getUsageSecret() {
1520
- return process.env["PRETEST_USAGE_SECRET"]?.trim() || process.env["PRETENSE_USAGE_SECRET"]?.trim() || USAGE_HMAC_SECRET;
1483
+ return process.env["PRETENSE_USAGE_SECRET"] ?? USAGE_HMAC_SECRET;
1521
1484
  }
1522
1485
  function computeUsageChecksum(data) {
1523
1486
  const payload = JSON.stringify({ month: data.month, mutations: data.mutations, firstUseDate: data.firstUseDate });
@@ -1529,10 +1492,10 @@ function verifyUsageChecksum(data) {
1529
1492
  }
1530
1493
  function loadUsage(dir) {
1531
1494
  const configDir = getConfigDir(dir);
1532
- const usagePath = join3(configDir, USAGE_FILE);
1495
+ const usagePath = join2(configDir, USAGE_FILE);
1533
1496
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
1534
1497
  const currentMonth = today.slice(0, 7);
1535
- if (!existsSync4(usagePath)) {
1498
+ if (!existsSync3(usagePath)) {
1536
1499
  return { month: currentMonth, mutations: 0, firstUseDate: today };
1537
1500
  }
1538
1501
  try {
@@ -1543,7 +1506,7 @@ function loadUsage(dir) {
1543
1506
  return { month: currentMonth, mutations: 0, firstUseDate: data.firstUseDate ?? legacyDate };
1544
1507
  }
1545
1508
  if (!verifyUsageChecksum({ month: data.month, mutations: data.mutations, firstUseDate: data.firstUseDate, checksum: data.checksum })) {
1546
- process.stderr.write("[PRETEST] Warning: usage.json integrity check failed. Resetting usage counter.\n");
1509
+ process.stderr.write("[PRETENSE] Warning: usage.json integrity check failed. Resetting usage counter.\n");
1547
1510
  return { month: currentMonth, mutations: 0, firstUseDate: data.firstUseDate ?? today };
1548
1511
  }
1549
1512
  if (data.month !== currentMonth) {
@@ -1556,10 +1519,10 @@ function loadUsage(dir) {
1556
1519
  }
1557
1520
  function saveUsage(usage, dir) {
1558
1521
  const configDir = getConfigDir(dir);
1559
- if (!existsSync4(configDir)) {
1522
+ if (!existsSync3(configDir)) {
1560
1523
  mkdirSync3(configDir, { recursive: true });
1561
1524
  }
1562
- const usagePath = join3(configDir, USAGE_FILE);
1525
+ const usagePath = join2(configDir, USAGE_FILE);
1563
1526
  const checksum = computeUsageChecksum(usage);
1564
1527
  writeFileSync3(usagePath, JSON.stringify({ ...usage, checksum }, null, 2), "utf-8");
1565
1528
  }
@@ -1568,7 +1531,7 @@ var LICENSE_PAYLOAD_REGEX = /^[a-zA-Z0-9]+$/;
1568
1531
  function isValidLicenseKey(key, prefix) {
1569
1532
  if (key.length < MIN_LICENSE_KEY_LENGTH) return false;
1570
1533
  const afterPrefix = key.slice(prefix.length);
1571
- const hmacSecret = process.env["PRETEST_LICENSE_SECRET"]?.trim() || process.env["PRETENSE_LICENSE_SECRET"]?.trim();
1534
+ const hmacSecret = process.env["PRETENSE_LICENSE_SECRET"];
1572
1535
  if (hmacSecret) {
1573
1536
  const lastUnderscore = afterPrefix.lastIndexOf("_");
1574
1537
  if (lastUnderscore === -1) return false;
@@ -1582,7 +1545,7 @@ function isValidLicenseKey(key, prefix) {
1582
1545
  return LICENSE_PAYLOAD_REGEX.test(afterPrefix);
1583
1546
  }
1584
1547
  function detectTier() {
1585
- const key = process.env["PRETEST_LICENSE_KEY"]?.trim() || process.env["PRETENSE_LICENSE_KEY"]?.trim() || "";
1548
+ const key = process.env["PRETENSE_LICENSE_KEY"] ?? "";
1586
1549
  if (key.startsWith("pre_ent_") && isValidLicenseKey(key, "pre_ent_")) return "enterprise";
1587
1550
  if (key.startsWith("pre_pro_") && isValidLicenseKey(key, "pre_pro_")) return "pro";
1588
1551
  return "free";
@@ -1605,13 +1568,13 @@ function getTierLimits(tier) {
1605
1568
  }
1606
1569
 
1607
1570
  // src/audit.ts
1608
- import { appendFileSync, existsSync as existsSync5, readFileSync as readFileSync4, mkdirSync as mkdirSync4 } from "fs";
1609
- import { join as join4, dirname as dirname2 } from "path";
1571
+ import { appendFileSync, existsSync as existsSync4, readFileSync as readFileSync4, mkdirSync as mkdirSync4 } from "fs";
1572
+ import { join as join3, dirname as dirname2 } from "path";
1610
1573
  function writeAuditEntry(entry, dir) {
1611
1574
  const configDir = getConfigDir(dir);
1612
- const auditPath = join4(configDir, "audit.log");
1575
+ const auditPath = join3(configDir, "audit.log");
1613
1576
  const logDir = dirname2(auditPath);
1614
- if (!existsSync5(logDir)) {
1577
+ if (!existsSync4(logDir)) {
1615
1578
  mkdirSync4(logDir, { recursive: true });
1616
1579
  }
1617
1580
  const line = JSON.stringify(entry) + "\n";
@@ -1631,8 +1594,8 @@ function createAuditEntry(sessionId, file, identifiersMutated, secretsBlocked, l
1631
1594
  function readAuditLog(options = {}) {
1632
1595
  const { limit, dir } = options;
1633
1596
  const configDir = getConfigDir(dir);
1634
- const auditPath = join4(configDir, "audit.log");
1635
- if (!existsSync5(auditPath)) {
1597
+ const auditPath = join3(configDir, "audit.log");
1598
+ if (!existsSync4(auditPath)) {
1636
1599
  return [];
1637
1600
  }
1638
1601
  const raw = readFileSync4(auditPath, "utf-8");
@@ -1699,7 +1662,7 @@ import { Hono } from "hono";
1699
1662
  import { serve } from "@hono/node-server";
1700
1663
  import { nanoid } from "nanoid";
1701
1664
  import { createServer } from "net";
1702
- import { existsSync as existsSync7, watch } from "fs";
1665
+ import { existsSync as existsSync6, watch } from "fs";
1703
1666
 
1704
1667
  // src/auth.ts
1705
1668
  import { createHash } from "crypto";
@@ -1819,55 +1782,18 @@ async function collectGitContextCached(cwd = process.cwd(), now = Date.now()) {
1819
1782
  }
1820
1783
 
1821
1784
  // src/commands/login.ts
1822
- import { existsSync as existsSync6, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4, readFileSync as readFileSync5, chmodSync, readSync } from "fs";
1823
- import { join as join5 } from "path";
1785
+ import { existsSync as existsSync5, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4, readFileSync as readFileSync5, chmodSync, readSync } from "fs";
1786
+ import { join as join4 } from "path";
1824
1787
  import { homedir as homedir2 } from "os";
1825
1788
  import readline from "readline/promises";
1826
1789
  import chalk from "chalk";
1827
-
1828
- // src/dashboard-env.ts
1829
- var DASHBOARD_API_KEY_ENVS = ["PRETEST_API_KEY", "PRETENSE_API_KEY"];
1830
- var DASHBOARD_API_URL_ENVS = ["PRETEST_API_URL", "PRETENSE_API_URL"];
1831
- var DASHBOARD_NO_BANNER_ENVS = ["PRETEST_NO_BANNER", "PRETENSE_NO_BANNER"];
1832
- function firstNonEmptyEnv(names) {
1833
- for (const name of names) {
1834
- const v = process.env[name]?.trim();
1835
- if (v) return v;
1836
- }
1837
- return "";
1838
- }
1839
- function activeDashboardApiKeyEnvName() {
1840
- for (const name of DASHBOARD_API_KEY_ENVS) {
1841
- const v = process.env[name]?.trim();
1842
- if (v) return name;
1843
- }
1844
- return null;
1845
- }
1846
- function assignDashboardApiKeyToProcess(key) {
1847
- process.env["PRETEST_API_KEY"] = key;
1848
- process.env["PRETENSE_API_KEY"] = key;
1849
- }
1850
- function clearDashboardApiKeyFromProcess() {
1851
- delete process.env["PRETEST_API_KEY"];
1852
- delete process.env["PRETENSE_API_KEY"];
1853
- }
1854
- function hasDashboardApiKeyInEnv() {
1855
- return DASHBOARD_API_KEY_ENVS.some((n) => !!process.env[n]?.trim());
1856
- }
1857
-
1858
- // src/publish-info.ts
1859
- var PUBLISH_PACKAGE_URL = "https://www.npmjs.com/package/@blockyfy/stg-cli";
1860
-
1861
- // src/commands/login.ts
1862
- var CONFIG_DIR_NAME2 = PROJECT_CONFIG_DIR_NAME;
1790
+ var CONFIG_DIR_NAME2 = ".pretense";
1863
1791
  var CONFIG_FILE2 = "config.json";
1864
1792
  function getUserDashboardConfigDir() {
1865
- const home = homedir2();
1866
- migrateLegacyProjectConfigDir(home);
1867
- return join5(home, CONFIG_DIR_NAME2);
1793
+ return join4(homedir2(), CONFIG_DIR_NAME2);
1868
1794
  }
1869
1795
  function getUserDashboardConfigPath() {
1870
- return join5(getUserDashboardConfigDir(), CONFIG_FILE2);
1796
+ return join4(getUserDashboardConfigDir(), CONFIG_FILE2);
1871
1797
  }
1872
1798
  function isValidKeyShape(key) {
1873
1799
  const trimmed = key.trim();
@@ -1900,30 +1826,29 @@ function maskKey(key) {
1900
1826
  return `${trimmed.slice(0, 12)}${"\u2022".repeat(8)}${trimmed.slice(-4)}`;
1901
1827
  }
1902
1828
  function logDashboardCredentialHint() {
1903
- const envName = activeDashboardApiKeyEnvName();
1904
- const env = envName ? process.env[envName]?.trim() ?? "" : "";
1829
+ const env = process.env["PRETENSE_API_KEY"]?.trim() ?? "";
1905
1830
  const envOk = env.length > 0 && isValidKeyShape(env);
1906
1831
  const abs = getUserDashboardConfigPath();
1907
1832
  const fk = loadApiKey();
1908
- if (envOk && envName) {
1833
+ if (envOk) {
1909
1834
  console.error(
1910
1835
  chalk.gray(
1911
- `[pretest] Dashboard key source: ${envName} in environment (${maskKey(env)}) \u2014 unset this variable after logout if you expect no key.`
1836
+ `[pretense] Dashboard key source: PRETENSE_API_KEY in environment (${maskKey(env)}) \u2014 unset this variable after logout if you expect no key.`
1912
1837
  )
1913
1838
  );
1914
1839
  } else if (fk && isValidKeyShape(fk)) {
1915
- console.error(chalk.gray(`[pretest] Dashboard key source: ${abs} (${maskKey(fk)})`));
1840
+ console.error(chalk.gray(`[pretense] Dashboard key source: ${abs} (${maskKey(fk)})`));
1916
1841
  } else {
1917
- console.error(chalk.gray("[pretest] Dashboard key source: none configured."));
1842
+ console.error(chalk.gray("[pretense] Dashboard key source: none configured."));
1918
1843
  }
1919
1844
  }
1920
1845
  function saveApiKey(key, configDir = getUserDashboardConfigDir()) {
1921
- if (!existsSync6(configDir)) {
1846
+ if (!existsSync5(configDir)) {
1922
1847
  mkdirSync5(configDir, { recursive: true });
1923
1848
  }
1924
- const path = join5(configDir, CONFIG_FILE2);
1849
+ const path = join4(configDir, CONFIG_FILE2);
1925
1850
  let existing = {};
1926
- if (existsSync6(path)) {
1851
+ if (existsSync5(path)) {
1927
1852
  try {
1928
1853
  existing = JSON.parse(readFileSync5(path, "utf-8"));
1929
1854
  } catch {
@@ -1943,8 +1868,8 @@ function saveApiKey(key, configDir = getUserDashboardConfigDir()) {
1943
1868
  return path;
1944
1869
  }
1945
1870
  function removeSavedDashboardCredentials(configDir = getUserDashboardConfigDir()) {
1946
- const path = join5(configDir, CONFIG_FILE2);
1947
- if (!existsSync6(path)) return { removed: false, path };
1871
+ const path = join4(configDir, CONFIG_FILE2);
1872
+ if (!existsSync5(path)) return { removed: false, path };
1948
1873
  let existing = {};
1949
1874
  try {
1950
1875
  existing = JSON.parse(readFileSync5(path, "utf-8"));
@@ -1964,8 +1889,8 @@ function removeSavedDashboardCredentials(configDir = getUserDashboardConfigDir()
1964
1889
  return { removed: true, path };
1965
1890
  }
1966
1891
  function loadApiKey(configDir = getUserDashboardConfigDir()) {
1967
- const path = join5(configDir, CONFIG_FILE2);
1968
- if (!existsSync6(path)) return null;
1892
+ const path = join4(configDir, CONFIG_FILE2);
1893
+ if (!existsSync5(path)) return null;
1969
1894
  try {
1970
1895
  const raw = readFileSync5(path, "utf-8");
1971
1896
  const parsed = JSON.parse(raw);
@@ -1978,7 +1903,7 @@ function loadApiKey(configDir = getUserDashboardConfigDir()) {
1978
1903
  return null;
1979
1904
  }
1980
1905
  function resolveDashboardKeyCandidate() {
1981
- const env = firstNonEmptyEnv(DASHBOARD_API_KEY_ENVS);
1906
+ const env = (process.env["PRETENSE_API_KEY"] ?? "").trim();
1982
1907
  if (env.length > 0) {
1983
1908
  if (!isValidKeyShape(env)) {
1984
1909
  return { key: null, fromFile: false, badEnv: true };
@@ -1994,14 +1919,14 @@ function resolveDashboardKeyCandidate() {
1994
1919
  function installDashboardKeyForCurrentProcess(key) {
1995
1920
  const trimmed = key.trim();
1996
1921
  const path = saveApiKey(trimmed);
1997
- assignDashboardApiKeyToProcess(trimmed);
1922
+ process.env["PRETENSE_API_KEY"] = trimmed;
1998
1923
  return path;
1999
1924
  }
2000
1925
  async function promptDashboardApiKeyAfterFailure() {
2001
1926
  if (!process.stdin.isTTY || !process.stdout.isTTY) return null;
2002
1927
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
2003
1928
  try {
2004
- const line = (await rl.question(chalk.bold("Dashboard API key: "))).trim();
1929
+ const line = (await rl.question(chalk.bold("Pretense dashboard API key: "))).trim();
2005
1930
  return line.length > 0 ? line : null;
2006
1931
  } finally {
2007
1932
  rl.close();
@@ -2010,15 +1935,9 @@ async function promptDashboardApiKeyAfterFailure() {
2010
1935
  async function ensureDashboardKeyForStart() {
2011
1936
  const { key, fromFile, badEnv } = resolveDashboardKeyCandidate();
2012
1937
  if (badEnv) {
1938
+ console.error(chalk.red("Error: PRETENSE_API_KEY is set but is not a valid Pretense dashboard API key shape."));
2013
1939
  console.error(
2014
- chalk.red(
2015
- "Error: A dashboard API key is set in the environment but does not match the expected key shape."
2016
- )
2017
- );
2018
- console.error(
2019
- chalk.gray(
2020
- "Keys look like prtns_live_\u2026 or pk_live_\u2026. Fix the variable or unset it to use ~/.pretest/config.json."
2021
- )
1940
+ chalk.gray("Keys look like prtns_live_\u2026 or pk_live_\u2026. Fix the variable or unset it to use ~/.pretense/config.json.")
2022
1941
  );
2023
1942
  process.exit(1);
2024
1943
  }
@@ -2028,34 +1947,32 @@ async function ensureDashboardKeyForStart() {
2028
1947
  if (fromFile) {
2029
1948
  console.warn(
2030
1949
  chalk.yellow(
2031
- "Ignoring invalid `api_key` in ~/.pretest/config.json (wrong shape). Enter a new key or run `pretest login --key ...`."
1950
+ "Ignoring invalid `api_key` in ~/.pretense/config.json (wrong shape). Enter a new key or run `pretense login --key ...`."
2032
1951
  )
2033
1952
  );
2034
1953
  }
2035
1954
  const stdinOk = process.stdin.isTTY;
2036
1955
  const stdoutOk = process.stdout.isTTY;
2037
1956
  if (!stdinOk || !stdoutOk) {
2038
- console.error(chalk.red("Error: Dashboard API key required to start the proxy."));
1957
+ console.error(chalk.red("Error: Pretense API key required to start the proxy."));
2039
1958
  console.error(
2040
- chalk.gray("Save one with `pretest login --key prtns_live_...` or set PRETEST_API_KEY.")
1959
+ chalk.gray(
1960
+ "Save one with `pretense login --key prtns_live_...` or set PRETENSE_API_KEY."
1961
+ )
2041
1962
  );
2042
1963
  process.exit(1);
2043
1964
  }
2044
1965
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
2045
1966
  try {
2046
- console.log(
2047
- chalk.cyan(
2048
- "No dashboard API key found in ~/.pretest/config.json. Set PRETEST_API_KEY or run pretest login."
2049
- )
2050
- );
2051
- const entered = (await rl.question(chalk.bold("Enter your dashboard API key: "))).trim();
1967
+ console.log(chalk.cyan("No Pretense API key found in ~/.pretense/config.json or $PRETENSE_API_KEY."));
1968
+ const entered = (await rl.question(chalk.bold("Enter your Pretense API key: "))).trim();
2052
1969
  if (!entered) {
2053
1970
  console.error(chalk.red("No key entered; exiting."));
2054
1971
  process.exit(1);
2055
1972
  }
2056
1973
  if (!isValidKeyShape(entered)) {
2057
- console.error(chalk.red("That does not look like a dashboard API key (expect prtns_live_\u2026 or pk_live_\u2026)."));
2058
- console.error(chalk.gray(`Get a key via the package page, then run \`pretest login --key ...\`: ${PUBLISH_PACKAGE_URL}`));
1974
+ console.error(chalk.red("That does not look like a Pretense API key (expect prtns_live_\u2026 or pk_live_\u2026)."));
1975
+ console.error(chalk.gray("Get one from your Pretense dashboard, then run `pretense login --key ...`."));
2059
1976
  process.exit(1);
2060
1977
  }
2061
1978
  const path = installDashboardKeyForCurrentProcess(entered);
@@ -2066,29 +1983,29 @@ async function ensureDashboardKeyForStart() {
2066
1983
  }
2067
1984
  const persisted = resolveDashboardKeyCandidate();
2068
1985
  if (!persisted.key || persisted.badEnv) {
2069
- console.error(chalk.red("Error: Dashboard API key could not be confirmed after login prompt."));
1986
+ console.error(chalk.red("Error: Pretense dashboard API key could not be confirmed after login prompt."));
2070
1987
  process.exit(1);
2071
1988
  }
2072
1989
  }
2073
1990
  function runLogin(opts = {}) {
2074
- const candidate = opts.key?.trim() || firstNonEmptyEnv(DASHBOARD_API_KEY_ENVS) || readStdinIfPiped();
1991
+ const candidate = opts.key?.trim() || (process.env["PRETENSE_API_KEY"] ?? "").trim() || readStdinIfPiped();
2075
1992
  if (!candidate) {
2076
1993
  console.error(chalk.red("Error: no API key provided."));
2077
1994
  console.error(
2078
- chalk.gray("Try: pretest login --key pk_live_xxxxx")
1995
+ chalk.gray("Try: pretense login --key pk_live_xxxxx")
2079
1996
  );
2080
1997
  console.error(
2081
- chalk.gray(" or: echo $PRETEST_API_KEY | pretest login")
1998
+ chalk.gray(" or: echo $PRETENSE_API_KEY | pretense login")
2082
1999
  );
2083
2000
  return 1;
2084
2001
  }
2085
2002
  if (!isValidKeyShape(candidate)) {
2086
- console.error(chalk.red("Error: that does not look like a dashboard API key."));
2003
+ console.error(chalk.red("Error: that does not look like a Pretense API key."));
2087
2004
  console.error(
2088
2005
  chalk.gray("Keys start with prtns_live_ (or pk_live_) and are at least 24 characters long.")
2089
2006
  );
2090
2007
  console.error(
2091
- chalk.gray(`See: ${PUBLISH_PACKAGE_URL}`)
2008
+ chalk.gray("Get one at https://pretense.ai/dashboard/settings/api-keys")
2092
2009
  );
2093
2010
  return 1;
2094
2011
  }
@@ -2113,10 +2030,10 @@ function usageSummaryFromValidate(v) {
2113
2030
  keyStatus: "active"
2114
2031
  };
2115
2032
  }
2116
- var DEFAULT_PRETENSE_API_URL = "https://pretense-stg-api.nxtsen.com";
2033
+ var DEFAULT_PRETENSE_API_URL = "https://api.pretense.ai";
2117
2034
  var DEFAULT_REQUEST_TIMEOUT_MS = 15e3;
2118
2035
  function getConfiguredApiRoot(rootOverride) {
2119
- const raw = (rootOverride?.trim() || firstNonEmptyEnv(DASHBOARD_API_URL_ENVS) || DEFAULT_PRETENSE_API_URL).trim();
2036
+ const raw = (rootOverride ?? process.env["PRETENSE_API_URL"] ?? DEFAULT_PRETENSE_API_URL).trim();
2120
2037
  if (!raw) {
2121
2038
  return DEFAULT_PRETENSE_API_URL.replace(/\/$/, "");
2122
2039
  }
@@ -2126,7 +2043,7 @@ function getConfiguredApiRoot(rootOverride) {
2126
2043
  }
2127
2044
  try {
2128
2045
  const u = new URL(normalized);
2129
- const origin = /^pretense\.ai$/i.test(u.hostname) ? DEFAULT_PRETENSE_API_URL.replace(/\/$/, "") : u.origin;
2046
+ const origin = /^pretense\.ai$/i.test(u.hostname) ? "https://api.pretense.ai" : u.origin;
2130
2047
  const path = u.pathname === "/" ? "" : u.pathname.replace(/\/$/, "");
2131
2048
  return `${origin}${path}`;
2132
2049
  } catch {
@@ -2139,20 +2056,20 @@ function getCliApiUrl(pathWithinCli, rootOverride) {
2139
2056
  return `${root}/api/cli/${tail}`;
2140
2057
  }
2141
2058
  function getApiRequestTimeoutMs() {
2142
- const raw = process.env["PRETEST_API_TIMEOUT_MS"]?.trim() || process.env["PRETENSE_API_TIMEOUT_MS"]?.trim();
2059
+ const raw = process.env["PRETENSE_API_TIMEOUT_MS"]?.trim();
2143
2060
  if (!raw || !/^\d+$/.test(raw)) return DEFAULT_REQUEST_TIMEOUT_MS;
2144
2061
  const n = parseInt(raw, 10);
2145
2062
  return Math.min(Math.max(n, 3e3), 12e4);
2146
2063
  }
2147
2064
  function getApiKey() {
2148
- const fromEnv = firstNonEmptyEnv(DASHBOARD_API_KEY_ENVS);
2065
+ const fromEnv = process.env["PRETENSE_API_KEY"]?.trim();
2149
2066
  if (fromEnv) return fromEnv;
2150
2067
  const fromFile = loadApiKey();
2151
2068
  if (!fromFile) return null;
2152
2069
  const t = fromFile.trim();
2153
2070
  return t.length > 0 ? t : null;
2154
2071
  }
2155
- function getDashboardApiKey() {
2072
+ function getPretenseApiKey() {
2156
2073
  return getApiKey();
2157
2074
  }
2158
2075
  var cachedValidation = null;
@@ -2192,7 +2109,7 @@ async function validateKey(opts = {}) {
2192
2109
  const apiKey = getApiKey();
2193
2110
  if (!apiKey) {
2194
2111
  if (enforceReachability) {
2195
- const err = new Error("Missing dashboard API key");
2112
+ const err = new Error("Missing Pretense dashboard API key");
2196
2113
  err.code = "MISSING_API_KEY";
2197
2114
  cachedValidation = null;
2198
2115
  lastValidationSuccessAt = 0;
@@ -2222,7 +2139,7 @@ async function validateKey(opts = {}) {
2222
2139
  throw err;
2223
2140
  }
2224
2141
  if (!resp.ok) {
2225
- const msg = `Dashboard API returned HTTP ${resp.status} from ${validateUrl}`;
2142
+ const msg = `Pretense API returned HTTP ${resp.status} from ${validateUrl}`;
2226
2143
  if (enforceReachability) {
2227
2144
  cachedValidation = null;
2228
2145
  lastValidationSuccessAt = 0;
@@ -2259,14 +2176,14 @@ async function validateKey(opts = {}) {
2259
2176
  throw err;
2260
2177
  }
2261
2178
  if (enforceReachability) {
2262
- const msg = err.name === "AbortError" ? `Timed out after ${timeoutMs}ms reaching ${validateUrl} (raise PRETEST_API_TIMEOUT_MS or PRETENSE_API_TIMEOUT_MS)` : `Cannot reach dashboard API at ${validateUrl}: ${err.message}`;
2179
+ const msg = err.name === "AbortError" ? `Timed out after ${timeoutMs}ms reaching ${validateUrl} (raise PRETENSE_API_TIMEOUT_MS)` : `Cannot reach Pretense API at ${validateUrl}: ${err.message}`;
2263
2180
  cachedValidation = null;
2264
2181
  lastValidationSuccessAt = 0;
2265
2182
  throw makeBackendReachabilityError("BACKEND_UNAVAILABLE", msg);
2266
2183
  }
2267
2184
  if (opts.verbose) {
2268
2185
  process.stderr.write(
2269
- `[PRETEST] Backend validation failed: ${err.message}
2186
+ `[PRETENSE] Backend validation failed: ${err.message}
2270
2187
  `
2271
2188
  );
2272
2189
  }
@@ -2292,7 +2209,7 @@ async function fetchUsageSummary(opts = {}) {
2292
2209
  } catch (err) {
2293
2210
  if (opts.verbose) {
2294
2211
  process.stderr.write(
2295
- `[PRETEST] Usage summary fetch failed: ${err.message}
2212
+ `[PRETENSE] Usage summary fetch failed: ${err.message}
2296
2213
  `
2297
2214
  );
2298
2215
  }
@@ -2305,10 +2222,15 @@ async function isWithinLimits() {
2305
2222
  const v = getCachedValidation();
2306
2223
  if (!v) return { allowed: true };
2307
2224
  if (v.mutationsRemaining !== -1 && v.mutationsRemaining <= 0) {
2308
- return {
2309
- allowed: false,
2310
- reason: `Monthly mutation limit reached (${v.mutationsUsed}/${v.monthlyMutationLimit}). See ${PUBLISH_PACKAGE_URL}`
2311
- };
2225
+ const fresh = await validateKey({ force: true }).catch(() => null);
2226
+ const check = fresh ?? v;
2227
+ if (check.mutationsRemaining !== -1 && check.mutationsRemaining <= 0) {
2228
+ return {
2229
+ allowed: false,
2230
+ reason: `Monthly mutation limit reached (${check.mutationsUsed}/${check.monthlyMutationLimit}). Upgrade at https://pretense.ai/pricing`
2231
+ };
2232
+ }
2233
+ return { allowed: true };
2312
2234
  }
2313
2235
  return { allowed: true };
2314
2236
  }
@@ -2340,13 +2262,13 @@ async function uploadLog(event, options) {
2340
2262
  signal: controller.signal
2341
2263
  });
2342
2264
  if (!resp.ok && verbose) {
2343
- process.stderr.write(`[PRETEST] log upload HTTP ${resp.status}
2265
+ process.stderr.write(`[PRETENSE] log upload HTTP ${resp.status}
2344
2266
  `);
2345
2267
  }
2346
2268
  } catch (err) {
2347
2269
  if (verbose) {
2348
2270
  const msg = err instanceof Error ? err.message : String(err);
2349
- process.stderr.write(`[PRETEST] log upload failed: ${msg}
2271
+ process.stderr.write(`[PRETENSE] log upload failed: ${msg}
2350
2272
  `);
2351
2273
  }
2352
2274
  } finally {
@@ -2360,18 +2282,13 @@ function printStartClientInstructions(port) {
2360
2282
  const host = `http://localhost:${port}`;
2361
2283
  console.log();
2362
2284
  console.log(chalk2.cyan.bold("\u2500\u2500 Client setup (environment variables) \u2500\u2500"));
2363
- console.log(chalk2.gray("Point the CLI at the backend API (optional if using default):"));
2285
+ console.log(chalk2.gray("Point the CLI at the Pretense backend API (optional if using default):"));
2364
2286
  console.log(
2365
- chalk2.white(`export PRETEST_API_URL='https://pretense-stg-api.nxtsen.com'`)
2287
+ chalk2.white(`export PRETENSE_API_URL='https://api.pretense.ai'`)
2366
2288
  );
2367
2289
  console.log();
2368
- console.log(chalk2.gray("Log in with your dashboard API key:"));
2369
- console.log(chalk2.white("pretest login --key your-dashboard-api-key"));
2370
- console.log();
2371
- console.log(
2372
- chalk2.gray("Documentation:"),
2373
- chalk2.cyan.underline(PUBLISH_PACKAGE_URL)
2374
- );
2290
+ console.log(chalk2.gray("Log in with your Pretense dashboard API key:"));
2291
+ console.log(chalk2.white("pretense login --key your-pretense-api-key"));
2375
2292
  console.log();
2376
2293
  console.log(
2377
2294
  chalk2.gray("Set the LLM base URL for your provider (proxy below):")
@@ -2388,15 +2305,15 @@ function printStartClientInstructions(port) {
2388
2305
  console.log(chalk2.cyan.bold("\u2500\u2500 Stop & log out \u2500\u2500"));
2389
2306
  console.log(
2390
2307
  chalk2.gray(
2391
- "Stop the proxy: press Ctrl+C in the terminal where pretest start is running."
2308
+ "Stop the proxy: press Ctrl+C in the terminal where pretense start is running."
2392
2309
  )
2393
2310
  );
2394
2311
  console.log(
2395
2312
  chalk2.gray(
2396
- "Remove the saved dashboard key from ~/.pretest/config.json:"
2313
+ "Remove the saved Pretense dashboard key from ~/.pretense/config.json:"
2397
2314
  )
2398
2315
  );
2399
- console.log(chalk2.white("pretest logout"));
2316
+ console.log(chalk2.white("pretense logout"));
2400
2317
  console.log(
2401
2318
  chalk2.gray(
2402
2319
  "(confirm with y / cancel with n.) Mutations stop immediately unless this proxy was started with"
@@ -2404,7 +2321,7 @@ function printStartClientInstructions(port) {
2404
2321
  );
2405
2322
  console.log(
2406
2323
  chalk2.gray(
2407
- "PRETEST_API_KEY in that same terminal \u2014 then press Ctrl+C and run pretest start again."
2324
+ "PRETENSE_API_KEY set in that same terminal \u2014 then press Ctrl+C and run pretense start again."
2408
2325
  )
2409
2326
  );
2410
2327
  console.log();
@@ -2437,11 +2354,11 @@ function attachDashboardLogoutWatcher(enabled) {
2437
2354
  if (!fk) {
2438
2355
  if (dashboardSavedCredentialsRevoked) return;
2439
2356
  dashboardSavedCredentialsRevoked = true;
2440
- clearDashboardApiKeyFromProcess();
2357
+ delete process.env["PRETENSE_API_KEY"];
2441
2358
  clearValidationCache();
2442
2359
  try {
2443
2360
  process.stderr.write(
2444
- `\x1B[33m[PRETEST] Saved dashboard API key removed (~/.pretest/config.json, e.g. pretest logout). LLM proxy POST requests are disabled until you run pretest login and restart pretest start.\x1B[0m
2361
+ `\x1B[33m[PRETENSE] Saved dashboard API key removed (~/.pretense/config.json, e.g. pretense logout). LLM proxy POST requests are disabled until you run pretense login and restart pretense start.\x1B[0m
2445
2362
  `
2446
2363
  );
2447
2364
  } catch {
@@ -2458,7 +2375,7 @@ function attachDashboardLogoutWatcher(enabled) {
2458
2375
  debounceTimer = setTimeout(applyFilesystemCredentialState, 120);
2459
2376
  };
2460
2377
  try {
2461
- if (!existsSync7(dir)) return;
2378
+ if (!existsSync6(dir)) return;
2462
2379
  watch(dir, () => {
2463
2380
  schedule();
2464
2381
  });
@@ -2567,8 +2484,8 @@ function daysSinceFirstUse() {
2567
2484
  function printUpgradeNudge(reason) {
2568
2485
  process.stdout.write(
2569
2486
  `
2570
- \x1B[33m[PRETEST] ${reason}\x1B[0m
2571
- \x1B[33m[PRETEST] Upgrade to Pro: ${PUBLISH_PACKAGE_URL}\x1B[0m
2487
+ \x1B[33m[PRETENSE] ${reason}\x1B[0m
2488
+ \x1B[33m[PRETENSE] Upgrade to Pro: https://pretense.ai/pricing\x1B[0m
2572
2489
 
2573
2490
  `
2574
2491
  );
@@ -2582,7 +2499,7 @@ function createProxy(opts = {}) {
2582
2499
  app.get(
2583
2500
  "/",
2584
2501
  (c) => c.json({
2585
- name: "pretest",
2502
+ name: "pretense",
2586
2503
  version: getCliSemver(),
2587
2504
  status: "running",
2588
2505
  routes: {
@@ -2593,7 +2510,7 @@ function createProxy(opts = {}) {
2593
2510
  "POST /*": "Proxy to upstream LLM API (Anthropic, OpenAI, Google auto-detected)"
2594
2511
  },
2595
2512
  languages: ["TypeScript", "JavaScript", "Python", "Go", "Java", "C#", "Ruby", "Rust"],
2596
- docs: PUBLISH_PACKAGE_URL
2513
+ docs: "https://pretense.ai/docs"
2597
2514
  })
2598
2515
  );
2599
2516
  app.get(
@@ -2652,19 +2569,19 @@ function createProxy(opts = {}) {
2652
2569
  {
2653
2570
  error: {
2654
2571
  type: "pretense_session_logged_out",
2655
- message: "Saved dashboard credentials were removed (for example pretest logout). Run pretest login, then restart pretest start. If you started the proxy with a dashboard API key in this shell, stop it (Ctrl+C) and start again after logout."
2572
+ message: "Saved Pretense dashboard credentials were removed (for example pretense logout). Run pretense login, then restart pretense start. If you started the proxy with PRETENSE_API_KEY in this shell, stop it (Ctrl+C) and start again after logout."
2656
2573
  }
2657
2574
  },
2658
2575
  401
2659
2576
  );
2660
2577
  }
2661
- const dashboardApiKey = getDashboardApiKey();
2662
- if (!dashboardApiKey) {
2578
+ const pretenseDashboardKey = getPretenseApiKey();
2579
+ if (!pretenseDashboardKey) {
2663
2580
  return c.json(
2664
2581
  {
2665
2582
  error: {
2666
2583
  type: "pretense_dashboard_key_required",
2667
- message: "Configure your dashboard API key: run `pretest login --key prtns_live_...` or set PRETEST_API_KEY."
2584
+ message: "Configure your Pretense dashboard API key: run `pretense login --key prtns_live_...` or set PRETENSE_API_KEY."
2668
2585
  }
2669
2586
  },
2670
2587
  401
@@ -2717,7 +2634,7 @@ function createProxy(opts = {}) {
2717
2634
  {
2718
2635
  error: {
2719
2636
  type: "pretense_rate_limit",
2720
- message: `Monthly mutation limit reached (${monthlyMutations}/month). Upgrade to Pro for unlimited: ${PUBLISH_PACKAGE_URL}`
2637
+ message: `Monthly mutation limit reached (${monthlyMutations}/month). Upgrade to Pro for unlimited: https://pretense.ai/pricing`
2721
2638
  }
2722
2639
  },
2723
2640
  429
@@ -2741,7 +2658,7 @@ function createProxy(opts = {}) {
2741
2658
  {
2742
2659
  error: {
2743
2660
  type: "pretense_forbidden",
2744
- message: "This API key is read-only. Create a read_write key in the dashboard to use the Pretest proxy."
2661
+ message: "This API key is read-only. Create a read_write key in the dashboard to use the Pretense proxy."
2745
2662
  }
2746
2663
  },
2747
2664
  403
@@ -2797,7 +2714,7 @@ function createProxy(opts = {}) {
2797
2714
  usage.mutations += tokensMutated;
2798
2715
  saveUsage(usage);
2799
2716
  const remoteLogDisabled = process.env["PRETENSE_DISABLE_REMOTE_LOG"] === "1";
2800
- if (dashboardApiKey && !remoteLogDisabled) {
2717
+ if (pretenseDashboardKey && !remoteLogDisabled) {
2801
2718
  void uploadLog(
2802
2719
  {
2803
2720
  file_count: 0,
@@ -2806,7 +2723,7 @@ function createProxy(opts = {}) {
2806
2723
  llm_provider: provider,
2807
2724
  cli_version: getCliSemver()
2808
2725
  },
2809
- { apiKey: dashboardApiKey, verbose }
2726
+ { apiKey: pretenseDashboardKey, verbose }
2810
2727
  );
2811
2728
  bumpCachedUsageAfterLog(tokensMutated);
2812
2729
  }
@@ -2815,7 +2732,7 @@ function createProxy(opts = {}) {
2815
2732
  printUpgradeNudge(`${usage.mutations}/${monthlyMutations} monthly mutations used. Running low!`);
2816
2733
  }
2817
2734
  if (tier === "free" && daysSinceFirstUse() >= 7) {
2818
- printUpgradeNudge("You've been using Pretest for 7+ days. Unlock Pro features: unlimited mutations, 90-day audit, Slack alerts.");
2735
+ printUpgradeNudge("You've been using Pretense for 7+ days. Unlock Pro features: unlimited mutations, 90-day audit, Slack alerts.");
2819
2736
  }
2820
2737
  const entry = {
2821
2738
  id: requestId,
@@ -2832,7 +2749,7 @@ function createProxy(opts = {}) {
2832
2749
  createAuditEntry(requestId, "proxy-request", tokensMutated, blockedSecrets.length, provider, latencyMs)
2833
2750
  );
2834
2751
  if (verbose && tokensMutated > 0) {
2835
- process.stdout.write(`[PRETEST] ${tokensMutated} tokens mutated for request ${requestId}
2752
+ process.stdout.write(`[PRETENSE] ${tokensMutated} tokens mutated for request ${requestId}
2836
2753
  `);
2837
2754
  }
2838
2755
  const headers = {};
@@ -2959,12 +2876,12 @@ function startProxy(opts = {}) {
2959
2876
  const requestedPort = opts.port ?? opts.config?.port ?? DEFAULT_CONFIG.port;
2960
2877
  const app = createProxy(opts);
2961
2878
  void (async () => {
2962
- const dashboardKeyFromEnvAtLaunch = hasDashboardApiKeyInEnv();
2963
- const dashboardKey = getDashboardApiKey();
2879
+ const pretenseDashboardKeyFromEnvAtLaunch = !!process.env["PRETENSE_API_KEY"]?.trim();
2880
+ const dashboardKey = getPretenseApiKey();
2964
2881
  if (!dashboardKey || !isValidKeyShape(dashboardKey)) {
2965
2882
  process.stderr.write(
2966
- `\x1B[31m[PRETEST] API key required or invalid shape. Run \`pretest login --key prtns_live_...\`\x1B[0m
2967
- \x1B[31m[PRETEST] or set PRETEST_API_KEY. See ${PUBLISH_PACKAGE_URL}\x1B[0m
2883
+ `\x1B[31m[PRETENSE] API key required or invalid shape. Run \`pretense login --key prtns_live_...\`\x1B[0m
2884
+ \x1B[31m[PRETENSE] or set PRETENSE_API_KEY. Get a key at https://pretense.ai/dashboard/settings/api-keys\x1B[0m
2968
2885
  `
2969
2886
  );
2970
2887
  process.exit(1);
@@ -2979,7 +2896,7 @@ function startProxy(opts = {}) {
2979
2896
  });
2980
2897
  if (!validation) {
2981
2898
  process.stderr.write(
2982
- `\x1B[31m[PRETEST] Startup validation failed (no API key or unreachable backend). Cannot start proxy.\x1B[0m
2899
+ `\x1B[31m[PRETENSE] Startup validation failed (no API key or unreachable backend). Cannot start proxy.\x1B[0m
2983
2900
  `
2984
2901
  );
2985
2902
  process.exit(1);
@@ -2987,7 +2904,7 @@ function startProxy(opts = {}) {
2987
2904
  const plan = validation.plan ?? "FREE";
2988
2905
  const remaining = validation.mutationsRemaining === -1 ? "unlimited" : String(validation.mutationsRemaining);
2989
2906
  process.stdout.write(
2990
- `\x1B[32m[PRETEST] Key validated: ${plan} plan` + (validation.organizationName ? ` (${validation.organizationName})` : "") + ` \u2014 ${remaining} mutations remaining\x1B[0m
2907
+ `\x1B[32m[PRETENSE] Key validated: ${plan} plan` + (validation.organizationName ? ` (${validation.organizationName})` : "") + ` \u2014 ${remaining} mutations remaining\x1B[0m
2991
2908
  `
2992
2909
  );
2993
2910
  break;
@@ -2995,62 +2912,62 @@ function startProxy(opts = {}) {
2995
2912
  const code = err.code;
2996
2913
  const msg = err.message;
2997
2914
  if (code === "BACKEND_UNAVAILABLE" || code === "AUTH_BACKEND_REJECTED") {
2998
- process.stderr.write(`\x1B[31m[PRETEST] ${msg}\x1B[0m
2915
+ process.stderr.write(`\x1B[31m[PRETENSE] ${msg}\x1B[0m
2999
2916
  `);
3000
- process.stderr.write(`\x1B[31m[PRETEST] Fix network or set PRETEST_API_URL (or PRETENSE_API_URL) if using a custom API.\x1B[0m
2917
+ process.stderr.write(`\x1B[31m[PRETENSE] Fix network or set PRETENSE_API_URL if using a custom API.\x1B[0m
3001
2918
  `);
3002
2919
  process.exit(1);
3003
2920
  }
3004
2921
  if (code === "ORG_INACTIVE") {
3005
- process.stderr.write(`\x1B[31m[PRETEST] ${msg}\x1B[0m
2922
+ process.stderr.write(`\x1B[31m[PRETENSE] ${msg}\x1B[0m
3006
2923
  `);
3007
- process.stderr.write(`\x1B[31m[PRETEST] Your organization is inactive; contact support.\x1B[0m
2924
+ process.stderr.write(`\x1B[31m[PRETENSE] Your organization is inactive; contact support.\x1B[0m
3008
2925
  `);
3009
2926
  process.exit(1);
3010
2927
  }
3011
2928
  const authRetryable = code === "INVALID_API_KEY" || code === "KEY_REVOKED" || code === "KEY_EXPIRED" || code === "AUTH_ERROR" || code === "MISSING_API_KEY";
3012
2929
  if (authRetryable && interactive) {
3013
- process.stderr.write(`\x1B[31m[PRETEST] ${msg}\x1B[0m
2930
+ process.stderr.write(`\x1B[31m[PRETENSE] ${msg}\x1B[0m
3014
2931
  `);
3015
2932
  process.stderr.write(
3016
- `\x1B[33m[PRETEST] Enter your dashboard API key and press Enter (Ctrl+C to quit).\x1B[0m
2933
+ `\x1B[33m[PRETENSE] Enter your Pretense dashboard API key and press Enter (Ctrl+C to quit).\x1B[0m
3017
2934
  `
3018
2935
  );
3019
2936
  let entered = null;
3020
2937
  for (; ; ) {
3021
2938
  entered = await promptDashboardApiKeyAfterFailure();
3022
2939
  if (!entered) {
3023
- process.stderr.write(`\x1B[31m[PRETEST] No key entered; exiting.\x1B[0m
2940
+ process.stderr.write(`\x1B[31m[PRETENSE] No key entered; exiting.\x1B[0m
3024
2941
  `);
3025
2942
  process.exit(1);
3026
2943
  }
3027
2944
  if (isValidKeyShape(entered)) break;
3028
2945
  process.stderr.write(
3029
- `\x1B[31m[PRETEST] That does not look like a dashboard key (expect prtns_live_\u2026 or pk_live_\u2026).\x1B[0m
2946
+ `\x1B[31m[PRETENSE] That does not look like a Pretense dashboard key (expect prtns_live_\u2026 or pk_live_\u2026).\x1B[0m
3030
2947
  `
3031
2948
  );
3032
2949
  }
3033
2950
  const savedPath = installDashboardKeyForCurrentProcess(entered);
3034
- process.stdout.write(`\x1B[32m[PRETEST] Saved API key to ${savedPath}\x1B[0m
2951
+ process.stdout.write(`\x1B[32m[PRETENSE] Saved API key to ${savedPath}\x1B[0m
3035
2952
  `);
3036
2953
  clearValidationCache();
3037
2954
  continue;
3038
2955
  }
3039
2956
  if (code === "KEY_REVOKED" || code === "KEY_EXPIRED" || code === "INVALID_API_KEY" || code === "AUTH_ERROR" || code === "MISSING_API_KEY") {
3040
- process.stderr.write(`\x1B[31m[PRETEST] ${msg}\x1B[0m
2957
+ process.stderr.write(`\x1B[31m[PRETENSE] ${msg}\x1B[0m
3041
2958
  `);
3042
- process.stderr.write(`\x1B[31m[PRETEST] Run 'pretest login --key <new-key>' to fix.\x1B[0m
2959
+ process.stderr.write(`\x1B[31m[PRETENSE] Run 'pretense login --key <new-key>' to fix.\x1B[0m
3043
2960
  `);
3044
2961
  process.exit(1);
3045
2962
  }
3046
- process.stderr.write(`\x1B[31m[PRETEST] ${msg}\x1B[0m
2963
+ process.stderr.write(`\x1B[31m[PRETENSE] ${msg}\x1B[0m
3047
2964
  `);
3048
- process.stderr.write(`\x1B[31m[PRETEST] Run 'pretest login --key <new-key>' or check connectivity.\x1B[0m
2965
+ process.stderr.write(`\x1B[31m[PRETENSE] Run 'pretense login --key <new-key>' or check connectivity.\x1B[0m
3049
2966
  `);
3050
2967
  process.exit(1);
3051
2968
  }
3052
2969
  }
3053
- attachDashboardLogoutWatcher(!dashboardKeyFromEnvAtLaunch);
2970
+ attachDashboardLogoutWatcher(!pretenseDashboardKeyFromEnvAtLaunch);
3054
2971
  const bannerTier = tierFromDashboardPlan(
3055
2972
  getCachedValidation()?.plan,
3056
2973
  detectTier()
@@ -3059,13 +2976,13 @@ function startProxy(opts = {}) {
3059
2976
  try {
3060
2977
  port = await findAvailablePort(requestedPort, 10);
3061
2978
  } catch (err) {
3062
- process.stderr.write(`\x1B[31m[PRETEST] ${err.message}\x1B[0m
2979
+ process.stderr.write(`\x1B[31m[PRETENSE] ${err.message}\x1B[0m
3063
2980
  `);
3064
2981
  process.exit(1);
3065
2982
  }
3066
2983
  if (port !== requestedPort) {
3067
2984
  process.stderr.write(
3068
- `\x1B[33m[PRETEST] Port ${requestedPort} in use, falling back to ${port}.\x1B[0m
2985
+ `\x1B[33m[PRETENSE] Port ${requestedPort} in use, falling back to ${port}.\x1B[0m
3069
2986
  `
3070
2987
  );
3071
2988
  }
@@ -3073,7 +2990,7 @@ function startProxy(opts = {}) {
3073
2990
  serve({ fetch: app.fetch, port }, () => {
3074
2991
  const portStr = String(port);
3075
2992
  process.stdout.write(`
3076
- \x1B[36mPretest v${getCliSemver()} [${bannerTier.toUpperCase()}]\x1B[0m
2993
+ \x1B[36mPretense v${getCliSemver()} [${bannerTier.toUpperCase()}]\x1B[0m
3077
2994
  Your code hits AI naked. We fix that.
3078
2995
 
3079
2996
  Proxy: http://localhost:${portStr}
@@ -3095,7 +3012,7 @@ function startProxy(opts = {}) {
3095
3012
  `);
3096
3013
  setInterval(() => {
3097
3014
  if (dashboardSavedCredentialsRevoked) return;
3098
- if (!getDashboardApiKey()) return;
3015
+ if (!getPretenseApiKey()) return;
3099
3016
  void validateKey({
3100
3017
  force: true,
3101
3018
  verbose: opts.verbose,
@@ -3151,13 +3068,13 @@ function printTokenFooter(filesScanned, mutationsMade) {
3151
3068
  if (tier === "free") {
3152
3069
  if (pct >= 80) {
3153
3070
  process.stderr.write(
3154
- chalk3.yellow(` \u26A0 Approaching free-tier limit. Upgrade: ${chalk3.bold("pretest upgrade")}
3071
+ chalk3.yellow(` \u26A0 Approaching free-tier limit. Upgrade: ${chalk3.bold("pretense upgrade")}
3155
3072
 
3156
3073
  `)
3157
3074
  );
3158
3075
  } else {
3159
3076
  process.stderr.write(
3160
- chalk3.gray(` Run ${chalk3.bold("pretest status")} for details, ${chalk3.bold("pretest upgrade")} to remove limits.
3077
+ chalk3.gray(` Run ${chalk3.bold("pretense status")} for details, ${chalk3.bold("pretense upgrade")} to remove limits.
3161
3078
 
3162
3079
  `)
3163
3080
  );
@@ -3169,19 +3086,19 @@ function printTokenFooter(filesScanned, mutationsMade) {
3169
3086
 
3170
3087
  // src/banner.ts
3171
3088
  import chalk4 from "chalk";
3172
- var BANNER_RAW = `\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 pretest
3089
+ var BANNER_RAW = `\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 pretense
3173
3090
  \u2588\u2588 \u2588\u2588
3174
3091
  \u2588\u2588 \u2588\u2588 Stop your code from
3175
3092
  \u2588\u2588 \u2588\u2588 leaking to any LLM.
3176
3093
  \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588
3177
- \u2588\u2588 @blockyfy/stg-cli
3094
+ \u2588\u2588 pretense.ai
3178
3095
  \u2588\u2588
3179
3096
  \u2588\u2588
3180
3097
  \u2588\u2588
3181
3098
  \u2588\u2588`;
3182
3099
  var ICE_BLUE = "#7DD3FC";
3183
3100
  function shouldPrint() {
3184
- if (DASHBOARD_NO_BANNER_ENVS.some((n) => process.env[n] === "1")) return false;
3101
+ if (process.env.PRETENSE_NO_BANNER === "1") return false;
3185
3102
  if (!process.stdout.isTTY) return false;
3186
3103
  if (process.env.CI) return false;
3187
3104
  return true;
@@ -3226,7 +3143,7 @@ async function runStatus() {
3226
3143
  const tierBadge2 = plan === "ENTERPRISE" ? chalk5.bgMagenta.white.bold(" ENTERPRISE ") : plan === "PRO" ? chalk5.bgBlue.white.bold(" PRO ") : chalk5.bgGray.white.bold(" FREE ");
3227
3144
  const lines2 = [];
3228
3145
  lines2.push("");
3229
- lines2.push(`${chalk5.cyan("Pretest")} ${chalk5.gray(`v${getCliSemver()}`)} ${tierBadge2} ${chalk5.green("(synced)")}`);
3146
+ lines2.push(`${chalk5.cyan("Pretense")} ${chalk5.gray(`v${getCliSemver()}`)} ${tierBadge2} ${chalk5.green("(synced)")}`);
3230
3147
  lines2.push("");
3231
3148
  lines2.push(` Plan: ${chalk5.bold(plan)}`);
3232
3149
  lines2.push(` Mutations: ${fmt2(remote.mutationsUsed)} / ${fmt2(remote.monthlyMutationLimit)} this month`);
@@ -3240,7 +3157,7 @@ async function runStatus() {
3240
3157
  }
3241
3158
  lines2.push("");
3242
3159
  if (plan === "FREE") {
3243
- lines2.push(` ${chalk5.gray("Upgrade:")} ${chalk5.bold("pretest upgrade")}`);
3160
+ lines2.push(` ${chalk5.gray("Upgrade:")} ${chalk5.bold("pretense upgrade")}`);
3244
3161
  lines2.push("");
3245
3162
  }
3246
3163
  process.stdout.write(lines2.join("\n") + "\n");
@@ -3253,7 +3170,7 @@ async function runStatus() {
3253
3170
  const tierBadge = tier === "enterprise" ? chalk5.bgMagenta.white.bold(" ENTERPRISE ") : tier === "pro" ? chalk5.bgBlue.white.bold(" PRO ") : chalk5.bgGray.white.bold(" FREE ");
3254
3171
  const lines = [];
3255
3172
  lines.push("");
3256
- lines.push(`${chalk5.cyan("Pretest")} ${chalk5.gray(`v${getCliSemver()}`)} ${tierBadge} ${chalk5.yellow("(offline)")}`);
3173
+ lines.push(`${chalk5.cyan("Pretense")} ${chalk5.gray(`v${getCliSemver()}`)} ${tierBadge} ${chalk5.yellow("(offline)")}`);
3257
3174
  lines.push("");
3258
3175
  lines.push(` Plan: ${chalk5.bold(PLAN_LABEL[tier])} ${chalk5.gray("(" + planLimits.pricePerMonth + ")")}`);
3259
3176
  lines.push(` Mutations: ${fmt2(usage.mutations)} / ${fmt2(planLimits.monthlyMutations)} this month`);
@@ -3262,8 +3179,8 @@ async function runStatus() {
3262
3179
  lines.push(` Audit log: ${Number.isFinite(tierLimits.auditRetentionDays) ? `${tierLimits.auditRetentionDays} days` : "unlimited"}`);
3263
3180
  lines.push("");
3264
3181
  if (tier === "free") {
3265
- lines.push(` ${chalk5.gray("Upgrade:")} ${chalk5.bold("pretest upgrade")}`);
3266
- lines.push(` ${chalk5.gray("Credits:")} ${chalk5.bold("pretest credits")}`);
3182
+ lines.push(` ${chalk5.gray("Upgrade:")} ${chalk5.bold("pretense upgrade")}`);
3183
+ lines.push(` ${chalk5.gray("Credits:")} ${chalk5.bold("pretense credits")}`);
3267
3184
  lines.push("");
3268
3185
  }
3269
3186
  process.stdout.write(lines.join("\n") + "\n");
@@ -3271,12 +3188,12 @@ async function runStatus() {
3271
3188
 
3272
3189
  // src/commands/upgrade.ts
3273
3190
  import chalk6 from "chalk";
3274
- var PRICING_URL = PUBLISH_PACKAGE_URL;
3191
+ var PRICING_URL = "https://pretense.ai/pricing";
3275
3192
  function runUpgrade() {
3276
3193
  const tier = detectTier();
3277
3194
  const lines = [];
3278
3195
  lines.push("");
3279
- lines.push(chalk6.cyan.bold(" Pretest Plans"));
3196
+ lines.push(chalk6.cyan.bold(" Pretense Plans"));
3280
3197
  lines.push("");
3281
3198
  lines.push(chalk6.gray(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
3282
3199
  lines.push(chalk6.gray(" \u2502 \u2502 Free \u2502 Pro \u2502 Enterprise \u2502"));
@@ -3295,7 +3212,7 @@ function runUpgrade() {
3295
3212
  lines.push(` ${chalk6.gray("Upgrade at:")} ${chalk6.cyan.underline(PRICING_URL)}`);
3296
3213
  lines.push("");
3297
3214
  lines.push(chalk6.gray(" After purchase, set:"));
3298
- lines.push(chalk6.gray(" export PRETEST_LICENSE_KEY=pre_pro_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
3215
+ lines.push(chalk6.gray(" export PRETENSE_LICENSE_KEY=pre_pro_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
3299
3216
  lines.push("");
3300
3217
  process.stdout.write(lines.join("\n") + "\n");
3301
3218
  }
@@ -3334,7 +3251,7 @@ async function runCredits() {
3334
3251
  const pct2 = cap2 > 0 && cap2 !== -1 ? Math.round(used2 / cap2 * 100) : 0;
3335
3252
  const lines2 = [];
3336
3253
  lines2.push("");
3337
- lines2.push(chalk7.cyan.bold(" Pretest Credits") + " " + chalk7.green("(synced)"));
3254
+ lines2.push(chalk7.cyan.bold(" Pretense Credits") + " " + chalk7.green("(synced)"));
3338
3255
  lines2.push("");
3339
3256
  lines2.push(` Plan: ${chalk7.bold(remote.plan)}`);
3340
3257
  lines2.push(` Resets: ${new Date(remote.periodResetsAt).toLocaleDateString()}`);
@@ -3344,10 +3261,10 @@ async function runCredits() {
3344
3261
  lines2.push(` Remaining: ${fmt3(remaining2)}`);
3345
3262
  lines2.push("");
3346
3263
  if (remote.plan === "FREE" && cap2 !== -1 && used2 >= cap2 * 0.8) {
3347
- lines2.push(chalk7.yellow(" Warning: Approaching free-tier limit. Run 'pretest upgrade' for unlimited."));
3264
+ lines2.push(chalk7.yellow(" Warning: Approaching free-tier limit. Run 'pretense upgrade' for unlimited."));
3348
3265
  lines2.push("");
3349
3266
  } else if (remote.plan === "FREE") {
3350
- lines2.push(chalk7.gray(" Tip: Run 'pretest upgrade' to compare plans."));
3267
+ lines2.push(chalk7.gray(" Tip: Run 'pretense upgrade' to compare plans."));
3351
3268
  lines2.push("");
3352
3269
  }
3353
3270
  process.stdout.write(lines2.join("\n") + "\n");
@@ -3362,7 +3279,7 @@ async function runCredits() {
3362
3279
  const pct = Number.isFinite(cap) && cap > 0 ? Math.round(used / cap * 100) : 0;
3363
3280
  const lines = [];
3364
3281
  lines.push("");
3365
- lines.push(chalk7.cyan.bold(" Pretest Credits") + " " + chalk7.yellow("(offline)"));
3282
+ lines.push(chalk7.cyan.bold(" Pretense Credits") + " " + chalk7.yellow("(offline)"));
3366
3283
  lines.push("");
3367
3284
  lines.push(` Plan: ${chalk7.bold(PLAN_LABEL2[tier])}`);
3368
3285
  lines.push(` Month: ${usage.month}`);
@@ -3372,10 +3289,10 @@ async function runCredits() {
3372
3289
  lines.push(` Remaining: ${fmt3(remaining)}`);
3373
3290
  lines.push("");
3374
3291
  if (tier === "free" && Number.isFinite(cap) && used >= cap * 0.8) {
3375
- lines.push(chalk7.yellow(" Warning: Approaching free-tier limit. Run 'pretest upgrade' for unlimited."));
3292
+ lines.push(chalk7.yellow(" Warning: Approaching free-tier limit. Run 'pretense upgrade' for unlimited."));
3376
3293
  lines.push("");
3377
3294
  } else if (tier === "free") {
3378
- lines.push(chalk7.gray(" Tip: Run 'pretest upgrade' to compare plans."));
3295
+ lines.push(chalk7.gray(" Tip: Run 'pretense upgrade' to compare plans."));
3379
3296
  lines.push("");
3380
3297
  }
3381
3298
  process.stdout.write(lines.join("\n") + "\n");
@@ -3386,16 +3303,14 @@ import readline2 from "readline/promises";
3386
3303
  import chalk8 from "chalk";
3387
3304
  async function runLogout(opts = {}) {
3388
3305
  if (!loadApiKey()) {
3389
- console.log(chalk8.gray("No saved dashboard API key in ~/.pretest/config.json."));
3390
- console.log(
3391
- chalk8.gray("If you use PRETEST_API_KEY in your shell, run unset PRETEST_API_KEY.")
3392
- );
3306
+ console.log(chalk8.gray("No saved Pretense dashboard API key in ~/.pretense/config.json."));
3307
+ console.log(chalk8.gray("If you use PRETENSE_API_KEY in your shell, run unset PRETENSE_API_KEY."));
3393
3308
  return 0;
3394
3309
  }
3395
3310
  if (!opts.assumeYes) {
3396
3311
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
3397
3312
  console.error(chalk8.red("Error: confirmation requires an interactive terminal."));
3398
- console.error(chalk8.gray("Run `pretest logout --yes` to skip the prompt."));
3313
+ console.error(chalk8.gray("Run `pretense logout --yes` to skip the prompt."));
3399
3314
  return 1;
3400
3315
  }
3401
3316
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
@@ -3412,19 +3327,17 @@ async function runLogout(opts = {}) {
3412
3327
  rl.close();
3413
3328
  }
3414
3329
  }
3415
- const hadEnvDashboardKey = hasDashboardApiKeyInEnv();
3330
+ const hadEnvDashboardKey = !!process.env["PRETENSE_API_KEY"]?.trim();
3416
3331
  const { removed, path } = removeSavedDashboardCredentials();
3417
3332
  clearValidationCache();
3418
- clearDashboardApiKeyFromProcess();
3333
+ delete process.env["PRETENSE_API_KEY"];
3419
3334
  if (removed) {
3420
3335
  console.log(chalk8.green("Logged out. Removed saved API key from"), chalk8.bold(path));
3421
- console.log(
3422
- chalk8.gray("Other terminals: run unset PRETEST_API_KEY if that variable is still exported (e.g. in ~/.zshrc).")
3423
- );
3336
+ console.log(chalk8.gray("Other terminals: run unset PRETENSE_API_KEY if that variable is still exported (e.g. in ~/.zshrc)."));
3424
3337
  if (hadEnvDashboardKey) {
3425
3338
  console.log(
3426
3339
  chalk8.yellow(
3427
- "This shell had a dashboard key in the environment; it was cleared for this process only. Restart any running pretest proxy (Ctrl+C, then pretest start)."
3340
+ "This shell had PRETENSE_API_KEY set; it was cleared for this process only. Restart any running pretense proxy (Ctrl+C, then pretense start)."
3428
3341
  )
3429
3342
  );
3430
3343
  }
@@ -3437,7 +3350,7 @@ async function runLogout(opts = {}) {
3437
3350
  const major = parseInt(process.versions.node.split(".")[0], 10);
3438
3351
  if (Number.isNaN(major) || major < 18) {
3439
3352
  process.stderr.write(
3440
- `pretest requires Node.js 18 or newer (you have v${process.versions.node}).
3353
+ `pretense requires Node.js 18 or newer (you have v${process.versions.node}).
3441
3354
  `
3442
3355
  );
3443
3356
  process.stderr.write(`Upgrade via nvm: nvm install 20 && nvm use 20
@@ -3569,7 +3482,7 @@ function validateLanguage(lang) {
3569
3482
  }
3570
3483
  function collectFiles(target) {
3571
3484
  const abs = resolve2(target);
3572
- if (!existsSync8(abs)) {
3485
+ if (!existsSync7(abs)) {
3573
3486
  return [];
3574
3487
  }
3575
3488
  const stat = statSync(abs);
@@ -3587,14 +3500,13 @@ function collectFiles(target) {
3587
3500
  ".git",
3588
3501
  "dist",
3589
3502
  "build",
3590
- ".pretest",
3591
3503
  ".pretense",
3592
3504
  ".next",
3593
3505
  "__pycache__",
3594
3506
  ".Trash"
3595
3507
  ]);
3596
3508
  for (const entry of entries) {
3597
- const fullPath = join6(dir, entry.name);
3509
+ const fullPath = join5(dir, entry.name);
3598
3510
  if (entry.isDirectory()) {
3599
3511
  if (skipDirs.has(entry.name)) continue;
3600
3512
  walk(fullPath);
@@ -3607,12 +3519,12 @@ function collectFiles(target) {
3607
3519
  return files;
3608
3520
  }
3609
3521
  var program = new Command();
3610
- program.name("pretest").description("AI firewall CLI \u2014 mutates proprietary code before LLM API calls").version(VERSION).hook("preAction", () => {
3522
+ program.name("pretense").description("AI firewall CLI \u2014 mutates proprietary code before LLM API calls").version(VERSION).hook("preAction", () => {
3611
3523
  printBanner();
3612
3524
  });
3613
- program.command("init").description("Initialize .pretest/ config in current directory").option("-d, --dir <path>", "Target directory", process.cwd()).action((opts) => {
3525
+ program.command("init").description("Initialize .pretense/ config in current directory").option("-d, --dir <path>", "Target directory", process.cwd()).action((opts) => {
3614
3526
  const dir = resolve2(opts.dir);
3615
- console.log(chalk9.cyan("Initializing Pretest in"), chalk9.bold(dir));
3527
+ console.log(chalk9.cyan("Initializing Pretense in"), chalk9.bold(dir));
3616
3528
  const configDir = initConfig(dir);
3617
3529
  const files = collectFiles(dir);
3618
3530
  const langCounts = {};
@@ -3620,16 +3532,16 @@ program.command("init").description("Initialize .pretest/ config in current dire
3620
3532
  const lang = langFromExt(f);
3621
3533
  langCounts[lang] = (langCounts[lang] ?? 0) + 1;
3622
3534
  }
3623
- console.log(chalk9.green("\n .pretest/ created at"), chalk9.bold(configDir));
3535
+ console.log(chalk9.green("\n .pretense/ created at"), chalk9.bold(configDir));
3624
3536
  console.log(chalk9.gray(`
3625
3537
  Scanned ${files.length} source files:`));
3626
3538
  for (const [lang, count] of Object.entries(langCounts)) {
3627
3539
  console.log(chalk9.gray(` ${lang}: ${count} files`));
3628
3540
  }
3629
- console.log(chalk9.cyan("\n Next: run"), chalk9.bold("pretest start"), chalk9.cyan("to launch the proxy"));
3541
+ console.log(chalk9.cyan("\n Next: run"), chalk9.bold("pretense start"), chalk9.cyan("to launch the proxy"));
3630
3542
  console.log();
3631
3543
  });
3632
- program.command("start").description("Start the Pretest proxy server").option("-p, --port <number>", "Port number", "9339").option("-v, --verbose", "Enable verbose logging", false).action(async (opts) => {
3544
+ program.command("start").description("Start the Pretense proxy server").option("-p, --port <number>", "Port number", "9339").option("-v, --verbose", "Enable verbose logging", false).action(async (opts) => {
3633
3545
  const config = loadConfig();
3634
3546
  const port = validatePort(opts.port);
3635
3547
  if (port === null) {
@@ -3748,7 +3660,7 @@ function parseSizeOption(value) {
3748
3660
  }
3749
3661
  program.command("scan <target>").description("Scan file or directory for identifiers and secrets (no mutation)").option("--secrets-only", "Only scan for secrets/credentials", false).option("--json", "Output as JSON", false).option("--max-file-size <size>", "Skip files larger than this (e.g. 10mb, 500k)", "10mb").option("--concurrency <n>", "Max files scanned in parallel", String(SCAN_CONCURRENCY)).option("--quiet", "Suppress progress output", false).action(async (target, opts) => {
3750
3662
  const absTarget = resolve2(target);
3751
- if (!existsSync8(absTarget)) {
3663
+ if (!existsSync7(absTarget)) {
3752
3664
  console.error(chalk9.red("Error: Path not found:"), chalk9.bold(absTarget));
3753
3665
  process.exit(1);
3754
3666
  }
@@ -3796,7 +3708,7 @@ program.command("scan <target>").description("Scan file or directory for identif
3796
3708
  interrupted
3797
3709
  }, null, 2));
3798
3710
  } else {
3799
- console.log(chalk9.cyan("\nPretest Scan Results\n"));
3711
+ console.log(chalk9.cyan("\nPretense Scan Results\n"));
3800
3712
  for (const r of allResults) {
3801
3713
  if (r.skipped) {
3802
3714
  if (r.skipped === "too-large") {
@@ -3837,9 +3749,9 @@ program.command("scan <target>").description("Scan file or directory for identif
3837
3749
  process.exit(2);
3838
3750
  }
3839
3751
  });
3840
- program.command("mutate <file>").description("Mutate identifiers for stdout (scanner redacts secrets/PII in the source first)").option("-s, --seed <seed>", "Mutation seed", "pretest").option("-l, --language <lang>", "Source language (typescript, javascript, python, go, java, csharp, ruby, rust)").option("--save", "Save mutation map to .pretest/", false).option("--json", "Output as JSON (includes map + stats)", false).action((file, opts) => {
3752
+ program.command("mutate <file>").description("Mutate identifiers for stdout (scanner redacts secrets/PII in the source first)").option("-s, --seed <seed>", "Mutation seed", "pretense").option("-l, --language <lang>", "Source language (typescript, javascript, python, go, java, csharp, ruby, rust)").option("--save", "Save mutation map to .pretense/", false).option("--json", "Output as JSON (includes map + stats)", false).action((file, opts) => {
3841
3753
  const absPath = resolve2(file);
3842
- if (!existsSync8(absPath)) {
3754
+ if (!existsSync7(absPath)) {
3843
3755
  console.error(chalk9.red("Error: File not found:"), chalk9.bold(absPath));
3844
3756
  process.exit(1);
3845
3757
  }
@@ -3859,13 +3771,13 @@ program.command("mutate <file>").description("Mutate identifiers for stdout (sca
3859
3771
  const code = readFileSync7(absPath, "utf-8");
3860
3772
  const lang = opts.language ? validateLanguage(opts.language) : langFromExt(absPath);
3861
3773
  const secretScan = scan2(code);
3862
- const effectiveSeed = effectiveSeedForMutation(opts.seed);
3774
+ const effectiveSeed = opts.seed === "pretense" ? buildSaltedSeed(opts.seed) : opts.seed;
3863
3775
  const { redactedCode: redacted, secretsMap } = applyRedactionsTracked(code, secretScan.matches, effectiveSeed);
3864
3776
  const secretsRedacted = secretsMap.size;
3865
3777
  const result = mutate(redacted, lang, opts.seed);
3866
3778
  if (opts.save) {
3867
3779
  const configDir = getConfigDir();
3868
- const store = new MutationStore(join6(configDir, "mutation-map.json"));
3780
+ const store = new MutationStore(join5(configDir, "mutation-map.json"));
3869
3781
  store.load();
3870
3782
  store.save({
3871
3783
  id: absPath,
@@ -3903,15 +3815,15 @@ program.command("mutate <file>").description("Mutate identifiers for stdout (sca
3903
3815
  });
3904
3816
  program.command("reverse <file>").description("Reverse mutations using stored map").option("-m, --map <path>", "Path to mutation map JSON file").action((file, opts) => {
3905
3817
  const absPath = resolve2(file);
3906
- if (!existsSync8(absPath)) {
3818
+ if (!existsSync7(absPath)) {
3907
3819
  console.error(chalk9.red("Error: File not found:"), chalk9.bold(absPath));
3908
3820
  process.exit(1);
3909
3821
  }
3910
3822
  const mutatedCode = readFileSync7(absPath, "utf-8");
3911
- const mapPath = opts.map ? resolve2(opts.map) : join6(getConfigDir(), "mutation-map.json");
3912
- if (!existsSync8(mapPath)) {
3823
+ const mapPath = opts.map ? resolve2(opts.map) : join5(getConfigDir(), "mutation-map.json");
3824
+ if (!existsSync7(mapPath)) {
3913
3825
  console.error(chalk9.red("Error: Mutation map not found:"), chalk9.bold(mapPath));
3914
- console.error(chalk9.gray("Run 'pretest mutate --save' first, or specify --map <path>"));
3826
+ console.error(chalk9.gray("Run 'pretense mutate --save' first, or specify --map <path>"));
3915
3827
  process.exit(1);
3916
3828
  }
3917
3829
  let store;
@@ -3920,13 +3832,13 @@ program.command("reverse <file>").description("Reverse mutations using stored ma
3920
3832
  store.load();
3921
3833
  } catch {
3922
3834
  console.error(chalk9.red("Error: Failed to load mutation map:"), chalk9.bold(mapPath));
3923
- console.error(chalk9.gray("The file may be corrupted. Run 'pretest mutate --save' to regenerate."));
3835
+ console.error(chalk9.gray("The file may be corrupted. Run 'pretense mutate --save' to regenerate."));
3924
3836
  process.exit(1);
3925
3837
  }
3926
3838
  const entry = store.get(absPath) ?? store.getByHash(absPath) ?? store.list(1)[0];
3927
3839
  if (!entry) {
3928
3840
  console.error(chalk9.red("Error: No mutation map entries found."));
3929
- console.error(chalk9.gray("Run 'pretest mutate --save <file>' first to generate a map."));
3841
+ console.error(chalk9.gray("Run 'pretense mutate --save <file>' first to generate a map."));
3930
3842
  process.exit(1);
3931
3843
  }
3932
3844
  const map = MutationStore.toMap(entry);
@@ -3946,16 +3858,16 @@ program.command("audit").description("View the audit log").option("--json", "Out
3946
3858
  const output = formatAudit(entries, format);
3947
3859
  console.log(output);
3948
3860
  });
3949
- program.command("version").description("Print Pretest CLI version").action(() => {
3950
- console.log(`@blockyfy/stg-cli v${VERSION}`);
3861
+ program.command("version").description("Print Pretense CLI version").action(() => {
3862
+ console.log(`@pretense/cli v${VERSION}`);
3951
3863
  });
3952
3864
  program.command("status").description("Show current plan, monthly quota, seat usage").action(async () => {
3953
3865
  await runStatus();
3954
3866
  });
3955
- program.command("usage").description("Alias for `pretest status` \u2014 show monthly quota usage").action(async () => {
3867
+ program.command("usage").description("Alias for `pretense status` \u2014 show monthly quota usage").action(async () => {
3956
3868
  await runStatus();
3957
3869
  });
3958
- program.command("tokens").description("Alias for `pretest credits` \u2014 show remaining mutation budget").action(async () => {
3870
+ program.command("tokens").description("Alias for `pretense credits` \u2014 show remaining mutation budget").action(async () => {
3959
3871
  await runCredits();
3960
3872
  });
3961
3873
  program.command("upgrade").description("Compare plans and upgrade to Pro or Enterprise").action(() => {
@@ -3964,11 +3876,11 @@ program.command("upgrade").description("Compare plans and upgrade to Pro or Ente
3964
3876
  program.command("credits").description("Show remaining mutation/scan budget for the current month").action(async () => {
3965
3877
  await runCredits();
3966
3878
  });
3967
- program.command("login").description("Save a dashboard API key to ~/.pretest/config.json for future CLI runs").option("-k, --key <key>", "API key (prtns_live_... or pk_live_...). If omitted, read from $PRETEST_API_KEY or stdin.").action((opts) => {
3879
+ program.command("login").description("Save a Pretense API key to ~/.pretense/config.json for future CLI runs").option("-k, --key <key>", "API key (prtns_live_... or pk_live_...). If omitted, read from $PRETENSE_API_KEY or stdin.").action((opts) => {
3968
3880
  const code = runLogin({ key: opts.key });
3969
3881
  if (code !== 0) process.exit(code);
3970
3882
  });
3971
- program.command("logout").description("Remove the saved dashboard API key from ~/.pretest/config.json").option("-y, --yes", "Skip confirmation prompt", false).action(async (opts) => {
3883
+ program.command("logout").description("Remove the saved Pretense dashboard API key from ~/.pretense/config.json").option("-y, --yes", "Skip confirmation prompt", false).action(async (opts) => {
3972
3884
  const code = await runLogout({ assumeYes: opts.yes === true });
3973
3885
  if (code !== 0) process.exit(code);
3974
3886
  });