@sovovs/bycli 2.1.59 → 2.1.61
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.zh-CN.md +34 -0
- package/cli-manifest.json +201 -3
- package/clis/ima/ax.js +41 -10
- package/clis/ima/download.js +57 -10
- package/clis/ima/native-client.js +55 -4
- package/clis/iwhalecloud/browser-download.js +83 -0
- package/clis/iwhalecloud/client.js +97 -0
- package/clis/iwhalecloud/download.js +77 -0
- package/clis/iwhalecloud/list.js +59 -0
- package/clis/iwhalecloud/read.js +25 -0
- package/dist/src/browser/cdp.js +8 -0
- package/dist/src/browser/page.js +12 -0
- package/extension/README.md +26 -0
- package/extension/dist/background.js +3380 -0
- package/extension/icons/icon-128.png +0 -0
- package/extension/icons/icon-16.png +0 -0
- package/extension/icons/icon-32.png +0 -0
- package/extension/icons/icon-48.png +0 -0
- package/extension/manifest.json +41 -0
- package/extension/popup.html +146 -0
- package/extension/popup.js +77 -0
- package/package.json +9 -2
- package/scripts/postinstall.js +5 -2
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifest_version": 3,
|
|
3
|
+
"name": "byCLI",
|
|
4
|
+
"version": "2.1.23",
|
|
5
|
+
"description": "Browser automation bridge for the byCLI CLI tool. Executes commands in Chrome tab leases via a local daemon.",
|
|
6
|
+
"permissions": [
|
|
7
|
+
"debugger",
|
|
8
|
+
"tabs",
|
|
9
|
+
"cookies",
|
|
10
|
+
"activeTab",
|
|
11
|
+
"alarms",
|
|
12
|
+
"storage",
|
|
13
|
+
"tabGroups",
|
|
14
|
+
"downloads"
|
|
15
|
+
],
|
|
16
|
+
"host_permissions": [
|
|
17
|
+
"<all_urls>"
|
|
18
|
+
],
|
|
19
|
+
"background": {
|
|
20
|
+
"service_worker": "dist/background.js",
|
|
21
|
+
"type": "module"
|
|
22
|
+
},
|
|
23
|
+
"icons": {
|
|
24
|
+
"16": "icons/icon-16.png",
|
|
25
|
+
"32": "icons/icon-32.png",
|
|
26
|
+
"48": "icons/icon-48.png",
|
|
27
|
+
"128": "icons/icon-128.png"
|
|
28
|
+
},
|
|
29
|
+
"action": {
|
|
30
|
+
"default_title": "byCLI",
|
|
31
|
+
"default_popup": "popup.html",
|
|
32
|
+
"default_icon": {
|
|
33
|
+
"16": "icons/icon-16.png",
|
|
34
|
+
"32": "icons/icon-32.png"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"content_security_policy": {
|
|
38
|
+
"extension_pages": "script-src 'self'; object-src 'self'"
|
|
39
|
+
},
|
|
40
|
+
"homepage_url": "https://github.com/sovovs/byCLI"
|
|
41
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<style>
|
|
6
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
7
|
+
body {
|
|
8
|
+
width: 300px;
|
|
9
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
10
|
+
font-size: 13px;
|
|
11
|
+
color: #1d1d1f;
|
|
12
|
+
background: #fff;
|
|
13
|
+
padding: 14px;
|
|
14
|
+
}
|
|
15
|
+
.header {
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
gap: 8px;
|
|
19
|
+
margin-bottom: 12px;
|
|
20
|
+
}
|
|
21
|
+
.header img { width: 22px; height: 22px; }
|
|
22
|
+
.header h1 { font-size: 14px; font-weight: 600; flex: 1; }
|
|
23
|
+
.header .version-tag {
|
|
24
|
+
font-size: 11px;
|
|
25
|
+
color: #86868b;
|
|
26
|
+
font-variant-numeric: tabular-nums;
|
|
27
|
+
}
|
|
28
|
+
.card {
|
|
29
|
+
border: 1px solid #ececec;
|
|
30
|
+
border-radius: 10px;
|
|
31
|
+
overflow: hidden;
|
|
32
|
+
}
|
|
33
|
+
.card .status-row {
|
|
34
|
+
display: flex;
|
|
35
|
+
align-items: center;
|
|
36
|
+
gap: 8px;
|
|
37
|
+
padding: 11px 12px;
|
|
38
|
+
background: #fafafa;
|
|
39
|
+
}
|
|
40
|
+
.dot {
|
|
41
|
+
width: 8px; height: 8px;
|
|
42
|
+
border-radius: 50%;
|
|
43
|
+
flex-shrink: 0;
|
|
44
|
+
}
|
|
45
|
+
.dot.connected { background: #34c759; }
|
|
46
|
+
.dot.disconnected { background: #ff3b30; }
|
|
47
|
+
.dot.connecting { background: #ff9500; }
|
|
48
|
+
.status-text {
|
|
49
|
+
font-size: 13px;
|
|
50
|
+
font-weight: 600;
|
|
51
|
+
color: #1d1d1f;
|
|
52
|
+
flex: 1;
|
|
53
|
+
}
|
|
54
|
+
.daemon-version {
|
|
55
|
+
font-size: 11px;
|
|
56
|
+
color: #86868b;
|
|
57
|
+
font-variant-numeric: tabular-nums;
|
|
58
|
+
}
|
|
59
|
+
.profile-row {
|
|
60
|
+
display: flex;
|
|
61
|
+
align-items: center;
|
|
62
|
+
gap: 8px;
|
|
63
|
+
padding: 10px 12px;
|
|
64
|
+
border-top: 1px solid #ececec;
|
|
65
|
+
background: #fff;
|
|
66
|
+
}
|
|
67
|
+
.profile-label {
|
|
68
|
+
font-size: 11px;
|
|
69
|
+
color: #86868b;
|
|
70
|
+
flex-shrink: 0;
|
|
71
|
+
}
|
|
72
|
+
.profile-id {
|
|
73
|
+
flex: 1;
|
|
74
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
75
|
+
font-size: 12px;
|
|
76
|
+
color: #1d1d1f;
|
|
77
|
+
user-select: all;
|
|
78
|
+
word-break: break-all;
|
|
79
|
+
}
|
|
80
|
+
.copy-btn {
|
|
81
|
+
flex-shrink: 0;
|
|
82
|
+
padding: 4px 9px;
|
|
83
|
+
font-size: 11px;
|
|
84
|
+
font-family: inherit;
|
|
85
|
+
color: #007aff;
|
|
86
|
+
background: transparent;
|
|
87
|
+
border: 1px solid #d2d2d7;
|
|
88
|
+
border-radius: 6px;
|
|
89
|
+
cursor: pointer;
|
|
90
|
+
transition: background 0.12s, color 0.12s;
|
|
91
|
+
}
|
|
92
|
+
.copy-btn:hover { background: #f0f6ff; }
|
|
93
|
+
.copy-btn:active { background: #e1edff; }
|
|
94
|
+
.copy-btn.copied { color: #34c759; border-color: #34c759; background: #f0fdf4; }
|
|
95
|
+
.hint {
|
|
96
|
+
padding: 10px 12px;
|
|
97
|
+
border-top: 1px solid #ececec;
|
|
98
|
+
background: #f9fafc;
|
|
99
|
+
font-size: 11px;
|
|
100
|
+
color: #6e6e73;
|
|
101
|
+
line-height: 1.5;
|
|
102
|
+
}
|
|
103
|
+
.hint code {
|
|
104
|
+
background: #ececec;
|
|
105
|
+
padding: 1px 5px;
|
|
106
|
+
border-radius: 3px;
|
|
107
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
108
|
+
font-size: 11px;
|
|
109
|
+
}
|
|
110
|
+
.footer {
|
|
111
|
+
margin-top: 12px;
|
|
112
|
+
text-align: center;
|
|
113
|
+
font-size: 11px;
|
|
114
|
+
color: #86868b;
|
|
115
|
+
}
|
|
116
|
+
.footer a { color: #007aff; text-decoration: none; }
|
|
117
|
+
.footer a:hover { text-decoration: underline; }
|
|
118
|
+
</style>
|
|
119
|
+
</head>
|
|
120
|
+
<body>
|
|
121
|
+
<div class="header">
|
|
122
|
+
<img src="icons/icon-48.png" alt="byCLI">
|
|
123
|
+
<h1>byCLI</h1>
|
|
124
|
+
<span class="version-tag" id="extVersion"></span>
|
|
125
|
+
</div>
|
|
126
|
+
<div class="card disconnected" id="card">
|
|
127
|
+
<div class="status-row">
|
|
128
|
+
<span class="dot disconnected" id="dot"></span>
|
|
129
|
+
<span class="status-text" id="status">Checking...</span>
|
|
130
|
+
<span class="daemon-version" id="daemonVersion"></span>
|
|
131
|
+
</div>
|
|
132
|
+
<div class="profile-row" id="profileRow" style="display: none;">
|
|
133
|
+
<span class="profile-label">Profile</span>
|
|
134
|
+
<span class="profile-id" id="contextId"></span>
|
|
135
|
+
<button type="button" class="copy-btn" id="copyBtn" title="Copy contextId">Copy</button>
|
|
136
|
+
</div>
|
|
137
|
+
<div class="hint" id="hint" style="display: none;">
|
|
138
|
+
The extension connects automatically when you run any <code>bycli</code> command.
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
<div class="footer">
|
|
142
|
+
<a href="https://github.com/sovovs/byCLI" target="_blank">Documentation</a>
|
|
143
|
+
</div>
|
|
144
|
+
<script src="popup.js"></script>
|
|
145
|
+
</body>
|
|
146
|
+
</html>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Query connection status from background service worker
|
|
2
|
+
chrome.runtime.sendMessage({ type: 'getStatus' }, (resp) => {
|
|
3
|
+
const card = document.getElementById('card');
|
|
4
|
+
const dot = document.getElementById('dot');
|
|
5
|
+
const status = document.getElementById('status');
|
|
6
|
+
const daemonVersion = document.getElementById('daemonVersion');
|
|
7
|
+
const profileRow = document.getElementById('profileRow');
|
|
8
|
+
const contextId = document.getElementById('contextId');
|
|
9
|
+
const copyBtn = document.getElementById('copyBtn');
|
|
10
|
+
const hint = document.getElementById('hint');
|
|
11
|
+
const extVersion = document.getElementById('extVersion');
|
|
12
|
+
|
|
13
|
+
if (resp && typeof resp.extensionVersion === 'string') {
|
|
14
|
+
extVersion.textContent = `v${resp.extensionVersion}`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (chrome.runtime.lastError || !resp) {
|
|
18
|
+
setState(card, dot, 'disconnected');
|
|
19
|
+
status.textContent = 'No daemon connected';
|
|
20
|
+
daemonVersion.textContent = '';
|
|
21
|
+
profileRow.style.display = 'none';
|
|
22
|
+
hint.style.display = 'block';
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (typeof resp.contextId === 'string' && resp.contextId.length > 0) {
|
|
27
|
+
contextId.textContent = resp.contextId;
|
|
28
|
+
profileRow.style.display = 'flex';
|
|
29
|
+
copyBtn.addEventListener('click', () => copyToClipboard(resp.contextId, copyBtn));
|
|
30
|
+
} else {
|
|
31
|
+
profileRow.style.display = 'none';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (resp.connected) {
|
|
35
|
+
setState(card, dot, 'connected');
|
|
36
|
+
status.textContent = 'Connected to daemon';
|
|
37
|
+
if (typeof resp.daemonVersion === 'string') {
|
|
38
|
+
daemonVersion.textContent = `daemon v${resp.daemonVersion}`;
|
|
39
|
+
}
|
|
40
|
+
hint.style.display = 'none';
|
|
41
|
+
} else if (resp.reconnecting) {
|
|
42
|
+
setState(card, dot, 'connecting');
|
|
43
|
+
status.textContent = 'Reconnecting...';
|
|
44
|
+
daemonVersion.textContent = '';
|
|
45
|
+
hint.style.display = 'none';
|
|
46
|
+
} else {
|
|
47
|
+
setState(card, dot, 'disconnected');
|
|
48
|
+
status.textContent = 'No daemon connected';
|
|
49
|
+
daemonVersion.textContent = '';
|
|
50
|
+
hint.style.display = 'block';
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
function setState(card, dot, state) {
|
|
55
|
+
card.classList.remove('connected', 'disconnected', 'connecting');
|
|
56
|
+
card.classList.add(state);
|
|
57
|
+
dot.classList.remove('connected', 'disconnected', 'connecting');
|
|
58
|
+
dot.classList.add(state);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function copyToClipboard(text, btn) {
|
|
62
|
+
navigator.clipboard.writeText(text).then(
|
|
63
|
+
() => {
|
|
64
|
+
const original = btn.textContent;
|
|
65
|
+
btn.textContent = 'Copied';
|
|
66
|
+
btn.classList.add('copied');
|
|
67
|
+
setTimeout(() => {
|
|
68
|
+
btn.textContent = original;
|
|
69
|
+
btn.classList.remove('copied');
|
|
70
|
+
}, 1200);
|
|
71
|
+
},
|
|
72
|
+
() => {
|
|
73
|
+
btn.textContent = 'Failed';
|
|
74
|
+
setTimeout(() => { btn.textContent = 'Copy'; }, 1200);
|
|
75
|
+
},
|
|
76
|
+
);
|
|
77
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sovovs/bycli",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.61",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -39,6 +39,12 @@
|
|
|
39
39
|
},
|
|
40
40
|
"files": [
|
|
41
41
|
"dist/src/",
|
|
42
|
+
"extension/dist/",
|
|
43
|
+
"extension/manifest.json",
|
|
44
|
+
"extension/popup.html",
|
|
45
|
+
"extension/popup.js",
|
|
46
|
+
"extension/icons/",
|
|
47
|
+
"extension/README.md",
|
|
42
48
|
"clis/",
|
|
43
49
|
"cli-manifest.json",
|
|
44
50
|
"scripts/",
|
|
@@ -52,6 +58,7 @@
|
|
|
52
58
|
"scripts": {
|
|
53
59
|
"dev": "tsx src/main.ts",
|
|
54
60
|
"build": "npm run clean-dist && npm run copy-yaml && npm run build-manifest",
|
|
61
|
+
"build:extension": "npm run build --prefix extension",
|
|
55
62
|
"prebuild-manifest": "tsc --build && node -e \"require('fs').chmodSync('dist/src/main.js', 0o755)\"",
|
|
56
63
|
"build-manifest": "tsx src/build-manifest.ts",
|
|
57
64
|
"clean-dist": "node scripts/clean-dist.cjs",
|
|
@@ -61,7 +68,7 @@
|
|
|
61
68
|
"postinstall": "node scripts/postinstall.js || true; node scripts/fetch-adapters.js || true",
|
|
62
69
|
"typecheck": "tsc --noEmit",
|
|
63
70
|
"prepare": "[ -d src ] && npm run build || true",
|
|
64
|
-
"prepublishOnly": "npm run build",
|
|
71
|
+
"prepublishOnly": "npm run build && npm run build:extension",
|
|
65
72
|
"test": "vitest run --project unit --project extension --project adapter",
|
|
66
73
|
"test:adapter": "vitest run --project adapter",
|
|
67
74
|
"test:all": "vitest run",
|
package/scripts/postinstall.js
CHANGED
|
@@ -16,8 +16,11 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { mkdirSync, writeFileSync, existsSync } from 'node:fs';
|
|
19
|
-
import { join } from 'node:path';
|
|
19
|
+
import { dirname, join } from 'node:path';
|
|
20
20
|
import { homedir } from 'node:os';
|
|
21
|
+
import { fileURLToPath } from 'node:url';
|
|
22
|
+
|
|
23
|
+
const PACKAGE_ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
21
24
|
|
|
22
25
|
|
|
23
26
|
// ── Completion script content ──────────────────────────────────────────────
|
|
@@ -163,7 +166,7 @@ function main() {
|
|
|
163
166
|
console.log('');
|
|
164
167
|
console.log(' \x1b[1mNext step — Browser Bridge setup\x1b[0m');
|
|
165
168
|
console.log(' Browser commands (bilibili, zhihu, twitter...) require the extension:');
|
|
166
|
-
console.log(' 1.
|
|
169
|
+
console.log(' 1. Browser Bridge is included at: ' + join(PACKAGE_ROOT, 'extension'));
|
|
167
170
|
console.log(' 2. In Chrome or Chromium, open chrome://extensions → enable Developer Mode → Load unpacked');
|
|
168
171
|
console.log('');
|
|
169
172
|
console.log(' Then run \x1b[36mbycli doctor\x1b[0m to verify.');
|