git-agents 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -1
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
A terminal UI tool to sync your AI agents and skills across machines using git.
|
|
4
4
|
|
|
5
|
+
Supports **OpenCode**, **Claude Code**, **Codex**, **Cursor**, and [41 more](#supported-agents).
|
|
6
|
+
|
|
5
7
|
## What it does
|
|
6
8
|
|
|
7
|
-
`ga` keeps your
|
|
9
|
+
`ga` keeps your AI agent directories in sync with a remote git repository — so your custom skills follow you everywhere.
|
|
8
10
|
|
|
9
11
|
## Install
|
|
10
12
|
|
|
@@ -71,3 +73,53 @@ Select **Edit Config** from the main menu to reconfigure your remote at any time
|
|
|
71
73
|
- [Bun](https://bun.sh)
|
|
72
74
|
- [git](https://git-scm.com)
|
|
73
75
|
- [GitHub CLI](https://cli.github.com) *(only if using the GH CLI remote option)*
|
|
76
|
+
|
|
77
|
+
## Supported agents
|
|
78
|
+
|
|
79
|
+
| Agent | Global path |
|
|
80
|
+
|-------|-------------|
|
|
81
|
+
| Amp | `~/.config/agents/` |
|
|
82
|
+
| Antigravity | `~/.gemini/antigravity/` |
|
|
83
|
+
| Augment | `~/.augment/` |
|
|
84
|
+
| IBM Bob | `~/.bob/` |
|
|
85
|
+
| Claude Code | `~/.claude/` |
|
|
86
|
+
| Cline | `~/.agents/` |
|
|
87
|
+
| CodeBuddy | `~/.codebuddy/` |
|
|
88
|
+
| Codex | `~/.codex/` |
|
|
89
|
+
| Command Code | `~/.commandcode/` |
|
|
90
|
+
| Continue | `~/.continue/` |
|
|
91
|
+
| Cortex Code | `~/.snowflake/cortex/` |
|
|
92
|
+
| Crush | `~/.config/crush/` |
|
|
93
|
+
| Cursor | `~/.cursor/` |
|
|
94
|
+
| Deep Agents | `~/.deepagents/agent/` |
|
|
95
|
+
| Droid | `~/.factory/` |
|
|
96
|
+
| Firebender | `~/.firebender/` |
|
|
97
|
+
| Gemini CLI | `~/.gemini/` |
|
|
98
|
+
| GitHub Copilot | `~/.copilot/` |
|
|
99
|
+
| Goose | `~/.config/goose/` |
|
|
100
|
+
| iFlow CLI | `~/.iflow/` |
|
|
101
|
+
| Junie | `~/.junie/` |
|
|
102
|
+
| Kilo Code | `~/.kilocode/` |
|
|
103
|
+
| Kimi Code CLI | `~/.config/agents/` |
|
|
104
|
+
| Kiro CLI | `~/.kiro/` |
|
|
105
|
+
| Kode | `~/.kode/` |
|
|
106
|
+
| MCPJam | `~/.mcpjam/` |
|
|
107
|
+
| Mistral Vibe | `~/.vibe/` |
|
|
108
|
+
| Mux | `~/.mux/` |
|
|
109
|
+
| OpenClaw | `~/.openclaw/` |
|
|
110
|
+
| OpenCode | `~/.config/opencode/` |
|
|
111
|
+
| OpenHands | `~/.openhands/` |
|
|
112
|
+
| Pi | `~/.pi/agent/` |
|
|
113
|
+
| Pochi | `~/.pochi/` |
|
|
114
|
+
| Qoder | `~/.qoder/` |
|
|
115
|
+
| Qwen Code | `~/.qwen/` |
|
|
116
|
+
| Replit | `~/.config/agents/` |
|
|
117
|
+
| Roo Code | `~/.roo/` |
|
|
118
|
+
| Trae | `~/.trae/` |
|
|
119
|
+
| Trae CN | `~/.trae-cn/` |
|
|
120
|
+
| Universal | `~/.config/agents/` |
|
|
121
|
+
| Warp | `~/.agents/` |
|
|
122
|
+
| Windsurf | `~/.codeium/windsurf/` |
|
|
123
|
+
| Zencoder | `~/.zencoder/` |
|
|
124
|
+
| Neovate | `~/.neovate/` |
|
|
125
|
+
| AdaL | `~/.adal/` |
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
import{createCliRenderer as Xn}from"@opentui/core";import{createRoot as Zn}from"@opentui/react";import{join as O}from"path";import{homedir as A}from"os";import{existsSync as pn,mkdirSync as ln,readFileSync as hn,writeFileSync as wn}from"fs";var $=O(A(),".git-agents"),N=O($,"config.json"),F=O($,".agents"),Y=O(A(),".agents");function _(){try{if(!pn(N))return null;let n=hn(N,"utf8");return JSON.parse(n)}catch{return null}}function S(n){ln($,{recursive:!0}),wn(N,JSON.stringify(n,null,2),"utf8")}import{useState as mn}from"react";import{useKeyboard as Wn}from"@opentui/react";import{useKeyboard as qn}from"@opentui/react";import{jsxDEV as P}from"@opentui/react/jsx-dev-runtime";function s({onNavigate:n}){return qn((o)=>{if(o.name==="escape"||o.ctrl&&o.name==="c")process.exit(0)}),P("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,children:[P("box",{flexDirection:"column",alignItems:"center",gap:1,children:[P("ascii-font",{font:"tiny",text:"git-agents"},void 0,!1,void 0,this),P("text",{children:"Sync your Claude agents directory with a remote git repo"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P("box",{flexDirection:"column",width:40,marginTop:2,children:P("select",{focused:!0,options:[{name:"Pull",description:"Download agents from remote to local"},{name:"Push",description:"Upload local agents to remote"},{name:"Edit Config",description:"Change remote configuration"}],onSelect:(o)=>{if(o===0)n({id:"sync",mode:"pull"});else if(o===1)n({id:"sync",mode:"push"});else if(o===2)n({id:"setup"})}},void 0,!1,void 0,this)},void 0,!1,void 0,this),P("box",{marginTop:1,children:P("text",{children:"\u2191\u2193 navigate Enter select Ctrl+C quit"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{useState as J,useEffect as vn}from"react";import{useKeyboard as Jn}from"@opentui/react";import{TextAttributes as B}from"@opentui/core";var{$:p}=globalThis.Bun;async function x(){try{let n=await p`gh --version`.quiet();return{ok:n.exitCode===0,output:n.stdout.toString()}}catch(n){return{ok:!1,error:n.message??"gh not found"}}}async function M(){try{return{ok:(await p`gh auth status`.quiet()).exitCode===0}}catch{return{ok:!1,error:"Not authenticated. Run: gh auth login"}}}async function j(n){try{return{ok:(await p`gh repo view ${n}`.quiet()).exitCode===0}}catch{return{ok:!1}}}async function V(n){try{let o=await p`gh repo create ${n} --private`.quiet();return{ok:o.exitCode===0,output:o.stdout.toString()}}catch(o){return{ok:!1,error:o.stderr?.toString()??o.message}}}async function T(n){try{let i=(await p`gh repo view ${n} --json sshUrl --jq .sshUrl`.quiet()).stdout.toString().trim();return{ok:!!i,output:i}}catch(o){return{ok:!1,error:o.message}}}async function D(n){try{return{ok:(await p`git ls-remote ${n}`.quiet()).exitCode===0}}catch{return{ok:!1,error:"Cannot reach repository"}}}async function E(n,o){try{return{ok:(await p`git clone ${n} ${o}`.quiet()).exitCode===0}}catch(i){return{ok:!1,error:i.stderr?.toString()??i.message}}}async function nn(n){try{let o=await p`git -C ${n} pull`.quiet();return{ok:o.exitCode===0,output:o.stdout.toString()}}catch(o){return{ok:!1,error:o.stderr?.toString()??o.message}}}async function rn(n,o){try{if(await p`git -C ${n} add -A`.quiet(),!(await p`git -C ${n} status --porcelain`.quiet()).stdout.toString().trim())return{ok:!0,output:"Nothing to commit"};return await p`git -C ${n} commit -m ${o}`.quiet(),{ok:(await p`git -C ${n} push`.quiet()).exitCode===0}}catch(i){return{ok:!1,error:i.stderr?.toString()??i.message}}}import{existsSync as $n,readdirSync as on,mkdirSync as en,cpSync as Cn}from"fs";import{join as Pn}from"path";function d(n){if(!$n(n))return[];try{return on(n,{withFileTypes:!0}).filter((o)=>o.isDirectory()).map((o)=>{let i=Pn(n,o.name),c=0;try{c=on(i).length}catch{}return{name:o.name,fileCount:c}}).sort((o,i)=>o.name.localeCompare(i.name))}catch{return[]}}function cn(n,o){let i=d(n),c=d(o),q=new Map(i.map((m)=>[m.name,m])),h=new Map(c.map((m)=>[m.name,m])),y=[],K=[],e=[],v=[];for(let m of i)if(!h.has(m.name))y.push(m);else{let W=h.get(m.name);if(m.fileCount!==W.fileCount)e.push(m);else v.push(m)}for(let m of c)if(!q.has(m.name))K.push(m);return{added:y,removed:K,modified:e,unchanged:v}}function tn(n,o){en(o,{recursive:!0}),Cn(n,o,{recursive:!0,force:!0})}import{jsxDEV as a}from"@opentui/react/jsx-dev-runtime";function an({mode:n,onBack:o}){let[i,c]=J("loading"),[q,h]=J("Fetching remote..."),[y,K]=J(null),[e,v]=J(0),[m,W]=J(0),[H,w]=J(null),[X,C]=J("");Jn((u)=>{if(u.name==="escape"){if(i==="done"||i==="review")o()}}),vn(()=>{async function u(){h("Pulling remote changes...");let Q=await nn($);if(!Q.ok){w(`Failed to pull remote: ${Q.error??"unknown error"}`),c("done");return}h("Comparing agents...");let t=n==="pull"?F:Y,f=n==="pull"?Y:F,I=cn(t,f),Z=d(t),R=d(f);K(I),W(n==="pull"?Z.length:R.length),v(n==="pull"?R.length:Z.length),c("review")}u()},[]);async function U(u){if(!u){o();return}c("executing"),h(n==="pull"?"Copying agents from remote...":"Copying agents to remote...");let Q=n==="pull"?F:Y,t=n==="pull"?Y:F;try{tn(Q,t)}catch(f){w(`Failed to copy agents: ${f.message}`),c("done");return}if(n==="push"){h("Committing and pushing to remote...");let f=await rn($,`sync: update agents from local (${new Date().toISOString().slice(0,10)})`);if(!f.ok){w(`Failed to push: ${f.error??"unknown error"}`),c("done");return}}C(n==="pull"?"Pull complete! Local agents updated.":"Push complete! Remote updated."),w(null),c("done")}let L=n==="pull"?"Pull":"Push";if(i==="loading"||i==="executing")return a("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,children:a("text",{children:q},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(i==="done")return a("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,gap:1,children:[H?a("text",{fg:"#ff5555",children:H},void 0,!1,void 0,this):a("text",{fg:"#50fa7b",children:X},void 0,!1,void 0,this),a("text",{attributes:B.DIM,children:"Press Esc to go back"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let g=y,b=g.added.length>0||g.removed.length>0||g.modified.length>0;return a("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,gap:1,children:[a("ascii-font",{font:"tiny",text:L},void 0,!1,void 0,this),a("box",{flexDirection:"column",border:!0,borderStyle:"rounded",title:" Comparison ",paddingX:2,paddingY:1,width:60,gap:1,children:[a("box",{flexDirection:"row",justifyContent:"space-between",children:[a("text",{children:[a("span",{children:"Remote: "},void 0,!1,void 0,this),a("span",{fg:"#8be9fd",children:[m," skills"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a("text",{children:[a("span",{children:"Local: "},void 0,!1,void 0,this),a("span",{fg:"#8be9fd",children:[e," skills"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),!b&&a("text",{attributes:B.DIM,children:"No changes"},void 0,!1,void 0,this),g.added.map((u)=>a("text",{children:[a("span",{fg:"#50fa7b",children:"+ "},void 0,!1,void 0,this),a("span",{children:u.name},void 0,!1,void 0,this)]},u.name,!0,void 0,this)),g.removed.map((u)=>a("text",{children:[a("span",{fg:"#ff5555",children:"- "},void 0,!1,void 0,this),a("span",{children:u.name},void 0,!1,void 0,this)]},u.name,!0,void 0,this)),g.modified.map((u)=>a("text",{children:[a("span",{fg:"#ffb86c",children:"~ "},void 0,!1,void 0,this),a("span",{children:u.name},void 0,!1,void 0,this)]},u.name,!0,void 0,this)),g.unchanged.length>0&&a("text",{attributes:B.DIM,children:[g.unchanged.length," skill",g.unchanged.length!==1?"s":""," unchanged"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a("box",{flexDirection:"column",alignItems:"center",gap:1,children:[a("text",{children:[a("span",{children:["Confirm ",n,"? "]},void 0,!0,void 0,this),a("span",{attributes:B.DIM,children:"(No is default \u2014 press Enter to cancel)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),a("select",{focused:!0,options:[{name:"No, cancel",description:"Go back to main menu"},{name:`Yes, ${n}`,description:b?"Apply changes":"No changes to apply"}],onSelect:(u)=>U(u===1),width:30},void 0,!1,void 0,this)]},void 0,!0,void 0,this),a("text",{attributes:B.DIM,children:"Esc to cancel"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{useState as k,useEffect as kn}from"react";import{useKeyboard as zn}from"@opentui/react";import{TextAttributes as l}from"@opentui/core";import{existsSync as Kn}from"fs";import{join as Qn}from"path";import{jsxDEV as r}from"@opentui/react/jsx-dev-runtime";var z="git-agents-remote";function fn({existingConfig:n,onComplete:o}){let[i,c]=k("welcome"),[q,h]=k(n?.remote??"gh"),[y,K]=k(n?.repoUrl??""),[e,v]=k(""),[m,W]=k(!1),[H,w]=k(""),[X,C]=k("");zn((t)=>{if(t.ctrl&&t.name==="c")process.exit(0);if(i==="welcome"&&t.name==="return")c("choose-remote");if(i==="gh-auth-needed"&&t.name==="return")U();if(i==="error"&&t.name==="return")c("choose-remote")});async function U(){if(c("gh-checking"),C("Checking gh auth..."),!(await M()).ok){c("gh-auth-needed");return}g()}async function L(){if(c("gh-checking"),C("Checking gh CLI..."),!(await x()).ok){w("GitHub CLI (gh) is not installed. Install it from https://cli.github.com and try again."),c("error");return}if(!(await M()).ok){c("gh-auth-needed");return}g()}async function g(){c("gh-checking"),C("Checking for git-agents repo...");let t=await j(z);if(W(t.ok),!t.ok){c("gh-repo-check");return}let f=await T(z);if(!f.ok||!f.output){w("Could not get repo URL from gh CLI."),c("error");return}v(f.output.trim()),c("gh-confirm")}async function b(){c("gh-checking"),C(`Creating private repo "${z}"...`);let t=await V(z);if(!t.ok){w(`Failed to create repo: ${t.error??"unknown error"}`),c("error");return}let f=await T(z);if(!f.ok||!f.output){w("Could not get repo URL after creating it."),c("error");return}v(f.output.trim()),c("gh-confirm")}async function u(t,f){c("cloning"),C(`Cloning ${t}...`);let I={remote:f,repoUrl:f==="git"?t:void 0};if(Kn(Qn($,".git"))){S(I),c("done");return}let Z=await E(t,$);if(!Z.ok){w(`Failed to clone: ${Z.error??"unknown error"}`),c("error");return}S(I),c("done")}async function Q(t){if(c("git-url-checking"),C("Validating repository..."),!(await D(t)).ok){w(`Cannot reach repository: ${t}
|
|
4
|
-
Make sure the URL is correct and you have access.`),
|
|
3
|
+
import{createCliRenderer as On}from"@opentui/core";import{createRoot as Qn}from"@opentui/react";import{join as z,relative as sn}from"path";import{homedir as H}from"os";import{existsSync as Pn,mkdirSync as Cn,readFileSync as wn,writeFileSync as vn}from"fs";var C=z(H(),".git-agents"),T=z(C,"config.json"),Gn=z(C,".agents"),$n=z(H(),".agents");function D(){try{if(!Pn(T))return null;let n=wn(T,"utf8");return JSON.parse(n)}catch{return null}}function _(n){Cn(C,{recursive:!0}),vn(T,JSON.stringify(n,null,2),"utf8")}function G(n){let e=sn(H(),n);return z(C,e)}import{useState as mn}from"react";import{useKeyboard as Bn}from"@opentui/react";import{useKeyboard as In}from"@opentui/react";import{jsxDEV as L}from"@opentui/react/jsx-dev-runtime";function j({onNavigate:n}){return In((e)=>{if(e.name==="escape"||e.ctrl&&e.name==="c")process.exit(0)}),L("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,children:[L("box",{flexDirection:"column",alignItems:"center",gap:1,children:[L("ascii-font",{font:"tiny",text:"git-agents"},void 0,!1,void 0,this),L("text",{children:"Sync your Claude agents directory with a remote git repo"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L("box",{flexDirection:"column",width:40,marginTop:2,children:L("select",{focused:!0,options:[{name:"Pull",description:"Download agents from remote to local"},{name:"Push",description:"Upload local agents to remote"},{name:"Edit Config",description:"Change remote configuration"}],onSelect:(e)=>{if(e===0)n({id:"sync",mode:"pull"});else if(e===1)n({id:"sync",mode:"push"});else if(e===2)n({id:"setup"})},height:6},void 0,!1,void 0,this)},void 0,!1,void 0,this),L("box",{marginTop:1,children:L("text",{children:"\u2191\u2193 navigate Enter select Ctrl+C quit"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{useState as O,useEffect as Kn}from"react";import{useKeyboard as qn}from"@opentui/react";import{TextAttributes as q}from"@opentui/core";var{$:h}=globalThis.Bun;async function V(){try{let n=await h`gh --version`.quiet();return{ok:n.exitCode===0,output:n.stdout.toString()}}catch(n){return{ok:!1,error:n.message??"gh not found"}}}async function $(){try{return{ok:(await h`gh auth status`.quiet()).exitCode===0}}catch{return{ok:!1,error:"Not authenticated. Run: gh auth login"}}}async function E(n){try{return{ok:(await h`gh repo view ${n}`.quiet()).exitCode===0}}catch{return{ok:!1}}}async function nn(n){try{let e=await h`gh repo create ${n} --private`.quiet();return{ok:e.exitCode===0,output:e.stdout.toString()}}catch(e){return{ok:!1,error:e.stderr?.toString()??e.message}}}async function U(n){try{let t=(await h`gh repo view ${n} --json sshUrl --jq .sshUrl`.quiet()).stdout.toString().trim();return{ok:!!t,output:t}}catch(e){return{ok:!1,error:e.message}}}async function on(n){try{return{ok:(await h`git ls-remote ${n}`.quiet()).exitCode===0}}catch{return{ok:!1,error:"Cannot reach repository"}}}async function en(n,e){try{return{ok:(await h`git clone ${n} ${e}`.quiet()).exitCode===0}}catch(t){return{ok:!1,error:t.stderr?.toString()??t.message}}}async function tn(n){try{let e=await h`git -C ${n} pull`.quiet();return{ok:e.exitCode===0,output:e.stdout.toString()}}catch(e){let t=e.stderr?.toString()??e.message??"";if(t.includes("no such ref was fetched")||t.includes("couldn't find remote ref"))return{ok:!0,output:"Remote is empty"};return{ok:!1,error:t}}}async function an(n,e){try{if(await h`git -C ${n} add -A`.quiet(),!(await h`git -C ${n} status --porcelain`.quiet()).stdout.toString().trim())return{ok:!0,output:"Nothing to commit"};return await h`git -C ${n} commit -m ${e}`.quiet(),{ok:(await h`git -C ${n} push -u origin HEAD`.quiet()).exitCode===0}}catch(t){return{ok:!1,error:t.stderr?.toString()??t.message}}}import{existsSync as An,readdirSync as rn,mkdirSync as Fn,cpSync as Ln}from"fs";import{join as Sn}from"path";function B(n){if(!An(n))return[];try{return rn(n,{withFileTypes:!0}).filter((e)=>e.isDirectory()).map((e)=>{let t=Sn(n,e.name),r=0;try{r=rn(t).length}catch{}return{name:e.name,fileCount:r}}).sort((e,t)=>e.name.localeCompare(t.name))}catch{return[]}}function ln(n,e){let t=B(n),r=B(e),w=new Map(t.map((p)=>[p.name,p])),s=new Map(r.map((p)=>[p.name,p])),d=[],K=[],v=[],P=[];for(let p of t)if(!s.has(p.name))d.push(p);else{let J=s.get(p.name);if(p.fileCount!==J.fileCount)v.push(p);else P.push(p)}for(let p of r)if(!w.has(p.name))K.push(p);return{added:d,removed:K,modified:v,unchanged:P}}function cn(n,e){Fn(e,{recursive:!0}),Ln(n,e,{recursive:!0,force:!0})}import{join as a}from"path";import{homedir as Nn}from"os";var i=Nn(),fn=[{id:"amp",name:"Amp",globalPath:a(i,".config/agents")},{id:"kimi-cli",name:"Kimi Code CLI",globalPath:a(i,".config/agents")},{id:"replit",name:"Replit",globalPath:a(i,".config/agents")},{id:"universal",name:"Universal",globalPath:a(i,".config/agents")},{id:"antigravity",name:"Antigravity",globalPath:a(i,".gemini/antigravity")},{id:"augment",name:"Augment",globalPath:a(i,".augment")},{id:"bob",name:"IBM Bob",globalPath:a(i,".bob")},{id:"claude-code",name:"Claude Code",globalPath:a(i,".claude")},{id:"openclaw",name:"OpenClaw",globalPath:a(i,".openclaw")},{id:"cline",name:"Cline",globalPath:a(i,".agents")},{id:"warp",name:"Warp",globalPath:a(i,".agents")},{id:"codebuddy",name:"CodeBuddy",globalPath:a(i,".codebuddy")},{id:"codex",name:"Codex",globalPath:a(i,".codex")},{id:"command-code",name:"Command Code",globalPath:a(i,".commandcode")},{id:"continue",name:"Continue",globalPath:a(i,".continue")},{id:"cortex",name:"Cortex Code",globalPath:a(i,".snowflake/cortex")},{id:"crush",name:"Crush",globalPath:a(i,".config/crush")},{id:"cursor",name:"Cursor",globalPath:a(i,".cursor")},{id:"deepagents",name:"Deep Agents",globalPath:a(i,".deepagents/agent")},{id:"droid",name:"Droid",globalPath:a(i,".factory")},{id:"firebender",name:"Firebender",globalPath:a(i,".firebender")},{id:"gemini-cli",name:"Gemini CLI",globalPath:a(i,".gemini")},{id:"github-copilot",name:"GitHub Copilot",globalPath:a(i,".copilot")},{id:"goose",name:"Goose",globalPath:a(i,".config/goose")},{id:"junie",name:"Junie",globalPath:a(i,".junie")},{id:"iflow-cli",name:"iFlow CLI",globalPath:a(i,".iflow")},{id:"kilo",name:"Kilo Code",globalPath:a(i,".kilocode")},{id:"kiro-cli",name:"Kiro CLI",globalPath:a(i,".kiro")},{id:"kode",name:"Kode",globalPath:a(i,".kode")},{id:"mcpjam",name:"MCPJam",globalPath:a(i,".mcpjam")},{id:"mistral-vibe",name:"Mistral Vibe",globalPath:a(i,".vibe")},{id:"mux",name:"Mux",globalPath:a(i,".mux")},{id:"opencode",name:"OpenCode",globalPath:a(i,".config/opencode")},{id:"openhands",name:"OpenHands",globalPath:a(i,".openhands")},{id:"pi",name:"Pi",globalPath:a(i,".pi/agent")},{id:"qoder",name:"Qoder",globalPath:a(i,".qoder")},{id:"qwen-code",name:"Qwen Code",globalPath:a(i,".qwen")},{id:"roo",name:"Roo Code",globalPath:a(i,".roo")},{id:"trae",name:"Trae",globalPath:a(i,".trae")},{id:"trae-cn",name:"Trae CN",globalPath:a(i,".trae-cn")},{id:"windsurf",name:"Windsurf",globalPath:a(i,".codeium/windsurf")},{id:"zencoder",name:"Zencoder",globalPath:a(i,".zencoder")},{id:"neovate",name:"Neovate",globalPath:a(i,".neovate")},{id:"pochi",name:"Pochi",globalPath:a(i,".pochi")},{id:"adal",name:"AdaL",globalPath:a(i,".adal")}];import{jsxDEV as c}from"@opentui/react/jsx-dev-runtime";function gn({mode:n,onBack:e}){let[t,r]=O("loading"),[w,s]=O("Fetching remote..."),[d,K]=O([]),[v,P]=O(null),[p,J]=O("");qn((f)=>{if(f.name==="escape"){if(t==="done"||t==="review")e()}}),Kn(()=>{async function f(){s("Pulling remote changes...");let g=await tn(C);if(!g.ok){P(`Failed to pull remote: ${g.error??"unknown error"}`),r("done");return}s("Comparing agents...");let u=new Map;for(let l of fn){let m=u.get(l.globalPath)??[];u.set(l.globalPath,[...m,l])}let b=[];for(let[l,m]of u){let k=G(l),Y=n==="pull"?k:l,x=n==="pull"?l:k,hn=ln(Y,x),Z=B(Y),M=B(x);if(Z.length===0&&M.length===0)continue;for(let yn of m)b.push({def:yn,diff:hn,remoteCount:n==="pull"?Z.length:M.length,localCount:n==="pull"?M.length:Z.length})}K(b),r("review")}f()},[]);async function Q(f){if(!f){e();return}r("executing"),s(n==="pull"?"Copying agents from remote...":"Copying agents to remote...");let g=new Set;try{for(let u of d){if(g.has(u.def.globalPath))continue;g.add(u.def.globalPath);let b=G(u.def.globalPath),l=n==="pull"?b:u.def.globalPath,m=n==="pull"?u.def.globalPath:b;cn(l,m)}}catch(u){P(`Failed to copy agents: ${u.message}`),r("done");return}if(n==="push"){s("Committing and pushing to remote...");let u=await an(C,`sync: update agents from local (${new Date().toISOString().slice(0,10)})`);if(!u.ok){P(`Failed to push: ${u.error??"unknown error"}`),r("done");return}}J(n==="pull"?"Pull complete! Local agents updated.":"Push complete! Remote updated."),P(null),r("done")}let A=n==="pull"?"Pull":"Push";if(t==="loading"||t==="executing")return c("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,children:c("text",{children:w},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(t==="done")return c("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,gap:1,children:[v?c("text",{fg:"#ff5555",children:v},void 0,!1,void 0,this):c("text",{fg:"#50fa7b",children:p},void 0,!1,void 0,this),c("text",{attributes:q.DIM,children:"Press Esc to go back"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let I=new Set,F=d.reduce((f,g)=>{if(I.has(g.def.globalPath))return f;return I.add(g.def.globalPath),f+g.remoteCount},0);I.clear();let W=d.reduce((f,g)=>{if(I.has(g.def.globalPath))return f;return I.add(g.def.globalPath),f+g.localCount},0),X=d.some((f)=>f.diff.added.length>0||f.diff.removed.length>0||f.diff.modified.length>0);return c("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,gap:1,children:[c("ascii-font",{font:"tiny",text:A},void 0,!1,void 0,this),c("box",{flexDirection:"column",border:!0,borderStyle:"rounded",title:" Comparison ",paddingX:2,paddingY:1,width:60,gap:1,children:[c("box",{flexDirection:"row",justifyContent:"space-between",children:[c("text",{children:[c("span",{children:"Remote: "},void 0,!1,void 0,this),c("span",{fg:"#8be9fd",children:[F," skills"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),c("text",{children:[c("span",{children:"Local: "},void 0,!1,void 0,this),c("span",{fg:"#8be9fd",children:[W," skills"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),d.length===0&&c("text",{attributes:q.DIM,children:"No agents found"},void 0,!1,void 0,this),d.map((f)=>{let g=f.diff,u=g.added.length>0||g.removed.length>0||g.modified.length>0;return c("box",{flexDirection:"column",children:[c("box",{flexDirection:"row",justifyContent:"space-between",children:[c("text",{fg:"#bd93f9",children:f.def.name},void 0,!1,void 0,this),c("text",{attributes:q.DIM,children:[f.remoteCount,"\u2193 / ",f.localCount,"\u2191"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),g.added.map((b)=>c("text",{children:[c("span",{fg:"#50fa7b",children:" + "},void 0,!1,void 0,this),c("span",{children:b.name},void 0,!1,void 0,this)]},b.name,!0,void 0,this)),g.removed.map((b)=>c("text",{children:[c("span",{fg:"#ff5555",children:" - "},void 0,!1,void 0,this),c("span",{children:b.name},void 0,!1,void 0,this)]},b.name,!0,void 0,this)),g.modified.map((b)=>c("text",{children:[c("span",{fg:"#ffb86c",children:" ~ "},void 0,!1,void 0,this),c("span",{children:b.name},void 0,!1,void 0,this)]},b.name,!0,void 0,this)),!u&&g.unchanged.length>0&&c("text",{attributes:q.DIM,children:[" ",g.unchanged.length," skill",g.unchanged.length!==1?"s":""," unchanged"]},void 0,!0,void 0,this)]},f.def.id,!0,void 0,this)})]},void 0,!0,void 0,this),c("box",{flexDirection:"column",alignItems:"center",gap:1,children:[c("text",{children:[c("span",{children:["Confirm ",n,"? "]},void 0,!0,void 0,this),c("span",{attributes:q.DIM,children:"(No is default \u2014 press Enter to cancel)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),c("select",{focused:!0,options:[{name:"No, cancel",description:"Go back to main menu"},{name:`Yes, ${n}`,description:X?"Apply changes":"No changes to apply"}],onSelect:(f)=>Q(f===1),width:30,height:4},void 0,!1,void 0,this)]},void 0,!0,void 0,this),c("text",{attributes:q.DIM,children:"Esc to cancel"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{useState as S,useEffect as Jn}from"react";import{useKeyboard as kn}from"@opentui/react";import{TextAttributes as y}from"@opentui/core";import{existsSync as Yn}from"fs";import{join as zn}from"path";import{jsxDEV as o}from"@opentui/react/jsx-dev-runtime";var N="git-agents-remote";function dn({existingConfig:n,onComplete:e}){let[t,r]=S("welcome"),[w,s]=S(n?.remote??"gh"),[d,K]=S(n?.repoUrl??""),[v,P]=S(""),[p,J]=S(!1),[Q,A]=S(""),[I,F]=S("");kn((l)=>{if(l.ctrl&&l.name==="c")process.exit(0);if(t==="welcome"&&l.name==="return")r("choose-remote");if(t==="gh-auth-needed"&&l.name==="return")W();if(t==="error"&&l.name==="return")r("choose-remote")});async function W(){if(r("gh-checking"),F("Checking gh auth..."),!(await $()).ok){r("gh-auth-needed");return}f()}async function X(){if(r("gh-checking"),F("Checking gh CLI..."),!(await V()).ok){A("GitHub CLI (gh) is not installed. Install it from https://cli.github.com and try again."),r("error");return}if(!(await $()).ok){r("gh-auth-needed");return}f()}async function f(){r("gh-checking"),F("Checking for git-agents repo...");let l=await E(N);if(J(l.ok),!l.ok){r("gh-repo-check");return}let m=await U(N);if(!m.ok||!m.output){A("Could not get repo URL from gh CLI."),r("error");return}P(m.output.trim()),r("gh-confirm")}async function g(){r("gh-checking"),F(`Creating private repo "${N}"...`);let l=await nn(N);if(!l.ok){A(`Failed to create repo: ${l.error??"unknown error"}`),r("error");return}let m=await U(N);if(!m.ok||!m.output){A("Could not get repo URL after creating it."),r("error");return}P(m.output.trim()),r("gh-confirm")}async function u(l,m){r("cloning"),F(`Cloning ${l}...`);let k={remote:m,repoUrl:m==="git"?l:void 0};if(Yn(zn(C,".git"))){_(k),r("done");return}let Y=await en(l,C);if(!Y.ok){A(`Failed to clone: ${Y.error??"unknown error"}`),r("error");return}_(k),r("done")}async function b(l){if(r("git-url-checking"),F("Validating repository..."),!(await on(l)).ok){A(`Cannot reach repository: ${l}
|
|
4
|
+
Make sure the URL is correct and you have access.`),r("error");return}await u(l,"git")}if(Jn(()=>{if(t==="done")e({remote:w,repoUrl:w==="git"?v||d:void 0})},[t]),t==="welcome")return o("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,gap:2,children:[o("ascii-font",{font:"tiny",text:"git-agents"},void 0,!1,void 0,this),o("box",{flexDirection:"column",alignItems:"center",gap:1,width:60,children:[o("text",{children:"Sync your Claude agents skills with a remote git repo."},void 0,!1,void 0,this),o("text",{attributes:y.DIM,children:"Keeps ~/.agents in sync across machines using git."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o("text",{children:[o("span",{attributes:y.DIM,children:"Press "},void 0,!1,void 0,this),o("span",{children:"Enter"},void 0,!1,void 0,this),o("span",{attributes:y.DIM,children:" to start setup"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);if(t==="choose-remote")return o("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,gap:2,children:[o("text",{children:"Choose how to connect your remote:"},void 0,!1,void 0,this),o("select",{focused:!0,options:[{name:"GitHub CLI (gh)",description:"Auto-create and manage a private GitHub repo"},{name:"Custom Git Repo",description:"Use any existing remote git repository"}],selectedIndex:w==="gh"?0:1,onSelect:(l)=>{let m=l===0?"gh":"git";if(s(m),m==="gh")X();else r("git-url-input")},width:50,height:4},void 0,!1,void 0,this),o("text",{attributes:y.DIM,children:"\u2191\u2193 navigate Enter select"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(t==="gh-checking")return o("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,children:o("text",{children:I},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(t==="gh-auth-needed")return o("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,gap:2,children:[o("text",{fg:"#ffb86c",children:"Not authenticated with GitHub CLI."},void 0,!1,void 0,this),o("box",{border:!0,borderStyle:"rounded",paddingX:2,paddingY:1,children:o("text",{children:[o("span",{attributes:y.DIM,children:"Run in another terminal: "},void 0,!1,void 0,this),o("span",{fg:"#50fa7b",children:"gh auth login"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o("text",{children:[o("span",{attributes:y.DIM,children:"Press "},void 0,!1,void 0,this),o("span",{children:"Enter"},void 0,!1,void 0,this),o("span",{attributes:y.DIM,children:" once authenticated to continue"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);if(t==="gh-repo-check")return o("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,gap:2,children:[o("text",{children:["Repo ",o("span",{fg:"#8be9fd",children:['"',N,'"']},void 0,!0,void 0,this)," does not exist on your GitHub account."]},void 0,!0,void 0,this),o("select",{focused:!0,options:[{name:`Create private repo "${N}"`,description:"Recommended"},{name:"Cancel",description:"Go back to remote selection"}],onSelect:(l)=>{if(l===0)g();else r("choose-remote")},width:50,height:4},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(t==="gh-confirm")return o("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,gap:2,children:[o("text",{fg:"#50fa7b",children:p?"Found existing repo!":"Repository ready!"},void 0,!1,void 0,this),o("box",{border:!0,borderStyle:"rounded",paddingX:2,paddingY:1,flexDirection:"column",gap:1,children:[o("text",{children:[o("span",{attributes:y.DIM,children:"Repo: "},void 0,!1,void 0,this),o("span",{fg:"#8be9fd",children:v},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o("text",{children:[o("span",{attributes:y.DIM,children:"Will clone to: "},void 0,!1,void 0,this),o("span",{children:"~/.git-agents"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),o("select",{focused:!0,options:[{name:"Continue",description:"Clone repo and save config"},{name:"Cancel",description:"Go back to remote selection"}],onSelect:(l)=>{if(l===0)u(v,"gh");else r("choose-remote")},width:40,height:4},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(t==="git-url-input")return o("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,gap:2,children:[o("text",{children:"Enter the Git repository URL:"},void 0,!1,void 0,this),o("box",{border:!0,borderStyle:"rounded",paddingX:2,paddingY:1,width:60,children:o("input",{focused:!0,placeholder:"git@github.com:user/repo.git",value:d,onInput:K,onSubmit:()=>{if(d.trim())b(d.trim())},flexGrow:1},void 0,!1,void 0,this)},void 0,!1,void 0,this),o("text",{attributes:y.DIM,children:"Enter to confirm Esc to go back"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(t==="git-url-checking")return o("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,children:o("text",{children:I},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(t==="cloning")return o("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,children:o("text",{children:I},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(t==="error")return o("box",{flexDirection:"column",alignItems:"center",justifyContent:"center",flexGrow:1,gap:2,children:[o("text",{fg:"#ff5555",children:Q},void 0,!1,void 0,this),o("text",{children:[o("span",{attributes:y.DIM,children:"Press "},void 0,!1,void 0,this),o("span",{children:"Enter"},void 0,!1,void 0,this),o("span",{attributes:y.DIM,children:" to try again"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);return null}import{jsxDEV as R}from"@opentui/react/jsx-dev-runtime";function pn({initialScreen:n,initialConfig:e}){let[t,r]=mn(n),[w,s]=mn(e);if(Bn((d)=>{if(d.ctrl&&d.name==="c")process.exit(0)}),t.id==="setup")return R(dn,{existingConfig:t.existingConfig??w,onComplete:(d)=>{s(d),r({id:"main"})}},void 0,!1,void 0,this);if(t.id==="sync")return R(gn,{mode:t.mode,onBack:()=>r({id:"main"})},void 0,!1,void 0,this);return R(j,{onNavigate:(d)=>r(d)},void 0,!1,void 0,this)}import{jsxDEV as Mn}from"@opentui/react/jsx-dev-runtime";var Wn=process.argv.slice(2),un=Wn[0],bn=D(),Xn=!bn?{id:"setup"}:un==="pull"?{id:"sync",mode:"pull"}:un==="push"?{id:"sync",mode:"push"}:{id:"main"},Zn=await On({exitOnCtrlC:!1});Qn(Zn).render(Mn(pn,{initialScreen:Xn,initialConfig:bn??void 0},void 0,!1,void 0,this));
|