@h-ai/cli 1.0.0-beta.21 → 1.0.0-beta.23

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 (60) hide show
  1. package/README.en.md +13 -12
  2. package/README.ja.md +13 -12
  3. package/README.md +13 -12
  4. package/dist/{chunk-2ZL5ORQ2.js → chunk-P2VZ3VV6.js} +2 -14
  5. package/dist/chunk-P2VZ3VV6.js.map +1 -0
  6. package/dist/{chunk-L53P43B2.js → chunk-V7WGSBX3.js} +41 -21
  7. package/dist/chunk-V7WGSBX3.js.map +1 -0
  8. package/dist/cli-config-templates-VLXJTHCQ.js +5 -0
  9. package/dist/{cli-config-templates-LWMD2I6V.js.map → cli-config-templates-VLXJTHCQ.js.map} +1 -1
  10. package/dist/{cli-skill-templates-D6S2OQ6X.js → cli-skill-templates-JKF6E3PI.js} +3 -3
  11. package/dist/{cli-skill-templates-D6S2OQ6X.js.map → cli-skill-templates-JKF6E3PI.js.map} +1 -1
  12. package/dist/index.js +161 -244
  13. package/dist/index.js.map +1 -1
  14. package/dist/metafile-esm.json +1 -1
  15. package/package.json +14 -14
  16. package/templates/apps/fullstack/docs/security-configuration.md.hbs +3 -3
  17. package/templates/apps/fullstack/images/web/nginx.conf.hbs +3 -1
  18. package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +1 -1
  19. package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/api-client.test.ts.hbs +4 -1
  20. package/templates/base/images/web/nginx.conf.hbs +3 -1
  21. package/templates/base/package.json.hbs +1 -1
  22. package/templates/shared/download-error/http.conf +19 -0
  23. package/templates/shared/download-error/server.conf +52 -0
  24. package/templates/skills/hai-ai/acp.md +1 -1
  25. package/templates/skills/hai-ai/guide.md +1 -1
  26. package/templates/skills/hai-ai/reference.md +1 -1
  27. package/templates/skills/hai-api-client/SKILL.md +2 -2
  28. package/templates/skills/hai-app-create/SKILL.md +2 -0
  29. package/templates/skills/hai-app-create/development.md +3 -3
  30. package/templates/skills/hai-app-create/logging.md +32 -0
  31. package/templates/skills/hai-app-create/project.md +1 -0
  32. package/templates/skills/hai-app-create/reference.md +2 -4
  33. package/templates/skills/hai-app-review/SKILL.md +1 -1
  34. package/templates/skills/hai-audit/SKILL.md +1 -1
  35. package/templates/skills/hai-audit/reference.md +1 -1
  36. package/templates/skills/hai-build/SKILL.md +1 -1
  37. package/templates/skills/hai-build/paths.md +1 -1
  38. package/templates/skills/hai-core/reference.md +2 -11
  39. package/templates/skills/hai-crypto/SKILL.md +1 -1
  40. package/templates/skills/hai-crypto/reference.md +3 -3
  41. package/templates/skills/hai-deploy/SKILL.md +8 -8
  42. package/templates/skills/hai-deploy/middleware.md +2 -2
  43. package/templates/skills/hai-framework-sync/SKILL.md +4 -4
  44. package/templates/skills/hai-iam/SKILL.md +1 -1
  45. package/templates/skills/hai-iam/reference.md +1 -1
  46. package/templates/skills/hai-kit/SKILL.md +2 -2
  47. package/templates/skills/hai-kit/reference.md +3 -3
  48. package/templates/skills/hai-reach/SKILL.md +1 -1
  49. package/templates/skills/hai-reldb/SKILL.md +1 -1
  50. package/templates/skills/hai-reldb/reference.md +2 -3
  51. package/templates/skills/hai-scheduler/reference.md +1 -1
  52. package/templates/skills/hai-serv/SKILL.md +1 -1
  53. package/templates/skills/hai-serv/reference.md +2 -2
  54. package/templates/skills/hai-storage/SKILL.md +1 -0
  55. package/templates/skills/hai-storage/reference.md +14 -4
  56. package/templates/skills/hai-vecdb/reference.md +1 -1
  57. package/dist/chunk-2ZL5ORQ2.js.map +0 -1
  58. package/dist/chunk-L53P43B2.js.map +0 -1
  59. package/dist/cli-config-templates-LWMD2I6V.js +0 -5
  60. package/templates/skills/hai-deploy/credentials.md +0 -19
@@ -8,7 +8,7 @@
8
8
 
9
9
  默认部署名取工程根(最近的 `hai.json` 或锁文件所在目录)的 `package.json.name`,缺失时报错,再附加显式环境后缀。例如 fullstack 工程 `hai-delivery` 扫描 `packages/hai-delivery-serv`,`--env test` 生成 `/opt/hai/apps/hai-delivery-test` 和 `bundle-hai-delivery-test-<部署ID>-<版本>.tar.gz`。远端目录、交付包、Compose 项目、API/Web/中间件容器、数据卷、服务器凭据状态及增量基线统一使用该名称;不会按字符串删除真实项目名中的 `-serv`。
10
10
 
11
- 资源身份和制品格式沿用[构建技能](../hai-build/SKILL.md)及[网站挂载目录](../hai-build/paths.md):根目录格式4,非根目录格式5,两者都有primaryService/hasWeb;webBasePath仅格式5。旧工程同步镜像角色、Dockerfile、-serv包名与引用后重建,不手改清单。旧部署先核对项目名、卷和受管凭据,再建立完整基线;工具不跨项目迁移数据,改target目录不能完成迁移。
11
+ 部署身份取自工程根 `package.json.name`。镜像清单字段及公开挂载目录见[构建技能](../hai-build/SKILL.md)与[网站挂载目录](../hai-build/paths.md)。
12
12
 
13
13
  `hai deploy` 首先输入部署环境,或用 `hai deploy --env test` 指定。`.env.test` / `.env.prod` 必须由用户先创建;缺失时停止,不代替用户创建一个空文件继续部署。指定要部署的目录,例如 `hai deploy packages/my-app-serv --env test`,该目录必须对应 lockfile 的一个 importer;不遍历 apps/packages 或猜测 fullstack 布局。环境文件默认取当前目录(有 `.env` 时)或 lockfile 根目录,必要时传 `--env-dir`。
14
14
 
@@ -23,7 +23,7 @@
23
23
 
24
24
  `.env.<mode>.local` 同时用于普通开发、Node 启动和部署;通过公共 Core 工具合并,不实现模块专用来源顺序。
25
25
 
26
- 交付 tar 内的 `.env.runtime` 是按上述配置生成的 Compose 运行文件,不是下次部署的配置源。`NODE_ENV` 默认按目标模式选择:test 为 test,dev/development 为 development,其余为 production;显式应用配置仍可覆盖。构建保持正式优化模式,旧包需重新生成。完整配置使用 `--env test --yes` 复用;需要保持中间件时追加 `--skip-middleware`。自建中间件的密码由服务器 `<remoteDir>/managed-secrets.env` 持久保存(权限 0600),应与数据卷一起备份。每次打包只生成首次初始化的随机候选,不依赖打包机缓存;在线 SDK、deploy.sh、deploy.ps1 和 deploy-local.sh 都在部署锁内复用服务器值,同时更新应用连接配置及中间件原生变量。交付 tar 保持不可变,只有服务器私有运行文件使用定稿值。若状态缺失而对应数据卷已存在,部署在变更服务前明确停止,须恢复服务器凭据备份;不会自动换密或删除数据。旧版本可通过显式预检和凭据导入流程迁移,缺状态的普通部署仍拒绝。
26
+ 交付 tar 内的 `.env.runtime` 是按上述配置生成的 Compose 运行文件,不是下次部署的配置源。`NODE_ENV` 默认按目标模式选择:test 为 test,dev/development 为 development,其余为 production;显式应用配置仍可覆盖。构建保持正式优化模式,旧包需重新生成。完整配置使用 `--env test --yes` 复用;需要保持中间件时追加 `--skip-middleware`。自建中间件的密码由服务器 `<remoteDir>/managed-secrets.env` 持久保存(权限 0600),应与数据卷一起备份。每次打包只生成首次初始化的随机候选,不依赖打包机缓存;在线 SDK、deploy.sh、deploy.ps1 和 deploy-local.sh 都在部署锁内复用服务器值,同时更新应用连接配置及中间件原生变量。交付 tar 保持不可变,只有服务器私有运行文件使用定稿值。若状态缺失而对应数据卷已存在,部署在变更服务前明确停止,须恢复服务器凭据备份;不会自动换密或删除数据。
27
27
 
28
28
  自建或云开通的整体 `HAI_*` 配置会清除被替换的旧叶字段,例如 Redis 覆盖后不再留下 `HAI_CACHE_TYPE=memory`。全局 `~/.hai/credentials.yml` 只补缺项,不能覆盖当前环境/进程的同名键或父配置。部署先启动选中中间件,等待 PostgreSQL/MySQL/Redis/S3 健康,再启动 serv/Web;增量和失败恢复沿用此顺序,未选容器保持不变。
29
29
 
@@ -17,7 +17,7 @@ description: "升级应用的 hai-framework 到最新或指定发布版本:分
17
17
 
18
18
  ## 任务入口
19
19
 
20
- - 用户说“升级 Hai-framework 到最新版本”时,直接从当前应用执行下方升级流程。该请求已授权常规依赖更新、必要兼容迁移、skills 合并和本地验证;不为每个文件修改重复确认,也不只输出升级建议后结束。
20
+ - 用户说“升级 Hai-framework 到最新版本”时,直接从当前应用执行下方升级流程。该请求已授权常规依赖更新、必要的应用调用和配置更新、skills 合并和本地验证;不为每个文件修改重复确认,也不只输出升级建议后结束。
21
21
  - 用户仅要求审查/比较版本时,完成现状、目标与差异分析,不安装或修改应用。
22
22
  - 仅同步通用规范、AI 入口或联调两个仓库时,按需读取 [同步与本地联调](sync.md);普通应用升级不要求框架仓库可写。
23
23
  - 先识别当前目录是否为目标应用;确实无法确定目标项目时才询问。应用升级不包含 npm 发布、部署、生产数据迁移或系统级工具安装,已有明确授权时按其范围执行。
@@ -50,7 +50,7 @@ npm view @h-ai/cli dist-tags --json
50
50
 
51
51
  ### 3. 比较累计差异并关联应用
52
52
 
53
- 在修改依赖前,读取当前到目标版本之间的 Release/CHANGELOG、迁移说明及官方提交差异,覆盖中间版本;混版本逐包比较。上游仓库从包元数据或官方 README 确认,按发布 tag/commit 定位,不能把 main 分支的未发布能力归到目标版本。
53
+ 在修改依赖前,读取当前到目标版本之间的 Release、CHANGELOG 和上游提交差异,覆盖中间版本;混版本逐包比较。上游仓库从包元数据或官方 README 确认,按发布 tag/commit 定位,不能把 main 分支的未发布能力归到目标版本。
54
54
 
55
55
  没有本地框架源码也应继续:在临时目录用 `npm pack <包名>@<精确版本> --ignore-scripts --pack-destination <临时目录>` 获取当前/目标包,比较 package.json.exports、公开 `.d.ts`、配置 schema/默认值、实现与随包文档;从同版本 CLI 的 `templates/skills/` 获取完整技能目录及入口模板。占位参数先替换为已确认值;只读比较产物,不覆盖应用或执行其中脚本。命令依据:[npm view](https://docs.npmjs.com/cli/commands/npm-view)、[npm pack](https://docs.npmjs.com/cli/commands/npm-pack)。
56
56
 
@@ -59,7 +59,7 @@ npm view @h-ai/cli dist-tags --json
59
59
  逐项检查并关联实际文件/调用点:
60
60
 
61
61
  - 公开入口、API/类型/错误码、HaiResult 与流/抛错语义、初始化依赖和关闭行为。
62
- - 配置 schema、默认行为、环境覆盖、认证/安全策略、DB schema/迁移、外部服务与引擎要求。
62
+ - 配置 schema、默认行为、环境覆盖、认证/安全策略、持久表结构、外部服务与引擎要求。
63
63
  - 构建/运行/发布脚本、第三方 peer 依赖、原生/容器集成,以及版本绑定的补丁是否仍必要。
64
64
  - skills 及相邻资源、AGENTS/Claude/Copilot/OpenCode 路由。
65
65
 
@@ -106,4 +106,4 @@ npm view @h-ai/cli dist-tags --json
106
106
  - 修复本次引入的失败,区分升级前已有失败。必要验收缺服务/凭证/平台时提示阻塞;额外平台或未涉及的真实 Provider 验证明确标为未执行及原因,不能用 mock/Web 结果冒充真实/原生验证。
107
107
  - 最终报告当前 → 目标及来源、复用的框架能力与清理项、补丁等用户决定、配置与关键流程的变动、变更文件与同步入口、实际门禁和未验证边界、恢复方法。依赖与必要迁移完成、选择/阻塞已解除且必要验证通过才称“升级完成”;否则报告当前进度与下一步,用户处理后继续完成。
108
108
 
109
- 指定精确版本后先 hai upgrade <version>,一次核对实际消费包及 CLI/deploy 发布完整性、制品/skills、catalog/lock/安装漂移和业务定制。此命令只读,缺包不得先改工程;报告完整后再按本 skill 执行获授权的升级,合并定制不覆盖。数据库迁移单独停旧写入、备份、migrateIam/migrateReach/migrateScheduler 预检;无凭据代次的旧会话重新登录。
109
+ 指定精确版本后先 hai upgrade <version>,一次核对实际消费包及 CLI/deploy 发布完整性、制品/skills、catalog/lock/安装漂移和业务定制。此命令只读,缺包不得先改工程;报告完整后再按本 skill 执行获授权的升级,合并定制不覆盖。发布前核对持久结构,保留数据库和会话缓存备份。在独立环境验证初始化和登录。
@@ -80,7 +80,7 @@ OTP 发布/消费用单身份 CAS;密码重置最终 SQL 同时核验 resetVer
80
80
 
81
81
  配置示例用 `IamConfigInput` 表达可省略默认值的输入;需要完整策略快照时用对应 Schema.parse 得到输出类型。应用仅从 `@h-ai/iam` 取公开函数/类型,不深导内部策略与仓储。源码内部示例明确标注上下文,文档示例类型检查不替代真实共享存储和通知集成验证。
82
82
 
83
- 默认 Reach 通知自动使用 sensitive/expiresAt/idempotencyKey,不保存凭据正文或进入延迟队列;自定义回调同样遵守有效期与幂等。RelDB 初始化后可 migrateIam({dryRun:true}),iam.init 执行支持版本的字段升级,保留用户/密码。升级前停旧写入并备份;无安全代次的旧会话需重新登录,不能降级凭据安全代次。
83
+ 默认 Reach 通知自动使用 sensitive/expiresAt/idempotencyKey,不保存凭据正文或进入延迟队列;自定义回调同样遵守有效期与幂等。先初始化 RelDB。`iam.init()` 创建并校验当前表结构,结构不符时返回初始化失败。会话凭据代次不匹配时重新登录。
84
84
 
85
85
  - 可选再认证规则为文件 operations 与权限 sensitiveOperations 的并集,主开关仍是 reauthentication.enabled;可信管理端使用 authz.setPermissionSensitiveOperations,异步 iam.getPublicConfig 返回含数据库的有效公开策略,读取失败拒绝放行。session.terminalLimits 按 web/app/desktop/api 限制,非空时未列类型拒绝;全局 maxSessions/singleDevice 同时生效,终端分组不是硬件真实性证明。原地登录使用标准 expectedUserId 限定原用户,凭据/验证码/锁定规则照常执行。
86
86
 
@@ -511,7 +511,7 @@ SvelteKit 使用 `kit.auth.createApi(iam)` 导出标准 handler,匿名端点
511
511
 
512
512
  未启用额外期限时,access 与 refresh 独立到期:access 过期仍可凭有效 refresh 轮换,刷新不先要求旧 access 认证。`session.idleTimeout`、`absoluteTimeout` 以秒配置,0关闭;启用后 access 与 refresh 均检查,刷新保留首次登录时间。成功的 access 认证请求算活动;自动 refresh 仅换票,不延长闲置期限。后台业务轮询仍需按项目设计。`maxSessions: 0` 不限,否则在用户分区 CAS 原子限制有效会话数;`singleDevice: true` 默认顶旧保新,`singleDeviceMode: 'reject'` 保留旧会话并拒绝新登录。删除 access、logoutAll、单设备替换均撤销对应 refresh;`revokeRefresh` 保留仍有效的 access。
513
513
 
514
- 账号生命周期仅使用必填 `accountStatus`(active/dormant/closed),无 User.enabled;列表过滤/排序同名,注册 defaultAccountStatus 默认 active、可设 dormant。beta.1 迁移前停旧写入并备份数据库;v6 将原停用 active 账号转 dormant 后删除旧列,镜像回滚不能恢复数据库。账号默认 `permanent/active`;管理端可配置 `temporary` 与 `accountExpiresAt`,或设 `accountStatus` 为 `dormant/closed`。状态/有效期变化推进持久凭据代际,重新激活不恢复旧会话。`accounts.dormantAfterDays: 0` 关闭自动休眠;启用后按 `scanIntervalSeconds` 扫描最后成功登录/创建时间,也可从可信后台调用 `iam.user.scanInactiveAccounts()`。公开注册不能接受管理字段;`closed` 保留记录,个人数据注销由项目处理。
514
+ 账号生命周期使用必填 `accountStatus`(active/dormant/closed)。列表过滤和排序使用同名字段,注册 `defaultAccountStatus` 默认为 `active`,也可设置为 `dormant`。账号默认 `permanent/active`;管理端可配置 `temporary` 与 `accountExpiresAt`,或设 `accountStatus` 为 `dormant/closed`。状态/有效期变化推进持久凭据代际,重新激活不恢复旧会话。`accounts.dormantAfterDays: 0` 关闭自动休眠;启用后按 `scanIntervalSeconds` 扫描最后成功登录/创建时间,也可从可信后台调用 `iam.user.scanInactiveAccounts()`。公开注册不能接受管理字段;`closed` 保留记录,个人数据注销由项目处理。
515
515
 
516
516
  `password.minCharacterClasses` 支持任意 N 类字符;创建/改密/重置共用服务端强度校验。`expirationDays: 0` 关闭期限;`preventSamePassword` 可独立启用,期限或首次强改时也拒绝旧密码。`requireInitialChange` 只约束管理端初始/重置密码,关闭后不受历史标记约束。首次/过期用户用 `iam.user.renewPassword({identifier,password,newPassword})` 完成原密码验证与换密后重新登录,不能先授予普通会话。AuthPanel 与标准 Kit/Serv 端点提供该流程。
517
517
 
@@ -28,7 +28,7 @@ transport 仅支持 v2:SM2 发送方签名、独立密钥的 Encrypt-then-HMAC
28
28
  3. 区分返回 HaiResult 的业务操作与抛 Response/redirect/error 的框架控制流,不吞掉控制流。
29
29
  4. 对齐 Cookie/CSRF/transport 与服务端配置,验证匿名、登录、权限拒绝和表单失败。
30
30
 
31
- 默认请求日志支持 prerender:查询应从独立 `new URL(event.request.url)` 读取,路径保留 `event.url.pathname`,不为观测读取跟踪 URL 的 search/searchParams 而建立页面依赖或触发静态构建错误。保持默认日志开启、JSON 正文日志默认关闭;查询/可选正文先脱敏再写 trace,正文读取副本,不能消耗业务请求。页面业务确实依赖查询时仍按 SvelteKit 的动态路由条件处理,不用日志绕过来声明业务可静态生成。
31
+ 默认请求日志支持 prerender。查询从独立 `new URL(event.request.url)` 统计参数数量,路径保留 `event.url.pathname`。JSON 正文日志默认关闭,显式启用时从请求副本读取并脱敏。页面业务确实依赖查询时按 SvelteKit 的动态路由条件处理。
32
32
 
33
33
  Kit 自动请求审计与 Serv 一样,仅在请求时发现 audit.isInitialized 才写入;未选 Audit 的站点不因默认 handle 产生未初始化错误。选择 Audit 时检查 init 结果并失败停止启动;显式业务审计仍遵守初始化和事务合同,已就绪模块写入失败必须保留诊断,不能当作可选模块静默跳过。handle 创建早于模块初始化时不能在装配阶段把审计永久禁用。
34
34
 
@@ -38,7 +38,7 @@ Kit 自动请求审计与 Serv 一样,仅在请求时发现 audit.isInitialize
38
38
 
39
39
  业务容量统一配置 transport.maxPlaintextBytes:UTF-8 JSON 明文字节,默认 1 MiB,有效整数范围 1 KiB~64 MiB,请求和响应共用。客户端从握手获取服务端预算,可选本地上限取较小值;resolveTransportBodyLimits 自动推导密文预算为两倍明文加 32 KiB。握手 JSON 16 KiB、公钥 4 KiB、认证头 16 KiB、路径 8 KiB、认证及防重放保持独立。原流超限/取消立即停止、取消并释放 reader;请求 413、响应返回加密的 500 容量错误,客户端识别 TransportBodyTooLargeError / hai:crypto:070。 通过 _kit.yml 的 transport.maxPlaintextBytes 或对应 HAI_*_TRANSPORT_MAXPLAINTEXTBYTES 配置并转发到服务端 transport;重建正文保留 signal 并删除旧长度/编码头。
40
40
 
41
- 错误提示与诊断分离:HTTP/UI 边界用 core.error.toPublic,仅公开 i18n 安全消息及 error.traceId;重新翻译后用 core.error.formatMessage 保留关联。ToastContainer 默认只显示可读说明,自动将编号移入排查信息图标,展开后可查看、复制并提供给客户支持或开发人员。前后端日志传完整 Error 和操作上下文,使用同一 requestId/traceId 并脱敏;禁止只写通用错误标题,也不能把 cause/ext/SQL/绑定值直接返回用户。数据库日志保留安全的驱动错误码、消息和堆栈。
41
+ HTTP/UI 边界用 `core.error.toPublic` 公开本地化安全消息和 `error.traceId`,重新翻译后用 `core.error.formatMessage` 保留编号。ToastContainer 可展开查看和复制。HTTP 4xx 记录 `debug`,5xx 记录 `error` 并保留安全的服务端诊断。日志字段和跨层关联按 [日志与错误诊断](../hai-app-create/logging.md)。
42
42
 
43
43
  ## 按需参考
44
44
 
@@ -8,7 +8,7 @@ HTTP/UI 边界只对明确的有效 4xx 状态公开业务提示;错误缺少
8
8
 
9
9
  认证协议仅支持 v2:独立随机 SM4-CBC 密钥和 HMAC-SM3 密钥由 SM2 封装,先验签、再验证 MAC,最后解密 CBC。请求由客户端私钥签名,响应由所选服务端版本签名。认证字段包括 version、direction、serverKeyId、clientId、128 位随机 requestId(兼 nonce)、issuedAt、HTTP method、pathname + 原始 search 的 SM3 pathHash,以及响应 status。请求默认有效期为 5 分钟,客户端时间最多可领先服务器 30 秒。服务端可用 `maxRequestAgeSeconds`(1~600)和 `maxFutureSkewSeconds`(0~300)调整,单位为整数秒。共享 registry 原子消费 (clientId, requestId),nonce 保留到 issuedAt + 11 分钟,覆盖最长可配窗口及节点时钟差,存储故障拒绝请求。Redis 必须保留有效 nonce,使用 noeviction/可靠持久化策略;各节点时钟须同步。此能力防止同一传输消息重放,业务重试仍需自己的幂等键。
10
10
 
11
- 在 `_kit.yml` 的 `transport` 块配置时间窗口,将字段传给服务端 transport 装配。完成旧节点升级后等待 12 分钟,再把有效期调到 300 秒以上。校时提示与 `TransportTimeError.serverTime` 见 [Crypto 参考](../hai-crypto/reference.md)。`kit.client.createAuthActions()` 将已认证校时错误转为 `HaiResult`,供 AuthPanel 展示。
11
+ 在 `_kit.yml` 的 `transport` 块配置时间窗口,将字段传给服务端 transport 装配。校时提示与 `TransportTimeError.serverTime` 见 [Crypto 参考](../hai-crypto/reference.md)。`kit.client.createAuthActions()` 将已认证校时错误转为 `HaiResult`,供 AuthPanel 展示。
12
12
 
13
13
  空 POST 也发送空明文的认证封装;GET/HEAD 将封装放在 X-Hai-Transport 头,204/304/HEAD 等无正文响应也使用同名头承载认证封装。其它请求/响应在 JSON 正文承载封装并带 X-Encrypted: true。客户端必须关联原请求上下文和 HTTP status,缺标记、旧格式或认证失败一律 reject;明文接口由 Serv/Kit 路径规则 `encryption: disabled` 或宿主 `excludePaths` 显式允许;调用方同步选择普通请求,API Client/Kit 包装器使用自己的 `excludePaths`。CORS 须允许并暴露 X-Hai-Transport。握手公钥的真实性依赖 TLS,不替代 IAM 业务授权。
14
14
 
@@ -42,7 +42,7 @@ export const handle: Handle = haiHandle
42
42
 
43
43
  ### 2. SvelteKit API endpoint
44
44
 
45
- 业务失败用 `kit.response.fromResult/fromError`,保留安全字段错误、显式 `publicExt` 和 HTTP 状态,内部异常仅进入关联日志;不要在业务 endpoint 手工拼接原始异常。
45
+ 业务失败用 `kit.response.fromResult/fromError`,保留安全字段错误、显式 `publicExt` 和 HTTP 状态。4xx 使用 `debug` 记录错误码、状态和追踪编号,5xx 使用 `error` 记录服务端异常诊断。请求日志仅记录查询参数数量。
46
46
 
47
47
  ```ts
48
48
  import { kit } from '@h-ai/kit'
@@ -101,7 +101,7 @@ export const handle = kit.createHandle({
101
101
  })
102
102
  ```
103
103
 
104
- 需要保护会话 Cookie 时配置 `crypto.encryptedCookies`,并通过 `crypto.cookieEncryptionKey` 或 `HAI_KIT_COOKIE_KEY` 提供密钥。密钥必须为 32 位十六进制。Cookie 采用分离子密钥的 SM4-CBC/HMAC-SHA256,先验证版本、名称、IV 与密文,再解密;旧版无认证 Cookie 升级后失效,需重新登录。缺少或非法密钥会在 `createHandle()` 时失败;加解密错误不会回退到明文 Cookie。
104
+ 需要保护会话 Cookie 时配置 `crypto.encryptedCookies`,并通过 `crypto.cookieEncryptionKey` 或 `HAI_KIT_COOKIE_KEY` 提供密钥。密钥必须为 32 位十六进制。Cookie 使用独立子密钥执行 SM4-CBC 和 HMAC-SHA256,验证版本、名称、IV 与密文后解密。`createHandle()` 会拒绝缺失或无效的密钥。
105
105
 
106
106
  不再使用无运行入口的旧 Crypto Helpers 或其 `CryptoServiceLike`、`EncryptedCookieConfig`、`CryptoCsrfConfig`、`WebhookVerifyConfig` 类型;这些已删除。Cookie 通过上述 `kit.createHandle` 配置保护,其他加密能力使用 `@h-ai/crypto` 真实公开 API。
107
107
 
@@ -42,4 +42,4 @@ API 空 2xx 表示受理成功;非空 JSON 回执上限 64 KiB。redirect 默
42
42
 
43
43
  IAM 通知使用 `otp_email`、`otp_sms`、`password_reset`、`password_reset_sms` 标准模板;将已初始化的 `reach` 传入 `iam.init`。Console Provider 只记录元数据,不输出验证码/令牌,不代替实际邮件/短信发送。
44
44
 
45
- 凭据通知用 sensitive:true、Unix 毫秒 expiresAt 和无凭据的稳定 idempotencyKey。共享 DB 仅存元数据回执,不存正文/变量/凭据摘要,不延迟重投;成功返回 receiptId,不明结果不自动重发。开发 Console 明确允许的输出与持久观察器隔离,生产 Console 限制不变。普通通知可用 deferPolicy: reject 将排队交给调用方。升级先 migrateReach({dryRun:true}),旧载荷一次性退役,旧在途 unknown,先备份停旧写入。
45
+ 凭据通知用 sensitive:true、Unix 毫秒 expiresAt 和无凭据的稳定 idempotencyKey。共享 DB 仅存元数据回执,不存正文/变量/凭据摘要,不延迟重投;成功返回 receiptId,不明结果不自动重发。开发 Console 明确允许的输出与持久观察器隔离,生产 Console 限制不变。普通通知可用 deferPolicy: reject 将排队交给调用方。`reach.init()` 创建并校验发送日志表及队列标识约束。
@@ -41,4 +41,4 @@ description: "使用 @h-ai/reldb 访问 SQLite/PostgreSQL/MySQL,编写 SQL、C
41
41
 
42
42
  JSON 对象合并使用 RFC 7396 补丁,必须将返回的 SQL/params 放在同一次 UPDATE 内;禁止先读对象再覆盖整个列来模拟跨节点原子合并。路径函数的后端差异和完整可类型检查示例见 [reference.md](reference.md)。
43
43
 
44
- 框架模块维护自己的版本迁移,应用不直接 ALTER 框架表。`reldb.schemaColumns(table, sql?)` 只读真实列;`reldb.migrateSchema(module, steps, { dryRun: true })` 不创建账本。生产先停旧写入并备份 DB/共享会话缓存;SQLite/PostgreSQL 事务,MySQL DDL 隐式提交须可重入,失败不推进版本且重试检查真实结构。回退恢复兼容 DB 与代码,不只换二进制。模块 migrateIam/migrateReach/migrateScheduler 分别预检,初始化执行受支持步骤。
44
+ `reldb.schemaColumns(table, sql?)` 读取实际列名。框架模块按当前定义初始化并校验各自的表。应用只管理自己的业务表。
@@ -5,7 +5,7 @@
5
5
  > `@h-ai/reldb` 提供统一的数据库操作接口,支持 SQLite、PostgreSQL、MySQL,包含 DDL、SQL、CRUD 抽象、事务与分页。
6
6
 
7
7
 
8
- 派生 `BaseReldbCrudRepository` 的自定义 SQL 方法先检查 `await this.ensureReady()`;构造函数启动自动建表不等于仓库就绪,服务 init 必须等待候选仓库的就绪入口再发布。PostgreSQL 自动提交的单条 `CREATE TABLE/INDEX IF NOT EXISTS` 仅对 `23505/pg_class_relname_nsp_index`(建表还包括 `pg_type_typname_nsp_index`)目录竞争,或建表时 `42710` 且服务端 routine 为 `heap_create_with_catalog` / `TypeCreate` 的行类型竞争重执行一次;重试仍失败则保留错误,DDL 与 SQL 入口一致;事务、业务唯一约束及其他错误不自动重试。初始化连接探测仅对临时 DNS 错误 `EAI_AGAIN` 最多尝试三次,间隔 250/500 ms;不重放业务 SQL。
8
+ 派生 `BaseReldbCrudRepository` 的自定义 SQL 方法先检查 `await this.ensureReady()`;构造函数启动自动建表不等于仓库就绪,服务 init 必须等待候选仓库的就绪入口再发布。PostgreSQL 自动提交的单条 `CREATE TABLE/INDEX IF NOT EXISTS` 仅对 `23505/pg_class_relname_nsp_index`(建表还包括 `pg_type_typname_nsp_index`)目录竞争,以及建表时 `42710/heap_create_with_catalog`、`42710/TypeCreate` 或 `42P07/heap_create_with_catalog` 的目录竞争重执行一次。DDL 和 SQL 入口均保留重试后的错误。事务、业务唯一约束及其他错误不自动重试。初始化连接探测仅对临时 DNS 错误 `EAI_AGAIN` 最多尝试三次,间隔 250/500 ms;不重放业务 SQL。
9
9
 
10
10
  ## 运行环境
11
11
 
@@ -444,7 +444,6 @@ if (!result.success) throw new Error(result.error.message)
444
444
  | `HaiReldbError.QUERY_FAILED` | `hai:reldb:002` | 查询或执行失败 |
445
445
  | `HaiReldbError.CONSTRAINT_VIOLATION` | `hai:reldb:003` | 约束违反 |
446
446
  | `HaiReldbError.TRANSACTION_FAILED` | `hai:reldb:004` | 事务失败 |
447
- | `HaiReldbError.MIGRATION_FAILED` | `hai:reldb:005` | 迁移失败 |
448
447
  | `HaiReldbError.RECORD_NOT_FOUND` | `hai:reldb:006` | 记录不存在 |
449
448
  | `HaiReldbError.DUPLICATE_ENTRY` | `hai:reldb:007` | 重复条目 |
450
449
  | `HaiReldbError.DEADLOCK` | `hai:reldb:008` | 死锁 |
@@ -500,7 +499,7 @@ const result = await reldb.tx.wrap(async (tx) => {
500
499
 
501
500
  ## 生产共享状态
502
501
 
503
- 应用自己的表迁移使用 `reldb.schemaColumns(table, sql?)` 读取真实列,使用 `reldb.migrateSchema(module, steps, options?)` 执行版本步骤;两者属于已初始化实例,不另传 reldb 句柄。`dryRun: true` 不写账本,失败不推进版本;MySQL DDL 必须可重入。框架表由各模块迁移入口维护,应用不要直接修改。
502
+ `reldb.schemaColumns(table, sql?)` 只读查询实际列名。传入当前事务的 SQL 操作句柄,可在同一事务中检查表结构。框架模块初始化时校验各自的表结构,业务表由应用管理。
504
503
 
505
504
  生产仅使用 PostgreSQL/MySQL;SQLite(含磁盘文件)只用于开发/明确测试,不能作为跨主机共享状态。 NODE_ENV 或 HAI_CORE_ENV 为 production 时在初始化成功前检查,只有 HAI_E2E=1/HAI_E2E_MOCK=1 明确测试豁免。不要将租约当作最终写入条件,外部未知效果须按稳定业务键核对。
506
505
 
@@ -175,7 +175,7 @@ await scheduler.init({
175
175
 
176
176
  可信服务端用 `execution.listLogFailures({ limit, offset })` 监控 pending(范围与 listUnknown 相同),用 `execution.repairLog(occurrenceId)` 从共享 journal 幂等补写;可跨节点、重启及并发调用。写入已提交但回执丢失时通过固定主键和完整内容核对去重。补写返回 `LOG_PERSIST_FAILED`(032)时继续保留 pending,并输出安全告警;全部数据库不可用且终态未提交时仍按 unknown 核对外部效果,不能假定存在可恢复结果。补写与日志保留均不调用业务 Hook。保留策略失败仅告警,不撤销已保存日志。`onTaskFinish` 是本地业务完成通知,其 unconfirmed 状态不是持久化确认;以 trigger 返回值及 execution.get 的 logPersistence 为准。
177
177
 
178
- 领取前竞争/跳过的 interrupted 仅为观测日志,没有可补写的终态;其写入未确认时返回 unconfirmed。JSON 大载荷保存完整结果和全部重试记录,避免 MySQL 的 255 字符截断;初始化会自动执行版本化迁移,归档并复制旧日志;升级前先 dry-run、备份并停止旧写入,按模块 README 核对迁移影响。关闭会等待在途补写,先关闭 scheduler 再关闭数据库。
178
+ 领取前竞争/跳过的 interrupted 仅为观测日志,没有可补写的终态;其写入未确认时返回 unconfirmed。JSON 大载荷保存完整结果和全部重试记录,避免 MySQL 的 255 字符截断;`scheduler.init()` 创建并校验任务、执行及日志表,结构不符时返回初始化失败。关闭会等待在途补写,先关闭 scheduler 再关闭数据库。
179
179
 
180
180
  ```ts
181
181
  const result = await scheduler.trigger('cleanup', { idempotencyKey: 'cleanup-2026-10-23' })
@@ -35,7 +35,7 @@ transport 仅支持 v2:SM2 发送方签名、独立密钥的 Encrypt-then-HMAC
35
35
 
36
36
  业务容量统一配置 transport.maxPlaintextBytes:UTF-8 JSON 明文字节,默认 1 MiB,有效整数范围 1 KiB~64 MiB,请求和响应共用。客户端从握手获取服务端预算,可选本地上限取较小值;resolveTransportBodyLimits 自动推导密文预算为两倍明文加 32 KiB。握手 JSON 16 KiB、公钥 4 KiB、认证头 16 KiB、路径 8 KiB、认证及防重放保持独立。原流超限/取消立即停止、取消并释放 reader;请求 413、响应返回加密的 500 容量错误,客户端识别 TransportBodyTooLargeError / hai:crypto:070。 通过 _serv.yml 的 transport.maxPlaintextBytes 或对应 HAI_*_TRANSPORT_MAXPLAINTEXTBYTES 配置并转发到服务端 transport;重建正文保留 signal 并删除旧长度/编码头。
37
37
 
38
- 错误提示与诊断分离:HTTP/UI 边界用 core.error.toPublic,仅公开 i18n 安全消息及 error.traceId;重新翻译后用 core.error.formatMessage 保留关联。ToastContainer 默认只显示可读说明,自动将编号移入排查信息图标,展开后可查看、复制并提供给客户支持或开发人员。前后端日志传完整 Error 和操作上下文,使用同一 requestId/traceId 并脱敏;禁止只写通用错误标题,也不能把 cause/ext/SQL/绑定值直接返回用户。数据库日志保留安全的驱动错误码、消息和堆栈。
38
+ Procedure 业务失败按公开错误中的归一化 HTTP 状态分类。4xx 以 `debug` 记录错误码和追踪编号,5xx 或未捕获异常由服务端以 `error` 保留脱敏诊断。对外提示由 `core.error.toPublic` 生成。日志字段与跨层关联按 [日志与错误诊断](../hai-app-create/logging.md)。
39
39
 
40
40
  ## 按需参考
41
41
 
@@ -297,7 +297,7 @@ transport:
297
297
 
298
298
  认证协议仅支持 v2:独立随机 SM4-CBC 密钥和 HMAC-SM3 密钥由 SM2 封装,先验签、再验证 MAC,最后解密 CBC。请求由客户端私钥签名,响应由所选服务端版本签名。认证字段包括 version、direction、serverKeyId、clientId、128 位随机 requestId(兼 nonce)、issuedAt、HTTP method、pathname + 原始 search 的 SM3 pathHash,以及响应 status。请求默认有效期为 5 分钟,客户端时间最多可领先服务器 30 秒。服务端可用 `maxRequestAgeSeconds`(1~600)和 `maxFutureSkewSeconds`(0~300)调整,单位为整数秒。共享 registry 原子消费 (clientId, requestId),nonce 保留到 issuedAt + 11 分钟,覆盖最长可配窗口及节点时钟差,存储故障拒绝请求。Redis 必须保留有效 nonce,使用 noeviction/可靠持久化策略;各节点时钟须同步。此能力防止同一传输消息重放,业务重试仍需自己的幂等键。
299
299
 
300
- 在 `_serv.yml` 的 `transport` 块配置时间窗口,将字段传给服务端 transport 装配。完成旧节点升级后等待 12 分钟,再把有效期调到 300 秒以上。校时提示与 `TransportTimeError.serverTime` 见 [Crypto 参考](../hai-crypto/reference.md)。
300
+ 在 `_serv.yml` 的 `transport` 块配置时间窗口,将字段传给服务端 transport 装配。校时提示与 `TransportTimeError.serverTime` 见 [Crypto 参考](../hai-crypto/reference.md)。
301
301
 
302
302
  空 POST 也发送空明文的认证封装;GET/HEAD 将封装放在 X-Hai-Transport 头,204/304/HEAD 等无正文响应也使用同名头承载认证封装。其它请求/响应在 JSON 正文承载封装并带 X-Encrypted: true。客户端必须关联原请求上下文和 HTTP status,缺标记、旧格式或认证失败一律 reject;明文接口由 Serv/Kit 路径规则 `encryption: disabled` 或宿主 `excludePaths` 显式允许;调用方同步选择普通请求,API Client/Kit 包装器使用自己的 `excludePaths`。CORS 须允许并暴露 X-Hai-Transport。握手公钥的真实性依赖 TLS,不替代 IAM 业务授权。
303
303
 
@@ -391,7 +391,7 @@ await apiClient.init({
391
391
 
392
392
  > 不要导入或暴露子目录内部 transport 工厂;公共装配点只有 `serv.createApp({ transport: { crypto, serverKeyRing, keyStore } })`。
393
393
 
394
- 启用 transport 必须显式注入 `serverKeyRing` 与 `keyStore`;多节点使用相同受管 ring 和共享 Redis/数据库 registry,仅共享客户端公钥不足以跨节点解密。通过根入口 `parseTransportServerKeyRing(process.env.HAI_CRYPTO_TRANSPORT_SERVERKEYRING)` 解析并检查 HaiResult,私钥不放 `_serv.yml`、PUBLIC_/VITE_、日志或响应。请求带协商 serverKeyId,未知/撤销 ID 拒绝。轮换先分发新旧 ring,再切 activeKeyId 并滚动重建;删除旧版本后客户端须 destroy 并重协商,不自动重放非幂等业务。默认 YAML maxClients 已删除;开发/测试显式 `createInMemoryKeyStore(capacity)`。无需 sticky session,详见 hai-crypto 的密钥轮换说明。
394
+ 启用 transport 必须显式注入 `serverKeyRing` 与 `keyStore`;多节点使用相同受管 ring 和共享 Redis/数据库 registry,仅共享客户端公钥不足以跨节点解密。通过根入口 `parseTransportServerKeyRing(process.env.HAI_CRYPTO_TRANSPORT_SERVERKEYRING)` 解析并检查 HaiResult,私钥不放 `_serv.yml`、PUBLIC_/VITE_、日志或响应。请求带协商 serverKeyId,未知/撤销 ID 拒绝。轮换先分发新旧 ring,再切 activeKeyId 并滚动重建;删除旧版本后客户端须 destroy 并重协商,不自动重放非幂等业务。开发和测试显式 `createInMemoryKeyStore(capacity)`。无需 sticky session,详见 hai-crypto 的密钥轮换说明。
395
395
 
396
396
  **上下文工厂优先级**(`context.session` 填充来源):
397
397
 
@@ -25,6 +25,7 @@ description: "实现本地/S3 文件与目录操作、流式读写、checksum
25
25
  5. 批量删除核对逐项进度,S3 每批最多 1000 项;HTTP 200 不能代替成功判断。unknown 结果先核对业务状态,避免重删并发新对象;dir.delete 不保证隔离并发写入或清除 S3 历史版本。
26
26
  6. 自建 Compose 的桶路径由 Web Nginx 或 SSR/API gateway 直达 storage,下载/Range 不经过 Serv,存储端口和控制台不公开。publicEndpoint 可含入口前缀,Nginx 用原始 request_uri 去前缀且保留编码、Host、签名查询,外层代理不能再剥离;入口可在网站目录内,拒绝 API/资源/健康冲突。新增网关、变更桶/公开地址需全量基线,增量及回滚保持原配置。外部 S3 不生成本地路由,Local 不开放目录。验证大文件、Range、过期/篡改/匿名拒绝、根/前缀路径和增量代理 DNS 刷新;签名 URL 不进入日志或截图。
27
27
  7. 同源对象可能包含不可信 HTML;默认代理返回 CSP sandbox/default-src none、nosniff、no-referrer、private/no-store,不用于执行网站脚本。外部 S3/CDN 须配置等价策略。自建 bucket/region 为空时由部署补 hai/us-east-1,不能误写成 Storage Schema 默认值。
28
+ 8. 写操作默认以 `debug` 记录,业务操作失败返回原错误并记录 `warn`,初始化、连接及关闭失败记录 `error`。正常日志由 Core 级别过滤。调用方按 [日志与错误诊断](../hai-app-create/logging.md) 保留原因和关联编号。
28
29
 
29
30
  ## 按需参考
30
31
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## 运行环境
6
6
 
7
- Local 的 key 路径拒绝文件符号链接和目录 junction;每个路径段都保留 `.meta.json` / `.upload.tmp` 后缀及 `.hai-storage-meta` 目录,不区分大小写。先在该内部目录准备文件身份对应的代际元数据(含显式空默认值),再原子发布内容;准备失败不改内容,发布后的历史记录清理失败只记录诊断,不回滚其他写入。代际记录是唯一格式,不读取旧 `<key>.meta.json`;缺少当前记录时明确失败,旧数据须离线迁移或重新 `file.put()`。备份与迁移包含内容和内部记录,不混用旧程序写入。copy 默认继承源元数据;S3 copy 接收原始 key,内部逐段编码 Unicode、空格和 URL 分隔字符。浏览器根入口仅导出 Schema、类型和客户端辅助能力。
7
+ Local 的 key 路径拒绝文件符号链接和目录 junction;每个路径段都保留 `.meta.json` / `.upload.tmp` 后缀及 `.hai-storage-meta` 目录,不区分大小写。先在该内部目录准备文件身份对应的代际元数据(含显式空默认值),再原子发布内容;准备失败不改内容,发布后的历史记录清理失败只记录诊断,不回滚其他写入。读取需要有效的代际元数据,备份须同时保存内容和内部记录。copy 默认继承源元数据;S3 copy 接收原始 key,内部逐段编码 Unicode、空格和 URL 分隔字符。浏览器根入口仅导出 Schema、类型和客户端辅助能力。
8
8
 
9
9
  > ⚠️ **服务端模块**。`storage.file` / `storage.dir` / `storage.presign` 均在 Node.js 端使用。浏览器端通过预签名 URL 或 API 端点间接访问存储(见下方「浏览器端文件上传」)。
10
10
 
@@ -35,12 +35,14 @@ root: ./data/storage
35
35
  # createBucket: ${HAI_STORAGE_CREATEBUCKET:false}
36
36
  # forcePathStyle: false
37
37
  # prefix: "${HAI_STORAGE_PREFIX:}"
38
+ # multipart:
39
+ # partSizeBytes: ${HAI_STORAGE_MULTIPART_PARTSIZEBYTES:5242880}
40
+ # queueSize: ${HAI_STORAGE_MULTIPART_QUEUESIZE:2}
38
41
  # publicUrl: ''
39
42
  operationLog:
40
43
  read: false # file.get/head/exists, dir.list, presign.getUrl/publicUrl
41
- write: false # file.put/delete/deleteMany/copy, dir.delete, presign.putUrl
44
+ write: true # file.put/delete/deleteMany/copy, dir.delete, presign.putUrl
42
45
  maxLength: 1000
43
- level: debug # info | debug | trace
44
46
  ```
45
47
 
46
48
  约定环境变量优先于 YAML,例如 `HAI_STORAGE_ROOT`、
@@ -52,7 +54,15 @@ MinIO、RustFS 使用同一个 S3 Provider:配置 `type: s3`、S3 API `endpoin
52
54
 
53
55
  使用 hai-deploy 的默认自建 S3 配置时,可通过 `hai.json` 的 `deploy.container.s3Engine`(`HAI_DEPLOY_CONTAINER_S3ENGINE`,`rustfs | minio`)选择实现,默认 RustFS。运行环境启用 `HAI_STORAGE_CREATEBUCKET=true` 后由应用初始化 storage 时建桶;部署不再生成独立初始化服务或脚本。自定义外部 S3 默认不建桶,可按凭据权限显式启用。
54
56
 
55
- `operationLog` 在 Local/S3 Provider 的真实 file/dir/presign 操作处输出日志,不要在 `storage-main.ts` 或调用方重复包装。文件内容不会写入日志,上传数据只记录字节长度;`maxLength` 用于截断序列化后的参数,`level` 默认 `debug`。
57
+ `operationLog` 默认记录写操作,读操作需显式开启。操作记录固定为 `debug`,由 `HAI_CORE_LOGGING_LEVEL` 过滤。业务失败返回原错误并记录一次 `warn`,初始化、连接和关闭失败为 `error`。`maxLength` 限制安全摘要的字符数,0 省略摘要。签名直传助手在浏览器记录失败,日志不包含对象键、签名 URL 或文件内容。
58
+
59
+ S3 服务端流式上传使用 `multipart.partSizeBytes` 和 `multipart.queueSize`,默认 5 MiB 和 2 片。大小为 5 MiB 至 5 GiB 的整数,队列大小为正整数。上述两个环境变量在初始化时覆盖相应字段。每个活跃上传的主要缓冲预算约为片大小乘以并发数。
60
+
61
+ S3 流式上传用 `error.cause` 获取首次失败,`error.ext?.s3Operation` 查看失败的 S3 操作。若分片清理也失败,从 `error.ext?.cleanupError` 获取清理错误。告警包含可取得的服务端请求编号。
62
+
63
+ 若 `UploadPart` 返回成功但缺少 `ETag`,用 `MissingETag`、分片编号及请求编号定位存储端和网关的响应。
64
+
65
+ 处理 `storage.file.put()` 失败时用 `error.code` 分支,底层原因可用时从 `error.cause` 读取。`ifNoneMatch: '*'` 的目标冲突为 `ALREADY_EXISTS`,文件或输入流读取失败为 `UPLOAD_FAILED`,取消保留 `AbortSignal.reason`。告警记录原因摘要、底层错误码及可用的 HTTP 状态。
56
66
 
57
67
  ### 2. 初始化与关闭
58
68
 
@@ -58,7 +58,7 @@ operationLog:
58
58
  约定环境变量优先于 YAML,例如 `HAI_VECDB_URL`、
59
59
  `HAI_VECDB_APIKEY`、`HAI_VECDB_OPERATIONLOG_LEVEL`。
60
60
 
61
- `operationLog` 在集合/向量操作进入真实 Provider 前输出日志,不要在 `vecdb-main.ts` 或调用方重复包装。`maxLength` 用于截断序列化后的向量、文档和过滤条件,`level` 默认 `debug`。
61
+ `operationLog` 在集合/向量操作进入真实 Provider 前输出日志。日志包含操作类型以及条数、维度、topK、是否有过滤条件等摘要。`maxLength` 限制摘要字符数,0 省略摘要。`level` 默认 `debug`。
62
62
 
63
63
  ### 2. 初始化与关闭
64
64