@h-ai/cli 1.0.0-beta.18 → 1.0.0-beta.19
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.
- package/README.en.md +4 -0
- package/README.ja.md +4 -0
- package/README.md +4 -0
- package/dist/{chunk-6YZBC5MO.js → chunk-2ZL5ORQ2.js} +85 -25
- package/dist/chunk-2ZL5ORQ2.js.map +1 -0
- package/dist/{chunk-7NVRYYHN.js → chunk-L53P43B2.js} +129 -31
- package/dist/chunk-L53P43B2.js.map +1 -0
- package/dist/cli-config-templates-LWMD2I6V.js +5 -0
- package/dist/{cli-config-templates-QG5HOYR5.js.map → cli-config-templates-LWMD2I6V.js.map} +1 -1
- package/dist/{cli-skill-templates-W4I6ZKYW.js → cli-skill-templates-D6S2OQ6X.js} +3 -3
- package/dist/{cli-skill-templates-W4I6ZKYW.js.map → cli-skill-templates-D6S2OQ6X.js.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2747 -671
- package/dist/index.js.map +1 -1
- package/dist/metafile-esm.json +1 -1
- package/package.json +22 -22
- package/templates/apps/admin/src/routes/+layout.svelte.hbs +16 -10
- package/templates/apps/admin/src/routes/+page.svelte.hbs +4 -4
- package/templates/apps/admin/src/routes/admin/+layout.svelte.hbs +17 -7
- package/templates/apps/admin/src/routes/admin/+page.svelte.hbs +26 -6
- package/templates/apps/admin/src/routes/admin/settings/+page.svelte.hbs +2 -2
- package/templates/apps/api/apps/{{projectName}}-contract/src/app-schemas.ts.hbs +6 -1
- package/templates/apps/api/apps/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +13 -5
- package/templates/apps/api/apps/{{projectName}}-contract/tests/contract.test.ts.hbs +13 -5
- package/templates/apps/api/apps/{{projectName}}-contract/tsup.config.ts.hbs +3 -1
- package/templates/apps/api/apps/{{projectName}}-serv/src/app.ts.hbs +71 -32
- package/templates/apps/api/apps/{{projectName}}-serv/src/build-metadata.ts.hbs +0 -1
- package/templates/apps/api/apps/{{projectName}}-serv/src/lib/server/init.ts.hbs +131 -54
- package/templates/apps/api/apps/{{projectName}}-serv/src/server/procedures/index.ts.hbs +39 -13
- package/templates/apps/api/apps/{{projectName}}-serv/tests/service.test.ts.hbs +78 -31
- package/templates/apps/api/apps/{{projectName}}-serv/tsup.config.ts.hbs +3 -1
- package/templates/apps/api/apps/{{projectName}}-serv/vitest.config.ts.hbs +3 -1
- package/templates/apps/api/e2e/api-serv.spec.ts.hbs +20 -3
- package/templates/apps/api/e2e/capture-evidence.ts.hbs +4 -1
- package/templates/apps/api/eslint.config.js.hbs +3 -1
- package/templates/apps/api/images/serv.Dockerfile.hbs +3 -4
- package/templates/apps/api/playwright.config.ts.hbs +23 -19
- package/templates/apps/api/pnpm-workspace.yaml.hbs +27 -16
- package/templates/apps/fullstack/apps/{{projectName}}-app/capacitor.config.ts.hbs +1 -3
- package/templates/apps/fullstack/apps/{{projectName}}-app/eslint.config.js.hbs +10 -2
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/App.svelte.hbs +10 -2
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/build-metadata.ts.hbs +0 -1
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/lib/capacitor.ts.hbs +0 -1
- package/templates/apps/fullstack/apps/{{projectName}}-app/svelte.config.js.hbs +4 -1
- package/templates/apps/fullstack/apps/{{projectName}}-app/vite.config.ts.hbs +16 -4
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/App.svelte.hbs +8 -2
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/build-metadata.ts.hbs +0 -1
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/svelte.config.js.hbs +4 -1
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/vite.config.ts.hbs +16 -4
- package/templates/apps/fullstack/apps/{{projectName}}-web/eslint.config.js.hbs +10 -2
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/build-metadata.ts.hbs +0 -1
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/main.ts.hbs +0 -2
- package/templates/apps/fullstack/apps/{{projectName}}-web/svelte.config.js.hbs +4 -1
- package/templates/apps/fullstack/apps/{{projectName}}-web/vite.config.ts.hbs +19 -5
- package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +111 -26
- package/templates/apps/fullstack/e2e/session-close.spec.ts.hbs +19 -5
- package/templates/apps/fullstack/eslint.config.js.hbs +3 -1
- package/templates/apps/fullstack/images/serv.Dockerfile.hbs +3 -4
- package/templates/apps/fullstack/images/web.Dockerfile.hbs +0 -2
- package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-contract.ts.hbs +114 -23
- package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-schemas.ts.hbs +57 -11
- package/templates/apps/fullstack/packages/{{projectName}}-contract/tsup.config.ts.hbs +3 -1
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/app-server.ts.hbs +65 -30
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/build-metadata.ts.hbs +0 -1
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/admin-service.ts.hbs +69 -21
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/business-settings.ts.hbs +21 -5
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/admin-procedures.ts.hbs +63 -11
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/app-procedures.ts.hbs +6 -1
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/index.ts.hbs +3 -1
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/runtime.ts.hbs +139 -49
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/security-roles.ts.hbs +43 -12
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/app-server.test.ts.hbs +139 -28
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/runtime.test.ts.hbs +33 -10
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/security.test.ts.hbs +141 -25
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tsup.config.ts.hbs +6 -2
- package/templates/apps/fullstack/packages/{{projectName}}-serv/vitest.config.ts.hbs +3 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/api-client.ts.hbs +9 -2
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/feedback-client.ts.hbs +0 -3
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/sensitive-actions.svelte.ts.hbs +15 -3
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AppShell.svelte.hbs +33 -7
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/FeedbackEntry.svelte.hbs +16 -2
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/audit.svelte.hbs +104 -13
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/feedback.svelte.hbs +37 -7
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/roles.svelte.hbs +9 -3
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/settings.svelte.hbs +25 -3
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/users.svelte.hbs +133 -19
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/security/role-label.ts.hbs +14 -2
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/guide-store.ts.hbs +66 -34
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/management-store.svelte.ts.hbs +132 -30
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/theme-store.svelte.ts.hbs +8 -2
- package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/api-client.test.ts.hbs +23 -5
- package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/management-store.test.ts.hbs +143 -21
- package/templates/apps/fullstack/packages/{{projectName}}-shared/vitest.config.ts.hbs +7 -2
- package/templates/apps/fullstack/playwright.config.ts.hbs +9 -3
- package/templates/apps/fullstack/pnpm-workspace.yaml.hbs +30 -15
- package/templates/apps/h5/src/routes/+layout.svelte.hbs +57 -21
- package/templates/apps/h5/src/routes/+page.svelte.hbs +2 -2
- package/templates/apps/h5/src/routes/discover/+page.svelte.hbs +2 -2
- package/templates/apps/h5/src/routes/profile/+page.svelte.hbs +2 -2
- package/templates/apps/mobile-app/src/App.svelte.hbs +17 -5
- package/templates/apps/mobile-app/src/lib/api.ts.hbs +14 -3
- package/templates/apps/mobile-app/src/lib/app-config.ts.hbs +8 -1
- package/templates/apps/mobile-app/src/lib/pages/home.svelte.hbs +6 -2
- package/templates/apps/mobile-app/src/lib/pages/tasks.svelte.hbs +5 -1
- package/templates/apps/website/scripts/static-website.mjs.hbs +16 -3
- package/templates/apps/website/src/routes/+layout.svelte.hbs +44 -23
- package/templates/apps/website/src/routes/+page.svelte.hbs +4 -4
- package/templates/apps/website/src/routes/about/+page.svelte.hbs +2 -2
- package/templates/apps/website/src/routes/contact/+page.svelte.hbs +2 -2
- package/templates/apps/website/src/routes/services/+page.svelte.hbs +20 -5
- package/templates/base/e2e/app.spec.ts.hbs +49 -16
- package/templates/base/eslint-rules.js +44 -25
- package/templates/base/eslint.config.js.hbs +3 -1
- package/templates/base/images/web.Dockerfile.hbs +3 -4
- package/templates/base/package.json.hbs +5 -4
- package/templates/base/patches/daisyui-5.7.50.patch +8 -0
- package/templates/base/patches/deepmerge-4.3.1.patch +51 -0
- package/templates/base/playwright.config.ts +3 -1
- package/templates/base/pnpm-workspace.yaml.hbs +33 -16
- package/templates/base/src/app.d.ts.hbs +1 -1
- package/templates/base/src/hooks.server.ts.hbs +36 -27
- package/templates/base/src/lib/build-metadata.ts.hbs +0 -1
- package/templates/base/src/lib/server/init.ts.hbs +124 -51
- package/templates/base/src/lib/server/kit-config.ts.hbs +7 -4
- package/templates/base/src/routes/+layout.server.ts.hbs +2 -2
- package/templates/base/svelte.config.js.hbs +10 -100
- package/templates/base/tests/scaffold.test.ts.hbs +12 -3
- package/templates/base/tsconfig.json.hbs +7 -4
- package/templates/base/vite.config.ts.hbs +108 -14
- package/templates/base/vitest.config.ts.hbs +6 -2
- package/templates/features/ai/routes/api/chat/+server.ts +3 -1
- package/templates/features/iam/routes-admin/(auth)/auth/forgot-password/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-admin/(auth)/auth/login/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-admin/(auth)/auth/register/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-admin/(auth)/auth/reset-password/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-h5/auth/forgot-password/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-h5/auth/login/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-h5/auth/register/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-h5/auth/reset-password/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-website/auth/forgot-password/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-website/auth/login/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-website/auth/register/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-website/auth/reset-password/+page.svelte.hbs +3 -3
- package/templates/features/payment/routes/api/v1/payment/create/+server.ts +11 -2
- package/templates/shared/browser-check/startup.js +32 -6
- package/templates/shared/browser-startup.spec.ts +3 -1
- package/templates/shared/build-metadata.ts +18 -4
- package/templates/shared/e2e-env.ts +22 -6
- package/templates/shared/native-name.mjs +9 -2
- package/templates/shared/public-base-path.mjs +17 -4
- package/templates/shared/run-e2e.mjs +40 -9
- package/templates/shared/run-node.mjs +15 -4
- package/templates/shared/run-tauri.mjs +37 -8
- package/templates/shared/vite-runtime-config.ts +9 -3
- package/templates/skills/AGENTS.md +10 -73
- package/templates/skills/bridges/admin/AGENTS.md +9 -65
- package/templates/skills/bridges/api/AGENTS.md +8 -59
- package/templates/skills/bridges/fullstack/AGENTS.md.hbs +9 -54
- package/templates/skills/bridges/h5/AGENTS.md +8 -63
- package/templates/skills/bridges/mobile-app/AGENTS.md +8 -62
- package/templates/skills/bridges/website/AGENTS.md +8 -63
- package/templates/skills/hai-ai/acp.md +2 -0
- package/templates/skills/hai-ai/guide.md +17 -6
- package/templates/skills/hai-ai/reference.md +21 -12
- package/templates/skills/hai-api-client/reference.md +1 -1
- package/templates/skills/hai-app-create/development.md +3 -1
- package/templates/skills/hai-app-create/project.md +33 -0
- package/templates/skills/hai-app-create/reference.md +8 -8
- package/templates/skills/hai-app-tests/reference.md +1 -1
- package/templates/skills/hai-build/SKILL.md +2 -2
- package/templates/skills/hai-build/paths.md +1 -1
- package/templates/skills/hai-build/reference.md +11 -7
- package/templates/skills/hai-capacitor/reference.md +2 -0
- package/templates/skills/hai-ci/SKILL.md +1 -0
- package/templates/skills/hai-core/reference.md +3 -0
- package/templates/skills/hai-crypto/reference.md +2 -0
- package/templates/skills/hai-deploy/SKILL.md +7 -1
- package/templates/skills/hai-deploy/middleware.md +3 -1
- package/templates/skills/hai-framework-sync/sync.md +2 -0
- package/templates/skills/hai-kit/reference.md +16 -4
- package/templates/skills/hai-payment/reference.md +2 -0
- package/templates/skills/hai-reach/SKILL.md +2 -1
- package/templates/skills/hai-reach/reference.md +1 -1
- package/templates/skills/hai-reldb/SKILL.md +1 -1
- package/templates/skills/hai-reldb/reference.md +4 -0
- package/templates/skills/hai-serv/reference.md +12 -2
- package/templates/skills/hai-storage/reference.md +12 -3
- package/templates/skills/hai-ui/SKILL.md +3 -2
- package/templates/skills/hai-ui/guide.md +1 -1
- package/templates/skills/hai-ui/reference.md +23 -35
- package/templates/skills/hai-vecdb/reference.md +1 -1
- package/dist/chunk-6YZBC5MO.js.map +0 -1
- package/dist/chunk-7NVRYYHN.js.map +0 -1
- package/dist/cli-config-templates-QG5HOYR5.js +0 -5
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# hai-core — 详细用法
|
|
2
2
|
|
|
3
|
+
HTTP/UI 边界只对明确的有效 4xx 状态公开业务提示;错误缺少 `httpStatus` 或状态非法时按 500 返回安全提示。手写业务错误须提供完整错误定义或显式状态,不能依赖缺省状态展示原文。
|
|
4
|
+
|
|
3
5
|
从 [SKILL.md](SKILL.md) 选择主题后读取对应小节。代码片段展示 API 用法;省略的业务变量、schema、依赖与 return 上下文需由应用补齐。
|
|
4
6
|
|
|
5
7
|
> `@h-ai/core` 是 hai-framework 的基础模块,提供配置管理、结构化日志、国际化、HaiResult 错误模型、Zod 校验错误本地化与模块生命周期工具。所有其他模块均依赖 core。
|
|
@@ -448,6 +450,7 @@ Core 模块定义了两组标准错误码:
|
|
|
448
450
|
| `HaiCommonError.VALIDATION_ERROR` | `hai:common:200` | 校验失败 |
|
|
449
451
|
| `HaiCommonError.INVALID_REQUEST` | `hai:common:201` | 请求无效 |
|
|
450
452
|
| `HaiCommonError.PARAMETER_MISSING` | `hai:common:202` | 参数缺失 |
|
|
453
|
+
| `HaiCommonError.RATE_LIMIT_EXCEEDED` | `hai:common:203` | 请求频率超限(HTTP 429) |
|
|
451
454
|
| `HaiCommonError.NOT_FOUND` | `hai:common:300` | 资源不存在 |
|
|
452
455
|
| `HaiCommonError.ALREADY_EXISTS` | `hai:common:301` | 资源已存在 |
|
|
453
456
|
| `HaiCommonError.CONFLICT` | `hai:common:302` | 冲突 |
|
|
@@ -47,12 +47,18 @@ description: "构建并发布或交付已有镜像:完整离线包、按服务
|
|
|
47
47
|
|
|
48
48
|
所有容器模板共用deploy.provider.expose.https,省略时HTTP。files指定domain、certificateFile、privateKeyFile(相对工程根),校验域名/期限/密钥并复制到私有包。letsencrypt指定domain、email、acceptTerms:true,HTTP hostPort必须80,公网DNS、80入站及CA出站须可达。固定版本官方Certbot申请并每12小时检查续期,Nginx自动重载。仅单域名HTTP-01,无DNS/通配符。HTTPS默认443、redirectHttp默认true;--yes复用配置。启停或改模式/域名/端口/本地证书需全量。状态在服务器https/acme及按域名隔离的https/certificates目录,需备份;续期失败保留旧证书并须及时处理,隔离目标用已有证书。打包/plan不申请证书。
|
|
49
49
|
|
|
50
|
+
files 只接收末级无软链接或硬链接的普通 PEM 文件,每份最多 1 MiB,父目录仍须可信。Certbot `live/` 软链需安全复制为受控目录中的普通文件,或使用框架 `letsencrypt` 模式。
|
|
51
|
+
|
|
50
52
|
默认.tar.gz,显式--output release.tar为未压缩,README仅外层。镜像从解包目录导入,release只留配置/恢复状态;成功后清理本次incoming,失败保留诊断。中间件归档按镜像内容ID缓存且复用前验摘要。
|
|
51
53
|
|
|
52
|
-
Serv 生产登录的刷新 Cookie 默认带 `Secure`。受控内网或 VPN 的 HTTP 部署可在所选 `.env.prod.local` 配置 `HAI_SERV_REFRESH_COOKIE_SECURE=false` 和实际 `HAI_SERV_CORS_ORIGIN
|
|
54
|
+
Serv 生产登录的刷新 Cookie 默认带 `Secure`。受控内网或 VPN 的 HTTP 部署可在所选 `.env.prod.local` 配置 `HAI_SERV_REFRESH_COOKIE_SECURE=false` 和实际 `HAI_SERV_CORS_ORIGIN`,再重新部署后端。仅在工程使用 Serv 且已交付 `hai-serv` 时读取该技能 `reference.md` 的“Cookie 规格”;Kit 应用按自己的 `hai-kit` 认证契约处理,不加载未交付的 Serv 技能。
|
|
53
55
|
|
|
54
56
|
## 后端运行配置重载
|
|
55
57
|
|
|
58
|
+
SvelteKit SSR 的 HTTP/HTTPS 部署均通过独立 `gateway`,SSR 容器不映射公开端口。网关覆盖 Host 与标准转发头;Compose 固定 adapter-node 的协议/主机/客户端地址信任,业务 `.env.runtime` 不能覆盖。adapter-node 6 不再读取运行期 `ORIGIN`,旧直接公开 SSR 的部署必须重新生成全量交付包;源应用默认不固定 `paths.origin`,保持镜像跨环境复用。
|
|
59
|
+
|
|
60
|
+
外层 TLS 终止时,独立 gateway 只接受 `trustedEdgeProxies` 白名单真实对端的单值 `http` / `https` 协议;外层必须覆盖 Host/XFF/协议头。未授权来源或组合值使用 gateway 自身协议,不直接透传外部 Forwarded、主机/端口转发值。
|
|
61
|
+
|
|
56
62
|
交付 README 仅列初始账号变量名及所选环境文件或 `process.env` 来源,不打印密码。Fullstack 初始密码在创建工程时生成,部署带入已有值;已有账号不因环境变量变更重置密码或恢复旧职责,自定义应用以实际引导逻辑为准。
|
|
57
63
|
|
|
58
64
|
独立读取的核心环境、职责账号初始密码和传输密钥环保留进程语义,不能仅按前缀判定已失效;Node 启动参数及私有代理标记由部署装配提供,不在运行文件重复保留无效项。
|
|
@@ -94,6 +94,8 @@ AI 使用 MySQL 的首次建表需 CREATE 与 INDEX 权限,节点可并发初
|
|
|
94
94
|
|
|
95
95
|
以下是自定义向导的连接字段;完整可用项、枚举与范围仍以项目 `.env.example` 和公开 Schema 为准。变量前缀为 `HAI_DB`、`HAI_CACHE`、`HAI_STORAGE`、`HAI_VECDB`、`HAI_IAM_LDAP`;Reach 使用实际索引 `HAI_REACH_PROVIDERS_<index>`。camelCase 不拆词,例如 `bindPassword` → `BINDPASSWORD`。
|
|
96
96
|
|
|
97
|
+
HTTP API 的全部自定义请求头整体写入私有环境文件,不能按头名猜测秘密。迁移已有 dotenv 项会处理行首空格/Tab、export 与多行引号,并移除同模式公共文件中的旧值;操作后仍核对私有文件与忽略规则,不在日志中输出值。
|
|
98
|
+
|
|
97
99
|
| 后端 | 连接字段 |
|
|
98
100
|
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
99
101
|
| SQLite | database(文件路径或 `:memory:`) |
|
|
@@ -128,7 +130,7 @@ manifest.json 的 partial 与 selectedServices、apply 脚本共同记录部署
|
|
|
128
130
|
|
|
129
131
|
生成 web.conf 时从目标环境解析后的 _serv.yml 读取 transport.maxPlaintextBytes,调用 crypto.resolveTransportBodyLimits 推导 client_max_body_size;默认 2129920 字节,8 MiB 明文对应 16809984 字节。请求/响应 buffering 关闭,认证头缓冲固定。SvelteKit 从 _kit.yml 自动推导 adapter-node BODY_SIZE_LIMIT。app 增量包携带代理配置;容量变化时复用现有 Web 镜像重建代理并纳入失败恢复,容量不变保留 Web 容器。容量变化须选择 app;路由/端口/其他代理策略改变仍要求全量部署。应用继续独立限制业务文件、解压和行数。自管代理调用 resolveTransportBodyLimits 获取同一预算。
|
|
130
132
|
|
|
131
|
-
完全离线构建另需基础镜像、Linux 依赖缓存、pnpm 和匹配驱动/Node ABI/架构/libc 的原生预编译包。联网准备可选 --image-source / --npm-source 的 official、cn、custom;npm 参数随 --build 使用。代理通过 --proxy-mode 及 --proxy-url / --proxy-bypass 配置,--no-http-proxy 等价 none;镜像拉取端还需配置引擎代理。具体契约见 [下载源与代理](../hai-build/reference.md#下载源与代理)
|
|
133
|
+
完全离线构建另需基础镜像、Linux 依赖缓存、pnpm 和匹配驱动/Node ABI/架构/libc 的原生预编译包。联网准备可选 --image-source / --npm-source 的 official、cn、custom;npm 参数随 --build 使用。代理通过 --proxy-mode 及 --proxy-url / --proxy-bypass 配置,--no-http-proxy 等价 none;镜像拉取端还需配置引擎代理。具体契约见 [下载源与代理](../hai-build/reference.md#下载源与代理)。SQLite 13 的原生二进制随 npm 包交付,不再需要独立镜像参数;deploy 不下载编译环境。生产 HTTPS、CORS、证书、DNS 另行准备。实际断网验收登录、刷新、重启和数据持久化。
|
|
132
134
|
|
|
133
135
|
## 命令输出
|
|
134
136
|
|
|
@@ -18,6 +18,8 @@ hai-framework 是通用能力和 skill 模板的源头;应用仓库消费这
|
|
|
18
18
|
|
|
19
19
|
## 同步完整技能与入口
|
|
20
20
|
|
|
21
|
+
依赖补丁必须与引用它的 pnpm 配置一起复制并验证安装。当前 DaisyUI 5.7.50 的 join 补丁是 CSS 构建兼容修复,**不是安全漏洞补丁**:它以零特异性的 `:where(:scope)` 避免优化器丢弃聚焦/悬停层级,依据 [官方问题](https://github.com/tailwindlabs/tailwindcss/issues/20668) 与[上游修复 PR](https://github.com/tailwindlabs/tailwindcss/pull/20671)。升级后验证实际 compile/optimize 与界面再决定移除;不要靠关闭优化或隐藏警告处理。纯 API 没有 UI/Svelte 构建依赖,不注册未使用的 DaisyUI/deepmerge 补丁;不能用安装豁免掩盖模板依赖差异。
|
|
22
|
+
|
|
21
23
|
通过 CLI 补齐缺失文件时,先按 [CLI 安装与命令](../hai-app-create/development.md#cli-安装与命令) 安装所需精确版本的 `@h-ai/cli` 并检查 `hai --version` / `hai --help`,再从应用根运行 `hai init`。临时使用 CLI 可隔离安装到临时目录;不为读取模板要求全局安装或改变系统级工具。
|
|
22
24
|
|
|
23
25
|
`hai init` 只补缺失内容,即使 `--force` 也不覆盖已有 AI 规则和 skills,不能用它代替旧版本规则合并。未发布模板修正从明确本地来源同步,不能假定已发布 CLI 已包含。
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
# hai-kit 参考
|
|
2
2
|
|
|
3
|
+
HTTP/UI 边界只对明确的有效 4xx 状态公开业务提示;错误缺少 `httpStatus` 或状态非法时按 500 返回安全提示。手写业务错误须提供完整错误定义或显式状态,不能依赖缺省状态展示原文。
|
|
4
|
+
|
|
3
5
|
> `@h-ai/kit` 只负责 SvelteKit 集成:`handle` hook、guard、response、validate、client、auth、crud、A2A。公共跨端 HTTP API 契约统一使用 `@h-ai/api-contract` + `@h-ai/serv`,不要在 kit 中定义业务 API contract。
|
|
4
6
|
|
|
7
|
+
命名空间公开类型为 `KitFunctions`(服务端)与 `BrowserKitFunctions`(浏览器)。浏览器条件入口仅暴露 client、crud、页面 Token 与默认语言操作,不含服务端认证、Hook 或限流。服务端认证 Cookie 的最小写入依赖为根入口的 `AuthCookieWriter`。运行时仍使用 `kit.xx`,导出方法或命名空间的声明不需要内部 helper 或私有构建路径。
|
|
8
|
+
|
|
5
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/可靠持久化策略;各节点时钟须同步。此能力防止同一传输消息重放,业务重试仍需自己的幂等键。
|
|
6
10
|
|
|
7
11
|
在 `_kit.yml` 的 `transport` 块配置时间窗口,将字段传给服务端 transport 装配。完成旧节点升级后等待 12 分钟,再把有效期调到 300 秒以上。校时提示与 `TransportTimeError.serverTime` 见 [Crypto 参考](../hai-crypto/reference.md)。`kit.client.createAuthActions()` 将已认证校时错误转为 `HaiResult`,供 AuthPanel 展示。
|
|
@@ -10,10 +14,14 @@
|
|
|
10
14
|
|
|
11
15
|
## 使用步骤
|
|
12
16
|
|
|
17
|
+
错误响应与 Serv 共用 `HaiCommonError`:未认证用 `UNAUTHORIZED.code`、无权限用 `FORBIDDEN.code`、限流用 `RATE_LIMIT_EXCEEDED.code`(429);不要匹配旧的无命名空间字符串。`fromError/fromResult` 保留安全字段校验、`httpStatus` 和追踪编号,内部异常只记录日志。前端使用已本地化的安全消息,排查按 `traceId` 关联服务端原因。
|
|
18
|
+
|
|
19
|
+
`kit.response.validationError(errors)` 同样经 `fromError` 过滤,响应 `error.cause` 只含本地化 `field/message`;不回显 rejectedValue、SQL 或其他字段,不再读取 `details.errors`。
|
|
20
|
+
|
|
13
21
|
### 1. 请求管道
|
|
14
22
|
|
|
15
23
|
```ts
|
|
16
|
-
import type { Handle } from '@sveltejs/kit'
|
|
24
|
+
import type { Handle } from '@sveltejs/kit/hooks'
|
|
17
25
|
import { cache } from '@h-ai/cache'
|
|
18
26
|
import { kit } from '@h-ai/kit'
|
|
19
27
|
|
|
@@ -34,6 +42,8 @@ export const handle: Handle = haiHandle
|
|
|
34
42
|
|
|
35
43
|
### 2. SvelteKit API endpoint
|
|
36
44
|
|
|
45
|
+
业务失败用 `kit.response.fromResult/fromError`,保留安全字段错误、显式 `publicExt` 和 HTTP 状态,内部异常仅进入关联日志;不要在业务 endpoint 手工拼接原始异常。
|
|
46
|
+
|
|
37
47
|
```ts
|
|
38
48
|
import { kit } from '@h-ai/kit'
|
|
39
49
|
import { z } from 'zod'
|
|
@@ -91,12 +101,14 @@ export const handle = kit.createHandle({
|
|
|
91
101
|
})
|
|
92
102
|
```
|
|
93
103
|
|
|
94
|
-
需要保护会话 Cookie 时配置 `crypto.encryptedCookies`,并通过 `crypto.cookieEncryptionKey` 或 `HAI_KIT_COOKIE_KEY`
|
|
104
|
+
需要保护会话 Cookie 时配置 `crypto.encryptedCookies`,并通过 `crypto.cookieEncryptionKey` 或 `HAI_KIT_COOKIE_KEY` 提供密钥。密钥必须为 32 位十六进制。Cookie 采用分离子密钥的 SM4-CBC/HMAC-SHA256,先验证版本、名称、IV 与密文,再解密;旧版无认证 Cookie 升级后失效,需重新登录。缺少或非法密钥会在 `createHandle()` 时失败;加解密错误不会回退到明文 Cookie。
|
|
105
|
+
|
|
106
|
+
不再使用无运行入口的旧 Crypto Helpers 或其 `CryptoServiceLike`、`EncryptedCookieConfig`、`CryptoCsrfConfig`、`WebhookVerifyConfig` 类型;这些已删除。Cookie 通过上述 `kit.createHandle` 配置保护,其他加密能力使用 `@h-ai/crypto` 真实公开 API。
|
|
95
107
|
|
|
96
108
|
```svelte
|
|
97
109
|
<!-- src/routes/+layout.svelte -->
|
|
98
110
|
<script lang='ts'>
|
|
99
|
-
import { browser } from '$app/
|
|
111
|
+
import { browser } from '$app/env'
|
|
100
112
|
import type { LayoutData } from './$types'
|
|
101
113
|
import { crypto } from '@h-ai/crypto'
|
|
102
114
|
import { kit } from '@h-ai/kit'
|
|
@@ -164,7 +176,7 @@ export function load() {
|
|
|
164
176
|
`resolveKitConfig()` 同时解析 `server`(host/port)与 `transport`;host/port 优先级为 `HOST` / `PORT` 环境变量 > `_kit.yml` 的 `server` > 默认 `127.0.0.1:3000`(与 `@h-ai/serv` 同构)。
|
|
165
177
|
`_kit.yml` 在服务端读取,可包含 access 和 trustedProxies;layout data 只投影公开 transport,不通过 ?raw 导入完整文件到浏览器,也不放密钥。如自定义 `keyExchangePath`,浏览器端必须同步映射为 `keyExchangeUrl`。请求策略按[共享约定](../hai-core/request-access.md)装配与验证。
|
|
166
178
|
|
|
167
|
-
|
|
179
|
+
子目录部署在 Vite 的 sveltekit 配置设置 `paths.relative: false`,从 `$app/paths` 用 `resolve('/').replace(/\/$/, '')` 取构建挂载目录 `base`,服务端 `crypto.transport.basePath` 与客户端 `installBrowserTransport(config, { crypto, basePath: base })` 同步;独立 client 的 `transport.basePath` 也用该值。默认空字符串为根目录,不能仅调整资源地址后把登录成功当作加密验证。交换/排除/容量路径保持完整请求路径,验证原始请求带加密标记、缺协议被拒绝、排除接口正常且不影响相邻目录。
|
|
168
180
|
|
|
169
181
|
## 核心 API
|
|
170
182
|
|
|
@@ -19,7 +19,8 @@ API 空 2xx 表示受理成功;非空 JSON 回执上限 64 KiB。redirect 默
|
|
|
19
19
|
|
|
20
20
|
## 使用路径
|
|
21
21
|
|
|
22
|
-
-
|
|
22
|
+
- 使用模板先初始化 reldb,再初始化 Reach;非空配置模板的仓库/保存失败会使 init 返回 CONFIG_ERROR 并关闭候选 Provider。单次发送从同一模板快照渲染内容和选择默认 Provider,显式 provider 仍可覆盖;直接发送须提供 provider。启用 DND delay 也必须先初始化 reldb 并确保队列表可用;成功时 `deferred: true` 与 `queueId` 表示可靠入队,尚未投递;缺库、断连或插入失败须按 HaiResult 失败处理。即时投递与排队状态须区分。
|
|
23
|
+
- API 自定义请求头整体视为私密数据,部署时写私有环境文件;`reach.config` 隐藏全部头值,不能只依靠 Authorization/token 等名称识别秘密。
|
|
23
24
|
- 验证模板替换和错误分支时使用隔离测试收件人;真实通知须在用户授权范围内。
|
|
24
25
|
- 阿里云短信的 `gateway` 通过 POST 转发已签名查询,可配置请求头和正文;服务端 `reach.init` 可按 Provider 名注入 `gatewayHooks`。受信内网 HTTP 须显式启用,转发日志应脱敏查询串。
|
|
25
26
|
- 缓存锁只减少扫描,按实际执行逐条领取并在途续租。API 只有接收端真正具备原子持久去重时才能声明 idempotent=true,全部请求固定用 queueId 作为 Idempotency-Key;旧节点迟到请求也必须去重。SMTP/短信/默认 API 的在途失败或过期转 unknown,禁止自动重发;可信服务端用 queue.get/resolveUnknown 在人工隔离旧 worker、核对外部记录后裁定 sent/discarded。
|
|
@@ -14,7 +14,7 @@ Provider 名称必须唯一,重名在连接前返回 CONFIG_ERROR。close 等
|
|
|
14
14
|
|
|
15
15
|
| 模块 | 用途 | 是否必需 | 初始化要求 |
|
|
16
16
|
| --- | --- | --- | --- |
|
|
17
|
-
| `@h-ai/reldb` | 数据库(发送日志与模板持久化) | DND delay
|
|
17
|
+
| `@h-ai/reldb` | 数据库(发送日志与模板持久化) | 模板与 DND delay 必需;其他即时发送可选 | 先初始化;非空配置模板保存或必需表准备失败则 reach.init 返回 CONFIG_ERROR 并关闭候选 Provider |
|
|
18
18
|
| `@h-ai/cache` | 缓存(DND delay 策略分布式锁) | 可选 | 已初始化时自动启用分布式锁 |
|
|
19
19
|
|
|
20
20
|
## 适用场景
|
|
@@ -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
|
|
44
|
+
框架模块维护自己的版本迁移,应用不直接 ALTER 框架表。`reldb.schemaColumns(table, sql?)` 只读真实列;`reldb.migrateSchema(module, steps, { dryRun: true })` 不创建账本。生产先停旧写入并备份 DB/共享会话缓存;SQLite/PostgreSQL 事务,MySQL DDL 隐式提交须可重入,失败不推进版本且重试检查真实结构。回退恢复兼容 DB 与代码,不只换二进制。模块 migrateIam/migrateReach/migrateScheduler 分别预检,初始化执行受支持步骤。
|
|
@@ -341,6 +341,8 @@ class UserRepository extends BaseReldbCrudRepository<User> {
|
|
|
341
341
|
|
|
342
342
|
### 事务 — `reldb.tx`
|
|
343
343
|
|
|
344
|
+
一个事务只允许一个结束操作。`commit()` 或 `rollback()` 开始后,新查询、重复提交和并发回滚立即返回 TRANSACTION_FAILED;连接只归还一次。调用方仍须等待首次结束结果,不能把并发结束当作故障恢复。
|
|
345
|
+
|
|
344
346
|
```typescript
|
|
345
347
|
// 方式1:wrap(自动 commit/rollback)
|
|
346
348
|
const result = await reldb.tx.wrap(async (tx) => {
|
|
@@ -498,6 +500,8 @@ const result = await reldb.tx.wrap(async (tx) => {
|
|
|
498
500
|
|
|
499
501
|
## 生产共享状态
|
|
500
502
|
|
|
503
|
+
应用自己的表迁移使用 `reldb.schemaColumns(table, sql?)` 读取真实列,使用 `reldb.migrateSchema(module, steps, options?)` 执行版本步骤;两者属于已初始化实例,不另传 reldb 句柄。`dryRun: true` 不写账本,失败不推进版本;MySQL DDL 必须可重入。框架表由各模块迁移入口维护,应用不要直接修改。
|
|
504
|
+
|
|
501
505
|
生产仅使用 PostgreSQL/MySQL;SQLite(含磁盘文件)只用于开发/明确测试,不能作为跨主机共享状态。 NODE_ENV 或 HAI_CORE_ENV 为 production 时在初始化成功前检查,只有 HAI_E2E=1/HAI_E2E_MOCK=1 明确测试豁免。不要将租约当作最终写入条件,外部未知效果须按稳定业务键核对。
|
|
502
506
|
|
|
503
507
|
MySQL 空 url(含空环境变量占位)按未配置处理,使用分字段;非空仍严格校验。
|
|
@@ -4,12 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
> `@h-ai/serv` 是 hai-framework 的 API Service 运行时,对外暴露最小 HTTP App 抽象,将 `@h-ai/api-contract` 的领域 contract 挂载成跨端可访问的 HTTP API;Hono 是内部实现细节,应用代码不要直接 import 或暴露 Hono。
|
|
6
6
|
|
|
7
|
+
命名空间的公开类型是根入口的 `ServFunctions`。上下文、工厂与泛型 contract 实现器均通过 `serv.xx` 使用;应用可导出方法或整个命名空间并生成声明,不要为类型推导改用私有构建路径或导入内部函数。
|
|
8
|
+
|
|
7
9
|
## 运行环境
|
|
8
10
|
|
|
9
11
|
> ⚠️ **服务端模块(Node.js 或满足同等 Node API 依赖的宿主)。** 浏览器端通过 `@h-ai/api-client` 调用由本模块暴露的 HTTP API。
|
|
10
12
|
|
|
11
13
|
> 生命周期说明:`@h-ai/serv` 是无状态 HTTP App 装配器,不提供 `init()` / `close()`;依赖模块(iam/storage/ai/crypto 等)由应用先初始化,并在 `serv.listen(..., { onClose })` 中反向释放。`serv.createApp()` 的启动期配置错误会 fail-fast 抛出。
|
|
12
14
|
|
|
15
|
+
返回的监听句柄允许立即 `close()` 取消未完成绑定,重复关闭复用结果;真实监听错误仍会拒绝。调用 `handle.close()` 不代替宿主的业务模块清理。
|
|
16
|
+
|
|
13
17
|
## 适用场景
|
|
14
18
|
|
|
15
19
|
- 将 `@h-ai/api-contract` contract 装配成最小 HTTP App 抽象
|
|
@@ -25,6 +29,8 @@
|
|
|
25
29
|
- 公开只读文件通过 `serv.storageAssets(...)` 统一处理安全 key、MIME 白名单、GET/HEAD、ETag 与缓存头
|
|
26
30
|
- 为 Audio WebSocket 配置一次性 ticket 校验、IAM/模型/配额授权与并发释放钩子
|
|
27
31
|
|
|
32
|
+
权限遵循 IAM/Kit 的精确值、全局 `*` 与冒号前缀 `users:*` 规则;声明多个权限时全部满足。返回的 listener `close()` 幂等并移除信号监听器,先关闭 Audio WebSocket,1 秒后终止未配合的音频连接;业务模块由宿主反序释放。
|
|
33
|
+
|
|
28
34
|
## 使用步骤
|
|
29
35
|
|
|
30
36
|
### 1. 安装依赖
|
|
@@ -63,6 +69,7 @@ const procedures = {
|
|
|
63
69
|
const app = serv.createApp({
|
|
64
70
|
contract,
|
|
65
71
|
procedures,
|
|
72
|
+
iam,
|
|
66
73
|
http: {
|
|
67
74
|
apiPrefix: '/api/v1',
|
|
68
75
|
openapi: { path: '/openapi.json' },
|
|
@@ -98,6 +105,7 @@ const app = serv.createApp({
|
|
|
98
105
|
openapi: security.exposeApiDocs ? servConfig.http.openapi : false,
|
|
99
106
|
docs: security.exposeApiDocs ? servConfig.http.docs : false,
|
|
100
107
|
},
|
|
108
|
+
iam,
|
|
101
109
|
refreshCookie: { secure: security.secureRefreshCookie },
|
|
102
110
|
middlewares: [{
|
|
103
111
|
middleware: serv.cors({
|
|
@@ -552,7 +560,7 @@ HTTP 审计、限流、CORS、租户头校验等跨 route 能力继续放在
|
|
|
552
560
|
|
|
553
561
|
HTTP middleware、自定义 Response、refresh-cookie、OpenAPI 入口权限和 transport 协议错误分别按自身响应契约处理,可返回真实 HTTP 4xx/5xx。`@h-ai/api-client` 在真实 HTTP 401 或 HTTP 200 的有效失败 HaiResult(`success=false`、字符串 `error.code/message`、`error.httpStatus=401`)后自动刷新,成功后只重试一次;内置登录、注册和配置的刷新路径除外,403/500 不刷新。启用 transport 时刷新和重试复用加密链路,不能手写明文刷新请求。
|
|
554
562
|
|
|
555
|
-
SvelteKit 的 `kit.response.fromError`
|
|
563
|
+
SvelteKit 的 `kit.response.fromError` 根据归一化后的 `error.httpStatus` 生成 HTTP Response;`kit.response.fromResult` 优先使用显式错误码映射,再使用错误自身的 `httpStatus`,缺失或非法状态统一为 500。这些响应转换规则不能套用到 serv 普通 procedure。
|
|
556
564
|
|
|
557
565
|
按三层处理:
|
|
558
566
|
|
|
@@ -581,7 +589,7 @@ const procedures = serv
|
|
|
581
589
|
.build()
|
|
582
590
|
```
|
|
583
591
|
|
|
584
|
-
>
|
|
592
|
+
> 下游 4xx 消息经脱敏后公开,5xx 和缺失或非法状态使用安全内部错误与 traceId,完整原因只记录服务端日志。`HaiError` 不携带 `messageKey/params`,领域消息的请求级 i18n 仍在创建消息的模块/feature 中接收 locale 后完成。自动审计使用同一归一化状态,失败不能按非法原始状态记为成功。
|
|
585
593
|
|
|
586
594
|
### `serv.parseRequestContext` — 默认 Context 解析器
|
|
587
595
|
|
|
@@ -737,6 +745,8 @@ route 实现器内置以下错误:
|
|
|
737
745
|
原生客户端匹配 `nativeTokenTransport.isRequest` 后,登录/注册/刷新响应保留轮换后的
|
|
738
746
|
`refreshToken`,刷新请求从 `{ refreshToken }` body 读取,且不读写浏览器 Cookie。
|
|
739
747
|
|
|
748
|
+
刷新失败经过同一公开错误投影,并记录英文关联日志;仅 401 认证失效会清除浏览器刷新 Cookie,限流、5xx 和缺失或非法状态保留凭据供稍后重试。未捕获的刷新异常返回安全的 HTTP 500 JSON,不公开内部 cause/ext。
|
|
749
|
+
|
|
740
750
|
若同时启用 `transport: { crypto, serverKeyRing, keyStore }`,`/auth/refresh` 也必须走加密链路;cookie-only 刷新请求允许空 body,服务端不要把 `Request.body === null` 误判为需要解密的请求体。
|
|
741
751
|
|
|
742
752
|
### 配置
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## 运行环境
|
|
6
6
|
|
|
7
|
-
Local 的 key 路径拒绝文件符号链接和目录 junction
|
|
7
|
+
Local 的 key 路径拒绝文件符号链接和目录 junction;每个路径段都保留 `.meta.json` / `.upload.tmp` 后缀及 `.hai-storage-meta` 目录,不区分大小写。先在该内部目录准备文件身份对应的代际元数据(含显式空默认值),再原子发布内容;准备失败不改内容,发布后的历史记录清理失败只记录诊断,不回滚其他写入。代际记录是唯一格式,不读取旧 `<key>.meta.json`;缺少当前记录时明确失败,旧数据须离线迁移或重新 `file.put()`。备份与迁移包含内容和内部记录,不混用旧程序写入。copy 默认继承源元数据;S3 copy 接收原始 key,内部逐段编码 Unicode、空格和 URL 分隔字符。浏览器根入口仅导出 Schema、类型和客户端辅助能力。
|
|
8
8
|
|
|
9
9
|
> ⚠️ **服务端模块**。`storage.file` / `storage.dir` / `storage.presign` 均在 Node.js 端使用。浏览器端通过预签名 URL 或 API 端点间接访问存储(见下方「浏览器端文件上传」)。
|
|
10
10
|
|
|
@@ -198,10 +198,19 @@ if (!result.success) return result
|
|
|
198
198
|
|
|
199
199
|
`checksum.generate(data, options?)` / `checksum.verify(data, expected, options?)` 默认 SHA-256、小写 hex,可选 sha384/sha512/sha1/md5、base64 编码与 signal;流仅消费一次,读取失败返回 HaiResult 错误,不匹配返回 false。MD5/SHA-1 不作安全认证,ETag 和 multipart 复合 checksum 不当作完整文件摘要。浏览器不导入 Node checksum;离线增量摘要需使用适用的浏览器实现,不把 SubtleCrypto.digest 当流式 API。
|
|
200
200
|
|
|
201
|
-
###
|
|
201
|
+
### Serv / Fullstack 私有附件
|
|
202
|
+
|
|
203
|
+
Fullstack/API 项目先读取本工程已交付的 hai-serv/reference.md 中“扩展应用自有 contract + procedures”和“Feature Procedures”,结合 hai-api-contract、hai-api-client 扩展;保留其 contract/serv/shared 分层,不复制下方 SvelteKit 路由。
|
|
204
|
+
|
|
205
|
+
- 在 `packages/<name>-contract`(API 为 `apps/<name>-contract`)声明应用自己的附件 contract,在 serv 的 procedures 聚合入口挂载。当前生成的 Fullstack 客户端是共享 `managementApi`,需先将新领域纳入工程 contract;不能把文档中的默认 `apiClient.storage` 当作工程已经开放的接口。
|
|
206
|
+
- 自有 procedure 使用 `serv.implement(contract).context<ServContext>().route(...).auth().handle(...)`;owner 来自可信 `context.session.userId`,按 ID 操作还须查验业务记录归属、状态与租户。key 由服务端生成,列表也在服务端限定本人范围。
|
|
207
|
+
- 可复用 `createStorageProcedures({ storage, authorize })` 的已有签名/列表/元数据/删除操作,authorize 必须按可信 session 核对 operation 与全部 keys,拒绝空 prefix 与跨用户请求。只挂载实际需要的子路由,不能绕过应用附件记录、限额或审计;框架没有默认的 `attachments.*` 业务 API。
|
|
208
|
+
- FileUpload 注入应用 uploadHandler;S3 签名 URL 是短期访问凭据,不能当作持续会话授权。上传完成后仍验证大小、实际内容与对象状态;仍有效的 PUT URL 可以重写其目标,严格发布时使用 staging/final 对象隔离。需要 Local 或严格逐次鉴权的二进制流程时,通过 Serv 自有 middleware 接入 `storage.file.put/getStream`,显式认证并精确配置传输策略,不能把公开 `serv.storageAssets` 用于本人私有附件。
|
|
209
|
+
|
|
210
|
+
### 与 kit 集成(SvelteKit 文件上传 API)
|
|
202
211
|
|
|
203
212
|
```typescript
|
|
204
|
-
import { storage } from '
|
|
213
|
+
import { storage } from '#lib/server/init.js'
|
|
205
214
|
// src/routes/api/files/upload/+server.ts
|
|
206
215
|
import { kit } from '@h-ai/kit'
|
|
207
216
|
import { z } from 'zod'
|
|
@@ -42,9 +42,10 @@ Toast 支持 F8 聚焦/返回、Escape 关闭可关闭提示并恢复焦点;Mo
|
|
|
42
42
|
- 先检查组件导入、Tailwind @source 和主题 CSS,再选场景 → 组合 → 原子组件,缺能力才自定义。
|
|
43
43
|
- 管理列表和工作台随可用宽度展开;flex/grid 子项设 min-width: 0,表格在自身容器滚动。阅读页与登录表单按内容约束宽度。实际检查 390、1440、1920、2560、3840px,避免宽屏仍挤在中央窄列,手机出现整页横向滚动。
|
|
44
44
|
- 按安装版本的 exports 选择明确列出的 components barrel 入口(不开放任意内部文件);主题工具使用 `@h-ai/ui/theme`,避免仅为主题加载根入口的 AI/图表组件。禁止导入内部 src/dist;例如原子组件使用 `@h-ai/ui/components/primitives/index`。
|
|
45
|
-
-
|
|
45
|
+
- 先执行 `vitePreprocess()` 或其他样式/模板语言转换,再执行 `autoImportHaiUi()`;自动导入读取整份 Svelte AST,不接受未转换的 SCSS/Pug,直接 markup API 保持同步。
|
|
46
|
+
- 自动导入按语法树识别真实 import,保留字符串/注释、别名与已有运行时绑定;根入口 `@h-ai/ui` 的 type-only 组件按需提升。外部同名类型冲突会构建报错并列出文件/组件名,应为类型设置别名或以其他本地名显式导入组件,不重写业务类型引用。
|
|
46
47
|
- 应用只提供页面级文案;组件内部中英日文由 @h-ai/ui 维护。
|
|
47
|
-
- `UserProfile` 用 `avatarAccept` / `avatarHint`
|
|
48
|
+
- `UserProfile` 用 `avatarAccept` / `avatarHint` 对齐业务的头像格式与大小限制;文件最终校验和上传由业务回调完成。`onsubmit` 必须返回 boolean,只有 `true` 退出编辑,`false` 或异常保留草稿与重试入口。
|
|
48
49
|
- `BareInput type="file"` 通过 `onchange` 的 `currentTarget.files` 读取文件,不绑定文件路径 `value`;其他输入类型可 `bind:value`。
|
|
49
50
|
- AI 文本视为不可信;Markdown/Mermaid 预览与允许执行 HTML/JS 的预览有不同边界。
|
|
50
51
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<script lang='ts'>
|
|
11
11
|
import { createGuide, GuideHost } from '@h-ai/ui/guide'
|
|
12
12
|
import { createSvelteKitNavAdapter } from '@h-ai/kit/client'
|
|
13
|
-
import * as m from '
|
|
13
|
+
import * as m from '#lib/paraglide/messages.js'
|
|
14
14
|
|
|
15
15
|
const guide = createGuide({
|
|
16
16
|
nav: createSvelteKitNavAdapter(),
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# hai-ui — 详细用法
|
|
2
2
|
|
|
3
|
+
HTTP/UI 边界只对明确的有效 4xx 状态公开业务提示;错误缺少 `httpStatus` 或状态非法时按 500 返回安全提示。手写业务错误须提供完整错误定义或显式状态,不能依赖缺省状态展示原文。
|
|
4
|
+
|
|
3
5
|
从 [SKILL.md](SKILL.md) 选择主题后读取对应小节。代码片段展示 API 用法;省略的业务变量、schema、依赖与 return 上下文需由应用补齐。
|
|
4
6
|
|
|
5
7
|
> `@h-ai/ui` 是基于 Svelte 5 Runes 的多端 UI 组件库,采用 DaisyUI v5 + Tailwind CSS v4 + Bits UI v2,内置 15 个精选 DaisyUI 主题及 high-contrast 高对比、formal 直角商务、eye-care 暖绿护眼主题、内置中英日文 i18n、自动导入。内置 Shiki 代码高亮、Mermaid 图表渲染、Design Token 系统和 7 个移动端组件。
|
|
@@ -39,7 +41,7 @@
|
|
|
39
41
|
|
|
40
42
|
至少检查以下四项:
|
|
41
43
|
|
|
42
|
-
- `
|
|
44
|
+
- SvelteKit 3 在 `vite.config.*` 的 `sveltekit({...})` 中设置预处理;纯 Svelte/Vite 使用 `svelte.config.*`。两者都先执行 `vitePreprocess()` 或其他样式/模板语言转换,再执行 `autoImportHaiUi()`;后者按整份 Svelte AST 定位实例脚本,不直接接受转换前的 SCSS/Pug,直接 markup 调用保持同步。
|
|
43
45
|
- `vite.config.*`:`ssr.noExternal` 包含 `@h-ai/ui` 和 `@h-ai/kit`,`optimizeDeps.exclude` 包含 `bits-ui`。
|
|
44
46
|
- `app.css`:已导入 `global.css` / `theme.css`;移动端还要导入 `design-tokens.css` / `mobile.css`。
|
|
45
47
|
- Tailwind:已配置 `@source` 扫描 `@h-ai/ui/dist/**/*.{svelte,js,ts}`。
|
|
@@ -99,55 +101,39 @@ npm install -D tailwindcss @tailwindcss/vite daisyui
|
|
|
99
101
|
npm install -D @iconify/tailwind4 @iconify-json/tabler
|
|
100
102
|
```
|
|
101
103
|
|
|
102
|
-
Node adapter 使用 Crypto、Kit 或 IAM 时,还需将 `sm-crypto@0.5.
|
|
103
|
-
|
|
104
|
-
### 2. svelte.config.js
|
|
105
|
-
|
|
106
|
-
```js
|
|
107
|
-
import { autoImportHaiUi } from '@h-ai/ui/auto-import'
|
|
108
|
-
import adapter from '@sveltejs/adapter-node'
|
|
109
|
-
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
|
|
104
|
+
Node adapter 使用 Crypto、Kit 或 IAM 时,还需将 `sm-crypto@0.5.8` 作为直接生产依赖安装,保留 Node 原生模块解析。
|
|
110
105
|
|
|
111
|
-
|
|
112
|
-
const config = {
|
|
113
|
-
// autoImportHaiUi 必须在 vitePreprocess 之前
|
|
114
|
-
preprocess: [autoImportHaiUi(), vitePreprocess()],
|
|
115
|
-
compilerOptions: {
|
|
116
|
-
runes: true, // 强制 Svelte 5 Runes 模式
|
|
117
|
-
},
|
|
118
|
-
kit: {
|
|
119
|
-
adapter: adapter(),
|
|
120
|
-
alias: {
|
|
121
|
-
$components: './src/lib/components',
|
|
122
|
-
$stores: './src/lib/stores',
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
}
|
|
106
|
+
### 2. package.json 的应用导入
|
|
126
107
|
|
|
127
|
-
|
|
108
|
+
```json
|
|
109
|
+
{ "imports": { "#lib/*": "./src/lib/*" } }
|
|
128
110
|
```
|
|
129
111
|
|
|
130
112
|
### 3. vite.config.ts
|
|
131
113
|
|
|
114
|
+
SvelteKit 3 的预处理、编译器和适配器统一配置在 Vite 插件;纯 Svelte/Vite 工程保留自己的 svelte.config.js。
|
|
115
|
+
|
|
132
116
|
```ts
|
|
117
|
+
import { autoImportHaiUi } from '@h-ai/ui/auto-import'
|
|
118
|
+
import { haiOptimizeExclude, haiPrebundledDeps } from '@h-ai/ui/vite'
|
|
119
|
+
import adapter from '@sveltejs/adapter-node'
|
|
133
120
|
import { sveltekit } from '@sveltejs/kit/vite'
|
|
121
|
+
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
|
|
134
122
|
import tailwindcss from '@tailwindcss/vite'
|
|
135
123
|
import { defineConfig } from 'vite'
|
|
136
124
|
|
|
137
125
|
export default defineConfig({
|
|
138
126
|
plugins: [
|
|
139
|
-
sveltekit(
|
|
127
|
+
sveltekit({
|
|
128
|
+
preprocess: [vitePreprocess(), autoImportHaiUi()],
|
|
129
|
+
compilerOptions: { runes: true },
|
|
130
|
+
adapter: adapter(),
|
|
131
|
+
paths: { relative: false },
|
|
132
|
+
}),
|
|
140
133
|
tailwindcss(),
|
|
141
134
|
],
|
|
142
|
-
optimizeDeps: {
|
|
143
|
-
|
|
144
|
-
exclude: ['bits-ui'],
|
|
145
|
-
},
|
|
146
|
-
ssr: {
|
|
147
|
-
// @h-ai 包为 ESM + Svelte 组件,需 Vite 在 SSR 时处理
|
|
148
|
-
noExternal: ['@h-ai/ui', '@h-ai/kit'],
|
|
149
|
-
external: ['@h-ai/core', 'sm-crypto'],
|
|
150
|
-
},
|
|
135
|
+
optimizeDeps: { exclude: [...haiOptimizeExclude], include: [...haiPrebundledDeps] },
|
|
136
|
+
ssr: { noExternal: ['@h-ai/ui', '@h-ai/kit'], external: ['@h-ai/core', 'sm-crypto'] },
|
|
151
137
|
})
|
|
152
138
|
```
|
|
153
139
|
|
|
@@ -367,6 +353,8 @@ const p = usePlatform()
|
|
|
367
353
|
| `RegisterForm` | `fields`, `minPasswordLength`, `errors` | 注册表单 |
|
|
368
354
|
| `UserProfile` | `user`, `editable`, `fields`, `avatarAccept`, `avatarHint` | 用户资料,选择器和提示对齐业务校验;最终验证和上传仍由回调负责 |
|
|
369
355
|
|
|
356
|
+
`UserProfile.onsubmit` 必须返回 `true` / `false` 表示保存成功 / 失败;仅成功退出编辑,失败保留编辑器与草稿。宿主在失败时更新错误提示并返回 `false`,不要把失败转换成正常关闭。
|
|
357
|
+
|
|
370
358
|
#### 错误页 / 设置场景组件
|
|
371
359
|
|
|
372
360
|
| 组件 | Props 要点 | 说明 |
|
|
@@ -187,7 +187,7 @@ Chroma 直连 `url` 仅支持 HTTP(S) 根端点,优先于 `host/port`;URL
|
|
|
187
187
|
|
|
188
188
|
直连初始化总截止为 5 秒,本地服务拉起使用 `startupTimeout`;超时中止候选 HTTP 请求。成功清除初始化 timer,不限制后续业务请求。
|
|
189
189
|
|
|
190
|
-
Qdrant
|
|
190
|
+
Qdrant 使用原生 HTTP 固定 REST 端点,无额外 SDK 依赖;超时 30 秒覆盖完整响应体,响应超过 16 MiB 明确失败。仅支持未命名向量字段的 cosine/euclidean/dot;外部 named-vector/Manhattan 集合的 info/写入/搜索返回 CONFIG_ERROR,不猜测维度或 metric。Chroma 使用 `chromadb 3.5.0` 的真实类型及 metadata/filter 校验,非法输入返回操作错误,不丢弃过滤;content 可省略。各后端的 null 和复杂元数据语义不承诺统一。
|
|
191
191
|
|
|
192
192
|
**VectorDocument**:
|
|
193
193
|
|