{
  "$comment": "Machine-readable map of NVX Stack Builder for AI agents. Verified by `npm run docs:check` (templateIds must equal src/data/template-ids.ts; every keyFiles path must exist). Human docs: docs/agents/AGENT-PLAYBOOK.md",
  "name": "nvx-stack-builder",
  "version": "0.6.0",
  "branchState": "main = v0.6.0 (deployed to devstack.bid). feat/d1-chat-schema = D1 nvx-db binding + chat schema migrations (schema only, no UI)",
  "stack": {
    "framework": "Next.js 16.4 App Router",
    "language": "TypeScript",
    "ui": "React 19 + Tailwind CSS v4",
    "runtime": "Cloudflare Workers via @opennextjs/cloudflare",
    "node": ">=22",
    "tests": "Vitest + Testing Library"
  },
  "subsystems": [
    {
      "id": "templates",
      "summary": "Stack Template data (10 templates), common/runtime/add-on steps",
      "keyFiles": [
        "src/data/templates/index.ts",
        "src/data/template-ids.ts",
        "src/data/common-steps.ts",
        "src/data/runtime-steps.ts",
        "src/data/addon-steps.ts",
        "src/lib/types.ts"
      ],
      "docs": "docs/architecture/templates-and-composer.md"
    },
    {
      "id": "composer",
      "summary": "Normalize config, filter by `when`, insert add-ons, resolve placeholders, dedupe, apply user edits",
      "keyFiles": [
        "src/lib/composer.ts",
        "src/lib/placeholders.ts"
      ],
      "docs": "docs/concepts/composition.md"
    },
    {
      "id": "scripts-export",
      "summary": "Generate setup.sh / setup.ps1 / README / zip and CLI export",
      "keyFiles": [
        "src/lib/scripts.ts",
        "src/lib/download.ts",
        "scripts/export-template.ts"
      ],
      "docs": "docs/architecture/scripts-and-share.md"
    },
    {
      "id": "share",
      "summary": "Share links in URL hash (#s= / #t=), base64url JSON v1",
      "keyFiles": [
        "src/lib/share.ts"
      ],
      "docs": "docs/user-guide/sharing.md"
    },
    {
      "id": "sanitizer",
      "summary": "Block/risky lists and size limits for all untrusted steps",
      "keyFiles": [
        "src/lib/sanitize.ts"
      ],
      "docs": "docs/concepts/safety-model.md"
    },
    {
      "id": "ai-planner",
      "summary": "POST /api/plan: OpenAI Responses API with Structured Outputs, rule-based fallback",
      "keyFiles": [
        "src/app/api/plan/route.ts",
        "src/lib/ai/openai.ts",
        "src/lib/ai/schema.ts",
        "src/lib/ai/plan.ts",
        "src/lib/ai/fallback.ts",
        "src/lib/ai/types.ts",
        "src/components/agent-panel.tsx"
      ],
      "docs": "docs/architecture/ai-planner.md"
    },
    {
      "id": "api-hardening",
      "summary": "Env validation, JSON body limits, rate limits, security headers",
      "keyFiles": [
        "src/lib/server/env.ts",
        "src/lib/server/http.ts",
        "src/lib/server/rate-limit.ts",
        "src/lib/rate-limit.ts",
        "src/lib/security-headers.ts",
        "next.config.ts",
        "public/_headers"
      ],
      "docs": "docs/architecture/api-hardening.md"
    },
    {
      "id": "ui-framework",
      "summary": "Design tokens, NVX UI components, tool logos, /design style guide; animated brand mascot and generated brand assets (favicon, app icons, OG image)",
      "keyFiles": [
        "src/app/tokens.css",
        "src/app/globals.css",
        "src/lib/design-tokens.ts",
        "src/components/ui/index.ts",
        "src/components/brand/tool-icon.tsx",
        "src/components/design-system.tsx",
        "src/components/brand/mascot.tsx",
        "scripts/gen-brand-assets.py",
        "assets/brand/nvx-logo-master.png",
        "src/app/manifest.ts"
      ],
      "docs": "docs/architecture/ui-framework.md"
    },
    {
      "id": "builder-ui",
      "summary": "4-step builder, catalog, template detail, command palette, i18n and theme",
      "keyFiles": [
        "src/components/builder.tsx",
        "src/components/sortable-steps.tsx",
        "src/components/catalog.tsx",
        "src/components/template-detail.tsx",
        "src/components/command-palette.tsx",
        "src/components/prefs.tsx",
        "src/lib/i18n.ts"
      ],
      "docs": "docs/user-guide/builder.md"
    },
    {
      "id": "cloudflare-runtime",
      "summary": "Worker config, OpenNext adapter and patch",
      "keyFiles": [
        "wrangler.jsonc",
        "open-next.config.ts",
        "cloudflare-env.d.ts",
        "scripts/patch-opennext.mjs"
      ],
      "docs": "docs/architecture/cloudflare-runtime.md"
    },
    {
      "id": "docs",
      "summary": "Documentation site and checker",
      "keyFiles": [
        "docs/README.md",
        "scripts/docs-check.mjs",
        "tests/docs-check.test.ts",
        "AGENTS.md"
      ],
      "docs": "docs/contributing/docs-maintenance.md"
    },
    {
      "id": "docs-site",
      "summary": "In-app docs at /docs: docs/**/*.md compiled at build time (no runtime fs) into sanitized HTML + raw Markdown; raw .md routes, llms.txt, client search, Mermaid pre-rendered to SVG",
      "keyFiles": [
        "scripts/build-docs.mjs",
        "scripts/render-diagrams.mjs",
        "src/lib/docs.ts",
        "src/lib/docs-search.ts",
        "src/app/docs/layout.tsx",
        "src/app/docs/page.tsx",
        "src/app/docs/[...slug]/page.tsx",
        "src/app/docs/raw/[...slug]/route.ts",
        "src/app/llms.txt/route.ts",
        "src/app/llms-full.txt/route.ts",
        "src/components/docs/docs-shell.tsx",
        "src/components/docs/doc-view.tsx",
        "src/components/docs/doc-article.tsx",
        "src/components/docs/doc-toc.tsx",
        "tests/docs-site.test.ts"
      ],
      "docs": "docs/architecture/docs-site.md"
    },
    {
      "id": "chat-data-model",
      "summary": "D1 database nvx-db (binding DB) with chat-history schema: users, conversations, messages, attachments (R2 keys), api_clients (hashed API keys). Schema only; no endpoints/UI yet. R2 bucket nvx-assets pending (R2 not enabled on account).",
      "keyFiles": [
        "migrations/0001_schema_meta.sql",
        "migrations/0002_chat_history.sql",
        "wrangler.jsonc"
      ],
      "docs": "docs/architecture/chat-data-model.md"
    }
  ],
  "templateIds": [
    "nextjs-dashboard",
    "vite-react-game",
    "express-api",
    "fastapi-ai",
    "streamlit-dashboard",
    "node-cli-npx",
    "pypi-package",
    "collab-workspace",
    "react-admin-tool",
    "nextjs-ai-chat"
  ],
  "routes": [
    {
      "path": "/",
      "file": "src/app/page.tsx"
    },
    {
      "path": "/templates",
      "file": "src/app/templates/page.tsx"
    },
    {
      "path": "/templates/[id]",
      "file": "src/app/templates/[id]/page.tsx",
      "notes": "unknown ids return real 404 via next.config.ts rewrite"
    },
    {
      "path": "/builder",
      "file": "src/app/builder/page.tsx",
      "notes": "hash #s=<token> opens Review, #t=<id> opens Configure, #pick opens picker"
    },
    {
      "path": "/design",
      "file": "src/app/design/page.tsx"
    },
    {
      "path": "/docs",
      "file": "src/app/docs/page.tsx",
      "notes": "docs landing rendered from docs/README.md"
    },
    {
      "path": "/docs/[...slug]",
      "file": "src/app/docs/[...slug]/page.tsx",
      "notes": "one page per docs/**/*.md (lower-case path without .md); unknown slugs return real 404 via next.config.ts rewrite"
    },
    {
      "path": "/docs/<slug>.md",
      "file": "src/app/docs/raw/[...slug]/route.ts",
      "notes": "exact raw Markdown, text/markdown; /docs/index.md = docs/README.md; rewritten to /docs/raw/<slug>"
    },
    {
      "path": "/llms.txt",
      "file": "src/app/llms.txt/route.ts",
      "notes": "llmstxt.org index of every raw docs URL"
    },
    {
      "path": "/llms-full.txt",
      "file": "src/app/llms-full.txt/route.ts",
      "notes": "all docs concatenated"
    }
  ],
  "endpoints": [
    {
      "method": "GET",
      "path": "/api/plan",
      "purpose": "capabilities: whether server AI is available",
      "docs": "docs/reference/api-plan.md"
    },
    {
      "method": "POST",
      "path": "/api/plan",
      "purpose": "prompt -> sanitized plan (ai or fallback)",
      "bodyLimitBytes": 16384,
      "statusCodes": [
        200,
        400,
        413,
        415,
        429
      ],
      "docs": "docs/reference/api-plan.md"
    },
    {
      "method": "GET",
      "path": "/manifest.webmanifest",
      "purpose": "web app manifest (src/app/manifest.ts)"
    },
    {
      "method": "GET",
      "path": "/opengraph-image.png",
      "purpose": "Open Graph card 1200x630"
    }
  ],
  "commands": {
    "install": "npm install",
    "dev": "npm run dev",
    "preview": "npm run preview",
    "lint": "npm run lint",
    "typecheck": "npm run typecheck",
    "test": "npm test",
    "docsCheck": "npm run docs:check",
    "build": "npm run build",
    "cfBuild": "npm run cf:build",
    "export": "npm run export -- <templateId> --out <dir>",
    "deploy": "npm run deploy  # REQUIRES HUMAN APPROVAL",
    "docsBundle": "npm run docs:bundle  # also runs automatically before dev/build/test/typecheck",
    "docsDiagrams": "PLAYWRIGHT_DIR=/tmp/pw npm run docs:diagrams  # after editing a Mermaid block",
    "dbMigrateLocal": "npm run db:migrate:local",
    "dbMigrateRemote": "npm run db:migrate:remote  # REQUIRES HUMAN APPROVAL"
  },
  "env": [
    {
      "name": "OPENAI_API_KEY",
      "secret": true,
      "default": null,
      "set": "wrangler secret put (stdin) / .dev.vars"
    },
    {
      "name": "OPENAI_MODEL",
      "secret": false,
      "default": "gpt-6.1-sol"
    },
    {
      "name": "OPENAI_MAX_OUTPUT_TOKENS",
      "secret": false,
      "default": "6000",
      "range": "512-16000"
    },
    {
      "name": "OPENAI_TIMEOUT_MS",
      "secret": false,
      "default": "60000",
      "range": "5000-120000",
      "wrangler": "75000"
    },
    {
      "name": "PLAN_AI_LIMIT_PER_MIN",
      "secret": false,
      "default": "5",
      "notes": "in-memory fallback limiter"
    },
    {
      "name": "PLAN_LIMIT_PER_MIN",
      "secret": false,
      "default": "20",
      "notes": "in-memory fallback limiter"
    },
    {
      "name": "NEXT_PUBLIC_SITE_URL",
      "secret": false,
      "default": "https://devstack.bid",
      "notes": "build-time metadataBase for og:image / twitter:image"
    },
    {
      "name": "NEXT_PUBLIC_REPO_URL",
      "secret": false,
      "default": null,
      "notes": "build-time; https repo URL enables 'Edit on GitHub' and GitHub links to source files in /docs"
    }
  ],
  "bindings": [
    {
      "name": "NVX_PLAN_AI_LIMITER",
      "type": "ratelimit",
      "namespaceId": "4711",
      "limit": "5/60s per IP"
    },
    {
      "name": "NVX_PLAN_LIMITER",
      "type": "ratelimit",
      "namespaceId": "4712",
      "limit": "20/60s per IP"
    },
    {
      "name": "ASSETS",
      "type": "assets"
    },
    {
      "name": "WORKER_SELF_REFERENCE",
      "type": "service",
      "service": "nvx-stack-builder"
    },
    {
      "name": "DB",
      "type": "d1",
      "databaseName": "nvx-db",
      "databaseId": "3ee9bbab-06b5-49da-b175-5f7162ad5086",
      "migrationsDir": "migrations"
    }
  ],
  "deployTarget": {
    "environment": "production",
    "worker": "nvx-stack-builder",
    "url": "https://devstack.bid",
    "customDomains": [
      {
        "hostname": "devstack.bid",
        "id": "8a5d7eb2f2cfa18393ac30447b9f6c65f5f83a3f",
        "certId": "f16d512e-25fd-4b1f-8cc8-e1b91d33ee43"
      },
      {
        "hostname": "www.devstack.bid",
        "id": "b58b3b3a650e9363bb329b327445d2a12a2f446a",
        "certId": "960b36e2-0c90-442a-910b-b40abe83927d",
        "behaviour": "308 redirect to https://devstack.bid (next.config.ts)"
      }
    ],
    "zone": {
      "name": "devstack.bid",
      "id": "f5ceb4b6eae9aad8aafccf24c350ae1e",
      "dnsRecords": [
        "AAAA devstack.bid 100:: proxied (managed by custom domain)",
        "AAAA www.devstack.bid 100:: proxied (managed by custom domain)"
      ]
    },
    "workersDevUrl": "https://nvx-stack-builder.examplessdk.workers.dev",
    "workersDevSubdomain": "examplessdk",
    "accountId": "2d92bd5b25768fa9093d6adc0a8887fc",
    "accountName": "Examplessdk@gmail.com's Account",
    "deployedVersion": "v0.6.0 + D1 binding (feat/d1-chat-schema b90ca11)",
    "currentVersionId": "450890b7-5432-4795-afbc-1c7ebd241bff",
    "previousVersionId": "7ddd9404-a31f-4e31-8460-82b3b90c7d0e",
    "olderVersionIds": [
      "671b6b3b-1074-40cb-84b0-0df2681b69ce",
      "d369f2b6-863a-4e44-8f9e-b5551e18361a",
      "107ab78e-2cdd-4159-95e7-e8fcb89130aa"
    ],
    "hsts": "max-age=31536000 (no includeSubDomains/preload)",
    "otherWorkersInAccount": [
      "odd-violet-5e66 (not ours, never modify)"
    ],
    "tokenNotes": "Attaching custom domains needs one token with Account Workers Scripts:Edit + zone access; CLOUDFLARE_API_TOKEN_DEVSTACK lacks Workers Scripts, CLOUDFLARE_API_TOKEN_EXAMPLESSDK worked.",
    "d1": {
      "database": "nvx-db",
      "id": "3ee9bbab-06b5-49da-b175-5f7162ad5086",
      "region": "WNAM",
      "appliedMigrations": [
        "0001_schema_meta.sql",
        "0002_chat_history.sql"
      ]
    },
    "r2": "not created: R2 not enabled on account (error 10042); needs owner to enable in dashboard + token with Workers R2 Storage:Edit"
  },
  "invariants": [
    "Commands are text only; the server never executes them",
    "Never print or commit secrets (.dev.vars, .env.local, API keys, Cloudflare tokens)",
    "Deploy, push, merge to main, tags, domains/routes/DNS, and deleting or modifying Cloudflare resources require explicit human approval",
    "Never touch other Workers, other DNS records, or the zone agents-sdk.space; devstack.bid custom domains are approved for nvx-stack-builder only",
    "Keep the existing page structure/layout; restyle only via tokens and classes unless approved",
    "Both themes pass WCAG AA contrast tests; no emoji in src/; all UI text bilingual",
    "Docs updated with code; npm run docs:check passes"
  ],
  "docs": {
    "index": "docs/README.md",
    "playbook": "docs/agents/AGENT-PLAYBOOK.md",
    "history": "docs/history/SUBSYSTEM-HISTORY.md",
    "deploy": "docs/DEPLOY.md",
    "d1Schema": "docs/reference/d1-schema.md",
    "d1Operations": "docs/operations/d1-database.md"
  },
  "previousDeployments": [
    {
      "environment": "test",
      "url": "https://nvx-stack-builder.space6.workers.dev",
      "deployedVersion": "v0.5.0",
      "status": "URL retired: account workers.dev subdomain renamed space6 -> examplessdk"
    },
    {
      "environment": "test",
      "worker": "nvx-stack-builder",
      "url": "https://nvx-stack-builder.agen-sdk-work.workers.dev",
      "accountId": "f70d35188a3c56b9781538c73a86e04e",
      "deployedVersion": "v0.3.0",
      "currentVersionId": "0fb9ecd4-d788-468c-8843-559545c357e3",
      "previousVersionId": "9b9b678a-f0b4-4727-96d7-e5f81fc00391",
      "status": "live, intentionally left untouched"
    }
  ]
}
