xtra-cli 1.0.5 → 1.0.7

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/dist/bin/xtra.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- var ge=Object.create;var C=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var fe=Object.getPrototypeOf,ye=Object.prototype.hasOwnProperty;var x=(e,t)=>()=>(e&&(t=e(e=0)),t);var k=(e,t)=>{for(var s in t)C(e,s,{get:t[s],enumerable:!0})},N=(e,t,s,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ue(t))!ye.call(e,n)&&n!==s&&C(e,n,{get:()=>t[n],enumerable:!(r=le(t,n))||r.enumerable});return e};var c=(e,t,s)=>(s=e!=null?ge(fe(e)):{},N(t||!e||!e.__esModule?C(s,"default",{value:e,enumerable:!0}):s,e)),S=e=>N(C({},"__esModule",{value:!0}),e);var M={};k(M,{createProfile:()=>xe,deleteProfile:()=>we,getActiveProfile:()=>B,getActiveProfileName:()=>I,getProfileValue:()=>Ce,listProfiles:()=>m,setActiveProfile:()=>he,setProfileValue:()=>ve,useProfile:()=>Se});function m(){return d.get("profiles")||{}}function I(){return process.env.XTRA_PROFILE||d.get("activeProfile")||"default"}function B(){let e=I();return m()[e]||{}}function he(e){if(!m()[e])throw new Error(`Profile '${e}' does not exist. Create it first with 'xtra profile create ${e}'.`);d.set("activeProfile",e)}function xe(e,t={}){let s=m();if(s[e])throw new Error(`Profile '${e}' already exists. Use 'xtra profile set' to edit it.`);s[e]={apiUrl:process.env.XTRA_API_URL||"https://www.xtrasecurity.in/api",...t},d.set("profiles",s)}function we(e){if(e==="default")throw new Error("Cannot delete the 'default' profile.");let t=m();if(!t[e])throw new Error(`Profile '${e}' not found.`);delete t[e],d.set("profiles",t),I()===e&&d.set("activeProfile","default")}function ve(e,t,s){let r=m();if(!r[e])throw new Error(`Profile '${e}' not found.`);r[e][t]=s,d.set("profiles",r)}function Ce(e){return B()[e]}function Se(e){if(!m()[e])throw new Error(`Profile '${e}' does not exist. Run 'xtra profile create ${e}' first.`);process.env.XTRA_PROFILE=e}var O,d,J=x(()=>{O=c(require("conf")),d=new O.default({projectName:"xtra-cli",defaults:{activeProfile:"default",profiles:{default:{apiUrl:process.env.XTRA_API_URL||"https://www.xtrasecurity.in/api"}}}})});var L={};k(L,{clearConfig:()=>ke,deleteConfig:()=>Ie,getAuthToken:()=>P,getBreakGlassSession:()=>$e,getConfig:()=>l,getConfigValue:()=>be,getProjectConfig:()=>Pe,getRcConfig:()=>Re,setBreakGlassSession:()=>Ae,setConfig:()=>je});var q,g,R,A,i,$,l,be,je,ke,Ie,P,$e,Ae,Pe,Re,w=x(()=>{q=c(require("conf")),g=c(require("fs")),R=c(require("path")),A="https://www.xtrasecurity.in/api",i=new q.default({projectName:"xtra-cli",defaults:{apiUrl:A}}),$=i.get("apiUrl");$&&!process.env.XTRA_API_URL&&($.includes("localhost")||$.includes("xtra-security.vercel.app"))&&i.set("apiUrl",A);l=()=>({...i.store,apiUrl:process.env.XTRA_API_URL||i.get("apiUrl")||A}),be=e=>i.get(e),je=(e,t)=>{if(i.set(e,t),e==="token"&&process.platform!=="win32"&&g.default.existsSync(i.path))try{g.default.chmodSync(i.path,384)}catch{}},ke=()=>i.clear(),Ie=e=>i.delete(e),P=()=>i.get("token"),$e=()=>i.get("breakGlassSessionId"),Ae=e=>{e?i.set("breakGlassSessionId",e):i.delete("breakGlassSessionId")},Pe=async()=>{try{let e=R.default.join(process.cwd(),"xtra.json");if(g.default.existsSync(e)){let t=g.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},Re=()=>{let e={};try{let t=R.default.join(process.cwd(),".xtrarc");g.default.existsSync(t)&&(e=JSON.parse(g.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||i.get("project")||"",env:e.env||i.get("env")||"development",branch:e.branch||i.get("branch")||"main"}}});function K(){let e=G.get("masterKey");e||(e=u.default.randomBytes(32).toString("hex"),G.set("masterKey",e));let t=(0,V.machineIdSync)();return u.default.createHash("sha256").update(e+t).digest()}var u,F,V,X,G,z,H,W=x(()=>{u=c(require("crypto")),F=c(require("conf")),V=require("node-machine-id"),X="aes-256-gcm",G=new F.default({projectName:"xtra-cli-crypto"});z=e=>{let t=u.default.randomBytes(16),s=K(),r=u.default.createCipheriv(X,s,t),n=r.update(e,"utf8","hex");n+=r.final("hex");let a=r.getAuthTag();return{iv:t.toString("hex"),content:n,tag:a.toString("hex")}},H=e=>{let t=K(),s=Buffer.from(e.iv,"hex"),r=Buffer.from(e.tag,"hex"),n=u.default.createDecipheriv(X,t,s);n.setAuthTag(r);let a=n.update(e.content,"hex","utf8");return a+=n.final("utf8"),a}});var Y,Q,Z,Le,o,ee,te=x(()=>{Y=c(require("axios"));w();Q=c(require("fs")),Z=c(require("path")),Le=JSON.parse(Q.readFileSync(Z.join(__dirname,"../../package.json"),"utf-8")),o=()=>{let{apiUrl:e}=l(),t=P();return Y.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":Le.version,...t?{Authorization:`Bearer ${t}`}:{}}})},ee={login:async(e,t,s)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,r,n="main")=>(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:r,branch:n})).data,getSecretDetails:async(e,t,s,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${r}`)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,r,n,a)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:r,sourceEnv:n,sourceKey:a})).data,rotateSecret:async(e,t,s,r,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:r,parsedNewValue:n})).data,promoteSecret:async(e,t,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,r)=>{let n={format:e};return t&&(n.startDate=t),s&&(n.endDate=s),r&&(n.projectId=r),(await o().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,r)=>(await o().post("/access/request",{projectId:e,secretId:r,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=l(),s=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=l(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await o().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:r})).data,cloneEnvironment:async(e,t,s,r,n)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:r,branch:n})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,post:async(e,t)=>(await o().post(e,t)).data}});var ne={};k(ne,{loadAuditLogs:()=>b,logAudit:()=>Te,saveAuditLogs:()=>j,syncAuditLogs:()=>_e});function Ue(e){if(!e||typeof e!="object")return e;let t={...e},s=["password","token","secret","value","apiKey","secretValue"];for(let r of Object.keys(t))s.some(n=>r.toLowerCase().includes(n))&&(t[r]="[REDACTED]");return t}async function re(e){try{if(!l().token)return!1;let s={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:Ue(e.details),timestamp:e.timestamp,projectId:e.projectId};return await ee.post("/audit/cli-logs",{logs:[s]}),!0}catch(t){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",t),!1}}function Te(e,t,s,r){let n={id:(0,se.v4)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:s,details:r,synced:!1},a=b();a.push(n),j(a),re(n).then(v=>{if(v){n.synced=!0;let h=b(),E=h.findIndex(me=>me.id===n.id);E!==-1&&(h[E].synced=!0,j(h))}}).catch(()=>{})}function b(){if(!f.default.existsSync(T))return[];try{let e=f.default.readFileSync(T,"utf-8"),t=JSON.parse(e),s=H(t);return JSON.parse(s)}catch{return[]}}function j(e){f.default.existsSync(U)||f.default.mkdirSync(U,{recursive:!0});let t=JSON.stringify(e),s=z(t);f.default.writeFileSync(T,JSON.stringify(s),"utf-8")}async function _e(){let e=b(),t=e.filter(r=>!r.synced);if(t.length===0)return 0;let s=0;for(let r of t)await re(r)&&(r.synced=!0,s++);return s>0&&j(e),s}var f,_,se,U,T,oe=x(()=>{f=c(require("fs")),_=c(require("path")),se=require("uuid");W();w();te();U=_.default.join(process.cwd(),".xtra"),T=_.default.join(U,"audit.enc")});var ie=require("commander"),ae=c(require("fs")),ce=c(require("path")),pe=c(require("update-notifier")),p=new ie.Command,de=JSON.parse(ae.readFileSync(ce.join(__dirname,"../../package.json"),"utf-8"));(0,pe.default)({pkg:de}).notify();p.name("xtra").description("XtraSync CLI - Secure Runtime Secret Injection").version(de.version).option("--profile <name>","Use a specific named profile for this command");var D={login:{module:"../commands/login",export:"loginCommand",desc:"Authenticate with XtraSecurity"},logout:{module:"../commands/logout",export:"logoutCommand",desc:"Logout and clear local token"},run:{module:"../commands/run",export:"runCommand",desc:"Run a command with injected secrets"},"jit-run":{module:"../commands/jit-run",export:"jitRunCommand",desc:"Run with temporary JIT access"},secrets:{module:"../commands/secrets",export:"secretsCommand",desc:"Manage secrets (List, Set, Delete)"},generate:{module:"../commands/generate",export:"generateCommand",desc:"Generate secret values"},status:{module:"../commands/status",export:"statusCommand",desc:"Check synchronization status"},diff:{module:"../commands/diff",export:"diffCommand",desc:"Show differences between environments"},rollback:{module:"../commands/rollback",export:"rollbackCommand",desc:"Rollback secrets to a previous version"},scan:{module:"../commands/scan",export:"scanCommand",desc:"Scan codebase for hardcoded secrets"},logs:{module:"../commands/logs",export:"logsCommand",desc:"View activity and audit logs"},export:{module:"../commands/export",export:"exportCommand",desc:"Export secrets to various formats"},import:{module:"../commands/import",export:"importCommand",desc:"Import secrets from files"},rotate:{module:"../commands/rotate",export:"rotateCommand",desc:"Trigger secret rotation"},audit:{module:"../commands/audit",export:"auditCommand",desc:"Manage audit configurations"},access:{module:"../commands/access",export:"accessCommand",desc:"Manage Just-in-Time access requests"},branch:{module:"../commands/branch",export:"branchCommand",desc:"Manage secret branches"},checkout:{module:"../commands/checkout",export:"checkoutCommand",desc:"Switch between branches"},project:{module:"../commands/project",export:"projectCommand",desc:"Manage project configuration"},admin:{module:"../commands/admin",export:"adminCommand",desc:"Administrative tasks (Roles, Teams)"},integration:{module:"../commands/integration",export:"integrationCommand",desc:"Sync secrets to external platforms"},kubernetes:{module:"../commands/integration",export:"kubernetesCommand",desc:"Kubernetes specific integrations"},history:{module:"../commands/history",export:"historyCommand",desc:"View secret version history"},env:{module:"../commands/env",export:"envCommand",desc:"Manage environments"},ui:{module:"../commands/ui",export:"uiCommand",desc:"Launch interactive TUI dashboard"},completion:{module:"../commands/completion",export:"completionCommand",desc:"Generate shell completion"},profile:{module:"../commands/profile",export:"profileCommand",desc:"Manage CLI profiles"},ci:{module:"../commands/ci",export:"ciCommand",desc:"CI/CD integration helpers"},template:{module:"../commands/template",export:"templateCommand",desc:"Manage secret templates"},doctor:{module:"../commands/doctor",export:"doctorCommand",desc:"Diagnose CLI configuration issues"},init:{module:"../commands/init",export:"initCommand",desc:"Initialize XtraSecurity in current directory"},watch:{module:"../commands/watch",export:"watchCommand",desc:"Watch for secret changes in real-time"},simulate:{module:"../commands/simulate",export:"simulateCommand",desc:"Simulate secret access behavior"},local:{module:"../commands/local",export:"localCommand",desc:"Manage local secret overrides"}},De=new Set(["login","logout","completion","doctor","help","jit-run"]);p.hook("preSubcommand",(e,t)=>{let s=e.opts().profile;if(s){let{useProfile:v}=(J(),S(M));try{v(s)}catch(h){console.error(`\x1B[31mError: ${h.message}\x1B[0m`),process.exit(1)}}let r=t.name();if(De.has(r))return;let{getAuthToken:n}=(w(),S(L));n()||(console.error(`\x1B[31m\u2716 You are not logged in.\x1B[0m
2
+ var ge=Object.create;var S=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var fe=Object.getPrototypeOf,ye=Object.prototype.hasOwnProperty;var x=(e,t)=>()=>(e&&(t=e(e=0)),t);var b=(e,t)=>{for(var s in t)S(e,s,{get:t[s],enumerable:!0})},E=(e,t,s,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of le(t))!ye.call(e,n)&&n!==s&&S(e,n,{get:()=>t[n],enumerable:!(r=ue(t,n))||r.enumerable});return e};var c=(e,t,s)=>(s=e!=null?ge(fe(e)):{},E(t||!e||!e.__esModule?S(s,"default",{value:e,enumerable:!0}):s,e)),C=e=>E(S({},"__esModule",{value:!0}),e);var B={};b(B,{createProfile:()=>xe,deleteProfile:()=>ve,getActiveProfile:()=>O,getActiveProfileName:()=>$,getProfileValue:()=>Se,listProfiles:()=>m,setActiveProfile:()=>he,setProfileValue:()=>we,useProfile:()=>Ce});function m(){return d.get("profiles")||{}}function $(){return process.env.XTRA_PROFILE||d.get("activeProfile")||"default"}function O(){let e=$();return m()[e]||{}}function he(e){if(!m()[e])throw new Error(`Profile '${e}' does not exist. Create it first with 'xtra profile create ${e}'.`);d.set("activeProfile",e)}function xe(e,t={}){let s=m();if(s[e])throw new Error(`Profile '${e}' already exists. Use 'xtra profile set' to edit it.`);s[e]={apiUrl:process.env.XTRA_API_URL||"https://www.xtrasecurity.in/api",...t},d.set("profiles",s)}function ve(e){if(e==="default")throw new Error("Cannot delete the 'default' profile.");let t=m();if(!t[e])throw new Error(`Profile '${e}' not found.`);delete t[e],d.set("profiles",t),$()===e&&d.set("activeProfile","default")}function we(e,t,s){let r=m();if(!r[e])throw new Error(`Profile '${e}' not found.`);r[e][t]=s,d.set("profiles",r)}function Se(e){return O()[e]}function Ce(e){if(!m()[e])throw new Error(`Profile '${e}' does not exist. Run 'xtra profile create ${e}' first.`);process.env.XTRA_PROFILE=e}var N,d,M=x(()=>{N=c(require("conf")),d=new N.default({projectName:"xtra-cli",defaults:{activeProfile:"default",profiles:{default:{apiUrl:process.env.XTRA_API_URL||"https://www.xtrasecurity.in/api"}}}})});var R={};b(R,{clearConfig:()=>be,deleteConfig:()=>$e,getAuthToken:()=>I,getBreakGlassSession:()=>Ae,getConfig:()=>u,getConfigValue:()=>je,getProjectConfig:()=>Pe,getRcConfig:()=>Re,setBreakGlassSession:()=>Ie,setConfig:()=>ke});var q,g,P,A,i,J,u,je,ke,be,$e,I,Ae,Ie,Pe,Re,v=x(()=>{q=c(require("conf")),g=c(require("fs")),P=c(require("path")),A="https://www.xtrasecurity.in/api",i=new q.default({projectName:"xtra-cli",defaults:{apiUrl:A}}),J=i.get("apiUrl");J&&!process.env.XTRA_API_URL&&J.includes("xtra-security.vercel.app")&&i.set("apiUrl",A);u=()=>({...i.store,apiUrl:process.env.XTRA_API_URL||i.get("apiUrl")||A}),je=e=>i.get(e),ke=(e,t)=>{if(i.set(e,t),e==="token"&&process.platform!=="win32"&&g.default.existsSync(i.path))try{g.default.chmodSync(i.path,384)}catch{}},be=()=>i.clear(),$e=e=>i.delete(e),I=()=>i.get("token"),Ae=()=>i.get("breakGlassSessionId"),Ie=e=>{e?i.set("breakGlassSessionId",e):i.delete("breakGlassSessionId")},Pe=async()=>{try{let e=P.default.join(process.cwd(),"xtra.json");if(g.default.existsSync(e)){let t=g.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},Re=()=>{let e={};try{let t=P.default.join(process.cwd(),".xtrarc");g.default.existsSync(t)&&(e=JSON.parse(g.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||i.get("project")||"",env:e.env||i.get("env")||"development",branch:e.branch||i.get("branch")||"main"}}});function X(){let e=G.get("masterKey");e||(e=l.default.randomBytes(32).toString("hex"),G.set("masterKey",e));let t=(0,K.machineIdSync)();return l.default.createHash("sha256").update(e+t).digest()}var l,F,K,V,G,z,H,W=x(()=>{l=c(require("crypto")),F=c(require("conf")),K=require("node-machine-id"),V="aes-256-gcm",G=new F.default({projectName:"xtra-cli-crypto"});z=e=>{let t=l.default.randomBytes(16),s=X(),r=l.default.createCipheriv(V,s,t),n=r.update(e,"utf8","hex");n+=r.final("hex");let a=r.getAuthTag();return{iv:t.toString("hex"),content:n,tag:a.toString("hex")}},H=e=>{let t=X(),s=Buffer.from(e.iv,"hex"),r=Buffer.from(e.tag,"hex"),n=l.default.createDecipheriv(V,t,s);n.setAuthTag(r);let a=n.update(e.content,"hex","utf8");return a+=n.final("utf8"),a}});var Y,Q,Z,Le,o,ee,te=x(()=>{Y=c(require("axios"));v();Q=c(require("fs")),Z=c(require("path")),Le=JSON.parse(Q.readFileSync(Z.join(__dirname,"../../package.json"),"utf-8")),o=()=>{let{apiUrl:e}=u(),t=I();return Y.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":Le.version,...t?{Authorization:`Bearer ${t}`}:{}}})},ee={login:async(e,t,s)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,r,n="main")=>(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:r,branch:n})).data,getSecretDetails:async(e,t,s,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${r}`)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,r,n,a)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:r,sourceEnv:n,sourceKey:a})).data,rotateSecret:async(e,t,s,r,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:r,parsedNewValue:n})).data,promoteSecret:async(e,t,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,r)=>{let n={format:e};return t&&(n.startDate=t),s&&(n.endDate=s),r&&(n.projectId=r),(await o().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,r)=>(await o().post("/access/request",{projectId:e,secretId:r,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=u(),s=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=u(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await o().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:r})).data,cloneEnvironment:async(e,t,s,r,n)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:r,branch:n})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await o().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await o().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await o().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await o().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,s,r)=>(await o().post(`/projects/${e}/service-accounts/${t}/keys`,{label:s,expiresAt:r})).data,deleteServiceAccountKey:async(e,t,s)=>(await o().delete(`/projects/${e}/service-accounts/${t}/keys/${s}`)).data,post:async(e,t)=>(await o().post(e,t)).data}});var ne={};b(ne,{loadAuditLogs:()=>j,logAudit:()=>Te,saveAuditLogs:()=>k,syncAuditLogs:()=>_e});function Ue(e){if(!e||typeof e!="object")return e;let t={...e},s=["password","token","secret","value","apiKey","secretValue"];for(let r of Object.keys(t))s.some(n=>r.toLowerCase().includes(n))&&(t[r]="[REDACTED]");return t}async function re(e){try{if(!u().token)return!1;let s={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:Ue(e.details),timestamp:e.timestamp,projectId:e.projectId};return await ee.post("/audit/cli-logs",{logs:[s]}),!0}catch(t){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",t),!1}}function Te(e,t,s,r){let n={id:(0,se.v4)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:s,details:r,synced:!1},a=j();a.push(n),k(a),re(n).then(w=>{if(w){n.synced=!0;let h=j(),D=h.findIndex(me=>me.id===n.id);D!==-1&&(h[D].synced=!0,k(h))}}).catch(()=>{})}function j(){if(!f.default.existsSync(U))return[];try{let e=f.default.readFileSync(U,"utf-8"),t=JSON.parse(e),s=H(t);return JSON.parse(s)}catch{return[]}}function k(e){f.default.existsSync(L)||f.default.mkdirSync(L,{recursive:!0});let t=JSON.stringify(e),s=z(t);f.default.writeFileSync(U,JSON.stringify(s),"utf-8")}async function _e(){let e=j(),t=e.filter(r=>!r.synced);if(t.length===0)return 0;let s=0;for(let r of t)await re(r)&&(r.synced=!0,s++);return s>0&&k(e),s}var f,T,se,L,U,oe=x(()=>{f=c(require("fs")),T=c(require("path")),se=require("uuid");W();v();te();L=T.default.join(process.cwd(),".xtra"),U=T.default.join(L,"audit.enc")});var ie=require("commander"),ae=c(require("fs")),ce=c(require("path")),pe=c(require("update-notifier")),p=new ie.Command,de=JSON.parse(ae.readFileSync(ce.join(__dirname,"../../package.json"),"utf-8"));(0,pe.default)({pkg:de}).notify();p.name("xtra").description("XtraSync CLI - Secure Runtime Secret Injection").version(de.version).option("--profile <name>","Use a specific named profile for this command");var _={login:{module:"../commands/login",export:"loginCommand",desc:"Authenticate with XtraSecurity"},logout:{module:"../commands/logout",export:"logoutCommand",desc:"Logout and clear local token"},run:{module:"../commands/run",export:"runCommand",desc:"Run a command with injected secrets"},"jit-run":{module:"../commands/jit-run",export:"jitRunCommand",desc:"Run with temporary JIT access"},secrets:{module:"../commands/secrets",export:"secretsCommand",desc:"Manage secrets (List, Set, Delete)"},generate:{module:"../commands/generate",export:"generateCommand",desc:"Generate secret values"},status:{module:"../commands/status",export:"statusCommand",desc:"Check synchronization status"},diff:{module:"../commands/diff",export:"diffCommand",desc:"Show differences between environments"},rollback:{module:"../commands/rollback",export:"rollbackCommand",desc:"Rollback secrets to a previous version"},scan:{module:"../commands/scan",export:"scanCommand",desc:"Scan codebase for hardcoded secrets"},logs:{module:"../commands/logs",export:"logsCommand",desc:"View activity and audit logs"},export:{module:"../commands/export",export:"exportCommand",desc:"Export secrets to various formats"},import:{module:"../commands/import",export:"importCommand",desc:"Import secrets from files"},rotate:{module:"../commands/rotate",export:"rotateCommand",desc:"Trigger secret rotation"},audit:{module:"../commands/audit",export:"auditCommand",desc:"Manage audit configurations"},access:{module:"../commands/access",export:"accessCommand",desc:"Manage Just-in-Time access requests"},branch:{module:"../commands/branch",export:"branchCommand",desc:"Manage secret branches"},checkout:{module:"../commands/checkout",export:"checkoutCommand",desc:"Switch between branches"},project:{module:"../commands/project",export:"projectCommand",desc:"Manage project configuration"},admin:{module:"../commands/admin",export:"adminCommand",desc:"Administrative tasks (Roles, Teams)"},integration:{module:"../commands/integration",export:"integrationCommand",desc:"Sync secrets to external platforms"},kubernetes:{module:"../commands/integration",export:"kubernetesCommand",desc:"Kubernetes specific integrations"},history:{module:"../commands/history",export:"historyCommand",desc:"View secret version history"},env:{module:"../commands/env",export:"envCommand",desc:"Manage environments"},ui:{module:"../commands/ui",export:"uiCommand",desc:"Launch interactive TUI dashboard"},completion:{module:"../commands/completion",export:"completionCommand",desc:"Generate shell completion"},profile:{module:"../commands/profile",export:"profileCommand",desc:"Manage CLI profiles"},ci:{module:"../commands/ci",export:"ciCommand",desc:"CI/CD integration helpers"},"service-account":{module:"../commands/service-account",export:"serviceAccountCommand",desc:"Manage service accounts and machine tokens"},sa:{module:"../commands/service-account",export:"serviceAccountCommand",desc:"Manage service accounts and machine tokens"},template:{module:"../commands/template",export:"templateCommand",desc:"Manage secret templates"},doctor:{module:"../commands/doctor",export:"doctorCommand",desc:"Diagnose CLI configuration issues"},init:{module:"../commands/init",export:"initCommand",desc:"Initialize XtraSecurity in current directory"},watch:{module:"../commands/watch",export:"watchCommand",desc:"Watch for secret changes in real-time"},simulate:{module:"../commands/simulate",export:"simulateCommand",desc:"Simulate secret access behavior"},local:{module:"../commands/local",export:"localCommand",desc:"Manage local secret overrides"}},De=new Set(["login","logout","completion","doctor","help","jit-run","ci"]);p.hook("preSubcommand",(e,t)=>{let s=e.opts().profile;if(s){let{useProfile:w}=(M(),C(B));try{w(s)}catch(h){console.error(`\x1B[31mError: ${h?.response?.data?.error||"An unexpected error occurred"}\x1B[0m`),process.exit(1)}}let r=t.name();if(De.has(r))return;let{getAuthToken:n}=(v(),C(R));n()||(console.error(`\x1B[31m\u2716 You are not logged in.\x1B[0m
3
3
  Run \x1B[36mxtra login\x1B[0m to authenticate before using this command.
4
- `),process.exit(1))});p.hook("postAction",(e,t)=>{let{getBreakGlassSession:s}=(w(),S(L)),r=s();if(r){let{logAudit:n}=(oe(),S(ne));n("BREAK_GLASS_CLI_ACTIVITY",null,null,{command:t.name(),args:t.args,options:t.opts(),sessionId:r})}});var Ee=process.argv.slice(2),y=Ee.find(e=>!e.startsWith("-"));if(y&&D[y]){let e=D[y];try{let s=require(e.module)[e.export||`${y}Command`];s?p.addCommand(s):p.command(y).description(e.desc||"")}catch{p.command(y).description(e.desc||"")}}else Object.entries(D).forEach(([e,t])=>{p.command(e).description(t.desc||"")});p.parse(process.argv);
4
+ `),process.exit(1))});p.hook("postAction",(e,t)=>{let{getBreakGlassSession:s}=(v(),C(R)),r=s();if(r){let{logAudit:n}=(oe(),C(ne));n("BREAK_GLASS_CLI_ACTIVITY",null,null,{command:t.name(),args:t.args,options:t.opts(),sessionId:r})}});var Ee=process.argv.slice(2),y=Ee.find(e=>!e.startsWith("-"));if(y&&_[y]){let e=_[y];try{let s=require(e.module)[e.export||`${y}Command`];s?p.addCommand(s):p.command(y).description(e.desc||"")}catch{p.command(y).description(e.desc||"")}}else Object.entries(_).forEach(([e,t])=>{p.command(e).description(t.desc||"")});p.parse(process.argv);
@@ -1 +1 @@
1
- var ce=Object.create;var A=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var ge=Object.getPrototypeOf,le=Object.prototype.hasOwnProperty;var C=(e,t)=>()=>(e&&(t=e(e=0)),t);var D=(e,t)=>{for(var s in t)A(e,s,{get:t[s],enumerable:!0})},G=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of de(t))!le.call(e,r)&&r!==s&&A(e,r,{get:()=>t[r],enumerable:!(n=pe(t,r))||n.enumerable});return e};var p=(e,t,s)=>(s=e!=null?ce(ge(e)):{},G(t||!e||!e.__esModule?A(s,"default",{value:e,enumerable:!0}):s,e)),R=e=>G(A({},"__esModule",{value:!0}),e);var V={};D(V,{clearConfig:()=>ye,deleteConfig:()=>fe,getAuthToken:()=>J,getBreakGlassSession:()=>he,getConfig:()=>y,getConfigValue:()=>ue,getProjectConfig:()=>we,getRcConfig:()=>w,setBreakGlassSession:()=>b,setConfig:()=>me});var F,m,P,U,c,T,y,ue,me,ye,fe,J,he,b,we,w,x=C(()=>{F=p(require("conf")),m=p(require("fs")),P=p(require("path")),U="https://www.xtrasecurity.in/api",c=new F.default({projectName:"xtra-cli",defaults:{apiUrl:U}}),T=c.get("apiUrl");T&&!process.env.XTRA_API_URL&&(T.includes("localhost")||T.includes("xtra-security.vercel.app"))&&c.set("apiUrl",U);y=()=>({...c.store,apiUrl:process.env.XTRA_API_URL||c.get("apiUrl")||U}),ue=e=>c.get(e),me=(e,t)=>{if(c.set(e,t),e==="token"&&process.platform!=="win32"&&m.default.existsSync(c.path))try{m.default.chmodSync(c.path,384)}catch{}},ye=()=>c.clear(),fe=e=>c.delete(e),J=()=>c.get("token"),he=()=>c.get("breakGlassSessionId"),b=e=>{e?c.set("breakGlassSessionId",e):c.delete("breakGlassSessionId")},we=async()=>{try{let e=P.default.join(process.cwd(),"xtra.json");if(m.default.existsSync(e)){let t=m.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},w=()=>{let e={};try{let t=P.default.join(process.cwd(),".xtrarc");m.default.existsSync(t)&&(e=JSON.parse(m.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||c.get("project")||"",env:e.env||c.get("env")||"development",branch:e.branch||c.get("branch")||"main"}}});var K,M,H,Ie,i,g,O=C(()=>{K=p(require("axios"));x();M=p(require("fs")),H=p(require("path")),Ie=JSON.parse(M.readFileSync(H.join(__dirname,"../../package.json"),"utf-8")),i=()=>{let{apiUrl:e}=y(),t=J();return K.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":Ie.version,...t?{Authorization:`Bearer ${t}`}:{}}})},g={login:async(e,t,s)=>(await i().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await i().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await i().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,n,r="main")=>(await i().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:n,branch:r})).data,getSecretDetails:async(e,t,s,n="main")=>(await i().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${n}`)).data,syncLogs:async e=>(await i().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,n,r,a)=>(await i().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:r,sourceKey:a})).data,rotateSecret:async(e,t,s,n,r)=>(await i().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:n,parsedNewValue:r})).data,promoteSecret:async(e,t,s)=>(await i().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await i().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,n)=>{let r={format:e};return t&&(r.startDate=t),s&&(r.endDate=s),n&&(r.projectId=n),(await i().post("/audit/export",r,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,n)=>(await i().post("/access/request",{projectId:e,secretId:n,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await i().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=y(),s=t?`&workspaceId=${t}`:"";return(await i().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await i().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=y(),t=e?`/project?workspaceId=${e}`:"/project";return(await i().get(t)).data},getBranches:async e=>(await i().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await i().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await i().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await i().put("/branch",{id:e,...t})).data,getRoles:async()=>(await i().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await i().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await i().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await i().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await i().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await i().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await i().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await i().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,n)=>(await i().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:n})).data,cloneEnvironment:async(e,t,s,n,r)=>(await i().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:n,branch:r})).data,generateJitLink:async e=>(await i().post("/jit/generate",e)).data,claimJitLink:async e=>(await i().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await i().get(`/jit/${e}`)).data,post:async(e,t)=>(await i().post(e,t)).data}});function W(){let e=z.get("masterKey");e||(e=I.default.randomBytes(32).toString("hex"),z.set("masterKey",e));let t=(0,Y.machineIdSync)();return I.default.createHash("sha256").update(e+t).digest()}var I,X,Y,Q,z,Z,ee,te=C(()=>{I=p(require("crypto")),X=p(require("conf")),Y=require("node-machine-id"),Q="aes-256-gcm",z=new X.default({projectName:"xtra-cli-crypto"});Z=e=>{let t=I.default.randomBytes(16),s=W(),n=I.default.createCipheriv(Q,s,t),r=n.update(e,"utf8","hex");r+=n.final("hex");let a=n.getAuthTag();return{iv:t.toString("hex"),content:r,tag:a.toString("hex")}},ee=e=>{let t=W(),s=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),r=I.default.createDecipheriv(Q,t,s);r.setAuthTag(n);let a=r.update(e.content,"hex","utf8");return a+=r.final("utf8"),a}});var re={};D(re,{loadAuditLogs:()=>L,logAudit:()=>Se,saveAuditLogs:()=>E,syncAuditLogs:()=>ve});function je(e){if(!e||typeof e!="object")return e;let t={...e},s=["password","token","secret","value","apiKey","secretValue"];for(let n of Object.keys(t))s.some(r=>n.toLowerCase().includes(r))&&(t[n]="[REDACTED]");return t}async function ne(e){try{if(!y().token)return!1;let s={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:je(e.details),timestamp:e.timestamp,projectId:e.projectId};return await g.post("/audit/cli-logs",{logs:[s]}),!0}catch(t){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",t),!1}}function Se(e,t,s,n){let r={id:(0,se.v4)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:s,details:n,synced:!1},a=L();a.push(r),E(a),ne(r).then(d=>{if(d){r.synced=!0;let v=L(),k=v.findIndex($=>$.id===r.id);k!==-1&&(v[k].synced=!0,E(v))}}).catch(()=>{})}function L(){if(!j.default.existsSync(B))return[];try{let e=j.default.readFileSync(B,"utf-8"),t=JSON.parse(e),s=ee(t);return JSON.parse(s)}catch{return[]}}function E(e){j.default.existsSync(N)||j.default.mkdirSync(N,{recursive:!0});let t=JSON.stringify(e),s=Z(t);j.default.writeFileSync(B,JSON.stringify(s),"utf-8")}async function ve(){let e=L(),t=e.filter(n=>!n.synced);if(t.length===0)return 0;let s=0;for(let n of t)await ne(n)&&(n.synced=!0,s++);return s>0&&E(e),s}var j,_,se,N,B,oe=C(()=>{j=p(require("fs")),_=p(require("path")),se=require("uuid");te();x();O();N=_.default.join(process.cwd(),".xtra"),B=_.default.join(N,"audit.enc")});var xe={};D(xe,{accessCommand:()=>be});module.exports=R(xe);var l=require("commander");O();var o=p(require("chalk")),f=p(require("ora")),ie=require("table");x();var q=(e,t,s)=>{try{let{logAudit:n}=(oe(),R(re));n(e,t,null,s)}catch{}},S=e=>e?.response?.data?.error||e?.message||"Unknown error",be=new l.Command("access").description("Manage Just-in-Time access requests").addCommand(new l.Command("request").description("Request access to a secret or project").option("-p, --project <projectId>","Project ID").option("-s, --secret <secretId>","Specific Secret ID (optional)").requiredOption("-d, --duration <minutes>","Duration in minutes").requiredOption("-r, --reason <text>","Reason for access").action(async e=>{let{project:t,secret:s,duration:n,reason:r}=e;t||(t=w().project),t||(console.error(o.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let a=(0,f.default)("Submitting access request...").start();try{let d=await g.requestAccess(t,r,parseInt(n),s);a.succeed(o.default.green(`Access request submitted! (ID: ${d.requestId})`)),console.log(o.default.yellow(`Status: ${d.status}`)),q("ACCESS_REQUESTED",t,{requestId:d.requestId,secretId:s,duration:n,reason:r})}catch(d){a.fail("Request failed"),console.error(o.default.red(S(d)))}})).addCommand(new l.Command("list").description("List access requests").option("--pending","Show pending approvals (for admins)",!1).action(async e=>{try{let t=e.pending?"pending":"my",s=await g.listAccessRequests(t);if(s.length===0){console.log(o.default.yellow("No requests found."));return}let n=[[o.default.bold("ID"),o.default.bold("User"),o.default.bold("Target"),o.default.bold("Duration"),o.default.bold("Reason"),o.default.bold("Status")]];s.forEach(r=>{let a=r.secret?`Secret: ${r.secret.key}`:`Project: ${r.projectId}`;n.push([r.id,r.user.email,a,`${r.duration}m`,r.reason,r.status==="pending"?o.default.yellow(r.status):r.status==="approved"?o.default.green(r.status):o.default.red(r.status)])}),console.log((0,ie.table)(n))}catch(t){console.error(o.default.red("Failed to list requests: "+S(t)))}})).addCommand(new l.Command("approve").description("Approve or reject a request").argument("<requestId>","Request ID").requiredOption("--decision <decision>","approved or rejected").action(async(e,t)=>{["approved","rejected"].includes(t.decision.toLowerCase())||(console.error(o.default.red(`Invalid decision: '${t.decision}'. Must be 'approved' or 'rejected'.`)),process.exit(1));let n=(0,f.default)("Processing decision...").start();try{let r=await g.approveAccess(e,t.decision);n.succeed(o.default.green(`Request ${t.decision}!`)),r.expiresAt&&console.log(o.default.blue(`Access granted until: ${new Date(r.expiresAt).toLocaleString()}`)),q(t.decision==="approved"?"ACCESS_APPROVED":"ACCESS_REJECTED",null,{requestId:e,decision:t.decision,expiresAt:r.expiresAt})}catch(r){n.fail("Operation failed"),console.error(o.default.red(S(r)))}})).addCommand(new l.Command("jit-generate").description("Generate a shareable JIT access link for a project").option("-p, --project <projectId>","Project ID").requiredOption("-d, --duration <minutes>","Access duration in minutes").option("-b, --branch <branchId>","Scope to branch ID").option("-e, --env <environment>","Scope to environment (production, staging, development)").option("-s, --secrets <ids>","Comma-separated secret IDs to scope access").option("--label <text>","Label for the JIT link").option("--max-uses <count>","Maximum number of uses","1").option("--expires <hours>","Link expiry in hours","24").action(async e=>{let{project:t,duration:s,branch:n,env:r,secrets:a,label:d,maxUses:v,expires:k}=e;t||(t=w().project),t||(console.error(o.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let $=(0,f.default)("Generating JIT link...").start();try{let u={projectId:t,duration:parseInt(s),maxUses:parseInt(v),expiresInHours:parseInt(k)};n&&(u.branchId=n),r&&(u.environment=r),a&&(u.secretIds=a.split(",").map(ae=>ae.trim())),d&&(u.label=d);let h=await g.generateJitLink(u);$.succeed(o.default.green("JIT link generated!")),console.log(),console.log(o.default.bold(" Shareable URL:")),console.log(o.default.cyan(` ${h.url}`)),console.log(),console.log(o.default.bold(" CLI Command:")),console.log(o.default.yellow(` ${h.cliCommand}`)),console.log(),console.log(o.default.dim(` Expires: ${new Date(h.expiresAt).toLocaleString()}`)),console.log(o.default.dim(` Duration: ${h.duration} minutes | Access: ${h.accessLevel}-only`)),q("JIT_LINK_GENERATED",t,{token:h.token,duration:s,env:r,branch:n})}catch(u){$.fail("Failed to generate JIT link"),console.error(o.default.red(S(u)))}})).addCommand(new l.Command("jit").description("Claim a JIT access link (request read-only access)").argument("<token>","JIT link token").action(async e=>{let t=(0,f.default)("Claiming JIT link...").start();try{let s=await g.getJitInfo(e);t.text=`Requesting access to "${s.projectName}"...`;let n=await g.claimJitLink(e);t.succeed(o.default.green("Access request submitted!")),console.log(),console.log(o.default.yellow(" Status: Pending admin/owner approval")),console.log(o.default.dim(` Request ID: ${n.requestId}`)),console.log(o.default.dim(` Access: ${n.accessLevel}-only for ${n.duration} minutes`)),console.log(),console.log(o.default.dim(" Run 'xtra access list' to check request status.")),q("JIT_LINK_CLAIMED",null,{token:e,requestId:n.requestId})}catch(s){t.fail("Failed to claim JIT link"),console.error(o.default.red(S(s)))}})).addCommand(new l.Command("break-glass").description("Emergency break-glass access management").addCommand(new l.Command("link").description("Link an active break-glass session from the dashboard to this CLI").requiredOption("--id <sessionId>","Active Break Glass Session ID").action(async e=>{let{id:t}=e,s=(0,f.default)("Verifying session...").start();try{let n=await g.post("/access/break-glass",{projectId:w().project,reason:"CLI Link Verification"});(n.session||n.success)&&(b(t),s.succeed(o.default.red.bold("\u{1F6A8} EMERGENCY ACCESS LINKED")),console.log(),console.log(o.default.yellow(` Session ID: ${t}`)),console.log(o.default.dim(" Permissions: Full Administrative (Root)")),console.log(o.default.dim(" Audit Status: FULL VERBOSE LOGGING ENABLED")),console.log(),console.log(o.default.cyan(" You can now run any command with elevated permissions.")),console.log(o.default.cyan(" Example: 'xtra secrets list' will now show all secrets in the project.")))}catch(n){s.fail("Link failed"),console.error(o.default.red(S(n)))}})).addCommand(new l.Command("deactivate").description("End the current break-glass session").action(async()=>{let{getBreakGlassSession:e}=(x(),R(V));if(!e()){console.log(o.default.blue("No active break-glass session found locally."));return}let s=(0,f.default)("Deactivating session...").start();try{await g.post("/access/break-glass",{projectId:w().project,deactivate:!0}),b(null),s.succeed(o.default.green("Break-glass session ended."))}catch{b(null),s.warn("Local session cleared. (API might have already expired it)")}})));0&&(module.exports={accessCommand});
1
+ var ce=Object.create;var A=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var ge=Object.getPrototypeOf,le=Object.prototype.hasOwnProperty;var C=(e,t)=>()=>(e&&(t=e(e=0)),t);var D=(e,t)=>{for(var s in t)A(e,s,{get:t[s],enumerable:!0})},_=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of de(t))!le.call(e,r)&&r!==s&&A(e,r,{get:()=>t[r],enumerable:!(n=pe(t,r))||n.enumerable});return e};var p=(e,t,s)=>(s=e!=null?ce(ge(e)):{},_(t||!e||!e.__esModule?A(s,"default",{value:e,enumerable:!0}):s,e)),R=e=>_(A({},"__esModule",{value:!0}),e);var K={};D(K,{clearConfig:()=>ye,deleteConfig:()=>fe,getAuthToken:()=>U,getBreakGlassSession:()=>he,getConfig:()=>y,getConfigValue:()=>ue,getProjectConfig:()=>we,getRcConfig:()=>w,setBreakGlassSession:()=>b,setConfig:()=>me});var F,m,J,T,c,G,y,ue,me,ye,fe,U,he,b,we,w,x=C(()=>{F=p(require("conf")),m=p(require("fs")),J=p(require("path")),T="https://www.xtrasecurity.in/api",c=new F.default({projectName:"xtra-cli",defaults:{apiUrl:T}}),G=c.get("apiUrl");G&&!process.env.XTRA_API_URL&&G.includes("xtra-security.vercel.app")&&c.set("apiUrl",T);y=()=>({...c.store,apiUrl:process.env.XTRA_API_URL||c.get("apiUrl")||T}),ue=e=>c.get(e),me=(e,t)=>{if(c.set(e,t),e==="token"&&process.platform!=="win32"&&m.default.existsSync(c.path))try{m.default.chmodSync(c.path,384)}catch{}},ye=()=>c.clear(),fe=e=>c.delete(e),U=()=>c.get("token"),he=()=>c.get("breakGlassSessionId"),b=e=>{e?c.set("breakGlassSessionId",e):c.delete("breakGlassSessionId")},we=async()=>{try{let e=J.default.join(process.cwd(),"xtra.json");if(m.default.existsSync(e)){let t=m.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},w=()=>{let e={};try{let t=J.default.join(process.cwd(),".xtrarc");m.default.existsSync(t)&&(e=JSON.parse(m.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||c.get("project")||"",env:e.env||c.get("env")||"development",branch:e.branch||c.get("branch")||"main"}}});var V,M,H,ve,i,g,P=C(()=>{V=p(require("axios"));x();M=p(require("fs")),H=p(require("path")),ve=JSON.parse(M.readFileSync(H.join(__dirname,"../../package.json"),"utf-8")),i=()=>{let{apiUrl:e}=y(),t=U();return V.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":ve.version,...t?{Authorization:`Bearer ${t}`}:{}}})},g={login:async(e,t,s)=>(await i().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await i().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await i().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,n,r="main")=>(await i().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:n,branch:r})).data,getSecretDetails:async(e,t,s,n="main")=>(await i().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${n}`)).data,syncLogs:async e=>(await i().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,n,r,a)=>(await i().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:r,sourceKey:a})).data,rotateSecret:async(e,t,s,n,r)=>(await i().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:n,parsedNewValue:r})).data,promoteSecret:async(e,t,s)=>(await i().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await i().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,n)=>{let r={format:e};return t&&(r.startDate=t),s&&(r.endDate=s),n&&(r.projectId=n),(await i().post("/audit/export",r,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,n)=>(await i().post("/access/request",{projectId:e,secretId:n,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await i().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=y(),s=t?`&workspaceId=${t}`:"";return(await i().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await i().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=y(),t=e?`/project?workspaceId=${e}`:"/project";return(await i().get(t)).data},getBranches:async e=>(await i().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await i().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await i().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await i().put("/branch",{id:e,...t})).data,getRoles:async()=>(await i().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await i().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await i().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await i().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await i().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await i().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await i().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await i().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,n)=>(await i().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:n})).data,cloneEnvironment:async(e,t,s,n,r)=>(await i().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:n,branch:r})).data,generateJitLink:async e=>(await i().post("/jit/generate",e)).data,claimJitLink:async e=>(await i().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await i().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await i().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await i().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await i().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await i().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,s,n)=>(await i().post(`/projects/${e}/service-accounts/${t}/keys`,{label:s,expiresAt:n})).data,deleteServiceAccountKey:async(e,t,s)=>(await i().delete(`/projects/${e}/service-accounts/${t}/keys/${s}`)).data,post:async(e,t)=>(await i().post(e,t)).data}});function W(){let e=z.get("masterKey");e||(e=v.default.randomBytes(32).toString("hex"),z.set("masterKey",e));let t=(0,Y.machineIdSync)();return v.default.createHash("sha256").update(e+t).digest()}var v,X,Y,Q,z,Z,ee,te=C(()=>{v=p(require("crypto")),X=p(require("conf")),Y=require("node-machine-id"),Q="aes-256-gcm",z=new X.default({projectName:"xtra-cli-crypto"});Z=e=>{let t=v.default.randomBytes(16),s=W(),n=v.default.createCipheriv(Q,s,t),r=n.update(e,"utf8","hex");r+=n.final("hex");let a=n.getAuthTag();return{iv:t.toString("hex"),content:r,tag:a.toString("hex")}},ee=e=>{let t=W(),s=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),r=v.default.createDecipheriv(Q,t,s);r.setAuthTag(n);let a=r.update(e.content,"hex","utf8");return a+=r.final("utf8"),a}});var re={};D(re,{loadAuditLogs:()=>L,logAudit:()=>je,saveAuditLogs:()=>E,syncAuditLogs:()=>Se});function Ie(e){if(!e||typeof e!="object")return e;let t={...e},s=["password","token","secret","value","apiKey","secretValue"];for(let n of Object.keys(t))s.some(r=>n.toLowerCase().includes(r))&&(t[n]="[REDACTED]");return t}async function ne(e){try{if(!y().token)return!1;let s={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:Ie(e.details),timestamp:e.timestamp,projectId:e.projectId};return await g.post("/audit/cli-logs",{logs:[s]}),!0}catch(t){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",t),!1}}function je(e,t,s,n){let r={id:(0,se.v4)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:s,details:n,synced:!1},a=L();a.push(r),E(a),ne(r).then(d=>{if(d){r.synced=!0;let S=L(),k=S.findIndex($=>$.id===r.id);k!==-1&&(S[k].synced=!0,E(S))}}).catch(()=>{})}function L(){if(!I.default.existsSync(N))return[];try{let e=I.default.readFileSync(N,"utf-8"),t=JSON.parse(e),s=ee(t);return JSON.parse(s)}catch{return[]}}function E(e){I.default.existsSync(O)||I.default.mkdirSync(O,{recursive:!0});let t=JSON.stringify(e),s=Z(t);I.default.writeFileSync(N,JSON.stringify(s),"utf-8")}async function Se(){let e=L(),t=e.filter(n=>!n.synced);if(t.length===0)return 0;let s=0;for(let n of t)await ne(n)&&(n.synced=!0,s++);return s>0&&E(e),s}var I,B,se,O,N,oe=C(()=>{I=p(require("fs")),B=p(require("path")),se=require("uuid");te();x();P();O=B.default.join(process.cwd(),".xtra"),N=B.default.join(O,"audit.enc")});var xe={};D(xe,{accessCommand:()=>be});module.exports=R(xe);var l=require("commander");P();var o=p(require("chalk")),f=p(require("ora")),ie=require("table");x();var q=(e,t,s)=>{try{let{logAudit:n}=(oe(),R(re));n(e,t,null,s)}catch{}},j=e=>e?.response?.data?.error||e?.message||"Unknown error",be=new l.Command("access").description("Manage Just-in-Time access requests").addCommand(new l.Command("request").description("Request access to a secret or project").option("-p, --project <projectId>","Project ID").option("-s, --secret <secretId>","Specific Secret ID (optional)").requiredOption("-d, --duration <minutes>","Duration in minutes").requiredOption("-r, --reason <text>","Reason for access").action(async e=>{let{project:t,secret:s,duration:n,reason:r}=e;t||(t=w().project),t||(console.error(o.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let a=(0,f.default)("Submitting access request...").start();try{let d=await g.requestAccess(t,r,parseInt(n),s);a.succeed(o.default.green(`Access request submitted! (ID: ${d.requestId})`)),console.log(o.default.yellow(`Status: ${d.status}`)),q("ACCESS_REQUESTED",t,{requestId:d.requestId,secretId:s,duration:n,reason:r})}catch(d){a.fail("Request failed"),console.error(o.default.red(j(d)))}})).addCommand(new l.Command("list").description("List access requests").option("--pending","Show pending approvals (for admins)",!1).action(async e=>{try{let t=e.pending?"pending":"my",s=await g.listAccessRequests(t);if(s.length===0){console.log(o.default.yellow("No requests found."));return}let n=[[o.default.bold("ID"),o.default.bold("User"),o.default.bold("Target"),o.default.bold("Duration"),o.default.bold("Reason"),o.default.bold("Status")]];s.forEach(r=>{let a=r.secret?`Secret: ${r.secret.key}`:`Project: ${r.projectId}`;n.push([r.id,r.user.email,a,`${r.duration}m`,r.reason,r.status==="pending"?o.default.yellow(r.status):r.status==="approved"?o.default.green(r.status):o.default.red(r.status)])}),console.log((0,ie.table)(n))}catch(t){console.error(o.default.red("Failed to list requests: "+j(t)))}})).addCommand(new l.Command("approve").description("Approve or reject a request").argument("<requestId>","Request ID").requiredOption("--decision <decision>","approved or rejected").action(async(e,t)=>{["approved","rejected"].includes(t.decision.toLowerCase())||(console.error(o.default.red(`Invalid decision: '${t.decision}'. Must be 'approved' or 'rejected'.`)),process.exit(1));let n=(0,f.default)("Processing decision...").start();try{let r=await g.approveAccess(e,t.decision);n.succeed(o.default.green(`Request ${t.decision}!`)),r.expiresAt&&console.log(o.default.blue(`Access granted until: ${new Date(r.expiresAt).toLocaleString()}`)),q(t.decision==="approved"?"ACCESS_APPROVED":"ACCESS_REJECTED",null,{requestId:e,decision:t.decision,expiresAt:r.expiresAt})}catch(r){n.fail("Operation failed"),console.error(o.default.red(j(r)))}})).addCommand(new l.Command("jit-generate").description("Generate a shareable JIT access link for a project").option("-p, --project <projectId>","Project ID").requiredOption("-d, --duration <minutes>","Access duration in minutes").option("-b, --branch <branchId>","Scope to branch ID").option("-e, --env <environment>","Scope to environment (production, staging, development)").option("-s, --secrets <ids>","Comma-separated secret IDs to scope access").option("--label <text>","Label for the JIT link").option("--max-uses <count>","Maximum number of uses","1").option("--expires <hours>","Link expiry in hours","24").action(async e=>{let{project:t,duration:s,branch:n,env:r,secrets:a,label:d,maxUses:S,expires:k}=e;t||(t=w().project),t||(console.error(o.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let $=(0,f.default)("Generating JIT link...").start();try{let u={projectId:t,duration:parseInt(s),maxUses:parseInt(S),expiresInHours:parseInt(k)};n&&(u.branchId=n),r&&(u.environment=r),a&&(u.secretIds=a.split(",").map(ae=>ae.trim())),d&&(u.label=d);let h=await g.generateJitLink(u);$.succeed(o.default.green("JIT link generated!")),console.log(),console.log(o.default.bold(" Shareable URL:")),console.log(o.default.cyan(` ${h.url}`)),console.log(),console.log(o.default.bold(" CLI Command:")),console.log(o.default.yellow(` ${h.cliCommand}`)),console.log(),console.log(o.default.dim(` Expires: ${new Date(h.expiresAt).toLocaleString()}`)),console.log(o.default.dim(` Duration: ${h.duration} minutes | Access: ${h.accessLevel}-only`)),q("JIT_LINK_GENERATED",t,{token:h.token,duration:s,env:r,branch:n})}catch(u){$.fail("Failed to generate JIT link"),console.error(o.default.red(j(u)))}})).addCommand(new l.Command("jit").description("Claim a JIT access link (request read-only access)").argument("<token>","JIT link token").action(async e=>{let t=(0,f.default)("Claiming JIT link...").start();try{let s=await g.getJitInfo(e);t.text=`Requesting access to "${s.projectName}"...`;let n=await g.claimJitLink(e);t.succeed(o.default.green("Access request submitted!")),console.log(),console.log(o.default.yellow(" Status: Pending admin/owner approval")),console.log(o.default.dim(` Request ID: ${n.requestId}`)),console.log(o.default.dim(` Access: ${n.accessLevel}-only for ${n.duration} minutes`)),console.log(),console.log(o.default.dim(" Run 'xtra access list' to check request status.")),q("JIT_LINK_CLAIMED",null,{token:e,requestId:n.requestId})}catch(s){t.fail("Failed to claim JIT link"),console.error(o.default.red(j(s)))}})).addCommand(new l.Command("break-glass").description("Emergency break-glass access management").addCommand(new l.Command("link").description("Link an active break-glass session from the dashboard to this CLI").requiredOption("--id <sessionId>","Active Break Glass Session ID").action(async e=>{let{id:t}=e,s=(0,f.default)("Verifying session...").start();try{let n=await g.post("/access/break-glass",{projectId:w().project,reason:"CLI Link Verification"});(n.session||n.success)&&(b(t),s.succeed(o.default.red.bold("\u{1F6A8} EMERGENCY ACCESS LINKED")),console.log(),console.log(o.default.yellow(` Session ID: ${t}`)),console.log(o.default.dim(" Permissions: Full Administrative (Root)")),console.log(o.default.dim(" Audit Status: FULL VERBOSE LOGGING ENABLED")),console.log(),console.log(o.default.cyan(" You can now run any command with elevated permissions.")),console.log(o.default.cyan(" Example: 'xtra secrets list' will now show all secrets in the project.")))}catch(n){s.fail("Link failed"),console.error(o.default.red(j(n)))}})).addCommand(new l.Command("deactivate").description("End the current break-glass session").action(async()=>{let{getBreakGlassSession:e}=(x(),R(K));if(!e()){console.log(o.default.blue("No active break-glass session found locally."));return}let s=(0,f.default)("Deactivating session...").start();try{await g.post("/access/break-glass",{projectId:w().project,deactivate:!0}),b(null),s.succeed(o.default.green("Break-glass session ended."))}catch{b(null),s.warn("Local session cleared. (API might have already expired it)")}})));0&&(module.exports={accessCommand});
@@ -1,5 +1,5 @@
1
- var te=Object.create;var f=Object.defineProperty;var se=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var re=Object.getPrototypeOf,oe=Object.prototype.hasOwnProperty;var h=(e,t)=>()=>(e&&(t=e(e=0)),t);var D=(e,t)=>{for(var s in t)f(e,s,{get:t[s],enumerable:!0})},E=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ne(t))!oe.call(e,r)&&r!==s&&f(e,r,{get:()=>t[r],enumerable:!(n=se(t,r))||n.enumerable});return e};var c=(e,t,s)=>(s=e!=null?te(re(e)):{},E(t||!e||!e.__esModule?f(s,"default",{value:e,enumerable:!0}):s,e)),N=e=>E(f({},"__esModule",{value:!0}),e);var B,j,u,S,p,O,$=h(()=>{B=c(require("conf")),j="https://www.xtrasecurity.in/api",u=new B.default({projectName:"xtra-cli",defaults:{apiUrl:j}}),S=u.get("apiUrl");S&&!process.env.XTRA_API_URL&&(S.includes("localhost")||S.includes("xtra-security.vercel.app"))&&u.set("apiUrl",j);p=()=>({...u.store,apiUrl:process.env.XTRA_API_URL||u.get("apiUrl")||j}),O=()=>u.get("token")});var T,_,F,ae,o,g,k=h(()=>{T=c(require("axios"));$();_=c(require("fs")),F=c(require("path")),ae=JSON.parse(_.readFileSync(F.join(__dirname,"../../package.json"),"utf-8")),o=()=>{let{apiUrl:e}=p(),t=O();return T.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":ae.version,...t?{Authorization:`Bearer ${t}`}:{}}})},g={login:async(e,t,s)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,n,r="main")=>(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:n,branch:r})).data,getSecretDetails:async(e,t,s,n="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${n}`)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,n,r,a)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:r,sourceKey:a})).data,rotateSecret:async(e,t,s,n,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:n,parsedNewValue:r})).data,promoteSecret:async(e,t,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,n)=>{let r={format:e};return t&&(r.startDate=t),s&&(r.endDate=s),n&&(r.projectId=n),(await o().post("/audit/export",r,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,n)=>(await o().post("/access/request",{projectId:e,secretId:n,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=p(),s=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=p(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await o().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:n})).data,cloneEnvironment:async(e,t,s,n,r)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:n,branch:r})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,post:async(e,t)=>(await o().post(e,t)).data}});function K(){let e=P.get("masterKey");e||(e=d.default.randomBytes(32).toString("hex"),P.set("masterKey",e));let t=(0,G.machineIdSync)();return d.default.createHash("sha256").update(e+t).digest()}var d,J,G,q,P,V,H,z=h(()=>{d=c(require("crypto")),J=c(require("conf")),G=require("node-machine-id"),q="aes-256-gcm",P=new J.default({projectName:"xtra-cli-crypto"});V=e=>{let t=d.default.randomBytes(16),s=K(),n=d.default.createCipheriv(q,s,t),r=n.update(e,"utf8","hex");r+=n.final("hex");let a=n.getAuthTag();return{iv:t.toString("hex"),content:r,tag:a.toString("hex")}},H=e=>{let t=K(),s=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),r=d.default.createDecipheriv(q,t,s);r.setAuthTag(n);let a=r.update(e.content,"hex","utf8");return a+=r.final("utf8"),a}});var Q={};D(Q,{loadAuditLogs:()=>w,logAudit:()=>ce,saveAuditLogs:()=>v,syncAuditLogs:()=>pe});function ie(e){if(!e||typeof e!="object")return e;let t={...e},s=["password","token","secret","value","apiKey","secretValue"];for(let n of Object.keys(t))s.some(r=>n.toLowerCase().includes(r))&&(t[n]="[REDACTED]");return t}async function X(e){try{if(!p().token)return!1;let s={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:ie(e.details),timestamp:e.timestamp,projectId:e.projectId};return await g.post("/audit/cli-logs",{logs:[s]}),!0}catch(t){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",t),!1}}function ce(e,t,s,n){let r={id:(0,M.v4)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:s,details:n,synced:!1},a=w();a.push(r),v(a),X(r).then(y=>{if(y){r.synced=!0;let x=w(),L=x.findIndex(ee=>ee.id===r.id);L!==-1&&(x[L].synced=!0,v(x))}}).catch(()=>{})}function w(){if(!l.default.existsSync(A))return[];try{let e=l.default.readFileSync(A,"utf-8"),t=JSON.parse(e),s=H(t);return JSON.parse(s)}catch{return[]}}function v(e){l.default.existsSync(I)||l.default.mkdirSync(I,{recursive:!0});let t=JSON.stringify(e),s=V(t);l.default.writeFileSync(A,JSON.stringify(s),"utf-8")}async function pe(){let e=w(),t=e.filter(n=>!n.synced);if(t.length===0)return 0;let s=0;for(let n of t)await X(n)&&(n.synced=!0,s++);return s>0&&v(e),s}var l,C,M,I,A,W=h(()=>{l=c(require("fs")),C=c(require("path")),M=require("uuid");z();$();k();I=C.default.join(process.cwd(),".xtra"),A=C.default.join(I,"audit.enc")});var ge={};D(ge,{adminCommand:()=>m});module.exports=N(ge);var R=require("commander");k();var i=c(require("chalk")),b=c(require("ora")),U=require("table"),m=new R.Command("admin").description("Admin commands for user and role management"),Y=new R.Command("role").description("Manage user roles and permissions"),Z=async()=>{let e=(0,b.default)("Fetching roles from server...").start();try{let t=await g.getRoles();e.stop(),console.log(i.default.bold(`
1
+ var te=Object.create;var f=Object.defineProperty;var se=Object.getOwnPropertyDescriptor;var re=Object.getOwnPropertyNames;var ne=Object.getPrototypeOf,oe=Object.prototype.hasOwnProperty;var h=(e,t)=>()=>(e&&(t=e(e=0)),t);var L=(e,t)=>{for(var s in t)f(e,s,{get:t[s],enumerable:!0})},D=(e,t,s,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of re(t))!oe.call(e,n)&&n!==s&&f(e,n,{get:()=>t[n],enumerable:!(r=se(t,n))||r.enumerable});return e};var c=(e,t,s)=>(s=e!=null?te(ne(e)):{},D(t||!e||!e.__esModule?f(s,"default",{value:e,enumerable:!0}):s,e)),E=e=>D(f({},"__esModule",{value:!0}),e);var B,j,u,N,p,O,b=h(()=>{B=c(require("conf")),j="https://www.xtrasecurity.in/api",u=new B.default({projectName:"xtra-cli",defaults:{apiUrl:j}}),N=u.get("apiUrl");N&&!process.env.XTRA_API_URL&&N.includes("xtra-security.vercel.app")&&u.set("apiUrl",j);p=()=>({...u.store,apiUrl:process.env.XTRA_API_URL||u.get("apiUrl")||j}),O=()=>u.get("token")});var T,_,F,ae,o,g,x=h(()=>{T=c(require("axios"));b();_=c(require("fs")),F=c(require("path")),ae=JSON.parse(_.readFileSync(F.join(__dirname,"../../package.json"),"utf-8")),o=()=>{let{apiUrl:e}=p(),t=O();return T.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":ae.version,...t?{Authorization:`Bearer ${t}`}:{}}})},g={login:async(e,t,s)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,r,n="main")=>(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:r,branch:n})).data,getSecretDetails:async(e,t,s,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${r}`)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,r,n,i)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:r,sourceEnv:n,sourceKey:i})).data,rotateSecret:async(e,t,s,r,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:r,parsedNewValue:n})).data,promoteSecret:async(e,t,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,r)=>{let n={format:e};return t&&(n.startDate=t),s&&(n.endDate=s),r&&(n.projectId=r),(await o().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,r)=>(await o().post("/access/request",{projectId:e,secretId:r,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=p(),s=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=p(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await o().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:r})).data,cloneEnvironment:async(e,t,s,r,n)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:r,branch:n})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await o().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await o().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await o().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await o().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,s,r)=>(await o().post(`/projects/${e}/service-accounts/${t}/keys`,{label:s,expiresAt:r})).data,deleteServiceAccountKey:async(e,t,s)=>(await o().delete(`/projects/${e}/service-accounts/${t}/keys/${s}`)).data,post:async(e,t)=>(await o().post(e,t)).data}});function q(){let e=P.get("masterKey");e||(e=d.default.randomBytes(32).toString("hex"),P.set("masterKey",e));let t=(0,G.machineIdSync)();return d.default.createHash("sha256").update(e+t).digest()}var d,J,G,K,P,V,H,z=h(()=>{d=c(require("crypto")),J=c(require("conf")),G=require("node-machine-id"),K="aes-256-gcm",P=new J.default({projectName:"xtra-cli-crypto"});V=e=>{let t=d.default.randomBytes(16),s=q(),r=d.default.createCipheriv(K,s,t),n=r.update(e,"utf8","hex");n+=r.final("hex");let i=r.getAuthTag();return{iv:t.toString("hex"),content:n,tag:i.toString("hex")}},H=e=>{let t=q(),s=Buffer.from(e.iv,"hex"),r=Buffer.from(e.tag,"hex"),n=d.default.createDecipheriv(K,t,s);n.setAuthTag(r);let i=n.update(e.content,"hex","utf8");return i+=n.final("utf8"),i}});var Q={};L(Q,{loadAuditLogs:()=>w,logAudit:()=>ce,saveAuditLogs:()=>v,syncAuditLogs:()=>pe});function ie(e){if(!e||typeof e!="object")return e;let t={...e},s=["password","token","secret","value","apiKey","secretValue"];for(let r of Object.keys(t))s.some(n=>r.toLowerCase().includes(n))&&(t[r]="[REDACTED]");return t}async function X(e){try{if(!p().token)return!1;let s={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:ie(e.details),timestamp:e.timestamp,projectId:e.projectId};return await g.post("/audit/cli-logs",{logs:[s]}),!0}catch(t){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",t),!1}}function ce(e,t,s,r){let n={id:(0,M.v4)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:s,details:r,synced:!1},i=w();i.push(n),v(i),X(n).then(y=>{if(y){n.synced=!0;let $=w(),U=$.findIndex(ee=>ee.id===n.id);U!==-1&&($[U].synced=!0,v($))}}).catch(()=>{})}function w(){if(!l.default.existsSync(k))return[];try{let e=l.default.readFileSync(k,"utf-8"),t=JSON.parse(e),s=H(t);return JSON.parse(s)}catch{return[]}}function v(e){l.default.existsSync(A)||l.default.mkdirSync(A,{recursive:!0});let t=JSON.stringify(e),s=V(t);l.default.writeFileSync(k,JSON.stringify(s),"utf-8")}async function pe(){let e=w(),t=e.filter(r=>!r.synced);if(t.length===0)return 0;let s=0;for(let r of t)await X(r)&&(r.synced=!0,s++);return s>0&&v(e),s}var l,I,M,A,k,W=h(()=>{l=c(require("fs")),I=c(require("path")),M=require("uuid");z();b();x();A=I.default.join(process.cwd(),".xtra"),k=I.default.join(A,"audit.enc")});var ge={};L(ge,{adminCommand:()=>m});module.exports=E(ge);var C=require("commander");x();var a=c(require("chalk")),S=c(require("ora")),R=require("table"),m=new C.Command("admin").description("Admin commands for user and role management"),Y=new C.Command("role").description("Manage user roles and permissions"),Z=async()=>{let e=(0,S.default)("Fetching roles from server...").start();try{let t=await g.getRoles();e.stop(),console.log(a.default.bold(`
2
2
  Available Roles:
3
- `));let s=[[i.default.bold("Role"),i.default.bold("Description"),i.default.bold("Permissions")]];t.forEach(n=>{s.push([i.default.cyan(n.name),n.description||"-",Array.isArray(n.permissions)?n.permissions.join(", "):n.permissions||"-"])}),console.log((0,U.table)(s))}catch(t){e.fail("Failed to fetch roles");let s=t.response?.data?.error||t.message||"Unknown error";console.error(i.default.red(s))}};Y.command("list").description("List all available roles").alias("ls").action(Z);m.addCommand(Y);m.command("roles").description("Alias for 'role list'").action(Z);m.command("users").description("List all users with their roles").option("-t, --team <teamId>","Filter by team ID").action(async e=>{let t=(0,b.default)("Fetching users...").start();try{let s=await g.getUsers(e.team);if(t.stop(),!s||s.length===0){console.log(i.default.yellow("No users found."));return}console.log(i.default.bold(`
3
+ `));let s=[[a.default.bold("Role"),a.default.bold("Description"),a.default.bold("Permissions")]];t.forEach(r=>{s.push([a.default.cyan(r.name),r.description||"-",Array.isArray(r.permissions)?r.permissions.join(", "):r.permissions||"-"])}),console.log((0,R.table)(s))}catch(t){e.fail("Failed to fetch roles");let s=t.response?.data?.error||"Unknown error";console.error(a.default.red(s))}};Y.command("list").description("List all available roles").alias("ls").action(Z);m.addCommand(Y);m.command("roles").description("Alias for 'role list'").action(Z);m.command("users").description("List all users with their roles").option("-t, --team <teamId>","Filter by team ID").action(async e=>{let t=(0,S.default)("Fetching users...").start();try{let s=await g.getUsers(e.team);if(t.stop(),!s||s.length===0){console.log(a.default.yellow("No users found."));return}console.log(a.default.bold(`
4
4
  Users:
5
- `));let n=[[i.default.bold("Email"),i.default.bold("Name"),i.default.bold("Role"),i.default.bold("Status")]];s.forEach(r=>{let a=r.role==="owner"||r.role==="admin"?i.default.magenta:r.role==="viewer"?i.default.gray:i.default.cyan;n.push([r.email,r.name||"-",a(r.role),r.status||"active"])}),console.log((0,U.table)(n))}catch(s){t.fail("Failed to fetch users"),console.error(i.default.red(s.message))}});m.command("set-role <email> <role>").description("Change a user's role (owner, admin, developer, viewer, guest)").option("-t, --team <teamId>","Team ID (for team-specific role)").action(async(e,t,s)=>{let n=["owner","admin","developer","viewer","guest"];n.includes(t.toLowerCase())||(console.error(i.default.red(`Invalid role: ${t}`)),console.log(i.default.yellow(`Valid roles: ${n.join(", ")}`)),process.exit(1));let r=(0,b.default)(`Updating role for ${e}...`).start();try{await g.setUserRole(e,t.toLowerCase(),s.team),r.succeed(i.default.green(`Role updated: ${e} \u2192 ${t}`));try{let{logAudit:a}=(W(),N(Q));a("ADMIN_ROLE_CHANGE",null,null,{email:e,newRole:t,teamId:s.team})}catch{}}catch(a){r.fail("Failed to update role");let y=a.response?.data?.error||a.message||"Unknown error";console.error(i.default.red(y))}});0&&(module.exports={adminCommand});
5
+ `));let r=[[a.default.bold("Email"),a.default.bold("Name"),a.default.bold("Role"),a.default.bold("Status")]];s.forEach(n=>{let i=n.role==="owner"||n.role==="admin"?a.default.magenta:n.role==="viewer"?a.default.gray:a.default.cyan;r.push([n.email,n.name||"-",i(n.role),n.status||"active"])}),console.log((0,R.table)(r))}catch(s){t.fail("Failed to fetch users"),console.error(a.default.red(s?.response?.data?.error||"An unexpected error occurred"))}});m.command("set-role <email> <role>").description("Change a user's role (owner, admin, developer, viewer, guest)").option("-t, --team <teamId>","Team ID (for team-specific role)").action(async(e,t,s)=>{let r=["owner","admin","developer","viewer","guest"];r.includes(t.toLowerCase())||(console.error(a.default.red(`Invalid role: ${t}`)),console.log(a.default.yellow(`Valid roles: ${r.join(", ")}`)),process.exit(1));let n=(0,S.default)(`Updating role for ${e}...`).start();try{await g.setUserRole(e,t.toLowerCase(),s.team),n.succeed(a.default.green(`Role updated: ${e} \u2192 ${t}`));try{let{logAudit:i}=(W(),E(Q));i("ADMIN_ROLE_CHANGE",null,null,{email:e,newRole:t,teamId:s.team})}catch{}}catch(i){n.fail("Failed to update role");let y=i.response?.data?.error||"Unknown error";console.error(a.default.red(y))}});0&&(module.exports={adminCommand});
@@ -1 +1 @@
1
- var I=Object.create;var d=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var R=Object.getPrototypeOf,U=Object.prototype.hasOwnProperty;var L=(e,t)=>{for(var s in t)d(e,s,{get:t[s],enumerable:!0})},$=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of A(t))!U.call(e,o)&&o!==s&&d(e,o,{get:()=>t[o],enumerable:!(n=C(t,o))||n.enumerable});return e};var c=(e,t,s)=>(s=e!=null?I(R(e)):{},$(t||!e||!e.__esModule?d(s,"default",{value:e,enumerable:!0}):s,e)),O=e=>$(d({},"__esModule",{value:!0}),e);var D={};L(D,{auditCommand:()=>_});module.exports=O(D);var u=require("commander");var v=c(require("axios"));var S=c(require("conf"));var m="https://www.xtrasecurity.in/api",g=new S.default({projectName:"xtra-cli",defaults:{apiUrl:m}}),y=g.get("apiUrl");y&&!process.env.XTRA_API_URL&&(y.includes("localhost")||y.includes("xtra-security.vercel.app"))&&g.set("apiUrl",m);var l=()=>({...g.store,apiUrl:process.env.XTRA_API_URL||g.get("apiUrl")||m});var j=()=>g.get("token");var x=c(require("fs")),b=c(require("path")),P=JSON.parse(x.readFileSync(b.join(__dirname,"../../package.json"),"utf-8")),r=()=>{let{apiUrl:e}=l(),t=j();return v.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":P.version,...t?{Authorization:`Bearer ${t}`}:{}}})},f={login:async(e,t,s)=>(await r().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,n,o="main")=>(await r().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:n,branch:o})).data,getSecretDetails:async(e,t,s,n="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${n}`)).data,syncLogs:async e=>(await r().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,n,o,i)=>(await r().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:o,sourceKey:i})).data,rotateSecret:async(e,t,s,n,o)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:n,parsedNewValue:o})).data,promoteSecret:async(e,t,s)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await r().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,n)=>{let o={format:e};return t&&(o.startDate=t),s&&(o.endDate=s),n&&(o.projectId=n),(await r().post("/audit/export",o,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,n)=>(await r().post("/access/request",{projectId:e,secretId:n,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await r().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=l(),s=t?`&workspaceId=${t}`:"";return(await r().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await r().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=l(),t=e?`/project?workspaceId=${e}`:"/project";return(await r().get(t)).data},getBranches:async e=>(await r().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await r().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await r().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await r().put("/branch",{id:e,...t})).data,getRoles:async()=>(await r().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await r().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await r().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await r().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await r().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await r().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await r().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await r().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,n)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:n})).data,cloneEnvironment:async(e,t,s,n,o)=>(await r().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:n,branch:o})).data,generateJitLink:async e=>(await r().post("/jit/generate",e)).data,claimJitLink:async e=>(await r().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await r().get(`/jit/${e}`)).data,post:async(e,t)=>(await r().post(e,t)).data};var a=c(require("chalk")),w=c(require("ora")),k=c(require("fs")),_=new u.Command("audit").description("Manage and verify audit logs").addCommand(new u.Command("verify").description("Verify the integrity of the audit log chain (Tamper-Evident)").action(async()=>{let e=(0,w.default)("Verifying audit chain integrity...").start();try{let t=await f.verifyAuditLogs();t.valid?e.succeed(a.default.green(t.message)):(e.fail(a.default.red("Verification Failed!")),console.error(a.default.red(`Broken at Log ID: ${t.details?.brokenAtId}`)),console.error(a.default.red(`Reason: ${t.details?.reason}`)))}catch(t){e.fail("Verification failed"),t.response?.data?.details?(console.error(a.default.red(`Chain Broken: ${t.response.data.message}`)),console.error(a.default.yellow(`Details: ${JSON.stringify(t.response.data.details,null,2)}`))):console.error(a.default.red(t.message))}})).addCommand(new u.Command("export").description("Export audit logs for compliance (SOC2/ISO)").option("-f, --format <format>","Output format (json, csv)","json").option("--start <date>","Start date (YYYY-MM-DD)").option("--end <date>","End date (YYYY-MM-DD)").option("-o, --output <file>","Output file path").action(async e=>{let{format:t,start:s,end:n,output:o}=e,i=(0,w.default)(`Exporting audit logs (${t})...`).start();try{let p=await f.exportAuditLogs(t,s,n),h=typeof p=="object"?JSON.stringify(p,null,2):p;o?(k.default.writeFileSync(o,h),i.succeed(a.default.green(`Export saved to ${o}`))):(i.stop(),console.log(h))}catch(p){i.fail("Export failed"),console.error(a.default.red(p.message))}}));0&&(module.exports={auditCommand});
1
+ var A=Object.create;var d=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var R=Object.getPrototypeOf,U=Object.prototype.hasOwnProperty;var L=(e,t)=>{for(var s in t)d(e,s,{get:t[s],enumerable:!0})},$=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of C(t))!U.call(e,o)&&o!==s&&d(e,o,{get:()=>t[o],enumerable:!(n=I(t,o))||n.enumerable});return e};var c=(e,t,s)=>(s=e!=null?A(R(e)):{},$(t||!e||!e.__esModule?d(s,"default",{value:e,enumerable:!0}):s,e)),O=e=>$(d({},"__esModule",{value:!0}),e);var D={};L(D,{auditCommand:()=>_});module.exports=O(D);var l=require("commander");var j=c(require("axios"));var v=c(require("conf"));var y="https://www.xtrasecurity.in/api",g=new v.default({projectName:"xtra-cli",defaults:{apiUrl:y}}),h=g.get("apiUrl");h&&!process.env.XTRA_API_URL&&h.includes("xtra-security.vercel.app")&&g.set("apiUrl",y);var u=()=>({...g.store,apiUrl:process.env.XTRA_API_URL||g.get("apiUrl")||y});var S=()=>g.get("token");var x=c(require("fs")),k=c(require("path")),P=JSON.parse(x.readFileSync(k.join(__dirname,"../../package.json"),"utf-8")),r=()=>{let{apiUrl:e}=u(),t=S();return j.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":P.version,...t?{Authorization:`Bearer ${t}`}:{}}})},m={login:async(e,t,s)=>(await r().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,n,o="main")=>(await r().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:n,branch:o})).data,getSecretDetails:async(e,t,s,n="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${n}`)).data,syncLogs:async e=>(await r().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,n,o,i)=>(await r().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:o,sourceKey:i})).data,rotateSecret:async(e,t,s,n,o)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:n,parsedNewValue:o})).data,promoteSecret:async(e,t,s)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await r().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,n)=>{let o={format:e};return t&&(o.startDate=t),s&&(o.endDate=s),n&&(o.projectId=n),(await r().post("/audit/export",o,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,n)=>(await r().post("/access/request",{projectId:e,secretId:n,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await r().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=u(),s=t?`&workspaceId=${t}`:"";return(await r().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await r().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=u(),t=e?`/project?workspaceId=${e}`:"/project";return(await r().get(t)).data},getBranches:async e=>(await r().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await r().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await r().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await r().put("/branch",{id:e,...t})).data,getRoles:async()=>(await r().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await r().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await r().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await r().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await r().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await r().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await r().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await r().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,n)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:n})).data,cloneEnvironment:async(e,t,s,n,o)=>(await r().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:n,branch:o})).data,generateJitLink:async e=>(await r().post("/jit/generate",e)).data,claimJitLink:async e=>(await r().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await r().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await r().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await r().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await r().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await r().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,s,n)=>(await r().post(`/projects/${e}/service-accounts/${t}/keys`,{label:s,expiresAt:n})).data,deleteServiceAccountKey:async(e,t,s)=>(await r().delete(`/projects/${e}/service-accounts/${t}/keys/${s}`)).data,post:async(e,t)=>(await r().post(e,t)).data};var a=c(require("chalk")),f=c(require("ora")),b=c(require("fs")),_=new l.Command("audit").description("Manage and verify audit logs").addCommand(new l.Command("verify").description("Verify the integrity of the audit log chain (Tamper-Evident)").action(async()=>{let e=(0,f.default)("Verifying audit chain integrity...").start();try{let t=await m.verifyAuditLogs();t.valid?e.succeed(a.default.green(t.message)):(e.fail(a.default.red("Verification Failed!")),console.error(a.default.red(`Broken at Log ID: ${t.details?.brokenAtId}`)),console.error(a.default.red(`Reason: ${t.details?.reason}`)))}catch(t){e.fail("Verification failed"),t.response?.data?.details?(console.error(a.default.red(`Chain Broken: ${t.response.data.message}`)),console.error(a.default.yellow(`Details: ${JSON.stringify(t.response.data.details,null,2)}`))):console.error(a.default.red(t?.response?.data?.error||"An unexpected error occurred"))}})).addCommand(new l.Command("export").description("Export audit logs for compliance (SOC2/ISO)").option("-f, --format <format>","Output format (json, csv)","json").option("--start <date>","Start date (YYYY-MM-DD)").option("--end <date>","End date (YYYY-MM-DD)").option("-o, --output <file>","Output file path").action(async e=>{let{format:t,start:s,end:n,output:o}=e,i=(0,f.default)(`Exporting audit logs (${t})...`).start();try{let p=await m.exportAuditLogs(t,s,n),w=typeof p=="object"?JSON.stringify(p,null,2):p;o?(b.default.writeFileSync(o,w),i.succeed(a.default.green(`Export saved to ${o}`))):(i.stop(),console.log(w))}catch(p){i.fail("Export failed"),console.error(a.default.red(p?.response?.data?.error||"An unexpected error occurred"))}}));0&&(module.exports={auditCommand});
@@ -1 +1 @@
1
- var se=Object.create;var j=Object.defineProperty;var ne=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var ae=Object.getPrototypeOf,ie=Object.prototype.hasOwnProperty;var x=(e,t)=>()=>(e&&(t=e(e=0)),t);var N=(e,t)=>{for(var r in t)j(e,r,{get:t[r],enumerable:!0})},R=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of oe(t))!ie.call(e,n)&&n!==r&&j(e,n,{get:()=>t[n],enumerable:!(s=ne(t,n))||s.enumerable});return e};var g=(e,t,r)=>(r=e!=null?se(ae(e)):{},R(t||!e||!e.__esModule?j(r,"default",{value:e,enumerable:!0}):r,e)),L=e=>R(j({},"__esModule",{value:!0}),e);var O,A,T,C,f,k,y,P,w,S=x(()=>{O=g(require("conf")),A=g(require("fs")),T=g(require("path")),C="https://www.xtrasecurity.in/api",f=new O.default({projectName:"xtra-cli",defaults:{apiUrl:C}}),k=f.get("apiUrl");k&&!process.env.XTRA_API_URL&&(k.includes("localhost")||k.includes("xtra-security.vercel.app"))&&f.set("apiUrl",C);y=()=>({...f.store,apiUrl:process.env.XTRA_API_URL||f.get("apiUrl")||C}),P=()=>f.get("token"),w=()=>{let e={};try{let t=T.default.join(process.cwd(),".xtrarc");A.default.existsSync(t)&&(e=JSON.parse(A.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||f.get("project")||"",env:e.env||f.get("env")||"development",branch:e.branch||f.get("branch")||"main"}}});var _,F,q,ce,o,u,B=x(()=>{_=g(require("axios"));S();F=g(require("fs")),q=g(require("path")),ce=JSON.parse(F.readFileSync(q.join(__dirname,"../../package.json"),"utf-8")),o=()=>{let{apiUrl:e}=y(),t=P();return _.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":ce.version,...t?{Authorization:`Bearer ${t}`}:{}}})},u={login:async(e,t,r)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:r})).data,getSecrets:async(e,t,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?branch=${r}`)).data,getSecretVersions:async(e,t,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${r}`)).data,setSecrets:async(e,t,r,s,n="main")=>(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:r,expectedVersions:s,branch:n})).data,getSecretDetails:async(e,t,r,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}?branch=${s}`)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,r,s,n,a)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:r,sourceProjectId:s,sourceEnv:n,sourceKey:a})).data,rotateSecret:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/rotate`,{strategy:s,parsedNewValue:n})).data,promoteSecret:async(e,t,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,r,s)=>{let n={format:e};return t&&(n.startDate=t),r&&(n.endDate=r),s&&(n.projectId=s),(await o().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,r,s)=>(await o().post("/access/request",{projectId:e,secretId:s,reason:t,duration:r})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=y(),r=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${r}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=y(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,r)=>(await o().post("/branch",{projectId:e,name:t,description:r})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,r)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:r})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let r=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${r}`)).data},getSecretHistory:async(e,t,r)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}/history`)).data,rollbackSecret:async(e,t,r,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/history`,{version:s})).data,cloneEnvironment:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:r,overwrite:s,branch:n})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,post:async(e,t)=>(await o().post(e,t)).data}});function H(){let e=J.get("masterKey");e||(e=m.default.randomBytes(32).toString("hex"),J.set("masterKey",e));let t=(0,K.machineIdSync)();return m.default.createHash("sha256").update(e+t).digest()}var m,G,K,V,J,z,M,X=x(()=>{m=g(require("crypto")),G=g(require("conf")),K=require("node-machine-id"),V="aes-256-gcm",J=new G.default({projectName:"xtra-cli-crypto"});z=e=>{let t=m.default.randomBytes(16),r=H(),s=m.default.createCipheriv(V,r,t),n=s.update(e,"utf8","hex");n+=s.final("hex");let a=s.getAuthTag();return{iv:t.toString("hex"),content:n,tag:a.toString("hex")}},M=e=>{let t=H(),r=Buffer.from(e.iv,"hex"),s=Buffer.from(e.tag,"hex"),n=m.default.createDecipheriv(V,t,r);n.setAuthTag(s);let a=n.update(e.content,"hex","utf8");return a+=n.final("utf8"),a}});var Y={};N(Y,{loadAuditLogs:()=>v,logAudit:()=>ge,saveAuditLogs:()=>$,syncAuditLogs:()=>de});function pe(e){if(!e||typeof e!="object")return e;let t={...e},r=["password","token","secret","value","apiKey","secretValue"];for(let s of Object.keys(t))r.some(n=>s.toLowerCase().includes(n))&&(t[s]="[REDACTED]");return t}async function W(e){try{if(!y().token)return!1;let r={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:pe(e.details),timestamp:e.timestamp,projectId:e.projectId};return await u.post("/audit/cli-logs",{logs:[r]}),!0}catch(t){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",t),!1}}function ge(e,t,r,s){let n={id:(0,Q.v4)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:r,details:s,synced:!1},a=v();a.push(n),$(a),W(n).then(i=>{if(i){n.synced=!0;let p=v(),d=p.findIndex(I=>I.id===n.id);d!==-1&&(p[d].synced=!0,$(p))}}).catch(()=>{})}function v(){if(!h.default.existsSync(U))return[];try{let e=h.default.readFileSync(U,"utf-8"),t=JSON.parse(e),r=M(t);return JSON.parse(r)}catch{return[]}}function $(e){h.default.existsSync(E)||h.default.mkdirSync(E,{recursive:!0});let t=JSON.stringify(e),r=z(t);h.default.writeFileSync(U,JSON.stringify(r),"utf-8")}async function de(){let e=v(),t=e.filter(s=>!s.synced);if(t.length===0)return 0;let r=0;for(let s of t)await W(s)&&(s.synced=!0,r++);return r>0&&$(e),r}var h,D,Q,E,U,Z=x(()=>{h=g(require("fs")),D=g(require("path")),Q=require("uuid");X();S();B();E=D.default.join(process.cwd(),".xtra"),U=D.default.join(E,"audit.enc")});var ue={};N(ue,{branchCommand:()=>l});module.exports=L(ue);var ee=require("commander");B();var c=g(require("chalk")),b=g(require("ora")),te=require("table");S();var re=g(require("inquirer")),l=new ee.Command("branch").description("Manage branches").option("-p, --project <projectId>","Project ID");l.command("list").description("List all branches").action(async e=>{let t=l.opts(),{project:r}=t;r||(r=w().project),r||(console.error(c.default.red("Error: Project ID is required. Use -p <id> or checkout a branch.")),process.exit(1));let s=(0,b.default)("Fetching branches...").start();try{let n=await u.getBranches(r);if(s.stop(),!n){console.log(c.default.yellow("No branches found."));return}if(!Array.isArray(n)){n.error?console.error(c.default.red(`Error: ${n.error}`)):console.error(c.default.red("Error: Unexpected API response format (not an array)."));return}if(n.length===0){console.log(c.default.yellow("No branches found."));return}let a=[[c.default.bold("Name"),c.default.bold("ID"),c.default.bold("Created By")]];n.forEach(i=>{let p=i.user?.email||i.user?.name||i.createdBy||"-";a.push([i.name,i.id,p])}),console.log((0,te.table)(a))}catch(n){s.fail("Failed to fetch branches"),n.response&&n.response.data&&n.response.data.error?console.error(c.default.red(`Server Error: ${n.response.data.error}`)):console.error(c.default.red(n.message))}});l.command("create").description("Create a new branch").argument("<name>","Branch name").option("-d, --description <text>","Description").action(async(e,t)=>{let r=l.opts(),{project:s}=r,{description:n}=t;s||(s=w().project),s||(console.error(c.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let a=(0,b.default)(`Creating branch '${e}'...`).start();try{await u.createBranch(s,e,n),a.succeed(`Branch '${e}' created successfully.`)}catch(i){a.fail("Failed to create branch"),i.response&&i.response.data&&i.response.data.error?console.error(c.default.red(`Server Error: ${i.response.data.error}`)):console.error(c.default.red(i.message))}});l.command("delete").description("Delete a branch").argument("<name>","Branch name").option("-y, --yes","Skip confirmation prompt",!1).action(async(e,t)=>{let r=l.opts(),{project:s}=r,{yes:n}=t;if(s||(s=w().project),s||(console.error(c.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1)),e==="main"){console.error(c.default.red("Error: Cannot delete the 'main' branch."));return}let a=(0,b.default)("Resolving branch...").start();try{let p=(await u.getBranches(s)).find(d=>d.name===e);if(!p){a.fail(`Branch '${e}' not found.`);return}if(a.stop(),!n){let{confirm:d}=await re.default.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to DELETE branch '${e}'? This action cannot be undone.`,default:!1}]);if(!d){console.log(c.default.gray("Operation cancelled."));return}}a.start("Deleting branch..."),await u.deleteBranch(p.id),a.succeed(`Branch '${e}' deleted successfully.`);try{let{logAudit:d}=(Z(),L(Y));d("BRANCH_DELETED",s,null,{branchName:e,branchId:p.id})}catch{}}catch(i){a.fail("Failed to delete branch"),i.response&&i.response.data&&i.response.data.error?console.error(c.default.red(`Server Error: ${i.response.data.error}`)):console.error(c.default.red(i.message))}});l.command("update").description("Update a branch").argument("<name>","Current branch name").option("-n, --new-name <newName>","New branch name").option("-d, --description <description>","New description").action(async(e,t)=>{let r=l.opts(),{project:s}=r,{newName:n,description:a}=t;if(s||(s=w().project),s||(console.error(c.default.red("Error: Project ID is required. Use -p <id> or checkout a branch.")),process.exit(1)),!n&&!a){console.log(c.default.yellow("No updates specified. Use --new-name or --description."));return}let i=(0,b.default)("Resolving branch...").start();try{let d=(await u.getBranches(s)).find(I=>I.name===e);if(!d){i.fail(`Branch '${e}' not found.`);return}i.text="Updating branch...",await u.updateBranch(d.id,{name:n,description:a}),i.succeed("Branch updated successfully.")}catch(p){i.fail("Failed to update branch"),p.response&&p.response.data&&p.response.data.error?console.error(c.default.red(`Server Error: ${p.response.data.error}`)):console.error(c.default.red(p.message))}});0&&(module.exports={branchCommand});
1
+ var se=Object.create;var j=Object.defineProperty;var ne=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var ae=Object.getPrototypeOf,ce=Object.prototype.hasOwnProperty;var v=(e,r)=>()=>(e&&(r=e(e=0)),r);var D=(e,r)=>{for(var t in r)j(e,t,{get:r[t],enumerable:!0})},N=(e,r,t,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of oe(r))!ce.call(e,n)&&n!==t&&j(e,n,{get:()=>r[n],enumerable:!(s=ne(r,n))||s.enumerable});return e};var g=(e,r,t)=>(t=e!=null?se(ae(e)):{},N(r||!e||!e.__esModule?j(t,"default",{value:e,enumerable:!0}):t,e)),R=e=>N(j({},"__esModule",{value:!0}),e);var O,k,T,I,f,L,y,P,w,x=v(()=>{O=g(require("conf")),k=g(require("fs")),T=g(require("path")),I="https://www.xtrasecurity.in/api",f=new O.default({projectName:"xtra-cli",defaults:{apiUrl:I}}),L=f.get("apiUrl");L&&!process.env.XTRA_API_URL&&L.includes("xtra-security.vercel.app")&&f.set("apiUrl",I);y=()=>({...f.store,apiUrl:process.env.XTRA_API_URL||f.get("apiUrl")||I}),P=()=>f.get("token"),w=()=>{let e={};try{let r=T.default.join(process.cwd(),".xtrarc");k.default.existsSync(r)&&(e=JSON.parse(k.default.readFileSync(r,"utf-8")))}catch{}return{project:e.project||f.get("project")||"",env:e.env||f.get("env")||"development",branch:e.branch||f.get("branch")||"main"}}});var _,F,q,ie,o,u,C=v(()=>{_=g(require("axios"));x();F=g(require("fs")),q=g(require("path")),ie=JSON.parse(F.readFileSync(q.join(__dirname,"../../package.json"),"utf-8")),o=()=>{let{apiUrl:e}=y(),r=P();return _.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":ie.version,...r?{Authorization:`Bearer ${r}`}:{}}})},u={login:async(e,r,t)=>(await o().post("/auth/cli-login",{email:e,password:r,apiKey:t})).data,getSecrets:async(e,r,t="main")=>(await o().get(`/projects/${e}/envs/${r}/secrets?branch=${t}`)).data,getSecretVersions:async(e,r,t="main")=>(await o().get(`/projects/${e}/envs/${r}/secrets?includeVersions=true&branch=${t}`)).data,setSecrets:async(e,r,t,s,n="main")=>(await o().post(`/projects/${e}/envs/${r}/secrets`,{secrets:t,expectedVersions:s,branch:n})).data,getSecretDetails:async(e,r,t,s="main")=>(await o().get(`/projects/${e}/envs/${r}/secrets/${t}?branch=${s}`)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,r,t,s,n,a)=>(await o().post(`/projects/${e}/envs/${r}/secrets/link`,{key:t,sourceProjectId:s,sourceEnv:n,sourceKey:a})).data,rotateSecret:async(e,r,t,s,n)=>(await o().post(`/projects/${e}/envs/${r}/secrets/${t}/rotate`,{strategy:s,parsedNewValue:n})).data,promoteSecret:async(e,r,t)=>(await o().post(`/projects/${e}/envs/${r}/secrets/${t}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,r,t,s)=>{let n={format:e};return r&&(n.startDate=r),t&&(n.endDate=t),s&&(n.projectId=s),(await o().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,r,t,s)=>(await o().post("/access/request",{projectId:e,secretId:s,reason:r,duration:t})).data,approveAccess:async(e,r)=>(await o().post("/access/approve",{requestId:e,decision:r})).data,listAccessRequests:async e=>{let{workspace:r}=y(),t=r?`&workspaceId=${r}`:"";return(await o().get(`/access/list?mode=${e}${t}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=y(),r=e?`/project?workspaceId=${e}`:"/project";return(await o().get(r)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,r,t)=>(await o().post("/branch",{projectId:e,name:r,description:t})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,r)=>(await o().put("/branch",{id:e,...r})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let r=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${r}`)).data},setUserRole:async(e,r,t)=>(await o().put("/admin/users/role",{email:e,role:r,teamId:t})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,r)=>{let t=new URLSearchParams(r).toString();return(await o().get(`/projects/${e}/kubernetes?${t}`)).data},getSecretHistory:async(e,r,t)=>(await o().get(`/projects/${e}/envs/${r}/secrets/${t}/history`)).data,rollbackSecret:async(e,r,t,s)=>(await o().post(`/projects/${e}/envs/${r}/secrets/${t}/history`,{version:s})).data,cloneEnvironment:async(e,r,t,s,n)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:r,toEnv:t,overwrite:s,branch:n})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await o().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,r)=>(await o().post(`/projects/${e}/service-accounts`,r)).data,deleteServiceAccount:async(e,r)=>(await o().delete(`/projects/${e}/service-accounts/${r}`)).data,getServiceAccountKeys:async(e,r)=>(await o().get(`/projects/${e}/service-accounts/${r}/keys`)).data,createServiceAccountKey:async(e,r,t,s)=>(await o().post(`/projects/${e}/service-accounts/${r}/keys`,{label:t,expiresAt:s})).data,deleteServiceAccountKey:async(e,r,t)=>(await o().delete(`/projects/${e}/service-accounts/${r}/keys/${t}`)).data,post:async(e,r)=>(await o().post(e,r)).data}});function H(){let e=J.get("masterKey");e||(e=m.default.randomBytes(32).toString("hex"),J.set("masterKey",e));let r=(0,G.machineIdSync)();return m.default.createHash("sha256").update(e+r).digest()}var m,K,G,V,J,z,M,X=v(()=>{m=g(require("crypto")),K=g(require("conf")),G=require("node-machine-id"),V="aes-256-gcm",J=new K.default({projectName:"xtra-cli-crypto"});z=e=>{let r=m.default.randomBytes(16),t=H(),s=m.default.createCipheriv(V,t,r),n=s.update(e,"utf8","hex");n+=s.final("hex");let a=s.getAuthTag();return{iv:r.toString("hex"),content:n,tag:a.toString("hex")}},M=e=>{let r=H(),t=Buffer.from(e.iv,"hex"),s=Buffer.from(e.tag,"hex"),n=m.default.createDecipheriv(V,r,t);n.setAuthTag(s);let a=n.update(e.content,"hex","utf8");return a+=n.final("utf8"),a}});var Y={};D(Y,{loadAuditLogs:()=>$,logAudit:()=>ge,saveAuditLogs:()=>S,syncAuditLogs:()=>de});function pe(e){if(!e||typeof e!="object")return e;let r={...e},t=["password","token","secret","value","apiKey","secretValue"];for(let s of Object.keys(r))t.some(n=>s.toLowerCase().includes(n))&&(r[s]="[REDACTED]");return r}async function W(e){try{if(!y().token)return!1;let t={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:pe(e.details),timestamp:e.timestamp,projectId:e.projectId};return await u.post("/audit/cli-logs",{logs:[t]}),!0}catch(r){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",r),!1}}function ge(e,r,t,s){let n={id:(0,Q.v4)(),timestamp:new Date().toISOString(),action:e,projectId:r,environment:t,details:s,synced:!1},a=$();a.push(n),S(a),W(n).then(c=>{if(c){n.synced=!0;let p=$(),d=p.findIndex(A=>A.id===n.id);d!==-1&&(p[d].synced=!0,S(p))}}).catch(()=>{})}function $(){if(!h.default.existsSync(E))return[];try{let e=h.default.readFileSync(E,"utf-8"),r=JSON.parse(e),t=M(r);return JSON.parse(t)}catch{return[]}}function S(e){h.default.existsSync(B)||h.default.mkdirSync(B,{recursive:!0});let r=JSON.stringify(e),t=z(r);h.default.writeFileSync(E,JSON.stringify(t),"utf-8")}async function de(){let e=$(),r=e.filter(s=>!s.synced);if(r.length===0)return 0;let t=0;for(let s of r)await W(s)&&(s.synced=!0,t++);return t>0&&S(e),t}var h,U,Q,B,E,Z=v(()=>{h=g(require("fs")),U=g(require("path")),Q=require("uuid");X();x();C();B=U.default.join(process.cwd(),".xtra"),E=U.default.join(B,"audit.enc")});var ue={};D(ue,{branchCommand:()=>l});module.exports=R(ue);var ee=require("commander");C();var i=g(require("chalk")),b=g(require("ora")),re=require("table");x();var te=g(require("inquirer")),l=new ee.Command("branch").description("Manage branches").option("-p, --project <projectId>","Project ID");l.command("list").description("List all branches").action(async e=>{let r=l.opts(),{project:t}=r;t||(t=w().project),t||(console.error(i.default.red("Error: Project ID is required. Use -p <id> or checkout a branch.")),process.exit(1));let s=(0,b.default)("Fetching branches...").start();try{let n=await u.getBranches(t);if(s.stop(),!n){console.log(i.default.yellow("No branches found."));return}if(!Array.isArray(n)){n.error?console.error(i.default.red(`Error: ${n.error}`)):console.error(i.default.red("Error: Unexpected API response format (not an array)."));return}if(n.length===0){console.log(i.default.yellow("No branches found."));return}let a=[[i.default.bold("Name"),i.default.bold("ID"),i.default.bold("Created By")]];n.forEach(c=>{let p=c.user?.email||c.user?.name||c.createdBy||"-";a.push([c.name,c.id,p])}),console.log((0,re.table)(a))}catch(n){s.fail("Failed to fetch branches"),n.response&&n.response.data&&n.response.data.error?console.error(i.default.red(`Server Error: ${n.response.data.error}`)):console.error(i.default.red(n?.response?.data?.error||"An unexpected error occurred"))}});l.command("create").description("Create a new branch").argument("<name>","Branch name").option("-d, --description <text>","Description").action(async(e,r)=>{let t=l.opts(),{project:s}=t,{description:n}=r;s||(s=w().project),s||(console.error(i.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let a=(0,b.default)(`Creating branch '${e}'...`).start();try{await u.createBranch(s,e,n),a.succeed(`Branch '${e}' created successfully.`)}catch(c){a.fail("Failed to create branch"),c.response&&c.response.data&&c.response.data.error?console.error(i.default.red(`Server Error: ${c.response.data.error}`)):console.error(i.default.red(c?.response?.data?.error||"An unexpected error occurred"))}});l.command("delete").description("Delete a branch").argument("<name>","Branch name").option("-y, --yes","Skip confirmation prompt",!1).action(async(e,r)=>{let t=l.opts(),{project:s}=t,{yes:n}=r;if(s||(s=w().project),s||(console.error(i.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1)),e==="main"){console.error(i.default.red("Error: Cannot delete the 'main' branch."));return}let a=(0,b.default)("Resolving branch...").start();try{let p=(await u.getBranches(s)).find(d=>d.name===e);if(!p){a.fail(`Branch '${e}' not found.`);return}if(a.stop(),!n){let{confirm:d}=await te.default.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to DELETE branch '${e}'? This action cannot be undone.`,default:!1}]);if(!d){console.log(i.default.gray("Operation cancelled."));return}}a.start("Deleting branch..."),await u.deleteBranch(p.id),a.succeed(`Branch '${e}' deleted successfully.`);try{let{logAudit:d}=(Z(),R(Y));d("BRANCH_DELETED",s,null,{branchName:e,branchId:p.id})}catch{}}catch(c){a.fail("Failed to delete branch"),c.response&&c.response.data&&c.response.data.error?console.error(i.default.red(`Server Error: ${c.response.data.error}`)):console.error(i.default.red(c?.response?.data?.error||"An unexpected error occurred"))}});l.command("update").description("Update a branch").argument("<name>","Current branch name").option("-n, --new-name <newName>","New branch name").option("-d, --description <description>","New description").action(async(e,r)=>{let t=l.opts(),{project:s}=t,{newName:n,description:a}=r;if(s||(s=w().project),s||(console.error(i.default.red("Error: Project ID is required. Use -p <id> or checkout a branch.")),process.exit(1)),!n&&!a){console.log(i.default.yellow("No updates specified. Use --new-name or --description."));return}let c=(0,b.default)("Resolving branch...").start();try{let d=(await u.getBranches(s)).find(A=>A.name===e);if(!d){c.fail(`Branch '${e}' not found.`);return}c.text="Updating branch...",await u.updateBranch(d.id,{name:n,description:a}),c.succeed("Branch updated successfully.")}catch(p){c.fail("Failed to update branch"),p.response&&p.response.data&&p.response.data.error?console.error(i.default.red(`Server Error: ${p.response.data.error}`)):console.error(i.default.red(p?.response?.data?.error||"An unexpected error occurred"))}});0&&(module.exports={branchCommand});
@@ -1 +1 @@
1
- var P=Object.create;var d=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var N=(e,t)=>{for(var s in t)d(e,s,{get:t[s],enumerable:!0})},$=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of L(t))!q.call(e,o)&&o!==s&&d(e,o,{get:()=>t[o],enumerable:!(n=B(t,o))||n.enumerable});return e};var c=(e,t,s)=>(s=e!=null?P(_(e)):{},$(t||!e||!e.__esModule?d(s,"default",{value:e,enumerable:!0}):s,e)),T=e=>$(d({},"__esModule",{value:!0}),e);var J={};N(J,{checkoutCommand:()=>D});module.exports=T(J);var U=require("commander");var x=c(require("axios"));var j=c(require("conf")),g=c(require("fs")),b=c(require("path")),f="https://www.xtrasecurity.in/api",i=new j.default({projectName:"xtra-cli",defaults:{apiUrl:f}}),h=i.get("apiUrl");h&&!process.env.XTRA_API_URL&&(h.includes("localhost")||h.includes("xtra-security.vercel.app"))&&i.set("apiUrl",f);var l=()=>({...i.store,apiUrl:process.env.XTRA_API_URL||i.get("apiUrl")||f});var u=(e,t)=>{if(i.set(e,t),e==="token"&&process.platform!=="win32"&&g.default.existsSync(i.path))try{g.default.chmodSync(i.path,384)}catch{}};var v=()=>i.get("token");var S=()=>{let e={};try{let t=b.default.join(process.cwd(),".xtrarc");g.default.existsSync(t)&&(e=JSON.parse(g.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||i.get("project")||"",env:e.env||i.get("env")||"development",branch:e.branch||i.get("branch")||"main"}};var k=c(require("fs")),I=c(require("path")),G=JSON.parse(k.readFileSync(I.join(__dirname,"../../package.json"),"utf-8")),r=()=>{let{apiUrl:e}=l(),t=v();return x.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":G.version,...t?{Authorization:`Bearer ${t}`}:{}}})},C={login:async(e,t,s)=>(await r().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,n,o="main")=>(await r().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:n,branch:o})).data,getSecretDetails:async(e,t,s,n="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${n}`)).data,syncLogs:async e=>(await r().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,n,o,a)=>(await r().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:o,sourceKey:a})).data,rotateSecret:async(e,t,s,n,o)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:n,parsedNewValue:o})).data,promoteSecret:async(e,t,s)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await r().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,n)=>{let o={format:e};return t&&(o.startDate=t),s&&(o.endDate=s),n&&(o.projectId=n),(await r().post("/audit/export",o,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,n)=>(await r().post("/access/request",{projectId:e,secretId:n,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await r().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=l(),s=t?`&workspaceId=${t}`:"";return(await r().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await r().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=l(),t=e?`/project?workspaceId=${e}`:"/project";return(await r().get(t)).data},getBranches:async e=>(await r().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await r().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await r().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await r().put("/branch",{id:e,...t})).data,getRoles:async()=>(await r().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await r().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await r().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await r().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await r().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await r().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await r().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await r().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,n)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:n})).data,cloneEnvironment:async(e,t,s,n,o)=>(await r().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:n,branch:o})).data,generateJitLink:async e=>(await r().post("/jit/generate",e)).data,claimJitLink:async e=>(await r().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await r().get(`/jit/${e}`)).data,post:async(e,t)=>(await r().post(e,t)).data};var p=c(require("chalk")),A=c(require("ora")),R=c(require("inquirer")),D=new U.Command("checkout").description("Switch the active branch context").argument("[branchName]","Branch name to switch to (optional - will show list if not provided)").option("-p, --project <projectId>","Project ID").option("-e, --env <environment>","Set the active environment (e.g. development, staging, production)").action(async(e,t)=>{let{project:s}=t;s||(s=S().project),s||(console.error(p.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let n=(0,A.default)("Fetching branches...").start();try{let o=await C.getBranches(s);if(n.stop(),!Array.isArray(o)||o.length===0){console.log(p.default.yellow("No branches found in this project."));return}let a=e;if(a){if(!o.find(y=>y.name===a)){console.error(p.default.red(`Branch '${a}' does not exist.`)),console.log(p.default.yellow(`Use 'xtra branch create ${a}' to create it.`));return}}else{let m=o.map(w=>({name:w.name,value:w.name})),{selected:y}=await R.default.prompt([{type:"list",name:"selected",message:"Select a branch:",choices:m}]);a=y}u("branch",a),u("project",s),t.env&&u("env",t.env),console.log(p.default.green(`\u2714 Switched to branch '${a}'`)),t.env&&console.log(p.default.green(`\u2714 Environment set to '${t.env}'`))}catch(o){n.fail("Failed to fetch branches"),o.response?.data?.error?console.error(p.default.red(`Error: ${o.response.data.error}`)):console.error(p.default.red(o.message))}});0&&(module.exports={checkoutCommand});
1
+ var P=Object.create;var d=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var N=(e,t)=>{for(var s in t)d(e,s,{get:t[s],enumerable:!0})},w=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of L(t))!q.call(e,o)&&o!==s&&d(e,o,{get:()=>t[o],enumerable:!(n=B(t,o))||n.enumerable});return e};var i=(e,t,s)=>(s=e!=null?P(_(e)):{},w(t||!e||!e.__esModule?d(s,"default",{value:e,enumerable:!0}):s,e)),T=e=>w(d({},"__esModule",{value:!0}),e);var J={};N(J,{checkoutCommand:()=>D});module.exports=T(J);var C=require("commander");var x=i(require("axios"));var v=i(require("conf")),g=i(require("fs")),S=i(require("path")),h="https://www.xtrasecurity.in/api",c=new v.default({projectName:"xtra-cli",defaults:{apiUrl:h}}),$=c.get("apiUrl");$&&!process.env.XTRA_API_URL&&$.includes("xtra-security.vercel.app")&&c.set("apiUrl",h);var u=()=>({...c.store,apiUrl:process.env.XTRA_API_URL||c.get("apiUrl")||h});var l=(e,t)=>{if(c.set(e,t),e==="token"&&process.platform!=="win32"&&g.default.existsSync(c.path))try{g.default.chmodSync(c.path,384)}catch{}};var j=()=>c.get("token");var b=()=>{let e={};try{let t=S.default.join(process.cwd(),".xtrarc");g.default.existsSync(t)&&(e=JSON.parse(g.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||c.get("project")||"",env:e.env||c.get("env")||"development",branch:e.branch||c.get("branch")||"main"}};var k=i(require("fs")),A=i(require("path")),G=JSON.parse(k.readFileSync(A.join(__dirname,"../../package.json"),"utf-8")),r=()=>{let{apiUrl:e}=u(),t=j();return x.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":G.version,...t?{Authorization:`Bearer ${t}`}:{}}})},I={login:async(e,t,s)=>(await r().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,n,o="main")=>(await r().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:n,branch:o})).data,getSecretDetails:async(e,t,s,n="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${n}`)).data,syncLogs:async e=>(await r().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,n,o,a)=>(await r().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:o,sourceKey:a})).data,rotateSecret:async(e,t,s,n,o)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:n,parsedNewValue:o})).data,promoteSecret:async(e,t,s)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await r().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,n)=>{let o={format:e};return t&&(o.startDate=t),s&&(o.endDate=s),n&&(o.projectId=n),(await r().post("/audit/export",o,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,n)=>(await r().post("/access/request",{projectId:e,secretId:n,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await r().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=u(),s=t?`&workspaceId=${t}`:"";return(await r().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await r().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=u(),t=e?`/project?workspaceId=${e}`:"/project";return(await r().get(t)).data},getBranches:async e=>(await r().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await r().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await r().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await r().put("/branch",{id:e,...t})).data,getRoles:async()=>(await r().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await r().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await r().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await r().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await r().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await r().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await r().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await r().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,n)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:n})).data,cloneEnvironment:async(e,t,s,n,o)=>(await r().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:n,branch:o})).data,generateJitLink:async e=>(await r().post("/jit/generate",e)).data,claimJitLink:async e=>(await r().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await r().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await r().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await r().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await r().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await r().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,s,n)=>(await r().post(`/projects/${e}/service-accounts/${t}/keys`,{label:s,expiresAt:n})).data,deleteServiceAccountKey:async(e,t,s)=>(await r().delete(`/projects/${e}/service-accounts/${t}/keys/${s}`)).data,post:async(e,t)=>(await r().post(e,t)).data};var p=i(require("chalk")),U=i(require("ora")),R=i(require("inquirer")),D=new C.Command("checkout").description("Switch the active branch context").argument("[branchName]","Branch name to switch to (optional - will show list if not provided)").option("-p, --project <projectId>","Project ID").option("-e, --env <environment>","Set the active environment (e.g. development, staging, production)").action(async(e,t)=>{let{project:s}=t;s||(s=b().project),s||(console.error(p.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let n=(0,U.default)("Fetching branches...").start();try{let o=await I.getBranches(s);if(n.stop(),!Array.isArray(o)||o.length===0){console.log(p.default.yellow("No branches found in this project."));return}let a=e;if(a){if(!o.find(m=>m.name===a)){console.error(p.default.red(`Branch '${a}' does not exist.`)),console.log(p.default.yellow(`Use 'xtra branch create ${a}' to create it.`));return}}else{let y=o.map(f=>({name:f.name,value:f.name})),{selected:m}=await R.default.prompt([{type:"list",name:"selected",message:"Select a branch:",choices:y}]);a=m}l("branch",a),l("project",s),t.env&&l("env",t.env),console.log(p.default.green(`\u2714 Switched to branch '${a}'`)),t.env&&console.log(p.default.green(`\u2714 Environment set to '${t.env}'`))}catch(o){n.fail("Failed to fetch branches"),o.response?.data?.error?console.error(p.default.red(`Error: ${o.response.data.error}`)):console.error(p.default.red(o?.response?.data?.error||"An unexpected error occurred"))}});0&&(module.exports={checkoutCommand});
@@ -1,6 +1,6 @@
1
- var $=Object.create;var E=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var X=Object.getOwnPropertyNames;var H=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var M=(e,t)=>{for(var n in t)E(e,n,{get:t[n],enumerable:!0})},N=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of X(t))!L.call(e,a)&&a!==n&&E(e,a,{get:()=>t[a],enumerable:!(i=K(t,a))||i.enumerable});return e};var h=(e,t,n)=>(n=e!=null?$(H(e)):{},N(t||!e||!e.__esModule?E(n,"default",{value:e,enumerable:!0}):n,e)),P=e=>N(E({},"__esModule",{value:!0}),e);var F={};M(F,{ciCommand:()=>g});module.exports=P(F);var R=require("commander"),S=require("child_process"),w=h(require("axios")),U=h(require("fs"));var O=h(require("conf")),k=h(require("fs")),T=h(require("path")),I="https://www.xtrasecurity.in/api",v=new O.default({projectName:"xtra-cli",defaults:{apiUrl:I}}),x=v.get("apiUrl");x&&!process.env.XTRA_API_URL&&(x.includes("localhost")||x.includes("xtra-security.vercel.app"))&&v.set("apiUrl",I);var b=()=>{let e={};try{let t=T.default.join(process.cwd(),".xtrarc");k.default.existsSync(t)&&(e=JSON.parse(k.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||v.get("project")||"",env:e.env||v.get("env")||"development",branch:e.branch||v.get("branch")||"main"}};function j(){let e=process.env.XTRA_MACHINE_TOKEN,t=process.env.XTRA_API_URL||"https://www.xtrasecurity.in/api";return e||o("XTRA_MACHINE_TOKEN environment variable is required for CI mode."),w.default.create({baseURL:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`,"X-CI-Mode":"true"}})}function o(e,t){process.stderr.write(JSON.stringify({ok:!1,error:e,detail:t||null},null,2)+`
2
- `),process.exit(1)}function C(e){process.stdout.write(JSON.stringify(e,null,2)+`
3
- `)}function y(){process.env.XTRA_MACHINE_TOKEN||o("XTRA_MACHINE_TOKEN is not set. Export it before running CI commands.",{hint:"export XTRA_MACHINE_TOKEN=your_service_account_token"})}function _(e){return e||o("--project <id> is required in CI mode. Set it explicitly (no config fallback)."),e}function A(e){return e||o("--env <environment> is required in CI mode."),e}var g=new R.Command("ci").description("CI/CD headless mode \u2014 JSON output, no prompts, XTRA_MACHINE_TOKEN auth").addHelpText("after",`
1
+ var S=Object.create;var y=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var K=Object.getPrototypeOf,X=Object.prototype.hasOwnProperty;var P=(e,t)=>{for(var r in t)y(e,r,{get:t[r],enumerable:!0})},_=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of $(t))!X.call(e,o)&&o!==r&&y(e,o,{get:()=>t[o],enumerable:!(a=U(t,o))||a.enumerable});return e};var v=(e,t,r)=>(r=e!=null?S(K(e)):{},_(t||!e||!e.__esModule?y(r,"default",{value:e,enumerable:!0}):r,e)),M=e=>_(y({},"__esModule",{value:!0}),e);var L={};P(L,{ciCommand:()=>h});module.exports=M(L);var T=require("commander"),I=require("child_process"),R=v(require("axios")),w=v(require("fs"));var C=v(require("conf")),A=v(require("fs")),O=v(require("path")),N="https://www.xtrasecurity.in/api",b=new C.default({projectName:"xtra-cli",defaults:{apiUrl:N}}),k=b.get("apiUrl");k&&!process.env.XTRA_API_URL&&k.includes("xtra-security.vercel.app")&&b.set("apiUrl",N);var d=()=>{let e={};try{let t=O.default.join(process.cwd(),".xtrarc");A.default.existsSync(t)&&(e=JSON.parse(A.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||b.get("project")||"",env:e.env||b.get("env")||"development",branch:e.branch||b.get("branch")||"main"}};function g(){let e=process.env.XTRA_MACHINE_TOKEN,t=process.env.XTRA_API_URL||"https://www.xtrasecurity.in/api";return e||c("XTRA_MACHINE_TOKEN environment variable is required for CI mode."),R.default.create({baseURL:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`,"X-CI-Mode":"true"}})}function c(e,t){process.stderr.write(JSON.stringify({ok:!1,error:e,detail:t||null},null,2)+`
2
+ `),process.exit(1)}function x(e){process.stdout.write(JSON.stringify(e,null,2)+`
3
+ `)}function H(){process.env.XTRA_MACHINE_TOKEN||c("XTRA_MACHINE_TOKEN is not set. Export it before running CI commands.",{hint:"export XTRA_MACHINE_TOKEN=your_service_account_token"})}async function j(e){if(e)return e;try{let a=await g().get("/service-account/resolve");if(a.data&&a.data.project)return a.data.project.id}catch{}let t=d();if(t.project)return t.project;c("--project <id> is required. Set it explicitly or ensure your token is linked to a project.")}function E(e){return e||c("--env <environment> is required in CI mode."),e}var h=new T.Command("ci").description("CI/CD headless mode \u2014 JSON output, no prompts, XTRA_MACHINE_TOKEN auth").addHelpText("after",`
4
4
  Environment Variables:
5
5
  XTRA_MACHINE_TOKEN Required. Service account token for authentication.
6
6
  XTRA_API_URL Optional. Override the API base URL.
@@ -20,12 +20,12 @@ Examples:
20
20
  XTRA_MACHINE_TOKEN=tok_... xtra ci secrets -p proj123 -e production
21
21
  XTRA_MACHINE_TOKEN=tok_... xtra ci set -p proj123 -e staging DEPLOY_VERSION=1.2.3
22
22
  XTRA_MACHINE_TOKEN=tok_... xtra ci run -- node app.js
23
- `);g.command("secrets").description("Fetch secrets as JSON (pipe-friendly)").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment").option("-b, --branch <branch>","Branch name").option("--keys <keys>","Comma-separated list of keys to include (default: all)").action(async e=>{y();let t=b(),n=_(e.project||t.project),i=A(e.env||t.env),a=e.branch||t.branch||"main";try{let s=(await j().get(`/projects/${n}/envs/${i}/secrets?branch=${a}`)).data;if(e.keys){let c=e.keys.split(",").map(p=>p.trim()),l={};for(let p of c)s[p]!==void 0?l[p]=s[p]:process.stderr.write(`Warning: key '${p}' not found
24
- `);s=l}C({ok:!0,project:n,env:i,branch:e.branch,secrets:s})}catch(d){let r=d?.response?.status,s=d?.response?.data?.error||d.message;r===401&&o("Unauthorized. Check your XTRA_MACHINE_TOKEN.",{status:r}),r===403&&o("Forbidden. This token lacks permission to read secrets.",{status:r}),r===404&&o(`Project '${n}' or environment '${i}' not found.`,{status:r}),o(s,{status:r})}});g.command("set").description("Set one or more secrets in CI mode (KEY=VALUE ...)").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment").option("-b, --branch <branch>","Branch name").argument("<secrets...>","Secrets to set (format: KEY=VALUE)").action(async(e,t)=>{y();let n=b(),i=_(t.project||n.project),a=A(t.env||n.env),d=t.branch||n.branch||"main",r={};for(let s of e){let c=s.indexOf("=");c===-1&&o(`Invalid format: '${s}'. Expected KEY=VALUE`),r[s.substring(0,c)]=s.substring(c+1)}Object.keys(r).length===0&&o("No valid KEY=VALUE pairs provided.");try{await j().post(`/projects/${i}/envs/${a}/secrets`,{secrets:r,branch:d}),C({ok:!0,project:i,env:a,branch:d,updated:Object.keys(r),count:Object.keys(r).length})}catch(s){let c=s?.response?.status;o(s?.response?.data?.error||s.message,{status:c})}});g.command("export").description("Export secrets to a file (dotenv, json, or github-actions format)").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment").option("-b, --branch <branch>","Branch name").option("-f, --format <format>","Output format: dotenv | json | github","dotenv").option("-o, --output <file>","Output file path (default: stdout)").action(async e=>{y();let t=b(),n=_(e.project||t.project),i=A(e.env||t.env),a=e.branch||t.branch||"main",{format:d,output:r}=e,s=["dotenv","json","github"];s.includes(d)||o(`Invalid format '${d}'. Must be one of: ${s.join(", ")}`);try{let p=(await j().get(`/projects/${n}/envs/${i}/secrets?branch=${a}`)).data,m;switch(d){case"dotenv":m=Object.entries(p).map(([u,f])=>`${u}=${f}`).join(`
23
+ `);h.command("secrets").description("Fetch secrets as JSON (pipe-friendly)").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment").option("-b, --branch <branch>","Branch name").option("--keys <keys>","Comma-separated list of keys to include (default: all)").action(async e=>{let t=await j(e.project),r=E(e.env||d().env),a=e.branch||d().branch||"main";try{let n=(await g().get(`/projects/${t}/envs/${r}/secrets?branch=${a}`)).data;if(e.keys){let i=e.keys.split(",").map(p=>p.trim()),l={};for(let p of i)n[p]!==void 0?l[p]=n[p]:process.stderr.write(`Warning: key '${p}' not found
24
+ `);n=l}x({ok:!0,project:t,env:r,branch:e.branch,secrets:n})}catch(o){let s=o?.response?.status,n=o?.response?.data?.error||o?.response?.data?.error||"An unexpected error occurred";s===401&&c("Unauthorized. Check your XTRA_MACHINE_TOKEN.",{status:s}),s===403&&c("Forbidden. This token lacks permission to read secrets.",{status:s}),s===404&&c(`Project '${t}' or environment '${r}' not found.`,{status:s}),c(n,{status:s})}});h.command("set").description("Set one or more secrets in CI mode (KEY=VALUE ...)").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment").option("-b, --branch <branch>","Branch name").argument("<secrets...>","Secrets to set (format: KEY=VALUE)").action(async(e,t)=>{let r=await j(t.project),a=E(t.env||d().env),o=t.branch||d().branch||"main",s={};for(let n of e){let i=n.indexOf("=");i===-1&&c(`Invalid format: '${n}'. Expected KEY=VALUE`),s[n.substring(0,i)]=n.substring(i+1)}Object.keys(s).length===0&&c("No valid KEY=VALUE pairs provided.");try{await g().post(`/projects/${r}/envs/${a}/secrets`,{secrets:s,branch:o}),x({ok:!0,project:r,env:a,branch:o,updated:Object.keys(s),count:Object.keys(s).length})}catch(n){let i=n?.response?.status;c(n?.response?.data?.error||n?.response?.data?.error||"An unexpected error occurred",{status:i})}});h.command("export").description("Export secrets to a file (dotenv, json, or github-actions format)").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment").option("-b, --branch <branch>","Branch name").option("-f, --format <format>","Output format: dotenv | json | github","dotenv").option("-o, --output <file>","Output file path (default: stdout)").action(async e=>{let t=await j(e.project),r=E(e.env||d().env),a=e.branch||d().branch||"main",{format:o,output:s}=e,n=["dotenv","json","github"];n.includes(o)||c(`Invalid format '${o}'. Must be one of: ${n.join(", ")}`);try{let p=(await g().get(`/projects/${t}/envs/${r}/secrets?branch=${a}`)).data,u;switch(o){case"dotenv":u=Object.entries(p).map(([m,f])=>`${m}=${f}`).join(`
25
25
  `)+`
26
- `;break;case"json":m=JSON.stringify(p,null,2)+`
27
- `;break;case"github":m=Object.entries(p).map(([u,f])=>`${u}=${f}`).join(`
26
+ `;break;case"json":u=JSON.stringify(p,null,2)+`
27
+ `;break;case"github":u=Object.entries(p).map(([m,f])=>`${m}=${f}`).join(`
28
28
  `)+`
29
- `;break;default:o("Unreachable format error.")}r?(U.writeFileSync(r,m,"utf8"),process.stderr.write(JSON.stringify({ok:!0,file:r,keys:Object.keys(p).length})+`
30
- `)):process.stdout.write(m)}catch(c){let l=c?.response?.status;o(c?.response?.data?.error||c.message,{status:l})}});g.command("run").description("Run a command with secrets injected as environment variables").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment").option("-b, --branch <branch>","Branch name").argument("<command>","Command to execute").argument("[args...]","Command arguments").action(async(e,t,n)=>{y();let i=b(),a=_(n.project||i.project),d=A(n.env||i.env),r=n.branch||i.branch||"main";/[;&|`$<>\\\n]/g.test(e)&&o("Command contains unsafe characters. Aborting for security.");try{let p=(await j().get(`/projects/${a}/envs/${d}/secrets?branch=${r}`)).data;process.stderr.write(`[xtra ci] Injecting ${Object.keys(p).length} secrets into process env
31
- `);let m={...process.env,...p},u=(0,S.spawn)(e,t,{env:m,stdio:"inherit",shell:!1});u.on("exit",f=>process.exit(f??0)),u.on("error",f=>o(`Failed to start process: ${f.message}`))}catch(c){let l=c?.response?.status;o(c?.response?.data?.error||c.message,{status:l})}});g.command("validate").description("Validate that XTRA_MACHINE_TOKEN is set and working").action(async()=>{y();try{let t=await j().get("/project");C({ok:!0,authenticated:!0,projects:t.data.length,message:"XTRA_MACHINE_TOKEN is valid and working."})}catch(e){let t=e?.response?.status;t===401&&o("XTRA_MACHINE_TOKEN is invalid or expired.",{status:t}),o(e?.response?.data?.error||e.message,{status:t})}});0&&(module.exports={ciCommand});
29
+ `;break;default:c("Unreachable format error.")}s?(w.writeFileSync(s,u,"utf8"),process.stderr.write(JSON.stringify({ok:!0,file:s,keys:Object.keys(p).length})+`
30
+ `)):process.stdout.write(u)}catch(i){let l=i?.response?.status;c(i?.response?.data?.error||i?.response?.data?.error||"An unexpected error occurred",{status:l})}});h.command("run").description("Run a command with secrets injected as environment variables").option("-p, --project <id>","Project ID").option("--env <environment>","Environment").option("-b, --branch <branch>","Branch name").option("--shell","Run command inside a shell (required for npm on Windows)").argument("<command>","Command to execute").argument("[args...]","Command arguments").action(async(e,t,r)=>{let a=await j(r.project),o=E(r.env||d().env),s=r.branch||d().branch||"main",n=/[;&|`$<>\\\n]/g;!r.shell&&n.test(e)&&c("Command contains unsafe characters. Aborting for security. Use --shell if intended.");try{let p=(await g().get(`/projects/${a}/envs/${o}/secrets?branch=${s}`)).data;process.stderr.write(`[xtra ci] Injecting ${Object.keys(p).length} secrets into process env
31
+ `);let u={...process.env,...p},m=(0,I.spawn)(e,t,{env:u,stdio:"inherit",shell:r.shell||!1});m.on("exit",f=>process.exit(f??0)),m.on("error",f=>c(`Failed to start process: ${f.message}`))}catch(i){let l=i?.response?.status;c(i?.response?.data?.error||i?.response?.data?.error||"An unexpected error occurred",{status:l})}});h.command("validate").description("Validate that XTRA_MACHINE_TOKEN is set and working").action(async()=>{H();try{let t=await g().get("/project");x({ok:!0,authenticated:!0,projects:t.data.length,message:"XTRA_MACHINE_TOKEN is valid and working."})}catch(e){let t=e?.response?.status;t===401&&c("XTRA_MACHINE_TOKEN is invalid or expired.",{status:t}),c(e?.response?.data?.error||e?.response?.data?.error||"An unexpected error occurred",{status:t})}});0&&(module.exports={ciCommand});
@@ -1,6 +1,6 @@
1
- var J=Object.create;var h=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var H=Object.getPrototypeOf,M=Object.prototype.hasOwnProperty;var X=(e,t)=>{for(var s in t)h(e,s,{get:t[s],enumerable:!0})},C=(e,t,s,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of V(t))!M.call(e,o)&&o!==s&&h(e,o,{get:()=>t[o],enumerable:!(r=K(t,o))||r.enumerable});return e};var c=(e,t,s)=>(s=e!=null?J(H(e)):{},C(t||!e||!e.__esModule?h(s,"default",{value:e,enumerable:!0}):s,e)),z=e=>C(h({},"__esModule",{value:!0}),e);var ee={};X(ee,{diffCommand:()=>Z});module.exports=z(ee);var q=require("commander");var P=c(require("axios"));var R=c(require("conf")),j=c(require("fs")),B=c(require("path")),b="https://www.xtrasecurity.in/api",l=new R.default({projectName:"xtra-cli",defaults:{apiUrl:b}}),S=l.get("apiUrl");S&&!process.env.XTRA_API_URL&&(S.includes("localhost")||S.includes("xtra-security.vercel.app"))&&l.set("apiUrl",b);var v=()=>({...l.store,apiUrl:process.env.XTRA_API_URL||l.get("apiUrl")||b}),U=e=>l.get(e);var A=()=>l.get("token");var x=()=>{let e={};try{let t=B.default.join(process.cwd(),".xtrarc");j.default.existsSync(t)&&(e=JSON.parse(j.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||l.get("project")||"",env:e.env||l.get("env")||"development",branch:e.branch||l.get("branch")||"main"}};var L=c(require("fs")),T=c(require("path")),Q=JSON.parse(L.readFileSync(T.join(__dirname,"../../package.json"),"utf-8")),n=()=>{let{apiUrl:e}=v(),t=A();return P.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":Q.version,...t?{Authorization:`Bearer ${t}`}:{}}})},$={login:async(e,t,s)=>(await n().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await n().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await n().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,r,o="main")=>(await n().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:r,branch:o})).data,getSecretDetails:async(e,t,s,r="main")=>(await n().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${r}`)).data,syncLogs:async e=>(await n().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,r,o,a)=>(await n().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:r,sourceEnv:o,sourceKey:a})).data,rotateSecret:async(e,t,s,r,o)=>(await n().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:r,parsedNewValue:o})).data,promoteSecret:async(e,t,s)=>(await n().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await n().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,r)=>{let o={format:e};return t&&(o.startDate=t),s&&(o.endDate=s),r&&(o.projectId=r),(await n().post("/audit/export",o,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,r)=>(await n().post("/access/request",{projectId:e,secretId:r,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await n().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=v(),s=t?`&workspaceId=${t}`:"";return(await n().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await n().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=v(),t=e?`/project?workspaceId=${e}`:"/project";return(await n().get(t)).data},getBranches:async e=>(await n().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await n().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await n().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await n().put("/branch",{id:e,...t})).data,getRoles:async()=>(await n().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await n().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await n().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await n().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await n().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await n().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await n().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await n().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,r)=>(await n().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:r})).data,cloneEnvironment:async(e,t,s,r,o)=>(await n().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:r,branch:o})).data,generateJitLink:async e=>(await n().post("/jit/generate",e)).data,claimJitLink:async e=>(await n().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await n().get(`/jit/${e}`)).data,post:async(e,t)=>(await n().post(e,t)).data};var i=c(require("chalk")),k=c(require("ora"));var w=c(require("crypto")),O=c(require("conf")),_=require("node-machine-id"),W="aes-256-gcm",N=new O.default({projectName:"xtra-cli-crypto"});function Y(){let e=N.get("masterKey");e||(e=w.default.randomBytes(32).toString("hex"),N.set("masterKey",e));let t=(0,_.machineIdSync)();return w.default.createHash("sha256").update(e+t).digest()}var D=e=>{let t=Y(),s=Buffer.from(e.iv,"hex"),r=Buffer.from(e.tag,"hex"),o=w.default.createDecipheriv(W,t,s);o.setAuthTag(r);let a=o.update(e.content,"hex","utf8");return a+=o.final("utf8"),a};var F=c(require("diff")),Z=new q.Command("diff").description("Show differences between local cache and remote secrets").argument("[env1]","Source Environment").argument("[env2]","Target Environment").option("-p, --project <projectId>","Project ID").option("-e, --env <environment>","Environment (dev, stg, prod)","dev").option("-b, --branch <branchName>","Branch Name").option("--show","Show actual value differences (sensitive)",!1).action(async(e,t,s)=>{let{project:r,env:o,branch:a,show:f}=s;r||(r=x().project),a||(a=x().branch||"main"),r||(console.error(i.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let u={dev:"development",stg:"staging",prod:"production"};if(e&&t){let g=u[e]||e,d=u[t]||t,p=(0,k.default)(`Fetching secrets for ${g} and ${d} (branch: ${a})...`).start();try{let[m,y]=await Promise.all([$.getSecrets(r,g,a),$.getSecrets(r,d,a)]);p.stop(),console.log(i.default.bold(`
2
- Diff Report (${g} <-> ${d} @ ${a}):
3
- `)),E(m,y,f)}catch(m){p.fail("Failed to fetch secrets"),console.error(i.default.red(m.message))}}else{let g=u[o]||o,d=(0,k.default)(`Fetching remote state for ${g} (branch: ${a})...`).start();try{let p=await $.getSecrets(r,g,a),m={};try{let y=`cache.${r}.${g}.${a}`,I=U(y);if(I){let G=D(I);m=JSON.parse(G)}}catch{}d.stop(),console.log(i.default.bold(`
4
- Diff Report (Remote ${g} vs Local Cache):
5
- `)),E(p,m,f)}catch(p){d.fail("Failed to run diff."),console.error(i.default.red(p.message))}}});function E(e,t,s){let r=new Set([...Object.keys(e),...Object.keys(t)]),o=!1;r.forEach(a=>{let f=e[a],u=t[a];if(f!==u){if(o=!0,f===void 0)console.log(i.default.green(`+ ${a} (Only in Target)`)),s&&console.log(i.default.green(` + "${u}"`));else if(u===void 0)console.log(i.default.red(`- ${a} (Only in Source)`)),s&&console.log(i.default.red(` - "${f}"`));else if(console.log(i.default.yellow(`~ ${a} (Modified)`)),s){let g=F.diffChars(f,u),d=" ";g.forEach(p=>{let m=p.added?i.default.green:p.removed?i.default.red:i.default.gray;d+=m(p.value)}),console.log(d)}}}),o?s||console.log(i.default.gray(`
6
- (Use --show to reveal secret values)`)):console.log(i.default.green("\u2714 No differences found."))}0&&(module.exports={diffCommand});
1
+ var G=Object.create;var h=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var H=Object.getPrototypeOf,M=Object.prototype.hasOwnProperty;var X=(e,t)=>{for(var s in t)h(e,s,{get:t[s],enumerable:!0})},A=(e,t,s,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of V(t))!M.call(e,o)&&o!==s&&h(e,o,{get:()=>t[o],enumerable:!(r=J(t,o))||r.enumerable});return e};var i=(e,t,s)=>(s=e!=null?G(H(e)):{},A(t||!e||!e.__esModule?h(s,"default",{value:e,enumerable:!0}):s,e)),z=e=>A(h({},"__esModule",{value:!0}),e);var ee={};X(ee,{diffCommand:()=>Z});module.exports=z(ee);var K=require("commander");var P=i(require("axios"));var C=i(require("conf")),S=i(require("fs")),B=i(require("path")),j="https://www.xtrasecurity.in/api",u=new C.default({projectName:"xtra-cli",defaults:{apiUrl:j}}),I=u.get("apiUrl");I&&!process.env.XTRA_API_URL&&I.includes("xtra-security.vercel.app")&&u.set("apiUrl",j);var v=()=>({...u.store,apiUrl:process.env.XTRA_API_URL||u.get("apiUrl")||j}),R=e=>u.get(e);var U=()=>u.get("token");var x=()=>{let e={};try{let t=B.default.join(process.cwd(),".xtrarc");S.default.existsSync(t)&&(e=JSON.parse(S.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||u.get("project")||"",env:e.env||u.get("env")||"development",branch:e.branch||u.get("branch")||"main"}};var L=i(require("fs")),T=i(require("path")),Q=JSON.parse(L.readFileSync(T.join(__dirname,"../../package.json"),"utf-8")),n=()=>{let{apiUrl:e}=v(),t=U();return P.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":Q.version,...t?{Authorization:`Bearer ${t}`}:{}}})},$={login:async(e,t,s)=>(await n().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await n().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await n().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,r,o="main")=>(await n().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:r,branch:o})).data,getSecretDetails:async(e,t,s,r="main")=>(await n().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${r}`)).data,syncLogs:async e=>(await n().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,r,o,a)=>(await n().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:r,sourceEnv:o,sourceKey:a})).data,rotateSecret:async(e,t,s,r,o)=>(await n().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:r,parsedNewValue:o})).data,promoteSecret:async(e,t,s)=>(await n().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await n().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,r)=>{let o={format:e};return t&&(o.startDate=t),s&&(o.endDate=s),r&&(o.projectId=r),(await n().post("/audit/export",o,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,r)=>(await n().post("/access/request",{projectId:e,secretId:r,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await n().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=v(),s=t?`&workspaceId=${t}`:"";return(await n().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await n().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=v(),t=e?`/project?workspaceId=${e}`:"/project";return(await n().get(t)).data},getBranches:async e=>(await n().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await n().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await n().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await n().put("/branch",{id:e,...t})).data,getRoles:async()=>(await n().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await n().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await n().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await n().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await n().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await n().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await n().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await n().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,r)=>(await n().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:r})).data,cloneEnvironment:async(e,t,s,r,o)=>(await n().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:r,branch:o})).data,generateJitLink:async e=>(await n().post("/jit/generate",e)).data,claimJitLink:async e=>(await n().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await n().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await n().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await n().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await n().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await n().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,s,r)=>(await n().post(`/projects/${e}/service-accounts/${t}/keys`,{label:s,expiresAt:r})).data,deleteServiceAccountKey:async(e,t,s)=>(await n().delete(`/projects/${e}/service-accounts/${t}/keys/${s}`)).data,post:async(e,t)=>(await n().post(e,t)).data};var c=i(require("chalk")),b=i(require("ora"));var w=i(require("crypto")),O=i(require("conf")),_=require("node-machine-id"),W="aes-256-gcm",N=new O.default({projectName:"xtra-cli-crypto"});function Y(){let e=N.get("masterKey");e||(e=w.default.randomBytes(32).toString("hex"),N.set("masterKey",e));let t=(0,_.machineIdSync)();return w.default.createHash("sha256").update(e+t).digest()}var D=e=>{let t=Y(),s=Buffer.from(e.iv,"hex"),r=Buffer.from(e.tag,"hex"),o=w.default.createDecipheriv(W,t,s);o.setAuthTag(r);let a=o.update(e.content,"hex","utf8");return a+=o.final("utf8"),a};var q=i(require("diff")),Z=new K.Command("diff").description("Show differences between local cache and remote secrets").argument("[env1]","Source Environment").argument("[env2]","Target Environment").option("-p, --project <projectId>","Project ID").option("-e, --env <environment>","Environment (dev, stg, prod)","dev").option("-b, --branch <branchName>","Branch Name").option("--show","Show actual value differences (sensitive)",!1).action(async(e,t,s)=>{let{project:r,env:o,branch:a,show:l}=s;r||(r=x().project),a||(a=x().branch||"main"),r||(console.error(c.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let f={dev:"development",stg:"staging",prod:"production"};if(e&&t){let p=f[e]||e,d=f[t]||t,g=(0,b.default)(`Fetching secrets for ${p} and ${d} (branch: ${a})...`).start();try{let[m,y]=await Promise.all([$.getSecrets(r,p,a),$.getSecrets(r,d,a)]);g.stop(),console.log(c.default.bold(`
2
+ Diff Report (${p} <-> ${d} @ ${a}):
3
+ `)),E(m,y,l)}catch(m){g.fail("Failed to fetch secrets"),console.error(c.default.red(m?.response?.data?.error||"An unexpected error occurred"))}}else{let p=f[o]||o,d=(0,b.default)(`Fetching remote state for ${p} (branch: ${a})...`).start();try{let g=await $.getSecrets(r,p,a),m={};try{let y=`cache.${r}.${p}.${a}`,k=R(y);if(k){let F=D(k);m=JSON.parse(F)}}catch{}d.stop(),console.log(c.default.bold(`
4
+ Diff Report (Remote ${p} vs Local Cache):
5
+ `)),E(g,m,l)}catch(g){d.fail("Failed to run diff."),console.error(c.default.red(g?.response?.data?.error||"An unexpected error occurred"))}}});function E(e,t,s){let r=new Set([...Object.keys(e),...Object.keys(t)]),o=!1;r.forEach(a=>{let l=e[a],f=t[a];if(l!==f){if(o=!0,l===void 0)console.log(c.default.green(`+ ${a} (Only in Target)`)),s&&console.log(c.default.green(` + "${f}"`));else if(f===void 0)console.log(c.default.red(`- ${a} (Only in Source)`)),s&&console.log(c.default.red(` - "${l}"`));else if(console.log(c.default.yellow(`~ ${a} (Modified)`)),s){let p=q.diffChars(l,f),d=" ";p.forEach(g=>{let m=g.added?c.default.green:g.removed?c.default.red:c.default.gray;d+=m(g.value)}),console.log(d)}}}),o?s||console.log(c.default.gray(`
6
+ (Use --show to reveal secret values)`)):console.log(c.default.green("\u2714 No differences found."))}0&&(module.exports={diffCommand});
@@ -1,2 +1,2 @@
1
- var _=Object.create;var u=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var L=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var G=(s,e)=>{for(var o in e)u(s,o,{get:e[o],enumerable:!0})},j=(s,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of O(e))!E.call(s,t)&&t!==o&&u(s,t,{get:()=>e[t],enumerable:!(r=$(e,t))||r.enumerable});return s};var i=(s,e,o)=>(o=s!=null?_(L(s)):{},j(e||!s||!s.__esModule?u(o,"default",{value:s,enumerable:!0}):o,s)),D=s=>j(u({},"__esModule",{value:!0}),s);var V={};G(V,{doctorCommand:()=>M});module.exports=D(V);var P=require("commander"),n=i(require("chalk")),f=i(require("fs")),C=i(require("path")),U=i(require("axios"));var A=i(require("conf")),d=i(require("fs")),v=i(require("path")),x="https://www.xtrasecurity.in/api",c=new A.default({projectName:"xtra-cli",defaults:{apiUrl:x}}),m=c.get("apiUrl");m&&!process.env.XTRA_API_URL&&(m.includes("localhost")||m.includes("xtra-security.vercel.app"))&&c.set("apiUrl",x);var b=()=>({...c.store,apiUrl:process.env.XTRA_API_URL||c.get("apiUrl")||x});var k=()=>c.get("token");var y=()=>{let s={};try{let e=v.default.join(process.cwd(),".xtrarc");d.default.existsSync(e)&&(s=JSON.parse(d.default.readFileSync(e,"utf-8")))}catch{}return{project:s.project||c.get("project")||"",env:s.env||c.get("env")||"development",branch:s.branch||c.get("branch")||"main"}};var w=65,p={tl:"\u256D",tr:"\u256E",bl:"\u2570",br:"\u256F",h:"\u2500",v:"\u2502"};function I(s){return p.h.repeat(s)}var F=n.default.green("\u2713 "),X=n.default.red("\u2717 "),B=n.default.yellow("\u26A0 ");async function J(){let s=[],e=b(),o=parseInt(process.versions.node.split(".")[0]);s.push({name:"Node.js Version",status:o>=18?"pass":"fail",message:`v${process.versions.node} ${o>=18?"(OK)":"(requires >=18)"}`});let r=k();s.push({name:"Auth Token",status:r?"pass":"fail",message:r?`Set (${r.substring(0,8)}...)`:"Not set \u2014 run 'xtra login'"});let t=e.apiUrl||process.env.XTRA_API_URL||"https://www.xtrasecurity.in/api";s.push({name:"API URL",status:e.apiUrl||process.env.XTRA_API_URL?"pass":"warn",message:t});try{let a=await U.default.get(`${t}/health`,{timeout:4e3});s.push({name:"API Connectivity",status:a.status===200?"pass":"warn",message:`${a.status} ${a.statusText}`})}catch(a){let N=a.code==="ECONNREFUSED"?"Connection refused (offline?)":a.code==="ETIMEDOUT"?"Timed out (unreachable)":a.response?.status===404?"API reachable (health endpoint missing)":a.message,T=a.response?.status===404?"pass":"fail";s.push({name:"API Connectivity",status:T,message:N})}let l=y().project;s.push({name:"Active Project",status:l?"pass":"warn",message:l||"Not set \u2014 run 'xtra project set <id>'"});let h=y().branch||"main";s.push({name:"Active Branch",status:"pass",message:h});let g=C.join(process.cwd(),".xtrarc"),R=C.join(process.cwd(),"xtra.json"),S=f.existsSync(g)||f.existsSync(R);return s.push({name:"Project Config",status:S?"pass":"warn",message:S?f.existsSync(g)?".xtrarc found":"xtra.json found":"Not found (run 'xtra init')"}),s}var M=new P.Command("doctor").description("Diagnose CLI configuration and API connectivity").option("--json","Output results as JSON",!1).action(async s=>{s.json||(console.log(),console.log(n.default.bold.cyan(" \u2695 XtraSecurity Diagnostics")),console.log(n.default.hex("#4a5568")(" "+p.tl+I(w)+p.tr)));let e=await J();if(s.json){process.stdout.write(JSON.stringify(e,null,2)+`
2
- `);return}let o=0,r=0;for(let t of e){t.status==="fail"&&o++,t.status==="warn"&&r++;let l=t.status==="pass"?F:t.status==="warn"?B:X,h=n.default.bold(n.default.white(t.name.padEnd(20))),g=t.status==="pass"?n.default.hex("#94a3b8")(t.message):t.status==="warn"?n.default.yellow(t.message):n.default.red(t.message);console.log(n.default.hex("#4a5568")(" "+p.v)+` ${l}${h} ${g}`.padEnd(w)+n.default.hex("#4a5568")(p.v))}if(console.log(n.default.hex("#4a5568")(" "+p.bl+I(w)+p.br)),console.log(),o===0&&r===0)console.log(n.default.green(" \u2713 All systems operational. The CLI is ready to use."));else{let t=[];o>0&&t.push(n.default.red(`${o} error(s)`)),r>0&&t.push(n.default.yellow(`${r} warning(s)`)),console.log(` Found ${t.join(" and ")}.`)}console.log()});0&&(module.exports={doctorCommand});
1
+ var _=Object.create;var u=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var L=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var G=(s,e)=>{for(var o in e)u(s,o,{get:e[o],enumerable:!0})},S=(s,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of O(e))!E.call(s,t)&&t!==o&&u(s,t,{get:()=>e[t],enumerable:!(r=$(e,t))||r.enumerable});return s};var i=(s,e,o)=>(o=s!=null?_(L(s)):{},S(e||!s||!s.__esModule?u(o,"default",{value:s,enumerable:!0}):o,s)),D=s=>S(u({},"__esModule",{value:!0}),s);var V={};G(V,{doctorCommand:()=>M});module.exports=D(V);var P=require("commander"),n=i(require("chalk")),f=i(require("fs")),w=i(require("path")),U=i(require("axios"));var A=i(require("conf")),m=i(require("fs")),v=i(require("path")),d="https://www.xtrasecurity.in/api",c=new A.default({projectName:"xtra-cli",defaults:{apiUrl:d}}),j=c.get("apiUrl");j&&!process.env.XTRA_API_URL&&j.includes("xtra-security.vercel.app")&&c.set("apiUrl",d);var b=()=>({...c.store,apiUrl:process.env.XTRA_API_URL||c.get("apiUrl")||d});var k=()=>c.get("token");var x=()=>{let s={};try{let e=v.default.join(process.cwd(),".xtrarc");m.default.existsSync(e)&&(s=JSON.parse(m.default.readFileSync(e,"utf-8")))}catch{}return{project:s.project||c.get("project")||"",env:s.env||c.get("env")||"development",branch:s.branch||c.get("branch")||"main"}};var y=65,p={tl:"\u256D",tr:"\u256E",bl:"\u2570",br:"\u256F",h:"\u2500",v:"\u2502"};function I(s){return p.h.repeat(s)}var F=n.default.green("\u2713 "),X=n.default.red("\u2717 "),B=n.default.yellow("\u26A0 ");async function J(){let s=[],e=b(),o=parseInt(process.versions.node.split(".")[0]);s.push({name:"Node.js Version",status:o>=18?"pass":"fail",message:`v${process.versions.node} ${o>=18?"(OK)":"(requires >=18)"}`});let r=k();s.push({name:"Auth Token",status:r?"pass":"fail",message:r?`Set (${r.substring(0,8)}...)`:"Not set \u2014 run 'xtra login'"});let t=e.apiUrl||process.env.XTRA_API_URL||"https://www.xtrasecurity.in/api";s.push({name:"API URL",status:e.apiUrl||process.env.XTRA_API_URL?"pass":"warn",message:t});try{let a=await U.default.get(`${t}/health`,{timeout:4e3});s.push({name:"API Connectivity",status:a.status===200?"pass":"warn",message:`${a.status} ${a.statusText}`})}catch(a){let N=a.code==="ECONNREFUSED"?"Connection refused (offline?)":a.code==="ETIMEDOUT"?"Timed out (unreachable)":a.response?.status===404?"API reachable (health endpoint missing)":a?.response?.data?.error||"An unexpected error occurred",T=a.response?.status===404?"pass":"fail";s.push({name:"API Connectivity",status:T,message:N})}let l=x().project;s.push({name:"Active Project",status:l?"pass":"warn",message:l||"Not set \u2014 run 'xtra project set <id>'"});let h=x().branch||"main";s.push({name:"Active Branch",status:"pass",message:h});let g=w.join(process.cwd(),".xtrarc"),R=w.join(process.cwd(),"xtra.json"),C=f.existsSync(g)||f.existsSync(R);return s.push({name:"Project Config",status:C?"pass":"warn",message:C?f.existsSync(g)?".xtrarc found":"xtra.json found":"Not found (run 'xtra init')"}),s}var M=new P.Command("doctor").description("Diagnose CLI configuration and API connectivity").option("--json","Output results as JSON",!1).action(async s=>{s.json||(console.log(),console.log(n.default.bold.cyan(" \u2695 XtraSecurity Diagnostics")),console.log(n.default.hex("#4a5568")(" "+p.tl+I(y)+p.tr)));let e=await J();if(s.json){process.stdout.write(JSON.stringify(e,null,2)+`
2
+ `);return}let o=0,r=0;for(let t of e){t.status==="fail"&&o++,t.status==="warn"&&r++;let l=t.status==="pass"?F:t.status==="warn"?B:X,h=n.default.bold(n.default.white(t.name.padEnd(20))),g=t.status==="pass"?n.default.hex("#94a3b8")(t.message):t.status==="warn"?n.default.yellow(t.message):n.default.red(t.message);console.log(n.default.hex("#4a5568")(" "+p.v)+` ${l}${h} ${g}`.padEnd(y)+n.default.hex("#4a5568")(p.v))}if(console.log(n.default.hex("#4a5568")(" "+p.bl+I(y)+p.br)),console.log(),o===0&&r===0)console.log(n.default.green(" \u2713 All systems operational. The CLI is ready to use."));else{let t=[];o>0&&t.push(n.default.red(`${o} error(s)`)),r>0&&t.push(n.default.yellow(`${r} warning(s)`)),console.log(` Found ${t.join(" and ")}.`)}console.log()});0&&(module.exports={doctorCommand});