coding-tool-x 3.8.7 → 3.8.9
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 +2 -2
- package/dist/web/assets/{AgentsDrawer-C7ePByZx.js → AgentsDrawer-Cj5CJ4d9.js} +1 -1
- package/dist/web/assets/Analytics-1doS-8uC.js +1 -0
- package/dist/web/assets/AssetPathField-C9TOPl7o.js +1 -0
- package/dist/web/assets/{ChatHistoryDrawer-Ccl4rhdz.js → ChatHistoryDrawer-BTmQ1aQr.js} +1 -1
- package/dist/web/assets/{CollapseItem-MxG_UD4o.js → CollapseItem-CwqJk3bE.js} +1 -1
- package/dist/web/assets/{CommandsDrawer-DWbaxHRZ.js → CommandsDrawer-CaZWDI_G.js} +1 -1
- package/dist/web/assets/ConfigExportDrawer-C3vSZEsS.js +1 -0
- package/dist/web/assets/{ConfigTemplates-AiRPv2cd.js → ConfigTemplates-gyERg9iC.js} +1 -1
- package/dist/web/assets/{ConfigTemplatesDrawer-CKMFsfEF.js → ConfigTemplatesDrawer-B17RqFi4.js} +1 -1
- package/dist/web/assets/{ConfigTemplatesPanel-Cvbnkvpt.js → ConfigTemplatesPanel-DKIC_FqG.js} +1 -1
- package/dist/web/assets/{Divider-D28g1gwj.js → Divider-DsdbkHrG.js} +1 -1
- package/dist/web/assets/{FavoritesDrawer-DA-dR_vP.js → FavoritesDrawer-DaziQmBp.js} +1 -1
- package/dist/web/assets/Forward-DLCL7aMY.js +1 -0
- package/dist/web/assets/{GatewayConvertDrawer-402_raGb.js → GatewayConvertDrawer-OMgWUUSc.js} +1 -1
- package/dist/web/assets/Home-DOSUTfrE.js +1 -0
- package/dist/web/assets/{MarkdownEditor-BvkDECwH.js → MarkdownEditor-9TTwTS-U.js} +1 -1
- package/dist/web/assets/McpDrawer-I8rl8lGH.js +1 -0
- package/dist/web/assets/{McpFormDrawer-DPMnyt5L.js → McpFormDrawer-DEP3C7ut.js} +1 -1
- package/dist/web/assets/{PluginManager-FKVeugr4.js → PluginManager-BuRcWuBj.js} +1 -1
- package/dist/web/assets/{PluginsDrawer-MvM1R55d.js → PluginsDrawer-_zZENaQn.js} +1 -1
- package/dist/web/assets/PluginsPanel-Bs5qZ-TK.js +1 -0
- package/dist/web/assets/PluginsPanel-CzGMK-Ap.css +1 -0
- package/dist/web/assets/ProjectList-BSxuL2td.js +1 -0
- package/dist/web/assets/{ProjectList-677RLZ8O.css → ProjectList-VbIYSHbH.css} +1 -1
- package/dist/web/assets/PromptsDrawer-CoZ-ZtsY.js +1 -0
- package/dist/web/assets/RecentSessionsDrawer-B_17aJBG.js +1 -0
- package/dist/web/assets/RecentSessionsDrawer-yrAD4p1A.css +1 -0
- package/dist/web/assets/SessionCard-BL_x0d3t.js +1 -0
- package/dist/web/assets/SessionList-DhRYZ6vl.js +1 -0
- package/dist/web/assets/SessionList-qG_XpPBJ.css +1 -0
- package/dist/web/assets/{SettingsDrawer-lMjttbkD.js → SettingsDrawer-fYb0DU7X.js} +1 -1
- package/dist/web/assets/SkillManager-S698Hns8.js +1 -0
- package/dist/web/assets/{SkillsDrawer-DF6JsSyj.js → SkillsDrawer-Ms4lPCow.js} +1 -1
- package/dist/web/assets/{SkillsPanel-B3Nm5j32.css → SkillsPanel-C4ke56nF.css} +1 -1
- package/dist/web/assets/SkillsPanel-rqnqAOGL.js +1 -0
- package/dist/web/assets/{SpeedTestDrawer-BaZkZqPP.js → SpeedTestDrawer-Bbn38SfV.js} +1 -1
- package/dist/web/assets/Upload-CdyVHxCI.js +1 -0
- package/dist/web/assets/{WorkspaceDrawer-BFSwZ5yU.js → WorkspaceDrawer-L7HJRc6u.js} +1 -1
- package/dist/web/assets/{WorkspaceManager-BHL1uYct.js → WorkspaceManager-DsoNg2z8.js} +1 -1
- package/dist/web/assets/{WorkspacePanel-B5PooBtg.js → WorkspacePanel-Be8PVZah.js} +1 -1
- package/dist/web/assets/{headers-cf-QapUq.js → headers-B5JWGn3v.js} +1 -1
- package/dist/web/assets/{icons-B2Vg-IOC.js → icons-DmFe4b5j.js} +1 -1
- package/dist/web/assets/{index-BohDDAy_.css → index-3Lp6z8TQ.css} +1 -1
- package/dist/web/assets/index-BKlAWTH-.js +2 -0
- package/dist/web/assets/{light-Cp0t7v32.js → light-0eavxNvt.js} +1 -1
- package/dist/web/assets/platforms-BmzzwnSw.js +1 -0
- package/dist/web/assets/platforms-DWXgmy2w.js +1 -0
- package/dist/web/assets/session-visibility-BAmxh3cK.js +1 -0
- package/dist/web/assets/sessions-CC0j-KH_.js +1 -0
- package/dist/web/assets/sessions-D4yQtfKb.js +1 -0
- package/dist/web/assets/use-message-DqCwefG6.js +1 -0
- package/dist/web/assets/{useResponsiveDrawer-D-DDpbnI.js → useResponsiveDrawer-V_onl9NV.js} +1 -1
- package/dist/web/index.html +7 -7
- package/package.json +1 -1
- package/src/commands/daemon.js +27 -4
- package/src/commands/search.js +17 -2
- package/src/config/paths.js +2 -0
- package/src/platforms/channel-auth-registry.js +36 -6
- package/src/platforms/channel-auth-service.js +12 -2
- package/src/platforms/driver-registry.js +9 -1
- package/src/platforms/drivers/claude/session-history-adapter.js +72 -1
- package/src/platforms/drivers/claude/sessions-implementation.js +49 -7
- package/src/platforms/drivers/claude/sessions.js +30 -6
- package/src/platforms/drivers/codex/parser.js +57 -1
- package/src/platforms/drivers/codex/session-history-adapter.js +8 -2
- package/src/platforms/drivers/codex/sessions-implementation.js +25 -3
- package/src/platforms/drivers/codex/sessions.js +18 -1
- package/src/platforms/drivers/dsh/api-operations.js +396 -0
- package/src/platforms/drivers/dsh/channels-implementation.js +458 -0
- package/src/platforms/drivers/dsh/channels.js +191 -0
- package/src/platforms/drivers/dsh/common.js +571 -0
- package/src/platforms/drivers/dsh/native-config.js +93 -0
- package/src/platforms/drivers/dsh/native-logs.js +116 -0
- package/src/platforms/drivers/dsh/plugin-manager.js +117 -0
- package/src/platforms/drivers/dsh/projects.js +23 -0
- package/src/platforms/drivers/dsh/proxy-implementation.js +260 -0
- package/src/platforms/drivers/dsh/proxy.js +23 -0
- package/src/platforms/drivers/dsh/resources.js +346 -0
- package/src/platforms/drivers/dsh/sessions.js +587 -0
- package/src/platforms/drivers/dsh/statistics-implementation.js +238 -0
- package/src/platforms/drivers/dsh/statistics.js +24 -0
- package/src/platforms/drivers/gemini/session-history-adapter.js +49 -1
- package/src/platforms/drivers/gemini/sessions-implementation.js +46 -1
- package/src/platforms/drivers/gemini/sessions.js +2 -1
- package/src/platforms/drivers/omp/prompts.js +58 -2
- package/src/platforms/drivers/omp/proxy-implementation.js +25 -1
- package/src/platforms/drivers/omp/session-history-adapter.js +42 -1
- package/src/platforms/drivers/omp/sessions-implementation.js +51 -3
- package/src/platforms/drivers/omp/sessions.js +33 -2
- package/src/platforms/drivers/opencode/channels-implementation.js +25 -22
- package/src/platforms/drivers/opencode/channels.js +6 -1
- package/src/platforms/drivers/opencode/sessions-implementation.js +89 -9
- package/src/platforms/drivers/opencode/sessions.js +37 -1
- package/src/platforms/manifest-schema.js +43 -3
- package/src/platforms/manifests/dsh.json +542 -0
- package/src/platforms/manifests/omp.json +2 -1
- package/src/platforms/manifests/opencode.json +28 -0
- package/src/platforms/native-oauth-adapters.js +318 -18
- package/src/platforms/oauth-credentials-service.js +344 -13
- package/src/platforms/path-resolver.js +2 -0
- package/src/platforms/platform-path-context.js +12 -2
- package/src/platforms/registry.js +16 -1
- package/src/platforms/runtime.js +5 -0
- package/src/platforms/session-history-adapters.js +1 -0
- package/src/server/api/platform-api-config.js +23 -2
- package/src/server/api/platform-route-factory.js +9 -2
- package/src/server/api/platforms.js +19 -1
- package/src/server/api/plugins.js +108 -13
- package/src/server/index.js +35 -1
- package/src/server/services/config-registry-service.js +10 -1
- package/src/server/services/config-templates-service.js +1 -0
- package/src/server/services/plugins-service.js +474 -103
- package/src/server/services/session-history-index.js +900 -140
- package/src/server/services/session-history-worker.js +3 -1
- package/src/server/services/skill-service.js +214 -7
- package/src/server/services/usage-log-utils.js +1 -0
- package/src/server/services/workspace-service.js +39 -10
- package/src/shared/driver-factories/api.js +22 -6
- package/src/shared/driver-factories/projects.js +8 -0
- package/dist/web/assets/Analytics-BVG6ehFv.js +0 -1
- package/dist/web/assets/AssetPathField-BZI9NvEr.js +0 -1
- package/dist/web/assets/ConfigExportDrawer-DrawKwxE.js +0 -1
- package/dist/web/assets/Home-CTF8ZWKW.js +0 -1
- package/dist/web/assets/McpDrawer-DZGHkuDm.js +0 -1
- package/dist/web/assets/PluginsPanel-CKuBs38B.js +0 -1
- package/dist/web/assets/PluginsPanel-D6ZqITcR.css +0 -1
- package/dist/web/assets/ProjectList-tsjwjXV1.js +0 -1
- package/dist/web/assets/PromptsDrawer-B-X9ci8n.js +0 -1
- package/dist/web/assets/RecentSessionsDrawer-CKFsOYDM.css +0 -1
- package/dist/web/assets/RecentSessionsDrawer-wLktMF_c.js +0 -1
- package/dist/web/assets/SessionCard-DkJPy0TY.js +0 -1
- package/dist/web/assets/SessionList-BpYRz1cX.css +0 -1
- package/dist/web/assets/SessionList-Gzhh4FOZ.js +0 -1
- package/dist/web/assets/SkillManager-CzFxWxx-.js +0 -1
- package/dist/web/assets/SkillsPanel--lLEts9y.js +0 -1
- package/dist/web/assets/Upload-BEQ-3Kqq.js +0 -1
- package/dist/web/assets/index-BFInlZGI.js +0 -2
- package/dist/web/assets/platforms-CBkB45JP.js +0 -1
- package/dist/web/assets/platforms-FTpjxAT6.js +0 -1
- package/dist/web/assets/sessions-Cmy31slD.js +0 -1
- package/dist/web/assets/sessions-yC_oVVh8.js +0 -1
- package/dist/web/assets/use-message-DoLM8C1C.js +0 -1
|
@@ -19,7 +19,8 @@ const PUBLIC_FIELDS = Object.freeze([
|
|
|
19
19
|
'apiPrefix',
|
|
20
20
|
'modelCatalogKey',
|
|
21
21
|
'promptLabel',
|
|
22
|
-
'resourceTypes'
|
|
22
|
+
'resourceTypes',
|
|
23
|
+
'resourceActions'
|
|
23
24
|
]);
|
|
24
25
|
|
|
25
26
|
function publicCapabilities(capabilities) {
|
|
@@ -41,6 +42,18 @@ function publicResourceTypes(resourceTypes) {
|
|
|
41
42
|
);
|
|
42
43
|
}
|
|
43
44
|
|
|
45
|
+
function publicResourceActions(resourceActions) {
|
|
46
|
+
if (!resourceActions || typeof resourceActions !== 'object' || Array.isArray(resourceActions)) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
return Object.fromEntries(Object.entries(resourceActions).map(([resourceType, actions]) => [
|
|
50
|
+
resourceType,
|
|
51
|
+
actions && typeof actions === 'object' && !Array.isArray(actions)
|
|
52
|
+
? Object.fromEntries(Object.entries(actions).filter(([, value]) => typeof value === 'boolean'))
|
|
53
|
+
: {}
|
|
54
|
+
]));
|
|
55
|
+
}
|
|
56
|
+
|
|
44
57
|
function toPublicDefinition(definition) {
|
|
45
58
|
if (!definition || typeof definition !== 'object') return null;
|
|
46
59
|
const result = {};
|
|
@@ -50,6 +63,11 @@ function toPublicDefinition(definition) {
|
|
|
50
63
|
if (resourceTypes) result.resourceTypes = resourceTypes;
|
|
51
64
|
continue;
|
|
52
65
|
}
|
|
66
|
+
if (field === 'resourceActions') {
|
|
67
|
+
const resourceActions = publicResourceActions(definition.resourceActions);
|
|
68
|
+
if (resourceActions) result.resourceActions = resourceActions;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
53
71
|
if (field === 'apiPrefix') {
|
|
54
72
|
const apiPrefix = definition.apiPrefix ?? definition.api?.prefix;
|
|
55
73
|
if (apiPrefix !== undefined) result.apiPrefix = apiPrefix || null;
|
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const express = require('express');
|
|
8
|
+
const path = require('path');
|
|
8
9
|
const { PluginsService } = require('../services/plugins-service');
|
|
10
|
+
const { SkillRefreshTaskService } = require('../services/skill-refresh-task-service');
|
|
11
|
+
const { PATHS } = require('../../config/paths');
|
|
9
12
|
const { maskToken } = require('../services/oauth-utils');
|
|
10
13
|
const { sendApiError } = require('./validation-errors');
|
|
11
14
|
const { resolveManagedPlatform } = require('../services/platform-resolution');
|
|
@@ -13,6 +16,13 @@ const { validateKnownProjectCwd } = require('../services/project-path-validation
|
|
|
13
16
|
|
|
14
17
|
const router = express.Router();
|
|
15
18
|
const pluginServices = new Map();
|
|
19
|
+
let routerOptions = {};
|
|
20
|
+
let defaultRefreshTasks;
|
|
21
|
+
|
|
22
|
+
router.createRouter = (options = {}) => {
|
|
23
|
+
routerOptions = options;
|
|
24
|
+
return router;
|
|
25
|
+
};
|
|
16
26
|
|
|
17
27
|
function resolvePlatform(rawPlatform) {
|
|
18
28
|
return resolveManagedPlatform(rawPlatform);
|
|
@@ -35,6 +45,26 @@ function getPluginsService(req) {
|
|
|
35
45
|
};
|
|
36
46
|
}
|
|
37
47
|
|
|
48
|
+
function getPluginServiceForPlatform(platform) {
|
|
49
|
+
if (!pluginServices.has(platform)) {
|
|
50
|
+
pluginServices.set(platform, new PluginsService(platform));
|
|
51
|
+
}
|
|
52
|
+
return pluginServices.get(platform);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getRefreshTasks() {
|
|
56
|
+
if (routerOptions.refreshTasks) return routerOptions.refreshTasks;
|
|
57
|
+
if (!defaultRefreshTasks) {
|
|
58
|
+
const persistencePath = PATHS.pluginRefreshTasks
|
|
59
|
+
|| path.join(PATHS.storage || process.cwd(), 'runtime', 'plugin-refresh-tasks.json');
|
|
60
|
+
defaultRefreshTasks = new SkillRefreshTaskService({
|
|
61
|
+
persistencePath,
|
|
62
|
+
worker: context => getPluginServiceForPlatform(context.platform).refreshRemotePlugins(context)
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return defaultRefreshTasks;
|
|
66
|
+
}
|
|
67
|
+
|
|
38
68
|
async function getRequestOptions(req, service) {
|
|
39
69
|
const scope = String(req.query?.scope || req.body?.scope || '').trim();
|
|
40
70
|
if (scope && scope !== 'user' && scope !== 'project') {
|
|
@@ -147,11 +177,15 @@ router.get('/', async (req, res) => {
|
|
|
147
177
|
const { platform, service, warning } = getPluginsService(req);
|
|
148
178
|
const options = await getRequestOptions(req, service);
|
|
149
179
|
const result = invokeWithOptions(service.listPlugins.bind(service), [], options);
|
|
180
|
+
const plugins = typeof service.sanitizePluginList === 'function'
|
|
181
|
+
? service.sanitizePluginList(result.plugins)
|
|
182
|
+
: result.plugins;
|
|
150
183
|
|
|
151
184
|
res.json({
|
|
152
185
|
success: true,
|
|
153
186
|
platform,
|
|
154
187
|
...result,
|
|
188
|
+
plugins,
|
|
155
189
|
...(warning ? { warnings: [warning] } : {})
|
|
156
190
|
});
|
|
157
191
|
} catch (err) {
|
|
@@ -168,12 +202,11 @@ router.get('/market', async (req, res) => {
|
|
|
168
202
|
try {
|
|
169
203
|
const { platform, service, warning } = getPluginsService(req);
|
|
170
204
|
const options = await getRequestOptions(req, service);
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
console.log(`[Plugins API] ${platform}: ${plugins.length} market plugins loaded (refresh=${forceRefresh})`);
|
|
205
|
+
const marketPlugins = await invokeWithOptions(service.getMarketPlugins.bind(service), [false], options);
|
|
206
|
+
const plugins = typeof service.sanitizePluginList === 'function'
|
|
207
|
+
? service.sanitizePluginList(marketPlugins)
|
|
208
|
+
: marketPlugins;
|
|
209
|
+
console.log(`[Plugins API] ${platform}: ${plugins.length} cached market plugins loaded`);
|
|
177
210
|
|
|
178
211
|
res.json({
|
|
179
212
|
success: true,
|
|
@@ -187,6 +220,53 @@ router.get('/market', async (req, res) => {
|
|
|
187
220
|
}
|
|
188
221
|
});
|
|
189
222
|
|
|
223
|
+
/**
|
|
224
|
+
* 启动插件远端全量缓存任务
|
|
225
|
+
* POST /api/plugins/refresh
|
|
226
|
+
*/
|
|
227
|
+
router.post('/refresh', async (req, res) => {
|
|
228
|
+
try {
|
|
229
|
+
const { platform, service } = getPluginsService(req);
|
|
230
|
+
const options = await getRequestOptions(req, service);
|
|
231
|
+
const refreshTasks = getRefreshTasks();
|
|
232
|
+
if (!refreshTasks) throw new Error('Plugin refresh task service is unavailable');
|
|
233
|
+
const task = refreshTasks.enqueue({
|
|
234
|
+
platform,
|
|
235
|
+
scope: options.scope || 'user',
|
|
236
|
+
projectPath: options.scope === 'project' ? options.cwd : null,
|
|
237
|
+
reason: 'manual'
|
|
238
|
+
});
|
|
239
|
+
res.status(202).json({ success: true, platform, task });
|
|
240
|
+
} catch (err) {
|
|
241
|
+
console.error('[Plugins API] Refresh plugins error:', err);
|
|
242
|
+
sendApiError(res, err);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
router.get('/refresh/:taskId', async (req, res) => {
|
|
247
|
+
try {
|
|
248
|
+
const { platform, service } = getPluginsService(req);
|
|
249
|
+
const options = await getRequestOptions({ query: req.query }, service);
|
|
250
|
+
const refreshTasks = getRefreshTasks();
|
|
251
|
+
const task = refreshTasks?.get(req.params.taskId);
|
|
252
|
+
if (!task) return res.status(404).json({ success: false, message: 'Refresh task not found' });
|
|
253
|
+
const taskScope = task.scope || 'user';
|
|
254
|
+
const taskProjectPath = taskScope === 'project' ? (task.projectPath || null) : null;
|
|
255
|
+
const requestedProjectPath = options.scope === 'project' ? (options.cwd || null) : null;
|
|
256
|
+
if (
|
|
257
|
+
task.platform !== platform
|
|
258
|
+
|| taskScope !== (options.scope || 'user')
|
|
259
|
+
|| taskProjectPath !== requestedProjectPath
|
|
260
|
+
) {
|
|
261
|
+
return res.status(404).json({ success: false, message: 'Refresh task not found' });
|
|
262
|
+
}
|
|
263
|
+
return res.json({ success: true, task });
|
|
264
|
+
} catch (err) {
|
|
265
|
+
console.error('[Plugins API] Get refresh task error:', err);
|
|
266
|
+
return sendApiError(res, err);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
|
|
190
270
|
/**
|
|
191
271
|
* 安装插件
|
|
192
272
|
* POST /api/plugins/install
|
|
@@ -435,20 +515,26 @@ router.put('/repos/auth', (req, res) => {
|
|
|
435
515
|
});
|
|
436
516
|
|
|
437
517
|
/**
|
|
438
|
-
*
|
|
518
|
+
* Legacy alias for the explicit plugin refresh task.
|
|
439
519
|
* POST /api/plugins/repos/sync
|
|
440
520
|
*/
|
|
441
521
|
router.post('/repos/sync', async (req, res) => {
|
|
442
522
|
try {
|
|
443
523
|
const { platform, service } = getPluginsService(req);
|
|
444
524
|
const options = await getRequestOptions(req, service);
|
|
445
|
-
const
|
|
525
|
+
const refreshTasks = getRefreshTasks();
|
|
526
|
+
const task = refreshTasks.enqueue({
|
|
527
|
+
platform,
|
|
528
|
+
scope: options.scope || 'user',
|
|
529
|
+
projectPath: options.scope === 'project' ? options.cwd : null,
|
|
530
|
+
reason: 'manual'
|
|
531
|
+
});
|
|
446
532
|
|
|
447
|
-
res.json({
|
|
533
|
+
res.status(202).json({
|
|
448
534
|
success: true,
|
|
449
535
|
platform,
|
|
450
|
-
|
|
451
|
-
message: '
|
|
536
|
+
task,
|
|
537
|
+
message: 'Plugin refresh task started'
|
|
452
538
|
});
|
|
453
539
|
} catch (err) {
|
|
454
540
|
console.error('[Plugins API] Sync repos error:', err);
|
|
@@ -487,6 +573,7 @@ router.get('/:name/readme', async (req, res) => {
|
|
|
487
573
|
try {
|
|
488
574
|
const { platform, service } = getPluginsService(req);
|
|
489
575
|
const { name } = req.params;
|
|
576
|
+
const options = await getRequestOptions(req, service);
|
|
490
577
|
const {
|
|
491
578
|
repoId,
|
|
492
579
|
repoProvider,
|
|
@@ -499,7 +586,9 @@ router.get('/:name/readme', async (req, res) => {
|
|
|
499
586
|
repoUrl,
|
|
500
587
|
repoProjectPath,
|
|
501
588
|
repoLocalPath,
|
|
502
|
-
installPath
|
|
589
|
+
installPath,
|
|
590
|
+
scope: queryScope,
|
|
591
|
+
cwd: queryCwd
|
|
503
592
|
} = req.query;
|
|
504
593
|
|
|
505
594
|
const pluginInfo = {
|
|
@@ -518,7 +607,13 @@ router.get('/:name/readme', async (req, res) => {
|
|
|
518
607
|
installPath
|
|
519
608
|
};
|
|
520
609
|
|
|
521
|
-
const
|
|
610
|
+
const readmeOptions = {
|
|
611
|
+
...(options.scope || queryScope ? { scope: options.scope || queryScope } : {}),
|
|
612
|
+
...(options.cwd || queryCwd ? { cwd: options.cwd || queryCwd } : {})
|
|
613
|
+
};
|
|
614
|
+
const readme = Object.keys(readmeOptions).length > 0
|
|
615
|
+
? await service.getPluginReadme(pluginInfo, readmeOptions)
|
|
616
|
+
: await service.getPluginReadme(pluginInfo);
|
|
522
617
|
|
|
523
618
|
res.json({
|
|
524
619
|
success: true,
|
package/src/server/index.js
CHANGED
|
@@ -58,6 +58,30 @@ function traceStartupMemory(stage) {
|
|
|
58
58
|
})}`);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
async function refreshNativeCodexOAuthOnStartup({ oauthService } = {}) {
|
|
62
|
+
try {
|
|
63
|
+
const service = oauthService || require('../platforms/oauth-credentials-service');
|
|
64
|
+
if (typeof service.refreshNativeCodexOAuth !== 'function') {
|
|
65
|
+
return { available: false, refreshed: false, synchronized: false };
|
|
66
|
+
}
|
|
67
|
+
const result = await service.refreshNativeCodexOAuth();
|
|
68
|
+
if (result?.refreshed) {
|
|
69
|
+
console.log('[Codex OAuth] Native OAuth token refreshed during startup');
|
|
70
|
+
} else if (result?.refreshFailed) {
|
|
71
|
+
console.warn('[Codex OAuth] 启动刷新失败,请运行 codex login 重新登录');
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.warn(`[Codex OAuth] 启动同步失败,保留本地凭证: ${error.message}`);
|
|
76
|
+
return {
|
|
77
|
+
available: false,
|
|
78
|
+
refreshed: false,
|
|
79
|
+
synchronized: false,
|
|
80
|
+
error: error.message
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
61
85
|
function printPortConflictHelp(port) {
|
|
62
86
|
console.log(chalk.yellow('\n[TIP] 解决方案:'));
|
|
63
87
|
console.log(chalk.gray(' 1. 运行 ctx 命令,选择"配置端口"修改端口'));
|
|
@@ -335,6 +359,7 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
|
|
|
335
359
|
console.log(chalk.yellow(' [LOCK] 已启用 LAN 安全保护:远程写操作默认关闭'));
|
|
336
360
|
}
|
|
337
361
|
}
|
|
362
|
+
await refreshNativeCodexOAuthOnStartup();
|
|
338
363
|
// 自动恢复代理状态
|
|
339
364
|
try {
|
|
340
365
|
await autoRestoreProxies({ ...platformContext, config });
|
|
@@ -382,6 +407,10 @@ async function autoRestoreProxies({ registry, runtime, config, fsImpl = require(
|
|
|
382
407
|
try {
|
|
383
408
|
const result = await driver.restoreOnBoot({ config: resolvedConfig });
|
|
384
409
|
if (!result || result.status === 'ok') {
|
|
410
|
+
const warnings = result?.warnings || result?.data?.warnings || result?.result?.warnings || [];
|
|
411
|
+
warnings.forEach((warning) => {
|
|
412
|
+
console.log(chalk.yellow(`[WARN] ${platform.label || key}: ${warning}`));
|
|
413
|
+
});
|
|
385
414
|
const port = result?.port;
|
|
386
415
|
const suffix = port
|
|
387
416
|
? platform.proxyMode === 'managed'
|
|
@@ -464,5 +493,10 @@ async function performStartupHealthCheck({ config = loadConfig() } = {}) {
|
|
|
464
493
|
|
|
465
494
|
module.exports = {
|
|
466
495
|
startServer,
|
|
467
|
-
_test: {
|
|
496
|
+
_test: {
|
|
497
|
+
autoRestoreProxies,
|
|
498
|
+
performStartupHealthCheck,
|
|
499
|
+
traceStartupMemory,
|
|
500
|
+
refreshNativeCodexOAuthOnStartup
|
|
501
|
+
}
|
|
468
502
|
};
|
|
@@ -32,9 +32,18 @@ const CLAUDE_DIRS = {
|
|
|
32
32
|
// Valid config types
|
|
33
33
|
const CONFIG_TYPES = ['skills', 'commands', 'agents', 'plugins'];
|
|
34
34
|
|
|
35
|
+
function supportsManagedResources(platform) {
|
|
36
|
+
const resourceTypes = platform?.resourceTypes;
|
|
37
|
+
if (!resourceTypes || typeof resourceTypes !== 'object' || Array.isArray(resourceTypes)) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
return CONFIG_TYPES.some(type => resourceTypes[type] !== false);
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
function getSupportedPlatforms(registry = getPlatformContext().registry) {
|
|
36
44
|
if (!registry || typeof registry.list !== 'function') return [];
|
|
37
45
|
return registry.list()
|
|
46
|
+
.filter(supportsManagedResources)
|
|
38
47
|
.map(platform => platform && platform.key)
|
|
39
48
|
.filter(Boolean);
|
|
40
49
|
}
|
|
@@ -43,7 +52,7 @@ function buildPlatformSupport(registry = getPlatformContext().registry) {
|
|
|
43
52
|
const support = Object.fromEntries(CONFIG_TYPES.map(type => [type, {}]));
|
|
44
53
|
for (const platform of (registry?.list?.() || [])) {
|
|
45
54
|
const key = platform && platform.key;
|
|
46
|
-
if (!key) continue;
|
|
55
|
+
if (!key || !supportsManagedResources(platform)) continue;
|
|
47
56
|
const resourceDriver = platform.capabilities?.resourceSync;
|
|
48
57
|
for (const type of CONFIG_TYPES) {
|
|
49
58
|
const typeCapability = platform.capabilities && Object.prototype.hasOwnProperty.call(platform.capabilities, type)
|
|
@@ -26,6 +26,7 @@ function getAiConfigMap(registry = getPlatformContext().registry) {
|
|
|
26
26
|
return Object.fromEntries(
|
|
27
27
|
registry.list({ enabledOnly: true })
|
|
28
28
|
.filter(platform => platform && platform.key)
|
|
29
|
+
.filter(platform => platform.resourceTypes?.commands !== false)
|
|
29
30
|
.map(platform => [platform.key, {
|
|
30
31
|
fileName: platform.promptFile || null,
|
|
31
32
|
name: platform.promptLabel
|