@norman-else/dsh-claude 0.1.28 → 0.1.29
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/INSTALL.md +55 -55
- package/LICENSE +21 -21
- package/README.md +82 -82
- package/cordis.patch.yml +12 -12
- package/legacy-preset/agent.cordis.yml +11 -11
- package/legacy-preset/preset.yml +4 -4
- package/lib/bin.mjs +0 -0
- package/lib/bin.mjs.map +1 -1
- package/lib/client.d.ts +1 -0
- package/lib/client.js +389 -6
- package/lib/client.js.map +1 -1
- package/lib/command-bridge-BYj0VF4J.mjs.map +1 -1
- package/lib/events-lDt9nTUw.mjs.map +1 -1
- package/lib/index.mjs.map +1 -1
- package/lib/preset-installer-CPOH9lAr.mjs.map +1 -1
- package/lib/preset-route.mjs.map +1 -1
- package/package.json +181 -181
- package/preset/claude/agent.cordis.yml +11 -11
- package/preset/claude/preset.yml +4 -4
package/lib/client.js
CHANGED
|
@@ -4,7 +4,7 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
module.exports;
|
|
6
6
|
var { Fragment, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } = require("react");
|
|
7
|
-
var { DiffBlock, DisclosureRow, HoverCard, IconApiOutline14, IconBranchOutline16, IconCheckOutline14, IconCheckOutline16, IconChevronDownOutline14, IconChevronUpOutline14, IconCloseOutline16, IconEditOutline16, IconFullscreenOutline16, IconQueueOutline14, IconSearchOutline16, IconSendOutline14, IconThinkOutline14, IconTrashOutline16, MarkdownText, Menu, Modal, StateDot, Tooltip } = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
7
|
+
var { DiffBlock, DisclosureRow, HoverCard, IconAgentPresetOutline16, IconApiOutline14, IconBranchOutline16, IconCheckOutline14, IconCheckOutline16, IconChevronDownOutline14, IconChevronUpOutline14, IconCloseOutline16, IconEditOutline16, IconFullscreenOutline16, IconQueueOutline14, IconSearchOutline16, IconSendOutline14, IconThinkOutline14, IconTrashOutline16, MarkdownText, Menu, Modal, StateDot, Tooltip } = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
8
8
|
var { Fragment: Fragment$1, jsx, jsxs } = require("react/jsx-runtime");
|
|
9
9
|
var { createPortal } = require("react-dom");
|
|
10
10
|
/** Claude's subagent dispatch tools; rendered as plugin-owned group cards
|
|
@@ -3857,10 +3857,10 @@ window.__ModuleLoader__.load({
|
|
|
3857
3857
|
".dsh-claude-act-running{animation:dsh-claude-act-pulse 1.2s ease-in-out infinite}",
|
|
3858
3858
|
"@keyframes dsh-claude-act-pulse{0%,100%{opacity:1}50%{opacity:.3}}"
|
|
3859
3859
|
].join("");
|
|
3860
|
-
let cssInjected = false;
|
|
3861
|
-
function ensureCss() {
|
|
3862
|
-
if (cssInjected || typeof document === "undefined") return;
|
|
3863
|
-
cssInjected = true;
|
|
3860
|
+
let cssInjected$2 = false;
|
|
3861
|
+
function ensureCss$2() {
|
|
3862
|
+
if (cssInjected$2 || typeof document === "undefined") return;
|
|
3863
|
+
cssInjected$2 = true;
|
|
3864
3864
|
const element = document.createElement("style");
|
|
3865
3865
|
element.dataset.dshClaudeActivity = "";
|
|
3866
3866
|
element.textContent = ACTIVITY_CSS;
|
|
@@ -4185,7 +4185,7 @@ window.__ModuleLoader__.load({
|
|
|
4185
4185
|
});
|
|
4186
4186
|
}
|
|
4187
4187
|
function ClaudeActivityNode({ node, useClaudeProjection, t }) {
|
|
4188
|
-
ensureCss();
|
|
4188
|
+
ensureCss$2();
|
|
4189
4189
|
const marker = node.data;
|
|
4190
4190
|
const activities = useClaudeProjection((value) => selectStepActivities(value, marker.turn, marker.step));
|
|
4191
4191
|
const tasks = useClaudeProjection((value) => value.tasks?.tasks ?? EMPTY_TASKS);
|
|
@@ -9560,6 +9560,274 @@ window.__ModuleLoader__.load({
|
|
|
9560
9560
|
}), portal);
|
|
9561
9561
|
}
|
|
9562
9562
|
//#endregion
|
|
9563
|
+
//#region src/client/ClaudeDiffHeaderAction.tsx
|
|
9564
|
+
/** Quiet by default, lit on hover, press, keyboard focus, and for as long as
|
|
9565
|
+
* the panel it opened is on screen. The header action row sits on the app
|
|
9566
|
+
* background, so a resting background would read as a filled control. */
|
|
9567
|
+
const ACTION_CSS = [
|
|
9568
|
+
".dsh-claude-header-diff{flex:none;display:inline-flex;align-items:center;justify-content:center;gap:5px;",
|
|
9569
|
+
"min-width:32px;height:32px;padding:0;border:0;border-radius:9px;background:transparent;",
|
|
9570
|
+
"color:var(--dsw-alias-label-secondary);cursor:pointer;",
|
|
9571
|
+
"font-family:var(--dsw-font-family);font-size:12px;line-height:20px;font-weight:650;",
|
|
9572
|
+
"transition:background .12s ease,color .12s ease}",
|
|
9573
|
+
".dsh-claude-header-diff[data-counts]{padding:0 10px 0 8px}",
|
|
9574
|
+
".dsh-claude-header-diff:hover,.dsh-claude-header-diff:focus-visible,.dsh-claude-header-diff[aria-pressed=\"true\"]{",
|
|
9575
|
+
"background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}",
|
|
9576
|
+
".dsh-claude-header-diff:active{background:var(--dsw-alias-interactive-bg-active)}",
|
|
9577
|
+
".dsh-claude-header-diff:focus-visible{outline:none}",
|
|
9578
|
+
".dsh-claude-header-diff>*{flex:none}",
|
|
9579
|
+
".dsh-claude-header-diff>svg.dsh-claude-header-diff-glyph{",
|
|
9580
|
+
"width:18px;height:18px;display:block;overflow:visible;opacity:1;",
|
|
9581
|
+
"fill:none;stroke:currentColor;stroke-width:2.1;stroke-linecap:round}",
|
|
9582
|
+
".dsh-claude-header-diff-add,.dsh-claude-header-diff-del{line-height:1}",
|
|
9583
|
+
".dsh-claude-header-diff-add{color:var(--dsw-alias-state-success-primary)}",
|
|
9584
|
+
".dsh-claude-header-diff-del{color:var(--dsw-alias-state-error-primary)}"
|
|
9585
|
+
].join("");
|
|
9586
|
+
let cssInjected$1 = false;
|
|
9587
|
+
function ensureCss$1() {
|
|
9588
|
+
if (cssInjected$1 || typeof document === "undefined") return;
|
|
9589
|
+
cssInjected$1 = true;
|
|
9590
|
+
const element = document.createElement("style");
|
|
9591
|
+
element.dataset.dshClaudeHeaderDiff = "";
|
|
9592
|
+
element.textContent = ACTION_CSS;
|
|
9593
|
+
document.head.appendChild(element);
|
|
9594
|
+
}
|
|
9595
|
+
/** Plus over minus: the diff glyph. Drawn inline because the primitives icon
|
|
9596
|
+
* set ships no diff icon.
|
|
9597
|
+
*
|
|
9598
|
+
* The ink spans y 3.5 to 14.5 — symmetric about the box's own centre line, so
|
|
9599
|
+
* `align-items:center` lands the drawn shape on the centre rather than the
|
|
9600
|
+
* bounding box that happens to contain it. */
|
|
9601
|
+
function DiffGlyph() {
|
|
9602
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
9603
|
+
className: "dsh-claude-header-diff-glyph",
|
|
9604
|
+
width: "18",
|
|
9605
|
+
height: "18",
|
|
9606
|
+
viewBox: "0 0 18 18",
|
|
9607
|
+
fill: "none",
|
|
9608
|
+
"aria-hidden": "true",
|
|
9609
|
+
focusable: "false",
|
|
9610
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
9611
|
+
d: "M9 3.5v5.5M6.25 6.25h5.5M6.25 14.5h5.5",
|
|
9612
|
+
stroke: "currentColor",
|
|
9613
|
+
strokeWidth: "2.1",
|
|
9614
|
+
strokeLinecap: "round"
|
|
9615
|
+
})
|
|
9616
|
+
});
|
|
9617
|
+
}
|
|
9618
|
+
function ClaudeDiffHeaderAction({ t, sessionId, toggleDiff, diffOpen, useClaudeProjection }) {
|
|
9619
|
+
const owned = useClaudeProjection((projection) => projection.owned);
|
|
9620
|
+
const additions = useClaudeProjection((projection) => projection.repository?.diff?.additions ?? 0);
|
|
9621
|
+
const deletions = useClaudeProjection((projection) => projection.repository?.diff?.deletions ?? 0);
|
|
9622
|
+
const open = useSyncExternalStore(diffOpen.subscribe, diffOpen.getSnapshot, diffOpen.getSnapshot);
|
|
9623
|
+
if (!owned) return null;
|
|
9624
|
+
ensureCss$1();
|
|
9625
|
+
const hasCounts = additions > 0 || deletions > 0;
|
|
9626
|
+
const label = t(open ? "diffClose" : "diffOpen");
|
|
9627
|
+
return /* @__PURE__ */ jsx(Tooltip, {
|
|
9628
|
+
label,
|
|
9629
|
+
side: "bottom",
|
|
9630
|
+
delayMs: 250,
|
|
9631
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
9632
|
+
type: "button",
|
|
9633
|
+
className: "dsh-claude-header-diff",
|
|
9634
|
+
"aria-label": label,
|
|
9635
|
+
"aria-pressed": open,
|
|
9636
|
+
"data-counts": hasCounts || void 0,
|
|
9637
|
+
"data-session": sessionId,
|
|
9638
|
+
onClick: toggleDiff,
|
|
9639
|
+
children: [/* @__PURE__ */ jsx(DiffGlyph, {}), hasCounts ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("span", {
|
|
9640
|
+
className: "dsh-claude-header-diff-add",
|
|
9641
|
+
children: ["+", additions]
|
|
9642
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
9643
|
+
className: "dsh-claude-header-diff-del",
|
|
9644
|
+
children: ["−", deletions]
|
|
9645
|
+
})] }) : null]
|
|
9646
|
+
})
|
|
9647
|
+
});
|
|
9648
|
+
}
|
|
9649
|
+
//#endregion
|
|
9650
|
+
//#region src/client/claude-mark.ts
|
|
9651
|
+
/** The Claude wordmark glyph, lifted verbatim from the brand SVG.
|
|
9652
|
+
*
|
|
9653
|
+
* Kept as raw geometry rather than a component because its only consumer
|
|
9654
|
+
* paints it through a CSS `background-image`: the Host draws the agent-preset
|
|
9655
|
+
* icon itself, so the swap has to happen in CSS, not in JSX. */
|
|
9656
|
+
const MARK_PATH = "M 233.959793 800.214905 L 468.644287 668.536987 L 472.590637 657.100647 L 468.644287 650.738403 L 457.208069 650.738403 L 417.986633 648.322144 L 283.892639 644.69812 L 167.597321 639.865845 L 54.926208 633.825623 L 26.577238 627.785339 L 3.3e-05 592.751709 L 2.73832 575.27533 L 26.577238 559.248352 L 60.724873 562.228149 L 136.187973 567.382629 L 249.422867 575.194763 L 331.570496 580.026978 L 453.261841 592.671082 L 472.590637 592.671082 L 475.328857 584.859009 L 468.724915 580.026978 L 463.570557 575.194763 L 346.389313 495.785217 L 219.543671 411.865906 L 153.100723 363.543762 L 117.181267 339.060425 L 99.060455 316.107361 L 91.248367 266.01355 L 123.865784 230.093994 L 167.677887 233.073853 L 178.872513 236.053772 L 223.248367 270.201477 L 318.040283 343.570496 L 441.825592 434.738342 L 459.946411 449.798706 L 467.194672 444.64447 L 468.080597 441.020203 L 459.946411 427.409485 L 392.617493 305.718323 L 320.778564 181.932983 L 288.80542 130.630859 L 280.348999 99.865845 C 277.369171 87.221436 275.194641 76.590698 275.194641 63.624268 L 312.322174 13.20813 L 332.8591 6.604126 L 382.389313 13.20813 L 403.248352 31.328979 L 434.013519 101.71814 L 483.865753 212.537048 L 561.181274 363.221497 L 583.812134 407.919434 L 595.892639 449.315491 L 600.40271 461.959839 L 608.214783 461.959839 L 608.214783 454.711609 L 614.577271 369.825623 L 626.335632 265.61084 L 637.771851 131.516846 L 641.718201 93.745117 L 660.402832 48.483276 L 697.530334 24.000122 L 726.52356 37.852417 L 750.362549 72 L 747.060486 94.067139 L 732.886047 186.201416 L 705.100708 330.52356 L 686.979919 427.167847 L 697.530334 427.167847 L 709.61084 415.087341 L 758.496704 350.174561 L 840.644348 247.490051 L 876.885925 206.738342 L 919.167847 161.71814 L 946.308838 140.29541 L 997.61084 140.29541 L 1035.38269 196.429626 L 1018.469849 254.416199 L 965.637634 321.422852 L 921.825562 378.201538 L 859.006714 462.765259 L 819.785278 530.41626 L 823.409424 535.812073 L 832.75177 534.92627 L 974.657776 504.724915 L 1051.328979 490.872559 L 1142.818848 475.167786 L 1184.214844 494.496582 L 1188.724854 514.147644 L 1172.456421 554.335693 L 1074.604126 578.496765 L 959.838989 601.449829 L 788.939636 641.879272 L 786.845764 643.409485 L 789.261841 646.389343 L 866.255127 653.637634 L 899.194702 655.409424 L 979.812134 655.409424 L 1129.932861 666.604187 L 1169.154419 692.537109 L 1192.671265 724.268677 L 1188.724854 748.429688 L 1128.322144 779.194641 L 1046.818848 759.865845 L 856.590759 714.604126 L 791.355774 698.335754 L 782.335693 698.335754 L 782.335693 703.731567 L 836.69812 756.885986 L 936.322205 846.845581 L 1061.073975 962.81897 L 1067.436279 991.490112 L 1051.409424 1014.120911 L 1034.496704 1011.704712 L 924.885986 929.234924 L 882.604126 892.107544 L 786.845764 811.48999 L 780.483276 811.48999 L 780.483276 819.946289 L 802.550415 852.241699 L 919.087341 1027.409424 L 925.127625 1081.127686 L 916.671204 1098.604126 L 886.469849 1109.154419 L 853.288696 1103.114136 L 785.073914 1007.355835 L 714.684631 899.516785 L 657.906067 802.872498 L 650.979858 806.81897 L 617.476624 1167.704834 L 601.771851 1186.147705 L 565.530212 1200 L 535.328857 1177.046997 L 519.302124 1139.919556 L 535.328857 1066.550537 L 554.657776 970.792053 L 570.362488 894.68457 L 584.536926 800.134277 L 592.993347 768.724976 L 592.429626 766.630859 L 585.503479 767.516968 L 514.22821 865.369263 L 405.825531 1011.865906 L 320.053711 1103.677979 L 299.516815 1111.812256 L 263.919525 1093.369263 L 267.221497 1060.429688 L 287.114136 1031.114136 L 405.825531 880.107361 L 477.422913 786.52356 L 523.651062 732.483276 L 523.328918 724.671265 L 520.590698 724.671265 L 205.288605 929.395935 L 149.154434 936.644409 L 124.993355 914.01355 L 127.973183 876.885986 L 139.409409 864.80542 L 234.201385 799.570435 L 233.879227 799.8927 Z";
|
|
9657
|
+
const MARK_COLOR = "#d97757";
|
|
9658
|
+
/** The mark as a CSS `url()` value.
|
|
9659
|
+
* @returns a percent-encoded `data:` URI, safe to inline in a stylesheet. */
|
|
9660
|
+
function claudeMarkUrl() {
|
|
9661
|
+
return `url("data:image/svg+xml;utf8,${encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 1200"><path fill="${MARK_COLOR}" d="${MARK_PATH}"/></svg>`)}")`;
|
|
9662
|
+
}
|
|
9663
|
+
//#endregion
|
|
9664
|
+
//#region src/client/agent-preset-roster.ts
|
|
9665
|
+
/** Locale keys the Host uses for the presets it ships, mirrored so a shadowed
|
|
9666
|
+
* label still shows their translated copy instead of a bare id. Every entry is
|
|
9667
|
+
* a lookup into the Host's own `settings.agentPreset` namespace; an id absent
|
|
9668
|
+
* here (this plugin's preset included) falls through to file metadata, which
|
|
9669
|
+
* is what the Host does too. */
|
|
9670
|
+
const BUILT_IN_KEYS = {
|
|
9671
|
+
standard: {
|
|
9672
|
+
name: "presetStandardName",
|
|
9673
|
+
description: "presetStandardDescription"
|
|
9674
|
+
},
|
|
9675
|
+
code: {
|
|
9676
|
+
name: "presetCodeName",
|
|
9677
|
+
description: "presetCodeDescription"
|
|
9678
|
+
},
|
|
9679
|
+
minimal: {
|
|
9680
|
+
name: "presetMinimalName",
|
|
9681
|
+
description: "presetMinimalDescription"
|
|
9682
|
+
},
|
|
9683
|
+
cordis: {
|
|
9684
|
+
name: "presetCordisName",
|
|
9685
|
+
description: "presetCordisDescription"
|
|
9686
|
+
}
|
|
9687
|
+
};
|
|
9688
|
+
/**
|
|
9689
|
+
* Resolve one preset's display copy the way the Host does: translated copy for
|
|
9690
|
+
* a preset it ships, file metadata otherwise.
|
|
9691
|
+
* @param row - the roster row, or undefined when the roster has not arrived.
|
|
9692
|
+
* @param presetId - the id recorded on the session.
|
|
9693
|
+
* @param hostT - lookup bound to the Host's preset namespace.
|
|
9694
|
+
* @returns the name to render and the description to put in the tooltip.
|
|
9695
|
+
*/
|
|
9696
|
+
function presetDisplayText(row, presetId, hostT) {
|
|
9697
|
+
const keys = row?.trust === "system" ? BUILT_IN_KEYS[row.id] : void 0;
|
|
9698
|
+
if (keys !== void 0) {
|
|
9699
|
+
const name = hostT(keys.name);
|
|
9700
|
+
const description = hostT(keys.description);
|
|
9701
|
+
if (name !== keys.name) return {
|
|
9702
|
+
name,
|
|
9703
|
+
...description === keys.description ? {} : { description }
|
|
9704
|
+
};
|
|
9705
|
+
}
|
|
9706
|
+
return {
|
|
9707
|
+
name: row?.name ?? presetId,
|
|
9708
|
+
...row?.description === void 0 ? {} : { description: row.description }
|
|
9709
|
+
};
|
|
9710
|
+
}
|
|
9711
|
+
var AgentPresetRoster = class {
|
|
9712
|
+
#api;
|
|
9713
|
+
#listeners = /* @__PURE__ */ new Set();
|
|
9714
|
+
#rows = [];
|
|
9715
|
+
#inflight;
|
|
9716
|
+
constructor(api) {
|
|
9717
|
+
this.#api = api;
|
|
9718
|
+
}
|
|
9719
|
+
/** Read the roster once. Concurrent calls share the in-flight read, and a
|
|
9720
|
+
* failed read leaves the previous rows in place — the label falls back to
|
|
9721
|
+
* the session's preset id, never to an empty header. */
|
|
9722
|
+
load() {
|
|
9723
|
+
if (this.#inflight !== void 0) return;
|
|
9724
|
+
this.#inflight = (async () => {
|
|
9725
|
+
try {
|
|
9726
|
+
const response = await this.#api.list({});
|
|
9727
|
+
if (!response.result.ok) return;
|
|
9728
|
+
this.#rows = response.result.value.presets;
|
|
9729
|
+
for (const listener of this.#listeners) listener();
|
|
9730
|
+
} catch {} finally {
|
|
9731
|
+
this.#inflight = void 0;
|
|
9732
|
+
}
|
|
9733
|
+
})();
|
|
9734
|
+
}
|
|
9735
|
+
subscribe = (listener) => {
|
|
9736
|
+
this.#listeners.add(listener);
|
|
9737
|
+
return () => {
|
|
9738
|
+
this.#listeners.delete(listener);
|
|
9739
|
+
};
|
|
9740
|
+
};
|
|
9741
|
+
getSnapshot = () => this.#rows;
|
|
9742
|
+
};
|
|
9743
|
+
//#endregion
|
|
9744
|
+
//#region src/client/ClaudeAgentPresetLabel.tsx
|
|
9745
|
+
/** Reproduces the Host label's own metrics — it sits in the same action row
|
|
9746
|
+
* beside the title, so it has to read as the same piece of chrome. */
|
|
9747
|
+
const LABEL_CSS = [
|
|
9748
|
+
".dsh-claude-preset-label{display:inline-flex;align-items:center;gap:4px;max-width:220px;height:22px;",
|
|
9749
|
+
"padding:0 2px 0 0;border-radius:6px;overflow:hidden;white-space:nowrap;",
|
|
9750
|
+
"color:var(--dsw-alias-label-secondary);font-family:var(--dsw-font-family);font-size:12px;line-height:22px}",
|
|
9751
|
+
".dsh-claude-preset-label>*{flex:none}",
|
|
9752
|
+
".dsh-claude-preset-name{min-width:0;overflow:hidden;text-overflow:ellipsis}",
|
|
9753
|
+
".dsh-claude-preset-icon{opacity:.7}",
|
|
9754
|
+
`.dsh-claude-preset-mark{width:14px;height:14px;background:${claudeMarkUrl()} center/contain no-repeat}`
|
|
9755
|
+
].join("");
|
|
9756
|
+
let cssInjected = false;
|
|
9757
|
+
function ensureCss() {
|
|
9758
|
+
if (cssInjected || typeof document === "undefined") return;
|
|
9759
|
+
cssInjected = true;
|
|
9760
|
+
const element = document.createElement("style");
|
|
9761
|
+
element.dataset.dshClaudePresetLabel = "";
|
|
9762
|
+
element.textContent = LABEL_CSS;
|
|
9763
|
+
document.head.appendChild(element);
|
|
9764
|
+
}
|
|
9765
|
+
function ClaudeAgentPresetLabel({ t, hostT, roster, sessionId, useSessions }) {
|
|
9766
|
+
const preset = useSessions((state) => state.byId[sessionId]?.agentPreset);
|
|
9767
|
+
const rows = useSyncExternalStore(roster.subscribe, roster.getSnapshot, roster.getSnapshot);
|
|
9768
|
+
const { load } = roster;
|
|
9769
|
+
useEffect(() => {
|
|
9770
|
+
if (preset !== void 0) load();
|
|
9771
|
+
}, [preset, load]);
|
|
9772
|
+
if (preset === void 0) return null;
|
|
9773
|
+
ensureCss();
|
|
9774
|
+
const text = presetDisplayText(rows.find((row) => row.id === preset), preset, hostT);
|
|
9775
|
+
return /* @__PURE__ */ jsx(Tooltip, {
|
|
9776
|
+
label: text.description ?? t("presetHeaderHint"),
|
|
9777
|
+
side: "bottom",
|
|
9778
|
+
delayMs: 250,
|
|
9779
|
+
maxWidth: 280,
|
|
9780
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
9781
|
+
className: "dsh-claude-preset-label",
|
|
9782
|
+
children: [preset === "claude" ? /* @__PURE__ */ jsx("span", {
|
|
9783
|
+
className: "dsh-claude-preset-mark",
|
|
9784
|
+
"aria-hidden": "true"
|
|
9785
|
+
}) : /* @__PURE__ */ jsx(IconAgentPresetOutline16, {
|
|
9786
|
+
size: 14,
|
|
9787
|
+
className: "dsh-claude-preset-icon"
|
|
9788
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
9789
|
+
className: "dsh-claude-preset-name",
|
|
9790
|
+
children: text.name
|
|
9791
|
+
})]
|
|
9792
|
+
})
|
|
9793
|
+
});
|
|
9794
|
+
}
|
|
9795
|
+
//#endregion
|
|
9796
|
+
//#region src/client/diff-open-store.ts
|
|
9797
|
+
var DiffOpenStore = class {
|
|
9798
|
+
#sessionId;
|
|
9799
|
+
#listeners = /* @__PURE__ */ new Set();
|
|
9800
|
+
/** Mark the diff panel open for one session, replacing any previous holder. */
|
|
9801
|
+
open(sessionId) {
|
|
9802
|
+
this.#set(sessionId);
|
|
9803
|
+
}
|
|
9804
|
+
/** Mark the diff panel closed. */
|
|
9805
|
+
close() {
|
|
9806
|
+
this.#set(void 0);
|
|
9807
|
+
}
|
|
9808
|
+
/** Whether the diff panel is currently open for this session. */
|
|
9809
|
+
isOpen(sessionId) {
|
|
9810
|
+
return this.#sessionId === sessionId;
|
|
9811
|
+
}
|
|
9812
|
+
/** A per-session snapshot source for `useSyncExternalStore`. */
|
|
9813
|
+
sourceFor(sessionId) {
|
|
9814
|
+
return {
|
|
9815
|
+
subscribe: (listener) => {
|
|
9816
|
+
this.#listeners.add(listener);
|
|
9817
|
+
return () => {
|
|
9818
|
+
this.#listeners.delete(listener);
|
|
9819
|
+
};
|
|
9820
|
+
},
|
|
9821
|
+
getSnapshot: () => this.isOpen(sessionId)
|
|
9822
|
+
};
|
|
9823
|
+
}
|
|
9824
|
+
#set(sessionId) {
|
|
9825
|
+
if (this.#sessionId === sessionId) return;
|
|
9826
|
+
this.#sessionId = sessionId;
|
|
9827
|
+
for (const listener of this.#listeners) listener();
|
|
9828
|
+
}
|
|
9829
|
+
};
|
|
9830
|
+
//#endregion
|
|
9563
9831
|
//#region src/client/claude-command-source.ts
|
|
9564
9832
|
const SOURCE_NAME = "Claude Code";
|
|
9565
9833
|
function commandsFor(store, session) {
|
|
@@ -9642,6 +9910,81 @@ window.__ModuleLoader__.load({
|
|
|
9642
9910
|
}
|
|
9643
9911
|
}
|
|
9644
9912
|
//#endregion
|
|
9913
|
+
//#region src/client/preset-seat-mark.ts
|
|
9914
|
+
/** Flags the Host's agent-preset seat while it names the Claude preset.
|
|
9915
|
+
*
|
|
9916
|
+
* The seat is a `single` slot whose occupant owns the whole picker — menu,
|
|
9917
|
+
* staging, the intro animation. Shadowing it to change one glyph would mean
|
|
9918
|
+
* reimplementing all of that, so the glyph is swapped in CSS instead. CSS
|
|
9919
|
+
* cannot read the seat's text, though, and the seat names whichever preset is
|
|
9920
|
+
* currently staged, so the brand mark would otherwise land on `standard` or
|
|
9921
|
+
* `cordis` too. This bridge supplies the one bit CSS is missing.
|
|
9922
|
+
*
|
|
9923
|
+
* Keyed on the seat icon's CSS Module local name plus `aria-haspopup`, both of
|
|
9924
|
+
* which fail open: a Host rename leaves the attribute unset and the stock
|
|
9925
|
+
* glyph in place.
|
|
9926
|
+
*/
|
|
9927
|
+
/** Attribute the stylesheet keys the mark swap off. */
|
|
9928
|
+
const CLAUDE_SEAT_ATTRIBUTE = "data-dsh-claude-preset";
|
|
9929
|
+
const SEAT_SELECTOR = "button[aria-haspopup=\"menu\"]";
|
|
9930
|
+
const SEAT_ICON_SELECTOR = "[class*=\"seatIcon\"]";
|
|
9931
|
+
/**
|
|
9932
|
+
* Set or clear the flag on every preset seat currently in the tree.
|
|
9933
|
+
* @param root - subtree to sweep; the document by default.
|
|
9934
|
+
*/
|
|
9935
|
+
function markClaudePresetSeats(root) {
|
|
9936
|
+
for (const icon of root.querySelectorAll(SEAT_ICON_SELECTOR)) {
|
|
9937
|
+
const seat = icon.closest(SEAT_SELECTOR);
|
|
9938
|
+
if (seat === null) continue;
|
|
9939
|
+
if (isClaudePresetText(seat.textContent ?? "")) seat.setAttribute(CLAUDE_SEAT_ATTRIBUTE, "");
|
|
9940
|
+
else seat.removeAttribute(CLAUDE_SEAT_ATTRIBUTE);
|
|
9941
|
+
}
|
|
9942
|
+
}
|
|
9943
|
+
/** Keep the flag in step with the Host's own re-renders.
|
|
9944
|
+
* @returns a disposer that stops observing and clears every flag it set. */
|
|
9945
|
+
function trackClaudePresetSeats() {
|
|
9946
|
+
if (typeof document === "undefined" || typeof window === "undefined" || typeof MutationObserver === "undefined") return () => {};
|
|
9947
|
+
let frame;
|
|
9948
|
+
const schedule = () => {
|
|
9949
|
+
if (frame !== void 0) return;
|
|
9950
|
+
frame = window.requestAnimationFrame(() => {
|
|
9951
|
+
frame = void 0;
|
|
9952
|
+
markClaudePresetSeats(document);
|
|
9953
|
+
});
|
|
9954
|
+
};
|
|
9955
|
+
const observer = new MutationObserver(schedule);
|
|
9956
|
+
observer.observe(document.body, {
|
|
9957
|
+
childList: true,
|
|
9958
|
+
subtree: true,
|
|
9959
|
+
characterData: true
|
|
9960
|
+
});
|
|
9961
|
+
markClaudePresetSeats(document);
|
|
9962
|
+
return () => {
|
|
9963
|
+
observer.disconnect();
|
|
9964
|
+
if (frame !== void 0) window.cancelAnimationFrame(frame);
|
|
9965
|
+
for (const seat of document.querySelectorAll(`[${CLAUDE_SEAT_ATTRIBUTE}]`)) seat.removeAttribute(CLAUDE_SEAT_ATTRIBUTE);
|
|
9966
|
+
};
|
|
9967
|
+
}
|
|
9968
|
+
const HOST_CHROME_CSS = `button[class*="sessionLogButton"]{display:none}${["header:has(.dsh-claude-header-diff)>[role=\"tablist\"]{display:none}", "header:has(.dsh-claude-header-diff){padding-bottom:10px}"].join("")}${[
|
|
9969
|
+
`button[${CLAUDE_SEAT_ATTRIBUTE}]>[class*="seatIcon"]{display:none}`,
|
|
9970
|
+
`button[${CLAUDE_SEAT_ATTRIBUTE}]::before{content:"";flex:none;width:16px;height:16px;`,
|
|
9971
|
+
`background:${claudeMarkUrl()} center/contain no-repeat}`
|
|
9972
|
+
].join("")}`;
|
|
9973
|
+
/** Install the stylesheet and the one DOM flag it depends on.
|
|
9974
|
+
* @returns a disposer that removes both again. */
|
|
9975
|
+
function restyleHostChrome() {
|
|
9976
|
+
if (typeof document === "undefined") return () => {};
|
|
9977
|
+
const element = document.createElement("style");
|
|
9978
|
+
element.dataset.dshClaudeHostChrome = "";
|
|
9979
|
+
element.textContent = HOST_CHROME_CSS;
|
|
9980
|
+
document.head.appendChild(element);
|
|
9981
|
+
const untrack = trackClaudePresetSeats();
|
|
9982
|
+
return () => {
|
|
9983
|
+
untrack();
|
|
9984
|
+
element.remove();
|
|
9985
|
+
};
|
|
9986
|
+
}
|
|
9987
|
+
//#endregion
|
|
9645
9988
|
//#region src/client/details-resize.ts
|
|
9646
9989
|
const DETAILS_MIN_WIDTH = 300;
|
|
9647
9990
|
const DETAILS_DEFAULT_WIDTH = 720;
|
|
@@ -9980,6 +10323,7 @@ window.__ModuleLoader__.load({
|
|
|
9980
10323
|
no: "否",
|
|
9981
10324
|
diffOpen: "查看分支改动",
|
|
9982
10325
|
diffClose: "关闭 Diff 面板",
|
|
10326
|
+
presetHeaderHint: "当前会话运行的 Agent 预设",
|
|
9983
10327
|
diffWorkingTree: "分支改动",
|
|
9984
10328
|
diffFiles: "{count} 个已修改文件",
|
|
9985
10329
|
diffFilesShort: "{count} 个文件",
|
|
@@ -10296,6 +10640,7 @@ window.__ModuleLoader__.load({
|
|
|
10296
10640
|
no: "No",
|
|
10297
10641
|
diffOpen: "View branch changes",
|
|
10298
10642
|
diffClose: "Close diff panel",
|
|
10643
|
+
presetHeaderHint: "The agent preset this session runs",
|
|
10299
10644
|
diffWorkingTree: "Branch changes",
|
|
10300
10645
|
diffFiles: "{count} modified file(s)",
|
|
10301
10646
|
diffFilesShort: "{count} files",
|
|
@@ -10475,6 +10820,7 @@ window.__ModuleLoader__.load({
|
|
|
10475
10820
|
en
|
|
10476
10821
|
}), "dsh-claude: client copy");
|
|
10477
10822
|
const t = ctx.locale.bind(namespace);
|
|
10823
|
+
ctx.effect(() => restyleHostChrome(), "dsh-claude: Host chrome restyling");
|
|
10478
10824
|
const projections = new ClaudeProjectionStore();
|
|
10479
10825
|
ctx.effect(() => ctx.inputTriggers.registerSource(createClaudeCommandSource(ctx, projections)), "dsh-claude: Claude slash source");
|
|
10480
10826
|
const sessions = ctx.get("sessions");
|
|
@@ -10516,6 +10862,7 @@ window.__ModuleLoader__.load({
|
|
|
10516
10862
|
let disposeDiffOverlay;
|
|
10517
10863
|
let disposeExpandedDetailsResize;
|
|
10518
10864
|
let detailsSessionId;
|
|
10865
|
+
const diffOpen = new DiffOpenStore();
|
|
10519
10866
|
const restoreDiff = () => {
|
|
10520
10867
|
if (disposeDiffOverlay === void 0) return;
|
|
10521
10868
|
disposeDiffOverlay();
|
|
@@ -10532,6 +10879,7 @@ window.__ModuleLoader__.load({
|
|
|
10532
10879
|
disposePluginDetails?.();
|
|
10533
10880
|
disposePluginDetails = void 0;
|
|
10534
10881
|
detailsSessionId = void 0;
|
|
10882
|
+
diffOpen.close();
|
|
10535
10883
|
layout?.closeDetails();
|
|
10536
10884
|
};
|
|
10537
10885
|
ctx.effect(() => ctx.slots.onEntryError((key, entry) => {
|
|
@@ -10641,6 +10989,7 @@ window.__ModuleLoader__.load({
|
|
|
10641
10989
|
detailsSessionId = void 0;
|
|
10642
10990
|
return;
|
|
10643
10991
|
}
|
|
10992
|
+
diffOpen.open(sessionId);
|
|
10644
10993
|
disposeExpandedDetailsResize = enableExpandedDetailsResize();
|
|
10645
10994
|
};
|
|
10646
10995
|
ctx.effect(() => {
|
|
@@ -10672,6 +11021,40 @@ window.__ModuleLoader__.load({
|
|
|
10672
11021
|
openTasks: (turn) => openTasksPanel(sessionId, turn)
|
|
10673
11022
|
})
|
|
10674
11023
|
}, ClaudeActivityTail));
|
|
11024
|
+
if (connection !== void 0) {
|
|
11025
|
+
const roster = new AgentPresetRoster(connection.api.agentPresets);
|
|
11026
|
+
const hostT = ctx.locale.bind("settings.agentPreset");
|
|
11027
|
+
ctx.slots.inject("conversation.session.header.actions", () => ctx.slots.register({
|
|
11028
|
+
name: "conversation.session.header.actions",
|
|
11029
|
+
id: "agent-preset",
|
|
11030
|
+
order: -10,
|
|
11031
|
+
priority: -10,
|
|
11032
|
+
locale: namespace,
|
|
11033
|
+
inject: () => ({
|
|
11034
|
+
t,
|
|
11035
|
+
hostT: (key) => hostT(key),
|
|
11036
|
+
roster: {
|
|
11037
|
+
subscribe: roster.subscribe,
|
|
11038
|
+
getSnapshot: roster.getSnapshot,
|
|
11039
|
+
load: () => roster.load()
|
|
11040
|
+
}
|
|
11041
|
+
})
|
|
11042
|
+
}, ClaudeAgentPresetLabel));
|
|
11043
|
+
}
|
|
11044
|
+
ctx.slots.inject("conversation.session.header.utilities", () => ctx.slots.register({
|
|
11045
|
+
name: "conversation.session.header.utilities",
|
|
11046
|
+
id: "claude-diff",
|
|
11047
|
+
order: 30,
|
|
11048
|
+
locale: namespace,
|
|
11049
|
+
inject: (sessionId) => ({
|
|
11050
|
+
t,
|
|
11051
|
+
toggleDiff: () => {
|
|
11052
|
+
if (diffOpen.isOpen(sessionId)) closePluginDetails();
|
|
11053
|
+
else openDiffPanel(sessionId);
|
|
11054
|
+
},
|
|
11055
|
+
diffOpen: diffOpen.sourceFor(sessionId)
|
|
11056
|
+
})
|
|
11057
|
+
}, ClaudeDiffHeaderAction));
|
|
10675
11058
|
ctx.slots.inject("conversation.input.dock", () => ctx.slots.register({
|
|
10676
11059
|
name: "conversation.input.dock",
|
|
10677
11060
|
id: "claude-review-comments",
|