{"version":3,"sources":["../../src/lib/config/defaults.ts","../../src/lib/wizard/html.ts","../../src/lib/wizard/server.ts","../../src/lib/wizard/index.ts","../../src/extensions/index.ts","../../src/lib/config/loader.ts","../../src/lib/config/schema.ts","../../src/lib/identity/env-provider.ts","../../src/lib/identity/local-provider.ts","../../src/lib/identity/chain.ts","../../src/lib/policy/yaml-engine.ts","../../src/lib/bash/patterns.ts","../../src/lib/bash/classifier.ts","../../src/lib/audit/logger.ts","../../src/lib/audit/sinks/jsonl.ts","../../src/lib/audit/sinks/webhook.ts","../../src/lib/hitl/cli-approver.ts","../../src/lib/hitl/webhook-approver.ts","../../src/lib/hitl/approval.ts","../../src/lib/budget/tracker.ts","../../src/lib/config/watcher.ts","../../src/lib/dlp/patterns.ts","../../src/lib/dlp/scanner.ts","../../src/lib/dlp/masker.ts","../../src/lib/deps/parser.ts","../../src/lib/deps/registry.ts","../../src/lib/deps/vulnerabilities.ts","../../src/lib/deps/levenshtein.ts","../../src/lib/deps/allowlist.ts","../../src/lib/deps/risk.ts","../../src/lib/deps/guardian.ts"],"sourcesContent":["import type { GovernanceConfig } from './schema.js';\n\nexport const DEFAULTS: GovernanceConfig = {\n  auth: {\n    provider: 'env',\n    env: {\n      user_var: 'PI_GOV_USER',\n      role_var: 'PI_GOV_ROLE',\n      org_unit_var: 'PI_GOV_ORG_UNIT',\n    },\n  },\n  policy: {\n    engine: 'yaml',\n    yaml: {\n      rules_file: './governance-rules.yaml',\n    },\n  },\n  templates: {\n    directory: './templates/',\n    default: 'project-lead',\n  },\n  hitl: {\n    default_mode: 'supervised',\n    approval_channel: 'cli',\n    timeout_seconds: 300,\n  },\n  audit: {\n    sinks: [{ type: 'jsonl', path: '~/.pi/agent/audit.jsonl' }],\n  },\n  dlp: {\n    enabled: true,\n    mode: 'audit',\n    on_input: 'block',\n    on_output: 'mask',\n    masking: {\n      strategy: 'partial',\n      show_chars: 4,\n      placeholder: '***',\n    },\n    severity_threshold: 'low',\n    built_in: {\n      secrets: true,\n      pii: true,\n    },\n  },\n};\n","export const WIZARD_HTML: string = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Pi Governance — Setup Wizard</title>\n<style>\n  :root {\n    --bg: #f8f9fa;\n    --bg-surface: #ffffff;\n    --bg-surface-alt: #f1f3f5;\n    --bg-code: #e9ecef;\n    --text: #212529;\n    --text-muted: #6c757d;\n    --text-inverse: #ffffff;\n    --border: #dee2e6;\n    --border-focus: #4263eb;\n    --primary: #4263eb;\n    --primary-hover: #3b5bdb;\n    --primary-subtle: #dbe4ff;\n    --success: #2f9e44;\n    --success-subtle: #d3f9d8;\n    --danger: #e03131;\n    --danger-subtle: #ffe3e3;\n    --warning: #f08c00;\n    --warning-subtle: #fff3bf;\n    --radius: 8px;\n    --radius-sm: 4px;\n    --shadow: 0 1px 3px rgba(0,0,0,0.08);\n    --shadow-lg: 0 4px 12px rgba(0,0,0,0.1);\n    --font-mono: 'SF Mono', 'Cascadia Code', 'Fira Code', monospace;\n    --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;\n    --transition: 150ms ease;\n  }\n\n  @media (prefers-color-scheme: dark) {\n    :root {\n      --bg: #1a1b1e;\n      --bg-surface: #25262b;\n      --bg-surface-alt: #2c2e33;\n      --bg-code: #2c2e33;\n      --text: #c1c2c5;\n      --text-muted: #909296;\n      --text-inverse: #1a1b1e;\n      --border: #373a40;\n      --border-focus: #5c7cfa;\n      --primary: #5c7cfa;\n      --primary-hover: #748ffc;\n      --primary-subtle: #1b2559;\n      --success: #51cf66;\n      --success-subtle: #0b3d1a;\n      --danger: #ff6b6b;\n      --danger-subtle: #3d0b0b;\n      --warning: #fcc419;\n      --warning-subtle: #3d2e00;\n      --shadow: 0 1px 3px rgba(0,0,0,0.3);\n      --shadow-lg: 0 4px 12px rgba(0,0,0,0.4);\n    }\n  }\n\n  * { margin: 0; padding: 0; box-sizing: border-box; }\n\n  body {\n    font-family: var(--font-sans);\n    background: var(--bg);\n    color: var(--text);\n    line-height: 1.6;\n    min-height: 100vh;\n  }\n\n  .layout {\n    display: grid;\n    grid-template-columns: 1fr 420px;\n    gap: 0;\n    min-height: 100vh;\n  }\n\n  @media (max-width: 1024px) {\n    .layout { grid-template-columns: 1fr; }\n    .preview-panel { display: none; }\n  }\n\n  /* --- Left column: Form --- */\n  .form-column {\n    padding: 32px 40px 80px;\n    overflow-y: auto;\n    max-height: 100vh;\n  }\n\n  .logo {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    margin-bottom: 8px;\n  }\n\n  .logo-icon {\n    width: 36px; height: 36px;\n    background: var(--primary);\n    border-radius: var(--radius);\n    display: flex; align-items: center; justify-content: center;\n    color: var(--text-inverse);\n    font-weight: 700; font-size: 18px;\n  }\n\n  .logo-text {\n    font-size: 20px;\n    font-weight: 700;\n    color: var(--text);\n  }\n\n  .logo-text span { color: var(--text-muted); font-weight: 400; }\n\n  h1 {\n    font-size: 28px;\n    font-weight: 700;\n    margin: 24px 0 8px;\n  }\n\n  .subtitle {\n    color: var(--text-muted);\n    font-size: 15px;\n    margin-bottom: 32px;\n  }\n\n  /* Sections */\n  .section {\n    background: var(--bg-surface);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n    padding: 24px;\n    margin-bottom: 20px;\n    box-shadow: var(--shadow);\n  }\n\n  .section-header {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    margin-bottom: 16px;\n    cursor: pointer;\n    user-select: none;\n  }\n\n  .section-header h2 {\n    font-size: 16px;\n    font-weight: 600;\n    flex: 1;\n  }\n\n  .section-badge {\n    font-size: 11px;\n    padding: 2px 8px;\n    border-radius: 10px;\n    font-weight: 600;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n  }\n\n  .badge-required { background: var(--danger-subtle); color: var(--danger); }\n  .badge-optional { background: var(--primary-subtle); color: var(--primary); }\n\n  .section-icon {\n    width: 32px; height: 32px;\n    border-radius: var(--radius-sm);\n    display: flex; align-items: center; justify-content: center;\n    font-size: 16px;\n    flex-shrink: 0;\n  }\n\n  .section-body { display: block; }\n  .section.collapsed .section-body { display: none; }\n  .section-chevron {\n    transition: transform var(--transition);\n    color: var(--text-muted);\n    font-size: 12px;\n  }\n  .section.collapsed .section-chevron { transform: rotate(-90deg); }\n\n  /* Form elements */\n  label {\n    display: block;\n    font-size: 13px;\n    font-weight: 600;\n    color: var(--text);\n    margin-bottom: 4px;\n  }\n\n  .label-hint {\n    font-weight: 400;\n    color: var(--text-muted);\n    font-size: 12px;\n  }\n\n  input[type=\"text\"],\n  input[type=\"number\"],\n  select {\n    width: 100%;\n    padding: 8px 12px;\n    border: 1px solid var(--border);\n    border-radius: var(--radius-sm);\n    background: var(--bg-surface);\n    color: var(--text);\n    font-size: 14px;\n    font-family: var(--font-sans);\n    transition: border-color var(--transition);\n    outline: none;\n  }\n\n  input:focus, select:focus {\n    border-color: var(--border-focus);\n    box-shadow: 0 0 0 2px var(--primary-subtle);\n  }\n\n  .field { margin-bottom: 16px; }\n\n  .field-row {\n    display: grid;\n    grid-template-columns: 1fr 1fr;\n    gap: 12px;\n  }\n\n  .field-row-3 {\n    display: grid;\n    grid-template-columns: 1fr 1fr 1fr;\n    gap: 12px;\n  }\n\n  /* Toggle switch */\n  .toggle-row {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    margin-bottom: 12px;\n  }\n\n  .toggle {\n    position: relative;\n    width: 40px; height: 22px;\n    flex-shrink: 0;\n  }\n\n  .toggle input { display: none; }\n\n  .toggle-slider {\n    position: absolute;\n    inset: 0;\n    background: var(--border);\n    border-radius: 11px;\n    cursor: pointer;\n    transition: background var(--transition);\n  }\n\n  .toggle-slider::before {\n    content: '';\n    position: absolute;\n    width: 16px; height: 16px;\n    left: 3px; top: 3px;\n    background: white;\n    border-radius: 50%;\n    transition: transform var(--transition);\n  }\n\n  .toggle input:checked + .toggle-slider {\n    background: var(--primary);\n  }\n\n  .toggle input:checked + .toggle-slider::before {\n    transform: translateX(18px);\n  }\n\n  .toggle-label {\n    font-size: 14px;\n    font-weight: 500;\n  }\n\n  /* Role cards */\n  .role-grid {\n    display: grid;\n    grid-template-columns: 1fr 1fr;\n    gap: 12px;\n  }\n\n  .role-card {\n    border: 2px solid var(--border);\n    border-radius: var(--radius);\n    padding: 16px;\n    cursor: pointer;\n    transition: all var(--transition);\n    position: relative;\n  }\n\n  .role-card:hover { border-color: var(--primary); }\n\n  .role-card.selected {\n    border-color: var(--primary);\n    background: var(--primary-subtle);\n  }\n\n  .role-card-check {\n    position: absolute;\n    top: 12px; right: 12px;\n    width: 20px; height: 20px;\n    border: 2px solid var(--border);\n    border-radius: 4px;\n    display: flex; align-items: center; justify-content: center;\n    font-size: 12px;\n    color: transparent;\n    transition: all var(--transition);\n  }\n\n  .role-card.selected .role-card-check {\n    background: var(--primary);\n    border-color: var(--primary);\n    color: white;\n  }\n\n  .role-name {\n    font-weight: 600;\n    font-size: 14px;\n    margin-bottom: 4px;\n  }\n\n  .role-desc {\n    font-size: 12px;\n    color: var(--text-muted);\n    margin-bottom: 8px;\n  }\n\n  .role-tags {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 4px;\n  }\n\n  .role-tag {\n    font-size: 11px;\n    padding: 1px 6px;\n    border-radius: 3px;\n    background: var(--bg-surface-alt);\n    color: var(--text-muted);\n    font-family: var(--font-mono);\n  }\n\n  .role-details {\n    display: none;\n    margin-top: 12px;\n    padding-top: 12px;\n    border-top: 1px solid var(--border);\n  }\n\n  .role-card.selected .role-details { display: block; }\n\n  /* Chip selector */\n  .chip-group {\n    display: flex;\n    gap: 6px;\n    flex-wrap: wrap;\n    margin-bottom: 12px;\n  }\n\n  .chip {\n    padding: 5px 14px;\n    border: 1px solid var(--border);\n    border-radius: 16px;\n    font-size: 13px;\n    cursor: pointer;\n    transition: all var(--transition);\n    background: var(--bg-surface);\n    color: var(--text);\n  }\n\n  .chip:hover { border-color: var(--primary); }\n\n  .chip.active {\n    background: var(--primary);\n    border-color: var(--primary);\n    color: var(--text-inverse);\n  }\n\n  /* Pattern list */\n  .pattern-list { margin-top: 12px; }\n\n  .pattern-item {\n    display: grid;\n    grid-template-columns: 1fr 1.5fr auto auto;\n    gap: 8px;\n    align-items: center;\n    margin-bottom: 8px;\n  }\n\n  .pattern-item input, .pattern-item select {\n    font-size: 13px;\n    padding: 6px 8px;\n  }\n\n  .btn-remove {\n    background: none;\n    border: none;\n    color: var(--danger);\n    cursor: pointer;\n    font-size: 18px;\n    padding: 4px;\n    line-height: 1;\n  }\n\n  .btn-add {\n    background: none;\n    border: 1px dashed var(--border);\n    border-radius: var(--radius-sm);\n    padding: 6px 14px;\n    color: var(--primary);\n    cursor: pointer;\n    font-size: 13px;\n    font-weight: 500;\n    transition: all var(--transition);\n  }\n\n  .btn-add:hover {\n    border-color: var(--primary);\n    background: var(--primary-subtle);\n  }\n\n  /* Allowlist */\n  .allowlist-item {\n    display: flex;\n    gap: 8px;\n    margin-bottom: 8px;\n  }\n\n  .allowlist-item input { flex: 1; font-size: 13px; padding: 6px 8px; }\n\n  /* Sink list */\n  .sink-item {\n    background: var(--bg-surface-alt);\n    border-radius: var(--radius-sm);\n    padding: 12px;\n    margin-bottom: 8px;\n    position: relative;\n  }\n\n  .sink-item .btn-remove {\n    position: absolute;\n    top: 8px; right: 8px;\n  }\n\n  /* --- Right column: Preview --- */\n  .preview-panel {\n    background: var(--bg-surface-alt);\n    border-left: 1px solid var(--border);\n    padding: 24px;\n    display: flex;\n    flex-direction: column;\n    position: sticky;\n    top: 0;\n    height: 100vh;\n    overflow: hidden;\n  }\n\n  .preview-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 16px;\n    flex-shrink: 0;\n  }\n\n  .preview-header h3 {\n    font-size: 14px;\n    font-weight: 600;\n  }\n\n  .preview-tabs {\n    display: flex;\n    gap: 4px;\n    margin-bottom: 12px;\n    flex-shrink: 0;\n  }\n\n  .preview-tab {\n    padding: 4px 12px;\n    font-size: 12px;\n    border: 1px solid var(--border);\n    border-radius: var(--radius-sm);\n    background: var(--bg-surface);\n    cursor: pointer;\n    color: var(--text-muted);\n    transition: all var(--transition);\n  }\n\n  .preview-tab.active {\n    background: var(--primary);\n    border-color: var(--primary);\n    color: var(--text-inverse);\n  }\n\n  .preview-content {\n    flex: 1;\n    overflow-y: auto;\n    background: var(--bg-surface);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n    padding: 16px;\n  }\n\n  .preview-content pre {\n    font-family: var(--font-mono);\n    font-size: 12px;\n    line-height: 1.5;\n    white-space: pre;\n    color: var(--text);\n    margin: 0;\n  }\n\n  /* Bottom bar */\n  .bottom-bar {\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    right: 420px;\n    padding: 16px 40px;\n    background: var(--bg-surface);\n    border-top: 1px solid var(--border);\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    z-index: 100;\n    box-shadow: 0 -2px 8px rgba(0,0,0,0.06);\n  }\n\n  @media (max-width: 1024px) {\n    .bottom-bar { right: 0; }\n  }\n\n  .btn-primary {\n    padding: 10px 28px;\n    background: var(--primary);\n    color: var(--text-inverse);\n    border: none;\n    border-radius: var(--radius);\n    font-size: 14px;\n    font-weight: 600;\n    cursor: pointer;\n    transition: background var(--transition);\n  }\n\n  .btn-primary:hover { background: var(--primary-hover); }\n  .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }\n\n  .btn-secondary {\n    padding: 10px 20px;\n    background: var(--bg-surface);\n    color: var(--text);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n    font-size: 14px;\n    font-weight: 500;\n    cursor: pointer;\n    transition: all var(--transition);\n  }\n\n  .btn-secondary:hover { border-color: var(--primary); color: var(--primary); }\n\n  .save-status {\n    font-size: 13px;\n    color: var(--text-muted);\n  }\n\n  .save-status.success { color: var(--success); }\n  .save-status.error { color: var(--danger); }\n\n  /* Toast */\n  .toast {\n    position: fixed;\n    top: 20px;\n    right: 20px;\n    padding: 12px 20px;\n    border-radius: var(--radius);\n    font-size: 14px;\n    font-weight: 500;\n    z-index: 1000;\n    box-shadow: var(--shadow-lg);\n    transform: translateY(-10px);\n    opacity: 0;\n    transition: all 300ms ease;\n    pointer-events: none;\n  }\n\n  .toast.visible { transform: translateY(0); opacity: 1; pointer-events: auto; }\n  .toast.success { background: var(--success); color: white; }\n  .toast.error { background: var(--danger); color: white; }\n\n  /* Helpers */\n  .help-text {\n    font-size: 12px;\n    color: var(--text-muted);\n    margin-top: 4px;\n  }\n\n  .divider {\n    border: none;\n    border-top: 1px solid var(--border);\n    margin: 16px 0;\n  }\n\n  .hidden { display: none !important; }\n</style>\n</head>\n<body>\n<div class=\"layout\">\n  <!-- ═══════════ LEFT: FORM ═══════════ -->\n  <div class=\"form-column\">\n    <div class=\"logo\">\n      <div class=\"logo-icon\">G</div>\n      <div class=\"logo-text\">Pi Governance <span>Setup Wizard</span></div>\n    </div>\n\n    <h1>Configure your governance policy</h1>\n    <p class=\"subtitle\">\n      AI coding agents are powerful but need guardrails. This wizard generates a\n      <code>governance.yaml</code> and <code>governance-rules.yaml</code> to control\n      tool access, bash safety, data-loss prevention, human approvals, and audit logging.\n    </p>\n\n    <!-- ── 1. Roles ── -->\n    <div class=\"section\" id=\"sec-roles\">\n      <div class=\"section-header\" onclick=\"toggleSection('sec-roles')\">\n        <div class=\"section-icon\" style=\"background:var(--primary-subtle);color:var(--primary)\">&#x1f465;</div>\n        <h2>Roles</h2>\n        <span class=\"section-badge badge-required\">Required</span>\n        <span class=\"section-chevron\">&#9660;</span>\n      </div>\n      <div class=\"section-body\">\n        <p class=\"help-text\" style=\"margin-bottom:12px\">Select the roles your team needs. Each role defines tool access, execution mode, and approval rules.</p>\n        <div class=\"role-grid\" id=\"role-grid\"></div>\n      </div>\n    </div>\n\n    <!-- ── 2. DLP ── -->\n    <div class=\"section\" id=\"sec-dlp\">\n      <div class=\"section-header\" onclick=\"toggleSection('sec-dlp')\">\n        <div class=\"section-icon\" style=\"background:var(--warning-subtle);color:var(--warning)\">&#x1f6e1;</div>\n        <h2>Data Loss Prevention</h2>\n        <span class=\"section-badge badge-optional\">Optional</span>\n        <span class=\"section-chevron\">&#9660;</span>\n      </div>\n      <div class=\"section-body\">\n        <div class=\"toggle-row\">\n          <label class=\"toggle\"><input type=\"checkbox\" id=\"dlp-enabled\" checked onchange=\"updatePreview()\"><span class=\"toggle-slider\"></span></label>\n          <span class=\"toggle-label\">Enable DLP scanning</span>\n        </div>\n\n        <div id=\"dlp-options\">\n          <div class=\"field\">\n            <label>Default Mode</label>\n            <div class=\"chip-group\" id=\"dlp-mode\">\n              <span class=\"chip active\" data-value=\"audit\" onclick=\"selectChip(this)\">Audit</span>\n              <span class=\"chip\" data-value=\"mask\" onclick=\"selectChip(this)\">Mask</span>\n              <span class=\"chip\" data-value=\"block\" onclick=\"selectChip(this)\">Block</span>\n            </div>\n          </div>\n\n          <div class=\"field-row\">\n            <div class=\"field\">\n              <label>On Input <span class=\"label-hint\">(agent receives)</span></label>\n              <select id=\"dlp-on-input\" onchange=\"updatePreview()\">\n                <option value=\"\">Use default mode</option>\n                <option value=\"audit\">Audit</option>\n                <option value=\"mask\">Mask</option>\n                <option value=\"block\" selected>Block</option>\n              </select>\n            </div>\n            <div class=\"field\">\n              <label>On Output <span class=\"label-hint\">(agent produces)</span></label>\n              <select id=\"dlp-on-output\" onchange=\"updatePreview()\">\n                <option value=\"\">Use default mode</option>\n                <option value=\"audit\">Audit</option>\n                <option value=\"mask\" selected>Mask</option>\n                <option value=\"block\">Block</option>\n              </select>\n            </div>\n          </div>\n\n          <hr class=\"divider\">\n          <label>Built-in Patterns</label>\n          <div class=\"toggle-row\" style=\"margin-top:6px\">\n            <label class=\"toggle\"><input type=\"checkbox\" id=\"dlp-secrets\" checked onchange=\"updatePreview()\"><span class=\"toggle-slider\"></span></label>\n            <span class=\"toggle-label\">Secrets <span class=\"label-hint\">(API keys, tokens, passwords)</span></span>\n          </div>\n          <div class=\"toggle-row\">\n            <label class=\"toggle\"><input type=\"checkbox\" id=\"dlp-pii\" checked onchange=\"updatePreview()\"><span class=\"toggle-slider\"></span></label>\n            <span class=\"toggle-label\">PII <span class=\"label-hint\">(emails, phone numbers, SSNs)</span></span>\n          </div>\n\n          <hr class=\"divider\">\n          <label>Masking Options</label>\n          <div class=\"field-row-3\" style=\"margin-top:8px\">\n            <div class=\"field\">\n              <label>Strategy</label>\n              <select id=\"dlp-mask-strategy\" onchange=\"updatePreview()\">\n                <option value=\"partial\" selected>Partial</option>\n                <option value=\"full\">Full</option>\n                <option value=\"hash\">Hash</option>\n              </select>\n            </div>\n            <div class=\"field\">\n              <label>Show Chars</label>\n              <input type=\"number\" id=\"dlp-mask-show\" value=\"4\" min=\"0\" onchange=\"updatePreview()\">\n            </div>\n            <div class=\"field\">\n              <label>Placeholder</label>\n              <input type=\"text\" id=\"dlp-mask-placeholder\" value=\"***\" onchange=\"updatePreview()\">\n            </div>\n          </div>\n\n          <hr class=\"divider\">\n          <label>Severity Threshold <span class=\"label-hint\">(minimum severity to trigger DLP)</span></label>\n          <div class=\"chip-group\" id=\"dlp-severity\" style=\"margin-top:6px\">\n            <span class=\"chip active\" data-value=\"low\" onclick=\"selectChip(this)\">Low</span>\n            <span class=\"chip\" data-value=\"medium\" onclick=\"selectChip(this)\">Medium</span>\n            <span class=\"chip\" data-value=\"high\" onclick=\"selectChip(this)\">High</span>\n            <span class=\"chip\" data-value=\"critical\" onclick=\"selectChip(this)\">Critical</span>\n          </div>\n\n          <hr class=\"divider\">\n          <label>Custom Patterns</label>\n          <div class=\"pattern-list\" id=\"dlp-custom-patterns\"></div>\n          <button class=\"btn-add\" onclick=\"addCustomPattern()\">+ Add pattern</button>\n\n          <hr class=\"divider\">\n          <label>Allowlist <span class=\"label-hint\">(patterns to ignore)</span></label>\n          <div id=\"dlp-allowlist\"></div>\n          <button class=\"btn-add\" onclick=\"addAllowlistEntry()\" style=\"margin-top:8px\">+ Add entry</button>\n        </div>\n      </div>\n    </div>\n\n    <!-- ── 3. Bash Classification ── -->\n    <div class=\"section\" id=\"sec-bash\">\n      <div class=\"section-header\" onclick=\"toggleSection('sec-bash')\">\n        <div class=\"section-icon\" style=\"background:var(--danger-subtle);color:var(--danger)\">&#x1f4bb;</div>\n        <h2>Bash Classification</h2>\n        <span class=\"section-badge badge-optional\">Optional</span>\n        <span class=\"section-chevron\">&#9660;</span>\n      </div>\n      <div class=\"section-body\">\n        <p class=\"help-text\" style=\"margin-bottom:12px\">The built-in bash classifier categorizes commands by danger level. Adjust the threshold for auto-blocking.</p>\n        <div class=\"field\">\n          <label>Auto-block Severity</label>\n          <p class=\"help-text\">Commands at or above this severity are blocked without HITL.</p>\n          <div class=\"chip-group\" id=\"bash-severity\" style=\"margin-top:6px\">\n            <span class=\"chip\" data-value=\"low\" onclick=\"selectChip(this)\">Low</span>\n            <span class=\"chip\" data-value=\"medium\" onclick=\"selectChip(this)\">Medium</span>\n            <span class=\"chip active\" data-value=\"high\" onclick=\"selectChip(this)\">High</span>\n            <span class=\"chip\" data-value=\"critical\" onclick=\"selectChip(this)\">Critical</span>\n          </div>\n        </div>\n      </div>\n    </div>\n\n    <!-- ── 4. HITL ── -->\n    <div class=\"section\" id=\"sec-hitl\">\n      <div class=\"section-header\" onclick=\"toggleSection('sec-hitl')\">\n        <div class=\"section-icon\" style=\"background:var(--success-subtle);color:var(--success)\">&#x1f9d1;</div>\n        <h2>Human-in-the-Loop</h2>\n        <span class=\"section-badge badge-required\">Required</span>\n        <span class=\"section-chevron\">&#9660;</span>\n      </div>\n      <div class=\"section-body\">\n        <div class=\"field\">\n          <label>Default Execution Mode</label>\n          <div class=\"chip-group\" id=\"hitl-mode\">\n            <span class=\"chip\" data-value=\"autonomous\" onclick=\"selectChip(this)\">Autonomous</span>\n            <span class=\"chip active\" data-value=\"supervised\" onclick=\"selectChip(this)\">Supervised</span>\n            <span class=\"chip\" data-value=\"dry_run\" onclick=\"selectChip(this)\">Dry Run</span>\n          </div>\n        </div>\n        <div class=\"field-row\">\n          <div class=\"field\">\n            <label>Approval Channel</label>\n            <select id=\"hitl-channel\" onchange=\"updatePreview()\">\n              <option value=\"cli\" selected>CLI (terminal prompt)</option>\n              <option value=\"webhook\">Webhook</option>\n            </select>\n          </div>\n          <div class=\"field\">\n            <label>Timeout <span class=\"label-hint\">(seconds)</span></label>\n            <input type=\"number\" id=\"hitl-timeout\" value=\"300\" min=\"10\" max=\"3600\" onchange=\"updatePreview()\">\n          </div>\n        </div>\n        <div class=\"field hidden\" id=\"hitl-webhook-field\">\n          <label>Webhook URL</label>\n          <input type=\"text\" id=\"hitl-webhook-url\" placeholder=\"https://...\" onchange=\"updatePreview()\">\n        </div>\n      </div>\n    </div>\n\n    <!-- ── 5. Audit ── -->\n    <div class=\"section\" id=\"sec-audit\">\n      <div class=\"section-header\" onclick=\"toggleSection('sec-audit')\">\n        <div class=\"section-icon\" style=\"background:var(--primary-subtle);color:var(--primary)\">&#x1f4dd;</div>\n        <h2>Audit Logging</h2>\n        <span class=\"section-badge badge-required\">Required</span>\n        <span class=\"section-chevron\">&#9660;</span>\n      </div>\n      <div class=\"section-body\">\n        <p class=\"help-text\" style=\"margin-bottom:12px\">All governance events are logged to one or more sinks.</p>\n        <div id=\"audit-sinks\"></div>\n        <button class=\"btn-add\" onclick=\"addAuditSink()\" style=\"margin-top:8px\">+ Add sink</button>\n      </div>\n    </div>\n\n    <!-- ── 6. Auth ── -->\n    <div class=\"section collapsed\" id=\"sec-auth\">\n      <div class=\"section-header\" onclick=\"toggleSection('sec-auth')\">\n        <div class=\"section-icon\" style=\"background:var(--bg-surface-alt);color:var(--text-muted)\">&#x1f511;</div>\n        <h2>Authentication</h2>\n        <span class=\"section-badge badge-optional\">Optional</span>\n        <span class=\"section-chevron\">&#9660;</span>\n      </div>\n      <div class=\"section-body\">\n        <div class=\"field\">\n          <label>Provider</label>\n          <div class=\"chip-group\" id=\"auth-provider\">\n            <span class=\"chip active\" data-value=\"env\" onclick=\"selectChip(this)\">Environment Vars</span>\n            <span class=\"chip\" data-value=\"local\" onclick=\"selectChip(this)\">Local File</span>\n            <span class=\"chip\" data-value=\"oidc\" onclick=\"selectChip(this)\">OIDC</span>\n          </div>\n        </div>\n        <div id=\"auth-env-fields\">\n          <div class=\"field-row-3\">\n            <div class=\"field\">\n              <label>User Var</label>\n              <input type=\"text\" id=\"auth-user-var\" value=\"PI_GOV_USER\" onchange=\"updatePreview()\">\n            </div>\n            <div class=\"field\">\n              <label>Role Var</label>\n              <input type=\"text\" id=\"auth-role-var\" value=\"PI_GOV_ROLE\" onchange=\"updatePreview()\">\n            </div>\n            <div class=\"field\">\n              <label>Org Unit Var</label>\n              <input type=\"text\" id=\"auth-org-unit-var\" value=\"PI_GOV_ORG_UNIT\" onchange=\"updatePreview()\">\n            </div>\n          </div>\n        </div>\n        <div id=\"auth-local-fields\" class=\"hidden\">\n          <div class=\"field\">\n            <label>Users File</label>\n            <input type=\"text\" id=\"auth-users-file\" value=\"./users.yaml\" onchange=\"updatePreview()\">\n          </div>\n        </div>\n      </div>\n    </div>\n\n    <div style=\"height:80px\"></div>\n  </div>\n\n  <!-- ═══════════ RIGHT: PREVIEW ═══════════ -->\n  <div class=\"preview-panel\">\n    <div class=\"preview-header\">\n      <h3>Live Preview</h3>\n    </div>\n    <div class=\"preview-tabs\">\n      <span class=\"preview-tab active\" data-tab=\"governance\" onclick=\"switchTab(this)\">governance.yaml</span>\n      <span class=\"preview-tab\" data-tab=\"rules\" onclick=\"switchTab(this)\">governance-rules.yaml</span>\n    </div>\n    <div class=\"preview-content\">\n      <pre id=\"preview-yaml\"></pre>\n    </div>\n  </div>\n</div>\n\n<!-- ── Bottom bar ── -->\n<div class=\"bottom-bar\">\n  <span class=\"save-status\" id=\"save-status\"></span>\n  <div style=\"display:flex;gap:10px\">\n    <button class=\"btn-secondary\" onclick=\"handleClose()\">Cancel</button>\n    <button class=\"btn-primary\" id=\"btn-save\" onclick=\"handleSave()\">Save Configuration</button>\n  </div>\n</div>\n\n<!-- Toast -->\n<div class=\"toast\" id=\"toast\"></div>\n\n<script>\n// ─── State ───────────────────────────────────────────────────────────\nconst PRESET_ROLES = {\n  analyst: {\n    label: 'Analyst',\n    desc: 'Read-only access, every action requires approval.',\n    allowed_tools: ['read','grep','find','ls'],\n    blocked_tools: ['write','edit','bash'],\n    prompt_template: 'analyst',\n    execution_mode: 'supervised',\n    human_approval: { required_for: ['all'] },\n    token_budget_daily: 100000,\n    allowed_paths: ['{{project_path}}/**'],\n    blocked_paths: ['**/secrets/**', '**/.env*']\n  },\n  project_lead: {\n    label: 'Project Lead',\n    desc: 'Full tools, bash & write need human approval.',\n    allowed_tools: ['read','write','edit','bash','grep','find','ls'],\n    blocked_tools: [],\n    prompt_template: 'project-lead',\n    execution_mode: 'supervised',\n    human_approval: { required_for: ['bash','write'], auto_approve: ['read','edit','grep','find','ls'] },\n    token_budget_daily: 500000,\n    allowed_paths: ['{{project_path}}/**'],\n    blocked_paths: ['**/secrets/**', '**/.env*'],\n    bash_overrides: { additional_blocked: ['sudo','ssh','curl.*\\\\\\\\|.*sh'] }\n  },\n  admin: {\n    label: 'Admin',\n    desc: 'Full autonomous access, no approvals, unlimited budget.',\n    allowed_tools: ['all'],\n    blocked_tools: [],\n    prompt_template: 'admin',\n    execution_mode: 'autonomous',\n    human_approval: { required_for: [] },\n    token_budget_daily: -1,\n    allowed_paths: ['**'],\n    blocked_paths: []\n  },\n  auditor: {\n    label: 'Auditor',\n    desc: 'Dry-run: all calls logged, nothing executed.',\n    allowed_tools: ['read','grep','find','ls'],\n    blocked_tools: ['write','edit','bash'],\n    prompt_template: 'analyst',\n    execution_mode: 'dry_run',\n    human_approval: { required_for: ['all'] },\n    token_budget_daily: 50000,\n    allowed_paths: ['**'],\n    blocked_paths: ['**/secrets/**']\n  }\n};\n\nlet selectedRoles = { analyst: false, project_lead: true, admin: false, auditor: false };\nlet customPatterns = [];\nlet allowlistEntries = [];\nlet auditSinks = [{ type: 'jsonl', path: '~/.pi/agent/audit.jsonl' }];\nlet activePreviewTab = 'governance';\n\n// ─── Init ────────────────────────────────────────────────────────────\ndocument.addEventListener('DOMContentLoaded', async () => {\n  renderRoles();\n  renderAuditSinks();\n  updatePreview();\n\n  try {\n    const [configRes, defaultsRes] = await Promise.all([\n      fetch('/api/config').catch(() => null),\n      fetch('/api/defaults').catch(() => null)\n    ]);\n    if (configRes && configRes.ok) {\n      const cfg = await configRes.json();\n      applyConfig(cfg);\n    }\n    if (defaultsRes && defaultsRes.ok) {\n      const defs = await defaultsRes.json();\n      if (!configRes || !configRes.ok) applyConfig(defs);\n    }\n  } catch (e) { /* use built-in defaults */ }\n\n  // watch for webhook channel\n  document.getElementById('hitl-channel').addEventListener('change', (e) => {\n    document.getElementById('hitl-webhook-field').classList.toggle('hidden', e.target.value !== 'webhook');\n    updatePreview();\n  });\n\n  // watch dlp toggle\n  document.getElementById('dlp-enabled').addEventListener('change', (e) => {\n    document.getElementById('dlp-options').classList.toggle('hidden', !e.target.checked);\n    updatePreview();\n  });\n});\n\n// ─── Apply Config ────────────────────────────────────────────────────\nfunction applyConfig(cfg) {\n  if (!cfg) return;\n\n  // Auth\n  if (cfg.auth) {\n    setChipValue('auth-provider', cfg.auth.provider || 'env');\n    if (cfg.auth.env) {\n      if (cfg.auth.env.user_var) document.getElementById('auth-user-var').value = cfg.auth.env.user_var;\n      if (cfg.auth.env.role_var) document.getElementById('auth-role-var').value = cfg.auth.env.role_var;\n      if (cfg.auth.env.org_unit_var) document.getElementById('auth-org-unit-var').value = cfg.auth.env.org_unit_var;\n    }\n    if (cfg.auth.local && cfg.auth.local.users_file) {\n      document.getElementById('auth-users-file').value = cfg.auth.local.users_file;\n    }\n  }\n\n  // HITL\n  if (cfg.hitl) {\n    if (cfg.hitl.default_mode) setChipValue('hitl-mode', cfg.hitl.default_mode);\n    if (cfg.hitl.approval_channel) {\n      document.getElementById('hitl-channel').value = cfg.hitl.approval_channel;\n      document.getElementById('hitl-webhook-field').classList.toggle('hidden', cfg.hitl.approval_channel !== 'webhook');\n    }\n    if (cfg.hitl.timeout_seconds) document.getElementById('hitl-timeout').value = cfg.hitl.timeout_seconds;\n    if (cfg.hitl.webhook && cfg.hitl.webhook.url) document.getElementById('hitl-webhook-url').value = cfg.hitl.webhook.url;\n  }\n\n  // DLP\n  if (cfg.dlp) {\n    document.getElementById('dlp-enabled').checked = cfg.dlp.enabled !== false;\n    document.getElementById('dlp-options').classList.toggle('hidden', !cfg.dlp.enabled);\n    if (cfg.dlp.mode) setChipValue('dlp-mode', cfg.dlp.mode);\n    if (cfg.dlp.on_input) document.getElementById('dlp-on-input').value = cfg.dlp.on_input;\n    if (cfg.dlp.on_output) document.getElementById('dlp-on-output').value = cfg.dlp.on_output;\n    if (cfg.dlp.masking) {\n      if (cfg.dlp.masking.strategy) document.getElementById('dlp-mask-strategy').value = cfg.dlp.masking.strategy;\n      if (cfg.dlp.masking.show_chars != null) document.getElementById('dlp-mask-show').value = cfg.dlp.masking.show_chars;\n      if (cfg.dlp.masking.placeholder) document.getElementById('dlp-mask-placeholder').value = cfg.dlp.masking.placeholder;\n    }\n    if (cfg.dlp.severity_threshold) setChipValue('dlp-severity', cfg.dlp.severity_threshold);\n    if (cfg.dlp.built_in) {\n      if (cfg.dlp.built_in.secrets != null) document.getElementById('dlp-secrets').checked = cfg.dlp.built_in.secrets;\n      if (cfg.dlp.built_in.pii != null) document.getElementById('dlp-pii').checked = cfg.dlp.built_in.pii;\n    }\n    if (cfg.dlp.custom_patterns) {\n      customPatterns = cfg.dlp.custom_patterns;\n      renderCustomPatterns();\n    }\n    if (cfg.dlp.allowlist) {\n      allowlistEntries = cfg.dlp.allowlist.map(e => e.pattern || e);\n      renderAllowlist();\n    }\n  }\n\n  // Audit\n  if (cfg.audit && cfg.audit.sinks) {\n    auditSinks = cfg.audit.sinks;\n    renderAuditSinks();\n  }\n\n  updatePreview();\n}\n\n// ─── Roles ───────────────────────────────────────────────────────────\nfunction renderRoles() {\n  const grid = document.getElementById('role-grid');\n  grid.innerHTML = '';\n  for (const [key, role] of Object.entries(PRESET_ROLES)) {\n    const sel = selectedRoles[key];\n    const card = document.createElement('div');\n    card.className = 'role-card' + (sel ? ' selected' : '');\n    card.dataset.role = key;\n    card.onclick = () => { toggleRole(key); };\n    card.innerHTML =\n      '<div class=\"role-card-check\">&#10003;</div>' +\n      '<div class=\"role-name\">' + role.label + '</div>' +\n      '<div class=\"role-desc\">' + role.desc + '</div>' +\n      '<div class=\"role-tags\">' +\n        '<span class=\"role-tag\">' + role.execution_mode + '</span>' +\n        '<span class=\"role-tag\">' + (role.token_budget_daily === -1 ? 'unlimited' : role.token_budget_daily.toLocaleString()) + ' budget</span>' +\n      '</div>' +\n      '<div class=\"role-details\">' +\n        '<div class=\"field\"><label>Allowed Tools</label>' +\n          '<input type=\"text\" value=\"' + role.allowed_tools.join(', ') + '\" onchange=\"updateRoleField(\\\\'' + key + '\\\\', \\\\'allowed_tools\\\\', this.value)\" onclick=\"event.stopPropagation()\">' +\n        '</div>' +\n        '<div class=\"field\"><label>Blocked Tools</label>' +\n          '<input type=\"text\" value=\"' + role.blocked_tools.join(', ') + '\" onchange=\"updateRoleField(\\\\'' + key + '\\\\', \\\\'blocked_tools\\\\', this.value)\" onclick=\"event.stopPropagation()\">' +\n        '</div>' +\n        '<div class=\"field\"><label>Execution Mode</label>' +\n          '<select onchange=\"updateRoleField(\\\\'' + key + '\\\\', \\\\'execution_mode\\\\', this.value)\" onclick=\"event.stopPropagation()\">' +\n            '<option value=\"supervised\"' + (role.execution_mode === 'supervised' ? ' selected' : '') + '>Supervised</option>' +\n            '<option value=\"autonomous\"' + (role.execution_mode === 'autonomous' ? ' selected' : '') + '>Autonomous</option>' +\n            '<option value=\"dry_run\"' + (role.execution_mode === 'dry_run' ? ' selected' : '') + '>Dry Run</option>' +\n          '</select>' +\n        '</div>' +\n        '<div class=\"field\"><label>Token Budget Daily</label>' +\n          '<input type=\"number\" value=\"' + role.token_budget_daily + '\" onchange=\"updateRoleField(\\\\'' + key + '\\\\', \\\\'token_budget_daily\\\\', parseInt(this.value))\" onclick=\"event.stopPropagation()\">' +\n        '</div>' +\n      '</div>';\n    grid.appendChild(card);\n  }\n}\n\nfunction toggleRole(key) {\n  selectedRoles[key] = !selectedRoles[key];\n  renderRoles();\n  updatePreview();\n}\n\nfunction updateRoleField(key, field, value) {\n  if (field === 'allowed_tools' || field === 'blocked_tools') {\n    PRESET_ROLES[key][field] = value.split(',').map(s => s.trim()).filter(Boolean);\n  } else {\n    PRESET_ROLES[key][field] = value;\n  }\n  updatePreview();\n}\n\n// ─── Section Toggle ──────────────────────────────────────────────────\nfunction toggleSection(id) {\n  document.getElementById(id).classList.toggle('collapsed');\n}\n\n// ─── Chip Groups ─────────────────────────────────────────────────────\nfunction selectChip(el) {\n  const group = el.parentElement;\n  group.querySelectorAll('.chip').forEach(c => c.classList.remove('active'));\n  el.classList.add('active');\n\n  // Auth provider visibility\n  if (group.id === 'auth-provider') {\n    const val = el.dataset.value;\n    document.getElementById('auth-env-fields').classList.toggle('hidden', val !== 'env');\n    document.getElementById('auth-local-fields').classList.toggle('hidden', val !== 'local');\n  }\n\n  updatePreview();\n}\n\nfunction getChipValue(groupId) {\n  const active = document.querySelector('#' + groupId + ' .chip.active');\n  return active ? active.dataset.value : '';\n}\n\nfunction setChipValue(groupId, value) {\n  const group = document.getElementById(groupId);\n  if (!group) return;\n  group.querySelectorAll('.chip').forEach(c => {\n    c.classList.toggle('active', c.dataset.value === value);\n  });\n}\n\n// ─── Custom Patterns ─────────────────────────────────────────────────\nfunction addCustomPattern() {\n  customPatterns.push({ name: '', pattern: '', severity: 'medium', action: 'audit' });\n  renderCustomPatterns();\n}\n\nfunction renderCustomPatterns() {\n  const container = document.getElementById('dlp-custom-patterns');\n  container.innerHTML = '';\n  customPatterns.forEach((p, i) => {\n    const div = document.createElement('div');\n    div.className = 'pattern-item';\n    div.innerHTML =\n      '<input type=\"text\" placeholder=\"Name\" value=\"' + esc(p.name) + '\" onchange=\"customPatterns[' + i + '].name=this.value;updatePreview()\">' +\n      '<input type=\"text\" placeholder=\"Regex pattern\" value=\"' + esc(p.pattern) + '\" onchange=\"customPatterns[' + i + '].pattern=this.value;updatePreview()\">' +\n      '<select onchange=\"customPatterns[' + i + '].severity=this.value;updatePreview()\">' +\n        '<option value=\"low\"' + (p.severity==='low'?' selected':'') + '>Low</option>' +\n        '<option value=\"medium\"' + (p.severity==='medium'?' selected':'') + '>Medium</option>' +\n        '<option value=\"high\"' + (p.severity==='high'?' selected':'') + '>High</option>' +\n        '<option value=\"critical\"' + (p.severity==='critical'?' selected':'') + '>Critical</option>' +\n      '</select>' +\n      '<button class=\"btn-remove\" onclick=\"customPatterns.splice(' + i + ',1);renderCustomPatterns();updatePreview()\">&times;</button>';\n    container.appendChild(div);\n  });\n}\n\n// ─── Allowlist ───────────────────────────────────────────────────────\nfunction addAllowlistEntry() {\n  allowlistEntries.push('');\n  renderAllowlist();\n}\n\nfunction renderAllowlist() {\n  const container = document.getElementById('dlp-allowlist');\n  container.innerHTML = '';\n  allowlistEntries.forEach((entry, i) => {\n    const div = document.createElement('div');\n    div.className = 'allowlist-item';\n    div.innerHTML =\n      '<input type=\"text\" placeholder=\"Pattern to allow\" value=\"' + esc(entry) + '\" onchange=\"allowlistEntries[' + i + ']=this.value;updatePreview()\">' +\n      '<button class=\"btn-remove\" onclick=\"allowlistEntries.splice(' + i + ',1);renderAllowlist();updatePreview()\">&times;</button>';\n    container.appendChild(div);\n  });\n}\n\n// ─── Audit Sinks ─────────────────────────────────────────────────────\nfunction addAuditSink() {\n  auditSinks.push({ type: 'jsonl', path: '' });\n  renderAuditSinks();\n}\n\nfunction renderAuditSinks() {\n  const container = document.getElementById('audit-sinks');\n  container.innerHTML = '';\n  auditSinks.forEach((sink, i) => {\n    const div = document.createElement('div');\n    div.className = 'sink-item';\n    let inner = '<button class=\"btn-remove\" onclick=\"auditSinks.splice(' + i + ',1);renderAuditSinks();updatePreview()\">&times;</button>';\n    inner += '<div class=\"field\"><label>Sink Type</label>' +\n      '<select onchange=\"auditSinks[' + i + '].type=this.value;renderAuditSinks();updatePreview()\">' +\n        '<option value=\"jsonl\"' + (sink.type==='jsonl'?' selected':'') + '>JSONL File</option>' +\n        '<option value=\"webhook\"' + (sink.type==='webhook'?' selected':'') + '>Webhook</option>' +\n        '<option value=\"postgres\"' + (sink.type==='postgres'?' selected':'') + '>PostgreSQL</option>' +\n      '</select></div>';\n    if (sink.type === 'jsonl') {\n      inner += '<div class=\"field\"><label>File Path</label>' +\n        '<input type=\"text\" value=\"' + esc(sink.path || '') + '\" placeholder=\"~/.pi/agent/audit.jsonl\" ' +\n        'onchange=\"auditSinks[' + i + '].path=this.value;updatePreview()\"></div>';\n    } else if (sink.type === 'webhook') {\n      inner += '<div class=\"field\"><label>Webhook URL</label>' +\n        '<input type=\"text\" value=\"' + esc(sink.url || '') + '\" placeholder=\"https://...\" ' +\n        'onchange=\"auditSinks[' + i + '].url=this.value;updatePreview()\"></div>';\n    } else if (sink.type === 'postgres') {\n      inner += '<div class=\"field\"><label>Connection String</label>' +\n        '<input type=\"text\" value=\"' + esc(sink.connection || '') + '\" placeholder=\"postgresql://...\" ' +\n        'onchange=\"auditSinks[' + i + '].connection=this.value;updatePreview()\"></div>';\n    }\n    div.innerHTML = inner;\n    container.appendChild(div);\n  });\n}\n\n// ─── Preview Tabs ────────────────────────────────────────────────────\nfunction switchTab(el) {\n  document.querySelectorAll('.preview-tab').forEach(t => t.classList.remove('active'));\n  el.classList.add('active');\n  activePreviewTab = el.dataset.tab;\n  updatePreview();\n}\n\n// ─── YAML Generator ──────────────────────────────────────────────────\nfunction toYaml(obj, indent) {\n  indent = indent || 0;\n  const pad = '  '.repeat(indent);\n  let out = '';\n\n  if (Array.isArray(obj)) {\n    if (obj.length === 0) return ' []\\\\n';\n    for (const item of obj) {\n      if (typeof item === 'object' && item !== null && !Array.isArray(item)) {\n        const keys = Object.keys(item);\n        if (keys.length > 0) {\n          out += pad + '- ' + keys[0] + ': ' + formatScalar(item[keys[0]]) + '\\\\n';\n          for (let k = 1; k < keys.length; k++) {\n            const val = item[keys[k]];\n            if (typeof val === 'object' && val !== null) {\n              out += pad + '  ' + keys[k] + ':\\\\n' + toYaml(val, indent + 2);\n            } else {\n              out += pad + '  ' + keys[k] + ': ' + formatScalar(val) + '\\\\n';\n            }\n          }\n        }\n      } else {\n        out += pad + '- ' + formatScalar(item) + '\\\\n';\n      }\n    }\n    return out;\n  }\n\n  if (typeof obj === 'object' && obj !== null) {\n    for (const [key, val] of Object.entries(obj)) {\n      if (val === undefined || val === null) continue;\n      if (typeof val === 'object') {\n        const yamlVal = toYaml(val, indent + 1);\n        if (Array.isArray(val) && val.length === 0) {\n          out += pad + key + ': []\\\\n';\n        } else {\n          out += pad + key + ':\\\\n' + yamlVal;\n        }\n      } else {\n        out += pad + key + ': ' + formatScalar(val) + '\\\\n';\n      }\n    }\n    return out;\n  }\n\n  return pad + formatScalar(obj) + '\\\\n';\n}\n\nfunction formatScalar(val) {\n  if (typeof val === 'boolean') return val ? 'true' : 'false';\n  if (typeof val === 'number') return String(val);\n  if (typeof val === 'string') {\n    if (val === '') return \"''\";\n    if (val === 'true' || val === 'false' || !isNaN(val)) return \"'\" + val + \"'\";\n    if (/[:#{}\\\\[\\\\],&*?|\\\\->!%@]/.test(val) || val.includes('\\\\\\\\')) return \"'\" + val.replace(/'/g, \"''\") + \"'\";\n    return val;\n  }\n  return String(val);\n}\n\n// ─── Build Config Objects ────────────────────────────────────────────\nfunction buildGovernanceConfig() {\n  const cfg = {};\n\n  // Auth\n  const authProvider = getChipValue('auth-provider');\n  cfg.auth = { provider: authProvider };\n  if (authProvider === 'env') {\n    cfg.auth.env = {\n      user_var: document.getElementById('auth-user-var').value || 'PI_GOV_USER',\n      role_var: document.getElementById('auth-role-var').value || 'PI_GOV_ROLE',\n      org_unit_var: document.getElementById('auth-org-unit-var').value || 'PI_GOV_ORG_UNIT'\n    };\n  } else if (authProvider === 'local') {\n    cfg.auth.local = {\n      users_file: document.getElementById('auth-users-file').value || './users.yaml'\n    };\n  }\n\n  // Policy\n  cfg.policy = {\n    engine: 'yaml',\n    yaml: { rules_file: './governance-rules.yaml' }\n  };\n\n  // HITL\n  cfg.hitl = {\n    default_mode: getChipValue('hitl-mode') || 'supervised',\n    approval_channel: document.getElementById('hitl-channel').value,\n    timeout_seconds: parseInt(document.getElementById('hitl-timeout').value) || 300\n  };\n  if (cfg.hitl.approval_channel === 'webhook') {\n    const url = document.getElementById('hitl-webhook-url').value;\n    if (url) cfg.hitl.webhook = { url: url };\n  }\n\n  // Audit\n  cfg.audit = { sinks: auditSinks.filter(s => {\n    if (s.type === 'jsonl') return s.path;\n    if (s.type === 'webhook') return s.url;\n    if (s.type === 'postgres') return s.connection;\n    return false;\n  }).map(s => {\n    if (s.type === 'jsonl') return { type: 'jsonl', path: s.path };\n    if (s.type === 'webhook') return { type: 'webhook', url: s.url };\n    if (s.type === 'postgres') return { type: 'postgres', connection: s.connection };\n    return s;\n  })};\n\n  // DLP\n  if (document.getElementById('dlp-enabled').checked) {\n    cfg.dlp = {\n      enabled: true,\n      mode: getChipValue('dlp-mode') || 'audit'\n    };\n    const onInput = document.getElementById('dlp-on-input').value;\n    const onOutput = document.getElementById('dlp-on-output').value;\n    if (onInput) cfg.dlp.on_input = onInput;\n    if (onOutput) cfg.dlp.on_output = onOutput;\n    cfg.dlp.masking = {\n      strategy: document.getElementById('dlp-mask-strategy').value,\n      show_chars: parseInt(document.getElementById('dlp-mask-show').value) || 4,\n      placeholder: document.getElementById('dlp-mask-placeholder').value || '***'\n    };\n    cfg.dlp.severity_threshold = getChipValue('dlp-severity') || 'low';\n    cfg.dlp.built_in = {\n      secrets: document.getElementById('dlp-secrets').checked,\n      pii: document.getElementById('dlp-pii').checked\n    };\n    const patterns = customPatterns.filter(p => p.name && p.pattern);\n    if (patterns.length > 0) cfg.dlp.custom_patterns = patterns;\n    const al = allowlistEntries.filter(Boolean);\n    if (al.length > 0) cfg.dlp.allowlist = al.map(p => ({ pattern: p }));\n  } else {\n    cfg.dlp = { enabled: false };\n  }\n\n  return cfg;\n}\n\nfunction buildRulesConfig() {\n  const roles = {};\n  for (const [key, sel] of Object.entries(selectedRoles)) {\n    if (!sel) continue;\n    const r = PRESET_ROLES[key];\n    const role = {\n      allowed_tools: r.allowed_tools,\n      blocked_tools: r.blocked_tools,\n      prompt_template: r.prompt_template,\n      execution_mode: r.execution_mode,\n      human_approval: r.human_approval,\n      token_budget_daily: r.token_budget_daily,\n      allowed_paths: r.allowed_paths,\n      blocked_paths: r.blocked_paths\n    };\n    if (r.bash_overrides) role.bash_overrides = r.bash_overrides;\n    roles[key] = role;\n  }\n  return { roles: roles };\n}\n\n// ─── Update Preview ──────────────────────────────────────────────────\nfunction updatePreview() {\n  const el = document.getElementById('preview-yaml');\n  if (activePreviewTab === 'governance') {\n    const cfg = buildGovernanceConfig();\n    el.textContent = '# governance.yaml\\\\n# Generated by Pi Governance Setup Wizard\\\\n\\\\n' + toYaml(cfg);\n  } else {\n    const rules = buildRulesConfig();\n    el.textContent = '# governance-rules.yaml\\\\n# Generated by Pi Governance Setup Wizard\\\\n\\\\n' + toYaml(rules);\n  }\n}\n\n// ─── Save ────────────────────────────────────────────────────────────\nasync function handleSave() {\n  const btn = document.getElementById('btn-save');\n  const status = document.getElementById('save-status');\n  btn.disabled = true;\n  status.textContent = 'Saving...';\n  status.className = 'save-status';\n\n  try {\n    const payload = {\n      governance: buildGovernanceConfig(),\n      rules: buildRulesConfig()\n    };\n    const res = await fetch('/api/save', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify(payload)\n    });\n    if (!res.ok) {\n      const err = await res.text();\n      throw new Error(err || 'Server error');\n    }\n    const result = await res.json();\n    showToast('Configuration saved!', 'success');\n    status.textContent = 'Saved: ' + (result.files || []).join(', ');\n    status.className = 'save-status success';\n  } catch (e) {\n    showToast('Failed to save: ' + e.message, 'error');\n    status.textContent = 'Error: ' + e.message;\n    status.className = 'save-status error';\n  } finally {\n    btn.disabled = false;\n  }\n}\n\nasync function handleClose() {\n  try { await fetch('/api/close', { method: 'POST' }); } catch (e) { /* ignore */ }\n  window.close();\n}\n\n// ─── Toast ───────────────────────────────────────────────────────────\nfunction showToast(msg, type) {\n  const toast = document.getElementById('toast');\n  toast.textContent = msg;\n  toast.className = 'toast ' + type + ' visible';\n  setTimeout(() => { toast.classList.remove('visible'); }, 3000);\n}\n\n// ─── Util ────────────────────────────────────────────────────────────\nfunction esc(s) {\n  return String(s).replace(/&/g,'&amp;').replace(/\"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;');\n}\n</script>\n</body>\n</html>`;\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { writeFileSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { stringify } from 'yaml';\nimport type { GovernanceConfig } from '../config/schema.js';\nimport { DEFAULTS } from '../config/defaults.js';\nimport { WIZARD_HTML } from './html.js';\n\nexport interface WizardServerOptions {\n  workingDirectory: string;\n  existingConfig?: GovernanceConfig;\n  onComplete: (files: { path: string; content: string }[]) => void;\n  onError: (error: Error) => void;\n}\n\nconst AUTO_SHUTDOWN_MS = 10 * 60 * 1000;\n\nconst BUILTIN_ROLES = {\n  analyst: {\n    allowed_tools: ['read', 'grep', 'find', 'ls'],\n    blocked_tools: ['bash', 'write', 'edit'],\n    hitl_mode: 'dry_run' as const,\n  },\n  project_lead: {\n    allowed_tools: ['read', 'write', 'edit', 'grep', 'find', 'ls', 'bash'],\n    blocked_tools: [],\n    hitl_mode: 'supervised' as const,\n  },\n  admin: {\n    allowed_tools: ['read', 'write', 'edit', 'grep', 'find', 'ls', 'bash'],\n    blocked_tools: [],\n    hitl_mode: 'autonomous' as const,\n  },\n  auditor: {\n    allowed_tools: ['read', 'grep', 'find', 'ls'],\n    blocked_tools: ['bash', 'write', 'edit'],\n    hitl_mode: 'dry_run' as const,\n  },\n};\n\nfunction setCorsHeaders(res: ServerResponse): void {\n  res.setHeader('Access-Control-Allow-Origin', 'http://localhost');\n  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n}\n\nfunction sendJson(res: ServerResponse, status: number, data: unknown): void {\n  res.writeHead(status, { 'Content-Type': 'application/json' });\n  res.end(JSON.stringify(data));\n}\n\nfunction readBody(req: IncomingMessage): Promise<string> {\n  return new Promise((resolve, reject) => {\n    const chunks: Buffer[] = [];\n    req.on('data', (chunk: Buffer) => chunks.push(chunk));\n    req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));\n    req.on('error', reject);\n  });\n}\n\nexport function startWizardServer(\n  options: WizardServerOptions,\n): Promise<{ port: number; close: () => void }> {\n  return new Promise((resolve, reject) => {\n    let shutdownTimer: ReturnType<typeof setTimeout> | undefined;\n\n    const server = createServer((req, res) => {\n      setCorsHeaders(res);\n\n      if (req.method === 'OPTIONS') {\n        res.writeHead(204);\n        res.end();\n        return;\n      }\n\n      const url = req.url ?? '/';\n\n      try {\n        if (req.method === 'GET' && url === '/') {\n          res.writeHead(200, { 'Content-Type': 'text/html' });\n          res.end(WIZARD_HTML);\n          return;\n        }\n\n        if (req.method === 'GET' && url === '/api/config') {\n          sendJson(res, 200, options.existingConfig ?? DEFAULTS);\n          return;\n        }\n\n        if (req.method === 'GET' && url === '/api/defaults') {\n          sendJson(res, 200, { defaults: DEFAULTS, roles: BUILTIN_ROLES });\n          return;\n        }\n\n        if (req.method === 'POST' && url === '/api/save') {\n          readBody(req)\n            .then((body) => {\n              const parsed: unknown = JSON.parse(body);\n              if (typeof parsed !== 'object' || parsed === null || !('governance' in parsed)) {\n                sendJson(res, 400, { error: 'Request body must include \"governance\" property' });\n                return;\n              }\n\n              const payload = parsed as { governance: GovernanceConfig; rules?: unknown };\n              const governanceYaml = stringify(payload.governance);\n              const piDir = join(options.workingDirectory, '.pi');\n              const governancePath = join(piDir, 'governance.yaml');\n\n              mkdirSync(piDir, { recursive: true });\n              writeFileSync(governancePath, governanceYaml, 'utf-8');\n\n              const files: { path: string; content: string }[] = [\n                { path: governancePath, content: governanceYaml },\n              ];\n\n              if (payload.rules !== undefined) {\n                const rulesYaml = stringify(payload.rules);\n                const rulesPath = join(options.workingDirectory, 'governance-rules.yaml');\n                writeFileSync(rulesPath, rulesYaml, 'utf-8');\n                files.push({ path: rulesPath, content: rulesYaml });\n              }\n\n              sendJson(res, 200, { ok: true, files: files.map((f) => f.path) });\n              options.onComplete(files);\n            })\n            .catch((err: unknown) => {\n              const message = err instanceof Error ? err.message : String(err);\n              sendJson(res, 400, { error: `Invalid request body: ${message}` });\n            });\n          return;\n        }\n\n        if (req.method === 'POST' && url === '/api/close') {\n          sendJson(res, 200, { ok: true });\n          setTimeout(() => {\n            closeServer();\n          }, 100);\n          return;\n        }\n\n        sendJson(res, 404, { error: 'Not found' });\n      } catch (err: unknown) {\n        const error = err instanceof Error ? err : new Error(String(err));\n        options.onError(error);\n        sendJson(res, 500, { error: 'Internal server error' });\n      }\n    });\n\n    function closeServer(): void {\n      if (shutdownTimer !== undefined) {\n        clearTimeout(shutdownTimer);\n        shutdownTimer = undefined;\n      }\n      server.close();\n    }\n\n    server.on('error', (err) => {\n      options.onError(err);\n      reject(err);\n    });\n\n    server.listen(0, () => {\n      const addr = server.address();\n      if (addr === null || typeof addr === 'string') {\n        const err = new Error('Failed to get server address');\n        options.onError(err);\n        reject(err);\n        return;\n      }\n\n      shutdownTimer = setTimeout(() => {\n        closeServer();\n      }, AUTO_SHUTDOWN_MS);\n\n      resolve({ port: addr.port, close: closeServer });\n    });\n  });\n}\n","export { startWizardServer } from './server.js';\nexport type { WizardServerOptions } from './server.js';\n","// Pi Extension API types — locally defined to avoid hard dependency on @mariozechner/pi-coding-agent\n// These match the real Pi extension API surface.\n\ninterface ToolCallEvent {\n  toolName: string;\n  input: Record<string, unknown>;\n}\n\ninterface ToolResultEvent {\n  toolName: string;\n  input: Record<string, unknown>;\n  output: string;\n  isError: boolean;\n}\n\ninterface ExtensionUI {\n  confirm(title: string, message: string, opts?: { timeout?: number }): Promise<boolean>;\n  notify(msg: string, type?: 'info' | 'warning' | 'error'): void;\n  setStatus(key: string, text: string): void;\n}\n\ninterface ExtensionContext {\n  ui: ExtensionUI;\n  sessionId: string;\n  workingDirectory: string;\n}\n\ntype ToolCallHandler = (\n  event: ToolCallEvent,\n  ctx: ExtensionContext,\n) => Promise<{ block: true; reason: string } | void>;\n\ntype ToolResultHandler = (event: ToolResultEvent, ctx: ExtensionContext) => Promise<void>;\n\ntype SessionHandler = (event: unknown, ctx: ExtensionContext) => Promise<void>;\n\ninterface ExtensionAPI {\n  on(event: 'session_start', handler: SessionHandler): void;\n  on(event: 'session_shutdown', handler: SessionHandler): void;\n  on(event: 'tool_call', handler: ToolCallHandler): void;\n  on(event: 'tool_result', handler: ToolResultHandler): void;\n  registerCommand(\n    name: string,\n    opts: {\n      description?: string;\n      handler: (args: string, ctx: ExtensionContext) => Promise<void>;\n    },\n  ): void;\n}\n\ntype ExtensionFactory = (pi: ExtensionAPI) => void;\n\n// --- Implementation ---\n\nimport { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { loadConfig } from '../lib/config/loader.js';\nimport { createIdentityChain } from '../lib/identity/chain.js';\nimport { YamlPolicyEngine } from '../lib/policy/yaml-engine.js';\nimport { BashClassifier } from '../lib/bash/classifier.js';\nimport { AuditLogger } from '../lib/audit/logger.js';\nimport { createApprovalFlow } from '../lib/hitl/approval.js';\nimport { BudgetTracker } from '../lib/budget/tracker.js';\nimport { ConfigWatcher } from '../lib/config/watcher.js';\nimport { DlpScanner } from '../lib/dlp/scanner.js';\nimport { DlpMasker } from '../lib/dlp/masker.js';\nimport type { DlpAction, DlpMatch, DlpScannerConfig } from '../lib/dlp/scanner.js';\nimport type { ApprovalFlow } from '../lib/hitl/approval.js';\nimport type { PolicyEngine, ExecutionMode } from '../lib/policy/engine.js';\nimport type { ResolvedIdentity } from '../lib/identity/provider.js';\nimport type {\n  GovernanceConfig,\n  DlpConfigType,\n  DependencyGuardianConfigType,\n} from '../lib/config/schema.js';\nimport { evaluateInstall, type DependencyGuardianConfig } from '../lib/deps/guardian.js';\nimport { parseInstallCommand } from '../lib/deps/parser.js';\n\n// Tools that involve file paths — used for path boundary checks\nconst PATH_TOOLS: Record<string, string> = {\n  read: 'path',\n  write: 'path',\n  edit: 'file_path',\n  grep: 'path',\n  find: 'path',\n  ls: 'path',\n};\n\n// Tools that are write operations for path checking\nconst WRITE_TOOLS = new Set(['write', 'edit']);\n\nfunction summarizeParams(\n  toolName: string,\n  input: Record<string, unknown>,\n): Record<string, unknown> {\n  switch (toolName) {\n    case 'bash': {\n      const cmd = typeof input['command'] === 'string' ? input['command'] : '';\n      return { command: cmd.slice(0, 100) + (cmd.length > 100 ? '...' : '') };\n    }\n    case 'read':\n      return { path: input['path'] };\n    case 'write':\n      return { path: input['path'] };\n    case 'edit':\n      return { file_path: input['file_path'] };\n    case 'grep':\n      return { pattern: input['pattern'], path: input['path'] };\n    case 'find':\n    case 'ls':\n      return { path: input['path'] };\n    default:\n      return {};\n  }\n}\n\nfunction extractPath(toolName: string, input: Record<string, unknown>): string | undefined {\n  const key = PATH_TOOLS[toolName];\n  if (!key) return undefined;\n  const val = input[key];\n  return typeof val === 'string' ? val : undefined;\n}\n\n// --- DLP helpers ---\n\nconst ACTION_PRIORITY: Record<DlpAction, number> = { audit: 0, mask: 1, block: 2 };\n\nfunction extractDlpFields(toolName: string, input: Record<string, unknown>): Map<string, string> {\n  const fields = new Map<string, string>();\n  switch (toolName) {\n    case 'bash': {\n      const cmd = input['command'];\n      if (typeof cmd === 'string') fields.set('command', cmd);\n      break;\n    }\n    case 'write': {\n      const content = input['content'];\n      if (typeof content === 'string') fields.set('content', content);\n      const path = input['path'];\n      if (typeof path === 'string') fields.set('path', path);\n      break;\n    }\n    case 'edit': {\n      const newStr = input['new_string'];\n      if (typeof newStr === 'string') fields.set('new_string', newStr);\n      const oldStr = input['old_string'];\n      if (typeof oldStr === 'string') fields.set('old_string', oldStr);\n      break;\n    }\n    default: {\n      // Scan all string values\n      for (const [key, val] of Object.entries(input)) {\n        if (typeof val === 'string') fields.set(key, val);\n      }\n    }\n  }\n  return fields;\n}\n\nfunction resolveHighestAction(\n  scanner: DlpScanner,\n  matches: DlpMatch[],\n  direction: 'input' | 'output',\n): DlpAction {\n  let highest: DlpAction = 'audit';\n  for (const match of matches) {\n    const action = scanner.getPatternAction(match, direction);\n    if (ACTION_PRIORITY[action] > ACTION_PRIORITY[highest]) {\n      highest = action;\n    }\n  }\n  return highest;\n}\n\nfunction resolveDlpConfig(\n  dlpConfig: DlpConfigType | undefined,\n  role: string,\n): DlpScannerConfig | undefined {\n  if (!dlpConfig?.enabled) return undefined;\n\n  // Apply role overrides\n  const roleOverride = dlpConfig.role_overrides?.[role];\n  if (roleOverride?.enabled === false) return undefined;\n\n  const patternOverrides = new Map<string, DlpAction>();\n\n  return {\n    enabled: true,\n    mode: roleOverride?.mode ?? dlpConfig.mode ?? 'audit',\n    on_input: roleOverride?.on_input ?? dlpConfig.on_input,\n    on_output: roleOverride?.on_output ?? dlpConfig.on_output,\n    severity_threshold: dlpConfig.severity_threshold ?? 'low',\n    built_in: {\n      secrets: dlpConfig.built_in?.secrets ?? true,\n      pii: dlpConfig.built_in?.pii ?? true,\n    },\n    custom_patterns: (dlpConfig.custom_patterns ?? []).map((cp) => ({\n      name: cp.name,\n      pattern: cp.pattern,\n      severity: cp.severity,\n      action: cp.action as DlpAction | undefined,\n    })),\n    allowlist: dlpConfig.allowlist ?? [],\n    pattern_overrides: patternOverrides,\n  };\n}\n\nfunction resolveGuardianConfig(\n  cfg: DependencyGuardianConfigType | undefined,\n): DependencyGuardianConfig | undefined {\n  if (!cfg || cfg.enabled === false) return undefined;\n\n  return {\n    enabled: cfg.enabled ?? true,\n    checks: {\n      existence: cfg.checks?.existence ?? true,\n      reputation: cfg.checks?.reputation ?? true,\n      typosquatting: cfg.checks?.typosquatting ?? true,\n      install_scripts: cfg.checks?.install_scripts ?? true,\n      vulnerabilities: cfg.checks?.vulnerabilities ?? true,\n    },\n    risk_thresholds: {\n      min_age_days: cfg.risk_thresholds?.min_age_days ?? 30,\n      min_weekly_downloads: cfg.risk_thresholds?.min_weekly_downloads ?? 100,\n    },\n    on_risk: cfg.on_risk ?? 'escalate',\n    allowlist: cfg.allowlist ?? [],\n    blocklist: cfg.blocklist ?? [],\n    blocklist_patterns: cfg.blocklist_patterns ?? [],\n    custom_registry_bypass: cfg.custom_registry_bypass ?? true,\n  };\n}\n\nconst piGovernance: ExtensionFactory = (pi) => {\n  // State — initialized in session_start\n  let config: GovernanceConfig;\n  let policyEngine: PolicyEngine;\n  let audit: AuditLogger;\n  let approvalFlow: ApprovalFlow | undefined;\n  let bashClassifier: BashClassifier;\n  let identity: ResolvedIdentity;\n  let executionMode: ExecutionMode;\n  let sessionId: string;\n  let budgetTracker: BudgetTracker;\n  let configWatcher: ConfigWatcher | undefined;\n  let dlpScanner: DlpScanner | undefined;\n  let dlpMasker: DlpMasker | undefined;\n  let guardianConfig: DependencyGuardianConfig | undefined;\n  let protectedPaths: Set<string> = new Set();\n\n  const stats = {\n    configTampered: 0,\n    allowed: 0,\n    denied: 0,\n    approvals: 0,\n    dryRun: 0,\n    budgetExceeded: 0,\n    dlpBlocked: 0,\n    dlpDetected: 0,\n    dlpMasked: 0,\n  };\n\n  pi.on('session_start', async (_event, ctx) => {\n    sessionId = ctx.sessionId;\n\n    // 1. Load config\n    const loaded = loadConfig();\n    config = loaded.config;\n\n    // 1b. Compute protected config paths (hardcoded — cannot be overridden)\n    const paths = new Set<string>();\n    if (loaded.source !== 'built-in') {\n      paths.add(resolve(loaded.source));\n    }\n    const rulesFileCfg = config.policy?.yaml?.rules_file ?? './governance-rules.yaml';\n    paths.add(resolve(rulesFileCfg));\n    // Fallback well-known paths — guard against undefined workingDirectory (e.g. Docker)\n    const cwd = ctx.workingDirectory ?? process.cwd();\n    paths.add(resolve(cwd, '.pi/governance.yaml'));\n    paths.add(resolve(cwd, 'governance-rules.yaml'));\n    protectedPaths = paths;\n\n    // 2. Resolve identity\n    const chain = createIdentityChain(config.auth);\n    identity = await chain.resolve();\n\n    // 3. Create policy engine\n    const rulesFile = config.policy?.yaml?.rules_file ?? './governance-rules.yaml';\n    if (existsSync(rulesFile)) {\n      policyEngine = new YamlPolicyEngine(rulesFile);\n    } else {\n      // No rules file found — use permissive defaults so the extension doesn't crash\n      policyEngine = new YamlPolicyEngine({\n        roles: {\n          admin: {\n            allowed_tools: ['all'],\n            blocked_tools: [],\n            prompt_template: 'admin',\n            execution_mode: 'autonomous',\n            human_approval: { required_for: [] },\n            token_budget_daily: -1,\n            allowed_paths: ['**'],\n            blocked_paths: [],\n          },\n          project_lead: {\n            allowed_tools: ['all'],\n            blocked_tools: [],\n            prompt_template: 'project-lead',\n            execution_mode: 'supervised',\n            human_approval: { required_for: ['bash', 'write'] },\n            token_budget_daily: -1,\n            allowed_paths: ['**'],\n            blocked_paths: [],\n          },\n          analyst: {\n            allowed_tools: ['read', 'grep', 'find', 'ls'],\n            blocked_tools: ['write', 'edit', 'bash'],\n            prompt_template: 'analyst',\n            execution_mode: 'supervised',\n            human_approval: { required_for: ['all'] },\n            token_budget_daily: -1,\n            allowed_paths: ['**'],\n            blocked_paths: [],\n          },\n        },\n      });\n      // Only warn if the user explicitly configured a rules file path\n      if (config.policy?.yaml?.rules_file) {\n        ctx.ui.notify(`Rules file not found: ${rulesFile} — using built-in defaults`, 'warning');\n      }\n    }\n\n    // 4. Get execution mode\n    executionMode = policyEngine.getExecutionMode(identity.role);\n\n    // 5. Create bash classifier with role overrides\n    const bashOverrides = policyEngine.getBashOverrides(identity.role);\n    bashClassifier = new BashClassifier(bashOverrides);\n\n    // 6. Create audit logger\n    audit = new AuditLogger(config.audit);\n\n    // 7. Create approval flow if supervised mode\n    if (executionMode === 'supervised') {\n      try {\n        approvalFlow = createApprovalFlow(\n          {\n            default_mode: config.hitl?.default_mode ?? 'supervised',\n            approval_channel: config.hitl?.approval_channel ?? 'cli',\n            timeout_seconds: config.hitl?.timeout_seconds ?? 300,\n            webhook: config.hitl?.webhook,\n          },\n          ctx.ui,\n        );\n      } catch {\n        // If CLI UI not available, approval flow stays undefined\n      }\n    }\n\n    // 8. Create budget tracker\n    const budget = policyEngine.getTokenBudget(identity.role);\n    budgetTracker = new BudgetTracker(budget);\n\n    // 9. Initialize DLP scanner/masker if enabled\n    const dlpCfg = resolveDlpConfig(config.dlp, identity.role);\n    if (dlpCfg) {\n      dlpScanner = new DlpScanner(dlpCfg);\n      dlpMasker = new DlpMasker(config.dlp?.masking);\n    }\n\n    // 10. Initialize Dependency Guardian\n    guardianConfig = resolveGuardianConfig(config.dependency_guardian);\n\n    // 11. Start config watcher\n    if (loaded.source !== 'built-in') {\n      configWatcher = new ConfigWatcher(\n        loaded.source,\n        (newConfig) => {\n          config = newConfig;\n          const newRulesFile = newConfig.policy?.yaml?.rules_file ?? './governance-rules.yaml';\n          if (existsSync(newRulesFile)) {\n            policyEngine = new YamlPolicyEngine(newRulesFile);\n          }\n          const newOverrides = policyEngine.getBashOverrides(identity.role);\n          bashClassifier = new BashClassifier(newOverrides);\n          // Recreate DLP scanner/masker on config reload\n          const newDlpCfg = resolveDlpConfig(newConfig.dlp, identity.role);\n          if (newDlpCfg) {\n            dlpScanner = new DlpScanner(newDlpCfg);\n            dlpMasker = new DlpMasker(newConfig.dlp?.masking);\n          } else {\n            dlpScanner = undefined;\n            dlpMasker = undefined;\n          }\n          guardianConfig = resolveGuardianConfig(newConfig.dependency_guardian);\n          audit.log({\n            sessionId,\n            event: 'config_reloaded',\n            userId: identity.userId,\n            role: identity.role,\n            orgUnit: identity.orgUnit,\n            metadata: { source: loaded.source },\n          });\n          ctx.ui.notify('Governance config reloaded', 'info');\n        },\n        (error) => {\n          ctx.ui.notify(`Config reload failed: ${error.message}`, 'warning');\n        },\n      );\n      configWatcher.start();\n    }\n\n    // 10. Audit session start\n    await audit.log({\n      sessionId,\n      event: 'session_start',\n      userId: identity.userId,\n      role: identity.role,\n      orgUnit: identity.orgUnit,\n      metadata: { source: loaded.source, executionMode },\n    });\n\n    // 11. UI feedback\n    ctx.ui.setStatus('governance', `Governance: ${identity.role} (${executionMode})`);\n    ctx.ui.notify(\n      `Governance active — Role: ${identity.role} | Mode: ${executionMode} | Org: ${identity.orgUnit}`,\n      'info',\n    );\n  });\n\n  pi.on('tool_call', async (event, ctx) => {\n    if (!audit || !policyEngine || !identity) return undefined;\n\n    const { toolName, input } = event;\n    const params = summarizeParams(toolName, input);\n\n    const baseRecord = {\n      sessionId,\n      userId: identity.userId,\n      role: identity.role,\n      orgUnit: identity.orgUnit,\n      tool: toolName,\n      input: params,\n    };\n\n    // 0. Hardcoded config self-protection — cannot be bypassed by policy\n    if (WRITE_TOOLS.has(toolName)) {\n      const filePath = extractPath(toolName, input);\n      if (filePath && protectedPaths.has(resolve(filePath))) {\n        stats.configTampered++;\n        await audit.log({\n          ...baseRecord,\n          event: 'config_tampered',\n          decision: 'denied',\n          reason: `Config self-protection: write to governance file blocked (${filePath})`,\n        });\n        return {\n          block: true,\n          reason: `Governance config files are protected and cannot be modified by agents`,\n        };\n      }\n    }\n\n    // 1. Dry-run mode — block everything, log as dry_run\n    if (executionMode === 'dry_run') {\n      stats.dryRun++;\n      await audit.log({\n        ...baseRecord,\n        event: 'tool_dry_run',\n        decision: 'blocked',\n        reason: 'Dry-run mode',\n      });\n      return { block: true, reason: 'Dry-run mode: tool execution blocked for observation' };\n    }\n\n    // 2. Budget check\n    if (!budgetTracker.consume()) {\n      stats.budgetExceeded++;\n      await audit.log({\n        ...baseRecord,\n        event: 'budget_exceeded',\n        decision: 'denied',\n        reason: `Budget exhausted (${budgetTracker.used()} invocations used)`,\n      });\n      return {\n        block: true,\n        reason: `Tool invocation budget exhausted (${budgetTracker.used()} used). Session limit reached.`,\n      };\n    }\n\n    // 3. Policy: evaluate tool access\n    const toolDecision = policyEngine.evaluateTool(identity.role, toolName);\n    if (toolDecision === 'deny') {\n      stats.denied++;\n      await audit.log({\n        ...baseRecord,\n        event: 'tool_denied',\n        decision: 'denied',\n        reason: 'Policy denied tool',\n      });\n      return { block: true, reason: `Policy denies ${identity.role} from using ${toolName}` };\n    }\n\n    // 4. Bash-specific classification\n    if (toolName === 'bash') {\n      const command = typeof input['command'] === 'string' ? input['command'] : '';\n      const classification = bashClassifier.classify(command);\n\n      if (classification === 'dangerous') {\n        // Check if this is an install command that the guardian should handle\n        if (guardianConfig && parseInstallCommand(command)) {\n          const guardianResult = await evaluateInstall(command, guardianConfig);\n\n          if (!guardianResult.skipped) {\n            if (guardianResult.overallRecommendation === 'block') {\n              stats.denied++;\n              await audit.log({\n                ...baseRecord,\n                event: 'dep_blocked',\n                decision: 'denied',\n                reason: guardianResult.summary,\n                metadata: guardianResult.auditMetadata,\n              });\n              return { block: true, reason: guardianResult.summary };\n            }\n\n            if (guardianResult.overallRecommendation === 'escalate') {\n              await audit.log({\n                ...baseRecord,\n                event: 'dep_escalated',\n                metadata: guardianResult.auditMetadata,\n              });\n\n              const approved = await ctx.ui.confirm(\n                'Dependency Review Required',\n                guardianResult.summary,\n              );\n\n              if (!approved) {\n                stats.denied++;\n                await audit.log({ ...baseRecord, event: 'dep_rejected' });\n                return { block: true, reason: 'Dependency rejected by reviewer' };\n              }\n\n              stats.approvals++;\n              await audit.log({ ...baseRecord, event: 'dep_approved' });\n            }\n\n            // 'allow' — log and proceed\n            await audit.log({\n              ...baseRecord,\n              event: 'dep_allowed',\n              metadata: guardianResult.auditMetadata,\n            });\n            stats.allowed++;\n            return undefined;\n          }\n          // If skipped (lockfile, custom registry, etc.), fall through to normal handling\n        }\n\n        stats.denied++;\n        await audit.log({\n          ...baseRecord,\n          event: 'bash_denied',\n          decision: 'denied',\n          reason: 'Dangerous command',\n        });\n        return { block: true, reason: `Dangerous bash command blocked: ${command.slice(0, 80)}` };\n      }\n\n      // needs_review with approval required\n      if (\n        classification === 'needs_review' &&\n        policyEngine.requiresApproval(identity.role, 'bash')\n      ) {\n        if (approvalFlow) {\n          stats.approvals++;\n          await audit.log({ ...baseRecord, event: 'approval_requested' });\n\n          const result = await approvalFlow.requestApproval(\n            { toolName, input },\n            { userId: identity.userId, role: identity.role, orgUnit: identity.orgUnit },\n          );\n\n          if (result.approved) {\n            await audit.log({\n              ...baseRecord,\n              event: 'approval_granted',\n              duration: result.duration,\n            });\n          } else {\n            stats.denied++;\n            await audit.log({\n              ...baseRecord,\n              event: 'approval_denied',\n              reason: result.reason,\n              duration: result.duration,\n            });\n            return { block: true, reason: result.reason ?? 'Approval denied' };\n          }\n        } else {\n          // No approval flow — deny\n          stats.denied++;\n          await audit.log({\n            ...baseRecord,\n            event: 'tool_denied',\n            decision: 'denied',\n            reason: 'Requires approval but no approval channel',\n          });\n          return {\n            block: true,\n            reason: 'Bash command requires approval but no approval channel is configured',\n          };\n        }\n      }\n    }\n\n    // 5. Path boundary check for file tools\n    const path = extractPath(toolName, input);\n    if (path) {\n      const operation = WRITE_TOOLS.has(toolName) ? 'write' : 'read';\n      const pathDecision = policyEngine.evaluatePath(\n        identity.role,\n        identity.orgUnit,\n        operation,\n        path,\n      );\n      if (pathDecision === 'deny') {\n        stats.denied++;\n        await audit.log({\n          ...baseRecord,\n          event: 'path_denied',\n          decision: 'denied',\n          reason: `Path denied: ${path}`,\n        });\n        return { block: true, reason: `Access denied to path: ${path}` };\n      }\n    }\n\n    // 6. DLP scan inputs\n    if (dlpScanner && dlpMasker) {\n      const fields = extractDlpFields(toolName, input);\n      const allMatches: DlpMatch[] = [];\n      for (const [, fieldValue] of fields) {\n        const result = dlpScanner.scan(fieldValue);\n        allMatches.push(...result.matches);\n      }\n\n      if (allMatches.length > 0) {\n        const action = resolveHighestAction(dlpScanner, allMatches, 'input');\n        const patternNames = [...new Set(allMatches.map((m) => m.patternName))];\n        const severities = [...new Set(allMatches.map((m) => m.severity))];\n        const dlpMeta = {\n          patterns: patternNames,\n          severities,\n          direction: 'input' as const,\n          count: allMatches.length,\n        };\n\n        if (action === 'block') {\n          stats.dlpBlocked++;\n          await audit.log({\n            ...baseRecord,\n            event: 'dlp_blocked',\n            decision: 'denied',\n            reason: `DLP: ${patternNames.join(', ')} detected in input`,\n            metadata: dlpMeta,\n          });\n          return {\n            block: true,\n            reason: `DLP blocked: sensitive data detected (${patternNames.join(', ')})`,\n          };\n        }\n\n        if (action === 'mask') {\n          stats.dlpMasked++;\n          // Mask each field independently to maintain correct positions\n          for (const [fieldKey, fieldValue] of fields) {\n            const fieldResult = dlpScanner.scan(fieldValue);\n            if (fieldResult.hasMatches) {\n              (input as Record<string, unknown>)[fieldKey] = dlpMasker.maskText(\n                fieldValue,\n                fieldResult.matches,\n              );\n            }\n          }\n          await audit.log({\n            ...baseRecord,\n            event: 'dlp_masked',\n            metadata: { ...dlpMeta, strategy: dlpMasker['config'].strategy },\n          });\n        } else {\n          // audit-only\n          stats.dlpDetected++;\n          await audit.log({\n            ...baseRecord,\n            event: 'dlp_detected',\n            metadata: dlpMeta,\n          });\n        }\n      }\n    }\n\n    // 7. HITL approval for non-bash tools if required\n    if (toolName !== 'bash' && policyEngine.requiresApproval(identity.role, toolName)) {\n      if (approvalFlow) {\n        stats.approvals++;\n        await audit.log({ ...baseRecord, event: 'approval_requested' });\n\n        const result = await approvalFlow.requestApproval(\n          { toolName, input },\n          { userId: identity.userId, role: identity.role, orgUnit: identity.orgUnit },\n        );\n\n        if (result.approved) {\n          await audit.log({ ...baseRecord, event: 'approval_granted', duration: result.duration });\n        } else {\n          stats.denied++;\n          await audit.log({\n            ...baseRecord,\n            event: 'approval_denied',\n            reason: result.reason,\n            duration: result.duration,\n          });\n          return { block: true, reason: result.reason ?? 'Approval denied' };\n        }\n      }\n    }\n\n    // 8. Tool allowed\n    stats.allowed++;\n    await audit.log({ ...baseRecord, event: 'tool_allowed', decision: 'allowed' });\n    return undefined;\n  });\n\n  pi.on('tool_result', async (event, _ctx) => {\n    if (!audit || !identity) return;\n\n    // DLP scan output before audit\n    if (dlpScanner && dlpMasker && event.output) {\n      const result = dlpScanner.scan(event.output);\n      if (result.hasMatches) {\n        const action = resolveHighestAction(dlpScanner, result.matches, 'output');\n        const patternNames = [...new Set(result.matches.map((m) => m.patternName))];\n        const severities = [...new Set(result.matches.map((m) => m.severity))];\n        const dlpMeta = {\n          patterns: patternNames,\n          severities,\n          direction: 'output' as const,\n          count: result.matches.length,\n        };\n\n        if (action === 'mask' || action === 'block') {\n          // block degrades to mask for outputs (handler returns void)\n          stats.dlpMasked++;\n          event.output = dlpMasker.maskText(event.output, result.matches);\n          await audit.log({\n            sessionId,\n            event: 'dlp_masked',\n            userId: identity.userId,\n            role: identity.role,\n            orgUnit: identity.orgUnit,\n            tool: event.toolName,\n            metadata: { ...dlpMeta, strategy: dlpMasker['config'].strategy },\n          });\n        } else {\n          stats.dlpDetected++;\n          await audit.log({\n            sessionId,\n            event: 'dlp_detected',\n            userId: identity.userId,\n            role: identity.role,\n            orgUnit: identity.orgUnit,\n            tool: event.toolName,\n            metadata: dlpMeta,\n          });\n        }\n      }\n    }\n\n    await audit.log({\n      sessionId,\n      event: 'tool_result',\n      userId: identity.userId,\n      role: identity.role,\n      orgUnit: identity.orgUnit,\n      tool: event.toolName,\n      input: summarizeParams(event.toolName, event.input),\n      metadata: { isError: event.isError },\n    });\n  });\n\n  pi.on('session_shutdown', async (_event, _ctx) => {\n    configWatcher?.stop();\n    if (!audit) return;\n    await audit.log({\n      sessionId,\n      event: 'session_end',\n      userId: identity?.userId,\n      role: identity?.role,\n      orgUnit: identity?.orgUnit,\n      metadata: {\n        stats: { ...stats },\n        budget: budgetTracker\n          ? { used: budgetTracker.used(), remaining: budgetTracker.remaining() }\n          : undefined,\n        summary: Object.fromEntries(audit.getSummary()),\n      },\n    });\n    await audit.flush();\n  });\n\n  pi.registerCommand('governance', {\n    description: 'Governance status and controls',\n    handler: async (args, ctx) => {\n      const subcommand = args.trim().split(/\\s+/)[0] ?? '';\n\n      if (subcommand === 'status') {\n        const summary = audit.getSummary();\n        const budgetInfo = budgetTracker.isUnlimited()\n          ? 'unlimited'\n          : `${budgetTracker.used()} / ${budgetTracker.used() + budgetTracker.remaining()} (${budgetTracker.remaining()} remaining)`;\n        const lines = [\n          `Role: ${identity.role}`,\n          `Org Unit: ${identity.orgUnit}`,\n          `Mode: ${executionMode}`,\n          `Session: ${sessionId}`,\n          `Budget: ${budgetInfo}`,\n          '',\n          'Session Stats:',\n          `  Allowed: ${stats.allowed}`,\n          `  Denied: ${stats.denied}`,\n          `  Approvals: ${stats.approvals}`,\n          `  Dry-run blocks: ${stats.dryRun}`,\n          `  Budget exceeded: ${stats.budgetExceeded}`,\n          `  Config tampered: ${stats.configTampered}`,\n          `  DLP blocked: ${stats.dlpBlocked}`,\n          `  DLP detected: ${stats.dlpDetected}`,\n          `  DLP masked: ${stats.dlpMasked}`,\n          '',\n          'Audit Events:',\n          ...[...summary.entries()].map(([k, v]) => `  ${k}: ${v}`),\n        ];\n        ctx.ui.notify(lines.join('\\n'), 'info');\n      } else if (subcommand === 'init') {\n        const { startWizardServer } = await import('../lib/wizard/index.js');\n\n        ctx.ui.notify('Starting governance configuration wizard...', 'info');\n\n        const { port, close } = await startWizardServer({\n          workingDirectory: ctx.workingDirectory,\n          existingConfig: config,\n          onComplete: (files) => {\n            const names = files.map((f) => f.path).join(', ');\n            ctx.ui.notify(`Configuration saved: ${names}`, 'info');\n            close();\n          },\n          onError: (err) => {\n            ctx.ui.notify(`Wizard error: ${err.message}`, 'error');\n            close();\n          },\n        });\n\n        const url = `http://localhost:${port}`;\n        const { exec } = await import('node:child_process');\n        const openCmd =\n          process.platform === 'darwin'\n            ? 'open'\n            : process.platform === 'win32'\n              ? 'start'\n              : 'xdg-open';\n        exec(`${openCmd} ${url}`);\n\n        ctx.ui.notify(`Wizard running at ${url}`, 'info');\n      } else {\n        ctx.ui.notify('Usage: /governance status | init', 'info');\n      }\n    },\n  });\n};\n\nexport default piGovernance;\n\n// Re-export types for consumers\nexport type {\n  ExtensionFactory,\n  ExtensionAPI,\n  ExtensionContext,\n  ExtensionUI,\n  ToolCallEvent,\n  ToolResultEvent,\n};\n","import { existsSync, readFileSync } from 'fs';\nimport { parse as parseYaml } from 'yaml';\nimport { Value } from '@sinclair/typebox/value';\nimport { GovernanceConfigSchema, type GovernanceConfig } from './schema.js';\nimport { DEFAULTS } from './defaults.js';\n\nfunction getConfigPaths(): (string | undefined)[] {\n  return [\n    process.env['PI_GOV_GOVERNANCE_CONFIG'],\n    '.pi/governance.yaml',\n    `${process.env['HOME']}/.pi/agent/governance.yaml`,\n  ];\n}\n\nexport function loadConfig(): { config: GovernanceConfig; source: string } {\n  for (const path of getConfigPaths()) {\n    if (path && existsSync(path)) {\n      const raw = readFileSync(path, 'utf-8');\n      const parsed = parseYaml(raw);\n\n      const resolved = resolveEnvVars(parsed);\n\n      const errors = [...Value.Errors(GovernanceConfigSchema, resolved)];\n      if (errors.length > 0) {\n        throw new ConfigValidationError(\n          path,\n          errors.map((e) => ({ path: e.path, message: e.message })),\n        );\n      }\n\n      const config = Value.Default(GovernanceConfigSchema, resolved) as GovernanceConfig;\n      return { config, source: path };\n    }\n  }\n\n  return { config: DEFAULTS, source: 'built-in' };\n}\n\nfunction resolveEnvVars(obj: unknown): unknown {\n  if (typeof obj === 'string') {\n    return obj.replace(/\\$\\{(\\w+)\\}/g, (_, name: string) => process.env[name] ?? '');\n  }\n  if (Array.isArray(obj)) return obj.map(resolveEnvVars);\n  if (obj && typeof obj === 'object') {\n    return Object.fromEntries(\n      Object.entries(obj as Record<string, unknown>).map(([k, v]) => [k, resolveEnvVars(v)]),\n    );\n  }\n  return obj;\n}\n\nexport class ConfigValidationError extends Error {\n  constructor(path: string, errors: Array<{ path: string; message: string }>) {\n    const details = errors.map((e) => `  ${e.path}: ${e.message}`).join('\\n');\n    super(`Invalid governance config at ${path}:\\n${details}`);\n    this.name = 'ConfigValidationError';\n  }\n}\n","import { Type, type Static } from '@sinclair/typebox';\n\nconst AuthEnvConfig = Type.Object({\n  user_var: Type.String({ default: 'PI_GOV_USER' }),\n  role_var: Type.String({ default: 'PI_GOV_ROLE' }),\n  org_unit_var: Type.String({ default: 'PI_GOV_ORG_UNIT' }),\n});\n\nconst AuthLocalConfig = Type.Object({\n  users_file: Type.String({ default: './users.yaml' }),\n});\n\nconst AuthConfig = Type.Object({\n  provider: Type.Union([Type.Literal('env'), Type.Literal('local'), Type.Literal('oidc')], {\n    default: 'env',\n  }),\n  env: Type.Optional(AuthEnvConfig),\n  local: Type.Optional(AuthLocalConfig),\n});\n\nexport type AuthConfigType = Static<typeof AuthConfig>;\n\nconst YamlPolicyConfig = Type.Object({\n  rules_file: Type.String({ default: './governance-rules.yaml' }),\n});\n\nconst OsoPolicyConfig = Type.Object({\n  polar_files: Type.Array(Type.String(), {\n    default: ['./policies/base.polar', './policies/tools.polar'],\n  }),\n});\n\nconst PolicyConfig = Type.Object({\n  engine: Type.Union([Type.Literal('yaml'), Type.Literal('oso')], { default: 'yaml' }),\n  yaml: Type.Optional(YamlPolicyConfig),\n  oso: Type.Optional(OsoPolicyConfig),\n});\n\nconst TemplatesConfig = Type.Object({\n  directory: Type.String({ default: './templates/' }),\n  default: Type.String({ default: 'project-lead' }),\n});\n\nconst HitlWebhookConfig = Type.Object({\n  url: Type.String(),\n});\n\nconst HitlConfig = Type.Object({\n  default_mode: Type.Union(\n    [Type.Literal('autonomous'), Type.Literal('supervised'), Type.Literal('dry_run')],\n    { default: 'supervised' },\n  ),\n  approval_channel: Type.Union([Type.Literal('cli'), Type.Literal('webhook')], { default: 'cli' }),\n  timeout_seconds: Type.Number({ default: 300, minimum: 10, maximum: 3600 }),\n  webhook: Type.Optional(HitlWebhookConfig),\n});\n\nconst JsonlSinkConfig = Type.Object({\n  type: Type.Literal('jsonl'),\n  path: Type.String({ default: '~/.pi/agent/audit.jsonl' }),\n});\n\nconst WebhookSinkConfig = Type.Object({\n  type: Type.Literal('webhook'),\n  url: Type.String(),\n});\n\nconst PostgresSinkConfig = Type.Object({\n  type: Type.Literal('postgres'),\n  connection: Type.String(),\n});\n\nconst AuditSinkConfig = Type.Union([JsonlSinkConfig, WebhookSinkConfig, PostgresSinkConfig]);\n\nconst AuditConfig = Type.Object({\n  sinks: Type.Array(AuditSinkConfig, {\n    default: [{ type: 'jsonl', path: '~/.pi/agent/audit.jsonl' }],\n  }),\n});\n\nconst OrgUnitOverride = Type.Object({\n  hitl: Type.Optional(Type.Partial(HitlConfig)),\n  policy: Type.Optional(\n    Type.Object({\n      extra_polar: Type.Optional(Type.String()),\n      extra_rules: Type.Optional(Type.String()),\n    }),\n  ),\n});\n\n// --- DLP (Data Loss Prevention) ---\n\nconst DlpMaskingConfig = Type.Object({\n  strategy: Type.Union([Type.Literal('partial'), Type.Literal('full'), Type.Literal('hash')], {\n    default: 'partial',\n  }),\n  show_chars: Type.Optional(Type.Number({ default: 4, minimum: 0 })),\n  placeholder: Type.Optional(Type.String({ default: '***' })),\n});\n\nconst DlpCustomPatternConfig = Type.Object({\n  name: Type.String(),\n  pattern: Type.String(),\n  severity: Type.Union([\n    Type.Literal('low'),\n    Type.Literal('medium'),\n    Type.Literal('high'),\n    Type.Literal('critical'),\n  ]),\n  action: Type.Optional(\n    Type.Union([Type.Literal('audit'), Type.Literal('mask'), Type.Literal('block')]),\n  ),\n});\n\nconst DlpAllowlistEntryConfig = Type.Object({\n  pattern: Type.String(),\n});\n\nconst DlpRoleOverrideConfig = Type.Object({\n  enabled: Type.Optional(Type.Boolean()),\n  mode: Type.Optional(\n    Type.Union([Type.Literal('audit'), Type.Literal('mask'), Type.Literal('block')]),\n  ),\n  on_input: Type.Optional(\n    Type.Union([Type.Literal('audit'), Type.Literal('mask'), Type.Literal('block')]),\n  ),\n  on_output: Type.Optional(\n    Type.Union([Type.Literal('audit'), Type.Literal('mask'), Type.Literal('block')]),\n  ),\n});\n\nconst DlpConfig = Type.Object({\n  enabled: Type.Boolean({ default: false }),\n  mode: Type.Optional(\n    Type.Union([Type.Literal('audit'), Type.Literal('mask'), Type.Literal('block')], {\n      default: 'audit',\n    }),\n  ),\n  on_input: Type.Optional(\n    Type.Union([Type.Literal('audit'), Type.Literal('mask'), Type.Literal('block')]),\n  ),\n  on_output: Type.Optional(\n    Type.Union([Type.Literal('audit'), Type.Literal('mask'), Type.Literal('block')]),\n  ),\n  masking: Type.Optional(DlpMaskingConfig),\n  severity_threshold: Type.Optional(\n    Type.Union(\n      [Type.Literal('low'), Type.Literal('medium'), Type.Literal('high'), Type.Literal('critical')],\n      { default: 'low' },\n    ),\n  ),\n  built_in: Type.Optional(\n    Type.Object({\n      secrets: Type.Boolean({ default: true }),\n      pii: Type.Boolean({ default: true }),\n    }),\n  ),\n  custom_patterns: Type.Optional(Type.Array(DlpCustomPatternConfig)),\n  allowlist: Type.Optional(Type.Array(DlpAllowlistEntryConfig)),\n  role_overrides: Type.Optional(Type.Record(Type.String(), DlpRoleOverrideConfig)),\n});\n\nexport type DlpConfigType = Static<typeof DlpConfig>;\n\n// --- Dependency Guardian ---\n\nconst DependencyGuardianChecksConfig = Type.Object({\n  existence: Type.Boolean({ default: true }),\n  reputation: Type.Boolean({ default: true }),\n  typosquatting: Type.Boolean({ default: true }),\n  install_scripts: Type.Boolean({ default: true }),\n  vulnerabilities: Type.Boolean({ default: true }),\n});\n\nconst DependencyGuardianConfig = Type.Object({\n  enabled: Type.Boolean({ default: true }),\n  checks: Type.Optional(DependencyGuardianChecksConfig),\n  risk_thresholds: Type.Optional(\n    Type.Object({\n      min_age_days: Type.Number({ default: 30, minimum: 0 }),\n      min_weekly_downloads: Type.Number({ default: 100, minimum: 0 }),\n    }),\n  ),\n  on_risk: Type.Optional(\n    Type.Union([Type.Literal('escalate'), Type.Literal('block'), Type.Literal('audit')], {\n      default: 'escalate',\n    }),\n  ),\n  allowlist: Type.Optional(Type.Array(Type.String())),\n  blocklist: Type.Optional(Type.Array(Type.String())),\n  blocklist_patterns: Type.Optional(Type.Array(Type.String())),\n  custom_registry_bypass: Type.Boolean({ default: true }),\n});\n\nexport type DependencyGuardianConfigType = Static<typeof DependencyGuardianConfig>;\n\nexport const GovernanceConfigSchema = Type.Object({\n  auth: Type.Optional(AuthConfig),\n  policy: Type.Optional(PolicyConfig),\n  templates: Type.Optional(TemplatesConfig),\n  hitl: Type.Optional(HitlConfig),\n  audit: Type.Optional(AuditConfig),\n  dlp: Type.Optional(DlpConfig),\n  dependency_guardian: Type.Optional(DependencyGuardianConfig),\n  org_units: Type.Optional(Type.Record(Type.String(), OrgUnitOverride)),\n});\n\nexport type GovernanceConfig = Static<typeof GovernanceConfigSchema>;\n","import type { IdentityProvider, ResolvedIdentity } from './provider.js';\n\nexport class EnvIdentityProvider implements IdentityProvider {\n  name = 'env';\n\n  constructor(\n    private userVar: string = 'PI_GOV_USER',\n    private roleVar: string = 'PI_GOV_ROLE',\n    private orgUnitVar: string = 'PI_GOV_ORG_UNIT',\n  ) {}\n\n  async resolve(): Promise<ResolvedIdentity | null> {\n    const userId = process.env[this.userVar];\n    const role = process.env[this.roleVar];\n    const orgUnit = process.env[this.orgUnitVar];\n\n    if (!userId || !role) return null;\n\n    return {\n      userId,\n      role,\n      orgUnit: orgUnit ?? 'default',\n      source: 'env',\n    };\n  }\n}\n","import { readFileSync } from 'fs';\nimport { parse as parseYaml } from 'yaml';\nimport type { IdentityProvider, ResolvedIdentity } from './provider.js';\n\ninterface UserEntry {\n  role: string;\n  org_unit?: string;\n}\n\nexport class LocalIdentityProvider implements IdentityProvider {\n  name = 'local';\n  private users: Record<string, UserEntry>;\n\n  constructor(usersFilePath: string) {\n    const raw = readFileSync(usersFilePath, 'utf-8');\n    this.users = parseYaml(raw) as Record<string, UserEntry>;\n  }\n\n  async resolve(): Promise<ResolvedIdentity | null> {\n    // Try to determine the current system username\n    const username = process.env.USER || process.env.USERNAME;\n    if (!username) return null;\n\n    const entry = this.users[username];\n    if (!entry) return null;\n\n    return {\n      userId: username,\n      role: entry.role,\n      orgUnit: entry.org_unit ?? 'default',\n      source: 'local',\n    };\n  }\n}\n","import type { IdentityProvider, ResolvedIdentity } from './provider.js';\nimport type { AuthConfigType } from '../config/schema.js';\nimport { EnvIdentityProvider } from './env-provider.js';\nimport { LocalIdentityProvider } from './local-provider.js';\n\nexport class IdentityChain {\n  private providers: IdentityProvider[];\n\n  constructor(providers: IdentityProvider[]) {\n    this.providers = providers;\n  }\n\n  async resolve(): Promise<ResolvedIdentity> {\n    for (const provider of this.providers) {\n      const identity = await provider.resolve();\n      if (identity) return identity;\n    }\n\n    // Fallback: default restricted identity\n    return {\n      userId: 'unknown',\n      role: 'analyst', // most restrictive role by default\n      orgUnit: 'default',\n      source: 'fallback',\n    };\n  }\n}\n\nexport function createIdentityChain(config?: AuthConfigType): IdentityChain {\n  const providers: IdentityProvider[] = [];\n\n  // Always try env first (fastest, works in CI)\n  providers.push(\n    new EnvIdentityProvider(\n      config?.env?.user_var,\n      config?.env?.role_var,\n      config?.env?.org_unit_var,\n    ),\n  );\n\n  // Then try local file if configured\n  if (config?.provider === 'local' && config.local?.users_file) {\n    try {\n      providers.push(new LocalIdentityProvider(config.local.users_file));\n    } catch {\n      // users file not found — skip this provider\n    }\n  }\n\n  return new IdentityChain(providers);\n}\n","import { readFileSync } from 'fs';\nimport { parse as parseYaml } from 'yaml';\nimport { minimatch } from 'minimatch';\nimport type {\n  PolicyEngine,\n  PolicyDecision,\n  PathOperation,\n  ExecutionMode,\n  BashOverrides,\n} from './engine.js';\n\nexport interface YamlRole {\n  allowed_tools: string[];\n  blocked_tools: string[];\n  prompt_template: string;\n  execution_mode: ExecutionMode;\n  human_approval: {\n    required_for: string[];\n    auto_approve?: string[];\n  };\n  token_budget_daily: number;\n  allowed_paths: string[];\n  blocked_paths: string[];\n  bash_overrides?: {\n    additional_blocked?: string[];\n    additional_allowed?: string[];\n  };\n}\n\nexport interface YamlRules {\n  roles: Record<string, YamlRole>;\n}\n\nexport class YamlPolicyEngine implements PolicyEngine {\n  private rules: YamlRules;\n\n  constructor(rulesFilePathOrRules: string | YamlRules) {\n    if (typeof rulesFilePathOrRules === 'string') {\n      const raw = readFileSync(rulesFilePathOrRules, 'utf-8');\n      this.rules = parseYaml(raw) as YamlRules;\n    } else {\n      this.rules = rulesFilePathOrRules;\n    }\n  }\n\n  private getRole(role: string): YamlRole {\n    const r = this.rules.roles[role];\n    if (!r) {\n      throw new Error(\n        `Unknown role: ${role}. Available roles: ${Object.keys(this.rules.roles).join(', ')}`,\n      );\n    }\n    return r;\n  }\n\n  evaluateTool(role: string, tool: string): PolicyDecision {\n    const r = this.getRole(role);\n\n    // Check blocked list first\n    if (r.blocked_tools.includes(tool)) return 'deny';\n\n    // Check allowed list\n    if (r.allowed_tools.includes('all') || r.allowed_tools.includes(tool)) {\n      return 'allow';\n    }\n\n    // Not in either list — deny by default\n    return 'deny';\n  }\n\n  evaluatePath(\n    role: string,\n    _orgUnit: string,\n    _operation: PathOperation,\n    path: string,\n  ): PolicyDecision {\n    const r = this.getRole(role);\n\n    // Check blocked paths first (takes precedence)\n    for (const pattern of r.blocked_paths) {\n      if (minimatch(path, pattern, { dot: true })) {\n        return 'deny';\n      }\n    }\n\n    // Check allowed paths\n    for (const pattern of r.allowed_paths) {\n      const resolved = pattern.replace('{{project_path}}', process.cwd());\n      if (minimatch(path, resolved, { dot: true })) {\n        return 'allow';\n      }\n    }\n\n    // Not in allowed paths — deny\n    return 'deny';\n  }\n\n  requiresApproval(role: string, tool: string): boolean {\n    const r = this.getRole(role);\n\n    // Auto-approve takes precedence\n    if (r.human_approval.auto_approve?.includes(tool)) return false;\n\n    // Check required list\n    if (r.human_approval.required_for.includes('all')) return true;\n    return r.human_approval.required_for.includes(tool);\n  }\n\n  getExecutionMode(role: string): ExecutionMode {\n    return this.getRole(role).execution_mode;\n  }\n\n  getTemplateName(role: string): string {\n    return this.getRole(role).prompt_template;\n  }\n\n  getBashOverrides(role: string): BashOverrides {\n    const r = this.getRole(role);\n    const overrides = r.bash_overrides;\n    if (!overrides) return {};\n\n    return {\n      additionalBlocked: overrides.additional_blocked?.map((p) => new RegExp(p)),\n      additionalAllowed: overrides.additional_allowed?.map((p) => new RegExp(p)),\n    };\n  }\n\n  getTokenBudget(role: string): number {\n    return this.getRole(role).token_budget_daily;\n  }\n}\n","export const SAFE_PATTERNS: RegExp[] = [\n  // File viewing\n  /^(cat|head|tail|less|more)\\s/,\n  /^(file|stat|wc|md5sum|sha256sum)\\s/,\n\n  // Directory listing\n  /^(ls|ll|la|tree|du|df)\\b/,\n  /^(pwd|cd)\\b/,\n\n  // Searching\n  /^(grep|rg|ag|ack|find|fd|locate)\\s/,\n  /^(which|whereis|type|command)\\s/,\n\n  // Text processing (read-only)\n  /^(sort|uniq|cut|awk|sed)\\s.*(?!-i)/, // sed without -i (in-place)\n  /^(tr|diff|comm|join|paste)\\s/,\n  /^(jq|yq|xmlstarlet)\\s/,\n\n  // Git (read-only operations)\n  /^git\\s+(log|status|diff|show|blame|branch|tag|remote|stash list)\\b/,\n  /^git\\s+(ls-files|ls-tree|rev-parse|describe)\\b/,\n\n  // System info\n  /^(whoami|id|groups|uname|hostname|date|uptime|env|printenv)\\b/,\n  /^(echo|printf)\\s/,\n\n  // Package info (not install)\n  /^(npm|yarn|pnpm)\\s+(list|ls|info|show|view|outdated|audit)\\b/,\n  /^pip\\s+(list|show|freeze)\\b/,\n  /^(node|python|ruby|go)\\s+--version\\b/,\n  /^(node|python|ruby)\\s+-e\\s/,\n\n  // Networking (read-only)\n  /^(ping|dig|nslookup|host|traceroute|tracepath)\\s/,\n  /^curl\\s.*--head\\b/,\n  /^curl\\s.*-I\\b/,\n\n  // Additional file viewing / inspection\n  /^(basename|dirname|realpath|readlink)\\s/,\n  /^(xxd|od|hexdump)\\s/,\n  /^(strings|nm|objdump)\\s/,\n\n  // Additional search / navigation\n  /^(xargs)\\s/,\n  /^(tee)\\s/,\n\n  // Additional text processing (read-only)\n  /^(fmt|fold|column|expand|unexpand)\\s/,\n  /^(tac|rev|nl)\\s/,\n  /^(yes|seq|shuf)\\s/,\n\n  // Additional system info\n  /^(lsof|ps|top|htop|vmstat|iostat|free|df)\\b/,\n  /^(lscpu|lsblk|lsusb|lspci)\\b/,\n  /^(nproc|getconf)\\b/,\n\n  // Additional git read-only\n  /^git\\s+(config\\s+--get|config\\s+-l|shortlog|reflog|cherry)\\b/,\n  /^git\\s+(cat-file|count-objects|fsck|verify-pack)\\b/,\n];\n\nexport const DANGEROUS_PATTERNS: RegExp[] = [\n  // Destructive file operations\n  /\\brm\\s+(-[a-zA-Z]*r|-[a-zA-Z]*f|--recursive|--force)\\b/,\n  /\\brm\\s+-[a-zA-Z]*rf\\b/,\n  /\\bshred\\b/,\n\n  // Privilege escalation\n  /\\bsudo\\b/,\n  /\\bsu\\s+-?\\s*\\w/,\n  /\\bdoas\\b/,\n\n  // Permission/ownership changes\n  /\\bchmod\\b/,\n  /\\bchown\\b/,\n  /\\bchgrp\\b/,\n\n  // Disk/partition operations\n  /\\bdd\\b.*\\bof=/,\n  /\\bmkfs\\b/,\n  /\\bfdisk\\b/,\n  /\\bparted\\b/,\n  /\\bmount\\b/,\n  /\\bumount\\b/,\n\n  // Remote code execution\n  /\\bcurl\\b.*\\|\\s*(bash|sh|zsh|python|perl|ruby)\\b/,\n  /\\bwget\\b.*\\|\\s*(bash|sh|zsh|python|perl|ruby)\\b/,\n  /\\bcurl\\b.*>\\s*.*\\.sh\\s*&&/,\n\n  // Remote access\n  /\\bssh\\b/,\n  /\\bscp\\b/,\n  /\\brsync\\b.*:\\//,\n  /\\bnc\\s+(-[a-zA-Z]*l|-[a-zA-Z]*p|--listen)\\b/,\n  /\\bncat\\b/,\n  /\\bsocat\\b/,\n  /\\btelnet\\b/,\n\n  // System modification\n  /\\bsystemctl\\s+(start|stop|restart|enable|disable)\\b/,\n  /\\bservice\\s+\\w+\\s+(start|stop|restart)\\b/,\n  /\\biptables\\b/,\n  /\\bufw\\b/,\n  /\\bfirewall-cmd\\b/,\n\n  // Package installation (can run arbitrary post-install scripts)\n  /\\bnpm\\s+(install|i|add|ci)\\b/,\n  /\\byarn\\s+(add|install)\\b/,\n  /\\bpnpm\\s+(add|install|i)\\b/,\n  /\\bpip\\s+install\\b/,\n  /\\bapt(-get)?\\s+install\\b/,\n  /\\bbrew\\s+install\\b/,\n  /\\bcargo\\s+install\\b/,\n\n  // Environment variable manipulation (can leak secrets)\n  /\\bexport\\b.*(KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL)/i,\n\n  // Cron / scheduled tasks\n  /\\bcrontab\\b/,\n  /\\bat\\s+/,\n\n  // Container escape vectors\n  /\\bdocker\\s+(run|exec|build|push|pull)\\b/,\n  /\\bkubectl\\s+(exec|run|apply|delete)\\b/,\n\n  // Process manipulation\n  /\\bkill\\b/,\n  /\\bkillall\\b/,\n  /\\bpkill\\b/,\n\n  // History manipulation\n  /\\bhistory\\s+-c\\b/,\n  /\\bunset\\s+HISTFILE\\b/,\n\n  // Compiler/build (can execute arbitrary code)\n  /\\bmake\\s/,\n  /\\bgcc\\b/,\n  /\\bg\\+\\+/,\n\n  // Governance config tampering — shell-based writes to governance files\n  /(cat|echo|printf)\\s.*>\\s*.*governance(-rules)?\\.yaml/,\n  /\\btee\\s+.*governance(-rules)?\\.yaml/,\n  /sed\\s+-i.*governance(-rules)?\\.yaml/,\n  /(cp|mv|rm)\\s.*governance(-rules)?\\.yaml/,\n  /(cat|echo|printf)\\s.*>\\s*.*\\.pi\\/governance/,\n  /\\btee\\s+.*\\.pi\\/governance/,\n  /sed\\s+-i.*\\.pi\\/governance/,\n  /(cp|mv|rm)\\s.*\\.pi\\/governance/,\n];\n","import { SAFE_PATTERNS, DANGEROUS_PATTERNS } from './patterns.js';\nimport type { BashOverrides } from '../policy/engine.js';\n\nexport type BashClassification = 'safe' | 'dangerous' | 'needs_review';\n\nexport class BashClassifier {\n  private safePatterns: RegExp[];\n  private dangerousPatterns: RegExp[];\n\n  constructor(overrides?: BashOverrides) {\n    this.safePatterns = [...SAFE_PATTERNS, ...(overrides?.additionalAllowed ?? [])];\n    this.dangerousPatterns = [...DANGEROUS_PATTERNS, ...(overrides?.additionalBlocked ?? [])];\n  }\n\n  classify(command: string): BashClassification {\n    const trimmed = command.trim();\n\n    // Check dangerous patterns against the full unsplit command first.\n    // This catches patterns like \"curl ... | bash\" that span pipe boundaries.\n    for (const pattern of this.dangerousPatterns) {\n      if (pattern.test(trimmed)) return 'dangerous';\n    }\n\n    // Multi-command detection: if the command contains pipes, semicolons,\n    // or && / ||, classify each segment independently and return the\n    // most restrictive classification\n    const segments = this.splitCommand(trimmed);\n\n    if (segments.length > 1) {\n      const classifications = segments.map((s) => this.classifySingle(s));\n      if (classifications.includes('dangerous')) return 'dangerous';\n      if (classifications.includes('needs_review')) return 'needs_review';\n      return 'safe';\n    }\n\n    return this.classifySingle(trimmed);\n  }\n\n  private classifySingle(command: string): BashClassification {\n    const trimmed = command.trim();\n\n    // Check dangerous first (takes precedence)\n    for (const pattern of this.dangerousPatterns) {\n      if (pattern.test(trimmed)) return 'dangerous';\n    }\n\n    // Check safe\n    for (const pattern of this.safePatterns) {\n      if (pattern.test(trimmed)) return 'safe';\n    }\n\n    // Default: needs review\n    return 'needs_review';\n  }\n\n  private splitCommand(command: string): string[] {\n    // Split on pipes, semicolons, && and || while respecting quotes\n    // This is a simplified parser — not a full shell parser\n    const segments: string[] = [];\n    let current = '';\n    let inSingleQuote = false;\n    let inDoubleQuote = false;\n    let escaped = false;\n\n    for (let i = 0; i < command.length; i++) {\n      const char = command[i]!;\n\n      if (escaped) {\n        current += char;\n        escaped = false;\n        continue;\n      }\n\n      if (char === '\\\\') {\n        escaped = true;\n        current += char;\n        continue;\n      }\n\n      if (char === \"'\" && !inDoubleQuote) {\n        inSingleQuote = !inSingleQuote;\n        current += char;\n        continue;\n      }\n\n      if (char === '\"' && !inSingleQuote) {\n        inDoubleQuote = !inDoubleQuote;\n        current += char;\n        continue;\n      }\n\n      if (!inSingleQuote && !inDoubleQuote) {\n        if (char === '|' && command[i + 1] !== '|') {\n          segments.push(current.trim());\n          current = '';\n          continue;\n        }\n        if (char === ';') {\n          segments.push(current.trim());\n          current = '';\n          continue;\n        }\n        if (char === '&' && command[i + 1] === '&') {\n          segments.push(current.trim());\n          current = '';\n          i++; // skip second &\n          continue;\n        }\n        if (char === '|' && command[i + 1] === '|') {\n          segments.push(current.trim());\n          current = '';\n          i++; // skip second |\n          continue;\n        }\n      }\n\n      current += char;\n    }\n\n    if (current.trim()) segments.push(current.trim());\n    return segments.filter((s) => s.length > 0);\n  }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { AuditRecord, AuditEventType } from './schema.js';\nimport type { AuditSink } from './sinks/sink.js';\nimport { JsonlAuditSink } from './sinks/jsonl.js';\nimport { WebhookAuditSink } from './sinks/webhook.js';\n\ninterface AuditSinkConfig {\n  type: 'jsonl' | 'webhook' | 'postgres';\n  path?: string;\n  url?: string;\n  connection?: string;\n}\n\ninterface AuditConfig {\n  sinks: AuditSinkConfig[];\n}\n\nexport class AuditLogger {\n  private sinks: AuditSink[];\n  private counts: Map<AuditEventType, number> = new Map();\n\n  constructor(config?: AuditConfig) {\n    const sinkConfigs = config?.sinks ?? [\n      { type: 'jsonl' as const, path: '~/.pi/agent/audit.jsonl' },\n    ];\n    this.sinks = [];\n\n    for (const sc of sinkConfigs) {\n      if (sc.type === 'jsonl') {\n        this.sinks.push(new JsonlAuditSink(sc.path ?? '~/.pi/agent/audit.jsonl'));\n      } else if (sc.type === 'webhook' && sc.url) {\n        this.sinks.push(new WebhookAuditSink(sc.url));\n      }\n      // postgres: skip for now\n    }\n\n    // Ensure at least one sink\n    if (this.sinks.length === 0) {\n      this.sinks.push(new JsonlAuditSink('~/.pi/agent/audit.jsonl'));\n    }\n  }\n\n  async log(record: Omit<AuditRecord, 'id' | 'timestamp'>): Promise<void> {\n    const full: AuditRecord = {\n      ...record,\n      id: randomUUID(),\n      timestamp: new Date().toISOString(),\n    };\n\n    this.counts.set(full.event, (this.counts.get(full.event) ?? 0) + 1);\n\n    await Promise.all(this.sinks.map((s) => s.write(full as unknown as Record<string, unknown>)));\n  }\n\n  async flush(): Promise<void> {\n    await Promise.all(this.sinks.map((s) => s.flush()));\n  }\n\n  getSummary(): Map<AuditEventType, number> {\n    return new Map(this.counts);\n  }\n}\n","import { appendFile, mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { AuditSink } from './sink.js';\n\nexport class JsonlAuditSink implements AuditSink {\n  private path: string;\n  private buffer: Record<string, unknown>[] = [];\n  private readonly flushThreshold = 10;\n\n  constructor(path: string) {\n    this.path = path.replace(/^~/, homedir());\n  }\n\n  async write(record: Record<string, unknown>): Promise<void> {\n    this.buffer.push(record);\n    if (this.buffer.length >= this.flushThreshold) {\n      await this.flush();\n    }\n  }\n\n  async flush(): Promise<void> {\n    if (this.buffer.length === 0) return;\n    const lines = this.buffer.map((r) => JSON.stringify(r)).join('\\n') + '\\n';\n    this.buffer = [];\n    await mkdir(dirname(this.path), { recursive: true });\n    await appendFile(this.path, lines, 'utf-8');\n  }\n}\n","import type { AuditSink } from './sink.js';\n\nexport class WebhookAuditSink implements AuditSink {\n  private url: string;\n  private buffer: Record<string, unknown>[] = [];\n  private readonly flushThreshold = 10;\n\n  constructor(url: string) {\n    this.url = url;\n  }\n\n  async write(record: Record<string, unknown>): Promise<void> {\n    this.buffer.push(record);\n    if (this.buffer.length >= this.flushThreshold) {\n      await this.flush();\n    }\n  }\n\n  async flush(): Promise<void> {\n    if (this.buffer.length === 0) return;\n    const records = [...this.buffer];\n    this.buffer = [];\n\n    try {\n      await this.send(records);\n    } catch {\n      // Retry once\n      try {\n        await this.send(records);\n      } catch {\n        // Drop records after second failure\n      }\n    }\n  }\n\n  private async send(records: Record<string, unknown>[]): Promise<void> {\n    const controller = new AbortController();\n    const timeout = setTimeout(() => controller.abort(), 10_000);\n\n    try {\n      const response = await fetch(this.url, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify(records),\n        signal: controller.signal,\n      });\n\n      if (!response.ok) {\n        throw new Error(`Webhook returned ${response.status}`);\n      }\n    } finally {\n      clearTimeout(timeout);\n    }\n  }\n}\n","import type { ApprovalFlow, ApprovalResult, GovernanceToolCall, ConfirmUI } from './approval.js';\n\nexport class CliApprover implements ApprovalFlow {\n  private ui: ConfirmUI;\n  private timeoutSeconds: number;\n\n  constructor(ui: ConfirmUI, timeoutSeconds: number = 300) {\n    this.ui = ui;\n    this.timeoutSeconds = timeoutSeconds;\n  }\n\n  async requestApproval(\n    toolCall: GovernanceToolCall,\n    context: { userId: string; role: string; orgUnit: string },\n  ): Promise<ApprovalResult> {\n    const title = `Approval Required: ${toolCall.toolName}`;\n    const inputSummary = Object.entries(toolCall.input)\n      .map(\n        ([k, v]) =>\n          `  ${k}: ${typeof v === 'string' ? v.slice(0, 200) : JSON.stringify(v).slice(0, 200)}`,\n      )\n      .join('\\n');\n    const message = `User: ${context.userId} (${context.role})\\nOrg: ${context.orgUnit}\\n\\nTool: ${toolCall.toolName}\\nInput:\\n${inputSummary}`;\n\n    const start = Date.now();\n\n    try {\n      const approved = await this.ui.confirm(title, message, {\n        timeout: this.timeoutSeconds * 1000,\n      });\n\n      return {\n        approved,\n        approver: 'cli',\n        duration: Date.now() - start,\n        reason: approved ? undefined : 'Denied by user',\n      };\n    } catch {\n      // Timeout or error — deny\n      return {\n        approved: false,\n        approver: 'cli',\n        duration: Date.now() - start,\n        reason: 'Approval timed out',\n      };\n    }\n  }\n}\n","import type { ApprovalFlow, ApprovalResult, GovernanceToolCall } from './approval.js';\n\nexport class WebhookApprover implements ApprovalFlow {\n  private url: string;\n  private timeoutMs: number;\n\n  constructor(url: string, timeoutSeconds: number = 300) {\n    this.url = url;\n    this.timeoutMs = timeoutSeconds * 1000;\n  }\n\n  async requestApproval(\n    toolCall: GovernanceToolCall,\n    context: { userId: string; role: string; orgUnit: string },\n  ): Promise<ApprovalResult> {\n    const start = Date.now();\n    const controller = new AbortController();\n    const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n    try {\n      const response = await fetch(this.url, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({\n          toolCall: { toolName: toolCall.toolName, input: toolCall.input },\n          context,\n        }),\n        signal: controller.signal,\n      });\n\n      if (!response.ok) {\n        return {\n          approved: false,\n          approver: 'webhook',\n          duration: Date.now() - start,\n          reason: `Webhook returned ${response.status}`,\n        };\n      }\n\n      const body = (await response.json()) as { approved: boolean; reason?: string };\n\n      return {\n        approved: body.approved,\n        approver: 'webhook',\n        duration: Date.now() - start,\n        reason: body.reason,\n      };\n    } catch (err) {\n      return {\n        approved: false,\n        approver: 'webhook',\n        duration: Date.now() - start,\n        reason:\n          err instanceof Error && err.name === 'AbortError'\n            ? 'Webhook timed out'\n            : 'Webhook request failed',\n      };\n    } finally {\n      clearTimeout(timeout);\n    }\n  }\n}\n","import { CliApprover } from './cli-approver.js';\nimport { WebhookApprover } from './webhook-approver.js';\n\nexport interface GovernanceToolCall {\n  toolName: string;\n  input: Record<string, unknown>;\n}\n\nexport interface ApprovalResult {\n  approved: boolean;\n  reason?: string;\n  approver: string;\n  duration: number;\n}\n\nexport interface ApprovalFlow {\n  requestApproval(\n    toolCall: GovernanceToolCall,\n    context: { userId: string; role: string; orgUnit: string },\n  ): Promise<ApprovalResult>;\n}\n\nexport interface ConfirmUI {\n  confirm(title: string, message: string, opts?: { timeout?: number }): Promise<boolean>;\n}\n\nexport interface HitlConfig {\n  default_mode: 'autonomous' | 'supervised' | 'dry_run';\n  approval_channel: 'cli' | 'webhook';\n  timeout_seconds: number;\n  webhook?: { url: string };\n}\n\nexport function createApprovalFlow(config: HitlConfig, ui?: ConfirmUI): ApprovalFlow {\n  if (config.approval_channel === 'webhook' && config.webhook?.url) {\n    return new WebhookApprover(config.webhook.url, config.timeout_seconds);\n  }\n\n  // Fall back to CLI (also handles webhook without URL)\n  if (!ui) {\n    throw new Error('CLI approval channel requires a ConfirmUI (ExtensionContext.ui)');\n  }\n\n  return new CliApprover(ui, config.timeout_seconds);\n}\n","/**\n * Tracks tool invocation count as a proxy for token budget.\n * The budget value represents max invocations per session; -1 means unlimited.\n */\nexport class BudgetTracker {\n  private _used = 0;\n  private readonly _budget: number;\n\n  constructor(budget: number) {\n    this._budget = budget;\n  }\n\n  /** Returns false if consuming would exceed the budget. On success, increments the counter. */\n  consume(amount = 1): boolean {\n    if (this._budget === -1) {\n      this._used += amount;\n      return true;\n    }\n    if (this._used + amount > this._budget) return false;\n    this._used += amount;\n    return true;\n  }\n\n  remaining(): number {\n    if (this._budget === -1) return Infinity;\n    return Math.max(0, this._budget - this._used);\n  }\n\n  used(): number {\n    return this._used;\n  }\n\n  isUnlimited(): boolean {\n    return this._budget === -1;\n  }\n}\n","import { watch, readFileSync, type FSWatcher } from 'node:fs';\nimport { parse as parseYaml } from 'yaml';\nimport { Value } from '@sinclair/typebox/value';\nimport { GovernanceConfigSchema, type GovernanceConfig } from './schema.js';\n\n/**\n * Watches a governance config file for changes and triggers a validated reload.\n * Uses fs.watch() with a 500ms debounce to avoid rapid reloads.\n */\nexport class ConfigWatcher {\n  private watcher: FSWatcher | undefined;\n  private debounceTimer: ReturnType<typeof setTimeout> | undefined;\n  private readonly configPath: string;\n  private readonly onChange: (config: GovernanceConfig) => void;\n  private readonly onError?: (error: Error) => void;\n\n  constructor(\n    configPath: string,\n    onChange: (config: GovernanceConfig) => void,\n    onError?: (error: Error) => void,\n  ) {\n    this.configPath = configPath;\n    this.onChange = onChange;\n    this.onError = onError;\n  }\n\n  start(): void {\n    if (this.watcher) return;\n    this.watcher = watch(this.configPath, () => this.handleChange());\n  }\n\n  stop(): void {\n    if (this.debounceTimer) {\n      clearTimeout(this.debounceTimer);\n      this.debounceTimer = undefined;\n    }\n    if (this.watcher) {\n      this.watcher.close();\n      this.watcher = undefined;\n    }\n  }\n\n  private handleChange(): void {\n    if (this.debounceTimer) clearTimeout(this.debounceTimer);\n    this.debounceTimer = setTimeout(() => this.reload(), 500);\n  }\n\n  private reload(): void {\n    try {\n      const raw = readFileSync(this.configPath, 'utf-8');\n      const parsed = parseYaml(raw);\n      const errors = [...Value.Errors(GovernanceConfigSchema, parsed)];\n      if (errors.length > 0) {\n        const msg = errors.map((e) => `${e.path}: ${e.message}`).join('; ');\n        this.onError?.(new Error(`Config validation failed: ${msg}`));\n        return;\n      }\n      const config = Value.Default(GovernanceConfigSchema, parsed) as GovernanceConfig;\n      this.onChange(config);\n    } catch (err) {\n      this.onError?.(err instanceof Error ? err : new Error(String(err)));\n    }\n  }\n}\n","export type DlpSeverity = 'low' | 'medium' | 'high' | 'critical';\nexport type DlpCategory = 'secret' | 'pii' | 'custom';\n\nexport interface DlpPatternDef {\n  name: string;\n  pattern: RegExp;\n  severity: DlpSeverity;\n  category: DlpCategory;\n}\n\nexport const SECRET_PATTERNS: DlpPatternDef[] = [\n  // AWS\n  {\n    name: 'aws_access_key',\n    pattern: /\\b(AKIA[0-9A-Z]{16})\\b/g,\n    severity: 'critical',\n    category: 'secret',\n  },\n  {\n    name: 'aws_secret_key',\n    pattern: /\\b([A-Za-z0-9/+=]{40})(?=\\s|$|\"|')/g,\n    severity: 'critical',\n    category: 'secret',\n  },\n\n  // GitHub\n  {\n    name: 'github_pat',\n    pattern: /\\b(ghp_[A-Za-z0-9]{36,})\\b/g,\n    severity: 'critical',\n    category: 'secret',\n  },\n  {\n    name: 'github_oauth',\n    pattern: /\\b(gho_[A-Za-z0-9]{36,})\\b/g,\n    severity: 'high',\n    category: 'secret',\n  },\n  {\n    name: 'github_app_token',\n    pattern: /\\b(ghu_[A-Za-z0-9]{36,})\\b/g,\n    severity: 'high',\n    category: 'secret',\n  },\n\n  // Anthropic\n  {\n    name: 'anthropic_api_key',\n    pattern: /\\b(sk-ant-api03-[A-Za-z0-9_-]{90,})\\b/g,\n    severity: 'critical',\n    category: 'secret',\n  },\n\n  // OpenAI\n  {\n    name: 'openai_api_key',\n    pattern: /\\b(sk-[A-Za-z0-9]{20,}T3BlbkFJ[A-Za-z0-9]{20,})\\b/g,\n    severity: 'critical',\n    category: 'secret',\n  },\n\n  // JWT\n  {\n    name: 'jwt_token',\n    pattern: /\\b(eyJ[A-Za-z0-9_-]{10,}\\.eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,})\\b/g,\n    severity: 'high',\n    category: 'secret',\n  },\n\n  // Private key headers\n  {\n    name: 'private_key',\n    pattern: /-----BEGIN\\s+(RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,\n    severity: 'critical',\n    category: 'secret',\n  },\n\n  // Database connection strings\n  {\n    name: 'database_url',\n    pattern: /\\b((?:postgres|mysql|mongodb|redis):\\/\\/[^\\s'\"]{10,})\\b/g,\n    severity: 'high',\n    category: 'secret',\n  },\n\n  // Slack\n  {\n    name: 'slack_token',\n    pattern: /\\b(xox[bpras]-[A-Za-z0-9-]{10,})\\b/g,\n    severity: 'high',\n    category: 'secret',\n  },\n\n  // Stripe\n  {\n    name: 'stripe_key',\n    pattern: /\\b([rs]k_(?:live|test)_[A-Za-z0-9]{20,})\\b/g,\n    severity: 'critical',\n    category: 'secret',\n  },\n\n  // npm\n  {\n    name: 'npm_token',\n    pattern: /\\b(npm_[A-Za-z0-9]{36,})\\b/g,\n    severity: 'high',\n    category: 'secret',\n  },\n\n  // SendGrid\n  {\n    name: 'sendgrid_key',\n    pattern: /\\b(SG\\.[A-Za-z0-9_-]{22,}\\.[A-Za-z0-9_-]{22,})\\b/g,\n    severity: 'high',\n    category: 'secret',\n  },\n\n  // Generic API key patterns (env-var style assignments)\n  {\n    name: 'generic_api_key',\n    pattern:\n      /\\b(?:API_KEY|API_SECRET|ACCESS_TOKEN|AUTH_TOKEN|SECRET_KEY)\\s*[=:]\\s*['\"]?([A-Za-z0-9_-]{16,})['\"]?/gi,\n    severity: 'medium',\n    category: 'secret',\n  },\n\n  // High-entropy string near keyword context\n  {\n    name: 'generic_secret_assignment',\n    pattern: /\\b(?:password|passwd|secret|token|credential)\\s*[=:]\\s*['\"]([^'\"]{8,})['\"]?/gi,\n    severity: 'medium',\n    category: 'secret',\n  },\n];\n\nexport const PII_PATTERNS: DlpPatternDef[] = [\n  // SSN (US)\n  {\n    name: 'ssn',\n    pattern: /\\b(\\d{3}-\\d{2}-\\d{4})\\b/g,\n    severity: 'critical',\n    category: 'pii',\n  },\n\n  // Credit card numbers\n  {\n    name: 'credit_card',\n    pattern:\n      /\\b(4\\d{3}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}|5[1-5]\\d{2}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}|3[47]\\d{2}[\\s-]?\\d{6}[\\s-]?\\d{5}|6(?:011|5\\d{2})[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4})\\b/g,\n    severity: 'critical',\n    category: 'pii',\n  },\n\n  // Email address\n  {\n    name: 'email',\n    pattern: /\\b([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,})\\b/g,\n    severity: 'low',\n    category: 'pii',\n  },\n\n  // US phone number\n  {\n    name: 'phone_us',\n    pattern: /\\b(\\+?1?[-.\\s]?\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4})\\b/g,\n    severity: 'medium',\n    category: 'pii',\n  },\n\n  // IPv4 address\n  {\n    name: 'ipv4',\n    pattern:\n      /\\b((?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?))\\b/g,\n    severity: 'low',\n    category: 'pii',\n  },\n];\n","import { SECRET_PATTERNS, PII_PATTERNS } from './patterns.js';\nimport type { DlpPatternDef, DlpSeverity, DlpCategory } from './patterns.js';\n\nexport type DlpAction = 'audit' | 'mask' | 'block';\n\nexport interface DlpMatch {\n  patternName: string;\n  category: DlpCategory;\n  severity: DlpSeverity;\n  start: number;\n  end: number;\n  matched: string;\n}\n\nexport interface DlpScanResult {\n  hasMatches: boolean;\n  matches: DlpMatch[];\n}\n\nexport interface DlpCustomPattern {\n  name: string;\n  pattern: string;\n  severity: DlpSeverity;\n  action?: DlpAction;\n}\n\nexport interface DlpAllowlistEntry {\n  pattern: string;\n}\n\nexport interface DlpScannerConfig {\n  enabled: boolean;\n  mode: DlpAction;\n  on_input?: DlpAction;\n  on_output?: DlpAction;\n  severity_threshold: DlpSeverity;\n  built_in: { secrets: boolean; pii: boolean };\n  custom_patterns: DlpCustomPattern[];\n  allowlist: DlpAllowlistEntry[];\n  pattern_overrides: Map<string, DlpAction>;\n}\n\nconst SEVERITY_ORDER: Record<DlpSeverity, number> = {\n  low: 0,\n  medium: 1,\n  high: 2,\n  critical: 3,\n};\n\ninterface CompiledPattern {\n  def: DlpPatternDef;\n  action?: DlpAction;\n}\n\nexport class DlpScanner {\n  private patterns: CompiledPattern[];\n  private allowlistRegexps: RegExp[];\n  private severityThreshold: number;\n  private config: DlpScannerConfig;\n\n  constructor(config: DlpScannerConfig) {\n    this.config = config;\n    this.severityThreshold = SEVERITY_ORDER[config.severity_threshold];\n    this.patterns = [];\n    this.allowlistRegexps = [];\n\n    // Compile built-in patterns\n    if (config.built_in.secrets) {\n      for (const def of SECRET_PATTERNS) {\n        this.patterns.push({ def });\n      }\n    }\n    if (config.built_in.pii) {\n      for (const def of PII_PATTERNS) {\n        this.patterns.push({ def });\n      }\n    }\n\n    // Compile custom patterns\n    for (const cp of config.custom_patterns) {\n      const def: DlpPatternDef = {\n        name: cp.name,\n        pattern: new RegExp(cp.pattern, 'g'),\n        severity: cp.severity,\n        category: 'custom',\n      };\n      this.patterns.push({ def, action: cp.action });\n    }\n\n    // Compile pattern overrides from config\n    for (const compiled of this.patterns) {\n      const override = config.pattern_overrides.get(compiled.def.name);\n      if (override) {\n        compiled.action = override;\n      }\n    }\n\n    // Compile allowlist\n    for (const entry of config.allowlist) {\n      this.allowlistRegexps.push(new RegExp(entry.pattern));\n    }\n  }\n\n  scan(text: string): DlpScanResult {\n    if (!this.config.enabled || text.length === 0) {\n      return { hasMatches: false, matches: [] };\n    }\n\n    const matches: DlpMatch[] = [];\n\n    for (const compiled of this.patterns) {\n      // Skip patterns below severity threshold\n      if (SEVERITY_ORDER[compiled.def.severity] < this.severityThreshold) {\n        continue;\n      }\n\n      // Reset the regex (global flag means lastIndex needs reset)\n      const regex = new RegExp(compiled.def.pattern.source, compiled.def.pattern.flags);\n\n      let match: RegExpExecArray | null;\n      while ((match = regex.exec(text)) !== null) {\n        // Use the first capturing group if present, otherwise the full match\n        const matched = match[1] ?? match[0];\n        const start = match[1] ? match.index + match[0].indexOf(match[1]) : match.index;\n        const end = start + matched.length;\n\n        // Check allowlist\n        if (this.isAllowlisted(matched)) {\n          continue;\n        }\n\n        matches.push({\n          patternName: compiled.def.name,\n          category: compiled.def.category,\n          severity: compiled.def.severity,\n          start,\n          end,\n          matched,\n        });\n      }\n    }\n\n    return { hasMatches: matches.length > 0, matches };\n  }\n\n  getAction(direction: 'input' | 'output'): DlpAction {\n    if (direction === 'input' && this.config.on_input) {\n      return this.config.on_input;\n    }\n    if (direction === 'output' && this.config.on_output) {\n      return this.config.on_output;\n    }\n    return this.config.mode;\n  }\n\n  getPatternAction(match: DlpMatch, direction: 'input' | 'output'): DlpAction {\n    // Check per-pattern override first\n    const compiled = this.patterns.find((p) => p.def.name === match.patternName);\n    if (compiled?.action) {\n      return compiled.action;\n    }\n\n    // Fall back to directional override or global mode\n    return this.getAction(direction);\n  }\n\n  private isAllowlisted(value: string): boolean {\n    for (const re of this.allowlistRegexps) {\n      if (re.test(value)) return true;\n    }\n    return false;\n  }\n}\n\nexport function compareSeverity(a: DlpSeverity, b: DlpSeverity): number {\n  return SEVERITY_ORDER[a] - SEVERITY_ORDER[b];\n}\n","import { createHash } from 'node:crypto';\nimport type { DlpMatch } from './scanner.js';\n\nexport interface MaskingConfig {\n  strategy: 'partial' | 'full' | 'hash';\n  show_chars: number;\n  placeholder: string;\n}\n\nconst DEFAULT_CONFIG: MaskingConfig = {\n  strategy: 'partial',\n  show_chars: 4,\n  placeholder: '***',\n};\n\nexport class DlpMasker {\n  private config: MaskingConfig;\n\n  constructor(config?: Partial<MaskingConfig>) {\n    this.config = { ...DEFAULT_CONFIG, ...config };\n  }\n\n  maskValue(value: string): string {\n    switch (this.config.strategy) {\n      case 'full':\n        return this.config.placeholder;\n      case 'hash': {\n        const hash = createHash('sha256').update(value).digest('hex').slice(0, 8);\n        return `[REDACTED:${hash}]`;\n      }\n      case 'partial':\n      default: {\n        if (value.length <= this.config.show_chars) {\n          return this.config.placeholder;\n        }\n        return this.config.placeholder + value.slice(-this.config.show_chars);\n      }\n    }\n  }\n\n  maskText(text: string, matches: DlpMatch[]): string {\n    if (matches.length === 0) return text;\n\n    // Sort by position descending to avoid index shifting\n    const sorted = [...matches].sort((a, b) => b.start - a.start);\n\n    let result = text;\n    for (const match of sorted) {\n      const masked = this.maskValue(match.matched);\n      result = result.slice(0, match.start) + masked + result.slice(match.end);\n    }\n    return result;\n  }\n}\n","/**\n * Extracts package names from shell install commands.\n *\n * Supports npm, yarn, pnpm, pip, and cargo.\n */\n\nexport type Ecosystem = 'npm' | 'pypi' | 'crates.io';\n\nexport type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'pip' | 'cargo';\n\nexport interface ParsedPackage {\n  name: string;\n  version?: string;\n  ecosystem: Ecosystem;\n}\n\nexport interface ParsedInstall {\n  manager: PackageManager;\n  packages: ParsedPackage[];\n  flags: string[];\n  raw: string;\n  isLockfileInstall: boolean;\n  usesCustomRegistry: boolean;\n}\n\n/** Flags that take a value argument (the next token should be skipped). */\nconst FLAGS_WITH_VALUE = new Set([\n  // npm/yarn/pnpm\n  '--registry',\n  '--save-prefix',\n  '--tag',\n  '--cache',\n  '--prefix',\n  // pip\n  '-r',\n  '--requirement',\n  '-c',\n  '--constraint',\n  '-e',\n  '--editable',\n  '-t',\n  '--target',\n  '--index-url',\n  '-i',\n  '--extra-index-url',\n  '--find-links',\n  '-f',\n  '--root',\n  '--prefix',\n  // cargo\n  '--git',\n  '--branch',\n  '--rev',\n  '--path',\n  '--version',\n]);\n\nconst CUSTOM_REGISTRY_FLAGS = new Set(['--registry', '--index-url', '-i', '--extra-index-url']);\n\n/** Patterns that indicate lockfile-only installs. */\nconst LOCKFILE_PATTERNS: RegExp[] = [\n  /\\bnpm\\s+ci\\b/,\n  /\\bpnpm\\s+install\\s+--frozen-lockfile\\b/,\n  /\\byarn\\s+install\\s+--frozen-lockfile\\b/,\n  /\\bpip\\s+install\\b.*--require-hashes\\b/,\n];\n\ninterface ManagerMatch {\n  manager: PackageManager;\n  ecosystem: Ecosystem;\n  subcommandPattern: RegExp;\n}\n\nconst MANAGER_MATCHERS: ManagerMatch[] = [\n  { manager: 'npm', ecosystem: 'npm', subcommandPattern: /\\bnpm\\s+(install|i|add)\\s/ },\n  { manager: 'yarn', ecosystem: 'npm', subcommandPattern: /\\byarn\\s+(add|install)\\s/ },\n  { manager: 'pnpm', ecosystem: 'npm', subcommandPattern: /\\bpnpm\\s+(add|install|i)\\s/ },\n  { manager: 'pip', ecosystem: 'pypi', subcommandPattern: /\\bpip\\s+install\\s/ },\n  { manager: 'cargo', ecosystem: 'crates.io', subcommandPattern: /\\bcargo\\s+(add|install)\\s/ },\n];\n\nfunction splitVersionFromName(\n  raw: string,\n  ecosystem: Ecosystem,\n): { name: string; version?: string } {\n  if (ecosystem === 'npm') {\n    // @scope/pkg@version or pkg@version\n    const atIdx = raw.lastIndexOf('@');\n    if (atIdx > 0) {\n      return { name: raw.slice(0, atIdx), version: raw.slice(atIdx + 1) };\n    }\n    return { name: raw };\n  }\n  if (ecosystem === 'pypi') {\n    // pkg==version, pkg>=version, pkg~=version, pkg!=version\n    const match = raw.match(/^([a-zA-Z0-9_.-]+)([=<>!~]+.+)?$/);\n    if (match) {\n      return { name: match[1]!, version: match[2] };\n    }\n    return { name: raw };\n  }\n  if (ecosystem === 'crates.io') {\n    // pkg@version\n    const atIdx = raw.indexOf('@');\n    if (atIdx > 0) {\n      return { name: raw.slice(0, atIdx), version: raw.slice(atIdx + 1) };\n    }\n    return { name: raw };\n  }\n  return { name: raw };\n}\n\n/**\n * Attempt to parse an install command and extract package names.\n * Returns undefined if the command is not a recognized install command.\n */\nexport function parseInstallCommand(command: string): ParsedInstall | undefined {\n  const trimmed = command.trim();\n\n  // Check lockfile patterns first\n  const isLockfileInstall = LOCKFILE_PATTERNS.some((p) => p.test(trimmed));\n\n  // npm ci is a lockfile install with no packages to parse\n  if (/\\bnpm\\s+ci\\b/.test(trimmed)) {\n    return {\n      manager: 'npm',\n      packages: [],\n      flags: [],\n      raw: trimmed,\n      isLockfileInstall: true,\n      usesCustomRegistry: false,\n    };\n  }\n\n  for (const matcher of MANAGER_MATCHERS) {\n    if (!matcher.subcommandPattern.test(trimmed)) continue;\n\n    // Extract everything after the subcommand\n    const subMatch = trimmed.match(matcher.subcommandPattern);\n    if (!subMatch) continue;\n\n    const afterSubcommand = trimmed.slice(subMatch.index! + subMatch[0].length);\n    const tokens = tokenize(afterSubcommand);\n\n    const packages: ParsedPackage[] = [];\n    const flags: string[] = [];\n    let usesCustomRegistry = false;\n\n    for (let i = 0; i < tokens.length; i++) {\n      const token = tokens[i]!;\n\n      if (token.startsWith('-')) {\n        flags.push(token);\n        // Extract flag name (before '=' if present)\n        const flagName = token.includes('=') ? token.slice(0, token.indexOf('=')) : token;\n        if (CUSTOM_REGISTRY_FLAGS.has(flagName)) {\n          usesCustomRegistry = true;\n        }\n        // If this flag takes a value, skip the next token\n        if (FLAGS_WITH_VALUE.has(flagName) || token.includes('=')) {\n          if (!token.includes('=')) i++;\n        }\n        continue;\n      }\n\n      // pip: skip file-based args\n      if (matcher.manager === 'pip' && (token.endsWith('.txt') || token.endsWith('.cfg'))) {\n        continue;\n      }\n\n      // pip: skip paths and URLs\n      if (\n        matcher.manager === 'pip' &&\n        (token.startsWith('/') ||\n          token.startsWith('./') ||\n          token.startsWith('http://') ||\n          token.startsWith('https://') ||\n          token.startsWith('git+'))\n      ) {\n        continue;\n      }\n\n      const { name, version } = splitVersionFromName(token, matcher.ecosystem);\n      if (name) {\n        packages.push({ name, version, ecosystem: matcher.ecosystem });\n      }\n    }\n\n    return {\n      manager: matcher.manager,\n      packages,\n      flags,\n      raw: trimmed,\n      isLockfileInstall,\n      usesCustomRegistry,\n    };\n  }\n\n  return undefined;\n}\n\n/** Simple tokenizer that respects quotes. */\nfunction tokenize(input: string): string[] {\n  const tokens: string[] = [];\n  let current = '';\n  let inSingleQuote = false;\n  let inDoubleQuote = false;\n\n  for (let i = 0; i < input.length; i++) {\n    const ch = input[i]!;\n\n    if (ch === \"'\" && !inDoubleQuote) {\n      inSingleQuote = !inSingleQuote;\n      continue;\n    }\n    if (ch === '\"' && !inSingleQuote) {\n      inDoubleQuote = !inDoubleQuote;\n      continue;\n    }\n\n    if (ch === ' ' && !inSingleQuote && !inDoubleQuote) {\n      if (current) tokens.push(current);\n      current = '';\n    } else {\n      current += ch;\n    }\n  }\n  if (current) tokens.push(current);\n  return tokens;\n}\n","/**\n * Registry clients for npm and PyPI.\n *\n * Uses built-in fetch() (Node 22+). Zero dependencies.\n * All endpoints are free and require no authentication.\n */\n\nimport type { Ecosystem } from './parser.js';\n\nexport interface RegistryMetadata {\n  name: string;\n  ecosystem: Ecosystem;\n  exists: boolean;\n  createdAt?: Date;\n  modifiedAt?: Date;\n  latestVersion?: string;\n  weeklyDownloads?: number;\n  maintainerCount?: number;\n  hasRepository: boolean;\n  hasReadme: boolean;\n  hasInstallScripts: boolean;\n  description?: string;\n  license?: string;\n}\n\nconst REQUEST_TIMEOUT_MS = 5_000;\n\nfunction withTimeout(ms: number): AbortSignal {\n  return AbortSignal.timeout(ms);\n}\n\n// --- npm ---\n\ninterface NpmPackument {\n  name: string;\n  description?: string;\n  'dist-tags'?: Record<string, string>;\n  time?: Record<string, string>;\n  maintainers?: Array<{ name: string; email?: string }>;\n  readme?: string;\n  license?: string;\n  repository?: unknown;\n  versions?: Record<string, NpmVersion>;\n}\n\ninterface NpmVersion {\n  scripts?: Record<string, string>;\n}\n\ninterface NpmDownloadResponse {\n  downloads: number;\n}\n\nasync function fetchNpmMetadata(name: string): Promise<RegistryMetadata> {\n  const encodedName = name.startsWith('@')\n    ? `@${encodeURIComponent(name.slice(1))}`\n    : encodeURIComponent(name);\n  const url = `https://registry.npmjs.org/${encodedName}`;\n\n  let res: Response;\n  try {\n    res = await fetch(url, { signal: withTimeout(REQUEST_TIMEOUT_MS) });\n  } catch {\n    return notFound(name, 'npm');\n  }\n\n  if (!res.ok) return notFound(name, 'npm');\n\n  const data = (await res.json()) as NpmPackument;\n  const latest = data['dist-tags']?.['latest'];\n  const latestVersion = latest ? data.versions?.[latest] : undefined;\n  const scripts = latestVersion?.scripts ?? {};\n  const hasInstallScripts = !!(\n    scripts['preinstall'] ||\n    scripts['install'] ||\n    scripts['postinstall']\n  );\n\n  // Downloads — separate request\n  let weeklyDownloads: number | undefined;\n  try {\n    const dlUrl = `https://api.npmjs.org/downloads/point/last-week/${encodedName}`;\n    const dlRes = await fetch(dlUrl, { signal: withTimeout(REQUEST_TIMEOUT_MS) });\n    if (dlRes.ok) {\n      const dlData = (await dlRes.json()) as NpmDownloadResponse;\n      weeklyDownloads = dlData.downloads;\n    }\n  } catch {\n    // Non-critical — leave undefined\n  }\n\n  return {\n    name,\n    ecosystem: 'npm',\n    exists: true,\n    createdAt: data.time?.['created'] ? new Date(data.time['created']) : undefined,\n    modifiedAt: data.time?.['modified'] ? new Date(data.time['modified']) : undefined,\n    latestVersion: latest,\n    weeklyDownloads,\n    maintainerCount: data.maintainers?.length,\n    hasRepository: !!data.repository,\n    hasReadme: !!(data.readme && data.readme.length > 10),\n    hasInstallScripts,\n    description: data.description,\n    license: data.license,\n  };\n}\n\n// --- PyPI ---\n\ninterface PyPIResponse {\n  info: {\n    name: string;\n    version: string;\n    summary?: string;\n    license?: string;\n    home_page?: string;\n    project_urls?: Record<string, string>;\n    author?: string;\n    maintainer?: string;\n    description?: string;\n  };\n  releases: Record<string, Array<{ upload_time: string }>>;\n  urls: Array<{ upload_time: string }>;\n}\n\ninterface PyPIStatsResponse {\n  data: {\n    last_week: number;\n  };\n}\n\nasync function fetchPyPIMetadata(name: string): Promise<RegistryMetadata> {\n  const url = `https://pypi.org/pypi/${encodeURIComponent(name)}/json`;\n\n  let res: Response;\n  try {\n    res = await fetch(url, { signal: withTimeout(REQUEST_TIMEOUT_MS) });\n  } catch {\n    return notFound(name, 'pypi');\n  }\n\n  if (!res.ok) return notFound(name, 'pypi');\n\n  const data = (await res.json()) as PyPIResponse;\n\n  // Find the earliest upload time across all releases\n  let earliest: Date | undefined;\n  for (const files of Object.values(data.releases)) {\n    for (const file of files) {\n      const d = new Date(file.upload_time);\n      if (!earliest || d < earliest) earliest = d;\n    }\n  }\n\n  // Determine if there's a project URL / repository\n  const projectUrls = data.info.project_urls ?? {};\n  const hasRepo = !!(\n    data.info.home_page ||\n    projectUrls['Source'] ||\n    projectUrls['Repository'] ||\n    projectUrls['GitHub'] ||\n    projectUrls['Homepage']\n  );\n\n  // Maintainer count — PyPI doesn't expose this directly, so we approximate\n  const hasMaintainer = !!(data.info.maintainer || data.info.author);\n\n  // Downloads — pypistats.org\n  let weeklyDownloads: number | undefined;\n  try {\n    const statsUrl = `https://pypistats.org/api/packages/${encodeURIComponent(name)}/recent`;\n    const statsRes = await fetch(statsUrl, {\n      signal: withTimeout(REQUEST_TIMEOUT_MS),\n      headers: { Accept: 'application/json' },\n    });\n    if (statsRes.ok) {\n      const statsData = (await statsRes.json()) as PyPIStatsResponse;\n      weeklyDownloads = statsData.data?.last_week;\n    }\n  } catch {\n    // Non-critical\n  }\n\n  return {\n    name,\n    ecosystem: 'pypi',\n    exists: true,\n    createdAt: earliest,\n    modifiedAt:\n      data.urls.length > 0 ? new Date(data.urls[data.urls.length - 1]!.upload_time) : undefined,\n    latestVersion: data.info.version,\n    weeklyDownloads,\n    maintainerCount: hasMaintainer ? 1 : 0,\n    hasRepository: hasRepo,\n    hasReadme: !!(data.info.description && data.info.description.length > 10),\n    hasInstallScripts: false, // PyPI doesn't have post-install scripts in the same way\n    description: data.info.summary,\n    license: data.info.license,\n  };\n}\n\n// --- Helpers ---\n\nfunction notFound(name: string, ecosystem: Ecosystem): RegistryMetadata {\n  return {\n    name,\n    ecosystem,\n    exists: false,\n    hasRepository: false,\n    hasReadme: false,\n    hasInstallScripts: false,\n  };\n}\n\n// --- Cache ---\n\nconst cache = new Map<string, RegistryMetadata>();\nconst MAX_CACHE_SIZE = 200;\n\nfunction cacheKey(name: string, ecosystem: Ecosystem): string {\n  return `${ecosystem}:${name}`;\n}\n\n// --- Public API ---\n\nexport async function fetchRegistryMetadata(\n  name: string,\n  ecosystem: Ecosystem,\n): Promise<RegistryMetadata> {\n  const key = cacheKey(name, ecosystem);\n  const cached = cache.get(key);\n  if (cached) return cached;\n\n  let result: RegistryMetadata;\n  switch (ecosystem) {\n    case 'npm':\n      result = await fetchNpmMetadata(name);\n      break;\n    case 'pypi':\n      result = await fetchPyPIMetadata(name);\n      break;\n    default:\n      result = notFound(name, ecosystem);\n  }\n\n  // LRU eviction\n  if (cache.size >= MAX_CACHE_SIZE) {\n    const firstKey = cache.keys().next().value;\n    if (firstKey !== undefined) cache.delete(firstKey);\n  }\n  cache.set(key, result);\n\n  return result;\n}\n\n/** Clear the cache (useful for testing). */\nexport function clearRegistryCache(): void {\n  cache.clear();\n}\n","/**\n * OSV.dev vulnerability database integration.\n *\n * Free, no auth, supports all major ecosystems.\n * https://osv.dev\n */\n\nimport type { Ecosystem } from './parser.js';\n\nexport interface VulnEntry {\n  id: string;\n  summary: string;\n  severity: 'low' | 'medium' | 'high' | 'critical';\n  fixedIn?: string;\n  aliases: string[];\n}\n\nexport interface VulnerabilityResult {\n  package: string;\n  ecosystem: Ecosystem;\n  vulnerabilities: VulnEntry[];\n  error?: string;\n}\n\nconst REQUEST_TIMEOUT_MS = 5_000;\n\n// Map ecosystem to OSV ecosystem identifier\nfunction osvEcosystem(ecosystem: Ecosystem): string {\n  switch (ecosystem) {\n    case 'npm':\n      return 'npm';\n    case 'pypi':\n      return 'PyPI';\n    case 'crates.io':\n      return 'crates.io';\n    default:\n      return ecosystem;\n  }\n}\n\ninterface OsvQueryRequest {\n  package: { name: string; ecosystem: string };\n  version?: string;\n}\n\ninterface OsvVuln {\n  id: string;\n  summary?: string;\n  details?: string;\n  aliases?: string[];\n  severity?: Array<{ type: string; score: string }>;\n  affected?: Array<{\n    ranges?: Array<{\n      events?: Array<{ fixed?: string }>;\n    }>;\n  }>;\n}\n\ninterface OsvQueryResponse {\n  vulns?: OsvVuln[];\n}\n\ninterface OsvBatchResponse {\n  results: Array<{ vulns?: OsvVuln[] }>;\n}\n\nfunction parseSeverity(vuln: OsvVuln): 'low' | 'medium' | 'high' | 'critical' {\n  const sevEntry = vuln.severity?.find((s) => s.type === 'CVSS_V3');\n  if (!sevEntry) return 'medium'; // default if no CVSS\n\n  // Parse CVSS v3 score from vector string: CVSS:3.1/AV:N/AC:L/...\n  // or it could be a numeric score\n  const scoreStr = sevEntry.score;\n  const numericMatch = scoreStr.match(/(\\d+\\.\\d+)/);\n  if (numericMatch) {\n    const score = parseFloat(numericMatch[1]!);\n    if (score >= 9.0) return 'critical';\n    if (score >= 7.0) return 'high';\n    if (score >= 4.0) return 'medium';\n    return 'low';\n  }\n\n  return 'medium';\n}\n\nfunction extractFixedVersion(vuln: OsvVuln): string | undefined {\n  for (const affected of vuln.affected ?? []) {\n    for (const range of affected.ranges ?? []) {\n      for (const event of range.events ?? []) {\n        if (event.fixed) return event.fixed;\n      }\n    }\n  }\n  return undefined;\n}\n\nfunction mapVuln(vuln: OsvVuln): VulnEntry {\n  return {\n    id: vuln.id,\n    summary: vuln.summary ?? vuln.details?.slice(0, 200) ?? 'No description',\n    severity: parseSeverity(vuln),\n    fixedIn: extractFixedVersion(vuln),\n    aliases: vuln.aliases ?? [],\n  };\n}\n\n/**\n * Query OSV.dev for vulnerabilities affecting a single package.\n */\nexport async function queryVulnerabilities(\n  name: string,\n  ecosystem: Ecosystem,\n  version?: string,\n): Promise<VulnerabilityResult> {\n  const body: OsvQueryRequest = {\n    package: { name, ecosystem: osvEcosystem(ecosystem) },\n  };\n  if (version) body.version = version;\n\n  try {\n    const res = await fetch('https://api.osv.dev/v1/query', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify(body),\n      signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n    });\n\n    if (!res.ok) {\n      return { package: name, ecosystem, vulnerabilities: [], error: `OSV HTTP ${res.status}` };\n    }\n\n    const data = (await res.json()) as OsvQueryResponse;\n    return {\n      package: name,\n      ecosystem,\n      vulnerabilities: (data.vulns ?? []).map(mapVuln),\n    };\n  } catch (err) {\n    return {\n      package: name,\n      ecosystem,\n      vulnerabilities: [],\n      error: err instanceof Error ? err.message : 'Unknown error',\n    };\n  }\n}\n\n/**\n * Batch query OSV.dev for multiple packages at once.\n */\nexport async function queryVulnerabilitiesBatch(\n  packages: Array<{ name: string; ecosystem: Ecosystem; version?: string }>,\n): Promise<VulnerabilityResult[]> {\n  if (packages.length === 0) return [];\n\n  // Single package — use the simpler endpoint\n  if (packages.length === 1) {\n    const pkg = packages[0]!;\n    return [await queryVulnerabilities(pkg.name, pkg.ecosystem, pkg.version)];\n  }\n\n  const queries = packages.map((pkg) => {\n    const q: OsvQueryRequest = {\n      package: { name: pkg.name, ecosystem: osvEcosystem(pkg.ecosystem) },\n    };\n    if (pkg.version) q.version = pkg.version;\n    return q;\n  });\n\n  try {\n    const res = await fetch('https://api.osv.dev/v1/querybatch', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ queries }),\n      signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n    });\n\n    if (!res.ok) {\n      return packages.map((pkg) => ({\n        package: pkg.name,\n        ecosystem: pkg.ecosystem,\n        vulnerabilities: [],\n        error: `OSV HTTP ${res.status}`,\n      }));\n    }\n\n    const data = (await res.json()) as OsvBatchResponse;\n    return data.results.map((result, i) => ({\n      package: packages[i]!.name,\n      ecosystem: packages[i]!.ecosystem,\n      vulnerabilities: (result.vulns ?? []).map(mapVuln),\n    }));\n  } catch (err) {\n    const errMsg = err instanceof Error ? err.message : 'Unknown error';\n    return packages.map((pkg) => ({\n      package: pkg.name,\n      ecosystem: pkg.ecosystem,\n      vulnerabilities: [],\n      error: errMsg,\n    }));\n  }\n}\n","/**\n * Levenshtein distance and typosquat detection.\n *\n * Single-row Wagner-Fischer: O(n*m) time, O(min(n,m)) space.\n * Zero dependencies.\n */\n\nexport function levenshteinDistance(a: string, b: string): number {\n  if (a === b) return 0;\n  if (a.length === 0) return b.length;\n  if (b.length === 0) return a.length;\n\n  // Ensure a is the shorter string for space efficiency\n  if (a.length > b.length) [a, b] = [b, a];\n\n  const m = a.length;\n  const n = b.length;\n  const row = new Array<number>(m + 1);\n  for (let j = 0; j <= m; j++) row[j] = j;\n\n  for (let i = 1; i <= n; i++) {\n    let corner = row[0]!;\n    row[0] = i;\n    for (let j = 1; j <= m; j++) {\n      const temp = row[j]!;\n      if (b[i - 1] === a[j - 1]) {\n        row[j] = corner;\n      } else {\n        row[j] = 1 + Math.min(corner, temp, row[j - 1]!);\n      }\n      corner = temp;\n    }\n  }\n  return row[m]!;\n}\n\nexport function normalizedSimilarity(a: string, b: string): number {\n  const maxLen = Math.max(a.length, b.length);\n  if (maxLen === 0) return 1.0;\n  return 1 - levenshteinDistance(a, b) / maxLen;\n}\n\n/**\n * Normalize a package name for comparison:\n * - Strip npm scope prefix (@scope/)\n * - Remove hyphens, underscores, dots\n * - Lowercase\n */\nexport function normalizeName(name: string): string {\n  // Strip scope\n  const stripped = name.replace(/^@[^/]+\\//, '');\n  // Remove separators and lowercase\n  return stripped.replace(/[-_.]/g, '').toLowerCase();\n}\n\nexport interface TyposquatMatch {\n  target: string;\n  distance: number;\n  similarity: number;\n}\n\n/**\n * Check a package name against a corpus of known-good names.\n * Returns the closest match if it looks like a typosquat.\n */\nexport function detectTyposquat(name: string, corpus: string[]): TyposquatMatch | undefined {\n  const normalized = normalizeName(name);\n\n  let bestMatch: TyposquatMatch | undefined;\n  let bestDistance = Infinity;\n\n  for (const target of corpus) {\n    const normalizedTarget = normalizeName(target);\n\n    // Skip exact matches (the package is the popular package itself)\n    if (normalizedTarget === normalized) return undefined;\n\n    const distance = levenshteinDistance(normalized, normalizedTarget);\n    const similarity = normalizedSimilarity(normalized, normalizedTarget);\n\n    // Flag thresholds:\n    // - edit distance 1: always flag\n    // - edit distance 2 + name length >= 5: flag\n    // - normalized similarity >= 0.85: flag\n    const shouldFlag =\n      distance === 1 || (distance === 2 && normalized.length >= 5) || similarity >= 0.85;\n\n    if (shouldFlag && distance < bestDistance) {\n      bestDistance = distance;\n      bestMatch = { target, distance, similarity };\n    }\n  }\n\n  return bestMatch;\n}\n","/**\n * Default allowlists and blocklists for dependency validation.\n *\n * The allowlist doubles as the \"popular packages\" corpus for typosquat detection.\n * Users extend these via config; user entries take precedence.\n */\n\nexport const DEFAULT_NPM_ALLOWLIST: string[] = [\n  // Frameworks\n  'express',\n  'react',\n  'react-dom',\n  'next',\n  'vue',\n  'angular',\n  'svelte',\n  'fastify',\n  'koa',\n  'hapi',\n  'nest',\n  'nuxt',\n  // Build tools\n  'typescript',\n  'webpack',\n  'vite',\n  'esbuild',\n  'tsup',\n  'rollup',\n  'parcel',\n  'babel',\n  'swc',\n  // Quality tools\n  'prettier',\n  'eslint',\n  'vitest',\n  'jest',\n  'mocha',\n  'chai',\n  'sinon',\n  'husky',\n  'lint-staged',\n  // Utilities\n  'lodash',\n  'axios',\n  'chalk',\n  'commander',\n  'debug',\n  'async',\n  'uuid',\n  'semver',\n  'glob',\n  'fs-extra',\n  'mkdirp',\n  'rimraf',\n  'minimist',\n  'yargs',\n  'dotenv',\n  'nanoid',\n  'date-fns',\n  'dayjs',\n  'moment',\n  'rxjs',\n  'immer',\n  // Validation\n  'zod',\n  'joi',\n  'ajv',\n  'yup',\n  // HTTP / API\n  'cors',\n  'body-parser',\n  'cookie-parser',\n  'morgan',\n  'helmet',\n  'jsonwebtoken',\n  'bcrypt',\n  'passport',\n  // Database\n  'mongoose',\n  'sequelize',\n  'prisma',\n  'typeorm',\n  'knex',\n  'pg',\n  'mysql2',\n  'redis',\n  'ioredis',\n  'better-sqlite3',\n  // Realtime\n  'socket.io',\n  'ws',\n  // State management\n  'zustand',\n  'redux',\n  'mobx',\n  // CSS\n  'tailwindcss',\n  'postcss',\n  'autoprefixer',\n  'sass',\n  'styled-components',\n  'clsx',\n  'classnames',\n  // Media\n  'sharp',\n  'puppeteer',\n  'cheerio',\n  'marked',\n  'highlight.js',\n  // Types\n  'tslib',\n];\n\nexport const DEFAULT_PYPI_ALLOWLIST: string[] = [\n  // Web\n  'requests',\n  'flask',\n  'django',\n  'fastapi',\n  'aiohttp',\n  'httpx',\n  'uvicorn',\n  'gunicorn',\n  'starlette',\n  // Data\n  'numpy',\n  'pandas',\n  'scipy',\n  'matplotlib',\n  'scikit-learn',\n  'pillow',\n  // Infrastructure\n  'boto3',\n  'botocore',\n  'urllib3',\n  'certifi',\n  'charset-normalizer',\n  'idna',\n  // Core\n  'setuptools',\n  'pip',\n  'wheel',\n  'packaging',\n  'typing-extensions',\n  'six',\n  'python-dateutil',\n  'pyyaml',\n  'tomli',\n  'filelock',\n  'attrs',\n  'click',\n  'importlib-metadata',\n  'zipp',\n  'platformdirs',\n  // Crypto\n  'cryptography',\n  'cffi',\n  'pycparser',\n  'jmespath',\n  'pyasn1',\n  // DB\n  'sqlalchemy',\n  'psycopg2',\n  'redis',\n  'celery',\n  // Template / Markup\n  'jinja2',\n  'markupsafe',\n  'beautifulsoup4',\n  'lxml',\n  'scrapy',\n  // Validation\n  'pydantic',\n  // Testing\n  'pytest',\n  'tox',\n  'coverage',\n  'mock',\n];\n\nexport const DEFAULT_BLOCKLIST_EXACT: string[] = [\n  // npm typosquats (historically malicious)\n  'crossenv',\n  'cross-env.js',\n  'd3.js',\n  'fabric-js',\n  'ffmpegs',\n  'gruntcli',\n  'http-proxy.js',\n  'jquery.js',\n  'mongose',\n  'mssql-node',\n  'nodecaffe',\n  'nodefabric',\n  'nodemailer-js',\n  'noderequest',\n  'nodesass',\n  'opencv.js',\n  'openssl.js',\n  'shadowsock',\n  'sqliter',\n  'sqlserver',\n  // npm compromised\n  'flatmap-stream',\n  // PyPI typosquats\n  'colourama',\n  'python3-dateutil',\n  'requesocks',\n  'requesst',\n  'beautifulsup',\n  'numppy',\n  'numpys',\n  'djanga',\n  'urlib3',\n];\n\nexport const DEFAULT_BLOCKLIST_PATTERNS: RegExp[] = [\n  /-free-download$/,\n  /-crack$/,\n  /-keygen$/,\n  /-license-key$/,\n  /-hack$/,\n  /-serial$/,\n  /-activation$/,\n  /-premium-free$/,\n  /-generator-free$/,\n];\n\nexport interface AllowBlockConfig {\n  allowlist: string[];\n  blocklist: string[];\n  blocklistPatterns: RegExp[];\n}\n\n/**\n * Build merged allow/block lists from defaults + user config.\n */\nexport function buildAllowBlockLists(\n  ecosystem: 'npm' | 'pypi' | 'crates.io',\n  userAllowlist: string[],\n  userBlocklist: string[],\n  userBlocklistPatterns: string[],\n): AllowBlockConfig {\n  const base =\n    ecosystem === 'npm'\n      ? DEFAULT_NPM_ALLOWLIST\n      : ecosystem === 'pypi'\n        ? DEFAULT_PYPI_ALLOWLIST\n        : [];\n\n  return {\n    allowlist: [...base, ...userAllowlist],\n    blocklist: [...DEFAULT_BLOCKLIST_EXACT, ...userBlocklist],\n    blocklistPatterns: [\n      ...DEFAULT_BLOCKLIST_PATTERNS,\n      ...userBlocklistPatterns.map((p) => new RegExp(p)),\n    ],\n  };\n}\n\n/**\n * Check if a package is on the allowlist.\n */\nexport function isAllowlisted(name: string, allowlist: string[]): boolean {\n  return allowlist.includes(name);\n}\n\n/**\n * Check if a package is on the blocklist (exact match or pattern).\n */\nexport function isBlocklisted(\n  name: string,\n  blocklist: string[],\n  blocklistPatterns: RegExp[],\n): boolean {\n  if (blocklist.includes(name)) return true;\n  return blocklistPatterns.some((p) => p.test(name));\n}\n","/**\n * Risk scoring engine for dependency validation.\n *\n * Computes a risk report for a single package based on registry metadata,\n * vulnerability data, and typosquat analysis.\n */\n\nimport type { RegistryMetadata } from './registry.js';\nimport type { VulnEntry } from './vulnerabilities.js';\nimport type { TyposquatMatch } from './levenshtein.js';\n\nexport type RiskSeverity = 'info' | 'low' | 'medium' | 'high' | 'critical';\nexport type RiskRecommendation = 'allow' | 'escalate' | 'block';\n\nexport interface RiskSignal {\n  name: string;\n  severity: RiskSeverity;\n  detail: string;\n}\n\nexport interface RiskReport {\n  package: string;\n  ecosystem: string;\n  overallRisk: RiskSeverity;\n  signals: RiskSignal[];\n  vulnerabilities: VulnEntry[];\n  recommendation: RiskRecommendation;\n  metadata: RegistryMetadata;\n}\n\nexport interface RiskThresholds {\n  minAgeDays: number;\n  minWeeklyDownloads: number;\n}\n\nconst DEFAULT_THRESHOLDS: RiskThresholds = {\n  minAgeDays: 30,\n  minWeeklyDownloads: 100,\n};\n\nconst SEVERITY_ORDER: Record<RiskSeverity, number> = {\n  info: 0,\n  low: 1,\n  medium: 2,\n  high: 3,\n  critical: 4,\n};\n\nfunction maxSeverity(a: RiskSeverity, b: RiskSeverity): RiskSeverity {\n  return SEVERITY_ORDER[a] >= SEVERITY_ORDER[b] ? a : b;\n}\n\nexport function computeRiskReport(\n  metadata: RegistryMetadata,\n  vulns: VulnEntry[],\n  typosquatMatch: TyposquatMatch | undefined,\n  isBlocklisted: boolean,\n  isAllowlisted: boolean,\n  thresholds: RiskThresholds = DEFAULT_THRESHOLDS,\n): RiskReport {\n  const signals: RiskSignal[] = [];\n  let overallRisk: RiskSeverity = 'info';\n\n  // --- Critical signals ---\n\n  if (!metadata.exists) {\n    signals.push({\n      name: 'package_not_found',\n      severity: 'critical',\n      detail: `Package \"${metadata.name}\" does not exist on ${metadata.ecosystem}`,\n    });\n    overallRisk = 'critical';\n  }\n\n  if (isBlocklisted) {\n    signals.push({\n      name: 'on_blocklist',\n      severity: 'critical',\n      detail: `Package \"${metadata.name}\" is on the blocklist`,\n    });\n    overallRisk = 'critical';\n  }\n\n  // Vulnerabilities\n  for (const vuln of vulns) {\n    signals.push({\n      name: 'known_vulnerability',\n      severity: vuln.severity,\n      detail: `${vuln.id}: ${vuln.summary}${vuln.fixedIn ? ` (fixed in ${vuln.fixedIn})` : ''}`,\n    });\n    overallRisk = maxSeverity(overallRisk, vuln.severity);\n  }\n\n  // If allowlisted, skip reputation checks but still report vulns/blocklist\n  if (isAllowlisted && signals.length === 0) {\n    return {\n      package: metadata.name,\n      ecosystem: metadata.ecosystem,\n      overallRisk: 'info',\n      signals: [],\n      vulnerabilities: vulns,\n      recommendation: 'allow',\n      metadata,\n    };\n  }\n\n  // --- Reputation signals (skipped for allowlisted packages) ---\n  if (!isAllowlisted && metadata.exists) {\n    // Package age\n    if (metadata.createdAt) {\n      const ageDays = (Date.now() - metadata.createdAt.getTime()) / (1000 * 60 * 60 * 24);\n      if (ageDays < 7) {\n        signals.push({\n          name: 'very_new_package',\n          severity: 'high',\n          detail: `Created ${Math.floor(ageDays)} days ago`,\n        });\n        overallRisk = maxSeverity(overallRisk, 'high');\n      } else if (ageDays < thresholds.minAgeDays) {\n        signals.push({\n          name: 'new_package',\n          severity: 'medium',\n          detail: `Created ${Math.floor(ageDays)} days ago (threshold: ${thresholds.minAgeDays})`,\n        });\n        overallRisk = maxSeverity(overallRisk, 'medium');\n      }\n    }\n\n    // Download count\n    if (metadata.weeklyDownloads !== undefined) {\n      if (metadata.weeklyDownloads < thresholds.minWeeklyDownloads) {\n        const sev = metadata.weeklyDownloads < 10 ? 'high' : 'medium';\n        signals.push({\n          name: 'low_downloads',\n          severity: sev,\n          detail: `${metadata.weeklyDownloads} weekly downloads (threshold: ${thresholds.minWeeklyDownloads})`,\n        });\n        overallRisk = maxSeverity(overallRisk, sev);\n      }\n    }\n\n    // Typosquatting\n    if (typosquatMatch) {\n      signals.push({\n        name: 'typosquat_suspect',\n        severity: 'high',\n        detail: `Similar to \"${typosquatMatch.target}\" (edit distance: ${typosquatMatch.distance})`,\n      });\n      overallRisk = maxSeverity(overallRisk, 'high');\n    }\n\n    // Install scripts\n    if (metadata.hasInstallScripts) {\n      signals.push({\n        name: 'has_install_scripts',\n        severity: 'medium',\n        detail: 'Package has preinstall/install/postinstall scripts',\n      });\n      overallRisk = maxSeverity(overallRisk, 'medium');\n    }\n\n    // No repository\n    if (!metadata.hasRepository) {\n      signals.push({\n        name: 'no_repository',\n        severity: 'low',\n        detail: 'No source repository URL in metadata',\n      });\n      overallRisk = maxSeverity(overallRisk, 'low');\n    }\n\n    // No README\n    if (!metadata.hasReadme) {\n      signals.push({\n        name: 'no_readme',\n        severity: 'low',\n        detail: 'No README content',\n      });\n      overallRisk = maxSeverity(overallRisk, 'low');\n    }\n\n    // No license\n    if (!metadata.license) {\n      signals.push({\n        name: 'no_license',\n        severity: 'low',\n        detail: 'No license declared',\n      });\n      overallRisk = maxSeverity(overallRisk, 'low');\n    }\n\n    // Single maintainer\n    if (metadata.maintainerCount !== undefined && metadata.maintainerCount <= 1) {\n      signals.push({\n        name: 'single_maintainer',\n        severity: 'info',\n        detail: `${metadata.maintainerCount} maintainer(s)`,\n      });\n    }\n  }\n\n  // --- Compute recommendation ---\n  let recommendation: RiskRecommendation;\n  if (SEVERITY_ORDER[overallRisk] >= SEVERITY_ORDER['critical']) {\n    recommendation = 'block';\n  } else if (SEVERITY_ORDER[overallRisk] >= SEVERITY_ORDER['medium']) {\n    recommendation = 'escalate';\n  } else {\n    recommendation = 'allow';\n  }\n\n  return {\n    package: metadata.name,\n    ecosystem: metadata.ecosystem,\n    overallRisk,\n    signals,\n    vulnerabilities: vulns,\n    recommendation,\n    metadata,\n  };\n}\n","/**\n * Dependency Guardian — orchestrator module.\n *\n * Parses install commands, runs all checks, and returns a risk report.\n */\n\nimport { parseInstallCommand } from './parser.js';\nimport { fetchRegistryMetadata } from './registry.js';\nimport { queryVulnerabilitiesBatch } from './vulnerabilities.js';\nimport { detectTyposquat } from './levenshtein.js';\nimport { buildAllowBlockLists, isAllowlisted, isBlocklisted } from './allowlist.js';\nimport { computeRiskReport, type RiskReport, type RiskRecommendation } from './risk.js';\n\nexport interface DependencyGuardianConfig {\n  enabled: boolean;\n  checks: {\n    existence: boolean;\n    reputation: boolean;\n    typosquatting: boolean;\n    install_scripts: boolean;\n    vulnerabilities: boolean;\n  };\n  risk_thresholds: {\n    min_age_days: number;\n    min_weekly_downloads: number;\n  };\n  on_risk: 'escalate' | 'block' | 'audit';\n  allowlist: string[];\n  blocklist: string[];\n  blocklist_patterns: string[];\n  custom_registry_bypass: boolean;\n}\n\nexport interface GuardianResult {\n  command: string;\n  packages: RiskReport[];\n  overallRecommendation: RiskRecommendation;\n  summary: string;\n  auditMetadata: Record<string, unknown>;\n  skipped: boolean;\n  skipReason?: string;\n}\n\nconst DEFAULT_CONFIG: DependencyGuardianConfig = {\n  enabled: true,\n  checks: {\n    existence: true,\n    reputation: true,\n    typosquatting: true,\n    install_scripts: true,\n    vulnerabilities: true,\n  },\n  risk_thresholds: {\n    min_age_days: 30,\n    min_weekly_downloads: 100,\n  },\n  on_risk: 'escalate',\n  allowlist: [],\n  blocklist: [],\n  blocklist_patterns: [],\n  custom_registry_bypass: true,\n};\n\n/**\n * Evaluate an install command and return a risk report for all packages.\n */\nexport async function evaluateInstall(\n  command: string,\n  config: DependencyGuardianConfig = DEFAULT_CONFIG,\n): Promise<GuardianResult> {\n  if (!config.enabled) {\n    return skippedResult(command, 'Dependency guardian is disabled');\n  }\n\n  const parsed = parseInstallCommand(command);\n  if (!parsed) {\n    return skippedResult(command, 'Not a recognized install command');\n  }\n\n  // Lock-file installs are low risk — skip\n  if (parsed.isLockfileInstall) {\n    return skippedResult(command, 'Lock-file install (pinned dependencies)');\n  }\n\n  // Custom registry bypass\n  if (config.custom_registry_bypass && parsed.usesCustomRegistry) {\n    return skippedResult(command, 'Custom registry detected (bypass enabled)');\n  }\n\n  // No packages extracted (e.g., `npm install` with no args reinstalls from package.json)\n  if (parsed.packages.length === 0) {\n    return skippedResult(command, 'No specific packages to validate');\n  }\n\n  // Build merged allow/block lists per ecosystem\n  const ecosystems = [...new Set(parsed.packages.map((p) => p.ecosystem))];\n  const listsPerEcosystem = new Map(\n    ecosystems.map((eco) => [\n      eco,\n      buildAllowBlockLists(eco, config.allowlist, config.blocklist, config.blocklist_patterns),\n    ]),\n  );\n\n  // Fetch registry metadata in parallel\n  const metadataPromises = parsed.packages.map(async (pkg) => {\n    if (!config.checks.existence && !config.checks.reputation && !config.checks.install_scripts) {\n      return undefined;\n    }\n    return fetchRegistryMetadata(pkg.name, pkg.ecosystem);\n  });\n\n  // Fetch vulnerabilities in batch\n  const vulnPromise = config.checks.vulnerabilities\n    ? queryVulnerabilitiesBatch(\n        parsed.packages.map((p) => ({\n          name: p.name,\n          ecosystem: p.ecosystem,\n          version: p.version,\n        })),\n      )\n    : Promise.resolve(\n        parsed.packages.map((p) => ({\n          package: p.name,\n          ecosystem: p.ecosystem,\n          vulnerabilities: [] as import('./vulnerabilities.js').VulnEntry[],\n        })),\n      );\n\n  const [metadataResults, vulnResults] = await Promise.all([\n    Promise.all(metadataPromises),\n    vulnPromise,\n  ]);\n\n  // Compute risk reports\n  const reports: RiskReport[] = [];\n  for (let i = 0; i < parsed.packages.length; i++) {\n    const pkg = parsed.packages[i]!;\n    const lists = listsPerEcosystem.get(pkg.ecosystem)!;\n    const allowed = isAllowlisted(pkg.name, lists.allowlist);\n    const blocked = isBlocklisted(pkg.name, lists.blocklist, lists.blocklistPatterns);\n\n    const metadata = metadataResults[i] ?? {\n      name: pkg.name,\n      ecosystem: pkg.ecosystem,\n      exists: true, // assume exists if we didn't check\n      hasRepository: true,\n      hasReadme: true,\n      hasInstallScripts: false,\n    };\n\n    const vulns = vulnResults[i]?.vulnerabilities ?? [];\n\n    const typosquatMatch =\n      config.checks.typosquatting && !allowed\n        ? detectTyposquat(pkg.name, lists.allowlist)\n        : undefined;\n\n    const report = computeRiskReport(metadata, vulns, typosquatMatch, blocked, allowed, {\n      minAgeDays: config.risk_thresholds.min_age_days,\n      minWeeklyDownloads: config.risk_thresholds.min_weekly_downloads,\n    });\n\n    reports.push(report);\n  }\n\n  // Compute overall recommendation (most restrictive)\n  let overallRecommendation: RiskRecommendation = 'allow';\n  for (const report of reports) {\n    if (report.recommendation === 'block') {\n      overallRecommendation = 'block';\n      break;\n    }\n    if (report.recommendation === 'escalate') {\n      overallRecommendation = 'escalate';\n    }\n  }\n\n  // If on_risk is 'audit', downgrade escalate→allow (still log)\n  if (config.on_risk === 'audit' && overallRecommendation === 'escalate') {\n    overallRecommendation = 'allow';\n  }\n  // If on_risk is 'block', upgrade escalate→block\n  if (config.on_risk === 'block' && overallRecommendation === 'escalate') {\n    overallRecommendation = 'block';\n  }\n\n  const summary = formatSummary(command, reports, overallRecommendation);\n\n  return {\n    command,\n    packages: reports,\n    overallRecommendation,\n    summary,\n    auditMetadata: {\n      command,\n      manager: parsed.manager,\n      packages: reports.map((r) => ({\n        name: r.package,\n        ecosystem: r.ecosystem,\n        risk: r.overallRisk,\n        signals: r.signals.map((s) => s.name),\n        vulnCount: r.vulnerabilities.length,\n      })),\n    },\n    skipped: false,\n  };\n}\n\nfunction skippedResult(command: string, reason: string): GuardianResult {\n  return {\n    command,\n    packages: [],\n    overallRecommendation: 'allow',\n    summary: reason,\n    auditMetadata: { command, skipped: true, reason },\n    skipped: true,\n    skipReason: reason,\n  };\n}\n\nfunction formatSummary(\n  command: string,\n  reports: RiskReport[],\n  recommendation: RiskRecommendation,\n): string {\n  const lines: string[] = [];\n  lines.push(`Command: ${command}`);\n  lines.push('');\n\n  for (const report of reports) {\n    if (report.signals.length === 0 && report.vulnerabilities.length === 0) continue;\n\n    lines.push(`Package: ${report.package} (${report.ecosystem})`);\n    lines.push(`Risk: ${report.overallRisk.toUpperCase()}`);\n\n    if (report.signals.length > 0) {\n      lines.push('Signals:');\n      for (const signal of report.signals) {\n        const icon =\n          signal.severity === 'critical' || signal.severity === 'high'\n            ? '!!'\n            : signal.severity === 'medium'\n              ? '! '\n              : '  ';\n        lines.push(`  ${icon} ${signal.name}: ${signal.detail}`);\n      }\n    }\n\n    lines.push('');\n  }\n\n  if (recommendation === 'block') {\n    lines.push('Recommendation: BLOCK');\n  } else if (recommendation === 'escalate') {\n    lines.push('Recommendation: Requires human approval');\n  }\n\n  return lines.join('\\n');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAEa;AAFb;AAAA;AAAA;AAEO,IAAM,WAA6B;AAAA,MACxC,MAAM;AAAA,QACJ,UAAU;AAAA,QACV,KAAK;AAAA,UACH,UAAU;AAAA,UACV,UAAU;AAAA,UACV,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA,QAAQ;AAAA,QACN,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,YAAY;AAAA,QACd;AAAA,MACF;AAAA,MACA,WAAW;AAAA,QACT,WAAW;AAAA,QACX,SAAS;AAAA,MACX;AAAA,MACA,MAAM;AAAA,QACJ,cAAc;AAAA,QACd,kBAAkB;AAAA,QAClB,iBAAiB;AAAA,MACnB;AAAA,MACA,OAAO;AAAA,QACL,OAAO,CAAC,EAAE,MAAM,SAAS,MAAM,0BAA0B,CAAC;AAAA,MAC5D;AAAA,MACA,KAAK;AAAA,QACH,SAAS;AAAA,QACT,MAAM;AAAA,QACN,UAAU;AAAA,QACV,WAAW;AAAA,QACX,SAAS;AAAA,UACP,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,aAAa;AAAA,QACf;AAAA,QACA,oBAAoB;AAAA,QACpB,UAAU;AAAA,UACR,SAAS;AAAA,UACT,KAAK;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC7CA,IAAa;AAAb;AAAA;AAAA;AAAO,IAAM,cAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","names":["resolve","import_node_fs","import_node_path","import_yaml","import_node_fs","import_node_path","parseYaml","import_fs","import_yaml","parseYaml","import_fs","import_yaml","parseYaml","import_yaml","import_value","parseYaml","import_node_crypto","REQUEST_TIMEOUT_MS","SEVERITY_ORDER","isBlocklisted","isAllowlisted","DEFAULT_CONFIG","startWizardServer"]}