@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.
Files changed (659) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +71 -2
  3. package/THIRD_PARTY_NOTICES.md +14 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +100 -0
  6. package/dist/generate.d.ts +55 -0
  7. package/dist/generate.js +154 -0
  8. package/dist/model.d.ts +33 -0
  9. package/dist/model.js +24 -0
  10. package/dist/verify.d.ts +61 -0
  11. package/dist/verify.js +264 -0
  12. package/package.json +49 -4
  13. package/schemas/manifest.json +171 -0
  14. package/schemas/plan.json +164 -0
  15. package/schemas/result.json +97 -0
  16. package/schemas/spec.json +50 -0
  17. package/skills/scaffold-use/SKILL.md +6 -0
  18. package/templates/catalog.json +37 -0
  19. package/templates/next-fullstack-antd/.agents/skills/design-contract/SKILL.md +23 -0
  20. package/templates/next-fullstack-antd/.agents/skills/project-work/SKILL.md +8 -0
  21. package/templates/next-fullstack-antd/.claude/skills/design-contract/SKILL.md +23 -0
  22. package/templates/next-fullstack-antd/.claude/skills/project-work/SKILL.md +8 -0
  23. package/templates/next-fullstack-antd/.dockerignore +18 -0
  24. package/templates/next-fullstack-antd/.env.example +13 -0
  25. package/templates/next-fullstack-antd/.grok/skills/design-contract/SKILL.md +23 -0
  26. package/templates/next-fullstack-antd/.grok/skills/project-work/SKILL.md +8 -0
  27. package/templates/next-fullstack-antd/.scaffold-checks.json +7 -0
  28. package/templates/next-fullstack-antd/AGENTS.md +11 -0
  29. package/templates/next-fullstack-antd/CLAUDE.md +1 -0
  30. package/templates/next-fullstack-antd/DESIGN.md +208 -0
  31. package/templates/next-fullstack-antd/LICENSE +21 -0
  32. package/templates/next-fullstack-antd/README.md +55 -0
  33. package/templates/next-fullstack-antd/THIRD_PARTY_NOTICES.md +14 -0
  34. package/templates/next-fullstack-antd/compose.yaml +18 -0
  35. package/templates/next-fullstack-antd/design/guide.md +61 -0
  36. package/templates/next-fullstack-antd/design/layout.css +6 -0
  37. package/templates/next-fullstack-antd/design/structure.json +107 -0
  38. package/templates/next-fullstack-antd/design/tokens.json +171 -0
  39. package/templates/next-fullstack-antd/design/widgets.css +30 -0
  40. package/templates/next-fullstack-antd/design/widgets.json +233 -0
  41. package/templates/next-fullstack-antd/docs/PROJECT.md +9 -0
  42. package/templates/next-fullstack-antd/docs/api.d.ts +516 -0
  43. package/templates/next-fullstack-antd/docs/openapi.json +439 -0
  44. package/templates/next-fullstack-antd/gitignore.template +19 -0
  45. package/templates/next-fullstack-antd/licenses/fastapi.txt +21 -0
  46. package/templates/next-fullstack-antd/licenses/nest.txt +22 -0
  47. package/templates/next-fullstack-antd/licenses/next.txt +21 -0
  48. package/templates/next-fullstack-antd/licenses/shadcn.txt +21 -0
  49. package/templates/next-fullstack-antd/licenses/sources.json +27 -0
  50. package/templates/next-fullstack-antd/licenses/spring.txt +202 -0
  51. package/templates/next-fullstack-antd/package-lock.json +440 -0
  52. package/templates/next-fullstack-antd/package.json +21 -0
  53. package/templates/next-fullstack-antd/playwright.config.ts +3 -0
  54. package/templates/next-fullstack-antd/project.json +8 -0
  55. package/templates/next-fullstack-antd/scripts/design-coverage.mjs +20 -0
  56. package/templates/next-fullstack-antd/scripts/design-next-cleanup.mjs +13 -0
  57. package/templates/next-fullstack-antd/scripts/design-verify.mjs +154 -0
  58. package/templates/next-fullstack-antd/scripts/design.mjs +108 -0
  59. package/templates/next-fullstack-antd/scripts/project.mjs +118 -0
  60. package/templates/next-fullstack-antd/tests/contract.spec.ts +47 -0
  61. package/templates/next-fullstack-antd/tests/design/harness.tsx +63 -0
  62. package/templates/next-fullstack-antd/tests/ui.spec.ts +61 -0
  63. package/templates/next-fullstack-antd/web/Dockerfile +12 -0
  64. package/templates/next-fullstack-antd/web/app/api/auth/login/route.ts +1 -0
  65. package/templates/next-fullstack-antd/web/app/api/auth/logout/route.ts +1 -0
  66. package/templates/next-fullstack-antd/web/app/api/auth/me/route.ts +1 -0
  67. package/templates/next-fullstack-antd/web/app/api/health/route.ts +1 -0
  68. package/templates/next-fullstack-antd/web/app/api/records/[id]/route.ts +5 -0
  69. package/templates/next-fullstack-antd/web/app/api/records/route.ts +3 -0
  70. package/templates/next-fullstack-antd/web/app/layout.tsx +5 -0
  71. package/templates/next-fullstack-antd/web/app/page.tsx +2 -0
  72. package/templates/next-fullstack-antd/web/eslint.config.mjs +3 -0
  73. package/templates/next-fullstack-antd/web/lib/api.ts +35 -0
  74. package/templates/next-fullstack-antd/web/lib/auth.ts +10 -0
  75. package/templates/next-fullstack-antd/web/lib/db.ts +3 -0
  76. package/templates/next-fullstack-antd/web/lib/session.test.ts +15 -0
  77. package/templates/next-fullstack-antd/web/lib/validation.test.ts +3 -0
  78. package/templates/next-fullstack-antd/web/lib/validation.ts +5 -0
  79. package/templates/next-fullstack-antd/web/next-env.d.ts +7 -0
  80. package/templates/next-fullstack-antd/web/next.config.ts +3 -0
  81. package/templates/next-fullstack-antd/web/package.json +35 -0
  82. package/templates/next-fullstack-antd/web/pnpm-lock.yaml +3756 -0
  83. package/templates/next-fullstack-antd/web/pnpm-workspace.yaml +7 -0
  84. package/templates/next-fullstack-antd/web/prisma/migrations/202610190001_initial/migration.sql +99 -0
  85. package/templates/next-fullstack-antd/web/prisma/migrations/migration_lock.toml +1 -0
  86. package/templates/next-fullstack-antd/web/prisma/schema.prisma +72 -0
  87. package/templates/next-fullstack-antd/web/scripts/seed.ts +4 -0
  88. package/templates/next-fullstack-antd/web/src/App.tsx +29 -0
  89. package/templates/next-fullstack-antd/web/src/design-layout.css +7 -0
  90. package/templates/next-fullstack-antd/web/src/design-runtime.json +511 -0
  91. package/templates/next-fullstack-antd/web/src/design-tokens.css +168 -0
  92. package/templates/next-fullstack-antd/web/src/design-widgets.css +31 -0
  93. package/templates/next-fullstack-antd/web/src/structure-view.tsx +16 -0
  94. package/templates/next-fullstack-antd/web/src/styles.css +3 -0
  95. package/templates/next-fullstack-antd/web/src/ui.tsx +30 -0
  96. package/templates/next-fullstack-antd/web/src/widget-icon.tsx +5 -0
  97. package/templates/next-fullstack-antd/web/src/widget-types.ts +13 -0
  98. package/templates/next-fullstack-antd/web/src/workspace-model.ts +85 -0
  99. package/templates/next-fullstack-antd/web/tsconfig.json +42 -0
  100. package/templates/next-fullstack-antd/web/vitest.config.ts +2 -0
  101. package/templates/next-fullstack-shadcn/.agents/skills/design-contract/SKILL.md +23 -0
  102. package/templates/next-fullstack-shadcn/.agents/skills/project-work/SKILL.md +8 -0
  103. package/templates/next-fullstack-shadcn/.claude/skills/design-contract/SKILL.md +23 -0
  104. package/templates/next-fullstack-shadcn/.claude/skills/project-work/SKILL.md +8 -0
  105. package/templates/next-fullstack-shadcn/.dockerignore +18 -0
  106. package/templates/next-fullstack-shadcn/.env.example +13 -0
  107. package/templates/next-fullstack-shadcn/.grok/skills/design-contract/SKILL.md +23 -0
  108. package/templates/next-fullstack-shadcn/.grok/skills/project-work/SKILL.md +8 -0
  109. package/templates/next-fullstack-shadcn/.scaffold-checks.json +7 -0
  110. package/templates/next-fullstack-shadcn/AGENTS.md +11 -0
  111. package/templates/next-fullstack-shadcn/CLAUDE.md +1 -0
  112. package/templates/next-fullstack-shadcn/DESIGN.md +208 -0
  113. package/templates/next-fullstack-shadcn/LICENSE +21 -0
  114. package/templates/next-fullstack-shadcn/README.md +55 -0
  115. package/templates/next-fullstack-shadcn/THIRD_PARTY_NOTICES.md +14 -0
  116. package/templates/next-fullstack-shadcn/compose.yaml +18 -0
  117. package/templates/next-fullstack-shadcn/design/guide.md +61 -0
  118. package/templates/next-fullstack-shadcn/design/layout.css +6 -0
  119. package/templates/next-fullstack-shadcn/design/structure.json +107 -0
  120. package/templates/next-fullstack-shadcn/design/tokens.json +171 -0
  121. package/templates/next-fullstack-shadcn/design/widgets.css +30 -0
  122. package/templates/next-fullstack-shadcn/design/widgets.json +233 -0
  123. package/templates/next-fullstack-shadcn/docs/PROJECT.md +9 -0
  124. package/templates/next-fullstack-shadcn/docs/api.d.ts +516 -0
  125. package/templates/next-fullstack-shadcn/docs/openapi.json +439 -0
  126. package/templates/next-fullstack-shadcn/gitignore.template +19 -0
  127. package/templates/next-fullstack-shadcn/licenses/fastapi.txt +21 -0
  128. package/templates/next-fullstack-shadcn/licenses/nest.txt +22 -0
  129. package/templates/next-fullstack-shadcn/licenses/next.txt +21 -0
  130. package/templates/next-fullstack-shadcn/licenses/shadcn.txt +21 -0
  131. package/templates/next-fullstack-shadcn/licenses/sources.json +27 -0
  132. package/templates/next-fullstack-shadcn/licenses/spring.txt +202 -0
  133. package/templates/next-fullstack-shadcn/package-lock.json +440 -0
  134. package/templates/next-fullstack-shadcn/package.json +21 -0
  135. package/templates/next-fullstack-shadcn/playwright.config.ts +3 -0
  136. package/templates/next-fullstack-shadcn/project.json +8 -0
  137. package/templates/next-fullstack-shadcn/scripts/design-coverage.mjs +20 -0
  138. package/templates/next-fullstack-shadcn/scripts/design-next-cleanup.mjs +13 -0
  139. package/templates/next-fullstack-shadcn/scripts/design-verify.mjs +154 -0
  140. package/templates/next-fullstack-shadcn/scripts/design.mjs +108 -0
  141. package/templates/next-fullstack-shadcn/scripts/project.mjs +118 -0
  142. package/templates/next-fullstack-shadcn/tests/contract.spec.ts +47 -0
  143. package/templates/next-fullstack-shadcn/tests/design/harness.tsx +63 -0
  144. package/templates/next-fullstack-shadcn/tests/ui.spec.ts +61 -0
  145. package/templates/next-fullstack-shadcn/web/Dockerfile +12 -0
  146. package/templates/next-fullstack-shadcn/web/app/api/auth/login/route.ts +1 -0
  147. package/templates/next-fullstack-shadcn/web/app/api/auth/logout/route.ts +1 -0
  148. package/templates/next-fullstack-shadcn/web/app/api/auth/me/route.ts +1 -0
  149. package/templates/next-fullstack-shadcn/web/app/api/health/route.ts +1 -0
  150. package/templates/next-fullstack-shadcn/web/app/api/records/[id]/route.ts +5 -0
  151. package/templates/next-fullstack-shadcn/web/app/api/records/route.ts +3 -0
  152. package/templates/next-fullstack-shadcn/web/app/layout.tsx +4 -0
  153. package/templates/next-fullstack-shadcn/web/app/page.tsx +2 -0
  154. package/templates/next-fullstack-shadcn/web/eslint.config.mjs +3 -0
  155. package/templates/next-fullstack-shadcn/web/lib/api.ts +35 -0
  156. package/templates/next-fullstack-shadcn/web/lib/auth.ts +10 -0
  157. package/templates/next-fullstack-shadcn/web/lib/db.ts +3 -0
  158. package/templates/next-fullstack-shadcn/web/lib/session.test.ts +15 -0
  159. package/templates/next-fullstack-shadcn/web/lib/validation.test.ts +3 -0
  160. package/templates/next-fullstack-shadcn/web/lib/validation.ts +5 -0
  161. package/templates/next-fullstack-shadcn/web/next-env.d.ts +7 -0
  162. package/templates/next-fullstack-shadcn/web/next.config.ts +3 -0
  163. package/templates/next-fullstack-shadcn/web/package.json +39 -0
  164. package/templates/next-fullstack-shadcn/web/pnpm-lock.yaml +3286 -0
  165. package/templates/next-fullstack-shadcn/web/pnpm-workspace.yaml +7 -0
  166. package/templates/next-fullstack-shadcn/web/postcss.config.mjs +1 -0
  167. package/templates/next-fullstack-shadcn/web/prisma/migrations/202610190001_initial/migration.sql +99 -0
  168. package/templates/next-fullstack-shadcn/web/prisma/migrations/migration_lock.toml +1 -0
  169. package/templates/next-fullstack-shadcn/web/prisma/schema.prisma +72 -0
  170. package/templates/next-fullstack-shadcn/web/scripts/seed.ts +4 -0
  171. package/templates/next-fullstack-shadcn/web/src/App.tsx +30 -0
  172. package/templates/next-fullstack-shadcn/web/src/design-layout.css +7 -0
  173. package/templates/next-fullstack-shadcn/web/src/design-runtime.json +511 -0
  174. package/templates/next-fullstack-shadcn/web/src/design-tokens.css +168 -0
  175. package/templates/next-fullstack-shadcn/web/src/design-widgets.css +31 -0
  176. package/templates/next-fullstack-shadcn/web/src/structure-view.tsx +16 -0
  177. package/templates/next-fullstack-shadcn/web/src/styles.css +3 -0
  178. package/templates/next-fullstack-shadcn/web/src/tailwind.css +2 -0
  179. package/templates/next-fullstack-shadcn/web/src/ui.tsx +13 -0
  180. package/templates/next-fullstack-shadcn/web/src/widget-icon.tsx +5 -0
  181. package/templates/next-fullstack-shadcn/web/src/widget-types.ts +13 -0
  182. package/templates/next-fullstack-shadcn/web/src/workspace-model.ts +85 -0
  183. package/templates/next-fullstack-shadcn/web/tsconfig.json +42 -0
  184. package/templates/next-fullstack-shadcn/web/vitest.config.ts +2 -0
  185. package/templates/react-fastapi-antd/.agents/skills/design-contract/SKILL.md +23 -0
  186. package/templates/react-fastapi-antd/.agents/skills/project-work/SKILL.md +8 -0
  187. package/templates/react-fastapi-antd/.claude/skills/design-contract/SKILL.md +23 -0
  188. package/templates/react-fastapi-antd/.claude/skills/project-work/SKILL.md +8 -0
  189. package/templates/react-fastapi-antd/.dockerignore +18 -0
  190. package/templates/react-fastapi-antd/.env.example +13 -0
  191. package/templates/react-fastapi-antd/.grok/skills/design-contract/SKILL.md +23 -0
  192. package/templates/react-fastapi-antd/.grok/skills/project-work/SKILL.md +8 -0
  193. package/templates/react-fastapi-antd/.scaffold-checks.json +7 -0
  194. package/templates/react-fastapi-antd/AGENTS.md +11 -0
  195. package/templates/react-fastapi-antd/CLAUDE.md +1 -0
  196. package/templates/react-fastapi-antd/DESIGN.md +208 -0
  197. package/templates/react-fastapi-antd/LICENSE +21 -0
  198. package/templates/react-fastapi-antd/README.md +55 -0
  199. package/templates/react-fastapi-antd/THIRD_PARTY_NOTICES.md +14 -0
  200. package/templates/react-fastapi-antd/backend/.python-version +1 -0
  201. package/templates/react-fastapi-antd/backend/Dockerfile +10 -0
  202. package/templates/react-fastapi-antd/backend/alembic.ini +3 -0
  203. package/templates/react-fastapi-antd/backend/app/__init__.py +0 -0
  204. package/templates/react-fastapi-antd/backend/app/core/__init__.py +0 -0
  205. package/templates/react-fastapi-antd/backend/app/core/security.py +25 -0
  206. package/templates/react-fastapi-antd/backend/app/db.py +11 -0
  207. package/templates/react-fastapi-antd/backend/app/main.py +146 -0
  208. package/templates/react-fastapi-antd/backend/app/models.py +21 -0
  209. package/templates/react-fastapi-antd/backend/app/seed.py +21 -0
  210. package/templates/react-fastapi-antd/backend/migrations/env.py +9 -0
  211. package/templates/react-fastapi-antd/backend/migrations/versions/0001_initial.py +18 -0
  212. package/templates/react-fastapi-antd/backend/pyproject.toml +16 -0
  213. package/templates/react-fastapi-antd/backend/tests/test_api.py +27 -0
  214. package/templates/react-fastapi-antd/backend/uv.lock +1085 -0
  215. package/templates/react-fastapi-antd/compose.yaml +18 -0
  216. package/templates/react-fastapi-antd/design/guide.md +61 -0
  217. package/templates/react-fastapi-antd/design/layout.css +6 -0
  218. package/templates/react-fastapi-antd/design/structure.json +107 -0
  219. package/templates/react-fastapi-antd/design/tokens.json +171 -0
  220. package/templates/react-fastapi-antd/design/widgets.css +30 -0
  221. package/templates/react-fastapi-antd/design/widgets.json +233 -0
  222. package/templates/react-fastapi-antd/docs/PROJECT.md +9 -0
  223. package/templates/react-fastapi-antd/docs/api.d.ts +516 -0
  224. package/templates/react-fastapi-antd/docs/openapi.json +439 -0
  225. package/templates/react-fastapi-antd/gitignore.template +19 -0
  226. package/templates/react-fastapi-antd/licenses/fastapi.txt +21 -0
  227. package/templates/react-fastapi-antd/licenses/nest.txt +22 -0
  228. package/templates/react-fastapi-antd/licenses/next.txt +21 -0
  229. package/templates/react-fastapi-antd/licenses/shadcn.txt +21 -0
  230. package/templates/react-fastapi-antd/licenses/sources.json +27 -0
  231. package/templates/react-fastapi-antd/licenses/spring.txt +202 -0
  232. package/templates/react-fastapi-antd/package-lock.json +440 -0
  233. package/templates/react-fastapi-antd/package.json +21 -0
  234. package/templates/react-fastapi-antd/playwright.config.ts +3 -0
  235. package/templates/react-fastapi-antd/project.json +8 -0
  236. package/templates/react-fastapi-antd/scripts/design-coverage.mjs +20 -0
  237. package/templates/react-fastapi-antd/scripts/design-next-cleanup.mjs +13 -0
  238. package/templates/react-fastapi-antd/scripts/design-verify.mjs +154 -0
  239. package/templates/react-fastapi-antd/scripts/design.mjs +108 -0
  240. package/templates/react-fastapi-antd/scripts/project.mjs +118 -0
  241. package/templates/react-fastapi-antd/tests/contract.spec.ts +47 -0
  242. package/templates/react-fastapi-antd/tests/design/harness.tsx +63 -0
  243. package/templates/react-fastapi-antd/tests/ui.spec.ts +61 -0
  244. package/templates/react-fastapi-antd/web/bun.lock +442 -0
  245. package/templates/react-fastapi-antd/web/eslint.config.mjs +3 -0
  246. package/templates/react-fastapi-antd/web/index.html +1 -0
  247. package/templates/react-fastapi-antd/web/package.json +28 -0
  248. package/templates/react-fastapi-antd/web/src/App.tsx +29 -0
  249. package/templates/react-fastapi-antd/web/src/design-layout.css +7 -0
  250. package/templates/react-fastapi-antd/web/src/design-runtime.json +511 -0
  251. package/templates/react-fastapi-antd/web/src/design-tokens.css +168 -0
  252. package/templates/react-fastapi-antd/web/src/design-widgets.css +31 -0
  253. package/templates/react-fastapi-antd/web/src/main.tsx +6 -0
  254. package/templates/react-fastapi-antd/web/src/structure-view.tsx +16 -0
  255. package/templates/react-fastapi-antd/web/src/styles.css +3 -0
  256. package/templates/react-fastapi-antd/web/src/ui.tsx +30 -0
  257. package/templates/react-fastapi-antd/web/src/widget-icon.tsx +5 -0
  258. package/templates/react-fastapi-antd/web/src/widget-types.ts +13 -0
  259. package/templates/react-fastapi-antd/web/src/workspace-model.ts +85 -0
  260. package/templates/react-fastapi-antd/web/tsconfig.json +22 -0
  261. package/templates/react-fastapi-antd/web/vite.config.ts +3 -0
  262. package/templates/react-fastapi-shadcn/.agents/skills/design-contract/SKILL.md +23 -0
  263. package/templates/react-fastapi-shadcn/.agents/skills/project-work/SKILL.md +8 -0
  264. package/templates/react-fastapi-shadcn/.claude/skills/design-contract/SKILL.md +23 -0
  265. package/templates/react-fastapi-shadcn/.claude/skills/project-work/SKILL.md +8 -0
  266. package/templates/react-fastapi-shadcn/.dockerignore +18 -0
  267. package/templates/react-fastapi-shadcn/.env.example +13 -0
  268. package/templates/react-fastapi-shadcn/.grok/skills/design-contract/SKILL.md +23 -0
  269. package/templates/react-fastapi-shadcn/.grok/skills/project-work/SKILL.md +8 -0
  270. package/templates/react-fastapi-shadcn/.scaffold-checks.json +7 -0
  271. package/templates/react-fastapi-shadcn/AGENTS.md +11 -0
  272. package/templates/react-fastapi-shadcn/CLAUDE.md +1 -0
  273. package/templates/react-fastapi-shadcn/DESIGN.md +208 -0
  274. package/templates/react-fastapi-shadcn/LICENSE +21 -0
  275. package/templates/react-fastapi-shadcn/README.md +55 -0
  276. package/templates/react-fastapi-shadcn/THIRD_PARTY_NOTICES.md +14 -0
  277. package/templates/react-fastapi-shadcn/backend/.python-version +1 -0
  278. package/templates/react-fastapi-shadcn/backend/Dockerfile +10 -0
  279. package/templates/react-fastapi-shadcn/backend/alembic.ini +3 -0
  280. package/templates/react-fastapi-shadcn/backend/app/__init__.py +0 -0
  281. package/templates/react-fastapi-shadcn/backend/app/core/__init__.py +0 -0
  282. package/templates/react-fastapi-shadcn/backend/app/core/security.py +25 -0
  283. package/templates/react-fastapi-shadcn/backend/app/db.py +11 -0
  284. package/templates/react-fastapi-shadcn/backend/app/main.py +146 -0
  285. package/templates/react-fastapi-shadcn/backend/app/models.py +21 -0
  286. package/templates/react-fastapi-shadcn/backend/app/seed.py +21 -0
  287. package/templates/react-fastapi-shadcn/backend/migrations/env.py +9 -0
  288. package/templates/react-fastapi-shadcn/backend/migrations/versions/0001_initial.py +18 -0
  289. package/templates/react-fastapi-shadcn/backend/pyproject.toml +16 -0
  290. package/templates/react-fastapi-shadcn/backend/tests/test_api.py +27 -0
  291. package/templates/react-fastapi-shadcn/backend/uv.lock +1085 -0
  292. package/templates/react-fastapi-shadcn/compose.yaml +18 -0
  293. package/templates/react-fastapi-shadcn/design/guide.md +61 -0
  294. package/templates/react-fastapi-shadcn/design/layout.css +6 -0
  295. package/templates/react-fastapi-shadcn/design/structure.json +107 -0
  296. package/templates/react-fastapi-shadcn/design/tokens.json +171 -0
  297. package/templates/react-fastapi-shadcn/design/widgets.css +30 -0
  298. package/templates/react-fastapi-shadcn/design/widgets.json +233 -0
  299. package/templates/react-fastapi-shadcn/docs/PROJECT.md +9 -0
  300. package/templates/react-fastapi-shadcn/docs/api.d.ts +516 -0
  301. package/templates/react-fastapi-shadcn/docs/openapi.json +439 -0
  302. package/templates/react-fastapi-shadcn/gitignore.template +19 -0
  303. package/templates/react-fastapi-shadcn/licenses/fastapi.txt +21 -0
  304. package/templates/react-fastapi-shadcn/licenses/nest.txt +22 -0
  305. package/templates/react-fastapi-shadcn/licenses/next.txt +21 -0
  306. package/templates/react-fastapi-shadcn/licenses/shadcn.txt +21 -0
  307. package/templates/react-fastapi-shadcn/licenses/sources.json +27 -0
  308. package/templates/react-fastapi-shadcn/licenses/spring.txt +202 -0
  309. package/templates/react-fastapi-shadcn/package-lock.json +440 -0
  310. package/templates/react-fastapi-shadcn/package.json +21 -0
  311. package/templates/react-fastapi-shadcn/playwright.config.ts +3 -0
  312. package/templates/react-fastapi-shadcn/project.json +8 -0
  313. package/templates/react-fastapi-shadcn/scripts/design-coverage.mjs +20 -0
  314. package/templates/react-fastapi-shadcn/scripts/design-next-cleanup.mjs +13 -0
  315. package/templates/react-fastapi-shadcn/scripts/design-verify.mjs +154 -0
  316. package/templates/react-fastapi-shadcn/scripts/design.mjs +108 -0
  317. package/templates/react-fastapi-shadcn/scripts/project.mjs +118 -0
  318. package/templates/react-fastapi-shadcn/tests/contract.spec.ts +47 -0
  319. package/templates/react-fastapi-shadcn/tests/design/harness.tsx +63 -0
  320. package/templates/react-fastapi-shadcn/tests/ui.spec.ts +61 -0
  321. package/templates/react-fastapi-shadcn/web/bun.lock +413 -0
  322. package/templates/react-fastapi-shadcn/web/eslint.config.mjs +3 -0
  323. package/templates/react-fastapi-shadcn/web/index.html +1 -0
  324. package/templates/react-fastapi-shadcn/web/package.json +33 -0
  325. package/templates/react-fastapi-shadcn/web/src/App.tsx +30 -0
  326. package/templates/react-fastapi-shadcn/web/src/design-layout.css +7 -0
  327. package/templates/react-fastapi-shadcn/web/src/design-runtime.json +511 -0
  328. package/templates/react-fastapi-shadcn/web/src/design-tokens.css +168 -0
  329. package/templates/react-fastapi-shadcn/web/src/design-widgets.css +31 -0
  330. package/templates/react-fastapi-shadcn/web/src/main.tsx +6 -0
  331. package/templates/react-fastapi-shadcn/web/src/structure-view.tsx +16 -0
  332. package/templates/react-fastapi-shadcn/web/src/styles.css +3 -0
  333. package/templates/react-fastapi-shadcn/web/src/tailwind.css +2 -0
  334. package/templates/react-fastapi-shadcn/web/src/ui.tsx +13 -0
  335. package/templates/react-fastapi-shadcn/web/src/widget-icon.tsx +5 -0
  336. package/templates/react-fastapi-shadcn/web/src/widget-types.ts +13 -0
  337. package/templates/react-fastapi-shadcn/web/src/workspace-model.ts +85 -0
  338. package/templates/react-fastapi-shadcn/web/tsconfig.json +22 -0
  339. package/templates/react-fastapi-shadcn/web/vite.config.ts +4 -0
  340. package/templates/react-nest-antd/.agents/skills/design-contract/SKILL.md +23 -0
  341. package/templates/react-nest-antd/.agents/skills/project-work/SKILL.md +8 -0
  342. package/templates/react-nest-antd/.claude/skills/design-contract/SKILL.md +23 -0
  343. package/templates/react-nest-antd/.claude/skills/project-work/SKILL.md +8 -0
  344. package/templates/react-nest-antd/.dockerignore +18 -0
  345. package/templates/react-nest-antd/.env.example +13 -0
  346. package/templates/react-nest-antd/.grok/skills/design-contract/SKILL.md +23 -0
  347. package/templates/react-nest-antd/.grok/skills/project-work/SKILL.md +8 -0
  348. package/templates/react-nest-antd/.scaffold-checks.json +7 -0
  349. package/templates/react-nest-antd/AGENTS.md +11 -0
  350. package/templates/react-nest-antd/CLAUDE.md +1 -0
  351. package/templates/react-nest-antd/DESIGN.md +208 -0
  352. package/templates/react-nest-antd/LICENSE +21 -0
  353. package/templates/react-nest-antd/README.md +55 -0
  354. package/templates/react-nest-antd/THIRD_PARTY_NOTICES.md +14 -0
  355. package/templates/react-nest-antd/backend/Dockerfile +12 -0
  356. package/templates/react-nest-antd/backend/eslint.config.mjs +3 -0
  357. package/templates/react-nest-antd/backend/jest.config.cjs +1 -0
  358. package/templates/react-nest-antd/backend/package.json +40 -0
  359. package/templates/react-nest-antd/backend/pnpm-lock.yaml +5165 -0
  360. package/templates/react-nest-antd/backend/pnpm-workspace.yaml +6 -0
  361. package/templates/react-nest-antd/backend/prisma/migrations/202610190001_initial/migration.sql +3 -0
  362. package/templates/react-nest-antd/backend/prisma/migrations/migration_lock.toml +1 -0
  363. package/templates/react-nest-antd/backend/prisma/schema.prisma +25 -0
  364. package/templates/react-nest-antd/backend/scripts/seed.ts +4 -0
  365. package/templates/react-nest-antd/backend/src/app.module.ts +43 -0
  366. package/templates/react-nest-antd/backend/src/main.ts +6 -0
  367. package/templates/react-nest-antd/backend/src/password.ts +3 -0
  368. package/templates/react-nest-antd/backend/src/validation.ts +7 -0
  369. package/templates/react-nest-antd/backend/test/api.test.ts +25 -0
  370. package/templates/react-nest-antd/backend/tsconfig.build.json +15 -0
  371. package/templates/react-nest-antd/backend/tsconfig.json +17 -0
  372. package/templates/react-nest-antd/compose.yaml +18 -0
  373. package/templates/react-nest-antd/design/guide.md +61 -0
  374. package/templates/react-nest-antd/design/layout.css +6 -0
  375. package/templates/react-nest-antd/design/structure.json +107 -0
  376. package/templates/react-nest-antd/design/tokens.json +171 -0
  377. package/templates/react-nest-antd/design/widgets.css +30 -0
  378. package/templates/react-nest-antd/design/widgets.json +233 -0
  379. package/templates/react-nest-antd/docs/PROJECT.md +9 -0
  380. package/templates/react-nest-antd/docs/api.d.ts +516 -0
  381. package/templates/react-nest-antd/docs/openapi.json +439 -0
  382. package/templates/react-nest-antd/gitignore.template +19 -0
  383. package/templates/react-nest-antd/licenses/fastapi.txt +21 -0
  384. package/templates/react-nest-antd/licenses/nest.txt +22 -0
  385. package/templates/react-nest-antd/licenses/next.txt +21 -0
  386. package/templates/react-nest-antd/licenses/shadcn.txt +21 -0
  387. package/templates/react-nest-antd/licenses/sources.json +27 -0
  388. package/templates/react-nest-antd/licenses/spring.txt +202 -0
  389. package/templates/react-nest-antd/package-lock.json +440 -0
  390. package/templates/react-nest-antd/package.json +21 -0
  391. package/templates/react-nest-antd/playwright.config.ts +3 -0
  392. package/templates/react-nest-antd/project.json +8 -0
  393. package/templates/react-nest-antd/scripts/design-coverage.mjs +20 -0
  394. package/templates/react-nest-antd/scripts/design-next-cleanup.mjs +13 -0
  395. package/templates/react-nest-antd/scripts/design-verify.mjs +154 -0
  396. package/templates/react-nest-antd/scripts/design.mjs +108 -0
  397. package/templates/react-nest-antd/scripts/project.mjs +118 -0
  398. package/templates/react-nest-antd/tests/contract.spec.ts +47 -0
  399. package/templates/react-nest-antd/tests/design/harness.tsx +63 -0
  400. package/templates/react-nest-antd/tests/ui.spec.ts +61 -0
  401. package/templates/react-nest-antd/web/eslint.config.mjs +3 -0
  402. package/templates/react-nest-antd/web/index.html +1 -0
  403. package/templates/react-nest-antd/web/package.json +28 -0
  404. package/templates/react-nest-antd/web/pnpm-lock.yaml +2215 -0
  405. package/templates/react-nest-antd/web/src/App.tsx +29 -0
  406. package/templates/react-nest-antd/web/src/design-layout.css +7 -0
  407. package/templates/react-nest-antd/web/src/design-runtime.json +511 -0
  408. package/templates/react-nest-antd/web/src/design-tokens.css +168 -0
  409. package/templates/react-nest-antd/web/src/design-widgets.css +31 -0
  410. package/templates/react-nest-antd/web/src/main.tsx +6 -0
  411. package/templates/react-nest-antd/web/src/structure-view.tsx +16 -0
  412. package/templates/react-nest-antd/web/src/styles.css +3 -0
  413. package/templates/react-nest-antd/web/src/ui.tsx +30 -0
  414. package/templates/react-nest-antd/web/src/widget-icon.tsx +5 -0
  415. package/templates/react-nest-antd/web/src/widget-types.ts +13 -0
  416. package/templates/react-nest-antd/web/src/workspace-model.ts +85 -0
  417. package/templates/react-nest-antd/web/tsconfig.json +22 -0
  418. package/templates/react-nest-antd/web/vite.config.ts +3 -0
  419. package/templates/react-nest-shadcn/.agents/skills/design-contract/SKILL.md +23 -0
  420. package/templates/react-nest-shadcn/.agents/skills/project-work/SKILL.md +8 -0
  421. package/templates/react-nest-shadcn/.claude/skills/design-contract/SKILL.md +23 -0
  422. package/templates/react-nest-shadcn/.claude/skills/project-work/SKILL.md +8 -0
  423. package/templates/react-nest-shadcn/.dockerignore +18 -0
  424. package/templates/react-nest-shadcn/.env.example +13 -0
  425. package/templates/react-nest-shadcn/.grok/skills/design-contract/SKILL.md +23 -0
  426. package/templates/react-nest-shadcn/.grok/skills/project-work/SKILL.md +8 -0
  427. package/templates/react-nest-shadcn/.scaffold-checks.json +7 -0
  428. package/templates/react-nest-shadcn/AGENTS.md +11 -0
  429. package/templates/react-nest-shadcn/CLAUDE.md +1 -0
  430. package/templates/react-nest-shadcn/DESIGN.md +208 -0
  431. package/templates/react-nest-shadcn/LICENSE +21 -0
  432. package/templates/react-nest-shadcn/README.md +55 -0
  433. package/templates/react-nest-shadcn/THIRD_PARTY_NOTICES.md +14 -0
  434. package/templates/react-nest-shadcn/backend/Dockerfile +12 -0
  435. package/templates/react-nest-shadcn/backend/eslint.config.mjs +3 -0
  436. package/templates/react-nest-shadcn/backend/jest.config.cjs +1 -0
  437. package/templates/react-nest-shadcn/backend/package.json +40 -0
  438. package/templates/react-nest-shadcn/backend/pnpm-lock.yaml +5165 -0
  439. package/templates/react-nest-shadcn/backend/pnpm-workspace.yaml +6 -0
  440. package/templates/react-nest-shadcn/backend/prisma/migrations/202610190001_initial/migration.sql +3 -0
  441. package/templates/react-nest-shadcn/backend/prisma/migrations/migration_lock.toml +1 -0
  442. package/templates/react-nest-shadcn/backend/prisma/schema.prisma +25 -0
  443. package/templates/react-nest-shadcn/backend/scripts/seed.ts +4 -0
  444. package/templates/react-nest-shadcn/backend/src/app.module.ts +43 -0
  445. package/templates/react-nest-shadcn/backend/src/main.ts +6 -0
  446. package/templates/react-nest-shadcn/backend/src/password.ts +3 -0
  447. package/templates/react-nest-shadcn/backend/src/validation.ts +7 -0
  448. package/templates/react-nest-shadcn/backend/test/api.test.ts +25 -0
  449. package/templates/react-nest-shadcn/backend/tsconfig.build.json +15 -0
  450. package/templates/react-nest-shadcn/backend/tsconfig.json +17 -0
  451. package/templates/react-nest-shadcn/compose.yaml +18 -0
  452. package/templates/react-nest-shadcn/design/guide.md +61 -0
  453. package/templates/react-nest-shadcn/design/layout.css +6 -0
  454. package/templates/react-nest-shadcn/design/structure.json +107 -0
  455. package/templates/react-nest-shadcn/design/tokens.json +171 -0
  456. package/templates/react-nest-shadcn/design/widgets.css +30 -0
  457. package/templates/react-nest-shadcn/design/widgets.json +233 -0
  458. package/templates/react-nest-shadcn/docs/PROJECT.md +9 -0
  459. package/templates/react-nest-shadcn/docs/api.d.ts +516 -0
  460. package/templates/react-nest-shadcn/docs/openapi.json +439 -0
  461. package/templates/react-nest-shadcn/gitignore.template +19 -0
  462. package/templates/react-nest-shadcn/licenses/fastapi.txt +21 -0
  463. package/templates/react-nest-shadcn/licenses/nest.txt +22 -0
  464. package/templates/react-nest-shadcn/licenses/next.txt +21 -0
  465. package/templates/react-nest-shadcn/licenses/shadcn.txt +21 -0
  466. package/templates/react-nest-shadcn/licenses/sources.json +27 -0
  467. package/templates/react-nest-shadcn/licenses/spring.txt +202 -0
  468. package/templates/react-nest-shadcn/package-lock.json +440 -0
  469. package/templates/react-nest-shadcn/package.json +21 -0
  470. package/templates/react-nest-shadcn/playwright.config.ts +3 -0
  471. package/templates/react-nest-shadcn/project.json +8 -0
  472. package/templates/react-nest-shadcn/scripts/design-coverage.mjs +20 -0
  473. package/templates/react-nest-shadcn/scripts/design-next-cleanup.mjs +13 -0
  474. package/templates/react-nest-shadcn/scripts/design-verify.mjs +154 -0
  475. package/templates/react-nest-shadcn/scripts/design.mjs +108 -0
  476. package/templates/react-nest-shadcn/scripts/project.mjs +118 -0
  477. package/templates/react-nest-shadcn/tests/contract.spec.ts +47 -0
  478. package/templates/react-nest-shadcn/tests/design/harness.tsx +63 -0
  479. package/templates/react-nest-shadcn/tests/ui.spec.ts +61 -0
  480. package/templates/react-nest-shadcn/web/eslint.config.mjs +3 -0
  481. package/templates/react-nest-shadcn/web/index.html +1 -0
  482. package/templates/react-nest-shadcn/web/package.json +33 -0
  483. package/templates/react-nest-shadcn/web/pnpm-lock.yaml +1788 -0
  484. package/templates/react-nest-shadcn/web/src/App.tsx +30 -0
  485. package/templates/react-nest-shadcn/web/src/design-layout.css +7 -0
  486. package/templates/react-nest-shadcn/web/src/design-runtime.json +511 -0
  487. package/templates/react-nest-shadcn/web/src/design-tokens.css +168 -0
  488. package/templates/react-nest-shadcn/web/src/design-widgets.css +31 -0
  489. package/templates/react-nest-shadcn/web/src/main.tsx +6 -0
  490. package/templates/react-nest-shadcn/web/src/structure-view.tsx +16 -0
  491. package/templates/react-nest-shadcn/web/src/styles.css +3 -0
  492. package/templates/react-nest-shadcn/web/src/tailwind.css +2 -0
  493. package/templates/react-nest-shadcn/web/src/ui.tsx +13 -0
  494. package/templates/react-nest-shadcn/web/src/widget-icon.tsx +5 -0
  495. package/templates/react-nest-shadcn/web/src/widget-types.ts +13 -0
  496. package/templates/react-nest-shadcn/web/src/workspace-model.ts +85 -0
  497. package/templates/react-nest-shadcn/web/tsconfig.json +22 -0
  498. package/templates/react-nest-shadcn/web/vite.config.ts +4 -0
  499. package/templates/react-spring-antd/.agents/skills/design-contract/SKILL.md +23 -0
  500. package/templates/react-spring-antd/.agents/skills/project-work/SKILL.md +8 -0
  501. package/templates/react-spring-antd/.claude/skills/design-contract/SKILL.md +23 -0
  502. package/templates/react-spring-antd/.claude/skills/project-work/SKILL.md +8 -0
  503. package/templates/react-spring-antd/.dockerignore +18 -0
  504. package/templates/react-spring-antd/.env.example +13 -0
  505. package/templates/react-spring-antd/.grok/skills/design-contract/SKILL.md +23 -0
  506. package/templates/react-spring-antd/.grok/skills/project-work/SKILL.md +8 -0
  507. package/templates/react-spring-antd/.scaffold-checks.json +7 -0
  508. package/templates/react-spring-antd/AGENTS.md +11 -0
  509. package/templates/react-spring-antd/CLAUDE.md +1 -0
  510. package/templates/react-spring-antd/DESIGN.md +208 -0
  511. package/templates/react-spring-antd/LICENSE +21 -0
  512. package/templates/react-spring-antd/README.md +55 -0
  513. package/templates/react-spring-antd/THIRD_PARTY_NOTICES.md +14 -0
  514. package/templates/react-spring-antd/backend/.mvn/wrapper/maven-wrapper.properties +3 -0
  515. package/templates/react-spring-antd/backend/Dockerfile +11 -0
  516. package/templates/react-spring-antd/backend/mvnw +295 -0
  517. package/templates/react-spring-antd/backend/pom.xml +15 -0
  518. package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Api.java +38 -0
  519. package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/AppUser.java +11 -0
  520. package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Application.java +7 -0
  521. package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Errors.java +13 -0
  522. package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/PersonalRecord.java +15 -0
  523. package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Records.java +14 -0
  524. package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Security.java +28 -0
  525. package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Seed.java +13 -0
  526. package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Users.java +5 -0
  527. package/templates/react-spring-antd/backend/src/main/resources/application.properties +17 -0
  528. package/templates/react-spring-antd/backend/src/main/resources/db/migration/V1__initial.sql +3 -0
  529. package/templates/react-spring-antd/backend/src/main/resources/openapi.json +439 -0
  530. package/templates/react-spring-antd/backend/src/test/java/dev/scaffold/app/ApiTest.java +28 -0
  531. package/templates/react-spring-antd/backend/src/test/java/dev/scaffold/app/SessionExpiryTest.java +37 -0
  532. package/templates/react-spring-antd/compose.yaml +18 -0
  533. package/templates/react-spring-antd/design/guide.md +61 -0
  534. package/templates/react-spring-antd/design/layout.css +6 -0
  535. package/templates/react-spring-antd/design/structure.json +107 -0
  536. package/templates/react-spring-antd/design/tokens.json +171 -0
  537. package/templates/react-spring-antd/design/widgets.css +30 -0
  538. package/templates/react-spring-antd/design/widgets.json +233 -0
  539. package/templates/react-spring-antd/docs/PROJECT.md +9 -0
  540. package/templates/react-spring-antd/docs/api.d.ts +516 -0
  541. package/templates/react-spring-antd/docs/openapi.json +439 -0
  542. package/templates/react-spring-antd/gitignore.template +19 -0
  543. package/templates/react-spring-antd/licenses/fastapi.txt +21 -0
  544. package/templates/react-spring-antd/licenses/nest.txt +22 -0
  545. package/templates/react-spring-antd/licenses/next.txt +21 -0
  546. package/templates/react-spring-antd/licenses/shadcn.txt +21 -0
  547. package/templates/react-spring-antd/licenses/sources.json +27 -0
  548. package/templates/react-spring-antd/licenses/spring.txt +202 -0
  549. package/templates/react-spring-antd/package-lock.json +440 -0
  550. package/templates/react-spring-antd/package.json +21 -0
  551. package/templates/react-spring-antd/playwright.config.ts +3 -0
  552. package/templates/react-spring-antd/project.json +8 -0
  553. package/templates/react-spring-antd/scripts/design-coverage.mjs +20 -0
  554. package/templates/react-spring-antd/scripts/design-next-cleanup.mjs +13 -0
  555. package/templates/react-spring-antd/scripts/design-verify.mjs +154 -0
  556. package/templates/react-spring-antd/scripts/design.mjs +108 -0
  557. package/templates/react-spring-antd/scripts/project.mjs +118 -0
  558. package/templates/react-spring-antd/tests/contract.spec.ts +47 -0
  559. package/templates/react-spring-antd/tests/design/harness.tsx +63 -0
  560. package/templates/react-spring-antd/tests/ui.spec.ts +61 -0
  561. package/templates/react-spring-antd/web/eslint.config.mjs +3 -0
  562. package/templates/react-spring-antd/web/index.html +1 -0
  563. package/templates/react-spring-antd/web/package.json +28 -0
  564. package/templates/react-spring-antd/web/pnpm-lock.yaml +2215 -0
  565. package/templates/react-spring-antd/web/src/App.tsx +29 -0
  566. package/templates/react-spring-antd/web/src/design-layout.css +7 -0
  567. package/templates/react-spring-antd/web/src/design-runtime.json +511 -0
  568. package/templates/react-spring-antd/web/src/design-tokens.css +168 -0
  569. package/templates/react-spring-antd/web/src/design-widgets.css +31 -0
  570. package/templates/react-spring-antd/web/src/main.tsx +6 -0
  571. package/templates/react-spring-antd/web/src/structure-view.tsx +16 -0
  572. package/templates/react-spring-antd/web/src/styles.css +3 -0
  573. package/templates/react-spring-antd/web/src/ui.tsx +30 -0
  574. package/templates/react-spring-antd/web/src/widget-icon.tsx +5 -0
  575. package/templates/react-spring-antd/web/src/widget-types.ts +13 -0
  576. package/templates/react-spring-antd/web/src/workspace-model.ts +85 -0
  577. package/templates/react-spring-antd/web/tsconfig.json +22 -0
  578. package/templates/react-spring-antd/web/vite.config.ts +3 -0
  579. package/templates/react-spring-shadcn/.agents/skills/design-contract/SKILL.md +23 -0
  580. package/templates/react-spring-shadcn/.agents/skills/project-work/SKILL.md +8 -0
  581. package/templates/react-spring-shadcn/.claude/skills/design-contract/SKILL.md +23 -0
  582. package/templates/react-spring-shadcn/.claude/skills/project-work/SKILL.md +8 -0
  583. package/templates/react-spring-shadcn/.dockerignore +18 -0
  584. package/templates/react-spring-shadcn/.env.example +13 -0
  585. package/templates/react-spring-shadcn/.grok/skills/design-contract/SKILL.md +23 -0
  586. package/templates/react-spring-shadcn/.grok/skills/project-work/SKILL.md +8 -0
  587. package/templates/react-spring-shadcn/.scaffold-checks.json +7 -0
  588. package/templates/react-spring-shadcn/AGENTS.md +11 -0
  589. package/templates/react-spring-shadcn/CLAUDE.md +1 -0
  590. package/templates/react-spring-shadcn/DESIGN.md +208 -0
  591. package/templates/react-spring-shadcn/LICENSE +21 -0
  592. package/templates/react-spring-shadcn/README.md +55 -0
  593. package/templates/react-spring-shadcn/THIRD_PARTY_NOTICES.md +14 -0
  594. package/templates/react-spring-shadcn/backend/.mvn/wrapper/maven-wrapper.properties +3 -0
  595. package/templates/react-spring-shadcn/backend/Dockerfile +11 -0
  596. package/templates/react-spring-shadcn/backend/mvnw +295 -0
  597. package/templates/react-spring-shadcn/backend/pom.xml +15 -0
  598. package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Api.java +38 -0
  599. package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/AppUser.java +11 -0
  600. package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Application.java +7 -0
  601. package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Errors.java +13 -0
  602. package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/PersonalRecord.java +15 -0
  603. package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Records.java +14 -0
  604. package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Security.java +28 -0
  605. package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Seed.java +13 -0
  606. package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Users.java +5 -0
  607. package/templates/react-spring-shadcn/backend/src/main/resources/application.properties +17 -0
  608. package/templates/react-spring-shadcn/backend/src/main/resources/db/migration/V1__initial.sql +3 -0
  609. package/templates/react-spring-shadcn/backend/src/main/resources/openapi.json +439 -0
  610. package/templates/react-spring-shadcn/backend/src/test/java/dev/scaffold/app/ApiTest.java +28 -0
  611. package/templates/react-spring-shadcn/backend/src/test/java/dev/scaffold/app/SessionExpiryTest.java +37 -0
  612. package/templates/react-spring-shadcn/compose.yaml +18 -0
  613. package/templates/react-spring-shadcn/design/guide.md +61 -0
  614. package/templates/react-spring-shadcn/design/layout.css +6 -0
  615. package/templates/react-spring-shadcn/design/structure.json +107 -0
  616. package/templates/react-spring-shadcn/design/tokens.json +171 -0
  617. package/templates/react-spring-shadcn/design/widgets.css +30 -0
  618. package/templates/react-spring-shadcn/design/widgets.json +233 -0
  619. package/templates/react-spring-shadcn/docs/PROJECT.md +9 -0
  620. package/templates/react-spring-shadcn/docs/api.d.ts +516 -0
  621. package/templates/react-spring-shadcn/docs/openapi.json +439 -0
  622. package/templates/react-spring-shadcn/gitignore.template +19 -0
  623. package/templates/react-spring-shadcn/licenses/fastapi.txt +21 -0
  624. package/templates/react-spring-shadcn/licenses/nest.txt +22 -0
  625. package/templates/react-spring-shadcn/licenses/next.txt +21 -0
  626. package/templates/react-spring-shadcn/licenses/shadcn.txt +21 -0
  627. package/templates/react-spring-shadcn/licenses/sources.json +27 -0
  628. package/templates/react-spring-shadcn/licenses/spring.txt +202 -0
  629. package/templates/react-spring-shadcn/package-lock.json +440 -0
  630. package/templates/react-spring-shadcn/package.json +21 -0
  631. package/templates/react-spring-shadcn/playwright.config.ts +3 -0
  632. package/templates/react-spring-shadcn/project.json +8 -0
  633. package/templates/react-spring-shadcn/scripts/design-coverage.mjs +20 -0
  634. package/templates/react-spring-shadcn/scripts/design-next-cleanup.mjs +13 -0
  635. package/templates/react-spring-shadcn/scripts/design-verify.mjs +154 -0
  636. package/templates/react-spring-shadcn/scripts/design.mjs +108 -0
  637. package/templates/react-spring-shadcn/scripts/project.mjs +118 -0
  638. package/templates/react-spring-shadcn/tests/contract.spec.ts +47 -0
  639. package/templates/react-spring-shadcn/tests/design/harness.tsx +63 -0
  640. package/templates/react-spring-shadcn/tests/ui.spec.ts +61 -0
  641. package/templates/react-spring-shadcn/web/eslint.config.mjs +3 -0
  642. package/templates/react-spring-shadcn/web/index.html +1 -0
  643. package/templates/react-spring-shadcn/web/package.json +33 -0
  644. package/templates/react-spring-shadcn/web/pnpm-lock.yaml +1788 -0
  645. package/templates/react-spring-shadcn/web/src/App.tsx +30 -0
  646. package/templates/react-spring-shadcn/web/src/design-layout.css +7 -0
  647. package/templates/react-spring-shadcn/web/src/design-runtime.json +511 -0
  648. package/templates/react-spring-shadcn/web/src/design-tokens.css +168 -0
  649. package/templates/react-spring-shadcn/web/src/design-widgets.css +31 -0
  650. package/templates/react-spring-shadcn/web/src/main.tsx +6 -0
  651. package/templates/react-spring-shadcn/web/src/structure-view.tsx +16 -0
  652. package/templates/react-spring-shadcn/web/src/styles.css +3 -0
  653. package/templates/react-spring-shadcn/web/src/tailwind.css +2 -0
  654. package/templates/react-spring-shadcn/web/src/ui.tsx +13 -0
  655. package/templates/react-spring-shadcn/web/src/widget-icon.tsx +5 -0
  656. package/templates/react-spring-shadcn/web/src/widget-types.ts +13 -0
  657. package/templates/react-spring-shadcn/web/src/workspace-model.ts +85 -0
  658. package/templates/react-spring-shadcn/web/tsconfig.json +22 -0
  659. package/templates/react-spring-shadcn/web/vite.config.ts +4 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 qinchaomeishenmeshi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,72 @@
1
- # Temporary Holding Version
1
+ # Agent Scaffold
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 面向 Codex、Claude Code、Grok Build 的项目脚手架。四套技术栈(React + FastAPI、React + Spring Boot、React + NestJS、Next.js)各支持 shadcn/ui 和 Ant Design,共八个组合。生成应用包含登录和个人记录 CRUD,默认不含 AI。
4
+
5
+ ## 本地使用
6
+
7
+ 需要 Node.js 24:
8
+
9
+ ```bash
10
+ npx @cherishxn/agent-scaffold@latest init
11
+ ```
12
+
13
+ 交互创建收集中文名称、英文名称、简介、技术栈和 UI;确认前不写项目文件。也可创建 `spec.json`:
14
+
15
+ ```json
16
+ {"schemaVersion":1,"nameZh":"客户服务平台","nameEn":"customer-service","description":"客户资料和服务记录管理","template":"react-fastapi","ui":"shadcn"}
17
+ ```
18
+
19
+ ```bash
20
+ npx @cherishxn/agent-scaffold@latest templates --json
21
+ npx @cherishxn/agent-scaffold@latest init --help --json
22
+ npx @cherishxn/agent-scaffold@latest plan --spec spec.json --out plan.json --json
23
+ npx @cherishxn/agent-scaffold@latest init --plan plan.json --json
24
+ ```
25
+
26
+ 也可直接 `init --spec spec.json --json`。命令返回安装步骤和工作目录,不自动安装依赖或启动服务。进入生成目录后:
27
+
28
+ ```bash
29
+ npm run setup
30
+ npm run dev
31
+ ```
32
+
33
+ 开发账号与随机密码写入被 Git 忽略的 `.scaffold-local-credentials`。FastAPI 需要 Python 3.12、uv、Bun;Spring 需要 Java 17 和 pnpm;Nest/Next 需要 pnpm。数据库使用 Docker。具体版本锁定在模板中。
34
+
35
+ ## 检查与报告
36
+
37
+ ```bash
38
+ npx @cherishxn/agent-scaffold@latest doctor --dir . --json
39
+ npx @cherishxn/agent-scaffold@latest verify --dir . --json
40
+ npx @cherishxn/agent-scaffold@latest report --dir . --json
41
+ ```
42
+
43
+ verify 启动独立 PostgreSQL,运行类型、Lint、构建、迁移、种子数据、原生测试、API 和浏览器测试,并清理本次容器。不会使用开发环境的数据库连接。结果保存于 `.scaffold-runs`,包含内容摘要和原生报告引用;代码变化后 report 标记 STALE。失败、空测试、缺前置与中断不会标为 PASS。生成项目的 verify 会执行该项目脚本,仅对自己信任的项目运行。
44
+
45
+ ## 视觉设计
46
+
47
+ 八组合默认使用从 [CleerScience](https://cleerscience.com/) 提炼的深色科技视觉:近黑蓝底、冷白文字、冰蓝强调与直角面板。可独立复用的 [通用 DESIGN.md](docs/reference/CLEERSCIENCE-DESIGN.md) 区分官网实测与产品适配;生成项目的根 DESIGN.md 是当前 UI 的实际规范。
48
+
49
+ 设计采用四层分离:共享 `design/` 规范、语义 Widget 契约、组件库适配层、独立业务模型。`design:sync` 生成 DESIGN.md、CSS 和运行时规范;`design:check` 检测漂移;`design:verify` 验证全部组件状态及页面在桌面/移动端的几何、颜色、圆角和图标。位置容差 0.6px,其余指定属性严格相等。生成项目内置三宿主可发现的 `design-contract` Skill。根目录 `npm run design:verify` 运行全部八种组合并比较跨模板测量;单个生成项目仅验证已选适配器。
50
+
51
+ ## Agent 入口
52
+
53
+ 打包后的 CLI 包含 `skills/scaffold-use/SKILL.md`。按当前宿主约定,把该目录复制到发起创建的工作目录:Codex 使用 `.agents/skills/scaffold-use`,Claude Code 使用 `.claude/skills/scaffold-use`,Grok Build 使用 `.grok/skills/scaffold-use`。这一步由使用者或已获授权的 Agent 执行;CLI 不改全局配置。
54
+
55
+ 生成项目自带 AGENTS.md、薄 CLAUDE.md,以及上述三个原生目录下同源的 project-work Skill。切换到新工程后核对规则与 Skill 是否加载。具体宿主兼容范围以交付记录为准。
56
+
57
+ ## 开发与分发
58
+
59
+ ```bash
60
+ npm run check
61
+ npm run test:interactive
62
+ npm run test:package
63
+ npm run test:onboarding
64
+ npm run matrix
65
+ npm pack
66
+ ```
67
+
68
+ 源码仓库保持私有,CLI 按发布白名单分发至 npm 公共包。`npm pack` 构建包含八套模板与锁文件的本地安装包。模板源码位于 template-src;templates 是可重新生成的产物。更新依赖后运行 scripts/lock-templates.mjs 并重新验证受影响矩阵。
69
+
70
+ [开发计划](docs/DEVELOPMENT-PLAN.md) · [验证记录](docs/VERIFICATION.md) · [设计基线 v0.5](docs/reference/AGENT-SCAFFOLD-DESIGN-v0.5.md) · [来源与许可证](THIRD_PARTY_NOTICES.md)
71
+
72
+ 运行测试通过不代表生产部署或产品/PM 业务验收完成。
@@ -0,0 +1,14 @@
1
+ # Template sources and licenses
2
+
3
+ Templates are maintained derivatives, not unmodified upstream distributions. Exact bundled files are hashed in templates/catalog.json; npm/uv/pnpm/Bun locks pin dependency resolution. Initialization is offline and never invokes upstream generators.
4
+
5
+ | Source | Fixed reference | Use / modifications | License |
6
+ | --- | --- | --- | --- |
7
+ | fastapi/full-stack-fastapi-template | b1125d8839482cb7bbae603ddc6d0081bf87532e | SQLModel/Alembic/JWT/pwdlib foundation; reduced accounts, replaced sample feature with owner-scoped records, retained Bun frontend | MIT, licenses/fastapi.txt |
8
+ | nestjs/typescript-starter | a122dea65cd0610ee205d7765ed46f9d73629141 | Nest module/bootstrap foundation; added Prisma, JWT/Guard, Jest/Supertest; no deployment tooling | MIT, licenses/nest.txt |
9
+ | Spring Initializr | starter.zip fetched 2026-10-19; Maven Wrapper and Java layout | Generator returned unresolved 4.1.1.RELEASE; parent adjusted to stable Maven Central 3.5.16, Session/JPA/Flyway/CRUD added | Apache-2.0 wrapper, licenses/spring.txt |
10
+ | create-next-app | npm 16.4.2 | Official App Router/TypeScript baseline; Better Auth + Prisma + records; no remote fonts | MIT, licenses/next.txt |
11
+ | shadcn/ui | Button/Input pattern, pinned source reference in licenses/sources.json | Adapted local CVA/Slot controls with Tailwind; retained copy ownership | MIT, licenses/shadcn.txt |
12
+ | Ant Design | npm 6.6.6 | Installed dependency; no copied source | MIT (package license) |
13
+
14
+ Package dependencies carry their own licenses. Generated apps include these notices; template authors must carry applicable notices when changing upstream-derived files. Names and marks remain their respective owners'.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { createInterface } from 'node:readline/promises';
4
+ import { resolve, join } from 'node:path';
5
+ import { stdin, stdout } from 'node:process';
6
+ import { CLI_VERSION, ScaffoldError, templates, uis } from './model.js';
7
+ import { catalog, initialize, jsonFile, makePlan, validatePlan, writePlan, packageRoot } from './generate.js';
8
+ import { doctor, verify, report } from './verify.js';
9
+ const args = process.argv.slice(2);
10
+ const json = args.includes('--json');
11
+ let commandName = 'scaffold';
12
+ function output(data, nextActions = []) {
13
+ const payload = { schemaVersion: 1, command: commandName, status: 'success', data, errors: [], warnings: [], nextActions };
14
+ stdout.write(JSON.stringify(payload, null, json ? undefined : 2) + '\n');
15
+ }
16
+ async function interactive() {
17
+ const r = createInterface({ input: stdin, output: stdout });
18
+ const abort = new AbortController();
19
+ let interrupted = false;
20
+ const stop = () => { interrupted = true; abort.abort(); r.close(); };
21
+ r.on('SIGINT', stop);
22
+ process.once('SIGINT', stop);
23
+ const ask = (prompt) => r.question(prompt, { signal: abort.signal });
24
+ try {
25
+ const nameZh = await ask('项目中文名称:');
26
+ const nameEn = await ask('项目英文名称(小写字母、数字、连字符):');
27
+ const description = await ask('项目简介:');
28
+ const templateAnswer = (await ask('技术栈 1 FastAPI / 2 Spring / 3 Nest / 4 Next [1]:')).trim() || '1';
29
+ const uiAnswer = (await ask('UI 1 shadcn/ui / 2 Ant Design [1]:')).trim() || '1';
30
+ const template = templates[Number(templateAnswer) - 1] ?? templateAnswer;
31
+ const ui = uis[Number(uiAnswer) - 1] ?? uiAnswer;
32
+ const input = { schemaVersion: 1, nameZh, nameEn, description, template, ui };
33
+ const plan = await makePlan(input);
34
+ const dir = (await ask(`创建目录 [./${plan.normalizedSpec.nameEn}]:`)).trim() || `./${plan.normalizedSpec.nameEn}`;
35
+ stdout.write(JSON.stringify({ project: plan.normalizedSpec, directory: resolve(dir), files: plan.files.length }, null, 2) + '\n');
36
+ const yes = (await ask('确认创建?[y/N]:')).trim().toLowerCase();
37
+ if (!['y', 'yes', '是'].includes(yes))
38
+ throw new ScaffoldError('CANCELLED', 'Creation cancelled; no project files were written.', 130);
39
+ return { spec: plan.normalizedSpec, dir };
40
+ }
41
+ catch (error) {
42
+ if (interrupted)
43
+ throw new ScaffoldError('CANCELLED', 'Creation interrupted; no project files were written.', 130);
44
+ throw error;
45
+ }
46
+ finally {
47
+ process.removeListener('SIGINT', stop);
48
+ r.close();
49
+ }
50
+ }
51
+ const program = new Command().name('scaffold').version(CLI_VERSION).description('Create and verify complete web projects.').option('--json', 'Non-interactive JSON output').exitOverride().configureOutput({ writeOut: s => process.stdout.write(s), writeErr: s => process.stderr.write(s) });
52
+ program.command('templates').description('List bundled templates and input schema').action(async () => { commandName = 'templates'; output(await catalog()); });
53
+ program.command('plan').description('Validate spec and write a new deterministic plan').requiredOption('--spec <file>').requiredOption('--out <file>').action(async (o) => { commandName = 'plan'; output(await writePlan(await jsonFile(o.spec), o.out)); });
54
+ program.command('init').description('Create a project interactively, from JSON spec, or from a plan').option('--spec <file>').option('--plan <file>').option('--dir <path>').action(async (o) => {
55
+ commandName = 'init';
56
+ if (o.spec && o.plan)
57
+ throw new ScaffoldError('MODE_CONFLICT', '--spec and --plan are mutually exclusive.');
58
+ let plan;
59
+ if (o.plan)
60
+ plan = await validatePlan(await jsonFile(o.plan));
61
+ else if (o.spec)
62
+ plan = await makePlan(await jsonFile(o.spec));
63
+ else {
64
+ if (json || !stdin.isTTY || !stdout.isTTY)
65
+ throw new ScaffoldError('MISSING_INPUT', 'Provide --spec or --plan in non-interactive mode.');
66
+ const i = await interactive();
67
+ plan = await makePlan(i.spec);
68
+ o.dir = o.dir ?? i.dir;
69
+ }
70
+ const result = await initialize(plan, o.dir ?? plan.normalizedSpec.nameEn);
71
+ output(result, result.nextActions);
72
+ });
73
+ program.command('doctor').description('Read-only local prerequisite checks').requiredOption('--dir <path>').action(async (o) => { commandName = 'doctor'; const r = await doctor(o.dir); output(r); process.exitCode = r.ok ? 0 : 3; });
74
+ program.command('verify').description('Run isolated baseline checks').requiredOption('--dir <path>').option('--profile <name>', 'Check profile', 'baseline').action(async (o) => { commandName = 'verify'; if (o.profile !== 'baseline')
75
+ throw new ScaffoldError('INVALID_PROFILE', 'Only baseline is supported.'); const r = await verify(o.dir); output(r); process.exitCode = r.exitCode; });
76
+ program.command('report').description('Read latest results and current content validity').requiredOption('--dir <path>').action(async (o) => { commandName = 'report'; output(await report(o.dir)); });
77
+ try {
78
+ if (json && (args.includes('--help') || args.includes('-h'))) {
79
+ const name = args.find(a => !a.startsWith('-'));
80
+ const c = name ? program.commands.find(c => c.name() === name) : program;
81
+ if (!c)
82
+ throw new ScaffoldError('UNKNOWN_COMMAND', 'Unknown command.');
83
+ commandName = 'help';
84
+ output({ version: CLI_VERSION, name: c.name(), description: c.description(), options: c.options.map(o => ({ flags: o.flags, description: o.description, required: o.mandatory })), commands: program.commands.map(c => ({ name: c.name(), description: c.description() })), schemas: ['spec', 'plan', 'manifest', 'result'].map(s => join(packageRoot, `schemas/${s}.json`)), exitCodes: { 0: 'command succeeded; inspect overallStatus for report', 2: 'invalid input', 3: 'environment or incomplete checks', 4: 'failed checks', 5: 'internal error', 130: 'interrupted' }, sideEffects: { templates: [], plan: ['write new plan'], init: ['write new project'], doctor: [], verify: ['build, isolated database, reports'], report: [] }, prerequisites: ['Node.js 24', 'See templates for stack-specific runtimes'] });
85
+ }
86
+ else if (args.length === 0)
87
+ program.help();
88
+ else
89
+ await program.parseAsync(process.argv);
90
+ }
91
+ catch (e) {
92
+ const c = e;
93
+ if (c.code === 'commander.helpDisplayed' || c.code === 'commander.version')
94
+ process.exitCode = 0;
95
+ else {
96
+ const error = e instanceof ScaffoldError ? e : new ScaffoldError(c.code?.startsWith('commander.') ? 'ARGUMENT_ERROR' : 'INTERNAL_ERROR', c.code?.startsWith('commander.') ? 'Invalid command arguments. See --help.' : 'Operation failed; no successful result was recorded.', c.code?.startsWith('commander.') ? 2 : 5);
97
+ stdout.write(JSON.stringify({ schemaVersion: 1, command: commandName, status: 'error', data: null, errors: [error.issue()], warnings: [], nextActions: [] }) + '\n');
98
+ process.exitCode = error.exitCode;
99
+ }
100
+ }
@@ -0,0 +1,55 @@
1
+ import { type Spec, type Action } from './model.js';
2
+ export declare const packageRoot: string;
3
+ export type FileEntry = {
4
+ path: string;
5
+ source: string;
6
+ digest: string;
7
+ mode: number;
8
+ };
9
+ export type Plan = {
10
+ schemaVersion: 1;
11
+ cliVersion: string;
12
+ templateId: string;
13
+ templateVersion: string;
14
+ templateDigest: string;
15
+ normalizedSpec: Spec;
16
+ files: FileEntry[];
17
+ nextActions: Action[];
18
+ planDigest: string;
19
+ };
20
+ export declare function jsonFile(path: string): Promise<unknown>;
21
+ export declare function specFrom(input: unknown): Promise<Spec>;
22
+ export declare function walk(root: string, prefix?: string): Promise<string[]>;
23
+ export declare function makePlan(input: unknown): Promise<Plan>;
24
+ export declare function validatePlan(input: unknown): Promise<Plan>;
25
+ export declare function writePlan(input: unknown, output: string): Promise<Plan>;
26
+ export declare function initialize(plan: Plan, target: string): Promise<{
27
+ directory: string;
28
+ status: string;
29
+ nextActions: {
30
+ cwd: string;
31
+ program: string;
32
+ args: string[];
33
+ prerequisites: string[];
34
+ sideEffects: string[];
35
+ }[];
36
+ }>;
37
+ export declare function catalog(): Promise<{
38
+ version: string;
39
+ templates: {
40
+ id: "react-fastapi" | "react-spring" | "react-nest" | "next-fullstack";
41
+ uis: ("shadcn" | "antd")[];
42
+ node: string;
43
+ database: string;
44
+ requirements: string[];
45
+ }[];
46
+ specSchema: string;
47
+ example: {
48
+ schemaVersion: number;
49
+ nameZh: string;
50
+ nameEn: string;
51
+ description: string;
52
+ template: string;
53
+ ui: string;
54
+ };
55
+ }>;
@@ -0,0 +1,154 @@
1
+ import { readFile, readdir, lstat, mkdir, writeFile, access } from 'node:fs/promises';
2
+ import { join, resolve, dirname, relative, isAbsolute, sep } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { Ajv } from 'ajv';
5
+ import { canonical, digest, ScaffoldError, CLI_VERSION, templates, uis } from './model.js';
6
+ export const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
7
+ export async function jsonFile(path) {
8
+ try {
9
+ return JSON.parse(await readFile(path, 'utf8'));
10
+ }
11
+ catch {
12
+ throw new ScaffoldError('INVALID_JSON', 'Cannot read a valid JSON file.', 2, path);
13
+ }
14
+ }
15
+ export async function specFrom(input) {
16
+ const schema = await jsonFile(join(packageRoot, 'schemas/spec.json'));
17
+ const ajv = new Ajv({ allErrors: true });
18
+ const validate = ajv.compile(schema);
19
+ const normalized = input && typeof input === 'object' && !Array.isArray(input) ? Object.fromEntries(Object.entries(input).map(([k, v]) => [k, typeof v === 'string' ? v.trim() : v])) : input;
20
+ if (!validate(normalized)) {
21
+ const e = validate.errors?.[0];
22
+ throw new ScaffoldError('INVALID_SPEC', e?.message ?? 'Invalid project specification.', 2, e?.instancePath || String(e?.params.missingProperty ?? 'spec'));
23
+ }
24
+ return normalized;
25
+ }
26
+ export async function walk(root, prefix = '') {
27
+ const out = [];
28
+ for (const entry of await readdir(join(root, prefix), { withFileTypes: true })) {
29
+ const name = prefix ? `${prefix}/${entry.name}` : entry.name;
30
+ if (entry.isSymbolicLink())
31
+ throw new ScaffoldError('SYMLINK', 'Symbolic links are not allowed in template/output files.', 2, name);
32
+ if (entry.isDirectory())
33
+ out.push(...await walk(root, name));
34
+ else if (entry.isFile())
35
+ out.push(name);
36
+ else
37
+ throw new ScaffoldError('FILE_TYPE', 'Unsupported file type.', 2, name);
38
+ }
39
+ return out.sort();
40
+ }
41
+ async function render(spec) {
42
+ const dir = join(packageRoot, 'templates', `${spec.template}-${spec.ui}`);
43
+ const catalog = await jsonFile(join(packageRoot, 'templates/catalog.json'));
44
+ const names = await walk(dir);
45
+ const source = await Promise.all(names.map(async (path) => ({ path, bytes: await readFile(join(dir, path)), mode: ((await lstat(join(dir, path))).mode & 0o111) ? 0o755 : 0o644 })));
46
+ const sourceDigest = digest(canonical(source.map(x => ({ path: x.path, digest: digest(x.bytes), mode: x.mode }))));
47
+ if (catalog.entries[`${spec.template}-${spec.ui}`]?.digest !== sourceDigest)
48
+ throw new ScaffoldError('TEMPLATE_INTEGRITY', 'Bundled template does not match the published catalog.');
49
+ const contents = new Map(source.map(x => [x.path === 'gitignore.template' ? '.gitignore' : x.path, { content: Buffer.from(x.bytes.toString('utf8').replaceAll('__NAME_EN__', spec.nameEn)), source: x.path, mode: x.mode }]));
50
+ contents.set('project.json', { content: Buffer.from(JSON.stringify(spec, null, 2) + '\n'), source: 'generated:spec', mode: 0o644 });
51
+ const pkg = contents.get('package.json');
52
+ if (pkg) {
53
+ const metadata = JSON.parse(pkg.content.toString());
54
+ metadata.description = spec.description;
55
+ pkg.content = Buffer.from(JSON.stringify(metadata, null, 2) + '\n');
56
+ }
57
+ const readme = contents.get('README.md');
58
+ if (readme)
59
+ readme.content = Buffer.from(`# ${spec.nameZh}\n\n${spec.description}\n\n` + readme.content.toString());
60
+ const project = contents.get('docs/PROJECT.md');
61
+ if (project)
62
+ project.content = Buffer.from(`# ${spec.nameZh}\n\n工程标识:${spec.nameEn}\n\n${spec.description}\n\n` + project.content.toString());
63
+ return { contents, sourceDigest };
64
+ }
65
+ function actions() { return ['setup', 'dev'].map(task => ({ program: 'npm', args: ['run', task], cwd: '.', prerequisites: task === 'setup' ? ['Node.js 24, Docker and template runtimes'] : ['Setup completed'], sideEffects: task === 'setup' ? ['Download locked dependencies and execute their installation scripts', 'Create local development database and explicitly seed development users'] : ['Build and start local application processes'] })); }
66
+ export async function makePlan(input) {
67
+ const normalizedSpec = await specFrom(input);
68
+ const { contents, sourceDigest } = await render(normalizedSpec);
69
+ const base = { schemaVersion: 1, cliVersion: CLI_VERSION, templateId: normalizedSpec.template, templateVersion: CLI_VERSION, templateDigest: sourceDigest, normalizedSpec, files: [...contents].sort(([a], [b]) => a.localeCompare(b, 'en')).map(([path, f]) => ({ path, source: f.source, digest: digest(f.content), mode: f.mode })), nextActions: actions() };
70
+ return { ...base, planDigest: digest(canonical(base)) };
71
+ }
72
+ export async function validatePlan(input) {
73
+ if (!input || typeof input !== 'object' || !('normalizedSpec' in input))
74
+ throw new ScaffoldError('INVALID_PLAN', 'Plan must contain normalizedSpec.');
75
+ const expected = await makePlan(input.normalizedSpec);
76
+ if (canonical(input) !== canonical(expected))
77
+ throw new ScaffoldError('PLAN_MISMATCH', 'Plan does not match this CLI and bundled template. Generate a fresh plan.');
78
+ return expected;
79
+ }
80
+ export async function writePlan(input, output) {
81
+ const plan = await makePlan(input);
82
+ try {
83
+ await writeFile(output, JSON.stringify(plan, null, 2) + '\n', { flag: 'wx', mode: 0o644 });
84
+ }
85
+ catch {
86
+ throw new ScaffoldError('PLAN_OUTPUT', 'Cannot create plan; output must be a new writable file.', 2, output);
87
+ }
88
+ return plan;
89
+ }
90
+ async function rejectSymlinkAncestors(path) {
91
+ // /tmp and /var are OS aliases on macOS; resolve the caller-selected parent before checking children.
92
+ let cursor = resolve(path);
93
+ while (cursor !== dirname(cursor)) {
94
+ try {
95
+ if ((await lstat(cursor)).isSymbolicLink() && cursor !== '/tmp' && cursor !== '/var')
96
+ throw new ScaffoldError('SYMLINK', 'Target directory cannot traverse a symbolic link.', 2, cursor);
97
+ }
98
+ catch (e) {
99
+ if (e instanceof ScaffoldError)
100
+ throw e;
101
+ if (e.code !== 'ENOENT')
102
+ throw e;
103
+ }
104
+ cursor = dirname(cursor);
105
+ }
106
+ }
107
+ export async function initialize(plan, target) {
108
+ await validatePlan(plan);
109
+ const dir = resolve(target);
110
+ await rejectSymlinkAncestors(dir);
111
+ let existing = [];
112
+ try {
113
+ existing = await walk(dir);
114
+ }
115
+ catch (e) {
116
+ if (e.code !== 'ENOENT')
117
+ throw e;
118
+ }
119
+ const manifestPath = join(dir, '.scaffold-manifest.json');
120
+ if (existing.length) {
121
+ try {
122
+ const m = await jsonFile(manifestPath);
123
+ if (m.status === 'complete' && m.planDigest === plan.planDigest && existing.length === plan.files.length + 1) {
124
+ for (const f of plan.files) {
125
+ if (digest(await readFile(join(dir, f.path))) !== f.digest)
126
+ throw new Error('changed');
127
+ }
128
+ return { directory: dir, status: 'already_initialized', nextActions: plan.nextActions.map(a => ({ ...a, cwd: dir })) };
129
+ }
130
+ }
131
+ catch { /* Existing data is never overwritten. */ }
132
+ throw new ScaffoldError('DIRECTORY_CONFLICT', 'Target is non-empty or contains changed/incomplete output.', 2, dir);
133
+ }
134
+ await mkdir(dir, { recursive: true });
135
+ // Reject even empty user-created subdirectories, and concurrent writes before the first output.
136
+ if ((await readdir(dir)).length)
137
+ throw new ScaffoldError('DIRECTORY_CONFLICT', 'Target must be empty.', 2, dir);
138
+ const manifest = { status: 'generating', ...plan };
139
+ await writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\n', { flag: 'wx' });
140
+ const { contents } = await render(plan.normalizedSpec);
141
+ for (const [path, f] of contents) {
142
+ if (isAbsolute(path) || relative(dir, resolve(dir, path)).split(sep).includes('..'))
143
+ throw new ScaffoldError('PATH_ESCAPE', 'Output path escapes target.');
144
+ await mkdir(dirname(join(dir, path)), { recursive: true });
145
+ await rejectSymlinkAncestors(join(dir, path));
146
+ await writeFile(join(dir, path), f.content, { flag: 'wx', mode: f.mode });
147
+ }
148
+ await writeFile(manifestPath, JSON.stringify({ ...manifest, status: 'complete' }, null, 2) + '\n');
149
+ return { directory: dir, status: 'created', nextActions: plan.nextActions.map(a => ({ ...a, cwd: dir })) };
150
+ }
151
+ export async function catalog() {
152
+ await access(join(packageRoot, 'templates/catalog.json'));
153
+ return { version: CLI_VERSION, templates: templates.map(id => ({ id, uis: [...uis], node: '24.x', database: 'PostgreSQL 17', requirements: id === 'react-fastapi' ? ['uv', 'Python 3.12', 'Bun', 'Docker'] : id === 'react-spring' ? ['Java 17', 'Maven Wrapper', 'pnpm', 'Docker'] : ['pnpm', 'Docker'] })), specSchema: join(packageRoot, 'schemas/spec.json'), example: { schemaVersion: 1, nameZh: '客户服务平台', nameEn: 'customer-service', description: '客户资料和服务记录管理', template: 'react-fastapi', ui: 'shadcn' } };
154
+ }
@@ -0,0 +1,33 @@
1
+ export declare const templates: readonly ["react-fastapi", "react-spring", "react-nest", "next-fullstack"];
2
+ export declare const uis: readonly ["shadcn", "antd"];
3
+ export type Spec = {
4
+ schemaVersion: 1;
5
+ nameZh: string;
6
+ nameEn: string;
7
+ description: string;
8
+ template: typeof templates[number];
9
+ ui: typeof uis[number];
10
+ };
11
+ export type Action = {
12
+ program: string;
13
+ args: string[];
14
+ cwd: string;
15
+ prerequisites: string[];
16
+ sideEffects: string[];
17
+ };
18
+ export type Issue = {
19
+ code: string;
20
+ message: string;
21
+ field?: string;
22
+ retryable: boolean;
23
+ };
24
+ export declare class ScaffoldError extends Error {
25
+ code: string;
26
+ exitCode: number;
27
+ field?: string | undefined;
28
+ constructor(code: string, message: string, exitCode?: number, field?: string | undefined);
29
+ issue(): Issue;
30
+ }
31
+ export declare function canonical(value: unknown): string;
32
+ export declare function digest(value: string | Buffer): string;
33
+ export declare const CLI_VERSION = "1.0.0";
package/dist/model.js ADDED
@@ -0,0 +1,24 @@
1
+ import { createHash } from 'node:crypto';
2
+ export const templates = ['react-fastapi', 'react-spring', 'react-nest', 'next-fullstack'];
3
+ export const uis = ['shadcn', 'antd'];
4
+ export class ScaffoldError extends Error {
5
+ code;
6
+ exitCode;
7
+ field;
8
+ constructor(code, message, exitCode = 2, field) {
9
+ super(message);
10
+ this.code = code;
11
+ this.exitCode = exitCode;
12
+ this.field = field;
13
+ }
14
+ issue() { return { code: this.code, message: this.message, ...(this.field ? { field: this.field } : {}), retryable: false }; }
15
+ }
16
+ export function canonical(value) {
17
+ if (Array.isArray(value))
18
+ return '[' + value.map(canonical).join(',') + ']';
19
+ if (value !== null && typeof value === 'object')
20
+ return '{' + Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, v]) => JSON.stringify(k) + ':' + canonical(v)).join(',') + '}';
21
+ return JSON.stringify(value);
22
+ }
23
+ export function digest(value) { return createHash('sha256').update(value).digest('hex'); }
24
+ export const CLI_VERSION = '1.0.0';
@@ -0,0 +1,61 @@
1
+ type Check = {
2
+ id: string;
3
+ status: 'PASS' | 'FAIL' | 'NOT RUN' | 'N/A';
4
+ reason: string;
5
+ startedAt: string;
6
+ finishedAt: string;
7
+ exitCode: number | null;
8
+ signal: string | null;
9
+ evidence: string[];
10
+ };
11
+ type Run = {
12
+ schemaVersion: 1;
13
+ runId: string;
14
+ template: string;
15
+ cliVersion: string;
16
+ platform: string;
17
+ runtime: string;
18
+ startedAt: string;
19
+ finishedAt: string;
20
+ beforeDigest: string;
21
+ afterDigest: string;
22
+ overallStatus: 'PASS' | 'FAIL' | 'NOT RUN';
23
+ validity: 'CURRENT' | 'STALE';
24
+ checks: Check[];
25
+ exitCode: number;
26
+ warnings: string[];
27
+ };
28
+ export declare function doctor(directory: string): Promise<{
29
+ ok: boolean;
30
+ checks: {
31
+ program: string;
32
+ ok: boolean;
33
+ version: string | undefined;
34
+ }[];
35
+ platform: string;
36
+ template: "react-fastapi" | "react-spring" | "react-nest" | "next-fullstack";
37
+ }>;
38
+ export declare function contentDigest(dir: string): Promise<string>;
39
+ export declare function verify(directory: string): Promise<Run>;
40
+ export declare function report(directory: string): Promise<{
41
+ overallStatus: string;
42
+ reason: string;
43
+ } | {
44
+ validity: string;
45
+ schemaVersion: 1;
46
+ runId: string;
47
+ template: string;
48
+ cliVersion: string;
49
+ platform: string;
50
+ runtime: string;
51
+ startedAt: string;
52
+ finishedAt: string;
53
+ beforeDigest: string;
54
+ afterDigest: string;
55
+ overallStatus: "PASS" | "FAIL" | "NOT RUN";
56
+ checks: Check[];
57
+ exitCode: number;
58
+ warnings: string[];
59
+ reason?: undefined;
60
+ }>;
61
+ export {};