@norman-else/dsh-claude 0.1.26 → 0.1.27
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 +20 -3
- package/lib/client.js +417 -165
- 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 +194 -34
- 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;
|
|
@@ -4418,6 +4479,183 @@ window.__ModuleLoader__.load({
|
|
|
4418
4479
|
}) : null]
|
|
4419
4480
|
});
|
|
4420
4481
|
}
|
|
4482
|
+
/** Fixed windows carry a translated label; server-named model buckets (e.g.
|
|
4483
|
+
* 'Fable') arrive with their own `label` and are shown verbatim. */
|
|
4484
|
+
const TRANSLATED_WINDOWS = /* @__PURE__ */ new Set([
|
|
4485
|
+
"five_hour",
|
|
4486
|
+
"seven_day",
|
|
4487
|
+
"seven_day_opus",
|
|
4488
|
+
"seven_day_sonnet"
|
|
4489
|
+
]);
|
|
4490
|
+
/** Per-setting label and the effect note that used to sit as a standalone
|
|
4491
|
+
* paragraph under the card; it now hangs off the label as a hover hint. */
|
|
4492
|
+
const SETTING_COPY = {
|
|
4493
|
+
outputStyle: {
|
|
4494
|
+
label: "outputStyle",
|
|
4495
|
+
hint: "globalSettingsNewSession"
|
|
4496
|
+
},
|
|
4497
|
+
worktreeBranchPrefix: {
|
|
4498
|
+
label: "worktreeBranchPrefix",
|
|
4499
|
+
hint: "worktreeBranchPrefixEffect"
|
|
4500
|
+
},
|
|
4501
|
+
maxProcesses: {
|
|
4502
|
+
label: "maxProcessesSetting",
|
|
4503
|
+
hint: "maxProcessesEffect"
|
|
4504
|
+
},
|
|
4505
|
+
idleTimeoutMinutes: {
|
|
4506
|
+
label: "idleTimeoutSetting",
|
|
4507
|
+
hint: "idleTimeoutEffect"
|
|
4508
|
+
}
|
|
4509
|
+
};
|
|
4510
|
+
/** '?' badge that reveals a setting's effect note on hover or keyboard focus. */
|
|
4511
|
+
function SettingHint({ text, label }) {
|
|
4512
|
+
return /* @__PURE__ */ jsx(Tooltip, {
|
|
4513
|
+
label: text,
|
|
4514
|
+
side: "top",
|
|
4515
|
+
delayMs: 150,
|
|
4516
|
+
maxWidth: 320,
|
|
4517
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
4518
|
+
role: "note",
|
|
4519
|
+
tabIndex: 0,
|
|
4520
|
+
"aria-label": `${label}: ${text}`,
|
|
4521
|
+
style: settingHint,
|
|
4522
|
+
children: "?"
|
|
4523
|
+
})
|
|
4524
|
+
});
|
|
4525
|
+
}
|
|
4526
|
+
function isPlanUsageReport(value) {
|
|
4527
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
4528
|
+
const report = value;
|
|
4529
|
+
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");
|
|
4530
|
+
}
|
|
4531
|
+
/** Coarse duration for a reset countdown or a fetch age: minutes below an
|
|
4532
|
+
* hour, then hours, then days. Never negative — a passed reset reads '0m'. */
|
|
4533
|
+
function durationLabel(milliseconds) {
|
|
4534
|
+
const minutes = Math.max(0, Math.round(milliseconds / 6e4));
|
|
4535
|
+
if (minutes < 60) return `${minutes}m`;
|
|
4536
|
+
const hours = Math.floor(minutes / 60);
|
|
4537
|
+
if (hours < 24) return minutes % 60 === 0 ? `${hours}h` : `${hours}h ${minutes % 60}m`;
|
|
4538
|
+
return `${Math.floor(hours / 24)}d`;
|
|
4539
|
+
}
|
|
4540
|
+
function PlanUsageMeter({ window: usageWindow, t, now }) {
|
|
4541
|
+
const used = usageWindow.utilization;
|
|
4542
|
+
const tone = planUsageTone(used);
|
|
4543
|
+
const resetsIn = usageWindow.resetsAt === void 0 ? void 0 : Date.parse(usageWindow.resetsAt);
|
|
4544
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
4545
|
+
style: planUsageMeter,
|
|
4546
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
4547
|
+
style: planUsageTrack,
|
|
4548
|
+
children: /* @__PURE__ */ jsx("span", { style: {
|
|
4549
|
+
...planUsageFill,
|
|
4550
|
+
width: `${used ?? 0}%`,
|
|
4551
|
+
background: tone.fill
|
|
4552
|
+
} })
|
|
4553
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
4554
|
+
style: {
|
|
4555
|
+
...planUsageMeta,
|
|
4556
|
+
color: tone.text
|
|
4557
|
+
},
|
|
4558
|
+
children: [used === void 0 ? "—" : t("planUsageUsed", { percent: Math.round(used) }), resetsIn === void 0 || !Number.isFinite(resetsIn) ? null : ` · ${t("planUsageResets", { age: durationLabel(resetsIn - now) })}`]
|
|
4559
|
+
})]
|
|
4560
|
+
});
|
|
4561
|
+
}
|
|
4562
|
+
/** Fetch the plan usage report; POST forces the backend to re-read it. */
|
|
4563
|
+
async function loadPlanUsage(refresh) {
|
|
4564
|
+
const response = await fetch(CLAUDE_USAGE_PATH, {
|
|
4565
|
+
method: refresh ? "POST" : "GET",
|
|
4566
|
+
credentials: "same-origin",
|
|
4567
|
+
headers: { accept: "application/json" }
|
|
4568
|
+
});
|
|
4569
|
+
const payload = await response.json();
|
|
4570
|
+
if (!response.ok) {
|
|
4571
|
+
const message = typeof payload === "object" && payload !== null && "error" in payload && typeof payload.error === "string" ? payload.error : `HTTP ${response.status}`;
|
|
4572
|
+
throw new Error(message);
|
|
4573
|
+
}
|
|
4574
|
+
if (!isPlanUsageReport(payload)) throw new Error("Invalid plan usage response");
|
|
4575
|
+
return payload;
|
|
4576
|
+
}
|
|
4577
|
+
function PlanUsageCard({ t, load }) {
|
|
4578
|
+
const [report, setReport] = useState();
|
|
4579
|
+
const [busy, setBusy] = useState(false);
|
|
4580
|
+
const [error, setError] = useState();
|
|
4581
|
+
const request = useCallback(async (refresh) => {
|
|
4582
|
+
setBusy(true);
|
|
4583
|
+
setError(void 0);
|
|
4584
|
+
try {
|
|
4585
|
+
setReport(await load(refresh));
|
|
4586
|
+
} catch (cause) {
|
|
4587
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
4588
|
+
} finally {
|
|
4589
|
+
setBusy(false);
|
|
4590
|
+
}
|
|
4591
|
+
}, [load]);
|
|
4592
|
+
useEffect(() => {
|
|
4593
|
+
request(false);
|
|
4594
|
+
}, [request]);
|
|
4595
|
+
const now = Date.now();
|
|
4596
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
4597
|
+
style: settingsCard,
|
|
4598
|
+
children: [
|
|
4599
|
+
/* @__PURE__ */ jsxs("div", {
|
|
4600
|
+
style: settingsCardHeader,
|
|
4601
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", {
|
|
4602
|
+
style: settingsSectionHeading,
|
|
4603
|
+
children: t("planUsage")
|
|
4604
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
4605
|
+
style: settingsBody,
|
|
4606
|
+
children: t("planUsageBody")
|
|
4607
|
+
})] }), /* @__PURE__ */ jsx("button", {
|
|
4608
|
+
type: "button",
|
|
4609
|
+
style: button,
|
|
4610
|
+
disabled: busy,
|
|
4611
|
+
onClick: () => {
|
|
4612
|
+
request(true);
|
|
4613
|
+
},
|
|
4614
|
+
children: busy ? t("planUsageRefreshing") : t("planUsageRefresh")
|
|
4615
|
+
})]
|
|
4616
|
+
}),
|
|
4617
|
+
report === void 0 ? /* @__PURE__ */ jsx("p", {
|
|
4618
|
+
style: notice,
|
|
4619
|
+
children: busy ? t("planUsageLoading") : t("planUsageNever")
|
|
4620
|
+
}) : report.windows.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
4621
|
+
style: notice,
|
|
4622
|
+
children: report.fetchedAt === 0 ? t("planUsageNever") : t("planUsageUnavailable")
|
|
4623
|
+
}) : /* @__PURE__ */ jsxs("div", {
|
|
4624
|
+
style: diagnosticGrid,
|
|
4625
|
+
children: [report.subscription === void 0 ? null : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
|
|
4626
|
+
style: diagnosticLabel,
|
|
4627
|
+
children: t("planUsageSubscription")
|
|
4628
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
4629
|
+
style: diagnosticValue,
|
|
4630
|
+
children: report.subscription
|
|
4631
|
+
})] }), report.windows.flatMap((usageWindow) => [/* @__PURE__ */ jsx("span", {
|
|
4632
|
+
style: diagnosticLabel,
|
|
4633
|
+
children: usageWindow.label ?? (TRANSLATED_WINDOWS.has(usageWindow.id) ? t(`planWindow_${usageWindow.id}`) : usageWindow.id)
|
|
4634
|
+
}, `${usageWindow.id}-label`), /* @__PURE__ */ jsx(PlanUsageMeter, {
|
|
4635
|
+
window: usageWindow,
|
|
4636
|
+
t,
|
|
4637
|
+
now
|
|
4638
|
+
}, `${usageWindow.id}-meter`)])]
|
|
4639
|
+
}),
|
|
4640
|
+
report !== void 0 && report.fetchedAt > 0 ? /* @__PURE__ */ jsx("p", {
|
|
4641
|
+
style: notice,
|
|
4642
|
+
children: t("planUsageUpdated", { age: durationLabel(now - report.fetchedAt) })
|
|
4643
|
+
}) : null,
|
|
4644
|
+
error === void 0 ? null : /* @__PURE__ */ jsxs("p", {
|
|
4645
|
+
role: "alert",
|
|
4646
|
+
style: {
|
|
4647
|
+
...notice,
|
|
4648
|
+
color: "var(--dsw-alias-state-error-primary)"
|
|
4649
|
+
},
|
|
4650
|
+
children: [
|
|
4651
|
+
t("planUsageError"),
|
|
4652
|
+
": ",
|
|
4653
|
+
error
|
|
4654
|
+
]
|
|
4655
|
+
})
|
|
4656
|
+
]
|
|
4657
|
+
});
|
|
4658
|
+
}
|
|
4421
4659
|
function ClaudeCodeSettings({ t }) {
|
|
4422
4660
|
const [report, setReport] = useState();
|
|
4423
4661
|
const [error, setError] = useState();
|
|
@@ -4622,6 +4860,10 @@ window.__ModuleLoader__.load({
|
|
|
4622
4860
|
})
|
|
4623
4861
|
]
|
|
4624
4862
|
}),
|
|
4863
|
+
/* @__PURE__ */ jsx(PlanUsageCard, {
|
|
4864
|
+
t,
|
|
4865
|
+
load: loadPlanUsage
|
|
4866
|
+
}),
|
|
4625
4867
|
/* @__PURE__ */ jsxs("section", {
|
|
4626
4868
|
style: settingsCard,
|
|
4627
4869
|
children: [
|
|
@@ -4635,37 +4877,31 @@ window.__ModuleLoader__.load({
|
|
|
4635
4877
|
globalSettings === void 0 ? /* @__PURE__ */ jsx("p", {
|
|
4636
4878
|
style: notice,
|
|
4637
4879
|
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,
|
|
4880
|
+
}) : globalSettings.settings.map((setting) => {
|
|
4881
|
+
const copy = SETTING_COPY[setting.key];
|
|
4882
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
4883
|
+
style: diagnosticGrid,
|
|
4884
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
4885
|
+
style: diagnosticLabel,
|
|
4886
|
+
children: [copy === void 0 ? setting.key : t(copy.label), copy === void 0 ? null : /* @__PURE__ */ jsx(SettingHint, {
|
|
4887
|
+
text: t(copy.hint),
|
|
4888
|
+
label: t("settingHint")
|
|
4889
|
+
})]
|
|
4890
|
+
}), setting.kind === "select" ? /* @__PURE__ */ jsx(GlobalSettingSelect, {
|
|
4891
|
+
setting,
|
|
4892
|
+
disabled: globalSettingsBusy,
|
|
4893
|
+
onChange: (nextValue) => {
|
|
4894
|
+
requestGlobalSettings({ [setting.key]: nextValue });
|
|
4895
|
+
}
|
|
4896
|
+
}) : /* @__PURE__ */ jsx(GlobalSettingText, {
|
|
4897
|
+
setting,
|
|
4898
|
+
disabled: globalSettingsBusy,
|
|
4899
|
+
onChange: (nextValue) => {
|
|
4900
|
+
requestGlobalSettings({ [setting.key]: nextValue });
|
|
4901
|
+
}
|
|
4902
|
+
})]
|
|
4903
|
+
}, setting.key);
|
|
4904
|
+
}),
|
|
4669
4905
|
globalSettingsError === void 0 ? null : /* @__PURE__ */ jsxs("p", {
|
|
4670
4906
|
role: "alert",
|
|
4671
4907
|
style: {
|
|
@@ -5017,12 +5253,15 @@ window.__ModuleLoader__.load({
|
|
|
5017
5253
|
}
|
|
5018
5254
|
return body;
|
|
5019
5255
|
}
|
|
5256
|
+
/** A wedged host must surface as an error; the hero has no other way out of its loading state. */
|
|
5257
|
+
const BRANCH_LOAD_TIMEOUT_MS = 15e3;
|
|
5020
5258
|
function loadRepositoryBranches(cwd, signal) {
|
|
5259
|
+
const timeout = AbortSignal.timeout(BRANCH_LOAD_TIMEOUT_MS);
|
|
5021
5260
|
return response(fetch(`${CLAUDE_REPOSITORY_SETUP_PATH}/branches?cwd=${encodeURIComponent(cwd)}`, {
|
|
5022
5261
|
method: "GET",
|
|
5023
5262
|
credentials: "same-origin",
|
|
5024
5263
|
headers: { accept: "application/json" },
|
|
5025
|
-
|
|
5264
|
+
signal: signal === void 0 ? timeout : AbortSignal.any([signal, timeout])
|
|
5026
5265
|
}));
|
|
5027
5266
|
}
|
|
5028
5267
|
async function prepareRepository(cwd, branch, worktree, branchName, onProgress = () => {}) {
|
|
@@ -5229,32 +5468,6 @@ window.__ModuleLoader__.load({
|
|
|
5229
5468
|
}
|
|
5230
5469
|
//#endregion
|
|
5231
5470
|
//#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
5471
|
/** Icon-only status: the tone carries the state, the full label lives in the tooltip and accessible name. */
|
|
5259
5472
|
function StatusGlyph({ label, tone, children }) {
|
|
5260
5473
|
const toneStyle = tone === "success" ? repositoryItemSuccess : tone === "warning" ? repositoryItemWarning : tone === "error" ? repositoryItemError : {};
|
|
@@ -6150,25 +6363,17 @@ window.__ModuleLoader__.load({
|
|
|
6150
6363
|
const aheadCount = repository.ahead ?? 0;
|
|
6151
6364
|
const pushable = repository.remote !== void 0 && repository.detached !== true && (aheadCount > 0 || repository.upstream === false);
|
|
6152
6365
|
const hasDiff = repository.diff !== void 0 && (repository.diff.additions > 0 || repository.diff.deletions > 0);
|
|
6153
|
-
const rateLimited = rateLimitBlocked(projection.activities);
|
|
6154
6366
|
if (repository.status !== "ready") return /* @__PURE__ */ jsx("div", {
|
|
6155
6367
|
style: repositoryBarFrame,
|
|
6156
6368
|
children: /* @__PURE__ */ jsxs("div", {
|
|
6157
6369
|
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
|
-
]
|
|
6370
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
6371
|
+
style: repositoryPrIcon,
|
|
6372
|
+
children: /* @__PURE__ */ jsx(PullRequestIcon, {})
|
|
6373
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
6374
|
+
style: repositoryPrimary,
|
|
6375
|
+
children: repository.status === "not-repository" ? t("repositoryNotGit") : t("repositoryUnavailable")
|
|
6376
|
+
})]
|
|
6172
6377
|
})
|
|
6173
6378
|
});
|
|
6174
6379
|
return /* @__PURE__ */ jsx("div", {
|
|
@@ -6215,83 +6420,76 @@ window.__ModuleLoader__.load({
|
|
|
6215
6420
|
}) : null,
|
|
6216
6421
|
/* @__PURE__ */ jsxs("span", {
|
|
6217
6422
|
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 }
|
|
6423
|
+
children: [hasDiff || pushable ? /* @__PURE__ */ jsxs("button", {
|
|
6424
|
+
type: "button",
|
|
6425
|
+
style: {
|
|
6426
|
+
...diffTrigger,
|
|
6427
|
+
...merged ? diffTriggerMuted : {}
|
|
6428
|
+
},
|
|
6429
|
+
onClick: openDiff,
|
|
6430
|
+
"aria-label": t("diffOpen"),
|
|
6431
|
+
children: [hasDiff && repository.diff !== void 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("span", {
|
|
6432
|
+
style: merged ? diffAddMuted : diffAdd,
|
|
6433
|
+
children: ["+", repository.diff.additions]
|
|
6434
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
6435
|
+
style: merged ? diffDeleteMuted : diffDelete,
|
|
6436
|
+
children: ["−", repository.diff.deletions]
|
|
6437
|
+
})] }) : null, pushable ? /* @__PURE__ */ jsxs("span", {
|
|
6438
|
+
style: merged ? diffAheadMuted : diffAhead,
|
|
6439
|
+
children: ["↑", aheadCount > 0 ? aheadCount : ""]
|
|
6440
|
+
}) : null]
|
|
6441
|
+
}) : null, pullRequest === void 0 ? null : merged ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("span", {
|
|
6442
|
+
style: repositoryMergedStatus,
|
|
6443
|
+
children: [
|
|
6444
|
+
/* @__PURE__ */ jsx("span", {
|
|
6445
|
+
style: repositoryMergedDot,
|
|
6446
|
+
"aria-hidden": "true"
|
|
6287
6447
|
}),
|
|
6288
|
-
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
t
|
|
6448
|
+
t("repositoryState_merged"),
|
|
6449
|
+
mergedAge === void 0 ? null : /* @__PURE__ */ jsxs("span", {
|
|
6450
|
+
style: repositoryMergedAge,
|
|
6451
|
+
children: ["· ", t("repositoryMergedAgo", { age: mergedAge })]
|
|
6292
6452
|
})
|
|
6293
|
-
]
|
|
6294
|
-
|
|
6453
|
+
]
|
|
6454
|
+
}), /* @__PURE__ */ jsx(CleanupControl, {
|
|
6455
|
+
repository,
|
|
6456
|
+
t,
|
|
6457
|
+
...deleteWorkspace === void 0 ? {} : { deleteWorkspace }
|
|
6458
|
+
})] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
6459
|
+
pullRequest.checks === "failing" ? /* @__PURE__ */ jsx(FailingChecksControl, {
|
|
6460
|
+
sessionId,
|
|
6461
|
+
pullNumber: pullRequest.number,
|
|
6462
|
+
t,
|
|
6463
|
+
...submitPrompt === void 0 ? {} : { submitPrompt }
|
|
6464
|
+
}) : pullRequest.checks === "none" ? null : /* @__PURE__ */ jsx(StatusGlyph, {
|
|
6465
|
+
label: t(`repositoryChecks_${pullRequest.checks}`),
|
|
6466
|
+
tone: pullRequest.checks === "passing" ? "success" : "warning",
|
|
6467
|
+
children: /* @__PURE__ */ jsx(ChecksGlyph, { state: pullRequest.checks })
|
|
6468
|
+
}),
|
|
6469
|
+
pullRequest.review === "none" ? null : /* @__PURE__ */ jsx(StatusGlyph, {
|
|
6470
|
+
label: t(`repositoryReview_${pullRequest.review}`),
|
|
6471
|
+
tone: pullRequest.review === "approved" ? "success" : pullRequest.review === "changes-requested" ? "error" : "neutral",
|
|
6472
|
+
children: /* @__PURE__ */ jsx(ReviewGlyph, {})
|
|
6473
|
+
}),
|
|
6474
|
+
/* @__PURE__ */ jsx(AutoFixControl, {
|
|
6475
|
+
sessionId,
|
|
6476
|
+
repository,
|
|
6477
|
+
running,
|
|
6478
|
+
t,
|
|
6479
|
+
...submitPrompt === void 0 ? {} : { submitPrompt }
|
|
6480
|
+
}),
|
|
6481
|
+
/* @__PURE__ */ jsx(UpdateBranchControl, {
|
|
6482
|
+
sessionId,
|
|
6483
|
+
repository,
|
|
6484
|
+
t,
|
|
6485
|
+
...submitPrompt === void 0 ? {} : { submitPrompt }
|
|
6486
|
+
}),
|
|
6487
|
+
/* @__PURE__ */ jsx(MergePullRequestControl, {
|
|
6488
|
+
sessionId,
|
|
6489
|
+
repository,
|
|
6490
|
+
t
|
|
6491
|
+
})
|
|
6492
|
+
] })]
|
|
6295
6493
|
})
|
|
6296
6494
|
]
|
|
6297
6495
|
})
|
|
@@ -8588,9 +8786,15 @@ window.__ModuleLoader__.load({
|
|
|
8588
8786
|
row = row.parentElement;
|
|
8589
8787
|
}
|
|
8590
8788
|
}
|
|
8789
|
+
/** Reuse the row's existing portal even when the host moved a node between it
|
|
8790
|
+
* and the seat: a fresh element would change React's portal identity and
|
|
8791
|
+
* restart (and abort) every effect keyed on it. */
|
|
8591
8792
|
function ensureClaudeHeroPortal(seat) {
|
|
8592
|
-
const
|
|
8593
|
-
if (
|
|
8793
|
+
const existing = seat.parentElement?.querySelector(`:scope > [${PORTAL_ATTRIBUTE}]`) ?? null;
|
|
8794
|
+
if (existing !== null) {
|
|
8795
|
+
if (existing.previousElementSibling !== seat) seat.insertAdjacentElement("afterend", existing);
|
|
8796
|
+
return existing;
|
|
8797
|
+
}
|
|
8594
8798
|
const portal = document.createElement("span");
|
|
8595
8799
|
portal.setAttribute(PORTAL_ATTRIBUTE, "");
|
|
8596
8800
|
seat.insertAdjacentElement("afterend", portal);
|
|
@@ -8635,6 +8839,8 @@ window.__ModuleLoader__.load({
|
|
|
8635
8839
|
if (key === "End") return count - 1;
|
|
8636
8840
|
return (current + (key === "ArrowDown" ? 1 : -1) + count) % count;
|
|
8637
8841
|
}
|
|
8842
|
+
const BRANCH_LOAD_RETRIES = 2;
|
|
8843
|
+
const BRANCH_LOAD_RETRY_MS = 1e3;
|
|
8638
8844
|
const WORKTREE_PROGRESS_STAGES = [
|
|
8639
8845
|
"inspecting",
|
|
8640
8846
|
"fetching",
|
|
@@ -9002,14 +9208,26 @@ window.__ModuleLoader__.load({
|
|
|
9002
9208
|
setTicketError(void 0);
|
|
9003
9209
|
if (portal === void 0 || path === void 0) return;
|
|
9004
9210
|
const controller = new AbortController();
|
|
9005
|
-
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9211
|
+
let timer;
|
|
9212
|
+
const load = (remaining) => {
|
|
9213
|
+
loadRepositoryBranches(path, controller.signal).then((value) => {
|
|
9214
|
+
setBranches(value);
|
|
9215
|
+
setSelected(value.current ?? value.branches[0] ?? "");
|
|
9216
|
+
}, (reason) => {
|
|
9217
|
+
if (controller.signal.aborted) return;
|
|
9218
|
+
if (remaining > 0) {
|
|
9219
|
+
timer = setTimeout(() => {
|
|
9220
|
+
load(remaining - 1);
|
|
9221
|
+
}, BRANCH_LOAD_RETRY_MS);
|
|
9222
|
+
return;
|
|
9223
|
+
}
|
|
9224
|
+
setError(reason instanceof Error ? reason.message : String(reason));
|
|
9225
|
+
});
|
|
9226
|
+
};
|
|
9227
|
+
load(BRANCH_LOAD_RETRIES);
|
|
9011
9228
|
return () => {
|
|
9012
9229
|
controller.abort();
|
|
9230
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
9013
9231
|
};
|
|
9014
9232
|
}, [
|
|
9015
9233
|
portal,
|
|
@@ -9409,7 +9627,7 @@ window.__ModuleLoader__.load({
|
|
|
9409
9627
|
//#endregion
|
|
9410
9628
|
//#region src/client/details-resize.ts
|
|
9411
9629
|
const DETAILS_MIN_WIDTH = 300;
|
|
9412
|
-
const DETAILS_DEFAULT_WIDTH =
|
|
9630
|
+
const DETAILS_DEFAULT_WIDTH = 720;
|
|
9413
9631
|
const DETAILS_MAX_RATIO = .5;
|
|
9414
9632
|
const DRAG_THRESHOLD = 4;
|
|
9415
9633
|
function clampDetailsWidth(width, frameWidth) {
|
|
@@ -9610,14 +9828,16 @@ window.__ModuleLoader__.load({
|
|
|
9610
9828
|
globalSettings: "Claude Code 设置",
|
|
9611
9829
|
globalSettingsBody: "修改受支持的 Claude Code 与插件设置;其他字段会被保留。",
|
|
9612
9830
|
globalSettingsLoading: "正在加载全局设置…",
|
|
9613
|
-
globalSettingsNewSession: "
|
|
9831
|
+
globalSettingsNewSession: "修改仅对新建 Claude 会话生效。",
|
|
9614
9832
|
globalSettingsError: "全局设置保存失败",
|
|
9615
9833
|
outputStyle: "Output Style",
|
|
9616
9834
|
worktreeBranchPrefix: "Worktree 分支前缀",
|
|
9617
9835
|
worktreeBranchPrefixEffect: "分支前缀修改会应用于之后自动创建的 Worktree 分支;显式指定的完整分支名不会被修改。",
|
|
9618
9836
|
maxProcessesSetting: "Claude 进程上限",
|
|
9619
9837
|
idleTimeoutSetting: "闲置回收时长(分钟)",
|
|
9620
|
-
|
|
9838
|
+
maxProcessesEffect: "进程上限在下次启动 Claude 进程时生效。留空或非法值会被拒绝。",
|
|
9839
|
+
idleTimeoutEffect: "闲置回收时长在下一次回合结束后生效。留空或非法值会被拒绝。",
|
|
9840
|
+
settingHint: "查看说明",
|
|
9621
9841
|
pluginUpdate: "插件更新",
|
|
9622
9842
|
pluginUpdateBody: "检查 npm 上的新版本。只有可唯一识别的 npm 安装才能直接更新;本地开发链接不会被替换。",
|
|
9623
9843
|
updateNotChecked: "尚未检查更新。",
|
|
@@ -9655,7 +9875,22 @@ window.__ModuleLoader__.load({
|
|
|
9655
9875
|
tasksViewActivity: "查看活动",
|
|
9656
9876
|
tasksHideActivity: "收起活动",
|
|
9657
9877
|
tasksRunningCount: "{count} 个运行中任务",
|
|
9658
|
-
|
|
9878
|
+
planUsage: "账号额度",
|
|
9879
|
+
planUsageBody: "当前 Claude 订阅的用量窗口,来自 Claude Code 的 /usage 数据。会话空闲时自动刷新,也可随时手动刷新。",
|
|
9880
|
+
planUsageLoading: "读取中…",
|
|
9881
|
+
planUsageRefresh: "刷新额度",
|
|
9882
|
+
planUsageRefreshing: "刷新中…",
|
|
9883
|
+
planUsageUnavailable: "此账号没有订阅额度(API key、Bedrock、Vertex 等不受套餐限流)。",
|
|
9884
|
+
planUsageNever: "尚未获取额度数据,运行一次对话或点击刷新。",
|
|
9885
|
+
planUsageError: "额度读取失败",
|
|
9886
|
+
planUsageSubscription: "订阅",
|
|
9887
|
+
planUsageUpdated: "更新于 {age}前",
|
|
9888
|
+
planUsageResets: "{age}后重置",
|
|
9889
|
+
planUsageUsed: "已用 {percent}%",
|
|
9890
|
+
planWindow_five_hour: "5 小时",
|
|
9891
|
+
planWindow_seven_day: "全部模型 · 每周",
|
|
9892
|
+
planWindow_seven_day_opus: "Opus · 每周",
|
|
9893
|
+
planWindow_seven_day_sonnet: "Sonnet · 每周",
|
|
9659
9894
|
tasksTurnRunning: "{count} 个任务执行中",
|
|
9660
9895
|
tasksTurnCompleted: "{count} 个任务已完成",
|
|
9661
9896
|
tasksTurnFailed: "{failed} 个任务失败,{completed} 个已完成",
|
|
@@ -9907,14 +10142,16 @@ window.__ModuleLoader__.load({
|
|
|
9907
10142
|
globalSettings: "Claude Code settings",
|
|
9908
10143
|
globalSettingsBody: "Modify supported Claude Code and plugin settings while preserving every other field.",
|
|
9909
10144
|
globalSettingsLoading: "Loading global settings…",
|
|
9910
|
-
globalSettingsNewSession: "
|
|
10145
|
+
globalSettingsNewSession: "Changes apply only to new Claude sessions.",
|
|
9911
10146
|
globalSettingsError: "Global settings save failed",
|
|
9912
10147
|
outputStyle: "Output Style",
|
|
9913
10148
|
worktreeBranchPrefix: "Worktree branch prefix",
|
|
9914
10149
|
worktreeBranchPrefixEffect: "Prefix changes apply to subsequently generated Worktree branches. Explicit full branch names remain unchanged.",
|
|
9915
10150
|
maxProcessesSetting: "Claude process limit",
|
|
9916
10151
|
idleTimeoutSetting: "Idle timeout (minutes)",
|
|
9917
|
-
|
|
10152
|
+
maxProcessesEffect: "The process limit applies when the next Claude process is admitted. Blank or invalid values are rejected.",
|
|
10153
|
+
idleTimeoutEffect: "The idle timeout applies after the next completed turn. Blank or invalid values are rejected.",
|
|
10154
|
+
settingHint: "Show details",
|
|
9918
10155
|
pluginUpdate: "Plugin updates",
|
|
9919
10156
|
pluginUpdateBody: "Check npm for new releases. Only a uniquely identified npm installation can update in place; local development links are never replaced.",
|
|
9920
10157
|
updateNotChecked: "Updates have not been checked yet.",
|
|
@@ -9952,7 +10189,22 @@ window.__ModuleLoader__.load({
|
|
|
9952
10189
|
tasksViewActivity: "View activity",
|
|
9953
10190
|
tasksHideActivity: "Hide activity",
|
|
9954
10191
|
tasksRunningCount: "{count} running task(s)",
|
|
9955
|
-
|
|
10192
|
+
planUsage: "Plan usage",
|
|
10193
|
+
planUsageBody: "Utilization windows for the signed-in Claude subscription, from Claude Code's /usage data. Refreshes whenever a session goes idle, and on demand.",
|
|
10194
|
+
planUsageLoading: "Loading…",
|
|
10195
|
+
planUsageRefresh: "Refresh usage",
|
|
10196
|
+
planUsageRefreshing: "Refreshing…",
|
|
10197
|
+
planUsageUnavailable: "This account has no plan limits (API key, Bedrock, and Vertex sessions are not rate limited by a subscription).",
|
|
10198
|
+
planUsageNever: "No usage data yet — run a turn or refresh.",
|
|
10199
|
+
planUsageError: "Usage lookup failed",
|
|
10200
|
+
planUsageSubscription: "Subscription",
|
|
10201
|
+
planUsageUpdated: "Updated {age} ago",
|
|
10202
|
+
planUsageResets: "Resets in {age}",
|
|
10203
|
+
planUsageUsed: "{percent}% used",
|
|
10204
|
+
planWindow_five_hour: "5-hour",
|
|
10205
|
+
planWindow_seven_day: "All models · weekly",
|
|
10206
|
+
planWindow_seven_day_opus: "Opus · weekly",
|
|
10207
|
+
planWindow_seven_day_sonnet: "Sonnet · weekly",
|
|
9956
10208
|
tasksTurnRunning: "{count} task(s) running",
|
|
9957
10209
|
tasksTurnCompleted: "{count} task(s) completed",
|
|
9958
10210
|
tasksTurnFailed: "{failed} failed, {completed} completed",
|