browser-pilot-cli 0.3.0-rc.4 → 0.3.0-rc.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/README.md +1 -1
- package/dist/cli.js +4 -7
- package/dist/daemon.js +45 -10
- package/docs/plans/v0.3.0-stabilization.md +4 -2
- package/docs/releases/v0.3.0-rc.5.md +26 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -182,7 +182,7 @@ A project can pin Browser Pilot locally and run the same CLI without a global
|
|
|
182
182
|
installation:
|
|
183
183
|
|
|
184
184
|
```bash
|
|
185
|
-
npm install --save-exact browser-pilot-cli@0.3.0-rc.
|
|
185
|
+
npm install --save-exact browser-pilot-cli@0.3.0-rc.5
|
|
186
186
|
npx --no-install browser-pilot tabs
|
|
187
187
|
```
|
|
188
188
|
|
package/dist/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ import { writeFileSync as writeFileSync2, readFileSync as readFileSync4, existsS
|
|
|
6
6
|
import { resolve as resolvePath } from "path";
|
|
7
7
|
|
|
8
8
|
// src/version.ts
|
|
9
|
-
var BROWSER_PILOT_VERSION = "0.3.0-rc.
|
|
9
|
+
var BROWSER_PILOT_VERSION = "0.3.0-rc.5";
|
|
10
10
|
|
|
11
11
|
// src/protocol/errors.ts
|
|
12
12
|
var ERROR_CODES = [
|
|
@@ -1804,7 +1804,7 @@ var scrollEvidenceSchema = objectSchema({
|
|
|
1804
1804
|
afterX: numberSchema({ minimum: 0 }),
|
|
1805
1805
|
afterY: numberSchema({ minimum: 0 }),
|
|
1806
1806
|
matchedText: sensitive(stringSchema({ maxLength: 4096 }), "browser_data"),
|
|
1807
|
-
reason: stringSchema({ enum: ["at_boundary", "text_not_found"] })
|
|
1807
|
+
reason: stringSchema({ enum: ["at_boundary", "text_not_found", "text_not_revealed"] })
|
|
1808
1808
|
}, [
|
|
1809
1809
|
"action",
|
|
1810
1810
|
"status",
|
|
@@ -4368,9 +4368,6 @@ program.command("close").description("Close current browser tab").option("-a, --
|
|
|
4368
4368
|
context: { failedTargetIds: failed }
|
|
4369
4369
|
});
|
|
4370
4370
|
}
|
|
4371
|
-
if (remainingTabs.length > 0 && !remainingTabs.some((tab) => tab.active)) {
|
|
4372
|
-
await client.callTool("browser.tabs.switch", { targetId: remainingTabs[0].targetId });
|
|
4373
|
-
}
|
|
4374
4371
|
emit(
|
|
4375
4372
|
{ ok: true, closed, remaining: remainingTabs.length },
|
|
4376
4373
|
`\u2713 Closed ${closed} Pilot tab(s)`
|
|
@@ -4381,8 +4378,8 @@ program.command("close").description("Close current browser tab").option("-a, --
|
|
|
4381
4378
|
const remainingTabs = await client.listTabs("all");
|
|
4382
4379
|
if (remainingTabs.length > 0) {
|
|
4383
4380
|
if (!remainingTabs.some((tab) => tab.active)) {
|
|
4384
|
-
const fallback = remainingTabs.find((tab) => tab.origin !== "user_tab")
|
|
4385
|
-
await client.callTool("browser.tabs.switch", { targetId: fallback.targetId });
|
|
4381
|
+
const fallback = remainingTabs.find((tab) => tab.origin !== "user_tab");
|
|
4382
|
+
if (fallback) await client.callTool("browser.tabs.switch", { targetId: fallback.targetId });
|
|
4386
4383
|
}
|
|
4387
4384
|
emit({ ok: true, remaining: remainingTabs.length }, "\u2713 Tab closed");
|
|
4388
4385
|
} else {
|
package/dist/daemon.js
CHANGED
|
@@ -747,7 +747,7 @@ var scrollEvidenceSchema = objectSchema({
|
|
|
747
747
|
afterX: numberSchema({ minimum: 0 }),
|
|
748
748
|
afterY: numberSchema({ minimum: 0 }),
|
|
749
749
|
matchedText: sensitive(stringSchema({ maxLength: 4096 }), "browser_data"),
|
|
750
|
-
reason: stringSchema({ enum: ["at_boundary", "text_not_found"] })
|
|
750
|
+
reason: stringSchema({ enum: ["at_boundary", "text_not_found", "text_not_revealed"] })
|
|
751
751
|
}, [
|
|
752
752
|
"action",
|
|
753
753
|
"status",
|
|
@@ -9012,6 +9012,10 @@ var ScrollService = class {
|
|
|
9012
9012
|
const exact=${exact};
|
|
9013
9013
|
const normalize=value=>String(value||'').replace(/\\s+/g,' ').trim();
|
|
9014
9014
|
const needle=normalize(query).toLocaleLowerCase();
|
|
9015
|
+
const slash=String.fromCharCode(92);
|
|
9016
|
+
const regexSpecials='^$.*+?()[]{}|'+slash;
|
|
9017
|
+
const escapeRegex=value=>Array.from(value,char=>regexSpecials.includes(char)?slash+char:char).join('');
|
|
9018
|
+
const queryPattern=exact?null:new RegExp(normalize(query).split(' ').map(escapeRegex).join(slash+'s+'),'iu');
|
|
9015
9019
|
const roots=[document];
|
|
9016
9020
|
let visited=0;
|
|
9017
9021
|
while(roots.length&&visited<20000){
|
|
@@ -9029,21 +9033,50 @@ var ScrollService = class {
|
|
|
9029
9033
|
if(!element)continue;
|
|
9030
9034
|
const tag=String(element.tagName||'').toLowerCase();
|
|
9031
9035
|
if(['script','style','noscript','template'].includes(tag))continue;
|
|
9032
|
-
const
|
|
9036
|
+
const raw=String(node.nodeValue||'');
|
|
9037
|
+
const content=normalize(raw);
|
|
9033
9038
|
const normalized=content.toLocaleLowerCase();
|
|
9034
9039
|
if(!(exact?normalized===needle:normalized.includes(needle)))continue;
|
|
9040
|
+
let matchStart=0;
|
|
9041
|
+
let matchEnd=raw.length;
|
|
9042
|
+
if(exact){
|
|
9043
|
+
matchStart=Math.max(0,raw.search(/\\S/u));
|
|
9044
|
+
matchEnd=Math.max(matchStart,raw.length-((raw.match(/\\s*$/u)||[''])[0].length));
|
|
9045
|
+
}else{
|
|
9046
|
+
const match=queryPattern.exec(raw);
|
|
9047
|
+
if(!match)continue;
|
|
9048
|
+
matchStart=match.index;
|
|
9049
|
+
matchEnd=match.index+match[0].length;
|
|
9050
|
+
}
|
|
9035
9051
|
const style=getComputedStyle(element);
|
|
9036
9052
|
if(style.display==='none'||style.visibility==='hidden'||style.visibility==='collapse'||element.getClientRects().length===0)continue;
|
|
9053
|
+
const viewportWidth=Math.max(0,window.innerWidth||document.documentElement.clientWidth||0);
|
|
9054
|
+
const viewportHeight=Math.max(0,window.innerHeight||document.documentElement.clientHeight||0);
|
|
9055
|
+
const range=document.createRange();
|
|
9056
|
+
range.setStart(node,matchStart);
|
|
9057
|
+
range.setEnd(node,matchEnd);
|
|
9058
|
+
const rangeRect=()=>range.getBoundingClientRect();
|
|
9059
|
+
const intersectsViewport=rect=>rect.width>0&&rect.height>0&&rect.bottom>0&&rect.right>0&&rect.top<viewportHeight&&rect.left<viewportWidth;
|
|
9037
9060
|
const beforeX=Math.max(0,window.scrollX||document.documentElement.scrollLeft||0);
|
|
9038
9061
|
const beforeY=Math.max(0,window.scrollY||document.documentElement.scrollTop||0);
|
|
9039
9062
|
element.scrollIntoView({block:'center',inline:'nearest',behavior:'instant'});
|
|
9040
|
-
|
|
9041
|
-
|
|
9063
|
+
let afterX=Math.max(0,window.scrollX||document.documentElement.scrollLeft||0);
|
|
9064
|
+
let afterY=Math.max(0,window.scrollY||document.documentElement.scrollTop||0);
|
|
9065
|
+
let rect=rangeRect();
|
|
9066
|
+
if(!intersectsViewport(rect)){
|
|
9067
|
+
const left=Math.max(0,afterX+rect.left-Math.max(0,(viewportWidth-rect.width)/2));
|
|
9068
|
+
const top=Math.max(0,afterY+rect.top-Math.max(0,(viewportHeight-rect.height)/2));
|
|
9069
|
+
window.scrollTo({left,top,behavior:'instant'});
|
|
9070
|
+
afterX=Math.max(0,window.scrollX||document.documentElement.scrollLeft||0);
|
|
9071
|
+
afterY=Math.max(0,window.scrollY||document.documentElement.scrollTop||0);
|
|
9072
|
+
rect=rangeRect();
|
|
9073
|
+
}
|
|
9042
9074
|
const round=value=>Math.round(Number(value)||0);
|
|
9043
9075
|
const moved=Math.abs(afterX-beforeX)>=1||Math.abs(afterY-beforeY)>=1;
|
|
9044
|
-
|
|
9076
|
+
const revealed=intersectsViewport(rect);
|
|
9077
|
+
return{ok:true,action:'scroll',status:revealed?'verified':'mismatch',mode:'text',target:'text',moved,
|
|
9045
9078
|
deltaX:round(afterX-beforeX),deltaY:round(afterY-beforeY),beforeX:round(beforeX),beforeY:round(beforeY),
|
|
9046
|
-
afterX:round(afterX),afterY:round(afterY),matchedText:content.slice(0,4096)};
|
|
9079
|
+
afterX:round(afterX),afterY:round(afterY),matchedText:content.slice(0,4096),...(revealed?{}:{reason:'text_not_revealed'})};
|
|
9047
9080
|
}
|
|
9048
9081
|
}
|
|
9049
9082
|
return{ok:true,action:'scroll',status:'mismatch',mode:'text',target:'text',moved:false,
|
|
@@ -9066,11 +9099,13 @@ var ScrollService = class {
|
|
|
9066
9099
|
var MAX_ANNOTATIONS = 200;
|
|
9067
9100
|
function annotationScript(data, annotations, viewport) {
|
|
9068
9101
|
return `(async() => {
|
|
9069
|
-
const
|
|
9102
|
+
const base64=${JSON.stringify(data)};
|
|
9070
9103
|
const annotations=${JSON.stringify(annotations)};
|
|
9071
9104
|
const viewport=${JSON.stringify(viewport)};
|
|
9072
|
-
const
|
|
9073
|
-
const
|
|
9105
|
+
const binary=atob(base64);
|
|
9106
|
+
const bytes=new Uint8Array(binary.length);
|
|
9107
|
+
for(let index=0;index<binary.length;index+=1)bytes[index]=binary.charCodeAt(index);
|
|
9108
|
+
const bitmap=await createImageBitmap(new Blob([bytes],{type:'image/png'}));
|
|
9074
9109
|
const canvas=document.createElement('canvas');
|
|
9075
9110
|
canvas.width=bitmap.width;canvas.height=bitmap.height;
|
|
9076
9111
|
const context=canvas.getContext('2d');
|
|
@@ -13979,7 +14014,7 @@ var ManagedTargetJanitorClient = class {
|
|
|
13979
14014
|
};
|
|
13980
14015
|
|
|
13981
14016
|
// src/version.ts
|
|
13982
|
-
var BROWSER_PILOT_VERSION = "0.3.0-rc.
|
|
14017
|
+
var BROWSER_PILOT_VERSION = "0.3.0-rc.5";
|
|
13983
14018
|
|
|
13984
14019
|
// src/daemon.ts
|
|
13985
14020
|
var CLI_EXECUTABLE_PATH = publicExecutablePath(import.meta.url);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Browser Pilot v0.3.0 Stabilization Plan
|
|
2
2
|
|
|
3
3
|
Status: **In progress**
|
|
4
|
-
Candidate baseline: `v0.3.0-rc.
|
|
4
|
+
Candidate baseline: `v0.3.0-rc.4`; correction target: `v0.3.0-rc.5`, protocol `1.2`
|
|
5
5
|
|
|
6
6
|
## Goal
|
|
7
7
|
|
|
@@ -35,8 +35,10 @@ products depend on. No Agent-specific behavior enters Browser Pilot.
|
|
|
35
35
|
integration checks against the installed standalone release executable.
|
|
36
36
|
- [x] Run one controlled user-Chrome host acceptance with explicit Profile
|
|
37
37
|
choices and a single authorization attempt.
|
|
38
|
-
- [
|
|
38
|
+
- [x] Publish `v0.3.0-rc.4` with Broker-backed CLI browser status and verify
|
|
39
39
|
that passive discovery reports the live authorized connection.
|
|
40
|
+
- [ ] Publish `v0.3.0-rc.5` with the real-site soak corrections and rerun the
|
|
41
|
+
same public information, form, capture, and managed-cleanup tasks.
|
|
40
42
|
- [ ] Soak several real Agent tasks through the installed candidate.
|
|
41
43
|
- [ ] Tag `v0.3.0`, publish npm `latest`, and verify upgrade/rollback metadata.
|
|
42
44
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Browser Pilot 0.3.0-rc.5
|
|
2
|
+
|
|
3
|
+
This release candidate fixes three edge cases found by running RC.4 through
|
|
4
|
+
real Agent tasks in two live Chrome Profiles.
|
|
5
|
+
|
|
6
|
+
- Text-targeted scrolling now verifies that the matched text actually entered
|
|
7
|
+
the viewport. If a site's `scrollIntoView` path is ineffective, Browser Pilot
|
|
8
|
+
falls back to the matched text Range's page coordinates; an unrevealed match
|
|
9
|
+
returns an explicit mismatch instead of a false success.
|
|
10
|
+
- Screenshot annotations no longer decode captured PNGs through
|
|
11
|
+
`fetch(data:)`. They use in-memory base64, Blob, and ImageBitmap conversion in
|
|
12
|
+
the isolated world, so restrictive site `connect-src` policies such as
|
|
13
|
+
GitHub's cannot break annotation.
|
|
14
|
+
- Tab cleanup no longer switches control to a user tab when Chrome has not yet
|
|
15
|
+
reported its next active target. `bp close --all` still closes only managed
|
|
16
|
+
tabs.
|
|
17
|
+
|
|
18
|
+
The soak otherwise completed public GitHub reading and targeted search, a
|
|
19
|
+
disposable HTTP form with verified input and control state, submission result
|
|
20
|
+
verification, multi-Profile routing, ordinary screenshots, annotated form
|
|
21
|
+
screenshots, PDF export, connection-status checks, and preservation of every
|
|
22
|
+
user tab and exported file.
|
|
23
|
+
|
|
24
|
+
RC.5 keeps protocol 1.2 and the Agent-neutral stdio contract unchanged.
|
|
25
|
+
Candidate gates passed with 276 Node tests, 109 isolated Playwright tests, and
|
|
26
|
+
TypeScript type checking.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "browser-pilot-cli",
|
|
3
|
-
"version": "0.3.0-rc.
|
|
3
|
+
"version": "0.3.0-rc.5",
|
|
4
4
|
"description": "CLI tool to control your browser via Chrome DevTools Protocol",
|
|
5
5
|
"repository": "https://github.com/relixiaobo/browser-pilot",
|
|
6
6
|
"type": "module",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"docs/releases/v0.3.0-rc.2.md",
|
|
49
49
|
"docs/releases/v0.3.0-rc.3.md",
|
|
50
50
|
"docs/releases/v0.3.0-rc.4.md",
|
|
51
|
+
"docs/releases/v0.3.0-rc.5.md",
|
|
51
52
|
"README.md",
|
|
52
53
|
"LICENSE"
|
|
53
54
|
],
|