refactor: tidy the whitespace the comment removal left behind Drops leading blank lines where a file header was removed, collapses double blank lines, and closes the empty catch/handler blocks whose only content had been a comment. Whitespace only. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
jump to
@@ -1,4 +1,3 @@
- import { decodeEvent } from "./events"; export type ConsoleLevel = "log" | "info" | "warn" | "error" | "debug";@@ -43,8 +42,7 @@ if (pattern.length >= 2 && pattern.startsWith("/") && pattern.endsWith("/")) {
try { const re = new RegExp(pattern.slice(1, -1)); return (text) => re.test(text); - } catch { - } + } catch {} } return (text) => text.includes(pattern); };
@@ -1,4 +1,3 @@
- import { createConnection, type Socket } from "node:net"; import { createInterface } from "node:readline"; import { type Result, err, ok } from "../util/result";@@ -13,7 +12,6 @@ type WireControl,
deserialize, serialize, } from "../daemon/protocol"; - export const createDaemonTransport = (clientId: string): CdpTransport => { let socket: Socket | null = null;@@ -35,7 +33,6 @@ if (socket) { try { socket.destroy(); } catch {} socket = null; }
for (const cb of closeListeners) cb(); }; - const connect = (_url: string, opts?: { timeoutMs?: number }): Promise<Result<void, CdpError>> => { const timeoutMs = opts?.timeoutMs ?? 10_000;@@ -117,8 +114,7 @@ return;
} }); - sock.on("error", () => { - }); + sock.on("error", () => {}); sock.on("close", () => { clearTimeout(connectTimer);@@ -140,7 +136,6 @@ });
}); }; - const close = async (): Promise<void> => { if (registered && socket && !socket.destroyed) { const dereg: WireControl = { type: "control", action: "deregister", clientId };@@ -148,7 +143,6 @@ try { socket.write(serialize(dereg) + "\n"); } catch {}
} cleanup("close() called"); }; - const request = ( method: string,@@ -175,9 +169,7 @@
return sendWithTimeout(pending, id, method, timeoutMs, "Daemon", () => sock.write(serialize(req) + "\n")); }; - const events = (): AsyncIterable<CdpEvent> => queue.iter; - const state = (): "open" | "closed" | "connecting" => { if (!socket) return "closed";
@@ -114,8 +114,7 @@ try {
raw = await readFile(portFile, "utf8"); try { mtimeMs = (await stat(portFile)).mtimeMs; - } catch { - } + } catch {} } catch (e) { // EPERM/EACCES is common under sandboxes; remember it and fall back to network probing rather than failing the whole discovery. const code = errnoCode(e);
@@ -1,4 +1,3 @@
- import { type Result, err } from "../util/result"; import { type CdpError, cdpError } from "./errors"; import type { CdpEvent } from "./types";
@@ -1,4 +1,3 @@
- import { decodeEvent } from "./events"; export type NetworkRecord = {@@ -47,8 +46,7 @@ if (pattern.length >= 2 && pattern.startsWith("/") && pattern.endsWith("/")) {
try { const re = new RegExp(pattern.slice(1, -1)); return (url) => re.test(url); - } catch { - } + } catch {} } return (url) => url.includes(pattern); };
@@ -1,4 +1,3 @@
- export type OwnershipRegistry = { add(targetId: string): void; remove(targetId: string): void;
@@ -1,4 +1,3 @@
- import WebSocket from "ws"; import { discoverWsUrl } from "../cdp/discovery"; import { isCdpRawMessage } from "../cdp/types";@@ -6,7 +5,6 @@ import type { CdpRawMessage } from "../cdp/types";
import type { WireRequest, WireResponse, WireEvent } from "./protocol"; import { CDP_CONNECT_TIMEOUT_MS, CDP_COMMAND_TIMEOUT_MS } from "./protocol"; import { asString, isRecord } from "../util/guards"; - export type SendToClient = (clientId: string, msg: WireResponse | WireEvent) => void;@@ -26,7 +24,6 @@ removeClient(clientId: string): void;
onEvent(handler: EventHandler): void; onClose(handler: CloseHandler): void; }; - interface PendingEntry { clientId: string;@@ -62,7 +59,6 @@ if (m) { for (const [, did] of m) this.pending.delete(did); }
this.localToRemote.delete(clientId); } } - class EventRouter { private owners = new Map<string, string>();@@ -108,7 +104,6 @@ return [...this.clientSessions.keys()];
} } - export const createCdpBridge = (): CdpBridge => { let ws: WebSocket | null = null; let wsUrl: string | null = null;@@ -124,7 +119,6 @@ localId: number;
timer: ReturnType<typeof setTimeout>; isAttach: boolean; }>(); - const onChromeMessage = (raw: string): void => { let parsed: unknown;@@ -183,8 +177,6 @@ eventHandler(wireEvent, targets);
} } }; - - let reconnectTimer: ReturnType<typeof setTimeout> | null = null; let reconnectAttempt = 0;
@@ -1,4 +1,3 @@
- import { createIpcServer } from "./server"; import { createCdpBridge, type SendToClient } from "./bridge"; import { DAEMON_IDLE_TIMEOUT_MS } from "./protocol";@@ -8,7 +7,6 @@ console.log("[pi-browser-daemon] Starting...");
const ipcServer = createIpcServer(); const cdpBridge = createCdpBridge(); - ipcServer.onMessage((msg, client) => { if (msg.type !== "request") return;@@ -38,7 +36,6 @@ action: "shutdown",
reason: "chrome_disconnected", }); }); - let idleTimer: ReturnType<typeof setTimeout> | null = null;@@ -60,7 +57,6 @@
ipcServer.onConnect(() => { cancelIdleTimer(); }); ipcServer.onDisconnect(() => { resetIdleTimer(); }); - try { await ipcServer.start(); console.log("[pi-browser-daemon] IPC server listening");@@ -72,7 +68,6 @@
await cdpBridge.start(); resetIdleTimer(); - const shutdown = async () => { console.log("[pi-browser-daemon] Shutting down...");
@@ -1,6 +1,4 @@
- import { isRecord } from "../util/guards"; - export type WireRequest = { readonly type: "request";@@ -36,7 +34,6 @@ readonly reason?: string;
}; export type WireMessage = WireRequest | WireResponse | WireEvent | WireControl; - export const isWireMessage = (v: unknown): v is WireMessage => { if (!isRecord(v)) return false;@@ -85,7 +82,6 @@ return false;
} }; - export const serialize = (msg: WireMessage): string => JSON.stringify(msg); export const deserialize = (line: string): WireMessage | null => {@@ -98,7 +94,6 @@ }
if (!isWireMessage(parsed)) return null; return parsed; }; - // Windows requires a named pipe (`\\.\pipe\<name>`); a Unix path is not a valid `net` listen/connect target there. export const DAEMON_SOCKET_PATH =
@@ -1,4 +1,3 @@
- import { createServer, type Server, type Socket } from "node:net"; import { createInterface, type Interface } from "node:readline"; import { unlinkSync } from "node:fs";@@ -10,7 +9,6 @@ DAEMON_SOCKET_PATH,
DAEMON_MAX_CLIENTS, DAEMON_STALE_SOCKET_CLEANUP, } from "./protocol"; - export type ClientSocket = { id: string;@@ -35,7 +33,6 @@ disconnectClient(clientId: string): void;
clients(): ReadonlyMap<string, ClientSocket>; clientCount(): number; }; - export const createIpcServer = (): IpcServer => { let server: Server | null = null;@@ -51,8 +48,7 @@ new Promise((resolve, reject) => {
if (DAEMON_STALE_SOCKET_CLEANUP) { try { unlinkSync(DAEMON_SOCKET_PATH); - } catch { - } + } catch {} } server = createServer({ pauseOnConnect: false }, (socket: Socket) => {@@ -113,8 +109,7 @@
messageHandler?.(msg, currentClient); }); - socket.on("error", () => { - }); + socket.on("error", () => {}); socket.on("close", () => { const found = clients.get(currentClient.id) ?? sockets.get(tempId);@@ -176,8 +171,7 @@ const client = clients.get(clientId);
if (!client) return; try { client.socket.write(JSON.stringify(msg) + "\n"); - } catch { - } + } catch {} }, broadcast(msg) { for (const [clientId] of clients) {
@@ -1,4 +1,3 @@
- import { spawn, type ChildProcess } from "node:child_process"; import { access, unlink } from "node:fs/promises"; import { existsSync } from "node:fs";
@@ -1,6 +1,4 @@
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent"; - export function buildDeepResearchPrompt(question: string): string { return (@@ -10,7 +8,6 @@ `subagents to research each against the live web, then synthesize a source-cited report file.\n\n` +
`Question: ${question}` ); } - export function registerDeepResearchCommand(pi: ExtensionAPI): void { pi.registerCommand("deep-research", {
@@ -1,4 +1,3 @@
- const BODY_TEXT_LIMIT = 20_000; export const buildPageCaptureExpr = (): string => `
@@ -1,4 +1,3 @@
- export type ContentBlock = { readonly kind: "paragraph" | "heading" | "listitem" | "blockquote" | "other"; readonly text: string;
@@ -1,4 +1,3 @@
- const PAGE_TEXT_LIMIT = 4000; export const buildSerpExtractionExpr = (): string => `
@@ -1,4 +1,3 @@
- export type SerpAnchor = { readonly href: string; readonly heading: string;
@@ -1,4 +1,3 @@
- import { Type } from "typebox"; import { Text } from "@mariozechner/pi-tui"; import type { Result } from "../util/result";
@@ -1,4 +1,3 @@
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent"; import { type BrowserClient, createBrowserClient } from "./client"; import { getBrowserSystemPrompt } from "./prompt";@@ -118,7 +117,6 @@ });
} else { client.setProfilePin(profilePin); } - if (!toolsRegistered) { registerAllTools(pi, client);
@@ -1,4 +1,3 @@
- import type { BrowserClient } from "../client"; import { attachTo } from "../cdp/attach"; import type { ResultOf } from "../cdp/commands";
@@ -106,7 +106,6 @@ const value = match[1] ?? match[2] ?? match[3];
return value && value.length > 0 ? value : undefined; }; - const collectLinux = async (): Promise<ReadonlyArray<BrowserCandidate>> => { let pids: string[]; try {@@ -135,8 +134,7 @@ if (!cmdline || hasChildProcessType(cmdline)) continue;
let link: string | undefined; try { link = await readlink(`/proc/${pid}/exe`); - } catch { - } + } catch {} // Chrome rewrites its argv to the bare executable path, so argv[0] is the live install location when /proc/<pid>/exe is unreadable or stale. const exePath = (link ? await spawnableExePath(link) : undefined) ??@@ -149,7 +147,6 @@ });
} return candidates; }; - const collectDarwin = async (): Promise<ReadonlyArray<BrowserCandidate>> => { let lines: string[];@@ -175,8 +172,7 @@ let args = "";
try { const { stdout } = await run("ps", ["-ww", "-o", "args=", "-p", pid], { timeout: EXEC_TIMEOUT_MS }); args = stdout.trim(); - } catch { - } + } catch {} if (args && hasChildProcessType(args)) continue; const explicit = args ? parseUserDataDirFlag(args) : undefined; candidates.push({@@ -186,7 +182,6 @@ });
} return candidates; }; - const POWERSHELL_QUERY = [ "$ErrorActionPreference='SilentlyContinue';",@@ -232,15 +227,13 @@ });
if (candidates.length > 0) return candidates; } } - } catch { - } + } catch {} try { const { stdout } = await run("tasklist.exe", [], { timeout: EXEC_TIMEOUT_MS, windowsHide: true }); const lower = stdout.toLowerCase(); if (WIN_IMAGE_NAMES.some((n) => lower.includes(n))) return [{}]; - } catch { - } + } catch {} return []; };@@ -273,13 +266,11 @@ );
const match = /REG_[A-Z_]+\s+(.+)$/m.exec(stdout.trim()); const path = match?.[1]?.trim(); if (path) return path; - } catch { - } + } catch {} } } return undefined; }; - export const detectRunningBrowser = async (preferUserDataDir?: string): Promise<RunningBrowser> => { const candidates =@@ -323,8 +314,7 @@ for (const candidate of winInstallCandidates()) {
try { await access(candidate); return candidate; - } catch { - } + } catch {} } return undefined; };
@@ -1,4 +1,3 @@
- import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent"; import type { BrowserClient } from "../client"; import { discoverEndpoint } from "../cdp/discovery";
@@ -1,4 +1,3 @@
- import { readdir, readFile } from "node:fs/promises"; import { join } from "node:path"; import { Type } from "typebox";
@@ -3,7 +3,6 @@
import { homedir } from "node:os"; import { join } from "node:path"; - const ENV_AGENT_DIR = "PI_CODING_AGENT_DIR"; // Deliberately mirrors pi's expandTildePath (never `~\…`) rather than improving on it, or the pin lands somewhere pi does not look.@@ -26,7 +25,6 @@ return join(homedir(), ".pi", "agent");
}; export const pinFilePath = (): string => join(agentDir(), "browser-harness.json"); - const localAppData = (): string => process.env["LOCALAPPDATA"] ?? join(homedir(), "AppData", "Local");
@@ -1,11 +1,9 @@
- import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent"; import type { BrowserClient } from "./client"; import { ensureDaemon } from "./daemon/spawn"; import { DAEMON_SOCKET_PATH } from "./daemon/protocol"; import { isBrowserRunning } from "./profile/browser-process"; import { promptForProfileIfUnset } from "./profile/command"; - export function registerSetupCommand(pi: ExtensionAPI, client: BrowserClient): void { pi.registerCommand("browser-setup", {@@ -21,9 +19,7 @@ },
}); } - export type SetupResult = { success: true; data: string } | { success: false; error: string }; - export async function performSetup(client: BrowserClient, ctx?: ExtensionContext): Promise<SetupResult> { const chromeRunning = await isBrowserRunning();
@@ -1,4 +1,3 @@
- import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent"; import { asArrayOf, asNumber, asString, isRecord } from "./util/guards";
@@ -34,14 +34,12 @@
await ipcServer.start(); console.log("Daemon started ✓"); - console.log("\nConnecting pi client (DaemonTransport)..."); const transport = createDaemonTransport("pi-e2e-test"); const connectResult = await transport.connect(""); check(connectResult.success, `Client connect: ${connectResult.success ? "ok" : connectResult.error.message}`); check(transport.state() === "open", "Transport state is open"); - let rawRequests: WireRequest[] = []; ipcServer.onMessage((msg, client) => {
@@ -44,8 +44,7 @@ if (pid === undefined) return;
if (process.platform === "win32") { try { execFileSync("taskkill.exe", ["/pid", String(pid), "/T", "/F"], { stdio: "ignore" }); - } catch { - } + } catch {} return; } try {@@ -53,8 +52,7 @@ process.kill(-pid, "SIGKILL");
} catch { try { process.kill(pid, "SIGKILL"); - } catch { - } + } catch {} } };@@ -81,8 +79,7 @@ await sleep(500);
try { const res = await fetch(`http://127.0.0.1:${PORT}/json/version`); if (res.ok) endpoint = ((await res.json()) as { webSocketDebuggerUrl: string }).webSocketDebuggerUrl; - } catch { - } + } catch {} } if (!endpoint) { check(false, `${label}: browser exposed its DevTools endpoint`);@@ -144,8 +141,7 @@ } finally {
killTree(browser.pid); try { rmSync(udd, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 }); - } catch { - } + } catch {} } }
@@ -47,8 +47,7 @@ for (const name of ["google-chrome", "chromium", "chromium-browser"]) {
try { const resolved = execFileSync("which", [name], { encoding: "utf8" }).trim(); if (resolved) return resolved; - } catch { - } + } catch {} } } return undefined;@@ -96,8 +95,7 @@ while (Date.now() < end) {
try { const res = await fetch(`http://127.0.0.1:${PORT}/json/version`); if (res.ok) return true; - } catch { - } + } catch {} await sleep(500); } return false;@@ -132,8 +130,7 @@ // Any surviving child keeps the user-data-dir locked, which on Windows also blocks the directory removal.
if (process.platform === "win32") { try { execFileSync("taskkill.exe", ["/pid", String(browser.pid), "/T", "/F"], { stdio: "ignore" }); - } catch { - } + } catch {} } else { try { // detached:true put the browser in its own process group, so the negative pid signals the whole group.@@ -141,14 +138,12 @@ process.kill(-browser.pid!, "SIGKILL");
} catch { try { browser.kill("SIGKILL"); - } catch { - } + } catch {} } } try { rmSync(udd, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 }); - } catch { - } + } catch {} }; try {
@@ -1,4 +1,3 @@
- import { access } from "node:fs/promises"; import { setTimeout as sleep } from "node:timers/promises"; import { spawn } from "node:child_process";