Z ZPI 文档 v0.3.8
介绍页

源码

packages/desktop/src/shared/bridge.ts

typescript642 行查看原文
import type { Model, ModelCompat, ModelDiscoveryResult, ProviderApi, ProviderPresetId } from "@zpi-dev/ai";
import type { SaveSubagentInput, SubagentCatalog } from "@zpi-dev/builtin-plugins/collaboration/types";
import type { MemorySettings, MemoryStatus } from "@zpi-dev/builtin-plugins/memory/types";
import type { CombinedSelection } from "@zpi-dev/builtin-plugins/types";
import type { Attachment, DiscoveredSkill, SkillList } from "@zpi-dev/coding-agent";
import type {
  DesktopEventEnvelope,
  FileAction,
  QueuedInput,
  RunStatus,
  SessionControls,
  SessionMentionSuggestion,
  SessionView,
  WorktreeInfo,
} from "@zpi-dev/ui";
import type { FileLocation } from "@zpi-dev/ui/links";
import type { CommandImportDiscovery, CommandImportRequest, CommandImportResult } from "./command-import.ts";
import type {
  CustomCommand,
  CustomCommandDelete,
  CustomCommandInput,
  CustomCommandSetEnabled,
  CustomCommandsList,
  CustomCommandUpdate,
} from "./custom-commands.ts";
import type { EditorInfo } from "./editors.ts";
import type { HooksCatalog, HookTarget, SaveHookInput } from "./hooks.ts";
import type { ShortcutCommand, ShortcutSettings } from "./shortcuts.ts";
import type { WorkspaceFileSearchInput, WorkspaceFileSearchResult } from "./workspace-files.ts";

export type { CombinedSelection, ModelSelection, ReasoningPreset } from "@zpi-dev/builtin-plugins/types";

export type { SessionControls } from "@zpi-dev/ui";

export type ErrorCode = "configuration" | "busy" | "not_found" | "provider" | "storage" | "invalid_input";
export type Result<T> = { ok: true; value: T } | { ok: false; error: { code: ErrorCode; message: string } };
export interface ProjectRecord {
  id: string;
  name: string;
  path: string;
  updatedAt: number;
  hidden?: boolean;
}
export interface TaskSearchChange {
  path: string;
  added: number;
  removed: number;
  lastTurnIndex: number;
  writeCount: number;
}
export interface TaskSearchResult extends SessionRecord {
  snippets: import("./task-search.ts").TaskSearchSnippet[];
}
export interface SessionRecord {
  parentSessionId?: string;
  newWorktree?: boolean;
  worktreeBaseRef?: string;
  worktree?: WorktreeInfo;
  draft?: boolean;
  id: string;
  projectId: string | null;
  cwd?: string;
  pinnedAt?: number | null;
  archivedAt?: number | null;
  unreadAt?: number;
  diagnostic?: string;
  title: string;
  status?: RunStatus;
  /** Runtime evidence supplied by SessionHost, never restored from persisted status. */
  running?: boolean;
  pendingQuestion?: Pick<import("@zpi-dev/ui").UserQuestionRequest, "id" | "autoResolution"> | null;
  activitySeq?: number;
  createdAt: number;
  updatedAt: number;
}
export interface GitEnvironment {
  branch: string;
  head: string;
  currentRef: string | null;
  branches: { ref: string; name: string; remote: boolean }[];
}
export interface ModelSettings {
  enabled?: boolean;
  useRecommendedConfig?: boolean;
  metadataSource?: "remote" | "catalog" | "defaults";
  id: string;
  name?: string;
  input?: ("text" | "image" | "video" | "pdf")[];
  reasoning?: boolean;
  contextWindow?: number;
  maxTokens?: number;
  compat?: ModelCompat;
  thinkingLevelMap?: Model["thinkingLevelMap"];
  reasoningConfig?: Model["reasoningConfig"];
  defaultThinkingLevel?: Model["defaultThinkingLevel"];
  availability?: "listed" | "unverified";
  samplingParams?: Model["samplingParams"];
}
export interface ProviderInput {
  api?: ProviderApi;
  enabled?: boolean;
  preset?: ProviderPresetId;
  id?: string;
  name: string;
  baseUrl: string;
  models: ModelSettings[];
  apiKey?: string;
}
export interface ProviderRecord extends Omit<ProviderInput, "apiKey" | "id"> {
  id: string;
  hasApiKey: boolean;
  chatgptAccount?: { label: string; connected: boolean };
}
export interface InterfacePreferences {
  codePreview?: import("@zpi-dev/ui/code-preview").CodePreviewSettings;
  theme: "system" | "light" | "dark";
  fontSize: number;
  showContextUsage: boolean;
  showModelPerformance: boolean;
  showSendButton: boolean;
  notificationEnabled: boolean;
  notificationSoundEnabled: boolean;
  sidebarCollapsed: boolean;
  sidebarWidth: number;
  collapsedProjectIds: string[];
  projectsCollapsed: boolean;
  tasksCollapsed: boolean;
}
export interface WebSearchSettingsInput {
  provider: "deepseek";
  enabled?: boolean;
  /** Omit to retain the saved key; an empty string removes it. */
  apiKey?: string;
}
export interface PublicSettings {
  webSearch: {
    provider: "deepseek";
    enabled: boolean;
    hasApiKey: boolean;
    apiKeyLength: number;
    credentialsPersisted: boolean;
    credentialsLocked: boolean;
  };
  shortcuts: ShortcutSettings;
  plugins: typeof import("@zpi-dev/builtin-plugins").defaultPluginSettings;
  providers: ProviderRecord[];
  lastSelection: CombinedSelection | null;
  interface: InterfacePreferences;
  credentialsPersisted: boolean;
  disabledSkillPaths: string[];
}
export interface SessionSnapshot {
  session: SessionRecord;
  view: SessionView;
  seq: number;
  controls: SessionControls;
  historyCursor?: number | null;
}
export interface RunInput {
  /** Internal plugin delivery; renderer IPC does not accept this field. */
  subagentNotification?: import("@zpi-dev/builtin-plugins/types").SubagentNotification;
  sessionId: string;
  text: string;
  fileReferences?: string[];
  attachments?: string[];
}
export type EditUserInput = Omit<RunInput, "sessionId"> & { workspaceMode?: "preserve" | "rewind" };
export type EditUserResult = SessionSnapshot | { conflicts: import("@zpi-dev/ui").FileRewindConflict[] };
export interface WorkspaceInfo {
  home: string;
  cwd: string;
  projectName: string;
  projectId: string | null;
}
export interface PromptPreview {
  cwd: string;
  projectName: string;
  basePrompt: string;
  customInstructions: string;
  prompt: string;
}
export interface DiffItem {
  id: string;
  path: string;
  oldPath?: string;
  status: string;
  area: string;
  patch?: string;
  patchAvailable?: boolean;
  reason?: string;
  snapshotUnavailable?: boolean;
  failed?: boolean;
  added?: number;
  removed?: number;
}
export interface ToolInfo {
  name: string;
  description: string;
  parameters: unknown;
  promptSnippet?: string;
  promptGuidelines?: string[];
  enabled: boolean;
}
export interface SkillSettings {
  skills: DiscoveredSkill[];
  diagnostics: { path: string; message: string }[];
  directories: string[];
}
export interface TextDraft {
  selections?: import("@zpi-dev/ui").ConversationSelection[];
  text: string;
  fileReferences: string[];
  selection: [number, number];
  revision: number;
}
export type FilePreview = { location?: FileLocation } & (
  | { path: string; kind: "text"; text: string; truncated: boolean }
  | {
      path: string;
      kind: "image" | "media" | "xlsx" | "docx" | "doc" | "pdf" | "pptx";
      bytes: Uint8Array;
      totalBytes?: number;
      mime?: string;
    }
  | { path: string; kind: "unsupported" }
  | { path: string; kind: "directory" }
);
export interface TerminalProfileTheme {
  selectionBackground?: string;
  selectionInactiveBackground?: string;
  black?: string;
  red?: string;
  green?: string;
  yellow?: string;
  blue?: string;
  magenta?: string;
  cyan?: string;
  white?: string;
  brightBlack?: string;
  brightRed?: string;
  brightGreen?: string;
  brightYellow?: string;
  brightBlue?: string;
  brightMagenta?: string;
  brightCyan?: string;
  brightWhite?: string;
}
export interface TerminalProfile {
  fontFamily?: string;
  fontSize?: number;
  theme?: TerminalProfileTheme;
}
export interface BrowserState {
  id: string;
  url: string;
  title: string;
  loading: boolean;
  back: boolean;
  forward: boolean;
  error?: string;
}
export type PaneEvent =
  | { type: "terminal"; id: string; data: string; exited?: boolean }
  | { type: "browser"; state: BrowserState };
export interface DesktopBridge {
  setSessionUnread(id: string): Promise<Result<void>>;
  getTaskGroups(): Promise<Result<import("./task-groups.ts").TaskGroupState>>;
  updateTaskGroups(
    command: Exclude<import("./task-groups.ts").TaskGroupCommand, { type: "create" }> | { type: "create" },
  ): Promise<Result<import("./task-groups.ts").TaskGroupState>>;
  listSubagents(sessionId: string | null): Promise<Result<SubagentCatalog>>;
  saveSubagent(input: SaveSubagentInput): Promise<Result<SubagentCatalog>>;
  deleteSubagent(id: string, sessionId: string | null): Promise<Result<SubagentCatalog>>;
  setSubagentEnabled(
    id: string,
    enabled: boolean,
    sessionId: string | null,
  ): Promise<Result<SubagentCatalog>>;
  stopSubagent(parentSessionId: string, agentId: string): Promise<Result<void>>;
  stopBackgroundTask(sessionId: string, taskId: string): Promise<Result<void>>;
  readBackgroundTask(
    sessionId: string,
    taskId: string,
  ): Promise<Result<import("@zpi-dev/ui").BackgroundTaskOutput>>;
  setPluginEnabled(id: string, enabled: boolean): Promise<Result<PublicSettings>>;
  getLocalPlugins(): Promise<Result<import("@zpi-dev/coding-agent").PluginMetadata[]>>;
  getHooks(projectId: string | null): Promise<Result<HooksCatalog>>;
  saveHook(input: SaveHookInput): Promise<Result<HooksCatalog>>;
  setHookEnabled(target: HookTarget, enabled: boolean): Promise<Result<HooksCatalog>>;
  deleteHook(target: HookTarget): Promise<Result<HooksCatalog>>;
  importLocalPlugin(): Promise<Result<PublicSettings>>;
  setPluginOptions(id: string, options: import("@zpi-dev/ai").JsonObject): Promise<Result<PublicSettings>>;
  snoozeQuestion(sessionId: string, requestId: string): Promise<Result<void>>;
  respondToQuestion(
    sessionId: string,
    requestId: string,
    response: import("@zpi-dev/ui").UserQuestionResponse,
  ): Promise<Result<void>>;
  closeSideChat(sessionId: string): Promise<Result<void>>;
  createSideChat(sessionId: string): Promise<Result<SessionRecord>>;
  getGitEnvironment(sessionId: string): Promise<Result<GitEnvironment | null>>;
  setNewWorktree(sessionId: string, enabled: boolean, baseRef?: string): Promise<Result<SessionRecord>>;
  logError(error: { source: string; message: string; stack?: string }): void;
  readonly platform: string;
  readonly workspacePanelRadius: number;
  onBeforeQuit(listener: () => Promise<void>): () => void;
  onTaskNotificationClick(listener: (sessionId: string) => void): () => void;
  onTaskNotificationSound(listener: () => void): () => void;
  archiveSession(id: string): Promise<Result<void>>;
  listArchivedSessions(): Promise<Result<(SessionRecord & { projectName: string })[]>>;
  restoreSession(id: string): Promise<Result<SessionRecord>>;
  openDirectory(path: string): Promise<Result<void>>;
  createTerminal(
    sessionId: string,
  ): Promise<Result<{ id: string; shell: string; profile?: TerminalProfile }>>;
  terminalInput(id: string, data: string): Promise<Result<void>>;
  resizeTerminal(id: string, cols: number, rows: number): Promise<Result<void>>;
  closeTerminal(id: string): Promise<Result<void>>;
  createBrowser(url: string): Promise<Result<BrowserState>>;
  browserAction(
    id: string,
    action: "navigate" | "back" | "forward" | "reload" | "stop",
    url?: string,
  ): Promise<Result<void>>;
  browserGuest(id: string, webContentsId: number, visible: boolean): Promise<Result<void>>;
  closeBrowser(id: string): Promise<Result<void>>;
  onPaneEvent(listener: (event: PaneEvent) => void): () => void;
  getDraft(id: string): Promise<Result<TextDraft & { warnings: string[] }>>;
  saveDraft(id: string, draft: TextDraft): Promise<Result<void>>;
  getHistoryPage(
    id: string,
    before: number,
  ): Promise<Result<{ view: SessionView; cursor: number | null; calls: number }>>;
  copyText(text: string): Promise<Result<void>>;
  copySessionPath(sessionId: string): Promise<Result<void>>;
  printPageToPdf(sessionId: string): Promise<Result<Uint8Array>>;
  savePreviewPdf(
    data: Uint8Array,
    suggestedName: string,
  ): Promise<Result<{ canceled: boolean; path?: string }>>;
  getInstalledEditors(): Promise<Result<EditorInfo[]>>;
  getMemorySettings(): Promise<Result<MemorySettings>>;
  saveMemorySettings(input: MemorySettings): Promise<Result<MemorySettings>>;
  getMemoryStatus(sessionId: string | null): Promise<Result<MemoryStatus>>;
  checkMemoryNow(sessionId: string | null): Promise<Result<MemoryStatus>>;
  clearLongMemory(): Promise<Result<MemoryStatus>>;
  openMemoryFile(
    sessionId: string | null,
    scope: "user" | "project" | "long",
    action: "view" | "edit",
  ): Promise<Result<{ path: string; content: string; exists: boolean }>>;
  openInEditor(sessionId: string, path: string, editorId: string): Promise<Result<void>>;
  fileAction(
    sessionId: string,
    path: string,
    action: FileAction,
    location?: FileLocation,
  ): Promise<Result<void>>;
  searchFiles(
    sessionId: string,
    query: string,
  ): Promise<Result<{ path: string; name: string; absolutePath: string; type: "file" | "directory" }[]>>;
  getWorkspaceInfo(sessionId: string | null): Promise<Result<WorkspaceInfo>>;
  readWebSourceIcon(
    sessionId: string,
    runId: string,
    sourceUrl: string,
  ): Promise<Result<{ dataUrl?: string }>>;
  downloadImage(src: string): Promise<Result<void>>;
  checkPreviewFiles(
    sessionId: string,
    paths: string[],
  ): Promise<Result<Array<{ path: string; exists: boolean }>>>;
  readPreviewRange(
    sessionId: string,
    path: string,
    offset: number,
    length: number,
  ): Promise<Result<Uint8Array>>;
  readFilePreview(sessionId: string, path: string, location?: FileLocation): Promise<Result<FilePreview>>;
  readWorkspaceDirectory(
    sessionId: string,
    path: string,
    rootPath?: string,
  ): Promise<Result<import("./workspace-files.ts").WorkspaceDirectoryEntry[]>>;
  workspaceGitStatus(
    sessionId: string,
    rootPath?: string,
  ): Promise<Result<import("./workspace-files.ts").WorkspaceGitSnapshot>>;
  ignoredWorkspacePaths(sessionId: string, paths: string[], rootPath?: string): Promise<Result<string[]>>;
  watchWorkspaceDirectory(
    sessionId: string,
    path: string,
    rootPath?: string,
    recursive?: boolean,
  ): Promise<Result<{ id: string }>>;
  watchReviewDirectory(sessionId: string, path: string): Promise<Result<{ id: string }>>;
  unwatchWorkspaceDirectory(id: string): Promise<Result<void>>;
  onWorkspaceDirectoryChange(id: string, listener: (event: { dirPath: string }) => void): () => void;

  pickAttachments(sessionId: string): Promise<Result<Attachment[]>>;
  importAttachment(sessionId: string, file: File): Promise<Result<Attachment>>;
  readAttachment(sessionId: string, id: string): Promise<Result<{ metadata: Attachment; data: string }>>;
  removeAttachment(sessionId: string, id: string): Promise<Result<void>>;
  getChanges(
    sessionId: string,
    runId: string | null,
    includePatch?: boolean,
    includeStats?: boolean,
  ): Promise<Result<DiffItem[]>>;
  readPatch(sessionId: string, runId: string | null, id: string): Promise<Result<string>>;
  getReview(
    sessionId: string,
    source: import("./review.ts").ReviewSource,
  ): Promise<Result<import("./review.ts").ReviewSnapshot>>;
  readReviewDiff(
    sessionId: string,
    source: import("./review.ts").ReviewSource,
    path: string,
    runId?: string,
  ): Promise<Result<import("./review.ts").ReviewDiffData>>;
  previewPrompt(): Promise<Result<PromptPreview>>;
  listTools(): Promise<Result<ToolInfo[]>>;
  getSkillSettings(): Promise<Result<SkillSettings>>;
  readSkill(path: string): Promise<Result<string>>;
  setSkillEnabled(path: string, enabled: boolean): Promise<Result<PublicSettings>>;
  listProjects(): Promise<Result<ProjectRecord[]>>;
  addProject(sessionId: string | null): Promise<Result<ProjectRecord | null>>;
  removeProject(id: string): Promise<Result<void>>;
  reorderProjects(ids: string[]): Promise<Result<void>>;
  listSessions(projectId: string): Promise<Result<SessionRecord[]>>;
  getTaskSearchChanges(sessionId: string): Promise<Result<TaskSearchChange[]>>;
  searchTasks(query: string, workspaceKey: string | null): Promise<Result<TaskSearchResult[]>>;
  searchWorkspaceFiles(
    sessionId: string | null,
    input: WorkspaceFileSearchInput,
  ): Promise<Result<WorkspaceFileSearchResult>>;
  cancelWorkspaceFileSearch(requestId: string): Promise<Result<void>>;
  listRecentSessions(): Promise<Result<SessionRecord[]>>;
  listSessionMentions(sessionId: string): Promise<Result<SessionMentionSuggestion[]>>;
  createSession(projectId: string | null, groupId?: string | null): Promise<Result<SessionRecord>>;
  activateSession(sessionId: string): Promise<Result<SessionRecord>>;
  setSessionPinned(sessionId: string, pinned: boolean): Promise<Result<SessionRecord>>;
  getSessionSnapshot(sessionId: string): Promise<Result<SessionSnapshot>>;
  renameSession(id: string, name: string): Promise<Result<SessionRecord>>;
  deleteSession(id: string): Promise<Result<void>>;
  startRun(input: RunInput): Promise<Result<{ runId: string }>>;
  submitInput(
    input: RunInput & { queueDisposition?: "keep" | "clear"; immediate?: boolean },
  ): Promise<Result<{ runId?: string; queueItemId?: string; confirmationRequired?: true }>>;
  editQueuedInput(
    sessionId: string,
    itemId: string,
  ): Promise<Result<{ item: QueuedInput; draft: TextDraft }>>;
  removeQueuedInput(sessionId: string, itemId: string): Promise<Result<void>>;
  sendQueuedNow(sessionId: string, itemId: string): Promise<Result<void>>;
  moveQueuedInput(sessionId: string, itemId: string, beforeId: string | null): Promise<Result<void>>;
  resumeInputQueue(sessionId: string): Promise<Result<void>>;
  forkSession(id: string, runId: string): Promise<Result<SessionRecord>>;
  editUserMessage(id: string, runId: string, input: EditUserInput): Promise<Result<EditUserResult>>;
  abortRun(input: { sessionId: string; runId: string }): Promise<Result<void>>;
  retryModelRequest(input: { sessionId: string; runId: string }): Promise<Result<boolean>>;
  getSettings(): Promise<Result<PublicSettings>>;
  updateShortcuts(input: ShortcutSettings): Promise<Result<PublicSettings>>;
  setShortcutCapture(capturing: boolean): Promise<Result<void>>;
  onShortcutModifier(listener: (held: boolean) => void): () => void;
  onShortcut(listener: (command: ShortcutCommand) => void): () => void;
  beginChatGPTLogin(providerId: string | null): Promise<Result<{ loginId: string; url: string }>>;
  completeChatGPTLogin(
    loginId: string,
  ): Promise<Result<{ settings: PublicSettings; providerId: string; warning?: string }>>;
  submitChatGPTCallback(loginId: string, url: string): Promise<Result<void>>;
  cancelChatGPTLogin(loginId: string): Promise<Result<void>>;
  disconnectChatGPT(providerId: string): Promise<Result<{ settings: PublicSettings; warning?: string }>>;
  onSettings(listener: (settings: PublicSettings) => void): () => void;
  discoverModels(input: {
    api?: ProviderApi;
    preset?: ProviderPresetId;
    providerId?: string;
    baseUrl?: string;
    apiKey?: string;
  }): Promise<Result<ModelDiscoveryResult>>;
  saveProvider(input: ProviderInput): Promise<Result<PublicSettings>>;
  saveWebSearch(input: WebSearchSettingsInput): Promise<Result<PublicSettings>>;
  reorderProviders(ids: string[]): Promise<Result<PublicSettings>>;
  deleteProvider(id: string): Promise<Result<PublicSettings>>;
  getProviderCredentials(id: string): Promise<Result<{ apiKey: string }>>;
  /** Read only when the user explicitly reveals the key in web search settings. */
  getWebSearchCredentials(): Promise<Result<{ apiKey: string }>>;
  updatePreferences(input: Partial<InterfacePreferences>): Promise<Result<PublicSettings>>;
  setSessionSelection(sessionId: string, selection: CombinedSelection): Promise<Result<SessionSnapshot>>;
  listSessionSkills(sessionId: string): Promise<Result<SkillList>>;
  listCommands(sessionId?: string): Promise<Result<{ name: string; description: string }[]>>;
  listSessionCustomCommands(sessionId: string): Promise<Result<CustomCommandsList>>;
  getCustomCommands(projectId?: string): Promise<Result<CustomCommandsList>>;
  createCustomCommand(input: CustomCommandInput, projectId?: string): Promise<Result<CustomCommand>>;
  updateCustomCommand(input: CustomCommandUpdate, projectId?: string): Promise<Result<CustomCommand>>;
  deleteCustomCommand(input: CustomCommandDelete, projectId?: string): Promise<Result<void>>;
  setCustomCommandEnabled(input: CustomCommandSetEnabled, projectId?: string): Promise<Result<CustomCommand>>;
  discoverCommandImports(projectId?: string): Promise<Result<CommandImportDiscovery>>;
  importCommands(input: CommandImportRequest, projectId?: string): Promise<Result<CommandImportResult>>;
  openExternal(url: string): Promise<Result<void>>;
  onEvent(listener: (event: DesktopEventEnvelope) => void): () => void;
  onEvents(listener: (events: readonly DesktopEventEnvelope[]) => void): () => void;
}
export const methods = [
  "getMemorySettings",
  "saveMemorySettings",
  "getMemoryStatus",
  "checkMemoryNow",
  "clearLongMemory",
  "openMemoryFile",
  "setSessionUnread",
  "getTaskGroups",
  "updateTaskGroups",
  "listSubagents",
  "saveSubagent",
  "deleteSubagent",
  "setSubagentEnabled",
  "stopSubagent",
  "stopBackgroundTask",
  "readBackgroundTask",
  "setPluginEnabled",
  "getLocalPlugins",
  "getHooks",
  "saveHook",
  "setHookEnabled",
  "deleteHook",
  "importLocalPlugin",
  "setPluginOptions",
  "respondToQuestion",
  "snoozeQuestion",
  "createSideChat",
  "closeSideChat",
  "getGitEnvironment",
  "setNewWorktree",
  "beginChatGPTLogin",
  "completeChatGPTLogin",
  "submitChatGPTCallback",
  "cancelChatGPTLogin",
  "disconnectChatGPT",
  "archiveSession",
  "listArchivedSessions",
  "restoreSession",
  "openDirectory",
  "createTerminal",
  "terminalInput",
  "resizeTerminal",
  "closeTerminal",
  "createBrowser",
  "browserAction",
  "browserGuest",
  "closeBrowser",
  "getDraft",
  "saveDraft",
  "getHistoryPage",
  "copyText",
  "copySessionPath",
  "fileAction",
  "getInstalledEditors",
  "printPageToPdf",
  "savePreviewPdf",
  "openInEditor",
  "searchFiles",
  "getWorkspaceInfo",
  "readFilePreview",
  "readWorkspaceDirectory",
  "workspaceGitStatus",
  "ignoredWorkspacePaths",
  "watchWorkspaceDirectory",
  "watchReviewDirectory",
  "unwatchWorkspaceDirectory",
  "readPreviewRange",
  "checkPreviewFiles",
  "downloadImage",
  "readWebSourceIcon",
  "pickAttachments",
  "importAttachment",
  "readAttachment",
  "removeAttachment",
  "getChanges",
  "readPatch",
  "getReview",
  "readReviewDiff",
  "previewPrompt",
  "listTools",
  "getSkillSettings",
  "readSkill",
  "setSkillEnabled",
  "listProjects",
  "addProject",
  "removeProject",
  "reorderProjects",
  "listSessions",
  "getTaskSearchChanges",
  "searchTasks",
  "searchWorkspaceFiles",
  "cancelWorkspaceFileSearch",
  "listRecentSessions",
  "listSessionMentions",
  "setSessionPinned",
  "createSession",
  "activateSession",
  "getSessionSnapshot",
  "renameSession",
  "deleteSession",
  "startRun",
  "submitInput",
  "editQueuedInput",
  "removeQueuedInput",
  "sendQueuedNow",
  "moveQueuedInput",
  "resumeInputQueue",
  "forkSession",
  "editUserMessage",
  "abortRun",
  "retryModelRequest",
  "getSettings",
  "updateShortcuts",
  "setShortcutCapture",
  "discoverModels",
  "saveProvider",
  "saveWebSearch",
  "reorderProviders",
  "deleteProvider",
  "getProviderCredentials",
  "getWebSearchCredentials",
  "updatePreferences",
  "setSessionSelection",
  "listSessionSkills",
  "listCommands",
  "getCustomCommands",
  "listSessionCustomCommands",
  "createCustomCommand",
  "updateCustomCommand",
  "deleteCustomCommand",
  "setCustomCommandEnabled",
  "discoverCommandImports",
  "importCommands",
  "openExternal",
] as const;