bisgit 0.3.0 → 0.5.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.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import{b as n,c as s}from"./chunk-HCUVDNFV.js";import{normalize as a}from"node:path";async function g(){let{stdout:t}=await n("git branch --show-current");return t.trim()}async function d(t){t??=await g();let{stdout:r}=await n(`git config --get branch.${t}.remote`);return r.trim()}async function y(t,r){try{let{stdout:e}=await n(`git rev-list --count ${t}/${r}..${r}`);return parseInt(e.trim(),10)}catch(e){return console.error("Error getting commits ahead:",e),NaN}}async function h(t,r){try{let{stdout:e}=await n(`git rev-list --count ${r}..${t}/${r}`);return parseInt(e.trim(),10)}catch(e){return console.error("Error getting commits behind:",e),NaN}}async function w(t){let{stdout:r}=await n(`git rev-parse --git-path ${t}`);return a(r.trim())}async function x(){let{stdout:t}=await n("git rev-parse --git-dir");return a(t.trim())}async function $(t){let{code:r}=await s("git",["remote","get-url",t],{stdio:"ignore"});return r===0}async function P(){let{stdout:t}=await n("git rev-parse --abbrev-ref HEAD");return t.trim()==="HEAD"}async function v(t,r){let e="git fetch";t&&(e+=` ${t}`),r&&(e+=` ${r}`),await n(e)}async function b(){let{stdout:t}=await s("git",["status","--porcelain"]);return!t?.trim()}async function D(){let{stdout:t}=await s("git",["status","--porcelain"]);return t?.trim()?.split(/\r?\n/)}async function m(t,r){let{stdout:e}=await n(`git merge-base ${t} ${r}`);return e.trim()}async function R(t,r){let e=await m(t,r),{stdout:i}=await s("git",["merge-tree",e,r,t]);return!i?.split(/\r?\n/)?.includes("+=======")}async function A(t){let{stdout:r}=await n(`git rev-parse ${t}`);return r.trim()}async function B(t,r,e){let{stdout:i}=await n(`git rev-list ${e?"--reverse":""} ${t}..${r}`);return i.trim().split(/\r?\n/)}async function G(){let{stdout:t}=await n("git for-each-ref --format='%(refname:short)' refs/heads");return t.trim().split(/\r?\n/)}async function L(){let{stdout:t}=await n("git remote -v");return t.trim().split(/\r?\n/).map(e=>{let i=e.match(/^(\S+)\s+(\S+)\s+\((fetch|push)\)$/);if(!i)return null;let[,o,c,u]=i;return{name:o,url:c,type:u}}).filter(e=>e!==null)}import p from"fs/promises";async function C(t){try{return await p.access(t),!0}catch{return!1}}export{g as a,d as b,y as c,h as d,w as e,x as f,$ as g,P as h,v as i,b as j,D as k,m as l,R as m,A as n,B as o,G as p,L as q,C as r};
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import{b as g,c as z}from"./chunk-5WTQIRZS.js";import{a as h,b as Z,c as B,d as H,e as D,f as Q,g as X,h as tt,i as W,j as d,k as G,l as R,m as et,n as ot,o as F,p as rt,r as y}from"./chunk-C7H7IYZ2.js";import{a as u,b as s,c as w,d as l}from"./chunk-HCUVDNFV.js";import S from"node:path";async function it(){let t=await G(),e=/^(UU|DU|UD)/;return!!t?.some(o=>e.test(o))}async function N(){let t=await Q(),[e,o,r,i,n]=await Promise.all([await y(S.join(t,"MERGE_HEAD")),await y(S.join(t,"rebase-merge")),await y(S.join(t,"rebase-apply")),await y(S.join(t,"CHERRY_PICK_HEAD")),await y(S.join(t,"REVERT_HEAD"))]);return{merge:e,rebaseMerge:o,rebaseApply:r,cherryPick:i,revert:n}}async function nt(){let{merge:t,rebaseMerge:e,rebaseApply:o,cherryPick:r,revert:i}=await N(),n="";if(t)n="merge";else if(e||o)n="rebase";else if(r)n="cherry-pick";else if(i)n="revert";else{let a=await it()?"Conflicts exist, but likely are from a stash and are not abortable. Resolve them manually.":"Nothing to abort.";console.log(a);return}console.log(`Aborting the ${n}`),await l([n,"--abort"])}import{spawnSync as st}from"node:child_process";function E(t,e,o){let{status:r}=st(t,e,{stdio:"ignore"});r!==0&&(o&&console.error(o),process.exit(1))}var at=()=>E("git",["rev-parse","--git-dir"],"Need to use command in a git repository."),C=()=>E("git",["rev-parse","HEAD"],"Need to create first commit."),b=(t="origin")=>E("git",["remote","get-url",t],`Need to add remote '${t}'.`),O=t=>E("git",["show-ref","--branches",t],`Branch '${t}' isn't tracked locally and may not exist.`),P=async()=>{await d()||(console.error("You should stash or commit your changes first."),process.exit(1))},M=async t=>{await y(t)||(console.error(`${t} must exist for this operation and it doesn't for some reason`),process.exit(1))},T=async()=>{await tt()&&(console.error("Operation not allowed in a 'detached HEAD' state"),process.exit(1))},ct=t=>E("git",["rev-parse","--abbrev-ref","--symbolic-full-name",`${t}@{u}`],`branch '${t}' has no upstream`);function $(t="Error: missing required argument"){if(process.argv[3])return process.argv[3];console.error(t),process.exit(1)}async function v(){let{status:t}=st("git",["diff","--staged","--quiet"],{stdio:"ignore"});t===0&&(console.error("You have no staged changes"),process.exit(1))}async function mt(){await T(),await v(),u("git",["commit","--amend","--no-edit",...g()],{stdio:"inherit",silent:!0,triggerExit:!0})}import{render as Kt}from"ink";import{render as Yt}from"ink";import{Suspense as Lt,use as Ut,useEffect as It}from"react";import{Text as lt,useApp as Ot}from"ink";import jt from"ink-spinner";import{jsx as L,jsxs as Vt}from"react/jsx-runtime";function c(t){let{msg:e}=t;return L(Lt,{fallback:Vt(lt,{children:[L(jt,{type:"dots"}),"\xA0",e]}),children:L(_t,{...t})})}function _t({msg:t,promise:e}){let o=Ut(e),{exit:r}=Ot();return It(()=>{r()},[o]),L(lt,{children:`\u2714 ${typeof o=="string"?o:t}`})}import{jsx as Jt}from"react/jsx-runtime";async function ft(){let t=process.argv[3],e=process.argv[4]??await h();if(O(t),O(e),t===e)return console.log(`No reason to merge '${t}' into '${e}'`);let o=await Z(t);b(o),Yt(Jt(c,{msg:"Updating target branch and merging",promise:(async()=>{try{await q(o,t)}catch{console.error(`Error when updating branch ${t} with remote ${o}. Fix divergent branches before merging into ${e}`);return}await h()!==e&&await s(`git switch ${e}`),u("git",["merge",t],{stdio:"inherit",silent:!0})})()}))}async function q(t,e){await W(t,e);let[o,r,i]=await Promise.all([B(t,e),H(t,e),h()]);if(r!==0){if(o===0&&i!==e){await s(`git fetch ${t} ${e}:${e}`);return}if(await s(`git switch ${e}`),o===0){await s(`git merge ${t}/${e}`);return}await l(["merge",`${t}/${e}`],["ignore","ignore","inherit"])}}async function k(){C(),b();let{stdout:t,code:e}=await w("git",["rev-parse","--abbrev-ref","origin/HEAD"]);if(e===0)return pt(t.trim());await s("git remote set-head origin -a");let{stdout:o}=await s("git rev-parse --abbrev-ref origin/HEAD");return pt(o.trim())}async function gt(){let{remote:t,branch:e}=await k();console.log(`Remote default branch is '${t}/${e}'`)}async function pt(t){let e=t.split("/"),o=t.split("/").map((r,i)=>e.slice(0,i+1).join("/"));for(let r of o)if(await X(r)){let i=t.slice(r.length+1);return{remote:r,branch:i}}throw new Error("Failed to get default remote")}import{jsx as Zt}from"react/jsx-runtime";var zt=["master","main","development","lingoport"];async function ut(){await P();let{branch:t,remote:e}=await k();await s(`git switch ${t}`);let o=(async()=>{await l(["fetch","--prune","--prune-tags"]),await q(e,t)})();Kt(Zt(c,{msg:"Fetching and pruning remote references",promise:o})),await o;let r=await rt();for(let i of r){if(i===t||zt.includes(i))continue;let{code:n}=await w("git",["diff","--quiet",t,i]);if(n===0){j(i);continue}let{code:a}=await w("git",["merge-base","--is-ancestor",i,t]);if(a===0){j(i);continue}let m=await R(i,t),{stdout:f}=await w("git",["merge-tree",m,t,i]);f?.trim()||j(i)}}function j(t){l(["branch","-D",t])}import{spawn as Qt}from"node:child_process";import{createInterface as Xt}from"node:readline/promises";async function wt(){C;let e=[...(await te()).entries()].sort(([,r],[,i])=>i-r).slice(0,25),o=e[0][1].toString().length;console.info(e.map(([r,i])=>`${String(i).padEnd(o)} ${r}:`).join(`
3
+ `))}async function te(){let{promise:t,resolve:e,reject:o}=Promise.withResolvers(),r=new Map,i=Qt("git",["log","--all","-M","-C","--name-only","--format=format:"]),n=Xt({input:i.stdout,crlfDelay:1/0});return n.on("line",a=>{let m=a.trim();m&&r.set(m,(r.get(m)??0)+1)}),n.on("close",()=>e(r)),i.on("error",o),t}import{render as ee}from"ink";import{jsx as re}from"react/jsx-runtime";async function ht(){await v();let t=$("Error: missing github username argument"),e=(async()=>{let i=await oe(t);return i.email||(console.error(`Couldn't find an email for ${t}`),process.exit(1)),i})();ee(re(c,{msg:"Fetching name and email",promise:e}));let{name:o,email:r}=await e;l(["commit","--edit","-m","<insert summary>","-m",`Co-authored-by: ${o} <${r}>`])}async function oe(t){let{stdout:e}=await s(`gh api users/${t}`);return JSON.parse(e.trim())}import{render as _}from"ink";import{isDeepStrictEqual as ie}from"node:util";import{jsx as V}from"react/jsx-runtime";async function dt(){let t=$("Error: missing id of PR to checkout");await P();let e=(async()=>Promise.all([s(`gh co ${t}`),s(`gh pr view ${t} --json baseRefName -q .baseRefName`)]))();_(V(c,{msg:`Checking out pr #${t}`,promise:e}));let[,{stdout:o}]=await e,r=o.trim(),i=(async()=>{await s(`git switch ${r}`),await s("git pull"),await s("git switch -")})();_(V(c,{msg:`Updating ${r} branch merge destination`,promise:i})),await i;let n=(async()=>{let p=await R(r,"HEAD");return await s(`git reset ${p} --soft`),await ne("HEAD")})();_(V(c,{msg:"Creating an editable, explorable, local PR experience",promise:n}));let[a,m]=await Promise.all([n,se(t)]),{files:f,additions:x,deletions:I}=m;if(ie(a,m))return console.info(`Files: ${f}, +${x} -${I}`);console.info("The PR stat doesn't match the local stat."),console.info("LOCAL"),console.table(a),console.info("GITHUB"),console.table(m),console.info("One option to fix (there'll likely be conflicts):"),console.info("1. git stash -u"),console.info(`2. git merge ${r}`),console.info("3. git stash pop")}async function ne(t){let{stdout:e}=await s(`git diff --shortstat ${t}`),o=/(\d+)\s+files? changed(?:, (\d+) insertions?\(\+\))?(?:, (\d+) deletions?\(-\))?/,r=e.trim().match(o);if(!r)throw new Error(`Couldn't generate short stat for ref(s): ${t}`);let[,i,n,a]=r;return{files:parseInt(i,10),additions:n?parseInt(n,10):0,deletions:a?parseInt(a,10):0}}async function se(t){let{stdout:e}=await s(`gh pr view ${t} --json deletions,files,additions`),o=JSON.parse(e.trim());return o.files=o.files.length,o}import{spawn as ae}from"node:child_process";import{createInterface as ce}from"node:readline/promises";import Y from"chalk";async function yt(){let t=$("Error: missing target branch argument"),e=await R("HEAD",t),{promise:o,resolve:r,reject:i}=Promise.withResolvers(),n=ae("git",["merge-tree",e,"HEAD",t]),a=ce({input:n.stdout,crlfDelay:1/0}),m=!1,f=0;a.on("line",p=>{p=p.trimEnd(),p==="+<<<<<<< .our"?(m=!0,console.info(Y.red(p)),f+=1):p==="+>>>>>>> .their"?(m=!1,console.info(Y.green(p))):p==="+======="?console.info(Y.yellow(p)):m&&console.info(p)}),a.on("close",()=>r(f)),n.on("error",i);let x=await o,I=x?`\u274C ${x} conflicts would occur!`:"\u2705 No conflicts. Safe to merge.";console.info(I)}async function bt(){let{merge:t,rebaseMerge:e,rebaseApply:o,cherryPick:r,revert:i}=await N(),n="";if(t)n="merge";else if(e||o)n="rebase";else if(r)n="cherry-pick";else if(i)n="revert";else{console.log("Nothing to continue.");return}console.log(`Continuing the ${n}`),await l([n,"--continue"])}import{appendFileSync as le}from"node:fs";import{readFile as me}from"node:fs/promises";async function U(t){return(await me(t,"utf-8")).split(/\r?\n/).map(o=>o.trim()).filter(o=>o&&!o.startsWith("#"))}async function $t(){let t=await D("info/exclude");await M(t);let e=await U(t);g().forEach(o=>{e.includes(o)?console.info(`Already Exists: '${o}'`):(le(t,`${o}
4
+ `),console.info(`Added '${o}'`))}),console.info(`
5
+ See file at ${t}`)}function xt(){u("git",["show","--name-only","--pretty=format:",...g()],{stdio:"inherit",silent:!0,triggerExit:!0})}import{spawn as fe}from"node:child_process";async function Rt(){let t=$("Error: missing valid target ref argument");await v();let e=await ot(t);await l(["commit",`--fixup=${e}`]);let r=(await F(`${e}^`,"HEAD",!0)).map(n=>pe(n));(await Promise.all(r)).every(Boolean)||(console.warn("Rebase conflict would occur!"),await s("git reset HEAD~1 --soft"),process.exit(1)),await s(`git rebase -i --autosquash ${e}^`)}async function pe(t){let{stdout:e}=await s(`git diff ${t}^ ${t}`),{promise:o,resolve:r,reject:i}=Promise.withResolvers(),n=fe("git",["apply","--check","--3way","-q"],{stdio:["pipe","ignore","ignore"]});return n.on("close",a=>{r(a===0)}),n.on("error",i),n.stdin.write(e),n.stdin.end(),o}import{readFile as ge,writeFile as ue}from"node:fs/promises";async function Ct(){let t=await D("info/exclude");await M(t);let e=await U(t),o=g();o.filter(a=>!e.includes(a)).forEach(a=>console.info(`No match: '${a}'`));let i=(await ge(t,"utf-8")).split(/\r?\n/).map(a=>a.trim()),n=i.filter(a=>!o.includes(a));await ue(t,n.join(`
6
+ `)),console.info(`
7
+ Removed ${i.length-n.length} entries from ${t}`)}import{render as we}from"ink";import{jsx as be}from"react/jsx-runtime";async function Pt(){let t=(async()=>{let i=await he();return await de(i)})();we(be(c,{msg:"Fetching repo languages",promise:t}));let e=await t,o=Object.values(e).reduce((i,n)=>i+n,0),r=Object.entries(e).map(([i,n])=>`${i}: ${Math.round(n/o*100)}% - ${ye(n)}`);console.log(r.join(`
8
+ `))}async function he(){let{stdout:t}=await s("gh repo view --json nameWithOwner -q .nameWithOwner");return t.trim()}async function de(t){let{stdout:e}=await s(`gh api repos/${t}/languages`);return JSON.parse(e.trim())}function ye(t,e=2){if(t===0)return"0 B";let o=1024,r=e<0?0:e,i=["B","KB","MB","GB","TB","PB","EB","ZB","YB"],n=Math.floor(Math.log(t)/Math.log(o));return`${parseFloat((t/Math.pow(o,n)).toFixed(r))} ${i[n]}`}import{execSync as $e}from"node:child_process";function xe(){return $e("git rev-parse --show-toplevel",{encoding:"utf-8"}).trim()}function vt(){let t=xe();console.log(t)}import{render as Dt}from"ink";function At(){return new Date().toLocaleString("en-US",{year:"2-digit",month:"2-digit",day:"2-digit",hour:"numeric",minute:"2-digit",hour12:!0}).replace(",","")}async function A(){let t=At();await s("git add -A"),await l(["commit","-m",`"WIP ${t}"`])}import{nanoid as Re}from"nanoid";import Ce from"chalk";import{jsx as St}from"react/jsx-runtime";async function Et(){let{remote:t,branch:e}=await k(),o=process.argv[3]??e;await d()||await A(),await et(o,"HEAD")||(console.warn("Conflicts would occur. Not safe to rebranch."),process.exit(1));let r=await h(),i=(async()=>{await q(t,o)})();Dt(St(c,{msg:`Updating branch ${o}`,promise:i})),await i;let n=`${Re(8)}`,a=(async()=>{await s(`git switch ${r}`),await s(`git branch ${n}`),await s(`git switch ${o}`),await s(`git branch -D ${r}`),await s(`git switch -c ${r}`);let m=await F(o,n,!0);for(let f of m)try{await s(`git cherry-pick ${f}`)}catch{let x=Ce.yellow(`git branch -D ${r} && git branch -m ${n} ${r}`);throw new Error(`\u274C cherry pick failed at ${f}
9
+ Run this to restore backup branch
10
+ > ${x}`)}await s(`git branch -D ${n}`)})();Dt(St(c,{msg:`Rewriting branch ${r}`,promise:a})),await a,console.info(`Successfully recreated branch ${r} from ${o}`)}import{execSync as Pe}from"node:child_process";async function qt(){C();let t=ve(process.argv[3]),{default:e}=await import("clipboardy");await e.write(t),console.log(`'${t}' copied to clipboard`)}function ve(t="HEAD"){return Pe(`git rev-parse --short ${t}`,{encoding:"utf-8"}).trim()}import{render as Ae}from"ink";import{jsx as De}from"react/jsx-runtime";async function kt(){let{remote:t,branch:e}=await z();b(t),await P();let o=W(t,e);Ae(De(c,{msg:`Fetching branch ${e} from ${t}`,promise:o})),await o,await l(["switch","-c",e,"--track",`${t}/${e}`])}async function J(){let{stdout:t}=await s("npm list -g bisgit --depth=0 --json");return JSON.parse(t.trim()).dependencies.bisgit.version}async function Bt(){console.info(await J())}async function Se(){let{code:t}=await w("npm",["outdated","-g","bisgit"]);return t===0}async function Ee(){let{stdout:t}=await s("npm view bisgit version",{encoding:"utf8"});return t.trim()}async function Ht(){if(await Se())return console.info("Already up to date");console.info(`Updating: ${await J()} -> ${await Ee()}`),u("npm",["i","-g","bisgit@latest"])}async function Wt(){let[t,e]=await Promise.allSettled([await ke("user.name"),await qe()]);t.status==="fulfilled"&&console.info(`Git: ${t.value}`),e.status==="fulfilled"&&console.info(`Github: ${e.value}`)}async function qe(){let{stdout:t}=await s("gh api user --jq .login");return t.trim()}async function ke(t){let{stdout:e}=await s(`git config ${t}`);return e.trim()}import{render as Me}from"ink";import{Text as Be,useApp as He,useInput as We}from"ink";import{useState as Ge}from"react";import{Fragment as Ne,jsx as Fe,jsxs as Gt}from"react/jsx-runtime";function Ft({prompt:t,msg:e,onConfirm:o}){let[r,i]=Ge(""),{exit:n}=He();return We((a,m)=>{if(r)return;let f=a.toLowerCase();f==="y"?i("Yes"):(f==="n"||m.return)&&(i("No"),n())}),Gt(Ne,{children:[Gt(Be,{children:[t," [y/N] ",r]}),r==="Yes"&&Fe(c,{msg:e,promise:o()})]})}import{jsx as Te}from"react/jsx-runtime";async function Nt(){if(at(),await d())return console.log("Already a clean working tree");let t=await G();if(!t)throw new Error("git status cmd failed");let e=new K(t);e.displayReport(),Me(Te(Ft,{prompt:"Approve these changes?",msg:"Running git reset && git clean",onConfirm:async()=>(await s("git reset --hard"),await s("git clean -f"),`Altered ${e.willDelete.length+e.willRecreate.length+e.willRevert.length} files.`)}))}var K=class{willDelete=[];willRecreate=[];willRevert=[];constructor(e){e.forEach(o=>{if(o){let r=o.slice(0,2).trim(),i=o.slice(3);r.includes("?")||r.includes("A")?this.willDelete.push(i):r==="DU"||r==="D"?this.willRecreate.push(i):this.willRevert.push(i)}}),this.willDelete.sort(),this.willRecreate.sort(),this.willRevert.sort()}displayReport(){this.displaySection("Will Recreate:",this.willRecreate),this.displaySection("Will Revert:",this.willRevert),this.displaySection("Will Delete:",this.willDelete)}displaySection(e,o){o.length&&console.log(`${e}
11
+ ${o.map(r=>`- ${r}
12
+ `)}`)}};import{nanoid as Le}from"nanoid";import{render as Ue}from"ink";import{jsx as Ie}from"react/jsx-runtime";async function Mt(){await T();let t=process.argv[3]??"origin";b(t);let e=await h();ct(e);let o="",i=(async()=>{let n=[s(`git fetch ${t} ${e} --force`)];await d()||n.push(A()),await Promise.all(n);let[a,m]=await Promise.all([B(t,e),H(t,e)]);if(!(a===0&&m===0)){if(a!==0){let f=`${e}-${Le(8)}`;o=`Created branch ${f}`,await s(`git branch ${f}`)}await s(`git reset --hard ${t}/${e}`)}})();Ue(Ie(c,{msg:`Force pull reseting ${e} -> ${t}`,promise:i})),await i,o&&console.info(o)}var Tt={abort:nt,amend:mt,autoprune:ut,backmerge:ft,churn:wt,coauthor:ht,"code-review":dt,conflict:yt,continue:bt,exclude:$t,files:xt,fixup:Rt,include:Ct,languages:Pt,pwd:vt,rebranch:Et,"remote-default":gt,savepoint:A,sha:qt,track:kt,update:Ht,"--version":Bt,whoami:Wt,wipe:Nt,yank:Mt};async function nn(t){return await Tt[t]?.(),Object.hasOwn(Tt,t)}export{nn as runCommand};
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import{a as oe,j as re,k as ne,p as ie,q as se,r as ce}from"./chunk-C7H7IYZ2.js";import{b as y}from"./chunk-HCUVDNFV.js";import{render as to}from"ink";import{createContext as _e,useContext as Ye,useState as qe}from"react";import{jsx as Qe}from"react/jsx-runtime";var ae=_e(void 0),de=({children:e})=>{let[t,o]=qe({}),r=(n,s)=>{o(c=>({...c,[n]:s}))},i=n=>{let s=Array.isArray(n)?n:[n];o(c=>{let d={...c};for(let m of s)delete d[m];return d})};return Qe(ae.Provider,{value:{keybindings:t,setKeybinding:r,removeKeybinding:i},children:e})},S=()=>{let e=Ye(ae);if(!e)throw new Error("useKeybindings must be used within a KeybindingsProvider");return e};import{useEffect as Xt}from"react";import{Text as Zt,Box as Fe,useInput as jt}from"ink";import{useStdout as Je}from"ink";function g(){let{stdout:e}=Je(),t=e.rows-2,o=Math.floor(t/2);return{width:e.columns,height:e.rows,sectionHeight:t,sectionHalfHeight:o}}import{Box as ue,Text as je}from"ink";import{useState as E,createContext as ze,useContext as Xe}from"react";import{jsx as Ze}from"react/jsx-runtime";var M={Status:"Status",Log:"Log","Commit Details":"Log",Branches:"Branches",Worktrees:"Branches",Remotes:"Branches"},L=Object.keys(M),le=ze({});function me({children:e}){let[t,o]=E(!1),r=()=>o(!0),i=()=>o(!1),[n,s]=E("Status"),[c,d]=E("Status"),m=a=>{t||(d(a),s(M[a]))},u=a=>{t||(s(a),d(a))},f=()=>{t||d(a=>{let l=L.at((L.indexOf(a)+1)%L.length);return s(M[l]),l})},p=()=>{t||d(a=>{let l=L.at(L.indexOf(a)-1);return s(M[l]),l})};return Ze(le.Provider,{value:{activeGroup:n,setActiveGroup:u,activeSection:c,setActiveSection:m,prevSection:p,nextSection:f,isLocked:t,lock:r,unlock:i},children:e})}function h(){let e=Xe(le);if(!e)throw new Error("useNavContext must be used within a NavProvider");return e}import{jsx as H}from"react/jsx-runtime";var et=Array.from(new Set(Object.values(M)));function fe(){let{activeGroup:e}=h();return H(ue,{width:"100%",flexDirection:"row",children:et.map((t,o)=>H(ue,{borderStyle:"classic",borderLeft:!!o,borderRight:!1,borderTop:!1,borderBottom:!1,children:H(je,{color:t===e?"cyan":"",children:` [${o+1}]: ${t} `})},t))})}import{Text as Qt,useInput as Jt}from"ink";import{Box as pe,measureElement as tt,Text as ge}from"ink";import{useMemo as ot,useRef as rt}from"react";import{Fragment as nt,jsx as D,jsxs as it}from"react/jsx-runtime";function v(e){let{title:t,footer:o,children:r,width:i,height:n,innerHeight:s,isModal:c,backgroundColor:d}=e,{width:m}=g(),u=i??m,f=rt(null),p=ot(()=>{if(!f.current)return 0;let{width:V}=tt(f.current);return V},[f.current]),a=p-8,l={...e,height:s,width:p},{activeSection:w}=h(),B=w===t||c?"cyan":"";return D(pe,{ref:f,flexDirection:"column",height:n,width:u,backgroundColor:d,children:p!==0&&it(nt,{children:[t&&D(ge,{color:B,wrap:"truncate-end",children:"\u256D\u2500\u2500\u2500\u2500 "+t+" "+"\u2500".repeat(a-t.length)+"\u256E"}),D(pe,{flexDirection:"column",...l,borderStyle:"round",borderColor:B,borderTop:!t,borderBottom:!o,paddingLeft:1,children:r}),o&&D(ge,{color:B,wrap:"truncate-end",children:"\u2570"+"\u2500".repeat(a-o.length)+" "+o+" \u2500\u2500\u2500\u2500\u256F"})]})})}import{Text as ct}from"ink";import{useEffect as st,useState as G}from"react";function x(e,t=[]){let[o,r]=G(void 0),[i,n]=G(!1),[s,c]=G(0),d=()=>c(m=>m+1);return st(()=>{let m=!1;return n(!1),r(void 0),e().then(u=>{m||(r(u),n(!0))}).catch(()=>{m||n(!0)}),()=>{m=!0}},[s,...t]),{value:o,resolved:i,refresh:d}}import{jsx as he}from"react/jsx-runtime";function $(){let{value:e,resolved:t}=x(ne);return he(v,{flexDirection:"column",title:"Bisgit",width:"100%",children:t&&e?.map((o,r)=>he(ct,{children:o},r))})}import{useEffect as At,useState as Ne}from"react";import{Box as Wt,useInput as It}from"ink";import{Text as at}from"ink";import{jsx as xe}from"react/jsx-runtime";function ve({sha:e}){let{resolved:t,value:o}=x(()=>dt(e),[e]);return xe(v,{title:"Commit Details",width:"50%",height:"100%",children:e&&t&&xe(at,{children:o})})}async function dt(e){if(!e)return;let{stdout:t}=await y(`git show ${e} --name-only`);return t.trim()}import{useEffect as mt}from"react";import{Box as K,Text as F,useInput as ut}from"ink";import{useEffect as lt,useState as ye}from"react";function R(e,t){let[o,r]=ye(0),[i,n]=ye(0);lt(()=>{r(0),n(0)},[e]);let s=Math.max(0,e.length-t),c=e.length-1,d=()=>{n(p=>{let a=Math.min(p+1,c);return r(l=>a>=l+t?Math.min(l+1,s):l),a})},m=()=>{n(p=>{let a=Math.max(p-1,0);return r(l=>a<l?Math.max(l-1,0):l),a})},u=e.slice(o,o+t),f=e[i];return{scrollDown:d,scrollUp:m,outList:u,selectedIndex:i,selectedValue:f}}import{jsx as C,jsxs as ft}from"react/jsx-runtime";function be({setSha:e,mode:t}){let{label:o,value:r}=t,{sectionHeight:i}=g(),{activeSection:n,isLocked:s}=h(),{resolved:c,value:d=[]}=x(r,[o]),{scrollUp:m,scrollDown:u,outList:f,selectedValue:p}=R(d,i-2),a=p?.sha;return mt(()=>{e(a)},[a]),ut((l,w)=>{n!=="Log"||s||(w.upArrow?m():w.downArrow&&u())}),C(v,{overflowY:"hidden",height:"100%",title:"Log",width:"50%",children:c&&f.map(({sha:l,message:w})=>ft(K,{flexDirection:"row",flexWrap:"nowrap",children:[C(K,{minWidth:2,children:l===a?C(F,{children:"> "}):null}),C(K,{minWidth:8,children:C(F,{color:"yellow",children:l})}),C(K,{children:C(F,{wrap:"truncate-end",children:w})})]},`${l}-${t}`))})}import{useState as Bt}from"react";import{useInput as Lt}from"ink";import Dt from"ink-text-input";import{useInput as pt}from"ink";import{createContext as gt,useContext as ht,useEffect as xt,useState as Se}from"react";import{Fragment as vt,jsx as bt,jsxs as yt}from"react/jsx-runtime";var we=gt({});function T(){let e=ht(we);if(!e)throw new Error("useKeybindings must be used within a KeybindingsProvider");return e}function Te({children:e}){let[t,o]=Se(null),{lock:r,unlock:i}=h(),[n,s]=Se(!1),c=()=>{i(),s(!1)},d=()=>{r(),s(!0)},m=()=>{n?c():d()},u=a=>{c(),o(a)};pt((a,l)=>{l.escape&&c()});let{setKeybinding:f,removeKeybinding:p}=S();return xt(()=>{if(n)return f("esc","close"),()=>{p("esc")}},[n]),bt(we.Provider,{value:{setModal:u,open:d,close:c,toggle:m,isOpen:n},children:yt(vt,{children:[e,t]})})}import{Box as Pe}from"ink";import U from"node:path";import _ from"node:os";import St from"node:fs/promises";import{createContext as wt,useContext as Tt}from"react";import{jsx as Pt}from"react/jsx-runtime";var Ce=wt({});function ke({children:e}){let{value:t}=x(Ct);return Pt(Ce.Provider,{value:{bgColor:t},children:e})}var Me=()=>{let e=Tt(Ce);if(!e)throw new Error("useKeybindings must be used within a KeybindingsProvider");return e};async function Ct(){if(!(!process.stdin.isTTY||!process.stdout.isTTY))return process.env.TERM_PROGRAM==="vscode"?await Mt():new Promise(e=>{let t="\x1B]11;?\x07",o="",r,i=s=>{clearTimeout(r),process.stdin.off("data",n);try{process.stdin.setRawMode(!1),process.stdin.pause()}catch{}e(s)},n=s=>{o+=s.toString("ascii");let c=o.match(/\x1b]11;rgb:([0-9a-fA-F]{1,4})\/([0-9a-fA-F]{1,4})\/([0-9a-fA-F]{1,4})\x07/);if(c){let d=kt(c[1],c[2],c[3]);i(d)}};try{process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.on("data",n),r=setTimeout(()=>i(void 0),150),process.stdout.write(t)}catch{i(void 0)}})}function kt(e,t,o){return"#"+[e,t,o].map(r=>Math.round(parseInt(r,16)*255/((1<<4*r.length)-1)).toString(16).padStart(2,"0")).join("")}async function Mt(){let e="Code";process.env.TERM_PROGRAM_VERSION?.includes("insider")&&(e="Code - Insiders");let t;switch(process.platform){case"win32":t=U.join(_.homedir(),"AppData","Roaming",e,"User","settings.json");break;case"linux":t=U.join(_.homedir(),".config",e,"User","settings.json");break;case"darwin":t=U.join(_.homedir(),"Library","Application Support",e,"User","settings.json");break;default:return}if(!await ce(t))return;let o=await St.readFile(t,{encoding:"utf-8"}),{default:r}=await import("strip-json-comments"),i=r(o).replace(/,\s*(\}|\])/g,"$1");switch(JSON.parse(i)["workbench.colorTheme"]){case"Default Dark Modern":case void 0:return"#181818";case"Visual Studio Dark":case"Default Dark+":return"#1e1e1e";case"Default High Contrast":return"#000000";case"Default Light+":case"Visual Studio Light":case"Default High Contrast Light":return"#ffffff";case"Default Light Modern":return"#f8f8f8";default:return}}import{jsx as Y}from"react/jsx-runtime";var Be=36;function N({children:e,title:t}){let o=g(),{width:r}=o,i=Math.floor((r-Be)/2),{bgColor:n}=Me();return Y(Pe,{...o,position:"absolute",children:Y(Pe,{alignSelf:"center",marginLeft:i,marginRight:i,children:Y(v,{title:t,width:Be,isModal:!0,backgroundColor:n,children:e})})})}import{jsx as Le}from"react/jsx-runtime";function De({title:e,handleSubmit:t}){let[o,r]=Bt(""),{isOpen:i,close:n}=T();return Lt((s,c)=>{c.return&&i&&(t(o),r(""),n())}),i&&Le(N,{title:e,children:Le(Dt,{value:o,onChange:r})})}import{useInput as Rt}from"ink";import Kt from"ink-select-input";import{jsx as Re}from"react/jsx-runtime";function Ke({title:e,handleSubmit:t,options:o,initialIndex:r}){let{isOpen:i,close:n}=T();return Rt((s,c)=>{c.return&&i&&n()}),i&&Re(N,{title:e,children:Re(Kt,{items:o,onSelect:t,initialIndex:r})})}var A=[{value:()=>q("git log --oneline -n 400"),label:"log"},{value:()=>q("git log --oneline --tags --no-walk --decorate"),label:"tags"},{value:()=>q("git reflog"),label:"reflog"}];async function q(e){let{stdout:t}=await y(e);return t.trim().split(/\r?\n/).map(Nt)}function Nt(e){let t=e.indexOf(" ");return{sha:e.slice(0,t),message:e.slice(t+1)}}import{jsx as Q,jsxs as Ot}from"react/jsx-runtime";function J(){let{setModal:e,toggle:t}=T(),[o,r]=Ne(),{width:i,sectionHeight:n}=g(),[s,c]=Ne(A[0]),{isLocked:d}=h();It((f,p)=>{f==="m"&&(e(Q(Ke,{options:A,title:"Log Type",handleSubmit:c,initialIndex:A.indexOf(s)})),t()),!d&&f==="c"&&o&&re().then(a=>{a&&y(`git checkout ${o}`)})});let{setKeybinding:m,removeKeybinding:u}=S();return At(()=>(m("c","checkout"),m("m","mode"),()=>{u(["c","m"])}),[]),Ot(Wt,{width:i,height:n,children:[Q(be,{setSha:r,mode:s}),Q(ve,{sha:o})]})}import{useEffect as Yt}from"react";import{Box as Ee}from"ink";import{Box as z,Text as Ae,useInput as Vt}from"ink";import{useEffect as Et}from"react";import{Fragment as Gt,jsx as k,jsxs as Ht}from"react/jsx-runtime";function We(){let{activeSection:e,isLocked:t}=h(),{sectionHalfHeight:o}=g(),{value:r=[],refresh:i}=x(ie),{value:n,refresh:s}=x(oe),{setKeybinding:c,removeKeybinding:d}=S();Et(()=>{if(e==="Branches")return c("s","switch"),()=>{d("s")}},[e]);let{outList:m,selectedValue:u,scrollUp:f,scrollDown:p}=R(r,o-2),a=async b=>{await y(`git branch ${b}`),i()},l=async()=>{await y(`git branch -D ${u}`),i()},w=async()=>{await y(`git switch ${u}`),i(),s()},{setModal:B,open:V}=T();return Vt((b,te)=>{e!=="Branches"||t||(te.upArrow?f():te.downArrow?p():b==="c"?(B(k(De,{title:"Name your new branch",handleSubmit:a})),V()):b==="d"?l():b==="s"&&w())}),k(Gt,{children:k(v,{width:"100%",title:"Branches",innerHeight:o-1,children:m.map(b=>Ht(z,{flexDirection:"row",flexWrap:"nowrap",children:[k(z,{minWidth:2,children:b===u?k(Ae,{children:"> "}):null}),k(z,{minWidth:8,children:k(Ae,{color:b===n?"magenta":void 0,children:b})})]},b))})})}import{Text as X}from"ink";import{Fragment as $t}from"react";import{jsx as Z,jsxs as Ie}from"react/jsx-runtime";function Oe(){let{value:e}=x(se);return Z(v,{width:"50%",title:"Remotes",children:e?.map(({url:t,name:o,type:r})=>Ie($t,{children:[Ie(X,{wrap:"truncate-end",children:[o," (",r,")"]}),Z(X,{wrap:"truncate-end",children:t}),Z(X,{children:" "})]},`${o}-${r}`))})}import{Text as j}from"ink";import{Fragment as Ft}from"react";import{jsx as W,jsxs as _t}from"react/jsx-runtime";function Ve(){let{sectionHalfHeight:e}=g(),{value:t}=x(Ut);return W(v,{width:"100%",title:"Worktrees",innerHeight:e-1,children:t?.map(({branch:o,detached:r,path:i,head:n})=>_t(Ft,{children:[W(j,{children:r?n:o}),W(j,{children:i}),W(j,{children:" "})]},i))})}async function Ut(){let{stdout:e}=await y("git worktree list --porcelain"),t=e.trim().split(/\r?\n/),o=[],r=[];for(let i of t)i.trim()===""?r.length&&(o.push(r),r=[]):r.push(i);return r.length&&o.push(r),o.map(i=>{let n={detached:!1};for(let s of i)s.startsWith("worktree ")?n.path=s.slice(9):s.startsWith("HEAD ")?n.head=s.slice(5):s.startsWith("branch ")?n.branch=s.slice(7):s==="detached"&&(n.detached=!0);return n})}import{Fragment as qt,jsx as I,jsxs as He}from"react/jsx-runtime";function Ge(){let{width:e,sectionHeight:t}=g(),{setKeybinding:o,removeKeybinding:r}=S();return Yt(()=>(o("c","create"),o("d","delete"),()=>{r(["c","d"])}),[]),I(qt,{children:He(Ee,{width:e,height:t,children:[He(Ee,{flexDirection:"column",width:"50%",height:t,children:[I(We,{}),I(Ve,{})]}),I(Oe,{})]})})}import{jsx as ee,jsxs as zt}from"react/jsx-runtime";function $e(){let{prevSection:e,nextSection:t,activeGroup:o,setActiveGroup:r}=h();switch(Jt((i,n)=>{n.tab&&n.shift?e():n.tab?t():i==="1"?r("Status"):i==="2"?r("Log"):i==="3"&&r("Branches")}),o){case"Status":return ee($,{});case"Log":return ee(J,{});case"Branches":return ee(Ge,{});default:return zt(Qt,{children:["Error, unknown page ",o]})}}import{jsx as O,jsxs as eo}from"react/jsx-runtime";function Ue(){let{isLocked:e}=h();jt((i,n)=>{e||i.toLowerCase()==="q"&&process.exit()});let t=g(),{keybindings:o,setKeybinding:r}=S();return Xt(()=>r("q","quit"),[]),eo(Fe,{flexDirection:"column",...t,children:[O(fe,{}),O($e,{}),O(Fe,{flexDirection:"row",children:Object.entries(o).map(([i,n])=>O(Zt,{children:`[${i}]: ${n} `},n))})]})}import{jsx as P}from"react/jsx-runtime";function oo(){return P(ke,{children:P(me,{children:P(de,{children:P(Te,{children:P(Ue,{})})})})})}var ei=()=>to(P(oo,{}),{patchConsole:!0});export{ei as renderApp};
package/dist/main.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{a as n}from"./chunks/chunk-5WTQIRZS.js";async function a(){let r=n();if(!r){let{renderApp:e}=await import("./chunks/pages-KZAY5E2R.js");return e()}let{runCommand:o}=await import("./chunks/commands-2D4LDHYD.js");if(await o(r))return;let{runWrapper:t}=await import("./chunks/wrapper-5X5SODCK.js");await t(r)||(console.error("unknown command"),process.exit(1))}a().catch(r=>{console.error(`An error occurred: ${r.stderr??r.message}`),process.exit(1)});
2
+ import{a as n}from"./chunks/chunk-5WTQIRZS.js";async function a(){let r=n();if(!r){let{renderApp:e}=await import("./chunks/pages-7PP5OZ4V.js");return e()}let{runCommand:o}=await import("./chunks/commands-AGYREPE5.js");if(await o(r))return;let{runWrapper:t}=await import("./chunks/wrapper-5X5SODCK.js");await t(r)||(console.error("unknown command"),process.exit(1))}a().catch(r=>{console.error(`An error occurred: ${r.stderr??r.message}`),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bisgit",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Git CLI tool to simplify common advanced git workflows",
5
5
  "main": "dist/main.js",
6
6
  "bin": {
@@ -60,8 +60,11 @@
60
60
  "chalk": "^5.6.2",
61
61
  "clipboardy": "^5.0.2",
62
62
  "ink": "^6.6.0",
63
+ "ink-select-input": "^6.2.0",
63
64
  "ink-spinner": "^5.0.0",
65
+ "ink-text-input": "^6.0.0",
64
66
  "nanoid": "^5.1.6",
65
- "react": "^19.2.3"
67
+ "react": "^19.2.3",
68
+ "strip-json-comments": "^5.0.3"
66
69
  }
67
70
  }
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{b as e,c as i}from"./chunk-HCUVDNFV.js";import{normalize as o}from"node:path";async function a(){let{stdout:t}=await e("git branch --show-current");return t.trim()}async function f(t){t??=await a();let{stdout:r}=await e(`git config --get branch.${t}.remote`);return r.trim()}async function p(t,r){try{let{stdout:n}=await e(`git rev-list --count ${t}/${r}..${r}`);return parseInt(n.trim(),10)}catch(n){return console.error("Error getting commits ahead:",n),NaN}}async function d(t,r){try{let{stdout:n}=await e(`git rev-list --count ${r}..${t}/${r}`);return parseInt(n.trim(),10)}catch(n){return console.error("Error getting commits behind:",n),NaN}}async function l(t){let{stdout:r}=await e(`git rev-parse --git-path ${t}`);return o(r.trim())}async function w(){let{stdout:t}=await e("git rev-parse --git-dir");return o(t.trim())}async function y(t){let{code:r}=await i("git",["remote","get-url",t],{stdio:"ignore"});return r===0}async function h(){let{stdout:t}=await e("git rev-parse --abbrev-ref HEAD");return t.trim()==="HEAD"}async function x(t,r){let n="git fetch";t&&(n+=` ${t}`),r&&(n+=` ${r}`),await e(n)}async function $(){let{stdout:t}=await i("git",["status","--porcelain"]);return!t?.trim()}async function v(){let{stdout:t}=await i("git",["status","--porcelain"]);return t?.trim()?.split(/\r?\n/)}async function c(t,r){let{stdout:n}=await e(`git merge-base ${t} ${r}`);return n.trim()}async function P(t,r){let n=await c(t,r),{stdout:s}=await i("git",["merge-tree",n,r,t]);return!s?.split(/\r?\n/)?.includes("+=======")}async function b(t){let{stdout:r}=await e(`git rev-parse ${t}`);return r.trim()}async function D(t,r,n){let{stdout:s}=await e(`git rev-list ${n?"--reverse":""} ${t}..${r}`);return s.trim().split(/\r?\n/)}async function A(){let{stdout:t}=await e("git for-each-ref --format='%(refname:short)' refs/heads");return t.trim().split(/\r?\n/)}export{a,f as b,p as c,d,l as e,w as f,y as g,h,x as i,$ as j,v as k,c as l,P as m,b as n,D as o,A as p};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{useStdout as y}from"ink";function A(){let{stdout:t}=y();return{width:t.columns,height:t.rows}}import{useState as p,createContext as N,useContext as h}from"react";import{jsx as C}from"react/jsx-runtime";var o={Status:"Status",Log:"Log","Commit Details":"Log"},c=Object.keys(o),v=N({});function k({children:t}){let[n,i]=p("Status"),[f,s]=p("Status"),d=e=>{s(e),i(o[e])},a=e=>{i(e),s(e)},l=()=>{s(e=>{let r=c.at((c.indexOf(e)+1)%c.length);return a(o[r]),r})},m=()=>{s(e=>{let r=c.at(c.indexOf(e)-1);return a(o[r]),r})};return C(v.Provider,{value:{activeGroup:n,setActiveGroup:a,activeSection:f,setActiveSection:d,prevSection:m,nextSection:l},children:t})}function S(){let t=h(v);if(!t)throw new Error("useNavContext must be used within a NavProvider");return t}import{Box as x,Text as G}from"ink";import{jsx as u}from"react/jsx-runtime";var w=Array.from(new Set(Object.values(o)));function D(){let{activeGroup:t}=S();return u(x,{width:"100%",flexDirection:"row",children:w.map((n,i)=>u(x,{borderStyle:"classic",borderLeft:!!i,borderRight:!1,borderTop:!1,borderBottom:!1,children:u(G,{color:n===t?"cyan":"",children:` [${i+1}]: ${n} `})},n))})}export{A as a,k as b,S as c,D as d};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{createContext as c,useContext as K,useState as u}from"react";import{jsx as v}from"react/jsx-runtime";var o=c(void 0),a=({children:e})=>{let[d,s]=u({}),g=(n,i)=>{s(t=>({...t,[n]:i}))},y=n=>{let i=Array.isArray(n)?n:[n];s(t=>{let r={...t};for(let b of i)delete r[b];return r})};return v(o.Provider,{value:{keybindings:d,setKeybinding:g,removeKeybinding:y},children:e})},p=()=>{let e=K(o);if(!e)throw new Error("useKeybindings must be used within a KeybindingsProvider");return e};export{a,p as b};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{a,c as m}from"./chunk-IX3J52I6.js";import{Box as p,measureElement as P,Text as x}from"ink";import{useMemo as S,useRef as w}from"react";import{Fragment as y,jsx as c,jsxs as R}from"react/jsx-runtime";function L(n){let{title:e,footer:t,children:i,width:d,height:o,innerHeight:r}=n,{width:l}=a(),v=d??l,s=w(null),u=S(()=>{if(!s.current)return 0;let{width:b}=P(s.current);return b},[s.current]),h=u-8,B={...n,height:r,width:u},{activeSection:T}=m(),f=T===e?"cyan":"";return c(p,{ref:s,flexDirection:"column",height:o,width:v,children:u!==0&&R(y,{children:[e&&c(x,{color:f,children:"\u256D\u2500\u2500\u2500\u2500 "+e+" "+"\u2500".repeat(h-e.length)+"\u256E"}),c(p,{flexDirection:"column",...B,borderStyle:"round",borderColor:f,borderTop:!e,borderBottom:!t,paddingLeft:1,children:i}),t&&c(x,{color:f,children:"\u2570"+"\u2500".repeat(h-t.length)+" "+t+" \u2500\u2500\u2500\u2500\u256F"})]})})}import{useEffect as D,useState as g}from"react";function k(n,e=[]){let[t,i]=g(void 0),[d,o]=g(!1);return D(()=>{let r=!1;return o(!1),i(void 0),n().then(l=>{r||(i(l),o(!0))}).catch(()=>{r||o(!0)}),()=>{r=!0}},e),{value:t,resolved:d}}export{L as a,k as b};
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env node
2
- import{b as g,c as K}from"./chunk-5WTQIRZS.js";import{a as u,b as V,c as k,d as B,e as v,f as z,g as J,h as Z,i as H,j as h,k as W,l as x,m as Q,n as X,o as G,p as tt}from"./chunk-7AM4AK3O.js";import{a as $,b as s,c as q,d as l}from"./chunk-HCUVDNFV.js";import A from"node:path";import Ft from"fs/promises";async function w(t){try{return await Ft.access(t),!0}catch{return!1}}async function et(){let t=await W(),e=/^(UU|DU|UD)/;return!!t?.some(o=>e.test(o))}async function F(){let t=await z(),[e,o,r,i,n]=await Promise.all([await w(A.join(t,"MERGE_HEAD")),await w(A.join(t,"rebase-merge")),await w(A.join(t,"rebase-apply")),await w(A.join(t,"CHERRY_PICK_HEAD")),await w(A.join(t,"REVERT_HEAD"))]);return{merge:e,rebaseMerge:o,rebaseApply:r,cherryPick:i,revert:n}}async function ot(){let{merge:t,rebaseMerge:e,rebaseApply:o,cherryPick:r,revert:i}=await F(),n="";if(t)n="merge";else if(e||o)n="rebase";else if(r)n="cherry-pick";else if(i)n="revert";else{let a=await et()?"Conflicts exist, but likely are from a stash and are not abortable. Resolve them manually.":"Nothing to abort.";console.log(a);return}console.log(`Aborting the ${n}`),await l([n,"--abort"])}function rt(){$("git",["commit","--amend","--no-edit",...g()],{stdio:"inherit",silent:!0,triggerExit:!0})}import{render as Yt}from"ink";import{spawnSync as it}from"node:child_process";function D(t,e,o){let{status:r}=it(t,e,{stdio:"ignore"});r!==0&&(o&&console.error(o),process.exit(1))}var nt=()=>D("git",["rev-parse","--git-dir"],"Need to use command in a git repository."),R=()=>D("git",["rev-parse","HEAD"],"Need to create first commit."),d=(t="origin")=>D("git",["remote","get-url",t],`Need to add remote '${t}'.`),U=t=>D("git",["show-ref","--branches",t],`Branch '${t}' isn't tracked locally and may not exist.`),P=async()=>{await h()||(console.error("You should stash or commit your changes first."),process.exit(1))},M=async t=>{await w(t)||(console.error(`${t} must exist for this operation and it doesn't for some reason`),process.exit(1))},st=async()=>{await Z()&&(console.error("Operation not allowed in a 'detached HEAD' state"),process.exit(1))},at=t=>D("git",["rev-parse","--abbrev-ref","--symbolic-full-name",`${t}@{u}`],`branch '${t}' has no upstream`);function y(t="Error: missing required argument"){if(process.argv[3])return process.argv[3];console.error(t),process.exit(1)}async function N(){let{status:t}=it("git",["diff","--staged","--quiet"],{stdio:"ignore"});t===0&&(console.error("You have no staged changes"),process.exit(1))}import{render as jt}from"ink";import{Suspense as Mt,use as Nt,useEffect as Tt}from"react";import{Text as ct,useApp as Lt}from"ink";import It from"ink-spinner";import{jsx as T,jsxs as Ot}from"react/jsx-runtime";function c(t){let{msg:e}=t;return T(Mt,{fallback:Ot(ct,{children:[T(It,{type:"dots"}),"\xA0",e]}),children:T(Ut,{...t})})}function Ut({msg:t,promise:e}){let o=Nt(e),{exit:r}=Lt();return Tt(()=>{r()},[o]),T(ct,{children:`\u2714 ${typeof o=="string"?o:t}`})}import{jsx as _t}from"react/jsx-runtime";async function mt(){let t=process.argv[3],e=process.argv[4]??await u();if(U(t),U(e),t===e)return console.log(`No reason to merge '${t}' into '${e}'`);let o=await V(t);d(o),jt(_t(c,{msg:"Updating target branch and merging",promise:(async()=>{try{await S(o,t)}catch{console.error(`Error when updating branch ${t} with remote ${o}. Fix divergent branches before merging into ${e}`);return}await u()!==e&&await s(`git switch ${e}`),$("git",["merge",t],{stdio:"inherit",silent:!0})})()}))}async function S(t,e){await H(t,e);let[o,r,i]=await Promise.all([k(t,e),B(t,e),u()]);if(r!==0){if(o===0&&i!==e){await s(`git fetch ${t} ${e}:${e}`);return}if(await s(`git switch ${e}`),o===0){await s(`git merge ${t}/${e}`);return}await l(["merge",`${t}/${e}`],["ignore","ignore","inherit"])}}async function E(){R(),d();let{stdout:t,code:e}=await q("git",["rev-parse","--abbrev-ref","origin/HEAD"]);if(e===0)return lt(t.trim());await s("git remote set-head origin -a");let{stdout:o}=await s("git rev-parse --abbrev-ref origin/HEAD");return lt(o.trim())}async function ft(){let{remote:t,branch:e}=await E();console.log(`Remote default branch is '${t}/${e}'`)}async function lt(t){let e=t.split("/"),o=t.split("/").map((r,i)=>e.slice(0,i+1).join("/"));for(let r of o)if(await J(r)){let i=t.slice(r.length+1);return{remote:r,branch:i}}throw new Error("Failed to get default remote")}import{jsx as Vt}from"react/jsx-runtime";var Kt=["master","main","development","lingoport"];async function pt(){await P();let{branch:t,remote:e}=await E();await s(`git switch ${t}`);let o=(async()=>{await l(["fetch","--prune","--prune-tags"]),await S(e,t)})();Yt(Vt(c,{msg:"Fetching and pruning remote references",promise:o})),await o;let r=await tt();for(let i of r){if(i===t||Kt.includes(i))continue;let n=await x(i,t),{code:a}=await q("git",["diff","--quiet",n,i]);a===0&&await l(["branch","-D",i])}}import{spawn as zt}from"node:child_process";import{createInterface as Jt}from"node:readline/promises";async function gt(){R;let e=[...(await Zt()).entries()].sort(([,r],[,i])=>i-r).slice(0,25),o=e[0][1].toString().length;console.info(e.map(([r,i])=>`${String(i).padEnd(o)} ${r}:`).join(`
3
- `))}async function Zt(){let{promise:t,resolve:e,reject:o}=Promise.withResolvers(),r=new Map,i=zt("git",["log","--all","-M","-C","--name-only","--format=format:"]),n=Jt({input:i.stdout,crlfDelay:1/0});return n.on("line",a=>{let m=a.trim();m&&r.set(m,(r.get(m)??0)+1)}),n.on("close",()=>e(r)),i.on("error",o),t}import{render as Qt}from"ink";import{jsx as te}from"react/jsx-runtime";async function ut(){await N();let t=y("Error: missing github username argument"),e=(async()=>{let i=await Xt(t);return i.email||(console.error(`Couldn't find an email for ${t}`),process.exit(1)),i})();Qt(te(c,{msg:"Fetching name and email",promise:e}));let{name:o,email:r}=await e;l(["commit","--edit","-m","<insert summary>","-m",`Co-authored-by: ${o} <${r}>`])}async function Xt(t){let{stdout:e}=await s(`gh api users/${t}`);return JSON.parse(e.trim())}import{render as O}from"ink";import{isDeepStrictEqual as ee}from"node:util";import{jsx as j}from"react/jsx-runtime";async function ht(){let t=y("Error: missing id of PR to checkout");await P();let e=(async()=>Promise.all([s(`gh co ${t}`),s(`gh pr view ${t} --json baseRefName -q .baseRefName`)]))();O(j(c,{msg:`Checking out pr #${t}`,promise:e}));let[,{stdout:o}]=await e,r=o.trim(),i=(async()=>{await s(`git switch ${r}`),await s("git pull"),await s("git switch -")})();O(j(c,{msg:`Updating ${r} branch merge destination`,promise:i})),await i;let n=(async()=>{let p=await x(r,"HEAD");return await s(`git reset ${p} --soft`),await oe("HEAD")})();O(j(c,{msg:"Creating an editable, explorable, local PR experience",promise:n}));let[a,m]=await Promise.all([n,re(t)]),{files:f,additions:b,deletions:I}=m;if(ee(a,m))return console.info(`Files: ${f}, +${b} -${I}`);console.info("The PR stat doesn't match the local stat."),console.info("LOCAL"),console.table(a),console.info("GITHUB"),console.table(m),console.info("One option to fix (there'll likely be conflicts):"),console.info("1. git stash -u"),console.info(`2. git merge ${r}`),console.info("3. git stash pop")}async function oe(t){let{stdout:e}=await s(`git diff --shortstat ${t}`),o=/(\d+)\s+files? changed(?:, (\d+) insertions?\(\+\))?(?:, (\d+) deletions?\(-\))?/,r=e.trim().match(o);if(!r)throw new Error(`Couldn't generate short stat for ref(s): ${t}`);let[,i,n,a]=r;return{files:parseInt(i,10),additions:n?parseInt(n,10):0,deletions:a?parseInt(a,10):0}}async function re(t){let{stdout:e}=await s(`gh pr view ${t} --json deletions,files,additions`),o=JSON.parse(e.trim());return o.files=o.files.length,o}import{spawn as ie}from"node:child_process";import{createInterface as ne}from"node:readline/promises";import _ from"chalk";async function wt(){let t=y("Error: missing target branch argument"),e=await x("HEAD",t),{promise:o,resolve:r,reject:i}=Promise.withResolvers(),n=ie("git",["merge-tree",e,"HEAD",t]),a=ne({input:n.stdout,crlfDelay:1/0}),m=!1,f=0;a.on("line",p=>{p=p.trimEnd(),p==="+<<<<<<< .our"?(m=!0,console.info(_.red(p)),f+=1):p==="+>>>>>>> .their"?(m=!1,console.info(_.green(p))):p==="+======="?console.info(_.yellow(p)):m&&console.info(p)}),a.on("close",()=>r(f)),n.on("error",i);let b=await o,I=b?`\u274C ${b} conflicts would occur!`:"\u2705 No conflicts. Safe to merge.";console.info(I)}async function dt(){let{merge:t,rebaseMerge:e,rebaseApply:o,cherryPick:r,revert:i}=await F(),n="";if(t)n="merge";else if(e||o)n="rebase";else if(r)n="cherry-pick";else if(i)n="revert";else{console.log("Nothing to continue.");return}console.log(`Continuing the ${n}`),await l([n,"--continue"])}import{appendFileSync as ae}from"node:fs";import{readFile as se}from"node:fs/promises";async function L(t){return(await se(t,"utf-8")).split(/\r?\n/).map(o=>o.trim()).filter(o=>o&&!o.startsWith("#"))}async function yt(){let t=await v("info/exclude");await M(t);let e=await L(t);g().forEach(o=>{e.includes(o)?console.info(`Already Exists: '${o}'`):(ae(t,`${o}
4
- `),console.info(`Added '${o}'`))}),console.info(`
5
- See file at ${t}`)}function bt(){$("git",["show","--name-only","--pretty=format:",...g()],{stdio:"inherit",silent:!0,triggerExit:!0})}import{spawn as ce}from"node:child_process";async function $t(){let t=y("Error: missing valid target ref argument");await N();let e=await X(t);await l(["commit",`--fixup=${e}`]);let r=(await G(`${e}^`,"HEAD",!0)).map(n=>me(n));(await Promise.all(r)).every(Boolean)||(console.warn("Rebase conflict would occur!"),await s("git reset HEAD~1 --soft"),process.exit(1)),await s(`git rebase -i --autosquash ${e}^`)}async function me(t){let{stdout:e}=await s(`git diff ${t}^ ${t}`),{promise:o,resolve:r,reject:i}=Promise.withResolvers(),n=ce("git",["apply","--check","--3way","-q"],{stdio:["pipe","ignore","ignore"]});return n.on("close",a=>{r(a===0)}),n.on("error",i),n.stdin.write(e),n.stdin.end(),o}import{readFile as le,writeFile as fe}from"node:fs/promises";async function xt(){let t=await v("info/exclude");await M(t);let e=await L(t),o=g();o.filter(a=>!e.includes(a)).forEach(a=>console.info(`No match: '${a}'`));let i=(await le(t,"utf-8")).split(/\r?\n/).map(a=>a.trim()),n=i.filter(a=>!o.includes(a));await fe(t,n.join(`
6
- `)),console.info(`
7
- Removed ${i.length-n.length} entries from ${t}`)}import{render as pe}from"ink";import{jsx as we}from"react/jsx-runtime";async function Rt(){let t=(async()=>{let i=await ge();return await ue(i)})();pe(we(c,{msg:"Fetching repo languages",promise:t}));let e=await t,o=Object.values(e).reduce((i,n)=>i+n,0),r=Object.entries(e).map(([i,n])=>`${i}: ${Math.round(n/o*100)}% - ${he(n)}`);console.log(r.join(`
8
- `))}async function ge(){let{stdout:t}=await s("gh repo view --json nameWithOwner -q .nameWithOwner");return t.trim()}async function ue(t){let{stdout:e}=await s(`gh api repos/${t}/languages`);return JSON.parse(e.trim())}function he(t,e=2){if(t===0)return"0 B";let o=1024,r=e<0?0:e,i=["B","KB","MB","GB","TB","PB","EB","ZB","YB"],n=Math.floor(Math.log(t)/Math.log(o));return`${parseFloat((t/Math.pow(o,n)).toFixed(r))} ${i[n]}`}import{execSync as de}from"node:child_process";function ye(){return de("git rev-parse --show-toplevel",{encoding:"utf-8"}).trim()}function Pt(){let t=ye();console.log(t)}import{render as vt}from"ink";function Ct(){return new Date().toLocaleString("en-US",{year:"2-digit",month:"2-digit",day:"2-digit",hour:"numeric",minute:"2-digit",hour12:!0}).replace(",","")}async function C(){let t=Ct();await s("git add -A"),await l(["commit","-m",`"WIP ${t}"`])}import{nanoid as be}from"nanoid";import $e from"chalk";import{jsx as At}from"react/jsx-runtime";async function Dt(){let{remote:t,branch:e}=await E(),o=process.argv[3]??e;await h()||await C(),await Q(o,"HEAD")||(console.warn("Conflicts would occur. Not safe to rebranch."),process.exit(1));let r=await u(),i=(async()=>{await S(t,o)})();vt(At(c,{msg:`Updating branch ${o}`,promise:i})),await i;let n=`${be(8)}`,a=(async()=>{await s(`git switch ${r}`),await s(`git branch ${n}`),await s(`git switch ${o}`),await s(`git branch -D ${r}`),await s(`git switch -c ${r}`);let m=await G(o,n,!0);for(let f of m)try{await s(`git cherry-pick ${f}`)}catch{let b=$e.yellow(`git branch -D ${r} && git branch -m ${n} ${r}`);throw new Error(`\u274C cherry pick failed at ${f}
9
- Run this to restore backup branch
10
- > ${b}`)}await s(`git branch -D ${n}`)})();vt(At(c,{msg:`Rewriting branch ${r}`,promise:a})),await a,console.info(`Successfully recreated branch ${r} from ${o}`)}import{execSync as xe}from"node:child_process";async function St(){R();let t=Re(process.argv[3]),{default:e}=await import("clipboardy");await e.write(t),console.log(`'${t}' copied to clipboard`)}function Re(t="HEAD"){return xe(`git rev-parse --short ${t}`,{encoding:"utf-8"}).trim()}import{render as Pe}from"ink";import{jsx as Ce}from"react/jsx-runtime";async function Et(){let{remote:t,branch:e}=await K();d(t),await P();let o=H(t,e);Pe(Ce(c,{msg:`Fetching branch ${e} from ${t}`,promise:o})),await o,await l(["switch","-c",e,"--track",`${t}/${e}`])}async function qt(){let[t,e]=await Promise.allSettled([await Ae("user.name"),await ve()]);t.status==="fulfilled"&&console.info(`Git: ${t.value}`),e.status==="fulfilled"&&console.info(`Github: ${e.value}`)}async function ve(){let{stdout:t}=await s("gh api user --jq .login");return t.trim()}async function Ae(t){let{stdout:e}=await s(`git config ${t}`);return e.trim()}import{render as He}from"ink";import{Text as De,useApp as Se,useInput as Ee}from"ink";import{useState as qe}from"react";import{Fragment as Be,jsx as ke,jsxs as kt}from"react/jsx-runtime";function Bt({prompt:t,msg:e,onConfirm:o}){let[r,i]=qe(""),{exit:n}=Se();return Ee((a,m)=>{if(r)return;let f=a.toLowerCase();f==="y"?i("Yes"):(f==="n"||m.return)&&(i("No"),n())}),kt(Be,{children:[kt(De,{children:[t," [y/N] ",r]}),r==="Yes"&&ke(c,{msg:e,promise:o()})]})}import{jsx as We}from"react/jsx-runtime";async function Ht(){if(nt(),await h())return console.log("Already a clean working tree");let t=await W();if(!t)throw new Error("git status cmd failed");let e=new Y(t);e.displayReport(),He(We(Bt,{prompt:"Approve these changes?",msg:"Running git reset && git clean",onConfirm:async()=>(await s("git reset --hard"),await s("git clean -f"),`Altered ${e.willDelete.length+e.willRecreate.length+e.willRevert.length} files.`)}))}var Y=class{willDelete=[];willRecreate=[];willRevert=[];constructor(e){e.forEach(o=>{if(o){let r=o.slice(0,2).trim(),i=o.slice(3);r.includes("?")||r.includes("A")?this.willDelete.push(i):r==="DU"||r==="D"?this.willRecreate.push(i):this.willRevert.push(i)}}),this.willDelete.sort(),this.willRecreate.sort(),this.willRevert.sort()}displayReport(){this.displaySection("Will Recreate:",this.willRecreate),this.displaySection("Will Revert:",this.willRevert),this.displaySection("Will Delete:",this.willDelete)}displaySection(e,o){o.length&&console.log(`${e}
11
- ${o.map(r=>`- ${r}
12
- `)}`)}};import{nanoid as Ge}from"nanoid";import{render as Fe}from"ink";import{jsx as Me}from"react/jsx-runtime";async function Wt(){await st();let t=process.argv[3]??"origin";d(t);let e=await u();at(e);let o="",i=(async()=>{let n=[s(`git fetch ${t} ${e} --force`)];await h()||n.push(C()),await Promise.all(n);let[a,m]=await Promise.all([k(t,e),B(t,e)]);if(!(a===0&&m===0)){if(a!==0){let f=`${e}-${Ge(8)}`;o=`Created branch ${f}`,await s(`git branch ${f}`)}await s(`git reset --hard ${t}/${e}`)}})();Fe(Me(c,{msg:`Force pull reseting ${e} -> ${t}`,promise:i})),await i,o&&console.info(o)}var Gt={abort:ot,amend:rt,autoprune:pt,backmerge:mt,churn:gt,coauthor:ut,"code-review":ht,conflict:wt,continue:dt,exclude:yt,files:bt,fixup:$t,include:xt,languages:Rt,pwd:Pt,rebranch:Dt,"remote-default":ft,savepoint:C,sha:St,track:Et,whoami:qt,wipe:Ht,yank:Wt};async function Ki(t){return await Gt[t]?.(),Object.hasOwn(Gt,t)}export{Ki as runCommand};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{a as S,b as v}from"./chunk-NWXSV6NP.js";import{b as T}from"./chunk-NAFT7YF6.js";import{a as y,c as b}from"./chunk-IX3J52I6.js";import{b as f}from"./chunk-HCUVDNFV.js";import{useEffect as A}from"react";import{Box as a,Text as x,useInput as E}from"ink";import{useEffect as C,useState as D}from"react";function L(t,o){let[r,c]=D(0),[u,l]=D(0);C(()=>{c(0),l(0)},[t]);let p=Math.max(0,t.length-o),h=t.length-1,m=()=>{l(i=>{let n=Math.min(i+1,h);return c(s=>n>=s+o?Math.min(s+1,p):s),n})},d=()=>{l(i=>{let n=Math.max(i-1,0);return c(s=>n<s?Math.max(s-1,0):s),n})},g=t.slice(r,r+o),w=t[u];return{scrollDown:m,scrollUp:d,outList:g,selectedIndex:u,selectedValue:w}}import M from"ink-spinner";import{Fragment as I,jsx as e,jsxs as B}from"react/jsx-runtime";async function K(){let{stdout:t}=await f("git log --oneline -n 30");return t.trim().split(/\r?\n/).map(W)}async function O(t){if(!t)return;let{stdout:o}=await f(`git show ${t} --name-only`);return o.trim()}function U(){let{height:t,width:o}=y(),r=t-5,{resolved:c,value:u=[]}=v(K),{scrollUp:l,scrollDown:p,outList:h,selectedValue:m}=L(u,r-2);E((i,n)=>{n.upArrow&&l(),n.downArrow&&p(),i==="c"&&f(`git checkout ${m.sha}`)});let{activeSection:d}=b(),{setKeybinding:g,removeKeybinding:w}=T();return A(()=>{if(d==="Log")return g("c","checkout"),()=>{w("c")}},[d]),e(I,{children:B(a,{width:o,children:[e(S,{overflowY:"hidden",height:r,title:"Log",width:"50%",children:c?e(I,{children:h.map(({sha:i,message:n})=>B(a,{flexDirection:"row",flexWrap:"nowrap",children:[e(a,{minWidth:2,children:i===m.sha?e(x,{children:"> "}):null}),e(a,{minWidth:8,children:e(x,{color:"yellow",children:i})}),e(a,{children:e(x,{wrap:"truncate-end",children:n})})]},i))}):e(M,{})}),e(V,{sha:m?.sha})]})})}function V({sha:t}){let{resolved:o,value:r}=v(()=>O(t),[t]);return e(S,{title:"Commit Details",width:"50%",height:"100%",children:t&&o?e(x,{children:r}):e(M,{})})}function W(t){let o=t.indexOf(" ");return{sha:t.slice(0,o),message:t.slice(o+1)}}export{U as default};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{a as s,b as p}from"./chunk-NAFT7YF6.js";import{a as m,b as f,c,d as u}from"./chunk-IX3J52I6.js";import{render as q}from"ink";import{lazy as d,useEffect as S}from"react";import{Text as A,Box as a,useInput as K}from"ink";import{jsx as t,jsxs as P}from"react/jsx-runtime";var L=d(()=>import("./status-UBYZMDYE.js")),N=d(()=>import("./log-4RIWY74K.js"));function v(){let{prevSection:g,nextSection:l,activeGroup:r,setActiveGroup:n}=c();K((e,o)=>{o.tab&&o.shift?g():o.tab?l():e.toLowerCase()==="q"?process.exit():e==="1"?n("Status"):e==="2"&&n("Log")});let x=m(),{keybindings:b,setKeybinding:y}=p();return S(()=>y("q","quit"),[]),P(a,{flexDirection:"column",...x,children:[t(u,{}),r==="Log"&&t(N,{}),r==="Status"&&t(L,{}),t(a,{flexDirection:"row",children:Object.entries(b).map(([e,o])=>t(A,{children:`[${e}]: ${o} `},o))})]})}import{jsx as i}from"react/jsx-runtime";function B(){return i(f,{children:i(s,{children:i(v,{})})})}var O=()=>q(i(B,{}),{patchConsole:!0});export{O as renderApp};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{a as t,b as e}from"./chunk-NWXSV6NP.js";import"./chunk-IX3J52I6.js";import{k as o}from"./chunk-7AM4AK3O.js";import"./chunk-HCUVDNFV.js";import{Text as s}from"ink";import{jsx as i}from"react/jsx-runtime";function u(){let{value:r,resolved:m}=e(o);return i(t,{flexDirection:"column",title:"Bisgit",width:"100%",children:m&&r?.map((l,n)=>i(s,{children:l},n))})}export{u as default};