/** * Bump whenever the grammar below changes. Stored selections are bound to this * value so an upgraded detector re-prompts instead of silently reusing a * selection that a different grammar produced. * * 2: workspace member manifests are read, and candidates carry the workspace * they came from. */ export declare const APP_PORT_DETECTOR_VERSION = 2; export declare const VITE_DEFAULT_PORT = 5173; export declare const NEXT_DEFAULT_PORT = 3000; /** Largest package.json the scanner will read from the Sandbox. */ export declare const MAX_PACKAGE_JSON_BYTES = 262144; /** Workspace patterns honored from one repository, and members read from them. */ export declare const MAX_WORKSPACE_PATTERNS = 16; export declare const MAX_WORKSPACE_MANIFESTS = 32; export type AppPortFramework = 'vite' | 'next'; /** Where a candidate port came from; both are safe to print. */ export type AppPortEvidence = 'framework-default' | 'dev-script'; /** The repository root manifest's path in a candidate or manifest list. */ export declare const ROOT_MANIFEST_PATH = "."; export interface PackageManifest { /** Path relative to the repository root; `.` for the root manifest. */ path: string; /** File contents, or null when the manifest does not exist. */ content: string | null; } export interface AppPortCandidate { port: number; framework: AppPortFramework; source: AppPortEvidence; /** Manifest the candidate came from; `.` for the repository root. */ workspace: string; } export interface AppPortDetection { candidates: AppPortCandidate[]; /** * True when a framework produced more than one literal port. Conflicting * candidates are labeled and require an explicit selection; they are never * silently resolved and never accepted by a bare Enter. */ conflicting: boolean; /** Bounded, content-free notices safe to print. */ warnings: string[]; fingerprint: string; } /** * Detect app-port candidates from one or more `package.json` manifests. * * A missing manifest yields no candidates. Malformed JSON yields a bounded * warning naming the path and no candidates from that manifest, so neither a * Sandbox nor the other workspaces are failed by one project's broken metadata. */ export declare function detectAppPorts(manifests: readonly PackageManifest[]): AppPortDetection; /** * Canonical candidate fingerprint: SHA-256 over a stable serialization of the * sorted candidates plus the detector version. */ export declare function fingerprintAppPortCandidates(candidates: readonly AppPortCandidate[]): string; /** Human-readable, content-free label for a candidate. */ export declare function describeAppPortCandidate(candidate: AppPortCandidate): string; /** * Workspace member patterns declared by a repository, as data. * * Two conventions exist and a repository may use either: npm/yarn/bun put a * `workspaces` array (or `{ packages: [...] }`) in the root `package.json`, * while pnpm keeps a `packages:` list in `pnpm-workspace.yaml`. Both are read * here; neither is executed. * * Only two pattern shapes are honored, matching the detector's refusal to * interpret: a literal path (`apps/web`) and a single-level trailing wildcard * (`apps/*`). Recursive `**`, negations, and anything with characters outside a * conservative path set are dropped rather than guessed at. */ export declare function parseWorkspacePatterns(rootPackageJson: string | null, pnpmWorkspaceYaml: string | null): string[];