@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
@@ -13,7 +13,7 @@ import { core } from '@h-ai/core'
13
13
  import { crypto } from '@h-ai/crypto'
14
14
  {{/if}}
15
15
  {{#if features.feedback}}
16
- import { feedback } from '@h-ai/feedback'
16
+ import { feedback, FeedbackConfigSchema } from '@h-ai/feedback'
17
17
  {{/if}}
18
18
  {{#if features.iam}}
19
19
  import { iam, IamConfigSchema } from '@h-ai/iam'
@@ -52,7 +52,10 @@ function startFeedback(): Promise<void> {
52
52
  feedbackClosing = false
53
53
  feedbackStarting = (async () => {
54
54
  try {
55
- const result = await feedback.init({ ...core.config.getOrThrow<import('@h-ai/feedback').FeedbackConfigInput>('feedback'), ...buildMetadata })
55
+ const result = await feedback.init({
56
+ ...core.config.getOrThrow<import('@h-ai/feedback').FeedbackConfigInput>('feedback'),
57
+ ...buildMetadata,
58
+ })
56
59
  if (!result.success) {
57
60
  if (feedbackFailure !== result.error.code)
58
61
  core.logger.warn('Optional feedback unavailable; business runtime remains ready', { module: 'feedback', code: result.error.code })
@@ -86,66 +89,174 @@ async function closeFeedback() {
86
89
  await feedbackStarting
87
90
  return feedback.close()
88
91
  }
89
-
90
92
  {{/if}}
91
93
 
92
94
  const runtime = core.module.createRuntime([
93
- { name: 'configuration', start: () => { core.init({ configDir: './config' }) }, close: () => {} },
95
+ {
96
+ name: 'configuration',
97
+ start: () => {
98
+ core.init({
99
+ configDir: './config',
100
+ configSchemas: {
101
+ {{#if features.ai}}
102
+ ai: AIConfigSchema,
103
+ {{/if}}
104
+ {{#if features.audit}}
105
+ audit: AuditInitConfigSchema,
106
+ {{/if}}
107
+ {{#if features.cache}}
108
+ cache: CacheConfigSchema,
109
+ {{/if}}
110
+ {{#if features.feedback}}
111
+ feedback: FeedbackConfigSchema,
112
+ {{/if}}
113
+ {{#if features.iam}}
114
+ iam: IamConfigSchema,
115
+ {{/if}}
116
+ {{#if features.reach}}
117
+ reach: ReachConfigSchema,
118
+ {{/if}}
94
119
  {{#if features.db}}
95
- { name: 'reldb', start: async () => {
96
- const config = ReldbConfigSchema.parse(core.config.getOrThrow('db'))
97
- if (config.type === 'sqlite' && config.database !== ':memory:') {
98
- const { mkdir } = await import('node:fs/promises')
99
- const { dirname } = await import('node:path')
100
- await mkdir(dirname(config.database), { recursive: true })
101
- }
102
- return reldb.init(config)
103
- }, close: () => reldb.close() },
120
+ db: ReldbConfigSchema,
121
+ {{/if}}
122
+ {{#if features.audit}}
123
+ {{#if features.scheduler}}
124
+ scheduler: SchedulerConfigSchema,
125
+ {{/if}}
126
+ {{/if}}
127
+ {{#if features.storage}}
128
+ storage: StorageConfigSchema,
129
+ {{/if}}
130
+ {{#if features.vecdb}}
131
+ vecdb: VecdbConfigSchema,
132
+ {{/if}}
133
+ },
134
+ })
135
+ },
136
+ close: () => { },
137
+ },
138
+ {{#if features.db}}
139
+ {
140
+ name: 'reldb',
141
+ start: async () => {
142
+ const config = ReldbConfigSchema.parse(core.config.getOrThrow('db'))
143
+ if (config.type === 'sqlite' && config.database !== ':memory:') {
144
+ const { mkdir } = await import('node:fs/promises')
145
+ const { dirname } = await import('node:path')
146
+ await mkdir(dirname(config.database), { recursive: true })
147
+ }
148
+ return reldb.init(config)
149
+ },
150
+ close: () => reldb.close(),
151
+ },
104
152
  {{/if}}
105
153
  {{#if features.cache}}
106
- { name: 'cache', start: () => cache.init(CacheConfigSchema.parse(core.config.getOrThrow('cache'))), close: () => cache.close() },
154
+ {
155
+ name: 'cache',
156
+ start: () => cache.init(CacheConfigSchema.parse(core.config.getOrThrow('cache'))),
157
+ close: () => cache.close(),
158
+ },
107
159
  {{/if}}
108
160
  {{#if features.vecdb}}
109
- { name: 'vecdb', start: () => vecdb.init(VecdbConfigSchema.parse(core.config.getOrThrow('vecdb'))), close: () => vecdb.close() },
161
+ {
162
+ name: 'vecdb',
163
+ start: () => vecdb.init(VecdbConfigSchema.parse(core.config.getOrThrow('vecdb'))),
164
+ close: () => vecdb.close(),
165
+ },
110
166
  {{/if}}
111
167
  {{#if features.crypto}}
112
- { name: 'crypto', start: () => crypto.init(), close: () => crypto.close() },
168
+ {
169
+ name: 'crypto',
170
+ start: () => crypto.init(),
171
+ close: () => crypto.close(),
172
+ },
113
173
  {{/if}}
114
174
  {{#if features.storage}}
115
- { name: 'storage', start: () => storage.init(StorageConfigSchema.parse(core.config.getOrThrow('storage'))), close: () => storage.close() },
175
+ {
176
+ name: 'storage',
177
+ start: () => storage.init(StorageConfigSchema.parse(core.config.getOrThrow('storage'))),
178
+ close: () => storage.close(),
179
+ },
116
180
  {{/if}}
117
181
  {{#if features.reach}}
118
- { name: 'reach', enabled: () => Boolean(core.config.get('reach')), start: () => reach.init(ReachConfigSchema.parse(core.config.getOrThrow('reach'))), close: () => reach.close() },
182
+ {
183
+ name: 'reach',
184
+ enabled: () => Boolean(core.config.get('reach')),
185
+ start: () => reach.init(ReachConfigSchema.parse(core.config.getOrThrow('reach'))),
186
+ close: () => reach.close(),
187
+ },
119
188
  {{/if}}
120
189
  {{#if features.audit}}
121
- { name: 'audit', start: () => audit.init({ ...AuditInitConfigSchema.parse(core.config.get('audit') ?? {}){{#if features.storage}}, storage{{/if}}{{#if features.reach}}, reach{{/if}} }), close: () => audit.close() },
190
+ {
191
+ name: 'audit',
192
+ start: () => audit.init({
193
+ ...AuditInitConfigSchema.parse(core.config.get('audit') ?? {}),
194
+ {{#if features.storage}}
195
+ storage,
196
+ {{/if}}
197
+ {{#if features.reach}}
198
+ reach,
199
+ {{/if}}
200
+ }),
201
+ close: () => audit.close(),
202
+ },
122
203
  {{/if}}
123
204
  {{#if features.iam}}
124
- { name: 'iam', start: () => iam.init({ ...IamConfigSchema.parse(core.config.getOrThrow('iam')){{#if features.reach}}, reach{{/if}} }), close: () => iam.close() },
205
+ {
206
+ name: 'iam',
207
+ start: () => iam.init({
208
+ ...IamConfigSchema.parse(core.config.getOrThrow('iam')),
209
+ {{#if features.reach}}
210
+ reach,
211
+ {{/if}}
212
+ }),
213
+ close: () => iam.close(),
214
+ },
125
215
  {{/if}}
126
216
  {{#if features.audit}}
127
217
  {{#if features.scheduler}}
128
- { name: 'audit-jobs', enabled: () => Boolean(audit.schedulerPlan), start: async () => {
129
- const schedule = audit.schedulerPlan
130
- if (!schedule)
131
- return
132
- const initialized = await scheduler.init({ ...SchedulerConfigSchema.parse(core.config.get('scheduler') ?? {}), ...schedule })
133
- if (!initialized.success)
134
- return initialized
135
- const started = scheduler.start()
136
- if (!started.success)
137
- await scheduler.close()
138
- return started
139
- }, close: () => scheduler.close() },
218
+ {
219
+ name: 'audit-jobs',
220
+ enabled: () => Boolean(audit.schedulerPlan),
221
+ start: async () => {
222
+ const schedule = audit.schedulerPlan
223
+ if (!schedule)
224
+ return
225
+ const initialized = await scheduler.init({
226
+ ...SchedulerConfigSchema.parse(core.config.get('scheduler') ?? {}),
227
+ ...schedule,
228
+ })
229
+ if (!initialized.success)
230
+ return initialized
231
+ const started = scheduler.start()
232
+ if (!started.success)
233
+ await scheduler.close()
234
+ return started
235
+ },
236
+ close: () => scheduler.close(),
237
+ },
140
238
  {{/if}}
141
239
  {{/if}}
142
240
  {{#if features.feedback}}
143
- { name: 'feedback', enabled: () => Boolean(core.config.get('feedback')), start: startFeedback, close: closeFeedback },
241
+ {
242
+ name: 'feedback',
243
+ enabled: () => Boolean(core.config.get('feedback')),
244
+ start: startFeedback,
245
+ close: closeFeedback,
246
+ },
144
247
  {{/if}}
145
248
  {{#if features.ai}}
146
- { name: 'ai', start: () => ai.init(AIConfigSchema.parse(core.config.getOrThrow('ai'))), close: () => ai.close() },
249
+ {
250
+ name: 'ai',
251
+ start: () => ai.init(AIConfigSchema.parse(core.config.getOrThrow('ai'))),
252
+ close: () => ai.close(),
253
+ },
147
254
  {{/if}}
148
- { name: 'bootstrap', start: () => { core.logger.info('Application initialized') }, close: () => {} },
255
+ {
256
+ name: 'bootstrap',
257
+ start: () => { core.logger.info('Application initialized') },
258
+ close: () => { },
259
+ },
149
260
  ])
150
261
 
151
262
  /** 启动失败只报告模块、错误码和配置路径,私密值不进入错误上下文。 */
@@ -1,7 +1,7 @@
1
1
  {{! @skipIfEmpty }}
2
2
  {{#unless isSvelteOnlyApp}}
3
3
  import type { KitConfig } from '@h-ai/kit'
4
- import { base } from '$app/paths'
4
+ import { resolve } from '$app/paths'
5
5
  import { core } from '@h-ai/core'
6
6
  import { KitConfigSchema } from '@h-ai/kit'
7
7
 
@@ -9,9 +9,9 @@ let configured: KitConfig | undefined
9
9
 
10
10
  /** 输入已由 Schema 校验为绝对路径;宿主补构建目录并保留绝对路径类型。 */
11
11
  function mounted(path: string): `/${string}` {
12
- if (!base || path === base || path.startsWith(`${base}/`))
12
+ if (!resolve('/').replace(/\/$/, '') || path === resolve('/').replace(/\/$/, '') || path.startsWith(`${resolve('/').replace(/\/$/, '')}/`))
13
13
  return `/${path.slice(1)}`
14
- return `/${base.slice(1)}${path}`
14
+ return `/${resolve('/').replace(/\/$/, '').slice(1)}${path}`
15
15
  }
16
16
 
17
17
  /** 启动时固定服务端配置;浏览器只能接收根 load 明确投影的 transport。 */
@@ -31,7 +31,10 @@ export function getKitConfig(): KitConfig {
31
31
  keyExchangePath: mounted(transport.keyExchangePath),
32
32
  excludePaths: transport.excludePaths.map(mounted),
33
33
  routePlaintextBytes: transport.routePlaintextBytes
34
- ? Object.fromEntries(Object.entries(transport.routePlaintextBytes).map(([path, bytes]) => [mounted(path), bytes]))
34
+ ? Object.fromEntries(Object.entries(transport.routePlaintextBytes).map(([path, bytes]) => [
35
+ mounted(path),
36
+ bytes,
37
+ ]))
35
38
  : undefined,
36
39
  },
37
40
  }
@@ -2,12 +2,12 @@
2
2
  {{#unless isSvelteOnlyApp}}
3
3
  import type { CoreConfig } from '@h-ai/core'
4
4
  import type { KitPublicConfig } from '@h-ai/kit'
5
- import { getKitConfig } from '$lib/server/kit-config.js'
6
5
  import { core } from '@h-ai/core'
7
6
  {{#if features.iam}}
8
7
  import { iam } from '@h-ai/iam'
9
8
  import { error } from '@sveltejs/kit'
10
9
  {{/if}}
10
+ import { getKitConfig } from '#lib/server/kit-config.js'
11
11
 
12
12
  /** 只向浏览器提供公开配置,避免暴露日志上下文、凭证或其它模块配置。 */
13
13
  export async function load() {
@@ -16,7 +16,7 @@ export async function load() {
16
16
  const publicConfig = await iam.getPublicConfig()
17
17
  if (!publicConfig.success) {
18
18
  core.logger.error('Failed to load public authentication configuration', { error: publicConfig.error })
19
- error(503, { message: core.error.toPublic(publicConfig.error).message })
19
+ error(503, core.error.toPublic(publicConfig.error).message)
20
20
  }
21
21
  {{/if}}
22
22
  return {
@@ -1,109 +1,19 @@
1
- /**
2
- * Svelte 配置
3
- */
4
- {{#unless isSvelteOnlyApp}}
5
- import process from 'node:process'
6
- {{/unless}}
1
+ {{! @skipIfEmpty }}
2
+ {{#if isSvelteOnlyApp}}
3
+ /** Svelte + Vite 客户端的预处理配置;SvelteKit 配置统一在 vite.config.ts。 */
7
4
  {{#if hasUi}}
8
5
  import { autoImportHaiUi } from '@h-ai/ui/auto-import'
9
6
  {{/if}}
10
- {{#unless isSvelteOnlyApp}}
11
- import adapter from '@sveltejs/adapter-node'
12
- {{#if_eq appType 'website'}}
13
- import staticAdapter from '@sveltejs/adapter-static'
14
- {{/if_eq}}
15
- {{/unless}}
16
7
  import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
17
- {{#unless isSvelteOnlyApp}}
18
- import { resolvePublicBasePath } from './scripts/public-base-path.mjs'
19
- {{/unless}}
20
- {{#if_eq appType 'website'}}
21
- import { resolveStaticWebsite, validateStaticRoutes } from './scripts/static-website.mjs'
22
-
23
- const website = resolveStaticWebsite()
24
- const staticOutput = staticAdapter({ strict: false })
25
- {{/if_eq}}
26
8
 
27
- {{#if isSvelteOnlyApp}}
28
9
  /** @type {import('@sveltejs/vite-plugin-svelte').SvelteConfig} */
29
- const config = {
30
- preprocess: [{{#if hasUi}}autoImportHaiUi(), {{/if}}vitePreprocess()],
31
- compilerOptions: {
32
- runes: true,
33
- },
34
- }
35
- {{else}}
36
- const DEFAULT_E2E_ORIGINS = ['http://localhost:4173', 'http://127.0.0.1:4173']
37
-
38
- function resolveTrustedOrigins() {
39
- if (process.env.HAI_E2E !== '1')
40
- return []
41
-
42
- const rawBaseUrl = process.env.BASE_URL ?? DEFAULT_E2E_ORIGINS[0]
43
-
44
- try {
45
- const url = new URL(rawBaseUrl)
46
- const origins = new Set([url.origin])
47
-
48
- if (url.hostname === 'localhost') {
49
- url.hostname = '127.0.0.1'
50
- origins.add(url.origin)
51
- }
52
- else if (url.hostname === '127.0.0.1') {
53
- url.hostname = 'localhost'
54
- origins.add(url.origin)
55
- }
56
-
57
- return [...origins]
58
- }
59
- catch {
60
- return DEFAULT_E2E_ORIGINS
61
- }
62
- }
63
-
64
- /** @type {import('@sveltejs/kit').Config} */
65
- const config = {
66
- preprocess: [{{#if hasUi}}autoImportHaiUi(), {{/if}}vitePreprocess()],
67
- compilerOptions: {
68
- runes: true,
69
- },
70
- kit: {
71
- // 环境文件由 Vite 的 core loader 统一加载;Kit 不再二次读取根目录私有配置。
72
- env: { dir: './.svelte-kit' },
73
- paths: { base: resolvePublicBasePath() },
74
- {{#if isCapacitorApp}}
75
- adapter: adapter({
76
- pages: 'build',
77
- assets: 'build',
78
- fallback: 'index.html',
79
- }),
80
- {{else}}
81
- {{#if_eq appType 'website'}}
82
- adapter: website.enabled
83
- ? {
84
- ...staticOutput,
85
- name: 'hai-static-website',
86
- async adapt(builder) {
87
- // 仅省略模板健康端点;自定义API或未预渲染页面明确失败,不用SPA回退掩盖。
88
- validateStaticRoutes(builder.routes)
89
- await staticOutput.adapt(builder)
90
- },
91
- }
92
- : adapter(),
93
- {{else}}
94
- adapter: adapter(),
95
- {{/if_eq}}
10
+ export default {
11
+ preprocess: [
12
+ vitePreprocess(),
13
+ {{#if hasUi}}
14
+ autoImportHaiUi(),
96
15
  {{/if}}
97
- csrf: {
98
- trustedOrigins: resolveTrustedOrigins(),
99
- },
100
- alias: {
101
- $components: './src/lib/components',
102
- $stores: './src/lib/stores',
103
- $utils: './src/lib/utils',
104
- },
105
- },
16
+ ],
17
+ compilerOptions: { runes: true },
106
18
  }
107
19
  {{/if}}
108
-
109
- export default config
@@ -39,7 +39,6 @@ describe('generated scaffold', () => {
39
39
  expect(pkg.scripts.test).toBeDefined()
40
40
  expect(pkg.scripts['test:e2e']).toBeDefined()
41
41
  })
42
-
43
42
  {{#if isSvelteOnlyApp}}
44
43
  it('renders the Vite app shell entry', async () => {
45
44
  const indexHtml = await readFile(join(rootDir, 'index.html'), 'utf-8')
@@ -83,7 +82,12 @@ describe('generated scaffold', () => {
83
82
  expect(await load()).toEqual({
84
83
  kitConfig: { transport: getKitConfig().transport },
85
84
  iamPublicConfig: publicConfig.data,
86
- appConfig: { name: config.name, version: config.version, env: config.env, defaultLocale: config.defaultLocale },
85
+ appConfig: {
86
+ name: config.name,
87
+ version: config.version,
88
+ env: config.env,
89
+ defaultLocale: config.defaultLocale,
90
+ },
87
91
  })
88
92
  }
89
93
  finally {
@@ -94,7 +98,12 @@ describe('generated scaffold', () => {
94
98
  {{else}}
95
99
  expect(await load()).toEqual({
96
100
  kitConfig: { transport: getKitConfig().transport },
97
- appConfig: { name: config.name, version: config.version, env: config.env, defaultLocale: config.defaultLocale },
101
+ appConfig: {
102
+ name: config.name,
103
+ version: config.version,
104
+ env: config.env,
105
+ defaultLocale: config.defaultLocale,
106
+ },
98
107
  })
99
108
  {{/if}}
100
109
  })
@@ -28,7 +28,7 @@
28
28
  }
29
29
  {{else}}
30
30
  {
31
- "extends": "./.svelte-kit/tsconfig.json",
31
+ "extends": "$app/tsconfig",
32
32
  "compilerOptions": {
33
33
  "moduleResolution": "bundler",
34
34
  "allowImportingTsExtensions": true,
@@ -39,12 +39,15 @@
39
39
  "skipLibCheck": true
40
40
  },
41
41
  "include": [
42
- "src/**/*",
43
- "src/**/*.svelte"
42
+ "src",
43
+ "tests",
44
+ "*.ts",
45
+ "*.js"
44
46
  ],
45
47
  "exclude": [
46
48
  "node_modules",
47
- ".svelte-kit"
49
+ "build",
50
+ "src/service-worker"
48
51
  ]
49
52
  }
50
53
  {{/if}}
@@ -10,6 +10,9 @@ import process from 'node:process'
10
10
  import { fileURLToPath } from 'node:url'
11
11
  import { core } from '@h-ai/core'
12
12
  {{#if hasUi}}
13
+ {{#unless isSvelteOnlyApp}}
14
+ import { autoImportHaiUi } from '@h-ai/ui/auto-import'
15
+ {{/unless}}
13
16
  import { haiOptimizeExclude, haiPrebundledDeps } from '@h-ai/ui/vite'
14
17
  {{/if}}
15
18
  {{#if hasI18n}}
@@ -18,26 +21,66 @@ import { paraglideVitePlugin } from '@inlang/paraglide-js'
18
21
  {{#if isSvelteOnlyApp}}
19
22
  import { svelte } from '@sveltejs/vite-plugin-svelte'
20
23
  {{else}}
24
+ import adapter from '@sveltejs/adapter-node'
25
+ {{#if_eq appType 'website'}}
26
+ import staticAdapter from '@sveltejs/adapter-static'
27
+ {{/if_eq}}
21
28
  import { sveltekit } from '@sveltejs/kit/vite'
29
+ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
22
30
  {{/if}}
23
31
  {{#if hasUi}}
24
32
  import tailwindcss from '@tailwindcss/vite'
25
33
  {{/if}}
26
34
  import { defineConfig } from 'vite'
27
35
  import { resolveBuildMetadata } from './scripts/build-metadata.js'
36
+ import { resolvePublicBasePath } from './scripts/public-base-path.mjs'
28
37
  {{#if_eq appType 'website'}}
29
- import { resolveStaticWebsite } from './scripts/static-website.mjs'
38
+ import { resolveStaticWebsite, validateStaticRoutes } from './scripts/static-website.mjs'
30
39
  {{/if_eq}}
31
40
  {{#if isSvelteOnlyApp}}
32
- import { resolvePublicBasePath } from './scripts/public-base-path.mjs'
33
41
  import { publicRuntimeConfig } from './scripts/vite-runtime-config.js'
34
42
  {{/if}}
35
43
 
44
+ {{#unless isSvelteOnlyApp}}
45
+ const DEFAULT_E2E_ORIGINS = ['http://localhost:4173', 'http://127.0.0.1:4173']
46
+
47
+ function resolveTrustedOrigins() {
48
+ if (process.env.HAI_E2E !== '1')
49
+ return []
50
+
51
+ const rawBaseUrl = process.env.BASE_URL ?? DEFAULT_E2E_ORIGINS[0]
52
+
53
+ try {
54
+ const url = new URL(rawBaseUrl)
55
+ const origins = new Set([url.origin])
56
+
57
+ if (url.hostname === 'localhost') {
58
+ url.hostname = '127.0.0.1'
59
+ origins.add(url.origin)
60
+ }
61
+ else if (url.hostname === '127.0.0.1') {
62
+ url.hostname = 'localhost'
63
+ origins.add(url.origin)
64
+ }
65
+
66
+ return [...origins]
67
+ }
68
+ catch {
69
+ return DEFAULT_E2E_ORIGINS
70
+ }
71
+ }
72
+ {{/unless}}
36
73
  export default defineConfig(({ mode, command }) => {
37
74
  {{#if_eq appType 'website'}}
38
75
  const website = resolveStaticWebsite()
76
+ const staticOutput = staticAdapter({ strict: false })
39
77
  {{/if_eq}}
40
- const envResult = command === 'build' || process.env.HAI_E2E === '1'{{#if_eq appType 'website'}} || website.enabled{{/if_eq}} ? { success: true as const, data: {} as Record<string, string> } : core.config.loadEnvFiles({ mode, envDir: process.cwd() })
78
+ const envResult = command === 'build' || process.env.HAI_E2E === '1'{{#if_eq appType 'website'}} || website.enabled{{/if_eq}}
79
+ ? { success: true as const, data: {} as Record<string, string> }
80
+ : core.config.loadEnvFiles({
81
+ mode,
82
+ envDir: process.cwd(),
83
+ })
41
84
  if (!envResult.success)
42
85
  throw new Error(envResult.error.message)
43
86
  const env = envResult.data
@@ -46,7 +89,11 @@ export default defineConfig(({ mode, command }) => {
46
89
  const metadataAsset: Plugin = {
47
90
  name: 'hai-build-metadata',
48
91
  generateBundle() {
49
- this.emitFile({ type: 'asset', fileName: 'build-metadata.json', source: JSON.stringify(buildMetadata) })
92
+ this.emitFile({
93
+ type: 'asset',
94
+ fileName: 'build-metadata.json',
95
+ source: JSON.stringify(buildMetadata),
96
+ })
50
97
  },
51
98
  }
52
99
  {{#if isSvelteOnlyApp}}
@@ -58,14 +105,18 @@ export default defineConfig(({ mode, command }) => {
58
105
  version: config.version,
59
106
  env: config.env,
60
107
  defaultLocale: config.defaultLocale,
61
- logging: config.logging ? { level: config.logging.level, format: config.logging.format } : undefined,
108
+ logging: config.logging
109
+ ? { level: config.logging.level, format: config.logging.format }
110
+ : undefined,
62
111
  }
63
112
  const publicBase = resolvePublicBasePath()
64
113
  {{/if}}
65
114
 
66
115
  return {
67
116
  {{#if isSvelteOnlyApp}}
68
- base: publicBase ? `${publicBase}/` : './',
117
+ base: publicBase
118
+ ? `${publicBase}/`
119
+ : './',
69
120
  {{/if}}
70
121
  envDir: false,
71
122
  envPrefix: ['VITE_', 'PUBLIC_'],
@@ -90,17 +141,58 @@ export default defineConfig(({ mode, command }) => {
90
141
  },
91
142
  },
92
143
  {{/if_eq}}
93
- {{#if isSvelteOnlyApp}}
94
- publicRuntimeConfig({ apiBase: process.env.PUBLIC_API_BASE, {{#if features.crypto}}apiTransport: process.env.PUBLIC_API_TRANSPORT, apiKeyExchangePath: process.env.PUBLIC_API_KEY_EXCHANGE_PATH, {{/if}}core: appConfig }),
144
+ {{#if isSvelteOnlyApp}}
145
+ publicRuntimeConfig({
146
+ apiBase: process.env.PUBLIC_API_BASE,
147
+ {{#if features.crypto}}
148
+ apiTransport: process.env.PUBLIC_API_TRANSPORT,
149
+ apiKeyExchangePath: process.env.PUBLIC_API_KEY_EXCHANGE_PATH,
150
+ {{/if}}
151
+ core: appConfig,
152
+ }),
95
153
  svelte(),
96
- {{else}}
97
- sveltekit(),
98
- {{/if}}
154
+ {{else}}
155
+ sveltekit({
156
+ preprocess: [
157
+ vitePreprocess(),
158
+ {{#if hasUi}}
159
+ autoImportHaiUi(),
160
+ {{/if}}
161
+ ],
162
+ compilerOptions: { runes: true },
163
+ // Core 统一加载环境文件;SSR 路径固定为绝对前缀供 HTTP/加密管道使用。
164
+ env: { dir: './.svelte-kit' },
165
+ paths: {
166
+ base: resolvePublicBasePath(),
167
+ relative: false,
168
+ },
169
+ {{#if_eq appType 'website'}}
170
+ adapter: website.enabled
171
+ ? {
172
+ ...staticOutput,
173
+ name: 'hai-static-website',
174
+ async adapt(builder) {
175
+ // 仅省略模板健康端点,自定义 API 或未预渲染页面仍须明确失败。
176
+ validateStaticRoutes(builder.routes)
177
+ await staticOutput.adapt(builder)
178
+ },
179
+ }
180
+ : adapter(),
181
+ {{else}}
182
+ adapter: adapter(),
183
+ {{/if_eq}}
184
+ csrf: {
185
+ trustedOrigins: resolveTrustedOrigins(),
186
+ },
187
+ }),
188
+ {{/if}}
99
189
  {{#if hasUi}}
100
190
  tailwindcss(),
101
191
  {{/if}}
102
192
  {{#if hasI18n}}
103
193
  paraglideVitePlugin({
194
+ // 共享物理消息产物供独立 Vitest/Node 工具读取。
195
+ outputStructure: 'message-modules',
104
196
  project: './project.inlang',
105
197
  outdir: './src/lib/paraglide',
106
198
  strategy: ['cookie', 'baseLocale'],
@@ -109,8 +201,8 @@ export default defineConfig(({ mode, command }) => {
109
201
  ],
110
202
  {{#if hasUi}}
111
203
  optimizeDeps: {
112
- // bits-ui 含 .svelte 源码须 exclude;@internationalized/date 须与 bits-ui 同为原始副本,
113
- // 避免日期类型 instanceof 失败("Unknown date type")。
204
+ // bits-ui 含 .svelte 源码须 exclude;@internationalized/date 须与 bits-ui 同为原始副本,
205
+ // 避免日期类型 instanceof 失败("Unknown date type")。
114
206
  exclude: [...haiOptimizeExclude],
115
207
  // 预打包 @h-ai/ui 的重型纯 JS 依赖,避免首次进入业务路由触发依赖再优化与整页刷新
116
208
  include: [...haiPrebundledDeps],
@@ -125,7 +217,9 @@ export default defineConfig(({ mode, command }) => {
125
217
  {{/unless}}
126
218
  server: {
127
219
  fs: {
128
- allow: [path.resolve(process.cwd())],
220
+ allow: [
221
+ path.resolve(process.cwd()),
222
+ ],
129
223
  },
130
224
  },
131
225
  }
@@ -7,9 +7,13 @@ import { resolveBuildMetadata } from './scripts/build-metadata.js'
7
7
 
8
8
  export default defineConfig({
9
9
  {{#unless isSvelteOnlyApp}}
10
- plugins: [sveltekit()],
10
+ plugins: [
11
+ sveltekit(),
12
+ ],
11
13
  {{/unless}}
12
- define: { __HAI_BUILD_METADATA__: JSON.stringify(resolveBuildMetadata(fileURLToPath(new URL('.', import.meta.url)))) },
14
+ define: {
15
+ __HAI_BUILD_METADATA__: JSON.stringify(resolveBuildMetadata(fileURLToPath(new URL('.', import.meta.url)))),
16
+ },
13
17
  test: {
14
18
  globals: true,
15
19
  environment: 'node',