@pretense/cli 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -0
- package/bin/pretense +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1581 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +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"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pretense/cli",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "AI firewall CLI — mutates proprietary code before LLM API calls",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"pretense": "bin/pretense"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist/",
|
|
11
|
+
"bin/",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsup",
|
|
16
|
+
"dev": "tsx src/index.ts",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"lint": "tsc --noEmit"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"chalk": "^5.3.0",
|
|
22
|
+
"commander": "^12.0.0",
|
|
23
|
+
"hono": "^4.0.0",
|
|
24
|
+
"@hono/node-server": "^1.8.0",
|
|
25
|
+
"nanoid": "^5.0.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^20.0.0",
|
|
29
|
+
"tsup": "^8.0.0",
|
|
30
|
+
"tsx": "^4.0.0",
|
|
31
|
+
"typescript": "^5.4.0",
|
|
32
|
+
"vitest": "^1.0.0"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public",
|
|
36
|
+
"registry": "https://registry.npmjs.org/"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"ai",
|
|
40
|
+
"security",
|
|
41
|
+
"code-mutation",
|
|
42
|
+
"llm",
|
|
43
|
+
"firewall",
|
|
44
|
+
"pretense",
|
|
45
|
+
"cli"
|
|
46
|
+
],
|
|
47
|
+
"homepage": "https://pretense.ai",
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/jimmymalhan/pretense.git",
|
|
51
|
+
"directory": "packages/cli"
|
|
52
|
+
},
|
|
53
|
+
"author": "Jimmy Malhan",
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": ">=18"
|
|
57
|
+
}
|
|
58
|
+
}
|