@h-ai/cli 0.1.0-alpha.10
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/LICENSE +202 -0
- package/README.md +167 -0
- package/dist/chunk-2H7UOFLK.js +10 -0
- package/dist/chunk-2H7UOFLK.js.map +1 -0
- package/dist/chunk-LANIDJC7.js +659 -0
- package/dist/chunk-LANIDJC7.js.map +1 -0
- package/dist/chunk-YV7WPUI6.js +206 -0
- package/dist/chunk-YV7WPUI6.js.map +1 -0
- package/dist/config-templates-S5RI2MC6.js +5 -0
- package/dist/config-templates-S5RI2MC6.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1650 -0
- package/dist/index.js.map +1 -0
- package/dist/skill-templates-N5DU5FNX.js +5 -0
- package/dist/skill-templates-N5DU5FNX.js.map +1 -0
- package/dist/src-XJ6YXNAF.js +15030 -0
- package/dist/src-XJ6YXNAF.js.map +1 -0
- package/package.json +59 -0
- package/templates/README.md +126 -0
- package/templates/apps/admin/messages/en-US.json +33 -0
- package/templates/apps/admin/messages/zh-CN.json +33 -0
- package/templates/apps/admin/src/routes/+layout.svelte.hbs +30 -0
- package/templates/apps/admin/src/routes/+page.svelte.hbs +35 -0
- package/templates/apps/admin/src/routes/admin/+layout.svelte.hbs +44 -0
- package/templates/apps/admin/src/routes/admin/+page.svelte.hbs +45 -0
- package/templates/apps/admin/src/routes/admin/settings/+page.svelte.hbs +37 -0
- package/templates/apps/admin/src/routes/api/health/+server.ts +12 -0
- package/templates/apps/android-app/.env.hbs +3 -0
- package/templates/apps/android-app/capacitor.config.ts.hbs +12 -0
- package/templates/apps/android-app/messages/en-US.json +24 -0
- package/templates/apps/android-app/messages/zh-CN.json +24 -0
- package/templates/apps/android-app/src/lib/api.ts.hbs +30 -0
- package/templates/apps/android-app/src/lib/capacitor.ts +21 -0
- package/templates/apps/android-app/src/routes/+layout.svelte.hbs +42 -0
- package/templates/apps/android-app/src/routes/+layout.ts +7 -0
- package/templates/apps/android-app/src/routes/+page.svelte.hbs +27 -0
- package/templates/apps/api/src/routes/+layout.svelte +14 -0
- package/templates/apps/api/src/routes/+page.svelte +11 -0
- package/templates/apps/api/src/routes/api/v1/health/+server.ts +14 -0
- package/templates/apps/api/src/routes/api/v1/items/+server.ts +37 -0
- package/templates/apps/api/src/routes/api/v1/items/[id]/+server.ts +30 -0
- package/templates/apps/h5/messages/en-US.json +37 -0
- package/templates/apps/h5/messages/zh-CN.json +37 -0
- package/templates/apps/h5/src/routes/+layout.svelte.hbs +57 -0
- package/templates/apps/h5/src/routes/+page.svelte.hbs +27 -0
- package/templates/apps/h5/src/routes/discover/+page.svelte.hbs +27 -0
- package/templates/apps/h5/src/routes/profile/+page.svelte.hbs +27 -0
- package/templates/apps/website/messages/en-US.json +32 -0
- package/templates/apps/website/messages/zh-CN.json +32 -0
- package/templates/apps/website/src/routes/+layout.svelte.hbs +66 -0
- package/templates/apps/website/src/routes/+page.svelte.hbs +33 -0
- package/templates/apps/website/src/routes/about/+page.svelte.hbs +27 -0
- package/templates/apps/website/src/routes/api/health/+server.ts +12 -0
- package/templates/apps/website/src/routes/contact/+page.svelte.hbs +59 -0
- package/templates/apps/website/src/routes/services/+page.svelte.hbs +63 -0
- package/templates/base/e2e/helpers.ts +49 -0
- package/templates/base/package.json.hbs +67 -0
- package/templates/base/playwright.config.ts +32 -0
- package/templates/base/src/app.css +2 -0
- package/templates/base/src/app.d.ts.hbs +18 -0
- package/templates/base/src/app.html.hbs +16 -0
- package/templates/base/src/hooks.server.ts.hbs +123 -0
- package/templates/base/src/lib/server/init.ts.hbs +190 -0
- package/templates/base/svelte.config.js.hbs +30 -0
- package/templates/base/tsconfig.json +8 -0
- package/templates/base/vite.config.ts.hbs +27 -0
- package/templates/features/ai/routes/api/chat/+server.ts +26 -0
- package/templates/features/datapipe/routes/api/datapipe/pipeline/+server.ts +41 -0
- package/templates/features/iam/routes-admin/(auth)/+layout.svelte.hbs +21 -0
- package/templates/features/iam/routes-admin/(auth)/auth/login/+page.svelte.hbs +98 -0
- package/templates/features/iam/routes-admin/(auth)/auth/register/+page.svelte.hbs +124 -0
- package/templates/features/iam/routes-h5/auth/login/+page.svelte.hbs +98 -0
- package/templates/features/iam/routes-h5/auth/register/+page.svelte.hbs +114 -0
- package/templates/features/iam/routes-shared/api/auth/login/+server.ts +32 -0
- package/templates/features/iam/routes-shared/api/auth/logout/+server.ts +15 -0
- package/templates/features/iam/routes-shared/api/auth/me/+server.ts +12 -0
- package/templates/features/iam/routes-shared/api/auth/register/+server.ts +26 -0
- package/templates/features/payment/routes/api/v1/payment/create/+server.ts +30 -0
- package/templates/features/payment/routes/api/v1/payment/notify/[provider]/+server.ts +42 -0
- package/templates/features/payment/routes/api/v1/payment/query/[orderNo]/+server.ts +25 -0
- package/templates/features/storage/routes/api/upload/+server.ts +35 -0
- package/templates/features/vecdb/routes/api/vecdb/search/+server.ts +36 -0
- package/templates/i18n/project.inlang/settings.json +11 -0
- package/templates/skills/AGENTS.md +26 -0
- package/templates/skills/CLAUDE.md +12 -0
- package/templates/skills/copilot-instructions.md +61 -0
- package/templates/skills/hai-ai/SKILL.md +721 -0
- package/templates/skills/hai-api-client/SKILL.md +355 -0
- package/templates/skills/hai-app-create/SKILL.md +371 -0
- package/templates/skills/hai-app-review/SKILL.md +156 -0
- package/templates/skills/hai-app-tests/SKILL.md +468 -0
- package/templates/skills/hai-audit/SKILL.md +145 -0
- package/templates/skills/hai-build/SKILL.md +319 -0
- package/templates/skills/hai-cache/SKILL.md +190 -0
- package/templates/skills/hai-capacitor/SKILL.md +377 -0
- package/templates/skills/hai-core/SKILL.md +484 -0
- package/templates/skills/hai-crypto/SKILL.md +198 -0
- package/templates/skills/hai-datapipe/SKILL.md +220 -0
- package/templates/skills/hai-deploy/SKILL.md +216 -0
- package/templates/skills/hai-iam/SKILL.md +361 -0
- package/templates/skills/hai-kit/SKILL.md +484 -0
- package/templates/skills/hai-payment/SKILL.md +275 -0
- package/templates/skills/hai-reach/SKILL.md +315 -0
- package/templates/skills/hai-reldb/SKILL.md +465 -0
- package/templates/skills/hai-scheduler/SKILL.md +188 -0
- package/templates/skills/hai-storage/SKILL.md +276 -0
- package/templates/skills/hai-ui/SKILL.md +438 -0
- package/templates/skills/hai-vecdb/SKILL.md +279 -0
- package/templates/skills/opencode.json +11 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hai-datapipe
|
|
3
|
+
description: 使用 @h-ai/datapipe 进行文本清洗(HTML/URL/空白移除)、多模式分块(句子/段落/Markdown/字符/自定义)和管线组合;当需求涉及文本预处理、文档分块、数据清洗或 RAG 入库前处理时使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# hai-datapipe
|
|
7
|
+
|
|
8
|
+
> `@h-ai/datapipe` 提供文本清洗(clean)、多模式分块(chunk)和可组合管线(pipeline),纯函数模块,无需初始化。
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 运行环境
|
|
13
|
+
|
|
14
|
+
> **服务端模块(Node.js only)。** 通常在 AI 知识库入库或文档预处理场景中使用,由 `@h-ai/ai` 内部调用或在服务端显式调用。
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 适用场景
|
|
19
|
+
|
|
20
|
+
- 文本清洗:移除 HTML 标签、URL、Email,标准化空白
|
|
21
|
+
- 文本分块:句子、段落、Markdown 标题、字数、字符、自定义分隔符
|
|
22
|
+
- RAG 入库前的文档预处理管线
|
|
23
|
+
- 管线模式组合多步清洗 + 分块 + 自定义转换
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 使用步骤
|
|
28
|
+
|
|
29
|
+
### 直接调用(无需 init)
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { datapipe } from '@h-ai/datapipe'
|
|
33
|
+
|
|
34
|
+
// 清洗
|
|
35
|
+
const cleaned = datapipe.clean(htmlText, { removeHtml: true, removeUrls: true })
|
|
36
|
+
|
|
37
|
+
// 分块
|
|
38
|
+
const chunks = datapipe.chunk(cleaned.data, { mode: 'markdown', maxSize: 2000, overlap: 200 })
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 管线模式
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
const result = await datapipe.pipeline()
|
|
45
|
+
.clean({ removeHtml: true, removeUrls: true })
|
|
46
|
+
.transform(text => text.toLowerCase())
|
|
47
|
+
.chunk({ mode: 'paragraph', maxSize: 1000, overlap: 100 })
|
|
48
|
+
.chunkTransform(chunks => chunks.filter(c => c.content.length > 50))
|
|
49
|
+
.run(rawText)
|
|
50
|
+
|
|
51
|
+
if (result.success) {
|
|
52
|
+
// result.data => { text: string, chunks: DataChunk[] }
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 核心 API
|
|
59
|
+
|
|
60
|
+
### 清洗 — `datapipe.clean`
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
datapipe.clean(text: string, options?: CleanOptionsInput): HaiResult<string>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**CleanOptionsInput**:
|
|
67
|
+
|
|
68
|
+
| 字段 | 类型 | 默认 | 说明 |
|
|
69
|
+
| -------------------- | ------------------ | ----- | ------------------------ |
|
|
70
|
+
| `removeHtml` | `boolean` | true | 移除 HTML 标签 |
|
|
71
|
+
| `removeUrls` | `boolean` | false | 移除 URL |
|
|
72
|
+
| `removeEmails` | `boolean` | false | 移除 Email 地址 |
|
|
73
|
+
| `normalizeWhitespace`| `boolean` | true | 多空格→单空格、去多余空行 |
|
|
74
|
+
| `trim` | `boolean` | true | 去除首尾空白 |
|
|
75
|
+
| `customReplacements` | `{ pattern, replacement }[]` | — | 自定义正则替换规则 |
|
|
76
|
+
|
|
77
|
+
### 分块 — `datapipe.chunk`
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
datapipe.chunk(text: string, options: ChunkOptionsInput): HaiResult<DataChunk[]>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**ChunkOptionsInput**:
|
|
84
|
+
|
|
85
|
+
| 字段 | 类型 | 默认 | 说明 |
|
|
86
|
+
| ------------------ | --------- | ---- | ------------------------------ |
|
|
87
|
+
| `mode` | `ChunkMode` | — | 分块模式(必填) |
|
|
88
|
+
| `maxSize` | `number` | 1000 | 分块最大大小 |
|
|
89
|
+
| `overlap` | `number` | 0 | 重叠大小(上下文衔接) |
|
|
90
|
+
| `separator` | `string` | — | 自定义分隔符正则(mode=custom)|
|
|
91
|
+
| `markdownMinLevel` | `number` | 2 | Markdown 最低标题级别(1-6) |
|
|
92
|
+
| `markdownKeepTitle`| `boolean` | true | 分块中保留 Markdown 标题 |
|
|
93
|
+
|
|
94
|
+
**分块模式**:
|
|
95
|
+
|
|
96
|
+
| 模式 | 说明 |
|
|
97
|
+
| ----------- | --------------------------- |
|
|
98
|
+
| `sentence` | 按句子(中英文句号/问号/感叹号) |
|
|
99
|
+
| `paragraph` | 按段落(双换行) |
|
|
100
|
+
| `markdown` | 按 Markdown 标题层级 |
|
|
101
|
+
| `page` | 按分页符(\f) |
|
|
102
|
+
| `word` | 按字数 |
|
|
103
|
+
| `character` | 按字符数 |
|
|
104
|
+
| `custom` | 自定义正则分隔符 |
|
|
105
|
+
|
|
106
|
+
**DataChunk**:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
interface DataChunk {
|
|
110
|
+
index: number // 分块索引(从 0 开始)
|
|
111
|
+
content: string // 分块内容
|
|
112
|
+
metadata?: Record<string, unknown> // 元数据(Markdown 模式含 title、level)
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 管线 — `datapipe.pipeline()`
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
datapipe.pipeline()
|
|
120
|
+
.clean(options?) // 添加清洗步骤
|
|
121
|
+
.transform(fn) // 添加文本转换步骤(同步/异步)
|
|
122
|
+
.chunk(options) // 添加分块步骤
|
|
123
|
+
.chunkTransform(fn) // 添加分块后处理步骤
|
|
124
|
+
.run(text) // 执行管线 → Promise<HaiResult<PipelineResult>>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**PipelineResult**:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
interface PipelineResult {
|
|
131
|
+
text: string // 处理后的文本(分块前的最终文本)
|
|
132
|
+
chunks: DataChunk[] // 分块列表(如果管线包含 chunk 步骤)
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 错误码 — `HaiDatapipeError`
|
|
139
|
+
|
|
140
|
+
| 错误码 | code | 说明 |
|
|
141
|
+
|--------|------|------|
|
|
142
|
+
| `HaiDatapipeError.CLEAN_FAILED` | `hai:datapipe:001` | 清洗失败 |
|
|
143
|
+
| `HaiDatapipeError.CHUNK_FAILED` | `hai:datapipe:002` | 分块失败 |
|
|
144
|
+
| `HaiDatapipeError.TRANSFORM_FAILED` | `hai:datapipe:003` | 转换失败 |
|
|
145
|
+
| `HaiDatapipeError.PIPELINE_FAILED` | `hai:datapipe:004` | 管线执行失败 |
|
|
146
|
+
| `HaiDatapipeError.CONFIG_ERROR` | `hai:datapipe:005` | 配置错误 |
|
|
147
|
+
| `HaiDatapipeError.MISSING_SEPARATOR` | `hai:datapipe:006` | 自定义分隔符缺失 |
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 常见模式
|
|
152
|
+
|
|
153
|
+
### RAG 文档入库前处理
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { datapipe } from '@h-ai/datapipe'
|
|
157
|
+
import { ai } from '@h-ai/ai'
|
|
158
|
+
import { vecdb } from '@h-ai/vecdb'
|
|
159
|
+
|
|
160
|
+
// 清洗 + Markdown 分块
|
|
161
|
+
const result = await datapipe.pipeline()
|
|
162
|
+
.clean({ removeHtml: true, removeUrls: true })
|
|
163
|
+
.chunk({ mode: 'markdown', maxSize: 1000, overlap: 100 })
|
|
164
|
+
.run(rawDocument)
|
|
165
|
+
|
|
166
|
+
if (!result.success) return result
|
|
167
|
+
|
|
168
|
+
// 生成嵌入
|
|
169
|
+
const embeddings = await ai.embedding.embedBatch(
|
|
170
|
+
result.data.chunks.map(c => c.content),
|
|
171
|
+
)
|
|
172
|
+
if (!embeddings.success) return embeddings
|
|
173
|
+
|
|
174
|
+
// 入库
|
|
175
|
+
const docs = result.data.chunks.map((chunk, i) => ({
|
|
176
|
+
id: `chunk-${i}`,
|
|
177
|
+
vector: embeddings.data[i],
|
|
178
|
+
content: chunk.content,
|
|
179
|
+
metadata: chunk.metadata,
|
|
180
|
+
}))
|
|
181
|
+
await vecdb.vector.insert('knowledge', docs)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 多步清洗管线
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const result = await datapipe.pipeline()
|
|
188
|
+
.clean({ removeHtml: true, removeEmails: true })
|
|
189
|
+
.transform(text => text.replace(/\[.*?\]/g, '')) // 移除 [注释]
|
|
190
|
+
.transform(text => text.replace(/\(https?:.*?\)/g, '')) // 移除 Markdown 链接 URL
|
|
191
|
+
.chunk({ mode: 'paragraph', maxSize: 800 })
|
|
192
|
+
.chunkTransform(chunks => chunks.filter(c => c.content.length > 20)) // 过滤过短分块
|
|
193
|
+
.run(rawText)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 错误分支处理
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
import { datapipe, HaiDatapipeError } from '@h-ai/datapipe'
|
|
200
|
+
|
|
201
|
+
const result = datapipe.chunk(text, { mode: 'custom' })
|
|
202
|
+
if (!result.success) {
|
|
203
|
+
switch (result.error.code) {
|
|
204
|
+
case HaiDatapipeError.MISSING_SEPARATOR.code:
|
|
205
|
+
// mode='custom' 时需提供 separator
|
|
206
|
+
break
|
|
207
|
+
case HaiDatapipeError.CONFIG_ERROR.code:
|
|
208
|
+
// 配置参数校验失败
|
|
209
|
+
break
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## 相关 Skills
|
|
217
|
+
|
|
218
|
+
- `hai-vecdb`:向量数据库存储(分块后入库)
|
|
219
|
+
- `hai-ai`:LLM 与 Embedding 能力
|
|
220
|
+
- `hai-core`:HaiResult 模型
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hai-deploy
|
|
3
|
+
description: 使用 @h-ai/deploy 进行自动化部署:Vercel 部署 + 基础设施开通(Neon/Upstash/R2/Resend/Aliyun);当需求涉及应用部署、环境配置、凭证管理或云服务开通时使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# hai-deploy
|
|
7
|
+
|
|
8
|
+
> `@h-ai/deploy` 提供自动化部署能力,将 SvelteKit 应用部署到 Vercel,并自动开通 PostgreSQL (Neon)、Redis (Upstash)、S3 (Cloudflare R2)、邮件 (Resend)、短信 (阿里云) 等基础设施服务。
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 运行环境
|
|
13
|
+
|
|
14
|
+
> ⚠️ **Node.js CLI / 服务端模块。** 通过 `hai deploy` CLI 命令或在 Node.js 脚本中使用。
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 适用场景
|
|
19
|
+
|
|
20
|
+
- 一键部署 SvelteKit 应用到 Vercel
|
|
21
|
+
- 自动开通 PostgreSQL、Redis、S3 等云服务
|
|
22
|
+
- 管理部署凭证(~/.hai/credentials.yml)
|
|
23
|
+
- 扫描应用依赖,自动检测所需服务
|
|
24
|
+
- CLI 部署流程(`hai deploy`)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 使用步骤
|
|
29
|
+
|
|
30
|
+
### 1. 配置
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
# config/_deploy.yml
|
|
34
|
+
provider:
|
|
35
|
+
type: vercel
|
|
36
|
+
token: ${HAI_DEPLOY_VERCEL_TOKEN}
|
|
37
|
+
|
|
38
|
+
services:
|
|
39
|
+
db:
|
|
40
|
+
provisioner: neon
|
|
41
|
+
apiKey: ${HAI_DEPLOY_NEON_API_KEY}
|
|
42
|
+
cache:
|
|
43
|
+
provisioner: upstash
|
|
44
|
+
email: ${HAI_DEPLOY_UPSTASH_EMAIL}
|
|
45
|
+
apiKey: ${HAI_DEPLOY_UPSTASH_API_KEY}
|
|
46
|
+
storage:
|
|
47
|
+
provisioner: cloudflare-r2
|
|
48
|
+
accountId: ${HAI_DEPLOY_CF_ACCOUNT_ID}
|
|
49
|
+
apiToken: ${HAI_DEPLOY_CF_API_TOKEN}
|
|
50
|
+
email:
|
|
51
|
+
provisioner: resend
|
|
52
|
+
apiKey: ${HAI_DEPLOY_RESEND_API_KEY}
|
|
53
|
+
sms:
|
|
54
|
+
provisioner: aliyun
|
|
55
|
+
accessKeyId: ${HAI_DEPLOY_ALIYUN_ACCESS_KEY_ID}
|
|
56
|
+
accessKeySecret: ${HAI_DEPLOY_ALIYUN_ACCESS_KEY_SECRET}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 2. 初始化与关闭
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { deploy } from '@h-ai/deploy'
|
|
63
|
+
|
|
64
|
+
await deploy.init({
|
|
65
|
+
provider: { type: 'vercel', token: 'vel_xxx' },
|
|
66
|
+
services: {
|
|
67
|
+
db: { provisioner: 'neon', apiKey: 'neon_xxx' },
|
|
68
|
+
},
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
// 使用后关闭
|
|
72
|
+
await deploy.close()
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 3. 扫描应用
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const scanResult = await deploy.scan('./apps/my-app')
|
|
79
|
+
if (scanResult.success) {
|
|
80
|
+
const { appName, isSvelteKit, requiredServices } = scanResult.data
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 4. 开通基础设施
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const provResults = await deploy.provisionAll('my-project')
|
|
88
|
+
if (provResults.success) {
|
|
89
|
+
for (const prov of provResults.data) {
|
|
90
|
+
// prov.envVars 包含需要注入的环境变量
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 5. 完整部署
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
const result = await deploy.deployApp('./apps/my-app', {
|
|
99
|
+
projectName: 'my-project',
|
|
100
|
+
skipProvision: false,
|
|
101
|
+
skipBuild: false,
|
|
102
|
+
})
|
|
103
|
+
if (result.success) {
|
|
104
|
+
// result.data.url — 部署地址
|
|
105
|
+
// result.data.deploymentId — 部署 ID
|
|
106
|
+
// result.data.envVarsSet — 已设置的环境变量列表
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 核心 API
|
|
113
|
+
|
|
114
|
+
| 方法 | 签名 | 说明 |
|
|
115
|
+
| ---------------------- | -------------------------------------------------------------------------- | ------------ |
|
|
116
|
+
| `deploy.init` | `(config: DeployConfigInput) => Promise<HaiResult<void>>` | 初始化模块 |
|
|
117
|
+
| `deploy.close` | `() => Promise<void>` | 关闭模块 |
|
|
118
|
+
| `deploy.scan` | `(appDir: string) => Promise<HaiResult<ScanResult>>` | 扫描应用 |
|
|
119
|
+
| `deploy.provisionAll` | `(projectName: string) => Promise<HaiResult<ProvisionResult[]>>` | 开通所有服务 |
|
|
120
|
+
| `deploy.deployApp` | `(appDir: string, options?) => Promise<HaiResult<DeployResult>>` | 完整部署 |
|
|
121
|
+
| `deploy.config` | `DeployConfig \| null` | 当前配置 |
|
|
122
|
+
| `deploy.isInitialized` | `boolean` | 初始化状态 |
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 凭证管理
|
|
127
|
+
|
|
128
|
+
| 函数 | 说明 |
|
|
129
|
+
| ---------------------------- | ------------------------------------------ |
|
|
130
|
+
| `loadCredentials()` | 加载 ~/.hai/credentials.yml 到 process.env |
|
|
131
|
+
| `saveCredential(key, value)` | 保存单个凭证 |
|
|
132
|
+
| `saveCredentials(entries)` | 批量保存凭证 |
|
|
133
|
+
| `getCredentialsPath()` | 获取凭证文件路径 |
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 错误码 — `HaiDeployError`
|
|
138
|
+
|
|
139
|
+
| 错误码 | code | 说明 |
|
|
140
|
+
| --------------------------------------- | ------------------ | ------------------------ |
|
|
141
|
+
| `HaiDeployError.DEPLOY_FAILED` | `hai:deploy:001` | 部署失败(通用) |
|
|
142
|
+
| `HaiDeployError.PROJECT_CREATE_FAILED` | `hai:deploy:002` | 平台项目创建失败 |
|
|
143
|
+
| `HaiDeployError.BUILD_FAILED` | `hai:deploy:003` | 应用构建失败 |
|
|
144
|
+
| `HaiDeployError.UPLOAD_FAILED` | `hai:deploy:004` | 构建产物上传失败 |
|
|
145
|
+
| `HaiDeployError.AUTH_REQUIRED` | `hai:deploy:005` | 未认证 |
|
|
146
|
+
| `HaiDeployError.AUTH_FAILED` | `hai:deploy:006` | 认证失败 |
|
|
147
|
+
| `HaiDeployError.PROVISION_FAILED` | `hai:deploy:007` | 基础设施开通失败 |
|
|
148
|
+
| `HaiDeployError.ADAPTER_MISSING` | `hai:deploy:008` | SvelteKit adapter 未安装 |
|
|
149
|
+
| `HaiDeployError.SCAN_FAILED` | `hai:deploy:009` | 应用扫描失败 |
|
|
150
|
+
| `HaiDeployError.ENV_VAR_FAILED` | `hai:deploy:010` | 环境变量设置失败 |
|
|
151
|
+
| `HaiDeployError.NOT_INITIALIZED` | `hai:deploy:011` | 模块未初始化 |
|
|
152
|
+
| `HaiDeployError.UNSUPPORTED_TYPE` | `hai:deploy:012` | 不支持的类型 |
|
|
153
|
+
| `HaiDeployError.CONFIG_ERROR` | `hai:deploy:013` | 配置错误 |
|
|
154
|
+
| `HaiDeployError.CREDENTIAL_ERROR` | `hai:deploy:014` | 凭证读写失败 |
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## CLI 命令
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# 部署当前目录
|
|
162
|
+
hai deploy
|
|
163
|
+
|
|
164
|
+
# 部署指定应用
|
|
165
|
+
hai deploy ./apps/admin-console
|
|
166
|
+
|
|
167
|
+
# 跳过基础设施开通
|
|
168
|
+
hai deploy --skip-provision
|
|
169
|
+
|
|
170
|
+
# 跳过构建
|
|
171
|
+
hai deploy --skip-build
|
|
172
|
+
|
|
173
|
+
# 自定义项目名
|
|
174
|
+
hai deploy --project-name my-custom-name
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 常见模式
|
|
180
|
+
|
|
181
|
+
### 仅部署(跳过基础设施)
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
await deploy.deployApp('./apps/my-app', { skipProvision: true })
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 仅开通基础设施
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
await deploy.init(config)
|
|
191
|
+
const result = await deploy.provisionAll('my-project')
|
|
192
|
+
// 手动使用 result.data 中的环境变量
|
|
193
|
+
await deploy.close()
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 自定义部署流程
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
import { deploy } from '@h-ai/deploy'
|
|
200
|
+
|
|
201
|
+
// Provider 通过 init 配置自动创建,不需要手动导入
|
|
202
|
+
await deploy.init({
|
|
203
|
+
provider: { type: 'vercel', token: 'vel_xxx' },
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
// 使用 deploy API 部署
|
|
207
|
+
const result = await deploy.deployApp('./apps/my-app')
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 相关 Skills
|
|
213
|
+
|
|
214
|
+
- **hai-core** — 配置加载、日志、HaiResult 类型
|
|
215
|
+
- **hai-reldb** — 数据库(Neon PostgreSQL)
|
|
216
|
+
- **hai-cache** — 缓存(Upstash Redis)
|