@civilization/dsh-git-workbench 0.4.0 → 0.4.2

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
@@ -334,7 +334,7 @@ window.__ModuleLoader__.load({
334
334
  };
335
335
  }
336
336
  // \0dsh-css:src/client/GitBody.module.css.mjs
337
- const css$1 = ".aeR_dq_root{height:100%;min-height:0;color:var(--dsw-alias-label-primary);font-size:var(--dsh-content-font-size-secondary,13px);user-select:none;background:0 0;flex-direction:column;flex:auto;line-height:1.5;display:flex}.aeR_dq_header{box-sizing:border-box;border-bottom:.5px solid var(--dsw-alias-border-l2);flex:none;justify-content:space-between;align-items:center;gap:8px;height:38px;padding:0 10px 0 12px;display:flex}.aeR_dq_branchInfo{align-items:center;gap:6px;min-width:0;display:flex}.aeR_dq_branchBadge{border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:4px;max-width:160px;padding:2px 7px;font-size:12px;font-weight:500;display:inline-flex;overflow:hidden}.aeR_dq_branchIcon{color:var(--dsw-alias-state-business-primary);flex-shrink:0}.aeR_dq_statusAheadBehind{gap:4px;font-size:11px;font-weight:600;display:inline-flex}.aeR_dq_aheadText{color:var(--dsw-alias-state-business-primary)}.aeR_dq_behindText{color:var(--dsw-alias-state-warn-primary)}.aeR_dq_headerActions{align-items:center;gap:4px;display:flex}.aeR_dq_iconButton{border-radius:var(--dsw-radius-sm);width:26px;height:26px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;padding:0;transition:background-color .15s,color .15s;display:inline-flex}.aeR_dq_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.aeR_dq_iconButton.aeR_dq_spinning svg{animation:.8s linear infinite aeR_dq_spin}@keyframes aeR_dq_spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.aeR_dq_tabs{border-bottom:.5px solid var(--dsw-alias-border-l2);background:0 0;align-items:center;gap:4px;padding:4px 10px;display:flex}.aeR_dq_tab{border-radius:var(--dsw-radius-sm);color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;align-items:center;gap:5px;padding:4px 10px;font-size:12px;font-weight:500;transition:all .15s;display:inline-flex}.aeR_dq_tab:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.aeR_dq_tabActive{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-state-business-primary);font-weight:600}.aeR_dq_tabCount{background:var(--dsw-alias-interactive-bg-hover);color:inherit;border-radius:10px;justify-content:center;align-items:center;padding:0 5px;font-size:10px;font-weight:700;display:inline-flex}.aeR_dq_content{flex-direction:column;flex:auto;gap:10px;min-height:0;padding:8px 10px;display:flex;overflow-y:auto}.aeR_dq_emptyState{text-align:center;color:var(--dsw-alias-label-tertiary);flex-direction:column;justify-content:center;align-items:center;gap:8px;padding:32px 16px;display:flex}.aeR_dq_emptyState svg{opacity:.6;width:28px;height:28px}.aeR_dq_section{border-radius:var(--dsw-radius-md);border:.5px solid var(--dsw-alias-border-l2);background:0 0;flex-direction:column;display:flex;overflow:hidden}.aeR_dq_sectionHeader{border-bottom:.5px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-hover);cursor:pointer;color:var(--dsw-alias-label-primary);justify-content:space-between;align-items:center;padding:6px 10px;font-size:12px;font-weight:600;display:flex}.aeR_dq_sectionTitle{align-items:center;gap:6px;display:flex}.aeR_dq_sectionActions{align-items:center;gap:4px;display:flex}.aeR_dq_actionTextBtn{border-radius:var(--dsw-radius-xs,3px);border:.5px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;padding:2px 6px;font-size:11px;transition:all .12s}.aeR_dq_actionTextBtn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.aeR_dq_fileList{flex-direction:column;display:flex}.aeR_dq_fileItem{border-top:.5px solid var(--dsw-alias-border-l1);cursor:pointer;color:var(--dsw-alias-label-primary);justify-content:space-between;align-items:center;padding:5px 10px;font-size:12px;transition:background .12s;display:flex}.aeR_dq_fileItem:hover{background:var(--dsw-alias-interactive-bg-hover)}.aeR_dq_fileLeft{flex:1;align-items:center;gap:6px;min-width:0;display:flex}.aeR_dq_statusBadge{border-radius:3px;flex-shrink:0;justify-content:center;align-items:center;width:16px;height:16px;font-size:10px;font-weight:700;display:inline-flex}.aeR_dq_statusM{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 15%, transparent);color:var(--dsw-alias-state-business-primary)}.aeR_dq_statusA{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent);color:var(--dsw-alias-state-success-primary)}.aeR_dq_statusD{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent);color:var(--dsw-alias-state-error-primary)}.aeR_dq_statusU{background:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 15%, transparent);color:var(--dsw-alias-state-warn-primary)}.aeR_dq_fileName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.aeR_dq_fileDir{color:var(--dsw-alias-label-tertiary);font-size:11px}.aeR_dq_fileItemActions{opacity:0;align-items:center;gap:4px;transition:opacity .12s;display:flex}.aeR_dq_fileItem:hover .aeR_dq_fileItemActions{opacity:1}.aeR_dq_fileMiniBtn{border-radius:var(--dsw-radius-xs,3px);background:var(--dsw-alias-interactive-bg-hover);width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;border:none;justify-content:center;align-items:center;font-size:12px;transition:background .12s,color .12s;display:inline-flex}.aeR_dq_fileMiniBtn:hover{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}.aeR_dq_commitBox{border-radius:var(--dsw-radius-md);border:.5px solid var(--dsw-alias-border-l2);background:0 0;flex-direction:column;gap:8px;margin-top:4px;padding:10px;display:flex}.aeR_dq_commitTextarea{box-sizing:border-box;border-radius:var(--dsw-radius-sm);border:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-interactive-bg-hover);width:100%;min-height:54px;max-height:120px;color:var(--dsw-alias-label-primary);resize:vertical;outline:none;padding:6px 8px;font-family:inherit;font-size:12px}.aeR_dq_commitTextarea:focus{border-color:var(--dsw-alias-state-business-primary)}.aeR_dq_commitButtonRow{justify-content:flex-end;align-items:center;gap:6px;display:flex}.aeR_dq_commitBtn{border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-label-primary-inverted);cursor:pointer;border:none;align-items:center;gap:4px;padding:4px 12px;font-size:12px;font-weight:600;transition:background .15s;display:inline-flex}.aeR_dq_commitBtn:hover{background:var(--dsw-alias-state-success-secondary)}.aeR_dq_commitPushBtn{border-radius:var(--dsw-radius-sm);border:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:4px;padding:4px 12px;font-size:12px;font-weight:500;transition:all .15s;display:inline-flex}.aeR_dq_commitPushBtn:hover{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}.aeR_dq_treeContainer{flex-direction:column;gap:0;min-height:0;display:flex;position:relative}.aeR_dq_treeRow{border-radius:var(--dsw-radius-sm);cursor:pointer;height:28px;color:var(--dsw-alias-label-primary);user-select:none;align-items:center;padding:0 6px;font-size:12px;transition:background .12s;display:flex}.aeR_dq_treeRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.aeR_dq_treeRowSelected{color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-interactive-bg-active)!important}.aeR_dq_graphSvg{flex-shrink:0;height:28px;margin-right:6px}.aeR_dq_graphOverlaySvg{pointer-events:none;z-index:1;position:absolute;top:0;left:10px}.aeR_dq_treeBody{flex:1;align-items:center;gap:6px;min-width:0;display:flex}.aeR_dq_refBadge{white-space:nowrap;border-radius:10px;flex-shrink:0;align-items:center;padding:1px 5px;font-size:10px;font-weight:700;line-height:12px;display:inline-flex}.aeR_dq_refHead{background:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 18%, transparent);color:var(--dsw-alias-state-warn-primary);border:.5px solid var(--dsw-alias-state-warn-primary)}.aeR_dq_refBranch{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 18%, transparent);color:var(--dsw-alias-state-success-primary);border:.5px solid var(--dsw-alias-state-success-primary)}.aeR_dq_refRemote{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 18%, transparent);color:var(--dsw-alias-state-business-primary);border:.5px solid var(--dsw-alias-state-business-primary)}.aeR_dq_treeSubject{text-overflow:ellipsis;white-space:nowrap;flex:1;font-weight:500;overflow:hidden}.aeR_dq_treeAuthor{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;flex-shrink:0;max-width:80px;font-size:11px;overflow:hidden}.aeR_dq_treeTime{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex-shrink:0;font-size:11px}.aeR_dq_treeHash{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover);border-radius:var(--dsw-radius-xs,3px);flex-shrink:0;padding:0 4px;font-family:monospace;font-size:11px}.aeR_dq_commitDetailPanel{border-radius:var(--dsw-radius-lg);border:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-specific-menu);backdrop-filter:var(--dsw-menu-backdrop-filter);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);flex-direction:column;gap:8px;margin-top:8px;padding:12px;display:flex}.aeR_dq_detailHeader{border-bottom:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:4px;padding-bottom:8px;display:flex}.aeR_dq_detailSubject{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.aeR_dq_detailMetaRow{color:var(--dsw-alias-label-tertiary);justify-content:space-between;align-items:center;font-size:11px;display:flex}.aeR_dq_detailFilesList{flex-direction:column;gap:2px;max-height:180px;display:flex;overflow-y:auto}.aeR_dq_detailFileItem{border-radius:var(--dsw-radius-sm);cursor:pointer;color:var(--dsw-alias-label-primary);justify-content:space-between;align-items:center;padding:4px 6px;font-size:11px;transition:background .12s;display:flex}.aeR_dq_detailFileItem:hover{background:var(--dsw-alias-interactive-bg-hover)}.aeR_dq_numstat{gap:4px;font-family:monospace;font-size:10px;display:inline-flex}.aeR_dq_addStat{color:var(--dsw-alias-state-success-primary)}.aeR_dq_delStat{color:var(--dsw-alias-state-error-primary)}.aeR_dq_diffViewer{border-radius:var(--dsw-radius-md);background:var(--dsw-alias-markdown-code-block);border:.5px solid var(--dsw-alias-border-l2);max-height:260px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:6px;padding:8px;font-family:monospace;font-size:11px;display:flex;overflow:auto}.aeR_dq_diffLine{white-space:pre-wrap;word-break:break-all;line-height:16px}.aeR_dq_diffAdd{background:var(--dsw-alias-code-diff-added);color:var(--dsw-alias-state-success-primary)}.aeR_dq_diffDel{background:var(--dsw-alias-code-diff-deleted);color:var(--dsw-alias-state-error-primary)}.aeR_dq_diffHunk{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);color:var(--dsw-alias-state-business-primary);font-weight:600}.aeR_dq_refTag{color:#f0883e;background:#f0883e2e;border:.5px solid #f0883e}.aeR_dq_treeRowHighlighted{border-left:2px solid var(--dsw-alias-state-business-primary);animation:2.5s ease-out forwards aeR_dq_rowGlow}@keyframes aeR_dq_rowGlow{0%{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 35%, transparent);box-shadow:inset 0 0 12px color-mix(in srgb, var(--dsw-alias-state-business-primary) 40%, transparent)}40%{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 25%, transparent);box-shadow:inset 0 0 8px color-mix(in srgb, var(--dsw-alias-state-business-primary) 20%, transparent)}to{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);box-shadow:none}}.aeR_dq_locateGlowRing{transform-origin:50%;stroke:var(--dsw-alias-state-business-primary);stroke-width:2px;fill:none;animation:1.5s ease-in-out infinite aeR_dq_pulseRing}@keyframes aeR_dq_pulseRing{0%{r:6;opacity:1}50%{r:10;opacity:.4}to{r:12;opacity:0}}.aeR_dq_treeRowActions{opacity:0;align-items:center;gap:2px;margin-left:4px;transition:opacity .12s;display:flex}.aeR_dq_treeRow:hover .aeR_dq_treeRowActions{opacity:1}.aeR_dq_treeActionBtn{border-radius:var(--dsw-radius-xs,3px);background:var(--dsw-alias-interactive-bg-hover);height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer;border:none;justify-content:center;align-items:center;padding:1px 4px;font-size:10px;transition:background .12s,color .12s;display:inline-flex}.aeR_dq_treeActionBtn:hover{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}.aeR_dq_tagList{flex-direction:column;gap:6px;display:flex}.aeR_dq_tagCard{border-radius:var(--dsw-radius-md);border:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-interactive-bg-hover);flex-direction:column;gap:6px;padding:10px 12px;transition:border-color .15s,background .15s;display:flex}.aeR_dq_tagCard:hover{border-color:var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-active)}.aeR_dq_tagCardHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.aeR_dq_tagTitleRow{flex:1;align-items:center;gap:8px;min-width:0;display:flex}.aeR_dq_tagName{color:var(--dsw-alias-state-business-primary);cursor:pointer;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;overflow:hidden}.aeR_dq_tagName:hover{text-decoration:underline}.aeR_dq_tagShaPill{border-radius:var(--dsw-radius-xs,3px);background:color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);color:var(--dsw-alias-label-secondary);cursor:pointer;padding:1px 6px;font-family:monospace;font-size:11px}.aeR_dq_tagShaPill:hover{background:color-mix(in srgb, var(--dsw-alias-label-primary) 15%, transparent);color:var(--dsw-alias-label-primary)}.aeR_dq_tagAnnotatedBadge{color:#f0883e;background:#f0883e2e;border:.5px solid #f0883e;border-radius:8px;padding:1px 5px;font-size:10px;font-weight:600}.aeR_dq_tagActions{flex-shrink:0;align-items:center;gap:4px;display:flex}.aeR_dq_tagLocateBtn{border:.5px solid color-mix(in srgb, var(--dsw-alias-state-business-primary) 40%, transparent);border-radius:var(--dsw-radius-sm);background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);color:var(--dsw-alias-state-business-primary);cursor:pointer;align-items:center;gap:4px;padding:3px 8px;font-size:11px;font-weight:600;transition:all .15s;display:inline-flex}.aeR_dq_tagLocateBtn:hover{background:var(--dsw-alias-state-business-primary);color:#fff}.aeR_dq_tagMessage{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.aeR_dq_tagMetaFooter{color:var(--dsw-alias-label-tertiary);justify-content:space-between;align-items:center;margin-top:2px;font-size:11px;display:flex}.aeR_dq_tagAuthor{color:var(--dsw-alias-label-secondary);align-items:center;gap:4px;display:inline-flex}.aeR_dq_tagForm{border-radius:var(--dsw-radius-md);border:.5px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-hover);flex-direction:column;gap:8px;padding:12px;display:flex}.aeR_dq_tagFormTitle{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:600}.aeR_dq_tagFormActions{justify-content:flex-end;gap:6px;display:flex}.aeR_dq_treeFilterRow{border-bottom:.5px solid var(--dsw-alias-border-l2);background:0 0;flex-shrink:0;justify-content:space-between;align-items:center;gap:8px;padding:6px 12px;display:flex}.aeR_dq_treeSearchInput{border-radius:var(--dsw-radius-sm);border:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-interactive-bg-hover);min-width:0;height:26px;color:var(--dsw-alias-label-primary);outline:none;flex:1;padding:0 8px;font-size:11px;transition:border-color .15s}.aeR_dq_treeSearchInput:focus{border-color:var(--dsw-alias-state-business-primary)}.aeR_dq_mainlineToggleGroup{border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-interactive-bg-hover);border:.5px solid var(--dsw-alias-border-l2);flex-shrink:0;align-items:center;padding:1px;display:inline-flex}.aeR_dq_mainlineToggleBtn{border-radius:var(--dsw-radius-xs,3px);color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;padding:2px 8px;font-size:11px;font-weight:500;transition:all .12s}.aeR_dq_mainlineToggleBtnActive{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary);font-weight:600}.aeR_dq_workstationLayout{flex:auto;min-height:0;display:flex;overflow:hidden;container-type:inline-size}.aeR_dq_tablePane{flex-direction:column;flex:auto;min-width:0;min-height:0;display:flex;overflow-y:auto}.aeR_dq_treeTableHeader{grid-template-columns:var(--git-graph-col-width,48px) minmax(200px, 1fr) 115px 90px 72px;border-bottom:.5px solid var(--dsw-alias-border-l2);background:color-mix(in srgb, var(--dsw-alias-label-primary) 3%, transparent);height:28px;color:var(--dsw-alias-label-tertiary);user-select:none;z-index:2;align-items:center;gap:8px;padding:0 10px;font-size:11px;font-weight:600;display:grid;position:sticky;top:0}.aeR_dq_colHeaderTitle{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.aeR_dq_treeRowGrid{box-sizing:border-box;grid-template-columns:var(--git-graph-col-width,48px) minmax(200px, 1fr) 115px 90px 72px;border-bottom:.5px solid color-mix(in srgb, var(--dsw-alias-border-l2) 40%, transparent);height:28px;min-height:28px;max-height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;user-select:none;align-items:center;gap:8px;padding:0 10px;font-size:12px;transition:background .1s;display:grid}.aeR_dq_treeRowGrid:hover{background:var(--dsw-alias-interactive-bg-hover)}.aeR_dq_treeRowGridSelected{color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-interactive-bg-active)!important}.aeR_dq_subjectCol{align-items:center;gap:6px;min-width:0;display:flex;overflow:hidden}.aeR_dq_typeBadge{border-radius:var(--dsw-radius-xs,3px);text-transform:lowercase;flex-shrink:0;justify-content:center;align-items:center;height:16px;padding:0 5px;font-size:10px;font-weight:600;line-height:16px;display:inline-flex}.aeR_dq_typeFeat{color:#2ea043;background:#2ea04329;border:.5px solid #2ea04366}.aeR_dq_typeFix{color:#f85149;background:#f8514929;border:.5px solid #f8514966}.aeR_dq_typeStyle,.aeR_dq_typeRefactor{color:#8250df;background:#8250df29;border:.5px solid #8250df66}.aeR_dq_typeRelease{color:#388bfd;background:#388bfd29;border:.5px solid #388bfd66}.aeR_dq_typeMerge{color:#6f42c1;background:#6f42c129;border:.5px solid #6f42c166}.aeR_dq_typeTest{color:#d29922;background:#d2992229;border:.5px solid #d2992266}.aeR_dq_typeDocs{color:#39c5bb;background:#39c5bb29;border:.5px solid #39c5bb66}.aeR_dq_typeChore,.aeR_dq_typeRevert{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 14%, transparent);color:var(--dsw-alias-label-secondary);border:.5px solid color-mix(in srgb, var(--dsw-alias-label-secondary) 30%, transparent)}.aeR_dq_authorCol{align-items:center;gap:6px;min-width:0;display:flex;overflow:hidden}.aeR_dq_authorAvatar{color:#fff;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:16px;height:16px;font-size:9px;font-weight:700;display:inline-flex}.aeR_dq_authorNameText{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.aeR_dq_timeCol{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.aeR_dq_shaCol{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-family:monospace;font-size:11px}.aeR_dq_detailsPane{border-left:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-specific-menu);width:330px;backdrop-filter:var(--dsw-menu-backdrop-filter);box-sizing:border-box;flex-direction:column;flex-shrink:0;display:flex;overflow-y:auto}.aeR_dq_detailsHeader{border-bottom:.5px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);letter-spacing:.5px;justify-content:space-between;align-items:center;padding:10px 12px;font-size:11px;font-weight:700;display:flex}.aeR_dq_detailsContent{flex-direction:column;gap:12px;padding:12px;display:flex}.aeR_dq_detailsSubject{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:18px}.aeR_dq_detailsBody{color:var(--dsw-alias-label-secondary);white-space:pre-wrap;word-break:break-word;font-size:11px;line-height:16px}.aeR_dq_detailsSectionTitle{color:var(--dsw-alias-label-tertiary);letter-spacing:.5px;margin-bottom:4px;font-size:10px;font-weight:700}.aeR_dq_detailsMetaGrid{flex-direction:column;gap:6px;font-size:11px;display:flex}.aeR_dq_detailsMetaRow{justify-content:space-between;align-items:center;gap:8px;display:flex}.aeR_dq_detailsMetaLabel{color:var(--dsw-alias-label-tertiary);flex-shrink:0}.aeR_dq_detailsMetaVal{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-family:monospace;overflow:hidden}.aeR_dq_detailsParentLink{color:var(--dsw-alias-state-business-primary);cursor:pointer;font-family:monospace}.aeR_dq_detailsParentLink:hover{text-decoration:underline}.aeR_dq_detailsBottomActions{gap:8px;margin-top:8px;display:flex}.aeR_dq_treeStatusFooter{border-top:.5px solid var(--dsw-alias-border-l2);background:color-mix(in srgb, var(--dsw-alias-label-primary) 2%, transparent);height:26px;color:var(--dsw-alias-label-tertiary);user-select:none;flex-shrink:0;justify-content:space-between;align-items:center;padding:0 10px;font-size:11px;display:flex}.aeR_dq_footerSyncStatus{align-items:center;gap:6px;display:flex}.aeR_dq_syncDot{background:var(--dsw-alias-state-success-primary);border-radius:50%;width:6px;height:6px}.aeR_dq_footerStats{align-items:center;gap:8px;display:flex}.aeR_dq_loadMoreLink{color:var(--dsw-alias-state-business-primary);cursor:pointer;font-weight:500}.aeR_dq_loadMoreLink:hover{text-decoration:underline}@container (width<=680px){.aeR_dq_workstationLayout{flex-direction:column}.aeR_dq_tablePane{flex:auto;min-height:160px}.aeR_dq_detailsPane{border-top:.5px solid var(--dsw-alias-border-l2);flex-shrink:0;max-height:340px;border-left:none!important;width:100%!important}}";
337
+ const css$1 = ".aeR_dq_root{height:100%;min-height:0;color:var(--dsw-alias-label-primary);font-size:var(--dsh-content-font-size-secondary,13px);user-select:none;background:0 0;flex-direction:column;flex:auto;line-height:1.5;display:flex}.aeR_dq_header{box-sizing:border-box;border-bottom:.5px solid var(--dsw-alias-border-l2);flex:none;justify-content:space-between;align-items:center;gap:8px;height:38px;padding:0 10px 0 12px;display:flex}.aeR_dq_branchInfo{align-items:center;gap:6px;min-width:0;display:flex}.aeR_dq_branchBadge{border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:4px;max-width:160px;padding:2px 7px;font-size:12px;font-weight:500;display:inline-flex;overflow:hidden}.aeR_dq_branchIcon{color:var(--dsw-alias-state-business-primary);flex-shrink:0}.aeR_dq_statusAheadBehind{gap:4px;font-size:11px;font-weight:600;display:inline-flex}.aeR_dq_aheadText{color:var(--dsw-alias-state-business-primary)}.aeR_dq_behindText{color:var(--dsw-alias-state-warn-primary)}.aeR_dq_headerActions{align-items:center;gap:4px;display:flex}.aeR_dq_iconButton{border-radius:var(--dsw-radius-sm);width:26px;height:26px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;padding:0;transition:background-color .15s,color .15s;display:inline-flex}.aeR_dq_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.aeR_dq_iconButton.aeR_dq_spinning svg{animation:.8s linear infinite aeR_dq_spin}@keyframes aeR_dq_spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.aeR_dq_tabs{border-bottom:.5px solid var(--dsw-alias-border-l2);background:0 0;align-items:center;gap:4px;padding:4px 10px;display:flex}.aeR_dq_tab{border-radius:var(--dsw-radius-sm);color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;align-items:center;gap:5px;padding:4px 10px;font-size:12px;font-weight:500;transition:all .15s;display:inline-flex}.aeR_dq_tab:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.aeR_dq_tabActive{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-state-business-primary);font-weight:600}.aeR_dq_tabCount{background:var(--dsw-alias-interactive-bg-hover);color:inherit;border-radius:10px;justify-content:center;align-items:center;padding:0 5px;font-size:10px;font-weight:700;display:inline-flex}.aeR_dq_content{flex-direction:column;flex:auto;gap:10px;min-height:0;padding:8px 10px;display:flex;overflow-y:auto}.aeR_dq_emptyState{text-align:center;color:var(--dsw-alias-label-tertiary);flex-direction:column;justify-content:center;align-items:center;gap:8px;padding:32px 16px;display:flex}.aeR_dq_emptyState svg{opacity:.6;width:28px;height:28px}.aeR_dq_section{border-radius:var(--dsw-radius-md);border:.5px solid var(--dsw-alias-border-l2);background:0 0;flex-direction:column;display:flex;overflow:hidden}.aeR_dq_sectionHeader{border-bottom:.5px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-hover);cursor:pointer;color:var(--dsw-alias-label-primary);justify-content:space-between;align-items:center;padding:6px 10px;font-size:12px;font-weight:600;display:flex}.aeR_dq_sectionTitle{align-items:center;gap:6px;display:flex}.aeR_dq_sectionActions{align-items:center;gap:4px;display:flex}.aeR_dq_actionTextBtn{border-radius:var(--dsw-radius-xs,3px);border:.5px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;padding:2px 6px;font-size:11px;transition:all .12s}.aeR_dq_actionTextBtn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.aeR_dq_fileList{flex-direction:column;display:flex}.aeR_dq_fileItem{border-top:.5px solid var(--dsw-alias-border-l1);cursor:pointer;color:var(--dsw-alias-label-primary);justify-content:space-between;align-items:center;padding:5px 10px;font-size:12px;transition:background .12s;display:flex}.aeR_dq_fileItem:hover{background:var(--dsw-alias-interactive-bg-hover)}.aeR_dq_fileLeft{flex:1;align-items:center;gap:6px;min-width:0;display:flex}.aeR_dq_statusBadge{border-radius:3px;flex-shrink:0;justify-content:center;align-items:center;width:16px;height:16px;font-size:10px;font-weight:700;display:inline-flex}.aeR_dq_statusM{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 15%, transparent);color:var(--dsw-alias-state-business-primary)}.aeR_dq_statusA{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent);color:var(--dsw-alias-state-success-primary)}.aeR_dq_statusD{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent);color:var(--dsw-alias-state-error-primary)}.aeR_dq_statusU{background:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 15%, transparent);color:var(--dsw-alias-state-warn-primary)}.aeR_dq_fileName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.aeR_dq_fileDir{color:var(--dsw-alias-label-tertiary);font-size:11px}.aeR_dq_fileItemActions{opacity:0;align-items:center;gap:4px;transition:opacity .12s;display:flex}.aeR_dq_fileItem:hover .aeR_dq_fileItemActions{opacity:1}.aeR_dq_fileMiniBtn{border-radius:var(--dsw-radius-xs,3px);background:var(--dsw-alias-interactive-bg-hover);width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;border:none;justify-content:center;align-items:center;font-size:12px;transition:background .12s,color .12s;display:inline-flex}.aeR_dq_fileMiniBtn:hover{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}.aeR_dq_commitBox{border-radius:var(--dsw-radius-md);border:.5px solid var(--dsw-alias-border-l2);background:0 0;flex-direction:column;gap:8px;margin-top:4px;padding:10px;display:flex}.aeR_dq_commitTextarea{box-sizing:border-box;border-radius:var(--dsw-radius-sm);border:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-interactive-bg-hover);width:100%;min-height:54px;max-height:120px;color:var(--dsw-alias-label-primary);resize:vertical;outline:none;padding:6px 8px;font-family:inherit;font-size:12px}.aeR_dq_commitTextarea:focus{border-color:var(--dsw-alias-state-business-primary)}.aeR_dq_commitButtonRow{justify-content:flex-end;align-items:center;gap:6px;display:flex}.aeR_dq_commitBtn{border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-label-primary-inverted);cursor:pointer;border:none;align-items:center;gap:4px;padding:4px 12px;font-size:12px;font-weight:600;transition:background .15s;display:inline-flex}.aeR_dq_commitBtn:hover{background:var(--dsw-alias-state-success-secondary)}.aeR_dq_commitPushBtn{border-radius:var(--dsw-radius-sm);border:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:4px;padding:4px 12px;font-size:12px;font-weight:500;transition:all .15s;display:inline-flex}.aeR_dq_commitPushBtn:hover{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}.aeR_dq_treeContainer{flex-direction:column;gap:0;min-height:0;display:flex;position:relative}.aeR_dq_treeRow{border-radius:var(--dsw-radius-sm);cursor:pointer;height:28px;color:var(--dsw-alias-label-primary);user-select:none;align-items:center;padding:0 6px;font-size:12px;transition:background .12s;display:flex}.aeR_dq_treeRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.aeR_dq_treeRowSelected{color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-interactive-bg-active)!important}.aeR_dq_graphSvg{flex-shrink:0;height:28px;margin-right:6px}.aeR_dq_graphOverlaySvg{pointer-events:none;z-index:1;position:absolute;top:0;left:10px}.aeR_dq_treeBody{flex:1;align-items:center;gap:6px;min-width:0;display:flex}.aeR_dq_refBadge{white-space:nowrap;border-radius:10px;flex-shrink:0;align-items:center;padding:1px 5px;font-size:10px;font-weight:700;line-height:12px;display:inline-flex}.aeR_dq_refHead{background:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 18%, transparent);color:var(--dsw-alias-state-warn-primary);border:.5px solid var(--dsw-alias-state-warn-primary)}.aeR_dq_refBranch{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 18%, transparent);color:var(--dsw-alias-state-success-primary);border:.5px solid var(--dsw-alias-state-success-primary)}.aeR_dq_refRemote{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 18%, transparent);color:var(--dsw-alias-state-business-primary);border:.5px solid var(--dsw-alias-state-business-primary)}.aeR_dq_treeSubject{text-overflow:ellipsis;white-space:nowrap;flex:1;font-weight:500;overflow:hidden}.aeR_dq_treeAuthor{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;flex-shrink:0;max-width:80px;font-size:11px;overflow:hidden}.aeR_dq_treeTime{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex-shrink:0;font-size:11px}.aeR_dq_treeHash{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover);border-radius:var(--dsw-radius-xs,3px);flex-shrink:0;padding:0 4px;font-family:monospace;font-size:11px}.aeR_dq_commitDetailPanel{border-radius:var(--dsw-radius-lg);border:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-specific-menu);backdrop-filter:var(--dsw-menu-backdrop-filter);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);flex-direction:column;gap:8px;margin-top:8px;padding:12px;display:flex}.aeR_dq_detailHeader{border-bottom:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:4px;padding-bottom:8px;display:flex}.aeR_dq_detailSubject{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.aeR_dq_detailMetaRow{color:var(--dsw-alias-label-tertiary);justify-content:space-between;align-items:center;font-size:11px;display:flex}.aeR_dq_detailFilesList{flex-direction:column;gap:2px;max-height:180px;display:flex;overflow-y:auto}.aeR_dq_detailFileItem{border-radius:var(--dsw-radius-sm);cursor:pointer;color:var(--dsw-alias-label-primary);justify-content:space-between;align-items:center;padding:4px 6px;font-size:11px;transition:background .12s;display:flex}.aeR_dq_detailFileItem:hover{background:var(--dsw-alias-interactive-bg-hover)}.aeR_dq_numstat{gap:4px;font-family:monospace;font-size:10px;display:inline-flex}.aeR_dq_addStat{color:var(--dsw-alias-state-success-primary)}.aeR_dq_delStat{color:var(--dsw-alias-state-error-primary)}.aeR_dq_diffViewer{border-radius:var(--dsw-radius-md);background:var(--dsw-alias-markdown-code-block);border:.5px solid var(--dsw-alias-border-l2);max-height:260px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:6px;padding:8px;font-family:monospace;font-size:11px;display:flex;overflow:auto}.aeR_dq_diffLine{white-space:pre-wrap;word-break:break-all;line-height:16px}.aeR_dq_diffAdd{background:var(--dsw-alias-code-diff-added);color:var(--dsw-alias-state-success-primary)}.aeR_dq_diffDel{background:var(--dsw-alias-code-diff-deleted);color:var(--dsw-alias-state-error-primary)}.aeR_dq_diffHunk{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);color:var(--dsw-alias-state-business-primary);font-weight:600}.aeR_dq_refTag{color:#f0883e;background:#f0883e2e;border:.5px solid #f0883e}.aeR_dq_treeRowHighlighted{border-left:2px solid var(--dsw-alias-state-business-primary);animation:2.5s ease-out forwards aeR_dq_rowGlow}@keyframes aeR_dq_rowGlow{0%{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 35%, transparent);box-shadow:inset 0 0 12px color-mix(in srgb, var(--dsw-alias-state-business-primary) 40%, transparent)}40%{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 25%, transparent);box-shadow:inset 0 0 8px color-mix(in srgb, var(--dsw-alias-state-business-primary) 20%, transparent)}to{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);box-shadow:none}}.aeR_dq_locateGlowRing{transform-origin:50%;stroke:var(--dsw-alias-state-business-primary);stroke-width:2px;fill:none;animation:1.5s ease-in-out infinite aeR_dq_pulseRing}@keyframes aeR_dq_pulseRing{0%{r:6;opacity:1}50%{r:10;opacity:.4}to{r:12;opacity:0}}.aeR_dq_treeRowActions{opacity:0;align-items:center;gap:2px;margin-left:4px;transition:opacity .12s;display:flex}.aeR_dq_treeRow:hover .aeR_dq_treeRowActions{opacity:1}.aeR_dq_treeActionBtn{border-radius:var(--dsw-radius-xs,3px);background:var(--dsw-alias-interactive-bg-hover);height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer;border:none;justify-content:center;align-items:center;padding:1px 4px;font-size:10px;transition:background .12s,color .12s;display:inline-flex}.aeR_dq_treeActionBtn:hover{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}.aeR_dq_tagList{flex-direction:column;gap:6px;display:flex}.aeR_dq_tagCard{border-radius:var(--dsw-radius-md);border:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-interactive-bg-hover);flex-direction:column;gap:6px;padding:10px 12px;transition:border-color .15s,background .15s;display:flex}.aeR_dq_tagCard:hover{border-color:var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-active)}.aeR_dq_tagCardHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.aeR_dq_tagTitleRow{flex:1;align-items:center;gap:8px;min-width:0;display:flex}.aeR_dq_tagName{color:var(--dsw-alias-state-business-primary);cursor:pointer;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;overflow:hidden}.aeR_dq_tagName:hover{text-decoration:underline}.aeR_dq_tagShaPill{border-radius:var(--dsw-radius-xs,3px);background:color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);color:var(--dsw-alias-label-secondary);cursor:pointer;padding:1px 6px;font-family:monospace;font-size:11px}.aeR_dq_tagShaPill:hover{background:color-mix(in srgb, var(--dsw-alias-label-primary) 15%, transparent);color:var(--dsw-alias-label-primary)}.aeR_dq_tagAnnotatedBadge{color:#f0883e;background:#f0883e2e;border:.5px solid #f0883e;border-radius:8px;padding:1px 5px;font-size:10px;font-weight:600}.aeR_dq_tagActions{flex-shrink:0;align-items:center;gap:4px;display:flex}.aeR_dq_tagLocateBtn{border:.5px solid color-mix(in srgb, var(--dsw-alias-state-business-primary) 40%, transparent);border-radius:var(--dsw-radius-sm);background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);color:var(--dsw-alias-state-business-primary);cursor:pointer;align-items:center;gap:4px;padding:3px 8px;font-size:11px;font-weight:600;transition:all .15s;display:inline-flex}.aeR_dq_tagLocateBtn:hover{background:var(--dsw-alias-state-business-primary);color:#fff}.aeR_dq_tagMessage{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.aeR_dq_tagMetaFooter{color:var(--dsw-alias-label-tertiary);justify-content:space-between;align-items:center;margin-top:2px;font-size:11px;display:flex}.aeR_dq_tagAuthor{color:var(--dsw-alias-label-secondary);align-items:center;gap:4px;display:inline-flex}.aeR_dq_tagForm{border-radius:var(--dsw-radius-md);border:.5px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-hover);flex-direction:column;gap:8px;padding:12px;display:flex}.aeR_dq_tagFormTitle{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:600}.aeR_dq_tagFormActions{justify-content:flex-end;gap:6px;display:flex}.aeR_dq_treeFilterRow{border-bottom:.5px solid var(--dsw-alias-border-l2);background:0 0;flex-shrink:0;justify-content:space-between;align-items:center;gap:8px;padding:6px 12px;display:flex}.aeR_dq_treeSearchInput{border-radius:var(--dsw-radius-sm);border:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-interactive-bg-hover);min-width:0;height:26px;color:var(--dsw-alias-label-primary);outline:none;flex:1;padding:0 8px;font-size:11px;transition:border-color .15s}.aeR_dq_treeSearchInput:focus{border-color:var(--dsw-alias-state-business-primary)}.aeR_dq_mainlineToggleGroup{border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-interactive-bg-hover);border:.5px solid var(--dsw-alias-border-l2);flex-shrink:0;align-items:center;padding:1px;display:inline-flex}.aeR_dq_mainlineToggleBtn{border-radius:var(--dsw-radius-xs,3px);color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;padding:2px 8px;font-size:11px;font-weight:500;transition:all .12s}.aeR_dq_mainlineToggleBtnActive{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary);font-weight:600}.aeR_dq_workstationLayout{flex:auto;min-height:0;display:flex;overflow:hidden;container-type:inline-size}.aeR_dq_tablePane{flex-direction:column;flex:auto;min-width:0;min-height:0;display:flex;overflow-y:auto}.aeR_dq_treeTableHeader{grid-template-columns:var(--git-graph-col-width,48px) minmax(200px, 1fr) 115px 90px 72px;border-bottom:.5px solid var(--dsw-alias-border-l2);background:color-mix(in srgb, var(--dsw-alias-label-primary) 3%, transparent);height:28px;color:var(--dsw-alias-label-tertiary);user-select:none;z-index:2;align-items:center;gap:8px;padding:0 10px;font-size:11px;font-weight:600;display:grid;position:sticky;top:0}.aeR_dq_colHeaderTitle{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.aeR_dq_treeRowGrid{box-sizing:border-box;grid-template-columns:var(--git-graph-col-width,48px) minmax(200px, 1fr) 115px 90px 72px;border-bottom:.5px solid color-mix(in srgb, var(--dsw-alias-border-l2) 40%, transparent);height:28px;min-height:28px;max-height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;user-select:none;align-items:center;gap:8px;padding:0 10px;font-size:12px;transition:background .1s;display:grid}.aeR_dq_treeRowGrid:hover{background:var(--dsw-alias-interactive-bg-hover)}.aeR_dq_treeRowGridSelected{color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-interactive-bg-active)!important}.aeR_dq_subjectCol{align-items:center;gap:6px;min-width:0;display:flex;overflow:hidden}.aeR_dq_typeBadge{border-radius:var(--dsw-radius-xs,3px);text-transform:lowercase;flex-shrink:0;justify-content:center;align-items:center;height:16px;padding:0 5px;font-size:10px;font-weight:600;line-height:16px;display:inline-flex}.aeR_dq_typeFeat{color:#2ea043;background:#2ea04329;border:.5px solid #2ea04366}.aeR_dq_typeFix{color:#f85149;background:#f8514929;border:.5px solid #f8514966}.aeR_dq_typeStyle,.aeR_dq_typeRefactor{color:#8250df;background:#8250df29;border:.5px solid #8250df66}.aeR_dq_typeRelease{color:#388bfd;background:#388bfd29;border:.5px solid #388bfd66}.aeR_dq_typeMerge{color:#6f42c1;background:#6f42c129;border:.5px solid #6f42c166}.aeR_dq_typeTest{color:#d29922;background:#d2992229;border:.5px solid #d2992266}.aeR_dq_typeDocs{color:#39c5bb;background:#39c5bb29;border:.5px solid #39c5bb66}.aeR_dq_typeChore,.aeR_dq_typeRevert{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 14%, transparent);color:var(--dsw-alias-label-secondary);border:.5px solid color-mix(in srgb, var(--dsw-alias-label-secondary) 30%, transparent)}.aeR_dq_authorCol{align-items:center;gap:6px;min-width:0;display:flex;overflow:hidden}.aeR_dq_authorAvatar{color:#fff;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:16px;height:16px;font-size:9px;font-weight:700;display:inline-flex}.aeR_dq_authorNameText{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.aeR_dq_timeCol{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.aeR_dq_shaCol{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-family:monospace;font-size:11px}.aeR_dq_detailsPane{border-left:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-specific-menu);width:330px;backdrop-filter:var(--dsw-menu-backdrop-filter);box-sizing:border-box;flex-direction:column;flex-shrink:0;display:flex;overflow-y:auto}.aeR_dq_detailsHeader{border-bottom:.5px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);letter-spacing:.5px;justify-content:space-between;align-items:center;padding:10px 12px;font-size:11px;font-weight:700;display:flex}.aeR_dq_detailsContent{flex-direction:column;gap:12px;padding:12px;display:flex}.aeR_dq_detailsSubject{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:18px}.aeR_dq_detailsBody{color:var(--dsw-alias-label-secondary);white-space:pre-wrap;word-break:break-word;font-size:11px;line-height:16px}.aeR_dq_detailsSectionTitle{color:var(--dsw-alias-label-tertiary);letter-spacing:.5px;margin-bottom:4px;font-size:10px;font-weight:700}.aeR_dq_detailsMetaGrid{flex-direction:column;gap:6px;font-size:11px;display:flex}.aeR_dq_detailsMetaRow{justify-content:space-between;align-items:center;gap:8px;display:flex}.aeR_dq_detailsMetaLabel{color:var(--dsw-alias-label-tertiary);flex-shrink:0}.aeR_dq_detailsMetaVal{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-family:monospace;overflow:hidden}.aeR_dq_detailsParentLink{color:var(--dsw-alias-state-business-primary);cursor:pointer;font-family:monospace}.aeR_dq_detailsParentLink:hover{text-decoration:underline}.aeR_dq_detailsBottomActions{gap:8px;margin-top:8px;display:flex}.aeR_dq_treeStatusFooter{border-top:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2,#f5f5f5);height:26px;color:var(--dsw-alias-label-tertiary);user-select:none;flex-shrink:0;justify-content:space-between;align-items:center;padding:0 10px;font-size:11px;display:flex}.aeR_dq_footerSyncStatus{align-items:center;gap:6px;display:flex}.aeR_dq_syncDot{background:var(--dsw-alias-state-success-primary);border-radius:50%;width:6px;height:6px}.aeR_dq_footerStats{align-items:center;gap:8px;display:flex}.aeR_dq_loadMoreLink{color:var(--dsw-alias-state-business-primary);cursor:pointer;font-weight:500}.aeR_dq_loadMoreLink:hover{text-decoration:underline}@container (width<=680px){.aeR_dq_workstationLayout{flex-direction:column}.aeR_dq_tablePane{flex:auto;min-height:160px}.aeR_dq_detailsPane{border-top:.5px solid var(--dsw-alias-border-l2);flex-shrink:0;max-height:340px;border-left:none!important;width:100%!important}}";
338
338
  const tagId$1 = "@civilization/dsh-git-workbench/GitBody.module.css";
339
339
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
340
340
  const tag = document.createElement("style");
@@ -2057,7 +2057,7 @@ window.__ModuleLoader__.load({
2057
2057
  });
2058
2058
  });
2059
2059
  // \0dsh-css:src/client/GitBranchPill.module.css.mjs
2060
- const css = ".J259IW_anchor{min-width:0;font-size:calc(var(--dsh-content-font-size-secondary,13px) - 1px);line-height:calc(20px + var(--dsh-content-font-delta-secondary,0px));display:inline-flex;position:relative}.J259IW_pill{box-sizing:border-box;border-radius:var(--dsw-radius-sm);max-width:100%;color:var(--dsw-alias-label-tertiary);font:inherit;font-variant-numeric:tabular-nums;font-weight:500;line-height:inherit;white-space:nowrap;cursor:pointer;background:0 0;border:none;align-items:center;gap:6px;padding:1px 8px;transition:background .15s,color .15s;display:inline-flex}.J259IW_pill:hover,.J259IW_pill[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.J259IW_icon{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none}.J259IW_pill:hover .J259IW_icon,.J259IW_pill[aria-expanded=true] .J259IW_icon{color:var(--dsw-alias-state-business-primary)}.J259IW_branchName{text-overflow:ellipsis;white-space:nowrap;max-width:150px;overflow:hidden}.J259IW_badge{border-radius:var(--dsw-radius-xs,3px);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);align-items:center;padding:0 4px;font-size:11px;font-weight:500;line-height:14px;display:inline-flex}.J259IW_badgeAhead{color:var(--dsw-alias-state-business-primary)}.J259IW_badgeBehind{color:var(--dsw-alias-state-warn-primary)}.J259IW_popover{z-index:1100;box-sizing:border-box;border-radius:var(--dsw-radius-lg);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);width:310px;max-height:440px;box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);cursor:default;border:0;flex-direction:column;font-size:12px;line-height:18px;animation:.15s cubic-bezier(.16,1,.3,1) J259IW_popoverFadeIn;display:flex;position:fixed;overflow:hidden}@keyframes J259IW_popoverFadeIn{0%{opacity:0;transform:translateY(4px)scale(.98)}to{opacity:1;transform:translateY(0)scale(1)}}.J259IW_header{border-bottom:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:6px;padding:8px 10px 6px;display:flex}.J259IW_searchRow{border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-interactive-bg-hover);border:.5px solid var(--dsw-alias-border-l2);align-items:center;gap:6px;padding:4px 8px;display:flex}.J259IW_searchIcon{width:13px;height:13px;color:var(--dsw-alias-label-tertiary);flex:none}.J259IW_searchInput{color:var(--dsw-alias-label-primary);background:0 0;border:none;outline:none;flex:1;font-size:12px}.J259IW_searchInput::placeholder{color:var(--dsw-alias-label-tertiary)}.J259IW_actionBar{justify-content:space-between;align-items:center;gap:4px;display:flex}.J259IW_toolBtnGroup{align-items:center;gap:4px;display:flex}.J259IW_toolBtn{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:4px;padding:3px 8px;font-family:inherit;font-size:11px;font-weight:500;transition:background .15s,color .15s;display:inline-flex}.J259IW_toolBtn:hover{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}.J259IW_btnIcon{flex:none;width:12px;height:12px}.J259IW_newBranchBox{gap:6px;margin-top:2px;display:flex}.J259IW_newBranchInput{border-radius:var(--dsw-radius-sm);border:.5px solid var(--dsw-alias-state-business-primary);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);outline:none;flex:1;padding:4px 8px;font-size:12px}.J259IW_newBranchInput::placeholder{color:var(--dsw-alias-label-tertiary)}.J259IW_branchList{flex:1;padding:4px;overflow-y:auto}.J259IW_groupLabel{color:var(--dsw-alias-label-tertiary);align-items:center;gap:6px;padding:6px 8px 3px;font-size:11px;font-weight:500;display:flex}.J259IW_branchItem{border-radius:var(--dsw-radius-sm);width:100%;color:var(--dsw-alias-label-secondary);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;justify-content:space-between;align-items:center;padding:5px 8px;font-size:12px;transition:background .12s,color .12s;display:flex}.J259IW_branchItem:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.J259IW_currentBranch{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-state-business-primary);font-weight:500}.J259IW_currentBranch:hover{background:var(--dsw-alias-interactive-bg-active)}.J259IW_branchItemLeft{flex:1;align-items:center;gap:6px;min-width:0;display:flex}.J259IW_itemIcon{width:13px;height:13px;color:var(--dsw-alias-label-tertiary);flex:none}.J259IW_currentBranch .J259IW_itemIcon{color:var(--dsw-alias-state-business-primary)}.J259IW_itemText{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.J259IW_checkMark{width:14px;height:14px;color:var(--dsw-alias-state-business-primary);flex:none}.J259IW_emptyTip{text-align:center;color:var(--dsw-alias-label-tertiary);padding:16px 8px;font-size:12px}";
2060
+ const css = ".J259IW_anchor{min-width:0;font-size:calc(var(--dsh-content-font-size-secondary,13px) - 1px);line-height:calc(20px + var(--dsh-content-font-delta-secondary,0px));display:inline-flex;position:relative}.J259IW_pill{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-bg-layer-1,#fff);max-width:100%;color:var(--dsw-alias-label-secondary);font:inherit;font-variant-numeric:tabular-nums;font-weight:500;line-height:inherit;white-space:nowrap;cursor:pointer;align-items:center;gap:6px;padding:1px 8px;transition:background .15s,border-color .15s,color .15s;display:inline-flex}.J259IW_pill:hover,.J259IW_pill[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary)}.J259IW_icon{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none}.J259IW_pill:hover .J259IW_icon,.J259IW_pill[aria-expanded=true] .J259IW_icon{color:var(--dsw-alias-state-business-primary)}.J259IW_branchName{text-overflow:ellipsis;white-space:nowrap;max-width:150px;overflow:hidden}.J259IW_badge{border-radius:var(--dsw-radius-xs,3px);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);align-items:center;padding:0 4px;font-size:11px;font-weight:500;line-height:14px;display:inline-flex}.J259IW_badgeAhead{color:var(--dsw-alias-state-business-primary)}.J259IW_badgeBehind{color:var(--dsw-alias-state-warn-primary)}.J259IW_popover{z-index:1100;box-sizing:border-box;background:var(--dsw-alias-bg-overlay,var(--dsw-alias-bg-layer-1,#fff));border:.5px solid var(--dsw-alias-border-l1);border-radius:var(--dsw-radius-lg);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);width:310px;max-height:440px;box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);cursor:default;flex-direction:column;font-size:12px;line-height:18px;animation:.15s cubic-bezier(.16,1,.3,1) J259IW_popoverFadeIn;display:flex;position:fixed;overflow:hidden}@keyframes J259IW_popoverFadeIn{0%{opacity:0;transform:translateY(4px)scale(.98)}to{opacity:1;transform:translateY(0)scale(1)}}.J259IW_header{border-bottom:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:6px;padding:8px 10px 6px;display:flex}.J259IW_searchRow{border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-interactive-bg-hover);border:.5px solid var(--dsw-alias-border-l2);align-items:center;gap:6px;padding:4px 8px;display:flex}.J259IW_searchIcon{width:13px;height:13px;color:var(--dsw-alias-label-tertiary);flex:none}.J259IW_searchInput{color:var(--dsw-alias-label-primary);background:0 0;border:none;outline:none;flex:1;font-size:12px}.J259IW_searchInput::placeholder{color:var(--dsw-alias-label-tertiary)}.J259IW_actionBar{justify-content:space-between;align-items:center;gap:4px;display:flex}.J259IW_toolBtnGroup{align-items:center;gap:4px;display:flex}.J259IW_toolBtn{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:4px;padding:3px 8px;font-family:inherit;font-size:11px;font-weight:500;transition:background .15s,color .15s;display:inline-flex}.J259IW_toolBtn:hover{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}.J259IW_btnIcon{flex:none;width:12px;height:12px}.J259IW_newBranchBox{gap:6px;margin-top:2px;display:flex}.J259IW_newBranchInput{border-radius:var(--dsw-radius-sm);border:.5px solid var(--dsw-alias-state-business-primary);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);outline:none;flex:1;padding:4px 8px;font-size:12px}.J259IW_newBranchInput::placeholder{color:var(--dsw-alias-label-tertiary)}.J259IW_branchList{flex:1;padding:4px;overflow-y:auto}.J259IW_groupLabel{color:var(--dsw-alias-label-tertiary);align-items:center;gap:6px;padding:6px 8px 3px;font-size:11px;font-weight:500;display:flex}.J259IW_branchItem{border-radius:var(--dsw-radius-sm);width:100%;color:var(--dsw-alias-label-secondary);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;justify-content:space-between;align-items:center;padding:5px 8px;font-size:12px;transition:background .12s,color .12s;display:flex}.J259IW_branchItem:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.J259IW_currentBranch{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-state-business-primary);font-weight:500}.J259IW_currentBranch:hover{background:var(--dsw-alias-interactive-bg-active)}.J259IW_branchItemLeft{flex:1;align-items:center;gap:6px;min-width:0;display:flex}.J259IW_itemIcon{width:13px;height:13px;color:var(--dsw-alias-label-tertiary);flex:none}.J259IW_currentBranch .J259IW_itemIcon{color:var(--dsw-alias-state-business-primary)}.J259IW_itemText{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.J259IW_checkMark{width:14px;height:14px;color:var(--dsw-alias-state-business-primary);flex:none}.J259IW_emptyTip{text-align:center;color:var(--dsw-alias-label-tertiary);padding:16px 8px;font-size:12px}";
2061
2061
  const tagId = "@civilization/dsh-git-workbench/GitBranchPill.module.css";
2062
2062
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
2063
2063
  const tag = document.createElement("style");
package/lib/index.js CHANGED
@@ -1157,118 +1157,215 @@ function registerGitTool(ctx, resolveDir) {
1157
1157
  /** Cordis plugin name */
1158
1158
  const name = "@civilization/dsh-git-workbench";
1159
1159
  /** Required host services */
1160
- const inject = ["connection", "webServer"];
1160
+ const inject = [
1161
+ "webServer",
1162
+ "sessions",
1163
+ "sandboxPolicy"
1164
+ ];
1161
1165
  /**
1162
- * Apply the Git host plugin.
1163
- * Sets up authenticated RPC handlers under `/git/*` and registers the model tool.
1164
- * @param ctx - Context carrying the connection and optional session services.
1166
+ * Execute Git operations based on requested endpoint and payload.
1165
1167
  */
1166
- function apply(ctx) {
1167
- const host = ctx;
1168
- const resolveTargetDir = (sessionId) => {
1169
- if (sessionId) {
1170
- const liveCwd = host.sessions?.get(sessionId)?.header?.cwd;
1171
- if (liveCwd) return liveCwd;
1172
- }
1173
- return host.sandboxPolicy?.workspaceRoot ?? process.cwd();
1174
- };
1175
- host.connection.rpc.handle("/git", async (endpoint, payload, _signal) => {
1168
+ async function executeGitEndpoint(endpoint, payload, resolveTargetDir) {
1169
+ try {
1176
1170
  const body = typeof payload === "object" && payload !== null ? payload : {};
1177
1171
  const sessionId = typeof body.sessionId === "string" ? body.sessionId : void 0;
1178
1172
  const cwd = typeof body.path === "string" ? body.path : resolveTargetDir(sessionId);
1179
- try {
1180
- if (endpoint === "status") return {
1181
- ok: true,
1182
- value: await getGitStatus(cwd)
1183
- };
1184
- if (endpoint === "log") return {
1185
- ok: true,
1186
- value: await getGitLog(cwd, typeof body.maxCount === "number" ? body.maxCount : 50)
1187
- };
1188
- if (endpoint === "commitDetails") return {
1173
+ if (endpoint === "status") return {
1174
+ ok: true,
1175
+ value: await getGitStatus(cwd)
1176
+ };
1177
+ if (endpoint === "log") return {
1178
+ ok: true,
1179
+ value: await getGitLog(cwd, typeof body.maxCount === "number" ? body.maxCount : 50)
1180
+ };
1181
+ if (endpoint === "commitDetails") return {
1182
+ ok: true,
1183
+ value: await getGitCommitDetails(cwd, typeof body.commit === "string" ? body.commit : "")
1184
+ };
1185
+ if (endpoint === "diff") {
1186
+ const path = typeof body.filePath === "string" ? body.filePath : void 0;
1187
+ const staged = typeof body.staged === "boolean" ? body.staged : false;
1188
+ const commit = typeof body.commit === "string" ? body.commit : void 0;
1189
+ return {
1189
1190
  ok: true,
1190
- value: await getGitCommitDetails(cwd, typeof body.commit === "string" ? body.commit : "")
1191
+ value: await getGitDiff(cwd, {
1192
+ ...path !== void 0 ? { path } : {},
1193
+ staged,
1194
+ ...commit !== void 0 ? { commit } : {}
1195
+ })
1191
1196
  };
1192
- if (endpoint === "diff") {
1193
- const path = typeof body.filePath === "string" ? body.filePath : void 0;
1194
- const staged = typeof body.staged === "boolean" ? body.staged : false;
1195
- const commit = typeof body.commit === "string" ? body.commit : void 0;
1196
- return {
1197
- ok: true,
1198
- value: await getGitDiff(cwd, {
1199
- ...path !== void 0 ? { path } : {},
1200
- staged,
1201
- ...commit !== void 0 ? { commit } : {}
1202
- })
1203
- };
1197
+ }
1198
+ if (endpoint === "branches") return {
1199
+ ok: true,
1200
+ value: await getGitAllBranches(cwd)
1201
+ };
1202
+ if (endpoint === "checkout") return {
1203
+ ok: true,
1204
+ value: await gitCheckout(cwd, typeof body.branch === "string" ? body.branch : "", typeof body.create === "boolean" ? body.create : false)
1205
+ };
1206
+ if (endpoint === "stage") return {
1207
+ ok: true,
1208
+ value: await gitStage(cwd, Array.isArray(body.paths) ? body.paths : body.paths === "all" ? "all" : typeof body.path === "string" ? [body.path] : "all")
1209
+ };
1210
+ if (endpoint === "unstage") return {
1211
+ ok: true,
1212
+ value: await gitUnstage(cwd, Array.isArray(body.paths) ? body.paths : body.paths === "all" ? "all" : typeof body.path === "string" ? [body.path] : "all")
1213
+ };
1214
+ if (endpoint === "discard") return {
1215
+ ok: true,
1216
+ value: await gitDiscard(cwd, Array.isArray(body.paths) ? body.paths : typeof body.path === "string" ? [body.path] : [])
1217
+ };
1218
+ if (endpoint === "commit") return {
1219
+ ok: true,
1220
+ value: await gitCommit(cwd, typeof body.message === "string" ? body.message : "")
1221
+ };
1222
+ if (endpoint === "fetch") return {
1223
+ ok: true,
1224
+ value: await gitFetch(cwd)
1225
+ };
1226
+ if (endpoint === "pull") return {
1227
+ ok: true,
1228
+ value: await gitPull(cwd)
1229
+ };
1230
+ if (endpoint === "push") return {
1231
+ ok: true,
1232
+ value: await gitPush(cwd)
1233
+ };
1234
+ if (endpoint === "tags") return {
1235
+ ok: true,
1236
+ value: await getGitTags(cwd)
1237
+ };
1238
+ if (endpoint === "createTag") return {
1239
+ ok: true,
1240
+ value: await gitCreateTag(cwd, typeof body.name === "string" ? body.name : "", typeof body.commit === "string" ? body.commit : void 0, typeof body.message === "string" ? body.message : void 0)
1241
+ };
1242
+ if (endpoint === "deleteTag") return {
1243
+ ok: true,
1244
+ value: await gitDeleteTag(cwd, typeof body.name === "string" ? body.name : "")
1245
+ };
1246
+ return {
1247
+ ok: false,
1248
+ error: {
1249
+ code: "git/not_found",
1250
+ message: `Unknown git RPC endpoint: ${endpoint}`,
1251
+ details: {}
1204
1252
  }
1205
- if (endpoint === "branches") return {
1206
- ok: true,
1207
- value: await getGitAllBranches(cwd)
1208
- };
1209
- if (endpoint === "checkout") return {
1210
- ok: true,
1211
- value: await gitCheckout(cwd, typeof body.branch === "string" ? body.branch : "", typeof body.create === "boolean" ? body.create : false)
1212
- };
1213
- if (endpoint === "stage") return {
1214
- ok: true,
1215
- value: await gitStage(cwd, Array.isArray(body.paths) ? body.paths : body.paths === "all" ? "all" : typeof body.path === "string" ? [body.path] : "all")
1216
- };
1217
- if (endpoint === "unstage") return {
1218
- ok: true,
1219
- value: await gitUnstage(cwd, Array.isArray(body.paths) ? body.paths : body.paths === "all" ? "all" : typeof body.path === "string" ? [body.path] : "all")
1220
- };
1221
- if (endpoint === "discard") return {
1222
- ok: true,
1223
- value: await gitDiscard(cwd, Array.isArray(body.paths) ? body.paths : typeof body.path === "string" ? [body.path] : [])
1224
- };
1225
- if (endpoint === "commit") return {
1226
- ok: true,
1227
- value: await gitCommit(cwd, typeof body.message === "string" ? body.message : "")
1228
- };
1229
- if (endpoint === "fetch") return {
1230
- ok: true,
1231
- value: await gitFetch(cwd)
1232
- };
1233
- if (endpoint === "pull") return {
1234
- ok: true,
1235
- value: await gitPull(cwd)
1236
- };
1237
- if (endpoint === "push") return {
1238
- ok: true,
1239
- value: await gitPush(cwd)
1240
- };
1241
- if (endpoint === "tags") return {
1242
- ok: true,
1243
- value: await getGitTags(cwd)
1244
- };
1245
- if (endpoint === "createTag") return {
1246
- ok: true,
1247
- value: await gitCreateTag(cwd, typeof body.name === "string" ? body.name : "", typeof body.commit === "string" ? body.commit : void 0, typeof body.message === "string" ? body.message : void 0)
1248
- };
1249
- if (endpoint === "deleteTag") return {
1250
- ok: true,
1251
- value: await gitDeleteTag(cwd, typeof body.name === "string" ? body.name : "")
1252
- };
1253
- return {
1254
- ok: false,
1255
- error: {
1256
- code: "git/not_found",
1257
- message: `Unknown git RPC endpoint: ${endpoint}`,
1258
- details: {}
1253
+ };
1254
+ } catch (error) {
1255
+ return {
1256
+ ok: false,
1257
+ error: {
1258
+ code: "git/error",
1259
+ message: error instanceof Error ? error.message : String(error),
1260
+ details: {}
1261
+ }
1262
+ };
1263
+ }
1264
+ }
1265
+ /**
1266
+ * Apply the Git host plugin.
1267
+ * Sets up direct WebServer HTTP route handlers under `/git/*` and registers the model tool.
1268
+ * @param ctx - Context carrying the webServer, sessions, and sandboxPolicy services.
1269
+ */
1270
+ function apply(ctx) {
1271
+ const host = ctx;
1272
+ const resolveTargetDir = (sessionId) => {
1273
+ try {
1274
+ if (sessionId) {
1275
+ const liveCwd = host.sessions?.get?.(sessionId)?.header?.cwd;
1276
+ if (liveCwd) return liveCwd;
1277
+ }
1278
+ } catch {}
1279
+ try {
1280
+ const workspaceRoot = host.sandboxPolicy?.workspaceRoot;
1281
+ if (workspaceRoot) return workspaceRoot;
1282
+ } catch {}
1283
+ return process.cwd();
1284
+ };
1285
+ const webServer = ctx.webServer;
1286
+ if (webServer?.register) ctx.effect(() => webServer.register({
1287
+ kind: "prefix",
1288
+ path: "/git",
1289
+ handler: async (req, res) => {
1290
+ try {
1291
+ if (req.method === "OPTIONS") {
1292
+ res.writeHead(204, {
1293
+ "Access-Control-Allow-Origin": "*",
1294
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
1295
+ "Access-Control-Allow-Headers": "Content-Type, Authorization"
1296
+ });
1297
+ return res.end();
1259
1298
  }
1260
- };
1261
- } catch (error) {
1262
- return {
1263
- ok: false,
1264
- error: {
1265
- code: "git/error",
1266
- message: error instanceof Error ? error.message : String(error),
1267
- details: {}
1299
+ if (req.method !== "POST") {
1300
+ res.writeHead(405, { "Content-Type": "application/json" });
1301
+ return res.end(JSON.stringify({
1302
+ ok: false,
1303
+ error: { message: "Method Not Allowed" }
1304
+ }));
1268
1305
  }
1269
- };
1306
+ const match = new URL(req.url ?? "/", "http://localhost").pathname.match(/^\/git\/([a-zA-Z0-9_-]+)/);
1307
+ const endpoint = match ? match[1] : void 0;
1308
+ if (!endpoint) {
1309
+ res.writeHead(404, { "Content-Type": "application/json" });
1310
+ return res.end(JSON.stringify({
1311
+ ok: false,
1312
+ error: { message: "Not Found" }
1313
+ }));
1314
+ }
1315
+ let rawBody = "";
1316
+ req.on("data", (chunk) => {
1317
+ rawBody += chunk.toString("utf8");
1318
+ });
1319
+ req.on("end", async () => {
1320
+ try {
1321
+ let body = {};
1322
+ try {
1323
+ if (rawBody.trim()) body = JSON.parse(rawBody);
1324
+ } catch {
1325
+ res.writeHead(400, { "Content-Type": "application/json" });
1326
+ return res.end(JSON.stringify({
1327
+ ok: false,
1328
+ error: { message: "Invalid JSON body" }
1329
+ }));
1330
+ }
1331
+ const rpcId = body?.type === "client-request" ? body.rpcId : void 0;
1332
+ const payload = body?.type === "client-request" ? body.payload ?? {} : body;
1333
+ const result = await executeGitEndpoint(endpoint, payload, resolveTargetDir);
1334
+ res.writeHead(200, {
1335
+ "Content-Type": "application/json; charset=utf-8",
1336
+ "Access-Control-Allow-Origin": "*"
1337
+ });
1338
+ if (rpcId !== void 0) res.end(JSON.stringify({
1339
+ type: "server-response",
1340
+ rpcId,
1341
+ result
1342
+ }));
1343
+ else res.end(JSON.stringify(result));
1344
+ } catch (err) {
1345
+ res.writeHead(500, { "Content-Type": "application/json" });
1346
+ res.end(JSON.stringify({
1347
+ ok: false,
1348
+ error: {
1349
+ code: "git/internal_error",
1350
+ message: err?.message ?? String(err)
1351
+ }
1352
+ }));
1353
+ }
1354
+ });
1355
+ } catch (err) {
1356
+ try {
1357
+ res.writeHead(500, { "Content-Type": "application/json" });
1358
+ res.end(JSON.stringify({
1359
+ ok: false,
1360
+ error: {
1361
+ code: "git/internal_error",
1362
+ message: err?.message ?? String(err)
1363
+ }
1364
+ }));
1365
+ } catch {}
1366
+ }
1270
1367
  }
1271
- });
1368
+ }), "git-workbench: /git routes");
1272
1369
  registerGitTool(ctx, resolveTargetDir);
1273
1370
  }
1274
- export { apply, inject, name };
1371
+ export { apply, executeGitEndpoint, inject, name };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@civilization/dsh-git-workbench",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "IntelliJ IDEA-grade Git Workbench, DAG topology graph, branch switcher, tag manager and agent tools for DeepSeek Harness.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -1229,7 +1229,7 @@
1229
1229
  height: 26px;
1230
1230
  padding: 0 10px;
1231
1231
  border-top: 0.5px solid var(--dsw-alias-border-l2);
1232
- background: color-mix(in srgb, var(--dsw-alias-label-primary) 2%, transparent);
1232
+ background: var(--dsw-alias-bg-layer-2, #f5f5f5);
1233
1233
  font-size: 11px;
1234
1234
  color: var(--dsw-alias-label-tertiary);
1235
1235
  flex-shrink: 0;
@@ -15,22 +15,23 @@
15
15
  box-sizing: border-box;
16
16
  max-width: 100%;
17
17
  padding: 1px 8px;
18
- border: none;
18
+ border: 0.5px solid var(--dsw-alias-border-l2);
19
19
  border-radius: var(--dsw-radius-sm);
20
- background: transparent;
21
- color: var(--dsw-alias-label-tertiary);
20
+ background: var(--dsw-alias-bg-layer-1, #ffffff);
21
+ color: var(--dsw-alias-label-secondary);
22
22
  font: inherit;
23
23
  font-weight: 500;
24
24
  font-variant-numeric: tabular-nums;
25
25
  line-height: inherit;
26
26
  white-space: nowrap;
27
27
  cursor: pointer;
28
- transition: background 0.15s ease, color 0.15s ease;
28
+ transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
29
29
  }
30
30
 
31
31
  .pill:hover,
32
32
  .pill[aria-expanded='true'] {
33
33
  background: var(--dsw-alias-interactive-bg-hover);
34
+ border-color: var(--dsw-alias-border-l1);
34
35
  color: var(--dsw-alias-label-primary);
35
36
  }
36
37
 
@@ -82,7 +83,8 @@
82
83
  display: flex;
83
84
  flex-direction: column;
84
85
  box-sizing: border-box;
85
- border: 0;
86
+ background: var(--dsw-alias-bg-overlay, var(--dsw-alias-bg-layer-1, #ffffff));
87
+ border: 0.5px solid var(--dsw-alias-border-l1);
86
88
  border-radius: var(--dsw-radius-lg);
87
89
  --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);
88
90
  box-shadow: var(--dsw-elevation-prominent);
package/src/index.ts CHANGED
@@ -30,17 +30,9 @@ export type * from './types.ts'
30
30
  export const name = '@civilization/dsh-git-workbench'
31
31
 
32
32
  /** Required host services */
33
- export const inject = ['connection', 'webServer']
33
+ export const inject = ['webServer', 'sessions', 'sandboxPolicy']
34
34
 
35
35
  interface HostServices {
36
- connection: {
37
- rpc: {
38
- handle: (
39
- channel: string,
40
- handler: (endpoint: string, payload: unknown, signal: AbortSignal) => Promise<unknown>
41
- ) => () => void
42
- }
43
- }
44
36
  webServer?: {
45
37
  register: (route: unknown) => () => void
46
38
  }
@@ -53,168 +45,260 @@ interface HostServices {
53
45
  }
54
46
 
55
47
  /**
56
- * Apply the Git host plugin.
57
- * Sets up authenticated RPC handlers under `/git/*` and registers the model tool.
58
- * @param ctx - Context carrying the connection and optional session services.
48
+ * Execute Git operations based on requested endpoint and payload.
59
49
  */
60
- export function apply(ctx: Context): void {
61
- const host = ctx as any as HostServices
62
- const resolveTargetDir = (sessionId?: string): string => {
63
- if (sessionId) {
64
- const liveCwd = host.sessions?.get(sessionId)?.header?.cwd
65
- if (liveCwd) return liveCwd
50
+ export async function executeGitEndpoint(
51
+ endpoint: string,
52
+ payload: unknown,
53
+ resolveTargetDir: (sessionId?: string) => string,
54
+ ): Promise<{ ok: true; value: unknown } | { ok: false; error: { code: string; message: string; details: Record<string, unknown> } }> {
55
+ try {
56
+ const body = (typeof payload === 'object' && payload !== null ? payload : {}) as Record<string, unknown>
57
+ const sessionId = typeof body.sessionId === 'string' ? body.sessionId : undefined
58
+ const cwd = typeof body.path === 'string' ? body.path : resolveTargetDir(sessionId)
59
+
60
+ if (endpoint === 'status') {
61
+ const status = await getGitStatus(cwd)
62
+ return { ok: true, value: status }
66
63
  }
67
- const workspaceRoot = host.sandboxPolicy?.workspaceRoot
68
- return workspaceRoot ?? process.cwd()
69
- }
70
64
 
71
- // Register dedicated /git RPC channel
72
- host.connection.rpc.handle(
73
- '/git',
74
- async (endpoint: string, payload: unknown, _signal: AbortSignal) => {
75
- const body = (typeof payload === 'object' && payload !== null ? payload : {}) as Record<string, unknown>
76
- const sessionId = typeof body.sessionId === 'string' ? body.sessionId : undefined
77
- const cwd = typeof body.path === 'string' ? body.path : resolveTargetDir(sessionId)
78
-
79
- try {
80
- if (endpoint === 'status') {
81
- const status = await getGitStatus(cwd)
82
- return { ok: true, value: status }
83
- }
65
+ if (endpoint === 'log') {
66
+ const maxCount = typeof body.maxCount === 'number' ? body.maxCount : 50
67
+ const commits = await getGitLog(cwd, maxCount)
68
+ return { ok: true, value: commits }
69
+ }
84
70
 
85
- if (endpoint === 'log') {
86
- const maxCount = typeof body.maxCount === 'number' ? body.maxCount : 50
87
- const commits = await getGitLog(cwd, maxCount)
88
- return { ok: true, value: commits }
89
- }
71
+ if (endpoint === 'commitDetails') {
72
+ const commit = typeof body.commit === 'string' ? body.commit : ''
73
+ const details = await getGitCommitDetails(cwd, commit)
74
+ return { ok: true, value: details }
75
+ }
90
76
 
91
- if (endpoint === 'commitDetails') {
92
- const commit = typeof body.commit === 'string' ? body.commit : ''
93
- const details = await getGitCommitDetails(cwd, commit)
94
- return { ok: true, value: details }
95
- }
77
+ if (endpoint === 'diff') {
78
+ const path = typeof body.filePath === 'string' ? body.filePath : undefined
79
+ const staged = typeof body.staged === 'boolean' ? body.staged : false
80
+ const commit = typeof body.commit === 'string' ? body.commit : undefined
81
+ const diff = await getGitDiff(cwd, {
82
+ ...path !== undefined ? { path } : {},
83
+ staged,
84
+ ...commit !== undefined ? { commit } : {},
85
+ })
86
+ return { ok: true, value: diff }
87
+ }
96
88
 
97
- if (endpoint === 'diff') {
98
- const path = typeof body.filePath === 'string' ? body.filePath : undefined
99
- const staged = typeof body.staged === 'boolean' ? body.staged : false
100
- const commit = typeof body.commit === 'string' ? body.commit : undefined
101
- const diff = await getGitDiff(cwd, {
102
- ...path !== undefined ? { path } : {},
103
- staged,
104
- ...commit !== undefined ? { commit } : {},
105
- })
106
- return { ok: true, value: diff }
107
- }
89
+ if (endpoint === 'branches') {
90
+ const branches = await getGitAllBranches(cwd)
91
+ return { ok: true, value: branches }
92
+ }
108
93
 
109
- if (endpoint === 'branches') {
110
- const branches = await getGitAllBranches(cwd)
111
- return { ok: true, value: branches }
112
- }
94
+ if (endpoint === 'checkout') {
95
+ const branch = typeof body.branch === 'string' ? body.branch : ''
96
+ const createNew = typeof body.create === 'boolean' ? body.create : false
97
+ const result = await gitCheckout(cwd, branch, createNew)
98
+ return { ok: true, value: result }
99
+ }
113
100
 
114
- if (endpoint === 'checkout') {
115
- const branch = typeof body.branch === 'string' ? body.branch : ''
116
- const createNew = typeof body.create === 'boolean' ? body.create : false
117
- const result = await gitCheckout(cwd, branch, createNew)
118
- return { ok: true, value: result }
119
- }
101
+ if (endpoint === 'stage') {
102
+ const paths = Array.isArray(body.paths)
103
+ ? (body.paths as string[])
104
+ : body.paths === 'all'
105
+ ? 'all'
106
+ : typeof body.path === 'string'
107
+ ? [body.path]
108
+ : 'all'
109
+ const result = await gitStage(cwd, paths)
110
+ return { ok: true, value: result }
111
+ }
120
112
 
121
- if (endpoint === 'stage') {
122
- const paths = Array.isArray(body.paths)
123
- ? (body.paths as string[])
124
- : body.paths === 'all'
125
- ? 'all'
126
- : typeof body.path === 'string'
127
- ? [body.path]
128
- : 'all'
129
- const result = await gitStage(cwd, paths)
130
- return { ok: true, value: result }
131
- }
113
+ if (endpoint === 'unstage') {
114
+ const paths = Array.isArray(body.paths)
115
+ ? (body.paths as string[])
116
+ : body.paths === 'all'
117
+ ? 'all'
118
+ : typeof body.path === 'string'
119
+ ? [body.path]
120
+ : 'all'
121
+ const result = await gitUnstage(cwd, paths)
122
+ return { ok: true, value: result }
123
+ }
132
124
 
133
- if (endpoint === 'unstage') {
134
- const paths = Array.isArray(body.paths)
135
- ? (body.paths as string[])
136
- : body.paths === 'all'
137
- ? 'all'
138
- : typeof body.path === 'string'
139
- ? [body.path]
140
- : 'all'
141
- const result = await gitUnstage(cwd, paths)
142
- return { ok: true, value: result }
143
- }
125
+ if (endpoint === 'discard') {
126
+ const paths = Array.isArray(body.paths)
127
+ ? (body.paths as string[])
128
+ : typeof body.path === 'string'
129
+ ? [body.path]
130
+ : []
131
+ const result = await gitDiscard(cwd, paths)
132
+ return { ok: true, value: result }
133
+ }
144
134
 
145
- if (endpoint === 'discard') {
146
- const paths = Array.isArray(body.paths)
147
- ? (body.paths as string[])
148
- : typeof body.path === 'string'
149
- ? [body.path]
150
- : []
151
- const result = await gitDiscard(cwd, paths)
152
- return { ok: true, value: result }
153
- }
135
+ if (endpoint === 'commit') {
136
+ const message = typeof body.message === 'string' ? body.message : ''
137
+ const result = await gitCommit(cwd, message)
138
+ return { ok: true, value: result }
139
+ }
154
140
 
155
- if (endpoint === 'commit') {
156
- const message = typeof body.message === 'string' ? body.message : ''
157
- const result = await gitCommit(cwd, message)
158
- return { ok: true, value: result }
159
- }
141
+ if (endpoint === 'fetch') {
142
+ const result = await gitFetch(cwd)
143
+ return { ok: true, value: result }
144
+ }
160
145
 
161
- if (endpoint === 'fetch') {
162
- const result = await gitFetch(cwd)
163
- return { ok: true, value: result }
164
- }
146
+ if (endpoint === 'pull') {
147
+ const result = await gitPull(cwd)
148
+ return { ok: true, value: result }
149
+ }
165
150
 
166
- if (endpoint === 'pull') {
167
- const result = await gitPull(cwd)
168
- return { ok: true, value: result }
169
- }
151
+ if (endpoint === 'push') {
152
+ const result = await gitPush(cwd)
153
+ return { ok: true, value: result }
154
+ }
170
155
 
171
- if (endpoint === 'push') {
172
- const result = await gitPush(cwd)
173
- return { ok: true, value: result }
174
- }
156
+ if (endpoint === 'tags') {
157
+ const tags = await getGitTags(cwd)
158
+ return { ok: true, value: tags }
159
+ }
175
160
 
176
- if (endpoint === 'tags') {
177
- const tags = await getGitTags(cwd)
178
- return { ok: true, value: tags }
179
- }
161
+ if (endpoint === 'createTag') {
162
+ const name = typeof body.name === 'string' ? body.name : ''
163
+ const commit = typeof body.commit === 'string' ? body.commit : undefined
164
+ const message = typeof body.message === 'string' ? body.message : undefined
165
+ const result = await gitCreateTag(cwd, name, commit, message)
166
+ return { ok: true, value: result }
167
+ }
180
168
 
181
- if (endpoint === 'createTag') {
182
- const name = typeof body.name === 'string' ? body.name : ''
183
- const commit = typeof body.commit === 'string' ? body.commit : undefined
184
- const message = typeof body.message === 'string' ? body.message : undefined
185
- const result = await gitCreateTag(cwd, name, commit, message)
186
- return { ok: true, value: result }
187
- }
169
+ if (endpoint === 'deleteTag') {
170
+ const name = typeof body.name === 'string' ? body.name : ''
171
+ const result = await gitDeleteTag(cwd, name)
172
+ return { ok: true, value: result }
173
+ }
188
174
 
189
- if (endpoint === 'deleteTag') {
190
- const name = typeof body.name === 'string' ? body.name : ''
191
- const result = await gitDeleteTag(cwd, name)
192
- return { ok: true, value: result }
193
- }
175
+ return {
176
+ ok: false,
177
+ error: {
178
+ code: 'git/not_found',
179
+ message: `Unknown git RPC endpoint: ${endpoint}`,
180
+ details: {},
181
+ },
182
+ }
183
+ } catch (error) {
184
+ return {
185
+ ok: false,
186
+ error: {
187
+ code: 'git/error',
188
+ message: error instanceof Error ? error.message : String(error),
189
+ details: {},
190
+ },
191
+ }
192
+ }
193
+ }
194
194
 
195
+ /**
196
+ * Apply the Git host plugin.
197
+ * Sets up direct WebServer HTTP route handlers under `/git/*` and registers the model tool.
198
+ * @param ctx - Context carrying the webServer, sessions, and sandboxPolicy services.
199
+ */
200
+ export function apply(ctx: Context): void {
201
+ const host = ctx as any as HostServices
195
202
 
196
- return {
197
- ok: false,
198
- error: {
199
- code: 'git/not_found',
200
- message: `Unknown git RPC endpoint: ${endpoint}`,
201
- details: {},
202
- },
203
- }
204
- } catch (error) {
205
- return {
206
- ok: false,
207
- error: {
208
- code: 'git/error',
209
- message: error instanceof Error ? error.message : String(error),
210
- details: {},
211
- },
212
- }
203
+ const resolveTargetDir = (sessionId?: string): string => {
204
+ try {
205
+ if (sessionId) {
206
+ const liveCwd = host.sessions?.get?.(sessionId)?.header?.cwd
207
+ if (liveCwd) return liveCwd
213
208
  }
214
- },
215
- )
209
+ } catch {}
210
+
211
+ try {
212
+ const workspaceRoot = host.sandboxPolicy?.workspaceRoot
213
+ if (workspaceRoot) return workspaceRoot
214
+ } catch {}
215
+
216
+ return process.cwd()
217
+ }
218
+
219
+ // 1. Direct WebServer route registration (Standard, robust DSH plugin route pattern)
220
+ const webServer = (ctx as any).webServer
221
+ if (webServer?.register) {
222
+ ctx.effect(() => webServer.register({
223
+ kind: 'prefix',
224
+ path: '/git',
225
+ handler: async (req: any, res: any) => {
226
+ try {
227
+ if (req.method === 'OPTIONS') {
228
+ res.writeHead(204, {
229
+ 'Access-Control-Allow-Origin': '*',
230
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
231
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
232
+ })
233
+ return res.end()
234
+ }
235
+
236
+ if (req.method !== 'POST') {
237
+ res.writeHead(405, { 'Content-Type': 'application/json' })
238
+ return res.end(JSON.stringify({ ok: false, error: { message: 'Method Not Allowed' } }))
239
+ }
240
+
241
+ const pathname = new URL(req.url ?? '/', 'http://localhost').pathname
242
+ const match = pathname.match(/^\/git\/([a-zA-Z0-9_-]+)/)
243
+ const endpoint = match ? match[1] : undefined
216
244
 
245
+ if (!endpoint) {
246
+ res.writeHead(404, { 'Content-Type': 'application/json' })
247
+ return res.end(JSON.stringify({ ok: false, error: { message: 'Not Found' } }))
248
+ }
249
+
250
+ let rawBody = ''
251
+ req.on('data', (chunk: Buffer) => { rawBody += chunk.toString('utf8') })
252
+ req.on('end', async () => {
253
+ try {
254
+ let body: any = {}
255
+ try {
256
+ if (rawBody.trim()) body = JSON.parse(rawBody)
257
+ } catch {
258
+ res.writeHead(400, { 'Content-Type': 'application/json' })
259
+ return res.end(JSON.stringify({ ok: false, error: { message: 'Invalid JSON body' } }))
260
+ }
261
+
262
+ const rpcId = body?.type === 'client-request' ? body.rpcId : undefined
263
+ const payload = body?.type === 'client-request' ? (body.payload ?? {}) : body
264
+
265
+ const result = await executeGitEndpoint(endpoint, payload, resolveTargetDir)
266
+
267
+ res.writeHead(200, {
268
+ 'Content-Type': 'application/json; charset=utf-8',
269
+ 'Access-Control-Allow-Origin': '*',
270
+ })
271
+
272
+ if (rpcId !== undefined) {
273
+ res.end(JSON.stringify({
274
+ type: 'server-response',
275
+ rpcId,
276
+ result,
277
+ }))
278
+ } else {
279
+ res.end(JSON.stringify(result))
280
+ }
281
+ } catch (err: any) {
282
+ res.writeHead(500, { 'Content-Type': 'application/json' })
283
+ res.end(JSON.stringify({
284
+ ok: false,
285
+ error: { code: 'git/internal_error', message: err?.message ?? String(err) },
286
+ }))
287
+ }
288
+ })
289
+ } catch (err: any) {
290
+ try {
291
+ res.writeHead(500, { 'Content-Type': 'application/json' })
292
+ res.end(JSON.stringify({
293
+ ok: false,
294
+ error: { code: 'git/internal_error', message: err?.message ?? String(err) },
295
+ }))
296
+ } catch {}
297
+ }
298
+ },
299
+ }), 'git-workbench: /git routes')
300
+ }
217
301
 
218
- // Register the agent tool
302
+ // 2. Register the agent tool
219
303
  registerGitTool(ctx, resolveTargetDir)
220
304
  }