@wrongstack/core 0.267.0 → 0.269.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/dist/{agent-bridge-STJ3JwwK.d.ts → agent-bridge-PcHQl_UQ.d.ts} +1 -1
- package/dist/{agent-subagent-runner-CzPGP3jA.d.ts → agent-subagent-runner-SHJW7t8q.d.ts} +8 -8
- package/dist/{brain-Cdg77tVN.d.ts → brain-BYcK__Ym.d.ts} +1 -1
- package/dist/{compactor-iMZ84CXq.d.ts → compactor-C2RKEBtC.d.ts} +1 -1
- package/dist/{config-Du3pYYln.d.ts → config-C_ae2k86.d.ts} +79 -2
- package/dist/{context-dT5Ueund.d.ts → context-Dp87Bcaq.d.ts} +47 -1
- package/dist/coordination/index.d.ts +62 -160
- package/dist/coordination/index.js +566 -149
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +26 -25
- package/dist/defaults/index.js +366 -137
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +72 -16
- package/dist/execution/index.js +267 -55
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/extension/index.d.ts +7 -6
- package/dist/global-mailbox-Bvrz1P3f.d.ts +664 -0
- package/dist/{goal-preamble-SulMTowG.d.ts → goal-preamble-CA_4yiGQ.d.ts} +9 -9
- package/dist/{goal-store-CABDwdFE.d.ts → goal-store-DhuJoUNG.d.ts} +1 -1
- package/dist/hq/index.d.ts +204 -0
- package/dist/hq/index.js +1931 -0
- package/dist/hq/index.js.map +1 -0
- package/dist/{index-DtCVWel4.d.ts → index-CZQ6Pwbs.d.ts} +8 -8
- package/dist/{index-Bms0m4oy.d.ts → index-W4VJCzHa.d.ts} +5 -5
- package/dist/{index-IEuxQd-E.d.ts → index-whDfTANu.d.ts} +2 -2
- package/dist/index.d.ts +46 -42
- package/dist/index.js +3472 -1651
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/infrastructure/index.js +48 -21
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +10 -9
- package/dist/{pipeline-BfD2k1rT.d.ts → mailbox-types-Ct2hJq0P.d.ts} +1 -244
- package/dist/{mcp-servers-C2cBTxUR.d.ts → mcp-servers-DJdZiRcv.d.ts} +10 -4
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +4 -3
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-BqGZNJQ-.d.ts → models-registry-C3a-2-Yd.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-B8R43uPz.d.ts → multi-agent-coordinator-CJSpTe5O.d.ts} +1 -1
- package/dist/{null-fleet-bus-CnXa5oTH.d.ts → null-fleet-bus-QVshIsDx.d.ts} +6 -6
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-DdNnw9BQ.d.ts → parallel-eternal-engine-D9y5Pkcc.d.ts} +9 -15
- package/dist/{path-resolver-COIMLCQL.d.ts → path-resolver-CnQ8SIfh.d.ts} +4 -3
- package/dist/{permission-B75JAi3-.d.ts → permission-CvYQNUqZ.d.ts} +1 -1
- package/dist/{permission-policy-DlR9eJAM.d.ts → permission-policy-D5Ss8j4B.d.ts} +2 -3
- package/dist/pipeline-l_zzFRh3.d.ts +245 -0
- package/dist/{plan-templates-DSIKCXZN.d.ts → plan-templates-NtPgyeJA.d.ts} +6 -5
- package/dist/{provider-model-resolve-BNRsNuJx.d.ts → provider-model-resolve-d5poT5y0.d.ts} +3 -3
- package/dist/{provider-runner-CX7iIvox.d.ts → provider-runner-gkctlQV_.d.ts} +3 -3
- package/dist/{retry-policy-BilV1ujH.d.ts → retry-policy-CtFhfwa8.d.ts} +1 -1
- package/dist/sdd/index.d.ts +9 -8
- package/dist/sdd/index.js +33 -3
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-gkvEZZfE.d.ts → secret-vault-BLsVmTIK.d.ts} +1 -1
- package/dist/security/index.d.ts +5 -5
- package/dist/security/index.js +39 -29
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-Bc7eWtT3.d.ts → selector-CXl2_y9W.d.ts} +1 -1
- package/dist/{session-event-bridge-D-araDEz.d.ts → session-event-bridge-Ccud20CC.d.ts} +1 -1
- package/dist/{session-reader-D7Dapswh.d.ts → session-reader-ZeXQmsmE.d.ts} +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/storage/index.d.ts +16 -12
- package/dist/storage/index.js +273 -100
- package/dist/storage/index.js.map +1 -1
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js +166 -31
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +22 -21
- package/dist/types/index.js +178 -70
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +22 -3
- package/dist/utils/index.js +197 -25
- package/dist/utils/index.js.map +1 -1
- package/package.json +5 -1
- package/skills/chimera/SKILL.md +1 -1
- package/skills/typescript-strict/SKILL.md +3 -3
- package/skills/typescript-strict/SKILL.save.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/security/secret-scrubber.ts","../../src/utils/atomic-write.ts","../../src/utils/deep-merge.ts","../../src/utils/error.ts","../../src/utils/expect-defined.ts","../../src/utils/glob-match.ts","../../src/utils/safe-json.ts","../../src/types/errors.ts","../../src/types/secret-vault.ts","../../src/security/secret-vault.ts","../../src/security/capabilities.ts","../../src/security/yolo-risk.ts","../../src/security/permission-policy.ts"],"names":["path","stat","resolve","randomBytes","path2","key","fsp","oldVersion","newVersion","relative","fs3","decision"],"mappings":"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","file":"index.js","sourcesContent":["import type { SecretScrubber } from '../types/secret-scrubber.js';\n\ninterface Pattern {\n type: string;\n regex: RegExp;\n}\n\nconst PATTERNS: Pattern[] = [\n // Anchored at the start where possible so partial matches inside larger\n // strings don't trigger false positives.\n {\n type: 'anthropic_key',\n regex: /(?<![A-Za-z0-9])sk-ant-api\\d+-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g,\n },\n { type: 'openai_key', regex: /(?<![A-Za-z0-9])sk-(?:proj-)?[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g },\n { type: 'github_pat', regex: /(?<![A-Za-z0-9])ghp_[A-Za-z0-9]{36,}(?![A-Za-z0-9])/g },\n { type: 'github_pat_v2', regex: /(?<![A-Za-z0-9])github_pat_[A-Za-z0-9_]{50,}(?![A-Za-z0-9])/g },\n { type: 'aws_access_key', regex: /(?<![A-Za-z0-9])AKIA[0-9A-Z]{16}(?![A-Za-z0-9])/g },\n { type: 'gcp_key', regex: /(?<![A-Za-z0-9])AIza[0-9A-Za-z_-]{35}(?![A-Za-z0-9])/g },\n { type: 'slack_token', regex: /(?<![A-Za-z0-9-])xox[abpos]-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g },\n {\n type: 'stripe_key',\n regex: /(?<![A-Za-z0-9])sk_(?:live|test)_[A-Za-z0-9]{24,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'twilio_sid', regex: /(?<![A-Za-z0-9])AC[a-f0-9]{32}(?![A-Za-z0-9])/g,\n },\n {\n type: 'telegram_bot_token',\n // Telegram tokens are of the form bot<digits>:<alphanum> in URL paths\n regex: /\\/bot\\d+:[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,\n },\n {\n type: 'jwt',\n // Anchored: look for literal \"eyJ\" which is unambiguous for JWT header\n regex:\n /(?<![A-Za-z0-9/+=])eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}(?![A-Za-z0-9/+=])/g,\n },\n {\n type: 'private_key',\n // Anchored: start must be BEGIN, end must be END with no extra dashes after END\n regex:\n /(?:^|\\n)-----BEGIN (?:RSA|EC|OPENSSH|DSA|PGP)? ?PRIVATE KEY-----[\\s\\S]*?-----END[^-]*-----(?:\\n|$)/g,\n },\n { type: 'mongodb_uri', regex: /mongodb(?:\\+srv)?:\\/\\/[^\\s\"'`]+/g },\n { type: 'postgres_uri', regex: /postgres(?:ql)?:\\/\\/[^\\s\"'`]+/g },\n { type: 'mysql_uri', regex: /mysql:\\/\\/[^\\s\"'`]+/g },\n { type: 'redis_uri', regex: /redis:\\/\\/[^\\s\"'`]+/g },\n // AI/ML provider keys — modern LLM services with well-known prefixes\n {\n type: 'huggingface_token',\n // HuggingFace tokens: hf_ followed by 34 alphanumeric chars\n regex: /(?<![A-Za-z0-9])hf_[A-Za-z0-9]{34}(?![A-Za-z0-9])/g,\n },\n {\n type: 'replicate_token',\n // Replicate tokens: r8_ followed by 40+ alphanumeric chars\n regex: /(?<![A-Za-z0-9])r8_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'perplexity_key',\n // Perplexity API keys: pplx- followed by 40+ alphanumeric chars\n regex: /(?<![A-Za-z0-9])pplx-[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'groq_key',\n // Groq API keys: gsk_ followed by 40+ alphanumeric chars\n regex: /(?<![A-Za-z0-9])gsk_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'bearer_token',\n // Anchored with alternation instead of negative lookahead — avoids V8\n // backtracking risk on adversarial input. Bounded at 512 chars.\n // Min 12 chars: some OAuth providers issue shorter-lived tokens (< 20\n // chars). A 12-char base64 string has ~71 bits of entropy — above the\n // threshold where random strings are unlikely to produce false matches.\n regex: /(?:^|[^A-Za-z0-9_.~+/-])Bearer\\s+[A-Za-z0-9._~+/-]{12,512}=*(?:$|[^A-Za-z0-9_.~+/-])/g,\n },\n {\n type: 'high_entropy_env',\n // Anchored with alternation instead of lookbehind to avoid backtracking.\n // Value bounded at 512 chars.\n regex: /(?:^|\\s)([A-Z_]{4,}(?:KEY|TOKEN|SECRET|PASSWORD|PWD))\\s*[:=]\\s*['\"]?([A-Za-z0-9_/+=-]{20,512})['\"]?(?:\\s|$)/g,\n },\n];\n\n/**\n * `high_entropy_env` is the one pattern that needs special replacement logic\n * (it preserves the key name), so it runs in its own pass. Every other pattern\n * is folded into a single combined regex. Derive the split by type rather than\n * by hard-coded indices so adding/removing a pattern can't silently drop one.\n */\nconst SIMPLE_PATTERNS = PATTERNS.filter((p) => p.type !== 'high_entropy_env');\n\n/**\n * Combined single-pass regex for all simple patterns. Each alternative is a\n * capturing group so the callback can determine which original pattern fired\n * (only one group is non-undefined at match time). Order matches SIMPLE_PATTERNS\n * (longer/more-specific prefixes first). Relies on each simple pattern source\n * containing no internal capturing groups — only `(?:...)` and lookarounds.\n */\nconst COMBINED_REGEX = new RegExp(SIMPLE_PATTERNS.map((p) => `(${p.regex.source})`).join('|'), 'g');\n\n/** Separate pattern for high_entropy_env (different replacement logic). */\nconst HIGH_ENTROPY_REGEX = PATTERNS.find((p) => p.type === 'high_entropy_env')!.regex;\n\n/**\n * Replacements for the combined patterns, parallel to SIMPLE_PATTERNS. The\n * combined-regex callback indexes into this with the matched group's position.\n */\nconst COMBINED_REPLACEMENTS = SIMPLE_PATTERNS.map((p) => `[REDACTED:${p.type}]`);\n\n/**\n * Per-chunk cap. Splits long inputs into 64 KB chunks to keep scrub() memory\n * bounded. Real scrub() inputs (LLM responses, tool outputs) are typically\n * much smaller; this cap handles edge cases without impacting normal usage.\n */\nconst SCRUB_CHUNK_BYTES = 64 * 1024;\n\n/**\n * Quick pre-scan: check if the text contains any substring that MUST be\n * present for a credential pattern to match. If none are found, the text\n * is guaranteed clean — skip all regex passes (2 total: 16-pattern combined + high_entropy_env).\n *\n * Each anchor is the shortest unique substring from the corresponding pattern.\n * V8's `String.includes()` is hand-tuned C++ — O(n) with near-zero overhead\n * for typical tool-output lengths (100–5000 chars). A single combined regex\n * via `text.search()` is consistently slower for this many alternatives.\n */\nfunction hasCredentialAnchors(text: string): boolean {\n return (\n text.includes('-----BEGIN') || // Private keys (most unique → cheap reject)\n text.includes('sk-') || // Anthropic + OpenAI keys\n text.includes('sk_') || // Stripe live/test keys\n text.includes('ghp_') || // GitHub PAT v1\n text.includes('github_pat_') || // GitHub PAT v2\n text.includes('eyJ') || // JWT\n text.includes('AKIA') || // AWS access key\n text.includes('AIza') || // GCP service key\n text.includes('xox') || // Slack token (xoxa/xoxb/xoxp/xoxo/xoxs)\n text.includes('Bearer ') || // Bearer token (space suffix reduces false positives)\n text.includes('/bot') || // Telegram bot token (URL path pattern)\n text.includes('hf_') || // HuggingFace token\n text.includes('r8_') || // Replicate token\n text.includes('pplx-') || // Perplexity API key\n text.includes('gsk_') || // Groq API key\n text.includes('_KEY=') || // High-entropy env vars: API_KEY=, SECRET_KEY=, ...\n text.includes('_TOKEN=') || // ACCESS_TOKEN=, AUTH_TOKEN=, ...\n text.includes('_SECRET=') || // API_SECRET=, CLIENT_SECRET=, ...\n text.includes('_PASSWORD=') || // DB_PASSWORD=, ROOT_PASSWORD=, ...\n text.includes('mongodb://') ||\n text.includes('mongodb+srv://') ||\n text.includes('postgres://') ||\n text.includes('postgresql://') ||\n text.includes('mysql://') ||\n text.includes('redis://')\n );\n}\n\nexport class DefaultSecretScrubber implements SecretScrubber {\n scrub(text: string): string {\n if (!text) return text;\n\n // Fast path: if no credential anchor substrings exist in the text,\n // none of the 17 regex patterns can match. Skip all regex work.\n // This covers the vast majority of tool outputs (~95% of calls on\n // typical sessions are file paths, status messages, diffs, etc.).\n if (!hasCredentialAnchors(text)) return text;\n\n // For oversize inputs, scrub in fixed chunks. We split on newlines\n // where possible so secrets that span a few hundred bytes still get\n // matched within a single chunk; only inputs above ~64 KB risk a\n // boundary cutting a secret in half, and those are uncommon.\n if (text.length <= SCRUB_CHUNK_BYTES) {\n return this.scrubOne(text);\n }\n const out: string[] = [];\n let i = 0;\n while (i < text.length) {\n let end = Math.min(i + SCRUB_CHUNK_BYTES, text.length);\n // Try to break on a newline near the boundary so we don't cut secrets.\n if (end < text.length) {\n const nl = text.lastIndexOf('\\n', end);\n if (nl > i + SCRUB_CHUNK_BYTES / 2) end = nl + 1;\n }\n out.push(this.scrubOne(text.slice(i, end)));\n i = end;\n }\n return out.join('');\n }\n\n private scrubOne(text: string): string {\n // Redundant guard: if we reached scrubOne via the chunked path, the\n // chunk may have been small enough to anchor-skip independently.\n if (!hasCredentialAnchors(text)) return text;\n\n // Pass 1: combined single-pass regex for all simple patterns. Each\n // alternative is a capturing group; only the group that matched is\n // non-undefined. The trailing offset/string args replace() appends are\n // always defined, so the matched group (which precedes them) is found first.\n let out = text.replace(\n COMBINED_REGEX,\n (match, ...groups) => {\n // groups[i] corresponds to SIMPLE_PATTERNS[i]; find which one fired.\n const idx = groups.findIndex((g) => g !== undefined);\n if (idx < 0) return match;\n const replacement = COMBINED_REPLACEMENTS[idx];\n return replacement !== undefined ? replacement : match;\n },\n );\n\n // Pass 2: high_entropy_env needs special handling — preserve the key name.\n out = out.replace(HIGH_ENTROPY_REGEX, (_match, group1, _group2) => {\n return `${group1}=[REDACTED:high_entropy_env]`;\n });\n\n return out;\n }\n\n /**\n * Recursively scrub every string value in an object/array graph. Secrets can\n * appear under any key — a URL query param, an `authorization` header, an\n * arbitrarily-named nested field — so we don't gate recursion on key names.\n * The per-string `scrub()` fast-path (anchor pre-scan) keeps this cheap: any\n * value without a credential anchor returns immediately without regex work.\n */\n scrubObject<T>(obj: T): T {\n const seen = new WeakSet();\n const visit = (v: unknown): unknown => {\n if (typeof v === 'string') return this.scrub(v);\n if (v === null || typeof v !== 'object') return v;\n if (seen.has(v as object)) return v;\n seen.add(v as object);\n if (Array.isArray(v)) return v.map(visit);\n const out: Record<string, unknown> = {};\n for (const [k, val] of Object.entries(v as Record<string, unknown>)) {\n out[k] = visit(val);\n }\n return out;\n };\n return visit(obj) as T;\n }\n}\n","import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists — extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n // ENOENT means the directory was deleted (e.g. by concurrent cleanup).\n // Recreate it and retry acquiring the lock.\n if (code === 'ENOENT') {\n await fs.mkdir(dir, { recursive: true });\n continue;\n }\n if (code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new Error(`Timed out waiting for file lock: ${targetPath}`);\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient — retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n","/**\n * Deep merge utility — safely merges nested objects with configurable\n * conflict resolution, array merging, and prototype-pollution guarding.\n *\n * Used by:\n * - config-loader (config layer merging with primitive-array concatenation)\n * - secret-vault (config patching)\n * - json-path (json_merge tool with prefer-base / prefer-patch semantics)\n *\n * @module utils/deep-merge\n */\n\n// ---------------------------------------------------------------------------\n// Prototype-pollution guard — shared set of forbidden __proto__ keys\n// ---------------------------------------------------------------------------\n\nexport const FORBIDDEN_PROTO_KEYS = new Set([\n '__proto__',\n 'constructor',\n 'prototype',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__',\n]);\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** True when every element is a primitive or null (no nested objects/arrays). */\nexport function isPrimitiveArray(a: unknown[]): boolean {\n return a.every((v) => v === null || (typeof v !== 'object' && typeof v !== 'function'));\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface DeepMergeOptions {\n /**\n * Which side wins on collision for scalars and arrays.\n *\n * - `'prefer-patch'` (default): patch value replaces base value.\n * - `'prefer-base'`: base value is kept, patch value is ignored.\n */\n conflictResolution?: 'prefer-base' | 'prefer-patch';\n\n /**\n * How to handle array values.\n *\n * - `'replace'` (default): patch array replaces base array entirely.\n * - `'concat-primitives'`: when both values are primitive arrays,\n * they are concatenated and deduped (via Set). Non-primitive\n * arrays still replace the base wholesale.\n */\n arrayMode?: 'replace' | 'concat-primitives';\n\n /**\n * Skip prototype-pollution keys (`__proto__`, `constructor`, etc.).\n * Enabled by default. Only disable when you control both inputs\n * and the keyset (e.g. when merging trusted JSON schemas).\n */\n protectProto?: boolean;\n\n /**\n * Optional callback fired when a non-primitive (object) array is\n * replaced wholesale (only relevant with `arrayMode: 'concat-primitives'`).\n * Receives the key name, existing array length, and patch array length.\n * Used by config-loader for debug logging.\n */\n onNonPrimitiveArrayReplace?: (\n key: string,\n existingLen: number,\n patchLen: number,\n ) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively merge `patch` into `base`, returning a new object.\n *\n * - Nested plain objects are merged recursively.\n * - Arrays are handled per `options.arrayMode`.\n * - Scalar collisions are resolved per `options.conflictResolution`.\n * - `null` and non-object values in `patch` replace the base value\n * (unless `conflictResolution` is `'prefer-base'`).\n * - Keys in `base` that are absent from `patch` are preserved.\n * - `FORBIDDEN_PROTO_KEYS` are skipped in the patch (unless\n * `options.protectProto` is set to `false`).\n *\n * The function is generic over `T extends Record<string, unknown>` for\n * callers that pass typed config objects, but the runtime signature\n * also accepts `unknown` inputs (used by the json-path plugin).\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n base: T,\n patch: Record<string, unknown>,\n options?: DeepMergeOptions,\n): T;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options?: DeepMergeOptions,\n): unknown;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options: DeepMergeOptions = {},\n): unknown {\n const {\n conflictResolution = 'prefer-patch',\n arrayMode = 'replace',\n protectProto = true,\n onNonPrimitiveArrayReplace,\n } = options;\n\n // Non-object / null handling — delegate to conflict resolution.\n if (typeof base !== 'object' || base === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n if (typeof patch !== 'object' || patch === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Arrays — handled *before* the object merge so array-of-objects\n // aren't accidentally treated as plain records.\n if (Array.isArray(base) && Array.isArray(patch)) {\n if (\n arrayMode === 'concat-primitives' &&\n isPrimitiveArray(base) &&\n isPrimitiveArray(patch)\n ) {\n return [...new Set([...base, ...patch])];\n }\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // If only one side is an array, treat as scalar collision.\n if (Array.isArray(base) || Array.isArray(patch)) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Plain object merge.\n const baseObj = base as Record<string, unknown>;\n const patchObj = patch as Record<string, unknown>;\n const out: Record<string, unknown> = { ...baseObj };\n\n for (const [k, v] of Object.entries(patchObj)) {\n if (protectProto && FORBIDDEN_PROTO_KEYS.has(k)) continue;\n\n const existing = out[k];\n if (\n v !== null &&\n typeof v === 'object' &&\n !Array.isArray(v) &&\n existing !== null &&\n typeof existing === 'object' &&\n !Array.isArray(existing)\n ) {\n // Recursive merge for nested plain objects.\n out[k] = deepMerge(existing, v, options);\n } else if (Array.isArray(v) && Array.isArray(existing)) {\n // Delegate to top-level array handling so arrayMode\n // (e.g. 'concat-primitives') applies to nested arrays too.\n // Fire debug hook when a non-primitive array replaces an existing\n // array (for non-primitive arrays, concat-primitives is a no-op and\n // the result is always a wholesale replacement).\n if (onNonPrimitiveArrayReplace && !isPrimitiveArray(v)) {\n onNonPrimitiveArrayReplace(k, existing.length, v.length);\n }\n out[k] = deepMerge(existing, v, options);\n } else if (v !== undefined) {\n // Fire debug hook when a non-primitive (object) array replaces an\n // existing value in concat-primitives mode.\n if (\n onNonPrimitiveArrayReplace &&\n Array.isArray(v) &&\n !isPrimitiveArray(v)\n ) {\n const existingLen = Array.isArray(existing) ? existing.length : 0;\n onNonPrimitiveArrayReplace(k, existingLen, v.length);\n }\n out[k] = v;\n }\n // When v === undefined, leave the existing value untouched\n // (this matches config-loader's behaviour: undefined in patch\n // means \"don't change this key\").\n }\n\n return out;\n}\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","import { expectDefined } from './expect-defined.js';\n/**\r\n * Minimal glob matcher for trust patterns.\r\n * Supports: *, **, ?, character classes [abc], [a-z], negation [!...] or [^...].\r\n *\r\n * Compiled regexes are cached so repeated calls with the same pattern\r\n * avoid recompilation overhead.\r\n */\r\n\r\nfunction escapeRegex(s: string): string {\r\n return s.replace(/[.+^${}()|\\\\]/g, '\\\\$&');\r\n}\r\n\r\n// Module-level cache to avoid recompiling the same pattern on every call.\r\n// LRU-ish eviction keeps unbounded growth in check for long-running processes.\r\nconst COMPILED_GLOB_CACHE = new Map<string, RegExp>();\r\nconst CACHE_MAX_SIZE = 2000;\r\n\r\nfunction getCachedGlob(pattern: string): RegExp {\r\n const cached = COMPILED_GLOB_CACHE.get(pattern);\r\n if (cached) return cached;\r\n if (COMPILED_GLOB_CACHE.size >= CACHE_MAX_SIZE) {\r\n // Evict oldest 25% when at capacity\r\n const keys = [...COMPILED_GLOB_CACHE.keys()];\r\n for (let i = 0; i < Math.floor(CACHE_MAX_SIZE / 4); i++) {\r\n COMPILED_GLOB_CACHE.delete(expectDefined(keys[i]));\r\n }\r\n }\r\n const re = compileGlob(pattern);\r\n COMPILED_GLOB_CACHE.set(pattern, re);\r\n return re;\r\n}\r\n\r\n// Cap glob pattern length to prevent excessively long compiled regexes.\r\nconst MAX_GLOB_PATTERN_LEN = 1024;\r\n\r\nexport function compileGlob(pattern: string): RegExp {\r\n if (pattern.length > MAX_GLOB_PATTERN_LEN) {\r\n throw new Error(`Glob pattern exceeds ${MAX_GLOB_PATTERN_LEN} characters`);\r\n }\r\n let i = 0;\r\n let re = '^';\r\n while (i < pattern.length) {\r\n const c = pattern[i];\r\n if (c === '*') {\r\n if (pattern[i + 1] === '*') {\r\n // ** matches any number of chars including /\r\n re += '.*';\r\n i += 2;\r\n // Skip trailing slash so '**/x' matches 'x'\r\n if (pattern[i] === '/') i++;\r\n } else {\r\n // single * matches any chars except /\r\n re += '[^/]*';\r\n i++;\r\n }\r\n } else if (c === '?') {\r\n re += '[^/]';\r\n i++;\r\n } else if (c === '[') {\r\n let cls = '[';\r\n i++;\r\n if (pattern[i] === '!' || pattern[i] === '^') {\r\n cls += '^';\r\n i++;\r\n }\r\n while (i < pattern.length && pattern[i] !== ']') {\r\n const ch = pattern[i] ?? '';\r\n // Inside a regex class, only `]`, `\\`, and `^`/`-` at boundaries need\r\n // escaping. We've already consumed the leading `^`; the rest are\r\n // literal. Escape `\\` defensively and pass the rest through verbatim\r\n // so ranges like `a-z` continue to work.\r\n if (ch === '\\\\') {\r\n cls += '\\\\\\\\';\r\n } else if (ch === ']' || ch === '^') {\r\n cls += `\\\\${ch}`;\r\n } else {\r\n cls += ch;\r\n }\r\n i++;\r\n }\r\n cls += ']';\r\n re += cls;\r\n i++; // skip closing ]\r\n } else {\r\n re += escapeRegex(c ?? '');\r\n i++;\r\n }\r\n }\r\n re += '$';\r\n return new RegExp(re);\r\n}\r\n\r\nexport function matchGlob(pattern: string, input: string): boolean {\r\n return getCachedGlob(pattern).test(input);\r\n}\r\n\r\nexport function matchAny(patterns: string[], input: string): boolean {\r\n return patterns.some((p) => matchGlob(p, input));\r\n}\r\n","import { toErrorMessage } from './error.js';\n\nexport interface SafeParseResult<T> {\n ok: boolean;\n value?: T | undefined;\n error?: string | undefined;\n}\n\nexport function safeParse<T = unknown>(input: string, maxBytes = 5_000_000): SafeParseResult<T> {\n if (input.length > maxBytes) {\n return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };\n }\n try {\n return { ok: true, value: JSON.parse(input) as T };\n } catch (err) {\n return {\n ok: false,\n error: toErrorMessage(err),\n };\n }\n}\n\nexport function safeStringify(value: unknown, pretty = false): string {\n const seen = new WeakSet();\n const replacer = (_k: string, v: unknown): unknown => {\n if (typeof v === 'bigint') return v.toString();\n if (v instanceof Error) {\n return { name: v.name, message: v.message, stack: v.stack };\n }\n if (typeof v === 'object' && v !== null) {\n if (seen.has(v as object)) return '[Circular]';\n seen.add(v as object);\n }\n return v;\n };\n try {\n return JSON.stringify(value, replacer, pretty ? 2 : undefined) ?? 'null';\n } catch (err) {\n return JSON.stringify({\n __serialization_error: toErrorMessage(err),\n });\n }\n}\n\n/**\n * Attempt to parse JSON5-style input and return a valid JSON string.\n * Handles trailing commas, single-line comments, and unquoted keys\n * that are common in provider output.\n *\n * Returns the sanitized string if it parses successfully as JSON,\n * or `null` if the input cannot be made valid. Callers use this to\n * decide whether to proceed with the parsed result or fall back to\n * raw handling.\n */\nexport function sanitizeJsonString(s: string): string | null {\n let out = s.trim();\n\n // Stage 1: strip single-line comments (// to end of line) that appear\n // outside of string values. This is a heuristic: comments inside strings\n // are preserved because we only strip // when preceded by a char that\n // strongly suggests we're not in a string (quote count modulo 2 is even).\n out = stripSingleLineComments(out);\n\n // Stage 2: strip trailing commas before } or ]\n out = out.replace(/,(\\s*[}\\]])/g, '$1');\n\n // Stage 3: escape literal control characters that appear *inside* string\n // values. Models frequently emit raw newlines/tabs inside a code payload\n // (e.g. edit's old_string/new_string) instead of the required \\n / \\t, which\n // makes JSON.parse throw. This is the single most common malformed-args case.\n out = escapeControlCharsInStrings(out);\n\n // Stage 4: attempt full parse; return null if it fails so callers can\n // distinguish \"already valid JSON\" from \"unrecoverable\".\n try {\n JSON.parse(out);\n return out;\n } catch {\n return null; // stripped but still not valid JSON; caller handles it\n }\n}\n\n/**\n * Walk the string tracking whether we are inside a JSON string literal and\n * replace raw control characters (U+0000–U+001F) that appear inside strings\n * with their valid JSON escape sequences. Characters outside strings are left\n * untouched (insignificant whitespace stays as-is). Already-escaped sequences\n * are not double-escaped because we only act on *literal* control bytes.\n */\nfunction escapeControlCharsInStrings(s: string): string {\n let inString = false;\n let out = '';\n for (let i = 0; i < s.length; i++) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s[i - 1] !== '\\\\')) {\n inString = !inString;\n out += c;\n continue;\n }\n const code = c.charCodeAt(0);\n if (inString && code < 0x20) {\n switch (c) {\n case '\\n':\n out += '\\\\n';\n break;\n case '\\r':\n out += '\\\\r';\n break;\n case '\\t':\n out += '\\\\t';\n break;\n case '\\b':\n out += '\\\\b';\n break;\n case '\\f':\n out += '\\\\f';\n break;\n default:\n out += `\\\\u${code.toString(16).padStart(4, '0')}`;\n }\n continue;\n }\n out += c;\n }\n return out;\n}\n\nfunction stripSingleLineComments(s: string): string {\n let inString = false;\n const chars: string[] = [];\n let i = 0;\n while (i < s.length) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s.charAt(i - 1) !== '\\\\')) {\n inString = !inString;\n chars.push(c);\n } else if (c === '/' && s.charAt(i + 1) === '/' && !inString) {\n // skip to end of line\n while (i < s.length && s.charAt(i) !== '\\n') i++;\n } else {\n chars.push(c);\n }\n i++;\n }\n return chars.join('');\n}\n","import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","/**\n * SecretVault encrypts secrets-at-rest in config files. The wire format is\n * `enc:v<N>:<base64-iv>:<base64-tag>:<base64-ciphertext>` where `<N>` is the\n * key version used for encryption. Plaintext strings (those that do not match\n * this prefix) are passed through unchanged so that existing configs and\n * env-var-derived values keep working.\n *\n * Key rotation produces a new key and re-encrypts all secrets under it.\n * After rotation, `encrypt()` emits the new version prefix (e.g. `enc:v2:`)\n * and `decrypt()` accepts any version prefix — it uses the current key\n * regardless, since rotation re-encrypts every value atomically.\n *\n * The vault is intentionally NOT designed to defeat a determined local\n * attacker who can read both the config file and the key file — that level\n * of secrecy needs the OS keychain. The goal is to keep keys from being\n * visible in screen shares, accidental log captures, and `cat config.json`\n * over someone's shoulder.\n */\nexport interface SecretVault {\n encrypt(plaintext: string): string;\n decrypt(value: string): string;\n isEncrypted(value: string): boolean;\n /** Current key version. Starts at 1; incremented by `rotateKey()`. */\n readonly keyVersion: number;\n}\n\n/**\n * RotatableSecretVault extends SecretVault with key rotation support.\n * `rotateKey()` generates a fresh key, writes it to disk, and increments\n * the key version. All subsequent `encrypt()` calls use the new version\n * prefix. The caller is responsible for re-encrypting existing config\n * values (see `rotateConfigKeys()`).\n */\nexport interface RotatableSecretVault extends SecretVault {\n rotateKey(): { oldVersion: number; newVersion: number };\n}\n\n/** Legacy v1 prefix — values encrypted before key rotation was introduced. */\nexport const ENCRYPTED_PREFIX = 'enc:v1:';\n\n/**\n * Match any versioned encrypted value prefix: `enc:v1:`, `enc:v2:`, etc.\n * Used by `isEncrypted()` and `decrypt()` to handle all versions uniformly.\n */\nexport const ENCRYPTED_PREFIX_PATTERN = /^enc:v(\\d+):/;\n\n/**\n * Return the encrypted prefix for a given key version.\n * @example encryptedPrefixForVersion(1) // 'enc:v1:'\n * @example encryptedPrefixForVersion(2) // 'enc:v2:'\n */\nexport function encryptedPrefixForVersion(version: number): string {\n return `enc:v${version}:`;\n}\n\n/**\n * Parse the key version from an encrypted value string.\n * Returns undefined if the string is not an encrypted value.\n */\nexport function parseEncryptedVersion(value: string): number | undefined {\n const match = value.match(ENCRYPTED_PREFIX_PATTERN);\n return match ? Number.parseInt(match[1]!, 10) : undefined;\n}\n\n/**\n * No-op SecretVault that passes values through unchanged.\n * Used in contexts where encryption is not needed — e.g. reading/writing\n * config sections that contain no secret fields (models, settings, etc.).\n */\nexport const noOpVault: SecretVault = {\n encrypt: (v) => v,\n decrypt: (v) => v,\n isEncrypted: () => false,\n keyVersion: 1,\n};\n","import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Logger } from '../types/logger.js';\nimport type { RotatableSecretVault, SecretVault } from '../types/secret-vault.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\nimport {\n ENCRYPTED_PREFIX_PATTERN,\n encryptedPrefixForVersion,\n} from '../types/secret-vault.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\nexport interface SecretVaultOptions {\n /** Absolute path to the key file. Created with mode 0o600 if missing. */\n keyFile: string;\n}\n\nconst KEY_BYTES = 32;\nconst IV_BYTES = 12;\nconst TAG_BYTES = 16;\nconst ALGO = 'aes-256-gcm';\n// Desired file mode for the key file on POSIX systems.\nconst KEY_FILE_MODE = 0o600;\n\n/**\n * Key file format v2+: 4-byte magic + 1-byte version + 32-byte key = 37 bytes.\n * The magic header distinguishes versioned key files from legacy 32-byte raw keys.\n */\nconst KEY_FILE_MAGIC = Buffer.from('WSKV', 'ascii');\nconst VERSIONED_KEY_FILE_SIZE = KEY_FILE_MAGIC.length + 1 + KEY_BYTES; // 37 bytes\n\n/**\n * Check and warn if the key file has incorrect permissions on POSIX.\n * On Windows this is a no-op (mode bits don't apply).\n */\nfunction checkKeyFilePermissions(keyFile: string): void {\n if (process.platform === 'win32') return; // No mode bits on Windows\n try {\n const stat = fs.statSync(keyFile);\n const actualMode = stat.mode & 0o777;\n if (actualMode !== KEY_FILE_MODE) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'vault.key_file_wrong_permissions',\n message: `Key file ${keyFile} has mode ${actualMode.toString(8)} — expected ${KEY_FILE_MODE.toString(8)}. Run: chmod ${KEY_FILE_MODE.toString(8)} ${keyFile}`,\n keyFile,\n expectedMode: KEY_FILE_MODE,\n actualMode,\n timestamp: new Date().toISOString(),\n }));\n }\n } catch {\n // stat can fail for reasons other than the file not existing;\n // if it does, the ENOENT path handles it.\n }\n}\n\n/**\n * Default vault: AES-256-GCM with a key stored at `keyFile` (mode 0o600).\n * The key is loaded lazily on first encrypt/decrypt; if it does not exist,\n * a fresh one is generated. Decryption of plaintext values is a no-op so\n * legacy configs continue to work.\n *\n * Key file format:\n * - Legacy (v1): exactly 32 raw bytes\n * - Versioned (v2+): 4-byte magic `WSKV` + 1-byte version + 32-byte key (37 bytes)\n *\n * Encrypted value format: `enc:v<N>:<iv>:<tag>:<ciphertext>` where N is the\n * key version. After rotation, encrypt() emits the new version prefix.\n */\nexport class DefaultSecretVault implements RotatableSecretVault {\n private readonly keyFile: string;\n private key?: Buffer | undefined;\n private _keyVersion: number = 1;\n\n constructor(opts: SecretVaultOptions) {\n this.keyFile = opts.keyFile;\n }\n\n /** Current key version. Starts at 1; incremented by rotateKey(). */\n get keyVersion(): number {\n // Ensure key is loaded so version is accurate\n if (!this.key) this.loadOrCreateKey();\n return this._keyVersion;\n }\n\n isEncrypted(value: string): boolean {\n return typeof value === 'string' && ENCRYPTED_PREFIX_PATTERN.test(value);\n }\n\n encrypt(plaintext: string): string {\n if (this.isEncrypted(plaintext)) return plaintext;\n const key = this.loadOrCreateKey();\n const iv = randomBytes(IV_BYTES);\n const cipher = createCipheriv(ALGO, key, iv);\n const ct = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);\n const tag = cipher.getAuthTag();\n const prefix = encryptedPrefixForVersion(this._keyVersion);\n return `${prefix}${iv.toString('base64')}:${tag.toString('base64')}:${ct.toString('base64')}`;\n }\n\n decrypt(value: string): string {\n if (!this.isEncrypted(value)) return value;\n // Strip the versioned prefix (enc:v1:, enc:v2:, etc.)\n const prefixMatch = value.match(ENCRYPTED_PREFIX_PATTERN);\n if (!prefixMatch) {\n throw new ConfigError({\n message: 'SecretVault: malformed encrypted value',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { field: 'encrypted_value' },\n });\n }\n const rest = value.slice(prefixMatch[0].length);\n const parts = rest.split(':');\n if (parts.length !== 3) {\n throw new ConfigError({\n message: 'SecretVault: malformed encrypted value',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { field: 'encrypted_value' },\n });\n }\n const [ivB64, tagB64, ctB64] = parts as [string, string, string];\n const iv = Buffer.from(ivB64, 'base64');\n const tag = Buffer.from(tagB64, 'base64');\n const ct = Buffer.from(ctB64, 'base64');\n if (iv.length !== IV_BYTES) throw new ConfigError({\n message: 'SecretVault: bad IV length',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { expected: IV_BYTES, actual: iv.length },\n });\n if (tag.length !== TAG_BYTES) throw new ConfigError({\n message: 'SecretVault: bad tag length',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { expected: TAG_BYTES, actual: tag.length },\n });\n const key = this.loadOrCreateKey();\n const decipher = createDecipheriv(ALGO, key, iv);\n decipher.setAuthTag(tag);\n const pt = Buffer.concat([decipher.update(ct), decipher.final()]);\n return pt.toString('utf8');\n }\n\n /**\n * Generate a new encryption key, write it to disk, and increment the key version.\n * After rotation, encrypt() emits the new version prefix (e.g. enc:v2:).\n * The caller must re-encrypt existing config values (see rotateConfigKeys()).\n */\n rotateKey(): { oldVersion: number; newVersion: number } {\n const oldVersion = this._keyVersion;\n const newKey = randomBytes(KEY_BYTES);\n const newVersion = oldVersion + 1;\n\n // Write versioned key file: WSKV + version byte + key\n const keyFileBuf = Buffer.alloc(VERSIONED_KEY_FILE_SIZE);\n KEY_FILE_MAGIC.copy(keyFileBuf, 0);\n keyFileBuf[KEY_FILE_MAGIC.length] = newVersion;\n newKey.copy(keyFileBuf, KEY_FILE_MAGIC.length + 1);\n\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\n fs.writeFileSync(this.keyFile, keyFileBuf, { mode: 0o600 });\n checkKeyFilePermissions(this.keyFile);\n\n this.key = newKey;\n this._keyVersion = newVersion;\n return { oldVersion, newVersion };\n }\n\n private loadOrCreateKey(): Buffer {\n // readFileSync blocks the event loop, but this is a one-time cost per\n // process: the key is cached after the first load and reused for every\n // subsequent encrypt/decrypt. For CLI usage (single run → exit) this is\n // negligible. For server contexts (eternal autonomy, MCP server mode),\n // the first encrypt/decrypt call causes a brief (<1ms) event loop stall.\n // Prefer calling vault.encrypt('') during boot to warm the cache if this\n // is a concern in your deployment.\n if (this.key) return this.key;\n try {\n const buf = fs.readFileSync(this.keyFile);\n\n // Detect key file format:\n if (buf.length === KEY_BYTES) {\n // Legacy v1: raw 32-byte key\n this.key = buf;\n this._keyVersion = 1;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n\n if (buf.length === VERSIONED_KEY_FILE_SIZE) {\n // Versioned v2+: WSKV magic + version byte + 32-byte key\n const magic = buf.subarray(0, KEY_FILE_MAGIC.length);\n if (!magic.equals(KEY_FILE_MAGIC)) {\n throw new ConfigError({\n message: `SecretVault: key file ${this.keyFile} has invalid magic header`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile },\n });\n }\n const version = buf[KEY_FILE_MAGIC.length]!;\n const key = buf.subarray(KEY_FILE_MAGIC.length + 1);\n if (key.length !== KEY_BYTES) {\n throw new ConfigError({\n message: `SecretVault: key file ${this.keyFile} has wrong key size (${key.length} bytes, expected ${KEY_BYTES})`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: key.length },\n });\n }\n this.key = Buffer.from(key);\n this._keyVersion = version;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n\n // Wrong size — neither legacy nor versioned format\n throw new ConfigError({\n message:\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\n `(expected ${KEY_BYTES} for v1 or ${VERSIONED_KEY_FILE_SIZE} for v2+). ` +\n `Remove it manually to generate a new key.`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: buf.length },\n });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n // Create a fresh key. Use sync APIs so the constructor-free getter\n // remains synchronous from the caller's perspective.\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\n const key = randomBytes(KEY_BYTES);\n // Use exclusive-create flag 'wx' to prevent races: if two processes race\n // to create the key file, only one succeeds and the loser gets EEXIST.\n try {\n fs.writeFileSync(this.keyFile, key, { mode: 0o600, flag: 'wx' });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST') throw err;\n // Another process won the race — re-read what they wrote.\n const buf = fs.readFileSync(this.keyFile);\n if (buf.length === KEY_BYTES) {\n // Legacy v1 format\n this.key = buf;\n this._keyVersion = 1;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n if (buf.length === VERSIONED_KEY_FILE_SIZE) {\n // Versioned format\n const magic = buf.subarray(0, KEY_FILE_MAGIC.length);\n if (!magic.equals(KEY_FILE_MAGIC)) {\n throw new ConfigError({\n message: `SecretVault: key file ${this.keyFile} has invalid magic header`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile },\n });\n }\n const version = buf[KEY_FILE_MAGIC.length]!;\n const winnerKey = buf.subarray(KEY_FILE_MAGIC.length + 1);\n this.key = Buffer.from(winnerKey);\n this._keyVersion = version;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n throw new ConfigError({\n message:\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\n `(expected ${KEY_BYTES} for v1 or ${VERSIONED_KEY_FILE_SIZE} for v2+). ` +\n `Remove it manually to generate a new key.`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: buf.length },\n });\n }\n this.key = key;\n this._keyVersion = 1;\n return key;\n }\n}\n\n/**\n * Walk a Config-shaped object and decrypt any apiKey-like fields in place,\n * returning a new object. Used by the config loader so the rest of the\n * system never has to know about the wire format.\n *\n * @param warn — callback for decryption warnings. Defaults to `console.warn`\n * for backward compatibility; pass `logger.warn` when a structured logger\n * is available (preferred in long-running/server contexts).\n */\nexport function decryptConfigSecrets<T>(\n cfg: T,\n vault: SecretVault,\n opts?: { warn?: (msg: string) => void },\n): T {\n const warn = opts?.warn ?? ((msg: string) => console.warn(msg));\n // A single corrupted/malformed encrypted field should not kill the entire\n // config load. Swallow per-field decrypt errors (zero the field so callers\n // see \"missing key\" instead of holding ciphertext) and surface a warning.\n return walk(cfg, vault, (v, key) => {\n try {\n return vault.decrypt(v);\n } catch (err) {\n warn(\n `[secret-vault] Failed to decrypt \"${key}\": ${err instanceof Error ? err.message : err}`,\n );\n return '';\n }\n });\n}\n\nexport function encryptConfigSecrets<T>(\n cfg: T,\n vault: SecretVault,\n _opts?: { warn?: (msg: string) => void },\n): T {\n return walk(cfg, vault, (v) => vault.encrypt(v));\n}\n\nfunction walk<T>(node: T, vault: SecretVault, transform: (s: string, key: string) => string): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walk(item, vault, transform)) as unknown as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k)) {\n out[k] = transform(v, k);\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walk(v, vault, transform);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * A key is treated as secret-bearing if its name (case-insensitive) contains\n * one of these tokens. Captures common variants like `apiKey`, `authToken`,\n * `refreshToken`, `sessionKey`, `password`, `client_secret`, `bearer`, etc.\n * Use a named field with `isSecret: false` annotation if you must opt out —\n * see `NON_SECRET_OVERRIDES` below.\n */\nconst SECRET_KEY_PATTERN =\n /(?:apikey|api_key|authtoken|auth_token|bearer|secret|password|passwd|pwd|refreshtoken|refresh_token|sessionkey|session_key|access[_-]?token|private[_-]?key)/i;\n\n// Field names that contain the literal substring \"key\" but are not secrets.\n// Keep this list short; the substring rule itself is intentionally narrow.\nconst NON_SECRET_OVERRIDES = new Set(['publickey', 'public_key']);\n\nexport function isSecretField(name: string): boolean {\n const lc = name.toLowerCase();\n if (NON_SECRET_OVERRIDES.has(lc)) return false;\n return SECRET_KEY_PATTERN.test(lc);\n}\n\n/**\n * Re-write `~/.wrongstack/config.json` (or any path) with all secret-bearing\n * fields encrypted. Used by the `wstack auth` subcommand.\n */\nexport async function rewriteConfigEncrypted(\n configPath: string,\n vault: SecretVault,\n patch?: Record<string, unknown>,\n): Promise<void> {\n let current: Record<string, unknown> = {};\n try {\n const raw = await fsp.readFile(configPath, 'utf8');\n current = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n // start from empty\n }\n const merged = deepMerge(current, patch ?? {});\n const encrypted = encryptConfigSecrets(merged, vault);\n await fsp.mkdir(path.dirname(configPath), { recursive: true });\n // atomicWrite: torn write here would erase every saved encrypted API key.\n await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 0o600 });\n await restrictFilePermissions(configPath);\n}\n\n/**\n * Scan a config file on disk for plaintext secret-bearing fields and\n * rewrite the file with them encrypted in place. Returns a count of how\n * many fields were migrated. Idempotent — calling on a fully-encrypted\n * file is a no-op and writes nothing. Used by the CLI on every boot so\n * users who had plaintext keys before the vault landed are upgraded\n * transparently.\n */\nexport async function migratePlaintextSecrets(\n configPath: string,\n vault: SecretVault,\n logger?: Pick<Logger, 'warn'>,\n): Promise<{ migrated: number; file: string }> {\n let raw: string;\n try {\n raw = await fsp.readFile(configPath, 'utf8');\n } catch {\n return { migrated: 0, file: configPath };\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return { migrated: 0, file: configPath };\n }\n const counter = { n: 0 };\n const migrated = walkCount(parsed, vault, counter);\n if (counter.n === 0) return { migrated: 0, file: configPath };\n // atomicWrite: runs on every boot for legacy users — torn write = wipe.\n await atomicWrite(configPath, JSON.stringify(migrated, null, 2), { mode: 0o600 });\n await restrictFilePermissions(\n configPath,\n logger ? { warn: (msg) => logger.warn(msg) } : undefined,\n );\n return { migrated: counter.n, file: configPath };\n}\n\n/**\n * Rotate the vault's encryption key and re-encrypt all secret-bearing\n * fields in a config file. This is the atomic key rotation operation:\n *\n * 1. Read the config file\n * 2. Decrypt all encrypted values with the old key\n * 3. Generate a new key (vault.rotateKey())\n * 4. Re-encrypt all values with the new key (new version prefix)\n * 5. Write the config file atomically\n *\n * Returns the number of fields re-encrypted and the version transition.\n * If the config file doesn't exist or has no encrypted fields, returns\n * { rotated: 0 } without modifying the key.\n */\nexport async function rotateConfigKeys(\n configPath: string,\n vault: RotatableSecretVault,\n logger?: Pick<Logger, 'warn' | 'info'>,\n): Promise<{ rotated: number; oldVersion: number; newVersion: number; file: string }> {\n const log = logger?.info ?? (() => {});\n const warn = logger?.warn ?? ((msg: string) => console.warn(msg));\n\n // Read the config file\n let raw: string;\n try {\n raw = await fsp.readFile(configPath, 'utf8');\n } catch {\n // No config file — just rotate the key without re-encrypting anything\n const { oldVersion, newVersion } = vault.rotateKey();\n log(`[secret-vault] Key rotated (v${oldVersion} → v${newVersion}) — no config file to re-encrypt`);\n return { rotated: 0, oldVersion, newVersion, file: configPath };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n warn(`[secret-vault] Config file ${configPath} is not valid JSON — skipping rotation`);\n return { rotated: 0, oldVersion: vault.keyVersion, newVersion: vault.keyVersion, file: configPath };\n }\n\n // Count encrypted fields and decrypt them\n const counter = { n: 0, failed: [] as string[] };\n const decrypted = walkDecryptCount(parsed, vault, counter);\n\n // Abort BEFORE rotating if any encrypted field could not be decrypted with\n // the current key. Rotation would discard the old key while these fields\n // still hold old-key ciphertext, and walkReencrypt skips already-encrypted\n // values — so they would become permanently undecryptable. Surface the\n // corruption and leave the key intact for the operator to investigate.\n if (counter.failed.length > 0) {\n throw new Error(\n `[secret-vault] Aborting key rotation: ${counter.failed.length} field(s) could not be decrypted ` +\n `with the current key and would be permanently lost on rotation: ${counter.failed.join(', ')}. ` +\n `Restore or remove these fields before rotating.`,\n );\n }\n\n if (counter.n === 0) {\n // No encrypted fields — just rotate the key\n const { oldVersion, newVersion } = vault.rotateKey();\n log(`[secret-vault] Key rotated (v${oldVersion} → v${newVersion}) — no encrypted fields to re-encrypt`);\n return { rotated: 0, oldVersion, newVersion, file: configPath };\n }\n\n // Rotate the key (generates new key, increments version)\n const { oldVersion, newVersion } = vault.rotateKey();\n\n // Re-encrypt all secret fields with the new key\n const reencrypted = walkReencrypt(decrypted, vault);\n\n // Write the config file atomically\n await atomicWrite(configPath, JSON.stringify(reencrypted, null, 2), { mode: 0o600 });\n await restrictFilePermissions(configPath, { warn });\n\n log(`[secret-vault] Key rotated (v${oldVersion} → v${newVersion}) — re-encrypted ${counter.n} field(s)`);\n return { rotated: counter.n, oldVersion, newVersion, file: configPath };\n}\n\n/**\n * Walk a config object, decrypt all encrypted values, and count them.\n * Returns a new object with decrypted values.\n *\n * `counter.failed` collects the key paths of any field that is encrypted but\n * could NOT be decrypted with the current key. These are left as-is (old\n * ciphertext). The caller MUST treat a non-empty `failed` list as a hard stop\n * before rotating: rotation discards the old key, and `walkReencrypt` skips\n * already-encrypted values, so a retained old-key ciphertext would become\n * permanently undecryptable. Surfacing it is strictly safer than entombing it.\n */\nfunction walkDecryptCount<T>(\n node: T,\n vault: SecretVault,\n counter: { n: number; failed: string[] },\n pathPrefix = '',\n): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item, i) =>\n walkDecryptCount(item, vault, counter, `${pathPrefix}[${i}]`),\n ) as unknown as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n const keyPath = pathPrefix ? `${pathPrefix}.${k}` : k;\n if (typeof v === 'string' && vault.isEncrypted(v)) {\n try {\n out[k] = vault.decrypt(v);\n counter.n++;\n } catch {\n // Decryption failed — record the path and keep the old ciphertext.\n // The caller aborts rotation when counter.failed is non-empty, so\n // the old key is never discarded while this value still depends on it.\n counter.failed.push(keyPath);\n out[k] = v;\n }\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkDecryptCount(v, vault, counter, keyPath);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * Walk a config object and re-encrypt all secret-bearing fields.\n * Unlike encryptConfigSecrets, this encrypts ALL string values that\n * were previously decrypted (they're now plaintext), not just those\n * matching the secret field pattern. This ensures we re-encrypt values\n * that were successfully decrypted in walkDecryptCount.\n */\nfunction walkReencrypt<T>(node: T, vault: SecretVault): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walkReencrypt(item, vault)) as unknown as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k) && v.length > 0 && !vault.isEncrypted(v)) {\n // This was a decrypted secret — re-encrypt it\n out[k] = vault.encrypt(v);\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkReencrypt(v, vault);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * Restrict a file to owner-only access. On POSIX this is chmod 0o600.\n * On Windows, chmod is a no-op — we use icacls to remove inherited\n * permissions and grant only the current user. Failures are logged\n * but not thrown so callers are not blocked on unsupported platforms.\n */\nasync function restrictFilePermissions(\n filePath: string,\n opts?: { warn?: (msg: string) => void },\n): Promise<void> {\n const warn = opts?.warn ?? ((msg: string) => console.warn(msg));\n if (process.platform === 'win32') {\n try {\n const { execFile } = await import('node:child_process');\n const { promisify } = await import('node:util');\n const execFileAsync = promisify(execFile);\n const user = windowsAccountName();\n if (!user) {\n warn(\n `[secret-vault] Could not determine the current Windows user for ${filePath}; skipping icacls hardening.`,\n );\n return;\n }\n // Remove inherited ACEs, grant full control only to current user.\n await execFileAsync('icacls', [filePath, '/inheritance:r', '/grant:r', `${user}:(F)`]);\n } catch {\n // Best-effort: icacls may not be available in all environments.\n warn(\n `[secret-vault] Could not restrict permissions on ${filePath} — config file may be readable by other users on this system.`,\n );\n }\n } else {\n try {\n await fsp.chmod(filePath, 0o600);\n } catch {\n // Best-effort\n }\n }\n}\n\nfunction windowsAccountName(): string | undefined {\n const username = process.env.USERNAME || process.env.USER;\n if (!username || username.includes('\\0')) return undefined;\n const domain = process.env.USERDOMAIN;\n if (domain && !domain.includes('\\0')) return `${domain}\\\\${username}`;\n return username;\n}\n\nfunction walkCount<T>(node: T, vault: SecretVault, counter: { n: number }): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walkCount(item, vault, counter)) as unknown as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k) && !vault.isEncrypted(v) && v.length > 0) {\n out[k] = vault.encrypt(v);\n counter.n++;\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkCount(v, vault, counter);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/** Keys that, when written into a plain object, can poison the prototype\n * chain. We never want user config to carry these. */\nimport { deepMerge } from '../utils/deep-merge.js';\n","/**\n * Well-known tool capabilities used for authorization decisions.\n *\n * These are the preferred values for `Tool.capabilities`.\n * New capabilities should be added here with clear documentation.\n *\n * Philosophy (2026-06+):\n * - Prefer capabilities over exact tool name matching.\n * - Subagent guards and future policies should primarily key off capabilities.\n * - Name-based denylists are legacy and will be phased down.\n */\nexport const ToolCapabilities = {\n /** Can execute arbitrary commands in the user's shell (the `bash` tool). */\n SHELL_ARBITRARY: 'shell.arbitrary',\n\n /** Can execute a restricted set of commands (the `exec` tool). */\n SHELL_RESTRICTED: 'shell.restricted',\n\n /** Can read files inside the project (and possibly outside via symlinks if not guarded). */\n FS_READ: 'fs.read',\n\n /** Can write / modify / delete files inside the project. */\n FS_WRITE: 'fs.write',\n\n /** Can write files outside the current project root (very high risk). */\n FS_WRITE_OUTSIDE_PROJECT: 'fs.write.outside-project',\n\n /** Can perform outbound network requests. */\n NET_OUTBOUND: 'net.outbound',\n\n /** Proxies tools from external MCP servers (unknown capability). */\n MCP_PROXY: 'mcp.proxy',\n\n /** Can spawn or manage subagents / multi-agent tasks. */\n SUBAGENT_SPAWN: 'subagent.spawn',\n\n /** Can mutate global or session configuration / trust state. */\n CONFIG_MUTATE: 'config.mutate',\n\n /** Can install packages or run package managers with side effects. */\n PACKAGE_INSTALL: 'package.install',\n} as const;\n\nexport type ToolCapability = (typeof ToolCapabilities)[keyof typeof ToolCapabilities];\n\n/**\n * Set of capabilities that are considered dangerous for subagents by default.\n * Subagents should not receive these capabilities unless the leader explicitly\n * allows the specific tool at spawn time.\n */\nexport const DANGEROUS_FOR_SUBAGENTS: readonly ToolCapability[] = [\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,\n ToolCapabilities.MCP_PROXY,\n ToolCapabilities.SUBAGENT_SPAWN,\n ToolCapabilities.CONFIG_MUTATE,\n ToolCapabilities.PACKAGE_INSTALL,\n];\n\n/**\n * Wide capability allowlist for subagents that the user has authorized to act\n * with full developer power (the CLI fleet host applies this to any subagent\n * that isn't given an explicit, narrower grant). It covers everything needed to\n * do real work end-to-end — read, write/edit inside the project, outbound\n * network, and shell/build/install — so a delegated coding or build agent runs\n * the same toolchain the leader would, without per-tool confirmation it cannot\n * answer.\n *\n * Deliberately EXCLUDED (require an explicit per-spawn `allowedCapabilities`\n * grant, because they escape the task's blast radius rather than perform it):\n * - `fs.write.outside-project` — writing outside the repo (e.g. ~/.ssh).\n * - `mcp.proxy` — third-party MCP tools (also hard-blocked by name).\n * - `subagent.spawn` — recursive delegation (the baseline prompt forbids it).\n * - `config.mutate` — rewriting trust/config is privilege escalation, not work.\n */\nexport const WIDE_SUBAGENT_CAPABILITIES: readonly ToolCapability[] = [\n ToolCapabilities.FS_READ,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.NET_OUTBOUND,\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.PACKAGE_INSTALL,\n];\n\n/**\n * Check if a tool (or its capabilities array) includes any dangerous capability\n * for subagent execution.\n */\nexport function hasDangerousCapabilityForSubagents(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): boolean {\n if (!toolOrCaps) return false;\n // Use `as unknown as ...` to allow accessing .capabilities on the union type\n const input = toolOrCaps as unknown as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.some((c) => DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability));\n}\n\n/**\n * Check if a tool declares a specific capability (or any of the provided ones).\n */\nexport function hasCapability(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n capability: ToolCapability | ToolCapability[],\n): boolean {\n if (!toolOrCaps) return false;\n // Use `as unknown as ...` to allow accessing .capabilities on the union type\n const input = toolOrCaps as unknown as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n const toCheck = Array.isArray(capability) ? capability : [capability];\n return toCheck.some((c) => caps.includes(c));\n}\n\n/**\n * Returns the intersection of a tool's capabilities with the dangerous set.\n * Useful for logging and audit trails.\n */\nexport function getDangerousCapabilities(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): ToolCapability[] {\n if (!toolOrCaps) return [];\n // Use `as unknown as ...` to allow accessing .capabilities on the union type\n const input = toolOrCaps as unknown as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.filter((c): c is ToolCapability =>\n DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability),\n );\n}\n","import * as path from 'node:path';\n\n// Best-effort heuristic detection of destructive shell commands — NOT a\n// security boundary. Static analysis of shell strings is inherently defeatable\n// by obfuscation: env-variable indirection (`$RM -rf /`), quote-splitting\n// (`r''m`), base64/eval pipes (`echo ... | base64 -d | sh`), command\n// substitution (`$(printf rm) -rf`), and aliases all evade these patterns.\n// This is one defense-in-depth layer behind the permission policy and the\n// project-escape checks below, not the sole gate. Treat a miss here as\n// expected, not as a hole to be plugged with ever-more-clever regexes.\nconst DESTRUCTIVE_BASH_PATTERNS: RegExp[] = [\n /\\bgit\\s+(?:clean\\s+-[^\\s]*[xdf]|reset\\s+--hard)\\b/i,\n /\\b(?:drop|truncate)\\s+(?:table|database|schema)\\b/i,\n /\\bdelete\\s+from\\b/i,\n /\\b(?:mkfs|format|diskpart|shutdown|reboot)\\b/i,\n /\\bchmod\\s+-R\\s+777\\b/i,\n /\\bchown\\s+-R\\b/i,\n /\\b(?:curl|wget)\\b.*\\|\\s*(?:sh|bash|zsh|pwsh|powershell)\\b/i,\n /\\b(?:powershell|pwsh)\\b.*(?:-encodedcommand|-enc)\\b/i,\n /:\\(\\)\\s*\\{\\s*:\\|:&\\s*}\\s*;/,\n];\n\nconst PROJECT_ESCAPE_PATTERN = /(?:^|[\\s\"'])\\.\\.(?:[\\\\/]|$)/;\nconst ABSOLUTE_PATH_PATTERN = /(?:^|[\\s\"'])(?:~[\\\\/]|\\/[A-Za-z0-9_.-]|[A-Za-z]:[\\\\/])/;\nconst SHELL_OPERATORS = new Set(['&&', '||', '|', ';', '>', '>>', '<', '2>', '2>>']);\n\nexport function getInputString(input: unknown, key: string): string | undefined {\n if (!input || typeof input !== 'object') return undefined;\n const value = (input as Record<string, unknown>)[key];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function pathLooksInsideProject(rawPath: string, projectRoot: string | undefined): boolean {\n if (!projectRoot) return false;\n // A leading ~ is the home directory, never the project root. Without this,\n // path.resolve() treats \"~/cache\" as a relative path *inside* the project\n // (there is no shell tilde-expansion here), masking an escape like `rm -rf ~/cache`.\n if (rawPath === '~' || rawPath.startsWith('~/') || rawPath.startsWith('~\\\\')) return false;\n const resolved = path.resolve(projectRoot, rawPath);\n const relative = path.relative(projectRoot, resolved);\n return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative);\n}\n\nfunction tokenizeShell(command: string): string[] {\n return command.match(/\"[^\"]*\"|'[^']*'|\\S+/g)?.map((token) => token.replace(/^['\"]|['\"]$/g, '')) ?? [];\n}\n\nfunction pathTokenIsOutsideProject(token: string, projectRoot: string | undefined): boolean {\n if (!token || SHELL_OPERATORS.has(token) || token.startsWith('-')) return false;\n if (token === '/' || token === '~' || token === '.' || token === '..') return token !== '.';\n if (token.includes('*')) return true;\n if (token.startsWith('..') || token.includes('../') || token.includes('..\\\\')) return true;\n if (path.isAbsolute(token) || token.startsWith('~/')) return !pathLooksInsideProject(token, projectRoot);\n return false;\n}\n\nfunction hasDangerousDeleteTarget(\n tokens: string[],\n start: number,\n projectRoot: string | undefined,\n): boolean {\n const targets = tokens\n .slice(start)\n .filter((token) => !token.startsWith('-') && !SHELL_OPERATORS.has(token));\n if (targets.length === 0) return true;\n return targets.some((target) => pathTokenIsOutsideProject(target, projectRoot));\n}\n\nfunction hasDestructiveDelete(command: string, projectRoot: string | undefined): boolean {\n const tokens = tokenizeShell(command);\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i]?.toLowerCase();\n if (!token) continue;\n\n if (token === 'rm') {\n const args = tokens.slice(i + 1);\n const recursiveOrForce = args.some(\n (arg) => /^-[^-]*[rf]/i.test(arg) || arg === '--recursive' || arg === '--force',\n );\n if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;\n }\n\n if (token === 'rmdir' || token === 'rd') {\n const args = tokens.slice(i + 1);\n const recursive = args.some((arg) => arg.toLowerCase() === '/s');\n if (recursive && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;\n }\n\n if (token === 'del' || token === 'erase') {\n if (hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;\n }\n\n if (token === 'remove-item') {\n const args = tokens.slice(i + 1).map((arg) => arg.toLowerCase());\n const recursiveOrForce = args.includes('-recurse') || args.includes('-force');\n if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;\n }\n }\n return false;\n}\n\nexport function isClearlyDestructiveBashCommand(\n command: string,\n projectRoot: string | undefined,\n): boolean {\n const trimmed = command.trim();\n if (!trimmed) return false;\n if (hasDestructiveDelete(trimmed, projectRoot)) return true;\n if (DESTRUCTIVE_BASH_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;\n\n // Changing directory or targeting paths outside the project turns arbitrary\n // shell from \"normal workspace work\" into something the user should see.\n if (/\\bcd\\s+(?:\\.\\.|~|\\/|[A-Za-z]:[\\\\/])/i.test(trimmed)) return true;\n if (PROJECT_ESCAPE_PATTERN.test(trimmed)) return true;\n\n const absolute = trimmed.match(ABSOLUTE_PATH_PATTERN)?.[0]?.trim().replace(/^['\"]|['\"]$/g, '');\n if (absolute && !pathLooksInsideProject(absolute, projectRoot)) return true;\n\n return false;\n}\n","import * as fs from 'node:fs/promises';\nimport type { Context } from '../core/context.js';\nimport type { InputReader } from '../types/input-reader.js';\nimport type { PermissionDecision, PermissionPolicy, TrustPolicy } from '../types/permission.js';\nimport type { Tool } from '../types/tool.js';\nimport { getDangerousCapabilities, hasCapability, ToolCapabilities } from './capabilities.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { matchAny, matchGlob } from '../utils/glob-match.js';\nimport { safeParse } from '../utils/safe-json.js';\nimport {\n getInputString,\n isClearlyDestructiveBashCommand,\n pathLooksInsideProject,\n} from './yolo-risk.js';\n\nexport interface PermissionPolicyOptions {\n trustFile: string;\n yolo?: boolean | undefined;\n /**\n * When true, YOLO mode auto-approves even destructive calls without confirm.\n * @deprecated YOLO now auto-approves everything by default. Use `confirmDestructive`\n * to opt back into destructive-operation confirmation prompts.\n */\n yoloDestructive?: boolean | undefined;\n /** @deprecated Use `yoloDestructive`. */\n forceAllYolo?: boolean | undefined;\n /**\n * When true AND yolo is true, destructive operations still require confirmation.\n * This is the opt-in safety net: set this if you want YOLO for normal work but\n * explicit approval for `rm -rf`, project-escaping writes, etc.\n * Has no effect when yolo is false (normal permission flow applies).\n */\n confirmDestructive?: boolean | undefined;\n promptDelegate?: (\n tool: Tool,\n input: unknown,\n suggestedPattern: string,\n ) => Promise<'yes' | 'no' | 'always' | 'deny'>;\n inputReader?: InputReader | undefined;\n}\n\nexport class DefaultPermissionPolicy implements PermissionPolicy {\n private policy: TrustPolicy = {};\n private loaded = false;\n private readonly trustFile: string;\n private yolo: boolean;\n private yoloDestructive: boolean;\n /** When true, destructive ops still require confirmation even in YOLO mode. */\n private confirmDestructive: boolean;\n /**\n * Session-scoped \"soft deny\" map. When the user presses 'n' (block once),\n * the tool+pattern is added here. If the LLM retries in the same session,\n * we return deny directly without asking again.\n *\n * Cleared on reload() since reload = fresh trust file snapshot.\n */\n private sessionDenied = new Map<string, boolean>();\n /**\n * Session-scoped \"soft trust\" map. When the user presses 'a' (allow once),\n * the tool+pattern is added here. If the LLM retries in the same session,\n * we return auto directly without asking again.\n *\n * Cleared on reload().\n */\n private sessionAllowed = new Map<string, boolean>();\n /**\n * Interactive prompt delegate. When set, `evaluate()` calls it to get a\n * user decision synchronously (CLI REPL path). When cleared (TUI / WebUI),\n * `evaluate()` returns `confirm` so the caller can emit\n * `tool.confirm_needed` for the UI layer to handle.\n *\n * Mutable so the host can switch from CLI-prompt to event-driven\n * confirmation at runtime (e.g. when `--goal` forces TUI mode after\n * the agent was already constructed).\n */\n private promptDelegate?: PermissionPolicyOptions['promptDelegate'] | undefined;\n /** Pre-compiled wildcard patterns — rebuilt on reload for O(1) lookup. */\n private wildcardEntries: { pattern: string; value: TrustPolicy[string] }[] = [];\n /**\n * Evaluate-result cache. Keyed by `tool.name::subject` so repeated calls\n * with the same tool+input skip namespace matching, subject computation,\n * pattern matching (matchAny), and YOLO destructive gating.\n *\n * Cleared on any state change (reload, trust, deny, yolo toggle) because\n * the result depends on the full policy state. The write-tool smart-bypass\n * (step 7 in `evaluate()`) is not cached since `ctx.hasRead()` changes\n * dynamically within a session.\n *\n * LRU eviction is not needed — the cache is cleared on state changes\n * that are rare (trust file ops, user confirm) and the number of unique\n * tool+subject pairs per iteration is small (<50).\n */\n private _evalCache = new Map<string, PermissionDecision>();\n\n constructor(opts: PermissionPolicyOptions) {\n this.trustFile = opts.trustFile;\n this.yolo = opts.yolo ?? false;\n this.yoloDestructive = opts.yoloDestructive ?? opts.forceAllYolo ?? false;\n this.confirmDestructive = opts.confirmDestructive ?? false;\n this.promptDelegate = opts.promptDelegate;\n }\n\n /**\n * Replace (or clear) the interactive prompt delegate at runtime.\n * Used by the CLI to switch from inline prompts (REPL) to event-driven\n * confirmation (TUI) when the run mode is determined after the policy\n * was constructed (e.g. `--goal` auto-flipping to TUI).\n */\n setPromptDelegate(delegate: PermissionPolicyOptions['promptDelegate']): void {\n this.promptDelegate = delegate;\n }\n\n /** Toggle YOLO (auto-approve) mode at runtime. */\n setYolo(enabled: boolean): void {\n if (this.yolo !== enabled) this._evalCache.clear();\n this.yolo = enabled;\n }\n\n /** Check whether YOLO mode is currently active. */\n getYolo(): boolean {\n return this.yolo;\n }\n\n /** Toggle the destructive YOLO override at runtime. */\n setYoloDestructive(enabled: boolean): void {\n if (this.yoloDestructive !== enabled) this._evalCache.clear();\n this.yoloDestructive = enabled;\n }\n\n /** Check whether the destructive YOLO override is active. */\n getYoloDestructive(): boolean {\n return this.yoloDestructive;\n }\n\n /** Toggle destructive confirmation gate (only meaningful when yolo is active). */\n setConfirmDestructive(enabled: boolean): void {\n if (this.confirmDestructive !== enabled) this._evalCache.clear();\n this.confirmDestructive = enabled;\n }\n\n /** Check whether destructive confirmation gate is active. */\n getConfirmDestructive(): boolean {\n return this.confirmDestructive;\n }\n\n async reload(): Promise<void> {\n try {\n const raw = await fs.readFile(this.trustFile, 'utf8');\n const parsed = safeParse<TrustPolicy>(raw);\n if (parsed.ok && parsed.value) this.policy = parsed.value;\n } catch {\n this.policy = {};\n }\n // Pre-compile wildcard entries so findNamespaceEntry is O(k) instead of O(n*m)\n this.wildcardEntries = [];\n for (const [key, val] of Object.entries(this.policy)) {\n if (key.includes('*')) this.wildcardEntries.push({ pattern: key, value: val });\n }\n // Clear session-scoped soft deny/allow — reload = fresh trust file snapshot\n this.sessionDenied.clear();\n this.sessionAllowed.clear();\n this._evalCache.clear();\n this.loaded = true;\n }\n\n async evaluate(tool: Tool, input: unknown, ctx: Context): Promise<PermissionDecision> {\n if (!this.loaded) await this.reload();\n\n // 1. Tool-namespace matching (mcp__server__* etc.)\n const namespaceEntry = this.findNamespaceEntry(tool.name);\n\n // 2. Tool-name entry\n const entry = this.policy[tool.name] ?? namespaceEntry;\n\n // 3. Compute subject (the thing being matched)\n const subject = this.subjectFor(tool.name, input, tool.subjectKey);\n const cacheKey = `${tool.name}::${subject ?? tool.name}`;\n\n // S1. Cache check — skip namespace/subject/pattern re-evaluation when the\n // same tool+subject was already decided. The write-tool smart bypass\n // (step 7) is NOT cached because `ctx.hasRead()` changes dynamically\n // within a session — we let it fall through below.\n if (tool.name !== 'write') {\n const cached = this._evalCache.get(cacheKey);\n if (cached !== undefined) return cached;\n }\n\n // 3a. Session soft deny — 'n' blocks this tool+pattern for the rest of\n // this session without writing to the trust file. Prevents LLM retry\n // from re-triggering the confirm prompt.\n if (this.sessionDenied.has(cacheKey)) {\n const decision: PermissionDecision = { permission: 'deny', source: 'deny', reason: 'session soft deny (user pressed no)' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n\n // 3b. Session soft allow — 'y' auto-approves this tool+pattern for the\n // rest of this session without writing to the trust file.\n if (this.sessionAllowed.has(cacheKey)) {\n const decision: PermissionDecision = {\n permission: 'auto',\n source: 'trust',\n reason: 'session soft allow (user pressed yes)',\n };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n\n // 4. Deny — absolute\n if (entry?.deny && subject && matchAny(entry.deny, subject)) {\n const decision: PermissionDecision = { permission: 'deny', source: 'deny', reason: 'matched deny pattern' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n if (tool.permission === 'deny') {\n const decision: PermissionDecision = { permission: 'deny', source: 'default', reason: 'tool default deny' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n\n // 5. Allow (trust file)\n if (entry?.allow && subject && matchAny(entry.allow, subject)) {\n const decision: PermissionDecision = { permission: 'auto', source: 'trust', reason: 'matched allow pattern' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n if (entry?.auto) {\n const decision: PermissionDecision = { permission: 'auto', source: 'trust' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n\n // 6. YOLO — auto-approve everything. Destructive operations are\n // included unless the user explicitly opted into `confirmDestructive`.\n if (this.yolo) {\n if (this.confirmDestructive) {\n const destructive = this.isDestructiveYoloCall(tool, input, ctx);\n if (destructive) {\n if (this.promptDelegate) {\n const decision = await this.promptDelegate(tool, input, subject ?? tool.name);\n if (decision === 'always') {\n await this.trust({ tool: tool.name, pattern: subject ?? tool.name });\n return { permission: 'auto', source: 'user', reason: 'destructive yolo always-allowed' };\n }\n if (decision === 'deny') {\n await this.deny({ tool: tool.name, pattern: subject ?? tool.name });\n return { permission: 'deny', source: 'user', reason: 'user denied destructive yolo' };\n }\n return { permission: decision === 'yes' ? 'auto' : 'deny', source: 'user' };\n }\n return {\n permission: 'confirm',\n source: 'yolo_destructive',\n riskTier: 'destructive',\n reason: 'destructive tool needs explicit approval (confirmDestructive is on)',\n };\n }\n }\n const decision: PermissionDecision = { permission: 'auto', source: 'yolo' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n\n // 7. Smart bypass: write tool — if the file was already read in this\n // session, the user has already seen the content. No confirm needed.\n // NOTE: deliberately NOT cached because ctx.hasRead() changes dynamically.\n if (tool.name === 'write' && subject) {\n if (ctx.hasRead(subject)) {\n return {\n permission: 'auto',\n source: 'context',\n reason: 'file already read in this session',\n };\n }\n }\n\n // 8. Tool default — but mutating tools need confirmation even with\n // auto-permission (e.g. shellcheck makes network calls; a remote WebSocket\n // client must not be able to trigger them without the user seeing the\n // tool.confirm_needed prompt). Non-mutating auto tools (read-only\n // heuristics, schema checks) are still safe to shortcut.\n //\n // Capability-based check: tools with fs.read or net.outbound (non-mutating)\n // can auto-approve; tools with fs.write, shell.*, etc. need confirmation.\n const hasWriteCap = hasCapability(tool, ToolCapabilities.FS_WRITE);\n const hasShellCap = hasCapability(tool, [\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ]);\n const hasInstallCap = hasCapability(tool, ToolCapabilities.PACKAGE_INSTALL);\n const hasConfigCap = hasCapability(tool, ToolCapabilities.CONFIG_MUTATE);\n const hasSubagentCap = hasCapability(tool, ToolCapabilities.SUBAGENT_SPAWN);\n const isMutating = tool.mutating || hasWriteCap || hasShellCap || hasInstallCap || hasConfigCap || hasSubagentCap;\n if (tool.permission === 'auto' && !isMutating) {\n const decision: PermissionDecision = { permission: 'auto', source: 'default' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n\n // 9. Confirm — delegate to prompt\n if (this.promptDelegate) {\n const decision = await this.promptDelegate(tool, input, subject ?? tool.name);\n if (decision === 'always') {\n await this.trust({ tool: tool.name, pattern: subject ?? tool.name });\n return { permission: 'auto', source: 'user', reason: 'user always-allowed' };\n }\n if (decision === 'deny') {\n await this.deny({ tool: tool.name, pattern: subject ?? tool.name });\n return { permission: 'deny', source: 'user', reason: 'user denied' };\n }\n return { permission: decision === 'yes' ? 'auto' : 'deny', source: 'user' };\n }\n return { permission: 'confirm', source: 'default' };\n }\n\n // Capability-based destructive check (preferred over name-based)\n private isDestructiveByCapability(tool: Tool): boolean {\n const caps = tool.capabilities ?? [];\n if (caps.includes('shell.arbitrary')) return true;\n if (caps.includes('fs.write')) return true;\n if (caps.includes('fs.write.outside-project')) return true;\n return false;\n }\n\n private isDestructiveYoloCall(tool: Tool, input: unknown, ctx: Context): boolean {\n // 1. Capability-based check (preferred — works for all tools, not just hardcoded names)\n if (this.isDestructiveByCapability(tool)) {\n // For shell tools, also check if the command is clearly destructive\n if (tool.name === 'bash') {\n const command = getInputString(input, 'command');\n return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : true;\n }\n // For write tools, check if path escapes project\n if (tool.name === 'write' || tool.name === 'edit' || tool.name === 'replace' || tool.name === 'patch') {\n const targetPath = getInputString(input, 'path') ?? getInputString(input, 'file');\n if (!targetPath || !ctx.projectRoot) return false;\n return !pathLooksInsideProject(targetPath, ctx.projectRoot);\n }\n return true;\n }\n\n // 2. Legacy name-based fallback (for tools without capabilities)\n if (tool.name === 'bash') {\n const command = getInputString(input, 'command');\n return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : true;\n }\n\n if (tool.name === 'write' || tool.name === 'edit' || tool.name === 'replace' || tool.name === 'patch') {\n const targetPath = getInputString(input, 'path') ?? getInputString(input, 'file');\n if (!targetPath || !ctx.projectRoot) return false;\n return !pathLooksInsideProject(targetPath, ctx.projectRoot);\n }\n\n return tool.riskTier === 'destructive';\n }\n\n async trust(rule: { tool: string; pattern: string }): Promise<void> {\n if (!this.loaded) await this.reload();\n const entry = this.policy[rule.tool] ?? {};\n entry.allow = Array.from(new Set([...(entry.allow ?? []), rule.pattern]));\n this.policy[rule.tool] = entry;\n this._evalCache.clear();\n try {\n await atomicWrite(this.trustFile, JSON.stringify(this.policy, null, 2));\n } catch (err) {\n // Revert in-memory state since disk write failed\n const existing = this.policy[rule.tool];\n if (existing?.allow) {\n const idx = existing.allow.indexOf(rule.pattern);\n if (idx !== -1) existing.allow.splice(idx, 1);\n }\n throw err;\n }\n }\n\n /** Persist a deny rule — this tool+pattern pair is permanently blocked. */\n async deny(rule: { tool: string; pattern: string }): Promise<void> {\n if (!this.loaded) await this.reload();\n const entry = this.policy[rule.tool] ?? {};\n entry.deny = Array.from(new Set([...(entry.deny ?? []), rule.pattern]));\n this.policy[rule.tool] = entry;\n this._evalCache.clear();\n try {\n await atomicWrite(this.trustFile, JSON.stringify(this.policy, null, 2));\n } catch (err) {\n // Revert in-memory state since disk write failed\n const existing = this.policy[rule.tool];\n if (existing?.deny) {\n const idx = existing.deny.indexOf(rule.pattern);\n if (idx !== -1) existing.deny.splice(idx, 1);\n }\n throw err;\n }\n }\n\n /** Block this tool+pattern for the rest of this session (no trust file). */\n denyOnce(rule: { tool: string; pattern: string }): void {\n this.sessionDenied.set(`${rule.tool}::${rule.pattern}`, true);\n this._evalCache.clear();\n }\n\n /** Auto-approve this tool+pattern for the rest of this session (no trust file). */\n allowOnce(rule: { tool: string; pattern: string }): void {\n this.sessionAllowed.set(`${rule.tool}::${rule.pattern}`, true);\n this._evalCache.clear();\n }\n\n private subjectFor(toolName: string, input: unknown, subjectKey?: string): string | undefined {\n if (!input || typeof input !== 'object') return undefined;\n const obj = input as Record<string, unknown>;\n\n // Glob metacharacters are dangerous: a crafted subject like \"**\" or \"foo/**/bar\"\n // can match too broadly in the allow/deny pattern match. Escape them so the\n // matching is done on the literal string.\n const globChars = /[*?[\\]]/g;\n const escapeGlob = (s: string) => s.replace(globChars, (c) => `\\\\${c}`);\n const normalizePath = (s: string) => escapeGlob(s.replace(/\\\\/g, '/'));\n\n // 1. Explicit subjectKey on the tool wins — eliminates the cross-tool\n // collision where e.g. an HTTP tool's `path` field meant \"request\n // path\" but was matched against filesystem-path trust rules.\n if (subjectKey) {\n const v = obj[subjectKey];\n if (typeof v === 'string') {\n // Heuristic: path-like keys get backslash normalization for glob\n // matching on Windows; everything else is treated as opaque.\n return subjectKey === 'path' || subjectKey === 'file' || subjectKey === 'files'\n ? normalizePath(v)\n : escapeGlob(v);\n }\n // subjectKey was declared but the runtime value isn't a string —\n // fall through to the legacy heuristic so the policy still has a\n // chance to match on something sensible.\n }\n\n // 2. Legacy heuristic — preserved for tools that haven't migrated.\n if (toolName === 'bash' && typeof obj.command === 'string') {\n return escapeGlob(obj.command);\n }\n if (typeof obj.path === 'string') {\n return normalizePath(obj.path);\n }\n if (typeof obj.url === 'string') {\n return escapeGlob(obj.url);\n }\n if (typeof obj.name === 'string') {\n return escapeGlob(obj.name);\n }\n return undefined;\n }\n\n private findNamespaceEntry(toolName: string): TrustPolicy[string] | undefined {\n // Use pre-compiled wildcard entries — O(k) where k = wildcard count\n for (const { pattern, value } of this.wildcardEntries) {\n if (matchGlob(pattern, toolName)) return value;\n }\n return undefined;\n }\n}\n\n/**\n * Auto-approving PermissionPolicy used for subagents. Subagents run\n * non-interactively under a director — they cannot answer permission\n * prompts, so a non-YOLO policy on the leader would silently hang the\n * delegated run on the first sensitive tool call. The user already\n * authorized the delegation when they invoked the leader; subagents\n * inherit that authorization automatically.\n *\n * Tool defaults of `permission: 'deny'` are still honored (this is a\n * subagent capability override, not a deny-bypass).\n *\n * 2026-06+: Primary decision is now based on declared `Tool.capabilities`\n * (capability allowlist / denylist model). The legacy name-based DENY set\n * is kept only for backward compatibility with tools that have not yet\n * declared capabilities.\n */\n/**\n * Auto-approving PermissionPolicy used for subagents. Subagents run\n * non-interactively under a director — they cannot answer permission\n * prompts, so a non-YOLO policy on the leader would silently hang the\n * delegated run on the first sensitive tool call. The user already\n * authorized the delegation when they invoked the leader; subagents\n * inherit that authorization automatically.\n *\n * Tool defaults of `permission: 'deny'` are still honored (this is a\n * subagent capability override, not a deny-bypass).\n *\n * 2026-06+: Primary decision is now based on declared `Tool.capabilities`\n * (capability allowlist / denylist model). The legacy name-based DENY set\n * is kept only for backward compatibility with tools that have not yet\n * declared capabilities.\n *\n * 2026-06-13+: Switched to allowlist-by-default. Only tools with explicitly\n * allowed capabilities are auto-approved. Everything else is denied.\n * Default allowed: fs.read, net.outbound (read-only, safe operations).\n */\nexport class AutoApprovePermissionPolicy implements PermissionPolicy {\n private readonly allowedCapabilities: readonly string[];\n\n constructor(allowedCapabilities?: readonly string[]) {\n // Default allowlist: read-only, safe operations\n this.allowedCapabilities = allowedCapabilities ?? [\n ToolCapabilities.FS_READ,\n ToolCapabilities.NET_OUTBOUND,\n ];\n }\n\n private static isMcpTool(name: string): boolean {\n return name.startsWith('mcp__');\n }\n\n async evaluate(tool: Tool): Promise<PermissionDecision> {\n const caps = tool.capabilities ?? [];\n const hasAllowedCap = caps.some((c) => this.allowedCapabilities.includes(c));\n const isMcp = AutoApprovePermissionPolicy.isMcpTool(tool.name);\n\n // A tool may bundle several capabilities (e.g. `install` declares both\n // `package.install` and `shell.restricted`). The `some()` check above only\n // confirms the tool has *a* useful allowed capability — it does not stop a\n // dangerous capability from riding along. Require every DANGEROUS capability\n // the tool declares to be explicitly present in the allowlist, so widening\n // the allowlist (e.g. `/techstack` adding `fs.write`) grants exactly that\n // capability and nothing more. This is what lets the ToolExecutor trust an\n // `auto` from this policy and skip its post-permission dangerous-capability\n // downgrade (which would otherwise force a `confirm` no subagent can answer).\n const dangerousNotAllowed = getDangerousCapabilities(tool).filter(\n (c) => !this.allowedCapabilities.includes(c),\n );\n\n // Block if: tool is MCP, tool default is deny, no allowed capability, or it\n // carries a dangerous capability the leader did not explicitly grant.\n const blocked =\n tool.permission === 'deny' || isMcp || !hasAllowedCap || dangerousNotAllowed.length > 0;\n\n if (blocked) {\n const reason = isMcp\n ? `MCP tool ${tool.name} is not auto-approved for subagents — ask the leader to allow it explicitly`\n : tool.permission === 'deny'\n ? 'tool default deny'\n : dangerousNotAllowed.length > 0\n ? `tool requires un-granted dangerous capability (needs: ${dangerousNotAllowed.join(', ')}, allowed: ${this.allowedCapabilities.join(', ')})`\n : `tool lacks allowed capability (has: ${caps.join(', ') || 'none'}, allowed: ${this.allowedCapabilities.join(', ')})`;\n\n return {\n permission: 'deny',\n source: 'subagent_guard',\n reason,\n };\n }\n\n return { permission: 'auto', source: 'yolo' };\n }\n async trust(): Promise<void> {\n // No-op: subagent permission decisions are ephemeral and must not\n // pollute the leader's persisted trust file.\n }\n async deny(): Promise<void> {\n // No-op: same as trust — subagent decisions are ephemeral.\n }\n denyOnce(): void {\n // No-op: subagent decisions are ephemeral.\n }\n allowOnce(): void {\n // No-op: subagent decisions are ephemeral.\n }\n async reload(): Promise<void> {\n // No-op: nothing to load.\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/security/secret-scrubber.ts","../../src/utils/atomic-write.ts","../../src/utils/deep-merge.ts","../../src/utils/error.ts","../../src/utils/expect-defined.ts","../../src/utils/glob-match.ts","../../src/utils/safe-json.ts","../../src/utils/tool-subject.ts","../../src/types/errors.ts","../../src/types/secret-vault.ts","../../src/security/secret-vault.ts","../../src/security/capabilities.ts","../../src/security/yolo-risk.ts","../../src/security/permission-policy.ts"],"names":["path","stat","resolve","randomBytes","path2","key","fsp","oldVersion","newVersion","relative","fs3","decision"],"mappings":";;;;;;AAOA,IAAM,QAAA,GAAsB;AAAA;AAAA;AAAA,EAG1B;AAAA,IACE,IAAA,EAAM,eAAA;AAAA,IACN,KAAA,EAAO;AAAA,GACT;AAAA,EACA,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,iEAAA,EAAkE;AAAA,EAC/F,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,sDAAA,EAAuD;AAAA,EACpF,EAAE,IAAA,EAAM,eAAA,EAAiB,KAAA,EAAO,8DAAA,EAA+D;AAAA,EAC/F,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,kDAAA,EAAmD;AAAA,EACpF,EAAE,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,uDAAA,EAAwD;AAAA,EAClF,EAAE,IAAA,EAAM,aAAA,EAAe,KAAA,EAAO,gEAAA,EAAiE;AAAA,EAC/F;AAAA,IACE,IAAA,EAAM,YAAA;AAAA,IACN,KAAA,EAAO;AAAA,GACT;AAAA,EACA;AAAA,IACE,IAAA,EAAM,YAAA;AAAA,IAAc,KAAA,EAAO;AAAA,GAC7B;AAAA,EACA;AAAA,IACE,IAAA,EAAM,oBAAA;AAAA;AAAA,IAEN,KAAA,EAAO;AAAA,GACT;AAAA,EACA;AAAA,IACE,IAAA,EAAM,KAAA;AAAA;AAAA,IAEN,KAAA,EACE;AAAA,GACJ;AAAA,EACA;AAAA,IACE,IAAA,EAAM,aAAA;AAAA;AAAA,IAEN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,EAAE,IAAA,EAAM,aAAA,EAAe,KAAA,EAAO,kCAAA,EAAmC;AAAA,EACjE,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,gCAAA,EAAiC;AAAA,EAChE,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,sBAAA,EAAuB;AAAA,EACnD,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,sBAAA,EAAuB;AAAA;AAAA,EAEnD;AAAA,IACE,IAAA,EAAM,mBAAA;AAAA;AAAA,IAEN,KAAA,EAAO;AAAA,GACT;AAAA,EACA;AAAA,IACE,IAAA,EAAM,iBAAA;AAAA;AAAA,IAEN,KAAA,EAAO;AAAA,GACT;AAAA,EACA;AAAA,IACE,IAAA,EAAM,gBAAA;AAAA;AAAA,IAEN,KAAA,EAAO;AAAA,GACT;AAAA,EACA;AAAA,IACE,IAAA,EAAM,UAAA;AAAA;AAAA,IAEN,KAAA,EAAO;AAAA,GACT;AAAA,EACA;AAAA,IACE,IAAA,EAAM,cAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMN,KAAA,EAAO;AAAA,GACT;AAAA,EACA;AAAA,IACE,IAAA,EAAM,kBAAA;AAAA;AAAA;AAAA,IAGN,KAAA,EAAO;AAAA;AAEX,CAAA;AAQA,IAAM,kBAAkB,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,kBAAkB,CAAA;AAS5E,IAAM,iBAAiB,IAAI,MAAA,CAAO,eAAA,CAAgB,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAA,EAAI,CAAA,CAAE,KAAA,CAAM,MAAM,CAAA,CAAA,CAAG,CAAA,CAAE,IAAA,CAAK,GAAG,GAAG,GAAG,CAAA;AAGlG,IAAM,kBAAA,GAAqB,SAAS,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,kBAAkB,CAAA,CAAG,KAAA;AAMhF,IAAM,qBAAA,GAAwB,gBAAgB,GAAA,CAAI,CAAC,MAAM,CAAA,UAAA,EAAa,CAAA,CAAE,IAAI,CAAA,CAAA,CAAG,CAAA;AAO/E,IAAM,oBAAoB,EAAA,GAAK,IAAA;AAY/B,SAAS,qBAAqB,IAAA,EAAuB;AACnD,EAAA,OACE,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,EAC1B,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EACnB,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EACnB,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,EACpB,IAAA,CAAK,SAAS,aAAa,CAAA;AAAA,EAC3B,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EACnB,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,EACpB,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,EACpB,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EACnB,IAAA,CAAK,SAAS,SAAS,CAAA;AAAA,EACvB,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,EACpB,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EACnB,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EACnB,IAAA,CAAK,SAAS,OAAO,CAAA;AAAA,EACrB,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,EACpB,IAAA,CAAK,SAAS,OAAO,CAAA;AAAA,EACrB,IAAA,CAAK,SAAS,SAAS,CAAA;AAAA,EACvB,IAAA,CAAK,SAAS,UAAU,CAAA;AAAA,EACxB,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,EAC1B,IAAA,CAAK,SAAS,YAAY,CAAA,IAC1B,KAAK,QAAA,CAAS,gBAAgB,CAAA,IAC9B,IAAA,CAAK,QAAA,CAAS,aAAa,KAC3B,IAAA,CAAK,QAAA,CAAS,eAAe,CAAA,IAC7B,IAAA,CAAK,SAAS,UAAU,CAAA,IACxB,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA;AAE5B;AAEO,IAAM,wBAAN,MAAsD;AAAA,EAC3D,MAAM,IAAA,EAAsB;AAC1B,IAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAMlB,IAAA,IAAI,CAAC,oBAAA,CAAqB,IAAI,CAAA,EAAG,OAAO,IAAA;AAMxC,IAAA,IAAI,IAAA,CAAK,UAAU,iBAAA,EAAmB;AACpC,MAAA,OAAO,IAAA,CAAK,SAAS,IAAI,CAAA;AAAA,IAC3B;AACA,IAAA,MAAM,MAAgB,EAAC;AACvB,IAAA,IAAI,CAAA,GAAI,CAAA;AACR,IAAA,OAAO,CAAA,GAAI,KAAK,MAAA,EAAQ;AACtB,MAAA,IAAI,MAAM,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,iBAAA,EAAmB,KAAK,MAAM,CAAA;AAErD,MAAA,IAAI,GAAA,GAAM,KAAK,MAAA,EAAQ;AACrB,QAAA,MAAM,EAAA,GAAK,IAAA,CAAK,WAAA,CAAY,IAAA,EAAM,GAAG,CAAA;AACrC,QAAA,IAAI,EAAA,GAAK,CAAA,GAAI,iBAAA,GAAoB,CAAA,QAAS,EAAA,GAAK,CAAA;AAAA,MACjD;AACA,MAAA,GAAA,CAAI,IAAA,CAAK,KAAK,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA,EAAG,GAAG,CAAC,CAAC,CAAA;AAC1C,MAAA,CAAA,GAAI,GAAA;AAAA,IACN;AACA,IAAA,OAAO,GAAA,CAAI,KAAK,EAAE,CAAA;AAAA,EACpB;AAAA,EAEQ,SAAS,IAAA,EAAsB;AAGrC,IAAA,IAAI,CAAC,oBAAA,CAAqB,IAAI,CAAA,EAAG,OAAO,IAAA;AAMxC,IAAA,IAAI,MAAM,IAAA,CAAK,OAAA;AAAA,MACb,cAAA;AAAA,MACA,CAAC,UAAU,MAAA,KAAW;AAEpB,QAAA,MAAM,MAAM,MAAA,CAAO,SAAA,CAAU,CAAC,CAAA,KAAM,MAAM,MAAS,CAAA;AACnD,QAAA,IAAI,GAAA,GAAM,GAAG,OAAO,KAAA;AACpB,QAAA,MAAM,WAAA,GAAc,sBAAsB,GAAG,CAAA;AAC7C,QAAA,OAAO,WAAA,KAAgB,SAAY,WAAA,GAAc,KAAA;AAAA,MACnD;AAAA,KACF;AAGA,IAAA,GAAA,GAAM,IAAI,OAAA,CAAQ,kBAAA,EAAoB,CAAC,MAAA,EAAQ,QAAQ,OAAA,KAAY;AACjE,MAAA,OAAO,GAAG,MAAM,CAAA,4BAAA,CAAA;AAAA,IAClB,CAAC,CAAA;AAED,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,YAAe,GAAA,EAAW;AACxB,IAAA,MAAM,IAAA,uBAAW,OAAA,EAAQ;AACzB,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,KAAwB;AACrC,MAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,IAAA,CAAK,MAAM,CAAC,CAAA;AAC9C,MAAA,IAAI,CAAA,KAAM,IAAA,IAAQ,OAAO,CAAA,KAAM,UAAU,OAAO,CAAA;AAChD,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,CAAW,CAAA,EAAG,OAAO,CAAA;AAClC,MAAA,IAAA,CAAK,IAAI,CAAW,CAAA;AACpB,MAAA,IAAI,MAAM,OAAA,CAAQ,CAAC,GAAG,OAAO,CAAA,CAAE,IAAI,KAAK,CAAA;AACxC,MAAA,MAAM,MAA+B,EAAC;AACtC,MAAA,KAAA,MAAW,CAAC,CAAA,EAAG,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,CAA4B,CAAA,EAAG;AACnE,QAAA,GAAA,CAAI,CAAC,CAAA,GAAI,KAAA,CAAM,GAAG,CAAA;AAAA,MACpB;AACA,MAAA,OAAO,GAAA;AAAA,IACT,CAAA;AACA,IAAA,OAAO,MAAM,GAAG,CAAA;AAAA,EAClB;AACF;ACpOA,eAAsB,WAAA,CACpB,UAAA,EACA,OAAA,EACA,IAAA,GAA2B,EAAC,EACb;AACf,EAAA,MAAM,GAAA,GAAWA,cAAQ,UAAU,CAAA;AACnC,EAAA,MAAS,EAAA,CAAA,KAAA,CAAM,GAAA,EAAK,EAAE,SAAA,EAAW,MAAM,CAAA;AACvC,EAAA,MAAM,GAAA,GAAWA,KAAA,CAAA,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAASA,eAAS,UAAU,CAAC,CAAA,CAAA,EAAI,WAAA,CAAY,CAAC,CAAA,CAAE,QAAA,CAAS,KAAK,CAAC,CAAA,IAAA,CAAM,CAAA;AAIhG,EAAA,IAAI;AACF,IAAA,IAAI,OAAO,YAAY,QAAA,EAAU;AAC/B,MAAA,MAAS,EAAA,CAAA,SAAA,CAAU,GAAA,EAAK,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,QAAA,EAAU,IAAA,CAAK,QAAA,IAAY,MAAA,EAAQ,CAAA;AAAA,IACpF,CAAA,MAAO;AACL,MAAA,MAAS,aAAU,GAAA,EAAK,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,IACjD;AACA,IAAA,IAAI;AACF,MAAA,MAAM,EAAA,GAAK,MAAS,EAAA,CAAA,IAAA,CAAK,GAAA,EAAK,IAAI,CAAA;AAClC,MAAA,IAAI;AACF,QAAA,MAAM,GAAG,IAAA,EAAK;AAAA,MAChB,CAAA,SAAE;AACA,QAAA,MAAM,GAAG,KAAA,EAAM;AAAA,MACjB;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAGA,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAMC,KAAAA,GAAO,MAAS,EAAA,CAAA,IAAA,CAAK,UAAU,CAAA;AACrC,MAAA,IAAA,GAAOA,MAAK,IAAA,GAAO,GAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,GAAO,IAAA,CAAK,IAAA;AAAA,IACd;AACA,IAAA,IAAI,SAAS,KAAA,CAAA,EAAW;AACtB,MAAA,MAAS,EAAA,CAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,IAC1B;AACA,IAAA,MAAM,eAAA,CAAgB,KAAK,UAAU,CAAA;AAAA,EACvC,SAAS,GAAA,EAAK;AACZ,IAAA,IAAI;AACF,MAAA,MAAS,UAAO,GAAG,CAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,MAAM,GAAA;AAAA,EACR;AACF;AAqEA,IAAM,sBAAA,uBAA6B,GAAA,CAAI,CAAC,SAAS,OAAA,EAAS,QAAA,EAAU,WAAW,CAAC,CAAA;AAEhF,eAAe,eAAA,CAAgB,MAAc,EAAA,EAA2B;AACtE,EAAA,IAAI,OAAA,CAAQ,aAAa,OAAA,EAAS;AAChC,IAAA,MAAS,EAAA,CAAA,MAAA,CAAO,MAAM,EAAE,CAAA;AACxB,IAAA;AAAA,EACF;AACA,EAAA,MAAM,SAAS,CAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,KAAK,GAAG,CAAA;AACpC,EAAA,IAAI,OAAA;AACJ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACvC,IAAA,IAAI;AACF,MAAA,MAAS,EAAA,CAAA,MAAA,CAAO,MAAM,EAAE,CAAA;AACxB,MAAA;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,GAAU,GAAA;AACV,MAAA,MAAM,OAAQ,GAAA,EAA+B,IAAA;AAC7C,MAAA,IAAI,CAAC,QAAQ,CAAC,sBAAA,CAAuB,IAAI,IAAI,CAAA,IAAK,CAAA,KAAM,MAAA,CAAO,MAAA,EAAQ;AACrE,QAAA,MAAM,GAAA;AAAA,MACR;AACA,MAAA,MAAM,IAAI,QAAQ,CAACC,QAAAA,KAAY,WAAWA,QAAAA,EAAS,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,IAC/D;AAAA,EACF;AACA,EAAA,MAAM,OAAA;AACR;;;AC1IO,IAAM,oBAAA,uBAA2B,GAAA,CAAI;AAAA,EAC1C,WAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA,EACA,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAOM,SAAS,iBAAiB,CAAA,EAAuB;AACtD,EAAA,OAAO,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,KAAM,IAAA,IAAS,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,CAAA,KAAM,UAAW,CAAA;AACxF;AA6EO,SAAS,SAAA,CACd,IAAA,EACA,KAAA,EACA,OAAA,GAA4B,EAAC,EACpB;AACT,EAAA,MAAM;AAAA,IACJ,kBAAA,GAAqB,cAAA;AAAA,IACrB,SAAA,GAAY,SAAA;AAAA,IACZ,YAAA,GAAe,IAAA;AAAA,IACf;AAAA,GACF,GAAI,OAAA;AAGJ,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,IAAA,EAAM;AAC7C,IAAA,OAAO,kBAAA,KAAuB,iBAAiB,KAAA,GAAQ,IAAA;AAAA,EACzD;AACA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,EAAM;AAC/C,IAAA,OAAO,kBAAA,KAAuB,iBAAiB,KAAA,GAAQ,IAAA;AAAA,EACzD;AAIA,EAAA,IAAI,MAAM,OAAA,CAAQ,IAAI,KAAK,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC/C,IAAA,IACE,cAAc,mBAAA,IACd,gBAAA,CAAiB,IAAI,CAAA,IACrB,gBAAA,CAAiB,KAAK,CAAA,EACtB;AACA,MAAA,OAAO,CAAC,mBAAG,IAAI,GAAA,CAAI,CAAC,GAAG,IAAA,EAAM,GAAG,KAAK,CAAC,CAAC,CAAA;AAAA,IACzC;AACA,IAAA,OAAO,kBAAA,KAAuB,iBAAiB,KAAA,GAAQ,IAAA;AAAA,EACzD;AAGA,EAAA,IAAI,MAAM,OAAA,CAAQ,IAAI,KAAK,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC/C,IAAA,OAAO,kBAAA,KAAuB,iBAAiB,KAAA,GAAQ,IAAA;AAAA,EACzD;AAGA,EAAA,MAAM,OAAA,GAAU,IAAA;AAChB,EAAA,MAAM,QAAA,GAAW,KAAA;AACjB,EAAA,MAAM,GAAA,GAA+B,EAAE,GAAG,OAAA,EAAQ;AAElD,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAC7C,IAAA,IAAI,YAAA,IAAgB,oBAAA,CAAqB,GAAA,CAAI,CAAC,CAAA,EAAG;AAEjD,IAAA,MAAM,QAAA,GAAW,IAAI,CAAC,CAAA;AACtB,IAAA,IACE,MAAM,IAAA,IACN,OAAO,MAAM,QAAA,IACb,CAAC,MAAM,OAAA,CAAQ,CAAC,KAChB,QAAA,KAAa,IAAA,IACb,OAAO,QAAA,KAAa,QAAA,IACpB,CAAC,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,EACvB;AAEA,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,SAAA,CAAU,QAAA,EAAU,GAAG,OAAO,CAAA;AAAA,IACzC,CAAA,MAAA,IAAW,MAAM,OAAA,CAAQ,CAAC,KAAK,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAMtD,MAAA,IAAI,0BAAA,IAA8B,CAAC,gBAAA,CAAiB,CAAC,CAAA,EAAG;AACtD,QAAA,0BAAA,CAA2B,CAAA,EAAG,QAAA,CAAS,MAAA,EAAQ,CAAA,CAAE,MAAM,CAAA;AAAA,MACzD;AACA,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,SAAA,CAAU,QAAA,EAAU,GAAG,OAAO,CAAA;AAAA,IACzC,CAAA,MAAA,IAAW,MAAM,MAAA,EAAW;AAG1B,MAAA,IACE,0BAAA,IACA,MAAM,OAAA,CAAQ,CAAC,KACf,CAAC,gBAAA,CAAiB,CAAC,CAAA,EACnB;AACA,QAAA,MAAM,cAAc,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,GAAI,SAAS,MAAA,GAAS,CAAA;AAChE,QAAA,0BAAA,CAA2B,CAAA,EAAG,WAAA,EAAa,CAAA,CAAE,MAAM,CAAA;AAAA,MACrD;AACA,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IACX;AAAA,EAIF;AAEA,EAAA,OAAO,GAAA;AACT;;;AChMO,SAAS,eAAe,GAAA,EAAsB;AACnD,EAAA,OAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AACxD;;;ACFO,SAAS,aAAA,CAAiB,OAA6B,KAAA,EAAmB;AAC/E,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AACzC,IAAA,MAAM,MAAM,IAAI,KAAA,CAAkD,8BAA8B,CAAA;AAChG,IAAA,GAAA,CAAI,IAAA,GAAO,oBAAA;AACX,IAAA,MAAM,GAAA;AAAA,EACR;AACA,EAAA,OAAO,KAAA;AACT;;;ACFA,SAAS,YAAY,CAAA,EAAmB;AACtC,EAAA,OAAO,CAAA,CAAE,OAAA,CAAQ,gBAAA,EAAkB,MAAM,CAAA;AAC3C;AAIA,IAAM,mBAAA,uBAA0B,GAAA,EAAoB;AACpD,IAAM,cAAA,GAAiB,GAAA;AAEvB,SAAS,cAAc,OAAA,EAAyB;AAC9C,EAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,GAAA,CAAI,OAAO,CAAA;AAC9C,EAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,EAAA,IAAI,mBAAA,CAAoB,QAAQ,cAAA,EAAgB;AAE9C,IAAA,MAAM,IAAA,GAAO,CAAC,GAAG,mBAAA,CAAoB,MAAM,CAAA;AAC3C,IAAA,KAAA,IAAS,CAAA,GAAI,GAAG,CAAA,GAAI,IAAA,CAAK,MAAM,cAAA,GAAiB,CAAC,GAAG,CAAA,EAAA,EAAK;AACvD,MAAA,mBAAA,CAAoB,MAAA,CAAO,aAAA,CAAc,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA;AAAA,IACnD;AAAA,EACF;AACA,EAAA,MAAM,EAAA,GAAK,YAAY,OAAO,CAAA;AAC9B,EAAA,mBAAA,CAAoB,GAAA,CAAI,SAAS,EAAE,CAAA;AACnC,EAAA,OAAO,EAAA;AACT;AAGA,IAAM,oBAAA,GAAuB,IAAA;AAEtB,SAAS,YAAY,OAAA,EAAyB;AACnD,EAAA,IAAI,OAAA,CAAQ,SAAS,oBAAA,EAAsB;AACzC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,oBAAoB,CAAA,WAAA,CAAa,CAAA;AAAA,EAC3E;AACA,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,IAAI,EAAA,GAAK,GAAA;AACT,EAAA,OAAO,CAAA,GAAI,QAAQ,MAAA,EAAQ;AACzB,IAAA,MAAM,CAAA,GAAI,QAAQ,CAAC,CAAA;AACnB,IAAA,IAAI,MAAM,GAAA,EAAK;AACb,MAAA,IAAI,OAAA,CAAQ,CAAA,GAAI,CAAC,CAAA,KAAM,GAAA,EAAK;AAE1B,QAAA,EAAA,IAAM,IAAA;AACN,QAAA,CAAA,IAAK,CAAA;AAEL,QAAA,IAAI,OAAA,CAAQ,CAAC,CAAA,KAAM,GAAA,EAAK,CAAA,EAAA;AAAA,MAC1B,CAAA,MAAO;AAEL,QAAA,EAAA,IAAM,OAAA;AACN,QAAA,CAAA,EAAA;AAAA,MACF;AAAA,IACF,CAAA,MAAA,IAAW,MAAM,GAAA,EAAK;AACpB,MAAA,EAAA,IAAM,MAAA;AACN,MAAA,CAAA,EAAA;AAAA,IACF,CAAA,MAAA,IAAW,MAAM,GAAA,EAAK;AACpB,MAAA,IAAI,GAAA,GAAM,GAAA;AACV,MAAA,CAAA,EAAA;AACA,MAAA,IAAI,QAAQ,CAAC,CAAA,KAAM,OAAO,OAAA,CAAQ,CAAC,MAAM,GAAA,EAAK;AAC5C,QAAA,GAAA,IAAO,GAAA;AACP,QAAA,CAAA,EAAA;AAAA,MACF;AACA,MAAA,OAAO,IAAI,OAAA,CAAQ,MAAA,IAAU,OAAA,CAAQ,CAAC,MAAM,GAAA,EAAK;AAC/C,QAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,CAAC,CAAA,IAAK,EAAA;AAKzB,QAAA,IAAI,OAAO,IAAA,EAAM;AACf,UAAA,GAAA,IAAO,MAAA;AAAA,QACT,CAAA,MAAA,IAAW,EAAA,KAAO,GAAA,IAAO,EAAA,KAAO,GAAA,EAAK;AACnC,UAAA,GAAA,IAAO,KAAK,EAAE,CAAA,CAAA;AAAA,QAChB,CAAA,MAAO;AACL,UAAA,GAAA,IAAO,EAAA;AAAA,QACT;AACA,QAAA,CAAA,EAAA;AAAA,MACF;AACA,MAAA,GAAA,IAAO,GAAA;AACP,MAAA,EAAA,IAAM,GAAA;AACN,MAAA,CAAA,EAAA;AAAA,IACF,CAAA,MAAO;AACL,MAAA,EAAA,IAAM,WAAA,CAAY,KAAK,EAAE,CAAA;AACzB,MAAA,CAAA,EAAA;AAAA,IACF;AAAA,EACF;AACA,EAAA,EAAA,IAAM,GAAA;AACN,EAAA,OAAO,IAAI,OAAO,EAAE,CAAA;AACtB;AAEO,SAAS,SAAA,CAAU,SAAiB,KAAA,EAAwB;AACjE,EAAA,OAAO,aAAA,CAAc,OAAO,CAAA,CAAE,IAAA,CAAK,KAAK,CAAA;AAC1C;AAEO,SAAS,QAAA,CAAS,UAAoB,KAAA,EAAwB;AACnE,EAAA,OAAO,SAAS,IAAA,CAAK,CAAC,MAAM,SAAA,CAAU,CAAA,EAAG,KAAK,CAAC,CAAA;AACjD;;;AC3FO,SAAS,SAAA,CAAuB,KAAA,EAAe,QAAA,GAAW,GAAA,EAA+B;AAC9F,EAAA,IAAI,KAAA,CAAM,SAAS,QAAA,EAAU;AAC3B,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,CAAA,qBAAA,EAAwB,QAAQ,CAAA,OAAA,CAAA,EAAU;AAAA,EACvE;AACA,EAAA,IAAI;AACF,IAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,OAAO,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA,EAAO;AAAA,EACnD,SAAS,GAAA,EAAK;AACZ,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,KAAA;AAAA,MACJ,KAAA,EAAO,eAAe,GAAG;AAAA,KAC3B;AAAA,EACF;AACF;;;ACpBA,IAAM,mBAAA,GAAsB,UAAA;AAErB,SAAS,kBAAkB,KAAA,EAAuB;AACvD,EAAA,OAAO,MAAM,OAAA,CAAQ,mBAAA,EAAqB,CAAC,IAAA,KAAS,CAAA,EAAA,EAAK,IAAI,CAAA,CAAE,CAAA;AACjE;AAEO,SAAS,qBAAqB,KAAA,EAAuB;AAC1D,EAAA,OAAO,iBAAA,CAAkB,KAAA,CAAM,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAC,CAAA;AACpD;AAEO,SAAS,iBAAiB,UAAA,EAA6B;AAC5D,EAAA,OAAO,UAAA,KAAe,MAAA,IAAU,UAAA,KAAe,MAAA,IAAU,UAAA,KAAe,OAAA;AAC1E;AAEO,SAAS,mBAAA,CACd,QAAA,EACA,KAAA,EACA,UAAA,EACoB;AACpB,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,MAAA;AAChD,EAAA,MAAM,GAAA,GAAM,KAAA;AAEZ,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAM,KAAA,GAAQ,IAAI,UAAU,CAAA;AAC5B,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,MAAA,OAAO,iBAAiB,UAAU,CAAA,GAAI,qBAAqB,KAAK,CAAA,GAAI,kBAAkB,KAAK,CAAA;AAAA,IAC7F;AAAA,EACF;AAEA,EAAA,IAAI,QAAA,KAAa,MAAA,IAAU,OAAO,GAAA,CAAI,YAAY,QAAA,EAAU;AAC1D,IAAA,OAAO,iBAAA,CAAkB,IAAI,OAAO,CAAA;AAAA,EACtC;AACA,EAAA,IAAI,OAAO,GAAA,CAAI,IAAA,KAAS,QAAA,EAAU;AAChC,IAAA,OAAO,oBAAA,CAAqB,IAAI,IAAI,CAAA;AAAA,EACtC;AACA,EAAA,IAAI,OAAO,GAAA,CAAI,GAAA,KAAQ,QAAA,EAAU;AAC/B,IAAA,OAAO,iBAAA,CAAkB,IAAI,GAAG,CAAA;AAAA,EAClC;AACA,EAAA,IAAI,OAAO,GAAA,CAAI,IAAA,KAAS,QAAA,EAAU;AAChC,IAAA,OAAO,iBAAA,CAAkB,IAAI,IAAI,CAAA;AAAA,EACnC;AACA,EAAA,OAAO,MAAA;AACT;;;AClBO,IAAM,WAAA,GAAc;AAAA;AAAA,EAEzB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,wBAAA,EAA0B,0BAAA;AAAA,EAC1B,qBAAA,EAAuB,uBAAA;AAAA,EACvB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,yBAAA,EAA2B,2BAAA;AAAA;AAAA,EAE3B,cAAA,EAAgB,gBAAA;AAAA,EAChB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,YAAA,EAAc,cAAA;AAAA,EACd,kBAAA,EAAoB,oBAAA;AAAA;AAAA,EAEpB,cAAA,EAAgB,gBAAA;AAAA,EAChB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,uBAAA,EAAyB,yBAAA;AAAA;AAAA,EAEzB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,yBAAA,EAA2B,2BAAA;AAAA;AAAA,EAE3B,qBAAA,EAAuB,uBAAA;AAAA,EACvB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,aAAA,EAAe,eAAA;AAAA,EACf,gBAAA,EAAkB,kBAAA;AAAA;AAAA,EAElB,iBAAA,EAAmB,mBAAA;AAAA,EACnB,iBAAA,EAAmB,mBAAA;AAAA,EACnB,oBAAA,EAAsB,sBAAA;AAAA;AAAA,EAEtB,6BAAA,EAA+B,+BAAA;AAAA,EAC/B,yBAAA,EAA2B,2BAAA;AAAA,EAC3B,6BAAA,EAA+B,+BAAA;AAAA,EAC/B,kBAAA,EAAoB,oBAAA;AAAA,EACpB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,gBAAA,EAAkB,kBAAA;AAAA;AAAA,EAElB,cAAA,EAAgB,gBAAA;AAAA,EAChB,eAAA,EAAiB,iBAAA;AAAA,EACjB,eAAA,EAAiB,iBAAA;AAAA,EACjB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,sBAAA,EAAwB,wBAAA;AAAA;AAAA,EAExB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,iBAAA,EAAmB,mBAAA;AAAA,EACnB,aAAA,EAAe,eAAA;AAAA;AAAA,EAEf,gBAAA,EAAkB,kBAAA;AAAA,EAClB,OAAA,EAAS;AACX,CAAA;AAwBO,IAAM,eAAA,GAAN,cAA8B,KAAA,CAAM;AAAA,EAChC,IAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EAET,YAAY,IAAA,EAQT;AACD,IAAA,KAAA,CAAM,KAAK,OAAA,EAAS,EAAE,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AACzC,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,QAAA,GAAW,KAAK,QAAA,IAAY,OAAA;AACjC,IAAA,IAAA,CAAK,WAAA,GAAc,KAAK,WAAA,IAAe,KAAA;AACvC,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAA,GAAmB;AACjB,IAAA,MAAM,GAAA,GAAM,KAAK,OAAA,GAAU,CAAA,CAAA,EAAI,cAAc,IAAA,CAAK,OAAO,CAAC,CAAA,CAAA,GAAK,EAAA;AAC/D,IAAA,OAAO,GAAG,IAAA,CAAK,IAAI,KAAK,IAAA,CAAK,OAAO,GAAG,GAAG,CAAA,CAAA;AAAA,EAC5C;AACF,CAAA;AAEA,SAAS,cAAc,GAAA,EAAsC;AAC3D,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,CAC7B,MAAA,CAAO,CAAC,GAAG,CAAC,CAAA,KAAM,CAAA,KAAM,MAAS,CAAA,CACjC,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CACV,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,CAAA;AACtC,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,GAAI,CAAA,CAAA,EAAI,MAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA;AACrD;AAyCO,IAAM,WAAA,GAAN,cAA0B,eAAA,CAAgB;AAAA,EAC/C,YAAY,IAAA,EAQT;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAA,EAAW,QAAA;AAAA,MACX,QAAA,EAAU,OAAA;AAAA,MACV,WAAA,EAAa,KAAA;AAAA,MACb,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AAAA,EACd;AACF,CAAA;;;ACjKO,IAAM,wBAAA,GAA2B,cAAA;AAOjC,SAAS,0BAA0B,OAAA,EAAyB;AACjE,EAAA,OAAO,QAAQ,OAAO,CAAA,CAAA,CAAA;AACxB;;;ACnCA,IAAM,SAAA,GAAY,EAAA;AAClB,IAAM,QAAA,GAAW,EAAA;AACjB,IAAM,SAAA,GAAY,EAAA;AAClB,IAAM,IAAA,GAAO,aAAA;AAEb,IAAM,aAAA,GAAgB,GAAA;AAMtB,IAAM,cAAA,GAAiB,MAAA,CAAO,IAAA,CAAK,MAAA,EAAQ,OAAO,CAAA;AAClD,IAAM,uBAAA,GAA0B,cAAA,CAAe,MAAA,GAAS,CAAA,GAAI,SAAA;AAM5D,SAAS,wBAAwB,OAAA,EAAuB;AACtD,EAAA,IAAI,OAAA,CAAQ,aAAa,OAAA,EAAS;AAClC,EAAA,IAAI;AACF,IAAA,MAAMD,KAAAA,GAAU,aAAS,OAAO,CAAA;AAChC,IAAA,MAAM,UAAA,GAAaA,MAAK,IAAA,GAAO,GAAA;AAC/B,IAAA,IAAI,eAAe,aAAA,EAAe;AAChC,MAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,QAC1B,KAAA,EAAO,MAAA;AAAA,QACP,KAAA,EAAO,kCAAA;AAAA,QACP,SAAS,CAAA,SAAA,EAAY,OAAO,aAAa,UAAA,CAAW,QAAA,CAAS,CAAC,CAAC,CAAA,iBAAA,EAAe,cAAc,QAAA,CAAS,CAAC,CAAC,CAAA,aAAA,EAAgB,aAAA,CAAc,SAAS,CAAC,CAAC,IAAI,OAAO,CAAA,CAAA;AAAA,QAC3J,OAAA;AAAA,QACA,YAAA,EAAc,aAAA;AAAA,QACd,UAAA;AAAA,QACA,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACnC,CAAC,CAAA;AAAA,IACJ;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAGR;AACF;AAeO,IAAM,qBAAN,MAAyD;AAAA,EAC7C,OAAA;AAAA,EACT,GAAA;AAAA,EACA,WAAA,GAAsB,CAAA;AAAA,EAE9B,YAAY,IAAA,EAA0B;AACpC,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,EACtB;AAAA;AAAA,EAGA,IAAI,UAAA,GAAqB;AAEvB,IAAA,IAAI,CAAC,IAAA,CAAK,GAAA,EAAK,IAAA,CAAK,eAAA,EAAgB;AACpC,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AAAA,EAEA,YAAY,KAAA,EAAwB;AAClC,IAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,wBAAA,CAAyB,KAAK,KAAK,CAAA;AAAA,EACzE;AAAA,EAEA,QAAQ,SAAA,EAA2B;AACjC,IAAA,IAAI,IAAA,CAAK,WAAA,CAAY,SAAS,CAAA,EAAG,OAAO,SAAA;AACxC,IAAA,MAAM,GAAA,GAAM,KAAK,eAAA,EAAgB;AACjC,IAAA,MAAM,EAAA,GAAKE,YAAY,QAAQ,CAAA;AAC/B,IAAA,MAAM,MAAA,GAAS,cAAA,CAAe,IAAA,EAAM,GAAA,EAAK,EAAE,CAAA;AAC3C,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,MAAA,CAAO,CAAC,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,MAAM,CAAA,EAAG,MAAA,CAAO,KAAA,EAAO,CAAC,CAAA;AAC3E,IAAA,MAAM,GAAA,GAAM,OAAO,UAAA,EAAW;AAC9B,IAAA,MAAM,MAAA,GAAS,yBAAA,CAA0B,IAAA,CAAK,WAAW,CAAA;AACzD,IAAA,OAAO,GAAG,MAAM,CAAA,EAAG,EAAA,CAAG,QAAA,CAAS,QAAQ,CAAC,CAAA,CAAA,EAAI,GAAA,CAAI,QAAA,CAAS,QAAQ,CAAC,CAAA,CAAA,EAAI,EAAA,CAAG,QAAA,CAAS,QAAQ,CAAC,CAAA,CAAA;AAAA,EAC7F;AAAA,EAEA,QAAQ,KAAA,EAAuB;AAC7B,IAAA,IAAI,CAAC,IAAA,CAAK,WAAA,CAAY,KAAK,GAAG,OAAO,KAAA;AAErC,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,KAAA,CAAM,wBAAwB,CAAA;AACxD,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,OAAA,EAAS,wCAAA;AAAA,QACT,MAAM,WAAA,CAAY,mBAAA;AAAA,QAClB,OAAA,EAAS,EAAE,KAAA,EAAO,iBAAA;AAAkB,OACrC,CAAA;AAAA,IACH;AACA,IAAA,MAAM,OAAO,KAAA,CAAM,KAAA,CAAM,WAAA,CAAY,CAAC,EAAE,MAAM,CAAA;AAC9C,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC5B,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,OAAA,EAAS,wCAAA;AAAA,QACT,MAAM,WAAA,CAAY,mBAAA;AAAA,QAClB,OAAA,EAAS,EAAE,KAAA,EAAO,iBAAA;AAAkB,OACrC,CAAA;AAAA,IACH;AACA,IAAA,MAAM,CAAC,KAAA,EAAO,MAAA,EAAQ,KAAK,CAAA,GAAI,KAAA;AAC/B,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,IAAA,CAAK,KAAA,EAAO,QAAQ,CAAA;AACtC,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,IAAA,CAAK,MAAA,EAAQ,QAAQ,CAAA;AACxC,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,IAAA,CAAK,KAAA,EAAO,QAAQ,CAAA;AACtC,IAAA,IAAI,EAAA,CAAG,MAAA,KAAW,QAAA,EAAU,MAAM,IAAI,WAAA,CAAY;AAAA,MAChD,OAAA,EAAS,4BAAA;AAAA,MACT,MAAM,WAAA,CAAY,mBAAA;AAAA,MAClB,SAAS,EAAE,QAAA,EAAU,QAAA,EAAU,MAAA,EAAQ,GAAG,MAAA;AAAO,KAClD,CAAA;AACD,IAAA,IAAI,GAAA,CAAI,MAAA,KAAW,SAAA,EAAW,MAAM,IAAI,WAAA,CAAY;AAAA,MAClD,OAAA,EAAS,6BAAA;AAAA,MACT,MAAM,WAAA,CAAY,mBAAA;AAAA,MAClB,SAAS,EAAE,QAAA,EAAU,SAAA,EAAW,MAAA,EAAQ,IAAI,MAAA;AAAO,KACpD,CAAA;AACD,IAAA,MAAM,GAAA,GAAM,KAAK,eAAA,EAAgB;AACjC,IAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,IAAA,EAAM,GAAA,EAAK,EAAE,CAAA;AAC/C,IAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AACvB,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,MAAA,CAAO,CAAC,QAAA,CAAS,MAAA,CAAO,EAAE,CAAA,EAAG,QAAA,CAAS,KAAA,EAAO,CAAC,CAAA;AAChE,IAAA,OAAO,EAAA,CAAG,SAAS,MAAM,CAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAA,GAAwD;AACtD,IAAA,MAAM,aAAa,IAAA,CAAK,WAAA;AACxB,IAAA,MAAM,MAAA,GAASA,YAAY,SAAS,CAAA;AACpC,IAAA,MAAM,aAAa,UAAA,GAAa,CAAA;AAGhC,IAAA,MAAM,UAAA,GAAa,MAAA,CAAO,KAAA,CAAM,uBAAuB,CAAA;AACvD,IAAA,cAAA,CAAe,IAAA,CAAK,YAAY,CAAC,CAAA;AACjC,IAAA,UAAA,CAAW,cAAA,CAAe,MAAM,CAAA,GAAI,UAAA;AACpC,IAAA,MAAA,CAAO,IAAA,CAAK,UAAA,EAAY,cAAA,CAAe,MAAA,GAAS,CAAC,CAAA;AAEjD,IAAG,GAAA,CAAA,SAAA,CAAeC,cAAQ,IAAA,CAAK,OAAO,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAC5D,IAAG,kBAAc,IAAA,CAAK,OAAA,EAAS,YAAY,EAAE,IAAA,EAAM,KAAO,CAAA;AAC1D,IAAA,uBAAA,CAAwB,KAAK,OAAO,CAAA;AAEpC,IAAA,IAAA,CAAK,GAAA,GAAM,MAAA;AACX,IAAA,IAAA,CAAK,WAAA,GAAc,UAAA;AACnB,IAAA,OAAO,EAAE,YAAY,UAAA,EAAW;AAAA,EAClC;AAAA,EAEQ,eAAA,GAA0B;AAQhC,IAAA,IAAI,IAAA,CAAK,GAAA,EAAK,OAAO,IAAA,CAAK,GAAA;AAC1B,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAS,GAAA,CAAA,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AAGxC,MAAA,IAAI,GAAA,CAAI,WAAW,SAAA,EAAW;AAE5B,QAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,QAAA,IAAA,CAAK,WAAA,GAAc,CAAA;AACnB,QAAA,uBAAA,CAAwB,KAAK,OAAO,CAAA;AACpC,QAAA,OAAO,IAAA,CAAK,GAAA;AAAA,MACd;AAEA,MAAA,IAAI,GAAA,CAAI,WAAW,uBAAA,EAAyB;AAE1C,QAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,QAAA,CAAS,CAAA,EAAG,eAAe,MAAM,CAAA;AACnD,QAAA,IAAI,CAAC,KAAA,CAAM,MAAA,CAAO,cAAc,CAAA,EAAG;AACjC,UAAA,MAAM,IAAI,WAAA,CAAY;AAAA,YACpB,OAAA,EAAS,CAAA,sBAAA,EAAyB,IAAA,CAAK,OAAO,CAAA,yBAAA,CAAA;AAAA,YAC9C,MAAM,WAAA,CAAY,cAAA;AAAA,YAClB,OAAA,EAAS,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA;AAAQ,WAClC,CAAA;AAAA,QACH;AACA,QAAA,MAAM,OAAA,GAAU,GAAA,CAAI,cAAA,CAAe,MAAM,CAAA;AACzC,QAAA,MAAMC,IAAAA,GAAM,GAAA,CAAI,QAAA,CAAS,cAAA,CAAe,SAAS,CAAC,CAAA;AAClD,QAAA,IAAIA,IAAAA,CAAI,WAAW,SAAA,EAAW;AAC5B,UAAA,MAAM,IAAI,WAAA,CAAY;AAAA,YACpB,OAAA,EAAS,yBAAyB,IAAA,CAAK,OAAO,wBAAwBA,IAAAA,CAAI,MAAM,oBAAoB,SAAS,CAAA,CAAA,CAAA;AAAA,YAC7G,MAAM,WAAA,CAAY,cAAA;AAAA,YAClB,OAAA,EAAS,EAAE,OAAA,EAAS,IAAA,CAAK,SAAS,aAAA,EAAe,SAAA,EAAW,WAAA,EAAaA,IAAAA,CAAI,MAAA;AAAO,WACrF,CAAA;AAAA,QACH;AACA,QAAA,IAAA,CAAK,GAAA,GAAM,MAAA,CAAO,IAAA,CAAKA,IAAG,CAAA;AAC1B,QAAA,IAAA,CAAK,WAAA,GAAc,OAAA;AACnB,QAAA,uBAAA,CAAwB,KAAK,OAAO,CAAA;AACpC,QAAA,OAAO,IAAA,CAAK,GAAA;AAAA,MACd;AAGA,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,OAAA,EACE,CAAA,sBAAA,EAAyB,IAAA,CAAK,OAAO,CAAA,IAAA,EAAO,IAAI,MAAM,CAAA,iBAAA,EACzC,SAAS,CAAA,WAAA,EAAc,uBAAuB,CAAA,oDAAA,CAAA;AAAA,QAE7D,MAAM,WAAA,CAAY,cAAA;AAAA,QAClB,OAAA,EAAS,EAAE,OAAA,EAAS,IAAA,CAAK,SAAS,aAAA,EAAe,SAAA,EAAW,WAAA,EAAa,GAAA,CAAI,MAAA;AAAO,OACrF,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,IAAK,GAAA,CAA8B,IAAA,KAAS,QAAA,EAAU,MAAM,GAAA;AAAA,IAC9D;AAGA,IAAG,GAAA,CAAA,SAAA,CAAeD,cAAQ,IAAA,CAAK,OAAO,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAC5D,IAAA,MAAM,GAAA,GAAMD,YAAY,SAAS,CAAA;AAGjC,IAAA,IAAI;AACF,MAAG,GAAA,CAAA,aAAA,CAAc,KAAK,OAAA,EAAS,GAAA,EAAK,EAAE,IAAA,EAAM,GAAA,EAAO,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,IACjE,SAAS,GAAA,EAAK;AACZ,MAAA,IAAK,GAAA,CAA8B,IAAA,KAAS,QAAA,EAAU,MAAM,GAAA;AAE5D,MAAA,MAAM,GAAA,GAAS,GAAA,CAAA,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AACxC,MAAA,IAAI,GAAA,CAAI,WAAW,SAAA,EAAW;AAE5B,QAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,QAAA,IAAA,CAAK,WAAA,GAAc,CAAA;AACnB,QAAA,uBAAA,CAAwB,KAAK,OAAO,CAAA;AACpC,QAAA,OAAO,IAAA,CAAK,GAAA;AAAA,MACd;AACA,MAAA,IAAI,GAAA,CAAI,WAAW,uBAAA,EAAyB;AAE1C,QAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,QAAA,CAAS,CAAA,EAAG,eAAe,MAAM,CAAA;AACnD,QAAA,IAAI,CAAC,KAAA,CAAM,MAAA,CAAO,cAAc,CAAA,EAAG;AACjC,UAAA,MAAM,IAAI,WAAA,CAAY;AAAA,YACpB,OAAA,EAAS,CAAA,sBAAA,EAAyB,IAAA,CAAK,OAAO,CAAA,yBAAA,CAAA;AAAA,YAC9C,MAAM,WAAA,CAAY,cAAA;AAAA,YAClB,OAAA,EAAS,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA;AAAQ,WAClC,CAAA;AAAA,QACH;AACA,QAAA,MAAM,OAAA,GAAU,GAAA,CAAI,cAAA,CAAe,MAAM,CAAA;AACzC,QAAA,MAAM,SAAA,GAAY,GAAA,CAAI,QAAA,CAAS,cAAA,CAAe,SAAS,CAAC,CAAA;AACxD,QAAA,IAAA,CAAK,GAAA,GAAM,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA;AAChC,QAAA,IAAA,CAAK,WAAA,GAAc,OAAA;AACnB,QAAA,uBAAA,CAAwB,KAAK,OAAO,CAAA;AACpC,QAAA,OAAO,IAAA,CAAK,GAAA;AAAA,MACd;AACA,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,OAAA,EACE,CAAA,sBAAA,EAAyB,IAAA,CAAK,OAAO,CAAA,IAAA,EAAO,IAAI,MAAM,CAAA,iBAAA,EACzC,SAAS,CAAA,WAAA,EAAc,uBAAuB,CAAA,oDAAA,CAAA;AAAA,QAE7D,MAAM,WAAA,CAAY,cAAA;AAAA,QAClB,OAAA,EAAS,EAAE,OAAA,EAAS,IAAA,CAAK,SAAS,aAAA,EAAe,SAAA,EAAW,WAAA,EAAa,GAAA,CAAI,MAAA;AAAO,OACrF,CAAA;AAAA,IACH;AACA,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,WAAA,GAAc,CAAA;AACnB,IAAA,OAAO,GAAA;AAAA,EACT;AACF;AAWO,SAAS,oBAAA,CACd,GAAA,EACA,KAAA,EACA,IAAA,EACG;AACH,EAAA,MAAM,OAAO,IAAA,EAAM,IAAA,KAAS,CAAC,GAAA,KAAgB,OAAA,CAAQ,KAAK,GAAG,CAAA,CAAA;AAI7D,EAAA,OAAO,IAAA,CAAK,GAAA,EAAK,KAAA,EAAO,CAAC,GAAG,GAAA,KAAQ;AAClC,IAAA,IAAI;AACF,MAAA,OAAO,KAAA,CAAM,QAAQ,CAAC,CAAA;AAAA,IACxB,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA;AAAA,QACE,qCAAqC,GAAG,CAAA,GAAA,EAAM,eAAe,KAAA,GAAQ,GAAA,CAAI,UAAU,GAAG,CAAA;AAAA,OACxF;AACA,MAAA,OAAO,EAAA;AAAA,IACT;AAAA,EACF,CAAC,CAAA;AACH;AAEO,SAAS,oBAAA,CACd,GAAA,EACA,KAAA,EACA,KAAA,EACG;AACH,EAAA,OAAO,IAAA,CAAK,KAAK,KAAA,EAAO,CAAC,MAAM,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAC,CAAA;AACjD;AAEA,SAAS,IAAA,CAAQ,IAAA,EAAS,KAAA,EAAoB,SAAA,EAAkD;AAC9F,EAAA,IAAI,IAAA,KAAS,IAAA,IAAQ,IAAA,KAAS,MAAA,EAAW,OAAO,IAAA;AAChD,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AACrC,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,IAAA,OAAO,IAAA,CAAK,IAAI,CAAC,IAAA,KAAS,KAAK,IAAA,EAAM,KAAA,EAAO,SAAS,CAAC,CAAA;AAAA,EACxD;AACA,EAAA,MAAM,GAAA,mBAA+B,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA;AACvD,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,IAA+B,CAAA,EAAG;AACpE,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,aAAA,CAAc,CAAC,CAAA,EAAG;AAC7C,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA;AAAA,IACzB,CAAA,MAAA,IAAW,OAAO,CAAA,KAAM,QAAA,IAAY,MAAM,IAAA,EAAM;AAC9C,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,IAAA,CAAK,CAAA,EAAG,OAAO,SAAS,CAAA;AAAA,IACnC,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IACX;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AASA,IAAM,kBAAA,GACJ,+JAAA;AAIF,IAAM,uCAAuB,IAAI,GAAA,CAAI,CAAC,WAAA,EAAa,YAAY,CAAC,CAAA;AAEzD,SAAS,cAAc,IAAA,EAAuB;AACnD,EAAA,MAAM,EAAA,GAAK,KAAK,WAAA,EAAY;AAC5B,EAAA,IAAI,oBAAA,CAAqB,GAAA,CAAI,EAAE,CAAA,EAAG,OAAO,KAAA;AACzC,EAAA,OAAO,kBAAA,CAAmB,KAAK,EAAE,CAAA;AACnC;AAMA,eAAsB,sBAAA,CACpB,UAAA,EACA,KAAA,EACA,KAAA,EACe;AACf,EAAA,IAAI,UAAmC,EAAC;AACxC,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAUG,EAAA,CAAA,QAAA,CAAS,UAAA,EAAY,MAAM,CAAA;AACjD,IAAA,OAAA,GAAU,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,MAAM,MAAA,GAAS,SAAA,CAAU,OAAA,EAAS,KAAA,IAAS,EAAE,CAAA;AAC7C,EAAA,MAAM,SAAA,GAAY,oBAAA,CAAqB,MAAA,EAAQ,KAAK,CAAA;AACpD,EAAA,MAAUA,SAAWF,KAAA,CAAA,OAAA,CAAQ,UAAU,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAE7D,EAAA,MAAM,WAAA,CAAY,UAAA,EAAY,IAAA,CAAK,SAAA,CAAU,SAAA,EAAW,IAAA,EAAM,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AACjF,EAAA,MAAM,wBAAwB,UAAU,CAAA;AAC1C;AAUA,eAAsB,uBAAA,CACpB,UAAA,EACA,KAAA,EACA,MAAA,EAC6C;AAC7C,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAUE,EAAA,CAAA,QAAA,CAAS,UAAA,EAAY,MAAM,CAAA;AAAA,EAC7C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,QAAA,EAAU,CAAA,EAAG,IAAA,EAAM,UAAA,EAAW;AAAA,EACzC;AACA,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,EACzB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,QAAA,EAAU,CAAA,EAAG,IAAA,EAAM,UAAA,EAAW;AAAA,EACzC;AACA,EAAA,MAAM,OAAA,GAAU,EAAE,CAAA,EAAG,CAAA,EAAE;AACvB,EAAA,MAAM,QAAA,GAAW,SAAA,CAAU,MAAA,EAAQ,KAAA,EAAO,OAAO,CAAA;AACjD,EAAA,IAAI,OAAA,CAAQ,MAAM,CAAA,EAAG,OAAO,EAAE,QAAA,EAAU,CAAA,EAAG,MAAM,UAAA,EAAW;AAE5D,EAAA,MAAM,WAAA,CAAY,UAAA,EAAY,IAAA,CAAK,SAAA,CAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AAChF,EAAA,MAAM,uBAAA;AAAA,IACJ,UAAA;AAAA,IACA,MAAA,GAAS,EAAE,IAAA,EAAM,CAAC,QAAQ,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,EAAE,GAAI;AAAA,GACjD;AACA,EAAA,OAAO,EAAE,QAAA,EAAU,OAAA,CAAQ,CAAA,EAAG,MAAM,UAAA,EAAW;AACjD;AAgBA,eAAsB,gBAAA,CACpB,UAAA,EACA,KAAA,EACA,MAAA,EACoF;AACpF,EAAA,MAAM,GAAA,GAAM,MAAA,EAAQ,IAAA,KAAS,MAAM;AAAA,EAAC,CAAA,CAAA;AACpC,EAAA,MAAM,OAAO,MAAA,EAAQ,IAAA,KAAS,CAAC,GAAA,KAAgB,OAAA,CAAQ,KAAK,GAAG,CAAA,CAAA;AAG/D,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAUA,EAAA,CAAA,QAAA,CAAS,UAAA,EAAY,MAAM,CAAA;AAAA,EAC7C,CAAA,CAAA,MAAQ;AAEN,IAAA,MAAM,EAAE,UAAA,EAAAC,WAAAA,EAAY,YAAAC,WAAAA,EAAW,GAAI,MAAM,SAAA,EAAU;AACnD,IAAA,GAAA,CAAI,CAAA,6BAAA,EAAgCD,WAAU,CAAA,SAAA,EAAOC,WAAU,CAAA,qCAAA,CAAkC,CAAA;AACjG,IAAA,OAAO,EAAE,SAAS,CAAA,EAAG,UAAA,EAAAD,aAAY,UAAA,EAAAC,WAAAA,EAAY,MAAM,UAAA,EAAW;AAAA,EAChE;AAEA,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,EACzB,CAAA,CAAA,MAAQ;AACN,IAAA,IAAA,CAAK,CAAA,2BAAA,EAA8B,UAAU,CAAA,2CAAA,CAAwC,CAAA;AACrF,IAAA,OAAO,EAAE,OAAA,EAAS,CAAA,EAAG,UAAA,EAAY,KAAA,CAAM,YAAY,UAAA,EAAY,KAAA,CAAM,UAAA,EAAY,IAAA,EAAM,UAAA,EAAW;AAAA,EACpG;AAGA,EAAA,MAAM,UAAU,EAAE,CAAA,EAAG,CAAA,EAAG,MAAA,EAAQ,EAAC,EAAc;AAC/C,EAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,MAAA,EAAQ,KAAA,EAAO,OAAO,CAAA;AAOzD,EAAA,IAAI,OAAA,CAAQ,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG;AAC7B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,sCAAA,EAAyC,QAAQ,MAAA,CAAO,MAAM,oGACO,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,iDAAA;AAAA,KAEhG;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,MAAM,CAAA,EAAG;AAEnB,IAAA,MAAM,EAAE,UAAA,EAAAD,WAAAA,EAAY,YAAAC,WAAAA,EAAW,GAAI,MAAM,SAAA,EAAU;AACnD,IAAA,GAAA,CAAI,CAAA,6BAAA,EAAgCD,WAAU,CAAA,SAAA,EAAOC,WAAU,CAAA,0CAAA,CAAuC,CAAA;AACtG,IAAA,OAAO,EAAE,SAAS,CAAA,EAAG,UAAA,EAAAD,aAAY,UAAA,EAAAC,WAAAA,EAAY,MAAM,UAAA,EAAW;AAAA,EAChE;AAGA,EAAA,MAAM,EAAE,UAAA,EAAY,UAAA,EAAW,GAAI,MAAM,SAAA,EAAU;AAGnD,EAAA,MAAM,WAAA,GAAc,aAAA,CAAc,SAAA,EAAW,KAAK,CAAA;AAGlD,EAAA,MAAM,WAAA,CAAY,UAAA,EAAY,IAAA,CAAK,SAAA,CAAU,WAAA,EAAa,IAAA,EAAM,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AACnF,EAAA,MAAM,uBAAA,CAAwB,UAAA,EAAY,EAAE,IAAA,EAAM,CAAA;AAElD,EAAA,GAAA,CAAI,gCAAgC,UAAU,CAAA,SAAA,EAAO,UAAU,CAAA,sBAAA,EAAoB,OAAA,CAAQ,CAAC,CAAA,SAAA,CAAW,CAAA;AACvG,EAAA,OAAO,EAAE,OAAA,EAAS,OAAA,CAAQ,GAAG,UAAA,EAAY,UAAA,EAAY,MAAM,UAAA,EAAW;AACxE;AAaA,SAAS,gBAAA,CACP,IAAA,EACA,KAAA,EACA,OAAA,EACA,aAAa,EAAA,EACV;AACH,EAAA,IAAI,IAAA,KAAS,IAAA,IAAQ,IAAA,KAAS,MAAA,EAAW,OAAO,IAAA;AAChD,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AACrC,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,MAAI,CAAC,IAAA,EAAM,CAAA,KACrB,gBAAA,CAAiB,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,CAAG;AAAA,KAC9D;AAAA,EACF;AACA,EAAA,MAAM,GAAA,mBAA+B,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA;AACvD,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,IAA+B,CAAA,EAAG;AACpE,IAAA,MAAM,UAAU,UAAA,GAAa,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,GAAK,CAAA;AACpD,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,KAAA,CAAM,WAAA,CAAY,CAAC,CAAA,EAAG;AACjD,MAAA,IAAI;AACF,QAAA,GAAA,CAAI,CAAC,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AACxB,QAAA,OAAA,CAAQ,CAAA,EAAA;AAAA,MACV,CAAA,CAAA,MAAQ;AAIN,QAAA,OAAA,CAAQ,MAAA,CAAO,KAAK,OAAO,CAAA;AAC3B,QAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,MACX;AAAA,IACF,CAAA,MAAA,IAAW,OAAO,CAAA,KAAM,QAAA,IAAY,MAAM,IAAA,EAAM;AAC9C,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,gBAAA,CAAiB,CAAA,EAAG,KAAA,EAAO,SAAS,OAAO,CAAA;AAAA,IACtD,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IACX;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AASA,SAAS,aAAA,CAAiB,MAAS,KAAA,EAAuB;AACxD,EAAA,IAAI,IAAA,KAAS,IAAA,IAAQ,IAAA,KAAS,MAAA,EAAW,OAAO,IAAA;AAChD,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AACrC,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,IAAA,OAAO,KAAK,GAAA,CAAI,CAAC,SAAS,aAAA,CAAc,IAAA,EAAM,KAAK,CAAC,CAAA;AAAA,EACtD;AACA,EAAA,MAAM,GAAA,mBAA+B,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA;AACvD,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,IAA+B,CAAA,EAAG;AACpE,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,aAAA,CAAc,CAAC,CAAA,IAAK,CAAA,CAAE,MAAA,GAAS,CAAA,IAAK,CAAC,KAAA,CAAM,WAAA,CAAY,CAAC,CAAA,EAAG;AAEtF,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC1B,CAAA,MAAA,IAAW,OAAO,CAAA,KAAM,QAAA,IAAY,MAAM,IAAA,EAAM;AAC9C,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,aAAA,CAAc,CAAA,EAAG,KAAK,CAAA;AAAA,IACjC,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IACX;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAQA,eAAe,uBAAA,CACb,UACA,IAAA,EACe;AACf,EAAA,MAAM,OAAO,IAAA,EAAM,IAAA,KAAS,CAAC,GAAA,KAAgB,OAAA,CAAQ,KAAK,GAAG,CAAA,CAAA;AAC7D,EAAA,IAAI,OAAA,CAAQ,aAAa,OAAA,EAAS;AAChC,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM,OAAO,eAAoB,CAAA;AACtD,MAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,OAAO,MAAW,CAAA;AAC9C,MAAA,MAAM,aAAA,GAAgB,UAAU,QAAQ,CAAA;AACxC,MAAA,MAAM,OAAO,kBAAA,EAAmB;AAChC,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,IAAA;AAAA,UACE,mEAAmE,QAAQ,CAAA,4BAAA;AAAA,SAC7E;AACA,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,aAAA,CAAc,UAAU,CAAC,QAAA,EAAU,kBAAkB,UAAA,EAAY,CAAA,EAAG,IAAI,CAAA,IAAA,CAAM,CAAC,CAAA;AAAA,IACvF,CAAA,CAAA,MAAQ;AAEN,MAAA,IAAA;AAAA,QACE,oDAAoD,QAAQ,CAAA,kEAAA;AAAA,OAC9D;AAAA,IACF;AAAA,EACF,CAAA,MAAO;AACL,IAAA,IAAI;AACF,MAAA,MAAUF,EAAA,CAAA,KAAA,CAAM,UAAU,GAAK,CAAA;AAAA,IACjC,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEA,SAAS,kBAAA,GAAyC;AAChD,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,GAAA,CAAI,QAAA,IAAY,QAAQ,GAAA,CAAI,IAAA;AACrD,EAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,QAAA,CAAS,IAAI,GAAG,OAAO,MAAA;AACjD,EAAA,MAAM,MAAA,GAAS,QAAQ,GAAA,CAAI,UAAA;AAC3B,EAAA,IAAI,MAAA,IAAU,CAAC,MAAA,CAAO,QAAA,CAAS,IAAI,GAAG,OAAO,CAAA,EAAG,MAAM,CAAA,EAAA,EAAK,QAAQ,CAAA,CAAA;AACnE,EAAA,OAAO,QAAA;AACT;AAEA,SAAS,SAAA,CAAa,IAAA,EAAS,KAAA,EAAoB,OAAA,EAA2B;AAC5E,EAAA,IAAI,IAAA,KAAS,IAAA,IAAQ,IAAA,KAAS,MAAA,EAAW,OAAO,IAAA;AAChD,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AACrC,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,IAAA,OAAO,IAAA,CAAK,IAAI,CAAC,IAAA,KAAS,UAAU,IAAA,EAAM,KAAA,EAAO,OAAO,CAAC,CAAA;AAAA,EAC3D;AACA,EAAA,MAAM,GAAA,mBAA+B,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA;AACvD,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,IAA+B,CAAA,EAAG;AACpE,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,aAAA,CAAc,CAAC,CAAA,IAAK,CAAC,KAAA,CAAM,WAAA,CAAY,CAAC,CAAA,IAAK,CAAA,CAAE,SAAS,CAAA,EAAG;AACtF,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AACxB,MAAA,OAAA,CAAQ,CAAA,EAAA;AAAA,IACV,CAAA,MAAA,IAAW,OAAO,CAAA,KAAM,QAAA,IAAY,MAAM,IAAA,EAAM;AAC9C,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,SAAA,CAAU,CAAA,EAAG,OAAO,OAAO,CAAA;AAAA,IACtC,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IACX;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;;;AC/mBO,IAAM,gBAAA,GAAmB;AAAA;AAAA,EAE9B,eAAA,EAAiB,iBAAA;AAAA;AAAA,EAGjB,gBAAA,EAAkB,kBAAA;AAAA;AAAA,EAGlB,OAAA,EAAS,SAAA;AAAA;AAAA,EAGT,QAAA,EAAU,UAAA;AAAA;AAAA,EAGV,wBAAA,EAA0B,0BAAA;AAAA;AAAA,EAG1B,YAAA,EAAc,cAAA;AAAA;AAAA,EAGd,SAAA,EAAW,WAAA;AAAA;AAAA,EAGX,cAAA,EAAgB,gBAAA;AAAA;AAAA,EAGhB,aAAA,EAAe,eAAA;AAAA;AAAA,EAGf,eAAA,EAAiB;AACnB;AASO,IAAM,uBAAA,GAAqD;AAAA,EAChE,gBAAA,CAAiB,eAAA;AAAA,EACjB,gBAAA,CAAiB,gBAAA;AAAA,EACjB,gBAAA,CAAiB,QAAA;AAAA,EACjB,gBAAA,CAAiB,wBAAA;AAAA,EACjB,gBAAA,CAAiB,SAAA;AAAA,EACjB,gBAAA,CAAiB,cAAA;AAAA,EACjB,gBAAA,CAAiB,aAAA;AAAA,EACjB,gBAAA,CAAiB;AACnB;AAkBqE;AAAA,EACnE,gBAAA,CAAiB,OAAA;AAAA,EACjB,gBAAA,CAAiB,QAAA;AAAA,EACjB,gBAAA,CAAiB,YAAA;AAAA,EACjB,gBAAA,CAAiB,eAAA;AAAA,EACjB,gBAAA,CAAiB,gBAAA;AAAA,EACjB,gBAAA,CAAiB;AACnB;AAMO,SAAS,mCACd,UAAA,EACS;AACT,EAAA,IAAI,CAAC,YAAY,OAAO,KAAA;AACxB,EAAA,MAAM,KAAA,GAAQ,UAAA;AACd,EAAA,MAAM,IAAA,GAA0B,MAAM,OAAA,CAAQ,UAAU,IAAI,UAAA,GAAc,KAAA,CAAM,gBAAgB,EAAC;AACjG,EAAA,OAAO,KAAK,IAAA,CAAK,CAAC,MAAM,uBAAA,CAAwB,QAAA,CAAS,CAAmB,CAAC,CAAA;AAC/E;AAKO,SAAS,aAAA,CACd,YACA,UAAA,EACS;AACT,EAAA,IAAI,CAAC,YAAY,OAAO,KAAA;AACxB,EAAA,MAAM,KAAA,GAAQ,UAAA;AACd,EAAA,MAAM,IAAA,GAA0B,MAAM,OAAA,CAAQ,UAAU,IAAI,UAAA,GAAc,KAAA,CAAM,gBAAgB,EAAC;AACjG,EAAA,MAAM,UAAU,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA,GAAI,UAAA,GAAa,CAAC,UAAU,CAAA;AACpE,EAAA,OAAO,QAAQ,IAAA,CAAK,CAAC,MAAM,IAAA,CAAK,QAAA,CAAS,CAAC,CAAC,CAAA;AAC7C;AAMO,SAAS,yBACd,UAAA,EACkB;AAClB,EAAA,IAAI,CAAC,UAAA,EAAY,OAAO,EAAC;AACzB,EAAA,MAAM,KAAA,GAAQ,UAAA;AACd,EAAA,MAAM,IAAA,GAA0B,MAAM,OAAA,CAAQ,UAAU,IAAI,UAAA,GAAc,KAAA,CAAM,gBAAgB,EAAC;AACjG,EAAA,OAAO,IAAA,CAAK,MAAA;AAAA,IAAO,CAAC,CAAA,KAClB,uBAAA,CAAwB,QAAA,CAAS,CAAmB;AAAA,GACtD;AACF;ACpHA,IAAM,yBAAA,GAAsC;AAAA,EAC1C,oDAAA;AAAA,EACA,oDAAA;AAAA,EACA,oBAAA;AAAA,EACA,+CAAA;AAAA,EACA,uBAAA;AAAA,EACA,iBAAA;AAAA,EACA,4DAAA;AAAA,EACA,sDAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,sBAAA,GAAyB,6BAAA;AAC/B,IAAM,qBAAA,GAAwB,wDAAA;AAC9B,IAAM,eAAA,mBAAkB,IAAI,GAAA,CAAI,CAAC,IAAA,EAAM,IAAA,EAAM,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,KAAK,CAAC,CAAA;AAE5E,SAAS,cAAA,CAAe,OAAgB,GAAA,EAAiC;AAC9E,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,MAAA;AAChD,EAAA,MAAM,KAAA,GAAS,MAAkC,GAAG,CAAA;AACpD,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,MAAA;AAC7C;AAEO,SAAS,sBAAA,CAAuB,SAAiB,WAAA,EAA0C;AAChG,EAAA,IAAI,CAAC,aAAa,OAAO,KAAA;AAIzB,EAAA,IAAI,OAAA,KAAY,GAAA,IAAO,OAAA,CAAQ,UAAA,CAAW,IAAI,KAAK,OAAA,CAAQ,UAAA,CAAW,KAAK,CAAA,EAAG,OAAO,KAAA;AACrF,EAAA,MAAM,QAAA,GAAgB,KAAA,CAAA,OAAA,CAAQ,WAAA,EAAa,OAAO,CAAA;AAClD,EAAA,MAAMG,SAAAA,GAAgB,KAAA,CAAA,QAAA,CAAS,WAAA,EAAa,QAAQ,CAAA;AACpD,EAAA,OAAO,CAAC,CAACA,SAAAA,IAAY,CAACA,SAAAA,CAAS,WAAW,IAAI,CAAA,IAAK,CAAM,KAAA,CAAA,UAAA,CAAWA,SAAQ,CAAA;AAC9E;AAEA,SAAS,cAAc,OAAA,EAA2B;AAChD,EAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,sBAAsB,CAAA,EAAG,GAAA,CAAI,CAAC,KAAA,KAAU,KAAA,CAAM,OAAA,CAAQ,cAAA,EAAgB,EAAE,CAAC,KAAK,EAAC;AACtG;AAEA,SAAS,yBAAA,CAA0B,OAAe,WAAA,EAA0C;AAC1F,EAAA,IAAI,CAAC,KAAA,IAAS,eAAA,CAAgB,GAAA,CAAI,KAAK,KAAK,KAAA,CAAM,UAAA,CAAW,GAAG,CAAA,EAAG,OAAO,KAAA;AAC1E,EAAA,IAAI,KAAA,KAAU,OAAO,KAAA,KAAU,GAAA,IAAO,UAAU,GAAA,IAAO,KAAA,KAAU,IAAA,EAAM,OAAO,KAAA,KAAU,GAAA;AACxF,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,GAAG,CAAA,EAAG,OAAO,IAAA;AAChC,EAAA,IAAI,KAAA,CAAM,UAAA,CAAW,IAAI,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,EAAG,OAAO,IAAA;AACtF,EAAA,IAAS,KAAA,CAAA,UAAA,CAAW,KAAK,CAAA,IAAK,KAAA,CAAM,UAAA,CAAW,IAAI,CAAA,EAAG,OAAO,CAAC,sBAAA,CAAuB,KAAA,EAAO,WAAW,CAAA;AACvG,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,wBAAA,CACP,MAAA,EACA,KAAA,EACA,WAAA,EACS;AACT,EAAA,MAAM,UAAU,MAAA,CACb,KAAA,CAAM,KAAK,CAAA,CACX,OAAO,CAAC,KAAA,KAAU,CAAC,KAAA,CAAM,WAAW,GAAG,CAAA,IAAK,CAAC,eAAA,CAAgB,GAAA,CAAI,KAAK,CAAC,CAAA;AAC1E,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AACjC,EAAA,OAAO,QAAQ,IAAA,CAAK,CAAC,WAAW,yBAAA,CAA0B,MAAA,EAAQ,WAAW,CAAC,CAAA;AAChF;AAEA,SAAS,oBAAA,CAAqB,SAAiB,WAAA,EAA0C;AACvF,EAAA,MAAM,MAAA,GAAS,cAAc,OAAO,CAAA;AACpC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACtC,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,CAAC,CAAA,EAAG,WAAA,EAAY;AACrC,IAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,IAAA,IAAI,UAAU,IAAA,EAAM;AAClB,MAAA,MAAM,IAAA,GAAO,MAAA,CAAO,KAAA,CAAM,CAAA,GAAI,CAAC,CAAA;AAC/B,MAAA,MAAM,mBAAmB,IAAA,CAAK,IAAA;AAAA,QAC5B,CAAC,QAAQ,cAAA,CAAe,IAAA,CAAK,GAAG,CAAA,IAAK,GAAA,KAAQ,iBAAiB,GAAA,KAAQ;AAAA,OACxE;AACA,MAAA,IAAI,oBAAoB,wBAAA,CAAyB,MAAA,EAAQ,IAAI,CAAA,EAAG,WAAW,GAAG,OAAO,IAAA;AAAA,IACvF;AAEA,IAAA,IAAI,KAAA,KAAU,OAAA,IAAW,KAAA,KAAU,IAAA,EAAM;AACvC,MAAA,MAAM,IAAA,GAAO,MAAA,CAAO,KAAA,CAAM,CAAA,GAAI,CAAC,CAAA;AAC/B,MAAA,MAAM,SAAA,GAAY,KAAK,IAAA,CAAK,CAAC,QAAQ,GAAA,CAAI,WAAA,OAAkB,IAAI,CAAA;AAC/D,MAAA,IAAI,aAAa,wBAAA,CAAyB,MAAA,EAAQ,IAAI,CAAA,EAAG,WAAW,GAAG,OAAO,IAAA;AAAA,IAChF;AAEA,IAAA,IAAI,KAAA,KAAU,KAAA,IAAS,KAAA,KAAU,OAAA,EAAS;AACxC,MAAA,IAAI,yBAAyB,MAAA,EAAQ,CAAA,GAAI,CAAA,EAAG,WAAW,GAAG,OAAO,IAAA;AAAA,IACnE;AAEA,IAAA,IAAI,UAAU,aAAA,EAAe;AAC3B,MAAA,MAAM,IAAA,GAAO,MAAA,CAAO,KAAA,CAAM,CAAA,GAAI,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,GAAA,KAAQ,GAAA,CAAI,WAAA,EAAa,CAAA;AAC/D,MAAA,MAAM,mBAAmB,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA,IAAK,IAAA,CAAK,SAAS,QAAQ,CAAA;AAC5E,MAAA,IAAI,oBAAoB,wBAAA,CAAyB,MAAA,EAAQ,IAAI,CAAA,EAAG,WAAW,GAAG,OAAO,IAAA;AAAA,IACvF;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,+BAAA,CACd,SACA,WAAA,EACS;AACT,EAAA,MAAM,OAAA,GAAU,QAAQ,IAAA,EAAK;AAC7B,EAAA,IAAI,CAAC,SAAS,OAAO,KAAA;AACrB,EAAA,IAAI,oBAAA,CAAqB,OAAA,EAAS,WAAW,CAAA,EAAG,OAAO,IAAA;AACvD,EAAA,IAAI,yBAAA,CAA0B,KAAK,CAAC,OAAA,KAAY,QAAQ,IAAA,CAAK,OAAO,CAAC,CAAA,EAAG,OAAO,IAAA;AAI/E,EAAA,IAAI,sCAAA,CAAuC,IAAA,CAAK,OAAO,CAAA,EAAG,OAAO,IAAA;AACjE,EAAA,IAAI,sBAAA,CAAuB,IAAA,CAAK,OAAO,CAAA,EAAG,OAAO,IAAA;AAEjD,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,qBAAqB,CAAA,GAAI,CAAC,CAAA,EAAG,IAAA,EAAK,CAAE,OAAA,CAAQ,cAAA,EAAgB,EAAE,CAAA;AAC7F,EAAA,IAAI,YAAY,CAAC,sBAAA,CAAuB,QAAA,EAAU,WAAW,GAAG,OAAO,IAAA;AAEvE,EAAA,OAAO,KAAA;AACT;;;AC7EO,IAAM,0BAAN,MAA0D;AAAA,EACvD,SAAsB,EAAC;AAAA,EACvB,MAAA,GAAS,KAAA;AAAA,EACA,SAAA;AAAA,EACT,IAAA;AAAA,EACA,eAAA;AAAA;AAAA,EAEA,kBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAA,uBAAoB,GAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQzC,cAAA,uBAAqB,GAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW1C,cAAA;AAAA;AAAA,EAEA,kBAAqE,EAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAetE,UAAA,uBAAiB,GAAA,EAAgC;AAAA,EAEzD,YAAY,IAAA,EAA+B;AACzC,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,KAAK,IAAA,IAAQ,KAAA;AACzB,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAA,CAAK,eAAA,IAAmB,IAAA,CAAK,YAAA,IAAgB,KAAA;AACpE,IAAA,IAAA,CAAK,kBAAA,GAAqB,KAAK,kBAAA,IAAsB,KAAA;AACrD,IAAA,IAAA,CAAK,iBAAiB,IAAA,CAAK,cAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,kBAAkB,QAAA,EAA2D;AAC3E,IAAA,IAAA,CAAK,cAAA,GAAiB,QAAA;AAAA,EACxB;AAAA;AAAA,EAGA,QAAQ,OAAA,EAAwB;AAC9B,IAAA,IAAI,IAAA,CAAK,IAAA,KAAS,OAAA,EAAS,IAAA,CAAK,WAAW,KAAA,EAAM;AACjD,IAAA,IAAA,CAAK,IAAA,GAAO,OAAA;AAAA,EACd;AAAA;AAAA,EAGA,OAAA,GAAmB;AACjB,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,EACd;AAAA;AAAA,EAGA,mBAAmB,OAAA,EAAwB;AACzC,IAAA,IAAI,IAAA,CAAK,eAAA,KAAoB,OAAA,EAAS,IAAA,CAAK,WAAW,KAAA,EAAM;AAC5D,IAAA,IAAA,CAAK,eAAA,GAAkB,OAAA;AAAA,EACzB;AAAA;AAAA,EAGA,kBAAA,GAA8B;AAC5B,IAAA,OAAO,IAAA,CAAK,eAAA;AAAA,EACd;AAAA;AAAA,EAGA,sBAAsB,OAAA,EAAwB;AAC5C,IAAA,IAAI,IAAA,CAAK,kBAAA,KAAuB,OAAA,EAAS,IAAA,CAAK,WAAW,KAAA,EAAM;AAC/D,IAAA,IAAA,CAAK,kBAAA,GAAqB,OAAA;AAAA,EAC5B;AAAA;AAAA,EAGA,qBAAA,GAAiC;AAC/B,IAAA,OAAO,IAAA,CAAK,kBAAA;AAAA,EACd;AAAA,EAEA,MAAM,MAAA,GAAwB;AAC5B,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAASC,EAAA,CAAA,QAAA,CAAS,IAAA,CAAK,WAAW,MAAM,CAAA;AACpD,MAAA,MAAM,MAAA,GAAS,UAAuB,GAAG,CAAA;AACzC,MAAA,IAAI,OAAO,EAAA,IAAM,MAAA,CAAO,KAAA,EAAO,IAAA,CAAK,SAAS,MAAA,CAAO,KAAA;AAAA,IACtD,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,CAAK,SAAS,EAAC;AAAA,IACjB;AAEA,IAAA,IAAA,CAAK,kBAAkB,EAAC;AACxB,IAAA,KAAA,MAAW,CAAC,KAAK,GAAG,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,EAAG;AACpD,MAAA,IAAI,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,EAAG,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,EAAE,OAAA,EAAS,GAAA,EAAK,KAAA,EAAO,GAAA,EAAK,CAAA;AAAA,IAC/E;AAEA,IAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AACzB,IAAA,IAAA,CAAK,eAAe,KAAA,EAAM;AAC1B,IAAA,IAAA,CAAK,WAAW,KAAA,EAAM;AACtB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAAA,EAChB;AAAA,EAEA,MAAM,QAAA,CAAS,IAAA,EAAY,KAAA,EAAgB,GAAA,EAA2C;AACpF,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,MAAM,KAAK,MAAA,EAAO;AAGpC,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAA;AAGxD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,IAAK,cAAA;AAGxC,IAAA,MAAM,UAAU,mBAAA,CAAoB,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,KAAK,UAAU,CAAA;AACrE,IAAA,MAAM,WAAW,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,OAAA,IAAW,KAAK,IAAI,CAAA,CAAA;AAMtD,IAAA,IAAI,IAAA,CAAK,SAAS,OAAA,EAAS;AACzB,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAQ,CAAA;AAC3C,MAAA,IAAI,MAAA,KAAW,QAAW,OAAO,MAAA;AAAA,IACnC;AAKA,IAAA,IAAI,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,QAAQ,CAAA,EAAG;AACpC,MAAA,MAAM,WAA+B,EAAE,UAAA,EAAY,QAAQ,MAAA,EAAQ,MAAA,EAAQ,QAAQ,qCAAA,EAAsC;AACzH,MAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAA;AACtC,MAAA,OAAO,QAAA;AAAA,IACT;AAIA,IAAA,IAAI,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,QAAQ,CAAA,EAAG;AACrC,MAAA,MAAM,QAAA,GAA+B;AAAA,QACnC,UAAA,EAAY,MAAA;AAAA,QACZ,MAAA,EAAQ,OAAA;AAAA,QACR,MAAA,EAAQ;AAAA,OACV;AACA,MAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAA;AACtC,MAAA,OAAO,QAAA;AAAA,IACT;AAGA,IAAA,IAAI,OAAO,IAAA,IAAQ,OAAA,IAAW,SAAS,KAAA,CAAM,IAAA,EAAM,OAAO,CAAA,EAAG;AAC3D,MAAA,MAAM,WAA+B,EAAE,UAAA,EAAY,QAAQ,MAAA,EAAQ,MAAA,EAAQ,QAAQ,sBAAA,EAAuB;AAC1G,MAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAA;AACtC,MAAA,OAAO,QAAA;AAAA,IACT;AACA,IAAA,IAAI,IAAA,CAAK,eAAe,MAAA,EAAQ;AAC9B,MAAA,MAAM,WAA+B,EAAE,UAAA,EAAY,QAAQ,MAAA,EAAQ,SAAA,EAAW,QAAQ,mBAAA,EAAoB;AAC1G,MAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAA;AACtC,MAAA,OAAO,QAAA;AAAA,IACT;AAGA,IAAA,IAAI,OAAO,KAAA,IAAS,OAAA,IAAW,SAAS,KAAA,CAAM,KAAA,EAAO,OAAO,CAAA,EAAG;AAC7D,MAAA,MAAM,WAA+B,EAAE,UAAA,EAAY,QAAQ,MAAA,EAAQ,OAAA,EAAS,QAAQ,uBAAA,EAAwB;AAC5G,MAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAA;AACtC,MAAA,OAAO,QAAA;AAAA,IACT;AACA,IAAA,IAAI,OAAO,IAAA,EAAM;AACf,MAAA,MAAM,QAAA,GAA+B,EAAE,UAAA,EAAY,MAAA,EAAQ,QAAQ,OAAA,EAAQ;AAC3E,MAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAA;AACtC,MAAA,OAAO,QAAA;AAAA,IACT;AAIA,IAAA,IAAI,KAAK,IAAA,EAAM;AACb,MAAA,IAAI,KAAK,kBAAA,EAAoB;AAC3B,QAAA,MAAM,WAAA,GAAc,IAAA,CAAK,qBAAA,CAAsB,IAAA,EAAM,OAAO,GAAG,CAAA;AAC/D,QAAA,IAAI,WAAA,EAAa;AACf,UAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,YAAA,MAAMC,SAAAA,GAAW,MAAM,IAAA,CAAK,cAAA,CAAe,MAAM,KAAA,EAAO,OAAA,IAAW,KAAK,IAAI,CAAA;AAC5E,YAAA,IAAIA,cAAa,QAAA,EAAU;AACzB,cAAA,MAAM,IAAA,CAAK,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,CAAK,MAAM,OAAA,EAAS,OAAA,IAAW,IAAA,CAAK,IAAA,EAAM,CAAA;AACnE,cAAA,OAAO,EAAE,UAAA,EAAY,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,QAAQ,iCAAA,EAAkC;AAAA,YACzF;AACA,YAAA,IAAIA,cAAa,MAAA,EAAQ;AACvB,cAAA,MAAM,IAAA,CAAK,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,CAAK,MAAM,OAAA,EAAS,OAAA,IAAW,IAAA,CAAK,IAAA,EAAM,CAAA;AAClE,cAAA,OAAO,EAAE,UAAA,EAAY,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,QAAQ,8BAAA,EAA+B;AAAA,YACtF;AACA,YAAA,OAAO,EAAE,UAAA,EAAYA,SAAAA,KAAa,QAAQ,MAAA,GAAS,MAAA,EAAQ,QAAQ,MAAA,EAAO;AAAA,UAC5E;AACA,UAAA,OAAO;AAAA,YACL,UAAA,EAAY,SAAA;AAAA,YACZ,MAAA,EAAQ,kBAAA;AAAA,YACR,QAAA,EAAU,aAAA;AAAA,YACV,MAAA,EAAQ;AAAA,WACV;AAAA,QACF;AAAA,MACF;AACA,MAAA,MAAM,QAAA,GAA+B,EAAE,UAAA,EAAY,MAAA,EAAQ,QAAQ,MAAA,EAAO;AAC1E,MAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAA;AACtC,MAAA,OAAO,QAAA;AAAA,IACT;AAKA,IAAA,IAAI,IAAA,CAAK,IAAA,KAAS,OAAA,IAAW,OAAA,EAAS;AACpC,MAAA,IAAI,GAAA,CAAI,OAAA,CAAQ,OAAO,CAAA,EAAG;AACxB,QAAA,OAAO;AAAA,UACL,UAAA,EAAY,MAAA;AAAA,UACZ,MAAA,EAAQ,SAAA;AAAA,UACR,MAAA,EAAQ;AAAA,SACV;AAAA,MACF;AAAA,IACF;AAUA,IAAA,MAAM,WAAA,GAAc,aAAA,CAAc,IAAA,EAAM,gBAAA,CAAiB,QAAQ,CAAA;AACjE,IAAA,MAAM,WAAA,GAAc,cAAc,IAAA,EAAM;AAAA,MACtC,gBAAA,CAAiB,eAAA;AAAA,MACjB,gBAAA,CAAiB;AAAA,KAClB,CAAA;AACD,IAAA,MAAM,aAAA,GAAgB,aAAA,CAAc,IAAA,EAAM,gBAAA,CAAiB,eAAe,CAAA;AAC1E,IAAA,MAAM,YAAA,GAAe,aAAA,CAAc,IAAA,EAAM,gBAAA,CAAiB,aAAa,CAAA;AACvE,IAAA,MAAM,cAAA,GAAiB,aAAA,CAAc,IAAA,EAAM,gBAAA,CAAiB,cAAc,CAAA;AAC1E,IAAA,MAAM,aAAa,IAAA,CAAK,QAAA,IAAY,WAAA,IAAe,WAAA,IAAe,iBAAiB,YAAA,IAAgB,cAAA;AACnG,IAAA,IAAI,IAAA,CAAK,UAAA,KAAe,MAAA,IAAU,CAAC,UAAA,EAAY;AAC7C,MAAA,MAAM,QAAA,GAA+B,EAAE,UAAA,EAAY,MAAA,EAAQ,QAAQ,SAAA,EAAU;AAC7E,MAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAA;AACtC,MAAA,OAAO,QAAA;AAAA,IACT;AAGA,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,cAAA,CAAe,MAAM,KAAA,EAAO,OAAA,IAAW,KAAK,IAAI,CAAA;AAC5E,MAAA,IAAI,aAAa,QAAA,EAAU;AACzB,QAAA,MAAM,IAAA,CAAK,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,CAAK,MAAM,OAAA,EAAS,OAAA,IAAW,IAAA,CAAK,IAAA,EAAM,CAAA;AACnE,QAAA,OAAO,EAAE,UAAA,EAAY,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,QAAQ,qBAAA,EAAsB;AAAA,MAC7E;AACA,MAAA,IAAI,aAAa,MAAA,EAAQ;AACvB,QAAA,MAAM,IAAA,CAAK,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,CAAK,MAAM,OAAA,EAAS,OAAA,IAAW,IAAA,CAAK,IAAA,EAAM,CAAA;AAClE,QAAA,OAAO,EAAE,UAAA,EAAY,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,QAAQ,aAAA,EAAc;AAAA,MACrE;AACA,MAAA,OAAO,EAAE,UAAA,EAAY,QAAA,KAAa,QAAQ,MAAA,GAAS,MAAA,EAAQ,QAAQ,MAAA,EAAO;AAAA,IAC5E;AACA,IAAA,OAAO,EAAE,UAAA,EAAY,SAAA,EAAW,MAAA,EAAQ,SAAA,EAAU;AAAA,EACpD;AAAA;AAAA,EAGQ,0BAA0B,IAAA,EAAqB;AACrD,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,YAAA,IAAgB,EAAC;AACnC,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,iBAAiB,CAAA,EAAG,OAAO,IAAA;AAC7C,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA,EAAG,OAAO,IAAA;AACtC,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,0BAA0B,CAAA,EAAG,OAAO,IAAA;AACtD,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,qBAAA,CAAsB,IAAA,EAAY,KAAA,EAAgB,GAAA,EAAuB;AAE/E,IAAA,IAAI,IAAA,CAAK,yBAAA,CAA0B,IAAI,CAAA,EAAG;AAExC,MAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAQ;AACxB,QAAA,MAAM,OAAA,GAAU,cAAA,CAAe,KAAA,EAAO,SAAS,CAAA;AAC/C,QAAA,OAAO,OAAA,GAAU,+BAAA,CAAgC,OAAA,EAAS,GAAA,CAAI,WAAW,CAAA,GAAI,IAAA;AAAA,MAC/E;AAEA,MAAA,IAAI,IAAA,CAAK,IAAA,KAAS,OAAA,IAAW,IAAA,CAAK,IAAA,KAAS,MAAA,IAAU,IAAA,CAAK,IAAA,KAAS,SAAA,IAAa,IAAA,CAAK,IAAA,KAAS,OAAA,EAAS;AACrG,QAAA,MAAM,aAAa,cAAA,CAAe,KAAA,EAAO,MAAM,CAAA,IAAK,cAAA,CAAe,OAAO,MAAM,CAAA;AAChF,QAAA,IAAI,CAAC,UAAA,IAAc,CAAC,GAAA,CAAI,aAAa,OAAO,KAAA;AAC5C,QAAA,OAAO,CAAC,sBAAA,CAAuB,UAAA,EAAY,GAAA,CAAI,WAAW,CAAA;AAAA,MAC5D;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAQ;AACxB,MAAA,MAAM,OAAA,GAAU,cAAA,CAAe,KAAA,EAAO,SAAS,CAAA;AAC/C,MAAA,OAAO,OAAA,GAAU,+BAAA,CAAgC,OAAA,EAAS,GAAA,CAAI,WAAW,CAAA,GAAI,IAAA;AAAA,IAC/E;AAEA,IAAA,IAAI,IAAA,CAAK,IAAA,KAAS,OAAA,IAAW,IAAA,CAAK,IAAA,KAAS,MAAA,IAAU,IAAA,CAAK,IAAA,KAAS,SAAA,IAAa,IAAA,CAAK,IAAA,KAAS,OAAA,EAAS;AACrG,MAAA,MAAM,aAAa,cAAA,CAAe,KAAA,EAAO,MAAM,CAAA,IAAK,cAAA,CAAe,OAAO,MAAM,CAAA;AAChF,MAAA,IAAI,CAAC,UAAA,IAAc,CAAC,GAAA,CAAI,aAAa,OAAO,KAAA;AAC5C,MAAA,OAAO,CAAC,sBAAA,CAAuB,UAAA,EAAY,GAAA,CAAI,WAAW,CAAA;AAAA,IAC5D;AAEA,IAAA,OAAO,KAAK,QAAA,KAAa,aAAA;AAAA,EAC3B;AAAA,EAEA,MAAM,MAAM,IAAA,EAAwD;AAClE,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,MAAM,KAAK,MAAA,EAAO;AACpC,IAAA,MAAM,QAAQ,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAI,KAAK,EAAC;AACzC,IAAA,KAAA,CAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,iBAAK,IAAI,IAAI,CAAC,GAAI,KAAA,CAAM,KAAA,IAAS,EAAC,EAAI,IAAA,CAAK,OAAO,CAAC,CAAC,CAAA;AACxE,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,GAAI,KAAA;AACzB,IAAA,IAAA,CAAK,WAAW,KAAA,EAAM;AACtB,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,CAAY,KAAK,SAAA,EAAW,IAAA,CAAK,UAAU,IAAA,CAAK,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAC,CAAA;AAAA,IACxE,SAAS,GAAA,EAAK;AAEZ,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA;AACtC,MAAA,IAAI,UAAU,KAAA,EAAO;AACnB,QAAA,MAAM,GAAA,GAAM,QAAA,CAAS,KAAA,CAAM,OAAA,CAAQ,KAAK,OAAO,CAAA;AAC/C,QAAA,IAAI,QAAQ,EAAA,EAAI,QAAA,CAAS,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MAC9C;AACA,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,KAAK,IAAA,EAAwD;AACjE,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,MAAM,KAAK,MAAA,EAAO;AACpC,IAAA,MAAM,QAAQ,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAI,KAAK,EAAC;AACzC,IAAA,KAAA,CAAM,IAAA,GAAO,KAAA,CAAM,IAAA,iBAAK,IAAI,IAAI,CAAC,GAAI,KAAA,CAAM,IAAA,IAAQ,EAAC,EAAI,IAAA,CAAK,OAAO,CAAC,CAAC,CAAA;AACtE,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,GAAI,KAAA;AACzB,IAAA,IAAA,CAAK,WAAW,KAAA,EAAM;AACtB,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,CAAY,KAAK,SAAA,EAAW,IAAA,CAAK,UAAU,IAAA,CAAK,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAC,CAAA;AAAA,IACxE,SAAS,GAAA,EAAK;AAEZ,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA;AACtC,MAAA,IAAI,UAAU,IAAA,EAAM;AAClB,QAAA,MAAM,GAAA,GAAM,QAAA,CAAS,IAAA,CAAK,OAAA,CAAQ,KAAK,OAAO,CAAA;AAC9C,QAAA,IAAI,QAAQ,EAAA,EAAI,QAAA,CAAS,IAAA,CAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MAC7C;AACA,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAGA,SAAS,IAAA,EAA+C;AACtD,IAAA,IAAA,CAAK,aAAA,CAAc,IAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,IAAA,CAAK,OAAO,CAAA,CAAA,EAAI,IAAI,CAAA;AAC5D,IAAA,IAAA,CAAK,WAAW,KAAA,EAAM;AAAA,EACxB;AAAA;AAAA,EAGA,UAAU,IAAA,EAA+C;AACvD,IAAA,IAAA,CAAK,cAAA,CAAe,IAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,IAAA,CAAK,OAAO,CAAA,CAAA,EAAI,IAAI,CAAA;AAC7D,IAAA,IAAA,CAAK,WAAW,KAAA,EAAM;AAAA,EACxB;AAAA,EAGQ,mBAAmB,QAAA,EAAmD;AAE5E,IAAA,KAAA,MAAW,EAAE,OAAA,EAAS,KAAA,EAAM,IAAK,KAAK,eAAA,EAAiB;AACrD,MAAA,IAAI,SAAA,CAAU,OAAA,EAAS,QAAQ,CAAA,EAAG,OAAO,KAAA;AAAA,IAC3C;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAsCO,IAAM,2BAAA,GAAN,MAAM,4BAAA,CAAwD;AAAA,EAClD,mBAAA;AAAA,EAEjB,YAAY,mBAAA,EAAyC;AAEnD,IAAA,IAAA,CAAK,sBAAsB,mBAAA,IAAuB;AAAA,MAChD,gBAAA,CAAiB,OAAA;AAAA,MACjB,gBAAA,CAAiB;AAAA,KACnB;AAAA,EACF;AAAA,EAEA,OAAe,UAAU,IAAA,EAAuB;AAC9C,IAAA,OAAO,IAAA,CAAK,WAAW,OAAO,CAAA;AAAA,EAChC;AAAA,EAEA,MAAM,SAAS,IAAA,EAAyC;AACtD,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,YAAA,IAAgB,EAAC;AACnC,IAAA,MAAM,aAAA,GAAgB,KAAK,IAAA,CAAK,CAAC,MAAM,IAAA,CAAK,mBAAA,CAAoB,QAAA,CAAS,CAAC,CAAC,CAAA;AAC3E,IAAA,MAAM,KAAA,GAAQ,4BAAA,CAA4B,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAC7D,IAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,mBAAA,CAAoB,QAAA,CAAS,iBAAiB,SAAS,CAAA;AAWpF,IAAA,MAAM,mBAAA,GAAsB,wBAAA,CAAyB,IAAI,CAAA,CAAE,MAAA;AAAA,MACzD,CAAC,CAAA,KAAM,CAAC,IAAA,CAAK,mBAAA,CAAoB,SAAS,CAAC;AAAA,KAC7C;AAKA,IAAA,MAAM,OAAA,GACJ,IAAA,CAAK,UAAA,KAAe,MAAA,IACnB,KAAA,IAAS,CAAC,eAAA,IACX,CAAC,aAAA,IACD,mBAAA,CAAoB,MAAA,GAAS,CAAA;AAE/B,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,MAAM,SAAS,KAAA,IAAS,CAAC,eAAA,GACrB,CAAA,SAAA,EAAY,KAAK,IAAI,CAAA,uFAAA,CAAA,GACrB,IAAA,CAAK,UAAA,KAAe,SAClB,mBAAA,GACA,mBAAA,CAAoB,SAAS,CAAA,GAC3B,CAAA,sDAAA,EAAyD,oBAAoB,IAAA,CAAK,IAAI,CAAC,CAAA,WAAA,EAAc,KAAK,mBAAA,CAAoB,IAAA,CAAK,IAAI,CAAC,MACxI,CAAA,oCAAA,EAAuC,IAAA,CAAK,IAAA,CAAK,IAAI,KAAK,MAAM,CAAA,WAAA,EAAc,KAAK,mBAAA,CAAoB,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA;AAEzH,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,MAAA;AAAA,QACZ,MAAA,EAAQ,gBAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,UAAA,EAAY,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAO;AAAA,EAC9C;AAAA,EACA,MAAM,KAAA,GAAuB;AAAA,EAG7B;AAAA,EACA,MAAM,IAAA,GAAsB;AAAA,EAE5B;AAAA,EACA,QAAA,GAAiB;AAAA,EAEjB;AAAA,EACA,SAAA,GAAkB;AAAA,EAElB;AAAA,EACA,MAAM,MAAA,GAAwB;AAAA,EAE9B;AACF","file":"index.js","sourcesContent":["import type { SecretScrubber } from '../types/secret-scrubber.js';\n\ninterface Pattern {\n type: string;\n regex: RegExp;\n}\n\nconst PATTERNS: Pattern[] = [\n // Anchored at the start where possible so partial matches inside larger\n // strings don't trigger false positives.\n {\n type: 'anthropic_key',\n regex: /(?<![A-Za-z0-9])sk-ant-api\\d+-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g,\n },\n { type: 'openai_key', regex: /(?<![A-Za-z0-9])sk-(?:proj-)?[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g },\n { type: 'github_pat', regex: /(?<![A-Za-z0-9])ghp_[A-Za-z0-9]{36,}(?![A-Za-z0-9])/g },\n { type: 'github_pat_v2', regex: /(?<![A-Za-z0-9])github_pat_[A-Za-z0-9_]{50,}(?![A-Za-z0-9])/g },\n { type: 'aws_access_key', regex: /(?<![A-Za-z0-9])AKIA[0-9A-Z]{16}(?![A-Za-z0-9])/g },\n { type: 'gcp_key', regex: /(?<![A-Za-z0-9])AIza[0-9A-Za-z_-]{35}(?![A-Za-z0-9])/g },\n { type: 'slack_token', regex: /(?<![A-Za-z0-9-])xox[abpos]-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g },\n {\n type: 'stripe_key',\n regex: /(?<![A-Za-z0-9])sk_(?:live|test)_[A-Za-z0-9]{24,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'twilio_sid', regex: /(?<![A-Za-z0-9])AC[a-f0-9]{32}(?![A-Za-z0-9])/g,\n },\n {\n type: 'telegram_bot_token',\n // Telegram tokens are of the form bot<digits>:<alphanum> in URL paths\n regex: /\\/bot\\d+:[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,\n },\n {\n type: 'jwt',\n // Anchored: look for literal \"eyJ\" which is unambiguous for JWT header\n regex:\n /(?<![A-Za-z0-9/+=])eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}(?![A-Za-z0-9/+=])/g,\n },\n {\n type: 'private_key',\n // Anchored: start must be BEGIN, end must be END with no extra dashes after END\n regex:\n /(?:^|\\n)-----BEGIN (?:RSA|EC|OPENSSH|DSA|PGP)? ?PRIVATE KEY-----[\\s\\S]*?-----END[^-]*-----(?:\\n|$)/g,\n },\n { type: 'mongodb_uri', regex: /mongodb(?:\\+srv)?:\\/\\/[^\\s\"'`]+/g },\n { type: 'postgres_uri', regex: /postgres(?:ql)?:\\/\\/[^\\s\"'`]+/g },\n { type: 'mysql_uri', regex: /mysql:\\/\\/[^\\s\"'`]+/g },\n { type: 'redis_uri', regex: /redis:\\/\\/[^\\s\"'`]+/g },\n // AI/ML provider keys — modern LLM services with well-known prefixes\n {\n type: 'huggingface_token',\n // HuggingFace tokens: hf_ followed by 34 alphanumeric chars\n regex: /(?<![A-Za-z0-9])hf_[A-Za-z0-9]{34}(?![A-Za-z0-9])/g,\n },\n {\n type: 'replicate_token',\n // Replicate tokens: r8_ followed by 40+ alphanumeric chars\n regex: /(?<![A-Za-z0-9])r8_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'perplexity_key',\n // Perplexity API keys: pplx- followed by 40+ alphanumeric chars\n regex: /(?<![A-Za-z0-9])pplx-[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'groq_key',\n // Groq API keys: gsk_ followed by 40+ alphanumeric chars\n regex: /(?<![A-Za-z0-9])gsk_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'bearer_token',\n // Anchored with alternation instead of negative lookahead — avoids V8\n // backtracking risk on adversarial input. Bounded at 512 chars.\n // Min 12 chars: some OAuth providers issue shorter-lived tokens (< 20\n // chars). A 12-char base64 string has ~71 bits of entropy — above the\n // threshold where random strings are unlikely to produce false matches.\n regex: /(?:^|[^A-Za-z0-9_.~+/-])Bearer\\s+[A-Za-z0-9._~+/-]{12,512}=*(?:$|[^A-Za-z0-9_.~+/-])/g,\n },\n {\n type: 'high_entropy_env',\n // Anchored with alternation instead of lookbehind to avoid backtracking.\n // Value bounded at 512 chars.\n regex: /(?:^|\\s)([A-Z_]{4,}(?:KEY|TOKEN|SECRET|PASSWORD|PWD))\\s*[:=]\\s*['\"]?([A-Za-z0-9_/+=-]{20,512})['\"]?(?:\\s|$)/g,\n },\n];\n\n/**\n * `high_entropy_env` is the one pattern that needs special replacement logic\n * (it preserves the key name), so it runs in its own pass. Every other pattern\n * is folded into a single combined regex. Derive the split by type rather than\n * by hard-coded indices so adding/removing a pattern can't silently drop one.\n */\nconst SIMPLE_PATTERNS = PATTERNS.filter((p) => p.type !== 'high_entropy_env');\n\n/**\n * Combined single-pass regex for all simple patterns. Each alternative is a\n * capturing group so the callback can determine which original pattern fired\n * (only one group is non-undefined at match time). Order matches SIMPLE_PATTERNS\n * (longer/more-specific prefixes first). Relies on each simple pattern source\n * containing no internal capturing groups — only `(?:...)` and lookarounds.\n */\nconst COMBINED_REGEX = new RegExp(SIMPLE_PATTERNS.map((p) => `(${p.regex.source})`).join('|'), 'g');\n\n/** Separate pattern for high_entropy_env (different replacement logic). */\nconst HIGH_ENTROPY_REGEX = PATTERNS.find((p) => p.type === 'high_entropy_env')!.regex;\n\n/**\n * Replacements for the combined patterns, parallel to SIMPLE_PATTERNS. The\n * combined-regex callback indexes into this with the matched group's position.\n */\nconst COMBINED_REPLACEMENTS = SIMPLE_PATTERNS.map((p) => `[REDACTED:${p.type}]`);\n\n/**\n * Per-chunk cap. Splits long inputs into 64 KB chunks to keep scrub() memory\n * bounded. Real scrub() inputs (LLM responses, tool outputs) are typically\n * much smaller; this cap handles edge cases without impacting normal usage.\n */\nconst SCRUB_CHUNK_BYTES = 64 * 1024;\n\n/**\n * Quick pre-scan: check if the text contains any substring that MUST be\n * present for a credential pattern to match. If none are found, the text\n * is guaranteed clean — skip all regex passes (2 total: 16-pattern combined + high_entropy_env).\n *\n * Each anchor is the shortest unique substring from the corresponding pattern.\n * V8's `String.includes()` is hand-tuned C++ — O(n) with near-zero overhead\n * for typical tool-output lengths (100–5000 chars). A single combined regex\n * via `text.search()` is consistently slower for this many alternatives.\n */\nfunction hasCredentialAnchors(text: string): boolean {\n return (\n text.includes('-----BEGIN') || // Private keys (most unique → cheap reject)\n text.includes('sk-') || // Anthropic + OpenAI keys\n text.includes('sk_') || // Stripe live/test keys\n text.includes('ghp_') || // GitHub PAT v1\n text.includes('github_pat_') || // GitHub PAT v2\n text.includes('eyJ') || // JWT\n text.includes('AKIA') || // AWS access key\n text.includes('AIza') || // GCP service key\n text.includes('xox') || // Slack token (xoxa/xoxb/xoxp/xoxo/xoxs)\n text.includes('Bearer ') || // Bearer token (space suffix reduces false positives)\n text.includes('/bot') || // Telegram bot token (URL path pattern)\n text.includes('hf_') || // HuggingFace token\n text.includes('r8_') || // Replicate token\n text.includes('pplx-') || // Perplexity API key\n text.includes('gsk_') || // Groq API key\n text.includes('_KEY=') || // High-entropy env vars: API_KEY=, SECRET_KEY=, ...\n text.includes('_TOKEN=') || // ACCESS_TOKEN=, AUTH_TOKEN=, ...\n text.includes('_SECRET=') || // API_SECRET=, CLIENT_SECRET=, ...\n text.includes('_PASSWORD=') || // DB_PASSWORD=, ROOT_PASSWORD=, ...\n text.includes('mongodb://') ||\n text.includes('mongodb+srv://') ||\n text.includes('postgres://') ||\n text.includes('postgresql://') ||\n text.includes('mysql://') ||\n text.includes('redis://')\n );\n}\n\nexport class DefaultSecretScrubber implements SecretScrubber {\n scrub(text: string): string {\n if (!text) return text;\n\n // Fast path: if no credential anchor substrings exist in the text,\n // none of the 17 regex patterns can match. Skip all regex work.\n // This covers the vast majority of tool outputs (~95% of calls on\n // typical sessions are file paths, status messages, diffs, etc.).\n if (!hasCredentialAnchors(text)) return text;\n\n // For oversize inputs, scrub in fixed chunks. We split on newlines\n // where possible so secrets that span a few hundred bytes still get\n // matched within a single chunk; only inputs above ~64 KB risk a\n // boundary cutting a secret in half, and those are uncommon.\n if (text.length <= SCRUB_CHUNK_BYTES) {\n return this.scrubOne(text);\n }\n const out: string[] = [];\n let i = 0;\n while (i < text.length) {\n let end = Math.min(i + SCRUB_CHUNK_BYTES, text.length);\n // Try to break on a newline near the boundary so we don't cut secrets.\n if (end < text.length) {\n const nl = text.lastIndexOf('\\n', end);\n if (nl > i + SCRUB_CHUNK_BYTES / 2) end = nl + 1;\n }\n out.push(this.scrubOne(text.slice(i, end)));\n i = end;\n }\n return out.join('');\n }\n\n private scrubOne(text: string): string {\n // Redundant guard: if we reached scrubOne via the chunked path, the\n // chunk may have been small enough to anchor-skip independently.\n if (!hasCredentialAnchors(text)) return text;\n\n // Pass 1: combined single-pass regex for all simple patterns. Each\n // alternative is a capturing group; only the group that matched is\n // non-undefined. The trailing offset/string args replace() appends are\n // always defined, so the matched group (which precedes them) is found first.\n let out = text.replace(\n COMBINED_REGEX,\n (match, ...groups) => {\n // groups[i] corresponds to SIMPLE_PATTERNS[i]; find which one fired.\n const idx = groups.findIndex((g) => g !== undefined);\n if (idx < 0) return match;\n const replacement = COMBINED_REPLACEMENTS[idx];\n return replacement !== undefined ? replacement : match;\n },\n );\n\n // Pass 2: high_entropy_env needs special handling — preserve the key name.\n out = out.replace(HIGH_ENTROPY_REGEX, (_match, group1, _group2) => {\n return `${group1}=[REDACTED:high_entropy_env]`;\n });\n\n return out;\n }\n\n /**\n * Recursively scrub every string value in an object/array graph. Secrets can\n * appear under any key — a URL query param, an `authorization` header, an\n * arbitrarily-named nested field — so we don't gate recursion on key names.\n * The per-string `scrub()` fast-path (anchor pre-scan) keeps this cheap: any\n * value without a credential anchor returns immediately without regex work.\n */\n scrubObject<T>(obj: T): T {\n const seen = new WeakSet();\n const visit = (v: unknown): unknown => {\n if (typeof v === 'string') return this.scrub(v);\n if (v === null || typeof v !== 'object') return v;\n if (seen.has(v as object)) return v;\n seen.add(v as object);\n if (Array.isArray(v)) return v.map(visit);\n const out: Record<string, unknown> = {};\n for (const [k, val] of Object.entries(v as Record<string, unknown>)) {\n out[k] = visit(val);\n }\n return out;\n };\n return visit(obj) as T;\n }\n}\n","import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists — extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n // ENOENT means the directory was deleted (e.g. by concurrent cleanup).\n // Recreate it and retry acquiring the lock.\n if (code === 'ENOENT') {\n await fs.mkdir(dir, { recursive: true });\n continue;\n }\n if (code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new Error(`Timed out waiting for file lock: ${targetPath}`);\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient — retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n","/**\n * Deep merge utility — safely merges nested objects with configurable\n * conflict resolution, array merging, and prototype-pollution guarding.\n *\n * Used by:\n * - config-loader (config layer merging with primitive-array concatenation)\n * - secret-vault (config patching)\n * - json-path (json_merge tool with prefer-base / prefer-patch semantics)\n *\n * @module utils/deep-merge\n */\n\n// ---------------------------------------------------------------------------\n// Prototype-pollution guard — shared set of forbidden __proto__ keys\n// ---------------------------------------------------------------------------\n\nexport const FORBIDDEN_PROTO_KEYS = new Set([\n '__proto__',\n 'constructor',\n 'prototype',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__',\n]);\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** True when every element is a primitive or null (no nested objects/arrays). */\nexport function isPrimitiveArray(a: unknown[]): boolean {\n return a.every((v) => v === null || (typeof v !== 'object' && typeof v !== 'function'));\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface DeepMergeOptions {\n /**\n * Which side wins on collision for scalars and arrays.\n *\n * - `'prefer-patch'` (default): patch value replaces base value.\n * - `'prefer-base'`: base value is kept, patch value is ignored.\n */\n conflictResolution?: 'prefer-base' | 'prefer-patch';\n\n /**\n * How to handle array values.\n *\n * - `'replace'` (default): patch array replaces base array entirely.\n * - `'concat-primitives'`: when both values are primitive arrays,\n * they are concatenated and deduped (via Set). Non-primitive\n * arrays still replace the base wholesale.\n */\n arrayMode?: 'replace' | 'concat-primitives';\n\n /**\n * Skip prototype-pollution keys (`__proto__`, `constructor`, etc.).\n * Enabled by default. Only disable when you control both inputs\n * and the keyset (e.g. when merging trusted JSON schemas).\n */\n protectProto?: boolean;\n\n /**\n * Optional callback fired when a non-primitive (object) array is\n * replaced wholesale (only relevant with `arrayMode: 'concat-primitives'`).\n * Receives the key name, existing array length, and patch array length.\n * Used by config-loader for debug logging.\n */\n onNonPrimitiveArrayReplace?: (\n key: string,\n existingLen: number,\n patchLen: number,\n ) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively merge `patch` into `base`, returning a new object.\n *\n * - Nested plain objects are merged recursively.\n * - Arrays are handled per `options.arrayMode`.\n * - Scalar collisions are resolved per `options.conflictResolution`.\n * - `null` and non-object values in `patch` replace the base value\n * (unless `conflictResolution` is `'prefer-base'`).\n * - Keys in `base` that are absent from `patch` are preserved.\n * - `FORBIDDEN_PROTO_KEYS` are skipped in the patch (unless\n * `options.protectProto` is set to `false`).\n *\n * The function is generic over `T extends Record<string, unknown>` for\n * callers that pass typed config objects, but the runtime signature\n * also accepts `unknown` inputs (used by the json-path plugin).\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n base: T,\n patch: Record<string, unknown>,\n options?: DeepMergeOptions,\n): T;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options?: DeepMergeOptions,\n): unknown;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options: DeepMergeOptions = {},\n): unknown {\n const {\n conflictResolution = 'prefer-patch',\n arrayMode = 'replace',\n protectProto = true,\n onNonPrimitiveArrayReplace,\n } = options;\n\n // Non-object / null handling — delegate to conflict resolution.\n if (typeof base !== 'object' || base === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n if (typeof patch !== 'object' || patch === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Arrays — handled *before* the object merge so array-of-objects\n // aren't accidentally treated as plain records.\n if (Array.isArray(base) && Array.isArray(patch)) {\n if (\n arrayMode === 'concat-primitives' &&\n isPrimitiveArray(base) &&\n isPrimitiveArray(patch)\n ) {\n return [...new Set([...base, ...patch])];\n }\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // If only one side is an array, treat as scalar collision.\n if (Array.isArray(base) || Array.isArray(patch)) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Plain object merge.\n const baseObj = base as Record<string, unknown>;\n const patchObj = patch as Record<string, unknown>;\n const out: Record<string, unknown> = { ...baseObj };\n\n for (const [k, v] of Object.entries(patchObj)) {\n if (protectProto && FORBIDDEN_PROTO_KEYS.has(k)) continue;\n\n const existing = out[k];\n if (\n v !== null &&\n typeof v === 'object' &&\n !Array.isArray(v) &&\n existing !== null &&\n typeof existing === 'object' &&\n !Array.isArray(existing)\n ) {\n // Recursive merge for nested plain objects.\n out[k] = deepMerge(existing, v, options);\n } else if (Array.isArray(v) && Array.isArray(existing)) {\n // Delegate to top-level array handling so arrayMode\n // (e.g. 'concat-primitives') applies to nested arrays too.\n // Fire debug hook when a non-primitive array replaces an existing\n // array (for non-primitive arrays, concat-primitives is a no-op and\n // the result is always a wholesale replacement).\n if (onNonPrimitiveArrayReplace && !isPrimitiveArray(v)) {\n onNonPrimitiveArrayReplace(k, existing.length, v.length);\n }\n out[k] = deepMerge(existing, v, options);\n } else if (v !== undefined) {\n // Fire debug hook when a non-primitive (object) array replaces an\n // existing value in concat-primitives mode.\n if (\n onNonPrimitiveArrayReplace &&\n Array.isArray(v) &&\n !isPrimitiveArray(v)\n ) {\n const existingLen = Array.isArray(existing) ? existing.length : 0;\n onNonPrimitiveArrayReplace(k, existingLen, v.length);\n }\n out[k] = v;\n }\n // When v === undefined, leave the existing value untouched\n // (this matches config-loader's behaviour: undefined in patch\n // means \"don't change this key\").\n }\n\n return out;\n}\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","import { expectDefined } from './expect-defined.js';\n/**\r\n * Minimal glob matcher for trust patterns.\r\n * Supports: *, **, ?, character classes [abc], [a-z], negation [!...] or [^...].\r\n *\r\n * Compiled regexes are cached so repeated calls with the same pattern\r\n * avoid recompilation overhead.\r\n */\r\n\r\nfunction escapeRegex(s: string): string {\r\n return s.replace(/[.+^${}()|\\\\]/g, '\\\\$&');\r\n}\r\n\r\n// Module-level cache to avoid recompiling the same pattern on every call.\r\n// LRU-ish eviction keeps unbounded growth in check for long-running processes.\r\nconst COMPILED_GLOB_CACHE = new Map<string, RegExp>();\r\nconst CACHE_MAX_SIZE = 2000;\r\n\r\nfunction getCachedGlob(pattern: string): RegExp {\r\n const cached = COMPILED_GLOB_CACHE.get(pattern);\r\n if (cached) return cached;\r\n if (COMPILED_GLOB_CACHE.size >= CACHE_MAX_SIZE) {\r\n // Evict oldest 25% when at capacity\r\n const keys = [...COMPILED_GLOB_CACHE.keys()];\r\n for (let i = 0; i < Math.floor(CACHE_MAX_SIZE / 4); i++) {\r\n COMPILED_GLOB_CACHE.delete(expectDefined(keys[i]));\r\n }\r\n }\r\n const re = compileGlob(pattern);\r\n COMPILED_GLOB_CACHE.set(pattern, re);\r\n return re;\r\n}\r\n\r\n// Cap glob pattern length to prevent excessively long compiled regexes.\r\nconst MAX_GLOB_PATTERN_LEN = 1024;\r\n\r\nexport function compileGlob(pattern: string): RegExp {\r\n if (pattern.length > MAX_GLOB_PATTERN_LEN) {\r\n throw new Error(`Glob pattern exceeds ${MAX_GLOB_PATTERN_LEN} characters`);\r\n }\r\n let i = 0;\r\n let re = '^';\r\n while (i < pattern.length) {\r\n const c = pattern[i];\r\n if (c === '*') {\r\n if (pattern[i + 1] === '*') {\r\n // ** matches any number of chars including /\r\n re += '.*';\r\n i += 2;\r\n // Skip trailing slash so '**/x' matches 'x'\r\n if (pattern[i] === '/') i++;\r\n } else {\r\n // single * matches any chars except /\r\n re += '[^/]*';\r\n i++;\r\n }\r\n } else if (c === '?') {\r\n re += '[^/]';\r\n i++;\r\n } else if (c === '[') {\r\n let cls = '[';\r\n i++;\r\n if (pattern[i] === '!' || pattern[i] === '^') {\r\n cls += '^';\r\n i++;\r\n }\r\n while (i < pattern.length && pattern[i] !== ']') {\r\n const ch = pattern[i] ?? '';\r\n // Inside a regex class, only `]`, `\\`, and `^`/`-` at boundaries need\r\n // escaping. We've already consumed the leading `^`; the rest are\r\n // literal. Escape `\\` defensively and pass the rest through verbatim\r\n // so ranges like `a-z` continue to work.\r\n if (ch === '\\\\') {\r\n cls += '\\\\\\\\';\r\n } else if (ch === ']' || ch === '^') {\r\n cls += `\\\\${ch}`;\r\n } else {\r\n cls += ch;\r\n }\r\n i++;\r\n }\r\n cls += ']';\r\n re += cls;\r\n i++; // skip closing ]\r\n } else {\r\n re += escapeRegex(c ?? '');\r\n i++;\r\n }\r\n }\r\n re += '$';\r\n return new RegExp(re);\r\n}\r\n\r\nexport function matchGlob(pattern: string, input: string): boolean {\r\n return getCachedGlob(pattern).test(input);\r\n}\r\n\r\nexport function matchAny(patterns: string[], input: string): boolean {\r\n return patterns.some((p) => matchGlob(p, input));\r\n}\r\n","import { toErrorMessage } from './error.js';\n\nexport interface SafeParseResult<T> {\n ok: boolean;\n value?: T | undefined;\n error?: string | undefined;\n}\n\nexport function safeParse<T = unknown>(input: string, maxBytes = 5_000_000): SafeParseResult<T> {\n if (input.length > maxBytes) {\n return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };\n }\n try {\n return { ok: true, value: JSON.parse(input) as T };\n } catch (err) {\n return {\n ok: false,\n error: toErrorMessage(err),\n };\n }\n}\n\nexport function safeStringify(value: unknown, pretty = false): string {\n const seen = new WeakSet();\n const replacer = (_k: string, v: unknown): unknown => {\n if (typeof v === 'bigint') return v.toString();\n if (v instanceof Error) {\n return { name: v.name, message: v.message, stack: v.stack };\n }\n if (typeof v === 'object' && v !== null) {\n if (seen.has(v as object)) return '[Circular]';\n seen.add(v as object);\n }\n return v;\n };\n try {\n return JSON.stringify(value, replacer, pretty ? 2 : undefined) ?? 'null';\n } catch (err) {\n return JSON.stringify({\n __serialization_error: toErrorMessage(err),\n });\n }\n}\n\n/**\n * Attempt to parse JSON5-style input and return a valid JSON string.\n * Handles trailing commas, single-line comments, and unquoted keys\n * that are common in provider output.\n *\n * Returns the sanitized string if it parses successfully as JSON,\n * or `null` if the input cannot be made valid. Callers use this to\n * decide whether to proceed with the parsed result or fall back to\n * raw handling.\n */\nexport function sanitizeJsonString(s: string): string | null {\n let out = s.trim();\n\n // Stage 1: strip single-line comments (// to end of line) that appear\n // outside of string values. This is a heuristic: comments inside strings\n // are preserved because we only strip // when preceded by a char that\n // strongly suggests we're not in a string (quote count modulo 2 is even).\n out = stripSingleLineComments(out);\n\n // Stage 2: strip trailing commas before } or ]\n out = out.replace(/,(\\s*[}\\]])/g, '$1');\n\n // Stage 3: escape literal control characters that appear *inside* string\n // values. Models frequently emit raw newlines/tabs inside a code payload\n // (e.g. edit's old_string/new_string) instead of the required \\n / \\t, which\n // makes JSON.parse throw. This is the single most common malformed-args case.\n out = escapeControlCharsInStrings(out);\n\n // Stage 4: attempt full parse; return null if it fails so callers can\n // distinguish \"already valid JSON\" from \"unrecoverable\".\n try {\n JSON.parse(out);\n return out;\n } catch {\n return null; // stripped but still not valid JSON; caller handles it\n }\n}\n\n/**\n * Walk the string tracking whether we are inside a JSON string literal and\n * replace raw control characters (U+0000–U+001F) that appear inside strings\n * with their valid JSON escape sequences. Characters outside strings are left\n * untouched (insignificant whitespace stays as-is). Already-escaped sequences\n * are not double-escaped because we only act on *literal* control bytes.\n */\nfunction escapeControlCharsInStrings(s: string): string {\n let inString = false;\n let out = '';\n for (let i = 0; i < s.length; i++) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s[i - 1] !== '\\\\')) {\n inString = !inString;\n out += c;\n continue;\n }\n const code = c.charCodeAt(0);\n if (inString && code < 0x20) {\n switch (c) {\n case '\\n':\n out += '\\\\n';\n break;\n case '\\r':\n out += '\\\\r';\n break;\n case '\\t':\n out += '\\\\t';\n break;\n case '\\b':\n out += '\\\\b';\n break;\n case '\\f':\n out += '\\\\f';\n break;\n default:\n out += `\\\\u${code.toString(16).padStart(4, '0')}`;\n }\n continue;\n }\n out += c;\n }\n return out;\n}\n\nfunction stripSingleLineComments(s: string): string {\n let inString = false;\n const chars: string[] = [];\n let i = 0;\n while (i < s.length) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s.charAt(i - 1) !== '\\\\')) {\n inString = !inString;\n chars.push(c);\n } else if (c === '/' && s.charAt(i + 1) === '/' && !inString) {\n // skip to end of line\n while (i < s.length && s.charAt(i) !== '\\n') i++;\n } else {\n chars.push(c);\n }\n i++;\n }\n return chars.join('');\n}\n","const GLOB_METACHARACTERS = /[*?[\\]]/g;\n\nexport function escapeGlobSubject(value: string): string {\n return value.replace(GLOB_METACHARACTERS, (char) => `\\\\${char}`);\n}\n\nexport function normalizePathSubject(value: string): string {\n return escapeGlobSubject(value.replace(/\\\\/g, '/'));\n}\n\nexport function isPathSubjectKey(subjectKey: string): boolean {\n return subjectKey === 'path' || subjectKey === 'file' || subjectKey === 'files';\n}\n\nexport function subjectForToolInput(\n toolName: string,\n input: unknown,\n subjectKey?: string,\n): string | undefined {\n if (!input || typeof input !== 'object') return undefined;\n const obj = input as Record<string, unknown>;\n\n if (subjectKey) {\n const value = obj[subjectKey];\n if (typeof value === 'string') {\n return isPathSubjectKey(subjectKey) ? normalizePathSubject(value) : escapeGlobSubject(value);\n }\n }\n\n if (toolName === 'bash' && typeof obj.command === 'string') {\n return escapeGlobSubject(obj.command);\n }\n if (typeof obj.path === 'string') {\n return normalizePathSubject(obj.path);\n }\n if (typeof obj.url === 'string') {\n return escapeGlobSubject(obj.url);\n }\n if (typeof obj.name === 'string') {\n return escapeGlobSubject(obj.name);\n }\n return undefined;\n}\n","import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","/**\n * SecretVault encrypts secrets-at-rest in config files. The wire format is\n * `enc:v<N>:<base64-iv>:<base64-tag>:<base64-ciphertext>` where `<N>` is the\n * key version used for encryption. Plaintext strings (those that do not match\n * this prefix) are passed through unchanged so that existing configs and\n * env-var-derived values keep working.\n *\n * Key rotation produces a new key and re-encrypts all secrets under it.\n * After rotation, `encrypt()` emits the new version prefix (e.g. `enc:v2:`)\n * and `decrypt()` accepts any version prefix — it uses the current key\n * regardless, since rotation re-encrypts every value atomically.\n *\n * The vault is intentionally NOT designed to defeat a determined local\n * attacker who can read both the config file and the key file — that level\n * of secrecy needs the OS keychain. The goal is to keep keys from being\n * visible in screen shares, accidental log captures, and `cat config.json`\n * over someone's shoulder.\n */\nexport interface SecretVault {\n encrypt(plaintext: string): string;\n decrypt(value: string): string;\n isEncrypted(value: string): boolean;\n /** Current key version. Starts at 1; incremented by `rotateKey()`. */\n readonly keyVersion: number;\n}\n\n/**\n * RotatableSecretVault extends SecretVault with key rotation support.\n * `rotateKey()` generates a fresh key, writes it to disk, and increments\n * the key version. All subsequent `encrypt()` calls use the new version\n * prefix. The caller is responsible for re-encrypting existing config\n * values (see `rotateConfigKeys()`).\n */\nexport interface RotatableSecretVault extends SecretVault {\n rotateKey(): { oldVersion: number; newVersion: number };\n}\n\n/** Legacy v1 prefix — values encrypted before key rotation was introduced. */\nexport const ENCRYPTED_PREFIX = 'enc:v1:';\n\n/**\n * Match any versioned encrypted value prefix: `enc:v1:`, `enc:v2:`, etc.\n * Used by `isEncrypted()` and `decrypt()` to handle all versions uniformly.\n */\nexport const ENCRYPTED_PREFIX_PATTERN = /^enc:v(\\d+):/;\n\n/**\n * Return the encrypted prefix for a given key version.\n * @example encryptedPrefixForVersion(1) // 'enc:v1:'\n * @example encryptedPrefixForVersion(2) // 'enc:v2:'\n */\nexport function encryptedPrefixForVersion(version: number): string {\n return `enc:v${version}:`;\n}\n\n/**\n * Parse the key version from an encrypted value string.\n * Returns undefined if the string is not an encrypted value.\n */\nexport function parseEncryptedVersion(value: string): number | undefined {\n const match = value.match(ENCRYPTED_PREFIX_PATTERN);\n return match ? Number.parseInt(match[1]!, 10) : undefined;\n}\n\n/**\n * No-op SecretVault that passes values through unchanged.\n * Used in contexts where encryption is not needed — e.g. reading/writing\n * config sections that contain no secret fields (models, settings, etc.).\n */\nexport const noOpVault: SecretVault = {\n encrypt: (v) => v,\n decrypt: (v) => v,\n isEncrypted: () => false,\n keyVersion: 1,\n};\n","import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Logger } from '../types/logger.js';\nimport type { RotatableSecretVault, SecretVault } from '../types/secret-vault.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\nimport {\n ENCRYPTED_PREFIX_PATTERN,\n encryptedPrefixForVersion,\n} from '../types/secret-vault.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\nexport interface SecretVaultOptions {\n /** Absolute path to the key file. Created with mode 0o600 if missing. */\n keyFile: string;\n}\n\nconst KEY_BYTES = 32;\nconst IV_BYTES = 12;\nconst TAG_BYTES = 16;\nconst ALGO = 'aes-256-gcm';\n// Desired file mode for the key file on POSIX systems.\nconst KEY_FILE_MODE = 0o600;\n\n/**\n * Key file format v2+: 4-byte magic + 1-byte version + 32-byte key = 37 bytes.\n * The magic header distinguishes versioned key files from legacy 32-byte raw keys.\n */\nconst KEY_FILE_MAGIC = Buffer.from('WSKV', 'ascii');\nconst VERSIONED_KEY_FILE_SIZE = KEY_FILE_MAGIC.length + 1 + KEY_BYTES; // 37 bytes\n\n/**\n * Check and warn if the key file has incorrect permissions on POSIX.\n * On Windows this is a no-op (mode bits don't apply).\n */\nfunction checkKeyFilePermissions(keyFile: string): void {\n if (process.platform === 'win32') return; // No mode bits on Windows\n try {\n const stat = fs.statSync(keyFile);\n const actualMode = stat.mode & 0o777;\n if (actualMode !== KEY_FILE_MODE) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'vault.key_file_wrong_permissions',\n message: `Key file ${keyFile} has mode ${actualMode.toString(8)} — expected ${KEY_FILE_MODE.toString(8)}. Run: chmod ${KEY_FILE_MODE.toString(8)} ${keyFile}`,\n keyFile,\n expectedMode: KEY_FILE_MODE,\n actualMode,\n timestamp: new Date().toISOString(),\n }));\n }\n } catch {\n // stat can fail for reasons other than the file not existing;\n // if it does, the ENOENT path handles it.\n }\n}\n\n/**\n * Default vault: AES-256-GCM with a key stored at `keyFile` (mode 0o600).\n * The key is loaded lazily on first encrypt/decrypt; if it does not exist,\n * a fresh one is generated. Decryption of plaintext values is a no-op so\n * legacy configs continue to work.\n *\n * Key file format:\n * - Legacy (v1): exactly 32 raw bytes\n * - Versioned (v2+): 4-byte magic `WSKV` + 1-byte version + 32-byte key (37 bytes)\n *\n * Encrypted value format: `enc:v<N>:<iv>:<tag>:<ciphertext>` where N is the\n * key version. After rotation, encrypt() emits the new version prefix.\n */\nexport class DefaultSecretVault implements RotatableSecretVault {\n private readonly keyFile: string;\n private key?: Buffer | undefined;\n private _keyVersion: number = 1;\n\n constructor(opts: SecretVaultOptions) {\n this.keyFile = opts.keyFile;\n }\n\n /** Current key version. Starts at 1; incremented by rotateKey(). */\n get keyVersion(): number {\n // Ensure key is loaded so version is accurate\n if (!this.key) this.loadOrCreateKey();\n return this._keyVersion;\n }\n\n isEncrypted(value: string): boolean {\n return typeof value === 'string' && ENCRYPTED_PREFIX_PATTERN.test(value);\n }\n\n encrypt(plaintext: string): string {\n if (this.isEncrypted(plaintext)) return plaintext;\n const key = this.loadOrCreateKey();\n const iv = randomBytes(IV_BYTES);\n const cipher = createCipheriv(ALGO, key, iv);\n const ct = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);\n const tag = cipher.getAuthTag();\n const prefix = encryptedPrefixForVersion(this._keyVersion);\n return `${prefix}${iv.toString('base64')}:${tag.toString('base64')}:${ct.toString('base64')}`;\n }\n\n decrypt(value: string): string {\n if (!this.isEncrypted(value)) return value;\n // Strip the versioned prefix (enc:v1:, enc:v2:, etc.)\n const prefixMatch = value.match(ENCRYPTED_PREFIX_PATTERN);\n if (!prefixMatch) {\n throw new ConfigError({\n message: 'SecretVault: malformed encrypted value',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { field: 'encrypted_value' },\n });\n }\n const rest = value.slice(prefixMatch[0].length);\n const parts = rest.split(':');\n if (parts.length !== 3) {\n throw new ConfigError({\n message: 'SecretVault: malformed encrypted value',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { field: 'encrypted_value' },\n });\n }\n const [ivB64, tagB64, ctB64] = parts as [string, string, string];\n const iv = Buffer.from(ivB64, 'base64');\n const tag = Buffer.from(tagB64, 'base64');\n const ct = Buffer.from(ctB64, 'base64');\n if (iv.length !== IV_BYTES) throw new ConfigError({\n message: 'SecretVault: bad IV length',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { expected: IV_BYTES, actual: iv.length },\n });\n if (tag.length !== TAG_BYTES) throw new ConfigError({\n message: 'SecretVault: bad tag length',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { expected: TAG_BYTES, actual: tag.length },\n });\n const key = this.loadOrCreateKey();\n const decipher = createDecipheriv(ALGO, key, iv);\n decipher.setAuthTag(tag);\n const pt = Buffer.concat([decipher.update(ct), decipher.final()]);\n return pt.toString('utf8');\n }\n\n /**\n * Generate a new encryption key, write it to disk, and increment the key version.\n * After rotation, encrypt() emits the new version prefix (e.g. enc:v2:).\n * The caller must re-encrypt existing config values (see rotateConfigKeys()).\n */\n rotateKey(): { oldVersion: number; newVersion: number } {\n const oldVersion = this._keyVersion;\n const newKey = randomBytes(KEY_BYTES);\n const newVersion = oldVersion + 1;\n\n // Write versioned key file: WSKV + version byte + key\n const keyFileBuf = Buffer.alloc(VERSIONED_KEY_FILE_SIZE);\n KEY_FILE_MAGIC.copy(keyFileBuf, 0);\n keyFileBuf[KEY_FILE_MAGIC.length] = newVersion;\n newKey.copy(keyFileBuf, KEY_FILE_MAGIC.length + 1);\n\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\n fs.writeFileSync(this.keyFile, keyFileBuf, { mode: 0o600 });\n checkKeyFilePermissions(this.keyFile);\n\n this.key = newKey;\n this._keyVersion = newVersion;\n return { oldVersion, newVersion };\n }\n\n private loadOrCreateKey(): Buffer {\n // readFileSync blocks the event loop, but this is a one-time cost per\n // process: the key is cached after the first load and reused for every\n // subsequent encrypt/decrypt. For CLI usage (single run → exit) this is\n // negligible. For server contexts (eternal autonomy, MCP server mode),\n // the first encrypt/decrypt call causes a brief (<1ms) event loop stall.\n // Prefer calling vault.encrypt('') during boot to warm the cache if this\n // is a concern in your deployment.\n if (this.key) return this.key;\n try {\n const buf = fs.readFileSync(this.keyFile);\n\n // Detect key file format:\n if (buf.length === KEY_BYTES) {\n // Legacy v1: raw 32-byte key\n this.key = buf;\n this._keyVersion = 1;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n\n if (buf.length === VERSIONED_KEY_FILE_SIZE) {\n // Versioned v2+: WSKV magic + version byte + 32-byte key\n const magic = buf.subarray(0, KEY_FILE_MAGIC.length);\n if (!magic.equals(KEY_FILE_MAGIC)) {\n throw new ConfigError({\n message: `SecretVault: key file ${this.keyFile} has invalid magic header`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile },\n });\n }\n const version = buf[KEY_FILE_MAGIC.length]!;\n const key = buf.subarray(KEY_FILE_MAGIC.length + 1);\n if (key.length !== KEY_BYTES) {\n throw new ConfigError({\n message: `SecretVault: key file ${this.keyFile} has wrong key size (${key.length} bytes, expected ${KEY_BYTES})`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: key.length },\n });\n }\n this.key = Buffer.from(key);\n this._keyVersion = version;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n\n // Wrong size — neither legacy nor versioned format\n throw new ConfigError({\n message:\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\n `(expected ${KEY_BYTES} for v1 or ${VERSIONED_KEY_FILE_SIZE} for v2+). ` +\n `Remove it manually to generate a new key.`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: buf.length },\n });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n // Create a fresh key. Use sync APIs so the constructor-free getter\n // remains synchronous from the caller's perspective.\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\n const key = randomBytes(KEY_BYTES);\n // Use exclusive-create flag 'wx' to prevent races: if two processes race\n // to create the key file, only one succeeds and the loser gets EEXIST.\n try {\n fs.writeFileSync(this.keyFile, key, { mode: 0o600, flag: 'wx' });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST') throw err;\n // Another process won the race — re-read what they wrote.\n const buf = fs.readFileSync(this.keyFile);\n if (buf.length === KEY_BYTES) {\n // Legacy v1 format\n this.key = buf;\n this._keyVersion = 1;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n if (buf.length === VERSIONED_KEY_FILE_SIZE) {\n // Versioned format\n const magic = buf.subarray(0, KEY_FILE_MAGIC.length);\n if (!magic.equals(KEY_FILE_MAGIC)) {\n throw new ConfigError({\n message: `SecretVault: key file ${this.keyFile} has invalid magic header`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile },\n });\n }\n const version = buf[KEY_FILE_MAGIC.length]!;\n const winnerKey = buf.subarray(KEY_FILE_MAGIC.length + 1);\n this.key = Buffer.from(winnerKey);\n this._keyVersion = version;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n throw new ConfigError({\n message:\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\n `(expected ${KEY_BYTES} for v1 or ${VERSIONED_KEY_FILE_SIZE} for v2+). ` +\n `Remove it manually to generate a new key.`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: buf.length },\n });\n }\n this.key = key;\n this._keyVersion = 1;\n return key;\n }\n}\n\n/**\n * Walk a Config-shaped object and decrypt any apiKey-like fields in place,\n * returning a new object. Used by the config loader so the rest of the\n * system never has to know about the wire format.\n *\n * @param warn — callback for decryption warnings. Defaults to `console.warn`\n * for backward compatibility; pass `logger.warn` when a structured logger\n * is available (preferred in long-running/server contexts).\n */\nexport function decryptConfigSecrets<T>(\n cfg: T,\n vault: SecretVault,\n opts?: { warn?: (msg: string) => void },\n): T {\n const warn = opts?.warn ?? ((msg: string) => console.warn(msg));\n // A single corrupted/malformed encrypted field should not kill the entire\n // config load. Swallow per-field decrypt errors (zero the field so callers\n // see \"missing key\" instead of holding ciphertext) and surface a warning.\n return walk(cfg, vault, (v, key) => {\n try {\n return vault.decrypt(v);\n } catch (err) {\n warn(\n `[secret-vault] Failed to decrypt \"${key}\": ${err instanceof Error ? err.message : err}`,\n );\n return '';\n }\n });\n}\n\nexport function encryptConfigSecrets<T>(\n cfg: T,\n vault: SecretVault,\n _opts?: { warn?: (msg: string) => void },\n): T {\n return walk(cfg, vault, (v) => vault.encrypt(v));\n}\n\nfunction walk<T>(node: T, vault: SecretVault, transform: (s: string, key: string) => string): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walk(item, vault, transform)) as never as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k)) {\n out[k] = transform(v, k);\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walk(v, vault, transform);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * A key is treated as secret-bearing if its name (case-insensitive) contains\n * one of these tokens. Captures common variants like `apiKey`, `authToken`,\n * `refreshToken`, `sessionKey`, `password`, `client_secret`, `bearer`, etc.\n * Use a named field with `isSecret: false` annotation if you must opt out —\n * see `NON_SECRET_OVERRIDES` below.\n */\nconst SECRET_KEY_PATTERN =\n /(?:apikey|api_key|authtoken|auth_token|bearer|secret|password|passwd|pwd|refreshtoken|refresh_token|sessionkey|session_key|access[_-]?token|private[_-]?key)/i;\n\n// Field names that contain the literal substring \"key\" but are not secrets.\n// Keep this list short; the substring rule itself is intentionally narrow.\nconst NON_SECRET_OVERRIDES = new Set(['publickey', 'public_key']);\n\nexport function isSecretField(name: string): boolean {\n const lc = name.toLowerCase();\n if (NON_SECRET_OVERRIDES.has(lc)) return false;\n return SECRET_KEY_PATTERN.test(lc);\n}\n\n/**\n * Re-write `~/.wrongstack/config.json` (or any path) with all secret-bearing\n * fields encrypted. Used by the `wstack auth` subcommand.\n */\nexport async function rewriteConfigEncrypted(\n configPath: string,\n vault: SecretVault,\n patch?: Record<string, unknown>,\n): Promise<void> {\n let current: Record<string, unknown> = {};\n try {\n const raw = await fsp.readFile(configPath, 'utf8');\n current = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n // start from empty\n }\n const merged = deepMerge(current, patch ?? {});\n const encrypted = encryptConfigSecrets(merged, vault);\n await fsp.mkdir(path.dirname(configPath), { recursive: true });\n // atomicWrite: torn write here would erase every saved encrypted API key.\n await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 0o600 });\n await restrictFilePermissions(configPath);\n}\n\n/**\n * Scan a config file on disk for plaintext secret-bearing fields and\n * rewrite the file with them encrypted in place. Returns a count of how\n * many fields were migrated. Idempotent — calling on a fully-encrypted\n * file is a no-op and writes nothing. Used by the CLI on every boot so\n * users who had plaintext keys before the vault landed are upgraded\n * transparently.\n */\nexport async function migratePlaintextSecrets(\n configPath: string,\n vault: SecretVault,\n logger?: Pick<Logger, 'warn'>,\n): Promise<{ migrated: number; file: string }> {\n let raw: string;\n try {\n raw = await fsp.readFile(configPath, 'utf8');\n } catch {\n return { migrated: 0, file: configPath };\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return { migrated: 0, file: configPath };\n }\n const counter = { n: 0 };\n const migrated = walkCount(parsed, vault, counter);\n if (counter.n === 0) return { migrated: 0, file: configPath };\n // atomicWrite: runs on every boot for legacy users — torn write = wipe.\n await atomicWrite(configPath, JSON.stringify(migrated, null, 2), { mode: 0o600 });\n await restrictFilePermissions(\n configPath,\n logger ? { warn: (msg) => logger.warn(msg) } : undefined,\n );\n return { migrated: counter.n, file: configPath };\n}\n\n/**\n * Rotate the vault's encryption key and re-encrypt all secret-bearing\n * fields in a config file. This is the atomic key rotation operation:\n *\n * 1. Read the config file\n * 2. Decrypt all encrypted values with the old key\n * 3. Generate a new key (vault.rotateKey())\n * 4. Re-encrypt all values with the new key (new version prefix)\n * 5. Write the config file atomically\n *\n * Returns the number of fields re-encrypted and the version transition.\n * If the config file doesn't exist or has no encrypted fields, returns\n * { rotated: 0 } without modifying the key.\n */\nexport async function rotateConfigKeys(\n configPath: string,\n vault: RotatableSecretVault,\n logger?: Pick<Logger, 'warn' | 'info'>,\n): Promise<{ rotated: number; oldVersion: number; newVersion: number; file: string }> {\n const log = logger?.info ?? (() => {});\n const warn = logger?.warn ?? ((msg: string) => console.warn(msg));\n\n // Read the config file\n let raw: string;\n try {\n raw = await fsp.readFile(configPath, 'utf8');\n } catch {\n // No config file — just rotate the key without re-encrypting anything\n const { oldVersion, newVersion } = vault.rotateKey();\n log(`[secret-vault] Key rotated (v${oldVersion} → v${newVersion}) — no config file to re-encrypt`);\n return { rotated: 0, oldVersion, newVersion, file: configPath };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n warn(`[secret-vault] Config file ${configPath} is not valid JSON — skipping rotation`);\n return { rotated: 0, oldVersion: vault.keyVersion, newVersion: vault.keyVersion, file: configPath };\n }\n\n // Count encrypted fields and decrypt them\n const counter = { n: 0, failed: [] as string[] };\n const decrypted = walkDecryptCount(parsed, vault, counter);\n\n // Abort BEFORE rotating if any encrypted field could not be decrypted with\n // the current key. Rotation would discard the old key while these fields\n // still hold old-key ciphertext, and walkReencrypt skips already-encrypted\n // values — so they would become permanently undecryptable. Surface the\n // corruption and leave the key intact for the operator to investigate.\n if (counter.failed.length > 0) {\n throw new Error(\n `[secret-vault] Aborting key rotation: ${counter.failed.length} field(s) could not be decrypted ` +\n `with the current key and would be permanently lost on rotation: ${counter.failed.join(', ')}. ` +\n `Restore or remove these fields before rotating.`,\n );\n }\n\n if (counter.n === 0) {\n // No encrypted fields — just rotate the key\n const { oldVersion, newVersion } = vault.rotateKey();\n log(`[secret-vault] Key rotated (v${oldVersion} → v${newVersion}) — no encrypted fields to re-encrypt`);\n return { rotated: 0, oldVersion, newVersion, file: configPath };\n }\n\n // Rotate the key (generates new key, increments version)\n const { oldVersion, newVersion } = vault.rotateKey();\n\n // Re-encrypt all secret fields with the new key\n const reencrypted = walkReencrypt(decrypted, vault);\n\n // Write the config file atomically\n await atomicWrite(configPath, JSON.stringify(reencrypted, null, 2), { mode: 0o600 });\n await restrictFilePermissions(configPath, { warn });\n\n log(`[secret-vault] Key rotated (v${oldVersion} → v${newVersion}) — re-encrypted ${counter.n} field(s)`);\n return { rotated: counter.n, oldVersion, newVersion, file: configPath };\n}\n\n/**\n * Walk a config object, decrypt all encrypted values, and count them.\n * Returns a new object with decrypted values.\n *\n * `counter.failed` collects the key paths of any field that is encrypted but\n * could NOT be decrypted with the current key. These are left as-is (old\n * ciphertext). The caller MUST treat a non-empty `failed` list as a hard stop\n * before rotating: rotation discards the old key, and `walkReencrypt` skips\n * already-encrypted values, so a retained old-key ciphertext would become\n * permanently undecryptable. Surfacing it is strictly safer than entombing it.\n */\nfunction walkDecryptCount<T>(\n node: T,\n vault: SecretVault,\n counter: { n: number; failed: string[] },\n pathPrefix = '',\n): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item, i) =>\n walkDecryptCount(item, vault, counter, `${pathPrefix}[${i}]`),\n ) as never as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n const keyPath = pathPrefix ? `${pathPrefix}.${k}` : k;\n if (typeof v === 'string' && vault.isEncrypted(v)) {\n try {\n out[k] = vault.decrypt(v);\n counter.n++;\n } catch {\n // Decryption failed — record the path and keep the old ciphertext.\n // The caller aborts rotation when counter.failed is non-empty, so\n // the old key is never discarded while this value still depends on it.\n counter.failed.push(keyPath);\n out[k] = v;\n }\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkDecryptCount(v, vault, counter, keyPath);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * Walk a config object and re-encrypt all secret-bearing fields.\n * Unlike encryptConfigSecrets, this encrypts ALL string values that\n * were previously decrypted (they're now plaintext), not just those\n * matching the secret field pattern. This ensures we re-encrypt values\n * that were successfully decrypted in walkDecryptCount.\n */\nfunction walkReencrypt<T>(node: T, vault: SecretVault): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walkReencrypt(item, vault)) as never as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k) && v.length > 0 && !vault.isEncrypted(v)) {\n // This was a decrypted secret — re-encrypt it\n out[k] = vault.encrypt(v);\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkReencrypt(v, vault);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * Restrict a file to owner-only access. On POSIX this is chmod 0o600.\n * On Windows, chmod is a no-op — we use icacls to remove inherited\n * permissions and grant only the current user. Failures are logged\n * but not thrown so callers are not blocked on unsupported platforms.\n */\nasync function restrictFilePermissions(\n filePath: string,\n opts?: { warn?: (msg: string) => void },\n): Promise<void> {\n const warn = opts?.warn ?? ((msg: string) => console.warn(msg));\n if (process.platform === 'win32') {\n try {\n const { execFile } = await import('node:child_process');\n const { promisify } = await import('node:util');\n const execFileAsync = promisify(execFile);\n const user = windowsAccountName();\n if (!user) {\n warn(\n `[secret-vault] Could not determine the current Windows user for ${filePath}; skipping icacls hardening.`,\n );\n return;\n }\n // Remove inherited ACEs, grant full control only to current user.\n await execFileAsync('icacls', [filePath, '/inheritance:r', '/grant:r', `${user}:(F)`]);\n } catch {\n // Best-effort: icacls may not be available in all environments.\n warn(\n `[secret-vault] Could not restrict permissions on ${filePath} — config file may be readable by other users on this system.`,\n );\n }\n } else {\n try {\n await fsp.chmod(filePath, 0o600);\n } catch {\n // Best-effort\n }\n }\n}\n\nfunction windowsAccountName(): string | undefined {\n const username = process.env.USERNAME || process.env.USER;\n if (!username || username.includes('\\0')) return undefined;\n const domain = process.env.USERDOMAIN;\n if (domain && !domain.includes('\\0')) return `${domain}\\\\${username}`;\n return username;\n}\n\nfunction walkCount<T>(node: T, vault: SecretVault, counter: { n: number }): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walkCount(item, vault, counter)) as never as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k) && !vault.isEncrypted(v) && v.length > 0) {\n out[k] = vault.encrypt(v);\n counter.n++;\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkCount(v, vault, counter);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/** Keys that, when written into a plain object, can poison the prototype\n * chain. We never want user config to carry these. */\nimport { deepMerge } from '../utils/deep-merge.js';\n","/**\n * Well-known tool capabilities used for authorization decisions.\n *\n * These are the preferred values for `Tool.capabilities`.\n * New capabilities should be added here with clear documentation.\n *\n * Philosophy (2026-06+):\n * - Prefer capabilities over exact tool name matching.\n * - Subagent guards and future policies should primarily key off capabilities.\n * - Name-based denylists are legacy and will be phased down.\n */\nexport const ToolCapabilities = {\n /** Can execute arbitrary commands in the user's shell (the `bash` tool). */\n SHELL_ARBITRARY: 'shell.arbitrary',\n\n /** Can execute a restricted set of commands (the `exec` tool). */\n SHELL_RESTRICTED: 'shell.restricted',\n\n /** Can read files inside the project (and possibly outside via symlinks if not guarded). */\n FS_READ: 'fs.read',\n\n /** Can write / modify / delete files inside the project. */\n FS_WRITE: 'fs.write',\n\n /** Can write files outside the current project root (very high risk). */\n FS_WRITE_OUTSIDE_PROJECT: 'fs.write.outside-project',\n\n /** Can perform outbound network requests. */\n NET_OUTBOUND: 'net.outbound',\n\n /** Proxies tools from external MCP servers (unknown capability). */\n MCP_PROXY: 'mcp.proxy',\n\n /** Can spawn or manage subagents / multi-agent tasks. */\n SUBAGENT_SPAWN: 'subagent.spawn',\n\n /** Can mutate global or session configuration / trust state. */\n CONFIG_MUTATE: 'config.mutate',\n\n /** Can install packages or run package managers with side effects. */\n PACKAGE_INSTALL: 'package.install',\n} as const;\n\nexport type ToolCapability = (typeof ToolCapabilities)[keyof typeof ToolCapabilities];\n\n/**\n * Set of capabilities that are considered dangerous for subagents by default.\n * Subagents should not receive these capabilities unless the leader explicitly\n * allows the specific tool at spawn time.\n */\nexport const DANGEROUS_FOR_SUBAGENTS: readonly ToolCapability[] = [\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,\n ToolCapabilities.MCP_PROXY,\n ToolCapabilities.SUBAGENT_SPAWN,\n ToolCapabilities.CONFIG_MUTATE,\n ToolCapabilities.PACKAGE_INSTALL,\n];\n\n/**\n * Wide capability allowlist for subagents that the user has authorized to act\n * with full developer power (the CLI fleet host applies this to any subagent\n * that isn't given an explicit, narrower grant). It covers everything needed to\n * do real work end-to-end — read, write/edit inside the project, outbound\n * network, and shell/build/install — so a delegated coding or build agent runs\n * the same toolchain the leader would, without per-tool confirmation it cannot\n * answer.\n *\n * Deliberately EXCLUDED (require an explicit per-spawn `allowedCapabilities`\n * grant, because they escape the task's blast radius rather than perform it):\n * - `fs.write.outside-project` — writing outside the repo (e.g. ~/.ssh).\n * - `mcp.proxy` — third-party MCP tools (also hard-blocked by name).\n * - `subagent.spawn` — recursive delegation (the baseline prompt forbids it).\n * - `config.mutate` — rewriting trust/config is privilege escalation, not work.\n */\nexport const WIDE_SUBAGENT_CAPABILITIES: readonly ToolCapability[] = [\n ToolCapabilities.FS_READ,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.NET_OUTBOUND,\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.PACKAGE_INSTALL,\n];\n\n/**\n * Check if a tool (or its capabilities array) includes any dangerous capability\n * for subagent execution.\n */\nexport function hasDangerousCapabilityForSubagents(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): boolean {\n if (!toolOrCaps) return false;\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.some((c) => DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability));\n}\n\n/**\n * Check if a tool declares a specific capability (or any of the provided ones).\n */\nexport function hasCapability(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n capability: ToolCapability | ToolCapability[],\n): boolean {\n if (!toolOrCaps) return false;\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n const toCheck = Array.isArray(capability) ? capability : [capability];\n return toCheck.some((c) => caps.includes(c));\n}\n\n/**\n * Returns the intersection of a tool's capabilities with the dangerous set.\n * Useful for logging and audit trails.\n */\nexport function getDangerousCapabilities(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): ToolCapability[] {\n if (!toolOrCaps) return [];\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.filter((c): c is ToolCapability =>\n DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability),\n );\n}\n","import * as path from 'node:path';\n\n// Best-effort heuristic detection of destructive shell commands — NOT a\n// security boundary. Static analysis of shell strings is inherently defeatable\n// by obfuscation: env-variable indirection (`$RM -rf /`), quote-splitting\n// (`r''m`), base64/eval pipes (`echo ... | base64 -d | sh`), command\n// substitution (`$(printf rm) -rf`), and aliases all evade these patterns.\n// This is one defense-in-depth layer behind the permission policy and the\n// project-escape checks below, not the sole gate. Treat a miss here as\n// expected, not as a hole to be plugged with ever-more-clever regexes.\nconst DESTRUCTIVE_BASH_PATTERNS: RegExp[] = [\n /\\bgit\\s+(?:clean\\s+-[^\\s]*[xdf]|reset\\s+--hard)\\b/i,\n /\\b(?:drop|truncate)\\s+(?:table|database|schema)\\b/i,\n /\\bdelete\\s+from\\b/i,\n /\\b(?:mkfs|format|diskpart|shutdown|reboot)\\b/i,\n /\\bchmod\\s+-R\\s+777\\b/i,\n /\\bchown\\s+-R\\b/i,\n /\\b(?:curl|wget)\\b.*\\|\\s*(?:sh|bash|zsh|pwsh|powershell)\\b/i,\n /\\b(?:powershell|pwsh)\\b.*(?:-encodedcommand|-enc)\\b/i,\n /:\\(\\)\\s*\\{\\s*:\\|:&\\s*}\\s*;/,\n];\n\nconst PROJECT_ESCAPE_PATTERN = /(?:^|[\\s\"'])\\.\\.(?:[\\\\/]|$)/;\nconst ABSOLUTE_PATH_PATTERN = /(?:^|[\\s\"'])(?:~[\\\\/]|\\/[A-Za-z0-9_.-]|[A-Za-z]:[\\\\/])/;\nconst SHELL_OPERATORS = new Set(['&&', '||', '|', ';', '>', '>>', '<', '2>', '2>>']);\n\nexport function getInputString(input: unknown, key: string): string | undefined {\n if (!input || typeof input !== 'object') return undefined;\n const value = (input as Record<string, unknown>)[key];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function pathLooksInsideProject(rawPath: string, projectRoot: string | undefined): boolean {\n if (!projectRoot) return false;\n // A leading ~ is the home directory, never the project root. Without this,\n // path.resolve() treats \"~/cache\" as a relative path *inside* the project\n // (there is no shell tilde-expansion here), masking an escape like `rm -rf ~/cache`.\n if (rawPath === '~' || rawPath.startsWith('~/') || rawPath.startsWith('~\\\\')) return false;\n const resolved = path.resolve(projectRoot, rawPath);\n const relative = path.relative(projectRoot, resolved);\n return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative);\n}\n\nfunction tokenizeShell(command: string): string[] {\n return command.match(/\"[^\"]*\"|'[^']*'|\\S+/g)?.map((token) => token.replace(/^['\"]|['\"]$/g, '')) ?? [];\n}\n\nfunction pathTokenIsOutsideProject(token: string, projectRoot: string | undefined): boolean {\n if (!token || SHELL_OPERATORS.has(token) || token.startsWith('-')) return false;\n if (token === '/' || token === '~' || token === '.' || token === '..') return token !== '.';\n if (token.includes('*')) return true;\n if (token.startsWith('..') || token.includes('../') || token.includes('..\\\\')) return true;\n if (path.isAbsolute(token) || token.startsWith('~/')) return !pathLooksInsideProject(token, projectRoot);\n return false;\n}\n\nfunction hasDangerousDeleteTarget(\n tokens: string[],\n start: number,\n projectRoot: string | undefined,\n): boolean {\n const targets = tokens\n .slice(start)\n .filter((token) => !token.startsWith('-') && !SHELL_OPERATORS.has(token));\n if (targets.length === 0) return true;\n return targets.some((target) => pathTokenIsOutsideProject(target, projectRoot));\n}\n\nfunction hasDestructiveDelete(command: string, projectRoot: string | undefined): boolean {\n const tokens = tokenizeShell(command);\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i]?.toLowerCase();\n if (!token) continue;\n\n if (token === 'rm') {\n const args = tokens.slice(i + 1);\n const recursiveOrForce = args.some(\n (arg) => /^-[^-]*[rf]/i.test(arg) || arg === '--recursive' || arg === '--force',\n );\n if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;\n }\n\n if (token === 'rmdir' || token === 'rd') {\n const args = tokens.slice(i + 1);\n const recursive = args.some((arg) => arg.toLowerCase() === '/s');\n if (recursive && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;\n }\n\n if (token === 'del' || token === 'erase') {\n if (hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;\n }\n\n if (token === 'remove-item') {\n const args = tokens.slice(i + 1).map((arg) => arg.toLowerCase());\n const recursiveOrForce = args.includes('-recurse') || args.includes('-force');\n if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;\n }\n }\n return false;\n}\n\nexport function isClearlyDestructiveBashCommand(\n command: string,\n projectRoot: string | undefined,\n): boolean {\n const trimmed = command.trim();\n if (!trimmed) return false;\n if (hasDestructiveDelete(trimmed, projectRoot)) return true;\n if (DESTRUCTIVE_BASH_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;\n\n // Changing directory or targeting paths outside the project turns arbitrary\n // shell from \"normal workspace work\" into something the user should see.\n if (/\\bcd\\s+(?:\\.\\.|~|\\/|[A-Za-z]:[\\\\/])/i.test(trimmed)) return true;\n if (PROJECT_ESCAPE_PATTERN.test(trimmed)) return true;\n\n const absolute = trimmed.match(ABSOLUTE_PATH_PATTERN)?.[0]?.trim().replace(/^['\"]|['\"]$/g, '');\n if (absolute && !pathLooksInsideProject(absolute, projectRoot)) return true;\n\n return false;\n}\n","import * as fs from 'node:fs/promises';\nimport type { Context } from '../core/context.js';\nimport type { InputReader } from '../types/input-reader.js';\nimport type { PermissionDecision, PermissionPolicy, TrustPolicy } from '../types/permission.js';\nimport type { Tool } from '../types/tool.js';\nimport { getDangerousCapabilities, hasCapability, ToolCapabilities } from './capabilities.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { matchAny, matchGlob } from '../utils/glob-match.js';\nimport { safeParse } from '../utils/safe-json.js';\nimport { subjectForToolInput } from '../utils/tool-subject.js';\nimport {\n getInputString,\n isClearlyDestructiveBashCommand,\n pathLooksInsideProject,\n} from './yolo-risk.js';\n\nexport interface PermissionPolicyOptions {\n trustFile: string;\n yolo?: boolean | undefined;\n /**\n * When true, YOLO mode auto-approves even destructive calls without confirm.\n * @deprecated YOLO now auto-approves everything by default. Use `confirmDestructive`\n * to opt back into destructive-operation confirmation prompts.\n */\n yoloDestructive?: boolean | undefined;\n /** @deprecated Use `yoloDestructive`. */\n forceAllYolo?: boolean | undefined;\n /**\n * When true AND yolo is true, destructive operations still require confirmation.\n * This is the opt-in safety net: set this if you want YOLO for normal work but\n * explicit approval for `rm -rf`, project-escaping writes, etc.\n * Has no effect when yolo is false (normal permission flow applies).\n */\n confirmDestructive?: boolean | undefined;\n promptDelegate?: (\n tool: Tool,\n input: unknown,\n suggestedPattern: string,\n ) => Promise<'yes' | 'no' | 'always' | 'deny'>;\n inputReader?: InputReader | undefined;\n}\n\nexport class DefaultPermissionPolicy implements PermissionPolicy {\n private policy: TrustPolicy = {};\n private loaded = false;\n private readonly trustFile: string;\n private yolo: boolean;\n private yoloDestructive: boolean;\n /** When true, destructive ops still require confirmation even in YOLO mode. */\n private confirmDestructive: boolean;\n /**\n * Session-scoped \"soft deny\" map. When the user presses 'n' (block once),\n * the tool+pattern is added here. If the LLM retries in the same session,\n * we return deny directly without asking again.\n *\n * Cleared on reload() since reload = fresh trust file snapshot.\n */\n private sessionDenied = new Map<string, boolean>();\n /**\n * Session-scoped \"soft trust\" map. When the user presses 'a' (allow once),\n * the tool+pattern is added here. If the LLM retries in the same session,\n * we return auto directly without asking again.\n *\n * Cleared on reload().\n */\n private sessionAllowed = new Map<string, boolean>();\n /**\n * Interactive prompt delegate. When set, `evaluate()` calls it to get a\n * user decision synchronously (CLI REPL path). When cleared (TUI / WebUI),\n * `evaluate()` returns `confirm` so the caller can emit\n * `tool.confirm_needed` for the UI layer to handle.\n *\n * Mutable so the host can switch from CLI-prompt to event-driven\n * confirmation at runtime (e.g. when `--goal` forces TUI mode after\n * the agent was already constructed).\n */\n private promptDelegate?: PermissionPolicyOptions['promptDelegate'] | undefined;\n /** Pre-compiled wildcard patterns — rebuilt on reload for O(1) lookup. */\n private wildcardEntries: { pattern: string; value: TrustPolicy[string] }[] = [];\n /**\n * Evaluate-result cache. Keyed by `tool.name::subject` so repeated calls\n * with the same tool+input skip namespace matching, subject computation,\n * pattern matching (matchAny), and YOLO destructive gating.\n *\n * Cleared on any state change (reload, trust, deny, yolo toggle) because\n * the result depends on the full policy state. The write-tool smart-bypass\n * (step 7 in `evaluate()`) is not cached since `ctx.hasRead()` changes\n * dynamically within a session.\n *\n * LRU eviction is not needed — the cache is cleared on state changes\n * that are rare (trust file ops, user confirm) and the number of unique\n * tool+subject pairs per iteration is small (<50).\n */\n private _evalCache = new Map<string, PermissionDecision>();\n\n constructor(opts: PermissionPolicyOptions) {\n this.trustFile = opts.trustFile;\n this.yolo = opts.yolo ?? false;\n this.yoloDestructive = opts.yoloDestructive ?? opts.forceAllYolo ?? false;\n this.confirmDestructive = opts.confirmDestructive ?? false;\n this.promptDelegate = opts.promptDelegate;\n }\n\n /**\n * Replace (or clear) the interactive prompt delegate at runtime.\n * Used by the CLI to switch from inline prompts (REPL) to event-driven\n * confirmation (TUI) when the run mode is determined after the policy\n * was constructed (e.g. `--goal` auto-flipping to TUI).\n */\n setPromptDelegate(delegate: PermissionPolicyOptions['promptDelegate']): void {\n this.promptDelegate = delegate;\n }\n\n /** Toggle YOLO (auto-approve) mode at runtime. */\n setYolo(enabled: boolean): void {\n if (this.yolo !== enabled) this._evalCache.clear();\n this.yolo = enabled;\n }\n\n /** Check whether YOLO mode is currently active. */\n getYolo(): boolean {\n return this.yolo;\n }\n\n /** Toggle the destructive YOLO override at runtime. */\n setYoloDestructive(enabled: boolean): void {\n if (this.yoloDestructive !== enabled) this._evalCache.clear();\n this.yoloDestructive = enabled;\n }\n\n /** Check whether the destructive YOLO override is active. */\n getYoloDestructive(): boolean {\n return this.yoloDestructive;\n }\n\n /** Toggle destructive confirmation gate (only meaningful when yolo is active). */\n setConfirmDestructive(enabled: boolean): void {\n if (this.confirmDestructive !== enabled) this._evalCache.clear();\n this.confirmDestructive = enabled;\n }\n\n /** Check whether destructive confirmation gate is active. */\n getConfirmDestructive(): boolean {\n return this.confirmDestructive;\n }\n\n async reload(): Promise<void> {\n try {\n const raw = await fs.readFile(this.trustFile, 'utf8');\n const parsed = safeParse<TrustPolicy>(raw);\n if (parsed.ok && parsed.value) this.policy = parsed.value;\n } catch {\n this.policy = {};\n }\n // Pre-compile wildcard entries so findNamespaceEntry is O(k) instead of O(n*m)\n this.wildcardEntries = [];\n for (const [key, val] of Object.entries(this.policy)) {\n if (key.includes('*')) this.wildcardEntries.push({ pattern: key, value: val });\n }\n // Clear session-scoped soft deny/allow — reload = fresh trust file snapshot\n this.sessionDenied.clear();\n this.sessionAllowed.clear();\n this._evalCache.clear();\n this.loaded = true;\n }\n\n async evaluate(tool: Tool, input: unknown, ctx: Context): Promise<PermissionDecision> {\n if (!this.loaded) await this.reload();\n\n // 1. Tool-namespace matching (mcp__server__* etc.)\n const namespaceEntry = this.findNamespaceEntry(tool.name);\n\n // 2. Tool-name entry\n const entry = this.policy[tool.name] ?? namespaceEntry;\n\n // 3. Compute subject (the thing being matched)\n const subject = subjectForToolInput(tool.name, input, tool.subjectKey);\n const cacheKey = `${tool.name}::${subject ?? tool.name}`;\n\n // S1. Cache check — skip namespace/subject/pattern re-evaluation when the\n // same tool+subject was already decided. The write-tool smart bypass\n // (step 7) is NOT cached because `ctx.hasRead()` changes dynamically\n // within a session — we let it fall through below.\n if (tool.name !== 'write') {\n const cached = this._evalCache.get(cacheKey);\n if (cached !== undefined) return cached;\n }\n\n // 3a. Session soft deny — 'n' blocks this tool+pattern for the rest of\n // this session without writing to the trust file. Prevents LLM retry\n // from re-triggering the confirm prompt.\n if (this.sessionDenied.has(cacheKey)) {\n const decision: PermissionDecision = { permission: 'deny', source: 'deny', reason: 'session soft deny (user pressed no)' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n\n // 3b. Session soft allow — 'y' auto-approves this tool+pattern for the\n // rest of this session without writing to the trust file.\n if (this.sessionAllowed.has(cacheKey)) {\n const decision: PermissionDecision = {\n permission: 'auto',\n source: 'trust',\n reason: 'session soft allow (user pressed yes)',\n };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n\n // 4. Deny — absolute\n if (entry?.deny && subject && matchAny(entry.deny, subject)) {\n const decision: PermissionDecision = { permission: 'deny', source: 'deny', reason: 'matched deny pattern' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n if (tool.permission === 'deny') {\n const decision: PermissionDecision = { permission: 'deny', source: 'default', reason: 'tool default deny' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n\n // 5. Allow (trust file)\n if (entry?.allow && subject && matchAny(entry.allow, subject)) {\n const decision: PermissionDecision = { permission: 'auto', source: 'trust', reason: 'matched allow pattern' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n if (entry?.auto) {\n const decision: PermissionDecision = { permission: 'auto', source: 'trust' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n\n // 6. YOLO — auto-approve everything. Destructive operations are\n // included unless the user explicitly opted into `confirmDestructive`.\n if (this.yolo) {\n if (this.confirmDestructive) {\n const destructive = this.isDestructiveYoloCall(tool, input, ctx);\n if (destructive) {\n if (this.promptDelegate) {\n const decision = await this.promptDelegate(tool, input, subject ?? tool.name);\n if (decision === 'always') {\n await this.trust({ tool: tool.name, pattern: subject ?? tool.name });\n return { permission: 'auto', source: 'user', reason: 'destructive yolo always-allowed' };\n }\n if (decision === 'deny') {\n await this.deny({ tool: tool.name, pattern: subject ?? tool.name });\n return { permission: 'deny', source: 'user', reason: 'user denied destructive yolo' };\n }\n return { permission: decision === 'yes' ? 'auto' : 'deny', source: 'user' };\n }\n return {\n permission: 'confirm',\n source: 'yolo_destructive',\n riskTier: 'destructive',\n reason: 'destructive tool needs explicit approval (confirmDestructive is on)',\n };\n }\n }\n const decision: PermissionDecision = { permission: 'auto', source: 'yolo' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n\n // 7. Smart bypass: write tool — if the file was already read in this\n // session, the user has already seen the content. No confirm needed.\n // NOTE: deliberately NOT cached because ctx.hasRead() changes dynamically.\n if (tool.name === 'write' && subject) {\n if (ctx.hasRead(subject)) {\n return {\n permission: 'auto',\n source: 'context',\n reason: 'file already read in this session',\n };\n }\n }\n\n // 8. Tool default — but mutating tools need confirmation even with\n // auto-permission (e.g. shellcheck makes network calls; a remote WebSocket\n // client must not be able to trigger them without the user seeing the\n // tool.confirm_needed prompt). Non-mutating auto tools (read-only\n // heuristics, schema checks) are still safe to shortcut.\n //\n // Capability-based check: tools with fs.read or net.outbound (non-mutating)\n // can auto-approve; tools with fs.write, shell.*, etc. need confirmation.\n const hasWriteCap = hasCapability(tool, ToolCapabilities.FS_WRITE);\n const hasShellCap = hasCapability(tool, [\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ]);\n const hasInstallCap = hasCapability(tool, ToolCapabilities.PACKAGE_INSTALL);\n const hasConfigCap = hasCapability(tool, ToolCapabilities.CONFIG_MUTATE);\n const hasSubagentCap = hasCapability(tool, ToolCapabilities.SUBAGENT_SPAWN);\n const isMutating = tool.mutating || hasWriteCap || hasShellCap || hasInstallCap || hasConfigCap || hasSubagentCap;\n if (tool.permission === 'auto' && !isMutating) {\n const decision: PermissionDecision = { permission: 'auto', source: 'default' };\n this._evalCache.set(cacheKey, decision);\n return decision;\n }\n\n // 9. Confirm — delegate to prompt\n if (this.promptDelegate) {\n const decision = await this.promptDelegate(tool, input, subject ?? tool.name);\n if (decision === 'always') {\n await this.trust({ tool: tool.name, pattern: subject ?? tool.name });\n return { permission: 'auto', source: 'user', reason: 'user always-allowed' };\n }\n if (decision === 'deny') {\n await this.deny({ tool: tool.name, pattern: subject ?? tool.name });\n return { permission: 'deny', source: 'user', reason: 'user denied' };\n }\n return { permission: decision === 'yes' ? 'auto' : 'deny', source: 'user' };\n }\n return { permission: 'confirm', source: 'default' };\n }\n\n // Capability-based destructive check (preferred over name-based)\n private isDestructiveByCapability(tool: Tool): boolean {\n const caps = tool.capabilities ?? [];\n if (caps.includes('shell.arbitrary')) return true;\n if (caps.includes('fs.write')) return true;\n if (caps.includes('fs.write.outside-project')) return true;\n return false;\n }\n\n private isDestructiveYoloCall(tool: Tool, input: unknown, ctx: Context): boolean {\n // 1. Capability-based check (preferred — works for all tools, not just hardcoded names)\n if (this.isDestructiveByCapability(tool)) {\n // For shell tools, also check if the command is clearly destructive\n if (tool.name === 'bash') {\n const command = getInputString(input, 'command');\n return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : true;\n }\n // For write tools, check if path escapes project\n if (tool.name === 'write' || tool.name === 'edit' || tool.name === 'replace' || tool.name === 'patch') {\n const targetPath = getInputString(input, 'path') ?? getInputString(input, 'file');\n if (!targetPath || !ctx.projectRoot) return false;\n return !pathLooksInsideProject(targetPath, ctx.projectRoot);\n }\n return true;\n }\n\n // 2. Legacy name-based fallback (for tools without capabilities)\n if (tool.name === 'bash') {\n const command = getInputString(input, 'command');\n return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : true;\n }\n\n if (tool.name === 'write' || tool.name === 'edit' || tool.name === 'replace' || tool.name === 'patch') {\n const targetPath = getInputString(input, 'path') ?? getInputString(input, 'file');\n if (!targetPath || !ctx.projectRoot) return false;\n return !pathLooksInsideProject(targetPath, ctx.projectRoot);\n }\n\n return tool.riskTier === 'destructive';\n }\n\n async trust(rule: { tool: string; pattern: string }): Promise<void> {\n if (!this.loaded) await this.reload();\n const entry = this.policy[rule.tool] ?? {};\n entry.allow = Array.from(new Set([...(entry.allow ?? []), rule.pattern]));\n this.policy[rule.tool] = entry;\n this._evalCache.clear();\n try {\n await atomicWrite(this.trustFile, JSON.stringify(this.policy, null, 2));\n } catch (err) {\n // Revert in-memory state since disk write failed\n const existing = this.policy[rule.tool];\n if (existing?.allow) {\n const idx = existing.allow.indexOf(rule.pattern);\n if (idx !== -1) existing.allow.splice(idx, 1);\n }\n throw err;\n }\n }\n\n /** Persist a deny rule — this tool+pattern pair is permanently blocked. */\n async deny(rule: { tool: string; pattern: string }): Promise<void> {\n if (!this.loaded) await this.reload();\n const entry = this.policy[rule.tool] ?? {};\n entry.deny = Array.from(new Set([...(entry.deny ?? []), rule.pattern]));\n this.policy[rule.tool] = entry;\n this._evalCache.clear();\n try {\n await atomicWrite(this.trustFile, JSON.stringify(this.policy, null, 2));\n } catch (err) {\n // Revert in-memory state since disk write failed\n const existing = this.policy[rule.tool];\n if (existing?.deny) {\n const idx = existing.deny.indexOf(rule.pattern);\n if (idx !== -1) existing.deny.splice(idx, 1);\n }\n throw err;\n }\n }\n\n /** Block this tool+pattern for the rest of this session (no trust file). */\n denyOnce(rule: { tool: string; pattern: string }): void {\n this.sessionDenied.set(`${rule.tool}::${rule.pattern}`, true);\n this._evalCache.clear();\n }\n\n /** Auto-approve this tool+pattern for the rest of this session (no trust file). */\n allowOnce(rule: { tool: string; pattern: string }): void {\n this.sessionAllowed.set(`${rule.tool}::${rule.pattern}`, true);\n this._evalCache.clear();\n }\n\n\n private findNamespaceEntry(toolName: string): TrustPolicy[string] | undefined {\n // Use pre-compiled wildcard entries — O(k) where k = wildcard count\n for (const { pattern, value } of this.wildcardEntries) {\n if (matchGlob(pattern, toolName)) return value;\n }\n return undefined;\n }\n}\n\n/**\n * Auto-approving PermissionPolicy used for subagents. Subagents run\n * non-interactively under a director — they cannot answer permission\n * prompts, so a non-YOLO policy on the leader would silently hang the\n * delegated run on the first sensitive tool call. The user already\n * authorized the delegation when they invoked the leader; subagents\n * inherit that authorization automatically.\n *\n * Tool defaults of `permission: 'deny'` are still honored (this is a\n * subagent capability override, not a deny-bypass).\n *\n * 2026-06+: Primary decision is now based on declared `Tool.capabilities`\n * (capability allowlist / denylist model). The legacy name-based DENY set\n * is kept only for backward compatibility with tools that have not yet\n * declared capabilities.\n */\n/**\n * Auto-approving PermissionPolicy used for subagents. Subagents run\n * non-interactively under a director — they cannot answer permission\n * prompts, so a non-YOLO policy on the leader would silently hang the\n * delegated run on the first sensitive tool call. The user already\n * authorized the delegation when they invoked the leader; subagents\n * inherit that authorization automatically.\n *\n * Tool defaults of `permission: 'deny'` are still honored (this is a\n * subagent capability override, not a deny-bypass).\n *\n * 2026-06+: Primary decision is now based on declared `Tool.capabilities`\n * (capability allowlist / denylist model). The legacy name-based DENY set\n * is kept only for backward compatibility with tools that have not yet\n * declared capabilities.\n *\n * 2026-06-13+: Switched to allowlist-by-default. Only tools with explicitly\n * allowed capabilities are auto-approved. Everything else is denied.\n * Default allowed: fs.read, net.outbound (read-only, safe operations).\n */\nexport class AutoApprovePermissionPolicy implements PermissionPolicy {\n private readonly allowedCapabilities: readonly string[];\n\n constructor(allowedCapabilities?: readonly string[]) {\n // Default allowlist: read-only, safe operations\n this.allowedCapabilities = allowedCapabilities ?? [\n ToolCapabilities.FS_READ,\n ToolCapabilities.NET_OUTBOUND,\n ];\n }\n\n private static isMcpTool(name: string): boolean {\n return name.startsWith('mcp__');\n }\n\n async evaluate(tool: Tool): Promise<PermissionDecision> {\n const caps = tool.capabilities ?? [];\n const hasAllowedCap = caps.some((c) => this.allowedCapabilities.includes(c));\n const isMcp = AutoApprovePermissionPolicy.isMcpTool(tool.name);\n const mcpProxyAllowed = this.allowedCapabilities.includes(ToolCapabilities.MCP_PROXY);\n\n // A tool may bundle several capabilities (e.g. `install` declares both\n // `package.install` and `shell.restricted`). The `some()` check above only\n // confirms the tool has *a* useful allowed capability — it does not stop a\n // dangerous capability from riding along. Require every DANGEROUS capability\n // the tool declares to be explicitly present in the allowlist, so widening\n // the allowlist (e.g. `/techstack` adding `fs.write`) grants exactly that\n // capability and nothing more. This is what lets the ToolExecutor trust an\n // `auto` from this policy and skip its post-permission dangerous-capability\n // downgrade (which would otherwise force a `confirm` no subagent can answer).\n const dangerousNotAllowed = getDangerousCapabilities(tool).filter(\n (c) => !this.allowedCapabilities.includes(c),\n );\n\n // Block if: tool is an MCP proxy without an explicit mcp.proxy grant,\n // tool default is deny, no allowed capability, or it carries a dangerous\n // capability the leader did not explicitly grant.\n const blocked =\n tool.permission === 'deny' ||\n (isMcp && !mcpProxyAllowed) ||\n !hasAllowedCap ||\n dangerousNotAllowed.length > 0;\n\n if (blocked) {\n const reason = isMcp && !mcpProxyAllowed\n ? `MCP tool ${tool.name} is not auto-approved for subagents — ask the leader to allow mcp.proxy explicitly`\n : tool.permission === 'deny'\n ? 'tool default deny'\n : dangerousNotAllowed.length > 0\n ? `tool requires un-granted dangerous capability (needs: ${dangerousNotAllowed.join(', ')}, allowed: ${this.allowedCapabilities.join(', ')})`\n : `tool lacks allowed capability (has: ${caps.join(', ') || 'none'}, allowed: ${this.allowedCapabilities.join(', ')})`;\n\n return {\n permission: 'deny',\n source: 'subagent_guard',\n reason,\n };\n }\n\n return { permission: 'auto', source: 'yolo' };\n }\n async trust(): Promise<void> {\n // No-op: subagent permission decisions are ephemeral and must not\n // pollute the leader's persisted trust file.\n }\n async deny(): Promise<void> {\n // No-op: same as trust — subagent decisions are ephemeral.\n }\n denyOnce(): void {\n // No-op: subagent decisions are ephemeral.\n }\n allowOnce(): void {\n // No-op: subagent decisions are ephemeral.\n }\n async reload(): Promise<void> {\n // No-op: nothing to load.\n }\n}\n"]}
|