Skip to content

IPC 协议字典

1. Channel 拓扑

flowchart TB
  R[Renderer] --> P[preload.ts]
  P -->|ipcRenderer.send/invoke| M[main/index.ts ipcMain]
  M -->|HTTP + internal token| B[backend routes]

2. Channel 字典

ChannelIPC TypeParamsReturn SchemaMain Handler Behavior
app:close-windowsendnonenoneCloses focused window or main window
i18n:get-localeinvokenonePromise<string>Returns current resolved locale
i18n:set-localeinvokelocale: stringPromise<string>Resolves/persists in-memory locale and updates title
app:get-runtime-user-nameinvokenonePromise<string>Returns OS username fallback chain
app:get-version-infoinvokenonePromise<{ appName: string; version: string; buildVersion: string; buildTime: string; commit: string; electron: string; chromium: string; node: string; v8: string; os: string }>为关于页返回应用名称、版本号、构建时间与运行时技术信息
app:get-pending-launch-working-directoryinvokenonePromise<string | null>返回当前待消费的上下文启动工作目录(来自 CLI 参数)
app:get-downloads-pathinvokenonePromise<string>返回系统下载目录,供本地保存默认路径使用
app:create-sftp-temporary-fileinvokefileName: stringPromise<string>在 Cosmosh SFTP 临时根目录下创建唯一的本地目标路径,供 backend 下载与打开流程使用
app:open-sftp-temporary-fileinvokelocalPath: stringPromise<boolean>使用系统默认应用打开 Cosmosh SFTP 临时根目录下的既有文件
app:start-sftp-temporary-file-watchinvokelocalPath: stringPromise<string>为 Cosmosh SFTP 临时根目录下的既有文件启动防抖监听,并返回 watch id
app:stop-sftp-temporary-file-watchinvokewatchId: stringPromise<boolean>停止此前创建的 SFTP 临时文件监听
app:show-sftp-open-with-dialoginvokelocalPath: stringPromise<boolean>仅 Windows:校验临时文件路径,并通过 shell openas verb 打开系统“打开方式”选择器
app:list-sftp-open-with-applicationsinvokelocalPath: stringPromise<Array<{ id: string; name: string; path: string; bundleIdentifier?: string; iconDataUrl?: string }>>仅 macOS:校验临时文件路径,并返回 NSWorkspace 判定可打开该文件的应用列表
app:open-sftp-file-with-applicationinvokelocalPath: string, applicationPath: stringPromise<boolean>仅 macOS:校验临时文件与所选应用属于可用应用列表后,使用该应用打开文件
app:sftp-temporary-file-changedevent (main -> renderer){ watchId: string; localPath: string; size: number; modifiedAt: string }none向拥有该监听的 renderer webContents 推送一次防抖后的 SFTP 临时文件变更事件
app:get-database-security-infoinvokenonePromise<{ runtimeMode: 'development' | 'production'; resolverMode: 'development-fixed-key' | 'safe-storage' | 'master-password-fallback'; safeStorageAvailable: boolean; databasePath: string; securityConfigPath: string; hasEncryptedDbMasterKey: boolean; hasMasterPasswordHash: boolean; hasMasterPasswordSalt: boolean; hasMasterPasswordEnv: boolean; fallbackReady: boolean }>为设置 → 高级页返回非敏感的数据库加密引导诊断信息
app:launch-working-directoryevent (main -> renderer)cwd: stringnone当第二实例触发时,向渲染层推送上下文启动工作目录
app:menu-actionevent (main -> renderer)action: 'open-about' | 'open-settings' | 'new-tab' | 'close-current-tab' | 'close-right-tabs' | 'show-tab-switcher'none将 macOS 系统菜单触发的应用菜单命令以受控枚举形式分发到渲染层标签页/状态处理器
app:open-devtoolsinvokenonePromise<boolean>为当前主窗口打开 DevTools(窗口可用时)
app:toggle-devtoolsinvokenonePromise<boolean>切换当前主窗口的分离式 DevTools(已打开则关闭,已关闭则打开)
app:reload-webviewinvokenonePromise<boolean>重新加载当前活动 renderer webContents,并忽略缓存以保证调试刷新可预测
app:restart-backend-runtimeinvokenonePromise<boolean>在开发环境中原位重启 backend 运行时,无需重启整个应用
app:show-in-file-managerinvoketargetPath?: stringPromise<boolean>Opens file/folder in OS file manager
app:open-external-urlinvoketargetUrl: stringPromise<boolean>使用系统默认浏览器打开受信任的 HTTP(S) 链接
app:set-windows-system-menu-symbol-colorinvokesymbolColor: stringPromise<boolean>将 token 驱动的 Windows 标题栏系统菜单符号色应用到当前主窗口 overlay
app:show-save-file-dialoginvokedefaultPath?: stringPromise<{ canceled: boolean; filePath?: string }>打开原生保存对话框,并在确认后返回所选本地文件路径
app:import-private-keyinvokenonePromise<{ canceled: boolean; content?: string }>调起系统文件选择器并在选择后返回 UTF-8 私钥内容
app:get-process-performance-statsinvokenonePromise<{ sampledAt: number; cpuPercent: number | null; mainProcessMemory: { rssBytes: number; heapTotalBytes: number; heapUsedBytes: number; externalBytes: number; arrayBuffersBytes: number }; rendererProcessMemory: { residentSetBytes: number; privateBytes: number; sharedBytes: number } | null; backendProcess: { pid: number; cpuPercent: number | null; memoryRssBytes: number | null } | null }>为调试浮层采样主进程 CPU/内存,基于当前活动窗口获取渲染进程内存,并补充 backend 子进程 CPU/RSS 内存数据
app:export-main-heap-snapshotinvokenonePromise<{ ok: boolean; filePath?: string; message?: string }>将主进程 V8 堆快照写入应用 user-data 下的 debug 快照目录
backend:test-pinginvokenonePromise<ApiTestPingResponse | ApiErrorResponse>Calls backend health test endpoint
backend:settings-getinvokenonePromise<ApiSettingsGetResponse | ApiErrorResponse>GET 已持久化设置
backend:settings-updateinvokepayload: ApiSettingsUpdateRequestPromise<ApiSettingsUpdateResponse | ApiErrorResponse>PUT 设置快照
backend:audit-list-eventsinvokequery?: ApiAuditEventListQueryPromise<ApiAuditEventListResponse | ApiErrorResponse>GET 审计事件列表(支持过滤与分页)
backend:audit-get-event-by-idinvokeeventId: stringPromise<ApiAuditEventDetailResponse | ApiErrorResponse>GET 单条审计事件详情
backend:ssh-list-serversinvokenonePromise<ApiSshListServersResponse | ApiErrorResponse>GET SSH server list
backend:ssh-create-serverinvokepayload: ApiSshCreateServerRequestPromise<ApiSshCreateServerResponse | ApiErrorResponse>POST create SSH server
backend:ssh-update-serverinvokeserverId: string, payload: ApiSshUpdateServerRequestPromise<ApiSshUpdateServerResponse | ApiErrorResponse>PUT update SSH server
backend:ssh-get-server-credentialsinvokeserverId: stringPromise<ApiSshGetServerCredentialsResponse | ApiErrorResponse>GET decrypted credentials
backend:ssh-list-foldersinvokenonePromise<ApiSshListFoldersResponse | ApiErrorResponse>GET folder list
backend:ssh-create-folderinvokepayload: ApiSshCreateFolderRequestPromise<ApiSshCreateFolderResponse | ApiErrorResponse>POST create folder
backend:ssh-update-folderinvokefolderId: string, payload: ApiSshUpdateFolderRequestPromise<ApiSshUpdateFolderResponse | ApiErrorResponse>PUT update folder
backend:ssh-list-tagsinvokenonePromise<ApiSshListTagsResponse | ApiErrorResponse>GET tag list
backend:ssh-create-taginvokepayload: ApiSshCreateTagRequestPromise<ApiSshCreateTagResponse | ApiErrorResponse>POST create tag
backend:ssh-list-keychainsinvokenonePromise<ApiSshListKeychainsResponse | ApiErrorResponse>GET 钥匙链列表
backend:ssh-create-keychaininvokepayload: ApiSshCreateKeychainRequestPromise<ApiSshCreateKeychainResponse | ApiErrorResponse>POST 创建钥匙链
backend:ssh-update-keychaininvokekeychainId: string, payload: ApiSshUpdateKeychainRequestPromise<ApiSshUpdateKeychainResponse | ApiErrorResponse>PUT 更新钥匙链
backend:ssh-get-keychain-credentialsinvokekeychainId: stringPromise<ApiSshGetKeychainCredentialsResponse | ApiErrorResponse>GET 解密后的钥匙链凭据
backend:ssh-create-sessioninvokepayload: ApiSshCreateSessionRequestPromise<ApiSshCreateSessionResponse | ApiSshCreateSessionHostVerificationRequiredResponse | ApiErrorResponse>POST create SSH shell session
backend:ssh-trust-fingerprintinvokepayload: ApiSshTrustFingerprintRequestPromise<ApiSshTrustFingerprintResponse | ApiErrorResponse>POST trust host fingerprint
backend:ssh-close-sessioninvokesessionId: stringPromise<{ success: boolean }>DELETE SSH session
backend:ssh-delete-serverinvokeserverId: stringPromise<{ success: boolean }>DELETE SSH server
backend:ssh-delete-folderinvokefolderId: stringPromise<{ success: boolean }>DELETE SSH folder
backend:ssh-delete-keychaininvokekeychainId: stringPromise<{ success: boolean }>DELETE SSH 钥匙链
backend:port-forward-list-rulesinvokenonePromise<ApiPortForwardListRulesResponse | ApiErrorResponse>GET 已持久化的 SSH 端口转发规则,并合并内存运行状态
backend:port-forward-create-ruleinvokepayload: ApiPortForwardCreateRuleRequestPromise<ApiPortForwardCreateRuleResponse | ApiErrorResponse>POST 创建一条 stopped 端口转发规则
backend:port-forward-update-ruleinvokeruleId: string, payload: ApiPortForwardUpdateRuleRequestPromise<ApiPortForwardUpdateRuleResponse | ApiErrorResponse>PUT 更新一条 stopped 端口转发规则
backend:port-forward-start-ruleinvokeruleId: stringPromise<ApiPortForwardStartRuleResponse | ApiErrorResponse>POST 启动一条规则;可能返回共享 SSH_HOST_UNTRUSTED payload 供指纹信任后重试
backend:port-forward-stop-ruleinvokeruleId: stringPromise<ApiPortForwardStopRuleResponse | ApiErrorResponse>POST 停止一条活动规则;已停止规则由 backend 幂等处理
backend:port-forward-delete-ruleinvokeruleId: stringPromise<{ success: boolean }>DELETE 一条 stopped 端口转发规则
backend:sftp-create-sessioninvokepayload: ApiSftpCreateSessionRequestPromise<ApiSftpCreateSessionResponse | ApiSftpCreateSessionHostVerificationRequiredResponse | ApiErrorResponse>POST 创建 SFTP 文件系统会话
backend:sftp-list-directoryinvokesessionId: string, query?: ApiSftpListDirectoryQueryPromise<ApiSftpListDirectoryResponse | ApiErrorResponse>GET 单个 SFTP 目录列表
backend:sftp-get-entry-detailsinvokesessionId: string, payload: ApiSftpEntryDetailsRequestPromise<ApiSftpEntryDetailsResponse | ApiErrorResponse>POST 获取已选 SFTP 条目的非递归元数据
backend:sftp-read-fileinvokesessionId: string, query: ApiSftpReadFileQueryPromise<ApiSftpReadFileResponse | ApiErrorResponse>GET 当前 SFTP 会话内有上限的 UTF-8 文件预览
backend:sftp-download-fileinvokesessionId: string, payload: ApiSftpDownloadFileRequestPromise<ApiSftpDownloadFileResponse | ApiErrorResponse>POST 将一个远程普通 SFTP 文件流式写入由 app utility IPC 选定的本地路径
backend:sftp-upload-fileinvokesessionId: string, payload: ApiSftpUploadFileRequestPromise<ApiSftpUploadFileResponse | ApiErrorResponse>POST 在远程 size/mtime 冲突检查通过后,将一个本地已编辑的 SFTP 临时文件流式写回远程文件;overwrite: true 只在 renderer 冲突确认后发送,远程冲突返回 SFTP_UPLOAD_CONFLICT
backend:sftp-create-directoryinvokesessionId: string, payload: ApiSftpCreateDirectoryRequestPromise<ApiSftpCreateDirectoryResponse | ApiErrorResponse>POST 创建远程 SFTP 目录
backend:sftp-create-fileinvokesessionId: string, payload: ApiSftpCreateFileRequestPromise<ApiSftpCreateFileResponse | ApiErrorResponse>POST 创建远程 SFTP 空文件
backend:sftp-rename-entryinvokesessionId: string, payload: ApiSftpRenameRequestPromise<ApiSftpRenameResponse | ApiErrorResponse>POST 重命名或移动远程 SFTP 条目
backend:sftp-copy-entryinvokesessionId: string, payload: ApiSftpCopyRequestPromise<ApiSftpCopyResponse | ApiErrorResponse>POST 复制远程 SFTP 文件或目录树
backend:sftp-delete-entryinvokesessionId: string, payload: ApiSftpDeleteRequestPromise<ApiSftpDeleteResponse | ApiErrorResponse>POST 删除远程 SFTP 文件、符号链接或目录树
backend:sftp-batch-operationinvokesessionId: string, payload: ApiSftpBatchOperationRequestPromise<ApiSftpBatchOperationResponse | ApiErrorResponse>POST 对多个 SFTP 条目执行有序批量复制、移动或删除
backend:sftp-close-sessioninvokesessionId: stringPromise<{ success: boolean }>DELETE SFTP 会话
backend:local-terminal-list-profilesinvokenonePromise<ApiLocalTerminalListProfilesResponse | ApiErrorResponse>GET local terminal profile list
backend:local-terminal-create-sessioninvokepayload: ApiLocalTerminalCreateSessionRequestPromise<ApiLocalTerminalCreateSessionResponse | ApiErrorResponse>POST 本地终端会话(Main 可能注入一次性 cwd 上下文)
backend:local-terminal-close-sessioninvokesessionId: stringPromise<{ success: boolean }>DELETE local terminal session

3. Schema 来源

  • API payload 类型来自 @cosmosh/api-contract,并由 packages/api-contract/openapi/cosmosh.openapi.yaml 生成。
  • Backend、Main IPC 代理与 renderer HTTP 调用端必须通过 @cosmosh/api-contract 中生成的 API_PATHS 及相关合同导出访问 API,不允许硬编码路由字符串。
  • 未由 OpenAPI 生成的 IPC-only payload(包括 AppMenuActionSftpOpenWithApplicationSftpTemporaryFileWatchChange)定义在 packages/api-contract/src/ipc.ts,供 main、preload 与 renderer 类型声明共同消费。

3.1 SSH 视觉元数据字段

以下 SSH 实体相关载荷已包含用于持久化图标/配色自定义的视觉字段:

  • ApiSshCreateServerRequest / ApiSshUpdateServerRequest:可选 iconKey、可选 colorKey
  • ApiSshCreateFolderRequest / ApiSshUpdateFolderRequest:可选 iconKey、可选 colorKey
  • ApiSshListServersResponse:每个服务器条目包含 iconKeycolorKey
  • ApiSshListFoldersResponse:每个文件夹条目包含 iconKeycolorKey

colorKey 受 API 契约中的预设配色枚举约束。

当前 SSH 安全策略相关字段:

  • ApiSshCreateServerRequest / ApiSshUpdateServerRequeststrictHostKeyenableSshCompression 以及仅供 renderer 使用的 disableCharacterWidthCompatibilityMode 布尔值。
  • ApiSshListServersResponse:每个 server 条目返回持久化 strictHostKeyenableSshCompressiondisableCharacterWidthCompatibilityMode
  • ApiSshCreateSessionRequest:可选 strictHostKeyenableSshCompression,可用于单次会话尝试覆盖。
  • 字符宽度兼容模式不会传入 SSH session create 或终端 WS 消息;renderer 会在创建 xterm 实例时应用该规则。

3.2 SSH 端口转发契约

端口转发 payload 由 OpenAPI 源生成,并被 backend、main、preload 与 renderer wrapper 共同消费:

  • ApiPortForwardListRulesResponse
  • ApiPortForwardCreateRuleRequest / ApiPortForwardCreateRuleResponse
  • ApiPortForwardUpdateRuleRequest / ApiPortForwardUpdateRuleResponse
  • ApiPortForwardStartRuleResponse
  • ApiPortForwardStopRuleResponse

规则类型为 localremotedynamic

类型专属字段:

  • Local:localBindHostlocalBindPorttargetHosttargetPort
  • Remote:remoteBindHostremoteBindPorttargetHosttargetPort
  • Dynamic:localBindHostlocalBindPort

运行状态通过 runtime.status 返回,但不会持久化。Start 可能返回 SSH_HOST_UNTRUSTED;renderer 必须先通过 backend:ssh-trust-fingerprint 信任指纹,然后再重试。

3.3 终端 WebSocket 契约(Renderer ↔ Backend)

终端流式消息虽然不属于 Electron IPC channel,但同样属于跨进程契约面,必须与 IPC 变更一起维护版本一致性。

  • 客户端到服务端(/ws/ssh/{sessionId}/ws/local-terminal/{sessionId}):
    • inputresizepingclosehistory-delete
    • completion-request,包含 requestIdlinePrefixcursorIndex、可选 workingDirectoryHint、可选 limit、可选 fuzzyMatch、可选来源过滤字段(includeHistoryincludeBuiltInCommandsincludePathSuggestionsincludePasswordSuggestions)、triggertypingmanual
  • 服务端到客户端:
    • readyoutputtelemetryhistorypongerrorexit
    • completion-response,包含 requestIdreplacePrefixLength 与排序后的候选 items

补全候选契约说明:

  • items[].source 目前包含 historyinshellisense 与运行时计算来源 runtime
  • items[].kind 在原有命令规范/历史分类之外,新增运行时分类(pathsecret)。
  • 运行时分类用于路径候选与交互式密钥填充动作,但仍复用相同的 completion-response 外层结构。

当前实现说明:

  • 补全消息在 SshSessionServiceLocalTerminalSessionService 中处理,输入规范化由 terminal/shared.ts 统一,排序引擎由 terminal/completion/engine.ts 共享。

4. 变更规则

当新增/修改 channel 时,必须在一个变更中同步更新:

  1. packages/main/src/preload.ts
  2. packages/main/src/index.ts
  3. packages/renderer/src/vite-env.d.ts
  4. 相关 renderer transport/service 封装
  5. 本文件(docs/zh-CN/developer/core/ipc-protocol.md

5. Channel 新增模板

新增 channel 时建议按以下清单执行:

  1. Channel 命名:domain:action-name
  2. IPC 类型:invokesend
  3. 参数 schema:在 bridge 与 renderer 声明中显式类型化
  4. 返回 schema:成功与错误结构
  5. Main 行为:后端代理或本地特权动作
  6. 安全说明:token/header 处理、权限边界、暴露范围
  7. 文档同步:同一变更集更新中英文协议文档