extension-guard 0.4.0 โ†’ 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -134,7 +134,9 @@ function createCli() {
134
134
  console.log();
135
135
  }
136
136
  }
137
- console.log(chalk.dim("Run `extension-guard rules --details <ruleId>` for more information."));
137
+ console.log(
138
+ chalk.dim("Run `extension-guard rules --details <ruleId>` for more information.")
139
+ );
138
140
  console.log();
139
141
  });
140
142
  program.command("baseline").description(
@@ -196,7 +198,9 @@ function createCli() {
196
198
  console.log("Usage:");
197
199
  console.log(` ${chalk.cyan("extension-guard scan --verify-integrity")}`);
198
200
  if (options.output) {
199
- console.log(` ${chalk.cyan(`extension-guard scan --verify-integrity --hash-db ${outputPath}`)}`);
201
+ console.log(
202
+ ` ${chalk.cyan(`extension-guard scan --verify-integrity --hash-db ${outputPath}`)}`
203
+ );
200
204
  }
201
205
  console.log();
202
206
  } catch (error) {
@@ -334,7 +338,9 @@ function printTableReport(report) {
334
338
  console.log(chalk.bold(`${icons.shield()} Extension Guard v${VERSION}`));
335
339
  console.log();
336
340
  for (const ide of report.environment.ides) {
337
- console.log(`${icons.folder()} ${chalk.cyan(ide.name)}: ${ide.path} (${ide.extensionCount} extensions)`);
341
+ console.log(
342
+ `${icons.folder()} ${chalk.cyan(ide.name)}: ${ide.path} (${ide.extensionCount} extensions)`
343
+ );
338
344
  }
339
345
  console.log();
340
346
  console.log(chalk.dim("\u2501".repeat(60)));
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport * as fs from 'node:fs';\nimport {\n ExtensionGuardScanner,\n VERSION,\n JsonReporter,\n SarifReporter,\n MarkdownReporter,\n loadPolicyConfig,\n PolicyEngine,\n DETECTION_RULES,\n detectIDEPaths,\n readExtensionsFromDirectory,\n collectFiles,\n createHashRecord,\n saveHashDatabase,\n loadHashDatabase,\n getDefaultDatabasePath,\n} from '@aspect-guard/core';\nimport type {\n FullScanReport,\n Reporter,\n PolicyViolation,\n PolicyAction,\n ExtensionHash,\n} from '@aspect-guard/core';\n\n// CLI output configuration\ninterface OutputConfig {\n color: boolean;\n emoji: boolean;\n}\n\nlet outputConfig: OutputConfig = {\n color: true,\n emoji: true,\n};\n\n// Emoji/text mappings\nconst icons = {\n shield: () => (outputConfig.emoji ? '๐Ÿ›ก๏ธ' : '[GUARD]'),\n folder: () => (outputConfig.emoji ? '๐Ÿ“' : '[DIR]'),\n critical: () => (outputConfig.emoji ? 'โ›”' : '[!!!]'),\n high: () => (outputConfig.emoji ? '๐Ÿ”ด' : '[!!]'),\n medium: () => (outputConfig.emoji ? '๐ŸŸก' : '[!]'),\n safe: () => (outputConfig.emoji ? '๐ŸŸข' : '[OK]'),\n summary: () => (outputConfig.emoji ? '๐Ÿ“Š' : '[SUM]'),\n time: () => (outputConfig.emoji ? 'โฑ๏ธ' : '[TIME]'),\n check: () => (outputConfig.emoji ? 'โœ“' : '[v]'),\n cross: () => (outputConfig.emoji ? 'โœ—' : '[x]'),\n info: () => (outputConfig.emoji ? 'โ„น' : '[i]'),\n};\n\nexport function createCli(): Command {\n const program = new Command();\n\n program\n .name('extension-guard')\n .description('Scan VSCode extensions for security issues')\n .version(VERSION)\n .option('--no-color', 'Disable colored output')\n .option('--no-emoji', 'Disable emoji output')\n .hook('preAction', (thisCommand) => {\n const opts = thisCommand.opts();\n outputConfig.color = opts.color !== false;\n outputConfig.emoji = opts.emoji !== false;\n if (!outputConfig.color) {\n chalk.level = 0;\n }\n });\n\n // Init command - create policy configuration file\n program\n .command('init')\n .description('Create a new .extension-guard.json policy configuration file')\n .option('-f, --force', 'Overwrite existing configuration file')\n .option('-o, --output <path>', 'Output path for configuration file', '.extension-guard.json')\n .action((options) => {\n const configPath = options.output;\n\n if (fs.existsSync(configPath) && !options.force) {\n console.error(chalk.red(`Error: ${configPath} already exists.`));\n console.error(chalk.dim('Use --force to overwrite.'));\n process.exit(2);\n }\n\n const template = {\n $schema:\n 'https://raw.githubusercontent.com/astroicers/extension-guard/main/schemas/policy.schema.json',\n version: '1.0',\n policy: {\n allowlist: [],\n blocklist: [],\n rules: {\n minTrustScore: {\n enabled: true,\n threshold: 60,\n action: 'warn',\n },\n blockObfuscated: {\n enabled: false,\n action: 'info',\n },\n requireVerifiedPublisher: {\n enabled: false,\n action: 'info',\n },\n },\n },\n scanning: {\n minSeverity: 'info',\n includeDevDependencies: false,\n },\n };\n\n fs.writeFileSync(configPath, JSON.stringify(template, null, 2) + '\\n');\n console.log(chalk.green(`${icons.check()} Created ${configPath}`));\n console.log();\n console.log('Next steps:');\n console.log(` 1. Edit ${chalk.cyan(configPath)} to customize your policy`);\n console.log(` 2. Run ${chalk.cyan('extension-guard audit')} to check your extensions`);\n console.log();\n });\n\n // Rules command - list available detection rules\n program\n .command('rules')\n .description('List available detection rules')\n .option('--details <ruleId>', 'Show detailed information for a specific rule')\n .action((options) => {\n if (options.details) {\n const rule = DETECTION_RULES.find((r) => r.id === options.details);\n if (!rule) {\n console.error(chalk.red(`Error: Rule '${options.details}' not found.`));\n console.log(chalk.dim('Run `extension-guard rules` to see available rules.'));\n process.exit(1);\n }\n\n console.log();\n console.log(chalk.bold(rule.id));\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log(`Name: ${rule.name}`);\n console.log(`Severity: ${formatSeverity(rule.severity)}`);\n console.log(`Category: ${rule.category}`);\n console.log(`Description: ${rule.description}`);\n if (rule.mitreAttackId) {\n console.log(`MITRE ATT&CK: ${rule.mitreAttackId}`);\n }\n console.log();\n return;\n }\n\n console.log();\n console.log(chalk.bold('Available Detection Rules'));\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log();\n\n const rulesBySeverity: Record<string, typeof DETECTION_RULES> = {};\n for (const rule of DETECTION_RULES) {\n if (!rulesBySeverity[rule.severity]) {\n rulesBySeverity[rule.severity] = [];\n }\n rulesBySeverity[rule.severity].push(rule);\n }\n\n const severityOrder = ['critical', 'high', 'medium', 'low', 'info'];\n for (const severity of severityOrder) {\n const rules = rulesBySeverity[severity];\n if (rules && rules.length > 0) {\n console.log(formatSeverity(severity));\n for (const rule of rules) {\n console.log(` ${chalk.cyan(rule.id.padEnd(14))} ${rule.name}`);\n }\n console.log();\n }\n }\n\n console.log(chalk.dim('Run `extension-guard rules --details <ruleId>` for more information.'));\n console.log();\n });\n\n // Baseline command - generate hash database from installed extensions\n program\n .command('baseline')\n .description(\n 'Generate integrity hash database from currently installed extensions\\n\\n' +\n 'This creates a baseline of known-good hashes that can be used to detect\\n' +\n 'tampering or supply chain attacks on trusted extensions.\\n\\n' +\n 'Examples:\\n' +\n ' extension-guard baseline Generate baseline from all IDEs\\n' +\n ' extension-guard baseline -o hashes.json Output to custom file\\n' +\n ' extension-guard baseline --append Add to existing database'\n )\n .option('-p, --path <paths...>', 'Custom extension paths to scan')\n .option('-o, --output <file>', 'Output path for hash database')\n .option('--append', 'Append to existing database instead of overwriting')\n .option('-q, --quiet', 'Only show results, no progress')\n .action(async (options) => {\n const spinner = options.quiet ? null : ora('Generating integrity baseline...').start();\n\n try {\n // Detect IDE paths\n let idePaths: string[];\n if (options.path && options.path.length > 0) {\n idePaths = options.path;\n } else {\n const ides = detectIDEPaths();\n idePaths = ides.map((ide) => ide.path);\n }\n\n if (idePaths.length === 0) {\n if (spinner) spinner.fail('No extension directories found');\n console.error(chalk.red('Error: No IDE extension directories detected.'));\n console.error(chalk.dim('Use --path to specify custom paths.'));\n process.exit(3);\n }\n\n // Load existing database if appending\n let hashes: Map<string, ExtensionHash>;\n const outputPath = options.output || getDefaultDatabasePath();\n if (options.append) {\n hashes = loadHashDatabase(outputPath);\n } else {\n hashes = new Map();\n }\n\n // Collect hashes from all extensions\n let processed = 0;\n let errors = 0;\n\n for (const idePath of idePaths) {\n if (spinner) spinner.text = `Processing ${idePath}...`;\n\n try {\n const extensions = await readExtensionsFromDirectory(idePath);\n\n for (const ext of extensions) {\n try {\n const files = await collectFiles(ext.installPath);\n const record = createHashRecord(ext.id, ext.version, files, 'manual');\n hashes.set(`${ext.id}@${ext.version}`, record);\n processed++;\n } catch {\n errors++;\n }\n }\n } catch {\n errors++;\n }\n }\n\n // Save database\n saveHashDatabase(hashes, outputPath);\n\n if (spinner) spinner.succeed('Baseline generated');\n\n console.log();\n console.log(chalk.bold('Integrity Baseline Generated'));\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log(`${icons.check()} Processed: ${chalk.green(processed)} extensions`);\n if (errors > 0) {\n console.log(`${icons.cross()} Errors: ${chalk.yellow(errors)}`);\n }\n console.log(`${icons.folder()} Database: ${chalk.cyan(outputPath)}`);\n console.log();\n console.log('Usage:');\n console.log(` ${chalk.cyan('extension-guard scan --verify-integrity')}`);\n if (options.output) {\n console.log(` ${chalk.cyan(`extension-guard scan --verify-integrity --hash-db ${outputPath}`)}`);\n }\n console.log();\n } catch (error) {\n if (spinner) spinner.fail('Baseline generation failed');\n console.error(chalk.red('Error:'), error instanceof Error ? error.message : error);\n process.exit(3);\n }\n });\n\n program\n .command('scan')\n .description(\n 'Scan installed VSCode extensions\\n\\n' +\n 'Examples:\\n' +\n ' extension-guard scan Scan all detected IDEs\\n' +\n ' extension-guard scan --ide cursor Scan Cursor IDE only\\n' +\n ' extension-guard scan --format json -o r.json Output as JSON file\\n' +\n ' extension-guard scan --format sarif Output for GitHub Code Scanning'\n )\n .option('-p, --path <paths...>', 'Custom extension paths to scan')\n .option('-f, --format <format>', 'Output format (table|json|sarif|markdown)', 'table')\n .option('-o, --output <file>', 'Output file path (default: stdout)')\n .option('-s, --severity <level>', 'Minimum severity to show', 'info')\n .option('-q, --quiet', 'Only show results, no progress')\n .option('--include-safe', 'Include safe extensions in output')\n .option('--verify-integrity', 'Verify extension integrity against known-good hashes')\n .option('--hash-db <path>', 'Path to custom hash database file')\n .action(async (options) => {\n const isJsonOutput = options.format === 'json' || options.format === 'sarif';\n const spinner = options.quiet || isJsonOutput ? null : ora('Scanning extensions...').start();\n\n try {\n const scanner = new ExtensionGuardScanner({\n autoDetect: !options.path,\n idePaths: options.path ?? [],\n severity: options.severity,\n verifyIntegrity: options.verifyIntegrity ?? false,\n hashDatabasePath: options.hashDb,\n });\n\n const report = await scanner.scan();\n\n if (spinner) {\n spinner.succeed('Scan complete');\n }\n\n // Generate output based on format\n const output = generateOutput(report, options.format, {\n includeSafe: options.includeSafe,\n });\n\n // Write to file or stdout\n if (options.output) {\n fs.writeFileSync(options.output, output);\n if (!options.quiet) {\n console.log(chalk.green(`Report saved to ${options.output}`));\n }\n } else if (options.format === 'table') {\n printTableReport(report);\n } else {\n console.log(output);\n }\n\n // Exit with error code if critical or high issues found\n const hasCritical = report.summary.bySeverity.critical > 0;\n const hasHigh = report.summary.bySeverity.high > 0;\n if (hasCritical || hasHigh) {\n process.exit(1);\n }\n } catch (error) {\n if (spinner) {\n spinner.fail('Scan failed');\n }\n console.error(chalk.red('Error:'), error instanceof Error ? error.message : error);\n process.exit(3);\n }\n });\n\n program\n .command('audit')\n .description('Audit extensions against policy rules')\n .option('-c, --config <path>', 'Path to policy config file', '.extension-guard.json')\n .option('-p, --path <paths...>', 'Custom extension paths to scan')\n .option('--fail-on <level>', 'Fail on violations at or above level (block|warn|info)', 'block')\n .option('-f, --format <format>', 'Output format (table|json|sarif|markdown)', 'table')\n .option('-o, --output <file>', 'Output file path (default: stdout)')\n .option('-q, --quiet', 'Only show results, no progress')\n .action(async (options) => {\n const isJsonOutput = options.format === 'json' || options.format === 'sarif';\n const spinner =\n options.quiet || isJsonOutput ? null : ora('Loading policy configuration...').start();\n\n try {\n // Load policy configuration\n const policyConfig = await loadPolicyConfig(options.config);\n\n if (!policyConfig) {\n if (spinner) {\n spinner.fail('Policy configuration not found');\n }\n console.error(chalk.red(`Error: Could not find policy config at ${options.config}`));\n console.error(\n chalk.dim('Create a .extension-guard.json file or specify a path with --config')\n );\n process.exit(2);\n }\n\n if (spinner) {\n spinner.text = 'Scanning extensions...';\n }\n\n // Run scan with config-based settings\n const scanner = new ExtensionGuardScanner({\n autoDetect: !options.path,\n idePaths: options.path ?? [],\n severity: policyConfig.scanning?.minSeverity ?? 'info',\n });\n\n const report = await scanner.scan();\n\n if (spinner) {\n spinner.text = 'Evaluating policy rules...';\n }\n\n // Evaluate policy\n const engine = new PolicyEngine(policyConfig);\n const violations = engine.evaluate(report.results);\n\n if (spinner) {\n spinner.succeed('Audit complete');\n }\n\n // Generate output based on format\n if (options.format !== 'table') {\n const output = generateOutput(report, options.format, {\n includeSafe: false,\n });\n if (options.output) {\n fs.writeFileSync(options.output, output);\n if (!options.quiet) {\n console.log(chalk.green(`Report saved to ${options.output}`));\n }\n } else {\n console.log(output);\n }\n }\n\n // Print violations summary\n printAuditResults(violations, options.failOn as PolicyAction);\n\n // Determine exit code based on --fail-on level\n const shouldFail = hasViolationsAtLevel(violations, options.failOn as PolicyAction);\n if (shouldFail) {\n process.exit(1);\n }\n } catch (error) {\n if (spinner) {\n spinner.fail('Audit failed');\n }\n console.error(chalk.red('Error:'), error instanceof Error ? error.message : error);\n process.exit(3);\n }\n });\n\n return program;\n}\n\nfunction generateOutput(\n report: FullScanReport,\n format: string,\n options: { includeSafe?: boolean } = {}\n): string {\n let reporter: Reporter;\n\n switch (format) {\n case 'json':\n reporter = new JsonReporter();\n break;\n case 'sarif':\n reporter = new SarifReporter();\n break;\n case 'markdown':\n reporter = new MarkdownReporter();\n break;\n case 'table':\n default:\n // Table format is handled separately\n return '';\n }\n\n return reporter.generate(report, {\n includeSafe: options.includeSafe,\n includeEvidence: true,\n });\n}\n\nfunction printTableReport(report: FullScanReport): void {\n console.log();\n console.log(chalk.bold(`${icons.shield()} Extension Guard v${VERSION}`));\n console.log();\n\n for (const ide of report.environment.ides) {\n console.log(`${icons.folder()} ${chalk.cyan(ide.name)}: ${ide.path} (${ide.extensionCount} extensions)`);\n }\n\n console.log();\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log();\n\n const critical = report.results.filter((r) => r.riskLevel === 'critical');\n const high = report.results.filter((r) => r.riskLevel === 'high');\n const medium = report.results.filter((r) => r.riskLevel === 'medium');\n const safe = report.results.filter((r) => r.riskLevel === 'safe' || r.riskLevel === 'low');\n\n if (critical.length > 0) {\n console.log(chalk.red.bold(`${icons.critical()} CRITICAL (${critical.length})`));\n for (const ext of critical) {\n printExtensionResult(ext);\n }\n }\n\n if (high.length > 0) {\n console.log(chalk.red(`${icons.high()} HIGH (${high.length})`));\n for (const ext of high) {\n printExtensionResult(ext);\n }\n }\n\n if (medium.length > 0) {\n console.log(chalk.yellow(`${icons.medium()} MEDIUM (${medium.length})`));\n for (const ext of medium) {\n console.log(` ${ext.extensionId} (Trust: ${ext.trustScore}/100)`);\n }\n console.log();\n }\n\n if (safe.length > 0) {\n console.log(chalk.green(`${icons.safe()} SAFE (${safe.length})`));\n }\n\n console.log();\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log();\n\n const { bySeverity, byRiskLevel } = report.summary;\n console.log(\n `${icons.summary()} Summary: ${report.uniqueExtensions} scanned ยท ` +\n `${bySeverity.critical} critical ยท ${bySeverity.high} high ยท ` +\n `${bySeverity.medium} medium ยท ${byRiskLevel.safe} safe`\n );\n console.log(`${icons.time()} Completed in ${(report.scanDurationMs / 1000).toFixed(1)}s`);\n console.log();\n}\n\nfunction formatSeverity(severity: string): string {\n switch (severity) {\n case 'critical':\n return chalk.red.bold('CRITICAL');\n case 'high':\n return chalk.red('HIGH');\n case 'medium':\n return chalk.yellow('MEDIUM');\n case 'low':\n return chalk.blue('LOW');\n case 'info':\n return chalk.dim('INFO');\n default:\n return severity;\n }\n}\n\nfunction printExtensionResult(result: FullScanReport['results'][0]): void {\n console.log(` ${chalk.bold(result.extensionId)} v${result.version}`);\n console.log(` Publisher: ${result.metadata.publisher.name}`);\n console.log(` Trust Score: ${result.trustScore}/100`);\n\n if (result.findings.length > 0) {\n for (const finding of result.findings.slice(0, 3)) {\n const icon = finding.severity === 'critical' ? 'CRIT' : finding.severity.toUpperCase();\n console.log(` โ”‚ ${icon} ${finding.title}`);\n if (finding.evidence.filePath) {\n console.log(\n ` โ”‚ at ${finding.evidence.filePath}:${finding.evidence.lineNumber ?? '?'}`\n );\n }\n // Show remediation tip if available\n if (finding.remediation) {\n console.log(chalk.dim(` โ”‚ ${icons.info()} ${finding.remediation}`));\n }\n }\n if (result.findings.length > 3) {\n console.log(chalk.dim(` โ”‚ ... and ${result.findings.length - 3} more findings`));\n }\n }\n console.log();\n}\n\n/**\n * Print audit results with violations grouped by action level.\n */\nfunction printAuditResults(violations: PolicyViolation[], failOnLevel: PolicyAction): void {\n console.log();\n console.log(chalk.bold('Policy Audit Results'));\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log();\n\n if (violations.length === 0) {\n console.log(chalk.green('No policy violations found.'));\n console.log();\n return;\n }\n\n const blocked = violations.filter((v) => v.action === 'block');\n const warned = violations.filter((v) => v.action === 'warn');\n const info = violations.filter((v) => v.action === 'info');\n\n if (blocked.length > 0) {\n console.log(chalk.red.bold(`BLOCKED (${blocked.length})`));\n for (const v of blocked) {\n console.log(` ${chalk.red('x')} ${chalk.bold(v.extensionId)}`);\n console.log(` Rule: ${v.rule}`);\n console.log(` ${v.message}`);\n }\n console.log();\n }\n\n if (warned.length > 0) {\n console.log(chalk.yellow.bold(`WARNINGS (${warned.length})`));\n for (const v of warned) {\n console.log(` ${chalk.yellow('!')} ${chalk.bold(v.extensionId)}`);\n console.log(` Rule: ${v.rule}`);\n console.log(` ${v.message}`);\n }\n console.log();\n }\n\n if (info.length > 0) {\n console.log(chalk.blue.bold(`INFO (${info.length})`));\n for (const v of info) {\n console.log(` ${chalk.blue('i')} ${chalk.bold(v.extensionId)}`);\n console.log(` Rule: ${v.rule}`);\n console.log(` ${v.message}`);\n }\n console.log();\n }\n\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log();\n\n const total = violations.length;\n const willFail = hasViolationsAtLevel(violations, failOnLevel);\n\n console.log(\n `Total: ${total} violation${total !== 1 ? 's' : ''} ` +\n `(${blocked.length} blocked, ${warned.length} warnings, ${info.length} info)`\n );\n console.log(`Fail-on level: ${failOnLevel}`);\n\n if (willFail) {\n console.log(chalk.red(`Status: FAILED - violations found at or above '${failOnLevel}' level`));\n } else {\n console.log(chalk.green(`Status: PASSED - no violations at or above '${failOnLevel}' level`));\n }\n console.log();\n}\n\n/**\n * Check if there are violations at or above the specified level.\n * Level hierarchy: block > warn > info\n */\nfunction hasViolationsAtLevel(violations: PolicyViolation[], level: PolicyAction): boolean {\n const levelHierarchy: Record<PolicyAction, number> = {\n block: 3,\n warn: 2,\n info: 1,\n };\n\n const threshold = levelHierarchy[level];\n\n return violations.some((v) => levelHierarchy[v.action] >= threshold);\n}\n","import { createCli } from './cli.js';\n\nconst cli = createCli();\ncli.parse();\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport * as fs from 'node:fs';\nimport {\n ExtensionGuardScanner,\n VERSION,\n JsonReporter,\n SarifReporter,\n MarkdownReporter,\n loadPolicyConfig,\n PolicyEngine,\n DETECTION_RULES,\n detectIDEPaths,\n readExtensionsFromDirectory,\n collectFiles,\n createHashRecord,\n saveHashDatabase,\n loadHashDatabase,\n getDefaultDatabasePath,\n} from '@aspect-guard/core';\nimport type {\n FullScanReport,\n Reporter,\n PolicyViolation,\n PolicyAction,\n ExtensionHash,\n} from '@aspect-guard/core';\n\n// CLI output configuration\ninterface OutputConfig {\n color: boolean;\n emoji: boolean;\n}\n\nlet outputConfig: OutputConfig = {\n color: true,\n emoji: true,\n};\n\n// Emoji/text mappings\nconst icons = {\n shield: () => (outputConfig.emoji ? '๐Ÿ›ก๏ธ' : '[GUARD]'),\n folder: () => (outputConfig.emoji ? '๐Ÿ“' : '[DIR]'),\n critical: () => (outputConfig.emoji ? 'โ›”' : '[!!!]'),\n high: () => (outputConfig.emoji ? '๐Ÿ”ด' : '[!!]'),\n medium: () => (outputConfig.emoji ? '๐ŸŸก' : '[!]'),\n safe: () => (outputConfig.emoji ? '๐ŸŸข' : '[OK]'),\n summary: () => (outputConfig.emoji ? '๐Ÿ“Š' : '[SUM]'),\n time: () => (outputConfig.emoji ? 'โฑ๏ธ' : '[TIME]'),\n check: () => (outputConfig.emoji ? 'โœ“' : '[v]'),\n cross: () => (outputConfig.emoji ? 'โœ—' : '[x]'),\n info: () => (outputConfig.emoji ? 'โ„น' : '[i]'),\n};\n\nexport function createCli(): Command {\n const program = new Command();\n\n program\n .name('extension-guard')\n .description('Scan VSCode extensions for security issues')\n .version(VERSION)\n .option('--no-color', 'Disable colored output')\n .option('--no-emoji', 'Disable emoji output')\n .hook('preAction', (thisCommand) => {\n const opts = thisCommand.opts();\n outputConfig.color = opts.color !== false;\n outputConfig.emoji = opts.emoji !== false;\n if (!outputConfig.color) {\n chalk.level = 0;\n }\n });\n\n // Init command - create policy configuration file\n program\n .command('init')\n .description('Create a new .extension-guard.json policy configuration file')\n .option('-f, --force', 'Overwrite existing configuration file')\n .option('-o, --output <path>', 'Output path for configuration file', '.extension-guard.json')\n .action((options) => {\n const configPath = options.output;\n\n if (fs.existsSync(configPath) && !options.force) {\n console.error(chalk.red(`Error: ${configPath} already exists.`));\n console.error(chalk.dim('Use --force to overwrite.'));\n process.exit(2);\n }\n\n const template = {\n $schema:\n 'https://raw.githubusercontent.com/astroicers/extension-guard/main/schemas/policy.schema.json',\n version: '1.0',\n policy: {\n allowlist: [],\n blocklist: [],\n rules: {\n minTrustScore: {\n enabled: true,\n threshold: 60,\n action: 'warn',\n },\n blockObfuscated: {\n enabled: false,\n action: 'info',\n },\n requireVerifiedPublisher: {\n enabled: false,\n action: 'info',\n },\n },\n },\n scanning: {\n minSeverity: 'info',\n includeDevDependencies: false,\n },\n };\n\n fs.writeFileSync(configPath, JSON.stringify(template, null, 2) + '\\n');\n console.log(chalk.green(`${icons.check()} Created ${configPath}`));\n console.log();\n console.log('Next steps:');\n console.log(` 1. Edit ${chalk.cyan(configPath)} to customize your policy`);\n console.log(` 2. Run ${chalk.cyan('extension-guard audit')} to check your extensions`);\n console.log();\n });\n\n // Rules command - list available detection rules\n program\n .command('rules')\n .description('List available detection rules')\n .option('--details <ruleId>', 'Show detailed information for a specific rule')\n .action((options) => {\n if (options.details) {\n const rule = DETECTION_RULES.find((r) => r.id === options.details);\n if (!rule) {\n console.error(chalk.red(`Error: Rule '${options.details}' not found.`));\n console.log(chalk.dim('Run `extension-guard rules` to see available rules.'));\n process.exit(1);\n }\n\n console.log();\n console.log(chalk.bold(rule.id));\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log(`Name: ${rule.name}`);\n console.log(`Severity: ${formatSeverity(rule.severity)}`);\n console.log(`Category: ${rule.category}`);\n console.log(`Description: ${rule.description}`);\n if (rule.mitreAttackId) {\n console.log(`MITRE ATT&CK: ${rule.mitreAttackId}`);\n }\n console.log();\n return;\n }\n\n console.log();\n console.log(chalk.bold('Available Detection Rules'));\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log();\n\n const rulesBySeverity: Record<string, typeof DETECTION_RULES> = {};\n for (const rule of DETECTION_RULES) {\n if (!rulesBySeverity[rule.severity]) {\n rulesBySeverity[rule.severity] = [];\n }\n rulesBySeverity[rule.severity]!.push(rule);\n }\n\n const severityOrder = ['critical', 'high', 'medium', 'low', 'info'];\n for (const severity of severityOrder) {\n const rules = rulesBySeverity[severity];\n if (rules && rules.length > 0) {\n console.log(formatSeverity(severity));\n for (const rule of rules) {\n console.log(` ${chalk.cyan(rule.id.padEnd(14))} ${rule.name}`);\n }\n console.log();\n }\n }\n\n console.log(\n chalk.dim('Run `extension-guard rules --details <ruleId>` for more information.')\n );\n console.log();\n });\n\n // Baseline command - generate hash database from installed extensions\n program\n .command('baseline')\n .description(\n 'Generate integrity hash database from currently installed extensions\\n\\n' +\n 'This creates a baseline of known-good hashes that can be used to detect\\n' +\n 'tampering or supply chain attacks on trusted extensions.\\n\\n' +\n 'Examples:\\n' +\n ' extension-guard baseline Generate baseline from all IDEs\\n' +\n ' extension-guard baseline -o hashes.json Output to custom file\\n' +\n ' extension-guard baseline --append Add to existing database'\n )\n .option('-p, --path <paths...>', 'Custom extension paths to scan')\n .option('-o, --output <file>', 'Output path for hash database')\n .option('--append', 'Append to existing database instead of overwriting')\n .option('-q, --quiet', 'Only show results, no progress')\n .action(async (options) => {\n const spinner = options.quiet ? null : ora('Generating integrity baseline...').start();\n\n try {\n // Detect IDE paths\n let idePaths: string[];\n if (options.path && options.path.length > 0) {\n idePaths = options.path;\n } else {\n const ides = detectIDEPaths();\n idePaths = ides.map((ide) => ide.path);\n }\n\n if (idePaths.length === 0) {\n if (spinner) spinner.fail('No extension directories found');\n console.error(chalk.red('Error: No IDE extension directories detected.'));\n console.error(chalk.dim('Use --path to specify custom paths.'));\n process.exit(3);\n }\n\n // Load existing database if appending\n let hashes: Map<string, ExtensionHash>;\n const outputPath = options.output || getDefaultDatabasePath();\n if (options.append) {\n hashes = loadHashDatabase(outputPath);\n } else {\n hashes = new Map();\n }\n\n // Collect hashes from all extensions\n let processed = 0;\n let errors = 0;\n\n for (const idePath of idePaths) {\n if (spinner) spinner.text = `Processing ${idePath}...`;\n\n try {\n const extensions = await readExtensionsFromDirectory(idePath);\n\n for (const ext of extensions) {\n try {\n const files = await collectFiles(ext.installPath);\n const record = createHashRecord(ext.id, ext.version, files, 'manual');\n hashes.set(`${ext.id}@${ext.version}`, record);\n processed++;\n } catch {\n errors++;\n }\n }\n } catch {\n errors++;\n }\n }\n\n // Save database\n saveHashDatabase(hashes, outputPath);\n\n if (spinner) spinner.succeed('Baseline generated');\n\n console.log();\n console.log(chalk.bold('Integrity Baseline Generated'));\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log(`${icons.check()} Processed: ${chalk.green(processed)} extensions`);\n if (errors > 0) {\n console.log(`${icons.cross()} Errors: ${chalk.yellow(errors)}`);\n }\n console.log(`${icons.folder()} Database: ${chalk.cyan(outputPath)}`);\n console.log();\n console.log('Usage:');\n console.log(` ${chalk.cyan('extension-guard scan --verify-integrity')}`);\n if (options.output) {\n console.log(\n ` ${chalk.cyan(`extension-guard scan --verify-integrity --hash-db ${outputPath}`)}`\n );\n }\n console.log();\n } catch (error) {\n if (spinner) spinner.fail('Baseline generation failed');\n console.error(chalk.red('Error:'), error instanceof Error ? error.message : error);\n process.exit(3);\n }\n });\n\n program\n .command('scan')\n .description(\n 'Scan installed VSCode extensions\\n\\n' +\n 'Examples:\\n' +\n ' extension-guard scan Scan all detected IDEs\\n' +\n ' extension-guard scan --ide cursor Scan Cursor IDE only\\n' +\n ' extension-guard scan --format json -o r.json Output as JSON file\\n' +\n ' extension-guard scan --format sarif Output for GitHub Code Scanning'\n )\n .option('-p, --path <paths...>', 'Custom extension paths to scan')\n .option('-f, --format <format>', 'Output format (table|json|sarif|markdown)', 'table')\n .option('-o, --output <file>', 'Output file path (default: stdout)')\n .option('-s, --severity <level>', 'Minimum severity to show', 'info')\n .option('-q, --quiet', 'Only show results, no progress')\n .option('--include-safe', 'Include safe extensions in output')\n .option('--verify-integrity', 'Verify extension integrity against known-good hashes')\n .option('--hash-db <path>', 'Path to custom hash database file')\n .action(async (options) => {\n const isJsonOutput = options.format === 'json' || options.format === 'sarif';\n const spinner = options.quiet || isJsonOutput ? null : ora('Scanning extensions...').start();\n\n try {\n const scanner = new ExtensionGuardScanner({\n autoDetect: !options.path,\n idePaths: options.path ?? [],\n severity: options.severity,\n verifyIntegrity: options.verifyIntegrity ?? false,\n hashDatabasePath: options.hashDb,\n });\n\n const report = await scanner.scan();\n\n if (spinner) {\n spinner.succeed('Scan complete');\n }\n\n // Generate output based on format\n const output = generateOutput(report, options.format, {\n includeSafe: options.includeSafe,\n });\n\n // Write to file or stdout\n if (options.output) {\n fs.writeFileSync(options.output, output);\n if (!options.quiet) {\n console.log(chalk.green(`Report saved to ${options.output}`));\n }\n } else if (options.format === 'table') {\n printTableReport(report);\n } else {\n console.log(output);\n }\n\n // Exit with error code if critical or high issues found\n const hasCritical = report.summary.bySeverity.critical > 0;\n const hasHigh = report.summary.bySeverity.high > 0;\n if (hasCritical || hasHigh) {\n process.exit(1);\n }\n } catch (error) {\n if (spinner) {\n spinner.fail('Scan failed');\n }\n console.error(chalk.red('Error:'), error instanceof Error ? error.message : error);\n process.exit(3);\n }\n });\n\n program\n .command('audit')\n .description('Audit extensions against policy rules')\n .option('-c, --config <path>', 'Path to policy config file', '.extension-guard.json')\n .option('-p, --path <paths...>', 'Custom extension paths to scan')\n .option('--fail-on <level>', 'Fail on violations at or above level (block|warn|info)', 'block')\n .option('-f, --format <format>', 'Output format (table|json|sarif|markdown)', 'table')\n .option('-o, --output <file>', 'Output file path (default: stdout)')\n .option('-q, --quiet', 'Only show results, no progress')\n .action(async (options) => {\n const isJsonOutput = options.format === 'json' || options.format === 'sarif';\n const spinner =\n options.quiet || isJsonOutput ? null : ora('Loading policy configuration...').start();\n\n try {\n // Load policy configuration\n const policyConfig = await loadPolicyConfig(options.config);\n\n if (!policyConfig) {\n if (spinner) {\n spinner.fail('Policy configuration not found');\n }\n console.error(chalk.red(`Error: Could not find policy config at ${options.config}`));\n console.error(\n chalk.dim('Create a .extension-guard.json file or specify a path with --config')\n );\n process.exit(2);\n }\n\n if (spinner) {\n spinner.text = 'Scanning extensions...';\n }\n\n // Run scan with config-based settings\n const scanner = new ExtensionGuardScanner({\n autoDetect: !options.path,\n idePaths: options.path ?? [],\n severity: policyConfig.scanning?.minSeverity ?? 'info',\n });\n\n const report = await scanner.scan();\n\n if (spinner) {\n spinner.text = 'Evaluating policy rules...';\n }\n\n // Evaluate policy\n const engine = new PolicyEngine(policyConfig);\n const violations = engine.evaluate(report.results);\n\n if (spinner) {\n spinner.succeed('Audit complete');\n }\n\n // Generate output based on format\n if (options.format !== 'table') {\n const output = generateOutput(report, options.format, {\n includeSafe: false,\n });\n if (options.output) {\n fs.writeFileSync(options.output, output);\n if (!options.quiet) {\n console.log(chalk.green(`Report saved to ${options.output}`));\n }\n } else {\n console.log(output);\n }\n }\n\n // Print violations summary\n printAuditResults(violations, options.failOn as PolicyAction);\n\n // Determine exit code based on --fail-on level\n const shouldFail = hasViolationsAtLevel(violations, options.failOn as PolicyAction);\n if (shouldFail) {\n process.exit(1);\n }\n } catch (error) {\n if (spinner) {\n spinner.fail('Audit failed');\n }\n console.error(chalk.red('Error:'), error instanceof Error ? error.message : error);\n process.exit(3);\n }\n });\n\n return program;\n}\n\nfunction generateOutput(\n report: FullScanReport,\n format: string,\n options: { includeSafe?: boolean } = {}\n): string {\n let reporter: Reporter;\n\n switch (format) {\n case 'json':\n reporter = new JsonReporter();\n break;\n case 'sarif':\n reporter = new SarifReporter();\n break;\n case 'markdown':\n reporter = new MarkdownReporter();\n break;\n case 'table':\n default:\n // Table format is handled separately\n return '';\n }\n\n return reporter.generate(report, {\n includeSafe: options.includeSafe,\n includeEvidence: true,\n });\n}\n\nfunction printTableReport(report: FullScanReport): void {\n console.log();\n console.log(chalk.bold(`${icons.shield()} Extension Guard v${VERSION}`));\n console.log();\n\n for (const ide of report.environment.ides) {\n console.log(\n `${icons.folder()} ${chalk.cyan(ide.name)}: ${ide.path} (${ide.extensionCount} extensions)`\n );\n }\n\n console.log();\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log();\n\n const critical = report.results.filter((r) => r.riskLevel === 'critical');\n const high = report.results.filter((r) => r.riskLevel === 'high');\n const medium = report.results.filter((r) => r.riskLevel === 'medium');\n const safe = report.results.filter((r) => r.riskLevel === 'safe' || r.riskLevel === 'low');\n\n if (critical.length > 0) {\n console.log(chalk.red.bold(`${icons.critical()} CRITICAL (${critical.length})`));\n for (const ext of critical) {\n printExtensionResult(ext);\n }\n }\n\n if (high.length > 0) {\n console.log(chalk.red(`${icons.high()} HIGH (${high.length})`));\n for (const ext of high) {\n printExtensionResult(ext);\n }\n }\n\n if (medium.length > 0) {\n console.log(chalk.yellow(`${icons.medium()} MEDIUM (${medium.length})`));\n for (const ext of medium) {\n console.log(` ${ext.extensionId} (Trust: ${ext.trustScore}/100)`);\n }\n console.log();\n }\n\n if (safe.length > 0) {\n console.log(chalk.green(`${icons.safe()} SAFE (${safe.length})`));\n }\n\n console.log();\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log();\n\n const { bySeverity, byRiskLevel } = report.summary;\n console.log(\n `${icons.summary()} Summary: ${report.uniqueExtensions} scanned ยท ` +\n `${bySeverity.critical} critical ยท ${bySeverity.high} high ยท ` +\n `${bySeverity.medium} medium ยท ${byRiskLevel.safe} safe`\n );\n console.log(`${icons.time()} Completed in ${(report.scanDurationMs / 1000).toFixed(1)}s`);\n console.log();\n}\n\nfunction formatSeverity(severity: string): string {\n switch (severity) {\n case 'critical':\n return chalk.red.bold('CRITICAL');\n case 'high':\n return chalk.red('HIGH');\n case 'medium':\n return chalk.yellow('MEDIUM');\n case 'low':\n return chalk.blue('LOW');\n case 'info':\n return chalk.dim('INFO');\n default:\n return severity;\n }\n}\n\nfunction printExtensionResult(result: FullScanReport['results'][0]): void {\n console.log(` ${chalk.bold(result.extensionId)} v${result.version}`);\n console.log(` Publisher: ${result.metadata.publisher.name}`);\n console.log(` Trust Score: ${result.trustScore}/100`);\n\n if (result.findings.length > 0) {\n for (const finding of result.findings.slice(0, 3)) {\n const icon = finding.severity === 'critical' ? 'CRIT' : finding.severity.toUpperCase();\n console.log(` โ”‚ ${icon} ${finding.title}`);\n if (finding.evidence.filePath) {\n console.log(\n ` โ”‚ at ${finding.evidence.filePath}:${finding.evidence.lineNumber ?? '?'}`\n );\n }\n // Show remediation tip if available\n if (finding.remediation) {\n console.log(chalk.dim(` โ”‚ ${icons.info()} ${finding.remediation}`));\n }\n }\n if (result.findings.length > 3) {\n console.log(chalk.dim(` โ”‚ ... and ${result.findings.length - 3} more findings`));\n }\n }\n console.log();\n}\n\n/**\n * Print audit results with violations grouped by action level.\n */\nfunction printAuditResults(violations: PolicyViolation[], failOnLevel: PolicyAction): void {\n console.log();\n console.log(chalk.bold('Policy Audit Results'));\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log();\n\n if (violations.length === 0) {\n console.log(chalk.green('No policy violations found.'));\n console.log();\n return;\n }\n\n const blocked = violations.filter((v) => v.action === 'block');\n const warned = violations.filter((v) => v.action === 'warn');\n const info = violations.filter((v) => v.action === 'info');\n\n if (blocked.length > 0) {\n console.log(chalk.red.bold(`BLOCKED (${blocked.length})`));\n for (const v of blocked) {\n console.log(` ${chalk.red('x')} ${chalk.bold(v.extensionId)}`);\n console.log(` Rule: ${v.rule}`);\n console.log(` ${v.message}`);\n }\n console.log();\n }\n\n if (warned.length > 0) {\n console.log(chalk.yellow.bold(`WARNINGS (${warned.length})`));\n for (const v of warned) {\n console.log(` ${chalk.yellow('!')} ${chalk.bold(v.extensionId)}`);\n console.log(` Rule: ${v.rule}`);\n console.log(` ${v.message}`);\n }\n console.log();\n }\n\n if (info.length > 0) {\n console.log(chalk.blue.bold(`INFO (${info.length})`));\n for (const v of info) {\n console.log(` ${chalk.blue('i')} ${chalk.bold(v.extensionId)}`);\n console.log(` Rule: ${v.rule}`);\n console.log(` ${v.message}`);\n }\n console.log();\n }\n\n console.log(chalk.dim('โ”'.repeat(60)));\n console.log();\n\n const total = violations.length;\n const willFail = hasViolationsAtLevel(violations, failOnLevel);\n\n console.log(\n `Total: ${total} violation${total !== 1 ? 's' : ''} ` +\n `(${blocked.length} blocked, ${warned.length} warnings, ${info.length} info)`\n );\n console.log(`Fail-on level: ${failOnLevel}`);\n\n if (willFail) {\n console.log(chalk.red(`Status: FAILED - violations found at or above '${failOnLevel}' level`));\n } else {\n console.log(chalk.green(`Status: PASSED - no violations at or above '${failOnLevel}' level`));\n }\n console.log();\n}\n\n/**\n * Check if there are violations at or above the specified level.\n * Level hierarchy: block > warn > info\n */\nfunction hasViolationsAtLevel(violations: PolicyViolation[], level: PolicyAction): boolean {\n const levelHierarchy: Record<PolicyAction, number> = {\n block: 3,\n warn: 2,\n info: 1,\n };\n\n const threshold = levelHierarchy[level];\n\n return violations.some((v) => levelHierarchy[v.action] >= threshold);\n}\n","import { createCli } from './cli.js';\n\nconst cli = createCli();\ncli.parse();\n"],"mappings":";;;AAAA,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,OAAO,SAAS;AAChB,YAAY,QAAQ;AACpB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAeP,IAAI,eAA6B;AAAA,EAC/B,OAAO;AAAA,EACP,OAAO;AACT;AAGA,IAAM,QAAQ;AAAA,EACZ,QAAQ,MAAO,aAAa,QAAQ,oBAAQ;AAAA,EAC5C,QAAQ,MAAO,aAAa,QAAQ,cAAO;AAAA,EAC3C,UAAU,MAAO,aAAa,QAAQ,WAAM;AAAA,EAC5C,MAAM,MAAO,aAAa,QAAQ,cAAO;AAAA,EACzC,QAAQ,MAAO,aAAa,QAAQ,cAAO;AAAA,EAC3C,MAAM,MAAO,aAAa,QAAQ,cAAO;AAAA,EACzC,SAAS,MAAO,aAAa,QAAQ,cAAO;AAAA,EAC5C,MAAM,MAAO,aAAa,QAAQ,iBAAO;AAAA,EACzC,OAAO,MAAO,aAAa,QAAQ,WAAM;AAAA,EACzC,OAAO,MAAO,aAAa,QAAQ,WAAM;AAAA,EACzC,MAAM,MAAO,aAAa,QAAQ,WAAM;AAC1C;AAEO,SAAS,YAAqB;AACnC,QAAM,UAAU,IAAI,QAAQ;AAE5B,UACG,KAAK,iBAAiB,EACtB,YAAY,4CAA4C,EACxD,QAAQ,OAAO,EACf,OAAO,cAAc,wBAAwB,EAC7C,OAAO,cAAc,sBAAsB,EAC3C,KAAK,aAAa,CAAC,gBAAgB;AAClC,UAAM,OAAO,YAAY,KAAK;AAC9B,iBAAa,QAAQ,KAAK,UAAU;AACpC,iBAAa,QAAQ,KAAK,UAAU;AACpC,QAAI,CAAC,aAAa,OAAO;AACvB,YAAM,QAAQ;AAAA,IAChB;AAAA,EACF,CAAC;AAGH,UACG,QAAQ,MAAM,EACd,YAAY,8DAA8D,EAC1E,OAAO,eAAe,uCAAuC,EAC7D,OAAO,uBAAuB,sCAAsC,uBAAuB,EAC3F,OAAO,CAAC,YAAY;AACnB,UAAM,aAAa,QAAQ;AAE3B,QAAO,cAAW,UAAU,KAAK,CAAC,QAAQ,OAAO;AAC/C,cAAQ,MAAM,MAAM,IAAI,UAAU,UAAU,kBAAkB,CAAC;AAC/D,cAAQ,MAAM,MAAM,IAAI,2BAA2B,CAAC;AACpD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,WAAW;AAAA,MACf,SACE;AAAA,MACF,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,WAAW,CAAC;AAAA,QACZ,WAAW,CAAC;AAAA,QACZ,OAAO;AAAA,UACL,eAAe;AAAA,YACb,SAAS;AAAA,YACT,WAAW;AAAA,YACX,QAAQ;AAAA,UACV;AAAA,UACA,iBAAiB;AAAA,YACf,SAAS;AAAA,YACT,QAAQ;AAAA,UACV;AAAA,UACA,0BAA0B;AAAA,YACxB,SAAS;AAAA,YACT,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAAA,MACA,UAAU;AAAA,QACR,aAAa;AAAA,QACb,wBAAwB;AAAA,MAC1B;AAAA,IACF;AAEA,IAAG,iBAAc,YAAY,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI,IAAI;AACrE,YAAQ,IAAI,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,UAAU,EAAE,CAAC;AACjE,YAAQ,IAAI;AACZ,YAAQ,IAAI,aAAa;AACzB,YAAQ,IAAI,aAAa,MAAM,KAAK,UAAU,CAAC,2BAA2B;AAC1E,YAAQ,IAAI,YAAY,MAAM,KAAK,uBAAuB,CAAC,2BAA2B;AACtF,YAAQ,IAAI;AAAA,EACd,CAAC;AAGH,UACG,QAAQ,OAAO,EACf,YAAY,gCAAgC,EAC5C,OAAO,sBAAsB,+CAA+C,EAC5E,OAAO,CAAC,YAAY;AACnB,QAAI,QAAQ,SAAS;AACnB,YAAM,OAAO,gBAAgB,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,OAAO;AACjE,UAAI,CAAC,MAAM;AACT,gBAAQ,MAAM,MAAM,IAAI,gBAAgB,QAAQ,OAAO,cAAc,CAAC;AACtE,gBAAQ,IAAI,MAAM,IAAI,qDAAqD,CAAC;AAC5E,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,cAAQ,IAAI;AACZ,cAAQ,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;AAC/B,cAAQ,IAAI,MAAM,IAAI,SAAI,OAAO,EAAE,CAAC,CAAC;AACrC,cAAQ,IAAI,gBAAgB,KAAK,IAAI,EAAE;AACvC,cAAQ,IAAI,gBAAgB,eAAe,KAAK,QAAQ,CAAC,EAAE;AAC3D,cAAQ,IAAI,gBAAgB,KAAK,QAAQ,EAAE;AAC3C,cAAQ,IAAI,gBAAgB,KAAK,WAAW,EAAE;AAC9C,UAAI,KAAK,eAAe;AACtB,gBAAQ,IAAI,iBAAiB,KAAK,aAAa,EAAE;AAAA,MACnD;AACA,cAAQ,IAAI;AACZ;AAAA,IACF;AAEA,YAAQ,IAAI;AACZ,YAAQ,IAAI,MAAM,KAAK,2BAA2B,CAAC;AACnD,YAAQ,IAAI,MAAM,IAAI,SAAI,OAAO,EAAE,CAAC,CAAC;AACrC,YAAQ,IAAI;AAEZ,UAAM,kBAA0D,CAAC;AACjE,eAAW,QAAQ,iBAAiB;AAClC,UAAI,CAAC,gBAAgB,KAAK,QAAQ,GAAG;AACnC,wBAAgB,KAAK,QAAQ,IAAI,CAAC;AAAA,MACpC;AACA,sBAAgB,KAAK,QAAQ,EAAG,KAAK,IAAI;AAAA,IAC3C;AAEA,UAAM,gBAAgB,CAAC,YAAY,QAAQ,UAAU,OAAO,MAAM;AAClE,eAAW,YAAY,eAAe;AACpC,YAAM,QAAQ,gBAAgB,QAAQ;AACtC,UAAI,SAAS,MAAM,SAAS,GAAG;AAC7B,gBAAQ,IAAI,eAAe,QAAQ,CAAC;AACpC,mBAAW,QAAQ,OAAO;AACxB,kBAAQ,IAAI,KAAK,MAAM,KAAK,KAAK,GAAG,OAAO,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE;AAAA,QAChE;AACA,gBAAQ,IAAI;AAAA,MACd;AAAA,IACF;AAEA,YAAQ;AAAA,MACN,MAAM,IAAI,sEAAsE;AAAA,IAClF;AACA,YAAQ,IAAI;AAAA,EACd,CAAC;AAGH,UACG,QAAQ,UAAU,EAClB;AAAA,IACC;AAAA,EAOF,EACC,OAAO,yBAAyB,gCAAgC,EAChE,OAAO,uBAAuB,+BAA+B,EAC7D,OAAO,YAAY,oDAAoD,EACvE,OAAO,eAAe,gCAAgC,EACtD,OAAO,OAAO,YAAY;AACzB,UAAM,UAAU,QAAQ,QAAQ,OAAO,IAAI,kCAAkC,EAAE,MAAM;AAErF,QAAI;AAEF,UAAI;AACJ,UAAI,QAAQ,QAAQ,QAAQ,KAAK,SAAS,GAAG;AAC3C,mBAAW,QAAQ;AAAA,MACrB,OAAO;AACL,cAAM,OAAO,eAAe;AAC5B,mBAAW,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI;AAAA,MACvC;AAEA,UAAI,SAAS,WAAW,GAAG;AACzB,YAAI,QAAS,SAAQ,KAAK,gCAAgC;AAC1D,gBAAQ,MAAM,MAAM,IAAI,+CAA+C,CAAC;AACxE,gBAAQ,MAAM,MAAM,IAAI,qCAAqC,CAAC;AAC9D,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAGA,UAAI;AACJ,YAAM,aAAa,QAAQ,UAAU,uBAAuB;AAC5D,UAAI,QAAQ,QAAQ;AAClB,iBAAS,iBAAiB,UAAU;AAAA,MACtC,OAAO;AACL,iBAAS,oBAAI,IAAI;AAAA,MACnB;AAGA,UAAI,YAAY;AAChB,UAAI,SAAS;AAEb,iBAAW,WAAW,UAAU;AAC9B,YAAI,QAAS,SAAQ,OAAO,cAAc,OAAO;AAEjD,YAAI;AACF,gBAAM,aAAa,MAAM,4BAA4B,OAAO;AAE5D,qBAAW,OAAO,YAAY;AAC5B,gBAAI;AACF,oBAAM,QAAQ,MAAM,aAAa,IAAI,WAAW;AAChD,oBAAM,SAAS,iBAAiB,IAAI,IAAI,IAAI,SAAS,OAAO,QAAQ;AACpE,qBAAO,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,OAAO,IAAI,MAAM;AAC7C;AAAA,YACF,QAAQ;AACN;AAAA,YACF;AAAA,UACF;AAAA,QACF,QAAQ;AACN;AAAA,QACF;AAAA,MACF;AAGA,uBAAiB,QAAQ,UAAU;AAEnC,UAAI,QAAS,SAAQ,QAAQ,oBAAoB;AAEjD,cAAQ,IAAI;AACZ,cAAQ,IAAI,MAAM,KAAK,8BAA8B,CAAC;AACtD,cAAQ,IAAI,MAAM,IAAI,SAAI,OAAO,EAAE,CAAC,CAAC;AACrC,cAAQ,IAAI,GAAG,MAAM,MAAM,CAAC,eAAe,MAAM,MAAM,SAAS,CAAC,aAAa;AAC9E,UAAI,SAAS,GAAG;AACd,gBAAQ,IAAI,GAAG,MAAM,MAAM,CAAC,YAAY,MAAM,OAAO,MAAM,CAAC,EAAE;AAAA,MAChE;AACA,cAAQ,IAAI,GAAG,MAAM,OAAO,CAAC,cAAc,MAAM,KAAK,UAAU,CAAC,EAAE;AACnE,cAAQ,IAAI;AACZ,cAAQ,IAAI,QAAQ;AACpB,cAAQ,IAAI,KAAK,MAAM,KAAK,yCAAyC,CAAC,EAAE;AACxE,UAAI,QAAQ,QAAQ;AAClB,gBAAQ;AAAA,UACN,KAAK,MAAM,KAAK,qDAAqD,UAAU,EAAE,CAAC;AAAA,QACpF;AAAA,MACF;AACA,cAAQ,IAAI;AAAA,IACd,SAAS,OAAO;AACd,UAAI,QAAS,SAAQ,KAAK,4BAA4B;AACtD,cAAQ,MAAM,MAAM,IAAI,QAAQ,GAAG,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AACjF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,MAAM,EACd;AAAA,IACC;AAAA,EAMF,EACC,OAAO,yBAAyB,gCAAgC,EAChE,OAAO,yBAAyB,6CAA6C,OAAO,EACpF,OAAO,uBAAuB,oCAAoC,EAClE,OAAO,0BAA0B,4BAA4B,MAAM,EACnE,OAAO,eAAe,gCAAgC,EACtD,OAAO,kBAAkB,mCAAmC,EAC5D,OAAO,sBAAsB,sDAAsD,EACnF,OAAO,oBAAoB,mCAAmC,EAC9D,OAAO,OAAO,YAAY;AACzB,UAAM,eAAe,QAAQ,WAAW,UAAU,QAAQ,WAAW;AACrE,UAAM,UAAU,QAAQ,SAAS,eAAe,OAAO,IAAI,wBAAwB,EAAE,MAAM;AAE3F,QAAI;AACF,YAAM,UAAU,IAAI,sBAAsB;AAAA,QACxC,YAAY,CAAC,QAAQ;AAAA,QACrB,UAAU,QAAQ,QAAQ,CAAC;AAAA,QAC3B,UAAU,QAAQ;AAAA,QAClB,iBAAiB,QAAQ,mBAAmB;AAAA,QAC5C,kBAAkB,QAAQ;AAAA,MAC5B,CAAC;AAED,YAAM,SAAS,MAAM,QAAQ,KAAK;AAElC,UAAI,SAAS;AACX,gBAAQ,QAAQ,eAAe;AAAA,MACjC;AAGA,YAAM,SAAS,eAAe,QAAQ,QAAQ,QAAQ;AAAA,QACpD,aAAa,QAAQ;AAAA,MACvB,CAAC;AAGD,UAAI,QAAQ,QAAQ;AAClB,QAAG,iBAAc,QAAQ,QAAQ,MAAM;AACvC,YAAI,CAAC,QAAQ,OAAO;AAClB,kBAAQ,IAAI,MAAM,MAAM,mBAAmB,QAAQ,MAAM,EAAE,CAAC;AAAA,QAC9D;AAAA,MACF,WAAW,QAAQ,WAAW,SAAS;AACrC,yBAAiB,MAAM;AAAA,MACzB,OAAO;AACL,gBAAQ,IAAI,MAAM;AAAA,MACpB;AAGA,YAAM,cAAc,OAAO,QAAQ,WAAW,WAAW;AACzD,YAAM,UAAU,OAAO,QAAQ,WAAW,OAAO;AACjD,UAAI,eAAe,SAAS;AAC1B,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,SAAS,OAAO;AACd,UAAI,SAAS;AACX,gBAAQ,KAAK,aAAa;AAAA,MAC5B;AACA,cAAQ,MAAM,MAAM,IAAI,QAAQ,GAAG,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AACjF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,OAAO,EACf,YAAY,uCAAuC,EACnD,OAAO,uBAAuB,8BAA8B,uBAAuB,EACnF,OAAO,yBAAyB,gCAAgC,EAChE,OAAO,qBAAqB,0DAA0D,OAAO,EAC7F,OAAO,yBAAyB,6CAA6C,OAAO,EACpF,OAAO,uBAAuB,oCAAoC,EAClE,OAAO,eAAe,gCAAgC,EACtD,OAAO,OAAO,YAAY;AACzB,UAAM,eAAe,QAAQ,WAAW,UAAU,QAAQ,WAAW;AACrE,UAAM,UACJ,QAAQ,SAAS,eAAe,OAAO,IAAI,iCAAiC,EAAE,MAAM;AAEtF,QAAI;AAEF,YAAM,eAAe,MAAM,iBAAiB,QAAQ,MAAM;AAE1D,UAAI,CAAC,cAAc;AACjB,YAAI,SAAS;AACX,kBAAQ,KAAK,gCAAgC;AAAA,QAC/C;AACA,gBAAQ,MAAM,MAAM,IAAI,0CAA0C,QAAQ,MAAM,EAAE,CAAC;AACnF,gBAAQ;AAAA,UACN,MAAM,IAAI,qEAAqE;AAAA,QACjF;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,UAAI,SAAS;AACX,gBAAQ,OAAO;AAAA,MACjB;AAGA,YAAM,UAAU,IAAI,sBAAsB;AAAA,QACxC,YAAY,CAAC,QAAQ;AAAA,QACrB,UAAU,QAAQ,QAAQ,CAAC;AAAA,QAC3B,UAAU,aAAa,UAAU,eAAe;AAAA,MAClD,CAAC;AAED,YAAM,SAAS,MAAM,QAAQ,KAAK;AAElC,UAAI,SAAS;AACX,gBAAQ,OAAO;AAAA,MACjB;AAGA,YAAM,SAAS,IAAI,aAAa,YAAY;AAC5C,YAAM,aAAa,OAAO,SAAS,OAAO,OAAO;AAEjD,UAAI,SAAS;AACX,gBAAQ,QAAQ,gBAAgB;AAAA,MAClC;AAGA,UAAI,QAAQ,WAAW,SAAS;AAC9B,cAAM,SAAS,eAAe,QAAQ,QAAQ,QAAQ;AAAA,UACpD,aAAa;AAAA,QACf,CAAC;AACD,YAAI,QAAQ,QAAQ;AAClB,UAAG,iBAAc,QAAQ,QAAQ,MAAM;AACvC,cAAI,CAAC,QAAQ,OAAO;AAClB,oBAAQ,IAAI,MAAM,MAAM,mBAAmB,QAAQ,MAAM,EAAE,CAAC;AAAA,UAC9D;AAAA,QACF,OAAO;AACL,kBAAQ,IAAI,MAAM;AAAA,QACpB;AAAA,MACF;AAGA,wBAAkB,YAAY,QAAQ,MAAsB;AAG5D,YAAM,aAAa,qBAAqB,YAAY,QAAQ,MAAsB;AAClF,UAAI,YAAY;AACd,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,SAAS,OAAO;AACd,UAAI,SAAS;AACX,gBAAQ,KAAK,cAAc;AAAA,MAC7B;AACA,cAAQ,MAAM,MAAM,IAAI,QAAQ,GAAG,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AACjF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,SAAO;AACT;AAEA,SAAS,eACP,QACA,QACA,UAAqC,CAAC,GAC9B;AACR,MAAI;AAEJ,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,iBAAW,IAAI,aAAa;AAC5B;AAAA,IACF,KAAK;AACH,iBAAW,IAAI,cAAc;AAC7B;AAAA,IACF,KAAK;AACH,iBAAW,IAAI,iBAAiB;AAChC;AAAA,IACF,KAAK;AAAA,IACL;AAEE,aAAO;AAAA,EACX;AAEA,SAAO,SAAS,SAAS,QAAQ;AAAA,IAC/B,aAAa,QAAQ;AAAA,IACrB,iBAAiB;AAAA,EACnB,CAAC;AACH;AAEA,SAAS,iBAAiB,QAA8B;AACtD,UAAQ,IAAI;AACZ,UAAQ,IAAI,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,sBAAsB,OAAO,EAAE,CAAC;AACxE,UAAQ,IAAI;AAEZ,aAAW,OAAO,OAAO,YAAY,MAAM;AACzC,YAAQ;AAAA,MACN,GAAG,MAAM,OAAO,CAAC,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,KAAK,IAAI,cAAc;AAAA,IAC/E;AAAA,EACF;AAEA,UAAQ,IAAI;AACZ,UAAQ,IAAI,MAAM,IAAI,SAAI,OAAO,EAAE,CAAC,CAAC;AACrC,UAAQ,IAAI;AAEZ,QAAM,WAAW,OAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,cAAc,UAAU;AACxE,QAAM,OAAO,OAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,cAAc,MAAM;AAChE,QAAM,SAAS,OAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,cAAc,QAAQ;AACpE,QAAM,OAAO,OAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,cAAc,UAAU,EAAE,cAAc,KAAK;AAEzF,MAAI,SAAS,SAAS,GAAG;AACvB,YAAQ,IAAI,MAAM,IAAI,KAAK,GAAG,MAAM,SAAS,CAAC,cAAc,SAAS,MAAM,GAAG,CAAC;AAC/E,eAAW,OAAO,UAAU;AAC1B,2BAAqB,GAAG;AAAA,IAC1B;AAAA,EACF;AAEA,MAAI,KAAK,SAAS,GAAG;AACnB,YAAQ,IAAI,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,UAAU,KAAK,MAAM,GAAG,CAAC;AAC9D,eAAW,OAAO,MAAM;AACtB,2BAAqB,GAAG;AAAA,IAC1B;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,YAAQ,IAAI,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,YAAY,OAAO,MAAM,GAAG,CAAC;AACvE,eAAW,OAAO,QAAQ;AACxB,cAAQ,IAAI,MAAM,IAAI,WAAW,YAAY,IAAI,UAAU,OAAO;AAAA,IACpE;AACA,YAAQ,IAAI;AAAA,EACd;AAEA,MAAI,KAAK,SAAS,GAAG;AACnB,YAAQ,IAAI,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,KAAK,MAAM,GAAG,CAAC;AAAA,EAClE;AAEA,UAAQ,IAAI;AACZ,UAAQ,IAAI,MAAM,IAAI,SAAI,OAAO,EAAE,CAAC,CAAC;AACrC,UAAQ,IAAI;AAEZ,QAAM,EAAE,YAAY,YAAY,IAAI,OAAO;AAC3C,UAAQ;AAAA,IACN,GAAG,MAAM,QAAQ,CAAC,aAAa,OAAO,gBAAgB,iBACjD,WAAW,QAAQ,kBAAe,WAAW,IAAI,cACjD,WAAW,MAAM,gBAAa,YAAY,IAAI;AAAA,EACrD;AACA,UAAQ,IAAI,GAAG,MAAM,KAAK,CAAC,mBAAmB,OAAO,iBAAiB,KAAM,QAAQ,CAAC,CAAC,GAAG;AACzF,UAAQ,IAAI;AACd;AAEA,SAAS,eAAe,UAA0B;AAChD,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,MAAM,IAAI,KAAK,UAAU;AAAA,IAClC,KAAK;AACH,aAAO,MAAM,IAAI,MAAM;AAAA,IACzB,KAAK;AACH,aAAO,MAAM,OAAO,QAAQ;AAAA,IAC9B,KAAK;AACH,aAAO,MAAM,KAAK,KAAK;AAAA,IACzB,KAAK;AACH,aAAO,MAAM,IAAI,MAAM;AAAA,IACzB;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,qBAAqB,QAA4C;AACxE,UAAQ,IAAI,MAAM,MAAM,KAAK,OAAO,WAAW,CAAC,KAAK,OAAO,OAAO,EAAE;AACrE,UAAQ,IAAI,iBAAiB,OAAO,SAAS,UAAU,IAAI,EAAE;AAC7D,UAAQ,IAAI,mBAAmB,OAAO,UAAU,MAAM;AAEtD,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,eAAW,WAAW,OAAO,SAAS,MAAM,GAAG,CAAC,GAAG;AACjD,YAAM,OAAO,QAAQ,aAAa,aAAa,SAAS,QAAQ,SAAS,YAAY;AACrF,cAAQ,IAAI,aAAQ,IAAI,KAAK,QAAQ,KAAK,EAAE;AAC5C,UAAI,QAAQ,SAAS,UAAU;AAC7B,gBAAQ;AAAA,UACN,sBAAiB,QAAQ,SAAS,QAAQ,IAAI,QAAQ,SAAS,cAAc,GAAG;AAAA,QAClF;AAAA,MACF;AAEA,UAAI,QAAQ,aAAa;AACvB,gBAAQ,IAAI,MAAM,IAAI,mBAAc,MAAM,KAAK,CAAC,IAAI,QAAQ,WAAW,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AACA,QAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,cAAQ,IAAI,MAAM,IAAI,qBAAgB,OAAO,SAAS,SAAS,CAAC,gBAAgB,CAAC;AAAA,IACnF;AAAA,EACF;AACA,UAAQ,IAAI;AACd;AAKA,SAAS,kBAAkB,YAA+B,aAAiC;AACzF,UAAQ,IAAI;AACZ,UAAQ,IAAI,MAAM,KAAK,sBAAsB,CAAC;AAC9C,UAAQ,IAAI,MAAM,IAAI,SAAI,OAAO,EAAE,CAAC,CAAC;AACrC,UAAQ,IAAI;AAEZ,MAAI,WAAW,WAAW,GAAG;AAC3B,YAAQ,IAAI,MAAM,MAAM,6BAA6B,CAAC;AACtD,YAAQ,IAAI;AACZ;AAAA,EACF;AAEA,QAAM,UAAU,WAAW,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO;AAC7D,QAAM,SAAS,WAAW,OAAO,CAAC,MAAM,EAAE,WAAW,MAAM;AAC3D,QAAM,OAAO,WAAW,OAAO,CAAC,MAAM,EAAE,WAAW,MAAM;AAEzD,MAAI,QAAQ,SAAS,GAAG;AACtB,YAAQ,IAAI,MAAM,IAAI,KAAK,YAAY,QAAQ,MAAM,GAAG,CAAC;AACzD,eAAW,KAAK,SAAS;AACvB,cAAQ,IAAI,MAAM,MAAM,IAAI,GAAG,CAAC,IAAI,MAAM,KAAK,EAAE,WAAW,CAAC,EAAE;AAC/D,cAAQ,IAAI,cAAc,EAAE,IAAI,EAAE;AAClC,cAAQ,IAAI,QAAQ,EAAE,OAAO,EAAE;AAAA,IACjC;AACA,YAAQ,IAAI;AAAA,EACd;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,YAAQ,IAAI,MAAM,OAAO,KAAK,aAAa,OAAO,MAAM,GAAG,CAAC;AAC5D,eAAW,KAAK,QAAQ;AACtB,cAAQ,IAAI,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,MAAM,KAAK,EAAE,WAAW,CAAC,EAAE;AAClE,cAAQ,IAAI,cAAc,EAAE,IAAI,EAAE;AAClC,cAAQ,IAAI,QAAQ,EAAE,OAAO,EAAE;AAAA,IACjC;AACA,YAAQ,IAAI;AAAA,EACd;AAEA,MAAI,KAAK,SAAS,GAAG;AACnB,YAAQ,IAAI,MAAM,KAAK,KAAK,SAAS,KAAK,MAAM,GAAG,CAAC;AACpD,eAAW,KAAK,MAAM;AACpB,cAAQ,IAAI,MAAM,MAAM,KAAK,GAAG,CAAC,IAAI,MAAM,KAAK,EAAE,WAAW,CAAC,EAAE;AAChE,cAAQ,IAAI,cAAc,EAAE,IAAI,EAAE;AAClC,cAAQ,IAAI,QAAQ,EAAE,OAAO,EAAE;AAAA,IACjC;AACA,YAAQ,IAAI;AAAA,EACd;AAEA,UAAQ,IAAI,MAAM,IAAI,SAAI,OAAO,EAAE,CAAC,CAAC;AACrC,UAAQ,IAAI;AAEZ,QAAM,QAAQ,WAAW;AACzB,QAAM,WAAW,qBAAqB,YAAY,WAAW;AAE7D,UAAQ;AAAA,IACN,UAAU,KAAK,aAAa,UAAU,IAAI,MAAM,EAAE,KAC5C,QAAQ,MAAM,aAAa,OAAO,MAAM,cAAc,KAAK,MAAM;AAAA,EACzE;AACA,UAAQ,IAAI,kBAAkB,WAAW,EAAE;AAE3C,MAAI,UAAU;AACZ,YAAQ,IAAI,MAAM,IAAI,kDAAkD,WAAW,SAAS,CAAC;AAAA,EAC/F,OAAO;AACL,YAAQ,IAAI,MAAM,MAAM,+CAA+C,WAAW,SAAS,CAAC;AAAA,EAC9F;AACA,UAAQ,IAAI;AACd;AAMA,SAAS,qBAAqB,YAA+B,OAA8B;AACzF,QAAM,iBAA+C;AAAA,IACnD,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAEA,QAAM,YAAY,eAAe,KAAK;AAEtC,SAAO,WAAW,KAAK,CAAC,MAAM,eAAe,EAAE,MAAM,KAAK,SAAS;AACrE;;;AC/oBA,IAAM,MAAM,UAAU;AACtB,IAAI,MAAM;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "extension-guard",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "CLI for scanning VSCode extensions for security issues",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,7 +13,7 @@
13
13
  "chalk": "^5.3.0",
14
14
  "commander": "^12.0.0",
15
15
  "ora": "^8.0.0",
16
- "@aspect-guard/core": "0.4.0"
16
+ "@aspect-guard/core": "0.5.0"
17
17
  },
18
18
  "devDependencies": {
19
19
  "tsup": "^8.0.0",