mac: bundle web chat assets
This commit is contained in:
35
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/ArtifactsRuntimeProvider.d.ts
vendored
Normal file
35
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/ArtifactsRuntimeProvider.d.ts
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { SandboxRuntimeProvider } from "./SandboxRuntimeProvider.js";
|
||||
interface ArtifactsPanelLike {
|
||||
artifacts: Map<string, {
|
||||
content: string;
|
||||
}>;
|
||||
tool: {
|
||||
execute(toolCallId: string, args: {
|
||||
command: string;
|
||||
filename: string;
|
||||
content?: string;
|
||||
}): Promise<any>;
|
||||
};
|
||||
}
|
||||
interface AgentLike {
|
||||
appendMessage(message: any): void;
|
||||
}
|
||||
/**
|
||||
* Artifacts Runtime Provider
|
||||
*
|
||||
* Provides programmatic access to session artifacts from sandboxed code.
|
||||
* Allows code to create, read, update, and delete artifacts dynamically.
|
||||
* Supports both online (extension) and offline (downloaded HTML) modes.
|
||||
*/
|
||||
export declare class ArtifactsRuntimeProvider implements SandboxRuntimeProvider {
|
||||
private artifactsPanel;
|
||||
private agent?;
|
||||
private readWrite;
|
||||
constructor(artifactsPanel: ArtifactsPanelLike, agent?: AgentLike | undefined, readWrite?: boolean);
|
||||
getData(): Record<string, any>;
|
||||
getRuntime(): (sandboxId: string) => void;
|
||||
handleMessage(message: any, respond: (response: any) => void): Promise<void>;
|
||||
getDescription(): string;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=ArtifactsRuntimeProvider.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ArtifactsRuntimeProvider.d.ts","sourceRoot":"","sources":["../../../src/components/sandbox/ArtifactsRuntimeProvider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAG1E,UAAU,kBAAkB;IAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5C,IAAI,EAAE;QACL,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;KACzG,CAAC;CACF;AAED,UAAU,SAAS;IAClB,aAAa,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;GAMG;AACH,qBAAa,wBAAyB,YAAW,sBAAsB;IAErE,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,KAAK,CAAC;IACd,OAAO,CAAC,SAAS;gBAFT,cAAc,EAAE,kBAAkB,EAClC,KAAK,CAAC,EAAE,SAAS,YAAA,EACjB,SAAS,GAAE,OAAc;IAGlC,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAS9B,UAAU,IAAI,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI;IAgGnC,aAAa,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA8ElF,cAAc,IAAI,MAAM;CAGxB"}
|
||||
@@ -0,0 +1,189 @@
|
||||
import { ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RO, ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RW, } from "../../prompts/prompts.js";
|
||||
/**
|
||||
* Artifacts Runtime Provider
|
||||
*
|
||||
* Provides programmatic access to session artifacts from sandboxed code.
|
||||
* Allows code to create, read, update, and delete artifacts dynamically.
|
||||
* Supports both online (extension) and offline (downloaded HTML) modes.
|
||||
*/
|
||||
export class ArtifactsRuntimeProvider {
|
||||
constructor(artifactsPanel, agent, readWrite = true) {
|
||||
this.artifactsPanel = artifactsPanel;
|
||||
this.agent = agent;
|
||||
this.readWrite = readWrite;
|
||||
}
|
||||
getData() {
|
||||
// Inject artifact snapshot for offline mode
|
||||
const snapshot = {};
|
||||
this.artifactsPanel.artifacts.forEach((artifact, filename) => {
|
||||
snapshot[filename] = artifact.content;
|
||||
});
|
||||
return { artifacts: snapshot };
|
||||
}
|
||||
getRuntime() {
|
||||
// This function will be stringified, so no external references!
|
||||
return (_sandboxId) => {
|
||||
// Auto-parse/stringify for .json files
|
||||
const isJsonFile = (filename) => filename.endsWith(".json");
|
||||
window.listArtifacts = async () => {
|
||||
// Online: ask extension
|
||||
if (window.sendRuntimeMessage) {
|
||||
const response = await window.sendRuntimeMessage({
|
||||
type: "artifact-operation",
|
||||
action: "list",
|
||||
});
|
||||
if (!response.success)
|
||||
throw new Error(response.error);
|
||||
return response.result;
|
||||
}
|
||||
// Offline: return snapshot keys
|
||||
else {
|
||||
return Object.keys(window.artifacts || {});
|
||||
}
|
||||
};
|
||||
window.getArtifact = async (filename) => {
|
||||
let content;
|
||||
// Online: ask extension
|
||||
if (window.sendRuntimeMessage) {
|
||||
const response = await window.sendRuntimeMessage({
|
||||
type: "artifact-operation",
|
||||
action: "get",
|
||||
filename,
|
||||
});
|
||||
if (!response.success)
|
||||
throw new Error(response.error);
|
||||
content = response.result;
|
||||
}
|
||||
// Offline: read snapshot
|
||||
else {
|
||||
if (!window.artifacts?.[filename]) {
|
||||
throw new Error(`Artifact not found (offline mode): ${filename}`);
|
||||
}
|
||||
content = window.artifacts[filename];
|
||||
}
|
||||
// Auto-parse .json files
|
||||
if (isJsonFile(filename)) {
|
||||
try {
|
||||
return JSON.parse(content);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Failed to parse JSON from ${filename}: ${e}`);
|
||||
}
|
||||
}
|
||||
return content;
|
||||
};
|
||||
window.createOrUpdateArtifact = async (filename, content, mimeType) => {
|
||||
if (!window.sendRuntimeMessage) {
|
||||
throw new Error("Cannot create/update artifacts in offline mode (read-only)");
|
||||
}
|
||||
let finalContent = content;
|
||||
// Auto-stringify .json files
|
||||
if (isJsonFile(filename) && typeof content !== "string") {
|
||||
finalContent = JSON.stringify(content, null, 2);
|
||||
}
|
||||
else if (typeof content !== "string") {
|
||||
finalContent = JSON.stringify(content, null, 2);
|
||||
}
|
||||
const response = await window.sendRuntimeMessage({
|
||||
type: "artifact-operation",
|
||||
action: "createOrUpdate",
|
||||
filename,
|
||||
content: finalContent,
|
||||
mimeType,
|
||||
});
|
||||
if (!response.success)
|
||||
throw new Error(response.error);
|
||||
};
|
||||
window.deleteArtifact = async (filename) => {
|
||||
if (!window.sendRuntimeMessage) {
|
||||
throw new Error("Cannot delete artifacts in offline mode (read-only)");
|
||||
}
|
||||
const response = await window.sendRuntimeMessage({
|
||||
type: "artifact-operation",
|
||||
action: "delete",
|
||||
filename,
|
||||
});
|
||||
if (!response.success)
|
||||
throw new Error(response.error);
|
||||
};
|
||||
};
|
||||
}
|
||||
async handleMessage(message, respond) {
|
||||
if (message.type !== "artifact-operation") {
|
||||
return;
|
||||
}
|
||||
const { action, filename, content, mimeType } = message;
|
||||
try {
|
||||
switch (action) {
|
||||
case "list": {
|
||||
const filenames = Array.from(this.artifactsPanel.artifacts.keys());
|
||||
respond({ success: true, result: filenames });
|
||||
break;
|
||||
}
|
||||
case "get": {
|
||||
const artifact = this.artifactsPanel.artifacts.get(filename);
|
||||
if (!artifact) {
|
||||
respond({ success: false, error: `Artifact not found: ${filename}` });
|
||||
}
|
||||
else {
|
||||
respond({ success: true, result: artifact.content });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "createOrUpdate": {
|
||||
try {
|
||||
const exists = this.artifactsPanel.artifacts.has(filename);
|
||||
const command = exists ? "rewrite" : "create";
|
||||
const action = exists ? "update" : "create";
|
||||
await this.artifactsPanel.tool.execute("", {
|
||||
command,
|
||||
filename,
|
||||
content,
|
||||
});
|
||||
this.agent?.appendMessage({
|
||||
role: "artifact",
|
||||
action,
|
||||
filename,
|
||||
content,
|
||||
...(action === "create" && { title: filename }),
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
respond({ success: true });
|
||||
}
|
||||
catch (err) {
|
||||
respond({ success: false, error: err.message });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "delete": {
|
||||
try {
|
||||
await this.artifactsPanel.tool.execute("", {
|
||||
command: "delete",
|
||||
filename,
|
||||
});
|
||||
this.agent?.appendMessage({
|
||||
role: "artifact",
|
||||
action: "delete",
|
||||
filename,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
respond({ success: true });
|
||||
}
|
||||
catch (err) {
|
||||
respond({ success: false, error: err.message });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
respond({ success: false, error: `Unknown artifact action: ${action}` });
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
respond({ success: false, error: error.message });
|
||||
}
|
||||
}
|
||||
getDescription() {
|
||||
return this.readWrite ? ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RW : ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RO;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=ArtifactsRuntimeProvider.js.map
|
||||
File diff suppressed because one or more lines are too long
17
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/AttachmentsRuntimeProvider.d.ts
vendored
Normal file
17
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/AttachmentsRuntimeProvider.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import type { Attachment } from "../../utils/attachment-utils.js";
|
||||
import type { SandboxRuntimeProvider } from "./SandboxRuntimeProvider.js";
|
||||
/**
|
||||
* Attachments Runtime Provider
|
||||
*
|
||||
* OPTIONAL provider that provides file access APIs to sandboxed code.
|
||||
* Only needed when attachments are present.
|
||||
* Attachments are read-only snapshot data - no messaging needed.
|
||||
*/
|
||||
export declare class AttachmentsRuntimeProvider implements SandboxRuntimeProvider {
|
||||
private attachments;
|
||||
constructor(attachments: Attachment[]);
|
||||
getData(): Record<string, any>;
|
||||
getRuntime(): (sandboxId: string) => void;
|
||||
getDescription(): string;
|
||||
}
|
||||
//# sourceMappingURL=AttachmentsRuntimeProvider.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"AttachmentsRuntimeProvider.d.ts","sourceRoot":"","sources":["../../../src/components/sandbox/AttachmentsRuntimeProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1E;;;;;;GAMG;AACH,qBAAa,0BAA2B,YAAW,sBAAsB;IAC5D,OAAO,CAAC,WAAW;gBAAX,WAAW,EAAE,UAAU,EAAE;IAE7C,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAa9B,UAAU,IAAI,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI;IAmCzC,cAAc,IAAI,MAAM;CAGxB"}
|
||||
@@ -0,0 +1,64 @@
|
||||
import { ATTACHMENTS_RUNTIME_DESCRIPTION } from "../../prompts/prompts.js";
|
||||
/**
|
||||
* Attachments Runtime Provider
|
||||
*
|
||||
* OPTIONAL provider that provides file access APIs to sandboxed code.
|
||||
* Only needed when attachments are present.
|
||||
* Attachments are read-only snapshot data - no messaging needed.
|
||||
*/
|
||||
export class AttachmentsRuntimeProvider {
|
||||
constructor(attachments) {
|
||||
this.attachments = attachments;
|
||||
}
|
||||
getData() {
|
||||
const attachmentsData = this.attachments.map((a) => ({
|
||||
id: a.id,
|
||||
fileName: a.fileName,
|
||||
mimeType: a.mimeType,
|
||||
size: a.size,
|
||||
content: a.content,
|
||||
extractedText: a.extractedText,
|
||||
}));
|
||||
return { attachments: attachmentsData };
|
||||
}
|
||||
getRuntime() {
|
||||
// This function will be stringified, so no external references!
|
||||
// These functions read directly from window.attachments
|
||||
// Works both online AND offline (no messaging needed!)
|
||||
return (_sandboxId) => {
|
||||
window.listAttachments = () => (window.attachments || []).map((a) => ({
|
||||
id: a.id,
|
||||
fileName: a.fileName,
|
||||
mimeType: a.mimeType,
|
||||
size: a.size,
|
||||
}));
|
||||
window.readTextAttachment = (attachmentId) => {
|
||||
const a = (window.attachments || []).find((x) => x.id === attachmentId);
|
||||
if (!a)
|
||||
throw new Error("Attachment not found: " + attachmentId);
|
||||
if (a.extractedText)
|
||||
return a.extractedText;
|
||||
try {
|
||||
return atob(a.content);
|
||||
}
|
||||
catch {
|
||||
throw new Error("Failed to decode text content for: " + attachmentId);
|
||||
}
|
||||
};
|
||||
window.readBinaryAttachment = (attachmentId) => {
|
||||
const a = (window.attachments || []).find((x) => x.id === attachmentId);
|
||||
if (!a)
|
||||
throw new Error("Attachment not found: " + attachmentId);
|
||||
const bin = atob(a.content);
|
||||
const bytes = new Uint8Array(bin.length);
|
||||
for (let i = 0; i < bin.length; i++)
|
||||
bytes[i] = bin.charCodeAt(i);
|
||||
return bytes;
|
||||
};
|
||||
};
|
||||
}
|
||||
getDescription() {
|
||||
return ATTACHMENTS_RUNTIME_DESCRIPTION;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=AttachmentsRuntimeProvider.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"AttachmentsRuntimeProvider.js","sourceRoot":"","sources":["../../../src/components/sandbox/AttachmentsRuntimeProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,0BAA0B,CAAC;AAI3E;;;;;;GAMG;AACH,MAAM,OAAO,0BAA0B;IACtC,YAAoB,WAAyB;QAAzB,gBAAW,GAAX,WAAW,CAAc;IAAG,CAAC;IAEjD,OAAO;QACN,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpD,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,aAAa,EAAE,CAAC,CAAC,aAAa;SAC9B,CAAC,CAAC,CAAC;QAEJ,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;IACzC,CAAC;IAED,UAAU;QACT,gEAAgE;QAChE,wDAAwD;QACxD,uDAAuD;QACvD,OAAO,CAAC,UAAkB,EAAE,EAAE;YAC5B,MAAc,CAAC,eAAe,GAAG,GAAG,EAAE,CACtC,CAAE,MAAc,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;gBACpD,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,IAAI,EAAE,CAAC,CAAC,IAAI;aACZ,CAAC,CAAC,CAAC;YAEJ,MAAc,CAAC,kBAAkB,GAAG,CAAC,YAAoB,EAAE,EAAE;gBAC7D,MAAM,CAAC,GAAG,CAAE,MAAc,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC,CAAC;gBACtF,IAAI,CAAC,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,YAAY,CAAC,CAAC;gBACjE,IAAI,CAAC,CAAC,aAAa;oBAAE,OAAO,CAAC,CAAC,aAAa,CAAC;gBAC5C,IAAI,CAAC;oBACJ,OAAO,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBACxB,CAAC;gBAAC,MAAM,CAAC;oBACR,MAAM,IAAI,KAAK,CAAC,qCAAqC,GAAG,YAAY,CAAC,CAAC;gBACvE,CAAC;YACF,CAAC,CAAC;YAED,MAAc,CAAC,oBAAoB,GAAG,CAAC,YAAoB,EAAE,EAAE;gBAC/D,MAAM,CAAC,GAAG,CAAE,MAAc,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC,CAAC;gBACtF,IAAI,CAAC,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,YAAY,CAAC,CAAC;gBACjE,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBAC5B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE;oBAAE,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAClE,OAAO,KAAK,CAAC;YACd,CAAC,CAAC;QACH,CAAC,CAAC;IACH,CAAC;IAED,cAAc;QACb,OAAO,+BAA+B,CAAC;IACxC,CAAC;CACD"}
|
||||
42
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/ConsoleRuntimeProvider.d.ts
vendored
Normal file
42
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/ConsoleRuntimeProvider.d.ts
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
import type { SandboxRuntimeProvider } from "./SandboxRuntimeProvider.js";
|
||||
export interface ConsoleLog {
|
||||
type: "log" | "warn" | "error" | "info";
|
||||
text: string;
|
||||
args?: unknown[];
|
||||
}
|
||||
/**
|
||||
* Console Runtime Provider
|
||||
*
|
||||
* REQUIRED provider that should always be included first.
|
||||
* Provides console capture, error handling, and execution lifecycle management.
|
||||
* Collects console output for retrieval by caller.
|
||||
*/
|
||||
export declare class ConsoleRuntimeProvider implements SandboxRuntimeProvider {
|
||||
private logs;
|
||||
private completionError;
|
||||
private completed;
|
||||
getData(): Record<string, any>;
|
||||
getDescription(): string;
|
||||
getRuntime(): (sandboxId: string) => void;
|
||||
handleMessage(message: any, respond: (response: any) => void): Promise<void>;
|
||||
/**
|
||||
* Get collected console logs
|
||||
*/
|
||||
getLogs(): ConsoleLog[];
|
||||
/**
|
||||
* Get completion status
|
||||
*/
|
||||
isCompleted(): boolean;
|
||||
/**
|
||||
* Get completion error if any
|
||||
*/
|
||||
getCompletionError(): {
|
||||
message: string;
|
||||
stack: string;
|
||||
} | null;
|
||||
/**
|
||||
* Reset state for reuse
|
||||
*/
|
||||
reset(): void;
|
||||
}
|
||||
//# sourceMappingURL=ConsoleRuntimeProvider.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ConsoleRuntimeProvider.d.ts","sourceRoot":"","sources":["../../../src/components/sandbox/ConsoleRuntimeProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;CACjB;AAED;;;;;;GAMG;AACH,qBAAa,sBAAuB,YAAW,sBAAsB;IACpE,OAAO,CAAC,IAAI,CAAoB;IAChC,OAAO,CAAC,eAAe,CAAmD;IAC1E,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAK9B,cAAc,IAAI,MAAM;IAIxB,UAAU,IAAI,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI;IA4GnC,aAAa,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBlF;;OAEG;IACH,OAAO,IAAI,UAAU,EAAE;IAIvB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,kBAAkB,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAI/D;;OAEG;IACH,KAAK,IAAI,IAAI;CAKb"}
|
||||
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* Console Runtime Provider
|
||||
*
|
||||
* REQUIRED provider that should always be included first.
|
||||
* Provides console capture, error handling, and execution lifecycle management.
|
||||
* Collects console output for retrieval by caller.
|
||||
*/
|
||||
export class ConsoleRuntimeProvider {
|
||||
constructor() {
|
||||
this.logs = [];
|
||||
this.completionError = null;
|
||||
this.completed = false;
|
||||
}
|
||||
getData() {
|
||||
// No data needed
|
||||
return {};
|
||||
}
|
||||
getDescription() {
|
||||
return "";
|
||||
}
|
||||
getRuntime() {
|
||||
return (_sandboxId) => {
|
||||
// Store truly original console methods on first wrap only
|
||||
// This prevents accumulation of wrapper functions across multiple executions
|
||||
if (!window.__originalConsole) {
|
||||
window.__originalConsole = {
|
||||
log: console.log.bind(console),
|
||||
error: console.error.bind(console),
|
||||
warn: console.warn.bind(console),
|
||||
info: console.info.bind(console),
|
||||
};
|
||||
}
|
||||
// Always use the truly original console, not the current (possibly wrapped) one
|
||||
const originalConsole = window.__originalConsole;
|
||||
// Track pending send promises to wait for them in onCompleted
|
||||
const pendingSends = [];
|
||||
["log", "error", "warn", "info"].forEach((method) => {
|
||||
console[method] = (...args) => {
|
||||
const text = args
|
||||
.map((arg) => {
|
||||
try {
|
||||
return typeof arg === "object" ? JSON.stringify(arg) : String(arg);
|
||||
}
|
||||
catch {
|
||||
return String(arg);
|
||||
}
|
||||
})
|
||||
.join(" ");
|
||||
// Always log locally too (using truly original console)
|
||||
originalConsole[method].apply(console, args);
|
||||
// Send immediately and track the promise (only in extension context)
|
||||
if (window.sendRuntimeMessage) {
|
||||
const sendPromise = window
|
||||
.sendRuntimeMessage({
|
||||
type: "console",
|
||||
method,
|
||||
text,
|
||||
args,
|
||||
})
|
||||
.catch(() => { });
|
||||
pendingSends.push(sendPromise);
|
||||
}
|
||||
};
|
||||
});
|
||||
// Register completion callback to wait for all pending sends
|
||||
if (window.onCompleted) {
|
||||
window.onCompleted(async (_success) => {
|
||||
// Wait for all pending console sends to complete
|
||||
if (pendingSends.length > 0) {
|
||||
await Promise.all(pendingSends);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Track errors for HTML artifacts
|
||||
let lastError = null;
|
||||
// Error handlers - track errors but don't log them
|
||||
// (they'll be shown via execution-error message)
|
||||
window.addEventListener("error", (e) => {
|
||||
const text = (e.error?.stack || e.message || String(e)) + " at line " + (e.lineno || "?") + ":" + (e.colno || "?");
|
||||
lastError = {
|
||||
message: e.error?.message || e.message || String(e),
|
||||
stack: e.error?.stack || text,
|
||||
};
|
||||
});
|
||||
window.addEventListener("unhandledrejection", (e) => {
|
||||
const text = "Unhandled promise rejection: " + (e.reason?.message || e.reason || "Unknown error");
|
||||
lastError = {
|
||||
message: e.reason?.message || String(e.reason) || "Unhandled promise rejection",
|
||||
stack: e.reason?.stack || text,
|
||||
};
|
||||
});
|
||||
// Expose complete() method for user code to call
|
||||
let completionSent = false;
|
||||
window.complete = async (error, returnValue) => {
|
||||
if (completionSent)
|
||||
return;
|
||||
completionSent = true;
|
||||
const finalError = error || lastError;
|
||||
if (window.sendRuntimeMessage) {
|
||||
if (finalError) {
|
||||
await window.sendRuntimeMessage({
|
||||
type: "execution-error",
|
||||
error: finalError,
|
||||
});
|
||||
}
|
||||
else {
|
||||
await window.sendRuntimeMessage({
|
||||
type: "execution-complete",
|
||||
returnValue,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
async handleMessage(message, respond) {
|
||||
if (message.type === "console") {
|
||||
// Collect console output
|
||||
this.logs.push({
|
||||
type: message.method === "error"
|
||||
? "error"
|
||||
: message.method === "warn"
|
||||
? "warn"
|
||||
: message.method === "info"
|
||||
? "info"
|
||||
: "log",
|
||||
text: message.text,
|
||||
args: message.args,
|
||||
});
|
||||
// Acknowledge receipt
|
||||
respond({ success: true });
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get collected console logs
|
||||
*/
|
||||
getLogs() {
|
||||
return this.logs;
|
||||
}
|
||||
/**
|
||||
* Get completion status
|
||||
*/
|
||||
isCompleted() {
|
||||
return this.completed;
|
||||
}
|
||||
/**
|
||||
* Get completion error if any
|
||||
*/
|
||||
getCompletionError() {
|
||||
return this.completionError;
|
||||
}
|
||||
/**
|
||||
* Reset state for reuse
|
||||
*/
|
||||
reset() {
|
||||
this.logs = [];
|
||||
this.completionError = null;
|
||||
this.completed = false;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=ConsoleRuntimeProvider.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ConsoleRuntimeProvider.js","sourceRoot":"","sources":["../../../src/components/sandbox/ConsoleRuntimeProvider.ts"],"names":[],"mappings":"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"}
|
||||
30
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/FileDownloadRuntimeProvider.d.ts
vendored
Normal file
30
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/FileDownloadRuntimeProvider.d.ts
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import type { SandboxRuntimeProvider } from "./SandboxRuntimeProvider.js";
|
||||
export interface DownloadableFile {
|
||||
fileName: string;
|
||||
content: string | Uint8Array;
|
||||
mimeType: string;
|
||||
}
|
||||
/**
|
||||
* File Download Runtime Provider
|
||||
*
|
||||
* Provides returnDownloadableFile() for creating user downloads.
|
||||
* Files returned this way are NOT accessible to the LLM later (one-time download).
|
||||
* Works both online (sends to extension) and offline (triggers browser download directly).
|
||||
* Collects files for retrieval by caller.
|
||||
*/
|
||||
export declare class FileDownloadRuntimeProvider implements SandboxRuntimeProvider {
|
||||
private files;
|
||||
getData(): Record<string, any>;
|
||||
getRuntime(): (sandboxId: string) => void;
|
||||
handleMessage(message: any, respond: (response: any) => void): Promise<void>;
|
||||
/**
|
||||
* Get collected files
|
||||
*/
|
||||
getFiles(): DownloadableFile[];
|
||||
/**
|
||||
* Reset state for reuse
|
||||
*/
|
||||
reset(): void;
|
||||
getDescription(): string;
|
||||
}
|
||||
//# sourceMappingURL=FileDownloadRuntimeProvider.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"FileDownloadRuntimeProvider.d.ts","sourceRoot":"","sources":["../../../src/components/sandbox/FileDownloadRuntimeProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,qBAAa,2BAA4B,YAAW,sBAAsB;IACzE,OAAO,CAAC,KAAK,CAA0B;IAEvC,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAK9B,UAAU,IAAI,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI;IAuDnC,aAAa,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAalF;;OAEG;IACH,QAAQ,IAAI,gBAAgB,EAAE;IAI9B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb,cAAc,IAAI,MAAM;CAGxB"}
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* File Download Runtime Provider
|
||||
*
|
||||
* Provides returnDownloadableFile() for creating user downloads.
|
||||
* Files returned this way are NOT accessible to the LLM later (one-time download).
|
||||
* Works both online (sends to extension) and offline (triggers browser download directly).
|
||||
* Collects files for retrieval by caller.
|
||||
*/
|
||||
export class FileDownloadRuntimeProvider {
|
||||
constructor() {
|
||||
this.files = [];
|
||||
}
|
||||
getData() {
|
||||
// No data needed
|
||||
return {};
|
||||
}
|
||||
getRuntime() {
|
||||
return (_sandboxId) => {
|
||||
window.returnDownloadableFile = async (fileName, content, mimeType) => {
|
||||
let finalContent, finalMimeType;
|
||||
if (content instanceof Blob) {
|
||||
const arrayBuffer = await content.arrayBuffer();
|
||||
finalContent = new Uint8Array(arrayBuffer);
|
||||
finalMimeType = mimeType || content.type || "application/octet-stream";
|
||||
if (!mimeType && !content.type) {
|
||||
throw new Error("returnDownloadableFile: MIME type is required for Blob content. Please provide a mimeType parameter (e.g., 'image/png').");
|
||||
}
|
||||
}
|
||||
else if (content instanceof Uint8Array) {
|
||||
finalContent = content;
|
||||
if (!mimeType) {
|
||||
throw new Error("returnDownloadableFile: MIME type is required for Uint8Array content. Please provide a mimeType parameter (e.g., 'image/png').");
|
||||
}
|
||||
finalMimeType = mimeType;
|
||||
}
|
||||
else if (typeof content === "string") {
|
||||
finalContent = content;
|
||||
finalMimeType = mimeType || "text/plain";
|
||||
}
|
||||
else {
|
||||
finalContent = JSON.stringify(content, null, 2);
|
||||
finalMimeType = mimeType || "application/json";
|
||||
}
|
||||
// Send to extension if in extension context (online mode)
|
||||
if (window.sendRuntimeMessage) {
|
||||
const response = await window.sendRuntimeMessage({
|
||||
type: "file-returned",
|
||||
fileName,
|
||||
content: finalContent,
|
||||
mimeType: finalMimeType,
|
||||
});
|
||||
if (response.error)
|
||||
throw new Error(response.error);
|
||||
}
|
||||
else {
|
||||
// Offline mode: trigger browser download directly
|
||||
const blob = new Blob([finalContent instanceof Uint8Array ? finalContent : finalContent], {
|
||||
type: finalMimeType,
|
||||
});
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = fileName;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
async handleMessage(message, respond) {
|
||||
if (message.type === "file-returned") {
|
||||
// Collect file for caller
|
||||
this.files.push({
|
||||
fileName: message.fileName,
|
||||
content: message.content,
|
||||
mimeType: message.mimeType,
|
||||
});
|
||||
respond({ success: true });
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get collected files
|
||||
*/
|
||||
getFiles() {
|
||||
return this.files;
|
||||
}
|
||||
/**
|
||||
* Reset state for reuse
|
||||
*/
|
||||
reset() {
|
||||
this.files = [];
|
||||
}
|
||||
getDescription() {
|
||||
return "returnDownloadableFile(filename, content, mimeType?) - Create downloadable file for user (one-time download, not accessible later)";
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=FileDownloadRuntimeProvider.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"FileDownloadRuntimeProvider.js","sourceRoot":"","sources":["../../../src/components/sandbox/FileDownloadRuntimeProvider.ts"],"names":[],"mappings":"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"}
|
||||
19
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/RuntimeMessageBridge.d.ts
vendored
Normal file
19
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/RuntimeMessageBridge.d.ts
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Generates sendRuntimeMessage() function for injection into execution contexts.
|
||||
* Provides unified messaging API that works in both sandbox iframe and user script contexts.
|
||||
*/
|
||||
export type MessageType = "request-response" | "fire-and-forget";
|
||||
export interface RuntimeMessageBridgeOptions {
|
||||
context: "sandbox-iframe" | "user-script";
|
||||
sandboxId: string;
|
||||
}
|
||||
export declare class RuntimeMessageBridge {
|
||||
/**
|
||||
* Generate sendRuntimeMessage() function as injectable string.
|
||||
* Returns the function source code to be injected into target context.
|
||||
*/
|
||||
static generateBridgeCode(options: RuntimeMessageBridgeOptions): string;
|
||||
private static generateSandboxBridge;
|
||||
private static generateUserScriptBridge;
|
||||
}
|
||||
//# sourceMappingURL=RuntimeMessageBridge.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"RuntimeMessageBridge.d.ts","sourceRoot":"","sources":["../../../src/components/sandbox/RuntimeMessageBridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,WAAW,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;AAEjE,MAAM,WAAW,2BAA2B;IAC3C,OAAO,EAAE,gBAAgB,GAAG,aAAa,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;CAClB;AAGD,qBAAa,oBAAoB;IAChC;;;OAGG;IACH,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,2BAA2B,GAAG,MAAM;IAQvE,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAwCpC,OAAO,CAAC,MAAM,CAAC,wBAAwB;CAevC"}
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Generates sendRuntimeMessage() function for injection into execution contexts.
|
||||
* Provides unified messaging API that works in both sandbox iframe and user script contexts.
|
||||
*/
|
||||
// biome-ignore lint/complexity/noStaticOnlyClass: fine
|
||||
export class RuntimeMessageBridge {
|
||||
/**
|
||||
* Generate sendRuntimeMessage() function as injectable string.
|
||||
* Returns the function source code to be injected into target context.
|
||||
*/
|
||||
static generateBridgeCode(options) {
|
||||
if (options.context === "sandbox-iframe") {
|
||||
return RuntimeMessageBridge.generateSandboxBridge(options.sandboxId);
|
||||
}
|
||||
else {
|
||||
return RuntimeMessageBridge.generateUserScriptBridge(options.sandboxId);
|
||||
}
|
||||
}
|
||||
static generateSandboxBridge(sandboxId) {
|
||||
// Returns stringified function that uses window.parent.postMessage
|
||||
return `
|
||||
window.__completionCallbacks = [];
|
||||
window.sendRuntimeMessage = async (message) => {
|
||||
const messageId = 'msg_' + Date.now() + '_' + Math.random().toString(36).substring(2, 9);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const handler = (e) => {
|
||||
if (e.data.type === 'runtime-response' && e.data.messageId === messageId) {
|
||||
window.removeEventListener('message', handler);
|
||||
if (e.data.success) {
|
||||
resolve(e.data);
|
||||
} else {
|
||||
reject(new Error(e.data.error || 'Operation failed'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('message', handler);
|
||||
|
||||
window.parent.postMessage({
|
||||
...message,
|
||||
sandboxId: ${JSON.stringify(sandboxId)},
|
||||
messageId: messageId
|
||||
}, '*');
|
||||
|
||||
// Timeout after 30s
|
||||
setTimeout(() => {
|
||||
window.removeEventListener('message', handler);
|
||||
reject(new Error('Runtime message timeout'));
|
||||
}, 30000);
|
||||
});
|
||||
};
|
||||
window.onCompleted = (callback) => {
|
||||
window.__completionCallbacks.push(callback);
|
||||
};
|
||||
`.trim();
|
||||
}
|
||||
static generateUserScriptBridge(sandboxId) {
|
||||
// Returns stringified function that uses chrome.runtime.sendMessage
|
||||
return `
|
||||
window.__completionCallbacks = [];
|
||||
window.sendRuntimeMessage = async (message) => {
|
||||
return await chrome.runtime.sendMessage({
|
||||
...message,
|
||||
sandboxId: ${JSON.stringify(sandboxId)}
|
||||
});
|
||||
};
|
||||
window.onCompleted = (callback) => {
|
||||
window.__completionCallbacks.push(callback);
|
||||
};
|
||||
`.trim();
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=RuntimeMessageBridge.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"RuntimeMessageBridge.js","sourceRoot":"","sources":["../../../src/components/sandbox/RuntimeMessageBridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,uDAAuD;AACvD,MAAM,OAAO,oBAAoB;IAChC;;;OAGG;IACH,MAAM,CAAC,kBAAkB,CAAC,OAAoC;QAC7D,IAAI,OAAO,CAAC,OAAO,KAAK,gBAAgB,EAAE,CAAC;YAC1C,OAAO,oBAAoB,CAAC,qBAAqB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACP,OAAO,oBAAoB,CAAC,wBAAwB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACzE,CAAC;IACF,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAAC,SAAiB;QACrD,mEAAmE;QACnE,OAAO;;;;;;;;;;;;;;;;;;;;;yBAqBgB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;;;;;;;;;;;;;;CAcjD,CAAC,IAAI,EAAE,CAAC;IACR,CAAC;IAEO,MAAM,CAAC,wBAAwB,CAAC,SAAiB;QACxD,oEAAoE;QACpE,OAAO;;;;;qBAKY,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;;;;;;CAM7C,CAAC,IAAI,EAAE,CAAC;IACR,CAAC;CACD"}
|
||||
65
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/RuntimeMessageRouter.d.ts
vendored
Normal file
65
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/RuntimeMessageRouter.d.ts
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
import type { SandboxRuntimeProvider } from "./SandboxRuntimeProvider.js";
|
||||
/**
|
||||
* Message consumer interface - components that want to receive messages from sandboxes
|
||||
*/
|
||||
export interface MessageConsumer {
|
||||
/**
|
||||
* Handle a message from a sandbox.
|
||||
* All consumers receive all messages - decide internally what to handle.
|
||||
*/
|
||||
handleMessage(message: any): Promise<void>;
|
||||
}
|
||||
/**
|
||||
* Centralized message router for all runtime communication.
|
||||
*
|
||||
* This singleton replaces all individual window.addEventListener("message") calls
|
||||
* with a single global listener that routes messages to the appropriate handlers.
|
||||
* Also handles user script messages from chrome.runtime.onUserScriptMessage.
|
||||
*
|
||||
* Benefits:
|
||||
* - Single global listener instead of multiple independent listeners
|
||||
* - Automatic cleanup when sandboxes are destroyed
|
||||
* - Support for bidirectional communication (providers) and broadcasting (consumers)
|
||||
* - Works with both sandbox iframes and user scripts
|
||||
* - Clear lifecycle management
|
||||
*/
|
||||
export declare class RuntimeMessageRouter {
|
||||
private sandboxes;
|
||||
private messageListener;
|
||||
private userScriptMessageListener;
|
||||
/**
|
||||
* Register a new sandbox with its runtime providers.
|
||||
* Call this BEFORE creating the iframe (for sandbox contexts) or executing user script.
|
||||
*/
|
||||
registerSandbox(sandboxId: string, providers: SandboxRuntimeProvider[], consumers: MessageConsumer[]): void;
|
||||
/**
|
||||
* Update the iframe reference for a sandbox.
|
||||
* Call this AFTER creating the iframe.
|
||||
* This is needed so providers can send responses back to the sandbox.
|
||||
*/
|
||||
setSandboxIframe(sandboxId: string, iframe: HTMLIFrameElement): void;
|
||||
/**
|
||||
* Unregister a sandbox and remove all its consumers.
|
||||
* Call this when the sandbox is destroyed.
|
||||
*/
|
||||
unregisterSandbox(sandboxId: string): void;
|
||||
/**
|
||||
* Add a message consumer for a sandbox.
|
||||
* Consumers receive broadcast messages (console, execution-complete, etc.)
|
||||
*/
|
||||
addConsumer(sandboxId: string, consumer: MessageConsumer): void;
|
||||
/**
|
||||
* Remove a message consumer from a sandbox.
|
||||
*/
|
||||
removeConsumer(sandboxId: string, consumer: MessageConsumer): void;
|
||||
/**
|
||||
* Setup the global message listeners (called automatically)
|
||||
*/
|
||||
private setupListener;
|
||||
}
|
||||
/**
|
||||
* Global singleton instance.
|
||||
* Import this from wherever you need to interact with the message router.
|
||||
*/
|
||||
export declare const RUNTIME_MESSAGE_ROUTER: RuntimeMessageRouter;
|
||||
//# sourceMappingURL=RuntimeMessageRouter.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"RuntimeMessageRouter.d.ts","sourceRoot":"","sources":["../../../src/components/sandbox/RuntimeMessageRouter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAK1E;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAYD;;;;;;;;;;;;;GAaG;AACH,qBAAa,oBAAoB;IAChC,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,eAAe,CAA4C;IACnE,OAAO,CAAC,yBAAyB,CAElB;IAEf;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,sBAAsB,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,IAAI;IAY3G;;;;OAIG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAOpE;;;OAGG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAmB1C;;;OAGG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI;IAO/D;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI;IAOlE;;OAEG;IACH,OAAO,CAAC,aAAa;CAuFrB;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,sBAA6B,CAAC"}
|
||||
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* Centralized message router for all runtime communication.
|
||||
*
|
||||
* This singleton replaces all individual window.addEventListener("message") calls
|
||||
* with a single global listener that routes messages to the appropriate handlers.
|
||||
* Also handles user script messages from chrome.runtime.onUserScriptMessage.
|
||||
*
|
||||
* Benefits:
|
||||
* - Single global listener instead of multiple independent listeners
|
||||
* - Automatic cleanup when sandboxes are destroyed
|
||||
* - Support for bidirectional communication (providers) and broadcasting (consumers)
|
||||
* - Works with both sandbox iframes and user scripts
|
||||
* - Clear lifecycle management
|
||||
*/
|
||||
export class RuntimeMessageRouter {
|
||||
constructor() {
|
||||
this.sandboxes = new Map();
|
||||
this.messageListener = null;
|
||||
this.userScriptMessageListener = null;
|
||||
}
|
||||
/**
|
||||
* Register a new sandbox with its runtime providers.
|
||||
* Call this BEFORE creating the iframe (for sandbox contexts) or executing user script.
|
||||
*/
|
||||
registerSandbox(sandboxId, providers, consumers) {
|
||||
this.sandboxes.set(sandboxId, {
|
||||
sandboxId,
|
||||
iframe: null, // Will be set via setSandboxIframe() for sandbox contexts
|
||||
providers,
|
||||
consumers: new Set(consumers),
|
||||
});
|
||||
// Setup global listener if not already done
|
||||
this.setupListener();
|
||||
}
|
||||
/**
|
||||
* Update the iframe reference for a sandbox.
|
||||
* Call this AFTER creating the iframe.
|
||||
* This is needed so providers can send responses back to the sandbox.
|
||||
*/
|
||||
setSandboxIframe(sandboxId, iframe) {
|
||||
const context = this.sandboxes.get(sandboxId);
|
||||
if (context) {
|
||||
context.iframe = iframe;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Unregister a sandbox and remove all its consumers.
|
||||
* Call this when the sandbox is destroyed.
|
||||
*/
|
||||
unregisterSandbox(sandboxId) {
|
||||
this.sandboxes.delete(sandboxId);
|
||||
// If no more sandboxes, remove global listeners
|
||||
if (this.sandboxes.size === 0) {
|
||||
// Remove iframe listener
|
||||
if (this.messageListener) {
|
||||
window.removeEventListener("message", this.messageListener);
|
||||
this.messageListener = null;
|
||||
}
|
||||
// Remove user script listener
|
||||
if (this.userScriptMessageListener && typeof chrome !== "undefined" && chrome.runtime?.onUserScriptMessage) {
|
||||
chrome.runtime.onUserScriptMessage.removeListener(this.userScriptMessageListener);
|
||||
this.userScriptMessageListener = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Add a message consumer for a sandbox.
|
||||
* Consumers receive broadcast messages (console, execution-complete, etc.)
|
||||
*/
|
||||
addConsumer(sandboxId, consumer) {
|
||||
const context = this.sandboxes.get(sandboxId);
|
||||
if (context) {
|
||||
context.consumers.add(consumer);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Remove a message consumer from a sandbox.
|
||||
*/
|
||||
removeConsumer(sandboxId, consumer) {
|
||||
const context = this.sandboxes.get(sandboxId);
|
||||
if (context) {
|
||||
context.consumers.delete(consumer);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Setup the global message listeners (called automatically)
|
||||
*/
|
||||
setupListener() {
|
||||
// Setup sandbox iframe listener
|
||||
if (!this.messageListener) {
|
||||
this.messageListener = async (e) => {
|
||||
const { sandboxId, messageId } = e.data;
|
||||
if (!sandboxId)
|
||||
return;
|
||||
const context = this.sandboxes.get(sandboxId);
|
||||
if (!context) {
|
||||
return;
|
||||
}
|
||||
// Create respond() function for bidirectional communication
|
||||
const respond = (response) => {
|
||||
context.iframe?.contentWindow?.postMessage({
|
||||
type: "runtime-response",
|
||||
messageId,
|
||||
sandboxId,
|
||||
...response,
|
||||
}, "*");
|
||||
};
|
||||
// 1. Try provider handlers first (for bidirectional comm)
|
||||
for (const provider of context.providers) {
|
||||
if (provider.handleMessage) {
|
||||
await provider.handleMessage(e.data, respond);
|
||||
// Don't stop - let consumers also handle the message
|
||||
}
|
||||
}
|
||||
// 2. Broadcast to consumers (one-way messages or lifecycle events)
|
||||
for (const consumer of context.consumers) {
|
||||
await consumer.handleMessage(e.data);
|
||||
// Don't stop - let all consumers see the message
|
||||
}
|
||||
};
|
||||
window.addEventListener("message", this.messageListener);
|
||||
}
|
||||
// Setup user script message listener
|
||||
if (!this.userScriptMessageListener) {
|
||||
// Guard: check if we're in extension context
|
||||
if (typeof chrome === "undefined" || !chrome.runtime?.onUserScriptMessage) {
|
||||
return;
|
||||
}
|
||||
this.userScriptMessageListener = (message, _sender, sendResponse) => {
|
||||
const { sandboxId } = message;
|
||||
if (!sandboxId)
|
||||
return false;
|
||||
const context = this.sandboxes.get(sandboxId);
|
||||
if (!context)
|
||||
return false;
|
||||
const respond = (response) => {
|
||||
sendResponse({
|
||||
...response,
|
||||
sandboxId,
|
||||
});
|
||||
};
|
||||
// Route to providers (async)
|
||||
(async () => {
|
||||
// 1. Try provider handlers first (for bidirectional comm)
|
||||
for (const provider of context.providers) {
|
||||
if (provider.handleMessage) {
|
||||
await provider.handleMessage(message, respond);
|
||||
// Don't stop - let consumers also handle the message
|
||||
}
|
||||
}
|
||||
// 2. Broadcast to consumers (one-way messages or lifecycle events)
|
||||
for (const consumer of context.consumers) {
|
||||
await consumer.handleMessage(message);
|
||||
// Don't stop - let all consumers see the message
|
||||
}
|
||||
})();
|
||||
return true; // Indicates async response
|
||||
};
|
||||
chrome.runtime.onUserScriptMessage.addListener(this.userScriptMessageListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Global singleton instance.
|
||||
* Import this from wherever you need to interact with the message router.
|
||||
*/
|
||||
export const RUNTIME_MESSAGE_ROUTER = new RuntimeMessageRouter();
|
||||
//# sourceMappingURL=RuntimeMessageRouter.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"RuntimeMessageRouter.js","sourceRoot":"","sources":["../../../src/components/sandbox/RuntimeMessageRouter.ts"],"names":[],"mappings":"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"}
|
||||
48
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/SandboxRuntimeProvider.d.ts
vendored
Normal file
48
apps/macos/Sources/Clawdis/Resources/WebChat/components/sandbox/SandboxRuntimeProvider.d.ts
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Interface for providing runtime capabilities to sandboxed iframes.
|
||||
* Each provider injects data and runtime functions into the sandbox context.
|
||||
*/
|
||||
export interface SandboxRuntimeProvider {
|
||||
/**
|
||||
* Returns data to inject into window scope.
|
||||
* Keys become window properties (e.g., { attachments: [...] } -> window.attachments)
|
||||
*/
|
||||
getData(): Record<string, any>;
|
||||
/**
|
||||
* Returns a runtime function that will be stringified and executed in the sandbox.
|
||||
* The function receives sandboxId and has access to data from getData() via window.
|
||||
*
|
||||
* IMPORTANT: This function will be converted to string via .toString() and injected
|
||||
* into the sandbox, so it cannot reference external variables or imports.
|
||||
*/
|
||||
getRuntime(): (sandboxId: string) => void;
|
||||
/**
|
||||
* Optional message handler for bidirectional communication.
|
||||
* All providers receive all messages - decide internally what to handle.
|
||||
*
|
||||
* @param message - The message from the sandbox
|
||||
* @param respond - Function to send a response back to the sandbox
|
||||
*/
|
||||
handleMessage?(message: any, respond: (response: any) => void): Promise<void>;
|
||||
/**
|
||||
* Optional documentation describing what globals/functions this provider injects.
|
||||
* This will be appended to tool descriptions dynamically so the LLM knows what's available.
|
||||
*/
|
||||
getDescription(): string;
|
||||
/**
|
||||
* Optional lifecycle callback invoked when sandbox execution starts.
|
||||
* Providers can use this to track abort signals for cancellation of async operations.
|
||||
*
|
||||
* @param sandboxId - The unique identifier for this sandbox execution
|
||||
* @param signal - Optional AbortSignal that will be triggered if execution is cancelled
|
||||
*/
|
||||
onExecutionStart?(sandboxId: string, signal?: AbortSignal): void;
|
||||
/**
|
||||
* Optional lifecycle callback invoked when sandbox execution ends (success, error, or abort).
|
||||
* Providers can use this to clean up any resources associated with the sandbox.
|
||||
*
|
||||
* @param sandboxId - The unique identifier for this sandbox execution
|
||||
*/
|
||||
onExecutionEnd?(sandboxId: string): void;
|
||||
}
|
||||
//# sourceMappingURL=SandboxRuntimeProvider.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"SandboxRuntimeProvider.d.ts","sourceRoot":"","sources":["../../../src/components/sandbox/SandboxRuntimeProvider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACtC;;;OAGG;IACH,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE/B;;;;;;OAMG;IACH,UAAU,IAAI,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAE1C;;;;;;OAMG;IACH,aAAa,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9E;;;OAGG;IACH,cAAc,IAAI,MAAM,CAAC;IAEzB;;;;;;OAMG;IACH,gBAAgB,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAEjE;;;;;OAKG;IACH,cAAc,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC"}
|
||||
@@ -0,0 +1,2 @@
|
||||
export {};
|
||||
//# sourceMappingURL=SandboxRuntimeProvider.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"SandboxRuntimeProvider.js","sourceRoot":"","sources":["../../../src/components/sandbox/SandboxRuntimeProvider.ts"],"names":[],"mappings":""}
|
||||
Reference in New Issue
Block a user