@cherishxn/agent-scaffold 0.0.0-stage → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +99 -2
- package/THIRD_PARTY_NOTICES.md +18 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +105 -0
- package/dist/diagnostics.d.ts +10 -0
- package/dist/diagnostics.js +27 -0
- package/dist/generate.d.ts +55 -0
- package/dist/generate.js +159 -0
- package/dist/model.d.ts +33 -0
- package/dist/model.js +24 -0
- package/dist/verify.d.ts +67 -0
- package/dist/verify.js +278 -0
- package/package.json +52 -4
- package/schemas/manifest.json +171 -0
- package/schemas/plan.json +164 -0
- package/schemas/result.json +97 -0
- package/schemas/spec.json +50 -0
- package/skills/scaffold-use/SKILL.md +24 -0
- package/templates/catalog.json +37 -0
- package/templates/next-fullstack-antd/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/next-fullstack-antd/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/next-fullstack-antd/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/next-fullstack-antd/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/next-fullstack-antd/.dockerignore +18 -0
- package/templates/next-fullstack-antd/.env.example +13 -0
- package/templates/next-fullstack-antd/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/next-fullstack-antd/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/next-fullstack-antd/.scaffold-checks.json +7 -0
- package/templates/next-fullstack-antd/AGENTS.md +11 -0
- package/templates/next-fullstack-antd/CLAUDE.md +1 -0
- package/templates/next-fullstack-antd/DESIGN.md +208 -0
- package/templates/next-fullstack-antd/LICENSE +21 -0
- package/templates/next-fullstack-antd/README.md +64 -0
- package/templates/next-fullstack-antd/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/next-fullstack-antd/compose.yaml +18 -0
- package/templates/next-fullstack-antd/design/guide.md +61 -0
- package/templates/next-fullstack-antd/design/layout.css +6 -0
- package/templates/next-fullstack-antd/design/structure.json +107 -0
- package/templates/next-fullstack-antd/design/tokens.json +171 -0
- package/templates/next-fullstack-antd/design/widgets.css +30 -0
- package/templates/next-fullstack-antd/design/widgets.json +233 -0
- package/templates/next-fullstack-antd/docs/PROJECT.md +32 -0
- package/templates/next-fullstack-antd/docs/api.d.ts +544 -0
- package/templates/next-fullstack-antd/docs/openapi.json +461 -0
- package/templates/next-fullstack-antd/gitignore.template +19 -0
- package/templates/next-fullstack-antd/licenses/fastapi.txt +21 -0
- package/templates/next-fullstack-antd/licenses/nest.txt +22 -0
- package/templates/next-fullstack-antd/licenses/next.txt +21 -0
- package/templates/next-fullstack-antd/licenses/shadcn.txt +21 -0
- package/templates/next-fullstack-antd/licenses/sources.json +27 -0
- package/templates/next-fullstack-antd/licenses/spring.txt +202 -0
- package/templates/next-fullstack-antd/package-lock.json +494 -0
- package/templates/next-fullstack-antd/package.json +26 -0
- package/templates/next-fullstack-antd/playwright.config.ts +3 -0
- package/templates/next-fullstack-antd/project.json +8 -0
- package/templates/next-fullstack-antd/scripts/api-check.mjs +18 -0
- package/templates/next-fullstack-antd/scripts/api-contract.mjs +46 -0
- package/templates/next-fullstack-antd/scripts/design-coverage.mjs +20 -0
- package/templates/next-fullstack-antd/scripts/design-next-cleanup.mjs +13 -0
- package/templates/next-fullstack-antd/scripts/design-verify.mjs +154 -0
- package/templates/next-fullstack-antd/scripts/design.mjs +108 -0
- package/templates/next-fullstack-antd/scripts/project.mjs +120 -0
- package/templates/next-fullstack-antd/tests/contract-client.ts +20 -0
- package/templates/next-fullstack-antd/tests/contract.spec.ts +49 -0
- package/templates/next-fullstack-antd/tests/design/harness.tsx +63 -0
- package/templates/next-fullstack-antd/tests/ui.spec.ts +61 -0
- package/templates/next-fullstack-antd/web/Dockerfile +12 -0
- package/templates/next-fullstack-antd/web/app/api/auth/login/route.ts +1 -0
- package/templates/next-fullstack-antd/web/app/api/auth/logout/route.ts +1 -0
- package/templates/next-fullstack-antd/web/app/api/auth/me/route.ts +1 -0
- package/templates/next-fullstack-antd/web/app/api/health/route.ts +1 -0
- package/templates/next-fullstack-antd/web/app/api/records/[id]/route.ts +5 -0
- package/templates/next-fullstack-antd/web/app/api/records/route.ts +3 -0
- package/templates/next-fullstack-antd/web/app/layout.tsx +5 -0
- package/templates/next-fullstack-antd/web/app/page.tsx +2 -0
- package/templates/next-fullstack-antd/web/eslint.config.mjs +3 -0
- package/templates/next-fullstack-antd/web/lib/api.ts +35 -0
- package/templates/next-fullstack-antd/web/lib/auth.ts +10 -0
- package/templates/next-fullstack-antd/web/lib/db.ts +3 -0
- package/templates/next-fullstack-antd/web/lib/session.test.ts +15 -0
- package/templates/next-fullstack-antd/web/lib/validation.test.ts +3 -0
- package/templates/next-fullstack-antd/web/lib/validation.ts +5 -0
- package/templates/next-fullstack-antd/web/next-env.d.ts +7 -0
- package/templates/next-fullstack-antd/web/next.config.ts +3 -0
- package/templates/next-fullstack-antd/web/package.json +35 -0
- package/templates/next-fullstack-antd/web/pnpm-lock.yaml +3756 -0
- package/templates/next-fullstack-antd/web/pnpm-workspace.yaml +7 -0
- package/templates/next-fullstack-antd/web/prisma/migrations/202610190001_initial/migration.sql +99 -0
- package/templates/next-fullstack-antd/web/prisma/migrations/migration_lock.toml +1 -0
- package/templates/next-fullstack-antd/web/prisma/schema.prisma +72 -0
- package/templates/next-fullstack-antd/web/scripts/seed.ts +4 -0
- package/templates/next-fullstack-antd/web/src/App.tsx +29 -0
- package/templates/next-fullstack-antd/web/src/design-layout.css +7 -0
- package/templates/next-fullstack-antd/web/src/design-runtime.json +511 -0
- package/templates/next-fullstack-antd/web/src/design-tokens.css +168 -0
- package/templates/next-fullstack-antd/web/src/design-widgets.css +31 -0
- package/templates/next-fullstack-antd/web/src/structure-view.tsx +16 -0
- package/templates/next-fullstack-antd/web/src/styles.css +3 -0
- package/templates/next-fullstack-antd/web/src/ui.tsx +30 -0
- package/templates/next-fullstack-antd/web/src/widget-icon.tsx +5 -0
- package/templates/next-fullstack-antd/web/src/widget-types.ts +13 -0
- package/templates/next-fullstack-antd/web/src/workspace-model.ts +85 -0
- package/templates/next-fullstack-antd/web/tsconfig.json +42 -0
- package/templates/next-fullstack-antd/web/vitest.config.ts +2 -0
- package/templates/next-fullstack-shadcn/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/next-fullstack-shadcn/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/next-fullstack-shadcn/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/next-fullstack-shadcn/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/next-fullstack-shadcn/.dockerignore +18 -0
- package/templates/next-fullstack-shadcn/.env.example +13 -0
- package/templates/next-fullstack-shadcn/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/next-fullstack-shadcn/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/next-fullstack-shadcn/.scaffold-checks.json +7 -0
- package/templates/next-fullstack-shadcn/AGENTS.md +11 -0
- package/templates/next-fullstack-shadcn/CLAUDE.md +1 -0
- package/templates/next-fullstack-shadcn/DESIGN.md +208 -0
- package/templates/next-fullstack-shadcn/LICENSE +21 -0
- package/templates/next-fullstack-shadcn/README.md +64 -0
- package/templates/next-fullstack-shadcn/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/next-fullstack-shadcn/compose.yaml +18 -0
- package/templates/next-fullstack-shadcn/design/guide.md +61 -0
- package/templates/next-fullstack-shadcn/design/layout.css +6 -0
- package/templates/next-fullstack-shadcn/design/structure.json +107 -0
- package/templates/next-fullstack-shadcn/design/tokens.json +171 -0
- package/templates/next-fullstack-shadcn/design/widgets.css +30 -0
- package/templates/next-fullstack-shadcn/design/widgets.json +233 -0
- package/templates/next-fullstack-shadcn/docs/PROJECT.md +32 -0
- package/templates/next-fullstack-shadcn/docs/api.d.ts +544 -0
- package/templates/next-fullstack-shadcn/docs/openapi.json +461 -0
- package/templates/next-fullstack-shadcn/gitignore.template +19 -0
- package/templates/next-fullstack-shadcn/licenses/fastapi.txt +21 -0
- package/templates/next-fullstack-shadcn/licenses/nest.txt +22 -0
- package/templates/next-fullstack-shadcn/licenses/next.txt +21 -0
- package/templates/next-fullstack-shadcn/licenses/shadcn.txt +21 -0
- package/templates/next-fullstack-shadcn/licenses/sources.json +27 -0
- package/templates/next-fullstack-shadcn/licenses/spring.txt +202 -0
- package/templates/next-fullstack-shadcn/package-lock.json +494 -0
- package/templates/next-fullstack-shadcn/package.json +26 -0
- package/templates/next-fullstack-shadcn/playwright.config.ts +3 -0
- package/templates/next-fullstack-shadcn/project.json +8 -0
- package/templates/next-fullstack-shadcn/scripts/api-check.mjs +18 -0
- package/templates/next-fullstack-shadcn/scripts/api-contract.mjs +46 -0
- package/templates/next-fullstack-shadcn/scripts/design-coverage.mjs +20 -0
- package/templates/next-fullstack-shadcn/scripts/design-next-cleanup.mjs +13 -0
- package/templates/next-fullstack-shadcn/scripts/design-verify.mjs +154 -0
- package/templates/next-fullstack-shadcn/scripts/design.mjs +108 -0
- package/templates/next-fullstack-shadcn/scripts/project.mjs +120 -0
- package/templates/next-fullstack-shadcn/tests/contract-client.ts +20 -0
- package/templates/next-fullstack-shadcn/tests/contract.spec.ts +49 -0
- package/templates/next-fullstack-shadcn/tests/design/harness.tsx +63 -0
- package/templates/next-fullstack-shadcn/tests/ui.spec.ts +61 -0
- package/templates/next-fullstack-shadcn/web/Dockerfile +12 -0
- package/templates/next-fullstack-shadcn/web/app/api/auth/login/route.ts +1 -0
- package/templates/next-fullstack-shadcn/web/app/api/auth/logout/route.ts +1 -0
- package/templates/next-fullstack-shadcn/web/app/api/auth/me/route.ts +1 -0
- package/templates/next-fullstack-shadcn/web/app/api/health/route.ts +1 -0
- package/templates/next-fullstack-shadcn/web/app/api/records/[id]/route.ts +5 -0
- package/templates/next-fullstack-shadcn/web/app/api/records/route.ts +3 -0
- package/templates/next-fullstack-shadcn/web/app/layout.tsx +4 -0
- package/templates/next-fullstack-shadcn/web/app/page.tsx +2 -0
- package/templates/next-fullstack-shadcn/web/eslint.config.mjs +3 -0
- package/templates/next-fullstack-shadcn/web/lib/api.ts +35 -0
- package/templates/next-fullstack-shadcn/web/lib/auth.ts +10 -0
- package/templates/next-fullstack-shadcn/web/lib/db.ts +3 -0
- package/templates/next-fullstack-shadcn/web/lib/session.test.ts +15 -0
- package/templates/next-fullstack-shadcn/web/lib/validation.test.ts +3 -0
- package/templates/next-fullstack-shadcn/web/lib/validation.ts +5 -0
- package/templates/next-fullstack-shadcn/web/next-env.d.ts +7 -0
- package/templates/next-fullstack-shadcn/web/next.config.ts +3 -0
- package/templates/next-fullstack-shadcn/web/package.json +39 -0
- package/templates/next-fullstack-shadcn/web/pnpm-lock.yaml +3286 -0
- package/templates/next-fullstack-shadcn/web/pnpm-workspace.yaml +7 -0
- package/templates/next-fullstack-shadcn/web/postcss.config.mjs +1 -0
- package/templates/next-fullstack-shadcn/web/prisma/migrations/202610190001_initial/migration.sql +99 -0
- package/templates/next-fullstack-shadcn/web/prisma/migrations/migration_lock.toml +1 -0
- package/templates/next-fullstack-shadcn/web/prisma/schema.prisma +72 -0
- package/templates/next-fullstack-shadcn/web/scripts/seed.ts +4 -0
- package/templates/next-fullstack-shadcn/web/src/App.tsx +30 -0
- package/templates/next-fullstack-shadcn/web/src/design-layout.css +7 -0
- package/templates/next-fullstack-shadcn/web/src/design-runtime.json +511 -0
- package/templates/next-fullstack-shadcn/web/src/design-tokens.css +168 -0
- package/templates/next-fullstack-shadcn/web/src/design-widgets.css +31 -0
- package/templates/next-fullstack-shadcn/web/src/structure-view.tsx +16 -0
- package/templates/next-fullstack-shadcn/web/src/styles.css +3 -0
- package/templates/next-fullstack-shadcn/web/src/tailwind.css +2 -0
- package/templates/next-fullstack-shadcn/web/src/ui.tsx +13 -0
- package/templates/next-fullstack-shadcn/web/src/widget-icon.tsx +5 -0
- package/templates/next-fullstack-shadcn/web/src/widget-types.ts +13 -0
- package/templates/next-fullstack-shadcn/web/src/workspace-model.ts +85 -0
- package/templates/next-fullstack-shadcn/web/tsconfig.json +42 -0
- package/templates/next-fullstack-shadcn/web/vitest.config.ts +2 -0
- package/templates/react-fastapi-antd/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/react-fastapi-antd/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/react-fastapi-antd/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/react-fastapi-antd/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/react-fastapi-antd/.dockerignore +18 -0
- package/templates/react-fastapi-antd/.env.example +13 -0
- package/templates/react-fastapi-antd/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/react-fastapi-antd/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/react-fastapi-antd/.scaffold-checks.json +7 -0
- package/templates/react-fastapi-antd/AGENTS.md +11 -0
- package/templates/react-fastapi-antd/CLAUDE.md +1 -0
- package/templates/react-fastapi-antd/DESIGN.md +208 -0
- package/templates/react-fastapi-antd/LICENSE +21 -0
- package/templates/react-fastapi-antd/README.md +64 -0
- package/templates/react-fastapi-antd/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/react-fastapi-antd/backend/.python-version +1 -0
- package/templates/react-fastapi-antd/backend/Dockerfile +10 -0
- package/templates/react-fastapi-antd/backend/alembic.ini +3 -0
- package/templates/react-fastapi-antd/backend/app/__init__.py +0 -0
- package/templates/react-fastapi-antd/backend/app/core/__init__.py +0 -0
- package/templates/react-fastapi-antd/backend/app/core/security.py +25 -0
- package/templates/react-fastapi-antd/backend/app/db.py +11 -0
- package/templates/react-fastapi-antd/backend/app/main.py +146 -0
- package/templates/react-fastapi-antd/backend/app/models.py +21 -0
- package/templates/react-fastapi-antd/backend/app/seed.py +21 -0
- package/templates/react-fastapi-antd/backend/migrations/env.py +9 -0
- package/templates/react-fastapi-antd/backend/migrations/versions/0001_initial.py +18 -0
- package/templates/react-fastapi-antd/backend/pyproject.toml +16 -0
- package/templates/react-fastapi-antd/backend/tests/test_api.py +27 -0
- package/templates/react-fastapi-antd/backend/uv.lock +1085 -0
- package/templates/react-fastapi-antd/compose.yaml +18 -0
- package/templates/react-fastapi-antd/design/guide.md +61 -0
- package/templates/react-fastapi-antd/design/layout.css +6 -0
- package/templates/react-fastapi-antd/design/structure.json +107 -0
- package/templates/react-fastapi-antd/design/tokens.json +171 -0
- package/templates/react-fastapi-antd/design/widgets.css +30 -0
- package/templates/react-fastapi-antd/design/widgets.json +233 -0
- package/templates/react-fastapi-antd/docs/PROJECT.md +32 -0
- package/templates/react-fastapi-antd/docs/api.d.ts +544 -0
- package/templates/react-fastapi-antd/docs/openapi.json +461 -0
- package/templates/react-fastapi-antd/gitignore.template +19 -0
- package/templates/react-fastapi-antd/licenses/fastapi.txt +21 -0
- package/templates/react-fastapi-antd/licenses/nest.txt +22 -0
- package/templates/react-fastapi-antd/licenses/next.txt +21 -0
- package/templates/react-fastapi-antd/licenses/shadcn.txt +21 -0
- package/templates/react-fastapi-antd/licenses/sources.json +27 -0
- package/templates/react-fastapi-antd/licenses/spring.txt +202 -0
- package/templates/react-fastapi-antd/package-lock.json +494 -0
- package/templates/react-fastapi-antd/package.json +26 -0
- package/templates/react-fastapi-antd/playwright.config.ts +3 -0
- package/templates/react-fastapi-antd/project.json +8 -0
- package/templates/react-fastapi-antd/scripts/api-check.mjs +18 -0
- package/templates/react-fastapi-antd/scripts/api-contract.mjs +46 -0
- package/templates/react-fastapi-antd/scripts/design-coverage.mjs +20 -0
- package/templates/react-fastapi-antd/scripts/design-next-cleanup.mjs +13 -0
- package/templates/react-fastapi-antd/scripts/design-verify.mjs +154 -0
- package/templates/react-fastapi-antd/scripts/design.mjs +108 -0
- package/templates/react-fastapi-antd/scripts/project.mjs +120 -0
- package/templates/react-fastapi-antd/tests/contract-client.ts +20 -0
- package/templates/react-fastapi-antd/tests/contract.spec.ts +49 -0
- package/templates/react-fastapi-antd/tests/design/harness.tsx +63 -0
- package/templates/react-fastapi-antd/tests/ui.spec.ts +61 -0
- package/templates/react-fastapi-antd/web/bun.lock +442 -0
- package/templates/react-fastapi-antd/web/eslint.config.mjs +3 -0
- package/templates/react-fastapi-antd/web/index.html +1 -0
- package/templates/react-fastapi-antd/web/package.json +28 -0
- package/templates/react-fastapi-antd/web/src/App.tsx +29 -0
- package/templates/react-fastapi-antd/web/src/design-layout.css +7 -0
- package/templates/react-fastapi-antd/web/src/design-runtime.json +511 -0
- package/templates/react-fastapi-antd/web/src/design-tokens.css +168 -0
- package/templates/react-fastapi-antd/web/src/design-widgets.css +31 -0
- package/templates/react-fastapi-antd/web/src/main.tsx +6 -0
- package/templates/react-fastapi-antd/web/src/structure-view.tsx +16 -0
- package/templates/react-fastapi-antd/web/src/styles.css +3 -0
- package/templates/react-fastapi-antd/web/src/ui.tsx +30 -0
- package/templates/react-fastapi-antd/web/src/widget-icon.tsx +5 -0
- package/templates/react-fastapi-antd/web/src/widget-types.ts +13 -0
- package/templates/react-fastapi-antd/web/src/workspace-model.ts +85 -0
- package/templates/react-fastapi-antd/web/tsconfig.json +22 -0
- package/templates/react-fastapi-antd/web/vite.config.ts +3 -0
- package/templates/react-fastapi-shadcn/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/react-fastapi-shadcn/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/react-fastapi-shadcn/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/react-fastapi-shadcn/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/react-fastapi-shadcn/.dockerignore +18 -0
- package/templates/react-fastapi-shadcn/.env.example +13 -0
- package/templates/react-fastapi-shadcn/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/react-fastapi-shadcn/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/react-fastapi-shadcn/.scaffold-checks.json +7 -0
- package/templates/react-fastapi-shadcn/AGENTS.md +11 -0
- package/templates/react-fastapi-shadcn/CLAUDE.md +1 -0
- package/templates/react-fastapi-shadcn/DESIGN.md +208 -0
- package/templates/react-fastapi-shadcn/LICENSE +21 -0
- package/templates/react-fastapi-shadcn/README.md +64 -0
- package/templates/react-fastapi-shadcn/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/react-fastapi-shadcn/backend/.python-version +1 -0
- package/templates/react-fastapi-shadcn/backend/Dockerfile +10 -0
- package/templates/react-fastapi-shadcn/backend/alembic.ini +3 -0
- package/templates/react-fastapi-shadcn/backend/app/__init__.py +0 -0
- package/templates/react-fastapi-shadcn/backend/app/core/__init__.py +0 -0
- package/templates/react-fastapi-shadcn/backend/app/core/security.py +25 -0
- package/templates/react-fastapi-shadcn/backend/app/db.py +11 -0
- package/templates/react-fastapi-shadcn/backend/app/main.py +146 -0
- package/templates/react-fastapi-shadcn/backend/app/models.py +21 -0
- package/templates/react-fastapi-shadcn/backend/app/seed.py +21 -0
- package/templates/react-fastapi-shadcn/backend/migrations/env.py +9 -0
- package/templates/react-fastapi-shadcn/backend/migrations/versions/0001_initial.py +18 -0
- package/templates/react-fastapi-shadcn/backend/pyproject.toml +16 -0
- package/templates/react-fastapi-shadcn/backend/tests/test_api.py +27 -0
- package/templates/react-fastapi-shadcn/backend/uv.lock +1085 -0
- package/templates/react-fastapi-shadcn/compose.yaml +18 -0
- package/templates/react-fastapi-shadcn/design/guide.md +61 -0
- package/templates/react-fastapi-shadcn/design/layout.css +6 -0
- package/templates/react-fastapi-shadcn/design/structure.json +107 -0
- package/templates/react-fastapi-shadcn/design/tokens.json +171 -0
- package/templates/react-fastapi-shadcn/design/widgets.css +30 -0
- package/templates/react-fastapi-shadcn/design/widgets.json +233 -0
- package/templates/react-fastapi-shadcn/docs/PROJECT.md +32 -0
- package/templates/react-fastapi-shadcn/docs/api.d.ts +544 -0
- package/templates/react-fastapi-shadcn/docs/openapi.json +461 -0
- package/templates/react-fastapi-shadcn/gitignore.template +19 -0
- package/templates/react-fastapi-shadcn/licenses/fastapi.txt +21 -0
- package/templates/react-fastapi-shadcn/licenses/nest.txt +22 -0
- package/templates/react-fastapi-shadcn/licenses/next.txt +21 -0
- package/templates/react-fastapi-shadcn/licenses/shadcn.txt +21 -0
- package/templates/react-fastapi-shadcn/licenses/sources.json +27 -0
- package/templates/react-fastapi-shadcn/licenses/spring.txt +202 -0
- package/templates/react-fastapi-shadcn/package-lock.json +494 -0
- package/templates/react-fastapi-shadcn/package.json +26 -0
- package/templates/react-fastapi-shadcn/playwright.config.ts +3 -0
- package/templates/react-fastapi-shadcn/project.json +8 -0
- package/templates/react-fastapi-shadcn/scripts/api-check.mjs +18 -0
- package/templates/react-fastapi-shadcn/scripts/api-contract.mjs +46 -0
- package/templates/react-fastapi-shadcn/scripts/design-coverage.mjs +20 -0
- package/templates/react-fastapi-shadcn/scripts/design-next-cleanup.mjs +13 -0
- package/templates/react-fastapi-shadcn/scripts/design-verify.mjs +154 -0
- package/templates/react-fastapi-shadcn/scripts/design.mjs +108 -0
- package/templates/react-fastapi-shadcn/scripts/project.mjs +120 -0
- package/templates/react-fastapi-shadcn/tests/contract-client.ts +20 -0
- package/templates/react-fastapi-shadcn/tests/contract.spec.ts +49 -0
- package/templates/react-fastapi-shadcn/tests/design/harness.tsx +63 -0
- package/templates/react-fastapi-shadcn/tests/ui.spec.ts +61 -0
- package/templates/react-fastapi-shadcn/web/bun.lock +413 -0
- package/templates/react-fastapi-shadcn/web/eslint.config.mjs +3 -0
- package/templates/react-fastapi-shadcn/web/index.html +1 -0
- package/templates/react-fastapi-shadcn/web/package.json +33 -0
- package/templates/react-fastapi-shadcn/web/src/App.tsx +30 -0
- package/templates/react-fastapi-shadcn/web/src/design-layout.css +7 -0
- package/templates/react-fastapi-shadcn/web/src/design-runtime.json +511 -0
- package/templates/react-fastapi-shadcn/web/src/design-tokens.css +168 -0
- package/templates/react-fastapi-shadcn/web/src/design-widgets.css +31 -0
- package/templates/react-fastapi-shadcn/web/src/main.tsx +6 -0
- package/templates/react-fastapi-shadcn/web/src/structure-view.tsx +16 -0
- package/templates/react-fastapi-shadcn/web/src/styles.css +3 -0
- package/templates/react-fastapi-shadcn/web/src/tailwind.css +2 -0
- package/templates/react-fastapi-shadcn/web/src/ui.tsx +13 -0
- package/templates/react-fastapi-shadcn/web/src/widget-icon.tsx +5 -0
- package/templates/react-fastapi-shadcn/web/src/widget-types.ts +13 -0
- package/templates/react-fastapi-shadcn/web/src/workspace-model.ts +85 -0
- package/templates/react-fastapi-shadcn/web/tsconfig.json +22 -0
- package/templates/react-fastapi-shadcn/web/vite.config.ts +4 -0
- package/templates/react-nest-antd/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/react-nest-antd/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/react-nest-antd/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/react-nest-antd/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/react-nest-antd/.dockerignore +18 -0
- package/templates/react-nest-antd/.env.example +13 -0
- package/templates/react-nest-antd/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/react-nest-antd/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/react-nest-antd/.scaffold-checks.json +7 -0
- package/templates/react-nest-antd/AGENTS.md +11 -0
- package/templates/react-nest-antd/CLAUDE.md +1 -0
- package/templates/react-nest-antd/DESIGN.md +208 -0
- package/templates/react-nest-antd/LICENSE +21 -0
- package/templates/react-nest-antd/README.md +64 -0
- package/templates/react-nest-antd/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/react-nest-antd/backend/Dockerfile +12 -0
- package/templates/react-nest-antd/backend/eslint.config.mjs +3 -0
- package/templates/react-nest-antd/backend/jest.config.cjs +1 -0
- package/templates/react-nest-antd/backend/package.json +40 -0
- package/templates/react-nest-antd/backend/pnpm-lock.yaml +5165 -0
- package/templates/react-nest-antd/backend/pnpm-workspace.yaml +6 -0
- package/templates/react-nest-antd/backend/prisma/migrations/202610190001_initial/migration.sql +3 -0
- package/templates/react-nest-antd/backend/prisma/migrations/migration_lock.toml +1 -0
- package/templates/react-nest-antd/backend/prisma/schema.prisma +25 -0
- package/templates/react-nest-antd/backend/scripts/seed.ts +4 -0
- package/templates/react-nest-antd/backend/src/app.module.ts +43 -0
- package/templates/react-nest-antd/backend/src/main.ts +6 -0
- package/templates/react-nest-antd/backend/src/password.ts +3 -0
- package/templates/react-nest-antd/backend/src/validation.ts +7 -0
- package/templates/react-nest-antd/backend/test/api.test.ts +25 -0
- package/templates/react-nest-antd/backend/tsconfig.build.json +15 -0
- package/templates/react-nest-antd/backend/tsconfig.json +17 -0
- package/templates/react-nest-antd/compose.yaml +18 -0
- package/templates/react-nest-antd/design/guide.md +61 -0
- package/templates/react-nest-antd/design/layout.css +6 -0
- package/templates/react-nest-antd/design/structure.json +107 -0
- package/templates/react-nest-antd/design/tokens.json +171 -0
- package/templates/react-nest-antd/design/widgets.css +30 -0
- package/templates/react-nest-antd/design/widgets.json +233 -0
- package/templates/react-nest-antd/docs/PROJECT.md +32 -0
- package/templates/react-nest-antd/docs/api.d.ts +544 -0
- package/templates/react-nest-antd/docs/openapi.json +461 -0
- package/templates/react-nest-antd/gitignore.template +19 -0
- package/templates/react-nest-antd/licenses/fastapi.txt +21 -0
- package/templates/react-nest-antd/licenses/nest.txt +22 -0
- package/templates/react-nest-antd/licenses/next.txt +21 -0
- package/templates/react-nest-antd/licenses/shadcn.txt +21 -0
- package/templates/react-nest-antd/licenses/sources.json +27 -0
- package/templates/react-nest-antd/licenses/spring.txt +202 -0
- package/templates/react-nest-antd/package-lock.json +494 -0
- package/templates/react-nest-antd/package.json +26 -0
- package/templates/react-nest-antd/playwright.config.ts +3 -0
- package/templates/react-nest-antd/project.json +8 -0
- package/templates/react-nest-antd/scripts/api-check.mjs +18 -0
- package/templates/react-nest-antd/scripts/api-contract.mjs +46 -0
- package/templates/react-nest-antd/scripts/design-coverage.mjs +20 -0
- package/templates/react-nest-antd/scripts/design-next-cleanup.mjs +13 -0
- package/templates/react-nest-antd/scripts/design-verify.mjs +154 -0
- package/templates/react-nest-antd/scripts/design.mjs +108 -0
- package/templates/react-nest-antd/scripts/project.mjs +120 -0
- package/templates/react-nest-antd/tests/contract-client.ts +20 -0
- package/templates/react-nest-antd/tests/contract.spec.ts +49 -0
- package/templates/react-nest-antd/tests/design/harness.tsx +63 -0
- package/templates/react-nest-antd/tests/ui.spec.ts +61 -0
- package/templates/react-nest-antd/web/eslint.config.mjs +3 -0
- package/templates/react-nest-antd/web/index.html +1 -0
- package/templates/react-nest-antd/web/package.json +28 -0
- package/templates/react-nest-antd/web/pnpm-lock.yaml +2215 -0
- package/templates/react-nest-antd/web/src/App.tsx +29 -0
- package/templates/react-nest-antd/web/src/design-layout.css +7 -0
- package/templates/react-nest-antd/web/src/design-runtime.json +511 -0
- package/templates/react-nest-antd/web/src/design-tokens.css +168 -0
- package/templates/react-nest-antd/web/src/design-widgets.css +31 -0
- package/templates/react-nest-antd/web/src/main.tsx +6 -0
- package/templates/react-nest-antd/web/src/structure-view.tsx +16 -0
- package/templates/react-nest-antd/web/src/styles.css +3 -0
- package/templates/react-nest-antd/web/src/ui.tsx +30 -0
- package/templates/react-nest-antd/web/src/widget-icon.tsx +5 -0
- package/templates/react-nest-antd/web/src/widget-types.ts +13 -0
- package/templates/react-nest-antd/web/src/workspace-model.ts +85 -0
- package/templates/react-nest-antd/web/tsconfig.json +22 -0
- package/templates/react-nest-antd/web/vite.config.ts +3 -0
- package/templates/react-nest-shadcn/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/react-nest-shadcn/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/react-nest-shadcn/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/react-nest-shadcn/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/react-nest-shadcn/.dockerignore +18 -0
- package/templates/react-nest-shadcn/.env.example +13 -0
- package/templates/react-nest-shadcn/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/react-nest-shadcn/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/react-nest-shadcn/.scaffold-checks.json +7 -0
- package/templates/react-nest-shadcn/AGENTS.md +11 -0
- package/templates/react-nest-shadcn/CLAUDE.md +1 -0
- package/templates/react-nest-shadcn/DESIGN.md +208 -0
- package/templates/react-nest-shadcn/LICENSE +21 -0
- package/templates/react-nest-shadcn/README.md +64 -0
- package/templates/react-nest-shadcn/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/react-nest-shadcn/backend/Dockerfile +12 -0
- package/templates/react-nest-shadcn/backend/eslint.config.mjs +3 -0
- package/templates/react-nest-shadcn/backend/jest.config.cjs +1 -0
- package/templates/react-nest-shadcn/backend/package.json +40 -0
- package/templates/react-nest-shadcn/backend/pnpm-lock.yaml +5165 -0
- package/templates/react-nest-shadcn/backend/pnpm-workspace.yaml +6 -0
- package/templates/react-nest-shadcn/backend/prisma/migrations/202610190001_initial/migration.sql +3 -0
- package/templates/react-nest-shadcn/backend/prisma/migrations/migration_lock.toml +1 -0
- package/templates/react-nest-shadcn/backend/prisma/schema.prisma +25 -0
- package/templates/react-nest-shadcn/backend/scripts/seed.ts +4 -0
- package/templates/react-nest-shadcn/backend/src/app.module.ts +43 -0
- package/templates/react-nest-shadcn/backend/src/main.ts +6 -0
- package/templates/react-nest-shadcn/backend/src/password.ts +3 -0
- package/templates/react-nest-shadcn/backend/src/validation.ts +7 -0
- package/templates/react-nest-shadcn/backend/test/api.test.ts +25 -0
- package/templates/react-nest-shadcn/backend/tsconfig.build.json +15 -0
- package/templates/react-nest-shadcn/backend/tsconfig.json +17 -0
- package/templates/react-nest-shadcn/compose.yaml +18 -0
- package/templates/react-nest-shadcn/design/guide.md +61 -0
- package/templates/react-nest-shadcn/design/layout.css +6 -0
- package/templates/react-nest-shadcn/design/structure.json +107 -0
- package/templates/react-nest-shadcn/design/tokens.json +171 -0
- package/templates/react-nest-shadcn/design/widgets.css +30 -0
- package/templates/react-nest-shadcn/design/widgets.json +233 -0
- package/templates/react-nest-shadcn/docs/PROJECT.md +32 -0
- package/templates/react-nest-shadcn/docs/api.d.ts +544 -0
- package/templates/react-nest-shadcn/docs/openapi.json +461 -0
- package/templates/react-nest-shadcn/gitignore.template +19 -0
- package/templates/react-nest-shadcn/licenses/fastapi.txt +21 -0
- package/templates/react-nest-shadcn/licenses/nest.txt +22 -0
- package/templates/react-nest-shadcn/licenses/next.txt +21 -0
- package/templates/react-nest-shadcn/licenses/shadcn.txt +21 -0
- package/templates/react-nest-shadcn/licenses/sources.json +27 -0
- package/templates/react-nest-shadcn/licenses/spring.txt +202 -0
- package/templates/react-nest-shadcn/package-lock.json +494 -0
- package/templates/react-nest-shadcn/package.json +26 -0
- package/templates/react-nest-shadcn/playwright.config.ts +3 -0
- package/templates/react-nest-shadcn/project.json +8 -0
- package/templates/react-nest-shadcn/scripts/api-check.mjs +18 -0
- package/templates/react-nest-shadcn/scripts/api-contract.mjs +46 -0
- package/templates/react-nest-shadcn/scripts/design-coverage.mjs +20 -0
- package/templates/react-nest-shadcn/scripts/design-next-cleanup.mjs +13 -0
- package/templates/react-nest-shadcn/scripts/design-verify.mjs +154 -0
- package/templates/react-nest-shadcn/scripts/design.mjs +108 -0
- package/templates/react-nest-shadcn/scripts/project.mjs +120 -0
- package/templates/react-nest-shadcn/tests/contract-client.ts +20 -0
- package/templates/react-nest-shadcn/tests/contract.spec.ts +49 -0
- package/templates/react-nest-shadcn/tests/design/harness.tsx +63 -0
- package/templates/react-nest-shadcn/tests/ui.spec.ts +61 -0
- package/templates/react-nest-shadcn/web/eslint.config.mjs +3 -0
- package/templates/react-nest-shadcn/web/index.html +1 -0
- package/templates/react-nest-shadcn/web/package.json +33 -0
- package/templates/react-nest-shadcn/web/pnpm-lock.yaml +1788 -0
- package/templates/react-nest-shadcn/web/src/App.tsx +30 -0
- package/templates/react-nest-shadcn/web/src/design-layout.css +7 -0
- package/templates/react-nest-shadcn/web/src/design-runtime.json +511 -0
- package/templates/react-nest-shadcn/web/src/design-tokens.css +168 -0
- package/templates/react-nest-shadcn/web/src/design-widgets.css +31 -0
- package/templates/react-nest-shadcn/web/src/main.tsx +6 -0
- package/templates/react-nest-shadcn/web/src/structure-view.tsx +16 -0
- package/templates/react-nest-shadcn/web/src/styles.css +3 -0
- package/templates/react-nest-shadcn/web/src/tailwind.css +2 -0
- package/templates/react-nest-shadcn/web/src/ui.tsx +13 -0
- package/templates/react-nest-shadcn/web/src/widget-icon.tsx +5 -0
- package/templates/react-nest-shadcn/web/src/widget-types.ts +13 -0
- package/templates/react-nest-shadcn/web/src/workspace-model.ts +85 -0
- package/templates/react-nest-shadcn/web/tsconfig.json +22 -0
- package/templates/react-nest-shadcn/web/vite.config.ts +4 -0
- package/templates/react-spring-antd/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/react-spring-antd/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/react-spring-antd/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/react-spring-antd/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/react-spring-antd/.dockerignore +18 -0
- package/templates/react-spring-antd/.env.example +13 -0
- package/templates/react-spring-antd/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/react-spring-antd/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/react-spring-antd/.scaffold-checks.json +7 -0
- package/templates/react-spring-antd/AGENTS.md +11 -0
- package/templates/react-spring-antd/CLAUDE.md +1 -0
- package/templates/react-spring-antd/DESIGN.md +208 -0
- package/templates/react-spring-antd/LICENSE +21 -0
- package/templates/react-spring-antd/README.md +64 -0
- package/templates/react-spring-antd/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/react-spring-antd/backend/.mvn/wrapper/maven-wrapper.properties +3 -0
- package/templates/react-spring-antd/backend/Dockerfile +11 -0
- package/templates/react-spring-antd/backend/mvnw +295 -0
- package/templates/react-spring-antd/backend/pom.xml +15 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Api.java +38 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/AppUser.java +11 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Application.java +7 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Errors.java +13 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/PersonalRecord.java +15 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Records.java +14 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Security.java +28 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Seed.java +13 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Users.java +5 -0
- package/templates/react-spring-antd/backend/src/main/resources/application.properties +17 -0
- package/templates/react-spring-antd/backend/src/main/resources/db/migration/V1__initial.sql +3 -0
- package/templates/react-spring-antd/backend/src/main/resources/openapi.json +461 -0
- package/templates/react-spring-antd/backend/src/test/java/dev/scaffold/app/ApiTest.java +28 -0
- package/templates/react-spring-antd/backend/src/test/java/dev/scaffold/app/SessionExpiryTest.java +37 -0
- package/templates/react-spring-antd/compose.yaml +18 -0
- package/templates/react-spring-antd/design/guide.md +61 -0
- package/templates/react-spring-antd/design/layout.css +6 -0
- package/templates/react-spring-antd/design/structure.json +107 -0
- package/templates/react-spring-antd/design/tokens.json +171 -0
- package/templates/react-spring-antd/design/widgets.css +30 -0
- package/templates/react-spring-antd/design/widgets.json +233 -0
- package/templates/react-spring-antd/docs/PROJECT.md +32 -0
- package/templates/react-spring-antd/docs/api.d.ts +544 -0
- package/templates/react-spring-antd/docs/openapi.json +461 -0
- package/templates/react-spring-antd/gitignore.template +19 -0
- package/templates/react-spring-antd/licenses/fastapi.txt +21 -0
- package/templates/react-spring-antd/licenses/nest.txt +22 -0
- package/templates/react-spring-antd/licenses/next.txt +21 -0
- package/templates/react-spring-antd/licenses/shadcn.txt +21 -0
- package/templates/react-spring-antd/licenses/sources.json +27 -0
- package/templates/react-spring-antd/licenses/spring.txt +202 -0
- package/templates/react-spring-antd/package-lock.json +494 -0
- package/templates/react-spring-antd/package.json +26 -0
- package/templates/react-spring-antd/playwright.config.ts +3 -0
- package/templates/react-spring-antd/project.json +8 -0
- package/templates/react-spring-antd/scripts/api-check.mjs +18 -0
- package/templates/react-spring-antd/scripts/api-contract.mjs +46 -0
- package/templates/react-spring-antd/scripts/design-coverage.mjs +20 -0
- package/templates/react-spring-antd/scripts/design-next-cleanup.mjs +13 -0
- package/templates/react-spring-antd/scripts/design-verify.mjs +154 -0
- package/templates/react-spring-antd/scripts/design.mjs +108 -0
- package/templates/react-spring-antd/scripts/project.mjs +120 -0
- package/templates/react-spring-antd/tests/contract-client.ts +20 -0
- package/templates/react-spring-antd/tests/contract.spec.ts +49 -0
- package/templates/react-spring-antd/tests/design/harness.tsx +63 -0
- package/templates/react-spring-antd/tests/ui.spec.ts +61 -0
- package/templates/react-spring-antd/web/eslint.config.mjs +3 -0
- package/templates/react-spring-antd/web/index.html +1 -0
- package/templates/react-spring-antd/web/package.json +28 -0
- package/templates/react-spring-antd/web/pnpm-lock.yaml +2215 -0
- package/templates/react-spring-antd/web/src/App.tsx +29 -0
- package/templates/react-spring-antd/web/src/design-layout.css +7 -0
- package/templates/react-spring-antd/web/src/design-runtime.json +511 -0
- package/templates/react-spring-antd/web/src/design-tokens.css +168 -0
- package/templates/react-spring-antd/web/src/design-widgets.css +31 -0
- package/templates/react-spring-antd/web/src/main.tsx +6 -0
- package/templates/react-spring-antd/web/src/structure-view.tsx +16 -0
- package/templates/react-spring-antd/web/src/styles.css +3 -0
- package/templates/react-spring-antd/web/src/ui.tsx +30 -0
- package/templates/react-spring-antd/web/src/widget-icon.tsx +5 -0
- package/templates/react-spring-antd/web/src/widget-types.ts +13 -0
- package/templates/react-spring-antd/web/src/workspace-model.ts +85 -0
- package/templates/react-spring-antd/web/tsconfig.json +22 -0
- package/templates/react-spring-antd/web/vite.config.ts +3 -0
- package/templates/react-spring-shadcn/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/react-spring-shadcn/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/react-spring-shadcn/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/react-spring-shadcn/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/react-spring-shadcn/.dockerignore +18 -0
- package/templates/react-spring-shadcn/.env.example +13 -0
- package/templates/react-spring-shadcn/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/react-spring-shadcn/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/react-spring-shadcn/.scaffold-checks.json +7 -0
- package/templates/react-spring-shadcn/AGENTS.md +11 -0
- package/templates/react-spring-shadcn/CLAUDE.md +1 -0
- package/templates/react-spring-shadcn/DESIGN.md +208 -0
- package/templates/react-spring-shadcn/LICENSE +21 -0
- package/templates/react-spring-shadcn/README.md +64 -0
- package/templates/react-spring-shadcn/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/react-spring-shadcn/backend/.mvn/wrapper/maven-wrapper.properties +3 -0
- package/templates/react-spring-shadcn/backend/Dockerfile +11 -0
- package/templates/react-spring-shadcn/backend/mvnw +295 -0
- package/templates/react-spring-shadcn/backend/pom.xml +15 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Api.java +38 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/AppUser.java +11 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Application.java +7 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Errors.java +13 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/PersonalRecord.java +15 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Records.java +14 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Security.java +28 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Seed.java +13 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Users.java +5 -0
- package/templates/react-spring-shadcn/backend/src/main/resources/application.properties +17 -0
- package/templates/react-spring-shadcn/backend/src/main/resources/db/migration/V1__initial.sql +3 -0
- package/templates/react-spring-shadcn/backend/src/main/resources/openapi.json +461 -0
- package/templates/react-spring-shadcn/backend/src/test/java/dev/scaffold/app/ApiTest.java +28 -0
- package/templates/react-spring-shadcn/backend/src/test/java/dev/scaffold/app/SessionExpiryTest.java +37 -0
- package/templates/react-spring-shadcn/compose.yaml +18 -0
- package/templates/react-spring-shadcn/design/guide.md +61 -0
- package/templates/react-spring-shadcn/design/layout.css +6 -0
- package/templates/react-spring-shadcn/design/structure.json +107 -0
- package/templates/react-spring-shadcn/design/tokens.json +171 -0
- package/templates/react-spring-shadcn/design/widgets.css +30 -0
- package/templates/react-spring-shadcn/design/widgets.json +233 -0
- package/templates/react-spring-shadcn/docs/PROJECT.md +32 -0
- package/templates/react-spring-shadcn/docs/api.d.ts +544 -0
- package/templates/react-spring-shadcn/docs/openapi.json +461 -0
- package/templates/react-spring-shadcn/gitignore.template +19 -0
- package/templates/react-spring-shadcn/licenses/fastapi.txt +21 -0
- package/templates/react-spring-shadcn/licenses/nest.txt +22 -0
- package/templates/react-spring-shadcn/licenses/next.txt +21 -0
- package/templates/react-spring-shadcn/licenses/shadcn.txt +21 -0
- package/templates/react-spring-shadcn/licenses/sources.json +27 -0
- package/templates/react-spring-shadcn/licenses/spring.txt +202 -0
- package/templates/react-spring-shadcn/package-lock.json +494 -0
- package/templates/react-spring-shadcn/package.json +26 -0
- package/templates/react-spring-shadcn/playwright.config.ts +3 -0
- package/templates/react-spring-shadcn/project.json +8 -0
- package/templates/react-spring-shadcn/scripts/api-check.mjs +18 -0
- package/templates/react-spring-shadcn/scripts/api-contract.mjs +46 -0
- package/templates/react-spring-shadcn/scripts/design-coverage.mjs +20 -0
- package/templates/react-spring-shadcn/scripts/design-next-cleanup.mjs +13 -0
- package/templates/react-spring-shadcn/scripts/design-verify.mjs +154 -0
- package/templates/react-spring-shadcn/scripts/design.mjs +108 -0
- package/templates/react-spring-shadcn/scripts/project.mjs +120 -0
- package/templates/react-spring-shadcn/tests/contract-client.ts +20 -0
- package/templates/react-spring-shadcn/tests/contract.spec.ts +49 -0
- package/templates/react-spring-shadcn/tests/design/harness.tsx +63 -0
- package/templates/react-spring-shadcn/tests/ui.spec.ts +61 -0
- package/templates/react-spring-shadcn/web/eslint.config.mjs +3 -0
- package/templates/react-spring-shadcn/web/index.html +1 -0
- package/templates/react-spring-shadcn/web/package.json +33 -0
- package/templates/react-spring-shadcn/web/pnpm-lock.yaml +1788 -0
- package/templates/react-spring-shadcn/web/src/App.tsx +30 -0
- package/templates/react-spring-shadcn/web/src/design-layout.css +7 -0
- package/templates/react-spring-shadcn/web/src/design-runtime.json +511 -0
- package/templates/react-spring-shadcn/web/src/design-tokens.css +168 -0
- package/templates/react-spring-shadcn/web/src/design-widgets.css +31 -0
- package/templates/react-spring-shadcn/web/src/main.tsx +6 -0
- package/templates/react-spring-shadcn/web/src/structure-view.tsx +16 -0
- package/templates/react-spring-shadcn/web/src/styles.css +3 -0
- package/templates/react-spring-shadcn/web/src/tailwind.css +2 -0
- package/templates/react-spring-shadcn/web/src/ui.tsx +13 -0
- package/templates/react-spring-shadcn/web/src/widget-icon.tsx +5 -0
- package/templates/react-spring-shadcn/web/src/widget-types.ts +13 -0
- package/templates/react-spring-shadcn/web/src/workspace-model.ts +85 -0
- package/templates/react-spring-shadcn/web/tsconfig.json +22 -0
- package/templates/react-spring-shadcn/web/vite.config.ts +4 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 qinchaomeishenmeshi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,100 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Agent Scaffold
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
面向 Codex、Claude Code、Grok Build 的项目脚手架。四套技术栈(React + FastAPI、React + Spring Boot、React + NestJS、Next.js)各支持 shadcn/ui 和 Ant Design,共八个组合。生成应用包含登录和个人记录 CRUD,默认不含 AI。
|
|
4
|
+
|
|
5
|
+
## 选择技术栈
|
|
6
|
+
|
|
7
|
+
| 已有偏好 | 建议起点 | 额外运行环境 |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| Python 后端 | React + FastAPI | Python 3.12、uv、Bun |
|
|
10
|
+
| Java / Spring 团队 | React + Spring Boot | JDK 17 或更高版本、pnpm 10;自带 Maven Wrapper |
|
|
11
|
+
| 前后端都用 TypeScript,独立 API | React + NestJS | pnpm 10 |
|
|
12
|
+
| 一个 TypeScript 全栈工程 | Next.js | pnpm 10 |
|
|
13
|
+
|
|
14
|
+
都需要 Node.js 24 和 Docker。没有既定偏好时可从 Next.js + shadcn 开始;两种 UI 的设计意图和业务能力保持一致,按组件库偏好选择。
|
|
15
|
+
|
|
16
|
+
## 本地使用
|
|
17
|
+
|
|
18
|
+
需要 Node.js 24:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx @cherishxn/agent-scaffold@latest init
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
交互创建收集中文名称、英文名称、简介、技术栈和 UI;确认前不写项目文件。也可创建 `spec.json`:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{"schemaVersion":1,"nameZh":"客户服务平台","nameEn":"customer-service","description":"客户资料和服务记录管理","template":"react-fastapi","ui":"shadcn"}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx @cherishxn/agent-scaffold@latest templates --json
|
|
32
|
+
npx @cherishxn/agent-scaffold@latest init --help --json
|
|
33
|
+
npx @cherishxn/agent-scaffold@latest plan --spec spec.json --out plan.json --json
|
|
34
|
+
npx @cherishxn/agent-scaffold@latest init --plan plan.json --json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
1.1.0 候选支持 `plan --spec spec.json --json` 的零写入预览;只有提供 `--out` 才保存计划。预览与创建使用同一精确 CLI 版本,计划绑定模板摘要。当前公开版与候选验收状态见 [验证记录](docs/VERIFICATION.md)。
|
|
38
|
+
|
|
39
|
+
也可直接 `init --spec spec.json --json`。命令返回安装步骤和工作目录,不自动安装依赖或启动服务。进入生成目录后:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm run setup
|
|
43
|
+
npm run dev
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
开发账号与随机密码写入被 Git 忽略的 `.scaffold-local-credentials`。FastAPI 需要 Python 3.12、uv、Bun;Spring 需要 Java 17 和 pnpm;Nest/Next 需要 pnpm。数据库使用 Docker。具体版本锁定在模板中。
|
|
47
|
+
|
|
48
|
+
## 检查与报告
|
|
49
|
+
|
|
50
|
+
1.1.0 候选提供安装前工具检查 `doctor --dir . --tools-only --json`,失败项会说明修复方法;默认 doctor 同时检查项目依赖。它只诊断,不安装工具或启动服务。
|
|
51
|
+
|
|
52
|
+
新生成项目的 `npm run check` 按类型、Lint、构建顺序执行,遇到失败即停止,适合日常反馈;它不替代以下真实业务验证。
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npx @cherishxn/agent-scaffold@latest doctor --dir . --json
|
|
57
|
+
npx @cherishxn/agent-scaffold@latest verify --dir . --json
|
|
58
|
+
npx @cherishxn/agent-scaffold@latest report --dir . --json
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
verify 启动独立 PostgreSQL,运行类型、Lint、构建、迁移、种子数据、原生测试、API 和浏览器测试,并清理本次容器。不会使用开发环境的数据库连接。结果保存于 `.scaffold-runs`,包含内容摘要和原生报告引用;代码变化后 report 标记 STALE。失败、空测试、缺前置与中断不会标为 PASS。生成项目的 verify 会执行该项目脚本,仅对自己信任的项目运行。
|
|
62
|
+
|
|
63
|
+
## 视觉设计
|
|
64
|
+
|
|
65
|
+
八组合默认使用从 [CleerScience](https://cleerscience.com/) 提炼的深色科技视觉:近黑蓝底、冷白文字、冰蓝强调与直角面板。可独立复用的 [通用 DESIGN.md](docs/reference/CLEERSCIENCE-DESIGN.md) 区分官网实测与产品适配;生成项目的根 DESIGN.md 是当前 UI 的实际规范。
|
|
66
|
+
|
|
67
|
+
设计采用四层分离:共享 `design/` 规范、语义 Widget 契约、组件库适配层、独立业务模型。`design:sync` 生成 DESIGN.md、CSS 和运行时规范;`design:check` 检测漂移;`design:verify` 验证全部组件状态及页面在桌面/移动端的几何、颜色、圆角和图标。位置容差 0.6px,其余指定属性严格相等。生成项目内置三宿主可发现的 `design-contract` Skill。根目录 `npm run design:verify` 运行全部八种组合并比较跨模板测量;单个生成项目仅验证已选适配器。
|
|
68
|
+
|
|
69
|
+
## Agent 入口
|
|
70
|
+
|
|
71
|
+
打包后的 CLI 包含 `skills/scaffold-use/SKILL.md`。按当前宿主约定,把该目录复制到发起创建的工作目录:Codex 使用 `.agents/skills/scaffold-use`,Claude Code 使用 `.claude/skills/scaffold-use`,Grok Build 使用 `.grok/skills/scaffold-use`。这一步由使用者或已获授权的 Agent 执行;CLI 不改全局配置。
|
|
72
|
+
|
|
73
|
+
生成项目自带 AGENTS.md、薄 CLAUDE.md,以及上述三个原生目录下同源的 project-work Skill。docs/PROJECT.md 的任务表按实际技术栈指向 API、认证、迁移、设计和测试入口。切换到新工程后核对规则与 Skill 是否加载。具体宿主兼容范围以交付记录为准。
|
|
74
|
+
|
|
75
|
+
## 开发与分发
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm run check
|
|
79
|
+
npm run test:interactive
|
|
80
|
+
npm run test:package
|
|
81
|
+
npm run test:onboarding
|
|
82
|
+
npm run matrix
|
|
83
|
+
npm pack
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
源码仓库保持私有,CLI 按发布白名单分发至 npm 公共包。`npm pack` 构建包含八套模板与锁文件的本地安装包。模板源码位于 template-src;templates 是可重新生成的产物。普通模板层只允许添加文件,路径冲突会停止构建;生成文件或锁文件替换由 materialize 脚本显式完成。更新依赖后运行 scripts/lock-templates.mjs 并重新验证受影响矩阵。
|
|
87
|
+
|
|
88
|
+
[开发计划](docs/DEVELOPMENT-PLAN.md) · [验证记录](docs/VERIFICATION.md) · [设计基线 v0.5](docs/reference/AGENT-SCAFFOLD-DESIGN-v0.5.md) · [来源与许可证](THIRD_PARTY_NOTICES.md)
|
|
89
|
+
|
|
90
|
+
运行测试通过不代表生产部署或产品/PM 业务验收完成。
|
|
91
|
+
|
|
92
|
+
本轮选择性学习 VibeStart 的预览、Agent 指引、快速反馈与模板文件归属机制;具体采用项和保留边界见 [源码研究与采纳映射](docs/reference/VIBESTART-REVIEW.md)。实现沿用本项目架构,未引入其技术栈或全量源码。
|
|
93
|
+
|
|
94
|
+
## 验证反馈与接口一致性
|
|
95
|
+
|
|
96
|
+
verify 保留原退出码和报告字段,失败分项新增 diagnostic(code、retryable、nextAction),evidence 指向脱敏日志及 JUnit。端口冲突、连接拒绝、主机解析失败、启动失败、超时与缺测试证据分开;未知错误保持 UNKNOWN_FAILURE,不自动重试或修改运行环境。API/浏览器测试采集服务 stdout/stderr。
|
|
97
|
+
|
|
98
|
+
生成项目提供 `npm run api:check`:在系统临时目录生成类型并比较 docs/api.d.ts,检查不回写源码;有意修改 docs/openapi.json 后运行 `npm run api:generate`。check/verify 自动运行此门禁,真实 HTTP 回归按契约检查响应状态和结构。
|
|
99
|
+
|
|
100
|
+
Codex 接手开发的固定题库、运行方法与局限见 [评测说明](evals/codex/README.md)。这与模板本身的八组合业务矩阵分别留证。
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Template sources and licenses
|
|
2
|
+
|
|
3
|
+
Templates are maintained derivatives, not unmodified upstream distributions. Exact bundled files are hashed in templates/catalog.json; npm/uv/pnpm/Bun locks pin dependency resolution. Initialization is offline and never invokes upstream generators.
|
|
4
|
+
|
|
5
|
+
| Source | Fixed reference | Use / modifications | License |
|
|
6
|
+
| --- | --- | --- | --- |
|
|
7
|
+
| fastapi/full-stack-fastapi-template | b1125d8839482cb7bbae603ddc6d0081bf87532e | SQLModel/Alembic/JWT/pwdlib foundation; reduced accounts, replaced sample feature with owner-scoped records, retained Bun frontend | MIT, licenses/fastapi.txt |
|
|
8
|
+
| nestjs/typescript-starter | a122dea65cd0610ee205d7765ed46f9d73629141 | Nest module/bootstrap foundation; added Prisma, JWT/Guard, Jest/Supertest; no deployment tooling | MIT, licenses/nest.txt |
|
|
9
|
+
| Spring Initializr | starter.zip fetched 2026-10-19; Maven Wrapper and Java layout | Generator returned unresolved 4.1.1.RELEASE; parent adjusted to stable Maven Central 3.5.16, Session/JPA/Flyway/CRUD added | Apache-2.0 wrapper, licenses/spring.txt |
|
|
10
|
+
| create-next-app | npm 16.4.2 | Official App Router/TypeScript baseline; Better Auth + Prisma + records; no remote fonts | MIT, licenses/next.txt |
|
|
11
|
+
| shadcn/ui | Button/Input pattern, pinned source reference in licenses/sources.json | Adapted local CVA/Slot controls with Tailwind; retained copy ownership | MIT, licenses/shadcn.txt |
|
|
12
|
+
| Ant Design | npm 6.6.6 | Installed dependency; no copied source | MIT (package license) |
|
|
13
|
+
|
|
14
|
+
Package dependencies carry their own licenses. Generated apps include these notices; template authors must carry applicable notices when changing upstream-derived files. Names and marks remain their respective owners'.
|
|
15
|
+
|
|
16
|
+
## Design and workflow reference
|
|
17
|
+
|
|
18
|
+
VinkyDev/vibestart at commit `5768fc561340422bf7736499fe69b1aae263790a` (MIT) informed the preview, task-oriented Agent guidance, quick checks and template-layer collision rules. These changes are independently implemented for Agent Scaffold; no VibeStart source, bundled skills, branding or UI assets are redistributed. The source review and selected adaptations are recorded in docs/reference/VIBESTART-REVIEW.md.
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { createInterface } from 'node:readline/promises';
|
|
4
|
+
import { resolve, join } from 'node:path';
|
|
5
|
+
import { stdin, stdout } from 'node:process';
|
|
6
|
+
import { CLI_VERSION, ScaffoldError, templates, uis } from './model.js';
|
|
7
|
+
import { catalog, initialize, jsonFile, makePlan, validatePlan, writePlan, packageRoot } from './generate.js';
|
|
8
|
+
import { doctor, verify, report } from './verify.js';
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
const json = args.includes('--json');
|
|
11
|
+
let commandName = 'scaffold';
|
|
12
|
+
function output(data, nextActions = []) {
|
|
13
|
+
const payload = { schemaVersion: 1, command: commandName, status: 'success', data, errors: [], warnings: [], nextActions };
|
|
14
|
+
stdout.write(JSON.stringify(payload, null, json ? undefined : 2) + '\n');
|
|
15
|
+
}
|
|
16
|
+
async function interactive() {
|
|
17
|
+
const r = createInterface({ input: stdin, output: stdout });
|
|
18
|
+
const abort = new AbortController();
|
|
19
|
+
let interrupted = false;
|
|
20
|
+
const stop = () => { interrupted = true; abort.abort(); r.close(); };
|
|
21
|
+
r.on('SIGINT', stop);
|
|
22
|
+
process.once('SIGINT', stop);
|
|
23
|
+
const ask = (prompt) => r.question(prompt, { signal: abort.signal });
|
|
24
|
+
try {
|
|
25
|
+
const nameZh = await ask('项目中文名称:');
|
|
26
|
+
const nameEn = await ask('项目英文名称(小写字母、数字、连字符):');
|
|
27
|
+
const description = await ask('项目简介:');
|
|
28
|
+
const templateAnswer = (await ask('技术栈 1 FastAPI / 2 Spring / 3 Nest / 4 Next [1]:')).trim() || '1';
|
|
29
|
+
const uiAnswer = (await ask('UI 1 shadcn/ui / 2 Ant Design [1]:')).trim() || '1';
|
|
30
|
+
const template = templates[Number(templateAnswer) - 1] ?? templateAnswer;
|
|
31
|
+
const ui = uis[Number(uiAnswer) - 1] ?? uiAnswer;
|
|
32
|
+
const input = { schemaVersion: 1, nameZh, nameEn, description, template, ui };
|
|
33
|
+
const plan = await makePlan(input);
|
|
34
|
+
const dir = (await ask(`创建目录 [./${plan.normalizedSpec.nameEn}]:`)).trim() || `./${plan.normalizedSpec.nameEn}`;
|
|
35
|
+
stdout.write(JSON.stringify({ project: plan.normalizedSpec, directory: resolve(dir), files: plan.files.length }, null, 2) + '\n');
|
|
36
|
+
const yes = (await ask('确认创建?[y/N]:')).trim().toLowerCase();
|
|
37
|
+
if (!['y', 'yes', '是'].includes(yes))
|
|
38
|
+
throw new ScaffoldError('CANCELLED', 'Creation cancelled; no project files were written.', 130);
|
|
39
|
+
return { spec: plan.normalizedSpec, dir };
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (interrupted)
|
|
43
|
+
throw new ScaffoldError('CANCELLED', 'Creation interrupted; no project files were written.', 130);
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
process.removeListener('SIGINT', stop);
|
|
48
|
+
r.close();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const program = new Command().name('scaffold').version(CLI_VERSION).description('Create and verify complete web projects.').option('--json', 'Non-interactive JSON output').exitOverride().configureOutput({ writeOut: s => process.stdout.write(s), writeErr: s => process.stderr.write(s) });
|
|
52
|
+
program.command('templates').description('List bundled templates and input schema').action(async () => { commandName = 'templates'; output(await catalog()); });
|
|
53
|
+
program.command('plan').description('Preview a deterministic plan; write it only when --out is provided').requiredOption('--spec <file>').option('--out <file>', 'Write to a new plan file').action(async (o) => { commandName = 'plan'; const spec = await jsonFile(o.spec); output(o.out ? await writePlan(spec, o.out) : await makePlan(spec)); });
|
|
54
|
+
program.command('init').description('Create a project interactively, from JSON spec, or from a plan').option('--spec <file>').option('--plan <file>').option('--dir <path>').action(async (o) => {
|
|
55
|
+
commandName = 'init';
|
|
56
|
+
if (o.spec && o.plan)
|
|
57
|
+
throw new ScaffoldError('MODE_CONFLICT', '--spec and --plan are mutually exclusive.');
|
|
58
|
+
let plan;
|
|
59
|
+
if (o.plan)
|
|
60
|
+
plan = await validatePlan(await jsonFile(o.plan));
|
|
61
|
+
else if (o.spec)
|
|
62
|
+
plan = await makePlan(await jsonFile(o.spec));
|
|
63
|
+
else {
|
|
64
|
+
if (json || !stdin.isTTY || !stdout.isTTY)
|
|
65
|
+
throw new ScaffoldError('MISSING_INPUT', 'Provide --spec or --plan in non-interactive mode.');
|
|
66
|
+
const i = await interactive();
|
|
67
|
+
plan = await makePlan(i.spec);
|
|
68
|
+
o.dir = o.dir ?? i.dir;
|
|
69
|
+
}
|
|
70
|
+
const result = await initialize(plan, o.dir ?? plan.normalizedSpec.nameEn);
|
|
71
|
+
if (json)
|
|
72
|
+
output(result, result.nextActions);
|
|
73
|
+
else {
|
|
74
|
+
const directory = "'" + result.directory.replaceAll("'", "'\"'\"'") + "'";
|
|
75
|
+
stdout.write(`\n${result.status === 'created' ? '已创建' : '工程已存在且内容一致'}:${plan.normalizedSpec.nameZh}\n${plan.templateId} / ${plan.normalizedSpec.ui}\n目录:${result.directory}\n\n下一步:\n cd ${directory}\n npm run setup\n npm run dev\n\n安装前检查:npx @cherishxn/agent-scaffold@${CLI_VERSION} doctor --dir . --tools-only --json\n开发规则:AGENTS.md;任务路径:docs/PROJECT.md;本地账号:.scaffold-local-credentials(setup 后生成)\n项目文件已生成;依赖安装、启动与业务验证尚未执行。\n`);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
program.command('doctor').description('Read-only local prerequisite checks').requiredOption('--dir <path>').option('--tools-only', 'Check tools before installing project dependencies').action(async (o) => { commandName = 'doctor'; const r = await doctor(o.dir, { toolsOnly: o.toolsOnly }); output(r); process.exitCode = r.ok ? 0 : 3; });
|
|
79
|
+
program.command('verify').description('Run isolated baseline checks').requiredOption('--dir <path>').option('--profile <name>', 'Check profile', 'baseline').action(async (o) => { commandName = 'verify'; if (o.profile !== 'baseline')
|
|
80
|
+
throw new ScaffoldError('INVALID_PROFILE', 'Only baseline is supported.'); const r = await verify(o.dir); output(r); process.exitCode = r.exitCode; });
|
|
81
|
+
program.command('report').description('Read latest results and current content validity').requiredOption('--dir <path>').action(async (o) => { commandName = 'report'; output(await report(o.dir)); });
|
|
82
|
+
try {
|
|
83
|
+
if (json && (args.includes('--help') || args.includes('-h'))) {
|
|
84
|
+
const name = args.find(a => !a.startsWith('-'));
|
|
85
|
+
const c = name ? program.commands.find(c => c.name() === name) : program;
|
|
86
|
+
if (!c)
|
|
87
|
+
throw new ScaffoldError('UNKNOWN_COMMAND', 'Unknown command.');
|
|
88
|
+
commandName = 'help';
|
|
89
|
+
output({ version: CLI_VERSION, name: c.name(), description: c.description(), options: c.options.map(o => ({ flags: o.flags, description: o.description, required: o.mandatory })), commands: program.commands.map(c => ({ name: c.name(), description: c.description() })), schemas: ['spec', 'plan', 'manifest', 'result'].map(s => join(packageRoot, `schemas/${s}.json`)), exitCodes: { 0: 'command succeeded; inspect overallStatus for report', 2: 'invalid input', 3: 'environment or incomplete checks', 4: 'failed checks', 5: 'internal error', 130: 'interrupted' }, sideEffects: { templates: [], plan: ['write new plan only with --out'], init: ['write new project'], doctor: [], verify: ['build, isolated database, reports'], report: [] }, prerequisites: ['Node.js 24', 'See templates for stack-specific runtimes'] });
|
|
90
|
+
}
|
|
91
|
+
else if (args.length === 0)
|
|
92
|
+
program.help();
|
|
93
|
+
else
|
|
94
|
+
await program.parseAsync(process.argv);
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
const c = e;
|
|
98
|
+
if (c.code === 'commander.helpDisplayed' || c.code === 'commander.version')
|
|
99
|
+
process.exitCode = 0;
|
|
100
|
+
else {
|
|
101
|
+
const error = e instanceof ScaffoldError ? e : new ScaffoldError(c.code?.startsWith('commander.') ? 'ARGUMENT_ERROR' : 'INTERNAL_ERROR', c.code?.startsWith('commander.') ? 'Invalid command arguments. See --help.' : 'Operation failed; no successful result was recorded.', c.code?.startsWith('commander.') ? 2 : 5);
|
|
102
|
+
stdout.write(JSON.stringify({ schemaVersion: 1, command: commandName, status: 'error', data: null, errors: [error.issue()], warnings: [], nextActions: [] }) + '\n');
|
|
103
|
+
process.exitCode = error.exitCode;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type Diagnostic = {
|
|
2
|
+
code: string;
|
|
3
|
+
retryable: boolean;
|
|
4
|
+
nextAction: string;
|
|
5
|
+
};
|
|
6
|
+
/** Classify observed failures only; unknown output must not invent a root cause. */
|
|
7
|
+
export declare function diagnose(stage: string, output: string, options?: {
|
|
8
|
+
timedOut?: boolean;
|
|
9
|
+
interrupted?: boolean;
|
|
10
|
+
}): Diagnostic;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Classify observed failures only; unknown output must not invent a root cause. */
|
|
2
|
+
export function diagnose(stage, output, options = {}) {
|
|
3
|
+
if (options.interrupted)
|
|
4
|
+
return { code: 'INTERRUPTED', retryable: false, nextAction: 'Review the completed steps and cleanup evidence before starting a new verification.' };
|
|
5
|
+
if (options.timedOut)
|
|
6
|
+
return { code: 'TIMEOUT', retryable: false, nextAction: 'Inspect the stage log and service startup output; resolve the stalled dependency before rerunning.' };
|
|
7
|
+
if (/EADDRINUSE|Address already in use|Port \d+ was already in use/i.test(output))
|
|
8
|
+
return { code: 'PORT_IN_USE', retryable: false, nextAction: 'Identify the process owning the reported port; choose a free port or stop only a process you own.' };
|
|
9
|
+
if (/UnknownHostException|Name or service not known|ENOTFOUND|getaddrinfo failed/i.test(output))
|
|
10
|
+
return { code: 'HOST_RESOLUTION_FAILED', retryable: false, nextAction: 'Check the failing hostname and this runtime\'s DNS/proxy configuration. Do not infer a database or application defect from this alone.' };
|
|
11
|
+
if (/ECONNREFUSED|Connection refused|connection to server .* failed|could not connect to server/i.test(output))
|
|
12
|
+
return { code: 'CONNECTION_REFUSED', retryable: false, nextAction: 'Use the endpoint in the log to check the expected service, port and runtime connectivity before retrying.' };
|
|
13
|
+
if (/Required report missing, contains failures, or has no executed test cases/.test(output))
|
|
14
|
+
return { code: 'TEST_EVIDENCE_INVALID', retryable: false, nextAction: 'Inspect the test command and JUnit artifact; missing, empty or failing reports cannot prove a pass.' };
|
|
15
|
+
if (/API_CONTRACT_DRIFT/.test(output))
|
|
16
|
+
return { code: 'API_CONTRACT_DRIFT', retryable: false, nextAction: 'Compare the contract and generated types; run api:generate after the intended contract change, then api:check.' };
|
|
17
|
+
if (/API_RESPONSE_INVALID/.test(output))
|
|
18
|
+
return { code: 'API_RESPONSE_INVALID', retryable: false, nextAction: 'Compare the reported operation, response status and schema path with the intended HTTP behavior.' };
|
|
19
|
+
if (/spawn(?:Sync)? \S+ ENOENT|command not found/.test(output))
|
|
20
|
+
return { code: 'COMMAND_NOT_FOUND', retryable: false, nextAction: 'Run doctor and install the missing executable or correct its path.' };
|
|
21
|
+
if (/ENOENT/.test(output))
|
|
22
|
+
return { code: 'FILE_NOT_FOUND', retryable: false, nextAction: 'Inspect the missing file path and the stage that requested it; an ENOENT file error does not establish a missing executable.' };
|
|
23
|
+
if (stage === 'test-api' || stage === 'test-e2e')
|
|
24
|
+
if (/Process from config.webServer|webServer.*(?:exited|failed)|Timed out waiting.*config.webServer/i.test(output))
|
|
25
|
+
return { code: 'SERVICE_START_FAILED', retryable: false, nextAction: 'Inspect the captured webServer stdout/stderr for the first startup error; the underlying cause is not yet classified.' };
|
|
26
|
+
return { code: 'UNKNOWN_FAILURE', retryable: false, nextAction: 'Inspect the linked log and artifacts. The cause is unknown; do not automatically repeat the action or modify unrelated code.' };
|
|
27
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type Spec, type Action } from './model.js';
|
|
2
|
+
export declare const packageRoot: string;
|
|
3
|
+
export type FileEntry = {
|
|
4
|
+
path: string;
|
|
5
|
+
source: string;
|
|
6
|
+
digest: string;
|
|
7
|
+
mode: number;
|
|
8
|
+
};
|
|
9
|
+
export type Plan = {
|
|
10
|
+
schemaVersion: 1;
|
|
11
|
+
cliVersion: string;
|
|
12
|
+
templateId: string;
|
|
13
|
+
templateVersion: string;
|
|
14
|
+
templateDigest: string;
|
|
15
|
+
normalizedSpec: Spec;
|
|
16
|
+
files: FileEntry[];
|
|
17
|
+
nextActions: Action[];
|
|
18
|
+
planDigest: string;
|
|
19
|
+
};
|
|
20
|
+
export declare function jsonFile(path: string): Promise<unknown>;
|
|
21
|
+
export declare function specFrom(input: unknown): Promise<Spec>;
|
|
22
|
+
export declare function walk(root: string, prefix?: string): Promise<string[]>;
|
|
23
|
+
export declare function makePlan(input: unknown): Promise<Plan>;
|
|
24
|
+
export declare function validatePlan(input: unknown): Promise<Plan>;
|
|
25
|
+
export declare function writePlan(input: unknown, output: string): Promise<Plan>;
|
|
26
|
+
export declare function initialize(plan: Plan, target: string): Promise<{
|
|
27
|
+
directory: string;
|
|
28
|
+
status: string;
|
|
29
|
+
nextActions: {
|
|
30
|
+
cwd: string;
|
|
31
|
+
program: string;
|
|
32
|
+
args: string[];
|
|
33
|
+
prerequisites: string[];
|
|
34
|
+
sideEffects: string[];
|
|
35
|
+
}[];
|
|
36
|
+
}>;
|
|
37
|
+
export declare function catalog(): Promise<{
|
|
38
|
+
version: string;
|
|
39
|
+
templates: {
|
|
40
|
+
id: "react-fastapi" | "react-spring" | "react-nest" | "next-fullstack";
|
|
41
|
+
uis: ("shadcn" | "antd")[];
|
|
42
|
+
node: string;
|
|
43
|
+
database: string;
|
|
44
|
+
requirements: string[];
|
|
45
|
+
}[];
|
|
46
|
+
specSchema: string;
|
|
47
|
+
example: {
|
|
48
|
+
schemaVersion: number;
|
|
49
|
+
nameZh: string;
|
|
50
|
+
nameEn: string;
|
|
51
|
+
description: string;
|
|
52
|
+
template: string;
|
|
53
|
+
ui: string;
|
|
54
|
+
};
|
|
55
|
+
}>;
|
package/dist/generate.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { readFile, readdir, lstat, mkdir, writeFile, access } from 'node:fs/promises';
|
|
2
|
+
import { join, resolve, dirname, relative, isAbsolute, sep } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { Ajv } from 'ajv';
|
|
5
|
+
import { canonical, digest, ScaffoldError, CLI_VERSION, templates, uis } from './model.js';
|
|
6
|
+
export const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
7
|
+
export async function jsonFile(path) {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.parse(await readFile(path, 'utf8'));
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
throw new ScaffoldError('INVALID_JSON', 'Cannot read a valid JSON file.', 2, path);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export async function specFrom(input) {
|
|
16
|
+
const schema = await jsonFile(join(packageRoot, 'schemas/spec.json'));
|
|
17
|
+
const ajv = new Ajv({ allErrors: true });
|
|
18
|
+
const validate = ajv.compile(schema);
|
|
19
|
+
const normalized = input && typeof input === 'object' && !Array.isArray(input) ? Object.fromEntries(Object.entries(input).map(([k, v]) => [k, typeof v === 'string' ? v.trim() : v])) : input;
|
|
20
|
+
if (!validate(normalized)) {
|
|
21
|
+
const e = validate.errors?.[0];
|
|
22
|
+
const field = e?.instancePath || String(e?.params.missingProperty ?? 'spec');
|
|
23
|
+
const reason = e?.keyword === 'enum' ? `Choose one of: ${e.params.allowedValues.join(', ')}.`
|
|
24
|
+
: field === '/nameEn' ? 'Use 1–50 lowercase letters, digits and single hyphens; start with a letter (for example: my-project).'
|
|
25
|
+
: e?.keyword === 'additionalProperties' ? `Unknown field: ${String(e.params.additionalProperty)}. See templates --json for the input schema.`
|
|
26
|
+
: `${e?.message ?? 'Invalid project specification'}. See templates --json for an example.`;
|
|
27
|
+
throw new ScaffoldError('INVALID_SPEC', reason, 2, field);
|
|
28
|
+
}
|
|
29
|
+
return normalized;
|
|
30
|
+
}
|
|
31
|
+
export async function walk(root, prefix = '') {
|
|
32
|
+
const out = [];
|
|
33
|
+
for (const entry of await readdir(join(root, prefix), { withFileTypes: true })) {
|
|
34
|
+
const name = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
35
|
+
if (entry.isSymbolicLink())
|
|
36
|
+
throw new ScaffoldError('SYMLINK', 'Symbolic links are not allowed in template/output files.', 2, name);
|
|
37
|
+
if (entry.isDirectory())
|
|
38
|
+
out.push(...await walk(root, name));
|
|
39
|
+
else if (entry.isFile())
|
|
40
|
+
out.push(name);
|
|
41
|
+
else
|
|
42
|
+
throw new ScaffoldError('FILE_TYPE', 'Unsupported file type.', 2, name);
|
|
43
|
+
}
|
|
44
|
+
return out.sort();
|
|
45
|
+
}
|
|
46
|
+
async function render(spec) {
|
|
47
|
+
const dir = join(packageRoot, 'templates', `${spec.template}-${spec.ui}`);
|
|
48
|
+
const catalog = await jsonFile(join(packageRoot, 'templates/catalog.json'));
|
|
49
|
+
const names = await walk(dir);
|
|
50
|
+
const source = await Promise.all(names.map(async (path) => ({ path, bytes: await readFile(join(dir, path)), mode: ((await lstat(join(dir, path))).mode & 0o111) ? 0o755 : 0o644 })));
|
|
51
|
+
const sourceDigest = digest(canonical(source.map(x => ({ path: x.path, digest: digest(x.bytes), mode: x.mode }))));
|
|
52
|
+
if (catalog.entries[`${spec.template}-${spec.ui}`]?.digest !== sourceDigest)
|
|
53
|
+
throw new ScaffoldError('TEMPLATE_INTEGRITY', 'Bundled template does not match the published catalog.');
|
|
54
|
+
const contents = new Map(source.map(x => [x.path === 'gitignore.template' ? '.gitignore' : x.path, { content: Buffer.from(x.bytes.toString('utf8').replaceAll('__NAME_EN__', spec.nameEn).replaceAll('__CLI_VERSION__', CLI_VERSION)), source: x.path, mode: x.mode }]));
|
|
55
|
+
contents.set('project.json', { content: Buffer.from(JSON.stringify(spec, null, 2) + '\n'), source: 'generated:spec', mode: 0o644 });
|
|
56
|
+
const pkg = contents.get('package.json');
|
|
57
|
+
if (pkg) {
|
|
58
|
+
const metadata = JSON.parse(pkg.content.toString());
|
|
59
|
+
metadata.description = spec.description;
|
|
60
|
+
pkg.content = Buffer.from(JSON.stringify(metadata, null, 2) + '\n');
|
|
61
|
+
}
|
|
62
|
+
const readme = contents.get('README.md');
|
|
63
|
+
if (readme)
|
|
64
|
+
readme.content = Buffer.from(`# ${spec.nameZh}\n\n${spec.description}\n\n` + readme.content.toString());
|
|
65
|
+
const project = contents.get('docs/PROJECT.md');
|
|
66
|
+
if (project)
|
|
67
|
+
project.content = Buffer.from(`# ${spec.nameZh}\n\n工程标识:${spec.nameEn}\n\n${spec.description}\n\n` + project.content.toString());
|
|
68
|
+
return { contents, sourceDigest };
|
|
69
|
+
}
|
|
70
|
+
function actions() { return ['setup', 'dev'].map(task => ({ program: 'npm', args: ['run', task], cwd: '.', prerequisites: task === 'setup' ? ['Node.js 24, Docker and template runtimes'] : ['Setup completed'], sideEffects: task === 'setup' ? ['Download locked dependencies and execute their installation scripts', 'Create local development database and explicitly seed development users'] : ['Build and start local application processes'] })); }
|
|
71
|
+
export async function makePlan(input) {
|
|
72
|
+
const normalizedSpec = await specFrom(input);
|
|
73
|
+
const { contents, sourceDigest } = await render(normalizedSpec);
|
|
74
|
+
const base = { schemaVersion: 1, cliVersion: CLI_VERSION, templateId: normalizedSpec.template, templateVersion: CLI_VERSION, templateDigest: sourceDigest, normalizedSpec, files: [...contents].sort(([a], [b]) => a.localeCompare(b, 'en')).map(([path, f]) => ({ path, source: f.source, digest: digest(f.content), mode: f.mode })), nextActions: actions() };
|
|
75
|
+
return { ...base, planDigest: digest(canonical(base)) };
|
|
76
|
+
}
|
|
77
|
+
export async function validatePlan(input) {
|
|
78
|
+
if (!input || typeof input !== 'object' || !('normalizedSpec' in input))
|
|
79
|
+
throw new ScaffoldError('INVALID_PLAN', 'Plan must contain normalizedSpec.');
|
|
80
|
+
const expected = await makePlan(input.normalizedSpec);
|
|
81
|
+
if (canonical(input) !== canonical(expected))
|
|
82
|
+
throw new ScaffoldError('PLAN_MISMATCH', 'Plan does not match this CLI and bundled template. Generate a fresh plan.');
|
|
83
|
+
return expected;
|
|
84
|
+
}
|
|
85
|
+
export async function writePlan(input, output) {
|
|
86
|
+
const plan = await makePlan(input);
|
|
87
|
+
try {
|
|
88
|
+
await writeFile(output, JSON.stringify(plan, null, 2) + '\n', { flag: 'wx', mode: 0o644 });
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
throw new ScaffoldError('PLAN_OUTPUT', 'Cannot create plan; output must be a new writable file.', 2, output);
|
|
92
|
+
}
|
|
93
|
+
return plan;
|
|
94
|
+
}
|
|
95
|
+
async function rejectSymlinkAncestors(path) {
|
|
96
|
+
// /tmp and /var are OS aliases on macOS; resolve the caller-selected parent before checking children.
|
|
97
|
+
let cursor = resolve(path);
|
|
98
|
+
while (cursor !== dirname(cursor)) {
|
|
99
|
+
try {
|
|
100
|
+
if ((await lstat(cursor)).isSymbolicLink() && cursor !== '/tmp' && cursor !== '/var')
|
|
101
|
+
throw new ScaffoldError('SYMLINK', 'Target directory cannot traverse a symbolic link.', 2, cursor);
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
if (e instanceof ScaffoldError)
|
|
105
|
+
throw e;
|
|
106
|
+
if (e.code !== 'ENOENT')
|
|
107
|
+
throw e;
|
|
108
|
+
}
|
|
109
|
+
cursor = dirname(cursor);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export async function initialize(plan, target) {
|
|
113
|
+
await validatePlan(plan);
|
|
114
|
+
const dir = resolve(target);
|
|
115
|
+
await rejectSymlinkAncestors(dir);
|
|
116
|
+
let existing = [];
|
|
117
|
+
try {
|
|
118
|
+
existing = await walk(dir);
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
if (e.code !== 'ENOENT')
|
|
122
|
+
throw e;
|
|
123
|
+
}
|
|
124
|
+
const manifestPath = join(dir, '.scaffold-manifest.json');
|
|
125
|
+
if (existing.length) {
|
|
126
|
+
try {
|
|
127
|
+
const m = await jsonFile(manifestPath);
|
|
128
|
+
if (m.status === 'complete' && m.planDigest === plan.planDigest && existing.length === plan.files.length + 1) {
|
|
129
|
+
for (const f of plan.files) {
|
|
130
|
+
if (digest(await readFile(join(dir, f.path))) !== f.digest)
|
|
131
|
+
throw new Error('changed');
|
|
132
|
+
}
|
|
133
|
+
return { directory: dir, status: 'already_initialized', nextActions: plan.nextActions.map(a => ({ ...a, cwd: dir })) };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch { /* Existing data is never overwritten. */ }
|
|
137
|
+
throw new ScaffoldError('DIRECTORY_CONFLICT', 'Target is non-empty or contains changed/incomplete output. Choose a new --dir; existing files were preserved.', 2, dir);
|
|
138
|
+
}
|
|
139
|
+
await mkdir(dir, { recursive: true });
|
|
140
|
+
// Reject even empty user-created subdirectories, and concurrent writes before the first output.
|
|
141
|
+
if ((await readdir(dir)).length)
|
|
142
|
+
throw new ScaffoldError('DIRECTORY_CONFLICT', 'Target must be empty.', 2, dir);
|
|
143
|
+
const manifest = { status: 'generating', ...plan };
|
|
144
|
+
await writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\n', { flag: 'wx' });
|
|
145
|
+
const { contents } = await render(plan.normalizedSpec);
|
|
146
|
+
for (const [path, f] of contents) {
|
|
147
|
+
if (isAbsolute(path) || relative(dir, resolve(dir, path)).split(sep).includes('..'))
|
|
148
|
+
throw new ScaffoldError('PATH_ESCAPE', 'Output path escapes target.');
|
|
149
|
+
await mkdir(dirname(join(dir, path)), { recursive: true });
|
|
150
|
+
await rejectSymlinkAncestors(join(dir, path));
|
|
151
|
+
await writeFile(join(dir, path), f.content, { flag: 'wx', mode: f.mode });
|
|
152
|
+
}
|
|
153
|
+
await writeFile(manifestPath, JSON.stringify({ ...manifest, status: 'complete' }, null, 2) + '\n');
|
|
154
|
+
return { directory: dir, status: 'created', nextActions: plan.nextActions.map(a => ({ ...a, cwd: dir })) };
|
|
155
|
+
}
|
|
156
|
+
export async function catalog() {
|
|
157
|
+
await access(join(packageRoot, 'templates/catalog.json'));
|
|
158
|
+
return { version: CLI_VERSION, templates: templates.map(id => ({ id, uis: [...uis], node: '24.x', database: 'PostgreSQL 17', requirements: id === 'react-fastapi' ? ['uv', 'Python 3.12', 'Bun', 'Docker'] : id === 'react-spring' ? ['Java 17', 'Maven Wrapper', 'pnpm', 'Docker'] : ['pnpm', 'Docker'] })), specSchema: join(packageRoot, 'schemas/spec.json'), example: { schemaVersion: 1, nameZh: '客户服务平台', nameEn: 'customer-service', description: '客户资料和服务记录管理', template: 'react-fastapi', ui: 'shadcn' } };
|
|
159
|
+
}
|
package/dist/model.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const templates: readonly ["react-fastapi", "react-spring", "react-nest", "next-fullstack"];
|
|
2
|
+
export declare const uis: readonly ["shadcn", "antd"];
|
|
3
|
+
export type Spec = {
|
|
4
|
+
schemaVersion: 1;
|
|
5
|
+
nameZh: string;
|
|
6
|
+
nameEn: string;
|
|
7
|
+
description: string;
|
|
8
|
+
template: typeof templates[number];
|
|
9
|
+
ui: typeof uis[number];
|
|
10
|
+
};
|
|
11
|
+
export type Action = {
|
|
12
|
+
program: string;
|
|
13
|
+
args: string[];
|
|
14
|
+
cwd: string;
|
|
15
|
+
prerequisites: string[];
|
|
16
|
+
sideEffects: string[];
|
|
17
|
+
};
|
|
18
|
+
export type Issue = {
|
|
19
|
+
code: string;
|
|
20
|
+
message: string;
|
|
21
|
+
field?: string;
|
|
22
|
+
retryable: boolean;
|
|
23
|
+
};
|
|
24
|
+
export declare class ScaffoldError extends Error {
|
|
25
|
+
code: string;
|
|
26
|
+
exitCode: number;
|
|
27
|
+
field?: string | undefined;
|
|
28
|
+
constructor(code: string, message: string, exitCode?: number, field?: string | undefined);
|
|
29
|
+
issue(): Issue;
|
|
30
|
+
}
|
|
31
|
+
export declare function canonical(value: unknown): string;
|
|
32
|
+
export declare function digest(value: string | Buffer): string;
|
|
33
|
+
export declare const CLI_VERSION = "1.1.0";
|
package/dist/model.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
export const templates = ['react-fastapi', 'react-spring', 'react-nest', 'next-fullstack'];
|
|
3
|
+
export const uis = ['shadcn', 'antd'];
|
|
4
|
+
export class ScaffoldError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
exitCode;
|
|
7
|
+
field;
|
|
8
|
+
constructor(code, message, exitCode = 2, field) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.exitCode = exitCode;
|
|
12
|
+
this.field = field;
|
|
13
|
+
}
|
|
14
|
+
issue() { return { code: this.code, message: this.message, ...(this.field ? { field: this.field } : {}), retryable: false }; }
|
|
15
|
+
}
|
|
16
|
+
export function canonical(value) {
|
|
17
|
+
if (Array.isArray(value))
|
|
18
|
+
return '[' + value.map(canonical).join(',') + ']';
|
|
19
|
+
if (value !== null && typeof value === 'object')
|
|
20
|
+
return '{' + Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, v]) => JSON.stringify(k) + ':' + canonical(v)).join(',') + '}';
|
|
21
|
+
return JSON.stringify(value);
|
|
22
|
+
}
|
|
23
|
+
export function digest(value) { return createHash('sha256').update(value).digest('hex'); }
|
|
24
|
+
export const CLI_VERSION = '1.1.0';
|
package/dist/verify.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type Diagnostic } from './diagnostics.js';
|
|
2
|
+
type Check = {
|
|
3
|
+
id: string;
|
|
4
|
+
status: 'PASS' | 'FAIL' | 'NOT RUN' | 'N/A';
|
|
5
|
+
reason: string;
|
|
6
|
+
startedAt: string;
|
|
7
|
+
finishedAt: string;
|
|
8
|
+
exitCode: number | null;
|
|
9
|
+
signal: string | null;
|
|
10
|
+
evidence: string[];
|
|
11
|
+
diagnostic?: Diagnostic | null;
|
|
12
|
+
};
|
|
13
|
+
type Run = {
|
|
14
|
+
schemaVersion: 1;
|
|
15
|
+
runId: string;
|
|
16
|
+
template: string;
|
|
17
|
+
cliVersion: string;
|
|
18
|
+
platform: string;
|
|
19
|
+
runtime: string;
|
|
20
|
+
startedAt: string;
|
|
21
|
+
finishedAt: string;
|
|
22
|
+
beforeDigest: string;
|
|
23
|
+
afterDigest: string;
|
|
24
|
+
overallStatus: 'PASS' | 'FAIL' | 'NOT RUN';
|
|
25
|
+
validity: 'CURRENT' | 'STALE';
|
|
26
|
+
checks: Check[];
|
|
27
|
+
exitCode: number;
|
|
28
|
+
warnings: string[];
|
|
29
|
+
};
|
|
30
|
+
export declare function doctor(directory: string, options?: {
|
|
31
|
+
toolsOnly?: boolean;
|
|
32
|
+
}): Promise<{
|
|
33
|
+
ok: boolean;
|
|
34
|
+
scope: string;
|
|
35
|
+
checks: {
|
|
36
|
+
program: string;
|
|
37
|
+
ok: boolean;
|
|
38
|
+
version: string | undefined;
|
|
39
|
+
remedy: string | null;
|
|
40
|
+
}[];
|
|
41
|
+
platform: string;
|
|
42
|
+
template: "react-fastapi" | "react-spring" | "react-nest" | "next-fullstack";
|
|
43
|
+
}>;
|
|
44
|
+
export declare function contentDigest(dir: string): Promise<string>;
|
|
45
|
+
export declare function verify(directory: string): Promise<Run>;
|
|
46
|
+
export declare function report(directory: string): Promise<{
|
|
47
|
+
overallStatus: string;
|
|
48
|
+
reason: string;
|
|
49
|
+
} | {
|
|
50
|
+
validity: string;
|
|
51
|
+
schemaVersion: 1;
|
|
52
|
+
runId: string;
|
|
53
|
+
template: string;
|
|
54
|
+
cliVersion: string;
|
|
55
|
+
platform: string;
|
|
56
|
+
runtime: string;
|
|
57
|
+
startedAt: string;
|
|
58
|
+
finishedAt: string;
|
|
59
|
+
beforeDigest: string;
|
|
60
|
+
afterDigest: string;
|
|
61
|
+
overallStatus: "PASS" | "FAIL" | "NOT RUN";
|
|
62
|
+
checks: Check[];
|
|
63
|
+
exitCode: number;
|
|
64
|
+
warnings: string[];
|
|
65
|
+
reason?: undefined;
|
|
66
|
+
}>;
|
|
67
|
+
export {};
|