@h-ai/cli 0.1.0-alpha9 → 1.0.0-beta.2

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 (438) hide show
  1. package/README.en.md +229 -0
  2. package/README.ja.md +229 -0
  3. package/README.md +175 -113
  4. package/dist/chunk-AKV2CQZV.js +1497 -0
  5. package/dist/chunk-AKV2CQZV.js.map +1 -0
  6. package/dist/chunk-EF7WOFWZ.js +7557 -0
  7. package/dist/chunk-EF7WOFWZ.js.map +1 -0
  8. package/dist/chunk-MUHRBJSW.js +29272 -0
  9. package/dist/chunk-MUHRBJSW.js.map +1 -0
  10. package/dist/chunk-ZSDEVXZ7.js +38 -0
  11. package/dist/{chunk-2H7UOFLK.js.map → chunk-ZSDEVXZ7.js.map} +1 -1
  12. package/dist/cli-config-templates-HHFHNXBN.js +5 -0
  13. package/dist/cli-config-templates-HHFHNXBN.js.map +1 -0
  14. package/dist/cli-skill-templates-PN4FLGBC.js +5 -0
  15. package/dist/cli-skill-templates-PN4FLGBC.js.map +1 -0
  16. package/dist/index.js +4444 -554
  17. package/dist/index.js.map +1 -1
  18. package/dist/metafile-esm.json +1 -0
  19. package/dist/src-TEBHR5I5.js +5 -0
  20. package/dist/src-TEBHR5I5.js.map +1 -0
  21. package/package.json +35 -15
  22. package/templates/README.md +56 -114
  23. package/templates/apps/admin/messages/en-US.json +7 -0
  24. package/templates/apps/admin/messages/ja-JP.json +40 -0
  25. package/templates/apps/admin/messages/zh-CN.json +7 -0
  26. package/templates/apps/admin/src/routes/+layout.svelte.hbs +65 -8
  27. package/templates/apps/admin/src/routes/+page.svelte.hbs +35 -14
  28. package/templates/apps/admin/src/routes/admin/+layout.svelte.hbs +54 -22
  29. package/templates/apps/admin/src/routes/admin/+page.svelte.hbs +33 -24
  30. package/templates/apps/admin/src/routes/admin/settings/+page.svelte.hbs +16 -13
  31. package/templates/apps/api/.dockerignore.hbs +25 -0
  32. package/templates/apps/api/.gitignore.hbs +22 -0
  33. package/templates/apps/api/.npmrc.hbs +1 -0
  34. package/templates/apps/api/apps/{{projectName}}-contract/README.md.hbs +39 -0
  35. package/templates/apps/api/apps/{{projectName}}-contract/package.json.hbs +41 -0
  36. package/templates/apps/api/apps/{{projectName}}-contract/src/app-contract.ts.hbs +27 -0
  37. package/templates/apps/api/apps/{{projectName}}-contract/src/app-schemas.ts.hbs +28 -0
  38. package/templates/apps/api/apps/{{projectName}}-contract/src/index.ts.hbs +5 -0
  39. package/templates/apps/api/apps/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +16 -0
  40. package/templates/apps/api/apps/{{projectName}}-contract/tests/contract.test.ts.hbs +18 -0
  41. package/templates/apps/api/apps/{{projectName}}-contract/tsconfig.json.hbs +12 -0
  42. package/templates/apps/api/apps/{{projectName}}-contract/tsup.config.ts.hbs +11 -0
  43. package/templates/apps/api/apps/{{projectName}}-contract/vitest.config.ts.hbs +9 -0
  44. package/templates/apps/api/apps/{{projectName}}-serv/README.md.hbs +60 -0
  45. package/templates/apps/api/apps/{{projectName}}-serv/config/_core.yml.hbs +17 -0
  46. package/templates/apps/api/apps/{{projectName}}-serv/config/_serv.yml.hbs +54 -0
  47. package/templates/apps/api/apps/{{projectName}}-serv/data/.gitkeep.hbs +1 -0
  48. package/templates/apps/api/apps/{{projectName}}-serv/package.json.hbs +66 -0
  49. package/templates/apps/api/apps/{{projectName}}-serv/src/app.ts.hbs +119 -0
  50. package/templates/apps/api/apps/{{projectName}}-serv/src/build-metadata.ts.hbs +7 -0
  51. package/templates/apps/api/apps/{{projectName}}-serv/src/index.ts.hbs +41 -0
  52. package/templates/apps/api/apps/{{projectName}}-serv/src/lib/server/init.ts.hbs +165 -0
  53. package/templates/apps/api/apps/{{projectName}}-serv/src/server/procedures/app-procedures.ts.hbs +57 -0
  54. package/templates/apps/api/apps/{{projectName}}-serv/src/server/procedures/index.ts.hbs +41 -0
  55. package/templates/apps/api/apps/{{projectName}}-serv/tests/service.test.ts.hbs +176 -0
  56. package/templates/apps/api/apps/{{projectName}}-serv/tsconfig.json.hbs +16 -0
  57. package/templates/apps/api/apps/{{projectName}}-serv/tsup.config.ts.hbs +20 -0
  58. package/templates/apps/api/apps/{{projectName}}-serv/vitest.config.ts.hbs +12 -0
  59. package/templates/apps/api/e2e/api-serv.spec.ts.hbs +113 -0
  60. package/templates/apps/api/e2e/capture-evidence.ts.hbs +23 -0
  61. package/templates/apps/api/eslint.config.js.hbs +30 -0
  62. package/templates/apps/api/hai.json.hbs +4 -0
  63. package/templates/apps/api/images/serv.Dockerfile.hbs +37 -0
  64. package/templates/apps/api/package.json.hbs +53 -0
  65. package/templates/apps/api/playwright.config.ts.hbs +67 -0
  66. package/templates/apps/api/pnpm-workspace.yaml.hbs +40 -0
  67. package/templates/apps/api/tsconfig.base.json +14 -0
  68. package/templates/apps/fullstack/.dockerignore.hbs +25 -0
  69. package/templates/apps/fullstack/.gitignore.hbs +38 -0
  70. package/templates/apps/fullstack/.npmrc.hbs +1 -0
  71. package/templates/apps/fullstack/apps/{{projectName}}-app/.env.example.hbs +10 -0
  72. package/templates/apps/fullstack/apps/{{projectName}}-app/README.md.hbs +67 -0
  73. package/templates/apps/fullstack/apps/{{projectName}}-app/capacitor.config.ts.hbs +20 -0
  74. package/templates/apps/fullstack/apps/{{projectName}}-app/eslint.config.js.hbs +20 -0
  75. package/templates/apps/fullstack/apps/{{projectName}}-app/index.html.hbs +22 -0
  76. package/templates/apps/fullstack/apps/{{projectName}}-app/messages/en-US.json.hbs +7 -0
  77. package/templates/apps/fullstack/apps/{{projectName}}-app/messages/ja-JP.json.hbs +7 -0
  78. package/templates/apps/fullstack/apps/{{projectName}}-app/messages/zh-CN.json.hbs +7 -0
  79. package/templates/apps/fullstack/apps/{{projectName}}-app/package.json.hbs +86 -0
  80. package/templates/apps/fullstack/apps/{{projectName}}-app/project.inlang/settings.json.hbs +17 -0
  81. package/templates/apps/fullstack/apps/{{projectName}}-app/public/runtime-config.js.hbs +4 -0
  82. package/templates/apps/fullstack/apps/{{projectName}}-app/src/App.svelte.hbs +59 -0
  83. package/templates/apps/fullstack/apps/{{projectName}}-app/src/app.css.hbs +20 -0
  84. package/templates/apps/fullstack/apps/{{projectName}}-app/src/app.d.ts.hbs +8 -0
  85. package/templates/apps/fullstack/apps/{{projectName}}-app/src/build-metadata.ts.hbs +9 -0
  86. package/templates/apps/fullstack/apps/{{projectName}}-app/src/lib/capacitor.ts.hbs +19 -0
  87. package/templates/apps/fullstack/apps/{{projectName}}-app/src/main.ts.hbs +21 -0
  88. package/templates/apps/fullstack/apps/{{projectName}}-app/svelte.config.js.hbs +16 -0
  89. package/templates/apps/fullstack/apps/{{projectName}}-app/tsconfig.json.hbs +23 -0
  90. package/templates/apps/fullstack/apps/{{projectName}}-app/vite.config.ts.hbs +74 -0
  91. package/templates/apps/fullstack/apps/{{projectName}}-desktop/.env.example.hbs +6 -0
  92. package/templates/apps/fullstack/apps/{{projectName}}-desktop/README.md.hbs +64 -0
  93. package/templates/apps/fullstack/apps/{{projectName}}-desktop/eslint.config.js.hbs +20 -0
  94. package/templates/apps/fullstack/apps/{{projectName}}-desktop/index.html.hbs +20 -0
  95. package/templates/apps/fullstack/apps/{{projectName}}-desktop/messages/en-US.json.hbs +7 -0
  96. package/templates/apps/fullstack/apps/{{projectName}}-desktop/messages/ja-JP.json.hbs +7 -0
  97. package/templates/apps/fullstack/apps/{{projectName}}-desktop/messages/zh-CN.json.hbs +7 -0
  98. package/templates/apps/fullstack/apps/{{projectName}}-desktop/package.json.hbs +66 -0
  99. package/templates/apps/fullstack/apps/{{projectName}}-desktop/project.inlang/settings.json.hbs +17 -0
  100. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/App.svelte.hbs +25 -0
  101. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/app.css.hbs +18 -0
  102. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/app.d.ts.hbs +8 -0
  103. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/build-metadata.ts.hbs +9 -0
  104. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/main.ts.hbs +20 -0
  105. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/Cargo.toml.hbs +33 -0
  106. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/build.rs.hbs +6 -0
  107. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/capabilities/default.json.hbs +16 -0
  108. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/128x128.png +0 -0
  109. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/128x128@2x.png +0 -0
  110. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/32x32.png +0 -0
  111. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/icon.icns +0 -0
  112. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/icon.ico +0 -0
  113. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/src/lib.rs.hbs +91 -0
  114. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/src/main.rs.hbs +8 -0
  115. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/tauri.conf.json.hbs +46 -0
  116. package/templates/apps/fullstack/apps/{{projectName}}-desktop/svelte.config.js.hbs +14 -0
  117. package/templates/apps/fullstack/apps/{{projectName}}-desktop/tsconfig.json.hbs +22 -0
  118. package/templates/apps/fullstack/apps/{{projectName}}-desktop/vite.config.ts.hbs +89 -0
  119. package/templates/apps/fullstack/apps/{{projectName}}-miniapp/README.md.hbs +25 -0
  120. package/templates/apps/fullstack/apps/{{projectName}}-miniapp/messages/en-US.json.hbs +12 -0
  121. package/templates/apps/fullstack/apps/{{projectName}}-miniapp/messages/ja-JP.json.hbs +12 -0
  122. package/templates/apps/fullstack/apps/{{projectName}}-miniapp/messages/zh-CN.json.hbs +12 -0
  123. package/templates/apps/fullstack/apps/{{projectName}}-miniapp/project.inlang/settings.json.hbs +17 -0
  124. package/templates/apps/fullstack/apps/{{projectName}}-web/README.md.hbs +54 -0
  125. package/templates/apps/fullstack/apps/{{projectName}}-web/eslint.config.js.hbs +20 -0
  126. package/templates/apps/fullstack/apps/{{projectName}}-web/index.html.hbs +21 -0
  127. package/templates/apps/fullstack/apps/{{projectName}}-web/messages/en-US.json.hbs +7 -0
  128. package/templates/apps/fullstack/apps/{{projectName}}-web/messages/ja-JP.json.hbs +7 -0
  129. package/templates/apps/fullstack/apps/{{projectName}}-web/messages/zh-CN.json.hbs +7 -0
  130. package/templates/apps/fullstack/apps/{{projectName}}-web/package.json.hbs +53 -0
  131. package/templates/apps/fullstack/apps/{{projectName}}-web/project.inlang/settings.json.hbs +17 -0
  132. package/templates/apps/fullstack/apps/{{projectName}}-web/public/runtime-config.js.hbs +1 -0
  133. package/templates/apps/fullstack/apps/{{projectName}}-web/src/App.svelte.hbs +18 -0
  134. package/templates/apps/fullstack/apps/{{projectName}}-web/src/app.css.hbs +18 -0
  135. package/templates/apps/fullstack/apps/{{projectName}}-web/src/app.d.ts.hbs +8 -0
  136. package/templates/apps/fullstack/apps/{{projectName}}-web/src/build-metadata.ts.hbs +9 -0
  137. package/templates/apps/fullstack/apps/{{projectName}}-web/src/main.ts.hbs +14 -0
  138. package/templates/apps/fullstack/apps/{{projectName}}-web/svelte.config.js.hbs +16 -0
  139. package/templates/apps/fullstack/apps/{{projectName}}-web/tsconfig.json.hbs +23 -0
  140. package/templates/apps/fullstack/apps/{{projectName}}-web/vite.config.ts.hbs +76 -0
  141. package/templates/apps/fullstack/docs/security-configuration.md.hbs +349 -0
  142. package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +988 -0
  143. package/templates/apps/fullstack/e2e/session-close.spec.ts.hbs +119 -0
  144. package/templates/apps/fullstack/eslint.config.js.hbs +41 -0
  145. package/templates/apps/fullstack/hai.json.hbs +11 -0
  146. package/templates/apps/fullstack/images/serv.Dockerfile.hbs +38 -0
  147. package/templates/apps/fullstack/images/web/19-runtime-config.envsh.hbs +5 -0
  148. package/templates/apps/fullstack/images/web/nginx.conf.hbs +24 -0
  149. package/templates/apps/fullstack/images/web/runtime-config.js.template.hbs +3 -0
  150. package/templates/apps/fullstack/images/web.Dockerfile.hbs +37 -0
  151. package/templates/apps/fullstack/package.json.hbs +61 -0
  152. package/templates/apps/fullstack/packages/{{projectName}}-contract/README.md.hbs +40 -0
  153. package/templates/apps/fullstack/packages/{{projectName}}-contract/package.json.hbs +30 -0
  154. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-contract.ts.hbs +78 -0
  155. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-schemas.ts.hbs +134 -0
  156. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/app-contract.ts.hbs +20 -0
  157. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/app-schemas.ts.hbs +35 -0
  158. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/index.ts.hbs +7 -0
  159. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +23 -0
  160. package/templates/apps/fullstack/packages/{{projectName}}-contract/tests/contract.test.ts.hbs +31 -0
  161. package/templates/apps/fullstack/packages/{{projectName}}-contract/tsconfig.json.hbs +9 -0
  162. package/templates/apps/fullstack/packages/{{projectName}}-contract/tsup.config.ts.hbs +9 -0
  163. package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +84 -0
  164. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_ai.yml.hbs +1 -0
  165. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_audit.yml.hbs +1 -0
  166. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_cache.yml.hbs +1 -0
  167. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_core.yml.hbs +22 -0
  168. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_db.yml.hbs +1 -0
  169. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_feedback.yml.hbs +1 -0
  170. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_iam.yml.hbs +1 -0
  171. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_payment.yml.hbs +1 -0
  172. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_reach.yml.hbs +60 -0
  173. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_scheduler.yml.hbs +1 -0
  174. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_serv.yml.hbs +64 -0
  175. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_storage.yml.hbs +1 -0
  176. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_vecdb.yml.hbs +1 -0
  177. package/templates/apps/fullstack/packages/{{projectName}}-serv/data/.gitkeep.hbs +1 -0
  178. package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +62 -0
  179. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/app-server.ts.hbs +115 -0
  180. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/build-metadata.ts.hbs +7 -0
  181. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/index.ts.hbs +40 -0
  182. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/admin-service.ts.hbs +294 -0
  183. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/audit-jobs.ts.hbs +28 -0
  184. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/business-settings.ts.hbs +50 -0
  185. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/messages.ts.hbs +50 -0
  186. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/admin-procedures.ts.hbs +106 -0
  187. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/app-procedures.ts.hbs +49 -0
  188. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/index.ts.hbs +34 -0
  189. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/runtime.ts.hbs +159 -0
  190. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/security-roles.ts.hbs +73 -0
  191. package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/app-server.test.ts.hbs +505 -0
  192. package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/runtime.test.ts.hbs +72 -0
  193. package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/security.test.ts.hbs +183 -0
  194. package/templates/apps/fullstack/packages/{{projectName}}-serv/tsconfig.json.hbs +10 -0
  195. package/templates/apps/fullstack/packages/{{projectName}}-serv/tsup.config.ts.hbs +18 -0
  196. package/templates/apps/fullstack/packages/{{projectName}}-serv/vitest.config.ts.hbs +12 -0
  197. package/templates/apps/fullstack/packages/{{projectName}}-shared/.gitignore.hbs +10 -0
  198. package/templates/apps/fullstack/packages/{{projectName}}-shared/README.md.hbs +97 -0
  199. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/en-US.json.hbs +164 -0
  200. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/ja-JP.json.hbs +164 -0
  201. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/zh-CN.json.hbs +164 -0
  202. package/templates/apps/fullstack/packages/{{projectName}}-shared/package.json.hbs +55 -0
  203. package/templates/apps/fullstack/packages/{{projectName}}-shared/project.inlang/settings.json.hbs +11 -0
  204. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/index.ts.hbs +7 -0
  205. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/api-client.ts.hbs +94 -0
  206. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/feedback-client.ts.hbs +36 -0
  207. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/sensitive-actions.svelte.ts.hbs +16 -0
  208. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/session-recovery.svelte.ts.hbs +4 -0
  209. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AdminWorkspace.svelte.hbs +122 -0
  210. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AppShell.svelte.hbs +90 -0
  211. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/FeedbackEntry.svelte.hbs +86 -0
  212. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/audit.svelte.hbs +94 -0
  213. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/configuration.svelte.hbs +25 -0
  214. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/feedback.svelte.hbs +157 -0
  215. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/roles.svelte.hbs +77 -0
  216. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/settings.svelte.hbs +44 -0
  217. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/users.svelte.hbs +216 -0
  218. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/security/role-label.ts.hbs +12 -0
  219. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/guide-store.ts.hbs +55 -0
  220. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/management-store.svelte.ts.hbs +614 -0
  221. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/theme-store.svelte.ts.hbs +23 -0
  222. package/templates/apps/fullstack/packages/{{projectName}}-shared/svelte.config.js.hbs +1 -0
  223. package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/api-client.test.ts.hbs +150 -0
  224. package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/management-store.test.ts.hbs +253 -0
  225. package/templates/apps/fullstack/packages/{{projectName}}-shared/tsconfig.json.hbs +17 -0
  226. package/templates/apps/fullstack/packages/{{projectName}}-shared/vitest.config.ts.hbs +7 -0
  227. package/templates/apps/fullstack/playwright.config.ts.hbs +114 -0
  228. package/templates/apps/fullstack/playwright.session-close.config.ts.hbs +18 -0
  229. package/templates/apps/fullstack/pnpm-workspace.yaml.hbs +38 -0
  230. package/templates/apps/fullstack/tsconfig.base.json +14 -0
  231. package/templates/apps/h5/messages/en-US.json +3 -0
  232. package/templates/apps/h5/messages/ja-JP.json +40 -0
  233. package/templates/apps/h5/messages/zh-CN.json +3 -0
  234. package/templates/apps/h5/src/routes/+layout.svelte.hbs +85 -30
  235. package/templates/apps/h5/src/routes/+page.svelte.hbs +20 -8
  236. package/templates/apps/h5/src/routes/discover/+page.svelte.hbs +17 -6
  237. package/templates/apps/h5/src/routes/profile/+page.svelte.hbs +17 -6
  238. package/templates/apps/mobile-app/.env.hbs +3 -0
  239. package/templates/apps/{android-app → mobile-app}/capacitor.config.ts.hbs +2 -2
  240. package/templates/apps/mobile-app/index.html.hbs +14 -0
  241. package/templates/apps/mobile-app/messages/en-US.json +36 -0
  242. package/templates/apps/mobile-app/messages/ja-JP.json +36 -0
  243. package/templates/apps/mobile-app/messages/zh-CN.json +36 -0
  244. package/templates/apps/mobile-app/public/runtime-config.js +1 -0
  245. package/templates/apps/mobile-app/src/App.svelte.hbs +153 -0
  246. package/templates/apps/mobile-app/src/lib/api.ts.hbs +213 -0
  247. package/templates/apps/mobile-app/src/lib/app-config.ts.hbs +14 -0
  248. package/templates/apps/{android-app → mobile-app}/src/lib/capacitor.ts +6 -7
  249. package/templates/apps/mobile-app/src/lib/pages/home.svelte.hbs +58 -0
  250. package/templates/apps/mobile-app/src/lib/pages/profile.svelte.hbs +13 -0
  251. package/templates/apps/mobile-app/src/lib/pages/tasks.svelte.hbs +16 -0
  252. package/templates/apps/mobile-app/src/main.ts.hbs +11 -0
  253. package/templates/apps/website/messages/en-US.json +4 -2
  254. package/templates/apps/website/messages/ja-JP.json +34 -0
  255. package/templates/apps/website/messages/zh-CN.json +4 -2
  256. package/templates/apps/website/scripts/static-website.mjs.hbs +67 -0
  257. package/templates/apps/website/src/routes/+layout.svelte.hbs +77 -26
  258. package/templates/apps/website/src/routes/+layout.ts +3 -0
  259. package/templates/apps/website/src/routes/+page.svelte.hbs +31 -12
  260. package/templates/apps/website/src/routes/about/+page.svelte.hbs +11 -6
  261. package/templates/apps/website/src/routes/api/health/+server.ts +3 -0
  262. package/templates/apps/website/src/routes/contact/+page.svelte.hbs +44 -34
  263. package/templates/apps/website/src/routes/services/+page.svelte.hbs +27 -40
  264. package/templates/base/.dockerignore.hbs +27 -0
  265. package/templates/base/.gitignore.hbs +41 -0
  266. package/templates/base/.npmrc.hbs +1 -0
  267. package/templates/base/e2e/app.spec.ts.hbs +213 -0
  268. package/templates/base/e2e/helpers.ts +1 -1
  269. package/templates/base/eslint-rules.js +45 -0
  270. package/templates/base/eslint.config.js.hbs +34 -0
  271. package/templates/base/hai.json.hbs +4 -0
  272. package/templates/base/images/web/nginx.conf.hbs +24 -0
  273. package/templates/base/images/web.Dockerfile.hbs +72 -0
  274. package/templates/base/package.json.hbs +125 -49
  275. package/templates/base/playwright.config.ts +44 -6
  276. package/templates/base/pnpm-workspace.yaml.hbs +40 -0
  277. package/templates/base/src/app.css.hbs +40 -0
  278. package/templates/base/src/app.d.ts.hbs +14 -1
  279. package/templates/base/src/app.html.hbs +13 -0
  280. package/templates/base/src/hooks.server.ts.hbs +115 -43
  281. package/templates/base/src/lib/build-metadata.ts.hbs +7 -0
  282. package/templates/base/src/lib/server/init.ts.hbs +125 -152
  283. package/templates/base/src/lib/server/kit-config.ts.hbs +40 -0
  284. package/templates/base/src/routes/+layout.server.ts.hbs +35 -0
  285. package/templates/base/static/favicon.png +0 -0
  286. package/templates/base/svelte.config.js.hbs +84 -5
  287. package/templates/base/tests/scaffold.test.ts.hbs +102 -0
  288. package/templates/base/tsconfig.json.hbs +50 -0
  289. package/templates/base/vite.config.ts.hbs +117 -12
  290. package/templates/base/vitest.config.ts.hbs +19 -0
  291. package/templates/features/ai/routes/api/chat/+server.ts +6 -7
  292. package/templates/features/iam/routes-admin/(auth)/+layout.svelte.hbs +3 -17
  293. package/templates/features/iam/routes-admin/(auth)/auth/forgot-password/+page.svelte.hbs +10 -0
  294. package/templates/features/iam/routes-admin/(auth)/auth/login/+page.svelte.hbs +9 -96
  295. package/templates/features/iam/routes-admin/(auth)/auth/register/+page.svelte.hbs +9 -122
  296. package/templates/features/iam/routes-admin/(auth)/auth/reset-password/+page.svelte.hbs +10 -0
  297. package/templates/features/iam/routes-h5/auth/forgot-password/+page.svelte.hbs +10 -0
  298. package/templates/features/iam/routes-h5/auth/login/+page.svelte.hbs +9 -96
  299. package/templates/features/iam/routes-h5/auth/register/+page.svelte.hbs +9 -112
  300. package/templates/features/iam/routes-h5/auth/reset-password/+page.svelte.hbs +10 -0
  301. package/templates/features/iam/routes-shared/api/auth/captcha/+server.ts.hbs +4 -0
  302. package/templates/features/iam/routes-shared/api/auth/config/+server.ts +4 -0
  303. package/templates/features/iam/routes-shared/api/auth/login/+server.ts +1 -29
  304. package/templates/features/iam/routes-shared/api/auth/login/ldap/+server.ts +4 -0
  305. package/templates/features/iam/routes-shared/api/auth/login/otp/+server.ts +4 -0
  306. package/templates/features/iam/routes-shared/api/auth/logout/+server.ts +13 -6
  307. package/templates/features/iam/routes-shared/api/auth/otp/send/+server.ts +4 -0
  308. package/templates/features/iam/routes-shared/api/auth/password/renew/+server.ts +5 -0
  309. package/templates/features/iam/routes-shared/api/auth/password-reset/confirm/+server.ts +4 -0
  310. package/templates/features/iam/routes-shared/api/auth/password-reset/request/+server.ts +4 -0
  311. package/templates/features/iam/routes-shared/api/auth/reauthenticate/+server.ts +5 -0
  312. package/templates/features/iam/routes-shared/api/auth/register/+server.ts +1 -23
  313. package/templates/features/iam/routes-shared/api/auth/session/close/+server.ts.hbs +4 -0
  314. package/templates/features/iam/routes-website/auth/forgot-password/+page.svelte.hbs +10 -0
  315. package/templates/features/iam/routes-website/auth/login/+page.svelte.hbs +11 -0
  316. package/templates/features/iam/routes-website/auth/register/+page.svelte.hbs +11 -0
  317. package/templates/features/iam/routes-website/auth/reset-password/+page.svelte.hbs +10 -0
  318. package/templates/features/payment/routes/api/v1/payment/create/+server.ts +25 -23
  319. package/templates/features/payment/routes/api/v1/payment/notify/[provider]/+server.ts +5 -2
  320. package/templates/features/storage/routes/api/upload/+server.ts +10 -8
  321. package/templates/i18n/project.inlang/settings.json +2 -2
  322. package/templates/shared/.gitattributes +11 -0
  323. package/templates/shared/build-metadata.ts +42 -0
  324. package/templates/shared/container-runtime-config.sh +30 -0
  325. package/templates/shared/e2e-env.ts +98 -0
  326. package/templates/shared/hash-router.svelte.ts +83 -0
  327. package/templates/shared/public-base-path.mjs +19 -0
  328. package/templates/shared/run-e2e.mjs +104 -0
  329. package/templates/shared/vite-runtime-config.ts +56 -0
  330. package/templates/skills/AGENTS.md +75 -16
  331. package/templates/skills/CLAUDE.md +0 -11
  332. package/templates/skills/bridges/admin/AGENTS.md +89 -0
  333. package/templates/skills/bridges/api/AGENTS.md +83 -0
  334. package/templates/skills/bridges/fullstack/AGENTS.md.hbs +102 -0
  335. package/templates/skills/bridges/h5/AGENTS.md +88 -0
  336. package/templates/skills/bridges/mobile-app/AGENTS.md +100 -0
  337. package/templates/skills/bridges/website/AGENTS.md +88 -0
  338. package/templates/skills/copilot-instructions.md +3 -59
  339. package/templates/skills/hai-ai/SKILL.md +44 -715
  340. package/templates/skills/hai-ai/guide.md +457 -0
  341. package/templates/skills/hai-ai/reference.md +292 -0
  342. package/templates/skills/hai-api-client/SKILL.md +26 -339
  343. package/templates/skills/hai-api-client/reference.md +180 -0
  344. package/templates/skills/hai-api-contract/SKILL.md +36 -0
  345. package/templates/skills/hai-api-contract/reference.md +280 -0
  346. package/templates/skills/hai-app-create/SKILL.md +38 -351
  347. package/templates/skills/hai-app-create/collaboration.md +52 -0
  348. package/templates/skills/hai-app-create/development.md +243 -0
  349. package/templates/skills/hai-app-create/reference.md +376 -0
  350. package/templates/skills/hai-app-review/SKILL.md +57 -126
  351. package/templates/skills/hai-app-review/differential.md +34 -0
  352. package/templates/skills/hai-app-tests/SKILL.md +34 -454
  353. package/templates/skills/hai-app-tests/reference.md +462 -0
  354. package/templates/skills/hai-app-tests/validation.md +42 -0
  355. package/templates/skills/hai-audit/SKILL.md +37 -122
  356. package/templates/skills/hai-audit/reference.md +184 -0
  357. package/templates/skills/hai-build/SKILL.md +62 -315
  358. package/templates/skills/hai-build/paths.md +30 -0
  359. package/templates/skills/hai-build/reference.md +353 -0
  360. package/templates/skills/hai-cache/SKILL.md +26 -175
  361. package/templates/skills/hai-cache/reference.md +229 -0
  362. package/templates/skills/hai-capacitor/SKILL.md +24 -364
  363. package/templates/skills/hai-capacitor/reference.md +358 -0
  364. package/templates/skills/hai-change-plan/SKILL.md +46 -0
  365. package/templates/skills/hai-ci/SKILL.md +114 -0
  366. package/templates/skills/hai-core/SKILL.md +31 -469
  367. package/templates/skills/hai-core/reference.md +557 -0
  368. package/templates/skills/hai-core/request-access.md +65 -0
  369. package/templates/skills/hai-crypto/SKILL.md +29 -180
  370. package/templates/skills/hai-crypto/reference.md +317 -0
  371. package/templates/skills/hai-datapipe/SKILL.md +24 -207
  372. package/templates/skills/hai-datapipe/reference.md +204 -0
  373. package/templates/skills/hai-deploy/SKILL.md +53 -178
  374. package/templates/skills/hai-deploy/credentials.md +19 -0
  375. package/templates/skills/hai-deploy/middleware.md +129 -0
  376. package/templates/skills/hai-feedback/SKILL.md +85 -0
  377. package/templates/skills/hai-framework-sync/SKILL.md +105 -0
  378. package/templates/skills/hai-framework-sync/sync.md +49 -0
  379. package/templates/skills/hai-iam/SKILL.md +53 -325
  380. package/templates/skills/hai-iam/reference.md +535 -0
  381. package/templates/skills/hai-kit/SKILL.md +33 -329
  382. package/templates/skills/hai-kit/reference.md +202 -0
  383. package/templates/skills/hai-payment/SKILL.md +28 -262
  384. package/templates/skills/hai-payment/reference.md +295 -0
  385. package/templates/skills/hai-pr-review/SKILL.md +41 -0
  386. package/templates/skills/hai-reach/SKILL.md +28 -300
  387. package/templates/skills/hai-reach/reference.md +363 -0
  388. package/templates/skills/hai-reldb/SKILL.md +28 -449
  389. package/templates/skills/hai-reldb/reference.md +500 -0
  390. package/templates/skills/hai-scheduler/SKILL.md +26 -174
  391. package/templates/skills/hai-scheduler/reference.md +216 -0
  392. package/templates/skills/hai-serv/SKILL.md +60 -0
  393. package/templates/skills/hai-serv/reference.md +792 -0
  394. package/templates/skills/hai-spec-implement/SKILL.md +50 -0
  395. package/templates/skills/hai-spec-implement/changes.md +67 -0
  396. package/templates/skills/hai-spec-implement/evaluation.md +18 -0
  397. package/templates/skills/hai-spec-implement/handoff.md +47 -0
  398. package/templates/skills/hai-spec-implement/templates.md +117 -0
  399. package/templates/skills/hai-spec-implement/workflow.md +56 -0
  400. package/templates/skills/hai-spec-review/SKILL.md +57 -0
  401. package/templates/skills/hai-spec-review/checklist.md +71 -0
  402. package/templates/skills/hai-storage/SKILL.md +31 -262
  403. package/templates/skills/hai-storage/reference.md +284 -0
  404. package/templates/skills/hai-ui/SKILL.md +62 -238
  405. package/templates/skills/hai-ui/guide.md +81 -0
  406. package/templates/skills/hai-ui/reference.md +705 -0
  407. package/templates/skills/hai-ui-design/SKILL.md +31 -0
  408. package/templates/skills/hai-ui-design/patterns.md +31 -0
  409. package/templates/skills/hai-ui-review/SKILL.md +32 -0
  410. package/templates/skills/hai-ui-review/checklist.md +29 -0
  411. package/templates/skills/hai-vecdb/SKILL.md +25 -267
  412. package/templates/skills/hai-vecdb/reference.md +325 -0
  413. package/templates/skills/opencode.json +0 -5
  414. package/dist/chunk-2H7UOFLK.js +0 -10
  415. package/dist/chunk-LANIDJC7.js +0 -659
  416. package/dist/chunk-LANIDJC7.js.map +0 -1
  417. package/dist/chunk-YV7WPUI6.js +0 -206
  418. package/dist/chunk-YV7WPUI6.js.map +0 -1
  419. package/dist/config-templates-S5RI2MC6.js +0 -5
  420. package/dist/config-templates-S5RI2MC6.js.map +0 -1
  421. package/dist/skill-templates-N5DU5FNX.js +0 -5
  422. package/dist/skill-templates-N5DU5FNX.js.map +0 -1
  423. package/dist/src-XJ6YXNAF.js +0 -15030
  424. package/dist/src-XJ6YXNAF.js.map +0 -1
  425. package/templates/apps/android-app/.env.hbs +0 -3
  426. package/templates/apps/android-app/messages/en-US.json +0 -24
  427. package/templates/apps/android-app/messages/zh-CN.json +0 -24
  428. package/templates/apps/android-app/src/lib/api.ts.hbs +0 -30
  429. package/templates/apps/android-app/src/routes/+layout.svelte.hbs +0 -42
  430. package/templates/apps/android-app/src/routes/+layout.ts +0 -7
  431. package/templates/apps/android-app/src/routes/+page.svelte.hbs +0 -27
  432. package/templates/apps/api/src/routes/+layout.svelte +0 -14
  433. package/templates/apps/api/src/routes/+page.svelte +0 -11
  434. package/templates/apps/api/src/routes/api/v1/health/+server.ts +0 -14
  435. package/templates/apps/api/src/routes/api/v1/items/+server.ts +0 -37
  436. package/templates/apps/api/src/routes/api/v1/items/[id]/+server.ts +0 -30
  437. package/templates/base/src/app.css +0 -2
  438. package/templates/base/tsconfig.json +0 -8
@@ -1,468 +1,48 @@
1
1
  ---
2
2
  name: hai-app-tests
3
- description: 以 TDD 驱动应用开发:先分析需求、生成单元测试(Vitest)与 E2E 测试(Playwright),确认测试全部失败后再编码实现直至测试通过;当需求涉及应用测试、TDD 流程、覆盖率提升、E2E 测试时使用。
3
+ description: "为 hai 应用编写或修复 Vitest/Playwright 测试,组织分轮验证、汇总失败和集中修复,验证需求与完整用户流程。"
4
4
  ---
5
5
 
6
- # hai-app-tests — TDD 驱动的应用测试规范
6
+ # hai-app-tests
7
7
 
8
- > 面向 AI 助手的 TDD 测试指南。**测试先行**:先写测试定义行为,再写实现让测试通过。涵盖 Vitest 单元测试与 Playwright E2E 测试。
8
+ ## 能力契约
9
9
 
10
- ---
11
-
12
- ## 适用场景
13
-
14
- - 以 TDD 方式开发新功能(先写测试 → 确认失败 → 再实现 → 确认通过)
15
- - 为 `$lib/server/services/` 编写服务层单元测试
16
- - 为 API 端点编写 E2E 测试(Playwright)
17
- - 为页面交互编写 UI E2E 测试(Playwright)
18
- - 为工具函数、Schema 校验编写单元测试
19
- - 需要提升测试覆盖率
20
-
21
- ---
22
-
23
- ## TDD 核心工作流(必须严格遵循)
24
-
25
- ### 阶段一:需求分析(Red 前准备)
26
-
27
- 1. **理解需求**:明确功能的输入、输出、边界条件、错误场景
28
- 2. **拆分测试点**:将需求转化为可验证的测试用例清单
29
- 3. **确定测试类型**:
30
- - **单元测试(Vitest)**:服务层、工具函数、Schema 校验、HaiResult 处理
31
- - **E2E 测试(Playwright)**:API 端点、页面交互、认证流程、跨模块集成
32
-
33
- ### 阶段二:Red — 编写失败的测试
34
-
35
- 1. **编写单元测试**:覆盖正常路径、边界路径、权限路径、错误路径
36
- 2. **编写 E2E 测试**:覆盖 API 端点和关键用户交互流程
37
- 3. **运行测试确认全部失败**:
38
- ```bash
39
- pnpm --filter <app-name> test # 单元测试 — 应全部 FAIL
40
- pnpm --filter <app-name> test:e2e # E2E 测试 — 应全部 FAIL
41
- ```
42
- 4. 如果测试意外通过,说明测试没有测到新功能,需要修正测试
43
-
44
- ### 阶段三:Green — 最小实现
45
-
46
- 1. 参照 `hai-app-create` 技能编写实现代码
47
- 2. 每实现一个功能点,立即运行对应测试确认通过
48
- 3. 只写让测试通过的最小代码,不做过度设计
49
- 4. 运行全部测试确认通过:
50
- ```bash
51
- pnpm --filter <app-name> test # 单元测试 — 应全部 PASS
52
- pnpm --filter <app-name> test:e2e # E2E 测试 — 应全部 PASS
53
- ```
54
-
55
- ### 阶段四:Refactor — 重构优化
56
-
57
- 1. 参照 `hai-app-review` 技能审查代码规范
58
- 2. 重构后再次运行所有测试确认仍然通过
59
- 3. 运行质量门禁:`pnpm typecheck && pnpm lint && pnpm test`
60
-
61
- ---
62
-
63
- ## 测试目录约定
64
-
65
- ```
66
- tests/ # 单元测试(Vitest)
67
- services/
68
- user.test.ts # 服务层测试
69
- article.test.ts
70
- schemas/
71
- user-schema.test.ts # Schema 校验测试
72
- utils/
73
- helper.test.ts # 工具函数测试
74
- e2e/ # E2E 测试(Playwright)
75
- helpers.ts # E2E 共用工具函数
76
- health.spec.ts # 健康检查 API
77
- auth-api.spec.ts # 认证 API 测试
78
- auth-ui.spec.ts # 认证页面 UI 测试
79
- users-api.spec.ts # 用户管理 API 测试
80
- users-ui.spec.ts # 用户管理页面 UI 测试
81
- ```
82
-
83
- ---
84
-
85
- ## 核心规则
86
-
87
- 1. **测试先行**:先写测试定义预期行为,再写实现代码。
88
- 2. **统一入口**:通过框架模块公共 API 测试(`reldb.sql`、`iam.authn`),不直接调用内部实现。
89
- 3. **从实际场景出发**:测试用例验证真实业务行为,不做形式覆盖。
90
- 4. **先审查后修复**:测试不通过时先审查业务逻辑是否有问题,不直接修改测试迎合通过。
91
- 5. **Mock 外部依赖**:单元测试中,数据库、缓存、网络请求使用 mock,不直连真实服务。
92
- 6. **E2E 真实环境**:E2E 测试运行在完整应用环境中,不使用 mock。
93
-
94
- ---
95
-
96
- ## 覆盖范围
97
-
98
- 每个功能至少覆盖以下路径(单元测试 + E2E 按需):
99
-
100
- | 路径 | 说明 | 单元测试示例 | E2E 测试示例 |
101
- | -------- | ------------------------ | ------------------ | ----------------------- |
102
- | 正常路径 | 核心功能可用 | 创建用户成功 | POST /api/users → 201 |
103
- | 边界路径 | 非法输入、空值、格式错误 | 空名称、超长字符串 | 空表单提交 → 校验提示 |
104
- | 权限路径 | 未认证、无权限 | 未登录调用服务 | 未登录访问 → 401/重定向 |
105
- | 错误路径 | 服务异常、数据库错误 | DB 失败时的 HaiResult | 服务不可用 → 错误提示页 |
106
-
107
- ---
108
-
109
- ## 单元测试(Vitest)
110
-
111
- ### 服务层测试模板
112
-
113
- ```typescript
114
- import { createArticle, listArticles } from '$lib/server/services/article'
115
- // tests/services/article.test.ts
116
- import { reldb } from '@h-ai/reldb'
117
- import { describe, expect, it, vi } from 'vitest'
118
-
119
- // Mock 依赖模块
120
- vi.mock('@h-ai/reldb', () => ({
121
- db: {
122
- sql: { query: vi.fn(), execute: vi.fn() },
123
- crud: { create: vi.fn(), findById: vi.fn(), paginate: vi.fn() },
124
- },
125
- }))
126
-
127
- vi.mock('@h-ai/core', () => ({
128
- core: { logger: { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } },
129
- }))
130
-
131
- describe('ArticleService', () => {
132
- // 正常路径
133
- it('should create article successfully', async () => {
134
- const mockArticle = { id: '1', title: 'Test', authorId: 'u1' }
135
- vi.mocked(reldb.crud.create).mockResolvedValue({ success: true, data: mockArticle })
136
-
137
- const result = await createArticle({ title: 'Test', authorId: 'u1' })
138
-
139
- expect(result.success).toBe(true)
140
- if (result.success) {
141
- expect(result.data.title).toBe('Test')
142
- }
143
- })
144
-
145
- // 边界路径
146
- it('should return error for empty title', async () => {
147
- const result = await createArticle({ title: '', authorId: 'u1' })
148
-
149
- expect(result.success).toBe(false)
150
- if (!result.success) {
151
- expect(result.error.code).toBeDefined()
152
- }
153
- })
154
-
155
- // 错误路径
156
- it('should return error when db fails', async () => {
157
- vi.mocked(reldb.crud.create).mockResolvedValue({
158
- success: false,
159
- error: { code: 'DB_ERROR', message: 'Connection lost' },
160
- })
161
-
162
- const result = await createArticle({ title: 'Test', authorId: 'u1' })
163
-
164
- expect(result.success).toBe(false)
165
- })
166
- })
167
- ```
168
-
169
- ### Schema 校验测试模板
170
-
171
- ```typescript
172
- import { CreateUserSchema } from '$lib/server/schemas/user'
173
- // tests/schemas/user-schema.test.ts
174
- import { describe, expect, it } from 'vitest'
175
-
176
- describe('CreateUserSchema', () => {
177
- it('should accept valid input', () => {
178
- const result = CreateUserSchema.safeParse({
179
- username: 'testuser',
180
- email: 'test@example.com',
181
- password: '12345678',
182
- })
183
- expect(result.success).toBe(true)
184
- })
185
-
186
- it('should reject short username', () => {
187
- const result = CreateUserSchema.safeParse({
188
- username: 'ab',
189
- email: 'test@example.com',
190
- password: '12345678',
191
- })
192
- expect(result.success).toBe(false)
193
- })
194
-
195
- it('should reject invalid email', () => {
196
- const result = CreateUserSchema.safeParse({
197
- username: 'testuser',
198
- email: 'not-email',
199
- password: '12345678',
200
- })
201
- expect(result.success).toBe(false)
202
- })
203
- })
204
- ```
205
-
206
- ---
207
-
208
- ## E2E 测试(Playwright)
10
+ | 项目 | 契约 |
11
+ | --- | --- |
12
+ | 能力 | 编写或修复 Vitest/Playwright 测试,组织质量门禁与业务流程的分轮验证 |
13
+ | 适用场景 | 需求验收、缺陷回归或应用测试改进 |
14
+ | 输入 | 验收条件、被测公共入口、现有测试和运行环境 |
15
+ | 输出 | 可复现用例及明确区分静态、mock、浏览器/外部服务的结果 |
16
+ | 限制 | Red 阶段验证本次目标用例因行为缺失而失败,不要求无关回归失败;不能为迁就实现删除断言或修改预期。 |
209
17
 
210
- ### Playwright 配置
18
+ ## 使用路径
211
19
 
212
- 项目中应有 `playwright.config.ts`(由 CLI 生成):
20
+ 测试或排错发现需要改变框架结构、配置、核心流程、模块边界时,先按 [变更影响与方案确认](../hai-change-plan/SKILL.md) 说明原因、影响与验证办法,待用户决定后改实现。不能通过修改断言把未确认的契约变化变成既定行为。
213
21
 
214
- ```typescript
215
- // playwright.config.ts
216
- import process from 'node:process'
217
- import { defineConfig } from '@playwright/test'
22
+ 测试增删、问题表达及同步检查遵循[沟通与同步维护](../hai-app-create/collaboration.md)。合并或删除用例前核对独有风险覆盖,交付说明新增、删除、调整的原因;界面与文档示例使用当前运行证据。
218
23
 
219
- const baseURL = process.env.BASE_URL || 'http://localhost:4173'
24
+ 先复用 [工作交接契约](../hai-spec-implement/handoff.md) 中的验收编号和本轮范围。结果关联提交与未提交差异、命令/操作、依赖与环境、退出码和证据位置;源码/配置/依赖或环境变化后按影响使旧结果失效并复测。测试通过只是相应验收的证据,整体验收仍逐项核对需求。
220
25
 
221
- export default defineConfig({
222
- testDir: './e2e',
223
- fullyParallel: false,
224
- forbidOnly: !!process.env.CI,
225
- retries: process.env.CI ? 2 : 0,
226
- workers: 2,
227
- reporter: 'list',
228
- timeout: 30_000,
229
- use: {
230
- baseURL,
231
- channel: 'chrome',
232
- trace: 'on-first-retry',
233
- screenshot: 'only-on-failure',
234
- },
235
- webServer: {
236
- command: 'pnpm build && pnpm preview --port 4173 --strictPort',
237
- env: { HAI_E2E: '1' },
238
- url: baseURL,
239
- reuseExistingServer: false,
240
- timeout: 180_000,
241
- },
242
- })
243
- ```
26
+ - 验证前先分析差异、调用方与受影响用户流程,再选择单元/集成/浏览器层;默认只跑变更相关 test/E2E 和必要门禁,用户明确要求时才全量。复用测试 fixture,验证用户可观察结果。
27
+ - 验收以用户当前明确要求和指定业务文档为准;模板测试不是不可变需求。规则已改变时同步更新或替换过期断言,记录新需求依据并覆盖新的授权/失败边界;保留仍适用的回归,不能用“保持旧测试通过”强留冲突业务。
28
+ - 按 [development.md](../hai-app-create/development.md) 的真实行为与安全边界选测试;新增/改变业务行为、缺陷修复有目标用例,纯文案/格式/文档及无行为变化的可逆低影响修改不补镜像测试。
29
+ - 不要求每个功能同时新增单元与 E2E;复用已有用例,选择能验证变化的最小适用层,关键跨层用户流程仍需端到端证据。
30
+ - 新用例已通过时先检查是否已有能力;不能为达成 Red 人为破坏旧测试。
31
+ - 执行多项门禁前读取 [分轮验证与集中修复](validation.md):一轮先脚本化收集所有可执行检查及日志,普通失败不立即改代码;汇总去重后集中修复,先定向复测失败、解除阻塞和直接受影响项,全部通过后再扩大验收。定向回归未通过时不重跑整套门禁。只有真实前置阻塞才暂停依赖检查;最终必需门禁均须对最终代码有效通过。小范围 TDD Red → Green 保留。
32
+ - 外部服务未运行必须报告;mock/Testcontainers/浏览器/真实付费 Provider 的结果分开表述。
244
33
 
245
- ### E2E 工具函数模板
246
-
247
- ```typescript
248
- // e2e/helpers.ts
249
- import type { APIRequestContext, Page } from '@playwright/test'
250
-
251
- /** 生成唯一测试用户 */
252
- export function uniqueUser(prefix = 'e2e') {
253
- const safePrefix = (prefix.replace(/\W/g, '') || 'e2e').slice(0, 8)
254
- const entropy = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`
255
- const id = entropy.slice(-10)
256
- const username = `${safePrefix}_${id}`.slice(0, 20)
257
- return {
258
- username,
259
- email: `${safePrefix}_${id}@test.local`,
260
- password: 'Test1234!@',
261
- }
262
- }
263
-
264
- /** 通过 API 注册用户 */
265
- export async function registerViaApi(
266
- request: APIRequestContext,
267
- user: ReturnType<typeof uniqueUser>,
268
- ) {
269
- return request.post('/api/auth/register', {
270
- data: {
271
- username: user.username,
272
- email: user.email,
273
- password: user.password,
274
- confirmPassword: user.password,
275
- },
276
- })
277
- }
278
-
279
- /** 注册并登录,返回已认证的 Page */
280
- export async function registerAndLogin(
281
- page: Page,
282
- request: APIRequestContext,
283
- prefix = 'e2e',
284
- ) {
285
- const user = uniqueUser(prefix)
286
- await registerViaApi(request, user)
287
- await page.goto('/login')
288
- await page.fill('[name="username"]', user.username)
289
- await page.fill('[name="password"]', user.password)
290
- await page.click('button[type="submit"]')
291
- await page.waitForURL('/')
292
- return user
293
- }
294
- ```
295
-
296
- ### API 端点 E2E 测试模板
297
-
298
- ```typescript
299
- // e2e/articles-api.spec.ts
300
- import { expect, test } from '@playwright/test'
301
- import { registerAndLogin } from './helpers'
302
-
303
- test.describe('Articles API', () => {
304
- test('GET /api/articles 未认证返回 401', async ({ request }) => {
305
- const response = await request.get('/api/articles')
306
- expect(response.status()).toBe(401)
307
- })
308
-
309
- test('POST /api/articles 创建文章成功', async ({ page, request }) => {
310
- await registerAndLogin(page, request, 'article')
311
-
312
- const response = await page.request.post('/api/articles', {
313
- data: { title: 'E2E Test Article', content: 'Test content' },
314
- })
315
- expect(response.status()).toBe(201)
316
-
317
- const body = await response.json()
318
- expect(body.success).toBe(true)
319
- expect(body.data.title).toBe('E2E Test Article')
320
- })
321
-
322
- test('POST /api/articles 空标题返回 400', async ({ page, request }) => {
323
- await registerAndLogin(page, request, 'article')
324
-
325
- const response = await page.request.post('/api/articles', {
326
- data: { title: '', content: '' },
327
- })
328
- expect(response.status()).toBe(400)
329
- })
330
-
331
- test('GET /api/articles 认证后获取列表', async ({ page, request }) => {
332
- await registerAndLogin(page, request, 'article')
333
-
334
- const response = await page.request.get('/api/articles')
335
- expect(response.ok()).toBeTruthy()
336
-
337
- const body = await response.json()
338
- expect(body.success).toBe(true)
339
- expect(Array.isArray(body.data)).toBe(true)
340
- })
341
- })
342
- ```
343
-
344
- ### 页面 UI E2E 测试模板
345
-
346
- ```typescript
347
- // e2e/articles-ui.spec.ts
348
- import { expect, test } from '@playwright/test'
349
- import { registerAndLogin } from './helpers'
350
-
351
- test.describe('Articles Page', () => {
352
- test('未登录跳转登录页', async ({ page }) => {
353
- await page.goto('/admin/articles')
354
- await expect(page).toHaveURL(/login/)
355
- })
356
-
357
- test('已登录显示文章列表', async ({ page, request }) => {
358
- await registerAndLogin(page, request, 'artui')
359
- await page.goto('/admin/articles')
360
-
361
- await expect(page.locator('h1, h2').first()).toContainText(/文章|article/i)
362
- })
363
-
364
- test('创建文章表单提交', async ({ page, request }) => {
365
- await registerAndLogin(page, request, 'artui')
366
- await page.goto('/admin/articles/new')
367
-
368
- await page.fill('[name="title"]', 'E2E Article')
369
- await page.fill('[name="content"]', 'E2E content')
370
- await page.click('button[type="submit"]')
371
-
372
- // 验证跳转或成功提示
373
- await expect(page.locator('.alert-success, .toast')).toBeVisible({ timeout: 5000 })
374
- })
375
- })
376
- ```
377
-
378
- ---
379
-
380
- ## TDD 用例设计策略
381
-
382
- ### 从需求到测试用例的转换
383
-
384
- ```
385
- 需求:用户可以创建文章,标题必填且不超过 100 字符,需要登录后才能操作
386
-
387
- ↓ 拆分测试点
388
-
389
- 单元测试(Vitest):
390
- ✅ 创建文章成功返回 HaiResult.ok
391
- ✅ 空标题返回 HaiResult.err + VALIDATION_FAILED
392
- ✅ 超长标题(>100 字符)返回 HaiResult.err
393
- ✅ DB 异常时透传错误
394
-
395
- Schema 测试(Vitest):
396
- ✅ 合法输入通过校验
397
- ✅ 空标题被拒绝
398
- ✅ 超长标题被拒绝
399
- ✅ 缺少必填字段被拒绝
400
-
401
- E2E 测试(Playwright):
402
- ✅ POST /api/articles 未认证 → 401
403
- ✅ POST /api/articles 合法数据 → 201
404
- ✅ POST /api/articles 空标题 → 400
405
- ✅ 页面表单提交成功 → 跳转/提示
406
- ✅ 未登录访问创建页 → 重定向登录
407
- ```
408
-
409
- ---
410
-
411
- ## 断言规范
412
-
413
- - 始终校验 `result.success`
414
- - 失败时校验 `error.code`(不只检查 `success === false`)
415
- - 使用类型缩窄后访问 data 或 error
416
- - E2E 断言使用 Playwright 内置 expect 匹配器
417
-
418
- ```typescript
419
- // ✅ 单元测试断言
420
- const result = await service.create(input)
421
- expect(result.success).toBe(true)
422
- if (result.success) {
423
- expect(result.data.id).toBeDefined()
424
- }
425
-
426
- // ✅ 单元测试错误断言
427
- const result = await service.create(invalidInput)
428
- expect(result.success).toBe(false)
429
- if (!result.success) {
430
- expect(result.error.code).toBe('VALIDATION_FAILED')
431
- }
432
-
433
- // ✅ E2E API 断言
434
- const response = await request.post('/api/articles', { data: input })
435
- expect(response.status()).toBe(201)
436
- const body = await response.json()
437
- expect(body.success).toBe(true)
438
-
439
- // ✅ E2E UI 断言
440
- await expect(page.locator('.alert-success')).toBeVisible()
441
- await expect(page).toHaveURL('/admin/articles')
442
- ```
443
-
444
- ---
445
-
446
- ## 质量门禁
447
-
448
- ```bash
449
- # 运行单元测试
450
- pnpm --filter <app-name> test
451
-
452
- # 运行 E2E 测试
453
- pnpm --filter <app-name> test:e2e
454
-
455
- # 覆盖率
456
- pnpm --filter <app-name> test:coverage
457
-
458
- # 全量门禁
459
- pnpm typecheck && pnpm lint && pnpm test
460
- ```
461
-
462
- ---
34
+ ## 按需参考
463
35
 
464
- ## 相关 Skills
36
+ 按任务读取 [reference.md](reference.md) 的对应小节;签名以当前源码或安装版本的公开类型为准,不默认加载全部资料。示例中的业务变量由应用提供。
465
37
 
466
- - `hai-app-create`:应用功能创建规范(TDD Green 阶段参照)
467
- - `hai-app-review`:应用代码审查规范(TDD Refactor 阶段参照)
468
- - `hai-build`:项目架构总览与 TDD 工作流导航
38
+ - 适用场景
39
+ - 行为验证与 TDD 工作流
40
+ - 测试目录约定
41
+ - 核心规则
42
+ - 覆盖范围
43
+ - 单元测试(Vitest)
44
+ - E2E 测试(Playwright)
45
+ - TDD 用例设计策略
46
+ - 断言规范
47
+ - 质量门禁
48
+ - 相关 Skills