@h-ai/cli 0.1.0-alpha.57 → 0.1.0-alpha.59

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 (177) hide show
  1. package/README.en.md +70 -21
  2. package/README.ja.md +70 -21
  3. package/README.md +70 -21
  4. package/dist/chunk-2H7UOFLK.js +0 -0
  5. package/dist/{chunk-O3ANVICQ.js → chunk-WUSFJFW5.js} +13 -7
  6. package/dist/chunk-WUSFJFW5.js.map +1 -0
  7. package/dist/{chunk-MJGUBOAV.js → chunk-WWG3U5ZD.js} +24 -42
  8. package/dist/chunk-WWG3U5ZD.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-ZYXES3NT.js → cli-skill-templates-2KDUACT6.js} +3 -3
  12. package/dist/{cli-skill-templates-ZYXES3NT.js.map → cli-skill-templates-2KDUACT6.js.map} +1 -1
  13. package/dist/index.js +192 -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 +19 -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/.npmrc.hbs +1 -2
  23. package/templates/apps/api/Dockerfile.hbs +6 -5
  24. package/templates/apps/api/apps/{{projectName}}-contract/package.json.hbs +1 -1
  25. package/templates/apps/api/apps/{{projectName}}-contract/src/app-schemas.ts.hbs +2 -0
  26. package/templates/apps/api/apps/{{projectName}}-contract/tsup.config.ts.hbs +1 -1
  27. package/templates/apps/api/apps/{{projectName}}-service/config/_core.yml.hbs +8 -0
  28. package/templates/apps/api/apps/{{projectName}}-service/package.json.hbs +1 -1
  29. package/templates/apps/api/apps/{{projectName}}-service/src/app.ts.hbs +7 -8
  30. package/templates/apps/api/apps/{{projectName}}-service/src/index.ts.hbs +4 -3
  31. package/templates/apps/api/apps/{{projectName}}-service/src/lib/server/init.ts.hbs +0 -1
  32. package/templates/apps/api/apps/{{projectName}}-service/src/server/procedures/app-procedures.ts.hbs +4 -0
  33. package/templates/apps/api/apps/{{projectName}}-service/tests/service.test.ts.hbs +3 -1
  34. package/templates/apps/api/e2e/api-service.spec.ts.hbs +3 -1
  35. package/templates/apps/api/package.json.hbs +2 -2
  36. package/templates/apps/api/pnpm-workspace.yaml.hbs +26 -0
  37. package/templates/apps/api/tsconfig.base.json +0 -1
  38. package/templates/apps/fullstack/.dockerignore.hbs +3 -0
  39. package/templates/apps/fullstack/.npmrc.hbs +1 -2
  40. package/templates/apps/fullstack/Dockerfile.hbs +6 -5
  41. package/templates/apps/fullstack/apps/{{projectName}}-app/README.md.hbs +2 -2
  42. package/templates/apps/fullstack/apps/{{projectName}}-app/capacitor.config.ts.hbs +1 -1
  43. package/templates/apps/fullstack/apps/{{projectName}}-app/index.html.hbs +7 -2
  44. package/templates/apps/fullstack/apps/{{projectName}}-app/messages/en-US.json.hbs +1 -34
  45. package/templates/apps/fullstack/apps/{{projectName}}-app/messages/zh-CN.json.hbs +1 -34
  46. package/templates/apps/fullstack/apps/{{projectName}}-app/package.json.hbs +2 -2
  47. package/templates/apps/fullstack/apps/{{projectName}}-app/src/App.svelte.hbs +30 -170
  48. package/templates/apps/fullstack/apps/{{projectName}}-app/src/app.d.ts.hbs +1 -1
  49. package/templates/apps/fullstack/apps/{{projectName}}-app/src/lib/capacitor.ts.hbs +6 -5
  50. package/templates/apps/fullstack/apps/{{projectName}}-app/src/main.ts.hbs +1 -1
  51. package/templates/apps/fullstack/apps/{{projectName}}-app/vite.config.ts.hbs +48 -22
  52. package/templates/apps/fullstack/apps/{{projectName}}-desktop/README.md.hbs +3 -1
  53. package/templates/apps/fullstack/apps/{{projectName}}-desktop/index.html.hbs +6 -1
  54. package/templates/apps/fullstack/apps/{{projectName}}-desktop/messages/en-US.json.hbs +1 -28
  55. package/templates/apps/fullstack/apps/{{projectName}}-desktop/messages/zh-CN.json.hbs +1 -28
  56. package/templates/apps/fullstack/apps/{{projectName}}-desktop/package.json.hbs +5 -4
  57. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/App.svelte.hbs +10 -141
  58. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/Cargo.toml.hbs +5 -5
  59. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/tauri.conf.json.hbs +3 -3
  60. package/templates/apps/fullstack/apps/{{projectName}}-desktop/vite.config.ts.hbs +21 -2
  61. package/templates/apps/fullstack/apps/{{projectName}}-web/README.md.hbs +2 -2
  62. package/templates/apps/fullstack/apps/{{projectName}}-web/index.html.hbs +6 -1
  63. package/templates/apps/fullstack/apps/{{projectName}}-web/messages/en-US.json.hbs +1 -28
  64. package/templates/apps/fullstack/apps/{{projectName}}-web/messages/zh-CN.json.hbs +1 -28
  65. package/templates/apps/fullstack/apps/{{projectName}}-web/package.json.hbs +2 -2
  66. package/templates/apps/fullstack/apps/{{projectName}}-web/src/App.svelte.hbs +5 -143
  67. package/templates/apps/fullstack/apps/{{projectName}}-web/src/app.d.ts.hbs +1 -1
  68. package/templates/apps/fullstack/apps/{{projectName}}-web/src/main.ts.hbs +1 -1
  69. package/templates/apps/fullstack/apps/{{projectName}}-web/vite.config.ts.hbs +48 -22
  70. package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +206 -16
  71. package/templates/apps/fullstack/package.json.hbs +2 -2
  72. package/templates/apps/fullstack/packages/{{projectName}}-contract/README.md.hbs +2 -0
  73. package/templates/apps/fullstack/packages/{{projectName}}-contract/package.json.hbs +1 -1
  74. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-contract.ts.hbs +66 -0
  75. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-schemas.ts.hbs +96 -0
  76. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/app-schemas.ts.hbs +3 -0
  77. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/index.ts.hbs +3 -1
  78. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +5 -0
  79. package/templates/apps/fullstack/packages/{{projectName}}-contract/tests/contract.test.ts.hbs +3 -0
  80. package/templates/apps/fullstack/packages/{{projectName}}-contract/tsup.config.ts.hbs +1 -1
  81. package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +13 -3
  82. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_audit.yml.hbs +3 -0
  83. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_cache.yml.hbs +2 -0
  84. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_core.yml.hbs +10 -3
  85. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_db.yml.hbs +3 -0
  86. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_iam.yml.hbs +21 -0
  87. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_serv.yml.hbs +10 -3
  88. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_storage.yml.hbs +3 -0
  89. package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +10 -3
  90. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/app-server.ts.hbs +63 -28
  91. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/index.ts.hbs +26 -11
  92. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/admin-service.ts.hbs +276 -0
  93. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/messages.ts.hbs +29 -0
  94. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/admin-procedures.ts.hbs +94 -0
  95. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/app-procedures.ts.hbs +6 -0
  96. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/index.ts.hbs +5 -1
  97. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/runtime.ts.hbs +98 -0
  98. package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/app-server.test.ts.hbs +446 -33
  99. package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/runtime.test.ts.hbs +48 -0
  100. package/templates/apps/fullstack/packages/{{projectName}}-serv/tsup.config.ts.hbs +1 -1
  101. package/templates/apps/fullstack/packages/{{projectName}}-shared/README.md.hbs +19 -26
  102. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/en-US.json.hbs +78 -15
  103. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/zh-CN.json.hbs +78 -15
  104. package/templates/apps/fullstack/packages/{{projectName}}-shared/package.json.hbs +4 -1
  105. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/index.ts.hbs +3 -4
  106. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/api-client.ts.hbs +53 -27
  107. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AdminWorkspace.svelte.hbs +73 -0
  108. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AppShell.svelte.hbs +55 -45
  109. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AuditManagement.svelte.hbs +61 -0
  110. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/ProfileSettings.svelte.hbs +57 -0
  111. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/RoleManagement.svelte.hbs +49 -0
  112. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/UserManagement.svelte.hbs +174 -0
  113. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/management-store.svelte.ts.hbs +399 -0
  114. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/theme-store.svelte.ts.hbs +7 -39
  115. package/templates/apps/fullstack/packages/{{projectName}}-shared/svelte.config.js.hbs +1 -0
  116. package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/api-client.test.ts.hbs +151 -0
  117. package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/management-store.test.ts.hbs +101 -0
  118. package/templates/apps/fullstack/packages/{{projectName}}-shared/vitest.config.ts.hbs +7 -0
  119. package/templates/apps/fullstack/playwright.config.ts.hbs +6 -0
  120. package/templates/apps/fullstack/pnpm-workspace.yaml.hbs +24 -0
  121. package/templates/apps/fullstack/tsconfig.base.json +0 -1
  122. package/templates/apps/h5/src/routes/+layout.svelte.hbs +4 -0
  123. package/templates/apps/h5/src/routes/+page.svelte.hbs +3 -2
  124. package/templates/apps/mobile-app/index.html.hbs +2 -2
  125. package/templates/apps/mobile-app/src/App.svelte.hbs +6 -2
  126. package/templates/apps/mobile-app/src/lib/app-config.ts.hbs +13 -0
  127. package/templates/apps/website/src/routes/+layout.svelte.hbs +8 -2
  128. package/templates/apps/website/src/routes/+page.svelte.hbs +4 -3
  129. package/templates/base/.npmrc.hbs +1 -15
  130. package/templates/base/Dockerfile.hbs +9 -8
  131. package/templates/base/e2e/app.spec.ts.hbs +1 -0
  132. package/templates/base/package.json.hbs +39 -42
  133. package/templates/base/pnpm-workspace.yaml.hbs +26 -0
  134. package/templates/base/src/app.d.ts.hbs +4 -0
  135. package/templates/base/src/hooks.server.ts.hbs +0 -8
  136. package/templates/base/src/lib/server/init.ts.hbs +26 -5
  137. package/templates/base/src/routes/+layout.server.ts.hbs +18 -0
  138. package/templates/base/tests/scaffold.test.ts.hbs +21 -1
  139. package/templates/base/vite.config.ts.hbs +21 -0
  140. package/templates/features/ai/routes/api/chat/+server.ts +6 -7
  141. package/templates/features/iam/routes-admin/(auth)/auth/login/+page.svelte.hbs +1 -1
  142. package/templates/features/iam/routes-h5/auth/login/+page.svelte.hbs +1 -1
  143. package/templates/features/iam/routes-shared/api/auth/login/+server.ts +14 -10
  144. package/templates/features/iam/routes-shared/api/auth/logout/+server.ts +6 -4
  145. package/templates/features/storage/routes/api/upload/+server.ts +10 -8
  146. package/templates/skills/CLAUDE.md +0 -14
  147. package/templates/skills/bridges/fullstack/AGENTS.md.hbs +13 -2
  148. package/templates/skills/bridges/fullstack/copilot-instructions.md.hbs +3 -0
  149. package/templates/skills/hai-api-client/SKILL.md +1 -1
  150. package/templates/skills/hai-app-create/SKILL.md +2 -0
  151. package/templates/skills/hai-app-create/development.md +21 -0
  152. package/templates/skills/hai-build/reference.md +4 -2
  153. package/templates/skills/hai-core/SKILL.md +2 -0
  154. package/templates/skills/hai-core/reference.md +6 -4
  155. package/templates/skills/hai-deploy/SKILL.md +2 -0
  156. package/templates/skills/hai-framework-sync/SKILL.md +5 -2
  157. package/templates/skills/hai-serv/SKILL.md +1 -0
  158. package/templates/skills/hai-serv/reference.md +3 -1
  159. package/templates/skills/hai-ui/SKILL.md +6 -0
  160. package/templates/skills/hai-ui/reference.md +7 -4
  161. package/templates/skills/hai-vecdb/reference.md +53 -49
  162. package/dist/chunk-MJGUBOAV.js.map +0 -1
  163. package/dist/chunk-O3ANVICQ.js.map +0 -1
  164. package/dist/cli-config-templates-OWBEGBZQ.js +0 -5
  165. package/dist/src-TBIET7YU.js.map +0 -1
  166. package/templates/apps/fullstack/apps/{{projectName}}-app/tests/api.test.ts.hbs +0 -28
  167. package/templates/apps/fullstack/apps/{{projectName}}-desktop/tests/api.test.ts.hbs +0 -28
  168. package/templates/apps/fullstack/apps/{{projectName}}-web/tests/api.test.ts.hbs +0 -55
  169. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/LanguageSwitcher.svelte.hbs +0 -27
  170. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/ThemeSwitcher.svelte.hbs +0 -18
  171. package/templates/skills/bridges/admin/CLAUDE.md +0 -15
  172. package/templates/skills/bridges/api/CLAUDE.md +0 -15
  173. package/templates/skills/bridges/fullstack/CLAUDE.md.hbs +0 -9
  174. package/templates/skills/bridges/h5/CLAUDE.md +0 -15
  175. package/templates/skills/bridges/mobile-app/CLAUDE.md +0 -15
  176. package/templates/skills/bridges/website/CLAUDE.md +0 -15
  177. package/templates/skills/claude-skill.md.hbs +0 -7
@@ -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}}
@@ -1,15 +1 @@
1
- # =============================================================================
2
- # pnpm configuration
3
- # =============================================================================
4
-
5
- # Hoist all packages to node_modules root (required for native addons like better-sqlite3)
6
- shamefully-hoist=true
7
-
8
- # Use hoisted node_modules layout instead of pnpm's default symlink isolation
9
- node-linker=hoisted
10
-
11
- # Do not fail on peer dependency conflicts
12
- strict-peer-dependencies=false
13
-
14
- # Automatically install missing peer dependencies
15
- auto-install-peers=true
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
  })
@@ -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.57",
4
+ "version": "0.1.0-alpha.59",
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
  // =============================================================================
@@ -30,6 +30,10 @@
30
30
  {{#if features.ai}}
31
31
  import type { AIConfigInput } from '@h-ai/ai'
32
32
  {{/if}}
33
+ {{#if features.audit}}
34
+ import type { AuditInitConfigInput } from '@h-ai/audit'
35
+ {{/if}}
36
+ import type { CoreConfig } from '@h-ai/core'
33
37
  {{#if features.iam}}
34
38
  import type { IamConfigSettingsInput } from '@h-ai/iam'
35
39
  {{/if}}
@@ -43,12 +47,15 @@ import type { StorageConfigInput } from '@h-ai/storage'
43
47
  import { ai } from '@h-ai/ai'
44
48
  {{/if}}
45
49
  {{#if features.audit}}
46
- import { audit } from '@h-ai/audit'
50
+ import { audit, AuditInitConfigSchema } from '@h-ai/audit'
47
51
  {{/if}}
48
52
  {{#if features.cache}}
49
53
  import { cache, CacheConfigSchema } from '@h-ai/cache'
50
54
  {{/if}}
51
55
  import { core } from '@h-ai/core'
56
+ {{#if features.crypto}}
57
+ import { crypto } from '@h-ai/crypto'
58
+ {{/if}}
52
59
  {{#if features.iam}}
53
60
  import { iam } from '@h-ai/iam'
54
61
  {{/if}}
@@ -81,9 +88,15 @@ export async function initApp(): Promise<void> {
81
88
  // 1. 加载配置
82
89
  core.init({
83
90
  configDir: './config',
84
- logging: { level: 'info' },
85
91
  })
86
92
 
93
+ {{#if features.crypto}}
94
+ // 加密模块初始化完成后才继续启动依赖它的 IAM / transport。
95
+ const cryptoResult = await crypto.init()
96
+ if (!cryptoResult.success)
97
+ throw new Error(`Crypto initialization failed: ${cryptoResult.error.message}`)
98
+ {{/if}}
99
+
87
100
  {{#if features.db}}
88
101
  // ─── 配置校验 ───
89
102
  const dbValidation = core.config.validate('db', ReldbConfigSchema)
@@ -97,6 +110,11 @@ export async function initApp(): Promise<void> {
97
110
  throw new Error(`Cache config invalid: ${cacheValidation.error.message}`)
98
111
  }
99
112
  {{/if}}
113
+ {{#if features.audit}}
114
+ const auditValidation = core.config.validate('audit', AuditInitConfigSchema)
115
+ if (!auditValidation.success)
116
+ throw new Error(`Audit config invalid: ${auditValidation.error.message}`)
117
+ {{/if}}
100
118
 
101
119
  {{#if features.db}}
102
120
  // ─── 获取配置 ───
@@ -108,6 +126,9 @@ export async function initApp(): Promise<void> {
108
126
  {{#if features.iam}}
109
127
  const iamConfig = core.config.getOrThrow<IamConfigSettingsInput>('iam')
110
128
  {{/if}}
129
+ {{#if features.audit}}
130
+ const auditConfig = core.config.getOrThrow<AuditInitConfigInput>('audit')
131
+ {{/if}}
111
132
  {{#if features.storage}}
112
133
  const storageConfig = core.config.get<StorageConfigInput>('storage')
113
134
  {{/if}}
@@ -177,9 +198,9 @@ export async function initApp(): Promise<void> {
177
198
 
178
199
  {{#if features.audit}}
179
200
  // ─── 初始化审计 ───
180
- const auditResult = await audit.init()
201
+ const auditResult = await audit.init(auditConfig)
181
202
  if (!auditResult.success) {
182
- core.logger.warn('Audit initialization failed', { error: auditResult.error.message })
203
+ throw new Error(`Audit initialization failed: ${auditResult.error.message}`)
183
204
  }
184
205
  {{/if}}
185
206
 
@@ -194,5 +215,5 @@ export async function initApp(): Promise<void> {
194
215
  {{/if}}
195
216
 
196
217
  initialized = true
197
- core.logger.info('{{projectName}} initialized.')
218
+ core.logger.info('Application initialized', { app: core.config.getOrThrow<CoreConfig>('core').name })
198
219
  }