@dsh-tom/dsh-css 0.2.11 → 0.3.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 CHANGED
@@ -22,7 +22,7 @@ npm publish --access public --registry=https://registry.npmjs.org/
22
22
  打开 **插件 → 添加插件 → 安装第三方插件**,在“包名或地址”输入:
23
23
 
24
24
  ```text
25
- D:\product\dsh-css\dsh-tom-dsh-css-0.2.11.tgz
25
+ D:\product\dsh-css\dsh-tom-dsh-css-0.3.2.tgz
26
26
  ```
27
27
 
28
28
  安装并启用,然后完全退出并重新打开 dsh。
@@ -32,7 +32,7 @@ D:\product\dsh-css\dsh-tom-dsh-css-0.2.11.tgz
32
32
  包发布到 npmjs 后,先卸载已安装的旧版,再打开 **插件 → 添加插件 → 安装第三方插件**,输入:
33
33
 
34
34
  ```text
35
- @dsh-tom/dsh-css@0.2.11
35
+ @dsh-tom/dsh-css@0.3.2
36
36
  ```
37
37
 
38
38
  选择 **安装源 → npm 官方源**,安装并启用,然后完全退出并重新打开 dsh。
package/dist/client.js CHANGED
@@ -29,7 +29,7 @@ __export(client_exports, {
29
29
  inject: () => inject2
30
30
  });
31
31
  module.exports = __toCommonJS(client_exports);
32
- var import_react8 = require("react");
32
+ var import_react9 = require("react");
33
33
 
34
34
  // theme.css
35
35
  var theme_default = `.dsh-css-unread-dot {
@@ -1319,8 +1319,48 @@ function registerUnread(ctx) {
1319
1319
  }, UnreadIndicator));
1320
1320
  }
1321
1321
 
1322
+ // src/rea/client.js
1323
+ var import_react5 = require("react");
1324
+ function ReaIcon(props) {
1325
+ return (0, import_react5.createElement)(
1326
+ "svg",
1327
+ {
1328
+ width: 16,
1329
+ height: 16,
1330
+ viewBox: "0 0 24 24",
1331
+ fill: "none",
1332
+ stroke: "currentColor",
1333
+ strokeWidth: 1.65,
1334
+ strokeLinecap: "round",
1335
+ strokeLinejoin: "round",
1336
+ "aria-hidden": true,
1337
+ ...props
1338
+ },
1339
+ (0, import_react5.createElement)("path", { d: "M6 3v2m4-2v2M3 8h2m-2 4h2m3 5v2M14 5H7a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2M8 8h4v3H8z" }),
1340
+ (0, import_react5.createElement)("circle", { cx: 15, cy: 15, r: 5 }),
1341
+ (0, import_react5.createElement)("path", { d: "m19 19 3 3" })
1342
+ );
1343
+ }
1344
+ function registerReaIcon(ctx) {
1345
+ ctx.effect(() => {
1346
+ const commands = ctx.commandUi;
1347
+ const original = commands.candidates;
1348
+ const descriptor = Object.getOwnPropertyDescriptor(commands, "candidates");
1349
+ const candidates = async function(...args) {
1350
+ const rows = await original.apply(this, args);
1351
+ return rows.map((row) => row.name === "rea" ? { ...row, icon: ReaIcon } : row);
1352
+ };
1353
+ commands.candidates = candidates;
1354
+ return () => {
1355
+ if (Object.getOwnPropertyDescriptor(commands, "candidates")?.value !== candidates) return;
1356
+ if (descriptor) Object.defineProperty(commands, "candidates", descriptor);
1357
+ else delete commands.candidates;
1358
+ };
1359
+ });
1360
+ }
1361
+
1322
1362
  // src/cost/client.js
1323
- var import_react7 = require("react");
1363
+ var import_react8 = require("react");
1324
1364
 
1325
1365
  // src/cost/pricing.js
1326
1366
  var PROJECTION_KEY = "dshTomCost";
@@ -1358,7 +1398,7 @@ function formatMoney(units) {
1358
1398
  }
1359
1399
 
1360
1400
  // src/cost/panel.js
1361
- var import_react5 = require("react");
1401
+ var import_react6 = require("react");
1362
1402
  var import_react_dom = require("react-dom");
1363
1403
 
1364
1404
  // src/cost/panel-styles.js
@@ -1434,8 +1474,8 @@ function costRows(totals, daily, day = beijingDay()) {
1434
1474
  ];
1435
1475
  }
1436
1476
  function useBeijingDay() {
1437
- const [day, setDay] = (0, import_react5.useState)(beijingDay);
1438
- (0, import_react5.useEffect)(() => {
1477
+ const [day, setDay] = (0, import_react6.useState)(beijingDay);
1478
+ (0, import_react6.useEffect)(() => {
1439
1479
  let timer;
1440
1480
  const refresh = () => {
1441
1481
  const current = beijingDay();
@@ -1449,7 +1489,7 @@ function useBeijingDay() {
1449
1489
  return day;
1450
1490
  }
1451
1491
  function CostIcon() {
1452
- return (0, import_react5.createElement)(
1492
+ return (0, import_react6.createElement)(
1453
1493
  "svg",
1454
1494
  {
1455
1495
  viewBox: "0 0 24 24",
@@ -1462,18 +1502,18 @@ function CostIcon() {
1462
1502
  strokeLinejoin: "round",
1463
1503
  "aria-hidden": true
1464
1504
  },
1465
- (0, import_react5.createElement)("circle", { cx: 12, cy: 12, r: 9 }),
1466
- (0, import_react5.createElement)("path", { d: "m8.5 7.5 3.5 4 3.5-4M8.5 12h7M8.5 15h7M12 11.5V18" })
1505
+ (0, import_react6.createElement)("circle", { cx: 12, cy: 12, r: 9 }),
1506
+ (0, import_react6.createElement)("path", { d: "m8.5 7.5 3.5 4 3.5-4M8.5 12h7M8.5 15h7M12 11.5V18" })
1467
1507
  );
1468
1508
  }
1469
1509
  function CostPanel({ totals, daily, balance }) {
1470
1510
  const day = useBeijingDay();
1471
1511
  const rows = costRows(totals, daily, day);
1472
- const [open2, setOpen] = (0, import_react5.useState)(false);
1473
- const anchor2 = (0, import_react5.useRef)(null);
1474
- const panel = (0, import_react5.useRef)(null);
1475
- const dialogId = (0, import_react5.useId)();
1476
- (0, import_react5.useLayoutEffect)(() => {
1512
+ const [open2, setOpen] = (0, import_react6.useState)(false);
1513
+ const anchor2 = (0, import_react6.useRef)(null);
1514
+ const panel = (0, import_react6.useRef)(null);
1515
+ const dialogId = (0, import_react6.useId)();
1516
+ (0, import_react6.useLayoutEffect)(() => {
1477
1517
  if (!open2) return;
1478
1518
  const element = panel.current;
1479
1519
  const document2 = element.ownerDocument;
@@ -1512,11 +1552,11 @@ function CostPanel({ totals, daily, balance }) {
1512
1552
  document2.removeEventListener("keydown", dismissEscape);
1513
1553
  };
1514
1554
  }, [open2]);
1515
- return (0, import_react5.createElement)(
1555
+ return (0, import_react6.createElement)(
1516
1556
  "span",
1517
1557
  { className: "dsh-tom-cost-anchor", "data-composer-stat": "cost" },
1518
- (0, import_react5.createElement)("style", { "data-dsh-tom-cost-styles": "" }, panelStyles),
1519
- (0, import_react5.createElement)("button", {
1558
+ (0, import_react6.createElement)("style", { "data-dsh-tom-cost-styles": "" }, panelStyles),
1559
+ (0, import_react6.createElement)("button", {
1520
1560
  ref: anchor2,
1521
1561
  type: "button",
1522
1562
  className: "dsh-tom-cost-pill",
@@ -1526,8 +1566,8 @@ function CostPanel({ totals, daily, balance }) {
1526
1566
  "aria-controls": open2 ? dialogId : void 0,
1527
1567
  "aria-label": `\u4F1A\u8BDD\u7D2F\u8BA1\u8D39\u7528 ${rows[1][1]}`,
1528
1568
  onClick: () => setOpen(!open2)
1529
- }, (0, import_react5.createElement)(CostIcon), (0, import_react5.createElement)("span", { className: "dsh-tom-cost-label" }, rows[1][1])),
1530
- open2 && (0, import_react_dom.createPortal)((0, import_react5.createElement)(
1569
+ }, (0, import_react6.createElement)(CostIcon), (0, import_react6.createElement)("span", { className: "dsh-tom-cost-label" }, rows[1][1])),
1570
+ open2 && (0, import_react_dom.createPortal)((0, import_react6.createElement)(
1531
1571
  "div",
1532
1572
  {
1533
1573
  ref: panel,
@@ -1537,11 +1577,11 @@ function CostPanel({ totals, daily, balance }) {
1537
1577
  className: "dsh-tom-cost-panel",
1538
1578
  style: { visibility: "hidden", left: 0, top: 0 }
1539
1579
  },
1540
- (0, import_react5.createElement)("div", { className: "dsh-tom-cost-title" }, (0, import_react5.createElement)(CostIcon), "\u8D39\u7528\u660E\u7EC6"),
1541
- (0, import_react5.createElement)("div", { className: "dsh-tom-cost-rule", "aria-hidden": true }),
1542
- (0, import_react5.createElement)("dl", { className: "dsh-tom-cost-details" }, rows.flatMap(([label, value]) => [
1543
- (0, import_react5.createElement)("dt", { key: label }, label),
1544
- (0, import_react5.createElement)("dd", { key: `${label}-value` }, value)
1580
+ (0, import_react6.createElement)("div", { className: "dsh-tom-cost-title" }, (0, import_react6.createElement)(CostIcon), "\u8D39\u7528\u660E\u7EC6"),
1581
+ (0, import_react6.createElement)("div", { className: "dsh-tom-cost-rule", "aria-hidden": true }),
1582
+ (0, import_react6.createElement)("dl", { className: "dsh-tom-cost-details" }, rows.flatMap(([label, value]) => [
1583
+ (0, import_react6.createElement)("dt", { key: label }, label),
1584
+ (0, import_react6.createElement)("dd", { key: `${label}-value` }, value)
1545
1585
  ]))
1546
1586
  ), anchor2.current.ownerDocument.body)
1547
1587
  );
@@ -21488,7 +21528,7 @@ function createBalanceStore(readBalance) {
21488
21528
  }
21489
21529
 
21490
21530
  // src/cost/settings.js
21491
- var import_react6 = require("react");
21531
+ var import_react7 = require("react");
21492
21532
 
21493
21533
  // src/cost/settings-styles.js
21494
21534
  var settingsStyles = `
@@ -21544,62 +21584,62 @@ function usageSummary(row) {
21544
21584
  function CostSettings({ useCostReport }) {
21545
21585
  const report = useCostReport((value2) => value2);
21546
21586
  const day = useBeijingDay();
21547
- const [hideZero, setHideZero] = (0, import_react6.useState)(true);
21587
+ const [hideZero, setHideZero] = (0, import_react7.useState)(true);
21548
21588
  const value = report.status === "ready" && report.value.day === day ? report.value : void 0;
21549
21589
  const status = report.status === "error" ? "\u8BFB\u53D6\u5931\u8D25" : "\u52A0\u8F7D\u4E2D\u2026";
21550
21590
  const rows = value ? visibleHistory(value.history, hideZero) : [];
21551
21591
  const summaries = [["today", "\u4ECA\u65E5\u8D39\u7528"], ["week", "\u672C\u5468\u8D39\u7528"], ["month", "\u672C\u6708\u8D39\u7528"]];
21552
- return (0, import_react6.createElement)(
21592
+ return (0, import_react7.createElement)(
21553
21593
  "section",
21554
21594
  { className: "dsh-tom-cost-settings", "aria-label": "\u8D39\u7528" },
21555
- (0, import_react6.createElement)("style", null, settingsStyles),
21556
- (0, import_react6.createElement)("div", { className: "dsh-tom-cost-cards" }, summaries.map(([key, label]) => {
21595
+ (0, import_react7.createElement)("style", null, settingsStyles),
21596
+ (0, import_react7.createElement)("div", { className: "dsh-tom-cost-cards" }, summaries.map(([key, label]) => {
21557
21597
  const row = value?.[key];
21558
- return (0, import_react6.createElement)(
21598
+ return (0, import_react7.createElement)(
21559
21599
  "div",
21560
21600
  { key, className: "dsh-tom-cost-card" },
21561
- (0, import_react6.createElement)("div", { className: "dsh-tom-cost-card-label" }, label),
21562
- (0, import_react6.createElement)("div", { className: "dsh-tom-cost-amount" }, row ? costValue(row.totals, row.failedSessions) : status),
21563
- (0, import_react6.createElement)("div", { className: "dsh-tom-cost-usage" }, usageSummary(row))
21601
+ (0, import_react7.createElement)("div", { className: "dsh-tom-cost-card-label" }, label),
21602
+ (0, import_react7.createElement)("div", { className: "dsh-tom-cost-amount" }, row ? costValue(row.totals, row.failedSessions) : status),
21603
+ (0, import_react7.createElement)("div", { className: "dsh-tom-cost-usage" }, usageSummary(row))
21564
21604
  );
21565
21605
  })),
21566
- (0, import_react6.createElement)(
21606
+ (0, import_react7.createElement)(
21567
21607
  "div",
21568
21608
  { className: "dsh-tom-cost-history-heading" },
21569
- (0, import_react6.createElement)("h3", null, "\u5386\u53F2\u8BB0\u5F55", (0, import_react6.createElement)("span", null, "\u6700\u8FD1 30 \u5929")),
21570
- (0, import_react6.createElement)(
21609
+ (0, import_react7.createElement)("h3", null, "\u5386\u53F2\u8BB0\u5F55", (0, import_react7.createElement)("span", null, "\u6700\u8FD1 30 \u5929")),
21610
+ (0, import_react7.createElement)(
21571
21611
  "label",
21572
21612
  { className: "dsh-tom-cost-filter" },
21573
- (0, import_react6.createElement)("input", { type: "checkbox", checked: hideZero, onChange: (event) => setHideZero(event.target.checked) }),
21613
+ (0, import_react7.createElement)("input", { type: "checkbox", checked: hideZero, onChange: (event) => setHideZero(event.target.checked) }),
21574
21614
  "\u8FC7\u6EE4\u96F6\u8D39\u7528\u65E5\u671F"
21575
21615
  )
21576
21616
  ),
21577
- (0, import_react6.createElement)(
21617
+ (0, import_react7.createElement)(
21578
21618
  "div",
21579
21619
  { className: "dsh-tom-cost-table-wrap", tabIndex: 0, role: "region", "aria-label": "\u6BCF\u65E5\u8D39\u7528\u5386\u53F2\u8BB0\u5F55" },
21580
- (0, import_react6.createElement)(
21620
+ (0, import_react7.createElement)(
21581
21621
  "table",
21582
21622
  { className: "dsh-tom-cost-table" },
21583
- (0, import_react6.createElement)("thead", null, (0, import_react6.createElement)("tr", null, ["\u65E5\u671F", "\u8C03\u7528", "\u8F93\u5165 tok", "\u7F13\u5B58 tok", "\u8F93\u51FA tok", "\u8D39\u7528"].map((label) => (0, import_react6.createElement)("th", { key: label, scope: "col" }, label)))),
21584
- (0, import_react6.createElement)("tbody", null, value && rows.length ? rows.map((row) => {
21623
+ (0, import_react7.createElement)("thead", null, (0, import_react7.createElement)("tr", null, ["\u65E5\u671F", "\u8C03\u7528", "\u8F93\u5165 tok", "\u7F13\u5B58 tok", "\u8F93\u51FA tok", "\u8D39\u7528"].map((label) => (0, import_react7.createElement)("th", { key: label, scope: "col" }, label)))),
21624
+ (0, import_react7.createElement)("tbody", null, value && rows.length ? rows.map((row) => {
21585
21625
  const totals = row.totals;
21586
21626
  const unavailable = row.failedSessions > 0 && calls(totals) === 0;
21587
- return (0, import_react6.createElement)(
21627
+ return (0, import_react7.createElement)(
21588
21628
  "tr",
21589
21629
  { key: row.day },
21590
- (0, import_react6.createElement)("td", null, row.day),
21591
- (0, import_react6.createElement)("td", null, unavailable ? "\u2014" : calls(totals).toLocaleString("zh-CN")),
21592
- ...["inputTokens", "cacheTokens", "outputTokens"].map((key) => (0, import_react6.createElement)("td", {
21630
+ (0, import_react7.createElement)("td", null, row.day),
21631
+ (0, import_react7.createElement)("td", null, unavailable ? "\u2014" : calls(totals).toLocaleString("zh-CN")),
21632
+ ...["inputTokens", "cacheTokens", "outputTokens"].map((key) => (0, import_react7.createElement)("td", {
21593
21633
  key,
21594
21634
  title: unavailable ? void 0 : totals[key].toLocaleString("zh-CN")
21595
21635
  }, unavailable ? "\u2014" : formatTokens(totals[key]))),
21596
- (0, import_react6.createElement)("td", null, costValue(totals, row.failedSessions))
21636
+ (0, import_react7.createElement)("td", null, costValue(totals, row.failedSessions))
21597
21637
  );
21598
- }) : (0, import_react6.createElement)("tr", null, (0, import_react6.createElement)("td", { colSpan: 6, className: "dsh-tom-cost-empty", role: "status" }, value ? "\u6700\u8FD1 30 \u5929\u6682\u65E0\u975E\u96F6\u8D39\u7528\u8BB0\u5F55" : status)))
21638
+ }) : (0, import_react7.createElement)("tr", null, (0, import_react7.createElement)("td", { colSpan: 6, className: "dsh-tom-cost-empty", role: "status" }, value ? "\u6700\u8FD1 30 \u5929\u6682\u65E0\u975E\u96F6\u8D39\u7528\u8BB0\u5F55" : status)))
21599
21639
  )
21600
21640
  ),
21601
- (0, import_react6.createElement)("p", { className: "dsh-tom-cost-note" }, "\u5317\u4EAC\u65F6\u95F4 \xB7 \u672C\u5468\u4ECE\u5468\u4E00\u5F00\u59CB \xB7 \u8D39\u7528\u6309\u672C\u673A\u4F1A\u8BDD\u8BB0\u5F55\u4F30\u7B97"),
21602
- value && value.history.some(incomplete) && (0, import_react6.createElement)(
21641
+ (0, import_react7.createElement)("p", { className: "dsh-tom-cost-note" }, "\u5317\u4EAC\u65F6\u95F4 \xB7 \u672C\u5468\u4ECE\u5468\u4E00\u5F00\u59CB \xB7 \u8D39\u7528\u6309\u672C\u673A\u4F1A\u8BDD\u8BB0\u5F55\u4F30\u7B97"),
21642
+ value && value.history.some(incomplete) && (0, import_react7.createElement)(
21603
21643
  "p",
21604
21644
  { className: "dsh-tom-cost-note", role: "status" },
21605
21645
  "\u90E8\u5206\u8BB0\u5F55\u65E0\u6CD5\u8BFB\u53D6\u6216\u8BA1\u4EF7\uFF0C\u76F8\u5173\u91D1\u989D\u53EF\u80FD\u4E0D\u5B8C\u6574\u3002"
@@ -21613,7 +21653,7 @@ function CostMount({ useProjection, useDailyCost, useAccountBalance, sessionId }
21613
21653
  const totals = useProjection(PROJECTION_KEY);
21614
21654
  const daily = useDailyCost((value) => value);
21615
21655
  const balance = useAccountBalance((value) => value);
21616
- return (0, import_react7.createElement)(CostPanel, { key: sessionId, totals, daily, balance });
21656
+ return (0, import_react8.createElement)(CostPanel, { key: sessionId, totals, daily, balance });
21617
21657
  }
21618
21658
  async function apply(ctx) {
21619
21659
  await ctx.remote.$mount(dailyRemote);
@@ -21643,16 +21683,16 @@ async function apply(ctx) {
21643
21683
  }
21644
21684
 
21645
21685
  // src/client.js
21646
- var inject2 = [.../* @__PURE__ */ new Set(["slots", "sessions", "workspaces", "layout", "uiWorkspace", ...inject])];
21686
+ var inject2 = [.../* @__PURE__ */ new Set(["slots", "sessions", "workspaces", "layout", "uiWorkspace", "commandUi", ...inject])];
21647
21687
  function ProjectHover({ sessionId, useWorkspaces, useSessions }) {
21648
21688
  const workspace = useWorkspaces((state) => state.items.find((item) => item.sessionIds.includes(sessionId)));
21649
21689
  const cwd = useSessions((state) => state.byId[sessionId]?.cwd);
21650
21690
  const path = workspace?.path || cwd;
21651
21691
  const name = workspace?.title || path?.split(/[\\/]/).filter(Boolean).at(-1) || path || "\u672A\u5F52\u5C5E\u9879\u76EE";
21652
- return (0, import_react8.createElement)(
21692
+ return (0, import_react9.createElement)(
21653
21693
  "div",
21654
21694
  { className: "dsh-css-project", title: path },
21655
- (0, import_react8.createElement)("svg", {
21695
+ (0, import_react9.createElement)("svg", {
21656
21696
  width: 14,
21657
21697
  height: 14,
21658
21698
  viewBox: "0 0 24 24",
@@ -21661,8 +21701,8 @@ function ProjectHover({ sessionId, useWorkspaces, useSessions }) {
21661
21701
  strokeWidth: 1.7,
21662
21702
  strokeLinejoin: "round",
21663
21703
  "aria-hidden": true
21664
- }, (0, import_react8.createElement)("path", { d: "M3 7V5a2 2 0 0 1 2-2h5l2 3h7a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Zm0 2h18" })),
21665
- (0, import_react8.createElement)("span", null, name)
21704
+ }, (0, import_react9.createElement)("path", { d: "M3 7V5a2 2 0 0 1 2-2h5l2 3h7a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Zm0 2h18" })),
21705
+ (0, import_react9.createElement)("span", null, name)
21666
21706
  );
21667
21707
  }
21668
21708
  function applySidebarWidth(layout) {
@@ -21741,6 +21781,7 @@ async function apply2(ctx) {
21741
21781
  registerDateGroups(ctx);
21742
21782
  registerProjects(ctx);
21743
21783
  registerUnread(ctx);
21784
+ registerReaIcon(ctx);
21744
21785
  ctx.slots.inject("sidebar.session.row.hover", () => ctx.slots.register({
21745
21786
  name: "sidebar.session.row.hover",
21746
21787
  id: "dsh-css-project",
package/dist/index.js CHANGED
@@ -20083,11 +20083,167 @@ function registerProgressUpdates(ctx) {
20083
20083
  });
20084
20084
  }
20085
20085
 
20086
+ // src/rea/index.js
20087
+ import { interpolate } from "@deepseek-ai/cordis-plugin-loader";
20088
+ import { createScope, scopeOf } from "@deepseek-ai/dsh-scope";
20089
+ import { createUserMessage } from "@deepseek-ai/dsh-llm";
20090
+ import * as mcpClient from "@deepseek-ai/dsh-mcp-client";
20091
+
20092
+ // src/rea/projection.js
20093
+ var REA_STATE = "dshTomRea";
20094
+ var reaProjection = {
20095
+ key: REA_STATE,
20096
+ stateVersion: 2,
20097
+ stateSchema: external_exports.object({ started: external_exports.boolean(), enabled: external_exports.boolean(), pending: external_exports.string().nullable() }),
20098
+ init: () => ({ started: false, enabled: false, pending: null }),
20099
+ apply(state, event) {
20100
+ if (event.type === "command/run") {
20101
+ if (event.data.name === "rea") {
20102
+ return state.started || state.enabled ? state : { ...state, pending: event.data.commandId };
20103
+ }
20104
+ return state.started ? state : { ...state, started: true };
20105
+ }
20106
+ if (event.type === "command/done" && event.data.commandId === state.pending) {
20107
+ return { ...state, enabled: event.data.kind === "success", pending: null };
20108
+ }
20109
+ if (event.type === "step/start" || event.type === "user/message" && event.data.source.kind === "user") {
20110
+ return state.started ? state : { ...state, started: true };
20111
+ }
20112
+ return state;
20113
+ }
20114
+ };
20115
+
20116
+ // src/rea/index.js
20117
+ var MCP_PLUGIN = "@deepseek-ai/dsh-mcp-client";
20118
+ function findReaEntries(loader) {
20119
+ return [...loader.entries()].filter((entry) => entry.options?.name === MCP_PLUGIN && entry.options.config?.serverName === "rea" && scopeOf(entry.ctx) === void 0);
20120
+ }
20121
+ function registerRea(ctx) {
20122
+ ctx.sessionProjections.register(reaProjection);
20123
+ const connections = /* @__PURE__ */ new Map();
20124
+ let source;
20125
+ let unregister;
20126
+ let disposed = false;
20127
+ let scheduled = false;
20128
+ let pending = Promise.resolve();
20129
+ const stateOf = (agent) => ctx.sessionProjections.stateOf(agent.session, REA_STATE);
20130
+ async function disconnect(agent) {
20131
+ const connection = connections.get(agent);
20132
+ if (!connection) return;
20133
+ connections.delete(agent);
20134
+ await connection.scope.dispose();
20135
+ }
20136
+ function connect(agent) {
20137
+ const existing = connections.get(agent);
20138
+ if (existing) return existing.ready;
20139
+ if (!source) throw new Error("\u672A\u68C0\u6D4B\u5230 REA MCP \u914D\u7F6E\uFF0C\u8BF7\u5148\u5728 DSH \u4E2D\u5B89\u88C5\u5E76\u914D\u7F6E REA\u3002");
20140
+ const scope = createScope(ctx, agent);
20141
+ const connection = { scope, ready: void 0 };
20142
+ connections.set(agent, connection);
20143
+ connection.ready = (async () => {
20144
+ try {
20145
+ const config2 = interpolate(source.ctx, source.options.config);
20146
+ const fiber = scope.ctx.plugin(mcpClient, { ...config2, failOnStartupError: true });
20147
+ await fiber;
20148
+ } catch (error62) {
20149
+ if (connections.get(agent) === connection) connections.delete(agent);
20150
+ await scope.dispose();
20151
+ throw error62;
20152
+ }
20153
+ })();
20154
+ return connection.ready;
20155
+ }
20156
+ async function execute({ agent, rawInput, attachments, signal }) {
20157
+ await pending;
20158
+ signal.throwIfAborted();
20159
+ const state = stateOf(agent);
20160
+ if (!state.enabled && (state.started || agent.status !== "idle" || agent.inbox.nextTurn.length || agent.inbox.nextStep.length)) {
20161
+ return { kind: "error", text: "\u8BF7\u65B0\u5EFA\u4F1A\u8BDD\uFF0C\u5E76\u4EE5 /rea \u6216 /rea \u4EFB\u52A1\u5185\u5BB9 \u5F00\u59CB\uFF1B\u666E\u901A\u4F1A\u8BDD\u4E0D\u4F1A\u4E2D\u9014\u52A0\u8F7D REA\u3002" };
20162
+ }
20163
+ const alreadyConnected = connections.has(agent);
20164
+ const cancel = () => {
20165
+ if (!alreadyConnected) void disconnect(agent).catch((error62) => ctx.logger.warn(error62));
20166
+ };
20167
+ signal.addEventListener("abort", cancel, { once: true });
20168
+ try {
20169
+ await connect(agent);
20170
+ signal.throwIfAborted();
20171
+ const text = rawInput.trim();
20172
+ if (text || attachments.length) agent.followup(createUserMessage({
20173
+ content: [...attachments, ...text ? [{ type: "text", text }] : []],
20174
+ source: { kind: "user" }
20175
+ }));
20176
+ return { kind: "success", text: "REA \u5DF2\u4E3A\u5F53\u524D\u4F1A\u8BDD\u542F\u7528\uFF0C\u540E\u7EED\u6D88\u606F\u65E0\u9700\u518D\u52A0 /rea\u3002" };
20177
+ } finally {
20178
+ signal.removeEventListener("abort", cancel);
20179
+ }
20180
+ }
20181
+ async function refresh() {
20182
+ if (disposed) return;
20183
+ const entries = findReaEntries(ctx.loader);
20184
+ source = entries.length === 1 ? entries[0] : void 0;
20185
+ if (!source) {
20186
+ unregister?.();
20187
+ unregister = void 0;
20188
+ await Promise.all([...connections.keys()].map(disconnect));
20189
+ if (entries.length > 1) ctx.logger.warn("\u68C0\u6D4B\u5230\u591A\u6761\u5168\u5C40 REA MCP \u914D\u7F6E\uFF0C\u8BF7\u4FDD\u7559\u4E00\u6761\u540E\u518D\u542F\u7528 /rea\u3002");
20190
+ return;
20191
+ }
20192
+ if (!source.disabled) {
20193
+ const fiber = source.fiber;
20194
+ await source.update({ disabled: true });
20195
+ while (fiber?.inertia) await fiber.inertia;
20196
+ }
20197
+ if (disposed) return;
20198
+ unregister ??= ctx.commands.register({
20199
+ definitionId: "@dsh-tom/dsh-css/rea",
20200
+ name: "rea",
20201
+ description: "\u5728\u65B0\u4F1A\u8BDD\u4E2D\u6309\u9700\u542F\u7528\u5DF2\u5B89\u88C5\u7684 REA \u9006\u5411\u5DE5\u5177",
20202
+ input: { hint: "[\u4EFB\u52A1\u5185\u5BB9]", attachments: true },
20203
+ handler: execute
20204
+ });
20205
+ for (const agent of ctx.agents.list()) if (stateOf(agent).enabled) await connect(agent);
20206
+ }
20207
+ function scheduleRefresh() {
20208
+ if (disposed || scheduled) return;
20209
+ scheduled = true;
20210
+ queueMicrotask(() => {
20211
+ scheduled = false;
20212
+ if (disposed) return;
20213
+ pending = pending.then(refresh).catch((error62) => ctx.logger.warn("REA \u6309\u9700\u52A0\u8F7D\u914D\u7F6E\u5931\u8D25\uFF1A%s", error62.message));
20214
+ });
20215
+ }
20216
+ ctx.on("loader/entry-init", scheduleRefresh, { global: true });
20217
+ ctx.on("loader/partial-dispose", scheduleRefresh, { global: true });
20218
+ ctx.on("internal/plugin", (fiber) => {
20219
+ if (fiber.entry?.options.name === MCP_PLUGIN && scopeOf(fiber.ctx) === void 0) scheduleRefresh();
20220
+ }, { global: true });
20221
+ ctx.on("agent/created", async ({ agent }) => {
20222
+ await Promise.resolve();
20223
+ await pending;
20224
+ if (stateOf(agent).enabled) await connect(agent);
20225
+ });
20226
+ ctx.on("agent/disposed", ({ agent }) => disconnect(agent));
20227
+ ctx.effect(() => async () => {
20228
+ disposed = true;
20229
+ unregister?.();
20230
+ await Promise.all([...connections.keys()].map(disconnect));
20231
+ });
20232
+ scheduleRefresh();
20233
+ return { settle: async () => {
20234
+ await Promise.resolve();
20235
+ await pending;
20236
+ } };
20237
+ }
20238
+
20086
20239
  // index.js
20087
20240
  var name = "dsh-css";
20088
20241
  function apply2(ctx) {
20089
20242
  apply(ctx);
20090
20243
  ctx.inject(["systemPrompt"], registerProgressUpdates);
20244
+ ctx.inject(["commands", "tools", "loader", "agents", "sessionProjections"], (reaCtx) => {
20245
+ registerRea(reaCtx);
20246
+ });
20091
20247
  }
20092
20248
  export {
20093
20249
  apply2 as apply,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-tom/dsh-css",
3
- "version": "0.2.11",
3
+ "version": "0.3.2",
4
4
  "description": "为 DeepSeek Harness 调整深色界面,增加项目管理、费用统计和任务进展播报。",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -35,6 +35,7 @@
35
35
  "@deepseek-ai/dsh-client-locale",
36
36
  "@deepseek-ai/dsh-client-ui-settings-general",
37
37
  "@deepseek-ai/dsh-client-ui-chat",
38
+ "@deepseek-ai/dsh-client-ui-commands",
38
39
  "@deepseek-ai/dsh-client-ui-session",
39
40
  "@deepseek-ai/dsh-client-ui-conversation"
40
41
  ]
@@ -49,9 +50,25 @@
49
50
  "license": "MIT",
50
51
  "peerDependencies": {
51
52
  "@deepseek-ai/cordis": "~4.0.5",
53
+ "@deepseek-ai/cordis-plugin-loader": "~1.0.6",
54
+ "@deepseek-ai/dsh-llm": "0.2.1-rc.2",
55
+ "@deepseek-ai/dsh-mcp-client": "0.2.1-rc.2",
56
+ "@deepseek-ai/dsh-scope": "0.2.1-rc.2",
52
57
  "@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.2"
53
58
  },
54
59
  "peerDependenciesMeta": {
60
+ "@deepseek-ai/cordis-plugin-loader": {
61
+ "optional": true
62
+ },
63
+ "@deepseek-ai/dsh-llm": {
64
+ "optional": true
65
+ },
66
+ "@deepseek-ai/dsh-mcp-client": {
67
+ "optional": true
68
+ },
69
+ "@deepseek-ai/dsh-scope": {
70
+ "optional": true
71
+ },
55
72
  "@deepseek-ai/cordis": {
56
73
  "optional": true
57
74
  },
@@ -61,11 +78,16 @@
61
78
  },
62
79
  "devDependencies": {
63
80
  "@deepseek-ai/cordis": "4.0.5",
81
+ "@deepseek-ai/cordis-plugin-loader": "1.0.6",
82
+ "@deepseek-ai/dsh-agent-loop": "0.2.1-rc.2",
64
83
  "@deepseek-ai/dsh-api-gateway": "0.2.1-rc.2",
65
- "@deepseek-ai/dsh-typert-registry": "0.2.1-rc.2",
66
- "@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.2",
84
+ "@deepseek-ai/dsh-commands": "0.2.1-rc.2",
85
+ "@deepseek-ai/dsh-mcp-client": "0.2.1-rc.2",
67
86
  "@deepseek-ai/dsh-session-projection": "0.2.1-rc.2",
68
87
  "@deepseek-ai/dsh-system-prompt": "0.2.1-rc.2",
88
+ "@deepseek-ai/dsh-tools": "0.2.1-rc.2",
89
+ "@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.2",
90
+ "@deepseek-ai/dsh-typert-registry": "0.2.1-rc.2",
69
91
  "esbuild": "0.28.2",
70
92
  "jsdom": "^27.0.0",
71
93
  "react": "18.3.1",