feat: add desktop app hot update channel
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
// 契约边界(已冻结):把主进程能力安全暴露给前端 window.api
|
||||
const { contextBridge, ipcRenderer } = require("electron");
|
||||
|
||||
contextBridge.exposeInMainWorld("api", {
|
||||
scanLocal: () => ipcRenderer.invoke("scan-local"),
|
||||
pickDir: () => ipcRenderer.invoke("pick-dir"),
|
||||
packLocal: (rels, destDir) => ipcRenderer.invoke("pack-local", { rels, destDir }),
|
||||
upload: (rels, repo, token, isPrivate) =>
|
||||
ipcRenderer.invoke("upload", { rels, repo, token, isPrivate }),
|
||||
marketList: () => ipcRenderer.invoke("market-list"),
|
||||
marketInstall: (entry) => ipcRenderer.invoke("market-install", { entry }),
|
||||
// —— 技能商店(cocoloop 镜像)——
|
||||
skillCatalog: () => ipcRenderer.invoke("skill-catalog"),
|
||||
skillInstall: (skill) => ipcRenderer.invoke("skill-install", { skill }),
|
||||
skillInstalled: () => ipcRenderer.invoke("skill-installed"),
|
||||
skillUninstall: (dir) => ipcRenderer.invoke("skill-uninstall", { dir }),
|
||||
skillMigrate: () => ipcRenderer.invoke("skill-migrate"),
|
||||
// —— 插件市场(tokendun 官方插件,自建 gitea)——
|
||||
pluginCatalog: () => ipcRenderer.invoke("plugin-catalog"),
|
||||
pluginInstall: (plugin) => ipcRenderer.invoke("plugin-install", { plugin }),
|
||||
pluginInstalled: () => ipcRenderer.invoke("plugin-installed"),
|
||||
pluginUninstall: (rel) => ipcRenderer.invoke("plugin-uninstall", { rel }),
|
||||
pluginMigrate: () => ipcRenderer.invoke("plugin-migrate"),
|
||||
// —— 热更新 ——
|
||||
hotCheck: () => ipcRenderer.invoke("hot-check"),
|
||||
hotApply: () => ipcRenderer.invoke("hot-apply"),
|
||||
hotConfirm: () => ipcRenderer.invoke("hot-confirm"),
|
||||
hotRestart: () => ipcRenderer.invoke("hot-restart"),
|
||||
onHotProgress: (cb) => {
|
||||
const handler = (_e, p) => cb(p);
|
||||
ipcRenderer.on("hot-progress", handler);
|
||||
return () => ipcRenderer.removeListener("hot-progress", handler);
|
||||
},
|
||||
ghPull: (repoInput, token) => ipcRenderer.invoke("gh-pull", { repoInput, token }),
|
||||
ghRestore: (rels, enable) => ipcRenderer.invoke("gh-restore", { rels, enable }),
|
||||
getSecret: (name) => ipcRenderer.invoke("get-secret", { name }),
|
||||
setSecret: (name, value) => ipcRenderer.invoke("set-secret", { name, value }),
|
||||
openExternal: (url) => ipcRenderer.invoke("open-external", { url }),
|
||||
quitApp: () => ipcRenderer.invoke("app-quit"),
|
||||
sessionsList: (opts) =>
|
||||
ipcRenderer.invoke("sessions-list", typeof opts === "object" && opts !== null ? opts : { includeSubagent: !!opts }),
|
||||
sessionRead: (path) => ipcRenderer.invoke("session-read", { path }),
|
||||
sessionExport: (item) => ipcRenderer.invoke("session-export", { item }),
|
||||
sessionsBackup: () => ipcRenderer.invoke("sessions-backup"),
|
||||
sessionsImport: () => ipcRenderer.invoke("sessions-import"),
|
||||
// —— 会话记忆 ——
|
||||
memoryStatus: () => ipcRenderer.invoke("memory-status"),
|
||||
memoryList: (opts) => ipcRenderer.invoke("memory-list", opts),
|
||||
memorySetEnabled: (enabled) => ipcRenderer.invoke("memory-set-enabled", { enabled }),
|
||||
memoryToggleProject: (cwd, enabled) => ipcRenderer.invoke("memory-toggle-project", { cwd, enabled }),
|
||||
memoryResummarize: (path) => ipcRenderer.invoke("memory-resummarize", { path }),
|
||||
memoryDelete: (id) => ipcRenderer.invoke("memory-delete", { id }),
|
||||
memoryOpenHandoff: (cwd) => ipcRenderer.invoke("memory-open-handoff", { cwd }),
|
||||
onMemoryChanged: (cb) => {
|
||||
const handler = () => cb();
|
||||
ipcRenderer.on("memory-changed", handler);
|
||||
return () => ipcRenderer.removeListener("memory-changed", handler);
|
||||
},
|
||||
providerSyncStatus: () => ipcRenderer.invoke("provider-sync-status"),
|
||||
providerSync: () => ipcRenderer.invoke("provider-sync"),
|
||||
onProviderSyncProgress: (cb) => {
|
||||
const handler = (_e, p) => cb(p);
|
||||
ipcRenderer.on("provider-sync-progress", handler);
|
||||
return () => ipcRenderer.removeListener("provider-sync-progress", handler);
|
||||
},
|
||||
routerStatus: () => ipcRenderer.invoke("router-status"),
|
||||
routerUpsertGroup: (group) => ipcRenderer.invoke("router-upsert-group", { group }),
|
||||
routerDeleteGroup: (id) => ipcRenderer.invoke("router-delete-group", { id }),
|
||||
routerSetActive: (id) => ipcRenderer.invoke("router-set-active", { id }),
|
||||
routerSetPort: (port) => ipcRenderer.invoke("router-set-port", { port }),
|
||||
routerStart: () => ipcRenderer.invoke("router-start"),
|
||||
routerStop: () => ipcRenderer.invoke("router-stop"),
|
||||
routerApplyCodex: () => ipcRenderer.invoke("router-apply-codex"),
|
||||
routerApplyClaude: () => ipcRenderer.invoke("router-apply-claude"),
|
||||
routerRestoreClaude: () => ipcRenderer.invoke("router-restore-claude"),
|
||||
routerSnippet: () => ipcRenderer.invoke("router-snippet"),
|
||||
routerFetchModels: (baseUrl, key, groupId) => ipcRenderer.invoke("router-fetch-models", { baseUrl, key, groupId }),
|
||||
onRouterChanged: (cb) => {
|
||||
const handler = (_e, s) => cb(s);
|
||||
ipcRenderer.on("router-changed", handler);
|
||||
return () => ipcRenderer.removeListener("router-changed", handler);
|
||||
},
|
||||
// —— 创意画布(中转执行层)——
|
||||
canvasStatus: () => ipcRenderer.invoke("canvas-status"),
|
||||
canvasRun: (kind, params) => ipcRenderer.invoke("canvas-run", { kind, params }),
|
||||
canvasGroups: () => ipcRenderer.invoke("canvas-groups"),
|
||||
canvasModels: (groupId) => ipcRenderer.invoke("canvas-models", { groupId }),
|
||||
onCanvasProgress: (cb) => {
|
||||
const h = (_e, p) => cb(p);
|
||||
ipcRenderer.on("canvas-progress", h);
|
||||
return () => ipcRenderer.removeListener("canvas-progress", h);
|
||||
},
|
||||
// —— 全局 / 系统代理 ——
|
||||
proxyStatus: () => ipcRenderer.invoke("proxy-status"),
|
||||
proxyGetConfig: () => ipcRenderer.invoke("proxy-get-config"),
|
||||
proxySetConfig: (cfg) => ipcRenderer.invoke("proxy-set-config", cfg),
|
||||
proxyStart: (mode) => ipcRenderer.invoke("proxy-start", { mode }),
|
||||
proxyStop: () => ipcRenderer.invoke("proxy-stop"),
|
||||
proxyTest: () => ipcRenderer.invoke("proxy-test"),
|
||||
onProxyChanged: (cb) => {
|
||||
const handler = (_e, s) => cb(s);
|
||||
ipcRenderer.on("proxy-changed", handler);
|
||||
return () => ipcRenderer.removeListener("proxy-changed", handler);
|
||||
},
|
||||
|
||||
// —— 检测 / 强制清除本机 Codex ——
|
||||
codexDetect: () => ipcRenderer.invoke("codex-detect"),
|
||||
codexPurge: (paths) => ipcRenderer.invoke("codex-purge", { paths }),
|
||||
|
||||
appVersion: () => ipcRenderer.invoke("app-version"),
|
||||
checkUpdate: () => ipcRenderer.invoke("check-update"),
|
||||
onUpdateStatus: (cb) => {
|
||||
const handler = (_e, s) => cb(s);
|
||||
ipcRenderer.on("update-status", handler);
|
||||
return () => ipcRenderer.removeListener("update-status", handler);
|
||||
},
|
||||
onLog: (cb) => {
|
||||
const handler = (_e, msg) => cb(msg);
|
||||
ipcRenderer.on("log", handler);
|
||||
return () => ipcRenderer.removeListener("log", handler);
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user