Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bproxy/cli",
"version": "0.9.2",
"version": "0.9.3",
"private": true,
"type": "module",
"bin": {
Expand Down
2 changes: 1 addition & 1 deletion extension/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bproxy/extension",
"version": "0.9.2",
"version": "0.9.3",
"private": true,
"type": "module",
"scripts": {
Expand Down
24 changes: 23 additions & 1 deletion extension/src/background/__tests__/dispatcher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,35 @@ describe("parseForwardedRequest", () => {
JSON.stringify(
makeRequest({
action: "links",
params: { selector: "#search", visibleOnly: true, limit: 10 },
params: {
selector: "#search",
visibleOnly: true,
limit: 10,
hrefContains: "/in/",
offset: 5,
},
}),
),
);
expect(parsed.success).toBe(true);
});

it("rejects negative links offset at the forwarded request boundary", () => {
const parsed = parseForwardedRequest(
JSON.stringify(
makeRequest({
action: "links",
params: { limit: 10, offset: -1 },
}),
),
);
expect(parsed).toMatchObject({
success: false,
id: "req-1",
error: "params are invalid for action links",
});
});

it("accepts click and hover params for forwarded DOM interactions", () => {
expect(
parseForwardedRequest(
Expand Down
33 changes: 29 additions & 4 deletions extension/src/background/forwarded-params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,15 @@ function isSelectorParams(value: unknown): value is ForwardedActionParams["text"
}

function isLinksParams(value: unknown): value is ForwardedActionParams["links"] {
if (!isStrictObject(value, ["selector", "visibleOnly", "limit", "hrefContains", "offset"])) {
return false;
}
return (
isStrictObject(value, ["selector", "visibleOnly", "limit"]) &&
(value["selector"] === undefined || typeof value["selector"] === "string") &&
(value["visibleOnly"] === undefined || typeof value["visibleOnly"] === "boolean") &&
(value["limit"] === undefined || isInteger(value["limit"]))
optionalFieldMatches(value, "selector", isString) &&
optionalFieldMatches(value, "visibleOnly", isBoolean) &&
optionalFieldMatches(value, "limit", isInteger) &&
optionalFieldMatches(value, "hrefContains", isString) &&
optionalFieldMatches(value, "offset", isNonNegativeInteger)
);
}

Expand Down Expand Up @@ -232,10 +236,31 @@ function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}

function optionalFieldMatches(
value: Record<string, unknown>,
key: string,
validator: (field: unknown) => boolean,
): boolean {
const field = value[key];
return field === undefined || validator(field);
}

function isString(value: unknown): value is string {
return typeof value === "string";
}

function isBoolean(value: unknown): value is boolean {
return typeof value === "boolean";
}

function isInteger(value: unknown): value is number {
return typeof value === "number" && Number.isInteger(value);
}

function isNonNegativeInteger(value: unknown): value is number {
return isInteger(value) && value >= 0;
}

export function isTarget(value: unknown): value is BproxyForwardedRequest["target"] {
return isStrictObject(value, ["tabId"]) && (value["tabId"] === null || isInteger(value["tabId"]));
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "bproxy",
"private": true,
"type": "module",
"version": "0.9.2",
"version": "0.9.3",
"description": "Human-in-the-loop browser proxy for AI agents.",
"license": "MIT",
"packageManager": "pnpm@9.15.0",
Expand Down
2 changes: 1 addition & 1 deletion service/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bproxy/service",
"version": "0.9.2",
"version": "0.9.3",
"private": true,
"type": "module",
"bin": {
Expand Down
2 changes: 1 addition & 1 deletion shared/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bproxy/shared",
"version": "0.9.2",
"version": "0.9.3",
"private": true,
"type": "module",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion shared/src/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

/** Current bproxy package version (semver). */
export const VERSION = "0.9.2";
export const VERSION = "0.9.3";

/** Protocol version for the daemon↔CLI↔extension wire format. */
export const PROTOCOL_VERSION = 2;
2 changes: 1 addition & 1 deletion skills/bproxy/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ description: >-
compatibility: Node >=24, bproxy installed (npm install -g @dimdasci/bproxy), daemon running, extension paired
license: MIT
metadata:
version: "0.9.2"
version: "0.9.3"
---

# bproxy
Expand Down
2 changes: 1 addition & 1 deletion views/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@bproxy/views",
"private": true,
"version": "0.9.2",
"version": "0.9.3",
"type": "module",
"scripts": {
"dev": "astro dev",
Expand Down