@norman-else/dsh-claude 0.1.52 → 0.1.54

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
@@ -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 { Button, DiffBlock, DisclosureRow, HoverCard, IconAgentPresetOutline16, IconApiOutline14, IconBranchOutline16, IconCheckOutline14, IconCheckOutline16, IconChevronDownOutline14, IconChevronRightOutline14, IconChevronUpOutline14, IconCloseOutline16, IconEditOutline16, IconListPenOutline16, IconLoadingOutline16, IconQueueOutline14, IconRefreshOutline14, IconRefreshOutline16, IconRightUpOutline14, IconSearchOutline16, IconSendOutline14, IconSparkle16, IconThinkOutline14, IconTrashOutline16, MarkdownText, Menu, Modal, StateDot, Toast, Tooltip, useDismissOnOutsidePointer } = require("@deepseek-ai/dsh-client-ui-primitives");
7
+ var { Button, DiffBlock, DisclosureRow, HoverCard, IconAgentPresetOutline16, IconApiOutline14, IconBranchOutline16, IconCheckOutline14, IconCheckOutline16, IconChevronDownOutline14, IconChevronRightOutline14, IconChevronUpOutline14, IconCloseOutline16, IconEditOutline16, IconListPenOutline16, IconLoadingOutline16, IconQueueOutline14, IconRefreshOutline14, IconRefreshOutline16, IconRightUpOutline14, IconSearchOutline16, IconSendOutline14, IconSparkle16, IconThinkOutline14, IconTrashOutline16, MarkdownText, Menu, Modal, RiskConfirmation, StateDot, Toast, Tooltip, useDismissOnOutsidePointer } = 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
@@ -26,6 +26,7 @@ window.__ModuleLoader__.load({
26
26
  const CLAUDE_JIRA_PATH = "/plugins/dsh-claude/jira";
27
27
  const CLAUDE_ASK_PATH = "/plugins/dsh-claude/ask";
28
28
  const CLAUDE_REWIND_PATH = "/plugins/dsh-claude/rewind";
29
+ const CLAUDE_PERMISSION_MODE_PATH = "/plugins/dsh-claude/permission-mode";
29
30
  const CLAUDE_PLAN_FEEDBACK_PATH = "/plugins/dsh-claude/plan/feedback";
30
31
  const CLAUDE_PROMPTS_PATH = "/plugins/dsh-claude/prompts";
31
32
  const CLAUDE_PROMPT_NAME_PATH = "/plugins/dsh-claude/prompts/name";
@@ -2293,15 +2294,18 @@ window.__ModuleLoader__.load({
2293
2294
  zIndex: 1100,
2294
2295
  bottom: "calc(100% + 8px)",
2295
2296
  right: 0,
2296
- width: 320,
2297
+ width: 360,
2298
+ maxWidth: "calc(100vw - 32px)",
2299
+ maxHeight: "min(480px, calc(100dvh - 48px))",
2300
+ overflowY: "auto",
2297
2301
  boxSizing: "border-box",
2298
2302
  display: "flex",
2299
2303
  flexDirection: "column",
2300
2304
  alignItems: "stretch",
2301
- gap: 8,
2302
- padding: 12,
2305
+ gap: 12,
2306
+ padding: 18,
2303
2307
  border: "1px solid var(--dsw-alias-border-l2, color-mix(in srgb, currentColor 16%, transparent))",
2304
- borderRadius: 10,
2308
+ borderRadius: 14,
2305
2309
  background: "var(--dsw-specific-menu, var(--dsw-alias-bg-layer-1))",
2306
2310
  boxShadow: "var(--dsw-shadow-lv3)",
2307
2311
  textAlign: "left",
@@ -2309,8 +2313,11 @@ window.__ModuleLoader__.load({
2309
2313
  };
2310
2314
  const repositoryChecksTitle = {
2311
2315
  color: "var(--dsw-alias-label-primary)",
2312
- fontSize: 12,
2313
- fontWeight: 650
2316
+ fontSize: 14,
2317
+ fontWeight: 650,
2318
+ lineHeight: "22px",
2319
+ paddingBottom: 10,
2320
+ borderBottom: "1px solid var(--dsw-alias-border-l2)"
2314
2321
  };
2315
2322
  const repositoryChecksHint = {
2316
2323
  color: "var(--dsw-alias-label-tertiary)",
@@ -2323,8 +2330,11 @@ window.__ModuleLoader__.load({
2323
2330
  const repositoryChecksItem = {
2324
2331
  display: "flex",
2325
2332
  flexDirection: "column",
2326
- gap: 2,
2327
- minWidth: 0
2333
+ gap: 5,
2334
+ minWidth: 0,
2335
+ padding: "10px 12px",
2336
+ borderRadius: 8,
2337
+ background: "var(--dsw-alias-bg-layer-2)"
2328
2338
  };
2329
2339
  const repositoryChecksName = {
2330
2340
  color: "var(--dsw-alias-label-primary)",
@@ -2337,14 +2347,13 @@ window.__ModuleLoader__.load({
2337
2347
  const repositoryChecksDesc = {
2338
2348
  color: "var(--dsw-alias-label-tertiary)",
2339
2349
  fontSize: 11,
2340
- overflow: "hidden",
2341
- textOverflow: "ellipsis",
2342
- whiteSpace: "nowrap"
2350
+ lineHeight: "18px",
2351
+ overflowWrap: "anywhere"
2343
2352
  };
2344
2353
  const repositoryChecksFix = {
2345
2354
  alignSelf: "flex-end",
2346
- minHeight: 26,
2347
- padding: "3px 10px",
2355
+ minHeight: 32,
2356
+ padding: "6px 12px",
2348
2357
  border: "none",
2349
2358
  borderRadius: 7,
2350
2359
  background: "var(--dsw-static-blue-450)",
@@ -2605,10 +2614,11 @@ window.__ModuleLoader__.load({
2605
2614
  boxSizing: "border-box",
2606
2615
  display: "flex",
2607
2616
  flexDirection: "column",
2608
- gap: 10,
2609
- padding: 12,
2617
+ gap: 14,
2618
+ padding: 18,
2619
+ overflowY: "auto",
2610
2620
  border: askSurfaceBorder,
2611
- borderRadius: 12,
2621
+ borderRadius: 14,
2612
2622
  background: "var(--dsw-alias-bg-layer-1)",
2613
2623
  color: "var(--dsw-alias-label-primary)",
2614
2624
  boxShadow: askSurfaceShadow,
@@ -2621,7 +2631,7 @@ window.__ModuleLoader__.load({
2621
2631
  WebkitLineClamp: 3,
2622
2632
  WebkitBoxOrient: "vertical",
2623
2633
  margin: 0,
2624
- padding: "6px 10px",
2634
+ padding: "10px 12px",
2625
2635
  overflow: "hidden",
2626
2636
  borderLeft: "3px solid color-mix(in srgb, var(--dsw-static-blue-450) 60%, transparent)",
2627
2637
  borderRadius: 6,
@@ -2642,7 +2652,8 @@ window.__ModuleLoader__.load({
2642
2652
  };
2643
2653
  const askTextarea = {
2644
2654
  width: "100%",
2645
- minHeight: 64,
2655
+ minHeight: 88,
2656
+ flexShrink: 0,
2646
2657
  boxSizing: "border-box",
2647
2658
  padding: "8px 10px",
2648
2659
  border: askSurfaceBorder,
@@ -2660,7 +2671,10 @@ window.__ModuleLoader__.load({
2660
2671
  display: "flex",
2661
2672
  alignItems: "center",
2662
2673
  justifyContent: "flex-end",
2663
- gap: 6
2674
+ gap: 8,
2675
+ flexWrap: "wrap",
2676
+ paddingTop: 12,
2677
+ borderTop: "1px solid var(--dsw-alias-border-l2)"
2664
2678
  };
2665
2679
  const askAnswer = {
2666
2680
  flex: "1 1 auto",
@@ -2670,8 +2684,8 @@ window.__ModuleLoader__.load({
2670
2684
  wordBreak: "break-word"
2671
2685
  };
2672
2686
  const askButton = {
2673
- minHeight: 26,
2674
- padding: "3px 10px",
2687
+ minHeight: 32,
2688
+ padding: "6px 12px",
2675
2689
  border: askSurfaceBorder,
2676
2690
  borderRadius: 7,
2677
2691
  outline: "none",
@@ -3160,8 +3174,8 @@ window.__ModuleLoader__.load({
3160
3174
  .${promptSaveFieldClass} {
3161
3175
  box-sizing: border-box;
3162
3176
  width: 100%;
3163
- height: 30px;
3164
- padding: 0 9px;
3177
+ height: 38px;
3178
+ padding: 0 11px;
3165
3179
  border: 1px solid var(--dsw-alias-border-inverted);
3166
3180
  border-radius: 7px;
3167
3181
  background: var(--dsw-alias-interactive-bg-hover);
@@ -3199,12 +3213,14 @@ window.__ModuleLoader__.load({
3199
3213
  boxSizing: "border-box",
3200
3214
  display: "flex",
3201
3215
  flexDirection: "column",
3202
- gap: 8,
3203
- width: 340,
3216
+ gap: 14,
3217
+ width: 360,
3204
3218
  maxWidth: "calc(100vw - 32px)",
3205
- padding: "10px 12px",
3219
+ maxHeight: "calc(100dvh - 32px)",
3220
+ overflowY: "auto",
3221
+ padding: 18,
3206
3222
  border: "1px solid var(--dsw-alias-border-inverted)",
3207
- borderRadius: 11,
3223
+ borderRadius: 14,
3208
3224
  background: "var(--dsw-specific-menu)",
3209
3225
  boxShadow: "var(--dsw-shadow-lv3)",
3210
3226
  color: "var(--dsw-alias-label-primary)",
@@ -3212,14 +3228,17 @@ window.__ModuleLoader__.load({
3212
3228
  lineHeight: "20px"
3213
3229
  };
3214
3230
  const promptSaveHeading = {
3215
- color: "var(--dsw-alias-label-tertiary)",
3216
- fontSize: 11,
3217
- lineHeight: "16px"
3231
+ color: "var(--dsw-alias-label-primary)",
3232
+ fontSize: 14,
3233
+ fontWeight: 600,
3234
+ lineHeight: "22px"
3218
3235
  };
3219
3236
  const promptSaveActions = {
3220
3237
  display: "flex",
3221
3238
  justifyContent: "flex-end",
3222
- gap: 6
3239
+ gap: 8,
3240
+ paddingTop: 12,
3241
+ borderTop: "1px solid var(--dsw-alias-border-l2)"
3223
3242
  };
3224
3243
  /** The saved file, wrapped rather than truncated: a path the user cannot read
3225
3244
  * in full does not tell them where to go and edit it. */
@@ -3227,7 +3246,10 @@ window.__ModuleLoader__.load({
3227
3246
  color: "var(--dsw-alias-label-tertiary)",
3228
3247
  fontSize: 11,
3229
3248
  lineHeight: "16px",
3230
- overflowWrap: "anywhere"
3249
+ overflowWrap: "anywhere",
3250
+ padding: "10px 12px",
3251
+ borderRadius: 8,
3252
+ background: "var(--dsw-alias-bg-layer-2)"
3231
3253
  };
3232
3254
  const promptSaveError = {
3233
3255
  color: "var(--dsw-static-red-450, #d64545)",
@@ -3310,6 +3332,7 @@ window.__ModuleLoader__.load({
3310
3332
  cursor: "pointer"
3311
3333
  };
3312
3334
  const diffRepositoryTriggerClass = "dshClaudeDiffRepositoryTrigger";
3335
+ const diffFileHeaderClass = "dshClaudeDiffFileHeader";
3313
3336
  /** The checkout switch: a quiet pill in the header's own type, lit on hover
3314
3337
  * and while its menu is open, with the chevron set off in a lighter tone. */
3315
3338
  const diffRepositoryCss = `
@@ -3344,6 +3367,15 @@ window.__ModuleLoader__.load({
3344
3367
  flex: none;
3345
3368
  color: var(--dsw-alias-label-tertiary);
3346
3369
  }
3370
+ /* Sticky headers each form a stacking context, so the host Tooltip bubble
3371
+ (rendered inline, position: fixed) is painted under the next file's header.
3372
+ Lift the hovered header above its siblings while the bubble can be open. */
3373
+ .${diffFileHeaderClass} {
3374
+ z-index: 1;
3375
+ }
3376
+ .${diffFileHeaderClass}:hover {
3377
+ z-index: 2;
3378
+ }
3347
3379
  `;
3348
3380
  /** A row of the checkout menu: name left, its counts right in tabular figures. */
3349
3381
  const diffRepositoryRow = {
@@ -3394,7 +3426,6 @@ window.__ModuleLoader__.load({
3394
3426
  const diffFileHeader = {
3395
3427
  position: "sticky",
3396
3428
  top: 0,
3397
- zIndex: 1,
3398
3429
  width: "100%",
3399
3430
  minHeight: 38,
3400
3431
  display: "flex",
@@ -3630,6 +3661,107 @@ window.__ModuleLoader__.load({
3630
3661
  outline: none;
3631
3662
  box-shadow: inset 0 0 0 1px var(--dsw-static-blue-450);
3632
3663
  }
3664
+ .dshClaudeUtilityDialog {
3665
+ width: min(580px, calc(100vw - 32px));
3666
+ max-width: calc(100vw - 32px);
3667
+ max-height: calc(100dvh - 32px);
3668
+ gap: 0;
3669
+ padding: 0;
3670
+ border: 1px solid var(--dsw-alias-border-l2);
3671
+ border-radius: 16px;
3672
+ }
3673
+ .dshClaudeUtilityContent { box-sizing: border-box; padding: 24px; }
3674
+ .dshClaudeUtilityContent > div:first-child { padding: 0 0 12px; }
3675
+ .dshClaudeUtilityContent h2 { font-size: 19px; line-height: 28px; letter-spacing: -.3px; }
3676
+ .dshClaudeUtilityContent > p { padding: 0; margin: 0 0 20px; color: var(--dsw-alias-label-secondary); }
3677
+ .dshClaudeUtilityContent > div:last-child:not(:first-child) { padding: 0; margin-top: 0; }
3678
+ .dshClaudeUtilityDialog > div:last-child:not(.dshClaudeUtilityContent) { padding: 16px 24px; border-top: 1px solid var(--dsw-alias-border-l2); }
3679
+ .dshClaudeUtilitySummary {
3680
+ padding: 14px;
3681
+ border: 1px solid var(--dsw-alias-border-l2);
3682
+ border-radius: 10px;
3683
+ background: var(--dsw-alias-bg-layer-1);
3684
+ flex-wrap: wrap;
3685
+ align-items: center;
3686
+ }
3687
+ .dshClaudeUtilitySummary > strong { color: var(--dsw-alias-label-primary); }
3688
+ .dshClaudeUtilitySummary > span { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
3689
+ .dshClaudeUtilityOption {
3690
+ padding: 13px 14px;
3691
+ border: 1px solid var(--dsw-alias-border-l2);
3692
+ border-radius: 10px;
3693
+ line-height: 20px;
3694
+ cursor: pointer;
3695
+ }
3696
+ .dshClaudeUtilityOption input { flex-shrink: 0; }
3697
+ .dshClaudeUtilityOption:has(input:checked) { border-color: color-mix(in srgb, var(--dsw-static-blue-450) 45%, var(--dsw-alias-border-l2)); background: color-mix(in srgb, var(--dsw-static-blue-450) 5%, transparent); }
3698
+ .dshClaudeUtilityOption:has(input:disabled) { cursor: default; }
3699
+ .dshClaudeUtilityContent ul { max-height: 240px; overflow-y: auto; }
3700
+ .dshClaudeUtilityContent li { padding: 8px 4px; overflow-wrap: anywhere; }
3701
+ .dshClaudeUtilityContent li + li { border-top: 1px solid var(--dsw-alias-border-l2); }
3702
+ .dshClaudeUtilityContent [role='alert'] { padding: 12px; border-radius: 8px; background: var(--dsw-alias-bg-layer-1); overflow-wrap: anywhere; }
3703
+ .dshClaudeUtilityDialog button:focus-visible { outline: 2px solid var(--dsw-static-blue-450); outline-offset: 2px; }
3704
+ @media (max-width: 640px) {
3705
+ .dshClaudeUtilityContent { padding: 18px; }
3706
+ .dshClaudeUtilityDialog > div:last-child:not(.dshClaudeUtilityContent) { padding: 14px 18px; }
3707
+ }
3708
+ .dshClaudeCommitDialog {
3709
+ gap: 0;
3710
+ padding: 0;
3711
+ width: min(880px, calc(100vw - 32px));
3712
+ max-width: calc(100vw - 32px);
3713
+ max-height: calc(100dvh - 32px);
3714
+ border: 1px solid var(--dsw-alias-border-l2);
3715
+ border-radius: 16px;
3716
+ overflow: hidden;
3717
+ }
3718
+ .dshClaudeCommitContent { padding: 24px; box-sizing: border-box; }
3719
+ .dshClaudeCommitContent > div:first-child { padding: 0 0 16px; }
3720
+ .dshClaudeCommitContent > div:last-child:not(:first-child) { padding: 0; margin-top: 0; }
3721
+ .dshClaudeCommitContent h2 { font-size: 19px; line-height: 28px; letter-spacing: -.3px; }
3722
+ .dshClaudeCommitContext {
3723
+ display: flex;
3724
+ align-items: center;
3725
+ flex-wrap: wrap;
3726
+ gap: 8px;
3727
+ padding-bottom: 18px;
3728
+ border-bottom: 1px solid var(--dsw-alias-border-l2);
3729
+ color: var(--dsw-alias-label-secondary);
3730
+ font-size: 12px;
3731
+ overflow-wrap: anywhere;
3732
+ }
3733
+ .dshClaudeCommitContext strong { color: var(--dsw-alias-label-primary); margin-right: 4px; }
3734
+ .dshClaudeCommitBranch {
3735
+ min-width: 0;
3736
+ padding: 3px 8px;
3737
+ border-radius: 6px;
3738
+ background: var(--dsw-alias-bg-layer-1);
3739
+ font-family: ui-monospace, monospace;
3740
+ }
3741
+ .dshClaudeCommitGrid { display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); gap: 24px; }
3742
+ .dshClaudeCommitSection, .dshClaudeCommitEditor { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
3743
+ .dshClaudeCommitSection h3 { margin: 0; font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-secondary); }
3744
+ .dshClaudeCommitChanges { padding-right: 24px; border-right: 1px solid var(--dsw-alias-border-l2); }
3745
+ .dshClaudeCommitFiles { max-height: 320px; overflow-y: auto; min-width: 0; }
3746
+ .dshClaudeCommitFile { display: flex; align-items: center; gap: 10px; padding: 11px 0; font-size: 12px; line-height: 18px; }
3747
+ .dshClaudeCommitFile + .dshClaudeCommitFile { border-top: 1px solid var(--dsw-alias-border-l2); }
3748
+ .dshClaudeCommitPath { flex: 1; min-width: 0; overflow-wrap: anywhere; }
3749
+ .dshClaudeCommitState { flex: none; max-width: 45%; padding: 2px 6px; border-radius: 4px; background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-secondary); font-size: 10px; line-height: 16px; }
3750
+ .dshClaudeCommitState[data-staged='true'] { color: var(--dsw-static-green-450, var(--dsw-alias-label-primary)); }
3751
+ .dshClaudeCommitHash { flex: none; color: var(--dsw-alias-label-secondary); font-size: 11px; }
3752
+ .dshClaudeCommitEditor textarea, .dshClaudeCommitEditor input { border-radius: 8px; }
3753
+ .dshClaudeCommitEditor textarea { width: 100%; box-sizing: border-box; }
3754
+ .dshClaudeCommitHint { margin: -6px 0 0; color: var(--dsw-alias-label-secondary); font-size: 11px; line-height: 18px; }
3755
+ .dshClaudeCommitProgress { margin: 0 0 16px; padding: 10px 12px; border-radius: 8px; background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-secondary); font-size: 12px; line-height: 18px; }
3756
+ .dshClaudeCommitDialog > div:last-child:not(.dshClaudeCommitContent) { padding: 16px 24px; border-top: 1px solid var(--dsw-alias-border-l2); }
3757
+ .dshClaudeCommitDialog button:focus-visible { outline: 2px solid var(--dsw-static-blue-450); outline-offset: 2px; }
3758
+ @media (max-width: 640px) {
3759
+ .dshClaudeCommitContent { padding: 18px; }
3760
+ .dshClaudeCommitGrid { grid-template-columns: minmax(0, 1fr); gap: 20px; }
3761
+ .dshClaudeCommitChanges { padding: 0 0 18px; border-right: 0; border-bottom: 1px solid var(--dsw-alias-border-l2); }
3762
+ .dshClaudeCommitFiles { max-height: 180px; }
3763
+ .dshClaudeCommitDialog > div:last-child:not(.dshClaudeCommitContent) { padding: 14px 18px; }
3764
+ }
3633
3765
  `;
3634
3766
  const diffModalBody = {
3635
3767
  display: "flex",
@@ -3654,31 +3786,6 @@ window.__ModuleLoader__.load({
3654
3786
  textOverflow: "ellipsis",
3655
3787
  whiteSpace: "nowrap"
3656
3788
  };
3657
- const diffModalFiles = {
3658
- minWidth: 0,
3659
- maxHeight: 300,
3660
- overflowX: "hidden",
3661
- overflowY: "auto",
3662
- border: "1px solid var(--dsw-alias-border-l2, color-mix(in srgb, currentColor 16%, transparent))",
3663
- borderRadius: 8
3664
- };
3665
- const diffModalFile = {
3666
- display: "flex",
3667
- justifyContent: "space-between",
3668
- gap: 12,
3669
- minWidth: 0,
3670
- padding: "8px 12px",
3671
- borderBottom: "1px solid var(--dsw-alias-border-l2, color-mix(in srgb, currentColor 16%, transparent))",
3672
- color: "var(--dsw-alias-label-secondary)",
3673
- fontSize: 12,
3674
- lineHeight: "18px"
3675
- };
3676
- const diffModalFilePath = {
3677
- minWidth: 0,
3678
- overflow: "hidden",
3679
- textOverflow: "ellipsis",
3680
- whiteSpace: "nowrap"
3681
- };
3682
3789
  const diffModalFileState = { flex: "none" };
3683
3790
  const diffModalField = {
3684
3791
  display: "flex",
@@ -3782,6 +3889,53 @@ window.__ModuleLoader__.load({
3782
3889
  fontSize: 13,
3783
3890
  lineHeight: "20px"
3784
3891
  };
3892
+ const permissionSelectClass = "dshClaudePermissionSelect";
3893
+ const permissionSelectTriggerClass = "dshClaudePermissionSelectTrigger";
3894
+ const permissionSelectIconClass = "dshClaudePermissionSelectIcon";
3895
+ const permissionSelectLabelClass = "dshClaudePermissionSelectLabel";
3896
+ const permissionSelectChevronClass = "dshClaudePermissionSelectChevron";
3897
+ /** The Host's PermissionSelect trigger (PermissionSelect.module.css
3898
+ * `.trigger`): a 28px capsule of 13px/500 secondary text with a 4px gap,
3899
+ * hover fill, no border. Matched here so the plugin's selector sits where the
3900
+ * Host's did without the row noticing the swap. */
3901
+ const permissionSelectCss = `
3902
+ .${permissionSelectClass} { display: inline-flex; align-items: center; min-width: 0; }
3903
+ .${permissionSelectTriggerClass} {
3904
+ min-width: 0;
3905
+ max-width: 220px;
3906
+ height: 28px;
3907
+ display: inline-flex;
3908
+ align-items: center;
3909
+ gap: 4px;
3910
+ padding: 0 4px 0 8px;
3911
+ border: none;
3912
+ border-radius: 24px;
3913
+ background: transparent;
3914
+ color: var(--dsw-alias-label-secondary);
3915
+ font-size: 13px;
3916
+ font-weight: 500;
3917
+ line-height: 20px;
3918
+ cursor: pointer;
3919
+ outline: none;
3920
+ }
3921
+ .${permissionSelectTriggerClass}:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }
3922
+ .${permissionSelectTriggerClass}:disabled { cursor: default; opacity: 0.5; }
3923
+ .${permissionSelectTriggerClass}:focus-visible { outline: none; }
3924
+ .${permissionSelectIconClass} { display: inline-flex; flex: none; }
3925
+ .${permissionSelectLabelClass} { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
3926
+ .${permissionSelectChevronClass} { flex: none; transition: transform 120ms ease; }
3927
+ .${permissionSelectChevronClass}[data-open] { transform: rotate(180deg); }
3928
+ `;
3929
+ const permissionSelectRowClass = "dshClaudePermissionSelectRow";
3930
+ const permissionSelectRowNameClass = "dshClaudePermissionSelectRowName";
3931
+ const permissionSelectRowHintClass = "dshClaudePermissionSelectRowHint";
3932
+ /** A mode row: its name, and under it the one line that says what the mode
3933
+ * does. In the row rather than a native title, which the Host never draws. */
3934
+ const permissionSelectRowCss = `
3935
+ .${permissionSelectRowClass} { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
3936
+ .${permissionSelectRowNameClass} { white-space: nowrap; }
3937
+ .${permissionSelectRowHintClass} { font-size: 12px; line-height: 16px; font-weight: 400; color: var(--dsw-alias-label-tertiary); white-space: normal; max-width: 260px; }
3938
+ `;
3785
3939
  //#endregion
3786
3940
  //#region src/client/markdown-theme.ts
3787
3941
  /** Claude Code's code presentation over the Host's Markdown renderer.
@@ -4133,6 +4287,26 @@ window.__ModuleLoader__.load({
4133
4287
  return ranges.some((range) => seq >= range.start && seq <= range.end);
4134
4288
  }
4135
4289
  //#endregion
4290
+ //#region src/permission-mode.ts
4291
+ /** Every mode the selector offers, in the order it lists them: tightest
4292
+ * first. `auto` hands each ask to Claude Code's own classifier and is a
4293
+ * per-model capability, so the selector greys it out where the catalog says
4294
+ * the session's model lacks it. */
4295
+ const CLAUDE_PERMISSION_MODES = [
4296
+ "plan",
4297
+ "default",
4298
+ "acceptEdits",
4299
+ "dontAsk",
4300
+ "auto",
4301
+ "bypassPermissions"
4302
+ ];
4303
+ function isClaudePermissionMode(value) {
4304
+ return typeof value === "string" && CLAUDE_PERMISSION_MODES.includes(value);
4305
+ }
4306
+ function isClaudePermissionSelector(value) {
4307
+ return value === "plugin" || value === "native";
4308
+ }
4309
+ //#endregion
4136
4310
  //#region src/client/plugin-transport.ts
4137
4311
  /**
4138
4312
  * The plugin's only door to the network.
@@ -4441,7 +4615,7 @@ window.__ModuleLoader__.load({
4441
4615
  const MAX_REPOSITORIES = 8;
4442
4616
  const MAX_REVIEW_COMMENT_CHARS = 2e3;
4443
4617
  const MAX_TRANSCRIPT_CHARS = 64e3;
4444
- function record$7(value) {
4618
+ function record$8(value) {
4445
4619
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
4446
4620
  }
4447
4621
  function nonNegativeInteger(value) {
@@ -4451,7 +4625,7 @@ window.__ModuleLoader__.load({
4451
4625
  return value === void 0 || typeof value === "string" && value.length <= MAX_REPOSITORY_TEXT_CHARS;
4452
4626
  }
4453
4627
  function validateRepository(value) {
4454
- const repository = record$7(value);
4628
+ const repository = record$8(value);
4455
4629
  if (repository === void 0 || ![
4456
4630
  "ready",
4457
4631
  "not-repository",
@@ -4463,11 +4637,11 @@ window.__ModuleLoader__.load({
4463
4637
  "revert"
4464
4638
  ].includes(String(repository.operation)) || repository.pullRequestOnly !== void 0 && typeof repository.pullRequestOnly !== "boolean" || repository.conflicts !== void 0 && (!Array.isArray(repository.conflicts) || repository.conflicts.length > MAX_CONFLICT_PATHS || repository.conflicts.some((path) => typeof path !== "string" || path.length > MAX_REPOSITORY_TEXT_CHARS))) return false;
4465
4639
  if (repository.diff !== void 0) {
4466
- const diff = record$7(repository.diff);
4640
+ const diff = record$8(repository.diff);
4467
4641
  if (diff === void 0 || !nonNegativeInteger(diff.additions) || !nonNegativeInteger(diff.deletions) || !nonNegativeInteger(diff.files) || typeof diff.truncated !== "boolean" || diff.elided !== void 0 && !(Array.isArray(diff.elided) && diff.elided.length <= 1e3 && diff.elided.every((item) => typeof item === "string")) || diff.patch !== void 0 && (typeof diff.patch !== "string" || diff.patch.length > MAX_DIFF_CHARS)) return false;
4468
4642
  }
4469
4643
  if (repository.pullRequest === void 0) return true;
4470
- const pullRequest = record$7(repository.pullRequest);
4644
+ const pullRequest = record$8(repository.pullRequest);
4471
4645
  if (pullRequest === void 0 || !Number.isSafeInteger(pullRequest.number) || Number(pullRequest.number) <= 0 || typeof pullRequest.title !== "string" || pullRequest.title.length > MAX_REPOSITORY_TEXT_CHARS || typeof pullRequest.url !== "string" || pullRequest.url.length > MAX_REPOSITORY_TEXT_CHARS || ![
4472
4646
  "open",
4473
4647
  "closed",
@@ -4492,33 +4666,38 @@ window.__ModuleLoader__.load({
4492
4666
  }
4493
4667
  /** Validate the public route envelope before publishing it to UI components. */
4494
4668
  function parseClaudeClientProjection(value) {
4495
- const input = record$7(value);
4669
+ const input = record$8(value);
4496
4670
  if (input === void 0 || input.schemaVersion !== 1 || !nonNegativeInteger(input.revision) || typeof input.owned !== "boolean" || !Array.isArray(input.commands) || input.commands.length > MAX_COMMANDS || !Array.isArray(input.activities) || input.activities.length > MAX_ACTIVITIES) throw new Error("invalid Claude sidecar projection");
4497
4671
  for (const item of input.commands) {
4498
- const command = record$7(item);
4672
+ const command = record$8(item);
4499
4673
  if (command === void 0 || typeof command.publicName !== "string" || typeof command.claudeName !== "string" || typeof command.description !== "string" || command.hint !== void 0 && typeof command.hint !== "string" || typeof command.prefixed !== "boolean") throw new Error("invalid Claude command projection");
4500
4674
  }
4501
4675
  for (const item of input.activities) {
4502
- const activity = record$7(item);
4676
+ const activity = record$8(item);
4503
4677
  if (activity === void 0 || !nonNegativeInteger(activity.turn) || !nonNegativeInteger(activity.step) || !nonNegativeInteger(activity.ordinal) || typeof activity.kind !== "string") throw new Error("invalid Claude sidecar activity");
4504
4678
  }
4505
- if (input.contextUsage !== void 0 && record$7(input.contextUsage) === void 0) throw new Error("invalid Claude context projection");
4506
- const tasks = input.tasks === void 0 ? void 0 : record$7(input.tasks);
4679
+ if (input.contextUsage !== void 0 && record$8(input.contextUsage) === void 0) throw new Error("invalid Claude context projection");
4680
+ const tasks = input.tasks === void 0 ? void 0 : record$8(input.tasks);
4507
4681
  if (tasks !== void 0 && !Array.isArray(tasks.tasks)) throw new Error("invalid Claude tasks projection");
4508
4682
  if (input.repository !== void 0 && !validateRepository(input.repository)) throw new Error("invalid Claude repository projection");
4509
4683
  if (input.repositories !== void 0 && (!Array.isArray(input.repositories) || input.repositories.length > MAX_REPOSITORIES || !input.repositories.every(validateRepository))) throw new Error("invalid Claude repositories projection");
4510
4684
  if (input.reviewComments !== void 0) {
4511
4685
  if (!Array.isArray(input.reviewComments) || input.reviewComments.length > MAX_REVIEW_COMMENTS) throw new Error("invalid Claude review comment projection");
4512
4686
  for (const item of input.reviewComments) {
4513
- const comment = record$7(item);
4687
+ const comment = record$8(item);
4514
4688
  if (comment === void 0 || typeof comment.id !== "string" || comment.id.length === 0 || comment.id.length > 128 || typeof comment.path !== "string" || comment.path.length === 0 || comment.path.length > MAX_REPOSITORY_TEXT_CHARS || !nonNegativeInteger(comment.line) || comment.side !== "old" && comment.side !== "new" || typeof comment.text !== "string" || comment.text.length > MAX_REVIEW_COMMENT_CHARS) throw new Error("invalid Claude review comment projection");
4515
4689
  }
4516
4690
  }
4691
+ if (input.permissionSelector !== void 0 && !isClaudePermissionSelector(input.permissionSelector)) throw new Error("invalid Claude permission selector projection");
4692
+ if (input.permissionMode !== void 0) {
4693
+ const view = record$8(input.permissionMode);
4694
+ if (view === void 0 || !isClaudePermissionMode(view.mode) || typeof view.locked !== "boolean" || view.autoSupported !== void 0 && typeof view.autoSupported !== "boolean") throw new Error("invalid Claude permission mode projection");
4695
+ }
4517
4696
  if (input.rewind !== void 0) {
4518
- const ranges = record$7(input.rewind)?.ranges;
4697
+ const ranges = record$8(input.rewind)?.ranges;
4519
4698
  if (!Array.isArray(ranges) || ranges.length > 200) throw new Error("invalid Claude rewind projection");
4520
4699
  for (const item of ranges) {
4521
- const range = record$7(item);
4700
+ const range = record$8(item);
4522
4701
  if (range === void 0 || !nonNegativeInteger(range.start) || !nonNegativeInteger(range.end)) throw new Error("invalid Claude rewind projection");
4523
4702
  }
4524
4703
  }
@@ -4576,6 +4755,8 @@ window.__ModuleLoader__.load({
4576
4755
  let repositories;
4577
4756
  let reviewComments;
4578
4757
  let rewind;
4758
+ let permissionMode;
4759
+ let permissionSelector;
4579
4760
  const byStep = /* @__PURE__ */ new Map();
4580
4761
  const stepOrder = [];
4581
4762
  /** Streaming prose still being revealed: full arrived text plus shown chars. */
@@ -4657,6 +4838,8 @@ window.__ModuleLoader__.load({
4657
4838
  ...repositories === void 0 ? {} : { repositories },
4658
4839
  ...reviewComments === void 0 ? {} : { reviewComments },
4659
4840
  ...rewind === void 0 ? {} : { rewind },
4841
+ ...permissionMode === void 0 ? {} : { permissionMode },
4842
+ ...permissionSelector === void 0 ? {} : { permissionSelector },
4660
4843
  byStep: new Map(byStep)
4661
4844
  };
4662
4845
  for (const listener of [...listeners]) listener();
@@ -4738,7 +4921,7 @@ window.__ModuleLoader__.load({
4738
4921
  } catch {
4739
4922
  return;
4740
4923
  }
4741
- const event = record$7(value);
4924
+ const event = record$8(value);
4742
4925
  if (event === void 0 || typeof event.type !== "string") return;
4743
4926
  if (event.type === "checkpoint") {
4744
4927
  if (nonNegativeInteger(event.seq) && seq !== void 0 && event.seq !== seq) desync("projection-gap", `checkpoint at ${event.seq}, applied ${seq}`);
@@ -4759,6 +4942,8 @@ window.__ModuleLoader__.load({
4759
4942
  repositories = next.repositories;
4760
4943
  reviewComments = next.reviewComments;
4761
4944
  rewind = next.rewind;
4945
+ permissionMode = next.permissionMode;
4946
+ permissionSelector = next.permissionSelector;
4762
4947
  reset(next.activities);
4763
4948
  break;
4764
4949
  }
@@ -4790,13 +4975,17 @@ window.__ModuleLoader__.load({
4790
4975
  commands: event.commands,
4791
4976
  ...event.repository === void 0 ? {} : { repository: event.repository },
4792
4977
  ...event.repositories === void 0 ? {} : { repositories: event.repositories },
4793
- ...event.reviewComments === void 0 ? {} : { reviewComments: event.reviewComments }
4978
+ ...event.reviewComments === void 0 ? {} : { reviewComments: event.reviewComments },
4979
+ ...event.permissionMode === void 0 ? {} : { permissionMode: event.permissionMode },
4980
+ ...event.permissionSelector === void 0 ? {} : { permissionSelector: event.permissionSelector }
4794
4981
  });
4795
4982
  owned = event.owned;
4796
4983
  commands = event.commands;
4797
4984
  repository = event.repository;
4798
4985
  repositories = event.repositories;
4799
4986
  reviewComments = event.reviewComments;
4987
+ if (event.permissionMode !== void 0) permissionMode = event.permissionMode;
4988
+ permissionSelector = event.permissionSelector;
4800
4989
  revision += 1;
4801
4990
  break;
4802
4991
  default: return;
@@ -5158,7 +5347,7 @@ window.__ModuleLoader__.load({
5158
5347
  return value;
5159
5348
  }
5160
5349
  }
5161
- function record$6(value) {
5350
+ function record$7(value) {
5162
5351
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
5163
5352
  }
5164
5353
  function text$1(value) {
@@ -5172,7 +5361,7 @@ window.__ModuleLoader__.load({
5172
5361
  if (typeof value === "string") return value;
5173
5362
  if (typeof value === "number" || typeof value === "boolean") return String(value);
5174
5363
  if (Array.isArray(value)) return value.map(displayValue).join(", ");
5175
- return record$6(value) === void 0 ? String(value) : Object.entries(value).map(([key, item]) => `${key}: ${displayValue(item)}`).join("\n");
5364
+ return record$7(value) === void 0 ? String(value) : Object.entries(value).map(([key, item]) => `${key}: ${displayValue(item)}`).join("\n");
5176
5365
  }
5177
5366
  function Section({ title, children }) {
5178
5367
  return /* @__PURE__ */ jsxs("section", {
@@ -5277,8 +5466,8 @@ window.__ModuleLoader__.load({
5277
5466
  function ToolPresentation({ tool, t }) {
5278
5467
  const inputValue = parsedValue(tool.input);
5279
5468
  const outputValue = parsedValue(tool.output);
5280
- const input = record$6(inputValue);
5281
- const output = record$6(outputValue);
5469
+ const input = record$7(inputValue);
5470
+ const output = record$7(outputValue);
5282
5471
  const outputTitle = tool.isError === true ? t("toolError") : t("toolOutput");
5283
5472
  if (tool.diffs !== void 0) return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DiffBlock, {
5284
5473
  diffs: [...tool.diffs],
@@ -5288,7 +5477,7 @@ window.__ModuleLoader__.load({
5288
5477
  value: typeof outputValue === "string" ? outputValue : void 0
5289
5478
  })] });
5290
5479
  if (tool.toolName === "Read") {
5291
- const file = record$6(output?.file);
5480
+ const file = record$7(output?.file);
5292
5481
  const path = text$1(file?.filePath) ?? text$1(input?.file_path);
5293
5482
  const content = text$1(file?.content) ?? (typeof outputValue === "string" ? outputValue : void 0);
5294
5483
  const offset = numberValue(input?.offset) ?? 1;
@@ -5991,7 +6180,7 @@ window.__ModuleLoader__.load({
5991
6180
  }
5992
6181
  //#endregion
5993
6182
  //#region src/client/pr-feedback-api.ts
5994
- function record$5(value) {
6183
+ function record$6(value) {
5995
6184
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
5996
6185
  }
5997
6186
  /** `root` names another checkout the session wrote into; absent, the
@@ -6005,7 +6194,7 @@ window.__ModuleLoader__.load({
6005
6194
  };
6006
6195
  }
6007
6196
  function answer(value) {
6008
- const body = record$5(value);
6197
+ const body = record$6(value);
6009
6198
  if (body === void 0) throw new Error("Invalid pull request feedback response.");
6010
6199
  return body;
6011
6200
  }
@@ -6021,7 +6210,7 @@ window.__ModuleLoader__.load({
6021
6210
  }));
6022
6211
  }
6023
6212
  function reviewComment(value) {
6024
- const input = record$5(value);
6213
+ const input = record$6(value);
6025
6214
  if (input === void 0 || typeof input.id !== "number" || typeof input.path !== "string" || typeof input.author !== "string" || typeof input.body !== "string" || typeof input.url !== "string" || input.avatarUrl !== void 0 && githubAvatarUrl(input.avatarUrl) === void 0 || input.side !== "new" && input.side !== "old" || input.line !== void 0 && typeof input.line !== "number" || input.createdAt !== void 0 && typeof input.createdAt !== "string" || input.bot !== void 0 && typeof input.bot !== "boolean") return void 0;
6026
6215
  return input;
6027
6216
  }
@@ -6030,7 +6219,7 @@ window.__ModuleLoader__.load({
6030
6219
  if (!Array.isArray(body.threads)) throw new Error("Invalid pull request comments response.");
6031
6220
  const threads = [];
6032
6221
  for (const item of body.threads) {
6033
- const input = record$5(item);
6222
+ const input = record$6(item);
6034
6223
  if (input === void 0 || typeof input.id !== "string" || typeof input.path !== "string" || input.side !== "new" && input.side !== "old" || input.line !== void 0 && typeof input.line !== "number" || !Array.isArray(input.comments)) continue;
6035
6224
  const comments = input.comments.map(reviewComment).filter((value) => value !== void 0);
6036
6225
  if (comments.length === 0) continue;
@@ -6070,7 +6259,7 @@ window.__ModuleLoader__.load({
6070
6259
  if (!Array.isArray(body.users)) return [];
6071
6260
  const users = [];
6072
6261
  for (const item of body.users) {
6073
- const input = record$5(item);
6262
+ const input = record$6(item);
6074
6263
  if (input === void 0 || typeof input.login !== "string" || input.login.length === 0) continue;
6075
6264
  const avatarUrl = githubAvatarUrl(input.avatarUrl);
6076
6265
  users.push({
@@ -6085,7 +6274,7 @@ window.__ModuleLoader__.load({
6085
6274
  if (!Array.isArray(body.checks)) throw new Error("Invalid pull request checks response.");
6086
6275
  const checks = [];
6087
6276
  for (const item of body.checks) {
6088
- const input = record$5(item);
6277
+ const input = record$6(item);
6089
6278
  if (input === void 0 || typeof input.name !== "string" || input.link !== void 0 && typeof input.link !== "string" || input.description !== void 0 && typeof input.description !== "string" || input.log !== void 0 && typeof input.log !== "string") continue;
6090
6279
  checks.push(input);
6091
6280
  }
@@ -6560,7 +6749,7 @@ window.__ModuleLoader__.load({
6560
6749
  if (code !== void 0) this.code = code;
6561
6750
  }
6562
6751
  };
6563
- function record$4(value) {
6752
+ function record$5(value) {
6564
6753
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
6565
6754
  }
6566
6755
  /**
@@ -6581,7 +6770,7 @@ window.__ModuleLoader__.load({
6581
6770
  return new JiraClientError(cause.message === cause.code ? "Jira is unavailable." : cause.message, cause.code);
6582
6771
  }
6583
6772
  function payload(value) {
6584
- const body = record$4(value);
6773
+ const body = record$5(value);
6585
6774
  if (body === void 0) throw new JiraClientError("Invalid Jira response.");
6586
6775
  return body;
6587
6776
  }
@@ -6617,7 +6806,7 @@ window.__ModuleLoader__.load({
6617
6806
  if (!Array.isArray(body.tickets)) throw new JiraClientError("Invalid Jira search response.");
6618
6807
  const tickets = [];
6619
6808
  for (const item of body.tickets) {
6620
- const ticket = record$4(item);
6809
+ const ticket = record$5(item);
6621
6810
  if (ticket === void 0 || typeof ticket.key !== "string" || typeof ticket.summary !== "string" || typeof ticket.url !== "string") continue;
6622
6811
  tickets.push(ticket);
6623
6812
  }
@@ -6878,8 +7067,9 @@ window.__ModuleLoader__.load({
6878
7067
  * so an older Host cannot make a setting unreachable. */
6879
7068
  function visibleGlobalSettings(settings) {
6880
7069
  const renderer = settings.find((setting) => setting.key === "renderer");
6881
- if (renderer === void 0 || renderer.value !== "native") return settings;
6882
- return settings.filter((setting) => setting.key !== "prose");
7070
+ const withProse = renderer === void 0 || renderer.value !== "native" ? settings : settings.filter((setting) => setting.key !== "prose");
7071
+ const selector = settings.find((setting) => setting.key === "permissionSelector");
7072
+ return selector === void 0 || selector.value !== "native" ? withProse : withProse.filter((setting) => setting.key !== "permissionMode");
6883
7073
  }
6884
7074
  /** Per-setting label and the effect note that used to sit as a standalone
6885
7075
  * paragraph under the card; it now hangs off the label as a hover hint. */
@@ -6888,6 +7078,14 @@ window.__ModuleLoader__.load({
6888
7078
  label: "outputStyle",
6889
7079
  hint: "globalSettingsNewSession"
6890
7080
  },
7081
+ permissionSelector: {
7082
+ label: "permissionSelector",
7083
+ hint: "permissionSelectorEffect"
7084
+ },
7085
+ permissionMode: {
7086
+ label: "defaultPermissionMode",
7087
+ hint: "defaultPermissionModeEffect"
7088
+ },
6891
7089
  renderer: {
6892
7090
  label: "renderer",
6893
7091
  hint: "rendererEffect"
@@ -6917,6 +7115,14 @@ window.__ModuleLoader__.load({
6917
7115
  * keyed `<setting>:<option>`. Options discovered on the machine (output style
6918
7116
  * names) carry no entry and keep the label the route reported. */
6919
7117
  const SETTING_OPTION_COPY = {
7118
+ "permissionSelector:plugin": "permissionSelectorPlugin",
7119
+ "permissionSelector:native": "permissionSelectorNative",
7120
+ "permissionMode:plan": "permissionModePlan",
7121
+ "permissionMode:default": "permissionModeDefault",
7122
+ "permissionMode:acceptEdits": "permissionModeAcceptEdits",
7123
+ "permissionMode:dontAsk": "permissionModeDontAsk",
7124
+ "permissionMode:auto": "permissionModeAuto",
7125
+ "permissionMode:bypassPermissions": "permissionModeBypass",
6920
7126
  "renderer:plugin": "rendererPlugin",
6921
7127
  "renderer:native": "rendererNative",
6922
7128
  "prose:plain": "prosePlain",
@@ -8025,7 +8231,7 @@ window.__ModuleLoader__.load({
8025
8231
  if (commit !== void 0) this.commit = commit;
8026
8232
  }
8027
8233
  };
8028
- function record$3(value) {
8234
+ function record$4(value) {
8029
8235
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
8030
8236
  }
8031
8237
  /** The dialog branches on `code`, so a route refusal keeps arriving as this
@@ -8038,20 +8244,20 @@ window.__ModuleLoader__.load({
8038
8244
  return error instanceof PluginRequestError ? new RepositoryActionClientError(error.message, error.code) : error;
8039
8245
  }
8040
8246
  function preview(value) {
8041
- const input = record$3(value);
8247
+ const input = record$4(value);
8042
8248
  if (input === void 0 || typeof input.root !== "string" || typeof input.branch !== "string" || typeof input.head !== "string" || typeof input.fingerprint !== "string" || !Array.isArray(input.files) || typeof input.patch !== "string" || typeof input.truncated !== "boolean" || typeof input.hasStaged !== "boolean" || typeof input.hasUnstaged !== "boolean" || typeof input.hasUntracked !== "boolean" || input.upstream !== void 0 && typeof input.upstream !== "string" || !Array.isArray(input.unpushedCommits) || typeof input.unpushedTruncated !== "boolean") throw new Error("Invalid repository action preview.");
8043
8249
  for (const file of input.files) {
8044
- const item = record$3(file);
8250
+ const item = record$4(file);
8045
8251
  if (item === void 0 || typeof item.path !== "string" || typeof item.staged !== "boolean" || typeof item.unstaged !== "boolean" || typeof item.untracked !== "boolean") throw new Error("Invalid repository action file.");
8046
8252
  }
8047
8253
  for (const commit of input.unpushedCommits) {
8048
- const item = record$3(commit);
8254
+ const item = record$4(commit);
8049
8255
  if (item === void 0 || typeof item.hash !== "string" || typeof item.subject !== "string") throw new Error("Invalid repository action commit.");
8050
8256
  }
8051
8257
  return input;
8052
8258
  }
8053
8259
  function result(value) {
8054
- const input = record$3(value);
8260
+ const input = record$4(value);
8055
8261
  if (input === void 0 || typeof input.commit !== "string" || typeof input.pushed !== "boolean" || input.pullRequestUrl !== void 0 && typeof input.pullRequestUrl !== "string" || input.conflicts !== void 0 && (!Array.isArray(input.conflicts) || input.conflicts.some((item) => typeof item !== "string"))) throw new Error("Invalid repository action result.");
8056
8262
  return input;
8057
8263
  }
@@ -8073,7 +8279,7 @@ window.__ModuleLoader__.load({
8073
8279
  }
8074
8280
  async function generateCommitMessage(sessionId, fingerprint, signal, root) {
8075
8281
  try {
8076
- const value = record$3(await pluginWrite(`${CLAUDE_REPOSITORY_ACTION_PATH}/message`, "remote", signal, {
8282
+ const value = record$4(await pluginWrite(`${CLAUDE_REPOSITORY_ACTION_PATH}/message`, "remote", signal, {
8077
8283
  query: sessionQuery(sessionId, root),
8078
8284
  json: { fingerprint }
8079
8285
  }));
@@ -8087,7 +8293,7 @@ window.__ModuleLoader__.load({
8087
8293
  * `baseBranch` empty means origin's default branch. */
8088
8294
  async function generatePullRequestText(sessionId, fingerprint, baseBranch, signal, root) {
8089
8295
  try {
8090
- const value = record$3(await pluginWrite(`${CLAUDE_REPOSITORY_ACTION_PATH}/pull-request`, "remote", signal, {
8296
+ const value = record$4(await pluginWrite(`${CLAUDE_REPOSITORY_ACTION_PATH}/pull-request`, "remote", signal, {
8091
8297
  query: sessionQuery(sessionId, root),
8092
8298
  json: {
8093
8299
  fingerprint,
@@ -8156,16 +8362,16 @@ window.__ModuleLoader__.load({
8156
8362
  /** The draft only has to describe the work; the host truncates it again before
8157
8363
  * summarizing, and the setup route caps the whole body at 16 KiB. */
8158
8364
  const MAX_INTENT_CHARS = 2e3;
8159
- function record$2(value) {
8365
+ function record$3(value) {
8160
8366
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
8161
8367
  }
8162
8368
  function setupResult(value) {
8163
- const item = record$2(value);
8369
+ const item = record$3(value);
8164
8370
  if (item === void 0 || item.mode !== "checkout" && item.mode !== "worktree" || typeof item.root !== "string" || typeof item.path !== "string" || typeof item.branch !== "string" || item.leaseId !== void 0 && typeof item.leaseId !== "string") return void 0;
8165
8371
  return item;
8166
8372
  }
8167
8373
  function parseRepositorySetupEvent(line, onProgress) {
8168
- const event = record$2(JSON.parse(line));
8374
+ const event = record$3(JSON.parse(line));
8169
8375
  if (event?.type === "progress" && typeof event.stage === "string" && HOST_STAGES.has(event.stage)) {
8170
8376
  onProgress(event.stage);
8171
8377
  return;
@@ -8867,8 +9073,8 @@ window.__ModuleLoader__.load({
8867
9073
  children: diffModalCss
8868
9074
  }),
8869
9075
  /* @__PURE__ */ jsx(Modal, {
8870
- className: "dshClaudeRepositoryActionModal",
8871
- contentClassName: "dshClaudeRepositoryActionModalContent",
9076
+ className: "dshClaudeRepositoryActionModal dshClaudeUtilityDialog",
9077
+ contentClassName: "dshClaudeRepositoryActionModalContent dshClaudeUtilityContent",
8872
9078
  open: dialog !== void 0,
8873
9079
  onClose: closeDialog,
8874
9080
  title: t("conflictTitle"),
@@ -8906,6 +9112,7 @@ window.__ModuleLoader__.load({
8906
9112
  style: diffModalBody,
8907
9113
  children: [
8908
9114
  /* @__PURE__ */ jsxs("div", {
9115
+ className: "dshClaudeUtilitySummary",
8909
9116
  style: diffModalMeta,
8910
9117
  children: [/* @__PURE__ */ jsxs("strong", {
8911
9118
  style: diffModalMetaText,
@@ -8933,6 +9140,7 @@ window.__ModuleLoader__.load({
8933
9140
  children: t("conflictResolve")
8934
9141
  }),
8935
9142
  repository.remote === void 0 ? null : /* @__PURE__ */ jsxs("label", {
9143
+ className: "dshClaudeUtilityOption",
8936
9144
  style: diffModalCheckbox,
8937
9145
  children: [/* @__PURE__ */ jsx("input", {
8938
9146
  type: "checkbox",
@@ -9059,8 +9267,8 @@ window.__ModuleLoader__.load({
9059
9267
  children: diffModalCss
9060
9268
  }),
9061
9269
  /* @__PURE__ */ jsx(Modal, {
9062
- className: "dshClaudeRepositoryActionModal",
9063
- contentClassName: "dshClaudeRepositoryActionModalContent",
9270
+ className: "dshClaudeRepositoryActionModal dshClaudeUtilityDialog",
9271
+ contentClassName: "dshClaudeRepositoryActionModalContent dshClaudeUtilityContent",
9064
9272
  open: dialog !== void 0,
9065
9273
  onClose: closeDialog,
9066
9274
  title: t("repositoryUpdateBranch"),
@@ -9092,6 +9300,7 @@ window.__ModuleLoader__.load({
9092
9300
  style: diffModalBody,
9093
9301
  children: [
9094
9302
  /* @__PURE__ */ jsxs("div", {
9303
+ className: "dshClaudeUtilitySummary",
9095
9304
  style: diffModalMeta,
9096
9305
  children: [/* @__PURE__ */ jsxs("strong", {
9097
9306
  style: diffModalMetaText,
@@ -9110,6 +9319,7 @@ window.__ModuleLoader__.load({
9110
9319
  })]
9111
9320
  }),
9112
9321
  ["rebase", "merge"].map((option) => /* @__PURE__ */ jsxs("label", {
9322
+ className: "dshClaudeUtilityOption",
9113
9323
  style: diffModalCheckbox,
9114
9324
  children: [/* @__PURE__ */ jsx("input", {
9115
9325
  type: "radio",
@@ -9192,8 +9402,8 @@ window.__ModuleLoader__.load({
9192
9402
  children: diffModalCss
9193
9403
  }),
9194
9404
  /* @__PURE__ */ jsx(Modal, {
9195
- className: "dshClaudeRepositoryActionModal",
9196
- contentClassName: "dshClaudeRepositoryActionModalContent",
9405
+ className: "dshClaudeRepositoryActionModal dshClaudeUtilityDialog",
9406
+ contentClassName: "dshClaudeRepositoryActionModalContent dshClaudeUtilityContent",
9197
9407
  open: dialog !== void 0,
9198
9408
  onClose: closeDialog,
9199
9409
  title: t("cleanupTitle"),
@@ -9224,6 +9434,7 @@ window.__ModuleLoader__.load({
9224
9434
  children: dialog === void 0 ? null : /* @__PURE__ */ jsxs("div", {
9225
9435
  style: diffModalBody,
9226
9436
  children: [/* @__PURE__ */ jsxs("div", {
9437
+ className: "dshClaudeUtilitySummary",
9227
9438
  style: diffModalMeta,
9228
9439
  children: [/* @__PURE__ */ jsxs("strong", {
9229
9440
  style: diffModalMetaText,
@@ -9340,8 +9551,8 @@ window.__ModuleLoader__.load({
9340
9551
  children: diffModalCss
9341
9552
  }),
9342
9553
  /* @__PURE__ */ jsx(Modal, {
9343
- className: "dshClaudeRepositoryActionModal",
9344
- contentClassName: "dshClaudeRepositoryActionModalContent",
9554
+ className: "dshClaudeRepositoryActionModal dshClaudeUtilityDialog",
9555
+ contentClassName: "dshClaudeRepositoryActionModalContent dshClaudeUtilityContent",
9345
9556
  open: dialog !== void 0,
9346
9557
  onClose: closeDialog,
9347
9558
  title: t("diffMergePr"),
@@ -9373,6 +9584,7 @@ window.__ModuleLoader__.load({
9373
9584
  style: diffModalBody,
9374
9585
  children: [
9375
9586
  /* @__PURE__ */ jsxs("div", {
9587
+ className: "dshClaudeUtilitySummary",
9376
9588
  style: diffModalMeta,
9377
9589
  children: [/* @__PURE__ */ jsxs("strong", {
9378
9590
  style: diffModalMetaText,
@@ -9392,6 +9604,7 @@ window.__ModuleLoader__.load({
9392
9604
  children: pullRequest.title
9393
9605
  }),
9394
9606
  /* @__PURE__ */ jsxs("label", {
9607
+ className: "dshClaudeUtilityOption",
9395
9608
  style: diffModalCheckbox,
9396
9609
  children: [/* @__PURE__ */ jsx("input", {
9397
9610
  type: "checkbox",
@@ -9732,7 +9945,7 @@ window.__ModuleLoader__.load({
9732
9945
  }
9733
9946
  //#endregion
9734
9947
  //#region src/client/review-comment-api.ts
9735
- function record$1(value) {
9948
+ function record$2(value) {
9736
9949
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
9737
9950
  }
9738
9951
  async function post(path, sessionId, body) {
@@ -9742,7 +9955,7 @@ window.__ModuleLoader__.load({
9742
9955
  });
9743
9956
  }
9744
9957
  async function addReviewComment(sessionId, comment) {
9745
- const created = record$1(record$1(await post("", sessionId, comment))?.comment);
9958
+ const created = record$2(record$2(await post("", sessionId, comment))?.comment);
9746
9959
  if (created === void 0 || typeof created.id !== "string") throw new Error("Invalid review comment response.");
9747
9960
  return created;
9748
9961
  }
@@ -14975,6 +15188,7 @@ window.__ModuleLoader__.load({
14975
15188
  style: diffFile,
14976
15189
  children: [/* @__PURE__ */ jsxs("button", {
14977
15190
  type: "button",
15191
+ className: diffFileHeaderClass,
14978
15192
  style: diffFileHeader,
14979
15193
  "aria-expanded": open,
14980
15194
  onClick: () => onOpenChange(!open),
@@ -15757,13 +15971,12 @@ window.__ModuleLoader__.load({
15757
15971
  ]
15758
15972
  }),
15759
15973
  /* @__PURE__ */ jsxs(Modal, {
15760
- className: "dshClaudeRepositoryActionModal",
15761
- contentClassName: "dshClaudeRepositoryActionModalContent",
15974
+ className: "dshClaudeRepositoryActionModal dshClaudeCommitDialog",
15975
+ contentClassName: "dshClaudeRepositoryActionModalContent dshClaudeCommitContent",
15762
15976
  open: dialog !== void 0,
15763
15977
  onClose: closeDialog,
15764
15978
  title: dialog === void 0 ? t("diffCommit") : actionLabel(dialog.action, t),
15765
15979
  closeLabel: t("diffCancel"),
15766
- description: t("diffConfirmDescription"),
15767
15980
  footer: /* @__PURE__ */ jsxs("div", {
15768
15981
  style: diffModalFooter,
15769
15982
  children: [/* @__PURE__ */ jsx("button", {
@@ -15783,120 +15996,161 @@ window.__ModuleLoader__.load({
15783
15996
  },
15784
15997
  disabled: dialog?.submitting === true || dialog?.preview === void 0 || dialog.action !== "push" && message.trim() === "",
15785
15998
  onClick: () => void confirm(),
15786
- children: dialog?.submitting === true ? t("diffSubmitting") : t("diffConfirm")
15999
+ children: dialog?.submitting === true ? t("diffSubmitting") : dialog === void 0 ? t("diffCommit") : actionLabel(dialog.action, t)
15787
16000
  })]
15788
16001
  }),
15789
16002
  children: [
15790
16003
  dialog?.loading === true ? /* @__PURE__ */ jsx("p", {
15791
- style: diffModalStatus,
15792
- children: t("diffGeneratingMessage")
16004
+ className: "dshClaudeCommitProgress",
16005
+ role: "status",
16006
+ children: t(dialog.preview === void 0 ? "diffLoadingPreview" : "diffGeneratingMessage")
15793
16007
  }) : null,
15794
16008
  dialog?.preview !== void 0 ? /* @__PURE__ */ jsxs("div", {
15795
16009
  style: diffModalBody,
15796
- children: [
15797
- /* @__PURE__ */ jsxs("div", {
15798
- style: diffModalMeta,
15799
- children: [/* @__PURE__ */ jsx("strong", {
15800
- style: diffModalMetaText,
15801
- title: dialog.preview.branch,
15802
- children: dialog.action === "push" ? `${dialog.preview.branch} → ${dialog.preview.upstream ?? `origin/${dialog.preview.branch}`}` : dialog.preview.branch
16010
+ children: [/* @__PURE__ */ jsxs("div", {
16011
+ className: "dshClaudeCommitContext",
16012
+ children: [
16013
+ /* @__PURE__ */ jsx("strong", {
16014
+ title: dialog.preview.root,
16015
+ children: repositoryLabel({
16016
+ root: dialog.preview.root,
16017
+ cwd: dialog.preview.root
16018
+ })
16019
+ }),
16020
+ /* @__PURE__ */ jsx("span", {
16021
+ className: "dshClaudeCommitBranch",
16022
+ children: dialog.preview.branch
16023
+ }),
16024
+ dialog.action === "push" || dialog.action === "commit-push" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
16025
+ "aria-hidden": "true",
16026
+ children: "→"
15803
16027
  }), /* @__PURE__ */ jsx("span", {
15804
- style: diffModalFileState,
15805
- children: dialog.action === "push" ? t("diffPushAhead", { count: dialog.preview.unpushedTruncated ? `${dialog.preview.unpushedCommits.length}+` : dialog.preview.unpushedCommits.length }) : t("diffFiles", { count: dialog.preview.files.length })
15806
- })]
15807
- }),
15808
- dialog.action === "push" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
15809
- style: diffModalFiles,
16028
+ className: "dshClaudeCommitBranch",
16029
+ children: dialog.preview.upstream ?? `origin/${dialog.preview.branch}`
16030
+ })] }) : null
16031
+ ]
16032
+ }), dialog.action === "push" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("section", {
16033
+ className: "dshClaudeCommitSection",
16034
+ children: [/* @__PURE__ */ jsx("h3", { children: t("diffPushAhead", { count: dialog.preview.unpushedTruncated ? `${dialog.preview.unpushedCommits.length}+` : dialog.preview.unpushedCommits.length }) }), /* @__PURE__ */ jsx("div", {
16035
+ className: "dshClaudeCommitFiles",
15810
16036
  children: dialog.preview.unpushedCommits.map((commit) => /* @__PURE__ */ jsxs("div", {
15811
- style: diffModalFile,
15812
- children: [/* @__PURE__ */ jsx("span", {
15813
- style: diffModalFilePath,
16037
+ className: "dshClaudeCommitFile",
16038
+ children: [/* @__PURE__ */ jsx("code", {
16039
+ className: "dshClaudeCommitHash",
16040
+ children: commit.hash.slice(0, 8)
16041
+ }), /* @__PURE__ */ jsx("span", {
16042
+ className: "dshClaudeCommitPath",
15814
16043
  title: commit.subject,
15815
16044
  children: commit.subject
15816
- }), /* @__PURE__ */ jsx("span", {
15817
- style: diffModalFileState,
15818
- children: commit.hash.slice(0, 8)
15819
16045
  })]
15820
16046
  }, commit.hash))
15821
- }), /* @__PURE__ */ jsx("p", {
15822
- style: diffModalStatus,
15823
- children: t("diffPushDescription")
15824
- })] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
15825
- /* @__PURE__ */ jsx("div", {
15826
- style: diffModalFiles,
15827
- children: dialog.preview.files.map((file) => /* @__PURE__ */ jsxs("div", {
15828
- style: diffModalFile,
15829
- children: [/* @__PURE__ */ jsx("span", {
15830
- style: diffModalFilePath,
15831
- title: file.path,
15832
- children: file.path
15833
- }), /* @__PURE__ */ jsx("span", {
15834
- style: diffModalFileState,
15835
- children: file.untracked ? t("diffUntracked") : file.staged && file.unstaged ? t("diffStagedUnstaged") : file.staged ? t("diffStaged") : t("diffUnstaged")
16047
+ })]
16048
+ }), /* @__PURE__ */ jsx("p", {
16049
+ style: diffModalStatus,
16050
+ children: t("diffPushDescription")
16051
+ })] }) : /* @__PURE__ */ jsxs("div", {
16052
+ className: "dshClaudeCommitGrid",
16053
+ children: [/* @__PURE__ */ jsxs("section", {
16054
+ className: "dshClaudeCommitSection dshClaudeCommitChanges",
16055
+ children: [
16056
+ /* @__PURE__ */ jsx("h3", { children: t("diffFilesShort", { count: dialog.preview.files.length }) }),
16057
+ /* @__PURE__ */ jsx("div", {
16058
+ className: "dshClaudeCommitFiles",
16059
+ children: dialog.preview.files.map((file) => /* @__PURE__ */ jsxs("div", {
16060
+ className: "dshClaudeCommitFile",
16061
+ children: [/* @__PURE__ */ jsx("span", {
16062
+ className: "dshClaudeCommitPath",
16063
+ title: file.path,
16064
+ children: file.path
16065
+ }), /* @__PURE__ */ jsx("span", {
16066
+ className: "dshClaudeCommitState",
16067
+ "data-staged": file.staged && !file.unstaged && !file.untracked,
16068
+ children: file.untracked ? t("diffUntracked") : file.staged && file.unstaged ? t("diffStagedUnstaged") : file.staged ? t("diffStaged") : t("diffUnstaged")
16069
+ })]
16070
+ }, file.path))
16071
+ }),
16072
+ /* @__PURE__ */ jsxs("label", {
16073
+ style: diffModalCheckbox,
16074
+ children: [/* @__PURE__ */ jsx("input", {
16075
+ type: "checkbox",
16076
+ checked: includeUnstaged,
16077
+ disabled: !dialog.preview.hasUnstaged && !dialog.preview.hasUntracked,
16078
+ onChange: (event) => setIncludeUnstaged(event.currentTarget.checked)
16079
+ }), t("diffIncludeUnstaged")]
16080
+ })
16081
+ ]
16082
+ }), /* @__PURE__ */ jsxs("div", {
16083
+ className: "dshClaudeCommitEditor",
16084
+ children: [
16085
+ dialog.action === "create-pr" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
16086
+ /* @__PURE__ */ jsxs("label", {
16087
+ style: diffModalField,
16088
+ children: [t("diffPrTitle"), /* @__PURE__ */ jsx("input", {
16089
+ style: {
16090
+ ...diffModalTextInput,
16091
+ fontWeight: 400
16092
+ },
16093
+ value: prTitle,
16094
+ maxLength: 256,
16095
+ onChange: (event) => setPrTitle(event.currentTarget.value)
16096
+ })]
16097
+ }),
16098
+ /* @__PURE__ */ jsxs("label", {
16099
+ style: diffModalField,
16100
+ children: [t("diffPrBase"), /* @__PURE__ */ jsx("input", {
16101
+ style: {
16102
+ ...diffModalTextInput,
16103
+ fontWeight: 400
16104
+ },
16105
+ value: baseBranch,
16106
+ maxLength: 512,
16107
+ placeholder: t("diffPrBaseDefault"),
16108
+ onChange: (event) => setBaseBranch(event.currentTarget.value)
16109
+ })]
16110
+ }),
16111
+ /* @__PURE__ */ jsxs("label", {
16112
+ style: diffModalField,
16113
+ children: [t("diffPrDescription"), /* @__PURE__ */ jsx("textarea", {
16114
+ style: {
16115
+ ...diffModalTextarea,
16116
+ fontWeight: 400,
16117
+ minHeight: 180
16118
+ },
16119
+ value: prBody,
16120
+ maxLength: 8192,
16121
+ onChange: (event) => setPrBody(event.currentTarget.value)
16122
+ })]
16123
+ }),
16124
+ /* @__PURE__ */ jsxs("label", {
16125
+ style: diffModalCheckbox,
16126
+ children: [/* @__PURE__ */ jsx("input", {
16127
+ type: "checkbox",
16128
+ checked: draft,
16129
+ onChange: (event) => setDraft(event.currentTarget.checked)
16130
+ }), t("diffPrDraft")]
16131
+ })
16132
+ ] }) : null,
16133
+ /* @__PURE__ */ jsxs("label", {
16134
+ style: diffModalField,
16135
+ children: [t("diffCommitMessage"), /* @__PURE__ */ jsx("textarea", {
16136
+ style: {
16137
+ ...diffModalTextarea,
16138
+ fontWeight: 400,
16139
+ minHeight: dialog.action === "create-pr" ? 100 : 220
16140
+ },
16141
+ value: message,
16142
+ maxLength: 2048,
16143
+ placeholder: t("diffCommitMessagePlaceholder"),
16144
+ onChange: (event) => setMessage(event.currentTarget.value)
15836
16145
  })]
15837
- }, file.path))
15838
- }),
15839
- /* @__PURE__ */ jsxs("label", {
15840
- style: diffModalCheckbox,
15841
- children: [/* @__PURE__ */ jsx("input", {
15842
- type: "checkbox",
15843
- checked: includeUnstaged,
15844
- disabled: !dialog.preview.hasUnstaged && !dialog.preview.hasUntracked,
15845
- onChange: (event) => setIncludeUnstaged(event.currentTarget.checked)
15846
- }), t("diffIncludeUnstaged")]
15847
- }),
15848
- /* @__PURE__ */ jsxs("label", {
15849
- style: diffModalField,
15850
- children: [t("diffCommitMessage"), /* @__PURE__ */ jsx("textarea", {
15851
- style: diffModalTextarea,
15852
- value: message,
15853
- maxLength: 2048,
15854
- onChange: (event) => setMessage(event.currentTarget.value)
15855
- })]
15856
- })
15857
- ] }),
15858
- dialog.action === "create-pr" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
15859
- /* @__PURE__ */ jsxs("label", {
15860
- style: diffModalField,
15861
- children: [t("diffPrTitle"), /* @__PURE__ */ jsx("input", {
15862
- style: diffModalTextInput,
15863
- value: prTitle,
15864
- maxLength: 256,
15865
- onChange: (event) => setPrTitle(event.currentTarget.value)
15866
- })]
15867
- }),
15868
- /* @__PURE__ */ jsxs("label", {
15869
- style: diffModalField,
15870
- children: [t("diffPrBase"), /* @__PURE__ */ jsx("input", {
15871
- style: diffModalTextInput,
15872
- value: baseBranch,
15873
- maxLength: 512,
15874
- placeholder: t("diffPrBaseDefault"),
15875
- onChange: (event) => setBaseBranch(event.currentTarget.value)
15876
- })]
15877
- }),
15878
- /* @__PURE__ */ jsxs("label", {
15879
- style: diffModalField,
15880
- children: [t("diffPrDescription"), /* @__PURE__ */ jsx("textarea", {
15881
- style: {
15882
- ...diffModalTextarea,
15883
- minHeight: 240
15884
- },
15885
- value: prBody,
15886
- maxLength: 8192,
15887
- onChange: (event) => setPrBody(event.currentTarget.value)
15888
- })]
15889
- }),
15890
- /* @__PURE__ */ jsxs("label", {
15891
- style: diffModalCheckbox,
15892
- children: [/* @__PURE__ */ jsx("input", {
15893
- type: "checkbox",
15894
- checked: draft,
15895
- onChange: (event) => setDraft(event.currentTarget.checked)
15896
- }), t("diffPrDraft")]
15897
- })
15898
- ] }) : null
15899
- ]
16146
+ }),
16147
+ /* @__PURE__ */ jsx("p", {
16148
+ className: "dshClaudeCommitHint",
16149
+ children: t("diffCommitMessageHint")
16150
+ })
16151
+ ]
16152
+ })]
16153
+ })]
15900
16154
  }) : null,
15901
16155
  dialog?.error !== void 0 ? /* @__PURE__ */ jsxs("p", {
15902
16156
  role: "alert",
@@ -16096,11 +16350,11 @@ window.__ModuleLoader__.load({
16096
16350
  }
16097
16351
  //#endregion
16098
16352
  //#region src/client/ask-api.ts
16099
- function record(value) {
16353
+ function record$1(value) {
16100
16354
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
16101
16355
  }
16102
16356
  function parseAskEvent(line) {
16103
- const event = record(JSON.parse(line));
16357
+ const event = record$1(JSON.parse(line));
16104
16358
  if (event?.type === "delta" && typeof event.text === "string") return {
16105
16359
  type: "delta",
16106
16360
  text: event.text
@@ -16571,6 +16825,10 @@ window.__ModuleLoader__.load({
16571
16825
  "data-dsh-claude-ask-styles": true,
16572
16826
  children: [panelIconButtonCss, askHighlightCss]
16573
16827
  }),
16828
+ /* @__PURE__ */ jsx("strong", {
16829
+ style: promptSaveHeading,
16830
+ children: t("askTooltip")
16831
+ }),
16574
16832
  /* @__PURE__ */ jsx("p", {
16575
16833
  style: askQuote,
16576
16834
  children: selection.text
@@ -17037,8 +17295,8 @@ window.__ModuleLoader__.load({
17037
17295
  children: diffModalCss
17038
17296
  }),
17039
17297
  /* @__PURE__ */ jsx(Modal, {
17040
- className: "dshClaudeRepositoryActionModal",
17041
- contentClassName: "dshClaudeRepositoryActionModalContent",
17298
+ className: "dshClaudeRepositoryActionModal dshClaudeUtilityDialog",
17299
+ contentClassName: "dshClaudeRepositoryActionModalContent dshClaudeUtilityContent",
17042
17300
  open: target !== void 0,
17043
17301
  onClose: close,
17044
17302
  title: t("rewindTitle"),
@@ -17074,6 +17332,7 @@ window.__ModuleLoader__.load({
17074
17332
  children: target.text.slice(0, 2e3)
17075
17333
  }),
17076
17334
  /* @__PURE__ */ jsxs("label", {
17335
+ className: "dshClaudeUtilityOption",
17077
17336
  style: diffModalCheckbox,
17078
17337
  children: [/* @__PURE__ */ jsx("input", {
17079
17338
  type: "checkbox",
@@ -18586,7 +18845,10 @@ window.__ModuleLoader__.load({
18586
18845
  role: "dialog",
18587
18846
  "aria-label": label,
18588
18847
  children: panel.kind === "saved" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
18589
- /* @__PURE__ */ jsx("span", { children: t("promptSaved", { name: panel.prompt.name }) }),
18848
+ /* @__PURE__ */ jsx("span", {
18849
+ style: promptSaveHeading,
18850
+ children: t("promptSaved", { name: panel.prompt.name })
18851
+ }),
18590
18852
  /* @__PURE__ */ jsx("span", {
18591
18853
  style: promptSaveLocation,
18592
18854
  children: panel.prompt.location
@@ -18609,8 +18871,13 @@ window.__ModuleLoader__.load({
18609
18871
  children: [
18610
18872
  /* @__PURE__ */ jsx("span", {
18611
18873
  style: promptSaveHeading,
18612
- children: panel.suggesting ? t("promptSaveNaming") : label
18874
+ children: label
18613
18875
  }),
18876
+ panel.suggesting ? /* @__PURE__ */ jsx("span", {
18877
+ role: "status",
18878
+ style: repositoryChecksHint,
18879
+ children: t("promptSaveNaming")
18880
+ }) : null,
18614
18881
  /* @__PURE__ */ jsx("input", {
18615
18882
  className: promptSaveFieldClass,
18616
18883
  "aria-label": t("promptSaveName"),
@@ -18656,6 +18923,244 @@ window.__ModuleLoader__.load({
18656
18923
  });
18657
18924
  }
18658
18925
  //#endregion
18926
+ //#region src/client/ClaudePermissionSelect.tsx
18927
+ const NAME_KEY = {
18928
+ plan: "permissionModePlan",
18929
+ default: "permissionModeDefault",
18930
+ acceptEdits: "permissionModeAcceptEdits",
18931
+ dontAsk: "permissionModeDontAsk",
18932
+ auto: "permissionModeAuto",
18933
+ bypassPermissions: "permissionModeBypass"
18934
+ };
18935
+ const HINT_KEY = {
18936
+ plan: "permissionModePlanHint",
18937
+ default: "permissionModeDefaultHint",
18938
+ acceptEdits: "permissionModeAcceptEditsHint",
18939
+ dontAsk: "permissionModeDontAskHint",
18940
+ auto: "permissionModeAutoHint",
18941
+ bypassPermissions: "permissionModeBypassHint"
18942
+ };
18943
+ /** One 16px outline glyph per mode, drawn to the Host's own icon grammar
18944
+ * (1.5px round strokes on currentColor) so the row reads as one set with
18945
+ * the attach and plan controls beside it. */
18946
+ function ClaudePermissionModeGlyph({ mode }) {
18947
+ return /* @__PURE__ */ jsx("svg", {
18948
+ width: "16",
18949
+ height: "16",
18950
+ viewBox: "0 0 16 16",
18951
+ fill: "none",
18952
+ "aria-hidden": "true",
18953
+ children: {
18954
+ plan: [
18955
+ "M6 2.75h4",
18956
+ "M4.5 3.75h7a1 1 0 0 1 1 1v8.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1v-8.5a1 1 0 0 1 1-1z",
18957
+ "M6 8h4",
18958
+ "M6 10.5h2.5"
18959
+ ],
18960
+ default: [
18961
+ "M8 2.25l5 1.9v3.6c0 3.05-2.15 5.15-5 6.25-2.85-1.1-5-3.2-5-6.25v-3.6l5-1.9z",
18962
+ "M8 6v3",
18963
+ "M8 11h.01"
18964
+ ],
18965
+ acceptEdits: [
18966
+ "M10.4 3.1l2.5 2.5L6.5 12H4v-2.5l6.4-6.4z",
18967
+ "M9 4.5l2.5 2.5",
18968
+ "M9.5 13.25l1.5 1.5 3-3"
18969
+ ],
18970
+ dontAsk: [
18971
+ "M5.25 9.5V7.25a2.75 2.75 0 0 1 5.5 0V9.5l1 1.75h-7.5l1-1.75z",
18972
+ "M6.75 12.75a1.25 1.25 0 0 0 2.5 0",
18973
+ "M3 3l10 10"
18974
+ ],
18975
+ auto: ["M8 2.5l1.4 3.6 3.6 1.4-3.6 1.4L8 12.5 6.6 8.9 3 7.5l3.6-1.4L8 2.5z", "M12.5 11.5l.5 1.25 1.25.5-1.25.5-.5 1.25-.5-1.25-1.25-.5 1.25-.5.5-1.25z"],
18976
+ bypassPermissions: [
18977
+ "M5 8V6.25a3 3 0 0 1 5.85-.95",
18978
+ "M4.25 8h7.5v5.5h-7.5z",
18979
+ "M8 10.25v1.5"
18980
+ ]
18981
+ }[mode].map((d) => /* @__PURE__ */ jsx("path", {
18982
+ d,
18983
+ stroke: "currentColor",
18984
+ strokeWidth: "1.5",
18985
+ strokeLinecap: "round",
18986
+ strokeLinejoin: "round"
18987
+ }, d))
18988
+ });
18989
+ }
18990
+ /**
18991
+ * Claude Code's own permission modes as the session's access control, in the
18992
+ * composer's tool row where the Host's three-mode selector sits for other
18993
+ * agent presets. That selector is hidden for Claude sessions (host-chrome.ts)
18994
+ * rather than replaced: it is not a slot. This one drives the same Host
18995
+ * knobs through the plugin's route, so approvals and the sandbox follow.
18996
+ *
18997
+ * The pick is shown the moment it is made and held until the projection
18998
+ * confirms it; a refused pick drops back to what the projection says.
18999
+ */
19000
+ function ClaudePermissionSelect({ t, setMode, notify, useClaudeProjection, useSession }) {
19001
+ const owned = useClaudeProjection((projection) => projection.owned);
19002
+ const selector = useClaudeProjection((projection) => projection.permissionSelector);
19003
+ const view = useClaudeProjection((projection) => projection.permissionMode);
19004
+ const running = useSession === void 0 ? false : useSession((session) => session.running);
19005
+ const [pick, setPick] = useState(null);
19006
+ const [open, setOpen] = useState(false);
19007
+ const [confirming, setConfirming] = useState(null);
19008
+ const [acknowledged, setAcknowledged] = useState(false);
19009
+ const [busy, setBusy] = useState(false);
19010
+ const reported = view?.mode;
19011
+ useEffect(() => {
19012
+ if (pick !== null && reported === pick) setPick(null);
19013
+ }, [pick, reported]);
19014
+ if (!owned || selector !== "plugin") return null;
19015
+ const current = pick ?? reported;
19016
+ const locked = running || view?.locked === true;
19017
+ const label = current === void 0 ? t("permissionMode") : t(NAME_KEY[current]);
19018
+ const hint = locked ? t("permissionModeLocked") : current === void 0 ? t("permissionMode") : t(HINT_KEY[current]);
19019
+ const autoUnsupported = view?.autoSupported === false;
19020
+ const hintOf = (mode) => mode === "auto" && autoUnsupported ? t("permissionModeAutoUnsupported") : t(HINT_KEY[mode]);
19021
+ const submit = (mode) => {
19022
+ setPick(mode);
19023
+ setBusy(true);
19024
+ setMode(mode).then((outcome) => {
19025
+ if (!outcome.hostSynced) notify?.("info", t("permissionModeHostKept"));
19026
+ }, (error) => {
19027
+ setPick(null);
19028
+ notify?.("error", t("permissionModeFailed", { message: error instanceof Error ? error.message : String(error) }));
19029
+ }).finally(() => {
19030
+ setBusy(false);
19031
+ });
19032
+ };
19033
+ const choose = (id) => {
19034
+ setOpen(false);
19035
+ if (id === current || !CLAUDE_PERMISSION_MODES.includes(id)) return;
19036
+ const mode = id;
19037
+ if (mode === "bypassPermissions") {
19038
+ setAcknowledged(false);
19039
+ setConfirming(mode);
19040
+ return;
19041
+ }
19042
+ submit(mode);
19043
+ };
19044
+ const closeConfirmation = () => {
19045
+ setAcknowledged(false);
19046
+ setConfirming(null);
19047
+ };
19048
+ return /* @__PURE__ */ jsxs("span", {
19049
+ className: permissionSelectClass,
19050
+ children: [
19051
+ /* @__PURE__ */ jsxs("style", {
19052
+ "data-dsh-claude-permission-select-styles": true,
19053
+ children: [permissionSelectCss, permissionSelectRowCss]
19054
+ }),
19055
+ /* @__PURE__ */ jsx(Menu, {
19056
+ open,
19057
+ items: CLAUDE_PERMISSION_MODES.map((mode) => ({
19058
+ id: mode,
19059
+ label: /* @__PURE__ */ jsxs("span", {
19060
+ className: permissionSelectRowClass,
19061
+ children: [/* @__PURE__ */ jsx("span", {
19062
+ className: permissionSelectRowNameClass,
19063
+ children: t(NAME_KEY[mode])
19064
+ }), /* @__PURE__ */ jsx("span", {
19065
+ className: permissionSelectRowHintClass,
19066
+ children: hintOf(mode)
19067
+ })]
19068
+ }),
19069
+ icon: /* @__PURE__ */ jsx(ClaudePermissionModeGlyph, { mode }),
19070
+ ...mode === "auto" && autoUnsupported ? { disabled: true } : {},
19071
+ ...mode === "bypassPermissions" ? { danger: true } : {}
19072
+ })),
19073
+ selectedId: current,
19074
+ onSelect: choose,
19075
+ onClose: () => {
19076
+ setOpen(false);
19077
+ },
19078
+ side: "top",
19079
+ anchor: /* @__PURE__ */ jsx(Tooltip, {
19080
+ label: hint,
19081
+ side: "top",
19082
+ delayMs: 250,
19083
+ disabled: open,
19084
+ children: /* @__PURE__ */ jsxs("button", {
19085
+ type: "button",
19086
+ className: permissionSelectTriggerClass,
19087
+ "aria-label": t("permissionModeAria", { name: label }),
19088
+ "aria-haspopup": "menu",
19089
+ "aria-expanded": open,
19090
+ disabled: locked || busy,
19091
+ onClick: () => {
19092
+ setOpen(!open);
19093
+ },
19094
+ children: [
19095
+ current === void 0 ? null : /* @__PURE__ */ jsx("span", {
19096
+ className: permissionSelectIconClass,
19097
+ children: /* @__PURE__ */ jsx(ClaudePermissionModeGlyph, { mode: current })
19098
+ }),
19099
+ /* @__PURE__ */ jsx("span", {
19100
+ className: permissionSelectLabelClass,
19101
+ children: label
19102
+ }),
19103
+ /* @__PURE__ */ jsx("svg", {
19104
+ className: permissionSelectChevronClass,
19105
+ width: "12",
19106
+ height: "12",
19107
+ viewBox: "0 0 12 12",
19108
+ fill: "none",
19109
+ "aria-hidden": "true",
19110
+ "data-open": open ? "" : void 0,
19111
+ children: /* @__PURE__ */ jsx("path", {
19112
+ d: "M3 4.5L6 7.5L9 4.5",
19113
+ stroke: "currentColor",
19114
+ strokeWidth: "1.5",
19115
+ strokeLinecap: "round",
19116
+ strokeLinejoin: "round"
19117
+ })
19118
+ })
19119
+ ]
19120
+ })
19121
+ })
19122
+ }),
19123
+ /* @__PURE__ */ jsx(RiskConfirmation, {
19124
+ open: confirming !== null,
19125
+ title: t("permissionBypassTitle"),
19126
+ description: t("permissionBypassDescription"),
19127
+ acknowledgeLabel: t("permissionBypassAcknowledge"),
19128
+ cancelLabel: t("permissionBypassCancel"),
19129
+ closeLabel: t("permissionBypassClose"),
19130
+ confirmLabel: t("permissionBypassConfirm"),
19131
+ acknowledged,
19132
+ disabled: locked,
19133
+ onAcknowledgedChange: setAcknowledged,
19134
+ onCancel: closeConfirmation,
19135
+ onConfirm: () => {
19136
+ if (locked || !acknowledged || confirming === null) return;
19137
+ const mode = confirming;
19138
+ closeConfirmation();
19139
+ submit(mode);
19140
+ }
19141
+ })
19142
+ ]
19143
+ });
19144
+ }
19145
+ //#endregion
19146
+ //#region src/client/permission-mode-api.ts
19147
+ function record(value) {
19148
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
19149
+ }
19150
+ /** Make `mode` the session's Claude permission mode from its next turn. */
19151
+ async function setClaudePermissionMode(sessionId, mode, signal) {
19152
+ const value = record(await pluginWrite(CLAUDE_PERMISSION_MODE_PATH, "fast", signal, { json: {
19153
+ sessionId,
19154
+ mode
19155
+ } }));
19156
+ if (value === void 0 || !isClaudePermissionMode(value.mode) || typeof value.sandbox !== "string" || typeof value.hostSynced !== "boolean") throw new Error("Invalid permission mode result.");
19157
+ return {
19158
+ mode: value.mode,
19159
+ sandbox: value.sandbox,
19160
+ hostSynced: value.hostSynced
19161
+ };
19162
+ }
19163
+ //#endregion
18659
19164
  //#region src/client/ClaudePromptRefineAction.tsx
18660
19165
  /**
18661
19166
  * Rewrite the draft in place, from the composer's own tool row.
@@ -18819,7 +19324,7 @@ window.__ModuleLoader__.load({
18819
19324
  `button[${CLAUDE_SEAT_ATTRIBUTE}]>[class*="seatIcon"]{display:none}`,
18820
19325
  `button[${CLAUDE_SEAT_ATTRIBUTE}]::before{content:"";flex:none;width:16px;height:16px;`,
18821
19326
  `background:${claudeMarkUrl()} center/contain no-repeat}`
18822
- ].join("")}`;
19327
+ ].join("")}${`[class*="_tools"]:has(.${permissionSelectClass}) [class*="_modes"]>*:has(span[class*="_triggerLabel"]){display:none}`}`;
18823
19328
  /** Install the stylesheet and the one DOM flag it depends on.
18824
19329
  * @returns a disposer that removes both again. */
18825
19330
  function restyleHostChrome() {
@@ -18882,6 +19387,12 @@ window.__ModuleLoader__.load({
18882
19387
  globalSettingsNewSession: "修改仅对新建 Claude 会话生效。",
18883
19388
  globalSettingsError: "全局设置保存失败",
18884
19389
  outputStyle: "Output Style",
19390
+ permissionSelector: "权限选择器",
19391
+ permissionSelectorPlugin: "插件(Claude Code 权限模式)",
19392
+ permissionSelectorNative: "DSH 原生(三档访问模式)",
19393
+ permissionSelectorEffect: "插件:composer 里显示本插件的选择器,提供 Claude Code 的全部权限模式,并按下面的\"默认权限模式\"初始化新会话。DSH 原生:保留 DSH 自带的只读 / 工作区写入 / 完全权限三档下拉,权限只按沙箱映射(只读对应计划,工作区写入对应自动接受编辑,完全权限对应跳过权限),会话里的选择和默认权限模式都不再参与。立即生效;正在运行的回合保持原模式。",
19394
+ defaultPermissionMode: "默认权限模式",
19395
+ defaultPermissionModeEffect: "新建 Claude 会话时采用的 Claude Code 权限模式,DSH 的访问预设会随之切到这个模式对应的沙箱;之后在 composer 里的权限选择器改过的会话按自己的选择运行。用 /permission 之类原生方式改过沙箱的会话,以沙箱对应的模式为准;当前模型不支持自动模式时退回默认模式。修改只对之后新建的会话生效。",
18885
19396
  renderer: "AI 输出渲染器",
18886
19397
  rendererPlugin: "插件渲染器",
18887
19398
  rendererNative: "DSH 原生渲染器",
@@ -19062,6 +19573,30 @@ window.__ModuleLoader__.load({
19062
19573
  promptSaved: "已存为「{name}」",
19063
19574
  promptSaveExists: "已有同名提示词,换个名字。",
19064
19575
  promptSaveFailed: "保存失败:{message}",
19576
+ permissionMode: "权限模式",
19577
+ permissionModeAria: "权限模式:{name}",
19578
+ permissionModePlan: "计划",
19579
+ permissionModePlanHint: "只读探索并写出计划,经你批准后才执行",
19580
+ permissionModeDefault: "默认",
19581
+ permissionModeDefaultHint: "每次文件改动和命令都先询问",
19582
+ permissionModeAcceptEdits: "自动接受编辑",
19583
+ permissionModeAcceptEditsHint: "文件改动自动放行,命令仍会询问",
19584
+ permissionModeDontAsk: "不询问",
19585
+ permissionModeDontAskHint: "没有预先放行的操作直接拒绝,不弹出审批",
19586
+ permissionModeAuto: "自动",
19587
+ permissionModeAutoHint: "由 Claude Code 的分类器代为批准,拿不准的才问你",
19588
+ permissionModeAutoUnsupported: "当前模型不支持自动模式",
19589
+ permissionModeBypass: "跳过权限",
19590
+ permissionModeBypassHint: "跳过所有权限检查",
19591
+ permissionModeLocked: "回合进行中无法切换权限模式",
19592
+ permissionModeFailed: "切换权限模式失败:{message}",
19593
+ permissionModeHostKept: "DSH 未同步访问模式,Claude 仍按所选模式运行",
19594
+ permissionBypassTitle: "跳过所有权限检查?",
19595
+ permissionBypassDescription: "Claude Code 将不再请求审批,直接执行文件改动和命令。",
19596
+ permissionBypassAcknowledge: "我了解风险",
19597
+ permissionBypassCancel: "取消",
19598
+ permissionBypassClose: "关闭",
19599
+ permissionBypassConfirm: "启用",
19065
19600
  presetHeaderHint: "当前会话运行的 Agent 预设",
19066
19601
  diffRepository: "仓库",
19067
19602
  repositoryLinked: "关联仓库:本会话改动过",
@@ -19090,6 +19625,9 @@ window.__ModuleLoader__.load({
19090
19625
  diffPushAhead: "{count} 个未推送的 commit",
19091
19626
  diffPushCompleted: "已推送 commit {commit}",
19092
19627
  diffGeneratingMessage: "正在生成建议的 commit message,只会填进你没写的字段。",
19628
+ diffLoadingPreview: "正在读取仓库变更…",
19629
+ diffCommitMessagePlaceholder: "简要描述这次修改…",
19630
+ diffCommitMessageHint: "首行写修改摘要,空一行后可补充详细说明。",
19093
19631
  diffActionFailed: "仓库操作失败。",
19094
19632
  diffIncludeUnstaged: "包含 unstaged 和 untracked 改动",
19095
19633
  diffCommitMessage: "Commit message",
@@ -19323,6 +19861,12 @@ window.__ModuleLoader__.load({
19323
19861
  globalSettingsNewSession: "Changes apply only to new Claude sessions.",
19324
19862
  globalSettingsError: "Global settings save failed",
19325
19863
  outputStyle: "Output Style",
19864
+ permissionSelector: "Permission selector",
19865
+ permissionSelectorPlugin: "Plugin (Claude Code permission modes)",
19866
+ permissionSelectorNative: "DSH native (three access modes)",
19867
+ permissionSelectorEffect: "Plugin: the composer shows this plugin's selector with every Claude Code permission mode, and new sessions start in the default mode below. DSH native: the Host's own read-only / workspace-write / full-access selector stays, and the mode follows the sandbox alone (read-only is Plan, workspace-write is Accept edits, full access is Bypass); per-session choices and the default mode are not consulted. Takes effect immediately; a running turn keeps its mode.",
19868
+ defaultPermissionMode: "Default permission mode",
19869
+ defaultPermissionModeEffect: "The Claude Code permission mode a new Claude session starts in; DSH's access preset is moved onto the sandbox that mode needs as the session is created. A session you have since changed with the composer's own selector runs its own choice. A sandbox switched natively (/permission) wins over the mode, and auto yields to Default on a model that cannot run it. Changes apply to sessions created from then on.",
19326
19870
  renderer: "AI output renderer",
19327
19871
  rendererPlugin: "Plugin renderer",
19328
19872
  rendererNative: "DSH native renderer",
@@ -19503,6 +20047,30 @@ window.__ModuleLoader__.load({
19503
20047
  promptSaved: "Saved as \"{name}\"",
19504
20048
  promptSaveExists: "A prompt with that name already exists. Try another.",
19505
20049
  promptSaveFailed: "Could not save: {message}",
20050
+ permissionMode: "Permission mode",
20051
+ permissionModeAria: "Permission mode: {name}",
20052
+ permissionModePlan: "Plan",
20053
+ permissionModePlanHint: "Read-only exploration; the plan comes back for your approval before anything runs",
20054
+ permissionModeDefault: "Default",
20055
+ permissionModeDefaultHint: "Every file edit and command asks first",
20056
+ permissionModeAcceptEdits: "Accept edits",
20057
+ permissionModeAcceptEditsHint: "File edits go through on their own; commands still ask",
20058
+ permissionModeDontAsk: "Don't ask",
20059
+ permissionModeDontAskHint: "Anything not pre-approved is refused instead of asked about",
20060
+ permissionModeAuto: "Auto",
20061
+ permissionModeAutoHint: "Claude Code's classifier approves on your behalf and asks you only when unsure",
20062
+ permissionModeAutoUnsupported: "The current model does not support auto mode",
20063
+ permissionModeBypass: "Bypass permissions",
20064
+ permissionModeBypassHint: "Skip every permission check",
20065
+ permissionModeLocked: "The permission mode cannot change while a turn is running",
20066
+ permissionModeFailed: "Could not switch the permission mode: {message}",
20067
+ permissionModeHostKept: "DSH kept its own access preset; Claude still runs the chosen mode",
20068
+ permissionBypassTitle: "Skip every permission check?",
20069
+ permissionBypassDescription: "Claude Code will run file edits and commands without asking for approval.",
20070
+ permissionBypassAcknowledge: "I understand the risk",
20071
+ permissionBypassCancel: "Cancel",
20072
+ permissionBypassClose: "Close",
20073
+ permissionBypassConfirm: "Enable",
19506
20074
  presetHeaderHint: "The agent preset this session runs",
19507
20075
  diffRepository: "Repository",
19508
20076
  repositoryLinked: "Linked repository: changed by this session",
@@ -19531,6 +20099,9 @@ window.__ModuleLoader__.load({
19531
20099
  diffPushAhead: "{count} unpushed commit(s)",
19532
20100
  diffPushCompleted: "Pushed commit {commit}",
19533
20101
  diffGeneratingMessage: "Suggesting a commit message. It only fills the fields you leave empty.",
20102
+ diffLoadingPreview: "Loading repository changes…",
20103
+ diffCommitMessagePlaceholder: "Describe what changed…",
20104
+ diffCommitMessageHint: "Start with a short summary. Add details after a blank line.",
19534
20105
  diffActionFailed: "Repository action failed.",
19535
20106
  diffIncludeUnstaged: "Include unstaged and untracked changes",
19536
20107
  diffCommitMessage: "Commit message",
@@ -19927,6 +20498,22 @@ window.__ModuleLoader__.load({
19927
20498
  diffOpen: sidebarTabs.sourceFor(CLAUDE_TAB_KINDS.diff, sessionId)
19928
20499
  })
19929
20500
  }, ClaudeDiffHeaderAction));
20501
+ ctx.slots.inject("conversation.input.left", () => ctx.slots.register({
20502
+ name: "conversation.input.left",
20503
+ id: "claude-permission-mode",
20504
+ order: 30,
20505
+ locale: namespace,
20506
+ inject: (sessionId) => {
20507
+ const scope = sessions?.scope(sessionId);
20508
+ return {
20509
+ t,
20510
+ setMode: (mode) => setClaudePermissionMode(sessionId, mode),
20511
+ ...scope === void 0 || conversation === void 0 ? {} : { notify: (level, text) => {
20512
+ sessionInput(conversation, scope).notify(level, text);
20513
+ } }
20514
+ };
20515
+ }
20516
+ }, ClaudePermissionSelect));
19930
20517
  ctx.slots.inject("conversation.input.left", () => ctx.slots.register({
19931
20518
  name: "conversation.input.left",
19932
20519
  id: "claude-prompt-save",