bisgit 0.3.0 → 0.4.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 l(t){t??=await g();let{stdout:r}=await n(`git config --get branch.${t}.remote`);return r.trim()}async function d(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 y(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 h(t){let{stdout:r}=await n(`git rev-parse --git-path ${t}`);return a(r.trim())}async function w(){let{stdout:t}=await n("git rev-parse --git-dir");return a(t.trim())}async function x(t){let{code:r}=await s("git",["remote","get-url",t],{stdio:"ignore"});return r===0}async function $(){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 P(){let{stdout:t}=await s("git",["status","--porcelain"]);return!t?.trim()}async function b(){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 D(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 R(t){let{stdout:r}=await n(`git rev-parse ${t}`);return r.trim()}async function A(t,r,e){let{stdout:i}=await n(`git rev-list ${e?"--reverse":""} ${t}..${r}`);return i.trim().split(/\r?\n/)}async function B(){let{stdout:t}=await n("git for-each-ref --format='%(refname:short)' refs/heads");return t.trim().split(/\r?\n/)}async function G(){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)}export{g as a,l as b,d as c,y as d,h as e,w as f,x as g,$ as h,v as i,P as j,b as k,m as l,D as m,R as n,A as o,B as p,G as q};
@@ -1,5 +1,5 @@
1
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(`
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-ZLDM3RDV.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
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
4
  `),console.info(`Added '${o}'`))}),console.info(`
5
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(`
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import{a as J,k as Q,p as X,q as Z}from"./chunk-ZLDM3RDV.js";import{b as w}from"./chunk-HCUVDNFV.js";import{render as yt}from"ink";import{createContext as Ke,useContext as Le,useState as De}from"react";import{jsx as Ne}from"react/jsx-runtime";var j=Ke(void 0),ee=({children:e})=>{let[t,o]=De({}),n=(r,s)=>{o(c=>({...c,[r]:s}))},i=r=>{let s=Array.isArray(r)?r:[r];o(c=>{let l={...c};for(let a of s)delete l[a];return l})};return Ne(j.Provider,{value:{keybindings:t,setKeybinding:n,removeKeybinding:i},children:e})},b=()=>{let e=Le(j);if(!e)throw new Error("useKeybindings must be used within a KeybindingsProvider");return e};import{useEffect as ht}from"react";import{Text as gt,Box as ke,useInput as xt}from"ink";import{useStdout as Pe}from"ink";function h(){let{stdout:e}=Pe(),t=e.rows-2,o=Math.floor(t/2);return{width:e.columns,height:e.rows,sectionHeight:t,sectionHalfHeight:o}}import{Box as ne,Text as Me}from"ink";import{useState as I,createContext as Re,useContext as We}from"react";import{jsx as Ae}from"react/jsx-runtime";var B={Status:"Status",Log:"Log","Commit Details":"Log",Branches:"Branches",Worktrees:"Branches",Remotes:"Branches"},C=Object.keys(B),te=Re({});function oe({children:e}){let[t,o]=I(!1),n=()=>o(!0),i=()=>o(!1),[r,s]=I("Status"),[c,l]=I("Status"),a=u=>{t||(l(u),s(B[u]))},m=u=>{t||(s(u),l(u))},f=()=>{t||l(u=>{let d=C.at((C.indexOf(u)+1)%C.length);return s(B[d]),d})},p=()=>{t||l(u=>{let d=C.at(C.indexOf(u)-1);return s(B[d]),d})};return Ae(te.Provider,{value:{activeGroup:r,setActiveGroup:m,activeSection:c,setActiveSection:a,prevSection:p,nextSection:f,isLocked:t,lock:n,unlock:i},children:e})}function g(){let e=We(te);if(!e)throw new Error("useNavContext must be used within a NavProvider");return e}import{jsx as G}from"react/jsx-runtime";var He=Array.from(new Set(Object.values(B)));function re(){let{activeGroup:e}=g();return G(ne,{width:"100%",flexDirection:"row",children:He.map((t,o)=>G(ne,{borderStyle:"classic",borderLeft:!!o,borderRight:!1,borderTop:!1,borderBottom:!1,children:G(Me,{color:t===e?"cyan":"",children:` [${o+1}]: ${t} `})},t))})}import{Text as ft,useInput as dt}from"ink";import{Box as ie,measureElement as Ie,Text as se}from"ink";import{useMemo as Ge,useRef as Ee}from"react";import{Fragment as Oe,jsx as D,jsxs as Ve}from"react/jsx-runtime";function v(e){let{title:t,footer:o,children:n,width:i,height:r,innerHeight:s,isModal:c}=e,{width:l}=h(),a=i??l,m=Ee(null),f=Ge(()=>{if(!m.current)return 0;let{width:L}=Ie(m.current);return L},[m.current]),p=f-8,u={...e,height:s,width:f},{activeSection:d}=g(),k=d===t||c?"cyan":"";return D(ie,{ref:m,flexDirection:"column",height:r,width:a,children:f!==0&&Ve(Oe,{children:[t&&D(se,{color:k,wrap:"truncate-end",children:"\u256D\u2500\u2500\u2500\u2500 "+t+" "+"\u2500".repeat(p-t.length)+"\u256E"}),D(ie,{flexDirection:"column",...u,borderStyle:"round",borderColor:k,borderTop:!t,borderBottom:!o,paddingLeft:1,children:n}),o&&D(se,{color:k,wrap:"truncate-end",children:"\u2570"+"\u2500".repeat(p-o.length)+" "+o+" \u2500\u2500\u2500\u2500\u256F"})]})})}import{Text as Fe}from"ink";import{useEffect as $e,useState as E}from"react";function y(e,t=[]){let[o,n]=E(void 0),[i,r]=E(!1),[s,c]=E(0),l=()=>c(a=>a+1);return $e(()=>{let a=!1;return r(!1),n(void 0),e().then(m=>{a||(n(m),r(!0))}).catch(()=>{a||r(!0)}),()=>{a=!0}},[s,...t]),{value:o,resolved:i,refresh:l}}import{jsx as ce}from"react/jsx-runtime";function O(){let{value:e,resolved:t}=y(Q);return ce(v,{flexDirection:"column",title:"Bisgit",width:"100%",children:t&&e?.map((o,n)=>ce(Fe,{children:o},n))})}import{useEffect as _e}from"react";import{Box as K,Text as P,useInput as qe}from"ink";import{useEffect as Ue,useState as ae}from"react";function N(e,t){let[o,n]=ae(0),[i,r]=ae(0);Ue(()=>{n(0),r(0)},[e]);let s=Math.max(0,e.length-t),c=e.length-1,l=()=>{r(p=>{let u=Math.min(p+1,c);return n(d=>u>=d+t?Math.min(d+1,s):d),u})},a=()=>{r(p=>{let u=Math.max(p-1,0);return n(d=>u<d?Math.max(d-1,0):d),u})},m=e.slice(o,o+t),f=e[i];return{scrollDown:l,scrollUp:a,outList:m,selectedIndex:i,selectedValue:f}}import me from"ink-spinner";import{Fragment as ue,jsx as x,jsxs as le}from"react/jsx-runtime";async function Ye(){let{stdout:e}=await w("git log --oneline -n 30");return e.trim().split(/\r?\n/).map(Qe)}async function ze(e){if(!e)return;let{stdout:t}=await w(`git show ${e} --name-only`);return t.trim()}function V(){let{width:e,sectionHeight:t}=h(),{resolved:o,value:n=[]}=y(Ye),{scrollUp:i,scrollDown:r,outList:s,selectedValue:c}=N(n,t-2);qe((f,p)=>{p.upArrow&&i(),p.downArrow&&r(),f==="c"&&w(`git checkout ${c.sha}`)});let{activeSection:l}=g(),{setKeybinding:a,removeKeybinding:m}=b();return _e(()=>{if(l==="Log")return a("c","checkout"),()=>{m("c")}},[l]),x(ue,{children:le(K,{width:e,children:[x(v,{overflowY:"hidden",height:t,title:"Log",width:"50%",children:o?x(ue,{children:s.map(({sha:f,message:p})=>le(K,{flexDirection:"row",flexWrap:"nowrap",children:[x(K,{minWidth:2,children:f===c.sha?x(P,{children:"> "}):null}),x(K,{minWidth:8,children:x(P,{color:"yellow",children:f})}),x(K,{children:x(P,{wrap:"truncate-end",children:p})})]},f))}):x(me,{})}),x(Je,{sha:c?.sha})]})})}function Je({sha:e}){let{resolved:t,value:o}=y(()=>ze(e),[e]);return x(v,{title:"Commit Details",width:"50%",height:"100%",children:e&&t?x(P,{children:o}):x(me,{})})}function Qe(e){let t=e.indexOf(" ");return{sha:e.slice(0,t),message:e.slice(t+1)}}import{useEffect as ut}from"react";import{Box as we}from"ink";import{Box as $,Text as ge,useInput as nt}from"ink";import{useState as Xe}from"react";import{Box as fe,useInput as Ze}from"ink";import je from"ink-text-input";import{jsx as R}from"react/jsx-runtime";var de=36;function pe({title:e,handleSubmit:t,modalControls:o}){let[n,i]=Xe(""),{isOpen:r,close:s}=o,c=h(),{width:l}=c,a=Math.floor((l-de)/2);return Ze((m,f)=>{f.return&&r&&(t(n),i(""),s())}),r&&R(fe,{...c,position:"absolute",children:R(fe,{alignSelf:"center",marginLeft:a,marginRight:a,children:R(v,{title:e,width:de,isModal:!0,children:R(je,{value:n,onChange:i})})})})}import{useInput as et}from"ink";import{useEffect as tt,useState as ot}from"react";function he(){let{lock:e,unlock:t}=g(),[o,n]=ot(!1),i=()=>{t(),n(!1)},r=()=>{e(),n(!0)};et((l,a)=>{a.escape&&i()});let{setKeybinding:s,removeKeybinding:c}=b();return tt(()=>{if(o)return s("esc","close"),()=>{c("esc")}},[o]),{isOpen:o,close:i,open:r}}import{useEffect as rt}from"react";import{Fragment as it,jsx as T,jsxs as xe}from"react/jsx-runtime";function F(){let{activeSection:e,isLocked:t}=g(),{sectionHalfHeight:o}=h(),{value:n=[],refresh:i}=y(X),{value:r,refresh:s}=y(J),{setKeybinding:c,removeKeybinding:l}=b();rt(()=>{if(e==="Branches")return c("s","switch"),()=>{l("s")}},[e]);let{outList:a,selectedValue:m,scrollUp:f,scrollDown:p}=N(n,o-2),u=async S=>{await w(`git branch ${S}`),i()},d=async()=>{await w(`git branch -D ${m}`),i()},k=async()=>{await w(`git switch ${m}`),i(),s()},L=he();return nt((S,z)=>{e!=="Branches"||t||(z.upArrow?f():z.downArrow?p():S==="c"?L.open():S==="d"?d():S==="s"&&k())}),xe(it,{children:[T(v,{width:"100%",title:"Branches",innerHeight:o-1,children:a.map(S=>xe($,{flexDirection:"row",flexWrap:"nowrap",children:[T($,{minWidth:2,children:S===m?T(ge,{children:"> "}):null}),T($,{minWidth:8,children:T(ge,{color:S===r?"magenta":void 0,children:S})})]},S))}),T(pe,{title:"Name your new branch",handleSubmit:u,modalControls:L})]})}import{Text as U}from"ink";import{Fragment as st}from"react";import{jsx as _,jsxs as ve}from"react/jsx-runtime";function ye(){let{value:e}=y(Z);return _(v,{width:"50%",title:"Remotes",children:e?.map(({url:t,name:o,type:n})=>ve(st,{children:[ve(U,{wrap:"truncate-end",children:[o," (",n,")"]}),_(U,{wrap:"truncate-end",children:t}),_(U,{children:" "})]},`${o}-${n}`))})}import{Text as q}from"ink";import{Fragment as ct}from"react";import{jsx as W,jsxs as lt}from"react/jsx-runtime";function Se(){let{sectionHalfHeight:e}=h(),{value:t}=y(at);return W(v,{width:"100%",title:"Worktrees",innerHeight:e-1,children:t?.map(({branch:o,detached:n,path:i,head:r})=>lt(ct,{children:[W(q,{children:n?r:o}),W(q,{children:i}),W(q,{children:" "})]},i))})}async function at(){let{stdout:e}=await w("git worktree list --porcelain"),t=e.trim().split(/\r?\n/),o=[],n=[];for(let i of t)i.trim()===""?n.length&&(o.push(n),n=[]):n.push(i);return n.length&&o.push(n),o.map(i=>{let r={detached:!1};for(let s of i)s.startsWith("worktree ")?r.path=s.slice(9):s.startsWith("HEAD ")?r.head=s.slice(5):s.startsWith("branch ")?r.branch=s.slice(7):s==="detached"&&(r.detached=!0);return r})}import{Fragment as mt,jsx as A,jsxs as be}from"react/jsx-runtime";function Be(){let{width:e,sectionHeight:t}=h(),{setKeybinding:o,removeKeybinding:n}=b();return ut(()=>(o("c","create"),o("d","delete"),()=>{n(["c","d"])}),[]),A(mt,{children:be(we,{width:e,height:t,children:[be(we,{flexDirection:"column",width:"50%",height:t,children:[A(F,{}),A(Se,{})]}),A(ye,{})]})})}import{jsx as Y,jsxs as pt}from"react/jsx-runtime";function Te(){let{prevSection:e,nextSection:t,activeGroup:o,setActiveGroup:n}=g();switch(dt((i,r)=>{r.tab&&r.shift?e():r.tab?t():i==="1"?n("Status"):i==="2"?n("Log"):i==="3"&&n("Branches")}),o){case"Status":return Y(O,{});case"Log":return Y(V,{});case"Branches":return Y(Be,{});default:return pt(ft,{children:["Error, unknown page ",o]})}}import{jsx as M,jsxs as vt}from"react/jsx-runtime";function Ce(){let{isLocked:e}=g();xt((i,r)=>{e||i.toLowerCase()==="q"&&process.exit()});let t=h(),{keybindings:o,setKeybinding:n}=b();return ht(()=>n("q","quit"),[]),vt(ke,{flexDirection:"column",...t,children:[M(re,{}),M(Te,{}),M(ke,{flexDirection:"row",children:Object.entries(o).map(([i,r])=>M(gt,{children:`[${i}]: ${r} `},r))})]})}import{jsx as H}from"react/jsx-runtime";function St(){return H(oe,{children:H(ee,{children:H(Ce,{})})})}var Nn=()=>yt(H(St,{}),{patchConsole:!0});export{Nn 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-ALXMXO3T.js");return e()}let{runCommand:o}=await import("./chunks/commands-2Y6VXVCP.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.4.0",
4
4
  "description": "Git CLI tool to simplify common advanced git workflows",
5
5
  "main": "dist/main.js",
6
6
  "bin": {
@@ -61,6 +61,7 @@
61
61
  "clipboardy": "^5.0.2",
62
62
  "ink": "^6.6.0",
63
63
  "ink-spinner": "^5.0.0",
64
+ "ink-text-input": "^6.0.0",
64
65
  "nanoid": "^5.1.6",
65
66
  "react": "^19.2.3"
66
67
  }
@@ -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,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};