@h-ai/cli 0.1.0-alpha.56 → 0.1.0-alpha.58

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 (208) hide show
  1. package/README.en.md +239 -0
  2. package/README.ja.md +239 -0
  3. package/README.md +51 -1
  4. package/dist/chunk-2H7UOFLK.js +0 -0
  5. package/dist/chunk-F4IBPVZ5.js +355 -0
  6. package/dist/chunk-F4IBPVZ5.js.map +1 -0
  7. package/dist/{chunk-O3ANVICQ.js → chunk-WUSFJFW5.js} +13 -7
  8. package/dist/chunk-WUSFJFW5.js.map +1 -0
  9. package/dist/cli-config-templates-6XA7V6CC.js +5 -0
  10. package/dist/{cli-config-templates-OWBEGBZQ.js.map → cli-config-templates-6XA7V6CC.js.map} +1 -1
  11. package/dist/{cli-skill-templates-ZIWYMS4Y.js → cli-skill-templates-45CK4RQ2.js} +3 -3
  12. package/dist/{cli-skill-templates-ZIWYMS4Y.js.map → cli-skill-templates-45CK4RQ2.js.map} +1 -1
  13. package/dist/index.js +134 -125
  14. package/dist/index.js.map +1 -1
  15. package/dist/{src-TBIET7YU.js → src-DUGLX4YB.js} +7270 -2119
  16. package/dist/src-DUGLX4YB.js.map +1 -0
  17. package/package.json +17 -17
  18. package/templates/README.md +4 -4
  19. package/templates/apps/admin/src/routes/+layout.svelte.hbs +7 -0
  20. package/templates/apps/admin/src/routes/+page.svelte.hbs +5 -4
  21. package/templates/apps/admin/src/routes/admin/+layout.svelte.hbs +2 -2
  22. package/templates/apps/api/.gitignore.hbs +13 -0
  23. package/templates/apps/api/.npmrc.hbs +1 -0
  24. package/templates/apps/api/Dockerfile.hbs +6 -5
  25. package/templates/apps/api/apps/{{projectName}}-contract/package.json.hbs +1 -1
  26. package/templates/apps/api/apps/{{projectName}}-contract/src/app-schemas.ts.hbs +2 -0
  27. package/templates/apps/api/apps/{{projectName}}-contract/tsup.config.ts.hbs +1 -1
  28. package/templates/apps/api/apps/{{projectName}}-service/config/_core.yml.hbs +8 -0
  29. package/templates/apps/api/apps/{{projectName}}-service/package.json.hbs +1 -1
  30. package/templates/apps/api/apps/{{projectName}}-service/src/app.ts.hbs +7 -8
  31. package/templates/apps/api/apps/{{projectName}}-service/src/index.ts.hbs +4 -3
  32. package/templates/apps/api/apps/{{projectName}}-service/src/lib/server/init.ts.hbs +0 -1
  33. package/templates/apps/api/apps/{{projectName}}-service/src/server/procedures/app-procedures.ts.hbs +4 -0
  34. package/templates/apps/api/apps/{{projectName}}-service/tests/service.test.ts.hbs +3 -1
  35. package/templates/apps/api/e2e/api-service.spec.ts.hbs +4 -2
  36. package/templates/apps/api/{eslint.config.js → eslint.config.js.hbs} +6 -8
  37. package/templates/apps/api/package.json.hbs +3 -3
  38. package/templates/apps/api/pnpm-workspace.yaml.hbs +26 -0
  39. package/templates/apps/api/tsconfig.base.json +0 -1
  40. package/templates/apps/fullstack/.dockerignore.hbs +3 -0
  41. package/templates/apps/fullstack/.gitignore.hbs +16 -0
  42. package/templates/apps/fullstack/.npmrc.hbs +1 -0
  43. package/templates/apps/fullstack/Dockerfile.hbs +6 -5
  44. package/templates/apps/fullstack/apps/{{projectName}}-app/README.md.hbs +2 -2
  45. package/templates/apps/fullstack/apps/{{projectName}}-app/capacitor.config.ts.hbs +1 -1
  46. package/templates/apps/fullstack/apps/{{projectName}}-app/eslint.config.js.hbs +5 -8
  47. package/templates/apps/fullstack/apps/{{projectName}}-app/index.html.hbs +7 -2
  48. package/templates/apps/fullstack/apps/{{projectName}}-app/messages/en-US.json.hbs +1 -34
  49. package/templates/apps/fullstack/apps/{{projectName}}-app/messages/zh-CN.json.hbs +1 -34
  50. package/templates/apps/fullstack/apps/{{projectName}}-app/package.json.hbs +2 -2
  51. package/templates/apps/fullstack/apps/{{projectName}}-app/src/App.svelte.hbs +30 -170
  52. package/templates/apps/fullstack/apps/{{projectName}}-app/src/app.d.ts.hbs +1 -1
  53. package/templates/apps/fullstack/apps/{{projectName}}-app/src/lib/capacitor.ts.hbs +6 -5
  54. package/templates/apps/fullstack/apps/{{projectName}}-app/src/main.ts.hbs +1 -1
  55. package/templates/apps/fullstack/apps/{{projectName}}-app/vite.config.ts.hbs +48 -22
  56. package/templates/apps/fullstack/apps/{{projectName}}-desktop/README.md.hbs +3 -1
  57. package/templates/apps/fullstack/apps/{{projectName}}-desktop/eslint.config.js.hbs +5 -8
  58. package/templates/apps/fullstack/apps/{{projectName}}-desktop/index.html.hbs +6 -1
  59. package/templates/apps/fullstack/apps/{{projectName}}-desktop/messages/en-US.json.hbs +1 -28
  60. package/templates/apps/fullstack/apps/{{projectName}}-desktop/messages/zh-CN.json.hbs +1 -28
  61. package/templates/apps/fullstack/apps/{{projectName}}-desktop/package.json.hbs +5 -4
  62. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/App.svelte.hbs +10 -141
  63. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/Cargo.toml.hbs +5 -5
  64. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/tauri.conf.json.hbs +3 -3
  65. package/templates/apps/fullstack/apps/{{projectName}}-desktop/vite.config.ts.hbs +21 -2
  66. package/templates/apps/fullstack/apps/{{projectName}}-web/README.md.hbs +2 -2
  67. package/templates/apps/fullstack/apps/{{projectName}}-web/eslint.config.js.hbs +5 -8
  68. package/templates/apps/fullstack/apps/{{projectName}}-web/index.html.hbs +6 -1
  69. package/templates/apps/fullstack/apps/{{projectName}}-web/messages/en-US.json.hbs +1 -28
  70. package/templates/apps/fullstack/apps/{{projectName}}-web/messages/zh-CN.json.hbs +1 -28
  71. package/templates/apps/fullstack/apps/{{projectName}}-web/package.json.hbs +2 -2
  72. package/templates/apps/fullstack/apps/{{projectName}}-web/src/App.svelte.hbs +5 -143
  73. package/templates/apps/fullstack/apps/{{projectName}}-web/src/app.d.ts.hbs +1 -1
  74. package/templates/apps/fullstack/apps/{{projectName}}-web/src/main.ts.hbs +1 -1
  75. package/templates/apps/fullstack/apps/{{projectName}}-web/vite.config.ts.hbs +48 -22
  76. package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +207 -17
  77. package/templates/apps/fullstack/{eslint.config.js → eslint.config.js.hbs} +6 -8
  78. package/templates/apps/fullstack/package.json.hbs +3 -3
  79. package/templates/apps/fullstack/packages/{{projectName}}-contract/README.md.hbs +2 -0
  80. package/templates/apps/fullstack/packages/{{projectName}}-contract/package.json.hbs +1 -1
  81. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-contract.ts.hbs +66 -0
  82. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-schemas.ts.hbs +96 -0
  83. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/app-schemas.ts.hbs +3 -0
  84. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/index.ts.hbs +3 -1
  85. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +5 -0
  86. package/templates/apps/fullstack/packages/{{projectName}}-contract/tests/contract.test.ts.hbs +3 -0
  87. package/templates/apps/fullstack/packages/{{projectName}}-contract/tsup.config.ts.hbs +1 -1
  88. package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +13 -3
  89. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_audit.yml.hbs +3 -0
  90. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_cache.yml.hbs +2 -0
  91. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_core.yml.hbs +10 -3
  92. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_db.yml.hbs +3 -0
  93. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_iam.yml.hbs +21 -0
  94. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_serv.yml.hbs +10 -3
  95. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_storage.yml.hbs +3 -0
  96. package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +10 -3
  97. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/app-server.ts.hbs +63 -28
  98. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/index.ts.hbs +26 -11
  99. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/admin-service.ts.hbs +276 -0
  100. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/messages.ts.hbs +29 -0
  101. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/admin-procedures.ts.hbs +94 -0
  102. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/app-procedures.ts.hbs +6 -0
  103. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/index.ts.hbs +5 -1
  104. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/runtime.ts.hbs +98 -0
  105. package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/app-server.test.ts.hbs +446 -33
  106. package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/runtime.test.ts.hbs +48 -0
  107. package/templates/apps/fullstack/packages/{{projectName}}-serv/tsup.config.ts.hbs +1 -1
  108. package/templates/apps/fullstack/packages/{{projectName}}-shared/README.md.hbs +19 -26
  109. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/en-US.json.hbs +78 -15
  110. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/zh-CN.json.hbs +78 -15
  111. package/templates/apps/fullstack/packages/{{projectName}}-shared/package.json.hbs +4 -1
  112. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/index.ts.hbs +3 -4
  113. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/api-client.ts.hbs +53 -27
  114. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AdminWorkspace.svelte.hbs +73 -0
  115. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AppShell.svelte.hbs +55 -45
  116. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AuditManagement.svelte.hbs +61 -0
  117. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/ProfileSettings.svelte.hbs +57 -0
  118. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/RoleManagement.svelte.hbs +49 -0
  119. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/UserManagement.svelte.hbs +174 -0
  120. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/management-store.svelte.ts.hbs +399 -0
  121. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/theme-store.svelte.ts.hbs +7 -39
  122. package/templates/apps/fullstack/packages/{{projectName}}-shared/svelte.config.js.hbs +1 -0
  123. package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/api-client.test.ts.hbs +151 -0
  124. package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/management-store.test.ts.hbs +101 -0
  125. package/templates/apps/fullstack/packages/{{projectName}}-shared/vitest.config.ts.hbs +7 -0
  126. package/templates/apps/fullstack/playwright.config.ts.hbs +6 -0
  127. package/templates/apps/fullstack/pnpm-workspace.yaml.hbs +24 -0
  128. package/templates/apps/fullstack/tsconfig.base.json +0 -1
  129. package/templates/apps/h5/src/routes/+layout.svelte.hbs +4 -0
  130. package/templates/apps/h5/src/routes/+page.svelte.hbs +3 -2
  131. package/templates/apps/mobile-app/index.html.hbs +2 -2
  132. package/templates/apps/mobile-app/src/App.svelte.hbs +6 -2
  133. package/templates/apps/mobile-app/src/lib/app-config.ts.hbs +13 -0
  134. package/templates/apps/website/src/routes/+layout.svelte.hbs +8 -2
  135. package/templates/apps/website/src/routes/+page.svelte.hbs +4 -3
  136. package/templates/base/.npmrc.hbs +1 -0
  137. package/templates/base/Dockerfile.hbs +9 -8
  138. package/templates/base/e2e/app.spec.ts.hbs +1 -0
  139. package/templates/base/eslint-rules.js +45 -0
  140. package/templates/base/eslint.config.js.hbs +6 -8
  141. package/templates/base/package.json.hbs +39 -42
  142. package/templates/base/pnpm-workspace.yaml.hbs +26 -0
  143. package/templates/base/src/app.d.ts.hbs +4 -0
  144. package/templates/base/src/hooks.server.ts.hbs +0 -8
  145. package/templates/base/src/lib/server/init.ts.hbs +26 -5
  146. package/templates/base/src/routes/+layout.server.ts.hbs +18 -0
  147. package/templates/base/tests/scaffold.test.ts.hbs +21 -1
  148. package/templates/base/vite.config.ts.hbs +21 -0
  149. package/templates/features/ai/routes/api/chat/+server.ts +6 -7
  150. package/templates/features/iam/routes-admin/(auth)/auth/login/+page.svelte.hbs +1 -1
  151. package/templates/features/iam/routes-h5/auth/login/+page.svelte.hbs +1 -1
  152. package/templates/features/iam/routes-shared/api/auth/login/+server.ts +14 -10
  153. package/templates/features/iam/routes-shared/api/auth/logout/+server.ts +6 -4
  154. package/templates/features/storage/routes/api/upload/+server.ts +10 -8
  155. package/templates/skills/AGENTS.md +9 -8
  156. package/templates/skills/CLAUDE.md +0 -10
  157. package/templates/skills/bridges/admin/AGENTS.md +8 -0
  158. package/templates/skills/bridges/admin/copilot-instructions.md +2 -0
  159. package/templates/skills/bridges/api/AGENTS.md +8 -1
  160. package/templates/skills/bridges/api/copilot-instructions.md +2 -0
  161. package/templates/skills/bridges/fullstack/AGENTS.md.hbs +21 -4
  162. package/templates/skills/bridges/fullstack/copilot-instructions.md.hbs +5 -0
  163. package/templates/skills/bridges/h5/AGENTS.md +8 -0
  164. package/templates/skills/bridges/h5/copilot-instructions.md +2 -0
  165. package/templates/skills/bridges/mobile-app/AGENTS.md +8 -0
  166. package/templates/skills/bridges/mobile-app/copilot-instructions.md +2 -0
  167. package/templates/skills/bridges/website/AGENTS.md +8 -0
  168. package/templates/skills/bridges/website/copilot-instructions.md +2 -0
  169. package/templates/skills/copilot-instructions.md +2 -0
  170. package/templates/skills/hai-api-client/SKILL.md +2 -0
  171. package/templates/skills/hai-app-create/SKILL.md +9 -7
  172. package/templates/skills/hai-app-create/development.md +72 -0
  173. package/templates/skills/hai-app-create/reference.md +44 -32
  174. package/templates/skills/hai-app-review/SKILL.md +50 -144
  175. package/templates/skills/hai-app-tests/SKILL.md +3 -1
  176. package/templates/skills/hai-app-tests/reference.md +47 -27
  177. package/templates/skills/hai-build/SKILL.md +5 -4
  178. package/templates/skills/hai-build/reference.md +56 -34
  179. package/templates/skills/hai-ci/SKILL.md +8 -15
  180. package/templates/skills/hai-core/SKILL.md +2 -0
  181. package/templates/skills/hai-core/reference.md +6 -4
  182. package/templates/skills/hai-framework-sync/SKILL.md +8 -2
  183. package/templates/skills/hai-pr-review/SKILL.md +5 -4
  184. package/templates/skills/hai-reldb/SKILL.md +1 -0
  185. package/templates/skills/hai-reldb/reference.md +3 -0
  186. package/templates/skills/hai-scheduler/SKILL.md +3 -0
  187. package/templates/skills/hai-serv/SKILL.md +2 -0
  188. package/templates/skills/hai-serv/reference.md +18 -2
  189. package/templates/skills/hai-storage/SKILL.md +3 -1
  190. package/templates/skills/hai-ui/SKILL.md +6 -0
  191. package/templates/skills/hai-ui/reference.md +7 -4
  192. package/templates/skills/hai-vecdb/reference.md +53 -49
  193. package/dist/chunk-O3ANVICQ.js.map +0 -1
  194. package/dist/chunk-WUYLYCW2.js +0 -237
  195. package/dist/chunk-WUYLYCW2.js.map +0 -1
  196. package/dist/cli-config-templates-OWBEGBZQ.js +0 -5
  197. package/dist/src-TBIET7YU.js.map +0 -1
  198. package/templates/apps/fullstack/apps/{{projectName}}-app/tests/api.test.ts.hbs +0 -28
  199. package/templates/apps/fullstack/apps/{{projectName}}-desktop/tests/api.test.ts.hbs +0 -28
  200. package/templates/apps/fullstack/apps/{{projectName}}-web/tests/api.test.ts.hbs +0 -55
  201. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/LanguageSwitcher.svelte.hbs +0 -27
  202. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/ThemeSwitcher.svelte.hbs +0 -18
  203. package/templates/skills/bridges/admin/CLAUDE.md +0 -11
  204. package/templates/skills/bridges/api/CLAUDE.md +0 -11
  205. package/templates/skills/bridges/fullstack/CLAUDE.md.hbs +0 -5
  206. package/templates/skills/bridges/h5/CLAUDE.md +0 -11
  207. package/templates/skills/bridges/mobile-app/CLAUDE.md +0 -11
  208. package/templates/skills/bridges/website/CLAUDE.md +0 -11
@@ -0,0 +1,101 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
2
+ import * as m from '../src/lib/paraglide/messages.js'
3
+ import { ManagementStore } from '../src/lib/stores/management-store.svelte.js'
4
+
5
+ const api = vi.hoisted(() => ({
6
+ auth: { clear: vi.fn(), setTokens: vi.fn() },
7
+ iam: { auth: { login: vi.fn(), logout: vi.fn(), currentUser: vi.fn() } },
8
+ admin: { users: { list: vi.fn() } },
9
+ }))
10
+ vi.mock('../src/lib/api/api-client.js', () => ({
11
+ managementApi: api,
12
+ initializeManagementApi: vi.fn(),
13
+ resolveAvatarUrl: (url: string | undefined) => url,
14
+ }))
15
+
16
+ const member = {
17
+ id: 'member-id',
18
+ username: 'member',
19
+ enabled: true,
20
+ roles: ['user'],
21
+ permissions: [],
22
+ createdAt: '2026-01-01T00:00:00.000Z',
23
+ updatedAt: '2026-01-01T00:00:00.000Z',
24
+ }
25
+ const administrator = { ...member, id: 'admin-id', username: 'admin', roles: ['admin'] }
26
+ const forbidden = { success: false, error: { code: 'test:forbidden', message: 'Forbidden', httpStatus: 403 } } as const
27
+
28
+ function deferred<T>() {
29
+ let resolve!: (result: T) => void
30
+ const promise = new Promise<T>((done) => {
31
+ resolve = done
32
+ })
33
+ return { promise, resolve }
34
+ }
35
+
36
+ beforeEach(() => {
37
+ vi.resetAllMocks()
38
+ api.iam.auth.login.mockResolvedValue({ success: true, data: { tokens: { accessToken: 'test-access', expiresIn: 3600, tokenType: 'Bearer' } } })
39
+ api.iam.auth.logout.mockResolvedValue({ success: true })
40
+ api.iam.auth.currentUser.mockResolvedValue({ success: true, data: member })
41
+ })
42
+
43
+ describe('management session and request ownership', () => {
44
+ it('ignores a previous administrator failure after logout and another user login', async () => {
45
+ const oldRequest = deferred<typeof forbidden>()
46
+ api.admin.users.list.mockReturnValueOnce(oldRequest.promise)
47
+ const store = new ManagementStore()
48
+ store.user = administrator
49
+ const loading = store.loadUsers()
50
+ await store.logout()
51
+ await store.login({ username: 'member', password: 'test-password', rememberMe: false })
52
+ oldRequest.resolve(forbidden)
53
+ await loading
54
+ expect(store.user?.id).toBe(member.id)
55
+ expect(store.page).toBe('settings')
56
+ expect(store.error).toBe('')
57
+ expect(store.loading).toBe(false)
58
+ expect(api.iam.auth.currentUser).toHaveBeenCalledTimes(1)
59
+ })
60
+
61
+ it('ignores an obsolete page failure after opening personal settings', async () => {
62
+ const oldRequest = deferred<typeof forbidden>()
63
+ api.admin.users.list.mockReturnValueOnce(oldRequest.promise)
64
+ const store = new ManagementStore()
65
+ store.user = administrator
66
+ const loading = store.loadUsers()
67
+ await store.navigate('settings')
68
+ oldRequest.resolve(forbidden)
69
+ await loading
70
+ expect(store.user?.id).toBe(administrator.id)
71
+ expect(store.page).toBe('settings')
72
+ expect(store.error).toBe('')
73
+ expect(store.loading).toBe(false)
74
+ expect(api.iam.auth.currentUser).not.toHaveBeenCalled()
75
+ })
76
+
77
+ it('refreshes revoked roles once and clears administration data', async () => {
78
+ api.admin.users.list.mockResolvedValueOnce(forbidden)
79
+ const store = new ManagementStore()
80
+ store.user = administrator
81
+ store.roles = [{ id: 'role-id', code: 'admin', name: 'Administrator', userCount: 1 }]
82
+ await store.loadUsers()
83
+ expect(store.user?.roles).toEqual(['user'])
84
+ expect(store.page).toBe('settings')
85
+ expect(store.roles).toEqual([])
86
+ expect(store.users).toEqual([])
87
+ expect(store.loading).toBe(false)
88
+ expect(store.error).toBe(m.forbidden())
89
+ expect(api.iam.auth.currentUser).toHaveBeenCalledTimes(1)
90
+ })
91
+
92
+ it('reports a connection failure separately from invalid credentials', async () => {
93
+ api.iam.auth.login.mockResolvedValueOnce({ success: false, error: { code: 'test:unavailable', message: 'Unavailable', httpStatus: 502 } })
94
+ const store = new ManagementStore()
95
+ await store.login({ username: 'member', password: 'test-password', rememberMe: false })
96
+ expect(store.error).toBe(m.network_error())
97
+ expect(store.error).not.toBe(m.login_invalid())
98
+ expect(store.saving).toBe(false)
99
+ expect(api.iam.auth.currentUser).not.toHaveBeenCalled()
100
+ })
101
+ })
@@ -0,0 +1,7 @@
1
+ import { svelte } from '@sveltejs/vite-plugin-svelte'
2
+ import { defineConfig } from 'vitest/config'
3
+
4
+ export default defineConfig({
5
+ plugins: [svelte()],
6
+ test: { environment: 'node', include: ['tests/**/*.test.ts'] },
7
+ })
@@ -55,6 +55,12 @@ export default defineConfig({
55
55
  env: {
56
56
  HOST: serviceHost,
57
57
  PORT: servicePort,
58
+ // 仅供脚手架验收:生产启动必须由部署环境提供初始管理员密码。
59
+ HAI_ADMIN_DEFAULT_PASSWORD: process.env.E2E_ADMIN_PASSWORD || 'Scaffold-test-Admin123!',
60
+ HAI_CORE_NAME: process.env.HAI_CORE_NAME || 'Configured scaffold',
61
+ HAI_CORE_VERSION: process.env.HAI_CORE_VERSION || '9.8.7',
62
+ HAI_CORE_ENV: process.env.HAI_CORE_ENV || 'test',
63
+ HAI_CORE_LOGGING_LEVEL: 'warn',
58
64
  },
59
65
  url: `${serviceBaseURL}/health`,
60
66
  reuseExistingServer: false,
@@ -2,6 +2,30 @@
2
2
  shellEmulator: true
3
3
 
4
4
  trustPolicy: no-downgrade
5
+ # 上游构建工具仍要求 4.x;4.0.3 tarball 已核对原 lockfile 的 SHA-512。
6
+ trustPolicyExclude:
7
+ - chokidar@4.0.3
8
+
9
+ # pnpm 12 配置;原生依赖仅运行明确列出的安装脚本。
10
+ nodeLinker: hoisted
11
+ allowBuilds:
12
+ onnxruntime-node: true
13
+ protobufjs: true
14
+ vue-demi: true
15
+ better-sqlite3: true
16
+ esbuild: true
17
+ core-js: false
18
+
19
+ overrides:
20
+ "@ai-sdk/provider-utils@>=4.0.0 <4.0.33": 4.0.57
21
+ cookie@<0.7.0: 0.7.2
22
+ esbuild@<0.28.1: 0.28.2
23
+ katex@<0.18.2: 0.18.10
24
+ sharp@<0.35.5: 0.35.5
25
+ tinypool@<2.1.2: 2.2.0
26
+ '@qdrant/js-client-rest>undici': 7.30.0
27
+ xcode>uuid: 11.1.1
28
+ "@types/node": "{{versions.nodeTypes}}"
5
29
 
6
30
  packages:
7
31
  - packages/*
@@ -3,7 +3,6 @@
3
3
  "target": "ES2022",
4
4
  "module": "NodeNext",
5
5
  "moduleResolution": "NodeNext",
6
- "ignoreDeprecations": "6.0",
7
6
  "resolveJsonModule": true,
8
7
  "strict": true,
9
8
  "esModuleInterop": true,
@@ -42,6 +42,10 @@
42
42
  {{/if}}
43
43
  </script>
44
44
 
45
+ <svelte:head>
46
+ <title>{page.data.appConfig.name}</title>
47
+ </svelte:head>
48
+
45
49
  <div class='min-h-screen flex flex-col bg-base-200'>
46
50
  <main class='flex-1 pb-16'>
47
51
  {@render children()}
@@ -1,5 +1,6 @@
1
1
  {{!-- H5 首页 --}}
2
2
  <script lang='ts'>
3
+ import { page } from '$app/state'
3
4
  /**
4
5
  * H5 首页
5
6
  */
@@ -11,9 +12,9 @@
11
12
 
12
13
  <svelte:head>
13
14
  {{#if hasI18n}}
14
- <title>{m.app_title()}</title>
15
+ <title>{page.data.appConfig.name}</title>
15
16
  {{else}}
16
- <title>H5 应用</title>
17
+ <title>{page.data.appConfig.name}</title>
17
18
  {{/if}}
18
19
  </svelte:head>
19
20
 
@@ -4,10 +4,10 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
6
6
  <meta name="theme-color" content="#2563eb" />
7
- <title>{{projectName}}</title>
7
+ <title></title>
8
8
  </head>
9
9
  <body>
10
10
  <div id="app"></div>
11
11
  <script type="module" src="/src/main.ts"></script>
12
12
  </body>
13
- </html>
13
+ </html>
@@ -2,6 +2,7 @@
2
2
  import { applyTheme, getSavedTheme, setGlobalLocale } from '@h-ai/ui'
3
3
  import { onMount } from 'svelte'
4
4
  import { closeApi, initApi, resolveApiBase, usesNativeTokenStorage } from './lib/api.js'
5
+ import { appConfig, initClientCore } from './lib/app-config.js'
5
6
  import { initCapacitor, isNativeApp } from './lib/capacitor.js'
6
7
  import * as m from './lib/paraglide/messages.js'
7
8
  import { getLocale } from './lib/paraglide/runtime.js'
@@ -22,6 +23,8 @@
22
23
 
23
24
  async function bootstrap(): Promise<void> {
24
25
  try {
26
+ initClientCore()
27
+ document.title = appConfig.name
25
28
  applyTheme(getSavedTheme(), false)
26
29
  setGlobalLocale(getLocale())
27
30
  await initCapacitor()
@@ -73,7 +76,7 @@
73
76
  {:else}
74
77
  <div class='hai-mobile-viewport'>
75
78
  <div class='hai-mobile-shell max-w-lg'>
76
- <AppBar title={m.app_title()} safeArea fixed={false} class='bg-base-100/95 backdrop-blur border-base-content/8' />
79
+ <AppBar title={appConfig.name} safeArea fixed={false} class='bg-base-100/95 backdrop-blur border-base-content/8' />
77
80
 
78
81
  <main class='hai-mobile-main'>
79
82
  {#if activeTab === 'home'}
@@ -102,6 +105,7 @@
102
105
  </div>
103
106
 
104
107
  <Card title={m.status_title()} shadow='sm'>
108
+ <p class='mb-3 text-xs text-base-content/50'>{appConfig.name} · {appConfig.version} · {appConfig.env}</p>
105
109
  <div class='grid grid-cols-2 gap-3 text-sm'>
106
110
  <div>
107
111
  <p class='text-base-content/50'>{m.status_api_label()}</p>
@@ -159,4 +163,4 @@
159
163
  </div>
160
164
  {/if}
161
165
 
162
- <ToastContainer />
166
+ <ToastContainer />
@@ -0,0 +1,13 @@
1
+ import type { CoreConfig } from '@h-ai/core'
2
+ import { core } from '@h-ai/core'
3
+
4
+ declare const __APP_CORE_CONFIG__: Pick<CoreConfig, 'name' | 'version' | 'env' | 'defaultLocale'> & {
5
+ logging?: Pick<NonNullable<CoreConfig['logging']>, 'level' | 'format'>
6
+ }
7
+
8
+ /** Vite 经 core 加载后注入的公开配置,修改 YAML 后重新构建客户端。 */
9
+ export const appConfig = __APP_CORE_CONFIG__
10
+
11
+ export function initClientCore(): void {
12
+ core.init({ logging: appConfig.logging })
13
+ }
@@ -8,6 +8,7 @@
8
8
  import { browser } from '$app/environment'
9
9
  {{/if}}
10
10
  import { resolve } from '$app/paths'
11
+ import { page } from '$app/state'
11
12
  {{#if hasI18n}}
12
13
  import * as m from '$lib/paraglide/messages'
13
14
  import { getLocale } from '$lib/paraglide/runtime.js'
@@ -43,13 +44,17 @@
43
44
  {{/if}}
44
45
  </script>
45
46
 
47
+ <svelte:head>
48
+ <title>{page.data.appConfig.name}</title>
49
+ </svelte:head>
50
+
46
51
  <div class='min-h-screen flex flex-col'>
47
52
  <header class='navbar bg-base-100 shadow-sm'>
48
53
  <div class='flex-1'>
49
54
  {{#if hasI18n}}
50
- <a href={resolve('/', {})} class='btn btn-ghost text-xl font-black tracking-tight'>{m.app_title()}</a>
55
+ <a href={resolve('/', {})} class='btn btn-ghost text-xl font-black tracking-tight'>{page.data.appConfig.name}</a>
51
56
  {{else}}
52
- <a href={resolve('/', {})} class='btn btn-ghost text-xl font-black tracking-tight'>官网</a>
57
+ <a href={resolve('/', {})} class='btn btn-ghost text-xl font-black tracking-tight'>{page.data.appConfig.name}</a>
53
58
  {{/if}}
54
59
  </div>
55
60
  <nav class='flex-none'>
@@ -66,6 +71,7 @@
66
71
  </main>
67
72
 
68
73
  <footer class='footer footer-center p-4 bg-base-300 text-base-content'>
74
+ <span>{page.data.appConfig.name} · {page.data.appConfig.version} · {page.data.appConfig.env}</span>
69
75
  {{#if hasI18n}}
70
76
  <p>{m.footer_copyright({ year: new Date().getFullYear() })}</p>
71
77
  {{else}}
@@ -4,6 +4,7 @@
4
4
  * 官网首页
5
5
  */
6
6
  import { resolve } from '$app/paths'
7
+ import { page } from '$app/state'
7
8
  {{#if hasI18n}}
8
9
  import * as m from '$lib/paraglide/messages'
9
10
  {{/if}}
@@ -12,9 +13,9 @@
12
13
 
13
14
  <svelte:head>
14
15
  {{#if hasI18n}}
15
- <title>{m.app_title()}</title>
16
+ <title>{page.data.appConfig.name}</title>
16
17
  {{else}}
17
- <title>官网</title>
18
+ <title>{page.data.appConfig.name}</title>
18
19
  {{/if}}
19
20
  </svelte:head>
20
21
 
@@ -25,7 +26,7 @@
25
26
  <Badge variant='primary'>
26
27
  <span class='icon-[tabler--sparkles] size-4'></span>
27
28
  {{#if hasI18n}}
28
- {m.app_title()}
29
+ {page.data.appConfig.name}
29
30
  {{else}}
30
31
  由 hai 驱动
31
32
  {{/if}}
@@ -0,0 +1 @@
1
+ # 注册表与认证可配置在此;pnpm 专属设置统一位于 pnpm-workspace.yaml。
@@ -1,15 +1,15 @@
1
1
  # syntax=docker/dockerfile:1.7
2
2
  {{#if isSvelteOnlyApp}}
3
- FROM node:22-bookworm-slim AS build
3
+ FROM node:24-bookworm-slim AS build
4
4
 
5
5
  ENV PNPM_HOME=/pnpm
6
6
  ENV PATH=$PNPM_HOME:$PATH
7
7
  ENV CI=true
8
8
  WORKDIR /workspace
9
9
 
10
- RUN corepack enable && corepack prepare pnpm@9.15.0 --activate
10
+ RUN corepack enable && corepack prepare pnpm@12.11.2 --activate
11
11
  COPY pnpm-lock.yaml pnpm-workspace.yaml ./
12
- RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm fetch --frozen-lockfile
12
+ RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm fetch
13
13
  COPY . .
14
14
  RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm install --offline --frozen-lockfile --ignore-scripts
15
15
  RUN pnpm build
@@ -23,24 +23,25 @@ EXPOSE 8080
23
23
  HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
24
24
  CMD wget -q -O /dev/null http://127.0.0.1:8080/health || exit 1
25
25
  {{else}}
26
- FROM node:22-bookworm-slim AS build
26
+ FROM node:24-bookworm-slim AS build
27
27
 
28
28
  ENV PNPM_HOME=/pnpm
29
29
  ENV PATH=$PNPM_HOME:$PATH
30
30
  ENV CI=true
31
31
  WORKDIR /workspace
32
32
 
33
- RUN corepack enable && corepack prepare pnpm@9.15.0 --activate
33
+ RUN corepack enable && corepack prepare pnpm@12.11.2 --activate
34
34
  COPY pnpm-lock.yaml pnpm-workspace.yaml ./
35
- RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm fetch --frozen-lockfile
35
+ RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm fetch
36
36
  COPY . .
37
37
  RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm install --offline --frozen-lockfile --ignore-scripts
38
38
  RUN pnpm build
39
- RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm --filter {{projectName}} --prod deploy /prod/app
39
+ RUN --mount=type=cache,id={{projectName}}-pnpm,target=/pnpm/store pnpm pm deploy --filter {{projectName}} --prod /prod/app
40
40
 
41
- FROM node:22-bookworm-slim AS runtime-base
41
+ FROM node:24-bookworm-slim AS runtime-base
42
42
 
43
43
  ENV NODE_ENV=production
44
+ ENV HAI_CORE_ENV=production
44
45
  ENV HOST=0.0.0.0
45
46
  ENV PORT=3000
46
47
  WORKDIR /app
@@ -5,6 +5,7 @@ test('home page renders from browser', async ({ page }) => {
5
5
  const pageErrors: string[] = []
6
6
  page.on('pageerror', error => pageErrors.push(error.message))
7
7
  await page.goto('/')
8
+ await expect(page).toHaveTitle(process.env.HAI_CORE_NAME ?? '{{projectName}}')
8
9
  await expect(pageErrors).toEqual([])
9
10
  await expect(page.locator('main, section').first()).toBeVisible()
10
11
  })
@@ -0,0 +1,45 @@
1
+ /**
2
+ * 应用共享质量门禁。依赖 Antfu 已注册的 TypeScript / ESLint comments 插件。
3
+ * 必要第三方 workaround 使用单行 eslint-disable-next-line <规则> -- 具体原因,
4
+ * 不关闭整个文件的检查。秘密泄漏、输入/权限校验仍需结合业务审查。
5
+ */
6
+ export const haiQualityConfig = {
7
+ files: ['**/*.{js,mjs,cjs,ts,tsx,svelte}'],
8
+ linterOptions: {
9
+ reportUnusedDisableDirectives: 'error',
10
+ },
11
+ rules: {
12
+ 'no-console': ['error', {}],
13
+ 'ts/no-explicit-any': 'error',
14
+ 'ts/ban-ts-comment': ['error', {
15
+ 'ts-ignore': true,
16
+ 'ts-nocheck': true,
17
+ 'ts-check': false,
18
+ 'ts-expect-error': 'allow-with-description',
19
+ 'minimumDescriptionLength': 10,
20
+ }],
21
+ 'eslint-comments/no-unlimited-disable': 'error',
22
+ 'eslint-comments/require-description': 'error',
23
+ // 只禁内部源码/构建目录,公开的 /client、/adapter 等 exports 子路径可用。
24
+ 'no-restricted-imports': ['error', {
25
+ patterns: [{
26
+ group: ['@h-ai/*/src', '@h-ai/*/src/**', '@h-ai/*/dist', '@h-ai/*/dist/**'],
27
+ message: 'Use the public exports of hai packages instead of their src/dist internals.',
28
+ }],
29
+ }],
30
+ 'no-restricted-syntax': ['error', {
31
+ selector: ':matches(TSAsExpression, TSTypeAssertion)[expression.typeAnnotation.type="TSUnknownKeyword"]',
32
+ message: 'Use the real upstream type or narrow unknown. Explain necessary third-party workarounds with a scoped lint exception.',
33
+ }, {
34
+ selector: 'ImportExpression[source.value=/^@h-ai\\/[^/]+\\/(src|dist)(\\/|$)/]',
35
+ message: 'Use the public exports of hai packages instead of their src/dist internals.',
36
+ }, {
37
+ // 仅识别明确的静态敏感键;变量键、别名及业务敏感程度仍需审查。
38
+ selector: 'CallExpression[callee.property.name="setItem"][callee.object.name="localStorage"][arguments.0.value=/^(token|password|secret|api[_-]?key|(access|refresh|auth|session)[_-]?token)$/i]',
39
+ message: 'Keep sensitive tokens in memory, httpOnly cookies or a secure native TokenStore instead of localStorage.',
40
+ }, {
41
+ selector: 'CallExpression[callee.property.name="setItem"][callee.object.property.name="localStorage"][arguments.0.value=/^(token|password|secret|api[_-]?key|(access|refresh|auth|session)[_-]?token)$/i]',
42
+ message: 'Keep sensitive tokens in memory, httpOnly cookies or a secure native TokenStore instead of localStorage.',
43
+ }],
44
+ },
45
+ }
@@ -4,9 +4,12 @@
4
4
  * @see https://github.com/antfu/eslint-config
5
5
  */
6
6
 
7
- import antfu from '@antfu/eslint-config'
7
+ import antfu, { GLOB_SRC } from '@antfu/eslint-config'
8
+ import { haiQualityConfig } from './eslint-rules.js'
8
9
 
9
10
  export default antfu({
11
+ // unused-imports 使用 TS 规则,JS 同样使用 TS parser 以保持 scope 契约一致。
12
+ typescript: { files: [GLOB_SRC] },
10
13
  formatters: true,
11
14
  ignores: [
12
15
  {{#unless isSvelteOnlyApp}}
@@ -18,6 +21,7 @@ export default antfu({
18
21
  '**/project.inlang/**',
19
22
  '**/paraglide/**',
20
23
  '**/.agents/**',
24
+ '**/.claude/**',
21
25
  '**/.github/**',
22
26
  '**/AGENTS.md',
23
27
  '**/CLAUDE.md',
@@ -27,10 +31,4 @@ export default antfu({
27
31
  '**/pnpm-workspace.yaml',
28
32
  ],
29
33
  svelte: true,
30
- }, {
31
- files: ['**/*.ts', '**/*.svelte'],
32
- rules: {
33
- 'no-console': 'error',
34
- 'ts/no-explicit-any': 'error',
35
- },
36
- })
34
+ }, haiQualityConfig)
@@ -1,9 +1,9 @@
1
1
  {
2
- "engines": { "node": ">=22.12.0" },
2
+ "engines": { "node": "^22.22.2 || ^24.15.0 || >=26.0.0" },
3
3
  "name": "{{projectName}}",
4
- "version": "0.1.0-alpha.56",
4
+ "version": "0.1.0-alpha.58",
5
5
  "private": true,
6
- "packageManager": "pnpm@9.15.0",
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",
@@ -75,51 +75,48 @@
75
75
  "@h-ai/capacitor": "{{haiPackageSpecifier}}"{{/if}}{{#if isCapacitorApp}}{{#unless features.api-client}},
76
76
  "@h-ai/api-client": "{{haiPackageSpecifier}}"{{/unless}}{{#unless features.capacitor}},
77
77
  "@h-ai/capacitor": "{{haiPackageSpecifier}}"{{/unless}}{{/if}},
78
- "zod": "^4.4.3"
78
+ "zod": "{{versions.zod}}"
79
79
  {{/if}}
80
80
  },
81
81
  "devDependencies": {
82
- "@antfu/eslint-config": "^9.0.0",
83
- "@playwright/test": "^1.60.0",
82
+ "@antfu/eslint-config": "{{versions.antfuEslintConfig}}",
83
+ "@playwright/test": "{{versions.playwright}}",
84
84
  {{#if isCapacitorApp}}
85
- "@aparajita/capacitor-secure-storage": "^8.0.0",
86
- "@capacitor/app": "^8.0.1",
87
- "@capacitor/camera": "^8.0.1",
88
- "@capacitor/cli": "^8.3.4",
89
- "@capacitor/core": "^8.3.4",
90
- "@capacitor/android": "^8.3.4",
91
- "@capacitor/device": "^8.0.1",
92
- "@capacitor/ios": "^8.3.4",
93
- "@capacitor/preferences": "^8.0.1",
94
- "@capacitor/push-notifications": "^8.0.1",
95
- "@capacitor/status-bar": "^8.0.1",
85
+ "@aparajita/capacitor-secure-storage": "{{versions.capacitorSecureStorage}}",
86
+ "@capacitor/app": "{{versions.capacitorApp}}",
87
+ "@capacitor/camera": "{{versions.capacitorCamera}}",
88
+ "@capacitor/cli": "{{versions.capacitorCli}}",
89
+ "@capacitor/core": "{{versions.capacitorCore}}",
90
+ "@capacitor/android": "{{versions.capacitorAndroid}}",
91
+ "@capacitor/device": "{{versions.capacitorDevice}}",
92
+ "@capacitor/ios": "{{versions.capacitorIos}}",
93
+ "@capacitor/preferences": "{{versions.capacitorPreferences}}",
94
+ "@capacitor/push-notifications": "{{versions.capacitorPushNotifications}}",
95
+ "@capacitor/status-bar": "{{versions.capacitorStatusBar}}",
96
96
  {{else}}
97
- "@sveltejs/adapter-node": "^5.5.4",
97
+ "@sveltejs/adapter-node": "{{versions.svelteAdapterNode}}",
98
98
  {{/if}}
99
99
  {{#unless isSvelteOnlyApp}}
100
- "@sveltejs/kit": "^2.61.1",
100
+ "@sveltejs/kit": "{{versions.svelteKit}}",
101
101
  {{/unless}}
102
- "@sveltejs/vite-plugin-svelte": "^7.1.2",
103
- "@types/node": "^25.9.1",
104
- "eslint": "^10.4.0",
105
- "eslint-plugin-format": "^2.0.1",
106
- "eslint-plugin-svelte": "^3.17.1",
107
- "rimraf": "^6.1.3",
108
- "svelte": "^5.55.9",
109
- "svelte-check": "^4.4.8",
110
- "svelte-eslint-parser": "^1.6.1",
111
- "typescript": "^6.0.3",
112
- "vite": "^8.0.14",
113
- "vitest": "^4.1.7"{{#if hasUi}},
114
- "@tailwindcss/vite": "^4.3.0",
115
- "tailwindcss": "^4.3.0",
116
- "daisyui": "^5.5.20",
117
- "@iconify-json/tabler": "^1.2.35",
118
- "@iconify/tailwind4": "^1.2.3"{{/if}}{{#if hasI18n}},
119
- "@inlang/paraglide-js": "^2.18.1",
120
- "@inlang/plugin-message-format": "^4.4.0"{{/if}}
121
- }{{#if features.db}},
122
- "pnpm": {
123
- "onlyBuiltDependencies": ["better-sqlite3"]
124
- }{{/if}}
102
+ "@sveltejs/vite-plugin-svelte": "{{versions.sveltePlugin}}",
103
+ "@types/node": "{{versions.nodeTypes}}",
104
+ "eslint": "{{versions.eslint}}",
105
+ "eslint-plugin-format": "{{versions.eslintPluginFormat}}",
106
+ "eslint-plugin-svelte": "{{versions.eslintPluginSvelte}}",
107
+ "rimraf": "{{versions.rimraf}}",
108
+ "svelte": "{{versions.svelte}}",
109
+ "svelte-check": "{{versions.svelteCheck}}",
110
+ "svelte-eslint-parser": "{{versions.svelteEslintParser}}",
111
+ "typescript": "{{versions.typescript}}",
112
+ "vite": "{{versions.vite}}",
113
+ "vitest": "{{versions.vitest}}"{{#if hasUi}},
114
+ "@tailwindcss/vite": "{{versions.tailwindcssVite}}",
115
+ "tailwindcss": "{{versions.tailwindcss}}",
116
+ "daisyui": "{{versions.daisyui}}",
117
+ "@iconify-json/tabler": "{{versions.iconifyJsonTabler}}",
118
+ "@iconify/tailwind4": "{{versions.iconifyTailwind}}"{{/if}}{{#if hasI18n}},
119
+ "@inlang/paraglide-js": "{{versions.inlangParaglide}}",
120
+ "@inlang/plugin-message-format": "{{versions.inlangMessageFormat}}"{{/if}}
121
+ }
125
122
  }
@@ -3,6 +3,32 @@
3
3
  shellEmulator: true
4
4
 
5
5
  trustPolicy: no-downgrade
6
+ # 上游构建工具仍要求 4.x;4.0.3 tarball 已核对原 lockfile 的 SHA-512。
7
+ trustPolicyExclude:
8
+ - chokidar@4.0.3
9
+
10
+ # pnpm 12 配置;原生依赖仅运行明确列出的安装脚本。
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
21
+
22
+ overrides:
23
+ "@ai-sdk/provider-utils@>=4.0.0 <4.0.33": 4.0.57
24
+ cookie@<0.7.0: 0.7.2
25
+ esbuild@<0.28.1: 0.28.2
26
+ katex@<0.18.2: 0.18.10
27
+ sharp@<0.35.5: 0.35.5
28
+ tinypool@<2.1.2: 2.2.0
29
+ '@qdrant/js-client-rest>undici': 7.30.0
30
+ xcode>uuid: 11.1.1
31
+ "@types/node": "{{versions.nodeTypes}}"
6
32
 
7
33
  packages:
8
34
  - .
@@ -6,6 +6,10 @@ import '@h-ai/ui/auto-import'
6
6
  {{/if}}
7
7
  declare global {
8
8
  namespace App {
9
+ interface PageData {
10
+ /** 经服务端 core 解析后可公开的应用配置 */
11
+ appConfig: Pick<import('@h-ai/core').CoreConfig, 'name' | 'version' | 'env' | 'defaultLocale'>
12
+ }
9
13
  interface Locals {
10
14
  /** 请求 ID */
11
15
  requestId: string
@@ -10,19 +10,11 @@ import { paraglideMiddleware } from '$lib/paraglide/server.js'
10
10
  {{/if}}
11
11
  import { initApp } from '$lib/server/init.js'
12
12
  import { core } from '@h-ai/core'
13
- {{#if features.crypto}}
14
- import { crypto } from '@h-ai/crypto'
15
- {{/if}}
16
13
  {{#if features.iam}}
17
14
  import { iam } from '@h-ai/iam'
18
15
  {{/if}}
19
16
  import { kit } from '@h-ai/kit'
20
17
 
21
- {{#if features.crypto}}
22
- // 初始化加密模块(同步)
23
- crypto.init()
24
-
25
- {{/if}}
26
18
  // =============================================================================
27
19
  // 应用初始化
28
20
  // =============================================================================