@norman-else/dsh-claude 0.1.26 → 0.1.28
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/bin.mjs +1 -1
- package/lib/client.d.ts +25 -6
- package/lib/client.js +477 -204
- package/lib/client.js.map +1 -1
- package/lib/{command-bridge-vyZoEeEO.mjs → command-bridge-BYj0VF4J.mjs} +2 -2
- package/lib/{command-bridge-vyZoEeEO.mjs.map → command-bridge-BYj0VF4J.mjs.map} +1 -1
- package/lib/{events-CY6V9oQ4.mjs → events-lDt9nTUw.mjs} +3 -2
- package/lib/events-lDt9nTUw.mjs.map +1 -0
- package/lib/index.d.mts +4 -0
- package/lib/index.mjs +207 -41
- package/lib/index.mjs.map +1 -1
- package/lib/{preset-installer-BMRaIHLu.mjs → preset-installer-CPOH9lAr.mjs} +2 -2
- package/lib/{preset-installer-BMRaIHLu.mjs.map → preset-installer-CPOH9lAr.mjs.map} +1 -1
- package/lib/preset-route.mjs +2 -2
- package/package.json +1 -1
- package/lib/events-CY6V9oQ4.mjs.map +0 -1
package/lib/client.js
CHANGED
|
@@ -12,6 +12,7 @@ window.__ModuleLoader__.load({
|
|
|
12
12
|
const TASK_TOOL_NAMES = /* @__PURE__ */ new Set(["Task", "Agent"]);
|
|
13
13
|
const CLAUDE_DOCTOR_PATH = "/plugins/dsh-claude/doctor";
|
|
14
14
|
const CLAUDE_UPDATE_CHECK_PATH = "/plugins/dsh-claude/update/check";
|
|
15
|
+
const CLAUDE_USAGE_PATH = "/plugins/dsh-claude/usage";
|
|
15
16
|
const CLAUDE_UPDATE_PATH = "/plugins/dsh-claude/update";
|
|
16
17
|
const CLAUDE_PROJECTION_PATH = "/plugins/dsh-claude/projection";
|
|
17
18
|
const CLAUDE_GLOBAL_SETTINGS_PATH = "/plugins/dsh-claude/settings/global";
|
|
@@ -713,6 +714,63 @@ window.__ModuleLoader__.load({
|
|
|
713
714
|
fontWeight: 700,
|
|
714
715
|
textAlign: "center"
|
|
715
716
|
};
|
|
717
|
+
const settingHint = {
|
|
718
|
+
display: "inline-grid",
|
|
719
|
+
placeItems: "center",
|
|
720
|
+
width: 14,
|
|
721
|
+
height: 14,
|
|
722
|
+
marginLeft: 6,
|
|
723
|
+
verticalAlign: "text-top",
|
|
724
|
+
borderRadius: "50%",
|
|
725
|
+
border: "1px solid currentColor",
|
|
726
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
727
|
+
fontSize: 9,
|
|
728
|
+
fontWeight: 600,
|
|
729
|
+
lineHeight: 1,
|
|
730
|
+
cursor: "help",
|
|
731
|
+
userSelect: "none"
|
|
732
|
+
};
|
|
733
|
+
const planUsageMeter = {
|
|
734
|
+
display: "flex",
|
|
735
|
+
alignItems: "center",
|
|
736
|
+
gap: 10,
|
|
737
|
+
minWidth: 0
|
|
738
|
+
};
|
|
739
|
+
const planUsageTrack = {
|
|
740
|
+
flex: "1 1 auto",
|
|
741
|
+
height: 6,
|
|
742
|
+
minWidth: 60,
|
|
743
|
+
borderRadius: 3,
|
|
744
|
+
background: "var(--dsw-alias-bg-layer-2)",
|
|
745
|
+
overflow: "hidden"
|
|
746
|
+
};
|
|
747
|
+
const planUsageFill = {
|
|
748
|
+
display: "block",
|
|
749
|
+
height: "100%",
|
|
750
|
+
borderRadius: 3,
|
|
751
|
+
transition: "width 200ms ease"
|
|
752
|
+
};
|
|
753
|
+
const planUsageMeta = {
|
|
754
|
+
flex: "0 0 auto",
|
|
755
|
+
fontSize: 12,
|
|
756
|
+
whiteSpace: "nowrap"
|
|
757
|
+
};
|
|
758
|
+
/** Bar colour, plus a matching text colour once a window is worth noticing.
|
|
759
|
+
* Below the warning threshold the reading stays quiet: accent bar, muted text. */
|
|
760
|
+
function planUsageTone(utilization) {
|
|
761
|
+
if (utilization !== void 0 && utilization >= 90) return {
|
|
762
|
+
fill: "var(--dsw-alias-state-error-primary)",
|
|
763
|
+
text: "var(--dsw-alias-state-error-primary)"
|
|
764
|
+
};
|
|
765
|
+
if (utilization !== void 0 && utilization >= 75) return {
|
|
766
|
+
fill: "var(--dsw-alias-state-warning-primary, #d69e2e)",
|
|
767
|
+
text: "var(--dsw-alias-state-warning-primary, #d69e2e)"
|
|
768
|
+
};
|
|
769
|
+
return {
|
|
770
|
+
fill: utilization === void 0 ? "transparent" : "var(--dsw-static-blue-450)",
|
|
771
|
+
text: "var(--dsw-alias-label-tertiary)"
|
|
772
|
+
};
|
|
773
|
+
}
|
|
716
774
|
const settingsActions = {
|
|
717
775
|
display: "flex",
|
|
718
776
|
flexWrap: "wrap",
|
|
@@ -2317,8 +2375,11 @@ window.__ModuleLoader__.load({
|
|
|
2317
2375
|
flex: none;
|
|
2318
2376
|
display: grid;
|
|
2319
2377
|
place-items: center;
|
|
2320
|
-
|
|
2321
|
-
|
|
2378
|
+
/* Stay on the line-number row: a wrapped line makes the flex row taller, and
|
|
2379
|
+
centering would float the button into the middle of the wrapped block.
|
|
2380
|
+
The margin centers the 18px button inside the first 22px line box. */
|
|
2381
|
+
align-self: flex-start;
|
|
2382
|
+
margin: 2px 2px 0;
|
|
2322
2383
|
padding: 0;
|
|
2323
2384
|
border: none;
|
|
2324
2385
|
border-radius: 4px;
|
|
@@ -2773,19 +2834,21 @@ window.__ModuleLoader__.load({
|
|
|
2773
2834
|
background: var(--dsw-alias-bg-layer-2);
|
|
2774
2835
|
}
|
|
2775
2836
|
.dshClaudeRepositoryActionModalContent h2 {
|
|
2776
|
-
font-size:
|
|
2777
|
-
line-height:
|
|
2837
|
+
font-size: 18px;
|
|
2838
|
+
line-height: 26px;
|
|
2778
2839
|
}
|
|
2779
2840
|
.dshClaudeRepositoryActionModalContent > p {
|
|
2780
|
-
font-size:
|
|
2781
|
-
line-height:
|
|
2841
|
+
font-size: 14px;
|
|
2842
|
+
line-height: 22px;
|
|
2782
2843
|
}
|
|
2783
|
-
.dshClaudeRepositoryActionModal input[type='checkbox'] {
|
|
2784
|
-
width:
|
|
2785
|
-
height:
|
|
2844
|
+
.dshClaudeRepositoryActionModal input:is([type='checkbox'], [type='radio']) {
|
|
2845
|
+
width: 16px;
|
|
2846
|
+
height: 16px;
|
|
2847
|
+
margin: 0;
|
|
2848
|
+
accent-color: var(--dsw-static-blue-450);
|
|
2786
2849
|
}
|
|
2787
2850
|
.dshClaudeRepositoryActionModal textarea:focus,
|
|
2788
|
-
.dshClaudeRepositoryActionModal input:not([type='checkbox']):focus {
|
|
2851
|
+
.dshClaudeRepositoryActionModal input:not([type='checkbox'], [type='radio']):focus {
|
|
2789
2852
|
outline: none;
|
|
2790
2853
|
box-shadow: inset 0 0 0 1px var(--dsw-static-blue-450);
|
|
2791
2854
|
}
|
|
@@ -2804,8 +2867,8 @@ window.__ModuleLoader__.load({
|
|
|
2804
2867
|
gap: 16,
|
|
2805
2868
|
minWidth: 0,
|
|
2806
2869
|
color: "var(--dsw-alias-label-secondary)",
|
|
2807
|
-
fontSize:
|
|
2808
|
-
lineHeight: "
|
|
2870
|
+
fontSize: 14,
|
|
2871
|
+
lineHeight: "22px"
|
|
2809
2872
|
};
|
|
2810
2873
|
const diffModalMetaText = {
|
|
2811
2874
|
minWidth: 0,
|
|
@@ -2829,8 +2892,8 @@ window.__ModuleLoader__.load({
|
|
|
2829
2892
|
padding: "10px 14px",
|
|
2830
2893
|
borderBottom: "1px solid var(--dsw-alias-border-l2, color-mix(in srgb, currentColor 16%, transparent))",
|
|
2831
2894
|
color: "var(--dsw-alias-label-secondary)",
|
|
2832
|
-
fontSize:
|
|
2833
|
-
lineHeight: "
|
|
2895
|
+
fontSize: 13,
|
|
2896
|
+
lineHeight: "20px"
|
|
2834
2897
|
};
|
|
2835
2898
|
const diffModalFilePath = {
|
|
2836
2899
|
minWidth: 0,
|
|
@@ -2844,32 +2907,32 @@ window.__ModuleLoader__.load({
|
|
|
2844
2907
|
flexDirection: "column",
|
|
2845
2908
|
gap: 8,
|
|
2846
2909
|
color: "var(--dsw-alias-label-secondary)",
|
|
2847
|
-
fontSize:
|
|
2848
|
-
lineHeight: "
|
|
2910
|
+
fontSize: 14,
|
|
2911
|
+
lineHeight: "22px",
|
|
2849
2912
|
fontWeight: 550
|
|
2850
2913
|
};
|
|
2851
2914
|
const diffModalTextarea = {
|
|
2852
2915
|
...settingTextInput,
|
|
2853
2916
|
minHeight: 140,
|
|
2854
2917
|
padding: "10px 14px",
|
|
2855
|
-
fontSize:
|
|
2856
|
-
lineHeight: "
|
|
2918
|
+
fontSize: 14,
|
|
2919
|
+
lineHeight: "22px",
|
|
2857
2920
|
resize: "vertical"
|
|
2858
2921
|
};
|
|
2859
2922
|
const diffModalTextInput = {
|
|
2860
2923
|
...settingTextInput,
|
|
2861
2924
|
minHeight: 44,
|
|
2862
2925
|
padding: "9px 14px",
|
|
2863
|
-
fontSize:
|
|
2864
|
-
lineHeight: "
|
|
2926
|
+
fontSize: 14,
|
|
2927
|
+
lineHeight: "22px"
|
|
2865
2928
|
};
|
|
2866
2929
|
const diffModalCheckbox = {
|
|
2867
2930
|
display: "flex",
|
|
2868
2931
|
alignItems: "center",
|
|
2869
2932
|
gap: 10,
|
|
2870
2933
|
color: "var(--dsw-alias-label-secondary)",
|
|
2871
|
-
fontSize:
|
|
2872
|
-
lineHeight: "
|
|
2934
|
+
fontSize: 14,
|
|
2935
|
+
lineHeight: "22px"
|
|
2873
2936
|
};
|
|
2874
2937
|
const diffModalFooter = {
|
|
2875
2938
|
display: "flex",
|
|
@@ -2877,28 +2940,28 @@ window.__ModuleLoader__.load({
|
|
|
2877
2940
|
gap: 12
|
|
2878
2941
|
};
|
|
2879
2942
|
const diffModalButton = {
|
|
2880
|
-
minHeight:
|
|
2943
|
+
minHeight: 36,
|
|
2881
2944
|
padding: "8px 18px",
|
|
2882
|
-
fontSize:
|
|
2883
|
-
lineHeight: "
|
|
2945
|
+
fontSize: 14,
|
|
2946
|
+
lineHeight: "22px"
|
|
2884
2947
|
};
|
|
2885
2948
|
const diffModalStatus = {
|
|
2886
2949
|
margin: 0,
|
|
2887
2950
|
color: "var(--dsw-alias-label-secondary)",
|
|
2888
|
-
fontSize:
|
|
2889
|
-
lineHeight: "
|
|
2951
|
+
fontSize: 14,
|
|
2952
|
+
lineHeight: "22px"
|
|
2890
2953
|
};
|
|
2891
2954
|
const diffModalError = {
|
|
2892
2955
|
margin: "10px 0 0",
|
|
2893
2956
|
color: "var(--dsw-alias-state-error-primary)",
|
|
2894
|
-
fontSize:
|
|
2895
|
-
lineHeight: "
|
|
2957
|
+
fontSize: 14,
|
|
2958
|
+
lineHeight: "22px"
|
|
2896
2959
|
};
|
|
2897
2960
|
const diffModalSuccess = {
|
|
2898
2961
|
margin: 0,
|
|
2899
2962
|
color: "var(--dsw-alias-state-success-primary)",
|
|
2900
|
-
fontSize:
|
|
2901
|
-
lineHeight: "
|
|
2963
|
+
fontSize: 14,
|
|
2964
|
+
lineHeight: "22px"
|
|
2902
2965
|
};
|
|
2903
2966
|
//#endregion
|
|
2904
2967
|
//#region src/client/token-format.ts
|
|
@@ -4418,6 +4481,183 @@ window.__ModuleLoader__.load({
|
|
|
4418
4481
|
}) : null]
|
|
4419
4482
|
});
|
|
4420
4483
|
}
|
|
4484
|
+
/** Fixed windows carry a translated label; server-named model buckets (e.g.
|
|
4485
|
+
* 'Fable') arrive with their own `label` and are shown verbatim. */
|
|
4486
|
+
const TRANSLATED_WINDOWS = /* @__PURE__ */ new Set([
|
|
4487
|
+
"five_hour",
|
|
4488
|
+
"seven_day",
|
|
4489
|
+
"seven_day_opus",
|
|
4490
|
+
"seven_day_sonnet"
|
|
4491
|
+
]);
|
|
4492
|
+
/** Per-setting label and the effect note that used to sit as a standalone
|
|
4493
|
+
* paragraph under the card; it now hangs off the label as a hover hint. */
|
|
4494
|
+
const SETTING_COPY = {
|
|
4495
|
+
outputStyle: {
|
|
4496
|
+
label: "outputStyle",
|
|
4497
|
+
hint: "globalSettingsNewSession"
|
|
4498
|
+
},
|
|
4499
|
+
worktreeBranchPrefix: {
|
|
4500
|
+
label: "worktreeBranchPrefix",
|
|
4501
|
+
hint: "worktreeBranchPrefixEffect"
|
|
4502
|
+
},
|
|
4503
|
+
maxProcesses: {
|
|
4504
|
+
label: "maxProcessesSetting",
|
|
4505
|
+
hint: "maxProcessesEffect"
|
|
4506
|
+
},
|
|
4507
|
+
idleTimeoutMinutes: {
|
|
4508
|
+
label: "idleTimeoutSetting",
|
|
4509
|
+
hint: "idleTimeoutEffect"
|
|
4510
|
+
}
|
|
4511
|
+
};
|
|
4512
|
+
/** '?' badge that reveals a setting's effect note on hover or keyboard focus. */
|
|
4513
|
+
function SettingHint({ text, label }) {
|
|
4514
|
+
return /* @__PURE__ */ jsx(Tooltip, {
|
|
4515
|
+
label: text,
|
|
4516
|
+
side: "top",
|
|
4517
|
+
delayMs: 150,
|
|
4518
|
+
maxWidth: 320,
|
|
4519
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
4520
|
+
role: "note",
|
|
4521
|
+
tabIndex: 0,
|
|
4522
|
+
"aria-label": `${label}: ${text}`,
|
|
4523
|
+
style: settingHint,
|
|
4524
|
+
children: "?"
|
|
4525
|
+
})
|
|
4526
|
+
});
|
|
4527
|
+
}
|
|
4528
|
+
function isPlanUsageReport(value) {
|
|
4529
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
4530
|
+
const report = value;
|
|
4531
|
+
return typeof report.available === "boolean" && typeof report.fetchedAt === "number" && Array.isArray(report.windows) && report.windows.every((entry) => typeof entry === "object" && entry !== null && typeof entry.id === "string");
|
|
4532
|
+
}
|
|
4533
|
+
/** Coarse duration for a reset countdown or a fetch age: minutes below an
|
|
4534
|
+
* hour, then hours, then days. Never negative — a passed reset reads '0m'. */
|
|
4535
|
+
function durationLabel(milliseconds) {
|
|
4536
|
+
const minutes = Math.max(0, Math.round(milliseconds / 6e4));
|
|
4537
|
+
if (minutes < 60) return `${minutes}m`;
|
|
4538
|
+
const hours = Math.floor(minutes / 60);
|
|
4539
|
+
if (hours < 24) return minutes % 60 === 0 ? `${hours}h` : `${hours}h ${minutes % 60}m`;
|
|
4540
|
+
return `${Math.floor(hours / 24)}d`;
|
|
4541
|
+
}
|
|
4542
|
+
function PlanUsageMeter({ window: usageWindow, t, now }) {
|
|
4543
|
+
const used = usageWindow.utilization;
|
|
4544
|
+
const tone = planUsageTone(used);
|
|
4545
|
+
const resetsIn = usageWindow.resetsAt === void 0 ? void 0 : Date.parse(usageWindow.resetsAt);
|
|
4546
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
4547
|
+
style: planUsageMeter,
|
|
4548
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
4549
|
+
style: planUsageTrack,
|
|
4550
|
+
children: /* @__PURE__ */ jsx("span", { style: {
|
|
4551
|
+
...planUsageFill,
|
|
4552
|
+
width: `${used ?? 0}%`,
|
|
4553
|
+
background: tone.fill
|
|
4554
|
+
} })
|
|
4555
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
4556
|
+
style: {
|
|
4557
|
+
...planUsageMeta,
|
|
4558
|
+
color: tone.text
|
|
4559
|
+
},
|
|
4560
|
+
children: [used === void 0 ? "—" : t("planUsageUsed", { percent: Math.round(used) }), resetsIn === void 0 || !Number.isFinite(resetsIn) ? null : ` · ${t("planUsageResets", { age: durationLabel(resetsIn - now) })}`]
|
|
4561
|
+
})]
|
|
4562
|
+
});
|
|
4563
|
+
}
|
|
4564
|
+
/** Fetch the plan usage report; POST forces the backend to re-read it. */
|
|
4565
|
+
async function loadPlanUsage(refresh) {
|
|
4566
|
+
const response = await fetch(CLAUDE_USAGE_PATH, {
|
|
4567
|
+
method: refresh ? "POST" : "GET",
|
|
4568
|
+
credentials: "same-origin",
|
|
4569
|
+
headers: { accept: "application/json" }
|
|
4570
|
+
});
|
|
4571
|
+
const payload = await response.json();
|
|
4572
|
+
if (!response.ok) {
|
|
4573
|
+
const message = typeof payload === "object" && payload !== null && "error" in payload && typeof payload.error === "string" ? payload.error : `HTTP ${response.status}`;
|
|
4574
|
+
throw new Error(message);
|
|
4575
|
+
}
|
|
4576
|
+
if (!isPlanUsageReport(payload)) throw new Error("Invalid plan usage response");
|
|
4577
|
+
return payload;
|
|
4578
|
+
}
|
|
4579
|
+
function PlanUsageCard({ t, load }) {
|
|
4580
|
+
const [report, setReport] = useState();
|
|
4581
|
+
const [busy, setBusy] = useState(false);
|
|
4582
|
+
const [error, setError] = useState();
|
|
4583
|
+
const request = useCallback(async (refresh) => {
|
|
4584
|
+
setBusy(true);
|
|
4585
|
+
setError(void 0);
|
|
4586
|
+
try {
|
|
4587
|
+
setReport(await load(refresh));
|
|
4588
|
+
} catch (cause) {
|
|
4589
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
4590
|
+
} finally {
|
|
4591
|
+
setBusy(false);
|
|
4592
|
+
}
|
|
4593
|
+
}, [load]);
|
|
4594
|
+
useEffect(() => {
|
|
4595
|
+
request(false);
|
|
4596
|
+
}, [request]);
|
|
4597
|
+
const now = Date.now();
|
|
4598
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
4599
|
+
style: settingsCard,
|
|
4600
|
+
children: [
|
|
4601
|
+
/* @__PURE__ */ jsxs("div", {
|
|
4602
|
+
style: settingsCardHeader,
|
|
4603
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", {
|
|
4604
|
+
style: settingsSectionHeading,
|
|
4605
|
+
children: t("planUsage")
|
|
4606
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
4607
|
+
style: settingsBody,
|
|
4608
|
+
children: t("planUsageBody")
|
|
4609
|
+
})] }), /* @__PURE__ */ jsx("button", {
|
|
4610
|
+
type: "button",
|
|
4611
|
+
style: button,
|
|
4612
|
+
disabled: busy,
|
|
4613
|
+
onClick: () => {
|
|
4614
|
+
request(true);
|
|
4615
|
+
},
|
|
4616
|
+
children: busy ? t("planUsageRefreshing") : t("planUsageRefresh")
|
|
4617
|
+
})]
|
|
4618
|
+
}),
|
|
4619
|
+
report === void 0 ? /* @__PURE__ */ jsx("p", {
|
|
4620
|
+
style: notice,
|
|
4621
|
+
children: busy ? t("planUsageLoading") : t("planUsageNever")
|
|
4622
|
+
}) : report.windows.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
4623
|
+
style: notice,
|
|
4624
|
+
children: report.fetchedAt === 0 ? t("planUsageNever") : t("planUsageUnavailable")
|
|
4625
|
+
}) : /* @__PURE__ */ jsxs("div", {
|
|
4626
|
+
style: diagnosticGrid,
|
|
4627
|
+
children: [report.subscription === void 0 ? null : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
|
|
4628
|
+
style: diagnosticLabel,
|
|
4629
|
+
children: t("planUsageSubscription")
|
|
4630
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
4631
|
+
style: diagnosticValue,
|
|
4632
|
+
children: report.subscription
|
|
4633
|
+
})] }), report.windows.flatMap((usageWindow) => [/* @__PURE__ */ jsx("span", {
|
|
4634
|
+
style: diagnosticLabel,
|
|
4635
|
+
children: usageWindow.label ?? (TRANSLATED_WINDOWS.has(usageWindow.id) ? t(`planWindow_${usageWindow.id}`) : usageWindow.id)
|
|
4636
|
+
}, `${usageWindow.id}-label`), /* @__PURE__ */ jsx(PlanUsageMeter, {
|
|
4637
|
+
window: usageWindow,
|
|
4638
|
+
t,
|
|
4639
|
+
now
|
|
4640
|
+
}, `${usageWindow.id}-meter`)])]
|
|
4641
|
+
}),
|
|
4642
|
+
report !== void 0 && report.fetchedAt > 0 ? /* @__PURE__ */ jsx("p", {
|
|
4643
|
+
style: notice,
|
|
4644
|
+
children: t("planUsageUpdated", { age: durationLabel(now - report.fetchedAt) })
|
|
4645
|
+
}) : null,
|
|
4646
|
+
error === void 0 ? null : /* @__PURE__ */ jsxs("p", {
|
|
4647
|
+
role: "alert",
|
|
4648
|
+
style: {
|
|
4649
|
+
...notice,
|
|
4650
|
+
color: "var(--dsw-alias-state-error-primary)"
|
|
4651
|
+
},
|
|
4652
|
+
children: [
|
|
4653
|
+
t("planUsageError"),
|
|
4654
|
+
": ",
|
|
4655
|
+
error
|
|
4656
|
+
]
|
|
4657
|
+
})
|
|
4658
|
+
]
|
|
4659
|
+
});
|
|
4660
|
+
}
|
|
4421
4661
|
function ClaudeCodeSettings({ t }) {
|
|
4422
4662
|
const [report, setReport] = useState();
|
|
4423
4663
|
const [error, setError] = useState();
|
|
@@ -4622,6 +4862,10 @@ window.__ModuleLoader__.load({
|
|
|
4622
4862
|
})
|
|
4623
4863
|
]
|
|
4624
4864
|
}),
|
|
4865
|
+
/* @__PURE__ */ jsx(PlanUsageCard, {
|
|
4866
|
+
t,
|
|
4867
|
+
load: loadPlanUsage
|
|
4868
|
+
}),
|
|
4625
4869
|
/* @__PURE__ */ jsxs("section", {
|
|
4626
4870
|
style: settingsCard,
|
|
4627
4871
|
children: [
|
|
@@ -4635,37 +4879,31 @@ window.__ModuleLoader__.load({
|
|
|
4635
4879
|
globalSettings === void 0 ? /* @__PURE__ */ jsx("p", {
|
|
4636
4880
|
style: notice,
|
|
4637
4881
|
children: t("globalSettingsLoading")
|
|
4638
|
-
}) : globalSettings.settings.map((setting) =>
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
style:
|
|
4642
|
-
children:
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
}
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
}
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
children: t("worktreeBranchPrefixEffect")
|
|
4664
|
-
}) : null,
|
|
4665
|
-
globalSettings?.settings.some((setting) => setting.key === "maxProcesses") === true ? /* @__PURE__ */ jsx("p", {
|
|
4666
|
-
style: notice,
|
|
4667
|
-
children: t("limitsSettingEffect")
|
|
4668
|
-
}) : null,
|
|
4882
|
+
}) : globalSettings.settings.map((setting) => {
|
|
4883
|
+
const copy = SETTING_COPY[setting.key];
|
|
4884
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
4885
|
+
style: diagnosticGrid,
|
|
4886
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
4887
|
+
style: diagnosticLabel,
|
|
4888
|
+
children: [copy === void 0 ? setting.key : t(copy.label), copy === void 0 ? null : /* @__PURE__ */ jsx(SettingHint, {
|
|
4889
|
+
text: t(copy.hint),
|
|
4890
|
+
label: t("settingHint")
|
|
4891
|
+
})]
|
|
4892
|
+
}), setting.kind === "select" ? /* @__PURE__ */ jsx(GlobalSettingSelect, {
|
|
4893
|
+
setting,
|
|
4894
|
+
disabled: globalSettingsBusy,
|
|
4895
|
+
onChange: (nextValue) => {
|
|
4896
|
+
requestGlobalSettings({ [setting.key]: nextValue });
|
|
4897
|
+
}
|
|
4898
|
+
}) : /* @__PURE__ */ jsx(GlobalSettingText, {
|
|
4899
|
+
setting,
|
|
4900
|
+
disabled: globalSettingsBusy,
|
|
4901
|
+
onChange: (nextValue) => {
|
|
4902
|
+
requestGlobalSettings({ [setting.key]: nextValue });
|
|
4903
|
+
}
|
|
4904
|
+
})]
|
|
4905
|
+
}, setting.key);
|
|
4906
|
+
}),
|
|
4669
4907
|
globalSettingsError === void 0 ? null : /* @__PURE__ */ jsxs("p", {
|
|
4670
4908
|
role: "alert",
|
|
4671
4909
|
style: {
|
|
@@ -5017,12 +5255,15 @@ window.__ModuleLoader__.load({
|
|
|
5017
5255
|
}
|
|
5018
5256
|
return body;
|
|
5019
5257
|
}
|
|
5258
|
+
/** A wedged host must surface as an error; the hero has no other way out of its loading state. */
|
|
5259
|
+
const BRANCH_LOAD_TIMEOUT_MS = 15e3;
|
|
5020
5260
|
function loadRepositoryBranches(cwd, signal) {
|
|
5261
|
+
const timeout = AbortSignal.timeout(BRANCH_LOAD_TIMEOUT_MS);
|
|
5021
5262
|
return response(fetch(`${CLAUDE_REPOSITORY_SETUP_PATH}/branches?cwd=${encodeURIComponent(cwd)}`, {
|
|
5022
5263
|
method: "GET",
|
|
5023
5264
|
credentials: "same-origin",
|
|
5024
5265
|
headers: { accept: "application/json" },
|
|
5025
|
-
|
|
5266
|
+
signal: signal === void 0 ? timeout : AbortSignal.any([signal, timeout])
|
|
5026
5267
|
}));
|
|
5027
5268
|
}
|
|
5028
5269
|
async function prepareRepository(cwd, branch, worktree, branchName, onProgress = () => {}) {
|
|
@@ -5173,8 +5414,10 @@ window.__ModuleLoader__.load({
|
|
|
5173
5414
|
}).join("\n\n")}`;
|
|
5174
5415
|
}
|
|
5175
5416
|
/** Draft handed to Claude after an update-branch merge left conflicts behind. */
|
|
5176
|
-
function composeConflictsPrompt(baseBranch, conflicts) {
|
|
5177
|
-
|
|
5417
|
+
function composeConflictsPrompt(baseBranch, conflicts, method = "merge") {
|
|
5418
|
+
const list = conflicts.map((file) => `- ${file}`).join("\n");
|
|
5419
|
+
if (method === "rebase") return `Rebasing the current branch onto origin/${baseBranch} stopped on conflicts in the files below. Resolve each conflict preserving the intent of both sides, stage the files, run \`git rebase --continue\` until the rebase finishes, then push with \`git push --force-with-lease\`.\n\n${list}`;
|
|
5420
|
+
return `Merging origin/${baseBranch} into the current branch left merge conflicts in the files below. Resolve each conflict preserving the intent of both sides, then commit the merge.\n\n${list}`;
|
|
5178
5421
|
}
|
|
5179
5422
|
//#endregion
|
|
5180
5423
|
//#region src/client/auto-fix.ts
|
|
@@ -5229,32 +5472,6 @@ window.__ModuleLoader__.load({
|
|
|
5229
5472
|
}
|
|
5230
5473
|
//#endregion
|
|
5231
5474
|
//#region src/client/ClaudeRepositoryStatus.tsx
|
|
5232
|
-
const RATE_LIMIT_TITLE_PREFIX = "Claude rate limit";
|
|
5233
|
-
const RATE_LIMIT_BLOCKING_TITLE = "Claude rate limit is blocking requests";
|
|
5234
|
-
/** Whether the newest quota update in the activity feed reports a blocked state. */
|
|
5235
|
-
function rateLimitBlocked(activities) {
|
|
5236
|
-
for (let index = activities.length - 1; index >= 0; index -= 1) {
|
|
5237
|
-
const title = activities[index]?.title;
|
|
5238
|
-
if (title?.startsWith(RATE_LIMIT_TITLE_PREFIX) === true) return title === RATE_LIMIT_BLOCKING_TITLE;
|
|
5239
|
-
}
|
|
5240
|
-
return false;
|
|
5241
|
-
}
|
|
5242
|
-
function StatusItem({ label, tone = "neutral" }) {
|
|
5243
|
-
const toneStyle = tone === "success" ? repositoryItemSuccess : tone === "warning" ? repositoryItemWarning : tone === "error" ? repositoryItemError : {};
|
|
5244
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
5245
|
-
style: {
|
|
5246
|
-
...repositoryItem,
|
|
5247
|
-
...toneStyle
|
|
5248
|
-
},
|
|
5249
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
5250
|
-
style: repositoryItemDot,
|
|
5251
|
-
"aria-hidden": "true"
|
|
5252
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
5253
|
-
style: repositoryItemLabel,
|
|
5254
|
-
children: label
|
|
5255
|
-
})]
|
|
5256
|
-
});
|
|
5257
|
-
}
|
|
5258
5475
|
/** Icon-only status: the tone carries the state, the full label lives in the tooltip and accessible name. */
|
|
5259
5476
|
function StatusGlyph({ label, tone, children }) {
|
|
5260
5477
|
const toneStyle = tone === "success" ? repositoryItemSuccess : tone === "warning" ? repositoryItemWarning : tone === "error" ? repositoryItemError : {};
|
|
@@ -5695,6 +5912,7 @@ window.__ModuleLoader__.load({
|
|
|
5695
5912
|
}
|
|
5696
5913
|
function UpdateBranchControl({ sessionId, repository, t, submitPrompt }) {
|
|
5697
5914
|
const [dialog, setDialog] = useState();
|
|
5915
|
+
const [method, setMethod] = useState("rebase");
|
|
5698
5916
|
const controller = useRef();
|
|
5699
5917
|
const pullRequest = repository.pullRequest;
|
|
5700
5918
|
const base = pullRequest?.baseBranch;
|
|
@@ -5746,7 +5964,8 @@ window.__ModuleLoader__.load({
|
|
|
5746
5964
|
fingerprint: dialog.fingerprint,
|
|
5747
5965
|
message: "",
|
|
5748
5966
|
includeUnstaged: false,
|
|
5749
|
-
baseBranch: base
|
|
5967
|
+
baseBranch: base,
|
|
5968
|
+
mergeMethod: method
|
|
5750
5969
|
}).then((result) => {
|
|
5751
5970
|
setDialog({
|
|
5752
5971
|
...pending,
|
|
@@ -5829,6 +6048,17 @@ window.__ModuleLoader__.load({
|
|
|
5829
6048
|
})
|
|
5830
6049
|
})]
|
|
5831
6050
|
}),
|
|
6051
|
+
["rebase", "merge"].map((option) => /* @__PURE__ */ jsxs("label", {
|
|
6052
|
+
style: diffModalCheckbox,
|
|
6053
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
6054
|
+
type: "radio",
|
|
6055
|
+
name: "dsh-claude-update-branch-method",
|
|
6056
|
+
value: option,
|
|
6057
|
+
checked: method === option,
|
|
6058
|
+
disabled: settled || dialog.submitting,
|
|
6059
|
+
onChange: () => setMethod(option)
|
|
6060
|
+
}), t(`diffUpdateBranch_${option}`, { base })]
|
|
6061
|
+
}, option)),
|
|
5832
6062
|
dialog.pushed === void 0 ? null : /* @__PURE__ */ jsx("p", {
|
|
5833
6063
|
style: diffModalSuccess,
|
|
5834
6064
|
children: t("diffUpdateBranchCompleted", { commit: dialog.pushed.slice(0, 8) })
|
|
@@ -5846,7 +6076,7 @@ window.__ModuleLoader__.load({
|
|
|
5846
6076
|
type: "button",
|
|
5847
6077
|
style: diffModalConflictResolve,
|
|
5848
6078
|
onClick: () => {
|
|
5849
|
-
submitPrompt(composeConflictsPrompt(base, dialog.conflicts ?? []));
|
|
6079
|
+
submitPrompt(composeConflictsPrompt(base, dialog.conflicts ?? [], method));
|
|
5850
6080
|
closeDialog();
|
|
5851
6081
|
},
|
|
5852
6082
|
children: t("diffUpdateBranchResolve")
|
|
@@ -6150,25 +6380,17 @@ window.__ModuleLoader__.load({
|
|
|
6150
6380
|
const aheadCount = repository.ahead ?? 0;
|
|
6151
6381
|
const pushable = repository.remote !== void 0 && repository.detached !== true && (aheadCount > 0 || repository.upstream === false);
|
|
6152
6382
|
const hasDiff = repository.diff !== void 0 && (repository.diff.additions > 0 || repository.diff.deletions > 0);
|
|
6153
|
-
const rateLimited = rateLimitBlocked(projection.activities);
|
|
6154
6383
|
if (repository.status !== "ready") return /* @__PURE__ */ jsx("div", {
|
|
6155
6384
|
style: repositoryBarFrame,
|
|
6156
6385
|
children: /* @__PURE__ */ jsxs("div", {
|
|
6157
6386
|
style: repositoryBar,
|
|
6158
|
-
children: [
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6165
|
-
children: repository.status === "not-repository" ? t("repositoryNotGit") : t("repositoryUnavailable")
|
|
6166
|
-
}),
|
|
6167
|
-
rateLimited ? /* @__PURE__ */ jsx(StatusItem, {
|
|
6168
|
-
label: t("repositoryRateLimited"),
|
|
6169
|
-
tone: "warning"
|
|
6170
|
-
}) : null
|
|
6171
|
-
]
|
|
6387
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
6388
|
+
style: repositoryPrIcon,
|
|
6389
|
+
children: /* @__PURE__ */ jsx(PullRequestIcon, {})
|
|
6390
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
6391
|
+
style: repositoryPrimary,
|
|
6392
|
+
children: repository.status === "not-repository" ? t("repositoryNotGit") : t("repositoryUnavailable")
|
|
6393
|
+
})]
|
|
6172
6394
|
})
|
|
6173
6395
|
});
|
|
6174
6396
|
return /* @__PURE__ */ jsx("div", {
|
|
@@ -6215,83 +6437,76 @@ window.__ModuleLoader__.load({
|
|
|
6215
6437
|
}) : null,
|
|
6216
6438
|
/* @__PURE__ */ jsxs("span", {
|
|
6217
6439
|
style: repositoryStatusItems,
|
|
6218
|
-
children: [
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
children: [
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
pullRequest === void 0 ? null : merged ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("span", {
|
|
6243
|
-
style: repositoryMergedStatus,
|
|
6244
|
-
children: [
|
|
6245
|
-
/* @__PURE__ */ jsx("span", {
|
|
6246
|
-
style: repositoryMergedDot,
|
|
6247
|
-
"aria-hidden": "true"
|
|
6248
|
-
}),
|
|
6249
|
-
t("repositoryState_merged"),
|
|
6250
|
-
mergedAge === void 0 ? null : /* @__PURE__ */ jsxs("span", {
|
|
6251
|
-
style: repositoryMergedAge,
|
|
6252
|
-
children: ["· ", t("repositoryMergedAgo", { age: mergedAge })]
|
|
6253
|
-
})
|
|
6254
|
-
]
|
|
6255
|
-
}), /* @__PURE__ */ jsx(CleanupControl, {
|
|
6256
|
-
repository,
|
|
6257
|
-
t,
|
|
6258
|
-
...deleteWorkspace === void 0 ? {} : { deleteWorkspace }
|
|
6259
|
-
})] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
6260
|
-
pullRequest.checks === "failing" ? /* @__PURE__ */ jsx(FailingChecksControl, {
|
|
6261
|
-
sessionId,
|
|
6262
|
-
pullNumber: pullRequest.number,
|
|
6263
|
-
t,
|
|
6264
|
-
...submitPrompt === void 0 ? {} : { submitPrompt }
|
|
6265
|
-
}) : pullRequest.checks === "none" ? null : /* @__PURE__ */ jsx(StatusGlyph, {
|
|
6266
|
-
label: t(`repositoryChecks_${pullRequest.checks}`),
|
|
6267
|
-
tone: pullRequest.checks === "passing" ? "success" : "warning",
|
|
6268
|
-
children: /* @__PURE__ */ jsx(ChecksGlyph, { state: pullRequest.checks })
|
|
6269
|
-
}),
|
|
6270
|
-
pullRequest.review === "none" ? null : /* @__PURE__ */ jsx(StatusGlyph, {
|
|
6271
|
-
label: t(`repositoryReview_${pullRequest.review}`),
|
|
6272
|
-
tone: pullRequest.review === "approved" ? "success" : pullRequest.review === "changes-requested" ? "error" : "neutral",
|
|
6273
|
-
children: /* @__PURE__ */ jsx(ReviewGlyph, {})
|
|
6274
|
-
}),
|
|
6275
|
-
/* @__PURE__ */ jsx(AutoFixControl, {
|
|
6276
|
-
sessionId,
|
|
6277
|
-
repository,
|
|
6278
|
-
running,
|
|
6279
|
-
t,
|
|
6280
|
-
...submitPrompt === void 0 ? {} : { submitPrompt }
|
|
6281
|
-
}),
|
|
6282
|
-
/* @__PURE__ */ jsx(UpdateBranchControl, {
|
|
6283
|
-
sessionId,
|
|
6284
|
-
repository,
|
|
6285
|
-
t,
|
|
6286
|
-
...submitPrompt === void 0 ? {} : { submitPrompt }
|
|
6440
|
+
children: [hasDiff || pushable ? /* @__PURE__ */ jsxs("button", {
|
|
6441
|
+
type: "button",
|
|
6442
|
+
style: {
|
|
6443
|
+
...diffTrigger,
|
|
6444
|
+
...merged ? diffTriggerMuted : {}
|
|
6445
|
+
},
|
|
6446
|
+
onClick: openDiff,
|
|
6447
|
+
"aria-label": t("diffOpen"),
|
|
6448
|
+
children: [hasDiff && repository.diff !== void 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("span", {
|
|
6449
|
+
style: merged ? diffAddMuted : diffAdd,
|
|
6450
|
+
children: ["+", repository.diff.additions]
|
|
6451
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
6452
|
+
style: merged ? diffDeleteMuted : diffDelete,
|
|
6453
|
+
children: ["−", repository.diff.deletions]
|
|
6454
|
+
})] }) : null, pushable ? /* @__PURE__ */ jsxs("span", {
|
|
6455
|
+
style: merged ? diffAheadMuted : diffAhead,
|
|
6456
|
+
children: ["↑", aheadCount > 0 ? aheadCount : ""]
|
|
6457
|
+
}) : null]
|
|
6458
|
+
}) : null, pullRequest === void 0 ? null : merged ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("span", {
|
|
6459
|
+
style: repositoryMergedStatus,
|
|
6460
|
+
children: [
|
|
6461
|
+
/* @__PURE__ */ jsx("span", {
|
|
6462
|
+
style: repositoryMergedDot,
|
|
6463
|
+
"aria-hidden": "true"
|
|
6287
6464
|
}),
|
|
6288
|
-
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
t
|
|
6465
|
+
t("repositoryState_merged"),
|
|
6466
|
+
mergedAge === void 0 ? null : /* @__PURE__ */ jsxs("span", {
|
|
6467
|
+
style: repositoryMergedAge,
|
|
6468
|
+
children: ["· ", t("repositoryMergedAgo", { age: mergedAge })]
|
|
6292
6469
|
})
|
|
6293
|
-
]
|
|
6294
|
-
|
|
6470
|
+
]
|
|
6471
|
+
}), /* @__PURE__ */ jsx(CleanupControl, {
|
|
6472
|
+
repository,
|
|
6473
|
+
t,
|
|
6474
|
+
...deleteWorkspace === void 0 ? {} : { deleteWorkspace }
|
|
6475
|
+
})] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
6476
|
+
pullRequest.checks === "failing" ? /* @__PURE__ */ jsx(FailingChecksControl, {
|
|
6477
|
+
sessionId,
|
|
6478
|
+
pullNumber: pullRequest.number,
|
|
6479
|
+
t,
|
|
6480
|
+
...submitPrompt === void 0 ? {} : { submitPrompt }
|
|
6481
|
+
}) : pullRequest.checks === "none" ? null : /* @__PURE__ */ jsx(StatusGlyph, {
|
|
6482
|
+
label: t(`repositoryChecks_${pullRequest.checks}`),
|
|
6483
|
+
tone: pullRequest.checks === "passing" ? "success" : "warning",
|
|
6484
|
+
children: /* @__PURE__ */ jsx(ChecksGlyph, { state: pullRequest.checks })
|
|
6485
|
+
}),
|
|
6486
|
+
pullRequest.review === "none" ? null : /* @__PURE__ */ jsx(StatusGlyph, {
|
|
6487
|
+
label: t(`repositoryReview_${pullRequest.review}`),
|
|
6488
|
+
tone: pullRequest.review === "approved" ? "success" : pullRequest.review === "changes-requested" ? "error" : "neutral",
|
|
6489
|
+
children: /* @__PURE__ */ jsx(ReviewGlyph, {})
|
|
6490
|
+
}),
|
|
6491
|
+
/* @__PURE__ */ jsx(AutoFixControl, {
|
|
6492
|
+
sessionId,
|
|
6493
|
+
repository,
|
|
6494
|
+
running,
|
|
6495
|
+
t,
|
|
6496
|
+
...submitPrompt === void 0 ? {} : { submitPrompt }
|
|
6497
|
+
}),
|
|
6498
|
+
/* @__PURE__ */ jsx(UpdateBranchControl, {
|
|
6499
|
+
sessionId,
|
|
6500
|
+
repository,
|
|
6501
|
+
t,
|
|
6502
|
+
...submitPrompt === void 0 ? {} : { submitPrompt }
|
|
6503
|
+
}),
|
|
6504
|
+
/* @__PURE__ */ jsx(MergePullRequestControl, {
|
|
6505
|
+
sessionId,
|
|
6506
|
+
repository,
|
|
6507
|
+
t
|
|
6508
|
+
})
|
|
6509
|
+
] })]
|
|
6295
6510
|
})
|
|
6296
6511
|
]
|
|
6297
6512
|
})
|
|
@@ -8588,9 +8803,15 @@ window.__ModuleLoader__.load({
|
|
|
8588
8803
|
row = row.parentElement;
|
|
8589
8804
|
}
|
|
8590
8805
|
}
|
|
8806
|
+
/** Reuse the row's existing portal even when the host moved a node between it
|
|
8807
|
+
* and the seat: a fresh element would change React's portal identity and
|
|
8808
|
+
* restart (and abort) every effect keyed on it. */
|
|
8591
8809
|
function ensureClaudeHeroPortal(seat) {
|
|
8592
|
-
const
|
|
8593
|
-
if (
|
|
8810
|
+
const existing = seat.parentElement?.querySelector(`:scope > [${PORTAL_ATTRIBUTE}]`) ?? null;
|
|
8811
|
+
if (existing !== null) {
|
|
8812
|
+
if (existing.previousElementSibling !== seat) seat.insertAdjacentElement("afterend", existing);
|
|
8813
|
+
return existing;
|
|
8814
|
+
}
|
|
8594
8815
|
const portal = document.createElement("span");
|
|
8595
8816
|
portal.setAttribute(PORTAL_ATTRIBUTE, "");
|
|
8596
8817
|
seat.insertAdjacentElement("afterend", portal);
|
|
@@ -8635,6 +8856,8 @@ window.__ModuleLoader__.load({
|
|
|
8635
8856
|
if (key === "End") return count - 1;
|
|
8636
8857
|
return (current + (key === "ArrowDown" ? 1 : -1) + count) % count;
|
|
8637
8858
|
}
|
|
8859
|
+
const BRANCH_LOAD_RETRIES = 2;
|
|
8860
|
+
const BRANCH_LOAD_RETRY_MS = 1e3;
|
|
8638
8861
|
const WORKTREE_PROGRESS_STAGES = [
|
|
8639
8862
|
"inspecting",
|
|
8640
8863
|
"fetching",
|
|
@@ -9002,14 +9225,26 @@ window.__ModuleLoader__.load({
|
|
|
9002
9225
|
setTicketError(void 0);
|
|
9003
9226
|
if (portal === void 0 || path === void 0) return;
|
|
9004
9227
|
const controller = new AbortController();
|
|
9005
|
-
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9228
|
+
let timer;
|
|
9229
|
+
const load = (remaining) => {
|
|
9230
|
+
loadRepositoryBranches(path, controller.signal).then((value) => {
|
|
9231
|
+
setBranches(value);
|
|
9232
|
+
setSelected(value.current ?? value.branches[0] ?? "");
|
|
9233
|
+
}, (reason) => {
|
|
9234
|
+
if (controller.signal.aborted) return;
|
|
9235
|
+
if (remaining > 0) {
|
|
9236
|
+
timer = setTimeout(() => {
|
|
9237
|
+
load(remaining - 1);
|
|
9238
|
+
}, BRANCH_LOAD_RETRY_MS);
|
|
9239
|
+
return;
|
|
9240
|
+
}
|
|
9241
|
+
setError(reason instanceof Error ? reason.message : String(reason));
|
|
9242
|
+
});
|
|
9243
|
+
};
|
|
9244
|
+
load(BRANCH_LOAD_RETRIES);
|
|
9011
9245
|
return () => {
|
|
9012
9246
|
controller.abort();
|
|
9247
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
9013
9248
|
};
|
|
9014
9249
|
}, [
|
|
9015
9250
|
portal,
|
|
@@ -9409,7 +9644,7 @@ window.__ModuleLoader__.load({
|
|
|
9409
9644
|
//#endregion
|
|
9410
9645
|
//#region src/client/details-resize.ts
|
|
9411
9646
|
const DETAILS_MIN_WIDTH = 300;
|
|
9412
|
-
const DETAILS_DEFAULT_WIDTH =
|
|
9647
|
+
const DETAILS_DEFAULT_WIDTH = 720;
|
|
9413
9648
|
const DETAILS_MAX_RATIO = .5;
|
|
9414
9649
|
const DRAG_THRESHOLD = 4;
|
|
9415
9650
|
function clampDetailsWidth(width, frameWidth) {
|
|
@@ -9610,14 +9845,16 @@ window.__ModuleLoader__.load({
|
|
|
9610
9845
|
globalSettings: "Claude Code 设置",
|
|
9611
9846
|
globalSettingsBody: "修改受支持的 Claude Code 与插件设置;其他字段会被保留。",
|
|
9612
9847
|
globalSettingsLoading: "正在加载全局设置…",
|
|
9613
|
-
globalSettingsNewSession: "
|
|
9848
|
+
globalSettingsNewSession: "修改仅对新建 Claude 会话生效。",
|
|
9614
9849
|
globalSettingsError: "全局设置保存失败",
|
|
9615
9850
|
outputStyle: "Output Style",
|
|
9616
9851
|
worktreeBranchPrefix: "Worktree 分支前缀",
|
|
9617
9852
|
worktreeBranchPrefixEffect: "分支前缀修改会应用于之后自动创建的 Worktree 分支;显式指定的完整分支名不会被修改。",
|
|
9618
9853
|
maxProcessesSetting: "Claude 进程上限",
|
|
9619
9854
|
idleTimeoutSetting: "闲置回收时长(分钟)",
|
|
9620
|
-
|
|
9855
|
+
maxProcessesEffect: "进程上限在下次启动 Claude 进程时生效。留空或非法值会被拒绝。",
|
|
9856
|
+
idleTimeoutEffect: "闲置回收时长在下一次回合结束后生效。留空或非法值会被拒绝。",
|
|
9857
|
+
settingHint: "查看说明",
|
|
9621
9858
|
pluginUpdate: "插件更新",
|
|
9622
9859
|
pluginUpdateBody: "检查 npm 上的新版本。只有可唯一识别的 npm 安装才能直接更新;本地开发链接不会被替换。",
|
|
9623
9860
|
updateNotChecked: "尚未检查更新。",
|
|
@@ -9655,7 +9892,22 @@ window.__ModuleLoader__.load({
|
|
|
9655
9892
|
tasksViewActivity: "查看活动",
|
|
9656
9893
|
tasksHideActivity: "收起活动",
|
|
9657
9894
|
tasksRunningCount: "{count} 个运行中任务",
|
|
9658
|
-
|
|
9895
|
+
planUsage: "账号额度",
|
|
9896
|
+
planUsageBody: "当前 Claude 订阅的用量窗口,来自 Claude Code 的 /usage 数据。会话空闲时自动刷新,也可随时手动刷新。",
|
|
9897
|
+
planUsageLoading: "读取中…",
|
|
9898
|
+
planUsageRefresh: "刷新额度",
|
|
9899
|
+
planUsageRefreshing: "刷新中…",
|
|
9900
|
+
planUsageUnavailable: "此账号没有订阅额度(API key、Bedrock、Vertex 等不受套餐限流)。",
|
|
9901
|
+
planUsageNever: "尚未获取额度数据,运行一次对话或点击刷新。",
|
|
9902
|
+
planUsageError: "额度读取失败",
|
|
9903
|
+
planUsageSubscription: "订阅",
|
|
9904
|
+
planUsageUpdated: "更新于 {age}前",
|
|
9905
|
+
planUsageResets: "{age}后重置",
|
|
9906
|
+
planUsageUsed: "已用 {percent}%",
|
|
9907
|
+
planWindow_five_hour: "5 小时",
|
|
9908
|
+
planWindow_seven_day: "全部模型 · 每周",
|
|
9909
|
+
planWindow_seven_day_opus: "Opus · 每周",
|
|
9910
|
+
planWindow_seven_day_sonnet: "Sonnet · 每周",
|
|
9659
9911
|
tasksTurnRunning: "{count} 个任务执行中",
|
|
9660
9912
|
tasksTurnCompleted: "{count} 个任务已完成",
|
|
9661
9913
|
tasksTurnFailed: "{failed} 个任务失败,{completed} 个已完成",
|
|
@@ -9773,10 +10025,12 @@ window.__ModuleLoader__.load({
|
|
|
9773
10025
|
diffMergeCompleted: "已合并 PR #{number}",
|
|
9774
10026
|
diffUpdateBranch: "Update branch…",
|
|
9775
10027
|
repositoryUpdateBranch: "Update branch",
|
|
9776
|
-
diffUpdateBranchDescription: "
|
|
10028
|
+
diffUpdateBranchDescription: "用 origin/{base} 更新当前分支并推送;出现冲突时可交给 Claude 解决。",
|
|
10029
|
+
diffUpdateBranch_rebase: "Rebase 到 origin/{base}(改写历史,以 --force-with-lease 推送)",
|
|
10030
|
+
diffUpdateBranch_merge: "将 origin/{base} 合并进当前分支",
|
|
9777
10031
|
diffUpdateBranchBehind: "落后 origin/{base} {count} 个 commit",
|
|
9778
|
-
diffUpdateBranchCompleted: "
|
|
9779
|
-
diffUpdateBranchConflicts: "
|
|
10032
|
+
diffUpdateBranchCompleted: "已更新并推送 commit {commit}",
|
|
10033
|
+
diffUpdateBranchConflicts: "更新产生冲突,以下文件需要解决:",
|
|
9780
10034
|
diffUpdateBranchResolve: "让 Claude 解决冲突",
|
|
9781
10035
|
repositoryChecksOpen: "查看失败的检查",
|
|
9782
10036
|
checksCardTitle: "失败的检查",
|
|
@@ -9907,14 +10161,16 @@ window.__ModuleLoader__.load({
|
|
|
9907
10161
|
globalSettings: "Claude Code settings",
|
|
9908
10162
|
globalSettingsBody: "Modify supported Claude Code and plugin settings while preserving every other field.",
|
|
9909
10163
|
globalSettingsLoading: "Loading global settings…",
|
|
9910
|
-
globalSettingsNewSession: "
|
|
10164
|
+
globalSettingsNewSession: "Changes apply only to new Claude sessions.",
|
|
9911
10165
|
globalSettingsError: "Global settings save failed",
|
|
9912
10166
|
outputStyle: "Output Style",
|
|
9913
10167
|
worktreeBranchPrefix: "Worktree branch prefix",
|
|
9914
10168
|
worktreeBranchPrefixEffect: "Prefix changes apply to subsequently generated Worktree branches. Explicit full branch names remain unchanged.",
|
|
9915
10169
|
maxProcessesSetting: "Claude process limit",
|
|
9916
10170
|
idleTimeoutSetting: "Idle timeout (minutes)",
|
|
9917
|
-
|
|
10171
|
+
maxProcessesEffect: "The process limit applies when the next Claude process is admitted. Blank or invalid values are rejected.",
|
|
10172
|
+
idleTimeoutEffect: "The idle timeout applies after the next completed turn. Blank or invalid values are rejected.",
|
|
10173
|
+
settingHint: "Show details",
|
|
9918
10174
|
pluginUpdate: "Plugin updates",
|
|
9919
10175
|
pluginUpdateBody: "Check npm for new releases. Only a uniquely identified npm installation can update in place; local development links are never replaced.",
|
|
9920
10176
|
updateNotChecked: "Updates have not been checked yet.",
|
|
@@ -9952,7 +10208,22 @@ window.__ModuleLoader__.load({
|
|
|
9952
10208
|
tasksViewActivity: "View activity",
|
|
9953
10209
|
tasksHideActivity: "Hide activity",
|
|
9954
10210
|
tasksRunningCount: "{count} running task(s)",
|
|
9955
|
-
|
|
10211
|
+
planUsage: "Plan usage",
|
|
10212
|
+
planUsageBody: "Utilization windows for the signed-in Claude subscription, from Claude Code's /usage data. Refreshes whenever a session goes idle, and on demand.",
|
|
10213
|
+
planUsageLoading: "Loading…",
|
|
10214
|
+
planUsageRefresh: "Refresh usage",
|
|
10215
|
+
planUsageRefreshing: "Refreshing…",
|
|
10216
|
+
planUsageUnavailable: "This account has no plan limits (API key, Bedrock, and Vertex sessions are not rate limited by a subscription).",
|
|
10217
|
+
planUsageNever: "No usage data yet — run a turn or refresh.",
|
|
10218
|
+
planUsageError: "Usage lookup failed",
|
|
10219
|
+
planUsageSubscription: "Subscription",
|
|
10220
|
+
planUsageUpdated: "Updated {age} ago",
|
|
10221
|
+
planUsageResets: "Resets in {age}",
|
|
10222
|
+
planUsageUsed: "{percent}% used",
|
|
10223
|
+
planWindow_five_hour: "5-hour",
|
|
10224
|
+
planWindow_seven_day: "All models · weekly",
|
|
10225
|
+
planWindow_seven_day_opus: "Opus · weekly",
|
|
10226
|
+
planWindow_seven_day_sonnet: "Sonnet · weekly",
|
|
9956
10227
|
tasksTurnRunning: "{count} task(s) running",
|
|
9957
10228
|
tasksTurnCompleted: "{count} task(s) completed",
|
|
9958
10229
|
tasksTurnFailed: "{failed} failed, {completed} completed",
|
|
@@ -10070,10 +10341,12 @@ window.__ModuleLoader__.load({
|
|
|
10070
10341
|
diffMergeCompleted: "Merged PR #{number}",
|
|
10071
10342
|
diffUpdateBranch: "Update branch…",
|
|
10072
10343
|
repositoryUpdateBranch: "Update branch",
|
|
10073
|
-
diffUpdateBranchDescription: "
|
|
10344
|
+
diffUpdateBranchDescription: "Update the current branch from origin/{base} and push; hand any conflicts to Claude.",
|
|
10345
|
+
diffUpdateBranch_rebase: "Rebase onto origin/{base} (rewrites history, pushes with --force-with-lease)",
|
|
10346
|
+
diffUpdateBranch_merge: "Merge origin/{base} into the current branch",
|
|
10074
10347
|
diffUpdateBranchBehind: "{count} commit(s) behind origin/{base}",
|
|
10075
|
-
diffUpdateBranchCompleted: "
|
|
10076
|
-
diffUpdateBranchConflicts: "The
|
|
10348
|
+
diffUpdateBranchCompleted: "Updated and pushed commit {commit}",
|
|
10349
|
+
diffUpdateBranchConflicts: "The update left conflicts in these files:",
|
|
10077
10350
|
diffUpdateBranchResolve: "Have Claude resolve the conflicts",
|
|
10078
10351
|
repositoryChecksOpen: "Show failing checks",
|
|
10079
10352
|
checksCardTitle: "Failing checks",
|