dsh-multi-router 0.3.8 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/client.jsx
21
21
  var client_exports = {};
22
22
  __export(client_exports, {
23
+ InitialSetup: () => InitialSetup,
24
+ PluginUpdatesPanel: () => PluginUpdatesPanel,
23
25
  RestartGuidance: () => RestartGuidance,
24
26
  RouterPage: () => RouterPage,
25
27
  apply: () => apply,
@@ -32,7 +34,7 @@ module.exports = __toCommonJS(client_exports);
32
34
  var import_react = require("react");
33
35
 
34
36
  // package.json
35
- var version = "0.3.8";
37
+ var version = "0.4.1";
36
38
 
37
39
  // src/client.jsx
38
40
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -142,6 +144,17 @@ function RouterPage({ view = "page" }) {
142
144
  }, 15e3);
143
145
  return () => clearInterval(timer);
144
146
  }, [view, live]);
147
+ (0, import_react.useEffect)(() => {
148
+ if (data?.pluginUpdates?.job?.state !== "running") return;
149
+ const timer = setInterval(() => {
150
+ if (polling.current) return;
151
+ polling.current = true;
152
+ void load().catch((e) => setError(e.message)).finally(() => {
153
+ polling.current = false;
154
+ });
155
+ }, 2e3);
156
+ return () => clearInterval(timer);
157
+ }, [data?.pluginUpdates?.job?.state]);
145
158
  async function act(action) {
146
159
  if (busy || backendNeedsRestart(data)) return false;
147
160
  setBusy(true);
@@ -152,7 +165,7 @@ function RouterPage({ view = "page" }) {
152
165
  const next = await readManagementResponse(res);
153
166
  const { exported, ...state } = next;
154
167
  setData(state);
155
- setNotice(action.action === "accounts.discover" || action.action === "monitor.refresh" ? "\u5DF2\u91CD\u65B0\u68C0\u6D4B\u672C\u673A\u767B\u5F55\u5E76\u5237\u65B0\u7528\u91CF\uFF1B\u68C0\u6D4B\u7ED3\u679C\u89C1\u4E0B\u65B9\u3002" : action.action.includes("refresh") ? "\u5DF2\u5237\u65B0\u3002\u65E0\u6CD5\u83B7\u53D6\u7684\u8D26\u53F7\u4F1A\u4FDD\u7559\u4E0A\u6B21\u6570\u636E\u5E76\u6807\u8BB0\u3002" : action.action === "config.import" ? "\u914D\u7F6E\u5DF2\u5BFC\u5165\u5E76\u751F\u6548\uFF0C\u539F\u914D\u7F6E\u5DF2\u5907\u4EFD\uFF1B\u6A21\u578B\u548C\u7528\u91CF\u6B63\u5728\u540E\u53F0\u66F4\u65B0\u3002" : action.action.startsWith("config.") || action.action === "account.export" ? "" : "\u5DF2\u4FDD\u5B58\u5E76\u751F\u6548\u3002");
168
+ setNotice(action.action.startsWith("plugins.") || action.action === "setup.dismiss" ? "" : action.action === "accounts.discover" || action.action === "monitor.refresh" ? "\u5DF2\u91CD\u65B0\u68C0\u6D4B\u672C\u673A\u767B\u5F55\u5E76\u5237\u65B0\u7528\u91CF\uFF1B\u68C0\u6D4B\u7ED3\u679C\u89C1\u4E0B\u65B9\u3002" : action.action.includes("refresh") ? "\u5DF2\u5237\u65B0\u3002\u65E0\u6CD5\u83B7\u53D6\u7684\u8D26\u53F7\u4F1A\u4FDD\u7559\u4E0A\u6B21\u6570\u636E\u5E76\u6807\u8BB0\u3002" : action.action === "config.import" ? "\u914D\u7F6E\u5DF2\u5BFC\u5165\u5E76\u751F\u6548\uFF0C\u539F\u914D\u7F6E\u5DF2\u5907\u4EFD\uFF1B\u6A21\u578B\u548C\u7528\u91CF\u6B63\u5728\u540E\u53F0\u66F4\u65B0\u3002" : action.action.startsWith("config.") || action.action === "account.export" ? "" : "\u5DF2\u4FDD\u5B58\u5E76\u751F\u6548\u3002");
156
169
  return next;
157
170
  } catch (e) {
158
171
  setError(e.message);
@@ -195,7 +208,7 @@ function RouterPage({ view = "page" }) {
195
208
  }, children: "\u5237\u65B0\u9762\u677F" })
196
209
  ] })
197
210
  ] }),
198
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("nav", { "aria-label": "\u8DEF\u7531\u63D2\u4EF6\u914D\u7F6E\u9875\u7B7E", children: [["overview", "\u603B\u89C8\u4E0E\u7528\u91CF"], ["usage", "Token \u660E\u7EC6"], ["accounts", "\u8D26\u53F7\u4E0E\u767B\u5F55"], ["models", "\u6A21\u578B\u7BA1\u7406"], ["routes", "\u8DEF\u7531\u89C4\u5219"], ["migration", "\u914D\u7F6E\u8FC1\u79FB"]].map(([key, label]) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { "aria-pressed": tab === key, onClick: () => {
211
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("nav", { "aria-label": "\u8DEF\u7531\u63D2\u4EF6\u914D\u7F6E\u9875\u7B7E", children: [["overview", "\u603B\u89C8\u4E0E\u7528\u91CF"], ["usage", "Token \u660E\u7EC6"], ["accounts", "\u8D26\u53F7\u4E0E\u767B\u5F55"], ["models", "\u6A21\u578B\u7BA1\u7406"], ["routes", "\u8DEF\u7531\u89C4\u5219"], ["plugins", "\u63D2\u4EF6\u66F4\u65B0"], ["migration", "\u914D\u7F6E\u8FC1\u79FB"]].map(([key, label]) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { "aria-pressed": tab === key, onClick: () => {
199
212
  setTab(key);
200
213
  setError("");
201
214
  setNotice("");
@@ -205,7 +218,9 @@ function RouterPage({ view = "page" }) {
205
218
  void load().catch((e) => setError(e.message));
206
219
  } }),
207
220
  !data ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { role: "status", children: error ? "\u63D2\u4EF6\u540E\u53F0\u6682\u4E0D\u53EF\u7528\u3002\u4FEE\u590D\u542F\u7528\u9519\u8BEF\u540E\u70B9\u51FB\u300C\u5237\u65B0\u9762\u677F\u300D\u3002" : "\u6B63\u5728\u8BFB\u53D6\u8D26\u53F7\u4E0E\u7528\u91CF\u2026" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", { className: "stack", style: { border: 0, padding: 0, margin: 0, minWidth: 0 }, disabled: backendNeedsRestart(data), "aria-busy": busy, children: [
221
+ ["overview", "accounts"].includes(tab) && data.setup?.dismissed !== true && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InitialSetup, { data, busy, act, go: (key) => setTab(key) }),
208
222
  tab === "overview" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Overview, { data, live, setLive, busy, act, go: (key) => setTab(key) }),
223
+ tab === "plugins" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluginUpdatesPanel, { data: data.pluginUpdates, busy, act }),
209
224
  tab === "usage" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UsageDetails, { data, busy, act }),
210
225
  tab === "accounts" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
211
226
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
@@ -531,15 +546,16 @@ function Overview({ data, live, setLive, busy, act, go }) {
531
546
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
532
547
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5FEB\u901F\u5F00\u59CB" }),
533
548
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
534
- "1. \u6DFB\u52A0\u8D26\u53F7\u5E76\u83B7\u53D6\u767B\u5F55\u4FE1\u606F",
549
+ "1. \u786E\u8BA4\u81EA\u52A8\u83B7\u53D6\u7684\u8D26\u53F7\uFF0C\u6216\u624B\u52A8\u6DFB\u52A0\u51ED\u8BC1",
535
550
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
536
- "2. \u83B7\u53D6\u6A21\u578B\u76EE\u5F55\uFF0C\u9009\u62E9\u8981\u5C55\u793A\u7684\u6A21\u578B",
551
+ "2. \u4F7F\u7528\u9884\u5236\u8DEF\u7531\uFF0C\u6309\u9700\u7F16\u8F91\u8D26\u53F7\u5207\u6362\u89C4\u5219",
537
552
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
538
- "3. \u5EFA\u7ACB\u7EDF\u4E00\u8DEF\u7531\uFF0C\u518D\u5230 DSH \u9009\u62E9\u5B83"
553
+ "3. \u5230 DSH \u6A21\u578B\u9009\u62E9\u5668\u9009\u62E9\u300C\u7EDF\u4E00\u8DEF\u7531\u300D\u4E2D\u7684\u6A21\u578B"
539
554
  ] }),
540
555
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
541
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => go("accounts"), children: "\u6DFB\u52A0\u8D26\u53F7" }),
542
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => go("routes"), children: "\u914D\u7F6E\u8DEF\u7531" })
556
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => go("accounts"), children: "\u67E5\u770B\u8D26\u53F7" }),
557
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => go("routes"), children: "\u914D\u7F6E\u8DEF\u7531" }),
558
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => go("plugins"), children: "\u68C0\u67E5\u6240\u6709\u63D2\u4EF6\u66F4\u65B0" })
543
559
  ] })
544
560
  ] })
545
561
  ] }),
@@ -1398,5 +1414,209 @@ function RouteForm({ draft, setDraft, data, act, busy, error, notice }) {
1398
1414
  ] })
1399
1415
  ] });
1400
1416
  }
1417
+ function InitialSetup({ data, busy, act, go }) {
1418
+ const discovery = data.localDiscovery ?? [];
1419
+ const saved = discovery.reduce((n, s) => n + (s.savedCount ?? 0), 0);
1420
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", "aria-label": "\u9996\u6B21\u8D26\u53F7\u8BBE\u7F6E", children: [
1421
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
1422
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
1423
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", { children: [
1424
+ "\u672C\u673A\u8D26\u53F7\u81EA\u52A8\u83B7\u53D6",
1425
+ discovery.length ? "\u5DF2\u5B8C\u6210" : "\u5F85\u91CD\u8BD5"
1426
+ ] }),
1427
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: saved ? `\u5DF2\u4FDD\u5B58 ${saved} \u4E2A WorkBuddy / Trae \u672C\u673A\u767B\u5F55\uFF0C\u65E0\u9700\u518D\u6B21\u624B\u52A8\u6DFB\u52A0\u3002` : "\u6682\u672A\u4FDD\u5B58\u672C\u673A\u767B\u5F55\u3002\u5148\u5728\u5B98\u65B9\u5BA2\u6237\u7AEF\u767B\u5F55\uFF0C\u518D\u70B9\u51FB\u300C\u4E00\u952E\u83B7\u53D6\u5E76\u4FDD\u5B58\u300D\u3002" })
1428
+ ] }),
1429
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
1430
+ void act({ action: "setup.dismiss" });
1431
+ }, children: "\u77E5\u9053\u4E86" })
1432
+ ] }),
1433
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "providers", children: discovery.map((s) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "steps", children: [
1434
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: data.providers.find((p) => p.id === s.provider)?.name ?? s.provider }),
1435
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: (s.savedCount ?? 0) > 0 ? "good" : "notice", children: s.savedCount ? `\u5DF2\u4FDD\u5B58 ${s.savedCount} \u4E2A\u767B\u5F55` : s.state === "found" ? "\u68C0\u6D4B\u5230\u767B\u5F55\uFF1B\u5DF2\u5FFD\u7565\u6216\u5C1A\u672A\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u65B0\u83B7\u53D6" : s.state === "unreadable" ? "\u767B\u5F55\u6587\u4EF6\u65E0\u6CD5\u8BFB\u53D6\uFF0C\u8BF7\u5728\u5BA2\u6237\u7AEF\u91CD\u65B0\u767B\u5F55\u540E\u91CD\u8BD5" : "\u672A\u68C0\u6D4B\u5230\u767B\u5F55\uFF0C\u8BF7\u5148\u767B\u5F55\u5B98\u65B9\u5BA2\u6237\u7AEF" })
1436
+ ] }, s.provider)) }),
1437
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
1438
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: busy, onClick: () => {
1439
+ void act({ action: "accounts.discover" });
1440
+ }, children: "\u4E00\u952E\u83B7\u53D6\u5E76\u4FDD\u5B58 WorkBuddy / Trae" }),
1441
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => go("accounts"), children: "\u67E5\u770B\u8D26\u53F7 / \u624B\u52A8\u6DFB\u52A0" }),
1442
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => go("routes"), children: "\u9009\u62E9\u8DEF\u7531\u6A21\u578B" })
1443
+ ] }),
1444
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u9996\u6B21\u542F\u52A8\u81EA\u52A8\u6267\u884C\u4E00\u6B21\uFF0C\u4E4B\u540E\u6BCF\u5206\u949F\u68C0\u6D4B\u65B0\u589E\u767B\u5F55\u3002Qoder \u4F7F\u7528 PAT\uFF0C\u8BF7\u5230\u300C\u8D26\u53F7\u4E0E\u767B\u5F55\u300D\u6DFB\u52A0\uFF1B\u672A\u5B89\u88C5\u5BA2\u6237\u7AEF\u4E5F\u53EF\u4EE5\u624B\u52A8\u586B\u5199\u51ED\u8BC1\u3002" })
1445
+ ] });
1446
+ }
1447
+ var updateNames = { unchecked: "\u5F85\u68C0\u67E5", available: "\u53EF\u66F4\u65B0", current: "\u5DF2\u540C\u6B65", pinned: "\u56FA\u5B9A\u63D0\u4EA4", builtin: "\u968F DSH \u5347\u7EA7", unsupported: "\u672C\u5730\u6765\u6E90", failed: "\u68C0\u67E5 / \u5B89\u88C5\u5931\u8D25", installed: "\u5DF2\u5B89\u88C5" };
1448
+ function PluginUpdatesPanel({ data, busy, act }) {
1449
+ const [query, setQuery] = (0, import_react.useState)(""), [selected, setSelected] = (0, import_react.useState)([]), [plan, setPlan] = (0, import_react.useState)(null), [registry, setRegistry] = (0, import_react.useState)(""), [filter, setFilter] = (0, import_react.useState)("all"), [pluginSearch, setPluginSearch] = (0, import_react.useState)("");
1450
+ const running = data?.job?.state === "running", blocked = busy || running;
1451
+ const rows = data?.rows ?? [], available = rows.filter((r) => r.status === "available" || r.status === "failed" && r.target);
1452
+ (0, import_react.useEffect)(() => {
1453
+ if (data?.available && !running) void act({ action: !data.checkedAt || Date.now() - data.checkedAt > 864e5 ? "plugins.check" : "plugins.list" });
1454
+ }, []);
1455
+ const chosen = available.filter((r) => selected.includes(r.name));
1456
+ const visibleRows = rows.filter((r) => r.name.toLowerCase().includes(pluginSearch.toLowerCase()) && (filter === "all" || (filter === "updates" ? available.includes(r) : r.source.kind === filter)));
1457
+ async function submitPlan() {
1458
+ if (await act(plan.kind === "install" ? { action: "plugins.install", spec: plan.spec, registry: registry || void 0 } : { action: "plugins.update", names: plan.rows.map((r) => r.name), registry: registry || void 0 })) {
1459
+ setPlan(null);
1460
+ setSelected([]);
1461
+ }
1462
+ }
1463
+ if (!data?.available) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
1464
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5F53\u524D DSH \u672A\u63D0\u4F9B\u63D2\u4EF6\u7BA1\u7406\u63A5\u53E3" }),
1465
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u8BF7\u5347\u7EA7 DeepSeek Harness \u540E\u91CD\u8BD5\u3002\u672C\u9875\u7BA1\u7406\u5F53\u524D DSH \u914D\u7F6E\u4E2D\u7684\u5168\u90E8\u5DF2\u5B89\u88C5\u63D2\u4EF6\u3002" })
1466
+ ] });
1467
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
1468
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
1469
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
1470
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
1471
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5DF2\u5B89\u88C5\u63D2\u4EF6\u4E0E\u66F4\u65B0" }),
1472
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "npm \u6309\u7248\u672C / \u53D1\u5E03\u9891\u9053\u68C0\u67E5\uFF1BGitHub \u6309\u5206\u652F\u63D0\u4EA4\u68C0\u67E5\uFF0C\u7248\u672C\u53F7\u4E0D\u53D8\u4E5F\u80FD\u53D1\u73B0\u66F4\u65B0\u3002" })
1473
+ ] }),
1474
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: blocked, onClick: () => {
1475
+ void act({ action: "plugins.check" });
1476
+ }, children: "\u68C0\u67E5\u5168\u90E8\u66F4\u65B0" })
1477
+ ] }),
1478
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
1479
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
1480
+ rows.length,
1481
+ " \u4E2A\u5DF2\u5B89\u88C5\u63D2\u4EF6 \xB7 ",
1482
+ available.length,
1483
+ " \u4E2A\u53EF\u66F4\u65B0 \xB7 \u4E0A\u6B21\u68C0\u67E5 ",
1484
+ when(data.checkedAt)
1485
+ ] }),
1486
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
1487
+ "npm \u5B89\u88C5\u6E90",
1488
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { value: registry, disabled: blocked, onChange: (e) => setRegistry(e.target.value), children: [
1489
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "DSH \u8BBE\u7F6E\uFF08\u542B\u56DE\u9000\u6765\u6E90\uFF09" }),
1490
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "https://registry.npmjs.org/", children: "npm \u5B98\u65B9" }),
1491
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "https://registry.npmmirror.com/", children: "npmmirror" })
1492
+ ] })
1493
+ ] })
1494
+ ] }),
1495
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u66F4\u65B0\u6CBF\u7528\u539F npm / GitHub \u6765\u6E90\uFF0C\u5E76\u4FDD\u7559\u542F\u7528\u72B6\u6001\uFF1Bnpm \u56FA\u5B9A\u7248\u672C\u548C\u8303\u56F4\u5347\u7EA7\u5230\u6240\u5728\u9891\u9053\u7684\u6700\u65B0\u7248\u672C\uFF0CGit \u56FA\u5B9A\u63D0\u4EA4\u4FDD\u6301\u4E0D\u52A8\u3002\u5B98\u65B9\u5185\u7F6E\u7EC4\u4EF6\u968F DSH \u66F4\u65B0\u3002" })
1496
+ ] }),
1497
+ data.job && !(data.job.kind === "check" && data.job.state === "done") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", "aria-live": "polite", children: [
1498
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
1499
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: running ? data.job.kind === "check" ? "\u6B63\u5728\u68C0\u67E5\u66F4\u65B0\u2026" : "\u6B63\u5728\u5B89\u88C5\u63D2\u4EF6\u2026" : data.job.state === "cancelled" ? "\u64CD\u4F5C\u5DF2\u53D6\u6D88" : data.job.state === "failed" ? "\u64CD\u4F5C\u672A\u5B8C\u6210" : "\u64CD\u4F5C\u5DF2\u5B8C\u6210" }),
1500
+ running && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
1501
+ void act({ action: "plugins.cancel" });
1502
+ }, children: "\u53D6\u6D88" })
1503
+ ] }),
1504
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("progress", { max: Math.max(1, data.job.total), value: data.job.results.length, "aria-label": "\u63D2\u4EF6\u64CD\u4F5C\u8FDB\u5EA6" }),
1505
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
1506
+ data.job.results.length,
1507
+ " / ",
1508
+ data.job.total,
1509
+ data.job.current ? ` \xB7 ${data.job.current}` : ""
1510
+ ] }),
1511
+ data.job.message && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "error", children: data.job.message }),
1512
+ data.job.results.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "item", children: [
1513
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: r.name }),
1514
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: r.status === "failed" ? "error" : "notice", children: r.message || updateNames[r.status] || r.status }),
1515
+ r.pendingBuilds?.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
1516
+ "\u5F85\u6388\u6743\u811A\u672C\uFF1A",
1517
+ r.pendingBuilds.join("\u3001"),
1518
+ "\u3002\u8BF7\u5728 DSH \u539F\u63D2\u4EF6\u5B89\u88C5\u9875\u6388\u6743\u540E\u91CD\u8BD5\u3002"
1519
+ ] })
1520
+ ] }, r.name + i)),
1521
+ data.job.results.some((r) => r.restartRequired) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "steps", children: "\u66F4\u65B0\u6587\u4EF6\u5DF2\u5B89\u88C5\u3002macOS \u4F7F\u7528 \u2318Q \u5B8C\u5168\u9000\u51FA DSH \u540E\u91CD\u5F00\uFF1BWindows \u9000\u51FA\u6258\u76D8\u5E94\u7528\u540E\u91CD\u5F00\uFF1B\u7F51\u9875\u7248\u91CD\u542F\u670D\u52A1\u3002\u5173\u95ED\u7A97\u53E3\u548C\u300C\u5237\u65B0\u9762\u677F\u300D\u4E0D\u4F1A\u91CD\u8F7D\u540E\u53F0\u3002" })
1522
+ ] }),
1523
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
1524
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
1525
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
1526
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked || !available.length, onClick: () => setSelected(available.map((r) => r.name)), children: "\u9009\u62E9\u5168\u90E8\u53EF\u66F4\u65B0" }),
1527
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked || !selected.length, onClick: () => setSelected([]), children: "\u6E05\u7A7A\u9009\u62E9" })
1528
+ ] }),
1529
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { className: "primary", disabled: blocked || !chosen.length, onClick: () => setPlan({ kind: "update", rows: chosen }), children: [
1530
+ "\u66F4\u65B0\u6240\u9009\uFF08",
1531
+ chosen.length,
1532
+ "\uFF09"
1533
+ ] })
1534
+ ] }),
1535
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
1536
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: { flex: 1 }, children: [
1537
+ "\u641C\u7D22\u5DF2\u5B89\u88C5\u63D2\u4EF6",
1538
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { value: pluginSearch, onChange: (e) => setPluginSearch(e.target.value), placeholder: "\u6309\u63D2\u4EF6\u540D\u79F0\u7B5B\u9009" })
1539
+ ] }),
1540
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
1541
+ "\u663E\u793A\u8303\u56F4",
1542
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { value: filter, onChange: (e) => setFilter(e.target.value), children: [
1543
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "all", children: "\u5168\u90E8\u5DF2\u5B89\u88C5\u63D2\u4EF6" }),
1544
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "updates", children: "\u53EF\u66F4\u65B0 / \u91CD\u8BD5" }),
1545
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "npm", children: "npm \u6765\u6E90" }),
1546
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "github", children: "GitHub \u6765\u6E90" }),
1547
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "builtin", children: "DSH \u5185\u7F6E\u7EC4\u4EF6" })
1548
+ ] })
1549
+ ] })
1550
+ ] }),
1551
+ visibleRows.map((r) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "item stack", children: [
1552
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
1553
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "check", children: [
1554
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", disabled: blocked || !available.includes(r), checked: selected.includes(r.name), onChange: (e) => setSelected(e.target.checked ? [...selected, r.name] : selected.filter((n) => n !== r.name)) }),
1555
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { className: "mono", children: r.name })
1556
+ ] }),
1557
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "badge", children: [
1558
+ updateNames[r.status],
1559
+ " \xB7 ",
1560
+ r.enabled ? "\u542F\u7528" : "\u505C\u7528"
1561
+ ] })
1562
+ ] }),
1563
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
1564
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
1565
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: r.source.kind === "npm" ? `npm \xB7 ${r.version || "\u672A\u77E5"}${r.latestVersion ? " \u2192 " + r.latestVersion : ""} \xB7 ${r.source.tag}` : r.source.kind === "github" ? `GitHub \xB7 ${r.version || "\u672A\u77E5\u7248\u672C"} \xB7 ${r.commit?.slice(0, 8) || "\u672A\u77E5\u63D0\u4EA4"}${r.latestCommit ? " \u2192 " + r.latestCommit.slice(0, 8) : ""}` : r.source.kind === "builtin" ? `DSH \u5185\u7F6E\u7EC4\u4EF6 \xB7 ${r.version || "\u672A\u77E5\u7248\u672C"}` : "\u672C\u5730\u6587\u4EF6 / \u5F00\u53D1\u94FE\u63A5" }),
1566
+ r.source.kind === "github" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice mono", children: r.source.source }),
1567
+ r.message && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: r.status === "failed" ? "notice error" : "notice", children: r.message })
1568
+ ] }),
1569
+ available.includes(r) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked, onClick: () => setPlan({ kind: "update", rows: [r] }), children: "\u67E5\u770B\u5E76\u66F4\u65B0" })
1570
+ ] })
1571
+ ] }, r.name)),
1572
+ !visibleRows.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "empty", children: running ? "\u6B63\u5728\u8BFB\u53D6\u63D2\u4EF6\u6E05\u5355\u2026" : rows.length ? "\u6CA1\u6709\u5339\u914D\u7684\u5DF2\u5B89\u88C5\u63D2\u4EF6\uFF0C\u8BF7\u8C03\u6574\u7B5B\u9009\u3002" : "\u5F53\u524D\u914D\u7F6E\u5C1A\u672A\u8BFB\u53D6\u63D2\u4EF6\uFF0C\u8BF7\u68C0\u67E5\u66F4\u65B0\u3002" })
1573
+ ] }),
1574
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
1575
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5B89\u88C5 npm / GitHub \u63D2\u4EF6" }),
1576
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { className: "row", onSubmit: (e) => {
1577
+ e.preventDefault();
1578
+ const spec = new FormData(e.currentTarget).get("spec").trim();
1579
+ if (spec) setPlan({ kind: "install", spec });
1580
+ }, children: [
1581
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: { flex: 1 }, children: [
1582
+ "\u5B89\u88C5\u5730\u5740",
1583
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { name: "spec", value: query, onChange: (e) => setQuery(e.target.value), disabled: blocked, required: true, placeholder: "\u5305\u540D\u3001\u5305\u540D@\u7248\u672C \u6216 github:\u7528\u6237/\u4ED3\u5E93", autoComplete: "off" })
1584
+ ] }),
1585
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked || !query.trim(), children: "\u67E5\u770B\u5E76\u5B89\u88C5" })
1586
+ ] }),
1587
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u4F7F\u7528 DSH \u81EA\u5E26\u5B89\u88C5\u5668\u6267\u884C\u517C\u5BB9\u68C0\u67E5\u3001\u955C\u50CF\u91CD\u8BD5\u548C\u5931\u8D25\u56DE\u6EDA\u3002npm \u955C\u50CF\u53EA\u4F5C\u7528\u4E8E npm \u5305\uFF0CGitHub \u4E0B\u8F7D\u5931\u8D25\u9700\u68C0\u67E5 GitHub \u7F51\u7EDC\u3002\u7F51\u7EDC\u5931\u8D25\u540E\u53EF\u91CD\u65B0\u68C0\u67E5\u6216\u66F4\u6362 npm \u5B89\u88C5\u6E90\u518D\u91CD\u8BD5\u3002" })
1588
+ ] }),
1589
+ plan && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Modal, { title: plan.kind === "install" ? "\u786E\u8BA4\u5B89\u88C5\u63D2\u4EF6" : "\u786E\u8BA4\u66F4\u65B0\u63D2\u4EF6", close: () => setPlan(null), busy: blocked, children: [
1590
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-body stack", children: [
1591
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u8FD9\u4E9B\u64CD\u4F5C\u4F5C\u7528\u4E8E\u5F53\u524D DSH \u914D\u7F6E\u7684\u6240\u6709\u4F1A\u8BDD\u3002\u5B89\u88C5\u540E\u662F\u5426\u9700\u8981\u91CD\u542F\uFF0C\u4F1A\u5728\u7ED3\u679C\u4E2D\u8BF4\u660E\u3002" }),
1592
+ plan.kind === "install" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mono", children: plan.spec }) : plan.rows.map((r) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "steps", children: [
1593
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: r.name }),
1594
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mono", children: r.target }),
1595
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: r.source.kind === "npm" ? `${r.version || "\u672A\u77E5"} \u2192 ${r.latestVersion}` : `${r.commit?.slice(0, 8) || "\u672A\u77E5\u63D0\u4EA4"} \u2192 ${r.latestCommit?.slice(0, 8) || "\u672A\u77E5\u63D0\u4EA4"}` }),
1596
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
1597
+ "\u4FDD\u7559\u4E3A",
1598
+ r.enabled ? "\u542F\u7528" : "\u505C\u7528",
1599
+ "\uFF1B",
1600
+ r.source.kind === "github" ? "\u7EE7\u7EED\u8DDF\u968F\u539F\u5206\u652F / \u6807\u7B7E" : "\u66F4\u65B0\u5230\u6240\u793A npm \u7248\u672C",
1601
+ "\u3002"
1602
+ ] })
1603
+ ] }, r.name)),
1604
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
1605
+ "npm \u5B89\u88C5\u6E90\uFF1A",
1606
+ registry || "\u6CBF\u7528 DSH \u8BBE\u7F6E"
1607
+ ] })
1608
+ ] }),
1609
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "modal-foot row", children: [
1610
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { className: "primary", disabled: blocked, onClick: () => {
1611
+ void submitPlan();
1612
+ }, children: [
1613
+ "\u786E\u8BA4",
1614
+ plan.kind === "install" ? "\u5B89\u88C5" : "\u66F4\u65B0"
1615
+ ] }),
1616
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: blocked, onClick: () => setPlan(null), children: "\u53D6\u6D88" })
1617
+ ] })
1618
+ ] })
1619
+ ] });
1620
+ }
1401
1621
  return module.exports; } });
1402
1622
  //# sourceMappingURL=client.js.map