/** The pnpm fetched when this machine has none of its own. */ declare const SCAFFOLD_PNPM = "pnpm@12.16.0"; /** A runnable pnpm: the executable and the arguments that must precede pnpm's own. */ interface PnpmInvocation { readonly file: string; readonly prefix: readonly string[]; } /** The pnpm this machine can run, or `null` when it can run none. */ declare function pnpmInvocation(): PnpmInvocation | null; /** * The same invocation as one shell string, for callers that shell out rather * than spawn — `pnpm install`, or `npx --yes pnpm@ install`. `null` when * this machine can run no pnpm at all. No argument here ever needs quoting: the * pieces are a fixed executable name, fixed flags, a `pnpm@` specifier * and the caller's own literal subcommands. */ declare function pnpmCommandLine(args: readonly string[]): string | null; /** What to tell a user whose machine can run no pnpm. Never says `corepack`. */ declare function noPnpmMessage(what: string, cwd: string): string; /** * What a user types to run pnpm on this machine, as the words before a * subcommand: `pnpm`, or `npx --yes pnpm@` (guuey#1741). Every command * the scaffold prints, and every command its templates show, starts with this, * so a user without pnpm is never told to type `pnpm`. When the machine can run * no pnpm at all it is `pnpm`: that user has to install pnpm first, and the * next steps say so. */ declare function pnpmRunner(inv: PnpmInvocation | null): string; /** * Opt-in analytics for a scaffolded app (guuey#1062): * * 1. The DEFAULT scaffold carries ZERO analytics bytes — no loader, no * import, no key placeholder. A customer's app never reports to Guuey's * PostHog by accident; `check-templates.mjs` asserts the template tree * itself is clean (the guuey#930-class guard: template bytes, not * emitted copies, are the truth). * 2. Opt-in ONLY by the explicit scaffold-time flag `--analytics posthog` * (non-interactive-safe; the guuey-owned demo recipe passes it). * 3. With the flag, `web/index.html` gains the SAME cookieless loader * guuey.com runs (landing guuey#626 / demos guuey#1059) — but the * project key is never a literal in these bytes: the loader reads * `%VITE_POSTHOG_KEY%` (+ optional `%VITE_POSTHOG_HOST%`), which Vite * substitutes in `index.html` at build time from the app's env, and it * renders nothing when the key is absent (Vite leaves an undefined * `%VITE_*%` token in place — the guard treats that as "no key"). * 4. Tracker semantics (cookieless_mode 'always', pageview/pageleave/ * autocapture, `register({ surface })`, the AEO bot register) mirror * growth's snippet; growth owns them — when growth's bytes move, this * block follows. */ type AnalyticsProvider = 'posthog'; /** Frameworks the scaffolder ships templates for. */ type Framework = 'claude-agent-sdk' | 'openai-agents-sdk' | 'google-adk'; /** * App templates the scaffolder ships. `base` = landing + login + home + * chat; `agentic-app` extends it with the split-sidebar product shell whose * agent dock swaps the main canvas to a fullscreen agent. */ type Template = 'base' | 'agentic-app' | 'agent'; /** * Who the agent is FOR (guuey#1597, stamped by guuey#1670): `personal` — the * builder's own assistant; `customers` — an agent on the builder's surface. * The same two values as `@guuey/config`'s `APP_BUILT_FOR`. That package is a * devDependency here, never a runtime one, so the list is restated and * `scaffold.test.ts` pins the two equal. */ type ScaffoldBuiltFor = 'personal' | 'customers'; interface ScaffoldOptions { /** Absolute or cwd-relative path to create/populate the new project in. */ targetDir: string; /** npm-safe project name (also used as the default scope). */ name: string; framework: Framework; /** App template. Default: `base`. */ template?: Template; /** Package scope for `@/*` packages. Default: `name`. */ scope?: string; /** Run `pnpm install` in the new project after scaffolding. Default: false. */ install?: boolean; /** Opt-in analytics loader in web/index.html (guuey#1062). Default: none — zero analytics bytes. */ analytics?: AnalyticsProvider; /** Run `git init` + an initial commit in the new project. Default: true. */ git?: boolean; /** * Bind the scaffold to an EXISTING guuey app (guuey#580 point 4 — the * tada page's one-liner): stamps top-level `appId` into the scaffolded * guuey.json, which is exactly where `scripts/bootstrap.mjs --link` * reads its default from — so the link phase runs promptless and the * repo is born bound to the just-created agent. No validation here * beyond non-empty: the id's truth is the platform's to judge at link * time (a wrong id fails loudly there, with auth in hand). */ appId?: string; /** * Who the agent is FOR (guuey#1670, `guuey create --for`). Stamps * `app.builtFor` into the scaffolded guuey.json. `guuey deploy` sends it * when it creates the app, and `guuey agent apply` converges it. Absent * writes no key, and `guuey deploy` asks the question before it creates * the app. */ builtFor?: ScaffoldBuiltFor; /** Scaffold into a non-empty targetDir anyway. Default: false. */ force?: boolean; /** * How this machine runs pnpm, when the caller already asked `pnpmInvocation()` * (`null`: it runs none). Omitted, the scaffold asks it once itself. Either * way there is one answer per scaffold (guuey#1741). */ pnpm?: PnpmInvocation | null; /** Root directory holding `