mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 11:04:51 +00:00
Integrate JailJS for CSP-restricted execution in browser extension
Major changes: - Migrate browser-extension to use web-ui package (85% code reduction) - Add JailJS content script with ES6+ transform support - Expose DOM constructors (Event, KeyboardEvent, etc.) to JailJS - Support top-level await by wrapping code in async IIFE - Add returnFile() support in JailJS execution - Refactor KeyStore into pluggable storage-adapter pattern - Make ChatPanel configurable with sandboxUrlProvider and additionalTools - Update jailjs to 0.1.1 Files deleted (33 duplicate files): - All browser-extension components, dialogs, state, tools, utils - Now using web-ui versions via @mariozechner/pi-web-ui Files added: - packages/browser-extension/src/content.ts (JailJS content script) - packages/web-ui/src/state/storage-adapter.ts - packages/web-ui/src/state/key-store.ts Browser extension now has only 5 source files (down from 38).
This commit is contained in:
parent
f2eecb78d2
commit
aaea0f4600
61 changed files with 633 additions and 9270 deletions
|
|
@ -1,10 +1,8 @@
|
|||
import { html, type TemplateResult } from "@mariozechner/mini-lit";
|
||||
import type { AgentTool, ToolResultMessage } from "@mariozechner/pi-ai";
|
||||
import { type Attachment, registerToolRenderer, type ToolRenderer } from "@mariozechner/pi-web-ui";
|
||||
import { type Static, Type } from "@sinclair/typebox";
|
||||
import "../components/ConsoleBlock.js"; // Ensure console-block is registered
|
||||
import type { Attachment } from "../utils/attachment-utils.js";
|
||||
import { registerToolRenderer } from "./renderer-registry.js";
|
||||
import type { ToolRenderer } from "./types.js";
|
||||
import "@mariozechner/pi-web-ui"; // Ensure all components are registered
|
||||
|
||||
// Cross-browser API compatibility
|
||||
// @ts-expect-error - browser global exists in Firefox, chrome in Chrome
|
||||
|
|
@ -211,13 +209,111 @@ This ensures reliable execution.`,
|
|||
const canUseEval = cspCheckResults[0]?.result?.canEval ?? false;
|
||||
const canUseScriptTag = cspCheckResults[0]?.result?.canUseScriptTag ?? false;
|
||||
|
||||
// If neither method works, return error immediately
|
||||
// If neither method works, fallback to JailJS via content script
|
||||
if (!canUseEval && !canUseScriptTag) {
|
||||
console.log("[pi-ai] CSP blocks eval and script injection, falling back to JailJS");
|
||||
|
||||
// Send execution request to content script
|
||||
const response = await new Promise<{
|
||||
success: boolean;
|
||||
result?: unknown;
|
||||
console?: Array<{ type: string; args: unknown[] }>;
|
||||
files?: Array<{ fileName: string; content: string | Uint8Array; mimeType: string }>;
|
||||
error?: string;
|
||||
stack?: string;
|
||||
}>((resolve) => {
|
||||
browser.tabs.sendMessage(
|
||||
tab.id,
|
||||
{
|
||||
type: "EXECUTE_CODE",
|
||||
mode: "jailjs",
|
||||
code: args.code,
|
||||
},
|
||||
resolve,
|
||||
);
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
return {
|
||||
output: `JailJS Execution Error: ${response.error}\n\nStack:\n${response.stack || "No stack trace"}`,
|
||||
isError: true,
|
||||
details: { files: [] },
|
||||
};
|
||||
}
|
||||
|
||||
// Format console output
|
||||
const formatArg = (arg: unknown): string => {
|
||||
if (arg === null) return "null";
|
||||
if (arg === undefined) return "undefined";
|
||||
if (typeof arg === "string") return arg;
|
||||
if (typeof arg === "number" || typeof arg === "boolean") return String(arg);
|
||||
try {
|
||||
return JSON.stringify(arg, null, 2);
|
||||
} catch {
|
||||
return String(arg);
|
||||
}
|
||||
};
|
||||
|
||||
// Build output with console logs
|
||||
let output = "";
|
||||
|
||||
// Add console output
|
||||
if (response.console && response.console.length > 0) {
|
||||
for (const entry of response.console) {
|
||||
const prefix = entry.type === "error" ? "[ERROR]" : entry.type === "warn" ? "[WARN]" : "";
|
||||
const formattedArgs = entry.args.map(formatArg).join(" ");
|
||||
const line = prefix ? `${prefix} ${formattedArgs}` : formattedArgs;
|
||||
output += line + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Add file notifications
|
||||
if (response.files && response.files.length > 0) {
|
||||
output += `\n[Files returned: ${response.files.length}]\n`;
|
||||
for (const file of response.files) {
|
||||
output += ` - ${file.fileName} (${file.mimeType})\n`;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert files to base64 for transport
|
||||
const files = (response.files || []).map(
|
||||
(f: { fileName: string; content: string | Uint8Array; mimeType: string }) => {
|
||||
const toBase64 = (input: string | Uint8Array): { base64: string; size: number } => {
|
||||
if (input instanceof Uint8Array) {
|
||||
let binary = "";
|
||||
const chunk = 0x8000;
|
||||
for (let i = 0; i < input.length; i += chunk) {
|
||||
binary += String.fromCharCode(...input.subarray(i, i + chunk));
|
||||
}
|
||||
return { base64: btoa(binary), size: input.length };
|
||||
} else {
|
||||
const enc = new TextEncoder();
|
||||
const bytes = enc.encode(input);
|
||||
let binary = "";
|
||||
const chunk = 0x8000;
|
||||
for (let i = 0; i < bytes.length; i += chunk) {
|
||||
binary += String.fromCharCode(...bytes.subarray(i, i + chunk));
|
||||
}
|
||||
return { base64: btoa(binary), size: bytes.length };
|
||||
}
|
||||
};
|
||||
|
||||
const { base64, size } = toBase64(f.content);
|
||||
return {
|
||||
fileName: f.fileName || "file",
|
||||
mimeType: f.mimeType || "application/octet-stream",
|
||||
size,
|
||||
contentBase64: base64,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
output:
|
||||
"Cannot execute JavaScript on this page. The page's Content Security Policy blocks both eval() and inline script injection. This is common on sites with strict CSP.",
|
||||
isError: true,
|
||||
details: { files: [] },
|
||||
output.trim() ||
|
||||
"Code executed successfully (no output)\n\n⚠️ Note: CSP blocked direct execution. Code ran via JailJS interpreter.",
|
||||
isError: false,
|
||||
details: { files },
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue