coding-tool-x 3.7.0 → 3.7.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.
- package/README.md +10 -11
- package/dist/web/assets/{Analytics-Dma_j2Rq.js → Analytics-D5kLOhUo.js} +1 -1
- package/dist/web/assets/{ConfigTemplates-C49Y1PLH.js → ConfigTemplates-D_-16blp.js} +1 -1
- package/dist/web/assets/Home-DM_56Fyr.js +1 -0
- package/dist/web/assets/Home-Jom_ZcdY.css +1 -0
- package/dist/web/assets/{PluginManager-B1ECTHyY.js → PluginManager-Cv_rv8Dh.js} +1 -1
- package/dist/web/assets/{ProjectList-B_L55-l9.css → ProjectList-D3a0oRum.css} +1 -1
- package/dist/web/assets/ProjectList-H_m4Tx4E.js +1 -0
- package/dist/web/assets/{SessionList-CH5GwwiJ.js → SessionList-DcUQvsbR.js} +1 -1
- package/dist/web/assets/{SkillManager-CRyVhjYQ.js → SkillManager-CRav3m2a.js} +1 -1
- package/dist/web/assets/{WorkspaceManager-CO9tclVt.js → WorkspaceManager-B3f8R4EF.js} +1 -1
- package/dist/web/assets/index-Bnni1zPN.js +2 -0
- package/dist/web/assets/index-CfMuHG8u.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +2 -1
- package/src/commands/channels.js +8 -8
- package/src/commands/daemon.js +4 -4
- package/src/commands/doctor.js +1 -1
- package/src/commands/logs.js +1 -3
- package/src/commands/port-config.js +4 -4
- package/src/commands/proxy-control.js +13 -13
- package/src/commands/stats.js +6 -6
- package/src/commands/toggle-proxy.js +8 -8
- package/src/commands/ui.js +1 -0
- package/src/config/default.js +3 -3
- package/src/config/paths.js +46 -49
- package/src/index.js +7 -7
- package/src/server/api/commands.js +1 -1
- package/src/server/api/config-export.js +2 -2
- package/src/server/api/config-registry.js +1 -1
- package/src/server/api/config.js +1 -1
- package/src/server/api/dashboard.js +16 -16
- package/src/server/api/mcp.js +2 -2
- package/src/server/api/oauth-credentials.js +15 -2
- package/src/server/api/{pi-channels.js → omp-channels.js} +115 -53
- package/src/server/api/{pi-config.js → omp-config.js} +13 -13
- package/src/server/api/{pi-projects.js → omp-projects.js} +5 -5
- package/src/server/api/{pi-proxy.js → omp-proxy.js} +18 -18
- package/src/server/api/{pi-sessions.js → omp-sessions.js} +21 -21
- package/src/server/api/{pi-statistics.js → omp-statistics.js} +1 -1
- package/src/server/api/plugins.js +1 -1
- package/src/server/api/skills.js +1 -1
- package/src/server/api/workspaces.js +1 -1
- package/src/server/index.js +23 -15
- package/src/server/{pi-proxy-server.js → omp-proxy-server.js} +13 -13
- package/src/server/services/channel-balance.js +3 -3
- package/src/server/services/channel-scheduler.js +4 -4
- package/src/server/services/commands-service.js +5 -5
- package/src/server/services/config-export-service.js +53 -53
- package/src/server/services/config-registry-service.js +8 -8
- package/src/server/services/config-sync-manager.js +26 -26
- package/src/server/services/config-templates-service.js +28 -28
- package/src/server/services/mcp-service.js +20 -20
- package/src/server/services/model-detector.js +15 -2
- package/src/server/services/native-oauth-adapters.js +212 -1
- package/src/server/services/network-access.js +5 -0
- package/src/server/services/notification-hooks.js +138 -6
- package/src/server/services/oauth-credentials-service.js +110 -3
- package/src/server/services/{pi-auth-providers.js → omp-auth-providers.js} +2 -2
- package/src/server/services/{pi-channels.js → omp-channels.js} +10 -5
- package/src/server/services/{pi-config.js → omp-config.js} +47 -65
- package/src/server/services/{pi-sessions.js → omp-sessions.js} +20 -20
- package/src/server/services/{pi-settings-manager.js → omp-settings-manager.js} +422 -18
- package/src/server/services/{pi-statistics-service.js → omp-statistics-service.js} +2 -2
- package/src/server/services/plugins-service.js +122 -122
- package/src/server/services/prompts-service.js +20 -20
- package/src/server/services/proxy-log-helper.js +1 -1
- package/src/server/services/proxy-runtime.js +1 -1
- package/src/server/services/skill-service.js +7 -7
- package/src/server/services/speed-test.js +29 -29
- package/src/server/services/ui-config.js +3 -3
- package/src/server/services/workspace-service.js +8 -8
- package/src/server/websocket-server.js +4 -4
- package/src/shared/platforms.js +201 -0
- package/dist/web/assets/Home-DGGC8H4g.js +0 -1
- package/dist/web/assets/Home-ewgeIhF7.css +0 -1
- package/dist/web/assets/ProjectList-DyiGyT-H.js +0 -1
- package/dist/web/assets/index-CM26UrnJ.css +0 -1
- package/dist/web/assets/index-EQq56pRa.js +0 -2
package/src/commands/stats.js
CHANGED
|
@@ -3,13 +3,13 @@ const http = require('http');
|
|
|
3
3
|
const { loadConfig } = require('../config/loader');
|
|
4
4
|
const { normalizePlatformKey } = require('../shared/platforms');
|
|
5
5
|
|
|
6
|
-
const TOOL_TYPES = ['claude', 'codex', 'gemini', 'opencode', '
|
|
6
|
+
const TOOL_TYPES = ['claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
7
7
|
const TOOL_ENDPOINTS = {
|
|
8
8
|
claude: '/api/claude/statistics',
|
|
9
9
|
codex: '/api/codex/statistics',
|
|
10
10
|
gemini: '/api/gemini/statistics',
|
|
11
11
|
opencode: '/api/opencode/statistics',
|
|
12
|
-
|
|
12
|
+
omp: '/api/omp/statistics'
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -252,7 +252,7 @@ async function handleStats(type = null, options = {}) {
|
|
|
252
252
|
try {
|
|
253
253
|
if (!validateToolType(normalizedType)) {
|
|
254
254
|
console.error(chalk.red(`\n[ERROR] 无效的渠道类型: ${type}\n`));
|
|
255
|
-
console.log(chalk.gray('支持的类型: claude, codex, gemini, opencode,
|
|
255
|
+
console.log(chalk.gray('支持的类型: claude, codex, gemini, opencode, omp\n'));
|
|
256
256
|
process.exit(1);
|
|
257
257
|
}
|
|
258
258
|
|
|
@@ -320,7 +320,7 @@ function displayStats(stats) {
|
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
if (!type && stats.byToolType) {
|
|
323
|
-
const iconMap = { claude: '[*]', codex: '[*]', gemini: '[*]', opencode: '[*]',
|
|
323
|
+
const iconMap = { claude: '[*]', codex: '[*]', gemini: '[*]', opencode: '[*]', omp: '[*]' };
|
|
324
324
|
console.log(chalk.bold('\n[CH] 分渠道汇总:'));
|
|
325
325
|
TOOL_TYPES.forEach((toolType) => {
|
|
326
326
|
const item = stats.byToolType[toolType] || emptySummary();
|
|
@@ -343,7 +343,7 @@ function displayStats(stats) {
|
|
|
343
343
|
|
|
344
344
|
function getToolDisplayName(type) {
|
|
345
345
|
const normalizedType = normalizePlatformKey(type);
|
|
346
|
-
if (normalizedType === '
|
|
346
|
+
if (normalizedType === 'omp') return 'OMP';
|
|
347
347
|
return String(normalizedType || '').toUpperCase();
|
|
348
348
|
}
|
|
349
349
|
|
|
@@ -371,7 +371,7 @@ async function handleStatsExport(type = null, format = 'json') {
|
|
|
371
371
|
try {
|
|
372
372
|
if (!validateToolType(normalizedType)) {
|
|
373
373
|
console.error(chalk.red(`\n[ERROR] 无效的渠道类型: ${type}\n`));
|
|
374
|
-
console.log(chalk.gray('支持的类型: claude, codex, gemini, opencode,
|
|
374
|
+
console.log(chalk.gray('支持的类型: claude, codex, gemini, opencode, omp\n'));
|
|
375
375
|
process.exit(1);
|
|
376
376
|
}
|
|
377
377
|
|
|
@@ -45,14 +45,14 @@ function getProxyServices(cliType) {
|
|
|
45
45
|
stopProxyServer: stopOpenCodeProxyServer,
|
|
46
46
|
defaultPort: 20091
|
|
47
47
|
};
|
|
48
|
-
} else if (normalizedCliType === '
|
|
49
|
-
const {
|
|
48
|
+
} else if (normalizedCliType === 'omp') {
|
|
49
|
+
const { getOmpProxyStatus, startOmpProxyServer, stopOmpProxyServer } = require('../server/omp-proxy-server');
|
|
50
50
|
const config = loadConfig();
|
|
51
51
|
return {
|
|
52
|
-
getProxyStatus:
|
|
53
|
-
startProxyServer:
|
|
54
|
-
stopProxyServer:
|
|
55
|
-
defaultPort: config.ports?.
|
|
52
|
+
getProxyStatus: getOmpProxyStatus,
|
|
53
|
+
startProxyServer: startOmpProxyServer,
|
|
54
|
+
stopProxyServer: stopOmpProxyServer,
|
|
55
|
+
defaultPort: config.ports?.ompProxy || 20092,
|
|
56
56
|
managedProviderConfig: true
|
|
57
57
|
};
|
|
58
58
|
}
|
|
@@ -198,7 +198,7 @@ async function handleStartProxy(cliType, services) {
|
|
|
198
198
|
codex: 'Codex',
|
|
199
199
|
gemini: 'Gemini',
|
|
200
200
|
opencode: 'OpenCode',
|
|
201
|
-
|
|
201
|
+
omp: 'OMP'
|
|
202
202
|
};
|
|
203
203
|
const toolName = toolNameMap[cliType] || 'Claude Code';
|
|
204
204
|
const defaultPort = services.defaultPort;
|
|
@@ -316,7 +316,7 @@ async function handleStopProxy(cliType, services) {
|
|
|
316
316
|
codex: 'Codex',
|
|
317
317
|
gemini: 'Gemini',
|
|
318
318
|
opencode: 'OpenCode',
|
|
319
|
-
|
|
319
|
+
omp: 'OMP'
|
|
320
320
|
};
|
|
321
321
|
const toolName = toolNameMap[cliType] || 'Claude Code';
|
|
322
322
|
const proxyStatus = services.getProxyStatus();
|
package/src/commands/ui.js
CHANGED
|
@@ -19,6 +19,7 @@ async function handleUI() {
|
|
|
19
19
|
console.log(chalk.cyan.bold('\n[NET] 启动 Coding-Tool Web UI...\n'));
|
|
20
20
|
if (enableHost) {
|
|
21
21
|
console.log(chalk.yellow('[WARN] LAN 访问已启用 (--host)\n'));
|
|
22
|
+
console.log(chalk.yellow('[WARN] LAN 模式默认允许远程写操作,可设置 CC_TOOL_ALLOW_REMOTE_WRITE=false 禁止\n'));
|
|
22
23
|
}
|
|
23
24
|
if (enableHttps) {
|
|
24
25
|
console.log(chalk.yellow('[LOCK] 已启用本地 HTTPS 模式 (--https)\n'));
|
package/src/config/default.js
CHANGED
|
@@ -14,14 +14,14 @@ const DEFAULT_CONFIG = {
|
|
|
14
14
|
defaultProject: null,
|
|
15
15
|
maxDisplaySessions: 100,
|
|
16
16
|
pageSize: 15,
|
|
17
|
-
currentCliType: 'claude', // 当前CLI工具类型: claude, codex, gemini, opencode,
|
|
17
|
+
currentCliType: 'claude', // 当前CLI工具类型: claude, codex, gemini, opencode, omp
|
|
18
18
|
ports: {
|
|
19
19
|
webUI: 19999, // Web UI 页面端口 (同时用于 WebSocket)
|
|
20
20
|
proxy: 20088, // Claude 代理服务端口
|
|
21
21
|
codexProxy: 20089, // Codex 代理服务端口
|
|
22
22
|
geminiProxy: 20090, // Gemini 代理服务端口
|
|
23
23
|
opencodeProxy: 20091, // OpenCode 代理服务端口
|
|
24
|
-
|
|
24
|
+
ompProxy: 20092 // OMP 托管 provider 状态端口占位
|
|
25
25
|
},
|
|
26
26
|
maxLogs: 100,
|
|
27
27
|
statsInterval: 30,
|
|
@@ -73,7 +73,7 @@ const DEFAULT_CONFIG = {
|
|
|
73
73
|
cacheRead: 0.25,
|
|
74
74
|
models: {}
|
|
75
75
|
},
|
|
76
|
-
|
|
76
|
+
omp: {
|
|
77
77
|
mode: 'auto',
|
|
78
78
|
input: 2.5,
|
|
79
79
|
output: 15,
|
package/src/config/paths.js
CHANGED
|
@@ -392,8 +392,8 @@ const PATHS = {
|
|
|
392
392
|
forkRelations: path.join(CONFIG_DIR, 'fork-relations.json'),
|
|
393
393
|
opencodeProjectOrder: path.join(CONFIG_DIR, 'opencode-project-order.json'),
|
|
394
394
|
opencodeSessionOrder: path.join(CONFIG_DIR, 'opencode-session-order.json'),
|
|
395
|
-
|
|
396
|
-
|
|
395
|
+
ompProjectOrder: path.join(CONFIG_DIR, 'omp-project-order.json'),
|
|
396
|
+
ompSessionOrder: path.join(CONFIG_DIR, 'omp-session-order.json'),
|
|
397
397
|
|
|
398
398
|
// 渠道配置
|
|
399
399
|
channelsDir: CHANNELS_DIR,
|
|
@@ -402,7 +402,7 @@ const PATHS = {
|
|
|
402
402
|
codex: path.join(CHANNELS_DIR, 'codex.json'),
|
|
403
403
|
gemini: path.join(CHANNELS_DIR, 'gemini.json'),
|
|
404
404
|
opencode: path.join(CHANNELS_DIR, 'opencode.json'),
|
|
405
|
-
|
|
405
|
+
omp: path.join(CHANNELS_DIR, 'omp.json')
|
|
406
406
|
},
|
|
407
407
|
activeChannelDir: ACTIVE_CHANNELS_DIR,
|
|
408
408
|
activeChannel: {
|
|
@@ -410,7 +410,7 @@ const PATHS = {
|
|
|
410
410
|
codex: path.join(ACTIVE_CHANNELS_DIR, 'codex.json'),
|
|
411
411
|
gemini: path.join(ACTIVE_CHANNELS_DIR, 'gemini.json'),
|
|
412
412
|
opencode: path.join(ACTIVE_CHANNELS_DIR, 'opencode.json'),
|
|
413
|
-
|
|
413
|
+
omp: path.join(ACTIVE_CHANNELS_DIR, 'omp.json')
|
|
414
414
|
},
|
|
415
415
|
|
|
416
416
|
// 统计与日志快照
|
|
@@ -442,7 +442,7 @@ const PATHS = {
|
|
|
442
442
|
codex: path.join(RUNTIME_DIR, 'codex-proxy.json'),
|
|
443
443
|
gemini: path.join(RUNTIME_DIR, 'gemini-proxy.json'),
|
|
444
444
|
opencode: path.join(RUNTIME_DIR, 'opencode-proxy.json'),
|
|
445
|
-
|
|
445
|
+
omp: path.join(RUNTIME_DIR, 'omp-proxy.json')
|
|
446
446
|
},
|
|
447
447
|
|
|
448
448
|
// 请求记录
|
|
@@ -451,7 +451,7 @@ const PATHS = {
|
|
|
451
451
|
codex: path.join(REQUESTS_DIR, 'codex.jsonl'),
|
|
452
452
|
gemini: path.join(REQUESTS_DIR, 'gemini.jsonl'),
|
|
453
453
|
opencode: path.join(REQUESTS_DIR, 'opencode.jsonl'),
|
|
454
|
-
|
|
454
|
+
omp: path.join(REQUESTS_DIR, 'omp.jsonl')
|
|
455
455
|
},
|
|
456
456
|
claudeRequestTemplate: path.join(REQUESTS_DIR, 'claude-request-template.json'),
|
|
457
457
|
|
|
@@ -464,35 +464,35 @@ const PATHS = {
|
|
|
464
464
|
codex: path.join(LOCAL_SKILLS_DIR, 'codex'),
|
|
465
465
|
gemini: path.join(LOCAL_SKILLS_DIR, 'gemini'),
|
|
466
466
|
opencode: path.join(LOCAL_SKILLS_DIR, 'opencode'),
|
|
467
|
-
|
|
467
|
+
omp: path.join(LOCAL_SKILLS_DIR, 'omp')
|
|
468
468
|
},
|
|
469
469
|
skillRepos: {
|
|
470
470
|
claude: path.join(REPOS_SKILLS_DIR, 'claude.json'),
|
|
471
471
|
codex: path.join(REPOS_SKILLS_DIR, 'codex.json'),
|
|
472
472
|
gemini: path.join(REPOS_SKILLS_DIR, 'gemini.json'),
|
|
473
473
|
opencode: path.join(REPOS_SKILLS_DIR, 'opencode.json'),
|
|
474
|
-
|
|
474
|
+
omp: path.join(REPOS_SKILLS_DIR, 'omp.json')
|
|
475
475
|
},
|
|
476
476
|
skillCaches: {
|
|
477
477
|
claude: path.join(CACHE_SKILLS_DIR, 'claude.json'),
|
|
478
478
|
codex: path.join(CACHE_SKILLS_DIR, 'codex.json'),
|
|
479
479
|
gemini: path.join(CACHE_SKILLS_DIR, 'gemini.json'),
|
|
480
480
|
opencode: path.join(CACHE_SKILLS_DIR, 'opencode.json'),
|
|
481
|
-
|
|
481
|
+
omp: path.join(CACHE_SKILLS_DIR, 'omp.json')
|
|
482
482
|
},
|
|
483
483
|
pluginRepos: {
|
|
484
484
|
claude: path.join(REPOS_PLUGINS_DIR, 'claude.json'),
|
|
485
485
|
codex: path.join(REPOS_PLUGINS_DIR, 'codex.json'),
|
|
486
486
|
gemini: path.join(REPOS_PLUGINS_DIR, 'gemini.json'),
|
|
487
487
|
opencode: path.join(REPOS_PLUGINS_DIR, 'opencode.json'),
|
|
488
|
-
|
|
488
|
+
omp: path.join(REPOS_PLUGINS_DIR, 'omp.json')
|
|
489
489
|
},
|
|
490
490
|
pluginMarketCache: {
|
|
491
491
|
claude: path.join(CACHE_PLUGINS_DIR, 'claude-market.json'),
|
|
492
492
|
codex: path.join(CACHE_PLUGINS_DIR, 'codex-market.json'),
|
|
493
493
|
gemini: path.join(CACHE_PLUGINS_DIR, 'gemini-market.json'),
|
|
494
494
|
opencode: path.join(CACHE_PLUGINS_DIR, 'opencode-market.json'),
|
|
495
|
-
|
|
495
|
+
omp: path.join(CACHE_PLUGINS_DIR, 'omp-market.json')
|
|
496
496
|
},
|
|
497
497
|
|
|
498
498
|
// 原生路径兼容
|
|
@@ -532,20 +532,20 @@ const LEGACY_STORAGE_RELOCATIONS = [
|
|
|
532
532
|
{ source: rootEntry('fork-relations.json'), target: PATHS.forkRelations },
|
|
533
533
|
{ source: rootEntry('opencode-project-order.json'), target: PATHS.opencodeProjectOrder },
|
|
534
534
|
{ source: rootEntry('opencode-session-order.json'), target: PATHS.opencodeSessionOrder },
|
|
535
|
-
{ source: rootEntry('
|
|
536
|
-
{ source: rootEntry('
|
|
535
|
+
{ source: rootEntry('omp-project-order.json'), target: PATHS.ompProjectOrder },
|
|
536
|
+
{ source: rootEntry('omp-session-order.json'), target: PATHS.ompSessionOrder },
|
|
537
537
|
|
|
538
538
|
// 渠道相关
|
|
539
539
|
{ source: rootEntry('channels.json'), target: PATHS.channels.claude },
|
|
540
540
|
{ source: rootEntry('codex-channels.json'), target: PATHS.channels.codex },
|
|
541
541
|
{ source: rootEntry('gemini-channels.json'), target: PATHS.channels.gemini },
|
|
542
542
|
{ source: rootEntry('opencode-channels.json'), target: PATHS.channels.opencode },
|
|
543
|
-
{ source: rootEntry('
|
|
543
|
+
{ source: rootEntry('omp-channels.json'), target: PATHS.channels.omp },
|
|
544
544
|
{ source: rootEntry('active-channel.json'), target: PATHS.activeChannel.claude },
|
|
545
545
|
{ source: rootEntry('codex-active-channel.json'), target: PATHS.activeChannel.codex },
|
|
546
546
|
{ source: rootEntry('gemini-active-channel.json'), target: PATHS.activeChannel.gemini },
|
|
547
547
|
{ source: rootEntry('opencode-active-channel.json'), target: PATHS.activeChannel.opencode },
|
|
548
|
-
{ source: rootEntry('
|
|
548
|
+
{ source: rootEntry('omp-active-channel.json'), target: PATHS.activeChannel.omp },
|
|
549
549
|
|
|
550
550
|
// 统计与日志
|
|
551
551
|
{ source: rootEntry('statistics.json'), target: PATHS.statistics.summary },
|
|
@@ -568,14 +568,14 @@ const LEGACY_STORAGE_RELOCATIONS = [
|
|
|
568
568
|
{ source: rootEntry('codex-proxy-runtime.json'), target: PATHS.proxyRuntime.codex },
|
|
569
569
|
{ source: rootEntry('gemini-proxy-runtime.json'), target: PATHS.proxyRuntime.gemini },
|
|
570
570
|
{ source: rootEntry('opencode-proxy-runtime.json'), target: PATHS.proxyRuntime.opencode },
|
|
571
|
-
{ source: rootEntry('
|
|
571
|
+
{ source: rootEntry('omp-proxy-runtime.json'), target: PATHS.proxyRuntime.omp },
|
|
572
572
|
{ source: rootEntry('notify-hook.js'), target: PATHS.notifyHook },
|
|
573
573
|
{ source: rootEntry('claude-request-template.json'), target: PATHS.claudeRequestTemplate },
|
|
574
574
|
{ source: rootEntry('claude-requests.jsonl'), target: PATHS.requestSnapshots.claude },
|
|
575
575
|
{ source: rootEntry('codex-requests.jsonl'), target: PATHS.requestSnapshots.codex },
|
|
576
576
|
{ source: rootEntry('gemini-requests.jsonl'), target: PATHS.requestSnapshots.gemini },
|
|
577
577
|
{ source: rootEntry('opencode-requests.jsonl'), target: PATHS.requestSnapshots.opencode },
|
|
578
|
-
{ source: rootEntry('
|
|
578
|
+
{ source: rootEntry('omp-requests.jsonl'), target: PATHS.requestSnapshots.omp },
|
|
579
579
|
|
|
580
580
|
// 备份
|
|
581
581
|
{ source: rootEntry('env-backups'), target: PATHS.envBackups },
|
|
@@ -585,29 +585,29 @@ const LEGACY_STORAGE_RELOCATIONS = [
|
|
|
585
585
|
{ source: rootEntry('codex-skills'), target: PATHS.localSkills.codex },
|
|
586
586
|
{ source: rootEntry('gemini-skills'), target: PATHS.localSkills.gemini },
|
|
587
587
|
{ source: rootEntry('opencode-skills'), target: PATHS.localSkills.opencode },
|
|
588
|
-
{ source: rootEntry('
|
|
588
|
+
{ source: rootEntry('omp-skills'), target: PATHS.localSkills.omp },
|
|
589
589
|
{ source: rootEntry('skill-repos.json'), target: PATHS.skillRepos.claude },
|
|
590
590
|
{ source: rootEntry('codex-skill-repos.json'), target: PATHS.skillRepos.codex },
|
|
591
591
|
{ source: rootEntry('gemini-skill-repos.json'), target: PATHS.skillRepos.gemini },
|
|
592
592
|
{ source: rootEntry('opencode-skill-repos.json'), target: PATHS.skillRepos.opencode },
|
|
593
|
-
{ source: rootEntry('
|
|
593
|
+
{ source: rootEntry('omp-skill-repos.json'), target: PATHS.skillRepos.omp },
|
|
594
594
|
{ source: rootEntry('skills-cache.json'), target: PATHS.skillCaches.claude },
|
|
595
595
|
{ source: rootEntry('codex-skills-cache.json'), target: PATHS.skillCaches.codex },
|
|
596
596
|
{ source: rootEntry('gemini-skills-cache.json'), target: PATHS.skillCaches.gemini },
|
|
597
597
|
{ source: rootEntry('opencode-skills-cache.json'), target: PATHS.skillCaches.opencode },
|
|
598
|
-
{ source: rootEntry('
|
|
598
|
+
{ source: rootEntry('omp-skills-cache.json'), target: PATHS.skillCaches.omp },
|
|
599
599
|
|
|
600
600
|
// 插件仓库缓存
|
|
601
601
|
{ source: rootEntry('plugin-repos.json'), target: PATHS.pluginRepos.claude },
|
|
602
602
|
{ source: rootEntry('codex-plugin-repos.json'), target: PATHS.pluginRepos.codex },
|
|
603
603
|
{ source: rootEntry('gemini-plugin-repos.json'), target: PATHS.pluginRepos.gemini },
|
|
604
604
|
{ source: rootEntry('opencode-plugin-repos.json'), target: PATHS.pluginRepos.opencode },
|
|
605
|
-
{ source: rootEntry('
|
|
605
|
+
{ source: rootEntry('omp-plugin-repos.json'), target: PATHS.pluginRepos.omp },
|
|
606
606
|
{ source: rootEntry('plugins-market-cache.json'), target: PATHS.pluginMarketCache.claude },
|
|
607
607
|
{ source: rootEntry('codex-plugins-market-cache.json'), target: PATHS.pluginMarketCache.codex },
|
|
608
608
|
{ source: rootEntry('gemini-plugins-market-cache.json'), target: PATHS.pluginMarketCache.gemini },
|
|
609
609
|
{ source: rootEntry('opencode-plugins-market-cache.json'), target: PATHS.pluginMarketCache.opencode },
|
|
610
|
-
{ source: rootEntry('
|
|
610
|
+
{ source: rootEntry('omp-plugins-market-cache.json'), target: PATHS.pluginMarketCache.omp },
|
|
611
611
|
|
|
612
612
|
// 已废弃但需要保留的数据
|
|
613
613
|
{ source: rootEntry('oauth-tokens.json'), target: PATHS.legacy.oauthTokens }
|
|
@@ -803,18 +803,15 @@ function normalizeOmpProfileName(profile = '') {
|
|
|
803
803
|
}
|
|
804
804
|
|
|
805
805
|
function getOmpProfileName() {
|
|
806
|
-
|
|
807
|
-
return normalizeOmpProfileName(process.env.OMP_PROFILE);
|
|
808
|
-
}
|
|
809
|
-
return normalizeOmpProfileName(process.env.PI_PROFILE);
|
|
806
|
+
return normalizeOmpProfileName(process.env.OMP_PROFILE);
|
|
810
807
|
}
|
|
811
808
|
|
|
812
809
|
function getOmpConfigRoot() {
|
|
813
|
-
return expandHomePath(resolveExistingEnvPath(process.env.
|
|
810
|
+
return expandHomePath(resolveExistingEnvPath(process.env.OMP_CONFIG_DIR) || path.join(HOME_DIR, '.omp'));
|
|
814
811
|
}
|
|
815
812
|
|
|
816
|
-
function
|
|
817
|
-
const configuredDir = resolveExistingEnvPath(process.env.
|
|
813
|
+
function getOmpAgentDir() {
|
|
814
|
+
const configuredDir = resolveExistingEnvPath(process.env.OMP_CODING_AGENT_DIR);
|
|
818
815
|
if (configuredDir) {
|
|
819
816
|
return path.resolve(expandHomePath(configuredDir));
|
|
820
817
|
}
|
|
@@ -876,25 +873,25 @@ const NATIVE_PATHS = {
|
|
|
876
873
|
auth: path.join(getOpenCodeDataDir(), 'auth.json')
|
|
877
874
|
},
|
|
878
875
|
|
|
879
|
-
// OMP
|
|
880
|
-
|
|
881
|
-
dir:
|
|
882
|
-
config: path.join(
|
|
883
|
-
settings: path.join(
|
|
884
|
-
settingsJsonLegacy: path.join(
|
|
885
|
-
auth: path.join(
|
|
886
|
-
models: path.join(
|
|
887
|
-
modelsYml: path.join(
|
|
888
|
-
modelsJsonLegacy: path.join(
|
|
889
|
-
mcp: path.join(
|
|
890
|
-
sessions: path.join(
|
|
891
|
-
skills: path.join(
|
|
892
|
-
prompts: path.join(
|
|
893
|
-
commands: path.join(
|
|
894
|
-
notes: path.join(
|
|
895
|
-
extensions: path.join(
|
|
896
|
-
themes: path.join(
|
|
897
|
-
packages: path.join(
|
|
876
|
+
// OMP 原生配置。
|
|
877
|
+
omp: {
|
|
878
|
+
dir: getOmpAgentDir(),
|
|
879
|
+
config: path.join(getOmpAgentDir(), 'config.yml'),
|
|
880
|
+
settings: path.join(getOmpAgentDir(), 'config.yml'),
|
|
881
|
+
settingsJsonLegacy: path.join(getOmpAgentDir(), 'settings.json'),
|
|
882
|
+
auth: path.join(getOmpAgentDir(), 'auth.json'),
|
|
883
|
+
models: path.join(getOmpAgentDir(), 'models.yml'),
|
|
884
|
+
modelsYml: path.join(getOmpAgentDir(), 'models.yml'),
|
|
885
|
+
modelsJsonLegacy: path.join(getOmpAgentDir(), 'models.json'),
|
|
886
|
+
mcp: path.join(getOmpAgentDir(), 'mcp.json'),
|
|
887
|
+
sessions: path.join(getOmpAgentDir(), 'sessions'),
|
|
888
|
+
skills: path.join(getOmpAgentDir(), 'skills'),
|
|
889
|
+
prompts: path.join(getOmpAgentDir(), 'prompts'),
|
|
890
|
+
commands: path.join(getOmpAgentDir(), 'commands'),
|
|
891
|
+
notes: path.join(getOmpAgentDir(), 'notes'),
|
|
892
|
+
extensions: path.join(getOmpAgentDir(), 'extensions'),
|
|
893
|
+
themes: path.join(getOmpAgentDir(), 'themes'),
|
|
894
|
+
packages: path.join(getOmpAgentDir(), 'packages')
|
|
898
895
|
}
|
|
899
896
|
};
|
|
900
897
|
|
|
@@ -915,5 +912,5 @@ module.exports = {
|
|
|
915
912
|
getGeminiDir,
|
|
916
913
|
getOpenCodeDataDir,
|
|
917
914
|
getOpenCodeConfigDir,
|
|
918
|
-
|
|
915
|
+
getOmpAgentDir
|
|
919
916
|
};
|
package/src/index.js
CHANGED
|
@@ -53,12 +53,13 @@ function showHelp() {
|
|
|
53
53
|
console.log(chalk.yellow('[UI] UI 管理:'));
|
|
54
54
|
console.log(' ctx ui 前台启动 Web UI(仅本地访问)');
|
|
55
55
|
console.log(' ctx ui --https 前台启动 Web UI(本地 HTTPS)');
|
|
56
|
-
console.log(' ctx ui --host 前台启动 Web UI(允许 LAN
|
|
56
|
+
console.log(' ctx ui --host 前台启动 Web UI(允许 LAN 访问,默认允许远程写操作)');
|
|
57
57
|
console.log(' ctx ui start 后台启动 Web UI');
|
|
58
58
|
console.log(' ctx ui start --https 后台启动 Web UI(本地 HTTPS)');
|
|
59
|
-
console.log(' ctx ui start --host 后台启动 Web UI(允许 LAN
|
|
59
|
+
console.log(' ctx ui start --host 后台启动 Web UI(允许 LAN 访问,默认允许远程写操作)');
|
|
60
60
|
console.log(' ctx ui stop 停止 Web UI');
|
|
61
61
|
console.log(' ctx ui restart 重启 Web UI\n');
|
|
62
|
+
console.log(chalk.gray(' 提示: 如需禁止 LAN 远程写操作,可设置 CC_TOOL_ALLOW_REMOTE_WRITE=false\n'));
|
|
62
63
|
|
|
63
64
|
console.log(chalk.yellow('[PROXY] 代理管理:'));
|
|
64
65
|
console.log(' ctx claude start 启动 Claude 代理');
|
|
@@ -67,9 +68,8 @@ function showHelp() {
|
|
|
67
68
|
console.log(' ctx codex start 启动 Codex 代理');
|
|
68
69
|
console.log(' ctx gemini start 启动 Gemini 代理');
|
|
69
70
|
console.log(' ctx opencode start 启动 OpenCode 代理');
|
|
70
|
-
console.log(' ctx
|
|
71
|
-
console.log('
|
|
72
|
-
console.log(chalk.gray(' (codex/gemini/opencode/pi/omp 命令与 claude 类似)\n'));
|
|
71
|
+
console.log(' ctx omp start 启用 OMP 受管模型配置');
|
|
72
|
+
console.log(chalk.gray(' (codex/gemini/opencode/omp 命令与 claude 类似)\n'));
|
|
73
73
|
|
|
74
74
|
console.log(chalk.yellow('[LOG] 日志管理:'));
|
|
75
75
|
console.log(' ctx logs 查看所有日志');
|
|
@@ -265,8 +265,8 @@ async function main() {
|
|
|
265
265
|
return;
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
-
// claude/codex/gemini/opencode/
|
|
269
|
-
const channels = ['claude', 'codex', 'gemini', 'opencode', '
|
|
268
|
+
// claude/codex/gemini/opencode/omp 代理管理命令
|
|
269
|
+
const channels = ['claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
270
270
|
const normalizedChannel = normalizePlatformKey(args[0]);
|
|
271
271
|
if (channels.includes(normalizedChannel)) {
|
|
272
272
|
const channel = String(args[0] || '').trim().toLowerCase();
|
|
@@ -9,7 +9,7 @@ const { CommandsService } = require('../services/commands-service');
|
|
|
9
9
|
const { sendApiError } = require('./validation-errors');
|
|
10
10
|
|
|
11
11
|
const router = express.Router();
|
|
12
|
-
const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', '
|
|
12
|
+
const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
13
13
|
const commandServices = new Map();
|
|
14
14
|
|
|
15
15
|
function resolvePlatform(rawPlatform) {
|
|
@@ -26,7 +26,7 @@ function resolveChannelsByType(exportData) {
|
|
|
26
26
|
codex: Array.isArray(typed.codex) ? typed.codex : [],
|
|
27
27
|
gemini: Array.isArray(typed.gemini) ? typed.gemini : [],
|
|
28
28
|
opencode: Array.isArray(typed.opencode) ? typed.opencode : [],
|
|
29
|
-
|
|
29
|
+
omp: Array.isArray(typed.omp) ? typed.omp: []
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -46,7 +46,7 @@ function buildPreviewSummary(data) {
|
|
|
46
46
|
...channelsByType.codex.map(c => ({ ...c, type: c.type || 'codex' })),
|
|
47
47
|
...channelsByType.gemini.map(c => ({ ...c, type: c.type || 'gemini' })),
|
|
48
48
|
...channelsByType.opencode.map(c => ({ ...c, type: c.type || 'opencode' })),
|
|
49
|
-
...channelsByType.
|
|
49
|
+
...channelsByType.omp.map(c => ({ ...c, type: c.type || 'omp' }))
|
|
50
50
|
];
|
|
51
51
|
|
|
52
52
|
return {
|
|
@@ -48,7 +48,7 @@ const PLATFORM_SYNC_METHODS = {
|
|
|
48
48
|
codex: { sync: 'syncToCodex', remove: 'removeFromCodex' },
|
|
49
49
|
gemini: { sync: 'syncToGemini', remove: 'removeFromGemini' },
|
|
50
50
|
opencode: { sync: 'syncToOpenCode', remove: 'removeFromOpenCode' },
|
|
51
|
-
|
|
51
|
+
omp: { sync: 'syncToOmp', remove: 'removeFromOmp' }
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
function syncPlatform(type, name, platform) {
|
package/src/server/api/config.js
CHANGED
|
@@ -409,7 +409,7 @@ router.get('/advanced', (req, res) => {
|
|
|
409
409
|
codexProxy: config.ports?.codexProxy || 20089,
|
|
410
410
|
geminiProxy: config.ports?.geminiProxy || 20090,
|
|
411
411
|
opencodeProxy: config.ports?.opencodeProxy || 20091,
|
|
412
|
-
|
|
412
|
+
ompProxy: config.ports?.ompProxy || 20092
|
|
413
413
|
},
|
|
414
414
|
maxLogs: config.maxLogs || 100,
|
|
415
415
|
statsInterval: config.statsInterval || 30,
|
|
@@ -10,25 +10,25 @@ const { getProxyStatus } = require('../proxy-server');
|
|
|
10
10
|
const { getCodexProxyStatus } = require('../codex-proxy-server');
|
|
11
11
|
const { getGeminiProxyStatus } = require('../gemini-proxy-server');
|
|
12
12
|
const { getOpenCodeProxyStatus } = require('../opencode-proxy-server');
|
|
13
|
-
const {
|
|
13
|
+
const { getOmpProxyStatus } = require('../omp-proxy-server');
|
|
14
14
|
const { getProjectAndSessionCounts: getClaudeCounts } = require('../services/sessions');
|
|
15
15
|
const { getProjectAndSessionCounts: getCodexCounts } = require('../services/codex-sessions');
|
|
16
16
|
const { getProjectAndSessionCounts: getGeminiCounts } = require('../services/gemini-sessions');
|
|
17
17
|
const { getProjectAndSessionCounts: getOpenCodeCounts } = require('../services/opencode-sessions');
|
|
18
|
-
const { getProjectAndSessionCounts:
|
|
18
|
+
const { getProjectAndSessionCounts: getOmpCounts } = require('../services/omp-sessions');
|
|
19
19
|
|
|
20
20
|
// Channel-specific services
|
|
21
21
|
const { getChannels: getCodexChannels } = require('../services/codex-channels');
|
|
22
22
|
const { getChannels: getGeminiChannels } = require('../services/gemini-channels');
|
|
23
23
|
const { getChannels: getOpenCodeChannels } = require('../services/opencode-channels');
|
|
24
|
-
const { getChannels:
|
|
24
|
+
const { getChannels: getOmpChannels } = require('../services/omp-channels');
|
|
25
25
|
|
|
26
26
|
// Statistics
|
|
27
27
|
const { getTodayStatistics: getClaudeTodayStatistics } = require('../services/claude-statistics-service');
|
|
28
28
|
const { getTodayStatistics: getCodexTodayStatistics } = require('../services/codex-statistics-service');
|
|
29
29
|
const { getTodayStatistics: getGeminiTodayStatistics } = require('../services/gemini-statistics-service');
|
|
30
30
|
const { getTodayStatistics: getOpenCodeTodayStatistics } = require('../services/opencode-statistics-service');
|
|
31
|
-
const { getTodayStatistics:
|
|
31
|
+
const { getTodayStatistics: getOmpTodayStatistics } = require('../services/omp-statistics-service');
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* GET /api/dashboard/init
|
|
@@ -46,22 +46,22 @@ router.get('/init', async (req, res) => {
|
|
|
46
46
|
codexChannels,
|
|
47
47
|
geminiChannels,
|
|
48
48
|
opencodeChannels,
|
|
49
|
-
|
|
49
|
+
ompChannels,
|
|
50
50
|
claudeProxyStatus,
|
|
51
51
|
codexProxyStatus,
|
|
52
52
|
geminiProxyStatus,
|
|
53
53
|
opencodeProxyStatus,
|
|
54
|
-
|
|
54
|
+
ompProxyStatus,
|
|
55
55
|
claudeTodayStats,
|
|
56
56
|
codexTodayStats,
|
|
57
57
|
geminiTodayStats,
|
|
58
58
|
opencodeTodayStats,
|
|
59
|
-
|
|
59
|
+
ompTodayStats,
|
|
60
60
|
claudeCounts,
|
|
61
61
|
codexCounts,
|
|
62
62
|
geminiCounts,
|
|
63
63
|
opencodeCounts,
|
|
64
|
-
|
|
64
|
+
ompCounts
|
|
65
65
|
] = await Promise.all([
|
|
66
66
|
// UI Config
|
|
67
67
|
Promise.resolve(loadUIConfig()),
|
|
@@ -74,28 +74,28 @@ router.get('/init', async (req, res) => {
|
|
|
74
74
|
Promise.resolve(getCodexChannels()),
|
|
75
75
|
Promise.resolve(getGeminiChannels()),
|
|
76
76
|
Promise.resolve(getOpenCodeChannels()),
|
|
77
|
-
Promise.resolve(
|
|
77
|
+
Promise.resolve(getOmpChannels()),
|
|
78
78
|
|
|
79
79
|
// Proxy Status
|
|
80
80
|
Promise.resolve(getProxyStatus()),
|
|
81
81
|
Promise.resolve(getCodexProxyStatus()),
|
|
82
82
|
Promise.resolve(getGeminiProxyStatus()),
|
|
83
83
|
Promise.resolve(getOpenCodeProxyStatus()),
|
|
84
|
-
Promise.resolve(
|
|
84
|
+
Promise.resolve(getOmpProxyStatus()),
|
|
85
85
|
|
|
86
86
|
// Today Stats (所有平台)
|
|
87
87
|
Promise.resolve(getClaudeTodayStatistics()),
|
|
88
88
|
Promise.resolve(getCodexTodayStatistics()),
|
|
89
89
|
Promise.resolve(getGeminiTodayStatistics()),
|
|
90
90
|
Promise.resolve(getOpenCodeTodayStatistics()),
|
|
91
|
-
Promise.resolve(
|
|
91
|
+
Promise.resolve(getOmpTodayStatistics()),
|
|
92
92
|
|
|
93
93
|
// 轻量级统计
|
|
94
94
|
Promise.resolve(getClaudeCounts(config)),
|
|
95
95
|
Promise.resolve(getCodexCounts()),
|
|
96
96
|
Promise.resolve(getGeminiCounts()),
|
|
97
97
|
Promise.resolve(getOpenCodeCounts()),
|
|
98
|
-
Promise.resolve(
|
|
98
|
+
Promise.resolve(getOmpCounts())
|
|
99
99
|
]);
|
|
100
100
|
|
|
101
101
|
// 格式化统计数据:取 summary 和 byModel 中的数据
|
|
@@ -121,28 +121,28 @@ router.get('/init', async (req, res) => {
|
|
|
121
121
|
codex: codexChannels,
|
|
122
122
|
gemini: geminiChannels,
|
|
123
123
|
opencode: opencodeChannels.channels || [],
|
|
124
|
-
|
|
124
|
+
omp: ompChannels.channels || []
|
|
125
125
|
},
|
|
126
126
|
proxyStatus: {
|
|
127
127
|
claude: claudeProxyStatus,
|
|
128
128
|
codex: codexProxyStatus,
|
|
129
129
|
gemini: geminiProxyStatus,
|
|
130
130
|
opencode: opencodeProxyStatus,
|
|
131
|
-
|
|
131
|
+
omp: ompProxyStatus
|
|
132
132
|
},
|
|
133
133
|
counts: {
|
|
134
134
|
claude: claudeCounts || { projectCount: 0, sessionCount: 0 },
|
|
135
135
|
codex: codexCounts || { projectCount: 0, sessionCount: 0 },
|
|
136
136
|
gemini: geminiCounts || { projectCount: 0, sessionCount: 0 },
|
|
137
137
|
opencode: opencodeCounts || { projectCount: 0, sessionCount: 0 },
|
|
138
|
-
|
|
138
|
+
omp: ompCounts || { projectCount: 0, sessionCount: 0 }
|
|
139
139
|
},
|
|
140
140
|
todayStats: {
|
|
141
141
|
claude: formatStats(claudeTodayStats),
|
|
142
142
|
codex: formatStats(codexTodayStats),
|
|
143
143
|
gemini: formatStats(geminiTodayStats),
|
|
144
144
|
opencode: formatStats(opencodeTodayStats),
|
|
145
|
-
|
|
145
|
+
omp: formatStats(ompTodayStats)
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
});
|
package/src/server/api/mcp.js
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
const express = require('express');
|
|
6
6
|
const router = express.Router();
|
|
7
7
|
const mcpService = require('../services/mcp-service');
|
|
8
|
-
const MCP_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', '
|
|
9
|
-
const MCP_EXPORT_FORMATS = ['json', 'claude', 'codex', 'gemini', 'opencode', '
|
|
8
|
+
const MCP_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
9
|
+
const MCP_EXPORT_FORMATS = ['json', 'claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* GET /api/mcp/servers
|
|
@@ -58,6 +58,15 @@ function broadcastToolProxyState(tool) {
|
|
|
58
58
|
const channels = getChannels().channels || [];
|
|
59
59
|
const activeChannel = channels.find(ch => ch.enabled !== false) || null;
|
|
60
60
|
broadcastProxyState('opencode', getOpenCodeProxyStatus(), activeChannel, channels);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (tool === 'omp') {
|
|
65
|
+
const { getOmpProxyStatus } = require('../omp-proxy-server');
|
|
66
|
+
const { getChannels } = require('../services/omp-channels');
|
|
67
|
+
const channels = getChannels().channels || [];
|
|
68
|
+
const activeChannel = channels.find(ch => ch.enabled !== false) || null;
|
|
69
|
+
broadcastProxyState('omp', getOmpProxyStatus(), activeChannel, channels);
|
|
61
70
|
}
|
|
62
71
|
}
|
|
63
72
|
|
|
@@ -120,7 +129,9 @@ router.post('/:tool/:credentialId/apply', async (req, res) => {
|
|
|
120
129
|
broadcastToolProxyState(tool);
|
|
121
130
|
const message = tool === 'opencode'
|
|
122
131
|
? 'opencode 已应用 OAuth 凭证,并保留现有 API providers'
|
|
123
|
-
:
|
|
132
|
+
: tool === 'omp'
|
|
133
|
+
? 'OMP 已应用 OAuth 凭证,并保留现有 OMP provider 渠道'
|
|
134
|
+
: `${tool} 已切换到 OAuth 凭证控制`;
|
|
124
135
|
res.json({
|
|
125
136
|
tool,
|
|
126
137
|
...result,
|
|
@@ -142,7 +153,9 @@ router.post('/:tool/:credentialId/disable-native', (req, res) => {
|
|
|
142
153
|
...result,
|
|
143
154
|
message: tool === 'opencode'
|
|
144
155
|
? 'opencode OAuth provider 已关闭'
|
|
145
|
-
:
|
|
156
|
+
: tool === 'omp'
|
|
157
|
+
? 'OMP OAuth provider 已关闭'
|
|
158
|
+
: `${tool} 本机 OAuth 已关闭`
|
|
146
159
|
});
|
|
147
160
|
} catch (error) {
|
|
148
161
|
res.status(error.statusCode || 500).json({ error: error.message });
|