/** * Opt-in analytics for a scaffolded app (guuey#1062 — platform's ruling on * the row, 2026-09-09): * * 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'; 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; /** Scaffold into a non-empty targetDir anyway. Default: false. */ force?: boolean; /** Root directory holding `