/** * Static Annotation Scanner * * Scans source code files for tool annotations using AST parsing. * Detects annotations nested inside tool definition objects/arrays * in ES module syntax that regex-based scanning would miss. * * Fixes Issue #192: Static annotation scanner misses nested annotations * in ES module syntax like: * const TOOLS = [{ name: 'x', annotations: { readOnlyHint: true } }]; * * @module helpers/StaticAnnotationScanner */ /** * Evidence from static annotation scanning */ export interface StaticAnnotationEvidence { /** File path where annotation was found */ filePath: string; /** Tool name associated with the annotation */ toolName: string; /** Confidence level */ confidence: "high" | "medium" | "low"; /** Description of how the annotation was found */ detail: string; /** Line number in source file */ lineNumber?: number; } /** * Extracted annotation from source code */ export interface StaticAnnotation { toolName: string; readOnlyHint?: boolean; destructiveHint?: boolean; idempotentHint?: boolean; openWorldHint?: boolean; } /** * Result of static annotation scanning */ export interface StaticAnnotationScanResult { /** Map of tool name to extracted annotations */ annotations: Map; /** Overall confidence of the scan */ confidence: "high" | "medium" | "low"; /** Evidence collected during scanning */ evidence: StaticAnnotationEvidence[]; /** Whether source code was scanned */ sourceCodeScanned: boolean; /** Count of tools with annotations found */ annotatedToolCount: number; /** Files that were scanned */ scannedFiles: string[]; /** Errors encountered during parsing */ parseErrors: Array<{ file: string; error: string; }>; } /** * Scans source code for tool annotations using AST parsing. * * Detection approach: * 1. Parse JS/TS files with acorn (ecmaVersion 2022, module syntax) * 2. Walk AST looking for Property nodes with key 'annotations' * 3. Extract annotation values (readOnlyHint, destructiveHint, etc.) * 4. Find associated tool name from sibling 'name' property in parent object * * @public */ export declare class StaticAnnotationScanner { /** * File patterns to skip during source code scanning * (same patterns as StdioTransportDetector for consistency) */ private readonly SKIP_FILE_PATTERNS; /** Maximum file size for source scanning (500KB) */ private readonly MAX_FILE_SIZE; /** File extensions to scan */ private readonly SCANNABLE_EXTENSIONS; /** * Scan source files for tool annotations. * * @param sourceCodeFiles - Map of file paths to content * @returns Static annotation scan results */ scan(sourceCodeFiles?: Map): StaticAnnotationScanResult; /** * Parse a single file for tool annotations. * * @param filePath - File path for error reporting * @param content - File content to parse * @returns Array of extracted annotations with line numbers */ private parseFile; /** * Check if a property node is an 'annotations' property. */ private isAnnotationsProperty; /** * Extract annotation values from an ObjectExpression node. */ private extractAnnotationValues; /** * Get the string name of a property key. */ private getPropertyKeyName; /** * Find the tool name from ancestor context. * Looks for a sibling 'name' property in the parent ObjectExpression. */ private findToolNameFromContext; /** * Strip common TypeScript syntax for basic parsing. * This is a simple approach - just removes type annotations to allow JS parsing. */ private stripTypeScript; /** * Check if file should be skipped during scanning. */ private shouldSkipFile; /** * Check if file has a scannable extension. */ private isScannableFile; /** * Compute overall confidence from collected evidence. * * Confidence rules: * - High: 2+ annotations found with explicit 'annotations' objects * - Medium: 1 annotation found * - Low: No annotations found */ private computeConfidence; } //# sourceMappingURL=StaticAnnotationScanner.d.ts.map