@dsh-tom/dsh-css 0.2.10 → 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 +2 -2
- package/dist/client.js +126 -72
- package/dist/index.js +156 -0
- package/package.json +25 -3
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.
|
|
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.10.tgz
|
|
|
32
32
|
包发布到 npmjs 后,先卸载已安装的旧版,再打开 **插件 → 添加插件 → 安装第三方插件**,输入:
|
|
33
33
|
|
|
34
34
|
```text
|
|
35
|
-
@dsh-tom/dsh-css@0.2
|
|
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
|
|
32
|
+
var import_react9 = require("react");
|
|
33
33
|
|
|
34
34
|
// theme.css
|
|
35
35
|
var theme_default = `.dsh-css-unread-dot {
|
|
@@ -1083,24 +1083,37 @@ function replacePercent(value, percent) {
|
|
|
1083
1083
|
function registerCacheHitPrecision(ctx) {
|
|
1084
1084
|
const slot = "conversation.composer.dock";
|
|
1085
1085
|
ctx.slots.inject(slot, () => {
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
const
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1086
|
+
let original;
|
|
1087
|
+
let dispose;
|
|
1088
|
+
const sync = () => {
|
|
1089
|
+
if (original && ctx.slots.entries(slot).includes(original)) return;
|
|
1090
|
+
dispose?.();
|
|
1091
|
+
dispose = void 0;
|
|
1092
|
+
original = ctx.slots.entries(slot).find((entry) => entry.options.id === "usage");
|
|
1093
|
+
if (!original) return;
|
|
1094
|
+
const renderUsage = original.component.type;
|
|
1095
|
+
function UsagePill(props) {
|
|
1096
|
+
const element = renderUsage(props);
|
|
1097
|
+
const usage = props.useProjection("tokenUsage");
|
|
1098
|
+
if (!usage) return element;
|
|
1099
|
+
const input2 = usage.uncachedInputTokens + usage.cacheReadTokens + usage.cacheWriteTokens;
|
|
1100
|
+
if (input2 === 0) return element;
|
|
1101
|
+
return replacePercent(element, (usage.cacheReadTokens / input2 * 100).toFixed(2));
|
|
1102
|
+
}
|
|
1103
|
+
dispose = ctx.slots.register({
|
|
1104
|
+
...original.options,
|
|
1105
|
+
name: slot,
|
|
1106
|
+
priority: (original.options.priority ?? 0) - 1,
|
|
1107
|
+
locale: original.locale,
|
|
1108
|
+
inject: original.inject
|
|
1109
|
+
}, UsagePill);
|
|
1110
|
+
};
|
|
1111
|
+
const unsubscribe = ctx.slots.subscribe(slot, sync);
|
|
1112
|
+
sync();
|
|
1113
|
+
return () => {
|
|
1114
|
+
unsubscribe();
|
|
1115
|
+
dispose?.();
|
|
1116
|
+
};
|
|
1104
1117
|
});
|
|
1105
1118
|
}
|
|
1106
1119
|
|
|
@@ -1306,8 +1319,48 @@ function registerUnread(ctx) {
|
|
|
1306
1319
|
}, UnreadIndicator));
|
|
1307
1320
|
}
|
|
1308
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
|
+
|
|
1309
1362
|
// src/cost/client.js
|
|
1310
|
-
var
|
|
1363
|
+
var import_react8 = require("react");
|
|
1311
1364
|
|
|
1312
1365
|
// src/cost/pricing.js
|
|
1313
1366
|
var PROJECTION_KEY = "dshTomCost";
|
|
@@ -1345,7 +1398,7 @@ function formatMoney(units) {
|
|
|
1345
1398
|
}
|
|
1346
1399
|
|
|
1347
1400
|
// src/cost/panel.js
|
|
1348
|
-
var
|
|
1401
|
+
var import_react6 = require("react");
|
|
1349
1402
|
var import_react_dom = require("react-dom");
|
|
1350
1403
|
|
|
1351
1404
|
// src/cost/panel-styles.js
|
|
@@ -1421,8 +1474,8 @@ function costRows(totals, daily, day = beijingDay()) {
|
|
|
1421
1474
|
];
|
|
1422
1475
|
}
|
|
1423
1476
|
function useBeijingDay() {
|
|
1424
|
-
const [day, setDay] = (0,
|
|
1425
|
-
(0,
|
|
1477
|
+
const [day, setDay] = (0, import_react6.useState)(beijingDay);
|
|
1478
|
+
(0, import_react6.useEffect)(() => {
|
|
1426
1479
|
let timer;
|
|
1427
1480
|
const refresh = () => {
|
|
1428
1481
|
const current = beijingDay();
|
|
@@ -1436,7 +1489,7 @@ function useBeijingDay() {
|
|
|
1436
1489
|
return day;
|
|
1437
1490
|
}
|
|
1438
1491
|
function CostIcon() {
|
|
1439
|
-
return (0,
|
|
1492
|
+
return (0, import_react6.createElement)(
|
|
1440
1493
|
"svg",
|
|
1441
1494
|
{
|
|
1442
1495
|
viewBox: "0 0 24 24",
|
|
@@ -1449,18 +1502,18 @@ function CostIcon() {
|
|
|
1449
1502
|
strokeLinejoin: "round",
|
|
1450
1503
|
"aria-hidden": true
|
|
1451
1504
|
},
|
|
1452
|
-
(0,
|
|
1453
|
-
(0,
|
|
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" })
|
|
1454
1507
|
);
|
|
1455
1508
|
}
|
|
1456
1509
|
function CostPanel({ totals, daily, balance }) {
|
|
1457
1510
|
const day = useBeijingDay();
|
|
1458
1511
|
const rows = costRows(totals, daily, day);
|
|
1459
|
-
const [open2, setOpen] = (0,
|
|
1460
|
-
const anchor2 = (0,
|
|
1461
|
-
const panel = (0,
|
|
1462
|
-
const dialogId = (0,
|
|
1463
|
-
(0,
|
|
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)(() => {
|
|
1464
1517
|
if (!open2) return;
|
|
1465
1518
|
const element = panel.current;
|
|
1466
1519
|
const document2 = element.ownerDocument;
|
|
@@ -1499,11 +1552,11 @@ function CostPanel({ totals, daily, balance }) {
|
|
|
1499
1552
|
document2.removeEventListener("keydown", dismissEscape);
|
|
1500
1553
|
};
|
|
1501
1554
|
}, [open2]);
|
|
1502
|
-
return (0,
|
|
1555
|
+
return (0, import_react6.createElement)(
|
|
1503
1556
|
"span",
|
|
1504
1557
|
{ className: "dsh-tom-cost-anchor", "data-composer-stat": "cost" },
|
|
1505
|
-
(0,
|
|
1506
|
-
(0,
|
|
1558
|
+
(0, import_react6.createElement)("style", { "data-dsh-tom-cost-styles": "" }, panelStyles),
|
|
1559
|
+
(0, import_react6.createElement)("button", {
|
|
1507
1560
|
ref: anchor2,
|
|
1508
1561
|
type: "button",
|
|
1509
1562
|
className: "dsh-tom-cost-pill",
|
|
@@ -1513,8 +1566,8 @@ function CostPanel({ totals, daily, balance }) {
|
|
|
1513
1566
|
"aria-controls": open2 ? dialogId : void 0,
|
|
1514
1567
|
"aria-label": `\u4F1A\u8BDD\u7D2F\u8BA1\u8D39\u7528 ${rows[1][1]}`,
|
|
1515
1568
|
onClick: () => setOpen(!open2)
|
|
1516
|
-
}, (0,
|
|
1517
|
-
open2 && (0, import_react_dom.createPortal)((0,
|
|
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)(
|
|
1518
1571
|
"div",
|
|
1519
1572
|
{
|
|
1520
1573
|
ref: panel,
|
|
@@ -1524,11 +1577,11 @@ function CostPanel({ totals, daily, balance }) {
|
|
|
1524
1577
|
className: "dsh-tom-cost-panel",
|
|
1525
1578
|
style: { visibility: "hidden", left: 0, top: 0 }
|
|
1526
1579
|
},
|
|
1527
|
-
(0,
|
|
1528
|
-
(0,
|
|
1529
|
-
(0,
|
|
1530
|
-
(0,
|
|
1531
|
-
(0,
|
|
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)
|
|
1532
1585
|
]))
|
|
1533
1586
|
), anchor2.current.ownerDocument.body)
|
|
1534
1587
|
);
|
|
@@ -21475,7 +21528,7 @@ function createBalanceStore(readBalance) {
|
|
|
21475
21528
|
}
|
|
21476
21529
|
|
|
21477
21530
|
// src/cost/settings.js
|
|
21478
|
-
var
|
|
21531
|
+
var import_react7 = require("react");
|
|
21479
21532
|
|
|
21480
21533
|
// src/cost/settings-styles.js
|
|
21481
21534
|
var settingsStyles = `
|
|
@@ -21531,62 +21584,62 @@ function usageSummary(row) {
|
|
|
21531
21584
|
function CostSettings({ useCostReport }) {
|
|
21532
21585
|
const report = useCostReport((value2) => value2);
|
|
21533
21586
|
const day = useBeijingDay();
|
|
21534
|
-
const [hideZero, setHideZero] = (0,
|
|
21587
|
+
const [hideZero, setHideZero] = (0, import_react7.useState)(true);
|
|
21535
21588
|
const value = report.status === "ready" && report.value.day === day ? report.value : void 0;
|
|
21536
21589
|
const status = report.status === "error" ? "\u8BFB\u53D6\u5931\u8D25" : "\u52A0\u8F7D\u4E2D\u2026";
|
|
21537
21590
|
const rows = value ? visibleHistory(value.history, hideZero) : [];
|
|
21538
21591
|
const summaries = [["today", "\u4ECA\u65E5\u8D39\u7528"], ["week", "\u672C\u5468\u8D39\u7528"], ["month", "\u672C\u6708\u8D39\u7528"]];
|
|
21539
|
-
return (0,
|
|
21592
|
+
return (0, import_react7.createElement)(
|
|
21540
21593
|
"section",
|
|
21541
21594
|
{ className: "dsh-tom-cost-settings", "aria-label": "\u8D39\u7528" },
|
|
21542
|
-
(0,
|
|
21543
|
-
(0,
|
|
21595
|
+
(0, import_react7.createElement)("style", null, settingsStyles),
|
|
21596
|
+
(0, import_react7.createElement)("div", { className: "dsh-tom-cost-cards" }, summaries.map(([key, label]) => {
|
|
21544
21597
|
const row = value?.[key];
|
|
21545
|
-
return (0,
|
|
21598
|
+
return (0, import_react7.createElement)(
|
|
21546
21599
|
"div",
|
|
21547
21600
|
{ key, className: "dsh-tom-cost-card" },
|
|
21548
|
-
(0,
|
|
21549
|
-
(0,
|
|
21550
|
-
(0,
|
|
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))
|
|
21551
21604
|
);
|
|
21552
21605
|
})),
|
|
21553
|
-
(0,
|
|
21606
|
+
(0, import_react7.createElement)(
|
|
21554
21607
|
"div",
|
|
21555
21608
|
{ className: "dsh-tom-cost-history-heading" },
|
|
21556
|
-
(0,
|
|
21557
|
-
(0,
|
|
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)(
|
|
21558
21611
|
"label",
|
|
21559
21612
|
{ className: "dsh-tom-cost-filter" },
|
|
21560
|
-
(0,
|
|
21613
|
+
(0, import_react7.createElement)("input", { type: "checkbox", checked: hideZero, onChange: (event) => setHideZero(event.target.checked) }),
|
|
21561
21614
|
"\u8FC7\u6EE4\u96F6\u8D39\u7528\u65E5\u671F"
|
|
21562
21615
|
)
|
|
21563
21616
|
),
|
|
21564
|
-
(0,
|
|
21617
|
+
(0, import_react7.createElement)(
|
|
21565
21618
|
"div",
|
|
21566
21619
|
{ className: "dsh-tom-cost-table-wrap", tabIndex: 0, role: "region", "aria-label": "\u6BCF\u65E5\u8D39\u7528\u5386\u53F2\u8BB0\u5F55" },
|
|
21567
|
-
(0,
|
|
21620
|
+
(0, import_react7.createElement)(
|
|
21568
21621
|
"table",
|
|
21569
21622
|
{ className: "dsh-tom-cost-table" },
|
|
21570
|
-
(0,
|
|
21571
|
-
(0,
|
|
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) => {
|
|
21572
21625
|
const totals = row.totals;
|
|
21573
21626
|
const unavailable = row.failedSessions > 0 && calls(totals) === 0;
|
|
21574
|
-
return (0,
|
|
21627
|
+
return (0, import_react7.createElement)(
|
|
21575
21628
|
"tr",
|
|
21576
21629
|
{ key: row.day },
|
|
21577
|
-
(0,
|
|
21578
|
-
(0,
|
|
21579
|
-
...["inputTokens", "cacheTokens", "outputTokens"].map((key) => (0,
|
|
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", {
|
|
21580
21633
|
key,
|
|
21581
21634
|
title: unavailable ? void 0 : totals[key].toLocaleString("zh-CN")
|
|
21582
21635
|
}, unavailable ? "\u2014" : formatTokens(totals[key]))),
|
|
21583
|
-
(0,
|
|
21636
|
+
(0, import_react7.createElement)("td", null, costValue(totals, row.failedSessions))
|
|
21584
21637
|
);
|
|
21585
|
-
}) : (0,
|
|
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)))
|
|
21586
21639
|
)
|
|
21587
21640
|
),
|
|
21588
|
-
(0,
|
|
21589
|
-
value && value.history.some(incomplete) && (0,
|
|
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)(
|
|
21590
21643
|
"p",
|
|
21591
21644
|
{ className: "dsh-tom-cost-note", role: "status" },
|
|
21592
21645
|
"\u90E8\u5206\u8BB0\u5F55\u65E0\u6CD5\u8BFB\u53D6\u6216\u8BA1\u4EF7\uFF0C\u76F8\u5173\u91D1\u989D\u53EF\u80FD\u4E0D\u5B8C\u6574\u3002"
|
|
@@ -21600,7 +21653,7 @@ function CostMount({ useProjection, useDailyCost, useAccountBalance, sessionId }
|
|
|
21600
21653
|
const totals = useProjection(PROJECTION_KEY);
|
|
21601
21654
|
const daily = useDailyCost((value) => value);
|
|
21602
21655
|
const balance = useAccountBalance((value) => value);
|
|
21603
|
-
return (0,
|
|
21656
|
+
return (0, import_react8.createElement)(CostPanel, { key: sessionId, totals, daily, balance });
|
|
21604
21657
|
}
|
|
21605
21658
|
async function apply(ctx) {
|
|
21606
21659
|
await ctx.remote.$mount(dailyRemote);
|
|
@@ -21630,16 +21683,16 @@ async function apply(ctx) {
|
|
|
21630
21683
|
}
|
|
21631
21684
|
|
|
21632
21685
|
// src/client.js
|
|
21633
|
-
var inject2 = [.../* @__PURE__ */ new Set(["slots", "sessions", "workspaces", "layout", "uiWorkspace", ...inject])];
|
|
21686
|
+
var inject2 = [.../* @__PURE__ */ new Set(["slots", "sessions", "workspaces", "layout", "uiWorkspace", "commandUi", ...inject])];
|
|
21634
21687
|
function ProjectHover({ sessionId, useWorkspaces, useSessions }) {
|
|
21635
21688
|
const workspace = useWorkspaces((state) => state.items.find((item) => item.sessionIds.includes(sessionId)));
|
|
21636
21689
|
const cwd = useSessions((state) => state.byId[sessionId]?.cwd);
|
|
21637
21690
|
const path = workspace?.path || cwd;
|
|
21638
21691
|
const name = workspace?.title || path?.split(/[\\/]/).filter(Boolean).at(-1) || path || "\u672A\u5F52\u5C5E\u9879\u76EE";
|
|
21639
|
-
return (0,
|
|
21692
|
+
return (0, import_react9.createElement)(
|
|
21640
21693
|
"div",
|
|
21641
21694
|
{ className: "dsh-css-project", title: path },
|
|
21642
|
-
(0,
|
|
21695
|
+
(0, import_react9.createElement)("svg", {
|
|
21643
21696
|
width: 14,
|
|
21644
21697
|
height: 14,
|
|
21645
21698
|
viewBox: "0 0 24 24",
|
|
@@ -21648,8 +21701,8 @@ function ProjectHover({ sessionId, useWorkspaces, useSessions }) {
|
|
|
21648
21701
|
strokeWidth: 1.7,
|
|
21649
21702
|
strokeLinejoin: "round",
|
|
21650
21703
|
"aria-hidden": true
|
|
21651
|
-
}, (0,
|
|
21652
|
-
(0,
|
|
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)
|
|
21653
21706
|
);
|
|
21654
21707
|
}
|
|
21655
21708
|
function applySidebarWidth(layout) {
|
|
@@ -21728,6 +21781,7 @@ async function apply2(ctx) {
|
|
|
21728
21781
|
registerDateGroups(ctx);
|
|
21729
21782
|
registerProjects(ctx);
|
|
21730
21783
|
registerUnread(ctx);
|
|
21784
|
+
registerReaIcon(ctx);
|
|
21731
21785
|
ctx.slots.inject("sidebar.session.row.hover", () => ctx.slots.register({
|
|
21732
21786
|
name: "sidebar.session.row.hover",
|
|
21733
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
|
|
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-
|
|
66
|
-
"@deepseek-ai/dsh-
|
|
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",
|