@adversity/coding-tool-x 2.6.0 → 2.6.1
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/dist/web/assets/icons-BlzwYoRU.js +1 -0
- package/dist/web/assets/{index-Ej0MPDUI.js → index-AtwYwBZD.js} +2 -2
- package/dist/web/assets/index-BNHWEpD4.css +41 -0
- package/dist/web/assets/{naive-ui-sh0u_0bf.js → naive-ui-BcSq2wzw.js} +1 -1
- package/dist/web/assets/{vendors-CzcvkTIS.js → vendors-D2HHw_aW.js} +1 -1
- package/dist/web/assets/{vue-vendor-CEeI-Azr.js → vue-vendor-6JaYHOiI.js} +1 -1
- package/dist/web/index.html +6 -6
- package/package.json +1 -1
- package/src/server/api/mcp.js +1 -1
- package/src/server/api/plugins.js +150 -10
- package/src/server/api/sessions.js +4 -4
- package/src/server/services/plugins-service.js +537 -37
- package/src/server/services/sessions.js +72 -16
- package/dist/web/assets/icons-CNM9_Fh0.js +0 -1
- package/dist/web/assets/index-BcmuQT-z.css +0 -41
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{S as t}from"./vue-vendor-
|
|
1
|
+
import{S as t}from"./vue-vendor-6JaYHOiI.js";"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function e(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}function n(t){if(t.__esModule)return t;var e=t.default;if("function"==typeof e){var n=function t(){return this instanceof t?Reflect.construct(e,arguments,this.constructor):e.apply(this,arguments)};n.prototype=e.prototype}else n={};return Object.defineProperty(n,"__esModule",{value:!0}),Object.keys(t).forEach(function(e){var r=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(n,e,r.get?r:{enumerable:!0,get:function(){return t[e]}})}),n}var r={exports:{}};const o=n(t);
|
|
2
2
|
/**!
|
|
3
3
|
* Sortable 1.14.0
|
|
4
4
|
* @author RubaXa <trash@rubaxa.org>
|
|
@@ -41,4 +41,4 @@ let ic;const lc=e=>ic=e,cc=Symbol();function ac(e){return e&&"object"==typeof e&
|
|
|
41
41
|
* vue-router v4.6.4
|
|
42
42
|
* (c) 2025 Eduardo San Martin Morote
|
|
43
43
|
* @license MIT
|
|
44
|
-
*/(e,t);n=Na(o.reverse(),"beforeRouteLeave",e,t);for(const s of o)s.leaveGuards.forEach(o=>{n.push(Ra(o,e,t))});const c=y.bind(null,e,t);return n.push(c),M(n).then(()=>{n=[];for(const o of s.list())n.push(Ra(o,e,t));return n.push(c),M(n)}).then(()=>{n=Na(r,"beforeRouteUpdate",e,t);for(const o of r)o.updateGuards.forEach(o=>{n.push(Ra(o,e,t))});return n.push(c),M(n)}).then(()=>{n=[];for(const o of l)if(o.beforeEnter)if(Pc(o.beforeEnter))for(const r of o.beforeEnter)n.push(Ra(r,e,t));else n.push(Ra(o.beforeEnter,e,t));return n.push(c),M(n)}).then(()=>(e.matched.forEach(e=>e.enterCallbacks={}),n=Na(l,"beforeRouteEnter",e,t,b),n.push(c),M(n))).then(()=>{n=[];for(const o of i.list())n.push(Ra(o,e,t));return n.push(c),M(n)}).catch(e=>ba(e,va.NAVIGATION_CANCELLED)?e:Promise.reject(e))}function S(e,t,n){l.list().forEach(o=>b(()=>o(e,t,n)))}function C(e,t,n,o,s){const i=g(e,t);if(i)return i;const l=t===ia,a=Tc?history.state:{};n&&(o||l?r.replace(e.fullPath,Oc({scroll:l&&a&&a.scroll},s)):r.push(e.fullPath,s)),c.value=e,N(e,t,n,l),R()}let x;function w(){x||(x=r.listen((e,t,n)=>{if(!L.listening)return;const o=d(e),s=v(o,L.currentRoute.value);if(s)return void _(Oc(s,{replace:!0,force:!0}),o).catch(Nc);a=o;const i=c.value;var l,u;Tc&&(l=ha(i.fullPath,n.delta),u=pa(),ga.set(l,u)),E(o,i).catch(e=>ba(e,va.NAVIGATION_ABORTED|va.NAVIGATION_CANCELLED)?e:ba(e,va.NAVIGATION_GUARD_REDIRECT)?(_(Oc(h(e.to),{force:!0}),o).then(e=>{ba(e,va.NAVIGATION_ABORTED|va.NAVIGATION_DUPLICATED)&&!n.delta&&n.type===la.pop&&r.go(-1,!1)}).catch(Nc),Promise.reject()):(n.delta&&r.go(-n.delta,!1),O(e,o,i))).then(e=>{(e=e||C(o,i,!1))&&(n.delta&&!ba(e,va.NAVIGATION_CANCELLED)?r.go(-n.delta,!1):n.type===la.pop&&ba(e,va.NAVIGATION_ABORTED|va.NAVIGATION_DUPLICATED)&&r.go(-1,!1)),S(o,i,e)}).catch(Nc)}))}let A,T=Oa(),k=Oa();function O(e,t,n){R(e);const o=k.list();return o.length&&o.forEach(o=>o(e,t,n)),Promise.reject(e)}function R(e){return A||(A=!e,w(),T.list().forEach(([t,n])=>e?n(e):t()),T.reset()),e}function N(t,n,o,r){const{scrollBehavior:s}=e;if(!Tc||!s)return Promise.resolve();const i=!o&&function(e){const t=ga.get(e);return ga.delete(e),t}(ha(t.fullPath,0))||(r||!o)&&history.state&&history.state.scroll||null;return an().then(()=>s(t,n,i)).then(e=>e&&da(e)).catch(e=>O(e,t,n))}const P=e=>r.go(e);let I;const D=new Set,L={currentRoute:c,listening:!0,addRoute:function(e,n){let o,r;return ma(e)?(o=t.getRecordMatcher(e),r=n):r=e,t.addRoute(r,o)},removeRoute:function(e){const n=t.getRecordMatcher(e);n&&t.removeRoute(n)},clearRoutes:t.clearRoutes,hasRoute:function(e){return!!t.getRecordMatcher(e)},getRoutes:function(){return t.getRoutes().map(e=>e.record)},resolve:d,options:e,push:m,replace:function(e){return m(Oc(h(e),{replace:!0}))},go:P,back:()=>P(-1),forward:()=>P(1),beforeEach:s.add,beforeResolve:i.add,afterEach:l.add,onError:k.add,isReady:function(){return A&&c.value!==ia?Promise.resolve():new Promise((e,t)=>{T.add([e,t])})},install(e){e.component("RouterLink",ou),e.component("RouterView",lu),e.config.globalProperties.$router=L,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>Dt(c)}),Tc&&!I&&c.value===ia&&(I=!0,m(r.location).catch(e=>{}));const t={};for(const o in ia)Object.defineProperty(t,o,{get:()=>c.value[o],enumerable:!0});e.provide(Aa,L),e.provide(Ta,vt(t)),e.provide(ka,c);const n=e.unmount;D.add(e),e.unmount=function(){D.delete(e),D.size<1&&(a=ia,x&&x(),x=null,c.value=ia,I=!1,A=!1),n()}}};function M(e){return e.reduce((e,t)=>e.then(()=>b(t)),Promise.resolve())}return L}function au(){return An(Aa)}function uu(e){return An(Ta)}export{au as $,Ki as A,Ls as B,vs as C,ms as D,At as E,gs as F,$o as G,W as H,ec as I,Dt as J,xt as K,wt as L,jt as M,U as N,As as O,Ps as P,Es as Q,Fs as R,sc as S,Wn as T,wc as U,Ac as V,Is as W,Sn as X,Vs as Y,Ts as Z,X as _,_t as a,Qo as a0,
|
|
44
|
+
*/(e,t);n=Na(o.reverse(),"beforeRouteLeave",e,t);for(const s of o)s.leaveGuards.forEach(o=>{n.push(Ra(o,e,t))});const c=y.bind(null,e,t);return n.push(c),M(n).then(()=>{n=[];for(const o of s.list())n.push(Ra(o,e,t));return n.push(c),M(n)}).then(()=>{n=Na(r,"beforeRouteUpdate",e,t);for(const o of r)o.updateGuards.forEach(o=>{n.push(Ra(o,e,t))});return n.push(c),M(n)}).then(()=>{n=[];for(const o of l)if(o.beforeEnter)if(Pc(o.beforeEnter))for(const r of o.beforeEnter)n.push(Ra(r,e,t));else n.push(Ra(o.beforeEnter,e,t));return n.push(c),M(n)}).then(()=>(e.matched.forEach(e=>e.enterCallbacks={}),n=Na(l,"beforeRouteEnter",e,t,b),n.push(c),M(n))).then(()=>{n=[];for(const o of i.list())n.push(Ra(o,e,t));return n.push(c),M(n)}).catch(e=>ba(e,va.NAVIGATION_CANCELLED)?e:Promise.reject(e))}function S(e,t,n){l.list().forEach(o=>b(()=>o(e,t,n)))}function C(e,t,n,o,s){const i=g(e,t);if(i)return i;const l=t===ia,a=Tc?history.state:{};n&&(o||l?r.replace(e.fullPath,Oc({scroll:l&&a&&a.scroll},s)):r.push(e.fullPath,s)),c.value=e,N(e,t,n,l),R()}let x;function w(){x||(x=r.listen((e,t,n)=>{if(!L.listening)return;const o=d(e),s=v(o,L.currentRoute.value);if(s)return void _(Oc(s,{replace:!0,force:!0}),o).catch(Nc);a=o;const i=c.value;var l,u;Tc&&(l=ha(i.fullPath,n.delta),u=pa(),ga.set(l,u)),E(o,i).catch(e=>ba(e,va.NAVIGATION_ABORTED|va.NAVIGATION_CANCELLED)?e:ba(e,va.NAVIGATION_GUARD_REDIRECT)?(_(Oc(h(e.to),{force:!0}),o).then(e=>{ba(e,va.NAVIGATION_ABORTED|va.NAVIGATION_DUPLICATED)&&!n.delta&&n.type===la.pop&&r.go(-1,!1)}).catch(Nc),Promise.reject()):(n.delta&&r.go(-n.delta,!1),O(e,o,i))).then(e=>{(e=e||C(o,i,!1))&&(n.delta&&!ba(e,va.NAVIGATION_CANCELLED)?r.go(-n.delta,!1):n.type===la.pop&&ba(e,va.NAVIGATION_ABORTED|va.NAVIGATION_DUPLICATED)&&r.go(-1,!1)),S(o,i,e)}).catch(Nc)}))}let A,T=Oa(),k=Oa();function O(e,t,n){R(e);const o=k.list();return o.length&&o.forEach(o=>o(e,t,n)),Promise.reject(e)}function R(e){return A||(A=!e,w(),T.list().forEach(([t,n])=>e?n(e):t()),T.reset()),e}function N(t,n,o,r){const{scrollBehavior:s}=e;if(!Tc||!s)return Promise.resolve();const i=!o&&function(e){const t=ga.get(e);return ga.delete(e),t}(ha(t.fullPath,0))||(r||!o)&&history.state&&history.state.scroll||null;return an().then(()=>s(t,n,i)).then(e=>e&&da(e)).catch(e=>O(e,t,n))}const P=e=>r.go(e);let I;const D=new Set,L={currentRoute:c,listening:!0,addRoute:function(e,n){let o,r;return ma(e)?(o=t.getRecordMatcher(e),r=n):r=e,t.addRoute(r,o)},removeRoute:function(e){const n=t.getRecordMatcher(e);n&&t.removeRoute(n)},clearRoutes:t.clearRoutes,hasRoute:function(e){return!!t.getRecordMatcher(e)},getRoutes:function(){return t.getRoutes().map(e=>e.record)},resolve:d,options:e,push:m,replace:function(e){return m(Oc(h(e),{replace:!0}))},go:P,back:()=>P(-1),forward:()=>P(1),beforeEach:s.add,beforeResolve:i.add,afterEach:l.add,onError:k.add,isReady:function(){return A&&c.value!==ia?Promise.resolve():new Promise((e,t)=>{T.add([e,t])})},install(e){e.component("RouterLink",ou),e.component("RouterView",lu),e.config.globalProperties.$router=L,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>Dt(c)}),Tc&&!I&&c.value===ia&&(I=!0,m(r.location).catch(e=>{}));const t={};for(const o in ia)Object.defineProperty(t,o,{get:()=>c.value[o],enumerable:!0});e.provide(Aa,L),e.provide(Ta,vt(t)),e.provide(ka,c);const n=e.unmount;D.add(e),e.unmount=function(){D.delete(e),D.size<1&&(a=ia,x&&x(),x=null,c.value=ia,I=!1,A=!1),n()}}};function M(e){return e.reduce((e,t)=>e.then(()=>b(t)),Promise.resolve())}return L}function au(){return An(Aa)}function uu(e){return An(Ta)}export{au as $,Ki as A,Ls as B,vs as C,ms as D,At as E,gs as F,$o as G,W as H,ec as I,Dt as J,xt as K,wt as L,jt as M,U as N,As as O,Ps as P,Es as Q,Fs as R,sc as S,Wn as T,wc as U,Ac as V,Is as W,Sn as X,Vs as Y,Ts as Z,X as _,_t as a,Qo as a0,zo as a1,Jo as a2,Wl as a3,uu as a4,ql as a5,cu as a6,La as a7,er as a8,To as a9,pc as aa,Bo as b,ui as c,Fo as d,mt as e,Oo as f,zs as g,Ro as h,An as i,Ms as j,co as k,Cn as l,fi as m,an as n,Vo as o,wn as p,tr as q,Rt as r,$s as s,$t as t,ks as u,Nt as v,Pn as w,Rn as x,Ri as y,Cl as z};
|
package/dist/web/index.html
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
<link rel="icon" href="/favicon.ico">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
7
|
<title>CC-TOOL - ClaudeCode增强工作助手</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="modulepreload" crossorigin href="/assets/vue-vendor-
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/vendors-
|
|
11
|
-
<link rel="modulepreload" crossorigin href="/assets/icons-
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/naive-ui-
|
|
13
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-AtwYwBZD.js"></script>
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/assets/vue-vendor-6JaYHOiI.js">
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/assets/vendors-D2HHw_aW.js">
|
|
11
|
+
<link rel="modulepreload" crossorigin href="/assets/icons-BlzwYoRU.js">
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/naive-ui-BcSq2wzw.js">
|
|
13
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BNHWEpD4.css">
|
|
14
14
|
</head>
|
|
15
15
|
<body>
|
|
16
16
|
<div id="app"></div>
|
package/package.json
CHANGED
package/src/server/api/mcp.js
CHANGED
|
@@ -341,7 +341,7 @@ router.get('/servers/:id/tools', async (req, res) => {
|
|
|
341
341
|
try {
|
|
342
342
|
const { id } = req.params;
|
|
343
343
|
const result = await mcpService.getServerTools(id);
|
|
344
|
-
res.json(result);
|
|
344
|
+
res.json({ success: true, ...result });
|
|
345
345
|
} catch (err) {
|
|
346
346
|
res.status(404).json({ success: false, error: err.message });
|
|
347
347
|
}
|
|
@@ -31,23 +31,50 @@ router.get('/', (req, res) => {
|
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* 获取市场插件列表
|
|
36
|
+
* GET /api/plugins/market
|
|
37
|
+
*/
|
|
38
|
+
router.get('/market', async (req, res) => {
|
|
39
|
+
try {
|
|
40
|
+
const plugins = await pluginsService.getMarketPlugins();
|
|
41
|
+
|
|
42
|
+
res.json({
|
|
43
|
+
success: true,
|
|
44
|
+
plugins
|
|
45
|
+
});
|
|
46
|
+
} catch (err) {
|
|
47
|
+
console.error('[Plugins API] Get market plugins error:', err);
|
|
48
|
+
res.status(500).json({
|
|
49
|
+
success: false,
|
|
50
|
+
message: err.message
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
34
55
|
/**
|
|
35
56
|
* 安装插件
|
|
36
57
|
* POST /api/plugins/install
|
|
37
|
-
* Body: {
|
|
58
|
+
* Body: { directory, repo: { owner, name, branch } }
|
|
38
59
|
*/
|
|
39
60
|
router.post('/install', async (req, res) => {
|
|
40
61
|
try {
|
|
41
|
-
const { gitUrl } = req.body;
|
|
42
|
-
|
|
43
|
-
|
|
62
|
+
const { directory, repo, gitUrl } = req.body;
|
|
63
|
+
|
|
64
|
+
// Support both new format (directory + repo) and legacy format (gitUrl)
|
|
65
|
+
let installUrl;
|
|
66
|
+
if (directory && repo) {
|
|
67
|
+
installUrl = `https://github.com/${repo.owner}/${repo.name}/tree/${repo.branch || 'main'}/${directory}`;
|
|
68
|
+
} else if (gitUrl) {
|
|
69
|
+
installUrl = gitUrl;
|
|
70
|
+
} else {
|
|
44
71
|
return res.status(400).json({
|
|
45
72
|
success: false,
|
|
46
|
-
message: '
|
|
73
|
+
message: 'Either (directory + repo) or gitUrl is required'
|
|
47
74
|
});
|
|
48
75
|
}
|
|
49
76
|
|
|
50
|
-
const result = await pluginsService.installPlugin(
|
|
77
|
+
const result = await pluginsService.installPlugin(installUrl);
|
|
51
78
|
|
|
52
79
|
if (!result.success) {
|
|
53
80
|
return res.status(400).json({
|
|
@@ -126,13 +153,13 @@ router.post('/repos', (req, res) => {
|
|
|
126
153
|
|
|
127
154
|
/**
|
|
128
155
|
* 删除插件仓库
|
|
129
|
-
* DELETE /api/plugins/repos/:
|
|
156
|
+
* DELETE /api/plugins/repos/:owner/:name
|
|
130
157
|
*/
|
|
131
|
-
router.delete('/repos/:
|
|
158
|
+
router.delete('/repos/:owner/:name', (req, res) => {
|
|
132
159
|
try {
|
|
133
|
-
const {
|
|
160
|
+
const { owner, name } = req.params;
|
|
134
161
|
|
|
135
|
-
const repos = pluginsService.removeRepo(
|
|
162
|
+
const repos = pluginsService.removeRepo(owner, name);
|
|
136
163
|
|
|
137
164
|
res.json({
|
|
138
165
|
success: true,
|
|
@@ -148,6 +175,119 @@ router.delete('/repos/:id', (req, res) => {
|
|
|
148
175
|
}
|
|
149
176
|
});
|
|
150
177
|
|
|
178
|
+
/**
|
|
179
|
+
* 切换插件仓库启用状态
|
|
180
|
+
* PUT /api/plugins/repos/:owner/:name/toggle
|
|
181
|
+
* Body: { enabled }
|
|
182
|
+
*/
|
|
183
|
+
router.put('/repos/:owner/:name/toggle', (req, res) => {
|
|
184
|
+
try {
|
|
185
|
+
const { owner, name } = req.params;
|
|
186
|
+
const { enabled } = req.body;
|
|
187
|
+
|
|
188
|
+
if (typeof enabled !== 'boolean') {
|
|
189
|
+
return res.status(400).json({
|
|
190
|
+
success: false,
|
|
191
|
+
message: 'enabled must be a boolean'
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const repos = pluginsService.toggleRepo(owner, name, enabled);
|
|
196
|
+
|
|
197
|
+
res.json({
|
|
198
|
+
success: true,
|
|
199
|
+
repos,
|
|
200
|
+
message: `Repository ${enabled ? 'enabled' : 'disabled'} successfully`
|
|
201
|
+
});
|
|
202
|
+
} catch (err) {
|
|
203
|
+
console.error('[Plugins API] Toggle repo error:', err);
|
|
204
|
+
res.status(500).json({
|
|
205
|
+
success: false,
|
|
206
|
+
message: err.message
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* 同步仓库到 Claude Code marketplace
|
|
213
|
+
* POST /api/plugins/repos/sync
|
|
214
|
+
*/
|
|
215
|
+
router.post('/repos/sync', async (req, res) => {
|
|
216
|
+
try {
|
|
217
|
+
const result = await pluginsService.syncRepos();
|
|
218
|
+
|
|
219
|
+
res.json({
|
|
220
|
+
success: true,
|
|
221
|
+
...result,
|
|
222
|
+
message: 'Repositories synced successfully'
|
|
223
|
+
});
|
|
224
|
+
} catch (err) {
|
|
225
|
+
console.error('[Plugins API] Sync repos error:', err);
|
|
226
|
+
res.status(500).json({
|
|
227
|
+
success: false,
|
|
228
|
+
message: err.message
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* 同步本地插件列表
|
|
235
|
+
* POST /api/plugins/sync
|
|
236
|
+
*/
|
|
237
|
+
router.post('/sync', async (req, res) => {
|
|
238
|
+
try {
|
|
239
|
+
const result = await pluginsService.syncPlugins();
|
|
240
|
+
|
|
241
|
+
res.json({
|
|
242
|
+
success: true,
|
|
243
|
+
...result,
|
|
244
|
+
message: 'Plugins synced successfully'
|
|
245
|
+
});
|
|
246
|
+
} catch (err) {
|
|
247
|
+
console.error('[Plugins API] Sync plugins error:', err);
|
|
248
|
+
res.status(500).json({
|
|
249
|
+
success: false,
|
|
250
|
+
message: err.message
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* 获取插件 README
|
|
257
|
+
* GET /api/plugins/:name/readme
|
|
258
|
+
* Query: repoOwner, repoName, repoBranch, directory, source, repoUrl
|
|
259
|
+
*/
|
|
260
|
+
router.get('/:name/readme', async (req, res) => {
|
|
261
|
+
try {
|
|
262
|
+
const { name } = req.params;
|
|
263
|
+
const { repoOwner, repoName, repoBranch, directory, source, repoUrl } = req.query;
|
|
264
|
+
|
|
265
|
+
const pluginInfo = {
|
|
266
|
+
name,
|
|
267
|
+
repoOwner,
|
|
268
|
+
repoName,
|
|
269
|
+
repoBranch,
|
|
270
|
+
directory,
|
|
271
|
+
source,
|
|
272
|
+
repoUrl
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
const readme = await pluginsService.getPluginReadme(pluginInfo);
|
|
276
|
+
|
|
277
|
+
res.json({
|
|
278
|
+
success: true,
|
|
279
|
+
readme
|
|
280
|
+
});
|
|
281
|
+
} catch (err) {
|
|
282
|
+
console.error('[Plugins API] Get plugin README error:', err);
|
|
283
|
+
res.status(500).json({
|
|
284
|
+
success: false,
|
|
285
|
+
message: err.message,
|
|
286
|
+
readme: ''
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
|
|
151
291
|
/**
|
|
152
292
|
* 获取单个插件详情
|
|
153
293
|
* GET /api/plugins/:name
|
|
@@ -10,7 +10,7 @@ const { broadcastLog } = require('../websocket-server');
|
|
|
10
10
|
|
|
11
11
|
module.exports = (config) => {
|
|
12
12
|
// GET /api/sessions/search/global - Search sessions across all projects
|
|
13
|
-
router.get('/search/global', (req, res) => {
|
|
13
|
+
router.get('/search/global', async (req, res) => {
|
|
14
14
|
try {
|
|
15
15
|
const { keyword, context } = req.query;
|
|
16
16
|
|
|
@@ -19,7 +19,7 @@ module.exports = (config) => {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
const contextLength = context ? parseInt(context) : 35;
|
|
22
|
-
const results = searchSessionsAcrossProjects(config, keyword, contextLength);
|
|
22
|
+
const results = await searchSessionsAcrossProjects(config, keyword, contextLength);
|
|
23
23
|
|
|
24
24
|
res.json({
|
|
25
25
|
keyword,
|
|
@@ -33,10 +33,10 @@ module.exports = (config) => {
|
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
// GET /api/sessions/recent - Get recent sessions across all projects
|
|
36
|
-
router.get('/recent/list', (req, res) => {
|
|
36
|
+
router.get('/recent/list', async (req, res) => {
|
|
37
37
|
try {
|
|
38
38
|
const limit = parseInt(req.query.limit) || 5;
|
|
39
|
-
const sessions = getRecentSessions(config, limit);
|
|
39
|
+
const sessions = await getRecentSessions(config, limit);
|
|
40
40
|
res.json({ sessions });
|
|
41
41
|
} catch (error) {
|
|
42
42
|
console.error('Error fetching recent sessions:', error);
|