@pretense/cli 0.3.0 → 0.3.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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/scanner.ts","../src/mutator.ts","../src/reverser.ts","../src/secrets.ts","../src/store.ts","../src/config.ts","../src/audit.ts","../src/proxy.ts"],"sourcesContent":["/**\n * Pretense CLI — Entry Point\n *\n * AI firewall CLI that mutates proprietary code identifiers before\n * sending to LLM APIs. Commands: init, start, scan, mutate, reverse, audit, version.\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { readFileSync, existsSync, readdirSync, statSync } from \"fs\";\nimport { resolve, extname, join } from \"path\";\nimport { scan, detectLanguage } from \"./scanner.js\";\nimport { mutate } from \"./mutator.js\";\nimport { reverse } from \"./reverser.js\";\nimport { scan as scanSecrets } from \"./secrets.js\";\nimport { MutationStore } from \"./store.js\";\nimport { initConfig, loadConfig, getConfigDir } from \"./config.js\";\nimport { readAuditLog, formatAudit } from \"./audit.js\";\nimport { startProxy } from \"./proxy.js\";\n\nconst VERSION = \"0.3.0\";\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction langFromExt(filePath: string): string {\n const ext = extname(filePath).toLowerCase();\n const map: Record<string, string> = {\n \".ts\": \"typescript\",\n \".tsx\": \"typescript\",\n \".js\": \"javascript\",\n \".jsx\": \"javascript\",\n \".mjs\": \"javascript\",\n \".cjs\": \"javascript\",\n \".py\": \"python\",\n \".go\": \"go\",\n \".java\": \"java\",\n };\n return map[ext] ?? \"typescript\";\n}\n\nfunction collectFiles(target: string): string[] {\n const abs = resolve(target);\n if (!existsSync(abs)) {\n return [];\n }\n const stat = statSync(abs);\n if (stat.isFile()) return [abs];\n\n const files: string[] = [];\n const supportedExts = new Set([\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\", \".py\", \".go\", \".java\"]);\n\n function walk(dir: string): void {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n // Skip common non-source dirs\n if ([\"node_modules\", \".git\", \"dist\", \"build\", \".pretense\", \".next\", \"__pycache__\"].includes(entry.name)) continue;\n walk(fullPath);\n } else if (entry.isFile() && supportedExts.has(extname(entry.name).toLowerCase())) {\n files.push(fullPath);\n }\n }\n }\n\n walk(abs);\n return files;\n}\n\n// ─── CLI ─────────────────────────────────────────────────────────────────────\n\nconst program = new Command();\n\nprogram\n .name(\"pretense\")\n .description(\"AI firewall CLI — mutates proprietary code before LLM API calls\")\n .version(VERSION);\n\n// ── init ──────────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"init\")\n .description(\"Initialize .pretense/ config in current directory\")\n .option(\"-d, --dir <path>\", \"Target directory\", process.cwd())\n .action((opts: { dir: string }) => {\n const dir = resolve(opts.dir);\n console.log(chalk.cyan(\"Initializing Pretense in\"), chalk.bold(dir));\n\n const configDir = initConfig(dir);\n\n // Scan for source files\n const files = collectFiles(dir);\n const langCounts: Record<string, number> = {};\n for (const f of files) {\n const lang = langFromExt(f);\n langCounts[lang] = (langCounts[lang] ?? 0) + 1;\n }\n\n console.log(chalk.green(\"\\n .pretense/ created at\"), chalk.bold(configDir));\n console.log(chalk.gray(`\\n Scanned ${files.length} source files:`));\n for (const [lang, count] of Object.entries(langCounts)) {\n console.log(chalk.gray(` ${lang}: ${count} files`));\n }\n console.log(chalk.cyan(\"\\n Next: run\"), chalk.bold(\"pretense start\"), chalk.cyan(\"to launch the proxy\"));\n console.log();\n });\n\n// ── start ─────────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"start\")\n .description(\"Start the Pretense proxy server\")\n .option(\"-p, --port <number>\", \"Port number\", \"9339\")\n .option(\"-v, --verbose\", \"Enable verbose logging\", false)\n .action((opts: { port: string; verbose: boolean }) => {\n const config = loadConfig();\n const port = parseInt(opts.port) || config.port;\n startProxy({ config, port, verbose: opts.verbose });\n });\n\n// ── scan ──────────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"scan <target>\")\n .description(\"Scan file or directory for identifiers and secrets (no mutation)\")\n .option(\"--secrets-only\", \"Only scan for secrets/credentials\", false)\n .option(\"--json\", \"Output as JSON\", false)\n .action((target: string, opts: { secretsOnly: boolean; json: boolean }) => {\n const files = collectFiles(target);\n if (files.length === 0) {\n console.error(chalk.red(\"No source files found at\"), chalk.bold(target));\n process.exit(1);\n }\n\n let totalIdentifiers = 0;\n let totalSecrets = 0;\n const allResults: Array<{ file: string; identifiers: number; secrets: number; secretTypes: string[] }> = [];\n\n for (const file of files) {\n const code = readFileSync(file, \"utf-8\");\n const lang = langFromExt(file);\n\n let identifiers = 0;\n if (!opts.secretsOnly) {\n const scanResult = scan(code, lang);\n identifiers = scanResult.tokens.length;\n totalIdentifiers += identifiers;\n }\n\n const secretResult = scanSecrets(code);\n const blocked = secretResult.matches.filter((m) => m.action === \"block\" || m.action === \"redact\");\n totalSecrets += blocked.length;\n\n allResults.push({\n file,\n identifiers,\n secrets: blocked.length,\n secretTypes: blocked.map((m) => m.type),\n });\n }\n\n if (opts.json) {\n console.log(JSON.stringify({ files: allResults, totalIdentifiers, totalSecrets }, null, 2));\n } else {\n console.log(chalk.cyan(\"\\nPretense Scan Results\\n\"));\n for (const r of allResults) {\n const secretBadge = r.secrets > 0\n ? chalk.red(` [${r.secrets} SECRET${r.secrets > 1 ? \"S\" : \"\"}]`)\n : \"\";\n console.log(\n chalk.gray(\" \") + chalk.white(r.file) + chalk.gray(` — ${r.identifiers} identifiers`) + secretBadge,\n );\n if (r.secrets > 0) {\n for (const t of r.secretTypes) {\n console.log(chalk.red(` ! ${t}`));\n }\n }\n }\n console.log(chalk.gray(`\\n Total: ${files.length} files, ${totalIdentifiers} identifiers, `) +\n (totalSecrets > 0 ? chalk.red(`${totalSecrets} secrets found`) : chalk.green(\"0 secrets\")));\n console.log();\n }\n\n // Exit code 2 if secrets found\n if (totalSecrets > 0) {\n process.exit(2);\n }\n });\n\n// ── mutate ────────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"mutate <file>\")\n .description(\"Mutate a file and print result to stdout\")\n .option(\"-s, --seed <seed>\", \"Mutation seed\", \"pretense\")\n .option(\"--save\", \"Save mutation map to .pretense/\", false)\n .option(\"--json\", \"Output as JSON (includes map + stats)\", false)\n .action((file: string, opts: { seed: string; save: boolean; json: boolean }) => {\n const absPath = resolve(file);\n if (!existsSync(absPath)) {\n console.error(chalk.red(\"File not found:\"), chalk.bold(absPath));\n process.exit(1);\n }\n\n const code = readFileSync(absPath, \"utf-8\");\n const lang = langFromExt(absPath);\n const result = mutate(code, lang, opts.seed);\n\n if (opts.save) {\n const configDir = getConfigDir();\n const store = new MutationStore(join(configDir, \"mutation-map.json\"));\n store.load();\n store.save({\n id: absPath,\n originalHash: absPath,\n mapEntries: MutationStore.fromMap(result.map),\n timestamp: Date.now(),\n language: lang,\n });\n store.persist();\n process.stderr.write(chalk.gray(`Mutation map saved to ${configDir}/mutation-map.json\\n`));\n }\n\n if (opts.json) {\n console.log(JSON.stringify({\n mutatedCode: result.mutatedCode,\n map: Object.fromEntries(result.map),\n stats: result.stats,\n }, null, 2));\n } else {\n process.stdout.write(result.mutatedCode);\n process.stderr.write(chalk.gray(`\\n--- ${result.stats.tokensMutated} identifiers mutated in ${result.stats.durationMs}ms ---\\n`));\n }\n });\n\n// ── reverse ───────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"reverse <file>\")\n .description(\"Reverse mutations using stored map\")\n .option(\"-m, --map <path>\", \"Path to mutation map JSON file\")\n .action((file: string, opts: { map?: string }) => {\n const absPath = resolve(file);\n if (!existsSync(absPath)) {\n console.error(chalk.red(\"File not found:\"), chalk.bold(absPath));\n process.exit(1);\n }\n\n const mutatedCode = readFileSync(absPath, \"utf-8\");\n\n // Load map from specified path or .pretense/mutation-map.json\n const mapPath = opts.map\n ? resolve(opts.map)\n : join(getConfigDir(), \"mutation-map.json\");\n\n if (!existsSync(mapPath)) {\n console.error(chalk.red(\"Mutation map not found:\"), chalk.bold(mapPath));\n console.error(chalk.gray(\"Run 'pretense mutate --save' first, or specify --map <path>\"));\n process.exit(1);\n }\n\n const store = new MutationStore(mapPath);\n store.load();\n\n // Try to find map by file path, or use the most recent entry\n const entry = store.get(absPath) ?? store.getByHash(absPath) ?? store.list(1)[0];\n if (!entry) {\n console.error(chalk.red(\"No mutation map found for this file.\"));\n process.exit(1);\n }\n\n const map = MutationStore.toMap(entry);\n const restored = reverse(mutatedCode, map);\n\n process.stdout.write(restored);\n process.stderr.write(chalk.gray(`\\n--- Reversed ${map.size} mutations ---\\n`));\n });\n\n// ── audit ─────────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"audit\")\n .description(\"View the audit log\")\n .option(\"--json\", \"Output as JSON\", false)\n .option(\"--csv\", \"Output as CSV\", false)\n .option(\"-l, --limit <number>\", \"Limit entries\", \"50\")\n .action((opts: { json: boolean; csv: boolean; limit: string }) => {\n const format = opts.json ? \"json\" : opts.csv ? \"csv\" : \"text\";\n const limit = parseInt(opts.limit) || 50;\n\n const entries = readAuditLog({ limit, format });\n const output = formatAudit(entries, format);\n console.log(output);\n });\n\n// ── version ───────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"version\")\n .description(\"Print Pretense CLI version\")\n .action(() => {\n console.log(`@pretense/cli v${VERSION}`);\n });\n\n// ─── Parse and run ───────────────────────────────────────────────────────────\n\nprogram.parse();\n","/**\n * Pretense Core — Shared Types\n * All domain interfaces and enums used across the mutation pipeline.\n */\n\n// ─── Token Types ───────────────────────────────────────────────────────────────\n\nexport enum TokenType {\n Variable = \"Variable\",\n Function = \"Function\",\n Class = \"Class\",\n String = \"String\",\n Comment = \"Comment\",\n Import = \"Import\",\n Property = \"Property\",\n Method = \"Method\",\n}\n\nexport interface Token {\n type: TokenType;\n value: string;\n start: number;\n end: number;\n line: number;\n}\n\n// ─── Scan ──────────────────────────────────────────────────────────────────────\n\nexport interface ScanResult {\n tokens: Token[];\n language: string;\n}\n\n// ─── Mutation ─────────────────────────────────────────────────────────────────\n\nexport interface MutationRule {\n /** Token type this rule targets */\n tokenType: TokenType;\n /** Whether to strip this token type entirely (e.g. comments) */\n strip?: boolean;\n /** Custom prefix to use instead of the default per-type prefix */\n prefix?: string;\n}\n\n/**\n * Maps every original token value to its mutated synthetic.\n * Used during forward mutation and exact reversal.\n */\nexport type MutationMap = Map<string, string>;\n\nexport interface MutationStats {\n tokensScanned: number;\n tokensMutated: number;\n durationMs: number;\n language: string;\n}\n\nexport interface MutationResult {\n mutatedCode: string;\n map: MutationMap;\n stats: MutationStats;\n}\n\n// ─── Store ────────────────────────────────────────────────────────────────────\n\nexport interface StoreEntry {\n id: string;\n originalHash: string;\n /** Serialized MutationMap (array of [original, synthetic] tuples) */\n mapEntries: [string, string][];\n timestamp: number;\n language: string;\n}\n\n// ─── Proxy ────────────────────────────────────────────────────────────────────\n\nexport interface ProxyRequest {\n body: string;\n targetUrl: string;\n headers: Record<string, string>;\n}\n\nexport interface ProxyResponse {\n body: string;\n statusCode: number;\n reversed: boolean;\n}\n\n// ─── Config ───────────────────────────────────────────────────────────────────\n\nexport interface PretenseConfig {\n port: number;\n targetApis: string[];\n languages: string[];\n mutationRules: MutationRule[];\n storePath: string;\n}\n\nexport const DEFAULT_CONFIG: PretenseConfig = {\n port: 9339,\n targetApis: [\"https://api.anthropic.com\", \"https://api.openai.com\"],\n languages: [\"typescript\", \"javascript\", \"python\", \"go\", \"java\"],\n mutationRules: [\n { tokenType: TokenType.Variable, prefix: \"_v\" },\n { tokenType: TokenType.Function, prefix: \"_fn\" },\n { tokenType: TokenType.Class, prefix: \"_cls\" },\n { tokenType: TokenType.String },\n { tokenType: TokenType.Comment, strip: true },\n { tokenType: TokenType.Import },\n { tokenType: TokenType.Property, prefix: \"_prop\" },\n { tokenType: TokenType.Method, prefix: \"_fn\" },\n ],\n storePath: `${process.env[\"HOME\"] ?? \"/tmp\"}/.pretense`,\n};\n","/**\n * Pretense Core — Token Scanner\n *\n * Regex-based token scanner for TypeScript/JavaScript, Python, Go, and Java.\n * Extracts mutable tokens (variables, functions, classes, strings, imports,\n * comments) with exact positions for accurate reversal.\n *\n * No tree-sitter dependency — pure regex MVP, production-ready accuracy.\n */\n\nimport { TokenType, type Token, type ScanResult } from \"./types.js\";\n\n// ─── Language keyword sets ─────────────────────────────────────────────────────\n\nconst TS_JS_KEYWORDS = new Set([\n \"abstract\", \"any\", \"as\", \"async\", \"await\", \"boolean\", \"break\", \"case\",\n \"catch\", \"class\", \"const\", \"constructor\", \"continue\", \"debugger\", \"declare\",\n \"default\", \"delete\", \"do\", \"else\", \"enum\", \"export\", \"extends\", \"false\",\n \"finally\", \"for\", \"from\", \"function\", \"get\", \"if\", \"implements\", \"import\",\n \"in\", \"instanceof\", \"interface\", \"keyof\", \"let\", \"module\", \"namespace\",\n \"never\", \"new\", \"null\", \"number\", \"object\", \"of\", \"package\", \"private\",\n \"protected\", \"public\", \"readonly\", \"require\", \"return\", \"set\", \"static\",\n \"string\", \"super\", \"switch\", \"symbol\", \"this\", \"throw\", \"true\", \"try\",\n \"type\", \"typeof\", \"undefined\", \"unknown\", \"var\", \"void\", \"while\", \"with\",\n \"yield\", \"satisfies\", \"using\", \"infer\", \"asserts\",\n]);\n\nconst PYTHON_KEYWORDS = new Set([\n \"False\", \"None\", \"True\", \"and\", \"as\", \"assert\", \"async\", \"await\",\n \"break\", \"class\", \"continue\", \"def\", \"del\", \"elif\", \"else\", \"except\",\n \"finally\", \"for\", \"from\", \"global\", \"if\", \"import\", \"in\", \"is\",\n \"lambda\", \"nonlocal\", \"not\", \"or\", \"pass\", \"raise\", \"return\", \"try\",\n \"while\", \"with\", \"yield\", \"self\", \"cls\",\n]);\n\nconst GO_KEYWORDS = new Set([\n \"break\", \"case\", \"chan\", \"const\", \"continue\", \"default\", \"defer\", \"else\",\n \"fallthrough\", \"for\", \"func\", \"go\", \"goto\", \"if\", \"import\", \"interface\",\n \"map\", \"package\", \"range\", \"return\", \"select\", \"struct\", \"switch\", \"type\",\n \"var\", \"nil\", \"true\", \"false\", \"error\", \"string\", \"int\", \"int8\", \"int16\",\n \"int32\", \"int64\", \"uint\", \"uint8\", \"uint16\", \"uint32\", \"uint64\", \"float32\",\n \"float64\", \"complex64\", \"complex128\", \"bool\", \"byte\", \"rune\", \"uintptr\",\n \"make\", \"new\", \"len\", \"cap\", \"append\", \"copy\", \"close\", \"delete\", \"panic\",\n \"recover\", \"print\", \"println\",\n]);\n\nconst JAVA_KEYWORDS = new Set([\n \"abstract\", \"assert\", \"boolean\", \"break\", \"byte\", \"case\", \"catch\", \"char\",\n \"class\", \"const\", \"continue\", \"default\", \"do\", \"double\", \"else\", \"enum\",\n \"extends\", \"final\", \"finally\", \"float\", \"for\", \"goto\", \"if\", \"implements\",\n \"import\", \"instanceof\", \"int\", \"interface\", \"long\", \"native\", \"new\",\n \"package\", \"private\", \"protected\", \"public\", \"return\", \"short\", \"static\",\n \"strictfp\", \"super\", \"switch\", \"synchronized\", \"this\", \"throw\", \"throws\",\n \"transient\", \"try\", \"void\", \"volatile\", \"while\", \"true\", \"false\", \"null\",\n \"var\", \"record\", \"sealed\", \"permits\", \"yield\",\n]);\n\n// ─── Language detection ────────────────────────────────────────────────────────\n\n/**\n * Detect the programming language from code heuristics.\n *\n * @example\n * detectLanguage(\"const x: number = 1;\") // => \"typescript\"\n * detectLanguage(\"def foo(x):\\n return x\") // => \"python\"\n */\nexport function detectLanguage(code: string): string {\n if (/:[\\s]*\\w+[\\s]*[;,{)]/.test(code) || /import.*from\\s+['\"]/.test(code) || /interface\\s+\\w+/.test(code)) return \"typescript\";\n if (/\\bdef\\s+\\w+\\s*\\(/.test(code) || /\\bimport\\s+\\w+/.test(code) && /:$/.test(code)) return \"python\";\n if (/\\bfunc\\s+\\w+\\s*\\(/.test(code) || /\\bpackage\\s+\\w+/.test(code)) return \"go\";\n if (/\\bpublic\\s+class\\s+\\w+/.test(code) || /\\bimport\\s+java\\./.test(code)) return \"java\";\n if (/\\bconst\\s+\\w+\\s*=/.test(code) || /\\bfunction\\s+\\w+\\s*\\(/.test(code)) return \"javascript\";\n return \"typescript\"; // default\n}\n\n// ─── Line-number helper ────────────────────────────────────────────────────────\n\nfunction lineAt(code: string, index: number): number {\n let line = 1;\n for (let i = 0; i < index && i < code.length; i++) {\n if (code[i] === \"\\n\") line++;\n }\n return line;\n}\n\n// ─── Per-language scanners ─────────────────────────────────────────────────────\n\nfunction scanTypeScript(code: string): Token[] {\n const tokens: Token[] = [];\n if (!code.trim()) return tokens;\n\n const patterns: Array<{ re: RegExp; type: TokenType; groupIndex?: number }> = [\n // Single-line comment\n { re: /\\/\\/[^\\n]*/g, type: TokenType.Comment },\n // Multi-line comment\n { re: /\\/\\*[\\s\\S]*?\\*\\//g, type: TokenType.Comment },\n // Import source (the module path string)\n { re: /\\bimport\\b[^'\"]*['\"]([^'\"]+)['\"]/g, type: TokenType.Import, groupIndex: 1 },\n // Class name\n { re: /\\bclass\\s+([A-Za-z_$][A-Za-z0-9_$]*)/g, type: TokenType.Class, groupIndex: 1 },\n // Function/method name (function keyword)\n { re: /\\bfunction\\s+([A-Za-z_$][A-Za-z0-9_$]*)/g, type: TokenType.Function, groupIndex: 1 },\n // Arrow function assigned to const/let/var\n { re: /\\b(?:const|let|var)\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*=\\s*(?:async\\s*)?\\(/g, type: TokenType.Function, groupIndex: 1 },\n // Method: identifier followed by (\n { re: /\\b([A-Za-z_$][A-Za-z0-9_$]*)\\s*\\(/g, type: TokenType.Method, groupIndex: 1 },\n // Variable declarations\n { re: /\\b(?:const|let|var)\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\b/g, type: TokenType.Variable, groupIndex: 1 },\n // Template literals (preserve backtick wrapper)\n { re: /`[^`]*`/g, type: TokenType.String },\n // Double-quoted strings\n { re: /\"(?:[^\"\\\\]|\\\\.)*\"/g, type: TokenType.String },\n // Single-quoted strings\n { re: /'(?:[^'\\\\]|\\\\.)*'/g, type: TokenType.String },\n ];\n\n for (const { re, type, groupIndex } of patterns) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(code)) !== null) {\n const fullMatch = m[0];\n const captureValue = groupIndex !== undefined ? (m[groupIndex] ?? fullMatch) : fullMatch;\n const captureStart = groupIndex !== undefined\n ? m.index + fullMatch.indexOf(captureValue)\n : m.index;\n\n if (!captureValue || captureValue.trim() === \"\") continue;\n\n // Skip language keywords for identifier tokens\n if (\n type === TokenType.Variable ||\n type === TokenType.Function ||\n type === TokenType.Class ||\n type === TokenType.Method ||\n type === TokenType.Property\n ) {\n if (TS_JS_KEYWORDS.has(captureValue)) continue;\n // Skip console/process/Object etc.\n if (/^(console|process|Object|Array|Math|JSON|Promise|Error|Map|Set|Date|RegExp|Symbol|Proxy|Reflect|global|globalThis|window|document|module|exports|require|__dirname|__filename)$/.test(captureValue)) continue;\n // Skip single-character identifiers (loop vars, etc.)\n if (captureValue.length <= 1) continue;\n }\n\n tokens.push({\n type,\n value: captureValue,\n start: captureStart,\n end: captureStart + captureValue.length,\n line: lineAt(code, captureStart),\n });\n }\n }\n\n return deduplicate(tokens);\n}\n\nfunction scanPython(code: string): Token[] {\n const tokens: Token[] = [];\n if (!code.trim()) return tokens;\n\n const patterns: Array<{ re: RegExp; type: TokenType; groupIndex?: number }> = [\n // Triple-quoted docstrings\n { re: /\"\"\"[\\s\\S]*?\"\"\"|'''[\\s\\S]*?'''/g, type: TokenType.Comment },\n // Line comments\n { re: /#[^\\n]*/g, type: TokenType.Comment },\n // Import module name\n { re: /\\bimport\\s+([A-Za-z_][A-Za-z0-9_.]*)/g, type: TokenType.Import, groupIndex: 1 },\n { re: /\\bfrom\\s+([A-Za-z_.][A-Za-z0-9_.]*)\\s+import/g, type: TokenType.Import, groupIndex: 1 },\n // Class name\n { re: /\\bclass\\s+([A-Za-z_][A-Za-z0-9_]*)/g, type: TokenType.Class, groupIndex: 1 },\n // Function/method def\n { re: /\\bdef\\s+([A-Za-z_][A-Za-z0-9_]*)/g, type: TokenType.Function, groupIndex: 1 },\n // Variable assignment (simple name = ...)\n { re: /^([A-Za-z_][A-Za-z0-9_]*)\\s*=/gm, type: TokenType.Variable, groupIndex: 1 },\n // Double-quoted strings\n { re: /\"(?:[^\"\\\\]|\\\\.)*\"/g, type: TokenType.String },\n // Single-quoted strings\n { re: /'(?:[^'\\\\]|\\\\.)*'/g, type: TokenType.String },\n ];\n\n for (const { re, type, groupIndex } of patterns) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(code)) !== null) {\n const fullMatch = m[0];\n const captureValue = groupIndex !== undefined ? (m[groupIndex] ?? fullMatch) : fullMatch;\n const captureStart = groupIndex !== undefined\n ? m.index + fullMatch.indexOf(captureValue)\n : m.index;\n\n if (!captureValue || captureValue.trim() === \"\") continue;\n\n if (\n type === TokenType.Variable ||\n type === TokenType.Function ||\n type === TokenType.Class\n ) {\n if (PYTHON_KEYWORDS.has(captureValue)) continue;\n if (captureValue.length <= 1) continue;\n // Skip dunder methods/vars\n if (captureValue.startsWith(\"__\") && captureValue.endsWith(\"__\")) continue;\n }\n\n tokens.push({\n type,\n value: captureValue,\n start: captureStart,\n end: captureStart + captureValue.length,\n line: lineAt(code, captureStart),\n });\n }\n }\n\n return deduplicate(tokens);\n}\n\nfunction scanGo(code: string): Token[] {\n const tokens: Token[] = [];\n if (!code.trim()) return tokens;\n\n const patterns: Array<{ re: RegExp; type: TokenType; groupIndex?: number }> = [\n { re: /\\/\\/[^\\n]*/g, type: TokenType.Comment },\n { re: /\\/\\*[\\s\\S]*?\\*\\//g, type: TokenType.Comment },\n // Import path\n { re: /import\\s*\\(\\s*([\\s\\S]*?)\\s*\\)/g, type: TokenType.Import },\n { re: /import\\s+\"([^\"]+)\"/g, type: TokenType.Import, groupIndex: 1 },\n // Type declaration\n { re: /\\btype\\s+([A-Za-z_][A-Za-z0-9_]*)\\s+(?:struct|interface)/g, type: TokenType.Class, groupIndex: 1 },\n // Func name\n { re: /\\bfunc\\s+(?:\\([^)]*\\)\\s*)?([A-Za-z_][A-Za-z0-9_]*)\\s*\\(/g, type: TokenType.Function, groupIndex: 1 },\n // Var/const declaration\n { re: /\\b(?:var|const)\\s+([A-Za-z_][A-Za-z0-9_]*)\\b/g, type: TokenType.Variable, groupIndex: 1 },\n // Short variable declaration\n { re: /\\b([A-Za-z_][A-Za-z0-9_]*)\\s*:=/g, type: TokenType.Variable, groupIndex: 1 },\n // Double-quoted strings\n { re: /\"(?:[^\"\\\\]|\\\\.)*\"/g, type: TokenType.String },\n // Backtick raw strings\n { re: /`[^`]*`/g, type: TokenType.String },\n ];\n\n for (const { re, type, groupIndex } of patterns) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(code)) !== null) {\n const fullMatch = m[0];\n const captureValue = groupIndex !== undefined ? (m[groupIndex] ?? fullMatch) : fullMatch;\n const captureStart = groupIndex !== undefined\n ? m.index + fullMatch.indexOf(captureValue)\n : m.index;\n\n if (!captureValue || captureValue.trim() === \"\") continue;\n\n if (\n type === TokenType.Variable ||\n type === TokenType.Function ||\n type === TokenType.Class\n ) {\n if (GO_KEYWORDS.has(captureValue)) continue;\n if (captureValue.length <= 1) continue;\n }\n\n tokens.push({\n type,\n value: captureValue,\n start: captureStart,\n end: captureStart + captureValue.length,\n line: lineAt(code, captureStart),\n });\n }\n }\n\n return deduplicate(tokens);\n}\n\nfunction scanJava(code: string): Token[] {\n const tokens: Token[] = [];\n if (!code.trim()) return tokens;\n\n const patterns: Array<{ re: RegExp; type: TokenType; groupIndex?: number }> = [\n { re: /\\/\\/[^\\n]*/g, type: TokenType.Comment },\n { re: /\\/\\*[\\s\\S]*?\\*\\//g, type: TokenType.Comment },\n // Import statement\n { re: /\\bimport\\s+([\\w.]+);/g, type: TokenType.Import, groupIndex: 1 },\n // Class/interface/enum\n { re: /\\b(?:class|interface|enum|record)\\s+([A-Za-z_$][A-Za-z0-9_$]*)/g, type: TokenType.Class, groupIndex: 1 },\n // Method declaration\n { re: /\\b(?:public|private|protected|static|final|abstract|synchronized|native|default)[\\w\\s<>\\[\\],]*\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*\\(/g, type: TokenType.Method, groupIndex: 1 },\n // Variable declaration\n { re: /\\b(?:int|long|double|float|boolean|char|byte|short|String|Object|var)\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*[=;,)]/g, type: TokenType.Variable, groupIndex: 1 },\n // Double-quoted strings\n { re: /\"(?:[^\"\\\\]|\\\\.)*\"/g, type: TokenType.String },\n ];\n\n for (const { re, type, groupIndex } of patterns) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(code)) !== null) {\n const fullMatch = m[0];\n const captureValue = groupIndex !== undefined ? (m[groupIndex] ?? fullMatch) : fullMatch;\n const captureStart = groupIndex !== undefined\n ? m.index + fullMatch.indexOf(captureValue)\n : m.index;\n\n if (!captureValue || captureValue.trim() === \"\") continue;\n\n if (\n type === TokenType.Variable ||\n type === TokenType.Method ||\n type === TokenType.Class\n ) {\n if (JAVA_KEYWORDS.has(captureValue)) continue;\n if (captureValue.length <= 1) continue;\n // Skip common stdlib class names\n if (/^(String|Object|Integer|Long|Double|Boolean|List|Map|Set|Array|Exception|Error|System|Math|Thread|Class|Enum)$/.test(captureValue)) continue;\n }\n\n tokens.push({\n type,\n value: captureValue,\n start: captureStart,\n end: captureStart + captureValue.length,\n line: lineAt(code, captureStart),\n });\n }\n }\n\n return deduplicate(tokens);\n}\n\n// ─── Deduplication ────────────────────────────────────────────────────────────\n\nfunction deduplicate(tokens: Token[]): Token[] {\n tokens.sort((a, b) => a.start - b.start);\n const seen = new Set<string>();\n const result: Token[] = [];\n for (const token of tokens) {\n const key = `${token.start}:${token.end}`;\n if (!seen.has(key)) {\n seen.add(key);\n result.push(token);\n }\n }\n return result;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Scan source code and extract mutable tokens with their positions.\n *\n * @example\n * const result = scan(\"const greeting = 'hello';\", \"typescript\");\n * result.tokens.map(t => t.value) // => [\"greeting\", \"'hello'\"]\n */\nexport function scan(code: string, language: string): ScanResult {\n if (!code || !code.trim()) {\n return { tokens: [], language };\n }\n\n const lang = language.toLowerCase();\n let tokens: Token[];\n\n switch (lang) {\n case \"typescript\":\n case \"javascript\":\n case \"ts\":\n case \"js\":\n case \"tsx\":\n case \"jsx\":\n tokens = scanTypeScript(code);\n break;\n case \"python\":\n case \"py\":\n tokens = scanPython(code);\n break;\n case \"go\":\n tokens = scanGo(code);\n break;\n case \"java\":\n tokens = scanJava(code);\n break;\n default:\n tokens = scanTypeScript(code);\n }\n\n return { tokens, language: lang };\n}\n","/**\n * Pretense Core — Deterministic Mutation Engine\n *\n * Replaces identifiers, strings, and comments with synthetic tokens.\n * Same input + same seed always produces the same output (seeded PRNG).\n * Tracks every substitution in a MutationMap for exact reversal.\n */\n\nimport { TokenType, type MutationMap, type MutationResult, type MutationStats } from \"./types.js\";\nimport { scan, detectLanguage } from \"./scanner.js\";\n\n// ─── Seeded hash ───────────────────────────────────────────────────────────────\n\n/**\n * Deterministic 32-bit hash (djb2 variant).\n * Returns a non-negative integer.\n */\nfunction hash32(str: string): number {\n let h = 5381;\n for (let i = 0; i < str.length; i++) {\n h = ((h << 5) + h) ^ str.charCodeAt(i);\n }\n return h >>> 0; // unsigned\n}\n\n/**\n * Convert a number to a base-36 alphanumeric string of exactly `len` chars.\n */\nfunction toAlphaNum(n: number, len: number): string {\n const CHARS = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let result = \"\";\n let v = n;\n for (let i = 0; i < len; i++) {\n result = CHARS[v % CHARS.length]! + result;\n v = Math.floor(v / CHARS.length);\n }\n return result;\n}\n\n/**\n * Generate a short deterministic identifier for a token value + seed.\n *\n * @example\n * deterministicId(\"getUserById\", \"proj-seed\", \"_fn\") // => \"_fnx3k7\"\n */\nfunction deterministicId(original: string, seed: string, prefix: string, len = 4): string {\n const combined = `${seed}:${prefix}:${original}`;\n const h = hash32(combined);\n return prefix + toAlphaNum(h, len);\n}\n\n// ─── Mutation logic ────────────────────────────────────────────────────────────\n\nfunction prefixForType(type: TokenType): string {\n switch (type) {\n case TokenType.Class: return \"_cls\";\n case TokenType.Function:\n case TokenType.Method: return \"_fn\";\n case TokenType.Variable: return \"_v\";\n case TokenType.Property: return \"_prop\";\n default: return \"_tok\";\n }\n}\n\n/**\n * Mutate source code deterministically. Returns mutated code and the\n * MutationMap needed to reverse it.\n *\n * @param code - Source code string\n * @param language - Language identifier (\"typescript\", \"python\", \"go\", \"java\")\n * @param seed - Optional seed for determinism (default: \"pretense\")\n *\n * @example\n * const { mutatedCode, map } = mutate(\"const apiKey = 'secret';\", \"typescript\");\n * mutatedCode // => \"const _va1b2 = '_strc3d4';\"\n */\nexport function mutate(code: string, language?: string, seed = \"pretense\"): MutationResult {\n const startMs = performance.now();\n const lang = language ?? detectLanguage(code);\n\n if (!code || !code.trim()) {\n const emptyMap: MutationMap = new Map();\n return {\n mutatedCode: code,\n map: emptyMap,\n stats: { tokensScanned: 0, tokensMutated: 0, durationMs: 0, language: lang },\n };\n }\n\n const { tokens } = scan(code, lang);\n const map: MutationMap = new Map<string, string>();\n\n // Build mutation map — one synthetic per unique original value\n for (const token of tokens) {\n if (map.has(token.value)) continue; // already mapped\n\n if (token.type === TokenType.Comment) {\n // Comments preserved verbatim — stripping breaks round-trip\n continue;\n }\n\n if (token.type === TokenType.String) {\n // Strings preserved verbatim — mutations break round-trip for multi-line strings\n continue;\n }\n\n if (token.type === TokenType.Import) {\n // Keep import paths intact — they refer to packages, not IP\n continue;\n }\n\n const prefix = prefixForType(token.type);\n const synthetic = deterministicId(token.value, seed, prefix);\n map.set(token.value, synthetic);\n }\n\n // Apply substitutions — longest-first to avoid partial match issues\n const entries = [...map.entries()].sort((a, b) => b[0].length - a[0].length);\n\n let mutatedCode = code;\n for (const [original, synthetic] of entries) {\n if (!synthetic) continue;\n // Use word-boundary aware replacement for identifiers\n const escaped = original.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n if (original.match(/^[A-Za-z_$][A-Za-z0-9_$]*$/)) {\n // Identifier: use word boundaries\n mutatedCode = mutatedCode.replace(new RegExp(`\\\\b${escaped}\\\\b`, \"g\"), synthetic);\n } else {\n // String literals or other: exact replacement\n mutatedCode = mutatedCode.split(original).join(synthetic);\n }\n }\n\n const durationMs = Math.round((performance.now() - startMs) * 100) / 100;\n\n return {\n mutatedCode,\n map,\n stats: {\n tokensScanned: tokens.length,\n tokensMutated: map.size,\n durationMs,\n language: lang,\n },\n };\n}\n","/**\n * Pretense Core — Exact Reverser\n *\n * Uses the MutationMap produced by mutate() to restore original code.\n * Applies replacements longest-first to prevent partial-match bugs.\n * After reversal, output must equal the original input byte-for-byte.\n */\n\nimport type { MutationMap } from \"./types.js\";\n\n/**\n * Reverse a previously mutated string back to the original.\n * Throws if the map contains entries whose synthetic values are not\n * present in the mutated code (indicates map/code mismatch).\n *\n * @param mutatedCode - Code that was produced by mutate()\n * @param map - The MutationMap returned by the same mutate() call\n *\n * @example\n * const { mutatedCode, map } = mutate(\"const apiKey = 'secret';\", \"typescript\");\n * reverse(mutatedCode, map) // => \"const apiKey = 'secret';\"\n */\nexport function reverse(mutatedCode: string, map: MutationMap): string {\n if (!mutatedCode || map.size === 0) return mutatedCode;\n\n // Build reverse map: synthetic → original\n // Skip comment strips (value === \"\") — they were deleted, can't be restored\n const reverseMap = new Map<string, string>();\n for (const [original, synthetic] of map.entries()) {\n if (synthetic === \"\" || !synthetic) continue; // stripped comments\n reverseMap.set(synthetic, original);\n }\n\n if (reverseMap.size === 0) return mutatedCode;\n\n // Sort by synthetic length (longest first) to avoid partial substitution\n const sortedEntries = [...reverseMap.entries()].sort((a, b) => b[0].length - a[0].length);\n\n let result = mutatedCode;\n for (const [synthetic, original] of sortedEntries) {\n const escaped = synthetic.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n if (synthetic.match(/^[A-Za-z_$][A-Za-z0-9_$]*$/) || synthetic.match(/^_[a-z]+[a-z0-9]{4,}$/)) {\n // Identifier: word boundaries\n result = result.replace(new RegExp(`\\\\b${escaped}\\\\b`, \"g\"), original);\n } else {\n // String literals: exact\n result = result.split(synthetic).join(original);\n }\n }\n\n return result;\n}\n","/**\n * Pretense Core — Secret Detection Engine\n *\n * 40+ regex patterns for API keys, tokens, credentials, and PII.\n * Sub-5ms per scan. Zero dependencies beyond regex.\n * Includes Shannon entropy check for high-entropy strings.\n */\n\nexport type ScanCategory = \"secret\" | \"pii\" | \"credential\" | \"proprietary\";\nexport type ScanAction = \"block\" | \"redact\" | \"mutate\" | \"warn\" | \"pass\";\nexport type ScanSeverity = \"critical\" | \"high\" | \"medium\" | \"low\";\n\nexport interface ScanMatch {\n id: string;\n category: ScanCategory;\n type: string;\n value: string;\n masked: string;\n start: number;\n end: number;\n severity: ScanSeverity;\n action: ScanAction;\n}\n\nexport interface SecretScanResult {\n clean: boolean;\n matches: ScanMatch[];\n scannedAt: number;\n durationMs: number;\n}\n\ninterface PatternDef {\n name: string;\n category: ScanCategory;\n severity: ScanSeverity;\n defaultAction: ScanAction;\n pattern: RegExp;\n validate?: (match: string) => boolean;\n}\n\nconst SECRET_PATTERNS: PatternDef[] = [\n { name: \"anthropic-api-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /sk-ant-api\\d{2}-[A-Za-z0-9_-]{40,}/g },\n { name: \"openai-api-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /sk-[A-Za-z0-9]{20,}/g },\n { name: \"aws-access-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /AKIA[0-9A-Z]{16}/g },\n { name: \"aws-secret-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /(?:aws_secret_access_key|AWS_SECRET_ACCESS_KEY)\\s*[=:]\\s*['\"]?([A-Za-z0-9/+=]{40})['\"]?/g },\n { name: \"github-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /gh[ps]_[A-Za-z0-9_]{36,}/g },\n { name: \"github-fine-grained\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /github_pat_[A-Za-z0-9_]{22,}/g },\n { name: \"stripe-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /(?:sk|pk|rk)_(?:test|live)_[A-Za-z0-9]{20,}/g },\n { name: \"private-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g },\n { name: \"jwt-token\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /eyJ[A-Za-z0-9_-]{10,}\\.eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}/g },\n { name: \"database-url\", category: \"credential\", severity: \"critical\", defaultAction: \"block\", pattern: /(?:postgres|mysql|mongodb|redis|amqp):\\/\\/[^\\s'\"\\\\)]+:[^\\s'\"\\\\)]+@[^\\s'\"\\\\)]+/g },\n { name: \"generic-password\", category: \"credential\", severity: \"high\", defaultAction: \"redact\", pattern: /(?:password|passwd|pwd|secret|token|api_key|apikey|api-key)\\s*[=:]\\s*['\"][^\\s'\"]{8,}['\"]/gi },\n { name: \"slack-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /xox[bpors]-[A-Za-z0-9-]{10,}/g },\n { name: \"google-api-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /AIza[A-Za-z0-9_-]{35}/g },\n { name: \"npm-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /npm_[A-Za-z0-9]{36}/g },\n { name: \"sendgrid-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /SG\\.[A-Za-z0-9_-]{22}\\.[A-Za-z0-9_-]{43}/g },\n { name: \"twilio-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /SK[a-f0-9]{32}/g },\n // ─── Additional patterns (v0.3) ──────────────────────────────────────────────\n { name: \"azure-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /(?:AccountKey|SharedAccessKey)=[A-Za-z0-9+/=]{40,}/g },\n { name: \"mailgun-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /key-[a-f0-9]{32}/g },\n { name: \"twilio-sid\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /AC[a-f0-9]{32}/g },\n { name: \"heroku-api-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /[hH]eroku.*[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/g },\n { name: \"shopify-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /shpat_[a-fA-F0-9]{32}/g },\n { name: \"datadog-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /dd[a-z]{1,2}_[a-zA-Z0-9]{32,}/g },\n { name: \"vercel-token\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /vc_[a-zA-Z0-9]{24,}/g },\n { name: \"supabase-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /sbp_[a-f0-9]{40}/g },\n { name: \"linear-api-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /lin_api_[A-Za-z0-9]{40}/g },\n { name: \"cloudflare-api-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /v1\\.0-[a-f0-9]{24}-[a-f0-9]{146}/g },\n { name: \"discord-bot-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /[MN][A-Za-z\\d]{23,}\\.[\\w-]{6}\\.[\\w-]{27}/g },\n { name: \"grafana-api-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /eyJrIjoi[A-Za-z0-9_-]{40,}/g },\n { name: \"confluent-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /CONFLUENT[A-Z_]*\\s*[=:]\\s*['\"]?[A-Za-z0-9/+=]{16,}['\"]?/g },\n { name: \"digitalocean-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /dop_v1_[a-f0-9]{64}/g },\n { name: \"doppler-token\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /dp\\.st\\.[a-z0-9_-]{2,}\\.[A-Za-z0-9]{40,}/g },\n { name: \"planetscale-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /pscale_tkn_[A-Za-z0-9_-]{32,}/g },\n { name: \"hashicorp-vault-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /hvs\\.[A-Za-z0-9_-]{24,}/g },\n { name: \"fastly-api-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /fastly_[A-Za-z0-9]{32}/g },\n { name: \"algolia-api-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /[a-f0-9]{32}/g, validate: (m) => /ALGOLIA|algolia/.test(m) },\n { name: \"pulumi-token\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /pul-[a-f0-9]{40}/g },\n];\n\nconst PII_PATTERNS: PatternDef[] = [\n { name: \"ssn\", category: \"pii\", severity: \"critical\", defaultAction: \"redact\", pattern: /\\b\\d{3}-\\d{2}-\\d{4}\\b/g },\n { name: \"credit-card\", category: \"pii\", severity: \"critical\", defaultAction: \"redact\", pattern: /\\b(?:\\d[ -]*?){13,19}\\b/g, validate: luhnCheck },\n { name: \"email\", category: \"pii\", severity: \"medium\", defaultAction: \"warn\", pattern: /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b/g },\n { name: \"phone-us\", category: \"pii\", severity: \"medium\", defaultAction: \"warn\", pattern: /\\b(?:\\+?1[-.\\s]?)?\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}\\b/g },\n { name: \"ip-address\", category: \"pii\", severity: \"low\", defaultAction: \"warn\", pattern: /\\b(?:(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\b/g, validate: (ip) => !ip.startsWith(\"127.\") && !ip.startsWith(\"0.\") && ip !== \"255.255.255.255\" },\n];\n\nconst ENV_PATTERNS: PatternDef[] = [\n { name: \"env-secret\", category: \"credential\", severity: \"high\", defaultAction: \"block\", pattern: /(?:process\\.env\\.|os\\.environ\\[|ENV\\[|getenv\\()['\"]?((?:SECRET|TOKEN|PASSWORD|API_KEY|PRIVATE|AUTH)[A-Z_0-9]*)['\"]?\\]?\\)?/gi },\n];\n\nfunction luhnCheck(num: string): boolean {\n const digits = num.replace(/\\D/g, \"\");\n if (digits.length < 13 || digits.length > 19) return false;\n let sum = 0;\n let alternate = false;\n for (let i = digits.length - 1; i >= 0; i--) {\n let n = parseInt(digits[i]!, 10);\n if (alternate) { n *= 2; if (n > 9) n -= 9; }\n sum += n;\n alternate = !alternate;\n }\n return sum % 10 === 0;\n}\n\n// ─── Shannon entropy check ────────────────────────────────────────────────────\n\n/**\n * Calculate Shannon entropy of a string. Higher values indicate more randomness.\n * Useful for detecting high-entropy strings that may be secrets/tokens.\n */\nexport function shannonEntropy(str: string): number {\n if (str.length === 0) return 0;\n const freq = new Map<string, number>();\n for (const ch of str) {\n freq.set(ch, (freq.get(ch) ?? 0) + 1);\n }\n let entropy = 0;\n const len = str.length;\n for (const count of freq.values()) {\n const p = count / len;\n if (p > 0) entropy -= p * Math.log2(p);\n }\n return entropy;\n}\n\n/**\n * Check if a string is likely a high-entropy secret.\n * Returns true if the string is > 20 chars and has entropy > 4.5.\n */\nexport function isHighEntropy(str: string, minLength = 20, threshold = 4.5): boolean {\n if (str.length <= minLength) return false;\n return shannonEntropy(str) > threshold;\n}\n\nfunction maskValue(value: string, type: string): string {\n if (type.includes(\"key\") || type.includes(\"token\") || type.includes(\"secret\")) return value.slice(0, 6) + \"...\" + value.slice(-4);\n if (type === \"ssn\") return \"***-**-\" + value.slice(-4);\n if (type === \"credit-card\") return \"****-****-****-\" + value.replace(/\\D/g, \"\").slice(-4);\n if (type === \"email\") { const [local, domain] = value.split(\"@\"); return (local?.[0] ?? \"*\") + \"***@\" + (domain ?? \"\"); }\n if (value.length > 12) return value.slice(0, 4) + \"...\" + value.slice(-4);\n return \"***\";\n}\n\nlet matchCounter = 0;\n\nexport function scan(text: string, actionOverrides?: Partial<Record<string, ScanAction>>): SecretScanResult {\n const start = performance.now();\n const matches: ScanMatch[] = [];\n const allPatterns = [...SECRET_PATTERNS, ...PII_PATTERNS, ...ENV_PATTERNS];\n\n for (const def of allPatterns) {\n def.pattern.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = def.pattern.exec(text)) !== null) {\n const value = m[0];\n if (def.validate && !def.validate(value)) continue;\n const action = actionOverrides?.[def.name] ?? def.defaultAction;\n matchCounter++;\n matches.push({\n id: `scan_${matchCounter}`,\n category: def.category,\n type: def.name,\n value,\n masked: maskValue(value, def.name),\n start: m.index,\n end: m.index + value.length,\n severity: def.severity,\n action,\n });\n }\n }\n\n // Shannon entropy check for unquoted high-entropy strings\n const highEntropyPattern = /\\b[A-Za-z0-9_\\-/.+=$]{21,}\\b/g;\n highEntropyPattern.lastIndex = 0;\n let hem: RegExpExecArray | null;\n while ((hem = highEntropyPattern.exec(text)) !== null) {\n const value = hem[0];\n // Skip if already matched by a pattern\n const alreadyMatched = matches.some(\n (m) => m.start <= hem!.index && m.end >= hem!.index + value.length,\n );\n if (alreadyMatched) continue;\n if (isHighEntropy(value)) {\n matchCounter++;\n matches.push({\n id: `scan_${matchCounter}`,\n category: \"secret\",\n type: \"high-entropy-string\",\n value,\n masked: value.slice(0, 6) + \"...\" + value.slice(-4),\n start: hem.index,\n end: hem.index + value.length,\n severity: \"medium\",\n action: actionOverrides?.[\"high-entropy-string\"] ?? \"warn\",\n });\n }\n }\n\n const severityRank: Record<ScanSeverity, number> = { critical: 4, high: 3, medium: 2, low: 1 };\n matches.sort((a, b) => a.start - b.start || severityRank[b.severity] - severityRank[a.severity]);\n\n const deduped: ScanMatch[] = [];\n let lastEnd = -1;\n for (const match of matches) {\n if (match.start >= lastEnd) {\n deduped.push(match);\n lastEnd = match.end;\n }\n }\n\n return {\n clean: deduped.filter((m) => m.action === \"block\" || m.action === \"redact\").length === 0,\n matches: deduped,\n scannedAt: Date.now(),\n durationMs: Math.round((performance.now() - start) * 100) / 100,\n };\n}\n\nexport function applyRedactions(text: string, matches: ScanMatch[]): string {\n const sorted = [...matches].sort((a, b) => b.start - a.start);\n let result = text;\n for (const match of sorted) {\n if (match.action === \"block\" || match.action === \"redact\") {\n result = result.slice(0, match.start) + `[PRETENSE:${match.type.toUpperCase()}]` + result.slice(match.end);\n }\n }\n return result;\n}\n\nexport function getPatternCount(): number {\n return SECRET_PATTERNS.length + PII_PATTERNS.length + ENV_PATTERNS.length;\n}\n","/**\n * Pretense Core — Mutation Store\n *\n * In-memory store with JSON file persistence for MutationMap entries.\n * SQLite replaces this in v0.2. For now: simple, zero-dependency, works.\n *\n * File: ~/.pretense/store.json (configurable)\n */\n\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from \"fs\";\nimport { dirname } from \"path\";\nimport type { StoreEntry, MutationMap } from \"./types.js\";\n\nexport class MutationStore {\n private entries: Map<string, StoreEntry> = new Map();\n private readonly filePath: string;\n\n constructor(filePath: string) {\n this.filePath = filePath;\n }\n\n /**\n * Persist a mutation map with associated metadata.\n *\n * @example\n * store.save({ id: \"req-1\", originalHash: \"abc\", mapEntries: [...], timestamp: Date.now(), language: \"typescript\" });\n */\n save(entry: StoreEntry): void {\n this.entries.set(entry.id, { ...entry });\n }\n\n /**\n * Retrieve a stored entry by request ID.\n *\n * @example\n * const entry = store.get(\"req-1\");\n */\n get(id: string): StoreEntry | null {\n return this.entries.get(id) ?? null;\n }\n\n /**\n * Find the most recent entry whose originalHash matches.\n *\n * @example\n * const entry = store.getByHash(\"sha256-abc123\");\n */\n getByHash(hash: string): StoreEntry | null {\n for (const entry of [...this.entries.values()].reverse()) {\n if (entry.originalHash === hash) return entry;\n }\n return null;\n }\n\n /**\n * Return all stored entries, newest first, up to `limit`.\n *\n * @example\n * store.list(10) // last 10 entries\n */\n list(limit = 50): StoreEntry[] {\n const all = [...this.entries.values()].reverse();\n return all.slice(0, limit);\n }\n\n /**\n * Delete an entry by ID. Returns true if it existed.\n */\n delete(id: string): boolean {\n return this.entries.delete(id);\n }\n\n /**\n * Remove all entries from memory.\n */\n clear(): void {\n this.entries.clear();\n }\n\n /**\n * Write current in-memory state to the JSON file.\n */\n persist(): void {\n const dir = dirname(this.filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n const data = JSON.stringify([...this.entries.values()], null, 2);\n writeFileSync(this.filePath, data, \"utf-8\");\n }\n\n /**\n * Load entries from the JSON file into memory.\n * No-ops if the file doesn't exist.\n */\n load(): void {\n if (!existsSync(this.filePath)) return;\n try {\n const raw = readFileSync(this.filePath, \"utf-8\");\n const parsed = JSON.parse(raw) as StoreEntry[];\n this.entries.clear();\n for (const entry of parsed) {\n this.entries.set(entry.id, entry);\n }\n } catch {\n // Corrupted or empty file — start fresh\n this.entries.clear();\n }\n }\n\n /** Total entries in memory */\n get size(): number {\n return this.entries.size;\n }\n\n /**\n * Reconstruct a MutationMap from a stored entry.\n *\n * @example\n * const map = store.toMap(entry);\n * reverse(mutatedCode, map);\n */\n static toMap(entry: StoreEntry): MutationMap {\n return new Map(entry.mapEntries);\n }\n\n /**\n * Serialize a MutationMap to the format stored in StoreEntry.\n */\n static fromMap(map: MutationMap): [string, string][] {\n return [...map.entries()];\n }\n}\n","/**\n * Pretense CLI — Configuration Manager\n *\n * Reads/writes the .pretense/ directory for project-level config,\n * mutation maps, and audit logs.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { join, resolve } from \"path\";\nimport type { PretenseConfig } from \"./types.js\";\nimport { DEFAULT_CONFIG } from \"./types.js\";\n\nconst CONFIG_DIR_NAME = \".pretense\";\nconst CONFIG_FILE = \"config.json\";\nconst MUTATION_MAP_FILE = \"mutation-map.json\";\nconst AUDIT_LOG_FILE = \"audit.log\";\nconst USAGE_FILE = \"usage.json\";\n\n/**\n * Get the .pretense/ config directory path for a given base directory.\n */\nexport function getConfigDir(baseDir?: string): string {\n const base = baseDir ?? process.cwd();\n return resolve(base, CONFIG_DIR_NAME);\n}\n\n/**\n * Initialize the .pretense/ directory with default config files.\n * Creates config.json, empty mutation-map.json, and empty audit.log.\n *\n * @returns The path to the created .pretense/ directory\n */\nexport function initConfig(dir?: string): string {\n const configDir = getConfigDir(dir);\n\n if (!existsSync(configDir)) {\n mkdirSync(configDir, { recursive: true });\n }\n\n // config.json\n const configPath = join(configDir, CONFIG_FILE);\n if (!existsSync(configPath)) {\n const config: PretenseConfig = {\n ...DEFAULT_CONFIG,\n storePath: configDir,\n };\n writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n }\n\n // mutation-map.json\n const mapPath = join(configDir, MUTATION_MAP_FILE);\n if (!existsSync(mapPath)) {\n writeFileSync(mapPath, \"[]\", \"utf-8\");\n }\n\n // audit.log\n const auditPath = join(configDir, AUDIT_LOG_FILE);\n if (!existsSync(auditPath)) {\n writeFileSync(auditPath, \"\", \"utf-8\");\n }\n\n // usage.json\n const usagePath = join(configDir, USAGE_FILE);\n if (!existsSync(usagePath)) {\n writeFileSync(\n usagePath,\n JSON.stringify({ date: new Date().toISOString().slice(0, 10), mutations: 0, firstUseDate: new Date().toISOString().slice(0, 10) }, null, 2),\n \"utf-8\",\n );\n }\n\n return configDir;\n}\n\n/**\n * Load config from .pretense/config.json.\n * Returns DEFAULT_CONFIG if the file doesn't exist or is corrupted.\n */\nexport function loadConfig(dir?: string): PretenseConfig {\n const configDir = getConfigDir(dir);\n const configPath = join(configDir, CONFIG_FILE);\n\n if (!existsSync(configPath)) {\n return { ...DEFAULT_CONFIG };\n }\n\n try {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<PretenseConfig>;\n return { ...DEFAULT_CONFIG, ...parsed };\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\n/**\n * Save config to .pretense/config.json.\n */\nexport function saveConfig(config: PretenseConfig, dir?: string): void {\n const configDir = getConfigDir(dir);\n if (!existsSync(configDir)) {\n mkdirSync(configDir, { recursive: true });\n }\n const configPath = join(configDir, CONFIG_FILE);\n writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n}\n\n// ─── Usage tracking ──────────────────────────────────────────────────────────\n\nexport interface UsageData {\n date: string;\n mutations: number;\n firstUseDate: string;\n}\n\nexport function loadUsage(dir?: string): UsageData {\n const configDir = getConfigDir(dir);\n const usagePath = join(configDir, USAGE_FILE);\n\n const today = new Date().toISOString().slice(0, 10);\n\n if (!existsSync(usagePath)) {\n return { date: today, mutations: 0, firstUseDate: today };\n }\n\n try {\n const raw = readFileSync(usagePath, \"utf-8\");\n const data = JSON.parse(raw) as UsageData;\n // Reset counter if it's a new day\n if (data.date !== today) {\n return { date: today, mutations: 0, firstUseDate: data.firstUseDate ?? today };\n }\n return data;\n } catch {\n return { date: today, mutations: 0, firstUseDate: today };\n }\n}\n\nexport function saveUsage(usage: UsageData, dir?: string): void {\n const configDir = getConfigDir(dir);\n if (!existsSync(configDir)) {\n mkdirSync(configDir, { recursive: true });\n }\n const usagePath = join(configDir, USAGE_FILE);\n writeFileSync(usagePath, JSON.stringify(usage, null, 2), \"utf-8\");\n}\n\n// ─── License tier detection ───────────────────────────────────────────────────\n\nexport type LicenseTier = \"free\" | \"pro\" | \"enterprise\";\n\nexport function detectTier(): LicenseTier {\n const key = process.env[\"PRETENSE_LICENSE_KEY\"] ?? \"\";\n if (key.startsWith(\"pre_ent_\")) return \"enterprise\";\n if (key.startsWith(\"pre_pro_\")) return \"pro\";\n return \"free\";\n}\n\nexport function getTierLimits(tier: LicenseTier): { dailyMutations: number; auditRetentionDays: number } {\n switch (tier) {\n case \"enterprise\":\n return { dailyMutations: Infinity, auditRetentionDays: Infinity };\n case \"pro\":\n return { dailyMutations: Infinity, auditRetentionDays: 90 };\n case \"free\":\n default:\n return { dailyMutations: 500, auditRetentionDays: 3 };\n }\n}\n","/**\n * Pretense CLI — Audit Logger\n *\n * Writes JSON lines to .pretense/audit.log for compliance and debugging.\n * Supports JSON and CSV output formats. Tier-gated retention.\n */\n\nimport { appendFileSync, existsSync, readFileSync, mkdirSync } from \"fs\";\nimport { join, dirname } from \"path\";\nimport { getConfigDir, detectTier, getTierLimits } from \"./config.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport interface AuditEntry {\n timestamp: string;\n sessionId: string;\n file: string;\n identifiersMutated: number;\n secretsBlocked: number;\n llmProvider: string;\n latencyMs: number;\n}\n\nexport interface AuditReadOptions {\n limit?: number;\n format?: \"json\" | \"csv\" | \"text\";\n dir?: string;\n}\n\n// ─── Write ───────────────────────────────────────────────────────────────────\n\n/**\n * Append an audit entry as a JSON line to .pretense/audit.log.\n */\nexport function writeAuditEntry(entry: AuditEntry, dir?: string): void {\n const configDir = getConfigDir(dir);\n const auditPath = join(configDir, \"audit.log\");\n\n const logDir = dirname(auditPath);\n if (!existsSync(logDir)) {\n mkdirSync(logDir, { recursive: true });\n }\n\n const line = JSON.stringify(entry) + \"\\n\";\n appendFileSync(auditPath, line, \"utf-8\");\n}\n\n/**\n * Create a new audit entry with current timestamp.\n */\nexport function createAuditEntry(\n sessionId: string,\n file: string,\n identifiersMutated: number,\n secretsBlocked: number,\n llmProvider: string,\n latencyMs: number,\n): AuditEntry {\n return {\n timestamp: new Date().toISOString(),\n sessionId,\n file,\n identifiersMutated,\n secretsBlocked,\n llmProvider,\n latencyMs,\n };\n}\n\n// ─── Read ────────────────────────────────────────────────────────────────────\n\n/**\n * Read and parse the audit log. Applies tier-based retention filtering.\n */\nexport function readAuditLog(options: AuditReadOptions = {}): AuditEntry[] {\n const { limit, dir } = options;\n const configDir = getConfigDir(dir);\n const auditPath = join(configDir, \"audit.log\");\n\n if (!existsSync(auditPath)) {\n return [];\n }\n\n const raw = readFileSync(auditPath, \"utf-8\");\n const lines = raw.trim().split(\"\\n\").filter(Boolean);\n\n let entries: AuditEntry[] = [];\n for (const line of lines) {\n try {\n entries.push(JSON.parse(line) as AuditEntry);\n } catch {\n // Skip malformed lines\n }\n }\n\n // Apply tier-based retention filter\n const tier = detectTier();\n const { auditRetentionDays } = getTierLimits(tier);\n\n if (auditRetentionDays !== Infinity) {\n const cutoff = Date.now() - auditRetentionDays * 24 * 60 * 60 * 1000;\n entries = entries.filter((e) => new Date(e.timestamp).getTime() >= cutoff);\n }\n\n // Sort newest first\n entries.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());\n\n // Apply limit\n if (limit && limit > 0) {\n entries = entries.slice(0, limit);\n }\n\n return entries;\n}\n\n// ─── Formatters ──────────────────────────────────────────────────────────────\n\n/**\n * Format audit entries as JSON string.\n */\nexport function formatJson(entries: AuditEntry[]): string {\n return JSON.stringify(entries, null, 2);\n}\n\n/**\n * Format audit entries as CSV string.\n */\nexport function formatCsv(entries: AuditEntry[]): string {\n const headers = \"timestamp,sessionId,file,identifiersMutated,secretsBlocked,llmProvider,latencyMs\";\n const rows = entries.map((e) =>\n [\n e.timestamp,\n e.sessionId,\n `\"${e.file.replace(/\"/g, '\"\"')}\"`,\n e.identifiersMutated,\n e.secretsBlocked,\n e.llmProvider,\n e.latencyMs,\n ].join(\",\"),\n );\n return [headers, ...rows].join(\"\\n\");\n}\n\n/**\n * Format audit entries as human-readable text.\n */\nexport function formatText(entries: AuditEntry[]): string {\n if (entries.length === 0) return \"No audit entries found.\";\n\n const lines = entries.map((e) => {\n const date = new Date(e.timestamp).toLocaleString();\n return `[${date}] ${e.file} | ${e.identifiersMutated} mutated | ${e.secretsBlocked} secrets blocked | ${e.llmProvider} | ${e.latencyMs}ms`;\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format entries using the specified format.\n */\nexport function formatAudit(entries: AuditEntry[], format: \"json\" | \"csv\" | \"text\" = \"text\"): string {\n switch (format) {\n case \"json\":\n return formatJson(entries);\n case \"csv\":\n return formatCsv(entries);\n case \"text\":\n default:\n return formatText(entries);\n }\n}\n","/**\n * Pretense CLI — Proxy Server\n *\n * Hono HTTP proxy that intercepts LLM API calls, scans + mutates\n * proprietary code, forwards to the real provider, then reverse-mutates\n * the response. Supports Anthropic, OpenAI, and Google Gemini.\n *\n * Includes free-tier enforcement, usage tracking, and upgrade nudges.\n * Drop-in replacement: set *_BASE_URL=http://localhost:9339 and done.\n */\n\nimport { Hono } from \"hono\";\nimport { serve } from \"@hono/node-server\";\nimport { nanoid } from \"nanoid\";\nimport { mutate } from \"./mutator.js\";\nimport { reverse } from \"./reverser.js\";\nimport { MutationStore } from \"./store.js\";\nimport { scan as scanSecrets, applyRedactions } from \"./secrets.js\";\nimport { writeAuditEntry, createAuditEntry } from \"./audit.js\";\nimport { loadUsage, saveUsage, detectTier, getTierLimits, getConfigDir } from \"./config.js\";\nimport type { StoreEntry, PretenseConfig } from \"./types.js\";\nimport { DEFAULT_CONFIG } from \"./types.js\";\n\n// ─── Provider detection ───────────────────────────────────────────────────────\n\nfunction detectUpstream(path: string): string {\n if (path.includes(\"/v1/messages\")) return \"https://api.anthropic.com\";\n if (path.includes(\"/v1/chat/completions\") || path.includes(\"/v1/completions\")) return \"https://api.openai.com\";\n if (path.includes(\"/v1beta/\") || path.includes(\"/v1/models\")) return \"https://generativelanguage.googleapis.com\";\n return \"https://api.openai.com\";\n}\n\nfunction detectProvider(path: string): string {\n if (path.includes(\"/v1/messages\")) return \"anthropic\";\n if (path.includes(\"/v1/chat/completions\") || path.includes(\"/v1/completions\")) return \"openai\";\n if (path.includes(\"/v1beta/\") || path.includes(\"/v1/models\")) return \"google\";\n return \"openai\";\n}\n\n// ─── Message text extraction ──────────────────────────────────────────────────\n\nfunction extractText(body: Record<string, unknown>): string {\n const parts: string[] = [];\n if (typeof body[\"system\"] === \"string\") parts.push(body[\"system\"]);\n if (Array.isArray(body[\"messages\"])) {\n for (const msg of body[\"messages\"] as Record<string, unknown>[]) {\n if (typeof msg[\"content\"] === \"string\") parts.push(msg[\"content\"]);\n else if (Array.isArray(msg[\"content\"])) {\n for (const block of msg[\"content\"] as Record<string, unknown>[]) {\n if (block[\"type\"] === \"text\" && typeof block[\"text\"] === \"string\") parts.push(block[\"text\"]);\n }\n }\n }\n }\n return parts.join(\"\\n\");\n}\n\n// ─── Code block extraction (inline — no external dep) ────────────────────────\n\ninterface CodeBlock {\n code: string;\n language: string;\n start: number;\n end: number;\n}\n\nfunction extractCodeBlocks(text: string): CodeBlock[] {\n const blocks: CodeBlock[] = [];\n const re = /```(\\w*)\\n([\\s\\S]*?)```/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n blocks.push({\n code: m[2] ?? \"\",\n language: m[1] ?? \"typescript\",\n start: m.index,\n end: m.index + m[0].length,\n });\n }\n return blocks;\n}\n\nfunction replaceCodeBlocks(text: string, blocks: CodeBlock[], replacements: string[]): string {\n let result = text;\n // Replace in reverse order to preserve indices\n for (let i = blocks.length - 1; i >= 0; i--) {\n const block = blocks[i]!;\n const replacement = replacements[i] ?? block.code;\n const lang = block.language ?? \"typescript\";\n result = result.slice(0, block.start) + \"```\" + lang + \"\\n\" + replacement + \"```\" + result.slice(block.end);\n }\n return result;\n}\n\n// ─── Apply text mutations to message body ────────────────────────────────────\n\nfunction applyToBody(\n body: Record<string, unknown>,\n transform: (text: string) => string,\n): Record<string, unknown> {\n const mutateField = (val: unknown): unknown => {\n if (typeof val === \"string\") return transform(val);\n if (Array.isArray(val)) return val.map(mutateField);\n if (val && typeof val === \"object\") {\n const obj = val as Record<string, unknown>;\n return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, mutateField(v)]));\n }\n return val;\n };\n\n return mutateField(body) as Record<string, unknown>;\n}\n\n// ─── Stats tracking ───────────────────────────────────────────────────────────\n\ninterface ProxyStats {\n requestsProcessed: number;\n totalTokensMutated: number;\n totalSecretsBlocked: number;\n startedAt: number;\n}\n\nconst stats: ProxyStats = {\n requestsProcessed: 0,\n totalTokensMutated: 0,\n totalSecretsBlocked: 0,\n startedAt: Date.now(),\n};\n\n// ─── Upgrade nudge helpers ───────────────────────────────────────────────────\n\nfunction daysSinceFirstUse(): number {\n const usage = loadUsage();\n if (!usage.firstUseDate) return 0;\n const first = new Date(usage.firstUseDate).getTime();\n return Math.floor((Date.now() - first) / (24 * 60 * 60 * 1000));\n}\n\nfunction printUpgradeNudge(reason: string): void {\n process.stdout.write(\n `\\n\\x1b[33m[PRETENSE] ${reason}\\x1b[0m\\n` +\n `\\x1b[33m[PRETENSE] Upgrade to Pro: https://pretense.ai/pricing\\x1b[0m\\n\\n`,\n );\n}\n\n// ─── Proxy factory ────────────────────────────────────────────────────────────\n\nexport interface ProxyOptions {\n config?: Partial<PretenseConfig>;\n store?: MutationStore;\n verbose?: boolean;\n}\n\nexport function createProxy(opts: ProxyOptions = {}): Hono {\n const config: PretenseConfig = { ...DEFAULT_CONFIG, ...opts.config };\n const store = opts.store ?? new MutationStore(`${config.storePath}/proxy-store.json`);\n const verbose = opts.verbose ?? false;\n\n const app = new Hono();\n\n // ── Health ─────────────────────────────────────────────────────────────────\n app.get(\"/health\", (c) =>\n c.json({\n status: \"ok\",\n version: \"0.3.0\",\n uptime: Math.floor((Date.now() - stats.startedAt) / 1000),\n stats: {\n requestsProcessed: stats.requestsProcessed,\n totalTokensMutated: stats.totalTokensMutated,\n },\n }),\n );\n\n // ── Stats ──────────────────────────────────────────────────────────────────\n app.get(\"/stats\", (c) =>\n c.json({\n ...stats,\n storeSize: store.size,\n }),\n );\n\n // ── Audit ──────────────────────────────────────────────────────────────────\n app.get(\"/audit\", (c) => {\n const limit = parseInt(c.req.query(\"limit\") ?? \"50\");\n return c.json(store.list(limit));\n });\n\n // ── Main proxy handler ─────────────────────────────────────────────────────\n app.all(\"/*\", async (c) => {\n if (c.req.method !== \"POST\") {\n // Pass-through non-POST (GET model lists, etc.)\n const upstream = c.req.header(\"x-pretense-upstream\") ?? detectUpstream(c.req.path);\n const url = upstream + c.req.path;\n const headers: Record<string, string> = {};\n c.req.raw.headers.forEach((v, k) => { headers[k] = v; });\n delete headers[\"host\"];\n headers[\"host\"] = new URL(upstream).host;\n const resp = await fetch(url, { method: c.req.method, headers });\n return new Response(resp.body, { status: resp.status, headers: Object.fromEntries(resp.headers.entries()) });\n }\n\n const requestStart = performance.now();\n\n // ── Parse body ────────────────────────────────────────────────────────\n let body: Record<string, unknown>;\n try {\n body = await c.req.json<Record<string, unknown>>();\n } catch {\n return c.json({ error: { type: \"invalid_request\", message: \"Invalid JSON body\" } }, 400);\n }\n\n if (!body || Object.keys(body).length === 0) {\n return c.json({ error: { type: \"invalid_request\", message: \"Empty request body\" } }, 400);\n }\n\n const requestId = nanoid(12);\n const upstream = c.req.header(\"x-pretense-upstream\") ?? detectUpstream(c.req.path);\n const provider = detectProvider(c.req.path);\n\n // ── Free tier enforcement ─────────────────────────────────────────────\n const tier = detectTier();\n const { dailyMutations } = getTierLimits(tier);\n const usage = loadUsage();\n\n if (tier === \"free\" && usage.mutations >= dailyMutations) {\n return c.json(\n {\n error: {\n type: \"pretense_rate_limit\",\n message: `Daily mutation limit reached (${dailyMutations}/day). Upgrade to Pro for unlimited: https://pretense.ai/pricing`,\n },\n },\n 429,\n );\n }\n\n // ── Secret scan ───────────────────────────────────────────────────────\n const fullText = extractText(body);\n const secretScan = scanSecrets(fullText);\n const blockedSecrets = secretScan.matches.filter((m) => m.action === \"block\");\n\n if (blockedSecrets.length > 0) {\n stats.totalSecretsBlocked += blockedSecrets.length;\n\n // Pro alert suggestion for secrets\n if (tier === \"free\") {\n printUpgradeNudge(`${blockedSecrets.length} secret(s) blocked. Pro tier includes real-time secret alerts via Slack/PagerDuty.`);\n }\n\n return c.json(\n {\n error: {\n type: \"pretense_blocked\",\n message: `Request blocked: ${blockedSecrets.length} secret(s) detected. Types: ${[...new Set(blockedSecrets.map((m) => m.type))].join(\", \")}`,\n },\n },\n 400,\n );\n }\n\n // Apply redactions (PII, warnings)\n const processedBody = applyToBody(body, (text) => applyRedactions(text, secretScan.matches));\n\n // ── Code mutation ─────────────────────────────────────────────────────\n const mutationMap = new Map<string, string>();\n let tokensMutated = 0;\n\n const mutatedBody = applyToBody(processedBody, (text) => {\n const blocks = extractCodeBlocks(text);\n if (blocks.length === 0) return text;\n\n const mutatedBlocks: string[] = [];\n for (const block of blocks) {\n const result = mutate(block.code, block.language);\n for (const [k, v] of result.map.entries()) mutationMap.set(k, v);\n tokensMutated += result.stats.tokensMutated;\n mutatedBlocks.push(result.mutatedCode);\n }\n\n return replaceCodeBlocks(text, blocks, mutatedBlocks);\n });\n\n // Update usage tracking\n usage.mutations += tokensMutated;\n saveUsage(usage);\n\n // Warning at 400 mutations (free tier)\n if (tier === \"free\" && usage.mutations >= 400 && usage.mutations - tokensMutated < 400) {\n printUpgradeNudge(`${usage.mutations}/${dailyMutations} daily mutations used. Running low!`);\n }\n\n // 7-day upgrade nudge\n if (tier === \"free\" && daysSinceFirstUse() >= 7) {\n printUpgradeNudge(\"You've been using Pretense for 7+ days. Unlock Pro features: unlimited mutations, 90-day audit, Slack alerts.\");\n }\n\n // Store mutation map for response reversal\n const entry: StoreEntry = {\n id: requestId,\n originalHash: requestId,\n mapEntries: [...mutationMap.entries()],\n timestamp: Date.now(),\n language: \"mixed\",\n };\n store.save(entry);\n stats.requestsProcessed++;\n stats.totalTokensMutated += tokensMutated;\n\n // Write audit entry\n const latencyMs = Math.round((performance.now() - requestStart) * 100) / 100;\n writeAuditEntry(\n createAuditEntry(requestId, \"proxy-request\", tokensMutated, blockedSecrets.length, provider, latencyMs),\n );\n\n if (verbose && tokensMutated > 0) {\n process.stdout.write(`[PRETENSE] ${tokensMutated} tokens mutated for request ${requestId}\\n`);\n }\n\n // ── Forward to upstream ───────────────────────────────────────────────\n const headers: Record<string, string> = {};\n c.req.raw.headers.forEach((v, k) => { headers[k] = v; });\n delete headers[\"host\"];\n delete headers[\"content-length\"];\n headers[\"host\"] = new URL(upstream).host;\n headers[\"x-pretense-request-id\"] = requestId;\n\n const forwardBody = JSON.stringify(mutatedBody);\n\n let upstreamResp: Response;\n try {\n upstreamResp = await fetch(upstream + c.req.path, {\n method: \"POST\",\n headers: { ...headers, \"content-type\": \"application/json\", \"content-length\": String(Buffer.byteLength(forwardBody)) },\n body: forwardBody,\n });\n } catch {\n return c.json({ error: { type: \"pretense_upstream_error\", message: \"Failed to reach upstream provider\" } }, 502);\n }\n\n // ── Streaming passthrough ────────────────────────────────────────────\n if (body[\"stream\"] === true) {\n return new Response(upstreamResp.body, {\n status: upstreamResp.status,\n headers: {\n \"content-type\": upstreamResp.headers.get(\"content-type\") ?? \"text/event-stream\",\n \"cache-control\": \"no-cache\",\n \"x-pretense-request-id\": requestId,\n \"x-pretense-protected\": \"true\",\n \"x-pretense-mutations\": String(tokensMutated),\n },\n });\n }\n\n // ── Reverse-mutate response ──────────────────────────────────────────\n const reverseMap = new Map(mutationMap);\n let respBody: Record<string, unknown>;\n try {\n respBody = (await upstreamResp.json()) as Record<string, unknown>;\n } catch {\n return new Response(null, {\n status: upstreamResp.status,\n headers: {\n \"x-pretense-protected\": \"true\",\n \"x-pretense-mutations\": String(tokensMutated),\n },\n });\n }\n\n const reversedBody = applyToBody(respBody, (text) => {\n const blocks = extractCodeBlocks(text);\n if (blocks.length === 0) return reverse(text, reverseMap);\n const reversedBlocks = blocks.map((b) => reverse(b.code, reverseMap));\n return replaceCodeBlocks(text, blocks, reversedBlocks);\n });\n\n c.header(\"x-pretense-request-id\", requestId);\n c.header(\"x-pretense-protected\", \"true\");\n c.header(\"x-pretense-mutations\", String(tokensMutated));\n return c.json(reversedBody, upstreamResp.status as 200);\n });\n\n return app;\n}\n\n// ─── Start server ─────────────────────────────────────────────────────────────\n\nexport function startProxy(opts: ProxyOptions & { port?: number } = {}): void {\n const port = opts.port ?? opts.config?.port ?? DEFAULT_CONFIG.port;\n const app = createProxy(opts);\n const tier = detectTier();\n\n serve({ fetch: app.fetch, port }, () => {\n process.stdout.write(`\n\\x1b[36m┌─────────────────────────────────────────────┐\n│ │\n│ \\x1b[1mPretense\\x1b[0m\\x1b[36m v0.3.0 [${tier.toUpperCase()}]${\" \".repeat(20 - tier.length)}│\n│ Your code hits AI naked. We fix that. │\n│ │\n│ Proxy: http://localhost:${port} │\n│ Health: http://localhost:${port}/health │\n│ Stats: http://localhost:${port}/stats │\n│ │\n│ ANTHROPIC_BASE_URL=http://localhost:${port} │\n│ OPENAI_BASE_URL=http://localhost:${port}/v1 │\n│ │\n└─────────────────────────────────────────────┘\\x1b[0m\n`);\n });\n}\n"],"mappings":"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","names":["readFileSync","existsSync","resolve","join","scan","existsSync","mkdirSync","readFileSync","writeFileSync","existsSync","mkdirSync","writeFileSync","readFileSync","existsSync","readFileSync","mkdirSync","writeFileSync","existsSync","readFileSync","mkdirSync","join","dirname","join","dirname","existsSync","mkdirSync","readFileSync","upstream","headers","scan","resolve","existsSync","join","readFileSync","scan"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/scanner.ts","../src/salt.ts","../src/mutator.ts","../src/reverser.ts","../src/secrets.ts","../src/store.ts","../src/config.ts","../src/audit.ts","../src/proxy.ts","../src/auth.ts","../src/session-store.ts","../src/token-footer.ts","../src/banner.ts","../src/commands/status.ts","../src/commands/upgrade.ts","../src/commands/credits.ts","../src/commands/login.ts"],"sourcesContent":["/**\n * Pretense CLI — Entry Point\n *\n * AI firewall CLI that mutates proprietary code identifiers before\n * sending to LLM APIs. Commands: init, start, scan, mutate, reverse,\n * audit, status, usage, tokens, upgrade, credits, version.\n */\n\n// ─── Node version preflight (must run before any other imports execute) ─────\n{\n const major = parseInt(process.versions.node.split(\".\")[0]!, 10);\n if (Number.isNaN(major) || major < 18) {\n process.stderr.write(\n `pretense requires Node.js 18 or newer (you have v${process.versions.node}).\\n`,\n );\n process.stderr.write(`Upgrade via nvm: nvm install 20 && nvm use 20\\n`);\n process.exit(1);\n }\n}\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { readFileSync, existsSync, readdirSync, statSync, openSync, readSync, closeSync } from \"fs\";\nimport { readFile, stat as fsStat, open as fsOpen } from \"fs/promises\";\nimport { resolve, extname, join, basename } from \"path\";\nimport os from \"node:os\";\nimport { scan, detectLanguage } from \"./scanner.js\";\nimport { mutate } from \"./mutator.js\";\nimport { reverse } from \"./reverser.js\";\nimport { scan as scanSecrets } from \"./secrets.js\";\nimport { MutationStore } from \"./store.js\";\nimport { initConfig, loadConfig, getConfigDir } from \"./config.js\";\nimport { readAuditLog, formatAudit } from \"./audit.js\";\nimport { startProxy } from \"./proxy.js\";\nimport { printTokenFooter } from \"./token-footer.js\";\nimport { printBanner } from \"./banner.js\";\nimport { runStatus } from \"./commands/status.js\";\nimport { runUpgrade } from \"./commands/upgrade.js\";\nimport { runCredits } from \"./commands/credits.js\";\nimport { runLogin } from \"./commands/login.js\";\n\nconst VERSION = \"0.3.0\";\n\n// ─── Scan defaults (P0 hang fix) ─────────────────────────────────────────────\n// Files larger than the --max-file-size value (default: 10mb) are skipped.\n// Real-world source files are almost always < 1 MB; anything larger is\n// typically generated/minified/vendored data that wedges the regex scanner\n// with no useful signal.\n//\n// Concurrency cap for parallel file scanning (1 worker per logical CPU,\n// minimum 2 to keep things moving on single-core CI).\nconst SCAN_CONCURRENCY = Math.max(2, os.cpus().length);\n// Throttle for streaming progress updates so we don't flood stderr.\nconst PROGRESS_INTERVAL_MS = 500;\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nconst SUPPORTED_LANGUAGES = [\"typescript\", \"javascript\", \"python\", \"go\", \"java\", \"csharp\", \"ruby\", \"rust\"];\n\nconst SUPPORTED_EXTENSIONS = new Set([\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\", \".py\", \".go\", \".java\", \".cs\", \".rb\", \".rs\"]);\n\n// Additional config/data file types scanned for secrets (not for identifier mutation).\nconst SUPPORTED_CONFIG_EXTENSIONS = new Set([\n \".json\", \".yaml\", \".yml\", \".toml\", \".env\", \".cfg\", \".ini\",\n \".tf\", \".tfstate\", \".tfvars\", \".hcl\",\n \".properties\", \".conf\", \".xml\", \".plist\",\n \".pem\", \".key\", \".crt\", \".pub\", \".pfx\", \".p12\", \".htpasswd\",\n]);\n\nconst SUPPORTED_FILENAMES = new Set([\n \".env\",\n \".env.local\",\n \".env.production\",\n \".env.development\",\n \".env.staging\",\n \".env.test\",\n \".npmrc\",\n \".netrc\",\n \".pypirc\",\n \"Dockerfile\",\n \"docker-compose.yml\",\n \"docker-compose.yaml\",\n]);\n\nfunction isScannableFile(filePath: string): boolean {\n const ext = extname(filePath).toLowerCase();\n return (\n SUPPORTED_EXTENSIONS.has(ext) ||\n SUPPORTED_CONFIG_EXTENSIONS.has(ext) ||\n SUPPORTED_FILENAMES.has(basename(filePath))\n );\n}\n\nfunction isSourceCodeFile(filePath: string): boolean {\n return SUPPORTED_EXTENSIONS.has(extname(filePath).toLowerCase());\n}\n\nfunction langFromExt(filePath: string): string {\n const ext = extname(filePath).toLowerCase();\n const map: Record<string, string> = {\n \".ts\": \"typescript\",\n \".tsx\": \"typescript\",\n \".js\": \"javascript\",\n \".jsx\": \"javascript\",\n \".mjs\": \"javascript\",\n \".cjs\": \"javascript\",\n \".py\": \"python\",\n \".go\": \"go\",\n \".java\": \"java\",\n \".cs\": \"csharp\",\n \".rb\": \"ruby\",\n \".rs\": \"rust\",\n };\n return map[ext] ?? \"typescript\";\n}\n\n/**\n * Validate a port number string. Returns the parsed integer or null if invalid.\n */\nfunction validatePort(value: string): number | null {\n const port = parseInt(value, 10);\n if (isNaN(port) || port.toString() !== value.trim()) return null;\n if (port < 1 || port > 65535) return null;\n return port;\n}\n\n/**\n * Detect if a file is likely binary by checking for null bytes\n * in the first 8KB. Only reads the bytes needed, not the whole file.\n */\nfunction isBinaryFile(filePath: string): boolean {\n let fd: number | undefined;\n try {\n fd = openSync(filePath, \"r\");\n const buf = Buffer.alloc(8192);\n const bytesRead = readSync(fd, buf, 0, 8192, 0);\n for (let i = 0; i < bytesRead; i++) {\n if (buf[i] === 0) return true;\n }\n return false;\n } catch {\n return false;\n } finally {\n if (fd !== undefined) closeSync(fd);\n }\n}\n\n/**\n * Async binary-file probe — reads only the first 8KB.\n * Used by the concurrent scanner so we never block the event loop.\n */\nasync function isBinaryFileAsync(filePath: string): Promise<boolean> {\n let handle: import(\"fs/promises\").FileHandle | undefined;\n try {\n handle = await fsOpen(filePath, \"r\");\n const buf = Buffer.alloc(8192);\n const { bytesRead } = await handle.read(buf, 0, 8192, 0);\n for (let i = 0; i < bytesRead; i++) {\n if (buf[i] === 0) return true;\n }\n return false;\n } catch {\n return false;\n } finally {\n if (handle) await handle.close().catch(() => {});\n }\n}\n\n/**\n * Validate that a language string is supported. Returns the normalized\n * language or null if unsupported.\n */\nfunction validateLanguage(lang: string): string | null {\n const normalized = lang.toLowerCase();\n const aliases: Record<string, string> = {\n ts: \"typescript\", tsx: \"typescript\",\n js: \"javascript\", jsx: \"javascript\",\n py: \"python\",\n cs: \"csharp\",\n rb: \"ruby\",\n rs: \"rust\",\n };\n const resolved = aliases[normalized] ?? normalized;\n return SUPPORTED_LANGUAGES.includes(resolved) ? resolved : null;\n}\n\nfunction collectFiles(target: string): string[] {\n const abs = resolve(target);\n if (!existsSync(abs)) {\n return [];\n }\n const stat = statSync(abs);\n if (stat.isFile()) return [abs];\n\n const files: string[] = [];\n\n function walk(dir: string): void {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n // Skip common non-source dirs\n if ([\"node_modules\", \".git\", \"dist\", \"build\", \".pretense\", \".next\", \"__pycache__\"].includes(entry.name)) continue;\n walk(fullPath);\n } else if (entry.isFile() && isScannableFile(entry.name)) {\n files.push(fullPath);\n }\n }\n }\n\n walk(abs);\n return files;\n}\n\n// ─── CLI ─────────────────────────────────────────────────────────────────────\n\nconst program = new Command();\n\nprogram\n .name(\"pretense\")\n .description(\"AI firewall CLI — mutates proprietary code before LLM API calls\")\n .version(VERSION)\n .hook(\"preAction\", () => {\n printBanner();\n });\n\n// ── init ──────────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"init\")\n .description(\"Initialize .pretense/ config in current directory\")\n .option(\"-d, --dir <path>\", \"Target directory\", process.cwd())\n .action((opts: { dir: string }) => {\n const dir = resolve(opts.dir);\n console.log(chalk.cyan(\"Initializing Pretense in\"), chalk.bold(dir));\n\n const configDir = initConfig(dir);\n\n // Scan for source files\n const files = collectFiles(dir);\n const langCounts: Record<string, number> = {};\n for (const f of files) {\n const lang = langFromExt(f);\n langCounts[lang] = (langCounts[lang] ?? 0) + 1;\n }\n\n console.log(chalk.green(\"\\n .pretense/ created at\"), chalk.bold(configDir));\n console.log(chalk.gray(`\\n Scanned ${files.length} source files:`));\n for (const [lang, count] of Object.entries(langCounts)) {\n console.log(chalk.gray(` ${lang}: ${count} files`));\n }\n console.log(chalk.cyan(\"\\n Next: run\"), chalk.bold(\"pretense start\"), chalk.cyan(\"to launch the proxy\"));\n console.log();\n });\n\n// ── start ─────────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"start\")\n .description(\"Start the Pretense proxy server\")\n .option(\"-p, --port <number>\", \"Port number\", \"9339\")\n .option(\"-v, --verbose\", \"Enable verbose logging\", false)\n .action((opts: { port: string; verbose: boolean }) => {\n const config = loadConfig();\n const port = validatePort(opts.port);\n if (port === null) {\n console.error(chalk.red(\"Error: Invalid port number:\"), chalk.bold(opts.port));\n console.error(chalk.gray(\"Port must be an integer between 1 and 65535.\"));\n process.exit(1);\n }\n startProxy({ config, port, verbose: opts.verbose });\n });\n\n// ── scan ──────────────────────────────────────────────────────────────────────\n\ninterface ScanRowResult {\n file: string;\n identifiers: number;\n secrets: number;\n secretTypes: string[];\n skipped?: \"too-large\" | \"binary\" | \"read-error\";\n sizeBytes?: number;\n}\n\n/**\n * Scan a single file. Pure async, fully bounded (file-size + binary checks\n * happen before reading). Returns null on unrecoverable read errors so the\n * caller can keep going on the next file.\n */\nasync function scanOneFile(\n file: string,\n opts: { secretsOnly: boolean; maxFileSize: number },\n): Promise<ScanRowResult | null> {\n let size = 0;\n try {\n const st = await fsStat(file);\n size = st.size;\n if (st.size > opts.maxFileSize) {\n return { file, identifiers: 0, secrets: 0, secretTypes: [], skipped: \"too-large\", sizeBytes: size };\n }\n } catch {\n return { file, identifiers: 0, secrets: 0, secretTypes: [], skipped: \"read-error\" };\n }\n\n // Cheap binary probe for unknown source extensions to avoid wedging\n // the regex engine on minified bundles, fixtures, or vendored blobs.\n if (!isSourceCodeFile(file)) {\n try {\n if (await isBinaryFileAsync(file)) {\n return { file, identifiers: 0, secrets: 0, secretTypes: [], skipped: \"binary\", sizeBytes: size };\n }\n } catch {\n /* fall through and try to read */\n }\n }\n\n let code: string;\n try {\n code = await readFile(file, \"utf-8\");\n } catch {\n return { file, identifiers: 0, secrets: 0, secretTypes: [], skipped: \"read-error\", sizeBytes: size };\n }\n\n const lang = langFromExt(file);\n let identifiers = 0;\n if (!opts.secretsOnly && isSourceCodeFile(file)) {\n try {\n const scanResult = scan(code, lang);\n identifiers = scanResult.tokens.length;\n } catch {\n /* identifier scan failures are non-fatal */\n }\n }\n\n let blocked: Array<{ type: string }> = [];\n try {\n const secretResult = scanSecrets(code);\n blocked = secretResult.matches.filter((m) => m.action === \"block\" || m.action === \"redact\");\n } catch {\n /* secret scan failures are non-fatal */\n }\n\n return {\n file,\n identifiers,\n secrets: blocked.length,\n secretTypes: blocked.map((m) => m.type),\n sizeBytes: size,\n };\n}\n\n/**\n * Process `files` with bounded concurrency, streaming progress to stderr\n * and listening for SIGINT/SIGTERM so partial results can be flushed.\n */\nasync function scanFilesParallel(\n files: string[],\n opts: { secretsOnly: boolean; maxFileSize: number; quiet: boolean; concurrency: number },\n): Promise<{ results: ScanRowResult[]; interrupted: boolean }> {\n const results: ScanRowResult[] = [];\n let cursor = 0;\n let done = 0;\n let lastPrint = 0;\n let interrupted = false;\n\n const stopHandler = (): void => { interrupted = true; };\n process.on(\"SIGINT\", stopHandler);\n process.on(\"SIGTERM\", stopHandler);\n\n const isTTY = process.stderr.isTTY === true;\n const printProgress = (force = false): void => {\n if (opts.quiet) return;\n const now = Date.now();\n if (!force && now - lastPrint < PROGRESS_INTERVAL_MS) return;\n lastPrint = now;\n const found = results.reduce((acc, r) => acc + r.secrets, 0);\n const msg = `Scanning ${done}/${files.length} files (${found} secrets so far)...`;\n if (isTTY) {\n process.stderr.write(`\\r\\x1b[K${msg}`);\n } else {\n process.stderr.write(`${msg}\\n`);\n }\n };\n\n async function worker(): Promise<void> {\n while (!interrupted) {\n const i = cursor++;\n if (i >= files.length) return;\n const file = files[i]!;\n const row = await scanOneFile(file, { secretsOnly: opts.secretsOnly, maxFileSize: opts.maxFileSize });\n if (row) results.push(row);\n done++;\n printProgress();\n }\n }\n\n printProgress(true);\n const workers = Array.from({ length: Math.min(opts.concurrency, files.length || 1) }, () => worker());\n await Promise.all(workers);\n\n process.removeListener(\"SIGINT\", stopHandler);\n process.removeListener(\"SIGTERM\", stopHandler);\n\n if (!opts.quiet && isTTY) {\n process.stderr.write(`\\r\\x1b[K`);\n }\n return { results, interrupted };\n}\n\nfunction parseSizeOption(value: string): number | null {\n // Accept plain bytes, or \"10m\" / \"10mb\" / \"500k\" / \"500kb\"\n const trimmed = value.trim().toLowerCase();\n const m = /^(\\d+(?:\\.\\d+)?)\\s*(b|k|kb|m|mb|g|gb)?$/.exec(trimmed);\n if (!m) return null;\n const n = parseFloat(m[1]!);\n if (!isFinite(n) || n <= 0) return null;\n const unit = m[2] ?? \"b\";\n const mult = unit.startsWith(\"g\") ? 1024 ** 3 : unit.startsWith(\"m\") ? 1024 ** 2 : unit.startsWith(\"k\") ? 1024 : 1;\n return Math.floor(n * mult);\n}\n\nprogram\n .command(\"scan <target>\")\n .description(\"Scan file or directory for identifiers and secrets (no mutation)\")\n .option(\"--secrets-only\", \"Only scan for secrets/credentials\", false)\n .option(\"--json\", \"Output as JSON\", false)\n .option(\"--max-file-size <size>\", \"Skip files larger than this (e.g. 10mb, 500k)\", \"10mb\")\n .option(\"--concurrency <n>\", \"Max files scanned in parallel\", String(SCAN_CONCURRENCY))\n .option(\"--quiet\", \"Suppress progress output\", false)\n .action(async (\n target: string,\n opts: { secretsOnly: boolean; json: boolean; maxFileSize: string; concurrency: string; quiet: boolean },\n ) => {\n const absTarget = resolve(target);\n if (!existsSync(absTarget)) {\n console.error(chalk.red(\"Error: Path not found:\"), chalk.bold(absTarget));\n process.exit(1);\n }\n\n const maxFileSize = parseSizeOption(opts.maxFileSize);\n if (maxFileSize === null) {\n console.error(chalk.red(\"Error: Invalid --max-file-size value:\"), chalk.bold(opts.maxFileSize));\n console.error(chalk.gray(\"Use bytes or a unit suffix, e.g. 10mb, 500k, 1048576\"));\n process.exit(1);\n }\n const concurrency = Math.max(1, parseInt(opts.concurrency, 10) || SCAN_CONCURRENCY);\n\n if (!opts.quiet && !opts.json) {\n process.stderr.write(chalk.gray(`Discovering files in ${absTarget}...\\n`));\n }\n const files = collectFiles(target);\n if (files.length === 0) {\n console.error(chalk.red(\"Error: No source files found at\"), chalk.bold(absTarget));\n console.error(chalk.gray(\"Supported extensions: \" + [...SUPPORTED_EXTENSIONS].join(\", \")));\n process.exit(1);\n }\n if (!opts.quiet && !opts.json) {\n process.stderr.write(chalk.gray(`Found ${files.length} candidate files. Scanning with concurrency=${concurrency}...\\n`));\n }\n\n const startedAt = Date.now();\n const { results: allResults, interrupted } = await scanFilesParallel(files, {\n secretsOnly: opts.secretsOnly,\n maxFileSize,\n quiet: opts.quiet || opts.json,\n concurrency,\n });\n const elapsedMs = Date.now() - startedAt;\n\n const totalIdentifiers = allResults.reduce((acc, r) => acc + r.identifiers, 0);\n const totalSecrets = allResults.reduce((acc, r) => acc + r.secrets, 0);\n const skippedLarge = allResults.filter((r) => r.skipped === \"too-large\").length;\n const skippedBinary = allResults.filter((r) => r.skipped === \"binary\").length;\n\n if (opts.json) {\n console.log(JSON.stringify({\n files: allResults,\n totalIdentifiers,\n totalSecrets,\n skippedLarge,\n skippedBinary,\n elapsedMs,\n interrupted,\n }, null, 2));\n } else {\n console.log(chalk.cyan(\"\\nPretense Scan Results\\n\"));\n for (const r of allResults) {\n if (r.skipped) {\n if (r.skipped === \"too-large\") {\n const mb = ((r.sizeBytes ?? 0) / 1024 / 1024).toFixed(1);\n console.log(chalk.gray(` ${r.file} — skipped (${mb} MB > limit)`));\n }\n continue;\n }\n const secretBadge = r.secrets > 0\n ? chalk.red(` [${r.secrets} SECRET${r.secrets > 1 ? \"S\" : \"\"}]`)\n : \"\";\n const showRow = r.secrets > 0 || (!opts.secretsOnly && r.identifiers > 0);\n if (!showRow) continue;\n console.log(\n chalk.gray(\" \") + chalk.white(r.file) + chalk.gray(` — ${r.identifiers} identifiers`) + secretBadge,\n );\n if (r.secrets > 0) {\n for (const t of r.secretTypes) {\n console.log(chalk.red(` ! ${t}`));\n }\n }\n }\n const skipNote = skippedLarge + skippedBinary > 0\n ? chalk.gray(` (skipped ${skippedLarge} large, ${skippedBinary} binary)`)\n : \"\";\n console.log(\n chalk.gray(`\\n Total: ${allResults.length} files in ${(elapsedMs / 1000).toFixed(2)}s, ${totalIdentifiers} identifiers, `) +\n (totalSecrets > 0 ? chalk.red(`${totalSecrets} secrets found`) : chalk.green(\"0 secrets\")) +\n skipNote,\n );\n if (interrupted) {\n console.log(chalk.yellow(\"\\n Interrupted — partial results shown above.\"));\n }\n console.log();\n }\n\n if (!opts.json) {\n printTokenFooter(allResults.length, totalIdentifiers);\n }\n\n if (interrupted) {\n // Flushed partial results; signal interruption with non-zero exit.\n process.exit(130);\n }\n // Exit code 2 if secrets found\n if (totalSecrets > 0) {\n process.exit(2);\n }\n });\n\n// ── mutate ────────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"mutate <file>\")\n .description(\"Mutate a file and print result to stdout\")\n .option(\"-s, --seed <seed>\", \"Mutation seed\", \"pretense\")\n .option(\"-l, --language <lang>\", \"Source language (typescript, javascript, python, go, java, csharp, ruby, rust)\")\n .option(\"--save\", \"Save mutation map to .pretense/\", false)\n .option(\"--json\", \"Output as JSON (includes map + stats)\", false)\n .action((file: string, opts: { seed: string; language?: string; save: boolean; json: boolean }) => {\n const absPath = resolve(file);\n if (!existsSync(absPath)) {\n console.error(chalk.red(\"Error: File not found:\"), chalk.bold(absPath));\n process.exit(1);\n }\n\n // Validate language option if provided\n if (opts.language) {\n const validLang = validateLanguage(opts.language);\n if (!validLang) {\n console.error(chalk.red(\"Error: Unsupported language:\"), chalk.bold(opts.language));\n console.error(chalk.gray(\"Supported languages: \" + SUPPORTED_LANGUAGES.join(\", \")));\n process.exit(1);\n }\n }\n\n // Check for binary files\n if (!SUPPORTED_EXTENSIONS.has(extname(absPath).toLowerCase()) && isBinaryFile(absPath)) {\n console.error(chalk.red(\"Error: Not a supported source file:\"), chalk.bold(absPath));\n console.error(chalk.gray(\"Supported extensions: \" + [...SUPPORTED_EXTENSIONS].join(\", \")));\n process.exit(1);\n }\n\n const code = readFileSync(absPath, \"utf-8\");\n const lang = opts.language ? validateLanguage(opts.language)! : langFromExt(absPath);\n const result = mutate(code, lang, opts.seed);\n\n if (opts.save) {\n const configDir = getConfigDir();\n const store = new MutationStore(join(configDir, \"mutation-map.json\"));\n store.load();\n store.save({\n id: absPath,\n originalHash: absPath,\n mapEntries: MutationStore.fromMap(result.map),\n timestamp: Date.now(),\n language: lang,\n });\n store.persist();\n process.stderr.write(chalk.gray(`Mutation map saved to ${configDir}/mutation-map.json\\n`));\n }\n\n if (opts.json) {\n console.log(JSON.stringify({\n mutatedCode: result.mutatedCode,\n map: Object.fromEntries(result.map),\n stats: result.stats,\n }, null, 2));\n } else {\n process.stdout.write(result.mutatedCode);\n process.stderr.write(chalk.gray(`\\n--- ${result.stats.tokensMutated} identifiers mutated in ${result.stats.durationMs}ms ---\\n`));\n printTokenFooter(1, result.stats.tokensMutated);\n }\n });\n\n// ── reverse ───────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"reverse <file>\")\n .description(\"Reverse mutations using stored map\")\n .option(\"-m, --map <path>\", \"Path to mutation map JSON file\")\n .action((file: string, opts: { map?: string }) => {\n const absPath = resolve(file);\n if (!existsSync(absPath)) {\n console.error(chalk.red(\"Error: File not found:\"), chalk.bold(absPath));\n process.exit(1);\n }\n\n const mutatedCode = readFileSync(absPath, \"utf-8\");\n\n // Load map from specified path or .pretense/mutation-map.json\n const mapPath = opts.map\n ? resolve(opts.map)\n : join(getConfigDir(), \"mutation-map.json\");\n\n if (!existsSync(mapPath)) {\n console.error(chalk.red(\"Error: Mutation map not found:\"), chalk.bold(mapPath));\n console.error(chalk.gray(\"Run 'pretense mutate --save' first, or specify --map <path>\"));\n process.exit(1);\n }\n\n let store: MutationStore;\n try {\n store = new MutationStore(mapPath);\n store.load();\n } catch {\n console.error(chalk.red(\"Error: Failed to load mutation map:\"), chalk.bold(mapPath));\n console.error(chalk.gray(\"The file may be corrupted. Run 'pretense mutate --save' to regenerate.\"));\n process.exit(1);\n }\n\n // Try to find map by file path, or use the most recent entry\n const entry = store.get(absPath) ?? store.getByHash(absPath) ?? store.list(1)[0];\n if (!entry) {\n console.error(chalk.red(\"Error: No mutation map entries found.\"));\n console.error(chalk.gray(\"Run 'pretense mutate --save <file>' first to generate a map.\"));\n process.exit(1);\n }\n\n const map = MutationStore.toMap(entry);\n const restored = reverse(mutatedCode, map);\n\n process.stdout.write(restored);\n process.stderr.write(chalk.gray(`\\n--- Reversed ${map.size} mutations ---\\n`));\n });\n\n// ── audit ─────────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"audit\")\n .description(\"View the audit log\")\n .option(\"--json\", \"Output as JSON\", false)\n .option(\"--csv\", \"Output as CSV\", false)\n .option(\"-l, --limit <number>\", \"Limit entries\", \"50\")\n .action((opts: { json: boolean; csv: boolean; limit: string }) => {\n const format = opts.json ? \"json\" : opts.csv ? \"csv\" : \"text\";\n const limit = parseInt(opts.limit) || 50;\n\n const entries = readAuditLog({ limit, format });\n const output = formatAudit(entries, format);\n console.log(output);\n });\n\n// ── version ───────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"version\")\n .description(\"Print Pretense CLI version\")\n .action(() => {\n console.log(`@pretense/cli v${VERSION}`);\n });\n\n// ── status / usage / tokens ─────────────────────────────────────────────────\n\nprogram\n .command(\"status\")\n .description(\"Show current plan, monthly quota, seat usage\")\n .action(() => {\n runStatus();\n });\n\nprogram\n .command(\"usage\")\n .description(\"Alias for `pretense status` — show monthly quota usage\")\n .action(() => {\n runStatus();\n });\n\nprogram\n .command(\"tokens\")\n .description(\"Alias for `pretense credits` — show remaining mutation budget\")\n .action(() => {\n runCredits();\n });\n\n// ── upgrade / credits ────────────────────────────────────────────────────────\n\nprogram\n .command(\"upgrade\")\n .description(\"Compare plans and upgrade to Pro or Enterprise\")\n .action(() => {\n runUpgrade();\n });\n\nprogram\n .command(\"credits\")\n .description(\"Show remaining mutation/scan budget for the current month\")\n .action(() => {\n runCredits();\n });\n\n// ── login ─────────────────────────────────────────────────────────────────────\n\nprogram\n .command(\"login\")\n .description(\"Save a Pretense API key to ~/.pretense/config.json for future CLI runs\")\n .option(\"-k, --key <key>\", \"API key (pk_live_...). If omitted, read from $PRETENSE_API_KEY or stdin.\")\n .action((opts: { key?: string }) => {\n const code = runLogin({ key: opts.key });\n if (code !== 0) process.exit(code);\n });\n\n// ─── Global error handler ───────────────────────────────────────────────────\n\nfunction handleFatalError(err: unknown): void {\n if (err instanceof Error && err.message) {\n console.error(chalk.red(\"Error:\"), err.message);\n } else {\n console.error(chalk.red(\"An unexpected error occurred.\"));\n }\n process.exit(1);\n}\n\nprocess.on(\"uncaughtException\", handleFatalError);\nprocess.on(\"unhandledRejection\", handleFatalError);\n\n// ─── Parse and run ───────────────────────────────────────────────────────────\n\nprogram\n .showSuggestionAfterError(true)\n .showHelpAfterError(\"(use --help for available commands)\");\n\nprogram.parse();\n","/**\n * Pretense Core — Shared Types\n * All domain interfaces and enums used across the mutation pipeline.\n */\n\n// ─── Token Types ───────────────────────────────────────────────────────────────\n\nexport enum TokenType {\n Variable = \"Variable\",\n Function = \"Function\",\n Class = \"Class\",\n String = \"String\",\n Comment = \"Comment\",\n Import = \"Import\",\n Property = \"Property\",\n Method = \"Method\",\n}\n\nexport interface Token {\n type: TokenType;\n value: string;\n start: number;\n end: number;\n line: number;\n}\n\n// ─── Scan ──────────────────────────────────────────────────────────────────────\n\nexport interface ScanResult {\n tokens: Token[];\n language: string;\n}\n\n// ─── Mutation ─────────────────────────────────────────────────────────────────\n\nexport interface MutationRule {\n /** Token type this rule targets */\n tokenType: TokenType;\n /** Whether to strip this token type entirely (e.g. comments) */\n strip?: boolean;\n /** Custom prefix to use instead of the default per-type prefix */\n prefix?: string;\n}\n\n/**\n * Maps every original token value to its mutated synthetic.\n * Used during forward mutation and exact reversal.\n */\nexport type MutationMap = Map<string, string>;\n\nexport interface MutationStats {\n tokensScanned: number;\n tokensMutated: number;\n durationMs: number;\n language: string;\n}\n\nexport interface MutationResult {\n mutatedCode: string;\n map: MutationMap;\n stats: MutationStats;\n}\n\n// ─── Store ────────────────────────────────────────────────────────────────────\n\nexport interface StoreEntry {\n id: string;\n originalHash: string;\n /** Serialized MutationMap (array of [original, synthetic] tuples) */\n mapEntries: [string, string][];\n timestamp: number;\n language: string;\n}\n\n// ─── Proxy ────────────────────────────────────────────────────────────────────\n\nexport interface ProxyRequest {\n body: string;\n targetUrl: string;\n headers: Record<string, string>;\n}\n\nexport interface ProxyResponse {\n body: string;\n statusCode: number;\n reversed: boolean;\n}\n\n// ─── Config ───────────────────────────────────────────────────────────────────\n\nexport interface PretenseConfig {\n port: number;\n targetApis: string[];\n languages: string[];\n mutationRules: MutationRule[];\n storePath: string;\n}\n\nexport const DEFAULT_CONFIG: PretenseConfig = {\n port: 9339,\n targetApis: [\"https://api.anthropic.com\", \"https://api.openai.com\"],\n languages: [\"typescript\", \"javascript\", \"python\", \"go\", \"java\", \"csharp\", \"ruby\", \"rust\"],\n mutationRules: [\n { tokenType: TokenType.Variable, prefix: \"_v\" },\n { tokenType: TokenType.Function, prefix: \"_fn\" },\n { tokenType: TokenType.Class, prefix: \"_cls\" },\n { tokenType: TokenType.String },\n { tokenType: TokenType.Comment, strip: true },\n { tokenType: TokenType.Import },\n { tokenType: TokenType.Property, prefix: \"_prop\" },\n { tokenType: TokenType.Method, prefix: \"_fn\" },\n ],\n storePath: `${process.env[\"HOME\"] ?? \"/tmp\"}/.pretense`,\n};\n","/**\n * Pretense Core — Token Scanner\n *\n * Regex-based token scanner for TypeScript/JavaScript, Python, Go, and Java.\n * Extracts mutable tokens (variables, functions, classes, strings, imports,\n * comments) with exact positions for accurate reversal.\n *\n * No tree-sitter dependency — pure regex MVP, production-ready accuracy.\n */\n\nimport { TokenType, type Token, type ScanResult } from \"./types.js\";\n\n// ─── Language keyword sets ─────────────────────────────────────────────────────\n\nconst TS_JS_KEYWORDS = new Set([\n \"abstract\", \"any\", \"as\", \"async\", \"await\", \"boolean\", \"break\", \"case\",\n \"catch\", \"class\", \"const\", \"constructor\", \"continue\", \"debugger\", \"declare\",\n \"default\", \"delete\", \"do\", \"else\", \"enum\", \"export\", \"extends\", \"false\",\n \"finally\", \"for\", \"from\", \"function\", \"get\", \"if\", \"implements\", \"import\",\n \"in\", \"instanceof\", \"interface\", \"keyof\", \"let\", \"module\", \"namespace\",\n \"never\", \"new\", \"null\", \"number\", \"object\", \"of\", \"package\", \"private\",\n \"protected\", \"public\", \"readonly\", \"require\", \"return\", \"set\", \"static\",\n \"string\", \"super\", \"switch\", \"symbol\", \"this\", \"throw\", \"true\", \"try\",\n \"type\", \"typeof\", \"undefined\", \"unknown\", \"var\", \"void\", \"while\", \"with\",\n \"yield\", \"satisfies\", \"using\", \"infer\", \"asserts\",\n]);\n\nconst PYTHON_KEYWORDS = new Set([\n \"False\", \"None\", \"True\", \"and\", \"as\", \"assert\", \"async\", \"await\",\n \"break\", \"class\", \"continue\", \"def\", \"del\", \"elif\", \"else\", \"except\",\n \"finally\", \"for\", \"from\", \"global\", \"if\", \"import\", \"in\", \"is\",\n \"lambda\", \"nonlocal\", \"not\", \"or\", \"pass\", \"raise\", \"return\", \"try\",\n \"while\", \"with\", \"yield\", \"self\", \"cls\",\n]);\n\nconst GO_KEYWORDS = new Set([\n \"break\", \"case\", \"chan\", \"const\", \"continue\", \"default\", \"defer\", \"else\",\n \"fallthrough\", \"for\", \"func\", \"go\", \"goto\", \"if\", \"import\", \"interface\",\n \"map\", \"package\", \"range\", \"return\", \"select\", \"struct\", \"switch\", \"type\",\n \"var\", \"nil\", \"true\", \"false\", \"error\", \"string\", \"int\", \"int8\", \"int16\",\n \"int32\", \"int64\", \"uint\", \"uint8\", \"uint16\", \"uint32\", \"uint64\", \"float32\",\n \"float64\", \"complex64\", \"complex128\", \"bool\", \"byte\", \"rune\", \"uintptr\",\n \"make\", \"new\", \"len\", \"cap\", \"append\", \"copy\", \"close\", \"delete\", \"panic\",\n \"recover\", \"print\", \"println\",\n]);\n\nconst JAVA_KEYWORDS = new Set([\n \"abstract\", \"assert\", \"boolean\", \"break\", \"byte\", \"case\", \"catch\", \"char\",\n \"class\", \"const\", \"continue\", \"default\", \"do\", \"double\", \"else\", \"enum\",\n \"extends\", \"final\", \"finally\", \"float\", \"for\", \"goto\", \"if\", \"implements\",\n \"import\", \"instanceof\", \"int\", \"interface\", \"long\", \"native\", \"new\",\n \"package\", \"private\", \"protected\", \"public\", \"return\", \"short\", \"static\",\n \"strictfp\", \"super\", \"switch\", \"synchronized\", \"this\", \"throw\", \"throws\",\n \"transient\", \"try\", \"void\", \"volatile\", \"while\", \"true\", \"false\", \"null\",\n \"var\", \"record\", \"sealed\", \"permits\", \"yield\",\n]);\n\nconst CSHARP_KEYWORDS = new Set([\n \"class\", \"interface\", \"namespace\", \"public\", \"private\", \"protected\",\n \"internal\", \"static\", \"void\", \"return\", \"new\", \"using\", \"override\", \"sealed\",\n \"abstract\", \"virtual\", \"readonly\", \"const\", \"var\", \"int\", \"string\", \"bool\",\n \"double\", \"float\", \"object\", \"null\", \"true\", \"false\", \"if\", \"else\", \"for\",\n \"foreach\", \"while\", \"do\", \"switch\", \"case\", \"break\", \"continue\", \"try\",\n \"catch\", \"finally\", \"throw\", \"async\", \"await\", \"get\", \"set\", \"partial\",\n \"enum\", \"struct\", \"delegate\", \"event\",\n]);\n\nconst RUBY_KEYWORDS = new Set([\n \"def\", \"class\", \"module\", \"end\", \"do\", \"if\", \"else\", \"elsif\", \"unless\",\n \"while\", \"until\", \"for\", \"begin\", \"rescue\", \"ensure\", \"raise\", \"return\",\n \"yield\", \"self\", \"super\", \"true\", \"false\", \"nil\", \"and\", \"or\", \"not\", \"in\",\n \"then\", \"case\", \"when\", \"puts\", \"print\", \"require\", \"require_relative\",\n \"include\", \"extend\", \"attr_accessor\", \"attr_reader\", \"attr_writer\",\n \"initialize\", \"new\", \"public\", \"private\", \"protected\",\n]);\n\nconst RUST_KEYWORDS = new Set([\n \"fn\", \"struct\", \"enum\", \"trait\", \"impl\", \"mod\", \"pub\", \"let\", \"mut\",\n \"const\", \"type\", \"use\", \"crate\", \"self\", \"super\", \"move\", \"ref\", \"match\",\n \"if\", \"else\", \"loop\", \"while\", \"for\", \"return\", \"break\", \"continue\",\n \"where\", \"as\", \"in\", \"true\", \"false\", \"unsafe\", \"extern\", \"dyn\", \"box\",\n \"static\", \"async\", \"await\", \"Box\", \"String\", \"Vec\", \"Option\", \"Result\",\n \"Ok\", \"Err\", \"Some\", \"None\",\n]);\n\n// ─── Language detection ────────────────────────────────────────────────────────\n\n/**\n * Detect the programming language from code heuristics.\n *\n * @example\n * detectLanguage(\"const x: number = 1;\") // => \"typescript\"\n * detectLanguage(\"def foo(x):\\n return x\") // => \"python\"\n */\nexport function detectLanguage(code: string): string {\n if (/:[\\s]*\\w+[\\s]*[;,{)]/.test(code) || /import.*from\\s+['\"]/.test(code) || /interface\\s+\\w+/.test(code)) return \"typescript\";\n if (/\\bdef\\s+\\w+\\s*\\(/.test(code) || /\\bimport\\s+\\w+/.test(code) && /:$/.test(code)) return \"python\";\n if (/\\bfunc\\s+\\w+\\s*\\(/.test(code) || /\\bpackage\\s+\\w+/.test(code)) return \"go\";\n if (/\\bpublic\\s+class\\s+\\w+/.test(code) || /\\bimport\\s+java\\./.test(code)) return \"java\";\n if (/\\bnamespace\\s+\\w+/.test(code) || /\\busing\\s+System/.test(code)) return \"csharp\";\n if (/\\bfn\\s+\\w+\\s*\\(/.test(code) || /\\blet\\s+mut\\s+\\w+/.test(code)) return \"rust\";\n if (/\\bdef\\s+\\w+/.test(code) && /\\bend\\b/.test(code)) return \"ruby\";\n if (/\\bconst\\s+\\w+\\s*=/.test(code) || /\\bfunction\\s+\\w+\\s*\\(/.test(code)) return \"javascript\";\n return \"typescript\"; // default\n}\n\n// ─── Line-number helper ────────────────────────────────────────────────────────\n\n/**\n * Build a sorted array of newline byte offsets so we can convert any\n * index → 1-based line number in O(log lines) via binary search.\n *\n * Replaces the old per-call O(N) lineAt() walk. On a 400 KB file with\n * 7K tokens, the old impl was ~3 billion char comparisons (O(tokens × file))\n * which made the scanner appear to hang on real-world repos.\n */\nfunction buildLineIndex(code: string): number[] {\n const offsets: number[] = [];\n for (let i = 0; i < code.length; i++) {\n if (code.charCodeAt(i) === 10 /* \\n */) offsets.push(i);\n }\n return offsets;\n}\n\nfunction lineFromIndex(lineOffsets: number[], index: number): number {\n // Binary search for first newline >= index. Lines are 1-based.\n let lo = 0;\n let hi = lineOffsets.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (lineOffsets[mid]! < index) lo = mid + 1;\n else hi = mid;\n }\n return lo + 1;\n}\n\n// ─── Per-language scanners ─────────────────────────────────────────────────────\n\nfunction scanTypeScript(code: string): Token[] {\n const tokens: Token[] = [];\n if (!code.trim()) return tokens;\n const lineOffsets = buildLineIndex(code);\n\n const patterns: Array<{ re: RegExp; type: TokenType; groupIndex?: number }> = [\n // Single-line comment\n { re: /\\/\\/[^\\n]*/g, type: TokenType.Comment },\n // Multi-line comment\n { re: /\\/\\*[\\s\\S]*?\\*\\//g, type: TokenType.Comment },\n // Import source (the module path string)\n { re: /\\bimport\\b[^'\"]*['\"]([^'\"]+)['\"]/g, type: TokenType.Import, groupIndex: 1 },\n // Class name\n { re: /\\bclass\\s+([A-Za-z_$][A-Za-z0-9_$]*)/g, type: TokenType.Class, groupIndex: 1 },\n // Function/method name (function keyword)\n { re: /\\bfunction\\s+([A-Za-z_$][A-Za-z0-9_$]*)/g, type: TokenType.Function, groupIndex: 1 },\n // Arrow function assigned to const/let/var\n { re: /\\b(?:const|let|var)\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*=\\s*(?:async\\s*)?\\(/g, type: TokenType.Function, groupIndex: 1 },\n // Method: identifier followed by (\n { re: /\\b([A-Za-z_$][A-Za-z0-9_$]*)\\s*\\(/g, type: TokenType.Method, groupIndex: 1 },\n // Variable declarations\n { re: /\\b(?:const|let|var)\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\b/g, type: TokenType.Variable, groupIndex: 1 },\n // Template literals (preserve backtick wrapper)\n { re: /`[^`]*`/g, type: TokenType.String },\n // Double-quoted strings\n { re: /\"(?:[^\"\\\\]|\\\\.)*\"/g, type: TokenType.String },\n // Single-quoted strings\n { re: /'(?:[^'\\\\]|\\\\.)*'/g, type: TokenType.String },\n ];\n\n for (const { re, type, groupIndex } of patterns) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(code)) !== null) {\n const fullMatch = m[0];\n const captureValue = groupIndex !== undefined ? (m[groupIndex] ?? fullMatch) : fullMatch;\n const captureStart = groupIndex !== undefined\n ? m.index + fullMatch.indexOf(captureValue)\n : m.index;\n\n if (!captureValue || captureValue.trim() === \"\") continue;\n\n // Skip language keywords for identifier tokens\n if (\n type === TokenType.Variable ||\n type === TokenType.Function ||\n type === TokenType.Class ||\n type === TokenType.Method ||\n type === TokenType.Property\n ) {\n if (TS_JS_KEYWORDS.has(captureValue)) continue;\n // Skip console/process/Object etc.\n if (/^(console|process|Object|Array|Math|JSON|Promise|Error|Map|Set|Date|RegExp|Symbol|Proxy|Reflect|global|globalThis|window|document|module|exports|require|__dirname|__filename)$/.test(captureValue)) continue;\n // Skip single-character identifiers (loop vars, etc.)\n if (captureValue.length <= 1) continue;\n }\n\n tokens.push({\n type,\n value: captureValue,\n start: captureStart,\n end: captureStart + captureValue.length,\n line: lineFromIndex(lineOffsets, captureStart),\n });\n }\n }\n\n return deduplicate(tokens);\n}\n\nfunction scanPython(code: string): Token[] {\n const tokens: Token[] = [];\n if (!code.trim()) return tokens;\n const lineOffsets = buildLineIndex(code);\n\n const patterns: Array<{ re: RegExp; type: TokenType; groupIndex?: number }> = [\n // Triple-quoted docstrings\n { re: /\"\"\"[\\s\\S]*?\"\"\"|'''[\\s\\S]*?'''/g, type: TokenType.Comment },\n // Line comments\n { re: /#[^\\n]*/g, type: TokenType.Comment },\n // Import module name\n { re: /\\bimport\\s+([A-Za-z_][A-Za-z0-9_.]*)/g, type: TokenType.Import, groupIndex: 1 },\n { re: /\\bfrom\\s+([A-Za-z_.][A-Za-z0-9_.]*)\\s+import/g, type: TokenType.Import, groupIndex: 1 },\n // Class name\n { re: /\\bclass\\s+([A-Za-z_][A-Za-z0-9_]*)/g, type: TokenType.Class, groupIndex: 1 },\n // Function/method def\n { re: /\\bdef\\s+([A-Za-z_][A-Za-z0-9_]*)/g, type: TokenType.Function, groupIndex: 1 },\n // Variable assignment (simple name = ...)\n { re: /^([A-Za-z_][A-Za-z0-9_]*)\\s*=/gm, type: TokenType.Variable, groupIndex: 1 },\n // Double-quoted strings\n { re: /\"(?:[^\"\\\\]|\\\\.)*\"/g, type: TokenType.String },\n // Single-quoted strings\n { re: /'(?:[^'\\\\]|\\\\.)*'/g, type: TokenType.String },\n ];\n\n for (const { re, type, groupIndex } of patterns) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(code)) !== null) {\n const fullMatch = m[0];\n const captureValue = groupIndex !== undefined ? (m[groupIndex] ?? fullMatch) : fullMatch;\n const captureStart = groupIndex !== undefined\n ? m.index + fullMatch.indexOf(captureValue)\n : m.index;\n\n if (!captureValue || captureValue.trim() === \"\") continue;\n\n if (\n type === TokenType.Variable ||\n type === TokenType.Function ||\n type === TokenType.Class\n ) {\n if (PYTHON_KEYWORDS.has(captureValue)) continue;\n if (captureValue.length <= 1) continue;\n // Skip dunder methods/vars\n if (captureValue.startsWith(\"__\") && captureValue.endsWith(\"__\")) continue;\n }\n\n tokens.push({\n type,\n value: captureValue,\n start: captureStart,\n end: captureStart + captureValue.length,\n line: lineFromIndex(lineOffsets, captureStart),\n });\n }\n }\n\n return deduplicate(tokens);\n}\n\nfunction scanGo(code: string): Token[] {\n const tokens: Token[] = [];\n if (!code.trim()) return tokens;\n const lineOffsets = buildLineIndex(code);\n\n const patterns: Array<{ re: RegExp; type: TokenType; groupIndex?: number }> = [\n { re: /\\/\\/[^\\n]*/g, type: TokenType.Comment },\n { re: /\\/\\*[\\s\\S]*?\\*\\//g, type: TokenType.Comment },\n // Import path\n { re: /import\\s*\\(\\s*([\\s\\S]*?)\\s*\\)/g, type: TokenType.Import },\n { re: /import\\s+\"([^\"]+)\"/g, type: TokenType.Import, groupIndex: 1 },\n // Type declaration\n { re: /\\btype\\s+([A-Za-z_][A-Za-z0-9_]*)\\s+(?:struct|interface)/g, type: TokenType.Class, groupIndex: 1 },\n // Func name\n { re: /\\bfunc\\s+(?:\\([^)]*\\)\\s*)?([A-Za-z_][A-Za-z0-9_]*)\\s*\\(/g, type: TokenType.Function, groupIndex: 1 },\n // Var/const declaration\n { re: /\\b(?:var|const)\\s+([A-Za-z_][A-Za-z0-9_]*)\\b/g, type: TokenType.Variable, groupIndex: 1 },\n // Short variable declaration\n { re: /\\b([A-Za-z_][A-Za-z0-9_]*)\\s*:=/g, type: TokenType.Variable, groupIndex: 1 },\n // Double-quoted strings\n { re: /\"(?:[^\"\\\\]|\\\\.)*\"/g, type: TokenType.String },\n // Backtick raw strings\n { re: /`[^`]*`/g, type: TokenType.String },\n ];\n\n for (const { re, type, groupIndex } of patterns) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(code)) !== null) {\n const fullMatch = m[0];\n const captureValue = groupIndex !== undefined ? (m[groupIndex] ?? fullMatch) : fullMatch;\n const captureStart = groupIndex !== undefined\n ? m.index + fullMatch.indexOf(captureValue)\n : m.index;\n\n if (!captureValue || captureValue.trim() === \"\") continue;\n\n if (\n type === TokenType.Variable ||\n type === TokenType.Function ||\n type === TokenType.Class\n ) {\n if (GO_KEYWORDS.has(captureValue)) continue;\n if (captureValue.length <= 1) continue;\n }\n\n tokens.push({\n type,\n value: captureValue,\n start: captureStart,\n end: captureStart + captureValue.length,\n line: lineFromIndex(lineOffsets, captureStart),\n });\n }\n }\n\n return deduplicate(tokens);\n}\n\nfunction scanJava(code: string): Token[] {\n const tokens: Token[] = [];\n if (!code.trim()) return tokens;\n const lineOffsets = buildLineIndex(code);\n\n const patterns: Array<{ re: RegExp; type: TokenType; groupIndex?: number }> = [\n { re: /\\/\\/[^\\n]*/g, type: TokenType.Comment },\n { re: /\\/\\*[\\s\\S]*?\\*\\//g, type: TokenType.Comment },\n // Import statement\n { re: /\\bimport\\s+([\\w.]+);/g, type: TokenType.Import, groupIndex: 1 },\n // Class/interface/enum\n { re: /\\b(?:class|interface|enum|record)\\s+([A-Za-z_$][A-Za-z0-9_$]*)/g, type: TokenType.Class, groupIndex: 1 },\n // Method declaration\n { re: /\\b(?:public|private|protected|static|final|abstract|synchronized|native|default)[\\w\\s<>\\[\\],]*\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*\\(/g, type: TokenType.Method, groupIndex: 1 },\n // Variable declaration\n { re: /\\b(?:int|long|double|float|boolean|char|byte|short|String|Object|var)\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*[=;,)]/g, type: TokenType.Variable, groupIndex: 1 },\n // Double-quoted strings\n { re: /\"(?:[^\"\\\\]|\\\\.)*\"/g, type: TokenType.String },\n ];\n\n for (const { re, type, groupIndex } of patterns) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(code)) !== null) {\n const fullMatch = m[0];\n const captureValue = groupIndex !== undefined ? (m[groupIndex] ?? fullMatch) : fullMatch;\n const captureStart = groupIndex !== undefined\n ? m.index + fullMatch.indexOf(captureValue)\n : m.index;\n\n if (!captureValue || captureValue.trim() === \"\") continue;\n\n if (\n type === TokenType.Variable ||\n type === TokenType.Method ||\n type === TokenType.Class\n ) {\n if (JAVA_KEYWORDS.has(captureValue)) continue;\n if (captureValue.length <= 1) continue;\n // Skip common stdlib class names\n if (/^(String|Object|Integer|Long|Double|Boolean|List|Map|Set|Array|Exception|Error|System|Math|Thread|Class|Enum)$/.test(captureValue)) continue;\n }\n\n tokens.push({\n type,\n value: captureValue,\n start: captureStart,\n end: captureStart + captureValue.length,\n line: lineFromIndex(lineOffsets, captureStart),\n });\n }\n }\n\n return deduplicate(tokens);\n}\n\nfunction scanCSharp(code: string): Token[] {\n const tokens: Token[] = [];\n if (!code.trim()) return tokens;\n const lineOffsets = buildLineIndex(code);\n\n const patterns: Array<{ re: RegExp; type: TokenType; groupIndex?: number }> = [\n { re: /\\/\\/[^\\n]*/g, type: TokenType.Comment },\n { re: /\\/\\*[\\s\\S]*?\\*\\//g, type: TokenType.Comment },\n // Namespace/using import\n { re: /\\busing\\s+([\\w.]+);/g, type: TokenType.Import, groupIndex: 1 },\n // Class/interface/struct/enum names\n { re: /\\b(?:class|interface|struct|enum)\\s+([A-Za-z_][A-Za-z0-9_]*)/g, type: TokenType.Class, groupIndex: 1 },\n // Method/property declaration\n { re: /\\b(?:public|private|protected|internal|static|virtual|override|async)\\s+(?:\\w+\\s+)+([a-zA-Z_]\\w*)\\s*\\(/g, type: TokenType.Method, groupIndex: 1 },\n // Local variable declarations\n { re: /\\b(?:var|int|string|bool|double|float|object)\\s+([a-zA-Z_]\\w*)\\b/g, type: TokenType.Variable, groupIndex: 1 },\n // Double-quoted strings\n { re: /\"(?:[^\"\\\\]|\\\\.)*\"/g, type: TokenType.String },\n // Verbatim strings\n { re: /@\"(?:[^\"]|\"\")*\"/g, type: TokenType.String },\n ];\n\n for (const { re, type, groupIndex } of patterns) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(code)) !== null) {\n const fullMatch = m[0];\n const captureValue = groupIndex !== undefined ? (m[groupIndex] ?? fullMatch) : fullMatch;\n const captureStart = groupIndex !== undefined\n ? m.index + fullMatch.indexOf(captureValue)\n : m.index;\n\n if (!captureValue || captureValue.trim() === \"\") continue;\n\n if (\n type === TokenType.Variable ||\n type === TokenType.Method ||\n type === TokenType.Class\n ) {\n if (CSHARP_KEYWORDS.has(captureValue)) continue;\n if (captureValue.length <= 1) continue;\n if (/^(String|Object|Integer|Boolean|Double|Float|List|Dictionary|Array|Exception|Task|Console|Math|Enum|Delegate)$/.test(captureValue)) continue;\n }\n\n tokens.push({\n type,\n value: captureValue,\n start: captureStart,\n end: captureStart + captureValue.length,\n line: lineFromIndex(lineOffsets, captureStart),\n });\n }\n }\n\n return deduplicate(tokens);\n}\n\nfunction scanRuby(code: string): Token[] {\n const tokens: Token[] = [];\n if (!code.trim()) return tokens;\n const lineOffsets = buildLineIndex(code);\n\n const patterns: Array<{ re: RegExp; type: TokenType; groupIndex?: number }> = [\n // Single-line comment\n { re: /#[^\\n]*/g, type: TokenType.Comment },\n // Method names\n { re: /\\bdef\\s+([a-zA-Z_]\\w*[!?]?)/g, type: TokenType.Function, groupIndex: 1 },\n // Class and module names\n { re: /\\b(?:class|module)\\s+([A-Z][a-zA-Z0-9_]*)/g, type: TokenType.Class, groupIndex: 1 },\n // Instance variables\n { re: /@([a-zA-Z_]\\w*)/g, type: TokenType.Property, groupIndex: 1 },\n // All-caps constants (3+ chars to avoid single-letter constants)\n { re: /\\b([A-Z][A-Z0-9_]{2,})\\b/g, type: TokenType.Variable, groupIndex: 1 },\n // Double-quoted strings\n { re: /\"(?:[^\"\\\\]|\\\\.)*\"/g, type: TokenType.String },\n // Single-quoted strings\n { re: /'(?:[^'\\\\]|\\\\.)*'/g, type: TokenType.String },\n ];\n\n for (const { re, type, groupIndex } of patterns) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(code)) !== null) {\n const fullMatch = m[0];\n const captureValue = groupIndex !== undefined ? (m[groupIndex] ?? fullMatch) : fullMatch;\n const captureStart = groupIndex !== undefined\n ? m.index + fullMatch.indexOf(captureValue)\n : m.index;\n\n if (!captureValue || captureValue.trim() === \"\") continue;\n\n if (\n type === TokenType.Variable ||\n type === TokenType.Function ||\n type === TokenType.Class ||\n type === TokenType.Property\n ) {\n if (RUBY_KEYWORDS.has(captureValue)) continue;\n if (captureValue.length <= 1) continue;\n }\n\n tokens.push({\n type,\n value: captureValue,\n start: captureStart,\n end: captureStart + captureValue.length,\n line: lineFromIndex(lineOffsets, captureStart),\n });\n }\n }\n\n return deduplicate(tokens);\n}\n\nfunction scanRust(code: string): Token[] {\n const tokens: Token[] = [];\n if (!code.trim()) return tokens;\n const lineOffsets = buildLineIndex(code);\n\n const patterns: Array<{ re: RegExp; type: TokenType; groupIndex?: number }> = [\n { re: /\\/\\/[^\\n]*/g, type: TokenType.Comment },\n { re: /\\/\\*[\\s\\S]*?\\*\\//g, type: TokenType.Comment },\n // Use declarations\n { re: /\\buse\\s+([\\w:]+)/g, type: TokenType.Import, groupIndex: 1 },\n // Named type declarations (struct, enum, trait)\n { re: /\\b(?:struct|enum|trait)\\s+([A-Z][a-zA-Z0-9_]*)/g, type: TokenType.Class, groupIndex: 1 },\n // Function names\n { re: /\\bfn\\s+([a-zA-Z_]\\w*)/g, type: TokenType.Function, groupIndex: 1 },\n // Constants (ALL_CAPS)\n { re: /\\bconst\\s+([A-Z_][A-Z0-9_]*)\\s*:/g, type: TokenType.Variable, groupIndex: 1 },\n // Variable bindings\n { re: /\\blet\\s+(?:mut\\s+)?([a-zA-Z_]\\w*)/g, type: TokenType.Variable, groupIndex: 1 },\n // Double-quoted strings\n { re: /\"(?:[^\"\\\\]|\\\\.)*\"/g, type: TokenType.String },\n ];\n\n for (const { re, type, groupIndex } of patterns) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(code)) !== null) {\n const fullMatch = m[0];\n const captureValue = groupIndex !== undefined ? (m[groupIndex] ?? fullMatch) : fullMatch;\n const captureStart = groupIndex !== undefined\n ? m.index + fullMatch.indexOf(captureValue)\n : m.index;\n\n if (!captureValue || captureValue.trim() === \"\") continue;\n\n if (\n type === TokenType.Variable ||\n type === TokenType.Function ||\n type === TokenType.Class\n ) {\n if (RUST_KEYWORDS.has(captureValue)) continue;\n if (captureValue.length <= 1) continue;\n }\n\n tokens.push({\n type,\n value: captureValue,\n start: captureStart,\n end: captureStart + captureValue.length,\n line: lineFromIndex(lineOffsets, captureStart),\n });\n }\n }\n\n return deduplicate(tokens);\n}\n\n// ─── Deduplication ────────────────────────────────────────────────────────────\n\nfunction deduplicate(tokens: Token[]): Token[] {\n tokens.sort((a, b) => a.start - b.start);\n const seen = new Set<string>();\n const result: Token[] = [];\n for (const token of tokens) {\n const key = `${token.start}:${token.end}`;\n if (!seen.has(key)) {\n seen.add(key);\n result.push(token);\n }\n }\n return result;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Scan source code and extract mutable tokens with their positions.\n *\n * @example\n * const result = scan(\"const greeting = 'hello';\", \"typescript\");\n * result.tokens.map(t => t.value) // => [\"greeting\", \"'hello'\"]\n */\nexport function scan(code: string, language: string): ScanResult {\n if (!code || !code.trim()) {\n return { tokens: [], language };\n }\n\n const lang = language.toLowerCase();\n let tokens: Token[];\n\n switch (lang) {\n case \"typescript\":\n case \"javascript\":\n case \"ts\":\n case \"js\":\n case \"tsx\":\n case \"jsx\":\n tokens = scanTypeScript(code);\n break;\n case \"python\":\n case \"py\":\n tokens = scanPython(code);\n break;\n case \"go\":\n tokens = scanGo(code);\n break;\n case \"java\":\n tokens = scanJava(code);\n break;\n case \"csharp\":\n case \"cs\":\n tokens = scanCSharp(code);\n break;\n case \"ruby\":\n case \"rb\":\n tokens = scanRuby(code);\n break;\n case \"rust\":\n case \"rs\":\n tokens = scanRust(code);\n break;\n default:\n tokens = scanTypeScript(code);\n }\n\n return { tokens, language: lang };\n}\n","/**\n * Pretense — Mutation Salt Manager\n *\n * Per-installation random salt for mutation hashing.\n * Stored at ~/.pretense/mutation.salt, never transmitted.\n *\n * Security: Without a salt, mutation hashes like _v1a2b can be reversed via\n * dictionary attack (65536 possibilities for 4 hex chars). With a 256-bit\n * per-installation salt, pre-image recovery is computationally infeasible.\n */\n\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from \"fs\";\nimport { join } from \"path\";\nimport { homedir } from \"os\";\nimport { randomBytes } from \"crypto\";\n\nconst SALT_BYTES = 32;\n\n// Paths are computed lazily so that tests can override HOME before calling getMutationSalt()\nfunction getSaltPath(): { dir: string; path: string } {\n const dir = join(homedir(), \".pretense\");\n return { dir, path: join(dir, \"mutation.salt\") };\n}\n\nlet _cachedSalt: string | null = null;\n\nexport function getMutationSalt(): string {\n if (_cachedSalt) return _cachedSalt;\n\n const { dir, path } = getSaltPath();\n\n if (existsSync(path)) {\n try {\n const raw = readFileSync(path, \"utf-8\").trim();\n if (/^[0-9a-f]{64}$/i.test(raw)) {\n _cachedSalt = raw.toLowerCase();\n return _cachedSalt;\n }\n } catch {\n // fall through\n }\n }\n\n const salt = randomBytes(SALT_BYTES).toString(\"hex\");\n try {\n mkdirSync(dir, { recursive: true });\n writeFileSync(path, salt, { mode: 0o600 });\n } catch {\n // in-memory only if FS is read-only\n }\n\n _cachedSalt = salt;\n return salt;\n}\n\nexport function buildSaltedSeed(baseSeed: string): string {\n return `${baseSeed}:${getMutationSalt()}`;\n}\n\n/** @internal */\nexport function _resetSaltCache(): void {\n _cachedSalt = null;\n}\n","/**\n * Pretense Core — Deterministic Mutation Engine\n *\n * Replaces identifiers, strings, and comments with synthetic tokens.\n * Same input + same seed always produces the same output (seeded PRNG).\n * Tracks every substitution in a MutationMap for exact reversal.\n */\n\nimport { TokenType, type MutationMap, type MutationResult, type MutationStats } from \"./types.js\";\nimport { scan, detectLanguage } from \"./scanner.js\";\nimport { buildSaltedSeed } from \"./salt.js\";\n\n// ─── Seeded hash ───────────────────────────────────────────────────────────────\n\n/**\n * Deterministic 32-bit hash (djb2 variant).\n * Returns a non-negative integer.\n */\nfunction hash32(str: string): number {\n let h = 5381;\n for (let i = 0; i < str.length; i++) {\n h = ((h << 5) + h) ^ str.charCodeAt(i);\n }\n return h >>> 0; // unsigned\n}\n\n/**\n * Convert a number to a base-36 alphanumeric string of exactly `len` chars.\n */\nfunction toAlphaNum(n: number, len: number): string {\n const CHARS = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let result = \"\";\n let v = n;\n for (let i = 0; i < len; i++) {\n result = CHARS[v % CHARS.length]! + result;\n v = Math.floor(v / CHARS.length);\n }\n return result;\n}\n\n/**\n * Generate a short deterministic identifier for a token value + seed.\n *\n * @example\n * deterministicId(\"getUserById\", \"proj-seed\", \"_fn\") // => \"_fnx3k7\"\n */\nfunction deterministicId(original: string, seed: string, prefix: string, len = 4): string {\n const combined = `${seed}:${prefix}:${original}`;\n const h = hash32(combined);\n return prefix + toAlphaNum(h, len);\n}\n\n// ─── Mutation logic ────────────────────────────────────────────────────────────\n\nfunction prefixForType(type: TokenType): string {\n switch (type) {\n case TokenType.Class: return \"_cls\";\n case TokenType.Function:\n case TokenType.Method: return \"_fn\";\n case TokenType.Variable: return \"_v\";\n case TokenType.Property: return \"_prop\";\n default: return \"_tok\";\n }\n}\n\n/**\n * Mutate source code deterministically. Returns mutated code and the\n * MutationMap needed to reverse it.\n *\n * @param code - Source code string\n * @param language - Language identifier (\"typescript\", \"python\", \"go\", \"java\")\n * @param seed - Optional seed for determinism (default: \"pretense\")\n *\n * @example\n * const { mutatedCode, map } = mutate(\"const apiKey = 'secret';\", \"typescript\");\n * mutatedCode // => \"const _va1b2 = '_strc3d4';\"\n */\nexport function mutate(code: string, language?: string, seed = \"pretense\"): MutationResult {\n const startMs = performance.now();\n const lang = language ?? detectLanguage(code);\n\n if (!code || !code.trim()) {\n const emptyMap: MutationMap = new Map();\n return {\n mutatedCode: code,\n map: emptyMap,\n stats: { tokensScanned: 0, tokensMutated: 0, durationMs: 0, language: lang },\n };\n }\n\n // Mix in per-installation salt when using the default seed (production path).\n // This prevents dictionary brute-force reversal of mutation hashes.\n const effectiveSeed = seed === \"pretense\" ? buildSaltedSeed(seed) : seed;\n\n const { tokens } = scan(code, lang);\n const map: MutationMap = new Map<string, string>();\n\n // Build mutation map — one synthetic per unique original value\n for (const token of tokens) {\n if (map.has(token.value)) continue; // already mapped\n\n if (token.type === TokenType.Comment) {\n // Comments preserved verbatim — stripping breaks round-trip\n continue;\n }\n\n if (token.type === TokenType.String) {\n // Strings preserved verbatim — mutations break round-trip for multi-line strings\n continue;\n }\n\n if (token.type === TokenType.Import) {\n // Keep import paths intact — they refer to packages, not IP\n continue;\n }\n\n const prefix = prefixForType(token.type);\n const synthetic = deterministicId(token.value, effectiveSeed, prefix);\n map.set(token.value, synthetic);\n }\n\n // Apply substitutions — longest-first to avoid partial match issues\n const entries = [...map.entries()].sort((a, b) => b[0].length - a[0].length);\n\n let mutatedCode = code;\n for (const [original, synthetic] of entries) {\n if (!synthetic) continue;\n // Use word-boundary aware replacement for identifiers\n const escaped = original.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n if (original.match(/^[A-Za-z_$][A-Za-z0-9_$]*$/)) {\n // Identifier: use word boundaries\n mutatedCode = mutatedCode.replace(new RegExp(`\\\\b${escaped}\\\\b`, \"g\"), synthetic);\n } else {\n // String literals or other: exact replacement\n mutatedCode = mutatedCode.split(original).join(synthetic);\n }\n }\n\n const durationMs = Math.round((performance.now() - startMs) * 100) / 100;\n\n return {\n mutatedCode,\n map,\n stats: {\n tokensScanned: tokens.length,\n tokensMutated: map.size,\n durationMs,\n language: lang,\n },\n };\n}\n","/**\n * Pretense Core — Exact Reverser\n *\n * Uses the MutationMap produced by mutate() to restore original code.\n * Applies replacements longest-first to prevent partial-match bugs.\n * After reversal, output must equal the original input byte-for-byte.\n */\n\nimport type { MutationMap } from \"./types.js\";\n\n/**\n * Reverse a previously mutated string back to the original.\n * Throws if the map contains entries whose synthetic values are not\n * present in the mutated code (indicates map/code mismatch).\n *\n * @param mutatedCode - Code that was produced by mutate()\n * @param map - The MutationMap returned by the same mutate() call\n *\n * @example\n * const { mutatedCode, map } = mutate(\"const apiKey = 'secret';\", \"typescript\");\n * reverse(mutatedCode, map) // => \"const apiKey = 'secret';\"\n */\nexport function reverse(mutatedCode: string, map: MutationMap): string {\n if (!mutatedCode || map.size === 0) return mutatedCode;\n\n // Build reverse map: synthetic → original\n // Skip comment strips (value === \"\") — they were deleted, can't be restored\n const reverseMap = new Map<string, string>();\n for (const [original, synthetic] of map.entries()) {\n if (synthetic === \"\" || !synthetic) continue; // stripped comments\n reverseMap.set(synthetic, original);\n }\n\n if (reverseMap.size === 0) return mutatedCode;\n\n // Sort by synthetic length (longest first) to avoid partial substitution\n const sortedEntries = [...reverseMap.entries()].sort((a, b) => b[0].length - a[0].length);\n\n let result = mutatedCode;\n for (const [synthetic, original] of sortedEntries) {\n const escaped = synthetic.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n if (synthetic.match(/^[A-Za-z_$][A-Za-z0-9_$]*$/) || synthetic.match(/^_[a-z]+[a-z0-9]{4,}$/)) {\n // Identifier: word boundaries\n result = result.replace(new RegExp(`\\\\b${escaped}\\\\b`, \"g\"), original);\n } else {\n // String literals: exact\n result = result.split(synthetic).join(original);\n }\n }\n\n return result;\n}\n","/**\n * Pretense Core — Secret Detection Engine\n *\n * 40+ regex patterns for API keys, tokens, credentials, and PII.\n * Sub-5ms per scan. Zero dependencies beyond regex.\n * Includes Shannon entropy check for high-entropy strings.\n */\n\nexport type ScanCategory = \"secret\" | \"pii\" | \"credential\" | \"proprietary\";\nexport type ScanAction = \"block\" | \"redact\" | \"mutate\" | \"warn\" | \"pass\";\nexport type ScanSeverity = \"critical\" | \"high\" | \"medium\" | \"low\";\n\nexport interface ScanMatch {\n id: string;\n category: ScanCategory;\n type: string;\n value: string;\n masked: string;\n start: number;\n end: number;\n severity: ScanSeverity;\n action: ScanAction;\n}\n\nexport interface SecretScanResult {\n clean: boolean;\n matches: ScanMatch[];\n scannedAt: number;\n durationMs: number;\n}\n\ninterface PatternDef {\n name: string;\n category: ScanCategory;\n severity: ScanSeverity;\n defaultAction: ScanAction;\n pattern: RegExp;\n validate?: (match: string) => boolean;\n}\n\nconst SECRET_PATTERNS: PatternDef[] = [\n { name: \"anthropic-api-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /sk-ant-api\\d{2}-[A-Za-z0-9_-]{40,}/g },\n { name: \"openai-api-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /sk-[A-Za-z0-9]{20,}/g },\n { name: \"aws-access-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /AKIA[0-9A-Z]{16}/g },\n { name: \"aws-secret-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /(?:aws_secret_access_key|AWS_SECRET_ACCESS_KEY)\\s*[=:]\\s*['\"]?([A-Za-z0-9/+=]{40})['\"]?/g },\n { name: \"github-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /gh[ps]_[A-Za-z0-9_]{36,}/g },\n { name: \"github-fine-grained\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /github_pat_[A-Za-z0-9_]{22,}/g },\n { name: \"stripe-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /(?:sk|pk|rk)_(?:test|live)_[A-Za-z0-9]{20,}/g },\n { name: \"private-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g },\n { name: \"jwt-token\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /eyJ[A-Za-z0-9_-]{10,}\\.eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}/g },\n { name: \"database-url\", category: \"credential\", severity: \"critical\", defaultAction: \"block\", pattern: /(?:postgres|mysql|mongodb|redis|amqp):\\/\\/[^\\s'\"\\\\)]+:[^\\s'\"\\\\)]+@[^\\s'\"\\\\)]+/g },\n { name: \"generic-password\", category: \"credential\", severity: \"high\", defaultAction: \"redact\", pattern: /(?:password|passwd|pwd|secret|token|api_key|apikey|api-key)\\s*[=:]\\s*['\"][^\\s'\"]{8,}['\"]/gi },\n { name: \"slack-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /xox[bpors]-[A-Za-z0-9-]{10,}/g },\n { name: \"google-api-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /AIza[A-Za-z0-9_-]{35}/g },\n { name: \"npm-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /npm_[A-Za-z0-9]{36}/g },\n { name: \"sendgrid-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /SG\\.[A-Za-z0-9_-]{22}\\.[A-Za-z0-9_-]{43}/g },\n { name: \"twilio-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /SK[a-f0-9]{32}/g },\n // ─── Additional patterns (v0.3) ──────────────────────────────────────────────\n { name: \"azure-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /(?:AccountKey|SharedAccessKey)=[A-Za-z0-9+/=]{40,}/g },\n { name: \"mailgun-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /key-[a-f0-9]{32}/g },\n { name: \"twilio-sid\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /AC[a-f0-9]{32}/g },\n { name: \"heroku-api-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /[hH]eroku.*[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/g },\n { name: \"shopify-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /shpat_[a-fA-F0-9]{32}/g },\n { name: \"datadog-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /dd[a-z]{1,2}_[a-zA-Z0-9]{32,}/g },\n { name: \"vercel-token\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /vc_[a-zA-Z0-9]{24,}/g },\n { name: \"supabase-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /sbp_[a-f0-9]{40}/g },\n { name: \"linear-api-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /lin_api_[A-Za-z0-9]{40}/g },\n { name: \"cloudflare-api-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /v1\\.0-[a-f0-9]{24}-[a-f0-9]{146}/g },\n { name: \"discord-bot-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /[MN][A-Za-z\\d]{23,}\\.[\\w-]{6}\\.[\\w-]{27}/g },\n { name: \"grafana-api-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /eyJrIjoi[A-Za-z0-9_-]{40,}/g },\n { name: \"confluent-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /CONFLUENT[A-Z_]*\\s*[=:]\\s*['\"]?[A-Za-z0-9/+=]{16,}['\"]?/g },\n { name: \"digitalocean-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /dop_v1_[a-f0-9]{64}/g },\n { name: \"doppler-token\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /dp\\.st\\.[a-z0-9_-]{2,}\\.[A-Za-z0-9]{40,}/g },\n { name: \"planetscale-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /pscale_tkn_[A-Za-z0-9_-]{32,}/g },\n { name: \"hashicorp-vault-token\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /hvs\\.[A-Za-z0-9_-]{24,}/g },\n { name: \"fastly-api-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /fastly_[A-Za-z0-9]{32}/g },\n { name: \"algolia-api-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /[a-f0-9]{32}/g, validate: (m) => /ALGOLIA|algolia/.test(m) },\n { name: \"pulumi-token\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /pul-[a-f0-9]{40}/g },\n // ─── Extended patterns (v0.6 unit 8) ─────────────────────────────────────────\n { name: \"google-oauth-refresh\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /\\bGOCSPX-[A-Za-z0-9_-]{20,}\\b/g },\n { name: \"slack-webhook-url\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /https:\\/\\/hooks\\.slack\\.com\\/services\\/T[A-Z0-9]+\\/B[A-Z0-9]+\\/[A-Za-z0-9]{20,}/g },\n { name: \"sentry-dsn\", category: \"secret\", severity: \"high\", defaultAction: \"redact\", pattern: /https:\\/\\/[a-f0-9]{32}@o\\d+\\.ingest\\.sentry\\.io\\/\\d+/g },\n { name: \"x509-certificate\", category: \"secret\", severity: \"high\", defaultAction: \"redact\", pattern: /-----BEGIN CERTIFICATE-----/g },\n { name: \"launchdarkly-sdk-key\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /\\bsdk-[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\\b/g },\n { name: \"launchdarkly-mobile-key\", category: \"secret\", severity: \"high\", defaultAction: \"block\", pattern: /\\bmob-[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\\b/g },\n { name: \"stripe-webhook-secret\", category: \"secret\", severity: \"critical\", defaultAction: \"block\", pattern: /\\bwhsec_[A-Za-z0-9]{32,}\\b/g },\n];\n\nconst PII_PATTERNS: PatternDef[] = [\n { name: \"ssn\", category: \"pii\", severity: \"critical\", defaultAction: \"redact\", pattern: /\\b\\d{3}-\\d{2}-\\d{4}\\b/g },\n { name: \"credit-card\", category: \"pii\", severity: \"critical\", defaultAction: \"redact\", pattern: /\\b(?:\\d[ -]*?){13,19}\\b/g, validate: luhnCheck },\n { name: \"email\", category: \"pii\", severity: \"medium\", defaultAction: \"warn\", pattern: /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b/g },\n { name: \"phone-us\", category: \"pii\", severity: \"medium\", defaultAction: \"warn\", pattern: /\\b(?:\\+?1[-.\\s]?)?\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}\\b/g },\n { name: \"ip-address\", category: \"pii\", severity: \"low\", defaultAction: \"warn\", pattern: /\\b(?:(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\b/g, validate: (ip) => !ip.startsWith(\"127.\") && !ip.startsWith(\"0.\") && ip !== \"255.255.255.255\" },\n];\n\nconst ENV_PATTERNS: PatternDef[] = [\n { name: \"env-secret\", category: \"credential\", severity: \"high\", defaultAction: \"block\", pattern: /(?:process\\.env\\.|os\\.environ\\[|ENV\\[|getenv\\()['\"]?((?:SECRET|TOKEN|PASSWORD|API_KEY|PRIVATE|AUTH)[A-Z_0-9]*)['\"]?\\]?\\)?/gi },\n];\n\nfunction luhnCheck(num: string): boolean {\n const digits = num.replace(/\\D/g, \"\");\n if (digits.length < 13 || digits.length > 19) return false;\n let sum = 0;\n let alternate = false;\n for (let i = digits.length - 1; i >= 0; i--) {\n let n = parseInt(digits[i]!, 10);\n if (alternate) { n *= 2; if (n > 9) n -= 9; }\n sum += n;\n alternate = !alternate;\n }\n return sum % 10 === 0;\n}\n\n// ─── Shannon entropy check ────────────────────────────────────────────────────\n\n/**\n * Calculate Shannon entropy of a string. Higher values indicate more randomness.\n * Useful for detecting high-entropy strings that may be secrets/tokens.\n */\nexport function shannonEntropy(str: string): number {\n if (str.length === 0) return 0;\n const freq = new Map<string, number>();\n for (const ch of str) {\n freq.set(ch, (freq.get(ch) ?? 0) + 1);\n }\n let entropy = 0;\n const len = str.length;\n for (const count of freq.values()) {\n const p = count / len;\n if (p > 0) entropy -= p * Math.log2(p);\n }\n return entropy;\n}\n\n/**\n * Check if a string is likely a high-entropy secret.\n * Returns true if the string is > 20 chars and has entropy > 4.5.\n */\nexport function isHighEntropy(str: string, minLength = 20, threshold = 4.5): boolean {\n if (str.length <= minLength) return false;\n return shannonEntropy(str) > threshold;\n}\n\nfunction maskValue(value: string, type: string): string {\n if (type.includes(\"key\") || type.includes(\"token\") || type.includes(\"secret\")) return value.slice(0, 6) + \"...\" + value.slice(-4);\n if (type === \"ssn\") return \"***-**-\" + value.slice(-4);\n if (type === \"credit-card\") return \"****-****-****-\" + value.replace(/\\D/g, \"\").slice(-4);\n if (type === \"email\") { const [local, domain] = value.split(\"@\"); return (local?.[0] ?? \"*\") + \"***@\" + (domain ?? \"\"); }\n if (value.length > 12) return value.slice(0, 4) + \"...\" + value.slice(-4);\n return \"***\";\n}\n\nlet matchCounter = 0;\n\n// Files larger than this byte budget skip the expensive entropy sweep.\n// Big generated/minified files trigger millions of high-entropy candidates\n// and produce no useful signal — the regex-pattern pass still runs.\nconst ENTROPY_SCAN_MAX_BYTES = 512 * 1024; // 512 KB\n\nexport function scan(text: string, actionOverrides?: Partial<Record<string, ScanAction>>): SecretScanResult {\n const start = performance.now();\n const matches: ScanMatch[] = [];\n const allPatterns = [...SECRET_PATTERNS, ...PII_PATTERNS, ...ENV_PATTERNS];\n\n for (const def of allPatterns) {\n def.pattern.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = def.pattern.exec(text)) !== null) {\n const value = m[0];\n if (def.validate && !def.validate(value)) continue;\n const action = actionOverrides?.[def.name] ?? def.defaultAction;\n matchCounter++;\n matches.push({\n id: `scan_${matchCounter}`,\n category: def.category,\n type: def.name,\n value,\n masked: maskValue(value, def.name),\n start: m.index,\n end: m.index + value.length,\n severity: def.severity,\n action,\n });\n }\n }\n\n // Shannon entropy check for unquoted high-entropy strings.\n // Skipped for very large inputs to avoid pathological O(N) regex sweeps\n // and the O(N) covered-range check below.\n if (text.length <= ENTROPY_SCAN_MAX_BYTES) {\n // Pre-sort regex matches by start index so we can skip already-covered\n // regions in O(log N) instead of O(N) per entropy candidate. Without this\n // the entropy pass becomes catastrophic on large files.\n const sortedByStart = [...matches].sort((a, b) => a.start - b.start);\n const coveredEnd = (idx: number): number => {\n // Returns the largest end-index of any match whose start <= idx.\n let lo = 0;\n let hi = sortedByStart.length - 1;\n let best = -1;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n if (sortedByStart[mid]!.start <= idx) {\n best = mid;\n lo = mid + 1;\n } else {\n hi = mid - 1;\n }\n }\n return best >= 0 ? sortedByStart[best]!.end : -1;\n };\n\n const highEntropyPattern = /\\b[A-Za-z0-9_\\-/.+=$]{21,}\\b/g;\n highEntropyPattern.lastIndex = 0;\n let hem: RegExpExecArray | null;\n while ((hem = highEntropyPattern.exec(text)) !== null) {\n const value = hem[0];\n const end = hem.index + value.length;\n // Skip if already matched by a pattern (covered-region check via binary search)\n if (coveredEnd(hem.index) >= end) continue;\n if (isHighEntropy(value)) {\n matchCounter++;\n matches.push({\n id: `scan_${matchCounter}`,\n category: \"secret\",\n type: \"high-entropy-string\",\n value,\n masked: value.slice(0, 6) + \"...\" + value.slice(-4),\n start: hem.index,\n end,\n severity: \"medium\",\n action: actionOverrides?.[\"high-entropy-string\"] ?? \"warn\",\n });\n }\n }\n }\n\n const severityRank: Record<ScanSeverity, number> = { critical: 4, high: 3, medium: 2, low: 1 };\n matches.sort((a, b) => a.start - b.start || severityRank[b.severity] - severityRank[a.severity]);\n\n const deduped: ScanMatch[] = [];\n let lastEnd = -1;\n for (const match of matches) {\n if (match.start >= lastEnd) {\n deduped.push(match);\n lastEnd = match.end;\n }\n }\n\n return {\n clean: deduped.filter((m) => m.action === \"block\" || m.action === \"redact\").length === 0,\n matches: deduped,\n scannedAt: Date.now(),\n durationMs: Math.round((performance.now() - start) * 100) / 100,\n };\n}\n\nexport function applyRedactions(text: string, matches: ScanMatch[]): string {\n const sorted = [...matches].sort((a, b) => b.start - a.start);\n let result = text;\n for (const match of sorted) {\n if (match.action === \"block\" || match.action === \"redact\") {\n result = result.slice(0, match.start) + `[PRETENSE:${match.type.toUpperCase()}]` + result.slice(match.end);\n }\n }\n return result;\n}\n\nexport function getPatternCount(): number {\n return SECRET_PATTERNS.length + PII_PATTERNS.length + ENV_PATTERNS.length;\n}\n","/**\n * Pretense Core — Mutation Store\n *\n * In-memory store with JSON file persistence for MutationMap entries.\n * SQLite replaces this in v0.2. For now: simple, zero-dependency, works.\n *\n * File: ~/.pretense/store.json (configurable)\n */\n\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from \"fs\";\nimport { dirname } from \"path\";\nimport type { StoreEntry, MutationMap } from \"./types.js\";\n\nexport class MutationStore {\n private entries: Map<string, StoreEntry> = new Map();\n private readonly filePath: string;\n\n constructor(filePath: string) {\n this.filePath = filePath;\n }\n\n /**\n * Persist a mutation map with associated metadata.\n *\n * @example\n * store.save({ id: \"req-1\", originalHash: \"abc\", mapEntries: [...], timestamp: Date.now(), language: \"typescript\" });\n */\n save(entry: StoreEntry): void {\n this.entries.set(entry.id, { ...entry });\n }\n\n /**\n * Retrieve a stored entry by request ID.\n *\n * @example\n * const entry = store.get(\"req-1\");\n */\n get(id: string): StoreEntry | null {\n return this.entries.get(id) ?? null;\n }\n\n /**\n * Find the most recent entry whose originalHash matches.\n *\n * @example\n * const entry = store.getByHash(\"sha256-abc123\");\n */\n getByHash(hash: string): StoreEntry | null {\n for (const entry of [...this.entries.values()].reverse()) {\n if (entry.originalHash === hash) return entry;\n }\n return null;\n }\n\n /**\n * Return all stored entries, newest first, up to `limit`.\n *\n * @example\n * store.list(10) // last 10 entries\n */\n list(limit = 50): StoreEntry[] {\n const all = [...this.entries.values()].reverse();\n return all.slice(0, limit);\n }\n\n /**\n * Delete an entry by ID. Returns true if it existed.\n */\n delete(id: string): boolean {\n return this.entries.delete(id);\n }\n\n /**\n * Remove all entries from memory.\n */\n clear(): void {\n this.entries.clear();\n }\n\n /**\n * Write current in-memory state to the JSON file.\n */\n persist(): void {\n const dir = dirname(this.filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n const data = JSON.stringify([...this.entries.values()], null, 2);\n writeFileSync(this.filePath, data, \"utf-8\");\n }\n\n /**\n * Load entries from the JSON file into memory.\n * No-ops if the file doesn't exist.\n */\n load(): void {\n if (!existsSync(this.filePath)) return;\n try {\n const raw = readFileSync(this.filePath, \"utf-8\");\n const parsed = JSON.parse(raw) as StoreEntry[];\n this.entries.clear();\n for (const entry of parsed) {\n this.entries.set(entry.id, entry);\n }\n } catch {\n // Corrupted or empty file — start fresh\n this.entries.clear();\n }\n }\n\n /** Total entries in memory */\n get size(): number {\n return this.entries.size;\n }\n\n /**\n * Reconstruct a MutationMap from a stored entry.\n *\n * @example\n * const map = store.toMap(entry);\n * reverse(mutatedCode, map);\n */\n static toMap(entry: StoreEntry): MutationMap {\n return new Map(entry.mapEntries);\n }\n\n /**\n * Serialize a MutationMap to the format stored in StoreEntry.\n */\n static fromMap(map: MutationMap): [string, string][] {\n return [...map.entries()];\n }\n}\n","/**\n * Pretense CLI — Configuration Manager\n *\n * Reads/writes the .pretense/ directory for project-level config,\n * mutation maps, and audit logs.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { join, resolve } from \"path\";\nimport { createHmac } from \"node:crypto\";\nimport type { PretenseConfig } from \"./types.js\";\nimport { DEFAULT_CONFIG } from \"./types.js\";\n\nconst CONFIG_DIR_NAME = \".pretense\";\nconst CONFIG_FILE = \"config.json\";\nconst MUTATION_MAP_FILE = \"mutation-map.json\";\nconst AUDIT_LOG_FILE = \"audit.log\";\nconst USAGE_FILE = \"usage.json\";\n\n/**\n * Get the .pretense/ config directory path for a given base directory.\n */\nexport function getConfigDir(baseDir?: string): string {\n const base = baseDir ?? process.cwd();\n return resolve(base, CONFIG_DIR_NAME);\n}\n\n/**\n * Initialize the .pretense/ directory with default config files.\n * Creates config.json, empty mutation-map.json, and empty audit.log.\n *\n * @returns The path to the created .pretense/ directory\n */\nexport function initConfig(dir?: string): string {\n const configDir = getConfigDir(dir);\n\n if (!existsSync(configDir)) {\n mkdirSync(configDir, { recursive: true });\n }\n\n // config.json\n const configPath = join(configDir, CONFIG_FILE);\n if (!existsSync(configPath)) {\n const config: PretenseConfig = {\n ...DEFAULT_CONFIG,\n storePath: configDir,\n };\n writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n }\n\n // mutation-map.json\n const mapPath = join(configDir, MUTATION_MAP_FILE);\n if (!existsSync(mapPath)) {\n writeFileSync(mapPath, \"[]\", \"utf-8\");\n }\n\n // audit.log\n const auditPath = join(configDir, AUDIT_LOG_FILE);\n if (!existsSync(auditPath)) {\n writeFileSync(auditPath, \"\", \"utf-8\");\n }\n\n // usage.json\n const usagePath = join(configDir, USAGE_FILE);\n if (!existsSync(usagePath)) {\n const today = new Date().toISOString().slice(0, 10);\n const month = today.slice(0, 7);\n const usageData: UsageData = { month, mutations: 0, firstUseDate: today };\n writeFileSync(\n usagePath,\n JSON.stringify({ ...usageData, date: today, checksum: computeUsageChecksum(usageData) }, null, 2),\n \"utf-8\",\n );\n }\n\n return configDir;\n}\n\n/**\n * Load config from .pretense/config.json.\n * Returns DEFAULT_CONFIG if the file doesn't exist or is corrupted.\n */\nexport function loadConfig(dir?: string): PretenseConfig {\n const configDir = getConfigDir(dir);\n const configPath = join(configDir, CONFIG_FILE);\n\n if (!existsSync(configPath)) {\n return { ...DEFAULT_CONFIG };\n }\n\n try {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<PretenseConfig>;\n return { ...DEFAULT_CONFIG, ...parsed };\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\n/**\n * Save config to .pretense/config.json.\n */\nexport function saveConfig(config: PretenseConfig, dir?: string): void {\n const configDir = getConfigDir(dir);\n if (!existsSync(configDir)) {\n mkdirSync(configDir, { recursive: true });\n }\n const configPath = join(configDir, CONFIG_FILE);\n writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n}\n\n// ─── Usage integrity ─────────────────────────────────────────────────────────\n\n/** App-level secret used for usage.json HMAC when no external secret is set */\nconst USAGE_HMAC_SECRET = \"pretense_usage_integrity_v1\";\n\nfunction getUsageSecret(): string {\n return process.env[\"PRETENSE_USAGE_SECRET\"] ?? USAGE_HMAC_SECRET;\n}\n\nfunction computeUsageChecksum(data: { month: string; mutations: number; firstUseDate: string }): string {\n const payload = JSON.stringify({ month: data.month, mutations: data.mutations, firstUseDate: data.firstUseDate });\n return createHmac(\"sha256\", getUsageSecret()).update(payload).digest(\"hex\");\n}\n\nfunction verifyUsageChecksum(data: { month: string; mutations: number; firstUseDate: string; checksum?: string }): boolean {\n if (!data.checksum) return false;\n return data.checksum === computeUsageChecksum(data);\n}\n\n// ─── Usage tracking ──────────────────────────────────────────────────────────\n\nexport interface UsageData {\n month: string;\n mutations: number;\n firstUseDate: string;\n}\n\nexport function loadUsage(dir?: string): UsageData {\n const configDir = getConfigDir(dir);\n const usagePath = join(configDir, USAGE_FILE);\n\n const today = new Date().toISOString().slice(0, 10);\n const currentMonth = today.slice(0, 7); // YYYY-MM\n\n if (!existsSync(usagePath)) {\n return { month: currentMonth, mutations: 0, firstUseDate: today };\n }\n\n try {\n const raw = readFileSync(usagePath, \"utf-8\");\n const data = JSON.parse(raw) as UsageData & { checksum?: string; date?: string };\n\n // Migrate legacy daily format: if 'date' field exists but not 'month'\n if (data.date && !data.month) {\n const legacyDate = data.date as string;\n return { month: currentMonth, mutations: 0, firstUseDate: data.firstUseDate ?? legacyDate };\n }\n\n // Verify integrity checksum\n if (!verifyUsageChecksum({ month: data.month, mutations: data.mutations, firstUseDate: data.firstUseDate, checksum: data.checksum })) {\n process.stderr.write(\"[PRETENSE] Warning: usage.json integrity check failed. Resetting usage counter.\\n\");\n return { month: currentMonth, mutations: 0, firstUseDate: data.firstUseDate ?? today };\n }\n\n // Reset counter if it's a new month\n if (data.month !== currentMonth) {\n return { month: currentMonth, mutations: 0, firstUseDate: data.firstUseDate ?? today };\n }\n return { month: data.month, mutations: data.mutations, firstUseDate: data.firstUseDate };\n } catch {\n return { month: currentMonth, mutations: 0, firstUseDate: today };\n }\n}\n\nexport function saveUsage(usage: UsageData, dir?: string): void {\n const configDir = getConfigDir(dir);\n if (!existsSync(configDir)) {\n mkdirSync(configDir, { recursive: true });\n }\n const usagePath = join(configDir, USAGE_FILE);\n const checksum = computeUsageChecksum(usage);\n writeFileSync(usagePath, JSON.stringify({ ...usage, checksum }, null, 2), \"utf-8\");\n}\n\n// ─── License tier detection ───────────────────────────────────────────────────\n\nexport type LicenseTier = \"free\" | \"pro\" | \"enterprise\";\n\n/** Minimum key length: 8-char prefix + 32-char alphanumeric payload */\nconst MIN_LICENSE_KEY_LENGTH = 40;\nconst LICENSE_PAYLOAD_REGEX = /^[a-zA-Z0-9]+$/;\n\n/**\n * Validate license key format:\n * 1. Must be at least MIN_LICENSE_KEY_LENGTH chars\n * 2. Payload (after prefix) must be alphanumeric\n * 3. If PRETENSE_LICENSE_SECRET is set, validate HMAC:\n * key format = `pre_pro_<payload>_<hmac>` where hmac = HMAC-SHA256(payload, secret) truncated to 16 hex chars\n */\nfunction isValidLicenseKey(key: string, prefix: string): boolean {\n if (key.length < MIN_LICENSE_KEY_LENGTH) return false;\n\n const afterPrefix = key.slice(prefix.length);\n\n const hmacSecret = process.env[\"PRETENSE_LICENSE_SECRET\"];\n if (hmacSecret) {\n // HMAC mode: expect format `<payload>_<hmac16hex>`\n const lastUnderscore = afterPrefix.lastIndexOf(\"_\");\n if (lastUnderscore === -1) return false;\n const payload = afterPrefix.slice(0, lastUnderscore);\n const providedHmac = afterPrefix.slice(lastUnderscore + 1);\n if (!payload || !providedHmac) return false;\n if (!LICENSE_PAYLOAD_REGEX.test(payload)) return false;\n const expectedHmac = createHmac(\"sha256\", hmacSecret).update(payload).digest(\"hex\").slice(0, 16);\n return providedHmac === expectedHmac;\n }\n\n // Offline mode: length + alphanumeric validation only\n return LICENSE_PAYLOAD_REGEX.test(afterPrefix);\n}\n\nexport function detectTier(): LicenseTier {\n const key = process.env[\"PRETENSE_LICENSE_KEY\"] ?? \"\";\n if (key.startsWith(\"pre_ent_\") && isValidLicenseKey(key, \"pre_ent_\")) return \"enterprise\";\n if (key.startsWith(\"pre_pro_\") && isValidLicenseKey(key, \"pre_pro_\")) return \"pro\";\n return \"free\";\n}\n\nexport function getTierLimits(tier: LicenseTier): { monthlyMutations: number; auditRetentionDays: number } {\n switch (tier) {\n case \"enterprise\":\n return { monthlyMutations: Infinity, auditRetentionDays: Infinity };\n case \"pro\":\n return { monthlyMutations: Infinity, auditRetentionDays: 90 };\n case \"free\":\n default:\n return { monthlyMutations: 1000, auditRetentionDays: 30 };\n }\n}\n","/**\n * Pretense CLI — Audit Logger\n *\n * Writes JSON lines to .pretense/audit.log for compliance and debugging.\n * Supports JSON and CSV output formats. Tier-gated retention.\n */\n\nimport { appendFileSync, existsSync, readFileSync, mkdirSync } from \"fs\";\nimport { join, dirname } from \"path\";\nimport { getConfigDir, detectTier, getTierLimits } from \"./config.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport interface AuditEntry {\n timestamp: string;\n sessionId: string;\n file: string;\n identifiersMutated: number;\n secretsBlocked: number;\n llmProvider: string;\n latencyMs: number;\n}\n\nexport interface AuditReadOptions {\n limit?: number;\n format?: \"json\" | \"csv\" | \"text\";\n dir?: string;\n}\n\n// ─── Write ───────────────────────────────────────────────────────────────────\n\n/**\n * Append an audit entry as a JSON line to .pretense/audit.log.\n */\nexport function writeAuditEntry(entry: AuditEntry, dir?: string): void {\n const configDir = getConfigDir(dir);\n const auditPath = join(configDir, \"audit.log\");\n\n const logDir = dirname(auditPath);\n if (!existsSync(logDir)) {\n mkdirSync(logDir, { recursive: true });\n }\n\n const line = JSON.stringify(entry) + \"\\n\";\n appendFileSync(auditPath, line, \"utf-8\");\n}\n\n/**\n * Create a new audit entry with current timestamp.\n */\nexport function createAuditEntry(\n sessionId: string,\n file: string,\n identifiersMutated: number,\n secretsBlocked: number,\n llmProvider: string,\n latencyMs: number,\n): AuditEntry {\n return {\n timestamp: new Date().toISOString(),\n sessionId,\n file,\n identifiersMutated,\n secretsBlocked,\n llmProvider,\n latencyMs,\n };\n}\n\n// ─── Read ────────────────────────────────────────────────────────────────────\n\n/**\n * Read and parse the audit log. Applies tier-based retention filtering.\n */\nexport function readAuditLog(options: AuditReadOptions = {}): AuditEntry[] {\n const { limit, dir } = options;\n const configDir = getConfigDir(dir);\n const auditPath = join(configDir, \"audit.log\");\n\n if (!existsSync(auditPath)) {\n return [];\n }\n\n const raw = readFileSync(auditPath, \"utf-8\");\n const lines = raw.trim().split(\"\\n\").filter(Boolean);\n\n let entries: AuditEntry[] = [];\n for (const line of lines) {\n try {\n entries.push(JSON.parse(line) as AuditEntry);\n } catch {\n // Skip malformed lines\n }\n }\n\n // Apply tier-based retention filter\n const tier = detectTier();\n const { auditRetentionDays } = getTierLimits(tier);\n\n if (auditRetentionDays !== Infinity) {\n const cutoff = Date.now() - auditRetentionDays * 24 * 60 * 60 * 1000;\n entries = entries.filter((e) => new Date(e.timestamp).getTime() >= cutoff);\n }\n\n // Sort newest first\n entries.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());\n\n // Apply limit\n if (limit && limit > 0) {\n entries = entries.slice(0, limit);\n }\n\n return entries;\n}\n\n// ─── Formatters ──────────────────────────────────────────────────────────────\n\n/**\n * Format audit entries as JSON string.\n */\nexport function formatJson(entries: AuditEntry[]): string {\n return JSON.stringify(entries, null, 2);\n}\n\n/**\n * Format audit entries as CSV string.\n */\nexport function formatCsv(entries: AuditEntry[]): string {\n const headers = \"timestamp,sessionId,file,identifiersMutated,secretsBlocked,llmProvider,latencyMs\";\n const rows = entries.map((e) =>\n [\n e.timestamp,\n e.sessionId,\n `\"${e.file.replace(/\"/g, '\"\"')}\"`,\n e.identifiersMutated,\n e.secretsBlocked,\n e.llmProvider,\n e.latencyMs,\n ].join(\",\"),\n );\n return [headers, ...rows].join(\"\\n\");\n}\n\n/**\n * Format audit entries as human-readable text.\n */\nexport function formatText(entries: AuditEntry[]): string {\n if (entries.length === 0) return \"No audit entries found.\";\n\n const lines = entries.map((e) => {\n const date = new Date(e.timestamp).toLocaleString();\n return `[${date}] ${e.file} | ${e.identifiersMutated} mutated | ${e.secretsBlocked} secrets blocked | ${e.llmProvider} | ${e.latencyMs}ms`;\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format entries using the specified format.\n */\nexport function formatAudit(entries: AuditEntry[], format: \"json\" | \"csv\" | \"text\" = \"text\"): string {\n switch (format) {\n case \"json\":\n return formatJson(entries);\n case \"csv\":\n return formatCsv(entries);\n case \"text\":\n default:\n return formatText(entries);\n }\n}\n","/**\n * Pretense CLI — Proxy Server\n *\n * Hono HTTP proxy that intercepts LLM API calls, scans + mutates\n * proprietary code, forwards to the real provider, then reverse-mutates\n * the response. Supports Anthropic, OpenAI, and Google Gemini.\n *\n * Includes free-tier enforcement, usage tracking, and upgrade nudges.\n * Drop-in replacement: set *_BASE_URL=http://localhost:9339 and done.\n */\n\nimport { Hono } from \"hono\";\nimport { serve } from \"@hono/node-server\";\nimport { nanoid } from \"nanoid\";\nimport { createServer } from \"node:net\";\nimport { mutate } from \"./mutator.js\";\nimport { reverse } from \"./reverser.js\";\nimport { MutationStore } from \"./store.js\";\nimport { scan as scanSecrets, applyRedactions } from \"./secrets.js\";\nimport { writeAuditEntry, createAuditEntry } from \"./audit.js\";\nimport { loadUsage, saveUsage, detectTier, getTierLimits, getConfigDir } from \"./config.js\";\nimport type { StoreEntry, PretenseConfig } from \"./types.js\";\nimport { DEFAULT_CONFIG } from \"./types.js\";\nimport { requireApiKey } from \"./auth.js\";\nimport { getSession, sessionCount } from \"./session-store.js\";\n\n// ─── Provider detection ───────────────────────────────────────────────────────\n\nfunction anthropicUpstream(): string { return process.env[\"ANTHROPIC_UPSTREAM_URL\"] ?? \"https://api.anthropic.com\"; }\nfunction openaiUpstream(): string { return process.env[\"OPENAI_UPSTREAM_URL\"] ?? \"https://api.openai.com\"; }\nfunction geminiUpstream(): string { return process.env[\"GEMINI_UPSTREAM_URL\"] ?? \"https://generativelanguage.googleapis.com\"; }\nfunction ollamaUpstream(): string { return process.env[\"OLLAMA_UPSTREAM_URL\"] ?? \"http://localhost:11434\"; }\n\nfunction detectUpstream(path: string): string {\n // Anthropic — Claude Code / Anthropic SDK\n if (path.startsWith(\"/v1/messages\")) return anthropicUpstream();\n // OpenAI — Chat Completions, Completions, Responses (Codex CLI)\n if (\n path.startsWith(\"/v1/chat/completions\") ||\n path.startsWith(\"/v1/completions\") ||\n path.startsWith(\"/v1/responses\")\n ) {\n return openaiUpstream();\n }\n // Google Gemini\n if (path.startsWith(\"/v1beta/\") || path.startsWith(\"/v1/models\")) return geminiUpstream();\n // Ollama (local LLM) — chat + generate endpoints\n if (path.startsWith(\"/api/chat\") || path.startsWith(\"/api/generate\")) return ollamaUpstream();\n // Default to Anthropic (Claude Code is the most common consumer)\n return anthropicUpstream();\n}\n\nfunction detectProvider(path: string): string {\n if (path.startsWith(\"/v1/messages\")) return \"anthropic\";\n if (\n path.startsWith(\"/v1/chat/completions\") ||\n path.startsWith(\"/v1/completions\") ||\n path.startsWith(\"/v1/responses\")\n ) {\n return \"openai\";\n }\n if (path.startsWith(\"/v1beta/\") || path.startsWith(\"/v1/models\")) return \"google\";\n if (path.startsWith(\"/api/chat\") || path.startsWith(\"/api/generate\")) return \"ollama\";\n return \"anthropic\";\n}\n\n// ─── Message text extraction ──────────────────────────────────────────────────\n\nfunction extractText(body: Record<string, unknown>): string {\n const parts: string[] = [];\n if (typeof body[\"system\"] === \"string\") parts.push(body[\"system\"]);\n if (Array.isArray(body[\"messages\"])) {\n for (const msg of body[\"messages\"] as Record<string, unknown>[]) {\n if (typeof msg[\"content\"] === \"string\") parts.push(msg[\"content\"]);\n else if (Array.isArray(msg[\"content\"])) {\n for (const block of msg[\"content\"] as Record<string, unknown>[]) {\n if (block[\"type\"] === \"text\" && typeof block[\"text\"] === \"string\") parts.push(block[\"text\"]);\n }\n }\n }\n }\n return parts.join(\"\\n\");\n}\n\n// ─── Code block extraction (inline — no external dep) ────────────────────────\n\ninterface CodeBlock {\n code: string;\n language: string;\n start: number;\n end: number;\n}\n\nfunction extractCodeBlocks(text: string): CodeBlock[] {\n const blocks: CodeBlock[] = [];\n const re = /```(\\w*)\\n([\\s\\S]*?)```/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n blocks.push({\n code: m[2] ?? \"\",\n language: m[1] ?? \"typescript\",\n start: m.index,\n end: m.index + m[0].length,\n });\n }\n return blocks;\n}\n\nfunction replaceCodeBlocks(text: string, blocks: CodeBlock[], replacements: string[]): string {\n let result = text;\n // Replace in reverse order to preserve indices\n for (let i = blocks.length - 1; i >= 0; i--) {\n const block = blocks[i]!;\n const replacement = replacements[i] ?? block.code;\n const lang = block.language ?? \"typescript\";\n result = result.slice(0, block.start) + \"```\" + lang + \"\\n\" + replacement + \"```\" + result.slice(block.end);\n }\n return result;\n}\n\n// ─── Apply text mutations to message body ────────────────────────────────────\n\nfunction applyToBody(\n body: Record<string, unknown>,\n transform: (text: string) => string,\n): Record<string, unknown> {\n const mutateField = (val: unknown): unknown => {\n if (typeof val === \"string\") return transform(val);\n if (Array.isArray(val)) return val.map(mutateField);\n if (val && typeof val === \"object\") {\n const obj = val as Record<string, unknown>;\n return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, mutateField(v)]));\n }\n return val;\n };\n\n return mutateField(body) as Record<string, unknown>;\n}\n\n// ─── Stats tracking ───────────────────────────────────────────────────────────\n\ninterface ProxyStats {\n requestsProcessed: number;\n totalTokensMutated: number;\n totalSecretsBlocked: number;\n startedAt: number;\n}\n\nconst stats: ProxyStats = {\n requestsProcessed: 0,\n totalTokensMutated: 0,\n totalSecretsBlocked: 0,\n startedAt: Date.now(),\n};\n\n// ─── Upgrade nudge helpers ───────────────────────────────────────────────────\n\nfunction daysSinceFirstUse(): number {\n const usage = loadUsage();\n if (!usage.firstUseDate) return 0;\n const first = new Date(usage.firstUseDate).getTime();\n return Math.floor((Date.now() - first) / (24 * 60 * 60 * 1000));\n}\n\nfunction printUpgradeNudge(reason: string): void {\n process.stdout.write(\n `\\n\\x1b[33m[PRETENSE] ${reason}\\x1b[0m\\n` +\n `\\x1b[33m[PRETENSE] Upgrade to Pro: https://pretense.ai/pricing\\x1b[0m\\n\\n`,\n );\n}\n\n// ─── Proxy factory ────────────────────────────────────────────────────────────\n\nexport interface ProxyOptions {\n config?: Partial<PretenseConfig>;\n store?: MutationStore;\n verbose?: boolean;\n}\n\ntype ProxyEnv = { Variables: { sessionHash: string } };\n\nexport function createProxy(opts: ProxyOptions = {}): Hono<ProxyEnv> {\n const config: PretenseConfig = { ...DEFAULT_CONFIG, ...opts.config };\n const store = opts.store ?? new MutationStore(`${config.storePath}/proxy-store.json`);\n const verbose = opts.verbose ?? false;\n\n const app = new Hono<ProxyEnv>();\n\n // ── Auth middleware ────────────────────────────────────────────────────────\n // Short-circuits public paths (/, /health, /stats, /audit, /tokens) and\n // rejects everything else lacking an API key with HTTP 401.\n app.use(\"*\", requireApiKey);\n\n // ── Root welcome ───────────────────────────────────────────────────────────\n app.get(\"/\", (c) =>\n c.json({\n name: \"pretense\",\n version: \"0.3.0\",\n status: \"running\",\n routes: {\n \"GET /\": \"This welcome page\",\n \"GET /health\": \"Health check with uptime\",\n \"GET /stats\": \"Mutation statistics\",\n \"GET /audit\": \"Audit log (?limit=50)\",\n \"POST /*\": \"Proxy to upstream LLM API (Anthropic, OpenAI, Google auto-detected)\",\n },\n languages: [\"TypeScript\", \"JavaScript\", \"Python\", \"Go\", \"Java\", \"C#\", \"Ruby\", \"Rust\"],\n docs: \"https://pretense.ai/docs\",\n }),\n );\n\n // ── Health ─────────────────────────────────────────────────────────────────\n app.get(\"/health\", (c) =>\n c.json({\n status: \"ok\",\n version: \"0.3.0\",\n uptime: Math.floor((Date.now() - stats.startedAt) / 1000),\n stats: {\n requestsProcessed: stats.requestsProcessed,\n totalTokensMutated: stats.totalTokensMutated,\n },\n }),\n );\n\n // ── Stats ──────────────────────────────────────────────────────────────────\n app.get(\"/stats\", (c) =>\n c.json({\n ...stats,\n storeSize: store.size,\n activeSessions: sessionCount(),\n }),\n );\n\n // ── Audit ──────────────────────────────────────────────────────────────────\n app.get(\"/audit\", (c) => {\n const limit = parseInt(c.req.query(\"limit\") ?? \"50\");\n return c.json(store.list(limit));\n });\n\n // ── Main proxy handler ─────────────────────────────────────────────────────\n app.all(\"/*\", async (c) => {\n if (c.req.method !== \"POST\") {\n // Pass-through non-POST (GET model lists, etc.)\n const upstream = c.req.header(\"x-pretense-upstream\") ?? detectUpstream(c.req.path);\n const url = upstream + c.req.path;\n const headers: Record<string, string> = {};\n c.req.raw.headers.forEach((v, k) => { headers[k] = v; });\n delete headers[\"host\"];\n headers[\"host\"] = new URL(upstream).host;\n const resp = await fetch(url, { method: c.req.method, headers });\n return new Response(resp.body, { status: resp.status, headers: Object.fromEntries(resp.headers.entries()) });\n }\n\n const requestStart = performance.now();\n\n // ── Parse body ────────────────────────────────────────────────────────\n let body: Record<string, unknown>;\n try {\n body = await c.req.json<Record<string, unknown>>();\n } catch {\n return c.json({ error: { type: \"invalid_request\", message: \"Invalid JSON body\" } }, 400);\n }\n\n if (!body || Object.keys(body).length === 0) {\n return c.json({ error: { type: \"invalid_request\", message: \"Empty request body\" } }, 400);\n }\n\n const requestId = nanoid(12);\n const upstream = c.req.header(\"x-pretense-upstream\") ?? detectUpstream(c.req.path);\n const provider = detectProvider(c.req.path);\n\n // ── Session isolation ─────────────────────────────────────────────────\n // Two different API keys MUST NOT share mutation map state. The\n // requireApiKey middleware already validated the key and stashed\n // sha256(key) under \"sessionHash\"; if we get here it's set.\n const sessHash = c.get(\"sessionHash\");\n const session = getSession(sessHash);\n\n // ── Free tier enforcement ─────────────────────────────────────────────\n const tier = detectTier();\n const { monthlyMutations } = getTierLimits(tier);\n const usage = loadUsage();\n\n if (tier === \"free\" && usage.mutations >= monthlyMutations) {\n return c.json(\n {\n error: {\n type: \"pretense_rate_limit\",\n message: `Monthly mutation limit reached (${monthlyMutations}/month). Upgrade to Pro for unlimited: https://pretense.ai/pricing`,\n },\n },\n 429,\n );\n }\n\n // ── Secret scan ───────────────────────────────────────────────────────\n const fullText = extractText(body);\n const secretScan = scanSecrets(fullText);\n const blockedSecrets = secretScan.matches.filter((m) => m.action === \"block\");\n\n if (blockedSecrets.length > 0) {\n stats.totalSecretsBlocked += blockedSecrets.length;\n\n // Pro alert suggestion for secrets\n if (tier === \"free\") {\n printUpgradeNudge(`${blockedSecrets.length} secret(s) blocked. Pro tier includes real-time secret alerts via Slack/PagerDuty.`);\n }\n\n return c.json(\n {\n error: {\n type: \"pretense_blocked\",\n message: `Request blocked: ${blockedSecrets.length} secret(s) detected. Types: ${[...new Set(blockedSecrets.map((m) => m.type))].join(\", \")}`,\n },\n },\n 400,\n );\n }\n\n // Apply redactions (PII, warnings)\n const processedBody = applyToBody(body, (text) => applyRedactions(text, secretScan.matches));\n\n // ── Code mutation ─────────────────────────────────────────────────────\n // The mutation map is scoped to the session (per-API-key) so two\n // different callers never see each other's tokens. We still track a\n // per-request local map for logging + the audit StoreEntry below.\n const mutationMap = new Map<string, string>();\n let tokensMutated = 0;\n\n const mutatedBody = applyToBody(processedBody, (text) => {\n const blocks = extractCodeBlocks(text);\n if (blocks.length === 0) return text;\n\n const mutatedBlocks: string[] = [];\n for (const block of blocks) {\n const result = mutate(block.code, block.language);\n for (const [k, v] of result.map) {\n mutationMap.set(k, v);\n session.mutationMap.set(k, v);\n session.reverseMap.set(v, k);\n }\n tokensMutated += result.stats.tokensMutated;\n mutatedBlocks.push(result.mutatedCode);\n }\n\n return replaceCodeBlocks(text, blocks, mutatedBlocks);\n });\n\n // Update usage tracking\n usage.mutations += tokensMutated;\n saveUsage(usage);\n\n // Warning at 80% of monthly limit (free tier)\n const warningThreshold = Math.floor(monthlyMutations * 0.8);\n if (tier === \"free\" && usage.mutations >= warningThreshold && usage.mutations - tokensMutated < warningThreshold) {\n printUpgradeNudge(`${usage.mutations}/${monthlyMutations} monthly mutations used. Running low!`);\n }\n\n // 7-day upgrade nudge\n if (tier === \"free\" && daysSinceFirstUse() >= 7) {\n printUpgradeNudge(\"You've been using Pretense for 7+ days. Unlock Pro features: unlimited mutations, 90-day audit, Slack alerts.\");\n }\n\n // Store mutation map for response reversal\n const entry: StoreEntry = {\n id: requestId,\n originalHash: requestId,\n mapEntries: [...mutationMap.entries()],\n timestamp: Date.now(),\n language: \"mixed\",\n };\n store.save(entry);\n stats.requestsProcessed++;\n stats.totalTokensMutated += tokensMutated;\n\n // Write audit entry\n const latencyMs = Math.round((performance.now() - requestStart) * 100) / 100;\n writeAuditEntry(\n createAuditEntry(requestId, \"proxy-request\", tokensMutated, blockedSecrets.length, provider, latencyMs),\n );\n\n if (verbose && tokensMutated > 0) {\n process.stdout.write(`[PRETENSE] ${tokensMutated} tokens mutated for request ${requestId}\\n`);\n }\n\n // ── Forward to upstream ───────────────────────────────────────────────\n const headers: Record<string, string> = {};\n c.req.raw.headers.forEach((v, k) => { headers[k] = v; });\n delete headers[\"host\"];\n delete headers[\"content-length\"];\n headers[\"host\"] = new URL(upstream).host;\n headers[\"x-pretense-request-id\"] = requestId;\n\n const forwardBody = JSON.stringify(mutatedBody);\n\n let upstreamResp: Response;\n try {\n upstreamResp = await fetch(upstream + c.req.path, {\n method: \"POST\",\n headers: { ...headers, \"content-type\": \"application/json\", \"content-length\": String(Buffer.byteLength(forwardBody)) },\n body: forwardBody,\n });\n } catch {\n return c.json({ error: { type: \"pretense_upstream_error\", message: \"Failed to reach upstream provider\" } }, 502);\n }\n\n // ── Streaming with reverse-mutation ────────────────────────────────────\n if (body[\"stream\"] === true) {\n const streamReverseMap = new Map(mutationMap);\n const upstream = upstreamResp.body;\n if (!upstream || tokensMutated === 0) {\n // No mutations to reverse -- pass through as-is.\n return new Response(upstream, {\n status: upstreamResp.status,\n headers: {\n \"content-type\": upstreamResp.headers.get(\"content-type\") ?? \"text/event-stream\",\n \"cache-control\": \"no-cache\",\n \"x-pretense-request-id\": requestId,\n \"x-pretense-protected\": \"true\",\n \"x-pretense-mutations\": String(tokensMutated),\n },\n });\n }\n\n // Build a TransformStream that reverse-mutates each SSE data line.\n const decoder = new TextDecoder();\n const encoder = new TextEncoder();\n let buffer = \"\";\n\n const transform = new TransformStream<Uint8Array, Uint8Array>({\n transform(chunk, controller) {\n buffer += decoder.decode(chunk, { stream: true });\n const lines = buffer.split(\"\\n\");\n // Keep the last partial line in the buffer\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"data: \") && line !== \"data: [DONE]\") {\n try {\n const json = JSON.parse(line.slice(6)) as Record<string, unknown>;\n // Reverse-mutate text content in the SSE payload\n const reversed = applyToBody(json, (text) => reverse(text, streamReverseMap));\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(reversed)}\\n`));\n } catch {\n // If JSON parsing fails, pass line through unchanged.\n controller.enqueue(encoder.encode(line + \"\\n\"));\n }\n } else {\n controller.enqueue(encoder.encode(line + \"\\n\"));\n }\n }\n },\n flush(controller) {\n if (buffer.length > 0) {\n controller.enqueue(encoder.encode(buffer));\n }\n },\n });\n\n const reversedStream = upstream.pipeThrough(transform);\n return new Response(reversedStream, {\n status: upstreamResp.status,\n headers: {\n \"content-type\": upstreamResp.headers.get(\"content-type\") ?? \"text/event-stream\",\n \"cache-control\": \"no-cache\",\n \"x-pretense-request-id\": requestId,\n \"x-pretense-protected\": \"true\",\n \"x-pretense-mutations\": String(tokensMutated),\n \"x-pretense-stream-reversal\": \"active\",\n },\n });\n }\n\n // ── Reverse-mutate response ──────────────────────────────────────────\n const reverseMap = new Map(mutationMap);\n let respBody: Record<string, unknown>;\n try {\n respBody = (await upstreamResp.json()) as Record<string, unknown>;\n } catch {\n return new Response(null, {\n status: upstreamResp.status,\n headers: {\n \"x-pretense-protected\": \"true\",\n \"x-pretense-mutations\": String(tokensMutated),\n },\n });\n }\n\n const reversedBody = applyToBody(respBody, (text) => {\n const blocks = extractCodeBlocks(text);\n if (blocks.length === 0) return reverse(text, reverseMap);\n const reversedBlocks = blocks.map((b) => reverse(b.code, reverseMap));\n return replaceCodeBlocks(text, blocks, reversedBlocks);\n });\n\n c.header(\"x-pretense-request-id\", requestId);\n c.header(\"x-pretense-protected\", \"true\");\n c.header(\"x-pretense-mutations\", String(tokensMutated));\n return c.json(reversedBody, upstreamResp.status as 200);\n });\n\n return app;\n}\n\n// ─── Port helpers ─────────────────────────────────────────────────────────────\n\n/**\n * Check whether a port is currently free on 127.0.0.1.\n */\nfunction isPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const tester = createServer()\n .once(\"error\", () => resolve(false))\n .once(\"listening\", () => {\n tester.once(\"close\", () => resolve(true)).close();\n })\n .listen(port, \"127.0.0.1\");\n });\n}\n\n/**\n * Try the requested port; if it is busy, walk forward up to `maxAttempts`\n * times until a free port is found. Returns the chosen port number.\n */\nexport async function findAvailablePort(startPort: number, maxAttempts = 10): Promise<number> {\n for (let i = 0; i < maxAttempts; i++) {\n const candidate = startPort + i;\n if (candidate < 1 || candidate > 65535) break;\n // eslint-disable-next-line no-await-in-loop\n if (await isPortAvailable(candidate)) return candidate;\n }\n throw new Error(\n `No available port found in range ${startPort}-${startPort + maxAttempts - 1}. ` +\n `Free a port or pass --port <number>.`,\n );\n}\n\n// ─── Start server ─────────────────────────────────────────────────────────────\n\nexport function startProxy(opts: ProxyOptions & { port?: number } = {}): void {\n const requestedPort = opts.port ?? opts.config?.port ?? DEFAULT_CONFIG.port;\n const app = createProxy(opts);\n const tier = detectTier();\n\n void (async () => {\n let port: number;\n try {\n port = await findAvailablePort(requestedPort, 10);\n } catch (err) {\n process.stderr.write(`\\x1b[31m[PRETENSE] ${(err as Error).message}\\x1b[0m\\n`);\n process.exit(1);\n }\n\n if (port !== requestedPort) {\n process.stderr.write(\n `\\x1b[33m[PRETENSE] Port ${requestedPort} in use, falling back to ${port}.\\x1b[0m\\n`,\n );\n }\n\n serve({ fetch: app.fetch, port }, () => {\n const portStr = String(port);\n process.stdout.write(`\n\\x1b[36mPretense v0.3.0 [${tier.toUpperCase()}]\\x1b[0m\n Your code hits AI naked. We fix that.\n\n Proxy: http://localhost:${portStr}\n Health: http://localhost:${portStr}/health\n Stats: http://localhost:${portStr}/stats\n\n Drop-in env vars:\n ANTHROPIC_BASE_URL=http://localhost:${portStr}\n OPENAI_BASE_URL=http://localhost:${portStr}/v1\n GEMINI_BASE_URL=http://localhost:${portStr}/v1beta\n OLLAMA_HOST=http://localhost:${portStr}\n\n Routes intercepted:\n /v1/messages -> Anthropic (Claude Code, SDK)\n /v1/chat/completions -> OpenAI (ChatGPT, Cursor)\n /v1/responses -> OpenAI (Codex CLI)\n /v1beta/... -> Google Gemini\n /api/chat, /api/generate -> Ollama (local)\n`);\n });\n })();\n}\n","/**\n * Pretense CLI — Proxy Authentication\n *\n * Extracts API keys from incoming requests and enforces presence on all\n * non-public routes. The hash of each API key is used as an isolation\n * key for per-session mutation maps (see session-store.ts), so two\n * different API keys can never read or write each other's token map.\n */\n\nimport { createHash } from \"node:crypto\";\nimport type { Context, MiddlewareHandler } from \"hono\";\n\nconst AUTH_HEADERS = [\"authorization\", \"x-api-key\", \"x-goog-api-key\"] as const;\n\n/**\n * Public routes that do NOT require an API key. Used for health checks,\n * welcome page, stats/audit dashboards, and any local introspection routes.\n */\nconst PUBLIC_PATHS = new Set<string>([\n \"/\",\n \"/health\",\n \"/stats\",\n \"/audit\",\n \"/tokens\",\n]);\n\n/**\n * Pull the API key out of the first matching auth header.\n * Strips optional \"Bearer \" prefix for Authorization headers.\n */\nexport function extractApiKey(c: Context): string | null {\n for (const h of AUTH_HEADERS) {\n const v = c.req.header(h);\n if (v && v.length > 0) {\n return v.replace(/^Bearer\\s+/i, \"\").trim();\n }\n }\n return null;\n}\n\n/**\n * Deterministic short hash of an API key, safe to use as a map key.\n * Uses sha256 truncated to 16 hex chars (64 bits) — plenty for isolation\n * without leaking the full key.\n */\nexport function sessionHash(apiKey: string): string {\n return createHash(\"sha256\").update(apiKey).digest(\"hex\").slice(0, 16);\n}\n\n/**\n * Hono middleware that:\n * 1. Lets public routes through untouched.\n * 2. Rejects protected routes missing an API key with HTTP 401 + JSON.\n * 3. Stores the session hash in the request context for downstream handlers.\n */\nexport const requireApiKey: MiddlewareHandler = async (c, next) => {\n if (PUBLIC_PATHS.has(c.req.path)) {\n return next();\n }\n const key = extractApiKey(c);\n if (!key) {\n return c.json(\n {\n error: {\n type: \"missing_api_key\",\n message:\n \"Authorization header required (Authorization, x-api-key, or x-goog-api-key)\",\n },\n },\n 401,\n );\n }\n c.set(\"sessionHash\", sessionHash(key));\n return next();\n};\n","/**\n * Pretense CLI — Per-Session Token Maps\n *\n * Keyed by sha256(API key) so two different API keys can never share\n * mutation map state. Each SessionState holds the forward + reverse\n * mutation maps used by the proxy to translate identifiers into\n * synthetic tokens (PretenseMut/pretense_mut markers) before the\n * request is forwarded upstream, and to reverse them on the response.\n */\n\nexport interface SessionState {\n /** original identifier -> transformed synthetic */\n mutationMap: Map<string, string>;\n /** transformed synthetic -> original identifier (used on response) */\n reverseMap: Map<string, string>;\n /** unix epoch ms the session was first created */\n createdAt: number;\n /** unix epoch ms of most recent activity (used for sweeping) */\n lastUsed: number;\n}\n\nconst sessions = new Map<string, SessionState>();\n\n/**\n * Fetch (or lazily create) the session associated with an API key hash.\n * Updates lastUsed on every access so idle sessions can be swept later.\n */\nexport function getSession(hash: string): SessionState {\n let s = sessions.get(hash);\n if (!s) {\n s = {\n mutationMap: new Map(),\n reverseMap: new Map(),\n createdAt: Date.now(),\n lastUsed: Date.now(),\n };\n sessions.set(hash, s);\n }\n s.lastUsed = Date.now();\n return s;\n}\n\n/** Number of active sessions. Exposed for /stats + tests. */\nexport function sessionCount(): number {\n return sessions.size;\n}\n\n/**\n * Clear every tracked session. Only used by tests so state does not\n * bleed between test cases.\n */\nexport function clearSessions(): void {\n sessions.clear();\n}\n\n/**\n * Remove sessions whose lastUsed is older than `maxAgeMs`. Returns the\n * number of sessions removed. Called on a timer by the long-lived proxy\n * process to bound memory growth.\n */\nexport function sweepSessions(maxAgeMs: number): number {\n const cutoff = Date.now() - maxAgeMs;\n let removed = 0;\n for (const [hash, s] of sessions.entries()) {\n if (s.lastUsed < cutoff) {\n sessions.delete(hash);\n removed++;\n }\n }\n return removed;\n}\n","/**\n * Pretense CLI — Token Visibility Footer\n *\n * Prints a small footer after scan/mutate commands so users always know\n * (a) what plan they're on, (b) how much of their monthly quota they have\n * left, and (c) where to upgrade. This is the \"tokens remaining\" bar that\n * pre-seed CISOs expect from a paid security tool.\n */\n\nimport chalk from \"chalk\";\nimport { detectTier, getTierLimits, loadUsage, type LicenseTier } from \"./config.js\";\n\ninterface PlanLimits {\n monthlyMutations: number;\n monthlyScans: number;\n seats: number;\n pricePerMonth: string;\n}\n\nconst PLAN_LIMITS: Record<LicenseTier, PlanLimits> = {\n free: { monthlyMutations: 1000, monthlyScans: 5000, seats: 3, pricePerMonth: \"$0/month\" },\n pro: { monthlyMutations: 100000, monthlyScans: 500000, seats: 25, pricePerMonth: \"$29/seat/month\" },\n enterprise: {\n monthlyMutations: Number.POSITIVE_INFINITY,\n monthlyScans: Number.POSITIVE_INFINITY,\n seats: Number.POSITIVE_INFINITY,\n pricePerMonth: \"$99/seat/month\",\n },\n};\n\nexport function getPlanLimits(tier: LicenseTier): PlanLimits {\n return PLAN_LIMITS[tier];\n}\n\nfunction fmt(n: number): string {\n if (!Number.isFinite(n)) return \"unlimited\";\n return n.toLocaleString(\"en-US\");\n}\n\n/**\n * Print a one-line \"tokens remaining\" footer after a CLI command completes.\n * Stays silent on enterprise tier (no quota to nag about).\n */\nexport function printTokenFooter(filesScanned: number, mutationsMade: number): void {\n const tier = detectTier();\n const limits = getPlanLimits(tier);\n const usage = loadUsage();\n\n // Enterprise users should not see upgrade nags\n if (tier === \"enterprise\") {\n process.stderr.write(\n chalk.gray(`\\n ${filesScanned} files, ${mutationsMade} mutations · Plan: Enterprise (unlimited)\\n\\n`),\n );\n return;\n }\n\n const used = usage.mutations;\n const cap = limits.monthlyMutations;\n const pct = cap > 0 ? Math.min(100, Math.round((used / cap) * 100)) : 0;\n\n // Reserve color for warning when over 80%\n const usageStr = pct >= 80 ? chalk.yellow(`${fmt(used)} / ${fmt(cap)}`) : chalk.gray(`${fmt(used)} / ${fmt(cap)}`);\n\n process.stderr.write(\n `\\n ${chalk.cyan(filesScanned + \" files\")}, ${chalk.cyan(mutationsMade + \" mutations\")} ` +\n `· Plan: ${chalk.bold(tier.toUpperCase())} · Mutations this month: ${usageStr} (${pct}%)\\n`,\n );\n\n if (tier === \"free\") {\n if (pct >= 80) {\n process.stderr.write(\n chalk.yellow(` ⚠ Approaching free-tier limit. Upgrade: ${chalk.bold(\"pretense upgrade\")}\\n\\n`),\n );\n } else {\n process.stderr.write(\n chalk.gray(` Run ${chalk.bold(\"pretense status\")} for details, ${chalk.bold(\"pretense upgrade\")} to remove limits.\\n\\n`),\n );\n }\n } else {\n process.stderr.write(\"\\n\");\n }\n}\n","/**\n * Pretense CLI banner.\n *\n * Printed before the commander routes a subcommand. Silent when the\n * terminal is a CI environment, pipeline, or non-TTY, or when the user\n * sets PRETENSE_NO_BANNER=1.\n *\n * Ice-blue tint (#7DD3FC) is applied via chalk.hex which needs a 256-color\n * terminal. We wrap the tint call in try/catch so older terminals without\n * truecolor support silently fall back to the plain banner. Never break\n * startup because a user runs Pretense on a legacy shell.\n */\n\nimport chalk from \"chalk\";\n\nconst BANNER_RAW = `██████████████ pretense\n██ ██\n██ ██ Stop your code from\n██ ██ leaking to any LLM.\n██████████████\n██ pretense.ai\n██\n██\n██\n██`;\n\nconst ICE_BLUE = \"#7DD3FC\";\n\nfunction shouldPrint(): boolean {\n if (process.env.PRETENSE_NO_BANNER === \"1\") return false;\n if (!process.stdout.isTTY) return false;\n if (process.env.CI) return false;\n return true;\n}\n\nfunction tint(line: string): string {\n // chalk.hex is only safe on terminals that understand truecolor or 256-color.\n // If chalk throws or the user's terminal strips the escape codes, we print\n // the plain line instead of garbled output.\n try {\n return chalk.hex(ICE_BLUE)(line);\n } catch {\n return line;\n }\n}\n\nexport function printBanner(): void {\n if (!shouldPrint()) return;\n const lines = BANNER_RAW.split(\"\\n\");\n for (const line of lines) {\n process.stderr.write(tint(line) + \"\\n\");\n }\n process.stderr.write(\"\\n\");\n}\n","/**\n * Pretense CLI — `status` command\n *\n * Shows the current plan, monthly quota usage, seat count, and quick\n * upgrade hint. This is the equivalent of `gh auth status` for Pretense:\n * one command, one screen, full visibility into entitlement state.\n */\n\nimport chalk from \"chalk\";\nimport { detectTier, getTierLimits, loadUsage, type LicenseTier } from \"../config.js\";\nimport { getPlanLimits } from \"../token-footer.js\";\n\nconst PLAN_LABEL: Record<LicenseTier, string> = {\n free: \"Free\",\n pro: \"Pro\",\n enterprise: \"Enterprise\",\n};\n\nfunction fmt(n: number): string {\n if (!Number.isFinite(n)) return \"unlimited\";\n return n.toLocaleString(\"en-US\");\n}\n\nexport function runStatus(): void {\n const tier = detectTier();\n const planLimits = getPlanLimits(tier);\n const tierLimits = getTierLimits(tier);\n const usage = loadUsage();\n\n const tierBadge =\n tier === \"enterprise\"\n ? chalk.bgMagenta.white.bold(\" ENTERPRISE \")\n : tier === \"pro\"\n ? chalk.bgBlue.white.bold(\" PRO \")\n : chalk.bgGray.white.bold(\" FREE \");\n\n const lines: string[] = [];\n lines.push(\"\");\n lines.push(`${chalk.cyan(\"Pretense\")} ${chalk.gray(\"v0.3.0\")} ${tierBadge}`);\n lines.push(\"\");\n lines.push(` Plan: ${chalk.bold(PLAN_LABEL[tier])} ${chalk.gray(\"(\" + planLimits.pricePerMonth + \")\")}`);\n lines.push(` Mutations: ${fmt(usage.mutations)} / ${fmt(planLimits.monthlyMutations)} this month`);\n lines.push(` Scans: 0 / ${fmt(planLimits.monthlyScans)} this month`);\n lines.push(` Seats: 1 / ${fmt(planLimits.seats)}`);\n lines.push(` Audit log: ${Number.isFinite(tierLimits.auditRetentionDays) ? `${tierLimits.auditRetentionDays} days` : \"unlimited\"}`);\n lines.push(\"\");\n\n if (tier === \"free\") {\n lines.push(` ${chalk.gray(\"Upgrade:\")} ${chalk.bold(\"pretense upgrade\")}`);\n lines.push(` ${chalk.gray(\"Credits:\")} ${chalk.bold(\"pretense credits\")}`);\n lines.push(\"\");\n }\n\n process.stdout.write(lines.join(\"\\n\") + \"\\n\");\n}\n","/**\n * Pretense CLI — `upgrade` command\n *\n * Prints a side-by-side comparison of Free / Pro / Enterprise tiers and\n * a one-click URL to start checkout. Doubles as the in-CLI pricing page.\n */\n\nimport chalk from \"chalk\";\nimport { detectTier } from \"../config.js\";\n\nconst PRICING_URL = \"https://pretense.ai/pricing\";\n\nexport function runUpgrade(): void {\n const tier = detectTier();\n\n const lines: string[] = [];\n lines.push(\"\");\n lines.push(chalk.cyan.bold(\" Pretense Plans\"));\n lines.push(\"\");\n lines.push(chalk.gray(\" ┌──────────────┬──────────┬──────────┬─────────────┐\"));\n lines.push(chalk.gray(\" │ │ Free │ Pro │ Enterprise │\"));\n lines.push(chalk.gray(\" ├──────────────┼──────────┼──────────┼─────────────┤\"));\n lines.push(` │ Price/seat │ ${chalk.bold(\"$0\")} │ ${chalk.bold(\"$29\")} │ ${chalk.bold(\"$99\")} │`);\n lines.push(\" │ Mutations/mo │ 1,000 │ 100,000 │ unlimited │\");\n lines.push(\" │ Scans/mo │ 5,000 │ 500,000 │ unlimited │\");\n lines.push(\" │ Seats │ 3 │ 25 │ unlimited │\");\n lines.push(\" │ Audit log │ 30 days │ 90 days │ unlimited │\");\n lines.push(\" │ SSO/SAML │ - │ - │ yes │\");\n lines.push(\" │ On-prem │ - │ - │ yes │\");\n lines.push(\" │ SLA │ - │ - │ 24/7 │\");\n lines.push(chalk.gray(\" └──────────────┴──────────┴──────────┴─────────────┘\"));\n lines.push(\"\");\n lines.push(` ${chalk.gray(\"Current plan:\")} ${chalk.bold(tier.toUpperCase())}`);\n lines.push(` ${chalk.gray(\"Upgrade at:\")} ${chalk.cyan.underline(PRICING_URL)}`);\n lines.push(\"\");\n lines.push(chalk.gray(\" After purchase, set:\"));\n lines.push(chalk.gray(\" export PRETENSE_LICENSE_KEY=pre_pro_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"));\n lines.push(\"\");\n\n process.stdout.write(lines.join(\"\\n\") + \"\\n\");\n}\n","/**\n * Pretense CLI — `credits` command\n *\n * Friendly summary of how much of the monthly mutation/scan quota the\n * user has burned through. Exists separately from `status` so that\n * `pretense credits` reads naturally, the same way `gh repo view` does.\n */\n\nimport chalk from \"chalk\";\nimport { detectTier, loadUsage, type LicenseTier } from \"../config.js\";\nimport { getPlanLimits } from \"../token-footer.js\";\n\nconst PLAN_LABEL: Record<LicenseTier, string> = {\n free: \"Free\",\n pro: \"Pro\",\n enterprise: \"Enterprise\",\n};\n\nfunction fmt(n: number): string {\n if (!Number.isFinite(n)) return \"unlimited\";\n return n.toLocaleString(\"en-US\");\n}\n\nfunction progressBar(used: number, cap: number, width = 24): string {\n if (!Number.isFinite(cap) || cap <= 0) return chalk.green(\"[\" + \"=\".repeat(width) + \"]\");\n const pct = Math.min(1, used / cap);\n const filled = Math.round(pct * width);\n const bar = \"=\".repeat(filled) + \"-\".repeat(width - filled);\n const colored = pct >= 0.8 ? chalk.yellow(bar) : pct >= 1 ? chalk.red(bar) : chalk.green(bar);\n return \"[\" + colored + \"]\";\n}\n\nexport function runCredits(): void {\n const tier = detectTier();\n const limits = getPlanLimits(tier);\n const usage = loadUsage();\n\n const used = usage.mutations;\n const cap = limits.monthlyMutations;\n const remaining = Number.isFinite(cap) ? Math.max(0, cap - used) : Number.POSITIVE_INFINITY;\n const pct = Number.isFinite(cap) && cap > 0 ? Math.round((used / cap) * 100) : 0;\n\n const lines: string[] = [];\n lines.push(\"\");\n lines.push(chalk.cyan.bold(\" Pretense Credits\"));\n lines.push(\"\");\n lines.push(` Plan: ${chalk.bold(PLAN_LABEL[tier])}`);\n lines.push(` Month: ${usage.month}`);\n lines.push(\"\");\n lines.push(` Mutations: ${progressBar(used, cap)} ${fmt(used)} / ${fmt(cap)}`);\n lines.push(` Used: ${pct}%`);\n lines.push(` Remaining: ${fmt(remaining)}`);\n lines.push(\"\");\n\n if (tier === \"free\" && Number.isFinite(cap) && used >= cap * 0.8) {\n lines.push(chalk.yellow(\" ⚠ Approaching free-tier limit. Run 'pretense upgrade' for unlimited.\"));\n lines.push(\"\");\n } else if (tier === \"free\") {\n lines.push(chalk.gray(\" Tip: Run 'pretense upgrade' to compare plans.\"));\n lines.push(\"\");\n }\n\n process.stdout.write(lines.join(\"\\n\") + \"\\n\");\n}\n","/**\n * `pretense login` — store an API key in the user-level config so future\n * CLI runs can authenticate against pretense.ai without re-entering it.\n *\n * Inputs (in priority order):\n * 1. --key <plaintext> explicit flag\n * 2. PRETENSE_API_KEY env var one-shot use\n * 3. stdin (if piped) scripted use, e.g. `echo $KEY | pretense login`\n *\n * Storage: ~/.pretense/config.json with `{ api_key, saved_at }`. File is\n * created with mode 0o600 so other users on the host cannot read it.\n *\n * Validation: prefix must be `pk_live_` or `ptns_live_` (legacy). The\n * payload must be 16 chars or longer. We never call the network here —\n * a wrong key just fails on the next CLI run with a clear error message.\n */\n\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, chmodSync, readSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport chalk from \"chalk\";\n\nconst CONFIG_DIR_NAME = \".pretense\";\nconst CONFIG_FILE = \"config.json\";\n\ninterface LoginConfig {\n api_key: string;\n saved_at: string;\n}\n\nfunction getUserConfigDir(): string {\n return join(homedir(), CONFIG_DIR_NAME);\n}\n\nfunction getUserConfigPath(): string {\n return join(getUserConfigDir(), CONFIG_FILE);\n}\n\n/** Validate the visible shape of a key. Network call happens later. */\nexport function isValidKeyShape(key: string): boolean {\n const trimmed = key.trim();\n if (trimmed.length < 24) return false;\n if (!/^[A-Za-z0-9_]+$/.test(trimmed)) return false;\n return trimmed.startsWith(\"pk_live_\") || trimmed.startsWith(\"ptns_live_\");\n}\n\n/**\n * Read up to 4KB of stdin synchronously. Returns \"\" if stdin is a TTY\n * (i.e. nothing was piped in). Used so `echo $KEY | pretense login` works.\n */\nfunction readStdinIfPiped(): string {\n if (process.stdin.isTTY) return \"\";\n try {\n const chunks: Buffer[] = [];\n const buf = Buffer.alloc(4096);\n let bytesRead = 0;\n do {\n try {\n bytesRead = readSync(0, buf, 0, buf.length, null);\n } catch {\n // EAGAIN on some platforms — bail cleanly\n bytesRead = 0;\n }\n if (bytesRead > 0) chunks.push(Buffer.from(buf.subarray(0, bytesRead)));\n } while (bytesRead === buf.length);\n return Buffer.concat(chunks).toString(\"utf-8\").trim();\n } catch {\n return \"\";\n }\n}\n\nfunction maskKey(key: string): string {\n const trimmed = key.trim();\n if (trimmed.length <= 12) return trimmed;\n return `${trimmed.slice(0, 12)}${\"•\".repeat(8)}${trimmed.slice(-4)}`;\n}\n\n/**\n * Persist the api key. Returns the path written.\n */\nexport function saveApiKey(key: string, configDir: string = getUserConfigDir()): string {\n if (!existsSync(configDir)) {\n mkdirSync(configDir, { recursive: true });\n }\n const path = join(configDir, CONFIG_FILE);\n\n // Merge with any existing config so we don't clobber unrelated fields.\n let existing: Record<string, unknown> = {};\n if (existsSync(path)) {\n try {\n existing = JSON.parse(readFileSync(path, \"utf-8\")) as Record<string, unknown>;\n } catch {\n existing = {};\n }\n }\n const next: Record<string, unknown> = {\n ...existing,\n api_key: key.trim(),\n saved_at: new Date().toISOString(),\n };\n writeFileSync(path, JSON.stringify(next, null, 2), { encoding: \"utf-8\", mode: 0o600 });\n try {\n chmodSync(path, 0o600);\n } catch {\n // Windows / sandboxed filesystems may reject — non-fatal.\n }\n return path;\n}\n\n/**\n * Load the saved api key, if any. Used by other CLI commands that need to\n * authenticate against pretense.ai.\n */\nexport function loadApiKey(configDir: string = getUserConfigDir()): string | null {\n const path = join(configDir, CONFIG_FILE);\n if (!existsSync(path)) return null;\n try {\n const raw = readFileSync(path, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<LoginConfig>;\n if (typeof parsed.api_key === \"string\" && parsed.api_key.length > 0) {\n return parsed.api_key;\n }\n } catch {\n /* ignore */\n }\n return null;\n}\n\ninterface RunLoginOptions {\n key?: string;\n configDir?: string;\n}\n\nexport function runLogin(opts: RunLoginOptions = {}): number {\n const candidate =\n opts.key?.trim() ||\n (process.env[\"PRETENSE_API_KEY\"] ?? \"\").trim() ||\n readStdinIfPiped();\n\n if (!candidate) {\n console.error(chalk.red(\"Error: no API key provided.\"));\n console.error(\n chalk.gray(\"Try: pretense login --key pk_live_xxxxx\"),\n );\n console.error(\n chalk.gray(\" or: echo $PRETENSE_API_KEY | pretense login\"),\n );\n return 1;\n }\n\n if (!isValidKeyShape(candidate)) {\n console.error(chalk.red(\"Error: that does not look like a Pretense API key.\"));\n console.error(\n chalk.gray(\"Keys start with pk_live_ and are at least 24 characters long.\"),\n );\n console.error(\n chalk.gray(\"Get one at https://pretense.ai/dashboard/settings/api-keys\"),\n );\n return 1;\n }\n\n const path = saveApiKey(candidate, opts.configDir);\n console.log(chalk.green(\"Saved API key to\"), chalk.bold(path));\n console.log(chalk.gray(` ${maskKey(candidate)}`));\n console.log(chalk.gray(\" File mode 600 — readable only by you.\"));\n return 0;\n}\n"],"mappings":"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","names":["chalk","readFileSync","existsSync","readSync","resolve","join","scan","readFileSync","writeFileSync","mkdirSync","existsSync","existsSync","mkdirSync","readFileSync","writeFileSync","join","existsSync","mkdirSync","join","writeFileSync","readFileSync","join","existsSync","readFileSync","mkdirSync","writeFileSync","existsSync","readFileSync","mkdirSync","join","dirname","join","dirname","existsSync","mkdirSync","readFileSync","upstream","headers","scan","resolve","chalk","chalk","fmt","chalk","chalk","chalk","chalk","PLAN_LABEL","fmt","chalk","existsSync","mkdirSync","writeFileSync","readFileSync","join","homedir","chalk","CONFIG_DIR_NAME","CONFIG_FILE","existsSync","mkdirSync","join","CONFIG_FILE","readFileSync","writeFileSync","chalk","readSync","resolve","existsSync","join","chalk","scan","readFileSync"]}