@adversity/coding-tool-x 3.1.0 → 3.1.2

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.
Files changed (142) hide show
  1. package/CHANGELOG.md +39 -18
  2. package/README.md +8 -8
  3. package/dist/web/assets/ConfigTemplates-Bidwfdf2.css +1 -0
  4. package/dist/web/assets/ConfigTemplates-DvcbKKdS.js +1 -0
  5. package/dist/web/assets/Home-BJKPCBuk.css +1 -0
  6. package/dist/web/assets/Home-Cw-F_Wnu.js +1 -0
  7. package/dist/web/assets/PluginManager-ROyoZ-6m.css +1 -0
  8. package/dist/web/assets/PluginManager-jy_4GVxI.js +1 -0
  9. package/dist/web/assets/ProjectList-C1fQb9OW.css +1 -0
  10. package/dist/web/assets/ProjectList-Df1-NcNr.js +1 -0
  11. package/dist/web/assets/SessionList-BGJWyneI.css +1 -0
  12. package/dist/web/assets/SessionList-UWcZtC2r.js +1 -0
  13. package/dist/web/assets/SkillManager-D7pd-d_P.css +1 -0
  14. package/dist/web/assets/SkillManager-IRdseMKB.js +1 -0
  15. package/dist/web/assets/Terminal-BasTyDut.js +1 -0
  16. package/dist/web/assets/Terminal-DGNJeVtc.css +1 -0
  17. package/dist/web/assets/WorkspaceManager-CrwgQgmP.css +1 -0
  18. package/dist/web/assets/WorkspaceManager-D-D2kK1V.js +1 -0
  19. package/dist/web/assets/icons-kcfLIMBB.js +1 -0
  20. package/dist/web/assets/index-CoB3zF0K.css +1 -0
  21. package/dist/web/assets/index-CryrSLv8.js +2 -0
  22. package/dist/web/assets/markdown-BfC0goYb.css +10 -0
  23. package/dist/web/assets/markdown-C9MYpaSi.js +1 -0
  24. package/dist/web/assets/naive-ui-CSrLusZZ.js +1 -0
  25. package/dist/web/assets/{vendors-D2HHw_aW.js → vendors-CO3Upi1d.js} +2 -2
  26. package/dist/web/assets/vue-vendor-DqyWIXEb.js +45 -0
  27. package/dist/web/assets/xterm-6GBZ9nXN.css +32 -0
  28. package/dist/web/assets/xterm-BJzAjXCH.js +13 -0
  29. package/dist/web/index.html +8 -6
  30. package/package.json +4 -2
  31. package/src/commands/channels.js +48 -1
  32. package/src/commands/cli-type.js +4 -2
  33. package/src/commands/daemon.js +81 -12
  34. package/src/commands/doctor.js +10 -9
  35. package/src/commands/list.js +1 -1
  36. package/src/commands/logs.js +6 -4
  37. package/src/commands/port-config.js +24 -4
  38. package/src/commands/proxy-control.js +12 -6
  39. package/src/commands/search.js +1 -1
  40. package/src/commands/security.js +3 -2
  41. package/src/commands/stats.js +226 -52
  42. package/src/commands/switch.js +1 -1
  43. package/src/commands/toggle-proxy.js +31 -6
  44. package/src/commands/update.js +97 -0
  45. package/src/commands/workspace.js +1 -1
  46. package/src/config/default.js +41 -2
  47. package/src/config/loader.js +74 -8
  48. package/src/config/model-metadata.js +415 -0
  49. package/src/config/model-pricing.js +23 -93
  50. package/src/config/paths.js +105 -33
  51. package/src/index.js +64 -3
  52. package/src/plugins/constants.js +3 -2
  53. package/src/plugins/plugin-api.js +1 -1
  54. package/src/reset-config.js +4 -2
  55. package/src/server/api/agents.js +57 -14
  56. package/src/server/api/channels.js +112 -33
  57. package/src/server/api/codex-channels.js +111 -18
  58. package/src/server/api/codex-proxy.js +14 -8
  59. package/src/server/api/commands.js +71 -18
  60. package/src/server/api/config-export.js +0 -6
  61. package/src/server/api/config-registry.js +11 -3
  62. package/src/server/api/config.js +376 -5
  63. package/src/server/api/convert.js +133 -0
  64. package/src/server/api/dashboard.js +22 -6
  65. package/src/server/api/gemini-channels.js +107 -18
  66. package/src/server/api/gemini-proxy.js +14 -8
  67. package/src/server/api/gemini-sessions.js +1 -1
  68. package/src/server/api/health-check.js +4 -3
  69. package/src/server/api/mcp.js +3 -3
  70. package/src/server/api/opencode-channels.js +497 -0
  71. package/src/server/api/opencode-projects.js +99 -0
  72. package/src/server/api/opencode-proxy.js +207 -0
  73. package/src/server/api/opencode-sessions.js +345 -0
  74. package/src/server/api/opencode-statistics.js +57 -0
  75. package/src/server/api/plugins.js +66 -19
  76. package/src/server/api/prompts.js +2 -2
  77. package/src/server/api/proxy.js +7 -4
  78. package/src/server/api/sessions.js +3 -0
  79. package/src/server/api/settings.js +111 -0
  80. package/src/server/api/skills.js +69 -18
  81. package/src/server/api/workspaces.js +78 -6
  82. package/src/server/codex-proxy-server.js +36 -22
  83. package/src/server/dev-server.js +1 -1
  84. package/src/server/gemini-proxy-server.js +21 -7
  85. package/src/server/index.js +174 -58
  86. package/src/server/opencode-proxy-server.js +5486 -0
  87. package/src/server/proxy-server.js +33 -22
  88. package/src/server/services/agents-service.js +61 -24
  89. package/src/server/services/channel-scheduler.js +9 -5
  90. package/src/server/services/channels.js +64 -37
  91. package/src/server/services/codex-channels.js +56 -43
  92. package/src/server/services/codex-sessions.js +105 -6
  93. package/src/server/services/codex-settings-manager.js +271 -49
  94. package/src/server/services/codex-statistics-service.js +2 -2
  95. package/src/server/services/commands-service.js +84 -25
  96. package/src/server/services/config-export-service.js +7 -45
  97. package/src/server/services/config-registry-service.js +63 -17
  98. package/src/server/services/config-sync-manager.js +160 -7
  99. package/src/server/services/config-templates-service.js +204 -51
  100. package/src/server/services/env-checker.js +50 -13
  101. package/src/server/services/env-manager.js +155 -19
  102. package/src/server/services/favorites.js +5 -3
  103. package/src/server/services/gemini-channels.js +33 -44
  104. package/src/server/services/gemini-statistics-service.js +2 -2
  105. package/src/server/services/mcp-service.js +350 -9
  106. package/src/server/services/model-detector.js +707 -221
  107. package/src/server/services/network-access.js +80 -0
  108. package/src/server/services/opencode-channels.js +208 -0
  109. package/src/server/services/opencode-gateway-converter.js +639 -0
  110. package/src/server/services/opencode-sessions.js +931 -0
  111. package/src/server/services/opencode-settings-manager.js +478 -0
  112. package/src/server/services/opencode-statistics-service.js +255 -0
  113. package/src/server/services/plugins-service.js +479 -22
  114. package/src/server/services/prompts-service.js +53 -11
  115. package/src/server/services/proxy-runtime.js +1 -1
  116. package/src/server/services/repo-scanner-base.js +1 -1
  117. package/src/server/services/response-decoder.js +21 -0
  118. package/src/server/services/security-config.js +1 -1
  119. package/src/server/services/session-cache.js +1 -1
  120. package/src/server/services/skill-service.js +300 -46
  121. package/src/server/services/speed-test.js +464 -186
  122. package/src/server/services/statistics-service.js +2 -2
  123. package/src/server/services/terminal-commands.js +10 -3
  124. package/src/server/services/terminal-config.js +1 -1
  125. package/src/server/services/ui-config.js +1 -1
  126. package/src/server/services/workspace-service.js +57 -100
  127. package/src/server/websocket-server.js +156 -8
  128. package/src/ui/menu.js +49 -40
  129. package/src/utils/port-helper.js +22 -8
  130. package/src/utils/session.js +5 -4
  131. package/dist/web/assets/icons-CO_2OFES.js +0 -1
  132. package/dist/web/assets/index-DI8QOi-E.js +0 -14
  133. package/dist/web/assets/index-uLHGdeZh.css +0 -41
  134. package/dist/web/assets/naive-ui-B1re3c-e.js +0 -1
  135. package/dist/web/assets/vue-vendor-6JaYHOiI.js +0 -44
  136. package/src/server/api/oauth.js +0 -294
  137. package/src/server/api/permissions.js +0 -385
  138. package/src/server/config/oauth-providers.js +0 -68
  139. package/src/server/services/oauth-callback-server.js +0 -284
  140. package/src/server/services/oauth-service.js +0 -378
  141. package/src/server/services/oauth-token-storage.js +0 -135
  142. package/src/server/services/permission-templates-service.js +0 -308
@@ -8,7 +8,24 @@ const express = require('express');
8
8
  const { CommandsService } = require('../services/commands-service');
9
9
 
10
10
  const router = express.Router();
11
- const commandsService = new CommandsService();
11
+ const SUPPORTED_PLATFORMS = ['claude', 'opencode'];
12
+ const commandServices = new Map();
13
+
14
+ function resolvePlatform(rawPlatform) {
15
+ return SUPPORTED_PLATFORMS.includes(rawPlatform) ? rawPlatform : 'claude';
16
+ }
17
+
18
+ function getPlatform(req) {
19
+ return resolvePlatform(req.query?.platform || req.body?.platform);
20
+ }
21
+
22
+ function getCommandsService(req) {
23
+ const platform = getPlatform(req);
24
+ if (!commandServices.has(platform)) {
25
+ commandServices.set(platform, new CommandsService(platform));
26
+ }
27
+ return { platform, service: commandServices.get(platform) };
28
+ }
12
29
 
13
30
  /**
14
31
  * 获取命令列表
@@ -17,11 +34,13 @@ const commandsService = new CommandsService();
17
34
  */
18
35
  router.get('/', (req, res) => {
19
36
  try {
37
+ const { platform, service } = getCommandsService(req);
20
38
  const { projectPath } = req.query;
21
- const result = commandsService.listCommands(projectPath || null);
39
+ const result = service.listCommands(projectPath || null);
22
40
 
23
41
  res.json({
24
42
  success: true,
43
+ platform,
25
44
  ...result
26
45
  });
27
46
  } catch (err) {
@@ -39,11 +58,13 @@ router.get('/', (req, res) => {
39
58
  */
40
59
  router.get('/stats', (req, res) => {
41
60
  try {
61
+ const { platform, service } = getCommandsService(req);
42
62
  const { projectPath } = req.query;
43
- const stats = commandsService.getStats(projectPath || null);
63
+ const stats = service.getStats(projectPath || null);
44
64
 
45
65
  res.json({
46
66
  success: true,
67
+ platform,
47
68
  ...stats
48
69
  });
49
70
  } catch (err) {
@@ -62,6 +83,7 @@ router.get('/stats', (req, res) => {
62
83
  */
63
84
  router.get('/:scope/:name', (req, res) => {
64
85
  try {
86
+ const { platform, service } = getCommandsService(req);
65
87
  const { scope, name } = req.params;
66
88
  const { projectPath, namespace } = req.query;
67
89
 
@@ -79,7 +101,7 @@ router.get('/:scope/:name', (req, res) => {
79
101
  });
80
102
  }
81
103
 
82
- const command = commandsService.getCommand(name, scope, projectPath || null, namespace || null);
104
+ const command = service.getCommand(name, scope, projectPath || null, namespace || null);
83
105
 
84
106
  if (!command) {
85
107
  return res.status(404).json({
@@ -90,6 +112,7 @@ router.get('/:scope/:name', (req, res) => {
90
112
 
91
113
  res.json({
92
114
  success: true,
115
+ platform,
93
116
  command
94
117
  });
95
118
  } catch (err) {
@@ -108,7 +131,8 @@ router.get('/:scope/:name', (req, res) => {
108
131
  */
109
132
  router.post('/', (req, res) => {
110
133
  try {
111
- const { name, scope, projectPath, namespace, description, allowedTools, argumentHint, body } = req.body;
134
+ const { platform, service } = getCommandsService(req);
135
+ const { name, scope, projectPath, namespace, description, allowedTools, argumentHint, agent, model, subtask, body } = req.body;
112
136
 
113
137
  if (!name) {
114
138
  return res.status(400).json({
@@ -131,7 +155,7 @@ router.post('/', (req, res) => {
131
155
  });
132
156
  }
133
157
 
134
- const command = commandsService.createCommand({
158
+ const command = service.createCommand({
135
159
  name,
136
160
  scope,
137
161
  projectPath: projectPath || null,
@@ -139,11 +163,15 @@ router.post('/', (req, res) => {
139
163
  description: description || '',
140
164
  allowedTools: allowedTools || '',
141
165
  argumentHint: argumentHint || '',
166
+ agent: agent || '',
167
+ model: model || '',
168
+ subtask: typeof subtask === 'boolean' ? subtask : undefined,
142
169
  body: body || ''
143
170
  });
144
171
 
145
172
  res.json({
146
173
  success: true,
174
+ platform,
147
175
  command,
148
176
  message: '命令创建成功'
149
177
  });
@@ -162,8 +190,9 @@ router.post('/', (req, res) => {
162
190
  */
163
191
  router.put('/:scope/:name', (req, res) => {
164
192
  try {
193
+ const { platform, service } = getCommandsService(req);
165
194
  const { scope, name } = req.params;
166
- const { projectPath, namespace, description, allowedTools, argumentHint, body } = req.body;
195
+ const { projectPath, namespace, description, allowedTools, argumentHint, agent, model, subtask, body } = req.body;
167
196
 
168
197
  if (!['user', 'project'].includes(scope)) {
169
198
  return res.status(400).json({
@@ -179,7 +208,7 @@ router.put('/:scope/:name', (req, res) => {
179
208
  });
180
209
  }
181
210
 
182
- const command = commandsService.updateCommand({
211
+ const command = service.updateCommand({
183
212
  name,
184
213
  scope,
185
214
  projectPath: projectPath || null,
@@ -187,11 +216,15 @@ router.put('/:scope/:name', (req, res) => {
187
216
  description: description || '',
188
217
  allowedTools: allowedTools || '',
189
218
  argumentHint: argumentHint || '',
219
+ agent: agent || '',
220
+ model: model || '',
221
+ subtask: typeof subtask === 'boolean' ? subtask : undefined,
190
222
  body: body || ''
191
223
  });
192
224
 
193
225
  res.json({
194
226
  success: true,
227
+ platform,
195
228
  command,
196
229
  message: '命令更新成功'
197
230
  });
@@ -210,6 +243,7 @@ router.put('/:scope/:name', (req, res) => {
210
243
  */
211
244
  router.delete('/:scope/:name', (req, res) => {
212
245
  try {
246
+ const { platform, service } = getCommandsService(req);
213
247
  const { scope, name } = req.params;
214
248
  const { projectPath, namespace } = req.query;
215
249
 
@@ -227,9 +261,10 @@ router.delete('/:scope/:name', (req, res) => {
227
261
  });
228
262
  }
229
263
 
230
- const result = commandsService.deleteCommand(name, scope, projectPath || null, namespace || null);
264
+ const result = service.deleteCommand(name, scope, projectPath || null, namespace || null);
231
265
 
232
266
  res.json({
267
+ platform,
233
268
  success: result.success,
234
269
  message: result.message
235
270
  });
@@ -251,12 +286,14 @@ router.delete('/:scope/:name', (req, res) => {
251
286
  */
252
287
  router.get('/all', async (req, res) => {
253
288
  try {
289
+ const { platform, service } = getCommandsService(req);
254
290
  const { projectPath, refresh } = req.query;
255
291
  const forceRefresh = refresh === '1';
256
- const result = await commandsService.listAllCommands(projectPath || null, forceRefresh);
292
+ const result = await service.listAllCommands(projectPath || null, forceRefresh);
257
293
 
258
294
  res.json({
259
295
  success: true,
296
+ platform,
260
297
  ...result
261
298
  });
262
299
  } catch (err) {
@@ -274,9 +311,11 @@ router.get('/all', async (req, res) => {
274
311
  */
275
312
  router.get('/repos', (req, res) => {
276
313
  try {
277
- const repos = commandsService.getRepos();
314
+ const { platform, service } = getCommandsService(req);
315
+ const repos = service.getRepos();
278
316
  res.json({
279
317
  success: true,
318
+ platform,
280
319
  repos
281
320
  });
282
321
  } catch (err) {
@@ -295,6 +334,7 @@ router.get('/repos', (req, res) => {
295
334
  */
296
335
  router.post('/repos', (req, res) => {
297
336
  try {
337
+ const { platform, service } = getCommandsService(req);
298
338
  const { owner, name, branch = 'main', directory = '', enabled = true } = req.body;
299
339
 
300
340
  if (!owner || !name) {
@@ -304,10 +344,11 @@ router.post('/repos', (req, res) => {
304
344
  });
305
345
  }
306
346
 
307
- const repos = commandsService.addRepo({ owner, name, branch, directory, enabled });
347
+ const repos = service.addRepo({ owner, name, branch, directory, enabled });
308
348
 
309
349
  res.json({
310
350
  success: true,
351
+ platform,
311
352
  repos
312
353
  });
313
354
  } catch (err) {
@@ -326,12 +367,14 @@ router.post('/repos', (req, res) => {
326
367
  */
327
368
  router.delete('/repos/:owner/:name', (req, res) => {
328
369
  try {
370
+ const { platform, service } = getCommandsService(req);
329
371
  const { owner, name } = req.params;
330
372
  const { directory = '' } = req.query;
331
- const repos = commandsService.removeRepo(owner, name, directory);
373
+ const repos = service.removeRepo(owner, name, directory);
332
374
 
333
375
  res.json({
334
376
  success: true,
377
+ platform,
335
378
  repos
336
379
  });
337
380
  } catch (err) {
@@ -350,13 +393,15 @@ router.delete('/repos/:owner/:name', (req, res) => {
350
393
  */
351
394
  router.put('/repos/:owner/:name/toggle', (req, res) => {
352
395
  try {
396
+ const { platform, service } = getCommandsService(req);
353
397
  const { owner, name } = req.params;
354
398
  const { enabled, directory = '' } = req.body;
355
399
 
356
- const repos = commandsService.toggleRepo(owner, name, directory, enabled);
400
+ const repos = service.toggleRepo(owner, name, directory, enabled);
357
401
 
358
402
  res.json({
359
403
  success: true,
404
+ platform,
360
405
  repos
361
406
  });
362
407
  } catch (err) {
@@ -375,6 +420,7 @@ router.put('/repos/:owner/:name/toggle', (req, res) => {
375
420
  */
376
421
  router.post('/install', async (req, res) => {
377
422
  try {
423
+ const { platform, service } = getCommandsService(req);
378
424
  const command = req.body;
379
425
 
380
426
  if (!command || !command.repoOwner || !command.repoName) {
@@ -384,10 +430,11 @@ router.post('/install', async (req, res) => {
384
430
  });
385
431
  }
386
432
 
387
- const result = await commandsService.installFromRemote(command);
433
+ const result = await service.installFromRemote(command);
388
434
 
389
435
  res.json({
390
436
  success: true,
437
+ platform,
391
438
  ...result
392
439
  });
393
440
  } catch (err) {
@@ -406,6 +453,7 @@ router.post('/install', async (req, res) => {
406
453
  */
407
454
  router.post('/uninstall', (req, res) => {
408
455
  try {
456
+ const { platform, service } = getCommandsService(req);
409
457
  const { path } = req.body;
410
458
 
411
459
  if (!path) {
@@ -415,10 +463,11 @@ router.post('/uninstall', (req, res) => {
415
463
  });
416
464
  }
417
465
 
418
- const result = commandsService.uninstallCommand(path);
466
+ const result = service.uninstallCommand(path);
419
467
 
420
468
  res.json({
421
469
  success: true,
470
+ platform,
422
471
  ...result
423
472
  });
424
473
  } catch (err) {
@@ -441,6 +490,7 @@ router.post('/uninstall', (req, res) => {
441
490
  */
442
491
  router.post('/convert', (req, res) => {
443
492
  try {
493
+ const { platform, service } = getCommandsService(req);
444
494
  const { content, targetFormat } = req.body;
445
495
 
446
496
  if (!content) {
@@ -457,10 +507,11 @@ router.post('/convert', (req, res) => {
457
507
  });
458
508
  }
459
509
 
460
- const result = commandsService.convertCommandFormat(content, targetFormat);
510
+ const result = service.convertCommandFormat(content, targetFormat);
461
511
 
462
512
  res.json({
463
513
  success: true,
514
+ platform,
464
515
  ...result
465
516
  });
466
517
  } catch (err) {
@@ -479,6 +530,7 @@ router.post('/convert', (req, res) => {
479
530
  */
480
531
  router.post('/detect-format', (req, res) => {
481
532
  try {
533
+ const { platform, service } = getCommandsService(req);
482
534
  const { content } = req.body;
483
535
 
484
536
  if (!content) {
@@ -488,10 +540,11 @@ router.post('/detect-format', (req, res) => {
488
540
  });
489
541
  }
490
542
 
491
- const format = commandsService.detectFormat(content);
543
+ const format = service.detectFormat(content);
492
544
 
493
545
  res.json({
494
546
  success: true,
547
+ platform,
495
548
  format
496
549
  });
497
550
  } catch (err) {
@@ -23,17 +23,11 @@ function buildPreviewSummary(data) {
23
23
  version: data.version,
24
24
  exportedAt: data.exportedAt,
25
25
  counts: {
26
- permissionTemplates: (data.data.permissionTemplates || []).length,
27
26
  configTemplates: (data.data.configTemplates || []).length,
28
27
  channels: (data.data.channels || []).length,
29
28
  plugins: (data.data.plugins || []).length
30
29
  },
31
30
  items: {
32
- permissionTemplates: (data.data.permissionTemplates || []).map(t => ({
33
- id: t.id,
34
- name: t.name,
35
- description: t.description
36
- })),
37
31
  configTemplates: (data.data.configTemplates || []).map(t => ({
38
32
  id: t.id,
39
33
  name: t.name,
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  const express = require('express');
9
- const { ConfigRegistryService, CONFIG_TYPES } = require('../services/config-registry-service');
9
+ const { ConfigRegistryService, CONFIG_TYPES, SUPPORTED_PLATFORMS } = require('../services/config-registry-service');
10
10
  const { ConfigSyncManager } = require('../services/config-sync-manager');
11
11
 
12
12
  const router = express.Router();
@@ -17,7 +17,7 @@ const syncManager = new ConfigSyncManager();
17
17
  const VALID_TYPES = CONFIG_TYPES;
18
18
 
19
19
  // Valid platforms
20
- const VALID_PLATFORMS = ['claude', 'codex'];
20
+ const VALID_PLATFORMS = SUPPORTED_PLATFORMS;
21
21
 
22
22
  /**
23
23
  * Validate config type parameter
@@ -199,10 +199,14 @@ router.put('/:type/:name/toggle', async (req, res) => {
199
199
  if (item.platforms?.codex) {
200
200
  syncManager.syncToCodex(type, name);
201
201
  }
202
+ if (item.platforms?.opencode) {
203
+ syncManager.syncToOpenCode(type, name);
204
+ }
202
205
  } else {
203
206
  // Remove from all platforms
204
207
  syncManager.removeFromClaude(type, name);
205
208
  syncManager.removeFromCodex(type, name);
209
+ syncManager.removeFromOpenCode(type, name);
206
210
  }
207
211
 
208
212
  res.json({
@@ -220,7 +224,7 @@ router.put('/:type/:name/toggle', async (req, res) => {
220
224
 
221
225
  /**
222
226
  * PUT /api/config-registry/:type/:name/platform/:platform
223
- * Toggle platform (claude/codex) for an item
227
+ * Toggle platform (claude/codex/opencode) for an item
224
228
  * Body: { enabled: boolean }
225
229
  * - Updates registry
226
230
  * - If enabling platform: sync to that platform (if item is enabled)
@@ -275,6 +279,8 @@ router.put('/:type/:name/platform/:platform', async (req, res) => {
275
279
  syncManager.syncToClaude(type, name);
276
280
  } else if (platform === 'codex') {
277
281
  syncManager.syncToCodex(type, name);
282
+ } else if (platform === 'opencode') {
283
+ syncManager.syncToOpenCode(type, name);
278
284
  }
279
285
  } else {
280
286
  // Remove from this platform
@@ -282,6 +288,8 @@ router.put('/:type/:name/platform/:platform', async (req, res) => {
282
288
  syncManager.removeFromClaude(type, name);
283
289
  } else if (platform === 'codex') {
284
290
  syncManager.removeFromCodex(type, name);
291
+ } else if (platform === 'opencode') {
292
+ syncManager.removeFromOpenCode(type, name);
285
293
  }
286
294
  }
287
295