/** * Entry-point inference (shared by orphan-subtree, test-only-reachable). * * A function is an entry point if: * 1. It's the bin entry (declared in package.json `bin`). * 2. It's a Tool registration's commands handler. * 3. Its name matches a heuristic list (main, start, register, init, etc.). * 4. Its `` is reachable (top-level statements always run). * 5. It's exported AND has no *external* in-project caller (someone * outside the project might call it). A self-recursive edge does not * count as a caller here: an exported public function whose only * in-project caller is itself (e.g. a recursive renderer consumed * only across a package boundary, where the cross-package call edge * does not resolve) is still an external entry point — counting its * own recursion as a "caller" would wrongly hide it (and its whole * file-local helper subtree) as an orphan. * 6. It's an EXPORTED symbol of a module reached via a dynamic * `import('')` / `await import('')` expression (including * the `const { x } = await import(...)` destructure form). The call * graph's static resolver cannot trace a binding through a dynamic * import, so a function reached only that way would otherwise look * orphaned. We treat the dynamic-import target the same way a static * import edge makes the imported module's exported surface reachable: * resolve the relative specifier to the target file and seed its * exported occurrences as entry points. This is conservative — it * only adds reachability (never suppresses a genuine orphan), and it * fires solely on exported symbols of an actually-imported file. * 7. It lives in a file matched by `targets..conventions.entrypoints`. * Frameworks often call route/action/config files dynamically, so the * graph treats those files as project-declared roots. * * v0.2 ships heuristics 3, 4, 5; 1 and 2 are project-specific and * deferred until cross-package call resolution is reliable. Heuristic 6 * (dynamic-import reachability) was added to fix a verified false * positive: a CLI command reached only via * `const { runReplay } = await import('../commands/.../replay.js')`. */ import type { Catalog, Indexes } from '../types.js'; export interface EntryPoint { readonly bodyHash: string; readonly reason: 'module-init' | 'name-match' | 'no-callers-exported' | 'dynamic-import' | 'target-convention'; } export declare function inferEntryPoints(catalog: Catalog, indexes: Indexes): readonly EntryPoint[]; //# sourceMappingURL=_entry-points.d.ts.map