import { Type } from "@sinclair/typebox"; import type { ExtensionAPI } from "../_shared/pi-api.js"; import { errorResult, getCommandText, setTextWidget } from "../_shared/pi-api.js"; import { validateParams } from "../_shared/validation.js"; const BrowserParams = Type.Object({ action: Type.Union([Type.Literal("open"), Type.Literal("close"), Type.Literal("run")], { description: "OMP browser action" }), name: Type.Optional(Type.String({ maxLength: 200, description: "Tab id; defaults to main in OMP" })), url: Type.Optional(Type.String({ maxLength: 2000, description: "URL to open" })), app: Type.Optional(Type.Object({ path: Type.Optional(Type.String({ maxLength: 2000 })), cdp_url: Type.Optional(Type.String({ maxLength: 2000 })), args: Type.Optional(Type.Array(Type.String({ maxLength: 500 }), { maxItems: 50 })), target: Type.Optional(Type.String({ maxLength: 500 })), })), viewport: Type.Optional(Type.Object({ width: Type.Number(), height: Type.Number(), scale: Type.Optional(Type.Number()), })), wait_until: Type.Optional(Type.Union([ Type.Literal("load"), Type.Literal("domcontentloaded"), Type.Literal("networkidle0"), Type.Literal("networkidle2"), ])), dialogs: Type.Optional(Type.Union([Type.Literal("accept"), Type.Literal("dismiss")])), code: Type.Optional(Type.String({ maxLength: 50_000, description: "Async JS body for OMP browser run" })), timeout: Type.Optional(Type.Number({ minimum: 1, maximum: 300 })), all: Type.Optional(Type.Boolean()), kill: Type.Optional(Type.Boolean()), }); export default function browser(pi: ExtensionAPI): void { pi.registerTool({ name: "browser", description: "Disabled OMP browser wrapper contract. Real browser automation must be ported from OMP before use.", parameters: BrowserParams, execute(_toolCallId, params) { const valid = validateParams(BrowserParams, params); if (!valid.ok) return valid.result; return browserNotPorted(valid.value.action); }, }); pi.registerCommand("browser", { description: "Browser wrapper status.", handler: async (args, ctx) => { const text = getCommandText(args).trim(); setTextWidget(ctx, "browser", browserStatus(text)); }, }); } function browserNotPorted(action: string) { return errorResult( "Browser automation is disabled in miloc-pi: the previous mock driver was removed. Port OMP BrowserTool before enabling this extension.", { action, defaultEnabled: false, ownershipStatus: "omp-owned-to-import", ompActions: ["open", "close", "run"], sourceEvidence: "docs/source-audit/browser.md", }, ); } function browserStatus(args: string): string { const command = args || "doctor"; return [ "browser disabled", "status: OMP BrowserTool not ported", "mockDriver: removed", "targetActions: open, close, run", `requestedCommand: ${command}`, ].join("\n"); }