dsh-diff-approval 0.8.0 → 0.9.0

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
@@ -11652,7 +11652,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
11652
11652
  }
11653
11653
  //#endregion
11654
11654
  //#region \0dsh-css:/home/runner/work/dsh-diff-approval/dsh-diff-approval/src/client/PendingPanel.module.css.mjs
11655
- const css = ".F1KBNa_layer{box-sizing:border-box;flex:none;align-items:center;width:calc(100% + 4px);height:42px;margin:4px -2px;display:flex;position:relative}.F1KBNa_footerButtons{align-items:center;width:100%;display:flex}.F1KBNa_badge{box-sizing:border-box;width:100%;height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.F1KBNa_badge:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_badge[data-active]{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_badge:disabled{color:var(--dsw-alias-label-tertiary);cursor:default;background:0 0}.F1KBNa_badgeLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.F1KBNa_badgeCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;margin-left:auto;font-size:12px;line-height:16px}.F1KBNa_layer.F1KBNa_rail{width:36px;height:36px;margin:8px 0 10px}.F1KBNa_rail .F1KBNa_badge{border-radius:50%;justify-content:center;gap:0;width:36px;height:36px;padding:0}.F1KBNa_rail .F1KBNa_badgeLabel{display:none}.F1KBNa_rail .F1KBNa_badgeCount{box-sizing:border-box;background:var(--dsw-alias-state-business-primary);min-width:18px;height:18px;color:var(--dsw-alias-label-primary-foreground);font-variant-numeric:tabular-nums;border-radius:9px;justify-content:center;align-items:center;padding:0 4px;font-size:11px;line-height:18px;display:flex;position:absolute;top:-3px;right:-7px}.F1KBNa_fullscreenBackdrop{z-index:29;background:var(--dsw-specific-sidebar-fill);position:fixed;inset:0}.F1KBNa_panel{z-index:30;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:auto;max-width:none;box-shadow:var(--dsw-shadow-lv2);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;flex-direction:column;display:flex;position:fixed;inset:8px 8px 128px;overflow:hidden}.F1KBNa_header{box-sizing:border-box;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;justify-content:space-between;align-items:center;min-height:44px;padding:10px 12px;display:flex}.F1KBNa_headerActions{align-items:center;gap:2px;display:flex}.F1KBNa_settingsPage{padding:8px 12px}.F1KBNa_settingsRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.F1KBNa_settingsRowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.F1KBNa_settingsRowTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.F1KBNa_settingsRowDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.F1KBNa_settingsSelector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.F1KBNa_settingsSelector:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_settingsSelectorChevron{flex:none}.F1KBNa_states{flex-direction:column;flex:1;min-height:0;padding:4px 12px 12px;display:flex;overflow-y:auto}.F1KBNa_split{flex:1;align-items:stretch;min-height:0;display:flex}.F1KBNa_fileList{box-sizing:border-box;border-right:1px solid var(--dsw-alias-border-l2);flex-direction:column;flex:none;width:240px;min-height:0;padding:4px 8px 12px;display:flex}.F1KBNa_listScroll{flex:1;min-height:0;overflow-y:auto}.F1KBNa_bulkActions{flex:none;gap:6px;padding-top:8px;display:flex}.F1KBNa_bulkActions .F1KBNa_action{text-align:center;flex:1}.F1KBNa_resizeHandle{cursor:col-resize;background:0 0;flex:none;width:5px;margin:0 -2px}.F1KBNa_resizeHandle:hover{background:var(--dsw-alias-border-l2)}.F1KBNa_detail{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.F1KBNa_detailEmpty{color:var(--dsw-alias-label-tertiary);text-align:center;flex:1;justify-content:center;align-items:center;margin:0;padding:24px;font-size:12px;line-height:18px;display:flex}.F1KBNa_title{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:20px}.F1KBNa_note,.F1KBNa_readError,.F1KBNa_hint{color:var(--dsw-alias-label-tertiary);margin:4px 0;font-size:12px;line-height:18px}.F1KBNa_noteCentered{text-align:center;margin:auto}.F1KBNa_emptyState{flex-direction:column;align-items:center;gap:10px;margin:auto;display:flex}.F1KBNa_importButton{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:5px 14px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_importButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_importButton:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_importNote{color:var(--dsw-alias-label-tertiary);text-align:center;margin:0;font-size:12px;line-height:18px}.F1KBNa_readError{color:var(--dsw-alias-state-error-primary)}.F1KBNa_group{color:var(--dsw-alias-label-tertiary);margin:8px 0 4px;font-size:12px;font-weight:500;line-height:16px}.F1KBNa_rows{margin:0;padding:0;list-style:none}.F1KBNa_row{border:1px solid #0000;border-radius:10px;margin:2px 0}.F1KBNa_rowHead{width:100%;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;align-items:baseline;gap:8px;padding:6px 8px;display:flex}.F1KBNa_rowHead:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_rowHead[data-selected]{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_rowPath{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-markdown-code-block);overflow:hidden}.F1KBNa_kindTag{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_kindHint{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px;line-height:16px}.F1KBNa_divergedHint,.F1KBNa_missingHint{border-bottom:1px solid var(--dsw-alias-border-l2);margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missing{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary));white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_rowFailed{border:1px solid var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_actionError{border-bottom:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missingHint{color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary))}.F1KBNa_rowMeta{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;gap:6px;margin-left:auto;font-size:12px;line-height:16px;display:inline-flex}.F1KBNa_addCount{color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 60%, var(--dsw-alias-label-primary))}.F1KBNa_delCount{color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 60%, var(--dsw-alias-label-primary))}.F1KBNa_diff{background:var(--dsw-alias-markdown-code-block);flex-direction:column;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.F1KBNa_diffHeader{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffPath{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary);font:var(--dsw-font-markdown-code-block);flex:1;font-size:12px;line-height:18px;overflow:hidden}.F1KBNa_diffActions{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffStats{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:12px;line-height:16px}.F1KBNa_flexSpacer{flex:1}.F1KBNa_action{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_action:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_actionPrimary{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50)}.F1KBNa_actionPrimary:hover:not(:disabled){background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-static-neutral-bluish-1000))}.F1KBNa_actionPrimary:disabled{background:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:.55}.F1KBNa_actionQuietDisabled:disabled{cursor:pointer;color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l1);background:0 0}.F1KBNa_actionPrimary.F1KBNa_actionQuietDisabled:disabled{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:1}.F1KBNa_iconAction{justify-content:center;align-items:center;min-height:25px;padding:4px 6px;display:inline-flex}.F1KBNa_close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expand{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_expand:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expandExpanded svg{transform:rotate(180deg)}.F1KBNa_diffBodyWrap{flex:1;min-height:0;display:flex;position:relative}.F1KBNa_diffBody{min-width:0;font:var(--dsw-font-markdown-code-block);cursor:text;outline:none;flex:1;padding:0;position:relative;overflow:auto}.F1KBNa_diffBody::-webkit-scrollbar,.F1KBNa_diffBody::-webkit-scrollbar-track,.F1KBNa_diffBody::-webkit-scrollbar-thumb{cursor:default}.F1KBNa_blockActions{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);z-index:2;border-radius:10px;align-items:center;gap:9px;padding:5px;display:flex;position:absolute;right:8px}.F1KBNa_blockPosition{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;margin-top:1px;margin-left:7px;font-size:12px;line-height:16px}.F1KBNa_searchBar{z-index:3;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);border-radius:10px;align-items:center;gap:4px;padding:4px;display:flex;position:absolute;top:8px;right:8px}.F1KBNa_searchInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);width:150px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:3px 8px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_searchInput:focus{border-color:var(--dsw-alias-state-business-primary)}.F1KBNa_searchCount{text-align:center;min-width:34px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:16px}.F1KBNa_diffBody [data-diff-search=hit]{background-image:linear-gradient(#facc1529,#facc1529)}.F1KBNa_diffBody [data-diff-search=current]{background-image:linear-gradient(#facc1552,#facc1552)}.F1KBNa_blockFlash{z-index:1;box-sizing:border-box;border:2px solid var(--dsw-alias-state-business-primary);pointer-events:none;border-radius:4px;animation:1s ease-out forwards F1KBNa_diffFlash;position:absolute;left:0;right:0}@keyframes F1KBNa_diffFlash{0%{opacity:1}to{opacity:0}}.F1KBNa_overviewRuler{pointer-events:none;opacity:.5;width:4px;position:absolute;top:0;bottom:0;right:0}.F1KBNa_overviewMarker{border-radius:2px;width:100%;min-height:2px;position:absolute;right:0}.F1KBNa_markerDel{background-color:var(--dsw-alias-state-error-primary)}.F1KBNa_markerAdd{background-color:var(--dsw-alias-state-success-primary)}.F1KBNa_lines{border-spacing:0;width:max-content;min-width:100%;display:table}.F1KBNa_line{height:22px;line-height:22px;display:table-row}.F1KBNa_vSpacer{display:table-row}.F1KBNa_gutter{box-sizing:border-box;text-align:right;width:44px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;user-select:none;cursor:default;padding-right:10px;display:table-cell}.F1KBNa_code{white-space:pre;display:table-cell}.F1KBNa_context{color:var(--dsw-alias-label-primary)}.F1KBNa_del{background-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.F1KBNa_add{background-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent)}.F1KBNa_statusBar{box-sizing:border-box;border-top:1px solid var(--dsw-alias-border-l2);height:34px;color:var(--dsw-alias-label-tertiary);font-family:var(--dsw-font-markdown-code-block);font-variant-numeric:tabular-nums;flex:none;align-items:center;padding:0 8px;font-size:12px;line-height:18px;display:flex}.F1KBNa_statusAction{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);white-space:nowrap;cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_statusAction:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langSelect{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;flex:none;align-items:center;gap:4px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px;display:inline-flex}.F1KBNa_langSelect:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langLabel{text-overflow:ellipsis;white-space:nowrap;max-width:140px;overflow:hidden}";
11655
+ const css = ".F1KBNa_layer{box-sizing:border-box;flex:none;align-items:center;width:calc(100% + 4px);height:42px;margin:4px -2px;display:flex;position:relative}.F1KBNa_footerButtons{align-items:center;width:100%;display:flex}.F1KBNa_badge{box-sizing:border-box;width:100%;height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.F1KBNa_badge:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_badge[data-active]{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_badge:disabled{color:var(--dsw-alias-label-tertiary);cursor:default;background:0 0}.F1KBNa_badgeLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.F1KBNa_badgeCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;margin-left:auto;font-size:12px;line-height:16px}.F1KBNa_layer.F1KBNa_rail{width:36px;height:36px;margin:8px 0 10px}.F1KBNa_rail .F1KBNa_badge{border-radius:50%;justify-content:center;gap:0;width:36px;height:36px;padding:0}.F1KBNa_rail .F1KBNa_badgeLabel{display:none}.F1KBNa_rail .F1KBNa_badgeCount{box-sizing:border-box;background:var(--dsw-alias-state-business-primary);min-width:18px;height:18px;color:var(--dsw-alias-label-primary-foreground);font-variant-numeric:tabular-nums;border-radius:9px;justify-content:center;align-items:center;padding:0 4px;font-size:11px;line-height:18px;display:flex;position:absolute;top:-3px;right:-7px}.F1KBNa_fullscreenBackdrop{z-index:29;background:var(--dsw-specific-sidebar-fill);position:fixed;inset:0}.F1KBNa_panel{z-index:30;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:auto;max-width:none;box-shadow:var(--dsw-shadow-lv2);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;flex-direction:column;display:flex;position:fixed;inset:8px 8px 128px;overflow:hidden}.F1KBNa_header{box-sizing:border-box;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;justify-content:space-between;align-items:center;min-height:44px;padding:10px 12px;display:flex}.F1KBNa_headerActions{align-items:center;gap:2px;display:flex}.F1KBNa_settingsPage{padding:8px 12px}.F1KBNa_settingsRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.F1KBNa_settingsRowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.F1KBNa_settingsRowTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.F1KBNa_settingsRowDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.F1KBNa_settingsSelector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.F1KBNa_settingsSelector:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_settingsSelectorChevron{flex:none}.F1KBNa_states{flex-direction:column;flex:1;min-height:0;padding:4px 12px 12px;display:flex;overflow-y:auto}.F1KBNa_split{flex:1;align-items:stretch;min-height:0;display:flex}.F1KBNa_fileList{box-sizing:border-box;border-right:1px solid var(--dsw-alias-border-l2);flex-direction:column;flex:none;width:240px;min-height:0;padding:4px 8px 12px;display:flex}.F1KBNa_listScroll{flex:1;min-height:0;overflow-y:auto}.F1KBNa_bulkActions{flex:none;gap:6px;padding-top:8px;display:flex}.F1KBNa_bulkActions .F1KBNa_action{text-align:center;flex:1}.F1KBNa_resizeHandle{cursor:col-resize;background:0 0;flex:none;width:5px;margin:0 -2px}.F1KBNa_resizeHandle:hover{background:var(--dsw-alias-border-l2)}.F1KBNa_detail{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.F1KBNa_detailEmpty{color:var(--dsw-alias-label-tertiary);text-align:center;flex:1;justify-content:center;align-items:center;margin:0;padding:24px;font-size:12px;line-height:18px;display:flex}.F1KBNa_title{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:20px}.F1KBNa_note,.F1KBNa_readError,.F1KBNa_hint{color:var(--dsw-alias-label-tertiary);margin:4px 0;font-size:12px;line-height:18px}.F1KBNa_noteCentered{text-align:center;margin:auto}.F1KBNa_emptyState{flex-direction:column;align-items:center;gap:10px;margin:auto;display:flex}.F1KBNa_importButton{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:5px 14px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_importButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_importButton:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_importNote{color:var(--dsw-alias-label-tertiary);text-align:center;margin:0;font-size:12px;line-height:18px}.F1KBNa_readError{color:var(--dsw-alias-state-error-primary)}.F1KBNa_group{color:var(--dsw-alias-label-tertiary);margin:8px 0 4px;font-size:12px;font-weight:500;line-height:16px}.F1KBNa_rows{margin:0;padding:0;list-style:none}.F1KBNa_row{border:1px solid #0000;border-radius:10px;margin:2px 0}.F1KBNa_rowHead{width:100%;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;align-items:baseline;gap:8px;padding:6px 8px;display:flex}.F1KBNa_rowHead:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_rowHead[data-selected]{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_rowPath{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-markdown-code-block);overflow:hidden}.F1KBNa_kindTag{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_kindHint{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px;line-height:16px}.F1KBNa_divergedHint,.F1KBNa_missingHint{border-bottom:1px solid var(--dsw-alias-border-l2);margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missing{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary));white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_rowFailed{border:1px solid var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_actionError{border-bottom:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missingHint{color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary))}.F1KBNa_rowMeta{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;gap:6px;margin-left:auto;font-size:12px;line-height:16px;display:inline-flex}.F1KBNa_addCount{color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 60%, var(--dsw-alias-label-primary))}.F1KBNa_delCount{color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 60%, var(--dsw-alias-label-primary))}.F1KBNa_diff{background:var(--dsw-alias-markdown-code-block);flex-direction:column;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.F1KBNa_diffHeader{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffPath{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary);font:var(--dsw-font-markdown-code-block);flex:1;font-size:12px;line-height:18px;overflow:hidden}.F1KBNa_diffActions{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffStats{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:12px;line-height:16px}.F1KBNa_flexSpacer{flex:1}.F1KBNa_action{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_action:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_actionPrimary{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50)}.F1KBNa_actionPrimary:hover:not(:disabled){background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-static-neutral-bluish-1000))}.F1KBNa_actionPrimary:disabled{background:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:.55}.F1KBNa_actionQuietDisabled:disabled{cursor:pointer;color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l1);background:0 0}.F1KBNa_actionPrimary.F1KBNa_actionQuietDisabled:disabled{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:1}.F1KBNa_iconAction{justify-content:center;align-items:center;min-height:25px;padding:4px 6px;display:inline-flex}.F1KBNa_close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expand{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_expand:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expandExpanded svg{transform:rotate(180deg)}.F1KBNa_diffBodyWrap{flex:1;min-height:0;display:flex;position:relative}.F1KBNa_diffBody{min-width:0;font:var(--dsw-font-markdown-code-block);cursor:text;outline:none;flex:1;padding:0;position:relative;overflow:auto}.F1KBNa_diffBody::-webkit-scrollbar,.F1KBNa_diffBody::-webkit-scrollbar-track,.F1KBNa_diffBody::-webkit-scrollbar-thumb{cursor:default}.F1KBNa_blockActions{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);z-index:2;border-radius:10px;align-items:center;gap:9px;padding:5px;display:flex;position:absolute;right:8px}.F1KBNa_blockPosition{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;margin-top:1px;margin-left:7px;font-size:12px;line-height:16px}.F1KBNa_searchBar{z-index:3;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);border-radius:10px;align-items:center;gap:4px;padding:4px;display:flex;position:absolute;top:8px;right:8px}.F1KBNa_searchInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);width:150px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:3px 8px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_searchInput:focus{border-color:var(--dsw-alias-state-business-primary)}.F1KBNa_searchCount{text-align:center;min-width:34px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:16px}.F1KBNa_diffBody [data-diff-search=hit]{background-image:linear-gradient(#facc1529,#facc1529)}.F1KBNa_diffBody [data-diff-search=current]{background-image:linear-gradient(#facc1552,#facc1552)}.F1KBNa_blockFlash{z-index:1;box-sizing:border-box;border:2px solid var(--dsw-alias-state-business-primary);pointer-events:none;border-radius:4px;animation:1s ease-out forwards F1KBNa_diffFlash;position:absolute;left:0;right:0}@keyframes F1KBNa_diffFlash{0%{opacity:1}to{opacity:0}}.F1KBNa_overviewRuler{pointer-events:none;opacity:.5;width:4px;position:absolute;top:0;bottom:0;right:0}.F1KBNa_overviewMarker{border-radius:2px;width:100%;min-height:2px;position:absolute;right:0}.F1KBNa_markerDel{background-color:var(--dsw-alias-state-error-primary)}.F1KBNa_markerAdd{background-color:var(--dsw-alias-state-success-primary)}.F1KBNa_lines{border-spacing:0;width:max-content;min-width:100%;display:table}.F1KBNa_line{height:22px;line-height:22px;display:table-row}.F1KBNa_vSpacer{display:table-row}.F1KBNa_gutter{box-sizing:border-box;text-align:right;width:44px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;user-select:none;cursor:default;padding-right:10px;display:table-cell}.F1KBNa_code{white-space:pre;display:table-cell}.F1KBNa_context{color:var(--dsw-alias-label-primary)}.F1KBNa_del{background-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.F1KBNa_add{background-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent)}.F1KBNa_statusBar{box-sizing:border-box;border-top:1px solid var(--dsw-alias-border-l2);height:34px;color:var(--dsw-alias-label-tertiary);font-family:var(--dsw-font-markdown-code-block);font-variant-numeric:tabular-nums;flex:none;align-items:center;padding:0 8px;font-size:12px;line-height:18px;display:flex}.F1KBNa_statusAction{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);white-space:nowrap;cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_statusAction:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langSelect{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;flex:none;align-items:center;gap:4px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px;display:inline-flex}.F1KBNa_langSelect:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langLabel{text-overflow:ellipsis;white-space:nowrap;max-width:140px;overflow:hidden}.F1KBNa_notice{z-index:60;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);max-width:360px;box-shadow:var(--dsw-shadow-lv3);border-radius:10px;align-items:flex-start;gap:12px;padding:12px 14px;display:flex;position:fixed;bottom:24px;right:24px}.F1KBNa_noticeText{font:var(--dsw-font-caption);color:var(--dsw-alias-label-primary);flex:1;margin:0;line-height:1.45}.F1KBNa_noticeButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);font:var(--dsw-font-caption);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px}.F1KBNa_noticeButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}";
11656
11656
  const tagId = "dsh-diff-approval/PendingPanel.module.css";
11657
11657
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
11658
11658
  const tag = document.createElement("style");
@@ -11662,92 +11662,95 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
11662
11662
  document.head.appendChild(tag);
11663
11663
  }
11664
11664
  var PendingPanel_module_css_default = {
11665
- "expandExpanded": "F1KBNa_expandExpanded",
11666
- "panel": "F1KBNa_panel",
11667
- "fullscreenBackdrop": "F1KBNa_fullscreenBackdrop",
11668
- "settingsPage": "F1KBNa_settingsPage",
11669
- "hint": "F1KBNa_hint",
11670
- "row": "F1KBNa_row",
11671
- "title": "F1KBNa_title",
11672
- "blockActions": "F1KBNa_blockActions",
11673
- "langLabel": "F1KBNa_langLabel",
11665
+ "rows": "F1KBNa_rows",
11666
+ "flexSpacer": "F1KBNa_flexSpacer",
11667
+ "importNote": "F1KBNa_importNote",
11674
11668
  "detailEmpty": "F1KBNa_detailEmpty",
11675
- "del": "F1KBNa_del",
11676
- "listScroll": "F1KBNa_listScroll",
11677
- "close": "F1KBNa_close",
11678
- "group": "F1KBNa_group",
11679
- "diffActions": "F1KBNa_diffActions",
11680
- "diffBodyWrap": "F1KBNa_diffBodyWrap",
11681
- "states": "F1KBNa_states",
11682
- "searchInput": "F1KBNa_searchInput",
11683
- "settingsRowText": "F1KBNa_settingsRowText",
11669
+ "divergedHint": "F1KBNa_divergedHint",
11670
+ "detail": "F1KBNa_detail",
11684
11671
  "note": "F1KBNa_note",
11685
- "addCount": "F1KBNa_addCount",
11686
- "layer": "F1KBNa_layer",
11687
- "diff": "F1KBNa_diff",
11688
- "add": "F1KBNa_add",
11689
- "overviewMarker": "F1KBNa_overviewMarker",
11690
11672
  "settingsRowDesc": "F1KBNa_settingsRowDesc",
11691
- "actionQuietDisabled": "F1KBNa_actionQuietDisabled",
11673
+ "add": "F1KBNa_add",
11692
11674
  "searchCount": "F1KBNa_searchCount",
11693
- "badgeCount": "F1KBNa_badgeCount",
11694
- "context": "F1KBNa_context",
11695
- "settingsSelectorChevron": "F1KBNa_settingsSelectorChevron",
11696
- "kindHint": "F1KBNa_kindHint",
11697
11675
  "footerButtons": "F1KBNa_footerButtons",
11698
- "diffHeader": "F1KBNa_diffHeader",
11699
- "resizeHandle": "F1KBNa_resizeHandle",
11700
- "statusBar": "F1KBNa_statusBar",
11701
- "rowPath": "F1KBNa_rowPath",
11702
- "settingsSelector": "F1KBNa_settingsSelector",
11703
- "importButton": "F1KBNa_importButton",
11704
- "markerAdd": "F1KBNa_markerAdd",
11705
- "header": "F1KBNa_header",
11706
11676
  "settingsRowTitle": "F1KBNa_settingsRowTitle",
11707
- "emptyState": "F1KBNa_emptyState",
11677
+ "title": "F1KBNa_title",
11678
+ "hint": "F1KBNa_hint",
11679
+ "overviewRuler": "F1KBNa_overviewRuler",
11680
+ "gutter": "F1KBNa_gutter",
11681
+ "code": "F1KBNa_code",
11682
+ "badge": "F1KBNa_badge",
11683
+ "badgeLabel": "F1KBNa_badgeLabel",
11708
11684
  "rail": "F1KBNa_rail",
11709
- "diffFlash": "F1KBNa_diffFlash",
11710
- "action": "F1KBNa_action",
11711
- "detail": "F1KBNa_detail",
11712
- "rowMeta": "F1KBNa_rowMeta",
11713
- "actionError": "F1KBNa_actionError",
11714
- "diffStats": "F1KBNa_diffStats",
11715
- "flexSpacer": "F1KBNa_flexSpacer",
11716
11685
  "diffBody": "F1KBNa_diffBody",
11717
- "statusAction": "F1KBNa_statusAction",
11718
- "readError": "F1KBNa_readError",
11686
+ "rowMeta": "F1KBNa_rowMeta",
11687
+ "resizeHandle": "F1KBNa_resizeHandle",
11719
11688
  "kindTag": "F1KBNa_kindTag",
11720
- "delCount": "F1KBNa_delCount",
11689
+ "states": "F1KBNa_states",
11690
+ "panel": "F1KBNa_panel",
11691
+ "diff": "F1KBNa_diff",
11692
+ "statusAction": "F1KBNa_statusAction",
11721
11693
  "blockPosition": "F1KBNa_blockPosition",
11722
- "overviewRuler": "F1KBNa_overviewRuler",
11694
+ "notice": "F1KBNa_notice",
11695
+ "noticeText": "F1KBNa_noticeText",
11723
11696
  "rowFailed": "F1KBNa_rowFailed",
11724
- "headerActions": "F1KBNa_headerActions",
11725
- "divergedHint": "F1KBNa_divergedHint",
11726
- "code": "F1KBNa_code",
11697
+ "context": "F1KBNa_context",
11698
+ "del": "F1KBNa_del",
11699
+ "markerDel": "F1KBNa_markerDel",
11700
+ "langLabel": "F1KBNa_langLabel",
11701
+ "missing": "F1KBNa_missing",
11702
+ "diffStats": "F1KBNa_diffStats",
11703
+ "actionError": "F1KBNa_actionError",
11704
+ "blockFlash": "F1KBNa_blockFlash",
11705
+ "noticeButton": "F1KBNa_noticeButton",
11706
+ "iconAction": "F1KBNa_iconAction",
11707
+ "diffFlash": "F1KBNa_diffFlash",
11727
11708
  "noteCentered": "F1KBNa_noteCentered",
11709
+ "badgeCount": "F1KBNa_badgeCount",
11710
+ "statusBar": "F1KBNa_statusBar",
11711
+ "listScroll": "F1KBNa_listScroll",
11712
+ "expandExpanded": "F1KBNa_expandExpanded",
11713
+ "lines": "F1KBNa_lines",
11714
+ "readError": "F1KBNa_readError",
11715
+ "layer": "F1KBNa_layer",
11728
11716
  "expand": "F1KBNa_expand",
11729
- "vSpacer": "F1KBNa_vSpacer",
11730
- "importNote": "F1KBNa_importNote",
11731
- "settingsRow": "F1KBNa_settingsRow",
11732
- "split": "F1KBNa_split",
11733
- "missing": "F1KBNa_missing",
11717
+ "blockActions": "F1KBNa_blockActions",
11734
11718
  "actionPrimary": "F1KBNa_actionPrimary",
11735
- "blockFlash": "F1KBNa_blockFlash",
11736
- "langSelect": "F1KBNa_langSelect",
11737
- "badge": "F1KBNa_badge",
11719
+ "fullscreenBackdrop": "F1KBNa_fullscreenBackdrop",
11720
+ "diffBodyWrap": "F1KBNa_diffBodyWrap",
11721
+ "diffHeader": "F1KBNa_diffHeader",
11722
+ "rowPath": "F1KBNa_rowPath",
11723
+ "headerActions": "F1KBNa_headerActions",
11724
+ "kindHint": "F1KBNa_kindHint",
11738
11725
  "diffPath": "F1KBNa_diffPath",
11739
- "iconAction": "F1KBNa_iconAction",
11740
- "markerDel": "F1KBNa_markerDel",
11741
- "bulkActions": "F1KBNa_bulkActions",
11742
- "gutter": "F1KBNa_gutter",
11726
+ "split": "F1KBNa_split",
11727
+ "importButton": "F1KBNa_importButton",
11728
+ "diffActions": "F1KBNa_diffActions",
11729
+ "delCount": "F1KBNa_delCount",
11743
11730
  "rowHead": "F1KBNa_rowHead",
11744
- "searchBar": "F1KBNa_searchBar",
11745
- "fileList": "F1KBNa_fileList",
11746
- "lines": "F1KBNa_lines",
11747
- "rows": "F1KBNa_rows",
11731
+ "overviewMarker": "F1KBNa_overviewMarker",
11732
+ "header": "F1KBNa_header",
11733
+ "searchInput": "F1KBNa_searchInput",
11734
+ "markerAdd": "F1KBNa_markerAdd",
11735
+ "vSpacer": "F1KBNa_vSpacer",
11736
+ "settingsRowText": "F1KBNa_settingsRowText",
11748
11737
  "missingHint": "F1KBNa_missingHint",
11738
+ "group": "F1KBNa_group",
11739
+ "emptyState": "F1KBNa_emptyState",
11740
+ "bulkActions": "F1KBNa_bulkActions",
11741
+ "settingsSelector": "F1KBNa_settingsSelector",
11742
+ "searchBar": "F1KBNa_searchBar",
11743
+ "settingsSelectorChevron": "F1KBNa_settingsSelectorChevron",
11744
+ "row": "F1KBNa_row",
11745
+ "close": "F1KBNa_close",
11749
11746
  "line": "F1KBNa_line",
11750
- "badgeLabel": "F1KBNa_badgeLabel"
11747
+ "settingsRow": "F1KBNa_settingsRow",
11748
+ "fileList": "F1KBNa_fileList",
11749
+ "settingsPage": "F1KBNa_settingsPage",
11750
+ "addCount": "F1KBNa_addCount",
11751
+ "action": "F1KBNa_action",
11752
+ "langSelect": "F1KBNa_langSelect",
11753
+ "actionQuietDisabled": "F1KBNa_actionQuietDisabled"
11751
11754
  };
11752
11755
  //#endregion
11753
11756
  //#region lib/types/client/PendingPanel.js
@@ -11790,10 +11793,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
11790
11793
  * 5px frame padding on each side + 1px border on each side, plus a little
11791
11794
  * breathing room so the bottom padding never sits flush against it. */
11792
11795
  const BLOCK_ACTIONS_FRAME_PX = 40;
11793
- /** How long a fully-processed list stays open before the panel folds, so the
11794
- * last action (a Keep-all/Revert-all especially) can still be undone with
11795
- * Ctrl+Z. An undo that restores an entry cancels the pending close. */
11796
- const EMPTY_CLOSE_GRACE_MS = 3e3;
11797
11796
  /** The trailing file-name segment of a path, used for row display. */
11798
11797
  function basenameOf(path) {
11799
11798
  const index = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
@@ -12123,8 +12122,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12123
12122
  const [flashKey, setFlashKey] = (0, react.useState)(0);
12124
12123
  (0, react.useEffect)(() => {
12125
12124
  setFocus(0);
12126
- setScrollTop(0);
12127
- if (bodyRef.current !== null) bodyRef.current.scrollTop = 0;
12128
12125
  bodyRef.current?.focus();
12129
12126
  setFlashKey((key) => key + 1);
12130
12127
  setHoveredBlock(void 0);
@@ -12400,7 +12397,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12400
12397
  children: t("panel.createHint")
12401
12398
  }),
12402
12399
  model.blocks.length > 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
12403
- label: t("action.prevDiff"),
12400
+ label: `${t("action.prevDiff")} (Ctrl+↑)`,
12404
12401
  side: "bottom",
12405
12402
  delayMs: 500,
12406
12403
  children: (0, react_jsx_runtime.jsx)("button", {
@@ -12415,7 +12412,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12415
12412
  children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronUpOutline14, { size: 14 })
12416
12413
  })
12417
12414
  }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
12418
- label: t("action.nextDiff"),
12415
+ label: `${t("action.nextDiff")} (Ctrl+↓)`,
12419
12416
  side: "bottom",
12420
12417
  delayMs: 500,
12421
12418
  children: (0, react_jsx_runtime.jsx)("button", {
@@ -12697,7 +12694,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12697
12694
  });
12698
12695
  }
12699
12696
  /** Render the pending-edit review panel and its unified footer action. */
12700
- function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, onPasteReference, onUndo, onRedo, onImportVcs, t }) {
12697
+ function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, onPasteReference, onUndo, onRedo, onImportVcs, onAckRedoCleared, t }) {
12701
12698
  const current = useSessions((state) => state.current);
12702
12699
  const currentBlank = useSessions((state) => {
12703
12700
  const id = state.current;
@@ -12725,8 +12722,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12725
12722
  const [importToast, setImportToast] = (0, react.useState)(null);
12726
12723
  /** A transient banner for a keep/revert failure. */
12727
12724
  const [actionToast, setActionToast] = (0, react.useState)(null);
12728
- /** Pending count captured at open time; auto-close needs a list that emptied. */
12729
- const [openedCount, setOpenedCount] = (0, react.useState)(0);
12725
+ /** Whether the redo-cleared notice is showing (bottom-right, OK to dismiss). */
12726
+ const [redoClearedNotice, setRedoClearedNotice] = (0, react.useState)(false);
12730
12727
  /** Bottom offset tracking the chat composer's top edge so the input stays visible. */
12731
12728
  const [bottomPx, setBottomPx] = (0, react.useState)(FALLBACK_BOTTOM_PX);
12732
12729
  /** Fullscreen expanded: the panel bottom pins to the window edge, ignoring the composer offset. */
@@ -12743,6 +12740,15 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12743
12740
  clearInterval(timer);
12744
12741
  };
12745
12742
  }, [current, onRefresh]);
12743
+ (0, react.useEffect)(() => {
12744
+ if (!open || !snapshot.redoCleared) return;
12745
+ onAckRedoCleared();
12746
+ setRedoClearedNotice(true);
12747
+ }, [
12748
+ open,
12749
+ snapshot.redoCleared,
12750
+ onAckRedoCleared
12751
+ ]);
12746
12752
  (0, react.useEffect)(() => {
12747
12753
  if (!open) return;
12748
12754
  const MEASURE_INTERVAL_MS = 400;
@@ -12814,23 +12820,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12814
12820
  files,
12815
12821
  selected
12816
12822
  ]);
12817
- (0, react.useEffect)(() => {
12818
- if (!open || openedCount === 0) return;
12819
- if (!(snapshot.read && snapshot.error === void 0 && files.length === 0)) return;
12820
- const timer = window.setTimeout(() => {
12821
- setOpenedCount(0);
12822
- setOpen(false);
12823
- }, EMPTY_CLOSE_GRACE_MS);
12824
- return () => {
12825
- window.clearTimeout(timer);
12826
- };
12827
- }, [
12828
- open,
12829
- openedCount,
12830
- snapshot.read,
12831
- snapshot.error,
12832
- files.length
12833
- ]);
12834
12823
  const runImportVcs = async () => {
12835
12824
  if (current === void 0 || importBusy) return;
12836
12825
  setImportBusy(true);
@@ -12850,7 +12839,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12850
12839
  }
12851
12840
  };
12852
12841
  const toggleOpen = () => {
12853
- if (!open) setOpenedCount(files.length);
12854
12842
  setOpen((value) => !value);
12855
12843
  };
12856
12844
  (0, react.useEffect)(() => {
@@ -13147,6 +13135,23 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
13147
13135
  })
13148
13136
  ]
13149
13137
  })
13138
+ }),
13139
+ redoClearedNotice && (0, react_jsx_runtime.jsxs)("div", {
13140
+ className: PendingPanel_module_css_default.notice,
13141
+ role: "status",
13142
+ "data-diff-approval-notice": true,
13143
+ children: [(0, react_jsx_runtime.jsx)("p", {
13144
+ className: PendingPanel_module_css_default.noticeText,
13145
+ children: t("panel.externalChanged")
13146
+ }), (0, react_jsx_runtime.jsx)("button", {
13147
+ type: "button",
13148
+ className: PendingPanel_module_css_default.noticeButton,
13149
+ "data-diff-notice-dismiss": true,
13150
+ onClick: () => {
13151
+ setRedoClearedNotice(false);
13152
+ },
13153
+ children: t("panel.dismiss")
13154
+ })]
13150
13155
  })
13151
13156
  ]
13152
13157
  });
@@ -13356,7 +13361,11 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
13356
13361
  const file = pendingFileOf(row);
13357
13362
  if (file !== void 0) files.push(file);
13358
13363
  }
13359
- return {
13364
+ return value.redoCleared === true ? {
13365
+ files,
13366
+ workspacePath,
13367
+ redoCleared: true
13368
+ } : {
13360
13369
  files,
13361
13370
  workspacePath
13362
13371
  };
@@ -13423,8 +13432,12 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
13423
13432
  busy: EMPTY_BUSY
13424
13433
  };
13425
13434
  const listeners = /* @__PURE__ */ new Set();
13435
+ let redoCleared = false;
13426
13436
  const publish = (next) => {
13427
- snapshot = next;
13437
+ snapshot = redoCleared ? {
13438
+ ...next,
13439
+ redoCleared: true
13440
+ } : next;
13428
13441
  for (const listener of [...listeners]) listener();
13429
13442
  };
13430
13443
  const failedOf = (value) => value.failed ?? EMPTY_FAILED;
@@ -13497,7 +13510,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
13497
13510
  return;
13498
13511
  }
13499
13512
  try {
13500
- const { files, workspacePath } = await port.list(sessionId);
13513
+ const { files, workspacePath, redoCleared: cleared } = await port.list(sessionId);
13514
+ if (cleared) redoCleared = true;
13501
13515
  publish({
13502
13516
  read: true,
13503
13517
  files,
@@ -13605,6 +13619,11 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
13605
13619
  files: [],
13606
13620
  busy: EMPTY_BUSY
13607
13621
  });
13622
+ },
13623
+ clearRedoCleared() {
13624
+ redoCleared = false;
13625
+ const { redoCleared: _omit, ...rest } = snapshot;
13626
+ publish(rest);
13608
13627
  }
13609
13628
  };
13610
13629
  }
@@ -13627,6 +13646,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
13627
13646
  "panel.searchPlaceholder": "搜索",
13628
13647
  "panel.missing": "文件已不存在",
13629
13648
  "panel.missingHint": "该文件已不存在,回退会恢复该文件。",
13649
+ "panel.externalChanged": "检测到文件在外部被修改,已更新对比并新建撤销点;重做历史已被重置。",
13650
+ "panel.dismiss": "知道了",
13630
13651
  "panel.createHint": "回退会删除该新建的文件。",
13631
13652
  "panel.pasteOnCopy": "复制引用后自动粘贴到消息输入框",
13632
13653
  "panel.pasteOnCopyDesc": "开启后,复制的引用会自动填入消息输入框,输入框会获得焦点。",
@@ -13683,6 +13704,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
13683
13704
  "panel.searchPlaceholder": "Search",
13684
13705
  "panel.missing": "File is gone",
13685
13706
  "panel.missingHint": "This file no longer exists; reverting restores it.",
13707
+ "panel.externalChanged": "A file changed outside the review. The comparison was updated and a new undo point created; the redo history was reset.",
13708
+ "panel.dismiss": "Got it",
13686
13709
  "panel.createHint": "Reverting removes this created file.",
13687
13710
  "panel.pasteOnCopy": "Paste the copied reference into the composer",
13688
13711
  "panel.pasteOnCopyDesc": "When enabled, a copied reference is pasted into the composer, which then receives focus.",
@@ -13765,6 +13788,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
13765
13788
  onUndo: (sessionId) => store.undo(sessionId),
13766
13789
  onRedo: (sessionId) => store.redo(sessionId),
13767
13790
  onImportVcs: (sessionId, includeUntracked) => store.importVcs(sessionId, includeUntracked),
13791
+ onAckRedoCleared: () => store.clearRedoCleared(),
13768
13792
  onPasteReference: (sessionId, reference) => {
13769
13793
  const actx = ctx.get("sessions")?.scope(sessionId);
13770
13794
  if (actx === void 0) return;
package/lib/index.js CHANGED
@@ -864,9 +864,16 @@ function apply(ctx, config) {
864
864
  await ensureLoaded(sessionId);
865
865
  if (store.fold(entry)) await persistSession(sessionId);
866
866
  }
867
+ /** The stable `FsError.code`, when the thrown value carries one. */
868
+ function fsErrorCodeOf(error) {
869
+ if (typeof error !== "object" || error === null) return void 0;
870
+ const code = error.code;
871
+ return typeof code === "string" ? code : void 0;
872
+ }
867
873
  /**
868
- * Read one path's live state: present content, an unresolvable (missing)
869
- * path, or a resolved-but-unreadable file.
874
+ * Read one path's live state. The only existence test is `stat`: it returns
875
+ * `undefined` for an absent target (gone), so a deleted file never falls into
876
+ * the unreadable bucket. A file that exists but cannot be read is `unavailable`.
870
877
  * @param path - backend display path to probe through `ctx.fs`.
871
878
  * @returns the live state.
872
879
  */
@@ -874,22 +881,23 @@ function apply(ctx, config) {
874
881
  let target;
875
882
  try {
876
883
  target = await ctx.fs.resolve(path, {});
877
- } catch {
878
- return {
879
- present: false,
880
- kind: "missing"
881
- };
884
+ } catch (error) {
885
+ return fsErrorCodeOf(error) === "FS_NOT_FOUND" ? { kind: "deleted" } : { kind: "unavailable" };
886
+ }
887
+ let info;
888
+ try {
889
+ info = await ctx.fs.stat(target, void 0);
890
+ } catch (error) {
891
+ return fsErrorCodeOf(error) === "FS_NOT_FOUND" ? { kind: "deleted" } : { kind: "unavailable" };
882
892
  }
893
+ if (info === void 0) return { kind: "deleted" };
883
894
  try {
884
895
  return {
885
- present: true,
896
+ kind: "present",
886
897
  content: await ctx.fs.readText(target, void 0)
887
898
  };
888
- } catch {
889
- return {
890
- present: false,
891
- kind: "unreadable"
892
- };
899
+ } catch (error) {
900
+ return fsErrorCodeOf(error) === "FS_NOT_FOUND" ? { kind: "deleted" } : { kind: "unavailable" };
893
901
  }
894
902
  }
895
903
  /**
@@ -898,7 +906,32 @@ function apply(ctx, config) {
898
906
  * @param entries - the store's entries for one session.
899
907
  * @returns entries with `missing` and `diverged` set from the live file.
900
908
  */
901
- async function listWithState(entries) {
909
+ /** Drop every undo/redo pair that belongs to a removed entry, so the LIFO
910
+ * queue stays traversable without ever trying to restore an unreadable file. */
911
+ function purgeForEntry(sessionId, entryId, path) {
912
+ const key = String(sessionId);
913
+ for (const stacks of [undoStacks, redoStacks]) {
914
+ const stack = stacks.get(key);
915
+ if (stack === void 0) continue;
916
+ stacks.set(key, stack.filter((pair) => {
917
+ const touches = (state) => state.id === entryId || state.path === path;
918
+ const batch = pair.before.batch ?? pair.after.batch;
919
+ if (batch !== void 0) return !batch.some((item) => item.id === entryId || item.path === path);
920
+ return !touches(pair.before) && !touches(pair.after);
921
+ }));
922
+ }
923
+ }
924
+ /**
925
+ * Settle each listed entry against its live file. Existence is decided by the
926
+ * live state alone: a deleted file leaves the list as an undoable checkpoint
927
+ * (Ctrl+Z recreates it and restores the entry), an unavailable one leaves the
928
+ * list and has its undo/redo records dropped, and externally changed content
929
+ * is adopted as the new baseline with its own checkpoint.
930
+ * @param sessionId - the session being listed.
931
+ * @param entries - the store's entries for one session.
932
+ * @returns the listed entries plus whether an external change cleared redo.
933
+ */
934
+ async function listWithState(sessionId, entries) {
902
935
  const byPath = /* @__PURE__ */ new Map();
903
936
  for (const entry of entries) {
904
937
  const group = byPath.get(entry.path);
@@ -906,21 +939,62 @@ function apply(ctx, config) {
906
939
  else group.push(entry);
907
940
  }
908
941
  const listed = [];
942
+ let redoCleared = false;
909
943
  for (const group of byPath.values()) {
910
944
  const newest = group[group.length - 1];
911
945
  if (newest === void 0) continue;
912
946
  const live = await liveStateOf(newest.path);
947
+ if (live.kind === "deleted") {
948
+ store.remove(sessionId, newest.id);
949
+ pushUndo(sessionId, {
950
+ id: newest.id,
951
+ path: newest.path,
952
+ entry: newest,
953
+ fileText: newest.newText
954
+ }, {
955
+ id: newest.id,
956
+ path: newest.path,
957
+ entry: void 0,
958
+ fileText: void 0
959
+ });
960
+ await persistSession(sessionId);
961
+ continue;
962
+ }
963
+ if (live.kind === "unavailable") {
964
+ store.remove(sessionId, newest.id);
965
+ purgeForEntry(sessionId, newest.id, newest.path);
966
+ await persistSession(sessionId);
967
+ continue;
968
+ }
969
+ const content = live.content;
913
970
  let adopted = newest.newText;
914
- if (live.present && typeof live.content === "string" && live.content !== newest.newText) {
915
- adopted = live.content;
916
- if (store.update(newest.sessionId, newest.id, { newText: live.content })) await persistSession(newest.sessionId);
971
+ const hasContent = typeof content === "string";
972
+ if (hasContent && content !== newest.newText) {
973
+ adopted = content;
974
+ const beforeText = newest.newText;
975
+ const redoWasPresent = redoStacks.has(String(sessionId));
976
+ store.update(sessionId, newest.id, { newText: content });
977
+ pushUndo(sessionId, {
978
+ id: newest.id,
979
+ path: newest.path,
980
+ entry: newest,
981
+ fileText: beforeText
982
+ }, {
983
+ id: newest.id,
984
+ path: newest.path,
985
+ entry: {
986
+ ...newest,
987
+ newText: content,
988
+ updatedAt: Date.now()
989
+ },
990
+ fileText: content
991
+ });
992
+ await persistSession(sessionId);
993
+ if (redoWasPresent) redoCleared = true;
917
994
  }
918
- const state = live.present ? {
995
+ const state = {
919
996
  missing: false,
920
- diverged: live.content !== adopted
921
- } : {
922
- missing: live.kind === "missing",
923
- diverged: live.kind === "unreadable"
997
+ diverged: hasContent ? content !== adopted : true
924
998
  };
925
999
  for (const entry of group) listed.push(entry.id === newest.id ? {
926
1000
  ...entry,
@@ -931,7 +1005,10 @@ function apply(ctx, config) {
931
1005
  ...state
932
1006
  });
933
1007
  }
934
- return listed;
1008
+ return {
1009
+ files: listed,
1010
+ redoCleared
1011
+ };
935
1012
  }
936
1013
  /**
937
1014
  * The workspace whose session account holds `sessionId`. Web sessions are
@@ -1146,11 +1223,13 @@ function apply(ctx, config) {
1146
1223
  case "list": {
1147
1224
  const sessionId = sessionOf(payload);
1148
1225
  if (sessionId === void 0) return rpcError("sessionId must be a non-empty string");
1226
+ const { files, redoCleared } = await listWithState(sessionId, await workspaceEntries(sessionId));
1149
1227
  return {
1150
1228
  ok: true,
1151
1229
  value: {
1152
- files: await listWithState(await workspaceEntries(sessionId)),
1153
- workspacePath: workspaceOf(sessionId)?.path
1230
+ files,
1231
+ workspacePath: workspaceOf(sessionId)?.path,
1232
+ redoCleared: redoCleared || void 0
1154
1233
  }
1155
1234
  };
1156
1235
  }
@@ -14,4 +14,4 @@ export type PendingPanelProps = PropsRuntime<'sidebar.footer.action'> & InjectFa
14
14
  */
15
15
  export declare function openSettingsSection(sectionLabel: string): void;
16
16
  /** Render the pending-edit review panel and its unified footer action. */
17
- export declare function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, onPasteReference, onUndo, onRedo, onImportVcs, t, }: PendingPanelProps): import("react").JSX.Element;
17
+ export declare function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, onPasteReference, onUndo, onRedo, onImportVcs, onAckRedoCleared, t, }: PendingPanelProps): import("react").JSX.Element;
@@ -15,6 +15,8 @@ export declare const zh: {
15
15
  'panel.searchPlaceholder': string;
16
16
  'panel.missing': string;
17
17
  'panel.missingHint': string;
18
+ 'panel.externalChanged': string;
19
+ 'panel.dismiss': string;
18
20
  'panel.createHint': string;
19
21
  'panel.pasteOnCopy': string;
20
22
  'panel.pasteOnCopyDesc': string;
@@ -79,6 +81,8 @@ export declare const en: {
79
81
  'panel.searchPlaceholder': string;
80
82
  'panel.missing': string;
81
83
  'panel.missingHint': string;
84
+ 'panel.externalChanged': string;
85
+ 'panel.dismiss': string;
82
86
  'panel.createHint': string;
83
87
  'panel.pasteOnCopy': string;
84
88
  'panel.pasteOnCopyDesc': string;
@@ -16,6 +16,10 @@ export interface PendingDiffSnapshot {
16
16
  failed?: ReadonlyMap<string, string> | undefined;
17
17
  /** The viewing session's workspace root (when it has one); enables workspace-relative references. */
18
18
  workspacePath?: string | undefined;
19
+ /** Latched when an external change created a fresh undo checkpoint that
20
+ * superseded the redo history; the panel surfaces it once (deferred if the
21
+ * panel is closed) via a bottom-right notice. */
22
+ redoCleared?: boolean;
19
23
  }
20
24
  /** The injected face the panel component receives from the plugin body. */
21
25
  export interface PendingPanelFace {
@@ -43,4 +47,6 @@ export interface PendingPanelFace {
43
47
  onRedo: (sessionId: SessionId) => Promise<string | undefined>;
44
48
  /** Import the workspace's local VCS changes as pending entries (detection included). */
45
49
  onImportVcs: (sessionId: SessionId, includeUntracked: boolean) => Promise<VcsImportValue>;
50
+ /** Acknowledge the redo-cleared notice so it is only surfaced once. */
51
+ onAckRedoCleared: () => void;
46
52
  }
@@ -32,6 +32,8 @@ export interface PendingDiffStore extends HostObservable<PendingDiffSnapshot> {
32
32
  open: (sessionId: SessionId, id: string, action: DiffApprovalOpenAction) => Promise<void>;
33
33
  /** Drop every local fact (used on connection reset). */
34
34
  reset: () => void;
35
+ /** Acknowledge a redo-cleared notice so the panel surfaces it only once. */
36
+ clearRedoCleared: () => void;
35
37
  }
36
38
  /**
37
39
  * Create the store over the review-channel port.
@@ -53,6 +53,10 @@ export interface DiffApprovalListValue {
53
53
  files: PendingFileDiff[];
54
54
  /** The viewing session's workspace root (when it has one), for workspace-relative references. */
55
55
  workspacePath?: string | undefined;
56
+ /** Set when a detected external change created a fresh undo checkpoint while
57
+ * redo history was pending, so the panel can surface that the redo stack was
58
+ * superseded. */
59
+ redoCleared?: boolean | undefined;
56
60
  }
57
61
  /** What the open endpoint asks the OS to do with a file. */
58
62
  export type DiffApprovalOpenAction = 'open' | 'reveal';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-diff-approval",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "DeepSeek Harness plugin: pending-edit review with whole-file diff and Keep/Revert",
5
5
  "packageManager": "pnpm@11.21.0",
6
6
  "author": "Wu Zhiwei",