dsh-superagent-console 0.1.1 → 0.1.3
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 +43 -64
- package/lib/client.js +480 -216
- package/lib/index.d.ts +13 -1
- package/lib/index.js +201 -12
- package/package.json +6 -3
package/lib/client.js
CHANGED
|
@@ -4,8 +4,31 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
// \0rolldown/runtime.js
|
|
8
|
+
var __create = Object.create;
|
|
9
|
+
var __defProp = Object.defineProperty;
|
|
10
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
11
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
12
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
16
|
+
key = keys[i];
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
18
|
+
get: ((k) => from[k]).bind(null, key),
|
|
19
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return to;
|
|
23
|
+
};
|
|
24
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
25
|
+
value: mod,
|
|
26
|
+
enumerable: true
|
|
27
|
+
}) : target, mod));
|
|
7
28
|
let react = require("react");
|
|
8
29
|
let react_dom = require("react-dom");
|
|
30
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
31
|
+
_deepseek_ai_dsh_client_ui_primitives = __toESM(_deepseek_ai_dsh_client_ui_primitives, 1);
|
|
9
32
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
33
|
// src/vendor/navigation.ts
|
|
11
34
|
/**
|
|
@@ -1334,13 +1357,14 @@ window.__ModuleLoader__.load({
|
|
|
1334
1357
|
});
|
|
1335
1358
|
}
|
|
1336
1359
|
// src/client/plugins-page.tsx
|
|
1337
|
-
/**
|
|
1338
|
-
* Plugins tab for the official panel
|
|
1339
|
-
*
|
|
1340
|
-
*
|
|
1341
|
-
*
|
|
1342
|
-
*
|
|
1343
|
-
*
|
|
1360
|
+
/**
|
|
1361
|
+
* Plugins tab for the official panel. The install dialog is rebuilt on the
|
|
1362
|
+
* desktop client's own ui-primitives (required at runtime — kept external by
|
|
1363
|
+
* tsdown, resolved by the ModuleLoader registry exactly like the native
|
|
1364
|
+
* manager does), so the modal shares the native plugin dialog's typography,
|
|
1365
|
+
* colors, focus rings and animation. Page-level dialog rules are ported
|
|
1366
|
+
* verbatim from the native manager's CSS module under sgc-* class names
|
|
1367
|
+
* (widths, gaps, the safety footer, the anchored registry popover).
|
|
1344
1368
|
*
|
|
1345
1369
|
* Backend contract (src/plugins.ts): install/remove run
|
|
1346
1370
|
* dsh plugin --profile <name> add|remove server-side (single-flight,
|
|
@@ -1375,26 +1399,75 @@ window.__ModuleLoader__.load({
|
|
|
1375
1399
|
if (/\bENOTFOUND\b|\bECONNRESET\b|\bETIMEDOUT\b|\bECONNREFUSED\b|\bEAI_AGAIN\b|FETCH_ERROR|Could not resolve/i.test(log)) return "network";
|
|
1376
1400
|
return "generic";
|
|
1377
1401
|
}
|
|
1378
|
-
const
|
|
1402
|
+
const GUIDE_ITEMS = [
|
|
1379
1403
|
{
|
|
1380
1404
|
key: "Npm",
|
|
1381
|
-
example: "dsh-plugin-whale-pet"
|
|
1405
|
+
example: "dsh-plugin-whale-pet",
|
|
1406
|
+
titleKey: "plugins.installGuideNpm",
|
|
1407
|
+
hintKey: "plugins.installGuideNpmHint"
|
|
1382
1408
|
},
|
|
1383
1409
|
{
|
|
1384
1410
|
key: "Git",
|
|
1385
|
-
example: "github:owner/dsh-plugin-example"
|
|
1411
|
+
example: "github:owner/dsh-plugin-example",
|
|
1412
|
+
titleKey: "plugins.installGuideGit",
|
|
1413
|
+
hintKey: "plugins.installGuideGitHint"
|
|
1386
1414
|
},
|
|
1387
1415
|
{
|
|
1388
1416
|
key: "Path",
|
|
1389
|
-
example: "/Users/me/MyCode/dsh-plugin-example"
|
|
1417
|
+
example: "/Users/me/MyCode/dsh-plugin-example",
|
|
1418
|
+
titleKey: "plugins.installGuidePath",
|
|
1419
|
+
hintKey: "plugins.installGuidePathHint"
|
|
1390
1420
|
}
|
|
1391
1421
|
];
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1422
|
+
/**
|
|
1423
|
+
* Dialog rules ported from the native manager's PluginManagerPage CSS module
|
|
1424
|
+
* (values verbatim; class names renamed to the sgc- prefix so they cannot
|
|
1425
|
+
* collide with either the native or the engine-panel classes).
|
|
1426
|
+
*/
|
|
1427
|
+
const SGC_CSS = `
|
|
1428
|
+
.sgc-installDialog{width:min(560px,100%);max-height:min(800px,100%)}
|
|
1429
|
+
.sgc-installContent{min-height:0;overflow-y:auto}
|
|
1430
|
+
.sgc-installBody{flex-direction:column;gap:12px;min-width:0;display:flex}
|
|
1431
|
+
.sgc-installField{flex-direction:column;gap:6px;font-size:13px;display:flex}
|
|
1432
|
+
.sgc-installField input[type=text]{border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-3);height:40px;font:inherit;color:var(--dsw-alias-label-primary);outline:none;padding:0 14px;font-size:13px}
|
|
1433
|
+
.sgc-installField input[type=text]:focus,.sgc-registryCustomField:focus{border-color:var(--dsw-alias-state-business-primary);box-shadow:inset 0 0 0 .5px var(--dsw-alias-state-business-primary)}
|
|
1434
|
+
.sgc-optionsRow{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 12px;display:flex}
|
|
1435
|
+
.sgc-guideToggle{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;align-self:flex-start;align-items:center;gap:4px;margin-top:4px;padding:0;font-size:12.5px;display:inline-flex}
|
|
1436
|
+
.sgc-guideToggle:hover{color:var(--dsw-alias-label-primary)}
|
|
1437
|
+
.sgc-guideChevron{transition:transform .16s}
|
|
1438
|
+
.sgc-guideToggle[aria-expanded=true] .sgc-guideChevron,.sgc-registryToggle[aria-expanded=true] .sgc-guideChevron{transform:rotate(180deg)}
|
|
1439
|
+
.sgc-guide{border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-layer-1);flex-direction:column;gap:10px;padding:8px 14px;display:flex}
|
|
1440
|
+
.sgc-guideList{flex-direction:column;gap:2px;margin:0;padding:0;list-style:none;display:flex}
|
|
1441
|
+
.sgc-guideItem{align-items:flex-start;gap:10px;padding:8px 0;display:flex}
|
|
1442
|
+
.sgc-guideItem>button{align-self:center}
|
|
1443
|
+
.sgc-guideMain{flex-direction:column;flex:1;gap:0;min-width:0;display:flex}
|
|
1444
|
+
.sgc-guideTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:20px}
|
|
1445
|
+
.sgc-guideHint{color:var(--dsw-alias-label-tertiary);margin:6px 0 0;font-size:12px;line-height:18px}
|
|
1446
|
+
.sgc-guideExample{color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere;font-size:12px;line-height:20px}
|
|
1447
|
+
.sgc-guideExample code{font-family:var(--ds-font-family-code)}
|
|
1448
|
+
.sgc-guideExampleLabel{color:var(--dsw-alias-label-tertiary)}
|
|
1449
|
+
.sgc-registryToggle{border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-2);height:28px;font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:6px;padding:0 8px 0 10px;font-size:12.5px;display:inline-flex}
|
|
1450
|
+
.sgc-registryToggle:hover:not(:disabled){color:var(--dsw-alias-label-primary)}
|
|
1451
|
+
.sgc-registryToggle:disabled{cursor:default;opacity:.6}
|
|
1452
|
+
.sgc-registryToggle[aria-expanded=true]{border-color:var(--dsw-alias-border-l3);background:var(--dsw-alias-bg-layer-3)}
|
|
1453
|
+
.sgc-registryChosen{color:var(--dsw-alias-label-primary);font-weight:500}
|
|
1454
|
+
.sgc-registry{z-index:1100;box-sizing:border-box;background:var(--dsw-alias-bg-layer-2);border-radius:var(--dsw-radius-lg);width:min(440px,calc(100vw - 24px));box-shadow:var(--dsw-elevation-prominent);border:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:4px;min-width:0;margin:0;padding:8px;display:flex;position:fixed}
|
|
1455
|
+
.sgc-registryOption{border-radius:var(--dsw-radius-md);cursor:pointer;border:0;flex-direction:column;gap:4px;padding:8px 10px;display:flex}
|
|
1456
|
+
.sgc-registryOption:hover{background:var(--dsw-alias-interactive-bg-hover)}
|
|
1457
|
+
label.sgc-registryOption{flex-direction:row;align-items:flex-start;gap:10px}
|
|
1458
|
+
.sgc-registryOption input[type=radio]{width:16px;height:16px;accent-color:var(--dsw-alias-brand-primary);flex:none;margin:2px 0 0}
|
|
1459
|
+
.sgc-registryTitle{color:var(--dsw-alias-label-primary);flex-wrap:wrap;align-items:center;gap:8px;font-size:13px;line-height:20px;display:flex}
|
|
1460
|
+
.sgc-registryHint{color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere;font-size:12px;line-height:18px}
|
|
1461
|
+
.sgc-registryCustomField{border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-3);height:32px;font:inherit;color:var(--dsw-alias-label-primary);outline:none;margin-left:26px;padding:0 10px;font-size:13px}
|
|
1462
|
+
.sgc-registryCustomError{margin:0 0 0 26px}
|
|
1463
|
+
.sgc-installFooter{flex-direction:column;flex:1;gap:20px;min-width:0;display:flex}
|
|
1464
|
+
.sgc-installSafety{border-radius:var(--dsw-radius-md);background:var(--dsw-alias-state-warn-tertiary);color:var(--dsw-alias-label-secondary);align-items:flex-start;gap:8px;margin:0;padding:10px 12px;font-size:12px;line-height:18px;display:flex}
|
|
1465
|
+
.sgc-installSafety>svg{color:var(--dsw-alias-state-warn-primary);flex:none;margin-top:2px}
|
|
1466
|
+
.sgc-installSafetyText{flex-direction:column;gap:4px;min-width:0;display:flex}
|
|
1467
|
+
.sgc-wide{border-radius:var(--dsw-radius-md);justify-content:center;width:100%;height:40px}
|
|
1468
|
+
.sgc-inputError{color:var(--dsw-alias-state-error-primary);margin:-4px 0 0;font-size:12px;line-height:18px}
|
|
1469
|
+
.sgc-dialogActions{display:flex;justify-content:flex-end;gap:10px}
|
|
1470
|
+
`;
|
|
1398
1471
|
function OutputBlock({ output }) {
|
|
1399
1472
|
if (!output) return null;
|
|
1400
1473
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
@@ -1406,15 +1479,37 @@ window.__ModuleLoader__.load({
|
|
|
1406
1479
|
children: output
|
|
1407
1480
|
});
|
|
1408
1481
|
}
|
|
1482
|
+
const REGISTRY_CHOICES = [
|
|
1483
|
+
{
|
|
1484
|
+
value: "",
|
|
1485
|
+
titleKey: "plugins.registryDefault"
|
|
1486
|
+
},
|
|
1487
|
+
{
|
|
1488
|
+
value: "official",
|
|
1489
|
+
titleKey: "plugins.registryOfficial"
|
|
1490
|
+
},
|
|
1491
|
+
{
|
|
1492
|
+
value: "npmmirror",
|
|
1493
|
+
titleKey: "plugins.registryNpmmirror"
|
|
1494
|
+
},
|
|
1495
|
+
{
|
|
1496
|
+
value: "custom",
|
|
1497
|
+
titleKey: "plugins.registryCustom"
|
|
1498
|
+
}
|
|
1499
|
+
];
|
|
1409
1500
|
function InstallModal({ open, onClose, onSettled }) {
|
|
1410
1501
|
const { t, notify } = usePanel();
|
|
1411
1502
|
const [spec, setSpec] = (0, react.useState)("");
|
|
1412
1503
|
const [step, setStep] = (0, react.useState)({ kind: "editing" });
|
|
1413
1504
|
const [guideOpen, setGuideOpen] = (0, react.useState)(false);
|
|
1414
|
-
const [
|
|
1415
|
-
const [lastOp, setLastOp] = (0, react.useState)(null);
|
|
1505
|
+
const [registryOpen, setRegistryOpen] = (0, react.useState)(false);
|
|
1416
1506
|
const [registry, setRegistry] = (0, react.useState)("");
|
|
1417
1507
|
const [customRegistry, setCustomRegistry] = (0, react.useState)("");
|
|
1508
|
+
const [customInvalid, setCustomInvalid] = (0, react.useState)(false);
|
|
1509
|
+
const [detailsOpen, setDetailsOpen] = (0, react.useState)(false);
|
|
1510
|
+
const [lastOp, setLastOp] = (0, react.useState)(null);
|
|
1511
|
+
const registryToggleRef = (0, react.useRef)(null);
|
|
1512
|
+
const [registryPos, setRegistryPos] = (0, react.useState)(null);
|
|
1418
1513
|
const settled = (0, react.useRef)(onSettled);
|
|
1419
1514
|
settled.current = onSettled;
|
|
1420
1515
|
(0, react.useEffect)(() => {
|
|
@@ -1432,26 +1527,79 @@ window.__ModuleLoader__.load({
|
|
|
1432
1527
|
};
|
|
1433
1528
|
const timer = setInterval(() => {
|
|
1434
1529
|
tick();
|
|
1435
|
-
},
|
|
1530
|
+
}, 800);
|
|
1436
1531
|
tick();
|
|
1437
1532
|
return () => {
|
|
1438
1533
|
active = false;
|
|
1439
1534
|
clearInterval(timer);
|
|
1440
1535
|
};
|
|
1441
1536
|
}, [step.kind]);
|
|
1537
|
+
(0, react.useEffect)(() => {
|
|
1538
|
+
if (!registryOpen) return;
|
|
1539
|
+
const place = () => {
|
|
1540
|
+
const el = registryToggleRef.current;
|
|
1541
|
+
if (!el) return;
|
|
1542
|
+
const rect = el.getBoundingClientRect();
|
|
1543
|
+
const width = Math.min(440, window.innerWidth - 24);
|
|
1544
|
+
const left = Math.max(12, Math.min(rect.left, window.innerWidth - width - 12));
|
|
1545
|
+
const top = Math.min(rect.bottom + 6, window.innerHeight - 200);
|
|
1546
|
+
setRegistryPos({
|
|
1547
|
+
left,
|
|
1548
|
+
top
|
|
1549
|
+
});
|
|
1550
|
+
};
|
|
1551
|
+
place();
|
|
1552
|
+
window.addEventListener("resize", place);
|
|
1553
|
+
window.addEventListener("scroll", place, true);
|
|
1554
|
+
return () => {
|
|
1555
|
+
window.removeEventListener("resize", place);
|
|
1556
|
+
window.removeEventListener("scroll", place, true);
|
|
1557
|
+
};
|
|
1558
|
+
}, [registryOpen]);
|
|
1559
|
+
(0, react.useEffect)(() => {
|
|
1560
|
+
if (!registryOpen) return;
|
|
1561
|
+
const onDoc = (event) => {
|
|
1562
|
+
const target = event.target;
|
|
1563
|
+
if (registryToggleRef.current?.contains(target)) return;
|
|
1564
|
+
if (target instanceof Element && target.closest("[data-sgc-registry]")) return;
|
|
1565
|
+
setRegistryOpen(false);
|
|
1566
|
+
};
|
|
1567
|
+
const onKey = (event) => {
|
|
1568
|
+
if (event.key === "Escape") setRegistryOpen(false);
|
|
1569
|
+
};
|
|
1570
|
+
document.addEventListener("mousedown", onDoc);
|
|
1571
|
+
document.addEventListener("keydown", onKey);
|
|
1572
|
+
return () => {
|
|
1573
|
+
document.removeEventListener("mousedown", onDoc);
|
|
1574
|
+
document.removeEventListener("keydown", onKey);
|
|
1575
|
+
};
|
|
1576
|
+
}, [registryOpen]);
|
|
1442
1577
|
const run = async () => {
|
|
1443
1578
|
let chosen = null;
|
|
1444
1579
|
if (registry === "official") chosen = "https://registry.npmjs.org/";
|
|
1445
1580
|
else if (registry === "npmmirror") chosen = "https://registry.npmmirror.com/";
|
|
1446
1581
|
else if (registry === "custom") {
|
|
1447
|
-
|
|
1448
|
-
if (!/^https?:\/\/\S+$/.test(
|
|
1449
|
-
|
|
1582
|
+
const url = customRegistry.trim();
|
|
1583
|
+
if (!/^https?:\/\/\S+$/.test(url)) {
|
|
1584
|
+
setCustomInvalid(true);
|
|
1450
1585
|
return;
|
|
1451
1586
|
}
|
|
1587
|
+
chosen = url;
|
|
1452
1588
|
}
|
|
1589
|
+
setRegistryOpen(false);
|
|
1453
1590
|
setDetailsOpen(false);
|
|
1454
1591
|
setLastOp(null);
|
|
1592
|
+
setStep({ kind: "checking" });
|
|
1593
|
+
try {
|
|
1594
|
+
const { problems } = await post("/superagent-console/api/plugins/check", { spec: spec.trim() });
|
|
1595
|
+
if (problems.length > 0) {
|
|
1596
|
+
setStep({
|
|
1597
|
+
kind: "refused",
|
|
1598
|
+
problems
|
|
1599
|
+
});
|
|
1600
|
+
return;
|
|
1601
|
+
}
|
|
1602
|
+
} catch {}
|
|
1455
1603
|
setStep({ kind: "running" });
|
|
1456
1604
|
try {
|
|
1457
1605
|
await post("/superagent-console/api/plugins/install", {
|
|
@@ -1463,224 +1611,283 @@ window.__ModuleLoader__.load({
|
|
|
1463
1611
|
setStep({ kind: "editing" });
|
|
1464
1612
|
}
|
|
1465
1613
|
};
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1614
|
+
/** 立即启用: mount every bundle the add introduced, then surface the restart notice. */
|
|
1615
|
+
const enableNow = async () => {
|
|
1616
|
+
const bundles = lastOp?.installed?.filter((item) => item.bundle) ?? [];
|
|
1617
|
+
for (const item of bundles) try {
|
|
1618
|
+
await post("/superagent-console/api/plugins/enable", {
|
|
1619
|
+
name: item.name,
|
|
1620
|
+
enabled: true
|
|
1621
|
+
});
|
|
1622
|
+
} catch (failure) {
|
|
1623
|
+
notify(errorText(failure));
|
|
1624
|
+
return;
|
|
1625
|
+
}
|
|
1626
|
+
settled.current(true);
|
|
1627
|
+
onClose();
|
|
1469
1628
|
};
|
|
1470
|
-
|
|
1629
|
+
const editing = step.kind === "editing";
|
|
1630
|
+
const enableTargets = step.kind === "done" && (lastOp?.installed?.some((item) => item.bundle) ?? false);
|
|
1631
|
+
const chosenTitle = t((REGISTRY_CHOICES.find((choice) => choice.value === registry) ?? REGISTRY_CHOICES[0]).titleKey);
|
|
1632
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: SGC_CSS }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1471
1633
|
open,
|
|
1472
1634
|
onClose,
|
|
1473
|
-
className: "
|
|
1635
|
+
className: "sgc-installDialog",
|
|
1636
|
+
contentClassName: "sgc-installContent",
|
|
1474
1637
|
title: step.kind === "running" ? t("plugins.installingTitle") : step.kind === "failed" ? t("plugins.installFailedTitle") : t("plugins.installTitle"),
|
|
1475
1638
|
closeLabel: t("plugins.installClose"),
|
|
1476
|
-
description:
|
|
1477
|
-
footer:
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1639
|
+
description: editing ? t("plugins.installDescription") : void 0,
|
|
1640
|
+
footer: editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1641
|
+
className: "sgc-installFooter",
|
|
1642
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
1643
|
+
className: "sgc-installSafety",
|
|
1644
|
+
role: "note",
|
|
1645
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutlineRegular, {
|
|
1646
|
+
size: 14,
|
|
1647
|
+
"aria-hidden": "true"
|
|
1648
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1649
|
+
className: "sgc-installSafetyText",
|
|
1650
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("plugins.installGuideSafety") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("plugins.installUpgradeNotice") })]
|
|
1651
|
+
})]
|
|
1652
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1489
1653
|
variant: "primary",
|
|
1654
|
+
className: "sgc-wide",
|
|
1655
|
+
disabled: !spec.trim(),
|
|
1490
1656
|
onClick: () => {
|
|
1491
1657
|
run();
|
|
1492
1658
|
},
|
|
1493
|
-
children: t("plugins.
|
|
1494
|
-
})
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1659
|
+
children: t("plugins.installRun")
|
|
1660
|
+
})]
|
|
1661
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1662
|
+
className: "sgc-dialogActions",
|
|
1663
|
+
children: [
|
|
1664
|
+
(step.kind === "running" || step.kind === "failed") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1665
|
+
variant: "ghost",
|
|
1666
|
+
onClick: onClose,
|
|
1667
|
+
children: t("plugins.installClose")
|
|
1668
|
+
}),
|
|
1669
|
+
step.kind === "refused" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1670
|
+
variant: "primary",
|
|
1671
|
+
onClick: () => setStep({ kind: "editing" }),
|
|
1672
|
+
children: t("plugins.installEdit")
|
|
1673
|
+
}),
|
|
1674
|
+
step.kind === "failed" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1675
|
+
variant: "ghost",
|
|
1676
|
+
onClick: () => setStep({ kind: "editing" }),
|
|
1677
|
+
children: t("plugins.installChangeRegistry")
|
|
1678
|
+
}),
|
|
1679
|
+
step.kind === "failed" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1680
|
+
variant: "primary",
|
|
1681
|
+
onClick: () => {
|
|
1682
|
+
run();
|
|
1683
|
+
},
|
|
1684
|
+
children: t("plugins.installRetry")
|
|
1685
|
+
}),
|
|
1686
|
+
step.kind === "done" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1687
|
+
variant: "ghost",
|
|
1688
|
+
onClick: onClose,
|
|
1689
|
+
children: t("plugins.installClose")
|
|
1690
|
+
}),
|
|
1691
|
+
step.kind === "done" && enableTargets && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1692
|
+
variant: "primary",
|
|
1693
|
+
onClick: () => {
|
|
1694
|
+
enableNow();
|
|
1695
|
+
},
|
|
1696
|
+
children: t("plugins.installEnableNow")
|
|
1697
|
+
})
|
|
1698
|
+
]
|
|
1699
|
+
}),
|
|
1501
1700
|
children: [
|
|
1502
|
-
|
|
1503
|
-
|
|
1701
|
+
editing && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1702
|
+
className: "sgc-installBody",
|
|
1504
1703
|
children: [
|
|
1505
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1704
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1705
|
+
className: "sgc-installField",
|
|
1706
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1707
|
+
type: "text",
|
|
1708
|
+
autoFocus: true,
|
|
1709
|
+
"data-modal-autofocus": true,
|
|
1710
|
+
value: spec,
|
|
1711
|
+
placeholder: t("plugins.installSpecPlaceholder"),
|
|
1712
|
+
"aria-label": t("plugins.installSpecLabel"),
|
|
1713
|
+
onChange: (event) => {
|
|
1714
|
+
setSpec(event.target.value);
|
|
1715
|
+
},
|
|
1716
|
+
onKeyDown: (event) => {
|
|
1717
|
+
if (event.nativeEvent.isComposing) return;
|
|
1718
|
+
if (event.key === "Enter" && spec.trim()) {
|
|
1719
|
+
event.preventDefault();
|
|
1720
|
+
run();
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
})
|
|
1514
1724
|
}),
|
|
1515
1725
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1516
|
-
|
|
1517
|
-
display: "flex",
|
|
1518
|
-
alignItems: "center",
|
|
1519
|
-
justifyContent: "space-between",
|
|
1520
|
-
gap: 12,
|
|
1521
|
-
marginTop: 12
|
|
1522
|
-
},
|
|
1726
|
+
className: "sgc-optionsRow",
|
|
1523
1727
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1524
1728
|
type: "button",
|
|
1525
|
-
className: "
|
|
1729
|
+
className: "sgc-guideToggle",
|
|
1526
1730
|
"aria-expanded": guideOpen,
|
|
1527
|
-
style: {
|
|
1528
|
-
display: "inline-flex",
|
|
1529
|
-
alignItems: "center",
|
|
1530
|
-
gap: 4
|
|
1531
|
-
},
|
|
1532
1731
|
onClick: () => setGuideOpen(!guideOpen),
|
|
1533
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1534
|
-
|
|
1535
|
-
size:
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
background: "transparent",
|
|
1559
|
-
width: "auto",
|
|
1560
|
-
height: "auto",
|
|
1561
|
-
padding: 0
|
|
1562
|
-
},
|
|
1563
|
-
"aria-label": t("plugins.registryTitle"),
|
|
1564
|
-
value: registry,
|
|
1565
|
-
onChange: (event) => setRegistry(event.target.value),
|
|
1566
|
-
children: [
|
|
1567
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1568
|
-
value: "",
|
|
1569
|
-
children: t("plugins.registryDefault")
|
|
1570
|
-
}),
|
|
1571
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1572
|
-
value: "official",
|
|
1573
|
-
children: t("plugins.registryOfficial")
|
|
1574
|
-
}),
|
|
1575
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1576
|
-
value: "npmmirror",
|
|
1577
|
-
children: t("plugins.registryNpmmirror")
|
|
1578
|
-
}),
|
|
1579
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1580
|
-
value: "custom",
|
|
1581
|
-
children: t("plugins.registryCustom")
|
|
1582
|
-
})
|
|
1583
|
-
]
|
|
1584
|
-
})]
|
|
1732
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, {
|
|
1733
|
+
className: "sgc-guideChevron",
|
|
1734
|
+
size: 13,
|
|
1735
|
+
"aria-hidden": "true"
|
|
1736
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: guideOpen ? t("plugins.installGuideHide") : t("plugins.installGuideToggle") })]
|
|
1737
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1738
|
+
ref: registryToggleRef,
|
|
1739
|
+
type: "button",
|
|
1740
|
+
className: "sgc-registryToggle",
|
|
1741
|
+
"aria-expanded": registryOpen,
|
|
1742
|
+
"aria-haspopup": "dialog",
|
|
1743
|
+
onClick: () => setRegistryOpen(!registryOpen),
|
|
1744
|
+
children: [
|
|
1745
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("plugins.registryTitle") }),
|
|
1746
|
+
" ",
|
|
1747
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1748
|
+
className: "sgc-registryChosen",
|
|
1749
|
+
children: chosenTitle
|
|
1750
|
+
}),
|
|
1751
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, {
|
|
1752
|
+
className: "sgc-guideChevron",
|
|
1753
|
+
size: 12,
|
|
1754
|
+
"aria-hidden": "true"
|
|
1755
|
+
})
|
|
1756
|
+
]
|
|
1585
1757
|
})]
|
|
1586
1758
|
}),
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
children:
|
|
1759
|
+
guideOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1760
|
+
className: "sgc-guide",
|
|
1761
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ol", {
|
|
1762
|
+
className: "sgc-guideList",
|
|
1763
|
+
children: GUIDE_ITEMS.map(({ key, example, titleKey, hintKey }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
1764
|
+
className: "sgc-guideItem",
|
|
1765
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1766
|
+
className: "sgc-guideMain",
|
|
1767
|
+
children: [
|
|
1768
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1769
|
+
className: "sgc-guideTitle",
|
|
1770
|
+
children: t(titleKey)
|
|
1771
|
+
}),
|
|
1772
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1773
|
+
className: "sgc-guideHint",
|
|
1774
|
+
children: t(hintKey)
|
|
1775
|
+
}),
|
|
1776
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1777
|
+
className: "sgc-guideExample",
|
|
1778
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1779
|
+
className: "sgc-guideExampleLabel",
|
|
1780
|
+
children: t("plugins.installGuideExampleLabel")
|
|
1781
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: example })]
|
|
1782
|
+
})
|
|
1783
|
+
]
|
|
1784
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1785
|
+
variant: "outline",
|
|
1786
|
+
size: "sm",
|
|
1787
|
+
"aria-label": t("plugins.fillExample", { example }),
|
|
1788
|
+
onClick: () => setSpec(example),
|
|
1789
|
+
children: t("plugins.installGuideFill")
|
|
1790
|
+
})]
|
|
1791
|
+
}, key))
|
|
1792
|
+
})
|
|
1793
|
+
}),
|
|
1794
|
+
registryOpen && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
|
|
1795
|
+
className: "sgc-registry",
|
|
1796
|
+
"data-sgc-registry": true,
|
|
1797
|
+
"aria-label": t("plugins.registryLegend"),
|
|
1798
|
+
style: registryPos ?? {
|
|
1799
|
+
visibility: "hidden",
|
|
1800
|
+
left: 0,
|
|
1801
|
+
top: 0
|
|
1802
|
+
},
|
|
1803
|
+
children: [REGISTRY_CHOICES.map(({ value, titleKey }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1804
|
+
className: "sgc-registryOption",
|
|
1805
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1806
|
+
type: "radio",
|
|
1807
|
+
name: "sgc-registry-choice",
|
|
1808
|
+
checked: registry === value,
|
|
1809
|
+
onChange: () => {
|
|
1810
|
+
setRegistry(value);
|
|
1811
|
+
if (value !== "custom") setCustomInvalid(false);
|
|
1812
|
+
}
|
|
1813
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1814
|
+
className: "sgc-registryTitle",
|
|
1815
|
+
children: t(titleKey)
|
|
1816
|
+
})]
|
|
1817
|
+
}, value || "default")), registry === "custom" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1590
1818
|
type: "text",
|
|
1819
|
+
className: "sgc-registryCustomField",
|
|
1591
1820
|
value: customRegistry,
|
|
1592
1821
|
placeholder: t("plugins.registryCustomPlaceholder"),
|
|
1822
|
+
"aria-invalid": customInvalid || void 0,
|
|
1593
1823
|
"aria-label": t("plugins.registryCustom"),
|
|
1594
|
-
style: { width: "100%" },
|
|
1595
1824
|
onChange: (event) => {
|
|
1596
1825
|
setCustomRegistry(event.target.value);
|
|
1826
|
+
setCustomInvalid(false);
|
|
1597
1827
|
}
|
|
1598
1828
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1599
|
-
className: "
|
|
1600
|
-
children: t("plugins.registryCustomHint")
|
|
1601
|
-
})]
|
|
1602
|
-
}),
|
|
1603
|
-
guideOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1604
|
-
className: "dt-disclosure-body",
|
|
1605
|
-
style: { marginTop: 12 },
|
|
1606
|
-
children: GUIDE_EXAMPLES.map(({ key, example }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1607
|
-
className: "dt-row",
|
|
1608
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, { state: "idle" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1609
|
-
className: "dt-row-main",
|
|
1610
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1611
|
-
className: "dt-row-title dt-line-text",
|
|
1612
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GuideText, { kind: key })
|
|
1613
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1614
|
-
className: "dt-row-meta",
|
|
1615
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
1616
|
-
className: "dt-code",
|
|
1617
|
-
children: example
|
|
1618
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1619
|
-
type: "button",
|
|
1620
|
-
className: "dt-textlink",
|
|
1621
|
-
"aria-label": t("plugins.fillExample", { example }),
|
|
1622
|
-
onClick: () => setSpec(example),
|
|
1623
|
-
children: t("plugins.fill")
|
|
1624
|
-
})]
|
|
1625
|
-
})]
|
|
1626
|
-
})]
|
|
1627
|
-
}, key))
|
|
1628
|
-
}),
|
|
1629
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1630
|
-
className: "dt-banner",
|
|
1631
|
-
style: { marginTop: 12 },
|
|
1632
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1633
|
-
style: {
|
|
1634
|
-
display: "inline-flex",
|
|
1635
|
-
alignItems: "flex-start",
|
|
1636
|
-
gap: 6
|
|
1637
|
-
},
|
|
1638
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
1639
|
-
name: "alert",
|
|
1640
|
-
size: 14
|
|
1641
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("plugins.installGuideSafety") })]
|
|
1642
|
-
})
|
|
1643
|
-
}),
|
|
1644
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button$1, {
|
|
1645
|
-
variant: "primary",
|
|
1646
|
-
style: {
|
|
1647
|
-
width: "100%",
|
|
1648
|
-
marginTop: 14,
|
|
1649
|
-
display: "flex",
|
|
1650
|
-
alignItems: "center",
|
|
1651
|
-
justifyContent: "center"
|
|
1652
|
-
},
|
|
1653
|
-
disabled: !spec.trim(),
|
|
1654
|
-
onClick: () => {
|
|
1655
|
-
run();
|
|
1656
|
-
},
|
|
1657
|
-
children: t("plugins.installRun")
|
|
1658
|
-
})
|
|
1829
|
+
className: customInvalid ? "sgc-inputError sgc-registryCustomError" : "sgc-registryHint sgc-registryCustomError",
|
|
1830
|
+
children: customInvalid ? t("plugins.registryCustomInvalid") : t("plugins.registryCustomHint")
|
|
1831
|
+
})] })]
|
|
1832
|
+
}), document.body)
|
|
1659
1833
|
]
|
|
1660
1834
|
}),
|
|
1835
|
+
step.kind === "checking" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1836
|
+
className: "dt-row",
|
|
1837
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, { state: "ongoing" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1838
|
+
className: "dt-row-main",
|
|
1839
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1840
|
+
className: "dt-row-title",
|
|
1841
|
+
children: t("plugins.installChecking")
|
|
1842
|
+
})
|
|
1843
|
+
})]
|
|
1844
|
+
}),
|
|
1845
|
+
step.kind === "refused" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1846
|
+
className: "dt-row",
|
|
1847
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, { state: "error" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1848
|
+
className: "dt-row-main",
|
|
1849
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1850
|
+
className: "dt-row-title",
|
|
1851
|
+
children: t("plugins.installConfirmedRefused")
|
|
1852
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1853
|
+
className: "dt-row-meta",
|
|
1854
|
+
children: step.problems.map((problem, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
1855
|
+
problem.kind === "invalid" && t("plugins.installProblemInvalid", { reason: problem.detail ?? "" }),
|
|
1856
|
+
problem.kind === "installed" && t("plugins.installProblemInstalled"),
|
|
1857
|
+
problem.kind === "links" && t("plugins.problemLinks")
|
|
1858
|
+
] }, index))
|
|
1859
|
+
})]
|
|
1860
|
+
})]
|
|
1861
|
+
}) }),
|
|
1661
1862
|
step.kind === "running" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1662
1863
|
className: "dt-row",
|
|
1663
1864
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, { state: "ongoing" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1664
1865
|
className: "dt-row-main",
|
|
1665
1866
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1666
1867
|
className: "dt-row-title",
|
|
1667
|
-
children: t("plugins.installingTitle")
|
|
1868
|
+
children: (lastOp?.output ?? "") === "" ? t("plugins.installStarting") : t("plugins.installingTitle")
|
|
1668
1869
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1669
1870
|
className: "dt-row-meta",
|
|
1670
1871
|
children: t("plugins.installBackground")
|
|
1671
1872
|
})]
|
|
1672
1873
|
})]
|
|
1673
1874
|
}), lastOp?.output && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OutputBlock, { output: lastOp.output })] }),
|
|
1674
|
-
step.kind === "done" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1875
|
+
step.kind === "done" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1675
1876
|
className: "dt-row",
|
|
1676
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, { state: "done" }), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
1877
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, { state: "done" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1677
1878
|
className: "dt-row-main",
|
|
1678
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1879
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1679
1880
|
className: "dt-row-title",
|
|
1680
|
-
children: t("plugins.
|
|
1681
|
-
})
|
|
1881
|
+
children: t("plugins.installedTitle")
|
|
1882
|
+
}), (lastOp?.installed?.length ?? 0) > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1883
|
+
className: "dt-row-meta",
|
|
1884
|
+
children: lastOp.installed.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [item.name, item.version ? " · " + t("plugins.installVersion", { version: item.version }) : ""] }, item.name))
|
|
1885
|
+
})]
|
|
1682
1886
|
})]
|
|
1683
|
-
}),
|
|
1887
|
+
}), lastOp?.profileDir && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1888
|
+
className: "dt-row-meta",
|
|
1889
|
+
children: t("plugins.installLocation", { dir: lastOp.profileDir })
|
|
1890
|
+
})] }),
|
|
1684
1891
|
step.kind === "failed" && lastOp && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1685
1892
|
className: "dt-row",
|
|
1686
1893
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, { state: "error" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1705,7 +1912,7 @@ window.__ModuleLoader__.load({
|
|
|
1705
1912
|
})]
|
|
1706
1913
|
}) })
|
|
1707
1914
|
]
|
|
1708
|
-
});
|
|
1915
|
+
})] });
|
|
1709
1916
|
}
|
|
1710
1917
|
function PluginItem({ row, busy, onUninstall, onToggle }) {
|
|
1711
1918
|
const { t } = usePanel();
|
|
@@ -1810,7 +2017,6 @@ window.__ModuleLoader__.load({
|
|
|
1810
2017
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1811
2018
|
className: "dt-form",
|
|
1812
2019
|
children: [
|
|
1813
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: ".dt-plugins-modal.dt-modal { width: min(680px, 100%); }" }),
|
|
1814
2020
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1815
2021
|
className: "dt-status-head",
|
|
1816
2022
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h2", {
|
|
@@ -4895,7 +5101,7 @@ window.__ModuleLoader__.load({
|
|
|
4895
5101
|
"plugins.uninstallTitle": ["卸载「{name}」?", "Uninstall \"{name}\"?"],
|
|
4896
5102
|
"plugins.uninstallDescription": ["卸载后它提供的功能会消失,重启引擎后生效。", "Its features disappear; the change applies when the engine restarts."],
|
|
4897
5103
|
"plugins.installTitle": ["添加插件", "Add plugin"],
|
|
4898
|
-
"plugins.installDescription": ["输入插件的包名、
|
|
5104
|
+
"plugins.installDescription": ["输入插件的包名、GitHub 仓库地址或本地目录路径。", "Enter the plugin's package name, GitHub repository address, or local directory path."],
|
|
4899
5105
|
"plugins.installSpecLabel": ["包名或地址", "Package or address"],
|
|
4900
5106
|
"plugins.installSpecPlaceholder": ["例如 dsh-plugin-whale-pet", "e.g. dsh-plugin-whale-pet"],
|
|
4901
5107
|
"plugins.registryTitle": ["安装源", "Registry"],
|
|
@@ -4904,16 +5110,22 @@ window.__ModuleLoader__.load({
|
|
|
4904
5110
|
"plugins.registryNpmmirror": ["中国大陆镜像源", "China mirror registry"],
|
|
4905
5111
|
"plugins.registryCustom": ["自定义地址", "Custom URL"],
|
|
4906
5112
|
"plugins.registryCustomPlaceholder": ["https://npm.example.com/", "https://npm.example.com/"],
|
|
4907
|
-
"plugins.registryCustomHint": ["
|
|
5113
|
+
"plugins.registryCustomHint": ["填写内网或私有 npm 源地址,以 http:// 或 https:// 开头。若为需要登录的源,请把凭据放在本机的 ~/.npmrc 里。", "Enter an internal or private npm registry address starting with http:// or https://. If it requires a login, store the credentials in ~/.npmrc on this machine."],
|
|
4908
5114
|
"plugins.registryCustomInvalid": ["请输入以 http:// 或 https:// 开头的地址", "Enter an address starting with http:// or https://"],
|
|
4909
5115
|
"plugins.installGuideToggle": ["插件安装引导和示例", "Install guide and examples"],
|
|
4910
5116
|
"plugins.installGuideHide": ["收起引导", "Hide guide"],
|
|
4911
|
-
"plugins.installGuideNpm": ["npm
|
|
4912
|
-
"plugins.
|
|
4913
|
-
"plugins.
|
|
4914
|
-
"plugins.
|
|
5117
|
+
"plugins.installGuideNpm": ["npm 包名", "npm package name"],
|
|
5118
|
+
"plugins.installGuideNpmHint": ["插件包名即 npm 包名(如 dsh-xxx 或 @作者/插件名)。", "The plugin name is its npm name (dsh-xxx or @author/plugin)."],
|
|
5119
|
+
"plugins.installGuideGit": ["Git 仓库", "Git repository"],
|
|
5120
|
+
"plugins.installGuideGitHint": ["github:owner/repo、git URL 或 .git 地址。", "github:owner/repo, a git URL, or a .git address."],
|
|
5121
|
+
"plugins.installGuidePath": ["本地目录", "Local directory"],
|
|
5122
|
+
"plugins.installGuidePathHint": ["本机插件 checkout 的绝对路径(以 link 方式安装)。", "An absolute path to a local checkout (installed as a link)."],
|
|
5123
|
+
"plugins.installGuideExampleLabel": ["示例:", "Example:"],
|
|
5124
|
+
"plugins.installGuideFill": ["填入示例", "Use example"],
|
|
4915
5125
|
"plugins.fillExample": ["填入示例 {example}", "Fill in the example {example}"],
|
|
4916
|
-
"plugins.installGuideSafety": ["
|
|
5126
|
+
"plugins.installGuideSafety": ["请确认插件来源可信。插件在本机以你的权限运行,来源不明的插件可能损坏 DeepSeek Harness,或读取和泄露你的数据。", "Install only plugins you trust: they run with your permissions and can damage DeepSeek Harness or leak your data."],
|
|
5127
|
+
"plugins.installUpgradeNotice": ["按需安装的官方插件会在版本与 DSH 不同时提供“更新”。其他插件请先卸载再安装新版。", "On-demand Official plugins offer Update when their version differs from DSH. To update other plugins, uninstall and reinstall them."],
|
|
5128
|
+
"plugins.registryLegend": ["从哪个 npm 源下载插件", "The npm registry the plugin is downloaded from"],
|
|
4917
5129
|
"plugins.installRun": ["安装", "Install"],
|
|
4918
5130
|
"plugins.installingTitle": ["插件安装中…", "Installing plugin…"],
|
|
4919
5131
|
"plugins.installBackground": ["可以关闭此窗口,安装会在后台继续;进度显示在列表上方的横幅里。", "You can close this dialog; the install continues in the background and its progress shows in the banner above the list."],
|
|
@@ -4923,6 +5135,18 @@ window.__ModuleLoader__.load({
|
|
|
4923
5135
|
"plugins.installDetailsHide": ["收起安装详情", "Hide install details"],
|
|
4924
5136
|
"plugins.installRetry": ["重试", "Retry"],
|
|
4925
5137
|
"plugins.installClose": ["完成", "Done"],
|
|
5138
|
+
"plugins.installChecking": ["正在检查…", "Checking…"],
|
|
5139
|
+
"plugins.installStarting": ["正在准备安装…", "Preparing installation…"],
|
|
5140
|
+
"plugins.installedTitle": ["已安装", "Installed"],
|
|
5141
|
+
"plugins.installEnableNow": ["立即启用", "Enable now"],
|
|
5142
|
+
"plugins.installVersion": ["版本 {version}", "Version {version}"],
|
|
5143
|
+
"plugins.installLocation": ["安装位置:{dir}", "Installs into {dir}"],
|
|
5144
|
+
"plugins.installChangeRegistry": ["更换安装源", "Change registry"],
|
|
5145
|
+
"plugins.installConfirmedRefused": ["无法安装此插件", "This plugin cannot be installed"],
|
|
5146
|
+
"plugins.installProblemInstalled": ["该插件已安装。如需升级,请卸载后重新安装", "This plugin is already installed. To upgrade it, uninstall it and install it again"],
|
|
5147
|
+
"plugins.installProblemInvalid": ["无法识别这个包名或地址:{reason}", "This is not a package name or address that can be installed: {reason}"],
|
|
5148
|
+
"plugins.installEdit": ["编辑", "Edit"],
|
|
5149
|
+
"plugins.problemLinks": ["引擎 profile 的 link: 依赖目标不存在,请先修复后再安装。", "A link dependency of the engine profile points to a missing target; repair it before installing."],
|
|
4926
5150
|
"plugins.failure.network": ["网络连接失败,请检查网络或代理后重试", "Network failed; check connectivity or proxy, then retry"],
|
|
4927
5151
|
"plugins.failure.notFound": ["未找到相关插件", "Plugin not found"],
|
|
4928
5152
|
"plugins.failure.version": ["没有匹配的版本", "No matching version"],
|
|
@@ -7852,7 +8076,12 @@ window.__ModuleLoader__.load({
|
|
|
7852
8076
|
children: props.label
|
|
7853
8077
|
});
|
|
7854
8078
|
}
|
|
7855
|
-
function PrereqList({ prereqs, title }) {
|
|
8079
|
+
function PrereqList({ prereqs, title, st }) {
|
|
8080
|
+
const copy = (text) => {
|
|
8081
|
+
const clip = navigator.clipboard;
|
|
8082
|
+
if (!clip) return;
|
|
8083
|
+
clip.writeText(text).catch(() => void 0);
|
|
8084
|
+
};
|
|
7856
8085
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7857
8086
|
style: { marginTop: 16 },
|
|
7858
8087
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -7865,13 +8094,45 @@ window.__ModuleLoader__.load({
|
|
|
7865
8094
|
},
|
|
7866
8095
|
children: prereqs.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
7867
8096
|
style: { color: item.ok ? "inherit" : "var(--dsh-danger, #d64545)" },
|
|
7868
|
-
children: [
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
8097
|
+
children: [
|
|
8098
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
8099
|
+
style: monoStyle,
|
|
8100
|
+
children: item.name
|
|
8101
|
+
}),
|
|
8102
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8103
|
+
style: { opacity: .75 },
|
|
8104
|
+
children: [" — ", item.detail]
|
|
8105
|
+
}),
|
|
8106
|
+
!item.ok && item.hint && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8107
|
+
style: {
|
|
8108
|
+
display: "inline-flex",
|
|
8109
|
+
alignItems: "center",
|
|
8110
|
+
gap: 6,
|
|
8111
|
+
marginLeft: 8
|
|
8112
|
+
},
|
|
8113
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
8114
|
+
style: {
|
|
8115
|
+
...monoStyle,
|
|
8116
|
+
opacity: .85
|
|
8117
|
+
},
|
|
8118
|
+
children: item.hint
|
|
8119
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8120
|
+
type: "button",
|
|
8121
|
+
onClick: () => {
|
|
8122
|
+
copy(item.hint ?? "");
|
|
8123
|
+
},
|
|
8124
|
+
style: {
|
|
8125
|
+
...buttonStyle,
|
|
8126
|
+
padding: "1px 8px",
|
|
8127
|
+
fontSize: 11,
|
|
8128
|
+
borderRadius: 6,
|
|
8129
|
+
color: "inherit",
|
|
8130
|
+
borderColor: "var(--dsh-border, rgba(128,128,128,.4))"
|
|
8131
|
+
},
|
|
8132
|
+
children: st("copyCommand")
|
|
8133
|
+
})]
|
|
8134
|
+
})
|
|
8135
|
+
]
|
|
7875
8136
|
}, item.name))
|
|
7876
8137
|
})]
|
|
7877
8138
|
});
|
|
@@ -8084,7 +8345,8 @@ window.__ModuleLoader__.load({
|
|
|
8084
8345
|
}),
|
|
8085
8346
|
(status.state === "not-installed" || status.state === "prereq-missing" || installing) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrereqList, {
|
|
8086
8347
|
prereqs: status.prereqs,
|
|
8087
|
-
title: st("prereqsTitle")
|
|
8348
|
+
title: st("prereqsTitle"),
|
|
8349
|
+
st
|
|
8088
8350
|
}),
|
|
8089
8351
|
(installing || status.setup.current || STAGES.some((id) => status.setup.stages[id]?.status !== "pending")) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StageList, {
|
|
8090
8352
|
setup: status.setup,
|
|
@@ -8166,7 +8428,7 @@ window.__ModuleLoader__.load({
|
|
|
8166
8428
|
descStopped: "引擎服务处于停止状态,可以一键拉起(tmux 会话由生命周期脚本托管)。",
|
|
8167
8429
|
descUnhealthy: "引擎进程存在但管理 API 不可达或组件报错,可尝试重启。",
|
|
8168
8430
|
descNotInstalled: "引擎运行在独立的 DSH profile 中。点击安装后,控制台会在线拉取官方源码、自动构建并部署到独立 profile(npm 上无此包,源码构建是官方唯一安装路径)。",
|
|
8169
|
-
descPrereq: "
|
|
8431
|
+
descPrereq: "在线安装需要以下工具,红项按提示命令补齐后点「重试」(凭据类操作仍需本人完成)。",
|
|
8170
8432
|
install: "在线安装引擎",
|
|
8171
8433
|
installResume: "继续安装",
|
|
8172
8434
|
installing: "正在安装…",
|
|
@@ -8176,6 +8438,7 @@ window.__ModuleLoader__.load({
|
|
|
8176
8438
|
starting: "正在启动…",
|
|
8177
8439
|
restarting: "正在重启…",
|
|
8178
8440
|
prereqsTitle: "前置依赖",
|
|
8441
|
+
copyCommand: "复制",
|
|
8179
8442
|
stageTitle: "安装进度",
|
|
8180
8443
|
setupWait: "引擎已启动,正在等待首次配置(Source 设置需在引擎面板完成)。",
|
|
8181
8444
|
manuallyStopped: "引擎带有手动停止标记,已按需忽略。",
|
|
@@ -8196,7 +8459,7 @@ window.__ModuleLoader__.load({
|
|
|
8196
8459
|
descStopped: "The engine service is stopped. Start it with one click (the tmux session is managed by the lifecycle script).",
|
|
8197
8460
|
descUnhealthy: "The engine process exists but the management API is unreachable or a component reports an error. Try a restart.",
|
|
8198
8461
|
descNotInstalled: "The engine runs in its own dedicated DSH profile. Installing fetches the official source online, builds it, and deploys it into that profile (the package is not published to npm; source build + link is the only official path).",
|
|
8199
|
-
descPrereq: "The online installer needs the tools below
|
|
8462
|
+
descPrereq: "The online installer needs the tools below — fix failing entries with the suggested command, then Retry (credential steps stay yours).",
|
|
8200
8463
|
install: "Install engine online",
|
|
8201
8464
|
installResume: "Resume install",
|
|
8202
8465
|
installing: "Installing…",
|
|
@@ -8206,6 +8469,7 @@ window.__ModuleLoader__.load({
|
|
|
8206
8469
|
starting: "Starting…",
|
|
8207
8470
|
restarting: "Restarting…",
|
|
8208
8471
|
prereqsTitle: "Prerequisites",
|
|
8472
|
+
copyCommand: "Copy",
|
|
8209
8473
|
stageTitle: "Install progress",
|
|
8210
8474
|
setupWait: "Engine is up and waiting for first-time setup (Source configuration happens in the engine panel).",
|
|
8211
8475
|
manuallyStopped: "The engine carries a manual-stop marker; honored on demand.",
|