Files
paseo/packages/app/src/plugins/host-navigation-model.ts
T
Mohamed Boudra c7db3c5a8c Let plugins open external links and workspace browsers (#4972)
* feat(plugins): open external links and workspace browsers

* fix(plugins): refuse invalid links and unavailable browser workspaces

* docs(plugins): clarify external links and browser navigation
2026-09-16 23:25:17 +02:00

43 lines
1.8 KiB
TypeScript

import type { PluginSurfaceProps } from "@getpaseo/plugin/client";
import type { NavigateToWorkspaceInput } from "@/stores/navigation-active-workspace-store";
import { isHttpUrl } from "@/utils/http-url";
interface HostNavigationOwner {
browserAvailable: boolean;
openAgent(input: { serverId: string; agentId: string }): void;
openWorkspace(input: NavigateToWorkspaceInput): void;
resolveWorkspace(input: { serverId: string; workspaceId: string }): string | null;
createBrowser(input: { initialUrl: string }): { browserId: string };
}
export function createPluginHostNavigation(
serverId: string,
owner: HostNavigationOwner,
): NonNullable<PluginSurfaceProps["navigation"]> {
return {
openAgent: ({ agentId, serverId: targetServerId }) =>
owner.openAgent({ serverId: targetServerId ?? serverId, agentId }),
openWorkspace: ({ workspaceId, serverId: targetServerId }) =>
owner.openWorkspace({ serverId: targetServerId ?? serverId, workspaceId }),
openBrowser: owner.browserAvailable
? ({ url, workspaceId, serverId: targetServerId }) => {
if (!isHttpUrl(url)) throw new Error("Only absolute HTTP(S) URLs are supported.");
if (!workspaceId.trim()) throw new Error("workspaceId is required.");
const destinationServerId = targetServerId ?? serverId;
const destinationWorkspaceId = owner.resolveWorkspace({
serverId: destinationServerId,
workspaceId,
});
if (!destinationWorkspaceId)
throw new Error("Workspace is unavailable on the requested host.");
const { browserId } = owner.createBrowser({ initialUrl: url });
owner.openWorkspace({
serverId: destinationServerId,
workspaceId: destinationWorkspaceId,
target: { kind: "browser", browserId },
});
}
: undefined,
};
}