@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.
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.59",
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",
@@ -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. Download: https://github.com/sovovs/byCLI/releases');
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.');