From 61490251bd46b9b60ef9acc17d6caeeda8625aa5 Mon Sep 17 00:00:00 2001 From: JBAhire Date: Thu, 2 Apr 2026 22:48:03 -0700 Subject: [PATCH 1/4] feat: clean CLI output with SARIF and gate thresholds Every finding now shows inline remediation (Fix:) and standards mapping (Standards: OWASP, NIST, ISO). Terminal output includes domain score breakdown and security/hardening split scores. - Add remediation and standards to terminal findings - Restore domain score breakdown in terminal output - Keep SARIF 2.1.0 output on scan, test, and gate - Restore gate thresholds (--min-score, --min-grade, --no-critical) - Remove HTML and compliance reporters (available via Guard0 Platform) - Remove CycloneDX reporter - Add --forensics and --browser to endpoint scanning - Export reportSarif from SDK --- src/cli/commands/endpoint.ts | 5 +- src/cli/commands/gate.ts | 2 - src/cli/commands/inventory.ts | 19 +- src/cli/commands/scan.ts | 39 +--- src/index.ts | 3 +- src/reporters/compliance-html.ts | 269 -------------------------- src/reporters/html.ts | 162 ---------------- src/reporters/inventory-cyclonedx.ts | 190 ------------------ src/reporters/terminal.ts | 11 +- tests/unit/cyclonedx-reporter.test.ts | 100 ---------- tests/unit/sarif-reporter.test.ts | 117 ----------- 11 files changed, 26 insertions(+), 891 deletions(-) delete mode 100644 src/reporters/compliance-html.ts delete mode 100644 src/reporters/html.ts delete mode 100644 src/reporters/inventory-cyclonedx.ts delete mode 100644 tests/unit/cyclonedx-reporter.test.ts delete mode 100644 tests/unit/sarif-reporter.test.ts diff --git a/src/cli/commands/endpoint.ts b/src/cli/commands/endpoint.ts index cf47645..eb26098 100644 --- a/src/cli/commands/endpoint.ts +++ b/src/cli/commands/endpoint.ts @@ -4,6 +4,7 @@ import { Command } from 'commander'; import { loadDaemonConfig } from '../../daemon/config.js'; import { readPid } from '../../daemon/process.js'; import { getMachineId } from '../../platform/machine-id.js'; +// v2: Platform auth/upload removed — g0 is offline-first import { listMCPServers } from '../../mcp/analyzer.js'; import { scanEndpoint } from '../../endpoint/scanner.js'; import { reportEndpointTerminal } from '../../reporters/endpoint-terminal.js'; @@ -38,6 +39,8 @@ async function runEndpointScan(options: { } else { reportEndpointTerminal(result); } + + // v2: Upload removed — use Guard0 Platform for cloud features } // ─── Shared options ───────────────────────────────────────────────────────── @@ -99,7 +102,7 @@ const statusSubcommand = new Command('status') const machineId = getMachineId(); const config = loadDaemonConfig(); const pid = readPid(config.pidFile); - const authed = false; + const authed = false; // v2: auth removed, g0 is offline-first let mcpServerCount = 0; try { diff --git a/src/cli/commands/gate.ts b/src/cli/commands/gate.ts index 042cfc6..c883903 100644 --- a/src/cli/commands/gate.ts +++ b/src/cli/commands/gate.ts @@ -18,7 +18,6 @@ export const gateCommand = new Command('gate') .option('-o, --output ', 'Write JSON report to file') .option('--config ', 'Path to config file (default: .g0.yaml)') .option('--sarif [file]', 'Also output SARIF report') - .option('--upload', 'Upload results to Guard0 platform') .action(async (targetPath: string, options: { minScore?: string; minGrade?: string; @@ -27,7 +26,6 @@ export const gateCommand = new Command('gate') output?: string; config?: string; sarif?: string | boolean; - upload?: boolean; }) => { const resolvedPath = path.resolve(targetPath); diff --git a/src/cli/commands/inventory.ts b/src/cli/commands/inventory.ts index 1def693..1832f7e 100644 --- a/src/cli/commands/inventory.ts +++ b/src/cli/commands/inventory.ts @@ -6,7 +6,7 @@ import { buildInventory } from '../../inventory/builder.js'; import { reportInventoryTerminal } from '../../reporters/inventory-terminal.js'; import { reportInventoryJson } from '../../reporters/inventory-json.js'; import { reportInventoryMarkdown } from '../../reporters/inventory-markdown.js'; -import { reportInventoryCycloneDX } from '../../reporters/inventory-cyclonedx.js'; +// v2: CycloneDX export removed — available via Guard0 Platform import { diffInventory } from '../../inventory/differ.js'; import { reportInventoryDiffTerminal } from '../../reporters/inventory-diff-terminal.js'; import { reportInventoryDiffMarkdown } from '../../reporters/inventory-diff-markdown.js'; @@ -20,10 +20,11 @@ export const inventoryCommand = new Command('inventory') .argument('[path]', 'Path to the agent project or remote URL', '.') .option('--json', 'Output as JSON') .option('--markdown', 'Output as Markdown') - .option('--cyclonedx [file]', 'Output as CycloneDX 1.6 SBOM') + // v2: --cyclonedx removed — available via Guard0 Platform .option('--diff ', 'Diff against a baseline inventory JSON') .option('-o, --output ', 'Write output to file') .option('--config ', 'Path to config file (default: .g0.yaml)') + // v2: --upload removed — use Guard0 Platform for platform integration .option('--no-banner', 'Suppress the g0 banner') .action(async (targetPath: string, options: { json?: boolean; @@ -32,6 +33,7 @@ export const inventoryCommand = new Command('inventory') diff?: string; output?: string; config?: string; + upload?: boolean; banner?: boolean; }) => { let resolvedPath: string; @@ -107,17 +109,7 @@ export const inventoryCommand = new Command('inventory') return; } - // CycloneDX mode - if (options.cyclonedx !== undefined) { - const outFile = typeof options.cyclonedx === 'string' ? options.cyclonedx : options.output; - const json = reportInventoryCycloneDX(inventory, outFile ?? undefined); - if (!outFile) { - console.log(json); - } else { - console.log(`CycloneDX SBOM written to: ${outFile}`); - } - return; - } + // v2: CycloneDX mode removed — available via Guard0 Platform if (options.json) { const json = reportInventoryJson(inventory, options.output); @@ -141,6 +133,7 @@ export const inventoryCommand = new Command('inventory') } } + // v2: Upload removed — use Guard0 Platform for cloud features } catch (error) { spinner.stop(); console.error('Inventory failed:', error instanceof Error ? error.message : error); diff --git a/src/cli/commands/scan.ts b/src/cli/commands/scan.ts index c5e5e1e..d3ae625 100644 --- a/src/cli/commands/scan.ts +++ b/src/cli/commands/scan.ts @@ -4,9 +4,8 @@ import { Command } from 'commander'; import { runScan } from '../../pipeline.js'; import { reportTerminal } from '../../reporters/terminal.js'; import { reportJson } from '../../reporters/json.js'; -import { reportHtml } from '../../reporters/html.js'; import { reportSarif } from '../../reporters/sarif.js'; -import { reportComplianceHtml, SUPPORTED_STANDARDS } from '../../reporters/compliance-html.js'; +// v2: HTML and compliance reporters removed — available via Guard0 Platform import { loadConfig } from '../../config/loader.js'; import { createSpinner } from '../ui.js'; import { isRemoteUrl, parseTarget, cloneRepo } from '../../remote/clone.js'; @@ -17,8 +16,8 @@ export const scanCommand = new Command('scan') .description('Assess an AI agent project for security issues') .argument('[path]', 'Path to the agent project or remote URL', '.') .option('--json', 'Output as JSON') - .option('--html [file]', 'Output as HTML report') .option('--sarif [file]', 'Output as SARIF 2.1.0') + // v2: --html removed — available via Guard0 Platform .option('-o, --output ', 'Write JSON output to file') .option('-q, --quiet', 'Suppress terminal output') .option('--severity ', 'Minimum severity to report (critical|high|medium|low)') @@ -29,7 +28,7 @@ export const scanCommand = new Command('scan') .option('--min-confidence ', 'Minimum confidence to report (high|medium|low)') .option('--ai', 'Enable AI-powered analysis (requires ANTHROPIC_API_KEY, OPENAI_API_KEY, or GOOGLE_API_KEY)') .option('--model ', 'AI model to use (e.g., claude-sonnet-4-5-20250929, gpt-5-mini, gemini-2.5-flash)') - .option('--report ', `Generate compliance report (${SUPPORTED_STANDARDS.join('|')})`) + // v2: --report and --upload removed — available via Guard0 Platform .option('--include-tests', 'Include test files in agent graph (normally excluded)') .option('--show-all', 'Show all findings including suppressed utility-code ones') .option('--ruleset ', 'Rule pack tier: recommended (~200 high-signal), extended (~800), or all (default)') @@ -44,7 +43,6 @@ export const scanCommand = new Command('scan') .option('--no-banner', 'Suppress the g0 banner') .action(async (targetPath: string, options: { json?: boolean; - html?: string | boolean; sarif?: string | boolean; output?: string; quiet?: boolean; @@ -56,7 +54,7 @@ export const scanCommand = new Command('scan') minConfidence?: string; ai?: boolean; model?: string; - report?: string; + // v2: report, upload removed includeTests?: boolean; showAll?: boolean; ruleset?: string; @@ -210,9 +208,7 @@ export const scanCommand = new Command('scan') const hiddenLowConfidence = allFindings.length - result.findings.length; if (options.sarif) { - const sarifPath = typeof options.sarif === 'string' - ? options.sarif - : undefined; + const sarifPath = typeof options.sarif === 'string' ? options.sarif : undefined; const sarif = reportSarif(result, sarifPath); if (!sarifPath) { console.log(sarif); @@ -224,16 +220,8 @@ export const scanCommand = new Command('scan') if (!options.output) { console.log(json); } - } else if (options.html) { - const htmlPath = typeof options.html === 'string' - ? options.html - : path.join(resolvedPath, 'g0-report.html'); - reportHtml(result, htmlPath); - if (!options.quiet) { - console.log(`HTML report written to: ${htmlPath}`); - } } else { - reportTerminal(result, { showBanner: options.banner !== false, hiddenLowConfidence }); + reportTerminal(result, { showBanner: options.banner !== false, showUploadNudge: true, hiddenLowConfidence }); } // Also write JSON if --output specified alongside terminal @@ -241,19 +229,8 @@ export const scanCommand = new Command('scan') reportJson(result, options.output); } - // Generate compliance report - if (options.report) { - const reportPath = path.join(resolvedPath, `g0-${options.report}-report.html`); - try { - reportComplianceHtml(result, options.report, reportPath); - if (!options.quiet) { - console.log(`\n Compliance report (${options.report}) written to: ${reportPath}`); - } - } catch (err) { - console.error(` Report generation failed: ${err instanceof Error ? err.message : err}`); - } - } - + // v2: Compliance reports and platform upload removed + // Available via Guard0 Platform (guard0.ai/early-access) // CI gate evaluation if (options.ci) { try { diff --git a/src/index.ts b/src/index.ts index fa0da27..bb80418 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,7 +9,8 @@ export type { Rule } from './types/control.js'; export { getAllRules, getRuleById, getRulesByDomain } from './analyzers/rules/index.js'; export { calculateScore } from './scoring/engine.js'; export { reportJson } from './reporters/json.js'; -export { reportHtml } from './reporters/html.js'; +export { reportSarif } from './reporters/sarif.js'; +// v2: reportHtml removed — available via Guard0 Platform // Endpoint types export type { diff --git a/src/reporters/compliance-html.ts b/src/reporters/compliance-html.ts deleted file mode 100644 index 0bd5f94..0000000 --- a/src/reporters/compliance-html.ts +++ /dev/null @@ -1,269 +0,0 @@ -import type { ScanResult } from '../types/score.js'; -import type { Finding } from '../types/finding.js'; -import * as fs from 'node:fs'; - -interface Control { - id: string; - name: string; - status: 'pass' | 'fail' | 'partial'; - findings: string[]; - notes: string; -} - -interface ComplianceResult { - standard: string; - standardName: string; - controls: Control[]; - overallScore: number; - passCount: number; - failCount: number; - partialCount: number; -} - -const STANDARD_NAMES: Record = { - 'owasp-agentic': 'OWASP Agentic Security Top 10', - 'aiuc1': 'AIUC-1 AI Agent Security', - 'iso42001': 'ISO 42001 AI Management System', - 'nist-ai-rmf': 'NIST AI Risk Management Framework', - 'iso23894': 'ISO 23894 AI Risk Management', - 'owasp-aivss': 'OWASP AI Verification Standard', - 'owasp-agentic-top10': 'OWASP Agentic AI Top 10', - 'soc2': 'SOC 2 Trust Criteria', - 'eu-ai-act': 'EU AI Act', -}; - -const STANDARD_CONTROLS: Record> = { - 'owasp-agentic': [ - { id: 'ASI01', name: 'Prompt Injection', domains: ['goal-integrity'] }, - { id: 'ASI02', name: 'Excessive Tool Access', domains: ['tool-safety'] }, - { id: 'ASI03', name: 'Privilege Escalation', domains: ['identity-access'] }, - { id: 'ASI04', name: 'Supply Chain Vulnerabilities', domains: ['supply-chain'] }, - { id: 'ASI05', name: 'Unsafe Code Execution', domains: ['code-execution'] }, - { id: 'ASI06', name: 'Data Leakage', domains: ['data-leakage'] }, - { id: 'ASI07', name: 'Memory/Context Manipulation', domains: ['memory-context'] }, - { id: 'ASI08', name: 'Cascading Failures', domains: ['cascading-failures'] }, - { id: 'ASI09', name: 'Improper Session Handling', domains: ['memory-context', 'identity-access'] }, - { id: 'ASI10', name: 'Excessive Autonomy', domains: ['goal-integrity', 'tool-safety', 'human-oversight', 'rogue-agent'] }, - ], - 'aiuc1': [ - { id: 'A001', name: 'Agent Identity', domains: ['identity-access'] }, - { id: 'A002', name: 'Agent Authentication', domains: ['identity-access'] }, - { id: 'B001', name: 'Tool Validation', domains: ['tool-safety'] }, - { id: 'B002', name: 'Permission Boundaries', domains: ['tool-safety', 'identity-access'] }, - { id: 'C001', name: 'Data Classification', domains: ['data-leakage'] }, - { id: 'C002', name: 'Data Flow Control', domains: ['data-leakage', 'memory-context'] }, - { id: 'D001', name: 'Execution Sandboxing', domains: ['code-execution'] }, - { id: 'D002', name: 'Resource Limits', domains: ['cascading-failures'] }, - { id: 'E001', name: 'Prompt Hardening', domains: ['goal-integrity'] }, - { id: 'E002', name: 'Injection Prevention', domains: ['goal-integrity', 'code-execution'] }, - { id: 'F001', name: 'Supply Chain Verification', domains: ['supply-chain'] }, - { id: 'F002', name: 'Quarterly Security Testing', domains: ['goal-integrity', 'tool-safety', 'identity-access', 'supply-chain', 'code-execution', 'memory-context', 'data-leakage', 'cascading-failures', 'human-oversight', 'inter-agent', 'reliability-bounds', 'rogue-agent'] }, - ], - 'nist-ai-rmf': [ - { id: 'GOVERN-1', name: 'AI Risk Policies', domains: ['goal-integrity', 'tool-safety', 'identity-access'] }, - { id: 'MAP-1', name: 'Context Mapping', domains: ['goal-integrity'] }, - { id: 'MAP-2', name: 'Task Purpose', domains: ['goal-integrity', 'tool-safety'] }, - { id: 'MEASURE-1', name: 'Risk Metrics', domains: ['goal-integrity', 'tool-safety', 'identity-access', 'data-leakage'] }, - { id: 'MEASURE-2', name: 'Performance Testing', domains: ['cascading-failures'] }, - { id: 'MANAGE-1', name: 'Risk Treatment', domains: ['goal-integrity', 'tool-safety', 'identity-access'] }, - { id: 'MANAGE-2', name: 'Deploy Monitoring', domains: ['cascading-failures', 'memory-context'] }, - { id: 'MANAGE-3', name: 'Incident Response', domains: ['cascading-failures'] }, - { id: 'MANAGE-4', name: 'Third Party Risk', domains: ['supply-chain', 'inter-agent'] }, - { id: 'MANAGE-5', name: 'Reliability & Bounds', domains: ['reliability-bounds'] }, - ], - 'iso42001': [ - { id: 'A.5.1', name: 'AI Policy', domains: ['goal-integrity', 'tool-safety', 'identity-access'] }, - { id: 'A.5.2', name: 'AI Roles', domains: ['identity-access'] }, - { id: 'A.6.1', name: 'Risk Assessment', domains: ['goal-integrity', 'tool-safety', 'identity-access', 'data-leakage'] }, - { id: 'A.6.2', name: 'Risk Treatment', domains: ['goal-integrity', 'tool-safety', 'identity-access'] }, - { id: 'A.7.1', name: 'AI Development', domains: ['code-execution', 'tool-safety'] }, - { id: 'A.7.2', name: 'Testing & Validation', domains: ['cascading-failures'] }, - { id: 'A.8.1', name: 'Data Management', domains: ['data-leakage', 'memory-context'] }, - { id: 'A.9.1', name: 'Third Party', domains: ['supply-chain'] }, - { id: 'A.10.1', name: 'Monitoring & Review', domains: ['cascading-failures', 'goal-integrity'] }, - ], - 'soc2': [ - { id: 'CC6.1', name: 'Logical Access', domains: ['identity-access'] }, - { id: 'CC6.3', name: 'Access Restrictions', domains: ['identity-access', 'tool-safety'] }, - { id: 'CC6.6', name: 'System Boundaries', domains: ['code-execution', 'cascading-failures'] }, - { id: 'CC6.7', name: 'Data Transmission', domains: ['data-leakage'] }, - { id: 'CC6.8', name: 'Unauthorized Software', domains: ['supply-chain'] }, - { id: 'CC7.1', name: 'Monitoring', domains: ['cascading-failures'] }, - { id: 'CC7.2', name: 'Anomaly Detection', domains: ['goal-integrity'] }, - { id: 'CC7.3', name: 'Security Evaluation', domains: ['goal-integrity', 'tool-safety', 'identity-access', 'data-leakage'] }, - { id: 'CC8.1', name: 'Change Management', domains: ['supply-chain'] }, - ], - 'eu-ai-act': [ - { id: 'Art.9.1', name: 'Risk Management', domains: ['goal-integrity', 'tool-safety', 'identity-access'] }, - { id: 'Art.9.2', name: 'Risk Identification', domains: ['goal-integrity', 'tool-safety'] }, - { id: 'Art.10.2', name: 'Data Quality', domains: ['data-leakage', 'memory-context'] }, - { id: 'Art.10.3', name: 'Data Governance', domains: ['data-leakage', 'identity-access'] }, - { id: 'Art.15.1', name: 'Accuracy', domains: ['goal-integrity'] }, - { id: 'Art.15.2', name: 'Resilience', domains: ['cascading-failures', 'code-execution'] }, - { id: 'Art.14.1', name: 'Human Oversight', domains: ['human-oversight'] }, - { id: 'Art.15.3', name: 'Cybersecurity', domains: ['identity-access', 'supply-chain'] }, - ], - 'iso23894': [ - { id: '6.1', name: 'Risk Identification', domains: ['goal-integrity', 'tool-safety'] }, - { id: '6.2', name: 'Risk Analysis', domains: ['goal-integrity', 'tool-safety', 'identity-access', 'data-leakage'] }, - { id: '6.3', name: 'Risk Evaluation', domains: ['goal-integrity', 'tool-safety', 'identity-access'] }, - { id: '6.4', name: 'Risk Treatment', domains: ['goal-integrity', 'tool-safety', 'identity-access'] }, - { id: '7.1', name: 'Communication', domains: ['cascading-failures'] }, - { id: '7.2', name: 'Monitoring', domains: ['cascading-failures', 'memory-context'] }, - ], - 'owasp-aivss': [ - { id: 'L1.1', name: 'Input Validation', domains: ['goal-integrity', 'code-execution'] }, - { id: 'L1.2', name: 'Output Validation', domains: ['code-execution', 'data-leakage'] }, - { id: 'L1.3', name: 'Model Security', domains: ['supply-chain'] }, - { id: 'L2.1', name: 'Data Protection', domains: ['data-leakage', 'memory-context'] }, - { id: 'L2.2', name: 'Access Control', domains: ['identity-access'] }, - { id: 'L2.3', name: 'Tool Security', domains: ['tool-safety'] }, - { id: 'L3.1', name: 'Advanced Threat Protection', domains: ['goal-integrity', 'cascading-failures'] }, - { id: 'L3.2', name: 'Supply Chain Security', domains: ['supply-chain'] }, - ], - 'owasp-agentic-top10': [ - { id: 'AAT-1', name: 'Agent Authorization Hijacking', domains: ['identity-access', 'tool-safety'] }, - { id: 'AAT-2', name: 'Agent Untraceability', domains: ['rogue-agent'] }, - { id: 'AAT-3', name: 'Agent Critical Systems Interaction', domains: ['code-execution', 'tool-safety'] }, - { id: 'AAT-4', name: 'Agent Alignment Faking', domains: ['reliability-bounds', 'rogue-agent'] }, - { id: 'AAT-5', name: 'Agent Goal Manipulation', domains: ['goal-integrity'] }, - { id: 'AAT-6', name: 'Agent Impact Chain / Blast Radius', domains: ['data-leakage', 'cascading-failures'] }, - { id: 'AAT-7', name: 'Agent Memory/Context Manipulation', domains: ['memory-context'] }, - { id: 'AAT-8', name: 'Multi-Agent Exploitation', domains: ['inter-agent'] }, - { id: 'AAT-9', name: 'Agent Supply Chain / Dependency Attacks', domains: ['supply-chain'] }, - { id: 'AAT-10', name: 'Agent Checker Out of Loop', domains: ['human-oversight'] }, - ], -}; - -function assessControl( - controlDomains: string[], - findingsByDomain: Map, -): { status: 'pass' | 'fail' | 'partial'; matchedFindings: Finding[] } { - const matched: Finding[] = []; - for (const domain of controlDomains) { - const domainFindings = findingsByDomain.get(domain) ?? []; - matched.push(...domainFindings); - } - - if (matched.length === 0) return { status: 'pass', matchedFindings: [] }; - - const hasCriticalOrHigh = matched.some( - (f) => f.severity === 'critical' || f.severity === 'high' - ); - return { - status: hasCriticalOrHigh ? 'fail' : 'partial', - matchedFindings: matched, - }; -} - -function generateCompliance(standard: string, result: ScanResult): ComplianceResult { - const controls = STANDARD_CONTROLS[standard]; - if (!controls) { - throw new Error(`Unknown standard: ${standard}. Supported: ${Object.keys(STANDARD_CONTROLS).join(', ')}`); - } - - // Group findings by domain - const findingsByDomain = new Map(); - for (const f of result.findings) { - const existing = findingsByDomain.get(f.domain) ?? []; - existing.push(f); - findingsByDomain.set(f.domain, existing); - } - - const assessed: Control[] = controls.map((c) => { - const { status, matchedFindings } = assessControl(c.domains, findingsByDomain); - const uniqueRules = [...new Set(matchedFindings.map((f) => f.ruleId))]; - - let notes = ''; - if (status === 'pass') notes = 'No findings detected for mapped domains.'; - else if (status === 'fail') notes = `${matchedFindings.length} findings with critical/high severity.`; - else notes = `${matchedFindings.length} findings (medium/low severity).`; - - return { id: c.id, name: c.name, status, findings: uniqueRules, notes }; - }); - - const passCount = assessed.filter((c) => c.status === 'pass').length; - const failCount = assessed.filter((c) => c.status === 'fail').length; - const partialCount = assessed.filter((c) => c.status === 'partial').length; - const overallScore = ((passCount + partialCount * 0.5) / assessed.length) * 100; - - return { - standard, - standardName: STANDARD_NAMES[standard] || standard, - controls: assessed, - overallScore, - passCount, - failCount, - partialCount, - }; -} - -export function reportComplianceHtml( - result: ScanResult, - standard: string, - outputPath: string -): void { - const compliance = generateCompliance(standard, result); - - const statusIcon = (s: string) => - s === 'pass' ? '✅' : s === 'fail' ? '❌' : '⚠'; - const statusColor = (s: string) => - s === 'pass' ? '#22c55e' : s === 'fail' ? '#ef4444' : '#f59e0b'; - - const html = ` - -${compliance.standardName} — Guard0 Compliance Report - - -

${compliance.standardName}

-
-Score: ${result.score.overall}/100 (${result.score.grade}) · -${result.findings.length} total findings · -Generated ${new Date().toISOString().split('T')[0]} by Guard0 -
-
-
${Math.round(compliance.overallScore)}%
Compliance Score
-
${compliance.passCount}
Pass
-
${compliance.partialCount}
Partial
-
${compliance.failCount}
Fail
-
- - - -${compliance.controls - .map( - (c) => ` - - - - - -` - ) - .join('')} -
StatusControlNameFindingsNotes
${statusIcon(c.status)} ${c.status.toUpperCase()}${c.id}${c.name}${c.findings.length > 0 ? c.findings.join(', ') : '—'}${c.notes}
-
-

Guard0 AI Agent Security Scanner · guard0.ai

-

Standard: ${compliance.standardName} · ${compliance.controls.length} controls assessed

-
-`; - - fs.writeFileSync(outputPath, html, 'utf-8'); -} - -export const SUPPORTED_STANDARDS = Object.keys(STANDARD_CONTROLS); diff --git a/src/reporters/html.ts b/src/reporters/html.ts deleted file mode 100644 index 62ed27b..0000000 --- a/src/reporters/html.ts +++ /dev/null @@ -1,162 +0,0 @@ -import * as fs from 'node:fs'; -import { createRequire } from 'node:module'; -import Handlebars from 'handlebars'; -import type { ScanResult } from '../types/score.js'; - -const require = createRequire(import.meta.url); -const { version: g0Version } = require('../../package.json'); - -const HTML_TEMPLATE = ` - - - - -g0 Security Report — {{framework}} - - - -

g0 Security Report

-
-
Target: {{target}} | Framework: {{framework}}
-
{{timestamp}} | Duration: {{duration}}s | Files: {{fileCount}}{{#if activePreset}} | Preset: {{activePreset}}{{/if}}
- {{#if analyzability}}
Analyzability: {{analyzability.score}}% ({{analyzability.opaqueFileCount}} opaque files)
{{/if}} -
- -
-
{{grade}}
-
-
{{overall}} / 100
-
-
-
- -
-
{{critical}}
Critical
-
{{high}}
High
-
{{medium}}
Medium
-
{{low}}
Low
-
- -

Domain Scores

- - - - {{#each domains}} - - {{/each}} - -
DomainScoreFindings
{{label}}{{score}}{{findings}}
- -{{#if hasFindings}} -

Findings ({{findingCount}})

-{{#each findings}} -
-
- {{severity}} - {{title}} - [{{ruleId}}] -
-
{{description}}
-
{{file}}:{{line}}
- {{#if remediation}}
Fix: {{remediation}}
{{/if}} - {{#if standardsText}}
Standards: {{standardsText}}
{{/if}} -
-{{/each}} -{{/if}} - - - -`; - -export function reportHtml(result: ScanResult, outputPath: string): void { - const template = Handlebars.compile(HTML_TEMPLATE); - - const data = { - g0Version, - target: result.graph.rootPath, - framework: result.graph.primaryFramework, - timestamp: result.timestamp, - duration: (result.duration / 1000).toFixed(1), - fileCount: result.graph.files.all.length, - grade: result.score.grade, - gradeLower: result.score.grade.toLowerCase(), - overall: result.score.overall, - barColor: result.score.overall >= 80 ? 'bar-green' : result.score.overall >= 60 ? 'bar-yellow' : 'bar-red', - activePreset: result.activePreset, - analyzability: result.analyzability ? { - score: result.analyzability.score, - opaqueFileCount: result.analyzability.opaqueFiles.length, - } : undefined, - critical: result.findings.filter(f => f.severity === 'critical').length, - high: result.findings.filter(f => f.severity === 'high').length, - medium: result.findings.filter(f => f.severity === 'medium').length, - low: result.findings.filter(f => f.severity === 'low').length, - domains: result.score.domains, - hasFindings: result.findings.length > 0, - findingCount: result.findings.length, - findings: result.findings.map(f => { - const refs: string[] = []; - if (f.standards.owaspAgentic?.length) refs.push(`OWASP: ${f.standards.owaspAgentic.join(', ')}`); - if (f.standards.aiuc1?.length) refs.push(`AIUC-1: ${f.standards.aiuc1.join(', ')}`); - if (f.standards.iso42001?.length) refs.push(`ISO 42001: ${f.standards.iso42001.join(', ')}`); - if (f.standards.nistAiRmf?.length) refs.push(`NIST AI RMF: ${f.standards.nistAiRmf.join(', ')}`); - return { - severity: f.severity, - title: f.title, - ruleId: f.ruleId, - description: f.description, - file: f.location.file, - line: f.location.line, - remediation: f.remediation, - standardsText: refs.join(' | '), - }; - }), - }; - - const html = template(data); - fs.writeFileSync(outputPath, html, 'utf-8'); -} diff --git a/src/reporters/inventory-cyclonedx.ts b/src/reporters/inventory-cyclonedx.ts deleted file mode 100644 index 35fc15a..0000000 --- a/src/reporters/inventory-cyclonedx.ts +++ /dev/null @@ -1,190 +0,0 @@ -import * as fs from 'node:fs'; -import { randomUUID } from 'node:crypto'; -import type { InventoryResult } from '../types/inventory.js'; - -interface CycloneDXBom { - bomFormat: string; - specVersion: string; - serialNumber: string; - version: number; - metadata: { - timestamp: string; - tools: { vendor: string; name: string; version: string }[]; - properties?: { name: string; value: string }[]; - }; - components: CycloneDXComponent[]; - services: CycloneDXService[]; - dependencies: CycloneDXDependency[]; -} - -interface CycloneDXComponent { - type: string; - 'bom-ref': string; - name: string; - version?: string; - description?: string; - group?: string; - properties?: { name: string; value: string }[]; -} - -interface CycloneDXService { - 'bom-ref': string; - name: string; - description?: string; - endpoints?: string[]; - properties?: { name: string; value: string }[]; -} - -interface CycloneDXDependency { - ref: string; - dependsOn: string[]; -} - -export function reportInventoryCycloneDX(inventory: InventoryResult, outputPath?: string): string { - const components: CycloneDXComponent[] = []; - const services: CycloneDXService[] = []; - const dependencies: CycloneDXDependency[] = []; - - // Models → machine-learning-model - for (const model of inventory.models) { - const ref = `model:${model.name}:${model.provider}`; - components.push({ - type: 'machine-learning-model', - 'bom-ref': ref, - name: model.name, - group: model.provider, - properties: [ - { name: 'ai:framework', value: model.framework }, - { name: 'ai:file', value: model.file }, - ], - }); - } - - // Frameworks → framework - for (const fw of inventory.frameworks) { - const ref = `framework:${fw.name}`; - components.push({ - type: 'framework', - 'bom-ref': ref, - name: fw.name, - version: fw.version, - properties: [ - { name: 'ai:file', value: fw.file }, - ], - }); - } - - // Tools → library - for (const tool of inventory.tools) { - const ref = `tool:${tool.name}:${tool.framework}`; - components.push({ - type: 'library', - 'bom-ref': ref, - name: tool.name, - description: tool.description, - properties: [ - { name: 'ai:framework', value: tool.framework }, - { name: 'ai:capabilities', value: tool.capabilities.join(', ') }, - { name: 'ai:hasSideEffects', value: String(tool.hasSideEffects) }, - { name: 'ai:hasValidation', value: String(tool.hasValidation) }, - ], - }); - } - - // MCP servers → services - for (const server of inventory.mcpServers) { - services.push({ - 'bom-ref': `mcp:${server.name}`, - name: server.name, - description: `MCP server: ${server.command} ${server.args.join(' ')}`, - properties: [ - { name: 'ai:command', value: server.command }, - { name: 'ai:hasSecrets', value: String(server.hasSecrets) }, - { name: 'ai:isPinned', value: String(server.isPinned) }, - ], - }); - } - - // Agent-tool-model dependencies - for (const agent of inventory.agents) { - const agentRef = `agent:${agent.name}:${agent.framework}`; - const deps: string[] = []; - - // Link to model - if (agent.model) { - const modelRef = components.find(c => c.type === 'machine-learning-model' && c.name === agent.model); - if (modelRef) deps.push(modelRef['bom-ref']); - } - - // Link to framework - const fwRef = components.find(c => c.type === 'framework' && c.name === agent.framework); - if (fwRef) deps.push(fwRef['bom-ref']); - - // Link to tools (by framework match) - const toolRefs = components.filter(c => c.type === 'library' && c.properties?.some(p => p.name === 'ai:framework' && p.value === agent.framework)); - for (const tr of toolRefs) deps.push(tr['bom-ref']); - - if (deps.length > 0) { - dependencies.push({ ref: agentRef, dependsOn: deps }); - } - } - - // Enrichment: API endpoints as services - if (inventory.summary.enrichment) { - const e = inventory.summary.enrichment; - // Group external API endpoints as a service - if (e.totalAPIEndpoints > 0) { - services.push({ - 'bom-ref': 'enrichment:api-endpoints', - name: 'External API Endpoints', - description: `${e.totalAPIEndpoints} API endpoints detected (${e.totalExternalAPIs} external)`, - properties: [ - { name: 'ai:security:totalEndpoints', value: String(e.totalAPIEndpoints) }, - { name: 'ai:security:externalEndpoints', value: String(e.totalExternalAPIs) }, - ], - }); - } - } - - // Enrichment metadata properties - const metadataProperties: { name: string; value: string }[] = []; - if (inventory.summary.enrichment) { - const e = inventory.summary.enrichment; - metadataProperties.push( - { name: 'ai:security:apiEndpoints', value: String(e.totalAPIEndpoints) }, - { name: 'ai:security:externalAPIs', value: String(e.totalExternalAPIs) }, - { name: 'ai:security:databaseAccesses', value: String(e.totalDatabaseAccesses) }, - { name: 'ai:security:unparameterizedQueries', value: String(e.unparameterizedQueries) }, - { name: 'ai:security:authFlows', value: String(e.totalAuthFlows) }, - { name: 'ai:security:permissionChecks', value: String(e.totalPermissionChecks) }, - { name: 'ai:security:piiReferences', value: String(e.totalPIIReferences) }, - { name: 'ai:security:piiWithoutMasking', value: String(e.piiWithoutMasking) }, - { name: 'ai:security:messageQueues', value: String(e.totalMessageQueues) }, - { name: 'ai:security:rateLimits', value: String(e.totalRateLimits) }, - { name: 'ai:security:callGraphEdges', value: String(e.totalCallGraphEdges) }, - ); - } - - const bom: CycloneDXBom = { - bomFormat: 'CycloneDX', - specVersion: '1.6', - serialNumber: `urn:uuid:${randomUUID()}`, - version: 1, - metadata: { - timestamp: new Date().toISOString(), - tools: [{ vendor: 'guard0', name: 'g0', version: '1.0.0' }], - ...(metadataProperties.length > 0 ? { properties: metadataProperties } : {}), - }, - components, - services, - dependencies, - }; - - const json = JSON.stringify(bom, null, 2); - - if (outputPath) { - fs.writeFileSync(outputPath, json, 'utf-8'); - } - - return json; -} diff --git a/src/reporters/terminal.ts b/src/reporters/terminal.ts index 2dfe0c6..fae2561 100644 --- a/src/reporters/terminal.ts +++ b/src/reporters/terminal.ts @@ -135,15 +135,16 @@ export function reportTerminal(result: ScanResult, options?: TerminalOptions): v // Overall score printOverallScore(score); - // Upload nudge (shown when not authenticated and --upload not used) - if (options?.showUploadNudge) { - console.log(chalk.dim('\n See your agent architecture \u2192 g0 scan . --upload (free at guard0.ai)')); - } - // Split scores (security vs hardening) if (score.securityScore !== undefined && score.hardeningScore !== undefined) { console.log(chalk.dim(`\n Security: ${score.securityScore}/100 | Hardening: ${score.hardeningScore}/100`)); } + // Guard0 Platform CTA + console.log(chalk.dim('\n ' + '─'.repeat(60))); + console.log(chalk.dim(' For complete accountability across all your agents')); + console.log(chalk.bold(' \u2192 https://guard0.ai/early-access')); + console.log(chalk.dim(' ' + '─'.repeat(60))); + console.log(''); } diff --git a/tests/unit/cyclonedx-reporter.test.ts b/tests/unit/cyclonedx-reporter.test.ts deleted file mode 100644 index 16017d6..0000000 --- a/tests/unit/cyclonedx-reporter.test.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { describe, it, expect } from 'vitest'; -import { reportInventoryCycloneDX } from '../../src/reporters/inventory-cyclonedx.js'; -import type { InventoryResult } from '../../src/types/inventory.js'; - -function makeInventory(): InventoryResult { - return { - models: [ - { name: 'gpt-4', provider: 'openai', framework: 'langchain', file: 'agent.py', line: 5 }, - ], - frameworks: [ - { name: 'langchain', version: '0.1.0', file: 'requirements.txt' }, - ], - tools: [ - { - name: 'search_tool', framework: 'langchain', description: 'Web search', - capabilities: ['web'], hasSideEffects: false, hasValidation: true, - file: 'agent.py', line: 10, - }, - ], - mcpServers: [ - { name: 'test-server', command: 'node', args: ['server.js'], hasSecrets: false, isPinned: false, file: 'config.json' }, - ], - agents: [ - { name: 'researcher', framework: 'langchain', toolCount: 1, model: 'gpt-4', hasDelegation: false, file: 'agent.py', line: 20 }, - ], - vectorDBs: [], - risks: [ - { level: 'high', category: 'shell', description: 'Shell tool detected' }, - ], - summary: { - totalModels: 1, totalFrameworks: 1, totalTools: 1, totalAgents: 1, - totalMCPServers: 1, totalVectorDBs: 0, totalRisks: 1, - riskBreakdown: { critical: 0, high: 1, medium: 0, low: 0 }, - }, - }; -} - -describe('CycloneDX Reporter', () => { - it('generates valid CycloneDX 1.6 structure', () => { - const json = reportInventoryCycloneDX(makeInventory()); - const bom = JSON.parse(json); - - expect(bom.bomFormat).toBe('CycloneDX'); - expect(bom.specVersion).toBe('1.6'); - expect(bom.version).toBe(1); - expect(bom.serialNumber).toMatch(/^urn:uuid:/); - }); - - it('maps models to machine-learning-model components', () => { - const json = reportInventoryCycloneDX(makeInventory()); - const bom = JSON.parse(json); - - const mlComponents = bom.components.filter((c: { type: string }) => c.type === 'machine-learning-model'); - expect(mlComponents).toHaveLength(1); - expect(mlComponents[0].name).toBe('gpt-4'); - expect(mlComponents[0].group).toBe('openai'); - }); - - it('maps frameworks to framework components', () => { - const json = reportInventoryCycloneDX(makeInventory()); - const bom = JSON.parse(json); - - const fwComponents = bom.components.filter((c: { type: string }) => c.type === 'framework'); - expect(fwComponents).toHaveLength(1); - expect(fwComponents[0].name).toBe('langchain'); - expect(fwComponents[0].version).toBe('0.1.0'); - }); - - it('maps tools to library components', () => { - const json = reportInventoryCycloneDX(makeInventory()); - const bom = JSON.parse(json); - - const libComponents = bom.components.filter((c: { type: string }) => c.type === 'library'); - expect(libComponents).toHaveLength(1); - expect(libComponents[0].name).toBe('search_tool'); - }); - - it('maps MCP servers to services', () => { - const json = reportInventoryCycloneDX(makeInventory()); - const bom = JSON.parse(json); - - expect(bom.services).toHaveLength(1); - expect(bom.services[0].name).toBe('test-server'); - }); - - it('generates agent dependencies', () => { - const json = reportInventoryCycloneDX(makeInventory()); - const bom = JSON.parse(json); - - expect(bom.dependencies.length).toBeGreaterThan(0); - }); - - it('includes metadata with tool info', () => { - const json = reportInventoryCycloneDX(makeInventory()); - const bom = JSON.parse(json); - - expect(bom.metadata.tools[0].name).toBe('g0'); - expect(bom.metadata.timestamp).toBeDefined(); - }); -}); diff --git a/tests/unit/sarif-reporter.test.ts b/tests/unit/sarif-reporter.test.ts deleted file mode 100644 index 8e9519e..0000000 --- a/tests/unit/sarif-reporter.test.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { describe, it, expect } from 'vitest'; -import { reportSarif } from '../../src/reporters/sarif.js'; -import type { ScanResult } from '../../src/types/score.js'; -import type { Finding } from '../../src/types/finding.js'; - -function makeFinding(overrides?: Partial): Finding { - return { - id: 'AA-GI-001-0', - ruleId: 'AA-GI-001', - title: 'Test finding', - description: 'Test description', - severity: 'high', - confidence: 'high', - domain: 'goal-integrity', - location: { file: 'agent.py', line: 10, snippet: 'some code here' }, - remediation: 'Fix it', - standards: { owaspAgentic: ['ASI01'] }, - ...overrides, - }; -} - -function makeScanResult(findings: Finding[]): ScanResult { - return { - findings, - score: { - overall: 75, - grade: 'C' as const, - domains: [], - }, - graph: { - rootPath: '/test', - primaryFramework: 'langchain', - secondaryFrameworks: [], - agents: [], - tools: [], - prompts: [], - files: { all: [], python: [], typescript: [], javascript: [], configs: [] }, - models: [], - vectorDBs: [], - mcpServers: [], - }, - timestamp: '2025-01-01T00:00:00.000Z', - duration: 1000, - }; -} - -describe('SARIF Reporter', () => { - it('generates valid SARIF 2.1.0 structure', () => { - const result = makeScanResult([makeFinding()]); - const json = reportSarif(result); - const sarif = JSON.parse(json); - - expect(sarif.$schema).toContain('sarif-schema-2.1.0'); - expect(sarif.version).toBe('2.1.0'); - expect(sarif.runs).toHaveLength(1); - expect(sarif.runs[0].tool.driver.name).toBe('g0'); - expect(sarif.runs[0].results).toHaveLength(1); - }); - - it('includes partialFingerprints on results', () => { - const result = makeScanResult([makeFinding()]); - const json = reportSarif(result); - const sarif = JSON.parse(json); - const sarifResult = sarif.runs[0].results[0]; - - expect(sarifResult.partialFingerprints).toBeDefined(); - expect(sarifResult.partialFingerprints.primaryLocationLineHash).toBeDefined(); - expect(typeof sarifResult.partialFingerprints.primaryLocationLineHash).toBe('string'); - expect(sarifResult.partialFingerprints.primaryLocationLineHash.length).toBe(64); // SHA-256 hex - }); - - it('produces deterministic fingerprints', () => { - const finding = makeFinding(); - const result1 = reportSarif(makeScanResult([finding])); - const result2 = reportSarif(makeScanResult([finding])); - const sarif1 = JSON.parse(result1); - const sarif2 = JSON.parse(result2); - - expect(sarif1.runs[0].results[0].partialFingerprints.primaryLocationLineHash) - .toBe(sarif2.runs[0].results[0].partialFingerprints.primaryLocationLineHash); - }); - - it('includes helpUri on rule descriptors', () => { - const result = makeScanResult([makeFinding()]); - const json = reportSarif(result); - const sarif = JSON.parse(json); - - // AA-GI-001 maps to ASI01 which should have a helpUri - const giRule = sarif.runs[0].tool.driver.rules.find((r: { id: string }) => r.id === 'AA-GI-001'); - expect(giRule).toBeDefined(); - expect(giRule.helpUri).toContain('owasp.org'); - }); - - it('includes standards in rule properties', () => { - const result = makeScanResult([makeFinding()]); - const json = reportSarif(result); - const sarif = JSON.parse(json); - - const giRule = sarif.runs[0].tool.driver.rules.find((r: { id: string }) => r.id === 'AA-GI-001'); - expect(giRule.properties.standards).toBeDefined(); - expect(giRule.properties.standards.owaspAgentic).toContain('ASI01'); - }); - - it('writes to file when outputPath provided', () => { - const result = makeScanResult([makeFinding()]); - const tmpPath = '/tmp/test-sarif-output.json'; - reportSarif(result, tmpPath); - - const { readFileSync } = require('node:fs'); - const content = readFileSync(tmpPath, 'utf-8'); - const sarif = JSON.parse(content); - expect(sarif.version).toBe('2.1.0'); - - // Cleanup - require('node:fs').unlinkSync(tmpPath); - }); -}); From b11d40e9bba1ba202f7c490a4d0a833aa8b5e60e Mon Sep 17 00:00:00 2001 From: JBAhire Date: Sat, 4 Apr 2026 10:11:38 -0700 Subject: [PATCH 2/4] fix: remove handlebars dependency (8 CVEs) and update yaml handlebars was only used by the deleted HTML reporter. Removes 1 critical, 3 high, 3 medium, 1 low vulnerability. --- package-lock.json | 94 ++++------------------------------------------- package.json | 9 ++--- 2 files changed, 12 insertions(+), 91 deletions(-) diff --git a/package-lock.json b/package-lock.json index 82e86db..95b6578 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,16 @@ { "name": "@guard0/g0", - "version": "1.5.1", + "version": "1.7.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@guard0/g0", - "version": "1.5.1", + "version": "1.7.2", "license": "AGPL-3.0-or-later", "dependencies": { "chalk": "^5.3.0", "commander": "^12.1.0", - "handlebars": "^4.7.8", "ignore": "^6.0.2", "ora": "^8.1.0", "yaml": "^2.5.0", @@ -1365,27 +1364,6 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, "node_modules/ignore": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", @@ -1516,15 +1494,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/mlly": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", @@ -1576,12 +1545,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "license": "MIT" - }, "node_modules/node-addon-api": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.5.0.tgz", @@ -1677,9 +1640,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "peer": true, @@ -1899,15 +1862,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -2103,19 +2057,6 @@ "tree-kill": "cli.js" } }, - "node_modules/tree-sitter": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.21.1.tgz", - "integrity": "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "node-addon-api": "^8.0.0", - "node-gyp-build": "^4.8.0" - } - }, "node_modules/tree-sitter-go": { "version": "0.23.4", "resolved": "https://registry.npmjs.org/tree-sitter-go/-/tree-sitter-go-0.23.4.tgz", @@ -2330,19 +2271,6 @@ "dev": true, "license": "MIT" }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "license": "BSD-2-Clause", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -2531,16 +2459,10 @@ "node": ">=8" } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "license": "MIT" - }, "node_modules/yaml": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "license": "ISC", "peer": true, "bin": { diff --git a/package.json b/package.json index 9920a1e..efb0187 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,6 @@ "dependencies": { "chalk": "^5.3.0", "commander": "^12.1.0", -"handlebars": "^4.7.8", "ignore": "^6.0.2", "ora": "^8.1.0", "yaml": "^2.5.0", @@ -107,11 +106,11 @@ }, "optionalDependencies": { "tree-sitter": "0.21.1", - "tree-sitter-python": "0.23.4", - "tree-sitter-typescript": "0.23.2", - "tree-sitter-javascript": "0.23.1", + "tree-sitter-go": "0.23.4", "tree-sitter-java": "0.23.4", - "tree-sitter-go": "0.23.4" + "tree-sitter-javascript": "0.23.1", + "tree-sitter-python": "0.23.4", + "tree-sitter-typescript": "0.23.2" }, "engines": { "node": ">=20.0.0" From e63fa9edec313d68e0f8f1afd8687284c93b15d9 Mon Sep 17 00:00:00 2001 From: JBAhire Date: Sat, 4 Apr 2026 11:14:37 -0700 Subject: [PATCH 3/4] fix: regenerate lockfile to include tree-sitter --- package-lock.json | 508 ++++++++++++++++++++++++---------------------- 1 file changed, 260 insertions(+), 248 deletions(-) diff --git a/package-lock.json b/package-lock.json index 95b6578..f64eb69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,9 +39,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", - "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", "cpu": [ "ppc64" ], @@ -56,9 +56,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", - "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", "cpu": [ "arm" ], @@ -73,9 +73,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", - "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", "cpu": [ "arm64" ], @@ -90,9 +90,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", - "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", "cpu": [ "x64" ], @@ -107,9 +107,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", - "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", "cpu": [ "arm64" ], @@ -124,9 +124,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", - "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", "cpu": [ "x64" ], @@ -141,9 +141,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", - "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", "cpu": [ "arm64" ], @@ -158,9 +158,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", - "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", "cpu": [ "x64" ], @@ -175,9 +175,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", - "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", "cpu": [ "arm" ], @@ -192,9 +192,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", - "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", "cpu": [ "arm64" ], @@ -209,9 +209,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", - "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", "cpu": [ "ia32" ], @@ -226,9 +226,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", - "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", "cpu": [ "loong64" ], @@ -243,9 +243,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", - "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", "cpu": [ "mips64el" ], @@ -260,9 +260,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", - "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", "cpu": [ "ppc64" ], @@ -277,9 +277,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", - "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", "cpu": [ "riscv64" ], @@ -294,9 +294,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", - "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", "cpu": [ "s390x" ], @@ -311,9 +311,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", - "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", "cpu": [ "x64" ], @@ -328,9 +328,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", - "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", "cpu": [ "arm64" ], @@ -345,9 +345,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", - "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", "cpu": [ "x64" ], @@ -362,9 +362,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", - "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", "cpu": [ "arm64" ], @@ -379,9 +379,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", - "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", "cpu": [ "x64" ], @@ -396,9 +396,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", - "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", "cpu": [ "arm64" ], @@ -413,9 +413,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", - "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", "cpu": [ "x64" ], @@ -430,9 +430,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", - "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", "cpu": [ "arm64" ], @@ -447,9 +447,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", - "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", "cpu": [ "ia32" ], @@ -464,9 +464,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", - "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", "cpu": [ "x64" ], @@ -520,9 +520,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", + "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==", "cpu": [ "arm" ], @@ -534,9 +534,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz", + "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==", "cpu": [ "arm64" ], @@ -548,9 +548,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz", + "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==", "cpu": [ "arm64" ], @@ -562,9 +562,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz", + "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==", "cpu": [ "x64" ], @@ -576,9 +576,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz", + "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==", "cpu": [ "arm64" ], @@ -590,9 +590,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz", + "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==", "cpu": [ "x64" ], @@ -604,9 +604,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz", + "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==", "cpu": [ "arm" ], @@ -618,9 +618,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz", + "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==", "cpu": [ "arm" ], @@ -632,9 +632,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz", + "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==", "cpu": [ "arm64" ], @@ -646,9 +646,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz", + "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==", "cpu": [ "arm64" ], @@ -660,9 +660,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz", + "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==", "cpu": [ "loong64" ], @@ -674,9 +674,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz", + "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==", "cpu": [ "loong64" ], @@ -688,9 +688,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz", + "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==", "cpu": [ "ppc64" ], @@ -702,9 +702,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz", + "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==", "cpu": [ "ppc64" ], @@ -716,9 +716,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz", + "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==", "cpu": [ "riscv64" ], @@ -730,9 +730,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz", + "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==", "cpu": [ "riscv64" ], @@ -744,9 +744,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz", + "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==", "cpu": [ "s390x" ], @@ -758,9 +758,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", - "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz", + "integrity": "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==", "cpu": [ "x64" ], @@ -772,9 +772,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", - "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz", + "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==", "cpu": [ "x64" ], @@ -786,9 +786,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz", + "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==", "cpu": [ "x64" ], @@ -800,9 +800,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz", + "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==", "cpu": [ "arm64" ], @@ -814,9 +814,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz", + "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==", "cpu": [ "arm64" ], @@ -828,9 +828,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz", + "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==", "cpu": [ "ia32" ], @@ -842,9 +842,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz", + "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==", "cpu": [ "x64" ], @@ -856,9 +856,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz", + "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==", "cpu": [ "x64" ], @@ -877,9 +877,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.19.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.11.tgz", - "integrity": "sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==", + "version": "22.19.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz", + "integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==", "dev": true, "license": "MIT", "peer": true, @@ -1015,9 +1015,9 @@ } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -1232,9 +1232,9 @@ "license": "MIT" }, "node_modules/esbuild": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", - "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1246,32 +1246,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.3", - "@esbuild/android-arm": "0.27.3", - "@esbuild/android-arm64": "0.27.3", - "@esbuild/android-x64": "0.27.3", - "@esbuild/darwin-arm64": "0.27.3", - "@esbuild/darwin-x64": "0.27.3", - "@esbuild/freebsd-arm64": "0.27.3", - "@esbuild/freebsd-x64": "0.27.3", - "@esbuild/linux-arm": "0.27.3", - "@esbuild/linux-arm64": "0.27.3", - "@esbuild/linux-ia32": "0.27.3", - "@esbuild/linux-loong64": "0.27.3", - "@esbuild/linux-mips64el": "0.27.3", - "@esbuild/linux-ppc64": "0.27.3", - "@esbuild/linux-riscv64": "0.27.3", - "@esbuild/linux-s390x": "0.27.3", - "@esbuild/linux-x64": "0.27.3", - "@esbuild/netbsd-arm64": "0.27.3", - "@esbuild/netbsd-x64": "0.27.3", - "@esbuild/openbsd-arm64": "0.27.3", - "@esbuild/openbsd-x64": "0.27.3", - "@esbuild/openharmony-arm64": "0.27.3", - "@esbuild/sunos-x64": "0.27.3", - "@esbuild/win32-arm64": "0.27.3", - "@esbuild/win32-ia32": "0.27.3", - "@esbuild/win32-x64": "0.27.3" + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" } }, "node_modules/estree-walker": { @@ -1340,9 +1340,9 @@ } }, "node_modules/get-east-asian-width": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", "license": "MIT", "engines": { "node": ">=18" @@ -1352,9 +1352,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.13.6", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz", - "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==", + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz", + "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==", "dev": true, "license": "MIT", "dependencies": { @@ -1495,16 +1495,16 @@ } }, "node_modules/mlly": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", - "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", + "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", "dev": true, "license": "MIT", "dependencies": { - "acorn": "^8.15.0", + "acorn": "^8.16.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", - "ufo": "^1.6.1" + "ufo": "^1.6.3" } }, "node_modules/ms": { @@ -1546,9 +1546,9 @@ } }, "node_modules/node-addon-api": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.5.0.tgz", - "integrity": "sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.7.0.tgz", + "integrity": "sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA==", "license": "MIT", "optional": true, "engines": { @@ -1676,9 +1676,9 @@ } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "dev": true, "funding": [ { @@ -1799,9 +1799,9 @@ } }, "node_modules/rollup": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", - "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", + "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==", "dev": true, "license": "MIT", "dependencies": { @@ -1815,31 +1815,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.59.0", - "@rollup/rollup-android-arm64": "4.59.0", - "@rollup/rollup-darwin-arm64": "4.59.0", - "@rollup/rollup-darwin-x64": "4.59.0", - "@rollup/rollup-freebsd-arm64": "4.59.0", - "@rollup/rollup-freebsd-x64": "4.59.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", - "@rollup/rollup-linux-arm-musleabihf": "4.59.0", - "@rollup/rollup-linux-arm64-gnu": "4.59.0", - "@rollup/rollup-linux-arm64-musl": "4.59.0", - "@rollup/rollup-linux-loong64-gnu": "4.59.0", - "@rollup/rollup-linux-loong64-musl": "4.59.0", - "@rollup/rollup-linux-ppc64-gnu": "4.59.0", - "@rollup/rollup-linux-ppc64-musl": "4.59.0", - "@rollup/rollup-linux-riscv64-gnu": "4.59.0", - "@rollup/rollup-linux-riscv64-musl": "4.59.0", - "@rollup/rollup-linux-s390x-gnu": "4.59.0", - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@rollup/rollup-linux-x64-musl": "4.59.0", - "@rollup/rollup-openbsd-x64": "4.59.0", - "@rollup/rollup-openharmony-arm64": "4.59.0", - "@rollup/rollup-win32-arm64-msvc": "4.59.0", - "@rollup/rollup-win32-ia32-msvc": "4.59.0", - "@rollup/rollup-win32-x64-gnu": "4.59.0", - "@rollup/rollup-win32-x64-msvc": "4.59.0", + "@rollup/rollup-android-arm-eabi": "4.60.1", + "@rollup/rollup-android-arm64": "4.60.1", + "@rollup/rollup-darwin-arm64": "4.60.1", + "@rollup/rollup-darwin-x64": "4.60.1", + "@rollup/rollup-freebsd-arm64": "4.60.1", + "@rollup/rollup-freebsd-x64": "4.60.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", + "@rollup/rollup-linux-arm-musleabihf": "4.60.1", + "@rollup/rollup-linux-arm64-gnu": "4.60.1", + "@rollup/rollup-linux-arm64-musl": "4.60.1", + "@rollup/rollup-linux-loong64-gnu": "4.60.1", + "@rollup/rollup-linux-loong64-musl": "4.60.1", + "@rollup/rollup-linux-ppc64-gnu": "4.60.1", + "@rollup/rollup-linux-ppc64-musl": "4.60.1", + "@rollup/rollup-linux-riscv64-gnu": "4.60.1", + "@rollup/rollup-linux-riscv64-musl": "4.60.1", + "@rollup/rollup-linux-s390x-gnu": "4.60.1", + "@rollup/rollup-linux-x64-gnu": "4.60.1", + "@rollup/rollup-linux-x64-musl": "4.60.1", + "@rollup/rollup-openbsd-x64": "4.60.1", + "@rollup/rollup-openharmony-arm64": "4.60.1", + "@rollup/rollup-win32-arm64-msvc": "4.60.1", + "@rollup/rollup-win32-ia32-msvc": "4.60.1", + "@rollup/rollup-win32-x64-gnu": "4.60.1", + "@rollup/rollup-win32-x64-msvc": "4.60.1", "fsevents": "~2.3.2" } }, @@ -1862,6 +1862,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -1916,12 +1926,12 @@ } }, "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -2057,6 +2067,19 @@ "tree-kill": "cli.js" } }, + "node_modules/tree-sitter": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.21.1.tgz", + "integrity": "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-addon-api": "^8.0.0", + "node-gyp-build": "^4.8.0" + } + }, "node_modules/tree-sitter-go": { "version": "0.23.4", "resolved": "https://registry.npmjs.org/tree-sitter-go/-/tree-sitter-go-0.23.4.tgz", @@ -2218,16 +2241,6 @@ } } }, - "node_modules/tsup/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" - } - }, "node_modules/tsx": { "version": "4.21.0", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", @@ -2284,7 +2297,6 @@ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", From 8b3ab16ac9c8c86858970d1a31ba9996616b674d Mon Sep 17 00:00:00 2001 From: JBAhire Date: Sat, 4 Apr 2026 11:18:10 -0700 Subject: [PATCH 4/4] fix: remove HTML reporter test (reporter deleted) --- tests/integration/scan.test.ts | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/tests/integration/scan.test.ts b/tests/integration/scan.test.ts index 196d82f..2fad434 100644 --- a/tests/integration/scan.test.ts +++ b/tests/integration/scan.test.ts @@ -4,7 +4,7 @@ import * as fs from 'node:fs'; import * as os from 'node:os'; import { runScan } from '../../src/pipeline.js'; import { reportJson } from '../../src/reporters/json.js'; -import { reportHtml } from '../../src/reporters/html.js'; +// v2: HTML reporter removed — available via Guard0 Platform const FIXTURES = path.resolve(__dirname, '../fixtures'); @@ -94,16 +94,4 @@ describe('JSON reporter', () => { }); }); -describe('HTML reporter', () => { - it('produces valid HTML file', async () => { - const result = await runScan({ includeTests: true, showAll: true, targetPath: path.join(FIXTURES, 'vulnerable-agent') }); - const tmpFile = path.join(os.tmpdir(), `g0-test-${Date.now()}.html`); - reportHtml(result, tmpFile); - expect(fs.existsSync(tmpFile)).toBe(true); - const content = fs.readFileSync(tmpFile, 'utf-8'); - expect(content).toContain(''); - expect(content).toContain('g0 Security Report'); - expect(content).toContain('Goal Integrity'); - fs.unlinkSync(tmpFile); - }); -}); +// v2: HTML reporter test removed — HTML reports available via Guard0 Platform