* feat(plugins): add workspace panels and command center contributions Give local plugins contextual UI entry points without making the daemon interpret client placement or callbacks. Panels receive stable IDs and read cached client state through required selectors with shallow equality, avoiding unrelated guest rerenders and context-discovery RPCs. * fix(plugins): align shared client state ownership Workspace panels and Command Center callbacks consume the same frozen client snapshots, so their adapter belongs to the plugin boundary rather than either contribution surface. Refresh the Nix dependency hash for the selector-store dependency added by this feature.
172 lines
5.0 KiB
TypeScript
172 lines
5.0 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 PluginHostProps {
|
|
theme: Record<string, unknown>;
|
|
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;
|