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
|
@@ -10,7 +10,7 @@ const { maskToken } = require('../services/oauth-utils');
|
|
|
10
10
|
const { sendApiError } = require('./validation-errors');
|
|
11
11
|
|
|
12
12
|
const router = express.Router();
|
|
13
|
-
const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', '
|
|
13
|
+
const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
14
14
|
const pluginServices = new Map();
|
|
15
15
|
|
|
16
16
|
function resolvePlatform(rawPlatform) {
|
package/src/server/api/skills.js
CHANGED
|
@@ -8,7 +8,7 @@ const { maskToken } = require('../services/oauth-utils');
|
|
|
8
8
|
const { sendApiError } = require('./validation-errors');
|
|
9
9
|
|
|
10
10
|
const router = express.Router();
|
|
11
|
-
const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', '
|
|
11
|
+
const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
12
12
|
const skillServices = new Map();
|
|
13
13
|
|
|
14
14
|
function resolvePlatform(rawPlatform) {
|
|
@@ -411,7 +411,7 @@ router.delete('/:id/projects/:projectName', (req, res) => {
|
|
|
411
411
|
/**
|
|
412
412
|
* POST /api/workspaces/:id/launch
|
|
413
413
|
* 获取在工作区启动 CLI 工具的命令
|
|
414
|
-
* Body: { tool: 'claude' | 'codex' | 'gemini' | 'opencode' | '
|
|
414
|
+
* Body: { tool: 'claude' | 'codex' | 'gemini' | 'opencode' | 'omp' | 'omp', projectName?: string }
|
|
415
415
|
*/
|
|
416
416
|
router.post('/:id/launch', (req, res) => {
|
|
417
417
|
try {
|
package/src/server/index.js
CHANGED
|
@@ -23,8 +23,11 @@ const { startProxyServer } = require('./proxy-server');
|
|
|
23
23
|
const { startCodexProxyServer } = require('./codex-proxy-server');
|
|
24
24
|
const { startGeminiProxyServer } = require('./gemini-proxy-server');
|
|
25
25
|
const { startOpenCodeProxyServer, collectProxyModelList } = require('./opencode-proxy-server');
|
|
26
|
-
const {
|
|
27
|
-
const {
|
|
26
|
+
const { startOmpProxyServer } = require('./omp-proxy-server');
|
|
27
|
+
const {
|
|
28
|
+
createRemoteMutationGuard,
|
|
29
|
+
isRemoteMutationAllowedByEnv
|
|
30
|
+
} = require('./services/network-access');
|
|
28
31
|
const { createApiRequestLogger } = require('./services/request-logger');
|
|
29
32
|
const { inspectWebBuildState, ensureWebDistReady } = require('./services/web-build');
|
|
30
33
|
const { ensureHttpsCredentials } = require('./services/https-cert');
|
|
@@ -151,7 +154,7 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
|
|
|
151
154
|
const app = express();
|
|
152
155
|
const useHttps = options.useHttps === true || process.argv.includes('--https');
|
|
153
156
|
const lanMode = host === '0.0.0.0';
|
|
154
|
-
const allowRemoteMutation = process.env
|
|
157
|
+
const allowRemoteMutation = isRemoteMutationAllowedByEnv(process.env);
|
|
155
158
|
|
|
156
159
|
// Middleware
|
|
157
160
|
app.use(express.json({ limit: '100mb' }));
|
|
@@ -175,7 +178,7 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
|
|
|
175
178
|
app.use('/api', createRemoteMutationGuard({
|
|
176
179
|
enabled: true,
|
|
177
180
|
allowRemoteMutation,
|
|
178
|
-
message: '
|
|
181
|
+
message: 'LAN 模式下远程写操作已被 CC_TOOL_ALLOW_REMOTE_WRITE=false 禁止。'
|
|
179
182
|
}));
|
|
180
183
|
|
|
181
184
|
}
|
|
@@ -203,12 +206,12 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
|
|
|
203
206
|
app.use('/api/opencode/statistics', require('./api/opencode-statistics'));
|
|
204
207
|
|
|
205
208
|
// OMP API Routes
|
|
206
|
-
app.use('/api/
|
|
207
|
-
app.use('/api/
|
|
208
|
-
app.use('/api/
|
|
209
|
-
app.use('/api/
|
|
210
|
-
app.use('/api/
|
|
211
|
-
app.use('/api/
|
|
209
|
+
app.use('/api/omp/projects', require('./api/omp-projects')(config));
|
|
210
|
+
app.use('/api/omp/sessions', require('./api/omp-sessions')(config));
|
|
211
|
+
app.use('/api/omp/channels', require('./api/omp-channels')(config));
|
|
212
|
+
app.use('/api/omp/proxy', require('./api/omp-proxy'));
|
|
213
|
+
app.use('/api/omp/statistics', require('./api/omp-statistics'));
|
|
214
|
+
app.use('/api/omp/config', require('./api/omp-config'));
|
|
212
215
|
|
|
213
216
|
app.use('/api/aliases', require('./api/aliases')());
|
|
214
217
|
app.use('/api/favorites', require('./api/favorites'));
|
|
@@ -325,8 +328,13 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
|
|
|
325
328
|
console.log(chalk.gray(' [TIP] 首次访问自签名证书时,浏览器可能会提示手动信任本地证书'));
|
|
326
329
|
}
|
|
327
330
|
|
|
328
|
-
if (host === '0.0.0.0'
|
|
329
|
-
|
|
331
|
+
if (host === '0.0.0.0') {
|
|
332
|
+
if (allowRemoteMutation) {
|
|
333
|
+
console.log(chalk.yellow(' [WARN] LAN 远程写操作已启用(默认行为)'));
|
|
334
|
+
console.log(chalk.gray(' 如需禁止,请设置 CC_TOOL_ALLOW_REMOTE_WRITE=false'));
|
|
335
|
+
} else {
|
|
336
|
+
console.log(chalk.yellow(' [LOCK] 已启用 LAN 安全保护:远程写操作被 CC_TOOL_ALLOW_REMOTE_WRITE=false 禁止'));
|
|
337
|
+
}
|
|
330
338
|
}
|
|
331
339
|
// 自动恢复代理状态
|
|
332
340
|
autoRestoreProxies();
|
|
@@ -451,10 +459,10 @@ function autoRestoreProxies() {
|
|
|
451
459
|
}
|
|
452
460
|
|
|
453
461
|
// 检查 OMP 受管 provider 配置状态文件
|
|
454
|
-
const
|
|
455
|
-
if (fs.existsSync(
|
|
462
|
+
const ompActiveFile = PATHS.activeChannel.omp;
|
|
463
|
+
if (fs.existsSync(ompActiveFile)) {
|
|
456
464
|
console.log(chalk.cyan('\n[SYNC] 检测到 OMP 受管渠道状态文件,正在自动恢复...'));
|
|
457
|
-
|
|
465
|
+
startOmpProxyServer({ preserveStartTime: true })
|
|
458
466
|
.then((result) => {
|
|
459
467
|
if (result.success) {
|
|
460
468
|
console.log(chalk.green(`[OK] OMP models.yml 受管 provider 已自动启用,端口: ${result.port}`));
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
const { loadConfig } = require('../config/loader');
|
|
2
2
|
const { saveProxyStartTime, clearProxyStartTime, getProxyStartTime, getProxyRuntime } = require('./services/proxy-runtime');
|
|
3
|
-
const { syncManagedOmpProviders, disableManagedOmpProviders, getEnabledChannels } = require('./services/
|
|
3
|
+
const { syncManagedOmpProviders, disableManagedOmpProviders, getEnabledChannels } = require('./services/omp-channels');
|
|
4
4
|
|
|
5
5
|
let running = false;
|
|
6
6
|
let currentPort = null;
|
|
7
7
|
let lastSyncResult = null;
|
|
8
8
|
|
|
9
|
-
async function
|
|
9
|
+
async function startOmpProxyServer(options = {}) {
|
|
10
10
|
const preserveStartTime = options.preserveStartTime || false;
|
|
11
11
|
const config = loadConfig();
|
|
12
|
-
currentPort = config.ports?.
|
|
12
|
+
currentPort = config.ports?.ompProxy || 20092;
|
|
13
13
|
lastSyncResult = syncManagedOmpProviders();
|
|
14
14
|
running = true;
|
|
15
|
-
saveProxyStartTime('
|
|
15
|
+
saveProxyStartTime('omp', preserveStartTime);
|
|
16
16
|
return {
|
|
17
17
|
success: true,
|
|
18
18
|
port: currentPort,
|
|
@@ -21,14 +21,14 @@ async function startPiProxyServer(options = {}) {
|
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
async function
|
|
24
|
+
async function stopOmpProxyServer(options = {}) {
|
|
25
25
|
const clearStartTime = options.clearStartTime !== false;
|
|
26
26
|
const stoppedPort = currentPort;
|
|
27
27
|
lastSyncResult = disableManagedOmpProviders();
|
|
28
28
|
running = false;
|
|
29
29
|
currentPort = null;
|
|
30
30
|
if (clearStartTime) {
|
|
31
|
-
clearProxyStartTime('
|
|
31
|
+
clearProxyStartTime('omp');
|
|
32
32
|
}
|
|
33
33
|
return {
|
|
34
34
|
success: true,
|
|
@@ -38,16 +38,16 @@ async function stopPiProxyServer(options = {}) {
|
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function
|
|
41
|
+
function getOmpProxyStatus() {
|
|
42
42
|
const config = loadConfig();
|
|
43
|
-
const startTime = getProxyStartTime('
|
|
44
|
-
const runtime = getProxyRuntime('
|
|
43
|
+
const startTime = getProxyStartTime('omp', { allowRecovery: running });
|
|
44
|
+
const runtime = getProxyRuntime('omp', { allowRecovery: running });
|
|
45
45
|
const enabledCount = getEnabledChannels().length;
|
|
46
46
|
const validation = lastSyncResult?.validation || null;
|
|
47
47
|
return {
|
|
48
48
|
running,
|
|
49
49
|
port: currentPort,
|
|
50
|
-
defaultPort: config.ports?.
|
|
50
|
+
defaultPort: config.ports?.ompProxy || 20092,
|
|
51
51
|
startTime,
|
|
52
52
|
runtime,
|
|
53
53
|
mode: 'models-yml-provider-config',
|
|
@@ -60,7 +60,7 @@ function getPiProxyStatus() {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
module.exports = {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
startOmpProxyServer,
|
|
64
|
+
stopOmpProxyServer,
|
|
65
|
+
getOmpProxyStatus
|
|
66
66
|
};
|
|
@@ -13,7 +13,7 @@ const MAX_RESPONSE_BYTES = 1024 * 1024;
|
|
|
13
13
|
const QUOTA_UNIT = 500000;
|
|
14
14
|
const VELOERA_QUOTA_UNIT = 1000000;
|
|
15
15
|
const NEWCLI_QUOTA_UNIT = 1000000;
|
|
16
|
-
const VALID_SOURCES = new Set(['claude', 'codex', 'gemini', 'opencode', '
|
|
16
|
+
const VALID_SOURCES = new Set(['claude', 'codex', 'gemini', 'opencode', 'omp']);
|
|
17
17
|
const GATEWAY_PATH_SEGMENTS = new Set(['openai', 'anthropic', 'claude', 'gemini', 'codex']);
|
|
18
18
|
const HUB_PLATFORMS = new Set(['new-api', 'one-api', 'one-hub', 'done-hub', 'veloera', 'anyrouter', 'aihubmix']);
|
|
19
19
|
const UNSUPPORTED_BALANCE_PLATFORMS = new Set(['dashscope', 'modelscope']);
|
|
@@ -1622,8 +1622,8 @@ function getChannelsForSource(source) {
|
|
|
1622
1622
|
if (source === 'opencode') {
|
|
1623
1623
|
return require('./opencode-channels').getChannels().channels || [];
|
|
1624
1624
|
}
|
|
1625
|
-
if (source === '
|
|
1626
|
-
return require('./
|
|
1625
|
+
if (source === 'omp') {
|
|
1626
|
+
return require('./omp-channels').getChannels().channels || [];
|
|
1627
1627
|
}
|
|
1628
1628
|
return [];
|
|
1629
1629
|
}
|
|
@@ -2,7 +2,7 @@ const { getAllChannels } = require('./channels');
|
|
|
2
2
|
const { getChannels: getCodexChannels } = require('./codex-channels');
|
|
3
3
|
const { getChannels: getGeminiChannels } = require('./gemini-channels');
|
|
4
4
|
const { getChannels: getOpenCodeChannels } = require('./opencode-channels');
|
|
5
|
-
const { getChannels:
|
|
5
|
+
const { getChannels: getOmpChannels } = require('./omp-channels');
|
|
6
6
|
const { isChannelAvailable, getChannelHealthStatus, setOnChannelFrozen, setChannelListProvider } = require('./channel-health');
|
|
7
7
|
|
|
8
8
|
const channelProviders = {
|
|
@@ -19,8 +19,8 @@ const channelProviders = {
|
|
|
19
19
|
const data = getOpenCodeChannels();
|
|
20
20
|
return Array.isArray(data?.channels) ? data.channels : [];
|
|
21
21
|
},
|
|
22
|
-
|
|
23
|
-
const data =
|
|
22
|
+
omp: () => {
|
|
23
|
+
const data = getOmpChannels();
|
|
24
24
|
return Array.isArray(data?.channels) ? data.channels : [];
|
|
25
25
|
}
|
|
26
26
|
};
|
|
@@ -39,7 +39,7 @@ const schedulerStates = {
|
|
|
39
39
|
codex: createState(),
|
|
40
40
|
gemini: createState(),
|
|
41
41
|
opencode: createState(),
|
|
42
|
-
|
|
42
|
+
omp: createState()
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
function getState(source = 'claude') {
|
|
@@ -22,7 +22,7 @@ const {
|
|
|
22
22
|
|
|
23
23
|
// 默认仓库源
|
|
24
24
|
const DEFAULT_REPOS = [];
|
|
25
|
-
const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', '
|
|
25
|
+
const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
26
26
|
const OPENCODE_CONFIG_DIR = NATIVE_PATHS.opencode.config;
|
|
27
27
|
const CLAUDE_COMMANDS_DIR = NATIVE_PATHS.claude.commands
|
|
28
28
|
|| path.join(NATIVE_PATHS.claude.dir || path.dirname(NATIVE_PATHS.claude.settings), 'commands');
|
|
@@ -59,10 +59,10 @@ const PLATFORM_CONFIG = {
|
|
|
59
59
|
repoType: 'gemini-commands',
|
|
60
60
|
fileExtension: '.toml'
|
|
61
61
|
},
|
|
62
|
-
|
|
63
|
-
userCommandsDir: NATIVE_PATHS.
|
|
62
|
+
omp: {
|
|
63
|
+
userCommandsDir: NATIVE_PATHS.omp.commands || path.join(NATIVE_PATHS.omp.dir, 'commands'),
|
|
64
64
|
projectCommandsDir: (projectPath) => path.join(projectPath, '.omp', 'commands'),
|
|
65
|
-
repoType: '
|
|
65
|
+
repoType: 'omp-commands'
|
|
66
66
|
}
|
|
67
67
|
};
|
|
68
68
|
|
|
@@ -379,7 +379,7 @@ class CommandsService {
|
|
|
379
379
|
if (this.platform === 'gemini') {
|
|
380
380
|
return generateGeminiCommandToml({ description, body });
|
|
381
381
|
}
|
|
382
|
-
if (this.platform === '
|
|
382
|
+
if (this.platform === 'omp') {
|
|
383
383
|
return body || '';
|
|
384
384
|
}
|
|
385
385
|
|
|
@@ -14,7 +14,7 @@ const channelsService = require('./channels');
|
|
|
14
14
|
const codexChannelsService = require('./codex-channels');
|
|
15
15
|
const geminiChannelsService = require('./gemini-channels');
|
|
16
16
|
const opencodeChannelsService = require('./opencode-channels');
|
|
17
|
-
const
|
|
17
|
+
const ompChannelsService = require('./omp-channels');
|
|
18
18
|
const { AgentsService } = require('./agents-service');
|
|
19
19
|
const { CommandsService } = require('./commands-service');
|
|
20
20
|
const { SkillService } = require('./skill-service');
|
|
@@ -55,18 +55,18 @@ const LEGACY_UI_CONFIG_PATH = PATHS.uiConfig;
|
|
|
55
55
|
const LEGACY_NOTIFY_HOOK_PATH = PATHS.notifyHook;
|
|
56
56
|
const GEMINI_SETTINGS_PATH = path.join(path.dirname(NATIVE_PATHS.gemini.env), 'settings.json');
|
|
57
57
|
const AGENT_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode'];
|
|
58
|
-
const COMMAND_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', '
|
|
59
|
-
const SKILL_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', '
|
|
60
|
-
const PLUGIN_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', '
|
|
58
|
+
const COMMAND_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
59
|
+
const SKILL_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
60
|
+
const PLUGIN_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
61
61
|
const CLAUDE_MARKETPLACES_REGISTRY = path.join(CLAUDE_PLUGINS_DIR, 'known_marketplaces.json');
|
|
62
62
|
const CODEX_PLUGINS_DIR = path.join(path.dirname(NATIVE_PATHS.codex.config), 'plugins');
|
|
63
63
|
const CODEX_PLUGINS_CACHE_DIR = path.join(CODEX_PLUGINS_DIR, 'cache');
|
|
64
64
|
const OPENCODE_PLUGINS_DIR = path.join(NATIVE_PATHS.opencode.config, 'plugins');
|
|
65
65
|
const OPENCODE_LEGACY_PLUGINS_DIR = path.join(NATIVE_PATHS.opencode.config, 'plugin');
|
|
66
|
-
const
|
|
67
|
-
const
|
|
66
|
+
const OMP_SETTINGS_PATH = NATIVE_PATHS.omp?.settings || path.join(PATHS.base, 'omp-config.yml');
|
|
67
|
+
const OMP_EXTENSIONS_DIR = NATIVE_PATHS.omp?.extensions || path.join(PATHS.base, 'omp-extensions');
|
|
68
68
|
|
|
69
|
-
function
|
|
69
|
+
function normalizeOmpResourceType(value = '') {
|
|
70
70
|
const key = String(value || '').trim().replace(/[\s_-]+/g, '').toLowerCase();
|
|
71
71
|
const map = {
|
|
72
72
|
extension: 'extension',
|
|
@@ -90,10 +90,10 @@ function normalizePiResourceType(value = '') {
|
|
|
90
90
|
return map[key] || String(value || '').trim();
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
function
|
|
93
|
+
function normalizeOmpResourceTypes(input = []) {
|
|
94
94
|
const result = [];
|
|
95
95
|
const add = (value) => {
|
|
96
|
-
const normalized =
|
|
96
|
+
const normalized = normalizeOmpResourceType(value);
|
|
97
97
|
if (normalized && !result.includes(normalized)) result.push(normalized);
|
|
98
98
|
};
|
|
99
99
|
if (Array.isArray(input)) {
|
|
@@ -130,7 +130,7 @@ function getOpenCodeNotificationPluginPath() {
|
|
|
130
130
|
function getNativeConfigSpecs() {
|
|
131
131
|
const openCodeConfigPaths = getOpenCodeConfigPaths();
|
|
132
132
|
const openCodeNotificationPluginPath = getOpenCodeNotificationPluginPath();
|
|
133
|
-
const
|
|
133
|
+
const ompDir = NATIVE_PATHS.omp.dir || path.dirname(NATIVE_PATHS.omp.settings);
|
|
134
134
|
return {
|
|
135
135
|
claude: {
|
|
136
136
|
settings: { path: NATIVE_PATHS.claude.settings, format: 'json' }
|
|
@@ -151,18 +151,18 @@ function getNativeConfigSpecs() {
|
|
|
151
151
|
? { codingToolNotifyPlugin: { path: openCodeNotificationPluginPath, format: 'text' } }
|
|
152
152
|
: {})
|
|
153
153
|
},
|
|
154
|
-
|
|
155
|
-
settings: { path: NATIVE_PATHS.
|
|
156
|
-
auth: { path: NATIVE_PATHS.
|
|
157
|
-
models: { path: NATIVE_PATHS.
|
|
158
|
-
commands: { path: NATIVE_PATHS.
|
|
159
|
-
prompts: { path: NATIVE_PATHS.
|
|
160
|
-
skills: { path: NATIVE_PATHS.
|
|
161
|
-
extensions: { path: NATIVE_PATHS.
|
|
162
|
-
themes: { path: NATIVE_PATHS.
|
|
163
|
-
packages: { path: NATIVE_PATHS.
|
|
164
|
-
npmPackages: { path: path.join(
|
|
165
|
-
gitPackages: { path: path.join(
|
|
154
|
+
omp: {
|
|
155
|
+
settings: { path: NATIVE_PATHS.omp.settings, format: 'yaml' },
|
|
156
|
+
auth: { path: NATIVE_PATHS.omp.auth, format: 'json', mode: 0o600 },
|
|
157
|
+
models: { path: NATIVE_PATHS.omp.models, format: 'yaml' },
|
|
158
|
+
commands: { path: NATIVE_PATHS.omp.commands || path.join(ompDir, 'commands'), format: 'directory' },
|
|
159
|
+
prompts: { path: NATIVE_PATHS.omp.prompts, format: 'directory' },
|
|
160
|
+
skills: { path: NATIVE_PATHS.omp.skills, format: 'directory' },
|
|
161
|
+
extensions: { path: NATIVE_PATHS.omp.extensions, format: 'directory' },
|
|
162
|
+
themes: { path: NATIVE_PATHS.omp.themes || path.join(ompDir, 'themes'), format: 'directory' },
|
|
163
|
+
packages: { path: NATIVE_PATHS.omp.packages || path.join(ompDir, 'packages'), format: 'directory' },
|
|
164
|
+
npmPackages: { path: path.join(ompDir, 'npm'), format: 'directory' },
|
|
165
|
+
gitPackages: { path: path.join(ompDir, 'git'), format: 'directory' }
|
|
166
166
|
}
|
|
167
167
|
};
|
|
168
168
|
}
|
|
@@ -1089,7 +1089,7 @@ function exportOpenCodePluginsByPlatform(service) {
|
|
|
1089
1089
|
name: plugin.name,
|
|
1090
1090
|
directory: plugin.directory || plugin.name,
|
|
1091
1091
|
installSource: plugin.installSource || plugin.source || plugin.name,
|
|
1092
|
-
resourceTypes:
|
|
1092
|
+
resourceTypes: normalizeOmpResourceTypes(plugin.resourceTypes || plugin.resources),
|
|
1093
1093
|
version: plugin.version || 'latest',
|
|
1094
1094
|
description: plugin.description || '',
|
|
1095
1095
|
enabled: plugin.enabled !== false,
|
|
@@ -1108,13 +1108,13 @@ function exportOpenCodePluginsByPlatform(service) {
|
|
|
1108
1108
|
return { plugins, control };
|
|
1109
1109
|
}
|
|
1110
1110
|
|
|
1111
|
-
function
|
|
1111
|
+
function exportOmpPluginsByPlatform(service) {
|
|
1112
1112
|
const plugins = (service.listPlugins().plugins || [])
|
|
1113
1113
|
.map((plugin) => {
|
|
1114
|
-
if (plugin.pluginType === 'package' || plugin.source === '
|
|
1114
|
+
if (plugin.pluginType === 'package' || plugin.source === 'omp-settings') {
|
|
1115
1115
|
return {
|
|
1116
|
-
platform: '
|
|
1117
|
-
type: '
|
|
1116
|
+
platform: 'omp',
|
|
1117
|
+
type: 'omp-package',
|
|
1118
1118
|
pluginType: 'package',
|
|
1119
1119
|
pluginKind: plugin.pluginKind || 'package',
|
|
1120
1120
|
name: plugin.name,
|
|
@@ -1123,18 +1123,18 @@ function exportPiPluginsByPlatform(service) {
|
|
|
1123
1123
|
description: plugin.description || '',
|
|
1124
1124
|
enabled: plugin.enabled !== false,
|
|
1125
1125
|
installed: plugin.installed !== false,
|
|
1126
|
-
source: plugin.source || '
|
|
1126
|
+
source: plugin.source || 'omp-settings'
|
|
1127
1127
|
};
|
|
1128
1128
|
}
|
|
1129
|
-
return buildManagedPluginExportItem(plugin, '
|
|
1130
|
-
type: '
|
|
1129
|
+
return buildManagedPluginExportItem(plugin, 'omp', OMP_EXTENSIONS_DIR, {
|
|
1130
|
+
type: 'omp-extension',
|
|
1131
1131
|
pluginType: plugin.pluginType || 'extension',
|
|
1132
1132
|
pluginKind: plugin.pluginKind || 'extension',
|
|
1133
|
-
manifestCandidates: ['
|
|
1133
|
+
manifestCandidates: ['omp.json', 'extension.json', 'plugin.json', 'package.json']
|
|
1134
1134
|
});
|
|
1135
1135
|
})
|
|
1136
1136
|
.filter(Boolean);
|
|
1137
|
-
const control = exportPluginControlSnapshot('
|
|
1137
|
+
const control = exportPluginControlSnapshot('omp', service);
|
|
1138
1138
|
return { plugins, control };
|
|
1139
1139
|
}
|
|
1140
1140
|
|
|
@@ -1148,8 +1148,8 @@ function exportPluginsSnapshotByPlatform() {
|
|
|
1148
1148
|
result[platform] = exportCodexPluginsByPlatform(service);
|
|
1149
1149
|
} else if (platform === 'opencode') {
|
|
1150
1150
|
result[platform] = exportOpenCodePluginsByPlatform(service);
|
|
1151
|
-
} else if (platform === '
|
|
1152
|
-
result[platform] =
|
|
1151
|
+
} else if (platform === 'omp') {
|
|
1152
|
+
result[platform] = exportOmpPluginsByPlatform(service);
|
|
1153
1153
|
} else {
|
|
1154
1154
|
result[platform] = {
|
|
1155
1155
|
plugins: service.listPlugins().plugins || [],
|
|
@@ -1515,22 +1515,22 @@ function writeOpenCodePluginConfig(packages = [], overwrite = true) {
|
|
|
1515
1515
|
return writeJsonFileAbsolute(configPath, { ...existing, plugin: mergedPlugins }, true);
|
|
1516
1516
|
}
|
|
1517
1517
|
|
|
1518
|
-
function
|
|
1518
|
+
function writeOmpPluginSettings(plugins = [], snapshot = {}, overwrite = true) {
|
|
1519
1519
|
const nativeSettings = snapshot.control?.nativeSettings;
|
|
1520
1520
|
if (nativeSettings?.content !== undefined) {
|
|
1521
|
-
return writeNativeConfigAbsolute({ path:
|
|
1521
|
+
return writeNativeConfigAbsolute({ path: OMP_SETTINGS_PATH, format: 'yaml' }, {
|
|
1522
1522
|
...nativeSettings,
|
|
1523
1523
|
format: 'yaml'
|
|
1524
1524
|
}, overwrite);
|
|
1525
1525
|
}
|
|
1526
1526
|
|
|
1527
|
-
const settings = readYamlFileSafe(
|
|
1528
|
-
if (fs.existsSync(
|
|
1527
|
+
const settings = readYamlFileSafe(OMP_SETTINGS_PATH) || {};
|
|
1528
|
+
if (fs.existsSync(OMP_SETTINGS_PATH) && !overwrite) {
|
|
1529
1529
|
return 'skipped';
|
|
1530
1530
|
}
|
|
1531
1531
|
const existingPackages = Array.isArray(settings.packages) ? settings.packages : [];
|
|
1532
1532
|
const existingDisabled = Array.isArray(settings.disabledPackages) ? settings.disabledPackages : [];
|
|
1533
|
-
const packagePlugins = plugins.filter(plugin => plugin.type === '
|
|
1533
|
+
const packagePlugins = plugins.filter(plugin => plugin.type === 'omp-package' || plugin.pluginType === 'package');
|
|
1534
1534
|
const packageIdentity = (item) => {
|
|
1535
1535
|
if (typeof item === 'string') return item;
|
|
1536
1536
|
if (!item || typeof item !== 'object') return '';
|
|
@@ -1540,7 +1540,7 @@ function writePiPluginSettings(plugins = [], snapshot = {}, overwrite = true) {
|
|
|
1540
1540
|
const name = plugin.name || plugin.directory || plugin.installSource || '';
|
|
1541
1541
|
if (!name) return null;
|
|
1542
1542
|
const installSource = plugin.installSource || plugin.packageSource || '';
|
|
1543
|
-
const resourceTypes =
|
|
1543
|
+
const resourceTypes = normalizeOmpResourceTypes(plugin.resourceTypes || plugin.resources);
|
|
1544
1544
|
if (!installSource || installSource === name) {
|
|
1545
1545
|
if (resourceTypes.length === 0 && !plugin.version && !plugin.description) return name;
|
|
1546
1546
|
}
|
|
@@ -1573,7 +1573,7 @@ function writePiPluginSettings(plugins = [], snapshot = {}, overwrite = true) {
|
|
|
1573
1573
|
return 'skipped';
|
|
1574
1574
|
}
|
|
1575
1575
|
|
|
1576
|
-
return writeYamlFileAbsolute(
|
|
1576
|
+
return writeYamlFileAbsolute(OMP_SETTINGS_PATH, {
|
|
1577
1577
|
...settings,
|
|
1578
1578
|
packages: mergePackageEntries(existingPackages, packages),
|
|
1579
1579
|
disabledPackages: mergePackageEntries(existingDisabled, disabledPackages)
|
|
@@ -1662,8 +1662,8 @@ function importPluginsByPlatformSnapshot(snapshotByPlatform = {}, legacyPlugins
|
|
|
1662
1662
|
.map(plugin => plugin.name || plugin.directory)
|
|
1663
1663
|
.filter(Boolean);
|
|
1664
1664
|
applyImportStatus(results, writeOpenCodePluginConfig(packages, overwrite));
|
|
1665
|
-
} else if (platform === '
|
|
1666
|
-
applyImportStatus(results,
|
|
1665
|
+
} else if (platform === 'omp' && (hasControl || plugins.length > 0)) {
|
|
1666
|
+
applyImportStatus(results, writeOmpPluginSettings(plugins, snapshot, overwrite));
|
|
1667
1667
|
}
|
|
1668
1668
|
|
|
1669
1669
|
for (const plugin of plugins) {
|
|
@@ -1675,11 +1675,11 @@ function importPluginsByPlatformSnapshot(snapshotByPlatform = {}, legacyPlugins
|
|
|
1675
1675
|
continue;
|
|
1676
1676
|
}
|
|
1677
1677
|
applyImportStatus(results, importPluginToDirectory(platform, plugin, getOpenCodePluginsDir(), overwrite));
|
|
1678
|
-
} else if (platform === '
|
|
1679
|
-
if (plugin.type === '
|
|
1678
|
+
} else if (platform === 'omp') {
|
|
1679
|
+
if (plugin.type === 'omp-package' || plugin.pluginType === 'package') {
|
|
1680
1680
|
continue;
|
|
1681
1681
|
}
|
|
1682
|
-
applyImportStatus(results, importPluginToDirectory(platform, plugin,
|
|
1682
|
+
applyImportStatus(results, importPluginToDirectory(platform, plugin, OMP_EXTENSIONS_DIR, overwrite));
|
|
1683
1683
|
} else if (platform === 'claude') {
|
|
1684
1684
|
const isLegacy = plugin.type === 'legacy';
|
|
1685
1685
|
applyImportStatus(results, importPluginToDirectory(
|
|
@@ -1750,8 +1750,8 @@ function getAllChannelsByType() {
|
|
|
1750
1750
|
const codex = codexChannelsService.getChannels()?.channels || [];
|
|
1751
1751
|
const gemini = geminiChannelsService.getChannels()?.channels || [];
|
|
1752
1752
|
const opencode = opencodeChannelsService.getChannels()?.channels || [];
|
|
1753
|
-
const
|
|
1754
|
-
return { claude, codex, gemini, opencode,
|
|
1753
|
+
const omp = ompChannelsService.getChannels()?.channels || [];
|
|
1754
|
+
return { claude, codex, gemini, opencode, omp };
|
|
1755
1755
|
}
|
|
1756
1756
|
|
|
1757
1757
|
/**
|
|
@@ -1963,7 +1963,7 @@ async function importConfigs(importData, options = {}) {
|
|
|
1963
1963
|
codex: hasTypedChannels && Array.isArray(channelsByType.codex) ? channelsByType.codex : [],
|
|
1964
1964
|
gemini: hasTypedChannels && Array.isArray(channelsByType.gemini) ? channelsByType.gemini : [],
|
|
1965
1965
|
opencode: hasTypedChannels && Array.isArray(channelsByType.opencode) ? channelsByType.opencode : [],
|
|
1966
|
-
|
|
1966
|
+
omp: hasTypedChannels && Array.isArray(channelsByType.omp) ? channelsByType.omp: []
|
|
1967
1967
|
};
|
|
1968
1968
|
|
|
1969
1969
|
// 导入配置模板
|
|
@@ -2060,16 +2060,16 @@ async function importConfigs(importData, options = {}) {
|
|
|
2060
2060
|
(channel.name && channel.baseUrl && c.name === channel.name && c.baseUrl === channel.baseUrl)
|
|
2061
2061
|
));
|
|
2062
2062
|
|
|
2063
|
-
importTypedChannels('
|
|
2063
|
+
importTypedChannels('omp', ompChannelsService, channel => {
|
|
2064
2064
|
const { name, baseUrl, apiKey, ...extraConfig } = channel;
|
|
2065
|
-
|
|
2065
|
+
ompChannelsService.createChannel(name, baseUrl, apiKey, extraConfig);
|
|
2066
2066
|
}, (existingChannels, channel) => existingChannels.find(c =>
|
|
2067
2067
|
(channel.id && c.id === channel.id) ||
|
|
2068
2068
|
(channel.providerKey && c.providerKey === channel.providerKey) ||
|
|
2069
2069
|
(channel.name && channel.baseUrl && c.name === channel.name && c.baseUrl === channel.baseUrl)
|
|
2070
2070
|
));
|
|
2071
|
-
if ((importChannelsByType.
|
|
2072
|
-
|
|
2071
|
+
if ((importChannelsByType.omp || []).length > 0 && typeof ompChannelsService.syncManagedProviderExtension === 'function') {
|
|
2072
|
+
ompChannelsService.syncManagedProviderExtension();
|
|
2073
2073
|
}
|
|
2074
2074
|
|
|
2075
2075
|
// 导入工作区配置
|
|
@@ -27,13 +27,13 @@ const CLAUDE_DIRS = {
|
|
|
27
27
|
|
|
28
28
|
// Valid config types
|
|
29
29
|
const CONFIG_TYPES = ['skills', 'commands', 'agents', 'plugins'];
|
|
30
|
-
const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', '
|
|
30
|
+
const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
31
31
|
|
|
32
32
|
const PLATFORM_SUPPORT = {
|
|
33
|
-
skills: { claude: true, codex: true, gemini: true, opencode: true,
|
|
34
|
-
commands: { claude: true, codex: true, gemini: true, opencode: true,
|
|
35
|
-
agents: { claude: true, codex: true, gemini: true, opencode: true,
|
|
36
|
-
plugins: { claude: true, codex: false, gemini: false, opencode: true,
|
|
33
|
+
skills: { claude: true, codex: true, gemini: true, opencode: true, omp: true },
|
|
34
|
+
commands: { claude: true, codex: true, gemini: true, opencode: true, omp: true },
|
|
35
|
+
agents: { claude: true, codex: true, gemini: true, opencode: true, omp: false },
|
|
36
|
+
plugins: { claude: true, codex: false, gemini: false, opencode: true, omp: true }
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
function normalizePlatforms(type, platforms = {}) {
|
|
@@ -585,7 +585,7 @@ class ConfigRegistryService {
|
|
|
585
585
|
codex: 0,
|
|
586
586
|
gemini: 0,
|
|
587
587
|
opencode: 0,
|
|
588
|
-
|
|
588
|
+
omp: 0
|
|
589
589
|
}
|
|
590
590
|
};
|
|
591
591
|
|
|
@@ -599,7 +599,7 @@ class ConfigRegistryService {
|
|
|
599
599
|
codex: items.filter(i => i.platforms?.codex).length,
|
|
600
600
|
gemini: items.filter(i => i.platforms?.gemini).length,
|
|
601
601
|
opencode: items.filter(i => i.platforms?.opencode).length,
|
|
602
|
-
|
|
602
|
+
omp: items.filter(i => i.platforms?.omp).length
|
|
603
603
|
};
|
|
604
604
|
|
|
605
605
|
stats.byType[type] = typeStats;
|
|
@@ -608,7 +608,7 @@ class ConfigRegistryService {
|
|
|
608
608
|
stats.byPlatform.codex += typeStats.codex;
|
|
609
609
|
stats.byPlatform.gemini += typeStats.gemini;
|
|
610
610
|
stats.byPlatform.opencode += typeStats.opencode;
|
|
611
|
-
stats.byPlatform.
|
|
611
|
+
stats.byPlatform.omp += typeStats.omp;
|
|
612
612
|
}
|
|
613
613
|
|
|
614
614
|
return stats;
|