diffstalker 0.1.7 → 0.2.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/bun.lock +72 -312
  3. package/dist/App.js +1136 -515
  4. package/dist/core/ExplorerStateManager.js +266 -0
  5. package/dist/core/FilePathWatcher.js +133 -0
  6. package/dist/core/GitStateManager.js +75 -16
  7. package/dist/git/ignoreUtils.js +30 -0
  8. package/dist/git/status.js +2 -34
  9. package/dist/index.js +67 -53
  10. package/dist/ipc/CommandClient.js +165 -0
  11. package/dist/ipc/CommandServer.js +152 -0
  12. package/dist/state/CommitFlowState.js +86 -0
  13. package/dist/state/UIState.js +182 -0
  14. package/dist/types/tabs.js +4 -0
  15. package/dist/ui/Layout.js +252 -0
  16. package/dist/ui/modals/BaseBranchPicker.js +110 -0
  17. package/dist/ui/modals/DiscardConfirm.js +77 -0
  18. package/dist/ui/modals/HotkeysModal.js +209 -0
  19. package/dist/ui/modals/ThemePicker.js +107 -0
  20. package/dist/ui/widgets/CommitPanel.js +58 -0
  21. package/dist/ui/widgets/CompareListView.js +216 -0
  22. package/dist/ui/widgets/DiffView.js +279 -0
  23. package/dist/ui/widgets/ExplorerContent.js +102 -0
  24. package/dist/ui/widgets/ExplorerView.js +95 -0
  25. package/dist/ui/widgets/FileList.js +185 -0
  26. package/dist/ui/widgets/Footer.js +46 -0
  27. package/dist/ui/widgets/Header.js +111 -0
  28. package/dist/ui/widgets/HistoryView.js +69 -0
  29. package/dist/utils/ansiToBlessed.js +125 -0
  30. package/dist/utils/displayRows.js +185 -6
  31. package/dist/utils/explorerDisplayRows.js +1 -1
  32. package/dist/utils/languageDetection.js +56 -0
  33. package/dist/utils/pathUtils.js +27 -0
  34. package/dist/utils/rowCalculations.js +37 -0
  35. package/dist/utils/wordDiff.js +50 -0
  36. package/package.json +11 -12
  37. package/dist/components/BaseBranchPicker.js +0 -60
  38. package/dist/components/BottomPane.js +0 -101
  39. package/dist/components/CommitPanel.js +0 -58
  40. package/dist/components/CompareListView.js +0 -110
  41. package/dist/components/ExplorerContentView.js +0 -80
  42. package/dist/components/ExplorerView.js +0 -37
  43. package/dist/components/FileList.js +0 -131
  44. package/dist/components/Footer.js +0 -6
  45. package/dist/components/Header.js +0 -107
  46. package/dist/components/HistoryView.js +0 -21
  47. package/dist/components/HotkeysModal.js +0 -108
  48. package/dist/components/Modal.js +0 -19
  49. package/dist/components/ScrollableList.js +0 -125
  50. package/dist/components/ThemePicker.js +0 -42
  51. package/dist/components/TopPane.js +0 -14
  52. package/dist/components/UnifiedDiffView.js +0 -115
  53. package/dist/hooks/useCommitFlow.js +0 -66
  54. package/dist/hooks/useCompareState.js +0 -123
  55. package/dist/hooks/useExplorerState.js +0 -248
  56. package/dist/hooks/useGit.js +0 -156
  57. package/dist/hooks/useHistoryState.js +0 -62
  58. package/dist/hooks/useKeymap.js +0 -167
  59. package/dist/hooks/useLayout.js +0 -154
  60. package/dist/hooks/useMouse.js +0 -87
  61. package/dist/hooks/useTerminalSize.js +0 -20
  62. package/dist/hooks/useWatcher.js +0 -137
package/dist/index.js CHANGED
@@ -1,45 +1,59 @@
1
1
  #!/usr/bin/env node
2
- import{jsx as xJ}from"react/jsx-runtime";import{render as pJ}from"ink";import{jsx as X0,jsxs as IX}from"react/jsx-runtime";import{useState as Q0,useCallback as k0,useMemo as VY,useEffect as v8,useRef as FX}from"react";import{Box as j8,Text as n8,useApp as wJ,useInput as gJ}from"ink";import{jsx as t,Fragment as cY,jsxs as m}from"react/jsx-runtime";import{Box as B0,Text as u}from"ink";import*as q0 from"node:fs";import*as B8 from"node:path";import*as $X from"node:os";var W$={targetFile:B8.join($X.homedir(),".cache","diffstalker","target"),watcherEnabled:!1,debug:!1,theme:"dark"},A8=B8.join($X.homedir(),".config","diffstalker","config.json"),H$=["dark","light","dark-colorblind","light-colorblind","dark-ansi","light-ansi"];function I$(X){return typeof X==="string"&&H$.includes(X)}function mY(){let X={...W$};if(process.env.DIFFSTALKER_PAGER)X.pager=process.env.DIFFSTALKER_PAGER;if(q0.existsSync(A8))try{let Y=JSON.parse(q0.readFileSync(A8,"utf-8"));if(Y.pager)X.pager=Y.pager;if(Y.targetFile)X.targetFile=Y.targetFile;if(I$(Y.theme))X.theme=Y.theme;if(typeof Y.splitRatio==="number"&&Y.splitRatio>=0.15&&Y.splitRatio<=0.85)X.splitRatio=Y.splitRatio}catch{}return X}function pX(X){let Y=B8.dirname(A8);if(!q0.existsSync(Y))q0.mkdirSync(Y,{recursive:!0});let $={};if(q0.existsSync(A8))try{$=JSON.parse(q0.readFileSync(A8,"utf-8"))}catch{}Object.assign($,X),q0.writeFileSync(A8,JSON.stringify($,null,2)+`
3
- `)}function fY(X){let Y=B8.dirname(X);if(!q0.existsSync(Y))q0.mkdirSync(Y,{recursive:!0})}function a0(X){let Y=$X.homedir();if(X.startsWith(Y))return"~"+X.slice(Y.length);return X}function lY(X,Y,$,J,Z=null,K=!1){if(!X)return 1;let Q=a0(X),V=Z==="Not a git repository",G=0;if(Y){if(G=Y.current.length,Y.tracking)G+=3+Y.tracking.length;if(Y.ahead>0)G+=3+String(Y.ahead).length;if(Y.behind>0)G+=3+String(Y.behind).length}let q=Q.length;if(K)q+=2;if(V)q+=24;if(Z&&!V)q+=Z.length+3;if($?.enabled&&$.sourceFile){let N=` (follow: ${a0($.sourceFile)})`,A=J-q-G-4;if(N.length>A){let E=J-q-2;if(N.length<=E)return 2}}return 1}function dY({branch:X}){return m(B0,{children:[t(u,{color:"green",bold:!0,children:X.current}),X.tracking&&m(cY,{children:[t(u,{dimColor:!0,children:" → "}),t(u,{color:"blue",children:X.tracking})]}),(X.ahead>0||X.behind>0)&&m(u,{children:[X.ahead>0&&m(u,{color:"green",children:[" ↑",X.ahead]}),X.behind>0&&m(u,{color:"red",children:[" ↓",X.behind]})]})]})}function nY({repoPath:X,branch:Y,isLoading:$,error:J,debug:Z,watcherState:K,width:Q=80}){if(!X)return m(B0,{flexDirection:"column",children:[m(B0,{children:[t(u,{dimColor:!0,children:"Waiting for target path..."}),t(u,{dimColor:!0,children:" (write path to ~/.cache/diffstalker/target)"})]}),Z&&K&&K.enabled&&K.sourceFile&&m(B0,{children:[m(u,{dimColor:!0,children:["[debug] source: ",a0(K.sourceFile)]}),K.rawContent&&m(u,{dimColor:!0,children:[' | raw: "',K.rawContent,'"']})]})]});let V=a0(X),G=J==="Not a git repository",q=(U)=>{if(!U)return"";return U.toLocaleTimeString()},z=0;if(Y){if(z=Y.current.length,Y.tracking)z+=3+Y.tracking.length;if(Y.ahead>0)z+=3+String(Y.ahead).length;if(Y.behind>0)z+=3+String(Y.behind).length}let N=V.length;if($)N+=2;if(G)N+=24;if(J&&!G)N+=J.length+3;let A=null,E=!1;if(K?.enabled&&K.sourceFile){let M=` (follow: ${a0(K.sourceFile)})`,O=Q-N-z-4;if(M.length<=O)A=M;else{let F=Q-N-2;if(M.length<=F)A=M,E=!0}}return m(B0,{flexDirection:"column",width:Q,children:[E?m(cY,{children:[t(B0,{justifyContent:"space-between",children:m(B0,{children:[t(u,{bold:!0,color:"cyan",children:V}),$&&t(u,{color:"yellow",children:" ⟳"}),G&&t(u,{color:"yellow",children:" (not a git repository)"}),J&&!G&&m(u,{color:"red",children:[" (",J,")"]}),A&&t(u,{dimColor:!0,children:A})]})}),t(B0,{justifyContent:"flex-end",children:Y&&t(dY,{branch:Y})})]}):m(B0,{justifyContent:"space-between",children:[m(B0,{children:[t(u,{bold:!0,color:"cyan",children:V}),$&&t(u,{color:"yellow",children:""}),G&&t(u,{color:"yellow",children:" (not a git repository)"}),J&&!G&&m(u,{color:"red",children:[" (",J,")"]}),A&&t(u,{dimColor:!0,children:A})]}),Y&&t(dY,{branch:Y})]}),Z&&K&&K.enabled&&K.sourceFile&&m(B0,{children:[m(u,{dimColor:!0,children:["[debug] source: ",a0(K.sourceFile)]}),m(u,{dimColor:!0,children:[' | raw: "',K.rawContent,'"']}),K.lastUpdate&&m(u,{dimColor:!0,children:[" | updated: ",q(K.lastUpdate)]})]})]})}import{jsx as I0,jsxs as i0}from"react/jsx-runtime";import{Box as uX,Text as z0}from"ink";function v0(X,Y){if(X.length<=Y)return X;let J=Math.max(Y,20);if(X.length<=J)return X;let Z=X.split("/");if(Z.length===1){let N=Math.floor((J-1)/2);return X.slice(0,N)+"…"+X.slice(-(J-N-1))}let K=Z[Z.length-1],Q=Z[0],V="/…/";if(Q.length+V.length+K.length>J){let N=J-2;if(K.length>N){let A=Math.floor((N-1)/2);return"…/"+K.slice(0,A)+"…"+K.slice(-(N-A-1))}return"…/"+K}let q=Q,z=1;while(z<Z.length-1){let N=Z[z],A=q+"/"+N;if(A.length+V.length+K.length<=J)q=A,z++;else break}if(z===Z.length-1)return X;return q+V+K}function g0(X){let Y=X.filter((Z)=>!Z.staged&&Z.status!=="untracked"),$=X.filter((Z)=>!Z.staged&&Z.status==="untracked"),J=X.filter((Z)=>Z.staged);return{modified:Y,untracked:$,staged:J,ordered:[...Y,...$,...J]}}function b8(X){let{modified:Y,untracked:$,staged:J}=g0(X);return{modifiedCount:Y.length,untrackedCount:$.length,stagedCount:J.length}}function F$(X){switch(X){case"modified":return"M";case"added":return"A";case"deleted":return"D";case"untracked":return"?";case"renamed":return"R";case"copied":return"C";default:return" "}}function R$(X){switch(X){case"modified":return"yellow";case"added":return"green";case"deleted":return"red";case"untracked":return"gray";case"renamed":return"blue";case"copied":return"cyan";default:return"white"}}function D$(X,Y){if(X===void 0&&Y===void 0)return null;let $=X??0,J=Y??0;if($===0&&J===0)return null;let Z=[];if($>0)Z.push(`+${$}`);if(J>0)Z.push(`-${J}`);return Z.join(" ")}function _$({file:X,isSelected:Y,isFocused:$,maxPathLength:J}){let Z=F$(X.status),K=R$(X.status),Q=X.staged?"[-]":"[+]",V=X.staged?"red":"green",G=D$(X.insertions,X.deletions),q=Y&&$,z=G?G.length+1:0,N=J-z,A=v0(X.path,N);return i0(uX,{children:[I0(z0,{color:q?"cyan":void 0,bold:q,children:q?"▸ ":" "}),i0(z0,{color:V,children:[Q," "]}),i0(z0,{color:K,children:[Z," "]}),I0(z0,{color:q?"cyan":void 0,inverse:q,children:A}),X.originalPath&&i0(z0,{dimColor:!0,children:[" ← ",v0(X.originalPath,30)]}),G&&i0(z0,{children:[I0(z0,{dimColor:!0,children:" "}),X.insertions!==void 0&&X.insertions>0&&i0(z0,{color:"green",children:["+",X.insertions]}),X.insertions!==void 0&&X.insertions>0&&X.deletions!==void 0&&X.deletions>0&&I0(z0,{dimColor:!0,children:" "}),X.deletions!==void 0&&X.deletions>0&&i0(z0,{color:"red",children:["-",X.deletions]})]})]})}function rY({files:X,selectedIndex:Y,isFocused:$,scrollOffset:J=0,maxHeight:Z,width:K=80}){let Q=K-10,{modified:V,untracked:G,staged:q}=g0(X);if(X.length===0)return I0(uX,{flexDirection:"column",children:I0(z0,{dimColor:!0,children:" No changes"})});let z=[],N=0;if(V.length>0)z.push({type:"header",content:"Modified:",headerColor:"yellow"}),V.forEach((E)=>{z.push({type:"file",file:E,fileIndex:N++})});if(G.length>0){if(V.length>0)z.push({type:"spacer"});z.push({type:"header",content:"Untracked:",headerColor:"gray"}),G.forEach((E)=>{z.push({type:"file",file:E,fileIndex:N++})})}if(q.length>0){if(V.length>0||G.length>0)z.push({type:"spacer"});z.push({type:"header",content:"Staged:",headerColor:"green"}),q.forEach((E)=>{z.push({type:"file",file:E,fileIndex:N++})})}let A=Z?z.slice(J,J+Z):z.slice(J);return I0(uX,{flexDirection:"column",children:A.map((E,U)=>{let M=`row-${J+U}`;if(E.type==="header")return I0(z0,{bold:!0,color:E.headerColor,children:E.content},M);if(E.type==="spacer")return I0(z0,{children:" "},M);if(E.type==="file"&&E.file!==void 0&&E.fileIndex!==void 0)return I0(_$,{file:E.file,isSelected:E.fileIndex===Y,isFocused:$,maxPathLength:Q},M);return null})})}function hX(X,Y){let{ordered:$}=g0(X);return $[Y]??null}function oY(X){return X.length}import{jsx as j0,jsxs as nX,Fragment as iY}from"react/jsx-runtime";import{Box as C$,Text as p0}from"ink";import{jsxs as mX,jsx as fX}from"react/jsx-runtime";import{useMemo as v$}from"react";import{Box as sY,Text as JX}from"ink";function x0({items:X,renderItem:Y,maxHeight:$,scrollOffset:J,getKey:Z,header:K,showIndicators:Q=!0,getItemHeight:V}){let G=!!V,{itemRowStarts:q,totalRows:z}=v$(()=>{if(!G)return{itemRowStarts:[],totalRows:X.length};let H=[],B=0;for(let L=0;L<X.length;L++)H.push(B),B+=V(X[L],L);return{itemRowStarts:H,totalRows:B}},[X,V,G]),N=$;if(K)N--;let A=J>0,U=(G?z:X.length)>$;if(Q&&U)N-=2;N=Math.max(1,N);let M=[],O=0,F=0,k=0;if(G){let H=0;for(let B=0;B<X.length;B++){let L=V(X[B],B);if(q[B]+L>J){H=B;break}}for(let B=H;B<X.length&&O<N;B++){let L=V(X[B],B);M.push({item:X[B],index:B}),O+=L}F=J,k=Math.max(0,z-J-O)}else{let H=Math.min(J+N,X.length);for(let B=J;B<H;B++)M.push({item:X[B],index:B}),O++;F=J,k=Math.max(0,X.length-J-O)}return mX(sY,{flexDirection:"column",overflowX:"hidden",height:$,overflow:"hidden",children:[K,Q&&U&&(A?mX(JX,{dimColor:!0,children:["↑ ",F," more above"]}):fX(JX,{children:" "})),M.map(({item:H,index:B})=>fX(sY,{children:Y(H,B)},`${J}-${B}-${Z(H,B)}`)),Q&&U&&(k>0?mX(JX,{dimColor:!0,children:[" ",k," more below"]}):fX(JX,{children:" "}))]})}function E8(X,Y,$=!1,J=!0){let Z=Y;if($)Z--;if(J&&X>Z)Z-=2;return Z=Math.max(1,Z),Math.max(0,X-Z)}function ZX(X){let $=new Date().getTime()-X.getTime(),J=Math.floor($/3600000),Z=Math.floor($/86400000);if(J<1)return`${Math.floor($/60000)}m ago`;else if(J<48)return`${J}h ago`;else if(Z<=14)return`${Z}d ago`;else return X.toLocaleDateString("en-US",{month:"short",day:"numeric"})}function dX(X){return X.toLocaleString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function j$(X,Y){if(X.length<=Y)return X;if(Y<=3)return X.slice(0,Y);return X.slice(0,Y-3)+"..."}function KX(X,Y,$,J=20){let Z=Y||"",K=Math.max(0,$-J-1),Q=Z;if(Q.length>K&&K>3)Q=Q.slice(0,K-3)+"...";else if(Q.length>K)Q="";let V=Q?Q.length+1:0,G=Math.max(J,$-V);return{displayMessage:j$(X,G),displayRefs:Q}}function y$(X){return!(X.startsWith("index ")||X.startsWith("--- ")||X.startsWith("+++ ")||X.startsWith("similarity index"))}function w8(X){if(X.type!=="header")return!0;return y$(X.content)}function QX(X,Y,$=!0){if(Y<=0)return[{text:X,isContinuation:!1}];if(X.length<=Y)return[{text:X,isContinuation:!1}];let J=[],Z=X,K=!0;while(Z.length>0){if(Z.length<=Y){J.push({text:Z,isContinuation:!K});break}J.push({text:Z.slice(0,Y),isContinuation:!K}),Z=Z.slice(Y),K=!1}if($)P$(X,Y,J);return J}function P$(X,Y,$){let J=$.map((Z)=>Z.text).join("");if(J!==X)throw Error(`[LineBreaking] Content was lost during breaking!
4
- Original (${X.length} chars): "${X.slice(0,50)}${X.length>50?"...":""}"
5
- Joined (${J.length} chars): "${J.slice(0,50)}${J.length>50?"...":""}"`);for(let Z=0;Z<$.length;Z++){let K=$[Z];if(K.text.length>Y&&Y>=1)throw Error(`[LineBreaking] Segment ${Z} exceeds maxWidth!
6
- Segment length: ${K.text.length}, maxWidth: ${Y}
7
- Segment: "${K.text.slice(0,50)}${K.text.length>50?"...":""}"`)}if($.length>0&&$[0].isContinuation)throw Error("[LineBreaking] First segment incorrectly marked as continuation!");for(let Z=1;Z<$.length;Z++)if(!$[Z].isContinuation)throw Error(`[LineBreaking] Segment ${Z} should be marked as continuation but isn't!`)}function g8(X,Y){if(Y<=0)return 1;if(X.length<=Y)return 1;return Math.ceil(X.length/Y)}function cX(X,Y,$,J=0){let Z=X+J;if(Z<0||Z>=Y.length)return-1;return Z}function T$(X){if(!X||X.files.length===0)return{raw:"",lines:[]};let Y=[],$=[];for(let J of X.files){for(let Z of J.diff.lines)Y.push(Z);$.push(J.diff.raw)}return{raw:$.join(`
8
- `),lines:Y}}function aY(X,Y){if(!X||Y<0||Y>=X.files.length)return 0;let $=T$(X),J=0,Z=0;for(let K of $.lines){if(K.type==="header"&&K.content.startsWith("diff --git")){if(Z===Y)return J;Z++}if(!w8(K))continue;J++}return 0}function lX(X,Y,$,J=!0,Z=!0){let K=0;if(Y>0){if(X===K)return-1;if(K++,J){if(X<K+Y)return X-K;K+=Y}}if($>0){if(Y>0){if(X===K)return-1;K++}if(X===K)return-1;if(K++,Z){if(X<K+$)return Y+(X-K)}}return-1}function tY({commits:X,selectedIndex:Y,scrollOffset:$,maxHeight:J,isActive:Z,width:K,onSelectCommit:Q}){if(X.length===0)return j0(C$,{children:j0(p0,{dimColor:!0,children:"No commits yet"})});return j0(x0,{items:X,maxHeight:J,scrollOffset:$,getKey:(V)=>V.hash,renderItem:(V,G)=>{let q=G===Y&&Z,z=ZX(V.date),N=11+z.length+2,A=K-N,{displayMessage:E,displayRefs:U}=KX(V.message,V.refs,A);return nX(iY,{children:[j0(p0,{color:"yellow",children:V.shortHash}),j0(p0,{children:" "}),j0(p0,{color:q?"cyan":void 0,bold:q,inverse:q,children:E}),j0(p0,{children:" "}),nX(p0,{dimColor:!0,children:["(",z,")"]}),U&&nX(iY,{children:[j0(p0,{children:" "}),j0(p0,{color:"green",children:U})]})]})}})}import{jsx as y0,Fragment as S$,jsxs as qX}from"react/jsx-runtime";import{Box as b$,Text as E0}from"ink";function eY({activeTab:X,mouseEnabled:Y=!0,autoTabEnabled:$=!1,wrapMode:J=!1,showMiddleDots:Z=!1}){return qX(b$,{justifyContent:"space-between",children:[qX(E0,{children:[y0(E0,{dimColor:!0,children:"?"})," ",y0(E0,{color:"yellow",children:Y?"[scroll]":"m:[select]"})," ",y0(E0,{color:$?"blue":void 0,dimColor:!$,children:"[auto]"})," ",y0(E0,{color:J?"blue":void 0,dimColor:!J,children:"[wrap]"}),X==="explorer"&&qX(S$,{children:[" ",y0(E0,{color:Z?"blue":void 0,dimColor:!Z,children:"[dots]"})]})]}),qX(E0,{children:[y0(E0,{color:X==="diff"?"cyan":void 0,bold:X==="diff",children:"[1]Diff"})," ",y0(E0,{color:X==="commit"?"cyan":void 0,bold:X==="commit",children:"[2]Commit"})," ",y0(E0,{color:X==="history"?"cyan":void 0,bold:X==="history",children:"[3]History"})," ",y0(E0,{color:X==="compare"?"cyan":void 0,bold:X==="compare",children:"[4]Compare"})]})]})}import{jsx as o,jsxs as e,Fragment as p8}from"react/jsx-runtime";import h$ from"react";import{Box as t0,Text as s}from"ink";import{jsx as n,jsxs as M0,Fragment as w$}from"react/jsx-runtime";import{useMemo as g$}from"react";import{Box as x8,Text as h}from"ink";function x$({commit:X,isSelected:Y,isActive:$,width:J}){let Z=ZX(X.date),K=13+Z.length+2,Q=J-K,{displayMessage:V,displayRefs:G}=KX(X.message,X.refs,Q);return M0(x8,{children:[n(h,{children:" "}),n(h,{color:"yellow",children:X.shortHash}),n(h,{children:" "}),n(h,{color:Y&&$?"cyan":void 0,bold:Y&&$,inverse:Y&&$,children:V}),n(h,{children:" "}),M0(h,{dimColor:!0,children:["(",Z,")"]}),G&&M0(w$,{children:[n(h,{children:" "}),n(h,{color:"green",children:G})]})]})}function p$({file:X,isSelected:Y,isActive:$,maxPathLength:J}){let Z={added:"green",modified:"yellow",deleted:"red",renamed:"blue"},K={added:"A",modified:"M",deleted:"D",renamed:"R"},Q=X.isUncommitted??!1,V=5+String(X.additions).length+String(X.deletions).length,G=Q?14:0,q=J-V-G;return M0(x8,{children:[n(h,{children:" "}),Q&&n(h,{color:"magenta",bold:!0,children:"*"}),n(h,{color:Q?"magenta":Z[X.status],bold:!0,children:K[X.status]}),M0(h,{bold:Y&&$,color:Y&&$?"cyan":Q?"magenta":void 0,inverse:Y&&$,children:[" ",v0(X.path,q)]}),n(h,{dimColor:!0,children:" ("}),M0(h,{color:"green",children:["+",X.additions]}),n(h,{dimColor:!0,children:" "}),M0(h,{color:"red",children:["-",X.deletions]}),n(h,{dimColor:!0,children:")"}),Q&&M0(h,{color:"magenta",dimColor:!0,children:[" ","[uncommitted]"]})]})}function X4({commits:X,files:Y,selectedItem:$,scrollOffset:J,maxHeight:Z,isActive:K,width:Q}){let z=g$(()=>{let N=[];if(X.length>0)N.push({type:"section-header",sectionType:"commits"}),X.forEach((A,E)=>{N.push({type:"commit",commitIndex:E,commit:A})});if(Y.length>0){if(X.length>0)N.push({type:"spacer"});N.push({type:"section-header",sectionType:"files"}),Y.forEach((A,E)=>{N.push({type:"file",fileIndex:E,file:A})})}return N},[X,Y,!0,!0]).slice(J,J+Z);if(X.length===0&&Y.length===0)return n(x8,{flexDirection:"column",children:n(h,{dimColor:!0,children:"No changes compared to base branch"})});return n(x8,{flexDirection:"column",children:z.map((N,A)=>{let E=`row-${J+A}`;if(N.type==="section-header"){let U=N.sectionType==="commits",M=U?!0:!0,O=U?X.length:Y.length;return M0(x8,{children:[M0(h,{bold:!0,color:"cyan",children:[M?"▼":"▶"," ",U?"Commits":"Files"]}),M0(h,{dimColor:!0,children:[" (",O,")"]})]},E)}if(N.type==="spacer")return n(h,{children:" "},E);if(N.type==="commit"&&N.commit!==void 0&&N.commitIndex!==void 0){let U=$?.type==="commit"&&$.index===N.commitIndex;return n(x$,{commit:N.commit,isSelected:U,isActive:K,width:Q},E)}if(N.type==="file"&&N.file!==void 0&&N.fileIndex!==void 0){let U=$?.type==="file"&&$.index===N.fileIndex;return n(p$,{file:N.file,isSelected:U,isActive:K,maxPathLength:Q-5},E)}return null})})}import{jsxs as u$,jsx as F0}from"react/jsx-runtime";import{Box as zX,Text as M8}from"ink";function Y4({currentPath:X,items:Y,selectedIndex:$,scrollOffset:J,maxHeight:Z,isActive:K,width:Q,isLoading:V=!1,error:G=null}){if(G)return F0(zX,{flexDirection:"column",children:u$(M8,{color:"red",children:["Error: ",G]})});if(V)return F0(zX,{flexDirection:"column",children:F0(M8,{dimColor:!0,children:"Loading..."})});if(Y.length===0)return F0(zX,{flexDirection:"column",children:F0(M8,{dimColor:!0,children:"(empty directory)"})});let q=Math.min(Math.max(...Y.map((z)=>z.name.length+(z.isDirectory?1:0))),Q-10);return F0(x0,{items:Y,maxHeight:Z,scrollOffset:J,getKey:(z)=>z.path||z.name,renderItem:(z,N)=>{let A=N===$&&K,U=(z.isDirectory?`${z.name}/`:z.name).padEnd(q+1);return F0(zX,{children:F0(M8,{color:A?"cyan":void 0,bold:A,inverse:A,children:z.isDirectory?F0(M8,{color:A?"cyan":"blue",children:U}):F0(M8,{color:A?"cyan":void 0,children:U})})})}})}function $4(X){if(!X)return[];return X.split("/").filter(Boolean)}function J4({bottomTab:X,currentPane:Y,terminalWidth:$,topPaneHeight:J,files:Z,selectedIndex:K,fileListScrollOffset:Q,stagedCount:V,onStage:G,onUnstage:q,commits:z,historySelectedIndex:N,historyScrollOffset:A,onSelectHistoryCommit:E,compareDiff:U,compareListSelection:M,compareScrollOffset:O,includeUncommitted:F,explorerCurrentPath:k="",explorerItems:H=[],explorerSelectedIndex:B=0,explorerScrollOffset:L=0,explorerIsLoading:R=!1,explorerError:S=null,hideHiddenFiles:P=!0,hideGitignored:W=!0}){let{modified:C,untracked:b}=g0(Z),w=C.length,g=b.length;return e(t0,{flexDirection:"column",height:J,width:$,overflowX:"hidden",overflowY:"hidden",children:[(X==="diff"||X==="commit")&&e(p8,{children:[e(t0,{children:[o(s,{bold:!0,color:Y==="files"?"cyan":void 0,children:"STAGING AREA"}),e(s,{dimColor:!0,children:[" ","(",w," modified, ",g," untracked, ",V," staged)"]})]}),o(rY,{files:Z,selectedIndex:K,isFocused:Y==="files",scrollOffset:Q,maxHeight:J-1,width:$,onStage:G,onUnstage:q})]}),X==="history"&&e(p8,{children:[e(t0,{children:[o(s,{bold:!0,color:Y==="history"?"cyan":void 0,children:"COMMITS"}),e(s,{dimColor:!0,children:[" (",z.length," commits)"]})]}),o(tY,{commits:z,selectedIndex:N,scrollOffset:A,maxHeight:J-1,isActive:Y==="history",width:$,onSelectCommit:E})]}),X==="compare"&&e(p8,{children:[e(t0,{children:[o(s,{bold:!0,color:Y==="compare"?"cyan":void 0,children:"COMPARE"}),o(s,{dimColor:!0,children:" (vs "}),o(s,{color:"cyan",children:U?.baseBranch??"..."}),e(s,{dimColor:!0,children:[": ",U?.commits.length??0," commits, ",U?.files.length??0," files) (b)"]}),U&&U.uncommittedCount>0&&e(p8,{children:[o(s,{dimColor:!0,children:" | "}),e(s,{color:F?"magenta":"yellow",children:["[",F?"x":" ","] uncommitted"]}),o(s,{dimColor:!0,children:" (u)"})]})]}),o(X4,{commits:U?.commits??[],files:U?.files??[],selectedItem:M,scrollOffset:O,maxHeight:J-1,isActive:Y==="compare",width:$})]}),X==="explorer"&&e(p8,{children:[e(t0,{justifyContent:"space-between",width:$,children:[e(t0,{children:[o(s,{bold:!0,color:Y==="explorer"?"cyan":void 0,children:"EXPLORER"}),o(s,{dimColor:!0,children:" "}),$4(k).map((p,f,_)=>e(h$.Fragment,{children:[o(s,{color:"blue",children:p}),f<_.length-1&&o(s,{dimColor:!0,children:" / "})]},f)),k&&o(s,{dimColor:!0,children:" /"}),!k&&o(s,{dimColor:!0,children:"(root)"})]}),o(t0,{children:(P||W)&&e(s,{dimColor:!0,children:[P&&"H",W&&"G"]})})]}),o(Y4,{currentPath:k,items:H,selectedIndex:B,scrollOffset:L,maxHeight:J-1,isActive:Y==="explorer",width:$,isLoading:R,error:S})]})]})}import{jsx as U0,jsxs as Y8}from"react/jsx-runtime";import{useMemo as R4}from"react";import{Box as I8,Text as O0}from"ink";import{jsxs as O8,jsx as c}from"react/jsx-runtime";import{useMemo as K4}from"react";import{Box as k8,Text as a}from"ink";var m$={name:"dark",displayName:"Dark",colors:{addBg:"#022800",delBg:"#3D0100",addHighlight:"#044700",delHighlight:"#5C0200",text:"white",addLineNum:"#368F35",delLineNum:"#A14040",contextLineNum:"gray",addSymbol:"greenBright",delSymbol:"redBright"}},f$={name:"light",displayName:"Light",colors:{addBg:"#69db7c",delBg:"#ffa8b4",addHighlight:"#2f9d44",delHighlight:"#d1454b",text:"black",addLineNum:"#2f9d44",delLineNum:"#d1454b",contextLineNum:"#6c757d",addSymbol:"green",delSymbol:"red"}},d$={name:"dark-colorblind",displayName:"Dark (colorblind)",colors:{addBg:"#004466",delBg:"#660000",addHighlight:"#0077b3",delHighlight:"#b30000",text:"white",addLineNum:"#0077b3",delLineNum:"#b30000",contextLineNum:"gray",addSymbol:"cyanBright",delSymbol:"redBright"}},c$={name:"light-colorblind",displayName:"Light (colorblind)",colors:{addBg:"#99ccff",delBg:"#ffcccc",addHighlight:"#3366cc",delHighlight:"#993333",text:"black",addLineNum:"#3366cc",delLineNum:"#993333",contextLineNum:"#6c757d",addSymbol:"blue",delSymbol:"red"}},l$={name:"dark-ansi",displayName:"Dark (ANSI)",colors:{addBg:"green",delBg:"red",addHighlight:"greenBright",delHighlight:"redBright",text:"white",addLineNum:"greenBright",delLineNum:"redBright",contextLineNum:"gray",addSymbol:"greenBright",delSymbol:"redBright"}},n$={name:"light-ansi",displayName:"Light (ANSI)",colors:{addBg:"green",delBg:"red",addHighlight:"greenBright",delHighlight:"redBright",text:"black",addLineNum:"green",delLineNum:"red",contextLineNum:"gray",addSymbol:"green",delSymbol:"red"}},VX={dark:m$,light:f$,"dark-colorblind":d$,"light-colorblind":c$,"dark-ansi":l$,"light-ansi":n$},e0=["dark","light","dark-colorblind","light-colorblind","dark-ansi","light-ansi"];function UX(X){return VX[X]??VX.dark}function rX(X){if(X.type==="addition"||X.type==="deletion")return X.content.slice(1);if(X.type==="context")return X.content.startsWith(" ")?X.content.slice(1):X.content;return X.content}function r$(X){switch(X.type){case"header":return{type:"diff-header",content:X.content};case"hunk":return{type:"diff-hunk",content:X.content};case"addition":return{type:"diff-add",lineNum:X.newLineNum,content:rX(X)};case"deletion":return{type:"diff-del",lineNum:X.oldLineNum,content:rX(X)};case"context":return{type:"diff-context",lineNum:X.oldLineNum??X.newLineNum,content:rX(X)}}}function X8(X){if(!X)return[];return X.lines.filter(w8).map(r$)}function GX(X,Y){let $=[];if(X){$.push({type:"commit-header",content:`commit ${X.hash}`}),$.push({type:"commit-header",content:`Author: ${X.author}`}),$.push({type:"commit-header",content:`Date: ${dX(X.date)}`}),$.push({type:"spacer"});for(let J of X.message.split(`
9
- `))$.push({type:"commit-message",content:` ${J}`});$.push({type:"spacer"})}return $.push(...X8(Y)),$}function NX(X){if(!X||X.files.length===0)return[];let Y=[];for(let $ of X.files)Y.push(...X8($.diff));return Y}function R0(X){let Y=0;for(let $ of X)if("lineNum"in $&&$.lineNum!==void 0)Y=Math.max(Y,$.lineNum);return Math.max(3,String(Y).length)}function Z4(X,Y,$){if(!$)return X;let Z=Math.max(10,Y),K=[];for(let Q of X)if(Q.type==="diff-add"||Q.type==="diff-del"||Q.type==="diff-context"){let V=Q.content;if(!V||V.length<=Z){K.push(Q);continue}let G=QX(V,Z);for(let q=0;q<G.length;q++){let z=G[q];K.push({...Q,content:z.text,lineNum:z.isContinuation?void 0:Q.lineNum,isContinuation:z.isContinuation})}}else K.push(Q);return K}function L8(X,Y,$){if(!$)return X.length;let Z=Math.max(10,Y),K=0;for(let Q of X)if(Q.type==="diff-add"||Q.type==="diff-del"||Q.type==="diff-context"){let V=Q.content;if(!V||V.length<=Z)K+=1;else K+=g8(V,Z)}else K+=1;return K}function P0(X,Y){if(Y<=0||X.length<=Y)return X;if(Y<=1)return"…";return X.slice(0,Y-1)+"…"}function oX(X,Y){if(X===void 0)return" ".repeat(Y);return String(X).padStart(Y," ")}function o$({row:X,lineNumWidth:Y,width:$,theme:J,wrapMode:Z}){let{colors:K}=J,Q=$-Y-5,V=$-2;switch(X.type){case"diff-header":{let G=X.content;if(G.startsWith("diff --git")){let q=G.match(/diff --git a\/.+ b\/(.+)$/);if(q){let z=V-6,N=P0(q[1],z);return O8(a,{color:"cyan",bold:!0,children:["── ",N," ──"]})}}return c(a,{dimColor:!0,children:P0(G,V)})}case"diff-hunk":{let G=X.content.match(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)$/);if(G){let q=parseInt(G[1],10),z=G[2]?parseInt(G[2],10):1,N=parseInt(G[3],10),A=G[4]?parseInt(G[4],10):1,E=G[5].trim(),U=q+z-1,M=N+A-1,O=z===1?`${q}`:`${q}-${U}`,F=A===1?`${N}`:`${N}-${M}`,k=`Lines ${O} → ${F}`,H=V-k.length-1,B=E&&H>3?" "+P0(E,H):"";return O8(k8,{children:[c(a,{color:"cyan",dimColor:!0,children:k}),B&&c(a,{color:"gray",children:B})]})}return c(a,{color:"cyan",dimColor:!0,children:P0(X.content,V)})}case"diff-add":{let G=X.isContinuation,q=G?"»":"+",N=" "+(Z?X.content||"":P0(X.content,Q)||"")||" ";return O8(k8,{children:[c(a,{backgroundColor:K.addBg,color:K.addLineNum,children:oX(X.lineNum,Y)+" "}),c(a,{backgroundColor:K.addBg,color:G?K.addLineNum:K.addSymbol,bold:!G,children:q}),c(a,{backgroundColor:K.addBg,color:K.text,children:N})]})}case"diff-del":{let G=X.isContinuation,q=G?"»":"-",N=" "+(Z?X.content||"":P0(X.content,Q)||"")||" ";return O8(k8,{children:[c(a,{backgroundColor:K.delBg,color:K.delLineNum,children:oX(X.lineNum,Y)+" "}),c(a,{backgroundColor:K.delBg,color:G?K.delLineNum:K.delSymbol,bold:!G,children:q}),c(a,{backgroundColor:K.delBg,color:K.text,children:N})]})}case"diff-context":{let q=X.isContinuation?"» ":" ",z=Z?X.content:P0(X.content,Q);return O8(k8,{children:[O8(a,{color:K.contextLineNum,children:[oX(X.lineNum,Y)," "]}),c(a,{dimColor:!0,children:q}),c(a,{children:z})]})}case"commit-header":return c(a,{color:"yellow",children:P0(X.content,V)});case"commit-message":return c(a,{children:P0(X.content,V)});case"spacer":return c(a,{children:" "})}}function Q4({rows:X,maxHeight:Y,scrollOffset:$,theme:J,width:Z,wrapMode:K=!1}){let Q=K4(()=>UX(J),[J]),V=K4(()=>R0(X),[X]);if(X.length===0)return c(k8,{paddingX:1,children:c(a,{dimColor:!0,children:"No diff to display"})});return c(k8,{flexDirection:"column",paddingX:1,width:Z,children:c(x0,{items:X,maxHeight:Y,scrollOffset:$,getKey:(G,q)=>`row-${q}`,renderItem:(G)=>c(o$,{row:G,lineNumWidth:V,width:Z,theme:Q,wrapMode:K})})})}import{jsx as V0,jsxs as h8}from"react/jsx-runtime";import{useEffect as a$}from"react";import{Box as u0,Text as T0,useInput as i$}from"ink";import t$ from"ink-text-input";import{useState as u8,useCallback as sX,useEffect as s$}from"react";function q4(X,Y,$){if(!X.trim())return{valid:!1,error:"Commit message cannot be empty"};if(Y===0&&!$)return{valid:!1,error:"No changes staged for commit"};return{valid:!0,error:null}}function z4(X){return X.trim()}function V4(X){let{stagedCount:Y,onCommit:$,onSuccess:J,getHeadMessage:Z}=X,[K,Q]=u8(""),[V,G]=u8(!1),[q,z]=u8(!1),[N,A]=u8(null),[E,U]=u8(!1);s$(()=>{if(V)Z().then((k)=>{if(k&&!K)Q(k)})},[V,Z]);let M=sX(()=>{G((k)=>!k)},[]),O=sX(async()=>{let k=q4(K,Y,V);if(!k.valid){A(k.error);return}z(!0),A(null);try{await $(z4(K),V),Q(""),G(!1),J()}catch(H){A(H instanceof Error?H.message:"Commit failed")}finally{z(!1)}},[K,Y,V,$,J]),F=sX(()=>{Q(""),G(!1),A(null),U(!1)},[]);return{message:K,amend:V,isCommitting:q,error:N,inputFocused:E,setMessage:Q,toggleAmend:M,setInputFocused:U,handleSubmit:O,reset:F}}function U4({isActive:X,stagedCount:Y,onCommit:$,onCancel:J,getHeadMessage:Z,onInputFocusChange:K}){let{message:Q,amend:V,isCommitting:G,error:q,inputFocused:z,setMessage:N,toggleAmend:A,setInputFocused:E,handleSubmit:U}=V4({stagedCount:Y,onCommit:$,onSuccess:J,getHeadMessage:Z});if(a$(()=>{K?.(z)},[z,K]),i$((M,O)=>{if(!X)return;if(O.escape){if(z)E(!1);else J();return}if(!z){if(M==="i"||O.return){E(!0);return}if(M==="a"){A();return}return}if(M==="a"&&!Q){A();return}},{isActive:X}),!X)return V0(u0,{paddingX:1,children:V0(T0,{dimColor:!0,children:"Press '2' or 'c' to open commit panel"})});return h8(u0,{flexDirection:"column",paddingX:1,children:[h8(u0,{marginBottom:1,children:[V0(T0,{bold:!0,children:"Commit Message"}),V&&V0(T0,{color:"yellow",children:" (amending)"})]}),V0(u0,{borderStyle:"round",borderColor:z?"cyan":void 0,paddingX:1,children:z?V0(t$,{value:Q,onChange:N,onSubmit:U,placeholder:"Enter commit message..."}):V0(T0,{dimColor:!Q,children:Q||"Press i or Enter to edit..."})}),h8(u0,{marginTop:1,gap:2,children:[h8(T0,{color:V?"green":"gray",children:["[",V?"x":" ","] Amend"]}),V0(T0,{dimColor:!0,children:"(a)"})]}),q&&V0(u0,{marginTop:1,children:V0(T0,{color:"red",children:q})}),G&&V0(u0,{marginTop:1,children:V0(T0,{color:"yellow",children:"Committing..."})}),V0(u0,{marginTop:1,children:h8(T0,{dimColor:!0,children:["Staged: ",Y," file(s) |"," ",z?"Enter: commit | Esc: unfocus":"i/Enter: edit | Esc: cancel | 1/3: switch tab"]})})]})}import{jsx as L0,jsxs as H4}from"react/jsx-runtime";import{useMemo as eX}from"react";import{Box as W8,Text as H8}from"ink";import{createEmphasize as e$}from"emphasize";import{common as XJ}from"lowlight";var A4=e$(XJ),YJ={ts:"typescript",tsx:"typescript",js:"javascript",jsx:"javascript",mjs:"javascript",cjs:"javascript",html:"xml",htm:"xml",xml:"xml",svg:"xml",css:"css",scss:"scss",sass:"scss",less:"less",json:"json",yaml:"yaml",yml:"yaml",toml:"ini",sh:"bash",bash:"bash",zsh:"bash",fish:"bash",ps1:"powershell",bat:"dos",cmd:"dos",c:"c",h:"c",cpp:"cpp",hpp:"cpp",cc:"cpp",cxx:"cpp",rs:"rust",go:"go",zig:"zig",java:"java",kt:"kotlin",kts:"kotlin",scala:"scala",groovy:"groovy",gradle:"groovy",py:"python",rb:"ruby",pl:"perl",lua:"lua",php:"php",r:"r",hs:"haskell",ml:"ocaml",fs:"fsharp",fsx:"fsharp",ex:"elixir",exs:"elixir",erl:"erlang",clj:"clojure",cljs:"clojure",cs:"csharp",vb:"vbnet",md:"markdown",markdown:"markdown",rst:"plaintext",txt:"plaintext",Makefile:"makefile",Dockerfile:"dockerfile",cmake:"cmake",ini:"ini",conf:"ini",cfg:"ini",sql:"sql",vim:"vim",diff:"diff",patch:"diff"},G4={Makefile:"makefile",makefile:"makefile",GNUmakefile:"makefile",Dockerfile:"dockerfile",dockerfile:"dockerfile",Jenkinsfile:"groovy",Vagrantfile:"ruby",Gemfile:"ruby",Rakefile:"ruby",".gitignore":"plaintext",".gitattributes":"plaintext",".editorconfig":"ini",".prettierrc":"json",".eslintrc":"json","tsconfig.json":"json","package.json":"json","package-lock.json":"json","bun.lockb":"plaintext","yarn.lock":"yaml","pnpm-lock.yaml":"yaml","Cargo.toml":"ini","Cargo.lock":"ini","go.mod":"go","go.sum":"plaintext"},aX=null;function N4(){if(!aX)aX=new Set(A4.listLanguages());return aX}function B4(X){if(!X)return null;let Y=X.split("/").pop()??"";if(G4[Y]){let Z=G4[Y];return N4().has(Z)?Z:null}let $=Y.includes(".")?Y.split(".").pop()?.toLowerCase():null;if(!$)return null;let J=YJ[$];if(!J)return null;return N4().has(J)?J:null}function E4(X,Y){if(!X||!Y)return X;try{return A4.highlight(Y,X).value}catch{return X}}function iX(X,Y,$){if(!X)return[];let J=[],Z=X.split(`
10
- `),K=Y?B4(Y):null;for(let Q=0;Q<Z.length;Q++){let V=Z[Q],G=K?E4(V,K):void 0;J.push({type:"code",lineNum:Q+1,content:V,highlighted:G})}if($)J.push({type:"truncation",content:"(file truncated)"});return J}function M4(X,Y,$){if(!$)return X;let Z=Math.max(10,Y),K=[];for(let Q of X)if(Q.type==="code"){let V=Q.content;if(!V||V.length<=Z){K.push(Q);continue}let G=QX(V,Z);for(let q=0;q<G.length;q++){let z=G[q];K.push({type:"code",lineNum:z.isContinuation?0:Q.lineNum,content:z.text,highlighted:void 0,isContinuation:z.isContinuation})}}else K.push(Q);return K}function L4(X,Y,$){if(!$)return X.length;let Z=Math.max(10,Y),K=0;for(let Q of X)if(Q.type==="code"){let V=Q.content;if(!V||V.length<=Z)K+=1;else K+=g8(V,Z)}else K+=1;return K}function tX(X){let Y=0;for(let $ of X)if($.type==="code"&&$.lineNum>Y)Y=$.lineNum;return Math.max(3,String(Y).length)}function O4(X,Y){if(!Y||!X)return X;let $=0;for(let K of X)if(K===" ")$++;else if(K==="\t")$+=2;else break;if($===0)return X;let J="·".repeat($),Z=X.slice($);return J+Z}var k4=/\x1b\[[0-9;]*m/g;function W4(X,Y,$="…"){if(Y<=0)return $;if(!X.includes("\x1B")&&X.length<=Y)return X;if(!X.includes("\x1B")){if(X.length<=Y)return X;return X.slice(0,Y-$.length)+$}let J=[],Z=0;k4.lastIndex=0;let K;while((K=k4.exec(X))!==null){if(K.index>Z)J.push({type:"text",content:X.slice(Z,K.index)});J.push({type:"ansi",content:K[0]}),Z=K.index+K[0].length}if(Z<X.length)J.push({type:"text",content:X.slice(Z)});let Q="",V=0,G=Y-$.length,q=!1,z=!1;for(let N of J)if(N.type==="ansi")Q+=N.content,q=!0;else{let A=G-V;if(A<=0){z=!0;break}if(N.content.length<=A)Q+=N.content,V+=N.content.length;else{Q+=N.content.slice(0,A),V+=A,z=!0;break}}if(z){if(q)Q+="\x1B[0m";Q+=$}return Q}function I4({filePath:X,content:Y,maxHeight:$,scrollOffset:J,truncated:Z=!1,wrapMode:K=!1,width:Q,showMiddleDots:V=!1}){let G=eX(()=>iX(Y,X,Z),[Y,X,Z]),q=eX(()=>tX(G),[G]),z=Q-q-3,N=eX(()=>M4(G,z,K),[G,z,K]);if(!X)return L0(W8,{paddingX:1,children:L0(H8,{dimColor:!0,children:"Select a file to view its contents"})});if(!Y)return L0(W8,{paddingX:1,children:L0(H8,{dimColor:!0,children:"Loading..."})});if(N.length===0)return L0(W8,{paddingX:1,children:L0(H8,{dimColor:!0,children:"(empty file)"})});return L0(W8,{flexDirection:"column",paddingX:1,children:L0(x0,{items:N,maxHeight:$,scrollOffset:J,getKey:(A,E)=>`${E}`,renderItem:(A)=>{if(A.type==="truncation")return L0(W8,{children:L0(H8,{color:"yellow",dimColor:!0,children:A.content})});let E=A.isContinuation??!1,U;if(E)U=">>".padStart(q," ");else U=String(A.lineNum).padStart(q," ");let M=A.content,O=!K&&M.length>z,F=A.highlighted&&!E&&!V,k;if(F&&A.highlighted)k=O?W4(A.highlighted,z):A.highlighted;else{let H=M;if(V&&!E)H=O4(H,!0);if(O)H=H.slice(0,Math.max(0,z-1))+"…";k=H}return H4(W8,{children:[H4(H8,{dimColor:!E,color:E?"cyan":void 0,children:[U," "]}),L0(H8,{dimColor:V&&!F,children:k||" "})]})}})})}function F4(X,Y,$,J,Z){if(!X)return 0;let K=iX(X,Y,$),Q=tX(K),V=J-Q-3;return L4(K,V,Z)}function D4({bottomTab:X,currentPane:Y,terminalWidth:$,bottomPaneHeight:J,diffScrollOffset:Z,currentTheme:K,diff:Q,selectedFile:V,stagedCount:G,onCommit:q,onCommitCancel:z,getHeadCommitMessage:N,onCommitInputFocusChange:A,historySelectedCommit:E,historyCommitDiff:U,compareDiff:M,compareLoading:O,compareError:F,compareListSelection:k,compareSelectionDiff:H,wrapMode:B,explorerSelectedFile:L=null,explorerFileScrollOffset:R=0,showMiddleDots:S=!1}){let P=Y!=="files"&&Y!=="history"&&Y!=="compare"&&Y!=="explorer",W=R4(()=>{if(X==="diff")return X8(Q);if(X==="history")return GX(E,U);if(X==="compare"){if(k?.type==="commit"&&H)return X8(H);return NX(M)}return[]},[X,Q,E,U,k,H,M]),C=R4(()=>{if(!B||W.length===0)return W;let g=R0(W),p=$-g-5;return Z4(W,p,B)},[W,$,B]),b=()=>{if(V&&X==="diff")return U0(O0,{dimColor:!0,children:v0(V.path,$-10)});if(X==="history"&&E)return Y8(O0,{dimColor:!0,children:[E.shortHash," - ",E.message.slice(0,50)]});if(X==="compare"&&k)if(k.type==="commit"){let g=M?.commits[k.index];return Y8(O0,{dimColor:!0,children:[g?.shortHash??""," - ",g?.message.slice(0,40)??""]})}else{let g=M?.files[k.index]?.path??"";return U0(O0,{dimColor:!0,children:v0(g,$-10)})}if(X==="explorer"&&L)return U0(O0,{dimColor:!0,children:v0(L.path,$-10)});return null},w=()=>{if(X==="commit")return U0(U4,{isActive:Y==="commit",stagedCount:G,onCommit:q,onCancel:z,getHeadMessage:N,onInputFocusChange:A});if(X==="compare"){if(O)return U0(O0,{dimColor:!0,children:"Loading compare diff..."});if(F)return U0(O0,{color:"red",children:F});if(!M)return U0(O0,{dimColor:!0,children:"No base branch found (no origin/main or origin/master)"});if(M.files.length===0)return Y8(O0,{dimColor:!0,children:["No changes compared to ",M.baseBranch]})}return U0(Q4,{rows:C,maxHeight:J-1,scrollOffset:Z,theme:K,width:$,wrapMode:B})};if(X==="explorer")return Y8(I8,{flexDirection:"column",height:J,width:$,overflowY:"hidden",children:[Y8(I8,{width:$,children:[U0(O0,{bold:!0,color:P?"cyan":void 0,children:"FILE"}),U0(I8,{flexGrow:1,justifyContent:"flex-end",children:b()})]}),U0(I4,{filePath:L?.path??null,content:L?.content??null,maxHeight:J-1,scrollOffset:R,truncated:L?.truncated,wrapMode:B,width:$,showMiddleDots:S})]});return Y8(I8,{flexDirection:"column",height:J,width:$,overflowX:"hidden",overflowY:"hidden",children:[Y8(I8,{width:$,children:[U0(O0,{bold:!0,color:P?"cyan":void 0,children:X==="commit"?"COMMIT":"DIFF"}),U0(I8,{flexGrow:1,justifyContent:"flex-end",children:b()})]}),w()]})}import{useState as _4,useEffect as v4,useRef as j4}from"react";import*as $8 from"node:fs";import*as h0 from"node:path";import*as XY from"node:os";import{watch as $J}from"chokidar";function y4(X){if(X.startsWith("~/"))return h0.join(XY.homedir(),X.slice(2));if(X==="~")return XY.homedir();return X}function P4(X){let Y=X.split(`
11
- `);for(let $=Y.length-1;$>=0;$--){let J=Y[$].trim();if(J)return J}return""}function T4(X,Y,$=!1){let[J,Z]=_4(X),[K,Q]=_4({path:null,lastUpdate:null,rawContent:null,sourceFile:X?Y:null,enabled:X}),V=j4(null),G=j4(null);return v4(()=>{Q((q)=>({...q,enabled:J,sourceFile:J?Y:null}))},[J,Y]),v4(()=>{if(!J)return;if(fY(Y),!$8.existsSync(Y))$8.writeFileSync(Y,"");let q=()=>{if(V.current)clearTimeout(V.current);V.current=setTimeout(()=>{try{let N=$8.readFileSync(Y,"utf-8"),A=P4(N);if(A&&A!==G.current){let E=y4(A),U=h0.isAbsolute(E)?E:h0.resolve(E),M=new Date;if($)process.stderr.write(`[diffstalker ${M.toISOString()}] Path change detected
12
- `),process.stderr.write(` Source file: ${Y}
13
- `),process.stderr.write(` Raw content: "${A}"
14
- `),process.stderr.write(` Previous: "${G.current??"(none)"}"
15
- `),process.stderr.write(` Resolved: "${U}"
16
- `);G.current=U,Q({path:U,lastUpdate:M,rawContent:A,sourceFile:Y,enabled:!0})}}catch{}},100)};try{let N=$8.readFileSync(Y,"utf-8"),A=P4(N);if(A){let E=y4(A),U=h0.isAbsolute(E)?E:h0.resolve(E),M=new Date;if($)process.stderr.write(`[diffstalker ${M.toISOString()}] Initial path read
17
- `),process.stderr.write(` Source file: ${Y}
18
- `),process.stderr.write(` Raw content: "${A}"
19
- `),process.stderr.write(` Resolved: "${U}"
20
- `);G.current=U,Q({path:U,lastUpdate:M,rawContent:A,sourceFile:Y,enabled:!0})}}catch{}let z=$J(Y,{persistent:!0,ignoreInitial:!0});return z.on("change",q),z.on("add",q),()=>{if(V.current)clearTimeout(V.current);z.close()}},[J,Y,$]),{state:K,setEnabled:Z}}import{useState as MX,useEffect as UJ,useCallback as $0,useRef as GJ}from"react";import*as d8 from"node:path";import*as Y9 from"node:fs";import{watch as X9}from"chokidar";import{EventEmitter as VJ}from"node:events";class C4{queue=[];isProcessing=!1;pendingMutations=0;refreshScheduled=!1;enqueue(X){return new Promise((Y,$)=>{this.queue.push({execute:X,resolve:Y,reject:$}),this.processNext()})}enqueueMutation(X){return this.pendingMutations++,this.enqueue(X).finally(()=>{this.pendingMutations--})}hasPendingMutations(){return this.pendingMutations>0}scheduleRefresh(X){if(this.pendingMutations>0)return;if(this.refreshScheduled)return;this.refreshScheduled=!0,this.enqueue(async()=>{this.refreshScheduled=!1,await X()}).catch(()=>{this.refreshScheduled=!1})}isBusy(){return this.isProcessing||this.queue.length>0}async processNext(){if(this.isProcessing||this.queue.length===0)return;this.isProcessing=!0;let X=this.queue.shift();try{let Y=await X.execute();X.resolve(Y)}catch(Y){X.reject(Y instanceof Error?Y:Error(String(Y)))}finally{this.isProcessing=!1,this.processNext()}}}var YY=new Map;function S4(X){let Y=YY.get(X);if(!Y)Y=new C4,YY.set(X,Y);return Y}function b4(X){YY.delete(X)}import{simpleGit as C0}from"simple-git";import*as x4 from"node:fs";import*as p4 from"node:path";function w4(X){let Y=new Map;for(let $ of X.trim().split(`
21
- `)){if(!$)continue;let J=$.split("\t");if(J.length>=3){let Z=J[0]==="-"?0:parseInt(J[0],10),K=J[1]==="-"?0:parseInt(J[1],10),Q=J.slice(2).join("\t");Y.set(Q,{insertions:Z,deletions:K})}}return Y}async function JJ(X,Y){try{let $=p4.join(X,Y);return(await x4.promises.readFile($,"utf-8")).split(`
22
- `).filter((Z)=>Z.length>0).length}catch{return 0}}async function ZJ(X,Y){if(Y.length===0)return new Set;try{let $=new Set,J=100;for(let Z=0;Z<Y.length;Z+=100){let K=Y.slice(Z,Z+100);try{let V=(await X.raw(["check-ignore",...K])).trim().split(`
23
- `).filter((G)=>G.length>0);for(let G of V)$.add(G)}catch{}}return $}catch{return new Set}}function g4(X){switch(X){case"M":return"modified";case"A":return"added";case"D":return"deleted";case"?":return"untracked";case"R":return"renamed";case"C":return"copied";default:return"modified"}}async function u4(X){let Y=C0(X);try{if(!await Y.checkIsRepo())return{files:[],branch:{current:"",ahead:0,behind:0},isRepo:!1};let J=await Y.status(),Z=[];for(let U of J.staged)Z.push({path:U,status:"added",staged:!0});for(let U of J.modified)if(!Z.find((O)=>O.path===U&&O.staged))Z.push({path:U,status:"modified",staged:!1});for(let U of J.deleted)Z.push({path:U,status:"deleted",staged:!1});for(let U of J.not_added)Z.push({path:U,status:"untracked",staged:!1});for(let U of J.renamed)Z.push({path:U.to,originalPath:U.from,status:"renamed",staged:!0});let K=[],Q=new Set,V=J.files.filter((U)=>U.working_dir==="?").map((U)=>U.path),G=await ZJ(Y,V);for(let U of J.files){if(U.index==="!"||U.working_dir==="!"||G.has(U.path))continue;let M=`${U.path}-${U.index!==" "&&U.index!=="?"}`;if(Q.has(M))continue;if(Q.add(M),U.index&&U.index!==" "&&U.index!=="?")K.push({path:U.path,status:g4(U.index),staged:!0});if(U.working_dir&&U.working_dir!==" ")K.push({path:U.path,status:U.working_dir==="?"?"untracked":g4(U.working_dir),staged:!1})}let[q,z]=await Promise.all([Y.diff(["--cached","--numstat"]).catch(()=>""),Y.diff(["--numstat"]).catch(()=>"")]),N=w4(q),A=w4(z);for(let U of K){let M=U.staged?N.get(U.path):A.get(U.path);if(M)U.insertions=M.insertions,U.deletions=M.deletions}let E=K.filter((U)=>U.status==="untracked");if(E.length>0){let U=await Promise.all(E.map((M)=>JJ(X,M.path)));for(let M=0;M<E.length;M++)E[M].insertions=U[M],E[M].deletions=0}return{files:K,branch:{current:J.current||"HEAD",tracking:J.tracking||void 0,ahead:J.ahead,behind:J.behind},isRepo:!0}}catch{return{files:[],branch:{current:"",ahead:0,behind:0},isRepo:!1}}}async function h4(X,Y){await C0(X).add(Y)}async function m4(X,Y){await C0(X).reset(["HEAD","--",Y])}async function f4(X){await C0(X).add("-A")}async function d4(X){await C0(X).reset(["HEAD"])}async function c4(X,Y){await C0(X).checkout(["--",Y])}async function l4(X,Y,$=!1){await C0(X).commit(Y,void 0,$?{"--amend":null}:void 0)}async function n4(X){let Y=C0(X);try{return(await Y.log({n:1})).latest?.message||""}catch{return""}}async function r4(X,Y=50){let $=C0(X);try{return(await $.log({n:Y})).all.map((Z)=>({hash:Z.hash,shortHash:Z.hash.slice(0,7),message:Z.message.split(`
24
- `)[0],author:Z.author_name,date:new Date(Z.date),refs:Z.refs||""}))}catch{return[]}}import{execSync as KJ}from"node:child_process";import{simpleGit as m8}from"simple-git";function QJ(X){let Y=X.match(/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/);if(Y)return{oldStart:parseInt(Y[1],10),newStart:parseInt(Y[2],10)};return null}function AX(X){let Y=X.split(`
25
- `),$=[],J=0,Z=0;for(let K of Y)if(K.startsWith("diff --git")||K.startsWith("index ")||K.startsWith("---")||K.startsWith("+++")||K.startsWith("new file")||K.startsWith("deleted file")||K.startsWith("Binary files")||K.startsWith("similarity index")||K.startsWith("rename from")||K.startsWith("rename to"))$.push({type:"header",content:K});else if(K.startsWith("@@")){let Q=QJ(K);if(Q)J=Q.oldStart,Z=Q.newStart;$.push({type:"hunk",content:K})}else if(K.startsWith("+"))$.push({type:"addition",content:K,newLineNum:Z++});else if(K.startsWith("-"))$.push({type:"deletion",content:K,oldLineNum:J++});else $.push({type:"context",content:K,oldLineNum:J++,newLineNum:Z++});return $}async function f8(X,Y,$=!1){let J=m8(X);try{let Z=[];if($)Z.push("--cached");if(Y)Z.push("--",Y);let K=await J.diff(Z),Q=AX(K);return{raw:K,lines:Q}}catch{return{raw:"",lines:[]}}}async function $Y(X,Y){try{let $=KJ(`cat "${Y}"`,{cwd:X,encoding:"utf-8"}),J=[{type:"header",content:`diff --git a/${Y} b/${Y}`},{type:"header",content:"new file mode 100644"},{type:"header",content:"--- /dev/null"},{type:"header",content:`+++ b/${Y}`}],Z=$.split(`
26
- `);J.push({type:"hunk",content:`@@ -0,0 +1,${Z.length} @@`});let K=1;for(let V of Z)J.push({type:"addition",content:"+"+V,newLineNum:K++});return{raw:J.map((V)=>V.content).join(`
27
- `),lines:J}}catch{return{raw:"",lines:[]}}}async function JY(X){return f8(X,void 0,!0)}async function ZY(X){let Y=m8(X),$=new Set,J=[];try{let Z=await Y.raw(["log","--oneline","--decorate=short","--all","-n","200"]),K=/\(([^)]+)\)/g;for(let Q of Z.split(`
28
- `)){let V=K.exec(Q);if(V){let G=V[1].split(",").map((q)=>q.trim());for(let q of G){if(q.startsWith("HEAD")||q.startsWith("tag:")||!q.includes("/"))continue;let z=q.replace(/^.*-> /,"");if(z.includes("/")&&!$.has(z))$.add(z),J.push(z)}}K.lastIndex=0}if(J.length>0)J.sort((Q,V)=>{let G=Q.split("/").slice(1).join("/"),q=V.split("/").slice(1).join("/"),z=G==="main"||G==="master",N=q==="main"||q==="master";if(z&&!N)return-1;if(!z&&N)return 1;if(z&&N){let A=Q.startsWith("origin/"),E=V.startsWith("origin/");if(A&&!E)return 1;if(!A&&E)return-1}return 0})}catch{}return[...new Set(J)]}async function o4(X){return(await ZY(X))[0]??null}async function KY(X,Y){let $=m8(X),Z=(await $.raw(["merge-base",Y,"HEAD"])).trim(),K=await $.raw(["diff","--numstat",`${Z}...HEAD`]),Q=await $.raw(["diff","--name-status",`${Z}...HEAD`]),V=await $.raw(["diff",`${Z}...HEAD`]),G=K.trim().split(`
29
- `).filter((B)=>B),q=new Map;for(let B of G){let L=B.split("\t");if(L.length>=3){let R=L[0]==="-"?0:parseInt(L[0],10),S=L[1]==="-"?0:parseInt(L[1],10),P=L.slice(2).join("\t");q.set(P,{additions:R,deletions:S})}}let z=Q.trim().split(`
30
- `).filter((B)=>B),N=new Map;for(let B of z){let L=B.split("\t");if(L.length>=2){let R=L[0][0],S=L[L.length-1],P;switch(R){case"A":P="added";break;case"D":P="deleted";break;case"R":P="renamed";break;default:P="modified"}N.set(S,P)}}let A=[],E=V.split(/(?=^diff --git )/m).filter((B)=>B.trim());for(let B of E){let L=B.match(/^diff --git a\/.+ b\/(.+)$/m);if(!L)continue;let R=L[1],S=AX(B),P=q.get(R)||{additions:0,deletions:0},W=N.get(R)||"modified";A.push({path:R,status:W,additions:P.additions,deletions:P.deletions,diff:{raw:B,lines:S}})}let U=0,M=0;for(let B of A)U+=B.additions,M+=B.deletions;let F=(await $.status()).files.length,H=(await $.log({from:Z,to:"HEAD"})).all.map((B)=>({hash:B.hash,shortHash:B.hash.slice(0,7),message:B.message.split(`
31
- `)[0],author:B.author_name,date:new Date(B.date),refs:B.refs||""}));return{baseBranch:Y,stats:{filesChanged:A.length,additions:U,deletions:M},files:A,commits:H,uncommittedCount:F}}async function QY(X,Y){let $=m8(X);try{let J=await $.raw(["show",Y,"--format="]),Z=AX(J);return{raw:J,lines:Z}}catch{return{raw:"",lines:[]}}}async function s4(X,Y){let $=m8(X),J=await KY(X,Y),Z=await $.diff(["--cached","--numstat"]),K=await $.diff(["--numstat"]),Q=await $.diff(["--cached"]),V=await $.diff([]),G=new Map;for(let B of Z.trim().split(`
32
- `).filter((L)=>L)){let L=B.split("\t");if(L.length>=3){let R=L[0]==="-"?0:parseInt(L[0],10),S=L[1]==="-"?0:parseInt(L[1],10),P=L.slice(2).join("\t");G.set(P,{additions:R,deletions:S,staged:!0,unstaged:!1})}}for(let B of K.trim().split(`
33
- `).filter((L)=>L)){let L=B.split("\t");if(L.length>=3){let R=L[0]==="-"?0:parseInt(L[0],10),S=L[1]==="-"?0:parseInt(L[1],10),P=L.slice(2).join("\t"),W=G.get(P);if(W)W.additions+=R,W.deletions+=S,W.unstaged=!0;else G.set(P,{additions:R,deletions:S,staged:!1,unstaged:!0})}}let q=await $.status(),z=new Map;for(let B of q.files)if(B.index==="A"||B.working_dir==="?")z.set(B.path,"added");else if(B.index==="D"||B.working_dir==="D")z.set(B.path,"deleted");else if(B.index==="R")z.set(B.path,"renamed");else z.set(B.path,"modified");let N=[],E=(Q+V).split(/(?=^diff --git )/m).filter((B)=>B.trim()),U=new Set;for(let B of E){let L=B.match(/^diff --git a\/.+ b\/(.+)$/m);if(!L)continue;let R=L[1];if(U.has(R))continue;U.add(R);let S=AX(B),P=G.get(R)||{additions:0,deletions:0},W=z.get(R)||"modified";N.push({path:R,status:W,additions:P.additions,deletions:P.deletions,diff:{raw:B,lines:S},isUncommitted:!0})}let M=new Set(J.files.map((B)=>B.path)),O=[];for(let B of J.files){let L=N.find((R)=>R.path===B.path);if(L)O.push(B),O.push(L);else O.push(B)}for(let B of N)if(!M.has(B.path))O.push(B);let F=0,k=0,H=new Set;for(let B of O){if(!H.has(B.path))H.add(B.path);F+=B.additions,k+=B.deletions}return{baseBranch:J.baseBranch,stats:{filesChanged:H.size,additions:F,deletions:k},files:O,commits:J.commits,uncommittedCount:J.uncommittedCount}}import*as S0 from"node:fs";import*as J8 from"node:path";import*as a4 from"node:os";var BX=J8.join(a4.homedir(),".cache","diffstalker","base-branches.json");function qJ(){let X=J8.dirname(BX);if(!S0.existsSync(X))S0.mkdirSync(X,{recursive:!0})}function i4(){try{if(S0.existsSync(BX))return JSON.parse(S0.readFileSync(BX,"utf-8"))}catch{}return{}}function zJ(X){qJ(),S0.writeFileSync(BX,JSON.stringify(X,null,2)+`
34
- `)}function t4(X){let Y=i4(),$=J8.resolve(X);return Y[$]}function e4(X,Y){let $=i4(),J=J8.resolve(X);$[J]=Y,zJ($)}class $9 extends VJ{repoPath;queue;gitWatcher=null;workingDirWatcher=null;_state={status:null,diff:null,stagedDiff:"",selectedFile:null,isLoading:!1,error:null};_compareState={compareDiff:null,compareBaseBranch:null,compareLoading:!1,compareError:null};_historyState={selectedCommit:null,commitDiff:null};_compareSelectionState={type:null,index:0,diff:null};constructor(X){super();this.repoPath=X,this.queue=S4(X)}get state(){return this._state}get compareState(){return this._compareState}get historyState(){return this._historyState}get compareSelectionState(){return this._compareSelectionState}updateState(X){this._state={...this._state,...X},this.emit("state-change",this._state)}updateCompareState(X){this._compareState={...this._compareState,...X},this.emit("compare-state-change",this._compareState)}updateHistoryState(X){this._historyState={...this._historyState,...X},this.emit("history-state-change",this._historyState)}updateCompareSelectionState(X){this._compareSelectionState={...this._compareSelectionState,...X},this.emit("compare-selection-change",this._compareSelectionState)}startWatching(){let X=d8.join(this.repoPath,".git");if(!Y9.existsSync(X))return;let Y=d8.join(X,"index"),$=d8.join(X,"HEAD"),J=d8.join(X,"refs");this.gitWatcher=X9([Y,$,J],{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}}),this.workingDirWatcher=X9(this.repoPath,{persistent:!0,ignoreInitial:!0,ignored:["**/node_modules/**","**/.git/**","**/dist/**","**/build/**","**/*.log","**/.DS_Store"],awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},depth:10});let Z=()=>this.scheduleRefresh();this.gitWatcher.on("change",Z),this.gitWatcher.on("add",Z),this.gitWatcher.on("unlink",Z),this.workingDirWatcher.on("change",Z),this.workingDirWatcher.on("add",Z),this.workingDirWatcher.on("unlink",Z)}dispose(){this.gitWatcher?.close(),this.workingDirWatcher?.close(),b4(this.repoPath)}scheduleRefresh(){this.queue.scheduleRefresh(()=>this.doRefresh())}async refresh(){await this.queue.enqueue(()=>this.doRefresh())}async doRefresh(){this.updateState({isLoading:!0,error:null});try{let X=await u4(this.repoPath);if(!X.isRepo){this.updateState({status:X,diff:null,stagedDiff:"",isLoading:!1,error:"Not a git repository"});return}let[Y,$]=await Promise.all([JY(this.repoPath),f8(this.repoPath,void 0,!1)]),J,Z=this._state.selectedFile;if(Z){let K=X.files.find((Q)=>Q.path===Z.path&&Q.staged===Z.staged);if(K)if(K.status==="untracked")J=await $Y(this.repoPath,K.path);else J=await f8(this.repoPath,K.path,K.staged);else J=$.raw?$:Y,this.updateState({selectedFile:null})}else if($.raw)J=$;else if(Y.raw)J=Y;else J={raw:"",lines:[]};this.updateState({status:X,diff:J,stagedDiff:Y.raw,isLoading:!1})}catch(X){this.updateState({isLoading:!1,error:X instanceof Error?X.message:"Unknown error"})}}async selectFile(X){if(this.updateState({selectedFile:X}),!this._state.status?.isRepo)return;await this.queue.enqueue(async()=>{if(X){let Y;if(X.status==="untracked")Y=await $Y(this.repoPath,X.path);else Y=await f8(this.repoPath,X.path,X.staged);this.updateState({diff:Y})}else{let Y=await JY(this.repoPath);this.updateState({diff:Y})}})}async stage(X){let Y=this._state.status;if(Y)this.updateState({status:{...Y,files:Y.files.map(($)=>$.path===X.path&&!$.staged?{...$,staged:!0}:$)}});try{await this.queue.enqueueMutation(()=>h4(this.repoPath,X.path)),this.scheduleRefresh()}catch($){await this.refresh(),this.updateState({error:`Failed to stage ${X.path}: ${$ instanceof Error?$.message:String($)}`})}}async unstage(X){let Y=this._state.status;if(Y)this.updateState({status:{...Y,files:Y.files.map(($)=>$.path===X.path&&$.staged?{...$,staged:!1}:$)}});try{await this.queue.enqueueMutation(()=>m4(this.repoPath,X.path)),this.scheduleRefresh()}catch($){await this.refresh(),this.updateState({error:`Failed to unstage ${X.path}: ${$ instanceof Error?$.message:String($)}`})}}async discard(X){if(X.staged||X.status==="untracked")return;try{await this.queue.enqueueMutation(()=>c4(this.repoPath,X.path)),await this.refresh()}catch(Y){this.updateState({error:`Failed to discard ${X.path}: ${Y instanceof Error?Y.message:String(Y)}`})}}async stageAll(){try{await this.queue.enqueueMutation(()=>f4(this.repoPath)),await this.refresh()}catch(X){this.updateState({error:`Failed to stage all: ${X instanceof Error?X.message:String(X)}`})}}async unstageAll(){try{await this.queue.enqueueMutation(()=>d4(this.repoPath)),await this.refresh()}catch(X){this.updateState({error:`Failed to unstage all: ${X instanceof Error?X.message:String(X)}`})}}async commit(X,Y=!1){try{await this.queue.enqueue(()=>l4(this.repoPath,X,Y)),await this.refresh()}catch($){this.updateState({error:`Failed to commit: ${$ instanceof Error?$.message:String($)}`})}}async getHeadCommitMessage(){return this.queue.enqueue(()=>n4(this.repoPath))}async refreshCompareDiff(X=!1){this.updateCompareState({compareLoading:!0,compareError:null});try{await this.queue.enqueue(async()=>{let Y=this._compareState.compareBaseBranch;if(!Y)Y=t4(this.repoPath)??await o4(this.repoPath),this.updateCompareState({compareBaseBranch:Y});if(Y){let $=X?await s4(this.repoPath,Y):await KY(this.repoPath,Y);this.updateCompareState({compareDiff:$,compareLoading:!1})}else this.updateCompareState({compareDiff:null,compareLoading:!1,compareError:"No base branch found"})})}catch(Y){this.updateCompareState({compareLoading:!1,compareError:`Failed to load compare diff: ${Y instanceof Error?Y.message:String(Y)}`})}}async getCandidateBaseBranches(){return ZY(this.repoPath)}async setCompareBaseBranch(X,Y=!1){this.updateCompareState({compareBaseBranch:X}),e4(this.repoPath,X),await this.refreshCompareDiff(Y)}async selectHistoryCommit(X){if(this.updateHistoryState({selectedCommit:X,commitDiff:null}),!X)return;try{await this.queue.enqueue(async()=>{let Y=await QY(this.repoPath,X.hash);this.updateHistoryState({commitDiff:Y})})}catch(Y){this.updateState({error:`Failed to load commit diff: ${Y instanceof Error?Y.message:String(Y)}`})}}async selectCompareCommit(X){let Y=this._compareState.compareDiff;if(!Y||X<0||X>=Y.commits.length){this.updateCompareSelectionState({type:null,index:0,diff:null});return}let $=Y.commits[X];this.updateCompareSelectionState({type:"commit",index:X,diff:null});try{await this.queue.enqueue(async()=>{let J=await QY(this.repoPath,$.hash);this.updateCompareSelectionState({diff:J})})}catch(J){this.updateState({error:`Failed to load commit diff: ${J instanceof Error?J.message:String(J)}`})}}selectCompareFile(X){let Y=this._compareState.compareDiff;if(!Y||X<0||X>=Y.files.length){this.updateCompareSelectionState({type:null,index:0,diff:null});return}let $=Y.files[X];this.updateCompareSelectionState({type:"file",index:X,diff:$.diff})}}var EX=new Map;function J9(X){let Y=EX.get(X);if(!Y)Y=new $9(X),EX.set(X,Y);return Y}function Z9(X){let Y=EX.get(X);if(Y)Y.dispose(),EX.delete(X)}function K9(X){let[Y,$]=MX({status:null,diff:null,stagedDiff:"",selectedFile:null,isLoading:!1,error:null}),[J,Z]=MX({compareDiff:null,compareBaseBranch:null,compareLoading:!1,compareError:null}),[K,Q]=MX({selectedCommit:null,commitDiff:null}),[V,G]=MX({type:null,index:0,diff:null}),q=GJ(null);UJ(()=>{if(!X){$({status:null,diff:null,stagedDiff:"",selectedFile:null,isLoading:!1,error:null});return}let W=J9(X);q.current=W;let C=(p)=>{$(p)},b=(p)=>{Z(p)},w=(p)=>{Q(p)},g=(p)=>{G(p)};return W.on("state-change",C),W.on("compare-state-change",b),W.on("history-state-change",w),W.on("compare-selection-change",g),W.startWatching(),W.refresh(),()=>{W.off("state-change",C),W.off("compare-state-change",b),W.off("history-state-change",w),W.off("compare-selection-change",g),Z9(X),q.current=null}},[X]);let z=$0((W)=>{q.current?.selectFile(W)},[]),N=$0(async(W)=>{await q.current?.stage(W)},[]),A=$0(async(W)=>{await q.current?.unstage(W)},[]),E=$0(async(W)=>{await q.current?.discard(W)},[]),U=$0(async()=>{await q.current?.stageAll()},[]),M=$0(async()=>{await q.current?.unstageAll()},[]),O=$0(async(W,C=!1)=>{await q.current?.commit(W,C)},[]),F=$0(async()=>{await q.current?.refresh()},[]),k=$0(async()=>{return q.current?.getHeadCommitMessage()??""},[]),H=$0(async(W=!1)=>{await q.current?.refreshCompareDiff(W)},[]),B=$0(async()=>{return q.current?.getCandidateBaseBranches()??[]},[]),L=$0(async(W,C=!1)=>{await q.current?.setCompareBaseBranch(W,C)},[]),R=$0(async(W)=>{await q.current?.selectHistoryCommit(W)},[]),S=$0(async(W)=>{await q.current?.selectCompareCommit(W)},[]),P=$0((W)=>{q.current?.selectCompareFile(W)},[]);return{status:Y.status,diff:Y.diff,stagedDiff:Y.stagedDiff,selectedFile:Y.selectedFile,isLoading:Y.isLoading,error:Y.error,selectFile:z,stage:N,unstage:A,discard:E,stageAll:U,unstageAll:M,commit:O,refresh:F,getHeadCommitMessage:k,compareDiff:J.compareDiff,compareBaseBranch:J.compareBaseBranch,compareLoading:J.compareLoading,compareError:J.compareError,refreshCompareDiff:H,getCandidateBaseBranches:B,setCompareBaseBranch:L,historySelectedCommit:K.selectedCommit,historyCommitDiff:K.commitDiff,selectHistoryCommit:R,compareSelectionType:V.type,compareSelectionIndex:V.index,compareSelectionDiff:V.diff,selectCompareCommit:S,selectCompareFile:P}}import{useInput as NJ}from"ink";function Q9(X,Y,$){NJ((J,Z)=>{if($)return;if(Z.ctrl&&J==="c"){X.onQuit();return}if(J==="q"){X.onQuit();return}if(J==="j"||Z.downArrow){X.onNavigateDown();return}if(J==="k"||Z.upArrow){X.onNavigateUp();return}if(Z.tab){X.onTogglePane();return}if(J==="1"){X.onSwitchTab("diff");return}if(J==="2"){X.onSwitchTab("commit");return}if(J==="3"){X.onSwitchTab("history");return}if(J==="4"){X.onSwitchTab("compare");return}if(J==="5"){X.onSwitchTab("explorer");return}if(J==="u"&&X.onToggleIncludeUncommitted){X.onToggleIncludeUncommitted();return}if(J==="b"&&X.onCycleBaseBranch){X.onCycleBaseBranch();return}if(J==="t"&&X.onOpenThemePicker){X.onOpenThemePicker();return}if(J==="?"&&X.onOpenHotkeysModal){X.onOpenHotkeysModal();return}if(J==="["&&X.onShrinkTopPane){X.onShrinkTopPane();return}if(J==="]"&&X.onGrowTopPane){X.onGrowTopPane();return}if(J==="m"&&X.onToggleMouse){X.onToggleMouse();return}if(J==="f"&&X.onToggleFollow){X.onToggleFollow();return}if(J==="a"&&X.onToggleAutoTab){X.onToggleAutoTab();return}if(J==="w"&&X.onToggleWrap){X.onToggleWrap();return}if(J==="."&&X.onToggleMiddleDots){X.onToggleMiddleDots();return}if(Z.ctrl&&J==="h"&&X.onToggleHideHiddenFiles){X.onToggleHideHiddenFiles();return}if(Z.ctrl&&J==="g"&&X.onToggleHideGitignored){X.onToggleHideGitignored();return}if(Z.ctrl&&J==="s"){X.onStage();return}if(Z.ctrl&&J==="u"){X.onUnstage();return}if(Z.ctrl&&J==="a"){X.onStageAll();return}if(Z.ctrl&&J==="z"){X.onUnstageAll();return}if(J==="c"){X.onCommit();return}if(Z.ctrl&&J==="r"){X.onRefresh();return}if(J==="r"){X.onRefresh();return}if(X.onExplorerEnter&&Z.return){X.onExplorerEnter();return}if(X.onExplorerBack&&(Z.backspace||Z.delete||J==="h")){X.onExplorerBack();return}if(Z.return||J===" "){X.onSelect();return}})}import{useEffect as LX,useState as AJ,useCallback as BJ,useRef as q9}from"react";import{useStdin as EJ}from"ink";function z9(X,Y=!1){let{stdin:$,setRawMode:J}=EJ(),[Z,K]=AJ(!0),Q=q9(X);LX(()=>{Q.current=X});let V=BJ(()=>{K((q)=>!q)},[]),G=q9(Z);return LX(()=>{G.current=Z},[Z]),LX(()=>{if(!Y&&Z)process.stdout.write("\x1B[?1000h"),process.stdout.write("\x1B[?1006h");else process.stdout.write("\x1B[?1006l"),process.stdout.write("\x1B[?1000l")},[Y,Z]),LX(()=>{if(!$||!J)return;let q=(z)=>{let N=z.toString(),A=N.match(/\x1b\[<(\d+);(\d+);(\d+)([Mm])/);if(A){let U=parseInt(A[1],10),M=parseInt(A[2],10),O=parseInt(A[3],10),F=A[4]==="m";if(U>=64&&U<96){if(G.current){let k=U===64?"scroll-up":"scroll-down";Q.current({x:M,y:O,type:k,button:"none"})}}else if(F&&U>=0&&U<3){let k=U===0?"left":U===1?"middle":"right";Q.current({x:M,y:O,type:"click",button:k})}return}let E=N.match(/\x1b\[M(.)(.)(.)/);if(E){let U=E[1].charCodeAt(0)-32,M=E[2].charCodeAt(0)-32,O=E[3].charCodeAt(0)-32;if(U>=64){if(G.current){let F=U===64?"scroll-up":"scroll-down";Q.current({x:M,y:O,type:F,button:"none"})}}else if(U>=0&&U<3){let F=U===0?"left":U===1?"middle":"right";Q.current({x:M,y:O,type:"click",button:F})}}};return $.on("data",q),()=>{$.off("data",q),process.stdout.write("\x1B[?1006l"),process.stdout.write("\x1B[?1000l")}},[$,J]),{mouseEnabled:Z,toggleMouse:V}}import{useState as MJ,useEffect as LJ}from"react";function V9(){let[X,Y]=MJ({rows:process.stdout.rows??24,columns:process.stdout.columns??80});return LJ(()=>{let $=()=>{Y({rows:process.stdout.rows??24,columns:process.stdout.columns??80})};return process.stdout.on("resize",$),()=>{process.stdout.off("resize",$)}},[]),X}import{useState as c8,useEffect as qY,useMemo as O9,useCallback as F8}from"react";function U9(X){let{modifiedCount:Y,untrackedCount:$,stagedCount:J}=b8(X),Z=0;if(Y>0)Z+=1+Y;if($>0){if(Y>0)Z+=1;Z+=1+$}if(J>0){if(Y>0||$>0)Z+=1;Z+=1+J}return Z}function G9(X,Y,$,J){let Z=0;if(X<Y)return 1+X;if(Y>0)Z+=1+Y;let K=Y;if(X<K+$){let G=X-K;if(Y>0)Z+=1;return Z+1+G}if($>0){if(Y>0)Z+=1;Z+=1+$}let Q=Y+$,V=X-Q;if(Y>0||$>0)Z+=1;return Z+1+V}function N9(X,Y,$){if(X<Y)return Math.max(0,X-1);else if(X>=Y+$)return X-$+1;return Y}function A9(X,Y,$,J=1){let Z=J+2,K=J+1+X,Q=K+1,V=K+2,G=V+Y-1;return{stagingPaneStart:Z,fileListEnd:K,separatorRow:Q,diffPaneStart:V,diffPaneEnd:G,footerRow:$}}function B9(X,Y,$,J,Z){if(X<J+1||X>Z)return-1;let K=X-(J+1)+Y,{modified:Q,untracked:V,staged:G}=g0($),q=0,z=0;if(Q.length>0){q++;for(let N=0;N<Q.length;N++){if(K===q)return z;q++,z++}}if(V.length>0){if(Q.length>0)q++;q++;for(let N=0;N<V.length;N++){if(K===q)return z;q++,z++}}if(G.length>0){if(Q.length>0||V.length>0)q++;q++;for(let N=0;N<G.length;N++){if(K===q)return z;q++,z++}}return-1}function OJ(X){let Y=X-51;return{diffStart:Y,diffEnd:Y+6,commitStart:Y+8,commitEnd:Y+16,historyStart:Y+18,historyEnd:Y+27,compareStart:Y+29,compareEnd:Y+38,explorerStart:Y+40,explorerEnd:Y+50}}function E9(X,Y){let $=OJ(Y);if(X>=$.diffStart&&X<=$.diffEnd)return"diff";else if(X>=$.commitStart&&X<=$.commitEnd)return"commit";else if(X>=$.historyStart&&X<=$.historyEnd)return"history";else if(X>=$.compareStart&&X<=$.compareEnd)return"compare";else if(X>=$.explorerStart&&X<=$.explorerEnd)return"explorer";return null}function M9(X){return X<=6}function OX(X,Y,$){return X>=Y&&X<=$}function L9(X){if(X===1)return"hotkeys";if(X>=3&&X<=10)return"mouse-mode";if(X>=12&&X<=17)return"auto-tab";if(X>=19&&X<=24)return"wrap";return null}var kJ=5,k9={diff:0.4,commit:0.4,history:0.5,compare:0.5,explorer:0.4},zY=0.05;function W9(X,Y,$,J,Z,K="diff",Q,V,G=0){let q=X-kJ-G,[z,N]=c8(V??null),A=z??k9[K],{topPaneHeight:E,bottomPaneHeight:U}=O9(()=>{let v=q-5,y=Math.floor(q*A),T=Math.max(5,Math.min(y,v)),j=q-T;return{topPaneHeight:T,bottomPaneHeight:j}},[q,A]),M=F8((_)=>{let v=Math.max(0.15,Math.min(0.85,_));N(v)},[]),O=F8((_)=>{let v=z??k9[K],y=Math.max(0.15,Math.min(0.85,v+_));N(y)},[z,K]),F=A,k=G+1,H=O9(()=>A9(E,U,X,k),[E,U,X,k]),[B,L]=c8(0),[R,S]=c8(0),[P,W]=c8(0),[C,b]=c8(0);qY(()=>{L(0)},[$.length]),qY(()=>{S(0)},[Z]),qY(()=>{let{modifiedCount:_,untrackedCount:v,stagedCount:y}=b8($),T=G9(J,_,v,y),j=E-1;L((x)=>{return N9(T,x,j)})},[J,$,E]);let w=F8((_,v=3,y=0)=>{let T=U-1,x=y>T?T-2:T,D=Math.max(0,y-x);S((y8)=>{if(_==="up")return Math.max(0,y8-v);else return Math.min(D,y8+v)})},[U]),g=F8((_,v=3)=>{let y=U9($),T=E-1,j=Math.max(0,y-T);L((x)=>{if(_==="up")return Math.max(0,x-v);else return Math.min(j,x+v)})},[$,E]),p=F8((_,v=0,y=3)=>{let T=E8(v,E-1);W((j)=>{if(_==="up")return Math.max(0,j-y);else return Math.min(T,j+y)})},[E]),f=F8((_,v,y=3)=>{let T=E8(v,E-1);b((j)=>{if(_==="up")return Math.max(0,j-y);else return Math.min(T,j+y)})},[E]);return{topPaneHeight:E,bottomPaneHeight:U,contentHeight:q,paneBoundaries:H,splitRatio:F,setSplitRatio:M,adjustSplitRatio:O,fileListScrollOffset:B,diffScrollOffset:R,historyScrollOffset:P,compareScrollOffset:C,setFileListScrollOffset:L,setDiffScrollOffset:S,setHistoryScrollOffset:W,setCompareScrollOffset:b,scrollDiff:w,scrollFileList:g,scrollHistory:p,scrollCompare:f}}import{useState as H9,useEffect as I9,useCallback as F9,useMemo as R9}from"react";function D9({repoPath:X,isActive:Y,selectHistoryCommit:$,historyCommitDiff:J,historySelectedCommit:Z,topPaneHeight:K,historyScrollOffset:Q,setHistoryScrollOffset:V,setDiffScrollOffset:G,status:q,wrapMode:z,terminalWidth:N}){let[A,E]=H9([]),[U,M]=H9(0);I9(()=>{if(X&&Y)r4(X,100).then(E)},[X,Y,q]),I9(()=>{if(Y&&A.length>0){let B=A[U];if(B)$(B),G(0)}},[Y,A,U,$,G]);let O=R9(()=>{let B=GX(Z,J);if(!z)return B.length;let L=R0(B),R=N-L-5;return L8(B,R,!0)},[Z,J,z,N]),F=R9(()=>A.length,[A]),k=F9(()=>{M((B)=>{let L=Math.max(0,B-1);if(L<Q)V(L);return L})},[Q,V]),H=F9(()=>{M((B)=>{let L=Math.min(A.length-1,B+1),R=Q+K-2;if(L>=R)V(Q+1);return L})},[A.length,Q,K,V]);return{commits:A,historySelectedIndex:U,setHistorySelectedIndex:M,historyDiffTotalRows:O,navigateHistoryUp:k,navigateHistoryDown:H,historyTotalRows:F}}import{useState as l8,useEffect as kX,useCallback as m0,useMemo as _9,useRef as WJ}from"react";function v9({repoPath:X,isActive:Y,compareDiff:$,refreshCompareDiff:J,getCandidateBaseBranches:Z,setCompareBaseBranch:K,selectCompareCommit:Q,topPaneHeight:V,compareScrollOffset:G,setCompareScrollOffset:q,setDiffScrollOffset:z,status:N,wrapMode:A,terminalWidth:E}){let[U,M]=l8(!0),[O,F]=l8(null),[k,H]=l8(0),B=WJ(!1),[L,R]=l8([]),[S,P]=l8(!1);kX(()=>{if(X&&Y)J(U)},[X,Y,N,J,U]),kX(()=>{if(X&&Y)Z().then(R)},[X,Y,Z]),kX(()=>{if(Y)B.current=!1,F(null),z(0)},[Y,z]),kX(()=>{if(Y&&$&&B.current){let T=$.commits.length,j=$.files.length;if(k<T)F({type:"commit",index:k}),Q(k),z(0);else if(k<T+j){let x=k-T;F({type:"file",index:x});let D=aY($,x);z(D)}}},[Y,$,k,Q,z]);let W=_9(()=>{if(!$)return 0;return $.commits.length+$.files.length},[$]),C=_9(()=>{let T=NX($);if(!A)return T.length;let j=R0(T),x=E-j-5;return L8(T,x,!0)},[$,A,E]),b=m0(()=>{M((T)=>!T)},[]),w=m0(()=>{P(!0)},[]),g=m0(()=>{P(!1)},[]),p=m0((T)=>{P(!1),K(T,U)},[K,U]),f=m0(()=>{B.current=!0},[]),_=m0(()=>{B.current=!0,H((T)=>{let j=Math.max(0,T-1);if(j<G)q(j);return j})},[G,q]),v=m0(()=>{B.current=!0,H((T)=>{let j=Math.min(W-1,T+1),x=G+V-2;if(j>=x)q(G+1);return j})},[W,G,V,q]),y=m0((T)=>{if(!$)return-1;return lX(T,$.commits.length,$.files.length)},[$]);return{includeUncommitted:U,compareListSelection:O,compareSelectedIndex:k,baseBranchCandidates:L,showBaseBranchPicker:S,compareTotalItems:W,compareDiffTotalRows:C,setCompareSelectedIndex:H,toggleIncludeUncommitted:b,openBaseBranchPicker:w,closeBaseBranchPicker:g,selectBaseBranch:p,navigateCompareUp:_,navigateCompareDown:v,markSelectionInitialized:f,getItemIndexFromRow:y}}import{useState as R8,useEffect as j9,useCallback as WX,useMemo as HJ}from"react";import*as HX from"node:fs";import*as D0 from"node:path";import{simpleGit as IJ}from"simple-git";var FJ=1048576,RJ=102400;function DJ(X){let Y=Math.min(X.length,8192);for(let $=0;$<Y;$++)if(X[$]===0)return!0;return!1}async function _J(X,Y){if(Y.length===0)return new Set;let $=IJ(X),J=new Set,Z=100;for(let K=0;K<Y.length;K+=Z){let Q=Y.slice(K,K+Z);try{let G=(await $.raw(["check-ignore",...Q])).trim().split(`
35
- `).filter((q)=>q.length>0);for(let q of G)J.add(q)}catch{}}return J}function y9({repoPath:X,isActive:Y,topPaneHeight:$,explorerScrollOffset:J,setExplorerScrollOffset:Z,fileScrollOffset:K,setFileScrollOffset:Q,hideHiddenFiles:V,hideGitignored:G}){let[q,z]=R8(""),[N,A]=R8([]),[E,U]=R8(0),[M,O]=R8(null),[F,k]=R8(!1),[H,B]=R8(null);j9(()=>{if(!Y||!X)return;(async()=>{k(!0),B(null);try{let b=D0.join(X,q),w=await HX.promises.readdir(b,{withFileTypes:!0}),g=w.map((_)=>q?D0.join(q,_.name):_.name),p=G?await _J(X,g):new Set,f=w.filter((_)=>{if(V&&_.name.startsWith("."))return!1;if(G){let v=q?D0.join(q,_.name):_.name;if(p.has(v))return!1}return!0}).map((_)=>({name:_.name,path:q?D0.join(q,_.name):_.name,isDirectory:_.isDirectory()}));if(f.sort((_,v)=>{if(_.isDirectory&&!v.isDirectory)return-1;if(!_.isDirectory&&v.isDirectory)return 1;return _.name.localeCompare(v.name)}),q)f.unshift({name:"..",path:D0.dirname(q)||"",isDirectory:!0});A(f),U(0),Z(0)}catch(b){B(b instanceof Error?b.message:"Failed to read directory"),A([])}finally{k(!1)}})()},[X,q,Y,Z,V,G]),j9(()=>{if(!Y||!X||N.length===0){O(null);return}let C=N[E];if(!C||C.isDirectory){O(null);return}(async()=>{try{let w=D0.join(X,C.path),g=await HX.promises.stat(w);if(g.size>FJ){O({path:C.path,content:`File too large to display (${(g.size/1024/1024).toFixed(2)} MB).
36
- Maximum size: 1 MB`,truncated:!0});return}let p=await HX.promises.readFile(w);if(DJ(p)){O({path:C.path,content:"Binary file - cannot display"});return}let f=p.toString("utf-8"),_=!1;if(g.size>RJ)f=`⚠ Large file (${(g.size/1024).toFixed(1)} KB)
2
+ import G8 from"neo-blessed";import o from"neo-blessed";var MK=0.05;function k8(K,$,J,X=1){let Z=X+4,Q=K-Z,q=Math.floor(Q*J),Y=Q-q;return{width:$,height:K,headerHeight:X,topPaneHeight:q,bottomPaneHeight:Y,footerRow:K-1}}function j8(K,$,J,X){let Z=$+1,Q=Z+J,q=Q+1,Y=q+X,V=K-1;return{stagingPaneStart:Z,fileListEnd:Q,diffPaneStart:q,diffPaneEnd:Y,footerRow:V}}class OK{screen;headerBox;topSeparator;topPane;middleSeparator;bottomPane;bottomSeparator;footerBox;_dimensions;_splitRatio;constructor(K,$=0.4){this.screen=K,this._splitRatio=$,this._dimensions=this.calculateDimensions(),this.headerBox=this.createHeaderBox(),this.topSeparator=this.createSeparator(this._dimensions.headerHeight),this.topPane=this.createTopPane(),this.middleSeparator=this.createSeparator(this._dimensions.headerHeight+1+this._dimensions.topPaneHeight),this.bottomPane=this.createBottomPane(),this.bottomSeparator=this.createSeparator(this._dimensions.headerHeight+2+this._dimensions.topPaneHeight+this._dimensions.bottomPaneHeight),this.footerBox=this.createFooterBox(),K.on("resize",()=>this.onResize())}get dimensions(){return this._dimensions}get splitRatio(){return this._splitRatio}setSplitRatio(K){this._splitRatio=Math.min(0.85,Math.max(0.15,K)),this.updateLayout()}adjustSplitRatio(K){this.setSplitRatio(this._splitRatio+K)}calculateDimensions(){let K=this.screen.height||24,$=this.screen.width||80;return k8(K,$,this._splitRatio)}createHeaderBox(){return o.box({parent:this.screen,top:0,left:0,width:"100%",height:this._dimensions.headerHeight,tags:!0})}createSeparator(K){let $=this.screen.width||80;return o.box({parent:this.screen,top:K,left:0,width:"100%",height:1,content:"─".repeat($),style:{fg:"gray"}})}createTopPane(){return o.box({parent:this.screen,top:this._dimensions.headerHeight+1,left:0,width:"100%",height:this._dimensions.topPaneHeight,tags:!0,scrollable:!0,alwaysScroll:!0,wrap:!1,scrollbar:{ch:" ",track:{bg:"gray"},style:{inverse:!0}}})}createBottomPane(){return o.box({parent:this.screen,top:this._dimensions.headerHeight+2+this._dimensions.topPaneHeight,left:0,width:"100%",height:this._dimensions.bottomPaneHeight,tags:!0,scrollable:!0,alwaysScroll:!0,wrap:!1,scrollbar:{ch:" ",track:{bg:"gray"},style:{inverse:!0}}})}createFooterBox(){return o.box({parent:this.screen,top:this._dimensions.footerRow,left:0,width:"100%",height:1,tags:!0})}onResize(){this._dimensions=this.calculateDimensions(),this.updateLayout()}updateLayout(){this._dimensions=this.calculateDimensions();let K=this.screen.width||80;this.headerBox.height=this._dimensions.headerHeight,this.headerBox.width=K,this.topSeparator.top=this._dimensions.headerHeight,this.topSeparator.width=K,this.topSeparator.setContent("".repeat(K)),this.topPane.top=this._dimensions.headerHeight+1,this.topPane.height=this._dimensions.topPaneHeight,this.topPane.width=K,this.middleSeparator.top=this._dimensions.headerHeight+1+this._dimensions.topPaneHeight,this.middleSeparator.width=K,this.middleSeparator.setContent("─".repeat(K)),this.bottomPane.top=this._dimensions.headerHeight+2+this._dimensions.topPaneHeight,this.bottomPane.height=this._dimensions.bottomPaneHeight,this.bottomPane.width=K,this.bottomSeparator.top=this._dimensions.headerHeight+2+this._dimensions.topPaneHeight+this._dimensions.bottomPaneHeight,this.bottomSeparator.width=K,this.bottomSeparator.setContent("─".repeat(K)),this.footerBox.top=this._dimensions.footerRow,this.footerBox.width=K}getPaneBoundaries(){return j8(this._dimensions.height,this._dimensions.headerHeight,this._dimensions.topPaneHeight,this._dimensions.bottomPaneHeight)}screenYToTopPaneRow(K){let $=this._dimensions.headerHeight+1,J=$+this._dimensions.topPaneHeight;if(K<$||K>=J)return-1;return K-$}screenYToBottomPaneRow(K){let $=this._dimensions.headerHeight+2+this._dimensions.topPaneHeight,J=$+this._dimensions.bottomPaneHeight;if(K<$||K>=J)return-1;return K-$}get topPaneTop(){return this._dimensions.headerHeight+1}get bottomPaneTop(){return this._dimensions.headerHeight+2+this._dimensions.topPaneHeight}}import*as F from"node:fs";import*as c from"node:path";import*as t from"node:os";var M8={targetFile:c.join(t.homedir(),".cache","diffstalker","target"),watcherEnabled:!1,debug:!1,theme:"dark"},h=c.join(t.homedir(),".config","diffstalker","config.json"),O8=["dark","light","dark-colorblind","light-colorblind","dark-ansi","light-ansi"];function N8(K){return typeof K==="string"&&O8.includes(K)}function $7(){let K={...M8};if(process.env.DIFFSTALKER_PAGER)K.pager=process.env.DIFFSTALKER_PAGER;if(F.existsSync(h))try{let $=JSON.parse(F.readFileSync(h,"utf-8"));if($.pager)K.pager=$.pager;if($.targetFile)K.targetFile=$.targetFile;if(N8($.theme))K.theme=$.theme;if(typeof $.splitRatio==="number"&&$.splitRatio>=0.15&&$.splitRatio<=0.85)K.splitRatio=$.splitRatio}catch{}return K}function NK(K){let $=c.dirname(h);if(!F.existsSync($))F.mkdirSync($,{recursive:!0});let J={};if(F.existsSync(h))try{J=JSON.parse(F.readFileSync(h,"utf-8"))}catch{}Object.assign(J,K),F.writeFileSync(h,JSON.stringify(J,null,2)+`
3
+ `)}function J7(K){let $=c.dirname(K);if(!F.existsSync($))F.mkdirSync($,{recursive:!0})}function e(K){let $=t.homedir();if(K.startsWith($))return"~"+K.slice($.length);return K}function H8(K){let $=`{bold}{green-fg}${K.current}{/green-fg}{/bold}`;if(K.tracking)$+=` {gray-fg}{/gray-fg} {blue-fg}${K.tracking}{/blue-fg}`;if(K.ahead>0)$+=` {green-fg}↑${K.ahead}{/green-fg}`;if(K.behind>0)$+=` {red-fg}↓${K.behind}{/red-fg}`;return $}function X7(K,$,J,X,Z,Q){if(!K)return"{gray-fg}Waiting for target path...{/gray-fg}";let q=e(K),Y=X==="Not a git repository",V=`{bold}{cyan-fg}${q}{/cyan-fg}{/bold}`;if(J)V+=" {yellow-fg}⟳{/yellow-fg}";if(Y)V+=" {yellow-fg}(not a git repository){/yellow-fg}";else if(X)V+=` {red-fg}(${X}){/red-fg}`;if(Z?.enabled&&Z.sourceFile){let z=e(Z.sourceFile);V+=` {gray-fg}(follow: ${z}){/gray-fg}`}let _=$?H8($):"";if(_){let z=q.length;if(J)z+=2;if(Y)z+=24;else if(X)z+=X.length+3;if(Z?.enabled&&Z.sourceFile){let k=e(Z.sourceFile);z+=10+k.length}let U=$?$.current.length+($.tracking?3+$.tracking.length:0)+($.ahead>0?3+String($.ahead).length:0)+($.behind>0?3+String($.behind).length:0):0,B=Math.max(1,Q-z-U-2);return V+" ".repeat(B)+_}return V}function Z7(K){return K.replace(/\{[^}]+\}/g,"").length}function Q7(K,$,J,X,Z,Q){let q="{gray-fg}?{/gray-fg} ";if(q+=$?"{yellow-fg}[scroll]{/yellow-fg}":"{yellow-fg}m:[select]{/yellow-fg}",q+=" ",q+=J?"{blue-fg}[auto]{/blue-fg}":"{gray-fg}[auto]{/gray-fg}",q+=" ",q+=X?"{blue-fg}[wrap]{/blue-fg}":"{gray-fg}[wrap]{/gray-fg}",K==="explorer")q+=" ",q+=Z?"{blue-fg}[dots]{/blue-fg}":"{gray-fg}[dots]{/gray-fg}";let V=[{key:"1",label:"Diff",tab:"diff"},{key:"2",label:"Commit",tab:"commit"},{key:"3",label:"History",tab:"history"},{key:"4",label:"Compare",tab:"compare"},{key:"5",label:"Explorer",tab:"explorer"}].map(({key:B,label:k,tab:G})=>{if(K===G)return`{bold}{cyan-fg}[${B}]${k}{/cyan-fg}{/bold}`;return`[${B}]${k}`}).join(" "),_=Z7(q),z=Z7(V),U=Math.max(1,Q-_-z);return q+" ".repeat(U)+V}function HK(K){let $=K.filter((Z)=>!Z.staged&&Z.status!=="untracked"),J=K.filter((Z)=>!Z.staged&&Z.status==="untracked"),X=K.filter((Z)=>Z.staged);return{modified:$,untracked:J,staged:X,ordered:[...$,...J,...X]}}function r(K,$){if(K.length<=$)return K;let X=Math.max($,20);if(K.length<=X)return K;let Z=K.split("/");if(Z.length===1){let U=Math.floor((X-1)/2);return K.slice(0,U)+"…"+K.slice(-(X-U-1))}let Q=Z[Z.length-1],q=Z[0],Y="/…/";if(q.length+Y.length+Q.length>X){let U=X-2;if(Q.length>U){let B=Math.floor((U-1)/2);return"…/"+Q.slice(0,B)+"…"+Q.slice(-(U-B-1))}return"…/"+Q}let _=q,z=1;while(z<Z.length-1){let U=Z[z],B=_+"/"+U;if(B.length+Y.length+Q.length<=X)_=B,z++;else break}if(z===Z.length-1)return K;return _+Y+Q}function T8(K){switch(K){case"modified":return"M";case"added":return"A";case"deleted":return"D";case"untracked":return"?";case"renamed":return"R";case"copied":return"C";default:return" "}}function E8(K){switch(K){case"modified":return"yellow";case"added":return"green";case"deleted":return"red";case"untracked":return"gray";case"renamed":return"blue";case"copied":return"cyan";default:return"white"}}function I8(K,$){if(K===void 0&&$===void 0)return"";let J=[];if(K!==void 0&&K>0)J.push(`{green-fg}+${K}{/green-fg}`);if($!==void 0&&$>0)J.push(`{red-fg}-${$}{/red-fg}`);return J.length>0?" "+J.join(" "):""}function KK(K){let{modified:$,untracked:J,staged:X}=HK(K),Z=[],Q=0;if($.length>0)Z.push({type:"header",content:"Modified:",headerColor:"yellow"}),$.forEach((q)=>{Z.push({type:"file",file:q,fileIndex:Q++})});if(J.length>0){if($.length>0)Z.push({type:"spacer"});Z.push({type:"header",content:"Untracked:",headerColor:"gray"}),J.forEach((q)=>{Z.push({type:"file",file:q,fileIndex:Q++})})}if(X.length>0){if($.length>0||J.length>0)Z.push({type:"spacer"});Z.push({type:"header",content:"Staged:",headerColor:"green"}),X.forEach((q)=>{Z.push({type:"file",file:q,fileIndex:Q++})})}return Z}function q7(K,$,J,X,Z=0,Q){if(K.length===0)return"{gray-fg} No changes{/gray-fg}";let q=KK(K),Y=X-12,V=Q?q.slice(Z,Z+Q):q.slice(Z),_=[];for(let z of V)if(z.type==="header")_.push(`{bold}{${z.headerColor}-fg}${z.content}{/${z.headerColor}-fg}{/bold}`);else if(z.type==="spacer")_.push("");else if(z.type==="file"&&z.file&&z.fileIndex!==void 0){let U=z.file,k=z.fileIndex===$&&J,G=T8(U.status),M=E8(U.status),T=U.staged?"[-]":"[+]",N=U.staged?"red":"green",H=I8(U.insertions,U.deletions),E=H.replace(/\{[^}]+\}/g,"").length,A=Y-E,j=r(U.path,A),O="";if(k)O+="{cyan-fg}{bold}{/bold}{/cyan-fg}";else O+=" ";if(O+=`{${N}-fg}${T}{/${N}-fg} `,O+=`{${M}-fg}${G}{/${M}-fg} `,k)O+=`{cyan-fg}{inverse}${j}{/inverse}{/cyan-fg}`;else O+=j;if(U.originalPath)O+=` {gray-fg} ${r(U.originalPath,30)}{/gray-fg}`;O+=H,_.push(O)}return _.join(`
4
+ `)}function Y7(K){return KK(K).length}function z7(K,$){let{ordered:J}=HK(K);return J[$]??null}function V7(K,$){let X=KK($)[K];if(X?.type==="file"&&X.fileIndex!==void 0)return X.fileIndex;return null}function TK(K,$){let J=KK($);for(let X=0;X<J.length;X++)if(J[X].type==="file"&&J[X].fileIndex===K)return X;return 0}var D8={name:"dark",displayName:"Dark",colors:{addBg:"#022800",delBg:"#3D0100",addHighlight:"#044700",delHighlight:"#5C0200",text:"white",addLineNum:"#368F35",delLineNum:"#A14040",contextLineNum:"gray",addSymbol:"greenBright",delSymbol:"redBright"}},R8={name:"light",displayName:"Light",colors:{addBg:"#69db7c",delBg:"#ffa8b4",addHighlight:"#2f9d44",delHighlight:"#d1454b",text:"black",addLineNum:"#2f9d44",delLineNum:"#d1454b",contextLineNum:"#6c757d",addSymbol:"green",delSymbol:"red"}},F8={name:"dark-colorblind",displayName:"Dark (colorblind)",colors:{addBg:"#004466",delBg:"#660000",addHighlight:"#0077b3",delHighlight:"#b30000",text:"white",addLineNum:"#0077b3",delLineNum:"#b30000",contextLineNum:"gray",addSymbol:"cyanBright",delSymbol:"redBright"}},v8={name:"light-colorblind",displayName:"Light (colorblind)",colors:{addBg:"#99ccff",delBg:"#ffcccc",addHighlight:"#3366cc",delHighlight:"#993333",text:"black",addLineNum:"#3366cc",delLineNum:"#993333",contextLineNum:"#6c757d",addSymbol:"blue",delSymbol:"red"}},L8={name:"dark-ansi",displayName:"Dark (ANSI)",colors:{addBg:"green",delBg:"red",addHighlight:"greenBright",delHighlight:"redBright",text:"white",addLineNum:"greenBright",delLineNum:"redBright",contextLineNum:"gray",addSymbol:"greenBright",delSymbol:"redBright"}},W8={name:"light-ansi",displayName:"Light (ANSI)",colors:{addBg:"green",delBg:"red",addHighlight:"greenBright",delHighlight:"redBright",text:"black",addLineNum:"green",delLineNum:"red",contextLineNum:"gray",addSymbol:"green",delSymbol:"red"}},$K={dark:D8,light:R8,"dark-colorblind":F8,"light-colorblind":v8,"dark-ansi":L8,"light-ansi":W8},C=["dark","light","dark-colorblind","light-colorblind","dark-ansi","light-ansi"];function s(K){return $K[K]??$K.dark}function JK(K){let J=new Date().getTime()-K.getTime(),X=Math.floor(J/3600000),Z=Math.floor(J/86400000);if(X<1)return`${Math.floor(J/60000)}m ago`;else if(X<48)return`${X}h ago`;else if(Z<=14)return`${Z}d ago`;else return K.toLocaleDateString("en-US",{month:"short",day:"numeric"})}function U7(K){return K.toLocaleString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function y8(K){return!(K.startsWith("index ")||K.startsWith("--- ")||K.startsWith("+++ ")||K.startsWith("similarity index"))}function _7(K){if(K.type!=="header")return!0;return y8(K.content)}function XK(K,$,J=!0){if($<=0)return[{text:K,isContinuation:!1}];if(K.length<=$)return[{text:K,isContinuation:!1}];let X=[],Z=K,Q=!0;while(Z.length>0){if(Z.length<=$){X.push({text:Z,isContinuation:!Q});break}X.push({text:Z.slice(0,$),isContinuation:!Q}),Z=Z.slice($),Q=!1}if(J)S8(K,$,X);return X}function S8(K,$,J){let X=J.map((Z)=>Z.text).join("");if(X!==K)throw Error(`[LineBreaking] Content was lost during breaking!
5
+ Original (${K.length} chars): "${K.slice(0,50)}${K.length>50?"...":""}"
6
+ Joined (${X.length} chars): "${X.slice(0,50)}${X.length>50?"...":""}"`);for(let Z=0;Z<J.length;Z++){let Q=J[Z];if(Q.text.length>$&&$>=1)throw Error(`[LineBreaking] Segment ${Z} exceeds maxWidth!
7
+ Segment length: ${Q.text.length}, maxWidth: ${$}
8
+ Segment: "${Q.text.slice(0,50)}${Q.text.length>50?"...":""}"`)}if(J.length>0&&J[0].isContinuation)throw Error("[LineBreaking] First segment incorrectly marked as continuation!");for(let Z=1;Z<J.length;Z++)if(!J[Z].isContinuation)throw Error(`[LineBreaking] Segment ${Z} should be marked as continuation but isn't!`)}function EK(K,$){if($<=0)return 1;if(K.length<=$)return 1;return Math.ceil(K.length/$)}import d from"fast-diff";function B7(K,$){if(!K||!$)return!1;let J=d(K,$),X=0,Z=0;for(let[q,Y]of J)if(Z+=Y.length,q===d.EQUAL)X+=Y.length;if(Z===0)return!1;return X/Z>=0.5}function G7(K,$){let J=d(K,$),X=[],Z=[];for(let[Q,q]of J)if(Q===d.EQUAL)X.push({text:q,type:"same"}),Z.push({text:q,type:"same"});else if(Q===d.DELETE)X.push({text:q,type:"changed"});else if(Q===d.INSERT)Z.push({text:q,type:"changed"});return{oldSegments:X,newSegments:Z}}import{createEmphasize as P8}from"emphasize";import{common as C8}from"lowlight";var DK=P8(C8),b8={ts:"typescript",tsx:"typescript",js:"javascript",jsx:"javascript",mjs:"javascript",cjs:"javascript",html:"xml",htm:"xml",xml:"xml",svg:"xml",css:"css",scss:"scss",sass:"scss",less:"less",json:"json",yaml:"yaml",yml:"yaml",toml:"ini",sh:"bash",bash:"bash",zsh:"bash",fish:"bash",ps1:"powershell",bat:"dos",cmd:"dos",c:"c",h:"c",cpp:"cpp",hpp:"cpp",cc:"cpp",cxx:"cpp",rs:"rust",go:"go",zig:"zig",java:"java",kt:"kotlin",kts:"kotlin",scala:"scala",groovy:"groovy",gradle:"groovy",py:"python",rb:"ruby",pl:"perl",lua:"lua",php:"php",r:"r",hs:"haskell",ml:"ocaml",fs:"fsharp",fsx:"fsharp",ex:"elixir",exs:"elixir",erl:"erlang",clj:"clojure",cljs:"clojure",cs:"csharp",vb:"vbnet",md:"markdown",markdown:"markdown",rst:"plaintext",txt:"plaintext",Makefile:"makefile",Dockerfile:"dockerfile",cmake:"cmake",ini:"ini",conf:"ini",cfg:"ini",sql:"sql",vim:"vim",diff:"diff",patch:"diff"},A7={Makefile:"makefile",makefile:"makefile",GNUmakefile:"makefile",Dockerfile:"dockerfile",dockerfile:"dockerfile",Jenkinsfile:"groovy",Vagrantfile:"ruby",Gemfile:"ruby",Rakefile:"ruby",".gitignore":"plaintext",".gitattributes":"plaintext",".editorconfig":"ini",".prettierrc":"json",".eslintrc":"json","tsconfig.json":"json","package.json":"json","package-lock.json":"json","bun.lockb":"plaintext","yarn.lock":"yaml","pnpm-lock.yaml":"yaml","Cargo.toml":"ini","Cargo.lock":"ini","go.mod":"go","go.sum":"plaintext"},IK=null;function k7(){if(!IK)IK=new Set(DK.listLanguages());return IK}function ZK(K){if(!K)return null;let $=K.split("/").pop()??"";if(A7[$]){let Z=A7[$];return k7().has(Z)?Z:null}let J=$.includes(".")?$.split(".").pop()?.toLowerCase():null;if(!J)return null;let X=b8[J];if(!X)return null;return k7().has(X)?X:null}function j7(K,$){if(!K||!$)return K;try{return DK.highlight($,K).value}catch{return K}}function RK(K,$){if(!$||K.length===0)return K;try{let J=K.join(`
9
+ `);return DK.highlight($,J).value.replace(/\x1b\[0m/g,"\x1B[39m").split(`
10
+ `)}catch{return K}}function b(K){let $;if(K.type==="addition"||K.type==="deletion")$=K.content.slice(1);else if(K.type==="context")$=K.content.startsWith(" ")?K.content.slice(1):K.content;else $=K.content;return $.replace(/[\x00-\x08\x0a-\x1f\x7f]/g,"").replace(/\t/g," ")}function M7(K){switch(K.type){case"header":return{type:"diff-header",content:K.content};case"hunk":return{type:"diff-hunk",content:K.content};case"addition":return{type:"diff-add",lineNum:K.newLineNum,content:b(K)};case"deletion":return{type:"diff-del",lineNum:K.oldLineNum,content:b(K)};case"context":return{type:"diff-context",lineNum:K.oldLineNum??K.newLineNum,content:b(K)}}}function x8(K){let $=K.match(/^diff --git a\/.+ b\/(.+)$/);return $?$[1]:null}function FK(K){if(!K)return[];let $=K.lines.filter(_7),J=[],X=[],Z=null,Q=0;while(Q<$.length){let q=$[Q];if(q.type==="header"){let B=x8(q.content);if(B){if(Z)X.push(Z),J.push({type:"spacer"});Z={language:ZK(B),startRowIndex:J.length,oldContent:[],oldRowIndices:[],newContent:[],newRowIndices:[]}}J.push(M7(q)),Q++;continue}if(q.type==="hunk"){J.push(M7(q)),Q++;continue}if(q.type==="context"){let B=b(q),k=J.length;if(J.push({type:"diff-context",lineNum:q.oldLineNum??q.newLineNum,content:B}),Z&&Z.language)Z.oldContent.push(B),Z.oldRowIndices.push(k),Z.newContent.push(B),Z.newRowIndices.push(k);Q++;continue}let Y=[];while(Q<$.length&&$[Q].type==="deletion")Y.push($[Q]),Q++;let V=[];while(Q<$.length&&$[Q].type==="addition")V.push($[Q]),Q++;let _=new Map,z=new Map,U=Math.min(Y.length,V.length);for(let B=0;B<U;B++){let k=b(Y[B]),G=b(V[B]);if(B7(k,G)){let{oldSegments:M,newSegments:T}=G7(k,G);_.set(B,M),z.set(B,T)}}for(let B=0;B<Y.length;B++){let k=Y[B],G=b(k),M=_.get(B),T=J.length;if(J.push({type:"diff-del",lineNum:k.oldLineNum,content:G,...M&&{wordDiffSegments:M}}),Z&&Z.language&&!M)Z.oldContent.push(G),Z.oldRowIndices.push(T)}for(let B=0;B<V.length;B++){let k=V[B],G=b(k),M=z.get(B),T=J.length;if(J.push({type:"diff-add",lineNum:k.newLineNum,content:G,...M&&{wordDiffSegments:M}}),Z&&Z.language&&!M)Z.newContent.push(G),Z.newRowIndices.push(T)}}if(Z)X.push(Z);for(let q of X){if(!q.language)continue;if(q.oldContent.length>0){let Y=RK(q.oldContent,q.language);for(let V=0;V<q.oldRowIndices.length;V++){let _=q.oldRowIndices[V],z=J[_],U=Y[V];if(U&&U!==z.content&&(z.type==="diff-del"||z.type==="diff-context"))z.highlighted=U}}if(q.newContent.length>0){let Y=RK(q.newContent,q.language);for(let V=0;V<q.newRowIndices.length;V++){let _=q.newRowIndices[V],z=J[_],U=Y[V];if(U&&U!==z.content&&(z.type==="diff-add"||z.type==="diff-context"))z.highlighted=U}}}return J}function O7(K,$){let J=[];if(K){J.push({type:"commit-header",content:`commit ${K.hash}`}),J.push({type:"commit-header",content:`Author: ${K.author}`}),J.push({type:"commit-header",content:`Date: ${U7(K.date)}`}),J.push({type:"spacer"});for(let X of K.message.split(`
11
+ `))J.push({type:"commit-message",content:` ${X}`});J.push({type:"spacer"})}return J.push(...FK($)),J}function vK(K){let $=0;for(let J of K)if("lineNum"in J&&J.lineNum!==void 0)$=Math.max($,J.lineNum);return Math.max(3,String($).length)}function LK(K,$,J){if(!J)return K;let Z=Math.max(10,$),Q=[];for(let q of K)if(q.type==="diff-add"||q.type==="diff-del"||q.type==="diff-context"){let Y=q.content;if(!Y||Y.length<=Z){Q.push(q);continue}let V=XK(Y,Z);for(let _=0;_<V.length;_++){let z=V[_];Q.push({...q,content:z.text,lineNum:z.isContinuation?void 0:q.lineNum,isContinuation:z.isContinuation})}}else Q.push(q);return Q}var N7={30:"black",31:"red",32:"green",33:"yellow",34:"blue",35:"magenta",36:"cyan",37:"white",90:"gray",91:"red",92:"green",93:"yellow",94:"blue",95:"magenta",96:"cyan",97:"white"};function QK(K){if(!K)return"";let $=[],J="",X=0;while(X<K.length){if(K[X]==="\x1B"&&K[X+1]==="["){let Q=X+2;while(Q<K.length&&K[Q]!=="m")Q++;if(K[Q]==="m"){let q=K.slice(X+2,Q).split(";").map(Number);for(let Y of q)if(Y===0)while($.length>0){let V=$.pop();if(V)J+=`{/${V}}`}else if(Y===1)$.push("bold"),J+="{bold}";else if(Y===2)$.push("gray-fg"),J+="{gray-fg}";else if(Y===3);else if(Y===4)$.push("underline"),J+="{underline}";else if(Y>=30&&Y<=37){let V=N7[Y];if(V)$.push(`${V}-fg`),J+=`{${V}-fg}`}else if(Y>=90&&Y<=97){let V=N7[Y];if(V)$.push(`${V}-fg`),J+=`{${V}-fg}`}X=Q+1;continue}}let Z=K[X];if(Z==="{"||Z==="}")J+=Z+Z;else J+=Z;X++}while($.length>0){let Z=$.pop();if(Z)J+=`{/${Z}}`}return J}var H7=/\x1b\[[0-9;]*m/g;function qK(K,$,J="…"){if($<=0)return J;if(!K.includes("\x1B")&&K.length<=$)return K;if(!K.includes("\x1B")){if(K.length<=$)return K;return K.slice(0,$-J.length)+J}let X=[],Z=0;H7.lastIndex=0;let Q;while((Q=H7.exec(K))!==null){if(Q.index>Z)X.push({type:"text",content:K.slice(Z,Q.index)});X.push({type:"ansi",content:Q[0]}),Z=Q.index+Q[0].length}if(Z<K.length)X.push({type:"text",content:K.slice(Z)});let q="",Y=0,V=$-J.length,_=!1,z=!1;for(let U of X)if(U.type==="ansi")q+=U.content,_=!0;else{let B=V-Y;if(B<=0){z=!0;break}if(U.content.length<=B)q+=U.content,Y+=U.content.length;else{q+=U.content.slice(0,B),Y+=B,z=!0;break}}if(z){if(_)q+="\x1B[0m";q+=J}return q}function R(K,$){if($<=0||K.length<=$)return K;if($<=1)return"…";return K.slice(0,$-1)+"…"}function WK(K,$){if(K===void 0)return" ".repeat($);return String(K).padStart($," ")}function x(K){return K.replace(/\{/g,"{{").replace(/\}/g,"}}")}function YK(K){let $=parseInt(K.slice(1,3),16),J=parseInt(K.slice(3,5),16),X=parseInt(K.slice(5,7),16);return`\x1B[48;2;${$};${J};${X}m`}function T7(K){let $=parseInt(K.slice(1,3),16),J=parseInt(K.slice(3,5),16),X=parseInt(K.slice(5,7),16);return`\x1B[38;2;${$};${J};${X}m`}var v="\x1B[0m";function E7(K,$,J,X,Z,Q){let{colors:q}=Z;switch(K.type){case"diff-header":{let Y=K.content;if(Y.startsWith("diff --git")){let V=Y.match(/diff --git a\/.+ b\/(.+)$/);if(V){let _=X-6;return`{bold}{cyan-fg}── ${R(V[1],_)} ──{/cyan-fg}{/bold}`}}return`{gray-fg}${x(R(Y,X))}{/gray-fg}`}case"diff-hunk":{let Y=K.content.match(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)$/);if(Y){let V=parseInt(Y[1],10),_=Y[2]?parseInt(Y[2],10):1,z=parseInt(Y[3],10),U=Y[4]?parseInt(Y[4],10):1,B=Y[5].trim(),k=V+_-1,G=z+U-1,M=_===1?`${V}`:`${V}-${k}`,T=U===1?`${z}`:`${z}-${G}`,N=`Lines ${M} → ${T}`,H=X-N.length-1,E=B&&H>3?" "+R(B,H):"";return`{cyan-fg}${N}{/cyan-fg}{gray-fg}${E}{/gray-fg}`}return`{cyan-fg}${x(R(K.content,X))}{/cyan-fg}`}case"diff-add":{let Y=K.isContinuation,V=Y?"»":"+",z=`${WK(K.lineNum,$)} ${V} `;if(Z.name.includes("ansi")){let N=Q?K.content||"":R(K.content||"",J),E=`${z}${N}`.padEnd(X," ");return`{green-bg}{white-fg}${x(E)}{/white-fg}{/green-bg}`}let U=YK(q.addBg),B=YK(q.addHighlight),k=T7("#ffffff");if(K.wordDiffSegments&&!Y){let N=K.content||"";if(!Q&&N.length>J){let j=R(N,J),D=`${z}${j}`.padEnd(X," ");return`{escape}${U}${k}${D}${v}{/escape}`}let H="";for(let j of K.wordDiffSegments)if(j.type==="changed")H+=`${B}${j.text}${U}`;else H+=j.text;let E=z.length+N.length,A=" ".repeat(Math.max(0,X-E));return`{escape}${U}${k}${z}${H}${A}${v}{/escape}`}if(K.highlighted&&!Y){let N=K.content||"";if(!Q&&N.length>J){let A=R(N,J),O=`${z}${A}`.padEnd(X," ");return`{escape}${U}${k}${O}${v}{/escape}`}let H=z.length+N.length,E=" ".repeat(Math.max(0,X-H));return`{escape}${U}${k}${z}${K.highlighted}${E}${v}{/escape}`}let G=Q?K.content||"":R(K.content||"",J),T=`${z}${G}`.padEnd(X," ");return`{escape}${U}${k}${T}${v}{/escape}`}case"diff-del":{let Y=K.isContinuation,V=Y?"»":"-",z=`${WK(K.lineNum,$)} ${V} `;if(Z.name.includes("ansi")){let N=Q?K.content||"":R(K.content||"",J),E=`${z}${N}`.padEnd(X," ");return`{red-bg}{white-fg}${x(E)}{/white-fg}{/red-bg}`}let U=YK(q.delBg),B=YK(q.delHighlight),k=T7("#ffffff");if(K.wordDiffSegments&&!Y){let N=K.content||"";if(!Q&&N.length>J){let j=R(N,J),D=`${z}${j}`.padEnd(X," ");return`{escape}${U}${k}${D}${v}{/escape}`}let H="";for(let j of K.wordDiffSegments)if(j.type==="changed")H+=`${B}${j.text}${U}`;else H+=j.text;let E=z.length+N.length,A=" ".repeat(Math.max(0,X-E));return`{escape}${U}${k}${z}${H}${A}${v}{/escape}`}if(K.highlighted&&!Y){let N=K.content||"";if(!Q&&N.length>J){let A=R(N,J),O=`${z}${A}`.padEnd(X," ");return`{escape}${U}${k}${O}${v}{/escape}`}let H=z.length+N.length,E=" ".repeat(Math.max(0,X-H));return`{escape}${U}${k}${z}${K.highlighted}${E}${v}{/escape}`}let G=Q?K.content||"":R(K.content||"",J),T=`${z}${G}`.padEnd(X," ");return`{escape}${U}${k}${T}${v}{/escape}`}case"diff-context":{let Y=K.isContinuation,V=Y?"»":" ",z=`${WK(K.lineNum,$)} ${V} `,U=K.content||"";if(K.highlighted&&!Y){let k=Q?K.highlighted:qK(K.highlighted,J),G=QK(k);return`{gray-fg}${z}{/gray-fg}${G}`}let B=Q?x(U):x(R(U,J));return`{gray-fg}${z}{/gray-fg}${B}`}case"commit-header":return`{yellow-fg}${x(R(K.content,X))}{/yellow-fg}`;case"commit-message":return x(R(K.content,X));case"spacer":return""}}function yK(K,$,J=0,X,Z="dark",Q=!1){let q=FK(K);if(q.length===0)return{content:"{gray-fg}No diff to display{/gray-fg}",totalRows:0};let Y=s(Z),V=vK(q),_=$-V-5,z=$-2,U=LK(q,_,Q),B=U.length;return{content:(X?U.slice(J,J+X):U.slice(J)).map((M)=>E7(M,V,_,z,Y,Q)).join(`
12
+ `),totalRows:B}}function I7(K,$,J,X=0,Z,Q="dark",q=!1){let Y=O7(K,$);if(Y.length===0)return{content:"{gray-fg}No commit selected{/gray-fg}",totalRows:0};let V=s(Q),_=vK(Y),z=J-_-5,U=J-2,B=LK(Y,z,q),k=B.length;return{content:(Z?B.slice(X,X+Z):B.slice(X)).map((T)=>E7(T,_,z,U,V,q)).join(`
13
+ `),totalRows:k}}function D7(K,$,J){let X=[],Z="{bold}Commit Message{/bold}";if(K.amend)Z+=" {yellow-fg}(amending){/yellow-fg}";X.push(Z),X.push("");let Q=K.inputFocused?"│":"│",q=K.inputFocused?"cyan":"gray",Y=Math.max(20,J-6);X.push(`{${q}-fg}┌${"─".repeat(Y+2)}┐{/${q}-fg}`);let V=K.message||(K.inputFocused?"":"Press i or Enter to edit..."),_=K.message?"":"{gray-fg}",z=K.message?"":"{/gray-fg}",U=V.length>Y?V.slice(0,Y-1)+"…":V.padEnd(Y);X.push(`{${q}-fg}${Q}{/${q}-fg} ${_}${U}${z} {${q}-fg}${Q}{/${q}-fg}`),X.push(`{${q}-fg}└${"─".repeat(Y+2)}┘{/${q}-fg}`),X.push("");let B=K.amend?"[x]":"[ ]",k=K.amend?"green":"gray";if(X.push(`{${k}-fg}${B}{/${k}-fg} Amend {gray-fg}(a){/gray-fg}`),K.error)X.push(""),X.push(`{red-fg}${K.error}{/red-fg}`);if(K.isCommitting)X.push(""),X.push("{yellow-fg}Committing...{/yellow-fg}");X.push("");let G=K.inputFocused?"Enter: commit | Esc: unfocus":"i/Enter: edit | Esc: cancel | a: toggle amend";return X.push(`{gray-fg}Staged: ${$} file(s) | ${G}{/gray-fg}`),X.join(`
14
+ `)}function w8(K,$){if(K.length<=$)return K;if($<=3)return K.slice(0,$);return K.slice(0,$-3)+"..."}function zK(K,$,J,X=20){let Z=$||"",Q=Math.max(0,J-X-1),q=Z;if(q.length>Q&&Q>3)q=q.slice(0,Q-3)+"...";else if(q.length>Q)q="";let Y=q?q.length+1:0,V=Math.max(X,J-Y);return{displayMessage:w8(K,V),displayRefs:q}}function R7(K,$,J,X,Z=0,Q){if(K.length===0)return"{gray-fg}No commits yet{/gray-fg}";let q=Q?K.slice(Z,Z+Q):K.slice(Z),Y=[];for(let V=0;V<q.length;V++){let _=q[V],B=Z+V===$&&J,k=JK(_.date),G=11+k.length+2+2,M=Math.max(10,X-G),{displayMessage:T,displayRefs:N}=zK(_.message,_.refs,M),H="";if(B)H+="{cyan-fg}{bold}▸ {/bold}{/cyan-fg}";else H+=" ";if(H+=`{yellow-fg}${_.shortHash}{/yellow-fg} `,B)H+=`{cyan-fg}{inverse}${SK(T)}{/inverse}{/cyan-fg}`;else H+=SK(T);if(H+=` {gray-fg}(${k}){/gray-fg}`,N)H+=` {green-fg}${SK(N)}{/green-fg}`;Y.push(H)}return Y.join(`
15
+ `)}function SK(K){return K.replace(/\{/g,"{{").replace(/\}/g,"}}")}function F7(K,$){return K[$]??null}function VK(K,$,J=!0,X=!0){let Z=[];if(K.length>0){if(Z.push({type:"section-header",sectionType:"commits"}),J)K.forEach((Q,q)=>{Z.push({type:"commit",commitIndex:q,commit:Q})})}if($.length>0){if(K.length>0)Z.push({type:"spacer"});if(Z.push({type:"section-header",sectionType:"files"}),X)$.forEach((Q,q)=>{Z.push({type:"file",fileIndex:q,file:Q})})}return Z}function l(K){return K.replace(/\{/g,"{{").replace(/\}/g,"}}")}function u8(K,$,J,X){let Z=$&&J,Q=JK(K.date),q=13+Q.length+2,Y=Math.max(10,X-q),{displayMessage:V,displayRefs:_}=zK(K.message,K.refs,Y),z=" ";if(z+=`{yellow-fg}${K.shortHash}{/yellow-fg} `,Z)z+=`{cyan-fg}{inverse}${l(V)}{/inverse}{/cyan-fg}`;else z+=l(V);if(z+=` {gray-fg}(${Q}){/gray-fg}`,_)z+=` {green-fg}${l(_)}{/green-fg}`;return z}function p8(K,$,J,X){let Z=$&&J,Q=K.isUncommitted??!1,q={added:"green",modified:"yellow",deleted:"red",renamed:"blue"},Y={added:"A",modified:"M",deleted:"D",renamed:"R"},V=5+String(K.additions).length+String(K.deletions).length,_=Q?14:0,z=Math.max(10,X-V-_),U=" ";if(Q)U+="{magenta-fg}{bold}*{/bold}{/magenta-fg}";let B=Q?"magenta":q[K.status];U+=`{${B}-fg}{bold}${Y[K.status]}{/bold}{/${B}-fg} `;let k=r(K.path,z);if(Z)U+=`{cyan-fg}{inverse}${l(k)}{/inverse}{/cyan-fg}`;else if(Q)U+=`{magenta-fg}${l(k)}{/magenta-fg}`;else U+=l(k);if(U+=` {gray-fg}({/gray-fg}{green-fg}+${K.additions}{/green-fg} {red-fg}-${K.deletions}{/red-fg}{gray-fg}){/gray-fg}`,Q)U+=" {magenta-fg}[uncommitted]{/magenta-fg}";return U}function v7(K,$,J,X,Z,Q=0,q){if(K.length===0&&$.length===0)return"{gray-fg}No changes compared to base branch{/gray-fg}";let Y=VK(K,$),V=q?Y.slice(Q,Q+q):Y.slice(Q),_=[];for(let z of V)if(z.type==="section-header"){let U=z.sectionType==="commits",B=U?K.length:$.length,k=U?"Commits":"Files";_.push(`{cyan-fg}{bold}▼ ${k}{/bold}{/cyan-fg} {gray-fg}(${B}){/gray-fg}`)}else if(z.type==="spacer")_.push("");else if(z.type==="commit"&&z.commit&&z.commitIndex!==void 0){let U=J?.type==="commit"&&J.index===z.commitIndex;_.push(u8(z.commit,U,X,Z))}else if(z.type==="file"&&z.file&&z.fileIndex!==void 0){let U=J?.type==="file"&&J.index===z.fileIndex;_.push(p8(z.file,U,X,Z-5))}return _.join(`
16
+ `)}function L7(K,$,J=!0,X=!0){let Z=0;if(K.length>0){if(Z+=1,J)Z+=K.length}if($.length>0){if(K.length>0)Z+=1;if(Z+=1,X)Z+=$.length}return Z}function PK(K,$,J,X=!0,Z=!0){let q=VK($,J,X,Z)[K];if(!q)return null;if(q.type==="commit"&&q.commitIndex!==void 0)return{type:"commit",index:q.commitIndex};if(q.type==="file"&&q.fileIndex!==void 0)return{type:"file",index:q.fileIndex};return null}function UK(K,$,J,X=!0,Z=!0){let Q=VK($,J,X,Z);for(let q=0;q<Q.length;q++){let Y=Q[q];if(K.type==="commit"&&Y.type==="commit"&&Y.commitIndex===K.index)return q;if(K.type==="file"&&Y.type==="file"&&Y.fileIndex===K.index)return q}return 0}function CK(K,$,J,X){let Z=VK($,J),Q=0;if(K)Q=UK(K,$,J);let q=X==="down"?1:-1,Y=Q+q;while(Y>=0&&Y<Z.length){let V=PK(Y,$,J);if(V)return V;Y+=q}return K}function a(K){return K.replace(/\{/g,"{{").replace(/\}/g,"}}")}function W7(K,$,J,X,Z=0,Q,q=!1,Y=null){if(Y)return`{red-fg}Error: ${a(Y)}{/red-fg}`;if(q)return"{gray-fg}Loading...{/gray-fg}";if(K.length===0)return"{gray-fg}(empty directory){/gray-fg}";let V=Q?K.slice(Z,Z+Q):K.slice(Z),_=Math.min(Math.max(...K.map((U)=>U.name.length+(U.isDirectory?1:0))),X-10),z=[];for(let U=0;U<V.length;U++){let B=V[U],M=Z+U===$&&J,N=(B.isDirectory?`${B.name}/`:B.name).padEnd(_+1),H="";if(M)if(B.isDirectory)H=`{cyan-fg}{bold}{inverse}${a(N)}{/inverse}{/bold}{/cyan-fg}`;else H=`{cyan-fg}{bold}{inverse}${a(N)}{/inverse}{/bold}{/cyan-fg}`;else if(B.isDirectory)H=`{blue-fg}${a(N)}{/blue-fg}`;else H=a(N);z.push(H)}return z.join(`
17
+ `)}function y7(K){return K.length}function bK(K,$,J){if(!K)return[];let X=K.split(`
18
+ `),Z=[],Q=$?ZK($):null;for(let q=0;q<X.length;q++){let Y=X[q],V=Q?j7(Y,Q):void 0;Z.push({type:"code",lineNum:q+1,content:Y,highlighted:V})}if(J)Z.push({type:"truncation",content:"(file truncated)"});return Z}function S7(K,$,J){if(!J)return K;let Z=Math.max(10,$),Q=[];for(let q of K)if(q.type==="code"){let Y=q.content;if(!Y||Y.length<=Z){Q.push(q);continue}let V=XK(Y,Z);for(let _=0;_<V.length;_++){let z=V[_];Q.push({type:"code",lineNum:z.isContinuation?0:q.lineNum,content:z.text,highlighted:void 0,isContinuation:z.isContinuation})}}else Q.push(q);return Q}function P7(K,$,J){if(!J)return K.length;let Z=Math.max(10,$),Q=0;for(let q of K)if(q.type==="code"){let Y=q.content;if(!Y||Y.length<=Z)Q+=1;else Q+=EK(Y,Z)}else Q+=1;return Q}function xK(K){let $=0;for(let J of K)if(J.type==="code"&&J.lineNum>$)$=J.lineNum;return Math.max(3,String($).length)}function C7(K,$){if(!$||!K)return K;let J=0;for(let Q of K)if(Q===" ")J++;else if(Q==="\t")J+=2;else break;if(J===0)return K;let X="·".repeat(J),Z=K.slice(J);return X+Z}function b7(K){return K.replace(/\{/g,"{{").replace(/\}/g,"}}")}function x7(K,$,J,X=0,Z,Q=!1,q=!1,Y=!1){if(!K)return"{gray-fg}Select a file to view its contents{/gray-fg}";if(!$)return"{gray-fg}Loading...{/gray-fg}";let V=bK($,K,Q);if(V.length===0)return"{gray-fg}(empty file){/gray-fg}";let _=xK(V),z=J-_-2,U=S7(V,z,q),B=Z?U.slice(X,X+Z):U.slice(X),k=[];for(let G of B){if(G.type==="truncation"){k.push(`{yellow-fg}${b7(G.content)}{/yellow-fg}`);continue}let M=G.isContinuation??!1,T;if(M)T=">>".padStart(_," ");else T=String(G.lineNum).padStart(_," ");let N=G.content,H=!q&&N.length>z,E=G.highlighted&&!M&&!Y,A;if(E&&G.highlighted){let O=H?qK(G.highlighted,z):G.highlighted;A=QK(O)}else{let O=N;if(Y&&!M)O=C7(O,!0);if(H)O=O.slice(0,Math.max(0,z-1))+"...";A=b7(O)}let j="";if(M)j=`{cyan-fg}${T}{/cyan-fg} ${A||" "}`;else j=`{gray-fg}${T}{/gray-fg} ${A||" "}`;k.push(j)}return k.join(`
19
+ `)}function w7(K,$,J,X,Z){if(!K)return 0;let Q=bK(K,$,J),q=xK(Q),Y=X-q-2;return P7(Q,Y,Z)}import*as BK from"node:fs";import*as L from"node:path";import{EventEmitter as m8}from"node:events";import{simpleGit as g8}from"simple-git";async function _K(K,$){if($.length===0)return new Set;let J=g8(K),X=new Set,Z=100;for(let Q=0;Q<$.length;Q+=Z){let q=$.slice(Q,Q+Z);try{let V=(await J.raw(["check-ignore",...q])).trim().split(`
20
+ `).filter((_)=>_.length>0);for(let _ of V)X.add(_)}catch{}}return X}var f8=1048576,h8=102400;function c8(K){let $=Math.min(K.length,8192);for(let J=0;J<$;J++)if(K[J]===0)return!0;return!1}class wK extends m8{repoPath;options;_state={currentPath:"",items:[],selectedIndex:0,selectedFile:null,isLoading:!1,error:null};constructor(K,$){super();this.repoPath=K,this.options=$}get state(){return this._state}updateState(K){this._state={...this._state,...K},this.emit("state-change",this._state)}async setOptions(K){this.options={...this.options,...K},await this.loadDirectory(this._state.currentPath)}async loadDirectory(K){this.updateState({isLoading:!0,error:null,currentPath:K});try{let $=L.join(this.repoPath,K),J=await BK.promises.readdir($,{withFileTypes:!0}),X=J.map((q)=>K?L.join(K,q.name):q.name),Z=this.options.hideGitignored?await _K(this.repoPath,X):new Set,Q=J.filter((q)=>{if(this.options.hideHidden&&q.name.startsWith("."))return!1;if(this.options.hideGitignored){let Y=K?L.join(K,q.name):q.name;if(Z.has(Y))return!1}return!0}).map((q)=>({name:q.name,path:K?L.join(K,q.name):q.name,isDirectory:q.isDirectory()}));if(Q.sort((q,Y)=>{if(q.isDirectory&&!Y.isDirectory)return-1;if(!q.isDirectory&&Y.isDirectory)return 1;return q.name.localeCompare(Y.name)}),K)Q.unshift({name:"..",path:L.dirname(K)||"",isDirectory:!0});this.updateState({items:Q,selectedIndex:0,selectedFile:null,isLoading:!1})}catch($){this.updateState({error:$ instanceof Error?$.message:"Failed to read directory",items:[],isLoading:!1})}}async loadFile(K){try{let $=L.join(this.repoPath,K),J=await BK.promises.stat($);if(J.size>f8){this.updateState({selectedFile:{path:K,content:`File too large to display (${(J.size/1024/1024).toFixed(2)} MB).
21
+ Maximum size: 1 MB`,truncated:!0}});return}let X=await BK.promises.readFile($);if(c8(X)){this.updateState({selectedFile:{path:K,content:"Binary file - cannot display"}});return}let Z=X.toString("utf-8"),Q=!1;if(J.size>h8)Z=`⚠ Large file (${(J.size/1024).toFixed(1)} KB)
37
22
 
38
- `+f;let v=5000,y=f.split(`
39
- `);if(y.length>v)f=y.slice(0,v).join(`
23
+ `+Z;let q=5000,Y=Z.split(`
24
+ `);if(Y.length>q)Z=Y.slice(0,q).join(`
40
25
  `)+`
41
26
 
42
- ... (truncated, ${y.length-v} more lines)`,_=!0;O({path:C.path,content:f,truncated:_}),Q(0)}catch(w){O({path:C.path,content:w instanceof Error?`Error: ${w.message}`:"Failed to read file"})}})()},[X,N,E,Y,Q]);let L=HJ(()=>N.length,[N]),R=WX(()=>{U((C)=>{let b=Math.max(0,C-1);if(b<J)Z(b);return b})},[J,Z]),S=WX(()=>{U((C)=>{let b=Math.min(N.length-1,C+1),w=$-1,p=N.length>w?w-2:w,f=J+p;if(b>=f)Z(J+1);return b})},[N.length,J,$,Z]),P=WX(()=>{let C=N[E];if(!C)return;if(C.isDirectory)if(C.name==="..")z(D0.dirname(q)||"");else z(C.path)},[N,E,q]),W=WX(()=>{if(q)z(D0.dirname(q)||"")},[q]);return{currentPath:q,items:N,selectedIndex:E,setSelectedIndex:U,selectedFile:M,fileScrollOffset:K,setFileScrollOffset:Q,navigateUp:R,navigateDown:S,enterDirectory:P,goUp:W,isLoading:F,error:H,explorerTotalRows:L}}import{jsx as r,jsxs as K8}from"react/jsx-runtime";import{useState as yJ}from"react";import{Box as f0,Text as Y0,useInput as PJ}from"ink";import{jsx as P9,jsxs as vJ}from"react/jsx-runtime";import{Box as T9,Text as jJ}from"ink";function Z8({x:X,y:Y,width:$,height:J,children:Z}){let K=" ".repeat($);return vJ(T9,{position:"absolute",marginLeft:X,marginTop:Y,flexDirection:"column",children:[Array.from({length:J}).map((Q,V)=>P9(jJ,{children:K},`blank-${V}`)),P9(T9,{position:"absolute",flexDirection:"column",children:Z})]})}function D8(X,Y,$,J){return{x:Math.floor(($-X)/2),y:Math.floor((J-Y)/2)}}function TJ({theme:X}){let{colors:Y}=X;return K8(f0,{flexDirection:"column",marginLeft:2,children:[K8(f0,{children:[r(Y0,{backgroundColor:Y.delBg,color:Y.delLineNum,children:" 5 "}),r(Y0,{backgroundColor:Y.delBg,color:Y.delSymbol,bold:!0,children:"- "}),r(Y0,{backgroundColor:Y.delBg,color:Y.text,children:"const "}),r(Y0,{backgroundColor:Y.delHighlight,color:Y.text,children:"old"}),r(Y0,{backgroundColor:Y.delBg,color:Y.text,children:" = value;"})]}),K8(f0,{children:[r(Y0,{backgroundColor:Y.addBg,color:Y.addLineNum,children:" 5 "}),r(Y0,{backgroundColor:Y.addBg,color:Y.addSymbol,bold:!0,children:"+ "}),r(Y0,{backgroundColor:Y.addBg,color:Y.text,children:"const "}),r(Y0,{backgroundColor:Y.addHighlight,color:Y.text,children:"new"}),r(Y0,{backgroundColor:Y.addBg,color:Y.text,children:" = value;"})]})]})}function C9({currentTheme:X,onSelect:Y,onCancel:$,width:J,height:Z}){let[K,Q]=yJ(()=>{let A=e0.indexOf(X);return A>=0?A:0}),V=UX(e0[K]);PJ((A,E)=>{if(E.escape)$();else if(E.return)Y(e0[K]);else if(E.upArrow||A==="k")Q((U)=>Math.max(0,U-1));else if(E.downArrow||A==="j")Q((U)=>Math.min(e0.length-1,U+1))});let G=Math.min(50,J-4),q=Math.min(e0.length+10,Z-4),{x:z,y:N}=D8(G,q,J,Z);return r(Z8,{x:z,y:N,width:G,height:q,children:K8(f0,{borderStyle:"round",borderColor:"cyan",flexDirection:"column",width:G,children:[r(f0,{justifyContent:"center",marginBottom:1,children:K8(Y0,{bold:!0,color:"cyan",children:[" ","Select Theme"," "]})}),e0.map((A,E)=>{let U=VX[A],M=E===K,O=A===X;return K8(f0,{children:[r(Y0,{color:M?"cyan":void 0,children:M?"▸ ":" "}),r(Y0,{bold:M,color:M?"cyan":void 0,children:U.displayName}),O&&r(Y0,{dimColor:!0,children:" (current)"})]},A)}),K8(f0,{marginTop:1,flexDirection:"column",children:[r(Y0,{dimColor:!0,children:"Preview:"}),r(TJ,{theme:V})]}),r(f0,{marginTop:1,justifyContent:"center",children:r(Y0,{dimColor:!0,children:"↑↓ navigate • Enter select • Esc cancel"})})]})})}import{jsx as J0,jsxs as Q8}from"react/jsx-runtime";import{Box as G0,Text as q8,useInput as CJ}from"ink";var d0=[{title:"Navigation",entries:[{key:"↑/k",description:"Move up"},{key:"↓/j",description:"Move down"},{key:"Tab",description:"Toggle pane focus"}]},{title:"Staging",entries:[{key:"^S",description:"Stage file"},{key:"^U",description:"Unstage file"},{key:"^A",description:"Stage all"},{key:"^Z",description:"Unstage all"},{key:"Space/Enter",description:"Toggle stage"}]},{title:"Actions",entries:[{key:"c",description:"Open commit panel"},{key:"r",description:"Refresh"},{key:"q",description:"Quit"}]},{title:"Pane Resize",entries:[{key:"[",description:"Shrink top pane"},{key:"]",description:"Grow top pane"}]},{title:"Tabs",entries:[{key:"1",description:"Diff view"},{key:"2",description:"Commit panel"},{key:"3",description:"History view"},{key:"4",description:"Compare view"},{key:"5",description:"Explorer view"},{key:"a",description:"Toggle auto-tab mode"}]},{title:"Explorer",entries:[{key:".",description:"Toggle middle-dots"},{key:"^H",description:"Toggle hidden files"},{key:"^G",description:"Toggle gitignored"},{key:"Enter",description:"Enter directory"},{key:"Backspace/h",description:"Go up"}]},{title:"Other",entries:[{key:"m",description:"Toggle scroll/select"},{key:"f",description:"Toggle follow mode"},{key:"w",description:"Toggle wrap mode"},{key:"t",description:"Theme picker"},{key:"b",description:"Base branch picker"},{key:"u",description:"Toggle uncommitted"},{key:"?",description:"This help"}]}];function S9({onClose:X,width:Y,height:$}){CJ((z,N)=>{if(N.escape||N.return||z==="?")X()});let J=Y>=90,Z=J?38:30,K=J?Math.min(82,Y-4):Math.min(40,Y-4),Q;if(J){let z=Math.ceil(d0.length/2),N=d0.slice(0,z),A=d0.slice(z),E=N.reduce((M,O)=>M+O.entries.length+2,0),U=A.reduce((M,O)=>M+O.entries.length+2,0);Q=Math.min(Math.max(E,U)+5,$-4)}else{let z=d0.reduce((N,A)=>N+A.entries.length+2,0)+4;Q=Math.min(z,$-4)}let{x:V,y:G}=D8(K,Q,Y,$),q=(z,N)=>Q8(G0,{flexDirection:"column",marginBottom:1,children:[J0(q8,{bold:!0,dimColor:!0,children:z.title}),z.entries.map((A)=>Q8(G0,{children:[J0(G0,{width:13,children:J0(q8,{color:"cyan",children:A.key})}),J0(G0,{width:N-13,children:J0(q8,{children:A.description})})]},A.key))]},z.title);if(J){let z=Math.ceil(d0.length/2),N=d0.slice(0,z),A=d0.slice(z);return J0(Z8,{x:V,y:G,width:K,height:Q,children:Q8(G0,{borderStyle:"round",borderColor:"cyan",flexDirection:"column",width:K,children:[J0(G0,{justifyContent:"center",marginBottom:1,children:Q8(q8,{bold:!0,color:"cyan",children:[" ","Keyboard Shortcuts"," "]})}),Q8(G0,{children:[J0(G0,{flexDirection:"column",width:Z,marginRight:2,children:N.map((E)=>q(E,Z))}),J0(G0,{flexDirection:"column",width:Z,children:A.map((E)=>q(E,Z))})]}),J0(G0,{marginTop:1,justifyContent:"center",children:J0(q8,{dimColor:!0,children:"Press Esc, Enter, or ? to close"})})]})})}return J0(Z8,{x:V,y:G,width:K,height:Q,children:Q8(G0,{borderStyle:"round",borderColor:"cyan",flexDirection:"column",width:K,children:[J0(G0,{justifyContent:"center",marginBottom:1,children:Q8(q8,{bold:!0,color:"cyan",children:[" ","Keyboard Shortcuts"," "]})}),d0.map((z)=>q(z,Z)),J0(G0,{marginTop:1,justifyContent:"center",children:J0(q8,{dimColor:!0,children:"Press Esc, Enter, or ? to close"})})]})})}import{jsxs as _8,jsx as Z0}from"react/jsx-runtime";import{useState as b9,useMemo as SJ}from"react";import{Box as c0,Text as N0,useInput as bJ}from"ink";function w9({candidates:X,currentBranch:Y,onSelect:$,onCancel:J,width:Z,height:K}){let[Q,V]=b9(""),[G,q]=b9(0),z=SJ(()=>{if(!Q)return X;let H=Q.toLowerCase();return X.filter((B)=>B.toLowerCase().includes(H))},[X,Q]),N=Math.min(G,Math.max(0,z.length-1));bJ((H,B)=>{if(B.escape)J();else if(B.return){if(z.length===0&&Q)$(Q);else if(z.length>0)$(z[N])}else if(B.upArrow)q((L)=>Math.max(0,L-1));else if(B.downArrow)q((L)=>Math.min(z.length-1,L+1));else if(B.backspace||B.delete)V((L)=>L.slice(0,-1)),q(0);else if(H&&!B.ctrl&&!B.meta)V((L)=>L+H),q(0)});let A=Math.min(60,Z-4),E=Math.min(10,K-10),U=Math.min(E+9,K-4),{x:M,y:O}=D8(A,U,Z,K),F=Math.max(0,N-E+1),k=z.slice(F,F+E);return Z0(Z8,{x:M,y:O,width:A,height:U,children:_8(c0,{borderStyle:"round",borderColor:"cyan",flexDirection:"column",width:A,children:[Z0(c0,{justifyContent:"center",marginBottom:1,children:_8(N0,{bold:!0,color:"cyan",children:[" ","Select Base Branch"," "]})}),_8(c0,{marginBottom:1,children:[Z0(N0,{dimColor:!0,children:"Filter: "}),Z0(N0,{color:"cyan",children:Q}),Z0(N0,{color:"cyan",children:"▌"})]}),Z0(c0,{flexDirection:"column",height:E,children:k.length>0?k.map((H,B)=>{let R=F+B===N,S=H===Y;return _8(c0,{children:[Z0(N0,{color:R?"cyan":void 0,children:R?"▸ ":" "}),Z0(N0,{bold:R,color:R?"cyan":void 0,children:H}),S&&Z0(N0,{dimColor:!0,children:" (current)"})]},H)}):Q?_8(c0,{children:[Z0(N0,{dimColor:!0,children:" No matches. Press Enter to use: "}),Z0(N0,{color:"yellow",children:Q})]}):Z0(N0,{dimColor:!0,children:" No candidates found"})}),z.length>E&&Z0(c0,{children:_8(N0,{dimColor:!0,children:[F>0?"↑ ":" ",F+E<z.length?"↓ more":""]})}),Z0(c0,{marginTop:1,justifyContent:"center",children:Z0(N0,{dimColor:!0,children:"↑↓ navigate • Enter select • Esc cancel"})})]})})}function g9({config:X,initialPath:Y}){let{exit:$}=wJ(),{rows:J,columns:Z}=V9(),{state:K,setEnabled:Q}=T4(X.watcherEnabled,X.targetFile,X.debug),V=Y??K.path??process.cwd(),{status:G,diff:q,selectedFile:z,isLoading:N,error:A,selectFile:E,stage:U,unstage:M,discard:O,stageAll:F,unstageAll:k,commit:H,refresh:B,getHeadCommitMessage:L,compareDiff:R,compareLoading:S,compareError:P,refreshCompareDiff:W,getCandidateBaseBranches:C,setCompareBaseBranch:b,historySelectedCommit:w,historyCommitDiff:g,selectHistoryCommit:p,compareSelectionDiff:f,selectCompareCommit:_}=K9(V),v=G?.files??[],y=oY(v),T=v.filter((I)=>I.staged).length,[j,x]=Q0("files"),[D,y8]=Q0("diff"),[l0,s8]=Q0(0),[P8,DX]=Q0(null),[UY,x9]=Q0(!1),[GY,p9]=Q0(X.theme),[T8,n0]=Q0(null),[_X,NY]=Q0(!1),[_0,AY]=Q0(!1),[a8,vX]=Q0(0),[BY,jX]=Q0(0),[EY,u9]=Q0(!1),[MY,h9]=Q0(!0),[LY,m9]=Q0(!0),OY=lY(V,G?.branch??null,K,Z,A,N),f9=OY-1,{topPaneHeight:r0,bottomPaneHeight:yX,paneBoundaries:kY,splitRatio:PX,adjustSplitRatio:WY,fileListScrollOffset:TX,diffScrollOffset:d9,historyScrollOffset:i8,compareScrollOffset:t8,setDiffScrollOffset:b0,setHistoryScrollOffset:CX,setCompareScrollOffset:c9,scrollDiff:z8,scrollFileList:HY,scrollHistory:IY,scrollCompare:FY}=W9(J,Z,v,l0,q,D,void 0,X.splitRatio,f9),V8=VY(()=>{let I=X8(q);if(!_0)return I.length;let W0=R0(I),H0=Z-W0-5;return L8(I,H0,!0)},[q,_0,Z]),{commits:C8,historySelectedIndex:l9,setHistorySelectedIndex:S8,historyDiffTotalRows:RY,navigateHistoryUp:DY,navigateHistoryDown:_Y,historyTotalRows:vY}=D9({repoPath:V,isActive:D==="history",selectHistoryCommit:p,historyCommitDiff:g,historySelectedCommit:w,topPaneHeight:r0,historyScrollOffset:i8,setHistoryScrollOffset:CX,setDiffScrollOffset:b0,status:G,wrapMode:_0,terminalWidth:Z}),{includeUncommitted:n9,compareListSelection:w0,baseBranchCandidates:r9,showBaseBranchPicker:SX,compareTotalItems:e8,compareDiffTotalRows:U8,setCompareSelectedIndex:jY,toggleIncludeUncommitted:o9,openBaseBranchPicker:s9,closeBaseBranchPicker:a9,selectBaseBranch:i9,navigateCompareUp:yY,navigateCompareDown:PY,markSelectionInitialized:TY,getItemIndexFromRow:CY}=v9({repoPath:V,isActive:D==="compare",compareDiff:R,refreshCompareDiff:W,getCandidateBaseBranches:C,setCompareBaseBranch:b,selectCompareCommit:_,topPaneHeight:r0,compareScrollOffset:t8,setCompareScrollOffset:c9,setDiffScrollOffset:b0,status:G,wrapMode:_0,terminalWidth:Z}),{currentPath:t9,items:XX,selectedIndex:e9,setSelectedIndex:SY,selectedFile:G8,navigateUp:bY,navigateDown:wY,enterDirectory:X$,goUp:Y$,isLoading:$$,error:J$,explorerTotalRows:gY}=y9({repoPath:V,isActive:D==="explorer",topPaneHeight:r0,explorerScrollOffset:a8,setExplorerScrollOffset:vX,fileScrollOffset:BY,setFileScrollOffset:jX,hideHiddenFiles:MY,hideGitignored:LY}),xY=VY(()=>{if(!G8)return 0;return F4(G8.content,G8.path,G8.truncated??!1,Z,_0)},[G8,Z,_0]),pY=FX(kY);pY.current=kY;let Z$=FX(X.splitRatio);v8(()=>{if(PX!==Z$.current){let I=setTimeout(()=>pX({splitRatio:PX}),500);return()=>clearTimeout(I)}},[PX]);let K0=VY(()=>hX(v,l0),[v,l0]);v8(()=>{if(y>0&&l0>=y)s8(Math.max(0,y-1))},[y,l0]),v8(()=>{E(K0)},[K0,E]),v8(()=>{if(D==="diff"||D==="commit")b0(0)},[l0,D,b0]),v8(()=>{b0(0)},[_0,b0]);let o0=k0((I)=>{y8(I),x({diff:"files",commit:"commit",history:"history",compare:"compare",explorer:"explorer"}[I])},[]),uY=FX(()=>{}),K$=k0((I)=>{let{x:W0,y:H0,type:YX,button:gX}=I,{stagingPaneStart:N8,fileListEnd:xX,diffPaneStart:L$,diffPaneEnd:O$,footerRow:k$}=pY.current;if(YX==="click"){if(T8!==null){n0(null);return}if(H0===k$&&gX==="left"){let A0=E9(W0,Z);if(A0){o0(A0);return}let i=L9(W0);if(i==="hotkeys"){n0("hotkeys");return}else if(i==="mouse-mode"){uY.current();return}else if(i==="auto-tab"){NY((d)=>!d);return}else if(i==="wrap"){AY((d)=>!d);return}}if(OX(H0,N8+1,xX)){let A0=r0-1,i=(d)=>d>A0?1:0;if(D==="diff"||D==="commit"){let d=B9(H0,TX,v,N8,xX);if(d>=0&&d<y){s8(d),x("files");let l=hX(v,d);if(l){if(gX==="right"&&!l.staged&&l.status!=="untracked")DX(l);else if(gX==="left"&&M9(W0))if(l.staged)M(l);else U(l)}return}}else if(D==="history"){let d=i(C8.length),l=H0-N8-1-d,s0=cX(l,C8,Z,i8);if(s0>=0&&s0<C8.length){S8(s0),x("history"),b0(0);return}}else if(D==="compare"&&R){let d=i(e8),l=H0-N8-1-d+t8,s0=CY(l);if(s0>=0&&s0<e8){TY(),jY(s0),x("compare");return}}else if(D==="explorer"){let d=i(XX.length),l=H0-N8-1-d+a8;if(l>=0&&l<XX.length){SY(l),x("explorer");return}}}if(OX(H0,L$,O$))x(D)}else if(YX==="scroll-up"||YX==="scroll-down"){let A0=YX==="scroll-up"?"up":"down";if(OX(H0,N8,xX)){if(D==="diff"||D==="commit")HY(A0);else if(D==="history")IY(A0,vY);else if(D==="compare")FY(A0,e8);else if(D==="explorer"){let i=A0==="up"?-3:3,d=E8(gY,r0-1);vX((l)=>Math.max(0,Math.min(l+i,d)))}}else if(D==="explorer"){let i=A0==="up"?-3:3,d=E8(xY,yX-1);jX((l)=>Math.max(0,Math.min(l+i,d)))}else{let i;if(D==="compare"&&w0?.type!=="commit")i=U8;else if(D==="history")i=RY;else if(D==="diff")i=V8;z8(A0,3,i)}}},[Z,TX,v,y,D,C8,R,e8,U,M,z8,HY,IY,FY,i8,t8,b0,S8,jY,TY,CY,w0?.type,U8,V8,RY,vY,T8,XX,a8,gY,xY,r0,yX,SY,vX,jX]),Q$=UY||SX,{mouseEnabled:q$,toggleMouse:hY}=z9(K$,Q$);uY.current=hY;let bX=FX(y);v8(()=>{if(!_X){bX.current=y;return}let I=bX.current;if(I===0&&y>0)o0("diff");else if(I>0&&y===0)S8(0),CX(0),o0("history");bX.current=y},[y,_X,o0,S8,CX]);let z$=k0(()=>{if(j==="files")s8((I)=>Math.max(0,I-1));else if(j==="diff"){let I;if(D==="compare"&&w0?.type!=="commit")I=U8;else if(D==="diff")I=V8;z8("up",3,I)}else if(j==="history")DY();else if(j==="compare")yY();else if(j==="explorer")bY()},[j,D,w0?.type,U8,V8,z8,DY,yY,bY]),V$=k0(()=>{if(j==="files")s8((I)=>Math.min(y-1,I+1));else if(j==="diff"){let I;if(D==="compare"&&w0?.type!=="commit")I=U8;else if(D==="diff")I=V8;z8("down",3,I)}else if(j==="history")_Y();else if(j==="compare")PY();else if(j==="explorer")wY()},[j,D,w0?.type,U8,V8,y,z8,_Y,PY,wY]),U$=k0(()=>{if(D==="diff"||D==="commit")x((I)=>I==="files"?"diff":"files");else if(D==="history")x((I)=>I==="history"?"diff":"history");else if(D==="compare")x((I)=>I==="compare"?"diff":"compare");else if(D==="explorer")x((I)=>I==="explorer"?"diff":"explorer")},[D]),G$=k0(async()=>{if(K0&&!K0.staged)await U(K0)},[K0,U]),N$=k0(async()=>{if(K0?.staged)await M(K0)},[K0,M]),A$=k0(async()=>{if(!K0)return;if(K0.staged)await M(K0);else await U(K0)},[K0,U,M]),B$=k0(()=>o0("commit"),[o0]),E$=k0(()=>{y8("diff"),x("files")},[]),M$=k0((I)=>{p9(I),n0(null),pX({theme:I})},[]);Q9({onStage:G$,onUnstage:N$,onStageAll:F,onUnstageAll:k,onCommit:B$,onQuit:$,onRefresh:B,onNavigateUp:z$,onNavigateDown:V$,onTogglePane:U$,onSwitchTab:o0,onSelect:A$,onToggleIncludeUncommitted:o9,onCycleBaseBranch:s9,onOpenThemePicker:()=>n0("theme"),onShrinkTopPane:()=>WY(-zY),onGrowTopPane:()=>WY(zY),onOpenHotkeysModal:()=>n0("hotkeys"),onToggleMouse:hY,onToggleFollow:()=>Q((I)=>!I),onToggleAutoTab:()=>NY((I)=>!I),onToggleWrap:()=>AY((I)=>!I),onToggleMiddleDots:D==="explorer"?()=>u9((I)=>!I):void 0,onToggleHideHiddenFiles:D==="explorer"?()=>h9((I)=>!I):void 0,onToggleHideGitignored:D==="explorer"?()=>m9((I)=>!I):void 0,onExplorerEnter:D==="explorer"?X$:void 0,onExplorerBack:D==="explorer"?Y$:void 0},j,UY||T8!==null||SX),gJ((I,W0)=>{if(!P8)return;if(I==="y"||I==="Y")O(P8),DX(null);else if(I==="n"||I==="N"||W0.escape)DX(null)},{isActive:!!P8});let wX=()=>X0(n8,{dimColor:!0,children:"─".repeat(Z)});return IX(j8,{flexDirection:"column",height:J,width:Z,overflowX:"hidden",children:[X0(j8,{height:OY,width:Z,children:X0(nY,{repoPath:V,branch:G?.branch??null,isLoading:N,error:A,debug:X.debug,watcherState:K,width:Z})}),X0(wX,{}),X0(J4,{bottomTab:D,currentPane:j,terminalWidth:Z,topPaneHeight:r0,files:v,selectedIndex:l0,fileListScrollOffset:TX,stagedCount:T,onStage:U,onUnstage:M,commits:C8,historySelectedIndex:l9,historyScrollOffset:i8,onSelectHistoryCommit:(I,W0)=>S8(W0),compareDiff:R,compareListSelection:w0,compareScrollOffset:t8,includeUncommitted:n9,explorerCurrentPath:t9,explorerItems:XX,explorerSelectedIndex:e9,explorerScrollOffset:a8,explorerIsLoading:$$,explorerError:J$,hideHiddenFiles:MY,hideGitignored:LY}),X0(wX,{}),X0(D4,{bottomTab:D,currentPane:j,terminalWidth:Z,bottomPaneHeight:yX,diffScrollOffset:d9,currentTheme:GY,diff:q,selectedFile:z,stagedCount:T,onCommit:H,onCommitCancel:E$,getHeadCommitMessage:L,onCommitInputFocusChange:x9,historySelectedCommit:w,historyCommitDiff:g,compareDiff:R,compareLoading:S,compareError:P,compareListSelection:w0,compareSelectionDiff:f,wrapMode:_0,explorerSelectedFile:G8,explorerFileScrollOffset:BY,showMiddleDots:EY}),X0(wX,{}),P8?IX(j8,{children:[IX(n8,{color:"yellow",bold:!0,children:["Discard changes to"," "]}),X0(n8,{color:"cyan",children:P8.path}),IX(n8,{color:"yellow",bold:!0,children:["?"," "]}),X0(n8,{dimColor:!0,children:"(y/n)"})]}):X0(eY,{activeTab:D,mouseEnabled:q$,autoTabEnabled:_X,wrapMode:_0,showMiddleDots:EY}),T8==="theme"&&X0(j8,{position:"absolute",marginTop:0,marginLeft:0,children:X0(C9,{currentTheme:GY,onSelect:M$,onCancel:()=>n0(null),width:Z,height:J})}),T8==="hotkeys"&&X0(j8,{position:"absolute",marginTop:0,marginLeft:0,children:X0(S9,{onClose:()=>n0(null),width:Z,height:J})}),SX&&X0(j8,{position:"absolute",marginTop:0,marginLeft:0,children:X0(w9,{candidates:r9,currentBranch:R?.baseBranch??null,onSelect:i9,onCancel:a9,width:Z,height:J})})]})}function o8(){process.stdout.write("\x1B[?1006l"),process.stdout.write("\x1B[?1002l"),process.stdout.write("\x1B[?1000l"),process.stdout.write("\x1B[?25h")}process.on("exit",o8);process.on("SIGINT",()=>{o8(),process.exit(0)});process.on("SIGTERM",()=>{o8(),process.exit(0)});process.on("uncaughtException",(X)=>{o8(),console.error("Uncaught exception:",X),process.exit(1)});process.on("unhandledRejection",(X)=>{o8(),console.error("Unhandled rejection:",X),process.exit(1)});function uJ(X){let Y={};for(let $=0;$<X.length;$++){let J=X[$];if(J==="--follow"||J==="-f"){if(Y.follow=!0,X[$+1]&&!X[$+1].startsWith("-"))Y.followFile=X[++$]}else if(J==="--once")Y.once=!0;else if(J==="--debug"||J==="-d")Y.debug=!0;else if(J==="--help"||J==="-h")console.log(`
27
+ ... (truncated, ${Y.length-q} more lines)`,Q=!0;this.updateState({selectedFile:{path:K,content:Z,truncated:Q}})}catch($){this.updateState({selectedFile:{path:K,content:$ instanceof Error?`Error: ${$.message}`:"Failed to read file"}})}}async selectIndex(K){if(K<0||K>=this._state.items.length)return;let $=this._state.items[K];if(this.updateState({selectedIndex:K}),$&&!$.isDirectory)await this.loadFile($.path);else this.updateState({selectedFile:null})}navigateUp(K){let $=Math.max(0,this._state.selectedIndex-1);if($===this._state.selectedIndex)return null;if(this.selectIndex($),$<K)return $;return null}navigateDown(K,$){let J=Math.min(this._state.items.length-1,this._state.selectedIndex+1);if(J===this._state.selectedIndex)return null;this.selectIndex(J);let Z=this._state.items.length>$?$-2:$,Q=K+Z;if(J>=Q)return K+1;return null}async enterDirectory(){let K=this._state.items[this._state.selectedIndex];if(!K)return;if(K.isDirectory)if(K.name===".."){let $=L.dirname(this._state.currentPath);await this.loadDirectory($==="."?"":$)}else await this.loadDirectory(K.path)}async goUp(){if(this._state.currentPath){let K=L.dirname(this._state.currentPath);await this.loadDirectory(K==="."?"":K)}}dispose(){this.removeAllListeners()}}import d8 from"neo-blessed";class uK{box;screen;selectedIndex;currentTheme;onSelect;onCancel;constructor(K,$,J,X){if(this.screen=K,this.currentTheme=$,this.onSelect=J,this.onCancel=X,this.selectedIndex=C.indexOf($),this.selectedIndex<0)this.selectedIndex=0;let Z=50,Q=C.length+12;this.box=d8.box({parent:K,top:"center",left:"center",width:Z,height:Q,border:{type:"line"},style:{border:{fg:"cyan"}},tags:!0,keys:!0}),this.setupKeyHandlers(),this.render()}setupKeyHandlers(){this.box.key(["escape","q"],()=>{this.close(),this.onCancel()}),this.box.key(["enter","space"],()=>{let K=C[this.selectedIndex];this.close(),this.onSelect(K)}),this.box.key(["up","k"],()=>{this.selectedIndex=Math.max(0,this.selectedIndex-1),this.render()}),this.box.key(["down","j"],()=>{this.selectedIndex=Math.min(C.length-1,this.selectedIndex+1),this.render()})}render(){let K=[];K.push("{bold}{cyan-fg} Select Theme{/cyan-fg}{/bold}"),K.push("");for(let J=0;J<C.length;J++){let X=C[J],Z=$K[X],Q=J===this.selectedIndex,q=X===this.currentTheme,Y=Q?"{cyan-fg}{bold}> ":" ";if(Y+=Z.displayName,Q)Y+="{/bold}{/cyan-fg}";if(q)Y+=" {gray-fg}(current){/gray-fg}";K.push(Y)}K.push(""),K.push("{gray-fg}Preview:{/gray-fg}");let $=s(C[this.selectedIndex]);K.push(" {green-fg}+ added line{/green-fg}"),K.push(" {red-fg}- deleted line{/red-fg}"),K.push(""),K.push("{gray-fg}j/k: navigate | Enter: select | Esc: cancel{/gray-fg}"),this.box.setContent(K.join(`
28
+ `)),this.screen.render()}close(){this.box.destroy()}focus(){this.box.focus()}}import l8 from"neo-blessed";var w=[{title:"Navigation",entries:[{key:"j/k",description:"Move up/down"},{key:"Tab",description:"Toggle pane focus"}]},{title:"Staging",entries:[{key:"s",description:"Stage file"},{key:"U",description:"Unstage file"},{key:"A",description:"Stage all"},{key:"Z",description:"Unstage all"},{key:"Space",description:"Toggle stage"}]},{title:"Actions",entries:[{key:"c",description:"Commit panel"},{key:"r",description:"Refresh"},{key:"q",description:"Quit"}]},{title:"Resize",entries:[{key:"-",description:"Shrink top pane"},{key:"+",description:"Grow top pane"}]},{title:"Tabs",entries:[{key:"1",description:"Diff view"},{key:"2",description:"Commit panel"},{key:"3",description:"History view"},{key:"4",description:"Compare view"},{key:"5",description:"Explorer view"}]},{title:"Toggles",entries:[{key:"m",description:"Mouse mode"},{key:"w",description:"Wrap mode"},{key:"f",description:"Follow mode"},{key:"t",description:"Theme picker"},{key:"?",description:"This help"}]},{title:"Explorer",entries:[{key:"Enter",description:"Enter directory"},{key:"Backspace",description:"Go up"}]},{title:"Compare",entries:[{key:"b",description:"Base branch picker"},{key:"u",description:"Toggle uncommitted"}]},{title:"Diff",entries:[{key:"d",description:"Discard changes"}]}];class pK{box;screen;onClose;constructor(K,$){this.screen=K,this.onClose=$;let{width:J,height:X}=K,Z=J>=90,Q=Z?Math.min(80,J-4):Math.min(42,J-4),q=Math.min(this.calculateHeight(Z),X-4);this.box=l8.box({parent:K,top:"center",left:"center",width:Q,height:q,border:{type:"line"},style:{border:{fg:"cyan"}},tags:!0,keys:!0,scrollable:!0,alwaysScroll:!0}),this.setupKeyHandlers(),this.render(Z,Q)}calculateHeight(K){if(K){let $=Math.ceil(w.length/2),J=w.slice(0,$),X=w.slice($),Z=J.reduce((q,Y)=>q+Y.entries.length+2,0),Q=X.reduce((q,Y)=>q+Y.entries.length+2,0);return Math.max(Z,Q)+5}else return w.reduce(($,J)=>$+J.entries.length+2,0)+5}setupKeyHandlers(){this.box.key(["escape","enter","?","q"],()=>{this.close(),this.onClose()}),this.box.on("click",()=>{this.close(),this.onClose()})}visibleWidth(K){return K.replace(/\{[^}]+\}/g,"").length}padToVisible(K,$){let J=this.visibleWidth(K),X=Math.max(0,$-J);return K+" ".repeat(X)}render(K,$){let J=[];if(J.push("{bold}{cyan-fg} Keyboard Shortcuts{/cyan-fg}{/bold}"),J.push(""),K){let X=Math.ceil(w.length/2),Z=w.slice(0,X),Q=w.slice(X),q=Math.floor(($-6)/2),Y=this.renderGroups(Z,q),V=this.renderGroups(Q,q),_=Math.max(Y.length,V.length);for(let z=0;z<_;z++){let U=this.padToVisible(Y[z]||"",q),B=V[z]||"";J.push(U+" "+B)}}else for(let X of w){J.push(`{bold}{gray-fg}${X.title}{/gray-fg}{/bold}`);for(let Z of X.entries)J.push(` {cyan-fg}${Z.key.padEnd(10)}{/cyan-fg} ${Z.description}`);J.push("")}J.push(""),J.push("{gray-fg}Press Esc, Enter, or ? to close{/gray-fg}"),this.box.setContent(J.join(`
29
+ `)),this.screen.render()}renderGroups(K,$){let J=[];for(let X of K){J.push(`{bold}{gray-fg}${X.title}{/gray-fg}{/bold}`);for(let Z of X.entries)J.push(` {cyan-fg}${Z.key.padEnd(10)}{/cyan-fg} ${Z.description}`);J.push("")}return J}close(){this.box.destroy()}focus(){this.box.focus()}}import o8 from"neo-blessed";class gK{box;screen;branches;selectedIndex;currentBranch;onSelect;onCancel;constructor(K,$,J,X,Z){if(this.screen=K,this.branches=$,this.currentBranch=J,this.onSelect=X,this.onCancel=Z,this.selectedIndex=J?$.indexOf(J):0,this.selectedIndex<0)this.selectedIndex=0;let Q=50,Y=Math.min($.length,15)+6;this.box=o8.box({parent:K,top:"center",left:"center",width:Q,height:Y,border:{type:"line"},style:{border:{fg:"cyan"}},tags:!0,keys:!0,scrollable:!0,alwaysScroll:!0}),this.setupKeyHandlers(),this.render()}setupKeyHandlers(){this.box.key(["escape","q"],()=>{this.close(),this.onCancel()}),this.box.key(["enter","space"],()=>{let K=this.branches[this.selectedIndex];if(K)this.close(),this.onSelect(K)}),this.box.key(["up","k"],()=>{this.selectedIndex=Math.max(0,this.selectedIndex-1),this.render()}),this.box.key(["down","j"],()=>{this.selectedIndex=Math.min(this.branches.length-1,this.selectedIndex+1),this.render()})}render(){let K=[];if(K.push("{bold}{cyan-fg} Select Base Branch{/cyan-fg}{/bold}"),K.push(""),this.branches.length===0)K.push("{gray-fg}No branches found{/gray-fg}");else for(let $=0;$<this.branches.length;$++){let J=this.branches[$],X=$===this.selectedIndex,Z=J===this.currentBranch,Q=X?"{cyan-fg}{bold}> ":" ";if(Q+=J,X)Q+="{/bold}{/cyan-fg}";if(Z)Q+=" {gray-fg}(current){/gray-fg}";K.push(Q)}K.push(""),K.push("{gray-fg}j/k: navigate | Enter: select | Esc: cancel{/gray-fg}"),this.box.setContent(K.join(`
30
+ `)),this.screen.render()}close(){this.box.destroy()}focus(){this.box.focus()}}import r8 from"neo-blessed";class mK{box;screen;filePath;onConfirm;onCancel;constructor(K,$,J,X){this.screen=K,this.filePath=$,this.onConfirm=J,this.onCancel=X;let Z=Math.min(60,Math.max(40,$.length+20)),Q=7;this.box=r8.box({parent:K,top:"center",left:"center",width:Z,height:Q,border:{type:"line"},style:{border:{fg:"yellow"}},tags:!0,keys:!0}),this.setupKeyHandlers(),this.render()}setupKeyHandlers(){this.box.key(["y","Y"],()=>{this.close(),this.onConfirm()}),this.box.key(["n","N","escape","q"],()=>{this.close(),this.onCancel()})}render(){let K=[];K.push("{bold}{yellow-fg} Discard Changes?{/yellow-fg}{/bold}"),K.push("");let $=this.box.width-6,J=this.filePath.length>$?"..."+this.filePath.slice(-($-3)):this.filePath;K.push(`{white-fg}${J}{/white-fg}`),K.push(""),K.push("{gray-fg}Press {/gray-fg}{green-fg}y{/green-fg}{gray-fg} to confirm, {/gray-fg}{red-fg}n{/red-fg}{gray-fg} or Esc to cancel{/gray-fg}"),this.box.setContent(K.join(`
31
+ `)),this.screen.render()}close(){this.box.destroy()}focus(){this.box.focus()}}import{EventEmitter as s8}from"node:events";function u7(K,$,J){if(!K.trim())return{valid:!1,error:"Commit message cannot be empty"};if($===0&&!J)return{valid:!1,error:"No changes staged for commit"};return{valid:!0,error:null}}function p7(K){return K.trim()}var g7={message:"",amend:!1,isCommitting:!1,error:null,inputFocused:!1};class fK extends s8{_state={...g7};getHeadMessage;onCommit;onSuccess;stagedCount=0;constructor(K){super();this.getHeadMessage=K.getHeadMessage,this.onCommit=K.onCommit,this.onSuccess=K.onSuccess}get state(){return this._state}update(K){this._state={...this._state,...K},this.emit("change",this._state)}setStagedCount(K){this.stagedCount=K}setMessage(K){this.update({message:K,error:null})}setInputFocused(K){this.update({inputFocused:K}),this.emit("focus-change",K)}async toggleAmend(){let K=!this._state.amend;if(this.update({amend:K}),K&&!this._state.message)try{let $=await this.getHeadMessage();if($)this.update({message:$})}catch{}}async submit(){let K=u7(this._state.message,this.stagedCount,this._state.amend);if(!K.valid){this.update({error:K.error});return}this.update({isCommitting:!0,error:null});try{await this.onCommit(p7(this._state.message),this._state.amend),this.update({message:"",amend:!1,isCommitting:!1,inputFocused:!1}),this.onSuccess()}catch($){this.update({isCommitting:!1,error:$ instanceof Error?$.message:"Commit failed"})}}reset(){this._state={...g7},this.emit("change",this._state)}}import{EventEmitter as a8}from"node:events";var n8={currentPane:"files",bottomTab:"diff",selectedIndex:0,fileListScrollOffset:0,diffScrollOffset:0,historyScrollOffset:0,compareScrollOffset:0,explorerScrollOffset:0,explorerFileScrollOffset:0,historySelectedIndex:0,compareSelectedIndex:0,includeUncommitted:!1,explorerSelectedIndex:0,wrapMode:!1,autoTabEnabled:!1,mouseEnabled:!0,showMiddleDots:!1,hideHiddenFiles:!0,hideGitignored:!0,splitRatio:0.4,activeModal:null,pendingDiscard:null,commitInputFocused:!1};class hK extends a8{_state;constructor(K={}){super();this._state={...n8,...K}}get state(){return this._state}update(K){this._state={...this._state,...K},this.emit("change",this._state)}setPane(K){if(this._state.currentPane!==K)this.update({currentPane:K}),this.emit("pane-change",K)}setTab(K){if(this._state.bottomTab!==K){let $={diff:"files",commit:"commit",history:"history",compare:"compare",explorer:"explorer"};this.update({bottomTab:K,currentPane:$[K]}),this.emit("tab-change",K)}}setSelectedIndex(K){if(this._state.selectedIndex!==K)this.update({selectedIndex:K}),this.emit("selection-change",K)}setFileListScrollOffset(K){this.update({fileListScrollOffset:Math.max(0,K)}),this.emit("scroll-change",{type:"fileList",offset:K})}setDiffScrollOffset(K){this.update({diffScrollOffset:Math.max(0,K)}),this.emit("scroll-change",{type:"diff",offset:K})}setHistoryScrollOffset(K){this.update({historyScrollOffset:Math.max(0,K)}),this.emit("scroll-change",{type:"history",offset:K})}setCompareScrollOffset(K){this.update({compareScrollOffset:Math.max(0,K)}),this.emit("scroll-change",{type:"compare",offset:K})}setExplorerScrollOffset(K){this.update({explorerScrollOffset:Math.max(0,K)}),this.emit("scroll-change",{type:"explorer",offset:K})}setExplorerFileScrollOffset(K){this.update({explorerFileScrollOffset:Math.max(0,K)}),this.emit("scroll-change",{type:"explorerFile",offset:K})}setHistorySelectedIndex(K){this.update({historySelectedIndex:Math.max(0,K)})}setCompareSelectedIndex(K){this.update({compareSelectedIndex:Math.max(0,K)})}toggleIncludeUncommitted(){this.update({includeUncommitted:!this._state.includeUncommitted})}setExplorerSelectedIndex(K){this.update({explorerSelectedIndex:Math.max(0,K)})}toggleWrapMode(){this.update({wrapMode:!this._state.wrapMode,diffScrollOffset:0})}toggleAutoTab(){this.update({autoTabEnabled:!this._state.autoTabEnabled})}toggleMouse(){this.update({mouseEnabled:!this._state.mouseEnabled})}toggleMiddleDots(){this.update({showMiddleDots:!this._state.showMiddleDots})}toggleHideHiddenFiles(){this.update({hideHiddenFiles:!this._state.hideHiddenFiles})}toggleHideGitignored(){this.update({hideGitignored:!this._state.hideGitignored})}adjustSplitRatio(K){let $=Math.min(0.85,Math.max(0.15,this._state.splitRatio+K));this.update({splitRatio:$})}setSplitRatio(K){this.update({splitRatio:Math.min(0.85,Math.max(0.15,K))})}openModal(K){this.update({activeModal:K}),this.emit("modal-change",K)}closeModal(){this.update({activeModal:null}),this.emit("modal-change",null)}toggleModal(K){if(this._state.activeModal===K)this.closeModal();else this.openModal(K)}setPendingDiscard(K){this.update({pendingDiscard:K})}setCommitInputFocused(K){this.update({commitInputFocused:K})}togglePane(){let{bottomTab:K,currentPane:$}=this._state;if(K==="diff"||K==="commit")this.setPane($==="files"?"diff":"files");else if(K==="history")this.setPane($==="history"?"diff":"history");else if(K==="compare")this.setPane($==="compare"?"diff":"compare");else if(K==="explorer")this.setPane($==="explorer"?"diff":"explorer")}}import*as W from"node:path";import*as g from"node:fs";import{watch as z8}from"chokidar";import{EventEmitter as J9}from"node:events";import X9 from"ignore";class m7{queue=[];isProcessing=!1;pendingMutations=0;refreshScheduled=!1;enqueue(K){return new Promise(($,J)=>{this.queue.push({execute:K,resolve:$,reject:J}),this.processNext()})}enqueueMutation(K){return this.pendingMutations++,this.enqueue(K).finally(()=>{this.pendingMutations--})}hasPendingMutations(){return this.pendingMutations>0}scheduleRefresh(K){if(this.pendingMutations>0)return;if(this.refreshScheduled)return;this.refreshScheduled=!0,this.enqueue(async()=>{this.refreshScheduled=!1,await K()}).catch(()=>{this.refreshScheduled=!1})}isBusy(){return this.isProcessing||this.queue.length>0}async processNext(){if(this.isProcessing||this.queue.length===0)return;this.isProcessing=!0;let K=this.queue.shift();try{let $=await K.execute();K.resolve($)}catch($){K.reject($ instanceof Error?$:Error(String($)))}finally{this.isProcessing=!1,this.processNext()}}}var cK=new Map;function f7(K){let $=cK.get(K);if(!$)$=new m7,cK.set(K,$);return $}function h7(K){cK.delete(K)}import{simpleGit as y}from"simple-git";import*as l7 from"node:fs";import*as o7 from"node:path";function c7(K){let $=new Map;for(let J of K.trim().split(`
32
+ `)){if(!J)continue;let X=J.split("\t");if(X.length>=3){let Z=X[0]==="-"?0:parseInt(X[0],10),Q=X[1]==="-"?0:parseInt(X[1],10),q=X.slice(2).join("\t");$.set(q,{insertions:Z,deletions:Q})}}return $}async function i8(K,$){try{let J=o7.join(K,$);return(await l7.promises.readFile(J,"utf-8")).split(`
33
+ `).filter((Z)=>Z.length>0).length}catch{return 0}}function d7(K){switch(K){case"M":return"modified";case"A":return"added";case"D":return"deleted";case"?":return"untracked";case"R":return"renamed";case"C":return"copied";default:return"modified"}}async function r7(K){let $=y(K);try{if(!await $.checkIsRepo())return{files:[],branch:{current:"",ahead:0,behind:0},isRepo:!1};let X=await $.status(),Z=[];for(let G of X.staged)Z.push({path:G,status:"added",staged:!0});for(let G of X.modified)if(!Z.find((T)=>T.path===G&&T.staged))Z.push({path:G,status:"modified",staged:!1});for(let G of X.deleted)Z.push({path:G,status:"deleted",staged:!1});for(let G of X.not_added)Z.push({path:G,status:"untracked",staged:!1});for(let G of X.renamed)Z.push({path:G.to,originalPath:G.from,status:"renamed",staged:!0});let Q=[],q=new Set,Y=X.files.filter((G)=>G.working_dir==="?").map((G)=>G.path),V=await _K(K,Y);for(let G of X.files){if(G.index==="!"||G.working_dir==="!"||V.has(G.path))continue;let M=`${G.path}-${G.index!==" "&&G.index!=="?"}`;if(q.has(M))continue;if(q.add(M),G.index&&G.index!==" "&&G.index!=="?")Q.push({path:G.path,status:d7(G.index),staged:!0});if(G.working_dir&&G.working_dir!==" ")Q.push({path:G.path,status:G.working_dir==="?"?"untracked":d7(G.working_dir),staged:!1})}let[_,z]=await Promise.all([$.diff(["--cached","--numstat"]).catch(()=>""),$.diff(["--numstat"]).catch(()=>"")]),U=c7(_),B=c7(z);for(let G of Q){let M=G.staged?U.get(G.path):B.get(G.path);if(M)G.insertions=M.insertions,G.deletions=M.deletions}let k=Q.filter((G)=>G.status==="untracked");if(k.length>0){let G=await Promise.all(k.map((M)=>i8(K,M.path)));for(let M=0;M<k.length;M++)k[M].insertions=G[M],k[M].deletions=0}return{files:Q,branch:{current:X.current||"HEAD",tracking:X.tracking||void 0,ahead:X.ahead,behind:X.behind},isRepo:!0}}catch{return{files:[],branch:{current:"",ahead:0,behind:0},isRepo:!1}}}async function s7(K,$){await y(K).add($)}async function a7(K,$){await y(K).reset(["HEAD","--",$])}async function n7(K){await y(K).add("-A")}async function i7(K){await y(K).reset(["HEAD"])}async function t7(K,$){await y(K).checkout(["--",$])}async function e7(K,$,J=!1){await y(K).commit($,void 0,J?{"--amend":null}:void 0)}async function K8(K){let $=y(K);try{return(await $.log({n:1})).latest?.message||""}catch{return""}}async function $8(K,$=50){let J=y(K);try{return(await J.log({n:$})).all.map((Z)=>({hash:Z.hash,shortHash:Z.hash.slice(0,7),message:Z.message.split(`
34
+ `)[0],author:Z.author_name,date:new Date(Z.date),refs:Z.refs||""}))}catch{return[]}}import{execSync as t8}from"node:child_process";import{simpleGit as n}from"simple-git";function e8(K){let $=K.match(/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/);if($)return{oldStart:parseInt($[1],10),newStart:parseInt($[2],10)};return null}function GK(K){let $=K.split(`
35
+ `),J=[],X=0,Z=0;for(let Q of $)if(Q.startsWith("diff --git")||Q.startsWith("index ")||Q.startsWith("---")||Q.startsWith("+++")||Q.startsWith("new file")||Q.startsWith("deleted file")||Q.startsWith("Binary files")||Q.startsWith("similarity index")||Q.startsWith("rename from")||Q.startsWith("rename to"))J.push({type:"header",content:Q});else if(Q.startsWith("@@")){let q=e8(Q);if(q)X=q.oldStart,Z=q.newStart;J.push({type:"hunk",content:Q})}else if(Q.startsWith("+"))J.push({type:"addition",content:Q,newLineNum:Z++});else if(Q.startsWith("-"))J.push({type:"deletion",content:Q,oldLineNum:X++});else J.push({type:"context",content:Q,oldLineNum:X++,newLineNum:Z++});return J}async function i(K,$,J=!1){let X=n(K);try{let Z=[];if(J)Z.push("--cached");if($)Z.push("--",$);let Q=await X.diff(Z),q=GK(Q);return{raw:Q,lines:q}}catch{return{raw:"",lines:[]}}}async function dK(K,$){try{let J=t8(`cat "${$}"`,{cwd:K,encoding:"utf-8"}),X=[{type:"header",content:`diff --git a/${$} b/${$}`},{type:"header",content:"new file mode 100644"},{type:"header",content:"--- /dev/null"},{type:"header",content:`+++ b/${$}`}],Z=J.split(`
36
+ `);X.push({type:"hunk",content:`@@ -0,0 +1,${Z.length} @@`});let Q=1;for(let Y of Z)X.push({type:"addition",content:"+"+Y,newLineNum:Q++});return{raw:X.map((Y)=>Y.content).join(`
37
+ `),lines:X}}catch{return{raw:"",lines:[]}}}async function lK(K){return i(K,void 0,!0)}async function oK(K){let $=n(K),J=new Set,X=[];try{let Z=await $.raw(["log","--oneline","--decorate=short","--all","-n","200"]),Q=/\(([^)]+)\)/g;for(let q of Z.split(`
38
+ `)){let Y=Q.exec(q);if(Y){let V=Y[1].split(",").map((_)=>_.trim());for(let _ of V){if(_.startsWith("HEAD")||_.startsWith("tag:")||!_.includes("/"))continue;let z=_.replace(/^.*-> /,"");if(z.includes("/")&&!J.has(z))J.add(z),X.push(z)}}Q.lastIndex=0}if(X.length>0)X.sort((q,Y)=>{let V=q.split("/").slice(1).join("/"),_=Y.split("/").slice(1).join("/"),z=V==="main"||V==="master",U=_==="main"||_==="master";if(z&&!U)return-1;if(!z&&U)return 1;if(z&&U){let B=q.startsWith("origin/"),k=Y.startsWith("origin/");if(B&&!k)return 1;if(!B&&k)return-1}return 0})}catch{}return[...new Set(X)]}async function J8(K){return(await oK(K))[0]??null}async function rK(K,$){let J=n(K),Z=(await J.raw(["merge-base",$,"HEAD"])).trim(),Q=await J.raw(["diff","--numstat",`${Z}...HEAD`]),q=await J.raw(["diff","--name-status",`${Z}...HEAD`]),Y=await J.raw(["diff",`${Z}...HEAD`]),V=Q.trim().split(`
39
+ `).filter((A)=>A),_=new Map;for(let A of V){let j=A.split("\t");if(j.length>=3){let O=j[0]==="-"?0:parseInt(j[0],10),D=j[1]==="-"?0:parseInt(j[1],10),I=j.slice(2).join("\t");_.set(I,{additions:O,deletions:D})}}let z=q.trim().split(`
40
+ `).filter((A)=>A),U=new Map;for(let A of z){let j=A.split("\t");if(j.length>=2){let O=j[0][0],D=j[j.length-1],I;switch(O){case"A":I="added";break;case"D":I="deleted";break;case"R":I="renamed";break;default:I="modified"}U.set(D,I)}}let B=[],k=Y.split(/(?=^diff --git )/m).filter((A)=>A.trim());for(let A of k){let j=A.match(/^diff --git a\/.+ b\/(.+)$/m);if(!j)continue;let O=j[1],D=GK(A),I=_.get(O)||{additions:0,deletions:0},P=U.get(O)||"modified";B.push({path:O,status:P,additions:I.additions,deletions:I.deletions,diff:{raw:A,lines:D}})}let G=0,M=0;for(let A of B)G+=A.additions,M+=A.deletions;let N=(await J.status()).files.length,E=(await J.log({from:Z,to:"HEAD"})).all.map((A)=>({hash:A.hash,shortHash:A.hash.slice(0,7),message:A.message.split(`
41
+ `)[0],author:A.author_name,date:new Date(A.date),refs:A.refs||""}));return{baseBranch:$,stats:{filesChanged:B.length,additions:G,deletions:M},files:B,commits:E,uncommittedCount:N}}async function sK(K,$){let J=n(K);try{let X=await J.raw(["show",$,"--format="]),Z=GK(X);return{raw:X,lines:Z}}catch{return{raw:"",lines:[]}}}async function X8(K,$){let J=n(K),X=await rK(K,$),Z=await J.diff(["--cached","--numstat"]),Q=await J.diff(["--numstat"]),q=await J.diff(["--cached"]),Y=await J.diff([]),V=new Map;for(let A of Z.trim().split(`
42
+ `).filter((j)=>j)){let j=A.split("\t");if(j.length>=3){let O=j[0]==="-"?0:parseInt(j[0],10),D=j[1]==="-"?0:parseInt(j[1],10),I=j.slice(2).join("\t");V.set(I,{additions:O,deletions:D,staged:!0,unstaged:!1})}}for(let A of Q.trim().split(`
43
+ `).filter((j)=>j)){let j=A.split("\t");if(j.length>=3){let O=j[0]==="-"?0:parseInt(j[0],10),D=j[1]==="-"?0:parseInt(j[1],10),I=j.slice(2).join("\t"),P=V.get(I);if(P)P.additions+=O,P.deletions+=D,P.unstaged=!0;else V.set(I,{additions:O,deletions:D,staged:!1,unstaged:!0})}}let _=await J.status(),z=new Map;for(let A of _.files)if(A.index==="A"||A.working_dir==="?")z.set(A.path,"added");else if(A.index==="D"||A.working_dir==="D")z.set(A.path,"deleted");else if(A.index==="R")z.set(A.path,"renamed");else z.set(A.path,"modified");let U=[],k=(q+Y).split(/(?=^diff --git )/m).filter((A)=>A.trim()),G=new Set;for(let A of k){let j=A.match(/^diff --git a\/.+ b\/(.+)$/m);if(!j)continue;let O=j[1];if(G.has(O))continue;G.add(O);let D=GK(A),I=V.get(O)||{additions:0,deletions:0},P=z.get(O)||"modified";U.push({path:O,status:P,additions:I.additions,deletions:I.deletions,diff:{raw:A,lines:D},isUncommitted:!0})}let M=new Set(X.files.map((A)=>A.path)),T=[];for(let A of X.files){let j=U.find((O)=>O.path===A.path);if(j)T.push(A),T.push(j);else T.push(A)}for(let A of U)if(!M.has(A.path))T.push(A);let N=0,H=0,E=new Set;for(let A of T){if(!E.has(A.path))E.add(A.path);N+=A.additions,H+=A.deletions}return{baseBranch:X.baseBranch,stats:{filesChanged:E.size,additions:N,deletions:H},files:T,commits:X.commits,uncommittedCount:X.uncommittedCount}}import*as S from"node:fs";import*as p from"node:path";import*as Z8 from"node:os";var AK=p.join(Z8.homedir(),".cache","diffstalker","base-branches.json");function K9(){let K=p.dirname(AK);if(!S.existsSync(K))S.mkdirSync(K,{recursive:!0})}function Q8(){try{if(S.existsSync(AK))return JSON.parse(S.readFileSync(AK,"utf-8"))}catch{}return{}}function $9(K){K9(),S.writeFileSync(AK,JSON.stringify(K,null,2)+`
44
+ `)}function q8(K){let $=Q8(),J=p.resolve(K);return $[J]}function Y8(K,$){let J=Q8(),X=p.resolve(K);J[X]=$,$9(J)}class V8 extends J9{repoPath;queue;gitWatcher=null;workingDirWatcher=null;ignorer=null;_state={status:null,diff:null,stagedDiff:"",selectedFile:null,isLoading:!1,error:null};_compareState={compareDiff:null,compareBaseBranch:null,compareLoading:!1,compareError:null};_historyState={commits:[],selectedCommit:null,commitDiff:null,isLoading:!1};_compareSelectionState={type:null,index:0,diff:null};constructor(K){super();this.repoPath=K,this.queue=f7(K)}get state(){return this._state}get compareState(){return this._compareState}get historyState(){return this._historyState}get compareSelectionState(){return this._compareSelectionState}updateState(K){this._state={...this._state,...K},this.emit("state-change",this._state)}updateCompareState(K){this._compareState={...this._compareState,...K},this.emit("compare-state-change",this._compareState)}updateHistoryState(K){this._historyState={...this._historyState,...K},this.emit("history-state-change",this._historyState)}updateCompareSelectionState(K){this._compareSelectionState={...this._compareSelectionState,...K},this.emit("compare-selection-change",this._compareSelectionState)}loadGitignore(){let K=X9();K.add(".git");let $=W.join(this.repoPath,".gitignore");if(g.existsSync($))K.add(g.readFileSync($,"utf-8"));let J=W.join(this.repoPath,".git","info","exclude");if(g.existsSync(J))K.add(g.readFileSync(J,"utf-8"));return K}startWatching(){let K=W.join(this.repoPath,".git");if(!g.existsSync(K))return;let $=W.join(K,"index"),J=W.join(K,"HEAD"),X=W.join(K,"refs"),Z=W.join(this.repoPath,".gitignore");this.gitWatcher=z8([$,J,X,Z],{persistent:!0,ignoreInitial:!0,usePolling:!0,interval:100}),this.ignorer=this.loadGitignore(),this.workingDirWatcher=z8(this.repoPath,{persistent:!0,ignoreInitial:!0,ignored:(q)=>{let Y=W.relative(this.repoPath,q);if(!Y)return!1;return this.ignorer?.ignores(Y)??!1},awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}});let Q=()=>this.scheduleRefresh();this.gitWatcher.on("change",(q)=>{if(q===Z)this.ignorer=this.loadGitignore();Q()}),this.gitWatcher.on("add",Q),this.gitWatcher.on("unlink",Q),this.gitWatcher.on("error",(q)=>{let Y=q instanceof Error?q.message:String(q);this.emit("error",`Git watcher error: ${Y}`)}),this.workingDirWatcher.on("change",Q),this.workingDirWatcher.on("add",Q),this.workingDirWatcher.on("unlink",Q),this.workingDirWatcher.on("error",(q)=>{let Y=q instanceof Error?q.message:String(q);this.emit("error",`Working dir watcher error: ${Y}`)})}dispose(){this.gitWatcher?.close(),this.workingDirWatcher?.close(),h7(this.repoPath)}scheduleRefresh(){this.queue.scheduleRefresh(()=>this.doRefresh())}async refresh(){await this.queue.enqueue(()=>this.doRefresh())}async doRefresh(){this.updateState({isLoading:!0,error:null});try{let K=await r7(this.repoPath);if(!K.isRepo){this.updateState({status:K,diff:null,stagedDiff:"",isLoading:!1,error:"Not a git repository"});return}let[$,J]=await Promise.all([lK(this.repoPath),i(this.repoPath,void 0,!1)]),X,Z=this._state.selectedFile;if(Z){let Q=K.files.find((q)=>q.path===Z.path&&q.staged===Z.staged);if(Q)if(Q.status==="untracked")X=await dK(this.repoPath,Q.path);else X=await i(this.repoPath,Q.path,Q.staged);else X=J.raw?J:$,this.updateState({selectedFile:null})}else if(J.raw)X=J;else if($.raw)X=$;else X={raw:"",lines:[]};this.updateState({status:K,diff:X,stagedDiff:$.raw,isLoading:!1})}catch(K){this.updateState({isLoading:!1,error:K instanceof Error?K.message:"Unknown error"})}}async selectFile(K){if(this.updateState({selectedFile:K}),!this._state.status?.isRepo)return;await this.queue.enqueue(async()=>{if(K){let $;if(K.status==="untracked")$=await dK(this.repoPath,K.path);else $=await i(this.repoPath,K.path,K.staged);this.updateState({diff:$})}else{let $=await lK(this.repoPath);this.updateState({diff:$})}})}async stage(K){let $=this._state.status;if($)this.updateState({status:{...$,files:$.files.map((J)=>J.path===K.path&&!J.staged?{...J,staged:!0}:J)}});try{await this.queue.enqueueMutation(()=>s7(this.repoPath,K.path)),this.scheduleRefresh()}catch(J){await this.refresh(),this.updateState({error:`Failed to stage ${K.path}: ${J instanceof Error?J.message:String(J)}`})}}async unstage(K){let $=this._state.status;if($)this.updateState({status:{...$,files:$.files.map((J)=>J.path===K.path&&J.staged?{...J,staged:!1}:J)}});try{await this.queue.enqueueMutation(()=>a7(this.repoPath,K.path)),this.scheduleRefresh()}catch(J){await this.refresh(),this.updateState({error:`Failed to unstage ${K.path}: ${J instanceof Error?J.message:String(J)}`})}}async discard(K){if(K.staged||K.status==="untracked")return;try{await this.queue.enqueueMutation(()=>t7(this.repoPath,K.path)),await this.refresh()}catch($){this.updateState({error:`Failed to discard ${K.path}: ${$ instanceof Error?$.message:String($)}`})}}async stageAll(){try{await this.queue.enqueueMutation(()=>n7(this.repoPath)),await this.refresh()}catch(K){this.updateState({error:`Failed to stage all: ${K instanceof Error?K.message:String(K)}`})}}async unstageAll(){try{await this.queue.enqueueMutation(()=>i7(this.repoPath)),await this.refresh()}catch(K){this.updateState({error:`Failed to unstage all: ${K instanceof Error?K.message:String(K)}`})}}async commit(K,$=!1){try{await this.queue.enqueue(()=>e7(this.repoPath,K,$)),await this.refresh()}catch(J){this.updateState({error:`Failed to commit: ${J instanceof Error?J.message:String(J)}`})}}async getHeadCommitMessage(){return this.queue.enqueue(()=>K8(this.repoPath))}async refreshCompareDiff(K=!1){this.updateCompareState({compareLoading:!0,compareError:null});try{await this.queue.enqueue(async()=>{let $=this._compareState.compareBaseBranch;if(!$)$=q8(this.repoPath)??await J8(this.repoPath),this.updateCompareState({compareBaseBranch:$});if($){let J=K?await X8(this.repoPath,$):await rK(this.repoPath,$);this.updateCompareState({compareDiff:J,compareLoading:!1})}else this.updateCompareState({compareDiff:null,compareLoading:!1,compareError:"No base branch found"})})}catch($){this.updateCompareState({compareLoading:!1,compareError:`Failed to load compare diff: ${$ instanceof Error?$.message:String($)}`})}}async getCandidateBaseBranches(){return oK(this.repoPath)}async setCompareBaseBranch(K,$=!1){this.updateCompareState({compareBaseBranch:K}),Y8(this.repoPath,K),await this.refreshCompareDiff($)}async loadHistory(K=100){this.updateHistoryState({isLoading:!0});try{let $=await this.queue.enqueue(()=>$8(this.repoPath,K));this.updateHistoryState({commits:$,isLoading:!1})}catch($){this.updateHistoryState({isLoading:!1}),this.updateState({error:`Failed to load history: ${$ instanceof Error?$.message:String($)}`})}}async selectHistoryCommit(K){if(this.updateHistoryState({selectedCommit:K,commitDiff:null}),!K)return;try{await this.queue.enqueue(async()=>{let $=await sK(this.repoPath,K.hash);this.updateHistoryState({commitDiff:$})})}catch($){this.updateState({error:`Failed to load commit diff: ${$ instanceof Error?$.message:String($)}`})}}async selectCompareCommit(K){let $=this._compareState.compareDiff;if(!$||K<0||K>=$.commits.length){this.updateCompareSelectionState({type:null,index:0,diff:null});return}let J=$.commits[K];this.updateCompareSelectionState({type:"commit",index:K,diff:null});try{await this.queue.enqueue(async()=>{let X=await sK(this.repoPath,J.hash);this.updateCompareSelectionState({diff:X})})}catch(X){this.updateState({error:`Failed to load commit diff: ${X instanceof Error?X.message:String(X)}`})}}selectCompareFile(K){let $=this._compareState.compareDiff;if(!$||K<0||K>=$.files.length){this.updateCompareSelectionState({type:null,index:0,diff:null});return}let J=$.files[K];this.updateCompareSelectionState({type:"file",index:K,diff:J.diff})}}var kK=new Map;function U8(K){let $=kK.get(K);if(!$)$=new V8(K),kK.set(K,$);return $}function aK(K){let $=kK.get(K);if($)$.dispose(),kK.delete(K)}import*as m from"node:fs";import*as jK from"node:path";import{watch as Z9}from"chokidar";import{EventEmitter as Q9}from"node:events";import*as _8 from"node:path";import*as nK from"node:os";function B8(K){if(K.startsWith("~/"))return _8.join(nK.homedir(),K.slice(2));if(K==="~")return nK.homedir();return K}function iK(K){let $=K.split(`
45
+ `);for(let J=$.length-1;J>=0;J--){let X=$[J].trim();if(X)return X}return""}class tK extends Q9{targetFile;debug;watcher=null;debounceTimer=null;lastReadPath=null;_state={path:null,lastUpdate:null,rawContent:null,sourceFile:null};constructor(K,$=!1){super();this.targetFile=K,this.debug=$,this._state.sourceFile=K}get state(){return this._state}updateState(K){this._state={...this._state,...K},this.emit("path-change",this._state)}processContent(K){if(!K)return null;let $=B8(K);return jK.isAbsolute($)?$:jK.resolve($)}readTargetDebounced(){if(this.debounceTimer)clearTimeout(this.debounceTimer);this.debounceTimer=setTimeout(()=>{this.readTarget()},100)}readTarget(){try{let K=m.readFileSync(this.targetFile,"utf-8"),$=iK(K);if($&&$!==this.lastReadPath){let J=this.processContent($),X=new Date;if(this.debug&&J)process.stderr.write(`[diffstalker ${X.toISOString()}] Path change detected
46
+ `),process.stderr.write(` Source file: ${this.targetFile}
47
+ `),process.stderr.write(` Raw content: "${$}"
48
+ `),process.stderr.write(` Previous: "${this.lastReadPath??"(none)"}"
49
+ `),process.stderr.write(` Resolved: "${J}"
50
+ `);this.lastReadPath=J,this.updateState({path:J,lastUpdate:X,rawContent:$})}}catch{}}start(){if(J7(this.targetFile),!m.existsSync(this.targetFile))m.writeFileSync(this.targetFile,"");try{let K=m.readFileSync(this.targetFile,"utf-8"),$=iK(K);if($){let J=this.processContent($),X=new Date;if(this.debug&&J)process.stderr.write(`[diffstalker ${X.toISOString()}] Initial path read
51
+ `),process.stderr.write(` Source file: ${this.targetFile}
52
+ `),process.stderr.write(` Raw content: "${$}"
53
+ `),process.stderr.write(` Resolved: "${J}"
54
+ `);this.lastReadPath=J,this._state={path:J,lastUpdate:X,rawContent:$,sourceFile:this.targetFile}}}catch{}this.watcher=Z9(this.targetFile,{persistent:!0,ignoreInitial:!0}),this.watcher.on("change",()=>this.readTargetDebounced()),this.watcher.on("add",()=>this.readTargetDebounced())}stop(){if(this.debounceTimer)clearTimeout(this.debounceTimer),this.debounceTimer=null;if(this.watcher)this.watcher.close(),this.watcher=null}}class eK{screen;layout;uiState;gitManager=null;fileWatcher=null;explorerManager=null;config;commandServer;repoPath;watcherState={enabled:!1};currentTheme;commitFlowState;commitTextarea=null;activeModal=null;bottomPaneTotalRows=0;constructor(K){this.config=K.config,this.commandServer=K.commandServer??null,this.repoPath=K.initialPath??process.cwd(),this.currentTheme=K.config.theme,this.uiState=new hK({splitRatio:K.config.splitRatio??0.4}),this.screen=G8.screen({smartCSR:!0,fullUnicode:!0,title:"diffstalker",mouse:!0,terminal:"xterm-256color"});let $=this.screen;if($.tput)$.tput.colors=256;if($.program?.tput)$.program.tput.colors=256;if(this.layout=new OK(this.screen,this.uiState.state.splitRatio),this.screen.on("resize",()=>{setImmediate(()=>this.render())}),this.commitFlowState=new fK({getHeadMessage:()=>this.gitManager?.getHeadCommitMessage()??Promise.resolve(""),onCommit:async(J,X)=>{await this.gitManager?.commit(J,X)},onSuccess:()=>{this.uiState.setTab("diff"),this.render()}}),this.commitTextarea=G8.textarea({parent:this.layout.bottomPane,top:3,left:1,width:"100%-4",height:1,inputOnFocus:!0,hidden:!0,style:{fg:"white",bg:"default"}}),this.commitTextarea.on("submit",()=>{this.commitFlowState.submit()}),this.commitTextarea.on("keypress",()=>{setImmediate(()=>{let J=this.commitTextarea?.getValue()??"";this.commitFlowState.setMessage(J)})}),this.setupKeyboardHandlers(),this.setupMouseHandlers(),this.setupStateListeners(),this.config.watcherEnabled)this.setupFileWatcher();if(this.commandServer)this.setupCommandHandler();this.initGitManager(),this.render()}setupKeyboardHandlers(){this.screen.key(["q","C-c"],()=>{this.exit()}),this.screen.key(["j","down"],()=>{if(this.activeModal)return;this.navigateDown()}),this.screen.key(["k","up"],()=>{if(this.activeModal)return;this.navigateUp()}),this.screen.key(["1"],()=>{if(this.activeModal)return;this.uiState.setTab("diff")}),this.screen.key(["2"],()=>{if(this.activeModal)return;this.uiState.setTab("commit")}),this.screen.key(["3"],()=>{if(this.activeModal)return;this.uiState.setTab("history")}),this.screen.key(["4"],()=>{if(this.activeModal)return;this.uiState.setTab("compare")}),this.screen.key(["5"],()=>{if(this.activeModal)return;this.uiState.setTab("explorer")}),this.screen.key(["tab"],()=>{if(this.activeModal)return;this.uiState.togglePane()}),this.screen.key(["s"],()=>{if(this.activeModal)return;this.stageSelected()}),this.screen.key(["S-u"],()=>{if(this.activeModal)return;this.unstageSelected()}),this.screen.key(["S-a"],()=>{if(this.activeModal)return;this.stageAll()}),this.screen.key(["S-z"],()=>{if(this.activeModal)return;this.unstageAll()}),this.screen.key(["enter","space"],()=>{if(this.activeModal)return;let K=this.uiState.state;if(K.bottomTab==="explorer"&&K.currentPane==="explorer")this.enterExplorerDirectory();else this.toggleSelected()}),this.screen.key(["backspace"],()=>{if(this.activeModal)return;let K=this.uiState.state;if(K.bottomTab==="explorer"&&K.currentPane==="explorer")this.goExplorerUp()}),this.screen.key(["c"],()=>{if(this.activeModal)return;this.uiState.setTab("commit")}),this.screen.key(["i"],()=>{if(this.uiState.state.bottomTab==="commit"&&!this.commitFlowState.state.inputFocused)this.focusCommitInput()}),this.screen.key(["a"],()=>{if(this.uiState.state.bottomTab==="commit"&&!this.commitFlowState.state.inputFocused)this.commitFlowState.toggleAmend(),this.render()}),this.screen.key(["escape"],()=>{if(this.uiState.state.bottomTab==="commit")if(this.commitFlowState.state.inputFocused)this.unfocusCommitInput();else this.uiState.setTab("diff")}),this.screen.key(["r"],()=>this.refresh()),this.screen.key(["w"],()=>this.uiState.toggleWrapMode()),this.screen.key(["m"],()=>this.toggleMouseMode()),this.screen.key(["S-t"],()=>this.uiState.toggleAutoTab()),this.screen.key(["-","_"],()=>{this.uiState.adjustSplitRatio(-MK),this.layout.setSplitRatio(this.uiState.state.splitRatio),this.render()}),this.screen.key(["=","+"],()=>{this.uiState.adjustSplitRatio(MK),this.layout.setSplitRatio(this.uiState.state.splitRatio),this.render()}),this.screen.key(["t"],()=>this.uiState.openModal("theme")),this.screen.key(["?"],()=>this.uiState.toggleModal("hotkeys")),this.screen.key(["f"],()=>this.toggleFollow()),this.screen.key(["b"],()=>{if(this.uiState.state.bottomTab==="compare")this.uiState.openModal("baseBranch")}),this.screen.key(["u"],()=>{if(this.uiState.state.bottomTab==="compare"){this.uiState.toggleIncludeUncommitted();let K=this.uiState.state.includeUncommitted;this.gitManager?.refreshCompareDiff(K)}}),this.screen.key(["d"],()=>{if(this.uiState.state.bottomTab==="diff"){let K=this.gitManager?.state.status?.files??[],$=this.uiState.state.selectedIndex,J=K[$];if(J&&!J.staged&&J.status!=="untracked")this.showDiscardConfirm(J)}})}setupMouseHandlers(){this.layout.topPane.on("wheeldown",()=>{this.handleTopPaneScroll(3)}),this.layout.topPane.on("wheelup",()=>{this.handleTopPaneScroll(-3)}),this.layout.bottomPane.on("wheeldown",()=>{this.handleBottomPaneScroll(3)}),this.layout.bottomPane.on("wheelup",()=>{this.handleBottomPaneScroll(-3)}),this.layout.topPane.on("click",($)=>{let J=this.layout.screenYToTopPaneRow($.y);if(J>=0)this.handleTopPaneClick(J)}),this.layout.footerBox.on("click",($)=>{this.handleFooterClick($.x)})}handleTopPaneClick(K){let $=this.uiState.state;if($.bottomTab==="history"){let J=$.historyScrollOffset+K;this.uiState.setHistorySelectedIndex(J),this.selectHistoryCommitByIndex(J)}else if($.bottomTab==="compare"){let J=this.gitManager?.compareState,X=J?.compareDiff?.commits??[],Z=J?.compareDiff?.files??[],Q=PK($.compareScrollOffset+K,X,Z);if(Q)this.selectCompareItem(Q)}else if($.bottomTab==="explorer"){let J=$.explorerScrollOffset+K;this.explorerManager?.selectIndex(J),this.uiState.setExplorerSelectedIndex(J)}else{let J=this.gitManager?.state.status?.files??[],X=V7(K+$.fileListScrollOffset,J);if(X!==null&&X>=0)this.uiState.setSelectedIndex(X),this.selectFileByIndex(X)}}handleFooterClick(K){let $=this.screen.width||80,J=[{tab:"explorer",label:"[5]Explorer",width:11},{tab:"compare",label:"[4]Compare",width:10},{tab:"history",label:"[3]History",width:10},{tab:"commit",label:"[2]Commit",width:9},{tab:"diff",label:"[1]Diff",width:7}],X=$;for(let{tab:Z,width:Q}of J){let q=X-Q-1;if(K>=q&&K<X){this.uiState.setTab(Z);return}X=q}if(K>=2&&K<=9)this.toggleMouseMode();else if(K>=11&&K<=16)this.uiState.toggleAutoTab();else if(K>=18&&K<=23)this.uiState.toggleWrapMode();else if(K>=25&&K<=30&&this.uiState.state.bottomTab==="explorer")this.uiState.toggleMiddleDots();else if(K===0)this.uiState.openModal("hotkeys")}handleTopPaneScroll(K){let $=this.uiState.state,J=this.layout.dimensions.topPaneHeight;if($.bottomTab==="history"){let X=this.gitManager?.historyState.commits.length??0,Z=Math.max(0,X-J),Q=Math.min(Z,Math.max(0,$.historyScrollOffset+K));this.uiState.setHistoryScrollOffset(Q)}else if($.bottomTab==="compare"){let X=this.gitManager?.compareState,Z=L7(X?.compareDiff?.commits??[],X?.compareDiff?.files??[]),Q=Math.max(0,Z-J),q=Math.min(Q,Math.max(0,$.compareScrollOffset+K));this.uiState.setCompareScrollOffset(q)}else if($.bottomTab==="explorer"){let X=y7(this.explorerManager?.state.items??[]),Z=Math.max(0,X-J),Q=Math.min(Z,Math.max(0,$.explorerScrollOffset+K));this.uiState.setExplorerScrollOffset(Q)}else{let X=this.gitManager?.state.status?.files??[],Z=Y7(X),Q=Math.max(0,Z-J),q=Math.min(Q,Math.max(0,$.fileListScrollOffset+K));this.uiState.setFileListScrollOffset(q)}}handleBottomPaneScroll(K){let $=this.uiState.state,J=this.layout.dimensions.bottomPaneHeight,X=this.screen.width||80;if($.bottomTab==="explorer"){let Z=this.explorerManager?.state.selectedFile,Q=w7(Z?.content??null,Z?.path??null,Z?.truncated??!1,X,$.wrapMode),q=Math.max(0,Q-J),Y=Math.min(q,Math.max(0,$.explorerFileScrollOffset+K));this.uiState.setExplorerFileScrollOffset(Y)}else{let Z=Math.max(0,this.bottomPaneTotalRows-J),Q=Math.min(Z,Math.max(0,$.diffScrollOffset+K));this.uiState.setDiffScrollOffset(Q)}}setupStateListeners(){this.uiState.on("change",()=>{this.render()}),this.uiState.on("tab-change",($)=>{if($==="history")this.gitManager?.loadHistory();else if($==="compare")this.gitManager?.refreshCompareDiff(this.uiState.state.includeUncommitted);else if($==="explorer"){if(!this.explorerManager?.state.items.length)this.explorerManager?.loadDirectory("")}}),this.uiState.on("modal-change",($)=>{if(this.activeModal)this.activeModal=null;if($==="theme")this.activeModal=new uK(this.screen,this.currentTheme,(J)=>{this.currentTheme=J,NK({theme:J}),this.activeModal=null,this.uiState.closeModal(),this.render()},()=>{this.activeModal=null,this.uiState.closeModal()}),this.activeModal.focus();else if($==="hotkeys")this.activeModal=new pK(this.screen,()=>{this.activeModal=null,this.uiState.closeModal()}),this.activeModal.focus();else if($==="baseBranch")this.gitManager?.getCandidateBaseBranches().then((J)=>{let X=this.gitManager?.compareState.compareBaseBranch??null;this.activeModal=new gK(this.screen,J,X,(Z)=>{this.activeModal=null,this.uiState.closeModal();let Q=this.uiState.state.includeUncommitted;this.gitManager?.setCompareBaseBranch(Z,Q)},()=>{this.activeModal=null,this.uiState.closeModal()}),this.activeModal.focus()})});let K=null;this.uiState.on("change",($)=>{if(K)clearTimeout(K);K=setTimeout(()=>{if($.splitRatio!==this.config.splitRatio)NK({splitRatio:$.splitRatio})},500)})}setupFileWatcher(){this.fileWatcher=new tK(this.config.targetFile),this.fileWatcher.on("path-change",($)=>{if($.path&&$.path!==this.repoPath)this.repoPath=$.path,this.watcherState={enabled:!0,sourceFile:$.sourceFile??this.config.targetFile,rawContent:$.rawContent??void 0,lastUpdate:$.lastUpdate??void 0},this.initGitManager(),this.render();if($.rawContent)this.navigateToFile($.rawContent),this.render()}),this.watcherState={enabled:!0,sourceFile:this.config.targetFile},this.fileWatcher.start();let K=this.fileWatcher.state;if(K.rawContent)this.watcherState.rawContent=K.rawContent,this.navigateToFile(K.rawContent)}initGitManager(){if(this.gitManager)this.gitManager.removeAllListeners(),aK(this.repoPath);this.gitManager=U8(this.repoPath),this.gitManager.on("state-change",()=>{this.render()}),this.gitManager.on("history-state-change",(K)=>{if(K.commits.length>0&&!K.selectedCommit){let $=this.uiState.state;if($.bottomTab==="history")this.selectHistoryCommitByIndex($.historySelectedIndex)}this.render()}),this.gitManager.on("compare-state-change",()=>{this.render()}),this.gitManager.on("compare-selection-change",()=>{this.render()}),this.gitManager.startWatching(),this.gitManager.refresh(),this.initExplorerManager()}initExplorerManager(){if(this.explorerManager)this.explorerManager.dispose();let K={hideHidden:!0,hideGitignored:!0};this.explorerManager=new wK(this.repoPath,K),this.explorerManager.on("state-change",()=>{this.render()}),this.explorerManager.loadDirectory("")}setupCommandHandler(){if(!this.commandServer)return;let K={navigateUp:()=>this.navigateUp(),navigateDown:()=>this.navigateDown(),switchTab:($)=>this.uiState.setTab($),togglePane:()=>this.uiState.togglePane(),stage:async()=>this.stageSelected(),unstage:async()=>this.unstageSelected(),stageAll:async()=>this.stageAll(),unstageAll:async()=>this.unstageAll(),commit:async($)=>this.commit($),refresh:async()=>this.refresh(),getState:()=>this.getAppState(),quit:()=>this.exit()};this.commandServer.setHandler(K),this.commandServer.notifyReady()}getAppState(){let K=this.uiState.state,$=this.gitManager?.state,J=this.gitManager?.historyState,X=$?.status?.files??[],Z=J?.commits??[];return{currentTab:K.bottomTab,currentPane:K.currentPane,selectedIndex:K.selectedIndex,totalFiles:X.length,stagedCount:X.filter((Q)=>Q.staged).length,files:X.map((Q)=>({path:Q.path,status:Q.status,staged:Q.staged})),historySelectedIndex:K.historySelectedIndex,historyCommitCount:Z.length,compareSelectedIndex:K.compareSelectedIndex,compareTotalItems:0,includeUncommitted:K.includeUncommitted,explorerPath:this.repoPath,explorerSelectedIndex:K.explorerSelectedIndex,explorerItemCount:0,wrapMode:K.wrapMode,mouseEnabled:K.mouseEnabled,autoTabEnabled:K.autoTabEnabled}}navigateUp(){let K=this.uiState.state;if(K.bottomTab==="history"){if(K.currentPane==="history")this.navigateHistoryUp();else if(K.currentPane==="diff")this.uiState.setDiffScrollOffset(Math.max(0,K.diffScrollOffset-3));return}if(K.bottomTab==="compare"){if(K.currentPane==="compare")this.navigateCompareUp();else if(K.currentPane==="diff")this.uiState.setDiffScrollOffset(Math.max(0,K.diffScrollOffset-3));return}if(K.bottomTab==="explorer"){if(K.currentPane==="explorer")this.navigateExplorerUp();else if(K.currentPane==="diff")this.uiState.setExplorerFileScrollOffset(Math.max(0,K.explorerFileScrollOffset-3));return}if(K.currentPane==="files"){let $=this.gitManager?.state.status?.files??[],J=Math.max(0,K.selectedIndex-1);this.uiState.setSelectedIndex(J),this.selectFileByIndex(J);let X=TK(J,$);if(X<K.fileListScrollOffset)this.uiState.setFileListScrollOffset(X)}else if(K.currentPane==="diff")this.uiState.setDiffScrollOffset(Math.max(0,K.diffScrollOffset-3))}navigateDown(){let K=this.uiState.state,$=this.gitManager?.state.status?.files??[];if(K.bottomTab==="history"){if(K.currentPane==="history")this.navigateHistoryDown();else if(K.currentPane==="diff")this.uiState.setDiffScrollOffset(K.diffScrollOffset+3);return}if(K.bottomTab==="compare"){if(K.currentPane==="compare")this.navigateCompareDown();else if(K.currentPane==="diff")this.uiState.setDiffScrollOffset(K.diffScrollOffset+3);return}if(K.bottomTab==="explorer"){if(K.currentPane==="explorer")this.navigateExplorerDown();else if(K.currentPane==="diff")this.uiState.setExplorerFileScrollOffset(K.explorerFileScrollOffset+3);return}if(K.currentPane==="files"){let J=Math.min($.length-1,K.selectedIndex+1);this.uiState.setSelectedIndex(J),this.selectFileByIndex(J);let X=TK(J,$),Z=K.fileListScrollOffset+this.layout.dimensions.topPaneHeight-1;if(X>=Z)this.uiState.setFileListScrollOffset(K.fileListScrollOffset+(X-Z+1))}else if(K.currentPane==="diff")this.uiState.setDiffScrollOffset(K.diffScrollOffset+3)}navigateHistoryUp(){let K=this.uiState.state,$=Math.max(0,K.historySelectedIndex-1);if($!==K.historySelectedIndex){if(this.uiState.setHistorySelectedIndex($),$<K.historyScrollOffset)this.uiState.setHistoryScrollOffset($);this.selectHistoryCommitByIndex($)}}navigateHistoryDown(){let K=this.uiState.state,$=this.gitManager?.historyState.commits??[],J=Math.min($.length-1,K.historySelectedIndex+1);if(J!==K.historySelectedIndex){this.uiState.setHistorySelectedIndex(J);let X=K.historyScrollOffset+this.layout.dimensions.topPaneHeight-1;if(J>=X)this.uiState.setHistoryScrollOffset(K.historyScrollOffset+1);this.selectHistoryCommitByIndex(J)}}selectHistoryCommitByIndex(K){let $=this.gitManager?.historyState.commits??[],J=F7($,K);if(J)this.uiState.setDiffScrollOffset(0),this.gitManager?.selectHistoryCommit(J)}compareSelection=null;navigateCompareUp(){let K=this.gitManager?.compareState,$=K?.compareDiff?.commits??[],J=K?.compareDiff?.files??[];if($.length===0&&J.length===0)return;let X=CK(this.compareSelection,$,J,"up");if(X&&(X.type!==this.compareSelection?.type||X.index!==this.compareSelection?.index)){this.selectCompareItem(X);let Z=this.uiState.state,Q=UK(X,$,J);if(Q<Z.compareScrollOffset)this.uiState.setCompareScrollOffset(Q)}}navigateCompareDown(){let K=this.gitManager?.compareState,$=K?.compareDiff?.commits??[],J=K?.compareDiff?.files??[];if($.length===0&&J.length===0)return;if(!this.compareSelection){if($.length>0)this.selectCompareItem({type:"commit",index:0});else if(J.length>0)this.selectCompareItem({type:"file",index:0});return}let X=CK(this.compareSelection,$,J,"down");if(X&&(X.type!==this.compareSelection?.type||X.index!==this.compareSelection?.index)){this.selectCompareItem(X);let Z=this.uiState.state,Q=UK(X,$,J),q=Z.compareScrollOffset+this.layout.dimensions.topPaneHeight-1;if(Q>=q)this.uiState.setCompareScrollOffset(Z.compareScrollOffset+(Q-q+1))}}selectCompareItem(K){if(this.compareSelection=K,this.uiState.setDiffScrollOffset(0),K.type==="commit")this.gitManager?.selectCompareCommit(K.index);else this.gitManager?.selectCompareFile(K.index)}navigateExplorerUp(){let K=this.uiState.state;if((this.explorerManager?.state.items??[]).length===0)return;let J=this.explorerManager?.navigateUp(K.explorerScrollOffset);if(J!==null&&J!==void 0)this.uiState.setExplorerScrollOffset(J);this.uiState.setExplorerSelectedIndex(this.explorerManager?.state.selectedIndex??0)}navigateExplorerDown(){let K=this.uiState.state;if((this.explorerManager?.state.items??[]).length===0)return;let J=this.layout.dimensions.topPaneHeight,X=this.explorerManager?.navigateDown(K.explorerScrollOffset,J);if(X!==null&&X!==void 0)this.uiState.setExplorerScrollOffset(X);this.uiState.setExplorerSelectedIndex(this.explorerManager?.state.selectedIndex??0)}async enterExplorerDirectory(){await this.explorerManager?.enterDirectory(),this.uiState.setExplorerScrollOffset(0),this.uiState.setExplorerFileScrollOffset(0),this.uiState.setExplorerSelectedIndex(0)}async goExplorerUp(){await this.explorerManager?.goUp(),this.uiState.setExplorerScrollOffset(0),this.uiState.setExplorerFileScrollOffset(0),this.uiState.setExplorerSelectedIndex(0)}selectFileByIndex(K){let $=this.gitManager?.state.status?.files??[],J=z7($,K);if(J)this.uiState.setDiffScrollOffset(0),this.gitManager?.selectFile(J)}navigateToFile(K){if(!K||!this.repoPath)return;let $=this.repoPath.endsWith("/")?this.repoPath:this.repoPath+"/";if(!K.startsWith($))return;let J=K.slice($.length);if(!J)return;let Z=(this.gitManager?.state.status?.files??[]).findIndex((Q)=>Q.path===J);if(Z>=0)this.uiState.setSelectedIndex(Z),this.selectFileByIndex(Z)}async stageSelected(){let $=(this.gitManager?.state.status?.files??[])[this.uiState.state.selectedIndex];if($&&!$.staged)await this.gitManager?.stage($)}async unstageSelected(){let $=(this.gitManager?.state.status?.files??[])[this.uiState.state.selectedIndex];if($?.staged)await this.gitManager?.unstage($)}async toggleSelected(){let $=(this.gitManager?.state.status?.files??[])[this.uiState.state.selectedIndex];if($)if($.staged)await this.gitManager?.unstage($);else await this.gitManager?.stage($)}async stageAll(){await this.gitManager?.stageAll()}async unstageAll(){await this.gitManager?.unstageAll()}showDiscardConfirm(K){this.activeModal=new mK(this.screen,K.path,async()=>{this.activeModal=null,await this.gitManager?.discard(K)},()=>{this.activeModal=null}),this.activeModal.focus()}async commit(K){await this.gitManager?.commit(K)}async refresh(){await this.gitManager?.refresh()}toggleMouseMode(){let K=!this.uiState.state.mouseEnabled;this.uiState.toggleMouse();let $=this.screen.program;if(K)$.enableMouse();else $.disableMouse()}toggleFollow(){if(this.fileWatcher)this.fileWatcher.stop(),this.fileWatcher=null,this.watcherState={enabled:!1};else this.setupFileWatcher();this.render()}focusCommitInput(){if(this.commitTextarea)this.commitTextarea.show(),this.commitTextarea.focus(),this.commitTextarea.setValue(this.commitFlowState.state.message),this.commitFlowState.setInputFocused(!0),this.render()}unfocusCommitInput(){if(this.commitTextarea){let K=this.commitTextarea.getValue()??"";this.commitFlowState.setMessage(K),this.commitTextarea.hide(),this.commitFlowState.setInputFocused(!1),this.screen.focusPush(this.layout.bottomPane),this.render()}}render(){this.updateHeader(),this.updateTopPane(),this.updateBottomPane(),this.updateFooter(),this.screen.render()}updateHeader(){let K=this.gitManager?.state,$=this.screen.width||80,J=X7(this.repoPath,K?.status?.branch??null,K?.isLoading??!1,K?.error??null,this.watcherState,$);this.layout.headerBox.setContent(J)}updateTopPane(){let K=this.gitManager?.state,$=this.gitManager?.historyState,J=this.gitManager?.compareState,X=K?.status?.files??[],Z=this.uiState.state,Q=this.screen.width||80,q;if(Z.bottomTab==="history"){let Y=$?.commits??[];q=R7(Y,Z.historySelectedIndex,Z.currentPane==="history",Q,Z.historyScrollOffset,this.layout.dimensions.topPaneHeight)}else if(Z.bottomTab==="compare"){let Y=J?.compareDiff,V=Y?.commits??[],_=Y?.files??[];q=v7(V,_,this.compareSelection,Z.currentPane==="compare",Q,Z.compareScrollOffset,this.layout.dimensions.topPaneHeight)}else if(Z.bottomTab==="explorer"){let Y=this.explorerManager?.state,V=Y?.items??[];q=W7(V,Z.explorerSelectedIndex,Z.currentPane==="explorer",Q,Z.explorerScrollOffset,this.layout.dimensions.topPaneHeight,Y?.isLoading??!1,Y?.error??null)}else q=q7(X,Z.selectedIndex,Z.currentPane==="files",Q,Z.fileListScrollOffset,this.layout.dimensions.topPaneHeight);this.layout.topPane.setContent(q)}updateBottomPane(){let K=this.gitManager?.state,$=this.gitManager?.historyState,J=K?.diff??null,X=this.uiState.state,Z=this.screen.width||80,q=(K?.status?.files??[]).filter((Y)=>Y.staged).length;if(this.commitFlowState.setStagedCount(q),X.bottomTab==="commit"){let Y=D7(this.commitFlowState.state,q,Z);if(this.layout.bottomPane.setContent(Y),this.commitTextarea)if(this.commitFlowState.state.inputFocused)this.commitTextarea.show();else this.commitTextarea.hide()}else if(X.bottomTab==="history"){if(this.commitTextarea)this.commitTextarea.hide();let Y=$?.selectedCommit??null,V=$?.commitDiff??null,{content:_,totalRows:z}=I7(Y,V,Z,X.diffScrollOffset,this.layout.dimensions.bottomPaneHeight,this.currentTheme,X.wrapMode);this.bottomPaneTotalRows=z,this.layout.bottomPane.setContent(_)}else if(X.bottomTab==="compare"){if(this.commitTextarea)this.commitTextarea.hide();let V=this.gitManager?.compareSelectionState?.diff??null;if(V){let{content:_,totalRows:z}=yK(V,Z,X.diffScrollOffset,this.layout.dimensions.bottomPaneHeight,this.currentTheme,X.wrapMode);this.bottomPaneTotalRows=z,this.layout.bottomPane.setContent(_)}else this.bottomPaneTotalRows=0,this.layout.bottomPane.setContent("{gray-fg}Select a commit or file to view diff{/gray-fg}")}else if(X.bottomTab==="explorer"){if(this.commitTextarea)this.commitTextarea.hide();let V=this.explorerManager?.state?.selectedFile??null,_=x7(V?.path??null,V?.content??null,Z,X.explorerFileScrollOffset,this.layout.dimensions.bottomPaneHeight,V?.truncated??!1,X.wrapMode,X.showMiddleDots);this.layout.bottomPane.setContent(_)}else{if(this.commitTextarea)this.commitTextarea.hide();let{content:Y,totalRows:V}=yK(J,Z,X.diffScrollOffset,this.layout.dimensions.bottomPaneHeight,this.currentTheme,X.wrapMode);this.bottomPaneTotalRows=V,this.layout.bottomPane.setContent(Y)}}updateFooter(){let K=this.uiState.state,$=this.screen.width||80,J=Q7(K.bottomTab,K.mouseEnabled,K.autoTabEnabled,K.wrapMode,K.showMiddleDots,$);this.layout.footerBox.setContent(J)}exit(){if(this.gitManager)aK(this.repoPath);if(this.explorerManager)this.explorerManager.dispose();if(this.fileWatcher)this.fileWatcher.stop();if(this.commandServer)this.commandServer.stop();this.screen.destroy()}start(){return new Promise((K)=>{this.screen.on("destroy",()=>{K()})})}}import*as A8 from"net";import*as u from"fs";import{EventEmitter as q9}from"events";class K7 extends q9{server=null;socketPath;handler=null;ready=!1;constructor(K){super();this.socketPath=K}setHandler(K){this.handler=K}notifyReady(){this.ready=!0,this.emit("ready")}isReady(){return this.ready&&this.handler!==null}async start(){if(u.existsSync(this.socketPath))u.unlinkSync(this.socketPath);return new Promise((K,$)=>{this.server=A8.createServer((J)=>{this.handleConnection(J)}),this.server.on("error",(J)=>{$(J)}),this.server.listen(this.socketPath,()=>{u.chmodSync(this.socketPath,384),K()})})}stop(){if(this.server)this.server.close(),this.server=null;if(u.existsSync(this.socketPath))u.unlinkSync(this.socketPath)}handleConnection(K){let $="";K.on("data",async(J)=>{$+=J.toString();let X=$.split(`
55
+ `);$=X.pop()||"";for(let Z of X)if(Z.trim()){let Q=await this.processCommand(Z);K.write(JSON.stringify(Q)+`
56
+ `)}}),K.on("error",(J)=>{this.emit("error",J)})}async processCommand(K){try{let $=JSON.parse(K);if($.action==="ping")return{success:!0,ready:this.isReady()};if(!this.handler)return{success:!1,error:"No handler registered"};switch($.action){case"navigateUp":return this.handler.navigateUp(),{success:!0};case"navigateDown":return this.handler.navigateDown(),{success:!0};case"switchTab":return this.handler.switchTab($.tab),{success:!0};case"togglePane":return this.handler.togglePane(),{success:!0};case"stage":return await this.handler.stage(),{success:!0};case"unstage":return await this.handler.unstage(),{success:!0};case"stageAll":return await this.handler.stageAll(),{success:!0};case"unstageAll":return await this.handler.unstageAll(),{success:!0};case"commit":return await this.handler.commit($.message),{success:!0};case"refresh":return await this.handler.refresh(),{success:!0};case"getState":return{success:!0,state:this.handler.getState()};case"quit":return this.handler.quit(),{success:!0};default:return{success:!1,error:`Unknown action: ${$.action}`}}}catch($){return{success:!1,error:$ instanceof Error?$.message:String($)}}}}function f(){process.stdout.write("\x1B[?1006l"),process.stdout.write("\x1B[?1002l"),process.stdout.write("\x1B[?1000l"),process.stdout.write("\x1B[?1003l"),process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[?1049l"),process.stdout.write("\x1B[r")}f();process.on("exit",f);process.on("SIGINT",()=>{f(),process.exit(0)});process.on("SIGTERM",()=>{f(),process.exit(0)});process.on("uncaughtException",(K)=>{f(),console.error("Uncaught exception:",K),process.exit(1)});process.on("unhandledRejection",(K)=>{f(),console.error("Unhandled rejection:",K),process.exit(1)});function Y9(K){let $={};for(let J=0;J<K.length;J++){let X=K[J];if(X==="--follow"||X==="-f"){if($.follow=!0,K[J+1]&&!K[J+1].startsWith("-"))$.followFile=K[++J]}else if(X==="--once")$.once=!0;else if(X==="--debug"||X==="-d")$.debug=!0;else if(X==="--socket"||X==="-s")if(K[J+1]&&!K[J+1].startsWith("-"))$.socket=K[++J];else console.error("Error: --socket requires a path argument"),process.exit(1);else if(X==="--help"||X==="-h")console.log(`
43
57
  diffstalker - Terminal git diff/status viewer
44
58
 
45
59
  Usage: diffstalker [options] [path]
@@ -47,6 +61,7 @@ Usage: diffstalker [options] [path]
47
61
  Options:
48
62
  -f, --follow [FILE] Follow hook file for dynamic repo switching
49
63
  (default: ~/.cache/diffstalker/target)
64
+ -s, --socket PATH Enable IPC server on Unix socket for testing
50
65
  --once Show status once and exit
51
66
  -d, --debug Log path changes to stderr for debugging
52
67
  -h, --help Show this help message
@@ -64,20 +79,19 @@ Environment:
64
79
  DIFFSTALKER_PAGER External pager for diff display
65
80
 
66
81
  Keyboard:
67
- j/k, ↑/↓ Navigate files / scroll diff
68
- Ctrl+S Stage selected file
69
- Ctrl+U Unstage selected file
70
- Ctrl+A Stage all files
71
- Ctrl+Z Unstage all files
72
- Enter/Space Toggle stage/unstage
73
- Tab Switch between panes
74
- 1/2 Switch bottom tab (Diff/Commit)
75
- c Open commit panel
76
- r Refresh
77
- q / Ctrl+C Quit
82
+ j/k, Up/Down Navigate files / scroll diff
83
+ s Stage selected file
84
+ Shift+u Unstage selected file
85
+ Shift+a Stage all files
86
+ Shift+z Unstage all files
87
+ Enter/Space Toggle stage/unstage
88
+ Tab Switch between panes
89
+ 1/2/3/4/5 Switch tabs (Diff/Commit/History/Compare/Explorer)
90
+ c Open commit panel
91
+ r Refresh
92
+ q / Ctrl+C Quit
78
93
 
79
94
  Mouse:
80
- Click Select file / focus pane
81
- Click [+/-] Stage/unstage file
82
- Scroll Navigate files / scroll diff
83
- `),process.exit(0);else if(!J.startsWith("-"))Y.initialPath=J}return Y}var r8=uJ(process.argv.slice(2)),RX=mY();if(r8.follow){if(RX.watcherEnabled=!0,r8.followFile)RX.targetFile=r8.followFile}if(r8.debug)RX.debug=!0;var{waitUntilExit:hJ}=pJ(xJ(g9,{config:RX,initialPath:r8.initialPath}));hJ().then(()=>{process.exit(0)});
95
+ Click Select file / focus pane
96
+ Scroll Navigate files / scroll diff
97
+ `),process.exit(0);else if(!X.startsWith("-"))$.initialPath=X}return $}async function z9(){let K=Y9(process.argv.slice(2)),$=$7();if(K.follow){if($.watcherEnabled=!0,K.followFile)$.targetFile=K.followFile}if(K.debug)$.debug=!0;let J=null;if(K.socket){J=new K7(K.socket);try{await J.start()}catch(Z){console.error("Failed to start command server:",Z),process.exit(1)}}if(await new eK({config:$,initialPath:K.initialPath,commandServer:J}).start(),J)J.stop();process.exit(0)}z9().catch((K)=>{console.error("Fatal error:",K),f(),process.exit(1)});