@h-ai/cli 0.1.0-alpha.19 → 0.1.0-alpha.20

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 (63) hide show
  1. package/dist/{chunk-BPO34NRL.js → chunk-3BBXDQ4Y.js} +5 -5
  2. package/dist/chunk-3BBXDQ4Y.js.map +1 -0
  3. package/dist/cli-config-templates-IGGO7P45.js +5 -0
  4. package/dist/{cli-config-templates-JCS7T3NU.js.map → cli-config-templates-IGGO7P45.js.map} +1 -1
  5. package/dist/index.js +67 -39
  6. package/dist/index.js.map +1 -1
  7. package/dist/{src-N4NPS7AG.js → src-QNEJJ3BV.js} +261 -103
  8. package/dist/src-QNEJJ3BV.js.map +1 -0
  9. package/package.json +2 -2
  10. package/templates/apps/admin/messages/en-US.json +5 -0
  11. package/templates/apps/admin/messages/zh-CN.json +5 -0
  12. package/templates/apps/admin/src/routes/+layout.svelte.hbs +5 -5
  13. package/templates/apps/admin/src/routes/+page.svelte.hbs +32 -12
  14. package/templates/apps/admin/src/routes/admin/+layout.svelte.hbs +37 -20
  15. package/templates/apps/admin/src/routes/admin/+page.svelte.hbs +33 -24
  16. package/templates/apps/admin/src/routes/admin/settings/+page.svelte.hbs +16 -13
  17. package/templates/apps/android-app/src/lib/api.ts.hbs +4 -3
  18. package/templates/apps/android-app/src/lib/capacitor.ts +1 -1
  19. package/templates/apps/android-app/src/routes/+layout.svelte.hbs +11 -10
  20. package/templates/apps/android-app/src/routes/+page.svelte.hbs +17 -6
  21. package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +4 -1
  22. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_core.yml.hbs +14 -0
  23. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_serv.yml.hbs +13 -0
  24. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/index.ts.hbs +3 -0
  25. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server-app.ts.hbs +23 -3
  26. package/templates/apps/h5/messages/en-US.json +3 -0
  27. package/templates/apps/h5/messages/zh-CN.json +3 -0
  28. package/templates/apps/h5/src/routes/+layout.svelte.hbs +30 -29
  29. package/templates/apps/h5/src/routes/+page.svelte.hbs +17 -6
  30. package/templates/apps/h5/src/routes/discover/+page.svelte.hbs +17 -6
  31. package/templates/apps/h5/src/routes/profile/+page.svelte.hbs +17 -6
  32. package/templates/apps/website/src/routes/+layout.svelte.hbs +35 -26
  33. package/templates/apps/website/src/routes/+page.svelte.hbs +28 -10
  34. package/templates/apps/website/src/routes/about/+page.svelte.hbs +11 -6
  35. package/templates/apps/website/src/routes/contact/+page.svelte.hbs +37 -34
  36. package/templates/apps/website/src/routes/services/+page.svelte.hbs +27 -40
  37. package/templates/base/package.json.hbs +26 -21
  38. package/templates/base/src/app.html.hbs +4 -0
  39. package/templates/base/src/hooks.server.ts.hbs +17 -7
  40. package/templates/base/src/lib/server/init.ts.hbs +20 -12
  41. package/templates/base/static/favicon.png +0 -0
  42. package/templates/base/tests/scaffold.test.ts.hbs +9 -1
  43. package/templates/base/vite.config.ts.hbs +3 -3
  44. package/templates/features/iam/routes-admin/(auth)/+layout.svelte.hbs +5 -5
  45. package/templates/features/iam/routes-admin/(auth)/auth/login/+page.svelte.hbs +34 -32
  46. package/templates/features/iam/routes-admin/(auth)/auth/register/+page.svelte.hbs +46 -48
  47. package/templates/features/iam/routes-h5/auth/login/+page.svelte.hbs +35 -31
  48. package/templates/features/iam/routes-h5/auth/register/+page.svelte.hbs +41 -38
  49. package/templates/skills/AGENTS.md +11 -1
  50. package/templates/skills/CLAUDE.md +2 -1
  51. package/templates/skills/copilot-instructions.md +22 -6
  52. package/templates/skills/hai-ai/SKILL.md +115 -648
  53. package/templates/skills/hai-ai/reference.md +197 -0
  54. package/templates/skills/hai-api-client/SKILL.md +3 -1
  55. package/templates/skills/hai-app-create/SKILL.md +1 -1
  56. package/templates/skills/hai-app-review/SKILL.md +1 -1
  57. package/templates/skills/hai-deploy/SKILL.md +12 -9
  58. package/templates/skills/hai-kit/SKILL.md +5 -3
  59. package/templates/skills/hai-serv/SKILL.md +2 -0
  60. package/templates/skills/hai-ui/SKILL.md +25 -11
  61. package/dist/chunk-BPO34NRL.js.map +0 -1
  62. package/dist/cli-config-templates-JCS7T3NU.js +0 -5
  63. package/dist/src-N4NPS7AG.js.map +0 -1
@@ -0,0 +1,197 @@
1
+ # @h-ai/ai reference
2
+
3
+ 本文件承载 `SKILL.md` 中不常用但仍需要保留的 API 参考。优先读取 `SKILL.md`;只有当任务需要完整方法清单、错误码或长示例时再读取本文件。
4
+
5
+ ## 初始化与依赖
6
+
7
+ | 能力 | 是否需要 `ai.init()` | 依赖 |
8
+ | --- | --- | --- |
9
+ | `ai.tools` | 否 | 无 |
10
+ | `ai.stream` | 否 | 无 |
11
+ | `ai.llm` | 是 | OpenAI 兼容 LLM 配置 |
12
+ | `ai.embedding` | 是 | LLM/Embedding 模型配置 |
13
+ | `ai.memory` | 是 | Store + 可选 Embedding |
14
+ | `ai.retrieval` / `ai.rag` | 是 | Embedding + Store |
15
+ | `ai.knowledge` | 是 | LLM + Embedding + Store + datapipe |
16
+ | `ai.context` | 是 | LLM + Store + 可选 Memory/RAG/Reasoning |
17
+ | `ai.a2a` | 是 | A2A 配置 + executor |
18
+
19
+ 关闭必须使用 `await ai.close()`,这样才能确定释放自定义 `AIStoreProvider.close()`。
20
+
21
+ ## LLM
22
+
23
+ | 方法 | 说明 |
24
+ | --- | --- |
25
+ | `chat(options)` | 非流式 Chat Completion |
26
+ | `chatStream(options)` | 流式 Chat Completion |
27
+ | `ask(query, options?)` | 返回纯文本的简易问答 |
28
+ | `askStream(query, options?)` | 流式纯文本问答 |
29
+ | `listModels()` | 查询可用模型 |
30
+ | `getHistory(scope, options?)` | 查询会话历史 |
31
+ | `listSessions(objectId)` | 查询主体会话 |
32
+
33
+ ```ts
34
+ const result = await ai.llm.chat({
35
+ model: 'fast',
36
+ messages: [
37
+ { role: 'system', content: '你是一个翻译助手' },
38
+ { role: 'user', content: '你好世界' },
39
+ ],
40
+ })
41
+ if (result.success) {
42
+ const reply = result.data.choices[0]?.message.content ?? ''
43
+ }
44
+ ```
45
+
46
+ ## Tools
47
+
48
+ - `ai.tools.define({ name, description, parameters, handler })`
49
+ - `ai.tools.createRegistry()`
50
+ - `registry.register(tool)` / `registry.unregister(name)`
51
+ - `registry.getDefinitions()`:传给 LLM 的工具定义
52
+ - `registry.execute(toolCall)` / `registry.executeAll(toolCalls, { parallel })`
53
+
54
+ 工具 handler 输入由 Zod schema 约束,外部输入不要绕过 schema。
55
+
56
+ ## MCP
57
+
58
+ ### 独立服务器
59
+
60
+ ```ts
61
+ const mcp = createMcpServer({ name: 'my-server', version: '1.0.0' })
62
+ mcp.registerResource('config', 'config://app', { description: '应用配置' }, async uri => ({
63
+ contents: [{ uri: uri.href, text: '{}' }],
64
+ }))
65
+ await mcp.connect(new StdioServerTransport())
66
+ ```
67
+
68
+ ### `ai.mcp`
69
+
70
+ | 方法 | 说明 |
71
+ | --- | --- |
72
+ | `registerTool(definition, handler)` | 注册内置工具 |
73
+ | `callTool(name, args, context?)` | 调用工具 |
74
+ | `registerResource(resource, handler)` | 注册资源 |
75
+ | `readResource(uri)` | 读取资源 |
76
+ | `registerPrompt(prompt, handler)` | 注册提示词 |
77
+ | `getPrompt(name, args)` | 生成提示词消息 |
78
+
79
+ ## Embedding
80
+
81
+ Embedding OpenAI 客户端按 `apiKey + baseURL + timeout` 缓存;同一 key 指向不同网关时不会复用错误客户端。
82
+
83
+ | 方法 | 说明 |
84
+ | --- | --- |
85
+ | `embed(request)` | 支持单条/批量输入 |
86
+ | `embedText(text)` | 返回单条向量 |
87
+ | `embedBatch(texts)` | 返回向量数组 |
88
+
89
+ ## Memory
90
+
91
+ | 方法 | 说明 |
92
+ | --- | --- |
93
+ | `extract(messages, options?)` | 从对话提取记忆并存储 |
94
+ | `add(entry)` | 手动添加记忆 |
95
+ | `get(memoryId)` / `update(memoryId, updates)` | 读取/更新 |
96
+ | `recall(query, options?)` | 检索相关记忆 |
97
+ | `injectMemories(messages, options?)` | 注入 system 记忆上下文 |
98
+ | `remove(memoryId)` / `clear(options?)` | 删除 |
99
+ | `list(options?)` / `listPage(options?)` | 列表/分页 |
100
+
101
+ 推荐所有记忆操作带 `objectId`,避免不同用户或 Agent 混写。
102
+
103
+ ## Retrieval / RAG
104
+
105
+ ```ts
106
+ await ai.retrieval.addSource({
107
+ id: 'docs',
108
+ name: '产品文档',
109
+ collection: 'doc_vectors',
110
+ topK: 5,
111
+ minScore: 0.7,
112
+ })
113
+
114
+ const result = await ai.rag.query('核心架构是什么?', {
115
+ sources: ['docs'],
116
+ topK: 5,
117
+ })
118
+ ```
119
+
120
+ `retrieve` 会并发检索目标 source 并按 score 合并排序;无 source 时返回 `RETRIEVAL_SOURCE_NOT_FOUND`。
121
+
122
+ ## Knowledge
123
+
124
+ | 方法 | 说明 |
125
+ | --- | --- |
126
+ | `setup(options?)` | 初始化 collection / 表 / 索引 |
127
+ | `ingest(input)` | 文档入库 |
128
+ | `ingestFile(input)` | 从文件导入(Node.js) |
129
+ | `ingestBatch(inputs, onProgress?)` | 批量导入 |
130
+ | `retrieve(query, options?)` | 实体增强检索 |
131
+ | `ask(query, options?)` | 知识库问答 |
132
+ | `findByEntity(entityName, options?)` | 实体关联文档 |
133
+ | `listEntities(options?)` / `listDocuments(options?)` | 列表 |
134
+ | `removeDocument(documentId, options?)` | 删除文档和关联 |
135
+
136
+ 入库链路:parse/clean → chunk → embedding → vecdb upsert → reldb metadata/entity index。
137
+
138
+ ## Context
139
+
140
+ `ai.context.createManager(options)` 返回有状态管理器,适合多轮对话。
141
+
142
+ 常用选项:
143
+
144
+ - `scope: { objectId, sessionId }`
145
+ - `systemPrompt`
146
+ - `compress: { auto, strategy, maxTokens, preserveLastN }`
147
+ - `memory: { enable, enableExtract, topK }`
148
+ - `rag: { enable, sources, topK, minScore }`
149
+ - `tools`
150
+
151
+ 常用方法:`addMessage`、`getMessages`、`getTokenUsage`、`chat`、`chatStream`、`save`、`reset`。
152
+
153
+ ## File / Rerank / Reasoning
154
+
155
+ - `ai.file.parse({ content, filename, options })`:text/html/pdf/docx/ocr 解析。
156
+ - `ai.file.parseText(content, filename?)`:直接返回文本。
157
+ - `ai.rerank.rerank(request)` / `rerankTexts(query, texts, topN?)`:相关性重排。
158
+ - `ai.reasoning.run(query, options?)` / `runStream(query, options?)`:`react`、`cot`、`plan-execute`。
159
+
160
+ ## A2A
161
+
162
+ | 方法 | 说明 |
163
+ | --- | --- |
164
+ | `registerExecutor(executor)` | 注册 Agent executor |
165
+ | `getAgentCard()` | 获取 Agent Card |
166
+ | `handleRequest(body, context?)` | 处理 A2A JSON-RPC 请求 |
167
+ | `listMessages(filter)` | 查询 A2A 消息记录 |
168
+ | `callRemoteAgent(remoteUrl, message, options?)` | 调用远端 Agent |
169
+
170
+ A2A 的 SDK handler 延迟创建;注册 executor 或首次处理请求时才装配运行时对象。
171
+
172
+ ## 错误码速查
173
+
174
+ | 分段 | 代表错误 |
175
+ | --- | --- |
176
+ | `hai:ai:000` | `INTERNAL_ERROR` |
177
+ | `hai:ai:010-012` | 初始化:`NOT_INITIALIZED` / `CONFIGURATION_ERROR` / `INIT_IN_PROGRESS` |
178
+ | `hai:ai:020-033` | Rerank / File |
179
+ | `hai:ai:100-107` | LLM / 历史记录 |
180
+ | `hai:ai:200-204` | MCP |
181
+ | `hai:ai:300-302` | Embedding |
182
+ | `hai:ai:400-403` | Tool |
183
+ | `hai:ai:500-502` | Reasoning |
184
+ | `hai:ai:600-701` | Retrieval / RAG |
185
+ | `hai:ai:800-805` | Knowledge |
186
+ | `hai:ai:900-904` | Memory |
187
+ | `hai:ai:950-971` | Context / Store / Session |
188
+ | `hai:ai:980-984` | A2A |
189
+
190
+ ## 浏览器端
191
+
192
+ 浏览器端通过 `@h-ai/api-client` 或自定义 endpoint 访问服务端 AI 能力。`ai.stream` 可在浏览器直接用于解析服务端流式 chunk。
193
+
194
+ ```ts
195
+ const response = await apiClient.ai.chats.createCompletion({ messages })
196
+ const memories = await apiClient.ai.memories.recall({ query: '偏好', objectId: 'user-001', topK: 5 })
197
+ ```
@@ -94,6 +94,8 @@ await client.init({ baseUrl: 'https://api.example.com/api/v1' })
94
94
  await apiClient.close()
95
95
  ```
96
96
 
97
+ > 已初始化后再次 `init()` 会返回 `CONFIG_ERROR`,不会覆盖现有 client;切换 `baseUrl` / `fetch` / `transport` 前必须先 `close()`,避免旧 transport 会话泄漏。
98
+
97
99
  ## Token Storage 适配器
98
100
 
99
101
  | 工厂调用 | 存储位置 | 适用场景 |
@@ -130,7 +132,7 @@ if (login.success) {
130
132
 
131
133
  | API | 用途 |
132
134
  | --- | --- |
133
- | `apiClient.init(config)` | 初始化默认 API Service client |
135
+ | `apiClient.init(config)` | 初始化默认 API Service client;重复初始化返回 `CONFIG_ERROR` |
134
136
  | `apiClient.close()` | 清理 client 状态 |
135
137
  | `apiClient.auth.setTokens(tokens)` | 写入 access token;非 httpOnly 存储会同时写入 refresh token |
136
138
  | `apiClient.auth.clear()` | 清理 Token |
@@ -55,7 +55,7 @@ description: 以 TDD 方式在应用中创建新功能:先编写测试定义
55
55
 
56
56
  ```
57
57
  src/
58
- hooks.server.ts # Handle Hook 入口
58
+ hooks.server.ts # `handle` hook 入口
59
59
  app.css # 全局样式(TailwindCSS 4)
60
60
  lib/
61
61
  server/
@@ -45,7 +45,7 @@ description: 对应用代码进行审查:检查 TDD 合规性、架构分层
45
45
 
46
46
  ### 架构分层
47
47
 
48
- - [ ] `hooks.server.ts` 仅做中间件编排(初始化、i18n、Handle Hook),无业务逻辑
48
+ - [ ] `hooks.server.ts` 仅做中间件编排(初始化、i18n、`handle` hook),无业务逻辑
49
49
  - [ ] `+page.server.ts` / `+server.ts` 仅做请求处理(守卫 → 校验 → 调用服务 → 响应)
50
50
  - [ ] 业务逻辑集中在 `$lib/server/services/`
51
51
  - [ ] 客户端组件不直接调用数据库或服务端模块
@@ -61,6 +61,8 @@ services:
61
61
  ```typescript
62
62
  import { deploy } from '@h-ai/deploy'
63
63
 
64
+ deploy.credentials.load()
65
+
64
66
  await deploy.init({
65
67
  provider: { type: 'vercel', token: 'vel_xxx' },
66
68
  services: {
@@ -113,9 +115,13 @@ if (result.success) {
113
115
 
114
116
  | 方法 | 签名 | 说明 |
115
117
  | ---------------------- | -------------------------------------------------------------------------- | ------------ |
118
+ | `deploy.credentials.load` | `() => HaiResult<string[]>` | 加载凭证到 `process.env` |
119
+ | `deploy.credentials.save` | `(key: string, value: string) => HaiResult<void>` | 保存单个凭证 |
120
+ | `deploy.credentials.saveAll` | `(entries: Record<string, string>) => HaiResult<void>` | 批量保存凭证 |
121
+ | `deploy.credentials.getPath` | `() => string` | 获取凭证文件路径 |
116
122
  | `deploy.init` | `(config: DeployConfigInput) => Promise<HaiResult<void>>` | 初始化模块 |
117
123
  | `deploy.close` | `() => Promise<void>` | 关闭模块 |
118
- | `deploy.scan` | `(appDir: string) => Promise<HaiResult<ScanResult>>` | 扫描应用 |
124
+ | `deploy.scan` | `(appDir: string) => Promise<HaiResult<ScanResult>>` | 扫描应用(不依赖 init) |
119
125
  | `deploy.provisionAll` | `(projectName: string) => Promise<HaiResult<ProvisionResult[]>>` | 开通所有服务 |
120
126
  | `deploy.deployApp` | `(appDir: string, options?) => Promise<HaiResult<DeployResult>>` | 完整部署 |
121
127
  | `deploy.config` | `DeployConfig \| null` | 当前配置 |
@@ -125,12 +131,9 @@ if (result.success) {
125
131
 
126
132
  ## 凭证管理
127
133
 
128
- | 函数 | 说明 |
129
- | ---------------------------- | ------------------------------------------ |
130
- | `loadCredentials()` | 加载 ~/.hai/credentials.yml 到 process.env |
131
- | `saveCredential(key, value)` | 保存单个凭证 |
132
- | `saveCredentials(entries)` | 批量保存凭证 |
133
- | `getCredentialsPath()` | 获取凭证文件路径 |
134
+ 所有凭证操作都通过 `deploy.credentials.*` 访问,模块入口不再单独导出自由函数。
135
+
136
+ > `deploy.credentials.*()` 与 `deploy.scan()` 都不依赖 `deploy.init()`,可用于 CLI 在读取 `_deploy.yml` 之前准备环境。
134
137
 
135
138
  ---
136
139
 
@@ -147,8 +150,8 @@ if (result.success) {
147
150
  | `HaiDeployError.PROVISION_FAILED` | `hai:deploy:007` | 基础设施开通失败 |
148
151
  | `HaiDeployError.ADAPTER_MISSING` | `hai:deploy:008` | SvelteKit adapter 未安装 |
149
152
  | `HaiDeployError.SCAN_FAILED` | `hai:deploy:009` | 应用扫描失败 |
150
- | `HaiDeployError.ENV_VAR_FAILED` | `hai:deploy:010` | 环境变量设置失败 |
151
- | `HaiDeployError.NOT_INITIALIZED` | `hai:deploy:011` | 模块未初始化 |
153
+ | `HaiDeployError.NOT_INITIALIZED` | `hai:deploy:010` | 模块未初始化 |
154
+ | `HaiDeployError.ENV_VAR_FAILED` | `hai:deploy:011` | 环境变量设置失败 |
152
155
  | `HaiDeployError.UNSUPPORTED_TYPE` | `hai:deploy:012` | 不支持的类型 |
153
156
  | `HaiDeployError.CONFIG_ERROR` | `hai:deploy:013` | 配置错误 |
154
157
  | `HaiDeployError.CREDENTIAL_ERROR` | `hai:deploy:014` | 凭证读写失败 |
@@ -5,7 +5,7 @@ description: 使用 @h-ai/kit 构建 SvelteKit 请求管道、认证守卫、统
5
5
 
6
6
  # hai-kit
7
7
 
8
- > `@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。
8
+ > `@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。
9
9
 
10
10
  ## 使用步骤
11
11
 
@@ -48,10 +48,12 @@ export const POST = kit.handler(async ({ request, locals }) => {
48
48
  ```ts
49
49
  import { kit } from '@h-ai/kit'
50
50
 
51
- const client = kit.client.create({ auth: true })
51
+ const client = kit.client.create()
52
52
  export const { apiFetch } = client
53
53
  ```
54
54
 
55
+ > 同源 endpoint 优先使用 httpOnly Cookie;`auth: true` 只读取 `kit.auth.setBrowserToken()` 写入的页面内存 Token,不会默认读写 localStorage。确需 Bearer Header 时,显式传入 `BrowserTokenStore`,禁止把敏感 Token 存入 localStorage。
56
+
55
57
  ### 4. 同源传输加密
56
58
 
57
59
  kit 不再维护本地传输加密实现;服务端和客户端都统一委托 `@h-ai/crypto` 的 `crypto.transport`。
@@ -100,7 +102,7 @@ export const handle = kit.createHandle({
100
102
  // lib/utils/api.ts —— 业务层只看到 apiFetch
101
103
  import { kit } from '@h-ai/kit'
102
104
 
103
- export const { apiFetch } = kit.client.create({ auth: true })
105
+ export const { apiFetch } = kit.client.create()
104
106
  ```
105
107
 
106
108
  默认协商端点:`/api/_hai/key-exchange`。如 `keyExchangePath` 自定义,浏览器端同步设置 `keyExchangeUrl`。
@@ -13,6 +13,8 @@ description: 使用 @h-ai/serv 将 oRPC contract 挂载为最小 HTTP App 抽象
13
13
 
14
14
  > ⚠️ **服务端模块(Node.js / Fetch Runtime)。** 浏览器端通过 `@h-ai/api-client` 调用由本模块暴露的 HTTP API。
15
15
 
16
+ > 生命周期说明:`@h-ai/serv` 是无状态 HTTP App 装配器,不提供 `init()` / `close()`;依赖模块(iam/storage/ai/crypto 等)由应用先初始化,并在 `serv.listen(..., { onClose })` 中反向释放。`serv.createApp()` 的启动期配置错误会 fail-fast 抛出。
17
+
16
18
  ---
17
19
 
18
20
  ## 适用场景
@@ -5,7 +5,7 @@ description: 使用 @h-ai/ui 构建多端应用界面,包含三层组件架构
5
5
 
6
6
  # hai-ui
7
7
 
8
- > `@h-ai/ui` 是基于 Svelte 5 Runes 的多端 UI 组件库,采用 DaisyUI v5 + Tailwind CSS v4 + Bits UI v2,支持 32 主题、内置中英文 i18n、自动导入。内置 Shiki 代码高亮、Design Token 系统和 7 个移动端组件。
8
+ > `@h-ai/ui` 是基于 Svelte 5 Runes 的多端 UI 组件库,采用 DaisyUI v5 + Tailwind CSS v4 + Bits UI v2,内置 15 个精选 DaisyUI 主题、内置中英文 i18n、自动导入。内置 Shiki 代码高亮、Design Token 系统和 7 个移动端组件。
9
9
 
10
10
  ---
11
11
 
@@ -20,8 +20,9 @@ description: 使用 @h-ai/ui 构建多端应用界面,包含三层组件架构
20
20
  - 构建管理后台页面(表单、表格、弹窗、导航等)
21
21
  - 移动端/App 界面开发(SafeArea、BottomNav、PullRefresh 等)
22
22
  - 使用 Bits UI headless 交互组件(Combobox、DatePicker、Calendar)
23
- - 使用 IAM 场景组件(登录/注册/密码/用户资料表单)
24
- - 使用 Storage 场景组件(文件上传/图片上传/文件列表)
23
+ - 使用 IAM 场景组件(登录/注册/密码/权限守卫/用户资料表单)
24
+ - 使用 Storage 场景组件(文件上传/图片上传/头像上传/文件列表)
25
+ - 使用 CRUD 场景组件(列表过滤、详情抽屉、编辑抽屉、删除确认)
25
26
  - 配置主题切换与 i18n 多语言
26
27
  - 多端平台检测与适配
27
28
 
@@ -146,7 +147,7 @@ export default defineConfig({
146
147
  <meta name="viewport" content="width=device-width, initial-scale=1" />
147
148
  <script>
148
149
  // 防止主题切换闪烁:在 DOM 渲染前应用已保存的主题
149
- (function(){var t=localStorage.getItem('hai-theme');if(t)document.documentElement.setAttribute('data-theme',t)})()
150
+ (function(){var t='light';try{var s=localStorage.getItem('theme');if(s)t=s}catch{}document.documentElement.setAttribute('data-theme',t)})()
150
151
  </script>
151
152
  %sveltekit.head%
152
153
  </head>
@@ -175,12 +176,12 @@ const p = usePlatform()
175
176
 
176
177
  ## 三层组件架构
177
178
 
178
- ### 原子组件(Primitives,21 个)
179
+ ### 原子组件(Primitives,20 个)
179
180
 
180
181
  | 组件 | Props 要点 | 说明 |
181
182
  | ------------ | ------------------------------------------------------------- | -------- |
182
183
  | `Button` | `variant`, `size`, `loading`, `disabled`, `outline`, `circle` | 按钮 |
183
- | `IconButton` | `icon: string \| Snippet`, `tooltip`, `variant`, `size` | 图标按钮 |
184
+ | `IconButton` | `icon: trusted SVG string \| Snippet`, `tooltip`, `variant`, `size` | 图标按钮 |
184
185
  | `Input` | `value`, `type`, `size`, `error`, `placeholder` | 输入框 |
185
186
  | `Textarea` | `value`, `rows`, `autoResize`, `error` | 文本域 |
186
187
  | `Select` | `value`, `options: SelectOption[]`, `placeholder` | 下拉选择 |
@@ -195,7 +196,7 @@ const p = usePlatform()
195
196
  | `Spinner` | `size`, `variant` | 加载动画 |
196
197
  | `Progress` | `value`, `max`, `striped`, `animated` | 进度条 |
197
198
 
198
- ### 组合组件(Compounds,25 + 7 移动端)
199
+ ### 组合组件(Compounds,33 个)
199
200
 
200
201
  由原子组件 + Bits UI headless 交互组合。
201
202
 
@@ -306,6 +307,7 @@ const p = usePlatform()
306
307
  | ------------- | ---------------------------------------------- | -------- |
307
308
  | `FileUpload` | `accept`, `maxSize`, `uploadUrl`, `autoUpload` | 文件上传 |
308
309
  | `ImageUpload` | `value`, `uploadUrl`, `aspectRatio` | 图片上传 |
310
+ | `AvatarUpload` | `value`, `size`, `maxSize`, `fallback` | 头像上传 |
309
311
  | `FileList` | `files: FileItem[]`, `layout`, `showPreview` | 文件列表 |
310
312
 
311
313
  #### AI 场景组件
@@ -313,9 +315,21 @@ const p = usePlatform()
313
315
  | 组件 | 说明 |
314
316
  | -------------------- | --------------------------------- |
315
317
  | `MarkdownRenderer` | Markdown 渲染(内置 Shiki 高亮) |
316
- | `AiDocumentEditor` | AI 文档编辑器 |
318
+ | `AiDocumentDownloadMenu` | AI 文档下载菜单 |
319
+ | `AiDocumentEditor` | AI 文档编辑器(支持受控代码预览) |
320
+ | `AiTableEditor` | AI 表格编辑器 |
317
321
 
318
- > AI 场景组件使用 Shiki(纯 ESM)进行代码高亮,支持 27 种语言,通过 CSS 变量 `--hai-hl-*` 自定义颜色。无需额外安装 Shiki,已内置。
322
+ > AI 场景组件使用 Shiki(纯 ESM)进行代码高亮,支持 27 种语言,通过 CSS 变量 `--hai-hl-*` 自定义颜色。无需额外安装 Shiki,已内置。`AiDocumentEditor` 默认只允许 Markdown 内置预览;HTML / JS / CSS 等高风险预览需要显式启用 `allowUnsafeCodePreview`,或通过 `oncoderun` 返回受控的预览结果。
323
+
324
+ #### CRUD 场景组件
325
+
326
+ | 组件 | 说明 |
327
+ | ------------------- | ---- |
328
+ | `CrudPage` | CRUD 主页面 |
329
+ | `CrudFilterBar` | 过滤工具栏 |
330
+ | `CrudDetailDrawer` | 详情抽屉 |
331
+ | `CrudEditDrawer` | 编辑抽屉 |
332
+ | `CrudDeleteConfirm` | 删除确认框 |
319
333
 
320
334
  ---
321
335
 
@@ -363,7 +377,7 @@ const p = usePlatform()
363
377
 
364
378
  ## 主题系统
365
379
 
366
- 支持 32 个 DaisyUI 主题。
380
+ 支持 15 个精选 DaisyUI 主题。
367
381
 
368
382
  ```typescript
369
383
  import { applyTheme, getCurrentTheme, isDarkTheme, THEMES, THEME_GROUPS } from '@h-ai/ui'
@@ -409,7 +423,7 @@ typescript, javascript, python, java, go, rust, c, cpp, csharp, ruby, php, swift
409
423
 
410
424
  1. **Svelte 5 Runes**:使用 `$state`、`$derived`、`$effect`
411
425
  2. **Snippet 插槽**:使用 `{#snippet name()}...{/snippet}` 语法
412
- 3. **自动导入例外**:`toast`、类型导入、`Range`/`FileList` 必须显式 `import`
426
+ 3. **自动导入例外**:`toast`、类型导入与 `Range` 必须显式 `import`;其余公开 Svelte 组件可自动导入
413
427
  4. **Combobox 统一单选/多选**:`MultiSelect` 已删除
414
428
  5. **移动端样式**:务必引入 `design-tokens.css` + `mobile.css`,使用 SafeArea 包裹原生 App 页面
415
429
  6. **`@source` 必须配置**:未配置则 TailwindCSS 无法扫描 `@h-ai/ui` 组件中的 class,样式会丢失
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/cli-config-templates.ts"],"names":[],"mappings":"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","file":"chunk-BPO34NRL.js","sourcesContent":["/**\n * @h-ai/cli — 配置文件模板\n *\n * 为各模块生成默认配置文件内容。\n * @module cli-config-templates\n */\n\nimport type { AiModuleConfig, CacheModuleConfig, CoreModuleConfig, DbModuleConfig, FeatureId, IamModuleConfig, ModuleConfigs, StorageModuleConfig } from '../cli-types.js'\n\n/**\n * 生成模块配置文件内容\n *\n * @param moduleKey - 模块标识(core/db/cache/iam/storage/ai)\n * @param configs - 用户自定义配置值\n * @returns YAML 格式的配置内容\n */\nexport function generateConfigFile(moduleKey: string, configs?: ModuleConfigs): string {\n switch (moduleKey) {\n case 'core':\n return generateCoreConfig(configs?.core)\n case 'db':\n return generateDbConfig(configs?.db)\n case 'cache':\n return generateCacheConfig(configs?.cache)\n case 'iam':\n return generateIamConfig(configs?.iam)\n case 'storage':\n return generateStorageConfig(configs?.storage)\n case 'ai':\n return generateAiConfig(configs?.ai)\n case 'deploy':\n return generateDeployConfig()\n case 'vecdb':\n return generateVecdbConfig()\n case 'reach':\n return generateReachConfig()\n case 'scheduler':\n return generateSchedulerConfig()\n case 'audit':\n return generateAuditConfig()\n case 'payment':\n return generatePaymentConfig()\n default:\n return `# ${moduleKey} 配置\\n`\n }\n}\n\nfunction generateCoreConfig(cfg?: CoreModuleConfig): string {\n const name = cfg?.name ?? 'my-app'\n const locale = cfg?.defaultLocale ?? 'zh-CN'\n const supportedLocales = locale === 'en-US'\n ? ` - en-US\\n - zh-CN`\n : ` - zh-CN\\n - en-US`\n\n return `# =============================================================================\n# 应用配置\n# =============================================================================\n\nname: ${name}\nversion: 0.1.0\nenv: \\${HAI_ENV:development}\ndebug: \\${HAI_DEBUG:false}\n\ndefaultLocale: ${locale}\nsupportedLocales:\n${supportedLocales}\n`\n}\n\nfunction generateDbConfig(cfg?: DbModuleConfig): string {\n const dbType = cfg?.type ?? 'sqlite'\n const database = cfg?.database ?? (dbType === 'sqlite' ? './data/app.db' : 'hai')\n const host = cfg?.host ?? 'localhost'\n const port = cfg?.port ?? (dbType === 'postgresql' ? 5432 : 3306)\n\n if (dbType === 'sqlite') {\n return `# =============================================================================\n# 数据库配置\n# =============================================================================\n\n# 数据库类型: sqlite | postgresql | mysql\ntype: sqlite\n\n# SQLite 数据库路径\ndatabase: \\${HAI_RELDB_DATABASE:${database}}\n\n# PostgreSQL/MySQL 配置(可选)\n# host: \\${HAI_RELDB_HOST:localhost}\n# port: \\${HAI_RELDB_PORT:5432}\n# user: \\${HAI_RELDB_USER:postgres}\n# password: \\${HAI_RELDB_PASSWORD:}\n`\n }\n\n const user = dbType === 'postgresql' ? 'postgres' : 'root'\n\n return `# =============================================================================\n# 数据库配置\n# =============================================================================\n\n# 数据库类型: sqlite | postgresql | mysql\ntype: ${dbType}\n\n# 数据库名称\ndatabase: \\${HAI_RELDB_DATABASE:${database}}\n\n# 连接配置\nhost: \\${HAI_RELDB_HOST:${host}}\nport: \\${HAI_RELDB_PORT:${port}}\nuser: \\${HAI_RELDB_USER:${user}}\npassword: \\${HAI_RELDB_PASSWORD:}\n`\n}\n\nfunction generateCacheConfig(cfg?: CacheModuleConfig): string {\n const cacheType = cfg?.type ?? 'memory'\n\n if (cacheType === 'memory') {\n return `# =============================================================================\n# 缓存配置\n# =============================================================================\n\n# 缓存类型: memory | redis\ntype: memory\n\n# Redis 配置(当 type 为 redis 时使用)\n# url: \\${HAI_CACHE_REDIS_URL:redis://localhost:6379/0}\n# host: \\${HAI_CACHE_REDIS_HOST:localhost}\n# port: \\${HAI_CACHE_REDIS_PORT:6379}\n# password: \\${HAI_CACHE_REDIS_PASSWORD:}\n# keyPrefix: \\${HAI_CACHE_KEY_PREFIX:hai:}\n`\n }\n\n const host = cfg?.host ?? 'localhost'\n const port = cfg?.port ?? 6379\n\n return `# =============================================================================\n# 缓存配置\n# =============================================================================\n\n# 缓存类型: memory | redis\ntype: redis\n\n# Redis 配置\nhost: \\${HAI_CACHE_REDIS_HOST:${host}}\nport: \\${HAI_CACHE_REDIS_PORT:${port}}\npassword: \\${HAI_CACHE_REDIS_PASSWORD:}\nkeyPrefix: \\${HAI_CACHE_KEY_PREFIX:hai:}\n`\n}\n\nfunction generateIamConfig(cfg?: IamModuleConfig): string {\n const loginPassword = cfg?.loginPassword ?? true\n const loginOtp = cfg?.loginOtp ?? false\n\n return `# =============================================================================\n# IAM 配置\n# =============================================================================\n\n# 登录配置\nlogin:\n password: ${loginPassword}\n otp: ${loginOtp}\n ldap: false\n\n# 密码策略\npassword:\n minLength: 8\n maxLength: 128\n requireUppercase: false\n requireLowercase: false\n requireNumber: false\n requireSpecialChar: false\n\n# 会话配置\nsession:\n maxAge: 86400 # 会话超时(秒),默认 24 小时\n sliding: true # 滑动窗口(每次请求刷新过期时间)\n singleDevice: false # 单设备登录\n refreshTokenMaxAge: 604800 # refreshToken 过期(秒),默认 7 天\n\n# RBAC 配置\nrbac:\n defaultRole: user\n\n# 是否自动创建默认数据\nseedDefaultData: true\n`\n}\n\nfunction generateStorageConfig(cfg?: StorageModuleConfig): string {\n const storageType = cfg?.type ?? 'local'\n\n if (storageType === 'local') {\n const localPath = cfg?.localPath ?? './data/uploads'\n return `# =============================================================================\n# 存储配置\n# =============================================================================\n\n# 默认 Provider\ndefaultProvider: local\n\n# Provider 配置\nproviders:\n local:\n type: local\n root: \\${HAI_STORAGE_PATH:${localPath}}\n maxFileSize: 10485760 # 10MB\n\n # S3 配置(可选)\n # s3:\n # type: s3\n # bucket: \\${HAI_STORAGE_S3_BUCKET}\n # region: \\${HAI_STORAGE_S3_REGION:us-east-1}\n # accessKeyId: \\${HAI_STORAGE_S3_ACCESS_KEY}\n # secretAccessKey: \\${HAI_STORAGE_S3_SECRET_KEY}\n # endpoint: \\${HAI_STORAGE_S3_ENDPOINT}\n # forcePathStyle: \\${HAI_STORAGE_S3_FORCE_PATH_STYLE:false}\n`\n }\n\n return `# =============================================================================\n# 存储配置\n# =============================================================================\n\n# 默认 Provider\ndefaultProvider: s3\n\n# Provider 配置\nproviders:\n s3:\n type: s3\n bucket: \\${HAI_STORAGE_S3_BUCKET}\n region: \\${HAI_STORAGE_S3_REGION:us-east-1}\n accessKeyId: \\${HAI_STORAGE_S3_ACCESS_KEY}\n secretAccessKey: \\${HAI_STORAGE_S3_SECRET_KEY}\n # endpoint: \\${HAI_STORAGE_S3_ENDPOINT}\n # forcePathStyle: \\${HAI_STORAGE_S3_FORCE_PATH_STYLE:false}\n\n # 本地存储(可选)\n # local:\n # type: local\n # root: \\${HAI_STORAGE_PATH:./data/uploads}\n # maxFileSize: 10485760 # 10MB\n`\n}\n\nfunction generateAiConfig(cfg?: AiModuleConfig): string {\n const model = cfg?.model ?? 'gpt-4o-mini'\n\n // AIConfigSchema 结构:llm(必填)+ 可选子模块\n // LLMConfigSchema 支持顶层 apiKey/model,以及多模型 models 数组\n return `# =============================================================================\n# AI 配置\n# =============================================================================\n\n# LLM 配置(必填)\nllm:\n # API Key(留空时自动读取 HAI_AI_LLM_API_KEY / OPENAI_API_KEY 环境变量)\n apiKey: \\${HAI_AI_LLM_API_KEY:}\n # Base URL(留空时自动读取 HAI_AI_LLM_BASE_URL / OPENAI_BASE_URL,默认 https://api.openai.com/v1)\n # baseUrl: \\${HAI_AI_LLM_BASE_URL:}\n # 默认模型\n model: ${model}\n # 全局最大 Token 数(默认 4096)\n # maxTokens: 4096\n # 采样温度(0-2,默认 0.7)\n # temperature: 0.7\n # 请求超时(毫秒,默认 60000)\n # timeout: 60000\n\n # 多模型配置(可选,用于场景路由)\n # models:\n # - id: fast\n # model: gpt-4o-mini\n # - id: smart\n # model: gpt-4o\n # apiKey: \\${HAI_AI_LLM_API_KEY:}\n\n # 场景模型映射(可选)\n # scenarios:\n # default: fast\n # analysis: smart\n`\n}\n\n/**\n * 根据选中的功能模块生成 .env.example 内容\n *\n * @param features - 选中的功能模块列表\n * @param configs - 用户自定义配置值\n * @returns .env.example 文件内容\n */\nexport function generateEnvExample(features: FeatureId[], configs?: ModuleConfigs): string {\n const sections: string[] = []\n\n // 文件头\n sections.push(`# =============================================================================\n# Environment Variables\n# =============================================================================\n#\n# Copy this file to .env and fill in actual values.\n# Config files in config/ reference these variables via \\${VAR_NAME:default} syntax.\n#\n# Naming convention: HAI_<MODULE>_<SETTING>\n# =============================================================================`)\n\n // 应用基础(始终生成)\n sections.push(`\n# =============================================================================\n# Application\n# =============================================================================\n# Environment: development | production | test\nHAI_ENV=development\n# Enable debug mode\nHAI_DEBUG=false`)\n\n // 数据库\n if (features.includes('db')) {\n const dbType = configs?.db?.type ?? 'sqlite'\n const dbDatabase = configs?.db?.database ?? (dbType === 'sqlite' ? './data/app.db' : 'hai')\n const isSqlite = dbType === 'sqlite'\n sections.push(`\n# =============================================================================\n# Database (@h-ai/reldb)\n# =============================================================================\n# Database type: sqlite | postgresql | mysql\nHAI_RELDB_TYPE=${dbType}\n# SQLite: file path; PostgreSQL/MySQL: database name\nHAI_RELDB_DATABASE=${dbDatabase}${isSqlite\n ? `\n# PostgreSQL/MySQL connection (uncomment when not using sqlite)\n# HAI_RELDB_HOST=localhost\n# HAI_RELDB_PORT=5432\n# HAI_RELDB_USER=postgres\n# HAI_RELDB_PASSWORD=`\n : `\n# Connection\nHAI_RELDB_HOST=${configs?.db?.host ?? 'localhost'}\nHAI_RELDB_PORT=${configs?.db?.port ?? (dbType === 'postgresql' ? 5432 : 3306)}\nHAI_RELDB_USER=${dbType === 'postgresql' ? 'postgres' : 'root'}\nHAI_RELDB_PASSWORD=`}`)\n }\n\n // IAM / Session\n if (features.includes('iam')) {\n sections.push(`\n# =============================================================================\n# IAM (@h-ai/iam)\n# =============================================================================\nHAI_IAM_SESSION_SECRET=change-me-to-a-strong-random-string-min-32-chars\n# HAI_IAM_PASSWORD_MIN_LENGTH=8\n# HAI_IAM_SESSION_MAX_AGE=86400\n# HAI_IAM_REFRESH_TOKEN_MAX_AGE=604800\n# HAI_IAM_MAX_LOGIN_ATTEMPTS=5\n# HAI_KIT_COOKIE_KEY= # 32-char hex for SM4-CBC cookie encryption\n`)\n }\n\n // 缓存\n if (features.includes('cache')) {\n const cacheType = configs?.cache?.type ?? 'memory'\n if (cacheType === 'redis') {\n sections.push(`\n# =============================================================================\n# Cache (@h-ai/cache)\n# =============================================================================\n# Cache type: memory | redis\nHAI_CACHE_TYPE=redis\n# Redis connection\nHAI_CACHE_REDIS_HOST=${configs?.cache?.host ?? 'localhost'}\nHAI_CACHE_REDIS_PORT=${configs?.cache?.port ?? 6379}\nHAI_CACHE_REDIS_PASSWORD=\n# HAI_CACHE_REDIS_URL=redis://localhost:6379/0\n# HAI_CACHE_REDIS_DB=0\n# HAI_CACHE_CONNECT_TIMEOUT=10000\n# HAI_CACHE_COMMAND_TIMEOUT=5000\n# HAI_CACHE_KEY_PREFIX=hai:`)\n }\n else {\n sections.push(`\n# =============================================================================\n# Cache (@h-ai/cache)\n# =============================================================================\n# Cache type: memory | redis\nHAI_CACHE_TYPE=memory\n# Redis connection (uncomment when type=redis)\n# HAI_CACHE_REDIS_URL=redis://localhost:6379/0\n# HAI_CACHE_REDIS_HOST=localhost\n# HAI_CACHE_REDIS_PORT=6379\n# HAI_CACHE_REDIS_PASSWORD=\n# HAI_CACHE_REDIS_DB=0\n# HAI_CACHE_CONNECT_TIMEOUT=10000\n# HAI_CACHE_COMMAND_TIMEOUT=5000\n# HAI_CACHE_KEY_PREFIX=hai:`)\n }\n }\n\n // 存储\n if (features.includes('storage')) {\n const storageType = configs?.storage?.type ?? 'local'\n if (storageType === 's3') {\n sections.push(`\n# =============================================================================\n# Storage (@h-ai/storage)\n# =============================================================================\n# Storage type: local | s3\nHAI_STORAGE_TYPE=s3\n# S3 / S3-compatible\nHAI_STORAGE_S3_BUCKET=\nHAI_STORAGE_S3_REGION=us-east-1\nHAI_STORAGE_S3_ACCESS_KEY=\nHAI_STORAGE_S3_SECRET_KEY=\n# HAI_STORAGE_S3_ENDPOINT= # Custom endpoint for MinIO / Aliyun OSS etc.\n# HAI_STORAGE_S3_FORCE_PATH_STYLE=false\n# Local storage (uncomment when type=local)\n# HAI_STORAGE_PATH=./data/uploads`)\n }\n else {\n sections.push(`\n# =============================================================================\n# Storage (@h-ai/storage)\n# =============================================================================\n# Storage type: local | s3\nHAI_STORAGE_TYPE=local\n# Local storage root path\nHAI_STORAGE_PATH=${configs?.storage?.localPath ?? './data/uploads'}\n# S3 / S3-compatible (uncomment when type=s3)\n# HAI_STORAGE_S3_BUCKET=\n# HAI_STORAGE_S3_REGION=us-east-1\n# HAI_STORAGE_S3_ACCESS_KEY=\n# HAI_STORAGE_S3_SECRET_KEY=\n# HAI_STORAGE_S3_ENDPOINT= # Custom endpoint for MinIO / Aliyun OSS etc.\n# HAI_STORAGE_S3_FORCE_PATH_STYLE=false`)\n }\n }\n\n // AI\n if (features.includes('ai')) {\n const provider = configs?.ai?.defaultProvider ?? 'openai'\n if (provider === 'anthropic') {\n sections.push(`\n# =============================================================================\n# AI (@h-ai/ai)\n# =============================================================================\n# OpenAI-compatible API Key (Anthropic models via OpenAI-compatible proxy)\nHAI_AI_LLM_API_KEY=\n# HAI_AI_LLM_BASE_URL= # Custom base URL\n# Optional compatibility fallback\n# OPENAI_API_KEY=`)\n }\n else if (provider === 'openai') {\n sections.push(`\n# =============================================================================\n# AI (@h-ai/ai)\n# =============================================================================\n# OpenAI / OpenAI-compatible\nHAI_AI_LLM_API_KEY=\n# HAI_AI_LLM_BASE_URL= # Custom base URL (e.g. local proxy, Azure)\n# Optional compatibility fallback\n# OPENAI_API_KEY=`)\n }\n else {\n sections.push(`\n# =============================================================================\n# AI (@h-ai/ai)\n# =============================================================================\n# OpenAI-compatible provider\nHAI_AI_LLM_API_KEY=\n# HAI_AI_LLM_BASE_URL= # Custom base URL\n# Optional compatibility fallback\n# OPENAI_API_KEY=`)\n }\n }\n\n // VecDB\n if (features.includes('vecdb')) {\n sections.push(`\n# =============================================================================\n# Vector Database (@h-ai/vecdb)\n# =============================================================================\n# Backend type: lancedb | pgvector | qdrant\nHAI_VECDB_TYPE=lancedb\n# LanceDB data path\nHAI_VECDB_PATH=./data/vecdb\n# Qdrant (uncomment when type=qdrant)\n# HAI_VECDB_QDRANT_URL=http://localhost:6333\n# HAI_VECDB_QDRANT_API_KEY=\n`)\n }\n\n // Reach\n if (features.includes('reach')) {\n sections.push(`\n# =============================================================================\n# Reach (@h-ai/reach)\n# =============================================================================\n# SMTP (uncomment when enabling email provider)\n# HAI_REACH_SMTP_HOST=smtp.example.com\n# HAI_REACH_SMTP_PORT=465\n# HAI_REACH_SMTP_USER=\n# HAI_REACH_SMTP_PASS=\n# HAI_REACH_SMTP_FROM=noreply@example.com\n`)\n }\n\n // Payment\n if (features.includes('payment')) {\n sections.push(`\n# =============================================================================\n# Payment (@h-ai/payment)\n# =============================================================================\n# WeChat Pay\n# HAI_PAYMENT_WECHAT_MCH_ID=\n# HAI_PAYMENT_WECHAT_API_V3_KEY=\n# HAI_PAYMENT_WECHAT_SERIAL_NO=\n# HAI_PAYMENT_WECHAT_PRIVATE_KEY=\n# HAI_PAYMENT_WECHAT_APP_ID=\n# Alipay\n# HAI_PAYMENT_ALIPAY_APP_ID=\n# HAI_PAYMENT_ALIPAY_PRIVATE_KEY=\n# HAI_PAYMENT_ALIPAY_PUBLIC_KEY=\n# Stripe\n# HAI_PAYMENT_STRIPE_SECRET_KEY=\n# HAI_PAYMENT_STRIPE_WEBHOOK_SECRET=\n`)\n }\n\n // 测试(始终生成)\n sections.push(`\n# =============================================================================\n# Testing\n# =============================================================================\n# E2E test mode (relaxes rate limiting etc.)\n# HAI_E2E=1\n`)\n\n return sections.join('\\n')\n}\n\nfunction generateDeployConfig(): string {\n return `# =============================================================================\n# 部署配置 (@h-ai/deploy)\n# =============================================================================\n# 部署平台凭证通过 ~/.hai/credentials.yml 管理\n# 环境变量引用格式: \\${VAR_NAME:default_value}\n\n# 部署平台\nprovider:\n type: vercel\n token: \\${HAI_DEPLOY_VERCEL_TOKEN}\n\n# 基础设施服务(按需开启)\nservices:\n # PostgreSQL 数据库 (Neon)\n # db:\n # provisioner: neon\n # apiKey: \\${HAI_DEPLOY_NEON_API_KEY}\n\n # Redis 缓存 (Upstash)\n # cache:\n # provisioner: upstash\n # email: \\${HAI_DEPLOY_UPSTASH_EMAIL}\n # apiKey: \\${HAI_DEPLOY_UPSTASH_API_KEY}\n\n # S3 存储 (Cloudflare R2)\n # storage:\n # provisioner: cloudflare-r2\n # accountId: \\${HAI_DEPLOY_CF_ACCOUNT_ID}\n # apiToken: \\${HAI_DEPLOY_CF_API_TOKEN}\n\n # 邮件 (Resend)\n # email:\n # provisioner: resend\n # apiKey: \\${HAI_DEPLOY_RESEND_API_KEY}\n\n # 短信 (阿里云)\n # sms:\n # provisioner: aliyun\n # accessKeyId: \\${HAI_DEPLOY_ALIYUN_ACCESS_KEY_ID}\n # accessKeySecret: \\${HAI_DEPLOY_ALIYUN_ACCESS_KEY_SECRET}\n`\n}\n\nfunction generateVecdbConfig(): string {\n return `# =============================================================================\n# 向量数据库配置 (@h-ai/vecdb)\n# =============================================================================\n\n# 数据库类型: lancedb | pgvector | qdrant\ntype: lancedb\n\n# LanceDB 数据目录\npath: \\${HAI_VECDB_PATH:./data/vecdb}\n\n# 距离度量: cosine | euclidean | dot\n# metric: cosine\n\n# pgvector 配置(当 type 为 pgvector 时使用)\n# type: pgvector\n# host: \\${HAI_RELDB_HOST:localhost}\n# port: \\${HAI_RELDB_PORT:5432}\n# database: \\${HAI_RELDB_DATABASE:hai}\n# user: \\${HAI_RELDB_USER:postgres}\n# password: \\${HAI_RELDB_PASSWORD:}\n# indexType: hnsw\n# tablePrefix: vec_\n\n# Qdrant 配置(当 type 为 qdrant 时使用)\n# type: qdrant\n# url: \\${HAI_VECDB_QDRANT_URL:http://localhost:6333}\n# apiKey: \\${HAI_VECDB_QDRANT_API_KEY:}\n`\n}\n\nfunction generateReachConfig(): string {\n return `# =============================================================================\n# 消息推送配置 (@h-ai/reach)\n# =============================================================================\n\nproviders:\n # 控制台输出(开发/测试用)\n - name: console_dev\n type: console\n\n # SMTP 邮件(按需开启)\n # - name: email\n # type: smtp\n # host: \\${HAI_REACH_SMTP_HOST:smtp.example.com}\n # port: \\${HAI_REACH_SMTP_PORT:465}\n # secure: true\n # user: \\${HAI_REACH_SMTP_USER:}\n # pass: \\${HAI_REACH_SMTP_PASS:}\n # from: \\${HAI_REACH_SMTP_FROM:noreply@example.com}\n\n # 阿里云短信(按需开启)\n # - name: sms\n # type: aliyun-sms\n # accessKeyId: \\${HAI_REACH_SMS_ACCESS_KEY}\n # accessKeySecret: \\${HAI_REACH_SMS_SECRET_KEY}\n # signName: MyApp\n\n# 模板(可选)\n# templates:\n# - name: verification_code\n# provider: email\n# subject: \"验证码: {code}\"\n# body: \"您的验证码是 {code},有效期 {minutes} 分钟。\"\n\n# 免打扰(可选)\n# dnd:\n# enabled: true\n# strategy: delay\n# start: \"22:00\"\n# end: \"08:00\"\n`\n}\n\nfunction generateSchedulerConfig(): string {\n return `# =============================================================================\n# 任务调度配置 (@h-ai/scheduler)\n# =============================================================================\n\n# 是否启用数据库日志(需要 @h-ai/reldb)\nenableDb: true\n\n# 执行日志表名\ntableName: hai_scheduler_logs\n\n# 任务定义表名\ntaskTableName: hai_scheduler_tasks\n\n# 分布式锁表名\nlockTableName: hai_scheduler_locks\n\n# 检查间隔(毫秒)\ntickInterval: 1000\n\n# 锁过期时间(毫秒)\nlockExpireMs: 300000\n`\n}\n\nfunction generateAuditConfig(): string {\n return `# =============================================================================\n# 审计日志配置 (@h-ai/audit)\n# =============================================================================\n\n# 审计日志表名\ntableName: hai_audit_logs\n\n# 用户表名(用于 JOIN 查询)\nuserTable: hai_iam_users\n\n# 用户表主键列名\nuserIdColumn: id\n\n# 用户名列名\nuserNameColumn: username\n`\n}\n\nfunction generatePaymentConfig(): string {\n return `# =============================================================================\n# 支付配置 (@h-ai/payment)\n# =============================================================================\n\n# 微信支付(按需开启)\n# wechat:\n# mchId: \\${HAI_PAYMENT_WECHAT_MCH_ID}\n# apiV3Key: \\${HAI_PAYMENT_WECHAT_API_V3_KEY}\n# serialNo: \\${HAI_PAYMENT_WECHAT_SERIAL_NO}\n# privateKey: \\${HAI_PAYMENT_WECHAT_PRIVATE_KEY}\n# appId: \\${HAI_PAYMENT_WECHAT_APP_ID}\n\n# 支付宝(按需开启)\n# alipay:\n# appId: \\${HAI_PAYMENT_ALIPAY_APP_ID}\n# privateKey: \\${HAI_PAYMENT_ALIPAY_PRIVATE_KEY}\n# alipayPublicKey: \\${HAI_PAYMENT_ALIPAY_PUBLIC_KEY}\n# signType: RSA2\n# sandbox: false\n\n# Stripe(按需开启)\n# stripe:\n# secretKey: \\${HAI_PAYMENT_STRIPE_SECRET_KEY}\n# webhookSecret: \\${HAI_PAYMENT_STRIPE_WEBHOOK_SECRET}\n`\n}\n"]}
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
- export { generateConfigFile, generateEnvExample } from './chunk-BPO34NRL.js';
3
- import './chunk-2H7UOFLK.js';
4
- //# sourceMappingURL=cli-config-templates-JCS7T3NU.js.map
5
- //# sourceMappingURL=cli-config-templates-JCS7T3NU.js.map