@norman-else/dsh-claude 0.1.51 → 0.1.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -1957,50 +1957,6 @@ window.__ModuleLoader__.load({
1957
1957
  borderColor: "color-mix(in srgb, #a78bfa 35%, transparent)",
1958
1958
  background: "color-mix(in srgb, #a78bfa 5%, var(--dsw-alias-bg-layer-1))"
1959
1959
  };
1960
- /** The linked bars as one stack, the fold control floating centred above. */
1961
- const linkedStack = { position: "relative" };
1962
- /** Two chevron glyphs stacked into one double chevron: 14px tall in all,
1963
- * the second pulled up over the first. */
1964
- const linkedFoldGlyph = {
1965
- display: "flex",
1966
- flexDirection: "column",
1967
- alignItems: "center",
1968
- height: 14,
1969
- marginTop: 2
1970
- };
1971
- const linkedFoldGlyphClass = "dshClaudeLinkedFoldGlyph";
1972
- /** The second chevron rides 7px up over the first. */
1973
- const linkedFoldGlyphCss = `
1974
- .${linkedFoldGlyphClass} > svg + svg { margin-top: -7px; }
1975
- `;
1976
- /** The fold control, drawn to the Host's jump-to-latest recipe exactly: a
1977
- * 34px circle on the floating fill, no border of its own -- the stroke is
1978
- * the elevation's, set through the same variable the Host sets -- and the
1979
- * circle asked for by name, since the Host's theme rounds as squircles.
1980
- * Where it sits comes from the component. Holds only the double chevron;
1981
- * the count lives in its tooltip. */
1982
- const linkedFoldChip = {
1983
- position: "absolute",
1984
- zIndex: 8,
1985
- boxSizing: "border-box",
1986
- display: "flex",
1987
- alignItems: "center",
1988
- justifyContent: "center",
1989
- width: 34,
1990
- height: 34,
1991
- padding: 0,
1992
- border: 0,
1993
- borderRadius: 100,
1994
- cornerShape: "round",
1995
- "--dsw-elevation-stroke-color": "var(--dsw-alias-border-l3)",
1996
- background: "var(--dsw-alias-button-floating-fill)",
1997
- color: "var(--dsw-alias-label-primary)",
1998
- boxShadow: "var(--dsw-elevation-panel)",
1999
- font: "inherit",
2000
- cursor: "pointer",
2001
- transition: "right .15s ease"
2002
- };
2003
- /** The folded count beside the chevrons. */
2004
1960
  /** A checkout the session wrote into besides its own: lighter, dashed, and
2005
1961
  * stacked above the session bar so it reads as attached rather than primary.
2006
1962
  * It keeps the bar's opaque fill: the dock floats over the end of the
@@ -8127,6 +8083,26 @@ window.__ModuleLoader__.load({
8127
8083
  throw actionError(error);
8128
8084
  }
8129
8085
  }
8086
+ /** Title and Summary/Changes body for the pull request the branch would open;
8087
+ * `baseBranch` empty means origin's default branch. */
8088
+ async function generatePullRequestText(sessionId, fingerprint, baseBranch, signal, root) {
8089
+ try {
8090
+ const value = record$3(await pluginWrite(`${CLAUDE_REPOSITORY_ACTION_PATH}/pull-request`, "remote", signal, {
8091
+ query: sessionQuery(sessionId, root),
8092
+ json: {
8093
+ fingerprint,
8094
+ ...baseBranch === void 0 || baseBranch.trim() === "" ? {} : { baseBranch: baseBranch.trim() }
8095
+ }
8096
+ }));
8097
+ if (typeof value?.title !== "string" || typeof value.body !== "string") throw new Error("Invalid generated pull request text.");
8098
+ return {
8099
+ title: value.title,
8100
+ body: value.body
8101
+ };
8102
+ } catch (error) {
8103
+ throw actionError(error);
8104
+ }
8105
+ }
8130
8106
  async function executeRepositoryAction(sessionId, request, root) {
8131
8107
  try {
8132
8108
  return result(await pluginWrite(CLAUDE_REPOSITORY_ACTION_PATH, "remote", void 0, {
@@ -9645,143 +9621,24 @@ window.__ModuleLoader__.load({
9645
9621
  ]
9646
9622
  });
9647
9623
  }
9648
- const linkedExpanded = /* @__PURE__ */ new Map();
9649
- /** Where the Host's jump-to-latest button sits relative to the linked
9650
- * stack, remembered from the last time it was on screen: the seat the fold
9651
- * control takes while the Host's button is away. Until it has been seen
9652
- * once, the Host's own geometry: 16px in from the column's edge, 16px above
9653
- * the composer. */
9654
- let hostSeat = {
9655
- top: -50,
9656
- rightInset: 16
9657
- };
9658
- const HOST_JUMP_GAP = 8;
9659
- /** The fold control's place: the Host's seat, or 8px left of the Host's
9660
- * button while that is showing. Found by the Host's class stem; one cheap
9661
- * query and two rects per DOM change or resize, on the next frame. */
9662
- function useHostJumpSeat(stack) {
9663
- const [seat, setSeat] = useState({
9664
- shown: false,
9665
- top: hostSeat.top,
9666
- right: hostSeat.rightInset
9667
- });
9668
- useEffect(() => {
9669
- if (typeof document === "undefined" || typeof MutationObserver === "undefined") return;
9670
- let frame;
9671
- const check = () => {
9672
- frame = void 0;
9673
- const native = document.querySelector("button[class*=\"toBottom\"]");
9674
- const frameRect = stack.current?.getBoundingClientRect();
9675
- if (native === null || frameRect === void 0) {
9676
- setSeat({
9677
- shown: false,
9678
- top: hostSeat.top,
9679
- right: hostSeat.rightInset
9680
- });
9681
- return;
9682
- }
9683
- const rect = native.getBoundingClientRect();
9684
- if (rect.width > 0) hostSeat = {
9685
- top: rect.top - frameRect.top,
9686
- rightInset: frameRect.right - rect.right
9687
- };
9688
- setSeat({
9689
- shown: true,
9690
- top: hostSeat.top,
9691
- right: frameRect.right - rect.left + HOST_JUMP_GAP
9692
- });
9693
- };
9694
- const schedule = () => {
9695
- if (frame === void 0) frame = requestAnimationFrame(check);
9696
- };
9697
- check();
9698
- const observer = new MutationObserver(schedule);
9699
- observer.observe(document.body, {
9700
- childList: true,
9701
- subtree: true
9702
- });
9703
- window.addEventListener("resize", schedule);
9704
- return () => {
9705
- observer.disconnect();
9706
- window.removeEventListener("resize", schedule);
9707
- if (frame !== void 0) cancelAnimationFrame(frame);
9708
- };
9709
- }, [stack]);
9710
- return seat;
9711
- }
9712
- /** The fold control floats above the dock in the Host's jump-to-latest seat,
9713
- * stepping left of that button while the Host shows it: a circle holding a
9714
- * double chevron pointing where the bars will go -- up while folded, since
9715
- * unfolding stacks more bars upward; down once open, since folding pulls
9716
- * them back down toward the composer. The count and the words live in its
9717
- * tooltip and accessible name. */
9718
- function LinkedFoldChip({ sessionId, hidden, expanded, onToggle, t, seat }) {
9719
- const label = expanded ? t("linkedCollapse") : `${t("linkedMore", { count: hidden })} · ${t("linkedShowAll")}`;
9720
- return /* @__PURE__ */ jsx(Tooltip, {
9721
- label,
9722
- side: "top",
9723
- delayMs: 250,
9724
- children: /* @__PURE__ */ jsx("button", {
9725
- type: "button",
9726
- style: {
9727
- ...linkedFoldChip,
9728
- top: seat.top,
9729
- right: seat.right
9730
- },
9731
- "aria-expanded": expanded,
9732
- "aria-label": label,
9733
- "data-dsh-claude-linked-fold": sessionId,
9734
- onClick: onToggle,
9735
- children: /* @__PURE__ */ jsx("span", {
9736
- className: linkedFoldGlyphClass,
9737
- style: linkedFoldGlyph,
9738
- "aria-hidden": "true",
9739
- children: expanded ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(IconChevronDownOutline14, {}), /* @__PURE__ */ jsx(IconChevronDownOutline14, {})] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(IconChevronUpOutline14, {}), /* @__PURE__ */ jsx(IconChevronUpOutline14, {})] })
9740
- })
9741
- })
9742
- });
9743
- }
9744
9624
  function ClaudeRepositoryStatus({ sessionId, useSessions, useClaudeProjection, t, openDiff, submitPrompt, openOverview, deleteWorkspace }) {
9745
9625
  const blank = useSessions((value) => value.byId[sessionId]?.blank === true);
9746
9626
  const running = useSessions((value) => value.byId[sessionId]?.running === true);
9747
9627
  const projection = useClaudeProjection((value) => value);
9748
9628
  const repository = projection.repository;
9749
9629
  const { toast, report } = useActionToast();
9750
- const [expanded, setExpanded] = useState(() => linkedExpanded.get(sessionId) ?? false);
9751
- useEffect(() => {
9752
- setExpanded(linkedExpanded.get(sessionId) ?? false);
9753
- }, [sessionId]);
9754
- const stackRef = useRef(null);
9755
- const seat = useHostJumpSeat(stackRef);
9756
9630
  if (blank || !projection.owned || repository === void 0) return null;
9757
9631
  const branch = branchLabel(repository, t);
9758
9632
  const merged = repository.pullRequest?.state === "merged";
9759
- const all = projection.repositories ?? [];
9760
- const shown = expanded ? all : all.slice(0, 3);
9761
- const linked = all.length === 0 ? null : /* @__PURE__ */ jsxs("div", {
9762
- ref: stackRef,
9763
- style: linkedStack,
9764
- children: [all.length > 3 ? /* @__PURE__ */ jsx(LinkedFoldChip, {
9765
- sessionId,
9766
- hidden: all.length - 3,
9767
- expanded,
9768
- seat,
9769
- t,
9770
- onToggle: () => {
9771
- const next = !expanded;
9772
- setExpanded(next);
9773
- linkedExpanded.set(sessionId, next);
9774
- }
9775
- }) : null, shown.map((item) => /* @__PURE__ */ jsx(LinkedRepositoryBar, {
9776
- sessionId,
9777
- repository: item,
9778
- running,
9779
- t,
9780
- openDiff,
9781
- report,
9782
- ...submitPrompt === void 0 ? {} : { submitPrompt }
9783
- }, item.root ?? `${item.remote ?? item.cwd}#${item.pullRequest?.number ?? ""}`))]
9784
- });
9633
+ const linked = (projection.repositories ?? []).map((item) => /* @__PURE__ */ jsx(LinkedRepositoryBar, {
9634
+ sessionId,
9635
+ repository: item,
9636
+ running,
9637
+ t,
9638
+ openDiff,
9639
+ report,
9640
+ ...submitPrompt === void 0 ? {} : { submitPrompt }
9641
+ }, item.root ?? `${item.remote ?? item.cwd}#${item.pullRequest?.number ?? ""}`));
9785
9642
  if (repository.status !== "ready") return /* @__PURE__ */ jsxs("div", {
9786
9643
  style: repositoryBarFrame,
9787
9644
  [CLAUDE_COMPOSER_BAR_ATTRIBUTE]: "",
@@ -9800,9 +9657,9 @@ window.__ModuleLoader__.load({
9800
9657
  style: repositoryBarFrame,
9801
9658
  [CLAUDE_COMPOSER_BAR_ATTRIBUTE]: "",
9802
9659
  children: [
9803
- /* @__PURE__ */ jsxs("style", {
9660
+ /* @__PURE__ */ jsx("style", {
9804
9661
  "data-dsh-claude-repository-bar-styles": true,
9805
- children: [repositoryAutoFixCss, linkedFoldGlyphCss]
9662
+ children: repositoryAutoFixCss
9806
9663
  }),
9807
9664
  toast,
9808
9665
  linked,
@@ -15420,10 +15277,15 @@ window.__ModuleLoader__.load({
15420
15277
  loading: true,
15421
15278
  submitting: false
15422
15279
  });
15423
- const generated = await generateCommitMessage(sessionId, preview.fingerprint, controller.signal, root);
15424
- setMessage((current) => current.trim() === "" ? generated : current);
15425
- setPrTitle((current) => current.trim() === "" ? generated : current);
15426
- setPrBody((current) => current.trim() === "" ? `Summary: ${generated}\n\nChanges:\n- ${generated}` : current);
15280
+ if (action === "create-pr") {
15281
+ const [pullRequest, generated] = await Promise.all([generatePullRequestText(sessionId, preview.fingerprint, void 0, controller.signal, root), preview.files.length > 0 ? generateCommitMessage(sessionId, preview.fingerprint, controller.signal, root) : Promise.resolve(void 0)]);
15282
+ setMessage((current) => current.trim() === "" ? generated ?? pullRequest.title : current);
15283
+ setPrTitle((current) => current.trim() === "" ? pullRequest.title : current);
15284
+ setPrBody((current) => current.trim() === "" ? pullRequest.body : current);
15285
+ } else {
15286
+ const generated = await generateCommitMessage(sessionId, preview.fingerprint, controller.signal, root);
15287
+ setMessage((current) => current.trim() === "" ? generated : current);
15288
+ }
15427
15289
  setDialog((current) => current === void 0 ? current : {
15428
15290
  ...current,
15429
15291
  loading: false
@@ -15988,7 +15850,7 @@ window.__ModuleLoader__.load({
15988
15850
  children: [t("diffCommitMessage"), /* @__PURE__ */ jsx("textarea", {
15989
15851
  style: diffModalTextarea,
15990
15852
  value: message,
15991
- maxLength: 512,
15853
+ maxLength: 2048,
15992
15854
  onChange: (event) => setMessage(event.currentTarget.value)
15993
15855
  })]
15994
15856
  })
@@ -19203,9 +19065,6 @@ window.__ModuleLoader__.load({
19203
19065
  presetHeaderHint: "当前会话运行的 Agent 预设",
19204
19066
  diffRepository: "仓库",
19205
19067
  repositoryLinked: "关联仓库:本会话改动过",
19206
- linkedMore: "还有 {count} 个关联仓库",
19207
- linkedShowAll: "全部展开",
19208
- linkedCollapse: "收起关联仓库",
19209
19068
  linkedRepositoryPrompt: "以下内容针对关联仓库 {root}(分支 {branch}),不是本会话自己的仓库。",
19210
19069
  diffFiles: "{count} 个已修改文件",
19211
19070
  diffFilesShort: "{count} 个文件",
@@ -19647,9 +19506,6 @@ window.__ModuleLoader__.load({
19647
19506
  presetHeaderHint: "The agent preset this session runs",
19648
19507
  diffRepository: "Repository",
19649
19508
  repositoryLinked: "Linked repository: changed by this session",
19650
- linkedMore: "{count} more linked repositories",
19651
- linkedShowAll: "Show all",
19652
- linkedCollapse: "Collapse linked repositories",
19653
19509
  linkedRepositoryPrompt: "The following concerns the linked repository at {root} (branch {branch}), not this session's own checkout.",
19654
19510
  diffFiles: "{count} modified file(s)",
19655
19511
  diffFilesShort: "{count} files",