dk-harness 0.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 +201 -0
- package/README.md +267 -0
- package/bin/dk-harness +206 -0
- package/package.json +36 -0
- package/templates/next-axum-monorepo/.eslintrc.js +13 -0
- package/templates/next-axum-monorepo/.github/workflows/ci.yml +92 -0
- package/templates/next-axum-monorepo/.gitleaks.toml +5 -0
- package/templates/next-axum-monorepo/.prettierignore +7 -0
- package/templates/next-axum-monorepo/.prettierrc +11 -0
- package/templates/next-axum-monorepo/AGENTS.md +35 -0
- package/templates/next-axum-monorepo/ARCHITECTURE.md +58 -0
- package/templates/next-axum-monorepo/README.md +45 -0
- package/templates/next-axum-monorepo/apps/axum/Cargo.lock +1041 -0
- package/templates/next-axum-monorepo/apps/axum/Cargo.toml +12 -0
- package/templates/next-axum-monorepo/apps/axum/deny.toml +13 -0
- package/templates/next-axum-monorepo/apps/axum/src/api/mod.rs +1 -0
- package/templates/next-axum-monorepo/apps/axum/src/api/router.rs +53 -0
- package/templates/next-axum-monorepo/apps/axum/src/core/config.rs +17 -0
- package/templates/next-axum-monorepo/apps/axum/src/core/mod.rs +1 -0
- package/templates/next-axum-monorepo/apps/axum/src/domain/health.rs +22 -0
- package/templates/next-axum-monorepo/apps/axum/src/domain/mod.rs +1 -0
- package/templates/next-axum-monorepo/apps/axum/src/lib.rs +6 -0
- package/templates/next-axum-monorepo/apps/axum/src/main.rs +15 -0
- package/templates/next-axum-monorepo/apps/web/app/favicon.ico +0 -0
- package/templates/next-axum-monorepo/apps/web/app/layout.tsx +43 -0
- package/templates/next-axum-monorepo/apps/web/app/page.tsx +19 -0
- package/templates/next-axum-monorepo/apps/web/biome.json +16 -0
- package/templates/next-axum-monorepo/apps/web/components/.gitkeep +0 -0
- package/templates/next-axum-monorepo/apps/web/components/theme-provider.tsx +71 -0
- package/templates/next-axum-monorepo/apps/web/components.json +23 -0
- package/templates/next-axum-monorepo/apps/web/dependency-cruiser.cjs +66 -0
- package/templates/next-axum-monorepo/apps/web/eslint.config.js +4 -0
- package/templates/next-axum-monorepo/apps/web/hooks/.gitkeep +0 -0
- package/templates/next-axum-monorepo/apps/web/knip.json +17 -0
- package/templates/next-axum-monorepo/apps/web/lib/.gitkeep +0 -0
- package/templates/next-axum-monorepo/apps/web/lighthouserc.json +23 -0
- package/templates/next-axum-monorepo/apps/web/next-env.d.ts +6 -0
- package/templates/next-axum-monorepo/apps/web/next.config.mjs +6 -0
- package/templates/next-axum-monorepo/apps/web/package.json +46 -0
- package/templates/next-axum-monorepo/apps/web/playwright.config.ts +18 -0
- package/templates/next-axum-monorepo/apps/web/postcss.config.mjs +1 -0
- package/templates/next-axum-monorepo/apps/web/skills-lock.json +15 -0
- package/templates/next-axum-monorepo/apps/web/tests/e2e/smoke.spec.ts +13 -0
- package/templates/next-axum-monorepo/apps/web/tests/unit/page.test.tsx +16 -0
- package/templates/next-axum-monorepo/apps/web/tsconfig.json +23 -0
- package/templates/next-axum-monorepo/apps/web/vitest.config.ts +13 -0
- package/templates/next-axum-monorepo/apps/web/vitest.setup.ts +1 -0
- package/templates/next-axum-monorepo/docs/DESIGN.md +10 -0
- package/templates/next-axum-monorepo/docs/FRONTEND.md +26 -0
- package/templates/next-axum-monorepo/docs/PLANS.md +25 -0
- package/templates/next-axum-monorepo/docs/PRODUCT_SENSE.md +11 -0
- package/templates/next-axum-monorepo/docs/QUALITY_SCORE.md +16 -0
- package/templates/next-axum-monorepo/docs/RELIABILITY.md +39 -0
- package/templates/next-axum-monorepo/docs/SECURITY.md +16 -0
- package/templates/next-axum-monorepo/docs/design-docs/core-beliefs.md +6 -0
- package/templates/next-axum-monorepo/docs/design-docs/included-skills.md +16 -0
- package/templates/next-axum-monorepo/docs/design-docs/index.md +6 -0
- package/templates/next-axum-monorepo/docs/exec-plans/active/.gitkeep +1 -0
- package/templates/next-axum-monorepo/docs/exec-plans/completed/.gitkeep +1 -0
- package/templates/next-axum-monorepo/docs/exec-plans/repeated-work.md +15 -0
- package/templates/next-axum-monorepo/docs/exec-plans/tech-debt-tracker.md +3 -0
- package/templates/next-axum-monorepo/docs/generated/db-schema.md +3 -0
- package/templates/next-axum-monorepo/docs/product-specs/index.md +5 -0
- package/templates/next-axum-monorepo/docs/product-specs/new-user-onboarding.md +12 -0
- package/templates/next-axum-monorepo/docs/references/design-system-reference-llms.txt +13 -0
- package/templates/next-axum-monorepo/justfile +36 -0
- package/templates/next-axum-monorepo/lefthook.yml +8 -0
- package/templates/next-axum-monorepo/mise.toml +5 -0
- package/templates/next-axum-monorepo/package.json +41 -0
- package/templates/next-axum-monorepo/packages/eslint-config/README.md +3 -0
- package/templates/next-axum-monorepo/packages/eslint-config/base.js +32 -0
- package/templates/next-axum-monorepo/packages/eslint-config/next.js +51 -0
- package/templates/next-axum-monorepo/packages/eslint-config/package.json +26 -0
- package/templates/next-axum-monorepo/packages/eslint-config/react-internal.js +41 -0
- package/templates/next-axum-monorepo/packages/typescript-config/README.md +3 -0
- package/templates/next-axum-monorepo/packages/typescript-config/base.json +20 -0
- package/templates/next-axum-monorepo/packages/typescript-config/nextjs.json +13 -0
- package/templates/next-axum-monorepo/packages/typescript-config/package.json +9 -0
- package/templates/next-axum-monorepo/packages/typescript-config/react-library.json +8 -0
- package/templates/next-axum-monorepo/packages/ui/components.json +23 -0
- package/templates/next-axum-monorepo/packages/ui/dependency-cruiser.cjs +100 -0
- package/templates/next-axum-monorepo/packages/ui/eslint.config.js +4 -0
- package/templates/next-axum-monorepo/packages/ui/package.json +49 -0
- package/templates/next-axum-monorepo/packages/ui/postcss.config.mjs +6 -0
- package/templates/next-axum-monorepo/packages/ui/src/config/.gitkeep +1 -0
- package/templates/next-axum-monorepo/packages/ui/src/providers/.gitkeep +1 -0
- package/templates/next-axum-monorepo/packages/ui/src/repo/.gitkeep +1 -0
- package/templates/next-axum-monorepo/packages/ui/src/runtime/hooks/.gitkeep +1 -0
- package/templates/next-axum-monorepo/packages/ui/src/runtime/utils.ts +6 -0
- package/templates/next-axum-monorepo/packages/ui/src/service/.gitkeep +1 -0
- package/templates/next-axum-monorepo/packages/ui/src/styles/globals.css +129 -0
- package/templates/next-axum-monorepo/packages/ui/src/types/.gitkeep +1 -0
- package/templates/next-axum-monorepo/packages/ui/src/ui/button.tsx +65 -0
- package/templates/next-axum-monorepo/packages/ui/src/utils/.gitkeep +1 -0
- package/templates/next-axum-monorepo/packages/ui/tsconfig.json +10 -0
- package/templates/next-axum-monorepo/packages/ui/tsconfig.lint.json +8 -0
- package/templates/next-axum-monorepo/pnpm-lock.yaml +12402 -0
- package/templates/next-axum-monorepo/pnpm-workspace.yaml +3 -0
- package/templates/next-axum-monorepo/renovate.json +6 -0
- package/templates/next-axum-monorepo/scripts/check-rust-layers.mjs +149 -0
- package/templates/next-axum-monorepo/skills-lock.json +30 -0
- package/templates/next-axum-monorepo/tsconfig.json +4 -0
- package/templates/next-axum-monorepo/turbo.json +27 -0
- package/templates/next-fastapi-monorepo/.eslintrc.js +13 -0
- package/templates/next-fastapi-monorepo/.github/workflows/ci.yml +92 -0
- package/templates/next-fastapi-monorepo/.gitleaks.toml +5 -0
- package/templates/next-fastapi-monorepo/.prettierignore +7 -0
- package/templates/next-fastapi-monorepo/.prettierrc +11 -0
- package/templates/next-fastapi-monorepo/AGENTS.md +35 -0
- package/templates/next-fastapi-monorepo/ARCHITECTURE.md +55 -0
- package/templates/next-fastapi-monorepo/README.md +65 -0
- package/templates/next-fastapi-monorepo/apps/api/.python-version +1 -0
- package/templates/next-fastapi-monorepo/apps/api/README.md +17 -0
- package/templates/next-fastapi-monorepo/apps/api/app/__init__.py +1 -0
- package/templates/next-fastapi-monorepo/apps/api/app/api/__init__.py +2 -0
- package/templates/next-fastapi-monorepo/apps/api/app/api/routes.py +16 -0
- package/templates/next-fastapi-monorepo/apps/api/app/core/__init__.py +2 -0
- package/templates/next-fastapi-monorepo/apps/api/app/core/config.py +11 -0
- package/templates/next-fastapi-monorepo/apps/api/app/domain/__init__.py +2 -0
- package/templates/next-fastapi-monorepo/apps/api/app/domain/health.py +7 -0
- package/templates/next-fastapi-monorepo/apps/api/app/main.py +8 -0
- package/templates/next-fastapi-monorepo/apps/api/package.json +14 -0
- package/templates/next-fastapi-monorepo/apps/api/pyproject.toml +54 -0
- package/templates/next-fastapi-monorepo/apps/api/tests/test_main.py +27 -0
- package/templates/next-fastapi-monorepo/apps/api/uv.lock +1797 -0
- package/templates/next-fastapi-monorepo/apps/web/app/favicon.ico +0 -0
- package/templates/next-fastapi-monorepo/apps/web/app/layout.tsx +43 -0
- package/templates/next-fastapi-monorepo/apps/web/app/page.tsx +19 -0
- package/templates/next-fastapi-monorepo/apps/web/biome.json +16 -0
- package/templates/next-fastapi-monorepo/apps/web/components/.gitkeep +0 -0
- package/templates/next-fastapi-monorepo/apps/web/components/theme-provider.tsx +71 -0
- package/templates/next-fastapi-monorepo/apps/web/components.json +23 -0
- package/templates/next-fastapi-monorepo/apps/web/dependency-cruiser.cjs +66 -0
- package/templates/next-fastapi-monorepo/apps/web/eslint.config.js +4 -0
- package/templates/next-fastapi-monorepo/apps/web/hooks/.gitkeep +0 -0
- package/templates/next-fastapi-monorepo/apps/web/knip.json +17 -0
- package/templates/next-fastapi-monorepo/apps/web/lib/.gitkeep +0 -0
- package/templates/next-fastapi-monorepo/apps/web/lighthouserc.json +23 -0
- package/templates/next-fastapi-monorepo/apps/web/next-env.d.ts +6 -0
- package/templates/next-fastapi-monorepo/apps/web/next.config.mjs +6 -0
- package/templates/next-fastapi-monorepo/apps/web/package.json +46 -0
- package/templates/next-fastapi-monorepo/apps/web/playwright.config.ts +18 -0
- package/templates/next-fastapi-monorepo/apps/web/postcss.config.mjs +1 -0
- package/templates/next-fastapi-monorepo/apps/web/skills-lock.json +40 -0
- package/templates/next-fastapi-monorepo/apps/web/tests/e2e/smoke.spec.ts +13 -0
- package/templates/next-fastapi-monorepo/apps/web/tests/unit/page.test.tsx +16 -0
- package/templates/next-fastapi-monorepo/apps/web/tsconfig.json +23 -0
- package/templates/next-fastapi-monorepo/apps/web/vitest.config.ts +13 -0
- package/templates/next-fastapi-monorepo/apps/web/vitest.setup.ts +1 -0
- package/templates/next-fastapi-monorepo/docs/DESIGN.md +10 -0
- package/templates/next-fastapi-monorepo/docs/FRONTEND.md +26 -0
- package/templates/next-fastapi-monorepo/docs/PLANS.md +25 -0
- package/templates/next-fastapi-monorepo/docs/PRODUCT_SENSE.md +11 -0
- package/templates/next-fastapi-monorepo/docs/QUALITY_SCORE.md +16 -0
- package/templates/next-fastapi-monorepo/docs/RELIABILITY.md +38 -0
- package/templates/next-fastapi-monorepo/docs/SECURITY.md +15 -0
- package/templates/next-fastapi-monorepo/docs/design-docs/core-beliefs.md +6 -0
- package/templates/next-fastapi-monorepo/docs/design-docs/included-skills.md +13 -0
- package/templates/next-fastapi-monorepo/docs/design-docs/index.md +6 -0
- package/templates/next-fastapi-monorepo/docs/exec-plans/active/.gitkeep +1 -0
- package/templates/next-fastapi-monorepo/docs/exec-plans/completed/.gitkeep +1 -0
- package/templates/next-fastapi-monorepo/docs/exec-plans/repeated-work.md +15 -0
- package/templates/next-fastapi-monorepo/docs/exec-plans/tech-debt-tracker.md +3 -0
- package/templates/next-fastapi-monorepo/docs/generated/db-schema.md +3 -0
- package/templates/next-fastapi-monorepo/docs/product-specs/index.md +5 -0
- package/templates/next-fastapi-monorepo/docs/product-specs/new-user-onboarding.md +12 -0
- package/templates/next-fastapi-monorepo/docs/references/design-system-reference-llms.txt +13 -0
- package/templates/next-fastapi-monorepo/docs/references/uv-llms.txt +7 -0
- package/templates/next-fastapi-monorepo/justfile +31 -0
- package/templates/next-fastapi-monorepo/lefthook.yml +8 -0
- package/templates/next-fastapi-monorepo/mise.toml +6 -0
- package/templates/next-fastapi-monorepo/package.json +41 -0
- package/templates/next-fastapi-monorepo/packages/eslint-config/README.md +3 -0
- package/templates/next-fastapi-monorepo/packages/eslint-config/base.js +32 -0
- package/templates/next-fastapi-monorepo/packages/eslint-config/next.js +51 -0
- package/templates/next-fastapi-monorepo/packages/eslint-config/package.json +26 -0
- package/templates/next-fastapi-monorepo/packages/eslint-config/react-internal.js +41 -0
- package/templates/next-fastapi-monorepo/packages/typescript-config/README.md +3 -0
- package/templates/next-fastapi-monorepo/packages/typescript-config/base.json +20 -0
- package/templates/next-fastapi-monorepo/packages/typescript-config/nextjs.json +13 -0
- package/templates/next-fastapi-monorepo/packages/typescript-config/package.json +9 -0
- package/templates/next-fastapi-monorepo/packages/typescript-config/react-library.json +8 -0
- package/templates/next-fastapi-monorepo/packages/ui/components.json +23 -0
- package/templates/next-fastapi-monorepo/packages/ui/dependency-cruiser.cjs +100 -0
- package/templates/next-fastapi-monorepo/packages/ui/eslint.config.js +4 -0
- package/templates/next-fastapi-monorepo/packages/ui/package.json +49 -0
- package/templates/next-fastapi-monorepo/packages/ui/postcss.config.mjs +6 -0
- package/templates/next-fastapi-monorepo/packages/ui/src/config/.gitkeep +1 -0
- package/templates/next-fastapi-monorepo/packages/ui/src/providers/.gitkeep +1 -0
- package/templates/next-fastapi-monorepo/packages/ui/src/repo/.gitkeep +1 -0
- package/templates/next-fastapi-monorepo/packages/ui/src/runtime/hooks/.gitkeep +1 -0
- package/templates/next-fastapi-monorepo/packages/ui/src/runtime/utils.ts +6 -0
- package/templates/next-fastapi-monorepo/packages/ui/src/service/.gitkeep +1 -0
- package/templates/next-fastapi-monorepo/packages/ui/src/styles/globals.css +129 -0
- package/templates/next-fastapi-monorepo/packages/ui/src/types/.gitkeep +1 -0
- package/templates/next-fastapi-monorepo/packages/ui/src/ui/button.tsx +65 -0
- package/templates/next-fastapi-monorepo/packages/ui/src/utils/.gitkeep +1 -0
- package/templates/next-fastapi-monorepo/packages/ui/tsconfig.json +10 -0
- package/templates/next-fastapi-monorepo/packages/ui/tsconfig.lint.json +8 -0
- package/templates/next-fastapi-monorepo/pnpm-lock.yaml +12404 -0
- package/templates/next-fastapi-monorepo/pnpm-workspace.yaml +3 -0
- package/templates/next-fastapi-monorepo/renovate.json +6 -0
- package/templates/next-fastapi-monorepo/tsconfig.json +4 -0
- package/templates/next-fastapi-monorepo/turbo.json +27 -0
- package/templates/next-monorepo/.eslintrc.js +13 -0
- package/templates/next-monorepo/.github/workflows/ci.yml +76 -0
- package/templates/next-monorepo/.gitleaks.toml +5 -0
- package/templates/next-monorepo/.prettierignore +7 -0
- package/templates/next-monorepo/.prettierrc +11 -0
- package/templates/next-monorepo/AGENTS.md +35 -0
- package/templates/next-monorepo/ARCHITECTURE.md +67 -0
- package/templates/next-monorepo/README.md +45 -0
- package/templates/next-monorepo/apps/web/app/favicon.ico +0 -0
- package/templates/next-monorepo/apps/web/app/layout.tsx +43 -0
- package/templates/next-monorepo/apps/web/app/page.tsx +19 -0
- package/templates/next-monorepo/apps/web/biome.json +16 -0
- package/templates/next-monorepo/apps/web/components/.gitkeep +0 -0
- package/templates/next-monorepo/apps/web/components/theme-provider.tsx +71 -0
- package/templates/next-monorepo/apps/web/components.json +23 -0
- package/templates/next-monorepo/apps/web/dependency-cruiser.cjs +66 -0
- package/templates/next-monorepo/apps/web/eslint.config.js +4 -0
- package/templates/next-monorepo/apps/web/hooks/.gitkeep +0 -0
- package/templates/next-monorepo/apps/web/knip.json +17 -0
- package/templates/next-monorepo/apps/web/lib/.gitkeep +0 -0
- package/templates/next-monorepo/apps/web/lighthouserc.json +23 -0
- package/templates/next-monorepo/apps/web/next-env.d.ts +6 -0
- package/templates/next-monorepo/apps/web/next.config.mjs +6 -0
- package/templates/next-monorepo/apps/web/package.json +46 -0
- package/templates/next-monorepo/apps/web/playwright.config.ts +18 -0
- package/templates/next-monorepo/apps/web/postcss.config.mjs +1 -0
- package/templates/next-monorepo/apps/web/skills-lock.json +40 -0
- package/templates/next-monorepo/apps/web/tests/e2e/smoke.spec.ts +13 -0
- package/templates/next-monorepo/apps/web/tests/unit/page.test.tsx +16 -0
- package/templates/next-monorepo/apps/web/tsconfig.json +23 -0
- package/templates/next-monorepo/apps/web/vitest.config.ts +13 -0
- package/templates/next-monorepo/apps/web/vitest.setup.ts +1 -0
- package/templates/next-monorepo/docs/DESIGN.md +11 -0
- package/templates/next-monorepo/docs/FRONTEND.md +32 -0
- package/templates/next-monorepo/docs/PLANS.md +25 -0
- package/templates/next-monorepo/docs/PRODUCT_SENSE.md +11 -0
- package/templates/next-monorepo/docs/QUALITY_SCORE.md +18 -0
- package/templates/next-monorepo/docs/RELIABILITY.md +37 -0
- package/templates/next-monorepo/docs/SECURITY.md +14 -0
- package/templates/next-monorepo/docs/design-docs/core-beliefs.md +6 -0
- package/templates/next-monorepo/docs/design-docs/included-skills.md +13 -0
- package/templates/next-monorepo/docs/design-docs/index.md +6 -0
- package/templates/next-monorepo/docs/exec-plans/active/.gitkeep +1 -0
- package/templates/next-monorepo/docs/exec-plans/completed/.gitkeep +1 -0
- package/templates/next-monorepo/docs/exec-plans/repeated-work.md +15 -0
- package/templates/next-monorepo/docs/exec-plans/tech-debt-tracker.md +3 -0
- package/templates/next-monorepo/docs/generated/db-schema.md +3 -0
- package/templates/next-monorepo/docs/product-specs/index.md +5 -0
- package/templates/next-monorepo/docs/product-specs/new-user-onboarding.md +12 -0
- package/templates/next-monorepo/docs/references/design-system-reference-llms.txt +13 -0
- package/templates/next-monorepo/justfile +26 -0
- package/templates/next-monorepo/lefthook.yml +8 -0
- package/templates/next-monorepo/mise.toml +4 -0
- package/templates/next-monorepo/package.json +41 -0
- package/templates/next-monorepo/packages/eslint-config/README.md +3 -0
- package/templates/next-monorepo/packages/eslint-config/base.js +32 -0
- package/templates/next-monorepo/packages/eslint-config/next.js +51 -0
- package/templates/next-monorepo/packages/eslint-config/package.json +26 -0
- package/templates/next-monorepo/packages/eslint-config/react-internal.js +41 -0
- package/templates/next-monorepo/packages/typescript-config/README.md +3 -0
- package/templates/next-monorepo/packages/typescript-config/base.json +20 -0
- package/templates/next-monorepo/packages/typescript-config/nextjs.json +13 -0
- package/templates/next-monorepo/packages/typescript-config/package.json +9 -0
- package/templates/next-monorepo/packages/typescript-config/react-library.json +8 -0
- package/templates/next-monorepo/packages/ui/components.json +23 -0
- package/templates/next-monorepo/packages/ui/dependency-cruiser.cjs +100 -0
- package/templates/next-monorepo/packages/ui/eslint.config.js +4 -0
- package/templates/next-monorepo/packages/ui/package.json +49 -0
- package/templates/next-monorepo/packages/ui/postcss.config.mjs +6 -0
- package/templates/next-monorepo/packages/ui/src/config/.gitkeep +1 -0
- package/templates/next-monorepo/packages/ui/src/providers/.gitkeep +1 -0
- package/templates/next-monorepo/packages/ui/src/repo/.gitkeep +1 -0
- package/templates/next-monorepo/packages/ui/src/runtime/hooks/.gitkeep +1 -0
- package/templates/next-monorepo/packages/ui/src/runtime/utils.ts +6 -0
- package/templates/next-monorepo/packages/ui/src/service/.gitkeep +1 -0
- package/templates/next-monorepo/packages/ui/src/styles/globals.css +129 -0
- package/templates/next-monorepo/packages/ui/src/types/.gitkeep +1 -0
- package/templates/next-monorepo/packages/ui/src/ui/button.tsx +65 -0
- package/templates/next-monorepo/packages/ui/src/utils/.gitkeep +1 -0
- package/templates/next-monorepo/packages/ui/tsconfig.json +10 -0
- package/templates/next-monorepo/packages/ui/tsconfig.lint.json +8 -0
- package/templates/next-monorepo/pnpm-lock.yaml +12402 -0
- package/templates/next-monorepo/pnpm-workspace.yaml +3 -0
- package/templates/next-monorepo/renovate.json +6 -0
- package/templates/next-monorepo/tsconfig.json +4 -0
- package/templates/next-monorepo/turbo.json +27 -0
- package/templates/registry.json +22 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Frontend
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
Frontend work lives in `apps/web` and `packages/ui`.
|
|
6
|
+
Backend work lives separately in `apps/axum`.
|
|
7
|
+
|
|
8
|
+
## Shared UI Package
|
|
9
|
+
|
|
10
|
+
Use these public paths from `@workspace/ui`:
|
|
11
|
+
|
|
12
|
+
- `@workspace/ui/ui/*`
|
|
13
|
+
- `@workspace/ui/runtime/*`
|
|
14
|
+
- `@workspace/ui/providers/*`
|
|
15
|
+
|
|
16
|
+
Keep shared UI work aligned with the enforced stack and do not reintroduce the old `components/hooks/lib` package layers.
|
|
17
|
+
|
|
18
|
+
## Component Workflow
|
|
19
|
+
|
|
20
|
+
Add shared primitives with:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm dlx shadcn@latest add button -c apps/web
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Generated shared components should land in `packages/ui/src/ui`.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Plans
|
|
2
|
+
|
|
3
|
+
Plans are first-class artifacts in this template.
|
|
4
|
+
|
|
5
|
+
## Planning Model
|
|
6
|
+
|
|
7
|
+
- small, transient work may use a short local plan without a committed plan file
|
|
8
|
+
- complex or multi-step work should create an execution plan in `docs/exec-plans/active/`
|
|
9
|
+
- finished execution plans move to `docs/exec-plans/completed/`
|
|
10
|
+
- known cleanup and follow-up items live in `docs/exec-plans/tech-debt-tracker.md`
|
|
11
|
+
- repeated operational work belongs in `docs/exec-plans/repeated-work.md`
|
|
12
|
+
|
|
13
|
+
## Required Sections For Execution Plans
|
|
14
|
+
|
|
15
|
+
Every execution plan in `active/` or `completed/` should include:
|
|
16
|
+
|
|
17
|
+
- `## Status`
|
|
18
|
+
- `## Scope`
|
|
19
|
+
- `## Steps`
|
|
20
|
+
- `## Progress Log`
|
|
21
|
+
- `## Decision Log`
|
|
22
|
+
|
|
23
|
+
## Operating Rule
|
|
24
|
+
|
|
25
|
+
Execution plans, completed plans, and tech debt are all versioned and stored in the repository so agents can work without hidden external context.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Product Sense
|
|
2
|
+
|
|
3
|
+
This starter is optimized for teams that want a Next.js frontend and a Rust service with clear boundaries from day one.
|
|
4
|
+
|
|
5
|
+
The default experience should communicate:
|
|
6
|
+
|
|
7
|
+
- the frontend is ready immediately
|
|
8
|
+
- the backend has a minimal health surface
|
|
9
|
+
- architecture boundaries are not optional
|
|
10
|
+
|
|
11
|
+
Detailed specs live in `product-specs/`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Quality Score
|
|
2
|
+
|
|
3
|
+
Use this rubric when reviewing the starter or changes to it.
|
|
4
|
+
|
|
5
|
+
## High Quality Means
|
|
6
|
+
|
|
7
|
+
- frontend and backend layer rules are mechanically enforced
|
|
8
|
+
- shared UI imports are obvious
|
|
9
|
+
- Rust startup and service logic stay separated
|
|
10
|
+
- docs match the actual command surface
|
|
11
|
+
|
|
12
|
+
## Red Flags
|
|
13
|
+
|
|
14
|
+
- UI code bypassing `providers`
|
|
15
|
+
- backend logic drifting into `main.rs`
|
|
16
|
+
- docs that lag behind the template
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Reliability
|
|
2
|
+
|
|
3
|
+
## Local Commands
|
|
4
|
+
|
|
5
|
+
Run from the repository root unless noted otherwise:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
just install
|
|
9
|
+
pnpm dev
|
|
10
|
+
just lint
|
|
11
|
+
just typecheck
|
|
12
|
+
just test
|
|
13
|
+
just ux
|
|
14
|
+
just supply-chain
|
|
15
|
+
just ci
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Run the Rust service directly when needed:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cd apps/axum
|
|
22
|
+
cargo run
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Lane Responsibilities
|
|
26
|
+
|
|
27
|
+
- `just lint`: web lint, shared UI layer checks, Rust layer check, `cargo fmt`, `clippy`, and `cargo udeps`
|
|
28
|
+
- `just typecheck`: Next.js typecheck plus `cargo check --all-targets`
|
|
29
|
+
- `just test`: Vitest plus `cargo nextest run`
|
|
30
|
+
- `just ux`: Playwright, axe, and Lighthouse for the web app
|
|
31
|
+
- `just supply-chain`: gitleaks, osv-scanner, `pnpm audit`, `cargo deny`, and `cargo audit`
|
|
32
|
+
|
|
33
|
+
## CI
|
|
34
|
+
|
|
35
|
+
GitHub Actions runs the build and test lanes defined in `.github/workflows/ci.yml`.
|
|
36
|
+
|
|
37
|
+
## Doc Gardening
|
|
38
|
+
|
|
39
|
+
Doc gardening is a repeated manual task tracked in `docs/exec-plans/repeated-work.md`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
This starter includes basic Node and Rust supply-chain checks.
|
|
4
|
+
|
|
5
|
+
## Included Checks
|
|
6
|
+
|
|
7
|
+
- `gitleaks`
|
|
8
|
+
- `osv-scanner`
|
|
9
|
+
- `pnpm audit`
|
|
10
|
+
- `cargo deny`
|
|
11
|
+
- `cargo audit`
|
|
12
|
+
|
|
13
|
+
## Expectations
|
|
14
|
+
|
|
15
|
+
- do not commit secrets
|
|
16
|
+
- keep Rust and Node dependencies current
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Core Beliefs
|
|
2
|
+
|
|
3
|
+
- the starter should feel production-minded without feeling heavy
|
|
4
|
+
- frontend and backend boundaries should be explicit from the first commit
|
|
5
|
+
- Rust service code should stay small, direct, and layered
|
|
6
|
+
- shared UI should remain easy to extend safely
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Included Skills
|
|
2
|
+
|
|
3
|
+
The web app ships with design and frontend reference skills in `apps/web/skills-lock.json`.
|
|
4
|
+
|
|
5
|
+
- `frontend-design`
|
|
6
|
+
- `shadcn`
|
|
7
|
+
|
|
8
|
+
The workspace also includes additional reference skills in `skills-lock.json`.
|
|
9
|
+
|
|
10
|
+
- `vercel-composition-patterns`
|
|
11
|
+
- `vercel-react-best-practices`
|
|
12
|
+
- `vercel-react-native-skills`
|
|
13
|
+
- `vercel-react-view-transitions`
|
|
14
|
+
- `web-design-guidelines`
|
|
15
|
+
|
|
16
|
+
Treat these as scaffolded defaults for UI and interaction work.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Repeated Work
|
|
2
|
+
|
|
3
|
+
## Doc Gardening
|
|
4
|
+
|
|
5
|
+
The knowledge base needs periodic manual gardening.
|
|
6
|
+
|
|
7
|
+
Repeat this work when template behavior, architecture rules, onboarding flow, or public commands change:
|
|
8
|
+
|
|
9
|
+
- review `AGENTS.md` and `ARCHITECTURE.md`
|
|
10
|
+
- review `docs/design-docs/`, `docs/product-specs/`, and `docs/references/`
|
|
11
|
+
- move stale execution plans from `active/` to `completed/`
|
|
12
|
+
- update `tech-debt-tracker.md` when cleanup work is discovered
|
|
13
|
+
- remove outdated or irrelevant references that no longer match the stack
|
|
14
|
+
|
|
15
|
+
This work is intentionally documented here rather than automated in CI.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# New User Onboarding
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
A freshly scaffolded project should prove both the web app and Rust service are wired correctly with minimal setup.
|
|
6
|
+
|
|
7
|
+
## Default Experience
|
|
8
|
+
|
|
9
|
+
- the home page renders immediately
|
|
10
|
+
- the shared button component is already usable
|
|
11
|
+
- the Rust service exposes a small health surface
|
|
12
|
+
- the next customization step is obvious
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
This reference should contain only design-system facts for the shared UI package.
|
|
2
|
+
|
|
3
|
+
Current baseline:
|
|
4
|
+
- UI system: `shadcn`
|
|
5
|
+
- style preset: `radix-lyra`
|
|
6
|
+
- Tailwind base color: `neutral`
|
|
7
|
+
- CSS variables: enabled
|
|
8
|
+
- icon library: `lucide`
|
|
9
|
+
- theme tokens live in `packages/ui/src/styles/globals.css`
|
|
10
|
+
- the starter includes light and dark theme tokens using OKLCH color values
|
|
11
|
+
- the radius scale is derived from `--radius: 0.625rem`
|
|
12
|
+
|
|
13
|
+
Update this file when the component style, token set, icon set, or theming rules change.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
set shell := ["bash", "-cu"]
|
|
2
|
+
|
|
3
|
+
install:
|
|
4
|
+
mise install
|
|
5
|
+
pnpm install --frozen-lockfile
|
|
6
|
+
rustup toolchain install nightly --component rust-src
|
|
7
|
+
cargo install cargo-nextest cargo-udeps cargo-deny cargo-audit --locked
|
|
8
|
+
pnpm exec playwright install chromium
|
|
9
|
+
|
|
10
|
+
lint:
|
|
11
|
+
pnpm --filter web lint
|
|
12
|
+
pnpm --dir packages/ui exec depcruise --config dependency-cruiser.cjs src
|
|
13
|
+
node ./scripts/check-rust-layers.mjs
|
|
14
|
+
(cd apps/axum && cargo fmt --check)
|
|
15
|
+
(cd apps/axum && cargo clippy --all-targets --all-features -- -D warnings)
|
|
16
|
+
(cd apps/axum && cargo +nightly udeps --all-targets)
|
|
17
|
+
|
|
18
|
+
typecheck:
|
|
19
|
+
pnpm --filter web typecheck
|
|
20
|
+
(cd apps/axum && cargo check --all-targets)
|
|
21
|
+
|
|
22
|
+
test:
|
|
23
|
+
pnpm --filter web test
|
|
24
|
+
(cd apps/axum && cargo nextest run)
|
|
25
|
+
|
|
26
|
+
ux:
|
|
27
|
+
pnpm --filter web ux
|
|
28
|
+
|
|
29
|
+
supply-chain:
|
|
30
|
+
gitleaks dir . --config .gitleaks.toml
|
|
31
|
+
osv-scanner scan source -r .
|
|
32
|
+
pnpm audit --audit-level=high
|
|
33
|
+
(cd apps/axum && cargo deny check)
|
|
34
|
+
(cd apps/axum && cargo audit)
|
|
35
|
+
|
|
36
|
+
ci: lint typecheck test ux supply-chain
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "next-axum-monorepo",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "turbo build",
|
|
7
|
+
"dev": "turbo dev --filter=web",
|
|
8
|
+
"lint": "just lint",
|
|
9
|
+
"format": "pnpm --filter web format",
|
|
10
|
+
"typecheck": "just typecheck",
|
|
11
|
+
"test": "just test",
|
|
12
|
+
"ux": "just ux",
|
|
13
|
+
"supply-chain": "just supply-chain",
|
|
14
|
+
"ci": "just ci"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@axe-core/playwright": "^4.11.0",
|
|
18
|
+
"@biomejs/biome": "^1.9.4",
|
|
19
|
+
"@lhci/cli": "^0.15.1",
|
|
20
|
+
"@playwright/test": "^1.51.1",
|
|
21
|
+
"@testing-library/jest-dom": "^6.8.0",
|
|
22
|
+
"@testing-library/react": "^16.3.0",
|
|
23
|
+
"@vitejs/plugin-react": "^5.0.4",
|
|
24
|
+
"@workspace/eslint-config": "workspace:*",
|
|
25
|
+
"@workspace/typescript-config": "workspace:*",
|
|
26
|
+
"dependency-cruiser": "^17.1.0",
|
|
27
|
+
"jsdom": "^26.1.0",
|
|
28
|
+
"knip": "^5.44.4",
|
|
29
|
+
"prettier": "^3.8.1",
|
|
30
|
+
"prettier-plugin-tailwindcss": "^0.7.2",
|
|
31
|
+
"start-server-and-test": "^3.0.2",
|
|
32
|
+
"turbo": "^2.8.17",
|
|
33
|
+
"typescript": "5.9.3",
|
|
34
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
35
|
+
"vitest": "^3.2.4"
|
|
36
|
+
},
|
|
37
|
+
"packageManager": "pnpm@9.15.9",
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=20"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import js from "@eslint/js"
|
|
2
|
+
import eslintConfigPrettier from "eslint-config-prettier"
|
|
3
|
+
import onlyWarn from "eslint-plugin-only-warn"
|
|
4
|
+
import turboPlugin from "eslint-plugin-turbo"
|
|
5
|
+
import tseslint from "typescript-eslint"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A shared ESLint configuration for the repository.
|
|
9
|
+
*
|
|
10
|
+
* @type {import("eslint").Linter.Config}
|
|
11
|
+
* */
|
|
12
|
+
export const config = [
|
|
13
|
+
js.configs.recommended,
|
|
14
|
+
eslintConfigPrettier,
|
|
15
|
+
...tseslint.configs.recommended,
|
|
16
|
+
{
|
|
17
|
+
plugins: {
|
|
18
|
+
turbo: turboPlugin,
|
|
19
|
+
},
|
|
20
|
+
rules: {
|
|
21
|
+
"turbo/no-undeclared-env-vars": "warn",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
plugins: {
|
|
26
|
+
onlyWarn,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
ignores: ["dist/**", ".next/**", "**/.turbo/**", "**/coverage/**"],
|
|
31
|
+
},
|
|
32
|
+
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import js from "@eslint/js"
|
|
2
|
+
import pluginNext from "@next/eslint-plugin-next"
|
|
3
|
+
import eslintConfigPrettier from "eslint-config-prettier"
|
|
4
|
+
import pluginReact from "eslint-plugin-react"
|
|
5
|
+
import pluginReactHooks from "eslint-plugin-react-hooks"
|
|
6
|
+
import globals from "globals"
|
|
7
|
+
import tseslint from "typescript-eslint"
|
|
8
|
+
|
|
9
|
+
import { config as baseConfig } from "./base.js"
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A custom ESLint configuration for libraries that use Next.js.
|
|
13
|
+
*
|
|
14
|
+
* @type {import("eslint").Linter.Config}
|
|
15
|
+
* */
|
|
16
|
+
export const nextJsConfig = [
|
|
17
|
+
...baseConfig,
|
|
18
|
+
js.configs.recommended,
|
|
19
|
+
eslintConfigPrettier,
|
|
20
|
+
...tseslint.configs.recommended,
|
|
21
|
+
{
|
|
22
|
+
...pluginReact.configs.flat.recommended,
|
|
23
|
+
languageOptions: {
|
|
24
|
+
...pluginReact.configs.flat.recommended.languageOptions,
|
|
25
|
+
globals: {
|
|
26
|
+
...globals.serviceworker,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
plugins: {
|
|
32
|
+
"@next/next": pluginNext,
|
|
33
|
+
},
|
|
34
|
+
rules: {
|
|
35
|
+
...pluginNext.configs.recommended.rules,
|
|
36
|
+
...pluginNext.configs["core-web-vitals"].rules,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
plugins: {
|
|
41
|
+
"react-hooks": pluginReactHooks,
|
|
42
|
+
},
|
|
43
|
+
settings: { react: { version: "detect" } },
|
|
44
|
+
rules: {
|
|
45
|
+
...pluginReactHooks.configs.recommended.rules,
|
|
46
|
+
// React scope no longer necessary with new JSX transform.
|
|
47
|
+
"react/react-in-jsx-scope": "off",
|
|
48
|
+
"react/prop-types": "off",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@workspace/eslint-config",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"private": true,
|
|
6
|
+
"exports": {
|
|
7
|
+
"./base": "./base.js",
|
|
8
|
+
"./next-js": "./next.js",
|
|
9
|
+
"./react-internal": "./react-internal.js"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@eslint/js": "^9.39.2",
|
|
13
|
+
"@next/eslint-plugin-next": "^16.1.6",
|
|
14
|
+
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
15
|
+
"@typescript-eslint/parser": "^8.54.0",
|
|
16
|
+
"eslint": "^9.39.2",
|
|
17
|
+
"eslint-config-prettier": "^10.1.8",
|
|
18
|
+
"eslint-plugin-only-warn": "^1.1.0",
|
|
19
|
+
"eslint-plugin-react": "^7.37.5",
|
|
20
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
21
|
+
"eslint-plugin-turbo": "^2.8.1",
|
|
22
|
+
"globals": "^17.2.0",
|
|
23
|
+
"typescript": "^5.9.3",
|
|
24
|
+
"typescript-eslint": "^8.54.0"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import js from "@eslint/js"
|
|
2
|
+
import eslintConfigPrettier from "eslint-config-prettier"
|
|
3
|
+
import pluginReact from "eslint-plugin-react"
|
|
4
|
+
import pluginReactHooks from "eslint-plugin-react-hooks"
|
|
5
|
+
import globals from "globals"
|
|
6
|
+
import tseslint from "typescript-eslint"
|
|
7
|
+
|
|
8
|
+
import { config as baseConfig } from "./base.js"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A custom ESLint configuration for libraries that use React.
|
|
12
|
+
*
|
|
13
|
+
* @type {import("eslint").Linter.Config} */
|
|
14
|
+
export const config = [
|
|
15
|
+
...baseConfig,
|
|
16
|
+
js.configs.recommended,
|
|
17
|
+
eslintConfigPrettier,
|
|
18
|
+
...tseslint.configs.recommended,
|
|
19
|
+
pluginReact.configs.flat.recommended,
|
|
20
|
+
{
|
|
21
|
+
languageOptions: {
|
|
22
|
+
...pluginReact.configs.flat.recommended.languageOptions,
|
|
23
|
+
globals: {
|
|
24
|
+
...globals.serviceworker,
|
|
25
|
+
...globals.browser,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
plugins: {
|
|
31
|
+
"react-hooks": pluginReactHooks,
|
|
32
|
+
},
|
|
33
|
+
settings: { react: { version: "detect" } },
|
|
34
|
+
rules: {
|
|
35
|
+
...pluginReactHooks.configs.recommended.rules,
|
|
36
|
+
// React scope no longer necessary with new JSX transform.
|
|
37
|
+
"react/react-in-jsx-scope": "off",
|
|
38
|
+
"react/prop-types": "off",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"display": "Default",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"declarationMap": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"incremental": false,
|
|
9
|
+
"isolatedModules": true,
|
|
10
|
+
"lib": ["es2022", "DOM", "DOM.Iterable"],
|
|
11
|
+
"module": "NodeNext",
|
|
12
|
+
"moduleDetection": "force",
|
|
13
|
+
"moduleResolution": "NodeNext",
|
|
14
|
+
"noUncheckedIndexedAccess": true,
|
|
15
|
+
"resolveJsonModule": true,
|
|
16
|
+
"skipLibCheck": true,
|
|
17
|
+
"strict": true,
|
|
18
|
+
"target": "ES2022"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"display": "Next.js",
|
|
4
|
+
"extends": "./base.json",
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"plugins": [{ "name": "next" }],
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"moduleResolution": "Bundler",
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
"jsx": "preserve",
|
|
11
|
+
"noEmit": true
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "radix-lyra",
|
|
4
|
+
"rsc": true,
|
|
5
|
+
"tsx": true,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "",
|
|
8
|
+
"css": "src/styles/globals.css",
|
|
9
|
+
"baseColor": "neutral",
|
|
10
|
+
"cssVariables": true
|
|
11
|
+
},
|
|
12
|
+
"iconLibrary": "lucide",
|
|
13
|
+
"aliases": {
|
|
14
|
+
"components": "@workspace/ui/ui",
|
|
15
|
+
"utils": "@workspace/ui/runtime/utils",
|
|
16
|
+
"hooks": "@workspace/ui/runtime/hooks",
|
|
17
|
+
"lib": "@workspace/ui/runtime",
|
|
18
|
+
"ui": "@workspace/ui/ui"
|
|
19
|
+
},
|
|
20
|
+
"rtl": true,
|
|
21
|
+
"menuColor": "default",
|
|
22
|
+
"menuAccent": "subtle"
|
|
23
|
+
}
|