@wrongstack/core 0.68.0 → 0.77.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.
Files changed (59) hide show
  1. package/dist/{agent-bridge-D-j6OOBT.d.ts → agent-bridge-EWdqs8v6.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-DRZ9-NnR.d.ts → agent-subagent-runner-D8qW8OSC.d.ts} +13 -5
  3. package/dist/{config--86aHSln.d.ts → config-Dy0CK_o6.d.ts} +44 -1
  4. package/dist/coordination/index.d.ts +10 -10
  5. package/dist/coordination/index.js +74 -10
  6. package/dist/coordination/index.js.map +1 -1
  7. package/dist/defaults/index.d.ts +17 -17
  8. package/dist/defaults/index.js +160 -67
  9. package/dist/defaults/index.js.map +1 -1
  10. package/dist/{events-CIplI98R.d.ts → events-CYaoLN5_.d.ts} +45 -0
  11. package/dist/execution/index.d.ts +9 -9
  12. package/dist/execution/index.js +4 -4
  13. package/dist/execution/index.js.map +1 -1
  14. package/dist/extension/index.d.ts +5 -5
  15. package/dist/{index-b5uhfTSl.d.ts → index-DIxjTOga.d.ts} +6 -6
  16. package/dist/{index-DKUvyTvV.d.ts → index-Dsda0uCn.d.ts} +4 -4
  17. package/dist/index.d.ts +108 -33
  18. package/dist/index.js +388 -58
  19. package/dist/index.js.map +1 -1
  20. package/dist/infrastructure/index.d.ts +5 -5
  21. package/dist/infrastructure/index.js +16 -2
  22. package/dist/infrastructure/index.js.map +1 -1
  23. package/dist/kernel/index.d.ts +7 -7
  24. package/dist/kernel/index.js.map +1 -1
  25. package/dist/{logger-bOzkF5LL.d.ts → logger-BppKxDqZ.d.ts} +9 -0
  26. package/dist/{mcp-servers-DwoNBf6r.d.ts → mcp-servers-T0O6UN_w.d.ts} +1 -1
  27. package/dist/{mode-CV077NjV.d.ts → mode-BO4SEUIv.d.ts} +7 -0
  28. package/dist/models/index.d.ts +1 -1
  29. package/dist/models/index.js +18 -9
  30. package/dist/models/index.js.map +1 -1
  31. package/dist/{multi-agent-coordinator-CWnH-CiX.d.ts → multi-agent-coordinator-DpbG3wiy.d.ts} +1 -1
  32. package/dist/{null-fleet-bus-CuN0ObJr.d.ts → null-fleet-bus-u5ys3lW_.d.ts} +28 -9
  33. package/dist/observability/index.d.ts +1 -1
  34. package/dist/{parallel-eternal-engine-0UwotoSx.d.ts → parallel-eternal-engine-Dn0P8Pbj.d.ts} +3 -3
  35. package/dist/{path-resolver-DVkEcIw8.d.ts → path-resolver-B32v2JIq.d.ts} +1 -1
  36. package/dist/{permission-C1A5whY5.d.ts → permission-V5BLOrY6.d.ts} +0 -4
  37. package/dist/{permission-policy-B2dK-T5N.d.ts → permission-policy-CBVx-d-8.d.ts} +1 -5
  38. package/dist/{plan-templates-Bprrzhbu.d.ts → plan-templates-BcUwLlMQ.d.ts} +8 -3
  39. package/dist/{provider-runner-mXvXGSIw.d.ts → provider-runner-CSi_7l0h.d.ts} +1 -1
  40. package/dist/sdd/index.d.ts +6 -6
  41. package/dist/sdd/index.js +3 -3
  42. package/dist/sdd/index.js.map +1 -1
  43. package/dist/security/index.d.ts +2 -2
  44. package/dist/security/index.js +0 -8
  45. package/dist/security/index.js.map +1 -1
  46. package/dist/skills/index.js +1 -0
  47. package/dist/skills/index.js.map +1 -1
  48. package/dist/storage/index.d.ts +4 -4
  49. package/dist/storage/index.js +48 -8
  50. package/dist/storage/index.js.map +1 -1
  51. package/dist/{system-prompt-b61lOd49.d.ts → system-prompt-CA11g6Jo.d.ts} +1 -1
  52. package/dist/types/index.d.ts +14 -14
  53. package/dist/types/index.js +35 -12
  54. package/dist/types/index.js.map +1 -1
  55. package/dist/utils/index.d.ts +2 -2
  56. package/dist/utils/index.js +14 -3
  57. package/dist/utils/index.js.map +1 -1
  58. package/dist/{wstack-paths-eMXnY1_X.d.ts → wstack-paths-D7evAFWM.d.ts} +8 -1
  59. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
1
  export { D as DefaultSecretScrubber, a as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, m as migratePlaintextSecrets, r as rewriteConfigEncrypted } from '../secret-scrubber-7rSC_emZ.js';
2
- export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-B2dK-T5N.js';
2
+ export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-CBVx-d-8.js';
3
3
  import '../secret-vault-DoISxaKO.js';
4
4
  import '../secret-scrubber-3MHDDAtm.js';
5
5
  import '../context-y87Jc5ei.js';
6
6
  import '../input-reader-E-ffP2ee.js';
7
- import '../permission-C1A5whY5.js';
7
+ import '../permission-V5BLOrY6.js';
8
8
 
9
9
  declare function isSecretField(name: string): boolean;
10
10
 
@@ -695,14 +695,6 @@ var DefaultPermissionPolicy = class {
695
695
  getConfirmDestructive() {
696
696
  return this.confirmDestructive;
697
697
  }
698
- /** @deprecated Use `setYoloDestructive`. */
699
- setForceAllYolo(enabled) {
700
- this.setYoloDestructive(enabled);
701
- }
702
- /** @deprecated Use `getYoloDestructive`. */
703
- getForceAllYolo() {
704
- return this.getYoloDestructive();
705
- }
706
698
  async reload() {
707
699
  try {
708
700
  const raw = await fs.readFile(this.trustFile, "utf8");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/security/secret-scrubber.ts","../../src/types/secret-vault.ts","../../src/utils/atomic-write.ts","../../src/security/secret-vault.ts","../../src/security/config-secrets.ts","../../src/security/capabilities.ts","../../src/utils/glob-match.ts","../../src/utils/safe-json.ts","../../src/security/yolo-risk.ts","../../src/security/permission-policy.ts"],"names":["path","stat","resolve","randomBytes","path2","fsp","SECRET_KEY_PATTERN","NON_SECRET_OVERRIDES","isSecretField","relative","fs3"],"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 {\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 * 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\nexport class DefaultSecretScrubber implements SecretScrubber {\n scrub(text: string): string {\n if (!text) return text;\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 let out = text;\n for (const p of PATTERNS) {\n out = out.replace(p.regex, (_match, group1, group2) => {\n if (p.type === 'high_entropy_env' && group1 && group2) {\n return `${group1}=[REDACTED:${p.type}]`;\n }\n return `[REDACTED:${p.type}]`;\n });\n }\n return out;\n }\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","/**\n * SecretVault encrypts secrets-at-rest in config files. The wire format is\n * `enc:v1:<base64-iv>:<base64-tag>:<base64-ciphertext>`. Plaintext strings\n * (those that do not match this prefix) are passed through unchanged so that\n * existing configs and env-var-derived values keep working.\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}\n\nexport const ENCRYPTED_PREFIX = 'enc:v1:';\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;\n encoding?: BufferEncoding;\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\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","import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';\r\nimport * as fs from 'node:fs';\r\nimport * as fsp from 'node:fs/promises';\r\nimport * as path from 'node:path';\r\nimport type { SecretVault } from '../types/secret-vault.js';\r\nimport { ENCRYPTED_PREFIX } from '../types/secret-vault.js';\r\nimport { atomicWrite } from '../utils/atomic-write.js';\r\n\r\nexport interface SecretVaultOptions {\r\n /** Absolute path to the key file. Created with mode 0o600 if missing. */\r\n keyFile: string;\r\n}\r\n\r\nconst KEY_BYTES = 32;\r\nconst IV_BYTES = 12;\r\nconst TAG_BYTES = 16;\r\nconst ALGO = 'aes-256-gcm';\r\n\r\n/**\r\n * Default vault: AES-256-GCM with a key stored at `keyFile` (mode 0o600).\r\n * The key is loaded lazily on first encrypt/decrypt; if it does not exist,\r\n * a fresh one is generated. Decryption of plaintext values is a no-op so\r\n * legacy configs continue to work.\r\n */\r\nexport class DefaultSecretVault implements SecretVault {\r\n private readonly keyFile: string;\r\n private key?: Buffer;\r\n\r\n constructor(opts: SecretVaultOptions) {\r\n this.keyFile = opts.keyFile;\r\n }\r\n\r\n isEncrypted(value: string): boolean {\r\n return typeof value === 'string' && value.startsWith(ENCRYPTED_PREFIX);\r\n }\r\n\r\n encrypt(plaintext: string): string {\r\n if (this.isEncrypted(plaintext)) return plaintext;\r\n const key = this.loadOrCreateKey();\r\n const iv = randomBytes(IV_BYTES);\r\n const cipher = createCipheriv(ALGO, key, iv);\r\n const ct = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);\r\n const tag = cipher.getAuthTag();\r\n return `${ENCRYPTED_PREFIX}${iv.toString('base64')}:${tag.toString('base64')}:${ct.toString('base64')}`;\r\n }\r\n\r\n decrypt(value: string): string {\r\n if (!this.isEncrypted(value)) return value;\r\n const rest = value.slice(ENCRYPTED_PREFIX.length);\r\n const parts = rest.split(':');\r\n if (parts.length !== 3) {\r\n throw new Error('SecretVault: malformed encrypted value');\r\n }\r\n const [ivB64, tagB64, ctB64] = parts as [string, string, string];\r\n const iv = Buffer.from(ivB64, 'base64');\r\n const tag = Buffer.from(tagB64, 'base64');\r\n const ct = Buffer.from(ctB64, 'base64');\r\n if (iv.length !== IV_BYTES) throw new Error('SecretVault: bad IV length');\r\n if (tag.length !== TAG_BYTES) throw new Error('SecretVault: bad tag length');\r\n const key = this.loadOrCreateKey();\r\n const decipher = createDecipheriv(ALGO, key, iv);\r\n decipher.setAuthTag(tag);\r\n const pt = Buffer.concat([decipher.update(ct), decipher.final()]);\r\n return pt.toString('utf8');\r\n }\r\n\r\n private loadOrCreateKey(): Buffer {\r\n if (this.key) return this.key;\r\n try {\r\n const buf = fs.readFileSync(this.keyFile);\r\n if (buf.length !== KEY_BYTES) {\r\n // A wrong-size key is not ENOENT — the file is corrupted or was\r\n // tampered with. Throwing instead of falling through to create a\r\n // new key protects all secrets encrypted under this key; the user\r\n // can remove the file manually to generate a fresh key.\r\n throw new Error(\r\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\r\n `(expected ${KEY_BYTES}). Remove it manually to generate a new key.`,\r\n );\r\n }\r\n this.key = buf;\r\n return this.key;\r\n } catch (err) {\r\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\r\n }\r\n // Create a fresh key. Use sync APIs so the constructor-free getter\r\n // remains synchronous from the caller's perspective.\r\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\r\n const key = randomBytes(KEY_BYTES);\r\n // Use exclusive-create flag 'wx' to prevent races: if two processes race\r\n // to create the key file, only one succeeds and the loser gets EEXIST.\r\n try {\r\n fs.writeFileSync(this.keyFile, key, { mode: 0o600, flag: 'wx' });\r\n } catch (err) {\r\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST') throw err;\r\n // Another process won the race — re-read what they wrote.\r\n const buf = fs.readFileSync(this.keyFile);\r\n if (buf.length !== KEY_BYTES) {\r\n // A wrong-size key is not ENOENT — the file is corrupted or was\r\n // tampered with. Throwing instead of falling through to create a\r\n // new key protects all secrets encrypted under this key; the user\r\n // can remove the file manually to generate a fresh key.\r\n throw new Error(\r\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\r\n `(expected ${KEY_BYTES}). Remove it manually to generate a new key.`,\r\n );\r\n }\r\n this.key = buf;\r\n return this.key;\r\n }\r\n this.key = key;\r\n return key;\r\n }\r\n}\r\n\r\n/**\r\n * Walk a Config-shaped object and decrypt any apiKey-like fields in place,\r\n * returning a new object. Used by the config loader so the rest of the\r\n * system never has to know about the wire format.\r\n */\r\nexport function decryptConfigSecrets<T>(cfg: T, vault: SecretVault): T {\r\n // A single corrupted/malformed encrypted field should not kill the entire\r\n // config load. Swallow per-field decrypt errors (zero the field so callers\r\n // see \"missing key\" instead of holding ciphertext) and surface a warning.\r\n return walk(cfg, vault, (v, key) => {\r\n try {\r\n return vault.decrypt(v);\r\n } catch (err) {\r\n console.warn(\r\n `[secret-vault] Failed to decrypt \"${key}\":`,\r\n err instanceof Error ? err.message : err,\r\n );\r\n return '';\r\n }\r\n });\r\n}\r\n\r\nexport function encryptConfigSecrets<T>(cfg: T, vault: SecretVault): T {\r\n return walk(cfg, vault, (v) => vault.encrypt(v));\r\n}\r\n\r\nfunction walk<T>(node: T, vault: SecretVault, transform: (s: string, key: string) => string): T {\r\n if (node === null || node === undefined) return node;\r\n if (typeof node !== 'object') return node;\r\n if (Array.isArray(node)) {\r\n return node.map((item) => walk(item, vault, transform)) as unknown as T;\r\n }\r\n const out: Record<string, unknown> = Object.create(null);\r\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\r\n if (typeof v === 'string' && isSecretField(k)) {\r\n out[k] = transform(v, k);\r\n } else if (typeof v === 'object' && v !== null) {\r\n out[k] = walk(v, vault, transform);\r\n } else {\r\n out[k] = v;\r\n }\r\n }\r\n return out as T;\r\n}\r\n\r\n/**\r\n * A key is treated as secret-bearing if its name (case-insensitive) contains\r\n * one of these tokens. Captures common variants like `apiKey`, `authToken`,\r\n * `refreshToken`, `sessionKey`, `password`, `client_secret`, `bearer`, etc.\r\n * Use a named field with `isSecret: false` annotation if you must opt out —\r\n * see `NON_SECRET_OVERRIDES` below.\r\n */\r\nconst SECRET_KEY_PATTERN =\r\n /(?:apikey|api_key|authtoken|auth_token|bearer|secret|password|passwd|pwd|refreshtoken|refresh_token|sessionkey|session_key|access[_-]?token|private[_-]?key)/i;\r\n\r\n// Field names that contain the literal substring \"key\" but are not secrets.\r\n// Keep this list short; the substring rule itself is intentionally narrow.\r\nconst NON_SECRET_OVERRIDES = new Set(['publickey', 'public_key']);\r\n\r\nfunction isSecretField(name: string): boolean {\r\n const lc = name.toLowerCase();\r\n if (NON_SECRET_OVERRIDES.has(lc)) return false;\r\n return SECRET_KEY_PATTERN.test(lc);\r\n}\r\n\r\n/**\r\n * Re-write `~/.wrongstack/config.json` (or any path) with all secret-bearing\r\n * fields encrypted. Used by the `wstack auth` subcommand.\r\n */\r\nexport async function rewriteConfigEncrypted(\r\n configPath: string,\r\n vault: SecretVault,\r\n patch?: Record<string, unknown>,\r\n): Promise<void> {\r\n let current: Record<string, unknown> = {};\r\n try {\r\n const raw = await fsp.readFile(configPath, 'utf8');\r\n current = JSON.parse(raw) as Record<string, unknown>;\r\n } catch {\r\n // start from empty\r\n }\r\n const merged = deepMerge(current, patch ?? {});\r\n const encrypted = encryptConfigSecrets(merged, vault);\r\n await fsp.mkdir(path.dirname(configPath), { recursive: true });\r\n // atomicWrite: torn write here would erase every saved encrypted API key.\r\n await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 0o600 });\r\n await restrictFilePermissions(configPath);\r\n}\r\n\r\n/**\r\n * Scan a config file on disk for plaintext secret-bearing fields and\r\n * rewrite the file with them encrypted in place. Returns a count of how\r\n * many fields were migrated. Idempotent — calling on a fully-encrypted\r\n * file is a no-op and writes nothing. Used by the CLI on every boot so\r\n * users who had plaintext keys before the vault landed are upgraded\r\n * transparently.\r\n */\r\nexport async function migratePlaintextSecrets(\r\n configPath: string,\r\n vault: SecretVault,\r\n): Promise<{ migrated: number; file: string }> {\r\n let raw: string;\r\n try {\r\n raw = await fsp.readFile(configPath, 'utf8');\r\n } catch {\r\n return { migrated: 0, file: configPath };\r\n }\r\n let parsed: unknown;\r\n try {\r\n parsed = JSON.parse(raw);\r\n } catch {\r\n return { migrated: 0, file: configPath };\r\n }\r\n const counter = { n: 0 };\r\n const migrated = walkCount(parsed, vault, counter);\r\n if (counter.n === 0) return { migrated: 0, file: configPath };\r\n // atomicWrite: runs on every boot for legacy users — torn write = wipe.\r\n await atomicWrite(configPath, JSON.stringify(migrated, null, 2), { mode: 0o600 });\r\n await restrictFilePermissions(configPath);\r\n return { migrated: counter.n, file: configPath };\r\n}\r\n\r\n/**\r\n * Restrict a file to owner-only access. On POSIX this is chmod 0o600.\r\n * On Windows, chmod is a no-op — we use icacls to remove inherited\r\n * permissions and grant only the current user. Failures are logged\r\n * but not thrown so callers are not blocked on unsupported platforms.\r\n */\r\nasync function restrictFilePermissions(filePath: string): Promise<void> {\r\n if (process.platform === 'win32') {\r\n try {\r\n const { execFile } = await import('node:child_process');\r\n const { promisify } = await import('node:util');\r\n const execFileAsync = promisify(execFile);\r\n // Remove inherited ACEs, grant full control only to current user.\r\n await execFileAsync('icacls', [filePath, '/inheritance:r', '/grant:r', `${process.env.USERNAME}:(F)`]);\r\n } catch {\r\n // Best-effort: icacls may not be available in all environments.\r\n console.warn(`[secret-vault] Could not restrict permissions on ${filePath} — config file may be readable by other users on this system.`);\r\n }\r\n } else {\r\n try {\r\n await fsp.chmod(filePath, 0o600);\r\n } catch {\r\n // Best-effort\r\n }\r\n }\r\n}\r\n\r\nfunction walkCount<T>(node: T, vault: SecretVault, counter: { n: number }): T {\r\n if (node === null || node === undefined) return node;\r\n if (typeof node !== 'object') return node;\r\n if (Array.isArray(node)) {\r\n return node.map((item) => walkCount(item, vault, counter)) as unknown as T;\r\n }\r\n const out: Record<string, unknown> = Object.create(null);\r\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\r\n if (typeof v === 'string' && isSecretField(k) && !vault.isEncrypted(v) && v.length > 0) {\r\n out[k] = vault.encrypt(v);\r\n counter.n++;\r\n } else if (typeof v === 'object' && v !== null) {\r\n out[k] = walkCount(v, vault, counter);\r\n } else {\r\n out[k] = v;\r\n }\r\n }\r\n return out as T;\r\n}\r\n\r\n/** Keys that, when written into a plain object, can poison the prototype\r\n * chain. We never want user config to carry these. */\r\nconst FORBIDDEN_PROTO_KEYS = new Set([\r\n '__proto__',\r\n 'constructor',\r\n 'prototype',\r\n '__defineGetter__',\r\n '__defineSetter__',\r\n '__lookupGetter__',\r\n '__lookupSetter__',\r\n]);\r\n\r\nfunction deepMerge<T extends Record<string, unknown>>(a: T, b: Record<string, unknown>): T {\r\n const out: Record<string, unknown> = { ...a };\r\n for (const [k, v] of Object.entries(b)) {\r\n if (FORBIDDEN_PROTO_KEYS.has(k)) continue;\r\n const existing = out[k];\r\n if (\r\n v !== null &&\r\n typeof v === 'object' &&\r\n !Array.isArray(v) &&\r\n existing !== null &&\r\n typeof existing === 'object' &&\r\n !Array.isArray(existing)\r\n ) {\r\n out[k] = deepMerge(existing as Record<string, unknown>, v as Record<string, unknown>);\r\n } else {\r\n out[k] = v;\r\n }\r\n }\r\n return out as T;\r\n}\r\n","import type { SecretVault } from '../types/secret-vault.js';\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 */\nexport function decryptConfigSecrets<T>(cfg: T, vault: SecretVault): T {\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 console.warn(\n `[secret-vault] Failed to decrypt \"${key}\":`,\n err instanceof Error ? err.message : err,\n );\n return '';\n }\n });\n}\n\nexport function encryptConfigSecrets<T>(cfg: T, vault: SecretVault): 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 // Use Object.create(null) to prevent prototype pollution — a crafted key\n // like \"__proto__\" in the input would otherwise corrupt Object.prototype.\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 */\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 * 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.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 * 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[] } | 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[] };\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[] } | 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[] };\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[] } | 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[] };\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","/**\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(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","export interface SafeParseResult<T> {\n ok: boolean;\n value?: T;\n error?: string;\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: err instanceof Error ? err.message : String(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: err instanceof Error ? err.message : String(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[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[i]!;\n if (c === '\"' && (i === 0 || s[i - 1] !== '\\\\')) {\n inString = !inString;\n chars.push(c);\n } else if (c === '/' && s[i + 1] === '/' && !inString) {\n // skip to end of line\n while (i < s.length && s[i] !== '\\n') i++;\n } else {\n chars.push(c);\n }\n i++;\n }\n return chars.join('');\n}\n","import * as path from 'node:path';\n\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 { hasDangerousCapabilityForSubagents } 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;\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;\n /** @deprecated Use `yoloDestructive`. */\n forceAllYolo?: boolean;\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;\n promptDelegate?: (\n tool: Tool,\n input: unknown,\n suggestedPattern: string,\n ) => Promise<'yes' | 'no' | 'always' | 'deny'>;\n inputReader?: InputReader;\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'];\n /** Pre-compiled wildcard patterns — rebuilt on reload for O(1) lookup. */\n private wildcardEntries: { pattern: string; value: TrustPolicy[string] }[] = [];\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 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 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 this.confirmDestructive = enabled;\n }\n\n /** Check whether destructive confirmation gate is active. */\n getConfirmDestructive(): boolean {\n return this.confirmDestructive;\n }\n\n /** @deprecated Use `setYoloDestructive`. */\n setForceAllYolo(enabled: boolean): void {\n this.setYoloDestructive(enabled);\n }\n\n /** @deprecated Use `getYoloDestructive`. */\n getForceAllYolo(): boolean {\n return this.getYoloDestructive();\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.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 subjectKey = `${tool.name}::${subject ?? tool.name}`;\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(subjectKey)) {\n return { permission: 'deny', source: 'deny', reason: 'session soft deny (user pressed no)' };\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(subjectKey)) {\n return {\n permission: 'auto',\n source: 'trust',\n reason: 'session soft allow (user pressed yes)',\n };\n }\n\n // 4. Deny — absolute\n if (entry?.deny && subject && matchAny(entry.deny, subject)) {\n return { permission: 'deny', source: 'deny', reason: 'matched deny pattern' };\n }\n if (tool.permission === 'deny') {\n return { permission: 'deny', source: 'default', reason: 'tool default deny' };\n }\n\n // 5. Allow (trust file)\n if (entry?.allow && subject && matchAny(entry.allow, subject)) {\n return { permission: 'auto', source: 'trust', reason: 'matched allow pattern' };\n }\n if (entry?.auto) {\n return { permission: 'auto', source: 'trust' };\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 return { permission: 'auto', source: 'yolo' };\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 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 if (tool.permission === 'auto' && !tool.mutating) {\n return { permission: 'auto', source: 'default' };\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 private isDestructiveYoloCall(tool: Tool, input: unknown, ctx: Context): boolean {\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 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 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 }\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 }\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 */\nexport class AutoApprovePermissionPolicy implements PermissionPolicy {\n /**\n * Legacy name-based denylist.\n * @deprecated Prefer declaring `capabilities` on the Tool and using capability-based checks.\n */\n private static readonly LEGACY_NAME_DENY = new Set([\n 'bash',\n 'write',\n 'edit',\n 'replace',\n 'scaffold',\n 'patch',\n 'install',\n 'exec',\n ]);\n\n // Note: hasDangerousCapabilityForSubagents is now the shared helper from capabilities.ts\n // The old private method was removed in favor of the centralized utility.\n\n /**\n * Tools from MCP servers (`mcp__<server>__<tool>`) are external code of\n * unknown capability — they may wrap a shell or filesystem. They are\n * fail-closed here: not auto-approved for subagents by default, so the\n * leader must allow them explicitly per-spawn.\n */\n private static isMcpTool(name: string): boolean {\n return name.startsWith('mcp__');\n }\n\n async evaluate(tool: Tool): Promise<PermissionDecision> {\n const hasDangerousCap = hasDangerousCapabilityForSubagents(tool);\n const legacyNameBlock = AutoApprovePermissionPolicy.LEGACY_NAME_DENY.has(tool.name);\n const isMcp = AutoApprovePermissionPolicy.isMcpTool(tool.name);\n\n const blocked = tool.permission === 'deny' || hasDangerousCap || legacyNameBlock || isMcp;\n\n if (blocked) {\n const reason = hasDangerousCap\n ? `tool declares dangerous capability (${tool.capabilities?.join(', ')}) — not auto-approved for subagents`\n : legacyNameBlock || isMcp\n ? `tool ${tool.name} is not auto-approved for subagents — ask the leader to allow it explicitly`\n : 'tool default deny';\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/types/secret-vault.ts","../../src/utils/atomic-write.ts","../../src/security/secret-vault.ts","../../src/security/config-secrets.ts","../../src/security/capabilities.ts","../../src/utils/glob-match.ts","../../src/utils/safe-json.ts","../../src/security/yolo-risk.ts","../../src/security/permission-policy.ts"],"names":["path","stat","resolve","randomBytes","path2","fsp","SECRET_KEY_PATTERN","NON_SECRET_OVERRIDES","isSecretField","relative","fs3"],"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 {\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 * 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\nexport class DefaultSecretScrubber implements SecretScrubber {\n scrub(text: string): string {\n if (!text) return text;\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 let out = text;\n for (const p of PATTERNS) {\n out = out.replace(p.regex, (_match, group1, group2) => {\n if (p.type === 'high_entropy_env' && group1 && group2) {\n return `${group1}=[REDACTED:${p.type}]`;\n }\n return `[REDACTED:${p.type}]`;\n });\n }\n return out;\n }\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","/**\n * SecretVault encrypts secrets-at-rest in config files. The wire format is\n * `enc:v1:<base64-iv>:<base64-tag>:<base64-ciphertext>`. Plaintext strings\n * (those that do not match this prefix) are passed through unchanged so that\n * existing configs and env-var-derived values keep working.\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}\n\nexport const ENCRYPTED_PREFIX = 'enc:v1:';\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;\n encoding?: BufferEncoding;\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\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","import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';\r\nimport * as fs from 'node:fs';\r\nimport * as fsp from 'node:fs/promises';\r\nimport * as path from 'node:path';\r\nimport type { SecretVault } from '../types/secret-vault.js';\r\nimport { ENCRYPTED_PREFIX } from '../types/secret-vault.js';\r\nimport { atomicWrite } from '../utils/atomic-write.js';\r\n\r\nexport interface SecretVaultOptions {\r\n /** Absolute path to the key file. Created with mode 0o600 if missing. */\r\n keyFile: string;\r\n}\r\n\r\nconst KEY_BYTES = 32;\r\nconst IV_BYTES = 12;\r\nconst TAG_BYTES = 16;\r\nconst ALGO = 'aes-256-gcm';\r\n\r\n/**\r\n * Default vault: AES-256-GCM with a key stored at `keyFile` (mode 0o600).\r\n * The key is loaded lazily on first encrypt/decrypt; if it does not exist,\r\n * a fresh one is generated. Decryption of plaintext values is a no-op so\r\n * legacy configs continue to work.\r\n */\r\nexport class DefaultSecretVault implements SecretVault {\r\n private readonly keyFile: string;\r\n private key?: Buffer;\r\n\r\n constructor(opts: SecretVaultOptions) {\r\n this.keyFile = opts.keyFile;\r\n }\r\n\r\n isEncrypted(value: string): boolean {\r\n return typeof value === 'string' && value.startsWith(ENCRYPTED_PREFIX);\r\n }\r\n\r\n encrypt(plaintext: string): string {\r\n if (this.isEncrypted(plaintext)) return plaintext;\r\n const key = this.loadOrCreateKey();\r\n const iv = randomBytes(IV_BYTES);\r\n const cipher = createCipheriv(ALGO, key, iv);\r\n const ct = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);\r\n const tag = cipher.getAuthTag();\r\n return `${ENCRYPTED_PREFIX}${iv.toString('base64')}:${tag.toString('base64')}:${ct.toString('base64')}`;\r\n }\r\n\r\n decrypt(value: string): string {\r\n if (!this.isEncrypted(value)) return value;\r\n const rest = value.slice(ENCRYPTED_PREFIX.length);\r\n const parts = rest.split(':');\r\n if (parts.length !== 3) {\r\n throw new Error('SecretVault: malformed encrypted value');\r\n }\r\n const [ivB64, tagB64, ctB64] = parts as [string, string, string];\r\n const iv = Buffer.from(ivB64, 'base64');\r\n const tag = Buffer.from(tagB64, 'base64');\r\n const ct = Buffer.from(ctB64, 'base64');\r\n if (iv.length !== IV_BYTES) throw new Error('SecretVault: bad IV length');\r\n if (tag.length !== TAG_BYTES) throw new Error('SecretVault: bad tag length');\r\n const key = this.loadOrCreateKey();\r\n const decipher = createDecipheriv(ALGO, key, iv);\r\n decipher.setAuthTag(tag);\r\n const pt = Buffer.concat([decipher.update(ct), decipher.final()]);\r\n return pt.toString('utf8');\r\n }\r\n\r\n private loadOrCreateKey(): Buffer {\r\n if (this.key) return this.key;\r\n try {\r\n const buf = fs.readFileSync(this.keyFile);\r\n if (buf.length !== KEY_BYTES) {\r\n // A wrong-size key is not ENOENT — the file is corrupted or was\r\n // tampered with. Throwing instead of falling through to create a\r\n // new key protects all secrets encrypted under this key; the user\r\n // can remove the file manually to generate a fresh key.\r\n throw new Error(\r\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\r\n `(expected ${KEY_BYTES}). Remove it manually to generate a new key.`,\r\n );\r\n }\r\n this.key = buf;\r\n return this.key;\r\n } catch (err) {\r\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\r\n }\r\n // Create a fresh key. Use sync APIs so the constructor-free getter\r\n // remains synchronous from the caller's perspective.\r\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\r\n const key = randomBytes(KEY_BYTES);\r\n // Use exclusive-create flag 'wx' to prevent races: if two processes race\r\n // to create the key file, only one succeeds and the loser gets EEXIST.\r\n try {\r\n fs.writeFileSync(this.keyFile, key, { mode: 0o600, flag: 'wx' });\r\n } catch (err) {\r\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST') throw err;\r\n // Another process won the race — re-read what they wrote.\r\n const buf = fs.readFileSync(this.keyFile);\r\n if (buf.length !== KEY_BYTES) {\r\n // A wrong-size key is not ENOENT — the file is corrupted or was\r\n // tampered with. Throwing instead of falling through to create a\r\n // new key protects all secrets encrypted under this key; the user\r\n // can remove the file manually to generate a fresh key.\r\n throw new Error(\r\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\r\n `(expected ${KEY_BYTES}). Remove it manually to generate a new key.`,\r\n );\r\n }\r\n this.key = buf;\r\n return this.key;\r\n }\r\n this.key = key;\r\n return key;\r\n }\r\n}\r\n\r\n/**\r\n * Walk a Config-shaped object and decrypt any apiKey-like fields in place,\r\n * returning a new object. Used by the config loader so the rest of the\r\n * system never has to know about the wire format.\r\n */\r\nexport function decryptConfigSecrets<T>(cfg: T, vault: SecretVault): T {\r\n // A single corrupted/malformed encrypted field should not kill the entire\r\n // config load. Swallow per-field decrypt errors (zero the field so callers\r\n // see \"missing key\" instead of holding ciphertext) and surface a warning.\r\n return walk(cfg, vault, (v, key) => {\r\n try {\r\n return vault.decrypt(v);\r\n } catch (err) {\r\n console.warn(\r\n `[secret-vault] Failed to decrypt \"${key}\":`,\r\n err instanceof Error ? err.message : err,\r\n );\r\n return '';\r\n }\r\n });\r\n}\r\n\r\nexport function encryptConfigSecrets<T>(cfg: T, vault: SecretVault): T {\r\n return walk(cfg, vault, (v) => vault.encrypt(v));\r\n}\r\n\r\nfunction walk<T>(node: T, vault: SecretVault, transform: (s: string, key: string) => string): T {\r\n if (node === null || node === undefined) return node;\r\n if (typeof node !== 'object') return node;\r\n if (Array.isArray(node)) {\r\n return node.map((item) => walk(item, vault, transform)) as unknown as T;\r\n }\r\n const out: Record<string, unknown> = Object.create(null);\r\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\r\n if (typeof v === 'string' && isSecretField(k)) {\r\n out[k] = transform(v, k);\r\n } else if (typeof v === 'object' && v !== null) {\r\n out[k] = walk(v, vault, transform);\r\n } else {\r\n out[k] = v;\r\n }\r\n }\r\n return out as T;\r\n}\r\n\r\n/**\r\n * A key is treated as secret-bearing if its name (case-insensitive) contains\r\n * one of these tokens. Captures common variants like `apiKey`, `authToken`,\r\n * `refreshToken`, `sessionKey`, `password`, `client_secret`, `bearer`, etc.\r\n * Use a named field with `isSecret: false` annotation if you must opt out —\r\n * see `NON_SECRET_OVERRIDES` below.\r\n */\r\nconst SECRET_KEY_PATTERN =\r\n /(?:apikey|api_key|authtoken|auth_token|bearer|secret|password|passwd|pwd|refreshtoken|refresh_token|sessionkey|session_key|access[_-]?token|private[_-]?key)/i;\r\n\r\n// Field names that contain the literal substring \"key\" but are not secrets.\r\n// Keep this list short; the substring rule itself is intentionally narrow.\r\nconst NON_SECRET_OVERRIDES = new Set(['publickey', 'public_key']);\r\n\r\nfunction isSecretField(name: string): boolean {\r\n const lc = name.toLowerCase();\r\n if (NON_SECRET_OVERRIDES.has(lc)) return false;\r\n return SECRET_KEY_PATTERN.test(lc);\r\n}\r\n\r\n/**\r\n * Re-write `~/.wrongstack/config.json` (or any path) with all secret-bearing\r\n * fields encrypted. Used by the `wstack auth` subcommand.\r\n */\r\nexport async function rewriteConfigEncrypted(\r\n configPath: string,\r\n vault: SecretVault,\r\n patch?: Record<string, unknown>,\r\n): Promise<void> {\r\n let current: Record<string, unknown> = {};\r\n try {\r\n const raw = await fsp.readFile(configPath, 'utf8');\r\n current = JSON.parse(raw) as Record<string, unknown>;\r\n } catch {\r\n // start from empty\r\n }\r\n const merged = deepMerge(current, patch ?? {});\r\n const encrypted = encryptConfigSecrets(merged, vault);\r\n await fsp.mkdir(path.dirname(configPath), { recursive: true });\r\n // atomicWrite: torn write here would erase every saved encrypted API key.\r\n await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 0o600 });\r\n await restrictFilePermissions(configPath);\r\n}\r\n\r\n/**\r\n * Scan a config file on disk for plaintext secret-bearing fields and\r\n * rewrite the file with them encrypted in place. Returns a count of how\r\n * many fields were migrated. Idempotent — calling on a fully-encrypted\r\n * file is a no-op and writes nothing. Used by the CLI on every boot so\r\n * users who had plaintext keys before the vault landed are upgraded\r\n * transparently.\r\n */\r\nexport async function migratePlaintextSecrets(\r\n configPath: string,\r\n vault: SecretVault,\r\n): Promise<{ migrated: number; file: string }> {\r\n let raw: string;\r\n try {\r\n raw = await fsp.readFile(configPath, 'utf8');\r\n } catch {\r\n return { migrated: 0, file: configPath };\r\n }\r\n let parsed: unknown;\r\n try {\r\n parsed = JSON.parse(raw);\r\n } catch {\r\n return { migrated: 0, file: configPath };\r\n }\r\n const counter = { n: 0 };\r\n const migrated = walkCount(parsed, vault, counter);\r\n if (counter.n === 0) return { migrated: 0, file: configPath };\r\n // atomicWrite: runs on every boot for legacy users — torn write = wipe.\r\n await atomicWrite(configPath, JSON.stringify(migrated, null, 2), { mode: 0o600 });\r\n await restrictFilePermissions(configPath);\r\n return { migrated: counter.n, file: configPath };\r\n}\r\n\r\n/**\r\n * Restrict a file to owner-only access. On POSIX this is chmod 0o600.\r\n * On Windows, chmod is a no-op — we use icacls to remove inherited\r\n * permissions and grant only the current user. Failures are logged\r\n * but not thrown so callers are not blocked on unsupported platforms.\r\n */\r\nasync function restrictFilePermissions(filePath: string): Promise<void> {\r\n if (process.platform === 'win32') {\r\n try {\r\n const { execFile } = await import('node:child_process');\r\n const { promisify } = await import('node:util');\r\n const execFileAsync = promisify(execFile);\r\n // Remove inherited ACEs, grant full control only to current user.\r\n await execFileAsync('icacls', [filePath, '/inheritance:r', '/grant:r', `${process.env.USERNAME}:(F)`]);\r\n } catch {\r\n // Best-effort: icacls may not be available in all environments.\r\n console.warn(`[secret-vault] Could not restrict permissions on ${filePath} — config file may be readable by other users on this system.`);\r\n }\r\n } else {\r\n try {\r\n await fsp.chmod(filePath, 0o600);\r\n } catch {\r\n // Best-effort\r\n }\r\n }\r\n}\r\n\r\nfunction walkCount<T>(node: T, vault: SecretVault, counter: { n: number }): T {\r\n if (node === null || node === undefined) return node;\r\n if (typeof node !== 'object') return node;\r\n if (Array.isArray(node)) {\r\n return node.map((item) => walkCount(item, vault, counter)) as unknown as T;\r\n }\r\n const out: Record<string, unknown> = Object.create(null);\r\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\r\n if (typeof v === 'string' && isSecretField(k) && !vault.isEncrypted(v) && v.length > 0) {\r\n out[k] = vault.encrypt(v);\r\n counter.n++;\r\n } else if (typeof v === 'object' && v !== null) {\r\n out[k] = walkCount(v, vault, counter);\r\n } else {\r\n out[k] = v;\r\n }\r\n }\r\n return out as T;\r\n}\r\n\r\n/** Keys that, when written into a plain object, can poison the prototype\r\n * chain. We never want user config to carry these. */\r\nconst FORBIDDEN_PROTO_KEYS = new Set([\r\n '__proto__',\r\n 'constructor',\r\n 'prototype',\r\n '__defineGetter__',\r\n '__defineSetter__',\r\n '__lookupGetter__',\r\n '__lookupSetter__',\r\n]);\r\n\r\nfunction deepMerge<T extends Record<string, unknown>>(a: T, b: Record<string, unknown>): T {\r\n const out: Record<string, unknown> = { ...a };\r\n for (const [k, v] of Object.entries(b)) {\r\n if (FORBIDDEN_PROTO_KEYS.has(k)) continue;\r\n const existing = out[k];\r\n if (\r\n v !== null &&\r\n typeof v === 'object' &&\r\n !Array.isArray(v) &&\r\n existing !== null &&\r\n typeof existing === 'object' &&\r\n !Array.isArray(existing)\r\n ) {\r\n out[k] = deepMerge(existing as Record<string, unknown>, v as Record<string, unknown>);\r\n } else {\r\n out[k] = v;\r\n }\r\n }\r\n return out as T;\r\n}\r\n","import type { SecretVault } from '../types/secret-vault.js';\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 */\nexport function decryptConfigSecrets<T>(cfg: T, vault: SecretVault): T {\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 console.warn(\n `[secret-vault] Failed to decrypt \"${key}\":`,\n err instanceof Error ? err.message : err,\n );\n return '';\n }\n });\n}\n\nexport function encryptConfigSecrets<T>(cfg: T, vault: SecretVault): 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 // Use Object.create(null) to prevent prototype pollution — a crafted key\n // like \"__proto__\" in the input would otherwise corrupt Object.prototype.\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 */\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 * 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.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 * 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[] } | 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[] };\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[] } | 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[] };\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[] } | 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[] };\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","/**\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(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","export interface SafeParseResult<T> {\n ok: boolean;\n value?: T;\n error?: string;\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: err instanceof Error ? err.message : String(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: err instanceof Error ? err.message : String(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[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[i]!;\n if (c === '\"' && (i === 0 || s[i - 1] !== '\\\\')) {\n inString = !inString;\n chars.push(c);\n } else if (c === '/' && s[i + 1] === '/' && !inString) {\n // skip to end of line\n while (i < s.length && s[i] !== '\\n') i++;\n } else {\n chars.push(c);\n }\n i++;\n }\n return chars.join('');\n}\n","import * as path from 'node:path';\n\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 { hasDangerousCapabilityForSubagents } 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;\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;\n /** @deprecated Use `yoloDestructive`. */\n forceAllYolo?: boolean;\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;\n promptDelegate?: (\n tool: Tool,\n input: unknown,\n suggestedPattern: string,\n ) => Promise<'yes' | 'no' | 'always' | 'deny'>;\n inputReader?: InputReader;\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'];\n /** Pre-compiled wildcard patterns — rebuilt on reload for O(1) lookup. */\n private wildcardEntries: { pattern: string; value: TrustPolicy[string] }[] = [];\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 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 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 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.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 subjectKey = `${tool.name}::${subject ?? tool.name}`;\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(subjectKey)) {\n return { permission: 'deny', source: 'deny', reason: 'session soft deny (user pressed no)' };\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(subjectKey)) {\n return {\n permission: 'auto',\n source: 'trust',\n reason: 'session soft allow (user pressed yes)',\n };\n }\n\n // 4. Deny — absolute\n if (entry?.deny && subject && matchAny(entry.deny, subject)) {\n return { permission: 'deny', source: 'deny', reason: 'matched deny pattern' };\n }\n if (tool.permission === 'deny') {\n return { permission: 'deny', source: 'default', reason: 'tool default deny' };\n }\n\n // 5. Allow (trust file)\n if (entry?.allow && subject && matchAny(entry.allow, subject)) {\n return { permission: 'auto', source: 'trust', reason: 'matched allow pattern' };\n }\n if (entry?.auto) {\n return { permission: 'auto', source: 'trust' };\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 return { permission: 'auto', source: 'yolo' };\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 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 if (tool.permission === 'auto' && !tool.mutating) {\n return { permission: 'auto', source: 'default' };\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 private isDestructiveYoloCall(tool: Tool, input: unknown, ctx: Context): boolean {\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 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 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 }\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 }\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 */\nexport class AutoApprovePermissionPolicy implements PermissionPolicy {\n /**\n * Legacy name-based denylist.\n * @deprecated Prefer declaring `capabilities` on the Tool and using capability-based checks.\n */\n private static readonly LEGACY_NAME_DENY = new Set([\n 'bash',\n 'write',\n 'edit',\n 'replace',\n 'scaffold',\n 'patch',\n 'install',\n 'exec',\n ]);\n\n // Note: hasDangerousCapabilityForSubagents is now the shared helper from capabilities.ts\n // The old private method was removed in favor of the centralized utility.\n\n /**\n * Tools from MCP servers (`mcp__<server>__<tool>`) are external code of\n * unknown capability — they may wrap a shell or filesystem. They are\n * fail-closed here: not auto-approved for subagents by default, so the\n * leader must allow them explicitly per-spawn.\n */\n private static isMcpTool(name: string): boolean {\n return name.startsWith('mcp__');\n }\n\n async evaluate(tool: Tool): Promise<PermissionDecision> {\n const hasDangerousCap = hasDangerousCapabilityForSubagents(tool);\n const legacyNameBlock = AutoApprovePermissionPolicy.LEGACY_NAME_DENY.has(tool.name);\n const isMcp = AutoApprovePermissionPolicy.isMcpTool(tool.name);\n\n const blocked = tool.permission === 'deny' || hasDangerousCap || legacyNameBlock || isMcp;\n\n if (blocked) {\n const reason = hasDangerousCap\n ? `tool declares dangerous capability (${tool.capabilities?.join(', ')}) — not auto-approved for subagents`\n : legacyNameBlock || isMcp\n ? `tool ${tool.name} is not auto-approved for subagents — ask the leader to allow it explicitly`\n : 'tool default deny';\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"]}
@@ -29,6 +29,7 @@ var MAX_TARBALL_SIZE = 50 * 1024 * 1024;
29
29
  async function downloadGitHubTarball(parsed) {
30
30
  const url = `https://api.github.com/repos/${parsed.owner}/${parsed.repo}/tarball/${parsed.ref}`;
31
31
  const response = await fetch(url, {
32
+ signal: AbortSignal.timeout(3e4),
32
33
  headers: {
33
34
  Accept: "application/vnd.github+json",
34
35
  "User-Agent": "wrongstack-skill-installer"