@h-ai/cli 0.1.0-alpha.65 → 0.1.0-alpha.67

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 (141) hide show
  1. package/README.en.md +66 -251
  2. package/README.ja.md +67 -252
  3. package/README.md +66 -251
  4. package/dist/{chunk-47V5OT22.js → chunk-7DSURTJ4.js} +32 -115
  5. package/dist/chunk-7DSURTJ4.js.map +1 -0
  6. package/dist/{chunk-IPG3QNYK.js → chunk-AOQ4N657.js} +212 -8
  7. package/dist/chunk-AOQ4N657.js.map +1 -0
  8. package/dist/cli-config-templates-6AHNUGBN.js +5 -0
  9. package/dist/{cli-config-templates-SJ2MBIR7.js.map → cli-config-templates-6AHNUGBN.js.map} +1 -1
  10. package/dist/{cli-skill-templates-A5VIR5J6.js → cli-skill-templates-FC3QRKDO.js} +3 -3
  11. package/dist/{cli-skill-templates-A5VIR5J6.js.map → cli-skill-templates-FC3QRKDO.js.map} +1 -1
  12. package/dist/index.js +644 -391
  13. package/dist/index.js.map +1 -1
  14. package/dist/{src-6PPBKQ6Q.js → src-2V6VP4I5.js} +972 -520
  15. package/dist/src-2V6VP4I5.js.map +1 -0
  16. package/package.json +8 -8
  17. package/templates/README.md +48 -145
  18. package/templates/apps/admin/src/routes/admin/+layout.svelte.hbs +1 -1
  19. package/templates/apps/api/.dockerignore.hbs +18 -12
  20. package/templates/apps/api/.gitignore.hbs +9 -1
  21. package/templates/apps/api/apps/{{projectName}}-contract/README.md.hbs +23 -2
  22. package/templates/apps/api/apps/{{projectName}}-service/README.md.hbs +28 -7
  23. package/templates/apps/api/apps/{{projectName}}-service/package.json.hbs +1 -3
  24. package/templates/apps/api/hai.build.json.hbs +1 -0
  25. package/templates/apps/api/images/app.Dockerfile.hbs +35 -0
  26. package/templates/apps/api/package.json.hbs +10 -8
  27. package/templates/apps/fullstack/.dockerignore.hbs +18 -14
  28. package/templates/apps/fullstack/.gitignore.hbs +9 -1
  29. package/templates/apps/fullstack/apps/{{projectName}}-app/README.md.hbs +23 -8
  30. package/templates/apps/fullstack/apps/{{projectName}}-app/index.html.hbs +1 -0
  31. package/templates/apps/fullstack/apps/{{projectName}}-app/package.json.hbs +0 -2
  32. package/templates/apps/fullstack/apps/{{projectName}}-app/public/runtime-config.js.hbs +4 -0
  33. package/templates/apps/fullstack/apps/{{projectName}}-app/vite.config.ts.hbs +3 -3
  34. package/templates/apps/fullstack/apps/{{projectName}}-desktop/README.md.hbs +25 -10
  35. package/templates/apps/fullstack/apps/{{projectName}}-desktop/package.json.hbs +2 -3
  36. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/src/lib.rs.hbs +73 -2
  37. package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/tauri.conf.json.hbs +2 -2
  38. package/templates/apps/fullstack/apps/{{projectName}}-desktop/vite.config.ts.hbs +2 -2
  39. package/templates/apps/fullstack/apps/{{projectName}}-miniapp/README.md.hbs +16 -6
  40. package/templates/apps/fullstack/apps/{{projectName}}-web/README.md.hbs +24 -10
  41. package/templates/apps/fullstack/apps/{{projectName}}-web/package.json.hbs +0 -2
  42. package/templates/apps/fullstack/apps/{{projectName}}-web/vite.config.ts.hbs +3 -3
  43. package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +12 -1
  44. package/templates/apps/fullstack/hai.build.json.hbs +7 -0
  45. package/templates/apps/fullstack/images/app.Dockerfile.hbs +36 -0
  46. package/templates/apps/fullstack/images/web.Dockerfile.hbs +34 -0
  47. package/templates/apps/fullstack/package.json.hbs +7 -12
  48. package/templates/apps/fullstack/packages/{{projectName}}-contract/README.md.hbs +23 -2
  49. package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +28 -7
  50. package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +0 -1
  51. package/templates/apps/fullstack/packages/{{projectName}}-shared/.gitignore.hbs +7 -0
  52. package/templates/apps/fullstack/packages/{{projectName}}-shared/README.md.hbs +33 -12
  53. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AppShell.svelte.hbs +2 -2
  54. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/settings.svelte.hbs +3 -3
  55. package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/api-client.test.ts.hbs +2 -2
  56. package/templates/apps/h5/src/routes/+layout.svelte.hbs +2 -2
  57. package/templates/apps/mobile-app/index.html.hbs +1 -0
  58. package/templates/apps/mobile-app/public/runtime-config.js +1 -0
  59. package/templates/apps/mobile-app/src/App.svelte.hbs +2 -2
  60. package/templates/apps/mobile-app/src/lib/api.ts.hbs +2 -1
  61. package/templates/apps/mobile-app/src/lib/app-config.ts.hbs +3 -2
  62. package/templates/apps/mobile-app/src/lib/pages/home.svelte.hbs +2 -2
  63. package/templates/apps/website/src/routes/+layout.svelte.hbs +3 -3
  64. package/templates/apps/website/src/routes/services/+page.svelte.hbs +1 -1
  65. package/templates/base/.dockerignore.hbs +18 -13
  66. package/templates/base/.gitignore.hbs +9 -1
  67. package/templates/base/e2e/app.spec.ts.hbs +10 -0
  68. package/templates/base/hai.build.json.hbs +1 -0
  69. package/templates/base/images/app.Dockerfile.hbs +64 -0
  70. package/templates/base/{docker → images/web}/nginx.conf.hbs +6 -0
  71. package/templates/base/package.json.hbs +20 -19
  72. package/templates/base/svelte.config.js.hbs +2 -0
  73. package/templates/base/vite.config.ts.hbs +9 -3
  74. package/templates/shared/.gitattributes +11 -0
  75. package/templates/shared/container-runtime-config.sh +30 -0
  76. package/templates/shared/run-e2e.mjs +65 -0
  77. package/templates/shared/vite-runtime-config.ts +54 -0
  78. package/templates/skills/AGENTS.md +3 -3
  79. package/templates/skills/bridges/admin/AGENTS.md +1 -1
  80. package/templates/skills/bridges/api/AGENTS.md +1 -1
  81. package/templates/skills/bridges/fullstack/AGENTS.md.hbs +1 -1
  82. package/templates/skills/bridges/h5/AGENTS.md +1 -1
  83. package/templates/skills/bridges/mobile-app/AGENTS.md +1 -1
  84. package/templates/skills/bridges/website/AGENTS.md +1 -1
  85. package/templates/skills/hai-api-client/SKILL.md +14 -161
  86. package/templates/skills/hai-api-client/reference.md +166 -0
  87. package/templates/skills/hai-api-contract/SKILL.md +15 -273
  88. package/templates/skills/hai-api-contract/reference.md +278 -0
  89. package/templates/skills/hai-app-create/SKILL.md +2 -2
  90. package/templates/skills/hai-app-create/development.md +6 -4
  91. package/templates/skills/hai-app-create/reference.md +5 -4
  92. package/templates/skills/hai-app-review/SKILL.md +1 -1
  93. package/templates/skills/hai-app-tests/SKILL.md +4 -3
  94. package/templates/skills/hai-app-tests/reference.md +2 -2
  95. package/templates/skills/hai-app-tests/validation.md +31 -0
  96. package/templates/skills/hai-audit/SKILL.md +17 -142
  97. package/templates/skills/hai-audit/reference.md +145 -0
  98. package/templates/skills/hai-build/SKILL.md +24 -3
  99. package/templates/skills/hai-build/reference.md +10 -9
  100. package/templates/skills/hai-cache/SKILL.md +15 -182
  101. package/templates/skills/hai-cache/reference.md +187 -0
  102. package/templates/skills/hai-capacitor/SKILL.md +4 -3
  103. package/templates/skills/hai-capacitor/reference.md +6 -4
  104. package/templates/skills/hai-ci/SKILL.md +2 -0
  105. package/templates/skills/hai-core/SKILL.md +3 -3
  106. package/templates/skills/hai-crypto/SKILL.md +16 -252
  107. package/templates/skills/hai-crypto/reference.md +256 -0
  108. package/templates/skills/hai-datapipe/SKILL.md +15 -196
  109. package/templates/skills/hai-datapipe/reference.md +202 -0
  110. package/templates/skills/hai-deploy/SKILL.md +28 -271
  111. package/templates/skills/hai-deploy/middleware.md +6 -18
  112. package/templates/skills/hai-framework-sync/SKILL.md +2 -2
  113. package/templates/skills/hai-framework-sync/sync.md +1 -1
  114. package/templates/skills/hai-iam/SKILL.md +1 -3
  115. package/templates/skills/hai-kit/SKILL.md +12 -167
  116. package/templates/skills/hai-kit/reference.md +172 -0
  117. package/templates/skills/hai-payment/SKILL.md +19 -251
  118. package/templates/skills/hai-payment/reference.md +256 -0
  119. package/templates/skills/hai-pr-review/SKILL.md +4 -4
  120. package/templates/skills/hai-reach/SKILL.md +2 -2
  121. package/templates/skills/hai-reldb/SKILL.md +1 -1
  122. package/templates/skills/hai-scheduler/SKILL.md +15 -195
  123. package/templates/skills/hai-scheduler/reference.md +202 -0
  124. package/templates/skills/hai-serv/SKILL.md +2 -2
  125. package/templates/skills/hai-spec-implement/SKILL.md +1 -1
  126. package/templates/skills/hai-spec-implement/workflow.md +3 -3
  127. package/templates/skills/hai-storage/SKILL.md +17 -238
  128. package/templates/skills/hai-storage/reference.md +243 -0
  129. package/templates/skills/hai-ui/SKILL.md +1 -1
  130. package/templates/skills/hai-ui/reference.md +11 -5
  131. package/templates/skills/hai-vecdb/SKILL.md +2 -2
  132. package/dist/chunk-47V5OT22.js.map +0 -1
  133. package/dist/chunk-IPG3QNYK.js.map +0 -1
  134. package/dist/cli-config-templates-SJ2MBIR7.js +0 -5
  135. package/dist/src-6PPBKQ6Q.js.map +0 -1
  136. package/templates/apps/api/Dockerfile.hbs +0 -48
  137. package/templates/apps/fullstack/Dockerfile.hbs +0 -69
  138. package/templates/base/Dockerfile.hbs +0 -79
  139. /package/templates/apps/fullstack/{docker → images/web}/19-runtime-config.envsh.hbs +0 -0
  140. /package/templates/apps/fullstack/{docker → images/web}/nginx.conf.hbs +0 -0
  141. /package/templates/apps/fullstack/{docker → images/web}/runtime-config.js.template.hbs +0 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: hai-app-tests
3
- description: "编写或修复 hai 应用的 Vitest/Playwright 测试,验证业务边界和完整用户流程。"
3
+ description: "为 hai 应用编写或修复 Vitest/Playwright 测试,组织分轮验证、汇总失败和集中修复,验证需求与完整用户流程。"
4
4
  ---
5
5
 
6
6
  # hai-app-tests
@@ -9,7 +9,7 @@ description: "编写或修复 hai 应用的 Vitest/Playwright 测试,验证业
9
9
 
10
10
  | 项目 | 契约 |
11
11
  | --- | --- |
12
- | 能力 | 编写或修复 hai 应用的 Vitest/Playwright 测试,验证业务边界和完整用户流程 |
12
+ | 能力 | 编写或修复 Vitest/Playwright 测试,组织质量门禁与业务流程的分轮验证 |
13
13
  | 适用场景 | 需求验收、缺陷回归或应用测试改进 |
14
14
  | 输入 | 验收条件、被测公共入口、现有测试和运行环境 |
15
15
  | 输出 | 可复现用例及明确区分静态、mock、浏览器/外部服务的结果 |
@@ -22,11 +22,12 @@ description: "编写或修复 hai 应用的 Vitest/Playwright 测试,验证业
22
22
  - 按 [development.md](../hai-app-create/development.md) 的真实行为与安全边界选测试;新增/改变业务行为、缺陷修复有目标用例,纯文案/格式/文档及无行为变化的可逆低影响修改不补镜像测试。
23
23
  - 不要求每个功能同时新增单元与 E2E;复用已有用例,选择能验证变化的最小适用层,关键跨层用户流程仍需端到端证据。
24
24
  - 新用例已通过时先检查是否已有能力;不能为达成 Red 人为破坏旧测试。
25
+ - 执行多项门禁前读取 [分轮验证与集中修复](validation.md):一轮先脚本化收集所有可执行检查及日志,普通失败不立即改代码;汇总去重后集中修复,再复测失败和受影响项。只有真实前置阻塞才暂停依赖检查;最终必需门禁均须对最终代码有效通过。小范围 TDD Red → Green 保留。
25
26
  - 外部服务未运行必须报告;mock/Testcontainers/浏览器/真实付费 Provider 的结果分开表述。
26
27
 
27
28
  ## 按需参考
28
29
 
29
- 详细配置、API 签名、错误码和范本在 [reference.md](reference.md)。按下列标题定位所需小节,不默认通读;用例中的业务变量需结合当前应用补齐。
30
+ 按任务读取 [reference.md](reference.md) 的对应小节;签名以当前源码或安装版本的公开类型为准,不默认加载全部资料。示例中的业务变量由应用提供。
30
31
 
31
32
  - 适用场景
32
33
  - 行为验证与 TDD 工作流
@@ -52,7 +52,7 @@
52
52
 
53
53
  1. 参照 `hai-app-review` 技能审查代码规范
54
54
  2. 重构后执行受影响测试与必要回归,确认已有行为保持通过
55
- 3. 从当前 scripts 选择门禁,按 `typecheck → lint → build(构建/配置/跨包变更)→ test → 相关 E2E` 执行;PowerShell 使用 `pnpm.cmd`
55
+ 3. 多项门禁按 [分轮验证与集中修复](validation.md) 收集一轮结果,汇总后修复、再验证;不要把目标用例的小范围 TDD 扩大为每修一处就从头运行全量门禁。PowerShell 使用 `pnpm.cmd`
56
56
 
57
57
  ## 测试目录约定
58
58
 
@@ -436,7 +436,7 @@ await expect(page).toHaveURL('/admin/articles')
436
436
 
437
437
  ## 质量门禁
438
438
 
439
- 从当前 package.json 确认实际脚本和 workspace 名称,按变更影响选择;不要为格式/文档改动运行无关 provider 或新增镜像测试。记录执行范围、mock/真实环境、退出结果与未验证原因。
439
+ 从当前 package.json 确认实际脚本和 workspace 名称,按 [分轮验证与集中修复](validation.md) 组织以下适用检查;不要为格式/文档改动运行无关 provider 或新增镜像测试。逐轮记录范围、状态/退出码、日志、mock/真实环境与未验证原因,完整日志按需读取。
440
440
 
441
441
  ```bash
442
442
  # 运行单元测试
@@ -0,0 +1,31 @@
1
+ # 分轮验证与集中修复
2
+
3
+ 适用于开发、审查修复、升级后的质量门禁与整体验收。默认执行“收集一轮 → 归并问题 → 集中修复 → 再验证”,不要遇到一个普通失败就修改代码并从头重跑。新增行为的目标用例仍可做小范围 TDD Red → Green;它不要求提前运行整套门禁。
4
+
5
+ ## 1. 确定本轮检查
6
+
7
+ - 先读当前 `package.json`、任务依赖与环境要求,按影响范围列出命令、工作目录、前置条件和预期证据。优先 workspace filter;用户要求全量验收时保留全量范围。纯文案/文档修改只做适用检查,不新增镜像测试。
8
+ - 一轮默认按 typecheck → lint → build(涉及构建/配置/模板/跨包契约)→ test → 相关 E2E 调度;顺序服从真实依赖。同轮收集不等于同时运行:只有输出目录、端口、数据库、容器与 fixture 均隔离的检查才可并行,共用 `dist`、`.svelte-kit` 或预览产物的构建与测试必须串行。
9
+ - 使用现有任务编排或一个临时调度脚本逐项执行、捕获真实退出码并保存日志。不要用跨检查的 `&&`、全局 fail-fast 或 `|| true` 代替结果收集;脚本内部有前置短路时,确认后续检查是否真正执行,必要时分别调度等价子任务,保留原门禁的最终验收。
10
+
11
+ ## 2. 收集全部可执行结果
12
+
13
+ - 本轮开始后保持被测源码、配置、依赖和运行环境稳定;协作 agent 也不得边测边改,不运行自动修复。普通类型错误、lint 错误、测试断言失败只记录,继续其余具备前置条件的检查。
14
+ - 只有真实前置失败才阻塞依赖它的检查,例如依赖无法安装、执行器无法启动、上游构建未产生必要产物、必需服务不可用。标明阻塞原因,继续独立检查;确实无法继续收集时才提前结束本轮、集中修复阻塞。不得使用旧构建、旧镜像或旧截图让下游假通过。
15
+ - 为每轮使用独立且被 Git 忽略的日志目录,例如 `tmp/validation/round-01/`。逐项记录命令/范围、源码版本及未提交改动、环境、状态(通过/失败/阻塞/未执行)、退出码、耗时和日志路径;未执行与不适用须说明原因,不能写成通过。超时、取消和环境失败单列,不能当作断言失败或忽略。
16
+ - 调度脚本等子进程退出后再记录结果;重定向或管道不能覆盖实际退出码。所有必需项均有有效通过结果,整轮才算通过;收集到任何失败或阻塞时,汇总必须保留非成功状态。
17
+ - 完整输出写日志,AI 先读汇总及每类失败的有限上下文,再按需定位原始日志;不反复载入整份成功日志、密集轮询或启动尚未结束的同一检查。长任务期间定期简述进度。
18
+
19
+ ## 3. 集中分析与修复
20
+
21
+ - 本轮可执行检查结束后,把问题按根因去重,记录位置、证据、影响、修复项及关联门禁。上游故障造成的连锁失败合并处理;区分本次引入、原有问题和环境问题。
22
+ - 在已有授权范围内集中修复本次范围的问题,保留仍有效的断言与回归。不能靠删断言、跳过用例、放宽超时或关闭规则换绿灯。环境故障先保存证据、确认恢复条件,再定向重试;不反复重跑到偶然通过。
23
+ - 新发现的独立问题加入同一清单;修复期间的小范围诊断不触发从头全量重跑,也不能替代下一轮必要验收。
24
+
25
+ ## 4. 下一轮与完成条件
26
+
27
+ - 修复后开启新一轮,先复测失败项、被阻塞项及受改动影响的检查和消费者;按同样方式收集完再修复。有影响范围不明、共享配置/依赖改变或用户要求时,扩大到全量门禁。
28
+ - 只有源码、依赖、配置、工具、环境及所用产物等输入均未改变的已通过项才可复用,并注明来源轮次或缓存;输入变化使相关结果失效。最终所有必需检查必须对最终代码仍有效,缺项不能称为完成。真实部署、Provider、浏览器或原生验收不能只引用静态检查/构建缓存。
29
+ - 保留原有 CI/发布门禁的失败阻断;问题收集时继续运行不代表允许失败提交发布或忽略 required checks。
30
+ - 每轮都在 finally/teardown 停止本轮进程、清理本轮临时工程/容器/镜像/数据;确认退出和资源释放后再运行冲突任务。日志、截图与报告保留到问题分析和交付结束,再按项目约定清理,不覆盖失败证据、不提交验收产物、不删除用户资源。
31
+ - 最终报告各项门禁状态、执行/复用范围、修复结果和未验证原因;mock、容器、真实服务及原生结果分别说明。只陈述实际证据,不以“脚本执行完了”代表验证通过。
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: hai-audit
3
- description: "使用 @h-ai/audit 记录、查询、统计和清理操作审计。"
3
+ description: "接入 @h-ai/audit 记录业务操作,查询分页日志与统计,并按保留期清理。"
4
4
  ---
5
5
 
6
- # @h-ai/audit — 审计日志模块
6
+ # hai-audit
7
7
 
8
8
  ## 能力契约
9
9
 
@@ -11,150 +11,25 @@ description: "使用 @h-ai/audit 记录、查询、统计和清理操作审计
11
11
  | --- | --- |
12
12
  | 能力 | 使用 @h-ai/audit 记录、查询、统计和清理操作审计 |
13
13
  | 适用场景 | 业务操作留痕与审计记录检索 |
14
- | 输入 | AuditConfigInput、已初始化 reldb、审计事件与查询条件 |
14
+ | 输入 | AuditInitConfigInput、已初始化 reldb、审计事件与查询条件 |
15
15
  | 输出 | 记录/查询/统计的 HaiResult |
16
16
  | 限制 | 仅服务端;审计内容需脱敏,保留期和清理范围由应用策略决定。 |
17
17
 
18
- 统一审计日志模块,基于 `@h-ai/reldb` 实现持久化,提供审计日志的记录、分页查询、清理与统计。
18
+ ## 使用路径
19
19
 
20
- ## 运行环境
20
+ 1. 确认已初始化 reldb,校验 `AuditInitConfigInput` 后初始化 audit;每步失败停止后续操作。
21
+ 2. 在实际业务成功/失败边界记录事件,明确审计失败如何影响业务,不重复记录同一事件。
22
+ 3. 查询使用返回的分页元数据;清理前核对保留期及授权范围。凭证字段会被脱敏,个人信息仍需业务策略。
23
+ 4. 检查写入、查询和清理的 HaiResult,先关闭 audit 再关闭数据库。
21
24
 
22
- > ⚠️ **服务端模块(Node.js only)。** 审计日志由服务端自动记录,浏览器端通过 API 端点查询审计数据。
25
+ ## 按需参考
23
26
 
24
- ## 依赖
27
+ 按本次操作读取对应小节;以已安装版本的公开类型核验签名,示例中的业务变量由应用提供。
25
28
 
26
- | 模块 | 用途 | 是否必需 | 初始化要求 |
27
- | --- | --- | --- | --- |
28
- | `@h-ai/reldb` | 数据库(审计日志持久化) | **必需** | 需在 `audit.init()` 前初始化 |
29
-
30
- ## 使用步骤
31
-
32
- ### 1. 配置
33
-
34
- 审计模块依赖已初始化的 `@h-ai/reldb` 单例,无需独立配置文件。审计日志固定存储在 `hai_audit_logs` 表中。
35
-
36
- ### 2. 初始化
37
-
38
- ```ts
39
- import { audit } from '@h-ai/audit'
40
- import { reldb } from '@h-ai/reldb'
41
-
42
- // 先初始化依赖
43
- await reldb.init({ type: 'sqlite', database: './data.db' })
44
-
45
- // 再初始化审计模块(自动使用已初始化的 reldb 单例)
46
- const result = await audit.init()
47
- if (!result.success) {
48
- // 处理错误
49
- }
50
- ```
51
-
52
- 自定义用户表映射:
53
-
54
- ```ts
55
- await audit.init({
56
- userTable: 'hai_iam_users',
57
- userIdColumn: 'id',
58
- userNameColumn: 'username',
59
- })
60
- ```
61
-
62
- ### 3. 关闭
63
-
64
- ```ts
65
- const closeResult = await audit.close()
66
- if (!closeResult.success) {
67
- throw new Error(closeResult.error.message)
68
- }
69
- ```
70
-
71
- ## 核心 API
72
-
73
- ### 生命周期
74
-
75
- | 方法 | 签名 | 说明 |
76
- | --------------------- | ---------------------------------------------------------------- | ---------- |
77
- | `audit.init` | `(config: AuditInitConfig) => Promise<HaiResult<void>>` | 初始化模块 |
78
- | `audit.close` | `() => Promise<HaiResult<void>>` | 关闭模块 |
79
- | `audit.isInitialized` | `boolean` | 初始化状态 |
80
-
81
- ### 日志操作
82
-
83
- | 方法 | 签名 | 说明 |
84
- | --------------------- | ----------------------------------------------------------------------------------- | -------------------- |
85
- | `audit.log` | `(input: CreateAuditLogInput) => Promise<HaiResult<AuditLog>>` | 记录审计日志 |
86
- | `audit.list` | `(options?: ListAuditLogsOptions) => Promise<HaiResult<PaginatedResult<AuditLogWithUser>>>` | 分页查询(items/total/page/pageSize,含用户名;使用返回的规范化元数据,默认 pageSize 20) |
87
- | `audit.getUserRecent` | `(userId: string, limit?: number) => Promise<HaiResult<AuditLog[]>>` | 用户最近活动 |
88
- | `audit.cleanup` | `(olderThanDays?: number) => Promise<HaiResult<number>>` | 清理旧日志 |
89
- | `audit.getStats` | `(days?: number) => Promise<HaiResult<AuditStatItem[]>>` | 操作统计 |
90
-
91
- ### 便捷记录器 (`audit.helper`)
92
-
93
- | 方法 | 说明 |
94
- | ------------------------------------------------------------------------------ | ------------ |
95
- | `audit.helper.login(userId, ip?, ua?)` | 登录 |
96
- | `audit.helper.logout(userId, ip?, ua?)` | 登出 |
97
- | `audit.helper.register(userId, ip?, ua?)` | 注册 |
98
- | `audit.helper.passwordResetRequest(email, ip?, ua?)` | 密码重置请求 |
99
- | `audit.helper.passwordResetComplete(userId, ip?, ua?)` | 密码重置完成 |
100
- | `audit.helper.crud(input)` | CRUD 操作 |
101
-
102
- > `audit.log()` / `audit.helper.*()` 中的 `details` 仅会自动脱敏凭证类字段(如 `password` / `token` / `secret`);邮箱、手机号默认保留原值。
103
-
104
- ## 错误码
105
-
106
- | 错误码 | code | 说明 |
107
- | --------------------------------- | ---------------- | ------------ |
108
- | `HaiAuditError.LOG_FAILED` | `hai:audit:001` | 记录失败 |
109
- | `HaiAuditError.QUERY_FAILED` | `hai:audit:002` | 查询失败 |
110
- | `HaiAuditError.CLEANUP_FAILED` | `hai:audit:003` | 清理失败 |
111
- | `HaiAuditError.STATS_FAILED` | `hai:audit:004` | 统计失败 |
112
- | `HaiAuditError.INIT_IN_PROGRESS` | `hai:audit:005` | 初始化进行中 |
113
- | `HaiAuditError.NOT_INITIALIZED` | `hai:audit:010` | 模块未初始化 |
114
- | `HaiAuditError.CONFIG_ERROR` | `hai:audit:012` | 配置错误 |
115
-
116
- ## 常见模式
117
-
118
- ### 用户认证审计
119
-
120
- ```ts
121
- // 登录
122
- await audit.helper.login(userId, request.ip, request.headers['user-agent'])
123
-
124
- // 登出
125
- await audit.helper.logout(userId, request.ip, request.headers['user-agent'])
126
- ```
127
-
128
- ### CRUD 操作审计
129
-
130
- ```ts
131
- await audit.helper.crud({ userId, action: 'create', resource: 'users', resourceId: newUser.id, details: { name: newUser.name } })
132
- await audit.helper.crud({ userId, action: 'update', resource: 'roles', resourceId: roleId, details: { changes } })
133
- await audit.helper.crud({ userId, action: 'delete', resource: 'permissions', resourceId: permId })
134
- ```
135
-
136
- ### 仪表盘数据
137
-
138
- ```ts
139
- // 最近日志
140
- const recentLogs = await audit.list({ pageSize: 10 })
141
-
142
- // 7 天统计
143
- const stats = await audit.getStats(7)
144
- ```
145
-
146
- ### 定期清理
147
-
148
- ```ts
149
- // 清理 90 天前的日志
150
- const result = await audit.cleanup(90)
151
- if (result.success) {
152
- logger.info(`Cleaned up ${result.data} old audit logs`)
153
- }
154
- ```
155
-
156
- ## 相关 Skills
157
-
158
- - `hai-reldb` — 数据库模块(审计模块依赖)
159
- - `hai-iam` — 身份认证与权限管理(审计的主要记录对象)
160
- - `hai-core` — 核心工具(日志、ID 生成、i18n)
29
+ - [运行环境](reference.md#运行环境)
30
+ - [依赖](reference.md#依赖)
31
+ - [使用步骤](reference.md#使用步骤)
32
+ - [核心 API](reference.md#核心-api)
33
+ - [错误码](reference.md#错误码)
34
+ - [常见模式](reference.md#常见模式)
35
+ - [相关 Skills](reference.md#相关-skills)
@@ -0,0 +1,145 @@
1
+ # hai-audit 参考
2
+
3
+ 统一审计日志模块,基于 `@h-ai/reldb` 实现持久化,提供审计日志的记录、分页查询、清理与统计。
4
+
5
+ ## 运行环境
6
+
7
+ > ⚠️ **服务端模块(Node.js only)。** 审计日志由服务端自动记录,浏览器端通过 API 端点查询审计数据。
8
+
9
+ ## 依赖
10
+
11
+ | 模块 | 用途 | 是否必需 | 初始化要求 |
12
+ | --- | --- | --- | --- |
13
+ | `@h-ai/reldb` | 数据库(审计日志持久化) | **必需** | 需在 `audit.init()` 前初始化 |
14
+
15
+ ## 使用步骤
16
+
17
+ ### 1. 配置
18
+
19
+ 审计模块依赖已初始化的 `@h-ai/reldb` 单例,无需独立配置文件。审计日志固定存储在 `hai_audit_logs` 表中。
20
+
21
+ ### 2. 初始化
22
+
23
+ ```ts
24
+ import { audit } from '@h-ai/audit'
25
+ import { reldb } from '@h-ai/reldb'
26
+
27
+ // 先初始化依赖
28
+ await reldb.init({ type: 'sqlite', database: './data.db' })
29
+
30
+ // 再初始化审计模块(自动使用已初始化的 reldb 单例)
31
+ const result = await audit.init()
32
+ if (!result.success) {
33
+ // 处理错误
34
+ }
35
+ ```
36
+
37
+ 自定义用户表映射:
38
+
39
+ ```ts
40
+ await audit.init({
41
+ userTable: 'hai_iam_users',
42
+ userIdColumn: 'id',
43
+ userNameColumn: 'username',
44
+ })
45
+ ```
46
+
47
+ ### 3. 关闭
48
+
49
+ ```ts
50
+ const closeResult = await audit.close()
51
+ if (!closeResult.success) {
52
+ throw new Error(closeResult.error.message)
53
+ }
54
+ ```
55
+
56
+ ## 核心 API
57
+
58
+ ### 生命周期
59
+
60
+ | 方法 | 签名 | 说明 |
61
+ | --------------------- | ---------------------------------------------------------------- | ---------- |
62
+ | `audit.init` | `(config?: AuditInitConfigInput) => Promise<HaiResult<void>>` | 初始化模块 |
63
+ | `audit.close` | `() => Promise<HaiResult<void>>` | 关闭模块 |
64
+ | `audit.isInitialized` | `boolean` | 初始化状态 |
65
+
66
+ ### 日志操作
67
+
68
+ | 方法 | 签名 | 说明 |
69
+ | --------------------- | ----------------------------------------------------------------------------------- | -------------------- |
70
+ | `audit.log` | `(input: CreateAuditLogInput) => Promise<HaiResult<AuditLog>>` | 记录审计日志 |
71
+ | `audit.list` | `(options?: ListAuditLogsOptions) => Promise<HaiResult<PaginatedResult<AuditLogWithUser>>>` | 分页查询(items/total/page/pageSize,含用户名;使用返回的规范化元数据,默认 pageSize 20) |
72
+ | `audit.getUserRecent` | `(userId: string, limit?: number) => Promise<HaiResult<AuditLog[]>>` | 用户最近活动 |
73
+ | `audit.cleanup` | `(olderThanDays?: number) => Promise<HaiResult<number>>` | 清理旧日志 |
74
+ | `audit.getStats` | `(days?: number) => Promise<HaiResult<AuditStatItem[]>>` | 操作统计 |
75
+
76
+ ### 便捷记录器 (`audit.helper`)
77
+
78
+ | 方法 | 说明 |
79
+ | ------------------------------------------------------------------------------ | ------------ |
80
+ | `audit.helper.login(userId, ip?, ua?)` | 登录 |
81
+ | `audit.helper.logout(userId, ip?, ua?)` | 登出 |
82
+ | `audit.helper.register(userId, ip?, ua?)` | 注册 |
83
+ | `audit.helper.passwordResetRequest(email, ip?, ua?)` | 密码重置请求 |
84
+ | `audit.helper.passwordResetComplete(userId, ip?, ua?)` | 密码重置完成 |
85
+ | `audit.helper.crud(input)` | CRUD 操作 |
86
+
87
+ > `audit.log()` / `audit.helper.*()` 中的 `details` 仅会自动脱敏凭证类字段(如 `password` / `token` / `secret`);邮箱、手机号默认保留原值。
88
+
89
+ ## 错误码
90
+
91
+ | 错误码 | code | 说明 |
92
+ | --------------------------------- | ---------------- | ------------ |
93
+ | `HaiAuditError.LOG_FAILED` | `hai:audit:001` | 记录失败 |
94
+ | `HaiAuditError.QUERY_FAILED` | `hai:audit:002` | 查询失败 |
95
+ | `HaiAuditError.CLEANUP_FAILED` | `hai:audit:003` | 清理失败 |
96
+ | `HaiAuditError.STATS_FAILED` | `hai:audit:004` | 统计失败 |
97
+ | `HaiAuditError.INIT_IN_PROGRESS` | `hai:audit:005` | 初始化进行中 |
98
+ | `HaiAuditError.NOT_INITIALIZED` | `hai:audit:010` | 模块未初始化 |
99
+ | `HaiAuditError.CONFIG_ERROR` | `hai:audit:012` | 配置错误 |
100
+
101
+ ## 常见模式
102
+
103
+ ### 用户认证审计
104
+
105
+ ```ts
106
+ // 登录
107
+ await audit.helper.login(userId, request.ip, request.headers['user-agent'])
108
+
109
+ // 登出
110
+ await audit.helper.logout(userId, request.ip, request.headers['user-agent'])
111
+ ```
112
+
113
+ ### CRUD 操作审计
114
+
115
+ ```ts
116
+ await audit.helper.crud({ userId, action: 'create', resource: 'users', resourceId: newUser.id, details: { name: newUser.name } })
117
+ await audit.helper.crud({ userId, action: 'update', resource: 'roles', resourceId: roleId, details: { changes } })
118
+ await audit.helper.crud({ userId, action: 'delete', resource: 'permissions', resourceId: permId })
119
+ ```
120
+
121
+ ### 仪表盘数据
122
+
123
+ ```ts
124
+ // 最近日志
125
+ const recentLogs = await audit.list({ pageSize: 10 })
126
+
127
+ // 7 天统计
128
+ const stats = await audit.getStats(7)
129
+ ```
130
+
131
+ ### 定期清理
132
+
133
+ ```ts
134
+ // 清理 90 天前的日志
135
+ const result = await audit.cleanup(90)
136
+ if (result.success) {
137
+ logger.info(`Cleaned up ${result.data} old audit logs`)
138
+ }
139
+ ```
140
+
141
+ ## 相关 Skills
142
+
143
+ - `hai-reldb` — 数据库模块(审计模块依赖)
144
+ - `hai-iam` — 身份认证与权限管理(审计的主要记录对象)
145
+ - `hai-core` — 核心工具(日志、ID 生成、i18n)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: hai-build
3
- description: "定位 hai 应用架构、模块依赖、初始化顺序、构建模式和对应技能。"
3
+ description: "构建或排查 hai 应用的源码、容器镜像和桌面产物;识别工程架构、依赖与对应构建入口。"
4
4
  ---
5
5
 
6
6
  # hai-build
@@ -21,11 +21,32 @@ description: "定位 hai 应用架构、模块依赖、初始化顺序、构建
21
21
  - 升级 hai-framework、比较版本差异或同步框架 skills 时,使用 [hai-framework-sync](../hai-framework-sync/SKILL.md) 完成版本发现、差异分析、选择/阻塞处理、迁移与验证。
22
22
  - 功能开发先用 [development.md](../hai-app-create/development.md) 把需求匹配到当前版本的框架能力与配置;再读取所选模块 skill 和公开类型。
23
23
  - 有生命周期的模块按真实依赖初始化、检查结果并反序清理;core、纯函数和工厂不套用相同生命周期。
24
- - 构建任务检查当前 engines、适配器、环境变量、缓存与目标产物,不能照搬框架仓库私有构建命令。
24
+ - 构建任务检查当前 engines、适配器、缓存与目标产物,不能照搬框架仓库私有构建命令。
25
+ - 多项门禁按 [分轮验证与集中修复](../hai-app-tests/validation.md) 先收集结果再集中修复;遵守产物依赖与资源隔离,不并行清理/重建同一输出目录,不用旧产物补成通过。
26
+
27
+ ## 构建与部署
28
+
29
+ - 创建默认包含开发期部署工具,可用 --no-deploy 关闭。每个镜像使用 images/ 中独立 Dockerfile,Web 配置位于 images/web/,不使用镜像阶段 target 配置。
30
+ - 构建器生成 images/dependencies/ 安装输入;fetch、安装和生产依赖整理共用 pnpm store,安装与生产依赖整理共用 SQLite 驱动缓存,并复用依赖层。file: 归档、补丁、workspace 元数据必须进入下载上下文;原生依赖缓存按系统/架构/ABI 区分。基础镜像、中间件及工具指定版本,禁止 latest。
31
+ - 默认容器面向 CPU 运行或远程 AI 服务,Dockerfile 设置 `ONNXRUNTIME_NODE_INSTALL_CUDA=skip`,跳过额外 CUDA/TensorRT 下载;使用宿主机 GPU 时定制镜像和运行参数,不修改本机 npm 或全局 AI/GPU 配置。
32
+ - pnpm run deploy --build 显式串联构建、打包和发布;--bundle-only 只交付完整离线包与跨平台脚本;--services 以服务器成功状态为基线只更新选中服务。完整包自动包含自建中间件镜像,服务器禁止联网拉取。
33
+ - `pnpm build` 默认仅编译源码(调用 compile);`pnpm build --target docker` 根据 hai.build.json 的 dockerfile 构建并导出 app/可选 web 镜像,可用 --images web 只构建前端,auto 优先可达 Podman、其次 Docker,可用 --runtime 显式指定。
34
+ - compile 交付源码编译结果,docker 交付镜像归档,desktop 交付 Tauri 系统安装包;每次只选一种。images[].dockerfile 指向独立镜像文件,最终阶段作为交付镜像;参数默认值和示例必须与真实入口同步。
35
+ - Podman 的客户端代理通过预定义构建参数传递,覆盖 Windows/macOS 远程引擎的服务端默认值;代理地址必须能从构建容器访问,--no-http-proxy 禁止此传递。不要把代理写成 Dockerfile ENV 或固化进交付镜像。
36
+ - --network 默认沿用引擎网络;只有实际构建网络无法访问依赖/代理时才显式选择网络,pasta 仅适用于 rootless Podman。build 与 run 的主机名解析可能不同,须验证构建网络中的可达性,不默认改成 host 网络。
37
+ - 从运行 build 的应用根 package.json.version 读取版本,不能使用 CLI/框架版本或服务子包版本代替。清单格式 version=3,appVersion 为应用版本;appContainerPort/webContainerPort 仅记录 images 配置显式填写的端口,部分构建也保留未选镜像端口,未填写时沿用部署默认值。镜像 tar 名含版本、buildId 区分同版本构建,Tauri 也接收根版本。不要手改清单或保留无版本的交付归档。
38
+ - 构建不区分 dev/test/prod,不加载部署环境覆盖,不注入运行期凭据;所选镜像清单含 SHA-256,全部成功才更新本机最近构建指针(不是镜像标签)。不要让 compile、Dockerfile 或 Tauri beforeBuildCommand 递归调用自身的原生/镜像构建。
39
+ - Vite 的 envDir 与 SvelteKit 的 kit.env.dir 是独立加载入口,必须同时阻止构建阶段读取工程根的 .env 文件;开发/预览由 core loader 注入,运行期由 deploy 注入。用临时 .env.local 哨兵值检查输出,避免只过滤进程变量却仍把私有文件固化进产物。
40
+ - 静态客户端通过 runtime-config.js 或原生宿主初始化脚本获取公开地址与元数据;仅投影公开白名单,禁止将完整 process.env、服务配置或密钥序列化到浏览器。预览与容器启动均须验证真实登录,不能依赖构建期 API 地址让 E2E 通过。
41
+ - Fullstack Capacitor App 在 `public/runtime-config.js` 提供公开 API 地址,再编译并同步原生资源;Tauri 从启动进程的 PUBLIC_API_BASE 注入。不能把开发代理的 .env 配置当作已安装原生包的运行配置。
42
+ - `pnpm build --target desktop --platform windows|linux|macos --arch x64|arm64` 调用对应工程的 Tauri build。要求在目标系统准备 Rust target、SDK 和打包工具,不假定跨系统编译。原生安装包必须按目标系统实测。
43
+ - deploy 默认消费已有产物,--build 显式先构建,详见 [hai-deploy](../hai-deploy/SKILL.md)。网络不通时 --bundle-only 生成 tar,按说明手工搬运;packaged 不代表部署已运行。
44
+ - 测试临时工程、镜像、容器、辅助进程和数据必须在 finally/teardown 自动清理,失败/取消也清理;日志、截图和报告保留到分析和交付结束再清理,不得提交测试产物或删除用户既有资源。
45
+ - 浏览器测试的数据放入本轮独立临时目录;Windows 等子进程与服务退出后再删除数据库和上传文件,不依赖下一轮测试补清理。
25
46
 
26
47
  ## 按需参考
27
48
 
28
- 详细配置、API 签名、错误码和范本在 [reference.md](reference.md)。按下列标题定位所需小节,不默认通读;用例中的业务变量需结合当前应用补齐。
49
+ 按任务读取 [reference.md](reference.md) 的对应小节;签名以当前源码或安装版本的公开类型为准,不默认加载全部资料。示例中的业务变量由应用提供。
29
50
 
30
51
  - 适用场景
31
52
  - 项目架构
@@ -42,7 +42,7 @@
42
42
  | 公共 API | oRPC contract + Hono + typed client |
43
43
  | 认证 | Bearer access token + httpOnly refresh cookie(浏览器推荐) |
44
44
 
45
- pnpm 专属配置放在 `pnpm-workspace.yaml`,`.npmrc` 仅用于注册表与认证。Docker 缓存层使用 `pnpm fetch` 读取锁文件;pnpm 12 的该命令不支持 `--frozen-lockfile`。后续仍通过 `pnpm install --offline --frozen-lockfile` 校验清单与锁文件一致。容器裁剪用 `pnpm pm deploy --filter <服务包> --prod <目标目录>`,确保执行内置命令,避免项目同名 `deploy` 脚本覆盖它。
45
+ pnpm 专属配置放在 `pnpm-workspace.yaml`,`.npmrc` 仅用于注册表与认证。Docker 缓存层使用 `pnpm fetch` 读取锁文件;pnpm 12 的该命令不支持 `--frozen-lockfile`。后续仍通过 `pnpm install --offline --frozen-lockfile` 校验清单与锁文件一致。容器裁剪用 `pnpm pm deploy --filter <服务包> --prod <目标目录>`,确保执行内置命令,避免项目同名 `deploy` 脚本覆盖它。保留 `.gitattributes`,让 `.dockerignore`、Dockerfile 和 POSIX 脚本统一使用 LF,保持跨平台输入一致并确保 Linux 脚本可运行。
46
46
 
47
47
  ### SvelteKit Adapter 模式
48
48
 
@@ -277,12 +277,15 @@ pnpm --filter <app-name> test:e2e
277
277
  pnpm --filter <app-name> test
278
278
  pnpm --filter <app-name> test:e2e
279
279
 
280
- # Refactor:质量门禁
280
+ # Refactor:按下方分轮验证流程收集适用门禁
281
281
  pnpm typecheck
282
282
  pnpm lint
283
+ pnpm build # 构建/配置/模板/跨包契约变更
283
284
  pnpm test
284
285
  ```
285
286
 
287
+ 以上命令按 [分轮验证与集中修复](../hai-app-tests/validation.md) 调度,不在普通失败时立即修改并从头重跑。
288
+
286
289
  ## 统一编码规范
287
290
 
288
291
  ### 强制规则
@@ -311,7 +314,7 @@ return kit.response.ok(result.data)
311
314
 
312
315
  ### 质量门禁
313
316
 
314
- 按当前项目已定义的 scripts 和变更影响执行;PowerShell 使用 `pnpm.cmd`:
317
+ 按当前项目已定义的 scripts 和变更影响选择检查,执行 [分轮验证与集中修复](../hai-app-tests/validation.md):普通失败先记录,独立检查继续,汇总后集中修复。PowerShell 使用 `pnpm.cmd`:
315
318
 
316
319
  ```bash
317
320
  pnpm typecheck # TypeScript 类型检查
@@ -338,11 +341,9 @@ pnpm test # Vitest 单元测试
338
341
 
339
342
  ### 变更后:验证
340
343
 
341
- 1. `pnpm typecheck` 通过
342
- 2. `pnpm lint` 通过
343
- 3. 构建/配置/跨包变更 `pnpm build` 通过
344
- 4. `pnpm test` 通过(单元测试)
345
- 5. UI/路由/端到端改动执行相应 `test:e2e`;从 package.json 确认入口
346
- 6. 搜索确认所有引用点已更新,报告未验证边界
344
+ 1. 按影响范围调度一轮 typecheck/lint/build/test;UI/路由/端到端改动加相应 E2E,从 package.json 确认入口
345
+ 2. 记录全部可执行结果与日志;真实前置失败只阻塞依赖项,普通失败不边测边改
346
+ 3. 归并问题并集中修复,再验证失败、阻塞及受影响项;最终必需门禁对最终代码有效通过
347
+ 4. 搜索确认所有引用点已更新,报告未验证边界与结果来源
347
348
 
348
349
  涉及原生交付时按当前项目 Tauri/Gradle/Xcode 等实际入口打包,在目标 OS/设备验证安装启动、会话、安全 TokenStorage、API 域名及覆盖升级。Web 构建/E2E 不代替原生验收;记录平台/工具链与结果,缺平台写未验证。