dsh-multi-router 0.3.7 → 0.4.0

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,18 +20,43 @@ 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,
25
+ RestartGuidance: () => RestartGuidance,
23
26
  RouterPage: () => RouterPage,
24
27
  apply: () => apply,
28
+ backendNeedsRestart: () => backendNeedsRestart,
25
29
  inject: () => inject,
26
30
  name: () => name,
27
31
  readManagementResponse: () => readManagementResponse
28
32
  });
29
33
  module.exports = __toCommonJS(client_exports);
30
34
  var import_react = require("react");
35
+
36
+ // package.json
37
+ var version = "0.4.0";
38
+
39
+ // src/client.jsx
31
40
  var import_jsx_runtime = require("react/jsx-runtime");
32
41
  var name = "dsh-multi-router-client";
33
42
  var inject = ["slots"];
34
43
  var ENDPOINT = "/.well-known/dsh-multi-router";
44
+ var backendNeedsRestart = (data) => !!data && data.pluginVersion !== version;
45
+ function RestartGuidance({ data, retry }) {
46
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", role: "alert", children: [
47
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u9700\u8981\u91CD\u65B0\u542F\u52A8 DeepSeek Harness" }),
48
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: data ? `\u9762\u677F\u7248\u672C ${version}\uFF0C\u540E\u53F0\u7248\u672C ${data.pluginVersion || "\u65E7\u7248"}\u3002\u66F4\u65B0\u540E\u7684\u540E\u53F0\u5C1A\u672A\u91CD\u65B0\u52A0\u8F7D\u3002` : "\u63D2\u4EF6\u540E\u53F0\u5C1A\u672A\u542F\u52A8\u3002\u82E5\u521A\u5B89\u88C5\u6216\u66F4\u65B0\u63D2\u4EF6\uFF0C\u8BF7\u5B8C\u6210\u4E0B\u9762\u7684\u91CD\u542F\u6B65\u9AA4\u3002" }),
49
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { children: [
50
+ "macOS\uFF1A\u9876\u90E8\u83DC\u5355\u300CDeepSeek Harness \u2192 \u9000\u51FA DeepSeek Harness\u300D\uFF08\u2318Q\uFF09\uFF0C\u518D\u91CD\u65B0\u6253\u5F00\u5E94\u7528\u3002",
51
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
52
+ "Windows\uFF1A\u9000\u51FA\u6258\u76D8\u4E2D\u7684 DeepSeek Harness\uFF0C\u518D\u91CD\u65B0\u6253\u5F00\u3002",
53
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
54
+ "\u7F51\u9875\u7248\uFF1A\u91CD\u542F\u8FD0\u884C DSH \u7684\u670D\u52A1\u8FDB\u7A0B\u3002"
55
+ ] }),
56
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5173\u95ED\u7A97\u53E3\u6216\u5237\u65B0\u9762\u677F\u4E0D\u4F1A\u91CD\u65B0\u52A0\u8F7D\u540E\u53F0\u3002\u91CD\u542F\u540E\u4F1A\u4FDD\u7559\u8D26\u53F7\u3001\u8DEF\u7531\u548C\u7528\u91CF\uFF1B\u5982\u4ECD\u63D0\u793A\u5F02\u5E38\uFF0C\u8BF7\u67E5\u770B\u4E0B\u65B9\u7EC4\u4EF6\u7684\u542F\u7528\u9519\u8BEF\u3002" }),
57
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: retry, children: "\u6211\u5DF2\u91CD\u542F\uFF0C\u91CD\u65B0\u68C0\u67E5" }) })
58
+ ] });
59
+ }
35
60
  async function readManagementResponse(res) {
36
61
  let next;
37
62
  try {
@@ -119,8 +144,19 @@ function RouterPage({ view = "page" }) {
119
144
  }, 15e3);
120
145
  return () => clearInterval(timer);
121
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]);
122
158
  async function act(action) {
123
- if (busy) return false;
159
+ if (busy || backendNeedsRestart(data)) return false;
124
160
  setBusy(true);
125
161
  setError("");
126
162
  setNotice("");
@@ -129,7 +165,7 @@ function RouterPage({ view = "page" }) {
129
165
  const next = await readManagementResponse(res);
130
166
  const { exported, ...state } = next;
131
167
  setData(state);
132
- setNotice(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");
133
169
  return next;
134
170
  } catch (e) {
135
171
  setError(e.message);
@@ -172,31 +208,40 @@ function RouterPage({ view = "page" }) {
172
208
  }, children: "\u5237\u65B0\u9762\u677F" })
173
209
  ] })
174
210
  ] }),
175
- /* @__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: () => {
176
212
  setTab(key);
177
213
  setError("");
178
214
  setNotice("");
179
215
  }, children: label }, key)) }),
180
216
  !draft && !accountModal && !presetModal && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error, notice }),
181
- !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)("div", { className: "stack", "aria-busy": busy, children: [
217
+ (backendNeedsRestart(data) || !data && error) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RestartGuidance, { data, retry: () => {
218
+ void load().catch((e) => setError(e.message));
219
+ } }),
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) }),
182
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 }),
183
224
  tab === "usage" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UsageDetails, { data, busy, act }),
184
225
  tab === "accounts" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack", children: [
185
226
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
186
227
  providerSelect,
187
228
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
229
+ !provider.startsWith("qoder") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
230
+ void act({ action: "accounts.discover", provider });
231
+ }, children: "\u91CD\u65B0\u68C0\u6D4B\u672C\u673A\u767B\u5F55" }),
188
232
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
189
233
  void act({ action: "monitor.refresh", provider });
190
234
  }, children: "\u5237\u65B0\u767B\u5F55\u4E0E\u7528\u91CF" }),
191
235
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: busy, onClick: () => openAccount("add"), children: "\u6DFB\u52A0\u8D26\u53F7" })
192
236
  ] })
193
237
  ] }),
194
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "steps", children: "\u6DFB\u52A0\u8D26\u53F7 \u2192 \u4E00\u952E\u8BFB\u53D6\u672C\u673A\u767B\u5F55\uFF0C\u6216\u624B\u52A8\u586B\u5199\u51ED\u8BC1 \u2192 \u4FDD\u5B58\u5230\u8D26\u53F7\u6C60\u3002\u6BCF\u4E2A\u8D26\u53F7\u72EC\u7ACB\u4FDD\u5B58\uFF0C\u53EF\u968F\u65F6\u8865\u5145\u6216\u66F4\u65B0\u51ED\u8BC1\u3002" }),
195
- !accounts.length && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "box empty", children: [
196
- "\u8FD8\u6CA1\u6709 ",
197
- p?.name,
198
- " \u8D26\u53F7\u3002\u70B9\u51FB\u300C\u6DFB\u52A0\u8D26\u53F7\u300D\u5F00\u59CB\u3002"
199
- ] }),
238
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "steps", children: "WorkBuddy \u4E0E Trae \u542F\u52A8\u65F6\u81EA\u52A8\u8BFB\u53D6\u672C\u673A\u5DF2\u767B\u5F55\u8D26\u53F7\uFF0C\u6BCF\u5206\u949F\u91CD\u65B0\u68C0\u6D4B\uFF1BTrae \u81EA\u52A8\u8BC6\u522B CN\u3001Global \u4E0E SOLO\u3002\u4E5F\u53EF\u6DFB\u52A0\u624B\u52A8\u51ED\u8BC1\u6216\u5BFC\u5165\u5176\u5B83\u8BBE\u5907\u8D26\u53F7\u3002\u5404\u8D26\u53F7\u4FDD\u7559\u72EC\u7ACB\u526F\u672C\u3002" }),
239
+ data.localDiscovery?.filter((s) => s.provider === provider).map((s) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
240
+ s.state === "found" ? "\u5DF2\u53D1\u73B0\u672C\u673A\u5BA2\u6237\u7AEF\u767B\u5F55\u3002" : s.state === "unreadable" ? "\u672C\u673A\u767B\u5F55\u6587\u4EF6\u65E0\u6CD5\u8BFB\u53D6\u3002\u8BF7\u5728\u5B98\u65B9\u5BA2\u6237\u7AEF\u91CD\u65B0\u767B\u5F55\u540E\u91CD\u8BD5\uFF0C\u6216\u5728\u300C\u6DFB\u52A0\u8D26\u53F7\u300D\u4E2D\u624B\u52A8\u586B\u5199\u51ED\u8BC1\u3002" : "\u672A\u627E\u5230\u672C\u673A\u5DF2\u767B\u5F55\u8D26\u53F7\u3002\u8BF7\u5148\u5B89\u88C5\u5E76\u767B\u5F55\u5BF9\u5E94\u533A\u57DF\u7684\u5B98\u65B9\u5BA2\u6237\u7AEF\uFF0C\u7136\u540E\u91CD\u65B0\u68C0\u6D4B\u3002",
241
+ " \xB7 ",
242
+ when(s.checkedAt)
243
+ ] }, s.provider)),
244
+ !accounts.length && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "box empty", children: provider.startsWith("qoder") ? "Qoder \u9700\u8981\u6DFB\u52A0 PAT\uFF0C\u6216\u8BFB\u53D6\u539F\u8FDE\u63A5\u5668\u5DF2\u4FDD\u5B58\u7684 PAT\u3002" : `\u8FD8\u6CA1\u6709 ${p?.name} \u8D26\u53F7\u3002\u767B\u5F55\u5B98\u65B9\u5BA2\u6237\u7AEF\u540E\u4F1A\u81EA\u52A8\u68C0\u6D4B\uFF0C\u4E5F\u53EF\u70B9\u51FB\u300C\u6DFB\u52A0\u8D26\u53F7\u300D\u624B\u52A8\u5BFC\u5165\u3002` }),
200
245
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid", children: accounts.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
201
246
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
202
247
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
@@ -501,15 +546,16 @@ function Overview({ data, live, setLive, busy, act, go }) {
501
546
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", children: [
502
547
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u5FEB\u901F\u5F00\u59CB" }),
503
548
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "notice", children: [
504
- "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",
505
550
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
506
- "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",
507
552
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
508
- "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"
509
554
  ] }),
510
555
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
511
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => go("accounts"), children: "\u6DFB\u52A0\u8D26\u53F7" }),
512
- /* @__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" })
513
559
  ] })
514
560
  ] })
515
561
  ] }),
@@ -821,7 +867,7 @@ function CredentialTransfer({ account, busy, act }) {
821
867
  function CredentialForm({ modal, provider, data, busy, act, close, error, notice }) {
822
868
  const replacing = modal.mode === "credentials";
823
869
  const [selected, setSelected] = (0, import_react.useState)(modal.account?.provider || provider), [mode, setMode] = (0, import_react.useState)("client"), [localError, setLocalError] = (0, import_react.useState)(""), [json, setJson] = (0, import_react.useState)("");
824
- const [edition, setEdition] = (0, import_react.useState)(modal.account?.login?.edition || (selected === "trae-global" ? "sg" : "cn"));
870
+ const [edition, setEdition] = (0, import_react.useState)(modal.account?.login?.edition || "auto");
825
871
  const isTrae = selected.startsWith("trae"), isQoder = selected.startsWith("qoder"), global = selected === "trae-global" || selected === "workbuddy-ai" || selected === "qoder-global";
826
872
  const field = (label, name2, type = "text", required = true, value) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
827
873
  label,
@@ -889,7 +935,7 @@ function CredentialForm({ modal, provider, data, busy, act, close, error, notice
889
935
  "\u4F9B\u5E94\u5546 / \u533A\u57DF",
890
936
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { disabled: busy || replacing, value: selected, onChange: (e) => {
891
937
  setSelected(e.target.value);
892
- setEdition(e.target.value === "trae-global" ? "sg" : "cn");
938
+ setEdition("auto");
893
939
  setJson("");
894
940
  setLocalError("");
895
941
  }, children: data.providers.map((p) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: p.id, children: p.name }, p.id)) })
@@ -897,13 +943,14 @@ function CredentialForm({ modal, provider, data, busy, act, close, error, notice
897
943
  field("\u8D26\u53F7\u540D\u79F0\uFF08\u53EF\u9009\uFF09", "name", "text", false, modal.account?.name),
898
944
  isTrae && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
899
945
  "\u767B\u5F55\u7684\u5BA2\u6237\u7AEF",
900
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { value: edition, disabled: busy, onChange: (e) => setEdition(e.target.value), children: (global ? [["sg", "Trae Global"], ["solo-sg", "TRAE SOLO Global"]] : [["cn", "Trae CN"], ["solo", "TRAE SOLO CN"]]).map(([id, label]) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: id, children: label }, id)) })
946
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { value: edition, disabled: busy, onChange: (e) => setEdition(e.target.value), children: (mode === "client" ? [["auto", "\u81EA\u52A8\u8BC6\u522B\uFF08\u63A8\u8350\uFF09"], ...global ? [["sg", "Trae Global"], ["solo-sg", "TRAE SOLO Global"]] : [["cn", "Trae CN"], ["solo", "TRAE SOLO CN"]]] : global ? [["sg", "Trae Global"], ["solo-sg", "TRAE SOLO Global"]] : [["cn", "Trae CN"], ["solo", "TRAE SOLO CN"]]).map(([id, label]) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: id, children: label }, id)) })
901
947
  ] })
902
948
  ] }),
903
949
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
904
950
  "\u51ED\u8BC1\u6DFB\u52A0\u65B9\u5F0F",
905
951
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { disabled: busy, value: mode, onChange: (e) => {
906
952
  setMode(e.target.value);
953
+ if (e.target.value !== "client" && edition === "auto") setEdition(global ? "sg" : "cn");
907
954
  setJson("");
908
955
  setLocalError("");
909
956
  }, children: [
@@ -1367,5 +1414,209 @@ function RouteForm({ draft, setDraft, data, act, busy, error, notice }) {
1367
1414
  ] })
1368
1415
  ] });
1369
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
+ }
1370
1621
  return module.exports; } });
1371
1622
  //# sourceMappingURL=client.js.map