dsh-git-branch-manage 1.0.3 → 1.0.5

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
@@ -44,6 +44,36 @@ window.__ModuleLoader__.load({
44
44
  if (/(^|\/)[^/]+\.lock($|\/)/.test(name)) return "illegal";
45
45
  return null;
46
46
  }
47
+ /**
48
+ * Shipped default for the cn-accelerate mirror prefix (the design doc's
49
+ * `cnAccelerateUrl` default and the popover's「恢复默认」target).
50
+ */
51
+ const ACCEL_DEFAULT_URL = "https://gh-proxy.com/";
52
+ /**
53
+ * Pre-flight check of the cn-accelerate prefix against what the rewrite can
54
+ * actually use: non-empty after trim, `http://` or `https://` scheme, and no
55
+ * whitespace anywhere (a space would break the `url.<base>.insteadOf=<target>`
56
+ * git config value and smuggle a second argument).
57
+ * @param value - raw draft text.
58
+ * @returns the issue kind, or undefined when the value is acceptable.
59
+ */
60
+ function accelerateUrlError(value) {
61
+ const trimmed = value.trim();
62
+ if (trimmed === "") return "empty";
63
+ if (/\s/.test(trimmed)) return "invalid";
64
+ if (!trimmed.startsWith("http://") && !trimmed.startsWith("https://")) return "invalid";
65
+ }
66
+ /**
67
+ * Normalize an accepted accelerate URL: trim, and append the trailing `/`
68
+ * the prefix concatenation requires (`https://gh-proxy.com/` + `o/r.git`
69
+ * must stay one valid URL). Callers pass the result to `url.<base>.insteadOf`.
70
+ * @param value - an accepted (non-empty, http(s), whitespace-free) URL.
71
+ * @returns the prefix ending in `/`.
72
+ */
73
+ function normalizeAccelerateUrl(value) {
74
+ const trimmed = value.trim();
75
+ return trimmed.endsWith("/") ? trimmed : `${trimmed}/`;
76
+ }
47
77
  //#endregion
48
78
  //#region src/wire.ts
49
79
  /**
@@ -391,6 +421,21 @@ window.__ModuleLoader__.load({
391
421
  return post(ROUTE_AI_COMMIT_MESSAGE, body);
392
422
  }
393
423
  //#endregion
424
+ //#region src/client/git-events.ts
425
+ const listeners = /* @__PURE__ */ new Set();
426
+ /** Announce that a surface changed repository state (checkout, rename,
427
+ * delete, create, commit, fetch, update, push). */
428
+ function emitGitMutated() {
429
+ for (const listener of [...listeners]) listener();
430
+ }
431
+ /** Subscribe; returns the unsubscribe function. */
432
+ function onGitMutated(listener) {
433
+ listeners.add(listener);
434
+ return () => {
435
+ listeners.delete(listener);
436
+ };
437
+ }
438
+ //#endregion
394
439
  //#region src/client/branch-tree.ts
395
440
  /** Whether a bare `git push` has a known upstream and local commits ahead. */
396
441
  function hasPushableCommits(rows, currentBranch) {
@@ -2735,6 +2780,12 @@ window.__ModuleLoader__.load({
2735
2780
  document.removeEventListener("visibilitychange", onVisibility);
2736
2781
  };
2737
2782
  }, [refresh]);
2783
+ (0, react.useEffect)(() => {
2784
+ return onGitMutated(() => {
2785
+ if (busyRef.current) return;
2786
+ refresh();
2787
+ });
2788
+ }, [refresh]);
2738
2789
  const showError = (0, react.useCallback)((message) => {
2739
2790
  pushToast(t("errorGeneric", { message }));
2740
2791
  }, [pushToast, t]);
@@ -2756,6 +2807,7 @@ window.__ModuleLoader__.load({
2756
2807
  setConfirm(null);
2757
2808
  if (!keepOpen) setMenuOpen(false);
2758
2809
  onSettled?.();
2810
+ emitGitMutated();
2759
2811
  }, [showError]);
2760
2812
  /** In-place switch flow: POST /switch, then refetch the status. */
2761
2813
  const doSwitch = (0, react.useCallback)((branch, keepOpen = false) => runGuarded(async () => {
@@ -3379,6 +3431,151 @@ window.__ModuleLoader__.load({
3379
3431
  }
3380
3432
  };
3381
3433
  //#endregion
3434
+ //#region src/client/accel-form.ts
3435
+ /** The fields this form edits. */
3436
+ const ACCEL_ENABLED_FIELD = "cnAccelerate";
3437
+ const ACCEL_URL_FIELD = "cnAccelerateUrl";
3438
+ /**
3439
+ * Stages the cn-accelerate edits over the `dsh-git-branch` Host entry.
3440
+ *
3441
+ * Publishes through a snapshot store like {@link CardForm}: the consumer
3442
+ * reads through a snapshot selector while the scope and the local drafts
3443
+ * change underneath; every projection is rebuilt from the two together.
3444
+ */
3445
+ var AccelForm = class {
3446
+ scope;
3447
+ snapshotValue;
3448
+ listeners = /* @__PURE__ */ new Set();
3449
+ enabledDraft;
3450
+ urlDraft;
3451
+ saving = false;
3452
+ failed = false;
3453
+ /**
3454
+ * @param scope - the bound configuration form for the `dsh-git-branch` Host entry.
3455
+ */
3456
+ constructor(scope) {
3457
+ this.scope = scope;
3458
+ this.snapshotValue = this.project();
3459
+ scope.subscribe(() => {
3460
+ this.publish();
3461
+ });
3462
+ }
3463
+ /** @returns the store a consumer reads through its bound selector. */
3464
+ bind() {
3465
+ return {
3466
+ getSnapshot: () => this.snapshotValue,
3467
+ subscribe: (listener) => {
3468
+ this.listeners.add(listener);
3469
+ return () => {
3470
+ this.listeners.delete(listener);
3471
+ };
3472
+ },
3473
+ set: (next) => {
3474
+ this.store(next);
3475
+ }
3476
+ };
3477
+ }
3478
+ /** @returns the stage, restore, save, and discard actions bound to this form. */
3479
+ actions() {
3480
+ return {
3481
+ setAccelEnabled: (value) => {
3482
+ this.enabledDraft = value;
3483
+ this.failed = false;
3484
+ this.publish();
3485
+ },
3486
+ editAccelUrl: (text) => {
3487
+ this.urlDraft = text;
3488
+ this.failed = false;
3489
+ this.publish();
3490
+ },
3491
+ restoreAccelDefault: () => {
3492
+ this.urlDraft = ACCEL_DEFAULT_URL;
3493
+ this.failed = false;
3494
+ this.publish();
3495
+ },
3496
+ saveAccel: () => this.save(),
3497
+ discardAccel: () => {
3498
+ if (this.enabledDraft === void 0 && this.urlDraft === void 0 && !this.failed) return;
3499
+ this.enabledDraft = void 0;
3500
+ this.urlDraft = void 0;
3501
+ this.failed = false;
3502
+ this.publish();
3503
+ }
3504
+ };
3505
+ }
3506
+ /** The URL as the user sees it: the live draft, else the stored value over
3507
+ * the shipped default. */
3508
+ effectiveUrlText() {
3509
+ const value = this.scope.getSnapshot().value?.[ACCEL_URL_FIELD];
3510
+ return this.urlDraft ?? value ?? "https://gh-proxy.com/";
3511
+ }
3512
+ /**
3513
+ * Write the switch and the normalized URL TOGETHER, then re-seed from what
3514
+ * the Host accepted. The URL is validated first — an unusable draft blocks
3515
+ * the save (and the surfaces disable the button on the same error), so the
3516
+ * switch can never land alone against a mirror the user has not confirmed.
3517
+ * A save that did not land keeps its drafts so the user can correct them.
3518
+ */
3519
+ async save() {
3520
+ if (this.enabledDraft === void 0 && this.urlDraft === void 0 || this.saving) return;
3521
+ const urlText = this.effectiveUrlText();
3522
+ if (accelerateUrlError(urlText) !== void 0) return;
3523
+ const intendedEnabled = this.enabledDraft ?? this.scope.getSnapshot().value?.["cnAccelerate"] ?? false;
3524
+ const intendedUrl = normalizeAccelerateUrl(urlText);
3525
+ this.saving = true;
3526
+ this.failed = false;
3527
+ this.publish();
3528
+ let landed = true;
3529
+ try {
3530
+ await this.scope.set(ACCEL_ENABLED_FIELD, intendedEnabled);
3531
+ await this.scope.set(ACCEL_URL_FIELD, intendedUrl);
3532
+ const user = this.userLayer();
3533
+ if (user?.["cnAccelerate"] !== intendedEnabled || user?.["cnAccelerateUrl"] !== intendedUrl) landed = false;
3534
+ } catch (_settingsWriteFailure) {
3535
+ landed = false;
3536
+ }
3537
+ if (landed) {
3538
+ this.enabledDraft = void 0;
3539
+ this.urlDraft = void 0;
3540
+ }
3541
+ this.saving = false;
3542
+ this.failed = !landed;
3543
+ this.publish();
3544
+ }
3545
+ /** The raw user layer narrowed to a record; the wire answer is `unknown`. */
3546
+ userLayer() {
3547
+ const user = this.scope.getSnapshot().user;
3548
+ return typeof user === "object" && user !== null ? user : void 0;
3549
+ }
3550
+ project() {
3551
+ const snapshot = this.scope.getSnapshot();
3552
+ const storedEnabled = snapshot.value?.["cnAccelerate"] ?? false;
3553
+ const storedUrl = snapshot.value?.["cnAccelerateUrl"] ?? "https://gh-proxy.com/";
3554
+ const urlText = this.effectiveUrlText();
3555
+ const enabledDirty = this.enabledDraft !== void 0 && this.enabledDraft !== storedEnabled;
3556
+ const urlDirty = this.urlDraft !== void 0 && this.urlDraft !== storedUrl;
3557
+ return {
3558
+ available: snapshot.status === "ready",
3559
+ writable: snapshot.writable,
3560
+ enabled: this.enabledDraft ?? storedEnabled,
3561
+ urlText,
3562
+ dirty: enabledDirty || urlDirty,
3563
+ saving: this.saving,
3564
+ failed: this.failed,
3565
+ urlError: accelerateUrlError(urlText) ?? null
3566
+ };
3567
+ }
3568
+ /** Replace the snapshot reference and notify, only when the fact moved. */
3569
+ store(next) {
3570
+ if (next === this.snapshotValue) return;
3571
+ this.snapshotValue = next;
3572
+ for (const listener of this.listeners) listener();
3573
+ }
3574
+ publish() {
3575
+ this.store(this.project());
3576
+ }
3577
+ };
3578
+ //#endregion
3382
3579
  //#region src/client/git-panel-data.ts
3383
3580
  /**
3384
3581
  * Classify raw %D decoration segments: `HEAD -> main` (and bare `HEAD`) is
@@ -3459,6 +3656,17 @@ window.__ModuleLoader__.load({
3459
3656
  if (needle === "") return [...commits];
3460
3657
  return commits.filter((commit) => commit.subject.toLowerCase().includes(needle) || commit.authorName.toLowerCase().includes(needle));
3461
3658
  }
3659
+ /**
3660
+ * Case-insensitive substring filter over the branch name — the branch card's
3661
+ * head search box. A remote row matches on its full `remote/name`, which
3662
+ * contains the prefix-stripped short name the tree renders, so searching what
3663
+ * the user sees and searching the remote prefix both hit.
3664
+ */
3665
+ function filterBranches(rows, query) {
3666
+ const needle = query.trim().toLowerCase();
3667
+ if (needle === "") return [...rows];
3668
+ return rows.filter((row) => row.name.toLowerCase().includes(needle));
3669
+ }
3462
3670
  /** Merge the next page into the accumulated list, dropping hash duplicates
3463
3671
  * (a ref moved between fetches must not duplicate rows). */
3464
3672
  function appendPage(current, page) {
@@ -3520,9 +3728,19 @@ window.__ModuleLoader__.load({
3520
3728
  branches
3521
3729
  })).sort((left, right) => left.remote.localeCompare(right.remote));
3522
3730
  }
3731
+ /** Every group key the branch tree renders — the collapse-all target set.
3732
+ * The bare `remote` key folds the whole remote tree; the nested
3733
+ * `remote:<name>` keys matter only for the groups it re-opens. */
3734
+ function branchGroupKeys(remotes) {
3735
+ return [
3736
+ "local",
3737
+ "remote",
3738
+ ...groupRemotes(remotes).map((group) => `remote:${group.remote}`)
3739
+ ];
3740
+ }
3523
3741
  //#endregion
3524
3742
  //#region \0git-worktree-css:/home/runner/work/dsh-git-branch/dsh-git-branch/src/client/GitHistoryPanel.module.css?inline
3525
- const css$2 = "/* Git panel (sidebar global panel). Three stacked sections over the main\n * column: uncommitted changes + commit box, branches, commit history. Host\n * tokens only; the few status colors fall back to the same literals the\n * settings card uses. */\n\n.page_427795137 {\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n}\n\n.topbar_427795137 {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 16px 8px;\n}\n\n.back_427795137 {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n border: 0;\n background: none;\n cursor: pointer;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary);\n padding: 4px 8px;\n border-radius: 8px;\n}\n\n.back_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.title_427795137 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n.repoPill_427795137 {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n font-size: 12px;\n line-height: 1.4;\n color: var(--dsw-alias-label-secondary);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 999px;\n padding: 3px 10px;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.repoName_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.branchName_427795137 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n.track_427795137 {\n font-variant-numeric: tabular-nums;\n}\n\n.topbarActions_427795137 {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n flex: none;\n}\n\n.refreshBtn_427795137 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 0;\n border-radius: 8px;\n background: none;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n.refreshBtn_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.refreshBtn_427795137[disabled] {\n opacity: 0.5;\n cursor: default;\n}\n\n.scroll_427795137 {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 0 16px 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n/* Sections NEVER flex-shrink: the scroll container is a definite-height\n * flex column, and a shrinkable child collapses to a fraction of its\n * content while the overflow paints over the following sections (the\n * branch section went empty and the commit box drifted into the history).\n * Natural heights; the container scrolls as a whole. */\n.section_427795137 {\n flex: none;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-2);\n display: flex;\n flex-direction: column;\n}\n\n.sectionHead_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.sectionTitle_427795137 {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n.countBadge_427795137 {\n font-size: 10px;\n line-height: 1;\n border-radius: 999px;\n padding: 3px 7px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-secondary);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.sectionTools_427795137 {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.sectionBody_427795137 {\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* Small action chip used across the section heads and the commit row. */\n.act_427795137 {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n cursor: pointer;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 7px;\n padding: 4px 10px;\n white-space: nowrap;\n}\n\n.act_427795137:hover:not([disabled]) {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.act_427795137[disabled] {\n opacity: 0.45;\n cursor: default;\n}\n\n.actPrimary_427795137 {\n /* Hardcoded blue by request — the brand token does not resolve reliably\n * inside the better-sidebar panel. */\n background: #4c6bf5;\n border-color: transparent;\n color: #fff;\n}\n\n.actPrimary_427795137:hover:not([disabled]) {\n border-color: transparent;\n filter: brightness(1.06);\n}\n\n/* Uncommitted changes */\n\n.groupTitleRow_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.linkBtn_427795137 {\n margin-left: auto;\n background: none;\n border: 0;\n padding: 2px 4px;\n font: inherit;\n font-size: 12px;\n color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n border-radius: 5px;\n}\n\n.linkBtn_427795137:hover:not([disabled]) {\n text-decoration: underline;\n}\n\n.linkBtn_427795137[disabled] {\n opacity: 0.5;\n cursor: default;\n}\n\n.changeRow_427795137 {\n display: grid;\n grid-template-columns: 16px 18px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 3px 6px;\n border-radius: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.changeRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.changeCheck_427795137 {\n width: 14px;\n height: 14px;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n margin: 0;\n}\n\n.statusBadge_427795137 {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n font-size: 10px;\n line-height: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n color: #fff;\n box-sizing: border-box;\n}\n\n.statusA_427795137 { background: var(--dsw-alias-status-success, #218358); }\n.statusM_427795137 { background: var(--dsw-alias-label-warning, #b07000); }\n.statusD_427795137 { background: var(--dsw-alias-status-danger, #d5304f); }\n.statusR_427795137 { background: #8350d8; }\n.statusC_427795137 { background: #8350d8; }\n.statusT_427795137 { background: #5b7a9d; }\n.statusQ_427795137 { background: var(--dsw-alias-label-dimmed, #9aa0aa); }\n.statusU_427795137 { background: #d5502e; }\n\n.changePath_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: ui-monospace, Consolas, monospace;\n font-size: 11.5px;\n direction: rtl;\n text-align: left;\n}\n\n.stageHint_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n flex: none;\n}\n\n.commitBox_427795137 {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 4px;\n}\n\n.commitInput_427795137 {\n width: 100%;\n box-sizing: border-box;\n resize: vertical;\n min-height: 52px;\n font: inherit;\n font-size: 12.5px;\n line-height: 1.5;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n padding: 7px 10px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n outline: none;\n}\n\n.commitInput_427795137:focus {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.commitActions_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.commitHint_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n min-height: 16px;\n}\n\n.split_427795137 {\n margin-left: auto;\n display: flex;\n position: relative;\n}\n\n.splitMain_427795137 {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n padding: 6px 16px;\n font-size: 13px;\n}\n\n.splitCaret_427795137 {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n margin-left: 1px;\n padding: 6px 6px;\n}\n\n.menu_427795137 {\n position: absolute;\n right: 0;\n top: calc(100% + 4px);\n z-index: 40;\n width: max-content;\n min-width: 0;\n background: var(--dsw-alias-surface-raised, var(--dsw-alias-bg-layer-3));\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n box-shadow: var(--dsw-shadow-lv3);\n backdrop-filter: var(--dsw-menu-backdrop-filter);\n padding: 3px;\n display: flex;\n flex-direction: column;\n}\n\n.menuItem_427795137 {\n display: block;\n width: 100%;\n text-align: left;\n background: none;\n border: 0;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n padding: 5px 10px;\n border-radius: 5px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.menuItem_427795137:hover:not([disabled]) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.menuItem_427795137[disabled] {\n opacity: 0.5;\n cursor: default;\n}\n\n.menuSub_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n margin-top: 1px;\n}\n\n/* Branch section — two IDEA-style trees: 本地 → branches, 远程 → per-remote → branches */\n\n.treeHead_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 6px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-label-secondary);\n user-select: none;\n}\n\n.treeHead_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.treeChevron_427795137 {\n display: inline-flex;\n align-items: center;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.treeChildren_427795137 {\n display: flex;\n flex-direction: column;\n margin-left: 12px;\n}\n\n.treeHeadNest_427795137 {\n font-weight: 400;\n}\n\n.treeNest_427795137 {\n margin-left: 12px;\n}\n\n.branchRow_427795137 {\n display: grid;\n grid-template-columns: 20px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 5px 8px;\n border-radius: 7px;\n cursor: pointer;\n font-size: 12.5px;\n color: var(--dsw-alias-label-primary);\n}\n\n.branchRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.branchRowCurrent_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n cursor: default;\n}\n\n.branchRowCurrent_427795137:hover {\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.branchMark_427795137 {\n color: var(--dsw-alias-brand-primary);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.branchName_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: 500;\n}\n\n.branchKind_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n margin-left: 6px;\n}\n\n.branchTrack_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n font-variant-numeric: tabular-nums;\n flex: none;\n}\n\n/* The branch action menu is portaled; fixed positioning by row rect. */\n.floatMenu_427795137 {\n position: fixed;\n z-index: 60;\n min-width: 190px;\n}\n\n.menuHead_427795137 {\n padding: 6px 10px 5px;\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n margin-bottom: 3px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.menuHeadStrong_427795137 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n.menuDanger_427795137 {\n color: var(--dsw-alias-status-danger, #d5304f);\n}\n\n.formField_427795137 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.formLabel_427795137 {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.formInput_427795137 {\n font: inherit;\n font-size: 13px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n padding: 7px 10px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n outline: none;\n}\n\n.formInput_427795137:focus {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.formError_427795137 {\n font-size: 12px;\n color: var(--dsw-alias-status-danger, #d5304f);\n min-height: 16px;\n}\n\n/* Commit history */\n\n.historyHead_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.searchBox_427795137 {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n flex: 1;\n max-width: 300px;\n min-width: 140px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 7px;\n padding: 0 9px;\n height: 28px;\n color: var(--dsw-alias-label-tertiary);\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.searchInput_427795137 {\n flex: 1;\n min-width: 0;\n border: 0;\n background: none;\n outline: none;\n font: inherit;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.searchInput_427795137::placeholder {\n color: var(--dsw-alias-label-tertiary);\n}\n\n.commitRow_427795137 {\n position: relative;\n display: grid;\n grid-template-columns: 22px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 6px 8px 6px 2px;\n cursor: pointer;\n border-radius: 7px;\n}\n\n.commitRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.commitRowOpen_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.commitRowOpen_427795137:hover {\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.commitGraph_427795137 {\n position: relative;\n align-self: stretch;\n min-height: 34px;\n}\n\n.commitGraph_427795137::before {\n content: \"\";\n position: absolute;\n left: 10px;\n top: 0;\n bottom: 0;\n width: 2px;\n background: var(--dsw-alias-border-l2);\n}\n\n.commitRowFirst_427795137 .commitGraph_427795137::before {\n top: 50%;\n}\n\n.commitRowLast_427795137 .commitGraph_427795137::before {\n bottom: 50%;\n}\n\n.commitDot_427795137 {\n position: absolute;\n left: 5px;\n top: 50%;\n transform: translateY(-50%);\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--dsw-alias-brand-primary);\n border: 3px solid var(--dsw-alias-bg-layer-2);\n box-sizing: content-box;\n margin-left: -3px;\n}\n\n.commitDotMerge_427795137 {\n background: #8350d8;\n}\n\n.commitMain_427795137 {\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n\n.commitSubject_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n font-size: 12.5px;\n color: var(--dsw-alias-label-primary);\n}\n\n.commitSubjectText_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.commitRowOpen_427795137 .commitSubjectText_427795137 {\n font-weight: 600;\n}\n\n.refBadges_427795137 {\n display: inline-flex;\n gap: 4px;\n flex: none;\n}\n\n.refBadge_427795137 {\n font-size: 10px;\n line-height: 1;\n border-radius: 4px;\n padding: 3px 5px;\n font-weight: 500;\n white-space: nowrap;\n max-width: 140px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.refHead_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary-bluish);\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.refTag_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-warning, #b07000);\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.refRemote_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: #8350d8;\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.refLocal_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-status-success, #218358);\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.commitMeta_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11.5px;\n}\n\n.authorDot_427795137 {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--dsw-alias-brand-primary);\n color: #fff;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 9px;\n flex: none;\n}\n\n.commitSide_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11.5px;\n flex: none;\n}\n\n.commitHash_427795137 {\n font-family: ui-monospace, Consolas, monospace;\n}\n\n.commitExpand_427795137 {\n grid-column: 1 / -1;\n padding: 2px 4px 8px 28px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.commitExpandTitle_427795137 {\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n margin-bottom: 3px;\n}\n\n.fileRow_427795137 {\n display: grid;\n grid-template-columns: 18px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 3px 6px;\n border-radius: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.fileRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.filePath_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: ui-monospace, Consolas, monospace;\n font-size: 11.5px;\n direction: rtl;\n text-align: left;\n}\n\n.fileNums_427795137 {\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-tertiary);\n flex: none;\n}\n\n.fileAdd_427795137 { color: var(--dsw-alias-status-success, #218358); }\n.fileDel_427795137 { color: var(--dsw-alias-status-danger, #d5304f); }\n\n.empty_427795137 {\n padding: 28px 16px;\n text-align: center;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12.5px;\n}\n\n.errorText_427795137 {\n padding: 20px 16px;\n text-align: center;\n color: var(--dsw-alias-status-danger, #d5304f);\n font-size: 12.5px;\n}\n\n.moreRow_427795137 {\n display: flex;\n justify-content: center;\n padding: 8px 0 2px;\n}\n";
3743
+ const css$2 = "/* Git panel (sidebar global panel). Three stacked sections over the main\n * column: uncommitted changes + commit box, branches, commit history. Host\n * tokens only; the few status colors fall back to the same literals the\n * settings card uses. */\n\n.page_427795137 {\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n}\n\n.topbar_427795137 {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 16px 8px;\n}\n\n.back_427795137 {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n border: 0;\n background: none;\n cursor: pointer;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary);\n padding: 4px 8px;\n border-radius: 8px;\n}\n\n.back_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.title_427795137 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n.repoPill_427795137 {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n font-size: 12px;\n line-height: 1.4;\n color: var(--dsw-alias-label-secondary);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 999px;\n padding: 3px 10px;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.repoName_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.branchName_427795137 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n.track_427795137 {\n font-variant-numeric: tabular-nums;\n}\n\n.topbarActions_427795137 {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n flex: none;\n}\n\n.refreshBtn_427795137 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 0;\n border-radius: 8px;\n background: none;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n.refreshBtn_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.refreshBtn_427795137[disabled] {\n opacity: 0.5;\n cursor: default;\n}\n\n/* Cn-accelerate: the topbar 国内加速 button and its anchored popover. The\n * button's on-state is brand tint + brand text + green dot; the popover\n * mirrors the settings card's switch/input affordances over this panel's\n * tokens (popup chrome follows .menu_427795137 above). */\n\n.cnWrap_427795137 {\n position: relative;\n display: inline-flex;\n}\n\n.cnBtn_427795137,\n.cnBtnOn_427795137 {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n height: 28px;\n padding: 0 10px;\n border: 0;\n border-radius: 8px;\n background: none;\n color: var(--dsw-alias-label-secondary);\n font: inherit;\n font-size: 12px;\n line-height: 1;\n cursor: pointer;\n}\n\n.cnBtn_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.cnBtnOn_427795137 {\n background: rgba(76, 107, 245, 0.16);\n color: var(--dsw-alias-brand-primary);\n}\n\n.cnBtnOn_427795137:hover {\n background: rgba(76, 107, 245, 0.22);\n color: var(--dsw-alias-brand-primary);\n}\n\n.cnDot_427795137 {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--dsw-alias-status-success, #218358);\n}\n\n.cnPop_427795137 {\n position: absolute;\n right: 0;\n top: calc(100% + 6px);\n z-index: 40;\n width: 320px;\n background: var(--dsw-alias-surface-raised, var(--dsw-alias-bg-layer-3));\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n box-shadow: var(--dsw-shadow-lv3);\n backdrop-filter: var(--dsw-menu-backdrop-filter);\n padding: 12px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.cnPopHead_427795137 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.cnPopTitle_427795137 {\n font-size: 13px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n.cnSwitchRow_427795137 {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n.cnSwitch_427795137 {\n width: 16px;\n height: 16px;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n\n.cnSwitch_427795137:disabled {\n cursor: default;\n}\n\n.cnHint_427795137 {\n margin: 0;\n font-size: 11px;\n line-height: 16px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.cnFieldHead_427795137 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n font-size: 12px;\n}\n\n.cnFieldLabel_427795137 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n.cnLink_427795137 {\n border: 0;\n background: none;\n padding: 0;\n font: inherit;\n font-size: 12px;\n color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n\n.cnLink_427795137:hover {\n text-decoration: underline;\n}\n\n.cnLink_427795137:disabled {\n opacity: 0.5;\n cursor: default;\n text-decoration: none;\n}\n\n.cnInput_427795137,\n.cnInputBad_427795137 {\n box-sizing: border-box;\n width: 100%;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n padding: 6px 8px;\n outline: none;\n}\n\n.cnInput_427795137:focus {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.cnInputBad_427795137,\n.cnInputBad_427795137:focus {\n border-color: var(--dsw-alias-status-danger, #d5304f);\n}\n\n.cnError_427795137 {\n font-size: 11px;\n line-height: 16px;\n color: var(--dsw-alias-status-danger, #d5304f);\n}\n\n.cnFooter_427795137 {\n display: flex;\n justify-content: flex-end;\n gap: 6px;\n margin-top: 2px;\n}\n\n.cnGhost_427795137,\n.cnSave_427795137 {\n border: 0;\n border-radius: 6px;\n font: inherit;\n font-size: 12px;\n padding: 5px 12px;\n cursor: pointer;\n}\n\n.cnGhost_427795137 {\n background: none;\n color: var(--dsw-alias-label-secondary);\n}\n\n.cnGhost_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.cnSave_427795137 {\n background: var(--dsw-alias-brand-primary);\n color: #fff;\n}\n\n.cnSave_427795137:disabled {\n opacity: 0.5;\n cursor: default;\n}\n\n.scroll_427795137 {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 0 16px 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n/* The page column below the topbar is a definite-height flex column and the\n * three cards split it 2:1:2 (uncommitted : branches : history) — five\n * shares, the topbar and gaps taking their natural height first. Each body\n * scrolls INSIDE its share — min-height: 0 is what lets a flex child shrink\n * below its content (the old natural-height model painted overflowing rows\n * over the sections below). A floor keeps a very short panel from\n * collapsing a card to its bare head; past the floor the column itself\n * scrolls. */\n.section_427795137 {\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-2);\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.sectionFill_427795137 {\n flex: 1 1 0;\n min-height: 84px;\n}\n\n/* The three flex-grow overrides of the 2:1:2 split. */\n.sectionChanges_427795137 {\n flex-grow: 2;\n}\n\n.sectionBranches_427795137 {\n flex-grow: 1;\n}\n\n.sectionHistory_427795137 {\n flex-grow: 2;\n}\n\n.sectionHead_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.sectionTitle_427795137 {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n.countBadge_427795137 {\n font-size: 10px;\n line-height: 1;\n border-radius: 999px;\n padding: 3px 7px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-secondary);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.sectionTools_427795137 {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.sectionBody_427795137 {\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n flex: 1 1 auto;\n min-height: 0;\n}\n\n/* The branch and history bodies scroll as a whole inside their share. */\n.sectionBodyScroll_427795137 {\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n/* Inside the uncommitted card only the file lists scroll; the commit box\n * below stays pinned however long the change tree is. */\n.changeList_427795137 {\n display: flex;\n flex-direction: column;\n gap: 8px;\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n/* The 全部展开/全部折叠 text chips in the branch card head. */\n.treeToggle_427795137 {\n background: none;\n border: 0;\n padding: 2px 5px;\n font: inherit;\n font-size: 11.5px;\n line-height: 1.4;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n border-radius: 5px;\n white-space: nowrap;\n}\n\n.treeToggle_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-brand-primary);\n}\n\n/* Small action chip used across the section heads and the commit row. */\n.act_427795137 {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n cursor: pointer;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 7px;\n padding: 4px 10px;\n white-space: nowrap;\n}\n\n.act_427795137:hover:not([disabled]) {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.act_427795137[disabled] {\n opacity: 0.45;\n cursor: default;\n}\n\n.actPrimary_427795137 {\n /* Hardcoded blue by request — the brand token does not resolve reliably\n * inside the better-sidebar panel. */\n background: #4c6bf5;\n border-color: transparent;\n color: #fff;\n}\n\n.actPrimary_427795137:hover:not([disabled]) {\n border-color: transparent;\n filter: brightness(1.06);\n}\n\n/* Uncommitted changes */\n\n.groupTitleRow_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.linkBtn_427795137 {\n margin-left: auto;\n background: none;\n border: 0;\n padding: 2px 4px;\n font: inherit;\n font-size: 12px;\n color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n border-radius: 5px;\n}\n\n.linkBtn_427795137:hover:not([disabled]) {\n text-decoration: underline;\n}\n\n.linkBtn_427795137[disabled] {\n opacity: 0.5;\n cursor: default;\n}\n\n.changeRow_427795137 {\n display: grid;\n grid-template-columns: 16px 18px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 3px 6px;\n border-radius: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.changeRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.changeCheck_427795137 {\n width: 14px;\n height: 14px;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n margin: 0;\n}\n\n.statusBadge_427795137 {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n font-size: 10px;\n line-height: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n color: #fff;\n box-sizing: border-box;\n}\n\n.statusA_427795137 { background: var(--dsw-alias-status-success, #218358); }\n.statusM_427795137 { background: var(--dsw-alias-label-warning, #b07000); }\n.statusD_427795137 { background: var(--dsw-alias-status-danger, #d5304f); }\n.statusR_427795137 { background: #8350d8; }\n.statusC_427795137 { background: #8350d8; }\n.statusT_427795137 { background: #5b7a9d; }\n.statusQ_427795137 { background: var(--dsw-alias-label-dimmed, #9aa0aa); }\n.statusU_427795137 { background: #d5502e; }\n\n.changePath_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: ui-monospace, Consolas, monospace;\n font-size: 11.5px;\n direction: rtl;\n text-align: left;\n}\n\n.stageHint_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n flex: none;\n}\n\n.commitBox_427795137 {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 4px;\n flex: none;\n}\n\n.commitInput_427795137 {\n width: 100%;\n box-sizing: border-box;\n resize: vertical;\n min-height: 52px;\n font: inherit;\n font-size: 12.5px;\n line-height: 1.5;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n padding: 7px 10px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n outline: none;\n}\n\n.commitInput_427795137:focus {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.commitActions_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.commitHint_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n min-height: 16px;\n}\n\n.split_427795137 {\n margin-left: auto;\n display: flex;\n position: relative;\n}\n\n.splitMain_427795137 {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n padding: 6px 16px;\n font-size: 13px;\n}\n\n.splitCaret_427795137 {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n margin-left: 1px;\n padding: 6px 6px;\n}\n\n.menu_427795137 {\n position: absolute;\n right: 0;\n top: calc(100% + 4px);\n z-index: 40;\n width: max-content;\n min-width: 0;\n background: var(--dsw-alias-surface-raised, var(--dsw-alias-bg-layer-3));\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n box-shadow: var(--dsw-shadow-lv3);\n backdrop-filter: var(--dsw-menu-backdrop-filter);\n padding: 3px;\n display: flex;\n flex-direction: column;\n}\n\n.menuItem_427795137 {\n display: block;\n width: 100%;\n text-align: left;\n background: none;\n border: 0;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n padding: 5px 10px;\n border-radius: 5px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.menuItem_427795137:hover:not([disabled]) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.menuItem_427795137[disabled] {\n opacity: 0.5;\n cursor: default;\n}\n\n.menuSub_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n margin-top: 1px;\n}\n\n/* Branch section — two IDEA-style trees: 本地 → branches, 远程 → per-remote → branches */\n\n.treeHead_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 6px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-label-secondary);\n user-select: none;\n}\n\n.treeHead_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.treeChevron_427795137 {\n display: inline-flex;\n align-items: center;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.treeChildren_427795137 {\n display: flex;\n flex-direction: column;\n margin-left: 12px;\n}\n\n.treeHeadNest_427795137 {\n font-weight: 400;\n}\n\n.treeNest_427795137 {\n margin-left: 12px;\n}\n\n.branchRow_427795137 {\n display: grid;\n grid-template-columns: 20px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 5px 8px;\n border-radius: 7px;\n /* The action menu opens on RIGHT-CLICK (Enter/Space for keyboard) — an\n * arrow, not the pointing hand a left-click affordance would promise. */\n cursor: default;\n font-size: 12.5px;\n color: var(--dsw-alias-label-primary);\n}\n\n.branchRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n/* Whole-row highlight for the current branch: the ✓ alone read as too\n * quiet inside the tree. A translucent brand-blue wash plus the inset left\n * accent and a colored name survives both themes; #4c6bf5 is the same\n * hardcoded blue actPrimary uses (the brand token does not resolve\n * reliably inside the better-sidebar panel). */\n.branchRowCurrent_427795137 {\n background: rgba(76, 107, 245, 0.16);\n box-shadow: inset 2px 0 0 #4c6bf5;\n cursor: default;\n}\n\n.branchRowCurrent_427795137:hover {\n background: rgba(76, 107, 245, 0.16);\n}\n\n.branchRowCurrent_427795137 .branchName_427795137 {\n color: #4c6bf5;\n font-weight: 600;\n}\n\n.branchMark_427795137 {\n color: var(--dsw-alias-brand-primary);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.branchName_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: 500;\n}\n\n.branchKind_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n margin-left: 6px;\n}\n\n.branchTrack_427795137 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n font-variant-numeric: tabular-nums;\n flex: none;\n}\n\n/* The branch action menu is portaled; fixed positioning by row rect. */\n.floatMenu_427795137 {\n position: fixed;\n z-index: 60;\n min-width: 190px;\n}\n\n.menuHead_427795137 {\n padding: 6px 10px 5px;\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n margin-bottom: 3px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.menuHeadStrong_427795137 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n.menuDanger_427795137 {\n color: var(--dsw-alias-status-danger, #d5304f);\n}\n\n.formField_427795137 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.formLabel_427795137 {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.formInput_427795137 {\n font: inherit;\n font-size: 13px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n padding: 7px 10px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n outline: none;\n}\n\n.formInput_427795137:focus {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.formError_427795137 {\n font-size: 12px;\n color: var(--dsw-alias-status-danger, #d5304f);\n min-height: 16px;\n}\n\n/* Commit history */\n\n.historyHead_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.searchBox_427795137 {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n flex: 1;\n max-width: 300px;\n min-width: 140px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 7px;\n padding: 0 9px;\n height: 28px;\n color: var(--dsw-alias-label-tertiary);\n background: var(--dsw-alias-bg-layer-3);\n}\n\n/* The branch card's head variant: sits right of the title and grows toward\n * the tools instead of being right-aligned by `margin-left: auto`. The\n * overrides win because both selectors are single classes and this one is\n * declared later. */\n.searchBoxHead_427795137 {\n margin-left: 0;\n flex: 1 1 auto;\n max-width: 320px;\n min-width: 90px;\n}\n\n.searchInput_427795137 {\n flex: 1;\n min-width: 0;\n border: 0;\n background: none;\n outline: none;\n font: inherit;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.searchInput_427795137::placeholder {\n color: var(--dsw-alias-label-tertiary);\n}\n\n.commitRow_427795137 {\n position: relative;\n display: grid;\n grid-template-columns: 22px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 6px 8px 6px 2px;\n cursor: pointer;\n border-radius: 7px;\n}\n\n.commitRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.commitRowOpen_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.commitRowOpen_427795137:hover {\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.commitGraph_427795137 {\n position: relative;\n align-self: stretch;\n min-height: 34px;\n}\n\n.commitGraph_427795137::before {\n content: \"\";\n position: absolute;\n left: 10px;\n top: 0;\n bottom: 0;\n width: 2px;\n background: var(--dsw-alias-border-l2);\n}\n\n.commitRowFirst_427795137 .commitGraph_427795137::before {\n top: 50%;\n}\n\n.commitRowLast_427795137 .commitGraph_427795137::before {\n bottom: 50%;\n}\n\n/* A small plain dot on the rail — the old 10px dot with a fat card-colored\n * ring read as a heavy black blob. #4c6bf5 for the same reason actPrimary\n * hardcodes it (the brand token does not resolve reliably in this panel). */\n.commitDot_427795137 {\n position: absolute;\n left: 8px;\n top: 50%;\n transform: translateY(-50%);\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: #4c6bf5;\n}\n\n.commitDotMerge_427795137 {\n background: #8350d8;\n}\n\n.commitMain_427795137 {\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n\n.commitSubject_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n font-size: 12.5px;\n color: var(--dsw-alias-label-primary);\n}\n\n.commitSubjectText_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.commitRowOpen_427795137 .commitSubjectText_427795137 {\n font-weight: 600;\n}\n\n.refBadges_427795137 {\n display: inline-flex;\n gap: 4px;\n flex: none;\n}\n\n.refBadge_427795137 {\n font-size: 10px;\n line-height: 1;\n border-radius: 4px;\n padding: 3px 5px;\n font-weight: 500;\n white-space: nowrap;\n max-width: 140px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.refHead_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary-bluish);\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.refTag_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-warning, #b07000);\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.refRemote_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: #8350d8;\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.refLocal_427795137 {\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-status-success, #218358);\n border: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.commitMeta_427795137 {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11.5px;\n}\n\n.commitSide_427795137 {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11.5px;\n flex: none;\n}\n\n.commitHash_427795137 {\n font-family: ui-monospace, Consolas, monospace;\n}\n\n.commitExpand_427795137 {\n grid-column: 1 / -1;\n padding: 2px 4px 8px 28px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.commitExpandTitle_427795137 {\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n margin-bottom: 3px;\n}\n\n.fileRow_427795137 {\n display: grid;\n grid-template-columns: 18px minmax(0, 1fr) auto;\n gap: 8px;\n align-items: center;\n padding: 3px 6px;\n border-radius: 6px;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.fileRow_427795137:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.filePath_427795137 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: ui-monospace, Consolas, monospace;\n font-size: 11.5px;\n direction: rtl;\n text-align: left;\n}\n\n.fileNums_427795137 {\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-tertiary);\n flex: none;\n}\n\n.fileAdd_427795137 { color: var(--dsw-alias-status-success, #218358); }\n.fileDel_427795137 { color: var(--dsw-alias-status-danger, #d5304f); }\n\n.empty_427795137 {\n padding: 28px 16px;\n text-align: center;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12.5px;\n}\n\n.errorText_427795137 {\n padding: 20px 16px;\n text-align: center;\n color: var(--dsw-alias-status-danger, #d5304f);\n font-size: 12.5px;\n}\n\n.moreRow_427795137 {\n display: flex;\n justify-content: center;\n padding: 8px 0 2px;\n}\n";
3526
3744
  const tagId$2 = "dsh-git-branch-manage/GitHistoryPanel.module.css";
3527
3745
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"" + tagId$2 + "\"]") === null) {
3528
3746
  const tag = document.createElement("style");
@@ -3542,13 +3760,40 @@ window.__ModuleLoader__.load({
3542
3760
  "track": "track_427795137",
3543
3761
  "topbarActions": "topbarActions_427795137",
3544
3762
  "refreshBtn": "refreshBtn_427795137",
3763
+ "menu": "menu_427795137",
3764
+ "cnWrap": "cnWrap_427795137",
3765
+ "cnBtn": "cnBtn_427795137",
3766
+ "cnBtnOn": "cnBtnOn_427795137",
3767
+ "cnDot": "cnDot_427795137",
3768
+ "cnPop": "cnPop_427795137",
3769
+ "cnPopHead": "cnPopHead_427795137",
3770
+ "cnPopTitle": "cnPopTitle_427795137",
3771
+ "cnSwitchRow": "cnSwitchRow_427795137",
3772
+ "cnSwitch": "cnSwitch_427795137",
3773
+ "cnHint": "cnHint_427795137",
3774
+ "cnFieldHead": "cnFieldHead_427795137",
3775
+ "cnFieldLabel": "cnFieldLabel_427795137",
3776
+ "cnLink": "cnLink_427795137",
3777
+ "cnInput": "cnInput_427795137",
3778
+ "cnInputBad": "cnInputBad_427795137",
3779
+ "cnError": "cnError_427795137",
3780
+ "cnFooter": "cnFooter_427795137",
3781
+ "cnGhost": "cnGhost_427795137",
3782
+ "cnSave": "cnSave_427795137",
3545
3783
  "scroll": "scroll_427795137",
3546
3784
  "section": "section_427795137",
3785
+ "sectionFill": "sectionFill_427795137",
3786
+ "sectionChanges": "sectionChanges_427795137",
3787
+ "sectionBranches": "sectionBranches_427795137",
3788
+ "sectionHistory": "sectionHistory_427795137",
3547
3789
  "sectionHead": "sectionHead_427795137",
3548
3790
  "sectionTitle": "sectionTitle_427795137",
3549
3791
  "countBadge": "countBadge_427795137",
3550
3792
  "sectionTools": "sectionTools_427795137",
3551
3793
  "sectionBody": "sectionBody_427795137",
3794
+ "sectionBodyScroll": "sectionBodyScroll_427795137",
3795
+ "changeList": "changeList_427795137",
3796
+ "treeToggle": "treeToggle_427795137",
3552
3797
  "act": "act_427795137",
3553
3798
  "actPrimary": "actPrimary_427795137",
3554
3799
  "groupTitleRow": "groupTitleRow_427795137",
@@ -3573,7 +3818,6 @@ window.__ModuleLoader__.load({
3573
3818
  "split": "split_427795137",
3574
3819
  "splitMain": "splitMain_427795137",
3575
3820
  "splitCaret": "splitCaret_427795137",
3576
- "menu": "menu_427795137",
3577
3821
  "menuItem": "menuItem_427795137",
3578
3822
  "menuSub": "menuSub_427795137",
3579
3823
  "treeHead": "treeHead_427795137",
@@ -3596,6 +3840,7 @@ window.__ModuleLoader__.load({
3596
3840
  "formError": "formError_427795137",
3597
3841
  "historyHead": "historyHead_427795137",
3598
3842
  "searchBox": "searchBox_427795137",
3843
+ "searchBoxHead": "searchBoxHead_427795137",
3599
3844
  "searchInput": "searchInput_427795137",
3600
3845
  "commitRow": "commitRow_427795137",
3601
3846
  "commitRowOpen": "commitRowOpen_427795137",
@@ -3614,7 +3859,6 @@ window.__ModuleLoader__.load({
3614
3859
  "refRemote": "refRemote_427795137",
3615
3860
  "refLocal": "refLocal_427795137",
3616
3861
  "commitMeta": "commitMeta_427795137",
3617
- "authorDot": "authorDot_427795137",
3618
3862
  "commitSide": "commitSide_427795137",
3619
3863
  "commitHash": "commitHash_427795137",
3620
3864
  "commitExpand": "commitExpand_427795137",
@@ -3632,18 +3876,36 @@ window.__ModuleLoader__.load({
3632
3876
  //#region src/client/panel/BranchSection.tsx
3633
3877
  /**
3634
3878
  * BranchSection: the panel's middle block — the branch list with an IDEA-style
3635
- * action menu. Clicking any row opens a small menu anchored to it (checkout,
3636
- * new branch from here, rename, delete, copy name — remote rows narrow it to
3637
- * the actions a remote branch can take); the CURRENT branch's menu hides only
3638
- * checkout and delete, so rename/new-from/copy stay reachable. Rename and
3639
- * create run through the Modal primitive with the same client-side name
3640
- * validation the composer chip applies; delete confirms first and always uses
3641
- * the safe `-d` form (git refuses unmerged). Presentational: every action
3642
- * arrives as a callback; the menu/dialog state is local and resets when the
3643
- * branch list identity changes.
3879
+ * action menu. RIGHT-CLICKING any row opens a small menu anchored to it
3880
+ * (checkout, new branch from here, rename, delete, copy name — remote rows
3881
+ * narrow it to the actions a remote branch can take); the CURRENT branch's
3882
+ * menu hides only checkout and delete, so rename/new-from/copy stay
3883
+ * reachable. Keyboard rows keep Enter/Space as the menu opener — a context
3884
+ * menu has no keyboard twin. Rename and create run through the Modal
3885
+ * primitive with the same client-side name validation the composer chip
3886
+ * applies; delete confirms first and always uses the safe `-d` form (git
3887
+ * refuses unmerged). Presentational: every action arrives as a callback; the
3888
+ * menu/dialog state is local and resets when the branch list identity
3889
+ * changes.
3890
+ *
3891
+ * The tree opens on 本地 only (the current branch lives there) and the card
3892
+ * takes one share of the panel's fixed 2:1:2 split (its body scrolls inside
3893
+ * it), so a branch-heavy repository can no longer push the other cards off
3894
+ * screen. 全部展开/全部折叠 drive every group at once, and after a checkout
3895
+ * (or expand-all) the card re-centers on the current branch row.
3896
+ *
3897
+ * The head carries a search box: it filters both trees by branch name
3898
+ * (case-insensitive substring), and while a query is active every matching
3899
+ * group renders expanded with its count following the filter — the folded
3900
+ * state the user set is untouched and comes back when the query clears.
3644
3901
  *
3645
3902
  * @module git-worktree/client/panel/BranchSection
3646
3903
  */
3904
+ /** Groups folded when the card mounts: the remote tree only. The current
3905
+ * branch lives at the TOP of the local group (buildBranchRows sorts it
3906
+ * first), so 本地 stays open — the card opens showing what the panel is
3907
+ * about, without the wall of remote branches. */
3908
+ const COLLAPSED_ON_MOUNT = /* @__PURE__ */ new Set(["remote"]);
3647
3909
  /** The action menu as a body portal, fixed-positioned next to the row. */
3648
3910
  function BranchFloatMenu(props) {
3649
3911
  const { state, t, busy, onAction, onClose } = props;
@@ -3739,7 +4001,16 @@ window.__ModuleLoader__.load({
3739
4001
  const [menu, setMenu] = (0, react.useState)(null);
3740
4002
  const [dialog, setDialog] = (0, react.useState)(null);
3741
4003
  const [draft, setDraft] = (0, react.useState)("");
3742
- const [collapsedGroups, setCollapsedGroups] = (0, react.useState)(/* @__PURE__ */ new Set());
4004
+ const [query, setQuery] = (0, react.useState)("");
4005
+ const [collapsedGroups, setCollapsedGroups] = (0, react.useState)(COLLAPSED_ON_MOUNT);
4006
+ /** The card's scroll body — the locate math centers rows inside it. */
4007
+ const bodyRef = (0, react.useRef)(null);
4008
+ /** The current branch this mount last centered on. A refresh re-centers
4009
+ * only when the checkout moved; a same-branch refresh (stage, commit…)
4010
+ * keeps the scroll where the user left it. */
4011
+ const locatedRef = (0, react.useRef)(null);
4012
+ /** Expand-all asks for one more locate — its rows mount on the next commit. */
4013
+ const pendingLocateRef = (0, react.useRef)(false);
3743
4014
  const toggleGroup = (key) => {
3744
4015
  setCollapsedGroups((prev) => {
3745
4016
  const next = new Set(prev);
@@ -3748,7 +4019,41 @@ window.__ModuleLoader__.load({
3748
4019
  return next;
3749
4020
  });
3750
4021
  };
4022
+ const expandAll = () => {
4023
+ pendingLocateRef.current = true;
4024
+ setCollapsedGroups(/* @__PURE__ */ new Set());
4025
+ };
4026
+ const collapseAll = () => {
4027
+ setCollapsedGroups(new Set(branchGroupKeys(remotes)));
4028
+ };
4029
+ /** Center the current branch row in the card body (no scroll when the
4030
+ * body is shorter than its cap). Rect arithmetic, not offsetTop: no
4031
+ * positioned ancestor is guaranteed between the row and the body. */
4032
+ const locateCurrent = () => {
4033
+ const body = bodyRef.current;
4034
+ if (body === null) return;
4035
+ const row = body.querySelector("[data-current=\"true\"]");
4036
+ if (!(row instanceof HTMLElement)) return;
4037
+ const top = row.getBoundingClientRect().top - body.getBoundingClientRect().top + body.scrollTop;
4038
+ body.scrollTop = Math.max(0, top - (body.clientHeight - row.offsetHeight) / 2);
4039
+ };
4040
+ (0, react.useLayoutEffect)(() => {
4041
+ const current = locals.find((row) => row.current)?.name;
4042
+ if (current === void 0) return;
4043
+ if (!pendingLocateRef.current && current === locatedRef.current) return;
4044
+ pendingLocateRef.current = false;
4045
+ locatedRef.current = current;
4046
+ locateCurrent();
4047
+ });
3751
4048
  const total = locals.length + remotes.length;
4049
+ /** The head search: name-substring rows only. A live query opens every
4050
+ * group whatever the folded state is (a hidden match reads as a bug),
4051
+ * without touching that state — clearing the query restores it. */
4052
+ const searching = query.trim() !== "";
4053
+ const visibleLocals = filterBranches(locals, query);
4054
+ const visibleRemotes = filterBranches(remotes, query);
4055
+ const openGroup = (key) => searching || !collapsedGroups.has(key);
4056
+ const matched = visibleLocals.length + visibleRemotes.length;
3752
4057
  const openMenu = (branch, event) => {
3753
4058
  const rect = event.currentTarget.getBoundingClientRect();
3754
4059
  setMenu({
@@ -3803,7 +4108,7 @@ window.__ModuleLoader__.load({
3803
4108
  className: `${GitHistoryPanel_module_default.treeHead} ${nested ? GitHistoryPanel_module_default.treeHeadNest : ""}`,
3804
4109
  role: "button",
3805
4110
  tabIndex: 0,
3806
- "aria-expanded": !collapsedGroups.has(key),
4111
+ "aria-expanded": openGroup(key),
3807
4112
  onClick: () => toggleGroup(key),
3808
4113
  onKeyDown: (event) => {
3809
4114
  if (event.key === "Enter" || event.key === " ") {
@@ -3814,7 +4119,7 @@ window.__ModuleLoader__.load({
3814
4119
  children: [
3815
4120
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3816
4121
  className: GitHistoryPanel_module_default.treeChevron,
3817
- children: collapsedGroups.has(key) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, { size: 12 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { size: 12 })
4122
+ children: openGroup(key) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { size: 12 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, { size: 12 })
3818
4123
  }),
3819
4124
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label }),
3820
4125
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -3825,9 +4130,13 @@ window.__ModuleLoader__.load({
3825
4130
  });
3826
4131
  const renderBranchRow = (row, displayName) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3827
4132
  className: `${GitHistoryPanel_module_default.branchRow} ${row.current ? GitHistoryPanel_module_default.branchRowCurrent : ""}`,
4133
+ "data-current": row.current ? "true" : void 0,
3828
4134
  role: "button",
3829
4135
  tabIndex: 0,
3830
- onClick: (event) => openMenu(row, event),
4136
+ onContextMenu: (event) => {
4137
+ event.preventDefault();
4138
+ openMenu(row, event);
4139
+ },
3831
4140
  onKeyDown: (event) => {
3832
4141
  if (event.key === "Enter" || event.key === " ") {
3833
4142
  event.preventDefault();
@@ -3851,39 +4160,75 @@ window.__ModuleLoader__.load({
3851
4160
  ]
3852
4161
  }, row.name);
3853
4162
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3854
- className: GitHistoryPanel_module_default.section,
4163
+ className: `${GitHistoryPanel_module_default.section} ${GitHistoryPanel_module_default.sectionFill} ${GitHistoryPanel_module_default.sectionBranches}`,
3855
4164
  "aria-label": t("panel.branches"),
3856
4165
  children: [
3857
4166
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3858
4167
  className: GitHistoryPanel_module_default.sectionHead,
3859
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
3860
- className: GitHistoryPanel_module_default.sectionTitle,
3861
- children: t("panel.branches")
3862
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3863
- className: GitHistoryPanel_module_default.sectionTools,
3864
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3865
- type: "button",
3866
- className: GitHistoryPanel_module_default.act,
3867
- disabled: busy,
3868
- onClick: () => openDialog("new"),
3869
- children: ["+ ", t("panel.branchNew")]
4168
+ children: [
4169
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
4170
+ className: GitHistoryPanel_module_default.sectionTitle,
4171
+ children: t("panel.branches")
4172
+ }),
4173
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4174
+ className: `${GitHistoryPanel_module_default.searchBox} ${GitHistoryPanel_module_default.searchBoxHead}`,
4175
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4176
+ "aria-hidden": "true",
4177
+ children: "⌕"
4178
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4179
+ type: "text",
4180
+ className: GitHistoryPanel_module_default.searchInput,
4181
+ value: query,
4182
+ placeholder: t("menuSearchPlaceholder"),
4183
+ "aria-label": t("menuSearchPlaceholder"),
4184
+ onChange: (event) => setQuery(event.target.value)
4185
+ })]
4186
+ }),
4187
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4188
+ className: GitHistoryPanel_module_default.sectionTools,
4189
+ children: [
4190
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4191
+ type: "button",
4192
+ className: GitHistoryPanel_module_default.treeToggle,
4193
+ onClick: expandAll,
4194
+ children: t("menuExpandAll")
4195
+ }),
4196
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4197
+ type: "button",
4198
+ className: GitHistoryPanel_module_default.treeToggle,
4199
+ onClick: collapseAll,
4200
+ children: t("menuCollapseAll")
4201
+ }),
4202
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
4203
+ type: "button",
4204
+ className: GitHistoryPanel_module_default.act,
4205
+ disabled: busy,
4206
+ onClick: () => openDialog("new"),
4207
+ children: ["+ ", t("panel.branchNew")]
4208
+ })
4209
+ ]
3870
4210
  })
3871
- })]
4211
+ ]
3872
4212
  }),
3873
4213
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3874
- className: GitHistoryPanel_module_default.sectionBody,
4214
+ className: `${GitHistoryPanel_module_default.sectionBody} ${GitHistoryPanel_module_default.sectionBodyScroll}`,
4215
+ ref: bodyRef,
3875
4216
  children: [
3876
4217
  total === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3877
4218
  className: GitHistoryPanel_module_default.empty,
3878
4219
  children: t("menuNoBranches")
3879
4220
  }) : null,
3880
- locals.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [groupHead("local", t("panel.branchLocals"), locals.length, false), !collapsedGroups.has("local") ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4221
+ total > 0 && matched === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4222
+ className: GitHistoryPanel_module_default.empty,
4223
+ children: t("menuNoMatches")
4224
+ }) : null,
4225
+ visibleLocals.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [groupHead("local", t("panel.branchLocals"), visibleLocals.length, false), openGroup("local") ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3881
4226
  className: GitHistoryPanel_module_default.treeChildren,
3882
- children: locals.map((row) => renderBranchRow(row))
4227
+ children: visibleLocals.map((row) => renderBranchRow(row))
3883
4228
  }) : null] }) : null,
3884
- remotes.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [groupHead("remote", t("panel.branchRemotes"), remotes.length, false), !collapsedGroups.has("remote") ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4229
+ visibleRemotes.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [groupHead("remote", t("panel.branchRemotes"), visibleRemotes.length, false), openGroup("remote") ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3885
4230
  className: GitHistoryPanel_module_default.treeNest,
3886
- children: groupRemotes(remotes).map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [groupHead(`remote:${group.remote}`, group.remote, group.branches.length, true), !collapsedGroups.has(`remote:${group.remote}`) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4231
+ children: groupRemotes(visibleRemotes).map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [groupHead(`remote:${group.remote}`, group.remote, group.branches.length, true), openGroup(`remote:${group.remote}`) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3887
4232
  className: GitHistoryPanel_module_default.treeChildren,
3888
4233
  children: group.branches.map((row) => renderBranchRow(row, row.short))
3889
4234
  }) : null] }, group.remote))
@@ -3965,6 +4310,135 @@ window.__ModuleLoader__.load({
3965
4310
  });
3966
4311
  }
3967
4312
  //#endregion
4313
+ //#region src/client/panel/CnAcceleratePopover.tsx
4314
+ /**
4315
+ * CnAcceleratePopover: the 国内加速 popover under the topbar button.
4316
+ *
4317
+ * This is the SHORTCUT surface of the same staged form the settings card row
4318
+ * edits ({@link ../accel-form}): enable switch + mirror URL stage together
4319
+ * and commit together on 保存. Closing the popover — Esc, outside click, 取消
4320
+ * — discards the staged edits through the owner's close handler, so an
4321
+ * abandoned draft can never land half-written.
4322
+ *
4323
+ * Layout follows docs/design/cn-accelerate.md §2.2: title + switch → security
4324
+ * hint → URL field with 恢复默认 → error line → footer.
4325
+ *
4326
+ * @module git-worktree/client/panel/CnAcceleratePopover
4327
+ */
4328
+ function CnAcceleratePopover(props) {
4329
+ const { accel, t, pushToast, onClose } = props;
4330
+ const rootRef = (0, react.useRef)(null);
4331
+ const state = (0, react.useSyncExternalStore)(accel.store.subscribe, accel.store.getSnapshot);
4332
+ (0, react.useEffect)(() => {
4333
+ const onKeyDown = (event) => {
4334
+ if (event.key === "Escape") onClose();
4335
+ };
4336
+ const onPointerDown = (event) => {
4337
+ if (rootRef.current !== null && !rootRef.current.contains(event.target)) onClose();
4338
+ };
4339
+ document.addEventListener("keydown", onKeyDown);
4340
+ document.addEventListener("pointerdown", onPointerDown);
4341
+ return () => {
4342
+ document.removeEventListener("keydown", onKeyDown);
4343
+ document.removeEventListener("pointerdown", onPointerDown);
4344
+ };
4345
+ }, [onClose]);
4346
+ const locked = state.saving || !state.writable;
4347
+ const onSave = (0, react.useCallback)(() => {
4348
+ if (state.saving || state.urlError !== null || !state.writable) return;
4349
+ (async () => {
4350
+ await accel.saveAccel();
4351
+ const after = accel.store.getSnapshot();
4352
+ if (after.failed) {
4353
+ pushToast(t("accel.saveFailed"), "error");
4354
+ return;
4355
+ }
4356
+ pushToast(after.enabled ? t("accel.savedOn", { url: after.urlText }) : t("accel.savedOff"), "success");
4357
+ onClose();
4358
+ })();
4359
+ }, [
4360
+ accel,
4361
+ onClose,
4362
+ pushToast,
4363
+ state.saving,
4364
+ state.urlError,
4365
+ state.writable,
4366
+ t
4367
+ ]);
4368
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4369
+ className: GitHistoryPanel_module_default.cnPop,
4370
+ ref: rootRef,
4371
+ role: "dialog",
4372
+ "aria-label": t("panel.cnAccelerate"),
4373
+ children: [
4374
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4375
+ className: GitHistoryPanel_module_default.cnPopHead,
4376
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4377
+ className: GitHistoryPanel_module_default.cnPopTitle,
4378
+ children: t("panel.cnAccelerate")
4379
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
4380
+ className: GitHistoryPanel_module_default.cnSwitchRow,
4381
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("accel.enable") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4382
+ type: "checkbox",
4383
+ className: GitHistoryPanel_module_default.cnSwitch,
4384
+ checked: state.enabled,
4385
+ disabled: locked,
4386
+ onChange: (event) => accel.setAccelEnabled(event.target.checked)
4387
+ })]
4388
+ })]
4389
+ }),
4390
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4391
+ className: GitHistoryPanel_module_default.cnHint,
4392
+ children: t("accel.hint")
4393
+ }),
4394
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4395
+ className: GitHistoryPanel_module_default.cnFieldHead,
4396
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4397
+ className: GitHistoryPanel_module_default.cnFieldLabel,
4398
+ children: t("accel.urlLabel")
4399
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4400
+ type: "button",
4401
+ className: GitHistoryPanel_module_default.cnLink,
4402
+ disabled: locked,
4403
+ onClick: () => accel.restoreAccelDefault(),
4404
+ children: t("accel.restoreDefault")
4405
+ })]
4406
+ }),
4407
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4408
+ type: "text",
4409
+ className: state.urlError !== null ? GitHistoryPanel_module_default.cnInputBad : GitHistoryPanel_module_default.cnInput,
4410
+ value: state.urlText,
4411
+ spellCheck: false,
4412
+ disabled: locked,
4413
+ "aria-invalid": state.urlError !== null,
4414
+ onChange: (event) => accel.editAccelUrl(event.target.value),
4415
+ onKeyDown: (event) => {
4416
+ if (event.key === "Enter") onSave();
4417
+ }
4418
+ }),
4419
+ state.urlError !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4420
+ className: GitHistoryPanel_module_default.cnError,
4421
+ children: state.urlError === "empty" ? t("accel.urlEmpty") : t("accel.urlInvalid")
4422
+ }) : null,
4423
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4424
+ className: GitHistoryPanel_module_default.cnFooter,
4425
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4426
+ type: "button",
4427
+ className: GitHistoryPanel_module_default.cnGhost,
4428
+ onClick: onClose,
4429
+ children: t("cancel")
4430
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4431
+ type: "button",
4432
+ className: GitHistoryPanel_module_default.cnSave,
4433
+ disabled: state.saving || state.urlError !== null || !state.writable,
4434
+ onClick: onSave,
4435
+ children: t("cardSave")
4436
+ })]
4437
+ })
4438
+ ]
4439
+ });
4440
+ }
4441
+ //#endregion
3968
4442
  //#region src/client/panel/HistorySection.tsx
3969
4443
  /**
3970
4444
  * HistorySection: the panel's third block — the commit list. One row shows
@@ -4024,7 +4498,6 @@ window.__ModuleLoader__.load({
4024
4498
  const badges = classifyRefs(commit.refs);
4025
4499
  const when = new Date(commit.date);
4026
4500
  const absolute = Number.isFinite(commit.date) && commit.date > 0 ? `${when.toLocaleDateString()} ${when.toLocaleTimeString()}` : "";
4027
- const authorInitial = commit.authorName.slice(0, 1);
4028
4501
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4029
4502
  ref,
4030
4503
  className: [
@@ -4069,15 +4542,7 @@ window.__ModuleLoader__.load({
4069
4542
  })]
4070
4543
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4071
4544
  className: GitHistoryPanel_module_default.commitMeta,
4072
- children: [
4073
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4074
- className: GitHistoryPanel_module_default.authorDot,
4075
- "aria-hidden": "true",
4076
- children: authorInitial
4077
- }),
4078
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: commit.authorName }),
4079
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: timeLabelFor(commit.date) })
4080
- ]
4545
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: commit.authorName }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: timeLabelFor(commit.date) })]
4081
4546
  })]
4082
4547
  }),
4083
4548
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -4122,7 +4587,7 @@ window.__ModuleLoader__.load({
4122
4587
  const needle = query.trim().toLowerCase();
4123
4588
  const visible = filterCommits(commits, query);
4124
4589
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
4125
- className: GitHistoryPanel_module_default.section,
4590
+ className: `${GitHistoryPanel_module_default.section} ${GitHistoryPanel_module_default.sectionFill} ${GitHistoryPanel_module_default.sectionHistory}`,
4126
4591
  "aria-label": t("panel.history"),
4127
4592
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4128
4593
  className: GitHistoryPanel_module_default.historyHead,
@@ -4144,7 +4609,7 @@ window.__ModuleLoader__.load({
4144
4609
  })]
4145
4610
  })]
4146
4611
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4147
- className: GitHistoryPanel_module_default.sectionBody,
4612
+ className: `${GitHistoryPanel_module_default.sectionBody} ${GitHistoryPanel_module_default.sectionBodyScroll}`,
4148
4613
  children: [loadError !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4149
4614
  className: GitHistoryPanel_module_default.errorText,
4150
4615
  children: loadError
@@ -4191,6 +4656,11 @@ window.__ModuleLoader__.load({
4191
4656
  * the draft, and every action arrive as props from the panel state owner, so
4192
4657
  * this file renders and never talks to git itself.
4193
4658
  *
4659
+ * The card takes two shares of the panel's fixed 2:1:2 split: the file
4660
+ * lists scroll inside their own region while the commit box stays pinned
4661
+ * below — a 500-change tree must not bury the commit affordance, and a
4662
+ * clean tree must not float it up either.
4663
+ *
4194
4664
  * The commit affordance is a split button: the main face commits, the caret
4195
4665
  * opens the two op variants (commit; commit and push). The AI button fills
4196
4666
  * the draft from the host's one-shot llm route — it renders only when the
@@ -4263,7 +4733,7 @@ window.__ModuleLoader__.load({
4263
4733
  const hint = staged.length === 0 ? t("panel.commitNeedsStaged") : commitDraft.trim() === "" ? t("panel.commitNeedsMessage") : "";
4264
4734
  const aiReady = aiAvailable && total > 0;
4265
4735
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
4266
- className: GitHistoryPanel_module_default.section,
4736
+ className: `${GitHistoryPanel_module_default.section} ${GitHistoryPanel_module_default.sectionFill} ${GitHistoryPanel_module_default.sectionChanges}`,
4267
4737
  "aria-label": t("panel.uncommitted"),
4268
4738
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4269
4739
  className: GitHistoryPanel_module_default.sectionHead,
@@ -4308,129 +4778,131 @@ window.__ModuleLoader__.load({
4308
4778
  ]
4309
4779
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4310
4780
  className: GitHistoryPanel_module_default.sectionBody,
4311
- children: [
4312
- total === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4313
- className: GitHistoryPanel_module_default.empty,
4314
- children: t("panel.clean")
4315
- }) : null,
4316
- truncated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4317
- className: GitHistoryPanel_module_default.empty,
4318
- children: t("panel.changesTruncated")
4319
- }) : null,
4320
- staged.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4321
- className: GitHistoryPanel_module_default.groupTitleRow,
4322
- children: [
4323
- t("panel.staged"),
4324
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4325
- className: GitHistoryPanel_module_default.countBadge,
4326
- children: String(staged.length)
4327
- }),
4328
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4329
- type: "button",
4330
- className: GitHistoryPanel_module_default.linkBtn,
4331
- disabled: busy,
4332
- onClick: onUnstageAll,
4333
- children: t("panel.unstageAll")
4334
- })
4335
- ]
4336
- }), staged.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChangeRowView, {
4337
- row,
4338
- disabled: busy,
4339
- onToggle: onToggleRow,
4340
- t
4341
- }, `${row.staged}:${row.path}:${row.oldPath ?? ""}`))] }) : null,
4342
- unstaged.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4343
- className: GitHistoryPanel_module_default.groupTitleRow,
4344
- children: [
4345
- t("panel.unstaged"),
4346
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4347
- className: GitHistoryPanel_module_default.countBadge,
4348
- children: String(unstaged.length)
4349
- }),
4350
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4351
- type: "button",
4352
- className: GitHistoryPanel_module_default.linkBtn,
4353
- disabled: busy,
4354
- onClick: onStageAll,
4355
- children: t("panel.stageAll")
4356
- })
4357
- ]
4358
- }), unstaged.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChangeRowView, {
4359
- row,
4360
- disabled: busy,
4361
- onToggle: onToggleRow,
4362
- t
4363
- }, `u:${row.path}:${row.oldPath ?? ""}`))] }) : null,
4364
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4365
- className: GitHistoryPanel_module_default.commitBox,
4366
- children: [
4367
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
4368
- className: GitHistoryPanel_module_default.commitInput,
4369
- value: commitDraft,
4370
- placeholder: t("panel.commitPlaceholder"),
4371
- "aria-label": t("panel.commitPlaceholder"),
4372
- rows: 2,
4373
- maxLength: COMMIT_MESSAGE_LIMIT,
4374
- onChange: (event) => onCommitDraft(event.target.value)
4375
- }),
4376
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4377
- className: GitHistoryPanel_module_default.commitActions,
4378
- children: [aiAvailable ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
4781
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4782
+ className: GitHistoryPanel_module_default.changeList,
4783
+ children: [
4784
+ total === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4785
+ className: GitHistoryPanel_module_default.empty,
4786
+ children: t("panel.clean")
4787
+ }) : null,
4788
+ truncated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4789
+ className: GitHistoryPanel_module_default.empty,
4790
+ children: t("panel.changesTruncated")
4791
+ }) : null,
4792
+ staged.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4793
+ className: GitHistoryPanel_module_default.groupTitleRow,
4794
+ children: [
4795
+ t("panel.staged"),
4796
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4797
+ className: GitHistoryPanel_module_default.countBadge,
4798
+ children: String(staged.length)
4799
+ }),
4800
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4379
4801
  type: "button",
4380
- className: GitHistoryPanel_module_default.act,
4381
- disabled: busy || aiBusy || !aiReady,
4382
- title: !aiReady ? t("panel.aiNeedsChanges") : void 0,
4383
- onClick: onAiGenerate,
4384
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSparkleRegular, { size: 13 }), aiBusy ? t("panel.aiBusy") : t("panel.aiGenerate")]
4385
- }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4386
- className: GitHistoryPanel_module_default.split,
4387
- ref: menuRef,
4388
- children: [
4389
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4802
+ className: GitHistoryPanel_module_default.linkBtn,
4803
+ disabled: busy,
4804
+ onClick: onUnstageAll,
4805
+ children: t("panel.unstageAll")
4806
+ })
4807
+ ]
4808
+ }), staged.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChangeRowView, {
4809
+ row,
4810
+ disabled: busy,
4811
+ onToggle: onToggleRow,
4812
+ t
4813
+ }, `${row.staged}:${row.path}:${row.oldPath ?? ""}`))] }) : null,
4814
+ unstaged.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4815
+ className: GitHistoryPanel_module_default.groupTitleRow,
4816
+ children: [
4817
+ t("panel.unstaged"),
4818
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4819
+ className: GitHistoryPanel_module_default.countBadge,
4820
+ children: String(unstaged.length)
4821
+ }),
4822
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4823
+ type: "button",
4824
+ className: GitHistoryPanel_module_default.linkBtn,
4825
+ disabled: busy,
4826
+ onClick: onStageAll,
4827
+ children: t("panel.stageAll")
4828
+ })
4829
+ ]
4830
+ }), unstaged.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChangeRowView, {
4831
+ row,
4832
+ disabled: busy,
4833
+ onToggle: onToggleRow,
4834
+ t
4835
+ }, `u:${row.path}:${row.oldPath ?? ""}`))] }) : null
4836
+ ]
4837
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4838
+ className: GitHistoryPanel_module_default.commitBox,
4839
+ children: [
4840
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
4841
+ className: GitHistoryPanel_module_default.commitInput,
4842
+ value: commitDraft,
4843
+ placeholder: t("panel.commitPlaceholder"),
4844
+ "aria-label": t("panel.commitPlaceholder"),
4845
+ rows: 2,
4846
+ maxLength: COMMIT_MESSAGE_LIMIT,
4847
+ onChange: (event) => onCommitDraft(event.target.value)
4848
+ }),
4849
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4850
+ className: GitHistoryPanel_module_default.commitActions,
4851
+ children: [aiAvailable ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
4852
+ type: "button",
4853
+ className: GitHistoryPanel_module_default.act,
4854
+ disabled: busy || aiBusy || !aiReady,
4855
+ title: !aiReady ? t("panel.aiNeedsChanges") : void 0,
4856
+ onClick: onAiGenerate,
4857
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSparkleRegular, { size: 13 }), aiBusy ? t("panel.aiBusy") : t("panel.aiGenerate")]
4858
+ }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4859
+ className: GitHistoryPanel_module_default.split,
4860
+ ref: menuRef,
4861
+ children: [
4862
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4863
+ type: "button",
4864
+ className: `${GitHistoryPanel_module_default.act} ${GitHistoryPanel_module_default.actPrimary} ${GitHistoryPanel_module_default.splitMain}`,
4865
+ disabled: !canCommit || busy,
4866
+ onClick: () => onCommit(false),
4867
+ children: busy ? t("panel.commitBusy") : t("panel.commit")
4868
+ }),
4869
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4870
+ type: "button",
4871
+ className: `${GitHistoryPanel_module_default.act} ${GitHistoryPanel_module_default.actPrimary} ${GitHistoryPanel_module_default.splitCaret}`,
4872
+ "aria-label": t("panel.commitMoreAria"),
4873
+ "aria-expanded": commitMenuOpen,
4874
+ disabled: !canCommit || busy,
4875
+ onClick: onToggleCommitMenu,
4876
+ children: "▾"
4877
+ }),
4878
+ commitMenuOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4879
+ className: GitHistoryPanel_module_default.menu,
4880
+ role: "menu",
4881
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4390
4882
  type: "button",
4391
- className: `${GitHistoryPanel_module_default.act} ${GitHistoryPanel_module_default.actPrimary} ${GitHistoryPanel_module_default.splitMain}`,
4392
- disabled: !canCommit || busy,
4883
+ role: "menuitem",
4884
+ className: GitHistoryPanel_module_default.menuItem,
4885
+ disabled: !canCommit,
4393
4886
  onClick: () => onCommit(false),
4394
- children: busy ? t("panel.commitBusy") : t("panel.commit")
4395
- }),
4396
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4887
+ children: t("panel.commit")
4888
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4397
4889
  type: "button",
4398
- className: `${GitHistoryPanel_module_default.act} ${GitHistoryPanel_module_default.actPrimary} ${GitHistoryPanel_module_default.splitCaret}`,
4399
- "aria-label": t("panel.commitMoreAria"),
4400
- "aria-expanded": commitMenuOpen,
4401
- disabled: !canCommit || busy,
4402
- onClick: onToggleCommitMenu,
4403
- children: "▾"
4404
- }),
4405
- commitMenuOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4406
- className: GitHistoryPanel_module_default.menu,
4407
- role: "menu",
4408
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4409
- type: "button",
4410
- role: "menuitem",
4411
- className: GitHistoryPanel_module_default.menuItem,
4412
- disabled: !canCommit,
4413
- onClick: () => onCommit(false),
4414
- children: t("panel.commit")
4415
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4416
- type: "button",
4417
- role: "menuitem",
4418
- className: GitHistoryPanel_module_default.menuItem,
4419
- disabled: !canCommit,
4420
- onClick: () => onCommit(true),
4421
- children: t("panel.commitPush")
4422
- })]
4423
- }) : null
4424
- ]
4425
- })]
4426
- }),
4427
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4428
- className: GitHistoryPanel_module_default.commitHint,
4429
- children: hint
4430
- })
4431
- ]
4432
- })
4433
- ]
4890
+ role: "menuitem",
4891
+ className: GitHistoryPanel_module_default.menuItem,
4892
+ disabled: !canCommit,
4893
+ onClick: () => onCommit(true),
4894
+ children: t("panel.commitPush")
4895
+ })]
4896
+ }) : null
4897
+ ]
4898
+ })]
4899
+ }),
4900
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4901
+ className: GitHistoryPanel_module_default.commitHint,
4902
+ children: hint
4903
+ })
4904
+ ]
4905
+ })]
4434
4906
  })]
4435
4907
  });
4436
4908
  }
@@ -4507,7 +4979,7 @@ window.__ModuleLoader__.load({
4507
4979
  /** Data owner for the three sections. Remounts when `cwd` changes (the page
4508
4980
  * keys the mount by cwd), so no state crosses a repository boundary. */
4509
4981
  const GitHistoryPanelData = (0, react.forwardRef)(function GitHistoryPanelData(props, ref) {
4510
- const { cwd, model, t, pushToast } = props;
4982
+ const { cwd, model, t, pushToast, accelOn } = props;
4511
4983
  const [status, setStatus] = (0, react.useState)(null);
4512
4984
  const [statusError, setStatusError] = (0, react.useState)();
4513
4985
  const [changes, setChanges] = (0, react.useState)([]);
@@ -4572,16 +5044,20 @@ window.__ModuleLoader__.load({
4572
5044
  const refresh = (0, react.useCallback)(() => {
4573
5045
  loadAll();
4574
5046
  }, [loadAll]);
5047
+ (0, react.useEffect)(() => onGitMutated(refresh), [refresh]);
4575
5048
  (0, react.useImperativeHandle)(ref, () => ({ refresh }), [refresh]);
4576
5049
  const repo = status !== null && status.repo ? status : null;
4577
5050
  /** Run one mutating verb with the section-busy guard and error toast.
4578
5051
  * Mutations refresh through `loadAll` so their re-read bumps the request
4579
5052
  * sequence — an older in-flight snapshot can never land over the fresh
4580
- * post-mutation state. */
5053
+ * post-mutation state. A SUCCESS also emits the cross-surface notice so
5054
+ * the composer chip drops the branch git just left (stage toggles ride
5055
+ * along — one extra idempotent /status beats per-verb wiring). */
4581
5056
  const runGuarded = (0, react.useCallback)(async (verb) => {
4582
5057
  setSectionBusy(true);
4583
5058
  try {
4584
5059
  await verb();
5060
+ emitGitMutated();
4585
5061
  } catch (error) {
4586
5062
  pushToast(t("errorGeneric", { message: failureText(error) }), "error");
4587
5063
  } finally {
@@ -4697,13 +5173,23 @@ window.__ModuleLoader__.load({
4697
5173
  pushToast,
4698
5174
  t
4699
5175
  ]);
5176
+ /** Fetch/update failure toast text: the git failure line, plus the
5177
+ * mirror-unavailable hint while cn-accelerate is on (push is never
5178
+ * accelerated, so its failures stay hint-free). */
5179
+ const syncFailureText = (0, react.useCallback)((message) => {
5180
+ const generic = t("errorGeneric", { message });
5181
+ return accelOn() ? `${generic} ${t("accel.mirrorDownHint")}` : generic;
5182
+ }, [accelOn, t]);
4700
5183
  const onFetch = (0, react.useCallback)(() => {
4701
5184
  setSyncBusy(true);
4702
5185
  (async () => {
4703
5186
  try {
4704
5187
  const result = await requestFetch(cwd);
4705
- if (!result.ok) pushToast(t("errorGeneric", { message: result.error }), "error");
4706
- else pushToast(t("fetchDone"), "success");
5188
+ if (!result.ok) pushToast(syncFailureText(result.error), "error");
5189
+ else {
5190
+ pushToast(t("fetchDone"), "success");
5191
+ emitGitMutated();
5192
+ }
4707
5193
  await loadAll();
4708
5194
  } finally {
4709
5195
  setSyncBusy(false);
@@ -4713,6 +5199,7 @@ window.__ModuleLoader__.load({
4713
5199
  cwd,
4714
5200
  loadAll,
4715
5201
  pushToast,
5202
+ syncFailureText,
4716
5203
  t
4717
5204
  ]);
4718
5205
  const onUpdate = (0, react.useCallback)(() => {
@@ -4720,8 +5207,11 @@ window.__ModuleLoader__.load({
4720
5207
  (async () => {
4721
5208
  try {
4722
5209
  const result = await requestUpdate(cwd);
4723
- if (!result.ok) pushToast(t("errorGeneric", { message: result.error }), "error");
4724
- else pushToast(result.updated ? t("updateDone", { branch: result.branch }) : t("updateUpToDate"), "success");
5210
+ if (!result.ok) pushToast(syncFailureText(result.error), "error");
5211
+ else {
5212
+ pushToast(result.updated ? t("updateDone", { branch: result.branch }) : t("updateUpToDate"), "success");
5213
+ emitGitMutated();
5214
+ }
4725
5215
  await loadAll();
4726
5216
  } finally {
4727
5217
  setSyncBusy(false);
@@ -4731,6 +5221,7 @@ window.__ModuleLoader__.load({
4731
5221
  cwd,
4732
5222
  loadAll,
4733
5223
  pushToast,
5224
+ syncFailureText,
4734
5225
  t
4735
5226
  ]);
4736
5227
  const onPush = (0, react.useCallback)(() => {
@@ -4739,7 +5230,10 @@ window.__ModuleLoader__.load({
4739
5230
  try {
4740
5231
  const result = await requestPush(cwd);
4741
5232
  if (!result.ok) pushToast(t("errorGeneric", { message: result.error }), "error");
4742
- else pushToast(result.pushed ? t("pushDone", { branch: result.branch }) : t("pushUpToDate"), "success");
5233
+ else {
5234
+ pushToast(result.pushed ? t("pushDone", { branch: result.branch }) : t("pushUpToDate"), "success");
5235
+ emitGitMutated();
5236
+ }
4743
5237
  await loadAll();
4744
5238
  } finally {
4745
5239
  setSyncBusy(false);
@@ -4936,7 +5430,7 @@ window.__ModuleLoader__.load({
4936
5430
  /** The registered better-sidebar tab's content: chrome + data owner, keyed
4937
5431
  * by cwd so a session switch starts every section from scratch. */
4938
5432
  function GitPanelTab(props) {
4939
- const { ctx, scope, t } = props;
5433
+ const { ctx, scope, t, accel } = props;
4940
5434
  const subscribe = (0, react.useCallback)((listener) => ctx.sessions.list.subscribe(listener), [ctx]);
4941
5435
  const cwd = (0, react.useSyncExternalStore)(subscribe, () => scope.cwd ?? ctx.sessions.list.getSnapshot().byId[scope.sessionId]?.cwd);
4942
5436
  const model = (0, react.useSyncExternalStore)(subscribe, () => {
@@ -4955,6 +5449,13 @@ window.__ModuleLoader__.load({
4955
5449
  tone
4956
5450
  }]);
4957
5451
  }, []);
5452
+ const accelState = (0, react.useSyncExternalStore)(accel.store.subscribe, accel.store.getSnapshot);
5453
+ const [accelOpen, setAccelOpen] = (0, react.useState)(false);
5454
+ const accelOn = (0, react.useCallback)(() => accel.store.getSnapshot().enabled, [accel]);
5455
+ const closeAccel = (0, react.useCallback)(() => {
5456
+ accel.discardAccel();
5457
+ setAccelOpen(false);
5458
+ }, [accel]);
4958
5459
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4959
5460
  className: GitHistoryPanel_module_default.page,
4960
5461
  children: [
@@ -4966,9 +5467,35 @@ window.__ModuleLoader__.load({
4966
5467
  className: GitHistoryPanel_module_default.repoName,
4967
5468
  children: cwd
4968
5469
  })
4969
- }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5470
+ }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4970
5471
  className: GitHistoryPanel_module_default.topbarActions,
4971
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5472
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5473
+ className: GitHistoryPanel_module_default.cnWrap,
5474
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
5475
+ type: "button",
5476
+ className: accelState.enabled ? GitHistoryPanel_module_default.cnBtnOn : GitHistoryPanel_module_default.cnBtn,
5477
+ title: t("panel.cnAccelerate"),
5478
+ "aria-label": t("panel.cnAccelerate"),
5479
+ "aria-expanded": accelOpen,
5480
+ onClick: () => accelOpen ? closeAccel() : setAccelOpen(true),
5481
+ children: [
5482
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5483
+ "aria-hidden": "true",
5484
+ children: "⚡"
5485
+ }),
5486
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("panel.cnAccelerate") }),
5487
+ accelState.enabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5488
+ className: GitHistoryPanel_module_default.cnDot,
5489
+ "aria-hidden": "true"
5490
+ }) : null
5491
+ ]
5492
+ }), accelOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CnAcceleratePopover, {
5493
+ accel,
5494
+ t,
5495
+ pushToast,
5496
+ onClose: closeAccel
5497
+ }) : null]
5498
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4972
5499
  type: "button",
4973
5500
  className: GitHistoryPanel_module_default.refreshBtn,
4974
5501
  disabled: cwd === void 0,
@@ -4979,7 +5506,7 @@ window.__ModuleLoader__.load({
4979
5506
  size: 14,
4980
5507
  "aria-hidden": "true"
4981
5508
  })
4982
- })
5509
+ })]
4983
5510
  })]
4984
5511
  }),
4985
5512
  cwd === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -4990,7 +5517,8 @@ window.__ModuleLoader__.load({
4990
5517
  cwd,
4991
5518
  model,
4992
5519
  t,
4993
- pushToast
5520
+ pushToast,
5521
+ accelOn
4994
5522
  }, cwd),
4995
5523
  toasts.map((toast) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
4996
5524
  text: toast.text,
@@ -5598,7 +6126,7 @@ window.__ModuleLoader__.load({
5598
6126
  }
5599
6127
  //#endregion
5600
6128
  //#region \0git-worktree-css:/home/runner/work/dsh-git-branch/dsh-git-branch/src/client/GitWorktreeCard.module.css?inline
5601
- const css = "/* git-worktree bundle configuration on the Plugins page. The page owns the\n * chrome (title, icon, breadcrumb); this component renders either the\n * bundle-row summary line or the configuration form inside the page. Visual\n * language mirrors the settings section's own card chrome (layer fills,\n * footer buttons); tokens only, no literal colors. */\n\n/* The one-line preview on the bundle's row. */\n.summary_1281848784 {\n margin: 0;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n/* The configuration form inside the bundle's page. */\n.page_1281848784 {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.note_1281848784 {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.field_1281848784 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.fieldLabel_1281848784 {\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* The read-only legacy storage root: text (not an input — the location is\n * historical and cannot be edited) plus its \"unused\" state on one row. */\n.rootRow_1281848784 {\n display: flex;\n align-items: baseline;\n gap: 8px;\n min-width: 0;\n}\n\n.rootValue_1281848784 {\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n overflow-wrap: anywhere;\n}\n\n.rootUnused_1281848784 {\n flex: none;\n font-size: 11px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 4px;\n padding: 0 5px;\n}\n\n.hint_1281848784 {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.footer_1281848784 {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 0 4px;\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.failed_1281848784 {\n flex: 1;\n min-width: 0;\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-error);\n}\n\n.discard_1281848784,\n.save_1281848784 {\n appearance: none;\n border: 0.5px solid transparent;\n border-radius: 8px;\n padding: 5px 14px;\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n cursor: pointer;\n}\n\n.discard_1281848784 {\n border-color: var(--dsw-alias-border-l2);\n background: none;\n color: var(--dsw-alias-label-secondary);\n}\n\n.discard_1281848784:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n border-color: var(--dsw-alias-label-dimmed);\n}\n\n.save_1281848784 {\n background: var(--dsw-alias-label-primary);\n color: var(--dsw-alias-bg-layer-3);\n}\n\n.discard_1281848784:disabled,\n.save_1281848784:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n.discard_1281848784:focus-visible,\n.save_1281848784:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* Sidebar-grouping switch: title + hint + caution beside a checkbox. */\n.toggleRow_1281848784 {\n margin-top: 10px;\n flex-direction: row;\n align-items: flex-start;\n gap: 10px;\n}\n\n.toggleText_1281848784 {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.toggleLabel_1281848784 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n.toggleMark_1281848784 {\n margin-left: 4px;\n font-weight: 400;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.toggleHint_1281848784 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n line-height: 18px;\n}\n\n.toggleControl_1281848784 {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: none;\n margin-top: 2px;\n}\n\n.spinner_1281848784 {\n display: flex;\n color: var(--dsw-alias-label-tertiary);\n animation: spin 0.7s linear infinite;\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n\n.toggle_1281848784 {\n width: 16px;\n height: 16px;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n\n.toggle_1281848784:disabled {\n cursor: progress;\n}\n\n/* Manager entry row: title + hint on the left (the toggle rows' text\n * column), the launcher button on the right — the same posture as the\n * grouping switch, minus the checkbox. (.field_1281848784 is columnar; the row\n * direction is restated here.) */\n.manageRow_1281848784 {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.manage_1281848784 {\n appearance: none;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n background: none;\n font: inherit;\n font-size: 13px;\n color: var(--dsw-alias-label-primary);\n padding: 6px 12px;\n cursor: pointer;\n}\n\n.manage_1281848784:hover {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.manage_1281848784:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n/* Keep-cap row: the number input rides the toggle row's title column, and\n * stays disabled while the auto-prune switch is off (the cap means nothing\n * without the prune that enforces it). */\n.keepRow_1281848784 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.keepControl_1281848784 {\n display: flex;\n justify-content: flex-start;\n}\n\n.keepInput_1281848784 {\n width: 96px;\n appearance: none;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-2);\n font: inherit;\n font-size: 13px;\n color: var(--dsw-alias-label-primary);\n padding: 6px 10px;\n}\n\n.keepInput_1281848784:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n.keepInput_1281848784:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n\n.keepBad_1281848784 {\n font-size: 12px;\n color: var(--dsw-alias-label-danger, #d64545);\n}\n\n.copyFilesRow_1281848784 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.copyFilesInput_1281848784 {\n width: 100%;\n box-sizing: border-box;\n appearance: none;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-2);\n font: inherit;\n font-family: monospace;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n padding: 6px 10px;\n resize: vertical;\n min-height: 64px;\n}\n\n.copyFilesInput_1281848784:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n.copyFilesInput_1281848784:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n\n/* Write-through switches flip optimistically, so a rejected write shows up\n * as the control snapping back. This note sits in the switch's own text\n * column and says which one did not take. */\n.switchBad_1281848784 {\n font-size: 12px;\n line-height: 16px;\n color: var(--dsw-alias-label-danger, #d64545);\n}\n\n/* The auto-prune audit trail (清理记录): newest first, one run per line —\n * relative time, the removed directories with their belonging, then the\n * run's exceptions in the secondary tone. */\n.historyRow_1281848784 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.history_1281848784 {\n margin: 0;\n padding: 0;\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.historyRun_1281848784 {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 4px 8px;\n border: 0.5px solid color-mix(in srgb, currentColor 12%, transparent);\n border-radius: 6px;\n}\n\n.historyTime_1281848784 {\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n.historyLine_1281848784 {\n font-size: 12px;\n line-height: 16px;\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n/* The fold toggle. A link, not a button chrome: it reveals rows in place,\n * it does not act on anything. */\n.historyMore_1281848784 {\n align-self: flex-start;\n padding: 0;\n border: none;\n background: none;\n font: inherit;\n font-size: 12px;\n line-height: 16px;\n color: var(--dsw-alias-label-link, var(--dsw-alias-label-secondary));\n cursor: pointer;\n}\n\n.historyMore_1281848784:hover {\n text-decoration: underline;\n}\n";
6129
+ const css = "/* git-worktree bundle configuration on the Plugins page. The page owns the\n * chrome (title, icon, breadcrumb); this component renders either the\n * bundle-row summary line or the configuration form inside the page. Visual\n * language mirrors the settings section's own card chrome (layer fills,\n * footer buttons); tokens only, no literal colors. */\n\n/* The one-line preview on the bundle's row. */\n.summary_1281848784 {\n margin: 0;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n/* The configuration form inside the bundle's page. */\n.page_1281848784 {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.note_1281848784 {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.field_1281848784 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.fieldLabel_1281848784 {\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* The read-only legacy storage root: text (not an input — the location is\n * historical and cannot be edited) plus its \"unused\" state on one row. */\n.rootRow_1281848784 {\n display: flex;\n align-items: baseline;\n gap: 8px;\n min-width: 0;\n}\n\n.rootValue_1281848784 {\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n overflow-wrap: anywhere;\n}\n\n.rootUnused_1281848784 {\n flex: none;\n font-size: 11px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 4px;\n padding: 0 5px;\n}\n\n.hint_1281848784 {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.footer_1281848784 {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 0 4px;\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.failed_1281848784 {\n flex: 1;\n min-width: 0;\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-error);\n}\n\n.discard_1281848784,\n.save_1281848784 {\n appearance: none;\n border: 0.5px solid transparent;\n border-radius: 8px;\n padding: 5px 14px;\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n cursor: pointer;\n}\n\n.discard_1281848784 {\n border-color: var(--dsw-alias-border-l2);\n background: none;\n color: var(--dsw-alias-label-secondary);\n}\n\n.discard_1281848784:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n border-color: var(--dsw-alias-label-dimmed);\n}\n\n.save_1281848784 {\n background: var(--dsw-alias-label-primary);\n color: var(--dsw-alias-bg-layer-3);\n}\n\n.discard_1281848784:disabled,\n.save_1281848784:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n.discard_1281848784:focus-visible,\n.save_1281848784:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* Sidebar-grouping switch: title + hint + caution beside a checkbox. */\n.toggleRow_1281848784 {\n margin-top: 10px;\n flex-direction: row;\n align-items: flex-start;\n gap: 10px;\n}\n\n.toggleText_1281848784 {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.toggleLabel_1281848784 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n.toggleMark_1281848784 {\n margin-left: 4px;\n font-weight: 400;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.toggleHint_1281848784 {\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n line-height: 18px;\n}\n\n.toggleControl_1281848784 {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: none;\n margin-top: 2px;\n}\n\n.spinner_1281848784 {\n display: flex;\n color: var(--dsw-alias-label-tertiary);\n animation: spin 0.7s linear infinite;\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n\n.toggle_1281848784 {\n width: 16px;\n height: 16px;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n\n.toggle_1281848784:disabled {\n cursor: progress;\n}\n\n/* Manager entry row: title + hint on the left (the toggle rows' text\n * column), the launcher button on the right — the same posture as the\n * grouping switch, minus the checkbox. (.field_1281848784 is columnar; the row\n * direction is restated here.) */\n.manageRow_1281848784 {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.manage_1281848784 {\n appearance: none;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n background: none;\n font: inherit;\n font-size: 13px;\n color: var(--dsw-alias-label-primary);\n padding: 6px 12px;\n cursor: pointer;\n}\n\n.manage_1281848784:hover {\n border-color: var(--dsw-alias-brand-primary);\n}\n\n.manage_1281848784:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n/* Keep-cap row: the number input rides the toggle row's title column, and\n * stays disabled while the auto-prune switch is off (the cap means nothing\n * without the prune that enforces it). */\n.keepRow_1281848784 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.keepControl_1281848784 {\n display: flex;\n justify-content: flex-start;\n}\n\n.keepInput_1281848784 {\n width: 96px;\n appearance: none;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-2);\n font: inherit;\n font-size: 13px;\n color: var(--dsw-alias-label-primary);\n padding: 6px 10px;\n}\n\n.keepInput_1281848784:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n.keepInput_1281848784:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n\n.keepBad_1281848784 {\n font-size: 12px;\n color: var(--dsw-alias-label-danger, #d64545);\n}\n\n.copyFilesRow_1281848784 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.copyFilesInput_1281848784 {\n width: 100%;\n box-sizing: border-box;\n appearance: none;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-2);\n font: inherit;\n font-family: monospace;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n padding: 6px 10px;\n resize: vertical;\n min-height: 64px;\n}\n\n.copyFilesInput_1281848784:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n.copyFilesInput_1281848784:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n\n/* Cn-accelerate URL row: a single-line URL text field (the keep row's input\n * posture at full width). The invalid-draft line reuses .keepBad_1281848784. */\n.accelInput_1281848784 {\n width: 100%;\n box-sizing: border-box;\n appearance: none;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-2);\n font: inherit;\n font-family: monospace;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n padding: 6px 10px;\n}\n\n.accelInput_1281848784:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n.accelInput_1281848784:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n\n/* Write-through switches flip optimistically, so a rejected write shows up\n * as the control snapping back. This note sits in the switch's own text\n * column and says which one did not take. */\n.switchBad_1281848784 {\n font-size: 12px;\n line-height: 16px;\n color: var(--dsw-alias-label-danger, #d64545);\n}\n\n/* The auto-prune audit trail (清理记录): newest first, one run per line —\n * relative time, the removed directories with their belonging, then the\n * run's exceptions in the secondary tone. */\n.historyRow_1281848784 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.history_1281848784 {\n margin: 0;\n padding: 0;\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.historyRun_1281848784 {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 4px 8px;\n border: 0.5px solid color-mix(in srgb, currentColor 12%, transparent);\n border-radius: 6px;\n}\n\n.historyTime_1281848784 {\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n.historyLine_1281848784 {\n font-size: 12px;\n line-height: 16px;\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n/* The fold toggle. A link, not a button chrome: it reveals rows in place,\n * it does not act on anything. */\n.historyMore_1281848784 {\n align-self: flex-start;\n padding: 0;\n border: none;\n background: none;\n font: inherit;\n font-size: 12px;\n line-height: 16px;\n color: var(--dsw-alias-label-link, var(--dsw-alias-label-secondary));\n cursor: pointer;\n}\n\n.historyMore_1281848784:hover {\n text-decoration: underline;\n}\n";
5602
6130
  const tagId = "dsh-git-branch-manage/GitWorktreeCard.module.css";
5603
6131
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"" + tagId + "\"]") === null) {
5604
6132
  const tag = document.createElement("style");
@@ -5637,6 +6165,7 @@ window.__ModuleLoader__.load({
5637
6165
  "keepBad": "keepBad_1281848784",
5638
6166
  "copyFilesRow": "copyFilesRow_1281848784",
5639
6167
  "copyFilesInput": "copyFilesInput_1281848784",
6168
+ "accelInput": "accelInput_1281848784",
5640
6169
  "switchBad": "switchBad_1281848784",
5641
6170
  "historyRow": "historyRow_1281848784",
5642
6171
  "history": "history_1281848784",
@@ -5713,13 +6242,14 @@ window.__ModuleLoader__.load({
5713
6242
  const shownHistory = historyAll ? history : history.slice(0, HISTORY_PREVIEW);
5714
6243
  const { t } = props;
5715
6244
  const state = props.useGitWorktreeCard((snapshot) => snapshot);
6245
+ const accelState = props.useGitWorktreeAccel((snapshot) => snapshot);
5716
6246
  if (!state.available) return null;
5717
6247
  if (!onPage) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5718
6248
  className: GitWorktreeCard_module_default.summary,
5719
6249
  children: t("cardDescription")
5720
6250
  });
5721
6251
  const lockInput = !state.writable;
5722
- const lockActions = !state.dirty || state.saving || !state.keepWorktreesValid;
6252
+ const lockActions = !state.dirty && !accelState.dirty || state.saving || accelState.saving || !state.keepWorktreesValid || accelState.urlError !== null;
5723
6253
  const legacyRootText = storage?.legacyRoot ?? (state.rootDir === "" ? "—" : state.rootDir);
5724
6254
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5725
6255
  className: GitWorktreeCard_module_default.page,
@@ -5893,6 +6423,56 @@ window.__ModuleLoader__.load({
5893
6423
  })
5894
6424
  ]
5895
6425
  }),
6426
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
6427
+ className: `${GitWorktreeCard_module_default.field} ${GitWorktreeCard_module_default.toggleRow}`,
6428
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6429
+ className: GitWorktreeCard_module_default.toggleText,
6430
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6431
+ className: GitWorktreeCard_module_default.toggleLabel,
6432
+ children: t("panel.cnAccelerate")
6433
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6434
+ className: GitWorktreeCard_module_default.toggleHint,
6435
+ children: t("accel.hint")
6436
+ })]
6437
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6438
+ className: GitWorktreeCard_module_default.toggleControl,
6439
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
6440
+ className: GitWorktreeCard_module_default.toggle,
6441
+ type: "checkbox",
6442
+ disabled: lockInput || accelState.saving,
6443
+ checked: accelState.enabled,
6444
+ onChange: (event) => {
6445
+ props.setAccelEnabled(event.target.checked);
6446
+ }
6447
+ })
6448
+ })]
6449
+ }),
6450
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
6451
+ className: `${GitWorktreeCard_module_default.field} ${GitWorktreeCard_module_default.copyFilesRow}`,
6452
+ htmlFor: "git-worktree-card-accel-url",
6453
+ children: [
6454
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6455
+ className: GitWorktreeCard_module_default.fieldLabel,
6456
+ children: t("accel.urlLabel")
6457
+ }),
6458
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
6459
+ id: "git-worktree-card-accel-url",
6460
+ className: GitWorktreeCard_module_default.accelInput,
6461
+ type: "text",
6462
+ spellCheck: false,
6463
+ disabled: lockInput || accelState.saving,
6464
+ value: accelState.urlText,
6465
+ onChange: (event) => {
6466
+ props.editAccelUrl(event.target.value);
6467
+ }
6468
+ }),
6469
+ accelState.urlError !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6470
+ className: GitWorktreeCard_module_default.keepBad,
6471
+ role: "alert",
6472
+ children: accelState.urlError === "empty" ? t("accel.urlEmpty") : t("accel.urlInvalid")
6473
+ }) : null
6474
+ ]
6475
+ }),
5896
6476
  history.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5897
6477
  className: `${GitWorktreeCard_module_default.field} ${GitWorktreeCard_module_default.historyRow}`,
5898
6478
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -5959,19 +6539,30 @@ window.__ModuleLoader__.load({
5959
6539
  role: "status",
5960
6540
  children: t("cardSaveFailed")
5961
6541
  }) : null,
6542
+ accelState.failed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
6543
+ className: GitWorktreeCard_module_default.failed,
6544
+ role: "status",
6545
+ children: t("accel.saveFailed")
6546
+ }) : null,
5962
6547
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5963
6548
  type: "button",
5964
6549
  className: GitWorktreeCard_module_default.discard,
5965
6550
  disabled: lockActions,
5966
- onClick: props.discard,
6551
+ onClick: () => {
6552
+ props.discard();
6553
+ props.discardAccel();
6554
+ },
5967
6555
  children: t("cardDiscard")
5968
6556
  }),
5969
6557
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5970
6558
  type: "button",
5971
6559
  className: GitWorktreeCard_module_default.save,
5972
6560
  disabled: lockActions,
5973
- onClick: props.save,
5974
- children: t(state.saving ? "cardSaving" : "cardSave")
6561
+ onClick: () => {
6562
+ props.save();
6563
+ props.saveAccel();
6564
+ },
6565
+ children: t(state.saving || accelState.saving ? "cardSaving" : "cardSave")
5975
6566
  })
5976
6567
  ]
5977
6568
  })
@@ -6168,7 +6759,18 @@ window.__ModuleLoader__.load({
6168
6759
  "panel.stCopy": "copied",
6169
6760
  "panel.stType": "type changed",
6170
6761
  "panel.stUntrack": "untracked",
6171
- "panel.stUnmerged": "conflict"
6762
+ "panel.stUnmerged": "conflict",
6763
+ "panel.cnAccelerate": "China acceleration",
6764
+ "accel.enable": "Enable acceleration",
6765
+ "accel.hint": "Accelerates https github.com remotes for fetch/update only; push is never proxied. The mirror sees repository content — do not use it for private or sensitive repositories.",
6766
+ "accel.urlLabel": "Acceleration URL",
6767
+ "accel.restoreDefault": "Restore default",
6768
+ "accel.urlInvalid": "Enter an http(s):// URL",
6769
+ "accel.urlEmpty": "Enter an acceleration URL",
6770
+ "accel.saveFailed": "The change did not save. Try again.",
6771
+ "accel.savedOn": "China acceleration enabled: {url}",
6772
+ "accel.savedOff": "China acceleration disabled",
6773
+ "accel.mirrorDownHint": "If the mirror is down, disable acceleration or change the URL"
6172
6774
  };
6173
6775
  /** 中文词典。 */
6174
6776
  const zh = {
@@ -6358,7 +6960,18 @@ window.__ModuleLoader__.load({
6358
6960
  "panel.stCopy": "复制",
6359
6961
  "panel.stType": "类型变更",
6360
6962
  "panel.stUntrack": "未跟踪",
6361
- "panel.stUnmerged": "冲突"
6963
+ "panel.stUnmerged": "冲突",
6964
+ "panel.cnAccelerate": "国内加速",
6965
+ "accel.enable": "启用加速",
6966
+ "accel.hint": "仅加速 https 的 github.com 仓库地址,作用于提取/更新;推送不走加速。第三方加速站可看到仓库内容,请勿用于私有/敏感仓库。",
6967
+ "accel.urlLabel": "加速地址",
6968
+ "accel.restoreDefault": "恢复默认",
6969
+ "accel.urlInvalid": "请输入以 http(s):// 开头的地址",
6970
+ "accel.urlEmpty": "请输入加速地址",
6971
+ "accel.saveFailed": "保存未生效,请重试。",
6972
+ "accel.savedOn": "已启用国内加速:{url}",
6973
+ "accel.savedOff": "已关闭国内加速",
6974
+ "accel.mirrorDownHint": "若加速地址不可用,可停用国内加速或更换地址"
6362
6975
  };
6363
6976
  //#endregion
6364
6977
  //#region src/client/index.ts
@@ -6609,6 +7222,11 @@ window.__ModuleLoader__.load({
6609
7222
  });
6610
7223
  const form = new CardForm(settingsForm);
6611
7224
  const store = form.bind();
7225
+ const accelForm = new AccelForm(settingsForm);
7226
+ const accelFace = {
7227
+ store: accelForm.bind(),
7228
+ ...accelForm.actions()
7229
+ };
6612
7230
  const describeFace = ctx.configForms.describe();
6613
7231
  let configDisposer;
6614
7232
  const syncCardSeat = () => {
@@ -6619,8 +7237,12 @@ window.__ModuleLoader__.load({
6619
7237
  key: PLUGIN_PACKAGE,
6620
7238
  locale: NS,
6621
7239
  inject: () => ({
6622
- hooks: { gitWorktreeCard: store },
7240
+ hooks: {
7241
+ gitWorktreeCard: store,
7242
+ gitWorktreeAccel: accelFace.store
7243
+ },
6623
7244
  ...form.actions(),
7245
+ ...accelForm.actions(),
6624
7246
  manager: managerFace()
6625
7247
  })
6626
7248
  }, GitWorktreeCard));
@@ -6652,7 +7274,8 @@ window.__ModuleLoader__.load({
6652
7274
  component: (tabProps) => (0, react.createElement)(GitPanelTab, {
6653
7275
  ctx: betterCtx,
6654
7276
  scope: tabProps.scope,
6655
- t: panelT
7277
+ t: panelT,
7278
+ accel: accelFace
6656
7279
  })
6657
7280
  }), "git-worktree: better-sidebar tab");
6658
7281
  });