mancode 0.6.4 → 0.6.6
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.en.md +165 -45
- package/README.md +109 -28
- package/dist/{chunk-7HPP3KYG.js → chunk-D5ABGAF4.js} +2422 -1003
- package/dist/chunk-D5ABGAF4.js.map +1 -0
- package/dist/chunk-GI24QVXE.js +1099 -0
- package/dist/chunk-GI24QVXE.js.map +1 -0
- package/dist/chunk-IRZQYMHD.js +334 -0
- package/dist/chunk-IRZQYMHD.js.map +1 -0
- package/dist/{chunk-WJ6WARGG.js → chunk-RMHUYJXB.js} +46 -47
- package/dist/chunk-RMHUYJXB.js.map +1 -0
- package/dist/chunk-THOE33LU.js +1124 -0
- package/dist/chunk-THOE33LU.js.map +1 -0
- package/dist/chunk-WRBNOPFA.js +1235 -0
- package/dist/chunk-WRBNOPFA.js.map +1 -0
- package/dist/cli.js +15488 -15613
- package/dist/cli.js.map +1 -1
- package/dist/gateway/worker.d.ts +2 -0
- package/dist/gateway/worker.js +181 -0
- package/dist/gateway/worker.js.map +1 -0
- package/dist/privacy-gateway-Q4GD2JXF.js +20 -0
- package/dist/store-LLXL7QYG.js +11 -0
- package/dist/{v3-adapter-T3IKK3LU.js → v3-adapter-KA2NOVI5.js} +2 -2
- package/dist/v3-adapter-KA2NOVI5.js.map +1 -0
- package/docs/README.md +34 -0
- package/docs/privacy-guide.md +76 -0
- package/docs/privacy-implementation-plan.md +101 -0
- package/docs/privacy-rule-sources.md +22 -0
- package/docs/privacy-upstream-license.txt +661 -0
- package/package.json +10 -4
- package/dist/chunk-7HPP3KYG.js.map +0 -1
- package/dist/chunk-WJ6WARGG.js.map +0 -1
- package/dist/store-LN63OL66.js +0 -9
- /package/dist/{store-LN63OL66.js.map → privacy-gateway-Q4GD2JXF.js.map} +0 -0
- /package/dist/{v3-adapter-T3IKK3LU.js.map → store-LLXL7QYG.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/gateway/errors.ts","../src/gateway/json.ts","../src/gateway/mapping.ts","../src/gateway/protocol.ts","../src/gateway/sse.ts"],"sourcesContent":["export class GatewayError extends Error {\n constructor(\n public readonly code: string,\n public readonly status = 400,\n ) {\n super(code);\n }\n}\n\nexport function gatewayErrorCode(error: unknown): string {\n return error instanceof GatewayError ? error.code : 'MANCODE_GATEWAY_FAILED';\n}\n","import { type Node, type ParseError, parseTree } from 'jsonc-parser';\nimport { GatewayError } from './errors.js';\n\nexport type JsonPath = (string | number)[];\nexport interface JsonEdit {\n offset: number;\n length: number;\n text: string;\n}\n\n/** Strict JSON validation with source offsets; never reserialize numeric values. */\nexport function parseStrictJson(source: string): Node {\n if (Buffer.byteLength(source) > 1024 * 1024)\n throw new GatewayError('MANCODE_GATEWAY_JSON_LIMIT');\n // Bound allocation and recursion before the recursive parser sees the input.\n let depth = 0;\n let structures = 0;\n let inString = false;\n let escaped = false;\n for (const character of source) {\n if (inString) {\n if (escaped) escaped = false;\n else if (character === '\\\\') escaped = true;\n else if (character === '\"') inString = false;\n } else if (character === '\"') inString = true;\n else if (character === '{' || character === '[') {\n if (++depth > 48 || ++structures > 8000)\n throw new GatewayError('MANCODE_GATEWAY_JSON_LIMIT');\n } else if (character === '}' || character === ']') depth--;\n else if ((character === ',' || character === ':') && ++structures > 8000)\n throw new GatewayError('MANCODE_GATEWAY_JSON_LIMIT');\n }\n const errors: ParseError[] = [];\n const tree = parseTree(source, errors, {\n allowTrailingComma: false,\n disallowComments: true,\n allowEmptyContent: false,\n });\n if (!tree || errors.length)\n throw new GatewayError('MANCODE_GATEWAY_INVALID_JSON');\n let count = 0;\n const visit = (node: Node, depth: number): void => {\n if (depth > 48 || ++count > 40_000)\n throw new GatewayError('MANCODE_GATEWAY_JSON_LIMIT');\n if (node.type === 'object') {\n const keys = new Set<string>();\n for (const property of node.children ?? []) {\n const key = property.children?.[0]?.value;\n if (keys.has(key))\n throw new GatewayError('MANCODE_GATEWAY_DUPLICATE_KEY');\n keys.add(key);\n }\n }\n for (const child of node.children ?? []) visit(child, depth + 1);\n };\n visit(tree, 0);\n return tree;\n}\n\nexport function property(node: Node, name: string): Node | undefined {\n return node.type === 'object'\n ? node.children?.find((child) => child.children?.[0]?.value === name)\n ?.children?.[1]\n : undefined;\n}\n\nexport function stringValue(node: Node | undefined): string | undefined {\n return node?.type === 'string' ? (node.value as string) : undefined;\n}\n\nexport function applyJsonEdits(input: string, edits: JsonEdit[]): string {\n let source = input;\n let last = source.length;\n for (const edit of [...edits].sort((a, b) => b.offset - a.offset)) {\n if (edit.offset + edit.length > last)\n throw new GatewayError('MANCODE_GATEWAY_OVERLAPPING_EDIT');\n source =\n source.slice(0, edit.offset) +\n edit.text +\n source.slice(edit.offset + edit.length);\n last = edit.offset;\n }\n return source;\n}\n\nexport function replaceString(\n edits: JsonEdit[],\n node: Node,\n value: string,\n): void {\n if (value !== node.value)\n edits.push({\n offset: node.offset,\n length: node.length,\n text: JSON.stringify(value),\n });\n}\n","import { randomBytes } from 'node:crypto';\nimport { scanSensitiveText } from '../privacy/detect.js';\nimport { GatewayError } from './errors.js';\n\nexport const TOKEN_PREFIX = '__MANCODE_';\nconst TOKEN_PATTERN = /__MANCODE_[a-f0-9]{32}__/g;\ninterface Entry {\n original: string;\n expires: number;\n pins: number;\n bytes: number;\n}\ninterface Lineage {\n tokens: Set<string>;\n expires: number;\n}\nexport interface MappingLimits {\n entries: number;\n bytes: number;\n ttlMs: number;\n lineage: number;\n}\nexport const DEFAULT_MAPPING_LIMITS: MappingLimits = {\n entries: 4096,\n bytes: 4 * 1024 * 1024,\n ttlMs: 15 * 60_000,\n lineage: 256,\n};\n\n/** One authenticated principal / checkout / launch / upstream / policy scope. */\nexport class MappingStore {\n private entries = new Map<string, Entry>();\n private originals = new Map<string, string>();\n private responses = new Map<string, Lineage>();\n private bytes = 0;\n constructor(\n readonly scope: string,\n private readonly limits = DEFAULT_MAPPING_LIMITS,\n private readonly now = Date.now,\n ) {}\n\n begin(previousResponseId?: string): RequestMapping {\n this.prune();\n const inherited = previousResponseId\n ? this.responses.get(previousResponseId)\n : undefined;\n if (previousResponseId && !inherited)\n throw new GatewayError('MANCODE_GATEWAY_HISTORY_UNAVAILABLE');\n const request = new RequestMapping(this);\n for (const token of inherited?.tokens ?? []) request.authorize(token);\n return request;\n }\n\n allocate(original: string): string {\n this.prune();\n const existing = this.originals.get(original);\n if (existing) return existing;\n const bytes = Buffer.byteLength(original);\n if (\n this.entries.size >= this.limits.entries ||\n this.bytes + bytes > this.limits.bytes\n )\n throw new GatewayError('MANCODE_GATEWAY_MAPPING_CAPACITY', 429);\n const token = `${TOKEN_PREFIX}${randomBytes(16).toString('hex')}__`;\n this.entries.set(token, {\n original,\n expires: this.now() + this.limits.ttlMs,\n pins: 0,\n bytes,\n });\n this.originals.set(original, token);\n this.bytes += bytes;\n return token;\n }\n\n pin(token: string): void {\n const entry = this.entries.get(token);\n if (!entry) throw new GatewayError('MANCODE_GATEWAY_UNKNOWN_TOKEN');\n entry.pins++;\n }\n\n original(token: string): string {\n const entry = this.entries.get(token);\n if (!entry) throw new GatewayError('MANCODE_GATEWAY_UNKNOWN_TOKEN');\n return entry.original;\n }\n\n finish(tokens: Set<string>, responseId?: string): void {\n if (responseId) {\n if (this.responses.has(responseId))\n throw new GatewayError('MANCODE_GATEWAY_RESPONSE_REPLAY');\n if (this.responses.size >= this.limits.lineage)\n this.responses.delete(this.responses.keys().next().value as string);\n this.responses.set(responseId, {\n tokens: new Set(tokens),\n expires: this.now() + this.limits.ttlMs,\n });\n }\n }\n\n release(tokens: Set<string>): void {\n for (const token of tokens) {\n const entry = this.entries.get(token);\n if (entry) {\n entry.pins--;\n entry.expires = this.now() + this.limits.ttlMs;\n }\n }\n }\n\n private prune(): void {\n for (const [token, entry] of this.entries)\n if (entry.pins === 0 && entry.expires <= this.now()) {\n this.entries.delete(token);\n this.originals.delete(entry.original);\n this.bytes -= entry.bytes;\n }\n for (const [id, lineage] of this.responses)\n if (\n lineage.expires <= this.now() ||\n [...lineage.tokens].some((token) => !this.entries.has(token))\n )\n this.responses.delete(id);\n }\n}\n\nexport class RequestMapping {\n readonly authorized = new Set<string>();\n claudeReadAllowed = false;\n private released = false;\n constructor(private readonly store: MappingStore) {}\n authorize(token: string): void {\n if (this.authorized.has(token)) return;\n this.store.pin(token);\n this.authorized.add(token);\n }\n\n mask(input: string, ruleIds?: readonly string[]): string {\n let value = input;\n // Only complete existing tokens in this scope may appear in client history.\n for (const match of value.matchAll(TOKEN_PATTERN)) this.authorize(match[0]);\n if (value.replace(TOKEN_PATTERN, '').includes(TOKEN_PREFIX))\n throw new GatewayError('MANCODE_GATEWAY_MALFORMED_TOKEN');\n const scan = scanSensitiveText(value, ruleIds);\n if (scan.status !== 'complete')\n throw new GatewayError('MANCODE_GATEWAY_SCAN_FAILED');\n const ranges: { start: number; end: number }[] = [];\n for (const finding of scan.findings) {\n const last = ranges.at(-1);\n if (last && finding.start <= last.end)\n last.end = Math.max(last.end, finding.end);\n else ranges.push({ start: finding.start, end: finding.end });\n }\n for (const range of ranges.reverse()) {\n const original = value.slice(range.start, range.end);\n const token = this.store.allocate(original);\n this.authorize(token);\n value = value.slice(0, range.start) + token + value.slice(range.end);\n }\n return value;\n }\n maskLiteral(value: string): string {\n if (value === '') return value;\n if (/^__MANCODE_[a-f0-9]{32}__$/.test(value)) {\n this.authorize(value);\n return value;\n }\n if (value.includes(TOKEN_PREFIX))\n throw new GatewayError('MANCODE_GATEWAY_MALFORMED_TOKEN');\n const token = this.store.allocate(value);\n this.authorize(token);\n return token;\n }\n\n restore(value: string): string {\n const stripped = value.replace(TOKEN_PATTERN, '');\n if (stripped.includes(TOKEN_PREFIX))\n throw new GatewayError('MANCODE_GATEWAY_MALFORMED_TOKEN');\n return value.replace(TOKEN_PATTERN, (token) => {\n if (!this.authorized.has(token))\n throw new GatewayError('MANCODE_GATEWAY_UNAUTHORIZED_TOKEN');\n return this.store.original(token);\n });\n }\n\n finish(responseId?: string): void {\n this.store.finish(this.authorized, responseId);\n }\n withoutKnownEchoes(value: string): string {\n let result = value;\n const originals = [...this.authorized]\n .map((token) => this.store.original(token))\n .sort((a, b) => b.length - a.length);\n for (const original of originals) result = result.split(original).join('');\n return result;\n }\n release(): void {\n if (!this.released) {\n this.released = true;\n this.store.release(this.authorized);\n }\n }\n}\n\nexport class IncrementalRestorer {\n private pending = '';\n constructor(private readonly mapping: RequestMapping) {}\n push(input: string, final = false): string {\n let value = this.pending + input;\n this.pending = '';\n if (!final) {\n const tokenStart = value.lastIndexOf(TOKEN_PREFIX);\n if (\n tokenStart >= 0 &&\n value.length - tokenStart < TOKEN_PREFIX.length + 34\n ) {\n this.pending = value.slice(tokenStart);\n value = value.slice(0, tokenStart);\n } else\n for (let length = TOKEN_PREFIX.length - 1; length > 0; length--) {\n const lastComplete = [...value.matchAll(TOKEN_PATTERN)].at(-1);\n const completeEnd = lastComplete\n ? lastComplete.index + lastComplete[0].length\n : 0;\n if (\n value.length - length >= completeEnd &&\n value.endsWith(TOKEN_PREFIX.slice(0, length))\n ) {\n this.pending = value.slice(-length);\n value = value.slice(0, -length);\n break;\n }\n }\n }\n return this.mapping.restore(value);\n }\n}\n","import { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport type { Node } from 'jsonc-parser';\nimport { scanSensitiveText } from '../privacy/detect.js';\nimport { GatewayError } from './errors.js';\nimport {\n type JsonEdit,\n applyJsonEdits,\n parseStrictJson,\n property,\n replaceString,\n stringValue,\n} from './json.js';\nimport { type RequestMapping, TOKEN_PREFIX } from './mapping.js';\n\nexport type GatewayProtocol = 'responses' | 'messages';\nexport interface TransformResult {\n body: string;\n opaqueBlocks: number;\n}\nconst SENSITIVE_NUMBER_KEY =\n /(?:phone|mobile|telephone|id_?card|card_?number|account_?number|ssn)/i;\nconst CREDENTIAL_KEY =\n /(?:^|[_-])(?:password|passwd|secret|token|api[_-]?key|access[_-]?key|authorization|cookie)$/i;\n\nfunction assertNoSensitive(value: string, rules?: readonly string[]): void {\n const scan = scanSensitiveText(value, rules);\n if (scan.status !== 'complete')\n throw new GatewayError('MANCODE_GATEWAY_SCAN_FAILED');\n if (scan.findings.length || value.includes(TOKEN_PREFIX))\n throw new GatewayError('MANCODE_GATEWAY_SENSITIVE_STRUCTURE');\n}\n\n/** Business values are not protocol metadata merely because a key is called call_id. */\nfunction transformData(\n source: string,\n node: Node,\n edits: JsonEdit[],\n mapping: RequestMapping,\n restore: boolean,\n rules?: readonly string[],\n key = '',\n): void {\n const credential =\n !restore &&\n CREDENTIAL_KEY.test(key) &&\n (!rules || rules.includes('named-secret'));\n if (credential && (node.type === 'object' || node.type === 'array'))\n throw new GatewayError('MANCODE_GATEWAY_CREDENTIAL_CONTAINER_UNSUPPORTED');\n if (node.type === 'string') {\n replaceString(\n edits,\n node,\n restore\n ? mapping.restore(node.value)\n : credential\n ? mapping.maskLiteral(node.value)\n : mapping.mask(node.value, rules),\n );\n } else if (\n (node.type === 'number' && SENSITIVE_NUMBER_KEY.test(key)) ||\n (credential &&\n node.type !== 'object' &&\n node.type !== 'array' &&\n node.type !== 'null')\n ) {\n throw new GatewayError('MANCODE_GATEWAY_SENSITIVE_NUMBER');\n } else if (node.type === 'object') {\n for (const field of node.children ?? []) {\n const name = field.children?.[0];\n const value = field.children?.[1];\n if (!name || !value)\n throw new GatewayError('MANCODE_GATEWAY_INVALID_JSON');\n assertNoSensitive(name.value, rules);\n transformData(source, value, edits, mapping, restore, rules, name.value);\n }\n } else\n for (const value of node.children ?? [])\n transformData(source, value, edits, mapping, restore, rules, key);\n}\n\nfunction scanStructure(\n source: string,\n node: Node,\n rules?: readonly string[],\n): void {\n if (node.type === 'string') assertNoSensitive(node.value, rules);\n else\n for (const child of node.children ?? [])\n scanStructure(source, child, rules);\n}\n\n/** Descriptive schema text is model context; constraints and property names stay exact. */\nfunction transformToolDefinitions(\n source: string,\n node: Node,\n edits: JsonEdit[],\n mapping: RequestMapping,\n rules?: readonly string[],\n fieldName = '',\n): void {\n if (\n node.type === 'string' &&\n (fieldName === 'description' || fieldName === 'title')\n ) {\n replaceString(edits, node, mapping.mask(node.value, rules));\n return;\n }\n if (node.type === 'object') {\n for (const field of node.children ?? []) {\n const key = field.children?.[0];\n const value = field.children?.[1];\n if (!key || !value)\n throw new GatewayError('MANCODE_GATEWAY_INVALID_JSON');\n assertNoSensitive(key.value, rules);\n if (\n key.value === 'enum' ||\n key.value === 'const' ||\n key.value === 'pattern' ||\n key.value === 'required'\n )\n scanStructure(source, value, rules);\n else\n transformToolDefinitions(\n source,\n value,\n edits,\n mapping,\n rules,\n key.value,\n );\n }\n } else if (node.type === 'array')\n for (const child of node.children ?? [])\n transformToolDefinitions(source, child, edits, mapping, rules, fieldName);\n else scanStructure(source, node, rules);\n}\n\nfunction transformText(\n value: string,\n mapping: RequestMapping,\n restore: boolean,\n rules?: readonly string[],\n): string {\n if (!restore && /^[\\s]*[\\[{]/.test(value)) {\n try {\n const tree = parseStrictJson(value);\n const edits: JsonEdit[] = [];\n transformData(value, tree, edits, mapping, false, rules);\n return applyJsonEdits(value, edits);\n } catch (error) {\n if (\n !(error instanceof GatewayError) ||\n error.code !== 'MANCODE_GATEWAY_INVALID_JSON'\n )\n throw error;\n }\n }\n return restore ? mapping.restore(value) : mapping.mask(value, rules);\n}\n\nconst CLAUDE_READ_SCHEMA_SHA256 =\n '384be111a755f235f20b1c632d0ed1a665e9f16d191f02108e80232c7fc4b488';\nfunction canonical(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(canonical);\n if (value && typeof value === 'object')\n return Object.fromEntries(\n Object.entries(value)\n .sort(([a], [b]) => a.localeCompare(b, 'en'))\n .map(([key, child]) => [key, canonical(child)]),\n );\n return value;\n}\n\n/** Only the captured Claude Code 2.1.142 Read schema has an audited data sink. */\nexport function restoreToolArguments(\n source: string,\n mapping?: RequestMapping,\n name?: string,\n): string {\n const tree = parseStrictJson(source);\n let needsRestore = false;\n const inspect = (node: Node): void => {\n if (node.type === 'string' && node.value.includes(TOKEN_PREFIX))\n needsRestore = true;\n for (const child of node.children ?? []) inspect(child);\n };\n inspect(tree);\n if (!needsRestore) return source;\n if (!mapping?.claudeReadAllowed || name !== 'Read' || tree.type !== 'object')\n throw new GatewayError('MANCODE_GATEWAY_TOOL_SINK_UNSUPPORTED');\n for (const field of tree.children ?? []) {\n const key = field.children?.[0]?.value;\n const value = field.children?.[1];\n if (key === 'file_path') continue;\n if (\n (key === 'offset' || key === 'limit') &&\n value?.type === 'number' &&\n Number.isSafeInteger(value.value) &&\n value.value >= (key === 'offset' ? 0 : 1)\n )\n continue;\n if (\n key === 'pages' &&\n value?.type === 'string' &&\n /^\\d+(?:-\\d+)?$/.test(value.value)\n )\n continue;\n throw new GatewayError('MANCODE_GATEWAY_TOOL_SINK_UNSUPPORTED');\n }\n const filePath = property(tree, 'file_path');\n if (\n filePath?.type !== 'string' ||\n !/^__MANCODE_[a-f0-9]{32}__$/.test(filePath.value)\n )\n throw new GatewayError('MANCODE_GATEWAY_TOOL_PATH_COMPOSITION');\n const restored = mapping.restore(filePath.value);\n if (\n (!path.isAbsolute(restored) && !path.win32.isAbsolute(restored)) ||\n /[\\0\\r\\n]/.test(restored) ||\n restored.startsWith('//') ||\n restored.startsWith('\\\\\\\\')\n )\n throw new GatewayError('MANCODE_GATEWAY_TOOL_PATH_INVALID');\n const edits: JsonEdit[] = [];\n replaceString(edits, filePath, restored);\n return applyJsonEdits(source, edits);\n}\n\nfunction content(\n source: string,\n node: Node,\n edits: JsonEdit[],\n mapping: RequestMapping,\n restore: boolean,\n coverage: { opaque: number },\n rules?: readonly string[],\n): void {\n if (node.type === 'string') {\n replaceString(\n edits,\n node,\n transformText(node.value, mapping, restore, rules),\n );\n return;\n }\n if (node.type === 'array') {\n for (const child of node.children ?? [])\n content(source, child, edits, mapping, restore, coverage, rules);\n return;\n }\n if (node.type !== 'object')\n throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_CONTENT');\n const type = stringValue(property(node, 'type'));\n const allowed: Record<string, string[]> = {\n message: ['type', 'role', 'content', 'id', 'status', 'phase'],\n input_text: ['type', 'text', 'cache_control'],\n output_text: ['type', 'text', 'annotations', 'logprobs'],\n text: ['type', 'text', 'cache_control', 'citations'],\n refusal: ['type', 'refusal'],\n function_call: ['type', 'id', 'call_id', 'name', 'arguments', 'status'],\n tool_use: ['type', 'id', 'name', 'input', 'cache_control'],\n function_call_output: ['type', 'id', 'call_id', 'output', 'status'],\n tool_result: [\n 'type',\n 'tool_use_id',\n 'content',\n 'is_error',\n 'cache_control',\n ],\n thinking: ['type', 'thinking', 'signature', 'cache_control'],\n redacted_thinking: ['type', 'data', 'cache_control'],\n reasoning: ['type', 'id', 'summary', 'encrypted_content', 'status'],\n };\n const keys = allowed[type ?? (property(node, 'role') ? 'message' : '')];\n if (\n !keys ||\n node.children?.some((field) => !keys.includes(field.children?.[0]?.value))\n )\n throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_CONTENT');\n for (const name of [\n 'id',\n 'call_id',\n 'tool_use_id',\n 'name',\n 'role',\n 'status',\n 'phase',\n 'type',\n ]) {\n const value = property(node, name);\n if (value && (value.type !== 'string' || value.value.length > 256))\n throw new GatewayError('MANCODE_GATEWAY_INVALID_PROTOCOL_ID');\n }\n const cacheControl = property(node, 'cache_control');\n if (cacheControl) scanStructure(source, cacheControl, rules);\n if (\n type === 'thinking' ||\n type === 'redacted_thinking' ||\n type === 'reasoning'\n ) {\n coverage.opaque++;\n return;\n }\n if (\n type === 'input_text' ||\n type === 'output_text' ||\n type === 'text' ||\n type === 'refusal'\n ) {\n const field = property(node, type === 'refusal' ? 'refusal' : 'text');\n if (!field || field.type !== 'string')\n throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_CONTENT');\n replaceString(\n edits,\n field,\n transformText(field.value, mapping, restore, rules),\n );\n for (const child of node.children ?? []) {\n const name = child.children?.[0]?.value;\n const value = child.children?.[1];\n if (value && name !== 'text' && name !== 'refusal' && name !== 'type')\n scanStructure(source, value, rules);\n }\n return;\n }\n if (type === 'function_call' || type === 'tool_use') {\n const args = property(\n node,\n type === 'function_call' ? 'arguments' : 'input',\n );\n if (!args) throw new GatewayError('MANCODE_GATEWAY_TOOL_ARGUMENTS_MISSING');\n if (args.type === 'string') {\n const inner = args.value as string;\n if (restore)\n replaceString(\n edits,\n args,\n restoreToolArguments(\n inner,\n mapping,\n stringValue(property(node, 'name')),\n ),\n );\n else {\n const innerEdits: JsonEdit[] = [];\n transformData(\n inner,\n parseStrictJson(inner),\n innerEdits,\n mapping,\n false,\n rules,\n );\n replaceString(edits, args, applyJsonEdits(inner, innerEdits));\n }\n } else if (type === 'tool_use' && args.type === 'object') {\n if (restore) {\n const restored = restoreToolArguments(\n source.slice(args.offset, args.offset + args.length),\n mapping,\n stringValue(property(node, 'name')),\n );\n edits.push({\n offset: args.offset,\n length: args.length,\n text: restored,\n });\n } else transformData(source, args, edits, mapping, false, rules);\n } else throw new GatewayError('MANCODE_GATEWAY_INVALID_TOOL_ARGUMENTS');\n return;\n }\n if (type === 'function_call_output' || type === 'tool_result') {\n const field = property(\n node,\n type === 'function_call_output' ? 'output' : 'content',\n );\n if (!field) throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_CONTENT');\n content(source, field, edits, mapping, restore, coverage, rules);\n return;\n }\n if (type === 'message' || (!type && property(node, 'role'))) {\n const field = property(node, 'content');\n if (!field) throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_CONTENT');\n content(source, field, edits, mapping, restore, coverage, rules);\n return;\n }\n throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_CONTENT');\n}\n\nconst REQUEST_FIELDS = {\n responses: new Set([\n 'model',\n 'input',\n 'instructions',\n 'tools',\n 'tool_choice',\n 'parallel_tool_calls',\n 'store',\n 'stream',\n 'temperature',\n 'top_p',\n 'max_output_tokens',\n 'text',\n 'reasoning',\n 'metadata',\n 'previous_response_id',\n 'include',\n 'service_tier',\n 'prompt_cache_key',\n 'prompt_cache_retention',\n 'truncation',\n 'user',\n 'safety_identifier',\n 'client_metadata',\n ]),\n messages: new Set([\n 'model',\n 'messages',\n 'system',\n 'tools',\n 'tool_choice',\n 'stream',\n 'temperature',\n 'top_p',\n 'top_k',\n 'max_tokens',\n 'stop_sequences',\n 'metadata',\n 'thinking',\n 'service_tier',\n 'context_management',\n 'output_config',\n ]),\n};\n\nexport function transformRequest(\n source: string,\n protocol: GatewayProtocol,\n mapping: RequestMapping,\n rules?: readonly string[],\n verifiedHost?: string,\n): TransformResult {\n const tree = parseStrictJson(source);\n const edits: JsonEdit[] = [];\n const coverage = { opaque: 0 };\n if (tree.type !== 'object')\n throw new GatewayError('MANCODE_GATEWAY_INVALID_REQUEST');\n const bodyField = protocol === 'responses' ? 'input' : 'messages';\n if (!property(tree, bodyField))\n throw new GatewayError('MANCODE_GATEWAY_INVALID_REQUEST');\n for (const child of tree.children ?? []) {\n const name = child.children?.[0]?.value as string;\n const value = child.children?.[1];\n if (!value || !REQUEST_FIELDS[protocol].has(name))\n throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_FIELD');\n if (name === bodyField || name === 'system' || name === 'instructions')\n content(source, value, edits, mapping, false, coverage, rules);\n else if (name === 'metadata' || name === 'client_metadata')\n transformData(source, value, edits, mapping, false, rules);\n else if (name === 'context_management') {\n const control = JSON.parse(\n source.slice(value.offset, value.offset + value.length),\n );\n if (\n JSON.stringify(canonical(control)) !==\n JSON.stringify(\n canonical({\n edits: [{ type: 'clear_thinking_20251015', keep: 'all' }],\n }),\n )\n )\n throw new GatewayError('MANCODE_GATEWAY_CONTEXT_CONTROL_UNSUPPORTED');\n } else if (name === 'output_config') {\n const effort = stringValue(property(value, 'effort'));\n if (\n value.type !== 'object' ||\n value.children?.length !== 1 ||\n !effort ||\n !['low', 'medium', 'high', 'max'].includes(effort)\n )\n throw new GatewayError('MANCODE_GATEWAY_OUTPUT_CONFIG_UNSUPPORTED');\n } else if (name === 'previous_response_id') {\n if (value.type !== 'string')\n throw new GatewayError('MANCODE_GATEWAY_INVALID_HISTORY');\n } else {\n if (\n name === 'tools' &&\n protocol === 'messages' &&\n verifiedHost === 'claude-code/2.1.142'\n ) {\n for (const tool of value.children ?? []) {\n const schema = property(tool, 'input_schema');\n if (stringValue(property(tool, 'name')) === 'Read' && schema) {\n const schemaValue = JSON.parse(\n source.slice(schema.offset, schema.offset + schema.length),\n );\n const digest = createHash('sha256')\n .update(JSON.stringify(canonical(schemaValue)))\n .digest('hex');\n mapping.claudeReadAllowed = digest === CLAUDE_READ_SCHEMA_SHA256;\n }\n }\n }\n if (name === 'tools')\n transformToolDefinitions(source, value, edits, mapping, rules);\n else scanStructure(source, value, rules);\n }\n }\n return { body: applyJsonEdits(source, edits), opaqueBlocks: coverage.opaque };\n}\n\nexport function transformResponse(\n source: string,\n protocol: GatewayProtocol,\n mapping: RequestMapping,\n): TransformResult {\n const tree = parseStrictJson(source);\n const edits: JsonEdit[] = [];\n const coverage = { opaque: 0 };\n const output = property(\n tree,\n protocol === 'responses' ? 'output' : 'content',\n );\n if (!output) throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_RESPONSE');\n content(source, output, edits, mapping, true, coverage);\n return { body: applyJsonEdits(source, edits), opaqueBlocks: coverage.opaque };\n}\n\nexport function transformContentItem(\n source: string,\n mapping: RequestMapping,\n): TransformResult {\n const tree = parseStrictJson(source);\n const edits: JsonEdit[] = [];\n const coverage = { opaque: 0 };\n content(source, tree, edits, mapping, true, coverage);\n return { body: applyJsonEdits(source, edits), opaqueBlocks: coverage.opaque };\n}\n","import type { Node } from 'jsonc-parser';\nimport { GatewayError } from './errors.js';\nimport {\n type JsonEdit,\n applyJsonEdits,\n parseStrictJson,\n property,\n replaceString,\n stringValue,\n} from './json.js';\nimport { IncrementalRestorer, type RequestMapping } from './mapping.js';\nimport {\n type GatewayProtocol,\n restoreToolArguments,\n transformContentItem,\n transformResponse,\n} from './protocol.js';\n\nexport interface SseFrame {\n event?: string;\n data: string;\n}\nexport class SseDecoder {\n private decoder = new TextDecoder('utf-8', { fatal: true });\n private pending = '';\n constructor(private readonly maxEventBytes = 256 * 1024) {}\n push(chunk: Uint8Array, final = false): SseFrame[] {\n try {\n this.pending += this.decoder.decode(chunk, { stream: !final });\n } catch {\n throw new GatewayError('MANCODE_GATEWAY_INVALID_UTF8');\n }\n const frames: SseFrame[] = [];\n for (;;) {\n const match = /\\r?\\n\\r?\\n/.exec(this.pending);\n if (!match) break;\n const block = this.pending.slice(0, match.index);\n this.pending = this.pending.slice(match.index + match[0].length);\n if (Buffer.byteLength(block) > this.maxEventBytes)\n throw new GatewayError('MANCODE_GATEWAY_EVENT_LIMIT');\n let event: string | undefined;\n const data: string[] = [];\n for (const line of block.split(/\\r?\\n/)) {\n if (line.startsWith(':') || line === '') continue;\n const colon = line.indexOf(':');\n const name = colon < 0 ? line : line.slice(0, colon);\n const value = colon < 0 ? '' : line.slice(colon + 1).replace(/^ /, '');\n if (name === 'event') event = value;\n else if (name === 'data') data.push(value);\n else throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_SSE_FIELD');\n }\n if (data.length) frames.push({ event, data: data.join('\\n') });\n if (frames.length > 256)\n throw new GatewayError('MANCODE_GATEWAY_EVENT_QUEUE_LIMIT');\n }\n if (Buffer.byteLength(this.pending) > this.maxEventBytes)\n throw new GatewayError('MANCODE_GATEWAY_EVENT_LIMIT');\n if (final && this.pending.trim())\n throw new GatewayError('MANCODE_GATEWAY_TRUNCATED_SSE');\n return frames;\n }\n}\n\nexport function encodeSse(frame: SseFrame): string {\n return `${frame.event ? `event: ${frame.event}\\n` : ''}${frame.data\n .split('\\n')\n .map((line) => `data: ${line}`)\n .join('\\n')}\\n\\n`;\n}\n\ninterface TextChannel {\n restorer: IncrementalRestorer;\n closed: boolean;\n}\ninterface ToolChannel {\n arguments: string;\n closed: boolean;\n initial?: SseFrame;\n name?: string;\n}\nconst RESPONSE_METADATA = new Set(['response.in_progress', 'response.queued']);\nconst OPAQUE_EVENTS = new Set([\n 'response.reasoning_summary_part.added',\n 'response.reasoning_summary_part.done',\n 'response.reasoning_summary_text.delta',\n 'response.reasoning_summary_text.done',\n 'response.reasoning_text.delta',\n 'response.reasoning_text.done',\n]);\n\n/** Incremental plain text; tool arguments remain private until a validated done event. */\nexport class ProtocolStream {\n private texts = new Map<string, TextChannel>();\n private tools = new Map<string, ToolChannel>();\n private anthropicTypes = new Map<number, string>();\n responseId: string | undefined;\n completed = false;\n opaqueBlocks = 0;\n constructor(\n private readonly protocol: GatewayProtocol,\n private readonly mapping: RequestMapping,\n private readonly maxChannels = 128,\n private readonly maxToolBytes = 256 * 1024,\n ) {}\n\n accept(frame: SseFrame): SseFrame[] {\n if (frame.data === '[DONE]') {\n if (!this.completed)\n throw new GatewayError('MANCODE_GATEWAY_TRUNCATED_RESPONSE');\n return [frame];\n }\n if (this.completed)\n throw new GatewayError('MANCODE_GATEWAY_EVENT_AFTER_DONE');\n const tree = parseStrictJson(frame.data);\n const type = stringValue(property(tree, 'type'));\n if (!type || (frame.event && frame.event !== type))\n throw new GatewayError('MANCODE_GATEWAY_EVENT_TYPE_MISMATCH');\n return this.protocol === 'responses'\n ? this.responses(frame, tree, type)\n : this.messages(frame, tree, type);\n }\n\n finish(): void {\n if (!this.completed)\n throw new GatewayError('MANCODE_GATEWAY_TRUNCATED_RESPONSE');\n for (const channel of this.texts.values())\n if (!channel.closed)\n throw new GatewayError('MANCODE_GATEWAY_UNFINISHED_CHANNEL');\n for (const channel of this.tools.values())\n if (!channel.closed)\n throw new GatewayError('MANCODE_GATEWAY_UNFINISHED_TOOL');\n }\n\n private key(tree: Node): string {\n const index = property(tree, 'output_index')?.value;\n const content = property(tree, 'content_index')?.value ?? 0;\n const item = stringValue(property(tree, 'item_id'));\n if (\n !Number.isSafeInteger(index) ||\n index < 0 ||\n !Number.isSafeInteger(content) ||\n content < 0 ||\n !item ||\n item.length > 256\n )\n throw new GatewayError('MANCODE_GATEWAY_CHANNEL_ID_INVALID');\n return `${index}:${content}:${item}`;\n }\n\n private limitChannels(): void {\n if (this.texts.size + this.tools.size >= this.maxChannels)\n throw new GatewayError('MANCODE_GATEWAY_CHANNEL_LIMIT');\n }\n\n private textDelta(key: string, delta: string, done = false): string {\n let channel = this.texts.get(key);\n if (!channel) {\n this.limitChannels();\n channel = {\n restorer: new IncrementalRestorer(this.mapping),\n closed: false,\n };\n this.texts.set(key, channel);\n }\n if (channel.closed)\n throw new GatewayError('MANCODE_GATEWAY_CHANNEL_ALREADY_DONE');\n const restored = channel.restorer.push(delta, done);\n channel.closed = done;\n return restored;\n }\n\n private toolDelta(key: string, delta: string): void {\n let channel = this.tools.get(key);\n if (!channel) {\n this.limitChannels();\n channel = { arguments: '', closed: false };\n this.tools.set(key, channel);\n }\n if (channel.closed)\n throw new GatewayError('MANCODE_GATEWAY_CHANNEL_ALREADY_DONE');\n if (\n Buffer.byteLength(channel.arguments) + Buffer.byteLength(delta) >\n this.maxToolBytes\n )\n throw new GatewayError('MANCODE_GATEWAY_TOOL_LIMIT');\n channel.arguments += delta;\n }\n\n private toolDone(key: string, snapshot?: string): string {\n const channel = this.tools.get(key);\n if (channel?.closed)\n throw new GatewayError('MANCODE_GATEWAY_CHANNEL_ALREADY_DONE');\n if (\n snapshot !== undefined &&\n channel?.arguments &&\n snapshot !== channel.arguments\n )\n throw new GatewayError('MANCODE_GATEWAY_TOOL_SNAPSHOT_MISMATCH');\n const argumentsText = snapshot ?? (channel?.arguments || '{}');\n const restored = restoreToolArguments(\n argumentsText,\n this.mapping,\n channel?.name,\n );\n if (channel) channel.closed = true;\n return restored;\n }\n\n private responses(frame: SseFrame, tree: Node, type: string): SseFrame[] {\n if (type === 'response.created') {\n if (this.responseId)\n throw new GatewayError('MANCODE_GATEWAY_DUPLICATE_RESPONSE');\n const response = property(tree, 'response');\n this.responseId = response && stringValue(property(response, 'id'));\n if (!this.responseId)\n throw new GatewayError('MANCODE_GATEWAY_RESPONSE_ID_MISSING');\n const output = response && property(response, 'output');\n if (output?.children?.length)\n throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_RESPONSE');\n return [frame];\n }\n if (\n type === 'response.output_text.delta' ||\n type === 'response.refusal.delta'\n ) {\n const delta = property(tree, 'delta');\n if (delta?.type !== 'string')\n throw new GatewayError('MANCODE_GATEWAY_INVALID_DELTA');\n const edits: JsonEdit[] = [];\n const value = this.textDelta(this.key(tree), delta.value);\n replaceString(edits, delta, value);\n return value\n ? [{ ...frame, data: applyJsonEdits(frame.data, edits) }]\n : [];\n }\n if (\n type === 'response.output_text.done' ||\n type === 'response.refusal.done'\n ) {\n const fieldName = type === 'response.refusal.done' ? 'refusal' : 'text';\n const field = property(tree, fieldName);\n if (field?.type !== 'string')\n throw new GatewayError('MANCODE_GATEWAY_INVALID_DELTA');\n const tail = this.textDelta(this.key(tree), '', true);\n const edits: JsonEdit[] = [];\n replaceString(edits, field, this.mapping.restore(field.value));\n const output: SseFrame[] = [];\n if (tail) {\n const delta = {\n type: type.replace(/\\.done$/, '.delta'),\n item_id: property(tree, 'item_id')?.value,\n output_index: property(tree, 'output_index')?.value,\n content_index: property(tree, 'content_index')?.value,\n delta: tail,\n };\n output.push({ event: delta.type, data: JSON.stringify(delta) });\n }\n output.push({ ...frame, data: applyJsonEdits(frame.data, edits) });\n return output;\n }\n if (type === 'response.function_call_arguments.delta') {\n const delta = stringValue(property(tree, 'delta'));\n if (delta === undefined)\n throw new GatewayError('MANCODE_GATEWAY_INVALID_DELTA');\n if (!this.tools.has(this.key(tree)))\n throw new GatewayError('MANCODE_GATEWAY_UNKNOWN_TOOL_CHANNEL');\n this.toolDelta(this.key(tree), delta);\n return [];\n }\n if (type === 'response.function_call_arguments.done') {\n const args = stringValue(property(tree, 'arguments'));\n if (args === undefined)\n throw new GatewayError('MANCODE_GATEWAY_INVALID_TOOL_ARGUMENTS');\n const value = this.toolDone(this.key(tree), args);\n // A single complete delta preserves the normal host protocol without exposing partial arguments.\n const delta = {\n type: 'response.function_call_arguments.delta',\n item_id: property(tree, 'item_id')?.value,\n output_index: property(tree, 'output_index')?.value,\n delta: value,\n };\n return [{ event: delta.type, data: JSON.stringify(delta) }, frame];\n }\n if (\n type === 'response.output_item.added' ||\n type === 'response.output_item.done' ||\n type === 'response.content_part.added' ||\n type === 'response.content_part.done'\n ) {\n const item = property(\n tree,\n type.includes('output_item') ? 'item' : 'part',\n );\n if (!item) throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_EVENT');\n if (\n type === 'response.output_item.added' &&\n stringValue(property(item, 'type')) === 'function_call' &&\n stringValue(property(item, 'arguments')) !== ''\n )\n throw new GatewayError('MANCODE_GATEWAY_NONEMPTY_INITIAL_TOOL');\n // Added tool items have empty arguments by protocol; they cannot execute until done.\n if (\n type === 'response.output_item.added' &&\n stringValue(property(item, 'type')) === 'function_call' &&\n stringValue(property(item, 'arguments')) === ''\n ) {\n const itemSource = frame.data.slice(\n item.offset,\n item.offset + item.length,\n );\n const itemTree = parseStrictJson(itemSource);\n const argumentsNode = property(itemTree, 'arguments');\n if (!argumentsNode)\n throw new GatewayError('MANCODE_GATEWAY_INVALID_TOOL_ARGUMENTS');\n transformContentItem(\n applyJsonEdits(itemSource, [\n {\n offset: argumentsNode.offset,\n length: argumentsNode.length,\n text: JSON.stringify('{}'),\n },\n ]),\n this.mapping,\n );\n const index = property(tree, 'output_index')?.value;\n const itemId = stringValue(property(item, 'id'));\n if (!Number.isSafeInteger(index) || index < 0 || !itemId)\n throw new GatewayError('MANCODE_GATEWAY_CHANNEL_ID_INVALID');\n const key = `${index}:0:${itemId}`;\n if (this.tools.has(key))\n throw new GatewayError('MANCODE_GATEWAY_DUPLICATE_TOOL');\n this.toolDelta(key, '');\n const channel = this.tools.get(key) as ToolChannel;\n channel.name = stringValue(property(item, 'name'));\n return [frame];\n }\n const result = transformContentItem(\n frame.data.slice(item.offset, item.offset + item.length),\n this.mapping,\n );\n this.opaqueBlocks += result.opaqueBlocks;\n return [\n {\n ...frame,\n data: applyJsonEdits(frame.data, [\n { offset: item.offset, length: item.length, text: result.body },\n ]),\n },\n ];\n }\n if (type === 'response.completed') {\n const response = property(tree, 'response');\n if (\n !response ||\n stringValue(property(response, 'id')) !== this.responseId\n )\n throw new GatewayError('MANCODE_GATEWAY_RESPONSE_SCOPE_MISMATCH');\n const result = transformResponse(\n frame.data.slice(response.offset, response.offset + response.length),\n 'responses',\n this.mapping,\n );\n this.opaqueBlocks += result.opaqueBlocks;\n this.completed = true;\n this.finish();\n return [\n {\n ...frame,\n data: applyJsonEdits(frame.data, [\n {\n offset: response.offset,\n length: response.length,\n text: result.body,\n },\n ]),\n },\n ];\n }\n if (OPAQUE_EVENTS.has(type)) {\n this.opaqueBlocks++;\n return [frame];\n }\n if (RESPONSE_METADATA.has(type)) return [frame];\n throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_EVENT');\n }\n\n private messages(frame: SseFrame, tree: Node, type: string): SseFrame[] {\n if (type === 'ping') return [frame];\n if (type === 'message_start') {\n if (this.responseId)\n throw new GatewayError('MANCODE_GATEWAY_DUPLICATE_RESPONSE');\n const message = property(tree, 'message');\n this.responseId = message && stringValue(property(message, 'id'));\n if (\n !this.responseId ||\n property(message as Node, 'content')?.children?.length\n )\n throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_RESPONSE');\n return [frame];\n }\n if (type === 'message_delta') return [frame];\n if (type === 'message_stop') {\n this.completed = true;\n this.finish();\n return [frame];\n }\n const index = property(tree, 'index')?.value;\n if (!Number.isSafeInteger(index) || index < 0)\n throw new GatewayError('MANCODE_GATEWAY_CHANNEL_ID_INVALID');\n const key = `messages:${index}`;\n if (type === 'content_block_start') {\n if (\n this.anthropicTypes.has(index) ||\n this.anthropicTypes.size >= this.maxChannels\n )\n throw new GatewayError('MANCODE_GATEWAY_CHANNEL_LIMIT');\n const block = property(tree, 'content_block');\n const blockType = block && stringValue(property(block, 'type'));\n if (!block || !blockType)\n throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_EVENT');\n this.anthropicTypes.set(index, blockType);\n if (blockType === 'tool_use') {\n const input = property(block, 'input');\n if (input?.type !== 'object' || input.children?.length)\n throw new GatewayError('MANCODE_GATEWAY_NONEMPTY_INITIAL_TOOL');\n transformContentItem(\n frame.data.slice(block.offset, block.offset + block.length),\n this.mapping,\n );\n this.toolDelta(key, '');\n const channel = this.tools.get(key) as ToolChannel;\n channel.initial = frame;\n channel.name = stringValue(property(block, 'name'));\n return [];\n }\n const result = transformContentItem(\n frame.data.slice(block.offset, block.offset + block.length),\n this.mapping,\n );\n this.opaqueBlocks += result.opaqueBlocks;\n return [\n {\n ...frame,\n data: applyJsonEdits(frame.data, [\n { offset: block.offset, length: block.length, text: result.body },\n ]),\n },\n ];\n }\n if (type === 'content_block_delta') {\n const delta = property(tree, 'delta');\n const deltaType = delta && stringValue(property(delta, 'type'));\n if (!delta) throw new GatewayError('MANCODE_GATEWAY_INVALID_DELTA');\n if (\n deltaType === 'input_json_delta' &&\n this.anthropicTypes.get(index) === 'tool_use'\n ) {\n const value = stringValue(property(delta, 'partial_json'));\n if (value === undefined)\n throw new GatewayError('MANCODE_GATEWAY_INVALID_DELTA');\n this.toolDelta(key, value);\n return [];\n }\n if (\n deltaType === 'text_delta' &&\n this.anthropicTypes.get(index) === 'text'\n ) {\n const field = property(delta, 'text');\n if (field?.type !== 'string')\n throw new GatewayError('MANCODE_GATEWAY_INVALID_DELTA');\n const edits: JsonEdit[] = [];\n const value = this.textDelta(key, field.value);\n replaceString(edits, field, value);\n return value\n ? [{ ...frame, data: applyJsonEdits(frame.data, edits) }]\n : [];\n }\n if (\n (deltaType === 'thinking_delta' || deltaType === 'signature_delta') &&\n this.anthropicTypes.get(index) === 'thinking'\n ) {\n this.opaqueBlocks++;\n return [frame];\n }\n throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_EVENT');\n }\n if (type === 'content_block_stop') {\n if (!this.anthropicTypes.has(index))\n throw new GatewayError('MANCODE_GATEWAY_CHANNEL_ID_INVALID');\n const tool = this.tools.get(key);\n if (tool) {\n const args = this.toolDone(key);\n const delta = {\n type: 'content_block_delta',\n index,\n delta: { type: 'input_json_delta', partial_json: args },\n };\n return [\n tool.initial as SseFrame,\n { event: delta.type, data: JSON.stringify(delta) },\n frame,\n ];\n }\n const tail = this.texts.has(key) ? this.textDelta(key, '', true) : '';\n if (tail) {\n const delta = {\n type: 'content_block_delta',\n index,\n delta: { type: 'text_delta', text: tail },\n };\n return [{ event: delta.type, data: JSON.stringify(delta) }, frame];\n }\n return [frame];\n }\n throw new GatewayError('MANCODE_GATEWAY_UNSUPPORTED_EVENT');\n }\n}\n"],"mappings":"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","names":["depth","property","content"]}
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
// src/privacy/named-secret.ts
|
|
2
|
+
var NAMED_SECRET_RULE_ID = "named-secret";
|
|
3
|
+
var NAMED_SECRET_ASSIGNMENT = /(?<![A-Za-z0-9_-])(?:-{1,2})?([A-Za-z][A-Za-z0-9_-]{0,127})(?:["']\s*|\s*)[=:]\s*/dg;
|
|
4
|
+
var CREDENTIAL_SUFFIX = /(?:^|[_-])(?:password|passwd|secret|token|api[_-]?key|access[_-]?key)$/i;
|
|
5
|
+
function namedSecretValue(text, match) {
|
|
6
|
+
if (!CREDENTIAL_SUFFIX.test(match[1] ?? "")) return null;
|
|
7
|
+
const valueStart = match.index + match[0].length;
|
|
8
|
+
const quote = text[valueStart];
|
|
9
|
+
if (quote === '"' || quote === "'") {
|
|
10
|
+
const start = valueStart + 1;
|
|
11
|
+
let end2 = start;
|
|
12
|
+
while (end2 < text.length && text[end2] !== quote) {
|
|
13
|
+
end2 += text[end2] === "\\" && end2 + 1 < text.length ? 2 : 1;
|
|
14
|
+
}
|
|
15
|
+
return end2 === start ? null : { start, end: end2, resume: end2 < text.length ? end2 + 1 : end2 };
|
|
16
|
+
}
|
|
17
|
+
const marker = /^\[REDACTED(?::[a-z_,]{1,256})?\]/.exec(
|
|
18
|
+
text.slice(valueStart, valueStart + 270)
|
|
19
|
+
);
|
|
20
|
+
let end = valueStart + (marker?.[0].length ?? 0);
|
|
21
|
+
while (end < text.length && !/[\s'";,]/.test(text[end] ?? "")) end += 1;
|
|
22
|
+
return end === valueStart ? null : { start: valueStart, end, resume: end };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/privacy/validators.ts
|
|
26
|
+
var IDENTITY_WEIGHTS = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
|
|
27
|
+
var IDENTITY_CHECKS = "10X98765432";
|
|
28
|
+
var PROVINCES = /* @__PURE__ */ new Set([
|
|
29
|
+
"11",
|
|
30
|
+
"12",
|
|
31
|
+
"13",
|
|
32
|
+
"14",
|
|
33
|
+
"15",
|
|
34
|
+
"21",
|
|
35
|
+
"22",
|
|
36
|
+
"23",
|
|
37
|
+
"31",
|
|
38
|
+
"32",
|
|
39
|
+
"33",
|
|
40
|
+
"34",
|
|
41
|
+
"35",
|
|
42
|
+
"36",
|
|
43
|
+
"37",
|
|
44
|
+
"41",
|
|
45
|
+
"42",
|
|
46
|
+
"43",
|
|
47
|
+
"44",
|
|
48
|
+
"45",
|
|
49
|
+
"46",
|
|
50
|
+
"50",
|
|
51
|
+
"51",
|
|
52
|
+
"52",
|
|
53
|
+
"53",
|
|
54
|
+
"54",
|
|
55
|
+
"61",
|
|
56
|
+
"62",
|
|
57
|
+
"63",
|
|
58
|
+
"64",
|
|
59
|
+
"65",
|
|
60
|
+
"71",
|
|
61
|
+
"81",
|
|
62
|
+
"82"
|
|
63
|
+
]);
|
|
64
|
+
function isPaymentCard(value) {
|
|
65
|
+
if (!/^(?:[2-6][0-9]{12,18}|[2-6][0-9]{3}([ -])[0-9]{4}\1[0-9]{4}\1[0-9]{1,4}(?:\1[0-9]{3})?|[3-6][0-9]{3}([ -])[0-9]{6}\2[0-9]{5})$/.test(
|
|
66
|
+
value
|
|
67
|
+
))
|
|
68
|
+
return false;
|
|
69
|
+
const digits = value.replace(/[ -]/g, "");
|
|
70
|
+
if (!/^[2-6][0-9]{12,18}$/.test(digits)) return false;
|
|
71
|
+
if (digits.startsWith("2") && (digits.length !== 16 || Number(digits.slice(0, 6)) < 222100 || Number(digits.slice(0, 6)) > 272099))
|
|
72
|
+
return false;
|
|
73
|
+
let sum = 0;
|
|
74
|
+
let double = false;
|
|
75
|
+
for (let index = digits.length - 1; index >= 0; index -= 1) {
|
|
76
|
+
let digit = Number(digits[index]);
|
|
77
|
+
if (double) {
|
|
78
|
+
digit *= 2;
|
|
79
|
+
if (digit > 9) digit -= 9;
|
|
80
|
+
}
|
|
81
|
+
sum += digit;
|
|
82
|
+
double = !double;
|
|
83
|
+
}
|
|
84
|
+
return sum % 10 === 0;
|
|
85
|
+
}
|
|
86
|
+
function isIdentityCard(value, currentYear = (/* @__PURE__ */ new Date()).getUTCFullYear()) {
|
|
87
|
+
if (!/^(?:[0-9]{15}|[0-9]{17}[0-9Xx])$/.test(value)) return false;
|
|
88
|
+
if (!PROVINCES.has(value.slice(0, 2))) return false;
|
|
89
|
+
const legacy = value.length === 15;
|
|
90
|
+
const dateText = legacy ? `19${value.slice(6, 12)}` : value.slice(6, 14);
|
|
91
|
+
const year = Number(dateText.slice(0, 4));
|
|
92
|
+
const month = Number(dateText.slice(4, 6));
|
|
93
|
+
const day = Number(dateText.slice(6, 8));
|
|
94
|
+
const date = new Date(Date.UTC(year, month - 1, day));
|
|
95
|
+
if (year < 1880 || year > currentYear || date.getUTCFullYear() !== year || date.getUTCMonth() !== month - 1 || date.getUTCDate() !== day)
|
|
96
|
+
return false;
|
|
97
|
+
if (legacy) return true;
|
|
98
|
+
const sum = IDENTITY_WEIGHTS.reduce(
|
|
99
|
+
(total, weight, index) => total + Number(value[index]) * weight,
|
|
100
|
+
0
|
|
101
|
+
);
|
|
102
|
+
return value[17]?.toUpperCase() === IDENTITY_CHECKS[sum % 11];
|
|
103
|
+
}
|
|
104
|
+
function isJwt(value) {
|
|
105
|
+
if (!/^[A-Za-z0-9_-]{2,1027}\.[A-Za-z0-9_-]{2,8192}\.[A-Za-z0-9_-]{1,2048}$/.test(
|
|
106
|
+
value
|
|
107
|
+
))
|
|
108
|
+
return false;
|
|
109
|
+
const segments = value.split(".");
|
|
110
|
+
try {
|
|
111
|
+
const decode = (segment) => {
|
|
112
|
+
const bytes = Buffer.from(segment, "base64url");
|
|
113
|
+
if (bytes.toString("base64url") !== segment) return null;
|
|
114
|
+
return JSON.parse(
|
|
115
|
+
new TextDecoder("utf-8", { fatal: true }).decode(bytes)
|
|
116
|
+
);
|
|
117
|
+
};
|
|
118
|
+
const header = decode(segments[0] ?? "");
|
|
119
|
+
const payload = decode(segments[1] ?? "");
|
|
120
|
+
return header !== null && typeof header === "object" && !Array.isArray(header) && "alg" in header && typeof header.alg === "string" && header.alg.length > 0 && payload !== null && typeof payload === "object" && !Array.isArray(payload);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (error instanceof SyntaxError || error instanceof TypeError)
|
|
123
|
+
return false;
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/privacy/rules.ts
|
|
129
|
+
var RULESET_VERSION = "mancode-sensitive-text:1";
|
|
130
|
+
var PRIVATE_KEY_RULE_ID = "pem-private-key";
|
|
131
|
+
var SENSITIVE_RULES = [
|
|
132
|
+
{
|
|
133
|
+
id: "authorization-header",
|
|
134
|
+
category: "authorization",
|
|
135
|
+
pattern: /\b(?:authorization|proxy-authorization)\s*:\s*(?:bearer|basic|token)\s+[^\s,;]+/dgi
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
id: "cookie-header",
|
|
139
|
+
category: "cookie",
|
|
140
|
+
pattern: /\b(?:set-cookie|cookie)\s*:\s*[^\r\n]+/dgi
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: NAMED_SECRET_RULE_ID,
|
|
144
|
+
category: "secret",
|
|
145
|
+
pattern: NAMED_SECRET_ASSIGNMENT
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: "absolute-local-path",
|
|
149
|
+
category: "absolute_path",
|
|
150
|
+
pattern: /(?:\b[A-Z]:\\|\/(?:Users|home|private|var\/folders|tmp|etc)\/)[^\s'"`]+/dg
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
id: "email-address",
|
|
154
|
+
category: "email",
|
|
155
|
+
// Bounded local/domain parts avoid repeated unbounded suffix searches.
|
|
156
|
+
pattern: /(?<![A-Za-z0-9._%+-])[A-Za-z0-9._%+-]{1,64}@[A-Za-z0-9.-]{1,253}\.[A-Za-z]{2,63}(?![A-Za-z0-9_%+-])/dg
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
id: "vendor-api-key",
|
|
160
|
+
category: "vendor_key",
|
|
161
|
+
pattern: /(?<![A-Za-z0-9_-])(?:gh[pousr]_[A-Za-z0-9]{20,255}|github_pat_[A-Za-z0-9_]{20,255}|sk-(?:proj-|ant-)?[A-Za-z0-9_-]{16,255}|(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,255}|AIza[A-Za-z0-9_-]{30,64}|xox[baprs]-[A-Za-z0-9-]{10,255})(?![A-Za-z0-9_-])/dg
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: "cloud-access-key",
|
|
165
|
+
category: "cloud_key",
|
|
166
|
+
pattern: /(?<![A-Za-z0-9])(?:AKIA[A-Z0-9]{16}|ASIA[A-Z0-9]{16}|LTAI[A-Za-z0-9]{12,32}|AKID[A-Za-z0-9]{13,40})(?![A-Za-z0-9])/dg
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
id: "connection-password",
|
|
170
|
+
category: "connection_password",
|
|
171
|
+
group: 1,
|
|
172
|
+
pattern: /\b[a-z][a-z0-9+.-]{0,31}:\/\/[^\s:@/]{1,255}:([^\s@/]{1,4096})@/dgi
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: "bearer-token",
|
|
176
|
+
category: "authorization",
|
|
177
|
+
group: 1,
|
|
178
|
+
pattern: /\bbearer\s+([A-Za-z0-9._~+/-]+=*)/dgi
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
id: "jwt-token",
|
|
182
|
+
category: "jwt",
|
|
183
|
+
validate: isJwt,
|
|
184
|
+
pattern: /(?<![A-Za-z0-9_-])eyJ[A-Za-z0-9_-]{1,1024}\.[A-Za-z0-9_-]{2,8192}\.[A-Za-z0-9_-]{1,2048}(?![A-Za-z0-9_-])/dg
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
id: "cn-mobile-phone",
|
|
188
|
+
category: "phone",
|
|
189
|
+
pattern: /(?<![A-Za-z0-9_])(?:(?:\+?86|0086|[((]\+?86[))])[ -]?)?1[3-9][0-9](?:([ -])[0-9]{4}\1[0-9]{4}|[0-9]{8})(?![A-Za-z0-9_])/dg
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
id: "cn-identity-card-18",
|
|
193
|
+
category: "identity_card",
|
|
194
|
+
pattern: /(?<![A-Za-z0-9_])[0-9]{17}[0-9Xx](?![A-Za-z0-9_])/dg,
|
|
195
|
+
validation: "checksum",
|
|
196
|
+
validate: isIdentityCard
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
id: "cn-identity-card-15",
|
|
200
|
+
category: "identity_card",
|
|
201
|
+
pattern: /(?<![A-Za-z0-9_])[0-9]{15}(?![A-Za-z0-9_])/dg,
|
|
202
|
+
validate: isIdentityCard
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: "payment-card",
|
|
206
|
+
category: "payment_card",
|
|
207
|
+
pattern: /(?<![A-Za-z0-9_])(?:[2-6][0-9]{12,18}|[2-6][0-9]{3}([ -])[0-9]{4}\1[0-9]{4}\1[0-9]{1,4}(?:\1[0-9]{3})?|[3-6][0-9]{3}([ -])[0-9]{6}\2[0-9]{5})(?![A-Za-z0-9_])/dg,
|
|
208
|
+
validation: "checksum",
|
|
209
|
+
validate: isPaymentCard
|
|
210
|
+
}
|
|
211
|
+
];
|
|
212
|
+
var DEFAULT_RULE_IDS = [
|
|
213
|
+
PRIVATE_KEY_RULE_ID,
|
|
214
|
+
...SENSITIVE_RULES.map((rule) => rule.id)
|
|
215
|
+
];
|
|
216
|
+
|
|
217
|
+
// src/privacy/detect.ts
|
|
218
|
+
import { performance } from "perf_hooks";
|
|
219
|
+
var MAX_SCAN_BYTES = 1024 * 1024;
|
|
220
|
+
var MAX_SCAN_FINDINGS = 4096;
|
|
221
|
+
var SCAN_BUDGET_MS = 500;
|
|
222
|
+
var REDACTED_CATEGORIES = /* @__PURE__ */ new Set([
|
|
223
|
+
"private_key",
|
|
224
|
+
...SENSITIVE_RULES.map((rule) => rule.category)
|
|
225
|
+
]);
|
|
226
|
+
function scanSensitiveText(value, ruleIds = DEFAULT_RULE_IDS) {
|
|
227
|
+
const failed = (reason) => ({
|
|
228
|
+
status: "failed",
|
|
229
|
+
rulesetVersion: RULESET_VERSION,
|
|
230
|
+
findings: [],
|
|
231
|
+
reason
|
|
232
|
+
});
|
|
233
|
+
if (typeof value !== "string" || /\0|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/.test(
|
|
234
|
+
value
|
|
235
|
+
))
|
|
236
|
+
return failed("invalid_text");
|
|
237
|
+
if (Buffer.byteLength(value, "utf8") > MAX_SCAN_BYTES)
|
|
238
|
+
return failed("input_too_large");
|
|
239
|
+
if (ruleIds.some((id) => !DEFAULT_RULE_IDS.includes(id)))
|
|
240
|
+
return failed("unknown_rule");
|
|
241
|
+
const enabled = new Set(ruleIds);
|
|
242
|
+
const started = performance.now();
|
|
243
|
+
const findings = [];
|
|
244
|
+
if (enabled.has(PRIVATE_KEY_RULE_ID)) {
|
|
245
|
+
const begin = /-----BEGIN(?: [A-Z0-9]+)? PRIVATE KEY-----/gi;
|
|
246
|
+
for (let match = begin.exec(value); match !== null; match = begin.exec(value)) {
|
|
247
|
+
const closing = new RegExp(
|
|
248
|
+
match[0].replace(/^-----BEGIN/i, "-----END"),
|
|
249
|
+
"gi"
|
|
250
|
+
);
|
|
251
|
+
closing.lastIndex = begin.lastIndex;
|
|
252
|
+
const close = closing.exec(value);
|
|
253
|
+
const end = close === null ? value.length : close.index + close[0].length;
|
|
254
|
+
findings.push({
|
|
255
|
+
ruleId: PRIVATE_KEY_RULE_ID,
|
|
256
|
+
category: "private_key",
|
|
257
|
+
start: match.index,
|
|
258
|
+
end,
|
|
259
|
+
validation: "shape"
|
|
260
|
+
});
|
|
261
|
+
begin.lastIndex = end;
|
|
262
|
+
if (findings.length > MAX_SCAN_FINDINGS)
|
|
263
|
+
return failed("too_many_findings");
|
|
264
|
+
if (performance.now() - started > SCAN_BUDGET_MS)
|
|
265
|
+
return failed("scan_budget_exceeded");
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
for (const rule of SENSITIVE_RULES) {
|
|
269
|
+
if (!enabled.has(rule.id)) continue;
|
|
270
|
+
const pattern = new RegExp(rule.pattern);
|
|
271
|
+
for (let match = pattern.exec(value); match !== null; match = pattern.exec(value)) {
|
|
272
|
+
if (performance.now() - started > SCAN_BUDGET_MS)
|
|
273
|
+
return failed("scan_budget_exceeded");
|
|
274
|
+
const group = rule.group ?? 0;
|
|
275
|
+
const assignment = rule.id === NAMED_SECRET_RULE_ID ? namedSecretValue(value, match) : void 0;
|
|
276
|
+
if (assignment === null) continue;
|
|
277
|
+
if (assignment !== void 0) pattern.lastIndex = assignment.resume;
|
|
278
|
+
const bounds = assignment === void 0 ? match.indices?.[group] : [assignment.start, assignment.end];
|
|
279
|
+
const candidate = assignment === void 0 ? match[group] : value.slice(assignment.start, assignment.end);
|
|
280
|
+
if (bounds === void 0 || candidate === void 0) continue;
|
|
281
|
+
const markerCategories = /^\[REDACTED:([a-z_,]+)\]$/.exec(candidate)?.[1]?.split(",");
|
|
282
|
+
if (candidate === "[REDACTED]" || markerCategories?.every((category) => REDACTED_CATEGORIES.has(category)))
|
|
283
|
+
continue;
|
|
284
|
+
if (rule.validate !== void 0 && !rule.validate(candidate)) continue;
|
|
285
|
+
findings.push({
|
|
286
|
+
ruleId: rule.id,
|
|
287
|
+
category: rule.category,
|
|
288
|
+
start: bounds[0],
|
|
289
|
+
end: bounds[1],
|
|
290
|
+
validation: rule.validation ?? "shape"
|
|
291
|
+
});
|
|
292
|
+
if (findings.length > MAX_SCAN_FINDINGS)
|
|
293
|
+
return failed("too_many_findings");
|
|
294
|
+
if (performance.now() - started > SCAN_BUDGET_MS)
|
|
295
|
+
return failed("scan_budget_exceeded");
|
|
296
|
+
}
|
|
297
|
+
if (performance.now() - started > SCAN_BUDGET_MS)
|
|
298
|
+
return failed("scan_budget_exceeded");
|
|
299
|
+
}
|
|
300
|
+
findings.sort(
|
|
301
|
+
(left, right) => left.start - right.start || right.end - left.end || left.ruleId.localeCompare(right.ruleId, "en")
|
|
302
|
+
);
|
|
303
|
+
const passwords = findings.filter(
|
|
304
|
+
(finding) => finding.category === "connection_password"
|
|
305
|
+
);
|
|
306
|
+
const filtered = findings.filter((finding) => {
|
|
307
|
+
if (finding.category !== "email") return true;
|
|
308
|
+
let low = 0;
|
|
309
|
+
let high = passwords.length;
|
|
310
|
+
while (low < high) {
|
|
311
|
+
const middle = low + high >>> 1;
|
|
312
|
+
if ((passwords[middle]?.start ?? Number.POSITIVE_INFINITY) <= finding.start)
|
|
313
|
+
low = middle + 1;
|
|
314
|
+
else high = middle;
|
|
315
|
+
}
|
|
316
|
+
const password = passwords[low - 1];
|
|
317
|
+
return password === void 0 || finding.start >= password.end;
|
|
318
|
+
});
|
|
319
|
+
if (performance.now() - started > SCAN_BUDGET_MS)
|
|
320
|
+
return failed("scan_budget_exceeded");
|
|
321
|
+
return {
|
|
322
|
+
status: "complete",
|
|
323
|
+
rulesetVersion: RULESET_VERSION,
|
|
324
|
+
findings: filtered
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export {
|
|
329
|
+
RULESET_VERSION,
|
|
330
|
+
DEFAULT_RULE_IDS,
|
|
331
|
+
MAX_SCAN_BYTES,
|
|
332
|
+
scanSensitiveText
|
|
333
|
+
};
|
|
334
|
+
//# sourceMappingURL=chunk-IRZQYMHD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/privacy/named-secret.ts","../src/privacy/validators.ts","../src/privacy/rules.ts","../src/privacy/detect.ts"],"sourcesContent":["export const NAMED_SECRET_RULE_ID = 'named-secret';\n\n// Match one complete ASCII field name, not a credential word inside a metric.\n// The two separator branches have distinct first characters, avoiding adjacent\n// whitespace quantifiers when an assignment-like line has no ':' or '='.\nexport const NAMED_SECRET_ASSIGNMENT =\n /(?<![A-Za-z0-9_-])(?:-{1,2})?([A-Za-z][A-Za-z0-9_-]{0,127})(?:[\"']\\s*|\\s*)[=:]\\s*/dg;\n\nconst CREDENTIAL_SUFFIX =\n /(?:^|[_-])(?:password|passwd|secret|token|api[_-]?key|access[_-]?key)$/i;\n\nexport function namedSecretValue(\n text: string,\n match: RegExpExecArray,\n): { start: number; end: number; resume: number } | null {\n if (!CREDENTIAL_SUFFIX.test(match[1] ?? '')) return null;\n const valueStart = match.index + match[0].length;\n const quote = text[valueStart];\n if (quote === '\"' || quote === \"'\") {\n const start = valueStart + 1;\n let end = start;\n // Disjoint cursor steps read every code unit at most once. An unfinished\n // quote protects the remaining input rather than falling back to one word.\n while (end < text.length && text[end] !== quote) {\n end += text[end] === '\\\\' && end + 1 < text.length ? 2 : 1;\n }\n return end === start\n ? null\n : { start, end, resume: end < text.length ? end + 1 : end };\n }\n // Preserve generated multi-category markers as one candidate. Validation of\n // the exact marker remains in the scanner; a trailing suffix is still secret.\n const marker = /^\\[REDACTED(?::[a-z_,]{1,256})?\\]/.exec(\n text.slice(valueStart, valueStart + 270),\n );\n let end = valueStart + (marker?.[0].length ?? 0);\n while (end < text.length && !/[\\s'\";,]/.test(text[end] ?? '')) end += 1;\n return end === valueStart ? null : { start: valueStart, end, resume: end };\n}\n","// Rule/validator provenance: see docs/privacy-rule-sources.md.\nconst IDENTITY_WEIGHTS = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];\nconst IDENTITY_CHECKS = '10X98765432';\nconst PROVINCES = new Set([\n '11',\n '12',\n '13',\n '14',\n '15',\n '21',\n '22',\n '23',\n '31',\n '32',\n '33',\n '34',\n '35',\n '36',\n '37',\n '41',\n '42',\n '43',\n '44',\n '45',\n '46',\n '50',\n '51',\n '52',\n '53',\n '54',\n '61',\n '62',\n '63',\n '64',\n '65',\n '71',\n '81',\n '82',\n]);\n\nexport function isPaymentCard(value: string): boolean {\n if (\n !/^(?:[2-6][0-9]{12,18}|[2-6][0-9]{3}([ -])[0-9]{4}\\1[0-9]{4}\\1[0-9]{1,4}(?:\\1[0-9]{3})?|[3-6][0-9]{3}([ -])[0-9]{6}\\2[0-9]{5})$/.test(\n value,\n )\n )\n return false;\n const digits = value.replace(/[ -]/g, '');\n if (!/^[2-6][0-9]{12,18}$/.test(digits)) return false;\n if (\n digits.startsWith('2') &&\n (digits.length !== 16 ||\n Number(digits.slice(0, 6)) < 222100 ||\n Number(digits.slice(0, 6)) > 272099)\n )\n return false;\n let sum = 0;\n let double = false;\n for (let index = digits.length - 1; index >= 0; index -= 1) {\n let digit = Number(digits[index]);\n if (double) {\n digit *= 2;\n if (digit > 9) digit -= 9;\n }\n sum += digit;\n double = !double;\n }\n return sum % 10 === 0;\n}\n\nexport function isIdentityCard(\n value: string,\n currentYear = new Date().getUTCFullYear(),\n): boolean {\n if (!/^(?:[0-9]{15}|[0-9]{17}[0-9Xx])$/.test(value)) return false;\n if (!PROVINCES.has(value.slice(0, 2))) return false;\n const legacy = value.length === 15;\n const dateText = legacy ? `19${value.slice(6, 12)}` : value.slice(6, 14);\n const year = Number(dateText.slice(0, 4));\n const month = Number(dateText.slice(4, 6));\n const day = Number(dateText.slice(6, 8));\n const date = new Date(Date.UTC(year, month - 1, day));\n if (\n year < 1880 ||\n year > currentYear ||\n date.getUTCFullYear() !== year ||\n date.getUTCMonth() !== month - 1 ||\n date.getUTCDate() !== day\n )\n return false;\n if (legacy) return true;\n const sum = IDENTITY_WEIGHTS.reduce(\n (total, weight, index) => total + Number(value[index]) * weight,\n 0,\n );\n return value[17]?.toUpperCase() === IDENTITY_CHECKS[sum % 11];\n}\n\n/** Shape validation only; this does not authenticate a JWT or verify a signature. */\nexport function isJwt(value: string): boolean {\n if (\n !/^[A-Za-z0-9_-]{2,1027}\\.[A-Za-z0-9_-]{2,8192}\\.[A-Za-z0-9_-]{1,2048}$/.test(\n value,\n )\n )\n return false;\n const segments = value.split('.');\n try {\n const decode = (segment: string): unknown => {\n const bytes = Buffer.from(segment, 'base64url');\n if (bytes.toString('base64url') !== segment) return null;\n return JSON.parse(\n new TextDecoder('utf-8', { fatal: true }).decode(bytes),\n );\n };\n const header = decode(segments[0] ?? '');\n const payload = decode(segments[1] ?? '');\n return (\n header !== null &&\n typeof header === 'object' &&\n !Array.isArray(header) &&\n 'alg' in header &&\n typeof header.alg === 'string' &&\n header.alg.length > 0 &&\n payload !== null &&\n typeof payload === 'object' &&\n !Array.isArray(payload)\n );\n } catch (error) {\n if (error instanceof SyntaxError || error instanceof TypeError)\n return false;\n throw error;\n }\n}\n","import {\n NAMED_SECRET_ASSIGNMENT,\n NAMED_SECRET_RULE_ID,\n} from './named-secret.js';\nimport type { SensitiveCategory } from './types.js';\nimport { isIdentityCard, isJwt, isPaymentCard } from './validators.js';\n\n// Adapted rule ideas from Maskit 19ee664; see docs/privacy-rule-sources.md.\nexport const RULESET_VERSION = 'mancode-sensitive-text:1';\nexport const PRIVATE_KEY_RULE_ID = 'pem-private-key';\n\nexport interface SensitiveRule {\n id: string;\n category: SensitiveCategory;\n pattern: RegExp;\n group?: number;\n validation?: 'checksum';\n validate?: (value: string) => boolean;\n}\n\nexport const SENSITIVE_RULES: readonly SensitiveRule[] = [\n {\n id: 'authorization-header',\n category: 'authorization',\n pattern:\n /\\b(?:authorization|proxy-authorization)\\s*:\\s*(?:bearer|basic|token)\\s+[^\\s,;]+/dgi,\n },\n {\n id: 'cookie-header',\n category: 'cookie',\n pattern: /\\b(?:set-cookie|cookie)\\s*:\\s*[^\\r\\n]+/dgi,\n },\n {\n id: NAMED_SECRET_RULE_ID,\n category: 'secret',\n pattern: NAMED_SECRET_ASSIGNMENT,\n },\n {\n id: 'absolute-local-path',\n category: 'absolute_path',\n pattern:\n /(?:\\b[A-Z]:\\\\|\\/(?:Users|home|private|var\\/folders|tmp|etc)\\/)[^\\s'\"`]+/dg,\n },\n {\n id: 'email-address',\n category: 'email',\n // Bounded local/domain parts avoid repeated unbounded suffix searches.\n pattern:\n /(?<![A-Za-z0-9._%+-])[A-Za-z0-9._%+-]{1,64}@[A-Za-z0-9.-]{1,253}\\.[A-Za-z]{2,63}(?![A-Za-z0-9_%+-])/dg,\n },\n {\n id: 'vendor-api-key',\n category: 'vendor_key',\n pattern:\n /(?<![A-Za-z0-9_-])(?:gh[pousr]_[A-Za-z0-9]{20,255}|github_pat_[A-Za-z0-9_]{20,255}|sk-(?:proj-|ant-)?[A-Za-z0-9_-]{16,255}|(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,255}|AIza[A-Za-z0-9_-]{30,64}|xox[baprs]-[A-Za-z0-9-]{10,255})(?![A-Za-z0-9_-])/dg,\n },\n {\n id: 'cloud-access-key',\n category: 'cloud_key',\n pattern:\n /(?<![A-Za-z0-9])(?:AKIA[A-Z0-9]{16}|ASIA[A-Z0-9]{16}|LTAI[A-Za-z0-9]{12,32}|AKID[A-Za-z0-9]{13,40})(?![A-Za-z0-9])/dg,\n },\n {\n id: 'connection-password',\n category: 'connection_password',\n group: 1,\n pattern:\n /\\b[a-z][a-z0-9+.-]{0,31}:\\/\\/[^\\s:@/]{1,255}:([^\\s@/]{1,4096})@/dgi,\n },\n {\n id: 'bearer-token',\n category: 'authorization',\n group: 1,\n pattern: /\\bbearer\\s+([A-Za-z0-9._~+/-]+=*)/dgi,\n },\n {\n id: 'jwt-token',\n category: 'jwt',\n validate: isJwt,\n pattern:\n /(?<![A-Za-z0-9_-])eyJ[A-Za-z0-9_-]{1,1024}\\.[A-Za-z0-9_-]{2,8192}\\.[A-Za-z0-9_-]{1,2048}(?![A-Za-z0-9_-])/dg,\n },\n {\n id: 'cn-mobile-phone',\n category: 'phone',\n pattern:\n /(?<![A-Za-z0-9_])(?:(?:\\+?86|0086|[((]\\+?86[))])[ -]?)?1[3-9][0-9](?:([ -])[0-9]{4}\\1[0-9]{4}|[0-9]{8})(?![A-Za-z0-9_])/dg,\n },\n {\n id: 'cn-identity-card-18',\n category: 'identity_card',\n pattern: /(?<![A-Za-z0-9_])[0-9]{17}[0-9Xx](?![A-Za-z0-9_])/dg,\n validation: 'checksum',\n validate: isIdentityCard,\n },\n {\n id: 'cn-identity-card-15',\n category: 'identity_card',\n pattern: /(?<![A-Za-z0-9_])[0-9]{15}(?![A-Za-z0-9_])/dg,\n validate: isIdentityCard,\n },\n {\n id: 'payment-card',\n category: 'payment_card',\n pattern:\n /(?<![A-Za-z0-9_])(?:[2-6][0-9]{12,18}|[2-6][0-9]{3}([ -])[0-9]{4}\\1[0-9]{4}\\1[0-9]{1,4}(?:\\1[0-9]{3})?|[3-6][0-9]{3}([ -])[0-9]{6}\\2[0-9]{5})(?![A-Za-z0-9_])/dg,\n validation: 'checksum',\n validate: isPaymentCard,\n },\n];\n\nexport const DEFAULT_RULE_IDS: readonly string[] = [\n PRIVATE_KEY_RULE_ID,\n ...SENSITIVE_RULES.map((rule) => rule.id),\n];\n","import { performance } from 'node:perf_hooks';\nimport { NAMED_SECRET_RULE_ID, namedSecretValue } from './named-secret.js';\nimport {\n DEFAULT_RULE_IDS,\n PRIVATE_KEY_RULE_ID,\n RULESET_VERSION,\n SENSITIVE_RULES,\n} from './rules.js';\nimport type { ScanResult, SensitiveFinding } from './types.js';\n\nexport const MAX_SCAN_BYTES = 1024 * 1024;\nexport const MAX_SCAN_FINDINGS = 4096;\nconst SCAN_BUDGET_MS = 500;\nconst REDACTED_CATEGORIES = new Set<string>([\n 'private_key',\n ...SENSITIVE_RULES.map((rule) => rule.category),\n]);\n\n/** No input text or secret-derived identifiers are retained in the result. */\nexport function scanSensitiveText(\n value: string,\n ruleIds: readonly string[] = DEFAULT_RULE_IDS,\n): ScanResult {\n const failed = (reason: ScanResult['reason']): ScanResult => ({\n status: 'failed',\n rulesetVersion: RULESET_VERSION,\n findings: [],\n reason,\n });\n if (\n typeof value !== 'string' ||\n /\\0|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/.test(\n value,\n )\n )\n return failed('invalid_text');\n if (Buffer.byteLength(value, 'utf8') > MAX_SCAN_BYTES)\n return failed('input_too_large');\n if (ruleIds.some((id) => !DEFAULT_RULE_IDS.includes(id)))\n return failed('unknown_rule');\n const enabled = new Set(ruleIds);\n const started = performance.now();\n const findings: SensitiveFinding[] = [];\n if (enabled.has(PRIVATE_KEY_RULE_ID)) {\n // A missing END consumes the remaining text, instead of re-scanning every BEGIN.\n const begin = /-----BEGIN(?: [A-Z0-9]+)? PRIVATE KEY-----/gi;\n for (\n let match = begin.exec(value);\n match !== null;\n match = begin.exec(value)\n ) {\n const closing = new RegExp(\n match[0].replace(/^-----BEGIN/i, '-----END'),\n 'gi',\n );\n closing.lastIndex = begin.lastIndex;\n const close = closing.exec(value);\n const end = close === null ? value.length : close.index + close[0].length;\n findings.push({\n ruleId: PRIVATE_KEY_RULE_ID,\n category: 'private_key',\n start: match.index,\n end,\n validation: 'shape',\n });\n begin.lastIndex = end;\n if (findings.length > MAX_SCAN_FINDINGS)\n return failed('too_many_findings');\n if (performance.now() - started > SCAN_BUDGET_MS)\n return failed('scan_budget_exceeded');\n }\n }\n for (const rule of SENSITIVE_RULES) {\n if (!enabled.has(rule.id)) continue;\n const pattern = new RegExp(rule.pattern);\n for (\n let match = pattern.exec(value);\n match !== null;\n match = pattern.exec(value)\n ) {\n if (performance.now() - started > SCAN_BUDGET_MS)\n return failed('scan_budget_exceeded');\n const group = rule.group ?? 0;\n const assignment =\n rule.id === NAMED_SECRET_RULE_ID\n ? namedSecretValue(value, match)\n : undefined;\n if (assignment === null) continue;\n if (assignment !== undefined) pattern.lastIndex = assignment.resume;\n const bounds: [number, number] | undefined =\n assignment === undefined\n ? match.indices?.[group]\n : [assignment.start, assignment.end];\n const candidate =\n assignment === undefined\n ? match[group]\n : value.slice(assignment.start, assignment.end);\n if (bounds === undefined || candidate === undefined) continue;\n const markerCategories = /^\\[REDACTED:([a-z_,]+)\\]$/\n .exec(candidate)?.[1]\n ?.split(',');\n if (\n candidate === '[REDACTED]' ||\n markerCategories?.every((category) => REDACTED_CATEGORIES.has(category))\n )\n continue;\n if (rule.validate !== undefined && !rule.validate(candidate)) continue;\n findings.push({\n ruleId: rule.id,\n category: rule.category,\n start: bounds[0],\n end: bounds[1],\n validation: rule.validation ?? 'shape',\n });\n if (findings.length > MAX_SCAN_FINDINGS)\n return failed('too_many_findings');\n if (performance.now() - started > SCAN_BUDGET_MS)\n return failed('scan_budget_exceeded');\n }\n if (performance.now() - started > SCAN_BUDGET_MS)\n return failed('scan_budget_exceeded');\n }\n findings.sort(\n (left, right) =>\n left.start - right.start ||\n right.end - left.end ||\n left.ruleId.localeCompare(right.ruleId, 'en'),\n );\n // A URI password followed by @host resembles an email address. Keep the\n // password capture so redaction does not consume non-secret routing fields.\n const passwords = findings.filter(\n (finding) => finding.category === 'connection_password',\n );\n const filtered = findings.filter((finding) => {\n if (finding.category !== 'email') return true;\n let low = 0;\n let high = passwords.length;\n while (low < high) {\n const middle = (low + high) >>> 1;\n if (\n (passwords[middle]?.start ?? Number.POSITIVE_INFINITY) <= finding.start\n )\n low = middle + 1;\n else high = middle;\n }\n const password = passwords[low - 1];\n return password === undefined || finding.start >= password.end;\n });\n if (performance.now() - started > SCAN_BUDGET_MS)\n return failed('scan_budget_exceeded');\n return {\n status: 'complete',\n rulesetVersion: RULESET_VERSION,\n findings: filtered,\n };\n}\n"],"mappings":"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","names":["end"]}
|