@0xobelisk/sui-cli 1.2.0-pre.97 → 1.2.0-pre.98

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/dubhe.js CHANGED
@@ -100,7 +100,7 @@ Watch stopped.`),f()})}},At=$n;import Nt from"wait-on";import le from"ora";impor
100
100
  - Sui localnode on port 9000
101
101
  - Sui faucet on port 9123
102
102
  - PostgreSQL database on port 5432
103
- - Dubhe GraphQL server on port 4000`):t["local-database"]?(s="Timeout waiting for local database",r="Please make sure PostgreSQL is running on port 5432"):t["local-node"]?(s="Timeout waiting for local Sui node",r="Please make sure Sui localnode is running on port 9123"):t["local-indexer"]&&(s="Timeout waiting for local indexer",r="Please make sure indexer is running and health endpoint is available at http://127.0.0.1:8080/health"),n.fail(X.red(s)),console.error(X.yellow(r)),f(1)}}},Mt=Tn;var Dn={command:"switch-env",describe:"Switch environment",builder(e){return e.option("network",{type:"string",choices:["mainnet","testnet","devnet","localnet"],default:"localnet",desc:"Switch to node network (mainnet/testnet/devnet/localnet)"})},async handler(e){await G(e.network),f()}},jt=Dn;import In from"dotenv";import Q from"chalk";In.config();var An={command:"info",describe:"Get information about the current Sui node",builder(e){return e.options({network:{type:"string",choices:["mainnet","testnet","devnet","localnet","default"],default:"default",desc:"Node network (mainnet/testnet/devnet/localnet)"}})},handler:async({network:e})=>{try{e=="default"&&(e=await A(),console.log(Q.yellow(`Use default network: [${e}]`)));let t=W({network:e}),o=t.getSigner();console.log(Q.blue("Account Information:")),console.log(` Network: ${Q.green(e)}`),console.log(` Address: ${Q.green(o.toSuiAddress())}`);try{let n=await t.getBalance("0x2::sui::SUI"),s=(Number(n.totalBalance)/10**9).toFixed(4);console.log(` Balance: ${Q.green(s)} SUI`)}catch{console.log(` Balance: ${Q.red("Failed to fetch balance")} ${Q.gray("(Network error)")}`)}f()}catch(t){z(t),f(1)}}},Ut=An;import{loadConfig as Nn}from"@0xobelisk/sui-common";async function Ht(e,t,o){if(o)await pe(e.name,t,o);else{let n=`${process.cwd()}/src/${e.name}`,s=await de(n,t);await pe(e.name,t,s)}}import On from"chalk";var Fn={command:"load-metadata",describe:"Load metadata for a package",builder(e){return e.options({network:{type:"string",choices:["mainnet","testnet","devnet","localnet","default"],default:"default",desc:"Node network (mainnet/testnet/devnet/localnet)"},"config-path":{type:"string",desc:"Configuration file path",default:"dubhe.config.ts"},"package-id":{type:"string",desc:"Package ID to load metadata for",optional:!0}})},async handler({network:e,"config-path":t,"package-id":o}){try{e=="default"&&(e=await A(),console.log(On.yellow(`Use default network: [${e}]`)));let n=await Nn(t);await Ht(n,e,o)}catch(n){z(n),f(1)}f()}},Lt=Fn;import i from"chalk";import{spawn as Un}from"child_process";import Bt from"cli-table3";import Te from"inquirer";import*as S from"fs";import*as N from"path";import*as ee from"os";import*as Gt from"net";import Hn from"axios";var Z={name:"@0xobelisk/sui-cli",version:"1.2.0-pre.97",description:"Tookit for interacting with move eps framework",keywords:["sui","obelisk labs","move","blockchain"],homepage:"https://github.com/0xobelisk/dubhe/tree/main/packages/sui-cli#readme",bugs:"https://github.com/0xobelisk/dubhe/issues",repository:{type:"git",url:"https://github.com/0xobelisk/dubhe.git"},license:"Apache-2.0",author:"team@obelisk.build",type:"module",exports:{".":"./dist/index.js"},types:"src/index.ts",bin:{dubhe:"./dist/dubhe.js"},scripts:{build:"pnpm run type-check && pnpm run build:js","build:js":"tsup && chmod +x ./dist/dubhe.js",clean:"pnpm run clean:js","clean:js":"rimraf dist",dev:"tsup --watch",format:"prettier --write .","format:check":"prettier --check .",lint:"eslint . --ext .ts",test:"vitest run","test:all":"pnpm test && pnpm test:integration","test:coverage":"vitest run --coverage","test:integration":"vitest run --config vitest.integration.config.ts","test:localnet":"vitest run --config vitest.integration.config.ts tests/integration/localnet.test.ts","test:testnet":"vitest run --config vitest.integration.config.ts tests/integration/testnet.test.ts","test:watch":"vitest","type-check":"tsc --noEmit",validate:"pnpm format:check && pnpm type-check"},dependencies:{"@0xobelisk/sui-client":"workspace:*","@0xobelisk/sui-common":"workspace:*","@mysten/sui":"1.35.0","@types/wait-on":"^5.3.4",axios:"^1.12.0",chalk:"^5.0.1",child_process:"^1.0.2",chokidar:"^3.5.3","cli-progress":"^3.12.0","cli-table3":"^0.6.5",dotenv:"^16.0.3",ejs:"^3.1.8",execa:"^7.0.0",glob:"^8.0.3","http-proxy-agent":"^7.0.2","https-proxy-agent":"^7.0.6",inquirer:"^9.2.15",ora:"^5.4.1",path:"^0.12.7",typescript:"^5.8.3","wait-on":"^7.0.1",yargs:"^17.7.1",zod:"^3.22.3","zod-validation-error":"^1.3.0"},devDependencies:{"@types/cli-progress":"^3.11.5","@types/ejs":"^3.1.1","@types/glob":"^7.2.0","@types/inquirer":"^9.0.7","@types/node":"^22.16.0","@types/yargs":"^17.0.10",eslint:"^9.0.0","eslint-config-prettier":"^9.1.0",prettier:"3.3.3","ts-node":"^10.9.1",tsup:"^6.7.0",tsx:"^3.12.6",vitest:"0.31.4"},engines:{node:">=22.0.0"},publishConfig:{access:"public"}};import Ee from"chalk";import*as Vt from"cli-progress";import*as zt from"fs";import Mn from"axios";async function Wt(e,t){try{let o=await Mn.get(e,{responseType:"stream",timeout:3e4,headers:{"User-Agent":"dubhe-cli"},maxRedirects:5,validateStatus:n=>n<400});await jn(o,t),console.log(Ee.green(" \u2713 Successfully downloaded"))}catch(o){if(o.code==="ENOTFOUND")throw new Error(`DNS resolution failed: ${o.message}. Please check your internet connection.`);if(o.code==="ECONNRESET")throw new Error(`Connection reset: ${o.message}. Please check your network connection.`);if(o.code==="ETIMEDOUT")throw new Error(`Connection timeout: ${o.message}. Please check your network connection.`);if(o.message.includes("protocol mismatch"))throw new Error(`Protocol mismatch: ${o.message}. Please check your network configuration.`);if(o.response)throw new Error(`HTTP ${o.response.status}: ${o.response.statusText}`);{let n=o instanceof Error?o.message:String(o);throw new Error(`Download failed: ${n}`)}}}async function jn(e,t){let o=parseInt(e.headers["content-length"]||"0"),n=new Vt.SingleBar({format:Ee.cyan("Download Progress")+" |{bar}| {percentage}% | {value}/{total} MB | Speed: {speed} MB/s | ETA: {eta}s",barCompleteChar:"\u2588",barIncompleteChar:"\u2591",hideCursor:!0,barsize:30,forceRedraw:!0});o>0?n.start(Math.round(o/1024/1024*100)/100,0,{speed:"0.00"}):console.log(Ee.blue("\u{1F4E5} Downloading... (unable to get file size)"));let s=zt.createWriteStream(t),r=0,a=Date.now();return new Promise((l,d)=>{e.data.on("data",c=>{if(r+=c.length,o>0){let g=Math.round(r/1024/1024*100)/100,u=(Date.now()-a)/1e3,b=u>0?Math.round(g/u*100)/100:0;n.update(g,{speed:b.toFixed(2)})}}),e.data.pipe(s),s.on("finish",()=>{o>0&&n.stop();let c=Math.round(r/1024/1024*100)/100,g=(Date.now()-a)/1e3,u=g>0?Math.round(c/g*100)/100:0;console.log(Ee.green(`\u2713 Download completed! ${c} MB, average speed: ${u} MB/s`)),l()}),s.on("error",c=>{o>0&&n.stop(),d(c)})})}function ze(){let e=process.platform,t=process.arch,o,n;switch(e){case"darwin":o="macos";break;case"win32":o="windows";break;case"linux":o="ubuntu";break;default:o=e}switch(t){case"x64":n="x86_64";break;case"arm64":n="aarch64";break;default:n=t}return{platform:e,arch:t,platformForAsset:o,archForAsset:n}}var L={sui:{name:"sui",repo:"MystenLabs/sui",binaryName:"sui",installDir:N.join(ee.homedir(),".dubhe","bin")},"dubhe-indexer":{name:"dubhe-indexer",repo:"0xobelisk/dubhe",binaryName:"dubhe-indexer",installDir:N.join(ee.homedir(),".dubhe","bin")}};async function B(e,t=[]){return new Promise(o=>{let n=Un(e,t,{shell:!0}),s="",r="";n.stdout?.on("data",a=>{s+=a.toString()}),n.stderr?.on("data",a=>{r+=a.toString()}),n.on("close",a=>{o({code:a||0,stdout:s,stderr:r})}),n.on("error",()=>{o({code:-1,stdout:s,stderr:r})})})}async function Kt(e,t={}){try{let o={timeout:3e4,maxRedirects:5,validateStatus:s=>s<500,...t},n=await Hn(e,o);return{ok:n.status>=200&&n.status<300,status:n.status,statusText:n.statusText,json:async()=>n.data,headers:n.headers}}catch(o){let n=o.response?.status||0,s=o.response?.statusText||o.message;return o.code==="ENOTFOUND"?s="DNS resolution failed - please check your internet connection":o.code==="ECONNRESET"?s="Connection reset - please check your network connection":o.code==="ETIMEDOUT"?s="Connection timeout - please check your network connection":o.message.includes("protocol mismatch")&&(s="Protocol mismatch - please check your network configuration"),{ok:!1,status:n,statusText:s,json:async()=>o.response?.data||{},headers:o.response?.headers||{}}}}async function We(e,t=10,o=3){let n=`https://api.github.com/repos/${e}/releases?per_page=${t}`;for(let s=1;s<=o;s++)try{s>1&&console.log(i.gray(` Retry ${s}/${o}...`));let r=await Kt(n,{headers:{"User-Agent":"dubhe-cli",Accept:"application/vnd.github.v3+json"}});if(!r.ok)throw r.status===403?new Error(`GitHub API rate limit: ${r.status}. Please retry later or set GITHUB_TOKEN environment variable`):new Error(`GitHub API request failed: ${r.status} ${r.statusText}`);return await r.json()}catch(r){if(s>1&&console.log(i.yellow(` \u26A0\uFE0F Attempt ${s} failed: ${r instanceof Error?r.message:String(r)}`)),s===o)return console.error(i.red(` \u274C Failed to fetch releases after ${o} attempts`)),[];await new Promise(a=>setTimeout(a,1e3*s))}return[]}function ye(e,t){return e.assets.filter(n=>{let s=n.name.toLowerCase(),r=[t.platformForAsset.toLowerCase(),...t.platformForAsset==="macos"?["darwin","apple"]:[],...t.platformForAsset==="windows"?["win","win32","windows"]:[],...t.platformForAsset==="ubuntu"?["linux","gnu"]:[]],a=[t.archForAsset.toLowerCase(),...t.archForAsset==="x86_64"?["amd64","x64"]:[],...t.archForAsset==="aarch64"?["arm64"]:[]],l=r.some(g=>s.includes(g)),d=a.some(g=>s.includes(g)),c=s.endsWith(".tar.gz")||s.endsWith(".zip")||s.endsWith(".tgz")||s.endsWith(".tar.bz2")||s.endsWith(".tar.xz");return l&&d&&c}).map(n=>n.name)}async function Ln(e,t){let o=L[e];return o?(await We(o.repo,10)).map(s=>({version:s.tag_name,hasCompatibleAsset:ye(s,t).length>0})):[]}async function Vn(e){try{let t=be();if(!t){console.log(i.gray(`Please add to PATH: export PATH="$PATH:${e}"`));return}let{shellName:o,configFile:n}=t,s=o==="fish"?`set -gx PATH $PATH ${e}`:`export PATH="$PATH:${e}"`;if(S.existsSync(n)&&S.readFileSync(n,"utf8").includes(e)){console.log(i.green(` \u2713 PATH already configured in ${n}`));return}let a=`# Added by dubhe doctor
103
+ - Dubhe GraphQL server on port 4000`):t["local-database"]?(s="Timeout waiting for local database",r="Please make sure PostgreSQL is running on port 5432"):t["local-node"]?(s="Timeout waiting for local Sui node",r="Please make sure Sui localnode is running on port 9123"):t["local-indexer"]&&(s="Timeout waiting for local indexer",r="Please make sure indexer is running and health endpoint is available at http://127.0.0.1:8080/health"),n.fail(X.red(s)),console.error(X.yellow(r)),f(1)}}},Mt=Tn;var Dn={command:"switch-env",describe:"Switch environment",builder(e){return e.option("network",{type:"string",choices:["mainnet","testnet","devnet","localnet"],default:"localnet",desc:"Switch to node network (mainnet/testnet/devnet/localnet)"})},async handler(e){await G(e.network),f()}},jt=Dn;import In from"dotenv";import Q from"chalk";In.config();var An={command:"info",describe:"Get information about the current Sui node",builder(e){return e.options({network:{type:"string",choices:["mainnet","testnet","devnet","localnet","default"],default:"default",desc:"Node network (mainnet/testnet/devnet/localnet)"}})},handler:async({network:e})=>{try{e=="default"&&(e=await A(),console.log(Q.yellow(`Use default network: [${e}]`)));let t=W({network:e}),o=t.getSigner();console.log(Q.blue("Account Information:")),console.log(` Network: ${Q.green(e)}`),console.log(` Address: ${Q.green(o.toSuiAddress())}`);try{let n=await t.getBalance("0x2::sui::SUI"),s=(Number(n.totalBalance)/10**9).toFixed(4);console.log(` Balance: ${Q.green(s)} SUI`)}catch{console.log(` Balance: ${Q.red("Failed to fetch balance")} ${Q.gray("(Network error)")}`)}f()}catch(t){z(t),f(1)}}},Ut=An;import{loadConfig as Nn}from"@0xobelisk/sui-common";async function Ht(e,t,o){if(o)await pe(e.name,t,o);else{let n=`${process.cwd()}/src/${e.name}`,s=await de(n,t);await pe(e.name,t,s)}}import On from"chalk";var Fn={command:"load-metadata",describe:"Load metadata for a package",builder(e){return e.options({network:{type:"string",choices:["mainnet","testnet","devnet","localnet","default"],default:"default",desc:"Node network (mainnet/testnet/devnet/localnet)"},"config-path":{type:"string",desc:"Configuration file path",default:"dubhe.config.ts"},"package-id":{type:"string",desc:"Package ID to load metadata for",optional:!0}})},async handler({network:e,"config-path":t,"package-id":o}){try{e=="default"&&(e=await A(),console.log(On.yellow(`Use default network: [${e}]`)));let n=await Nn(t);await Ht(n,e,o)}catch(n){z(n),f(1)}f()}},Lt=Fn;import i from"chalk";import{spawn as Un}from"child_process";import Bt from"cli-table3";import Te from"inquirer";import*as S from"fs";import*as N from"path";import*as ee from"os";import*as Gt from"net";import Hn from"axios";var Z={name:"@0xobelisk/sui-cli",version:"1.2.0-pre.98",description:"Tookit for interacting with move eps framework",keywords:["sui","obelisk labs","move","blockchain"],homepage:"https://github.com/0xobelisk/dubhe/tree/main/packages/sui-cli#readme",bugs:"https://github.com/0xobelisk/dubhe/issues",repository:{type:"git",url:"https://github.com/0xobelisk/dubhe.git"},license:"Apache-2.0",author:"team@obelisk.build",type:"module",exports:{".":"./dist/index.js"},types:"src/index.ts",bin:{dubhe:"./dist/dubhe.js"},scripts:{build:"pnpm run type-check && pnpm run build:js","build:js":"tsup && chmod +x ./dist/dubhe.js",clean:"pnpm run clean:js","clean:js":"rimraf dist",dev:"tsup --watch",format:"prettier --write .","format:check":"prettier --check .",lint:"eslint . --ext .ts",test:"vitest run","test:all":"pnpm test && pnpm test:integration","test:coverage":"vitest run --coverage","test:integration":"vitest run --config vitest.integration.config.ts","test:localnet":"vitest run --config vitest.integration.config.ts tests/integration/localnet.test.ts","test:testnet":"vitest run --config vitest.integration.config.ts tests/integration/testnet.test.ts","test:watch":"vitest","type-check":"tsc --noEmit",validate:"pnpm format:check && pnpm type-check"},dependencies:{"@0xobelisk/sui-client":"workspace:*","@0xobelisk/sui-common":"workspace:*","@mysten/sui":"1.35.0","@types/wait-on":"^5.3.4",axios:"^1.12.0",chalk:"^5.0.1",child_process:"^1.0.2",chokidar:"^3.5.3","cli-progress":"^3.12.0","cli-table3":"^0.6.5",dotenv:"^16.0.3",ejs:"^3.1.8",execa:"^7.0.0",glob:"^8.0.3","http-proxy-agent":"^7.0.2","https-proxy-agent":"^7.0.6",inquirer:"^9.2.15",ora:"^5.4.1",path:"^0.12.7",typescript:"^5.8.3","wait-on":"^7.0.1",yargs:"^17.7.1",zod:"^3.22.3","zod-validation-error":"^1.3.0"},devDependencies:{"@types/cli-progress":"^3.11.5","@types/ejs":"^3.1.1","@types/glob":"^7.2.0","@types/inquirer":"^9.0.7","@types/node":"^22.16.0","@types/yargs":"^17.0.10",eslint:"^9.0.0","eslint-config-prettier":"^9.1.0",prettier:"3.3.3","ts-node":"^10.9.1",tsup:"^6.7.0",tsx:"^3.12.6",vitest:"0.31.4"},engines:{node:">=22.0.0"},publishConfig:{access:"public"}};import Ee from"chalk";import*as Vt from"cli-progress";import*as zt from"fs";import Mn from"axios";async function Wt(e,t){try{let o=await Mn.get(e,{responseType:"stream",timeout:3e4,headers:{"User-Agent":"dubhe-cli"},maxRedirects:5,validateStatus:n=>n<400});await jn(o,t),console.log(Ee.green(" \u2713 Successfully downloaded"))}catch(o){if(o.code==="ENOTFOUND")throw new Error(`DNS resolution failed: ${o.message}. Please check your internet connection.`);if(o.code==="ECONNRESET")throw new Error(`Connection reset: ${o.message}. Please check your network connection.`);if(o.code==="ETIMEDOUT")throw new Error(`Connection timeout: ${o.message}. Please check your network connection.`);if(o.message.includes("protocol mismatch"))throw new Error(`Protocol mismatch: ${o.message}. Please check your network configuration.`);if(o.response)throw new Error(`HTTP ${o.response.status}: ${o.response.statusText}`);{let n=o instanceof Error?o.message:String(o);throw new Error(`Download failed: ${n}`)}}}async function jn(e,t){let o=parseInt(e.headers["content-length"]||"0"),n=new Vt.SingleBar({format:Ee.cyan("Download Progress")+" |{bar}| {percentage}% | {value}/{total} MB | Speed: {speed} MB/s | ETA: {eta}s",barCompleteChar:"\u2588",barIncompleteChar:"\u2591",hideCursor:!0,barsize:30,forceRedraw:!0});o>0?n.start(Math.round(o/1024/1024*100)/100,0,{speed:"0.00"}):console.log(Ee.blue("\u{1F4E5} Downloading... (unable to get file size)"));let s=zt.createWriteStream(t),r=0,a=Date.now();return new Promise((l,d)=>{e.data.on("data",c=>{if(r+=c.length,o>0){let g=Math.round(r/1024/1024*100)/100,u=(Date.now()-a)/1e3,b=u>0?Math.round(g/u*100)/100:0;n.update(g,{speed:b.toFixed(2)})}}),e.data.pipe(s),s.on("finish",()=>{o>0&&n.stop();let c=Math.round(r/1024/1024*100)/100,g=(Date.now()-a)/1e3,u=g>0?Math.round(c/g*100)/100:0;console.log(Ee.green(`\u2713 Download completed! ${c} MB, average speed: ${u} MB/s`)),l()}),s.on("error",c=>{o>0&&n.stop(),d(c)})})}function ze(){let e=process.platform,t=process.arch,o,n;switch(e){case"darwin":o="macos";break;case"win32":o="windows";break;case"linux":o="ubuntu";break;default:o=e}switch(t){case"x64":n="x86_64";break;case"arm64":n="aarch64";break;default:n=t}return{platform:e,arch:t,platformForAsset:o,archForAsset:n}}var L={sui:{name:"sui",repo:"MystenLabs/sui",binaryName:"sui",installDir:N.join(ee.homedir(),".dubhe","bin")},"dubhe-indexer":{name:"dubhe-indexer",repo:"0xobelisk/dubhe",binaryName:"dubhe-indexer",installDir:N.join(ee.homedir(),".dubhe","bin")}};async function B(e,t=[]){return new Promise(o=>{let n=Un(e,t,{shell:!0}),s="",r="";n.stdout?.on("data",a=>{s+=a.toString()}),n.stderr?.on("data",a=>{r+=a.toString()}),n.on("close",a=>{o({code:a||0,stdout:s,stderr:r})}),n.on("error",()=>{o({code:-1,stdout:s,stderr:r})})})}async function Kt(e,t={}){try{let o={timeout:3e4,maxRedirects:5,validateStatus:s=>s<500,...t},n=await Hn(e,o);return{ok:n.status>=200&&n.status<300,status:n.status,statusText:n.statusText,json:async()=>n.data,headers:n.headers}}catch(o){let n=o.response?.status||0,s=o.response?.statusText||o.message;return o.code==="ENOTFOUND"?s="DNS resolution failed - please check your internet connection":o.code==="ECONNRESET"?s="Connection reset - please check your network connection":o.code==="ETIMEDOUT"?s="Connection timeout - please check your network connection":o.message.includes("protocol mismatch")&&(s="Protocol mismatch - please check your network configuration"),{ok:!1,status:n,statusText:s,json:async()=>o.response?.data||{},headers:o.response?.headers||{}}}}async function We(e,t=10,o=3){let n=`https://api.github.com/repos/${e}/releases?per_page=${t}`;for(let s=1;s<=o;s++)try{s>1&&console.log(i.gray(` Retry ${s}/${o}...`));let r=await Kt(n,{headers:{"User-Agent":"dubhe-cli",Accept:"application/vnd.github.v3+json"}});if(!r.ok)throw r.status===403?new Error(`GitHub API rate limit: ${r.status}. Please retry later or set GITHUB_TOKEN environment variable`):new Error(`GitHub API request failed: ${r.status} ${r.statusText}`);return await r.json()}catch(r){if(s>1&&console.log(i.yellow(` \u26A0\uFE0F Attempt ${s} failed: ${r instanceof Error?r.message:String(r)}`)),s===o)return console.error(i.red(` \u274C Failed to fetch releases after ${o} attempts`)),[];await new Promise(a=>setTimeout(a,1e3*s))}return[]}function ye(e,t){return e.assets.filter(n=>{let s=n.name.toLowerCase(),r=[t.platformForAsset.toLowerCase(),...t.platformForAsset==="macos"?["darwin","apple"]:[],...t.platformForAsset==="windows"?["win","win32","windows"]:[],...t.platformForAsset==="ubuntu"?["linux","gnu"]:[]],a=[t.archForAsset.toLowerCase(),...t.archForAsset==="x86_64"?["amd64","x64"]:[],...t.archForAsset==="aarch64"?["arm64"]:[]],l=r.some(g=>s.includes(g)),d=a.some(g=>s.includes(g)),c=s.endsWith(".tar.gz")||s.endsWith(".zip")||s.endsWith(".tgz")||s.endsWith(".tar.bz2")||s.endsWith(".tar.xz");return l&&d&&c}).map(n=>n.name)}async function Ln(e,t){let o=L[e];return o?(await We(o.repo,10)).map(s=>({version:s.tag_name,hasCompatibleAsset:ye(s,t).length>0})):[]}async function Vn(e){try{let t=be();if(!t){console.log(i.gray(`Please add to PATH: export PATH="$PATH:${e}"`));return}let{shellName:o,configFile:n}=t,s=o==="fish"?`set -gx PATH $PATH ${e}`:`export PATH="$PATH:${e}"`;if(S.existsSync(n)&&S.readFileSync(n,"utf8").includes(e)){console.log(i.green(` \u2713 PATH already configured in ${n}`));return}let a=`# Added by dubhe doctor
104
104
  ${s}`;S.appendFileSync(n,`
105
105
  ${a}
106
106
  `),console.log(i.green(` \u2713 Automatically added to PATH in ${n}`)),console.log(i.blue(` \u{1F4DD} To apply changes: source ${n} or restart terminal`))}catch(t){console.log(i.yellow(` \u26A0\uFE0F Could not auto-configure PATH: ${t instanceof Error?t.message:String(t)}`)),console.log(i.gray(` Please manually add to PATH: export PATH="$PATH:${e}"`))}}function be(){let e=ee.homedir(),t=process.env.SHELL;if(t){if(t.includes("zsh"))return{shellName:"zsh",configFile:N.join(e,".zshrc")};if(t.includes("bash")){let n=N.join(e,".bash_profile"),s=N.join(e,".bashrc");return{shellName:"bash",configFile:process.platform==="darwin"&&S.existsSync(n)?n:s}}else if(t.includes("fish")){let n=N.join(e,".config","fish");return S.existsSync(n)||S.mkdirSync(n,{recursive:!0}),{shellName:"fish",configFile:N.join(n,"config.fish")}}}let o=[{name:"zsh",file:N.join(e,".zshrc")},{name:"bash",file:process.platform==="darwin"?N.join(e,".bash_profile"):N.join(e,".bashrc")},{name:"bash",file:N.join(e,".bashrc")}];for(let n of o)if(S.existsSync(n.file))return{shellName:n.name,configFile:n.file};return process.env.ZSH||S.existsSync("/bin/zsh")?{shellName:"zsh",configFile:N.join(e,".zshrc")}:null}async function Ve(e,t){let o=L[e];if(!o)return console.error(`Unknown tool: ${e}`),!1;let n=ze();console.log(i.gray(` System: ${n.platform}/${n.arch}`));try{console.log(i.gray(" Fetching release information..."));let s=await We(o.repo,10);if(s.length===0)return console.error(i.red(` \u274C Unable to fetch releases for ${o.name}`)),!1;let r=null;if(t){if(t.startsWith("v")||(t=`v${t}`),r=s.find(m=>m.tag_name===t)||null,!r)return console.error(`Version ${t} not found`),!1}else for(let m of s)if(ye(m,n).length>0){r=m;break}if(!r)return console.error("No compatible version found"),!1;let a=ye(r,n);if(a.length===0)return console.error(`Version ${r.tag_name} has no compatible binaries`),!1;let l=a[0],d=r.assets.find(m=>m.name===l);if(!d)return console.error(`Asset file not found: ${l}`),!1;console.log(i.green(` \u2713 Found compatible version: ${r.tag_name}`)),console.log(i.gray(` Download file: ${d.name}`));try{let m=await Kt(d.browser_download_url,{method:"HEAD",headers:{"User-Agent":"dubhe-cli"}});if(!m.ok)console.log(i.yellow(` \u26A0\uFE0F Warning: Unable to access download file (${m.status})`));else{let v=m.headers["content-length"];v&&console.log(i.gray(` File size: ${Math.round(parseInt(v)/1024/1024*100)/100} MB`))}}catch{console.log(i.yellow(" \u26A0\uFE0F Warning: Unable to verify download file"))}S.existsSync(o.installDir)||(S.mkdirSync(o.installDir,{recursive:!0}),console.log(i.gray(` Created install directory: ${o.installDir}`))),console.log(i.blue(" \u{1F4E5} Downloading..."));let c=N.join(ee.tmpdir(),d.name),g=3;for(let m=1;m<=g;m++)try{m>1&&console.log(i.gray(` Attempt ${m} to download...`)),await Wt(d.browser_download_url,c);break}catch(v){let p=v instanceof Error?v.message:String(v);if(console.log(i.yellow(` \u26A0\uFE0F Download failed (attempt ${m}): ${p}`)),m===g)throw new Error(`Download failed after ${g} attempts: ${p}`);console.log(i.gray(` Waiting ${m*2} seconds before retry...`)),await new Promise(h=>setTimeout(h,m*2e3))}console.log(i.blue(" \u{1F4E6} Extracting and installing..."));let u=N.join(ee.tmpdir(),`extract_${Date.now()}`);if(S.mkdirSync(u,{recursive:!0}),d.name.endsWith(".tar.gz")||d.name.endsWith(".tgz")){let m=await B("tar",["-xzf",c,"-C",u]);if(m.code!==0)throw new Error(`Extraction failed: ${m.stderr}`)}else if(d.name.endsWith(".tar.bz2")){let m=await B("tar",["-xjf",c,"-C",u]);if(m.code!==0)throw new Error(`Extraction failed: ${m.stderr}`)}else if(d.name.endsWith(".tar.xz")){let m=await B("tar",["-xJf",c,"-C",u]);if(m.code!==0)throw new Error(`Extraction failed: ${m.stderr}`)}else if(d.name.endsWith(".zip")){let m=await B("unzip",["-q",c,"-d",u]);if(m.code!==0)throw new Error(`Extraction failed: ${m.stderr}`)}else throw new Error(`Unsupported compression format: ${d.name}`);let b=m=>{let v=S.readdirSync(m,{withFileTypes:!0});for(let p of v){let h=N.join(m,p.name);if(p.isDirectory()){let C=b(h);if(C)return C}else if(p.name===o.binaryName||p.name===`${o.binaryName}.exe`)return h}return null},y=b(u);if(!y)throw new Error(`Cannot find ${o.binaryName} binary in extracted files`);let x=N.join(o.installDir,o.binaryName+(process.platform==="win32"?".exe":""));return S.copyFileSync(y,x),process.platform!=="win32"&&S.chmodSync(x,493),S.rmSync(c,{force:!0}),S.rmSync(u,{recursive:!0,force:!0}),console.log(i.green(" \u2705 Installation completed!")),console.log(i.gray(` Location: ${x}`)),console.log(i.gray(` Version: ${r.tag_name}`)),(process.env.PATH||"").includes(o.installDir)||(console.log(i.yellow(" \u26A0\uFE0F Warning: Install directory is not in PATH environment variable")),process.platform==="win32"?console.log(i.gray(` Please add to PATH: set PATH=%PATH%;${o.installDir}`)):await Vn(o.installDir)),!0}catch(s){return console.error(i.red(`\u274C Installation failed: ${s}`)),!1}}async function zn(e){let t=ze(),o=await Ln(e,t);if(o.length===0)return console.log(i.red(`Unable to get version information for ${e}`)),null;let n=o.filter(r=>r.hasCompatibleAsset).slice(0,5);if(n.length===0)return console.log(i.red("No compatible versions found for current system")),null;console.log(i.blue(`