@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
@@ -2,39 +2,6 @@
2
2
  {{#if fullstack.frontends.app}}
3
3
  {
4
4
  "$schema": "https://inlang.com/schema/inlang-message-format",
5
- "page_title": "{name} · App",
6
- "platform_name": "App/H5",
7
- "nav_workspace": "Workspace",
8
- "nav_status": "Status",
9
- "nav_settings": "Settings",
10
- "settings_description": "Switch theme and language here to verify shared theme and i18n state take effect instantly on mobile.",
11
- "settings_theme_description": "Theme switching reuses the shared theme store and persists the preference on the device.",
12
- "settings_language_description": "Language switching keeps the shared runtime and the app runtime in sync.",
13
- "hero_badge": "Mobile workspace",
14
- "hero_title": "{name} App Experience",
15
- "hero_subtitle": "A mobile and H5 oriented entry point. This app keeps its own messages so onboarding and campaign copy can evolve independently.",
16
- "hero_primary_action": "View service status",
17
- "hero_secondary_action": "Customize the starter",
18
- "preview_title": "Mobile-first interface",
19
- "preview_body": "Ready for H5, Capacitor or embedded WebViews",
20
- "preview_metric_shared": "Shared shell and API",
21
- "preview_metric_local": "App-owned messages",
22
- "preview_metric_theme": "Theme from config",
23
- "status_title": "Service connectivity",
24
- "status_description": "The mobile page calls the same backend API to verify cross-platform contract and shared API client wiring.",
25
- "status_online": "{name} is connected",
26
- "status_version": "Service version",
27
- "status_started": "Started at: {time}",
28
- "status_frontends": "Service frontends: {list}",
29
- "status_frontends_count": "{count} frontend targets",
30
- "custom_shared_title": "Shared owns common capabilities",
31
- "custom_shared_body": "Keep cross-platform layout, locale, theme and API access in packages/{{projectName}}-shared.",
32
- "custom_local_title": "App owns mobile copy",
33
- "custom_local_body": "Write App-specific copy in apps/{{projectName}}-app/messages so mobile UX can iterate independently.",
34
- "flow_title": "Collaboration boundary",
35
- "flow_contract": "Contract constrains requests/responses",
36
- "flow_service": "Service exposes unified APIs",
37
- "flow_shared": "Shared reuses cross-platform capabilities",
38
- "flow_frontend": "App composes the mobile experience"
5
+ "page_title": "{name}"
39
6
  }
40
7
  {{/if}}
@@ -2,39 +2,6 @@
2
2
  {{#if fullstack.frontends.app}}
3
3
  {
4
4
  "$schema": "https://inlang.com/schema/inlang-message-format",
5
- "page_title": "{name} · App",
6
- "platform_name": "App/H5",
7
- "nav_workspace": "工作台",
8
- "nav_status": "状态",
9
- "nav_settings": "设置",
10
- "settings_description": "在这里切换主题与语言,验证 shared 的主题与 i18n 在移动端即时生效。",
11
- "settings_theme_description": "主题切换复用 shared theme store,并将偏好持久化到本地设备。",
12
- "settings_language_description": "语言切换会同时同步 shared runtime 与当前 App runtime。",
13
- "hero_badge": "移动端工作台",
14
- "hero_title": "{name} App 体验",
15
- "hero_subtitle": "面向移动端与 H5 场景的轻量入口,保留本端 messages 以便独立调整文案、引导语和运营内容。",
16
- "hero_primary_action": "查看服务状态",
17
- "hero_secondary_action": "了解如何自定义",
18
- "preview_title": "移动优先界面",
19
- "preview_body": "适合 H5、Capacitor 或内嵌 WebView",
20
- "preview_metric_shared": "共享 Shell 与接口",
21
- "preview_metric_local": "App 自有 messages",
22
- "preview_metric_theme": "主题跟随配置",
23
- "status_title": "服务联通状态",
24
- "status_description": "移动端页面会调用同一套后端 API,验证跨端 contract 与 shared API client 正常工作。",
25
- "status_online": "{name} 已连接",
26
- "status_version": "服务版本",
27
- "status_started": "启动时间:{time}",
28
- "status_frontends": "服务声明的前端:{list}",
29
- "status_frontends_count": "{count} 个前端目标",
30
- "custom_shared_title": "共享层放通用能力",
31
- "custom_shared_body": "跨端一致的布局、语言、主题和 API 访问都放在 packages/{{projectName}}-shared。",
32
- "custom_local_title": "App 层放移动文案",
33
- "custom_local_body": "App 独有文案写在 apps/{{projectName}}-app/messages,便于移动端独立迭代。",
34
- "flow_title": "协同边界",
35
- "flow_contract": "Contract 约束请求响应",
36
- "flow_service": "Service 提供统一 API",
37
- "flow_shared": "Shared 复用跨端能力",
38
- "flow_frontend": "App 组织移动端体验"
5
+ "page_title": "{name}"
39
6
  }
40
7
  {{/if}}
@@ -5,7 +5,7 @@
5
5
  "type": "module",
6
6
  "version": "0.1.0",
7
7
  "private": true,
8
- "engines": { "node": ">=22.12.0" },
8
+ "engines": { "node": "^22.22.2 || ^24.15.0 || >=26.0.0" },
9
9
  "scripts": {
10
10
  "paraglide:compile": "paraglide-js compile --project ./project.inlang --outdir ./src/lib/paraglide",
11
11
  "paraglide:watch": "paraglide-js compile --project ./project.inlang --outdir ./src/lib/paraglide --watch",
@@ -16,7 +16,7 @@
16
16
  "preview": "vite preview --host 127.0.0.1 --port {{fullstack.ports.app}} --strictPort",
17
17
  "typecheck": "pnpm paraglide:compile && svelte-check --tsconfig ./tsconfig.json",
18
18
  "lint": "eslint .",
19
- "test": "pnpm paraglide:compile && vitest run",
19
+ "test": "pnpm paraglide:compile && vitest run --passWithNoTests",
20
20
  "test:watch": "pnpm paraglide:compile && vitest",
21
21
  "clean": "rimraf dist build android ios .turbo src/lib/paraglide",
22
22
  "cap:add:android": "cap add android",
@@ -1,186 +1,46 @@
1
1
  {{! @skipIfEmpty }}
2
2
  {{#if fullstack.frontends.app}}
3
3
  <script lang="ts">
4
- import type { AppInfo } from '{{fullstack.sharedPackageName}}'
5
- import * as appM from './lib/paraglide/messages.js'
6
- import { setLocale } from './lib/paraglide/runtime.js'
7
- import { Alert, Button, Card, Skeleton } from '@h-ai/ui'
4
+ import type { ManagementApiOptions } from '{{fullstack.sharedPackageName}}'
5
+ import { capacitor, createCapacitorTokenStorage } from '@h-ai/capacitor'
6
+ import { Alert } from '@h-ai/ui/components/compounds/index'
7
+ import { Button, Spinner } from '@h-ai/ui/components/primitives/index'
8
8
  import { onMount } from 'svelte'
9
- import {
10
- fetchAppInfo,
11
- getLocale as getSharedLocale,
12
- LanguageSwitcher,
13
- messages as sharedM,
14
- ThemeSwitcher,
15
- } from '{{fullstack.sharedPackageName}}'
9
+ import { AdminWorkspace, messages } from '{{fullstack.sharedPackageName}}'
16
10
  import { initCapacitor } from './lib/capacitor.js'
11
+ import { setLocale } from './lib/paraglide/runtime.js'
17
12
 
18
- type TabId = 'workspace' | 'status' | 'settings'
19
-
20
- let info = $state<AppInfo | null>(null)
21
- let loading = $state(true)
22
- let errorMessage = $state('')
23
- let activeTab = $state<TabId>('workspace')
24
-
25
- const navItems = $derived([
26
- { id: 'workspace', label: appM.nav_workspace(), iconClass: 'icon-[tabler--layout-dashboard]' },
27
- { id: 'status', label: appM.nav_status(), iconClass: 'icon-[tabler--activity-heartbeat]' },
28
- { id: 'settings', label: appM.nav_settings(), iconClass: 'icon-[tabler--settings]' },
29
- ])
30
-
13
+ let apiOptions = $state<ManagementApiOptions | null>(null)
14
+ let startupFailed = $state(false)
31
15
  function syncLocale(locale: string) {
32
- setLocale(locale as Parameters<typeof setLocale>[0])
16
+ setLocale(locale as Parameters<typeof setLocale>[0], { reload: false })
33
17
  }
34
-
35
- function handleTabChange(id: string): void {
36
- if (id === 'workspace' || id === 'status' || id === 'settings')
37
- activeTab = id
38
- }
39
-
40
- async function refreshStatus() {
41
- loading = true
42
- errorMessage = ''
43
- try {
44
- info = await fetchAppInfo({ clientName: '{{projectName}}-app' })
18
+ async function initialize() {
19
+ startupFailed = false
20
+ const result = await initCapacitor()
21
+ if (!result.success) {
22
+ startupFailed = true
23
+ return
45
24
  }
46
- catch {
47
- info = null
48
- errorMessage = sharedM.home_error()
49
- }
50
- finally {
51
- loading = false
25
+ apiOptions = {
26
+ clientName: '{{projectName}}-app',
27
+ ...(capacitor.isNative() ? { requireApiBase: true, tokenStorage: createCapacitorTokenStorage(), headers: { 'X-HAI-Token-Transport': 'body' } } : {}),
52
28
  }
53
29
  }
54
-
55
30
  onMount(() => {
56
- document.title = appM.page_title({ name: sharedM.app_name() })
57
- syncLocale(getSharedLocale())
58
- void initCapacitor()
59
- void refreshStatus()
31
+ void initialize()
32
+ return () => void capacitor.close()
60
33
  })
61
34
  </script>
62
35
 
63
- <div class="hai-mobile-viewport">
64
- <div class="hai-mobile-shell max-w-lg">
65
- <AppBar title={sharedM.app_name()} safeArea fixed={false} class="bg-base-100/95 backdrop-blur border-base-content/8" />
66
-
67
- <main class="hai-mobile-main">
68
- {#if activeTab === 'workspace'}
69
- <section class="space-y-4 p-4 pb-6">
70
- <div class="bg-primary text-primary-content rounded-2xl p-5 shadow-sm">
71
- <p class="text-sm opacity-75">{appM.hero_badge()}</p>
72
- <h1 class="mt-1 text-2xl font-bold">{appM.hero_title({ name: sharedM.app_name() })}</h1>
73
- <p class="mt-2 text-sm opacity-80">{appM.hero_subtitle()}</p>
74
- </div>
75
-
76
- <div class="grid grid-cols-2 gap-3">
77
- <Card padding="sm" shadow="sm">
78
- <div class="flex flex-col gap-2">
79
- <span class="icon-[tabler--components] text-primary text-2xl"></span>
80
- <span class="text-sm font-medium">{appM.preview_metric_shared()}</span>
81
- <span class="text-base-content/60 text-xs">{appM.custom_shared_body()}</span>
82
- </div>
83
- </Card>
84
- <Card padding="sm" shadow="sm">
85
- <div class="flex flex-col gap-2">
86
- <span class="icon-[tabler--message-language] text-primary text-2xl"></span>
87
- <span class="text-sm font-medium">{appM.preview_metric_local()}</span>
88
- <span class="text-base-content/60 text-xs">{appM.custom_local_body()}</span>
89
- </div>
90
- </Card>
91
- </div>
92
-
93
- <Alert variant="info">
94
- {appM.flow_frontend()}
95
- </Alert>
96
- </section>
97
- {:else if activeTab === 'status'}
98
- <section class="space-y-4 p-4 pb-6">
99
- <Card title={appM.status_title()} shadow="sm">
100
- <p class="mb-4 text-sm text-base-content/65">{appM.status_description()}</p>
101
- {#if loading}
102
- <Skeleton variant="title" class="mb-3" />
103
- <Skeleton count={3} />
104
- <p class="sr-only" data-testid="service-status">{sharedM.home_loading()}</p>
105
- {:else if info}
106
- <Alert variant="success" title={appM.status_online({ name: info.name })}>
107
- <p data-testid="service-status">{info.name}</p>
108
- </Alert>
109
- <div class="mt-4 grid grid-cols-2 gap-3 text-sm">
110
- <div>
111
- <p class="text-base-content/50">{appM.status_version()}</p>
112
- <p class="font-medium">{info.version}</p>
113
- </div>
114
- <div>
115
- <p class="text-base-content/50">{appM.status_frontends_count({ count: String(info.frontends.length) })}</p>
116
- <p class="font-medium">{info.frontends.join(' / ')}</p>
117
- </div>
118
- </div>
119
- {:else}
120
- <Alert variant="error" title={sharedM.home_error()}>
121
- <p data-testid="service-status">{errorMessage}</p>
122
- </Alert>
123
- {/if}
124
-
125
- {#snippet footer()}
126
- <Button variant="ghost" size="sm" onclick={refreshStatus}>{sharedM.home_refresh()}</Button>
127
- {/snippet}
128
- </Card>
129
- </section>
130
- {:else}
131
- <section class="space-y-4 p-4 pb-6">
132
- <Card title={sharedM.settings_title()} shadow="sm">
133
- <p class="mb-4 text-sm text-base-content/65">{appM.settings_description()}</p>
134
-
135
- <div class="space-y-3">
136
- <div class="rounded-2xl border border-base-300/70 bg-base-200/60 p-4">
137
- <div class="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
138
- <div class="min-w-0 flex-1">
139
- <h2 class="text-sm font-semibold">{sharedM.settings_theme()}</h2>
140
- <p class="mt-1 text-xs leading-5 text-base-content/65">{appM.settings_theme_description()}</p>
141
- </div>
142
- <div class="shrink-0">
143
- <ThemeSwitcher />
144
- </div>
145
- </div>
146
- </div>
147
-
148
- <div class="rounded-2xl border border-base-300/70 bg-base-200/60 p-4">
149
- <div class="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
150
- <div class="min-w-0 flex-1">
151
- <h2 class="text-sm font-semibold">{sharedM.settings_language()}</h2>
152
- <p class="mt-1 text-xs leading-5 text-base-content/65">{appM.settings_language_description()}</p>
153
- </div>
154
- <div class="shrink-0">
155
- <LanguageSwitcher onLocaleChange={syncLocale} />
156
- </div>
157
- </div>
158
- </div>
159
- </div>
160
- </Card>
161
-
162
- <Card title={appM.flow_title()} shadow="sm">
163
- <div class="space-y-3 text-sm">
164
- <div class="bg-base-200 rounded-xl p-3">{appM.flow_contract()}</div>
165
- <div class="bg-base-200 rounded-xl p-3">{appM.flow_service()}</div>
166
- <div class="bg-base-200 rounded-xl p-3">{appM.flow_shared()}</div>
167
- </div>
168
- </Card>
169
- </section>
170
- {/if}
171
- </main>
172
-
173
- <BottomNav
174
- items={navItems}
175
- active={activeTab}
176
- onchange={handleTabChange}
177
- safeArea
178
- centered
179
- maxWidth="lg"
180
- class="border-base-content/8 shadow-[0_-12px_32px_rgba(15,23,42,0.08)]"
181
- />
36
+ {#if startupFailed}
37
+ <div class="mx-auto flex min-h-dvh max-w-md flex-col justify-center gap-4 p-6">
38
+ <Alert variant="error">{messages.operation_failed()}</Alert>
39
+ <Button onclick={() => void initialize()}>{messages.home_refresh()}</Button>
182
40
  </div>
183
- </div>
184
-
185
- <ToastContainer />
186
- {{/if}}
41
+ {:else if apiOptions}
42
+ <AdminWorkspace platform="app" {apiOptions} onLocaleChange={syncLocale} />
43
+ {:else}
44
+ <div class="flex min-h-dvh items-center justify-center"><Spinner /></div>
45
+ {/if}
46
+ {{/if}}
@@ -5,4 +5,4 @@
5
5
  import '@h-ai/ui/auto-import'
6
6
 
7
7
  declare module '*.css'
8
- {{/if}}
8
+ {{/if}}
@@ -1,18 +1,19 @@
1
1
  {{! @skipIfEmpty }}
2
2
  {{#if fullstack.frontends.app}}
3
+ import type { HaiResult } from '@h-ai/core'
3
4
  import { capacitor } from '@h-ai/capacitor'
4
5
 
5
- export async function initCapacitor(): Promise<void> {
6
+ export async function initCapacitor(): Promise<HaiResult<void>> {
6
7
  const result = await capacitor.init()
7
- if (!result.success) {
8
- return
9
- }
8
+ if (!result.success)
9
+ return result
10
10
 
11
11
  if (capacitor.isNative()) {
12
- await capacitor.statusBar.configure({
12
+ return capacitor.statusBar.configure({
13
13
  style: 'dark',
14
14
  overlay: true,
15
15
  })
16
16
  }
17
+ return result
17
18
  }
18
19
  {{/if}}
@@ -11,4 +11,4 @@ if (!target)
11
11
  const app = mount(App, { target })
12
12
 
13
13
  export default app
14
- {{/if}}
14
+ {{/if}}
@@ -1,32 +1,58 @@
1
1
  {{! @skipIfEmpty }}
2
2
  {{#if fullstack.frontends.app}}
3
+ import process from 'node:process'
4
+ import { fileURLToPath } from 'node:url'
3
5
  import { haiOptimizeExclude, haiPrebundledDeps } from '@h-ai/ui/vite'
4
6
  import { paraglideVitePlugin } from '@inlang/paraglide-js'
5
7
  import { svelte } from '@sveltejs/vite-plugin-svelte'
6
8
  import tailwindcss from '@tailwindcss/vite'
9
+ import { loadEnv } from 'vite'
7
10
  import { defineConfig } from 'vitest/config'
8
11
 
9
- export default defineConfig({
10
- plugins: [
11
- svelte(),
12
- tailwindcss(),
13
- paraglideVitePlugin({
14
- project: './project.inlang',
15
- outdir: './src/lib/paraglide',
16
- strategy: ['cookie', 'baseLocale'],
17
- }),
18
- ],
19
- optimizeDeps: {
20
- exclude: [...haiOptimizeExclude],
21
- include: [...haiPrebundledDeps],
22
- },
23
- envPrefix: ['VITE_', 'PUBLIC_'],
24
- ssr: {
25
- noExternal: [/@h-ai\//, /{{fullstack.sharedPackageName}}/],
26
- },
27
- test: {
28
- environment: 'node',
29
- include: ['tests/**/*.test.ts'],
30
- },
12
+ const envDir = fileURLToPath(new URL('../../', import.meta.url))
13
+
14
+ export default defineConfig(({ mode }) => {
15
+ const env = loadEnv(mode, envDir, 'PUBLIC_')
16
+ const target = (env.PUBLIC_API_BASE || process.env.SERVICE_BASE_URL || 'http://127.0.0.1:3000').replace(/\/api\/v1\/?$/, '')
17
+ const proxy = { '/api': { target, changeOrigin: true } }
18
+ return {
19
+ envDir,
20
+ server: { proxy },
21
+ preview: { proxy },
22
+ build: {
23
+ rolldownOptions: {
24
+ output: {
25
+ codeSplitting: {
26
+ groups: [
27
+ { name: 'vendor-ui', test: /node_modules\/(?:@h-ai\/ui|bits-ui|svelte)\// },
28
+ { name: 'vendor-crypto', test: /node_modules\/(?:@h-ai\/(?:core|crypto)|sm-crypto(?:-v2)?)\// },
29
+ { name: 'vendor-api', test: /node_modules\/(?:@orpc\/|zod\/)/ },
30
+ ],
31
+ },
32
+ },
33
+ },
34
+ },
35
+ plugins: [
36
+ svelte(),
37
+ paraglideVitePlugin({
38
+ project: './project.inlang',
39
+ outdir: './src/lib/paraglide',
40
+ strategy: ['cookie', 'baseLocale'],
41
+ }),
42
+ tailwindcss(),
43
+ ],
44
+ optimizeDeps: {
45
+ exclude: [...haiOptimizeExclude],
46
+ include: [...haiPrebundledDeps],
47
+ },
48
+ envPrefix: ['VITE_', 'PUBLIC_'],
49
+ ssr: {
50
+ noExternal: [/@h-ai\//, /{{fullstack.sharedPackageName}}/],
51
+ },
52
+ test: {
53
+ environment: 'node',
54
+ include: ['tests/**/*.test.ts'],
55
+ },
56
+ }
31
57
  })
32
58
  {{/if}}
@@ -8,7 +8,9 @@
8
8
 
9
9
  - 本端页面文案:`messages/{locale}.json` + `project.inlang/settings.json`
10
10
  - 共享 Shell/主题/语言/API:`packages/{{fullstack.sharedPackageName}}`
11
- - 语言切换由 shared 的 `LanguageSwitcher` 触发,并同步本端 `$lib/paraglide/runtime.js`
11
+ - 个人设置保存语言与风格偏好到 IAM 元数据,并同步 shared 和本端 Paraglide runtime
12
+
13
+ 原生 Tauri 使用内存 TokenStorage,不将凭证写入磁盘;重启后需要重新登录。浏览器预览使用 httpOnly refresh Cookie。两种方式均经共享加密 API 客户端。`src-tauri/tauri.conf.json` 的资源与网络白名单应与部署的 API 地址同步。
12
14
 
13
15
  自定义建议:桌面端菜单、状态、快捷操作文案放在本目录 `messages/`;跨端通用能力放到 shared。
14
16
 
@@ -1,18 +1,15 @@
1
1
  {{! @skipIfEmpty }}
2
2
  {{#if fullstack.frontends.desktop}}
3
- import antfu from '@antfu/eslint-config'
3
+ import antfu, { GLOB_SRC } from '@antfu/eslint-config'
4
+ import { haiQualityConfig } from '../../eslint-rules.js'
4
5
 
5
6
  export default antfu({
7
+ // unused-imports 使用 TS 规则,JS 同样使用 TS parser 以保持 scope 契约一致。
8
+ typescript: { files: [GLOB_SRC] },
6
9
  formatters: true,
7
10
  ignores: ['**/build/**', '**/dist/**', '**/*.d.ts', '**/project.inlang/**', '**/src/lib/paraglide/**'],
8
11
  svelte: true,
9
- }, {
10
- files: ['**/*.ts', '**/*.svelte'],
11
- rules: {
12
- 'no-console': 'error',
13
- 'ts/no-explicit-any': 'error',
14
- },
15
- }, {
12
+ }, haiQualityConfig, {
16
13
  files: ['**/*.svelte'],
17
14
  rules: {
18
15
  'svelte/html-quotes': 'off',
@@ -5,7 +5,12 @@
5
5
  <head>
6
6
  <meta charset="UTF-8" />
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
- <title>{{projectName}} Desktop</title>
8
+ <title>{{html fullstack.appName}}</title>
9
+ <link
10
+ rel="icon"
11
+ type="image/svg+xml"
12
+ href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='8' fill='%234438df'/%3E%3Cpath d='M10 8v16M22 8v16M10 16h12' fill='none' stroke='white' stroke-width='3'/%3E%3C/svg%3E"
13
+ />
9
14
  </head>
10
15
  <body>
11
16
  <div id="app"></div>
@@ -2,33 +2,6 @@
2
2
  {{#if fullstack.frontends.desktop}}
3
3
  {
4
4
  "$schema": "https://inlang.com/schema/inlang-message-format",
5
- "page_title": "{name} · Desktop",
6
- "platform_name": "Desktop",
7
- "hero_badge": "Desktop workspace",
8
- "hero_title": "{name} Desktop Command Center",
9
- "hero_subtitle": "A wide-screen desktop starter that can later integrate Tauri while reusing shared shell, theme, locale and API client capabilities.",
10
- "hero_primary_action": "View service status",
11
- "hero_secondary_action": "Customize the starter",
12
- "preview_title": "Desktop productivity UI",
13
- "preview_body": "Ready for command centers, tool workspaces and native-enhanced apps",
14
- "preview_metric_shared": "Shared UI/API capabilities",
15
- "preview_metric_local": "Desktop-owned messages",
16
- "preview_metric_theme": "Configurable themes",
17
- "status_title": "Service connectivity",
18
- "status_description": "The desktop page calls the backend service to verify API contract, service and shared client wiring.",
19
- "status_online": "{name} is connected",
20
- "status_version": "Service version",
21
- "status_started": "Started at: {time}",
22
- "status_frontends": "Service frontends: {list}",
23
- "status_frontends_count": "{count} frontend targets",
24
- "custom_shared_title": "Shared owns common capabilities",
25
- "custom_shared_body": "Common shell, theme, locale switching and API client live in packages/{{projectName}}-shared and are reused by Desktop.",
26
- "custom_local_title": "Desktop owns desktop copy",
27
- "custom_local_body": "Desktop-specific menus, states and feature descriptions live in apps/{{projectName}}-desktop/messages.",
28
- "flow_title": "Collaboration boundary",
29
- "flow_contract": "Contract locks API contracts",
30
- "flow_service": "Service provides runtime capabilities",
31
- "flow_shared": "Shared reuses cross-platform UI/API",
32
- "flow_frontend": "Desktop composes the product experience"
5
+ "page_title": "{name}"
33
6
  }
34
7
  {{/if}}
@@ -2,33 +2,6 @@
2
2
  {{#if fullstack.frontends.desktop}}
3
3
  {
4
4
  "$schema": "https://inlang.com/schema/inlang-message-format",
5
- "page_title": "{name} · Desktop",
6
- "platform_name": "Desktop",
7
- "hero_badge": "桌面端工作台",
8
- "hero_title": "{name} Desktop 控制中心",
9
- "hero_subtitle": "面向桌面端的大屏工作台样板,可后续接入 Tauri,同时复用 shared 的 Shell、主题、语言与 API 客户端。",
10
- "hero_primary_action": "查看服务状态",
11
- "hero_secondary_action": "了解如何自定义",
12
- "preview_title": "桌面端生产力界面",
13
- "preview_body": "适合控制中心、工具台与本地增强应用",
14
- "preview_metric_shared": "共享 UI/API 能力",
15
- "preview_metric_local": "Desktop 自有 messages",
16
- "preview_metric_theme": "主题可配置",
17
- "status_title": "服务联通状态",
18
- "status_description": "桌面端页面会调用后端服务,确认 API contract、service 与 shared client 链路正常。",
19
- "status_online": "{name} 已连接",
20
- "status_version": "服务版本",
21
- "status_started": "启动时间:{time}",
22
- "status_frontends": "服务声明的前端:{list}",
23
- "status_frontends_count": "{count} 个前端目标",
24
- "custom_shared_title": "共享层放通用能力",
25
- "custom_shared_body": "通用 Shell、主题、语言切换和 API client 放在 packages/{{projectName}}-shared,桌面端直接复用。",
26
- "custom_local_title": "Desktop 层放桌面文案",
27
- "custom_local_body": "桌面端特有菜单、状态与功能说明写在 apps/{{projectName}}-desktop/messages。",
28
- "flow_title": "协同边界",
29
- "flow_contract": "Contract 固化接口契约",
30
- "flow_service": "Service 提供运行时能力",
31
- "flow_shared": "Shared 复用跨端基础 UI/API",
32
- "flow_frontend": "Desktop 组合桌面产品体验"
5
+ "page_title": "{name}"
33
6
  }
34
7
  {{/if}}
@@ -1,7 +1,7 @@
1
1
  {{! @skipIfEmpty }}
2
2
  {{#if fullstack.frontends.desktop}}
3
3
  {
4
- "engines": { "node": ">=22.12.0" },
4
+ "engines": { "node": "^22.22.2 || ^24.15.0 || >=26.0.0" },
5
5
  "name": "{{projectName}}-desktop",
6
6
  "type": "module",
7
7
  "version": "0.1.0",
@@ -15,9 +15,9 @@
15
15
  "deploy": "pnpm package",
16
16
  "preview": "vite preview --host 127.0.0.1 --port {{fullstack.ports.desktop}} --strictPort",
17
17
  "typecheck": "pnpm paraglide:compile && svelte-check --tsconfig ./tsconfig.json",
18
- "lint": "eslint src tests vite.config.ts svelte.config.js",
19
- "lint:fix": "eslint src tests vite.config.ts svelte.config.js --fix",
20
- "test": "pnpm paraglide:compile && vitest run",
18
+ "lint": "eslint src vite.config.ts svelte.config.js",
19
+ "lint:fix": "eslint src vite.config.ts svelte.config.js --fix",
20
+ "test": "pnpm paraglide:compile && vitest run --passWithNoTests",
21
21
  "test:watch": "pnpm paraglide:compile && vitest",
22
22
  "clean": "rimraf dist .turbo src-tauri/target src/lib/paraglide",
23
23
  "tauri": "tauri",
@@ -25,6 +25,7 @@
25
25
  "tauri:build": "tauri build"
26
26
  },
27
27
  "dependencies": {
28
+ "@h-ai/api-client": "{{haiPackageSpecifier}}",
28
29
  "@h-ai/ui": "{{haiPackageSpecifier}}",
29
30
  "{{fullstack.sharedPackageName}}": "workspace:*"
30
31
  },