uniner-cli 1.0.10 → 1.0.12

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/README.md CHANGED
@@ -61,6 +61,7 @@ uniner-cli --help
61
61
  uniner-cli web browser open --url "https://example.com"
62
62
  uniner-cli web element click --xpath "//button[@id='submit']"
63
63
  uniner-cli web element get-text --xpath "//h1"
64
+ uniner-cli web action pdf --output report.pdf
64
65
 
65
66
  # Excel
66
67
  uniner-cli excel data read --file data.xlsx --cell A1
@@ -178,7 +179,15 @@ npm install -g uniner-cli
178
179
 
179
180
  ## Changelog
180
181
 
181
- ### 1.1.0 (2026-07-05)
182
+ ### 1.0.11 (2026-07-16)
183
+
184
+ - **feat**: 新增 `web action pdf` 命令,支持将当前网页导出为 PDF(纸张格式 / 横向 / 背景 / 页边距 / 页眉页脚 / 缩放 / 页面范围)。SDK 层新增 `chrome.pdf()` 方法。
185
+
186
+ ### 1.0.10 (2026-07-10)
187
+
188
+ - **feat**: 优化 Windows 端用户体验
189
+
190
+ ### 1.0.9 (2026-07-05)
182
191
 
183
192
  - **feat**: SDK 1.24.0 同步 —— 新增 `tool ftp` 子命令(create-folder / check-folder / check-file / list-dir),跨平台可用
184
193
  - **feat**: `web browser close` 现在自动终止残留 chrome.exe 进程,避免进程泄漏
@@ -64,7 +64,7 @@ web 浏览器自动化(Playwright + CDP)
64
64
  ├── element click / input / get-text / get-value / select / check / hover / screenshot
65
65
  ├── iframe enter / exit / list
66
66
  ├── page list / switch / close
67
- └── action screenshot / execute-js / get-cookie / set-cookie
67
+ └── action screenshot / pdf / execute-js / get-cookie / set-cookie
68
68
 
69
69
  tool 通用工具
70
70
  ├── list 创建 / append / remove / find / sort / unique
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uniner-cli",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "uniner-cli — RPA automation CLI: browser automation (Playwright/CDP), Excel, OCR, desktop/SAP, crypto/HTTP/email tools. Auto-installs a Claude Code skill on install.",
5
5
  "keywords": [
6
6
  "rpa",
@@ -1,123 +1,123 @@
1
- // Shared cleanup logic for uninstall.
2
- // Extracted so both the npm lifecycle hook (preuninstall.js) and the
3
- // manual command (bin/uniner-cli-uninstall.js) can share it.
4
-
5
- 'use strict';
6
-
7
- const fs = require('fs');
8
- const path = require('path');
9
-
10
- const {
11
- rootDir,
12
- skillDir,
13
- skillFile,
14
- } = require('../lib/paths');
15
-
16
- function rmRf(p) {
17
- try {
18
- if (fs.existsSync(p)) {
19
- fs.rmSync(p, { recursive: true, force: true });
20
- return true;
21
- }
22
- return false;
23
- } catch (_) {
24
- return false;
25
- }
26
- }
27
-
28
- function rmFile(p) {
29
- try {
30
- if (fs.existsSync(p)) {
31
- fs.unlinkSync(p);
32
- return true;
33
- }
34
- return false;
35
- } catch (_) {
36
- return false;
37
- }
38
- }
39
-
40
- /**
41
- * Run the full uninstall cleanup.
42
- *
43
- * @param {object} [opts]
44
- * @param {boolean} [opts.verbose=false] Print progress lines to stdout.
45
- * The preuninstall hook should pass false
46
- * because npm swallows lifecycle output
47
- * unless --verbose is used; the manual
48
- * command passes true so the user sees
49
- * what happened.
50
- * @returns {{ didSomething: boolean, scenariosKept: number, scenariosDir: string|null }}
51
- */
52
- function cleanup(opts) {
53
- const verbose = (opts && opts.verbose) || false;
54
-
55
- function log(msg) {
56
- if (verbose) {
57
- console.log(`[uniner-cli] ${msg}`);
58
- }
59
- }
60
-
61
- const root = rootDir();
62
- let didSomething = false;
63
-
64
- // 1. Remove the entire ~/.uniner-cli/ tree (all versions).
65
- // The version-specific layout exists so the installer can support
66
- // multi-version coexistence, but on uninstall the user wants a full
67
- // removal — orphaned old version dirs would just waste disk space.
68
- if (rmRf(root)) {
69
- log(`Removed ${root}`);
70
- didSomething = true;
71
- }
72
-
73
- // 2. Remove ONLY the SKILL.md file. NEVER rm -rf the whole skill dir,
74
- // because the user's accumulated scenarios/<name>/ subdirectories
75
- // live there and represent real work they've sedimented over time.
76
- const dir = skillDir();
77
- if (rmFile(skillFile())) {
78
- log(`Removed ${skillFile()}`);
79
- didSomething = true;
80
- }
81
-
82
- // 3. Count scenarios/ subdirs that contain a meta.json.
83
- let scenariosKept = 0;
84
- const scenariosPath = path.join(dir, 'scenarios');
85
- if (fs.existsSync(scenariosPath)) {
86
- try {
87
- scenariosKept = fs.readdirSync(scenariosPath).filter(n => {
88
- const meta = path.join(scenariosPath, n, 'meta.json');
89
- return fs.existsSync(meta);
90
- }).length;
91
- } catch (_) {
92
- // best-effort
93
- }
94
- }
95
-
96
- // 4. If skill dir is now genuinely empty, remove it. Otherwise keep it.
97
- try {
98
- if (fs.existsSync(dir)) {
99
- const remaining = fs.readdirSync(dir);
100
- if (remaining.length === 0) {
101
- fs.rmdirSync(dir);
102
- log(`Removed empty ${dir}`);
103
- didSomething = true;
104
- } else if (verbose) {
105
- log(`Keeping ${dir} (${scenariosKept} scenario(s) preserved)`);
106
- }
107
- }
108
- } catch (_) {
109
- // best-effort
110
- }
111
-
112
- if (!didSomething) {
113
- log('Nothing to clean — already removed.');
114
- }
115
-
116
- return {
117
- didSomething,
118
- scenariosKept,
119
- scenariosDir: scenariosKept > 0 ? scenariosPath : null,
120
- };
121
- }
122
-
123
- module.exports = { cleanup };
1
+ // Shared cleanup logic for uninstall.
2
+ // Extracted so both the npm lifecycle hook (preuninstall.js) and the
3
+ // manual command (bin/uniner-cli-uninstall.js) can share it.
4
+
5
+ 'use strict';
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ const {
11
+ rootDir,
12
+ skillDir,
13
+ skillFile,
14
+ } = require('../lib/paths');
15
+
16
+ function rmRf(p) {
17
+ try {
18
+ if (fs.existsSync(p)) {
19
+ fs.rmSync(p, { recursive: true, force: true });
20
+ return true;
21
+ }
22
+ return false;
23
+ } catch (_) {
24
+ return false;
25
+ }
26
+ }
27
+
28
+ function rmFile(p) {
29
+ try {
30
+ if (fs.existsSync(p)) {
31
+ fs.unlinkSync(p);
32
+ return true;
33
+ }
34
+ return false;
35
+ } catch (_) {
36
+ return false;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Run the full uninstall cleanup.
42
+ *
43
+ * @param {object} [opts]
44
+ * @param {boolean} [opts.verbose=false] Print progress lines to stdout.
45
+ * The preuninstall hook should pass false
46
+ * because npm swallows lifecycle output
47
+ * unless --verbose is used; the manual
48
+ * command passes true so the user sees
49
+ * what happened.
50
+ * @returns {{ didSomething: boolean, scenariosKept: number, scenariosDir: string|null }}
51
+ */
52
+ function cleanup(opts) {
53
+ const verbose = (opts && opts.verbose) || false;
54
+
55
+ function log(msg) {
56
+ if (verbose) {
57
+ console.log(`[uniner-cli] ${msg}`);
58
+ }
59
+ }
60
+
61
+ const root = rootDir();
62
+ let didSomething = false;
63
+
64
+ // 1. Remove the entire ~/.uniner-cli/ tree (all versions).
65
+ // The version-specific layout exists so the installer can support
66
+ // multi-version coexistence, but on uninstall the user wants a full
67
+ // removal — orphaned old version dirs would just waste disk space.
68
+ if (rmRf(root)) {
69
+ log(`Removed ${root}`);
70
+ didSomething = true;
71
+ }
72
+
73
+ // 2. Remove ONLY the SKILL.md file. NEVER rm -rf the whole skill dir,
74
+ // because the user's accumulated scenarios/<name>/ subdirectories
75
+ // live there and represent real work they've sedimented over time.
76
+ const dir = skillDir();
77
+ if (rmFile(skillFile())) {
78
+ log(`Removed ${skillFile()}`);
79
+ didSomething = true;
80
+ }
81
+
82
+ // 3. Count scenarios/ subdirs that contain a meta.json.
83
+ let scenariosKept = 0;
84
+ const scenariosPath = path.join(dir, 'scenarios');
85
+ if (fs.existsSync(scenariosPath)) {
86
+ try {
87
+ scenariosKept = fs.readdirSync(scenariosPath).filter(n => {
88
+ const meta = path.join(scenariosPath, n, 'meta.json');
89
+ return fs.existsSync(meta);
90
+ }).length;
91
+ } catch (_) {
92
+ // best-effort
93
+ }
94
+ }
95
+
96
+ // 4. If skill dir is now genuinely empty, remove it. Otherwise keep it.
97
+ try {
98
+ if (fs.existsSync(dir)) {
99
+ const remaining = fs.readdirSync(dir);
100
+ if (remaining.length === 0) {
101
+ fs.rmdirSync(dir);
102
+ log(`Removed empty ${dir}`);
103
+ didSomething = true;
104
+ } else if (verbose) {
105
+ log(`Keeping ${dir} (${scenariosKept} scenario(s) preserved)`);
106
+ }
107
+ }
108
+ } catch (_) {
109
+ // best-effort
110
+ }
111
+
112
+ if (!didSomething) {
113
+ log('Nothing to clean — already removed.');
114
+ }
115
+
116
+ return {
117
+ didSomething,
118
+ scenariosKept,
119
+ scenariosDir: scenariosKept > 0 ? scenariosPath : null,
120
+ };
121
+ }
122
+
123
+ module.exports = { cleanup };
@@ -1,25 +1,25 @@
1
- #!/usr/bin/env node
2
- // preuninstall.js — npm lifecycle hook, runs automatically on
3
- // `npm uninstall -g uniner-cli`.
4
- //
5
- // Cleans up the runtime tree (~/.uniner-cli/<version>/) and the skill file
6
- // (~/.claude/skills/uniner-cli/SKILL.md). Preserves user scenarios under
7
- // ~/.claude/skills/uniner-cli/scenarios/ — those represent accumulated
8
- // knowledge and are never deleted automatically.
9
- //
10
- // IMPORTANT: This script MUST exit 0 in all cases, otherwise it would
11
- // abort the user's `npm uninstall`. Errors are swallowed silently.
12
- //
13
- // The manual `uniner-cli-uninstall` command is still useful for users who
14
- // want verbose feedback, or who want to clean up before the npm package is
15
- // gone (e.g. if the hook somehow didn't fire).
16
-
17
- 'use strict';
18
-
19
- const { cleanup } = require('./cleanup');
20
-
21
- try {
22
- cleanup({ verbose: false });
23
- } catch (_) {
24
- // Never fail the uninstall — swallow all errors.
25
- }
1
+ #!/usr/bin/env node
2
+ // preuninstall.js — npm lifecycle hook, runs automatically on
3
+ // `npm uninstall -g uniner-cli`.
4
+ //
5
+ // Cleans up the runtime tree (~/.uniner-cli/<version>/) and the skill file
6
+ // (~/.claude/skills/uniner-cli/SKILL.md). Preserves user scenarios under
7
+ // ~/.claude/skills/uniner-cli/scenarios/ — those represent accumulated
8
+ // knowledge and are never deleted automatically.
9
+ //
10
+ // IMPORTANT: This script MUST exit 0 in all cases, otherwise it would
11
+ // abort the user's `npm uninstall`. Errors are swallowed silently.
12
+ //
13
+ // The manual `uniner-cli-uninstall` command is still useful for users who
14
+ // want verbose feedback, or who want to clean up before the npm package is
15
+ // gone (e.g. if the hook somehow didn't fire).
16
+
17
+ 'use strict';
18
+
19
+ const { cleanup } = require('./cleanup');
20
+
21
+ try {
22
+ cleanup({ verbose: false });
23
+ } catch (_) {
24
+ // Never fail the uninstall — swallow all errors.
25
+ }