@h-ai/cli 0.1.0-alpha.66 → 0.1.0-alpha.68

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 (198) hide show
  1. package/README.en.md +86 -241
  2. package/README.ja.md +86 -241
  3. package/README.md +86 -241
  4. package/dist/{src-RDQ2EIBT.js → chunk-FI56GONY.js} +32 -2669
  5. package/dist/chunk-FI56GONY.js.map +1 -0
  6. package/dist/chunk-MBPB37FR.js +1348 -0
  7. package/dist/chunk-MBPB37FR.js.map +1 -0
  8. package/dist/{chunk-QYX6V7H2.js → chunk-ZFNBUF77.js} +347 -276
  9. package/dist/chunk-ZFNBUF77.js.map +1 -0
  10. package/dist/cli-config-templates-W2LLPMB6.js +5 -0
  11. package/dist/{cli-config-templates-3XSFIXBP.js.map → cli-config-templates-W2LLPMB6.js.map} +1 -1
  12. package/dist/{cli-skill-templates-TSYEQTCY.js → cli-skill-templates-US5CCAJ4.js} +3 -3
  13. package/dist/{cli-skill-templates-TSYEQTCY.js.map → cli-skill-templates-US5CCAJ4.js.map} +1 -1
  14. package/dist/index.js +1304 -532
  15. package/dist/index.js.map +1 -1
  16. package/dist/metafile-esm.json +1 -0
  17. package/dist/src-DSJJXM2F.js +3849 -0
  18. package/dist/src-DSJJXM2F.js.map +1 -0
  19. package/package.json +9 -8
  20. package/templates/README.md +48 -145
  21. package/templates/apps/admin/messages/ja-JP.json +38 -0
  22. package/templates/apps/admin/src/routes/+layout.svelte.hbs +16 -6
  23. package/templates/apps/admin/src/routes/admin/+layout.svelte.hbs +3 -3
  24. package/templates/apps/api/.dockerignore.hbs +14 -7
  25. package/templates/apps/api/.gitignore.hbs +7 -0
  26. package/templates/apps/api/apps/{{projectName}}-contract/README.md.hbs +23 -2
  27. package/templates/apps/api/apps/{{projectName}}-contract/src/index.ts.hbs +2 -0
  28. package/templates/apps/api/apps/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +4 -1
  29. package/templates/apps/api/apps/{{projectName}}-service/README.md.hbs +33 -8
  30. package/templates/apps/api/apps/{{projectName}}-service/config/_core.yml.hbs +0 -10
  31. package/templates/apps/api/apps/{{projectName}}-service/config/_serv.yml.hbs +2 -1
  32. package/templates/apps/api/apps/{{projectName}}-service/package.json.hbs +1 -2
  33. package/templates/apps/api/apps/{{projectName}}-service/src/app.ts.hbs +24 -11
  34. package/templates/apps/api/apps/{{projectName}}-service/src/index.ts.hbs +8 -1
  35. package/templates/apps/api/apps/{{projectName}}-service/src/lib/server/init.ts.hbs +68 -11
  36. package/templates/apps/api/apps/{{projectName}}-service/src/server/procedures/index.ts.hbs +10 -2
  37. package/templates/apps/api/e2e/api-service.spec.ts.hbs +2 -2
  38. package/templates/apps/api/hai.build.json.hbs +1 -1
  39. package/templates/apps/api/images/app.Dockerfile.hbs +35 -0
  40. package/templates/apps/api/package.json.hbs +6 -1
  41. package/templates/apps/api/playwright.config.ts.hbs +15 -7
  42. package/templates/apps/fullstack/.dockerignore.hbs +14 -9
  43. package/templates/apps/fullstack/.gitignore.hbs +7 -0
  44. package/templates/apps/fullstack/apps/{{projectName}}-app/README.md.hbs +24 -6
  45. package/templates/apps/fullstack/apps/{{projectName}}-app/index.html.hbs +1 -0
  46. package/templates/apps/fullstack/apps/{{projectName}}-app/messages/ja-JP.json.hbs +7 -0
  47. package/templates/apps/fullstack/apps/{{projectName}}-app/public/runtime-config.js.hbs +4 -0
  48. package/templates/apps/fullstack/apps/{{projectName}}-app/src/App.svelte.hbs +7 -1
  49. package/templates/apps/fullstack/apps/{{projectName}}-app/vite.config.ts.hbs +2 -2
  50. package/templates/apps/fullstack/apps/{{projectName}}-desktop/README.md.hbs +23 -5
  51. package/templates/apps/fullstack/apps/{{projectName}}-desktop/messages/ja-JP.json.hbs +7 -0
  52. package/templates/apps/fullstack/apps/{{projectName}}-desktop/vite.config.ts.hbs +1 -1
  53. package/templates/apps/fullstack/apps/{{projectName}}-miniapp/README.md.hbs +16 -6
  54. package/templates/apps/fullstack/apps/{{projectName}}-miniapp/messages/ja-JP.json.hbs +12 -0
  55. package/templates/apps/fullstack/apps/{{projectName}}-web/README.md.hbs +24 -6
  56. package/templates/apps/fullstack/apps/{{projectName}}-web/messages/ja-JP.json.hbs +7 -0
  57. package/templates/apps/fullstack/apps/{{projectName}}-web/vite.config.ts.hbs +2 -2
  58. package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +30 -9
  59. package/templates/apps/fullstack/hai.build.json.hbs +2 -2
  60. package/templates/apps/fullstack/images/app.Dockerfile.hbs +36 -0
  61. package/templates/apps/fullstack/images/web.Dockerfile.hbs +34 -0
  62. package/templates/apps/fullstack/package.json.hbs +3 -1
  63. package/templates/apps/fullstack/packages/{{projectName}}-contract/README.md.hbs +23 -2
  64. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-schemas.ts.hbs +1 -1
  65. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/index.ts.hbs +2 -0
  66. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +3 -0
  67. package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +32 -8
  68. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_core.yml.hbs +0 -6
  69. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_reach.yml.hbs +8 -0
  70. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_serv.yml.hbs +2 -1
  71. package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +6 -0
  72. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/app-server.ts.hbs +9 -5
  73. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/admin-service.ts.hbs +3 -2
  74. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/messages.ts.hbs +16 -1
  75. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/admin-procedures.ts.hbs +7 -3
  76. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/index.ts.hbs +3 -0
  77. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/runtime.ts.hbs +58 -7
  78. package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/app-server.test.ts.hbs +13 -3
  79. package/templates/apps/fullstack/packages/{{projectName}}-shared/.gitignore.hbs +7 -0
  80. package/templates/apps/fullstack/packages/{{projectName}}-shared/README.md.hbs +40 -14
  81. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/ja-JP.json.hbs +105 -0
  82. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AdminWorkspace.svelte.hbs +3 -3
  83. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AppShell.svelte.hbs +6 -6
  84. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/audit.svelte.hbs +7 -7
  85. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/settings.svelte.hbs +4 -4
  86. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/users.svelte.hbs +8 -8
  87. package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/api-client.test.ts.hbs +13 -14
  88. package/templates/apps/fullstack/playwright.config.ts.hbs +15 -6
  89. package/templates/apps/h5/messages/ja-JP.json +40 -0
  90. package/templates/apps/h5/src/routes/+layout.svelte.hbs +16 -5
  91. package/templates/apps/mobile-app/messages/ja-JP.json +36 -0
  92. package/templates/apps/mobile-app/src/App.svelte.hbs +15 -5
  93. package/templates/apps/mobile-app/src/lib/api.ts.hbs +173 -14
  94. package/templates/apps/mobile-app/src/lib/pages/home.svelte.hbs +2 -2
  95. package/templates/apps/website/messages/ja-JP.json +32 -0
  96. package/templates/apps/website/src/routes/+layout.svelte.hbs +13 -5
  97. package/templates/apps/website/src/routes/services/+page.svelte.hbs +1 -1
  98. package/templates/base/.dockerignore.hbs +14 -8
  99. package/templates/base/.gitignore.hbs +7 -0
  100. package/templates/base/e2e/app.spec.ts.hbs +23 -8
  101. package/templates/base/hai.build.json.hbs +1 -1
  102. package/templates/base/{Dockerfile.hbs → images/app.Dockerfile.hbs} +19 -17
  103. package/templates/base/package.json.hbs +11 -3
  104. package/templates/base/playwright.config.ts +15 -4
  105. package/templates/base/src/hooks.server.ts.hbs +15 -6
  106. package/templates/base/src/lib/server/init.ts.hbs +139 -30
  107. package/templates/base/vite.config.ts.hbs +5 -3
  108. package/templates/features/iam/routes-shared/api/auth/logout/+server.ts +11 -6
  109. package/templates/features/payment/routes/api/v1/payment/create/+server.ts +18 -25
  110. package/templates/features/payment/routes/api/v1/payment/notify/[provider]/+server.ts +4 -0
  111. package/templates/i18n/project.inlang/settings.json +1 -1
  112. package/templates/shared/.gitattributes +6 -0
  113. package/templates/shared/e2e-env.ts +98 -0
  114. package/templates/shared/run-e2e.mjs +51 -12
  115. package/templates/skills/AGENTS.md +7 -3
  116. package/templates/skills/bridges/admin/AGENTS.md +6 -2
  117. package/templates/skills/bridges/api/AGENTS.md +3 -1
  118. package/templates/skills/bridges/fullstack/AGENTS.md.hbs +5 -1
  119. package/templates/skills/bridges/h5/AGENTS.md +6 -2
  120. package/templates/skills/bridges/mobile-app/AGENTS.md +6 -2
  121. package/templates/skills/bridges/website/AGENTS.md +6 -2
  122. package/templates/skills/hai-ai/SKILL.md +8 -2
  123. package/templates/skills/hai-ai/guide.md +134 -60
  124. package/templates/skills/hai-ai/reference.md +51 -11
  125. package/templates/skills/hai-api-client/SKILL.md +15 -160
  126. package/templates/skills/hai-api-client/reference.md +178 -0
  127. package/templates/skills/hai-api-contract/SKILL.md +16 -273
  128. package/templates/skills/hai-api-contract/reference.md +280 -0
  129. package/templates/skills/hai-app-create/SKILL.md +6 -2
  130. package/templates/skills/hai-app-create/development.md +24 -8
  131. package/templates/skills/hai-app-create/reference.md +7 -5
  132. package/templates/skills/hai-app-review/SKILL.md +7 -3
  133. package/templates/skills/hai-app-review/differential.md +34 -0
  134. package/templates/skills/hai-app-tests/SKILL.md +6 -3
  135. package/templates/skills/hai-app-tests/reference.md +5 -5
  136. package/templates/skills/hai-app-tests/validation.md +38 -0
  137. package/templates/skills/hai-audit/SKILL.md +24 -147
  138. package/templates/skills/hai-audit/reference.md +148 -0
  139. package/templates/skills/hai-build/SKILL.md +14 -8
  140. package/templates/skills/hai-build/reference.md +16 -13
  141. package/templates/skills/hai-cache/SKILL.md +20 -181
  142. package/templates/skills/hai-cache/reference.md +229 -0
  143. package/templates/skills/hai-capacitor/SKILL.md +7 -4
  144. package/templates/skills/hai-capacitor/reference.md +15 -9
  145. package/templates/skills/hai-ci/SKILL.md +2 -0
  146. package/templates/skills/hai-core/SKILL.md +7 -3
  147. package/templates/skills/hai-core/reference.md +25 -5
  148. package/templates/skills/hai-crypto/SKILL.md +22 -250
  149. package/templates/skills/hai-crypto/reference.md +310 -0
  150. package/templates/skills/hai-datapipe/SKILL.md +16 -195
  151. package/templates/skills/hai-datapipe/reference.md +204 -0
  152. package/templates/skills/hai-deploy/SKILL.md +24 -54
  153. package/templates/skills/hai-deploy/middleware.md +51 -43
  154. package/templates/skills/hai-framework-sync/SKILL.md +2 -2
  155. package/templates/skills/hai-framework-sync/sync.md +1 -1
  156. package/templates/skills/hai-iam/SKILL.md +25 -11
  157. package/templates/skills/hai-iam/reference.md +181 -154
  158. package/templates/skills/hai-kit/SKILL.md +35 -174
  159. package/templates/skills/hai-kit/reference.md +190 -0
  160. package/templates/skills/hai-payment/SKILL.md +33 -263
  161. package/templates/skills/hai-payment/reference.md +295 -0
  162. package/templates/skills/hai-pr-review/SKILL.md +21 -88
  163. package/templates/skills/hai-reach/SKILL.md +6 -3
  164. package/templates/skills/hai-reach/reference.md +83 -22
  165. package/templates/skills/hai-reldb/SKILL.md +6 -3
  166. package/templates/skills/hai-reldb/reference.md +68 -25
  167. package/templates/skills/hai-scheduler/SKILL.md +18 -195
  168. package/templates/skills/hai-scheduler/reference.md +216 -0
  169. package/templates/skills/hai-serv/SKILL.md +25 -10
  170. package/templates/skills/hai-serv/reference.md +123 -87
  171. package/templates/skills/hai-spec-implement/SKILL.md +5 -1
  172. package/templates/skills/hai-spec-implement/evaluation.md +18 -0
  173. package/templates/skills/hai-spec-implement/handoff.md +47 -0
  174. package/templates/skills/hai-spec-implement/templates.md +5 -0
  175. package/templates/skills/hai-spec-implement/workflow.md +5 -3
  176. package/templates/skills/hai-spec-review/SKILL.md +4 -0
  177. package/templates/skills/hai-storage/SKILL.md +23 -238
  178. package/templates/skills/hai-storage/reference.md +282 -0
  179. package/templates/skills/hai-ui/SKILL.md +17 -3
  180. package/templates/skills/hai-ui/guide.md +3 -3
  181. package/templates/skills/hai-ui/reference.md +26 -11
  182. package/templates/skills/hai-ui-design/SKILL.md +31 -0
  183. package/templates/skills/hai-ui-design/patterns.md +26 -0
  184. package/templates/skills/hai-ui-review/SKILL.md +30 -0
  185. package/templates/skills/hai-ui-review/checklist.md +22 -0
  186. package/templates/skills/hai-vecdb/SKILL.md +14 -10
  187. package/templates/skills/hai-vecdb/reference.md +33 -3
  188. package/dist/chunk-FWN5B54L.js +0 -468
  189. package/dist/chunk-FWN5B54L.js.map +0 -1
  190. package/dist/chunk-QYX6V7H2.js.map +0 -1
  191. package/dist/cli-config-templates-3XSFIXBP.js +0 -5
  192. package/dist/src-RDQ2EIBT.js.map +0 -1
  193. package/templates/apps/api/Dockerfile.hbs +0 -35
  194. package/templates/apps/fullstack/Dockerfile.hbs +0 -57
  195. /package/templates/apps/fullstack/{docker → images/web}/19-runtime-config.envsh.hbs +0 -0
  196. /package/templates/apps/fullstack/{docker → images/web}/nginx.conf.hbs +0 -0
  197. /package/templates/apps/fullstack/{docker → images/web}/runtime-config.js.template.hbs +0 -0
  198. /package/templates/base/{docker → images/web}/nginx.conf.hbs +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@h-ai/cli",
3
3
  "type": "module",
4
- "version": "0.1.0-alpha.66",
4
+ "version": "0.1.0-alpha.68",
5
5
  "description": "Hai Framework CLI for project scaffolding and code generation.",
6
6
  "license": "Apache-2.0",
7
7
  "keywords": [
@@ -30,7 +30,7 @@
30
30
  "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
31
31
  },
32
32
  "dependencies": {
33
- "@h-ai/core": "0.1.0-alpha.66",
33
+ "@h-ai/core": "0.1.0-alpha.68",
34
34
  "cac": "^7.0.1",
35
35
  "chalk": "^6.0.1",
36
36
  "fast-wrap-ansi": "^0.2.2",
@@ -41,12 +41,13 @@
41
41
  "yaml": "^2.9.1"
42
42
  },
43
43
  "devDependencies": {
44
- "@h-ai/cache": "0.1.0-alpha.66",
45
- "@h-ai/crypto": "0.1.0-alpha.66",
46
- "@h-ai/deploy": "0.1.0-alpha.66",
47
- "@h-ai/reach": "0.1.0-alpha.66",
48
- "@h-ai/reldb": "0.1.0-alpha.66",
49
- "@h-ai/storage": "0.1.0-alpha.66",
44
+ "@h-ai/api-client": "0.1.0-alpha.68",
45
+ "@h-ai/cache": "0.1.0-alpha.68",
46
+ "@h-ai/crypto": "0.1.0-alpha.68",
47
+ "@h-ai/deploy": "0.1.0-alpha.68",
48
+ "@h-ai/reach": "0.1.0-alpha.68",
49
+ "@h-ai/reldb": "0.1.0-alpha.68",
50
+ "@h-ai/storage": "0.1.0-alpha.68",
50
51
  "@types/fs-extra": "^11.0.4",
51
52
  "@types/node": "^26.6.5",
52
53
  "@types/prompts": "^2.4.9",
@@ -1,163 +1,66 @@
1
- # CLI Templates
1
+ # CLI 项目模板
2
2
 
3
- 此目录包含 `hai create` 命令使用的项目模板文件。
3
+ ## 简介
4
4
 
5
- ## 目录结构
5
+ 这里保存 `hai create` 生成应用时使用的源码、配置和 AI 指引。维护模板后,需要生成真实项目验证,不能只检查模板文件本身。
6
6
 
7
- ```
8
- templates/
9
- ├── base/ # 所有应用类型共用的骨架文件
10
- │ ├── package.json.hbs # 动态:按 features 注入依赖
11
- │ ├── vite.config.ts.hbs # 动态:按 hasI18n / hasUi 注入插件
12
- │ ├── tsconfig.json.hbs # 动态:SvelteKit / 纯 Svelte 5 分支
13
- │ ├── svelte.config.js.hbs # 动态:SvelteKit / 纯 Svelte 5 分支
14
- │ ├── .gitignore.hbs # 动态:纯 Svelte 5 应用不输出 .svelte-kit
15
- │ ├── playwright.config.ts
16
- │ └── src/
17
- │ ├── app.html.hbs # 动态:SvelteKit 应用输出 app shell
18
- │ ├── app.d.ts.hbs # 动态:SvelteKit 应用输出 App namespace
19
- │ ├── app.css
20
- │ ├── hooks.server.ts.hbs # 动态:按 features / hasI18n 组装 handle 序列
21
- │ └── lib/server/
22
- │ └── init.ts.hbs # 动态:按 features 注入模块初始化
23
- │
24
- ├── apps/ # 应用类型专属路由与页面
25
- │ ├── admin/ # 管理后台
26
- │ │ ├── messages/ # i18n 消息文件(zh-CN / en-US)
27
- │ │ └── src/routes/ # +page / +layout .svelte.hbs
28
- │ ├── website/ # 企业官网
29
- │ │ ├── messages/
30
- │ │ └── src/routes/
31
- │ ├── h5/ # H5 移动端
32
- │ │ ├── messages/
33
- │ │ └── src/routes/
34
- │ ├── api/ # 纯 API 服务(无 UI / 无 i18n)
35
- │ │ └── src/routes/
36
- │ ├── mobile-app/ # Svelte 5 + Vite + Capacitor 移动应用
37
- │ │ ├── index.html.hbs
38
- │ │ ├── messages/
39
- │ │ └── src/App.svelte.hbs
40
- │ └── fullstack/ # 前后端分离多包工程(contract / serv / web / app / desktop / miniapp 占位)
41
- │ ├── packages/ # 共享 contract 与后端 serv 包
42
- │ ├── apps/ # 多前端目标,按用户选择条件生成
43
- │ └── e2e/ # 服务端 + 页面级 Playwright 流程
44
- │
45
- ├── features/ # 可选 feature 路由(叠加到 src/routes/)
46
- │ ├── iam/
47
- │ │ ├── routes-shared/ # 所有应用类型共用(API 端点)
48
- │ │ ├── routes-admin/ # admin 专属(登录/注册页 .hbs)
49
- │ │ └── routes-h5/ # h5 专属(登录/注册页 .hbs)
50
- │ ├── storage/
51
- │ │ └── routes/ # 上传 API
52
- │ └── ai/
53
- │ └── routes/ # 聊天流 API
54
- │
55
- ├── i18n/ # i18n 脚手架(hasI18n 时复制到项目根)
56
- │ └── project.inlang/
57
- │ └── settings.json # Paraglide 项目配置
58
- │
59
- └── skills/ # AI Skill 与各 appType 桥接指引
60
- └── bridges/ # admin / api / website / h5 / mobile-app / fullstack 专属 AGENTS
61
- ```
7
+ ## 核心功能清单
62
8
 
63
- ## AI Skill 模板(Single Source of Truth)
64
-
65
- `templates/skills/` 是 CLI 生成共享 AI 上下文时的单一来源,同时用于 `hai create` 与 `hai add`。
66
-
67
- - `hai create` 会把 `templates/skills/` 下所有 `hai-*` Skill 目录复制到 `.agents/skills/<skill>/`,再按 appType 排除互斥项(例如 fullstack 不复制 `hai-kit`;admin / website / h5 不复制 `hai-serv`、`hai-api-contract`、`hai-api-client`、`hai-capacitor`;mobile-app 不复制 `hai-core`、`hai-kit`、`hai-serv`、`hai-api-contract`)
68
- - 通用 `copilot-instructions.md` 复制到 `.github/copilot-instructions.md`,只引用项目根 `AGENTS.md`,不另维护 appType 专属规则
69
- - `bridges/<appType>/AGENTS.md` 会复制到项目根目录,确保不同样板工程使用自己的 AI 指引;通用 `CLAUDE.md` 仅包含 `@AGENTS.md`
70
- - `opencode.json` 会复制到项目根目录
71
- - `templates/skills/AGENTS.md` 是缺少 appType 上下文时的通用规则;`CLAUDE.md`、`copilot-instructions.md` 与 `opencode.json` 是各工具的轻量入口,用于创建项目和回填 AI 支持
72
- - Codex 原生读取根 `AGENTS.md` 并发现 `.agents/skills/`,支持 `$hai-app-create` 等显式调用和按任务自动选择;无需 `.codex/skills` 或工具专属配置。依据:[Codex skills](https://learn.chatgpt.com/docs/build-skills)、[AGENTS.md](https://learn.chatgpt.com/docs/agent-configuration/agents-md)
73
- - `opencode.json` 使用 OpenCode 的 `instructions` 配置直接引用 `AGENTS.md`;`.agents/skills/` 由 OpenCode 原生发现,不再写入过期的 `skills.paths`
74
- - `CLAUDE.md` 通过 `@AGENTS.md` 复用共享规范,Claude Code 按其中的任务导航读取 `.agents/skills/` 正文与参考。CLI 不生成 `.claude/` 技能副本;此模式不提供 Claude 原生技能自动发现或 `/skill` 命令。依据:[Claude Code 项目指引](https://code.claude.com/docs/en/memory)、[原生 skills](https://code.claude.com/docs/en/skills)
75
- - `hai add` / `hai init` 只补齐缺失的 AI 支持文件,不覆盖用户已自定义的桥接文件,也不会自动删除遗留的 `.github/skills/` 或 `.claude/`
76
-
77
- ## 文件类型说明
78
-
79
- | 类型 | 处理方式 |
80
- | ------------------------------------------ | -------------------------------------------- |
81
- | 普通文件(`.ts` / `.svelte` / `.json` 等) | 直接复制,内容不变 |
82
- | `.hbs` 文件 | 经 Handlebars 渲染后输出(去掉 `.hbs` 后缀) |
83
-
84
- ## 渲染上下文(TemplateContext)
85
-
86
- 所有 `.hbs` 文件可使用以下变量:
87
-
88
- | 变量 | 类型 | 说明 |
89
- | ---------------------- | --------- | ----------------------------------------- |
90
- | `{{projectName}}` | `string` | 项目名称(如 `my-app`) |
91
- | `{{appType}}` | `string` | 应用类型 |
92
- | `{{hasUi}}` | `boolean` | 是否包含 UI(非 `api` 类型为 `true`) |
93
- | `{{hasI18n}}` | `boolean` | 是否启用 i18n(非 `api` 类型为 `true`) |
94
- | `{{isSvelteOnlyApp}}` | `boolean` | 是否为不依赖 SvelteKit 的纯 Svelte 5 应用 |
95
- | `{{isCapacitorApp}}` | `boolean` | 是否为 Capacitor 移动应用 |
96
- | `{{defaultLocale}}` | `string` | 默认语言,如 `zh-CN` |
97
- | `{{packageManager}}` | `string` | 包管理器:`pnpm` / `npm` / `yarn` |
98
- | `{{fullstack.*}}` | `object` | fullstack 类型专用上下文 |
99
- | `{{features.iam}}` | `boolean` | 是否选中 iam feature |
100
- | `{{features.db}}` | `boolean` | 是否选中 db feature |
101
- | `{{features.cache}}` | `boolean` | 是否选中 cache feature |
102
- | `{{features.crypto}}` | `boolean` | 是否选中 crypto feature |
103
- | `{{features.storage}}` | `boolean` | 是否选中 storage feature |
104
- | `{{features.ai}}` | `boolean` | 是否选中 ai feature |
105
-
106
- `appType` 支持 `admin` / `website` / `h5` / `api` / `mobile-app` / `fullstack`。
107
-
108
- H5 业务页面复用 `@h-ai/ui` 的 `BottomNav` 和移动端壳样式,桌面预览保持居中限宽,认证路由独立显示。
109
-
110
- `fullstack.*` 包含包名、前端选择、依赖版本、`contractExportName` 和原生壳 `nativeAppIdSegment`,用于渲染 contract / serv / 多端 UI / Capacitor / Tauri 模板。
111
-
112
- `moduleConfigs` 保留创建时指定的模块值。Fullstack 的模块 YAML 用 `{{{moduleConfig 'db' true}}}` 等 helper 复用 `cli-config-templates.ts`;可选模块传 `features.ai` 等开关,未选择时整份注释。创建流程保留已渲染的配置,不再用精简内容覆盖;core、serv、Reach 保留应用专用默认值及完整的可选字段。新增 Schema 字段同步此生成器和相应模板。
113
-
114
- 所有根 `.gitignore`(base / api / fullstack)保留 `**/data/`,包括 `.gitkeep` 在内的运行数据不跟踪。Fullstack 服务端 config 始终含 core、serv、db、cache、iam、storage、audit、reach、ai、vecdb、payment、scheduler、deploy 共 13 份 YAML;不为无配置入口的 crypto/datapipe 生成 YAML。未启用块的后续接入步骤见 [CLI 配置说明](../README.md#应用配置与显示)。
115
-
116
- ### 常用条件写法
117
-
118
- ```handlebars
119
- {{!-- 按 feature 条件注入内容 --}}
120
- {{#if features.iam}}
121
- import { iam } from '@h-ai/iam'
122
- {{/if}}
123
-
124
- {{!-- 按 i18n 条件切换内容 --}}
125
- {{#if hasI18n}}
126
- <title>{m.page_title()}</title>
127
- {{else}}
128
- <title>首页</title>
129
- {{/if}}
130
- ```
9
+ - `admin`、`website`、`h5`:SvelteKit 应用。
10
+ - `api`:共享 contract 与 API service 的 workspace。
11
+ - `mobile-app`:Svelte + Vite + Capacitor 应用。
12
+ - `fullstack`:contract、API、共享界面,以及按需选择的 Web/App/Desktop;miniapp 仅预留说明。
13
+ - 后台工作区随窗口扩展;手机壳支持宽屏,表格在内部滚动,文章与认证表单保留阅读宽度。
14
+ - 默认部署工具、独立镜像 Dockerfile、环境示例和可复制的 AI 技能。
15
+
16
+ ## 使用入门
17
+
18
+ ### 文件如何组合
131
19
 
132
- ## 生成流程
20
+ | 目录 | 用途 |
21
+ | -------------- | ------------------------------------------------------------------- |
22
+ | `base/` | 普通应用共用的配置、脚本和入口 |
23
+ | `apps/<类型>/` | 应用专属页面、workspace、原生壳与配置;API/fullstack 维护自己的骨架 |
24
+ | `features/` | 按所选模块叠加的路由和页面 |
25
+ | `i18n/` | Paraglide 工程配置 |
26
+ | `skills/` | 完整的技能目录与各类型 AI 入口 |
133
27
 
134
- 模板引擎执行 6 个步骤:
28
+ 普通文件直接复制,`.hbs` 经 Handlebars 渲染并去掉后缀。`cli-template-engine.ts` 决定适用目录与条件;`cli-create.ts` 完成配置、镜像定义和根 README 等生成工作。修改前先查实际调用路径,API/fullstack 不套用 SvelteKit 文件路由。
135
29
 
136
- 1. **复制 `base/` 静态文件** → 项目根
137
- 2. **复制 `apps/{appType}/` 专属文件** → 项目根(`messages/` 仅 `hasI18n` 时复制)
138
- 3. **叠加 feature 静态路由** → `src/routes/`(纯 Svelte 5 应用跳过 SvelteKit 路由)
139
- 4. **渲染所有 `.hbs` 文件** — `base/` + `apps/{appType}/` 输出到项目根;`features/*/routes*/` 输出到 `src/routes/`
140
- 5. **复制 `i18n/` 脚手架** → 项目根(仅 `hasI18n` 时)
141
- 6. **确保 `static/` 目录存在**
30
+ ### 配置与构建
142
31
 
143
- ## 新增模板
32
+ 模板通过 `projectName`、`appType`、`features`、`hasUi`、`hasI18n`、`versions` 以及 `api`/`fullstack` 上下文渲染,完整字段见 [cli-types.ts](../src/cli-types.ts)。模块 YAML 使用 `moduleConfig` helper,与 [配置生成器](../src/commands/cli-config-templates.ts) 共用字段和默认值。
144
33
 
145
- ### 新增应用页面
34
+ 部署默认启用,`--no-deploy` 可关闭;SDK 是开发依赖。每个镜像使用 `images/` 中独立 Dockerfile,Web 资源放 `images/web/`。`hai.build.json` 直接选择文件;依赖输入由构建器生成到 `images/dependencies/`。所有根 `.gitignore` 均忽略 `**/images/dependencies/`、运行数据和私有环境文件。
146
35
 
147
- 在 `apps/{appType}/src/routes/` 下创建 `.svelte` 或 `.svelte.hbs` 文件。若含用户可见文本,使用 `.hbs` 并加 `{{#if hasI18n}}` 条件,同时在对应的 `apps/{appType}/messages/` 里补充 i18n key。
36
+ Fullstack 服务端保留各模块的配置示例,未使用模块保持注释。安装依赖、校验和初始化、接入业务后才启用对应配置。修改公开 Schema 时同步配置生成器、环境变量说明、调用方与技能。
148
37
 
149
- ### 新增 feature 路由
38
+ ### AI 指引
150
39
 
151
- 在 `features/{featureId}/routes-shared/`(API 路由)或 `features/{featureId}/routes-{appType}/`(UI 页面)下创建文件,然后在 `cli-template-engine.ts` 的 `FEATURE_ROUTE_DIRS` / `FEATURE_APP_ROUTE_DIRS` 中注册该目录。
40
+ `skills/hai-*` 的完整目录复制到生成应用 `.agents/skills/`,按应用架构排除不适用项。`bridges/<类型>/AGENTS.md` 提供根入口;Claude/Copilot/OpenCode 配置只引用共享规则。新增参考文件必须随 skill 一起复制,不能链接回框架私有路径。
152
41
 
153
- ## 配置驱动认证页面
42
+ `hai add` / `hai init` 补齐缺失文件,保留应用已有的自定义内容。框架升级时按目标发布版本比较并合并,不直接覆盖应用规则。
154
43
 
155
- 协议支持配置中的 userAgreementMarkdown/privacyPolicyMarkdown 正文及 URL;同主题优先 Markdown,由安全渲染器在弹窗显示。
44
+ ### 页面与文案
156
45
 
157
- 选用 IAM 的 admin/h5/website 模板提供 AuthPanel 和标准认证路由;mobile-app 与 fullstack Web/App/Desktop 使用 API 客户端共享动作。修改服务端 config/_iam.yml 即可控制登录方式、注册、重置、协议和品牌,无需改表单。配置 Reach 模板和真实发送 Provider 后启用 OTP/重置。分布式部署使用共享数据库与 Redis。
46
+ 用户可见文本加入对应 messages。认证复用 AuthPanel 与服务端公开 IAM 配置;表单复用 Form/FormLayout/FormField。业务规则由应用需求决定,模板默认角色、流程和限额可调整,修改时同步授权、界面、测试和文档。
47
+
48
+ ## 开发测试
49
+
50
+ 维护模板时保留 `shared/.gitattributes`,让生成工程的 `.dockerignore`、Dockerfile 和 POSIX 脚本统一使用 LF,保持跨平台输入一致并确保 Linux 脚本可运行。在仓库根执行:
51
+
52
+ ```sh
53
+ pnpm --filter @h-ai/cli typecheck
54
+ pnpm --filter @h-ai/cli lint
55
+ pnpm --filter @h-ai/cli build
56
+ pnpm --filter @h-ai/cli test
57
+ pnpm check:skills
58
+ pnpm --filter @h-ai/cli test:scaffold-gates
59
+ pnpm --filter @h-ai/cli test:deploy-gates
60
+ ```
158
61
 
159
- LDAP/Reach 是可选 peer;IAM 不强制启用 Reach。默认 LDAP 客户端由应用选择安装 ldapts。自定义通知回调、协议弹窗、表单 snippet 用法随 hai-iam/hai-ui skills 完整复制到生成项目,不能要求应用读取本仓库私有路径。
62
+ 脚手架门禁会生成项目并执行安装、类型检查、lint、构建、测试和浏览器流程。部署门禁另需可用 Podman/Docker,验证镜像构建、隔离服务器上的 SSH/人工部署与部分更新。原生安装包和真实第三方服务需要各自的验收环境。
160
63
 
161
- ## 表单布局
64
+ ## 许可证
162
65
 
163
- 新增/编辑复用 `@h-ai/ui` 的 Form/FormLayout/FormField:可选一列或双列、标签独立成行或与控件同行,多行文本与多选自动跨列,窄容器自动收为一列。CRUD 使用 `form` 配置,字段可用 `colSpan` 覆盖。错误显示在字段附近并随 UI 语言更新。website 联系页采用 FormLayout + FormField;fullstack 共享用户编辑页采用双列同行标签,个人资料与密码页复用 UI 场景组件。没有数据表单的模板保留现有骨架,新增表单按 hai-ui skill 接入。
66
+ Apache-2.0
@@ -0,0 +1,38 @@
1
+ {
2
+ "app_title": "管理コンソール",
3
+ "app_description": "hai Agent Frameworkで構築した管理コンソール",
4
+ "meta_description": "管理コンソール — 企業管理システム",
5
+ "nav_home": "ホーム",
6
+ "nav_dashboard": "ダッシュボード",
7
+ "nav_settings": "設定",
8
+ "nav_admin": "管理画面へ",
9
+ "page_home_title": "管理コンソール",
10
+ "page_home_subtitle": "hai Agent Frameworkで構築",
11
+ "page_home_badge": "Powered by hai",
12
+ "page_dashboard_title": "ダッシュボード",
13
+ "page_dashboard_subtitle": "システム稼働状況の概要",
14
+ "page_dashboard_total_users": "総ユーザー数",
15
+ "page_dashboard_today_active": "本日のアクティブユーザー",
16
+ "page_dashboard_revenue": "月間売上",
17
+ "page_dashboard_orders": "未処理の注文",
18
+ "page_settings_title": "システム設定",
19
+ "page_settings_subtitle": "システム設定を管理",
20
+ "page_settings_basic": "基本設定",
21
+ "page_settings_desc": "ここでシステムの設定を管理します。",
22
+ "auth_login_title": "ログイン",
23
+ "auth_login_submit": "ログイン",
24
+ "auth_login_loading": "ログイン中...",
25
+ "auth_login_failed": "ログインに失敗しました",
26
+ "auth_login_to_register": "アカウントをお持ちでない方は新規登録",
27
+ "auth_register_title": "登録",
28
+ "auth_register_submit": "登録",
29
+ "auth_register_loading": "登録中...",
30
+ "auth_register_failed": "登録に失敗しました",
31
+ "auth_register_to_login": "既にアカウントをお持ちの方はログイン",
32
+ "auth_label_username": "ユーザー名",
33
+ "auth_label_email": "メールアドレス",
34
+ "auth_label_password": "パスワード",
35
+ "auth_label_confirm_password": "パスワードの確認",
36
+ "auth_error_network": "ネットワークエラー",
37
+ "auth_error_password_mismatch": "パスワードが一致しません"
38
+ }
@@ -9,8 +9,8 @@
9
9
  {{/if}}
10
10
  import { page } from '$app/state'
11
11
  {{#if hasI18n}}
12
- import { getLocale } from '$lib/paraglide/runtime.js'
13
- import { setGlobalLocale } from '@h-ai/ui'
12
+ import { getLocale, setLocale } from '$lib/paraglide/runtime.js'
13
+ import { LanguageSwitch, setGlobalLocale } from '@h-ai/ui'
14
14
  {{/if}}
15
15
  import '../app.css'
16
16
 
@@ -21,6 +21,11 @@
21
21
  const { children }: Props = $props()
22
22
  {{#if hasI18n}}
23
23
 
24
+ function handleLanguageChange(language: string) {
25
+ setGlobalLocale(language)
26
+ setLocale(language as Parameters<typeof setLocale>[0])
27
+ }
28
+
24
29
  if (browser) {
25
30
  const paraglideLocale = getLocale()
26
31
  setGlobalLocale(paraglideLocale)
@@ -32,8 +37,13 @@
32
37
  <title>{page.data.appConfig.name}</title>
33
38
  </svelte:head>
34
39
 
35
- <div class='min-h-screen flex flex-col bg-base-200'>
36
- <header class='navbar border-b border-base-300 bg-base-100 px-6'><span class='text-lg font-semibold'>{page.data.appConfig.name}</span></header>
37
- <div class='flex-1'>{@render children()}</div>
38
- <footer class='border-t border-base-300 bg-base-100 p-3 text-center text-xs text-base-content/60'>{page.data.appConfig.name} · {page.data.appConfig.version} · {page.data.appConfig.env}</footer>
40
+ <div class='h-dvh flex flex-col overflow-hidden bg-base-200'>
41
+ <header class='navbar shrink-0 border-b border-base-300 bg-base-100 px-6'>
42
+ <span class='flex-1 text-lg font-semibold'>{page.data.appConfig.name}</span>
43
+ {{#if hasI18n}}
44
+ <LanguageSwitch currentLanguage={getLocale()} onchange={handleLanguageChange} />
45
+ {{/if}}
46
+ </header>
47
+ <div class='flex min-h-0 flex-1 flex-col overflow-auto'>{@render children()}</div>
48
+ <footer class='shrink-0 border-t border-base-300 bg-base-100 p-3 text-center text-xs text-base-content/60'>{page.data.appConfig.name} · {page.data.appConfig.version} · {page.data.appConfig.env}</footer>
39
49
  </div>
@@ -27,10 +27,10 @@
27
27
  ] as const)
28
28
  </script>
29
29
 
30
- <div class='drawer lg:drawer-open'>
30
+ <div class='drawer min-h-0 flex-1 lg:drawer-open'>
31
31
  <input id='admin-drawer' type='checkbox' class='drawer-toggle' />
32
- <div class='drawer-content p-6'>
33
- <label for='admin-drawer' class='btn btn-ghost btn-sm drawer-button lg:hidden mb-4'>
32
+ <div class='drawer-content flex min-h-0 min-w-0 flex-col overflow-auto p-4 sm:p-6'>
33
+ <label for='admin-drawer' class='btn btn-ghost btn-sm drawer-button shrink-0 self-start lg:hidden mb-4'>
34
34
  <span class='icon-[tabler--menu-2] size-5'></span>
35
35
  </label>
36
36
  {@render children()}
@@ -1,16 +1,23 @@
1
- .git
1
+ **/.git
2
+ **/node_modules
3
+ **/.pnpm-store
4
+ **/.cache
5
+ **/.svelte-kit
6
+ **/.turbo
7
+ **/build
8
+ **/dist
9
+ **/coverage
10
+ **/playwright-report
11
+ **/test-results
12
+ **/src-tauri/target
13
+ **/hash-core/target
14
+ tmp
2
15
  **/*.tar
3
16
  .github
4
17
  .agents
5
18
  .claude
6
19
  .codex
7
20
  .opencode
8
- .turbo
9
- build
10
- dist
11
- node_modules
12
- playwright-report
13
- test-results
14
21
  **/data
15
22
  *.log
16
23
  # 仅保留公共基础 .env;分环境配置、私有覆盖及已有交付包不进入构建上下文。
@@ -13,3 +13,10 @@ test-results
13
13
  # 本机私有配置;公共 .env 与 dev/test/prod 环境文件纳入版本控制。
14
14
  .env.local
15
15
  .env.*.local
16
+
17
+ # 构建器生成的安装输入快照
18
+ **/images/dependencies/
19
+
20
+ # 项目本地缓存
21
+ **/.pnpm-store/
22
+ **/.cache/
@@ -1,8 +1,18 @@
1
1
  # {{api.contractPackageName}}
2
2
 
3
+ ## 简介
4
+
3
5
  {{projectName}} API service 的共享 contract 包。
4
6
 
5
- ## 包含内容
7
+ ## 核心功能清单
8
+
9
+ - 共享接口路径、输入输出 Schema 和类型。
10
+ - 客户端与服务端使用同一份 contract。
11
+ - 不包含服务端业务实现,也不加载私有配置。
12
+
13
+ ## 使用入门
14
+
15
+ ### 包含内容
6
16
 
7
17
  - `app-contract.ts`:应用级接口定义,业务 path 与一次性输出 Schema 就近内联
8
18
  - `app-schemas.ts`:跨接口、跨层复用的输入/数据 Zod Schema
@@ -10,9 +20,20 @@
10
20
 
11
21
  API 前缀、健康检查与跨端 Header 等传输配置位于 service 的 `config/_serv.yml`。
12
22
 
13
- ## 常用命令
23
+ ### 常用命令
14
24
 
15
25
  ```bash
16
26
  pnpm --filter {{api.contractPackageName}} build
17
27
  pnpm --filter {{api.contractPackageName}} test
18
28
  ```
29
+
30
+ ## 开发测试
31
+
32
+ ```sh
33
+ pnpm --filter {{api.contractPackageName}} typecheck
34
+ pnpm --filter {{api.contractPackageName}} test
35
+ ```
36
+
37
+ ## 许可证
38
+
39
+ Apache-2.0
@@ -1,3 +1,5 @@
1
1
  export * from './app-contract.js'
2
2
  export * from './app-schemas.js'
3
3
  export * from './{{projectName}}-contract.js'
4
+
5
+ // @hai-generator:contracts:exports
@@ -1,12 +1,15 @@
1
1
  import { apiContract } from '@h-ai/api-contract'
2
2
  import { appContract } from './app-contract.js'
3
3
 
4
+ // @hai-generator:contracts:imports
5
+
4
6
  /** 工程级应用 contract。 */
5
7
  export const {{api.contractExportName}} = apiContract.create({
6
8
  {{#if features.iam}} iam: apiContract.iam,
7
9
  {{/if}}{{#if features.storage}} storage: apiContract.storage,
8
10
  {{/if}}{{#if features.ai}} ai: apiContract.ai,
9
- {{/if}} app: appContract,
11
+ {{/if}} // @hai-generator:contracts:entries
12
+ app: appContract,
10
13
  })
11
14
 
12
15
  export type ApiWorkspaceContract = typeof {{api.contractExportName}}
@@ -1,21 +1,35 @@
1
1
  # {{api.servicePackageName}}
2
2
 
3
+ ## 简介
4
+
3
5
  {{projectName}} API service 包,负责模块初始化、procedure 装配与 HTTP 入口。
4
6
 
5
- ## 常用命令
7
+ ## 核心功能清单
8
+
9
+ - 初始化所选框架模块,装配共享接口并提供 HTTP 服务。
10
+ - 配置、健康检查和应用 procedures 各有明确入口。
11
+ - 从工程根构建镜像,支持自动发布与离线包。
12
+
13
+ ## 使用入门
14
+
15
+ ### 常用命令
6
16
 
7
17
  ```bash
8
18
  pnpm --filter {{api.servicePackageName}} dev
9
19
  pnpm --filter {{api.servicePackageName}} test
10
20
  ```
11
21
 
12
- ## 容器运行
22
+ ### 容器运行
23
+
13
24
 
14
- 从工程根运行 `pnpm build --target docker` 构建并导出镜像,再运行 `pnpm deploy --env test`。deploy 只消费已构建镜像;含 Web 时一并发布 API/Web。网络不通用 `pnpm deploy --env prod --bundle-only`,按输出说明手工搬运 tar。
15
25
  - 配置默认打包自本目录 `config/`,可在运行时只读挂载到 `/app/config`,敏感值通过环境变量注入。
16
- 从工程根运行 `pnpm build --target docker` 构建并导出镜像,再运行 `pnpm deploy --env test`。deploy 只消费已构建镜像;含 Web 时一并发布 API/Web。网络不通用 `pnpm deploy --env prod --bundle-only`,按输出说明手工搬运 tar。
17
26
 
18
- ## 关键目录
27
+
28
+ ### 关键目录
29
+
30
+ {{#if features.crypto}}启用 transport 时,`serverKeyRing` 与客户端 `keyStore` 都必须显式提供。CLI 在本服务被忽略的 `.env.local` 中一次性生成独立开发 ring,变量为 `HAI_CRYPTO_TRANSPORT_SERVERKEYRING`;运行时不生成密钥。部署使用 Secret Manager 向所有节点分发相同受管 ring,配合共享数据库 registry。公钥/版本参与协商,私钥不进入普通 YAML、PUBLIC_/VITE_、日志或公开响应。轮换先分发新旧版本再切 activeKeyId,过渡期后撤销旧 ID;无需会话粘性。
31
+ {{#unless features.db}}本模板未选择 db,registry 仅在 development/test 显式使用内存;production/staging 会拒绝启动 transport。选择 db 并配置共享数据库后再部署,或显式关闭 transport。
32
+ {{/unless}}{{/if}}
19
33
 
20
34
  - `config/`:service 配置
21
35
  - `src/app.ts`:HTTP App 装配
@@ -23,13 +37,24 @@ pnpm --filter {{api.servicePackageName}} test
23
37
  - `src/server/procedures/`:应用级 procedures
24
38
 
25
39
  {{#if features.iam}}
26
- ## IAM 认证配置
40
+ ### IAM 认证配置
27
41
 
28
- 服务端 `config/_iam.yml` 统一控制登录、注册、重置、协议与 `ui` 品牌。邮件/短信可用 `_reach.yml` 中的 Provider/标准模板或自定义发送回调。客户端可通过安全公开配置和框架认证动作接入 `AuthPanel`。所有节点共享同一 DB 与 Redis;Memory 仅用于单进程。
42
+ 服务端 `config/_iam.yml` 统一控制登录、注册、重置、协议与 `ui` 品牌。邮件/短信可用 `_reach.yml` 中的 Provider/标准模板或自定义发送回调。客户端可通过安全公开配置和框架认证动作接入 `AuthPanel`。单实例可使用 Memory;多实例需共享数据库与 Redis,并按工程根 README 配置写入路由和传输会话。
29
43
 
30
- LDAP/Reach 均可选:基础认证无需安装。默认 LDAP 客户端需在 IAM 服务端 workspace 安装 ldapts,再配置 login.ldap 与连接信息。自定义 onOtpSendEmail/onOtpSendSms/onPasswordResetRequest 回调可独立于 Reach 使用,投递失败须拒绝 Promise。协议在 Modal 显示;LoginForm/RegisterForm 提供 header/extraFields/footer,AuthPanel 透传 loginHeader/loginFields/loginFooter 和 registerHeader/registerFields/registerFooter。配置及例子见生成项目的 hai-iam/hai-ui skills。
44
+ LDAP/Reach 均可选:基础认证无需安装。默认 LDAP 客户端需在 IAM 服务端 workspace 安装 ldapts,再配置 login.ldap 与连接信息。自定义 onOtpSendEmail/onOtpSendSms/onPasswordResetRequest 回调可独立于 Reach 使用,投递失败须拒绝 Promise;回调第三参数 context 提供 expiresAt/idempotencyKey,发送服务按稳定键持久化去重,异常/超时为结果未知且不自动重发。协议在 Modal 显示;LoginForm/RegisterForm 提供 header/extraFields/footer,AuthPanel 透传 loginHeader/loginFields/loginFooter 和 registerHeader/registerFields/registerFooter。配置及例子见生成项目的 hai-iam/hai-ui skills。
31
45
 
32
46
  协议支持配置中的 userAgreementMarkdown/privacyPolicyMarkdown 正文及 URL;同主题优先 Markdown,由安全渲染器在弹窗显示。
33
47
 
34
48
  完整契约见生成应用的 `.agents/skills/hai-iam/reference.md`。
35
49
  {{/if}}
50
+
51
+ ## 开发测试
52
+
53
+ ```sh
54
+ pnpm --filter {{api.servicePackageName}} typecheck
55
+ pnpm --filter {{api.servicePackageName}} test
56
+ ```
57
+
58
+ ## 许可证
59
+
60
+ Apache-2.0
@@ -5,7 +5,6 @@
5
5
  name: {{projectName}} API Service
6
6
  version: 0.1.0
7
7
  env: ${HAI_CORE_ENV:development}
8
- debug: ${HAI_CORE_DEBUG:false}
9
8
 
10
9
  logging:
11
10
  level: info
@@ -16,12 +15,3 @@ logging:
16
15
  - secret
17
16
 
18
17
  defaultLocale: {{defaultLocale}}
19
- supportedLocales:
20
- {{#if_eq defaultLocale 'en-US'}} - en-US
21
- - zh-CN
22
- {{else}} - zh-CN
23
- - en-US
24
- {{/if_eq}}
25
-
26
- features:
27
- apiAccess: true
@@ -27,11 +27,13 @@ cors:
27
27
  - Content-Type
28
28
  {{#if features.crypto}} - X-Client-Id
29
29
  - X-Encrypted
30
+ - X-Hai-Transport
30
31
  {{/if}} - X-Hai-Locale
31
32
  - X-Request-Id
32
33
  - X-Requested-With
33
34
  exposedHeaders:
34
35
  {{#if features.crypto}} - X-Encrypted
36
+ - X-Hai-Transport
35
37
  {{/if}} - X-Request-Id
36
38
 
37
39
  {{#if features.crypto}}transport:
@@ -42,6 +44,5 @@ cors:
42
44
  - /openapi.json
43
45
  - /docs
44
46
  - /_hai/scalar.js
45
- maxClients: 10000
46
47
  {{else}}transport: false
47
48
  {{/if}}
@@ -43,8 +43,7 @@
43
43
  "@h-ai/audit": "{{haiPackageSpecifier}}"{{/if}}{{#if features.cache}},
44
44
  "@h-ai/cache": "{{haiPackageSpecifier}}"{{/if}}{{#if features.crypto}},
45
45
  "@h-ai/crypto": "{{haiPackageSpecifier}}"{{/if}}{{#if features.datapipe}},
46
- "@h-ai/datapipe": "{{haiPackageSpecifier}}"{{/if}}{{#if features.deploy}},
47
- "@h-ai/deploy": "{{haiPackageSpecifier}}"{{/if}}{{#if features.iam}},
46
+ "@h-ai/datapipe": "{{haiPackageSpecifier}}"{{/if}}{{#if features.iam}},
48
47
  "@h-ai/iam": "{{haiPackageSpecifier}}"{{/if}}{{#if features.payment}},
49
48
  "@h-ai/payment": "{{haiPackageSpecifier}}"{{/if}}{{#if features.reach}},
50
49
  "@h-ai/reach": "{{haiPackageSpecifier}}"{{/if}}{{#if features.db}},
@@ -1,9 +1,12 @@
1
1
  import type { CoreConfig } from '@h-ai/core'
2
- import type { ServConfig } from '@h-ai/serv'
2
+ import type { ServConfig{{#if features.crypto}}, ServTransportConfig{{/if}} } from '@h-ai/serv'
3
+ {{#if features.crypto}}import process from 'node:process'
4
+ {{/if}}
3
5
  import { core } from '@h-ai/core'
4
- {{#if features.crypto}}import { crypto } from '@h-ai/crypto'
6
+ {{#if features.crypto}}import { {{#if features.db}}createReldbTransportKeyStore{{else}}createInMemoryKeyStore{{/if}}, crypto, parseTransportServerKeyRing } from '@h-ai/crypto'
5
7
  {{/if}}{{#if features.iam}}import { iam } from '@h-ai/iam'
6
- {{/if}}import { serv } from '@h-ai/serv'
8
+ {{/if}}{{#if features.crypto}}{{#if features.db}}import { reldb } from '@h-ai/reldb'
9
+ {{/if}}{{/if}}import { serv } from '@h-ai/serv'
7
10
  import { {{api.contractExportName}} } from '{{api.contractPackageName}}'
8
11
  import { {{api.serviceProceduresFactoryName}} } from './server/procedures/index.js'
9
12
 
@@ -24,14 +27,24 @@ export function {{api.serviceAppFactoryName}}(_options: CreateApiServiceAppOptio
24
27
  nativeOrigins: servConfig.cors.nativeOrigins,
25
28
  })
26
29
  {{#if features.crypto}} const transportMode = _options.transport ?? 'config'
27
- const transport = transportMode === 'disabled' || servConfig.transport === false
28
- ? undefined
29
- : {
30
- crypto,
31
- keyExchangePath: servConfig.transport.keyExchangePath,
32
- excludePaths: [...servConfig.transport.excludePaths],
33
- maxClients: servConfig.transport.maxClients,
34
- }
30
+ let transport: ServTransportConfig | undefined
31
+ if (transportMode !== 'disabled' && servConfig.transport !== false) {
32
+ {{#unless features.db}} if (coreConfig.env !== 'development' && coreConfig.env !== 'test')
33
+ throw new Error('Production transport requires a shared registry; enable the db feature and configure a shared database')
34
+ {{/unless}}
35
+ const ring = parseTransportServerKeyRing(process.env.HAI_CRYPTO_TRANSPORT_SERVERKEYRING)
36
+ if (!ring.success)
37
+ throw new Error(ring.error.message)
38
+ transport = {
39
+ crypto,
40
+ serverKeyRing: ring.data,
41
+ {{#if features.db}} keyStore: createReldbTransportKeyStore({ reldb, ttlSeconds: 3600 }),
42
+ {{else}} keyStore: createInMemoryKeyStore(), // 无 db 的模板仅在 development/test 使用内存 registry。
43
+ {{/if}}
44
+ keyExchangePath: servConfig.transport.keyExchangePath,
45
+ excludePaths: [...servConfig.transport.excludePaths],
46
+ }
47
+ }
35
48
  {{else}} const transport = undefined
36
49
  {{/if}}
37
50
  {{#if features.iam}}