/** * Scanner Plugin Types * * Defines the plugin interface for external scanners. * Plugins can be installed from: * 1. Local directory: `.vaspera/plugins/{name}/manifest.json` * 2. npm package: `vaspera-scanner-{name}` * * @module plugins/types */ import { z } from "zod"; import type { Severity } from "../certification/types.js"; import type { DeterministicFinding, ScannerResult } from "../scanners/types.js"; /** * Plugin manifest schema * * Defines the structure of a plugin's manifest.json file. */ export declare const PluginManifestSchema: z.ZodObject<{ /** Plugin name (alphanumeric with hyphens) */ name: z.ZodString; /** Plugin version (semver) */ version: z.ZodString; /** Human-readable description */ description: z.ZodString; /** Plugin author */ author: z.ZodOptional; /** Plugin homepage/repository URL */ homepage: z.ZodOptional; /** License identifier */ license: z.ZodOptional; /** Minimum Vaspera version required */ minVasperaVersion: z.ZodOptional; /** Scanner configuration */ scanner: z.ZodObject<{ /** Scanner type identifier */ type: z.ZodString; /** Languages/frameworks this scanner supports */ languages: z.ZodArray; /** File patterns to include (glob) */ include: z.ZodOptional>; /** File patterns to exclude (glob) */ exclude: z.ZodOptional>; /** Whether scanner requires external binary */ requiresBinary: z.ZodDefault; /** Binary name to check for availability */ binaryName: z.ZodOptional; /** Default timeout in milliseconds */ defaultTimeout: z.ZodDefault; }, "strip", z.ZodTypeAny, { type: string; languages: string[]; requiresBinary: boolean; defaultTimeout: number; include?: string[] | undefined; exclude?: string[] | undefined; binaryName?: string | undefined; }, { type: string; languages: string[]; include?: string[] | undefined; exclude?: string[] | undefined; requiresBinary?: boolean | undefined; binaryName?: string | undefined; defaultTimeout?: number | undefined; }>; /** Entry point configuration */ entryPoint: z.ZodObject<{ /** Path to main module (relative to manifest) */ module: z.ZodString; /** Export name for the scanner function */ exportName: z.ZodDefault; }, "strip", z.ZodTypeAny, { module: string; exportName: string; }, { module: string; exportName?: string | undefined; }>; /** Custom rules configuration */ rules: z.ZodOptional; /** Rule file extensions */ extensions: z.ZodDefault>; }, "strip", z.ZodTypeAny, { extensions: string[]; directory?: string | undefined; }, { directory?: string | undefined; extensions?: string[] | undefined; }>>; /** Plugin capabilities */ capabilities: z.ZodDefault; /** Supports auto-fix */ autofix: z.ZodDefault; /** Supports custom rules */ customRules: z.ZodDefault; /** Can run in sandbox */ sandboxable: z.ZodDefault; }, "strip", z.ZodTypeAny, { autofix: boolean; incremental: boolean; customRules: boolean; sandboxable: boolean; }, { autofix?: boolean | undefined; incremental?: boolean | undefined; customRules?: boolean | undefined; sandboxable?: boolean | undefined; }>>; }, "strip", z.ZodTypeAny, { name: string; version: string; scanner: { type: string; languages: string[]; requiresBinary: boolean; defaultTimeout: number; include?: string[] | undefined; exclude?: string[] | undefined; binaryName?: string | undefined; }; description: string; capabilities: { autofix: boolean; incremental: boolean; customRules: boolean; sandboxable: boolean; }; entryPoint: { module: string; exportName: string; }; author?: string | undefined; license?: string | undefined; rules?: { extensions: string[]; directory?: string | undefined; } | undefined; homepage?: string | undefined; minVasperaVersion?: string | undefined; }, { name: string; version: string; scanner: { type: string; languages: string[]; include?: string[] | undefined; exclude?: string[] | undefined; requiresBinary?: boolean | undefined; binaryName?: string | undefined; defaultTimeout?: number | undefined; }; description: string; entryPoint: { module: string; exportName?: string | undefined; }; author?: string | undefined; capabilities?: { autofix?: boolean | undefined; incremental?: boolean | undefined; customRules?: boolean | undefined; sandboxable?: boolean | undefined; } | undefined; license?: string | undefined; rules?: { directory?: string | undefined; extensions?: string[] | undefined; } | undefined; homepage?: string | undefined; minVasperaVersion?: string | undefined; }>; export type PluginManifest = z.infer; /** * Scanner plugin context provided to the scanner function */ export interface ScannerPluginContext { /** Project path being scanned */ projectPath: string; /** Files to scan (if incremental mode) */ files?: string[]; /** Scanner timeout in milliseconds */ timeout: number; /** Custom rules directory */ rulesDir?: string; /** Plugin-specific configuration from .vaspera/config.yaml */ config?: Record; /** Logger instance */ logger: { debug: (message: string, data?: Record) => void; info: (message: string, data?: Record) => void; warn: (message: string, data?: Record) => void; error: (message: string, data?: Record) => void; }; } /** * Scanner plugin function signature * * Plugins must export a function matching this signature. */ export type ScannerPluginFn = (context: ScannerPluginContext) => Promise; /** * Loaded scanner plugin */ export interface LoadedPlugin { /** Plugin manifest */ manifest: PluginManifest; /** Path to plugin directory */ path: string; /** Source of the plugin */ source: "local" | "npm"; /** Scanner function */ scan: ScannerPluginFn; /** Whether plugin is enabled */ enabled: boolean; /** Load error if failed */ loadError?: string; } /** * Plugin registry entry */ export interface PluginRegistryEntry { /** Plugin name */ name: string; /** Plugin version */ version: string; /** Plugin source */ source: "local" | "npm"; /** Whether plugin is loaded */ loaded: boolean; /** Load error if any */ error?: string; /** Last loaded timestamp */ loadedAt?: string; } /** * Plugin load options */ export interface PluginLoadOptions { /** Whether to load from local .vaspera/plugins */ loadLocal?: boolean; /** Whether to load from npm packages */ loadNpm?: boolean; /** Specific plugins to load (by name) */ only?: string[]; /** Plugins to skip */ skip?: string[]; /** Whether to run plugins in sandbox (child process) */ sandbox?: boolean; /** Plugin-specific configurations */ configs?: Record>; } /** * Plugin execution result */ export interface PluginExecutionResult { /** Plugin name */ plugin: string; /** Scanner result */ result: ScannerResult; /** Execution time in ms */ durationMs: number; /** Whether execution was sandboxed */ sandboxed: boolean; /** Error if execution failed */ error?: string; } /** * Severity mapping configuration for a plugin */ export interface PluginSeverityMapping { /** Plugin name */ plugin: string; /** Mapping from plugin severity to Vaspera severity */ mapping: Record; /** Default severity if no mapping found */ default: Severity; } /** * Plugin finding with source information */ export interface PluginFinding extends DeterministicFinding { /** Source plugin name */ pluginSource: string; /** Original severity from plugin */ originalSeverity?: string; } /** * Check if a value is a valid plugin manifest */ export declare function isValidManifest(value: unknown): value is PluginManifest; /** * Validate a plugin manifest and return errors */ export declare function validateManifest(value: unknown): { valid: boolean; manifest?: PluginManifest; errors?: string[]; }; //# sourceMappingURL=types.d.ts.map