dsh-multi-router 0.5.6 → 0.5.7

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
@@ -35,33 +35,40 @@ __export(client_exports, {
35
35
  name: () => name,
36
36
  performanceSummary: () => performanceSummary,
37
37
  readManagementResponse: () => readManagementResponse,
38
+ requestPluginReload: () => requestPluginReload,
38
39
  usageDateBounds: () => usageDateBounds
39
40
  });
40
41
  module.exports = __toCommonJS(client_exports);
41
42
  var import_react = require("react");
42
43
 
43
44
  // package.json
44
- var version = "0.5.6";
45
+ var version = "0.5.7";
45
46
 
46
47
  // src/client.jsx
47
48
  var import_jsx_runtime = require("react/jsx-runtime");
48
49
  var name = "dsh-multi-router-client";
49
50
  var inject = ["slots"];
50
51
  var ENDPOINT = "/.well-known/dsh-multi-router";
52
+ var reloadFromHost;
53
+ async function requestPluginReload(remote) {
54
+ if (!remote?.pluginManager?.setBundleEnabled) throw Error("\u5F53\u524D DSH \u672A\u63D0\u4F9B\u91CD\u65B0\u52A0\u8F7D\u63A5\u53E3\uFF0C\u8BF7\u5347\u7EA7 DSH \u6216\u5728\u63D2\u4EF6\u9875\u5173\u95ED\u540E\u91CD\u65B0\u542F\u7528\u672C\u63D2\u4EF6\u3002");
55
+ const answer = await remote.pluginManager.setBundleEnabled("dsh-multi-router", true);
56
+ const result = answer?.ok === true ? answer.value : answer;
57
+ if (answer?.ok === false || result?.application !== "applied") throw Error("DSH \u672A\u80FD\u5373\u65F6\u91CD\u8F7D\uFF0C\u8BF7\u68C0\u67E5\u7EC4\u4EF6\u9519\u8BEF\uFF1B\u4E0D\u652F\u6301\u70ED\u52A0\u8F7D\u7684\u65E7\u7248 DSH \u4ECD\u9700\u91CD\u542F\u3002");
58
+ }
51
59
  var backendNeedsRestart = (data) => !!data && data.pluginVersion !== version;
52
- function RestartGuidance({ data, retry }) {
60
+ function RestartGuidance({ data, retry, reload, busy }) {
53
61
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", role: "alert", children: [
54
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u9700\u8981\u91CD\u65B0\u542F\u52A8 DeepSeek Harness" }),
55
- /* @__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" }),
56
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { children: [
57
- "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",
58
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
59
- "Windows\uFF1A\u9000\u51FA\u6258\u76D8\u4E2D\u7684 DeepSeek Harness\uFF0C\u518D\u91CD\u65B0\u6253\u5F00\u3002",
60
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
61
- "\u7F51\u9875\u7248\uFF1A\u91CD\u542F\u8FD0\u884C DSH \u7684\u670D\u52A1\u8FDB\u7A0B\u3002"
62
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u63D2\u4EF6\u6B63\u5728\u8FDE\u63A5\u6216\u540C\u6B65\u7248\u672C" }),
63
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: data ? `\u9762\u677F v${version}\uFF0C\u8FD0\u884C\u4E2D\u7684\u540E\u53F0 v${data.pluginVersion || "\u65E7\u7248"}\u3002\u6B63\u5728\u7B49\u5F85 DSH \u540C\u6B65\u65B0\u7248\u672C\u3002` : "\u6682\u65F6\u65E0\u6CD5\u8FDE\u63A5\u63D2\u4EF6\u540E\u53F0\u3002\u5B89\u88C5\u6216\u66F4\u65B0\u540E\u4F1A\u81EA\u52A8\u91CD\u8BD5\uFF0C\u4E5F\u53EF\u4EE5\u53EA\u91CD\u65B0\u52A0\u8F7D\u672C\u63D2\u4EF6\u3002" }),
64
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
65
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: reload, children: "\u91CD\u65B0\u52A0\u8F7D\u63D2\u4EF6" }),
66
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: retry, children: "\u91CD\u65B0\u8FDE\u63A5" })
62
67
  ] }),
63
- /* @__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" }),
64
- /* @__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" }) })
68
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { children: [
69
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "\u4ECD\u65E0\u6CD5\u8FDE\u63A5\uFF1F" }),
70
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u5148\u68C0\u67E5\u4E0B\u65B9\u7EC4\u4EF6\u7684\u542F\u7528\u9519\u8BEF\u3002\u65E7\u7248 DSH \u82E5\u4E0D\u652F\u6301\u8FD0\u884C\u4E2D\u91CD\u8F7D\uFF0C\u53EF\u5347\u7EA7 DSH\uFF0C\u6216\u901A\u8FC7\u300C\u9000\u51FA DeepSeek Harness\u300D\u5B8C\u5168\u9000\u51FA\u540E\u91CD\u65B0\u6253\u5F00\u3002\u5173\u95ED\u7A97\u53E3\u4E0D\u7B49\u4E8E\u9000\u51FA\uFF0C\u8D26\u53F7\u3001\u8DEF\u7531\u4E0E\u7528\u91CF\u4F1A\u4FDD\u7559\u3002" })
71
+ ] })
65
72
  ] });
66
73
  }
67
74
  async function readManagementResponse(res) {
@@ -69,7 +76,7 @@ async function readManagementResponse(res) {
69
76
  try {
70
77
  next = JSON.parse(await res.text());
71
78
  } catch {
72
- throw Error(`\u63D2\u4EF6\u540E\u53F0\u672A\u5C31\u7EEA\uFF08HTTP ${res.status}\uFF09\u3002\u8BF7\u68C0\u67E5\u63D2\u4EF6\u7EC4\u4EF6\u7684\u542F\u7528\u9519\u8BEF\uFF0C\u66F4\u65B0\u63D2\u4EF6\u540E\u5B8C\u5168\u9000\u51FA\u5E76\u91CD\u542F DSH\u3002`);
79
+ throw Error(`\u63D2\u4EF6\u540E\u53F0\u672A\u5C31\u7EEA\uFF08HTTP ${res.status}\uFF09\u3002\u6B63\u5728\u91CD\u65B0\u8FDE\u63A5\uFF1B\u82E5\u6301\u7EED\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u52A0\u8F7D\u63D2\u4EF6\u5E76\u68C0\u67E5\u7EC4\u4EF6\u9519\u8BEF\u3002`);
73
80
  }
74
81
  if (!next || typeof next !== "object" || Array.isArray(next)) throw Error("\u63D2\u4EF6\u540E\u53F0\u8FD4\u56DE\u4E86\u65E0\u6548\u6570\u636E\uFF0C\u8BF7\u5237\u65B0\u9762\u677F\u6216\u91CD\u542F DSH\u3002");
75
82
  if (!res.ok) throw Error(next.error || `\u64CD\u4F5C\u5931\u8D25\uFF08HTTP ${res.status}\uFF09`);
@@ -109,6 +116,7 @@ var styles = `
109
116
  @media(prefers-reduced-motion:reduce){.mr *{transition:none!important}}
110
117
  `;
111
118
  function apply(ctx) {
119
+ reloadFromHost = () => requestPluginReload(ctx.get?.("remote"));
112
120
  ctx.slots.inject("plugins.bundle.config", () => ctx.slots.register({ name: "plugins.bundle.config", key: "dsh-multi-router" }, RouterPage));
113
121
  ctx.slots.inject("shell.overlay", () => ctx.slots.register({ name: "shell.overlay", key: "dsh-multi-router-updates" }, UpdateReminder));
114
122
  }
@@ -235,33 +243,43 @@ function RouterPage({ view = "page" }) {
235
243
  const [accountProvider, setAccountProvider] = (0, import_react.useState)(""), [provider, setProvider] = (0, import_react.useState)("workbuddy"), [busy, setBusy] = (0, import_react.useState)(false), [live, setLive] = (0, import_react.useState)(true);
236
244
  const [error, setError] = (0, import_react.useState)(""), [notice, setNotice] = (0, import_react.useState)(""), [draft, setDraft] = (0, import_react.useState)(null), [accountModal, setAccountModal] = (0, import_react.useState)(null), [presetModal, setPresetModal] = (0, import_react.useState)(false), [search, setSearch] = (0, import_react.useState)("");
237
245
  const polling = (0, import_react.useRef)(false);
238
- async function load() {
239
- const next = await readManagementResponse(await fetch(ENDPOINT, { cache: "no-store" }));
246
+ async function load(signal = AbortSignal.timeout(8e3)) {
247
+ const next = await readManagementResponse(await fetch(ENDPOINT, { cache: "no-store", signal }));
240
248
  setData(next);
241
249
  setError("");
242
250
  }
243
251
  (0, import_react.useEffect)(() => {
244
- const accountProviderSelect2 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "filter", children: [
245
- "\u4F9B\u5E94\u5546 / \u533A\u57DF",
246
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { value: accountProvider, onChange: (e) => setAccountProvider(e.target.value), children: [
247
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\u5168\u90E8\u4F9B\u5E94\u5546" }),
248
- data?.providers.map((p2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: p2.id, children: p2.name }, p2.id))
249
- ] })
250
- ] });
251
252
  if (view === "summary") return;
252
- void load().catch((e) => setError(e.message));
253
- if (!live) return;
254
- const timer = setInterval(() => {
253
+ let stopped = false, retry, attempts = 0;
254
+ const abort = new AbortController();
255
+ async function connect() {
256
+ try {
257
+ await load(AbortSignal.any([abort.signal, AbortSignal.timeout(4e3)]));
258
+ } catch (e) {
259
+ if (stopped) return;
260
+ if (++attempts < 8) retry = setTimeout(connect, 750);
261
+ else setError(e.message);
262
+ }
263
+ }
264
+ void connect();
265
+ const timer = live && setInterval(() => {
255
266
  if (document.hidden || polling.current) return;
256
267
  polling.current = true;
257
- void load().catch((e) => setError(e.message)).finally(() => {
268
+ void load(abort.signal).catch((e) => {
269
+ if (!stopped) setError(e.message);
270
+ }).finally(() => {
258
271
  polling.current = false;
259
272
  });
260
273
  }, 15e3);
261
- return () => clearInterval(timer);
274
+ return () => {
275
+ stopped = true;
276
+ abort.abort();
277
+ clearTimeout(retry);
278
+ clearInterval(timer);
279
+ };
262
280
  }, [view, live]);
263
281
  (0, import_react.useEffect)(() => {
264
- if (data?.pluginUpdates?.job?.state !== "running" && !data?.checkins?.running) return;
282
+ if (data?.startup?.phase !== "discovering" && !["waiting", "reloading"].includes(data?.runtime?.phase) && data?.pluginUpdates?.job?.state !== "running" && !data?.checkins?.running) return;
265
283
  const timer = setInterval(() => {
266
284
  if (polling.current) return;
267
285
  polling.current = true;
@@ -270,7 +288,20 @@ function RouterPage({ view = "page" }) {
270
288
  });
271
289
  }, 2e3);
272
290
  return () => clearInterval(timer);
273
- }, [data?.pluginUpdates?.job?.state, data?.checkins?.running]);
291
+ }, [data?.startup?.phase, data?.runtime?.phase, data?.pluginUpdates?.job?.state, data?.checkins?.running]);
292
+ async function reload() {
293
+ setBusy(true);
294
+ setError("");
295
+ try {
296
+ if (!reloadFromHost) throw Error("\u8BF7\u5728 DSH \u63D2\u4EF6\u9875\u91CD\u65B0\u542F\u7528\u672C\u63D2\u4EF6\u3002");
297
+ await reloadFromHost();
298
+ await load();
299
+ } catch (e) {
300
+ setError(e.message);
301
+ } finally {
302
+ setBusy(false);
303
+ }
304
+ }
274
305
  async function act(action) {
275
306
  if (busy || backendNeedsRestart(data)) return false;
276
307
  setBusy(true);
@@ -325,9 +356,13 @@ function RouterPage({ view = "page" }) {
325
356
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "muted", children: "\u7BA1\u7406\u4E09\u5BB6\u8D26\u53F7\u3001\u6A21\u578B\u4E0E\u7528\u91CF" })
326
357
  ] }),
327
358
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
359
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "badge", children: [
360
+ "v",
361
+ data?.pluginVersion ?? version
362
+ ] }),
328
363
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "status", children: [
329
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("i", { className: busy ? "warn" : "good", "aria-hidden": "true" }),
330
- busy ? "\u6B63\u5728\u5904\u7406\u2026" : "\u672C\u673A\u8FD0\u884C"
364
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("i", { className: busy || !data ? "warn" : "good", "aria-hidden": "true" }),
365
+ busy ? "\u6B63\u5728\u5904\u7406\u2026" : !data ? "\u6B63\u5728\u8FDE\u63A5\u2026" : "\u672C\u673A\u8FD0\u884C"
331
366
  ] }),
332
367
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
333
368
  void load().catch((e) => setError(e.message));
@@ -340,10 +375,30 @@ function RouterPage({ view = "page" }) {
340
375
  setNotice("");
341
376
  }, children: label }, key)) }),
342
377
  !draft && !accountModal && !presetModal && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Feedback, { error, notice }),
343
- (backendNeedsRestart(data) || !data && error) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RestartGuidance, { data, retry: () => {
378
+ (backendNeedsRestart(data) || !data && error) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RestartGuidance, { data, busy, reload: () => {
379
+ void reload();
380
+ }, retry: () => {
344
381
  void load().catch((e) => setError(e.message));
345
382
  } }),
346
- !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: [
383
+ !data ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", role: "status", "aria-live": "polite", children: [
384
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: error ? "\u7B49\u5F85\u540E\u53F0\u8FDE\u63A5" : "\u6B63\u5728\u8FDE\u63A5\u672C\u673A\u63D2\u4EF6\u2026" }),
385
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: "\u9875\u9762\u4F1A\u81EA\u52A8\u91CD\u65B0\u8FDE\u63A5\u3002\u8D26\u53F7\u53D1\u73B0\u3001\u7528\u91CF\u548C\u6A21\u578B\u76EE\u5F55\u5C06\u5728\u540E\u53F0\u66F4\u65B0\u3002" }),
386
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("progress", { "aria-label": "\u6B63\u5728\u8FDE\u63A5\u63D2\u4EF6\u540E\u53F0" })
387
+ ] }) : /* @__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: [
388
+ data.startup?.phase === "discovering" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "steps", role: "status", children: "\u6B63\u5728\u540E\u53F0\u83B7\u53D6\u672C\u673A\u8D26\u53F7\uFF0C\u5DF2\u6709\u8D26\u53F7\u548C\u8DEF\u7531\u73B0\u5728\u5373\u53EF\u4F7F\u7528\u3002" }),
389
+ data.runtime?.phase && data.runtime.phase !== "current" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "steps", children: [
390
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { children: [
391
+ data.runtime.message,
392
+ "\uFF08\u8FD0\u884C v",
393
+ data.runtime.runningVersion,
394
+ " / \u5DF2\u5B89\u88C5 v",
395
+ data.runtime.installedVersion,
396
+ "\uFF09"
397
+ ] }),
398
+ ["failed", "restart-required"].includes(data.runtime.phase) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
399
+ void reload();
400
+ }, children: "\u91CD\u65B0\u52A0\u8F7D\u63D2\u4EF6" })
401
+ ] }),
347
402
  ["overview", "accounts"].includes(tab) && data.setup?.dismissed !== true && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InitialSetup, { data, busy, act, go: (key) => setTab(key) }),
348
403
  tab === "overview" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Overview, { data, live, setLive, busy, act, go: (key) => setTab(key) }),
349
404
  tab === "plugins" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluginUpdatesPanel, { data: data.pluginUpdates, busy, act }),
@@ -1927,15 +1982,16 @@ function RouteForm({ draft, setDraft, data, act, busy, error, notice }) {
1927
1982
  }
1928
1983
  function InitialSetup({ data, busy, act, go }) {
1929
1984
  const discovery = data.localDiscovery ?? [];
1985
+ const discovering = data.startup?.phase === "discovering";
1930
1986
  const saved = discovery.reduce((n, s) => n + (s.savedCount ?? 0), 0);
1931
1987
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "box stack", "aria-label": "\u9996\u6B21\u8D26\u53F7\u8BBE\u7F6E", children: [
1932
1988
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bar", children: [
1933
1989
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
1934
1990
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", { children: [
1935
1991
  "\u672C\u673A\u8D26\u53F7\u81EA\u52A8\u83B7\u53D6",
1936
- discovery.length ? "\u5DF2\u5B8C\u6210" : "\u5F85\u91CD\u8BD5"
1992
+ discovering ? "\u8FDB\u884C\u4E2D" : discovery.length ? "\u5DF2\u5B8C\u6210" : "\u5F85\u91CD\u8BD5"
1937
1993
  ] }),
1938
- /* @__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" })
1994
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "notice", children: discovering ? "\u6B63\u5728\u540E\u53F0\u8BFB\u53D6 WorkBuddy / Trae \u672C\u673A\u767B\u5F55\uFF0C\u65E0\u9700\u624B\u52A8\u91CD\u590D\u83B7\u53D6\uFF0C\u5DF2\u6709\u8D26\u53F7\u53EF\u4EE5\u7EE7\u7EED\u4F7F\u7528\u3002" : 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" })
1939
1995
  ] }),
1940
1996
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => {
1941
1997
  void act({ action: "setup.dismiss" });
@@ -1946,7 +2002,7 @@ function InitialSetup({ data, busy, act, go }) {
1946
2002
  /* @__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" })
1947
2003
  ] }, s.provider)) }),
1948
2004
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "row", children: [
1949
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: busy, onClick: () => {
2005
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "primary", disabled: busy || discovering, onClick: () => {
1950
2006
  void act({ action: "accounts.discover" });
1951
2007
  }, children: "\u4E00\u952E\u83B7\u53D6\u5E76\u4FDD\u5B58 WorkBuddy / Trae" }),
1952
2008
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { disabled: busy, onClick: () => go("accounts"), children: "\u67E5\u770B\u8D26\u53F7 / \u624B\u52A8\u6DFB\u52A0" }),