export type SpiVersion = 1; export type SemanticProgramIndex = { version: SpiVersion; generated_at: string; workspace: SpiWorkspace; files: SpiFile[]; symbols: SpiSymbol[]; edges: SpiEdge[]; diagnostics: SpiDiagnostic[]; }; export type SpiWorkspace = { root: string; fingerprint: string; extractor_version: string; madar_version: string; }; export type SpiLanguage = 'typescript' | 'javascript' | 'tsx' | 'jsx' | 'json' | 'unknown'; export type SpiFile = { id: string; path: string; language: SpiLanguage; loc: number; hash: string; }; export type SpiSymbolKind = 'function' | 'class' | 'interface' | 'type-alias' | 'enum' | 'method' | 'constant' | 'variable' | 'namespace'; export type SpiPosition = { line: number; column: number; }; export type SpiRange = { start: SpiPosition; end: SpiPosition; }; export type SpiFrameworkRole = 'nest_module' | 'nest_controller' | 'nest_route' | 'nest_provider' | 'nest_guard' | 'nest_pipe' | 'nest_interceptor' | 'routing_controllers_controller' | 'routing_controllers_route' | 'express_app' | 'express_router' | 'express_route' | 'express_middleware' | 'nextjs_app_page' | 'nextjs_app_route' | 'nextjs_app_layout' | 'nextjs_app_loading' | 'nextjs_app_error' | 'nextjs_app_template' | 'nextjs_pages_page' | 'nextjs_pages_api' | 'nextjs_middleware' | 'nextjs_client_component' | 'nextjs_server_action' | 'react_router_router' | 'react_router_loader' | 'react_router_action' | 'redux_slice' | 'redux_store' | 'redux_selector' | 'redux_async_thunk' | 'redux_rtk_query_api' | 'hono_app' | 'hono_route' | 'hono_middleware' | 'fastify_app' | 'fastify_route' | 'fastify_plugin' | 'trpc_router' | 'trpc_procedure_query' | 'trpc_procedure_mutation' | 'trpc_procedure_subscription' | 'prisma_client' | 'prisma_model_reader' | 'prisma_model_writer' | 'prisma_model_access' | 'repository_reader' | 'repository_writer'; export type SpiStorageOperation = 'save' | 'create' | 'update' | 'upsert' | 'findUnique' | 'findMany' | '$transaction'; export type SpiRuntimeBoundary = 'client' | 'server'; export type SpiFrameworkMetadata = { storage_operation?: SpiStorageOperation; runtime_boundary?: SpiRuntimeBoundary; [key: string]: unknown; }; export type SpiSymbol = { id: string; file_id: string; name: string; kind: SpiSymbolKind; range: SpiRange; exported: boolean; framework_role?: SpiFrameworkRole; /** * #72 slice 1c-ii.f — opt-in framework metadata bag. Populated by * framework detectors when the symbol carries framework-specific data * that doesn't fit the generic SpiSymbol shape: * * - Express route handler (\`express_route\` role): * \`route_path: string\` — the route path string from the first * argument of \`.(path, handler)\`. * e.g. \`'/users/:id'\`. * - Express middleware (\`express_middleware\` role): * \`mount_path?: string\` — the optional prefix from * \`app.use('/api', middleware)\`. Absent * when middleware is registered globally. * * Per the SPI v1 design's open questions: the schema is intentionally * \`unknown\` so framework extensions can store framework-specific * fields without rev-ing the SpiSymbol type. A consumer that wants to * type-narrow should do so against the symbol's \`framework_role\`. */ framework_metadata?: SpiFrameworkMetadata; }; export type SpiEdgeKind = 'imports' | 'exports' | 'declares' | 'references' | 'calls' | 'enqueues_job' | 'extends' | 'implements' | 'param_type' | 'return_type' | 'covered_by' | 'changed_in' | 'module_provides' | 'module_imports' | 'module_exports' | 'controller_route' | 'route_handler' | 'registers_controller' | 'injects' | 'guards' | 'intercepts' | 'pipes'; export type SpiEdgeConfidence = 'high' | 'medium' | 'low'; export type SpiEdgeSource = 'typescript-semantic' | 'typescript-syntactic' | 'tree-sitter' | 'framework-decorator' | 'heuristic'; export type SpiEdgeEvidence = { file_id: string; range: SpiRange; }; export type SpiEdge = { from: string; to: string; kind: SpiEdgeKind; confidence: SpiEdgeConfidence; source: SpiEdgeSource; evidence?: SpiEdgeEvidence; }; export type SpiDiagnosticLevel = 'info' | 'warn' | 'error'; export type SpiDiagnosticEvidence = { file_id: string; range?: SpiRange; }; export type SpiDiagnostic = { id: string; level: SpiDiagnosticLevel; message: string; evidence?: SpiDiagnosticEvidence; }; export type SpiDiffOverlay = { base_ref: string; head_ref: string; changed_files: string[]; changed_symbols: string[]; edges_added: SpiEdge[]; };