export type HostFramework = "next" | "express" | "unknown"; export interface VendoWiring { server: boolean; client: boolean; /** A VISIBLE agent surface is mounted — alone is a context provider that renders nothing (0.4.1 E2E cert B3: by-the-book installs ended doctor-green with nothing on screen). */ surface: boolean; /** The host still uses the removed — doctor prints the swap. The NAME alone is not evidence: a host's own wrapper component may be called VendoRoot (Maple's is), so this is the import from @vendoai, or the tag with no anywhere in the source. */ legacyRoot: boolean; } /** What counts as a visible surface: the shipped chrome ( and the pieces it is built from), the BYO embeds a host chat renders, and the hooks a host uses to drive a custom surface. Deliberately generous — this list gates a doctor FAILURE, so a host with any plausible surface of its own must pass. */ export declare const SURFACE_MARKERS: readonly string[]; export declare function detectFramework(root: string): Promise; /** What Next must leave OUT of the server bundle. `@vendoai/vendo` USED TO BE ON THIS LIST and cannot be, because `serverExternalPackages` is package-granular and this package has a "use client" half. Externalizing it hands Next the client doors through the server condition, so `VendoProvider` renders with no client boundary and prerender dies on `Cannot read properties of null (reading 'useMemo')` — `next build` exit 1 for any host that prerenders a Vendo surface. Meanwhile `vendo doctor` demanded the entry, so there was no config a host could write that satisfied both. Reproduced against the published 0.60.0 tarball, so this predates the core+ui fold: 0.60.0 already shipped `./react`. What the entry was FOR is still real and is not lost. PGlite's Emscripten module breaks under production chunking, so `@electric-sql/pglite` stays listed by name. The app checker imports esbuild through a VARIABLE specifier behind bundler-ignore comments (src/apps/checking/toolchain.ts), so Next never sees a static request to match — bundled, that import becomes a bare runtime resolve from the app root, which npm hoists to and pnpm does not. That is a generated-screen degradation on pnpm hosts, and it is strictly smaller than a build that fails for everyone. Verified end to end on a real tarball host: build exit 0, and the server half answers /api/vendo/status 200 with store, agent, actions, guard, apps and automations all live. */ export declare const NEXT_SERVER_EXTERNALS: readonly string[]; /** The property exactly as init writes it and doctor tells you to paste it. */ export declare const NEXT_SERVER_EXTERNALS_LINE: string; /** The list, under either spelling: Next 15's `serverExternalPackages` and Next 14's `experimental.serverComponentsExternalPackages` (renamed, same wiring). Group 1 is everything through the `[`, group 2 the names already listed. */ export declare const SERVER_EXTERNALS_ARRAY: RegExp; /** The host's next.config, whichever extension it uses; null when it has none. */ export declare function nextConfigPath(root: string): Promise; /** The source with every comment BLANKED to spaces rather than removed, so it stays the same LENGTH and an index into it is an index into the original. A commented-out `serverExternalPackages` line is exactly what a host debugging its bundle leaves behind, and reading one as configuration greened E-CFG-004 on a host that was still broken. Deliberately not a parser: it blanks a `//` inside a string literal too, and the cost of that is a printed paste instead of an edit — never a wrong edit. */ export declare function blankComments(source: string): string; /** Which externals a next.config's TEXT does not already carry. */ export declare function missingServerExternals(source: string): string[]; /** Which of those the host TRANSPILES — the one state where the property must not be written for them. Next REFUSES a package named in both lists and hard-fatals at boot, so a source-linked host (our own demo-bank was one) that follows the advice unedited loses its dev server. */ export declare function transpiledServerExternals(source: string): string[]; /** The extra sentence init's paste and doctor's finding both carry in that state: the fix is two steps, and doing only the second one bricks the host. */ export declare const transpileConflictNote: (conflicting: readonly string[]) => string; /** The workspace packages that look like the real host, for an init run one level too high: a monorepo root declares neither next nor express, so detection lands on the runtime-neutral custom scaffold and the dev never notices. Deliberately just the two conventional workspace dirs — a hint that names a candidate, not a workspace-glob resolver. Paths are relative and posix-style (they go straight into a `vendo init ` suggestion). */ export declare function workspaceHostCandidates(root: string): Promise; /** Both supported spellings of the Supabase preset specifier — the scoped umbrella and the unscoped `vendoai` alias re-export ("both names ship the same wire"; greptile on #1374: an alias-wired host missed E-AUTH-009 entirely). A regex, not string literals, so the dependency guard never reads an import-shaped alias specifier here (same reason as LEGACY_ROOT_IMPORT above). */ export declare const SUPABASE_PRESET_IMPORT: RegExp; /** The clerk preset's specifier, both spellings — same shape, same reasons (#1338 rides the same table E-AUTH-009 does). */ export declare const CLERK_PRESET_IMPORT: RegExp; /** Whether any host source imports the Supabase auth preset. Import marker only: outside a known Vendo composition file a bare `supabase(` call is the host's OWN Supabase client, not the preset (expense.fyi defines exactly such a helper). */ export declare function wiresSupabaseAuth(root: string): Promise; export declare function wiresClerkAuth(root: string): Promise; /** Whether any host source reaches the tenant-connector API. A property read on the Vendo handle is unambiguous evidence — the name exists nowhere else — so unlike the Supabase marker this needs no composition-file narrowing. */ export declare function wiresTenantConnectors(root: string): Promise; /** Whether the host's guard is wired to read its rules from a FILE. The empty policy object is that and nothing else — it is what `vendo init` writes (cli/init-scaffolds.ts) and the one spelling whose only meaning is "the rules live at the default path". Inline rules, a preset name and an explicitly named `file` all say something different and are deliberately not matched: the first two replace the file, the third fails loud on its own (packages/vendo/src/guard/policy.ts:115). */ export declare function wiresPolicyFile(root: string): Promise; /** Whether the host builds its OWN store. Load-bearing for anything that reads a key as evidence of a Cloud seam: an explicitly passed store always wins over VENDO_API_KEY (the adapter rule, compose-store.ts's `selectStore`), so a host that calls this has a local store no matter what its environment says. */ export declare function composesOwnStore(root: string): Promise; /** The host's own agent-loop route, as a posix-style root-relative directory * (`app/api/chat`), or null. * * This is what makes "through your own agent loop" the RECOMMENDED use case for * a host that already has one, instead of a third option nobody reads. The * evidence is the route scanner's own marker (`runsAgentLoop`), which is also * what excludes that route from the callable catalog — so the recommendation * and the exclusion can never disagree about what a loop is. * * Not `hostSourceMatches`: that one walks every source file and answers a * boolean, and this needs both the narrower route filter and the PATH — the * route's directory is what the recommendation shows the developer. * * Same bounded walk and comment-stripping as `detectVendoWiring`, so a host too * big to scan is judged consistently. First match wins: one loop is the whole * answer, and the directory is what a human recognises. */ export declare function detectAgentLoopRoute(root: string): Promise; /** Bounded source scan shared by init and doctor so their wiring verdicts agree. */ export declare function detectVendoWiring(root: string): Promise;