@optima-chat/optima-agent 0.4.17 → 0.4.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/.claude/settings.local.json +69 -0
- package/.claude/skills/collection/SKILL.md +24 -17
- package/.claude/skills/homepage/SKILL.md +2 -4
- package/.claude/skills/inventory/SKILL.md +33 -81
- package/.claude/skills/merchant/SKILL.md +9 -9
- package/.claude/skills/product/SKILL.md +2 -139
- package/.claude/skills/product-page/SKILL.md +2 -2
- package/.claude/skills/review/SKILL.md +19 -23
- package/dist/bin/bi-cli.js +0 -0
- package/dist/bin/comfy.js +0 -0
- package/dist/bin/commerce.js +0 -0
- package/dist/bin/google-ads.js +0 -0
- package/dist/bin/optima.js +0 -0
- package/dist/bin/scout.js +0 -0
- package/dist/src/ui/App.d.ts +6 -0
- package/dist/src/ui/App.d.ts.map +1 -0
- package/dist/src/ui/App.js +164 -0
- package/dist/src/ui/App.js.map +1 -0
- package/dist/src/ui/components/Composer.d.ts +10 -0
- package/dist/src/ui/components/Composer.d.ts.map +1 -0
- package/dist/src/ui/components/Composer.js +13 -0
- package/dist/src/ui/components/Composer.js.map +1 -0
- package/dist/src/ui/components/Header.d.ts +7 -0
- package/dist/src/ui/components/Header.d.ts.map +1 -0
- package/dist/src/ui/components/Header.js +7 -0
- package/dist/src/ui/components/Header.js.map +1 -0
- package/dist/src/ui/components/Message.d.ts +12 -0
- package/dist/src/ui/components/Message.d.ts.map +1 -0
- package/dist/src/ui/components/Message.js +21 -0
- package/dist/src/ui/components/Message.js.map +1 -0
- package/dist/src/ui/components/MessageList.d.ts +9 -0
- package/dist/src/ui/components/MessageList.d.ts.map +1 -0
- package/dist/src/ui/components/MessageList.js +18 -0
- package/dist/src/ui/components/MessageList.js.map +1 -0
- package/dist/src/ui/components/Spinner.d.ts +6 -0
- package/dist/src/ui/components/Spinner.d.ts.map +1 -0
- package/dist/src/ui/components/Spinner.js +7 -0
- package/dist/src/ui/components/Spinner.js.map +1 -0
- package/dist/src/ui/components/StatusBar.d.ts +11 -0
- package/dist/src/ui/components/StatusBar.d.ts.map +1 -0
- package/dist/src/ui/components/StatusBar.js +7 -0
- package/dist/src/ui/components/StatusBar.js.map +1 -0
- package/dist/src/ui/components/index.d.ts +7 -0
- package/dist/src/ui/components/index.d.ts.map +1 -0
- package/dist/src/ui/components/index.js +7 -0
- package/dist/src/ui/components/index.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(gh api:*)",
|
|
5
|
+
"WebFetch(domain:platform.claude.com)",
|
|
6
|
+
"Bash(git init:*)",
|
|
7
|
+
"Bash(mkdir:*)",
|
|
8
|
+
"Bash(npm run typecheck:*)",
|
|
9
|
+
"Bash(npm view:*)",
|
|
10
|
+
"WebSearch",
|
|
11
|
+
"Bash(commerce --help)",
|
|
12
|
+
"Bash(done)",
|
|
13
|
+
"Bash(commerce product:*)",
|
|
14
|
+
"Bash(commerce order:*)",
|
|
15
|
+
"Bash(commerce i18n:*)",
|
|
16
|
+
"Bash(google-ads:*)",
|
|
17
|
+
"Bash(scout --help:*)",
|
|
18
|
+
"Bash(tree:*)",
|
|
19
|
+
"Bash(cloc:*)",
|
|
20
|
+
"Bash(npm run build:*)",
|
|
21
|
+
"Bash(git restore:*)",
|
|
22
|
+
"Bash(gh repo view:*)",
|
|
23
|
+
"Bash(mv:*)",
|
|
24
|
+
"Bash(rmdir:*)",
|
|
25
|
+
"Bash(git add:*)",
|
|
26
|
+
"Bash(git commit:*)",
|
|
27
|
+
"Bash(git push)",
|
|
28
|
+
"Bash(timeout 5 npm run optima:*)",
|
|
29
|
+
"Bash(npm install:*)",
|
|
30
|
+
"Bash(cat:*)",
|
|
31
|
+
"Bash(gh issue create:*)",
|
|
32
|
+
"Bash(npx tsx:*)",
|
|
33
|
+
"Bash(timeout 30 npx tsx:*)",
|
|
34
|
+
"Bash(git push origin feature/ask-user-question)",
|
|
35
|
+
"Bash(node:*)",
|
|
36
|
+
"Bash(npm version:*)",
|
|
37
|
+
"Bash(git push:*)",
|
|
38
|
+
"Bash(npm publish:*)",
|
|
39
|
+
"Bash(pkill:*)",
|
|
40
|
+
"Bash(git -C /Users/verypro/optima-agent log --oneline --all -- \".claude/\")",
|
|
41
|
+
"Bash(wc:*)",
|
|
42
|
+
"Bash(grep:*)",
|
|
43
|
+
"Bash(find:*)",
|
|
44
|
+
"Bash(commerce collection --help:*)",
|
|
45
|
+
"Bash(commerce collection update --help:*)",
|
|
46
|
+
"Bash(commerce collection set-cover:*)",
|
|
47
|
+
"Bash(commerce collection get --help:*)",
|
|
48
|
+
"Bash(commerce collection list --help:*)",
|
|
49
|
+
"Bash(commerce collection create --help:*)",
|
|
50
|
+
"Bash(commerce collection remove-products:*)",
|
|
51
|
+
"Bash(commerce collection list-products:*)",
|
|
52
|
+
"Bash(commerce --version:*)",
|
|
53
|
+
"Bash(bi-cli --version:*)",
|
|
54
|
+
"Bash(commerce homepage create --help:*)",
|
|
55
|
+
"Bash(commerce homepage reorder --help:*)",
|
|
56
|
+
"Bash(commerce homepage delete --help:*)",
|
|
57
|
+
"Bash(commerce homepage update-images:*)",
|
|
58
|
+
"Bash(commerce homepage update-collections:*)",
|
|
59
|
+
"Bash(commerce homepage update-target:*)",
|
|
60
|
+
"Bash(commerce homepage switch-template:*)",
|
|
61
|
+
"Bash(commerce inventory:*)",
|
|
62
|
+
"Bash(commerce merchant:*)",
|
|
63
|
+
"Bash(commerce review:*)",
|
|
64
|
+
"Bash(commerce product-page:*)"
|
|
65
|
+
],
|
|
66
|
+
"deny": [],
|
|
67
|
+
"ask": []
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: collection
|
|
3
|
-
description:
|
|
3
|
+
description: 商品集合管理。创建、编辑集合,设置封面图,管理集合中的商品。当用户需要对商品进行分组、创建促销专区、管理商品分类、设置集合封面时使用。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
## 概念
|
|
@@ -37,40 +37,47 @@ Collection
|
|
|
37
37
|
当用户说:
|
|
38
38
|
- "查看所有集合" / "集合列表" → `commerce collection list`
|
|
39
39
|
- "创建集合 XX" → `commerce collection create --name "XX" --slug xx`
|
|
40
|
-
- "查看集合详情" → `commerce collection get --
|
|
41
|
-
- "删除集合 XX" → `commerce collection delete --
|
|
42
|
-
- "把商品加到集合" → `commerce collection add-products --
|
|
43
|
-
- "从集合移除商品" → `commerce collection remove-products --
|
|
44
|
-
- "查看集合里有哪些商品" → `commerce collection list-products --
|
|
40
|
+
- "查看集合详情" → `commerce collection get --id xx`
|
|
41
|
+
- "删除集合 XX" → `commerce collection delete --id xx --yes`
|
|
42
|
+
- "把商品加到集合" → `commerce collection add-products --id xx --product-ids p1,p2`
|
|
43
|
+
- "从集合移除商品" → `commerce collection remove-products --id xx --product-ids p1`
|
|
44
|
+
- "查看集合里有哪些商品" → `commerce collection list-products --id xx`
|
|
45
|
+
- "设置集合封面" / "给集合加封面图" → `commerce collection set-cover --id xx --path ./cover.jpg`
|
|
45
46
|
|
|
46
47
|
## 命令参考
|
|
47
48
|
|
|
48
49
|
### 集合 CRUD
|
|
49
50
|
- `commerce collection list` - 列出所有集合
|
|
50
|
-
- `commerce collection create
|
|
51
|
-
- `commerce collection get --
|
|
52
|
-
- `commerce collection update --
|
|
53
|
-
- `commerce collection delete --
|
|
54
|
-
- `commerce collection set-cover --
|
|
51
|
+
- `commerce collection create --name <name> --slug <slug>` - 创建集合
|
|
52
|
+
- `commerce collection get --id <id>` - 查看集合详情
|
|
53
|
+
- `commerce collection update --id <id>` - 更新集合(支持 --name, --slug, --description 等)
|
|
54
|
+
- `commerce collection delete --id <id> --yes` - 删除集合
|
|
55
|
+
- `commerce collection set-cover --id <id>` - 设置封面图(支持 --media-id, --url, --path)
|
|
55
56
|
|
|
56
57
|
### 商品管理
|
|
57
|
-
- `commerce collection add-products --
|
|
58
|
-
- `commerce collection remove-products --
|
|
59
|
-
- `commerce collection list-products --
|
|
58
|
+
- `commerce collection add-products --id <id> --product-ids <ids>` - 添加商品
|
|
59
|
+
- `commerce collection remove-products --id <id> --product-ids <ids>` - 移除商品
|
|
60
|
+
- `commerce collection list-products --id <id>` - 列出集合中的商品
|
|
60
61
|
|
|
61
62
|
## 创建集合示例
|
|
62
63
|
|
|
63
64
|
```bash
|
|
64
|
-
#
|
|
65
|
+
# 创建促销集合(返回 id,用于后续操作)
|
|
65
66
|
commerce collection create \
|
|
66
67
|
--name "Summer Sale 2024" \
|
|
67
68
|
--slug summer-sale-2024 \
|
|
68
69
|
--description "Hot deals for summer"
|
|
70
|
+
# 输出: { "id": "coll_xxx", ... }
|
|
69
71
|
|
|
70
|
-
#
|
|
72
|
+
# 添加商品到集合(使用返回的 id)
|
|
71
73
|
commerce collection add-products \
|
|
72
|
-
--
|
|
74
|
+
--id coll_xxx \
|
|
73
75
|
--product-ids prod_123,prod_456,prod_789
|
|
76
|
+
|
|
77
|
+
# 设置封面图
|
|
78
|
+
commerce collection set-cover \
|
|
79
|
+
--id coll_xxx \
|
|
80
|
+
--path ./summer-sale-cover.jpg
|
|
74
81
|
```
|
|
75
82
|
|
|
76
83
|
## 注意事项
|
|
@@ -16,8 +16,6 @@ Homepage(首页)是店铺的入口页面,由多个 Section(区块)组
|
|
|
16
16
|
- `collection_products` 区块:展示某个集合的商品(引用单个 collection slug)
|
|
17
17
|
- `featured` 区块:可推荐某个集合(target_type=collection)
|
|
18
18
|
|
|
19
|
-
→ 参考 [Collection Skill](../collection/SKILL.md) 了解集合管理
|
|
20
|
-
|
|
21
19
|
## 结构
|
|
22
20
|
|
|
23
21
|
```
|
|
@@ -169,7 +167,7 @@ Homepage
|
|
|
169
167
|
- "添加轮播图区块" → `commerce homepage create --type banner --title "主 Banner"`
|
|
170
168
|
- "更新轮播图图片" → `commerce homepage update-images --id xx --images '[...]'`
|
|
171
169
|
- "设置集合列表" → `commerce homepage update-collections --id xx --slugs "a,b,c"`
|
|
172
|
-
- "调整区块顺序" → `commerce homepage reorder --
|
|
170
|
+
- "调整区块顺序" → `commerce homepage reorder --moves '[{"section_id":"id1","new_position":0}]'`
|
|
173
171
|
- "使用模板" → `commerce homepage switch-template --template-key minimal`
|
|
174
172
|
- "删除区块" → `commerce homepage delete --id xx --yes`
|
|
175
173
|
|
|
@@ -187,7 +185,7 @@ Homepage
|
|
|
187
185
|
- `commerce homepage get --id <id>` - 查看区块详情
|
|
188
186
|
- `commerce homepage update --id <id>` - 更新区块
|
|
189
187
|
- `commerce homepage delete --id <id> --yes` - 删除区块
|
|
190
|
-
- `commerce homepage reorder --
|
|
188
|
+
- `commerce homepage reorder --moves <json>` - 重新排序(JSON 格式:`[{"section_id":"xx","new_position":0}]`)
|
|
191
189
|
|
|
192
190
|
### 区块设置
|
|
193
191
|
- `commerce homepage update-images --id <id> --images <json>` - 更新 banner 图片
|
|
@@ -14,11 +14,10 @@ description: Inventory management and stock monitoring. Track stock levels, upda
|
|
|
14
14
|
| 用户需求 | 推荐命令 | 关键注意点 |
|
|
15
15
|
|---------|---------|-----------|
|
|
16
16
|
| 查看低库存 | `inventory low-stock --threshold 10` | 阈值根据品类和销售速度设定 |
|
|
17
|
-
| 补货操作 | `inventory update --
|
|
18
|
-
| 预留库存 | `inventory reserve --
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
| 盘点调整 | `inventory update --reason "盘点调整"` | 账实不符时手动调整,记录差异原因 |
|
|
17
|
+
| 补货操作 | `inventory update --id XX --quantity YY` | 使用 product list 获取商品 ID |
|
|
18
|
+
| 预留库存 | `inventory reserve --id XX --quantity YY` | 订单创建时立即预留,避免超卖 |
|
|
19
|
+
| 查看历史 | `inventory history --id XX` | 分析库存变化趋势,优化补货策略 |
|
|
20
|
+
| 盘点调整 | `inventory update --id XX --quantity YY` | 账实不符时手动调整 |
|
|
22
21
|
|
|
23
22
|
### 1. 查看低库存预警
|
|
24
23
|
|
|
@@ -35,15 +34,12 @@ commerce inventory low-stock --threshold 5
|
|
|
35
34
|
|
|
36
35
|
```bash
|
|
37
36
|
# 用户说:"商品prod_123补货100个"
|
|
38
|
-
commerce inventory update
|
|
39
|
-
--id prod_123 \
|
|
40
|
-
--quantity 100 \
|
|
41
|
-
--reason "定期补货"
|
|
37
|
+
commerce inventory update --id prod_123 --quantity 100
|
|
42
38
|
|
|
43
39
|
# 根据销售数据决定补货量
|
|
44
|
-
commerce inventory update --id prod_hot --quantity 500
|
|
45
|
-
commerce inventory update --id prod_normal --quantity 100
|
|
46
|
-
commerce inventory update --id prod_slow --quantity 20
|
|
40
|
+
commerce inventory update --id prod_hot --quantity 500
|
|
41
|
+
commerce inventory update --id prod_normal --quantity 100
|
|
42
|
+
commerce inventory update --id prod_slow --quantity 20
|
|
47
43
|
```
|
|
48
44
|
|
|
49
45
|
### 3. 预留库存
|
|
@@ -52,16 +48,11 @@ commerce inventory update --id prod_slow --quantity 20 --reason "滞销品少量
|
|
|
52
48
|
|
|
53
49
|
```bash
|
|
54
50
|
# 用户说:"为订单预留5个商品"
|
|
55
|
-
commerce inventory reserve
|
|
56
|
-
--product-id prod_123 \
|
|
57
|
-
--quantity 5 \
|
|
58
|
-
--order-id order_456
|
|
51
|
+
commerce inventory reserve --id prod_123 --quantity 5
|
|
59
52
|
```
|
|
60
53
|
|
|
61
54
|
**库存预留机制**:
|
|
62
55
|
- **订单创建时预留** - 避免超卖,保证订单可履行
|
|
63
|
-
- **支付超时释放** - 未支付订单15分钟后自动释放预留
|
|
64
|
-
- **取消订单释放** - 订单取消后立即释放预留
|
|
65
56
|
- **发货后扣减** - 商品发货后从可用库存扣减
|
|
66
57
|
|
|
67
58
|
### 4. 盘点调整
|
|
@@ -70,13 +61,7 @@ commerce inventory reserve \
|
|
|
70
61
|
|
|
71
62
|
```bash
|
|
72
63
|
# 实际库存95,账面库存100,差异5个
|
|
73
|
-
commerce inventory update
|
|
74
|
-
--id prod_123 \
|
|
75
|
-
--quantity 95 \
|
|
76
|
-
--reason "盘点调整:实际库存95,账面100,差异-5(仓库损耗)"
|
|
77
|
-
|
|
78
|
-
# 验证更新
|
|
79
|
-
commerce inventory get --id prod_123
|
|
64
|
+
commerce inventory update --id prod_123 --quantity 95
|
|
80
65
|
```
|
|
81
66
|
|
|
82
67
|
### 5. 处理超卖
|
|
@@ -103,9 +88,7 @@ commerce inventory get --id prod_123
|
|
|
103
88
|
|
|
104
89
|
```bash
|
|
105
90
|
# 用户说:"查看商品prod_123的库存变更记录"
|
|
106
|
-
commerce inventory history
|
|
107
|
-
--product-id prod_123 \
|
|
108
|
-
--limit 20
|
|
91
|
+
commerce inventory history --id prod_123
|
|
109
92
|
```
|
|
110
93
|
|
|
111
94
|
## 卓越标准
|
|
@@ -128,8 +111,8 @@ commerce inventory history \
|
|
|
128
111
|
1. **查看低库存** - 每日 `commerce inventory low-stock --threshold 10`
|
|
129
112
|
2. **分析销售趋势** - 结合订单数据判断补货优先级
|
|
130
113
|
3. **制定补货计划** - 畅销品加大补货量,滞销品谨慎补货
|
|
131
|
-
4. **执行补货** - `commerce inventory update --id XX --quantity YY
|
|
132
|
-
5. **验证更新** - `commerce
|
|
114
|
+
4. **执行补货** - `commerce inventory update --id XX --quantity YY`
|
|
115
|
+
5. **验证更新** - `commerce product get --id XX` 确认库存正确
|
|
133
116
|
6. **定期盘点** - 每月实地盘点,调整账面库存
|
|
134
117
|
|
|
135
118
|
## 常见问题
|
|
@@ -140,7 +123,7 @@ commerce inventory history \
|
|
|
140
123
|
```bash
|
|
141
124
|
# 不分析就盲目补货,可能造成库存积压
|
|
142
125
|
for product_id in $(commerce inventory low-stock --json | jq -r '.[].id'); do
|
|
143
|
-
commerce inventory update --id $product_id --quantity 100
|
|
126
|
+
commerce inventory update --id $product_id --quantity 100
|
|
144
127
|
done
|
|
145
128
|
```
|
|
146
129
|
|
|
@@ -150,9 +133,9 @@ done
|
|
|
150
133
|
commerce inventory low-stock --threshold 10
|
|
151
134
|
|
|
152
135
|
# 根据销售数据决定补货量
|
|
153
|
-
commerce inventory update --id prod_hot --quantity 500
|
|
154
|
-
commerce inventory update --id prod_normal --quantity 100
|
|
155
|
-
commerce inventory update --id prod_slow --quantity 20
|
|
136
|
+
commerce inventory update --id prod_hot --quantity 500 # 畅销品大量补货
|
|
137
|
+
commerce inventory update --id prod_normal --quantity 100 # 常规补货
|
|
138
|
+
commerce inventory update --id prod_slow --quantity 20 # 滞销品少量补货
|
|
156
139
|
```
|
|
157
140
|
|
|
158
141
|
### ❌ 问题2:库存差异超过5%未深入调查
|
|
@@ -165,11 +148,8 @@ commerce inventory update --id prod_slow --quantity 20 --reason "滞销品少量
|
|
|
165
148
|
3. 差异率 > 5%需要深入调查根本原因
|
|
166
149
|
|
|
167
150
|
```bash
|
|
168
|
-
#
|
|
169
|
-
commerce inventory update
|
|
170
|
-
--id prod_123 \
|
|
171
|
-
--quantity 95 \
|
|
172
|
-
--reason "盘点调整:实际95,账面100,差异-5(仓库损耗,需检查存储条件)"
|
|
151
|
+
# 调整库存(记录差异原因:实际95,账面100,差异-5,仓库损耗)
|
|
152
|
+
commerce inventory update --id prod_123 --quantity 95
|
|
173
153
|
```
|
|
174
154
|
|
|
175
155
|
### ❌ 问题3:滞销商品长期占用库存
|
|
@@ -184,24 +164,17 @@ commerce inventory update \
|
|
|
184
164
|
|
|
185
165
|
```bash
|
|
186
166
|
# 查看库存历史判断是否滞销
|
|
187
|
-
commerce inventory history --
|
|
167
|
+
commerce inventory history --id prod_slow
|
|
188
168
|
```
|
|
189
169
|
|
|
190
|
-
### ❌ 问题4
|
|
170
|
+
### ❌ 问题4:不分析销售数据就补货
|
|
191
171
|
|
|
192
|
-
|
|
193
|
-
```bash
|
|
194
|
-
# 缺少原因,无法追溯
|
|
195
|
-
commerce inventory update --id prod_123 --quantity 100
|
|
196
|
-
```
|
|
172
|
+
**错误做法**:直接设置固定数量,不考虑销售速度
|
|
197
173
|
|
|
198
174
|
**✅ 正确做法**:
|
|
199
175
|
```bash
|
|
200
|
-
#
|
|
201
|
-
commerce inventory update
|
|
202
|
-
--id prod_123 \
|
|
203
|
-
--quantity 100 \
|
|
204
|
-
--reason "定期补货:上周销量50,预计2周销量"
|
|
176
|
+
# 根据销售数据决定补货量(如上周销量50,预计2周销量)
|
|
177
|
+
commerce inventory update --id prod_123 --quantity 100
|
|
205
178
|
```
|
|
206
179
|
|
|
207
180
|
### ❌ 问题5:超卖后处理不当
|
|
@@ -223,23 +196,16 @@ commerce inventory update \
|
|
|
223
196
|
|
|
224
197
|
当用户说:
|
|
225
198
|
- "查看库存低于10的商品" → `commerce inventory low-stock --threshold 10`
|
|
226
|
-
- "商品XX补货50个" → `commerce inventory update --id XX --quantity 50
|
|
227
|
-
- "预留库存" → `commerce inventory reserve --
|
|
228
|
-
- "查看库存历史" → `commerce inventory history --
|
|
229
|
-
- "查看所有商品库存" → `commerce inventory list`
|
|
199
|
+
- "商品XX补货50个" → `commerce inventory update --id XX --quantity 50`
|
|
200
|
+
- "预留库存" → `commerce inventory reserve --id XX --quantity YY`
|
|
201
|
+
- "查看库存历史" → `commerce inventory history --id XX`
|
|
230
202
|
|
|
231
203
|
### 核心功能
|
|
232
204
|
|
|
233
|
-
**库存查询**:
|
|
234
|
-
- `commerce inventory list` - 查看所有商品库存
|
|
235
|
-
- `commerce inventory get` - 查看单个商品库存
|
|
236
205
|
- `commerce inventory low-stock` - 查看低库存商品
|
|
237
|
-
- `commerce inventory history` - 查看库存变更历史
|
|
238
|
-
|
|
239
|
-
**库存更新**:
|
|
240
206
|
- `commerce inventory update` - 更新库存数量
|
|
207
|
+
- `commerce inventory history` - 查看库存变更历史
|
|
241
208
|
- `commerce inventory reserve` - 预留库存
|
|
242
|
-
- `commerce inventory release` - 释放预留库存
|
|
243
209
|
|
|
244
210
|
## 详细示例
|
|
245
211
|
|
|
@@ -252,40 +218,26 @@ commerce inventory low-stock --threshold 5
|
|
|
252
218
|
### 补货操作
|
|
253
219
|
```bash
|
|
254
220
|
# 用户说:"商品prod_123补货100个"
|
|
255
|
-
commerce inventory update
|
|
256
|
-
--id prod_123 \
|
|
257
|
-
--quantity 100 \
|
|
258
|
-
--reason "定期补货"
|
|
221
|
+
commerce inventory update --id prod_123 --quantity 100
|
|
259
222
|
```
|
|
260
223
|
|
|
261
224
|
### 预留库存
|
|
262
225
|
```bash
|
|
263
226
|
# 用户说:"为订单预留5个商品"
|
|
264
227
|
commerce inventory reserve \
|
|
265
|
-
--
|
|
266
|
-
--quantity 5
|
|
267
|
-
--order-id order_456
|
|
228
|
+
--id prod_123 \
|
|
229
|
+
--quantity 5
|
|
268
230
|
```
|
|
269
231
|
|
|
270
232
|
### 查看库存历史
|
|
271
233
|
```bash
|
|
272
234
|
# 用户说:"查看商品prod_123的库存变更记录"
|
|
273
|
-
commerce inventory history
|
|
274
|
-
--product-id prod_123 \
|
|
275
|
-
--limit 20
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
### 批量查看库存
|
|
279
|
-
```bash
|
|
280
|
-
# 用户说:"查看所有商品的库存情况"
|
|
281
|
-
commerce inventory list --limit 100
|
|
235
|
+
commerce inventory history --id prod_123
|
|
282
236
|
```
|
|
283
237
|
|
|
284
238
|
## 重要提示
|
|
285
239
|
|
|
286
240
|
- 库存变更会自动记录历史
|
|
287
241
|
- 预留库存不会减少可用库存数量
|
|
288
|
-
-
|
|
289
|
-
- 低库存阈值可以自定义
|
|
290
|
-
- 支持批量库存更新(通过脚本循环调用)
|
|
242
|
+
- 低库存阈值可自定义(默认5)
|
|
291
243
|
- 使用 `--help` 查看命令详细参数
|
|
@@ -19,19 +19,19 @@ commerce merchant info
|
|
|
19
19
|
|
|
20
20
|
### 更新店铺信息
|
|
21
21
|
```bash
|
|
22
|
-
commerce merchant update --name "新店铺名" --description "描述" --currency USD
|
|
22
|
+
commerce merchant update --name "新店铺名" --description "描述" --default-currency USD
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
可更新的字段:
|
|
26
26
|
- `--name`: 店铺名称
|
|
27
27
|
- `--slug`: 店铺标识(URL 友好)
|
|
28
28
|
- `--description`: 店铺描述
|
|
29
|
-
- `--currency`: 默认货币(USD, CNY, EUR 等)
|
|
29
|
+
- `--default-currency`: 默认货币(USD, CNY, EUR 等)
|
|
30
30
|
- `--contact-name`: 联系人姓名
|
|
31
31
|
- `--contact-phone`: 联系电话
|
|
32
32
|
- `--contact-email`: 联系邮箱
|
|
33
|
-
- `--company`: 公司名称
|
|
34
|
-
- `--
|
|
33
|
+
- `--company-name`: 公司名称
|
|
34
|
+
- `--origin-*`: 发货地址字段(origin-country-alpha2, origin-city, origin-postal-code 等)
|
|
35
35
|
|
|
36
36
|
## 完整命令列表
|
|
37
37
|
|
|
@@ -46,10 +46,10 @@ commerce merchant update --name "我的店铺" --description "这是一个很棒
|
|
|
46
46
|
commerce merchant update --contact-name "张三" --contact-phone "1234567890" --contact-email "contact@example.com"
|
|
47
47
|
|
|
48
48
|
# 更新发货地址
|
|
49
|
-
commerce merchant update --
|
|
49
|
+
commerce merchant update --origin-country-alpha2 "CN" --origin-city "深圳" --origin-postal-code "518000"
|
|
50
50
|
|
|
51
51
|
# 更新多个字段
|
|
52
|
-
commerce merchant update --name "新店铺" --currency "CNY" --company "我的公司"
|
|
52
|
+
commerce merchant update --name "新店铺" --default-currency "CNY" --company-name "我的公司"
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
## 工作流示例
|
|
@@ -75,9 +75,9 @@ commerce merchant update \
|
|
|
75
75
|
--contact-name "张三" \
|
|
76
76
|
--contact-phone "13800138000" \
|
|
77
77
|
--contact-email "shop@example.com" \
|
|
78
|
-
--
|
|
79
|
-
--
|
|
80
|
-
--
|
|
78
|
+
--origin-country-alpha2 "CN" \
|
|
79
|
+
--origin-city "深圳" \
|
|
80
|
+
--origin-postal-code "518000"
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
### 示例 3:修改店铺名称
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: product
|
|
3
|
-
description: Product catalog management for e-commerce stores. Create and update products, manage variants/SKUs, upload product images, organize tags
|
|
3
|
+
description: Product catalog management for e-commerce stores. Create and update products, manage variants/SKUs, upload product images, organize tags. Use when user needs to add new products, update pricing, manage product inventory, upload photos, or organize product catalog.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Commerce CLI - Product Management
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
商品管理模块,用于电商商品目录的创建、编辑和组织。
|
|
9
9
|
|
|
10
10
|
## 典型场景
|
|
11
11
|
|
|
@@ -73,45 +73,6 @@ commerce upload image --path ./new-photo.jpg # 获得 media_new
|
|
|
73
73
|
commerce product add-images --id prod_123 --media-id media_new
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
### 场景6:创建商品集合
|
|
77
|
-
|
|
78
|
-
**推荐集合类型**:
|
|
79
|
-
- **时令集合** - 春夏秋冬、节日促销(如"Christmas Sale")
|
|
80
|
-
- **品类集合** - 按商品类型分组(如"T-Shirts", "Dresses")
|
|
81
|
-
- **主题集合** - 按场景分组(如"Office Wear", "Casual Style")
|
|
82
|
-
- **促销集合** - 新品、热卖、折扣(如"New Arrivals", "Best Sellers")
|
|
83
|
-
|
|
84
|
-
**创建流程**:
|
|
85
|
-
```bash
|
|
86
|
-
# 1. 创建集合
|
|
87
|
-
commerce collection create \
|
|
88
|
-
--name "Summer Sale 2024" \
|
|
89
|
-
--slug "summer-sale-2024" \
|
|
90
|
-
--description "Hot deals for summer"
|
|
91
|
-
|
|
92
|
-
# 2. 添加商品到集合
|
|
93
|
-
commerce collection add-products \
|
|
94
|
-
--slug summer-sale-2024 \
|
|
95
|
-
--product-ids prod_123,prod_456,prod_789
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### 场景7:设置集合封面图
|
|
99
|
-
|
|
100
|
-
**三种方式**:
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
# 方式 1:使用 Media ID(推荐,可复用已上传图片)
|
|
104
|
-
commerce upload image --path ./cover.jpg
|
|
105
|
-
# 获取 media_id: media_456
|
|
106
|
-
commerce collection set-cover --id coll-123 --media-id media_456
|
|
107
|
-
|
|
108
|
-
# 方式 2:使用 URL
|
|
109
|
-
commerce collection set-cover --id coll-123 --url "https://example.com/cover.jpg"
|
|
110
|
-
|
|
111
|
-
# 方式 3:上传本地文件
|
|
112
|
-
commerce collection set-cover --id coll-123 --path ./cover.jpg
|
|
113
|
-
```
|
|
114
|
-
|
|
115
76
|
### 场景决策表
|
|
116
77
|
|
|
117
78
|
| 用户需求 | 推荐命令 | 关键注意点 |
|
|
@@ -122,8 +83,6 @@ commerce collection set-cover --id coll-123 --path ./cover.jpg
|
|
|
122
83
|
| 更新价格 | `product update --price` | 如有变体,需逐个更新变体价格 |
|
|
123
84
|
| 促销标签 | `product update --tags` | 用逗号分隔,保留原有标签 |
|
|
124
85
|
| 图片更新 | `upload` + `add-images` | 先上传再关联,不要直接删除旧图 |
|
|
125
|
-
| 创建促销集合 | `collection create --slug sale` | slug 简短有意义,添加10-30个商品 |
|
|
126
|
-
| 设置集合封面 | `collection set-cover --id XX` | 支持 media-id/url/path 三种方式 |
|
|
127
86
|
|
|
128
87
|
## 卓越标准
|
|
129
88
|
|
|
@@ -219,54 +178,6 @@ commerce product update --id prod_123 --tags "featured,new,sale"
|
|
|
219
178
|
commerce product create --title "T恤" --price 99 --stock 50 # 确保真实有50件
|
|
220
179
|
```
|
|
221
180
|
|
|
222
|
-
### ❌ 问题6:集合命名随意,无规划
|
|
223
|
-
|
|
224
|
-
**错误做法**:
|
|
225
|
-
```bash
|
|
226
|
-
# 命名不规范,slug 无意义
|
|
227
|
-
commerce collection create --name "aaa" --slug "test123"
|
|
228
|
-
commerce collection create --name "商品111" --slug "product-collection"
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
**正确做法**:
|
|
232
|
-
```bash
|
|
233
|
-
# 命名清晰,slug 符合 SEO 规范
|
|
234
|
-
commerce collection create --name "Summer Sale 2024" --slug "summer-sale-2024"
|
|
235
|
-
commerce collection create --name "Men's T-Shirts" --slug "mens-tshirts"
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### ❌ 问题7:集合缺少商品
|
|
239
|
-
|
|
240
|
-
**错误做法**:
|
|
241
|
-
```bash
|
|
242
|
-
# 创建集合后忘记添加商品
|
|
243
|
-
commerce collection create --name "New Arrivals" --slug "new-arrivals"
|
|
244
|
-
# 集合页面显示空白
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
**正确做法**:
|
|
248
|
-
```bash
|
|
249
|
-
# 创建集合后立即添加商品(至少5个)
|
|
250
|
-
commerce collection create --name "New Arrivals" --slug "new-arrivals"
|
|
251
|
-
commerce collection add-products --slug new-arrivals --product-ids prod_1,prod_2,prod_3,prod_4,prod_5
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### ❌ 问题8:slug 使用中文或特殊字符
|
|
255
|
-
|
|
256
|
-
**错误做法**:
|
|
257
|
-
```bash
|
|
258
|
-
# slug 包含中文或特殊字符,影响 SEO 和 URL 可读性
|
|
259
|
-
commerce collection create --name "夏季促销" --slug "夏季促销"
|
|
260
|
-
commerce collection create --name "Sale!!!" --slug "sale!!!"
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
**正确做法**:
|
|
264
|
-
```bash
|
|
265
|
-
# slug 使用英文、数字、连字符
|
|
266
|
-
commerce collection create --name "夏季促销" --slug "summer-sale"
|
|
267
|
-
commerce collection create --name "Sale!!!" --slug "sale"
|
|
268
|
-
```
|
|
269
|
-
|
|
270
181
|
## 命令参考
|
|
271
182
|
|
|
272
183
|
### 自然语言映射
|
|
@@ -278,11 +189,6 @@ commerce collection create --name "Sale!!!" --slug "sale"
|
|
|
278
189
|
- "更新商品价格" → `commerce product update --id XX --price YY`
|
|
279
190
|
- "给商品打标签" → `commerce product update --id XX --tags "featured,new"`
|
|
280
191
|
- "查看所有商品" → `commerce product list`
|
|
281
|
-
- "创建商品集合" → `commerce collection create --name XX --slug YY`
|
|
282
|
-
- "把商品添加到集合" → `commerce collection add-products --slug XX --product-ids YY`
|
|
283
|
-
- "设置集合封面图" → `commerce collection set-cover --id XX --media-id YY`
|
|
284
|
-
- "上传集合封面" → `commerce collection set-cover --id XX --path ./cover.jpg`
|
|
285
|
-
- "集合封面图 URL 是 https://..." → `commerce collection set-cover --id XX --url "https://..."`
|
|
286
192
|
|
|
287
193
|
### 核心功能
|
|
288
194
|
|
|
@@ -304,15 +210,6 @@ commerce collection create --name "Sale!!!" --slug "sale"
|
|
|
304
210
|
- `commerce product add-images` - 关联图片到商品
|
|
305
211
|
- `commerce product remove-images` - 移除商品图片
|
|
306
212
|
|
|
307
|
-
**商品集合**:
|
|
308
|
-
- `commerce collection create` - 创建集合
|
|
309
|
-
- `commerce collection list` - 查看集合列表
|
|
310
|
-
- `commerce collection update` - 更新集合
|
|
311
|
-
- `commerce collection delete` - 删除集合
|
|
312
|
-
- `commerce collection add-products` - 添加商品到集合
|
|
313
|
-
- `commerce collection remove-products` - 从集合移除商品
|
|
314
|
-
- `commerce collection set-cover` - 设置集合封面图(支持 media-id/url/path)
|
|
315
|
-
|
|
316
213
|
## 详细示例
|
|
317
214
|
|
|
318
215
|
### 示例1:创建单个商品
|
|
@@ -398,38 +295,6 @@ commerce product add-images --id prod_123 --media-id media_red,media_blue
|
|
|
398
295
|
commerce product get --id prod_123
|
|
399
296
|
```
|
|
400
297
|
|
|
401
|
-
### 示例7:创建商品集合
|
|
402
|
-
```bash
|
|
403
|
-
# 用户说:"创建夏季促销集合"
|
|
404
|
-
commerce collection create \
|
|
405
|
-
--name "Summer Sale" \
|
|
406
|
-
--slug summer-sale \
|
|
407
|
-
--description "Hot deals for summer"
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
### 示例8:添加商品到集合
|
|
411
|
-
```bash
|
|
412
|
-
# 用户说:"把商品prod_123和prod_456添加到summer-sale集合"
|
|
413
|
-
commerce collection add-products \
|
|
414
|
-
--slug summer-sale \
|
|
415
|
-
--product-ids prod_123,prod_456
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
### 示例9:设置集合封面图
|
|
419
|
-
```bash
|
|
420
|
-
# 用户说:"给集合设置封面图"
|
|
421
|
-
|
|
422
|
-
# 方式 1:使用 Media ID(推荐)
|
|
423
|
-
commerce upload image --path ./cover.jpg # 获得 media_456
|
|
424
|
-
commerce collection set-cover --id coll-123 --media-id media_456
|
|
425
|
-
|
|
426
|
-
# 方式 2:使用 URL
|
|
427
|
-
commerce collection set-cover --id coll-123 --url "https://example.com/cover.jpg"
|
|
428
|
-
|
|
429
|
-
# 方式 3:上传本地文件
|
|
430
|
-
commerce collection set-cover --id coll-123 --path ./cover.jpg
|
|
431
|
-
```
|
|
432
|
-
|
|
433
298
|
## 重要提示
|
|
434
299
|
|
|
435
300
|
- 所有命令默认 JSON 输出,便于 AI 解析
|
|
@@ -440,5 +305,3 @@ commerce collection set-cover --id coll-123 --path ./cover.jpg
|
|
|
440
305
|
- 使用 `--help` 查看命令详细参数
|
|
441
306
|
- 删除商品会同时删除所有变体和图片关联
|
|
442
307
|
- 价格单位默认为美元(USD),可通过后台配置修改
|
|
443
|
-
- 集合 slug 必须唯一,用于 URL,使用英文和连字符
|
|
444
|
-
- 集合封面支持三种方式:`--media-id`(推荐)、`--url`、`--path`
|
|
@@ -72,7 +72,7 @@ content 支持模板变量,在前端渲染时自动替换:
|
|
|
72
72
|
- "覆盖护理说明" → `commerce product-page create --handle care --operation-type override ...`
|
|
73
73
|
- "隐藏环保说明" → `commerce product-page hide --handle eco-friendly`
|
|
74
74
|
- "添加品牌故事区块" → `commerce product-page create --handle brand-story --operation-type new ...`
|
|
75
|
-
- "调整区块顺序" → `commerce product-page reorder --
|
|
75
|
+
- "调整区块顺序" → `commerce product-page reorder --sections '[{"handle":"h1","position":1},{"handle":"h2","position":2}]'`
|
|
76
76
|
- "给某商品单独设置" → `commerce product-page product create --product-handle xxx ...`
|
|
77
77
|
|
|
78
78
|
## 命令参考
|
|
@@ -85,7 +85,7 @@ content 支持模板变量,在前端渲染时自动替换:
|
|
|
85
85
|
- `commerce product-page update --handle <handle>` - 更新区块
|
|
86
86
|
- `commerce product-page delete --handle <handle> --yes` - 删除自定义
|
|
87
87
|
- `commerce product-page hide --handle <handle>` - 隐藏区块(快捷方式)
|
|
88
|
-
- `commerce product-page reorder --
|
|
88
|
+
- `commerce product-page reorder --sections <json>` - 重新排序(JSON 格式:`[{"handle":"xx","position":1}]`)
|
|
89
89
|
|
|
90
90
|
### 商品级命令(仅影响单个商品)
|
|
91
91
|
|
|
@@ -17,7 +17,7 @@ description: Review management and moderation. View, approve, reject, and respon
|
|
|
17
17
|
- "设为精选" → `commerce review feature --id XX --enable`
|
|
18
18
|
- "查看举报" → `commerce review reports --status pending`
|
|
19
19
|
- "查看评价设置" → `commerce review get-settings`
|
|
20
|
-
- "开启自动审核" → `commerce review update-settings --auto-approve
|
|
20
|
+
- "开启自动审核" → `commerce review update-settings --auto-approve`
|
|
21
21
|
|
|
22
22
|
### 场景决策表
|
|
23
23
|
|
|
@@ -30,7 +30,7 @@ description: Review management and moderation. View, approve, reject, and respon
|
|
|
30
30
|
| 处理举报 | `review handle-report` | 核实后决定删除或驳回 |
|
|
31
31
|
| 查看统计 | `review stats` | 监控平均分和评分分布趋势 |
|
|
32
32
|
| 查看设置 | `review get-settings` | 了解当前自动审核等配置 |
|
|
33
|
-
| 开启自动审核 | `review update-settings --auto-approve` |
|
|
33
|
+
| 开启自动审核 | `review update-settings --auto-approve` | 所有评价自动通过 |
|
|
34
34
|
|
|
35
35
|
### 标准评价管理流程
|
|
36
36
|
1. **每日审核** - `commerce review list --status pending` 查看待审核
|
|
@@ -202,31 +202,27 @@ commerce review get-settings
|
|
|
202
202
|
|
|
203
203
|
### 更新评价设置
|
|
204
204
|
```bash
|
|
205
|
-
# 用户说:"
|
|
206
|
-
commerce review update-settings
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
# 允许用户上传图片和视频
|
|
214
|
-
commerce review update-settings \
|
|
215
|
-
--allow-media \
|
|
216
|
-
--max-images 5 \
|
|
217
|
-
--max-videos 1
|
|
205
|
+
# 用户说:"开启自动审核"
|
|
206
|
+
commerce review update-settings --auto-approve
|
|
207
|
+
|
|
208
|
+
# 设置评价时间窗口(订单后30天内可评价)
|
|
209
|
+
commerce review update-settings --review-window-days 30
|
|
210
|
+
|
|
211
|
+
# 允许用户上传图片,设置最大5张
|
|
212
|
+
commerce review update-settings --allow-images --max-images 5
|
|
218
213
|
```
|
|
219
214
|
|
|
220
215
|
## 评价设置配置项
|
|
221
216
|
|
|
222
|
-
| 配置 | 说明 |
|
|
223
|
-
|
|
224
|
-
| `
|
|
225
|
-
| `
|
|
226
|
-
| `
|
|
227
|
-
| `
|
|
228
|
-
| `
|
|
229
|
-
| `
|
|
217
|
+
| 配置 | 说明 |
|
|
218
|
+
|------|------|
|
|
219
|
+
| `--auto-approve` | 新评价自动通过 |
|
|
220
|
+
| `--require-purchase` | 需要验证购买才能评价 |
|
|
221
|
+
| `--allow-anonymous` | 允许匿名评价 |
|
|
222
|
+
| `--review-window-days` | 评价时间窗口(1-365天)|
|
|
223
|
+
| `--allow-images` | 允许上传图片 |
|
|
224
|
+
| `--max-images` | 最大图片数(0-10)|
|
|
225
|
+
| `--allow-edit` | 允许编辑评价 |
|
|
230
226
|
|
|
231
227
|
## 重要提示
|
|
232
228
|
|
package/dist/bin/bi-cli.js
CHANGED
|
File without changes
|
package/dist/bin/comfy.js
CHANGED
|
File without changes
|
package/dist/bin/commerce.js
CHANGED
|
File without changes
|
package/dist/bin/google-ads.js
CHANGED
|
File without changes
|
package/dist/bin/optima.js
CHANGED
|
File without changes
|
package/dist/bin/scout.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../src/ui/App.tsx"],"names":[],"mappings":"AAcA,UAAU,QAAQ;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,QAAQ,2CAqMpC"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useCallback, useRef } from "react";
|
|
3
|
+
import { Box, useApp, useInput } from "ink";
|
|
4
|
+
import { Header, Composer, MessageList, StatusBar, Spinner, } from "./components/index.js";
|
|
5
|
+
import { OptimaAgent } from "../agent.js";
|
|
6
|
+
const VERSION = "0.1.25";
|
|
7
|
+
export function App({ cwd }) {
|
|
8
|
+
const { exit } = useApp();
|
|
9
|
+
const [input, setInput] = useState("");
|
|
10
|
+
const [messages, setMessages] = useState([]);
|
|
11
|
+
const [isProcessing, setIsProcessing] = useState(false);
|
|
12
|
+
const [skills, setSkills] = useState([]);
|
|
13
|
+
const [tokens, setTokens] = useState();
|
|
14
|
+
const [agent] = useState(() => new OptimaAgent({ cwd }));
|
|
15
|
+
const abortControllerRef = useRef(null);
|
|
16
|
+
// 处理斜杠命令
|
|
17
|
+
const handleSlashCommand = useCallback((command) => {
|
|
18
|
+
const cmd = command.toLowerCase().trim();
|
|
19
|
+
if (cmd === "/help") {
|
|
20
|
+
setMessages((prev) => [
|
|
21
|
+
...prev,
|
|
22
|
+
{
|
|
23
|
+
role: "assistant",
|
|
24
|
+
content: `可用命令:
|
|
25
|
+
/help - 显示帮助
|
|
26
|
+
/clear - 清空对话
|
|
27
|
+
/skills - 查看已加载技能
|
|
28
|
+
/exit - 退出`,
|
|
29
|
+
},
|
|
30
|
+
]);
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
if (cmd === "/clear") {
|
|
34
|
+
setMessages([]);
|
|
35
|
+
agent.reset();
|
|
36
|
+
setSkills([]);
|
|
37
|
+
setTokens(undefined);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
if (cmd === "/skills") {
|
|
41
|
+
setMessages((prev) => [
|
|
42
|
+
...prev,
|
|
43
|
+
{
|
|
44
|
+
role: "assistant",
|
|
45
|
+
content: skills.length > 0
|
|
46
|
+
? `已加载技能: ${skills.join(", ")}`
|
|
47
|
+
: "暂无已加载技能",
|
|
48
|
+
},
|
|
49
|
+
]);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
if (cmd === "/exit") {
|
|
53
|
+
exit();
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}, [agent, exit, skills]);
|
|
58
|
+
// 取消当前请求
|
|
59
|
+
const handleCancel = useCallback(() => {
|
|
60
|
+
if (abortControllerRef.current) {
|
|
61
|
+
abortControllerRef.current.abort();
|
|
62
|
+
abortControllerRef.current = null;
|
|
63
|
+
setIsProcessing(false);
|
|
64
|
+
setMessages((prev) => [
|
|
65
|
+
...prev,
|
|
66
|
+
{ role: "system", content: "已取消" },
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
}, []);
|
|
70
|
+
// 处理消息提交
|
|
71
|
+
const handleSubmit = useCallback(async (text) => {
|
|
72
|
+
// 检查斜杠命令
|
|
73
|
+
if (text.startsWith("/")) {
|
|
74
|
+
if (handleSlashCommand(text)) {
|
|
75
|
+
setInput("");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// 添加用户消息
|
|
80
|
+
setMessages((prev) => [...prev, { role: "user", content: text }]);
|
|
81
|
+
setInput("");
|
|
82
|
+
setIsProcessing(true);
|
|
83
|
+
// 创建 AbortController
|
|
84
|
+
const abortController = new AbortController();
|
|
85
|
+
abortControllerRef.current = abortController;
|
|
86
|
+
let assistantContent = "";
|
|
87
|
+
try {
|
|
88
|
+
for await (const msg of agent.chat(text, { signal: abortController.signal })) {
|
|
89
|
+
// 处理系统消息(获取 skills)
|
|
90
|
+
if (msg.type === "system" && "skills" in msg && msg.skills) {
|
|
91
|
+
const skillsData = msg.skills;
|
|
92
|
+
setSkills(skillsData.filter(Boolean));
|
|
93
|
+
}
|
|
94
|
+
// 处理助手消息
|
|
95
|
+
if (msg.type === "assistant" && msg.message?.content) {
|
|
96
|
+
for (const block of msg.message.content) {
|
|
97
|
+
if (block.type === "text") {
|
|
98
|
+
assistantContent += block.text;
|
|
99
|
+
}
|
|
100
|
+
else if (block.type === "tool_use") {
|
|
101
|
+
// 显示工具调用
|
|
102
|
+
setMessages((prev) => [
|
|
103
|
+
...prev,
|
|
104
|
+
{
|
|
105
|
+
role: "tool",
|
|
106
|
+
toolName: block.name,
|
|
107
|
+
content: typeof block.input === "string"
|
|
108
|
+
? block.input
|
|
109
|
+
: JSON.stringify(block.input, null, 2),
|
|
110
|
+
},
|
|
111
|
+
]);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// 处理结果(累计 tokens)
|
|
116
|
+
if (msg.type === "result") {
|
|
117
|
+
const usage = msg.usage;
|
|
118
|
+
setTokens((prev) => ({
|
|
119
|
+
input: (prev?.input ?? 0) + (usage?.input_tokens ?? 0),
|
|
120
|
+
output: (prev?.output ?? 0) + (usage?.output_tokens ?? 0),
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// 添加助手回复
|
|
125
|
+
if (assistantContent) {
|
|
126
|
+
setMessages((prev) => [
|
|
127
|
+
...prev,
|
|
128
|
+
{ role: "assistant", content: assistantContent },
|
|
129
|
+
]);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
// 用户取消不显示错误
|
|
134
|
+
const errorMsg = error instanceof Error ? error.message : "未知错误";
|
|
135
|
+
if (!errorMsg.includes("aborted")) {
|
|
136
|
+
setMessages((prev) => [
|
|
137
|
+
...prev,
|
|
138
|
+
{
|
|
139
|
+
role: "error",
|
|
140
|
+
content: errorMsg,
|
|
141
|
+
},
|
|
142
|
+
]);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
setIsProcessing(false);
|
|
147
|
+
abortControllerRef.current = null;
|
|
148
|
+
}
|
|
149
|
+
}, [agent, handleSlashCommand]);
|
|
150
|
+
// 快捷键
|
|
151
|
+
useInput((input, key) => {
|
|
152
|
+
if (key.ctrl && input === "c") {
|
|
153
|
+
exit();
|
|
154
|
+
}
|
|
155
|
+
if (key.ctrl && input === "l") {
|
|
156
|
+
setMessages([]);
|
|
157
|
+
}
|
|
158
|
+
if (key.escape && isProcessing) {
|
|
159
|
+
handleCancel();
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
return (_jsxs(Box, { flexDirection: "column", height: "100%", children: [_jsx(Header, { version: VERSION }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [_jsx(MessageList, { messages: messages }), isProcessing && _jsx(Spinner, {})] }), _jsx(StatusBar, { skills: skills, tokens: tokens }), _jsx(Composer, { value: input, onChange: setInput, onSubmit: handleSubmit, disabled: isProcessing })] }));
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=App.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.js","sourceRoot":"","sources":["../../../src/ui/App.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface ComposerProps {
|
|
3
|
+
value: string;
|
|
4
|
+
onChange: (value: string) => void;
|
|
5
|
+
onSubmit: (value: string) => void;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare const Composer: React.NamedExoticComponent<ComposerProps>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=Composer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Composer.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/Composer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAIjD,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,QAAQ,2CA6BnB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useCallback } from "react";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
import TextInput from "ink-text-input";
|
|
5
|
+
export const Composer = memo(function Composer({ value, onChange, onSubmit, disabled = false, }) {
|
|
6
|
+
const handleSubmit = useCallback((text) => {
|
|
7
|
+
if (text.trim()) {
|
|
8
|
+
onSubmit(text.trim());
|
|
9
|
+
}
|
|
10
|
+
}, [onSubmit]);
|
|
11
|
+
return (_jsxs(Box, { borderStyle: "single", borderColor: disabled ? "gray" : "green", paddingX: 1, children: [_jsxs(Text, { color: disabled ? "gray" : "green", bold: true, children: [">", " "] }), disabled ? (_jsx(Text, { color: "gray", children: "\u8BF7\u7B49\u5F85\u54CD\u5E94..." })) : (_jsx(TextInput, { value: value, onChange: onChange, onSubmit: handleSubmit, placeholder: "\u8F93\u5165\u6D88\u606F\u6216 /help \u83B7\u53D6\u5E2E\u52A9" }))] }));
|
|
12
|
+
});
|
|
13
|
+
//# sourceMappingURL=Composer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Composer.js","sourceRoot":"","sources":["../../../../src/ui/components/Composer.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,SAAS,MAAM,gBAAgB,CAAC;AASvC,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,QAAQ,CAAC,EAC7C,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,GAAG,KAAK,GACF;IACd,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,IAAY,EAAE,EAAE;QAChD,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YAChB,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,OAAO,CACL,MAAC,GAAG,IAAC,WAAW,EAAC,QAAQ,EAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,aAC7E,MAAC,IAAI,IAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,mBAC3C,GAAG,EAAE,GAAG,IACJ,EACN,QAAQ,CAAC,CAAC,CAAC,CACV,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,kDAAgB,CACnC,CAAC,CAAC,CAAC,CACF,KAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,YAAY,EACtB,WAAW,EAAC,+DAAkB,GAC9B,CACH,IACG,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/Header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAe,MAAM,OAAO,CAAC;AAGpC,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,MAAM,yCAWjB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from "react";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
export const Header = memo(function Header({ version }) {
|
|
5
|
+
return (_jsxs(Box, { borderStyle: "single", paddingX: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "Optima Agent" }), _jsxs(Text, { color: "gray", children: [" v", version] }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: "gray", children: "[Ctrl+C \u9000\u51FA]" })] }));
|
|
6
|
+
});
|
|
7
|
+
//# sourceMappingURL=Header.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Header.js","sourceRoot":"","sources":["../../../../src/ui/components/Header.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAMhC,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,MAAM,CAAC,EAAE,OAAO,EAAe;IACjE,OAAO,CACL,MAAC,GAAG,IAAC,WAAW,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,aACnC,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,MAAM,6BAEhB,EACP,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,mBAAI,OAAO,IAAQ,EACrC,KAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,GAAI,EACpB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,sCAAmB,IACjC,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface MessageItem {
|
|
3
|
+
role: "user" | "assistant" | "tool" | "error" | "system";
|
|
4
|
+
content: string;
|
|
5
|
+
toolName?: string;
|
|
6
|
+
}
|
|
7
|
+
interface MessageProps {
|
|
8
|
+
message: MessageItem;
|
|
9
|
+
}
|
|
10
|
+
export declare const Message: React.NamedExoticComponent<MessageProps>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=Message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/Message.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAe,MAAM,OAAO,CAAC;AAGpC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,YAAY;IACpB,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,eAAO,MAAM,OAAO,0CAmDlB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from "react";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
export const Message = memo(function Message({ message }) {
|
|
5
|
+
const { role, content, toolName } = message;
|
|
6
|
+
if (role === "user") {
|
|
7
|
+
return (_jsxs(Box, { marginY: 1, children: [_jsxs(Text, { color: "green", bold: true, children: [">", " "] }), _jsx(Text, { children: content })] }));
|
|
8
|
+
}
|
|
9
|
+
if (role === "tool") {
|
|
10
|
+
return (_jsxs(Box, { marginY: 1, borderStyle: "round", borderColor: "gray", paddingX: 1, flexDirection: "column", children: [_jsx(Text, { color: "yellow", children: toolName || "Tool" }), _jsx(Text, { color: "gray", children: content })] }));
|
|
11
|
+
}
|
|
12
|
+
if (role === "error") {
|
|
13
|
+
return (_jsx(Box, { marginY: 1, children: _jsxs(Text, { color: "red", children: ["\u9519\u8BEF: ", content] }) }));
|
|
14
|
+
}
|
|
15
|
+
if (role === "system") {
|
|
16
|
+
return (_jsx(Box, { marginY: 1, children: _jsx(Text, { color: "gray", italic: true, children: content }) }));
|
|
17
|
+
}
|
|
18
|
+
// assistant
|
|
19
|
+
return (_jsx(Box, { marginY: 1, children: _jsx(Text, { children: content }) }));
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=Message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Message.js","sourceRoot":"","sources":["../../../../src/ui/components/Message.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAYhC,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,OAAO,CAAC,EAAE,OAAO,EAAgB;IACpE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE5C,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,OAAO,CACL,MAAC,GAAG,IAAC,OAAO,EAAE,CAAC,aACb,MAAC,IAAI,IAAC,KAAK,EAAC,OAAO,EAAC,IAAI,mBACrB,GAAG,EAAE,GAAG,IACJ,EACP,KAAC,IAAI,cAAE,OAAO,GAAQ,IAClB,CACP,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,OAAO,CACL,MAAC,GAAG,IACF,OAAO,EAAE,CAAC,EACV,WAAW,EAAC,OAAO,EACnB,WAAW,EAAC,MAAM,EAClB,QAAQ,EAAE,CAAC,EACX,aAAa,EAAC,QAAQ,aAEtB,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,YAAE,QAAQ,IAAI,MAAM,GAAQ,EAChD,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,OAAO,GAAQ,IAC/B,CACP,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO,CACL,KAAC,GAAG,IAAC,OAAO,EAAE,CAAC,YACb,MAAC,IAAI,IAAC,KAAK,EAAC,KAAK,+BAAM,OAAO,IAAQ,GAClC,CACP,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,CACL,KAAC,GAAG,IAAC,OAAO,EAAE,CAAC,YACb,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,MAAM,kBAAE,OAAO,GAAQ,GACtC,CACP,CAAC;IACJ,CAAC;IAED,YAAY;IACZ,OAAO,CACL,KAAC,GAAG,IAAC,OAAO,EAAE,CAAC,YACb,KAAC,IAAI,cAAE,OAAO,GAAQ,GAClB,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { MessageItem } from "./Message.js";
|
|
3
|
+
interface MessageListProps {
|
|
4
|
+
messages: MessageItem[];
|
|
5
|
+
maxVisible?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const MessageList: React.NamedExoticComponent<MessageListProps>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=MessageList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAE7C,OAAO,EAAW,WAAW,EAAE,MAAM,cAAc,CAAC;AAEpD,UAAU,gBAAgB;IACxB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,WAAW,8CA6BtB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useMemo } from "react";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
import { Message } from "./Message.js";
|
|
5
|
+
export const MessageList = memo(function MessageList({ messages, maxVisible = 10 }) {
|
|
6
|
+
// 只显示最近的消息,避免内容超出屏幕导致闪烁
|
|
7
|
+
const { visibleMessages, hiddenCount } = useMemo(() => {
|
|
8
|
+
if (messages.length <= maxVisible) {
|
|
9
|
+
return { visibleMessages: messages, hiddenCount: 0 };
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
visibleMessages: messages.slice(-maxVisible),
|
|
13
|
+
hiddenCount: messages.length - maxVisible,
|
|
14
|
+
};
|
|
15
|
+
}, [messages, maxVisible]);
|
|
16
|
+
return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [hiddenCount > 0 && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: "gray", italic: true, children: ["... ", hiddenCount, " \u6761\u5386\u53F2\u6D88\u606F\u5DF2\u9690\u85CF (\u4F7F\u7528 /clear \u6E05\u7A7A)"] }) })), visibleMessages.map((msg, index) => (_jsx(Message, { message: msg }, messages.length - maxVisible + index)))] }));
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=MessageList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageList.js","sourceRoot":"","sources":["../../../../src/ui/components/MessageList.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,OAAO,EAAe,MAAM,cAAc,CAAC;AAOpD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,WAAW,CAAC,EACnD,QAAQ,EACR,UAAU,GAAG,EAAE,EACE;IACjB,wBAAwB;IACxB,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;QACpD,IAAI,QAAQ,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;YAClC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;QACvD,CAAC;QACD,OAAO;YACL,eAAe,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC;YAC5C,WAAW,EAAE,QAAQ,CAAC,MAAM,GAAG,UAAU;SAC1C,CAAC;IACJ,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;IAE3B,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,aACpC,WAAW,GAAG,CAAC,IAAI,CAClB,KAAC,GAAG,IAAC,YAAY,EAAE,CAAC,YAClB,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,MAAM,2BAClB,WAAW,4FACX,GACH,CACP,EACA,eAAe,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CACnC,KAAC,OAAO,IAA4C,OAAO,EAAE,GAAG,IAAlD,QAAQ,CAAC,MAAM,GAAG,UAAU,GAAG,KAAK,CAAkB,CACrE,CAAC,IACE,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/Spinner.tsx"],"names":[],"mappings":"AAIA,UAAU,YAAY;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,OAAO,CAAC,EAAE,OAAkB,EAAE,EAAE,YAAY,2CAS3D"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import InkSpinner from "ink-spinner";
|
|
4
|
+
export function Spinner({ message = "思考中..." }) {
|
|
5
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: _jsx(InkSpinner, { type: "dots" }) }), _jsxs(Text, { color: "gray", children: [" ", message] })] }));
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=Spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.js","sourceRoot":"","sources":["../../../../src/ui/components/Spinner.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,UAAU,MAAM,aAAa,CAAC;AAMrC,MAAM,UAAU,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,EAAgB;IAC1D,OAAO,CACL,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAChB,KAAC,UAAU,IAAC,IAAI,EAAC,MAAM,GAAG,GACrB,EACP,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,kBAAG,OAAO,IAAQ,IAChC,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface StatusBarProps {
|
|
3
|
+
skills: string[];
|
|
4
|
+
tokens?: {
|
|
5
|
+
input: number;
|
|
6
|
+
output: number;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export declare const StatusBar: React.NamedExoticComponent<StatusBarProps>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=StatusBar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAe,MAAM,OAAO,CAAC;AAGpC,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5C;AAED,eAAO,MAAM,SAAS,4CAoBpB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from "react";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
export const StatusBar = memo(function StatusBar({ skills, tokens }) {
|
|
5
|
+
return (_jsxs(Box, { paddingX: 1, justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { color: "gray", children: "Skills: " }), skills.length > 0 ? (_jsx(Text, { color: "cyan", children: skills.join(", ") })) : (_jsx(Text, { color: "gray", children: "\u65E0" }))] }), tokens && (_jsx(Box, { children: _jsxs(Text, { color: "gray", children: ["Tokens: ", tokens.input.toLocaleString(), " in / ", tokens.output.toLocaleString(), " out"] }) }))] }));
|
|
6
|
+
});
|
|
7
|
+
//# sourceMappingURL=StatusBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../../src/ui/components/StatusBar.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAOhC,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAkB;IACjF,OAAO,CACL,MAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,EAAE,cAAc,EAAC,eAAe,aAC9C,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,yBAAgB,EACjC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACnB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAQ,CAC9C,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,uBAAS,CAC5B,IACG,EACL,MAAM,IAAI,CACT,KAAC,GAAG,cACF,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,yBACP,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,YAAQ,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,YACvE,GACH,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { Header } from "./Header.js";
|
|
2
|
+
export { Spinner } from "./Spinner.js";
|
|
3
|
+
export { Message, type MessageItem } from "./Message.js";
|
|
4
|
+
export { MessageList } from "./MessageList.js";
|
|
5
|
+
export { Composer } from "./Composer.js";
|
|
6
|
+
export { StatusBar } from "./StatusBar.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { Header } from "./Header.js";
|
|
2
|
+
export { Spinner } from "./Spinner.js";
|
|
3
|
+
export { Message } from "./Message.js";
|
|
4
|
+
export { MessageList } from "./MessageList.js";
|
|
5
|
+
export { Composer } from "./Composer.js";
|
|
6
|
+
export { StatusBar } from "./StatusBar.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ui/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAoB,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|