dsh-plugin-capabilities 0.2.1 → 0.3.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/README.md CHANGED
@@ -39,7 +39,7 @@ MCP 行的变更需要重启 dsh 才会进入组合。MCP 页头部有常驻的
39
39
 
40
40
  ![「MCP 市场」](docs/images/screenshot-market-mcp.png)
41
41
 
42
- 「市场」页分两栏:「技能市场」是精选的技能仓库(Anthropic 官方技能集、Superpowers 工作流集等),点「安装」走的就是上文 GitHub 仓库的下载解包流程,装完立即出现在「技能」页;「MCP 市场」是一份精选服务器列表(官方 filesystem/memory/git 等,加上 context7 这类常用第三方),点「添加」直接写入一条 profile 服务器行,和手工添加完全等价。列表数据来自[本插件仓库](https://github.com/qinyre/dsh-plugin-capabilities)的在线索引(`market/*.json`),离线时自动回退到包内快照;需要 API 密钥的服务器会在卡片上标出环境变量名,装好后到 MCP 列表里补填即可。已安装的条目可以直接卸载:技能仓库走仓库移除,MCP 行走服务器删除。
42
+ 「市场」页分两栏:「技能市场」是精选的技能仓库(Anthropic 官方技能集、Superpowers 工作流集等),点「安装」走的就是上文 GitHub 仓库的下载解包流程,装完立即出现在「技能」页;「MCP 市场」是一份精选服务器列表(官方 filesystem/memory/git 等,加上 context7 这类常用第三方),点「添加」直接写入一条 profile 服务器行,和手工添加完全等价。0.3.0 起点开条目可以看详情:技能仓库列出里面具体有哪些技能,MCP 服务器列出启动命令、需要的环境变量和提供的工具,不必再去 GitHub 主页。列表数据来自[本插件仓库](https://github.com/qinyre/dsh-plugin-capabilities)的在线索引(`market/*.json`),离线时自动回退到包内快照;需要 API 密钥的服务器会在卡片上标出环境变量名,装好后到 MCP 列表里补填即可。已安装的条目可以直接卸载:技能仓库走仓库移除,MCP 行走服务器删除。
43
43
 
44
44
  ## 安装
45
45
 
package/lib/client.js CHANGED
@@ -58,7 +58,7 @@ var CSS = `
58
58
  .dpc-refresh:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px}
59
59
  .dpc-empty{margin:0;font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary)}
60
60
  .dpc-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));align-items:stretch;gap:10px;margin:0;padding:0;list-style:none}
61
- .dpc-card{display:flex;flex-direction:column;gap:8px;min-width:0;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-3);padding:12px 14px}
61
+ .dpc-card{display:flex;flex-direction:column;gap:8px;min-width:0;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-3);padding:12px 14px;cursor:pointer}
62
62
  .dpc-card:hover{background:var(--dsw-alias-interactive-bg-hover)}
63
63
  .dpc-cardTop{display:flex;align-items:center;gap:8px}
64
64
  .dpc-cardTitle{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;line-height:20px;font-weight:600;font-family:var(--ds-font-family-code)}
@@ -140,6 +140,15 @@ var CSS = `
140
140
  .dpc-format .dpc-form{margin-top:8px}
141
141
  .dpc-formatHint{margin:2px 0 0;font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary)}
142
142
  .dpc-code{margin:4px 0 8px;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;padding:8px 10px;overflow-x:auto;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);font-family:var(--ds-font-family-code);font-size:11px;line-height:17px;white-space:pre}
143
+ /* Market detail modal. */
144
+ .dpc-detailDesc{margin:0;font-size:13px;line-height:20px}
145
+ .dpc-detailSection{margin-top:12px;display:flex;flex-direction:column;gap:6px}
146
+ .dpc-detailLabel{font-size:11px;line-height:16px;color:var(--dsw-alias-label-secondary)}
147
+ .dpc-detailTags{display:flex;flex-wrap:wrap;gap:4px}
148
+ .dpc-skillList{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:4px}
149
+ .dpc-skillItem{display:flex;gap:8px;align-items:baseline;font-size:12px;line-height:18px;min-width:0}
150
+ .dpc-skillName{font-family:var(--ds-font-family-code);color:var(--dsw-alias-label-primary);white-space:nowrap;flex:none}
151
+ .dpc-skillDesc{color:var(--dsw-alias-label-secondary);min-width:0}
143
152
  @media(max-width:680px){.dpc-cards{grid-template-columns:minmax(0,1fr)}}
144
153
  `;
145
154
 
@@ -157,6 +166,7 @@ function MarketTab(props) {
157
166
  const [busyId, setBusyId] = (0, import_react.useState)(null);
158
167
  const [outcome, setOutcome] = (0, import_react.useState)(null);
159
168
  const [confirmUninstall, setConfirmUninstall] = (0, import_react.useState)(null);
169
+ const [detail, setDetail] = (0, import_react.useState)(null);
160
170
  const [reload, setReload] = (0, import_react.useState)(0);
161
171
  const refreshSkills = (0, import_react.useCallback)(() => {
162
172
  setRepos(null);
@@ -240,6 +250,12 @@ function MarketTab(props) {
240
250
  const pick = (base, zh2) => zhUi() && zh2 !== void 0 ? zh2 : base;
241
251
  const title = (entry) => pick(entry.name, entry.nameZh);
242
252
  const desc = (entry) => pick(entry.description, entry.descriptionZh);
253
+ const longText = (entry) => entry.detail !== void 0 ? pick(entry.detail, entry.detailZh) : desc(entry);
254
+ const cardStop = (event) => {
255
+ event.stopPropagation();
256
+ };
257
+ const detailRepo = detail !== null && detail.kind === "skills" && repos !== null ? repos.find((repo) => repo.id === detail.id) ?? null : null;
258
+ const detailServer = detail !== null && detail.kind === "mcp" && servers !== null ? servers.find((server) => server.id === detail.id) ?? null : null;
243
259
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-section", children: [
244
260
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: CSS }),
245
261
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-head", children: [
@@ -264,7 +280,7 @@ function MarketTab(props) {
264
280
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-intro", children: t("marketSkillsIntro") }),
265
281
  repos === null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-empty", children: t("loading") }),
266
282
  repos !== null && repos.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-empty", children: t("marketEmpty") }),
267
- repos !== null && repos.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "dpc-cards", children: repos.map((repo) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "dpc-card", children: [
283
+ repos !== null && repos.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "dpc-cards", children: repos.map((repo) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "dpc-card", onClick: () => setDetail({ kind: "skills", id: repo.id }), children: [
268
284
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-cardTop", children: [
269
285
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { className: "dpc-cardTitle", title: repo.url, children: title(repo) }),
270
286
  repo.skillCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-tag", children: t("marketSkillCount").replace("{n}", String(repo.skillCount)) }),
@@ -272,9 +288,16 @@ function MarketTab(props) {
272
288
  ] }),
273
289
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-cardDesc", children: desc(repo) }),
274
290
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-cardRow", children: [
275
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { className: "dpc-link", href: repo.homepage ?? repo.url, target: "_blank", rel: "noreferrer", children: t("marketHome") }),
291
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "dpc-link", onClick: () => setDetail({ kind: "skills", id: repo.id }), children: t("marketDetail") }),
292
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { className: "dpc-link", href: repo.homepage ?? repo.url, target: "_blank", rel: "noreferrer", onClick: cardStop, children: t("marketHome") }),
276
293
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-spacer" }),
277
- repo.installedId !== null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "ghost", size: "sm", disabled: busyId !== null, onClick: () => setConfirmUninstall({ kind: "root", id: repo.installedId, name: title(repo) }), children: t("marketUninstall") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "primary", size: "sm", disabled: busyId !== null, onClick: () => void doInstallRepo(repo), children: busyId === repo.id ? t("marketInstalling") : t("marketInstall") })
294
+ repo.installedId !== null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "ghost", size: "sm", disabled: busyId !== null, onClick: (event) => {
295
+ event.stopPropagation();
296
+ setConfirmUninstall({ kind: "root", id: repo.installedId, name: title(repo) });
297
+ }, children: t("marketUninstall") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "primary", size: "sm", disabled: busyId !== null, onClick: (event) => {
298
+ event.stopPropagation();
299
+ void doInstallRepo(repo);
300
+ }, children: busyId === repo.id ? t("marketInstalling") : t("marketInstall") })
278
301
  ] })
279
302
  ] }, repo.id)) })
280
303
  ] }),
@@ -282,7 +305,7 @@ function MarketTab(props) {
282
305
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-intro", children: t("marketMcpIntro") }),
283
306
  servers === null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-empty", children: t("loading") }),
284
307
  servers !== null && servers.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-empty", children: t("marketEmpty") }),
285
- servers !== null && servers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "dpc-cards", children: servers.map((server) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "dpc-card", children: [
308
+ servers !== null && servers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "dpc-cards", children: servers.map((server) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "dpc-card", onClick: () => setDetail({ kind: "mcp", id: server.id }), children: [
286
309
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-cardTop", children: [
287
310
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { className: "dpc-cardTitle", title: server.id, children: title(server) }),
288
311
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-tag", children: server.transport }),
@@ -296,18 +319,83 @@ function MarketTab(props) {
296
319
  server.envKeys.join(", ")
297
320
  ] }),
298
321
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-cardRow", children: [
299
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { className: "dpc-link", href: server.homepage, target: "_blank", rel: "noreferrer", children: t("marketHome") }),
322
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "dpc-link", onClick: () => setDetail({ kind: "mcp", id: server.id }), children: t("marketDetail") }),
323
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { className: "dpc-link", href: server.homepage, target: "_blank", rel: "noreferrer", onClick: cardStop, children: t("marketHome") }),
300
324
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-spacer" }),
301
- server.installed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "ghost", size: "sm", disabled: busyId !== null, onClick: () => void mcp.list().then(
302
- (body) => {
303
- const row = body.servers.find((item) => item.serverName === server.id);
304
- if (row !== void 0) setConfirmUninstall({ kind: "mcp", id: row.id, name: server.id });
305
- },
306
- (error) => setOutcome({ ok: false, text: `${t("failed")}: ${String(error.message ?? error)}` })
307
- ), children: t("marketUninstall") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "primary", size: "sm", disabled: busyId !== null, onClick: () => void doInstallMcp(server), children: busyId === server.id ? t("marketInstalling") : t("marketAdd") })
325
+ server.installed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "ghost", size: "sm", disabled: busyId !== null, onClick: (event) => {
326
+ event.stopPropagation();
327
+ void mcp.list().then(
328
+ (body) => {
329
+ const row = body.servers.find((item) => item.serverName === server.id);
330
+ if (row !== void 0) setConfirmUninstall({ kind: "mcp", id: row.id, name: server.id });
331
+ },
332
+ (error) => setOutcome({ ok: false, text: `${t("failed")}: ${String(error.message ?? error)}` })
333
+ );
334
+ }, children: t("marketUninstall") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "primary", size: "sm", disabled: busyId !== null, onClick: (event) => {
335
+ event.stopPropagation();
336
+ void doInstallMcp(server);
337
+ }, children: busyId === server.id ? t("marketInstalling") : t("marketAdd") })
308
338
  ] })
309
339
  ] }, server.id)) })
310
340
  ] }),
341
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
342
+ import_dsh_client_ui_primitives.Modal,
343
+ {
344
+ open: detailRepo !== null || detailServer !== null,
345
+ onClose: () => setDetail(null),
346
+ title: detailRepo !== null ? title(detailRepo) : detailServer !== null ? title(detailServer) : "",
347
+ footer: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
348
+ detailRepo !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { className: "dpc-link", href: detailRepo.homepage ?? detailRepo.url, target: "_blank", rel: "noreferrer", children: t("marketHome") }),
349
+ detailServer !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { className: "dpc-link", href: detailServer.homepage, target: "_blank", rel: "noreferrer", children: t("marketHome") }),
350
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-spacer" }),
351
+ detailRepo !== null && (detailRepo.installedId !== null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "ghost", disabled: busyId !== null, onClick: () => {
352
+ setConfirmUninstall({ kind: "root", id: detailRepo.installedId, name: title(detailRepo) });
353
+ setDetail(null);
354
+ }, children: t("marketUninstall") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "primary", disabled: busyId !== null, onClick: () => void doInstallRepo(detailRepo), children: busyId === detailRepo.id ? t("marketInstalling") : t("marketInstall") })),
355
+ detailServer !== null && (detailServer.installed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "ghost", disabled: busyId !== null, onClick: () => void mcp.list().then(
356
+ (body) => {
357
+ const row = body.servers.find((item) => item.serverName === detailServer.id);
358
+ if (row !== void 0) {
359
+ setConfirmUninstall({ kind: "mcp", id: row.id, name: title(detailServer) });
360
+ setDetail(null);
361
+ }
362
+ },
363
+ (error) => setOutcome({ ok: false, text: `${t("failed")}: ${String(error.message ?? error)}` })
364
+ ), children: t("marketUninstall") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "primary", disabled: busyId !== null, onClick: () => void doInstallMcp(detailServer), children: busyId === detailServer.id ? t("marketInstalling") : t("marketAdd") }))
365
+ ] }),
366
+ children: [
367
+ detailRepo !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
368
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-detailDesc", children: longText(detailRepo) }),
369
+ detailRepo.skills !== void 0 && detailRepo.skills.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-detailSection", children: [
370
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dpc-detailLabel", children: t("marketSkillListLabel") }),
371
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "dpc-skillList", children: detailRepo.skills.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "dpc-skillItem", children: [
372
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { className: "dpc-skillName", children: item.name }),
373
+ item.description !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-skillDesc", children: pick(item.description, item.descriptionZh) })
374
+ ] }, item.name)) })
375
+ ] })
376
+ ] }),
377
+ detailServer !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
378
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-detailDesc", children: longText(detailServer) }),
379
+ detailServer.command !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-detailSection", children: [
380
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dpc-detailLabel", children: t("marketCommandLabel") }),
381
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { className: "dpc-code", children: [detailServer.command, ...detailServer.args ?? []].join(" ") })
382
+ ] }),
383
+ detailServer.transport === "streamable-http" && detailServer.url !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-detailSection", children: [
384
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dpc-detailLabel", children: t("marketCommandLabel") }),
385
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { className: "dpc-code", children: detailServer.url })
386
+ ] }),
387
+ detailServer.envKeys !== void 0 && detailServer.envKeys.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-detailSection", children: [
388
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dpc-detailLabel", children: t("marketNeedsEnv") }),
389
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dpc-detailTags", children: detailServer.envKeys.map((key) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-tag", children: key }, key)) })
390
+ ] }),
391
+ detailServer.tools !== void 0 && detailServer.tools.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-detailSection", children: [
392
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dpc-detailLabel", children: t("marketToolsLabel") }),
393
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dpc-detailTags", children: detailServer.tools.map((name2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-tag", children: name2 }, name2)) })
394
+ ] })
395
+ ] })
396
+ ]
397
+ }
398
+ ),
311
399
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
312
400
  import_dsh_client_ui_primitives.Modal,
313
401
  {
@@ -1588,7 +1676,11 @@ var zh = {
1588
1676
  marketNeedsEnv: "\u9700\u8981\u73AF\u5883\u53D8\u91CF",
1589
1677
  marketRepoInstalled: "\u4ED3\u5E93\u5DF2\u5B89\u88C5\uFF0C\u6280\u80FD\u7A0D\u5019\u51FA\u73B0\u5728\u300C\u6280\u80FD\u300D\u9875\u5217\u8868\u3002",
1590
1678
  marketUninstallConfirm: "\u786E\u8BA4\u79FB\u9664\uFF1F",
1591
- marketUninstallRootWarn: "\u5C06\u53D6\u6D88\u626B\u63CF\u8BE5\u4ED3\u5E93\u5E76\u5220\u9664\u4E0B\u8F7D\u7684\u526F\u672C\uFF08\u79FB\u9664\u540E\u53EF\u91CD\u65B0\u5B89\u88C5\uFF09\u3002"
1679
+ marketUninstallRootWarn: "\u5C06\u53D6\u6D88\u626B\u63CF\u8BE5\u4ED3\u5E93\u5E76\u5220\u9664\u4E0B\u8F7D\u7684\u526F\u672C\uFF08\u79FB\u9664\u540E\u53EF\u91CD\u65B0\u5B89\u88C5\uFF09\u3002",
1680
+ marketDetail: "\u8BE6\u60C5",
1681
+ marketSkillListLabel: "\u6280\u80FD\u6E05\u5355",
1682
+ marketToolsLabel: "\u63D0\u4F9B\u5DE5\u5177",
1683
+ marketCommandLabel: "\u542F\u52A8\u547D\u4EE4"
1592
1684
  };
1593
1685
  var en = {
1594
1686
  sectionNav: "Skills & MCP",
@@ -1714,7 +1806,11 @@ var en = {
1714
1806
  marketNeedsEnv: "Needs environment variables",
1715
1807
  marketRepoInstalled: "Repository installed \u2014 its skills appear on the Skills tab shortly.",
1716
1808
  marketUninstallConfirm: "Uninstall?",
1717
- marketUninstallRootWarn: "Stops scanning the repository and deletes the downloaded copy (you can reinstall later)."
1809
+ marketUninstallRootWarn: "Stops scanning the repository and deletes the downloaded copy (you can reinstall later).",
1810
+ marketDetail: "Details",
1811
+ marketSkillListLabel: "Skills included",
1812
+ marketToolsLabel: "Tools provided",
1813
+ marketCommandLabel: "Launch command"
1718
1814
  };
1719
1815
 
1720
1816
  // src/client/index.ts