ccnew 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -0
- package/build/icon.ico +0 -0
- package/build/icon.png +0 -0
- package/core/apply.js +152 -0
- package/core/backup.js +53 -0
- package/core/constants.js +78 -0
- package/core/desktop-service.js +403 -0
- package/core/desktop-state.js +1021 -0
- package/core/index.js +1468 -0
- package/core/paths.js +99 -0
- package/core/presets.js +171 -0
- package/core/probe.js +70 -0
- package/core/routing.js +334 -0
- package/core/store.js +218 -0
- package/core/utils.js +225 -0
- package/core/writers/codex.js +102 -0
- package/core/writers/index.js +16 -0
- package/core/writers/openclaw.js +93 -0
- package/core/writers/opencode.js +91 -0
- package/desktop/assets/fml-icon.png +0 -0
- package/desktop/assets/march-mark.svg +26 -0
- package/desktop/main.js +275 -0
- package/desktop/preload.cjs +67 -0
- package/desktop/preload.js +49 -0
- package/desktop/renderer/app.js +327 -0
- package/desktop/renderer/index.html +130 -0
- package/desktop/renderer/styles.css +490 -0
- package/package.json +111 -0
- package/scripts/build-web.mjs +95 -0
- package/scripts/desktop-dev.mjs +90 -0
- package/scripts/desktop-pack-win.mjs +81 -0
- package/scripts/postinstall.mjs +49 -0
- package/scripts/prepublish-check.mjs +57 -0
- package/scripts/serve-site.mjs +51 -0
- package/site/app.js +10 -0
- package/site/assets/fml-icon.png +0 -0
- package/site/assets/march-mark.svg +26 -0
- package/site/index.html +337 -0
- package/site/styles.css +840 -0
- package/src/App.tsx +1557 -0
- package/src/components/layout/app-sidebar.tsx +103 -0
- package/src/components/layout/top-toolbar.tsx +44 -0
- package/src/components/layout/workspace-tabs.tsx +32 -0
- package/src/components/providers/inspector-panel.tsx +84 -0
- package/src/components/providers/metric-strip.tsx +26 -0
- package/src/components/providers/provider-editor.tsx +87 -0
- package/src/components/providers/provider-table.tsx +85 -0
- package/src/components/ui/logo-mark.tsx +32 -0
- package/src/features/mcp/mcp-view.tsx +45 -0
- package/src/features/prompts/prompts-view.tsx +40 -0
- package/src/features/providers/providers-view.tsx +40 -0
- package/src/features/providers/types.ts +26 -0
- package/src/features/skills/skills-view.tsx +44 -0
- package/src/hooks/use-control-workspace.ts +235 -0
- package/src/index.css +22 -0
- package/src/lib/client.ts +726 -0
- package/src/lib/query-client.ts +3 -0
- package/src/lib/workspace-sections.ts +34 -0
- package/src/main.tsx +14 -0
- package/src/types.ts +137 -0
- package/src/vite-env.d.ts +64 -0
- package/src-tauri/README.md +11 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { DEFAULT_PRIMARY_MODEL, MODEL_DEFINITIONS } from "../constants.js";
|
|
2
|
+
import { getOpenCodeConfigPath, getOpenCodeDir } from "../paths.js";
|
|
3
|
+
import { deepMerge, ensureDir, isRecord, readJson, writeJson } from "../utils.js";
|
|
4
|
+
|
|
5
|
+
function buildModelMap() {
|
|
6
|
+
return Object.fromEntries(
|
|
7
|
+
MODEL_DEFINITIONS.map((model) => [
|
|
8
|
+
model.id,
|
|
9
|
+
{
|
|
10
|
+
name: model.id,
|
|
11
|
+
options: {
|
|
12
|
+
store: false
|
|
13
|
+
},
|
|
14
|
+
variants: {
|
|
15
|
+
low: {},
|
|
16
|
+
medium: {},
|
|
17
|
+
high: {},
|
|
18
|
+
xhigh: {}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
])
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function writeOpenCodeConfig(provider, options = {}) {
|
|
26
|
+
ensureDir(getOpenCodeDir());
|
|
27
|
+
|
|
28
|
+
const configPath = getOpenCodeConfigPath();
|
|
29
|
+
const mode = options.mode === "overwrite" ? "overwrite" : "merge";
|
|
30
|
+
const existing = mode === "overwrite" ? {} : readJson(configPath, {});
|
|
31
|
+
const existingProviders =
|
|
32
|
+
mode === "overwrite" || !isRecord(existing?.provider) ? {} : existing.provider;
|
|
33
|
+
|
|
34
|
+
const nextConfig = deepMerge(
|
|
35
|
+
{
|
|
36
|
+
$schema: "https://opencode.ai/config.json",
|
|
37
|
+
model: `openai/${provider.model || DEFAULT_PRIMARY_MODEL}`,
|
|
38
|
+
provider: {
|
|
39
|
+
openai: {
|
|
40
|
+
options: {
|
|
41
|
+
baseURL: provider.baseUrl,
|
|
42
|
+
apiKey: provider.apiKey
|
|
43
|
+
},
|
|
44
|
+
models: buildModelMap()
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
agent: {
|
|
48
|
+
build: {
|
|
49
|
+
options: {
|
|
50
|
+
store: false
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
plan: {
|
|
54
|
+
options: {
|
|
55
|
+
store: false
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
existing
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
nextConfig.model = `openai/${provider.model || DEFAULT_PRIMARY_MODEL}`;
|
|
64
|
+
nextConfig.provider = {
|
|
65
|
+
...existingProviders,
|
|
66
|
+
openai: {
|
|
67
|
+
...(isRecord(existingProviders.openai) ? existingProviders.openai : {}),
|
|
68
|
+
options: {
|
|
69
|
+
...(isRecord(existingProviders.openai?.options) ? existingProviders.openai.options : {}),
|
|
70
|
+
baseURL: provider.baseUrl,
|
|
71
|
+
apiKey: provider.apiKey
|
|
72
|
+
},
|
|
73
|
+
models: buildModelMap()
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
nextConfig.agent = {
|
|
77
|
+
...(isRecord(nextConfig.agent) ? nextConfig.agent : {}),
|
|
78
|
+
build: {
|
|
79
|
+
options: {
|
|
80
|
+
store: false
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
plan: {
|
|
84
|
+
options: {
|
|
85
|
+
store: false
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
writeJson(configPath, nextConfig);
|
|
91
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="fml-bg" x1="16" y1="12" x2="108" y2="116" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop stop-color="#071A24"/>
|
|
5
|
+
<stop offset="0.55" stop-color="#103847"/>
|
|
6
|
+
<stop offset="1" stop-color="#0C8E7F"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
<radialGradient id="fml-glow" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(96 28) rotate(135) scale(42)">
|
|
9
|
+
<stop stop-color="#5EEAD4" stop-opacity="0.85"/>
|
|
10
|
+
<stop offset="1" stop-color="#5EEAD4" stop-opacity="0"/>
|
|
11
|
+
</radialGradient>
|
|
12
|
+
<linearGradient id="fml-stroke" x1="24" y1="30" x2="98" y2="98" gradientUnits="userSpaceOnUse">
|
|
13
|
+
<stop stop-color="#FFF9EE"/>
|
|
14
|
+
<stop offset="1" stop-color="#D5FBF5"/>
|
|
15
|
+
</linearGradient>
|
|
16
|
+
</defs>
|
|
17
|
+
<rect x="8" y="8" width="112" height="112" rx="30" fill="url(#fml-bg)"/>
|
|
18
|
+
<rect x="8.75" y="8.75" width="110.5" height="110.5" rx="29.25" stroke="rgba(255,255,255,0.12)" stroke-width="1.5"/>
|
|
19
|
+
<circle cx="96" cy="28" r="30" fill="url(#fml-glow)" opacity="0.72"/>
|
|
20
|
+
<path d="M26 36V92" stroke="url(#fml-stroke)" stroke-width="10" stroke-linecap="round"/>
|
|
21
|
+
<path d="M26 36H54" stroke="url(#fml-stroke)" stroke-width="10" stroke-linecap="round"/>
|
|
22
|
+
<path d="M26 62H47" stroke="url(#fml-stroke)" stroke-width="10" stroke-linecap="round"/>
|
|
23
|
+
<path d="M60 92V36L74 62L88 36V92" stroke="url(#fml-stroke)" stroke-width="10" stroke-linecap="round" stroke-linejoin="round"/>
|
|
24
|
+
<path d="M102 36V92" stroke="#F3C46C" stroke-width="10" stroke-linecap="round"/>
|
|
25
|
+
<path d="M88 92H102" stroke="#F3C46C" stroke-width="10" stroke-linecap="round"/>
|
|
26
|
+
</svg>
|
package/desktop/main.js
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { app, BrowserWindow, dialog, ipcMain, shell } from "electron";
|
|
6
|
+
import {
|
|
7
|
+
activateProviderFromDesktop,
|
|
8
|
+
applyPresetFromDesktop,
|
|
9
|
+
deleteMcpFromDesktop,
|
|
10
|
+
deletePresetFromDesktop,
|
|
11
|
+
deletePromptFromDesktop,
|
|
12
|
+
deleteSkillFromDesktop,
|
|
13
|
+
exportPresetsToDesktop,
|
|
14
|
+
getDesktopSnapshot,
|
|
15
|
+
importPresetsFromDesktop,
|
|
16
|
+
probeCandidateFromDesktop,
|
|
17
|
+
probePlatformProvidersFromDesktop,
|
|
18
|
+
saveProviderFromDesktop,
|
|
19
|
+
savePresetFromDesktop,
|
|
20
|
+
toggleMcpFromDesktop,
|
|
21
|
+
togglePromptFromDesktop,
|
|
22
|
+
toggleSkillRepoFromDesktop,
|
|
23
|
+
updateRoutingFromDesktop,
|
|
24
|
+
upsertMcpFromDesktop,
|
|
25
|
+
upsertPromptFromDesktop,
|
|
26
|
+
upsertSkillFromDesktop
|
|
27
|
+
} from "../core/desktop-service.js";
|
|
28
|
+
|
|
29
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
30
|
+
const __dirname = path.dirname(__filename);
|
|
31
|
+
|
|
32
|
+
async function exists(filePath) {
|
|
33
|
+
try {
|
|
34
|
+
await fs.access(filePath);
|
|
35
|
+
return true;
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function resolveTargetPath(input) {
|
|
42
|
+
const raw = `${input ?? ""}`.trim();
|
|
43
|
+
if (!raw) {
|
|
44
|
+
throw new Error("目标路径不能为空");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (raw.startsWith("~/")) {
|
|
48
|
+
return path.join(os.homedir(), raw.slice(2));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!path.isAbsolute(raw)) {
|
|
52
|
+
throw new Error("仅支持绝对路径或 ~/ 开头路径");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return raw;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function openPathFromDesktop(targetPath) {
|
|
59
|
+
const resolvedPath = resolveTargetPath(targetPath);
|
|
60
|
+
const error = await shell.openPath(resolvedPath);
|
|
61
|
+
if (error) {
|
|
62
|
+
throw new Error(error);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
ok: true,
|
|
67
|
+
targetPath: resolvedPath
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function choosePresetImportPath() {
|
|
72
|
+
const result = await dialog.showOpenDialog({
|
|
73
|
+
title: "导入 ccon 预设",
|
|
74
|
+
properties: ["openFile"],
|
|
75
|
+
filters: [{ name: "JSON", extensions: ["json"] }]
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (result.canceled || result.filePaths.length === 0) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return result.filePaths[0];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function choosePresetExportPath() {
|
|
86
|
+
const result = await dialog.showSaveDialog({
|
|
87
|
+
title: "导出 ccon 预设",
|
|
88
|
+
defaultPath: path.join(os.homedir(), `ccon-presets-${new Date().toISOString().slice(0, 10)}.json`),
|
|
89
|
+
filters: [{ name: "JSON", extensions: ["json"] }]
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (result.canceled || !result.filePath) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return result.filePath;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function loadRenderer(window) {
|
|
100
|
+
const devUrl = `${process.env.MARCH_DESKTOP_DEV_URL || ""}`.trim();
|
|
101
|
+
if (devUrl) {
|
|
102
|
+
await window.loadURL(devUrl);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const externalDistIndex = path.join(path.dirname(process.execPath), "dist", "index.html");
|
|
107
|
+
if (await exists(externalDistIndex)) {
|
|
108
|
+
await window.loadFile(externalDistIndex);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const appRoot = app.getAppPath();
|
|
113
|
+
const distIndex = path.join(appRoot, "dist", "index.html");
|
|
114
|
+
|
|
115
|
+
if (app.isPackaged && (await exists(distIndex))) {
|
|
116
|
+
await window.loadFile(distIndex);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
await window.loadFile(path.join(__dirname, "renderer", "index.html"));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function createWindow() {
|
|
124
|
+
const windowIcon = path.join(app.getAppPath(), "build", "icon.png");
|
|
125
|
+
const win = new BrowserWindow({
|
|
126
|
+
width: 1480,
|
|
127
|
+
height: 960,
|
|
128
|
+
minWidth: 1180,
|
|
129
|
+
minHeight: 760,
|
|
130
|
+
backgroundColor: "#f4efe6",
|
|
131
|
+
autoHideMenuBar: true,
|
|
132
|
+
title: "ccon",
|
|
133
|
+
icon: windowIcon,
|
|
134
|
+
webPreferences: {
|
|
135
|
+
preload: path.join(__dirname, "preload.cjs"),
|
|
136
|
+
contextIsolation: true,
|
|
137
|
+
nodeIntegration: false
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
loadRenderer(win).catch((error) => {
|
|
142
|
+
console.error("failed to load desktop renderer", error);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
return win;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
ipcMain.handle("desktop:getSnapshot", async () => getDesktopSnapshot());
|
|
149
|
+
|
|
150
|
+
ipcMain.handle("desktop:saveProvider", async (_event, payload = {}) => {
|
|
151
|
+
const platform = payload.platform;
|
|
152
|
+
const input = payload.input || {
|
|
153
|
+
name: payload.name,
|
|
154
|
+
baseUrl: payload.baseUrl,
|
|
155
|
+
apiKey: payload.apiKey,
|
|
156
|
+
model: payload.model
|
|
157
|
+
};
|
|
158
|
+
return saveProviderFromDesktop(platform, input, payload.options);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
ipcMain.handle("desktop:activateProvider", async (_event, payload = {}) => {
|
|
162
|
+
const platform = payload.platform;
|
|
163
|
+
const nameOrId = payload.nameOrId || payload.providerId;
|
|
164
|
+
return activateProviderFromDesktop(platform, nameOrId, payload.options);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
ipcMain.handle("desktop:probePlatform", async (_event, payload = {}) => {
|
|
168
|
+
return probePlatformProvidersFromDesktop(payload.platform);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
ipcMain.handle("desktop:probeCandidate", async (_event, payload = {}) => {
|
|
172
|
+
return probeCandidateFromDesktop(payload.platform, payload.baseUrl);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
ipcMain.handle("desktop:savePreset", async (_event, payload = {}) => {
|
|
176
|
+
return savePresetFromDesktop(payload);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
ipcMain.handle("desktop:deletePreset", async (_event, payload = {}) => {
|
|
180
|
+
return deletePresetFromDesktop(payload.name);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
ipcMain.handle("desktop:applyPreset", async (_event, payload = {}) => {
|
|
184
|
+
return applyPresetFromDesktop(payload.name, payload.options);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
ipcMain.handle("desktop:importPresets", async () => {
|
|
188
|
+
const filePath = await choosePresetImportPath();
|
|
189
|
+
if (!filePath) {
|
|
190
|
+
return { canceled: true };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
canceled: false,
|
|
195
|
+
filePath,
|
|
196
|
+
...(await importPresetsFromDesktop(filePath))
|
|
197
|
+
};
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
ipcMain.handle("desktop:exportPresets", async () => {
|
|
201
|
+
const filePath = await choosePresetExportPath();
|
|
202
|
+
if (!filePath) {
|
|
203
|
+
return { canceled: true };
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
canceled: false,
|
|
208
|
+
...(await exportPresetsToDesktop(filePath))
|
|
209
|
+
};
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
ipcMain.handle("desktop:updateRouting", async (_event, payload = {}) => {
|
|
213
|
+
return updateRoutingFromDesktop(payload.platform, payload);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
ipcMain.handle("desktop:toggleMcp", async (_event, payload = {}) => {
|
|
217
|
+
return toggleMcpFromDesktop(payload.serverId, payload.platform);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
ipcMain.handle("desktop:upsertMcp", async (_event, payload = {}) => {
|
|
221
|
+
return upsertMcpFromDesktop(payload);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
ipcMain.handle("desktop:deleteMcp", async (_event, payload = {}) => {
|
|
225
|
+
return deleteMcpFromDesktop(payload.serverId);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
ipcMain.handle("desktop:togglePrompt", async (_event, payload = {}) => {
|
|
229
|
+
return togglePromptFromDesktop(payload.promptId);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
ipcMain.handle("desktop:upsertPrompt", async (_event, payload = {}) => {
|
|
233
|
+
return upsertPromptFromDesktop(payload);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
ipcMain.handle("desktop:deletePrompt", async (_event, payload = {}) => {
|
|
237
|
+
return deletePromptFromDesktop(payload.promptId);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
ipcMain.handle("desktop:upsertSkill", async (_event, payload = {}) => {
|
|
241
|
+
return upsertSkillFromDesktop(payload);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
ipcMain.handle("desktop:deleteSkill", async (_event, payload = {}) => {
|
|
245
|
+
return deleteSkillFromDesktop(payload.skillId);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
ipcMain.handle("desktop:toggleSkillRepo", async (_event, payload = {}) => {
|
|
249
|
+
return toggleSkillRepoFromDesktop(payload.repoId);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
ipcMain.handle("desktop:openPath", async (_event, payload) => {
|
|
253
|
+
const targetPath = typeof payload === "string" ? payload : payload?.targetPath;
|
|
254
|
+
return openPathFromDesktop(targetPath);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
app.whenReady().then(() => {
|
|
258
|
+
const mainWindow = createWindow();
|
|
259
|
+
|
|
260
|
+
mainWindow.once("ready-to-show", () => {
|
|
261
|
+
mainWindow.show();
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
app.on("activate", () => {
|
|
265
|
+
if (BrowserWindow.getAllWindows().length === 0) {
|
|
266
|
+
createWindow();
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
app.on("window-all-closed", () => {
|
|
272
|
+
if (process.platform !== "darwin") {
|
|
273
|
+
app.quit();
|
|
274
|
+
}
|
|
275
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const { contextBridge, ipcRenderer } = require("electron");
|
|
2
|
+
|
|
3
|
+
contextBridge.exposeInMainWorld("marchDesktop", {
|
|
4
|
+
getSnapshot() {
|
|
5
|
+
return ipcRenderer.invoke("desktop:getSnapshot");
|
|
6
|
+
},
|
|
7
|
+
saveProvider(payload) {
|
|
8
|
+
return ipcRenderer.invoke("desktop:saveProvider", payload);
|
|
9
|
+
},
|
|
10
|
+
activateProvider(payload) {
|
|
11
|
+
return ipcRenderer.invoke("desktop:activateProvider", payload);
|
|
12
|
+
},
|
|
13
|
+
probePlatform(payload) {
|
|
14
|
+
return ipcRenderer.invoke("desktop:probePlatform", payload);
|
|
15
|
+
},
|
|
16
|
+
probeCandidate(payload) {
|
|
17
|
+
return ipcRenderer.invoke("desktop:probeCandidate", payload);
|
|
18
|
+
},
|
|
19
|
+
savePreset(payload) {
|
|
20
|
+
return ipcRenderer.invoke("desktop:savePreset", payload);
|
|
21
|
+
},
|
|
22
|
+
deletePreset(payload) {
|
|
23
|
+
return ipcRenderer.invoke("desktop:deletePreset", payload);
|
|
24
|
+
},
|
|
25
|
+
applyPreset(payload) {
|
|
26
|
+
return ipcRenderer.invoke("desktop:applyPreset", payload);
|
|
27
|
+
},
|
|
28
|
+
importPresets() {
|
|
29
|
+
return ipcRenderer.invoke("desktop:importPresets");
|
|
30
|
+
},
|
|
31
|
+
exportPresets() {
|
|
32
|
+
return ipcRenderer.invoke("desktop:exportPresets");
|
|
33
|
+
},
|
|
34
|
+
updateRouting(payload) {
|
|
35
|
+
return ipcRenderer.invoke("desktop:updateRouting", payload);
|
|
36
|
+
},
|
|
37
|
+
toggleMcp(payload) {
|
|
38
|
+
return ipcRenderer.invoke("desktop:toggleMcp", payload);
|
|
39
|
+
},
|
|
40
|
+
upsertMcp(payload) {
|
|
41
|
+
return ipcRenderer.invoke("desktop:upsertMcp", payload);
|
|
42
|
+
},
|
|
43
|
+
deleteMcp(payload) {
|
|
44
|
+
return ipcRenderer.invoke("desktop:deleteMcp", payload);
|
|
45
|
+
},
|
|
46
|
+
togglePrompt(payload) {
|
|
47
|
+
return ipcRenderer.invoke("desktop:togglePrompt", payload);
|
|
48
|
+
},
|
|
49
|
+
upsertPrompt(payload) {
|
|
50
|
+
return ipcRenderer.invoke("desktop:upsertPrompt", payload);
|
|
51
|
+
},
|
|
52
|
+
deletePrompt(payload) {
|
|
53
|
+
return ipcRenderer.invoke("desktop:deletePrompt", payload);
|
|
54
|
+
},
|
|
55
|
+
upsertSkill(payload) {
|
|
56
|
+
return ipcRenderer.invoke("desktop:upsertSkill", payload);
|
|
57
|
+
},
|
|
58
|
+
deleteSkill(payload) {
|
|
59
|
+
return ipcRenderer.invoke("desktop:deleteSkill", payload);
|
|
60
|
+
},
|
|
61
|
+
toggleSkillRepo(payload) {
|
|
62
|
+
return ipcRenderer.invoke("desktop:toggleSkillRepo", payload);
|
|
63
|
+
},
|
|
64
|
+
openPath(targetPath) {
|
|
65
|
+
return ipcRenderer.invoke("desktop:openPath", targetPath);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { contextBridge, ipcRenderer } from "electron";
|
|
2
|
+
|
|
3
|
+
contextBridge.exposeInMainWorld("marchDesktop", {
|
|
4
|
+
getSnapshot() {
|
|
5
|
+
return ipcRenderer.invoke("desktop:getSnapshot");
|
|
6
|
+
},
|
|
7
|
+
saveProvider(payload) {
|
|
8
|
+
return ipcRenderer.invoke("desktop:saveProvider", payload);
|
|
9
|
+
},
|
|
10
|
+
activateProvider(payload) {
|
|
11
|
+
return ipcRenderer.invoke("desktop:activateProvider", payload);
|
|
12
|
+
},
|
|
13
|
+
probePlatform(payload) {
|
|
14
|
+
return ipcRenderer.invoke("desktop:probePlatform", payload);
|
|
15
|
+
},
|
|
16
|
+
probeCandidate(payload) {
|
|
17
|
+
return ipcRenderer.invoke("desktop:probeCandidate", payload);
|
|
18
|
+
},
|
|
19
|
+
toggleMcp(payload) {
|
|
20
|
+
return ipcRenderer.invoke("desktop:toggleMcp", payload);
|
|
21
|
+
},
|
|
22
|
+
upsertMcp(payload) {
|
|
23
|
+
return ipcRenderer.invoke("desktop:upsertMcp", payload);
|
|
24
|
+
},
|
|
25
|
+
deleteMcp(payload) {
|
|
26
|
+
return ipcRenderer.invoke("desktop:deleteMcp", payload);
|
|
27
|
+
},
|
|
28
|
+
togglePrompt(payload) {
|
|
29
|
+
return ipcRenderer.invoke("desktop:togglePrompt", payload);
|
|
30
|
+
},
|
|
31
|
+
upsertPrompt(payload) {
|
|
32
|
+
return ipcRenderer.invoke("desktop:upsertPrompt", payload);
|
|
33
|
+
},
|
|
34
|
+
deletePrompt(payload) {
|
|
35
|
+
return ipcRenderer.invoke("desktop:deletePrompt", payload);
|
|
36
|
+
},
|
|
37
|
+
upsertSkill(payload) {
|
|
38
|
+
return ipcRenderer.invoke("desktop:upsertSkill", payload);
|
|
39
|
+
},
|
|
40
|
+
deleteSkill(payload) {
|
|
41
|
+
return ipcRenderer.invoke("desktop:deleteSkill", payload);
|
|
42
|
+
},
|
|
43
|
+
toggleSkillRepo(payload) {
|
|
44
|
+
return ipcRenderer.invoke("desktop:toggleSkillRepo", payload);
|
|
45
|
+
},
|
|
46
|
+
openPath(targetPath) {
|
|
47
|
+
return ipcRenderer.invoke("desktop:openPath", targetPath);
|
|
48
|
+
}
|
|
49
|
+
});
|