@flrande/bak-extension 0.1.0
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/dist/background.global.js +623 -0
- package/dist/content.global.js +2042 -0
- package/dist/manifest.json +20 -0
- package/dist/popup.global.js +52 -0
- package/dist/popup.html +106 -0
- package/package.json +18 -0
- package/public/manifest.json +20 -0
- package/public/popup.html +106 -0
- package/scripts/copy-assets.mjs +16 -0
- package/src/background.ts +705 -0
- package/src/content.ts +2267 -0
- package/src/limitations.ts +38 -0
- package/src/popup.ts +65 -0
- package/src/privacy.ts +135 -0
- package/src/reconnect.ts +25 -0
- package/src/url-policy.ts +12 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifest_version": 3,
|
|
3
|
+
"name": "Browser Agent Kit",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"action": {
|
|
6
|
+
"default_popup": "popup.html"
|
|
7
|
+
},
|
|
8
|
+
"permissions": ["storage", "tabs", "activeTab"],
|
|
9
|
+
"host_permissions": ["<all_urls>"],
|
|
10
|
+
"background": {
|
|
11
|
+
"service_worker": "background.global.js"
|
|
12
|
+
},
|
|
13
|
+
"content_scripts": [
|
|
14
|
+
{
|
|
15
|
+
"matches": ["http://*/*", "https://*/*"],
|
|
16
|
+
"js": ["content.global.js"],
|
|
17
|
+
"run_at": "document_idle"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
(() => {
|
|
3
|
+
// src/popup.ts
|
|
4
|
+
var statusEl = document.getElementById("status");
|
|
5
|
+
var tokenInput = document.getElementById("token");
|
|
6
|
+
var portInput = document.getElementById("port");
|
|
7
|
+
var debugRichTextInput = document.getElementById("debugRichText");
|
|
8
|
+
var saveBtn = document.getElementById("save");
|
|
9
|
+
var disconnectBtn = document.getElementById("disconnect");
|
|
10
|
+
function setStatus(text, bad = false) {
|
|
11
|
+
statusEl.textContent = text;
|
|
12
|
+
statusEl.style.color = bad ? "#dc2626" : "#0f172a";
|
|
13
|
+
}
|
|
14
|
+
async function refreshState() {
|
|
15
|
+
const state = await chrome.runtime.sendMessage({ type: "bak.getState" });
|
|
16
|
+
if (state.ok) {
|
|
17
|
+
portInput.value = String(state.port);
|
|
18
|
+
debugRichTextInput.checked = Boolean(state.debugRichText);
|
|
19
|
+
if (state.connected) {
|
|
20
|
+
setStatus("Connected to bak CLI");
|
|
21
|
+
} else if (state.lastError) {
|
|
22
|
+
setStatus(`Disconnected: ${state.lastError}`, true);
|
|
23
|
+
} else {
|
|
24
|
+
setStatus("Disconnected");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
saveBtn.addEventListener("click", async () => {
|
|
29
|
+
const token = tokenInput.value.trim();
|
|
30
|
+
const port = Number.parseInt(portInput.value.trim(), 10);
|
|
31
|
+
if (!token) {
|
|
32
|
+
setStatus("Pair token is required", true);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (!Number.isInteger(port) || port <= 0) {
|
|
36
|
+
setStatus("Port is invalid", true);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
await chrome.runtime.sendMessage({
|
|
40
|
+
type: "bak.updateConfig",
|
|
41
|
+
token,
|
|
42
|
+
port,
|
|
43
|
+
debugRichText: debugRichTextInput.checked
|
|
44
|
+
});
|
|
45
|
+
await refreshState();
|
|
46
|
+
});
|
|
47
|
+
disconnectBtn.addEventListener("click", async () => {
|
|
48
|
+
await chrome.runtime.sendMessage({ type: "bak.disconnect" });
|
|
49
|
+
await refreshState();
|
|
50
|
+
});
|
|
51
|
+
void refreshState();
|
|
52
|
+
})();
|
package/dist/popup.html
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>BAK Pairing</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 14px;
|
|
11
|
+
width: 320px;
|
|
12
|
+
font-family: "Segoe UI", sans-serif;
|
|
13
|
+
color: #0f172a;
|
|
14
|
+
background: linear-gradient(160deg, #f8fafc, #eef2ff);
|
|
15
|
+
}
|
|
16
|
+
h1 {
|
|
17
|
+
margin: 0 0 12px;
|
|
18
|
+
font-size: 16px;
|
|
19
|
+
}
|
|
20
|
+
label {
|
|
21
|
+
display: block;
|
|
22
|
+
margin-top: 10px;
|
|
23
|
+
font-size: 12px;
|
|
24
|
+
}
|
|
25
|
+
input {
|
|
26
|
+
width: 100%;
|
|
27
|
+
box-sizing: border-box;
|
|
28
|
+
margin-top: 4px;
|
|
29
|
+
padding: 8px;
|
|
30
|
+
border: 1px solid #cbd5e1;
|
|
31
|
+
border-radius: 6px;
|
|
32
|
+
font-size: 12px;
|
|
33
|
+
}
|
|
34
|
+
.toggle {
|
|
35
|
+
display: flex;
|
|
36
|
+
align-items: flex-start;
|
|
37
|
+
gap: 8px;
|
|
38
|
+
margin-top: 12px;
|
|
39
|
+
padding: 8px;
|
|
40
|
+
border: 1px solid #fbbf24;
|
|
41
|
+
border-radius: 6px;
|
|
42
|
+
background: #fffbeb;
|
|
43
|
+
}
|
|
44
|
+
.toggle input {
|
|
45
|
+
width: auto;
|
|
46
|
+
margin-top: 2px;
|
|
47
|
+
}
|
|
48
|
+
.toggle-text {
|
|
49
|
+
font-size: 11px;
|
|
50
|
+
color: #92400e;
|
|
51
|
+
}
|
|
52
|
+
.row {
|
|
53
|
+
display: flex;
|
|
54
|
+
gap: 8px;
|
|
55
|
+
margin-top: 12px;
|
|
56
|
+
}
|
|
57
|
+
button {
|
|
58
|
+
flex: 1;
|
|
59
|
+
border: none;
|
|
60
|
+
border-radius: 6px;
|
|
61
|
+
padding: 8px;
|
|
62
|
+
font-size: 12px;
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
}
|
|
65
|
+
#save {
|
|
66
|
+
background: #0f172a;
|
|
67
|
+
color: #fff;
|
|
68
|
+
}
|
|
69
|
+
#disconnect {
|
|
70
|
+
background: #e2e8f0;
|
|
71
|
+
color: #0f172a;
|
|
72
|
+
}
|
|
73
|
+
#status {
|
|
74
|
+
margin-top: 10px;
|
|
75
|
+
font-size: 12px;
|
|
76
|
+
}
|
|
77
|
+
.hint {
|
|
78
|
+
margin-top: 10px;
|
|
79
|
+
font-size: 11px;
|
|
80
|
+
color: #334155;
|
|
81
|
+
}
|
|
82
|
+
</style>
|
|
83
|
+
</head>
|
|
84
|
+
<body>
|
|
85
|
+
<h1>Browser Agent Kit</h1>
|
|
86
|
+
<label>
|
|
87
|
+
Pair token
|
|
88
|
+
<input id="token" placeholder="paste token from `bak pair`" />
|
|
89
|
+
</label>
|
|
90
|
+
<label>
|
|
91
|
+
CLI port
|
|
92
|
+
<input id="port" value="17373" />
|
|
93
|
+
</label>
|
|
94
|
+
<label class="toggle">
|
|
95
|
+
<input id="debugRichText" type="checkbox" />
|
|
96
|
+
<span class="toggle-text">Allow richer text capture for debugging (still redacted, off by default)</span>
|
|
97
|
+
</label>
|
|
98
|
+
<div class="row">
|
|
99
|
+
<button id="save">Save & Connect</button>
|
|
100
|
+
<button id="disconnect">Disconnect</button>
|
|
101
|
+
</div>
|
|
102
|
+
<div id="status">Checking...</div>
|
|
103
|
+
<div class="hint">Extension only connects to ws://127.0.0.1</div>
|
|
104
|
+
<script src="./popup.global.js"></script>
|
|
105
|
+
</body>
|
|
106
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flrande/bak-extension",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@flrande/bak-protocol": "0.1.0"
|
|
7
|
+
},
|
|
8
|
+
"devDependencies": {
|
|
9
|
+
"@types/chrome": "^0.1.14",
|
|
10
|
+
"tsup": "^8.5.0"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsup src/background.ts src/content.ts src/popup.ts --format iife --out-dir dist --clean && node scripts/copy-assets.mjs",
|
|
14
|
+
"dev": "node scripts/copy-assets.mjs && tsup src/background.ts src/content.ts src/popup.ts --format iife --out-dir dist --watch",
|
|
15
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
16
|
+
"lint": "eslint src --ext .ts"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifest_version": 3,
|
|
3
|
+
"name": "Browser Agent Kit",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"action": {
|
|
6
|
+
"default_popup": "popup.html"
|
|
7
|
+
},
|
|
8
|
+
"permissions": ["storage", "tabs", "activeTab"],
|
|
9
|
+
"host_permissions": ["<all_urls>"],
|
|
10
|
+
"background": {
|
|
11
|
+
"service_worker": "background.global.js"
|
|
12
|
+
},
|
|
13
|
+
"content_scripts": [
|
|
14
|
+
{
|
|
15
|
+
"matches": ["http://*/*", "https://*/*"],
|
|
16
|
+
"js": ["content.global.js"],
|
|
17
|
+
"run_at": "document_idle"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>BAK Pairing</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 14px;
|
|
11
|
+
width: 320px;
|
|
12
|
+
font-family: "Segoe UI", sans-serif;
|
|
13
|
+
color: #0f172a;
|
|
14
|
+
background: linear-gradient(160deg, #f8fafc, #eef2ff);
|
|
15
|
+
}
|
|
16
|
+
h1 {
|
|
17
|
+
margin: 0 0 12px;
|
|
18
|
+
font-size: 16px;
|
|
19
|
+
}
|
|
20
|
+
label {
|
|
21
|
+
display: block;
|
|
22
|
+
margin-top: 10px;
|
|
23
|
+
font-size: 12px;
|
|
24
|
+
}
|
|
25
|
+
input {
|
|
26
|
+
width: 100%;
|
|
27
|
+
box-sizing: border-box;
|
|
28
|
+
margin-top: 4px;
|
|
29
|
+
padding: 8px;
|
|
30
|
+
border: 1px solid #cbd5e1;
|
|
31
|
+
border-radius: 6px;
|
|
32
|
+
font-size: 12px;
|
|
33
|
+
}
|
|
34
|
+
.toggle {
|
|
35
|
+
display: flex;
|
|
36
|
+
align-items: flex-start;
|
|
37
|
+
gap: 8px;
|
|
38
|
+
margin-top: 12px;
|
|
39
|
+
padding: 8px;
|
|
40
|
+
border: 1px solid #fbbf24;
|
|
41
|
+
border-radius: 6px;
|
|
42
|
+
background: #fffbeb;
|
|
43
|
+
}
|
|
44
|
+
.toggle input {
|
|
45
|
+
width: auto;
|
|
46
|
+
margin-top: 2px;
|
|
47
|
+
}
|
|
48
|
+
.toggle-text {
|
|
49
|
+
font-size: 11px;
|
|
50
|
+
color: #92400e;
|
|
51
|
+
}
|
|
52
|
+
.row {
|
|
53
|
+
display: flex;
|
|
54
|
+
gap: 8px;
|
|
55
|
+
margin-top: 12px;
|
|
56
|
+
}
|
|
57
|
+
button {
|
|
58
|
+
flex: 1;
|
|
59
|
+
border: none;
|
|
60
|
+
border-radius: 6px;
|
|
61
|
+
padding: 8px;
|
|
62
|
+
font-size: 12px;
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
}
|
|
65
|
+
#save {
|
|
66
|
+
background: #0f172a;
|
|
67
|
+
color: #fff;
|
|
68
|
+
}
|
|
69
|
+
#disconnect {
|
|
70
|
+
background: #e2e8f0;
|
|
71
|
+
color: #0f172a;
|
|
72
|
+
}
|
|
73
|
+
#status {
|
|
74
|
+
margin-top: 10px;
|
|
75
|
+
font-size: 12px;
|
|
76
|
+
}
|
|
77
|
+
.hint {
|
|
78
|
+
margin-top: 10px;
|
|
79
|
+
font-size: 11px;
|
|
80
|
+
color: #334155;
|
|
81
|
+
}
|
|
82
|
+
</style>
|
|
83
|
+
</head>
|
|
84
|
+
<body>
|
|
85
|
+
<h1>Browser Agent Kit</h1>
|
|
86
|
+
<label>
|
|
87
|
+
Pair token
|
|
88
|
+
<input id="token" placeholder="paste token from `bak pair`" />
|
|
89
|
+
</label>
|
|
90
|
+
<label>
|
|
91
|
+
CLI port
|
|
92
|
+
<input id="port" value="17373" />
|
|
93
|
+
</label>
|
|
94
|
+
<label class="toggle">
|
|
95
|
+
<input id="debugRichText" type="checkbox" />
|
|
96
|
+
<span class="toggle-text">Allow richer text capture for debugging (still redacted, off by default)</span>
|
|
97
|
+
</label>
|
|
98
|
+
<div class="row">
|
|
99
|
+
<button id="save">Save & Connect</button>
|
|
100
|
+
<button id="disconnect">Disconnect</button>
|
|
101
|
+
</div>
|
|
102
|
+
<div id="status">Checking...</div>
|
|
103
|
+
<div class="hint">Extension only connects to ws://127.0.0.1</div>
|
|
104
|
+
<script src="./popup.global.js"></script>
|
|
105
|
+
</body>
|
|
106
|
+
</html>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { cpSync, existsSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
|
|
4
|
+
const root = resolve(import.meta.dirname, '..');
|
|
5
|
+
const fromDir = resolve(root, 'public');
|
|
6
|
+
const distDir = resolve(root, 'dist');
|
|
7
|
+
|
|
8
|
+
if (!existsSync(distDir)) {
|
|
9
|
+
mkdirSync(distDir, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
for (const file of ['manifest.json', 'popup.html']) {
|
|
13
|
+
cpSync(resolve(fromDir, file), resolve(distDir, file), { force: true });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
console.log('Copied extension assets to dist');
|