uniner-cli 1.0.2 → 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 CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2026 Uniner Tech. All rights reserved.
2
-
3
- This software is proprietary. Use is subject to the terms of the
4
- license agreement at https://www.uniner.com/.
1
+ Copyright (c) 2026 Uniner Tech. All rights reserved.
2
+
3
+ This software is proprietary. Use is subject to the terms of the
4
+ license agreement at https://www.uniner.com/.
package/README.md CHANGED
@@ -1,161 +1,161 @@
1
- # uniner-cli
2
-
3
- `uniner-cli` 是 [Uniner](https://www.uniner.com/) 的 RPA 自动化命令行工具,提供:
4
-
5
- - **Web 自动化**(Playwright + CDP)—— 浏览器抓取、表单填写、元素交互
6
- - **Excel 操作** —— 读写、批量处理、样式
7
- - **OCR 识别** —— ddddocr(验证码)+ PaddleOCR(通用)
8
- - **桌面 / SAP 自动化**(仅 Windows)
9
- - **通用工具** —— 加密、HTTP、邮件、文件、PDF、压缩
10
-
11
- 安装时会自动注册一个 [Claude Code](https://claude.com/claude-code) 技能(`~/.claude/skills/uniner-cli/SKILL.md`),让 Claude 一启动就能识别并调用本 CLI。
12
-
13
- ---
14
-
15
- ## 安装
16
-
17
- ```bash
18
- npm install -g uniner-cli
19
- ```
20
-
21
- 安装过程:
22
-
23
- 1. npm 装本壳包(约 50KB)
24
- 2. `postinstall` 钩子从 `static.uniner.com` 拉取约 250MB 便携包
25
- 3. 解压到 `%USERPROFILE%\.uniner-cli\<version>\`
26
- 4. 写入 `%USERPROFILE%\.claude\skills\uniner-cli\SKILL.md`
27
-
28
- 完成后任意终端:
29
-
30
- ```bash
31
- uniner-cli --help
32
- ```
33
-
34
- ## 系统要求
35
-
36
- | 项 | 要求 |
37
- |---|---|
38
- | 操作系统 | 64 位 Windows 10 / 11 |
39
- | Node.js | >= 14 |
40
- | 磁盘空间 | ≥ 1.5 GB |
41
- | 网络 | 能访问 `static.uniner.com` |
42
-
43
- > Linux / macOS 支持在路上。
44
-
45
- ## 使用示例
46
-
47
- ```bash
48
- # 看一级命令
49
- uniner-cli --help
50
-
51
- # 浏览器自动化
52
- uniner-cli web browser open --url "https://example.com"
53
- uniner-cli web element click --xpath "//button[@id='submit']"
54
- uniner-cli web element get-text --xpath "//h1"
55
-
56
- # Excel
57
- uniner-cli excel data read --file data.xlsx --cell A1
58
- uniner-cli excel data write --file out.xlsx --cell B2 --value "hello"
59
-
60
- # OCR
61
- uniner-cli tool ocr ddddocr --img captcha.png
62
- ```
63
-
64
- 完整命令树(一级 + 二级 + 三级参数)见安装后 `%USERPROFILE%\.uniner-cli\<version>\skills\cli\SKILL.md`。
65
-
66
- ## 升级
67
-
68
- ```bash
69
- npm update -g uniner-cli
70
- ```
71
-
72
- 或者重新安装:
73
-
74
- ```bash
75
- npm install -g uniner-cli@latest
76
- ```
77
-
78
- > 不支持降级。如需回滚,请手动卸载后再装旧版。
79
-
80
- ## 卸载
81
-
82
- ```bash
83
- # 1. 先清理运行时数据(删 ~/.uniner-cli/ 和 Claude Code 技能)
84
- uniner-cli-uninstall
85
-
86
- # 2. 再卸载 npm 包本身
87
- npm uninstall -g uniner-cli
88
- ```
89
-
90
- > **为什么是两步?** npm 7+ 出于安全考虑不再在卸载时运行 lifecycle 脚本,所以我们提供 `uniner-cli-uninstall` 命令让你显式触发清理。
91
-
92
- 清理会移除:
93
-
94
- - `%USERPROFILE%\.uniner-cli\<version>\` 安装目录
95
- - `%USERPROFILE%\.claude\skills\uniner-cli\SKILL.md` 技能
96
-
97
- ## 环境变量
98
-
99
- 无需手动配置。npm 全局 bin 目录已自动加入 PATH。
100
-
101
- ## 故障排查
102
-
103
- ### `uniner-cli: command not found`
104
-
105
- 确认 npm 全局 bin 在 PATH 上:
106
-
107
- ```powershell
108
- npm config get prefix
109
- # 应输出类似 C:\Users\xxx\AppData\Roaming\npm
110
- $env:Path -split ';' | Where-Object { $_ -like '*npm*' }
111
- ```
112
-
113
- 如果没有,手动加 `%APPDATA%\npm` 到 PATH。
114
-
115
- ### 安装时下载失败 / 超时
116
-
117
- 公司代理或防火墙可能屏蔽 `static.uniner.com`。试试:
118
-
119
- ```bash
120
- npm config get proxy
121
- npm config get https-proxy
122
- # 设置代理:
123
- npm config set https-proxy http://your-proxy:port
124
- ```
125
-
126
- 或者直接走原生安装方式(不走 npm):
127
-
128
- ```powershell
129
- iwr https://static.uniner.com/soft/editor/uninercli/install.ps1 -UseBasicParsing | iex
130
- ```
131
-
132
- ### postinstall 卡在解压
133
-
134
- 杀软(360 / 火绒)会扫描 1279 个新文件,慢则 5–10 分钟。让它跑完即可。
135
-
136
- ### 想重装
137
-
138
- ```bash
139
- npm uninstall -g uniner-cli
140
- npm install -g uniner-cli
141
- ```
142
-
143
- ## 备选安装方式(不走 npm)
144
-
145
- 如果你不想要 Node.js 依赖,可以用 PowerShell 一行安装(基于 Inno Setup 安装器):
146
-
147
- ```powershell
148
- iwr https://static.uniner.com/soft/editor/uninercli/install.ps1 -UseBasicParsing | iex
149
- ```
150
-
151
- 两种方式互不干扰,但**不要**同时启用——会有两份 SKILL.md / 两份二进制。
152
-
153
- ## 链接
154
-
155
- - 官网:[https://www.uniner.com/](https://www.uniner.com/)
156
- - 技术支持:support@uniner.com
157
- - Claude Code:[https://claude.com/claude-code](https://claude.com/claude-code)
158
-
159
- ## License
160
-
161
- Proprietary. (C) 2026 Uniner Tech.
1
+ # uniner-cli
2
+
3
+ `uniner-cli` 是 [Uniner](https://www.uniner.com/) 的 RPA 自动化命令行工具,提供:
4
+
5
+ - **Web 自动化**(Playwright + CDP)—— 浏览器抓取、表单填写、元素交互
6
+ - **Excel 操作** —— 读写、批量处理、样式
7
+ - **OCR 识别** —— ddddocr(验证码)+ PaddleOCR(通用)
8
+ - **桌面 / SAP 自动化**(仅 Windows)
9
+ - **通用工具** —— 加密、HTTP、邮件、文件、PDF、压缩
10
+
11
+ 安装时会自动注册一个 [Claude Code](https://claude.com/claude-code) 技能(`~/.claude/skills/uniner-cli/SKILL.md`),让 Claude 一启动就能识别并调用本 CLI。
12
+
13
+ ---
14
+
15
+ ## 安装
16
+
17
+ ```bash
18
+ npm install -g uniner-cli
19
+ ```
20
+
21
+ 安装过程:
22
+
23
+ 1. npm 装本壳包(约 50KB)
24
+ 2. `postinstall` 钩子从 `static.uniner.com` 拉取约 250MB 便携包
25
+ 3. 解压到 `%USERPROFILE%\.uniner-cli\<version>\`
26
+ 4. 写入 `%USERPROFILE%\.claude\skills\uniner-cli\SKILL.md`
27
+
28
+ 完成后任意终端:
29
+
30
+ ```bash
31
+ uniner-cli --help
32
+ ```
33
+
34
+ ## 系统要求
35
+
36
+ | 项 | 要求 |
37
+ |---|---|
38
+ | 操作系统 | 64 位 Windows 10 / 11 |
39
+ | Node.js | >= 14 |
40
+ | 磁盘空间 | ≥ 1.5 GB |
41
+ | 网络 | 能访问 `static.uniner.com` |
42
+
43
+ > Linux / macOS 支持在路上。
44
+
45
+ ## 使用示例
46
+
47
+ ```bash
48
+ # 看一级命令
49
+ uniner-cli --help
50
+
51
+ # 浏览器自动化
52
+ uniner-cli web browser open --url "https://example.com"
53
+ uniner-cli web element click --xpath "//button[@id='submit']"
54
+ uniner-cli web element get-text --xpath "//h1"
55
+
56
+ # Excel
57
+ uniner-cli excel data read --file data.xlsx --cell A1
58
+ uniner-cli excel data write --file out.xlsx --cell B2 --value "hello"
59
+
60
+ # OCR
61
+ uniner-cli tool ocr ddddocr --img captcha.png
62
+ ```
63
+
64
+ 完整命令树(一级 + 二级 + 三级参数)见安装后 `%USERPROFILE%\.uniner-cli\<version>\skills\cli\SKILL.md`。
65
+
66
+ ## 升级
67
+
68
+ ```bash
69
+ npm update -g uniner-cli
70
+ ```
71
+
72
+ 或者重新安装:
73
+
74
+ ```bash
75
+ npm install -g uniner-cli@latest
76
+ ```
77
+
78
+ > 不支持降级。如需回滚,请手动卸载后再装旧版。
79
+
80
+ ## 卸载
81
+
82
+ ```bash
83
+ # 1. 先清理运行时数据(删 ~/.uniner-cli/ 和 Claude Code 技能)
84
+ uniner-cli-uninstall
85
+
86
+ # 2. 再卸载 npm 包本身
87
+ npm uninstall -g uniner-cli
88
+ ```
89
+
90
+ > **为什么是两步?** npm 7+ 出于安全考虑不再在卸载时运行 lifecycle 脚本,所以我们提供 `uniner-cli-uninstall` 命令让你显式触发清理。
91
+
92
+ 清理会移除:
93
+
94
+ - `%USERPROFILE%\.uniner-cli\<version>\` 安装目录
95
+ - `%USERPROFILE%\.claude\skills\uniner-cli\SKILL.md` 技能
96
+
97
+ ## 环境变量
98
+
99
+ 无需手动配置。npm 全局 bin 目录已自动加入 PATH。
100
+
101
+ ## 故障排查
102
+
103
+ ### `uniner-cli: command not found`
104
+
105
+ 确认 npm 全局 bin 在 PATH 上:
106
+
107
+ ```powershell
108
+ npm config get prefix
109
+ # 应输出类似 C:\Users\xxx\AppData\Roaming\npm
110
+ $env:Path -split ';' | Where-Object { $_ -like '*npm*' }
111
+ ```
112
+
113
+ 如果没有,手动加 `%APPDATA%\npm` 到 PATH。
114
+
115
+ ### 安装时下载失败 / 超时
116
+
117
+ 公司代理或防火墙可能屏蔽 `static.uniner.com`。试试:
118
+
119
+ ```bash
120
+ npm config get proxy
121
+ npm config get https-proxy
122
+ # 设置代理:
123
+ npm config set https-proxy http://your-proxy:port
124
+ ```
125
+
126
+ 或者直接走原生安装方式(不走 npm):
127
+
128
+ ```powershell
129
+ iwr https://static.uniner.com/soft/editor/uninercli/install.ps1 -UseBasicParsing | iex
130
+ ```
131
+
132
+ ### postinstall 卡在解压
133
+
134
+ 杀软(360 / 火绒)会扫描 1279 个新文件,慢则 5–10 分钟。让它跑完即可。
135
+
136
+ ### 想重装
137
+
138
+ ```bash
139
+ npm uninstall -g uniner-cli
140
+ npm install -g uniner-cli
141
+ ```
142
+
143
+ ## 备选安装方式(不走 npm)
144
+
145
+ 如果你不想要 Node.js 依赖,可以用 PowerShell 一行安装(基于 Inno Setup 安装器):
146
+
147
+ ```powershell
148
+ iwr https://static.uniner.com/soft/editor/uninercli/install.ps1 -UseBasicParsing | iex
149
+ ```
150
+
151
+ 两种方式互不干扰,但**不要**同时启用——会有两份 SKILL.md / 两份二进制。
152
+
153
+ ## 链接
154
+
155
+ - 官网:[https://www.uniner.com/](https://www.uniner.com/)
156
+ - 技术支持:support@uniner.com
157
+ - Claude Code:[https://claude.com/claude-code](https://claude.com/claude-code)
158
+
159
+ ## License
160
+
161
+ Proprietary. (C) 2026 Uniner Tech.
@@ -1,145 +1,145 @@
1
- #!/usr/bin/env node
2
- // uniner-cli-uninstall - removes the runtime tree and Claude Code skill.
3
- //
4
- // npm 7+ no longer runs preuninstall/postuninstall lifecycle scripts on
5
- // uninstall (security tightening). So we ship this command for users to
6
- // run BEFORE `npm uninstall -g uniner-cli` to clean their machine.
7
- //
8
- // Recommended workflow:
9
- // uniner-cli-uninstall # this script: clean ~/.uniner-cli/ + skill
10
- // npm uninstall -g uniner-cli # npm: remove the npm package itself
11
- //
12
- // Idempotent: if files are already gone, just no-ops.
13
-
14
- 'use strict';
15
-
16
- const fs = require('fs');
17
- const path = require('path');
18
-
19
- const {
20
- pkg,
21
- rootDir,
22
- versionDir,
23
- skillDir,
24
- skillFile,
25
- } = require('../lib/paths');
26
-
27
- function log(msg) { console.log(`[uniner-cli] ${msg}`); }
28
- function warn(msg) { console.warn(`[uniner-cli] [WARN] ${msg}`); }
29
-
30
- function rmRf(p) {
31
- try {
32
- if (fs.existsSync(p)) {
33
- fs.rmSync(p, { recursive: true, force: true });
34
- log(`Removed ${p}`);
35
- return true;
36
- }
37
- return false;
38
- } catch (e) {
39
- warn(`Could not remove ${p}: ${e.message}`);
40
- return false;
41
- }
42
- }
43
-
44
- function rmFile(p) {
45
- try {
46
- if (fs.existsSync(p)) {
47
- fs.unlinkSync(p);
48
- log(`Removed ${p}`);
49
- return true;
50
- }
51
- return false;
52
- } catch (e) {
53
- warn(`Could not remove ${p}: ${e.message}`);
54
- return false;
55
- }
56
- }
57
-
58
- function main() {
59
- console.log('');
60
- console.log('==========================================');
61
- console.log(' uniner-cli uninstall cleanup');
62
- console.log('==========================================');
63
-
64
- const myVersion = pkg.version;
65
- const myVersionDir = versionDir(myVersion);
66
- let didSomething = false;
67
-
68
- // 1. Remove our version's runtime tree.
69
- if (rmRf(myVersionDir)) didSomething = true;
70
-
71
- // 2. If ~/.uniner-cli/ has no other versions, drop the whole directory.
72
- try {
73
- const root = rootDir();
74
- if (fs.existsSync(root)) {
75
- const remaining = fs.readdirSync(root);
76
- if (remaining.length === 0) {
77
- fs.rmdirSync(root);
78
- log(`Removed empty ${root}`);
79
- didSomething = true;
80
- } else {
81
- log(`Other uniner-cli versions still installed: ${remaining.join(', ')}`);
82
- log(`Keeping ${root}`);
83
- }
84
- }
85
- } catch (e) {
86
- warn(`Could not inspect ${rootDir()}: ${e.message}`);
87
- }
88
-
89
- // 3. Remove ONLY the SKILL.md file. NEVER rm -rf the whole skill dir,
90
- // because the user's accumulated scenarios/<name>/ subdirectories
91
- // live there and represent real work they've sedimented over time.
92
- // If they really want everything gone they can do it manually; we
93
- // surface the path below so they know where to look.
94
- const dir = skillDir();
95
- if (rmFile(skillFile())) didSomething = true;
96
-
97
- // 4. Look for scenarios/ — if there are any, keep them and tell the user.
98
- let scenariosKept = 0;
99
- const scenariosDir = path.join(dir, 'scenarios');
100
- if (fs.existsSync(scenariosDir)) {
101
- try {
102
- scenariosKept = fs.readdirSync(scenariosDir).filter(n => {
103
- const meta = path.join(scenariosDir, n, 'meta.json');
104
- return fs.existsSync(meta);
105
- }).length;
106
- } catch (_) {
107
- // best-effort
108
- }
109
- }
110
-
111
- // 5. If skill dir is now genuinely empty, remove it. Otherwise keep it.
112
- try {
113
- if (fs.existsSync(dir)) {
114
- const remaining = fs.readdirSync(dir);
115
- if (remaining.length === 0) {
116
- fs.rmdirSync(dir);
117
- log(`Removed empty ${dir}`);
118
- didSomething = true;
119
- }
120
- }
121
- } catch (_) {
122
- // best-effort
123
- }
124
-
125
- if (!didSomething) {
126
- log('Nothing to clean — already removed.');
127
- }
128
-
129
- console.log('');
130
- if (scenariosKept > 0) {
131
- console.log('==========================================');
132
- console.log(` ${scenariosKept} scenario(s) PRESERVED at:`);
133
- console.log(` ${scenariosDir}`);
134
- console.log(' (your accumulated knowledge — not deleted)');
135
- console.log(' To delete them too:');
136
- console.log(` rm -rf "${scenariosDir}" # bash`);
137
- console.log(` Remove-Item "${scenariosDir}" -Recurse -Force # PowerShell`);
138
- console.log('==========================================');
139
- }
140
- console.log('Cleanup done. To complete uninstall, also run:');
141
- console.log(' npm uninstall -g uniner-cli');
142
- console.log('');
143
- }
144
-
145
- main();
1
+ #!/usr/bin/env node
2
+ // uniner-cli-uninstall - removes the runtime tree and Claude Code skill.
3
+ //
4
+ // npm 7+ no longer runs preuninstall/postuninstall lifecycle scripts on
5
+ // uninstall (security tightening). So we ship this command for users to
6
+ // run BEFORE `npm uninstall -g uniner-cli` to clean their machine.
7
+ //
8
+ // Recommended workflow:
9
+ // uniner-cli-uninstall # this script: clean ~/.uniner-cli/ + skill
10
+ // npm uninstall -g uniner-cli # npm: remove the npm package itself
11
+ //
12
+ // Idempotent: if files are already gone, just no-ops.
13
+
14
+ 'use strict';
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+
19
+ const {
20
+ pkg,
21
+ rootDir,
22
+ versionDir,
23
+ skillDir,
24
+ skillFile,
25
+ } = require('../lib/paths');
26
+
27
+ function log(msg) { console.log(`[uniner-cli] ${msg}`); }
28
+ function warn(msg) { console.warn(`[uniner-cli] [WARN] ${msg}`); }
29
+
30
+ function rmRf(p) {
31
+ try {
32
+ if (fs.existsSync(p)) {
33
+ fs.rmSync(p, { recursive: true, force: true });
34
+ log(`Removed ${p}`);
35
+ return true;
36
+ }
37
+ return false;
38
+ } catch (e) {
39
+ warn(`Could not remove ${p}: ${e.message}`);
40
+ return false;
41
+ }
42
+ }
43
+
44
+ function rmFile(p) {
45
+ try {
46
+ if (fs.existsSync(p)) {
47
+ fs.unlinkSync(p);
48
+ log(`Removed ${p}`);
49
+ return true;
50
+ }
51
+ return false;
52
+ } catch (e) {
53
+ warn(`Could not remove ${p}: ${e.message}`);
54
+ return false;
55
+ }
56
+ }
57
+
58
+ function main() {
59
+ console.log('');
60
+ console.log('==========================================');
61
+ console.log(' uniner-cli uninstall cleanup');
62
+ console.log('==========================================');
63
+
64
+ const myVersion = pkg.version;
65
+ const myVersionDir = versionDir(myVersion);
66
+ let didSomething = false;
67
+
68
+ // 1. Remove our version's runtime tree.
69
+ if (rmRf(myVersionDir)) didSomething = true;
70
+
71
+ // 2. If ~/.uniner-cli/ has no other versions, drop the whole directory.
72
+ try {
73
+ const root = rootDir();
74
+ if (fs.existsSync(root)) {
75
+ const remaining = fs.readdirSync(root);
76
+ if (remaining.length === 0) {
77
+ fs.rmdirSync(root);
78
+ log(`Removed empty ${root}`);
79
+ didSomething = true;
80
+ } else {
81
+ log(`Other uniner-cli versions still installed: ${remaining.join(', ')}`);
82
+ log(`Keeping ${root}`);
83
+ }
84
+ }
85
+ } catch (e) {
86
+ warn(`Could not inspect ${rootDir()}: ${e.message}`);
87
+ }
88
+
89
+ // 3. Remove ONLY the SKILL.md file. NEVER rm -rf the whole skill dir,
90
+ // because the user's accumulated scenarios/<name>/ subdirectories
91
+ // live there and represent real work they've sedimented over time.
92
+ // If they really want everything gone they can do it manually; we
93
+ // surface the path below so they know where to look.
94
+ const dir = skillDir();
95
+ if (rmFile(skillFile())) didSomething = true;
96
+
97
+ // 4. Look for scenarios/ — if there are any, keep them and tell the user.
98
+ let scenariosKept = 0;
99
+ const scenariosDir = path.join(dir, 'scenarios');
100
+ if (fs.existsSync(scenariosDir)) {
101
+ try {
102
+ scenariosKept = fs.readdirSync(scenariosDir).filter(n => {
103
+ const meta = path.join(scenariosDir, n, 'meta.json');
104
+ return fs.existsSync(meta);
105
+ }).length;
106
+ } catch (_) {
107
+ // best-effort
108
+ }
109
+ }
110
+
111
+ // 5. If skill dir is now genuinely empty, remove it. Otherwise keep it.
112
+ try {
113
+ if (fs.existsSync(dir)) {
114
+ const remaining = fs.readdirSync(dir);
115
+ if (remaining.length === 0) {
116
+ fs.rmdirSync(dir);
117
+ log(`Removed empty ${dir}`);
118
+ didSomething = true;
119
+ }
120
+ }
121
+ } catch (_) {
122
+ // best-effort
123
+ }
124
+
125
+ if (!didSomething) {
126
+ log('Nothing to clean — already removed.');
127
+ }
128
+
129
+ console.log('');
130
+ if (scenariosKept > 0) {
131
+ console.log('==========================================');
132
+ console.log(` ${scenariosKept} scenario(s) PRESERVED at:`);
133
+ console.log(` ${scenariosDir}`);
134
+ console.log(' (your accumulated knowledge — not deleted)');
135
+ console.log(' To delete them too:');
136
+ console.log(` rm -rf "${scenariosDir}" # bash`);
137
+ console.log(` Remove-Item "${scenariosDir}" -Recurse -Force # PowerShell`);
138
+ console.log('==========================================');
139
+ }
140
+ console.log('Cleanup done. To complete uninstall, also run:');
141
+ console.log(' npm uninstall -g uniner-cli');
142
+ console.log('');
143
+ }
144
+
145
+ main();