Files
paseo/packages/plugin/src/contracts.ts
T
Mohamed Boudra 91024bc029 fix(plugins): install local plugins on packaged desktop
The plugin compiler spawned esbuild through app.asar, and the subprocess
imported the React client barrel. Point esbuild at the unpacked binary,
add a react-free @paseo/plugin/server entry, and pass a typed PluginTheme
so plugin UI follows the active theme on desktop and mobile.
2026-08-19 11:54:55 +02:00

183 lines
5.3 KiB
TypeScript

import type { ComponentType } from "react";
import type { PaseoApi } from "@getpaseo/client";
import type { ZodType, input as ZodInput, output as ZodOutput } from "zod";
import type { PluginRpcContract } from "./rpc.js";
export interface PluginTheme {
readonly colors: {
readonly surface0: string;
readonly foreground: string;
readonly foregroundMuted: string;
readonly accent: string;
readonly accentForeground: string;
readonly statusDanger: string;
};
}
export interface PluginHostProps {
theme: PluginTheme;
host: {
id: string;
label: string;
};
layout: {
compact: boolean;
platform: "ios" | "android" | "web";
};
}
export interface PluginSurfaceProps extends PluginHostProps {}
export interface PluginWorkspaceSnapshot {
readonly id: string;
readonly projectId: string;
readonly projectDisplayName: string;
readonly projectRootPath: string;
readonly directory: string;
readonly projectKind: "git" | "non_git" | "directory";
readonly kind: "directory" | "local_checkout" | "checkout" | "worktree";
readonly name: string;
readonly title: string | null;
readonly status: "needs_input" | "failed" | "running" | "attention" | "done";
readonly statusEnteredAt: string | null;
readonly archivingAt: string | null;
readonly diffStat: { readonly additions: number; readonly deletions: number } | null;
}
export interface PluginAgentSnapshot {
readonly id: string;
readonly workspaceId: string;
readonly provider: string;
readonly status: "initializing" | "idle" | "running" | "error" | "closed";
readonly createdAt: string;
readonly updatedAt: string;
readonly lastActivityAt: string;
readonly title: string | null;
readonly cwd: string;
readonly model: string | null;
readonly currentModeId: string | null;
readonly thinkingOptionId: string | null;
readonly requiresAttention: boolean;
readonly attentionReason: "finished" | "error" | "permission" | null;
readonly parentAgentId: string | null;
readonly labels: Readonly<Record<string, string>>;
}
interface PluginWorkspacePanelBase {
id: string;
title: string;
icon: string;
}
export interface PluginWorkspacePanelProps extends PluginHostProps {
context: "workspace";
workspaceId: string;
}
export interface PluginAgentPanelProps extends PluginHostProps {
context: "agent";
workspaceId: string;
agentId: string;
}
export type PluginWorkspacePanelContribution =
| (PluginWorkspacePanelBase & {
context: "workspace";
Component: ComponentType<PluginWorkspacePanelProps>;
})
| (PluginWorkspacePanelBase & {
context: "agent";
Component: ComponentType<PluginAgentPanelProps>;
});
export interface PluginSurfaceContribution {
id: string;
Component: ComponentType<PluginSurfaceProps>;
}
export interface PluginSidebarContribution {
id: string;
title: string;
icon: string;
surface: string;
}
export interface PluginAttachmentSourceContribution {
id: string;
title: string;
icon: string;
pickerTitle: string;
searchPlaceholder: string;
search: PluginRpcContract;
}
export interface PluginCommandCapabilities {
paseo: PaseoApi;
rpc<InputSchema extends ZodType, OutputSchema extends ZodType>(
contract: PluginRpcContract<InputSchema, OutputSchema>,
input: ZodInput<InputSchema>,
): Promise<ZodOutput<OutputSchema>>;
openSurface(id: string): void;
}
export interface PluginGlobalCommandContext extends PluginCommandCapabilities {
context: "global";
}
export interface PluginWorkspaceCommandContext extends PluginCommandCapabilities {
context: "workspace";
workspace: PluginWorkspaceSnapshot;
openPanel(id: string): void;
}
export interface PluginAgentCommandContext extends PluginCommandCapabilities {
context: "agent";
workspace: PluginWorkspaceSnapshot;
agent: PluginAgentSnapshot;
openPanel(id: string): void;
}
interface PluginCommandCenterItemBase {
id: string;
title: string;
icon: string;
keywords?: readonly string[];
}
export type PluginCommandCenterItemContribution =
| (PluginCommandCenterItemBase & {
context: "global";
onSelect(context: PluginGlobalCommandContext): void | Promise<void>;
})
| (PluginCommandCenterItemBase & {
context: "workspace";
onSelect(context: PluginWorkspaceCommandContext): void | Promise<void>;
})
| (PluginCommandCenterItemBase & {
context: "agent";
onSelect(context: PluginAgentCommandContext): void | Promise<void>;
});
export interface PluginHandlerContext {
paseo: PaseoApi;
}
export interface PluginContext {
handle<InputSchema extends ZodType, OutputSchema extends ZodType>(
contract: PluginRpcContract<InputSchema, OutputSchema>,
handler: (
input: ZodOutput<InputSchema>,
context: PluginHandlerContext,
) => ZodInput<OutputSchema> | Promise<ZodInput<OutputSchema>>,
): void;
addSurface(id: string, Component: ComponentType<PluginSurfaceProps>): void;
addSidebarItem(contribution: PluginSidebarContribution): void;
addWorkspacePanel(contribution: PluginWorkspacePanelContribution): void;
addCommandCenterItem(contribution: PluginCommandCenterItemContribution): void;
addAttachmentSource(contribution: PluginAttachmentSourceContribution): void;
}
export type PluginCleanup = () => void | Promise<void>;
export type PluginContribution = (plugin: PluginContext) => PluginCleanup;