@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
|
@@ -2,35 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
> Capacitor Mobile App 项目 AI 编程助手入口。优先结合 `README.md`、`.agents/skills/`、`src/`、`messages/*` 与移动端测试工作。
|
|
4
4
|
|
|
5
|
-
## 需求与模板
|
|
6
|
-
|
|
7
|
-
- 业务行为以用户当前明确要求及其指定的需求/设计文档为准。本文件、README、skills、示例、生成代码及其测试中的模板默认行为是起点,不是不可变的业务约束;角色代码、权限模型、页面流程、字段、限额、存储方式与架构均可按实际需求调整。
|
|
8
|
-
- 需求与模板不同,审查时记录为模板适配项,不据此判定需求错误或阻塞审查,也不要求用户额外授权“覆盖模板”;实施时在已有授权范围内修改或移除冲突逻辑,并同步 contract、鉴权、数据迁移、界面、配置、测试、文档及本文件中的过期规则。
|
|
9
|
-
- 未说明的行为可参考现有实现并注明假设,不能升级为强制需求。只有业务要求自身矛盾、与已确认项目决策的优先级不明,或存在真实技术/安全障碍时才提出具体问题;已明确的规则不重复要求选择。
|
|
10
|
-
- 业务规则与技术契约分别判断:可用 API 以当前安装版本的公开类型为准;输入校验、服务端授权、资源隔离和密钥保护仍须落实。需求涉及替换技术方案时说明影响并同步迁移,不能用保留模板默认值代替解决问题。
|
|
11
5
|
|
|
12
6
|
## 行为契约
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
需求/设计文档审查或从文档生成代码时,读取 [hai-spec-review](.agents/skills/hai-spec-review/SKILL.md),严格确认完备性、歧义、技术正确性与命名一致性;影响行为的问题未解决前不判定文档可生成。普通小改动不重审无关文档。
|
|
17
|
-
|
|
18
|
-
升级 hai-framework 到最新/指定版本、比较版本差异或同步框架 skills 时,先读 [框架升级与同步 Skill](.agents/skills/hai-framework-sync/SKILL.md),执行版本发现、差异分析、用户选择/阻塞处理、迁移与验证;仅要求比较时不修改应用。
|
|
19
|
-
|
|
20
|
-
根据文档规划、实施、继续、返修或按已提交文档变更同步实现时,读取 [hai-spec-implement](.agents/skills/hai-spec-implement/SKILL.md):维护 docs 清单与任务记录,比较已验收与目标文档 Git 快照,更新原任务或新建任务,每项独立分支 TDD、验证并本地合并;全部差异与整体验收通过后才推进基线。返修复用原任务与分支。仅规划不实施,指定任务先核验依赖。
|
|
21
|
-
|
|
22
|
-
普通新增、修改、修复任务开始前,先读 [应用开发 Skill](.agents/skills/hai-app-create/SKILL.md) 和 [开发规范与框架能力路由](.agents/skills/hai-app-create/development.md);再按任务读取模块 Skill 及其相邻参考文件。架构/构建、审查、测试分别读取 hai-build、hai-app-review、hai-app-tests,不加载整个 skill 树。
|
|
8
|
+
先读 [项目共同规则](.agents/skills/hai-app-create/project.md),按当前任务读取下面的入口;不要加载整个 skill 树。业务以用户当前明确要求及指定文档为准,模板行为是可调整的起点。
|
|
23
9
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
先读 README、package.json、相关实现/测试和所需 .agents/skills;不要加载整个 skill 树。新增抽象前确认复用路径与真实需求;保留用户改动。跨文件任务简述影响和验证计划,无须固定规模标签或重复问卷。
|
|
31
|
-
|
|
32
|
-
- 直接影响:哪些页面、store、原生桥接、messages、README、测试和打包脚本会变。
|
|
33
|
-
- 间接影响:哪些 Android/iOS 权限、API 调用方、构建/打包流程和共享组件需要同步。
|
|
10
|
+
| 任务 | 入口 |
|
|
11
|
+
| --- | --- |
|
|
12
|
+
| 新增、修改、修复应用 | [hai-app-create](.agents/skills/hai-app-create/SKILL.md);配置、注释与能力选择按需查 [development.md](.agents/skills/hai-app-create/development.md) |
|
|
13
|
+
| 需求/设计文档审查 | [hai-spec-review](.agents/skills/hai-spec-review/SKILL.md) |
|
|
14
|
+
| 文档驱动规划、实施或返修 | [hai-spec-implement](.agents/skills/hai-spec-implement/SKILL.md) |
|
|
15
|
+
| 代码审查 / 测试 / 构建 / 升级 | 按任务读取同名 hai-app-review / hai-app-tests / hai-build / hai-framework-sync;模块按实际依赖选择 |
|
|
34
16
|
|
|
35
17
|
## 项目概述
|
|
36
18
|
|
|
@@ -58,43 +40,7 @@ pnpm cap:build:android:debug
|
|
|
58
40
|
pnpm cap:build:android:release
|
|
59
41
|
```
|
|
60
42
|
|
|
61
|
-
## 工作流程
|
|
62
|
-
|
|
63
|
-
1. 先搜索现有页面、stores、原生桥接、API client、messages 和测试。
|
|
64
|
-
2. 修改原生能力、权限、登录态或 API 流程时,同步 README、i18n 和测试。
|
|
65
|
-
3. 按改动范围验证,修复本次引入的失败;已有问题与未运行项明确报告。
|
|
66
|
-
|
|
67
|
-
## 代码注释与示例
|
|
68
|
-
|
|
69
|
-
- 尽可能补充有信息量的中文 JSDoc:所有 export 的函数/类/方法、核心算法与业务流程、所有数据库表/列、接口/type/schema 及其字段都必须说明用途、单位、约束和关联关系。核心逻辑解释决策原因、边界、权限与失败路径,不逐行复述代码。
|
|
70
|
-
- 函数按实际契约写 @param、@returns,仅确实抛错时写 @throws;异步、HaiResult 与事务失败行为须说明。类型/表结构说明字段含义、可空性、默认值、主外键和唯一约束。
|
|
71
|
-
- 上述函数和结构的 JSDoc 均提供可理解的 @example:函数给调用及结果判断,结构给合法数据,表给典型行或查询示例。省略上下文要标明,不使用真实凭据。示例随实现同步,不能只堆叠没有信息量的注释。
|
|
72
|
-
- 调用及结构示例见 [.agents/skills/hai-app-create/development.md](.agents/skills/hai-app-create/development.md) 的 JSDoc 注释一节。
|
|
73
|
-
|
|
74
|
-
## 质量门禁
|
|
75
|
-
|
|
76
|
-
先核对 package.json,按 [分轮验证与集中修复](.agents/skills/hai-app-tests/validation.md) 收集适用检查与日志,再归并修复、复测失败及受影响项;普通失败不中断独立检查,真实前置阻塞才暂停依赖项。文档检查引用,UI/路由变更加 E2E,未运行项说明原因。
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
pnpm typecheck
|
|
80
|
-
pnpm lint
|
|
81
|
-
pnpm build
|
|
82
|
-
pnpm test
|
|
83
|
-
pnpm test:e2e
|
|
84
|
-
```
|
|
85
43
|
|
|
86
44
|
## 完成条件
|
|
87
45
|
|
|
88
|
-
-
|
|
89
|
-
- 若改动影响打包 / 原生权限 / 设备能力,README 与脚本说明必须同步更新。
|
|
90
|
-
- 最终回复说明门禁状态、已更新移动端流程 / 文档与未完成项。
|
|
91
|
-
|
|
92
|
-
## 优先 Skills
|
|
93
|
-
|
|
94
|
-
- `hai-build`、`hai-app-review`、`hai-app-tests`
|
|
95
|
-
- `hai-ui`、`hai-api-client`、`hai-capacitor`
|
|
96
|
-
- 其它 `hai-*` 模块按需读取
|
|
97
|
-
|
|
98
|
-
前端页面先按 [hai-ui-design](.agents/skills/hai-ui-design/SKILL.md) 确定任务、布局、状态与组件映射,使用 [hai-ui](.agents/skills/hai-ui/SKILL.md) 实现,再由 [hai-ui-review](.agents/skills/hai-ui-review/SKILL.md) 检查真实页面。窄范围修改复用已有设计;按实际语言/主题/尺寸验证。
|
|
99
|
-
|
|
100
|
-
工作流技能按 hai-领域-动作 命名,能力使用类沿用领域名。需求、验收、发现与当前版本证据按 [工作交接契约](.agents/skills/hai-spec-implement/handoff.md) 传递,沿既有清单恢复任务。
|
|
46
|
+
按实际 package scripts 和 [分轮验证](.agents/skills/hai-app-tests/validation.md) 选择受影响范围,依次收集 typecheck → lint → build(需要时)→ test → 相关 E2E;例如 `pnpm typecheck`。普通失败不中断独立检查,汇总后集中修复并定向复测。报告实际结果、文档/调用方同步与未验证原因;不能用静态、mock 或 Web 结果代替真实业务、外部服务或原生验证。
|
|
@@ -2,35 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
> 企业官网项目 AI 编程助手入口。优先结合 `README.md`、`.agents/skills/`、`src/routes/`、`messages/*` 与测试工作。
|
|
4
4
|
|
|
5
|
-
## 需求与模板
|
|
6
|
-
|
|
7
|
-
- 业务行为以用户当前明确要求及其指定的需求/设计文档为准。本文件、README、skills、示例、生成代码及其测试中的模板默认行为是起点,不是不可变的业务约束;角色代码、权限模型、页面流程、字段、限额、存储方式与架构均可按实际需求调整。
|
|
8
|
-
- 需求与模板不同,审查时记录为模板适配项,不据此判定需求错误或阻塞审查,也不要求用户额外授权“覆盖模板”;实施时在已有授权范围内修改或移除冲突逻辑,并同步 contract、鉴权、数据迁移、界面、配置、测试、文档及本文件中的过期规则。
|
|
9
|
-
- 未说明的行为可参考现有实现并注明假设,不能升级为强制需求。只有业务要求自身矛盾、与已确认项目决策的优先级不明,或存在真实技术/安全障碍时才提出具体问题;已明确的规则不重复要求选择。
|
|
10
|
-
- 业务规则与技术契约分别判断:可用 API 以当前安装版本的公开类型为准;输入校验、服务端授权、资源隔离和密钥保护仍须落实。需求涉及替换技术方案时说明影响并同步迁移,不能用保留模板默认值代替解决问题。
|
|
11
5
|
|
|
12
6
|
## 行为契约
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
需求/设计文档审查或从文档生成代码时,读取 [hai-spec-review](.agents/skills/hai-spec-review/SKILL.md),严格确认完备性、歧义、技术正确性与命名一致性;影响行为的问题未解决前不判定文档可生成。普通小改动不重审无关文档。
|
|
17
|
-
|
|
18
|
-
升级 hai-framework 到最新/指定版本、比较版本差异或同步框架 skills 时,先读 [框架升级与同步 Skill](.agents/skills/hai-framework-sync/SKILL.md),执行版本发现、差异分析、用户选择/阻塞处理、迁移与验证;仅要求比较时不修改应用。
|
|
19
|
-
|
|
20
|
-
根据文档规划、实施、继续、返修或按已提交文档变更同步实现时,读取 [hai-spec-implement](.agents/skills/hai-spec-implement/SKILL.md):维护 docs 清单与任务记录,比较已验收与目标文档 Git 快照,更新原任务或新建任务,每项独立分支 TDD、验证并本地合并;全部差异与整体验收通过后才推进基线。返修复用原任务与分支。仅规划不实施,指定任务先核验依赖。
|
|
21
|
-
|
|
22
|
-
普通新增、修改、修复任务开始前,先读 [应用开发 Skill](.agents/skills/hai-app-create/SKILL.md) 和 [开发规范与框架能力路由](.agents/skills/hai-app-create/development.md);再按任务读取模块 Skill 及其相邻参考文件。架构/构建、审查、测试分别读取 hai-build、hai-app-review、hai-app-tests,不加载整个 skill 树。
|
|
8
|
+
先读 [项目共同规则](.agents/skills/hai-app-create/project.md),按当前任务读取下面的入口;不要加载整个 skill 树。业务以用户当前明确要求及指定文档为准,模板行为是可调整的起点。
|
|
23
9
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
先读 README、package.json、相关实现/测试和所需 .agents/skills;不要加载整个 skill 树。新增抽象前确认复用路径与真实需求;保留用户改动。跨文件任务简述影响和验证计划,无须固定规模标签或重复问卷。
|
|
31
|
-
|
|
32
|
-
- 直接影响:哪些页面、layout、表单/API、messages、README、测试会变。
|
|
33
|
-
- 间接影响:哪些导航入口、SEO 标签、部署脚本和共享组件需要同步。
|
|
10
|
+
| 任务 | 入口 |
|
|
11
|
+
| --- | --- |
|
|
12
|
+
| 新增、修改、修复应用 | [hai-app-create](.agents/skills/hai-app-create/SKILL.md);配置、注释与能力选择按需查 [development.md](.agents/skills/hai-app-create/development.md) |
|
|
13
|
+
| 需求/设计文档审查 | [hai-spec-review](.agents/skills/hai-spec-review/SKILL.md) |
|
|
14
|
+
| 文档驱动规划、实施或返修 | [hai-spec-implement](.agents/skills/hai-spec-implement/SKILL.md) |
|
|
15
|
+
| 代码审查 / 测试 / 构建 / 升级 | 按任务读取同名 hai-app-review / hai-app-tests / hai-build / hai-framework-sync;模块按实际依赖选择 |
|
|
34
16
|
|
|
35
17
|
## 项目定位
|
|
36
18
|
|
|
@@ -45,44 +27,7 @@
|
|
|
45
27
|
- SEO 元信息、路由结构和消息文案要一起维护。
|
|
46
28
|
- 本样板默认不以 `@h-ai/serv`、`@h-ai/api-contract`、`@h-ai/api-client`、`@h-ai/capacitor` 作为主架构。
|
|
47
29
|
|
|
48
|
-
## 工作流程
|
|
49
|
-
|
|
50
|
-
1. 先搜索现有页面、layout、组件、messages、表单/API 和测试。
|
|
51
|
-
2. 修改页面时同步 README、i18n、测试和 SEO 相关元信息。
|
|
52
|
-
3. 按改动范围验证,修复本次引入的失败;已有问题与未运行项明确报告。
|
|
53
|
-
|
|
54
|
-
页面统一继承根布局的 header/footer;新增页面沿用 SvelteKit 自动文件路由,刷新定位及服务端 load/鉴权保持一致。
|
|
55
|
-
|
|
56
|
-
## 代码注释与示例
|
|
57
|
-
|
|
58
|
-
- 尽可能补充有信息量的中文 JSDoc:所有 export 的函数/类/方法、核心算法与业务流程、所有数据库表/列、接口/type/schema 及其字段都必须说明用途、单位、约束和关联关系。核心逻辑解释决策原因、边界、权限与失败路径,不逐行复述代码。
|
|
59
|
-
- 函数按实际契约写 @param、@returns,仅确实抛错时写 @throws;异步、HaiResult 与事务失败行为须说明。类型/表结构说明字段含义、可空性、默认值、主外键和唯一约束。
|
|
60
|
-
- 上述函数和结构的 JSDoc 均提供可理解的 @example:函数给调用及结果判断,结构给合法数据,表给典型行或查询示例。省略上下文要标明,不使用真实凭据。示例随实现同步,不能只堆叠没有信息量的注释。
|
|
61
|
-
- 调用及结构示例见 [.agents/skills/hai-app-create/development.md](.agents/skills/hai-app-create/development.md) 的 JSDoc 注释一节。
|
|
62
|
-
|
|
63
|
-
## 质量门禁
|
|
64
|
-
|
|
65
|
-
先核对 package.json,按 [分轮验证与集中修复](.agents/skills/hai-app-tests/validation.md) 收集适用检查与日志,再归并修复、复测失败及受影响项;普通失败不中断独立检查,真实前置阻塞才暂停依赖项。文档检查引用,UI/路由变更加 E2E,未运行项说明原因。
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
pnpm typecheck
|
|
69
|
-
pnpm lint
|
|
70
|
-
pnpm build
|
|
71
|
-
pnpm test
|
|
72
|
-
pnpm test:e2e
|
|
73
|
-
```
|
|
74
30
|
|
|
75
31
|
## 完成条件
|
|
76
32
|
|
|
77
|
-
-
|
|
78
|
-
- 最终回复说明门禁状态、已更新页面 / 表单 / 文档与未完成项。
|
|
79
|
-
|
|
80
|
-
## 优先 Skills
|
|
81
|
-
|
|
82
|
-
- `hai-build`、`hai-app-create`、`hai-app-review`、`hai-app-tests`
|
|
83
|
-
- `hai-kit`、`hai-ui`、`hai-reldb`、`hai-cache`
|
|
84
|
-
- 其它 `hai-*` 模块按需读取
|
|
85
|
-
|
|
86
|
-
前端页面先按 [hai-ui-design](.agents/skills/hai-ui-design/SKILL.md) 确定任务、布局、状态与组件映射,使用 [hai-ui](.agents/skills/hai-ui/SKILL.md) 实现,再由 [hai-ui-review](.agents/skills/hai-ui-review/SKILL.md) 检查真实页面。窄范围修改复用已有设计;按实际语言/主题/尺寸验证。
|
|
87
|
-
|
|
88
|
-
工作流技能按 hai-领域-动作 命名,能力使用类沿用领域名。需求、验收、发现与当前版本证据按 [工作交接契约](.agents/skills/hai-spec-implement/handoff.md) 传递,沿既有清单恢复任务。
|
|
33
|
+
按实际 package scripts 和 [分轮验证](.agents/skills/hai-app-tests/validation.md) 选择受影响范围,依次收集 typecheck → lint → build(需要时)→ test → 相关 E2E;例如 `pnpm typecheck`。普通失败不中断独立检查,汇总后集中修复并定向复测。报告实际结果、文档/调用方同步与未验证原因;不能用静态、mock 或 Web 结果代替真实业务、外部服务或原生验证。
|
|
@@ -106,6 +106,8 @@ Podman 不自动继承远程服务的代理变量。需要代理时,使用 Age
|
|
|
106
106
|
|
|
107
107
|
## 工程和 Git
|
|
108
108
|
|
|
109
|
+
相对 Git 地址固定相对于工作区根目录解析,clone/fetch/push 使用相同目标。协议取消因断连失败后,close 仍尝试核验拥有的进程/容器已退出;无法确认退出时保留锁。删除与同 ID 重建争用同一会话锁,忙碌失败不会建立 opening 记录。
|
|
110
|
+
|
|
109
111
|
每个 Git 工程必须写明 `mainBranch`,remote 默认为 origin。`prepare` 只克隆缺失工程并校验既有工程;不自动 pull、不重置脏目录。`workspaces.importFiles(id, [{ path, content }])` 添加普通文件,拒绝路径逃逸、链接和覆盖;没有 Git 工程的工作区无需安装 Git。涉及 Git 而命令缺失返回 `ACP_GIT_NOT_FOUND`。
|
|
110
112
|
|
|
111
113
|
当前托管 Git 面向普通仓库;发现子模块或 Git LFS 属性时返回 `ACP_UNSUPPORTED`,不把未拉取的子模块或 LFS 指针当作完整工程。需要这些能力的应用可自行准备环境并使用低层 `connect`,其 Git 生命周期由应用负责。
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
|
|
16
16
|
## 初始化与关闭
|
|
17
17
|
|
|
18
|
+
`ai.close()` 等待已开始的初始化完成并清理,合并并发关闭;重初始化先清理旧实例,关闭期间不接受新初始化。
|
|
19
|
+
|
|
18
20
|
```ts
|
|
19
21
|
import { ai } from '@h-ai/ai'
|
|
20
22
|
import { core } from '@h-ai/core'
|
|
@@ -109,7 +111,7 @@ knowledge:
|
|
|
109
111
|
maxSize: 1500
|
|
110
112
|
overlap: 200
|
|
111
113
|
|
|
112
|
-
# 可选:
|
|
114
|
+
# 可选:Mem0 数据格式适配;仅支持 Qdrant,生产不允许临时回退
|
|
113
115
|
memory:
|
|
114
116
|
provider: mem0
|
|
115
117
|
defaultTopK: 10
|
|
@@ -239,15 +241,17 @@ await server.connect(new StreamableHTTPServerTransport({ sessionIdGenerator: cor
|
|
|
239
241
|
|
|
240
242
|
## 记忆、RAG 与知识库
|
|
241
243
|
|
|
242
|
-
`memory.
|
|
244
|
+
`ai.memory.scoped({ objectId })` 要求非空且非纯空白的主体 ID,否则工厂立即抛 `TypeError`,不会创建未绑定实例。公共 `clear({ scope: {} })` 等空范围返回失败;跨主体全清必须调用显式管理员入口。原生记忆的访问统计与更新使用版本 CAS,迟到读取不会复活已删除记录;数据库或向量清理失败通过 HaiResult 返回,不能当作成功。 Memory/Persona 的存储故障返回固定本地化文案,具体原因仅写服务端日志;先检查 result.success。
|
|
245
|
+
|
|
246
|
+
`memory.provider` 默认为 `native`(推荐),复用 vecdb/reldb/LLM/Embedding 并支持 Mem0 式批量合并。`mem0` 是 Mem0 数据格式适配,复用框架提取与 Embedding,通过原生 HTTP 读写 Qdrant,保留 UUID/payload、主体隔离和既有数据;不运行完整上游引擎。生产拒绝实际内存回退,只有开发或显式 E2E 可配置临时回退。两者提供同一组 `ai.memory.*` 操作。
|
|
247
|
+
|
|
248
|
+
切换 `native` 与 Mem0 数据格式适配不会自动迁移数据。切换前备份关系库和向量集合,并显式迁移/核对每条记忆的 ID、objectId、scope、元数据及 Embedding 模型/维度;不得把一个后端的数据目录或集合名直接配置为另一个后端并当作迁移完成。
|
|
243
249
|
|
|
244
|
-
Mem0 的 `update`
|
|
250
|
+
Mem0 的 `update` 原地修改文本与元数据,保持 `id` 和创建时间。候选扫描有界:`list` / `listPage` / 条件 `clear` 最多支持每主体 1000 条原始候选(含过期条目),多取一条探测完整性;超限返回 `MEMORY_LIST_INCOMPLETE`(906),不会伪造 total 或执行部分条件删除。候选完整时按 UTC 日期剔除过期项,再按类型/scope 过滤和分页;仅 `objectId` 的清理使用后端过滤删除,不受列表上限限制。公共空条件清理被拒绝;跨主体全清仅限受信管理员显式 `admin.clearAll({ confirm: true })`。
|
|
245
251
|
|
|
246
|
-
Mem0 3.3.1 的 Qdrant 适配仍依赖 `QdrantClient.search`;项目将 `@qdrant/js-client-rest` 精确锁定为受测的 `1.18.0`,AI 的可选 peer 也声明此版本。启动会检查该公开方法,缺失时明确配置失败;不要覆盖为已移除此方法的 1.19。
|
|
247
252
|
|
|
248
|
-
Mem0 的 pgvector 组合在所有环境拒绝启动:当前 SDK 将 PostgreSQL 连接保存在私有对象中,未提供公开关闭入口,框架无法履行资源清理契约。需要 pgvector 时选择 `memory.provider: native`;该原生后端保持支持。`disableHistory: true` 使用 SDK 无资源的历史占位实现,不创建历史 SQLite 文件。工厂通过公开的一条有界只读查询等待实际后端 ready 后才发布成功。
|
|
249
253
|
|
|
250
|
-
`add` / `extract`
|
|
254
|
+
`add` / `extract` 的写入回执不含完整业务字段,框架写后读取权威记录再返回;并发提取等待全部在途写入结束。若写入或写后读失败,`error.ext.requiresEffectReconciliation=true`,`memoryIds` 保存已知写入 ID(回执丢失时可能为空)。应按主体核对实际记忆后决定恢复,不能盲目重做 add/extract;框架不自动重放。
|
|
251
255
|
|
|
252
256
|
```ts
|
|
253
257
|
const enriched = await ai.memory.injectMemories(messages, { objectId: 'user-001', topK: 5 })
|
|
@@ -453,7 +457,14 @@ export const POST = kit.handler(async ({ request }) => {
|
|
|
453
457
|
- 只向模型注册允许自动执行的工具;写操作默认要求业务侧确认或幂等键,不能把“模型请求调用”当作授权。
|
|
454
458
|
- 批量导入、批量 embedding 用批量 API,避免 await-in-loop。
|
|
455
459
|
- 文件解析/OCR 失败按 `HaiAIError.FILE_*` 返回,不抛业务异常。
|
|
460
|
+
- HTML 文件按 HTML 结构解析并迭代提取,script/style 不进入结果,正常正文不截断。`data.text` 仍是文本/Markdown,不是可信 HTML;使用文本绑定或 `MarkdownRenderer`,不能直接交给 `{@html}`。
|
|
456
461
|
- A2A 认证失败返回 `A2A_AUTH_FAILED`;`callRemoteAgent` 只依赖 `ai.init()`,无需注册本地 executor。远端 URL 仅接受 HTTP(S) 且不得内嵌凭据,应用仍须配置 origin 白名单与出口网络策略。不要记录 token、apiKey、私钥、完整 headers 或带 query 的 URL。
|
|
457
462
|
- A2A 入站日志保存并重验租约后才执行业务,出站日志在已有有界队列内完成后才发布;日志失败产生 failed/interrupted Task,不重放相同 receipt。日志不是交付回执,按 requiresEffectReconciliation 核对可能已执行的效果;listMessages 失败为安全的 A2A_LIST_MESSAGES_FAILED(984)。
|
|
458
463
|
- A2A 任务与事件只有共享 journal 一套权威,不装配旧 TaskStore;push notification 配置和 authenticated extended card RPC 返回 SDK 标准不支持/未配置错误。应用通过公开 executor 接口接入,不导入内部 handler/Store 装配类型。
|
|
459
464
|
- Context 的 flush 会报告本节点后台提取异常及失败 HaiResult;同轮并发调用共享一次报告,返回即确认该批,后续只观察新任务。save/reset(waitForMemoryTasks)/consolidate 传播失败并停止后续写入,pendingMemoryTasks=0 不代表成功,不自动重试未知副作用。
|
|
465
|
+
|
|
466
|
+
A2A 使用原生 1.0 协议:JSON-RPC 方法为 `SendMessage` / `SendStreamingMessage` / `GetTask` / `CancelTask` / `SubscribeToTask`,不接收旧版方法名。请求的消息 role 使用 `ROLE_USER`;执行器通过 `AgentEvent.message(Message.fromJSON(...))` 或 `AgentEvent.task(Task.fromJSON(...))` 发布事件(构建器与枚举从 `@h-ai/ai` 导入),文本 Part 的 ProtoJSON 为 `{ text: '...' }`,解码后的 SDK Part 从 `content.$case/value` 读取。SDK 的 `Role` / `TaskState` 为数值枚举,远端调用的 `taskState` 同样返回该枚举;直接 HTTP 响应由 `getAgentCard` / `handleRequest` 完成标准 ProtoJSON 编码,无需调用方了解 SDK oneof。远端调用自定义头按大小写不敏感的同名字段覆盖,并拒绝 HTTP 重定向,避免把认证头转发到其它目标。
|
|
467
|
+
|
|
468
|
+
Mem0 格式存储与 VecDB 的 Qdrant Provider 均使用原生 HTTP,无需额外 SDK。固定 REST 请求使用 `query`,路径段编码;30 秒超时覆盖完整响应体,响应超过 16 MiB 明确失败。写入和删除等待 `wait=true` 的实际完成回执。列表和条件清理最多核对每主体 1000 条原始候选(包括过期项),超限返回 `MEMORY_LIST_INCOMPLETE`,不执行部分条件删除;仅按主体清理不受此列表上限限制。
|
|
469
|
+
|
|
470
|
+
Qdrant 格式后端要求 1.19 或更新版本,并拒绝 HTTP 重定向。更新使用服务端 `update_only` 与主体/版本条件,同一次原子写入拒绝已删除或已被其它写入更新的条目;迟到更新不会复活删除记录。写后版本核对失败仍需按已有回执核对实际效果。
|
|
@@ -111,16 +111,13 @@ Embedding OpenAI 客户端按 `apiKey + baseURL + timeout` 缓存;同一 key
|
|
|
111
111
|
Memory 后端通过 `memory.provider` 选择:
|
|
112
112
|
|
|
113
113
|
- `native`(默认):HAI 原生引擎,复用 vecdb/reldb/LLM/Embedding。`extract` 采用 Mem0 式批量合并(ADD/UPDATE/DELETE/NONE + `category`);`maxEntriesPerObject`(单主体配额)/`maxEntriesGlobal`(全局上限)/`recencyDecay`/`embeddingEnabled`/`writebackRelatedTopK` 作用于此后端;淘汰按 `objectId` 分区。
|
|
114
|
-
-
|
|
115
|
-
- 两者对外 API(extract/recall/injectMemories/add/update/get/remove/list/listPage/clear)完全一致;`objectId` 隔离不同主体的记忆,`scope`(key-value)用于业务作用域隔离(recall/list/listPage/clear 均严格过滤)。mem0 后端 `extract`
|
|
114
|
+
- **`mem0`(数据格式适配)**:框架负责提取与 Embedding,通过原生 HTTP 读写 Qdrant 的 Mem0 UUID/payload 格式,可读取既有数据;不运行完整上游引擎、遥测或历史数据库。仅映射带完整连接参数的 Qdrant。生产(`NODE_ENV` 或 `HAI_CORE_ENV=production`)拒绝临时回退;开发或明确 E2E 可显式使用 `memory.allowEphemeralFallback: true`。其它持久化后端选择 `native`。
|
|
115
|
+
- 两者对外 API(extract/recall/injectMemories/add/update/get/remove/list/listPage/clear)完全一致;`objectId` 隔离不同主体的记忆,`scope`(key-value)用于业务作用域隔离(recall/list/listPage/clear 均严格过滤)。mem0 后端 `extract` 在框架层分类打分后直接写入格式存储(保留 `hai_type`/`hai_importance`),`recall` 支持 `types`/`recencyWeight`,与 native 一致;Mem0 的 `update` 原地修改文本与元数据,保持 `id` 和创建时间。候选扫描有界:`list` / `listPage` / 条件 `clear` 最多支持每主体 1000 条原始候选(含过期条目),多取一条探测完整性;超限返回 `MEMORY_LIST_INCOMPLETE`(906),不会伪造 total 或执行部分条件删除。候选完整时按 UTC 日期剔除过期项,再按类型/scope 过滤和分页;仅 `objectId` 的清理使用后端过滤删除,不受列表上限限制。公共空条件清理被拒绝;跨主体全清仅限受信管理员显式 `admin.clearAll({ confirm: true })`。
|
|
116
116
|
|
|
117
|
-
Mem0 3.3.1 的 Qdrant 适配仍依赖 `QdrantClient.search`;项目将 `@qdrant/js-client-rest` 精确锁定为受测的 `1.18.0`,AI 的可选 peer 也声明此版本。启动会检查该公开方法,缺失时明确配置失败;不要覆盖为已移除此方法的 1.19。
|
|
118
117
|
|
|
119
|
-
适配器通过 SDK 公开的 `client` 配置注入独享客户端;Mem0 的 Qdrant 写入与删除均使用 `wait: true`,等待服务端应用完成后才继续写后读或分批清理。
|
|
120
118
|
|
|
121
|
-
Mem0 的 pgvector 组合在所有环境拒绝启动:当前 SDK 将 PostgreSQL 连接保存在私有对象中,未提供公开关闭入口,框架无法履行资源清理契约。需要 pgvector 时选择 `memory.provider: native`;该原生后端保持支持。`disableHistory: true` 使用 SDK 无资源的历史占位实现,不创建历史 SQLite 文件。工厂通过公开的一条有界只读查询等待实际后端 ready 后才发布成功。
|
|
122
119
|
|
|
123
|
-
`add` / `extract`
|
|
120
|
+
`add` / `extract` 的写入回执不含完整业务字段,框架写后读取权威记录再返回;并发提取等待全部在途写入结束。若写入或写后读失败,`error.ext.requiresEffectReconciliation=true`,`memoryIds` 保存已知写入 ID(回执丢失时可能为空)。应按主体核对实际记忆后决定恢复,不能盲目重做 add/extract;框架不自动重放。
|
|
124
121
|
|
|
125
122
|
## Retrieval / RAG
|
|
126
123
|
|
|
@@ -209,13 +206,19 @@ IndexTTS 的 Node HTTP 请求使用同版本 Undici fetch/Agent/FormData;模
|
|
|
209
206
|
| `getCapabilities({ operation, model? })` | `HaiResult<AudioModelCapabilities>` | 按模型与操作查询 `transcribe` / `synthesize` 能力分支,并拒绝操作不匹配模型 |
|
|
210
207
|
|
|
211
208
|
- 音频类型:`AudioContent { data: Uint8Array, format: 'pcm16'|'wav'|'mp3'|'opus', sampleRate?, channels? }`;`pcm16` 等裸音频必须传 `sampleRate`。
|
|
212
|
-
-
|
|
213
|
-
-
|
|
214
|
-
-
|
|
215
|
-
-
|
|
216
|
-
-
|
|
209
|
+
- 请求可选(识别):`contextHints?`(热词)/ `timestampGranularities?: ('segment'|'word')[]` / `vad?` / `strictCapabilities?`;结果 `TranscriptionResult { text, language?, durationMs?, segments?[{ id?, text, startMs, endMs, words?, speakerId? }] }`(词级时间戳在 `segments[].words`,毫秒整数)。
|
|
210
|
+
- 请求可选(合成):`instruction?` / `language?` / `speakerReference?: { audio, transcript?, language? }`(谁在说)/ `styleReference?`(怎么说)/ `styleStrength?`(`[0,1]`)/ `speed?`(>1 更快,与 `targetDurationMs` 互斥)/ `targetDurationMs?` + `durationToleranceMs?` / `strictCapabilities?`;结果 `SynthesisResult extends AudioContent { durationMs?, metadata?: { durationMatched?, speed? } }`。均支持 `signal`。
|
|
211
|
+
- `strictCapabilities` 为真时请求的高级能力若模型不支持 → 调 Provider 前 `AUDIO_UNSUPPORTED_INPUT`;参数非法(风格强度越界、语速非正、speed 与 targetDurationMs 冲突、durationTolerance 缺 target 等)→ `AUDIO_INVALID_REQUEST`。
|
|
212
|
+
- 模型配置:`audio.models: [{ id, provider: 'openai'|'mimo'|'qwen'|'doubao'|'whisper'|'indextts', model, operations: ('transcribe'|'synthesize')[](至少一项、不重复), apiKey?, baseUrl?, appKey?, accessKey?, resourceId?, workspaceId? }]`。`provider` 表示调用协议而非部署位置;`whisper`(ASR)/ `indextts`(TTS)可自托管,无 canonical 端点,必须显式配置 `baseUrl`(缺失 → `CONFIGURATION_ERROR`),可无凭据(配 `apiKey` 后按 `Authorization: Bearer` 发送);云平台缺凭据 → `CONFIGURATION_ERROR`。
|
|
213
|
+
- 无原生流式的平台:`whisper` 完整音频降级为最终 `transcript`、持续音频输入 → `AUDIO_UNSUPPORTED_INPUT`;`indextts` 按段完整合成降级、`streamingAudioOutput` 保持 `false`。自托管部署参考框架同版本的 `packages/ai/models/`(优先 ModelScope 下载)。
|
|
214
|
+
- 凭据优先级:模型条目 `apiKey` → 显式启用 `audio.inheritLlmApiKey` 后的 LLM `apiKey` → `HAI_AI_AUDIO_<PROVIDER>_APIKEY` 或 `OPENAI_API_KEY` / `MIMO_API_KEY` / `DASHSCOPE_API_KEY` / `VOLC_API_KEY`(豆包旧版控制台额外 `VOLC_APP_KEY` / `VOLC_ACCESS_KEY`)。
|
|
215
|
+
- 资源上限:`audio.maxAudioBytes`(默 10 MiB,同时保护说话人/风格参考)、`audio.maxStreamDurationMs`(默 5 分钟);所有请求支持 `signal: AbortSignal` 打断。
|
|
217
216
|
- Provider 为内部实现,不从根入口导出;不支持的输入方式招 `AUDIO_UNSUPPORTED_INPUT`,不伪装实时。取消 → `AUDIO_CANCELLED`,超时 → `AUDIO_TIMEOUT`,连接失败或 `end` 前异常断连 → `AUDIO_CONNECTION_FAILED`。浏览器客户端(`@h-ai/ai/client`)严格区分正常结束 / 取消 / 异常断连:取消招 `AUDIO_CANCELLED`、`end` 前断连招 `AUDIO_CONNECTION_FAILED`、服务端 error 帧保留其领域错误码,`synthesize` 不把未完成的部分音频当作成功返回。
|
|
218
217
|
|
|
218
|
+
- 播放负载:`serializePlayableAudio(audio)` 返回 `HaiResult<PlayableAudio>`;`PlayableAudio` 为 `{ audioBase64, format: 'wav'|'mp3', mimeType }`。该函数将 `pcm16` 封装为 WAV,透传 WAV/MP3;`opus` 不支持转换。
|
|
219
|
+
|
|
220
|
+
能力快照 `getCapabilities` 为同步读取;跨节点更新模型后,先调用异步 `ai.audio.models.get/list` 或音频操作刷新本节点,再据能力决定参数。
|
|
221
|
+
|
|
219
222
|
## Image
|
|
220
223
|
|
|
221
224
|
| 方法 | 返回 | 说明 |
|
|
@@ -246,7 +249,7 @@ IndexTTS 的 Node HTTP 请求使用同版本 Undici fetch/Agent/FormData;模
|
|
|
246
249
|
| `listMessages(filter)` | 查询 A2A 消息记录 |
|
|
247
250
|
| `callRemoteAgent(remoteUrl, message, options?)` | 调用远端 Agent;只依赖 `ai.init()`,不要求本地 executor |
|
|
248
251
|
|
|
249
|
-
A2A 服务端 SDK handler 在注册 executor 时延迟创建;远端客户端调用不依赖服务端配置。getAgentCard
|
|
252
|
+
A2A 服务端 SDK handler 在注册 executor 时延迟创建;远端客户端调用不依赖服务端配置。getAgentCard 返回可直接 HTTP 输出的标准 A2A 1.0 ProtoJSON Card(supportedInterfaces、MIME、streaming、安全方案);Kit 默认发现路径为 `/.well-known/agent-card.json`。handleRequest 在未初始化时也返回 JSON-RPC 错误;可信 context.agentId 映射 SDK user.userName。Kit 配置 authenticate 后空身份返回 401;不声明 push notifications、gRPC、REST 支持。
|
|
250
253
|
|
|
251
254
|
A2A journal、context 归属和消息表在 `ai.init()` 阶段初始化;可信 agentId 是身份来源,匿名共用主体,生产须认证。Task 与事件一次 CAS 发布,支持任意节点订阅、真实 owner 取消和 input-required 跨节点续接。同 message ID/内容重试复用同一轮,内容改变或旧轮重试拒绝;取消未确认时同一 Task 拒绝新消息,防止迟到回调影响新一代;失租、绝对期限或 working 状态退出标记 failed/interrupted 与 metadata.haiExecution.requiresEffectReconciliation=true,不自动重放未知副作用。a2a.execution 默认 leaseMs=30000、pollIntervalMs=250、maxExecutionMs=300000;单消息1MiB、journal8MiB、每轮2048事件、每Task256回执、32个reference tasks。listMessages 是服务端管理接口,callerId/contextId/since 不能替代调用授权。外部工具须使用稳定业务幂等键并核对未知结果,SDK异常不向用户暴露驱动凭据。
|
|
252
255
|
|
|
@@ -290,3 +293,9 @@ Knowledge 分块直接遵循 datapipe 的单位与硬上限:word 为词,其
|
|
|
290
293
|
JSDoc 公开示例使用真实包入口,内部工厂示例标记“模块内部上下文”;应用使用所安装版本的公开类型,并通过本应用已有的类型检查验证使用示例。调用示例须保留 HaiResult 成功检查、受信主体范围、共享 CAS 版本与存储端期限,不将后台 flush 失败或未知外部效果当作成功重试。
|
|
291
294
|
|
|
292
295
|
SSE:Node 的 ai.stream 解码器支持跨片 LF/CRLF/CR、多行 data,只去冒号后一个空格;无 data 块不派发,空或缺省事件名按 message,id/retry 继承最近有效值,reset 清空连接状态,EOF 不补空行。encodeSSE 允许合法 data 换行并规范化,id/event 换行、id 的 NUL、非负安全整数以外的 retry 显式抛 TypeError/RangeError。真实 Anthropic/MiMo 使用同一内部 UTF-8 reader,退出/取消/协议结束/错误均取消正文并释放 reader;无自动重连/副作用重放。Anthropic 总 timeout 覆盖正文,MiMo 保留每请求独立 timeout。
|
|
296
|
+
|
|
297
|
+
A2A 使用原生 1.0 协议:JSON-RPC 方法为 `SendMessage` / `SendStreamingMessage` / `GetTask` / `CancelTask` / `SubscribeToTask`,不接收旧版方法名。请求的消息 role 使用 `ROLE_USER`;执行器通过 `AgentEvent.message(Message.fromJSON(...))` 或 `AgentEvent.task(Task.fromJSON(...))` 发布事件(构建器与枚举从 `@h-ai/ai` 导入),文本 Part 的 ProtoJSON 为 `{ text: '...' }`,解码后的 SDK Part 从 `content.$case/value` 读取。SDK 的 `Role` / `TaskState` 为数值枚举,远端调用的 `taskState` 同样返回该枚举;直接 HTTP 响应由 `getAgentCard` / `handleRequest` 完成标准 ProtoJSON 编码,无需调用方了解 SDK oneof。
|
|
298
|
+
|
|
299
|
+
Mem0 格式存储与 VecDB 的 Qdrant Provider 均使用原生 HTTP,无需额外 SDK。固定 REST 请求使用 `query`,路径段编码;30 秒超时覆盖完整响应体,响应超过 16 MiB 明确失败。写入和删除等待 `wait=true` 的实际完成回执。列表和条件清理最多核对每主体 1000 条原始候选(包括过期项),超限返回 `MEMORY_LIST_INCOMPLETE`,不执行部分条件删除;仅按主体清理不受此列表上限限制。
|
|
300
|
+
|
|
301
|
+
Qdrant 格式后端要求 1.19 或更新版本,并拒绝 HTTP 重定向。更新使用服务端 `update_only` 与主体/版本条件,同一次原子写入拒绝已删除或已被其它写入更新的条目;迟到更新不会复活删除记录。写后版本核对失败仍需按已有回执核对实际效果。
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
## 使用步骤
|
|
11
11
|
|
|
12
|
-
`client.close()` 使旧刷新失效并等待已开始的凭据写入,但不清除宿主 TokenStorage。关闭完成后可复用同一存储重新 init;迟到刷新不能覆盖新身份。请求 timeout
|
|
12
|
+
`client.close()` 使旧刷新失效并等待已开始的凭据写入,但不清除宿主 TokenStorage。关闭完成后可复用同一存储重新 init;迟到刷新不能覆盖新身份。请求 timeout 覆盖响应头、完整 JSON 和所有失败响应正文(包括 HTML);超时或取消不启动刷新。自定义流按需读取,以调用方 signal 取消正文。内置 Cookie 适配器的登录和刷新包含跨域凭据,服务端须配置明确 Origin;内存/原生存储保留原请求凭据策略。
|
|
13
13
|
|
|
14
14
|
### 1. 初始化
|
|
15
15
|
|
|
@@ -73,7 +73,9 @@ YAML 使用 `${HAI_DB_TYPE:sqlite}` 等显式引用,冒号后是未配置时
|
|
|
73
73
|
|
|
74
74
|
`prod` 是文件模式名,对应 `HAI_CORE_ENV=production`;环境枚举为 `development | test | production | staging`。SvelteKit adapter-node 产物使用 `node scripts/run-node.mjs prod . build/index.js`。路径相对工作目录,公共文件提交 Git,私有文件不进入镜像或版本库。部署容器由 SDK 统一运行文件加载,浏览器只接收公开白名单。
|
|
75
75
|
|
|
76
|
-
当前 SDK 的 Node 后端默认读取实际挂载的发布 `.env.runtime`,修改后重启容器生效;托管连接保持更高优先级,静态 Web、中间件、网关路径、端口/挂载和 Node
|
|
76
|
+
当前 SDK 的 Node 后端默认读取实际挂载的发布 `.env.runtime`,修改后重启容器生效;托管连接保持更高优先级,静态 Web、中间件、网关路径、端口/挂载和 Node 启动参数按部署流程更新。长期修改同步回源环境,下一次后端发布会重新生成;已交付 `hai-deploy` 的工程按该技能“后端运行配置重载”小节处理,未交付时以本工程实际启动/部署脚本为准。自行维护且只使用 Compose `env_file` 注入环境的容器,改文件后需要重新创建,通常无需重建镜像。请求策略可固定引用只读挂载 YAML,后续改文件并重启服务实例重新读取;运行中不监视文件、不逐请求读盘。同一来源先应用 `HAI_SERV` / `HAI_KIT` 父 JSON,再由叶子变量覆盖;更高来源的父对象才清除低来源细项,遵循本节统一来源顺序。待上传归档与 SDK 策略快照不能手改;运维外部文件和 Compose override 另行备份,SDK 自动回滚不恢复外部文件。
|
|
77
|
+
|
|
78
|
+
SDK 的 SvelteKit SSR 在 HTTP/HTTPS 下均通过独立 gateway,后端不公开端口;协议、Host 与客户端地址由网关覆盖,adapter 转发信任由 Compose 固定。adapter-node 6 不读取运行期 `ORIGIN`,不能靠改该变量切换访问地址;应用默认不固定 `paths.origin`,旧直接公开 SSR 的部署须重新生成全量交付包。
|
|
77
79
|
|
|
78
80
|
Fullstack 的环境文件在工程根;service 脚本通过 `../../.env*` 加载,Web/App/Desktop 的 Vite 自动 dotenv 加载关闭(`envDir: false`),开发和预览由 `core.config.loadEnvFiles` 从工程根读取,构建不读取部署环境文件。API workspace 的环境文件在 `apps/<name>-serv/`。独立应用在各自根目录加载。静态 Web 通过 `runtime-config.js` 获取公开地址,部署环境覆盖无需重建镜像;原生包在复制静态资源前配置该入口。修改编译进客户端的默认值时仍需重新构建;fullstack 的公开应用元数据由 service `app.info` 返回。
|
|
79
81
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# 生成应用共同规则
|
|
2
|
+
|
|
3
|
+
本文件随 hai-app-create 完整目录交付。AGENTS 保留当前工程架构,公共约束在这里维护;先读 README、package.json、相关实现与测试,按任务读取所需 skill,不预加载全部参考。
|
|
4
|
+
|
|
5
|
+
## 需求与授权
|
|
6
|
+
|
|
7
|
+
- 业务以用户当前明确要求及其指定需求/设计文档为准;模板角色、权限、流程、字段、限额、存储和架构是初始实现。冲突时在已有授权内适配,同步 contract、鉴权、迁移、界面、配置、测试与过期规则,不要求把需求改回模板。
|
|
8
|
+
- 未说明的业务行为注明假设;只有实质矛盾、优先级不明或真实技术/安全障碍才提出具体问题。只读或仅规划请求不扩展为实现。
|
|
9
|
+
- 框架结构、配置、核心流程或模块边界的重要变化,按 [hai-change-plan](../hai-change-plan/SKILL.md) 说明方案与影响后等待决定;已确认且未扩大的方案不重复确认。普通应用私有实现沿已有授权推进。
|
|
10
|
+
|
|
11
|
+
## 实现与安全
|
|
12
|
+
|
|
13
|
+
- 先用 rg 查实现、引用、测试与文档,保留已有改动。优先复用真实适用的框架能力和公开类型;skill 已交付不表示模块已安装或启用。不为覆盖清单添加无关依赖、抽象或转发层。
|
|
14
|
+
- 按实际安装版本的 exports/types 核验契约。生命周期模块按依赖顺序 init → use → close,每步检查结果、失败清理、关闭反序;core/serv/kit、工厂、纯函数和流按实际签名使用。HaiResult 先判断 success,tx.wrap 返回失败结果不会自动回滚。
|
|
15
|
+
- 服务端校验输入、身份、权限及资源/租户归属;SQL 值参数化、标识符白名单、文件路径防逃逸。不把隐藏按钮当授权,不执行不可信 HTML/AI 内容。
|
|
16
|
+
- 密钥不进入 PUBLIC_/VITE_、浏览器或日志,敏感 token 不写 localStorage;沿现有 Cookie/内存或原生安全存储流程。用户提示准确且脱敏,日志保留英文操作上下文及可关联错误,未知提交不自动重放。
|
|
17
|
+
- 禁止 any、无说明的 as unknown as、console.log、硬编码密钥。注释中文,结构化日志英文且脱敏,用户文本沿现有 i18n 同步全部 locale。
|
|
18
|
+
|
|
19
|
+
## 代码注释与示例
|
|
20
|
+
|
|
21
|
+
- 尽可能补充有信息量的中文 JSDoc:所有 export 的函数/类/方法、核心算法与业务流程、所有数据库表/列、接口/type/schema 及其字段都必须说明用途、单位、约束和关联关系。核心逻辑解释决策原因、边界、权限与失败路径,不逐行复述代码。
|
|
22
|
+
- 函数按实际契约写 @param、@returns,仅确实抛错时写 @throws;异步、HaiResult 与事务失败行为须说明。类型/表结构说明字段含义、可空性、默认值、主外键和唯一约束。
|
|
23
|
+
- 上述函数和结构的 JSDoc 均提供可理解的 @example:函数给调用及结果判断,结构给合法数据,表给典型行或查询示例。省略上下文要标明,不使用真实凭据。示例随实现同步,不能只堆叠没有信息量的注释。
|
|
24
|
+
- 调用及结构示例见 [development.md](development.md) 的 JSDoc 注释一节。
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## 同步与验证
|
|
28
|
+
|
|
29
|
+
按 [沟通与同步维护](collaboration.md) 先说明结论,区分已确认、待验证、计划、完成和未解决。跨边界变更核对实现、配置、注释、README、网站源、模板、调用方、i18n 与测试;共享任务沿 [交接契约](../hai-spec-implement/handoff.md) 续跑。
|
|
30
|
+
|
|
31
|
+
按真实差异、调用方和用户路径选择必要门禁,遵循 [分轮验证](../hai-app-tests/validation.md),不默认全量重跑。UI/路由验证实际交互、失败恢复和适用尺寸/语言/主题;仅在新页面或明显改版时进入已交付的 hai-ui-design,组件实现用 hai-ui,真实页面走查用 hai-ui-review。纯 API 不加载 UI 路径。临时工程、进程、容器和数据在 teardown/finally 清理,只清理本次创建资源;证据放项目忽略目录。
|
|
32
|
+
|
|
33
|
+
完成时说明行为变化、实际复用、已执行门禁、同步文档/依赖方及未验证原因;文档修改明确是否影响运行时代码。
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
- 新增页面(路由)
|
|
10
10
|
- 新增 API 端点
|
|
11
|
-
-
|
|
11
|
+
- 新增服务层模块(`#lib/server/services/`)
|
|
12
12
|
- 新增数据库表 / 数据模型
|
|
13
13
|
- 新增业务组件
|
|
14
14
|
- 修改或修复已有功能、接口和交互
|
|
@@ -197,7 +197,7 @@ export const POST = kit.handler(async ({ request, locals }) => {
|
|
|
197
197
|
|
|
198
198
|
## 创建服务层
|
|
199
199
|
|
|
200
|
-
服务层位于
|
|
200
|
+
服务层位于 `#lib/server/services/`,处理业务逻辑。
|
|
201
201
|
|
|
202
202
|
```typescript
|
|
203
203
|
import type { HaiResult, PaginatedResult } from '@h-ai/core'
|
|
@@ -237,7 +237,7 @@ export async function listArticles(params: ListParams): Promise<HaiResult<Pagina
|
|
|
237
237
|
|
|
238
238
|
### Schema 定义(SQL DDL)
|
|
239
239
|
|
|
240
|
-
沿用当前应用的迁移/建表入口;仅开发初始化用的简单 SvelteKit 示例可在
|
|
240
|
+
沿用当前应用的迁移/建表入口;仅开发初始化用的简单 SvelteKit 示例可在 `#lib/server/init.ts` 建表。不要把本例 SQLite DDL 无修改复制到 PostgreSQL/MySQL,迁移与索引需匹配实际数据库。
|
|
241
241
|
|
|
242
242
|
```typescript
|
|
243
243
|
const BUSINESS_SCHEMA = `
|
|
@@ -279,13 +279,13 @@ interface CreateArticleInput {
|
|
|
279
279
|
|
|
280
280
|
## 创建业务组件
|
|
281
281
|
|
|
282
|
-
业务组件放在
|
|
282
|
+
业务组件放在 `#lib/components/`,通用 UI 使用 `@h-ai/ui`。
|
|
283
283
|
|
|
284
284
|
```svelte
|
|
285
285
|
<!-- src/lib/components/ArticleCard.svelte -->
|
|
286
286
|
<script lang="ts">
|
|
287
|
-
import type { Article } from '
|
|
288
|
-
import * as m from '
|
|
287
|
+
import type { Article } from '#lib/types/article.js'
|
|
288
|
+
import * as m from '#lib/paraglide/messages.js'
|
|
289
289
|
|
|
290
290
|
let { article, onEdit }: { article: Article, onEdit?: () => void } = $props()
|
|
291
291
|
</script>
|
|
@@ -311,7 +311,7 @@ interface CreateArticleInput {
|
|
|
311
311
|
- 事件回调通过 props 传入(非 `createEventDispatcher`)
|
|
312
312
|
- 样式使用 TailwindCSS 4 + DaisyUI 5 class
|
|
313
313
|
- 通用 UI 组件优先使用 `@h-ai/ui`,不重复实现
|
|
314
|
-
- i18n 文本使用
|
|
314
|
+
- i18n 文本使用 `#lib/paraglide/messages.js` 中的 key
|
|
315
315
|
|
|
316
316
|
## 初始化顺序
|
|
317
317
|
|
|
@@ -325,7 +325,7 @@ H5 所有页面继承根布局的 header/footer;认证页隐藏底部导航,
|
|
|
325
325
|
|
|
326
326
|
Fullstack 的公共 `.env` 启用当前模块的运行参数,YAML 显式引用同名变量并保留本地回退;未启用模块与可选字段保留注释。环境文件的用途、加载优先级及私有值保存方式遵守 [环境配置规范](development.md#环境配置),模块仍按公开 Schema 校验。
|
|
327
327
|
|
|
328
|
-
复用当前应用服务端启动/关闭入口;SvelteKit 通常为
|
|
328
|
+
复用当前应用服务端启动/关闭入口;SvelteKit 通常为 `#lib/server/init.ts`,API/fullstack 使用已有 service/serv 初始化文件。下列是启用 IAM 时的常见依赖关系,不要求无关应用安装这些模块:
|
|
329
329
|
|
|
330
330
|
```
|
|
331
331
|
core.init() → crypto.init() → reldb.init() → cache.init() → iam.init() → createBusinessTables()
|
|
@@ -136,7 +136,7 @@ describe('article persistence', () => {
|
|
|
136
136
|
### Schema 校验测试模板
|
|
137
137
|
|
|
138
138
|
```typescript
|
|
139
|
-
import { CreateUserSchema } from '
|
|
139
|
+
import { CreateUserSchema } from '#lib/server/schemas/user.js'
|
|
140
140
|
// tests/schemas/user-schema.test.ts
|
|
141
141
|
import { describe, expect, it } from 'vitest'
|
|
142
142
|
|
|
@@ -52,7 +52,7 @@ description: "构建或排查 hai 应用的源码、静态网站、容器镜像
|
|
|
52
52
|
- 静态客户端通过 runtime-config.js 或原生宿主初始化脚本获取公开地址与元数据;仅投影公开白名单,禁止将完整 process.env、服务配置或密钥序列化到浏览器。预览与容器启动均须验证真实登录,不能依赖构建期 API 地址让 E2E 通过。
|
|
53
53
|
- Fullstack Capacitor App 在 `public/runtime-config.js` 提供公开 API 地址,再编译并同步原生资源;Tauri 从启动进程的 PUBLIC_API_BASE 注入。不能把开发代理的 .env 配置当作已安装原生包的运行配置。
|
|
54
54
|
- `pnpm build --target desktop --platform windows|linux|macos --arch x64|arm64` 调用对应工程的 Tauri build。要求在目标系统准备 Rust target、SDK 和打包工具,不假定跨系统编译。原生安装包必须按目标系统实测。
|
|
55
|
-
- deploy 默认消费已有产物,--build
|
|
55
|
+
- deploy 默认消费已有产物,--build 显式先构建。工程已交付 `hai-deploy` 时按需读取该技能;已有工程的通用 AI 支持不假定已安装部署工具,先核对实际 scripts 与依赖。网络不通时 --bundle-only 默认生成 tar.gz(显式--output release.tar保留未压缩格式),按说明手工搬运;packaged 不代表部署已运行。
|
|
56
56
|
- 测试临时工程、镜像、容器、辅助进程和数据必须在 finally/teardown 自动清理,失败/取消也清理;日志、截图和报告保留到分析和交付结束再清理,不得提交测试产物或删除用户既有资源。
|
|
57
57
|
- 浏览器测试的数据放入本轮独立临时目录;Windows 等子进程与服务退出后再删除数据库和上传文件,不依赖下一轮测试补清理。
|
|
58
58
|
|
|
@@ -73,4 +73,4 @@ Windows 构建子进程使用追加式 pnpm 日志并规范 CRLF,等待输出
|
|
|
73
73
|
- 统一编码规范
|
|
74
74
|
- 标准工作流
|
|
75
75
|
|
|
76
|
-
`pnpm build --target app --platform android --runtime auto --debug` 容器打调试 APK,省略 `--debug` 使用发布签名;`--runtime` 可选 auto/docker/podman,省略时使用本机工具链。iOS 在 macOS/Xcode 上签名导出 IPA。原生打包拒绝同步后的 `CAPACITOR_SERVER_URL`,成功后按平台、构建类型和批次归档到 `.hai/build/app/` 或 `.hai/build/desktop/`,更新对应的 `latest
|
|
76
|
+
`pnpm build --target app --platform android --runtime auto --debug` 容器打调试 APK,省略 `--debug` 使用发布签名;`--runtime` 可选 auto/docker/podman,省略时使用本机工具链。iOS 在 macOS/Xcode 上签名导出 IPA。原生打包拒绝同步后的 `CAPACITOR_SERVER_URL`,成功后按平台、构建类型和批次归档到 `.hai/build/app/` 或 `.hai/build/desktop/`,更新对应的 `latest`。只有工程已交付 `hai-capacitor` 时,才按需读取该技能 `reference.md` 的“Android 容器打包”小节;纯 API 工程不交付原生技能,新增原生端时先补当前版本的能力与技能。构建身份统一 128 字符,显式非法 `HAI_BUILD_ID`/`HAI_BUILD_COMMIT` 报错且不回显原值。
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## SvelteKit
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
SvelteKit 3 的宿主在 `sveltekit({ paths: { base: 挂载目录, relative: false } })` 中固定绝对前缀,再通过公开 `$app/paths.resolve('/').replace(/\/$/, '')` 获取目录。启用 transport 时,将同一前缀传给服务端 `crypto.transport.basePath`、浏览器 `installBrowserTransport(config, { crypto, basePath })` 与独立 Kit client 的 `transport.basePath`。默认空字符串为域名根目录,不在 YAML 另维护一份挂载目录;SSR 相对路径不能作为协议前缀。交换/排除/容量路径仍用完整路径。目录验收须检查带前缀 API 的加密标记和缺协议拒绝,页面、登录成功不能替代协议验证。
|
|
8
8
|
|
|
9
9
|
- admin、h5和website从构建进程的PUBLIC_BASE_PATH设置kit.paths.base,默认空字符串。根目录保持空,子目录如`/yyy`无末尾斜杠;构建不读取私有dotenv中的这个控制值。
|
|
10
10
|
- 组件链接用`$app/paths`的resolve;认证动作使用带base的api/auth地址。守卫匹配实际URL,protectedPaths/publicPaths/loginUrl都应带base。新模板已接好,旧应用与自定义路由须同步核对。
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
应用 Node/工具链要求以当前 `package.json.engines`、lockfile 与 CI 为准。使用 Turbo 时核对影响产物的环境变量、共享配置和模式切换清理策略,并验证实际产物;不要假定应用使用框架仓库的 tsup/Turbo 私有脚本。
|
|
6
6
|
|
|
7
|
+
镜像 JSON 的 `manifest.source.dirty` 检查工程、所选 context 与 Dockerfile 中未忽略文件的 Git 状态;context 指向仓库根时包含兄弟包。跨所属仓库或检查不完整返回 null,不能解释为干净;它不是构建输入的内容证明,发布 Worker 仍须使用固定提交的受控检出。
|
|
8
|
+
|
|
7
9
|
本技能帮助识别应用架构、依赖和技能。日常开发决策、安全边界与能力选择见 [development.md](../hai-app-create/development.md)。
|
|
8
10
|
|
|
9
11
|
## 适用场景
|
|
@@ -44,6 +46,8 @@
|
|
|
44
46
|
|
|
45
47
|
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
48
|
|
|
49
|
+
镜像构建只应使用可信且构建期间不会被其他主体替换的 context。CLI 在各 context 的 `images/dependencies/` 生成依赖缓存及 `.managed.json` 跟踪清单;缓存祖先目录不得是符号链接或 Windows junction,缓存文件不得是链接或多硬链接文件。更新通过独占临时文件原子替换,内容未变时保留时间戳;旧清单清理仅限该缓存树。若报缓存路径错误,按提示的原因和诊断码检查该路径,处理链接或访问权限后再重建。跟踪清单最多 16MiB,超限或 JSON 损坏时会给出诊断,且不会回显原文件内容。
|
|
50
|
+
|
|
47
51
|
### 下载源与代理
|
|
48
52
|
|
|
49
53
|
```sh
|
|
@@ -56,7 +60,7 @@ pnpm build --target image --image-source custom --image-mirrors "docker.io=mirro
|
|
|
56
60
|
|
|
57
61
|
代理形如 `{ "mode": "custom", "url": "http://127.0.0.1:10808", "bypass": "localhost,127.0.0.1" }`。inherit 使用进程变量;system 读取 Windows/macOS 静态代理,PAC/自动发现或其他平台用继承/自定义;none 清空本次代理变量,--no-http-proxy 等价 none。自定义地址不含认证,认证代理仅从环境继承。Podman 默认构建网络保留原代理地址,显式 --network pasta 等隔离网络时回环地址替换为 host.containers.internal;Docker 非 host 网络使用 host.docker.internal。须验证真实构建网络,run 结果不能代替;默认不通时显式试 --network pasta 或改用可达代理地址。Docker/远程 Podman 拉取使用引擎侧代理,不能用构建参数代替配置引擎,修改与重启独立安排。
|
|
58
62
|
|
|
59
|
-
Dockerfile 在 FROM 前声明 HAI_NODE_IMAGE / 适用的 HAI_NGINX_IMAGE,构建阶段用 HAI_NPM_REGISTRY 设置 COREPACK_NPM_REGISTRY、npm_config_registry、pnpm_config_registry。首个下载步骤验证代理 TCP 可达性,代理不进入运行 ENV。旧工程同步模板后重新构建;显式 tarball/Git URL 和原生包不由 registry
|
|
63
|
+
Dockerfile 在 FROM 前声明 HAI_NODE_IMAGE / 适用的 HAI_NGINX_IMAGE,构建阶段用 HAI_NPM_REGISTRY 设置 COREPACK_NPM_REGISTRY、npm_config_registry、pnpm_config_registry。首个下载步骤验证代理 TCP 可达性,代理不进入运行 ENV。旧工程同步模板后重新构建;显式 tarball/Git URL 和原生包不由 registry 覆盖。SQLite 13 原生二进制随 npm 包交付,使用同一 npm 源,无独立下载步骤。deploy 的 npm 参数须与 --build 一起使用。
|
|
60
64
|
|
|
61
65
|
### SvelteKit Adapter 模式
|
|
62
66
|
|
|
@@ -74,14 +78,14 @@ CLI website模板默认Node SSR,只安装Core/Kit/UI;注释配置和环境
|
|
|
74
78
|
**Adapter 切换**:
|
|
75
79
|
|
|
76
80
|
```typescript
|
|
77
|
-
//
|
|
81
|
+
// vite.config.ts — SvelteKit 3 的配置在 Vite 插件中
|
|
78
82
|
import { createAdapter } from '@h-ai/kit/adapter'
|
|
83
|
+
import { sveltekit } from '@sveltejs/kit/vite'
|
|
84
|
+
import { defineConfig } from 'vite'
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
},
|
|
84
|
-
}
|
|
86
|
+
export default defineConfig({
|
|
87
|
+
plugins: [sveltekit({ adapter: await createAdapter(), paths: { relative: false } })],
|
|
88
|
+
})
|
|
85
89
|
```
|
|
86
90
|
|
|
87
91
|
- `VITE_ADAPTER=node`(默认)→ adapter-node(SSR)
|
|
@@ -84,6 +84,8 @@ await apiClient.init({
|
|
|
84
84
|
|
|
85
85
|
任一 key 写入失败也会屏蔽整对凭据,避免 access 已落盘而 refresh 保存失败后的半完成登录。登录/注册保存失败后尝试 `auth.clear()` 清理部分数据;清理失败继续显示未确认删除的错误,不能只清界面身份或宣称持久删除成功。
|
|
86
86
|
|
|
87
|
+
同一模块内全部 TokenStorage 共享原生写入/删除队列;clear 等待此前写入再删除,后续显式写入才可建立新凭据。该顺序覆盖同模块多适配器,不跨独立 WebView/JavaScript 运行环境提供进程间协调。
|
|
88
|
+
|
|
87
89
|
#### Preferences 子操作
|
|
88
90
|
|
|
89
91
|
```typescript
|
|
@@ -79,6 +79,7 @@ lint/typecheck 只能执行已配置的规则。新增开发规范时区分可
|
|
|
79
79
|
- [ ] 使用 `concurrency` 取消同分支旧任务
|
|
80
80
|
- [ ] 不在 CI 日志打印 token、cookie、连接串、`.env` 内容
|
|
81
81
|
- [ ] release workflow 独立提权,只在 main/tag/manual 触发
|
|
82
|
+
- [ ] 自动推进默认发布标签时核对实际来源顺序;互斥锁不保证旧 CI 先完成,迟到版本不能回退默认标签,人工回退使用显式入口
|
|
82
83
|
- [ ] 失败日志可定位,不吞错、不 `|| true` 掩盖核心质量门禁
|
|
83
84
|
|
|
84
85
|
## Secret scan 策略
|