@dsh-tom/dsh-css 0.2.11 → 0.3.4

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.4.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.4
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 {
@@ -78,6 +78,14 @@ html body[data-ds-dark-theme] {
78
78
  --dsw-alias-markdown-code-block: rgb(55, 56, 50) !important;
79
79
  }
80
80
 
81
+ /* \u5DF2\u7F16\u8F91\u6587\u4EF6\u5361\u7247\uFF1A\u533A\u57DF 1 \u4E3A\u6807\u9898\uFF0C\u533A\u57DF 2 \u4E3A\u6587\u4EF6\u5217\u8868\u53CA\u5C55\u5F00\u6309\u94AE\u3002 */
82
+ html body[data-ds-dark-theme] [data-changed-files] {
83
+ --changes-fill: #30312b;
84
+ --changes-hover: #353630;
85
+ --dsw-alias-interactive-bg-hover: #3a3b34;
86
+ background: #292b25;
87
+ }
88
+
81
89
  /* \u6807\u9898\u680F\u53CA\u539F\u751F\u7A97\u53E3\u6309\u94AE\u5171\u4EAB\u6B64\u989C\u8272\uFF0C\u4F1A\u8BDD\u5217\u8868\u7EE7\u7EED\u4F7F\u7528\u539F\u6765\u7684\u80CC\u666F\u3002 */
82
90
  html[data-windows-titlebar] body[data-ds-dark-theme] {
83
91
  --dsw-specific-sidebar-fill: rgb(32, 32, 32) !important;
@@ -1319,8 +1327,48 @@ function registerUnread(ctx) {
1319
1327
  }, UnreadIndicator));
1320
1328
  }
1321
1329
 
1330
+ // src/rea/client.js
1331
+ var import_react5 = require("react");
1332
+ function ReaIcon(props) {
1333
+ return (0, import_react5.createElement)(
1334
+ "svg",
1335
+ {
1336
+ width: 16,
1337
+ height: 16,
1338
+ viewBox: "0 0 24 24",
1339
+ fill: "none",
1340
+ stroke: "currentColor",
1341
+ strokeWidth: 1.65,
1342
+ strokeLinecap: "round",
1343
+ strokeLinejoin: "round",
1344
+ "aria-hidden": true,
1345
+ ...props
1346
+ },
1347
+ (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" }),
1348
+ (0, import_react5.createElement)("circle", { cx: 15, cy: 15, r: 5 }),
1349
+ (0, import_react5.createElement)("path", { d: "m19 19 3 3" })
1350
+ );
1351
+ }
1352
+ function registerReaIcon(ctx) {
1353
+ ctx.effect(() => {
1354
+ const commands = ctx.commandUi;
1355
+ const original = commands.candidates;
1356
+ const descriptor = Object.getOwnPropertyDescriptor(commands, "candidates");
1357
+ const candidates = async function(...args) {
1358
+ const rows = await original.apply(this, args);
1359
+ return rows.map((row) => row.name === "rea" ? { ...row, icon: ReaIcon } : row);
1360
+ };
1361
+ commands.candidates = candidates;
1362
+ return () => {
1363
+ if (Object.getOwnPropertyDescriptor(commands, "candidates")?.value !== candidates) return;
1364
+ if (descriptor) Object.defineProperty(commands, "candidates", descriptor);
1365
+ else delete commands.candidates;
1366
+ };
1367
+ });
1368
+ }
1369
+
1322
1370
  // src/cost/client.js
1323
- var import_react7 = require("react");
1371
+ var import_react8 = require("react");
1324
1372
 
1325
1373
  // src/cost/pricing.js
1326
1374
  var PROJECTION_KEY = "dshTomCost";
@@ -1358,7 +1406,7 @@ function formatMoney(units) {
1358
1406
  }
1359
1407
 
1360
1408
  // src/cost/panel.js
1361
- var import_react5 = require("react");
1409
+ var import_react6 = require("react");
1362
1410
  var import_react_dom = require("react-dom");
1363
1411
 
1364
1412
  // src/cost/panel-styles.js
@@ -1434,8 +1482,8 @@ function costRows(totals, daily, day = beijingDay()) {
1434
1482
  ];
1435
1483
  }
1436
1484
  function useBeijingDay() {
1437
- const [day, setDay] = (0, import_react5.useState)(beijingDay);
1438
- (0, import_react5.useEffect)(() => {
1485
+ const [day, setDay] = (0, import_react6.useState)(beijingDay);
1486
+ (0, import_react6.useEffect)(() => {
1439
1487
  let timer;
1440
1488
  const refresh = () => {
1441
1489
  const current = beijingDay();
@@ -1449,7 +1497,7 @@ function useBeijingDay() {
1449
1497
  return day;
1450
1498
  }
1451
1499
  function CostIcon() {
1452
- return (0, import_react5.createElement)(
1500
+ return (0, import_react6.createElement)(
1453
1501
  "svg",
1454
1502
  {
1455
1503
  viewBox: "0 0 24 24",
@@ -1462,18 +1510,18 @@ function CostIcon() {
1462
1510
  strokeLinejoin: "round",
1463
1511
  "aria-hidden": true
1464
1512
  },
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" })
1513
+ (0, import_react6.createElement)("circle", { cx: 12, cy: 12, r: 9 }),
1514
+ (0, import_react6.createElement)("path", { d: "m8.5 7.5 3.5 4 3.5-4M8.5 12h7M8.5 15h7M12 11.5V18" })
1467
1515
  );
1468
1516
  }
1469
1517
  function CostPanel({ totals, daily, balance }) {
1470
1518
  const day = useBeijingDay();
1471
1519
  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)(() => {
1520
+ const [open2, setOpen] = (0, import_react6.useState)(false);
1521
+ const anchor2 = (0, import_react6.useRef)(null);
1522
+ const panel = (0, import_react6.useRef)(null);
1523
+ const dialogId = (0, import_react6.useId)();
1524
+ (0, import_react6.useLayoutEffect)(() => {
1477
1525
  if (!open2) return;
1478
1526
  const element = panel.current;
1479
1527
  const document2 = element.ownerDocument;
@@ -1512,11 +1560,11 @@ function CostPanel({ totals, daily, balance }) {
1512
1560
  document2.removeEventListener("keydown", dismissEscape);
1513
1561
  };
1514
1562
  }, [open2]);
1515
- return (0, import_react5.createElement)(
1563
+ return (0, import_react6.createElement)(
1516
1564
  "span",
1517
1565
  { 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", {
1566
+ (0, import_react6.createElement)("style", { "data-dsh-tom-cost-styles": "" }, panelStyles),
1567
+ (0, import_react6.createElement)("button", {
1520
1568
  ref: anchor2,
1521
1569
  type: "button",
1522
1570
  className: "dsh-tom-cost-pill",
@@ -1526,8 +1574,8 @@ function CostPanel({ totals, daily, balance }) {
1526
1574
  "aria-controls": open2 ? dialogId : void 0,
1527
1575
  "aria-label": `\u4F1A\u8BDD\u7D2F\u8BA1\u8D39\u7528 ${rows[1][1]}`,
1528
1576
  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)(
1577
+ }, (0, import_react6.createElement)(CostIcon), (0, import_react6.createElement)("span", { className: "dsh-tom-cost-label" }, rows[1][1])),
1578
+ open2 && (0, import_react_dom.createPortal)((0, import_react6.createElement)(
1531
1579
  "div",
1532
1580
  {
1533
1581
  ref: panel,
@@ -1537,11 +1585,11 @@ function CostPanel({ totals, daily, balance }) {
1537
1585
  className: "dsh-tom-cost-panel",
1538
1586
  style: { visibility: "hidden", left: 0, top: 0 }
1539
1587
  },
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)
1588
+ (0, import_react6.createElement)("div", { className: "dsh-tom-cost-title" }, (0, import_react6.createElement)(CostIcon), "\u8D39\u7528\u660E\u7EC6"),
1589
+ (0, import_react6.createElement)("div", { className: "dsh-tom-cost-rule", "aria-hidden": true }),
1590
+ (0, import_react6.createElement)("dl", { className: "dsh-tom-cost-details" }, rows.flatMap(([label, value]) => [
1591
+ (0, import_react6.createElement)("dt", { key: label }, label),
1592
+ (0, import_react6.createElement)("dd", { key: `${label}-value` }, value)
1545
1593
  ]))
1546
1594
  ), anchor2.current.ownerDocument.body)
1547
1595
  );
@@ -21488,7 +21536,7 @@ function createBalanceStore(readBalance) {
21488
21536
  }
21489
21537
 
21490
21538
  // src/cost/settings.js
21491
- var import_react6 = require("react");
21539
+ var import_react7 = require("react");
21492
21540
 
21493
21541
  // src/cost/settings-styles.js
21494
21542
  var settingsStyles = `
@@ -21544,62 +21592,62 @@ function usageSummary(row) {
21544
21592
  function CostSettings({ useCostReport }) {
21545
21593
  const report = useCostReport((value2) => value2);
21546
21594
  const day = useBeijingDay();
21547
- const [hideZero, setHideZero] = (0, import_react6.useState)(true);
21595
+ const [hideZero, setHideZero] = (0, import_react7.useState)(true);
21548
21596
  const value = report.status === "ready" && report.value.day === day ? report.value : void 0;
21549
21597
  const status = report.status === "error" ? "\u8BFB\u53D6\u5931\u8D25" : "\u52A0\u8F7D\u4E2D\u2026";
21550
21598
  const rows = value ? visibleHistory(value.history, hideZero) : [];
21551
21599
  const summaries = [["today", "\u4ECA\u65E5\u8D39\u7528"], ["week", "\u672C\u5468\u8D39\u7528"], ["month", "\u672C\u6708\u8D39\u7528"]];
21552
- return (0, import_react6.createElement)(
21600
+ return (0, import_react7.createElement)(
21553
21601
  "section",
21554
21602
  { 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]) => {
21603
+ (0, import_react7.createElement)("style", null, settingsStyles),
21604
+ (0, import_react7.createElement)("div", { className: "dsh-tom-cost-cards" }, summaries.map(([key, label]) => {
21557
21605
  const row = value?.[key];
21558
- return (0, import_react6.createElement)(
21606
+ return (0, import_react7.createElement)(
21559
21607
  "div",
21560
21608
  { 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))
21609
+ (0, import_react7.createElement)("div", { className: "dsh-tom-cost-card-label" }, label),
21610
+ (0, import_react7.createElement)("div", { className: "dsh-tom-cost-amount" }, row ? costValue(row.totals, row.failedSessions) : status),
21611
+ (0, import_react7.createElement)("div", { className: "dsh-tom-cost-usage" }, usageSummary(row))
21564
21612
  );
21565
21613
  })),
21566
- (0, import_react6.createElement)(
21614
+ (0, import_react7.createElement)(
21567
21615
  "div",
21568
21616
  { 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)(
21617
+ (0, import_react7.createElement)("h3", null, "\u5386\u53F2\u8BB0\u5F55", (0, import_react7.createElement)("span", null, "\u6700\u8FD1 30 \u5929")),
21618
+ (0, import_react7.createElement)(
21571
21619
  "label",
21572
21620
  { className: "dsh-tom-cost-filter" },
21573
- (0, import_react6.createElement)("input", { type: "checkbox", checked: hideZero, onChange: (event) => setHideZero(event.target.checked) }),
21621
+ (0, import_react7.createElement)("input", { type: "checkbox", checked: hideZero, onChange: (event) => setHideZero(event.target.checked) }),
21574
21622
  "\u8FC7\u6EE4\u96F6\u8D39\u7528\u65E5\u671F"
21575
21623
  )
21576
21624
  ),
21577
- (0, import_react6.createElement)(
21625
+ (0, import_react7.createElement)(
21578
21626
  "div",
21579
21627
  { 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)(
21628
+ (0, import_react7.createElement)(
21581
21629
  "table",
21582
21630
  { 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) => {
21631
+ (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)))),
21632
+ (0, import_react7.createElement)("tbody", null, value && rows.length ? rows.map((row) => {
21585
21633
  const totals = row.totals;
21586
21634
  const unavailable = row.failedSessions > 0 && calls(totals) === 0;
21587
- return (0, import_react6.createElement)(
21635
+ return (0, import_react7.createElement)(
21588
21636
  "tr",
21589
21637
  { 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", {
21638
+ (0, import_react7.createElement)("td", null, row.day),
21639
+ (0, import_react7.createElement)("td", null, unavailable ? "\u2014" : calls(totals).toLocaleString("zh-CN")),
21640
+ ...["inputTokens", "cacheTokens", "outputTokens"].map((key) => (0, import_react7.createElement)("td", {
21593
21641
  key,
21594
21642
  title: unavailable ? void 0 : totals[key].toLocaleString("zh-CN")
21595
21643
  }, unavailable ? "\u2014" : formatTokens(totals[key]))),
21596
- (0, import_react6.createElement)("td", null, costValue(totals, row.failedSessions))
21644
+ (0, import_react7.createElement)("td", null, costValue(totals, row.failedSessions))
21597
21645
  );
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)))
21646
+ }) : (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
21647
  )
21600
21648
  ),
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)(
21649
+ (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"),
21650
+ value && value.history.some(incomplete) && (0, import_react7.createElement)(
21603
21651
  "p",
21604
21652
  { className: "dsh-tom-cost-note", role: "status" },
21605
21653
  "\u90E8\u5206\u8BB0\u5F55\u65E0\u6CD5\u8BFB\u53D6\u6216\u8BA1\u4EF7\uFF0C\u76F8\u5173\u91D1\u989D\u53EF\u80FD\u4E0D\u5B8C\u6574\u3002"
@@ -21613,7 +21661,7 @@ function CostMount({ useProjection, useDailyCost, useAccountBalance, sessionId }
21613
21661
  const totals = useProjection(PROJECTION_KEY);
21614
21662
  const daily = useDailyCost((value) => value);
21615
21663
  const balance = useAccountBalance((value) => value);
21616
- return (0, import_react7.createElement)(CostPanel, { key: sessionId, totals, daily, balance });
21664
+ return (0, import_react8.createElement)(CostPanel, { key: sessionId, totals, daily, balance });
21617
21665
  }
21618
21666
  async function apply(ctx) {
21619
21667
  await ctx.remote.$mount(dailyRemote);
@@ -21643,16 +21691,16 @@ async function apply(ctx) {
21643
21691
  }
21644
21692
 
21645
21693
  // src/client.js
21646
- var inject2 = [.../* @__PURE__ */ new Set(["slots", "sessions", "workspaces", "layout", "uiWorkspace", ...inject])];
21694
+ var inject2 = [.../* @__PURE__ */ new Set(["slots", "sessions", "workspaces", "layout", "uiWorkspace", "commandUi", ...inject])];
21647
21695
  function ProjectHover({ sessionId, useWorkspaces, useSessions }) {
21648
21696
  const workspace = useWorkspaces((state) => state.items.find((item) => item.sessionIds.includes(sessionId)));
21649
21697
  const cwd = useSessions((state) => state.byId[sessionId]?.cwd);
21650
21698
  const path = workspace?.path || cwd;
21651
21699
  const name = workspace?.title || path?.split(/[\\/]/).filter(Boolean).at(-1) || path || "\u672A\u5F52\u5C5E\u9879\u76EE";
21652
- return (0, import_react8.createElement)(
21700
+ return (0, import_react9.createElement)(
21653
21701
  "div",
21654
21702
  { className: "dsh-css-project", title: path },
21655
- (0, import_react8.createElement)("svg", {
21703
+ (0, import_react9.createElement)("svg", {
21656
21704
  width: 14,
21657
21705
  height: 14,
21658
21706
  viewBox: "0 0 24 24",
@@ -21661,8 +21709,8 @@ function ProjectHover({ sessionId, useWorkspaces, useSessions }) {
21661
21709
  strokeWidth: 1.7,
21662
21710
  strokeLinejoin: "round",
21663
21711
  "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)
21712
+ }, (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" })),
21713
+ (0, import_react9.createElement)("span", null, name)
21666
21714
  );
21667
21715
  }
21668
21716
  function applySidebarWidth(layout) {
@@ -21741,6 +21789,7 @@ async function apply2(ctx) {
21741
21789
  registerDateGroups(ctx);
21742
21790
  registerProjects(ctx);
21743
21791
  registerUnread(ctx);
21792
+ registerReaIcon(ctx);
21744
21793
  ctx.slots.inject("sidebar.session.row.hover", () => ctx.slots.register({
21745
21794
  name: "sidebar.session.row.hover",
21746
21795
  id: "dsh-css-project",
package/dist/index.js CHANGED
@@ -20083,11 +20083,171 @@ 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
+ const fiber = source.fiber;
20193
+ if (!source.disabled || fiber?.uid) {
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) return;
20220
+ if (fiber.entry === source && source.disabled && fiber.uid) {
20221
+ Promise.resolve(fiber.dispose()).catch((error62) => ctx.logger.warn(error62));
20222
+ }
20223
+ scheduleRefresh();
20224
+ }, { global: true });
20225
+ ctx.on("agent/created", async ({ agent }) => {
20226
+ await Promise.resolve();
20227
+ await pending;
20228
+ if (stateOf(agent).enabled) await connect(agent);
20229
+ });
20230
+ ctx.on("agent/disposed", ({ agent }) => disconnect(agent));
20231
+ ctx.effect(() => async () => {
20232
+ disposed = true;
20233
+ unregister?.();
20234
+ await Promise.all([...connections.keys()].map(disconnect));
20235
+ });
20236
+ scheduleRefresh();
20237
+ return { settle: async () => {
20238
+ await Promise.resolve();
20239
+ await pending;
20240
+ } };
20241
+ }
20242
+
20086
20243
  // index.js
20087
20244
  var name = "dsh-css";
20088
20245
  function apply2(ctx) {
20089
20246
  apply(ctx);
20090
20247
  ctx.inject(["systemPrompt"], registerProgressUpdates);
20248
+ ctx.inject(["commands", "tools", "loader", "agents", "sessionProjections"], (reaCtx) => {
20249
+ registerRea(reaCtx);
20250
+ });
20091
20251
  }
20092
20252
  export {
20093
20253
  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.4",
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",
package/theme.css CHANGED
@@ -44,6 +44,14 @@ html body[data-ds-dark-theme] {
44
44
  --dsw-alias-markdown-code-block: rgb(55, 56, 50) !important;
45
45
  }
46
46
 
47
+ /* 已编辑文件卡片:区域 1 为标题,区域 2 为文件列表及展开按钮。 */
48
+ html body[data-ds-dark-theme] [data-changed-files] {
49
+ --changes-fill: #30312b;
50
+ --changes-hover: #353630;
51
+ --dsw-alias-interactive-bg-hover: #3a3b34;
52
+ background: #292b25;
53
+ }
54
+
47
55
  /* 标题栏及原生窗口按钮共享此颜色,会话列表继续使用原来的背景。 */
48
56
  html[data-windows-titlebar] body[data-ds-dark-theme] {
49
57
  --dsw-specific-sidebar-fill: rgb(32, 32, 32) !important;