@optima-chat/optima-agent 0.8.102 → 0.9.0

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 (92) hide show
  1. package/.claude/skills/ads/SKILL.md +21 -18
  2. package/.claude/skills/channels/SKILL.md +179 -0
  3. package/.claude/skills/ingesting-sources/SKILL.md +30 -3
  4. package/.claude/skills/skillify/SKILL.md +114 -0
  5. package/dist/bin/bi-cli.js +0 -0
  6. package/dist/bin/browser-cli.js +0 -0
  7. package/dist/bin/channels.d.ts +3 -0
  8. package/dist/bin/channels.d.ts.map +1 -0
  9. package/dist/bin/channels.js +3 -0
  10. package/dist/bin/channels.js.map +1 -0
  11. package/dist/bin/commerce.js +0 -0
  12. package/dist/bin/gen.js +0 -0
  13. package/dist/bin/google-ads.js +0 -0
  14. package/dist/bin/logistics.js +0 -0
  15. package/dist/bin/optima.js +0 -0
  16. package/dist/bin/scout.js +0 -0
  17. package/dist/bin/sentinel.js +0 -0
  18. package/dist/bin/shopify.js +0 -0
  19. package/package.json +4 -2
  20. package/.claude/settings.local.json +0 -166
  21. package/dist/bin/comfy.d.ts +0 -3
  22. package/dist/bin/comfy.d.ts.map +0 -1
  23. package/dist/bin/comfy.js +0 -3
  24. package/dist/bin/comfy.js.map +0 -1
  25. package/dist/bin/growth.d.ts +0 -3
  26. package/dist/bin/growth.d.ts.map +0 -1
  27. package/dist/bin/growth.js +0 -3
  28. package/dist/bin/growth.js.map +0 -1
  29. package/dist/src/hooks-loader.d.ts +0 -6
  30. package/dist/src/hooks-loader.d.ts.map +0 -1
  31. package/dist/src/hooks-loader.js +0 -215
  32. package/dist/src/hooks-loader.js.map +0 -1
  33. package/dist/src/ui/App.d.ts +0 -6
  34. package/dist/src/ui/App.d.ts.map +0 -1
  35. package/dist/src/ui/App.js +0 -164
  36. package/dist/src/ui/App.js.map +0 -1
  37. package/dist/src/ui/components/Composer.d.ts +0 -10
  38. package/dist/src/ui/components/Composer.d.ts.map +0 -1
  39. package/dist/src/ui/components/Composer.js +0 -13
  40. package/dist/src/ui/components/Composer.js.map +0 -1
  41. package/dist/src/ui/components/Header.d.ts +0 -7
  42. package/dist/src/ui/components/Header.d.ts.map +0 -1
  43. package/dist/src/ui/components/Header.js +0 -7
  44. package/dist/src/ui/components/Header.js.map +0 -1
  45. package/dist/src/ui/components/Message.d.ts +0 -12
  46. package/dist/src/ui/components/Message.d.ts.map +0 -1
  47. package/dist/src/ui/components/Message.js +0 -21
  48. package/dist/src/ui/components/Message.js.map +0 -1
  49. package/dist/src/ui/components/MessageList.d.ts +0 -9
  50. package/dist/src/ui/components/MessageList.d.ts.map +0 -1
  51. package/dist/src/ui/components/MessageList.js +0 -18
  52. package/dist/src/ui/components/MessageList.js.map +0 -1
  53. package/dist/src/ui/components/Spinner.d.ts +0 -6
  54. package/dist/src/ui/components/Spinner.d.ts.map +0 -1
  55. package/dist/src/ui/components/Spinner.js +0 -7
  56. package/dist/src/ui/components/Spinner.js.map +0 -1
  57. package/dist/src/ui/components/StatusBar.d.ts +0 -11
  58. package/dist/src/ui/components/StatusBar.d.ts.map +0 -1
  59. package/dist/src/ui/components/StatusBar.js +0 -7
  60. package/dist/src/ui/components/StatusBar.js.map +0 -1
  61. package/dist/src/ui/components/index.d.ts +0 -7
  62. package/dist/src/ui/components/index.d.ts.map +0 -1
  63. package/dist/src/ui/components/index.js +0 -7
  64. package/dist/src/ui/components/index.js.map +0 -1
  65. package/dist/src/validation/error-formatter.d.ts +0 -21
  66. package/dist/src/validation/error-formatter.d.ts.map +0 -1
  67. package/dist/src/validation/error-formatter.js +0 -98
  68. package/dist/src/validation/error-formatter.js.map +0 -1
  69. package/dist/src/validation/index.d.ts +0 -10
  70. package/dist/src/validation/index.d.ts.map +0 -1
  71. package/dist/src/validation/index.js +0 -10
  72. package/dist/src/validation/index.js.map +0 -1
  73. package/dist/src/validation/json-validator.d.ts +0 -25
  74. package/dist/src/validation/json-validator.d.ts.map +0 -1
  75. package/dist/src/validation/json-validator.js +0 -173
  76. package/dist/src/validation/json-validator.js.map +0 -1
  77. package/dist/src/validation/schema.d.ts +0 -353
  78. package/dist/src/validation/schema.d.ts.map +0 -1
  79. package/dist/src/validation/schema.js +0 -57
  80. package/dist/src/validation/schema.js.map +0 -1
  81. package/dist/src/validation/suggestions.d.ts +0 -25
  82. package/dist/src/validation/suggestions.d.ts.map +0 -1
  83. package/dist/src/validation/suggestions.js +0 -144
  84. package/dist/src/validation/suggestions.js.map +0 -1
  85. package/dist/src/validation/types.d.ts +0 -40
  86. package/dist/src/validation/types.d.ts.map +0 -1
  87. package/dist/src/validation/types.js +0 -5
  88. package/dist/src/validation/types.js.map +0 -1
  89. package/dist/src/validation/yaml-validator.d.ts +0 -25
  90. package/dist/src/validation/yaml-validator.d.ts.map +0 -1
  91. package/dist/src/validation/yaml-validator.js +0 -177
  92. package/dist/src/validation/yaml-validator.js.map +0 -1
@@ -39,7 +39,7 @@ AI 广告官:通过 `~/ads/` 工作目录持续运营用户的付费广告投放
39
39
  2. `cat ~/ads/PROGRESS.md | head -30` — 上次做了什么、异常、下次待办
40
40
  3. `git -C ~/ads log --oneline -5` — 最近变更
41
41
  4. `ls ~/ads/campaigns/` — 列出本地登记的 campaign
42
- 5. `ads status --json` — 从后端拉事实: 在跑的 campaign 列表 + 7 天花费 + 钱包 + 月度 cap
42
+ 5. `ads status` — 从后端拉事实(默认 JSON 输出,加 `--pretty` 可读格式): 在跑的 campaign 列表 + 7 天花费 + 钱包 + 月度 cap
43
43
  - 如果钱包余额 < 阈值,第一时间告诉用户
44
44
  - 如果月度 cap 使用率 > 80%,同样提示
45
45
  - 如果后端 campaign 和本地目录对不齐,视为需要修复
@@ -60,7 +60,7 @@ AI 广告官:通过 `~/ads/` 工作目录持续运营用户的付费广告投放
60
60
  4. `ads init --total-monthly-budget <X>` — 后端创建 user_ads 记录 + 确保 Google Ads label 存在 + 查 USD wallet
61
61
  5. 把后端返回的 ID 自动填进 ADS.md 的"后端登记"段,`git commit -m "register backend"`
62
62
  6. 提示用户:
63
- - 钱包余额为 0 → "需要先充值. 说 'topup 100' 可充 $100"
63
+ - 钱包余额为 0 → "需要先充值. 说 'ads budget topup --amount 100' 可充 $100"
64
64
  - 有余额 → "可以现在 launch 第一个 campaign,或者下次会话再开始"
65
65
 
66
66
  **不会自动 launch 任何 campaign.** 第一次 launch 必须由用户明确要求。
@@ -81,7 +81,7 @@ AI 广告官:通过 `~/ads/` 工作目录持续运营用户的付费广告投放
81
81
  1. 读 ADS.md 拿整体策略,确认推什么产品、受众、预算
82
82
  2. 调 `gen image` 生成多个素材变体到 `~/ads/assets/`
83
83
  3. 构造 CampaignSpec JSON(参考下方"CampaignSpec 结构"),写到 `/tmp/spec.json`
84
- 4. `ads launch --spec /tmp/spec.json --reason "..."` — 默认 PAUSED
84
+ 4. `ads launch create --spec /tmp/spec.json --reason "..."` — 默认 PAUSED
85
85
  5. **必做**: 创建 `~/ads/campaigns/<slug>/` 子目录:
86
86
  ```bash
87
87
  slug=<campaign-slug>
@@ -103,11 +103,14 @@ AI 广告官:通过 `~/ads/` 工作目录持续运营用户的付费广告投放
103
103
  2. 读 `~/ads/campaigns/<slug>/CREATIVES.md` 看变体表现
104
104
  3. 读 `~/ads/LEARNINGS.md` 看历史经验
105
105
  4. 决定要改什么(一个或多个):
106
- - 淘汰低 CTR 素材: `ads optimize pause-creative <id> --reason "..."`
107
- - 加新关键词: `ads optimize add-keywords <ad_group_id> --keywords "..." --reason "..."`
108
- - 加否定词: `ads optimize add-negatives <ad_group_id> --keywords "..." --reason "..."`
109
- - 调出价修正: `ads optimize change-bid-mod <criterion_id> --modifier 1.2 --reason "..."`
110
- - 调预算: `ads budget set --campaign <id> --daily <usd> --reason "..."`
106
+ - 淘汰低 CTR 素材: `ads optimize pause-variant --campaign <id> --variant <id> --reason "..."`
107
+ - 恢复素材: `ads optimize resume-variant --campaign <id> --variant <id> --reason "..."`
108
+ - 加新关键词: `ads optimize add-keywords --campaign <id> --keywords "word1" "word2" --reason "..."`
109
+ - 移除关键词: `ads optimize remove-keywords --campaign <id> --keywords "word1" --reason "..."`
110
+ - 加否定词: `ads optimize add-negatives --campaign <id> --keywords "word1" "word2" --reason "..."`
111
+ - 调出价修正: `ads optimize change-bid-mod --campaign <id> --modifier 1.2 --reason "..."`
112
+ - 替换素材: `ads optimize replace-variant --campaign <id> --old-variant <id> --spec /tmp/v.json --reason "..."`
113
+ - 调预算: `ads budget set --campaign <id> --daily <micros> --reason "..."`
111
114
  5. 更新 `campaigns/<slug>/CREATIVES.md`(把被淘汰的变体移到"已淘汰"段)
112
115
  6. 追加一段到 `campaigns/<slug>/NOTES.md`(观察 + 推理 + 下次验证点)
113
116
  7. 如果这个洞察是可泛化的,也追加到 `~/ads/LEARNINGS.md`
@@ -119,8 +122,8 @@ AI 广告官:通过 `~/ads/` 工作目录持续运营用户的付费广告投放
119
122
  **触发**: 定时(每天)或作为其它动作的前置。
120
123
 
121
124
  **流程**:
122
- 1. `ads collect --days 7` → 后端从 Google Ads 拉 per-campaign 和 per-creative 的最新数据,返回 JSON
123
- 2. 对返回的每个 `creative_perf` 项,找到对应 `campaigns/<slug>/CREATIVES.md`(通过 `campaign_id` 匹配——每个 `campaigns/<slug>/STRATEGY.md` 的"后端关联"段记录了 `campaign_id`),用新 CTR/CVR/花费重写"在投变体"表
125
+ 1. `ads collect --days 7` → 后端从 Google Ads 拉 per-campaign 和 per-variant 的最新数据,返回 JSON
126
+ 2. 对返回的每个 snapshot 中的 `variantPerf` 项,找到对应 `campaigns/<slug>/CREATIVES.md`(通过 `campaign_id` 匹配——每个 `campaigns/<slug>/STRATEGY.md` 的"后端关联"段记录了 `campaign_id`),用新 CTR/CVR/花费重写"在投变体"表
124
127
  3. 如果是纯 collect session(不是被其它动作调用),追加一段到 PROGRESS.md 和 commit。
125
128
  如果是嵌入在其它动作里,则跟那个动作的 commit 合并。
126
129
 
@@ -140,9 +143,9 @@ AI 广告官:通过 `~/ads/` 工作目录持续运营用户的付费广告投放
140
143
  **触发**: 用户说"加预算"、"充钱"。
141
144
 
142
145
  **场景**:
143
- - "加到 $20/天" → `ads budget set --campaign <id> --daily 20 --reason "..."`
144
- - "月度上限改 $500" → `ads budget set --total-monthly 500 --reason "..."`
145
- - "充 $100" → `ads budget topup 100` → 把返回的 `checkout_url` 作为 markdown 链接输出给用户
146
+ - "加到 $20/天" → `ads budget set --campaign <id> --daily 20000000 --reason "..."`
147
+ - "月度上限改 $500" → `ads budget set --total-monthly 500000000 --reason "..."`
148
+ - "充 $100" → `ads budget topup --amount 100` → 把返回的 `checkout_url` 作为 markdown 链接输出给用户(topup 用 USD)
146
149
  - "看下预算" → `ads budget show`
147
150
 
148
151
  改完之后相应更新 `ADS.md`(月度 cap 变化)或 `campaigns/<slug>/STRATEGY.md`(campaign 日预算变化),commit。
@@ -154,7 +157,7 @@ AI 广告官:通过 `~/ads/` 工作目录持续运营用户的付费广告投放
154
157
  **流程**:
155
158
  - "停掉 XX campaign" → `ads pause campaign <id> --reason "..."`
156
159
  - "全停" → `ads pause all --reason "..."`
157
- - "停某个素材" → `ads pause creative <variant_id> --reason "..."`
160
+ - "停某个素材" → `ads pause variant <variant_id> --reason "..."`
158
161
  - "恢复" → `ads resume ...`(但钱包低余额或月度 cap 超出时会被后端拒)
159
162
 
160
163
  停掉之后在对应 `campaigns/<slug>/NOTES.md` 记一笔,commit。
@@ -176,12 +179,12 @@ AI 广告官:通过 `~/ads/` 工作目录持续运营用户的付费广告投放
176
179
  **触发**: 独立会话,聚焦素材质量。
177
180
 
178
181
  **流程**:
179
- 1. `ads status --include-creatives` 看现状
182
+ 1. `ads status --include-variants` 看现状
180
183
  2. 读 `~/ads/campaigns/<slug>/CREATIVES.md` 和 `~/ads/LEARNINGS.md`
181
184
  3. 决定要生成什么新变体(几个 prompt、什么风格)
182
185
  4. `gen image "<prompt>" -o ~/ads/assets` 多次调用
183
186
  5. 写进对应 `campaigns/<slug>/CREATIVES.md`
184
- 6. 如果要把新变体上线到现有 campaign: `ads optimize replace-creative <campaign_id> --new-spec /tmp/v.json --reason "..."`
187
+ 6. 如果要把新变体上线到现有 campaign: `ads optimize replace-variant --campaign <campaign_id> --old-variant <id> --spec /tmp/v.json --reason "..."`
185
188
  7. 如果只是建素材库待用,不上线,也 OK
186
189
  8. commit
187
190
 
@@ -201,8 +204,8 @@ AI 广告官:通过 `~/ads/` 工作目录持续运营用户的付费广告投放
201
204
  "intentSignals": ["夏季连衣裙", "summer dress"],
202
205
  "excludeSignals": ["免费", "free"]
203
206
  },
204
- "budget": { "dailyLimitUsd": 10 },
205
- "creatives": [
207
+ "budget": { "dailyLimitMicros": 10000000, "totalLimitMicros": 300000000 },
208
+ "variants": [
206
209
  {
207
210
  "variantId": "v_abc123",
208
211
  "headlines": ["标题1 最多 30 字", "标题2", "标题3", "标题4", "标题5"],
@@ -0,0 +1,179 @@
1
+ ---
2
+ name: channels
3
+ description: "社交渠道管理。接入/管理 Telegram、WhatsApp、Discord、Slack、飞书、LINE、Zalo 等社交渠道,绑定用户账号,发送通知。使用场景:接入渠道(connect channel)、绑定(bind)、社交(social)、Telegram、WhatsApp、Discord、Slack、飞书、LINE、Zalo、通知(notify)、推送(push)、消息(message)。"
4
+ ---
5
+
6
+ # Optima Channels - 社交渠道管理
7
+
8
+ 管理社交渠道接入、用户绑定和消息推送。支持 Telegram、WhatsApp、Discord、Slack、飞书、LINE、Zalo。
9
+
10
+ ## 典型场景
11
+
12
+ 当用户说:
13
+ - "帮我接入 Telegram" → 引导创建 bot → `channels accounts add telegram --account-id store --token <token>`
14
+ - "查看我的渠道" → `channels accounts list`
15
+ - "关掉 Telegram" → `channels accounts disable telegram store`
16
+ - "重新开启 Telegram" → `channels accounts enable telegram store`
17
+ - "删除 Telegram 渠道" → `channels accounts remove telegram store`
18
+ - "帮我绑定 Telegram" → `channels bind generate`
19
+ - "查看我的绑定" → `channels bind list`
20
+ - "解绑 Telegram" → `channels bind remove --platform telegram --account-id store --platform-uid 123456`
21
+ - "给用户发通知" → `channels send --user-id <id> --text "消息内容"`
22
+ - "广播消息" → `channels broadcast --text "消息" --user-ids id1,id2`
23
+ - "查看渠道状态" → `channels status`
24
+
25
+ ### 场景决策表
26
+
27
+ | 用户需求 | 推荐命令 | 关键注意点 |
28
+ |---------|---------|-----------|
29
+ | 接入新渠道 | `channels accounts add <platform>` | 不同平台需要不同参数,见下方 |
30
+ | 查看渠道列表 | `channels accounts list` | 显示所有账号及状态 |
31
+ | 启用/禁用渠道 | `channels accounts enable/disable` | 不删除配置,只是暂停 |
32
+ | 删除渠道 | `channels accounts remove` | 永久删除,需重新配置 |
33
+ | 绑定社交账号 | `channels bind generate` | 生成绑定码,用户在社交 App 发给 bot |
34
+ | 查看绑定 | `channels bind list` | 显示当前用户绑定的社交账号 |
35
+ | 解绑 | `channels bind remove` | 需要指定 platform、account-id、platform-uid |
36
+ | 发送通知 | `channels send` | 发到用户所有已绑定渠道 |
37
+ | 广播 | `channels broadcast` | 发给多个用户 |
38
+
39
+ ## 场景1:接入 Telegram
40
+
41
+ **流程**: 创建 Bot → 获取 Token → 添加到 Optima
42
+
43
+ ```bash
44
+ # 1. 引导用户:
45
+ # "请在 Telegram 找 @BotFather,发送 /newbot,按提示创建 bot,然后把 token 发给我"
46
+
47
+ # 2. 用户提供 token 后,添加渠道
48
+ channels accounts add telegram --account-id store --token "123456:AAHxxxxxxxxxx"
49
+
50
+ # 3. 验证
51
+ channels status
52
+ ```
53
+
54
+ ## 场景2:接入 Discord
55
+
56
+ ```bash
57
+ # 1. 引导用户:
58
+ # "请在 Discord Developer Portal (discord.com/developers) 创建 Application → Bot,
59
+ # 开启 MESSAGE CONTENT Intent,复制 Bot Token"
60
+
61
+ # 2. 添加渠道
62
+ channels accounts add discord --account-id store --token "MTA3xxx..."
63
+
64
+ # 3. 验证
65
+ channels status
66
+ ```
67
+
68
+ ## 场景3:接入 Slack
69
+
70
+ ```bash
71
+ # 1. 引导用户:
72
+ # "请在 api.slack.com 创建 App,启用 Socket Mode,获取 Bot Token 和 App Token"
73
+
74
+ # 2. 添加渠道
75
+ channels accounts add slack --account-id store \
76
+ --bot-token "xoxb-..." \
77
+ --app-token "xapp-..." \
78
+ --signing-secret "..."
79
+
80
+ # 3. 验证
81
+ channels status
82
+ ```
83
+
84
+ ## 场景4:接入飞书
85
+
86
+ ```bash
87
+ # 1. 引导用户:
88
+ # "请在飞书开发者后台创建应用,获取 App ID 和 App Secret"
89
+
90
+ # 2. 添加渠道
91
+ channels accounts add feishu --account-id store \
92
+ --app-id "cli_xxx" \
93
+ --app-secret "xxx"
94
+
95
+ # 3. 验证
96
+ channels status
97
+ ```
98
+
99
+ ## 场景5:接入 LINE
100
+
101
+ ```bash
102
+ # 1. 引导用户:
103
+ # "请在 LINE Developers Console 创建 Messaging API channel,获取 Channel Access Token 和 Channel Secret"
104
+
105
+ # 2. 添加渠道
106
+ channels accounts add line --account-id store \
107
+ --channel-access-token "xxx" \
108
+ --channel-secret "xxx"
109
+
110
+ # 3. 配置 Webhook URL(需在 LINE Developer Console 手动设置):
111
+ # https://channels-api.optima.onl/webhook/line/store
112
+
113
+ # 4. 验证
114
+ channels status
115
+ ```
116
+
117
+ ## 场景6:绑定社交账号
118
+
119
+ **流程**: 生成绑定码 → 用户在社交 App 发给 bot
120
+
121
+ ```bash
122
+ # 1. 生成绑定码(默认当前登录用户)
123
+ channels bind generate
124
+ # 输出: { "code": "BIND-A3X7K9", "expiresIn": 300 }
125
+
126
+ # 2. 告诉用户:
127
+ # "请在 Telegram 给 @YourBot 发送: BIND-A3X7K9(5分钟内有效)"
128
+
129
+ # 3. 确认绑定
130
+ channels bind list
131
+ ```
132
+
133
+ ## 场景7:发送通知
134
+
135
+ ```bash
136
+ # 发送给单个用户(发到所有已绑定渠道)
137
+ channels send --user-id "uuid-xxx" --text "您的订单 #1234 已发货"
138
+
139
+ # 指定渠道发送
140
+ channels send --user-id "uuid-xxx" --text "消息" --platform telegram
141
+
142
+ # 广播给多个用户
143
+ channels broadcast --text "新品上架!限时8折" --user-ids "uuid-1,uuid-2,uuid-3"
144
+ ```
145
+
146
+ ## 各平台必需参数
147
+
148
+ | 平台 | 必需参数 | 获取方式 |
149
+ |------|---------|---------|
150
+ | Telegram | `--token` | @BotFather 创建 bot |
151
+ | Discord | `--token` | Developer Portal → Bot |
152
+ | Slack | `--bot-token` `--app-token` `--signing-secret` | api.slack.com → App |
153
+ | LINE | `--channel-access-token` `--channel-secret` | LINE Developers Console |
154
+ | 飞书 | `--app-id` `--app-secret` | 飞书开发者后台 |
155
+ | WhatsApp | `--session-dir`(可选) | baileys QR 扫码认证 |
156
+ | Zalo | `--token` | Zalo Developer Console |
157
+
158
+ ## 命令参考
159
+
160
+ ```bash
161
+ # 状态
162
+ channels status
163
+
164
+ # 账号管理
165
+ channels accounts list
166
+ channels accounts add <platform> --account-id <id> [平台参数]
167
+ channels accounts remove <platform> <accountId>
168
+ channels accounts enable <platform> <accountId>
169
+ channels accounts disable <platform> <accountId>
170
+
171
+ # 绑定管理
172
+ channels bind generate [--user-id <id>]
173
+ channels bind list [--user-id <id>]
174
+ channels bind remove --platform <p> --account-id <a> --platform-uid <uid>
175
+
176
+ # 消息
177
+ channels send --user-id <id> --text "消息"
178
+ channels broadcast --text "消息" --user-ids "id1,id2"
179
+ ```
@@ -18,11 +18,34 @@ description: "将新素材收录到知识库。当用户说'收录这篇文章'
18
18
  - 多个 active → 根据用户问题匹配 `主题` + `说明` 字段;无法判断时列出让用户选
19
19
  4. 读 `~/kb/<slug>/AGENTS.md` 了解该 KB 的契约
20
20
 
21
+ ## 获取素材到 raw/
22
+
23
+ 用户可能通过以下方式提供素材:
24
+
25
+ - 本地文件路径 → `cp <path> ~/kb/<slug>/raw/<命名后的文件名>`
26
+ - URL → 下载到 `~/kb/<slug>/raw/`(用 WebFetch 或 curl)
27
+ - 直接贴图/附件 → 保存到 `~/kb/<slug>/raw/`
28
+
29
+ 文件命名规则:`YYYY-MM-DD-short-description.{ext}`,保留原始扩展名。
30
+
31
+ ## 按类型读取素材
32
+
33
+ | 类型 | 扩展名 | 读取方式 |
34
+ |------|--------|----------|
35
+ | 文本 | `.md` `.txt` | 直接读取 |
36
+ | PDF | `.pdf` | 直接读取(Claude 原生支持) |
37
+ | 图片 | `.png` `.jpg` `.webp` `.gif` | 用 Read 工具查看图片,生成文本描述 |
38
+ | 音频 | `.mp3` `.wav` `.m4a` | 加载 gen skill,调 ASR 转文字 |
39
+ | 视频 | `.mp4` `.mov` `.webm` | 加载 ffmpeg skill 提取音频 → ASR 转文字;提取关键帧 → 查看描述 |
40
+
41
+ 如果素材类型不在上表中,尝试直接读取;读不了就告诉用户不支持该格式。
42
+
21
43
  ## Ingest 流程
22
44
 
23
- 1. `~/kb/<slug>/raw/` 中定位来源文件
24
- 2. 仔细阅读来源,提取主要论点、证据、实体和开放问题
25
- 3. 在 `~/kb/<slug>/wiki/sources/` 中创建或更新对应页面
45
+ 1. 确认素材已在 `~/kb/<slug>/raw/` 中(如不在,先执行上方"获取素材"步骤)
46
+ 2. 按上方类型表读取素材内容
47
+ 3. 提取主要论点、证据、实体和开放问题
48
+ 4. 在 `~/kb/<slug>/wiki/sources/` 中创建或更新对应页面
26
49
  4. 列出哪些 entity、overview 和 analysis 页面受到影响
27
50
  5. 如果任务范围包含来源页之外的更新,交给 updating-related-pages 处理,或执行一次有边界的相关页更新
28
51
  6. 如果这个来源是首次进入 wiki,更新 `~/kb/<slug>/index.md` 和 `~/kb/<slug>/log.md`
@@ -34,6 +57,8 @@ description: "将新素材收录到知识库。当用户说'收录这篇文章'
34
57
  来源页应至少包含:
35
58
 
36
59
  - 来源标题
60
+ - 来源类型(文本 / 图片 / 音频 / 视频 / PDF)
61
+ - 原始文件路径(`raw/` 下的相对路径)
37
62
  - 简短摘要
38
63
  - 关键论点
39
64
  - 关键证据或观察
@@ -41,6 +66,8 @@ description: "将新素材收录到知识库。当用户说'收录这篇文章'
41
66
  - 对既有理解产生的冲突、修正或压力
42
67
  - 指向受影响页面的链接
43
68
 
69
+ 对于多媒体来源,描述就是 source page 的核心内容。如果描述不够准确,直接编辑 source page 或重新 ingest 即可——source page 是可变的,raw/ 里的原始文件才是不可变的。
70
+
44
71
  ## 抽取规则
45
72
 
46
73
  - 将来源明确表达的内容与综合推断区分开
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: skillify
3
+ description: "Create custom reusable skills from conversation patterns or described workflows"
4
+ when_to_use: "Use when user wants to create a skill, automate a workflow, save a repeatable process, or says 'make this a skill'"
5
+ ---
6
+
7
+ # Skillify — Create Custom Skills
8
+
9
+ ## Goal
10
+ Help the user create a reusable skill (SKILL.md file) and register it for immediate use.
11
+
12
+ ## Step 1: Understand Intent
13
+
14
+ Ask the user:
15
+ - "What do you want to automate?"
16
+ - "Is this based on something we just did, or a new workflow?"
17
+
18
+ If based on conversation history, review the recent tool calls to extract the pattern.
19
+
20
+ ## Step 2: Interview (3-5 questions)
21
+
22
+ Use AskUserQuestion (if available) or direct questions:
23
+
24
+ 1. **Name**: "What should this skill be called?"
25
+ - Generate slug: lowercase, hyphens only, letters/numbers, start with letter, max 50 chars
26
+ - Examples: "Competitor Analysis" → `competitor-analysis`, "竞品分析" → `competitor-analysis`
27
+ - **Always use English for slug, even if name is in Chinese**
28
+
29
+ 2. **Trigger**: "When should this skill activate? Give me example phrases."
30
+
31
+ 3. **Arguments**: "What inputs does it need each time?" (e.g., keyword, region, URL)
32
+
33
+ 4. **Config**: "Does it need any API keys or credentials?" (most skills don't)
34
+
35
+ 5. **Output**: "Should it produce a file, display results, or both?"
36
+
37
+ ## Step 3: Generate SKILL.md
38
+
39
+ Create the file following this template exactly:
40
+
41
+ ```
42
+ ---
43
+ name: {slug}
44
+ description: "{one-line description in the user's language}"
45
+ when_to_use: "{trigger phrases as a sentence}"
46
+ ---
47
+
48
+ # {Display Name}
49
+
50
+ ## Goal
51
+ {Clear statement of what this skill accomplishes}
52
+
53
+ ## Inputs
54
+ - `$arg1`: {description}
55
+ - `$arg2`: {description}
56
+
57
+ ## Steps
58
+
59
+ ### 1. {First Step}
60
+ {Specific instructions — use exact CLI commands where possible}
61
+
62
+ **Success criteria**: {How to verify this step succeeded}
63
+
64
+ ### 2. {Second Step}
65
+ ...
66
+
67
+ ### N. {Final Step — Output}
68
+ {Generate report / display results / write file}
69
+
70
+ **Success criteria**: {Final deliverable verification}
71
+ ```
72
+
73
+ **Rules:**
74
+ - Every step MUST have **Success criteria**
75
+ - Use `$arg_name` for referencing inputs (this is a prompt convention, not a template system)
76
+ - Be specific: include exact CLI commands (e.g., `scout search "$keyword"`)
77
+ - If a step uses a known skill's CLI, include the full command syntax
78
+ - Keep total content under 100KB
79
+ - Frontmatter: only use `name`, `description`, `when_to_use` (other fields are for future use)
80
+
81
+ ## Step 4: Preview & Confirm
82
+
83
+ Show the complete SKILL.md to the user:
84
+
85
+ "Here's your new skill. Review it and let me know if you want changes:"
86
+
87
+ Display the full content. Wait for confirmation. If changes requested, modify and show again.
88
+
89
+ ## Step 5: Save
90
+
91
+ On confirmation:
92
+
93
+ 1. Create directory and write file:
94
+ ```bash
95
+ mkdir -p /home/aiuser/.claude/skills/{slug}
96
+ ```
97
+ Then use Write tool: `/home/aiuser/.claude/skills/{slug}/SKILL.md`
98
+
99
+ 2. Register with registry:
100
+ ```bash
101
+ optima-skills-cli skill create --slug "{slug}" --name "{name}" --description "{description}" --file "/home/aiuser/.claude/skills/{slug}/SKILL.md"
102
+ ```
103
+
104
+ 3. Parse the JSON output. If it contains an `id` field, creation succeeded.
105
+
106
+ 4. Tell the user: "Skill '{name}' created! Try it by saying: '{trigger phrase}'"
107
+
108
+ ## Step 6: Error Handling
109
+
110
+ - **CLI outputs `TOKEN_EXPIRED`**: "注册失败(token 过期),但 skill 在当前会话可用。刷新页面后重试。"
111
+ - **CLI outputs error with `slug already exists`**: Suggest alternative slug, retry with new slug.
112
+ - **CLI outputs other error**: "Skill 保存到本地成功,但注册到云端失败。当前会话可正常使用。"
113
+ - **Write tool fails**: Inform user and abort.
114
+ - **CLI hangs (10s timeout)**: CLI will auto-abort. Tell user: "注册超时,但 skill 在当前会话可用。"
File without changes
File without changes
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import "@optima-chat/channels-cli";
3
+ //# sourceMappingURL=channels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../bin/channels.ts"],"names":[],"mappings":";AACA,OAAO,2BAA2B,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import "@optima-chat/channels-cli";
3
+ //# sourceMappingURL=channels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channels.js","sourceRoot":"","sources":["../../bin/channels.ts"],"names":[],"mappings":";AACA,OAAO,2BAA2B,CAAC"}
File without changes
package/dist/bin/gen.js CHANGED
File without changes
File without changes
File without changes
File without changes
package/dist/bin/scout.js CHANGED
File without changes
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optima-chat/optima-agent",
3
- "version": "0.8.102",
3
+ "version": "0.9.0",
4
4
  "description": "基于 Claude Agent SDK 的电商运营 AI 助手",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -16,7 +16,8 @@
16
16
  "shopify": "./dist/bin/shopify.js",
17
17
  "logistics": "./dist/bin/logistics.js",
18
18
  "browser-cli": "./dist/bin/browser-cli.js",
19
- "kb-skills": "./dist/bin/kb-skills.js"
19
+ "kb-skills": "./dist/bin/kb-skills.js",
20
+ "channels": "./dist/bin/channels.js"
20
21
  },
21
22
  "files": [
22
23
  "dist",
@@ -51,6 +52,7 @@
51
52
  "@optima-chat/ads-cli": "latest",
52
53
  "@optima-chat/bi-cli": "latest",
53
54
  "@optima-chat/browser-cli": "latest",
55
+ "@optima-chat/channels-cli": "latest",
54
56
  "@optima-chat/commerce-cli": "latest",
55
57
  "@optima-chat/gen-cli": "latest",
56
58
  "@optima-chat/logistics-cli": "latest",