Advertisement

← ubon

src/types/index.ts

4.3 KB Download file
import type { RuleCategory, RuleSeverity } from '../rules/types';

export type { RuleCategory, RuleSeverity } from '../rules/types';

export interface ScanResult {
  type: 'error' | 'warning' | 'info';
  category: RuleCategory;
  message: string;
  file?: string;
  line?: number;
  range?: { startLine: number; startColumn: number; endLine: number; endColumn: number };
  severity: RuleSeverity;
  ruleId: string;
  confidence: number; // 0.0 - 1.0 likelihood this is a true issue
  confidenceReason?: string; // explanation of why this confidence level was assigned
  match?: string; // the matched snippet used for fingerprinting
  fingerprint?: string; // Stable fingerprint for suppression/baseline
  fix?: string;
  fixEdits?: FixEdit[]; // optional machine-actionable edits
  helpUri?: string; // optional documentation URL for this rule
  suppressed?: boolean; // whether this result was suppressed by inline comment
  suppressionReason?: string; // optional reason for suppression
  context?: {
    before: string[];
    line: string;
    after: string[];
  }; // optional source context for JSON/MCP agent consumers
}

export interface ScanOptions {
  directory: string;
  port?: number;
  skipBuild?: boolean;
  include?: string[];
  exclude?: string[];
  verbose?: boolean;
  // Configurable scanning behavior
  minConfidence?: number; // 0.0 - 1.0; default undefined means no filter
  enabledRules?: string[]; // if provided, only include these ruleIds
  disabledRules?: string[]; // exclude these ruleIds
  failOn?: 'none' | 'warning' | 'error'; // CLI gating threshold
  // Baseline
  baselinePath?: string; // path to baseline file; default .ubon.baseline.json in directory
  updateBaseline?: boolean; // write current findings to baseline and exit
  useBaseline?: boolean; // apply baseline to filter findings (default true)
  // Changed-files mode
  changedFiles?: string[]; // limit scanning to these relative file paths
  gitChangedSince?: string; // use git diff --name-only <ref> to populate changedFiles
  // Profile selection
  profile?: 'auto' | 'react' | 'next' | 'lovable' | 'sveltekit' | 'astro' | 'remix' | 'hono';
  // History scanning
  gitHistoryDepth?: number; // number of commits to search for secrets
  // Internal crawler (opt-in)
  crawlInternal?: boolean;
  crawlStartUrl?: string;
  crawlDepth?: number;
  crawlTimeoutMs?: number;
  // Performance mode
  fast?: boolean;
  skipPatterns?: string[];
  maxFileSize?: number;
  // Focus filters (human-friendly)
  focusCritical?: boolean; // only show severity high
  focusSecurity?: boolean; // only category security
  focusNew?: boolean; // only issues not in baseline (applied post-baseline)
  detailed?: boolean; // show all, including lower-confidence
  quickTopN?: number; // for 'quick' command, top N critical issues
  // Output mode
  json?: boolean; // whether JSON output is desired
  color?: 'auto' | 'always' | 'never'; // colorized output mode
  groupBy?: 'category' | 'file' | 'rule' | 'severity'; // how to group results
  format?: 'human' | 'table'; // output format for human mode
  minSeverity?: 'low' | 'medium' | 'high'; // minimum severity filter
  maxIssues?: number; // limit number of results shown
  showContext?: boolean; // show code context around findings
  explain?: boolean; // show "why it matters" explanations
  showConfidence?: boolean; // show per-finding confidence in human output
  showSuppressed?: boolean; // include suppressed results in output
  ignoreSuppressed?: boolean; // completely ignore suppressed results
  clearCache?: boolean; // clear OSV cache before scanning
  noCache?: boolean; // disable OSV caching
  // Result cache for performance
  noResultCache?: boolean; // disable per-file result cache
  // Interactive mode
  interactive?: boolean; // walk through issues interactively
  // Output verbosity
  quiet?: boolean; // suppress banners, suggestions, and contextual guidance
  ndjson?: boolean; // emit one JSON-encoded finding per line (streaming-friendly)
  allowConfigJs?: boolean; // permit loading ubon.config.js (executes user code)
}

export interface FixEdit {
  file: string;
  startLine: number;
  startColumn: number;
  endLine: number;
  endColumn: number;
  replacement: string;
}

export interface Scanner {
  name: string;
  scan(options: ScanOptions): Promise<ScanResult[]>;
}