uniner-cli 1.0.3 → 1.0.5
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 +4 -4
- package/README.md +161 -171
- package/bin/uniner-cli-uninstall.js +145 -145
- package/bin/uniner-cli.js +42 -42
- package/lib/SKILL.md.template +371 -371
- package/lib/paths.js +78 -78
- package/package.json +49 -47
- package/scripts/postinstall-helpers.js +140 -0
- package/scripts/postinstall.js +385 -428
package/lib/SKILL.md.template
CHANGED
|
@@ -1,371 +1,371 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: uniner-cli
|
|
3
|
-
description: RPA 自动化 CLI 工具,提供浏览器自动化、Excel 操作、OCR 识别、桌面/SAP 自动化、加密/HTTP/邮件等通用工具能力。Use when user mentions RPA、自动化、抓取网页、抓数据、填表、读 Excel、写 Excel、识别验证码、OCR、SAP、桌面操作、uniner-cli、爬虫、表单自动化.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# uniner-cli Skill
|
|
7
|
-
|
|
8
|
-
> 由 UninerCLI Installer v{{VERSION}} 自动安装到 `%USERPROFILE%\.claude\skills\uniner-cli\`
|
|
9
|
-
> 安装位置(绝对路径):`{{INSTALL_PATH}}`
|
|
10
|
-
|
|
11
|
-
## 🛑 任务结束硬性规则(最重要,先读这一节)
|
|
12
|
-
|
|
13
|
-
**每次用 uniner-cli 完成一个任务后,在你要说"任务完成"或写汇总表之前,必须先执行下面这段:**
|
|
14
|
-
|
|
15
|
-
如果这次任务**满足任一条件**:
|
|
16
|
-
|
|
17
|
-
- 调用了 ≥ 3 个 uniner-cli 命令
|
|
18
|
-
- 涉及 web / desktop / OCR 任何一个模块
|
|
19
|
-
- 用户提到过"以后还会跑" / "每天都要" / "做成自动化"
|
|
20
|
-
- 任务里踩过坑(XPath 不稳、参数名错、Vue 组件、超时调整等)
|
|
21
|
-
|
|
22
|
-
→ **必须主动问用户**:"这个流程涉及多步,要不要保存为可重放场景?以后 `uniner-cli skill run <name> --param ...` 就能 0 token 重放,可以放定时任务/RPA 平台里跑。要保存吗?"
|
|
23
|
-
|
|
24
|
-
不要等用户开口,**主动**问。这是最有价值的一步——你刚刚花了上千 token 调通的流程,沉淀下来下次就能秒跑。
|
|
25
|
-
|
|
26
|
-
如果用户说"好" / "可以" / "保存吧":按下面"场景沉淀(4 步流程)"章节执行。
|
|
27
|
-
|
|
28
|
-
如果用户说"不用":直接结束,不再追问。
|
|
29
|
-
|
|
30
|
-
**违反这条规则 = 任务未完成。** 不管你跑得多顺,没问就是没问完整。
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## 何时使用本 Skill
|
|
35
|
-
|
|
36
|
-
用户提到以下任一关键词或任务,**优先调用 uniner-cli**:
|
|
37
|
-
|
|
38
|
-
- **网页类**:打开网页、抓取数据、点击/填表/登录、获取标题/表格、OCR 验证码
|
|
39
|
-
- **Excel 类**:创建/读写 Excel、单元格操作、批量数据导出
|
|
40
|
-
- **桌面类**:SAP 操作、窗口控制、键鼠模拟、图像识别(仅 Windows)
|
|
41
|
-
- **工具类**:MD5/AES/RSA 加密、HTTP 请求、收发邮件、文件/PDF/ZIP 操作
|
|
42
|
-
|
|
43
|
-
## 调用前提(已自动配置)
|
|
44
|
-
|
|
45
|
-
- ✅ `uniner-cli` 命令已加入 PATH(安装时自动配置,新终端立即生效)
|
|
46
|
-
- ✅ 环境变量 `UNINER_CLI_HOME = {{INSTALL_PATH}}`
|
|
47
|
-
- ✅ Web 模块自动通过 CDP 连接本机 Chrome / Edge —— **不要手动启动 Chrome**
|
|
48
|
-
- ⚠️ desktop 模块仅 Windows,依赖外部 Agent 服务(魔奈 RPA 编辑器自带)
|
|
49
|
-
|
|
50
|
-
## 命令结构(一级 + 二级)
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
uniner-cli <模块> <子模块> <命令> [选项]
|
|
54
|
-
|
|
55
|
-
excel Excel 文件操作
|
|
56
|
-
├── file 创建 / 打开 / 关闭 / 保存 / 复制 / 删除 / info / list
|
|
57
|
-
├── sheet 工作表 创建 / 删除 / 重命名 / 复制 / info / list
|
|
58
|
-
├── data 读 / 写 / 区域读 / 区域写 / 查找 / 清除
|
|
59
|
-
└── style 字体 / 边框 / 填充 / 对齐 / 数字格式
|
|
60
|
-
|
|
61
|
-
web 浏览器自动化(Playwright + CDP)
|
|
62
|
-
├── browser open / close / reconnect
|
|
63
|
-
├── navigation goto / back / forward / refresh / wait
|
|
64
|
-
├── element click / input / get-text / get-value / select / check / hover / screenshot
|
|
65
|
-
├── iframe enter / exit / list
|
|
66
|
-
├── page list / switch / close
|
|
67
|
-
└── action screenshot / execute-js / get-cookie / set-cookie
|
|
68
|
-
|
|
69
|
-
tool 通用工具
|
|
70
|
-
├── list 创建 / append / remove / find / sort / unique
|
|
71
|
-
├── dict 创建 / get / set / remove / keys / values
|
|
72
|
-
├── time now / format / parse / calc / diff
|
|
73
|
-
├── string format / replace / split / join / trim / upper / lower
|
|
74
|
-
├── data json-parse / json-stringify / csv-parse / csv-write
|
|
75
|
-
├── file read / write / copy / move / delete / list / info / exists
|
|
76
|
-
├── system execute / kill-app / env / clipboard [Windows]
|
|
77
|
-
├── ui alert / confirm / prompt [Windows]
|
|
78
|
-
├── crypto md5 / sha256 / aes-encrypt / aes-decrypt / rsa-* / base64-*
|
|
79
|
-
├── math add / sub / mul / div / round / abs / min / max
|
|
80
|
-
├── pdf read / merge / split / extract-text
|
|
81
|
-
├── ocr ddddocr(验证码) / paddleocr(通用) / image-to-text
|
|
82
|
-
├── zip create / extract / list
|
|
83
|
-
├── ftp connect / upload / download / list / delete
|
|
84
|
-
├── email send / receive / list
|
|
85
|
-
└── http get / post / put / delete
|
|
86
|
-
|
|
87
|
-
desktop 桌面自动化 [仅 Windows]
|
|
88
|
-
├── window find / activate / close / info / list
|
|
89
|
-
├── element find / click / get-text / set-value
|
|
90
|
-
├── keyboard type / press / hotkey
|
|
91
|
-
├── mouse click / move / scroll / drag
|
|
92
|
-
├── image find / click / wait
|
|
93
|
-
└── sap login / transaction / field / table
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## 全局选项(写在子命令前)
|
|
97
|
-
|
|
98
|
-
```bash
|
|
99
|
-
uniner-cli [全局选项] <模块> <子命令> <命令> [命令选项]
|
|
100
|
-
|
|
101
|
-
--timeout, -t <毫秒> 超时(默认 3000ms)
|
|
102
|
-
--exc <0|1> 异常处理:0=抛错退出,1=静默返回错误 JSON
|
|
103
|
-
--verbose, -v 详细日志
|
|
104
|
-
--quiet, -q 静默
|
|
105
|
-
--json/--plain 输出格式(默认 --json)
|
|
106
|
-
--config, -c <PATH> 配置文件路径
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## 输出格式(始终是 JSON)
|
|
110
|
-
|
|
111
|
-
```json
|
|
112
|
-
// 成功
|
|
113
|
-
{"success": true, "command": "web browser open", "data": {"session_id": "abc123"}, "timestamp": "..."}
|
|
114
|
-
|
|
115
|
-
// 失败
|
|
116
|
-
{"success": false, "error": "元素未找到: xpath=...", "error_type": "ElementNotFoundError"}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
调用方应 `json.loads(stdout)` 解析,**不要 grep/regex**。
|
|
120
|
-
|
|
121
|
-
## 场景 → 命令映射(高频)
|
|
122
|
-
|
|
123
|
-
| 用户意图 | 命令模板 |
|
|
124
|
-
|---|---|
|
|
125
|
-
| 打开网页 | `web browser open --url <URL>` |
|
|
126
|
-
| 等待元素出现 | `web navigation wait --type element --xpath <X>` |
|
|
127
|
-
| 点击 | `web element click --xpath <X>` |
|
|
128
|
-
| 输入文本 | `web element input --xpath <X> --value <V>` |
|
|
129
|
-
| 获取文本 | `web element get-text --xpath <X>` |
|
|
130
|
-
| 获取表格 / 复杂提取 | `web action execute-js --code "..."` |
|
|
131
|
-
| 元素截图 | `web element screenshot --xpath <X> --output <PATH>` |
|
|
132
|
-
| 进 iframe | `web iframe enter --xpath <X>`(或 XPath JSON 写法) |
|
|
133
|
-
| 创建 Excel | `excel file create --file <PATH>` |
|
|
134
|
-
| 读单元格 | `excel data read --file <PATH> --cell A1` |
|
|
135
|
-
| 写单元格 | `excel data write --file <PATH> --cell A1 --value <V>` |
|
|
136
|
-
| 区域写入 | `excel data write-range --file <PATH> --cell A1 --values <2D-JSON>` |
|
|
137
|
-
| OCR 验证码 | `tool ocr ddddocr --img <PATH>` |
|
|
138
|
-
| OCR 通用 | `tool ocr paddleocr --img <PATH>` |
|
|
139
|
-
| MD5 / SHA256 | `tool crypto md5 --text <S>` |
|
|
140
|
-
| HTTP GET | `tool http get --url <URL>` |
|
|
141
|
-
| 发送邮件 | `tool email send --to <addr> --subject <S> --body <B>` |
|
|
142
|
-
| 结束进程 | `tool system kill-app --name chrome.exe` |
|
|
143
|
-
| SAP 登录 | `desktop sap login --user <U> --password <P>` |
|
|
144
|
-
|
|
145
|
-
## 命令选择优先级
|
|
146
|
-
|
|
147
|
-
1. **网页操作只用 `web`**(即使是桌面里嵌的 web)
|
|
148
|
-
2. **`web action execute-js` 是万能 fallback**:Vue/React 组件、动态元素、复杂表格提取,普通 element 命令做不到时直接 JS
|
|
149
|
-
3. **iframe 嵌套**用 XPath JSON 格式:`{"ElementName":"...","XPaths":[["iframe_xpath","element_xpath"],["backup_xpath"]]}`
|
|
150
|
-
4. **session 自动管理**:第一次 `web browser open` 后,后续 web 命令默认用最新 session,可省 `--session`
|
|
151
|
-
|
|
152
|
-
## 关键注意事项(6 条 TOC,详情看链接)
|
|
153
|
-
|
|
154
|
-
1. **Chrome CDP 自动管理** — 别手动 kill Chrome;客户机必须装 Chrome 或 Edge
|
|
155
|
-
2. **session 持久化** — `$TEMP\.uniner-cli\sessions.json`;CLI 退出后用 `web browser reconnect` 恢复
|
|
156
|
-
3. **Vue/Element UI 组件** — 日期选择器、级联下拉等,用 `execute-js` 直接操作组件模型,不要硬 input
|
|
157
|
-
4. **desktop 返回 -999** = Agent 服务未启动;此时改用 `web action execute-js` 或 `tool system execute`
|
|
158
|
-
5. **Linux 平台** — Playwright 默认 HTTPS-only,访问 HTTP 站点需改 wrapper 加 `--disable-features=HttpsOnlyMode`,或用 Firefox `--browser-type 1`
|
|
159
|
-
6. **Windows GBK 编码** — CLI 内部已强制 UTF-8 输出;调用方读 stdout 也要 UTF-8
|
|
160
|
-
|
|
161
|
-
## 详细文档(按需 Read)
|
|
162
|
-
|
|
163
|
-
| 主题 | 路径 |
|
|
164
|
-
|---|---|
|
|
165
|
-
| 命令树全集 + 三级参数 | [{{INSTALL_PATH}}\skills\cli\SKILL.md]({{INSTALL_PATH}}\skills\cli\SKILL.md) |
|
|
166
|
-
| SDK ↔ CLI 命令映射 | [{{INSTALL_PATH}}\skills\cli\sdk-cli-mapping.md]({{INSTALL_PATH}}\skills\cli\sdk-cli-mapping.md) |
|
|
167
|
-
| Windows 配置指南 | [{{INSTALL_PATH}}\skills\windows-setup-guide.md]({{INSTALL_PATH}}\skills\windows-setup-guide.md) |
|
|
168
|
-
| Linux 配置指南 | [{{INSTALL_PATH}}\skills\linux-setup-guide.md]({{INSTALL_PATH}}\skills\linux-setup-guide.md) |
|
|
169
|
-
| 实战案例(TMS 抓单) | [{{INSTALL_PATH}}\skills\tms-workflow-test-report.md]({{INSTALL_PATH}}\skills\tms-workflow-test-report.md) |
|
|
170
|
-
| Helper 脚本(Chrome 启动 / Vue 日期 / 表格提取) | [{{INSTALL_PATH}}\skills\cli\helpers\]({{INSTALL_PATH}}\skills\cli\helpers\) |
|
|
171
|
-
| 用户手册 | [{{INSTALL_PATH}}\docs\]({{INSTALL_PATH}}\docs\) |
|
|
172
|
-
| 工作目录(保存截图/Excel/下载) | [{{INSTALL_PATH}}\workdir\]({{INSTALL_PATH}}\workdir\) |
|
|
173
|
-
|
|
174
|
-
## 典型完整流程(参考)
|
|
175
|
-
|
|
176
|
-
**网页 → OCR → 提取 → Excel**:
|
|
177
|
-
|
|
178
|
-
```bash
|
|
179
|
-
# 1. 打开浏览器
|
|
180
|
-
uniner-cli web browser open --url "https://example.com/login"
|
|
181
|
-
|
|
182
|
-
# 2. 输账号密码 + 截验证码 + OCR
|
|
183
|
-
uniner-cli web element input --xpath "//input[@id='user']" --value "u01"
|
|
184
|
-
uniner-cli web element input --xpath "//input[@id='pwd']" --value "p01"
|
|
185
|
-
uniner-cli web element screenshot --xpath "//img[@id='captcha']" --output "{{INSTALL_PATH}}\workdir\cap.png"
|
|
186
|
-
uniner-cli tool ocr ddddocr --img "{{INSTALL_PATH}}\workdir\cap.png"
|
|
187
|
-
# 从返回 JSON 的 data.result 取识别文本
|
|
188
|
-
|
|
189
|
-
# 3. 提交登录
|
|
190
|
-
uniner-cli web element input --xpath "//input[@id='captcha']" --value "<识别结果>"
|
|
191
|
-
uniner-cli web element click --xpath "//button[@type='submit']"
|
|
192
|
-
|
|
193
|
-
# 4. 等表格 + 提取
|
|
194
|
-
uniner-cli web navigation wait --type element --xpath "//table"
|
|
195
|
-
uniner-cli web action execute-js --code "return Array.from(document.querySelectorAll('table tr')).map(r => Array.from(r.cells).map(c => c.textContent.trim()))"
|
|
196
|
-
|
|
197
|
-
# 5. 写 Excel
|
|
198
|
-
uniner-cli excel file create --file "{{INSTALL_PATH}}\workdir\out.xlsx"
|
|
199
|
-
uniner-cli excel data write-range --file "{{INSTALL_PATH}}\workdir\out.xlsx" --cell A1 --values "<上一步的 JSON 二维数组>"
|
|
200
|
-
|
|
201
|
-
# 6. 关浏览器
|
|
202
|
-
uniner-cli web browser close
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
## 场景沉淀(4 步流程)
|
|
206
|
-
|
|
207
|
-
> 这是顶部"任务结束硬性规则"提到的"4 步流程"。用户同意保存场景后,按这里走。
|
|
208
|
-
|
|
209
|
-
每个场景一个目录,三件套:`meta.json` + `steps.json` + `SKILL.md`,存到:
|
|
210
|
-
|
|
211
|
-
```
|
|
212
|
-
%USERPROFILE%\.claude\skills\uniner-cli\scenarios\<kebab-case-name>\
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
**4 步标准流程**:
|
|
216
|
-
|
|
217
|
-
```bash
|
|
218
|
-
# Step 1: 生成骨架(自动创建目录和模板文件)
|
|
219
|
-
uniner-cli skill init <name>
|
|
220
|
-
|
|
221
|
-
# Step 2: 用 Write 工具改 meta.json / steps.json / SKILL.md(见下方 schema)
|
|
222
|
-
|
|
223
|
-
# Step 3: 校验
|
|
224
|
-
uniner-cli skill validate <name>
|
|
225
|
-
|
|
226
|
-
# Step 4: 试跑一次
|
|
227
|
-
uniner-cli skill run <name> --param ...
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### meta.json schema
|
|
231
|
-
|
|
232
|
-
```json
|
|
233
|
-
{
|
|
234
|
-
"name": "<kebab-case-name>",
|
|
235
|
-
"version": "1.0",
|
|
236
|
-
"description": "一句话描述(会被用来匹配触发关键词)",
|
|
237
|
-
"params": {
|
|
238
|
-
"URL": { "type": "string", "required": true, "description": "登录页地址" },
|
|
239
|
-
"USERNAME": { "type": "string", "required": true, "description": "账号" },
|
|
240
|
-
"PASSWORD": { "type": "string", "required": true, "sensitive": true, "description": "密码" },
|
|
241
|
-
"DATE_FROM": { "type": "string", "required": false, "default": "today", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### steps.json schema
|
|
247
|
-
|
|
248
|
-
```json
|
|
249
|
-
{
|
|
250
|
-
"version": "1.0",
|
|
251
|
-
"name": "<同 meta.name>",
|
|
252
|
-
"steps": [
|
|
253
|
-
{
|
|
254
|
-
"id": "open-browser",
|
|
255
|
-
"cmd": "web browser open",
|
|
256
|
-
"args": { "url": "${URL}" },
|
|
257
|
-
"timeout_ms": 10000
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
"id": "ocr-captcha",
|
|
261
|
-
"cmd": "tool ocr ddddocr",
|
|
262
|
-
"args": { "img": "workdir/captcha.png" },
|
|
263
|
-
"store": "ocrResult",
|
|
264
|
-
"comment": "整个 stdout JSON 存到 ocrResult,下面用 ${ocrResult.data.result} 取"
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
"id": "input-captcha",
|
|
268
|
-
"cmd": "web element input",
|
|
269
|
-
"args": { "xpath": "//input[@placeholder='验证码']", "value": "${ocrResult.data.result}" }
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
"id": "close-browser",
|
|
273
|
-
"cmd": "web browser close",
|
|
274
|
-
"always_run": true,
|
|
275
|
-
"comment": "无论前面成功与否都跑(清理用)"
|
|
276
|
-
}
|
|
277
|
-
]
|
|
278
|
-
}
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### 每个 step 支持的字段
|
|
282
|
-
|
|
283
|
-
| 字段 | 必需 | 说明 |
|
|
284
|
-
|---|---|---|
|
|
285
|
-
| `id` | ✅ | 步骤 ID(唯一) |
|
|
286
|
-
| `cmd` | ✅ | uniner-cli 子命令,**不带 `uniner-cli` 前缀**,如 `web element input` |
|
|
287
|
-
| `args` | ✅ | dict 形式参数,对应 CLI 的 `--key value` |
|
|
288
|
-
| `store` | ❌ | 把 stdout JSON 整个存到变量名 |
|
|
289
|
-
| `if` | ❌ | 条件表达式(见下) |
|
|
290
|
-
| `on_fail` | ❌ | `abort`(默认)/ `continue` / `goto:<step_id>` |
|
|
291
|
-
| `retry` | ❌ | 失败重试次数(不含首次) |
|
|
292
|
-
| `retry_delay_ms` | ❌ | 重试间隔(默认 1000) |
|
|
293
|
-
| `timeout_ms` | ❌ | 单步超时(覆盖全局) |
|
|
294
|
-
| `always_run` | ❌ | 即使前面失败也跑(清理用) |
|
|
295
|
-
| `comment` | ❌ | 给人/AI 看的注释 |
|
|
296
|
-
|
|
297
|
-
### 变量替换语法
|
|
298
|
-
|
|
299
|
-
| 写法 | 含义 |
|
|
300
|
-
|---|---|
|
|
301
|
-
| `${URL}` | 用户传入的 `--param URL=xxx` |
|
|
302
|
-
| `${ocrResult.data.result}` | 上一步 store 的 dict 字段(点号路径) |
|
|
303
|
-
| `${tableData.0.1}` | list 索引(0-based) |
|
|
304
|
-
| `${env:USERPROFILE}` | 环境变量 |
|
|
305
|
-
|
|
306
|
-
### 条件表达式语法(白名单)
|
|
307
|
-
|
|
308
|
-
| 写法 | 含义 |
|
|
309
|
-
|---|---|
|
|
310
|
-
| `${var}` | 真值判断 |
|
|
311
|
-
| `!${var}` | 取反 |
|
|
312
|
-
| `${var} == 'yes'` | 字符串/数值相等 |
|
|
313
|
-
| `${var} != 'no'` | 不等 |
|
|
314
|
-
| `${var} > 5` | 数值比较(>=, <=, < 同理) |
|
|
315
|
-
| `${var}.includes('login')` | 包含 |
|
|
316
|
-
| `${var}.startsWith('https')` / `endsWith('.xlsx')` | 前/后缀 |
|
|
317
|
-
| `!${var}.includes('admin')` | 取反组合 |
|
|
318
|
-
|
|
319
|
-
**故意不支持** `&&` / `||` / `()`。要复合逻辑用多步 + `if` + `on_fail` 拆开。
|
|
320
|
-
|
|
321
|
-
### 失败时的客户体验
|
|
322
|
-
|
|
323
|
-
```
|
|
324
|
-
$ uniner-cli skill run tms-export --param URL=...
|
|
325
|
-
{"success": false, "failed_step": "click-search", ...}
|
|
326
|
-
|
|
327
|
-
────────── How to debug ──────────
|
|
328
|
-
Step 'click-search' failed: timeout
|
|
329
|
-
Open Claude Code, paste this:
|
|
330
|
-
|
|
331
|
-
I ran 'uniner-cli skill run' and step 'click-search' failed.
|
|
332
|
-
Error: timeout
|
|
333
|
-
Please look at the scenario at:
|
|
334
|
-
C:\Users\xxx\.claude\skills\uniner-cli\scenarios\tms-export
|
|
335
|
-
Especially steps.json. Help me figure out why and suggest a fix.
|
|
336
|
-
──────────────────────────────────
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
客户复制这段给你 → 你 Read steps.json 调试 → 改完 `Write` 回去 → 让客户重跑。
|
|
340
|
-
|
|
341
|
-
### 给 Claude 的对话范式(用户同意保存后)
|
|
342
|
-
|
|
343
|
-
按这个顺序,**不要跳步**:
|
|
344
|
-
|
|
345
|
-
1. 想一个 kebab-case 名字(如 `tms-export-waybills` / `sap-monthly-report`)
|
|
346
|
-
2. Bash 跑 `uniner-cli skill init <name>`(生成骨架)
|
|
347
|
-
3. Write 写**真正的**:
|
|
348
|
-
- `meta.json`:含动态参数 schema(URL / USERNAME / PASSWORD / DATE_FROM 等)
|
|
349
|
-
- `steps.json`:把刚才跑过的命令序列**完整**写进去,含已知坑的避坑配置(retry / on_fail / always_run)
|
|
350
|
-
- `SKILL.md`:经验文档(已知坑、用法说明)
|
|
351
|
-
4. Bash 跑 `uniner-cli skill validate <name>` 确认格式无误
|
|
352
|
-
5. 让用户 `uniner-cli skill run <name> --param ...` 自己跑一次确认 0 token 重放可行
|
|
353
|
-
|
|
354
|
-
**关键**:steps.json 不是命令清单的注释——是**真正可执行的工作流**。要把 `${URL}` `${USERNAME}` `${ocrResult.data.result}` 这种变量绑好,让 `skill run` 真能跑通。
|
|
355
|
-
|
|
356
|
-
### 已沉淀的场景库
|
|
357
|
-
|
|
358
|
-
```bash
|
|
359
|
-
uniner-cli skill list # 看所有
|
|
360
|
-
uniner-cli skill show <name> # 看某个的元数据 + 步骤摘要
|
|
361
|
-
uniner-cli skill show <name> --steps # 看完整步骤
|
|
362
|
-
uniner-cli skill where # 看场景库根目录(可手动浏览)
|
|
363
|
-
uniner-cli skill delete <name> --yes # 删除(默认 dry-run)
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
## 不确定时
|
|
367
|
-
|
|
368
|
-
- `uniner-cli --help` 看一级
|
|
369
|
-
- `uniner-cli web --help` 看二级
|
|
370
|
-
- `uniner-cli web element click --help` 看具体参数
|
|
371
|
-
- 仍不确定 → Read [{{INSTALL_PATH}}\skills\cli\SKILL.md]({{INSTALL_PATH}}\skills\cli\SKILL.md)
|
|
1
|
+
---
|
|
2
|
+
name: uniner-cli
|
|
3
|
+
description: RPA 自动化 CLI 工具,提供浏览器自动化、Excel 操作、OCR 识别、桌面/SAP 自动化、加密/HTTP/邮件等通用工具能力。Use when user mentions RPA、自动化、抓取网页、抓数据、填表、读 Excel、写 Excel、识别验证码、OCR、SAP、桌面操作、uniner-cli、爬虫、表单自动化.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# uniner-cli Skill
|
|
7
|
+
|
|
8
|
+
> 由 UninerCLI Installer v{{VERSION}} 自动安装到 `%USERPROFILE%\.claude\skills\uniner-cli\`
|
|
9
|
+
> 安装位置(绝对路径):`{{INSTALL_PATH}}`
|
|
10
|
+
|
|
11
|
+
## 🛑 任务结束硬性规则(最重要,先读这一节)
|
|
12
|
+
|
|
13
|
+
**每次用 uniner-cli 完成一个任务后,在你要说"任务完成"或写汇总表之前,必须先执行下面这段:**
|
|
14
|
+
|
|
15
|
+
如果这次任务**满足任一条件**:
|
|
16
|
+
|
|
17
|
+
- 调用了 ≥ 3 个 uniner-cli 命令
|
|
18
|
+
- 涉及 web / desktop / OCR 任何一个模块
|
|
19
|
+
- 用户提到过"以后还会跑" / "每天都要" / "做成自动化"
|
|
20
|
+
- 任务里踩过坑(XPath 不稳、参数名错、Vue 组件、超时调整等)
|
|
21
|
+
|
|
22
|
+
→ **必须主动问用户**:"这个流程涉及多步,要不要保存为可重放场景?以后 `uniner-cli skill run <name> --param ...` 就能 0 token 重放,可以放定时任务/RPA 平台里跑。要保存吗?"
|
|
23
|
+
|
|
24
|
+
不要等用户开口,**主动**问。这是最有价值的一步——你刚刚花了上千 token 调通的流程,沉淀下来下次就能秒跑。
|
|
25
|
+
|
|
26
|
+
如果用户说"好" / "可以" / "保存吧":按下面"场景沉淀(4 步流程)"章节执行。
|
|
27
|
+
|
|
28
|
+
如果用户说"不用":直接结束,不再追问。
|
|
29
|
+
|
|
30
|
+
**违反这条规则 = 任务未完成。** 不管你跑得多顺,没问就是没问完整。
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 何时使用本 Skill
|
|
35
|
+
|
|
36
|
+
用户提到以下任一关键词或任务,**优先调用 uniner-cli**:
|
|
37
|
+
|
|
38
|
+
- **网页类**:打开网页、抓取数据、点击/填表/登录、获取标题/表格、OCR 验证码
|
|
39
|
+
- **Excel 类**:创建/读写 Excel、单元格操作、批量数据导出
|
|
40
|
+
- **桌面类**:SAP 操作、窗口控制、键鼠模拟、图像识别(仅 Windows)
|
|
41
|
+
- **工具类**:MD5/AES/RSA 加密、HTTP 请求、收发邮件、文件/PDF/ZIP 操作
|
|
42
|
+
|
|
43
|
+
## 调用前提(已自动配置)
|
|
44
|
+
|
|
45
|
+
- ✅ `uniner-cli` 命令已加入 PATH(安装时自动配置,新终端立即生效)
|
|
46
|
+
- ✅ 环境变量 `UNINER_CLI_HOME = {{INSTALL_PATH}}`
|
|
47
|
+
- ✅ Web 模块自动通过 CDP 连接本机 Chrome / Edge —— **不要手动启动 Chrome**
|
|
48
|
+
- ⚠️ desktop 模块仅 Windows,依赖外部 Agent 服务(魔奈 RPA 编辑器自带)
|
|
49
|
+
|
|
50
|
+
## 命令结构(一级 + 二级)
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
uniner-cli <模块> <子模块> <命令> [选项]
|
|
54
|
+
|
|
55
|
+
excel Excel 文件操作
|
|
56
|
+
├── file 创建 / 打开 / 关闭 / 保存 / 复制 / 删除 / info / list
|
|
57
|
+
├── sheet 工作表 创建 / 删除 / 重命名 / 复制 / info / list
|
|
58
|
+
├── data 读 / 写 / 区域读 / 区域写 / 查找 / 清除
|
|
59
|
+
└── style 字体 / 边框 / 填充 / 对齐 / 数字格式
|
|
60
|
+
|
|
61
|
+
web 浏览器自动化(Playwright + CDP)
|
|
62
|
+
├── browser open / close / reconnect
|
|
63
|
+
├── navigation goto / back / forward / refresh / wait
|
|
64
|
+
├── element click / input / get-text / get-value / select / check / hover / screenshot
|
|
65
|
+
├── iframe enter / exit / list
|
|
66
|
+
├── page list / switch / close
|
|
67
|
+
└── action screenshot / execute-js / get-cookie / set-cookie
|
|
68
|
+
|
|
69
|
+
tool 通用工具
|
|
70
|
+
├── list 创建 / append / remove / find / sort / unique
|
|
71
|
+
├── dict 创建 / get / set / remove / keys / values
|
|
72
|
+
├── time now / format / parse / calc / diff
|
|
73
|
+
├── string format / replace / split / join / trim / upper / lower
|
|
74
|
+
├── data json-parse / json-stringify / csv-parse / csv-write
|
|
75
|
+
├── file read / write / copy / move / delete / list / info / exists
|
|
76
|
+
├── system execute / kill-app / env / clipboard [Windows]
|
|
77
|
+
├── ui alert / confirm / prompt [Windows]
|
|
78
|
+
├── crypto md5 / sha256 / aes-encrypt / aes-decrypt / rsa-* / base64-*
|
|
79
|
+
├── math add / sub / mul / div / round / abs / min / max
|
|
80
|
+
├── pdf read / merge / split / extract-text
|
|
81
|
+
├── ocr ddddocr(验证码) / paddleocr(通用) / image-to-text
|
|
82
|
+
├── zip create / extract / list
|
|
83
|
+
├── ftp connect / upload / download / list / delete
|
|
84
|
+
├── email send / receive / list
|
|
85
|
+
└── http get / post / put / delete
|
|
86
|
+
|
|
87
|
+
desktop 桌面自动化 [仅 Windows]
|
|
88
|
+
├── window find / activate / close / info / list
|
|
89
|
+
├── element find / click / get-text / set-value
|
|
90
|
+
├── keyboard type / press / hotkey
|
|
91
|
+
├── mouse click / move / scroll / drag
|
|
92
|
+
├── image find / click / wait
|
|
93
|
+
└── sap login / transaction / field / table
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 全局选项(写在子命令前)
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
uniner-cli [全局选项] <模块> <子命令> <命令> [命令选项]
|
|
100
|
+
|
|
101
|
+
--timeout, -t <毫秒> 超时(默认 3000ms)
|
|
102
|
+
--exc <0|1> 异常处理:0=抛错退出,1=静默返回错误 JSON
|
|
103
|
+
--verbose, -v 详细日志
|
|
104
|
+
--quiet, -q 静默
|
|
105
|
+
--json/--plain 输出格式(默认 --json)
|
|
106
|
+
--config, -c <PATH> 配置文件路径
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## 输出格式(始终是 JSON)
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
// 成功
|
|
113
|
+
{"success": true, "command": "web browser open", "data": {"session_id": "abc123"}, "timestamp": "..."}
|
|
114
|
+
|
|
115
|
+
// 失败
|
|
116
|
+
{"success": false, "error": "元素未找到: xpath=...", "error_type": "ElementNotFoundError"}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
调用方应 `json.loads(stdout)` 解析,**不要 grep/regex**。
|
|
120
|
+
|
|
121
|
+
## 场景 → 命令映射(高频)
|
|
122
|
+
|
|
123
|
+
| 用户意图 | 命令模板 |
|
|
124
|
+
|---|---|
|
|
125
|
+
| 打开网页 | `web browser open --url <URL>` |
|
|
126
|
+
| 等待元素出现 | `web navigation wait --type element --xpath <X>` |
|
|
127
|
+
| 点击 | `web element click --xpath <X>` |
|
|
128
|
+
| 输入文本 | `web element input --xpath <X> --value <V>` |
|
|
129
|
+
| 获取文本 | `web element get-text --xpath <X>` |
|
|
130
|
+
| 获取表格 / 复杂提取 | `web action execute-js --code "..."` |
|
|
131
|
+
| 元素截图 | `web element screenshot --xpath <X> --output <PATH>` |
|
|
132
|
+
| 进 iframe | `web iframe enter --xpath <X>`(或 XPath JSON 写法) |
|
|
133
|
+
| 创建 Excel | `excel file create --file <PATH>` |
|
|
134
|
+
| 读单元格 | `excel data read --file <PATH> --cell A1` |
|
|
135
|
+
| 写单元格 | `excel data write --file <PATH> --cell A1 --value <V>` |
|
|
136
|
+
| 区域写入 | `excel data write-range --file <PATH> --cell A1 --values <2D-JSON>` |
|
|
137
|
+
| OCR 验证码 | `tool ocr ddddocr --img <PATH>` |
|
|
138
|
+
| OCR 通用 | `tool ocr paddleocr --img <PATH>` |
|
|
139
|
+
| MD5 / SHA256 | `tool crypto md5 --text <S>` |
|
|
140
|
+
| HTTP GET | `tool http get --url <URL>` |
|
|
141
|
+
| 发送邮件 | `tool email send --to <addr> --subject <S> --body <B>` |
|
|
142
|
+
| 结束进程 | `tool system kill-app --name chrome.exe` |
|
|
143
|
+
| SAP 登录 | `desktop sap login --user <U> --password <P>` |
|
|
144
|
+
|
|
145
|
+
## 命令选择优先级
|
|
146
|
+
|
|
147
|
+
1. **网页操作只用 `web`**(即使是桌面里嵌的 web)
|
|
148
|
+
2. **`web action execute-js` 是万能 fallback**:Vue/React 组件、动态元素、复杂表格提取,普通 element 命令做不到时直接 JS
|
|
149
|
+
3. **iframe 嵌套**用 XPath JSON 格式:`{"ElementName":"...","XPaths":[["iframe_xpath","element_xpath"],["backup_xpath"]]}`
|
|
150
|
+
4. **session 自动管理**:第一次 `web browser open` 后,后续 web 命令默认用最新 session,可省 `--session`
|
|
151
|
+
|
|
152
|
+
## 关键注意事项(6 条 TOC,详情看链接)
|
|
153
|
+
|
|
154
|
+
1. **Chrome CDP 自动管理** — 别手动 kill Chrome;客户机必须装 Chrome 或 Edge
|
|
155
|
+
2. **session 持久化** — `$TEMP\.uniner-cli\sessions.json`;CLI 退出后用 `web browser reconnect` 恢复
|
|
156
|
+
3. **Vue/Element UI 组件** — 日期选择器、级联下拉等,用 `execute-js` 直接操作组件模型,不要硬 input
|
|
157
|
+
4. **desktop 返回 -999** = Agent 服务未启动;此时改用 `web action execute-js` 或 `tool system execute`
|
|
158
|
+
5. **Linux 平台** — Playwright 默认 HTTPS-only,访问 HTTP 站点需改 wrapper 加 `--disable-features=HttpsOnlyMode`,或用 Firefox `--browser-type 1`
|
|
159
|
+
6. **Windows GBK 编码** — CLI 内部已强制 UTF-8 输出;调用方读 stdout 也要 UTF-8
|
|
160
|
+
|
|
161
|
+
## 详细文档(按需 Read)
|
|
162
|
+
|
|
163
|
+
| 主题 | 路径 |
|
|
164
|
+
|---|---|
|
|
165
|
+
| 命令树全集 + 三级参数 | [{{INSTALL_PATH}}\skills\cli\SKILL.md]({{INSTALL_PATH}}\skills\cli\SKILL.md) |
|
|
166
|
+
| SDK ↔ CLI 命令映射 | [{{INSTALL_PATH}}\skills\cli\sdk-cli-mapping.md]({{INSTALL_PATH}}\skills\cli\sdk-cli-mapping.md) |
|
|
167
|
+
| Windows 配置指南 | [{{INSTALL_PATH}}\skills\windows-setup-guide.md]({{INSTALL_PATH}}\skills\windows-setup-guide.md) |
|
|
168
|
+
| Linux 配置指南 | [{{INSTALL_PATH}}\skills\linux-setup-guide.md]({{INSTALL_PATH}}\skills\linux-setup-guide.md) |
|
|
169
|
+
| 实战案例(TMS 抓单) | [{{INSTALL_PATH}}\skills\tms-workflow-test-report.md]({{INSTALL_PATH}}\skills\tms-workflow-test-report.md) |
|
|
170
|
+
| Helper 脚本(Chrome 启动 / Vue 日期 / 表格提取) | [{{INSTALL_PATH}}\skills\cli\helpers\]({{INSTALL_PATH}}\skills\cli\helpers\) |
|
|
171
|
+
| 用户手册 | [{{INSTALL_PATH}}\docs\]({{INSTALL_PATH}}\docs\) |
|
|
172
|
+
| 工作目录(保存截图/Excel/下载) | [{{INSTALL_PATH}}\workdir\]({{INSTALL_PATH}}\workdir\) |
|
|
173
|
+
|
|
174
|
+
## 典型完整流程(参考)
|
|
175
|
+
|
|
176
|
+
**网页 → OCR → 提取 → Excel**:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# 1. 打开浏览器
|
|
180
|
+
uniner-cli web browser open --url "https://example.com/login"
|
|
181
|
+
|
|
182
|
+
# 2. 输账号密码 + 截验证码 + OCR
|
|
183
|
+
uniner-cli web element input --xpath "//input[@id='user']" --value "u01"
|
|
184
|
+
uniner-cli web element input --xpath "//input[@id='pwd']" --value "p01"
|
|
185
|
+
uniner-cli web element screenshot --xpath "//img[@id='captcha']" --output "{{INSTALL_PATH}}\workdir\cap.png"
|
|
186
|
+
uniner-cli tool ocr ddddocr --img "{{INSTALL_PATH}}\workdir\cap.png"
|
|
187
|
+
# 从返回 JSON 的 data.result 取识别文本
|
|
188
|
+
|
|
189
|
+
# 3. 提交登录
|
|
190
|
+
uniner-cli web element input --xpath "//input[@id='captcha']" --value "<识别结果>"
|
|
191
|
+
uniner-cli web element click --xpath "//button[@type='submit']"
|
|
192
|
+
|
|
193
|
+
# 4. 等表格 + 提取
|
|
194
|
+
uniner-cli web navigation wait --type element --xpath "//table"
|
|
195
|
+
uniner-cli web action execute-js --code "return Array.from(document.querySelectorAll('table tr')).map(r => Array.from(r.cells).map(c => c.textContent.trim()))"
|
|
196
|
+
|
|
197
|
+
# 5. 写 Excel
|
|
198
|
+
uniner-cli excel file create --file "{{INSTALL_PATH}}\workdir\out.xlsx"
|
|
199
|
+
uniner-cli excel data write-range --file "{{INSTALL_PATH}}\workdir\out.xlsx" --cell A1 --values "<上一步的 JSON 二维数组>"
|
|
200
|
+
|
|
201
|
+
# 6. 关浏览器
|
|
202
|
+
uniner-cli web browser close
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## 场景沉淀(4 步流程)
|
|
206
|
+
|
|
207
|
+
> 这是顶部"任务结束硬性规则"提到的"4 步流程"。用户同意保存场景后,按这里走。
|
|
208
|
+
|
|
209
|
+
每个场景一个目录,三件套:`meta.json` + `steps.json` + `SKILL.md`,存到:
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
%USERPROFILE%\.claude\skills\uniner-cli\scenarios\<kebab-case-name>\
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**4 步标准流程**:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Step 1: 生成骨架(自动创建目录和模板文件)
|
|
219
|
+
uniner-cli skill init <name>
|
|
220
|
+
|
|
221
|
+
# Step 2: 用 Write 工具改 meta.json / steps.json / SKILL.md(见下方 schema)
|
|
222
|
+
|
|
223
|
+
# Step 3: 校验
|
|
224
|
+
uniner-cli skill validate <name>
|
|
225
|
+
|
|
226
|
+
# Step 4: 试跑一次
|
|
227
|
+
uniner-cli skill run <name> --param ...
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### meta.json schema
|
|
231
|
+
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"name": "<kebab-case-name>",
|
|
235
|
+
"version": "1.0",
|
|
236
|
+
"description": "一句话描述(会被用来匹配触发关键词)",
|
|
237
|
+
"params": {
|
|
238
|
+
"URL": { "type": "string", "required": true, "description": "登录页地址" },
|
|
239
|
+
"USERNAME": { "type": "string", "required": true, "description": "账号" },
|
|
240
|
+
"PASSWORD": { "type": "string", "required": true, "sensitive": true, "description": "密码" },
|
|
241
|
+
"DATE_FROM": { "type": "string", "required": false, "default": "today", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### steps.json schema
|
|
247
|
+
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
"version": "1.0",
|
|
251
|
+
"name": "<同 meta.name>",
|
|
252
|
+
"steps": [
|
|
253
|
+
{
|
|
254
|
+
"id": "open-browser",
|
|
255
|
+
"cmd": "web browser open",
|
|
256
|
+
"args": { "url": "${URL}" },
|
|
257
|
+
"timeout_ms": 10000
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"id": "ocr-captcha",
|
|
261
|
+
"cmd": "tool ocr ddddocr",
|
|
262
|
+
"args": { "img": "workdir/captcha.png" },
|
|
263
|
+
"store": "ocrResult",
|
|
264
|
+
"comment": "整个 stdout JSON 存到 ocrResult,下面用 ${ocrResult.data.result} 取"
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"id": "input-captcha",
|
|
268
|
+
"cmd": "web element input",
|
|
269
|
+
"args": { "xpath": "//input[@placeholder='验证码']", "value": "${ocrResult.data.result}" }
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"id": "close-browser",
|
|
273
|
+
"cmd": "web browser close",
|
|
274
|
+
"always_run": true,
|
|
275
|
+
"comment": "无论前面成功与否都跑(清理用)"
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### 每个 step 支持的字段
|
|
282
|
+
|
|
283
|
+
| 字段 | 必需 | 说明 |
|
|
284
|
+
|---|---|---|
|
|
285
|
+
| `id` | ✅ | 步骤 ID(唯一) |
|
|
286
|
+
| `cmd` | ✅ | uniner-cli 子命令,**不带 `uniner-cli` 前缀**,如 `web element input` |
|
|
287
|
+
| `args` | ✅ | dict 形式参数,对应 CLI 的 `--key value` |
|
|
288
|
+
| `store` | ❌ | 把 stdout JSON 整个存到变量名 |
|
|
289
|
+
| `if` | ❌ | 条件表达式(见下) |
|
|
290
|
+
| `on_fail` | ❌ | `abort`(默认)/ `continue` / `goto:<step_id>` |
|
|
291
|
+
| `retry` | ❌ | 失败重试次数(不含首次) |
|
|
292
|
+
| `retry_delay_ms` | ❌ | 重试间隔(默认 1000) |
|
|
293
|
+
| `timeout_ms` | ❌ | 单步超时(覆盖全局) |
|
|
294
|
+
| `always_run` | ❌ | 即使前面失败也跑(清理用) |
|
|
295
|
+
| `comment` | ❌ | 给人/AI 看的注释 |
|
|
296
|
+
|
|
297
|
+
### 变量替换语法
|
|
298
|
+
|
|
299
|
+
| 写法 | 含义 |
|
|
300
|
+
|---|---|
|
|
301
|
+
| `${URL}` | 用户传入的 `--param URL=xxx` |
|
|
302
|
+
| `${ocrResult.data.result}` | 上一步 store 的 dict 字段(点号路径) |
|
|
303
|
+
| `${tableData.0.1}` | list 索引(0-based) |
|
|
304
|
+
| `${env:USERPROFILE}` | 环境变量 |
|
|
305
|
+
|
|
306
|
+
### 条件表达式语法(白名单)
|
|
307
|
+
|
|
308
|
+
| 写法 | 含义 |
|
|
309
|
+
|---|---|
|
|
310
|
+
| `${var}` | 真值判断 |
|
|
311
|
+
| `!${var}` | 取反 |
|
|
312
|
+
| `${var} == 'yes'` | 字符串/数值相等 |
|
|
313
|
+
| `${var} != 'no'` | 不等 |
|
|
314
|
+
| `${var} > 5` | 数值比较(>=, <=, < 同理) |
|
|
315
|
+
| `${var}.includes('login')` | 包含 |
|
|
316
|
+
| `${var}.startsWith('https')` / `endsWith('.xlsx')` | 前/后缀 |
|
|
317
|
+
| `!${var}.includes('admin')` | 取反组合 |
|
|
318
|
+
|
|
319
|
+
**故意不支持** `&&` / `||` / `()`。要复合逻辑用多步 + `if` + `on_fail` 拆开。
|
|
320
|
+
|
|
321
|
+
### 失败时的客户体验
|
|
322
|
+
|
|
323
|
+
```
|
|
324
|
+
$ uniner-cli skill run tms-export --param URL=...
|
|
325
|
+
{"success": false, "failed_step": "click-search", ...}
|
|
326
|
+
|
|
327
|
+
────────── How to debug ──────────
|
|
328
|
+
Step 'click-search' failed: timeout
|
|
329
|
+
Open Claude Code, paste this:
|
|
330
|
+
|
|
331
|
+
I ran 'uniner-cli skill run' and step 'click-search' failed.
|
|
332
|
+
Error: timeout
|
|
333
|
+
Please look at the scenario at:
|
|
334
|
+
C:\Users\xxx\.claude\skills\uniner-cli\scenarios\tms-export
|
|
335
|
+
Especially steps.json. Help me figure out why and suggest a fix.
|
|
336
|
+
──────────────────────────────────
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
客户复制这段给你 → 你 Read steps.json 调试 → 改完 `Write` 回去 → 让客户重跑。
|
|
340
|
+
|
|
341
|
+
### 给 Claude 的对话范式(用户同意保存后)
|
|
342
|
+
|
|
343
|
+
按这个顺序,**不要跳步**:
|
|
344
|
+
|
|
345
|
+
1. 想一个 kebab-case 名字(如 `tms-export-waybills` / `sap-monthly-report`)
|
|
346
|
+
2. Bash 跑 `uniner-cli skill init <name>`(生成骨架)
|
|
347
|
+
3. Write 写**真正的**:
|
|
348
|
+
- `meta.json`:含动态参数 schema(URL / USERNAME / PASSWORD / DATE_FROM 等)
|
|
349
|
+
- `steps.json`:把刚才跑过的命令序列**完整**写进去,含已知坑的避坑配置(retry / on_fail / always_run)
|
|
350
|
+
- `SKILL.md`:经验文档(已知坑、用法说明)
|
|
351
|
+
4. Bash 跑 `uniner-cli skill validate <name>` 确认格式无误
|
|
352
|
+
5. 让用户 `uniner-cli skill run <name> --param ...` 自己跑一次确认 0 token 重放可行
|
|
353
|
+
|
|
354
|
+
**关键**:steps.json 不是命令清单的注释——是**真正可执行的工作流**。要把 `${URL}` `${USERNAME}` `${ocrResult.data.result}` 这种变量绑好,让 `skill run` 真能跑通。
|
|
355
|
+
|
|
356
|
+
### 已沉淀的场景库
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
uniner-cli skill list # 看所有
|
|
360
|
+
uniner-cli skill show <name> # 看某个的元数据 + 步骤摘要
|
|
361
|
+
uniner-cli skill show <name> --steps # 看完整步骤
|
|
362
|
+
uniner-cli skill where # 看场景库根目录(可手动浏览)
|
|
363
|
+
uniner-cli skill delete <name> --yes # 删除(默认 dry-run)
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## 不确定时
|
|
367
|
+
|
|
368
|
+
- `uniner-cli --help` 看一级
|
|
369
|
+
- `uniner-cli web --help` 看二级
|
|
370
|
+
- `uniner-cli web element click --help` 看具体参数
|
|
371
|
+
- 仍不确定 → Read [{{INSTALL_PATH}}\skills\cli\SKILL.md]({{INSTALL_PATH}}\skills\cli\SKILL.md)
|