@cherishxn/agent-scaffold 0.0.0-stage → 1.0.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 +71 -2
- package/THIRD_PARTY_NOTICES.md +14 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +100 -0
- package/dist/generate.d.ts +55 -0
- package/dist/generate.js +154 -0
- package/dist/model.d.ts +33 -0
- package/dist/model.js +24 -0
- package/dist/verify.d.ts +61 -0
- package/dist/verify.js +264 -0
- package/package.json +49 -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 +6 -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 +8 -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 +8 -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 +8 -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 +55 -0
- package/templates/next-fullstack-antd/THIRD_PARTY_NOTICES.md +14 -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 +9 -0
- package/templates/next-fullstack-antd/docs/api.d.ts +516 -0
- package/templates/next-fullstack-antd/docs/openapi.json +439 -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 +440 -0
- package/templates/next-fullstack-antd/package.json +21 -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/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 +118 -0
- package/templates/next-fullstack-antd/tests/contract.spec.ts +47 -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 +8 -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 +8 -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 +8 -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 +55 -0
- package/templates/next-fullstack-shadcn/THIRD_PARTY_NOTICES.md +14 -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 +9 -0
- package/templates/next-fullstack-shadcn/docs/api.d.ts +516 -0
- package/templates/next-fullstack-shadcn/docs/openapi.json +439 -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 +440 -0
- package/templates/next-fullstack-shadcn/package.json +21 -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/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 +118 -0
- package/templates/next-fullstack-shadcn/tests/contract.spec.ts +47 -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 +8 -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 +8 -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 +8 -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 +55 -0
- package/templates/react-fastapi-antd/THIRD_PARTY_NOTICES.md +14 -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 +9 -0
- package/templates/react-fastapi-antd/docs/api.d.ts +516 -0
- package/templates/react-fastapi-antd/docs/openapi.json +439 -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 +440 -0
- package/templates/react-fastapi-antd/package.json +21 -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/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 +118 -0
- package/templates/react-fastapi-antd/tests/contract.spec.ts +47 -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 +8 -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 +8 -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 +8 -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 +55 -0
- package/templates/react-fastapi-shadcn/THIRD_PARTY_NOTICES.md +14 -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 +9 -0
- package/templates/react-fastapi-shadcn/docs/api.d.ts +516 -0
- package/templates/react-fastapi-shadcn/docs/openapi.json +439 -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 +440 -0
- package/templates/react-fastapi-shadcn/package.json +21 -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/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 +118 -0
- package/templates/react-fastapi-shadcn/tests/contract.spec.ts +47 -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 +8 -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 +8 -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 +8 -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 +55 -0
- package/templates/react-nest-antd/THIRD_PARTY_NOTICES.md +14 -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 +9 -0
- package/templates/react-nest-antd/docs/api.d.ts +516 -0
- package/templates/react-nest-antd/docs/openapi.json +439 -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 +440 -0
- package/templates/react-nest-antd/package.json +21 -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/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 +118 -0
- package/templates/react-nest-antd/tests/contract.spec.ts +47 -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 +8 -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 +8 -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 +8 -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 +55 -0
- package/templates/react-nest-shadcn/THIRD_PARTY_NOTICES.md +14 -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 +9 -0
- package/templates/react-nest-shadcn/docs/api.d.ts +516 -0
- package/templates/react-nest-shadcn/docs/openapi.json +439 -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 +440 -0
- package/templates/react-nest-shadcn/package.json +21 -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/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 +118 -0
- package/templates/react-nest-shadcn/tests/contract.spec.ts +47 -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 +8 -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 +8 -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 +8 -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 +55 -0
- package/templates/react-spring-antd/THIRD_PARTY_NOTICES.md +14 -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 +439 -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 +9 -0
- package/templates/react-spring-antd/docs/api.d.ts +516 -0
- package/templates/react-spring-antd/docs/openapi.json +439 -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 +440 -0
- package/templates/react-spring-antd/package.json +21 -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/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 +118 -0
- package/templates/react-spring-antd/tests/contract.spec.ts +47 -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 +8 -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 +8 -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 +8 -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 +55 -0
- package/templates/react-spring-shadcn/THIRD_PARTY_NOTICES.md +14 -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 +439 -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 +9 -0
- package/templates/react-spring-shadcn/docs/api.d.ts +516 -0
- package/templates/react-spring-shadcn/docs/openapi.json +439 -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 +440 -0
- package/templates/react-spring-shadcn/package.json +21 -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/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 +118 -0
- package/templates/react-spring-shadcn/tests/contract.spec.ts +47 -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
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* Generated by design:sync. Edit design/widgets.css. */
|
|
2
|
+
/* These semantic hooks belong to the widget contract, never to a library. */
|
|
3
|
+
[data-widget]{box-sizing:border-box!important;font-family:var(--design-typography-body-font-family)!important;letter-spacing:normal!important;text-transform:none!important;box-shadow:none!important}
|
|
4
|
+
[data-widget="button"]{display:inline-flex!important;align-items:center!important;justify-content:center!important;gap:8px!important;vertical-align:middle!important;position:relative!important;min-width:0!important;height:var(--design-widgets-button-height)!important;min-height:var(--design-widgets-button-height)!important;padding:var(--design-widgets-button-padding-y) var(--design-widgets-button-padding-x)!important;margin:0!important;border:var(--design-widgets-button-border-width) solid transparent!important;border-radius:var(--design-widgets-button-radius)!important;font-size:var(--design-widgets-button-font-size)!important;font-weight:var(--design-widgets-button-font-weight)!important;line-height:var(--design-widgets-button-line-height)!important;cursor:pointer!important;text-align:center!important;white-space:nowrap!important;transition:background-color 180ms,border-color 180ms,color 180ms!important}
|
|
5
|
+
[data-widget="button"] [data-part="label"]{display:inline!important;margin:0!important;padding:0!important;font:inherit!important;line-height:inherit!important;color:inherit!important}
|
|
6
|
+
[data-widget="button"][data-variant="primary"]{background:var(--design-colors-primary)!important;color:var(--design-colors-primary-text)!important}
|
|
7
|
+
[data-widget="button"][data-variant="primary"]:hover{background:var(--design-colors-primary-hover)!important}
|
|
8
|
+
[data-widget="button"][data-variant="primary"]:active{background:var(--design-colors-primary-active)!important}
|
|
9
|
+
[data-widget="button"][data-variant="secondary"]{background:var(--design-colors-control-background)!important;color:var(--design-colors-secondary-text)!important;border-color:var(--design-colors-secondary-border)!important}
|
|
10
|
+
[data-widget="button"][data-variant="secondary"]:hover,[data-widget="button"][data-variant="secondary"]:active{background:var(--design-colors-secondary-hover)!important}
|
|
11
|
+
[data-widget="button"][data-variant="danger"]{background:var(--design-colors-danger-background)!important;color:var(--design-colors-danger-text)!important;border-color:var(--design-colors-danger-border)!important}
|
|
12
|
+
[data-widget="button"][data-variant="danger"]:hover,[data-widget="button"][data-variant="danger"]:active{background:var(--design-colors-danger-hover)!important}
|
|
13
|
+
[data-widget="button"]:disabled{opacity:.5!important;cursor:not-allowed!important;pointer-events:none!important}
|
|
14
|
+
[data-widget="input"],[data-widget="textarea"]{display:block!important;width:100%!important;min-width:0!important;margin:0!important;padding:var(--design-widgets-input-padding-y) var(--design-widgets-input-padding-x)!important;border:var(--design-widgets-input-border-width) solid var(--design-colors-control-border)!important;border-radius:var(--design-widgets-input-radius)!important;background:var(--design-colors-control-background)!important;color:var(--design-colors-text)!important;font-size:var(--design-widgets-input-font-size)!important;font-weight:400!important;line-height:var(--design-widgets-input-line-height)!important;outline:none!important;transition:border-color 180ms!important}
|
|
15
|
+
[data-widget="input"]{height:var(--design-widgets-input-height)!important;min-height:var(--design-widgets-input-height)!important}
|
|
16
|
+
[data-widget="textarea"]{padding:var(--design-widgets-textarea-padding-y) var(--design-widgets-textarea-padding-x)!important;border-width:var(--design-widgets-textarea-border-width)!important;border-radius:var(--design-widgets-textarea-radius)!important;font-size:var(--design-widgets-textarea-font-size)!important;line-height:var(--design-widgets-textarea-line-height)!important;resize:vertical!important;min-height:0!important}
|
|
17
|
+
[data-widget="input"]::placeholder,[data-widget="textarea"]::placeholder{color:var(--design-colors-muted)!important;opacity:1!important}
|
|
18
|
+
[data-widget="input"]:hover,[data-widget="textarea"]:hover{border-color:var(--design-colors-control-focus)!important}
|
|
19
|
+
[data-widget="input"][aria-invalid="true"],[data-widget="textarea"][aria-invalid="true"]{border-color:var(--design-colors-error-border)!important}
|
|
20
|
+
[data-widget="input"]:disabled,[data-widget="textarea"]:disabled{opacity:.5!important;cursor:not-allowed!important}
|
|
21
|
+
[data-widget="button"]:focus-visible,[data-widget="input"]:focus,[data-widget="textarea"]:focus{outline:2px solid var(--design-colors-control-focus)!important;outline-offset:2px!important}
|
|
22
|
+
[data-widget="alert"]{display:flex!important;align-items:flex-start!important;gap:var(--design-widgets-alert-gap)!important;margin:16px 0!important;padding:var(--design-widgets-alert-padding-y) var(--design-widgets-alert-padding-x)!important;border:var(--design-widgets-alert-border-width) solid var(--design-colors-error-border)!important;border-radius:var(--design-widgets-alert-radius)!important;background:var(--design-colors-error-background)!important;color:var(--design-colors-error-text)!important;font-size:var(--design-widgets-alert-font-size)!important;font-weight:400!important;line-height:var(--design-widgets-alert-line-height)!important}
|
|
23
|
+
[data-widget="alert"][data-variant="success"]{background:var(--design-colors-success-background)!important;color:var(--design-colors-success-text)!important;border-color:var(--design-colors-success-border)!important}
|
|
24
|
+
[data-widget="alert"] [data-part="icon"]{display:block!important;width:var(--design-widgets-alert-icon-size)!important;height:var(--design-widgets-alert-icon-size)!important;flex:none!important;margin:3px 0 0!important;color:inherit!important}
|
|
25
|
+
[data-widget="alert"] [data-part="message"]{display:block!important;margin:0!important;padding:0!important;font:inherit!important;line-height:inherit!important;color:inherit!important;overflow-wrap:anywhere}
|
|
26
|
+
[data-widget="badge"]{display:inline-flex!important;align-items:center!important;vertical-align:middle!important;white-space:nowrap!important;margin:0!important;padding:var(--design-widgets-badge-padding-y) var(--design-widgets-badge-padding-x)!important;border:var(--design-widgets-badge-border-width) solid var(--design-colors-badge-border)!important;border-radius:var(--design-widgets-badge-radius)!important;background:transparent!important;color:var(--design-colors-badge-text)!important;font-size:var(--design-widgets-badge-font-size)!important;font-weight:400!important;line-height:var(--design-widgets-badge-line-height)!important}
|
|
27
|
+
[data-widget="panel"]{background:var(--design-colors-surface)!important;border:var(--design-widgets-panel-border-width) solid var(--design-colors-panel-border)!important;border-radius:var(--design-widgets-panel-radius)!important;padding:var(--design-widgets-panel-padding)!important;box-shadow:var(--design-effects-panel-shadow)!important}
|
|
28
|
+
[data-widget="field"]{display:flex!important;flex-direction:column!important;gap:var(--design-widgets-field-gap)!important;margin:var(--design-widgets-field-margin-y) 0!important}
|
|
29
|
+
[data-widget="field"]>[data-part="label"]{font-size:var(--design-widgets-field-font-size)!important;font-weight:var(--design-widgets-field-font-weight)!important;line-height:var(--design-widgets-field-line-height)!important}
|
|
30
|
+
@media(max-width:760px){[data-widget="panel"]{padding:var(--design-spacing-s20)!important}}
|
|
31
|
+
@media(prefers-reduced-motion:reduce){[data-widget]{transition-duration:0.01ms!important}}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {createElement,Fragment,type ReactNode} from 'react';
|
|
2
|
+
import design from './design-runtime.json';
|
|
3
|
+
import type {WidgetSet} from './widget-types';
|
|
4
|
+
type Node={element:string;region:string;slot?:string;children?:Node[]};
|
|
5
|
+
export function Structure({name,slots,widgets}:{widgets:WidgetSet;name:'root'|'checking'|'login'|'workspace';slots:Record<string,ReactNode>}) {
|
|
6
|
+
const {Panel}=widgets;
|
|
7
|
+
const node:Node=name==='root'?design.structure.root:design.structure.pages[name];
|
|
8
|
+
function render(item:Node):ReactNode {
|
|
9
|
+
const children=item.slot?slots[item.slot]:item.children?.map(render);
|
|
10
|
+
if(item.element==='slot')return <Fragment key={item.region}>{children}</Fragment>;
|
|
11
|
+
if(item.slot&&children==null)return null;
|
|
12
|
+
const props={className:item.region,'data-region':item.region,...(item.element==='a'?{href:'/'}:{})};
|
|
13
|
+
return item.element==='panel'?<Panel key={item.region} {...props}>{children}</Panel>:createElement(item.element,{key:item.region,...props},children);
|
|
14
|
+
}
|
|
15
|
+
return render(node);
|
|
16
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
import {cva} from 'class-variance-authority';
|
|
3
|
+
import {WidgetIcon} from './widget-icon';
|
|
4
|
+
import type {AlertProps,ButtonProps,FieldProps,InputProps,PanelProps,TextAreaProps} from './widget-types';
|
|
5
|
+
const button=cva('inline-flex items-center justify-center');
|
|
6
|
+
export function Button({children,variant='primary',loading=false,disabled,className,type='button',...props}:ButtonProps){return <button {...props} type={type} data-widget="button" data-variant={variant} aria-busy={loading||undefined} disabled={disabled||loading} className={button({className})}><span data-part="label">{children}</span></button>;}
|
|
7
|
+
export function Input({invalid,...props}:InputProps){return <input {...props} data-widget="input" aria-invalid={invalid||undefined}/>;}
|
|
8
|
+
export function TextArea({invalid,...props}:TextAreaProps){return <textarea {...props} data-widget="textarea" aria-invalid={invalid||undefined}/>;}
|
|
9
|
+
export function Panel({children,className='',...props}:PanelProps){return <section {...props} data-widget="panel" className={`panel ${className}`}>{children}</section>;}
|
|
10
|
+
export function Field({children,label,htmlFor}:FieldProps){return <div data-widget="field" className="field"><label data-part="label" htmlFor={htmlFor}>{label}</label><div data-part="control">{children}</div></div>;}
|
|
11
|
+
export function Alert({children,variant='error'}:AlertProps){return <div data-widget="alert" data-variant={variant} role={variant==='error'?'alert':'status'}><WidgetIcon kind={variant}/><div data-part="message">{children}</div></div>;}
|
|
12
|
+
export function Badge({children}:{children:React.ReactNode}){return <span data-widget="badge" className="badge"><span data-part="label">{children}</span></span>;}
|
|
13
|
+
export function Theme({children}:{children:React.ReactNode}){return <>{children}</>;}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import design from './design-runtime.json';
|
|
2
|
+
export function WidgetIcon({kind}:{kind:'error'|'success'}) {
|
|
3
|
+
const icon=design.widgets.icons[kind];
|
|
4
|
+
return <svg data-part="icon" aria-hidden="true" viewBox={icon.viewBox} fill="none" stroke="currentColor" strokeWidth={icon.strokeWidth} strokeLinecap="round" strokeLinejoin="round">{icon.paths.map((path,index)=><path key={index} d={path}/>)}</svg>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
export type ButtonProps=Omit<React.ButtonHTMLAttributes<HTMLButtonElement>,'color'>&{variant?:'primary'|'secondary'|'danger';loading?:boolean};
|
|
3
|
+
export type InputProps=Omit<React.InputHTMLAttributes<HTMLInputElement>,'size'>&{invalid?:boolean};
|
|
4
|
+
export type TextAreaProps=React.TextareaHTMLAttributes<HTMLTextAreaElement>&{invalid?:boolean};
|
|
5
|
+
export type AlertProps={children:React.ReactNode;variant?:'error'|'success'};
|
|
6
|
+
export type PanelProps=React.HTMLAttributes<HTMLElement>;
|
|
7
|
+
export type FieldProps={children:React.ReactNode;label:string;htmlFor:string};
|
|
8
|
+
|
|
9
|
+
export type WidgetSet={
|
|
10
|
+
Button:React.ComponentType<ButtonProps>;Input:React.ComponentType<InputProps>;TextArea:React.ComponentType<TextAreaProps>;
|
|
11
|
+
Alert:React.ComponentType<AlertProps>;Panel:React.ComponentType<PanelProps>;Field:React.ComponentType<FieldProps>;
|
|
12
|
+
Badge:React.ComponentType<{children:React.ReactNode}>;Theme:React.ComponentType<{children:React.ReactNode}>;
|
|
13
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export type User={id:string;email:string};
|
|
2
|
+
export type RecordItem={id:string;title:string;content:string;created_at:string;updated_at:string};
|
|
3
|
+
export type RecordPage={items:RecordItem[];total:number;page:number;pageSize:number};
|
|
4
|
+
export type WorkspaceState={user:User|null;checking:boolean;email:string;password:string;list:RecordPage;page:number;selected:string|null;title:string;content:string;editing:boolean;busy:boolean;loading:boolean;error:string;notice:string};
|
|
5
|
+
const emptyList=():RecordPage=>({items:[],total:0,page:1,pageSize:10});
|
|
6
|
+
export const initialWorkspaceState=():WorkspaceState=>({user:null,checking:true,email:'',password:'',list:emptyList(),page:1,selected:null,title:'',content:'',editing:false,busy:false,loading:false,error:'',notice:''});
|
|
7
|
+
class StaleRequest extends Error {}
|
|
8
|
+
class ApiError extends Error {constructor(message:string,public status:number){super(message);}}
|
|
9
|
+
export function validateRecord(title:string,content:string):string {
|
|
10
|
+
const length=Array.from(title.trim()).length;
|
|
11
|
+
if(length<1||length>120)return '标题需为 1–120 个字符。';
|
|
12
|
+
if(Array.from(content).length>10000)return '正文最多 10,000 个字符。';
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
/** Framework-neutral business model. Views subscribe and forward user intent. */
|
|
16
|
+
export function createWorkspaceModel(request:typeof fetch=fetch) {
|
|
17
|
+
let state=initialWorkspaceState(),token:string|null=null;
|
|
18
|
+
let identityEpoch=0,refreshSequence=0,busySequence=0,lifecycle=0;
|
|
19
|
+
const requests=new Set<AbortController>(),listeners=new Set<()=>void>();
|
|
20
|
+
const patch=(value:Partial<WorkspaceState>)=>{state={...state,...value};for(const listener of listeners)listener();};
|
|
21
|
+
function cancelRequests(){for(const controller of requests)controller.abort();requests.clear();}
|
|
22
|
+
function clearIdentity(){
|
|
23
|
+
identityEpoch++;refreshSequence++;busySequence++;cancelRequests();token=null;
|
|
24
|
+
patch({user:null,list:emptyList(),page:1,selected:null,title:'',content:'',editing:false,notice:'',error:'',password:'',busy:false,loading:false});
|
|
25
|
+
}
|
|
26
|
+
async function api<T>(path:string,method='GET',body?:unknown):Promise<T> {
|
|
27
|
+
const epoch=identityEpoch,controller=new AbortController();requests.add(controller);
|
|
28
|
+
const timer=setTimeout(()=>controller.abort(),15000);
|
|
29
|
+
try{
|
|
30
|
+
const response=await request(`/api${path}`,{method,credentials:'same-origin',headers:{...(body===undefined?{}:{'Content-Type':'application/json'}),...(token?{Authorization:`Bearer ${token}`}:{})},...(body===undefined?{}:{body:JSON.stringify(body)}),signal:controller.signal});
|
|
31
|
+
if(epoch!==identityEpoch)throw new StaleRequest();
|
|
32
|
+
if(response.status===204)return undefined as T;
|
|
33
|
+
const data=await response.json();
|
|
34
|
+
if(epoch!==identityEpoch)throw new StaleRequest();
|
|
35
|
+
if(!response.ok){if(response.status===401)clearIdentity();throw new ApiError(data.error?.message||'请求失败,请检查输入后重试。',response.status);}
|
|
36
|
+
return data as T;
|
|
37
|
+
}catch(error){
|
|
38
|
+
if(error instanceof ApiError||error instanceof StaleRequest)throw error;
|
|
39
|
+
if(epoch!==identityEpoch)throw new StaleRequest();
|
|
40
|
+
throw new Error('请求失败或超时,输入已保留。请先查看记录,确认结果后再操作。',{cause:error});
|
|
41
|
+
}finally{clearTimeout(timer);requests.delete(controller);}
|
|
42
|
+
}
|
|
43
|
+
const report=(error:unknown)=>{if(!(error instanceof StaleRequest))patch({error:(error as Error).message});};
|
|
44
|
+
function busy(){const sequence=++busySequence;patch({busy:true,error:''});return ()=>{if(sequence===busySequence)patch({busy:false});};}
|
|
45
|
+
async function refresh(){
|
|
46
|
+
const sequence=++refreshSequence;patch({loading:true});
|
|
47
|
+
try{const list=await api<RecordPage>(`/records?page=${state.page}&pageSize=10`);if(sequence===refreshSequence)patch({list});}
|
|
48
|
+
catch(error){if(sequence===refreshSequence)report(error);}
|
|
49
|
+
finally{if(sequence===refreshSequence)patch({loading:false});}
|
|
50
|
+
}
|
|
51
|
+
async function start(){
|
|
52
|
+
const current=++lifecycle;patch({checking:true});
|
|
53
|
+
try{const data=await api<{user:User}>('/auth/me');if(current===lifecycle){patch({user:data.user});await refresh();}}
|
|
54
|
+
catch(error){if(current===lifecycle&&!(error instanceof ApiError&&error.status===401))report(error);}
|
|
55
|
+
finally{if(current===lifecycle)patch({checking:false});}
|
|
56
|
+
}
|
|
57
|
+
function stop(){lifecycle++;identityEpoch++;refreshSequence++;busySequence++;cancelRequests();}
|
|
58
|
+
async function login(){
|
|
59
|
+
const done=busy();
|
|
60
|
+
try{const data=await api<{user:User;token?:string}>('/auth/login','POST',{email:state.email,password:state.password});clearIdentity();token=data.token??null;patch({user:data.user,password:'',notice:''});await refresh();}
|
|
61
|
+
catch(error){report(error);}finally{done();}
|
|
62
|
+
}
|
|
63
|
+
async function logout(){const done=busy();try{await api('/auth/logout','POST',{});clearIdentity();}catch(error){report(error);}finally{done();}}
|
|
64
|
+
function create(){patch({selected:null,title:'',content:'',editing:true,error:'',notice:''});}
|
|
65
|
+
async function open(id:string){
|
|
66
|
+
const done=busy();patch({notice:''});
|
|
67
|
+
try{const data=await api<RecordItem>(`/records/${id}`);patch({selected:data.id,title:data.title,content:data.content,editing:true});}
|
|
68
|
+
catch(error){report(error);}finally{done();}
|
|
69
|
+
}
|
|
70
|
+
async function save(){
|
|
71
|
+
const error=validateRecord(state.title,state.content);patch({error,notice:''});if(error)return;
|
|
72
|
+
const done=busy();
|
|
73
|
+
try{const data=await api<RecordItem>(state.selected?`/records/${state.selected}`:'/records',state.selected?'PUT':'POST',{title:state.title,content:state.content});patch({selected:data.id,title:data.title,content:data.content,notice:'已保存'});await refresh();}
|
|
74
|
+
catch(error){report(error);}finally{done();}
|
|
75
|
+
}
|
|
76
|
+
async function remove(confirmed:boolean){
|
|
77
|
+
if(!state.selected||!confirmed)return;
|
|
78
|
+
const done=busy();patch({notice:''});
|
|
79
|
+
try{await api(`/records/${state.selected}`,'DELETE');patch({editing:false,selected:null,title:'',content:'',notice:'已删除',...(state.page>1&&state.list.items.length===1?{page:state.page-1}:{})});await refresh();}
|
|
80
|
+
catch(error){report(error);}finally{done();}
|
|
81
|
+
}
|
|
82
|
+
async function changePage(page:number){if(page<1||!Number.isInteger(page))return;patch({page});await refresh();}
|
|
83
|
+
return {getSnapshot:()=>state,subscribe:(listener:()=>void)=>{listeners.add(listener);return ()=>{listeners.delete(listener);};},start,stop,login,logout,create,open,save,remove,changePage,setField:(field:'email'|'password'|'title'|'content',value:string)=>patch({[field]:value})};
|
|
84
|
+
}
|
|
85
|
+
export type WorkspaceModel=ReturnType<typeof createWorkspaceModel>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2017",
|
|
4
|
+
"lib": [
|
|
5
|
+
"dom",
|
|
6
|
+
"dom.iterable",
|
|
7
|
+
"esnext"
|
|
8
|
+
],
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"strict": true,
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"esModuleInterop": true,
|
|
14
|
+
"module": "esnext",
|
|
15
|
+
"moduleResolution": "bundler",
|
|
16
|
+
"resolveJsonModule": true,
|
|
17
|
+
"isolatedModules": true,
|
|
18
|
+
"jsx": "react-jsx",
|
|
19
|
+
"incremental": false,
|
|
20
|
+
"plugins": [
|
|
21
|
+
{
|
|
22
|
+
"name": "next"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"paths": {
|
|
26
|
+
"@/*": [
|
|
27
|
+
"./*"
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"include": [
|
|
32
|
+
"next-env.d.ts",
|
|
33
|
+
"**/*.ts",
|
|
34
|
+
"**/*.tsx",
|
|
35
|
+
".next/types/**/*.ts",
|
|
36
|
+
".next/dev/types/**/*.ts",
|
|
37
|
+
"**/*.mts"
|
|
38
|
+
],
|
|
39
|
+
"exclude": [
|
|
40
|
+
"node_modules"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-contract
|
|
3
|
+
description: Implement or change UI from this project's design contract, adapt its component library, and verify every declared widget state and page scenario. Use for UI implementation, design-token changes, library adaptation, or design drift.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Read root DESIGN.md, design/widgets.json, and design/structure.json before UI work. The shared design source is design/tokens.json plus the framework-neutral layout/widget styles and guide. Generated files are outputs, never the edit target.
|
|
7
|
+
|
|
8
|
+
Keep these boundaries:
|
|
9
|
+
- Design decisions belong in the design source only when the user requests a design change. A library default is not a reason to change the contract.
|
|
10
|
+
- Widget anatomy, variants, states, geometry and icon paths belong in widgets.json. A new state needs a fixture; do not silently skip unsupported states.
|
|
11
|
+
- Page regions and nesting belong in structure.json; framework views bind those slots to content.
|
|
12
|
+
- Business state, validation and identity/request isolation belong in web/src/workspace-model.ts, which has no framework or component-library imports.
|
|
13
|
+
- Library API names, DOM fixes and theme translation belong in web/src/ui.tsx. Use the canonical icon geometry; never silently substitute a similar library icon.
|
|
14
|
+
|
|
15
|
+
After changes, run `npm run design:sync`, `npm run design:check`, then `npm run design:verify`. Run the affected business checks from README as well. Design verification starts a local, temporary fixture server, compares the selected adapter with the independent semantic HTML reference, and cleans its own fixture files. Dependencies and the Playwright Chromium browser must already be installed with the project's documented install command.
|
|
16
|
+
|
|
17
|
+
The checker enumerates every variant/state in widgets.json and every page scenario in structure.json at every declared viewport. Position tolerance is 0.6 CSS px; computed colors, radii and SVG geometry must be identical. Keep browser, font availability, DPR, locale and content fixed. A screenshot is supporting evidence, not the pass criterion. Missing fixtures, TODOs, errors or incomplete coverage mean FAIL/NOT RUN, never PASS.
|
|
18
|
+
|
|
19
|
+
For scaffold maintainers, root `npm run design:verify` regenerates and checks all eight stack/UI combinations and compares their actual measurements. A generated project's command covers its selected adapter against the reference; it does not claim that uninstalled libraries or other platforms were tested. A new framework needs its view binding; adding a library also requires dependency/lockfile registration, without changing design or business intent.
|
|
20
|
+
|
|
21
|
+
When extracting a new website reference, inspect rendered desktop/mobile pages and computed styles. Separate observed values from approved adaptations. Record source limitations; do not infer exact values from screenshots or convert brand-specific content into a product requirement. Useful upstream approaches: [create-design-md](https://github.com/ibelick/ui-skills/blob/main/skills/create-design-md/SKILL.md) for evidence-based extraction and [Impeccable](https://github.com/pbakaus/impeccable) for targeted refinement. They are optional references, not runtime dependencies or authorization to install tools.
|
|
22
|
+
|
|
23
|
+
Report the changed layer, exact commands, coverage and result.json path. Fix adapter deviations rather than weakening tolerances, dropping cases, accepting a new baseline, or changing the shared design to fit one library.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-work
|
|
3
|
+
description: Implement or fix this generated project using its documented commands and verify the requested behavior.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Read AGENTS.md, docs/PROJECT.md and README.md. Check Git changes and the current request. Implement only the requested behavior. Run the relevant project checks, inspect the diff, and report files, commands and actual results. A failed or unrun check is not a pass. Follow the task's existing authorization for external writes.
|
|
7
|
+
|
|
8
|
+
For UI work, read root DESIGN.md before editing. Follow its source/sync workflow, use the bundled design-contract Skill, run `npm run design:check` and `npm run design:verify`, and verify affected business flows in the browser.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-contract
|
|
3
|
+
description: Implement or change UI from this project's design contract, adapt its component library, and verify every declared widget state and page scenario. Use for UI implementation, design-token changes, library adaptation, or design drift.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Read root DESIGN.md, design/widgets.json, and design/structure.json before UI work. The shared design source is design/tokens.json plus the framework-neutral layout/widget styles and guide. Generated files are outputs, never the edit target.
|
|
7
|
+
|
|
8
|
+
Keep these boundaries:
|
|
9
|
+
- Design decisions belong in the design source only when the user requests a design change. A library default is not a reason to change the contract.
|
|
10
|
+
- Widget anatomy, variants, states, geometry and icon paths belong in widgets.json. A new state needs a fixture; do not silently skip unsupported states.
|
|
11
|
+
- Page regions and nesting belong in structure.json; framework views bind those slots to content.
|
|
12
|
+
- Business state, validation and identity/request isolation belong in web/src/workspace-model.ts, which has no framework or component-library imports.
|
|
13
|
+
- Library API names, DOM fixes and theme translation belong in web/src/ui.tsx. Use the canonical icon geometry; never silently substitute a similar library icon.
|
|
14
|
+
|
|
15
|
+
After changes, run `npm run design:sync`, `npm run design:check`, then `npm run design:verify`. Run the affected business checks from README as well. Design verification starts a local, temporary fixture server, compares the selected adapter with the independent semantic HTML reference, and cleans its own fixture files. Dependencies and the Playwright Chromium browser must already be installed with the project's documented install command.
|
|
16
|
+
|
|
17
|
+
The checker enumerates every variant/state in widgets.json and every page scenario in structure.json at every declared viewport. Position tolerance is 0.6 CSS px; computed colors, radii and SVG geometry must be identical. Keep browser, font availability, DPR, locale and content fixed. A screenshot is supporting evidence, not the pass criterion. Missing fixtures, TODOs, errors or incomplete coverage mean FAIL/NOT RUN, never PASS.
|
|
18
|
+
|
|
19
|
+
For scaffold maintainers, root `npm run design:verify` regenerates and checks all eight stack/UI combinations and compares their actual measurements. A generated project's command covers its selected adapter against the reference; it does not claim that uninstalled libraries or other platforms were tested. A new framework needs its view binding; adding a library also requires dependency/lockfile registration, without changing design or business intent.
|
|
20
|
+
|
|
21
|
+
When extracting a new website reference, inspect rendered desktop/mobile pages and computed styles. Separate observed values from approved adaptations. Record source limitations; do not infer exact values from screenshots or convert brand-specific content into a product requirement. Useful upstream approaches: [create-design-md](https://github.com/ibelick/ui-skills/blob/main/skills/create-design-md/SKILL.md) for evidence-based extraction and [Impeccable](https://github.com/pbakaus/impeccable) for targeted refinement. They are optional references, not runtime dependencies or authorization to install tools.
|
|
22
|
+
|
|
23
|
+
Report the changed layer, exact commands, coverage and result.json path. Fix adapter deviations rather than weakening tolerances, dropping cases, accepting a new baseline, or changing the shared design to fit one library.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-work
|
|
3
|
+
description: Implement or fix this generated project using its documented commands and verify the requested behavior.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Read AGENTS.md, docs/PROJECT.md and README.md. Check Git changes and the current request. Implement only the requested behavior. Run the relevant project checks, inspect the diff, and report files, commands and actual results. A failed or unrun check is not a pass. Follow the task's existing authorization for external writes.
|
|
7
|
+
|
|
8
|
+
For UI work, read root DESIGN.md before editing. Follow its source/sync workflow, use the bundled design-contract Skill, run `npm run design:check` and `npm run design:verify`, and verify affected business flows in the browser.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
**/node_modules
|
|
2
|
+
**/.venv
|
|
3
|
+
**/.next
|
|
4
|
+
**/target
|
|
5
|
+
**/dist
|
|
6
|
+
**/__pycache__
|
|
7
|
+
.git
|
|
8
|
+
.env
|
|
9
|
+
.env.*
|
|
10
|
+
.scaffold-local-credentials
|
|
11
|
+
.scaffold-runs
|
|
12
|
+
reports
|
|
13
|
+
|
|
14
|
+
**/test-results
|
|
15
|
+
**/playwright-report
|
|
16
|
+
**/.env
|
|
17
|
+
**/.env.*
|
|
18
|
+
!**/.env.example
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Copy only for explicit local development. Never use production credentials in verify.
|
|
2
|
+
APP_ORIGIN=http://localhost:5173
|
|
3
|
+
PORT=8000
|
|
4
|
+
WEB_PORT=5173
|
|
5
|
+
POSTGRES_PORT=54329
|
|
6
|
+
POSTGRES_USER=app
|
|
7
|
+
POSTGRES_PASSWORD=replace-with-local-random-password
|
|
8
|
+
POSTGRES_DB=app
|
|
9
|
+
DATABASE_URL=postgresql://app:replace-with-local-random-password@localhost:54329/app
|
|
10
|
+
AUTH_SECRET=replace-with-at-least-32-random-characters
|
|
11
|
+
SEED_A_EMAIL=alice@example.test
|
|
12
|
+
SEED_B_EMAIL=bob@example.test
|
|
13
|
+
SEED_PASSWORD=replace-with-local-random-password
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-contract
|
|
3
|
+
description: Implement or change UI from this project's design contract, adapt its component library, and verify every declared widget state and page scenario. Use for UI implementation, design-token changes, library adaptation, or design drift.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Read root DESIGN.md, design/widgets.json, and design/structure.json before UI work. The shared design source is design/tokens.json plus the framework-neutral layout/widget styles and guide. Generated files are outputs, never the edit target.
|
|
7
|
+
|
|
8
|
+
Keep these boundaries:
|
|
9
|
+
- Design decisions belong in the design source only when the user requests a design change. A library default is not a reason to change the contract.
|
|
10
|
+
- Widget anatomy, variants, states, geometry and icon paths belong in widgets.json. A new state needs a fixture; do not silently skip unsupported states.
|
|
11
|
+
- Page regions and nesting belong in structure.json; framework views bind those slots to content.
|
|
12
|
+
- Business state, validation and identity/request isolation belong in web/src/workspace-model.ts, which has no framework or component-library imports.
|
|
13
|
+
- Library API names, DOM fixes and theme translation belong in web/src/ui.tsx. Use the canonical icon geometry; never silently substitute a similar library icon.
|
|
14
|
+
|
|
15
|
+
After changes, run `npm run design:sync`, `npm run design:check`, then `npm run design:verify`. Run the affected business checks from README as well. Design verification starts a local, temporary fixture server, compares the selected adapter with the independent semantic HTML reference, and cleans its own fixture files. Dependencies and the Playwright Chromium browser must already be installed with the project's documented install command.
|
|
16
|
+
|
|
17
|
+
The checker enumerates every variant/state in widgets.json and every page scenario in structure.json at every declared viewport. Position tolerance is 0.6 CSS px; computed colors, radii and SVG geometry must be identical. Keep browser, font availability, DPR, locale and content fixed. A screenshot is supporting evidence, not the pass criterion. Missing fixtures, TODOs, errors or incomplete coverage mean FAIL/NOT RUN, never PASS.
|
|
18
|
+
|
|
19
|
+
For scaffold maintainers, root `npm run design:verify` regenerates and checks all eight stack/UI combinations and compares their actual measurements. A generated project's command covers its selected adapter against the reference; it does not claim that uninstalled libraries or other platforms were tested. A new framework needs its view binding; adding a library also requires dependency/lockfile registration, without changing design or business intent.
|
|
20
|
+
|
|
21
|
+
When extracting a new website reference, inspect rendered desktop/mobile pages and computed styles. Separate observed values from approved adaptations. Record source limitations; do not infer exact values from screenshots or convert brand-specific content into a product requirement. Useful upstream approaches: [create-design-md](https://github.com/ibelick/ui-skills/blob/main/skills/create-design-md/SKILL.md) for evidence-based extraction and [Impeccable](https://github.com/pbakaus/impeccable) for targeted refinement. They are optional references, not runtime dependencies or authorization to install tools.
|
|
22
|
+
|
|
23
|
+
Report the changed layer, exact commands, coverage and result.json path. Fix adapter deviations rather than weakening tolerances, dropping cases, accepting a new baseline, or changing the shared design to fit one library.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-work
|
|
3
|
+
description: Implement or fix this generated project using its documented commands and verify the requested behavior.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Read AGENTS.md, docs/PROJECT.md and README.md. Check Git changes and the current request. Implement only the requested behavior. Run the relevant project checks, inspect the diff, and report files, commands and actual results. A failed or unrun check is not a pass. Follow the task's existing authorization for external writes.
|
|
7
|
+
|
|
8
|
+
For UI work, read root DESIGN.md before editing. Follow its source/sync workflow, use the bundled design-contract Skill, run `npm run design:check` and `npm run design:verify`, and verify affected business flows in the browser.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# 项目规则
|
|
2
|
+
|
|
3
|
+
先读 README.md 的实际命令与 docs/PROJECT.md 的需求和架构。project.json 记录项目基本信息,个人记录是基础示例,简介不代表额外功能已经实现。
|
|
4
|
+
|
|
5
|
+
按需求实现并运行相关检查:安装、启动、构建成功;登录和增删改查真实持久化;用户 A 无法访问用户 B 的记录。自查差异,允许合理更新测试,不以删除断言、跳过检查或关闭类型校验掩盖失败。交付实际文件、命令、结果,未运行明确说明。
|
|
6
|
+
|
|
7
|
+
仅修改任务范围,保留其他改动。秘密只放本地环境,不提交或打印;模板 verify 使用隔离数据库。推送、发布和外部写入依任务授权执行。
|
|
8
|
+
|
|
9
|
+
需要开发指引时使用 project-work Skill;未自动发现时按以上规则和 README 执行。
|
|
10
|
+
|
|
11
|
+
修改 UI 前先读根目录 DESIGN.md。使用 design-contract Skill;设计源、同步命令和一致性检查以该文件为准。交付前运行 design:check 与 design:verify,报告实际覆盖范围。
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: "alpha"
|
|
3
|
+
name: "Scientific Workspace"
|
|
4
|
+
description: "从 CleerScience 提炼的通用深色科技视觉,适配可读、安静的工具型界面。"
|
|
5
|
+
colors:
|
|
6
|
+
primary: "#8fc3ff"
|
|
7
|
+
primary-hover: "#b5d8ff"
|
|
8
|
+
primary-active: "#69a9f3"
|
|
9
|
+
primary-text: "#02040a"
|
|
10
|
+
background: "#02040a"
|
|
11
|
+
text: "#f4f8ff"
|
|
12
|
+
surface: "#0b111d"
|
|
13
|
+
focus: "#8fc3ff"
|
|
14
|
+
border: "#283547"
|
|
15
|
+
brand: "#f4f8ff"
|
|
16
|
+
eyebrow: "#9baecb"
|
|
17
|
+
muted: "#a1afc3"
|
|
18
|
+
intro: "#b5c3d7"
|
|
19
|
+
panel-border: "#283547"
|
|
20
|
+
divider: "#202c3e"
|
|
21
|
+
record-text: "#f4f8ff"
|
|
22
|
+
record-meta: "#a1afc3"
|
|
23
|
+
record-hover: "#142237"
|
|
24
|
+
pagination-border: "#283547"
|
|
25
|
+
empty: "#a1afc3"
|
|
26
|
+
empty-heading: "#e2eeff"
|
|
27
|
+
success-background: "#102b25"
|
|
28
|
+
success-border: "#387c69"
|
|
29
|
+
success-text: "#a2e6cc"
|
|
30
|
+
error-background: "#311b24"
|
|
31
|
+
error-border: "#8f4c61"
|
|
32
|
+
error-text: "#ffbdcd"
|
|
33
|
+
footer-border: "#283547"
|
|
34
|
+
footer-text: "#a1afc3"
|
|
35
|
+
badge-border: "#435773"
|
|
36
|
+
badge-text: "#b5c3d7"
|
|
37
|
+
control-focus: "#8fc3ff"
|
|
38
|
+
control-border: "#657891"
|
|
39
|
+
control-background: "#080e18"
|
|
40
|
+
secondary-border: "#657891"
|
|
41
|
+
secondary-text: "#e2eeff"
|
|
42
|
+
secondary-hover: "#19283d"
|
|
43
|
+
danger-border: "#ad6578"
|
|
44
|
+
danger-background: "#311b24"
|
|
45
|
+
danger-text: "#ffbdcd"
|
|
46
|
+
danger-hover: "#472636"
|
|
47
|
+
typography:
|
|
48
|
+
body:
|
|
49
|
+
fontFamily: "Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Hiragino Sans GB\",\"Microsoft YaHei\",sans-serif"
|
|
50
|
+
fontSize: "16px"
|
|
51
|
+
lineHeight: 1.65
|
|
52
|
+
h1:
|
|
53
|
+
fontSize: "36px"
|
|
54
|
+
lineHeight: 1.2
|
|
55
|
+
letterSpacing: "-0.03em"
|
|
56
|
+
fontWeight: 560
|
|
57
|
+
login-heading:
|
|
58
|
+
fontSize: "48px"
|
|
59
|
+
lineHeight: 1.15
|
|
60
|
+
fontWeight: 560
|
|
61
|
+
letterSpacing: "-0.03em"
|
|
62
|
+
h2:
|
|
63
|
+
fontSize: "20px"
|
|
64
|
+
lineHeight: 1.4
|
|
65
|
+
fontWeight: 580
|
|
66
|
+
letterSpacing: "-0.02em"
|
|
67
|
+
h3:
|
|
68
|
+
fontSize: "18px"
|
|
69
|
+
fontWeight: 600
|
|
70
|
+
lineHeight: 1.5
|
|
71
|
+
label:
|
|
72
|
+
fontSize: "14px"
|
|
73
|
+
fontWeight: 600
|
|
74
|
+
eyebrow:
|
|
75
|
+
fontSize: "11px"
|
|
76
|
+
fontWeight: 700
|
|
77
|
+
letterSpacing: "0.22em"
|
|
78
|
+
lineHeight: 1.5
|
|
79
|
+
button:
|
|
80
|
+
fontSize: "14px"
|
|
81
|
+
fontWeight: 600
|
|
82
|
+
lineHeight: "20px"
|
|
83
|
+
caption:
|
|
84
|
+
fontSize: "12px"
|
|
85
|
+
intro:
|
|
86
|
+
fontSize: "18px"
|
|
87
|
+
lineHeight: 1.8
|
|
88
|
+
mobile-heading:
|
|
89
|
+
fontSize: "32px"
|
|
90
|
+
lineHeight: 1.2
|
|
91
|
+
mobile-page-heading:
|
|
92
|
+
fontSize: "28px"
|
|
93
|
+
lineHeight: 1.25
|
|
94
|
+
rounded:
|
|
95
|
+
md: "0px"
|
|
96
|
+
panel: "0px"
|
|
97
|
+
full: "0px"
|
|
98
|
+
spacing:
|
|
99
|
+
s0: "0px"
|
|
100
|
+
s1: "1px"
|
|
101
|
+
s2: "2px"
|
|
102
|
+
s3: "3px"
|
|
103
|
+
s4: "4px"
|
|
104
|
+
s6: "6px"
|
|
105
|
+
s8: "8px"
|
|
106
|
+
s10: "10px"
|
|
107
|
+
s12: "12px"
|
|
108
|
+
s14: "14px"
|
|
109
|
+
s15: "15px"
|
|
110
|
+
s16: "16px"
|
|
111
|
+
s18: "18px"
|
|
112
|
+
s20: "20px"
|
|
113
|
+
s22: "22px"
|
|
114
|
+
s24: "24px"
|
|
115
|
+
s26: "26px"
|
|
116
|
+
s28: "28px"
|
|
117
|
+
s30: "30px"
|
|
118
|
+
s32: "32px"
|
|
119
|
+
s34: "34px"
|
|
120
|
+
s38: "38px"
|
|
121
|
+
s44: "44px"
|
|
122
|
+
s48: "48px"
|
|
123
|
+
s60: "60px"
|
|
124
|
+
s80: "80px"
|
|
125
|
+
s88: "88px"
|
|
126
|
+
shell-max: "1240px"
|
|
127
|
+
login-max: "1020px"
|
|
128
|
+
intro-max: "460px"
|
|
129
|
+
login-card-max: "430px"
|
|
130
|
+
list-min: "260px"
|
|
131
|
+
footer-reserve: "155px"
|
|
132
|
+
mobile-breakpoint: "760px"
|
|
133
|
+
control-min: "44px"
|
|
134
|
+
components:
|
|
135
|
+
button-primary:
|
|
136
|
+
backgroundColor: "{colors.primary}"
|
|
137
|
+
textColor: "{colors.primary-text}"
|
|
138
|
+
rounded: "{rounded.md}"
|
|
139
|
+
height: "{spacing.control-min}"
|
|
140
|
+
panel:
|
|
141
|
+
backgroundColor: "{colors.surface}"
|
|
142
|
+
padding: "{spacing.s26}"
|
|
143
|
+
rounded: "{rounded.panel}"
|
|
144
|
+
input:
|
|
145
|
+
rounded: "{rounded.md}"
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Overview
|
|
149
|
+
|
|
150
|
+
**Scientific Workspace**:从 [CleerScience 官网](https://cleerscience.com/) 提炼的通用深色科技视觉。以近黑蓝底、冷白文字、冰蓝重点、直角薄边框和清晰排版传达秩序;各组件库使用同一份视觉、控件和结构规格。它服务于登录、列表与编辑任务,不把科学品牌、产品名或营销文案带入生成项目。
|
|
151
|
+
|
|
152
|
+
来源于 2026-10-20 对官网桌面 1440px 和手机 375px 的实际页面及计算样式观察。官网原值包括背景 #02040a、正文 #f4f8ff、冰蓝 #8fc3ff、0px 面板圆角;本模板沿用这些核心值。正文与控件对比度、实体表面、较小标题和 44px 以上操作尺寸是工具型界面的适配决定,并非官网原样复刻。背景视频、品牌标识、全屏叙事和科学插图不属于本模板。
|
|
153
|
+
|
|
154
|
+
**唯一编辑源**:`design/tokens.json`、`design/widgets.json`、`design/structure.json`、`design/guide.md` 及中立布局/控件样式。执行 `npm run design:sync` 生成本文件、design-tokens.css、design-layout.css、design-widgets.css、design-runtime.json,再执行 `npm run design:check`。不要直接修改派生产物;build/typecheck/lint 会拒绝漂移。YAML 是与组件库无关的有效 token;阴影等非标准字段在正文给出,避免伪装成官方 schema 字段。
|
|
155
|
+
|
|
156
|
+
## Colors
|
|
157
|
+
|
|
158
|
+
背景使用 `colors.background`,面板使用 `colors.surface`,输入区使用 `colors.control-background`。正文使用 `colors.text`,辅助说明使用 `colors.muted`,标题不降低透明度。不要把官网用于装饰的低透明度文字直接用于表单标签或必要说明。
|
|
159
|
+
|
|
160
|
+
`primary` 仅用于主要操作、当前选中项和可见焦点;按钮文字使用 `primary-text`,确保亮色按钮上的深色字可读。`primary-hover` / `primary-active` 表达交互状态。普通表面保持中性冷色,避免整页泛蓝或大面积发光。错误和成功使用各自的 background/border/text 组合,同时保留明确文字或状态角色。
|
|
161
|
+
|
|
162
|
+
必要文字对比度至少 4.5:1,焦点与操作控件边界至少 3:1;装饰分隔线可以更弱。对比度必须按实际背景检查,不能只比较两个透明 token。新项目若改变主色,需重新验证文字、hover、active 和焦点,不仅替换一个十六进制值。
|
|
163
|
+
|
|
164
|
+
## Typography
|
|
165
|
+
|
|
166
|
+
一套无衬线字体贯穿全站:Inter 可用时优先,否则落到系统字体与 PingFang SC / Microsoft YaHei;不主动下载字体。中文正文 16px、行高 1.65,标签 14px,辅助信息 12px;避免将官网 11px 导航字直接当作表单正文。
|
|
167
|
+
|
|
168
|
+
页面标题 36px、登录标题 48px,手机分别 28px/32px;h2 为 20px,h3 为 18px。标题使用 560–600 字重与轻微负字距,中文不采用官网展示标题的 -0.075em 压缩。`eyebrow` 用 11px、700 字重、0.22em 字距作短标签,不承载唯一操作说明。标题平衡换行,说明文字自然换行,长记录标题允许断行,账号单行省略。
|
|
169
|
+
|
|
170
|
+
具体字号、字重与行高以 typography 为准。所有套件严格使用同一按钮字号 14px 与行高 20px;不要混用第二套展示字体。
|
|
171
|
+
|
|
172
|
+
## Layout
|
|
173
|
+
|
|
174
|
+
沿用工作空间的信息结构:顶栏、页面标题、记录列表与编辑区。桌面 shell-max 为 1240px,水平边距 32px;记录区两栏,登录页说明与表单两栏。面板间距 24px,桌面面板内边距 26px。避免为了科技感给每一行再套卡片。
|
|
175
|
+
|
|
176
|
+
在 `spacing.mobile-breakpoint`(当前 760px)收为单列,水平边距 18px、面板内边距 20px。375px 不允许横向溢出;操作区允许自然增长,不用全屏固定高度压缩内容。布局 CSS 与媒体查询由同一 token 源生成。
|
|
177
|
+
|
|
178
|
+
官网的超大留白、全屏分区与宽幅媒体可用于品牌落地页,但不是登录和 CRUD 页面默认规则。新增导航、统计卡或营销分区需要业务需求,不能由设计规范自行扩张功能。
|
|
179
|
+
|
|
180
|
+
## Elevation & Depth
|
|
181
|
+
|
|
182
|
+
面板首先依靠深浅表面和 1px 冷色边框分层;阴影为 `0 16px 48px rgba(0,0,0,0.18)`,来自 design/tokens.json 的 effects.panelShadow。控件边框比装饰分隔线更清晰。选中记录增加冰蓝侧线与背景变化,不只靠文字颜色。
|
|
183
|
+
|
|
184
|
+
官网玻璃面板的 blur(14px) 和影像叠层可作为品牌页面参考;本工具使用实体表面保证阅读和性能,不全局加 backdrop-filter。禁止给每个按钮、输入框加辉光或重阴影。
|
|
185
|
+
|
|
186
|
+
## Shapes
|
|
187
|
+
|
|
188
|
+
`rounded.md` 为 0px、`rounded.panel` 为 0px、`rounded.full` 为 0px:按钮、输入、面板和标签保持精确直角。`full` 是沿用的 token 名,在当前主题不代表胶囊。修改形状时同步组件 token;所有尺寸的圆角由套件显式绑定,避免库派生出另一种圆角。
|
|
189
|
+
|
|
190
|
+
边框厚度通常为 1px。图标沿用所选组件库的简洁线性风格,保持光学尺寸一致;不复制官网 Logo 或专有插图。
|
|
191
|
+
|
|
192
|
+
## Components
|
|
193
|
+
|
|
194
|
+
主按钮:冰蓝填充、深色文字;secondary:深色表面与清晰描边;danger:暗红表面与浅红文字。按钮与单行输入高度 44px,保持键盘焦点。default/hover/active/focus/disabled/loading 与输入错误态由 design/widgets.json 定义,套件逐项翻译,不接受原生默认值偏差。颜色派生结果以共享 token 为准;图标使用同一份 SVG 几何,套件不得替换成近似图标。
|
|
195
|
+
|
|
196
|
+
输入:深色底、冷白输入文字、可读 placeholder,标签始终可见。加载时禁用重复提交;错误后保留输入;空态说明下一步;记录正文以纯文本显示。删除需确认,退出清除当前编辑内容。控件自身焦点、输入和禁用状态由原生控件/套件管理;登录身份、校验、记录状态与请求隔离只在框架无关的 workspace-model 中实现。页面区块顺序和嵌套来自 design/structure.json,框架视图负责绑定。上述行为由业务实现与 Playwright 测试负责,设计文件不替代执行逻辑。
|
|
197
|
+
|
|
198
|
+
动效只用于短暂状态反馈;遵循 150–250ms 的颜色/边框变化,不新增背景循环、滚动接管或入场延迟。`prefers-reduced-motion: reduce` 下取消非必要动画与过渡。品牌页面如果采用背景媒体,需静态后备、降低亮度、保障文字对比度,并单独验收性能。
|
|
199
|
+
|
|
200
|
+
## Do's and Don'ts
|
|
201
|
+
|
|
202
|
+
- UI 开发前读本文件;设计修改先改源,再 sync/check,最后看浏览器真实结果。
|
|
203
|
+
- 复用冷色中性层级、单一字体、直角薄边框与有限强调色;保持所选 UI 库的一致性。
|
|
204
|
+
- 验证默认、hover、active、focus、disabled、loading、empty、error,以及键盘与 375px 布局。
|
|
205
|
+
- 不将来源网站的行业、品牌内容、低对比装饰字或全屏动效当成通用业务要求。
|
|
206
|
+
- 不给每个面板加玻璃、光晕或渐变;库默认值与规格不符时修改套件,不反向修改规范。
|
|
207
|
+
- 全量执行控件/页面比较:位置容差 ≤0.6 CSS px;颜色、圆角、图标几何零容差;必须覆盖 widgets.json 和 structure.json 的全部声明项。
|
|
208
|
+
- 不直接编辑生成文件,不把文档格式通过当成浏览器验收通过,不根据项目简介随机改变视觉。
|