gigabuddy 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +1 -1
- package/index.js +9 -9
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -83,7 +83,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
83
83
|
`);s.push("",r("1"," What to do:"));for(let i of e.advice){let a=i.replace(/(.{1,74})(\s|$)/g,`$1
|
|
84
84
|
`).trimEnd().split(`
|
|
85
85
|
`);s.push(` \u2022 ${a[0]}`);for(let c of a.slice(1))s.push(` ${c}`)}return s.join(`
|
|
86
|
-
`)}var oP=["agent:spawn","discovery:read","packages:read"],Ne="user",sP="https://auth.gigabuddy.com",iP="https://api.gigabuddy.com",aP="https://auth.staging.gigabuddy.com",cP="https://api.staging.gigabuddy.com";function $y(e){let t=e.staging??!1;return{staging:t,authUrl:e.authUrl??(t?aP:sP),apiUrl:e.apiUrl??(t?cP:iP)}}function xy(e){try{return Hc(e,"utf-8")}catch{return""}}function h(e=""){console.error(e)}function Jt(e){return e?(Kt(e),{name:e,source:"env"}):Xe()}function ls(e){return e===Ct?"":` (account: ${e})`}async function zy(e,t){let r=Jt(t).name;h(`Signing in to ${e.staging?"Gigabuddy Staging":"Gigabuddy"}${ls(r)}\u2026`);let n=await sy({authUrl:e.authUrl,apiUrl:e.apiUrl,clientId:"gigabuddy-cli",scopes:oP,onPrompt:({verificationUrl:s,userCode:i})=>{h(),h(` Open: ${s}`),h(` Code: ${i}`),h()},onPending:()=>process.stderr.write(".")}),o={refreshToken:n.refreshToken,userId:n.userId,userEmail:n.userEmail,authUrl:e.authUrl,apiUrl:e.apiUrl,createdAt:new Date().toISOString()};return ws(o,e.staging,Ne,r),o}async function ky(e,t={}){let r=Jt(t.account).name,n=await zy(e,r);h(),h(" Signed in."),n.userEmail&&h(` Account: ${n.userEmail}${ls(r)}`),h(` Saved to: ${jr(e.staging,Ne,r)}`),t.account&&await uP(t.account),h(),h(` To install ${He} packages from the Gigabuddy registry: gigabuddy login --npm`)}async function uP(e){let t=Xe();if(t.name===e)return;let r=Ar(process.cwd());if(process.stdin.isTTY!==!0||process.stderr.isTTY!==!0){h(),h(` This directory resolves account "${t.name}". To use ${e} here: gigabuddy use ${e}`);return}h();let n=by.createInterface({input:process.stdin,output:process.stderr});try{let o=(await n.question(` Always use "${e}" in ${r}? [Y/n] `)).trim().toLowerCase();o===""||o==="y"||o==="yes"?(vs(r,e),h(` Pinned. Everything under this repo (worktrees included) now signs as ${e}.`)):h(` Left unpinned \u2014 this login is saved, and \`gigabuddy use ${e}\` pins it later.`)}finally{n.close()}}function Gc(e){if(e<=0)return"";let t=Math.round(e/86400);if(t>=1)return` (valid ~${t} days)`;let r=Math.round(e/3600);return r>=1?` (valid ${r}h)`:` (valid ${Math.max(1,Math.round(e/60))}m)`}async function Sy(e,t){if(Mc()){await dP(e);return}let r=Jt(t).name,n=je(e.staging,Ne,r),o=!n;if(n||(h("Not signed in yet \u2014 signing in first."),h(),n=await zy(e,r),h(),h(" Signed in.")),!o){await _y(n);return}try{await _y(n)}catch(s){h(),h(` \u26A0 Signed in, but npm setup failed: ${s instanceof Error?s.message:String(s)}`),h(" You are signed in \u2014 retry just that half with: gigabuddy login --npm"),process.exitCode=1}}var lP=7*24*60*60*1e3;async function Py(e,t,r=Date.now()){if(Mc())return;let n=je(e.staging,Ne,Jt(t).name);if(!n)return;let o=py(Ey(e.staging,t));if(o&&!(o.expiresAt&&o.expiresAt.getTime()-r>lP))try{let s=await Ac({authUrl:n.authUrl,refreshToken:n.refreshToken}),i=is(s);h(`Renewed the npm credential for ${He}${Gc(s.expiresIn)} in ${i}`)}catch(s){h(`Could not renew the npm credential: ${s instanceof Error?s.message:String(s)}`),h("Run `gigabuddy login --npm` to renew it by hand."),process.exitCode=1}}async function _y(e){let t=await Ac({authUrl:e.authUrl,refreshToken:e.refreshToken}),r=is(t);h(),h(` npm is set up for ${He} packages${Gc(t.expiresIn)}`),h(` Registry: ${t.registryUrl}`),h(` Written to: ${r}`),h(),h(` Try it: npm install ${He}/app-kit`),h(),h(" This credential is registry-only \u2014 it installs what you can install and nothing else."),h(" Run this again when it expires, or after your access changes.");let n=Zc(process.cwd()).filter(o=>as(xy(o),t.registryUrl));n.length>0&&(h(),h(` \u26A0 ${n[0]} also configures this registry, and npm prefers it over ${r}.`),h(" Installs will keep using THAT credential, not this one. Delete its _authToken line."))}async function dP(e){h("GitHub Actions detected \u2014 using the job\u2019s OIDC identity (no sign-in, nothing stored).");let t=await my(),r=await hy({authUrl:e.authUrl,idToken:t}),n=is(r);h(),h(` npm is set up for ${He} packages as ${r.repository}\u2019s CI${Gc(r.expiresIn)}`),h(` Registry: ${r.registryUrl}`),h(` Written to: ${n}`),r.bindings.length>0&&h(` Sponsored by ${r.bindings.length} room(s): ${r.bindings.map(o=>o.placeId).join(", ")}`),h(),h(" This credential is registry-only and expires with the job. Run it again in any later job that installs.")}function Ey(e,t){let r=je(e,Ne,Jt(t).name),n=process.env.GIGABUDDY_NPM_REGISTRY_URL;return n||(r?.authUrl.includes("staging")?"https://npm.staging.gigabuddy.com":"https://npm.gigabuddy.com")}function Bc(e,t){let r=fy(Ey(e.staging,t));if(!r){h(`No ${He} registry entries found in ${$e()}`);return}h(`Removed ${He} registry credentials from ${r}`)}async function Ty(e,t){let r=Jt(t).name,n=je(e.staging,Ne,r);if(Bc(e,r),!n){h(`Not signed in${ls(r)}.`);return}let o=await dy({authUrl:n.authUrl,refreshToken:n.refreshToken});lu(e.staging,Ne,r),o?h(`Signed out${e.staging?" of staging":""}. Any npm credential from this session stops working shortly.`):(h(`Signed out locally${e.staging?" of staging":""} \u2014 but could not reach the server to revoke the session.`),h(" Credentials already copied elsewhere may keep working. Sign out again when you are back online,"),h(" or revoke the session from your account settings."))}async function Jc(e,t,r){if(e.userEmail)return e.userEmail;try{let n=await new Rt({refreshToken:e.refreshToken,authUrl:e.authUrl}).getToken(),o=Jn(n);return o?(ws({...e,userEmail:o},t,Ne,r),o):e.userId}catch{return e.userId}}async function Ry(e,t){let r=await gy({readNpmrc:()=>{try{return Hc($e(),"utf-8")}catch{return""}},npmEffectiveRegistry:()=>{try{let o=wy("npm",["config","get",`${He}:registry`],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim();return o&&o!=="undefined"&&o!=="null"?o:null}catch{return null}},shadowingNpmrcFiles:()=>Zc(process.cwd()).map(o=>({path:o,contents:xy(o)})),fetchImpl:fetch,nodeVersion:process.version,loadCredentials:o=>je(o,Ne),readClaudeConfig:()=>{try{return JSON.parse(Hc(nP(rP(),".claude.json"),"utf-8"))}catch{return null}},projectDir:process.cwd()},t),n=process.stderr.isTTY===!0&&!process.env.NO_COLOR;h(),h(yy(r,n)),h(),r.advice.length>0&&(process.exitCode=1)}var Rr="gigabuddy/agent-plugins",It="gigabuddy@gigabuddy",Kc="gigabuddy",Wc="@gigabuddy/agent",us=["install","-g",`${Wc}@latest`,"--@gigabuddy:registry=https://registry.npmjs.org/"],ds=["claude","codex"];function Fc(e,t,r){let n=Tr(e,t,{stdio:["ignore","inherit","inherit"],timeout:r});if(n.error&&n.error.code==="ENOENT")return"missing";if(n.error&&n.error.code==="ETIMEDOUT")return 1;if(n.error)throw n.error;return n.status??1}function Yc(e){return Tr(e,["--version"],{stdio:"ignore"}).status===0}var Vc;function cs(){if(Vc===void 0){let e=["codex"];process.platform==="darwin"&&e.push("/Applications/ChatGPT.app/Contents/Resources/codex","/Applications/Codex.app/Contents/Resources/codex"),Vc=e.find(Yc)??null}return Vc}var vy="0.148.0";function pP(e,t){let r=s=>(s.match(/\d+(\.\d+)*/)?.[0]??"0").split(".").map(Number),n=r(e),o=r(t);for(let s=0;s<Math.max(n.length,o.length);s++){let i=(n[s]??0)-(o[s]??0);if(i!==0)return i>0}return!0}function fP(e){let t=Tr(e,["--version"],{encoding:"utf-8"});return t.status===0?/\d+\.\d+\.\d+/.exec(t.stdout)?.[0]??null:null}var Bn={has:e=>e==="claude"?Yc("claude"):cs()!==null,runClaude:e=>Fc("claude",e),runCodex(e){let t=cs();return t?Fc(t,e):"missing"},codexVersion(){let e=cs();return e?fP(e):null},installAgent(){return Tr("npm",us,{stdio:["ignore","inherit","inherit"]}).status??1},warmAgent:()=>Fc("gigabuddy-agent",["warm"],3e4)};function Iy(e,t=Bn){let r=e?[e]:ds.filter(n=>t.has(n));if(r.length===0){h("Could not find Claude Code or Codex on this machine."),h(),h(" In Claude Code, run these inside any session:"),h(),h(` /plugin marketplace add ${Rr}`),h(` /plugin install ${It}`),h(),h(" For Codex, install it and run `gigabuddy setup codex`."),process.exitCode=1;return}r.forEach((n,o)=>{o>0&&h(),n==="claude"?mP(t):hP(t)})}function mP(e){h("Setting up Gigabuddy for Claude Code\u2026"),h();let t=e.runClaude(["plugin","marketplace","add",Rr]);if(t==="missing"){h(" Could not find the `claude` command on this machine."),h(" If Claude Code is installed, run these inside any Claude Code session instead:"),h(),h(` /plugin marketplace add ${Rr}`),h(` /plugin install ${It}`),h(),h(" Then restart Claude Code."),process.exitCode=1;return}if(t!==0){h(),h(" \u26A0 Adding the Gigabuddy marketplace failed (see above). Nothing else was changed."),process.exitCode=1;return}if(e.runClaude(["plugin","install",It])!==0){h(),h(" \u26A0 Installing the plugin failed (see above). The marketplace was added \u2014 retry with:"),h(),h(` claude plugin install ${It}`),process.exitCode=1;return}h(),h(` Installing the agent (${Wc})\u2026`),e.installAgent()!==0&&(h(),h(" \u26A0 Installing the agent failed (see above). The plugin still works, but downloads the"),h(" agent each time it starts. Retry with:"),h(),h(` npm ${us.slice(0,3).join(" ")}`)),h(),h(" Gigabuddy is installed in Claude Code. Next:"),h(),h(" 1. Restart Claude Code so the plugin loads."),h(" 2. Ask your session to sign you in and connect you to a room."),h(' (Several identities on this machine? Say which: "sign in as my work account".)')}function hP(e){h("Setting up Gigabuddy for Codex\u2026"),h();let t=e.codexVersion();if(t&&!pP(t,vy)){h(` Gigabuddy needs Codex ${vy} or newer; this machine has ${t}.`),h(" Update Codex first (the desktop app updates itself; for the CLI run"),h(" `npm install -g @openai/codex@latest`), then run `gigabuddy setup codex` again."),process.exitCode=1;return}let r=e.runCodex(["plugin","marketplace","add",Rr]);if(r==="missing"){h(" Could not find the `codex` command on this machine. Once Codex is installed, run:"),h(),h(` codex plugin marketplace add ${Rr}`),h(` codex plugin add ${It}`),h(` npm ${us.slice(0,3).join(" ")}`),process.exitCode=1;return}if(r!==0){h(),h(" \u26A0 Adding the Gigabuddy marketplace failed (see above). Nothing else was changed."),process.exitCode=1;return}if(e.runCodex(["plugin","marketplace","upgrade",Kc]),e.runCodex(["plugin","add",It])!==0){h(),h(" \u26A0 Installing the plugin failed (see above). The marketplace was added \u2014 retry with:"),h(),h(` codex plugin add ${It}`),process.exitCode=1;return}h(),h(` Installing the agent (${Wc})\u2026`),e.installAgent()!==0?(h(),h(" \u26A0 Installing the agent failed (see above). The plugin works without it, but starts"),h(" too slowly for Codex some of the time. Retry with:"),h(),h(` npm ${us.slice(0,3).join(" ")}`),process.exitCode=1):e.warmAgent()!==0&&(h(" Your room's tools will be listed from your second Codex session. Once the above is"),h(" fixed, `gigabuddy setup codex` again gets them into the first.")),h(),h(" Gigabuddy is installed in Codex. Next:"),h(),h(" 1. Restart Codex so the plugin loads."),h(" 2. In a new thread, ask Codex to connect you to your Gigabuddy room.")}function Qc(e){switch(e.source){case"env":return"from GIGABUDDY_ACCOUNT";case"pin":return`pinned at ${e.pinnedAt}`;case"config-default":return"your default account";case"fallback":return""}}var gP={latestVersion(){try{return wy("npm",["view","gigabuddy","version"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||null}catch{return null}},installLatest(){return Tr("npm",["install","-g","gigabuddy@latest"],{stdio:["ignore","inherit","inherit"]}).status??1},refreshPlugin(){return Bn.runClaude(["plugin","marketplace","add",Rr])},refreshCodexPlugin(){let e=cs();if(!e)return"missing";let t=Tr(e,["plugin","marketplace","list"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]});if(!new RegExp(`^${Kc}\\s`,"m").test(t.stdout??""))return"missing";let r=Bn.runCodex(["plugin","marketplace","upgrade",Kc]);return r===0?Bn.runCodex(["plugin","add",It]):r},updateAgent(){return Yc("gigabuddy-agent")?Bn.installAgent():"not-installed"}};async function Cy(e,t=gP){let r=t.latestVersion();if(!r){h("Could not reach npm to check for a newer version \u2014 are you online?"),process.exitCode=1;return}if(r===e)h(`gigabuddy v${e} is already the latest.`);else{if(h(`Updating gigabuddy v${e} \u2192 v${r}\u2026`),t.installLatest()!==0){h(),h(" \u26A0 npm install failed (see above). Try: npm install -g gigabuddy@latest"),process.exitCode=1;return}h(` Updated to v${r}.`)}t.refreshPlugin()===0&&h(" Claude Code plugin refreshed (restart Claude Code to pick up a new version)."),t.refreshCodexPlugin()===0&&h(" Codex plugin refreshed (restart Codex to pick up a new version).");let o=t.updateAgent();o===0?h(" Agent (@gigabuddy/agent) updated."):o!=="not-installed"&&(h(" \u26A0 Updating the agent failed (see above). Try: npm install -g @gigabuddy/agent@latest"),process.exitCode=1)}async function Oy(e){let t=Jt(e),r=je(!1,Ne,t.name),n=je(!0,Ne,t.name),o=Yn().length>1||t.name!==Ct;if(o){let s=Qc(t);h(`Account: ${t.name}${s?` (${s})`:""}`),h()}if(!r&&!n){h(`Not signed in${o?ls(t.name):""}.`),h(),h(" gigabuddy login");return}for(let[s,i,a]of[["Production",r,!1],["Staging",n,!0]])i&&(h(`${s}:`),h(` Account: ${await Jc(i,a,t.name)}`),h(` Since: ${i.createdAt}`))}async function Ny(){let e=Xe(),t=Gt(),r=Yn();r.includes(e.name)||r.push(e.name),h("Accounts:");for(let o of r){let s=je(!1,Ne,o),i=je(!0,Ne,o),a=s?await Jc(s,!1,o):i?`${await Jc(i,!0,o)} (staging only)`:"not signed in",c=[];o===e.name&&c.push("active here"),o===(t.defaultAccount??Ct)&&c.push("default"),h(` ${o===e.name?"*":" "} ${o} \u2014 ${a}${c.length?` [${c.join(", ")}]`:""}`)}let n=Qc(e);n&&(h(),h(` Active account here: ${e.name} \u2014 ${n}`)),h(),h(" gigabuddy login --account <name> sign an account in"),h(" gigabuddy use <name> use an account for this repo"),h(" gigabuddy use --default <name> make an account the machine default")}function Ay(e,t={},r=process.cwd()){let n=Ar(r);if(t.unpin){h(cu(n)?`Unpinned ${n}.`:`No pin on ${n}.`);return}if(!e){let o=Xe(r),s=Qc(o);h(`Active account here: ${o.name}${s?` (${s})`:""}`),h(),h(" gigabuddy use <name> pin this repo to an account"),h(" gigabuddy use --unpin remove this repo's pin");return}if(Kt(e),Yn().includes(e)||h(`Note: no account "${e}" exists yet \u2014 sign it in with: gigabuddy login --account ${e}`),t.default){au(e),h(`Default account is now ${e}.`);return}vs(n,e),h(`Pinned ${n} \u2192 ${e}.`),h("Everything under it (worktrees included) now signs as this account.")}import{existsSync as Xc,mkdirSync as yP,readFileSync as eu,writeFileSync as jy}from"node:fs";import{join as Wn}from"node:path";var tu=".gigabuddy",_P="channel-policy.json",vP="default-place.json";function ps(e){return Wn(e,tu,_P)}function Zy(e){let t=ps(e);if(!Xc(t))return{};try{let r=JSON.parse(eu(t,"utf-8"));return r&&typeof r=="object"&&!Array.isArray(r)?r:{}}catch(r){throw new Error(`${t} is not valid JSON (${r instanceof Error?r.message:String(r)}) \u2014 fix or remove it first.`)}}function Dy(e,t){let r=Wn(e,tu);yP(r,{recursive:!0}),Xc(Wn(r,".gitignore"))||jy(Wn(r,".gitignore"),`*
|
|
86
|
+
`)}var oP=["agent:spawn","discovery:read","packages:read"],Ne="user",sP="https://auth.gigabuddy.com",iP="https://api.gigabuddy.com",aP="https://auth.staging.gigabuddy.com",cP="https://api.staging.gigabuddy.com";function $y(e){let t=e.staging??!1;return{staging:t,authUrl:e.authUrl??(t?aP:sP),apiUrl:e.apiUrl??(t?cP:iP)}}function xy(e){try{return Hc(e,"utf-8")}catch{return""}}function h(e=""){console.error(e)}function Jt(e){return e?(Kt(e),{name:e,source:"env"}):Xe()}function ls(e){return e===Ct?"":` (account: ${e})`}async function zy(e,t){let r=Jt(t).name;h(`Signing in to ${e.staging?"Gigabuddy Staging":"Gigabuddy"}${ls(r)}\u2026`);let n=await sy({authUrl:e.authUrl,apiUrl:e.apiUrl,clientId:"gigabuddy-cli",scopes:oP,onPrompt:({verificationUrl:s,userCode:i})=>{h(),h(` Open: ${s}`),h(` Code: ${i}`),h()},onPending:()=>process.stderr.write(".")}),o={refreshToken:n.refreshToken,userId:n.userId,userEmail:n.userEmail,authUrl:e.authUrl,apiUrl:e.apiUrl,createdAt:new Date().toISOString()};return ws(o,e.staging,Ne,r),o}async function ky(e,t={}){let r=Jt(t.account).name,n=await zy(e,r);h(),h(" Signed in."),n.userEmail&&h(` Account: ${n.userEmail}${ls(r)}`),h(` Saved to: ${jr(e.staging,Ne,r)}`),t.account&&await uP(t.account),h(),h(` To install ${He} packages from the Gigabuddy registry: gigabuddy login --npm`)}async function uP(e){let t=Xe();if(t.name===e)return;let r=Ar(process.cwd());if(process.stdin.isTTY!==!0||process.stderr.isTTY!==!0){h(),h(` This directory resolves account "${t.name}". To use ${e} here: gigabuddy use ${e}`);return}h();let n=by.createInterface({input:process.stdin,output:process.stderr});try{let o=(await n.question(` Always use "${e}" in ${r}? [Y/n] `)).trim().toLowerCase();o===""||o==="y"||o==="yes"?(vs(r,e),h(` Pinned. Everything under this repo (worktrees included) now signs as ${e}.`)):h(` Left unpinned \u2014 this login is saved, and \`gigabuddy use ${e}\` pins it later.`)}finally{n.close()}}function Gc(e){if(e<=0)return"";let t=Math.round(e/86400);if(t>=1)return` (valid ~${t} days)`;let r=Math.round(e/3600);return r>=1?` (valid ${r}h)`:` (valid ${Math.max(1,Math.round(e/60))}m)`}async function Sy(e,t){if(Mc()){await dP(e);return}let r=Jt(t).name,n=je(e.staging,Ne,r),o=!n;if(n||(h("Not signed in yet \u2014 signing in first."),h(),n=await zy(e,r),h(),h(" Signed in.")),!o){await _y(n);return}try{await _y(n)}catch(s){h(),h(` \u26A0 Signed in, but npm setup failed: ${s instanceof Error?s.message:String(s)}`),h(" You are signed in \u2014 retry just that half with: gigabuddy login --npm"),process.exitCode=1}}var lP=7*24*60*60*1e3;async function Py(e,t,r=Date.now()){if(Mc())return;let n=je(e.staging,Ne,Jt(t).name);if(!n)return;let o=py(Ey(e.staging,t));if(o&&!(o.expiresAt&&o.expiresAt.getTime()-r>lP))try{let s=await Ac({authUrl:n.authUrl,refreshToken:n.refreshToken}),i=is(s);h(`Renewed the npm credential for ${He}${Gc(s.expiresIn)} in ${i}`)}catch(s){h(`Could not renew the npm credential: ${s instanceof Error?s.message:String(s)}`),h("Run `gigabuddy login --npm` to renew it by hand."),process.exitCode=1}}async function _y(e){let t=await Ac({authUrl:e.authUrl,refreshToken:e.refreshToken}),r=is(t);h(),h(` npm is set up for ${He} packages${Gc(t.expiresIn)}`),h(` Registry: ${t.registryUrl}`),h(` Written to: ${r}`),h(),h(` Try it: npm install ${He}/app-kit`),h(),h(" This credential is registry-only \u2014 it installs what you can install and nothing else."),h(" Run this again when it expires, or after your access changes.");let n=Zc(process.cwd()).filter(o=>as(xy(o),t.registryUrl));n.length>0&&(h(),h(` \u26A0 ${n[0]} also configures this registry, and npm prefers it over ${r}.`),h(" Installs will keep using THAT credential, not this one. Delete its _authToken line."))}async function dP(e){h("GitHub Actions detected \u2014 using the job\u2019s OIDC identity (no sign-in, nothing stored).");let t=await my(),r=await hy({authUrl:e.authUrl,idToken:t}),n=is(r);h(),h(` npm is set up for ${He} packages as ${r.repository}\u2019s CI${Gc(r.expiresIn)}`),h(` Registry: ${r.registryUrl}`),h(` Written to: ${n}`),r.bindings.length>0&&h(` Sponsored by ${r.bindings.length} room(s): ${r.bindings.map(o=>o.placeId).join(", ")}`),h(),h(" This credential is registry-only and expires with the job. Run it again in any later job that installs.")}function Ey(e,t){let r=je(e,Ne,Jt(t).name),n=process.env.GIGABUDDY_NPM_REGISTRY_URL;return n||(r?.authUrl.includes("staging")?"https://npm.staging.gigabuddy.com":"https://npm.gigabuddy.com")}function Bc(e,t){let r=fy(Ey(e.staging,t));if(!r){h(`No ${He} registry entries found in ${$e()}`);return}h(`Removed ${He} registry credentials from ${r}`)}async function Ty(e,t){let r=Jt(t).name,n=je(e.staging,Ne,r);if(Bc(e,r),!n){h(`Not signed in${ls(r)}.`);return}let o=await dy({authUrl:n.authUrl,refreshToken:n.refreshToken});lu(e.staging,Ne,r),o?h(`Signed out${e.staging?" of staging":""}. Any npm credential from this session stops working shortly.`):(h(`Signed out locally${e.staging?" of staging":""} \u2014 but could not reach the server to revoke the session.`),h(" Credentials already copied elsewhere may keep working. Sign out again when you are back online,"),h(" or revoke the session from your account settings."))}async function Jc(e,t,r){if(e.userEmail)return e.userEmail;try{let n=await new Rt({refreshToken:e.refreshToken,authUrl:e.authUrl}).getToken(),o=Jn(n);return o?(ws({...e,userEmail:o},t,Ne,r),o):e.userId}catch{return e.userId}}async function Ry(e,t){let r=await gy({readNpmrc:()=>{try{return Hc($e(),"utf-8")}catch{return""}},npmEffectiveRegistry:()=>{try{let o=wy("npm",["config","get",`${He}:registry`],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim();return o&&o!=="undefined"&&o!=="null"?o:null}catch{return null}},shadowingNpmrcFiles:()=>Zc(process.cwd()).map(o=>({path:o,contents:xy(o)})),fetchImpl:fetch,nodeVersion:process.version,loadCredentials:o=>je(o,Ne),readClaudeConfig:()=>{try{return JSON.parse(Hc(nP(rP(),".claude.json"),"utf-8"))}catch{return null}},projectDir:process.cwd()},t),n=process.stderr.isTTY===!0&&!process.env.NO_COLOR;h(),h(yy(r,n)),h(),r.advice.length>0&&(process.exitCode=1)}var Rr="gigabuddy/agent-plugins",It="gigabuddy@gigabuddy",Kc="gigabuddy",Wc="@gigabuddy/agent",us=["install","-g",`${Wc}@latest`,"--@gigabuddy:registry=https://registry.npmjs.org/"],ds=["claude","codex"];function Fc(e,t,r){let n=Tr(e,t,{stdio:["ignore","inherit","inherit"],timeout:r});if(n.error&&n.error.code==="ENOENT")return"missing";if(n.error&&n.error.code==="ETIMEDOUT")return 1;if(n.error)throw n.error;return n.status??1}function Yc(e){return Tr(e,["--version"],{stdio:"ignore"}).status===0}var Vc;function cs(){if(Vc===void 0){let e=["codex"];process.platform==="darwin"&&e.push("/Applications/ChatGPT.app/Contents/Resources/codex-cli/CodexCLI.app/Contents/MacOS/codex","/Applications/ChatGPT.app/Contents/Resources/codex","/Applications/Codex.app/Contents/Resources/codex"),Vc=e.find(Yc)??null}return Vc}var vy="0.148.0";function pP(e,t){let r=s=>(s.match(/\d+(\.\d+)*/)?.[0]??"0").split(".").map(Number),n=r(e),o=r(t);for(let s=0;s<Math.max(n.length,o.length);s++){let i=(n[s]??0)-(o[s]??0);if(i!==0)return i>0}return!0}function fP(e){let t=Tr(e,["--version"],{encoding:"utf-8"});return t.status===0?/\d+\.\d+\.\d+/.exec(t.stdout)?.[0]??null:null}var Bn={has:e=>e==="claude"?Yc("claude"):cs()!==null,runClaude:e=>Fc("claude",e),runCodex(e){let t=cs();return t?Fc(t,e):"missing"},codexVersion(){let e=cs();return e?fP(e):null},installAgent(){return Tr("npm",us,{stdio:["ignore","inherit","inherit"]}).status??1},warmAgent:()=>Fc("gigabuddy-agent",["warm"],3e4)};function Iy(e,t=Bn){let r=e?[e]:ds.filter(n=>t.has(n));if(r.length===0){h("Could not find Claude Code or Codex on this machine."),h(),h(" In Claude Code, run these inside any session:"),h(),h(` /plugin marketplace add ${Rr}`),h(` /plugin install ${It}`),h(),h(" For Codex, install it and run `gigabuddy setup codex`."),process.exitCode=1;return}r.forEach((n,o)=>{o>0&&h(),n==="claude"?mP(t):hP(t)})}function mP(e){h("Setting up Gigabuddy for Claude Code\u2026"),h();let t=e.runClaude(["plugin","marketplace","add",Rr]);if(t==="missing"){h(" Could not find the `claude` command on this machine."),h(" If Claude Code is installed, run these inside any Claude Code session instead:"),h(),h(` /plugin marketplace add ${Rr}`),h(` /plugin install ${It}`),h(),h(" Then restart Claude Code."),process.exitCode=1;return}if(t!==0){h(),h(" \u26A0 Adding the Gigabuddy marketplace failed (see above). Nothing else was changed."),process.exitCode=1;return}if(e.runClaude(["plugin","install",It])!==0){h(),h(" \u26A0 Installing the plugin failed (see above). The marketplace was added \u2014 retry with:"),h(),h(` claude plugin install ${It}`),process.exitCode=1;return}h(),h(` Installing the agent (${Wc})\u2026`),e.installAgent()!==0&&(h(),h(" \u26A0 Installing the agent failed (see above). The plugin still works, but downloads the"),h(" agent each time it starts. Retry with:"),h(),h(` npm ${us.slice(0,3).join(" ")}`)),h(),h(" Gigabuddy is installed in Claude Code. Next:"),h(),h(" 1. Restart Claude Code so the plugin loads."),h(" 2. Ask your session to sign you in and connect you to a room."),h(' (Several identities on this machine? Say which: "sign in as my work account".)')}function hP(e){h("Setting up Gigabuddy for Codex\u2026"),h();let t=e.codexVersion();if(t&&!pP(t,vy)){h(` Gigabuddy needs Codex ${vy} or newer; this machine has ${t}.`),h(" Update Codex first (the desktop app updates itself; for the CLI run"),h(" `npm install -g @openai/codex@latest`), then run `gigabuddy setup codex` again."),process.exitCode=1;return}let r=e.runCodex(["plugin","marketplace","add",Rr]);if(r==="missing"){h(" Could not find the `codex` command on this machine. Once Codex is installed, run:"),h(),h(` codex plugin marketplace add ${Rr}`),h(` codex plugin add ${It}`),h(` npm ${us.slice(0,3).join(" ")}`),process.exitCode=1;return}if(r!==0){h(),h(" \u26A0 Adding the Gigabuddy marketplace failed (see above). Nothing else was changed."),process.exitCode=1;return}if(e.runCodex(["plugin","marketplace","upgrade",Kc]),e.runCodex(["plugin","add",It])!==0){h(),h(" \u26A0 Installing the plugin failed (see above). The marketplace was added \u2014 retry with:"),h(),h(` codex plugin add ${It}`),process.exitCode=1;return}h(),h(` Installing the agent (${Wc})\u2026`),e.installAgent()!==0?(h(),h(" \u26A0 Installing the agent failed (see above). The plugin works without it, but starts"),h(" too slowly for Codex some of the time. Retry with:"),h(),h(` npm ${us.slice(0,3).join(" ")}`),process.exitCode=1):e.warmAgent()!==0&&(h(" Your room's tools will be listed from your second Codex session. Once the above is"),h(" fixed, `gigabuddy setup codex` again gets them into the first.")),h(),h(" Gigabuddy is installed in Codex. Next:"),h(),h(" 1. Restart Codex so the plugin loads."),h(" 2. In a new thread, ask Codex to connect you to your Gigabuddy room.")}function Qc(e){switch(e.source){case"env":return"from GIGABUDDY_ACCOUNT";case"pin":return`pinned at ${e.pinnedAt}`;case"config-default":return"your default account";case"fallback":return""}}var gP={latestVersion(){try{return wy("npm",["view","gigabuddy","version"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||null}catch{return null}},installLatest(){return Tr("npm",["install","-g","gigabuddy@latest"],{stdio:["ignore","inherit","inherit"]}).status??1},refreshPlugin(){return Bn.runClaude(["plugin","marketplace","add",Rr])},refreshCodexPlugin(){let e=cs();if(!e)return"missing";let t=Tr(e,["plugin","marketplace","list"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]});if(!new RegExp(`^${Kc}\\s`,"m").test(t.stdout??""))return"missing";let r=Bn.runCodex(["plugin","marketplace","upgrade",Kc]);return r===0?Bn.runCodex(["plugin","add",It]):r},updateAgent(){return Yc("gigabuddy-agent")?Bn.installAgent():"not-installed"}};async function Cy(e,t=gP){let r=t.latestVersion();if(!r){h("Could not reach npm to check for a newer version \u2014 are you online?"),process.exitCode=1;return}if(r===e)h(`gigabuddy v${e} is already the latest.`);else{if(h(`Updating gigabuddy v${e} \u2192 v${r}\u2026`),t.installLatest()!==0){h(),h(" \u26A0 npm install failed (see above). Try: npm install -g gigabuddy@latest"),process.exitCode=1;return}h(` Updated to v${r}.`)}t.refreshPlugin()===0&&h(" Claude Code plugin refreshed (restart Claude Code to pick up a new version)."),t.refreshCodexPlugin()===0&&h(" Codex plugin refreshed (restart Codex to pick up a new version).");let o=t.updateAgent();o===0?h(" Agent (@gigabuddy/agent) updated."):o!=="not-installed"&&(h(" \u26A0 Updating the agent failed (see above). Try: npm install -g @gigabuddy/agent@latest"),process.exitCode=1)}async function Oy(e){let t=Jt(e),r=je(!1,Ne,t.name),n=je(!0,Ne,t.name),o=Yn().length>1||t.name!==Ct;if(o){let s=Qc(t);h(`Account: ${t.name}${s?` (${s})`:""}`),h()}if(!r&&!n){h(`Not signed in${o?ls(t.name):""}.`),h(),h(" gigabuddy login");return}for(let[s,i,a]of[["Production",r,!1],["Staging",n,!0]])i&&(h(`${s}:`),h(` Account: ${await Jc(i,a,t.name)}`),h(` Since: ${i.createdAt}`))}async function Ny(){let e=Xe(),t=Gt(),r=Yn();r.includes(e.name)||r.push(e.name),h("Accounts:");for(let o of r){let s=je(!1,Ne,o),i=je(!0,Ne,o),a=s?await Jc(s,!1,o):i?`${await Jc(i,!0,o)} (staging only)`:"not signed in",c=[];o===e.name&&c.push("active here"),o===(t.defaultAccount??Ct)&&c.push("default"),h(` ${o===e.name?"*":" "} ${o} \u2014 ${a}${c.length?` [${c.join(", ")}]`:""}`)}let n=Qc(e);n&&(h(),h(` Active account here: ${e.name} \u2014 ${n}`)),h(),h(" gigabuddy login --account <name> sign an account in"),h(" gigabuddy use <name> use an account for this repo"),h(" gigabuddy use --default <name> make an account the machine default")}function Ay(e,t={},r=process.cwd()){let n=Ar(r);if(t.unpin){h(cu(n)?`Unpinned ${n}.`:`No pin on ${n}.`);return}if(!e){let o=Xe(r),s=Qc(o);h(`Active account here: ${o.name}${s?` (${s})`:""}`),h(),h(" gigabuddy use <name> pin this repo to an account"),h(" gigabuddy use --unpin remove this repo's pin");return}if(Kt(e),Yn().includes(e)||h(`Note: no account "${e}" exists yet \u2014 sign it in with: gigabuddy login --account ${e}`),t.default){au(e),h(`Default account is now ${e}.`);return}vs(n,e),h(`Pinned ${n} \u2192 ${e}.`),h("Everything under it (worktrees included) now signs as this account.")}import{existsSync as Xc,mkdirSync as yP,readFileSync as eu,writeFileSync as jy}from"node:fs";import{join as Wn}from"node:path";var tu=".gigabuddy",_P="channel-policy.json",vP="default-place.json";function ps(e){return Wn(e,tu,_P)}function Zy(e){let t=ps(e);if(!Xc(t))return{};try{let r=JSON.parse(eu(t,"utf-8"));return r&&typeof r=="object"&&!Array.isArray(r)?r:{}}catch(r){throw new Error(`${t} is not valid JSON (${r instanceof Error?r.message:String(r)}) \u2014 fix or remove it first.`)}}function Dy(e,t){let r=Wn(e,tu);yP(r,{recursive:!0}),Xc(Wn(r,".gitignore"))||jy(Wn(r,".gitignore"),`*
|
|
87
87
|
`),jy(ps(e),JSON.stringify(t,null,2)+`
|
|
88
88
|
`)}function My(e){return(e.trustedSenders??[]).map(t=>typeof t=="string"?{id:t}:t).filter(t=>!!t?.id)}function wP(e){try{let t=JSON.parse(eu(Wn(e,tu,vP),"utf-8"));return typeof t.placeId=="string"&&t.placeId?{placeId:t.placeId,placeName:t.placeName}:null}catch{return null}}async function bP(e,t){let n=((await t.fetchJson(`${e}/api/installations/mine`)).installations??[]).map(i=>i.installationId).filter(Boolean),o=[],s=[];for(let i of n){let a;try{a=await t.fetchJson(`${e}/ext/places/boot?tenancyId=${encodeURIComponent(i)}`)}catch(c){s.push(`${i}: ${c instanceof Error?c.message:String(c)}`);continue}for(let c of a.places??[])o.push({id:c.id,name:c.name??c.id,members:c.members??[]})}if(o.length===0&&s.length>0)throw new Error(`Could not read any room roster:
|
|
89
89
|
${s.map(i=>` ${i}`).join(`
|