@h-ai/cli 0.1.0-alpha.12 → 0.1.0-alpha.15

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@h-ai/cli",
3
3
  "type": "module",
4
- "version": "0.1.0-alpha.12",
4
+ "version": "0.1.0-alpha.15",
5
5
  "description": "Hai Framework CLI for project scaffolding and code generation.",
6
6
  "license": "Apache-2.0",
7
7
  "keywords": [
@@ -34,7 +34,7 @@
34
34
  "ora": "^9.1.0",
35
35
  "prompts": "^2.4.2",
36
36
  "yaml": "^2.7.0",
37
- "@h-ai/core": "0.1.0-alpha.12"
37
+ "@h-ai/core": "0.1.0-alpha.15"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/fs-extra": "^11.0.4",
@@ -7,8 +7,9 @@
7
7
  import { api } from '@h-ai/api-client'
8
8
  import { createCapacitorTokenStorage } from '@h-ai/capacitor'
9
9
 
10
- /** API 基础地址(开发时指向本地后端) */
11
- const API_BASE = import.meta.env.PUBLIC_API_BASE ?? 'http://localhost:3000'
10
+ // Capacitor 静态构建后通过 Vite 的 import.meta.env 注入 PUBLIC_* 变量
11
+ // 此处不使用 SvelteKit 的 $env/static/public,避免脱离 SvelteKit SSR 上下文时的类型/运行时缺失
12
+ const API_BASE = (import.meta.env.PUBLIC_API_BASE as string | undefined) ?? 'http://localhost:3000'
12
13
 
13
14
  /**
14
15
  * 初始化 API 客户端
@@ -19,10 +20,10 @@ const API_BASE = import.meta.env.PUBLIC_API_BASE ?? 'http://localhost:3000'
19
20
  */
20
21
  export async function initApi() {
21
22
  return api.init({
22
- baseUrl: API_BASE,
23
+ baseUrl: `${API_BASE}/api/v1`,
23
24
  auth: {
24
25
  storage: createCapacitorTokenStorage(),
25
- refreshUrl: '/api/v1/auth/refresh',
26
+ refreshPath: '/auth/refresh',
26
27
  },
27
28
  })
28
29
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "{{projectName}}",
3
- "version": "0.1.0-alpha.12",
3
+ "version": "0.1.0-alpha.15",
4
4
  "private": true,
5
5
  "description": "{{#if_eq appType 'admin'}}Enterprise management system built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'website'}}Enterprise website built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'h5'}}Mobile H5 app built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'api'}}REST API service built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'android-app'}}Android app built with hai Agent Framework{{/if_eq}}",
6
6
  "keywords": ["hai", "sveltekit", "svelte5", "{{appType}}"],
@@ -21,26 +21,26 @@
21
21
  "clean": "rimraf .svelte-kit build .turbo"
22
22
  },
23
23
  "dependencies": {
24
- "@h-ai/core": "^0.1.0-alpha.12",
25
- "@h-ai/kit": "^0.1.0-alpha.12"{{#if hasUi}},
26
- "@h-ai/ui": "^0.1.0-alpha.12"{{/if}}{{#if features.db}},
27
- "@h-ai/reldb": "^0.1.0-alpha.12"{{/if}}{{#if features.cache}},
28
- "@h-ai/cache": "^0.1.0-alpha.12"{{/if}}{{#if features.iam}},
29
- "@h-ai/iam": "^0.1.0-alpha.12"{{/if}}{{#if features.crypto}},
30
- "@h-ai/crypto": "^0.1.0-alpha.12"{{/if}}{{#if features.storage}},
31
- "@h-ai/storage": "^0.1.0-alpha.12"{{/if}}{{#if features.ai}},
32
- "@h-ai/ai": "^0.1.0-alpha.12"{{/if}}{{#if features.audit}},
33
- "@h-ai/audit": "^0.1.0-alpha.12"{{/if}}{{#if features.reach}},
34
- "@h-ai/reach": "^0.1.0-alpha.12"{{/if}}{{#if features.payment}},
35
- "@h-ai/payment": "^0.1.0-alpha.12"{{/if}}{{#if features.vecdb}},
36
- "@h-ai/vecdb": "^0.1.0-alpha.12"{{/if}}{{#if features.datapipe}},
37
- "@h-ai/datapipe": "^0.1.0-alpha.12"{{/if}}{{#if features.scheduler}},
38
- "@h-ai/scheduler": "^0.1.0-alpha.12"{{/if}}{{#if features.deploy}},
39
- "@h-ai/deploy": "^0.1.0-alpha.12"{{/if}}{{#if features.api-client}},
40
- "@h-ai/api-client": "^0.1.0-alpha.12"{{/if}}{{#if features.capacitor}},
41
- "@h-ai/capacitor": "^0.1.0-alpha.12"{{/if}}{{#if isCapacitorApp}}{{#unless features.api-client}},
42
- "@h-ai/api-client": "^0.1.0-alpha.12"{{/unless}}{{#unless features.capacitor}},
43
- "@h-ai/capacitor": "^0.1.0-alpha.12"{{/unless}}{{/if}},
24
+ "@h-ai/core": "^0.1.0-alpha.15",
25
+ "@h-ai/kit": "^0.1.0-alpha.15"{{#if hasUi}},
26
+ "@h-ai/ui": "^0.1.0-alpha.15"{{/if}}{{#if features.db}},
27
+ "@h-ai/reldb": "^0.1.0-alpha.15"{{/if}}{{#if features.cache}},
28
+ "@h-ai/cache": "^0.1.0-alpha.15"{{/if}}{{#if features.iam}},
29
+ "@h-ai/iam": "^0.1.0-alpha.15"{{/if}}{{#if features.crypto}},
30
+ "@h-ai/crypto": "^0.1.0-alpha.15"{{/if}}{{#if features.storage}},
31
+ "@h-ai/storage": "^0.1.0-alpha.15"{{/if}}{{#if features.ai}},
32
+ "@h-ai/ai": "^0.1.0-alpha.15"{{/if}}{{#if features.audit}},
33
+ "@h-ai/audit": "^0.1.0-alpha.15"{{/if}}{{#if features.reach}},
34
+ "@h-ai/reach": "^0.1.0-alpha.15"{{/if}}{{#if features.payment}},
35
+ "@h-ai/payment": "^0.1.0-alpha.15"{{/if}}{{#if features.vecdb}},
36
+ "@h-ai/vecdb": "^0.1.0-alpha.15"{{/if}}{{#if features.datapipe}},
37
+ "@h-ai/datapipe": "^0.1.0-alpha.15"{{/if}}{{#if features.scheduler}},
38
+ "@h-ai/scheduler": "^0.1.0-alpha.15"{{/if}}{{#if features.deploy}},
39
+ "@h-ai/deploy": "^0.1.0-alpha.15"{{/if}}{{#if features.api-client}},
40
+ "@h-ai/api-client": "^0.1.0-alpha.15"{{/if}}{{#if features.capacitor}},
41
+ "@h-ai/capacitor": "^0.1.0-alpha.15"{{/if}}{{#if isCapacitorApp}}{{#unless features.api-client}},
42
+ "@h-ai/api-client": "^0.1.0-alpha.15"{{/unless}}{{#unless features.capacitor}},
43
+ "@h-ai/capacitor": "^0.1.0-alpha.15"{{/unless}}{{/if}},
44
44
  "zod": "^4.3.6"
45
45
  },
46
46
  "devDependencies": {
@@ -9,7 +9,8 @@
9
9
  @import '@h-ai/ui/styles/mobile.css';
10
10
 
11
11
  /* ─── 扫描 @h-ai/ui 组件中使用的 Tailwind 类名 ─── */
12
- @source "../node_modules/@h-ai/ui/dist/**/*.{svelte,ts}";
12
+ @source "../node_modules/@h-ai/ui/dist/**/*.{svelte,js,ts}";
13
+ @source "../../../node_modules/@h-ai/ui/dist/**/*.{svelte,js,ts}";
13
14
 
14
15
  /* ─── DaisyUI 主题 ─── */
15
16
  @plugin "daisyui" {
@@ -24,3 +24,4 @@
24
24
  - **框架模块**:`hai-core/`、`hai-kit/`、`hai-reldb/`、`hai-iam/`、`hai-crypto/`、`hai-cache/`、`hai-storage/`、`hai-ai/`
25
25
  - **UI 组件**:`hai-ui/SKILL.md`
26
26
  - **TDD 开发流程**:`hai-app-tests/`(TDD 测试先行)、`hai-app-create/`(TDD 实现)、`hai-app-review/`(TDD 重构审查)
27
+ - **仓库工程流程**:`hai-ci/`(CI/CD 与质量门禁)、`hai-pr-review/`(PR / Issue 交付审查与 AI Review)、`hai-framework-sync/`(两仓同步)
@@ -48,6 +48,9 @@
48
48
  | `hai-app-create` | TDD 驱动的功能创建(先测试后实现) |
49
49
  | `hai-app-review` | 应用代码审查(含 TDD 合规检查) |
50
50
  | `hai-app-tests` | TDD 测试规范(Vitest 单元测试 + Playwright E2E) |
51
+ | `hai-ci` | CI/CD、GitHub Actions、质量门禁与 workflow 安全 |
52
+ | `hai-pr-review` | PR / Issue 交付审查、AI Review 策略、CODEOWNERS 与合并门禁 |
53
+ | `hai-framework-sync` | hai-framework 模板源头与应用仓库同步 |
51
54
 
52
55
  ## 开发流程
53
56
 
@@ -20,7 +20,7 @@ description: 使用 @h-ai/ai 进行 LLM 调用(OpenAI 兼容)、MCP 服务
20
20
  | `ai.memory` / `ai.conversation` | ✅ | ❌(通过 API 查询) |
21
21
  | `ai.knowledge` 知识库 | ✅ | ❌(通过 API 查询) |
22
22
 
23
- 浏览器端消费 AI 能力的标准模式:通过 `api.stream()` 或 `apiFetch` 调用服务端 API 端点。
23
+ 浏览器端消费 AI 能力的标准模式:通过 `@h-ai/api-client` 的 typed contract 调用 `apiClient.ai.chats.*`;如需 SSE 流式输出,由应用显式暴露自定义流式 endpoint,再用 `fetch` / `apiFetch` 消费。
24
24
 
25
25
  ---
26
26
 
@@ -266,27 +266,20 @@ await mcp.connect(transport)
266
266
  ### 前端客户端
267
267
 
268
268
  ```typescript
269
- import { api } from '@h-ai/api-client'
270
- import { createAIClient } from '@h-ai/ai/client'
269
+ import { apiClient } from '@h-ai/api-client'
271
270
 
272
- await api.init({ baseUrl: '/api', auth: { ... } })
273
- const client = createAIClient({ api })
271
+ await apiClient.init({ baseUrl: '/api/v1', auth: {} })
274
272
 
275
273
  // 非流式
276
- const response = await client.chat({ messages })
277
-
278
- // 流式
279
- for await (const chunk of client.chatStream({ messages }, {
280
- onProgress: (p) => { /* 处理进度 */ },
281
- })) { /* ... */ }
274
+ const response = await apiClient.ai.chats.createCompletion({ messages })
282
275
 
283
276
  // 便捷方法
284
- const reply = await client.sendMessage('你好', '系统提示')
277
+ const reply = await apiClient.ai.chats.sendMessage({ message: '你好', systemPrompt: '系统提示' })
285
278
 
286
279
  // 记忆与会话查询
287
- const memories = await client.recallMemories('用户偏好', { topK: 5, objectId: 'user-001' })
288
- const page = await client.listMemories({ objectId: 'user-001', offset: 0, limit: 20 })
289
- const sessions = await client.listSessions('user-001')
280
+ const memories = await apiClient.ai.memories.recall({ query: '用户偏好', topK: 5, objectId: 'user-001' })
281
+ const page = await apiClient.ai.memories.list({ objectId: 'user-001', limit: 20 })
282
+ const sessions = await apiClient.ai.sessions.list({ objectId: 'user-001' })
290
283
  ```
291
284
 
292
285
  ### 记忆管理 — `ai.memory`
@@ -656,36 +649,57 @@ async function manualChat(userInput: string) {
656
649
 
657
650
  ## 浏览器端使用
658
651
 
659
- ### 流式对话(SSE)
652
+ ### typed 对话调用
660
653
 
661
- 浏览器通过 `api.stream()` 消费服务端流式 API:
654
+ 浏览器 / App 通过 `@h-ai/api-client` 调用由 `@h-ai/api-contract` 定义、`@h-ai/serv` 挂载的 AI contract:
662
655
 
663
656
  ```typescript
664
- import { api } from '@h-ai/api-client'
657
+ import { apiClient } from '@h-ai/api-client'
665
658
 
666
- const controller = new AbortController()
659
+ const result = await apiClient.ai.chats.createCompletion({
660
+ messages: [{ role: 'user', content: '你好' }],
661
+ })
667
662
 
668
- for await (const chunk of api.stream('/api/v1/ai/chat', {
669
- conversationId: 'conv-1',
670
- content: '你好',
671
- }, { signal: controller.signal })) {
672
- // 每个 chunk 是 SSE data: 行的文本内容
673
- appendToUI(chunk)
663
+ if (result.success) {
664
+ appendToUI(result.data.choices[0]?.message?.content ?? '')
674
665
  }
675
-
676
- // 主动停止
677
- controller.abort()
678
666
  ```
679
667
 
680
- 或使用 `apiFetch`(SSR SvelteKit 同源场景):
668
+ ### 流式对话(SSE,自定义 endpoint)
669
+
670
+ 标准 `api-client` 不再提供旧的通用流式方法。若产品需要 SSE 流式输出,请在应用服务端显式定义流式 endpoint(例如 SvelteKit `+server.ts` 或 `@h-ai/serv` 自定义 route),浏览器端再用 `fetch` / `apiFetch` 消费。
681
671
 
682
672
  ```typescript
683
673
  import { apiFetch } from '$lib/utils/api'
684
674
 
685
- const res = await apiFetch('/api/v1/ai/chat', {
675
+ const controller = new AbortController()
676
+
677
+ const res = await apiFetch('/api/ai/chat-stream', {
678
+ method: 'POST',
679
+ headers: { 'Content-Type': 'application/json' },
680
+ body: JSON.stringify({ conversationId: 'conv-1', content: '你好' }),
681
+ signal: controller.signal,
682
+ })
683
+
684
+ const reader = res.body!.getReader()
685
+ const decoder = new TextDecoder()
686
+ while (true) {
687
+ const { done, value } = await reader.read()
688
+ if (done)
689
+ break
690
+
691
+ appendToUI(decoder.decode(value))
692
+ }
693
+ ```
694
+
695
+ 或直接使用原生 `fetch`(跨域公共 API 场景):
696
+
697
+ ```typescript
698
+ const res = await fetch(`${apiBase}/ai/chat-stream`, {
686
699
  method: 'POST',
687
700
  headers: { 'Content-Type': 'application/json' },
688
701
  body: JSON.stringify({ conversationId, content: userInput }),
702
+ signal: controller.signal,
689
703
  })
690
704
 
691
705
  // 手动消费 SSE 流