@h-ai/cli 1.0.0-beta.2 → 1.0.0-beta.21

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 (254) hide show
  1. package/README.en.md +74 -154
  2. package/README.ja.md +74 -154
  3. package/README.md +74 -154
  4. package/dist/{chunk-AKV2CQZV.js → chunk-2ZL5ORQ2.js} +316 -97
  5. package/dist/chunk-2ZL5ORQ2.js.map +1 -0
  6. package/dist/{chunk-EF7WOFWZ.js → chunk-L53P43B2.js} +1312 -163
  7. package/dist/chunk-L53P43B2.js.map +1 -0
  8. package/dist/cli-config-templates-LWMD2I6V.js +5 -0
  9. package/dist/{cli-config-templates-HHFHNXBN.js.map → cli-config-templates-LWMD2I6V.js.map} +1 -1
  10. package/dist/{cli-skill-templates-PN4FLGBC.js → cli-skill-templates-D6S2OQ6X.js} +3 -3
  11. package/dist/{cli-skill-templates-PN4FLGBC.js.map → cli-skill-templates-D6S2OQ6X.js.map} +1 -1
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.js +30118 -3253
  14. package/dist/index.js.map +1 -1
  15. package/dist/metafile-esm.json +1 -1
  16. package/package.json +22 -18
  17. package/templates/README.md +45 -30
  18. package/templates/apps/admin/src/routes/+layout.svelte.hbs +16 -10
  19. package/templates/apps/admin/src/routes/+page.svelte.hbs +4 -4
  20. package/templates/apps/admin/src/routes/admin/+layout.svelte.hbs +17 -7
  21. package/templates/apps/admin/src/routes/admin/+page.svelte.hbs +26 -6
  22. package/templates/apps/admin/src/routes/admin/settings/+page.svelte.hbs +2 -2
  23. package/templates/apps/api/.dockerignore.hbs +10 -0
  24. package/templates/apps/api/apps/{{projectName}}-contract/README.md.hbs +8 -0
  25. package/templates/apps/api/apps/{{projectName}}-contract/src/app-schemas.ts.hbs +6 -1
  26. package/templates/apps/api/apps/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +13 -5
  27. package/templates/apps/api/apps/{{projectName}}-contract/tests/contract.test.ts.hbs +13 -5
  28. package/templates/apps/api/apps/{{projectName}}-contract/tsup.config.ts.hbs +3 -1
  29. package/templates/apps/api/apps/{{projectName}}-serv/README.md.hbs +6 -2
  30. package/templates/apps/api/apps/{{projectName}}-serv/config/_serv.yml.hbs +24 -2
  31. package/templates/apps/api/apps/{{projectName}}-serv/package.json.hbs +4 -4
  32. package/templates/apps/api/apps/{{projectName}}-serv/src/app.ts.hbs +74 -24
  33. package/templates/apps/api/apps/{{projectName}}-serv/src/build-metadata.ts.hbs +0 -1
  34. package/templates/apps/api/apps/{{projectName}}-serv/src/lib/server/init.ts.hbs +153 -37
  35. package/templates/apps/api/apps/{{projectName}}-serv/src/server/procedures/index.ts.hbs +39 -13
  36. package/templates/apps/api/apps/{{projectName}}-serv/tests/service.test.ts.hbs +106 -33
  37. package/templates/apps/api/apps/{{projectName}}-serv/tsup.config.ts.hbs +3 -1
  38. package/templates/apps/api/apps/{{projectName}}-serv/vitest.config.ts.hbs +3 -1
  39. package/templates/apps/api/e2e/api-serv.spec.ts.hbs +20 -3
  40. package/templates/apps/api/e2e/capture-evidence.ts.hbs +4 -1
  41. package/templates/apps/api/eslint.config.js.hbs +3 -1
  42. package/templates/apps/api/images/serv.Dockerfile.hbs +15 -10
  43. package/templates/apps/api/playwright.config.ts.hbs +23 -19
  44. package/templates/apps/api/pnpm-workspace.yaml.hbs +27 -16
  45. package/templates/apps/fullstack/.dockerignore.hbs +10 -0
  46. package/templates/apps/fullstack/.gitignore.hbs +7 -2
  47. package/templates/apps/fullstack/apps/{{projectName}}-app/README.md.hbs +14 -12
  48. package/templates/apps/fullstack/apps/{{projectName}}-app/capacitor.config.ts.hbs +5 -3
  49. package/templates/apps/fullstack/apps/{{projectName}}-app/eslint.config.js.hbs +10 -2
  50. package/templates/apps/fullstack/apps/{{projectName}}-app/package.json.hbs +1 -1
  51. package/templates/apps/fullstack/apps/{{projectName}}-app/src/App.svelte.hbs +10 -2
  52. package/templates/apps/fullstack/apps/{{projectName}}-app/src/build-metadata.ts.hbs +0 -1
  53. package/templates/apps/fullstack/apps/{{projectName}}-app/src/lib/capacitor.ts.hbs +0 -1
  54. package/templates/apps/fullstack/apps/{{projectName}}-app/svelte.config.js.hbs +4 -1
  55. package/templates/apps/fullstack/apps/{{projectName}}-app/vite.config.ts.hbs +16 -4
  56. package/templates/apps/fullstack/apps/{{projectName}}-desktop/README.md.hbs +10 -8
  57. package/templates/apps/fullstack/apps/{{projectName}}-desktop/package.json.hbs +3 -3
  58. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/App.svelte.hbs +8 -2
  59. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/build-metadata.ts.hbs +0 -1
  60. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/tauri.conf.json.hbs +0 -2
  61. package/templates/apps/fullstack/apps/{{projectName}}-desktop/svelte.config.js.hbs +4 -1
  62. package/templates/apps/fullstack/apps/{{projectName}}-desktop/vite.config.ts.hbs +16 -4
  63. package/templates/apps/fullstack/apps/{{projectName}}-miniapp/README.md.hbs +2 -0
  64. package/templates/apps/fullstack/apps/{{projectName}}-web/README.md.hbs +9 -9
  65. package/templates/apps/fullstack/apps/{{projectName}}-web/eslint.config.js.hbs +10 -2
  66. package/templates/apps/fullstack/apps/{{projectName}}-web/index.html.hbs +1 -0
  67. package/templates/apps/fullstack/apps/{{projectName}}-web/src/build-metadata.ts.hbs +0 -1
  68. package/templates/apps/fullstack/apps/{{projectName}}-web/src/main.ts.hbs +0 -2
  69. package/templates/apps/fullstack/apps/{{projectName}}-web/svelte.config.js.hbs +4 -1
  70. package/templates/apps/fullstack/apps/{{projectName}}-web/vite.config.ts.hbs +19 -5
  71. package/templates/apps/fullstack/docs/security-configuration.md.hbs +4 -1
  72. package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +140 -28
  73. package/templates/apps/fullstack/e2e/session-close.spec.ts.hbs +19 -5
  74. package/templates/apps/fullstack/eslint.config.js.hbs +3 -1
  75. package/templates/apps/fullstack/images/serv.Dockerfile.hbs +19 -11
  76. package/templates/apps/fullstack/images/web.Dockerfile.hbs +17 -8
  77. package/templates/apps/fullstack/package.json.hbs +2 -1
  78. package/templates/apps/fullstack/packages/{{projectName}}-contract/README.md.hbs +7 -5
  79. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-contract.ts.hbs +114 -23
  80. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-schemas.ts.hbs +57 -11
  81. package/templates/apps/fullstack/packages/{{projectName}}-contract/tsup.config.ts.hbs +3 -1
  82. package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +17 -7
  83. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_reach.yml.hbs +13 -7
  84. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_serv.yml.hbs +17 -7
  85. package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +10 -4
  86. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/app-server.ts.hbs +65 -30
  87. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/build-metadata.ts.hbs +0 -1
  88. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/index.ts.hbs +1 -2
  89. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/admin-service.ts.hbs +69 -21
  90. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/business-settings.ts.hbs +21 -5
  91. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/admin-procedures.ts.hbs +63 -11
  92. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/app-procedures.ts.hbs +6 -1
  93. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/index.ts.hbs +3 -1
  94. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/runtime.ts.hbs +147 -33
  95. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/security-roles.ts.hbs +43 -12
  96. package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/app-server.test.ts.hbs +146 -30
  97. package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/runtime.test.ts.hbs +33 -10
  98. package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/security.test.ts.hbs +142 -26
  99. package/templates/apps/fullstack/packages/{{projectName}}-serv/tsup.config.ts.hbs +6 -2
  100. package/templates/apps/fullstack/packages/{{projectName}}-serv/vitest.config.ts.hbs +3 -1
  101. package/templates/apps/fullstack/packages/{{projectName}}-shared/README.md.hbs +48 -66
  102. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/en-US.json.hbs +1 -0
  103. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/ja-JP.json.hbs +1 -0
  104. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/zh-CN.json.hbs +1 -0
  105. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/api-client.ts.hbs +9 -2
  106. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/feedback-client.ts.hbs +0 -3
  107. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/sensitive-actions.svelte.ts.hbs +15 -3
  108. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AppShell.svelte.hbs +33 -7
  109. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/FeedbackEntry.svelte.hbs +16 -2
  110. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/audit.svelte.hbs +104 -13
  111. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/feedback.svelte.hbs +37 -7
  112. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/roles.svelte.hbs +9 -3
  113. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/settings.svelte.hbs +25 -3
  114. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/users.svelte.hbs +133 -19
  115. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/security/role-label.ts.hbs +14 -2
  116. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/guide-store.ts.hbs +66 -34
  117. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/management-store.svelte.ts.hbs +132 -30
  118. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/theme-store.svelte.ts.hbs +8 -2
  119. package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/api-client.test.ts.hbs +23 -5
  120. package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/management-store.test.ts.hbs +143 -21
  121. package/templates/apps/fullstack/packages/{{projectName}}-shared/vitest.config.ts.hbs +7 -2
  122. package/templates/apps/fullstack/playwright.config.ts.hbs +25 -3
  123. package/templates/apps/fullstack/pnpm-workspace.yaml.hbs +30 -14
  124. package/templates/apps/h5/src/routes/+layout.svelte.hbs +74 -30
  125. package/templates/apps/h5/src/routes/+page.svelte.hbs +2 -2
  126. package/templates/apps/h5/src/routes/discover/+page.svelte.hbs +2 -2
  127. package/templates/apps/h5/src/routes/profile/+page.svelte.hbs +2 -2
  128. package/templates/apps/mobile-app/capacitor.config.ts.hbs +5 -2
  129. package/templates/apps/mobile-app/messages/en-US.json +2 -2
  130. package/templates/apps/mobile-app/messages/ja-JP.json +2 -2
  131. package/templates/apps/mobile-app/messages/zh-CN.json +2 -2
  132. package/templates/apps/mobile-app/src/App.svelte.hbs +17 -5
  133. package/templates/apps/mobile-app/src/lib/api.ts.hbs +20 -6
  134. package/templates/apps/mobile-app/src/lib/app-config.ts.hbs +8 -1
  135. package/templates/apps/mobile-app/src/lib/pages/home.svelte.hbs +6 -2
  136. package/templates/apps/mobile-app/src/lib/pages/profile.svelte.hbs +13 -1
  137. package/templates/apps/mobile-app/src/lib/pages/tasks.svelte.hbs +5 -1
  138. package/templates/apps/website/scripts/static-website.mjs.hbs +19 -6
  139. package/templates/apps/website/src/routes/+layout.svelte.hbs +56 -29
  140. package/templates/apps/website/src/routes/+page.svelte.hbs +4 -4
  141. package/templates/apps/website/src/routes/about/+page.svelte.hbs +2 -2
  142. package/templates/apps/website/src/routes/contact/+page.svelte.hbs +2 -2
  143. package/templates/apps/website/src/routes/services/+page.svelte.hbs +20 -5
  144. package/templates/base/.dockerignore.hbs +10 -0
  145. package/templates/base/.gitignore.hbs +7 -2
  146. package/templates/base/e2e/app.spec.ts.hbs +130 -36
  147. package/templates/base/eslint-rules.js +44 -25
  148. package/templates/base/eslint.config.js.hbs +3 -1
  149. package/templates/base/images/web.Dockerfile.hbs +25 -14
  150. package/templates/base/package.json.hbs +13 -7
  151. package/templates/base/patches/daisyui-5.7.50.patch +8 -0
  152. package/templates/base/patches/deepmerge-4.3.1.patch +51 -0
  153. package/templates/base/playwright.config.ts +3 -1
  154. package/templates/base/pnpm-workspace.yaml.hbs +33 -16
  155. package/templates/base/src/app.d.ts.hbs +1 -1
  156. package/templates/base/src/app.html.hbs +1 -0
  157. package/templates/base/src/hooks.server.ts.hbs +44 -33
  158. package/templates/base/src/lib/build-metadata.ts.hbs +0 -1
  159. package/templates/base/src/lib/server/init.ts.hbs +146 -35
  160. package/templates/base/src/lib/server/kit-config.ts.hbs +7 -4
  161. package/templates/base/src/routes/+layout.server.ts.hbs +2 -2
  162. package/templates/base/svelte.config.js.hbs +10 -100
  163. package/templates/base/tests/scaffold.test.ts.hbs +12 -3
  164. package/templates/base/tsconfig.json.hbs +7 -4
  165. package/templates/base/vite.config.ts.hbs +108 -14
  166. package/templates/base/vitest.config.ts.hbs +6 -2
  167. package/templates/features/ai/routes/api/chat/+server.ts +3 -1
  168. package/templates/features/iam/routes-admin/(auth)/auth/forgot-password/+page.svelte.hbs +3 -3
  169. package/templates/features/iam/routes-admin/(auth)/auth/login/+page.svelte.hbs +3 -3
  170. package/templates/features/iam/routes-admin/(auth)/auth/register/+page.svelte.hbs +3 -3
  171. package/templates/features/iam/routes-admin/(auth)/auth/reset-password/+page.svelte.hbs +3 -3
  172. package/templates/features/iam/routes-h5/auth/forgot-password/+page.svelte.hbs +3 -3
  173. package/templates/features/iam/routes-h5/auth/login/+page.svelte.hbs +3 -3
  174. package/templates/features/iam/routes-h5/auth/register/+page.svelte.hbs +3 -3
  175. package/templates/features/iam/routes-h5/auth/reset-password/+page.svelte.hbs +3 -3
  176. package/templates/features/iam/routes-website/auth/forgot-password/+page.svelte.hbs +3 -3
  177. package/templates/features/iam/routes-website/auth/login/+page.svelte.hbs +3 -3
  178. package/templates/features/iam/routes-website/auth/register/+page.svelte.hbs +3 -3
  179. package/templates/features/iam/routes-website/auth/reset-password/+page.svelte.hbs +3 -3
  180. package/templates/features/payment/routes/api/v1/payment/create/+server.ts +14 -3
  181. package/templates/shared/browser-check/startup.js +115 -0
  182. package/templates/shared/browser-check/update.css +37 -0
  183. package/templates/shared/browser-check/update.html +19 -0
  184. package/templates/shared/browser-startup.spec.ts +23 -0
  185. package/templates/shared/build-metadata.ts +18 -4
  186. package/templates/shared/e2e-env.ts +22 -6
  187. package/templates/shared/native-name.d.mts +5 -0
  188. package/templates/shared/native-name.mjs +94 -0
  189. package/templates/shared/public-base-path.mjs +17 -4
  190. package/templates/shared/run-e2e.mjs +46 -12
  191. package/templates/shared/run-node.mjs +56 -0
  192. package/templates/shared/run-tauri.mjs +74 -0
  193. package/templates/shared/vite-runtime-config.ts +9 -3
  194. package/templates/skills/AGENTS.md +10 -73
  195. package/templates/skills/bridges/admin/AGENTS.md +9 -65
  196. package/templates/skills/bridges/api/AGENTS.md +8 -59
  197. package/templates/skills/bridges/fullstack/AGENTS.md.hbs +9 -54
  198. package/templates/skills/bridges/h5/AGENTS.md +8 -63
  199. package/templates/skills/bridges/mobile-app/AGENTS.md +8 -62
  200. package/templates/skills/bridges/website/AGENTS.md +8 -63
  201. package/templates/skills/hai-ai/SKILL.md +6 -2
  202. package/templates/skills/hai-ai/acp.md +153 -0
  203. package/templates/skills/hai-ai/guide.md +27 -12
  204. package/templates/skills/hai-ai/reference.md +24 -15
  205. package/templates/skills/hai-ai/resources.md +69 -0
  206. package/templates/skills/hai-api-client/SKILL.md +1 -1
  207. package/templates/skills/hai-api-client/reference.md +3 -1
  208. package/templates/skills/hai-app-create/collaboration.md +7 -0
  209. package/templates/skills/hai-app-create/development.md +19 -10
  210. package/templates/skills/hai-app-create/project.md +33 -0
  211. package/templates/skills/hai-app-create/reference.md +10 -10
  212. package/templates/skills/hai-app-tests/reference.md +1 -1
  213. package/templates/skills/hai-app-tests/validation.md +1 -0
  214. package/templates/skills/hai-build/SKILL.md +19 -9
  215. package/templates/skills/hai-build/paths.md +4 -2
  216. package/templates/skills/hai-build/reference.md +26 -8
  217. package/templates/skills/hai-cache/reference.md +6 -2
  218. package/templates/skills/hai-capacitor/SKILL.md +1 -0
  219. package/templates/skills/hai-capacitor/reference.md +24 -0
  220. package/templates/skills/hai-ci/SKILL.md +3 -0
  221. package/templates/skills/hai-core/SKILL.md +9 -4
  222. package/templates/skills/hai-core/reference.md +40 -10
  223. package/templates/skills/hai-core/request-access.md +2 -2
  224. package/templates/skills/hai-crypto/SKILL.md +2 -2
  225. package/templates/skills/hai-crypto/reference.md +7 -3
  226. package/templates/skills/hai-deploy/SKILL.md +41 -5
  227. package/templates/skills/hai-deploy/middleware.md +26 -14
  228. package/templates/skills/hai-framework-sync/SKILL.md +13 -9
  229. package/templates/skills/hai-framework-sync/sync.md +2 -0
  230. package/templates/skills/hai-iam/reference.md +2 -2
  231. package/templates/skills/hai-kit/SKILL.md +1 -1
  232. package/templates/skills/hai-kit/reference.md +19 -5
  233. package/templates/skills/hai-payment/reference.md +41 -17
  234. package/templates/skills/hai-reach/SKILL.md +3 -1
  235. package/templates/skills/hai-reach/reference.md +29 -9
  236. package/templates/skills/hai-reldb/SKILL.md +1 -1
  237. package/templates/skills/hai-reldb/reference.md +9 -2
  238. package/templates/skills/hai-scheduler/reference.md +1 -1
  239. package/templates/skills/hai-serv/SKILL.md +2 -1
  240. package/templates/skills/hai-serv/reference.md +26 -15
  241. package/templates/skills/hai-storage/reference.md +23 -6
  242. package/templates/skills/hai-ui/SKILL.md +11 -6
  243. package/templates/skills/hai-ui/charts.md +51 -0
  244. package/templates/skills/hai-ui/guide.md +1 -1
  245. package/templates/skills/hai-ui/reference.md +58 -38
  246. package/templates/skills/hai-vecdb/reference.md +8 -3
  247. package/dist/chunk-AKV2CQZV.js.map +0 -1
  248. package/dist/chunk-EF7WOFWZ.js.map +0 -1
  249. package/dist/chunk-MUHRBJSW.js +0 -29272
  250. package/dist/chunk-MUHRBJSW.js.map +0 -1
  251. package/dist/cli-config-templates-HHFHNXBN.js +0 -5
  252. package/dist/src-TEBHR5I5.js +0 -5
  253. package/dist/src-TEBHR5I5.js.map +0 -1
  254. package/templates/apps/fullstack/playwright.session-close.config.ts.hbs +0 -18
@@ -1,5 +1,7 @@
1
+ ARG HAI_NODE_IMAGE=node:24.22.1-bookworm-slim
2
+ ARG HAI_NGINX_IMAGE=nginxinc/nginx-unprivileged:1.29.8-alpine
1
3
  {{#if isSvelteOnlyApp}}
2
- FROM node:24.22.1-bookworm-slim AS build
4
+ FROM ${HAI_NODE_IMAGE} AS build
3
5
 
4
6
  ENV PNPM_HOME=/pnpm
5
7
  ENV PATH=$PNPM_HOME:$PATH
@@ -7,30 +9,33 @@ ENV CI=true
7
9
  ENV ONNXRUNTIME_NODE_INSTALL_CUDA=skip
8
10
  WORKDIR /workspace
9
11
 
10
- RUN corepack enable && corepack prepare pnpm@12.11.2 --activate && pnpm config set store-dir /pnpm/store
12
+ ARG HAI_NPM_REGISTRY=https://registry.npmjs.org
13
+ ARG COREPACK_NPM_REGISTRY=$HAI_NPM_REGISTRY
14
+ ARG npm_config_registry=$HAI_NPM_REGISTRY
15
+ ARG pnpm_config_registry=$HAI_NPM_REGISTRY
16
+ RUN node -e "const p=process.env.HTTPS_PROXY||process.env.HTTP_PROXY;if(p){const u=new URL(p);const s=require('node:net').connect({host:u.hostname,port:Number(u.port||(u.protocol==='https:'?443:80))});s.setTimeout(3000);s.on('connect',()=>s.end());const fail=()=>{process.stderr.write('Build proxy is unreachable from the container. Check the host address and proxy listener.\\n');process.exit(1)};s.on('error',fail);s.on('timeout',fail)}" && corepack enable && corepack prepare pnpm@12.11.2 --activate && pnpm config set store-dir /pnpm/store
11
17
  COPY pnpm-lock.yaml pnpm-workspace.yaml ./
12
18
  COPY images/dependencies/ ./
13
- RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm fetch --ignore-scripts
19
+ RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm fetch --reporter=append-only --ignore-scripts
20
+ RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm install --reporter=append-only --offline --frozen-lockfile --ignore-scripts
14
21
  COPY . .
15
- RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm install --offline --frozen-lockfile --ignore-scripts
16
22
  ARG HAI_BUILD_ID=
17
23
  ARG HAI_BUILD_COMMIT=unknown
18
24
  ARG PUBLIC_BASE_PATH=
19
25
  RUN HAI_BUILD_ID="$HAI_BUILD_ID" HAI_BUILD_COMMIT="$HAI_BUILD_COMMIT" PUBLIC_BASE_PATH="$PUBLIC_BASE_PATH" pnpm compile
20
26
 
21
- FROM nginxinc/nginx-unprivileged:1.29.8-alpine AS runtime
27
+ FROM ${HAI_NGINX_IMAGE} AS runtime
22
28
 
23
29
  COPY --chmod=755 images/web/19-runtime-config.sh /docker-entrypoint.d/19-hai-runtime-config.sh
24
30
  COPY images/web/nginx.conf /etc/nginx/conf.d/default.conf
25
31
  COPY --from=build /workspace/dist /usr/share/nginx/html
32
+ RUN find /usr/share/nginx/html -type f -name '*.map' -delete
26
33
 
27
34
  EXPOSE 8080
28
35
  HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
29
36
  CMD wget -q -O /dev/null http://127.0.0.1:8080/health || exit 1
30
37
  {{else}}
31
- FROM node:24.22.1-bookworm-slim AS build
32
- ARG SQLITE_PREBUILD_MIRROR=
33
- ENV npm_config_better_sqlite3_binary_host_mirror=$SQLITE_PREBUILD_MIRROR
38
+ FROM ${HAI_NODE_IMAGE} AS build
34
39
 
35
40
  ENV PNPM_HOME=/pnpm
36
41
  ENV PATH=$PNPM_HOME:$PATH
@@ -38,20 +43,26 @@ ENV CI=true
38
43
  ENV ONNXRUNTIME_NODE_INSTALL_CUDA=skip
39
44
  WORKDIR /workspace
40
45
 
41
- RUN corepack enable && corepack prepare pnpm@12.11.2 --activate && pnpm config set store-dir /pnpm/store
46
+ ARG HAI_NPM_REGISTRY=https://registry.npmjs.org
47
+ ARG COREPACK_NPM_REGISTRY=$HAI_NPM_REGISTRY
48
+ ARG npm_config_registry=$HAI_NPM_REGISTRY
49
+ ARG pnpm_config_registry=$HAI_NPM_REGISTRY
50
+ RUN node -e "const p=process.env.HTTPS_PROXY||process.env.HTTP_PROXY;if(p){const u=new URL(p);const s=require('node:net').connect({host:u.hostname,port:Number(u.port||(u.protocol==='https:'?443:80))});s.setTimeout(3000);s.on('connect',()=>s.end());const fail=()=>{process.stderr.write('Build proxy is unreachable from the container. Check the host address and proxy listener.\\n');process.exit(1)};s.on('error',fail);s.on('timeout',fail)}" && corepack enable && corepack prepare pnpm@12.11.2 --activate && pnpm config set store-dir /pnpm/store
42
51
  COPY pnpm-lock.yaml pnpm-workspace.yaml ./
43
52
  COPY images/dependencies/ ./
44
- RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm fetch --ignore-scripts
53
+ RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm fetch --reporter=append-only --ignore-scripts
54
+ RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm install --reporter=append-only --offline --frozen-lockfile --ignore-scripts
45
55
  COPY . .
46
- RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm install --offline --frozen-lockfile --ignore-scripts
47
56
  ARG HAI_BUILD_ID=
48
57
  ARG HAI_BUILD_COMMIT=unknown
49
58
  ARG PUBLIC_BASE_PATH=
50
59
  RUN HAI_BUILD_ID="$HAI_BUILD_ID" HAI_BUILD_COMMIT="$HAI_BUILD_COMMIT" PUBLIC_BASE_PATH="$PUBLIC_BASE_PATH" pnpm compile
51
- RUN --mount=type=cache,id={{projectName}}-sqlite,target=/root/.npm/_prebuilds if [ -d node_modules/better-sqlite3 ]; then cd node_modules/better-sqlite3; for attempt in 1 2 3; do node -e "require('node:child_process').execFileSync(process.execPath,[require.resolve('prebuild-install/bin.js'),'--verbose'],{stdio:'inherit'})" && break; [ "$attempt" = 3 ] && exit 1; sleep 3; done; fi
52
- RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store --mount=type=cache,id={{projectName}}-sqlite,target=/root/.npm/_prebuilds pnpm pm deploy --filter {{projectName}} --prod /prod/app
60
+ # SQLite 13 的原生二进制随 npm 包交付,在构建时验证实际加载。
61
+ RUN if [ -d node_modules/better-sqlite3 ]; then node -e "const Database=require('better-sqlite3');const db=new Database(':memory:');db.prepare('SELECT 1').get();db.close()"; fi
62
+ RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm pm deploy --filter {{projectName}} --prod /prod/app
63
+ RUN rm -f /prod/app/README* && find /prod/app/build -type f \( -name '*.map' -o -name '*.d.ts' -o -name '*.d.mts' -o -name '*.d.cts' \) -delete
53
64
 
54
- FROM node:24.22.1-bookworm-slim AS runtime-base
65
+ FROM ${HAI_NODE_IMAGE} AS runtime-base
55
66
 
56
67
  ARG PUBLIC_BASE_PATH=
57
68
  ENV PUBLIC_BASE_PATH=$PUBLIC_BASE_PATH
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "engines": { "node": "^22.23.4 || ^24.22.1 || ^26.12.1" },
3
3
  "name": "{{projectName}}",
4
- "version": "1.0.0-beta.2",
4
+ "version": "1.0.0-beta.21",
5
5
  "private": true,
6
6
  "packageManager": "pnpm@12.11.2",
7
7
  "description": "{{#if_eq appType 'admin'}}Enterprise management system built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'website'}}Enterprise website built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'h5'}}Mobile H5 app built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'api'}}REST API service built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'mobile-app'}}Mobile app built with hai Agent Framework{{/if_eq}}",
8
8
  "keywords": ["hai", {{#unless isSvelteOnlyApp}}"sveltekit", {{/unless}}"svelte5", "{{appType}}"],
9
9
  "license": "Apache-2.0",
10
10
  "type": "module",
11
+ "imports": { "#lib/*": "./src/lib/*" },
11
12
  {{#unless isSvelteOnlyApp}}
12
13
  "files": [
13
14
  "build",
@@ -29,8 +30,8 @@
29
30
  "deploy": "hai deploy",
30
31
  {{/if}}
31
32
  {{#unless isSvelteOnlyApp}}
32
- "start": "node --env-file=.env --env-file=.env.prod --env-file-if-exists=.env.local build/index.js",
33
- "start:test": "node --env-file=.env --env-file=.env.test --env-file-if-exists=.env.local build/index.js",
33
+ "start": "node scripts/run-node.mjs prod . build/index.js",
34
+ "start:test": "node scripts/run-node.mjs test . build/index.js",
34
35
  "start:prod": "pnpm start",
35
36
  {{/unless}}
36
37
  "preview": "vite preview",
@@ -38,10 +39,10 @@
38
39
  "typecheck": "{{#if hasI18n}}pnpm paraglide:compile && {{/if}}{{#if isSvelteOnlyApp}}svelte-check --tsconfig ./tsconfig.json{{else}}svelte-kit sync && svelte-check --tsconfig ./tsconfig.json{{/if}}",
39
40
  "lint": "eslint .",
40
41
  "lint:fix": "eslint . --fix",
41
- "test": "{{#if hasI18n}}pnpm paraglide:compile && {{/if}}vitest run",
42
- "test:watch": "vitest",
42
+ "test": "{{#if hasI18n}}pnpm paraglide:compile && {{/if}}{{#unless isSvelteOnlyApp}}svelte-kit sync && {{/unless}}vitest run",
43
+ "test:watch": "{{#if hasI18n}}pnpm paraglide:compile && {{/if}}{{#unless isSvelteOnlyApp}}svelte-kit sync && {{/unless}}vitest",
43
44
  "test:e2e": "node scripts/run-e2e.mjs",
44
- "clean": "{{#if isSvelteOnlyApp}}rimraf dist build android ios .turbo src/lib/paraglide{{else}}rimraf .svelte-kit build .turbo{{/if}}"{{#if isCapacitorApp}},
45
+ "clean": "{{#if isSvelteOnlyApp}}rimraf dist build .turbo src/lib/paraglide{{else}}rimraf .svelte-kit build .turbo{{/if}}"{{#if isCapacitorApp}},
45
46
  "cap:add:android": "cap add android",
46
47
  "cap:add:ios": "cap add ios",
47
48
  "cap:sync": "pnpm compile && cap sync",
@@ -56,7 +57,9 @@
56
57
  "cap:build:ios": "pnpm compile && cap sync ios && cap build ios"{{/if}}
57
58
  },
58
59
  "dependencies": {
60
+ {{#unless isSvelteOnlyApp}}
59
61
  "pino-pretty": "{{versions.pinoPretty}}",
62
+ {{/unless}}
60
63
  {{#if isSvelteOnlyApp}}
61
64
  "@h-ai/api-client": "{{haiPackageSpecifier}}",
62
65
  "@h-ai/capacitor": "{{haiPackageSpecifier}}",
@@ -85,7 +88,7 @@
85
88
  "@h-ai/capacitor": "{{haiPackageSpecifier}}"{{/if}}{{#if isCapacitorApp}}{{#unless features.api-client}},
86
89
  "@h-ai/api-client": "{{haiPackageSpecifier}}"{{/unless}}{{#unless features.capacitor}},
87
90
  "@h-ai/capacitor": "{{haiPackageSpecifier}}"{{/unless}}{{/if}},
88
- "sm-crypto": "0.5.7",
91
+ "sm-crypto": "0.5.8",
89
92
  "zod": "{{versions.zod}}"
90
93
  {{/if}}
91
94
  },
@@ -96,6 +99,9 @@
96
99
  "@h-ai/cli": "{{haiPackageSpecifier}}",
97
100
  {{#if isSvelteOnlyApp}}
98
101
  "@h-ai/core": "{{haiPackageSpecifier}}",
102
+ {{#if features.iam}}
103
+ "@h-ai/api-contract": "{{haiPackageSpecifier}}",
104
+ {{/if}}
99
105
  {{/if}}
100
106
  "@antfu/eslint-config": "{{versions.antfuEslintConfig}}",
101
107
  "@playwright/test": "{{versions.playwright}}",
@@ -0,0 +1,8 @@
1
+ diff --git a/utilities/join/object.js b/utilities/join/object.js
2
+ --- a/utilities/join/object.js
3
+ +++ b/utilities/join/object.js
4
+ @@ -1 +1 @@
5
+ -export default {".join":{"display":"inline-flex","align-items":"stretch","--join-ss":"0","--join-se":"0","--join-es":"0","--join-ee":"0","--join-ml":"0","--join-mt":"0","--join-v":"0","--join-h":"1","@scope (&)":{"> :where(:focus, :has(:focus))":{"z-index":2},"@media (hover: hover)":{"> :where(.btn:hover, :has(.btn:hover))":{"z-index":1}},":where(:scope > :first-child)":{"--join-ss":"var(--radius-field)","--join-se":"calc(var(--radius-field) * var(--join-v))","--join-es":"calc(var(--radius-field) * var(--join-h))","--join-ee":"0"},":where(:scope > :last-child)":{"--join-ss":"0","--join-se":"calc(var(--radius-field) * var(--join-h))","--join-es":"calc(var(--radius-field) * var(--join-v))","--join-ee":"var(--radius-field)"},":where(:scope > :only-child)":{"--join-ss":"var(--radius-field)","--join-se":"var(--radius-field)","--join-es":"var(--radius-field)","--join-ee":"var(--radius-field)"},":where(:scope > :not(:first-child))":{"--join-ml":"calc(var(--border, 1px) * -1 * var(--join-h))","--join-mt":"calc(var(--border, 1px) * -1 * var(--join-v))"}}},".join-item":{"@layer daisyui.l1.l2.l3.l4":{"> *":{"--join-ss":"initial","--join-se":"initial","--join-es":"initial","--join-ee":"initial"}},"border-style":"solid","border-width":"var(--border, 1px)","border-start-start-radius":"var(--join-ss)","border-start-end-radius":"var(--join-se)","border-end-start-radius":"var(--join-es)","border-end-end-radius":"var(--join-ee)","&:not(:disabled, [disabled], .btn-disabled)":{"margin-inline-start":"var(--join-ml, 0)","margin-block-start":"var(--join-mt, 0)"},"&:is(:disabled, [disabled], .btn-disabled)":{"border-width":"var(--border, 1px)","border-inline-end-width":"calc(var(--border, 1px) * var(--join-v))","border-block-end-width":"calc(var(--border, 1px) * var(--join-h))"}},".join-vertical":{"flex-direction":"column","--join-v":"1","--join-h":"0"},".join-horizontal":{"flex-direction":"row","--join-v":"0","--join-h":"1"}};
6
+
7
+ +export default {".join":{"display":"inline-flex","align-items":"stretch","--join-ss":"0","--join-se":"0","--join-es":"0","--join-ee":"0","--join-ml":"0","--join-mt":"0","--join-v":"0","--join-h":"1","@scope (&)":{":where(:scope) > :where(:focus, :has(:focus))":{"z-index":2},"@media (hover: hover)":{":where(:scope) > :where(.btn:hover, :has(.btn:hover))":{"z-index":1}},":where(:scope > :first-child)":{"--join-ss":"var(--radius-field)","--join-se":"calc(var(--radius-field) * var(--join-v))","--join-es":"calc(var(--radius-field) * var(--join-h))","--join-ee":"0"},":where(:scope > :last-child)":{"--join-ss":"0","--join-se":"calc(var(--radius-field) * var(--join-h))","--join-es":"calc(var(--radius-field) * var(--join-v))","--join-ee":"var(--radius-field)"},":where(:scope > :only-child)":{"--join-ss":"var(--radius-field)","--join-se":"var(--radius-field)","--join-es":"var(--radius-field)","--join-ee":"var(--radius-field)"},":where(:scope > :not(:first-child))":{"--join-ml":"calc(var(--border, 1px) * -1 * var(--join-h))","--join-mt":"calc(var(--border, 1px) * -1 * var(--join-v))"}}},".join-item":{"@layer daisyui.l1.l2.l3.l4":{"> *":{"--join-ss":"initial","--join-se":"initial","--join-es":"initial","--join-ee":"initial"}},"border-style":"solid","border-width":"var(--border, 1px)","border-start-start-radius":"var(--join-ss)","border-start-end-radius":"var(--join-se)","border-end-start-radius":"var(--join-es)","border-end-end-radius":"var(--join-ee)","&:not(:disabled, [disabled], .btn-disabled)":{"margin-inline-start":"var(--join-ml, 0)","margin-block-start":"var(--join-mt, 0)"},"&:is(:disabled, [disabled], .btn-disabled)":{"border-width":"var(--border, 1px)","border-inline-end-width":"calc(var(--border, 1px) * var(--join-v))","border-block-end-width":"calc(var(--border, 1px) * var(--join-h))"}},".join-vertical":{"flex-direction":"column","--join-v":"1","--join-h":"0"},".join-horizontal":{"flex-direction":"row","--join-v":"0","--join-h":"1"}};
8
+
@@ -0,0 +1,51 @@
1
+ diff --git a/index.js b/index.js
2
+ --- a/index.js
3
+ +++ b/index.js
4
+ @@ -55,11 +55,12 @@
5
+ var destination = {}
6
+ if (options.isMergeableObject(target)) {
7
+ getKeys(target).forEach(function(key) {
8
+ + if (key === '__proto__') return
9
+ destination[key] = cloneUnlessOtherwiseSpecified(target[key], options)
10
+ })
11
+ }
12
+ getKeys(source).forEach(function(key) {
13
+ - if (propertyIsUnsafe(target, key)) {
14
+ + if (key === '__proto__' || propertyIsUnsafe(target, key)) {
15
+ return
16
+ }
17
+
18
+ diff --git a/dist/cjs.js b/dist/cjs.js
19
+ --- a/dist/cjs.js
20
+ +++ b/dist/cjs.js
21
+ @@ -80,11 +80,12 @@
22
+ var destination = {};
23
+ if (options.isMergeableObject(target)) {
24
+ getKeys(target).forEach(function(key) {
25
+ + if (key === '__proto__') return
26
+ destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
27
+ });
28
+ }
29
+ getKeys(source).forEach(function(key) {
30
+ - if (propertyIsUnsafe(target, key)) {
31
+ + if (key === '__proto__' || propertyIsUnsafe(target, key)) {
32
+ return
33
+ }
34
+
35
+ diff --git a/dist/umd.js b/dist/umd.js
36
+ --- a/dist/umd.js
37
+ +++ b/dist/umd.js
38
+ @@ -84,11 +84,12 @@
39
+ var destination = {};
40
+ if (options.isMergeableObject(target)) {
41
+ getKeys(target).forEach(function(key) {
42
+ + if (key === '__proto__') return
43
+ destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
44
+ });
45
+ }
46
+ getKeys(source).forEach(function(key) {
47
+ - if (propertyIsUnsafe(target, key)) {
48
+ + if (key === '__proto__' || propertyIsUnsafe(target, key)) {
49
+ return
50
+ }
51
+
@@ -24,7 +24,9 @@ function resolvePortFromBaseUrl(urlString: string, fallbackPort: string): string
24
24
  return url.port
25
25
  }
26
26
 
27
- return url.protocol === 'https:' ? '443' : '80'
27
+ return url.protocol === 'https:'
28
+ ? '443'
29
+ : '80'
28
30
  }
29
31
  catch {
30
32
  return fallbackPort
@@ -1,6 +1,6 @@
1
1
  {{! @skipIfEmpty }}
2
2
  {{#if useCatalogProtocol}}
3
- shellEmulator: true
3
+ minimumReleaseAgeExcludePrune: true
4
4
 
5
5
  trustPolicy: no-downgrade
6
6
  # 上游构建工具仍要求 4.x;4.0.3 tarball 已核对原 lockfile 的 SHA-512。
@@ -9,32 +9,49 @@ trustPolicyExclude:
9
9
 
10
10
  # pnpm 12 配置;原生依赖仅运行明确列出的安装脚本。
11
11
  nodeLinker: hoisted
12
- allowBuilds:
13
- cpu-features: true
14
- onnxruntime-node: true
15
- protobufjs: true
16
- ssh2: true
17
- vue-demi: true
18
- better-sqlite3: true
19
- esbuild: true
20
- core-js: false
12
+ shellEmulator: true
13
+
14
+ packages:
15
+ - .
21
16
 
17
+ # 构建与浏览器依赖的安全修复;版本与框架工作区同步维护。
22
18
  overrides:
23
- "@ai-sdk/provider-utils@>=4.0.0 <4.0.33": 4.0.57
19
+ '@ai-sdk/provider-utils@>=4.0.0 <4.0.33': 4.0.57
20
+ '@types/node': {{versions.nodeTypes}}
21
+ body-parser@>=2 <2.4.0: 2.4.0
24
22
  cookie@<0.7.0: 0.7.2
23
+ dompurify@>=3 <3.4.17: 3.4.17
25
24
  esbuild@<0.28.1: 0.28.2
25
+ fast-uri@>=3 <3.1.9: 3.1.9
26
+ follow-redirects@>=1.16.0 <1.16.2: 1.16.2
27
+ glob@>=9 <=14.0.1: 14.0.4
28
+ ip-address@<=10.7.3: 10.7.6
26
29
  katex@<0.18.2: 0.18.10
30
+ minimatch@>=7 <11.0.1: 11.0.5
31
+ parse5@>=8 <8.1.0: 8.1.0
32
+ qs@>=6.7 <6.16.1: 6.17.1
33
+ runed@<0.38.0: 0.38.0
27
34
  sharp@<0.35.5: 0.35.5
28
35
  tinypool@<2.1.2: 2.2.0
29
- '@qdrant/js-client-rest>undici': 7.30.0
30
36
  xcode>uuid: 11.1.1
31
- "@types/node": "{{versions.nodeTypes}}"
32
37
 
33
- packages:
34
- - .
38
+ {{#if hasUi}}
39
+ patchedDependencies:
40
+ daisyui@5.7.50: patches/daisyui-5.7.50.patch
41
+ deepmerge@4.3.1: patches/deepmerge-4.3.1.patch
42
+ {{/if}}
43
+
44
+ allowBuilds:
45
+ core-js: false
46
+ cpu-features: true
47
+ esbuild: true
48
+ onnxruntime-node: true
49
+ protobufjs: true
50
+ ssh2: true
51
+ vue-demi: true
35
52
 
36
53
  catalog:
37
54
  {{#each haiCatalogPackages}}
38
- '{{@key}}': {{this}}
55
+ {{{yaml @key this}}}
39
56
  {{/each}}
40
57
  {{/if}}
@@ -27,5 +27,5 @@ declare global {
27
27
  }
28
28
  }
29
29
 
30
- export {}
30
+ export { }
31
31
  {{/unless}}
@@ -13,6 +13,7 @@
13
13
  <head>
14
14
  <meta charset="utf-8" />
15
15
  <meta name="viewport" content="width=device-width, initial-scale=1" />
16
+ <script id="hai-browser-startup" src="%sveltekit.assets%/_hai/browser-check/startup.js"></script>
16
17
  <link rel="icon" href="%sveltekit.assets%/favicon.png" />
17
18
  <script>
18
19
  ;(function () {
@@ -3,34 +3,22 @@
3
3
  * {{projectName}} - Server Hooks
4
4
  * =============================================================================
5
5
  */
6
-
7
6
  {{#if features.crypto}}
8
7
  import type { TransportEncryptionOptions } from '@h-ai/kit'
9
8
  {{/if}}
10
- import type { Handle } from '@sveltejs/kit'
11
- {{#if features.cache}}
12
- import process from 'node:process'
13
- {{else}}
14
- {{#if features.crypto}}
9
+ import type { Handle } from '@sveltejs/kit/hooks'
15
10
  import process from 'node:process'
16
- {{/if}}
17
- {{/if}}
18
11
  {{#if hasI18n}}
19
- import { base } from '$app/paths'
12
+ import { resolve as resolvePath } from '$app/paths'
20
13
  {{else}}
21
14
  {{#if features.iam}}
22
- import { base } from '$app/paths'
15
+ import { resolve as resolvePath } from '$app/paths'
23
16
  {{else}}
24
17
  {{#if features.crypto}}
25
- import { base } from '$app/paths'
26
- {{/if}}
18
+ import { resolve as resolvePath } from '$app/paths'
27
19
  {{/if}}
28
20
  {{/if}}
29
- {{#if hasI18n}}
30
- import { paraglideMiddleware } from '$lib/paraglide/server.js'
31
21
  {{/if}}
32
- import { initApp } from '$lib/server/init.js'
33
- import { getKitConfig } from '$lib/server/kit-config.js'
34
22
  {{#if features.cache}}
35
23
  import { cache } from '@h-ai/cache'
36
24
  {{/if}}
@@ -47,6 +35,11 @@ import { kit } from '@h-ai/kit'
47
35
  import { reldb } from '@h-ai/reldb'
48
36
  {{/if}}
49
37
  {{/if}}
38
+ {{#if hasI18n}}
39
+ import { paraglideMiddleware } from '#lib/paraglide/server.js'
40
+ {{/if}}
41
+ import { closeApp, initApp } from '#lib/server/init.js'
42
+ import { getKitConfig } from '#lib/server/kit-config.js'
50
43
 
51
44
  // =============================================================================
52
45
  // 应用初始化
@@ -54,6 +47,14 @@ import { reldb } from '@h-ai/reldb'
54
47
 
55
48
  let appInitPromise: Promise<void> | null = null
56
49
 
50
+ // Node 适配器停止接收请求后释放模块,避免数据库或后台任务阻止进程退出。
51
+ process.once('sveltekit:shutdown', () => {
52
+ void closeApp().catch((error: unknown) => {
53
+ core.logger.error('Application shutdown failed', { error })
54
+ process.exitCode = 1
55
+ })
56
+ })
57
+
57
58
  async function ensureAppInitialized() {
58
59
  if (!appInitPromise) {
59
60
  appInitPromise = initApp().catch((err: unknown) => {
@@ -72,7 +73,6 @@ const initHandle: Handle = async ({ event, resolve }) => {
72
73
  await ensureAppInitialized()
73
74
  return resolve(event)
74
75
  }
75
-
76
76
  {{#if hasI18n}}
77
77
  // =============================================================================
78
78
  // Paraglide i18n Middleware
@@ -84,7 +84,7 @@ const initHandle: Handle = async ({ event, resolve }) => {
84
84
  * API 请求跳过 paraglideMiddleware(不需要页面级 locale + 避免消耗 body)
85
85
  */
86
86
  const i18nHandle: Handle = async ({ event, resolve }) => {
87
- if (event.url.pathname.startsWith(`${base}/api/`)) {
87
+ if (event.url.pathname.startsWith(`${resolvePath('/').replace(/\/$/, '')}/api/`)) {
88
88
  const locale = event.cookies.get('PARAGLIDE_LOCALE') ?? '{{defaultLocale}}'
89
89
  event.locals.locale = locale
90
90
  return kit.i18n.runWithLocale(locale, () => resolve(event))
@@ -97,7 +97,6 @@ const i18nHandle: Handle = async ({ event, resolve }) => {
97
97
  }))
98
98
  })
99
99
  }
100
-
101
100
  {{/if}}
102
101
  // =============================================================================
103
102
  // hai Handle(会话验证 + 限流 + 日志)
@@ -111,20 +110,20 @@ const haiHandle: Handle = async (input) => {
111
110
  let transport: TransportEncryptionOptions | undefined
112
111
  if (settings.transport !== false) {
113
112
  {{#unless features.db}}
114
- if (core.module.requiresSharedState(process.env))
115
- throw new Error('Production transport requires the db feature and a shared database registry')
113
+ if (core.module.requiresSharedState(process.env))
114
+ throw new Error('Production transport requires the db feature and a shared database registry')
116
115
  {{/unless}}
117
116
  const ring = parseTransportServerKeyRing(process.env.HAI_CRYPTO_TRANSPORT_SERVERKEYRING)
118
117
  if (!ring.success)
119
118
  throw new Error(`HAI_CRYPTO_TRANSPORT_SERVERKEYRING: ${ring.error.message} (${ring.error.code})`)
120
119
  transport = {
121
120
  ...settings.transport,
122
- basePath: base,
121
+ basePath: resolvePath('/').replace(/\/$/, ''),
123
122
  serverKeyRing: ring.data,
124
123
  {{#if features.db}}
125
124
  keyStore: createReldbTransportKeyStore({ reldb, ttlSeconds: 3600 }),
126
125
  {{else}}
127
- keyStore: createInMemoryKeyStore(),
126
+ keyStore: createInMemoryKeyStore(),
128
127
  {{/if}}
129
128
  }
130
129
  }
@@ -138,7 +137,7 @@ const haiHandle: Handle = async (input) => {
138
137
  {{#if features.crypto}}
139
138
  crypto: { crypto, transport },
140
139
  {{/if}}
141
- {{#if features.iam}}
140
+ {{#if features.iam}}
142
141
  auth: {
143
142
  verifyToken: async (token) => {
144
143
  const result = await iam.auth.verifyToken(token)
@@ -154,18 +153,27 @@ const haiHandle: Handle = async (input) => {
154
153
  data: session.data,
155
154
  }
156
155
  },
157
- loginUrl: `${base}/auth/login`,
158
- protectedPaths: ['/admin/*', '/api/*'].map(path => `${base}${path}`),
159
- publicPaths: [...kit.auth.publicPaths, '/api/auth/logout', '/api/public/*', '/api/health'].map(path => `${base}${path}`),
156
+ loginUrl: `${resolvePath('/').replace(/\/$/, '')}/auth/login`,
157
+ protectedPaths: ['/admin/*', '/api/*'].map(path => `${resolvePath('/').replace(/\/$/, '')}${path}`),
158
+ publicPaths: [
159
+ ...kit.auth.publicPaths,
160
+ '/api/auth/logout',
161
+ '/api/public/*',
162
+ '/api/health',
163
+ ].map(path => `${resolvePath('/').replace(/\/$/, '')}${path}`),
160
164
  operations: () => iam.auth,
161
165
  },
162
- {{/if}}
163
- {{#if features.cache}}
164
- rateLimit: { windowMs: 60000, maxRequests: 200, store: kit.middleware.createCacheRateLimitStore(cache, { namespace: '{{projectName}}', allowMemory: process.env.NODE_ENV !== 'production' || process.env.HAI_E2E === '1' }) },
165
- {{else}}
166
+ {{/if}}
167
+ {{#if features.cache}}
168
+ rateLimit: {
169
+ windowMs: 60000,
170
+ maxRequests: 200,
171
+ store: kit.middleware.createCacheRateLimitStore(cache, { namespace: '{{projectName}}', allowMemory: process.env.NODE_ENV !== 'production' || process.env.HAI_E2E === '1' }),
172
+ },
173
+ {{else}}
166
174
  // 未选择cache能力时不启用限流;启用前须接入共享原子store。
167
175
  rateLimit: false,
168
- {{/if}}
176
+ {{/if}}
169
177
  logging: { logBody: false },
170
178
  onError: (error: unknown, _event) => {
171
179
  core.logger.error('Request error:', { error })
@@ -174,7 +182,10 @@ const haiHandle: Handle = async (input) => {
174
182
  success: false,
175
183
  error: core.error.toPublic({ code: 'INTERNAL_ERROR', message: '', httpStatus: 500 }),
176
184
  }),
177
- { status: 500, headers: { 'Content-Type': 'application/json' } },
185
+ {
186
+ status: 500,
187
+ headers: { 'Content-Type': 'application/json' },
188
+ },
178
189
  )
179
190
  },
180
191
  })
@@ -2,6 +2,5 @@
2
2
  {{#if features.feedback}}
3
3
  /** 当前应用编译时烘焙的产物身份;运行时配置不能覆盖。 */
4
4
  declare const __HAI_BUILD_METADATA__: { appVersion: string, buildId: string, commit: string }
5
-
6
5
  export const buildMetadata = __HAI_BUILD_METADATA__
7
6
  {{/if}}