@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
@@ -0,0 +1,229 @@
1
+ # hai-cache 参考
2
+
3
+ > `@h-ai/cache` 提供统一缓存接口,支持 Memory 与 Redis 后端,包含 KV / Hash / List / Set / ZSet / 分布式锁 六类操作。
4
+
5
+ 内存 KV 在到期时间点即失效。整数计数器拒绝 null/boolean/array、非整数增量和安全整数溢出,失败不修改原值;Hash 的 `__proto__` / `constructor` 名称按普通字段保留。
6
+
7
+ ## 运行环境
8
+
9
+ > ⚠️ **服务端模块(Node.js only)。** 浏览器端无需直接操作缓存,由服务端模块(如 IAM、Scheduler)内部使用。
10
+
11
+ ## 适用场景
12
+
13
+ - 缓存热点数据减少数据库查询
14
+ - 会话存储(配合 IAM)
15
+ - 分布式缓存(Redis)与本地测试缓存(Memory)
16
+ - 集合操作(权限缓存、标签集合)
17
+ - 排行榜(ZSet)与队列(List)
18
+ - 分布式锁(多节点部署互斥控制)
19
+
20
+ ## 使用步骤
21
+
22
+ ### 1. 配置
23
+
24
+ ```yaml
25
+ # config/_cache.yml
26
+ type: memory # memory | redis
27
+ # Redis 配置(type=redis 时生效):
28
+ # host: localhost
29
+ # port: 6379
30
+ # password: ''
31
+ # db: 0
32
+ # keyPrefix: 'hai:'
33
+ ```
34
+
35
+ 约定环境变量优先于 YAML,例如 `HAI_CACHE_TYPE`、`HAI_CACHE_HOST`、
36
+ `HAI_CACHE_KEYPREFIX`。
37
+
38
+ ### 2. 初始化与关闭
39
+
40
+ ```typescript
41
+ import { cache } from '@h-ai/cache'
42
+
43
+ await cache.init(core.config.get('cache'))
44
+ // 使用后关闭
45
+ const closed = await cache.close()
46
+ if (!closed.success) throw new Error(closed.error.message)
47
+ ```
48
+
49
+
50
+ 初始化只在健康检查成功后发布连接;失败时释放候选资源。若清理仍失败,初始化错误的 `error.ext.cleanupPending` 为 `true`。`cache.close()` 返回 `Promise<HaiResult<void>>`,等待正在进行的初始化,并合并并发关闭。开始清理后 `isInitialized` 为 `false`,配置与业务操作不再可用;清理失败仍保留资源,后续 `close()` 或 `init()` 先重试释放,成功前不会创建替代连接。调用方必须检查关闭结果。
51
+
52
+ ```ts
53
+ const closed = await cache.close()
54
+ if (!closed.success) {
55
+ // 处理清理故障后有限重试;再次失败应向应用报告。
56
+ const retried = await cache.close()
57
+ if (!retried.success) throw new Error(retried.error.message)
58
+ }
59
+ ```
60
+
61
+
62
+ `cache.config` 返回的是脱敏后的配置快照;Redis `password` / `url` 等敏感值不会原样暴露给日志或调试输出。
63
+
64
+ ## 核心 API
65
+
66
+ ### KV 操作(`cache.kv`)
67
+
68
+ | 方法 | 说明 |
69
+ | ----------------------------------- | -------------------- |
70
+ | `get / set / del / exists` | 基础读写与存在性判断 |
71
+ | `expire / expireAt / ttl / persist` | TTL 管理 |
72
+ | `incr / incrBy / decr / decrBy` | 计数器操作 |
73
+ | `mget / mset` | 批量读写 |
74
+ | `scan / keys / type` | Key 检索与类型判断 |
75
+
76
+ ```typescript
77
+ await cache.kv.set('user:123', { name: '张三' }, { ex: 3600 })
78
+ const result = await cache.kv.get<{ name: string }>('user:123')
79
+ if (result.success && result.data) {
80
+ // result.data.name === '张三'
81
+ }
82
+
83
+ await cache.kv.del('user:123')
84
+ ```
85
+
86
+ ### Cluster 多键与扫描
87
+
88
+ `mget/del/exists` 跨 slot 时有界并发且无整体原子性/快照;mget 保留输入顺序,DEL 失败可能已部分删除,重试幂等。`mset`、集合交/并/差和多键 blocking pop 须同 slot,否则返回 `CROSS_SLOT`;使用共同的 `{hash-tag}`,MSET 不做部分写入回退。
89
+
90
+ scan 首次传字符串 `'0'`,后续原样传回不透明游标,返回 `'0'` 表示完成。Cluster 覆盖所有 master;同配置和拓扑的另一应用节点可接续。拓扑、match 或 keyPrefix 改变时返回 `SCAN_TOPOLOGY_CHANGED`,从 `'0'` 重启;无效游标或 count 返回 `INVALID_SCAN`。返回去除 keyPrefix 的逻辑 key,前缀 glob 字符按字面量解释;keys 同样扫描并去重。SCAN 无快照,可能重复,count 仅为正整数提示值。
91
+
92
+ ```ts
93
+ const first = await cache.kv.scan('0', { match: 'users:*', count: 100 })
94
+ if (first.success && first.data[0] !== '0') {
95
+ const next = await cache.kv.scan(first.data[0], { match: 'users:*', count: 100 })
96
+ }
97
+ ```
98
+
99
+ ### Hash/List/Set/ZSet(`cache.hash/list/set_/zset`)
100
+
101
+ - `cache.hash`:对象字段读写(如用户 profile 局部更新)
102
+ - `cache.list`:队列/消息顺序处理
103
+ - `cache.set_`:去重集合(成员关系、权限集合)
104
+ - `cache.zset`:分数排序(排行榜、权重调度)
105
+
106
+ ```typescript
107
+ await cache.hash.hset('profile:1', { nickname: 'alice' })
108
+ await cache.list.lpush('queue:jobs', 'job-1', 'job-2')
109
+ await cache.set_.sadd('role:admin:perms', 'user.read', 'user.write')
110
+ await cache.zset.zadd('rank:daily', { member: 'u1', score: 100 })
111
+ ```
112
+
113
+ ### 分布式锁(`cache.lock`)
114
+
115
+ | 方法 | 说明 |
116
+ | ---------- | ------------------------------------------ |
117
+ | `acquire` | 尝试获锁(SET NX EX),返回唯一 owner 或 null |
118
+ | `release` | 释放锁(必须携带本次 owner,防止误释放) |
119
+ | `isLocked` | 检查锁是否被持有 |
120
+ | `extend` | 续期锁 TTL(必须携带本次 owner) |
121
+
122
+ ```typescript
123
+ // acquire 返回本次唯一 owner,后续释放/续期必须复用该凭据
124
+ const acquired = await cache.lock.acquire('my-lock', { ttl: 30 })
125
+ if (acquired.success && acquired.data) {
126
+ const owner = acquired.data
127
+ try {
128
+ // 长任务仅在仍持有锁时续期;失败或 data=false 时停止依赖锁的后续操作
129
+ const extended = await cache.lock.extend('my-lock', 60, owner)
130
+ if (!extended.success || !extended.data) {
131
+ logger.warn('Lock extension failed; protected work cancelled')
132
+ }
133
+ else {
134
+ // 受保护的操作
135
+ }
136
+ }
137
+ finally {
138
+ await cache.lock.release('my-lock', owner)
139
+ }
140
+ }
141
+
142
+ // 检查
143
+ const locked = await cache.lock.isLocked('my-lock')
144
+ ```
145
+
146
+ **最佳实践:**
147
+
148
+ - `owner` 必须取自成功的 acquire.data;缓存内部每次生成唯一凭据,不能使用 nodeId 替代。释放/续期复用该凭据。
149
+ - 释放锁时传入 `owner` 防止误释放他人锁
150
+ - Memory 后端适合开发/测试;Redis 后端用 Lua 脚本保证 release/extend 原子性
151
+
152
+ ## 错误码 — `HaiCacheError`
153
+
154
+ | 错误码 | code | 说明 |
155
+ |--------|------|------|
156
+ | `HaiCacheError.CONNECTION_FAILED` | `hai:cache:001` | 连接失败 |
157
+ | `HaiCacheError.OPERATION_FAILED` | `hai:cache:002` | 操作失败 |
158
+ | `HaiCacheError.SERIALIZATION_FAILED` | `hai:cache:003` | 序列化失败 |
159
+ | `HaiCacheError.DESERIALIZATION_FAILED` | `hai:cache:004` | 反序列化失败 |
160
+ | `HaiCacheError.KEY_NOT_FOUND` | `hai:cache:005` | 键不存在 |
161
+ | `HaiCacheError.TIMEOUT` | `hai:cache:006` | 超时 |
162
+ | `HaiCacheError.NOT_INITIALIZED` | `hai:cache:010` | 未初始化 |
163
+ | `HaiCacheError.UNSUPPORTED_TYPE` | `hai:cache:011` | 不支持的缓存类型 |
164
+ | `HaiCacheError.CONFIG_ERROR` | `hai:cache:012` | 配置错误 |
165
+ | `HaiCacheError.INVALID_SCAN` | `hai:cache:013` | 游标或 count 无效 |
166
+ | `HaiCacheError.SCAN_TOPOLOGY_CHANGED` | `hai:cache:014` | 拓扑或条件变化,重新遍历 |
167
+ | `HaiCacheError.CROSS_SLOT` | `hai:cache:015` | 多键操作不在同一 slot |
168
+
169
+ ## 常见模式
170
+
171
+ ### 缓存命中与回源(未缓存空值,不防穿透)
172
+
173
+ ```typescript
174
+ async function getUserCached(userId: string) {
175
+ const cached = await cache.kv.get<User>(`user:${userId}`)
176
+ if (cached.success && cached.data)
177
+ return cached.data
178
+
179
+ const user = await userRepo.findById(userId)
180
+ if (user.success && user.data) {
181
+ await cache.kv.set(`user:${userId}`, user.data, { ex: 3600 })
182
+ return user.data
183
+ }
184
+ return null
185
+ }
186
+ ```
187
+
188
+ ### 分布式锁保护共享资源
189
+
190
+ ```typescript
191
+ const lockKey = 'batch:import'
192
+ const acquired = await cache.lock.acquire(lockKey, { ttl: 60 })
193
+ if (acquired.success && acquired.data) {
194
+ const owner = acquired.data
195
+ try {
196
+ await runBatchImportWithConditionalCommit()
197
+ }
198
+ finally {
199
+ await cache.lock.release(lockKey, owner)
200
+ }
201
+ }
202
+ else if (acquired.success) {
203
+ logger.info('Another node is running the import')
204
+ }
205
+ else {
206
+ logger.error('Lock acquisition failed', { code: acquired.error.code })
207
+ }
208
+ ```
209
+
210
+ ## 相关 Skills
211
+
212
+ - `hai-build`:模块初始化顺序(cache 在 iam 之前;cache 自身不依赖 reldb)
213
+ - `hai-core`:配置与 HaiResult 模型
214
+ - `hai-iam`:会话存储与权限缓存(底层使用 cache)
215
+ - `hai-scheduler`:定时任务分布式锁(底层使用 cache.lock)
216
+ - `hai-reach`:消息发送互斥锁(底层使用 cache.lock)
217
+ - `hai-kit`:SvelteKit 集成层
218
+
219
+ Cluster 与 Sentinel 数据节点认证使用 `password`,Cluster 发现的新节点继承同一鉴权配置。`url` 模式只使用 URL 内凭据,单独 password 不覆盖 URL。
220
+
221
+ 单键 compareAndSwap(key, expected, value, {px?,keepTtl?}) 比较 JSON 序列化快照并原子替换,必须检查 success 与 boolean data。expected=undefined 表示不存在,value=undefined 表示删除,null 是值;px 正整数且与 keepTtl 互斥。比较失败不修改 TTL;跨节点版本状态优先使用 CAS 而不是租约后无条件 SET。
222
+
223
+ owner 只校验租约续期/释放,不是资源 fencing token。暂停或过期后旧任务仍可能执行,最终持久化写入必须使用资源自己的 CAS/代际条件/事务约束。批量导入等应用函数须在每次提交时校验条件,不能只靠锁包裹 Promise。
224
+
225
+ ## 生产共享状态
226
+
227
+ 生产仅使用 Redis(含 Cluster);memory 只用于开发/明确测试。Redis 故障返回失败,不回退本机缓存。 NODE_ENV 或 HAI_CORE_ENV 为 production 时在初始化成功前检查,只有 HAI_E2E=1/HAI_E2E_MOCK=1 明确测试豁免。不要将租约当作最终写入条件,外部未知效果须按稳定业务键核对。
228
+
229
+ `kv.set` 返回 `HaiResult<boolean>`:`data=true` 表示实际写入,NX/XX 未命中返回 `success=true,data=false` 且不改变原值或 TTL。签发票据、会话或登记公钥前必须检查这两个字段。`ex/px/exat/pxat` 分别使用秒、毫秒、Unix 秒、Unix 毫秒,须为正安全整数且只能指定一种,与 `keepTtl=true` 互斥;`nx/xx` 也互斥。零、负数、小数、非有限值或溢出返回 `INVALID_SET_OPTIONS`(`cache:016`),不会写成永久键。过去的正绝对时间表示立即过期。省略期限会移除原 TTL;`keepTtl` 保留已有 TTL,新键仍永久保存。memory 和 Redis 都保存 JSON 快照。
@@ -1,377 +1,37 @@
1
1
  ---
2
2
  name: hai-capacitor
3
- description: 使用 @h-ai/capacitor 桥接 Capacitor 原生能力(Token 安全存储、设备信息、推送通知、相机、状态栏),构建 Android/iOS 原生应用;当需求涉及原生 App 开发、Capacitor 集成、安全存储或原生设备功能时使用。
3
+ description: "在 Android/iOS 应用中接入 @h-ai/capacitor 设备、相机、推送与安全 Token 存储,处理 Web/原生差异。"
4
4
  ---
5
5
 
6
6
  # hai-capacitor
7
7
 
8
- > `@h-ai/capacitor` 是 hai-framework 的 Capacitor 原生桥接模块,封装常用原生能力为统一 API,返回 `HaiResult<T>`。与 `@h-ai/api-client` 配合实现 App 端 Token 安全存储。
8
+ ## 能力契约
9
9
 
10
- ---
11
-
12
- ## 运行环境
13
-
14
- > **浏览器端 / 原生 App 专用。** 在 Capacitor 原生环境(Android/iOS)中提供完整能力,纯 Web 环境下部分功能退化(如 Preferences 退化为 localStorage)。
15
-
16
- ---
17
-
18
- ## 适用场景
19
-
20
- - Android/iOS 原生应用开发(SvelteKit + Capacitor)
21
- - Token 安全存储(Capacitor Preferences → SharedPreferences / UserDefaults)
22
- - 设备信息获取(平台、型号、版本)
23
- - 推送通知注册与监听(FCM / APNs)
24
- - 原生相机拍照 / 相册选取
25
- - 状态栏配置(沉浸式、颜色、样式)
26
-
27
- ---
28
-
29
- ## 使用步骤
30
-
31
- ### 1. 初始化与关闭
32
-
33
- ```typescript
34
- import { capacitor } from '@h-ai/capacitor'
35
-
36
- // 应用启动时初始化(检测 Capacitor 环境可用性)
37
- const result = await capacitor.init()
38
- if (!result.success) {
39
- // result.error.code === HaiCapacitorError.NOT_AVAILABLE.code
40
- // 非 Capacitor 环境(纯 Web)
41
- }
42
-
43
- // 检查状态
44
- capacitor.isInitialized // boolean
45
- capacitor.getPlatform() // 'android' | 'ios' | 'web'
46
- capacitor.isNative() // true = 原生 App
47
-
48
- // 关闭模块(重置状态)
49
- await capacitor.close()
50
- ```
51
-
52
- ### 2. Token 安全存储(与 api-client 配合)
53
-
54
- ```typescript
55
- import { api } from '@h-ai/api-client'
56
- import { createCapacitorTokenStorage } from '@h-ai/capacitor'
57
-
58
- await api.init({
59
- baseUrl: import.meta.env.PUBLIC_API_BASE,
60
- auth: {
61
- storage: createCapacitorTokenStorage(),
62
- refreshUrl: '/api/v1/auth/refresh',
63
- },
64
- })
65
- ```
66
-
67
- `createCapacitorTokenStorage()` 返回 `TokenStorage` 实例(兼容 `@h-ai/api-client`),底层使用 `@capacitor/preferences`:
68
-
69
- - Android → SharedPreferences(应用沙盒)
70
- - iOS → UserDefaults
71
- - Web → localStorage(退化,建议仅原生端使用)
72
-
73
- 所有方法内置 try-catch,Preferences 异常时 get 返回 `null`、set/clear 静默失败并记录日志。
74
-
75
- #### Preferences 子操作
76
-
77
- ```typescript
78
- import { capacitor } from '@h-ai/capacitor'
79
-
80
- // 返回 HaiResult<string | null>
81
- const result = await capacitor.preferences.get('my_key')
82
- if (result.success) {
83
- // result.data — 值或 null
84
- }
85
-
86
- await capacitor.preferences.set('my_key', 'value')
87
- await capacitor.preferences.remove('my_key')
88
- ```
89
-
90
- ### 3. 设备信息
91
-
92
- ```typescript
93
- import { capacitor } from '@h-ai/capacitor'
94
-
95
- const info = await capacitor.device.getInfo()
96
- if (info.success) {
97
- info.data.platform // 'android' | 'ios' | 'web'
98
- info.data.model // 'Pixel 7'
99
- info.data.osVersion // '14'
100
- info.data.manufacturer // 'Google'
101
- info.data.isVirtual // false
102
- }
103
-
104
- const version = await capacitor.device.getAppVersion()
105
- if (version.success) {
106
- version.data.version // '1.0.0'
107
- version.data.build // '42'
108
- }
109
- ```
110
-
111
- ### 4. 推送通知
112
-
113
- ```typescript
114
- import { capacitor } from '@h-ai/capacitor'
115
-
116
- // 注册推送(请求权限 + 获取设备 Token)
117
- const reg = await capacitor.push.register()
118
- if (reg.success) {
119
- // 将 reg.data.token 上报给后端
120
- await api.post('/push/register', { token: reg.data.token })
121
- }
122
-
123
- // 监听推送事件(返回 HaiResult 包裹的 async 清理函数)
124
- const listenResult = await capacitor.push.listen({
125
- onReceived: (notification) => {
126
- // 前台收到推送
127
- // notification: { id, title?, body?, data? }
128
- },
129
- onActionPerformed: (notification) => {
130
- // 用户点击推送
131
- },
132
- })
133
-
134
- // 停止监听
135
- if (listenResult.success) {
136
- await listenResult.data()
137
- }
138
- ```
139
-
140
- ### 5. 相机
141
-
142
- ```typescript
143
- import { capacitor } from '@h-ai/capacitor'
144
-
145
- const photo = await capacitor.camera.takePhoto({
146
- quality: 80, // 0-100
147
- source: 'camera', // 'camera' | 'photos' | 'prompt'
148
- resultType: 'base64', // 'uri' | 'base64' | 'dataUrl'
149
- width: 800, // 最大宽度(可选)
150
- height: 600, // 最大高度(可选)
151
- })
152
-
153
- if (photo.success) {
154
- const imgSrc = `data:image/${photo.data.format};base64,${photo.data.data}`
155
- }
156
- ```
157
-
158
- ### 6. 状态栏
159
-
160
- ```typescript
161
- import { capacitor } from '@h-ai/capacitor'
162
-
163
- await capacitor.statusBar.configure({
164
- backgroundColor: '#ffffff',
165
- style: 'dark', // 'dark' | 'light' | 'default'(文字颜色)
166
- overlay: true, // 沉浸式
167
- })
10
+ | 项目 | 契约 |
11
+ | --- | --- |
12
+ | 能力 | 使用 @h-ai/capacitor 接入原生设备、相机、推送、状态栏和安全 Token 存储 |
13
+ | 适用场景 | Android/iOS 原生壳集成与平台差异处理 |
14
+ | 输入 | Capacitor 配置、原生插件、设备权限和平台状态 |
15
+ | 输出 | 原生操作结果及 TokenStorage 适配器 |
16
+ | 限制 | 区分浏览器与 Android/iOS;安全存储需原生插件,Web 使用 httpOnly Cookie/内存认证,不降级到 localStorage。H5 验证不能代替真机验证。 |
168
17
 
169
- await capacitor.statusBar.hide()
170
- await capacitor.statusBar.show()
171
- ```
18
+ ## 使用路径
172
19
 
173
- ---
174
-
175
- ## 核心 API
176
-
177
- | API | 用途 | 返回值 |
178
- | --- | --- | --- |
179
- | `capacitor.init()` | 初始化模块(检测环境) | `HaiResult<void>` |
180
- | `capacitor.close()` | 关闭模块,重置状态 | `Promise<void>` |
181
- | `capacitor.getPlatform()` | 获取当前平台 | `'android' \| 'ios' \| 'web'` |
182
- | `capacitor.isNative()` | 是否为原生环境 | `boolean` |
183
- | `capacitor.isInitialized` | 是否已初始化 | `boolean` |
184
- | `createCapacitorTokenStorage()` | 创建 Token 存储 | `TokenStorage`(兼容 api-client) |
185
- | `capacitor.preferences.get(key)` | 安全读取 Preference | `HaiResult<string \| null>` |
186
- | `capacitor.preferences.set(key, value)` | 安全写入 Preference | `HaiResult<void>` |
187
- | `capacitor.preferences.remove(key)` | 安全删除 Preference | `HaiResult<void>` |
188
- | `capacitor.device.getInfo()` | 设备信息 | `HaiResult<DeviceInfo>` |
189
- | `capacitor.device.getAppVersion()` | 应用版本 | `HaiResult<{ version, build }>` |
190
- | `capacitor.push.register()` | 注册推送 | `HaiResult<PushRegistration>` |
191
- | `capacitor.push.listen(callbacks)` | 监听推送事件 | `HaiResult<() => Promise<void>>`(async 清理函数) |
192
- | `capacitor.camera.takePhoto(options?)` | 拍照 / 选取图片 | `HaiResult<PhotoResult>` |
193
- | `capacitor.statusBar.configure(config)` | 配置状态栏 | `HaiResult<void>` |
194
- | `capacitor.statusBar.show()` | 显示状态栏 | `HaiResult<void>` |
195
- | `capacitor.statusBar.hide()` | 隐藏状态栏 | `HaiResult<void>` |
196
-
197
- ---
198
-
199
- ## 错误码 — `HaiCapacitorError`
200
-
201
- | 错误码 | code | 说明 |
202
- | -------------------------------------------- | ---------------------- | -------------------- |
203
- | `HaiCapacitorError.INIT_FAILED` | `hai:capacitor:001` | 初始化失败 |
204
- | `HaiCapacitorError.NOT_AVAILABLE` | `hai:capacitor:002` | Capacitor 不可用 |
205
- | `HaiCapacitorError.INIT_IN_PROGRESS` | `hai:capacitor:003` | 正在初始化中 |
206
- | `HaiCapacitorError.NOT_INITIALIZED` | `hai:capacitor:010` | 模块未初始化 |
207
- | `HaiCapacitorError.PREFERENCES_GET_FAILED` | `hai:capacitor:011` | Preferences 读取失败 |
208
- | `HaiCapacitorError.PREFERENCES_SET_FAILED` | `hai:capacitor:012` | Preferences 写入失败 |
209
- | `HaiCapacitorError.PREFERENCES_REMOVE_FAILED`| `hai:capacitor:013` | Preferences 删除失败 |
210
- | `HaiCapacitorError.DEVICE_INFO_FAILED` | `hai:capacitor:020` | 获取设备信息失败 |
211
- | `HaiCapacitorError.PUSH_REGISTER_FAILED` | `hai:capacitor:030` | 推送注册失败 |
212
- | `HaiCapacitorError.PUSH_LISTEN_FAILED` | `hai:capacitor:031` | 推送监听失败 |
213
- | `HaiCapacitorError.CAMERA_FAILED` | `hai:capacitor:040` | 拍照/相册失败 |
214
- | `HaiCapacitorError.STATUS_BAR_FAILED` | `hai:capacitor:050` | 状态栏配置失败 |
215
-
216
- ---
217
-
218
- ## 常见模式
219
-
220
- ### Android 应用标准初始化
221
-
222
- ```typescript
223
- // src/lib/capacitor.ts
224
- import { capacitor } from '@h-ai/capacitor'
225
-
226
- export async function initCapacitor() {
227
- const result = await capacitor.init()
228
- if (!result.success) {
229
- return
230
- }
231
-
232
- if (capacitor.isNative()) {
233
- await capacitor.statusBar.configure({
234
- backgroundColor: '#ffffff',
235
- style: 'light',
236
- overlay: false,
237
- })
238
- }
239
- }
240
- ```
241
-
242
- ```svelte
243
- <!-- src/routes/+layout.svelte -->
244
- <script lang="ts">
245
- import { onMount } from 'svelte'
246
- import { initCapacitor } from '$lib/capacitor'
247
-
248
- onMount(() => { initCapacitor() })
249
- </script>
250
- ```
251
-
252
- ### SPA 模式配置(必需)
253
-
254
- Capacitor 应用必须使用 SPA 模式:
255
-
256
- ```typescript
257
- // src/routes/+layout.ts
258
- export const prerender = true
259
- export const ssr = false
260
- ```
261
-
262
- ```javascript
263
- // svelte.config.js
264
- import adapter from '@sveltejs/adapter-static'
265
-
266
- const config = {
267
- kit: {
268
- adapter: adapter({
269
- pages: 'build',
270
- assets: 'build',
271
- fallback: 'index.html',
272
- }),
273
- },
274
- }
275
- ```
20
+ - 先判断平台和插件可用性,复用已有 SPA 入口;原生 UI 变化验证权限拒绝、取消和返回路径。
21
+ - TokenStorage 在原生端使用安全插件;Web/插件不可用或存储失败时拒绝 Promise。调用方处理 setTokens/clear 失败并释放 loading;clear 的实例内屏蔽不替代服务端撤销。
22
+ - 原生打包前确认公开 API 地址的运行配置入口;fullstack App 使用 `public/runtime-config.js`,构建不会读取部署环境文件。这里只放公开地址,不能放 Token 或密钥。
276
23
 
277
- ### Token 存储 + 认证流程
24
+ ## 按需参考
278
25
 
279
- ```typescript
280
- // src/lib/api.ts
281
- import { api } from '@h-ai/api-client'
282
- import { createCapacitorTokenStorage } from '@h-ai/capacitor'
283
-
284
- export async function initApi() {
285
- return api.init({
286
- baseUrl: `${import.meta.env.PUBLIC_API_BASE}/api/v1`,
287
- auth: {
288
- storage: createCapacitorTokenStorage(),
289
- refreshUrl: '/auth/refresh',
290
- },
291
- })
292
- }
293
-
294
- export { api }
295
- ```
296
-
297
- ### 推送通知完整流程
298
-
299
- ```typescript
300
- import { capacitor } from '@h-ai/capacitor'
301
-
302
- export async function setupPush() {
303
- if (!capacitor.isNative()) {
304
- return
305
- }
306
-
307
- const reg = await capacitor.push.register()
308
- if (!reg.success) {
309
- return
310
- }
311
-
312
- // 上报 Token 给后端
313
- await api.post('/push/register', {
314
- token: reg.data.token,
315
- platform: capacitor.getPlatform(),
316
- })
317
-
318
- // 监听推送
319
- const listenResult = await capacitor.push.listen({
320
- onReceived: (n) => {
321
- // 前台通知处理
322
- },
323
- onActionPerformed: (n) => {
324
- // 用户点击跳转
325
- },
326
- })
327
- }
328
- ```
329
-
330
- ### 拍照上传
331
-
332
- ```typescript
333
- import { capacitor } from '@h-ai/capacitor'
334
-
335
- async function captureAndUpload() {
336
- const photo = await capacitor.camera.takePhoto({
337
- source: 'camera',
338
- resultType: 'base64',
339
- quality: 80,
340
- width: 1024,
341
- })
342
-
343
- if (!photo.success) {
344
- return
345
- }
346
-
347
- // 上传 base64 给后端
348
- await api.post('/files/upload', {
349
- data: photo.data.data,
350
- format: photo.data.format,
351
- })
352
- }
353
- ```
354
-
355
- ---
356
-
357
- ## 插件依赖
358
-
359
- | 插件 | 类型 | 用于 |
360
- | --- | --- | --- |
361
- | `@capacitor/core` | peerDependency(必需) | 核心运行时 |
362
- | `@capacitor/preferences` | peerDependency(必需) | Token 存储 |
363
- | `@capacitor/device` | 可选 | `getDeviceInfo()` |
364
- | `@capacitor/app` | 可选 | `getAppVersion()` |
365
- | `@capacitor/push-notifications` | 可选 | `registerPush()` / `listenPush()` |
366
- | `@capacitor/camera` | 可选 | `takePhoto()` |
367
- | `@capacitor/status-bar` | 可选 | `configureStatusBar()` / `show/hide` |
368
-
369
- 可选插件未安装时,对应 API 调用会返回 `err`(动态 import 失败被 catch)。
370
-
371
- ---
26
+ 按任务读取 [reference.md](reference.md) 的对应小节;签名以当前源码或安装版本的公开类型为准,不默认加载全部资料。示例中的业务变量由应用提供。
372
27
 
373
- ## 相关 Skills
28
+ - 运行环境
29
+ - 适用场景
30
+ - 使用步骤
31
+ - 核心 API
32
+ - 错误码 — `HaiCapacitorError`
33
+ - 常见模式
34
+ - 插件依赖
35
+ - 相关 Skills
374
36
 
375
- - `hai-api-client`:HTTP 客户端(Token 管理依赖 capacitor 存储)
376
- - `hai-iam`:认证流程(登录获取 Token → 存储到 Capacitor)
377
- - `hai-ui`:移动端 UI 组件(SafeArea、BottomNav 等)
37
+ 推送仅在实际原生平台调用插件。`push.register({ signal? })` 与 `push.listen(callbacks, { signal? })` 的设置阶段限时 30 秒(包含权限和监听器挂载);失败、超时、取消及 `capacitor.close()` 都会停止回调并移除本次拥有的句柄,迟到的句柄在完成后立即移除,不调用影响其他消费者的 removeAllListeners。listen 成功后信号仍有效,也可调用返回的 cleanup。cleanup 与 close 均返回 `HaiResult<void>`;原生 remove 失败返回 `PUSH_CLEANUP_FAILED`(`capacitor:032`),失败句柄保留供再次调用重试,成功移除的句柄不重复操作。模块关闭后立即不可用;重新初始化前先重试遗留清理。自动化验证控制插件时序,不能代替 Android/iOS 真机 FCM/APNs 权限、注册与反复挂载验收。