@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,557 @@
1
+ # hai-core — 详细用法
2
+
3
+ 从 [SKILL.md](SKILL.md) 选择主题后读取对应小节。代码片段展示 API 用法;省略的业务变量、schema、依赖与 return 上下文需由应用补齐。
4
+
5
+ > `@h-ai/core` 是 hai-framework 的基础模块,提供配置管理、结构化日志、国际化、HaiResult 错误模型、Zod 校验错误本地化与模块生命周期工具。所有其他模块均依赖 core。
6
+
7
+ ## 运行环境
8
+
9
+ **Node.js + 浏览器双端可用。** 构建工具自动选择正确入口(`package.json` exports 条件导出)。
10
+
11
+ | 能力 | Node.js | 浏览器 |
12
+ |------|---------|--------|
13
+ | `core.logger` | ✅ pino(结构化 JSON / pretty) | ✅ loglevel(DevTools console) |
14
+ | `core.config` | ✅ 完整(YAML 加载、watch、validate) | ⚠️ 占位 API;文件配置方法返回 `SERVICE_UNAVAILABLE` |
15
+ | `core.i18n` | ✅ | ✅ |
16
+ | `core.zodValidation` | ✅ | ✅ |
17
+ | `core.id` | ✅ | ✅ |
18
+ | 工具函数 | ✅ | ✅ |
19
+
20
+ ## 适用场景
21
+
22
+ - 项目初始化与配置加载
23
+ - 使用 `core.logger` 记录日志
24
+ - 使用 `core.config` 读取/校验模块配置
25
+ - 使用 `core.i18n` 管理多语言
26
+ - 使用 `core.zodValidation` 将 Zod 默认英文错误映射为模块自己的 i18n 文案
27
+ - 使用 `ok()` / `err()` 构建 HaiResult 类型返回值
28
+ - 创建模块级 logger 或 i18n 消息获取器
29
+
30
+ ## 使用步骤
31
+
32
+ ### 1. 初始化
33
+
34
+ ```typescript
35
+ import { core } from '@h-ai/core'
36
+
37
+ // 自动加载配置目录内所有 .yml / .yaml
38
+ core.init({ configDir: './config' })
39
+
40
+ // 也可指定日志级别和配置监听
41
+ core.init({ configDir: './config', watchConfig: true })
42
+ ```
43
+
44
+ 项目根 `hai.json` 的 `build` / `deploy` 由 CLI 读取;Core 自动加载和监听配置目录内所有 YAML,不设置保留文件名。单项 `config.load` 返回失败时记录错误并继续,应用须 validate 必需配置并检查 success。目录扫描、日志设置等异常仍可能传播,不能把同步 void 当作所有配置加载成功的证明。
45
+
46
+ 生命周期宿主可用 `core.module.createRuntime` 编排真实模块;失败消息保留模块、错误码与配置字段路径,不回显配置值或 SDK 原始异常。启动配置错误附带原因和处理建议:`ext.fields` 配合 `HaiConfigError.CONFIG_ENV_VAR_MISSING.code` 明确提示环境变量未设置,`CONFIG_VALIDATION_ERROR.code` 或 Schema 异常提示校验未通过;只有字段路径时提示配置缺失或无效,不推断缺失。自定义启动钩子缺少必需变量时可抛出带上述错误码和 `ext: { fields: ['变量名'] }` 的异常。即使只打印 `error.message`,也能定位配置项并看到处理方式。
47
+
48
+ ### 2. 使用功能
49
+
50
+ ```typescript
51
+ // 日志
52
+ core.logger.info('Server started', { port: 3000 })
53
+
54
+ // 配置
55
+ const dbConfig = core.config.get('db')
56
+
57
+ // Zod 校验错误本地化
58
+ const formErrors = core.zodValidation.mapZodErrorToFormErrors(zodError, getMessage)
59
+ ```
60
+
61
+ ## 核心 API
62
+
63
+ ### 生命周期
64
+
65
+ | 方法 | 签名 | 说明 |
66
+ | ----------- | --------------------------------- | ----------------------------------------- |
67
+ | `core.init` | `(options?: CoreOptions) => void` | 同步加载运行时 YAML,排除两个 `_deploy` 保留文件 |
68
+
69
+ > `CoreOptions`:`{ logging?: Partial<LoggingConfig>, configDir?: string, watchConfig?: boolean }`
70
+ >
71
+ > 注意:core 没有 `close()` 方法,初始化后持续可用。
72
+
73
+ ### 配置管理 — `core.config`
74
+
75
+ > 浏览器端保留 `core.config` 对象用于类型/runtime 对齐,但没有文件系统:`get()` 返回 `undefined`,`has()` 返回 `false`,`keys()` 返回 `[]`;`load()` / `validate()` / `reload()` 返回 `HaiCommonError.SERVICE_UNAVAILABLE`;`watch()` 会立即回调该错误并返回 no-op 取消函数。
76
+
77
+ | 方法 | 签名 | 说明 |
78
+ | ------------ | -------------------------------------------------------------- | ------------------------------ |
79
+ | `get` | `<T>(name: string) => T \| undefined` | 获取模块配置段 |
80
+ | `getOrThrow` | `<T>(name: string) => T` | 获取配置(未加载时抛异常) |
81
+ | `load` | `<T>(name, filePath, schema?) => HaiResult<T>` | 手动加载配置文件 |
82
+ | `validate` | `<T>(name: string, schema: ZodType) => HaiResult<T>` | 用 Zod Schema 校验已加载的配置 |
83
+ | `has` | `(name: string) => boolean` | 检查配置段是否存在 |
84
+ | `reload` | `(name: string) => HaiResult<unknown>` | 重新从磁盘加载配置 |
85
+ | `clear` | `(name?: string) => void` | 清除配置缓存 |
86
+ | `keys` | `() => string[]` | 获取所有已加载的配置名称 |
87
+ | `watch` | `<T>(name, callback) => () => void` | 监听配置文件变更并自动重载 |
88
+ | `unwatch` | `(name?: string) => void` | 停止配置文件监听 |
89
+ | `isWatching` | `(name: string) => boolean` | 检查是否正在监听某个配置 |
90
+
91
+ **`watch()` 回调处理**:
92
+
93
+ ```typescript
94
+ // watch 回调签名:(config: T | null, error?: HaiError) => void
95
+ // - 成功重载时:传入新配置,error 为 undefined
96
+ // - 重载失败时:config 为 null,error 为错误详情(包含 code 和 message)
97
+
98
+ const unwatch = core.config.watch('db', (cfg, error) => {
99
+ if (error) {
100
+ // 处理重载失败(如文件解析错误),不应更新本地使用的配置
101
+ core.logger.error('Config reload failed', {
102
+ name: 'db',
103
+ code: error.code,
104
+ message: error.message,
105
+ })
106
+ return
107
+ }
108
+ // 使用新配置
109
+ // 注意:此时 core.config.get('db') 已经指向新数据
110
+ core.logger.info('Config updated', { name: 'db' }) // 不记录含密码的完整配置
111
+ })
112
+
113
+ // 调用 unwatch() 停止监听
114
+ unwatch()
115
+ ```
116
+
117
+ 配置文件格式(YAML,支持约定式环境变量映射和显式插值):
118
+
119
+ - YAML 根、对象、数组和叶子节点均可映射为 `HAI_<配置名>_<YAML 路径>`;配置名和 key 转大写、层级以 `_` 分隔,camelCase 不拆词
120
+ - 例如 `core.config.load('ai', ...)` 加载的 `llm.apiKey` 对应 `HAI_AI_LLM_APIKEY`,`llm.models[0].temperature` 对应 `HAI_AI_LLM_MODELS_0_TEMPERATURE`
121
+ - 约定环境变量存在时整体替换对应节点并按 YAML 规则解析;例如 HAI_DB 可注入整段连接配置、HAI_REACH_PROVIDERS 可替换数组。父节点覆盖优先于子节点,覆盖后不再遍历其叶子变量;无父节点覆盖时,只遍历 YAML 已有路径
122
+ - 优先级为父节点约定变量 > 当前节点约定变量 > 显式 `${VAR}` > YAML 默认值;显式语法只用于指定特殊变量名
123
+
124
+ - `${VAR}` — 读取 `process.env.VAR`;缺失则返回 `HaiConfigError.CONFIG_ENV_VAR_MISSING` 错误
125
+ - `${VAR:default}` — 读取 `process.env.VAR`;缺失则使用默认值
126
+ - **类型还原**:整个值恰好是单个变量表达式时,结果还原为原生类型(number / boolean 等);混合文本始终为字符串
127
+ - **空值语义**:`${VAR:}` 或值为空字符串的 `${VAR}` 保持为 `''`,不会被 YAML 解析为 `null`;是否把空字符串视为未配置由模块 Schema 明确定义
128
+
129
+ ```yaml
130
+ # config/_core.yml
131
+ name: my-app
132
+ env: development
133
+ logging:
134
+ level: info
135
+ format: pretty
136
+ feature:
137
+ debug: false
138
+ maxRetries: 3
139
+ # 只有特殊变量名才需要显式语法:
140
+ url: http://${HOST}:${PORT} # → string(混合文本,不还原)
141
+ ```
142
+
143
+ ### 日志 — `core.logger`
144
+
145
+ `core.logger` 既是默认 Logger 实例,也是日志管理的统一入口。
146
+
147
+ `core.init` 加载 `_core.yml.logging`、`configure` 和 `setLevel` 会改变已有默认、模块及嵌套 child Logger 的后续实际输出;不需要重新创建模块 Logger。`create` 显式指定的 level/format/context 保持优先,未指定选项动态继承全局配置;调用时 context 覆盖固定 context,附加 redact 规则统一生效。
148
+
149
+ **日志记录**(实例方法):`trace` / `debug` / `info` / `warn` / `error` / `fatal`
150
+
151
+ ```typescript
152
+ core.logger.info('User created', { userId: '123' })
153
+ core.logger.error('Failed to connect', { error })
154
+ core.logger.debug('Processing item', { id, step: 'validation' })
155
+ ```
156
+
157
+ 原生 `Error` 的 `name/message/stack/cause`、`AggregateError.errors` 与可枚举自有上下文先转成副本,再走字段/URL 脱敏与附加 `redact`;两端原异常均不变。Error 子图循环用 `[Circular]`,达到 32 层用 `[MaxDepth]`,自定义替换值也经过同一规范化;普通对象的循环与替换语义不变。自由文本不会自动解析秘密,可配置 `redact: ['error.message', 'error.stack']` 遮蔽整条诊断路径。
158
+
159
+ **管理方法**:
160
+
161
+ | 方法 | 签名 | 说明 |
162
+ | ----------- | -------------------------------------- | ------------------------ |
163
+ | `create` | `(options?: LoggerOptions) => Logger` | 创建新 Logger 实例 |
164
+ | `child` | `(context: Record<string, unknown>) => Logger` | 创建携带固定上下文的子 Logger |
165
+ | `configure` | `(config: Partial<LoggingConfig>) => void` | 配置全局日志选项(级别、格式等) |
166
+ | `setLevel` | `(level: LogLevel) => void` | 设置全局日志级别 |
167
+ | `getLevel` | `() => LogLevel` | 获取当前全局日志级别 |
168
+
169
+ ```typescript
170
+ // 创建模块级 logger
171
+ const logger = core.logger.create({ name: 'my-module' })
172
+ logger.info('Module initialized')
173
+
174
+ // 创建携带固定上下文的子 logger(自动合并到每条日志)
175
+ const reqLogger = core.logger.child({ requestId: 'req-001' })
176
+ reqLogger.info('Request started') // 日志中自动包含 requestId
177
+
178
+ // 配置输出格式和级别
179
+ core.logger.configure({
180
+ level: 'warn',
181
+ format: 'json',
182
+ redact: ['password', 'token'], // 脱敏字段
183
+ }) // Node.js 支持
184
+ core.logger.setLevel('debug')
185
+ const level = core.logger.getLevel() // 'debug'
186
+ ```
187
+
188
+ **日志级别规范**:
189
+
190
+ | 级别 | 适用场景 |
191
+ | ------- | ---------------------------------- |
192
+ | `trace` | 循环内详细调试数据 |
193
+ | `debug` | 函数进入、参数概要、读操作 |
194
+ | `info` | 业务事件(初始化完成、写操作成功) |
195
+ | `warn` | 异常但可恢复(校验失败、重试) |
196
+ | `error` | 操作失败(需人工排查) |
197
+ | `fatal` | 致命错误(服务无法继续) |
198
+
199
+ ### 国际化 — `core.i18n`
200
+
201
+ | 方法 | 签名 | 说明 |
202
+ | --------------------- | --------------------------------------------------------------------- | -------------- |
203
+ | `getGlobalLocale` | `() => string` | 获取当前语言 |
204
+ | `setGlobalLocale` | `(locale: string) => void` | 浏览器语言/启动默认值;请求内只改当前上下文 |
205
+ | `runWithLocale` | `<T>(locale: string, callback: () => T) => T` | Node 请求/SSR 异步语言隔离 |
206
+ | `createMessageGetter` | `(messages: Record<string, Record<string, string>>) => MessageGetter` | 创建消息获取器 |
207
+
208
+ 创建模块 i18n:
209
+
210
+ ```typescript
211
+ import enUS from '../messages/en-US.json'
212
+ import jaJP from '../messages/ja-JP.json'
213
+ import zhCN from '../messages/zh-CN.json'
214
+
215
+ const m = core.i18n.createMessageGetter({
216
+ 'zh-CN': zhCN,
217
+ 'en-US': enUS,
218
+ 'ja-JP': jaJP,
219
+ })
220
+
221
+ // 使用
222
+ m('user_created') // "用户已创建"
223
+ m('welcome', { params: { name: '张三' } }) // "欢迎,张三"
224
+ ```
225
+
226
+ ### Zod 校验错误映射 — `core.zodValidation`
227
+
228
+ 适用于 `@h-ai/kit`、`@h-ai/serv`、`@h-ai/api-client` 等需要把 Zod 默认英文错误
229
+ 转换为模块自身 i18n 文案的场景。优先复用 `core.zodValidation`,不要在各模块重复维护
230
+ 默认消息正则 / issue 本地化逻辑。
231
+
232
+ | 方法 | 签名 | 说明 |
233
+ |------|------|------|
234
+ | `createPrefixedZodMessageGetter` | `(prefix, getMessage) => ZodMessageGetter` | 按模块前缀自动派生 `serv_validation*` / `kit_validation*` 这类消息 key |
235
+ | `mapZodErrorToFormErrors` | `(error, getMessage) => ValidationFormError[]` | 一步完成提取 + 本地化 + 扁平化 |
236
+
237
+ ```typescript
238
+ import type { ZodMessageGetter } from '@h-ai/core'
239
+ import { core } from '@h-ai/core'
240
+ import { z } from 'zod'
241
+
242
+ const LoginSchema = z.object({
243
+ email: z.string().email(),
244
+ password: z.string().min(8),
245
+ nickname: z.string().min(1, '请填写昵称'),
246
+ })
247
+
248
+ const getMessage: ZodMessageGetter = (key, params) => {
249
+ switch (key) {
250
+ case 'validationEmail':
251
+ return '请输入合法邮箱地址'
252
+ case 'validationStringMin':
253
+ return `至少输入 ${params?.min} 个字符`
254
+ default:
255
+ return '输入不合法'
256
+ }
257
+ }
258
+
259
+ const result = LoginSchema.safeParse({
260
+ email: 'bad',
261
+ password: '123',
262
+ nickname: '',
263
+ })
264
+
265
+ if (!result.success) {
266
+ const getMessage = core.zodValidation.createPrefixedZodMessageGetter(
267
+ 'serv',
268
+ (messageKey, params) => {
269
+ if (messageKey === 'serv_validationEmail')
270
+ return '请输入合法邮箱地址'
271
+ if (messageKey === 'serv_validationStringMin')
272
+ return `至少输入 ${params?.min} 个字符`
273
+ return '输入不合法'
274
+ },
275
+ )
276
+ const errors = core.zodValidation.mapZodErrorToFormErrors(result.error, getMessage)
277
+
278
+ errors[0]?.field // 'email'
279
+ errors[0]?.message // '请输入合法邮箱地址'
280
+ errors[2]?.message // '请填写昵称'(schema 自定义消息原样保留)
281
+ }
282
+ ```
283
+
284
+ ### ID 生成 — `core.id`
285
+
286
+ | 方法 | 签名 | 说明 |
287
+ | -------------- | --------------------------------------- | ----------------------------- |
288
+ | `generate` | `(size?: number) => string` | nanoid(默认 21 字符) |
289
+ | `short` | `() => string` | 10 字符短 ID |
290
+ | `withPrefix` | `(prefix: string, length?: number) => string` | 带前缀的 nanoid |
291
+ | `trace` | `() => string` | `trace-` 前缀 ID |
292
+ | `request` | `() => string` | `req-` 前缀 ID |
293
+ | `uuid` | `() => string` | UUID v4 |
294
+ | `isValidUUID` | `(value: string) => boolean` | 校验 UUID 格式 |
295
+ | `isValidNanoId`| `(value: string, size?: number) => boolean` | 校验 nanoid 格式 |
296
+
297
+ ```typescript
298
+ const id = core.id.generate() // 'V1StGXR_Z5j3eK4uA9b8c'
299
+ const shortId = core.id.short() // 10 字符
300
+ const prefixed = core.id.withPrefix('order_') // 'order_V1StGXR...'
301
+ const traceId = core.id.trace() // 'trace-V1StGXR...'
302
+ const reqId = core.id.request() // 'req-V1StGXR...'
303
+ const uuid = core.id.uuid() // UUID v4
304
+
305
+ core.id.isValidUUID('f47ac10b-...') // true/false
306
+ core.id.isValidNanoId('abc123', 6) // true/false
307
+ ```
308
+
309
+ #### UUID 生成规范(强制)
310
+
311
+ - 生成 UUID **一律用 `core.id.uuid()`**,禁止裸调 `crypto.randomUUID()`。
312
+ - 原因:`crypto.randomUUID` 仅在**安全上下文(HTTPS / localhost)**下可用,生产 http 环境会抛
313
+ `crypto.randomUUID is not a function`;`core.id.uuid()` 仅使用 randomUUID 或密码学安全的 getRandomValues;两者不可用时明确抛错,绝不降级到 Math.random。
314
+ - 需要不带横线的 compact 形式:`core.id.uuid().replaceAll('-', '')`。
315
+ - 代码评审与新建代码时以此为准,发现裸调 `crypto.randomUUID()` 一律改走 `core.id.uuid()`。
316
+
317
+ ### 工具函数
318
+
319
+ #### 类型检查 — `core.typeUtils`
320
+
321
+ `isDefined` / `isObject` / `isFunction` / `isPromise` / `isString` / `isNumber` / `isBoolean` / `isArray`
322
+
323
+ #### 对象操作 — `core.object`
324
+
325
+ `deepClone` / `deepMerge` / `pick` / `omit` / `keys` / `values` / `entries` / `fromEntries`
326
+
327
+ ```typescript
328
+ core.object.deepMerge(a, b, c) // 递归合并(防原型污染)
329
+ core.object.pick(obj, ['a', 'b'])
330
+ core.object.omit(obj, ['c', 'd'])
331
+ ```
332
+
333
+ #### 字符串操作 — `core.string`
334
+
335
+ `capitalize` / `kebabCase` / `camelCase` / `snakeCase` / `pascalCase` / `truncate` / `trim` / `isBlank` / `isNotBlank` / `padStart` / `padEnd` / `constantTimeEqual`
336
+
337
+ ```typescript
338
+ core.string.capitalize('hello') // 'Hello'
339
+ core.string.kebabCase('helloWorld') // 'hello-world'
340
+ core.string.constantTimeEqual(a, b) // Node 使用原生等长比较;浏览器不保证恒时
341
+ ```
342
+
343
+ #### 数组操作 — `core.array`
344
+
345
+ `unique` / `chunk` / `groupBy` / `first` / `last` / `flatten` / `compact` / `shuffle` / `intersection` / `difference`
346
+
347
+ ```typescript
348
+ core.array.unique([1, 1, 2]) // [1, 2]
349
+ core.array.chunk([1, 2, 3, 4], 2) // [[1,2], [3,4]]
350
+ core.array.groupBy(items, item => item.type) // Record<string, T[]>
351
+ core.array.intersection([1, 2], [2, 3]) // [2]
352
+ ```
353
+
354
+ #### 异步操作 — `core.async`
355
+
356
+ `delay` / `withTimeout` / `retry` / `parallel` / `serial` / `debounce` / `throttle`
357
+
358
+ ```typescript
359
+ await core.async.delay(1000)
360
+ await core.async.withTimeout(fetch('/api'), 5000)
361
+ await core.async.retry(fn, { maxRetries: 3, delay: 1000 })
362
+ await core.async.parallel(items, processFn, 5) // 并发限制
363
+ const debouncedFn = core.async.debounce(fn, 300)
364
+ ```
365
+
366
+ #### 时间操作 — `core.time`
367
+
368
+ `formatDate` / `timeAgo` / `now` / `nowSeconds` / `parseDate` / `isValidDate` / `addDays` / `addHours` / `startOfDay` / `endOfDay`
369
+
370
+ ```typescript
371
+ core.time.formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss')
372
+ core.time.timeAgo(new Date(Date.now() - 60000)) // '1 分钟前'
373
+ core.time.addDays(date, 7)
374
+ ```
375
+
376
+ ### HaiResult 模型与错误处理
377
+
378
+ 返回 `HaiResult<T>` 的操作须处理成功/失败分支;core 工具等直接返回值的 API 不套用此模式:
379
+
380
+ ```typescript
381
+ import { ok, err, HaiCommonError } from '@h-ai/core'
382
+
383
+ // 成功
384
+ return ok(data)
385
+
386
+ // 失败
387
+ return err(HaiCommonError.NOT_FOUND, 'Resource not found')
388
+ ```
389
+
390
+ **使用模式**:
391
+
392
+ ```typescript
393
+ const result = await someOperation()
394
+
395
+ // 模式1:直接检查
396
+ if (!result.success) {
397
+ core.logger.error('Operation failed', { error: result.error })
398
+ return result // 直接透传错误
399
+ }
400
+ const data = result.data
401
+
402
+ // 模式2:提前返回
403
+ if (!result.success)
404
+ return result
405
+ // 后续代码可安全使用 result.data
406
+ ```
407
+
408
+ ## 错误码
409
+
410
+ Core 模块定义了两组标准错误码:
411
+
412
+ ### `HaiCommonError`(通用错误)
413
+
414
+ | 错误码 | code | 说明 |
415
+ |--------|------|------|
416
+ | `HaiCommonError.NOT_INITIALIZED` | `hai:common:001` | 模块未初始化 |
417
+ | `HaiCommonError.INIT_FAILED` | `hai:common:002` | 初始化失败 |
418
+ | `HaiCommonError.INIT_IN_PROGRESS` | `hai:common:004` | 正在初始化中 |
419
+ | `HaiCommonError.UNAUTHORIZED` | `hai:common:100` | 未认证 |
420
+ | `HaiCommonError.FORBIDDEN` | `hai:common:101` | 无权限 |
421
+ | `HaiCommonError.TOKEN_EXPIRED` | `hai:common:102` | Token 已过期 |
422
+ | `HaiCommonError.TOKEN_INVALID` | `hai:common:103` | Token 无效 |
423
+ | `HaiCommonError.VALIDATION_ERROR` | `hai:common:200` | 校验失败 |
424
+ | `HaiCommonError.INVALID_REQUEST` | `hai:common:201` | 请求无效 |
425
+ | `HaiCommonError.PARAMETER_MISSING` | `hai:common:202` | 参数缺失 |
426
+ | `HaiCommonError.NOT_FOUND` | `hai:common:300` | 资源不存在 |
427
+ | `HaiCommonError.ALREADY_EXISTS` | `hai:common:301` | 资源已存在 |
428
+ | `HaiCommonError.CONFLICT` | `hai:common:302` | 冲突 |
429
+ | `HaiCommonError.API_ERROR` | `hai:common:400` | API 错误 |
430
+ | `HaiCommonError.NETWORK_ERROR` | `hai:common:401` | 网络错误 |
431
+ | `HaiCommonError.TIMEOUT` | `hai:common:402` | 超时 |
432
+ | `HaiCommonError.SERVICE_UNAVAILABLE` | `hai:common:403` | 服务不可用 |
433
+ | `HaiCommonError.INTERNAL_ERROR` | `hai:common:500` | 内部错误 |
434
+ | `HaiCommonError.DATABASE_ERROR` | `hai:common:501` | 数据库错误 |
435
+ | `HaiCommonError.UNKNOWN_ERROR` | `hai:common:599` | 未知错误 |
436
+
437
+ **使用示例**:
438
+
439
+ ```typescript
440
+ import { HaiCommonError, err } from '@h-ai/core'
441
+
442
+ // 创建错误实例
443
+ err(HaiCommonError.NOT_FOUND, 'User not found')
444
+ err(HaiCommonError.VALIDATION_ERROR, 'Invalid email', validationErrors)
445
+ ```
446
+
447
+ ### `HaiConfigError`(配置错误)
448
+
449
+ | 错误码 | code | 说明 |
450
+ |--------|------|------|
451
+ | `HaiConfigError.CONFIG_FILE_NOT_FOUND` | `hai:core:010` | 配置文件不存在 |
452
+ | `HaiConfigError.CONFIG_PARSE_ERROR` | `hai:core:011` | YAML 解析失败 |
453
+ | `HaiConfigError.CONFIG_VALIDATION_ERROR` | `hai:core:012` | Schema 校验失败 |
454
+ | `HaiConfigError.CONFIG_ENV_VAR_MISSING` | `hai:core:013` | 必需环境变量缺失 |
455
+ | `HaiConfigError.CONFIG_NOT_LOADED` | `hai:core:014` | 配置未加载 |
456
+
457
+ **使用场景**:
458
+
459
+ ```typescript
460
+ import { core, HaiConfigError } from '@h-ai/core'
461
+
462
+ const result = core.config.load('db', './config/db.yml', schema)
463
+ if (!result.success) {
464
+ if (result.error.code === HaiConfigError.CONFIG_FILE_NOT_FOUND.code) {
465
+ core.logger.error('Config file missing')
466
+ }
467
+ else if (result.error.code === HaiConfigError.CONFIG_VALIDATION_ERROR.code) {
468
+ core.logger.error('Config validation failed', { issues: result.error.cause })
469
+ }
470
+ }
471
+ ```
472
+
473
+ ## 常见模式
474
+
475
+ ### 服务端初始化(SvelteKit hooks.server.ts)
476
+
477
+ 在应用已有的 init.ts 中执行 core.init({ configDir: './config' }),然后初始化依赖模块;hooks.server.ts 等待该启动流程完成后接入 kit.createHandle。完整依赖顺序与失败清理见 [hai-build](../hai-build/SKILL.md)。不要在一个文件里同时 import 和声明同名 initModules。
478
+
479
+ ### 配置校验最佳实践
480
+
481
+ ```typescript
482
+ import { z } from 'zod'
483
+
484
+ const MyConfigSchema = z.object({
485
+ apiKey: z.string().min(1),
486
+ timeout: z.number().positive().default(5000),
487
+ })
488
+
489
+ // 模块初始化时校验
490
+ const result = core.config.validate('myModule', MyConfigSchema)
491
+ if (!result.success) {
492
+ core.logger.error('Invalid config', { error: result.error })
493
+ return result
494
+ }
495
+ const config = result.data // 类型安全
496
+ ```
497
+
498
+ ## 相关 Skills
499
+
500
+ - `hai-build`:项目整体架构与技能导航
501
+ - `hai-kit`:SvelteKit 集成层(Handle/Guard/Middleware)
502
+ - `hai-reldb` / `hai-cache` / `hai-iam`:使用 core.config 读取配置的下游模块
503
+
504
+ ## 浏览器侧使用
505
+
506
+ > **禁止在应用中直接引入 `loglevel`。** `core.logger` 在浏览器端自动使用 loglevel 作为后端,API 与 Node.js 完全一致。
507
+
508
+ ### 初始化
509
+
510
+ 浏览器端无文件系统,不需要 `configDir`。在 `+layout.svelte` 或应用入口调用:
511
+
512
+ ```typescript
513
+ import { core } from '@h-ai/core'
514
+
515
+ // 浏览器端:仅传入 logging 配置即可
516
+ core.init({ logging: { level: 'info' } })
517
+ ```
518
+
519
+ ### 日志记录
520
+
521
+ ```typescript
522
+ // 与 Node.js 完全一致的 API
523
+ core.logger.info('Page loaded', { route: '/home' })
524
+ core.logger.error('API call failed', { url, status })
525
+
526
+ // 创建模块级 logger
527
+ const logger = core.logger.create({ name: 'my-page' })
528
+ logger.debug('Data fetched', { count: items.length })
529
+
530
+ // ❌ 禁止直接引用底层日志库
531
+ // import log from 'loglevel' ← 不要这样做
532
+ ```
533
+
534
+ ### 浏览器侧限制
535
+
536
+ | 功能 | 行为 |
537
+ |------|------|
538
+ | `core.config` 文件配置 | 不支持;文件相关方法返回 `SERVICE_UNAVAILABLE`,配置应由服务端读取后下发 |
539
+ | `format: 'json' \| 'pretty'` | 始终输出到 DevTools console;json 为包含 level/msg 的 JSON 字符串,pretty 为可读消息与上下文 |
540
+ | 自定义 `redact` 配置 | 与默认 sanitizeSensitiveFields 同时生效;支持嵌套点/括号路径与 `*`,不修改调用方对象;消息文本需调用方脱敏 |
541
+ | `fatal` 级别 | 映射为 console.error;pretty 带 `[FATAL]` 前缀,json 使用 `level: 'fatal'` |
542
+ | context 输出 | pretty 追加 JSON 上下文,json 合并上下文到结构化 JSON 字符串 |
543
+
544
+ 云资源输出格式与部署配置消费见 [hai-deploy](../hai-deploy/SKILL.md);这里的父节点覆盖规则同样适用。
545
+
546
+ ### URL 日志脱敏
547
+
548
+ 使用 `core.sanitize.sanitizeUrl(url)` 统一处理连接地址;它会遮蔽用户名、密码、敏感 query 参数和 OAuth 键值 fragment。非法地址返回固定占位符。`sanitizeSensitiveFields` 对 URL 类字段使用同一规则;自定义 matcher 同样匹配参数名,不能只遮蔽 userinfo 后记录含 token 的 URL。
549
+
550
+ ```ts
551
+ const safeUrl = core.sanitize.sanitizeUrl("https://example.com/a?token=value&limit=10")
552
+ // https://example.com/a?token=[REDACTED]&limit=10
553
+ ```
554
+
555
+ Node 请求/SSR 必须用 `core.i18n.runWithLocale(locale, callback)`(kit 同名方法)包裹实际异步 resolve;serv 自动建立请求语言上下文。浏览器 setGlobalLocale/createLocaleStore 继续管理应用语言,SSR 的 UI setter/store 不写全局值。显式 MessageOptions.locale 优先;进程默认语言仅在启动时设置。
556
+
557
+ Node 入口的 core.string.constantTimeEqual 将原始 UTF-16 单元编码后使用 node:crypto.timingSafeEqual 比较等长字节,长度不相同时直接 false,长度本身不受保护。浏览器实现仅避免按内容提前返回,不提供 JavaScript 引擎级恒时保证,不用于服务端凭证校验。外围分支、编码和请求处理不因此自动成为恒时。
@@ -0,0 +1,65 @@
1
+ # 请求访问策略与真实客户端地址
2
+
3
+ 用于 Serv/SvelteKit 的每次请求限制、独立策略文件和入口代理排查。先确认应用实际宿主和安装版本,不把 IAM 的登录条件当作全部请求的守卫。
4
+
5
+ ## 装配与默认值
6
+
7
+ 独立文件建议置于 `config/security/` 并显式引用,避免 Core 自动把配置根目录的 YAML 当作业务配置预读。Core 不递归自动加载此子目录;策略始终由宿主创建时验证和编译,改变文件后重建宿主。
8
+
9
+ - Serv:服务端 `_serv.yml` 的 `http.access` / `http.trustedProxies`,转发到 `serv.createApp({ http })`。
10
+ - SvelteKit:服务端 `_kit.yml` 的 `access` / `trustedProxies`,初始化后一次性传给 `kit.createHandle`。仅加载配置不代表安装守卫。
11
+ - `access` 默认 `false`。内联对象与 `{ file: './config/security/request-access.yml' }` 二选一,不能混合。文件按服务工作目录解析,最大 1 MiB,只在创建宿主时读取;缺失、未知字段、重复键、YAML 别名导致启动失败。修改后重建 App/Handle,不在请求中轮询文件。
12
+ - `global` 约束宿主处理的全部请求,包括健康检查;`rules` 按完整 URL pathname 限制指定入口。静态服务器和 S3 直接返回的资源不经过 Node 守卫,另设入口/对象授权。
13
+
14
+ ```yaml
15
+ rules:
16
+ - id: external-api
17
+ paths: [/api/v1/external/**]
18
+ methods: [POST]
19
+ encryption: disabled
20
+ allowIps: [192.0.2.0/24]
21
+ denyIps: [192.0.2.42]
22
+ timezone: Asia/Shanghai
23
+ windows:
24
+ - days: [1, 2, 3, 4, 5]
25
+ start: '09:00'
26
+ end: '18:00'
27
+ ```
28
+
29
+ 全局和所有命中规则取交集;deny 优先。地址/时间列表默认空,不限对应维度;时区默认 UTC。配置了地址限制而无法取得可信地址时拒绝。星期一至日为 1~7,含开始、不含结束,跨午夜按开始日,相同起止无效。路径只支持精确或末尾 `/**`,包含部署 base、大小写敏感;末尾 `/**` 同时匹配该节点和子路径。空 methods 匹配全部,GET 不隐含 HEAD。现有会话、OPTIONS 和密钥交换也受策略约束;不要靠公开认证路径或 transport.excludePaths 绕过它。
30
+
31
+ ## 接口加解密
32
+
33
+ `rules[].encryption` 只控制应用层协议:`required` 强制加密,`disabled` 使用普通 HTTPS 请求响应,省略沿用宿主。disabled 不跳过 IP、时间、认证或业务授权,不能接收框架加密信封;required 优先于宿主 excludePaths。重叠路径/方法的相反模式在装配时失败,不按先后覆盖。没有宿主 transport 却声明 required 同样失败。密钥交换保持框架协议,OPTIONS 不携带业务密文,均继续检查适用访问条件。
34
+
35
+ `core.access.createRequestCheck` 返回可调用检查器;`.encryption(path, method)` 只查询索引,`.requiresEncryption` 供宿主验证必需装配,全部公开类型在 core-types。Core 不执行加解密。没有加密规则时选择器是常量空结果,不增加路径扫描;不要为此增加请求期文件读取或逐条正则。
36
+
37
+ SvelteKit CLI 模板选择 crypto 后可启用 `_kit.yml.transport`;服务端显式装配密钥环和 registry,根 layout 只投影公开 transport 并安装浏览器包装。生产选择 db 和共享数据库,无 db 的内存 registry 仅限开发/测试;不支持的示例明确拒绝配置,不能静默忽略。Fullstack 管理默认强制加密并拒绝 transport:false,外部接口用 scoped disabled 例外。
38
+
39
+ 调用方协议必须匹配服务端。普通外部 HTTP 客户端直接使用 HTTPS;安装全局 fetch 加密的浏览器若需调用明文接口,使用独立接口前缀并同步公开 transport.excludePaths。排除列表按路径段前缀匹配,不能误扩大。服务端访问策略的 IP/时间/文件内容仍不公开,不自动重试或降级协议。
40
+
41
+ ## 真实 IP 的信任链
42
+
43
+ `trustedProxies` 默认 `auto`,普通宿主相当于 `[]`,不信任转发头。只有受管 Compose 设置 `HAI_DEPLOY_PRIVATE_PROXY=1` 且后端私有、存在入口代理时,才编译本容器网络。不要在公开后端或宿主机手动设置这个内部标志。自管入口明确列出实际代理 IP/CIDR;`[]` 显式关闭。
44
+
45
+ Node listener 使用 socket 对端;Fetch 必须传可信平台 `remoteAddress`,不能复制头字段。SvelteKit 从受信平台取得对端,解析后的 `event.getClientAddress()` 与 IAM、审计和限流共用。可信 XFF 从右向左停在首个不可信地址;无效链不回退到一个伪造客户端身份。
46
+
47
+ 生成 Nginx 用 `$remote_addr` 覆盖 XFF/X-Real-IP,客户端伪造头不会直接进入后端。外层负载均衡通过 Docker SSH Provider 的 `trustedEdgeProxies` 显式信任;省略或 `[]` 均不信任上游。源 IP 若已被 rootless 端口转发器抹除,应用不能恢复;实际核对代理与后端日志后再启用白名单。
48
+
49
+ ## 部署与公共边界
50
+
51
+ `.env.<环境>` 或私有覆盖可设置 `HAI_SERV_HTTP_ACCESS='{"file":"./config/security/request-access.yml"}'` / `HAI_KIT_ACCESS=...`。Core 父节点覆盖优先;已有 `HAI_SERV` / `HAI_KIT` 时应修改父对象,不能假定叶子变量会叠加。
52
+
53
+ 部署校验当前选中后端的配置文件,规范化快照放入交付包并参加 SHA-256 校验,容器通过 `/run/hai/request-access.yml` 只读挂载。工程原始引用不回写成容器路径。仅更新前端时保留后端原文件;失败恢复使用旧发布的 Compose/文件。交付 `.env.runtime` 不可随意编辑,配置变化重新打包发布;镜像/配置回退不能撤销数据库和业务效果。
54
+
55
+ 完整 Kit 配置只留在服务端;layout data 只下发 transport 等公开字段,不把策略、代理网段和文件路径用 `?raw` 打入浏览器。
56
+
57
+ Core 工具只从 `core.access` 调用:`createClientIpResolver`、`normalizeClientIp`、`createConditionCheck`、`createRequestCheck`、`loadPolicy`。仅 Node 有执行能力,浏览器无同名伪实现。公共类型以包入口的 `core-types` 为准,不跨包导入内部函数文件。
58
+
59
+ ## 验证与定位
60
+
61
+ 按变更影响验证精确/子路径/前缀、方法、deny 优先、未知 IP、伪造头、窗口边界、已有会话、预检、握手与加密拒绝;增加明文的允许/拒绝、实际密文成功、模式冲突和未装配加密的失败启动。文件覆盖读取一次和无正文泄漏;部署核对全量、后端增量、仅前端保留、模式快照和失败恢复。
62
+
63
+ 规则在启动时编译,路径走索引、CIDR 走 BlockList、时区格式化按分钟复用;热路径不读文件、不解析配置或全表扫规则。新增性能变化用已构建的公开入口测单规则、多路径仅命中一条、无命中、大地址列表及重叠规则;预热后有界批次,报告环境和指标定义,不把批次均值或 mock 当成生产请求尾延迟。
64
+
65
+ 请求拒绝为 HTTP 403 / `hai:common:104`,登录条件拒绝为 `hai:iam:026`;普通加密请求保留响应加密。提示走 ToastContainer,可读原因优先,traceId 默认隐藏、排查图标展开。日志保留规则 ID、原因、可信地址与 requestId,策略正文及敏感数据不返回客户端。